mirror of
git://sourceware.org/git/glibc.git
synced 2024-11-27 03:41:23 +08:00
elf: Relocate libc.so early during startup and dlmopen (bug 31083)
This makes it more likely that objects without dependencies can use IFUNC resolvers in libc.so. Reviewed-by: Carlos O'Donell <carlos@redhat.com>
This commit is contained in:
parent
a74c2e1cbc
commit
78ca44da01
21
elf/Makefile
21
elf/Makefile
@ -433,6 +433,8 @@ tests += \
|
||||
tst-nodelete-dlclose \
|
||||
tst-nodelete-opened \
|
||||
tst-nodelete2 \
|
||||
tst-nodeps1 \
|
||||
tst-nodeps2 \
|
||||
tst-noload \
|
||||
tst-non-directory-path \
|
||||
tst-null-argv \
|
||||
@ -863,6 +865,8 @@ modules-names += \
|
||||
tst-nodelete-dlclose-plugin \
|
||||
tst-nodelete-opened-lib \
|
||||
tst-nodelete2mod \
|
||||
tst-nodeps1-mod \
|
||||
tst-nodeps2-mod \
|
||||
tst-non-directory-mod \
|
||||
tst-null-argv-lib \
|
||||
tst-p_alignmod-base \
|
||||
@ -1030,6 +1034,8 @@ modules-names-nobuild += \
|
||||
tst-audit24bmod1 \
|
||||
tst-audit24bmod2 \
|
||||
tst-big-note-lib \
|
||||
tst-nodeps1-mod \
|
||||
tst-nodeps2-mod \
|
||||
tst-ro-dynamic-mod \
|
||||
# modules-names-nobuild
|
||||
|
||||
@ -3009,3 +3015,18 @@ tst-env-setuid-ARGS = -- $(host-test-program-cmd)
|
||||
|
||||
# Reuse a module with a SONAME, to specific as the LD_PROFILE.
|
||||
$(objpfx)tst-env-setuid: $(objpfx)tst-sonamemove-runmod2.so
|
||||
|
||||
# The object tst-nodeps1-mod.so has no explicit dependencies on libc.so.
|
||||
$(objpfx)tst-nodeps1-mod.so: $(objpfx)tst-nodeps1-mod.os
|
||||
$(LINK.o) -nostartfiles -nostdlib -shared -o $@ $^
|
||||
tst-nodeps1.so-no-z-defs = yes
|
||||
# Link libc.so before the test module with the IFUNC resolver reference.
|
||||
LDFLAGS-tst-nodeps1 = $(common-objpfx)libc.so $(objpfx)tst-nodeps1-mod.so
|
||||
$(objpfx)tst-nodeps1: $(objpfx)tst-nodeps1-mod.so
|
||||
# Reuse the tst-nodeps1 module. Link libc.so before the test module
|
||||
# with the IFUNC resolver reference.
|
||||
$(objpfx)tst-nodeps2-mod.so: $(common-objpfx)libc.so \
|
||||
$(objpfx)tst-nodeps1-mod.so $(objpfx)tst-nodeps2-mod.os
|
||||
$(LINK.o) -Wl,--no-as-needed -nostartfiles -nostdlib -shared -o $@ $^
|
||||
$(objpfx)tst-nodeps2.out: \
|
||||
$(objpfx)tst-nodeps1-mod.so $(objpfx)tst-nodeps2-mod.so
|
||||
|
@ -708,6 +708,17 @@ dl_open_worker_begin (void *a)
|
||||
them. However, such relocation dependencies in IFUNC resolvers
|
||||
are undefined anyway, so this is not a problem. */
|
||||
|
||||
/* Ensure that libc is relocated first. This helps with the
|
||||
execution of IFUNC resolvers in libc, and matters only to newly
|
||||
created dlmopen namespaces. Do not do this for static dlopen
|
||||
because libc has relocations against ld.so, which may not have
|
||||
been relocated at this point. */
|
||||
#ifdef SHARED
|
||||
if (GL(dl_ns)[args->nsid].libc_map != NULL)
|
||||
_dl_open_relocate_one_object (args, r, GL(dl_ns)[args->nsid].libc_map,
|
||||
reloc_mode, &relocation_in_progress);
|
||||
#endif
|
||||
|
||||
for (unsigned int i = last; i-- > first; )
|
||||
_dl_open_relocate_one_object (args, r, new->l_initfini[i], reloc_mode,
|
||||
&relocation_in_progress);
|
||||
|
10
elf/rtld.c
10
elf/rtld.c
@ -2272,11 +2272,17 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||
objects. We do not re-relocate the dynamic linker itself in this
|
||||
loop because that could result in the GOT entries for functions we
|
||||
call being changed, and that would break us. It is safe to relocate
|
||||
the dynamic linker out of order because it has no copy relocs (we
|
||||
know that because it is self-contained). */
|
||||
the dynamic linker out of order because it has no copy relocations.
|
||||
Likewise for libc, which is relocated early to ensure that IFUNC
|
||||
resolvers in libc work. */
|
||||
|
||||
int consider_profiling = GLRO(dl_profile) != NULL;
|
||||
|
||||
if (GL(dl_ns)[LM_ID_BASE].libc_map != NULL)
|
||||
_dl_relocate_object (GL(dl_ns)[LM_ID_BASE].libc_map,
|
||||
GL(dl_ns)[LM_ID_BASE].libc_map->l_scope,
|
||||
GLRO(dl_lazy) ? RTLD_LAZY : 0, consider_profiling);
|
||||
|
||||
/* If we are profiling we also must do lazy reloaction. */
|
||||
GLRO(dl_lazy) |= consider_profiling;
|
||||
|
||||
|
25
elf/tst-nodeps1-mod.c
Normal file
25
elf/tst-nodeps1-mod.c
Normal file
@ -0,0 +1,25 @@
|
||||
/* Test module with no libc.so dependency and string function references.
|
||||
Copyright (C) 2023 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 <string.h>
|
||||
|
||||
/* Some references to libc symbols which are likely to have IFUNC
|
||||
resolvers. If they do not, this module does not exercise bug 31083. */
|
||||
void *memcpy_pointer = memcpy;
|
||||
void *memmove_pointer = memmove;
|
||||
void *memset_pointer = memset;
|
23
elf/tst-nodeps1.c
Normal file
23
elf/tst-nodeps1.c
Normal file
@ -0,0 +1,23 @@
|
||||
/* Test initially loaded module with implicit libc.so dependency (bug 31083).
|
||||
Copyright (C) 2023 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/>. */
|
||||
|
||||
/* Testing happens before main. */
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
}
|
1
elf/tst-nodeps2-mod.c
Normal file
1
elf/tst-nodeps2-mod.c
Normal file
@ -0,0 +1 @@
|
||||
/* Empty test module which depends on tst-nodeps1-mod.so. */
|
29
elf/tst-nodeps2.c
Normal file
29
elf/tst-nodeps2.c
Normal file
@ -0,0 +1,29 @@
|
||||
/* Test dlmopen with implicit libc.so dependency (bug 31083).
|
||||
Copyright (C) 2023 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 <support/xdlfcn.h>
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
void *handle = xdlmopen (LM_ID_NEWLM, "tst-nodeps2-mod.so", RTLD_NOW);
|
||||
xdlclose (handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include <support/test-driver.c>
|
Loading…
Reference in New Issue
Block a user