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/sparc64 | |
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/sparc64')
-rw-r--r-- | libexec/ld.so/sparc64/rtld_machine.c | 68 |
1 files changed, 33 insertions, 35 deletions
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)) { /* |