diff options
author | Philip Guenther <guenther@cvs.openbsd.org> | 2019-08-04 23:51:46 +0000 |
---|---|---|
committer | Philip Guenther <guenther@cvs.openbsd.org> | 2019-08-04 23:51:46 +0000 |
commit | 70c8650d865f6421df65fc33c7991cff1ca26339 (patch) | |
tree | 4aaa212d84916f4311b26cd6a8d8d74f3f99dcc7 /libexec/ld.so | |
parent | 5d78eea126a1d3367fc351ff73244359b90e76f6 (diff) |
Simplify _dl_find_symbol(). Currently, it returns three values:
- the symbol it found, returned via the second argument
- the base offset of the the object it was found in, via the return value
- optionally: the object it was found in, returned via the last argument
Instead, return a struct with the symbol and object pointers and let the
caller get the base offset from the object's obj_base member. On at least
aarch64, amd64, mips64, powerpc, and sparc64, a two word struct like this
is passed in registers.
ok mpi@, kettenis@
Diffstat (limited to 'libexec/ld.so')
-rw-r--r-- | libexec/ld.so/aarch64/rtld_machine.c | 48 | ||||
-rw-r--r-- | libexec/ld.so/alpha/rtld_machine.c | 51 | ||||
-rw-r--r-- | libexec/ld.so/amd64/rtld_machine.c | 48 | ||||
-rw-r--r-- | libexec/ld.so/arm/rtld_machine.c | 48 | ||||
-rw-r--r-- | libexec/ld.so/dlfcn.c | 32 | ||||
-rw-r--r-- | libexec/ld.so/hppa/rtld_machine.c | 85 | ||||
-rw-r--r-- | libexec/ld.so/i386/rtld_machine.c | 51 | ||||
-rw-r--r-- | libexec/ld.so/loader.c | 46 | ||||
-rw-r--r-- | libexec/ld.so/m88k/rtld_machine.c | 56 | ||||
-rw-r--r-- | libexec/ld.so/mips64/rtld_machine.c | 110 | ||||
-rw-r--r-- | libexec/ld.so/powerpc/rtld_machine.c | 98 | ||||
-rw-r--r-- | libexec/ld.so/resolve.c | 84 | ||||
-rw-r--r-- | libexec/ld.so/resolve.h | 16 | ||||
-rw-r--r-- | libexec/ld.so/sh/rtld_machine.c | 55 | ||||
-rw-r--r-- | libexec/ld.so/sparc64/rtld_machine.c | 68 |
15 files changed, 402 insertions, 494 deletions
diff --git a/libexec/ld.so/aarch64/rtld_machine.c b/libexec/ld.so/aarch64/rtld_machine.c index 7630b58d85f..26cd7423591 100644 --- a/libexec/ld.so/aarch64/rtld_machine.c +++ b/libexec/ld.so/aarch64/rtld_machine.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtld_machine.c,v 1.7 2018/11/16 21:15:47 guenther Exp $ */ +/* $OpenBSD: rtld_machine.c,v 1.8 2019/08/04 23:51:45 guenther Exp $ */ /* * Copyright (c) 2004 Dale Rahn @@ -148,9 +148,9 @@ _dl_md_reloc(elf_object_t *object, int rel, int relsz) *where += loff; } for (; i < numrel; i++, rels++) { - Elf_Addr *where, value, ooff, mask; + Elf_Addr *where, value, mask; Elf_Word type; - const Elf_Sym *sym, *this; + const Elf_Sym *sym; const char *symn; type = ELF_R_TYPE(rels->r_info); @@ -185,14 +185,13 @@ _dl_md_reloc(elf_object_t *object, int rel, int relsz) } else if (sym == prev_sym) { value += prev_value; } else { - this = NULL; - ooff = _dl_find_symbol_bysym(object, - ELF_R_SYM(rels->r_info), &this, + struct sym_res sr; + + sr = _dl_find_symbol(symn, SYM_SEARCH_ALL|SYM_WARNNOTFOUND| ((type == R_TYPE(JUMP_SLOT)) ? - SYM_PLT : SYM_NOTPLT), - sym, NULL); - if (this == NULL) { + SYM_PLT : SYM_NOTPLT), sym, object); + if (sr.sym == NULL) { resolve_failed: if (ELF_ST_BIND(sym->st_info) != STB_WEAK) @@ -200,7 +199,8 @@ resolve_failed: continue; } prev_sym = sym; - prev_value = (Elf_Addr)(ooff + this->st_value); + prev_value = (Elf_Addr)(sr.obj->obj_base + + sr.sym->st_value); value += prev_value; } } @@ -216,16 +216,16 @@ resolve_failed: if (type == R_TYPE(COPY)) { void *dstaddr = where; const void *srcaddr; - const Elf_Sym *dstsym = sym, *srcsym = NULL; - Elf_Addr soff; + const Elf_Sym *dstsym = sym; + struct sym_res sr; - soff = _dl_find_symbol(symn, &srcsym, + sr = _dl_find_symbol(symn, SYM_SEARCH_OTHER|SYM_WARNNOTFOUND|SYM_NOTPLT, - dstsym, object, NULL); - if (srcsym == NULL) + dstsym, object); + if (sr.sym == NULL) goto resolve_failed; - srcaddr = (void *)(soff + srcsym->st_value); + srcaddr = (void *)(sr.obj->obj_base + sr.sym->st_value); _dl_bcopy(srcaddr, dstaddr, dstsym->st_size); continue; } @@ -317,10 +317,9 @@ Elf_Addr _dl_bind(elf_object_t *object, int relidx) { Elf_RelA *rel; - const Elf_Sym *sym, *this; + const Elf_Sym *sym; const char *symn; - const elf_object_t *sobj; - Elf_Addr ooff; + struct sym_res sr; int64_t cookie = pcookie; struct { struct __kbind param; @@ -333,15 +332,14 @@ _dl_bind(elf_object_t *object, int relidx) sym += ELF_R_SYM(rel->r_info); symn = object->dyn.strtab + sym->st_name; - this = NULL; - ooff = _dl_find_symbol(symn, &this, - SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, sym, object, &sobj); - if (this == NULL) + sr = _dl_find_symbol(symn, SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, + sym, object); + if (sr.sym == NULL) _dl_die("lazy binding failed!"); - buf.newval = ooff + this->st_value; + buf.newval = sr.obj->obj_base + sr.sym->st_value; - if (sobj->traced && _dl_trace_plt(sobj, symn)) + if (sr.obj->traced && _dl_trace_plt(sr.obj, symn)) return buf.newval; buf.param.kb_addr = (Elf_Word *)(object->obj_base + rel->r_offset); diff --git a/libexec/ld.so/alpha/rtld_machine.c b/libexec/ld.so/alpha/rtld_machine.c index 6c9a81539ea..bc7926dbcb7 100644 --- a/libexec/ld.so/alpha/rtld_machine.c +++ b/libexec/ld.so/alpha/rtld_machine.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtld_machine.c,v 1.65 2018/11/22 21:37:30 guenther Exp $ */ +/* $OpenBSD: rtld_machine.c,v 1.66 2019/08/04 23:51:45 guenther Exp $ */ /* * Copyright (c) 1999 Dale Rahn @@ -111,8 +111,8 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz) } for (; i < numrela; i++, relas++) { Elf64_Addr *r_addr; - Elf64_Addr ooff; - const Elf64_Sym *sym, *this; + struct sym_res sr; + const Elf64_Sym *sym; const char *symn; r_addr = (Elf64_Addr *)(relas->r_offset + loff); @@ -125,16 +125,15 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz) sym += ELF64_R_SYM(relas->r_info); symn = object->dyn.strtab + sym->st_name; - this = NULL; switch (ELF64_R_TYPE(relas->r_info)) { case R_TYPE(REFQUAD): - ooff = _dl_find_symbol_bysym(object, - ELF64_R_SYM(relas->r_info), &this, + sr = _dl_find_symbol(symn, SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_NOTPLT, - sym, NULL); - if (this == NULL) + sym, object); + if (sr.sym == NULL) goto resolve_failed; - *r_addr += ooff + this->st_value + relas->r_addend; + *r_addr += sr.obj->obj_base + sr.sym->st_value + + relas->r_addend; break; case R_TYPE(RELATIVE): /* @@ -154,26 +153,26 @@ _dl_printf("unaligned RELATIVE: %p type: %d %s 0x%lx -> 0x%lx\n", r_addr, *r_addr += loff; break; case R_TYPE(JMP_SLOT): - ooff = _dl_find_symbol(symn, &this, + sr = _dl_find_symbol(symn, SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, - sym, object, NULL); - if (this == NULL) + sym, object); + if (sr.sym == NULL) goto resolve_failed; - *r_addr = ooff + this->st_value + relas->r_addend; + *r_addr = sr.obj->obj_base + sr.sym->st_value + + relas->r_addend; break; case R_TYPE(GLOB_DAT): if (sym == prev_sym) { *r_addr = prev_value + relas->r_addend; break; } - ooff = _dl_find_symbol_bysym(object, - ELF64_R_SYM(relas->r_info), &this, + sr = _dl_find_symbol(symn, SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_NOTPLT, - sym, NULL); - if (this == NULL) + sym, object); + if (sr.sym == NULL) goto resolve_failed; prev_sym = sym; - prev_value = ooff + this->st_value; + prev_value = sr.obj->obj_base + sr.sym->st_value; *r_addr = prev_value + relas->r_addend; break; case R_TYPE(NONE): @@ -208,10 +207,9 @@ Elf_Addr _dl_bind(elf_object_t *object, int reloff) { Elf_RelA *rela; - Elf_Addr ooff; - const Elf_Sym *sym, *this; + struct sym_res sr; + const Elf_Sym *sym; const char *symn; - const elf_object_t *sobj; uint64_t cookie = pcookie; struct { struct __kbind param; @@ -224,15 +222,14 @@ _dl_bind(elf_object_t *object, int reloff) sym += ELF64_R_SYM(rela->r_info); symn = object->dyn.strtab + sym->st_name; - this = NULL; - ooff = _dl_find_symbol(symn, &this, - SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, sym, object, &sobj); - if (this == NULL) + sr = _dl_find_symbol(symn, SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, + sym, object); + if (sr.sym == NULL) _dl_die("lazy binding failed!"); - buf.newval = ooff + this->st_value + rela->r_addend; + buf.newval = sr.obj->obj_base + sr.sym->st_value + rela->r_addend; - if (__predict_false(sobj->traced) && _dl_trace_plt(sobj, symn)) + if (__predict_false(sr.obj->traced) && _dl_trace_plt(sr.obj, symn)) return (buf.newval); buf.param.kb_addr = (Elf_Addr *)(object->obj_base + rela->r_offset); diff --git a/libexec/ld.so/amd64/rtld_machine.c b/libexec/ld.so/amd64/rtld_machine.c index 0a5e02ae374..012b2cf2eb1 100644 --- a/libexec/ld.so/amd64/rtld_machine.c +++ b/libexec/ld.so/amd64/rtld_machine.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtld_machine.c,v 1.31 2019/08/03 19:56:40 guenther Exp $ */ +/* $OpenBSD: rtld_machine.c,v 1.32 2019/08/04 23:51:45 guenther Exp $ */ /* * Copyright (c) 2002,2004 Dale Rahn @@ -214,9 +214,9 @@ _dl_md_reloc(elf_object_t *object, int rel, int relsz) *where = rels->r_addend + loff; } for (; i < numrel; i++, rels++) { - Elf_Addr *where, value, ooff, mask; + Elf_Addr *where, value, mask; Elf_Word type; - const Elf_Sym *sym, *this; + const Elf_Sym *sym; const char *symn; type = ELF_R_TYPE(rels->r_info); @@ -250,14 +250,13 @@ _dl_md_reloc(elf_object_t *object, int rel, int relsz) } else if (sym == prev_sym) { value += prev_value; } else { - this = NULL; - ooff = _dl_find_symbol_bysym(object, - ELF_R_SYM(rels->r_info), &this, + struct sym_res sr; + + sr = _dl_find_symbol(symn, SYM_SEARCH_ALL|SYM_WARNNOTFOUND| ((type == R_TYPE(JUMP_SLOT))? - SYM_PLT:SYM_NOTPLT), - sym, NULL); - if (this == NULL) { + SYM_PLT:SYM_NOTPLT), sym, object); + if (sr.sym == NULL) { resolve_failed: if (ELF_ST_BIND(sym->st_info) != STB_WEAK) @@ -265,7 +264,8 @@ resolve_failed: continue; } prev_sym = sym; - prev_value = (Elf_Addr)(ooff + this->st_value); + prev_value = (Elf_Addr)(sr.obj->obj_base + + sr.sym->st_value); value += prev_value; } } @@ -278,16 +278,16 @@ resolve_failed: if (type == R_TYPE(COPY)) { void *dstaddr = where; const void *srcaddr; - const Elf_Sym *dstsym = sym, *srcsym = NULL; - Elf_Addr soff; + const Elf_Sym *dstsym = sym; + struct sym_res sr; - soff = _dl_find_symbol(symn, &srcsym, + sr = _dl_find_symbol(symn, SYM_SEARCH_OTHER|SYM_WARNNOTFOUND|SYM_NOTPLT, - dstsym, object, NULL); - if (srcsym == NULL) + dstsym, object); + if (sr.sym == NULL) goto resolve_failed; - srcaddr = (void *)(soff + srcsym->st_value); + srcaddr = (void *)(sr.obj->obj_base + sr.sym->st_value); _dl_bcopy(srcaddr, dstaddr, dstsym->st_size); continue; } @@ -337,10 +337,9 @@ Elf_Addr _dl_bind(elf_object_t *object, int index) { Elf_RelA *rel; - const Elf_Sym *sym, *this; + const Elf_Sym *sym; const char *symn; - const elf_object_t *sobj; - Elf_Addr ooff; + struct sym_res sr; int64_t cookie = pcookie; struct { struct __kbind param; @@ -353,15 +352,14 @@ _dl_bind(elf_object_t *object, int index) sym += ELF_R_SYM(rel->r_info); symn = object->dyn.strtab + sym->st_name; - this = NULL; - ooff = _dl_find_symbol(symn, &this, - SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, sym, object, &sobj); - if (this == NULL) + sr = _dl_find_symbol(symn, SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, + sym, object); + if (sr.sym == NULL) _dl_die("lazy binding failed!"); - buf.newval = ooff + this->st_value; + buf.newval = sr.obj->obj_base + sr.sym->st_value; - if (__predict_false(sobj->traced) && _dl_trace_plt(sobj, symn)) + if (__predict_false(sr.obj->traced) && _dl_trace_plt(sr.obj, symn)) return (buf.newval); buf.param.kb_addr = (Elf_Word *)(object->obj_base + rel->r_offset); diff --git a/libexec/ld.so/arm/rtld_machine.c b/libexec/ld.so/arm/rtld_machine.c index 797f09c8e7a..aca7be9552d 100644 --- a/libexec/ld.so/arm/rtld_machine.c +++ b/libexec/ld.so/arm/rtld_machine.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtld_machine.c,v 1.28 2018/11/16 21:15:47 guenther Exp $ */ +/* $OpenBSD: rtld_machine.c,v 1.29 2019/08/04 23:51:45 guenther Exp $ */ /* * Copyright (c) 2004 Dale Rahn @@ -209,9 +209,9 @@ _dl_md_reloc(elf_object_t *object, int rel, int relsz) *where += loff; } for (; i < numrel; i++, rels++) { - Elf_Addr *where, value, ooff, mask; + Elf_Addr *where, value, mask; Elf_Word type; - const Elf_Sym *sym, *this; + const Elf_Sym *sym; const char *symn; type = ELF_R_TYPE(rels->r_info); @@ -248,14 +248,13 @@ _dl_md_reloc(elf_object_t *object, int rel, int relsz) } else if (sym == prev_sym) { value += prev_value; } else { - this = NULL; - ooff = _dl_find_symbol_bysym(object, - ELF_R_SYM(rels->r_info), &this, + struct sym_res sr; + + sr = _dl_find_symbol(symn, SYM_SEARCH_ALL|SYM_WARNNOTFOUND| ((type == R_TYPE(JUMP_SLOT)) ? - SYM_PLT : SYM_NOTPLT), - sym, NULL); - if (this == NULL) { + SYM_PLT : SYM_NOTPLT), sym, object); + if (sr.sym == NULL) { resolve_failed: if (ELF_ST_BIND(sym->st_info) != STB_WEAK) @@ -263,7 +262,8 @@ resolve_failed: continue; } prev_sym = sym; - prev_value = (Elf_Addr)(ooff + this->st_value); + prev_value = (Elf_Addr)(sr.obj->obj_base + + sr.sym->st_value); value += prev_value; } } @@ -279,16 +279,16 @@ resolve_failed: if (type == R_TYPE(COPY)) { void *dstaddr = where; const void *srcaddr; - const Elf_Sym *dstsym = sym, *srcsym = NULL; - Elf_Addr soff; + const Elf_Sym *dstsym = sym; + struct sym_res sr; - soff = _dl_find_symbol(symn, &srcsym, + sr = _dl_find_symbol(symn, SYM_SEARCH_OTHER|SYM_WARNNOTFOUND|SYM_NOTPLT, - dstsym, object, NULL); - if (srcsym == NULL) + dstsym, object); + if (sr.sym == NULL) goto resolve_failed; - srcaddr = (void *)(soff + srcsym->st_value); + srcaddr = (void *)(sr.obj->obj_base + sr.sym->st_value); _dl_bcopy(srcaddr, dstaddr, dstsym->st_size); continue; } @@ -380,10 +380,9 @@ Elf_Addr _dl_bind(elf_object_t *object, int relidx) { Elf_Rel *rel; - const Elf_Sym *sym, *this; + const Elf_Sym *sym; const char *symn; - const elf_object_t *sobj; - Elf_Addr ooff; + struct sym_res sr; int64_t cookie = pcookie; struct { struct __kbind param; @@ -396,15 +395,14 @@ _dl_bind(elf_object_t *object, int relidx) sym += ELF_R_SYM(rel->r_info); symn = object->dyn.strtab + sym->st_name; - this = NULL; - ooff = _dl_find_symbol(symn, &this, - SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, sym, object, &sobj); - if (this == NULL) + sr = _dl_find_symbol(symn, SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, + sym, object); + if (sr.sym == NULL) _dl_die("lazy binding failed!"); - buf.newval = ooff + this->st_value; + buf.newval = sr.obj->obj_base + sr.sym->st_value; - if (__predict_false(sobj->traced) && _dl_trace_plt(sobj, symn)) + if (__predict_false(sr.obj->traced) && _dl_trace_plt(sr.obj, symn)) return (buf.newval); buf.param.kb_addr = (Elf_Addr *)(object->obj_base + rel->r_offset); diff --git a/libexec/ld.so/dlfcn.c b/libexec/ld.so/dlfcn.c index 39fdf27457d..b74a4e9d81c 100644 --- a/libexec/ld.so/dlfcn.c +++ b/libexec/ld.so/dlfcn.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dlfcn.c,v 1.103 2019/07/21 03:54:16 guenther Exp $ */ +/* $OpenBSD: dlfcn.c,v 1.104 2019/08/04 23:51:45 guenther Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -148,10 +148,9 @@ dlsym(void *handle, const char *name) { elf_object_t *object; elf_object_t *dynobj; - const elf_object_t *pobj; - char *retval; - const Elf_Sym *sym = NULL; - int flags; + struct sym_res sr; + int flags; + Elf_Addr addr; if (handle == NULL || handle == RTLD_NEXT || handle == RTLD_SELF || handle == RTLD_DEFAULT) { @@ -187,21 +186,20 @@ dlsym(void *handle, const char *name) } } - retval = (void *)_dl_find_symbol(name, &sym, - flags|SYM_NOWARNNOTFOUND, NULL, object, &pobj); + sr = _dl_find_symbol(name, flags|SYM_NOWARNNOTFOUND, NULL, object); + if (sr.sym == NULL) { + _dl_errno = DL_NO_SYMBOL; + return NULL; + } - if (sym != NULL) { - retval += sym->st_value; + addr = sr.obj->obj_base + sr.sym->st_value; #ifdef __hppa__ - if (ELF_ST_TYPE(sym->st_info) == STT_FUNC) - retval = (void *)_dl_md_plabel((Elf_Addr)retval, - pobj->dyn.pltgot); + if (ELF_ST_TYPE(sr.sym->st_info) == STT_FUNC) + addr = _dl_md_plabel(addr, sr.obj->dyn.pltgot); #endif - DL_DEB(("dlsym: %s in %s: %p\n", - name, object->load_name, retval)); - } else - _dl_errno = DL_NO_SYMBOL; - return (retval); + DL_DEB(("dlsym: %s in %s: %p\n", + name, object->load_name, (void *)addr)); + return (void *)addr; } int diff --git a/libexec/ld.so/hppa/rtld_machine.c b/libexec/ld.so/hppa/rtld_machine.c index 0c11b75c269..d51e9dcc8a3 100644 --- a/libexec/ld.so/hppa/rtld_machine.c +++ b/libexec/ld.so/hppa/rtld_machine.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtld_machine.c,v 1.37 2018/11/16 21:15:47 guenther Exp $ */ +/* $OpenBSD: rtld_machine.c,v 1.38 2019/08/04 23:51:45 guenther Exp $ */ /* * Copyright (c) 2004 Michael Shalayeff @@ -106,7 +106,6 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz) Elf_RelA *rela; Elf_Addr loff; int i, numrela, fails = 0; - size_t size; struct load_list *llist; loff = object->obj_base; @@ -167,9 +166,9 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz) _hppa_dl_set_dp(object->dyn.pltgot); for (i = 0; i < numrela; i++, rela++) { - const elf_object_t *sobj; - const Elf_Sym *sym, *this; - Elf_Addr *pt, ooff; + struct sym_res sr; + const Elf_Sym *sym; + Elf_Addr *pt; const char *symn; int type; @@ -178,23 +177,21 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz) continue; sym = object->dyn.symtab + ELF_R_SYM(rela->r_info); - sobj = object; symn = object->dyn.strtab + sym->st_name; pt = (Elf_Addr *)(rela->r_offset + loff); - ooff = 0; - this = NULL; if (ELF_R_SYM(rela->r_info) && sym->st_name) { - ooff = _dl_find_symbol_bysym(object, - ELF_R_SYM(rela->r_info), &this, - SYM_SEARCH_ALL|SYM_WARNNOTFOUND| - ((type == RELOC_IPLT) ? SYM_PLT: SYM_NOTPLT), - sym, &sobj); - if (this == NULL) { + sr = _dl_find_symbol(symn, + SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_NOTPLT, + sym, object); + if (sr.sym == NULL) { if (ELF_ST_BIND(sym->st_info) != STB_WEAK) fails++; continue; } + } else { + sr.sym = NULL; + sr.obj = object; } #ifdef DEBUG @@ -205,16 +202,17 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz) switch (type) { case RELOC_DIR32: if (ELF_R_SYM(rela->r_info) && sym->st_name) { - *pt = ooff + this->st_value + rela->r_addend; + *pt = sr.obj->obj_base + sr.sym->st_value + + rela->r_addend; #ifdef DEBUG DL_DEB(("[%x]DIR32: %s:%s -> 0x%x in %s\n", i, symn, object->load_name, - *pt, sobj->load_name)); + *pt, sr.obj->load_name)); #endif } else { /* * XXX should objects ever get their - * sections loaded insequential this + * sections loaded nonsequential this * would have to get a section number * (ELF_R_SYM(rela->r_info))-1 and then: * *pt = sect->addr + rela->r_addend; @@ -232,17 +230,17 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz) case RELOC_PLABEL32: if (ELF_R_SYM(rela->r_info)) { - if (ELF_ST_TYPE(this->st_info) != STT_FUNC) { + if (ELF_ST_TYPE(sr.sym->st_info) != STT_FUNC) { DL_DEB(("[%x]PLABEL32: bad\n", i)); break; } - *pt = _dl_md_plabel(sobj->obj_base + - this->st_value + rela->r_addend, - sobj->dyn.pltgot); + *pt = _dl_md_plabel(sr.obj->obj_base + + sr.sym->st_value + rela->r_addend, + sr.obj->dyn.pltgot); #ifdef DEBUG DL_DEB(("[%x]PLABEL32: %s:%s -> 0x%x in %s\n", i, symn, object->load_name, - *pt, sobj->load_name)); + *pt, sr.obj->load_name)); #endif } else { *pt = loff + rela->r_addend; @@ -255,12 +253,13 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz) case RELOC_IPLT: if (ELF_R_SYM(rela->r_info)) { - pt[0] = ooff + this->st_value + rela->r_addend; - pt[1] = (Elf_Addr)sobj->dyn.pltgot; + pt[0] = sr.obj->obj_base + sr.sym->st_value + + rela->r_addend; + pt[1] = (Elf_Addr)sr.obj->dyn.pltgot; #ifdef DEBUG DL_DEB(("[%x]IPLT: %s:%s -> 0x%x:0x%x in %s\n", i, symn, object->load_name, - pt[0], pt[1], sobj->load_name)); + pt[0], pt[1], sr.obj->load_name)); #endif } else { pt[0] = loff + rela->r_addend; @@ -274,19 +273,17 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz) case RELOC_COPY: { - const Elf32_Sym *cpysrc = NULL; - size = sym->st_size; - ooff = _dl_find_symbol(symn, &cpysrc, + sr = _dl_find_symbol(symn, SYM_SEARCH_OTHER|SYM_WARNNOTFOUND|SYM_NOTPLT, - sym, object, NULL); - if (cpysrc) { - _dl_bcopy((void *)(ooff + cpysrc->st_value), - pt, sym->st_size); + sym, object); + if (sr.sym) { + _dl_bcopy((void *)(sr.obj->obj_base + + sr.sym->st_value), pt, sym->st_size); #ifdef DEBUG DL_DEB(("[%x]COPY: %s[%x]:%s -> %p[%x] in %s\n", - i, symn, ooff + cpysrc->st_value, - object->load_name, pt, sym->st_size, - sobj->load_name)); + i, symn, sr.obj->obj_base + + sr.sym->st_value, object->load_name, + pt, sym->st_size, sr.obj->load_name)); #endif } else DL_DEB(("[%x]COPY: no sym\n", i)); @@ -437,9 +434,8 @@ _dl_md_reloc_got(elf_object_t *object, int lazy) uint64_t _dl_bind(elf_object_t *object, int reloff) { - const elf_object_t *sobj; - const Elf_Sym *sym, *this; - Elf_Addr ooff; + struct sym_res sr; + const Elf_Sym *sym; const char *symn; Elf_Addr value; Elf_RelA *rela; @@ -455,17 +451,16 @@ _dl_bind(elf_object_t *object, int reloff) sym += ELF_R_SYM(rela->r_info); symn = object->dyn.strtab + sym->st_name; - this = NULL; - ooff = _dl_find_symbol(symn, &this, - SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, sym, object, &sobj); - if (this == NULL) + sr = _dl_find_symbol(symn, SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, + sym, object); + if (sr.sym == NULL) _dl_die("lazy binding failed!"); - value = ooff + this->st_value + rela->r_addend; + value = sr.obj->obj_base + sr.sym->st_value + rela->r_addend; - buf.newval = ((uint64_t)value << 32) | (Elf_Addr)sobj->dyn.pltgot; + buf.newval = ((uint64_t)value << 32) | (Elf_Addr)sr.obj->dyn.pltgot; - if (__predict_false(sobj->traced) && _dl_trace_plt(sobj, symn)) + if (__predict_false(sr.obj->traced) && _dl_trace_plt(sr.obj, symn)) return (buf.newval); buf.param.kb_addr = (Elf_Addr *)(object->obj_base + rela->r_offset); diff --git a/libexec/ld.so/i386/rtld_machine.c b/libexec/ld.so/i386/rtld_machine.c index 5c35ac02523..01c7873beae 100644 --- a/libexec/ld.so/i386/rtld_machine.c +++ b/libexec/ld.so/i386/rtld_machine.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtld_machine.c,v 1.39 2018/11/16 21:15:47 guenther Exp $ */ +/* $OpenBSD: rtld_machine.c,v 1.40 2019/08/04 23:51:45 guenther Exp $ */ /* * Copyright (c) 2002 Dale Rahn @@ -214,9 +214,9 @@ _dl_md_reloc(elf_object_t *object, int rel, int relsz) *where += loff; } for (; i < numrel; i++, rels++) { - Elf_Addr *where, value, ooff, mask; + Elf_Addr *where, value, mask; Elf_Word type; - const Elf_Sym *sym, *this; + const Elf_Sym *sym; const char *symn; type = ELF_R_TYPE(rels->r_info); @@ -247,14 +247,13 @@ _dl_md_reloc(elf_object_t *object, int rel, int relsz) } else if (sym == prev_sym) { value += prev_value; } else { - this = NULL; - ooff = _dl_find_symbol_bysym(object, - ELF_R_SYM(rels->r_info), &this, + struct sym_res sr; + + sr = _dl_find_symbol(symn, SYM_SEARCH_ALL|SYM_WARNNOTFOUND| ((type == R_TYPE(JUMP_SLOT))? - SYM_PLT:SYM_NOTPLT), - sym, NULL); - if (this == NULL) { + SYM_PLT:SYM_NOTPLT), sym, object); + if (sr.sym == NULL) { resolve_failed: if (ELF_ST_BIND(sym->st_info) != STB_WEAK) @@ -262,7 +261,8 @@ resolve_failed: continue; } prev_sym = sym; - prev_value = (Elf_Addr)(ooff + this->st_value); + prev_value = (Elf_Addr)(sr.obj->obj_base + + sr.sym->st_value); value += prev_value; } } @@ -275,18 +275,17 @@ resolve_failed: if (type == R_TYPE(COPY)) { void *dstaddr = where; const void *srcaddr; - const Elf_Sym *dstsym = sym, *srcsym = NULL; - size_t size = dstsym->st_size; - Elf_Addr soff; + const Elf_Sym *dstsym = sym; + struct sym_res sr; - soff = _dl_find_symbol(symn, &srcsym, + sr = _dl_find_symbol(symn, SYM_SEARCH_OTHER|SYM_WARNNOTFOUND|SYM_NOTPLT, - sym, object, NULL); - if (srcsym == NULL) + dstsym, object); + if (sr.sym == NULL) goto resolve_failed; - srcaddr = (void *)(soff + srcsym->st_value); - _dl_bcopy(srcaddr, dstaddr, size); + srcaddr = (void *)(sr.obj->obj_base + sr.sym->st_value); + _dl_bcopy(srcaddr, dstaddr, dstsym->st_size); continue; } @@ -361,10 +360,9 @@ Elf_Addr _dl_bind(elf_object_t *object, int index) { Elf_Rel *rel; - const Elf_Sym *sym, *this; + const Elf_Sym *sym; const char *symn; - const elf_object_t *sobj; - Elf_Addr ooff; + struct sym_res sr; uint64_t cookie = pcookie; struct { struct __kbind param; @@ -379,15 +377,14 @@ _dl_bind(elf_object_t *object, int index) sym += ELF_R_SYM(rel->r_info); symn = object->dyn.strtab + sym->st_name; - this = NULL; - ooff = _dl_find_symbol(symn, &this, - SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, sym, object, &sobj); - if (this == NULL) + sr = _dl_find_symbol(symn, SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, + sym, object); + if (sr.sym == NULL) _dl_die("lazy binding failed!"); - buf.newval = ooff + this->st_value; + buf.newval = sr.obj->obj_base + sr.sym->st_value; - if (__predict_false(sobj->traced) && _dl_trace_plt(sobj, symn)) + if (__predict_false(sr.obj->traced) && _dl_trace_plt(sr.obj, symn)) return (buf.newval); buf.param.kb_addr = (Elf_Word *)(object->obj_base + rel->r_offset); diff --git a/libexec/ld.so/loader.c b/libexec/ld.so/loader.c index e7b4e031b54..918c299aa61 100644 --- a/libexec/ld.so/loader.c +++ b/libexec/ld.so/loader.c @@ -1,4 +1,4 @@ -/* $OpenBSD: loader.c,v 1.183 2019/07/21 03:54:16 guenther Exp $ */ +/* $OpenBSD: loader.c,v 1.184 2019/08/04 23:51:45 guenther Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -847,6 +847,23 @@ _dl_unsetenv(const char *var, char **env) } } +static inline void +fixup_sym(struct elf_object *dummy_obj, const char *name, void *addr) +{ + struct sym_res sr; + + sr = _dl_find_symbol(name, SYM_SEARCH_ALL|SYM_NOWARNNOTFOUND|SYM_PLT, + NULL, dummy_obj); + if (sr.sym != NULL) { + void *p = (void *)(sr.sym->st_value + sr.obj->obj_base); + if (p != addr) { + DL_DEB(("setting %s %p@%s[%p] from %p\n", name, + p, sr.obj->load_name, (void *)sr.obj, addr)); + *(void **)p = *(void **)addr; + } + } +} + /* * _dl_fixup_user_env() * @@ -856,35 +873,12 @@ _dl_unsetenv(const char *var, char **env) void _dl_fixup_user_env(void) { - const struct elf_object *obj; - const Elf_Sym *sym; - Elf_Addr ooff; struct elf_object dummy_obj; dummy_obj.dyn.symbolic = 0; dummy_obj.load_name = "ld.so"; - - sym = NULL; - ooff = _dl_find_symbol("environ", &sym, - SYM_SEARCH_ALL|SYM_NOWARNNOTFOUND|SYM_PLT, NULL, &dummy_obj, &obj); - if (sym != NULL) { - DL_DEB(("setting environ %p@%s[%p] from %p\n", - (void *)(sym->st_value + ooff), obj->load_name, - (void *)obj, (void *)&environ)); - if ((char ***)(sym->st_value + ooff) != &environ) - *((char ***)(sym->st_value + ooff)) = environ; - } - - sym = NULL; - ooff = _dl_find_symbol("__progname", &sym, - SYM_SEARCH_ALL|SYM_NOWARNNOTFOUND|SYM_PLT, NULL, &dummy_obj, &obj); - if (sym != NULL) { - DL_DEB(("setting __progname %p@%s[%p] from %p\n", - (void *)(sym->st_value + ooff), obj->load_name, - (void *)obj, (void *)&__progname)); - if ((char **)(sym->st_value + ooff) != &__progname) - *((char **)(sym->st_value + ooff)) = __progname; - } + fixup_sym(&dummy_obj, "environ", &environ); + fixup_sym(&dummy_obj, "__progname", &__progname); } const void * diff --git a/libexec/ld.so/m88k/rtld_machine.c b/libexec/ld.so/m88k/rtld_machine.c index c818426f23b..054aacc70d8 100644 --- a/libexec/ld.so/m88k/rtld_machine.c +++ b/libexec/ld.so/m88k/rtld_machine.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtld_machine.c,v 1.23 2018/11/16 21:15:47 guenther Exp $ */ +/* $OpenBSD: rtld_machine.c,v 1.24 2019/08/04 23:51:45 guenther Exp $ */ /* * Copyright (c) 2013 Miodrag Vallat. @@ -114,8 +114,8 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz) } for (; i < numrela; i++, relas++) { Elf32_Addr *r_addr = (Elf32_Addr *)(relas->r_offset + loff); - Elf32_Addr ooff, addend, newval; - const Elf32_Sym *sym, *this; + Elf32_Addr addend, newval; + const Elf32_Sym *sym; const char *symn; int type; @@ -138,24 +138,14 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz) * searching all objects but _not_ the current object, * first one found wins. */ - const Elf32_Sym *cpysrc = NULL; - Elf32_Addr src_loff; - int size; + struct sym_res sr; - src_loff = 0; - src_loff = _dl_find_symbol(symn, &cpysrc, + sr = _dl_find_symbol(symn, SYM_SEARCH_OTHER | SYM_WARNNOTFOUND | SYM_NOTPLT, sym, object, NULL); - if (cpysrc != NULL) { - size = sym->st_size; - if (sym->st_size != cpysrc->st_size) { - /* _dl_find_symbol() has warned - about this already */ - size = sym->st_size < cpysrc->st_size ? - sym->st_size : cpysrc->st_size; - } - _dl_bcopy((void *)(src_loff + cpysrc->st_value), - r_addr, size); + if (sr.sym != NULL) { + _dl_bcopy((void *)(sr.obj->obj_base + + sr.sym->st_value), r_addr, sym->st_size); } else fails++; @@ -172,22 +162,22 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz) prev_value = 0; prev_ooff = object->obj_base; } else { - this = NULL; - ooff = _dl_find_symbol_bysym(object, - ELF32_R_SYM(relas->r_info), &this, + struct sym_res sr; + + sr = _dl_find_symbol(symn, SYM_SEARCH_ALL | SYM_WARNNOTFOUND | ((type == RELOC_GOTP_ENT) ? - SYM_PLT : SYM_NOTPLT), sym, NULL); + SYM_PLT : SYM_NOTPLT), sym, object, NULL); - if (this == NULL) { + if (sr.sym == NULL) { if (ELF_ST_BIND(sym->st_info) != STB_WEAK) fails++; continue; } prev_sym = sym; - prev_value = this->st_value; - prev_ooff = ooff; + prev_value = sr.sym->st_value; + prev_ooff = sr.obj->obj_base; } } @@ -337,10 +327,9 @@ Elf_Addr _dl_bind(elf_object_t *object, int reloff) { Elf_RelA *rel; - Elf_Addr ooff; - const Elf_Sym *sym, *this; + struct sym_res sr; + const Elf_Sym *sym; const char *symn; - const elf_object_t *sobj; uint64_t cookie = pcookie; struct { struct __kbind param; @@ -353,15 +342,14 @@ _dl_bind(elf_object_t *object, int reloff) sym += ELF_R_SYM(rel->r_info); symn = object->dyn.strtab + sym->st_name; - this = NULL; - ooff = _dl_find_symbol(symn, &this, - SYM_SEARCH_ALL | SYM_WARNNOTFOUND | SYM_PLT, sym, object, &sobj); - if (this == NULL) + sr = _dl_find_symbol(symn, SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, + sym, object); + if (sr.sym == NULL) _dl_die("lazy binding failed!"); - buf.newval = ooff + this->st_value; + buf.newval = sr.obj->obj_base + sr.sym->st_value; - if (__predict_false(sobj->traced) && _dl_trace_plt(sobj, symn)) + if (__predict_false(sr.obj->traced) && _dl_trace_plt(sr.obj, symn)) return (buf.newval); buf.param.kb_addr = (Elf_Addr *)(object->obj_base + rel->r_offset); diff --git a/libexec/ld.so/mips64/rtld_machine.c b/libexec/ld.so/mips64/rtld_machine.c index 2e14ec9f0a9..c2dd8950f25 100644 --- a/libexec/ld.so/mips64/rtld_machine.c +++ b/libexec/ld.so/mips64/rtld_machine.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtld_machine.c,v 1.29 2018/11/16 21:15:47 guenther Exp $ */ +/* $OpenBSD: rtld_machine.c,v 1.30 2019/08/04 23:51:45 guenther Exp $ */ /* * Copyright (c) 1998-2004 Opsycon AB, Sweden. @@ -41,6 +41,23 @@ int64_t pcookie __attribute__((section(".openbsd.randomdata"))) __dso_hidden; +static inline void +_dl_reloc_ent(Elf64_Addr r_addr, Elf64_Addr value) +{ + if ((r_addr & 7) == 0) + *(u_int64_t *)r_addr += value; + else { + /* + * XXX Handle non aligned relocs. .eh_frame + * XXX in libstdc++ seems to have them... + */ + u_int64_t robj; + + _dl_bcopy((char *)r_addr, &robj, sizeof(robj)); + robj += value; + _dl_bcopy(&robj, (char *)r_addr, sizeof(robj)); + } +} int _dl_md_reloc(elf_object_t *object, int rel, int relsz) @@ -50,7 +67,6 @@ _dl_md_reloc(elf_object_t *object, int rel, int relsz) int fails = 0; struct load_list *load_list; Elf64_Addr loff; - Elf64_Addr ooff; Elf64_Rel *relocs; const Elf64_Sym *sym, *this; Elf64_Addr prev_value = 0; @@ -85,7 +101,6 @@ _dl_md_reloc(elf_object_t *object, int rel, int relsz) if (ELF64_R_SYM(relocs->r_info) == 0xffffff) continue; - ooff = 0; sym = object->dyn.symtab; sym += ELF64_R_SYM(relocs->r_info); symn = object->dyn.strtab + sym->st_name; @@ -97,44 +112,33 @@ _dl_md_reloc(elf_object_t *object, int rel, int relsz) this = sym; /* XXX non-NULL */ else if (!(ELF64_ST_BIND(sym->st_info) == STB_LOCAL && ELF64_ST_TYPE (sym->st_info) == STT_NOTYPE)) { - ooff = _dl_find_symbol(symn, &this, - SYM_SEARCH_ALL | SYM_WARNNOTFOUND | SYM_PLT, - sym, object, NULL); + struct sym_res sr; - if (this == NULL) { + sr = _dl_find_symbol(symn, + SYM_SEARCH_ALL | SYM_WARNNOTFOUND | SYM_PLT, + sym, object); + + if (sr.sym == NULL) { if (ELF_ST_BIND(sym->st_info) != STB_WEAK) fails++; continue; } prev_sym = sym; - prev_value = this->st_value + ooff; + prev_value = sr.obj->obj_base + + sr.sym->st_value; + this = sym; /* XXX non-NULL */ } } switch (ELF64_R_TYPE(relocs->r_info)) { - /* XXX Handle non aligned relocs. .eh_frame - * XXX in libstdc++ seems to have them... */ - u_int64_t robj; - case R_MIPS_REL32_64: if (ELF64_ST_BIND(sym->st_info) == STB_LOCAL && (ELF64_ST_TYPE(sym->st_info) == STT_SECTION || - ELF64_ST_TYPE(sym->st_info) == STT_NOTYPE) ) { - if ((long)r_addr & 7) { - _dl_bcopy((char *)r_addr, &robj, sizeof(robj)); - robj += loff + sym->st_value; - _dl_bcopy(&robj, (char *)r_addr, sizeof(robj)); - } else { - *(u_int64_t *)r_addr += loff + sym->st_value; - } - } else if (this && ((long)r_addr & 7)) { - _dl_bcopy((char *)r_addr, &robj, sizeof(robj)); - robj += prev_value; - _dl_bcopy(&robj, (char *)r_addr, sizeof(robj)); - } else if (this) { - *(u_int64_t *)r_addr += prev_value; - } + ELF64_ST_TYPE(sym->st_info) == STT_NOTYPE) ) + _dl_reloc_ent(r_addr, loff + sym->st_value); + else if (this) + _dl_reloc_ent(r_addr, prev_value); break; case R_MIPS_NONE: @@ -172,10 +176,8 @@ _dl_md_reloc_got(elf_object_t *object, int lazy) { int i, n; Elf64_Addr loff; - Elf64_Addr ooff; Elf64_Addr *gotp; const Elf64_Sym *symp; - const Elf64_Sym *this; const char *strt; if (object->status & STAT_GOT_DONE) @@ -205,8 +207,6 @@ _dl_md_reloc_got(elf_object_t *object, int lazy) n = object->Dyn.info[DT_MIPS_SYMTABNO - DT_LOPROC + DT_NUM] - object->Dyn.info[DT_MIPS_GOTSYM - DT_LOPROC + DT_NUM]; - this = NULL; - if (object->traced) lazy = 1; @@ -215,37 +215,37 @@ _dl_md_reloc_got(elf_object_t *object, int lazy) * Quickstart is not yet implemented. */ while (n--) { + const char *symn = strt + symp->st_name; + struct sym_res sr; + if (symp->st_shndx == SHN_UNDEF && ELF64_ST_TYPE(symp->st_info) == STT_FUNC) { if (symp->st_value == 0 || !lazy) { - this = NULL; - ooff = _dl_find_symbol(strt + symp->st_name, - &this, + sr = _dl_find_symbol(symn, SYM_SEARCH_ALL|SYM_NOWARNNOTFOUND|SYM_PLT, - symp, object, NULL); - if (this) - *gotp = this->st_value + ooff; + symp, object); + if (sr.sym) + *gotp = sr.sym->st_value + + sr.obj->obj_base; } else *gotp = symp->st_value + loff; } else if (symp->st_shndx == SHN_COMMON || symp->st_shndx == SHN_UNDEF) { - this = NULL; - ooff = _dl_find_symbol(strt + symp->st_name, &this, + sr = _dl_find_symbol(symn, SYM_SEARCH_ALL|SYM_NOWARNNOTFOUND|SYM_PLT, - symp, object, NULL); - if (this) - *gotp = this->st_value + ooff; + symp, object); + if (sr.sym) + *gotp = sr.sym->st_value + sr.obj->obj_base; } else if ((ELF64_ST_TYPE(symp->st_info) == STT_FUNC && symp->st_value != *gotp) || ELF_ST_VISIBILITY(symp->st_other) == STV_PROTECTED) { *gotp += loff; } else { /* Resolve all others immediately */ - this = NULL; - ooff = _dl_find_symbol(strt + symp->st_name, &this, + sr = _dl_find_symbol(symn, SYM_SEARCH_ALL|SYM_NOWARNNOTFOUND|SYM_PLT, - symp, object, NULL); - if (this) - *gotp = this->st_value + ooff; + symp, object); + if (sr.sym) + *gotp = sr.sym->st_value + sr.obj->obj_base; else *gotp = symp->st_value + loff; } @@ -261,10 +261,9 @@ Elf_Addr _dl_bind(elf_object_t *object, int symidx) { Elf_Addr *gotp = object->dyn.pltgot; - Elf_Addr ooff; - const Elf_Sym *sym, *this; + struct sym_res sr; + const Elf_Sym *sym; const char *symn; - const elf_object_t *sobj; int64_t cookie = pcookie; struct { struct __kbind param; @@ -278,15 +277,14 @@ _dl_bind(elf_object_t *object, int symidx) n = object->Dyn.info[DT_MIPS_LOCAL_GOTNO - DT_LOPROC + DT_NUM] - object->Dyn.info[DT_MIPS_GOTSYM - DT_LOPROC + DT_NUM]; - this = NULL; - ooff = _dl_find_symbol(symn, &this, - SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, sym, object, &sobj); - if (this == NULL) + sr = _dl_find_symbol(symn, SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, + sym, object); + if (sr.sym == NULL) _dl_die("lazy binding failed!"); - buf.newval = ooff + this->st_value; + buf.newval = sr.obj->obj_base + sr.sym->st_value; - if (__predict_false(sobj->traced) && _dl_trace_plt(sobj, symn)) + if (__predict_false(sr.obj->traced) && _dl_trace_plt(sr.obj, symn)) return (buf.newval); buf.param.kb_addr = &gotp[n + symidx]; diff --git a/libexec/ld.so/powerpc/rtld_machine.c b/libexec/ld.so/powerpc/rtld_machine.c index 8601401551d..f0bc44369f5 100644 --- a/libexec/ld.so/powerpc/rtld_machine.c +++ b/libexec/ld.so/powerpc/rtld_machine.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtld_machine.c,v 1.65 2018/11/16 21:15:47 guenther Exp $ */ +/* $OpenBSD: rtld_machine.c,v 1.66 2019/08/04 23:51:45 guenther Exp $ */ /* * Copyright (c) 1999 Dale Rahn @@ -118,8 +118,7 @@ _dl_printf("object relocation size %x, numrela %x\n", } for (; i < numrela; i++, relas++) { Elf32_Addr *r_addr = (Elf32_Addr *)(relas->r_offset + loff); - Elf32_Addr ooff; - const Elf32_Sym *sym, *this; + const Elf32_Sym *sym; const char *symn; int type; @@ -135,31 +134,25 @@ _dl_printf("object relocation size %x, numrela %x\n", sym += ELF32_R_SYM(relas->r_info); symn = object->dyn.strtab + sym->st_name; - ooff = 0; - this = NULL; if (ELF32_R_SYM(relas->r_info) && !(ELF32_ST_BIND(sym->st_info) == STB_LOCAL && - ELF32_ST_TYPE (sym->st_info) == STT_NOTYPE)) { - if (sym == prev_sym) { - this = sym; /* XXX any non-NULL */ - ooff = prev_ooff; - } else { - ooff = _dl_find_symbol_bysym(object, - ELF32_R_SYM(relas->r_info), &this, - SYM_SEARCH_ALL|SYM_WARNNOTFOUND| - ((type == RELOC_JMP_SLOT) ? - SYM_PLT:SYM_NOTPLT), sym, NULL); - - if (this == NULL) { - if (ELF_ST_BIND(sym->st_info) != - STB_WEAK) - fails++; - continue; - } - prev_sym = sym; - prev_value = this->st_value; - prev_ooff = ooff; + ELF32_ST_TYPE (sym->st_info) == STT_NOTYPE) && + sym != prev_sym) { + struct sym_res sr; + + sr = _dl_find_symbol(symn, + SYM_SEARCH_ALL|SYM_WARNNOTFOUND| + ((type == RELOC_JMP_SLOT) ? + SYM_PLT:SYM_NOTPLT), sym, object); + + if (sr.sym == NULL) { + if (ELF_ST_BIND(sym->st_info) != STB_WEAK) + fails++; + continue; } + prev_sym = sym; + prev_value = sr.sym->st_value; + prev_ooff = sr.obj->obj_base; } switch (type) { @@ -167,9 +160,9 @@ _dl_printf("object relocation size %x, numrela %x\n", if (ELF32_ST_BIND(sym->st_info) == STB_LOCAL && (ELF32_ST_TYPE(sym->st_info) == STT_SECTION || ELF32_ST_TYPE(sym->st_info) == STT_NOTYPE) ) { - *r_addr = ooff + relas->r_addend; + *r_addr = prev_ooff + relas->r_addend; } else { - *r_addr = ooff + prev_value + + *r_addr = prev_ooff + prev_value + relas->r_addend; } break; @@ -181,7 +174,7 @@ _dl_printf("object relocation size %x, numrela %x\n", #ifdef DL_PRINTF_DEBUG _dl_printf("rel1 r_addr %x val %x loff %x ooff %x addend %x\n", r_addr, - loff + relas->r_addend, loff, ooff, relas->r_addend); + loff + relas->r_addend, loff, prev_ooff, relas->r_addend); #endif } else { @@ -196,13 +189,13 @@ _dl_printf("rel1 r_addr %x val %x loff %x ooff %x addend %x\n", r_addr, */ case RELOC_JMP_SLOT: case RELOC_GLOB_DAT: - *r_addr = ooff + prev_value + relas->r_addend; + *r_addr = prev_ooff + prev_value + relas->r_addend; break; #if 1 /* should not be supported ??? */ case RELOC_REL24: { - Elf32_Addr val = ooff + prev_value + + Elf32_Addr val = prev_ooff + prev_value + relas->r_addend - (Elf32_Addr)r_addr; if (!B24_VALID_RANGE(val)) { /* invalid offset */ @@ -259,7 +252,7 @@ _dl_printf("rel1 r_addr %x val %x loff %x ooff %x addend %x\n", r_addr, case RELOC_REL14: case RELOC_REL14_NTAKEN: { - Elf32_Addr val = ooff + prev_value + + Elf32_Addr val = prev_ooff + prev_value + relas->r_addend - (Elf32_Addr)r_addr; if (((val & 0xffff8000) != 0) && ((val & 0xffff8000) != 0xffff8000)) { @@ -280,10 +273,11 @@ _dl_printf("rel1 r_addr %x val %x loff %x ooff %x addend %x\n", r_addr, break; case RELOC_COPY: { + struct sym_res sr; #ifdef DL_PRINTF_DEBUG _dl_printf("copy r_addr %x, sym %x [%s] size %d val %x\n", r_addr, sym, symn, sym->st_size, - (ooff + prev_value+ + (prev_ooff + prev_value+ relas->r_addend)); #endif /* @@ -292,28 +286,16 @@ _dl_printf("rel1 r_addr %x val %x loff %x ooff %x addend %x\n", r_addr, * searching all objects but _not_ the current object, * first one found wins. */ - const Elf32_Sym *cpysrc = NULL; - Elf32_Addr src_loff; - int size; - - src_loff = 0; - src_loff = _dl_find_symbol(symn, &cpysrc, + sr = _dl_find_symbol(symn, SYM_SEARCH_OTHER|SYM_WARNNOTFOUND| SYM_NOTPLT, - sym, object, NULL); - if (cpysrc != NULL) { - size = sym->st_size; - if (sym->st_size != cpysrc->st_size) { - _dl_printf("symbols size differ [%s] \n", - symn); - size = sym->st_size < cpysrc->st_size ? - sym->st_size : cpysrc->st_size; - } + sym, object); + if (sr.sym != NULL) { #ifdef DL_PRINTF_DEBUG _dl_printf(" found other symbol at %x size %d\n", - src_loff + cpysrc->st_value, cpysrc->st_size); + sr.obj->obj_base + sr.sym->st_value, sr.sym->st_size); #endif - _dl_bcopy((void *)(src_loff + cpysrc->st_value), - r_addr, size); + _dl_bcopy((void *)(sr.obj->obj_base + sr.sym->st_value), + r_addr, sym->st_size); } else fails++; } @@ -383,10 +365,9 @@ _dl_md_reloc_got(elf_object_t *object, int lazy) Elf_Addr _dl_bind(elf_object_t *object, int reloff) { - const Elf_Sym *sym, *this; - Elf_Addr ooff; + const Elf_Sym *sym; + struct sym_res sr; const char *symn; - const elf_object_t *sobj; Elf_RelA *relas; Elf32_Addr *plttable; int64_t cookie = pcookie; @@ -401,15 +382,14 @@ _dl_bind(elf_object_t *object, int reloff) sym += ELF_R_SYM(relas->r_info); symn = object->dyn.strtab + sym->st_name; - this = NULL; - ooff = _dl_find_symbol(symn, &this, - SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, sym, object, &sobj); - if (this == NULL) + sr = _dl_find_symbol(symn, SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, + sym, object); + if (sr.sym == NULL) _dl_die("lazy binding failed!"); - buf.newval = ooff + this->st_value; + buf.newval = sr.obj->obj_base + sr.sym->st_value; - if (__predict_false(sobj->traced) && _dl_trace_plt(sobj, symn)) + if (__predict_false(sr.obj->traced) && _dl_trace_plt(sr.obj, symn)) return buf.newval; plttable = (Elf32_Addr *)(Elf32_Rela *)(object->Dyn.info[DT_PLTGOT]); diff --git a/libexec/ld.so/resolve.c b/libexec/ld.so/resolve.c index 2b9874ba7b3..c4bd6097f5d 100644 --- a/libexec/ld.so/resolve.c +++ b/libexec/ld.so/resolve.c @@ -1,4 +1,4 @@ -/* $OpenBSD: resolve.c,v 1.91 2019/07/21 03:54:16 guenther Exp $ */ +/* $OpenBSD: resolve.c,v 1.92 2019/08/04 23:51:45 guenther Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -45,10 +45,8 @@ typedef enum { struct symlookup { const char *sl_name; - const elf_object_t *sl_obj_out; - const Elf_Sym *sl_sym_out; - const elf_object_t *sl_weak_obj_out; - const Elf_Sym *sl_weak_sym_out; + struct sym_res sl_out; + struct sym_res sl_weak_out; unsigned long sl_elf_hash; uint32_t sl_gnu_hash; int sl_flags; @@ -517,22 +515,6 @@ _dl_remove_object(elf_object_t *object) free_objects = object; } - -Elf_Addr -_dl_find_symbol_bysym(elf_object_t *req_obj, unsigned int symidx, - const Elf_Sym **this, int flags, const Elf_Sym *ref_sym, - const elf_object_t **pobj) -{ - const Elf_Sym *sym; - const char *symn; - - sym = req_obj->dyn.symtab; - sym += symidx; - symn = req_obj->dyn.strtab + sym->st_name; - - return _dl_find_symbol(symn, this, flags, ref_sym, req_obj, pobj); -} - static int matched_symbol(elf_object_t *obj, const Elf_Sym *sym, struct symlookup *sl) { @@ -564,18 +546,18 @@ matched_symbol(elf_object_t *obj, const Elf_Sym *sym, struct symlookup *sl) return 0; } - if (sym != sl->sl_sym_out && + if (sym != sl->sl_out.sym && _dl_strcmp(sl->sl_name, obj->dyn.strtab + sym->st_name)) return 0; if (ELF_ST_BIND(sym->st_info) == STB_GLOBAL) { - sl->sl_sym_out = sym; - sl->sl_obj_out = obj; + sl->sl_out.sym = sym; + sl->sl_out.obj = obj; return 1; } else if (ELF_ST_BIND(sym->st_info) == STB_WEAK) { - if (sl->sl_weak_sym_out == NULL) { - sl->sl_weak_sym_out = sym; - sl->sl_weak_obj_out = obj; + if (sl->sl_weak_out.sym == NULL) { + sl->sl_weak_out.sym = sym; + sl->sl_weak_out.obj = obj; } /* done with this object, but need to check other objects */ return -1; @@ -638,19 +620,17 @@ _dl_find_symbol_obj(elf_object_t *obj, struct symlookup *sl) return 0; } -Elf_Addr -_dl_find_symbol(const char *name, const Elf_Sym **this, - int flags, const Elf_Sym *ref_sym, elf_object_t *req_obj, - const elf_object_t **pobj) +struct sym_res +_dl_find_symbol(const char *name, int flags, const Elf_Sym *ref_sym, + elf_object_t *req_obj) { const unsigned char *p; unsigned char c; struct dep_node *n, *m; struct symlookup sl = { .sl_name = name, - .sl_obj_out = NULL, - .sl_weak_obj_out = NULL, - .sl_weak_sym_out = NULL, + .sl_out = { .sym = NULL }, + .sl_weak_out = { .sym = NULL }, .sl_elf_hash = 0, .sl_gnu_hash = 5381, .sl_flags = flags, @@ -675,7 +655,7 @@ _dl_find_symbol(const char *name, const Elf_Sym **this, goto found; /* weak definition in the specified object is good enough */ - if (sl.sl_weak_obj_out != NULL) + if (sl.sl_weak_out.sym != NULL) goto found; /* search dlopened obj and all children */ @@ -717,33 +697,29 @@ _dl_find_symbol(const char *name, const Elf_Sym **this, } found: - if (sl.sl_sym_out != NULL) { - *this = sl.sl_sym_out; - } else if (sl.sl_weak_obj_out != NULL) { - sl.sl_obj_out = sl.sl_weak_obj_out; - *this = sl.sl_weak_sym_out; - } else { - if ((ref_sym == NULL || - (ELF_ST_BIND(ref_sym->st_info) != STB_WEAK)) && - (flags & SYM_WARNNOTFOUND)) - _dl_printf("%s:%s: undefined symbol '%s'\n", - __progname, req_obj->load_name, name); - return (0); + if (sl.sl_out.sym == NULL) { + if (sl.sl_weak_out.sym != NULL) + sl.sl_out = sl.sl_weak_out; + else { + if ((ref_sym == NULL || + (ELF_ST_BIND(ref_sym->st_info) != STB_WEAK)) && + (flags & SYM_WARNNOTFOUND)) + _dl_printf("%s:%s: undefined symbol '%s'\n", + __progname, req_obj->load_name, name); + return (struct sym_res){ NULL, NULL }; + } } if (ref_sym != NULL && ref_sym->st_size != 0 && - (ref_sym->st_size != (*this)->st_size) && - (ELF_ST_TYPE((*this)->st_info) != STT_FUNC) ) { + (ref_sym->st_size != sl.sl_out.sym->st_size) && + (ELF_ST_TYPE(sl.sl_out.sym->st_info) != STT_FUNC) ) { _dl_printf("%s:%s: %s : WARNING: " "symbol(%s) size mismatch, relink your program\n", - __progname, req_obj->load_name, sl.sl_obj_out->load_name, + __progname, req_obj->load_name, sl.sl_out.obj->load_name, name); } - if (pobj != NULL) - *pobj = sl.sl_obj_out; - - return sl.sl_obj_out->obj_base; + return sl.sl_out; } void diff --git a/libexec/ld.so/resolve.h b/libexec/ld.so/resolve.h index ac90ac4a0e7..7d9b2ab27c9 100644 --- a/libexec/ld.so/resolve.h +++ b/libexec/ld.so/resolve.h @@ -1,4 +1,4 @@ -/* $OpenBSD: resolve.h,v 1.93 2019/07/21 03:54:16 guenther Exp $ */ +/* $OpenBSD: resolve.h,v 1.94 2019/08/04 23:51:45 guenther Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -249,12 +249,14 @@ elf_object_t *_dl_tryload_shlib(const char *libname, int type, int flags); int _dl_md_reloc(elf_object_t *object, int rel, int relsz); int _dl_md_reloc_got(elf_object_t *object, int lazy); -Elf_Addr _dl_find_symbol(const char *name, const Elf_Sym **this, - int flags, const Elf_Sym *ref_sym, elf_object_t *object, - const elf_object_t **pobj); -Elf_Addr _dl_find_symbol_bysym(elf_object_t *req_obj, unsigned int symidx, - const Elf_Sym **ref, int flags, const Elf_Sym *ref_sym, - const elf_object_t **pobj); +struct sym_res { + const Elf_Sym *sym; + const elf_object_t *obj; +}; + +struct sym_res _dl_find_symbol(const char *name, int flags, + const Elf_Sym *ref_sym, elf_object_t *object); + /* * defines for _dl_find_symbol() flag field, three bits of meaning * myself - clear: search all objects, set: search only this object diff --git a/libexec/ld.so/sh/rtld_machine.c b/libexec/ld.so/sh/rtld_machine.c index 37fbabf0718..5478f7745ec 100644 --- a/libexec/ld.so/sh/rtld_machine.c +++ b/libexec/ld.so/sh/rtld_machine.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtld_machine.c,v 1.27 2018/11/16 21:15:47 guenther Exp $ */ +/* $OpenBSD: rtld_machine.c,v 1.28 2019/08/04 23:51:45 guenther Exp $ */ /* * Copyright (c) 2004 Dale Rahn @@ -646,9 +646,9 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz) *where = rels->r_addend + loff; } for (; i < numrela; i++, rels++) { - Elf_Addr *where, value, ooff, mask; + Elf_Addr *where, value, mask; Elf_Word type; - const Elf_Sym *sym, *this; + const Elf_Sym *sym; const char *symn; type = ELF_R_TYPE(rels->r_info); @@ -688,22 +688,14 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz) } else if (sym == prev_sym) { value += prev_value; } else { - this = NULL; -#if 1 - ooff = _dl_find_symbol_bysym(object, - ELF_R_SYM(rels->r_info), &this, + struct sym_res sr; + + sr = _dl_find_symbol(symn, SYM_SEARCH_ALL|SYM_WARNNOTFOUND| ((type == R_TYPE(JMP_SLOT)) ? SYM_PLT : SYM_NOTPLT), - sym, NULL); -#else - ooff = _dl_find_symbol_bysym(object, - ELF_R_SYM(rels->r_info), &this, - SYM_SEARCH_ALL|SYM_WARNNOTFOUND| - SYM_PLT, - sym, NULL); -#endif - if (this == NULL) { + sym, object); + if (sr.sym == NULL) { resolve_failed: if (ELF_ST_BIND(sym->st_info) != STB_WEAK) @@ -711,7 +703,8 @@ resolve_failed: continue; } prev_sym = sym; - prev_value = (Elf_Addr)(ooff + this->st_value); + prev_value = (Elf_Addr)(sr.obj->obj_base + + sr.sym->st_value); value += prev_value; } } @@ -724,16 +717,16 @@ resolve_failed: if (type == R_TYPE(COPY)) { void *dstaddr = where; const void *srcaddr; - const Elf_Sym *dstsym = sym, *srcsym = NULL; - Elf_Addr soff; + const Elf_Sym *dstsym = sym; + struct sym_res sr; - soff = _dl_find_symbol(symn, &srcsym, + sr = _dl_find_symbol(symn, SYM_SEARCH_OTHER|SYM_WARNNOTFOUND|SYM_NOTPLT, - dstsym, object, NULL); - if (srcsym == NULL) + dstsym, object); + if (sr.sym == NULL) goto resolve_failed; - srcaddr = (void *)(soff + srcsym->st_value); + srcaddr = (void *)(sr.obj->obj_base + sr.sym->st_value); _dl_bcopy(srcaddr, dstaddr, dstsym->st_size); continue; } @@ -832,10 +825,9 @@ Elf_Addr _dl_bind(elf_object_t *object, int reloff) { Elf_RelA *rel; - const Elf_Sym *sym, *this; + const Elf_Sym *sym; const char *symn; - const elf_object_t *sobj; - Elf_Addr ooff; + struct sym_res sr; uint64_t cookie = pcookie; struct { struct __kbind param; @@ -848,15 +840,14 @@ _dl_bind(elf_object_t *object, int reloff) sym += ELF_R_SYM(rel->r_info); symn = object->dyn.strtab + sym->st_name; - this = NULL; - ooff = _dl_find_symbol(symn, &this, - SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, sym, object, &sobj); - if (this == NULL) + sr = _dl_find_symbol(symn, SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, + sym, object); + if (sr.sym == NULL) _dl_die("lazy binding failed!"); - buf.newval = ooff + this->st_value; + buf.newval = sr.obj->obj_base + sr.sym->st_value; - if (__predict_false(sobj->traced) && _dl_trace_plt(sobj, symn)) + if (__predict_false(sr.obj->traced) && _dl_trace_plt(sr.obj, symn)) return (buf.newval); buf.param.kb_addr = (Elf_Addr *)(object->obj_base + rel->r_offset); diff --git a/libexec/ld.so/sparc64/rtld_machine.c b/libexec/ld.so/sparc64/rtld_machine.c index f106011606e..65ca082a7eb 100644 --- a/libexec/ld.so/sparc64/rtld_machine.c +++ b/libexec/ld.so/sparc64/rtld_machine.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtld_machine.c,v 1.63 2018/11/16 21:15:47 guenther Exp $ */ +/* $OpenBSD: rtld_machine.c,v 1.64 2019/08/04 23:51:45 guenther Exp $ */ /* * Copyright (c) 1999 Dale Rahn @@ -251,9 +251,9 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz) *where = relas->r_addend + loff; } for (; i < numrela; i++, relas++) { - Elf_Addr *where, value, ooff, mask; + Elf_Addr *where, value, mask; Elf_Word type; - const Elf_Sym *sym, *this; + const Elf_Sym *sym; const char *symn; type = ELF_R_TYPE(relas->r_info); @@ -281,14 +281,12 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz) } else if (sym == prev_sym) { value += prev_value; } else { - this = NULL; - ooff = _dl_find_symbol_bysym(object, - ELF_R_SYM(relas->r_info), &this, - SYM_SEARCH_ALL|SYM_WARNNOTFOUND| - ((type == R_TYPE(JMP_SLOT)) ? - SYM_PLT : SYM_NOTPLT), - sym, NULL); - if (this == NULL) { + struct sym_res sr; + + sr = _dl_find_symbol(symn, + SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_NOTPLT, + sym, object); + if (sr.sym == NULL) { resolve_failed: if (ELF_ST_BIND(sym->st_info) != STB_WEAK) @@ -296,7 +294,8 @@ resolve_failed: continue; } prev_sym = sym; - prev_value = (Elf_Addr)(ooff + this->st_value); + prev_value = (Elf_Addr)(sr.obj->obj_base + + sr.sym->st_value); value += prev_value; } } @@ -304,18 +303,17 @@ resolve_failed: if (type == R_TYPE(COPY)) { void *dstaddr = where; const void *srcaddr; - const Elf_Sym *dstsym = sym, *srcsym = NULL; - size_t size = dstsym->st_size; - Elf_Addr soff; + const Elf_Sym *dstsym = sym; + struct sym_res sr; - soff = _dl_find_symbol(symn, &srcsym, + sr = _dl_find_symbol(symn, SYM_SEARCH_OTHER|SYM_WARNNOTFOUND|SYM_NOTPLT, - dstsym, object, NULL); - if (srcsym == NULL) + dstsym, object); + if (sr.sym == NULL) goto resolve_failed; - srcaddr = (void *)(soff + srcsym->st_value); - _dl_bcopy(srcaddr, dstaddr, size); + srcaddr = (void *)(sr.obj->obj_base + sr.sym->st_value); + _dl_bcopy(srcaddr, dstaddr, dstsym->st_size); continue; } @@ -591,10 +589,10 @@ _dl_bind(elf_object_t *object, int index) { Elf_RelA *rela; Elf_Word *addr; - Elf_Addr ooff, newvalue; - const Elf_Sym *sym, *this; + Elf_Addr newvalue; + struct sym_res sr; + const Elf_Sym *sym; const char *symn; - const elf_object_t *sobj; int64_t cookie = pcookie; struct { struct __kbind param[2]; @@ -632,15 +630,14 @@ _dl_bind(elf_object_t *object, int index) sym += ELF64_R_SYM(rela->r_info); symn = object->dyn.strtab + sym->st_name; - this = NULL; - ooff = _dl_find_symbol(symn, &this, - SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, sym, object, &sobj); - if (this == NULL) + sr = _dl_find_symbol(symn, SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, + sym, object); + if (sr.sym == NULL) _dl_die("lazy binding failed!"); - newvalue = ooff + this->st_value; + newvalue = sr.obj->obj_base + sr.sym->st_value; - if (__predict_false(sobj->traced) && _dl_trace_plt(sobj, symn)) + if (__predict_false(sr.obj->traced) && _dl_trace_plt(sr.obj, symn)) return (newvalue); /* @@ -790,24 +787,25 @@ _dl_md_reloc_all_plt(elf_object_t *object) for (i = 0; i < numrela; i++, relas++) { Elf_Addr value; Elf_Word *where; - const Elf_Sym *sym, *this; + struct sym_res sr; + const Elf_Sym *sym; if (ELF_R_TYPE(relas->r_info) != R_TYPE(JMP_SLOT)) continue; sym = object->dyn.symtab + ELF_R_SYM(relas->r_info); - this = NULL; - value = _dl_find_symbol_bysym(object, ELF_R_SYM(relas->r_info), - &this, SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, sym, NULL); - if (this == NULL) { + sr = _dl_find_symbol(object->dyn.strtab + sym->st_name, + SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, + sym, object); + if (sr.sym == NULL) { if (ELF_ST_BIND(sym->st_info) != STB_WEAK) fails++; continue; } where = (Elf_Word *)(relas->r_offset + loff); - value += this->st_value; + value = sr.obj->obj_base + sr.sym->st_value; if (__predict_false(relas->r_addend)) { /* |