glibc/elf/setup-vdso.h

114 lines
4.0 KiB
C
Raw Normal View History

/* Set up the data structures for the system-supplied DSO.
Copyright (C) 2012-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
Prefer https to http for gnu.org and fsf.org URLs Also, change sources.redhat.com to sourceware.org. This patch was automatically generated by running the following shell script, which uses GNU sed, and which avoids modifying files imported from upstream: sed -ri ' s,(http|ftp)(://(.*\.)?(gnu|fsf|sourceware)\.org($|[^.]|\.[^a-z])),https\2,g s,(http|ftp)(://(.*\.)?)sources\.redhat\.com($|[^.]|\.[^a-z]),https\2sourceware.org\4,g ' \ $(find $(git ls-files) -prune -type f \ ! -name '*.po' \ ! -name 'ChangeLog*' \ ! -path COPYING ! -path COPYING.LIB \ ! -path manual/fdl-1.3.texi ! -path manual/lgpl-2.1.texi \ ! -path manual/texinfo.tex ! -path scripts/config.guess \ ! -path scripts/config.sub ! -path scripts/install-sh \ ! -path scripts/mkinstalldirs ! -path scripts/move-if-change \ ! -path INSTALL ! -path locale/programs/charmap-kw.h \ ! -path po/libc.pot ! -path sysdeps/gnu/errlist.c \ ! '(' -name configure \ -execdir test -f configure.ac -o -f configure.in ';' ')' \ ! '(' -name preconfigure \ -execdir test -f preconfigure.ac ';' ')' \ -print) and then by running 'make dist-prepare' to regenerate files built from the altered files, and then executing the following to cleanup: chmod a+x sysdeps/unix/sysv/linux/riscv/configure # Omit irrelevant whitespace and comment-only changes, # perhaps from a slightly-different Autoconf version. git checkout -f \ sysdeps/csky/configure \ sysdeps/hppa/configure \ sysdeps/riscv/configure \ sysdeps/unix/sysv/linux/csky/configure # Omit changes that caused a pre-commit check to fail like this: # remote: *** error: sysdeps/powerpc/powerpc64/ppc-mcount.S: trailing lines git checkout -f \ sysdeps/powerpc/powerpc64/ppc-mcount.S \ sysdeps/unix/sysv/linux/s390/s390-64/syscall.S # Omit change that caused a pre-commit check to fail like this: # remote: *** error: sysdeps/sparc/sparc64/multiarch/memcpy-ultra3.S: last line does not end in newline git checkout -f sysdeps/sparc/sparc64/multiarch/memcpy-ultra3.S
2019-09-07 05:40:42 +00:00
<https://www.gnu.org/licenses/>. */
static inline void __attribute__ ((always_inline))
setup_vdso (struct link_map *main_map __attribute__ ((unused)),
struct link_map ***first_preload __attribute__ ((unused)))
{
2013-03-01 22:44:44 +00:00
#ifdef NEED_DL_SYSINFO_DSO
if (GLRO(dl_sysinfo_dso) == NULL)
return;
/* Do an abridged version of the work _dl_map_object_from_fd would do
to map in the object. It's already mapped and prelinked (and
better be, since it's read-only and so we couldn't relocate it).
We just want our data structures to describe it as if we had just
mapped and relocated it normally. */
struct link_map *l = _dl_new_object ((char *) "", "", lt_library, NULL,
0, LM_ID_BASE);
if (__glibc_likely (l != NULL))
{
l->l_phdr = ((const void *) GLRO(dl_sysinfo_dso)
+ GLRO(dl_sysinfo_dso)->e_phoff);
l->l_phnum = GLRO(dl_sysinfo_dso)->e_phnum;
for (uint_fast16_t i = 0; i < l->l_phnum; ++i)
{
const ElfW(Phdr) *const ph = &l->l_phdr[i];
if (ph->p_type == PT_DYNAMIC)
{
l->l_ld = (void *) ph->p_vaddr;
l->l_ldnum = ph->p_memsz / sizeof (ElfW(Dyn));
l->l_ld_readonly = (ph->p_flags & PF_W) == 0;
}
else if (ph->p_type == PT_LOAD)
{
if (! l->l_addr)
l->l_addr = ph->p_vaddr;
if (ph->p_vaddr + ph->p_memsz >= l->l_map_end)
l->l_map_end = ph->p_vaddr + ph->p_memsz;
if ((ph->p_flags & PF_X)
&& ph->p_vaddr + ph->p_memsz >= l->l_text_end)
l->l_text_end = ph->p_vaddr + ph->p_memsz;
}
else
/* There must be no TLS segment. */
assert (ph->p_type != PT_TLS);
}
l->l_map_start = (ElfW(Addr)) GLRO(dl_sysinfo_dso);
l->l_addr = l->l_map_start - l->l_addr;
l->l_map_end += l->l_addr;
l->l_text_end += l->l_addr;
l->l_ld = (void *) ((ElfW(Addr)) l->l_ld + l->l_addr);
elf: Fix dynamic-link.h usage on rtld.c The 4af6982e4c fix does not fully handle RTLD_BOOTSTRAP usage on rtld.c due two issues: 1. RTLD_BOOTSTRAP is also used on dl-machine.h on various architectures and it changes the semantics of various machine relocation functions. 2. The elf_get_dynamic_info() change was done sideways, previously to 490e6c62aa get-dynamic-info.h was included by the first dynamic-link.h include *without* RTLD_BOOTSTRAP being defined. It means that the code within elf_get_dynamic_info() that uses RTLD_BOOTSTRAP is in fact unused. To fix 1. this patch now includes dynamic-link.h only once with RTLD_BOOTSTRAP defined. The ELF_DYNAMIC_RELOCATE call will now have the relocation fnctions with the expected semantics for the loader. And to fix 2. part of 4af6982e4c is reverted (the check argument elf_get_dynamic_info() is not required) and the RTLD_BOOTSTRAP pieces are removed. To reorganize the includes the static TLS definition is moved to its own header to avoid a circular dependency (it is defined on dynamic-link.h and dl-machine.h requires it at same time other dynamic-link.h definition requires dl-machine.h defitions). Also ELF_MACHINE_NO_REL, ELF_MACHINE_NO_RELA, and ELF_MACHINE_PLT_REL are moved to its own header. Only ancient ABIs need special values (arm, i386, and mips), so a generic one is used as default. The powerpc Elf64_FuncDesc is also moved to its own header, since csu code required its definition (which would require either include elf/ folder or add a full path with elf/). Checked on x86_64, i686, aarch64, armhf, powerpc64, powerpc32, and powerpc64le. Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
2021-10-13 12:49:34 +00:00
elf_get_dynamic_info (l);
_dl_setup_hash (l);
l->l_relocated = 1;
/* The vDSO is always used. */
l->l_used = 1;
/* Initialize l_local_scope to contain just this map. This allows
the use of dl_lookup_symbol_x to resolve symbols within the vdso.
So we create a single entry list pointing to l_real as its only
element */
l->l_local_scope[0]->r_nlist = 1;
l->l_local_scope[0]->r_list = &l->l_real;
/* Now that we have the info handy, use the DSO image's soname
so this object can be looked up by name. */
if (l->l_info[DT_SONAME] != NULL)
{
char *dsoname = ((char *) D_PTR (l, l_info[DT_STRTAB])
+ l->l_info[DT_SONAME]->d_un.d_val);
l->l_libname->name = dsoname;
l->l_name = dsoname;
}
/* Add the vDSO to the object list. */
_dl_add_to_namespace_list (l, LM_ID_BASE);
Remove IS_IN_rtld Replace with IS_IN (rtld). Generated code is unchanged on x86_64. * elf/Makefile (CPPFLAGS-.os): Remove IS_IN_rtld. * elf/dl-open.c: Use IS_IN (rtld) instead if IS_IN_rtld. * elf/rtld-Rules: Likewise. * elf/setup-vdso.h: Likewise. * include/assert.h: Likewise. * include/bits/stdlib-float.h: Likewise. * include/errno.h: Likewise. * include/sys/stat.h: Likewise. * include/unistd.h: Likewise. * sysdeps/aarch64/setjmp.S: Likewise. * sysdeps/alpha/setjmp.S: Likewise. * sysdeps/arm/__longjmp.S: Likewise. * sysdeps/arm/aeabi_unwind_cpp_pr1.c: Likewise. * sysdeps/arm/setjmp.S: Likewise. * sysdeps/arm/sysdep.h: Likewise. * sysdeps/generic/_itoa.h: Likewise. * sysdeps/generic/dl-sysdep.h: Likewise. * sysdeps/generic/ldsodefs.h: Likewise. * sysdeps/i386/dl-tls.h: Likewise. * sysdeps/i386/setjmp.S: Likewise. * sysdeps/m68k/setjmp.c: Likewise. * sysdeps/mach/hurd/dl-execstack.c: Likewise. * sysdeps/mach/hurd/opendir.c: Likewise. * sysdeps/posix/getcwd.c: Likewise. * sysdeps/posix/opendir.c: Likewise. * sysdeps/posix/profil.c: Likewise. * sysdeps/powerpc/dl-procinfo.h: Likewise. * sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S: Likewise. * sysdeps/powerpc/powerpc32/fpu/setjmp-common.S: Likewise. * sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h: Likewise. * sysdeps/powerpc/powerpc32/setjmp-common.S: Likewise. * sysdeps/powerpc/powerpc64/__longjmp-common.S: Likewise. * sysdeps/powerpc/powerpc64/setjmp-common.S: Likewise. * sysdeps/s390/dl-tls.h: Likewise. * sysdeps/s390/s390-32/setjmp.S: Likewise. * sysdeps/s390/s390-64/setjmp.S: Likewise. * sysdeps/sh/sh3/setjmp.S: Likewise. * sysdeps/sh/sh4/setjmp.S: Likewise. * sysdeps/unix/alpha/sysdep.h: Likewise. * sysdeps/unix/arm/sysdep.S: Likewise. * sysdeps/unix/i386/sysdep.S: Likewise. * sysdeps/unix/sysv/linux/aarch64/sysdep.h: Likewise. * sysdeps/unix/sysv/linux/getcwd.c: Likewise. * sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.h: Likewise. * sysdeps/unix/sysv/linux/i386/lowlevellock.h: Likewise. * sysdeps/unix/sysv/linux/i386/sysdep.h: Likewise. * sysdeps/unix/sysv/linux/ia64/lowlevellock.h: Likewise. * sysdeps/unix/sysv/linux/ia64/setjmp.S: Likewise. * sysdeps/unix/sysv/linux/ia64/sysdep.h: Likewise. * sysdeps/unix/sysv/linux/lowlevellock-futex.h: Likewise. * sysdeps/unix/sysv/linux/m68k/bits/m68k-vdso.h: Likewise. * sysdeps/unix/sysv/linux/m68k/m68k-helpers.S: Likewise. * sysdeps/unix/sysv/linux/microblaze/lowlevellock.h: Likewise. * sysdeps/unix/sysv/linux/powerpc/lowlevellock.h: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h: Likewise. * sysdeps/unix/sysv/linux/s390/lowlevellock.h: Likewise. * sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h: Likewise. * sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h: Likewise. * sysdeps/unix/sysv/linux/sh/lowlevellock.h: Likewise. * sysdeps/unix/sysv/linux/sh/sysdep.h: Likewise. * sysdeps/unix/sysv/linux/sparc/lowlevellock.h: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h: Likewise. * sysdeps/unix/sysv/linux/tile/lowlevellock.h: Likewise. * sysdeps/unix/sysv/linux/tile/sysdep.h: Likewise. * sysdeps/unix/sysv/linux/x86_64/lowlevellock.h: Likewise. * sysdeps/unix/sysv/linux/x86_64/sysdep.h: Likewise. * sysdeps/unix/x86_64/sysdep.S: Likewise. * sysdeps/x86_64/setjmp.S: Likewise.
2014-11-20 15:39:43 +00:00
# if IS_IN (rtld)
/* Rearrange the list so this DSO appears after rtld_map. */
assert (l->l_next == NULL);
assert (l->l_prev == main_map);
GL(dl_rtld_map).l_next = l;
l->l_prev = &GL(dl_rtld_map);
*first_preload = &l->l_next;
2012-10-05 17:22:14 +00:00
# else
GL(dl_nns) = 1;
# endif
/* We have a prelinked DSO preloaded by the system. */
GLRO(dl_sysinfo_map) = l;
# ifdef NEED_DL_SYSINFO
if (GLRO(dl_sysinfo) == DL_SYSINFO_DEFAULT)
GLRO(dl_sysinfo) = GLRO(dl_sysinfo_dso)->e_entry + l->l_addr;
# endif
}
#endif
}