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/sh | |
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/sh')
-rw-r--r-- | libexec/ld.so/sh/rtld_machine.c | 55 |
1 files changed, 23 insertions, 32 deletions
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); |