diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2021-08-17 19:35:48 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2021-09-19 13:51:35 -0700 |
commit | a93d9e03a31ec14405cb3a09aa95413b67067380 (patch) | |
tree | 532f865c7241b3cf363433272e5923c468ea2969 /elf/tst-dlmopen4.c | |
parent | 885762aa31d75de8b9fea4c0e2e372b582d4c548 (diff) | |
download | glibc-a93d9e03a31ec14405cb3a09aa95413b67067380.tar.gz glibc-a93d9e03a31ec14405cb3a09aa95413b67067380.tar.xz glibc-a93d9e03a31ec14405cb3a09aa95413b67067380.zip |
Extend struct r_debug to support multiple namespaces [BZ #15971]
Glibc does not provide an interface for debugger to access libraries loaded in multiple namespaces via dlmopen. The current rtld-debugger interface is described in the file: elf/rtld-debugger-interface.txt under the "Standard debugger interface" heading. This interface only provides access to the first link-map (LM_ID_BASE). 1. Bump r_version to 2 when multiple namespaces are used. This triggers the GDB bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28236 2. Add struct r_debug_extended to extend struct r_debug into a linked-list, where each element correlates to an unique namespace. 3. Initialize the r_debug_extended structure. Bump r_version to 2 for the new namespace and add the new namespace to the namespace linked list. 4. Add _dl_debug_update to return the address of struct r_debug' of a namespace. 5. Add a hidden symbol, _r_debug_extended, for struct r_debug_extended. 6. Provide the symbol, _r_debug, with size of struct r_debug, as an alias of _r_debug_extended, for programs which reference _r_debug. This fixes BZ #15971. Reviewed-by: Florian Weimer <fweimer@redhat.com>
Diffstat (limited to 'elf/tst-dlmopen4.c')
-rw-r--r-- | elf/tst-dlmopen4.c | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/elf/tst-dlmopen4.c b/elf/tst-dlmopen4.c new file mode 100644 index 0000000000..3fe150e50b --- /dev/null +++ b/elf/tst-dlmopen4.c @@ -0,0 +1,72 @@ +/* Test struct r_debug_extended via DT_DEBUG. + Copyright (C) 2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#include <stdio.h> +#include <link.h> +#include <stdlib.h> +#include <string.h> +#include <gnu/lib-names.h> +#include <support/xdlfcn.h> +#include <support/check.h> +#include <support/test-driver.h> + +#ifndef ELF_MACHINE_GET_R_DEBUG +# define ELF_MACHINE_GET_R_DEBUG(d) \ + (__extension__ ({ \ + struct r_debug_extended *debug; \ + if ((d)->d_tag == DT_DEBUG) \ + debug = (struct r_debug_extended *) (d)->d_un.d_ptr; \ + else \ + debug = NULL; \ + debug; })) +#endif + +static int +do_test (void) +{ + ElfW(Dyn) *d; + struct r_debug_extended *debug = NULL; + + for (d = _DYNAMIC; d->d_tag != DT_NULL; ++d) + { + debug = ELF_MACHINE_GET_R_DEBUG (d); + if (debug != NULL) + break; + } + + TEST_VERIFY_EXIT (debug != NULL); + TEST_COMPARE (debug->base.r_version, 1); + TEST_VERIFY_EXIT (debug->r_next == NULL); + + void *h = xdlmopen (LM_ID_NEWLM, "$ORIGIN/tst-dlmopen1mod.so", + RTLD_LAZY); + + TEST_COMPARE (debug->base.r_version, 2); + 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_COMPARE_STRING (name, "tst-dlmopen1mod.so"); + + xdlclose (h); + + return 0; +} + +#include <support/test-driver.c> |