summaryrefslogtreecommitdiff
path: root/libexec/ld.so
diff options
context:
space:
mode:
authorPhilip Guenther <guenther@cvs.openbsd.org>2019-08-04 23:51:46 +0000
committerPhilip Guenther <guenther@cvs.openbsd.org>2019-08-04 23:51:46 +0000
commit70c8650d865f6421df65fc33c7991cff1ca26339 (patch)
tree4aaa212d84916f4311b26cd6a8d8d74f3f99dcc7 /libexec/ld.so
parent5d78eea126a1d3367fc351ff73244359b90e76f6 (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.c48
-rw-r--r--libexec/ld.so/alpha/rtld_machine.c51
-rw-r--r--libexec/ld.so/amd64/rtld_machine.c48
-rw-r--r--libexec/ld.so/arm/rtld_machine.c48
-rw-r--r--libexec/ld.so/dlfcn.c32
-rw-r--r--libexec/ld.so/hppa/rtld_machine.c85
-rw-r--r--libexec/ld.so/i386/rtld_machine.c51
-rw-r--r--libexec/ld.so/loader.c46
-rw-r--r--libexec/ld.so/m88k/rtld_machine.c56
-rw-r--r--libexec/ld.so/mips64/rtld_machine.c110
-rw-r--r--libexec/ld.so/powerpc/rtld_machine.c98
-rw-r--r--libexec/ld.so/resolve.c84
-rw-r--r--libexec/ld.so/resolve.h16
-rw-r--r--libexec/ld.so/sh/rtld_machine.c55
-rw-r--r--libexec/ld.so/sparc64/rtld_machine.c68
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)) {
/*