[PATCH 2/4] Add GPIO ioctl decoding
Dmitry V. Levin
ldv at altlinux.org
Sat Jan 2 15:53:36 UTC 2021
On Sat, Jan 02, 2021 at 11:44:03PM +0800, Kent Gibson wrote:
> On Wed, Dec 30, 2020 at 12:47:28PM +0300, Dmitry V. Levin wrote:
> > On Wed, Dec 30, 2020 at 10:58:14AM +0800, Kent Gibson wrote:
> > > On Wed, Dec 30, 2020 at 05:07:42AM +0300, Dmitry V. Levin wrote:
> > > > On Wed, Dec 23, 2020 at 06:07:46AM +0800, Kent Gibson wrote:
> > > > > Decode the GPIO character device ioctls first introduced in Linux v4.8,
> > > > > as well as those added in subsequent kernel releases up to Linux v5.7.
> > > > >
> > > > > Signed-off-by: Kent Gibson <warthog618 at gmail.com>
> > > > [...]
> > >
> > > [...]
> > > > > + PRINT_FIELD_U("{", info, line_offset);
> > > > > + if (!tcp->u_rval) {
> > > > > + tprints(", flags=");
> > > > > + printflags(gpio_line_flags, info.flags, "GPIOLINE_FLAG_???");
> > > > > + PRINT_FIELD_CSTRING(", ", info, name);
> > > > > + PRINT_FIELD_CSTRING(", ", info, consumer);
> > > > > + }
> > > > > + tprints("}");
> > > >
> > > > Both GPIO_GET_LINEINFO_IOCTL and GPIO_GET_LINEINFO_WATCH_IOCTL are
> > > > read-write ioctls, that is, the kernel reads struct gpioline_info on
> > > > entering syscall and writes it back on exiting. A comprehensive decoder
> > > > would do the same, i.e. print the relevant parts of the structure both on
> > > > entering and on exiting. There would be no need to use
> > > > umove_or_printaddr_ignore_syserror and ignore syscall errors.
> > > >
> > >
> > > Sorry I don't have prompt replies for your other comments - this code has
> > > been sitting in my working tree for months as I was having problems
> > > mailing to the list back then so I'll have to spend some time recapturing
> > > what I was thinking while writing it.
> > >
> > > A decoder can't be comprehensive if it is only decoding relevant parts ;-).
> > >
> > > So should the decoder decode the full struct both ways, or just the fields
> > > the kernel reads on the way in and the fields it wrote on the way out?
> >
> > There is no need to print the full struct two times, only those fields
> > that could be accessed by the kernel.
>
> Is this the sort of thing you are after for the IOWRs?:
>
> [pid 107] ioctl(3, GPIO_GET_LINEINFO_IOCTL, {line_offset=2} => {flags=GPIOLINE_FLAG_KERNEL, name="gpio-mockup-A-2", consumer="test-as-is"}) = 0
>
> I'm using this idiom to decode it:
>
> static int
> print_gpioline_info(struct tcb *const tcp, const kernel_ulong_t arg)
> {
> struct gpioline_info info;
>
> if (entering(tcp)) {
> tprints(", ");
> if (umove_or_printaddr(tcp, arg, &info))
> return RVAL_IOCTL_DECODED;
>
> PRINT_FIELD_U("{", info, line_offset);
> tprints("}");
> return 0;
> }
>
> /* exiting */
> if (!syserror(tcp) && !umove(tcp, arg, &info)) {
> tprints(" => {flags=");
> printflags(gpio_line_flags, info.flags, "GPIOLINE_FLAG_???");
> PRINT_FIELD_CSTRING(", ", info, name);
> PRINT_FIELD_CSTRING(", ", info, consumer);
> tprints("}");
> }
>
> return RVAL_IOCTL_DECODED;
> }
Yes, and you can use PRINT_FIELD_FLAGS macro as well.
> If that works for you I'll rework the rest similarly.
Thanks,
--
ldv
More information about the Strace-devel
mailing list