diff options
Diffstat (limited to 'elf')
-rw-r--r-- | elf/dl-conflict.c | 39 | ||||
-rw-r--r-- | elf/dl-reloc-static-pie.c | 15 | ||||
-rw-r--r-- | elf/dl-reloc.c | 57 | ||||
-rw-r--r-- | elf/do-rel.h | 16 | ||||
-rw-r--r-- | elf/dynamic-link.h | 58 | ||||
-rw-r--r-- | elf/get-dynamic-info.h | 15 | ||||
-rw-r--r-- | elf/rtld.c | 15 |
7 files changed, 108 insertions, 107 deletions
diff --git a/elf/dl-conflict.c b/elf/dl-conflict.c index 64fa5793d2..b58929cc5d 100644 --- a/elf/dl-conflict.c +++ b/elf/dl-conflict.c @@ -26,20 +26,12 @@ #include <sys/types.h> #include "dynamic-link.h" -void -_dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict, - ElfW(Rela) *conflictend) -{ -#if ! ELF_MACHINE_NO_RELA - if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_RELOC)) - _dl_debug_printf ("\nconflict processing: %s\n", DSO_FILENAME (l->l_name)); - - { - /* Do the conflict relocation of the object and library GOT and other - data. */ +/* Used at loading time solely for prelink executable. It is not called + concurrently so it is be safe to defined as static. */ +static struct link_map *resolve_conflict_map __attribute__ ((__unused__)); /* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code. */ -#define RESOLVE_MAP(ref, version, flags) (*ref = NULL, NULL) +#define RESOLVE_MAP(map, scope, ref, version, flags) (*ref = NULL, NULL) #define RESOLVE(ref, version, flags) (*ref = NULL, 0) #define RESOLVE_CONFLICT_FIND_MAP(map, r_offset) \ do { \ @@ -50,12 +42,23 @@ _dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict, (map) = resolve_conflict_map; \ } while (0) +#include "dynamic-link.h" + +void +_dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict, + ElfW(Rela) *conflictend) +{ +#if ! ELF_MACHINE_NO_RELA + if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_RELOC)) + _dl_debug_printf ("\nconflict processing: %s\n", DSO_FILENAME (l->l_name)); + + { + /* Do the conflict relocation of the object and library GOT and other + data. */ + /* Prelinking makes no sense for anything but the main namespace. */ assert (l->l_ns == LM_ID_BASE); - struct link_map *resolve_conflict_map __attribute__ ((__unused__)) - = GL(dl_ns)[LM_ID_BASE]._ns_loaded; - -#include "dynamic-link.h" + resolve_conflict_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded; /* Override these, defined in dynamic-link.h. */ #undef CHECK_STATIC_TLS @@ -66,8 +69,8 @@ _dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict, GL(dl_num_cache_relocations) += conflictend - conflict; for (; conflict < conflictend; ++conflict) - elf_machine_rela (l, conflict, NULL, NULL, (void *) conflict->r_offset, - 0); + elf_machine_rela (l, NULL, conflict, NULL, NULL, + (void *) conflict->r_offset, 0); } #endif } diff --git a/elf/dl-reloc-static-pie.c b/elf/dl-reloc-static-pie.c index 68ded176cd..4007580453 100644 --- a/elf/dl-reloc-static-pie.c +++ b/elf/dl-reloc-static-pie.c @@ -19,8 +19,14 @@ #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. */ @@ -30,11 +36,6 @@ _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 (); @@ -53,12 +54,12 @@ _dl_relocate_static_pie (void) elf_get_dynamic_info (main_map); # ifdef ELF_MACHINE_BEFORE_RTLD_RELOC - ELF_MACHINE_BEFORE_RTLD_RELOC (main_map->l_info); + 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, 0, 0, 0); + ELF_DYNAMIC_RELOCATE (main_map, NULL, 0, 0, 0); main_map->l_relocated = 1; /* Initialize _r_debug_extended. */ diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c index 6c957456b8..0d5b727c64 100644 --- a/elf/dl-reloc.c +++ b/elf/dl-reloc.c @@ -162,6 +162,32 @@ _dl_nothread_init_static_tls (struct link_map *map) } #endif /* !PTHREAD_IN_LIBC */ +/* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code. */ +#define RESOLVE_MAP(l, scope, ref, version, r_type) \ + ((ELFW(ST_BIND) ((*ref)->st_info) != STB_LOCAL \ + && __glibc_likely (!dl_symbol_visibility_binds_local_p (*ref))) \ + ? ((__glibc_unlikely ((*ref) == l->l_lookup_cache.sym) \ + && elf_machine_type_class (r_type) == l->l_lookup_cache.type_class) \ + ? (bump_num_cache_relocations (), \ + (*ref) = l->l_lookup_cache.ret, \ + l->l_lookup_cache.value) \ + : ({ lookup_t _lr; \ + int _tc = elf_machine_type_class (r_type); \ + l->l_lookup_cache.type_class = _tc; \ + l->l_lookup_cache.sym = (*ref); \ + const struct r_found_version *v = NULL; \ + if ((version) != NULL && (version)->hash != 0) \ + v = (version); \ + _lr = _dl_lookup_symbol_x ((const char *) D_PTR (l, l_info[DT_STRTAB]) + (*ref)->st_name, \ + l, (ref), scope, v, _tc, \ + DL_LOOKUP_ADD_DEPENDENCY \ + | DL_LOOKUP_FOR_RELOCATE, NULL); \ + l->l_lookup_cache.ret = (*ref); \ + l->l_lookup_cache.value = _lr; })) \ + : l) + +#include "dynamic-link.h" + void _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], int reloc_mode, int consider_profiling) @@ -243,36 +269,7 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], { /* Do the actual relocation of the object's GOT and other data. */ - /* String table object symbols. */ - const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]); - - /* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code. */ -#define RESOLVE_MAP(ref, version, r_type) \ - ((ELFW(ST_BIND) ((*ref)->st_info) != STB_LOCAL \ - && __glibc_likely (!dl_symbol_visibility_binds_local_p (*ref))) \ - ? ((__builtin_expect ((*ref) == l->l_lookup_cache.sym, 0) \ - && elf_machine_type_class (r_type) == l->l_lookup_cache.type_class) \ - ? (bump_num_cache_relocations (), \ - (*ref) = l->l_lookup_cache.ret, \ - l->l_lookup_cache.value) \ - : ({ lookup_t _lr; \ - int _tc = elf_machine_type_class (r_type); \ - l->l_lookup_cache.type_class = _tc; \ - l->l_lookup_cache.sym = (*ref); \ - const struct r_found_version *v = NULL; \ - if ((version) != NULL && (version)->hash != 0) \ - v = (version); \ - _lr = _dl_lookup_symbol_x (strtab + (*ref)->st_name, l, (ref), \ - scope, v, _tc, \ - DL_LOOKUP_ADD_DEPENDENCY \ - | DL_LOOKUP_FOR_RELOCATE, NULL); \ - l->l_lookup_cache.ret = (*ref); \ - l->l_lookup_cache.value = _lr; })) \ - : l) - -#include "dynamic-link.h" - - ELF_DYNAMIC_RELOCATE (l, lazy, consider_profiling, skip_ifunc); + ELF_DYNAMIC_RELOCATE (l, scope, lazy, consider_profiling, skip_ifunc); #ifndef PROF if (__glibc_unlikely (consider_profiling) diff --git a/elf/do-rel.h b/elf/do-rel.h index 321ac2b359..f441b74919 100644 --- a/elf/do-rel.h +++ b/elf/do-rel.h @@ -37,8 +37,8 @@ relocations; they should be set up to call _dl_runtime_resolve, rather than fully resolved now. */ -auto inline void __attribute__ ((always_inline)) -elf_dynamic_do_Rel (struct link_map *map, +static inline void __attribute__ ((always_inline)) +elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[], ElfW(Addr) reladdr, ElfW(Addr) relsize, __typeof (((ElfW(Dyn) *) 0)->d_un.d_val) nrelative, int lazy, int skip_ifunc) @@ -68,13 +68,13 @@ elf_dynamic_do_Rel (struct link_map *map, } else # endif - elf_machine_lazy_rel (map, l_addr, r, skip_ifunc); + elf_machine_lazy_rel (map, scope, l_addr, r, skip_ifunc); # ifdef ELF_MACHINE_IRELATIVE if (r2 != NULL) for (; r2 <= end2; ++r2) if (ELFW(R_TYPE) (r2->r_info) == ELF_MACHINE_IRELATIVE) - elf_machine_lazy_rel (map, l_addr, r2, skip_ifunc); + elf_machine_lazy_rel (map, scope, l_addr, r2, skip_ifunc); # endif } else @@ -134,7 +134,7 @@ elf_dynamic_do_Rel (struct link_map *map, #endif ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff; - elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], + elf_machine_rel (map, scope, r, &symtab[ELFW(R_SYM) (r->r_info)], &map->l_versions[ndx], (void *) (l_addr + r->r_offset), skip_ifunc); } @@ -146,7 +146,7 @@ elf_dynamic_do_Rel (struct link_map *map, { ElfW(Half) ndx = version[ELFW(R_SYM) (r2->r_info)] & 0x7fff; - elf_machine_rel (map, r2, + elf_machine_rel (map, scope, r2, &symtab[ELFW(R_SYM) (r2->r_info)], &map->l_versions[ndx], (void *) (l_addr + r2->r_offset), @@ -167,14 +167,14 @@ elf_dynamic_do_Rel (struct link_map *map, } else # endif - elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL, + elf_machine_rel (map, scope, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL, (void *) (l_addr + r->r_offset), skip_ifunc); # ifdef ELF_MACHINE_IRELATIVE if (r2 != NULL) for (; r2 <= end2; ++r2) if (ELFW(R_TYPE) (r2->r_info) == ELF_MACHINE_IRELATIVE) - elf_machine_rel (map, r2, &symtab[ELFW(R_SYM) (r2->r_info)], + elf_machine_rel (map, scope, r2, &symtab[ELFW(R_SYM) (r2->r_info)], NULL, (void *) (l_addr + r2->r_offset), skip_ifunc); # endif diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h index 3eb24ba3a6..7cc3021164 100644 --- a/elf/dynamic-link.h +++ b/elf/dynamic-link.h @@ -59,31 +59,33 @@ int _dl_try_allocate_static_tls (struct link_map *map, bool optional) copying memory, breaking the very code written to handle the unaligned cases. */ # if ! ELF_MACHINE_NO_REL -auto inline void __attribute__((always_inline)) -elf_machine_rel (struct link_map *map, const ElfW(Rel) *reloc, - const ElfW(Sym) *sym, const struct r_found_version *version, +static inline void __attribute__((always_inline)) +elf_machine_rel (struct link_map *map, struct r_scope_elem *scope[], + const ElfW(Rel) *reloc, const ElfW(Sym) *sym, + const struct r_found_version *version, void *const reloc_addr, int skip_ifunc); -auto inline void __attribute__((always_inline)) +static inline void __attribute__((always_inline)) elf_machine_rel_relative (ElfW(Addr) l_addr, const ElfW(Rel) *reloc, void *const reloc_addr); # endif # if ! ELF_MACHINE_NO_RELA -auto inline void __attribute__((always_inline)) -elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, - const ElfW(Sym) *sym, const struct r_found_version *version, - void *const reloc_addr, int skip_ifunc); -auto inline void __attribute__((always_inline)) +static inline void __attribute__((always_inline)) +elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], + const ElfW(Rela) *reloc, const ElfW(Sym) *sym, + const struct r_found_version *version, void *const reloc_addr, + int skip_ifunc); +static inline void __attribute__((always_inline)) elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc, void *const reloc_addr); # endif # if ELF_MACHINE_NO_RELA || defined ELF_MACHINE_PLT_REL -auto inline void __attribute__((always_inline)) -elf_machine_lazy_rel (struct link_map *map, +static inline void __attribute__((always_inline)) +elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], ElfW(Addr) l_addr, const ElfW(Rel) *reloc, int skip_ifunc); # else -auto inline void __attribute__((always_inline)) -elf_machine_lazy_rel (struct link_map *map, +static inline void __attribute__((always_inline)) +elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], ElfW(Addr) l_addr, const ElfW(Rela) *reloc, int skip_ifunc); # endif @@ -114,7 +116,7 @@ elf_machine_lazy_rel (struct link_map *map, consumes precisely the very end of the DT_REL*, or DT_JMPREL and DT_REL* are completely separate and there is a gap between them. */ -# define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, skip_ifunc, test_rel) \ +# define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, scope, do_lazy, skip_ifunc, test_rel) \ do { \ struct { ElfW(Addr) start, size; \ __typeof (((ElfW(Dyn) *) 0)->d_un.d_val) nrelative; int lazy; } \ @@ -152,18 +154,18 @@ elf_machine_lazy_rel (struct link_map *map, } \ \ if (ELF_DURING_STARTUP) \ - elf_dynamic_do_##reloc ((map), ranges[0].start, ranges[0].size, \ - ranges[0].nrelative, 0, skip_ifunc); \ + elf_dynamic_do_##reloc ((map), scope, ranges[0].start, ranges[0].size, \ + ranges[0].nrelative, 0, skip_ifunc); \ else \ { \ int ranges_index; \ for (ranges_index = 0; ranges_index < 2; ++ranges_index) \ - elf_dynamic_do_##reloc ((map), \ + elf_dynamic_do_##reloc ((map), scope, \ ranges[ranges_index].start, \ ranges[ranges_index].size, \ ranges[ranges_index].nrelative, \ ranges[ranges_index].lazy, \ - skip_ifunc); \ + skip_ifunc); \ } \ } while (0) @@ -175,29 +177,29 @@ elf_machine_lazy_rel (struct link_map *map, # if ! ELF_MACHINE_NO_REL # include "do-rel.h" -# define ELF_DYNAMIC_DO_REL(map, lazy, skip_ifunc) \ - _ELF_DYNAMIC_DO_RELOC (REL, Rel, map, lazy, skip_ifunc, _ELF_CHECK_REL) +# define ELF_DYNAMIC_DO_REL(map, scope, lazy, skip_ifunc) \ + _ELF_DYNAMIC_DO_RELOC (REL, Rel, map, scope, lazy, skip_ifunc, _ELF_CHECK_REL) # else -# define ELF_DYNAMIC_DO_REL(map, lazy, skip_ifunc) /* Nothing to do. */ +# define ELF_DYNAMIC_DO_REL(map, scope, lazy, skip_ifunc) /* Nothing to do. */ # endif # if ! ELF_MACHINE_NO_RELA # define DO_RELA # include "do-rel.h" -# define ELF_DYNAMIC_DO_RELA(map, lazy, skip_ifunc) \ - _ELF_DYNAMIC_DO_RELOC (RELA, Rela, map, lazy, skip_ifunc, _ELF_CHECK_REL) +# define ELF_DYNAMIC_DO_RELA(map, scope, lazy, skip_ifunc) \ + _ELF_DYNAMIC_DO_RELOC (RELA, Rela, map, scope, lazy, skip_ifunc, _ELF_CHECK_REL) # else -# define ELF_DYNAMIC_DO_RELA(map, lazy, skip_ifunc) /* Nothing to do. */ +# define ELF_DYNAMIC_DO_RELA(map, scope, lazy, skip_ifunc) /* Nothing to do. */ # endif /* This can't just be an inline function because GCC is too dumb to inline functions containing inlines themselves. */ -# define ELF_DYNAMIC_RELOCATE(map, lazy, consider_profile, skip_ifunc) \ +# define ELF_DYNAMIC_RELOCATE(map, scope, lazy, consider_profile, skip_ifunc) \ do { \ - int edr_lazy = elf_machine_runtime_setup ((map), (lazy), \ + int edr_lazy = elf_machine_runtime_setup ((map), (scope), (lazy), \ (consider_profile)); \ - ELF_DYNAMIC_DO_REL ((map), edr_lazy, skip_ifunc); \ - ELF_DYNAMIC_DO_RELA ((map), edr_lazy, skip_ifunc); \ + ELF_DYNAMIC_DO_REL ((map), (scope), edr_lazy, skip_ifunc); \ + ELF_DYNAMIC_DO_RELA ((map), (scope), edr_lazy, skip_ifunc); \ } while (0) #endif diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h index 4aa2058abf..15c316b38c 100644 --- a/elf/get-dynamic-info.h +++ b/elf/get-dynamic-info.h @@ -16,18 +16,15 @@ License along with the GNU C Library; if not, see <https://www.gnu.org/licenses/>. */ -/* This file is included multiple times and therefore lacks a header - file inclusion guard. */ +/* Populate dynamic tags in l_info. */ + +#ifndef _GET_DYNAMIC_INFO_H +#define _GET_DYNAMIC_INFO_H #include <assert.h> #include <libc-diag.h> -#ifndef RESOLVE_MAP -static -#else -auto -#endif -inline void __attribute__ ((unused, always_inline)) +static inline void __attribute__ ((unused, always_inline)) elf_get_dynamic_info (struct link_map *l) { #if __ELF_NATIVE_CLASS == 32 @@ -165,3 +162,5 @@ elf_get_dynamic_info (struct link_map *l) info[DT_RPATH] = NULL; #endif } + +#endif diff --git a/elf/rtld.c b/elf/rtld.c index 628245d8cd..5eee9e1091 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -501,13 +501,9 @@ _dl_start_final (void *arg, struct dl_start_final_info *info) return start_addr; } -static ElfW(Addr) __attribute_used__ -_dl_start (void *arg) -{ #ifdef DONT_USE_BOOTSTRAP_MAP # define bootstrap_map GL(dl_rtld_map) #else - struct dl_start_final_info info; # define bootstrap_map info.l #endif @@ -516,13 +512,16 @@ _dl_start (void *arg) Since ld.so must not have any undefined symbols the result is trivial: always the map of ld.so itself. */ #define RTLD_BOOTSTRAP -#define BOOTSTRAP_MAP (&bootstrap_map) -#define RESOLVE_MAP(sym, version, flags) BOOTSTRAP_MAP +#define RESOLVE_MAP(map, scope, sym, version, flags) map #include "dynamic-link.h" +static ElfW(Addr) __attribute_used__ +_dl_start (void *arg) +{ #ifdef DONT_USE_BOOTSTRAP_MAP rtld_timer_start (&start_time); #else + struct dl_start_final_info info; rtld_timer_start (&info.start_time); #endif @@ -555,7 +554,7 @@ _dl_start (void *arg) #endif #ifdef ELF_MACHINE_BEFORE_RTLD_RELOC - ELF_MACHINE_BEFORE_RTLD_RELOC (bootstrap_map.l_info); + ELF_MACHINE_BEFORE_RTLD_RELOC (&bootstrap_map, bootstrap_map.l_info); #endif if (bootstrap_map.l_addr || ! bootstrap_map.l_info[VALIDX(DT_GNU_PRELINKED)]) @@ -563,7 +562,7 @@ _dl_start (void *arg) /* Relocate ourselves so we can do normal function calls and data access using the global offset table. */ - ELF_DYNAMIC_RELOCATE (&bootstrap_map, 0, 0, 0); + ELF_DYNAMIC_RELOCATE (&bootstrap_map, NULL, 0, 0, 0); } bootstrap_map.l_relocated = 1; |