summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2015-09-27 01:33:43 +0000
committerkib <kib@FreeBSD.org>2015-09-27 01:33:43 +0000
commitb44e8c14438c6602432ef5d490df5fd818d5a1db (patch)
tree606c7d952a5108145e2f9e88a6ecd9c4b0d13664
parent8a6fcabbcf4777957124f6be9ba9dba42b68a9b7 (diff)
downloadFreeBSD-src-b44e8c14438c6602432ef5d490df5fd818d5a1db.zip
FreeBSD-src-b44e8c14438c6602432ef5d490df5fd818d5a1db.tar.gz
MFC r288000:
Add support for weak symbols to the kernel linkers.
-rw-r--r--sys/amd64/amd64/elf_machdep.c17
-rw-r--r--sys/arm/arm/elf_machdep.c9
-rw-r--r--sys/i386/i386/elf_machdep.c13
-rw-r--r--sys/ia64/ia64/elf_machdep.c39
-rw-r--r--sys/kern/link_elf.c30
-rw-r--r--sys/kern/link_elf_obj.c51
-rw-r--r--sys/mips/mips/elf_machdep.c33
-rw-r--r--sys/powerpc/powerpc/elf32_machdep.c15
-rw-r--r--sys/powerpc/powerpc/elf64_machdep.c9
-rw-r--r--sys/sparc64/sparc64/elf_machdep.c5
-rw-r--r--sys/sys/linker.h2
11 files changed, 127 insertions, 96 deletions
diff --git a/sys/amd64/amd64/elf_machdep.c b/sys/amd64/amd64/elf_machdep.c
index 23fa39b..f9ba30d 100644
--- a/sys/amd64/amd64/elf_machdep.c
+++ b/sys/amd64/amd64/elf_machdep.c
@@ -167,6 +167,7 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
Elf_Size rtype, symidx;
const Elf_Rel *rel;
const Elf_Rela *rela;
+ int error;
switch (type) {
case ELF_RELOC_REL:
@@ -202,29 +203,29 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
break;
case R_X86_64_64: /* S + A */
- addr = lookup(lf, symidx, 1);
+ error = lookup(lf, symidx, 1, &addr);
val = addr + addend;
- if (addr == 0)
+ if (error != 0)
return -1;
if (*where != val)
*where = val;
break;
case R_X86_64_PC32: /* S + A - P */
- addr = lookup(lf, symidx, 1);
+ error = lookup(lf, symidx, 1, &addr);
where32 = (Elf32_Addr *)where;
val32 = (Elf32_Addr)(addr + addend - (Elf_Addr)where);
- if (addr == 0)
+ if (error != 0)
return -1;
if (*where32 != val32)
*where32 = val32;
break;
case R_X86_64_32S: /* S + A sign extend */
- addr = lookup(lf, symidx, 1);
+ error = lookup(lf, symidx, 1, &addr);
val32 = (Elf32_Addr)(addr + addend);
where32 = (Elf32_Addr *)where;
- if (addr == 0)
+ if (error != 0)
return -1;
if (*where32 != val32)
*where32 = val32;
@@ -241,8 +242,8 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
case R_X86_64_GLOB_DAT: /* S */
case R_X86_64_JMP_SLOT: /* XXX need addend + offset */
- addr = lookup(lf, symidx, 1);
- if (addr == 0)
+ error = lookup(lf, symidx, 1, &addr);
+ if (error != 0)
return -1;
if (*where != addr)
*where = addr;
diff --git a/sys/arm/arm/elf_machdep.c b/sys/arm/arm/elf_machdep.c
index 8ef9bd4..931a82b 100644
--- a/sys/arm/arm/elf_machdep.c
+++ b/sys/arm/arm/elf_machdep.c
@@ -132,6 +132,7 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
Elf_Word rtype, symidx;
const Elf_Rel *rel;
const Elf_Rela *rela;
+ int error;
switch (type) {
case ELF_RELOC_REL:
@@ -167,8 +168,8 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
break;
case R_ARM_ABS32:
- addr = lookup(lf, symidx, 1);
- if (addr == 0)
+ error = lookup(lf, symidx, 1, &addr);
+ if (error != 0)
return -1;
*where += addr;
break;
@@ -183,8 +184,8 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
break;
case R_ARM_JUMP_SLOT:
- addr = lookup(lf, symidx, 1);
- if (addr) {
+ error = lookup(lf, symidx, 1, &addr);
+ if (error == 0) {
*where = addr;
return (0);
}
diff --git a/sys/i386/i386/elf_machdep.c b/sys/i386/i386/elf_machdep.c
index 8cd4440..6acd32a 100644
--- a/sys/i386/i386/elf_machdep.c
+++ b/sys/i386/i386/elf_machdep.c
@@ -177,6 +177,7 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
Elf_Word rtype, symidx;
const Elf_Rel *rel;
const Elf_Rela *rela;
+ int error;
switch (type) {
case ELF_RELOC_REL:
@@ -212,8 +213,8 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
break;
case R_386_32: /* S + A */
- addr = lookup(lf, symidx, 1);
- if (addr == 0)
+ error = lookup(lf, symidx, 1, &addr);
+ if (error != 0)
return -1;
addr += addend;
if (*where != addr)
@@ -221,8 +222,8 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
break;
case R_386_PC32: /* S + A - P */
- addr = lookup(lf, symidx, 1);
- if (addr == 0)
+ error = lookup(lf, symidx, 1, &addr);
+ if (error != 0)
return -1;
addr += addend - (Elf_Addr)where;
if (*where != addr)
@@ -239,8 +240,8 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
break;
case R_386_GLOB_DAT: /* S */
- addr = lookup(lf, symidx, 1);
- if (addr == 0)
+ error = lookup(lf, symidx, 1, &addr);
+ if (error != 0)
return -1;
if (*where != addr)
*where = addr;
diff --git a/sys/ia64/ia64/elf_machdep.c b/sys/ia64/ia64/elf_machdep.c
index 05cb641..f1ab4a0 100644
--- a/sys/ia64/ia64/elf_machdep.c
+++ b/sys/ia64/ia64/elf_machdep.c
@@ -127,17 +127,18 @@ elf64_dump_thread(struct thread *td, void *dst, size_t *off __unused)
}
-static Elf_Addr
-lookup_fdesc(linker_file_t lf, Elf_Size symidx, elf_lookup_fn lookup)
+static int
+lookup_fdesc(linker_file_t lf, Elf_Size symidx, elf_lookup_fn lookup,
+ Elf_Addr *addr1)
{
linker_file_t top;
Elf_Addr addr;
const char *symname;
- int i;
+ int i, error;
static int eot = 0;
- addr = lookup(lf, symidx, 0);
- if (addr == 0) {
+ error = lookup(lf, symidx, 0, &addr);
+ if (error != 0) {
top = lf;
symname = elf_get_symname(top, symidx);
for (i = 0; i < top->ndeps; i++) {
@@ -148,30 +149,33 @@ lookup_fdesc(linker_file_t lf, Elf_Size symidx, elf_lookup_fn lookup)
break;
}
if (addr == 0)
- return (0);
+ return (EINVAL);
}
if (eot)
- return (0);
+ return (EINVAL);
/*
* Lookup and/or construct OPD
*/
for (i = 0; i < 8192; i += 2) {
- if (fptr_storage[i] == addr)
- return (Elf_Addr)(fptr_storage + i);
+ if (fptr_storage[i] == addr) {
+ *addr1 = (Elf_Addr)(fptr_storage + i);
+ return (0);
+ }
if (fptr_storage[i] == 0) {
fptr_storage[i] = addr;
fptr_storage[i+1] = link_elf_get_gp(lf);
- return (Elf_Addr)(fptr_storage + i);
+ *addr1 = (Elf_Addr)(fptr_storage + i);
+ return (0);
}
}
printf("%s: fptr table full\n", __func__);
eot = 1;
- return (0);
+ return (EINVAL);
}
/* Process one elf relocation with addend. */
@@ -184,6 +188,7 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
Elf_Size rtype, symidx;
const Elf_Rel *rel;
const Elf_Rela *rela;
+ int error;
switch (type) {
case ELF_RELOC_REL:
@@ -223,8 +228,8 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
case R_IA_64_NONE:
break;
case R_IA_64_DIR64LSB: /* word64 LSB S + A */
- addr = lookup(lf, symidx, 1);
- if (addr == 0)
+ error = lookup(lf, symidx, 1, &addr);
+ if (error != 0)
return (-1);
*where = addr + addend;
break;
@@ -233,16 +238,16 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
printf("%s: addend ignored for OPD relocation\n",
__func__);
}
- addr = lookup_fdesc(lf, symidx, lookup);
- if (addr == 0)
+ error = lookup_fdesc(lf, symidx, lookup, &addr);
+ if (error != 0)
return (-1);
*where = addr;
break;
case R_IA_64_REL64LSB: /* word64 LSB BD + A */
break;
case R_IA_64_IPLTLSB:
- addr = lookup_fdesc(lf, symidx, lookup);
- if (addr == 0)
+ error = lookup_fdesc(lf, symidx, lookup, &addr);
+ if (error != 0)
return (-1);
where[0] = *((Elf_Addr*)addr) + addend;
where[1] = *((Elf_Addr*)addr + 1);
diff --git a/sys/kern/link_elf.c b/sys/kern/link_elf.c
index 631ba75..b4f6586 100644
--- a/sys/kern/link_elf.c
+++ b/sys/kern/link_elf.c
@@ -158,7 +158,7 @@ static int link_elf_each_function_nameval(linker_file_t,
static void link_elf_reloc_local(linker_file_t);
static long link_elf_symtab_get(linker_file_t, const Elf_Sym **);
static long link_elf_strtab_get(linker_file_t, caddr_t *);
-static Elf_Addr elf_lookup(linker_file_t, Elf_Size, int);
+static int elf_lookup(linker_file_t, Elf_Size, int, Elf_Addr *);
static kobj_method_t link_elf_methods[] = {
KOBJMETHOD(linker_lookup_symbol, link_elf_lookup_symbol),
@@ -1498,8 +1498,8 @@ elf_get_symname(linker_file_t lf, Elf_Size symidx)
* This is not only more efficient, it's also more correct. It's not always
* the case that the symbol can be found through the hash table.
*/
-static Elf_Addr
-elf_lookup(linker_file_t lf, Elf_Size symidx, int deps)
+static int
+elf_lookup(linker_file_t lf, Elf_Size symidx, int deps, Elf_Addr *res)
{
elf_file_t ef = (elf_file_t)lf;
const Elf_Sym *sym;
@@ -1507,8 +1507,10 @@ elf_lookup(linker_file_t lf, Elf_Size symidx, int deps)
Elf_Addr addr, start, base;
/* Don't even try to lookup the symbol if the index is bogus. */
- if (symidx >= ef->nchains)
- return (0);
+ if (symidx >= ef->nchains) {
+ *res = 0;
+ return (EINVAL);
+ }
sym = ef->symtab + symidx;
@@ -1518,9 +1520,12 @@ elf_lookup(linker_file_t lf, Elf_Size symidx, int deps)
*/
if (ELF_ST_BIND(sym->st_info) == STB_LOCAL) {
/* Force lookup failure when we have an insanity. */
- if (sym->st_shndx == SHN_UNDEF || sym->st_value == 0)
- return (0);
- return ((Elf_Addr)ef->address + sym->st_value);
+ if (sym->st_shndx == SHN_UNDEF || sym->st_value == 0) {
+ *res = 0;
+ return (EINVAL);
+ }
+ *res = ((Elf_Addr)ef->address + sym->st_value);
+ return (0);
}
/*
@@ -1533,8 +1538,10 @@ elf_lookup(linker_file_t lf, Elf_Size symidx, int deps)
symbol = ef->strtab + sym->st_name;
/* Force a lookup failure if the symbol name is bogus. */
- if (*symbol == 0)
- return (0);
+ if (*symbol == 0) {
+ *res = 0;
+ return (EINVAL);
+ }
addr = ((Elf_Addr)linker_file_lookup_symbol(lf, symbol, deps));
@@ -1544,7 +1551,8 @@ elf_lookup(linker_file_t lf, Elf_Size symidx, int deps)
else if (elf_set_find(&set_vnet_list, addr, &start, &base))
addr = addr - start + base;
#endif
- return addr;
+ *res = addr;
+ return (0);
}
static void
diff --git a/sys/kern/link_elf_obj.c b/sys/kern/link_elf_obj.c
index 4f40258..453d8ce 100644
--- a/sys/kern/link_elf_obj.c
+++ b/sys/kern/link_elf_obj.c
@@ -144,7 +144,8 @@ static void link_elf_reloc_local(linker_file_t);
static long link_elf_symtab_get(linker_file_t, const Elf_Sym **);
static long link_elf_strtab_get(linker_file_t, caddr_t *);
-static Elf_Addr elf_obj_lookup(linker_file_t lf, Elf_Size symidx, int deps);
+static int elf_obj_lookup(linker_file_t lf, Elf_Size symidx, int deps,
+ Elf_Addr *);
static kobj_method_t link_elf_methods[] = {
KOBJMETHOD(linker_lookup_symbol, link_elf_lookup_symbol),
@@ -1224,38 +1225,46 @@ elf_obj_cleanup_globals_cache(elf_file_t ef)
* This is not only more efficient, it's also more correct. It's not always
* the case that the symbol can be found through the hash table.
*/
-static Elf_Addr
-elf_obj_lookup(linker_file_t lf, Elf_Size symidx, int deps)
+static int
+elf_obj_lookup(linker_file_t lf, Elf_Size symidx, int deps, Elf_Addr *res)
{
elf_file_t ef = (elf_file_t)lf;
Elf_Sym *sym;
const char *symbol;
- Elf_Addr ret;
+ Elf_Addr res1;
/* Don't even try to lookup the symbol if the index is bogus. */
- if (symidx >= ef->ddbsymcnt)
- return (0);
+ if (symidx >= ef->ddbsymcnt) {
+ *res = 0;
+ return (EINVAL);
+ }
sym = ef->ddbsymtab + symidx;
/* Quick answer if there is a definition included. */
- if (sym->st_shndx != SHN_UNDEF)
- return (sym->st_value);
+ if (sym->st_shndx != SHN_UNDEF) {
+ *res = sym->st_value;
+ return (0);
+ }
/* If we get here, then it is undefined and needs a lookup. */
switch (ELF_ST_BIND(sym->st_info)) {
case STB_LOCAL:
/* Local, but undefined? huh? */
- return (0);
+ *res = 0;
+ return (EINVAL);
case STB_GLOBAL:
+ case STB_WEAK:
/* Relative to Data or Function name */
symbol = ef->ddbstrtab + sym->st_name;
/* Force a lookup failure if the symbol name is bogus. */
- if (*symbol == 0)
- return (0);
- ret = ((Elf_Addr)linker_file_lookup_symbol(lf, symbol, deps));
+ if (*symbol == 0) {
+ *res = 0;
+ return (EINVAL);
+ }
+ res1 = (Elf_Addr)linker_file_lookup_symbol(lf, symbol, deps);
/*
* Cache global lookups during module relocation. The failure
@@ -1267,18 +1276,20 @@ elf_obj_lookup(linker_file_t lf, Elf_Size symidx, int deps)
* restored to SHN_UNDEF in elf_obj_cleanup_globals_cache(),
* above.
*/
- if (ret != 0) {
+ if (res1 != 0) {
sym->st_shndx = SHN_FBSD_CACHED;
- sym->st_value = ret;
+ sym->st_value = res1;
+ *res = res1;
+ return (0);
+ } else if (ELF_ST_BIND(sym->st_info) == STB_WEAK) {
+ sym->st_value = 0;
+ *res = 0;
+ return (0);
}
- return (ret);
-
- case STB_WEAK:
- printf("link_elf_obj: Weak symbols not supported\n");
- return (0);
+ return (EINVAL);
default:
- return (0);
+ return (EINVAL);
}
}
diff --git a/sys/mips/mips/elf_machdep.c b/sys/mips/mips/elf_machdep.c
index d374713..2e22281 100644
--- a/sys/mips/mips/elf_machdep.c
+++ b/sys/mips/mips/elf_machdep.c
@@ -174,6 +174,7 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
Elf_Word rtype = (Elf_Word)0, symidx;
const Elf_Rel *rel = NULL;
const Elf_Rela *rela = NULL;
+ int error;
/*
* Stash R_MIPS_HI16 info so we can use it when processing R_MIPS_LO16
@@ -213,8 +214,8 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
break;
case R_MIPS_32: /* S + A */
- addr = lookup(lf, symidx, 1);
- if (addr == 0)
+ error = lookup(lf, symidx, 1, &addr);
+ if (error != 0)
return (-1);
addr += addend;
if (*where != addr)
@@ -222,8 +223,8 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
break;
case R_MIPS_26: /* ((A << 2) | (P & 0xf0000000) + S) >> 2 */
- addr = lookup(lf, symidx, 1);
- if (addr == 0)
+ error = lookup(lf, symidx, 1, &addr);
+ if (error != 0)
return (-1);
addend &= 0x03ffffff;
@@ -241,8 +242,8 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
break;
case R_MIPS_64: /* S + A */
- addr = lookup(lf, symidx, 1);
- if (addr == 0)
+ error = lookup(lf, symidx, 1, &addr);
+ if (error != 0)
return (-1);
addr += addend;
if (*(Elf64_Addr*)where != addr)
@@ -251,8 +252,8 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
case R_MIPS_HI16: /* ((AHL + S) - ((short)(AHL + S)) >> 16 */
if (rela != NULL) {
- addr = lookup(lf, symidx, 1);
- if (addr == 0)
+ error = lookup(lf, symidx, 1, &addr);
+ if (error != 0)
return (-1);
addr += addend;
*where &= 0xffff0000;
@@ -266,8 +267,8 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
case R_MIPS_LO16: /* AHL + S */
if (rela != NULL) {
- addr = lookup(lf, symidx, 1);
- if (addr == 0)
+ error = lookup(lf, symidx, 1, &addr);
+ if (error != 0)
return (-1);
addr += addend;
*where &= 0xffff0000;
@@ -275,8 +276,8 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
}
else {
ahl += (int16_t)addend;
- addr = lookup(lf, symidx, 1);
- if (addr == 0)
+ error = lookup(lf, symidx, 1, &addr);
+ if (error != 0)
return (-1);
addend &= 0xffff0000;
@@ -292,8 +293,8 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
break;
case R_MIPS_HIGHER: /* %higher(A+S) */
- addr = lookup(lf, symidx, 1);
- if (addr == 0)
+ error = lookup(lf, symidx, 1, &addr);
+ if (error != 0)
return (-1);
addr += addend;
*where &= 0xffff0000;
@@ -301,8 +302,8 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
break;
case R_MIPS_HIGHEST: /* %highest(A+S) */
- addr = lookup(lf, symidx, 1);
- if (addr == 0)
+ error = lookup(lf, symidx, 1, &addr);
+ if (error != 0)
return (-1);
addr += addend;
*where &= 0xffff0000;
diff --git a/sys/powerpc/powerpc/elf32_machdep.c b/sys/powerpc/powerpc/elf32_machdep.c
index dbe58df..c2094ff 100644
--- a/sys/powerpc/powerpc/elf32_machdep.c
+++ b/sys/powerpc/powerpc/elf32_machdep.c
@@ -164,6 +164,7 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
Elf_Addr addend;
Elf_Word rtype, symidx;
const Elf_Rela *rela;
+ int error;
switch (type) {
case ELF_RELOC_REL:
@@ -187,16 +188,16 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
break;
case R_PPC_ADDR32: /* word32 S + A */
- addr = lookup(lf, symidx, 1);
- if (addr == 0)
- return -1;
+ error = lookup(lf, symidx, 1, &addr);
+ if (error != 0)
+ return -1;
addr += addend;
*where = addr;
break;
case R_PPC_ADDR16_LO: /* #lo(S) */
- addr = lookup(lf, symidx, 1);
- if (addr == 0)
+ error = lookup(lf, symidx, 1, &addr);
+ if (error != 0)
return -1;
/*
* addend values are sometimes relative to sections
@@ -211,8 +212,8 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
break;
case R_PPC_ADDR16_HA: /* #ha(S) */
- addr = lookup(lf, symidx, 1);
- if (addr == 0)
+ error = lookup(lf, symidx, 1, &addr);
+ if (error != 0)
return -1;
/*
* addend values are sometimes relative to sections
diff --git a/sys/powerpc/powerpc/elf64_machdep.c b/sys/powerpc/powerpc/elf64_machdep.c
index 0c41a8d..3fcca47 100644
--- a/sys/powerpc/powerpc/elf64_machdep.c
+++ b/sys/powerpc/powerpc/elf64_machdep.c
@@ -135,6 +135,7 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
Elf_Addr addend;
Elf_Word rtype, symidx;
const Elf_Rela *rela;
+ int error;
switch (type) {
case ELF_RELOC_REL:
@@ -157,9 +158,9 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
break;
case R_PPC64_ADDR64: /* doubleword64 S + A */
- addr = lookup(lf, symidx, 1);
- if (addr == 0)
- return -1;
+ error = lookup(lf, symidx, 1, &addr);
+ if (error != 0)
+ return -1;
addr += addend;
*where = addr;
break;
@@ -169,7 +170,7 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
break;
case R_PPC_JMP_SLOT: /* function descriptor copy */
- addr = lookup(lf, symidx, 1);
+ lookup(lf, symidx, 1, &addr);
memcpy(where, (Elf_Addr *)addr, 3*sizeof(Elf_Addr));
__asm __volatile("dcbst 0,%0; sync" :: "r"(where) : "memory");
break;
diff --git a/sys/sparc64/sparc64/elf_machdep.c b/sys/sparc64/sparc64/elf_machdep.c
index 4d55717..621e643 100644
--- a/sys/sparc64/sparc64/elf_machdep.c
+++ b/sys/sparc64/sparc64/elf_machdep.c
@@ -343,6 +343,7 @@ elf_reloc(linker_file_t lf, Elf_Addr relocbase, const void *data, int type,
Elf_Addr value;
Elf_Addr mask;
Elf_Addr addr;
+ int error;
if (type != ELF_RELOC_RELA)
return (-1);
@@ -371,8 +372,8 @@ elf_reloc(linker_file_t lf, Elf_Addr relocbase, const void *data, int type,
value = rela->r_addend;
if (RELOC_RESOLVE_SYMBOL(rtype)) {
- addr = lookup(lf, symidx, 1);
- if (addr == 0)
+ error = lookup(lf, symidx, 1, &addr);
+ if (error != 0)
return (-1);
value += addr;
if (RELOC_BARE_SYMBOL(rtype))
diff --git a/sys/sys/linker.h b/sys/sys/linker.h
index b2942f2..ce4d86e 100644
--- a/sys/sys/linker.h
+++ b/sys/sys/linker.h
@@ -259,7 +259,7 @@ extern int kld_debug;
#endif
-typedef Elf_Addr elf_lookup_fn(linker_file_t, Elf_Size, int);
+typedef int elf_lookup_fn(linker_file_t, Elf_Size, int, Elf_Addr *);
/* Support functions */
int elf_reloc(linker_file_t _lf, Elf_Addr base, const void *_rel, int _type, elf_lookup_fn _lu);
OpenPOWER on IntegriCloud