Module Name: src Committed By: joerg Date: Mon Jun 19 11:57:02 UTC 2017
Modified Files: src/libexec/ld.elf_so: Makefile map_object.c rtld.h symbol.c src/libexec/ld.elf_so/arch/aarch64: mdreloc.c src/libexec/ld.elf_so/arch/alpha: alpha_reloc.c src/libexec/ld.elf_so/arch/arm: mdreloc.c src/libexec/ld.elf_so/arch/hppa: hppa_reloc.c src/libexec/ld.elf_so/arch/i386: mdreloc.c src/libexec/ld.elf_so/arch/m68k: mdreloc.c src/libexec/ld.elf_so/arch/mips: mips_reloc.c src/libexec/ld.elf_so/arch/or1k: mdreloc.c src/libexec/ld.elf_so/arch/powerpc: ppc_reloc.c src/libexec/ld.elf_so/arch/riscv: mdreloc.c src/libexec/ld.elf_so/arch/sh3: mdreloc.c src/libexec/ld.elf_so/arch/sparc: mdreloc.c src/libexec/ld.elf_so/arch/sparc64: mdreloc.c src/libexec/ld.elf_so/arch/vax: mdreloc.c src/libexec/ld.elf_so/arch/x86_64: mdreloc.c Log Message: Replace COMBREL with just-in-time check in _rtld_relocate_nonplt_objects. The COMBREL logic predates thread-safety of the dynamic linker and breaks the use of shared locks for the common symbol lookup case. It is unlikely to provide any benefit for lazy binding or PLT lookups, so provide equivalent functionality in the non-PLT relocation handling loop by checking if the symbol used by the current relocation is the same as the one used during the last lookup. No inter-object cachine is done as it is also unlikely to be benefical. Testing with Firefox startup on AMD64 shows a small performance gain by the new method. To generate a diff of this commit: cvs rdiff -u -r1.136 -r1.137 src/libexec/ld.elf_so/Makefile cvs rdiff -u -r1.57 -r1.58 src/libexec/ld.elf_so/map_object.c cvs rdiff -u -r1.126 -r1.127 src/libexec/ld.elf_so/rtld.h cvs rdiff -u -r1.67 -r1.68 src/libexec/ld.elf_so/symbol.c cvs rdiff -u -r1.2 -r1.3 src/libexec/ld.elf_so/arch/aarch64/mdreloc.c cvs rdiff -u -r1.41 -r1.42 src/libexec/ld.elf_so/arch/alpha/alpha_reloc.c cvs rdiff -u -r1.38 -r1.39 src/libexec/ld.elf_so/arch/arm/mdreloc.c cvs rdiff -u -r1.43 -r1.44 src/libexec/ld.elf_so/arch/hppa/hppa_reloc.c cvs rdiff -u -r1.37 -r1.38 src/libexec/ld.elf_so/arch/i386/mdreloc.c cvs rdiff -u -r1.31 -r1.32 src/libexec/ld.elf_so/arch/m68k/mdreloc.c cvs rdiff -u -r1.65 -r1.66 src/libexec/ld.elf_so/arch/mips/mips_reloc.c cvs rdiff -u -r1.1 -r1.2 src/libexec/ld.elf_so/arch/or1k/mdreloc.c cvs rdiff -u -r1.53 -r1.54 src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c cvs rdiff -u -r1.2 -r1.3 src/libexec/ld.elf_so/arch/riscv/mdreloc.c cvs rdiff -u -r1.32 -r1.33 src/libexec/ld.elf_so/arch/sh3/mdreloc.c cvs rdiff -u -r1.49 -r1.50 src/libexec/ld.elf_so/arch/sparc/mdreloc.c cvs rdiff -u -r1.60 -r1.61 src/libexec/ld.elf_so/arch/sparc64/mdreloc.c cvs rdiff -u -r1.31 -r1.32 src/libexec/ld.elf_so/arch/vax/mdreloc.c cvs rdiff -u -r1.41 -r1.42 src/libexec/ld.elf_so/arch/x86_64/mdreloc.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/libexec/ld.elf_so/Makefile diff -u src/libexec/ld.elf_so/Makefile:1.136 src/libexec/ld.elf_so/Makefile:1.137 --- src/libexec/ld.elf_so/Makefile:1.136 Thu Dec 1 14:29:15 2016 +++ src/libexec/ld.elf_so/Makefile Mon Jun 19 11:57:01 2017 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.136 2016/12/01 14:29:15 christos Exp $ +# $NetBSD: Makefile,v 1.137 2017/06/19 11:57:01 joerg Exp $ # # NOTE: when changing ld.so, ensure that ldd still compiles. # @@ -97,7 +97,6 @@ CPPFLAGS+= -I${.CURDIR} -I. -D_KERNTYPES CPPFLAGS+= -DRTLD_LOADER CPPFLAGS+= -DGNU_RELRO CPPFLAGS+= -D_RTLD_SOURCE -CPPFLAGS+= -DCOMBRELOC #CPPFLAGS+= -DDEBUG #CPPFLAGS+= -DRTLD_DEBUG #CPPFLAGS+= -DRTLD_DEBUG_RELOC Index: src/libexec/ld.elf_so/map_object.c diff -u src/libexec/ld.elf_so/map_object.c:1.57 src/libexec/ld.elf_so/map_object.c:1.58 --- src/libexec/ld.elf_so/map_object.c:1.57 Fri Mar 10 09:13:49 2017 +++ src/libexec/ld.elf_so/map_object.c Mon Jun 19 11:57:01 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: map_object.c,v 1.57 2017/03/10 09:13:49 maya Exp $ */ +/* $NetBSD: map_object.c,v 1.58 2017/06/19 11:57:01 joerg Exp $ */ /* * Copyright 1996 John D. Polstra. @@ -34,7 +34,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: map_object.c,v 1.57 2017/03/10 09:13:49 maya Exp $"); +__RCSID("$NetBSD: map_object.c,v 1.58 2017/06/19 11:57:01 joerg Exp $"); #endif /* not lint */ #include <errno.h> @@ -462,9 +462,6 @@ _rtld_obj_free(Obj_Entry *obj) } if (!obj->phdr_loaded) xfree((void *)(uintptr_t)obj->phdr); -#ifdef COMBRELOC - _rtld_combreloc_reset(obj); -#endif xfree(obj); } Index: src/libexec/ld.elf_so/rtld.h diff -u src/libexec/ld.elf_so/rtld.h:1.126 src/libexec/ld.elf_so/rtld.h:1.127 --- src/libexec/ld.elf_so/rtld.h:1.126 Wed Nov 30 19:43:32 2016 +++ src/libexec/ld.elf_so/rtld.h Mon Jun 19 11:57:01 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: rtld.h,v 1.126 2016/11/30 19:43:32 christos Exp $ */ +/* $NetBSD: rtld.h,v 1.127 2017/06/19 11:57:01 joerg Exp $ */ /* * Copyright 1996 John D. Polstra. @@ -432,9 +432,6 @@ const Elf_Sym *_rtld_symlook_default(con const Elf_Sym *_rtld_symlook_needed(const char *, unsigned long, const Needed_Entry *, const Obj_Entry **, u_int, const Ver_Entry *, DoneList *, DoneList *); -#ifdef COMBRELOC -void _rtld_combreloc_reset(const Obj_Entry *); -#endif /* symver.c */ void _rtld_object_add_name(Obj_Entry *, const char *); Index: src/libexec/ld.elf_so/symbol.c diff -u src/libexec/ld.elf_so/symbol.c:1.67 src/libexec/ld.elf_so/symbol.c:1.68 --- src/libexec/ld.elf_so/symbol.c:1.67 Thu Dec 1 14:29:15 2016 +++ src/libexec/ld.elf_so/symbol.c Mon Jun 19 11:57:01 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: symbol.c,v 1.67 2016/12/01 14:29:15 christos Exp $ */ +/* $NetBSD: symbol.c,v 1.68 2017/06/19 11:57:01 joerg Exp $ */ /* * Copyright 1996 John D. Polstra. @@ -40,7 +40,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: symbol.c,v 1.67 2016/12/01 14:29:15 christos Exp $"); +__RCSID("$NetBSD: symbol.c,v 1.68 2017/06/19 11:57:01 joerg Exp $"); #endif /* not lint */ #include <err.h> @@ -323,21 +323,6 @@ _rtld_symlook_obj(const char *name, unsi return NULL; } -#ifdef COMBRELOC -static const Obj_Entry *_rtld_last_refobj; - -/* - * Called when an object is freed. Reset the cached symbol look up if - * our last referencing or definition object just got unloaded. - */ -void -_rtld_combreloc_reset(const Obj_Entry *obj) -{ - if (_rtld_last_refobj == obj) - _rtld_last_refobj = NULL; -} -#endif - /* * Given a symbol number in a referencing object, find the corresponding * definition of the symbol. Returns a pointer to the symbol, or NULL if @@ -354,25 +339,6 @@ _rtld_find_symdef(unsigned long symnum, const char *name; unsigned long hash; -#ifdef COMBRELOC - /* - * COMBRELOC combines multiple reloc sections and sorts them to make - * dynamic symbol lookup caching possible. - * - * So if the lookup we are doing is the same as the previous lookup - * return the cached results. - */ - static unsigned long last_symnum; - static const Obj_Entry *last_defobj; - static const Elf_Sym *last_def; - - if (symnum == last_symnum && refobj == _rtld_last_refobj - && !(flags & SYMLOOK_IN_PLT)) { - *defobj_out = last_defobj; - return last_def; - } -#endif - ref = refobj->symtab + symnum; name = refobj->strtab + ref->st_name; @@ -409,18 +375,6 @@ _rtld_find_symdef(unsigned long symnum, if (def != NULL) { *defobj_out = defobj; -#ifdef COMBRELOC - if (!(flags & SYMLOOK_IN_PLT)) { - /* - * Cache the lookup arguments and results if this was - * non-PLT lookup. - */ - last_symnum = symnum; - _rtld_last_refobj = refobj; - last_def = def; - last_defobj = defobj; - } -#endif } else { rdbg(("lookup failed")); _rtld_error("%s: Undefined %ssymbol \"%s\" (symnum = %ld)", Index: src/libexec/ld.elf_so/arch/aarch64/mdreloc.c diff -u src/libexec/ld.elf_so/arch/aarch64/mdreloc.c:1.2 src/libexec/ld.elf_so/arch/aarch64/mdreloc.c:1.3 --- src/libexec/ld.elf_so/arch/aarch64/mdreloc.c:1.2 Mon Aug 25 20:40:52 2014 +++ src/libexec/ld.elf_so/arch/aarch64/mdreloc.c Mon Jun 19 11:57:01 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: mdreloc.c,v 1.2 2014/08/25 20:40:52 joerg Exp $ */ +/* $NetBSD: mdreloc.c,v 1.3 2017/06/19 11:57:01 joerg Exp $ */ /*- * Copyright (c) 2014 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: mdreloc.c,v 1.2 2014/08/25 20:40:52 joerg Exp $"); +__RCSID("$NetBSD: mdreloc.c,v 1.3 2017/06/19 11:57:01 joerg Exp $"); #endif /* not lint */ #include <sys/types.h> @@ -78,27 +78,43 @@ _rtld_relocate_nonplt_self(Elf_Dyn *dynp int _rtld_relocate_nonplt_objects(Obj_Entry *obj) { - + const Elf_Sym *def = NULL; + const Obj_Entry *defobj = NULL; + unsigned long last_symnum = ULONG_MAX; + for (const Elf_Rela *rela = obj->rela; rela < obj->relalim; rela++) { Elf_Addr *where; - const Elf_Sym *def; - const Obj_Entry *defobj; unsigned long symnum; Elf_Addr addend; where = (Elf_Addr *)(obj->relocbase + rela->r_offset); - symnum = ELF_R_SYM(rela->r_info); addend = rela->r_addend; switch (ELF_R_TYPE(rela->r_info)) { + case R_TYPE(ABS64): /* word B + S + A */ + case R_TYPE(GLOB_DAT): /* word B + S */ + case R_TLS_TYPE(TLS_DTPREL): + case R_TLS_TYPE(TLS_DTPMOD): + case R_TLS_TYPE(TLS_TPREL): + symnum = ELF_R_SYM(rela->r_info); + if (last_symnum != symnum) { + last_symnum = symnum; + def = _rtld_find_symdef(symnum, obj, &defobj, + false); + if (def == NULL) + return -1; + } + + default: + break; + } + + switch (ELF_R_TYPE(rela->r_info)) { case R_TYPE(NONE): break; case R_TYPE(ABS64): /* word B + S + A */ case R_TYPE(GLOB_DAT): /* word B + S */ - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; *where = addend + (Elf_Addr)defobj->relocbase + def->st_value; rdbg(("ABS64/GLOB_DAT %s in %s --> %p @ %p in %s", @@ -129,10 +145,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry break; case R_TLS_TYPE(TLS_DTPREL): - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; - *where = addend + (Elf_Addr)(def->st_value); rdbg(("TLS_DTPOFF32 %s in %s --> %p", @@ -141,10 +153,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry break; case R_TLS_TYPE(TLS_DTPMOD): - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; - *where = (Elf_Addr)(defobj->tlsindex); rdbg(("TLS_DTPMOD %s in %s --> %p", @@ -154,10 +162,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry break; case R_TLS_TYPE(TLS_TPREL): - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; - if (!defobj->tls_done && _rtld_tls_offset_allocate(obj)) return -1; @@ -172,7 +176,8 @@ _rtld_relocate_nonplt_objects(Obj_Entry default: rdbg(("sym = %lu, type = %lu, offset = %p, " "contents = %p, symbol = %s", - symnum, (u_long)ELF_R_TYPE(rela->r_info), + (u_long)ELF_R_SYM(rela->r_info), + (u_long)ELF_R_TYPE(rela->r_info), (void *)rela->r_offset, *where, obj->strtab + obj->symtab[symnum].st_name)); _rtld_error("%s: Unsupported relocation type %ld " Index: src/libexec/ld.elf_so/arch/alpha/alpha_reloc.c diff -u src/libexec/ld.elf_so/arch/alpha/alpha_reloc.c:1.41 src/libexec/ld.elf_so/arch/alpha/alpha_reloc.c:1.42 --- src/libexec/ld.elf_so/arch/alpha/alpha_reloc.c:1.41 Mon Aug 25 20:40:52 2014 +++ src/libexec/ld.elf_so/arch/alpha/alpha_reloc.c Mon Jun 19 11:57:01 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: alpha_reloc.c,v 1.41 2014/08/25 20:40:52 joerg Exp $ */ +/* $NetBSD: alpha_reloc.c,v 1.42 2017/06/19 11:57:01 joerg Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -62,7 +62,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: alpha_reloc.c,v 1.41 2014/08/25 20:40:52 joerg Exp $"); +__RCSID("$NetBSD: alpha_reloc.c,v 1.42 2017/06/19 11:57:01 joerg Exp $"); #endif /* not lint */ #include <sys/types.h> @@ -200,16 +200,36 @@ _rtld_relocate_nonplt_objects(Obj_Entry { const Elf_Rela *rela; Elf_Addr target = -1; + const Elf_Sym *def = NULL; + const Obj_Entry *defobj = NULL; + unsigned long last_symnum = ULONG_MAX; for (rela = obj->rela; rela < obj->relalim; rela++) { Elf_Addr *where; - const Elf_Sym *def; - const Obj_Entry *defobj; Elf_Addr tmp; unsigned long symnum; where = (Elf_Addr *)(obj->relocbase + rela->r_offset); - symnum = ELF_R_SYM(rela->r_info); + + switch (ELF_R_TYPE(rela->r_info)) { + case R_TYPE(REFQUAD): + case R_TYPE(GLOB_DAT): + case R_TYPE(TPREL64): + case R_TYPE(DTPMOD64): + case R_TYPE(DTPREL64): + symnum = ELF_R_SYM(rela->r_info); + if (last_symnum != symnum) { + last_symnum = symnum; + def = _rtld_find_symdef(symnum, obj, &defobj, + false); + if (def == NULL) + return -1; + } + break; + + default: + break; + } switch (ELF_R_TYPE(rela->r_info)) { case R_TYPE(NONE): @@ -217,9 +237,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry case R_TYPE(REFQUAD): case R_TYPE(GLOB_DAT): - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; target = (Elf_Addr)(defobj->relocbase + def->st_value); @@ -263,10 +280,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry break; case R_TYPE(TPREL64): - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; - if (!defobj->tls_done && _rtld_tls_offset_allocate(obj)) return -1; @@ -287,10 +300,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry break; case R_TYPE(DTPMOD64): - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; - tmp = (Elf64_Addr)defobj->tlsindex; if (__predict_true(RELOC_ALIGNED_P(where))) *where = tmp; @@ -304,10 +313,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry break; case R_TYPE(DTPREL64): - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; - tmp = (Elf64_Addr)(def->st_value + rela->r_addend); if (__predict_true(RELOC_ALIGNED_P(where))) *where = tmp; @@ -323,7 +328,8 @@ _rtld_relocate_nonplt_objects(Obj_Entry default: rdbg(("sym = %lu, type = %lu, offset = %p, " "addend = %p, contents = %p, symbol = %s", - symnum, (u_long)ELF_R_TYPE(rela->r_info), + (u_long)ELF_R_SYM(rela->r_info), + (u_long)ELF_R_TYPE(rela->r_info), (void *)rela->r_offset, (void *)rela->r_addend, (void *)load_ptr(where), obj->strtab + obj->symtab[symnum].st_name)); Index: src/libexec/ld.elf_so/arch/arm/mdreloc.c diff -u src/libexec/ld.elf_so/arch/arm/mdreloc.c:1.38 src/libexec/ld.elf_so/arch/arm/mdreloc.c:1.39 --- src/libexec/ld.elf_so/arch/arm/mdreloc.c:1.38 Mon Aug 25 20:40:52 2014 +++ src/libexec/ld.elf_so/arch/arm/mdreloc.c Mon Jun 19 11:57:01 2017 @@ -1,8 +1,8 @@ -/* $NetBSD: mdreloc.c,v 1.38 2014/08/25 20:40:52 joerg Exp $ */ +/* $NetBSD: mdreloc.c,v 1.39 2017/06/19 11:57:01 joerg Exp $ */ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: mdreloc.c,v 1.38 2014/08/25 20:40:52 joerg Exp $"); +__RCSID("$NetBSD: mdreloc.c,v 1.39 2017/06/19 11:57:01 joerg Exp $"); #endif /* not lint */ #include <sys/types.h> @@ -74,16 +74,37 @@ int _rtld_relocate_nonplt_objects(Obj_Entry *obj) { const Elf_Rel *rel; + const Elf_Sym *def = NULL; + const Obj_Entry *defobj = NULL; + unsigned long last_symnum = ULONG_MAX; for (rel = obj->rel; rel < obj->rellim; rel++) { Elf_Addr *where; - const Elf_Sym *def; - const Obj_Entry *defobj; Elf_Addr tmp; unsigned long symnum; where = (Elf_Addr *)(obj->relocbase + rel->r_offset); - symnum = ELF_R_SYM(rel->r_info); + + switch (ELF_R_TYPE(rel->r_info)) { + case R_TYPE(PC24): /* word32 S - P + A */ + case R_TYPE(ABS32): /* word32 B + S + A */ + case R_TYPE(GLOB_DAT): /* word32 B + S */ + case R_TYPE(TLS_DTPOFF32): + case R_TYPE(TLS_DTPMOD32): + case R_TYPE(TLS_TPOFF32): + symnum = ELF_R_SYM(rel->r_info); + if (last_symnum != symnum) { + last_symnum = symnum; + def = _rtld_find_symdef(symnum, obj, &defobj, + false); + if (def == NULL) + return -1; + } + break; + + default: + break; + } switch (ELF_R_TYPE(rel->r_info)) { case R_TYPE(NONE): @@ -99,10 +120,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry addend = *where; if (addend & 0x00800000) addend |= 0xff000000; - - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; tmp = (Elf_Addr)obj->relocbase + def->st_value - (Elf_Addr)where + (addend << 2); if ((tmp & 0xfe000000) != 0xfe000000 && @@ -126,9 +143,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry case R_TYPE(ABS32): /* word32 B + S + A */ case R_TYPE(GLOB_DAT): /* word32 B + S */ - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; if (__predict_true(RELOC_ALIGNED_P(where))) { tmp = *where + (Elf_Addr)defobj->relocbase + def->st_value; @@ -180,10 +194,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry break; case R_TYPE(TLS_DTPOFF32): - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; - tmp = (Elf_Addr)(def->st_value); if (__predict_true(RELOC_ALIGNED_P(where))) *where = tmp; @@ -196,10 +206,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry break; case R_TYPE(TLS_DTPMOD32): - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; - tmp = (Elf_Addr)(defobj->tlsindex); if (__predict_true(RELOC_ALIGNED_P(where))) *where = tmp; @@ -213,10 +219,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry break; case R_TYPE(TLS_TPOFF32): - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; - if (!defobj->tls_done && _rtld_tls_offset_allocate(obj)) return -1; @@ -235,7 +237,8 @@ _rtld_relocate_nonplt_objects(Obj_Entry default: rdbg(("sym = %lu, type = %lu, offset = %p, " "contents = %p, symbol = %s", - symnum, (u_long)ELF_R_TYPE(rel->r_info), + (u_long)ELF_R_SYM(rel->r_info), + (u_long)ELF_R_TYPE(rel->r_info), (void *)rel->r_offset, (void *)load_ptr(where), obj->strtab + obj->symtab[symnum].st_name)); _rtld_error("%s: Unsupported relocation type %ld " Index: src/libexec/ld.elf_so/arch/hppa/hppa_reloc.c diff -u src/libexec/ld.elf_so/arch/hppa/hppa_reloc.c:1.43 src/libexec/ld.elf_so/arch/hppa/hppa_reloc.c:1.44 --- src/libexec/ld.elf_so/arch/hppa/hppa_reloc.c:1.43 Mon Aug 25 20:40:52 2014 +++ src/libexec/ld.elf_so/arch/hppa/hppa_reloc.c Mon Jun 19 11:57:01 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: hppa_reloc.c,v 1.43 2014/08/25 20:40:52 joerg Exp $ */ +/* $NetBSD: hppa_reloc.c,v 1.44 2017/06/19 11:57:01 joerg Exp $ */ /*- * Copyright (c) 2002, 2004 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: hppa_reloc.c,v 1.43 2014/08/25 20:40:52 joerg Exp $"); +__RCSID("$NetBSD: hppa_reloc.c,v 1.44 2017/06/19 11:57:01 joerg Exp $"); #endif /* not lint */ #include <stdlib.h> @@ -413,46 +413,23 @@ int _rtld_relocate_nonplt_objects(Obj_Entry *obj) { const Elf_Rela *rela; + const Elf_Sym *def = NULL; + const Obj_Entry *defobj = NULL; + unsigned long last_symnum = ULONG_MAX; for (rela = obj->rela; rela < obj->relalim; rela++) { Elf_Addr *where; - const Elf_Sym *def; - const Obj_Entry *defobj; Elf_Addr tmp; unsigned long symnum; where = (Elf_Addr *)(obj->relocbase + rela->r_offset); - symnum = ELF_R_SYM(rela->r_info); - - switch (ELF_R_TYPE(rela->r_info)) { - case R_TYPE(NONE): - break; - - case R_TYPE(DIR32): - if (symnum) { - /* - * This is either a DIR32 against a symbol - * (def->st_name != 0), or against a local - * section (def->st_name == 0). - */ - def = obj->symtab + symnum; - defobj = obj; - if (def->st_name != 0) - def = _rtld_find_symdef(symnum, obj, - &defobj, false); - if (def == NULL) - return -1; - - tmp = (Elf_Addr)(defobj->relocbase + - def->st_value + rela->r_addend); - if (load_ptr(where) != tmp) - store_ptr(where, tmp); - rdbg(("DIR32 %s in %s --> %p in %s", - obj->strtab + obj->symtab[symnum].st_name, - obj->path, (void *)load_ptr(where), - defobj->path)); - } else { + /* First, handle DIR32 and PLABEL32 without symbol. */ + if (ELF_R_SYM(rela->r_info) == 0) { + switch (ELF_R_TYPE(rela->r_info)) { + default: + break; + case R_TYPE(DIR32): tmp = (Elf_Addr)(obj->relocbase + rela->r_addend); @@ -460,27 +437,8 @@ _rtld_relocate_nonplt_objects(Obj_Entry store_ptr(where, tmp); rdbg(("DIR32 in %s --> %p", obj->path, (void *)load_ptr(where))); - } - break; - - case R_TYPE(PLABEL32): - if (symnum) { - def = _rtld_find_symdef(symnum, obj, &defobj, - false); - if (def == NULL) - return -1; - - tmp = _rtld_function_descriptor_alloc(defobj, - def, rela->r_addend); - if (tmp == (Elf_Addr)-1) - return -1; - - if (*where != tmp) - *where = tmp; - rdbg(("PLABEL32 %s in %s --> %p in %s", - obj->strtab + obj->symtab[symnum].st_name, - obj->path, (void *)*where, defobj->path)); - } else { + continue; + case R_TYPE(PLABEL32): /* * This is a PLABEL for a static function, and * the dynamic linker has both allocated a PLT @@ -505,8 +463,68 @@ _rtld_relocate_nonplt_objects(Obj_Entry *where = tmp; rdbg(("PLABEL32 in %s --> %p", obj->path, (void *)*where)); + continue; + } + } + + switch (ELF_R_TYPE(rela->r_info)) { + case R_TYPE(DIR32): + case R_TYPE(PLABEL32): + case R_TYPE(COPY): + case R_TYPE(TLS_TPREL32): + case R_TYPE(TLS_DTPMOD32): + case R_TYPE(TLS_DTPOFF32): + symnum = ELF_R_SYM(rela->r_info); + if (last_symnum != symnum) { + last_symnum = symnum; + if (ELF_R_TYPE(rela->r_info) == R_TYPE(DIR32)) { + /* + * DIR32 relocation against local + * symbols are special... + */ + def = obj->symtab + symnum; + defobj = obj; + if (def->st_name == 0) + break; + } + def = _rtld_find_symdef(symnum, obj, &defobj, + false); + if (def == NULL) + return -1; } break; + default: + break; + } + + switch (ELF_R_TYPE(rela->r_info)) { + case R_TYPE(NONE): + break; + + case R_TYPE(DIR32): + tmp = (Elf_Addr)(defobj->relocbase + + def->st_value + rela->r_addend); + + if (load_ptr(where) != tmp) + store_ptr(where, tmp); + rdbg(("DIR32 %s in %s --> %p in %s", + obj->strtab + obj->symtab[symnum].st_name, + obj->path, (void *)load_ptr(where), + defobj->path)); + break; + + case R_TYPE(PLABEL32): + tmp = _rtld_function_descriptor_alloc(defobj, + def, rela->r_addend); + if (tmp == (Elf_Addr)-1) + return -1; + + if (*where != tmp) + *where = tmp; + rdbg(("PLABEL32 %s in %s --> %p in %s", + obj->strtab + obj->symtab[symnum].st_name, + obj->path, (void *)*where, defobj->path)); + break; case R_TYPE(COPY): /* @@ -525,10 +543,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry break; case R_TYPE(TLS_TPREL32): - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; - if (!defobj->tls_done && _rtld_tls_offset_allocate(obj)) return -1; @@ -541,10 +555,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry break; case R_TYPE(TLS_DTPMOD32): - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; - *where = (Elf_Addr)(defobj->tlsindex); rdbg(("TLS_DTPMOD32 %s in %s --> %p", @@ -554,10 +564,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry break; case R_TYPE(TLS_DTPOFF32): - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; - *where = (Elf_Addr)(def->st_value); rdbg(("TLS_DTPOFF32 %s in %s --> %p", Index: src/libexec/ld.elf_so/arch/i386/mdreloc.c diff -u src/libexec/ld.elf_so/arch/i386/mdreloc.c:1.37 src/libexec/ld.elf_so/arch/i386/mdreloc.c:1.38 --- src/libexec/ld.elf_so/arch/i386/mdreloc.c:1.37 Sun Aug 31 20:06:22 2014 +++ src/libexec/ld.elf_so/arch/i386/mdreloc.c Mon Jun 19 11:57:01 2017 @@ -1,8 +1,8 @@ -/* $NetBSD: mdreloc.c,v 1.37 2014/08/31 20:06:22 joerg Exp $ */ +/* $NetBSD: mdreloc.c,v 1.38 2017/06/19 11:57:01 joerg Exp $ */ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: mdreloc.c,v 1.37 2014/08/31 20:06:22 joerg Exp $"); +__RCSID("$NetBSD: mdreloc.c,v 1.38 2017/06/19 11:57:01 joerg Exp $"); #endif /* not lint */ #include <sys/types.h> @@ -53,16 +53,39 @@ _rtld_relocate_nonplt_objects(Obj_Entry { const Elf_Rel *rel; Elf_Addr target = 0; + const Elf_Sym *def = NULL; + const Obj_Entry *defobj = NULL; + unsigned long last_symnum = ULONG_MAX; for (rel = obj->rel; rel < obj->rellim; rel++) { Elf_Addr *where; - const Elf_Sym *def; - const Obj_Entry *defobj; Elf_Addr tmp; unsigned long symnum; where = (Elf_Addr *)(obj->relocbase + rel->r_offset); - symnum = ELF_R_SYM(rel->r_info); + + switch (ELF_R_TYPE(rel->r_info)) { + case R_TYPE(PC32): + case R_TYPE(GOT32): + case R_TYPE(32): + case R_TYPE(GLOB_DAT): + case R_TYPE(TLS_TPOFF): + case R_TYPE(TLS_TPOFF32): + case R_TYPE(TLS_DTPMOD32): + case R_TYPE(TLS_DTPOFF32): + symnum = ELF_R_SYM(rel->r_info); + if (symnum != last_symnum) { + last_symnum = symnum; + def = _rtld_find_symdef(symnum, obj, &defobj, + false); + if (def == NULL) + return -1; + } + break; + default: + break; + } + switch (ELF_R_TYPE(rel->r_info)) { case R_TYPE(NONE): @@ -70,9 +93,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry #if 1 /* XXX should not occur */ case R_TYPE(PC32): - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; target = (Elf_Addr)(defobj->relocbase + def->st_value); *where += target - (Elf_Addr)where; @@ -85,9 +105,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry #endif case R_TYPE(32): case R_TYPE(GLOB_DAT): - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; target = (Elf_Addr)(defobj->relocbase + def->st_value); tmp = target + *where; @@ -121,10 +138,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry break; case R_TYPE(TLS_TPOFF): - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; - if (!defobj->tls_done && _rtld_tls_offset_allocate(obj)) return -1; @@ -137,10 +150,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry break; case R_TYPE(TLS_TPOFF32): - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; - if (!defobj->tls_done && _rtld_tls_offset_allocate(obj)) return -1; @@ -152,10 +161,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry break; case R_TYPE(TLS_DTPMOD32): - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; - *where = (Elf_Addr)(defobj->tlsindex); rdbg(("TLS_DTPMOD32 %s in %s --> %p", @@ -164,10 +169,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry break; case R_TYPE(TLS_DTPOFF32): - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; - *where = (Elf_Addr)(def->st_value); rdbg(("TLS_DTPOFF32 %s in %s --> %p", @@ -179,7 +180,8 @@ _rtld_relocate_nonplt_objects(Obj_Entry default: rdbg(("sym = %lu, type = %lu, offset = %p, " "contents = %p, symbol = %s", - symnum, (u_long)ELF_R_TYPE(rel->r_info), + (u_long)ELF_R_SYM(rel->r_info), + (u_long)ELF_R_TYPE(rel->r_info), (void *)rel->r_offset, (void *)*where, obj->strtab + obj->symtab[symnum].st_name)); _rtld_error("%s: Unsupported relocation type %ld " Index: src/libexec/ld.elf_so/arch/m68k/mdreloc.c diff -u src/libexec/ld.elf_so/arch/m68k/mdreloc.c:1.31 src/libexec/ld.elf_so/arch/m68k/mdreloc.c:1.32 --- src/libexec/ld.elf_so/arch/m68k/mdreloc.c:1.31 Thu Apr 14 20:17:07 2016 +++ src/libexec/ld.elf_so/arch/m68k/mdreloc.c Mon Jun 19 11:57:01 2017 @@ -1,8 +1,8 @@ -/* $NetBSD: mdreloc.c,v 1.31 2016/04/14 20:17:07 skrll Exp $ */ +/* $NetBSD: mdreloc.c,v 1.32 2017/06/19 11:57:01 joerg Exp $ */ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: mdreloc.c,v 1.31 2016/04/14 20:17:07 skrll Exp $"); +__RCSID("$NetBSD: mdreloc.c,v 1.32 2017/06/19 11:57:01 joerg Exp $"); #endif /* not lint */ #include <sys/types.h> @@ -52,16 +52,37 @@ int _rtld_relocate_nonplt_objects(Obj_Entry *obj) { const Elf_Rela *rela; + const Elf_Sym *def = NULL; + const Obj_Entry *defobj = NULL; + unsigned long last_symnum = ULONG_MAX; for (rela = obj->rela; rela < obj->relalim; rela++) { Elf_Addr *where; - const Elf_Sym *def; - const Obj_Entry *defobj; Elf_Addr tmp; unsigned long symnum; where = (Elf_Addr *)(obj->relocbase + rela->r_offset); - symnum = ELF_R_SYM(rela->r_info); + + switch (ELF_R_TYPE(rela->r_info)) { + case R_TYPE(PC32): + case R_TYPE(GOT32): + case R_TYPE(32): + case R_TYPE(GLOB_DAT): + case R_TYPE(TLS_DTPMOD32): + case R_TYPE(TLS_DTPREL32): + case R_TYPE(TLS_TPREL32): + symnum = ELF_R_SYM(rela->r_info); + if (last_symnum != symnum) { + last_symnum = symnum; + def = _rtld_find_symdef(symnum, obj, &defobj, + false); + if (def == NULL) + return -1; + } + break; + default: + break; + } switch (ELF_R_TYPE(rela->r_info)) { case R_TYPE(NONE): @@ -69,10 +90,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry #if 1 /* XXX should not occur */ case R_TYPE(PC32): - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; - tmp = (Elf_Addr)(defobj->relocbase + def->st_value + rela->r_addend) - (Elf_Addr)where; if (*where != tmp) @@ -86,10 +103,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry #endif case R_TYPE(32): case R_TYPE(GLOB_DAT): - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; - tmp = (Elf_Addr)(defobj->relocbase + def->st_value + rela->r_addend); if (*where != tmp) @@ -122,10 +135,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry break; case R_TYPE(TLS_DTPMOD32): - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; - *where = (Elf_Addr)defobj->tlsindex; rdbg(("DTPMOD32 %s in %s --> %p in %s", obj->strtab + obj->symtab[symnum].st_name, @@ -133,10 +142,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry break; case R_TYPE(TLS_DTPREL32): - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; - if (!defobj->tls_done && _rtld_tls_offset_allocate(obj)) return -1; @@ -148,10 +153,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry break; case R_TYPE(TLS_TPREL32): - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; - if (!defobj->tls_done && _rtld_tls_offset_allocate(obj)) return -1; @@ -165,7 +166,8 @@ _rtld_relocate_nonplt_objects(Obj_Entry default: rdbg(("sym = %lu, type = %lu, offset = %p, " "addend = %p, contents = %p, symbol = %s", - symnum, (u_long)ELF_R_TYPE(rela->r_info), + (u_long)ELF_R_SYM(rela->r_info), + (u_long)ELF_R_TYPE(rela->r_info), (void *)rela->r_offset, (void *)rela->r_addend, (void *)*where, obj->strtab + obj->symtab[symnum].st_name)); Index: src/libexec/ld.elf_so/arch/mips/mips_reloc.c diff -u src/libexec/ld.elf_so/arch/mips/mips_reloc.c:1.65 src/libexec/ld.elf_so/arch/mips/mips_reloc.c:1.66 --- src/libexec/ld.elf_so/arch/mips/mips_reloc.c:1.65 Sat Feb 20 15:20:23 2016 +++ src/libexec/ld.elf_so/arch/mips/mips_reloc.c Mon Jun 19 11:57:01 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: mips_reloc.c,v 1.65 2016/02/20 15:20:23 christos Exp $ */ +/* $NetBSD: mips_reloc.c,v 1.66 2017/06/19 11:57:01 joerg Exp $ */ /* * Copyright 1997 Michael L. Hitch <mhi...@montana.edu> @@ -30,7 +30,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: mips_reloc.c,v 1.65 2016/02/20 15:20:23 christos Exp $"); +__RCSID("$NetBSD: mips_reloc.c,v 1.66 2017/06/19 11:57:01 joerg Exp $"); #endif /* not lint */ #include <sys/types.h> @@ -230,6 +230,7 @@ _rtld_relocate_nonplt_objects(Obj_Entry Elf_Addr *got = obj->pltgot; const Elf_Sym *sym, *def; const Obj_Entry *defobj; + unsigned long last_symnum = ULONG_MAX; Elf_Word i; #ifdef SUPPORT_OLD_BROKEN_LD int broken; @@ -313,14 +314,35 @@ _rtld_relocate_nonplt_objects(Obj_Entry got = obj->pltgot; for (rel = obj->rel; rel < obj->rellim; rel++) { - Elf_Word r_symndx, r_type; + unsigned long symnum; void *where; where = obj->relocbase + rel->r_offset; - r_symndx = ELF_R_SYM(rel->r_info); - r_type = ELF_R_TYPE(rel->r_info); - switch (r_type & 0xff) { + switch (ELF_R_TYPE(rel->r_info)) { +#if ELFSIZE == 64 + case R_TYPE(TLS_DTPMOD64): + case R_TYPE(TLS_DTPREL64): + case R_TYPE(TLS_TPREL64): +#else + case R_TYPE(TLS_DTPMOD32): + case R_TYPE(TLS_DTPREL32): + case R_TYPE(TLS_TPREL32): +#endif + symnum = ELF_R_SYM(rela->r_info); + if (last_symnum != symnum) { + last_symnum = symnum; + def = _rtld_find_symdef(symnum, obj, &defobj, + false); + if (def == NULL) + return -1; + } + break; + default: + break; + } + + switch (ELF_R_TYPE(rel->r_info)) { case R_TYPE(NONE): break; @@ -385,10 +407,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry Elf_Addr old = load_ptr(where, ELFSIZE / 8); Elf_Addr val = old; - def = _rtld_find_symdef(r_symndx, obj, &defobj, false); - if (def == NULL) - return -1; - val += (Elf_Addr)defobj->tlsindex; store_ptr(where, val, ELFSIZE / 8); @@ -407,10 +425,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry Elf_Addr old = load_ptr(where, ELFSIZE / 8); Elf_Addr val = old; - def = _rtld_find_symdef(r_symndx, obj, &defobj, false); - if (def == NULL) - return -1; - if (!defobj->tls_done && _rtld_tls_offset_allocate(obj)) return -1; @@ -432,10 +446,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry Elf_Addr old = load_ptr(where, ELFSIZE / 8); Elf_Addr val = old; - def = _rtld_find_symdef(r_symndx, obj, &defobj, false); - if (def == NULL) - return -1; - if (!defobj->tls_done && _rtld_tls_offset_allocate(obj)) return -1; @@ -452,7 +462,8 @@ _rtld_relocate_nonplt_objects(Obj_Entry default: rdbg(("sym = %lu, type = %lu, offset = %p, " "contents = %p, symbol = %s", - (u_long)r_symndx, (u_long)ELF_R_TYPE(rel->r_info), + (u_long)ELF_R_SYM(rel->r_info), + (u_long)ELF_R_TYPE(rel->r_info), (void *)rel->r_offset, (void *)load_ptr(where, sizeof(Elf_Sword)), obj->strtab + obj->symtab[r_symndx].st_name)); Index: src/libexec/ld.elf_so/arch/or1k/mdreloc.c diff -u src/libexec/ld.elf_so/arch/or1k/mdreloc.c:1.1 src/libexec/ld.elf_so/arch/or1k/mdreloc.c:1.2 --- src/libexec/ld.elf_so/arch/or1k/mdreloc.c:1.1 Wed Sep 3 19:34:26 2014 +++ src/libexec/ld.elf_so/arch/or1k/mdreloc.c Mon Jun 19 11:57:02 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: mdreloc.c,v 1.1 2014/09/03 19:34:26 matt Exp $ */ +/* $NetBSD: mdreloc.c,v 1.2 2017/06/19 11:57:02 joerg Exp $ */ /*- * Copyright (c) 2014 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: mdreloc.c,v 1.1 2014/09/03 19:34:26 matt Exp $"); +__RCSID("$NetBSD: mdreloc.c,v 1.2 2017/06/19 11:57:02 joerg Exp $"); #endif /* not lint */ #include <stdarg.h> @@ -93,16 +93,35 @@ int _rtld_relocate_nonplt_objects(Obj_Entry *obj) { const Elf_Rela *rela; + const Elf_Sym *def = NULL; + const Obj_Entry *defobj = NULL; + unsigned long last_symnum = ULONG_MAX; for (rela = obj->rela; rela < obj->relalim; rela++) { Elf_Addr *where; - const Elf_Sym *def; - const Obj_Entry *defobj; Elf_Addr tmp; unsigned long symnum; where = (Elf_Addr *)(obj->relocbase + rela->r_offset); - symnum = ELF_R_SYM(rela->r_info); + + switch (ELF_R_TYPE(rela->r_info)) { + case R_TYPE(32): /* <address> S + A */ + case R_TYPE(GLOB_DAT): /* <address> S + A */ + case R_TYPE(TLS_DTPMOD): + case R_TYPE(TLS_DTPOFF): + case R_TYPE(TLS_TPOFF): + symnum = ELF_R_SYM(rela->r_info); + if (last_symnum != symnum) { + last_symnum = symnum; + def = _rtld_find_symdef(symnum, obj, &defobj, + false); + if (def == NULL) + return -1; + } + break; + default: + break; + } switch (ELF_R_TYPE(rela->r_info)) { #if 1 /* XXX Should not be necessary. */ @@ -113,10 +132,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry case R_TYPE(32): /* <address> S + A */ case R_TYPE(GLOB_DAT): /* <address> S + A */ - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; - tmp = (Elf_Addr)(defobj->relocbase + def->st_value + rela->r_addend); if (*where != tmp) @@ -149,10 +164,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry break; case R_TYPE(TLS_DTPMOD): - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; - *where = (Elf_Addr)defobj->tlsindex; rdbg(("DTPMOD32 %s in %s --> %p in %s", obj->strtab + obj->symtab[symnum].st_name, @@ -160,10 +171,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry break; case R_TYPE(TLS_DTPOFF): - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; - if (!defobj->tls_done && _rtld_tls_offset_allocate(obj)) return -1; @@ -175,10 +182,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry break; case R_TYPE(TLS_TPOFF): - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; - if (!defobj->tls_done && _rtld_tls_offset_allocate(obj)) return -1; @@ -192,7 +195,8 @@ _rtld_relocate_nonplt_objects(Obj_Entry default: rdbg(("sym = %lu, type = %lu, offset = %p, " "addend = %p, contents = %p, symbol = %s", - symnum, (u_long)ELF_R_TYPE(rela->r_info), + (u_long)ELF_R_SYM(rela->r_info), + (u_long)ELF_R_TYPE(rela->r_info), (void *)rela->r_offset, (void *)rela->r_addend, (void *)*where, obj->strtab + obj->symtab[symnum].st_name)); Index: src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c diff -u src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c:1.53 src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c:1.54 --- src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c:1.53 Mon Aug 25 20:40:52 2014 +++ src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c Mon Jun 19 11:57:02 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ppc_reloc.c,v 1.53 2014/08/25 20:40:52 joerg Exp $ */ +/* $NetBSD: ppc_reloc.c,v 1.54 2017/06/19 11:57:02 joerg Exp $ */ /*- * Copyright (C) 1998 Tsubai Masanari @@ -30,7 +30,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: ppc_reloc.c,v 1.53 2014/08/25 20:40:52 joerg Exp $"); +__RCSID("$NetBSD: ppc_reloc.c,v 1.54 2017/06/19 11:57:02 joerg Exp $"); #endif /* not lint */ #include <stdarg.h> @@ -178,16 +178,39 @@ int _rtld_relocate_nonplt_objects(Obj_Entry *obj) { const Elf_Rela *rela; + const Elf_Sym *def = NULL; + const Obj_Entry *defobj = NULL; + unsigned long last_symnum = ULONG_MAX; for (rela = obj->rela; rela < obj->relalim; rela++) { Elf_Addr *where; - const Elf_Sym *def; - const Obj_Entry *defobj; Elf_Addr tmp; unsigned long symnum; where = (Elf_Addr *)(obj->relocbase + rela->r_offset); - symnum = ELF_R_SYM(rela->r_info); + + switch (ELF_R_TYPE(rela->r_info)) { +#ifdef _LP64 + case R_TYPE(ADDR64): /* <address> S + A */ +#else + case R_TYPE(ADDR32): /* <address> S + A */ +#endif + case R_TYPE(GLOB_DAT): /* <address> S + A */ + case R_TYPE(DTPMOD): + case R_TYPE(DTPREL): + case R_TYPE(TPREL): + symnum = ELF_R_SYM(rela->r_info); + if (last_symnum != symnum) { + last_symnum = symnum; + def = _rtld_find_symdef(symnum, obj, &defobj, + false); + if (def == NULL) + return -1; + } + break; + default: + break; + } switch (ELF_R_TYPE(rela->r_info)) { #if 1 /* XXX Should not be necessary. */ @@ -202,10 +225,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry case R_TYPE(ADDR32): /* <address> S + A */ #endif case R_TYPE(GLOB_DAT): /* <address> S + A */ - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; - tmp = (Elf_Addr)(defobj->relocbase + def->st_value + rela->r_addend); if (*where != tmp) @@ -238,10 +257,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry break; case R_TYPE(DTPMOD): - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; - *where = (Elf_Addr)defobj->tlsindex; rdbg(("DTPMOD32 %s in %s --> %p in %s", obj->strtab + obj->symtab[symnum].st_name, @@ -249,10 +264,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry break; case R_TYPE(DTPREL): - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; - if (!defobj->tls_done && _rtld_tls_offset_allocate(obj)) return -1; @@ -264,10 +275,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry break; case R_TYPE(TPREL): - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; - if (!defobj->tls_done && _rtld_tls_offset_allocate(obj)) return -1; @@ -281,7 +288,8 @@ _rtld_relocate_nonplt_objects(Obj_Entry default: rdbg(("sym = %lu, type = %lu, offset = %p, " "addend = %p, contents = %p, symbol = %s", - symnum, (u_long)ELF_R_TYPE(rela->r_info), + (u_long)ELF_R_SYM(rela->r_info), + (u_long)ELF_R_TYPE(rela->r_info), (void *)rela->r_offset, (void *)rela->r_addend, (void *)*where, obj->strtab + obj->symtab[symnum].st_name)); Index: src/libexec/ld.elf_so/arch/riscv/mdreloc.c diff -u src/libexec/ld.elf_so/arch/riscv/mdreloc.c:1.2 src/libexec/ld.elf_so/arch/riscv/mdreloc.c:1.3 --- src/libexec/ld.elf_so/arch/riscv/mdreloc.c:1.2 Fri Mar 27 23:14:53 2015 +++ src/libexec/ld.elf_so/arch/riscv/mdreloc.c Mon Jun 19 11:57:02 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: mdreloc.c,v 1.2 2015/03/27 23:14:53 matt Exp $ */ +/* $NetBSD: mdreloc.c,v 1.3 2017/06/19 11:57:02 joerg Exp $ */ /*- * Copyright (c) 2014 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: mdreloc.c,v 1.2 2015/03/27 23:14:53 matt Exp $"); +__RCSID("$NetBSD: mdreloc.c,v 1.3 2017/06/19 11:57:02 joerg Exp $"); #endif /* not lint */ #include <sys/types.h> @@ -99,14 +99,32 @@ int _rtld_relocate_nonplt_objects(Obj_Entry *obj) { const Elf_Rela *rela; - const Elf_Sym *def; - const Obj_Entry *defobj; + const Elf_Sym *def = NULL; + const Obj_Entry *defobj = NULL; + unsigned long last_symnum = ULONG_MAX; for (rela = obj->rela; rela < obj->relalim; rela++) { Elf_Addr * const where = (Elf_Addr *)(obj->relocbase + rela->r_offset); - const Elf_Word r_symndx = ELF_R_SYM(rela->r_info); const Elf_Word r_type = ELF_R_TYPE(rela->r_info); + unsigned long symnum; + + switch (r_type) { + case R_TYPESZ(ADDR): + case R_TYPESZ(TLS_DTPMOD): + case R_TYPESZ(TLS_DTPREL): + symnum = ELF_R_SYM(rela->r_info); + if (last_symnum != symnum) { + last_symnum = symnum; + def = _rtld_find_symdef(symnum, obj, &defobj, + false); + if (def == NULL) + return -1; + } + break; + default: + break; + } switch (r_type) { case R_TYPE(NONE): @@ -126,10 +144,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry } case R_TYPESZ(ADDR): { - def = _rtld_find_symdef(r_symndx, obj, &defobj, false); - if (def == NULL) - return -1; - Elf_Addr val = (Elf_Addr)defobj->relocbase + rela->r_addend; *where = val; @@ -140,10 +154,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry } case R_TYPESZ(TLS_DTPMOD): { - def = _rtld_find_symdef(r_symndx, obj, &defobj, false); - if (def == NULL) - return -1; - Elf_Addr val = (Elf_Addr)defobj->tlsindex + rela->r_addend; *where = val; @@ -157,10 +167,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry Elf_Addr old = *where; Elf_Addr val = old; - def = _rtld_find_symdef(r_symndx, obj, &defobj, false); - if (def == NULL) - return -1; - if (!defobj->tls_done && _rtld_tls_offset_allocate(obj)) return -1; @@ -176,7 +182,8 @@ _rtld_relocate_nonplt_objects(Obj_Entry default: rdbg(("sym = %lu, type = %lu, offset = %p, " "addend = %p, contents = %p, symbol = %s", - (u_long)r_symndx, (u_long)r_type, + (u_long)ELF_R_SYM(rela->r_info), + (u_long)ELF_R_TYPE(rela->r_info), (void *)rela->r_offset, (void *)rela->r_addend, (void *)load_ptr(where, sizeof(Elf_Addr)), obj->strtab + obj->symtab[r_symndx].st_name)); Index: src/libexec/ld.elf_so/arch/sh3/mdreloc.c diff -u src/libexec/ld.elf_so/arch/sh3/mdreloc.c:1.32 src/libexec/ld.elf_so/arch/sh3/mdreloc.c:1.33 --- src/libexec/ld.elf_so/arch/sh3/mdreloc.c:1.32 Thu Apr 14 20:17:07 2016 +++ src/libexec/ld.elf_so/arch/sh3/mdreloc.c Mon Jun 19 11:57:02 2017 @@ -1,8 +1,8 @@ -/* $NetBSD: mdreloc.c,v 1.32 2016/04/14 20:17:07 skrll Exp $ */ +/* $NetBSD: mdreloc.c,v 1.33 2017/06/19 11:57:02 joerg Exp $ */ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: mdreloc.c,v 1.32 2016/04/14 20:17:07 skrll Exp $"); +__RCSID("$NetBSD: mdreloc.c,v 1.33 2017/06/19 11:57:02 joerg Exp $"); #endif /* not lint */ #include <sys/types.h> @@ -61,7 +61,27 @@ _rtld_relocate_nonplt_objects(Obj_Entry unsigned long symnum; where = (Elf_Addr *)(obj->relocbase + rela->r_offset); - symnum = ELF_R_SYM(rela->r_info); + + switch (ELF_R_TYPE(rela->r_info)) { + case R_TYPE(GOT32): + case R_TYPE(REL32): + case R_TYPE(DIR32): + case R_TYPE(GLOB_DAT): + case R_TYPE(TLS_DTPOFF32): + case R_TYPE(TLS_DTPMOD32): + case R_TYPE(TLS_TPOFF32): + symnum = ELF_R_SYM(rela->r_info); + if (last_symnum != symnum) { + last_symnum = symnum; + def = _rtld_find_symdef(symnum, obj, &defobj, + false); + if (def == NULL) + return -1; + } + break; + default: + break; + } switch (ELF_R_TYPE(rela->r_info)) { case R_TYPE(NONE): @@ -69,10 +89,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry #if 1 /* XXX should not occur */ case R_TYPE(GOT32): - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; - tmp = (Elf_Addr)(defobj->relocbase + def->st_value + rela->r_addend); if (*where != tmp) @@ -83,10 +99,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry break; case R_TYPE(REL32): - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; - tmp = (Elf_Addr)(defobj->relocbase + def->st_value + rela->r_addend) - (Elf_Addr)where; if (*where != tmp) @@ -98,10 +110,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry #endif case R_TYPE(DIR32): - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; - tmp = (Elf_Addr)(defobj->relocbase + def->st_value + rela->r_addend); if (*where != tmp) @@ -112,10 +120,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry break; case R_TYPE(GLOB_DAT): - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; - tmp = (Elf_Addr)(defobj->relocbase + def->st_value) + rela->r_addend; if (*where != tmp) @@ -151,10 +155,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry break; case R_TYPE(TLS_DTPOFF32): - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; - *where = (Elf_Addr)(def->st_value); rdbg(("TLS_DTPOFF32 %s in %s --> %p", @@ -163,10 +163,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry break; case R_TYPE(TLS_DTPMOD32): - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; - *where = (Elf_Addr)(defobj->tlsindex); rdbg(("TLS_DTPMOD32 %s in %s --> %p", @@ -176,10 +172,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry break; case R_TYPE(TLS_TPOFF32): - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; - if (!defobj->tls_done && _rtld_tls_offset_allocate(obj)) return -1; @@ -196,7 +188,8 @@ _rtld_relocate_nonplt_objects(Obj_Entry default: rdbg(("sym = %lu, type = %lu, offset = %p, " "addend = %p, contents = %p, symbol = %s", - symnum, (u_long)ELF_R_TYPE(rela->r_info), + (u_long)ELF_R_SYM(rela->r_info), + (u_long)ELF_R_TYPE(rela->r_info), (void *)rela->r_offset, (void *)rela->r_addend, (void *)*where, obj->strtab + obj->symtab[symnum].st_name)); Index: src/libexec/ld.elf_so/arch/sparc/mdreloc.c diff -u src/libexec/ld.elf_so/arch/sparc/mdreloc.c:1.49 src/libexec/ld.elf_so/arch/sparc/mdreloc.c:1.50 --- src/libexec/ld.elf_so/arch/sparc/mdreloc.c:1.49 Thu Jun 15 23:08:46 2017 +++ src/libexec/ld.elf_so/arch/sparc/mdreloc.c Mon Jun 19 11:57:02 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: mdreloc.c,v 1.49 2017/06/15 23:08:46 joerg Exp $ */ +/* $NetBSD: mdreloc.c,v 1.50 2017/06/19 11:57:02 joerg Exp $ */ /*- * Copyright (c) 1999, 2002 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: mdreloc.c,v 1.49 2017/06/15 23:08:46 joerg Exp $"); +__RCSID("$NetBSD: mdreloc.c,v 1.50 2017/06/19 11:57:02 joerg Exp $"); #endif /* not lint */ #include <errno.h> @@ -201,16 +201,16 @@ int _rtld_relocate_nonplt_objects(Obj_Entry *obj) { const Elf_Rela *rela; + const Elf_Sym *def = NULL; + const Obj_Entry *defobj = NULL; + unsigned long last_symnum = ULONG_MAX; for (rela = obj->rela; rela < obj->relalim; rela++) { Elf_Addr *where; Elf_Word type, value, mask; - const Elf_Sym *def = NULL; - const Obj_Entry *defobj = NULL; unsigned long symnum; where = (Elf_Addr *) (obj->relocbase + rela->r_offset); - symnum = ELF_R_SYM(rela->r_info); type = ELF_R_TYPE(rela->r_info); if (type == R_TYPE(NONE)) @@ -233,17 +233,23 @@ _rtld_relocate_nonplt_objects(Obj_Entry value = rela->r_addend; + if (RELOC_RESOLVE_SYMBOL(type) || RELOC_TLS(type)) { + symnum = ELF_R_SYM(rela->r_info); + if (last_symnum != symnum) { + last_symnum = symnum; + def = _rtld_find_symdef(symnum, obj, &defobj, + false); + if (def == NULL) + return -1; + } + } + /* * Handle TLS relocations here, they are different. */ if (RELOC_TLS(type)) { switch (type) { case R_TYPE(TLS_DTPMOD32): - def = _rtld_find_symdef(symnum, obj, - &defobj, false); - if (def == NULL) - return -1; - *where = (Elf_Addr)defobj->tlsindex; rdbg(("TLS_DTPMOD32 %s in %s --> %p", @@ -254,11 +260,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry break; case R_TYPE(TLS_DTPOFF32): - def = _rtld_find_symdef(symnum, obj, - &defobj, false); - if (def == NULL) - return -1; - *where = (Elf_Addr)(def->st_value + rela->r_addend); @@ -270,11 +271,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry break; case R_TYPE(TLS_TPOFF32): - def = _rtld_find_symdef(symnum, obj, - &defobj, false); - if (def == NULL) - return -1; - if (!defobj->tls_done && _rtld_tls_offset_allocate(obj)) return -1; @@ -310,12 +306,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry } if (RELOC_RESOLVE_SYMBOL(type)) { - - /* Find the symbol */ - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return (-1); - /* Add in the symbol's absolute address */ value += (Elf_Word)(defobj->relocbase + def->st_value); } Index: src/libexec/ld.elf_so/arch/sparc64/mdreloc.c diff -u src/libexec/ld.elf_so/arch/sparc64/mdreloc.c:1.60 src/libexec/ld.elf_so/arch/sparc64/mdreloc.c:1.61 --- src/libexec/ld.elf_so/arch/sparc64/mdreloc.c:1.60 Thu Jun 15 23:10:12 2017 +++ src/libexec/ld.elf_so/arch/sparc64/mdreloc.c Mon Jun 19 11:57:02 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: mdreloc.c,v 1.60 2017/06/15 23:10:12 joerg Exp $ */ +/* $NetBSD: mdreloc.c,v 1.61 2017/06/19 11:57:02 joerg Exp $ */ /*- * Copyright (c) 2000 Eduardo Horvath. @@ -32,7 +32,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: mdreloc.c,v 1.60 2017/06/15 23:10:12 joerg Exp $"); +__RCSID("$NetBSD: mdreloc.c,v 1.61 2017/06/19 11:57:02 joerg Exp $"); #endif /* not lint */ #include <errno.h> @@ -310,15 +310,15 @@ _rtld_relocate_nonplt_objects(Obj_Entry const Elf_Rela *rela; const Elf_Sym *def = NULL; const Obj_Entry *defobj = NULL; + unsigned long last_symnum = ULONG_MAX; for (rela = obj->rela; rela < obj->relalim; rela++) { Elf_Addr *where; Elf_Word type; Elf_Addr value = 0, mask; - unsigned long symnum; + unsigned long symnum; where = (Elf_Addr *) (obj->relocbase + rela->r_offset); - symnum = ELF_R_SYM(rela->r_info); type = ELF_R_TYPE(rela->r_info); if (type == R_TYPE(NONE)) @@ -347,17 +347,23 @@ _rtld_relocate_nonplt_objects(Obj_Entry value = rela->r_addend; + if (RELOC_RESOLVE_SYMBOL(type) || RELOC_TLS(type)) { + symnum = ELF_R_SYM(rela->r_info); + if (last_symnum != symnum) { + last_symnum = symnum; + def = _rtld_find_symdef(symnum, obj, &defobj, + false); + if (def == NULL) + return -1; + } + } + /* * Handle TLS relocations here, they are different. */ if (RELOC_TLS(type)) { switch (type) { case R_TYPE(TLS_DTPMOD64): - def = _rtld_find_symdef(symnum, obj, - &defobj, false); - if (def == NULL) - return -1; - *where = (Elf64_Addr)defobj->tlsindex; rdbg(("TLS_DTPMOD64 %s in %s --> %p", @@ -368,11 +374,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry break; case R_TYPE(TLS_DTPOFF64): - def = _rtld_find_symdef(symnum, obj, - &defobj, false); - if (def == NULL) - return -1; - *where = (Elf64_Addr)(def->st_value + rela->r_addend); @@ -384,11 +385,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry break; case R_TYPE(TLS_TPOFF64): - def = _rtld_find_symdef(symnum, obj, - &defobj, false); - if (def == NULL) - return -1; - if (!defobj->tls_done && _rtld_tls_offset_allocate(obj)) return -1; @@ -416,13 +412,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry } if (RELOC_RESOLVE_SYMBOL(type)) { - - /* Find the symbol */ - def = _rtld_find_symdef(symnum, obj, &defobj, - false); - if (def == NULL) - return -1; - /* Add in the symbol's absolute address */ value += (Elf_Addr)(defobj->relocbase + def->st_value); } Index: src/libexec/ld.elf_so/arch/vax/mdreloc.c diff -u src/libexec/ld.elf_so/arch/vax/mdreloc.c:1.31 src/libexec/ld.elf_so/arch/vax/mdreloc.c:1.32 --- src/libexec/ld.elf_so/arch/vax/mdreloc.c:1.31 Thu Apr 14 20:17:07 2016 +++ src/libexec/ld.elf_so/arch/vax/mdreloc.c Mon Jun 19 11:57:02 2017 @@ -1,8 +1,8 @@ -/* $NetBSD: mdreloc.c,v 1.31 2016/04/14 20:17:07 skrll Exp $ */ +/* $NetBSD: mdreloc.c,v 1.32 2017/06/19 11:57:02 joerg Exp $ */ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: mdreloc.c,v 1.31 2016/04/14 20:17:07 skrll Exp $"); +__RCSID("$NetBSD: mdreloc.c,v 1.32 2017/06/19 11:57:02 joerg Exp $"); #endif /* not lint */ #include <sys/types.h> @@ -51,16 +51,32 @@ int _rtld_relocate_nonplt_objects(Obj_Entry *obj) { const Elf_Rela *rela; + const Elf_Sym *def = NULL; + const Obj_Entry *defobj = NULL; + unsigned long last_symnum = ULONG_MAX; for (rela = obj->rela; rela < obj->relalim; rela++) { Elf_Addr *where; - const Elf_Sym *def; - const Obj_Entry *defobj; Elf_Addr tmp; - unsigned long symnum; where = (Elf_Addr *)(obj->relocbase + rela->r_offset); - symnum = ELF_R_SYM(rela->r_info); + + switch (ELF_R_TYPE(rela->r_info)) { + case R_TYPE(32): /* word32 S + A */ + case R_TYPE(GLOB_DAT): /* word32 S + A */ + symnum = ELF_R_SYM(rela->r_info); + if (last_symnum != symnum) { + last_symnum = symnum; + def = _rtld_find_symdef(symnum, obj, &defobj, + false); + if (def == NULL) + return -1; + } + break; + + default: + break; + } switch (ELF_R_TYPE(rela->r_info)) { case R_TYPE(NONE): @@ -68,10 +84,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry case R_TYPE(32): /* word32 S + A */ case R_TYPE(GLOB_DAT): /* word32 S + A */ - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; - tmp = (Elf_Addr)(defobj->relocbase + def->st_value + rela->r_addend); @@ -109,7 +121,8 @@ _rtld_relocate_nonplt_objects(Obj_Entry default: rdbg(("sym = %lu, type = %lu, offset = %p, " "addend = %p, contents = %p, symbol = %s", - symnum, (u_long)ELF_R_TYPE(rela->r_info), + (u_long)ELF_R_SYM(rela->r_info), + (u_long)ELF_R_TYPE(rela->r_info), (void *)rela->r_offset, (void *)rela->r_addend, (void *)*where, obj->strtab + obj->symtab[symnum].st_name)); Index: src/libexec/ld.elf_so/arch/x86_64/mdreloc.c diff -u src/libexec/ld.elf_so/arch/x86_64/mdreloc.c:1.41 src/libexec/ld.elf_so/arch/x86_64/mdreloc.c:1.42 --- src/libexec/ld.elf_so/arch/x86_64/mdreloc.c:1.41 Mon Aug 25 20:40:53 2014 +++ src/libexec/ld.elf_so/arch/x86_64/mdreloc.c Mon Jun 19 11:57:02 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: mdreloc.c,v 1.41 2014/08/25 20:40:53 joerg Exp $ */ +/* $NetBSD: mdreloc.c,v 1.42 2017/06/19 11:57:02 joerg Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -68,7 +68,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: mdreloc.c,v 1.41 2014/08/25 20:40:53 joerg Exp $"); +__RCSID("$NetBSD: mdreloc.c,v 1.42 2017/06/19 11:57:02 joerg Exp $"); #endif /* not lint */ #include <sys/types.h> @@ -131,18 +131,41 @@ _rtld_relocate_nonplt_objects(Obj_Entry { const Elf_Rela *rela; const Elf_Sym *def = NULL; - const Obj_Entry *defobj =NULL; + const Obj_Entry *defobj = NULL; + unsigned long last_symnum = ULONG_MAX; for (rela = obj->rela; rela < obj->relalim; rela++) { Elf64_Addr *where64; Elf32_Addr *where32; Elf64_Addr tmp64; Elf32_Addr tmp32; - unsigned long symnum; + unsigned long symnum; where64 = (Elf64_Addr *)(obj->relocbase + rela->r_offset); where32 = (Elf32_Addr *)where64; - symnum = ELF_R_SYM(rela->r_info); + + switch (ELF_R_TYPE(rela->r_info)) { + case R_TYPE(32): /* word32 S + A, truncate */ + case R_TYPE(32S): /* word32 S + A, signed truncate */ + case R_TYPE(GOT32): /* word32 G + A (XXX can we see these?) */ + case R_TYPE(64): /* word64 S + A */ + case R_TYPE(PC32): /* word32 S + A - P */ + case R_TYPE(GLOB_DAT): /* word64 S */ + case R_TYPE(TPOFF64): + case R_TYPE(DTPMOD64): + case R_TYPE(DTPOFF64): + symnum = ELF_R_SYM(rela->r_info); + if (last_symnum != symnum) { + last_symnum = symnum; + def = _rtld_find_symdef(symnum, obj, &defobj, + false); + if (def == NULL) + return -1; + } + break; + default: + break; + } switch (ELF_R_TYPE(rela->r_info)) { case R_TYPE(NONE): @@ -151,9 +174,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry case R_TYPE(32): /* word32 S + A, truncate */ case R_TYPE(32S): /* word32 S + A, signed truncate */ case R_TYPE(GOT32): /* word32 G + A (XXX can we see these?) */ - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; tmp32 = (Elf32_Addr)(u_long)(defobj->relocbase + def->st_value + rela->r_addend); @@ -165,9 +185,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry defobj->path)); break; case R_TYPE(64): /* word64 S + A */ - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; tmp64 = (Elf64_Addr)(defobj->relocbase + def->st_value + rela->r_addend); @@ -178,9 +195,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry obj->path, (void *)*where64, defobj->path)); break; case R_TYPE(PC32): /* word32 S + A - P */ - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; tmp32 = (Elf32_Addr)(u_long)(defobj->relocbase + def->st_value + rela->r_addend - (Elf64_Addr)where64); @@ -192,9 +206,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry defobj->path)); break; case R_TYPE(GLOB_DAT): /* word64 S */ - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; tmp64 = (Elf64_Addr)(defobj->relocbase + def->st_value); if (*where64 != tmp64) @@ -212,10 +223,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry break; case R_TYPE(TPOFF64): - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; - if (!defobj->tls_done && _rtld_tls_offset_allocate(obj)) return -1; @@ -230,10 +237,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry break; case R_TYPE(DTPMOD64): - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; - *where64 = (Elf64_Addr)defobj->tlsindex; rdbg(("DTPMOD64 %s in %s --> %p", @@ -243,10 +246,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry break; case R_TYPE(DTPOFF64): - def = _rtld_find_symdef(symnum, obj, &defobj, false); - if (def == NULL) - return -1; - *where64 = (Elf64_Addr)(def->st_value + rela->r_addend); rdbg(("DTPOFF64 %s in %s --> %p", @@ -262,7 +261,8 @@ _rtld_relocate_nonplt_objects(Obj_Entry default: rdbg(("sym = %lu, type = %lu, offset = %p, " "addend = %p, contents = %p, symbol = %s", - symnum, (u_long)ELF_R_TYPE(rela->r_info), + (u_long)ELF_R_SYM(rela->r_info), + (u_long)ELF_R_TYPE(rela->r_info), (void *)rela->r_offset, (void *)rela->r_addend, (void *)*where64, obj->strtab + obj->symtab[symnum].st_name));