Re: [RFC/RFA] Target vectors for native Linux targets

Mark Kettenis
2005-08-20T22:15:07Z

> From: Ulrich Weigand <uweigand@de.ibm.com>
> Date: Fri, 19 Aug 2005 02:51:24 +0200 (CEST)
>
> Mark Kettenis wrote:
>
> > Sorry, but you're not supposed to add anything to nm.h files anymore.
> > Instead you should add things to the target vector. Take a look at
> > inf-ttrace.c on how to do this.
> >
> > This may be hard to do at the moment, since the target vector stuff
> > for native Linux targets is a bit of a mess. That really needs to be
> > fixed!
>
> Some time ago I attempted to do this, but never got around to submitting
> the patches. This looks like a good opportunity to resurrect them ...
>
> One problem with the conversion is that I wouldn't want to have to
> convert all the various Linux subtargets at the same time. It's a
> lot of work, and I'm unable to test most of those platforms.

Yeah, that's a general problem. These days, there doesn't seem to be
anyone who feels responsible for gdb on more than one or two different
Linux platforms.

> Thus I've thought of a way to stage the conversion:
>
> - First, linux-nat.c is changed to support either the old-style target
> (overriding deprecated_child_ops entries) or new-style targets
> implemented via a linux_target () routine. The new style is selected
> by defining USE_LINUX_TARGET in the nm file.
>

Hmm, it would be preferable to have it the other way around, since
that would make eliminating the nm-linux.h files, but I can see why
you did it this way. In the end we might just define USE_LINUX_TARGET
if GDB_NM_FILE isn't defined. So it's not really important. I've
added some more comments on the patch inline.

>
> - Then, Linux subtargets can be converted one by one to use the new style.
> I'd hope the various maintainers would take on their platforms.

I can take care of i386/amd64 and sparc.

> In a subsequent mail I'll send a patch implementing this step for s390.

Cool.

> - Once all targets have been converted, the remains of old-style support
> (and USE_LINUX_TARGET) are removed frome linux-nat.c.

I think we should set a date for removal of that code; say six months
after we check this stuff in. Any Linux target that hasn't been
converted by then will be marked as broken and eventually removed.
>
> The patch below implements the first step. By itself, it shouldn't change
> the behaviour at all. The changes are relatively mechanical; in particular
> the way the miscellaneous thread and process stratum target layers are
> related to each other isn't changed at all -- the new style simply uses
> a target generated by linux_target () instead of deprecated_child_ops
> as process stratum.
>
> To avoid calling child_xfer_memory I had to switch to using xfer_partial
> instead. This change also bubbled up to linux-thread-db.c. (But seeing
> as xfer_memory is deprecated, that's probably a good idea anyway.)

Indeed. When I did conversions in the past the
depreceated_xfer_memory always came back to haunt me, so we have to be
a bit careful. Did you test your patch on another Linux target that
wasn't converted yet?

> What do you think of this approach?

I think this should be committed. However, since Daniel did some work
in this area before, I'd like to give him the opportunity to comment.
Can you keep this patch on the backburner until he's back?

> Index: gdb/linux-nat.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/linux-nat.c,v
> retrieving revision 1.31
> diff -c -p -r1.31 linux-nat.c
> *** gdb/linux-nat.c 9 Aug 2005 16:35:45 -0000 1.31
> --- gdb/linux-nat.c 18 Aug 2005 23:45:50 -0000

[snip]

> + /* Create a prototype generic Linux target. The client can override
> + it with local methods. */
> +
> + struct target_ops *
> + linux_target (void)
> + {
> + struct target_ops *t;
> +
> + t = inf_ptrace_target ();
> + t->to_wait = child_wait;
> + t->to_kill = kill_inferior;
> + t->to_insert_fork_catchpoint = child_insert_fork_catchpoint;
> + t->to_insert_vfork_catchpoint = child_insert_vfork_catchpoint;
> + t->to_insert_exec_catchpoint = child_insert_exec_catchpoint;
> + t->to_pid_to_exec_file = child_pid_to_exec_file;
> + t->to_post_startup_inferior = child_post_startup_inferior;
> + t->to_post_attach = child_post_attach;
> + t->to_follow_fork = child_follow_fork;
> + t->to_find_memory_regions = linux_nat_find_memory_regions;
> + t->to_make_corefile_notes = linux_nat_make_corefile_notes;
> +
> + inf_ptrace_xfer_partial = t->to_xfer_partial;
> + t->to_xfer_partial = linux_xfer_partial;
> +
> + linux_ops = t;
> + return t;
> + }
> + #endif /* USE_LINUX_TARGET */

Daniels earlier attempt had linux_target accept a `struct target_ops
*' as an argument to serve as an alternative for a plain
inf_ptrace_target(). I thought that was necessary for i386 and sparc
Linux targets, but I think I've convinced myself that it isn't.