diff options
Diffstat (limited to 'elf')
-rw-r--r-- | elf/Makefile | 7 | ||||
-rw-r--r-- | elf/dl-reloc-static-pie.c | 52 | ||||
-rw-r--r-- | elf/dl-support.c | 11 | ||||
-rw-r--r-- | elf/dynamic-link.h | 2 | ||||
-rw-r--r-- | elf/get-dynamic-info.h | 6 |
5 files changed, 72 insertions, 6 deletions
diff --git a/elf/Makefile b/elf/Makefile index 8563555079..47c3d23ed8 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -24,7 +24,8 @@ include ../Makeconfig headers = elf.h bits/elfclass.h link.h bits/link.h routines = $(all-dl-routines) dl-support dl-iteratephdr \ dl-addr dl-addr-obj enbl-secure dl-profstub \ - dl-origin dl-libc dl-sym dl-sysdep dl-error + dl-origin dl-libc dl-sym dl-sysdep dl-error \ + dl-reloc-static-pie # The core dynamic linking functions are in libc for the static and # profiled libraries. @@ -52,7 +53,7 @@ endif all-dl-routines = $(dl-routines) $(sysdep-dl-routines) # But they are absent from the shared libc, because that code is in ld.so. elide-routines.os = $(all-dl-routines) dl-support enbl-secure dl-origin \ - dl-sysdep dl-exception + dl-sysdep dl-exception dl-reloc-static-pie shared-only-routines += dl-caller # ld.so uses those routines, plus some special stuff for being the program @@ -153,7 +154,7 @@ tests-static-internal := tst-tls1-static tst-tls2-static \ tst-tls1-static-non-pie CRT-tst-tls1-static-non-pie := $(csu-objpfx)crt1.o -DEFAULT-LDFLAGS-tst-tls1-static-non-pie = $(no-pie-ldflag) +tst-tls1-static-non-pie-no-pie = yes tests := tst-tls9 tst-leaks1 \ tst-array1 tst-array2 tst-array3 tst-array4 tst-array5 \ diff --git a/elf/dl-reloc-static-pie.c b/elf/dl-reloc-static-pie.c new file mode 100644 index 0000000000..6e43aea76a --- /dev/null +++ b/elf/dl-reloc-static-pie.c @@ -0,0 +1,52 @@ +/* Support for relocating static PIE. + Copyright (C) 2017 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 + <http://www.gnu.org/licenses/>. */ + +#if ENABLE_STATIC_PIE +#include <unistd.h> +#include <ldsodefs.h> +#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 (); + +# define STATIC_PIE_BOOTSTRAP +# define BOOTSTRAP_MAP (main_map) +# define RESOLVE_MAP(sym, version, flags) BOOTSTRAP_MAP +# include "dynamic-link.h" + + /* 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 ()); + elf_get_dynamic_info (main_map, NULL); + +# ifdef ELF_MACHINE_BEFORE_RTLD_RELOC + ELF_MACHINE_BEFORE_RTLD_RELOC (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, 0, 0, 0); + main_map->l_relocated = 1; +} +#endif diff --git a/elf/dl-support.c b/elf/dl-support.c index 235d3a7f46..b9fc1a66fe 100644 --- a/elf/dl-support.c +++ b/elf/dl-support.c @@ -385,3 +385,14 @@ _dl_non_dynamic_init (void) #ifdef DL_SYSINFO_IMPLEMENTATION DL_SYSINFO_IMPLEMENTATION #endif + +#if ENABLE_STATIC_PIE +/* Since relocation to hidden _dl_main_map causes relocation overflow on + aarch64, a function is used to get the address of _dl_main_map. */ + +struct link_map * +_dl_get_dl_main_map (void) +{ + return &_dl_main_map; +} +#endif diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h index ebea7567cd..6278649711 100644 --- a/elf/dynamic-link.h +++ b/elf/dynamic-link.h @@ -94,7 +94,7 @@ elf_machine_lazy_rel (struct link_map *map, #ifdef RESOLVE_MAP -# ifdef RTLD_BOOTSTRAP +# if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP # define ELF_DURING_STARTUP (1) # else # define ELF_DURING_STARTUP (0) diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h index 7525c3a5b2..eb26d23649 100644 --- a/elf/get-dynamic-info.h +++ b/elf/get-dynamic-info.h @@ -38,7 +38,7 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp) typedef Elf64_Xword d_tag_utype; #endif -#ifndef RTLD_BOOTSTRAP +#if !defined RTLD_BOOTSTRAP && !defined STATIC_PIE_BOOTSTRAP if (dyn == NULL) return; #endif @@ -139,9 +139,11 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp) /* Only the bind now flags are allowed. */ assert (info[VERSYMIDX (DT_FLAGS_1)] == NULL || (info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val & ~DF_1_NOW) == 0); + /* Flags must not be set for ld.so. */ assert (info[DT_FLAGS] == NULL || (info[DT_FLAGS]->d_un.d_val & ~DF_BIND_NOW) == 0); - /* Flags must not be set for ld.so. */ +#endif +#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP assert (info[DT_RUNPATH] == NULL); assert (info[DT_RPATH] == NULL); #else |