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