|
Message-ID: <CAMe9rOrxnZCRQkBpC8MjsufC7os0-dGUqz36dpu-L4JeuZtK7Q@mail.gmail.com> Date: Mon, 6 Sep 2021 06:19:36 -0700 From: "H.J. Lu" <hjl.tools@...il.com> To: Florian Weimer <fweimer@...hat.com> Cc: GNU C Library <libc-alpha@...rceware.org>, GDB <gdb@...rceware.org>, libc-coord@...ts.openwall.com, Daniel Walker <danielwa@...co.com> Subject: Re: [PATCH v6 2/2] Extend struct r_debug to support multiple namespaces On Mon, Sep 6, 2021 at 2:39 AM Florian Weimer <fweimer@...hat.com> wrote: > > * H. J. Lu: > > > +* The r_version update in the debugger interface makes the glibc binary > > + incompatible with GDB binaries built without the following commits: > > + > > + c0154a4a21a gdb: Don't assume r_ldsomap when r_version > 1 on Linux > > + 4eb629d50d4 gdbserver: Check r_version < 1 for Linux debugger interface > > Does this incompatibility happen even if audit modules and dlmopen are > not used? Yes. > > +ifeq ($(build-shared),yes) > > +# dl-debug-compat-symbols.os and dl-debug-compat-symbols.o are assembly > > +# codes included in dl-debug-symbols.S. > > +generated += dl-debug-compat-symbols.os dl-debug-compat-symbols.o > > + > > +libof-dl-debug-compat-symbols = rtld > > + > > +$(objpfx)dl-debug-compat-symbols.os: dl-debug-symbols-gen.c > > + $(compile-command.c) -S > > + > > +$(objpfx)dl-debug-compat-symbols.o: dl-debug-symbols-gen.c > > + $(compile-command.c) -S > > + > > +$(objpfx)dl-debug-symbols.os: $(objpfx)dl-debug-compat-symbols.os > > +$(objpfx)dl-debug-symbols.o: $(objpfx)dl-debug-compat-symbols.o > > +endif > > This puts the assember output from the compiler through the > preprocessor. That seems to be brittle. I think you would have to > preprocess the manually written fragment separately. > > However, I think we are overdesigning things here. The following in > dl-debug-symbols-gen.c should work (and the file should have a different > name then): > > /* Alias _r_debug to a prefix of _r_debug_extended. */ > asm (".set _r_debug, _r_debug_extended\n\t" > ".type _r_debug, %object\n\t" > ".symver _r_debug_extended, _r_debug@@" FIRST_VERSION_ld__r_debug_STRING); > #if __WORDSIZE == 64 > _Static_assert (sizeof (struct r_debug) == 40, "sizeof (struct r_debug)"); > asm (".size _r_debug, 40"); > #else > _Static_assert (sizeof (struct r_debug) == 20, "sizeof (struct r_debug)"); > asm (".size _r_debug, 20"); > #endif > > It's not exactly pretty, but at least it's obvious what is going on. > (Extended asm with input operands is not supported outside of functions.) This was the first thing I tried and it didn't work: [hjl@...-cfl-2 tmp]$ cat foo.s .set _r_debug, _r_debug_extended .globl _r_debug .type _r_debug, %object .size _r_debug, 40 .data .type _r_debug_extended, %object .size _r_debug_extended, 48 .globl _r_debug_extended _r_debug_extended: .zero 48 [hjl@...-cfl-2 tmp]$ gcc -c foo.s [hjl@...-cfl-2 tmp]$ readelf -sW foo.o | grep _r_debug 1: 0000000000000000 48 OBJECT GLOBAL DEFAULT 2 _r_debug 2: 0000000000000000 48 OBJECT GLOBAL DEFAULT 2 _r_debug_extended [hjl@...-cfl-2 tmp]$ > And it's not that the size of struct _r_debug is going to change. > > > diff --git a/elf/dl-close.c b/elf/dl-close.c > > index f39001cab9..43873d2543 100644 > > --- a/elf/dl-close.c > > +++ b/elf/dl-close.c > > @@ -709,6 +709,27 @@ _dl_close_worker (struct link_map *map, bool force) > > assert (nsid != LM_ID_BASE); > > ns->_ns_loaded = imap->l_next; > > > > + if (ns->_ns_loaded == NULL) > > + { > > + /* Remove the empty namespace from the namespace linked > > + list. */ > > + struct r_debug_extended **pp, *p; > > + > > + for (pp = &_r_debug_extended.r_next; > > + (p = *pp) != NULL; > > + pp = &p->r_next) > > + if (p == &ns->_ns_debug) > > + { > > + /* Remove the empty namespace. */ > > + *pp = p->r_next; > > + > > + /* Clear r_version to indicate that it is > > + unused. */ > > + p->base.r_version = 0; > > + break; > > + } > > + } > > Is this necessary? It makes concurrent access to the list harder and When _dl_close_worker is called, it holds GL(dl_load_lock). Why does this change make concurrent access harder? > does not save any memory. _dl_debug_initialize can be called multiple times with the same namespace. Only the first time we need to initialize the namespace. I use base.r_version == 0 to check if I need to initialize the namespace and put it on the linked list. > > > diff --git a/elf/rtld-debugger-interface.txt b/elf/rtld-debugger-interface.txt > > index 61bc99e4b0..f6aaa28706 100644 > > --- a/elf/rtld-debugger-interface.txt > > +++ b/elf/rtld-debugger-interface.txt > > @@ -9,6 +9,9 @@ structure can be found. > > > > The r_debug structure contains (amongst others) the following fields: > > > > + int r_version: > > + Version number for this protocol. It should be greater than 0. > > + > > It seems to me that r_version starts out as 0 and is initialized later. > Maybe this should be described here, and tested in the test case. r_version is never zero (initialized by _dl_debug_initialize) when the namespace is in use. The unused namespace isn't accessible from user programs. > Thanks, > Florian > Thanks. -- H.J.
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.