mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-21 20:40:05 +00:00
490e6c62aa
dynamic-link.h is included more than once in some elf/ files (rtld.c, dl-conflict.c, dl-reloc.c, dl-reloc-static-pie.c) and uses GCC nested functions. This harms readability and the nested functions usage is the biggest obstacle prevents Clang build (Clang doesn't support GCC nested functions). The key idea for unnesting is to add extra parameters (struct link_map *and struct r_scope_elm *[]) to RESOLVE_MAP, ELF_MACHINE_BEFORE_RTLD_RELOC, ELF_DYNAMIC_RELOCATE, elf_machine_rel[a], elf_machine_lazy_rel, and elf_machine_runtime_setup. (This is inspired by Stan Shebs' ppc64/x86-64 implementation in the google/grte/v5-2.27/master which uses mixed extra parameters and static variables.) Future simplification: * If mips elf_machine_runtime_setup no longer needs RESOLVE_GOTSYM, elf_machine_runtime_setup can drop the `scope` parameter. * If TLSDESC no longer need to be in elf_machine_lazy_rel, elf_machine_lazy_rel can drop the `scope` parameter. Tested on aarch64, i386, x86-64, powerpc64le, powerpc64, powerpc32, sparc64, sparcv9, s390x, s390, hppa, ia64, armhf, alpha, and mips64. In addition, tested build-many-glibcs.py with {arc,csky,microblaze,nios2}-linux-gnu and riscv64-linux-gnu-rv64imafdc-lp64d. Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
82 lines
2.7 KiB
C
82 lines
2.7 KiB
C
/* Support for relocating static PIE.
|
|
Copyright (C) 2017-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/>. */
|
|
|
|
#if ENABLE_STATIC_PIE
|
|
/* Mark symbols hidden in static PIE for early self relocation to work. */
|
|
# pragma GCC visibility push(hidden)
|
|
#include <assert.h>
|
|
#include <unistd.h>
|
|
#include <ldsodefs.h>
|
|
|
|
#include <dl-machine.h>
|
|
|
|
#define STATIC_PIE_BOOTSTRAP
|
|
#define RESOLVE_MAP(map, scope, sym, version, flags) map
|
|
#include "dynamic-link.h"
|
|
|
|
/* Relocate static executable with PIE. */
|
|
|
|
void
|
|
_dl_relocate_static_pie (void)
|
|
{
|
|
struct link_map *main_map = _dl_get_dl_main_map ();
|
|
|
|
/* Figure out the run-time load address of static PIE. */
|
|
main_map->l_addr = elf_machine_load_address ();
|
|
|
|
/* Read our own dynamic section and fill in the info array. */
|
|
main_map->l_ld = ((void *) main_map->l_addr + elf_machine_dynamic ());
|
|
|
|
const ElfW(Phdr) *ph, *phdr = GL(dl_phdr);
|
|
size_t phnum = GL(dl_phnum);
|
|
for (ph = phdr; ph < &phdr[phnum]; ++ph)
|
|
if (ph->p_type == PT_DYNAMIC)
|
|
{
|
|
main_map->l_ld_readonly = (ph->p_flags & PF_W) == 0;
|
|
break;
|
|
}
|
|
|
|
elf_get_dynamic_info (main_map);
|
|
|
|
# ifdef ELF_MACHINE_BEFORE_RTLD_RELOC
|
|
ELF_MACHINE_BEFORE_RTLD_RELOC (main_map, main_map->l_info);
|
|
# endif
|
|
|
|
/* Relocate ourselves so we can do normal function calls and
|
|
data access using the global offset table. */
|
|
ELF_DYNAMIC_RELOCATE (main_map, NULL, 0, 0, 0);
|
|
main_map->l_relocated = 1;
|
|
|
|
/* Initialize _r_debug_extended. */
|
|
struct r_debug *r = _dl_debug_initialize (0, LM_ID_BASE);
|
|
r->r_state = RT_CONSISTENT;
|
|
|
|
/* Set up debugging before the debugger is notified for the first
|
|
time. */
|
|
# ifdef ELF_MACHINE_DEBUG_SETUP
|
|
/* Some machines (e.g. MIPS) don't use DT_DEBUG in this way. */
|
|
ELF_MACHINE_DEBUG_SETUP (main_map, r);
|
|
# else
|
|
if (main_map->l_info[DT_DEBUG] != NULL)
|
|
/* There is a DT_DEBUG entry in the dynamic section. Fill it in
|
|
with the run-time address of the r_debug structure */
|
|
main_map->l_info[DT_DEBUG]->d_un.d_ptr = (ElfW(Addr)) r;
|
|
# endif
|
|
}
|
|
#endif
|