Re: [PATCH v8 1/1] Extend struct r_debug to support multiple namespaces [BZ #15971]

"H.J. Lu via Gdb" <[email protected]>
Newsgroups gmane.comp.gdb.devel,gmane.comp.lib.glibc.alpha
Message-ID <CAMe9rOrnPcvWZ1fu0Pmvt6-yHNQhObV2EKhgGFTP2+9xKziy-Q@mail.gmail.com>
On Fri, Sep 10, 2021 at 11:59 AM Florian Weimer <[email protected]> wrote:
>
> * H. J. Lu:
>
> > diff --git a/elf/link.h b/elf/link.h
> > index ff3a85c847..a297318236 100644
> > --- a/elf/link.h
> > +++ b/elf/link.h
> > @@ -34,14 +34,13 @@
>
> > -/* This is the instance of that structure used by the dynamic linker.  */
> > +/* This is the compatibility symbol of that structure provided by the
> > +   dynamic linker.  */
> >  extern struct r_debug _r_debug;
>
> I don't think we should say “compatibility symbol” in a public header.

I will remove "compatibility".

> Can we move GNAT off this symbol and deprecate it at least?

There is no harm in keeping it.

> > +/* The extended rendezvous structure used by the run-time dynamic linker
> > +   to communicate details of shared object loading to the debugger.  If
> > +   the executable's dynamic section has a DT_DEBUG element, the run-time
> > +   linker sets that element's value to the address where this structure
> > +   can be found.  */
> > +
> > +struct r_debug_extended
> > +  {
> > +    struct r_debug base;
> > +
> > +    /* The following field is added by r_version == 2.  */
> > +
> > +    /* Link to the next r_debug_extended structure.  Each r_debug_extended
> > +       structure represents a different namespace.  The first
> > +       r_debug_extended structure is for the default namespace.  */
> > +    struct r_debug_extended *r_next;
> > +  };
> > +
> >  /* This symbol refers to the "dynamic structure" in the `.dynamic' section
> >     of whatever module refers to `_DYNAMIC'.  So, to find its own
> > -   `struct r_debug', a program could do:
> > +   `struct r_debug_extended', a program could do:
> >       for (dyn = _DYNAMIC; dyn->d_tag != DT_NULL; ++dyn)
> >         if (dyn->d_tag == DT_DEBUG)
> > -      r_debug = (struct r_debug *) dyn->d_un.d_ptr;
> > -   */
> > +      r_debug_extended = (struct r_debug_extended *) dyn->d_un.d_ptr;
> > + */
> >  extern ElfW(Dyn) _DYNAMIC[];
>
> What about shared objects?  How can they find r_debug_extended?  Should
> they just make sure they have DT_DEBUG in their dynamic section?

Linker generates DT_DEBUG only in the executable.   dl_iterate_phdr can be
used to locate DT_DEBUG in the executable.

>
> Calling getauxval (AT_PHDR) has a relocation dependencies, which I
> expect some consumers want to avoid.
>
> > +Extension to the r_debug structure
> > +==================================
> > +
> > +The r_debug_extended structure is an extension of the r_debug interface.
> > +If r_version is 2, one additional field is available:
> > +
> > +  struct r_debug_extended *r_next;
> > +    Link to the next r_debug_extended structure.  Each r_debug_extended
> > +    structure represents a different namespace.  The first r_debug_extended
> > +    structure is for the default namespace.
>
> I think this should say how a reader can determine which list elements
> are in fact active.

I will update it.

>
> > diff --git a/elf/tst-dlmopen4.c b/elf/tst-dlmopen4.c
> > new file mode 100644
> > index 0000000000..7a6c502e8c
> > --- /dev/null
> > +++ b/elf/tst-dlmopen4.c
>
> > +static int
> > +do_test (void)
> > +{
> > +  void *h = xdlmopen (LM_ID_NEWLM, "$ORIGIN/tst-dlmopen1mod.so",
> > +                   RTLD_LAZY);
>
> I think this should test that r_version is 1 before the dlmopen call.

I will add the test.

> > +
> > +  int status = EXIT_FAILURE;
> > +  ElfW(Dyn) *d;
> > +  for (d = _DYNAMIC; d->d_tag != DT_NULL; ++d)
> > +    {
> > +      struct r_debug_extended *debug = ELF_MACHINE_GET_R_DEBUG (d);
> > +      if (debug != NULL)
> > +     {
> > +       TEST_VERIFY_EXIT (debug->base.r_version == 2);
>
> You could use TEST_COMPARE.

I will fix it.

>
> > +       TEST_VERIFY_EXIT (debug->r_next != NULL);
> > +       TEST_VERIFY_EXIT (debug->r_next->r_next == NULL);
> > +       TEST_VERIFY_EXIT (debug->r_next->base.r_map != NULL);
> > +       TEST_VERIFY_EXIT (debug->r_next->base.r_map->l_name != NULL);
> > +       const char *name = basename (debug->r_next->base.r_map->l_name);
> > +       TEST_VERIFY_EXIT (strcmp (name, "tst-dlmopen1mod.so") == 0);
>
> You could use TEST_COMPARE_STRING.

I will fix it.

> Sorry, I have not reviewed the actual mechanics of the patch.
>
> Thanks,
> Florian
>

Thanks.

-- 
H.J.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.