aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Wemm <peter@FreeBSD.org>2004-05-16 20:00:28 +0000
committerPeter Wemm <peter@FreeBSD.org>2004-05-16 20:00:28 +0000
commite8855d4f975f9d1b62f28eb2dbe90a8e4ce67038 (patch)
tree9c824fecb4de303fa016d7216c651ec04ecaec13
parent1a292b80154d3df2676821b8ce96fa6261061025 (diff)
downloadsrc-e8855d4f975f9d1b62f28eb2dbe90a8e4ce67038.tar.gz
src-e8855d4f975f9d1b62f28eb2dbe90a8e4ce67038.zip
Make a small revision to the api between the elf linker core and the
elf_reloc() backends for two reasons. First, to support the possibility of there being two elf linkers in the kernel (eg: amd64), and second, to pass the relocbase explicitly (for relocating .o format kld files).
Notes
Notes: svn path=/head/; revision=129282
-rw-r--r--sys/alpha/alpha/elf_machdep.c20
-rw-r--r--sys/amd64/amd64/elf_machdep.c61
-rw-r--r--sys/arm/arm/elf_machdep.c18
-rw-r--r--sys/i386/i386/elf_machdep.c20
-rw-r--r--sys/ia64/ia64/elf_machdep.c23
-rw-r--r--sys/kern/link_elf.c21
-rw-r--r--sys/powerpc/powerpc/elf_machdep.c18
-rw-r--r--sys/sparc64/sparc64/elf_machdep.c9
-rw-r--r--sys/sys/linker.h7
9 files changed, 113 insertions, 84 deletions
diff --git a/sys/alpha/alpha/elf_machdep.c b/sys/alpha/alpha/elf_machdep.c
index 794328c05b87..25c3ac7fab72 100644
--- a/sys/alpha/alpha/elf_machdep.c
+++ b/sys/alpha/alpha/elf_machdep.c
@@ -108,9 +108,9 @@ SYSINIT(oelf64, SI_SUB_EXEC, SI_ORDER_ANY,
/* Process one elf relocation with addend. */
static int
-elf_reloc_internal(linker_file_t lf, const void *data, int type, int local)
+elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
+ int type, int local, elf_lookup_fn lookup)
{
- Elf_Addr relocbase = (Elf_Addr) lf->address;
Elf_Addr *where;
Elf_Addr addr;
Elf_Addr addend;
@@ -152,7 +152,7 @@ elf_reloc_internal(linker_file_t lf, const void *data, int type, int local)
break;
case R_ALPHA_REFQUAD:
- addr = elf_lookup(lf, symidx, 1);
+ addr = lookup(lf, symidx, 1);
if (addr == 0)
return -1;
addr += addend;
@@ -161,7 +161,7 @@ elf_reloc_internal(linker_file_t lf, const void *data, int type, int local)
break;
case R_ALPHA_GLOB_DAT:
- addr = elf_lookup(lf, symidx, 1);
+ addr = lookup(lf, symidx, 1);
if (addr == 0)
return -1;
addr += addend;
@@ -171,7 +171,7 @@ elf_reloc_internal(linker_file_t lf, const void *data, int type, int local)
case R_ALPHA_JMP_SLOT:
/* No point in lazy binding for kernel modules. */
- addr = elf_lookup(lf, symidx, 1);
+ addr = lookup(lf, symidx, 1);
if (addr == 0)
return -1;
if (*where != addr)
@@ -198,17 +198,19 @@ elf_reloc_internal(linker_file_t lf, const void *data, int type, int local)
}
int
-elf_reloc(linker_file_t lf, const void *data, int type)
+elf_reloc(linker_file_t lf, Elf_Addr relocbase, const void *data, int type,
+ elf_lookup_fn lookup)
{
- return (elf_reloc_internal(lf, data, type, 0));
+ return (elf_reloc_internal(lf, relocbase, data, type, 0, lookup));
}
int
-elf_reloc_local(linker_file_t lf, const void *data, int type)
+elf_reloc_local(linker_file_t lf, Elf_Addr relocbase, const void *data,
+ int type, elf_lookup_fn lookup)
{
- return (elf_reloc_internal(lf, data, type, 1));
+ return (elf_reloc_internal(lf, relocbase, data, type, 1, lookup));
}
int
diff --git a/sys/amd64/amd64/elf_machdep.c b/sys/amd64/amd64/elf_machdep.c
index 04d81aacd1db..32325125e2fa 100644
--- a/sys/amd64/amd64/elf_machdep.c
+++ b/sys/amd64/amd64/elf_machdep.c
@@ -104,10 +104,11 @@ SYSINIT(oelf64, SI_SUB_EXEC, SI_ORDER_ANY,
/* Process one elf relocation with addend. */
static int
-elf_reloc_internal(linker_file_t lf, const void *data, int type, int local)
+elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
+ int type, int local, elf_lookup_fn lookup)
{
- Elf_Addr relocbase = (Elf_Addr) lf->address;
- Elf_Addr *where;
+ Elf64_Addr *where, val;
+ Elf32_Addr *where32, val32;
Elf_Addr addr;
Elf_Addr addend;
Elf_Word rtype, symidx;
@@ -133,37 +134,39 @@ elf_reloc_internal(linker_file_t lf, const void *data, int type, int local)
panic("unknown reloc type %d\n", type);
}
- if (local) {
- if (rtype == R_X86_64_RELATIVE) { /* A + B */
- addr = relocbase + addend;
- if (*where != addr)
- *where = addr;
- }
- return (0);
- }
-
switch (rtype) {
+
case R_X86_64_NONE: /* none */
break;
case R_X86_64_64: /* S + A */
- addr = elf_lookup(lf, symidx, 1);
+ addr = lookup(lf, symidx, 1);
+ val = addr + addend;
if (addr == 0)
return -1;
- addr += addend;
- if (*where != addr)
- *where = addr;
+ if (*where != val)
+ *where = val;
break;
case R_X86_64_PC32: /* S + A - P */
- addr = elf_lookup(lf, symidx, 1);
+ addr = lookup(lf, symidx, 1);
+ where32 = (Elf32_Addr *)where;
+ val32 = (Elf32_Addr)(addr + addend - (Elf_Addr)where);
if (addr == 0)
return -1;
- addr += addend - (Elf_Addr)where;
- /* XXX needs to be 32 bit *where, not 64 bit */
- if (*where != addr)
- *where = addr;
+ if (*where32 != val32)
+ *where32 = val32;
+ break;
+
+ case R_X86_64_32S: /* S + A sign extend */
+ addr = lookup(lf, symidx, 1);
+ val32 = (Elf32_Addr)(addr + addend);
+ where32 = (Elf32_Addr *)where;
+ if (addr == 0)
+ return -1;
+ if (*where32 != val32)
+ *where32 = val32;
break;
case R_X86_64_COPY: /* none */
@@ -176,7 +179,7 @@ elf_reloc_internal(linker_file_t lf, const void *data, int type, int local)
break;
case R_X86_64_GLOB_DAT: /* S */
- addr = elf_lookup(lf, symidx, 1);
+ addr = lookup(lf, symidx, 1);
if (addr == 0)
return -1;
if (*where != addr)
@@ -184,6 +187,10 @@ elf_reloc_internal(linker_file_t lf, const void *data, int type, int local)
break;
case R_X86_64_RELATIVE: /* B + A */
+ addr = relocbase + addend;
+ val = addr;
+ if (*where != val)
+ *where = val;
break;
default:
@@ -195,17 +202,19 @@ elf_reloc_internal(linker_file_t lf, const void *data, int type, int local)
}
int
-elf_reloc(linker_file_t lf, const void *data, int type)
+elf_reloc(linker_file_t lf, Elf_Addr relocbase, const void *data, int type,
+ elf_lookup_fn lookup)
{
- return (elf_reloc_internal(lf, data, type, 0));
+ return (elf_reloc_internal(lf, relocbase, data, type, 0, lookup));
}
int
-elf_reloc_local(linker_file_t lf, const void *data, int type)
+elf_reloc_local(linker_file_t lf, Elf_Addr relocbase, const void *data,
+ int type, elf_lookup_fn lookup)
{
- return (elf_reloc_internal(lf, data, type, 1));
+ return (elf_reloc_internal(lf, relocbase, data, type, 1, lookup));
}
int
diff --git a/sys/arm/arm/elf_machdep.c b/sys/arm/arm/elf_machdep.c
index 373e93774ee2..303832b15de7 100644
--- a/sys/arm/arm/elf_machdep.c
+++ b/sys/arm/arm/elf_machdep.c
@@ -104,9 +104,9 @@ SYSINIT(oelf32, SI_SUB_EXEC, SI_ORDER_ANY,
/* Process one elf relocation with addend. */
static int
-elf_reloc_internal(linker_file_t lf, const void *data, int type, int local)
+elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
+ int type, int local, elf_lookup_fn lookup)
{
- Elf_Addr relocbase = (Elf_Addr) lf->address;
Elf_Addr *where;
Elf_Addr addr;
Elf_Addr addend;
@@ -148,7 +148,7 @@ elf_reloc_internal(linker_file_t lf, const void *data, int type, int local)
break;
case R_ARM_PC24: /* S + A - P */
- addr = elf_lookup(lf, symidx, 1);
+ addr = lookup(lf, symidx, 1);
if (addr == 0)
return -1;
addr += addend - (Elf_Addr)where;
@@ -166,7 +166,7 @@ elf_reloc_internal(linker_file_t lf, const void *data, int type, int local)
break;
case R_ARM_GLOB_DAT: /* S */
- addr = elf_lookup(lf, symidx, 1);
+ addr = lookup(lf, symidx, 1);
if (addr == 0)
return -1;
if (*where != addr)
@@ -185,17 +185,19 @@ elf_reloc_internal(linker_file_t lf, const void *data, int type, int local)
}
int
-elf_reloc(linker_file_t lf, const void *data, int type)
+elf_reloc(linker_file_t lf, Elf_Addr relocbase, const void *data, int type,
+ elf_lookup_fn lookup)
{
- return (elf_reloc_internal(lf, data, type, 0));
+ return (elf_reloc_internal(lf, relocbase, data, type, 0, lookup));
}
int
-elf_reloc_local(linker_file_t lf, const void *data, int type)
+elf_reloc_local(linker_file_t lf, Elf_Addr relocbase, const void *data,
+ int type, elf_lookup_fn lookup)
{
- return (elf_reloc_internal(lf, data, type, 1));
+ return (elf_reloc_internal(lf, relocbase, data, type, 1, lookup));
}
int
diff --git a/sys/i386/i386/elf_machdep.c b/sys/i386/i386/elf_machdep.c
index 8bed56a350aa..c6b1ce6d635e 100644
--- a/sys/i386/i386/elf_machdep.c
+++ b/sys/i386/i386/elf_machdep.c
@@ -104,9 +104,9 @@ SYSINIT(oelf32, SI_SUB_EXEC, SI_ORDER_ANY,
/* Process one elf relocation with addend. */
static int
-elf_reloc_internal(linker_file_t lf, const void *data, int type, int local)
+elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
+ int type, int local, elf_lookup_fn lookup)
{
- Elf_Addr relocbase = (Elf_Addr) lf->address;
Elf_Addr *where;
Elf_Addr addr;
Elf_Addr addend;
@@ -148,7 +148,7 @@ elf_reloc_internal(linker_file_t lf, const void *data, int type, int local)
break;
case R_386_32: /* S + A */
- addr = elf_lookup(lf, symidx, 1);
+ addr = lookup(lf, symidx, 1);
if (addr == 0)
return -1;
addr += addend;
@@ -157,7 +157,7 @@ elf_reloc_internal(linker_file_t lf, const void *data, int type, int local)
break;
case R_386_PC32: /* S + A - P */
- addr = elf_lookup(lf, symidx, 1);
+ addr = lookup(lf, symidx, 1);
if (addr == 0)
return -1;
addr += addend - (Elf_Addr)where;
@@ -175,7 +175,7 @@ elf_reloc_internal(linker_file_t lf, const void *data, int type, int local)
break;
case R_386_GLOB_DAT: /* S */
- addr = elf_lookup(lf, symidx, 1);
+ addr = lookup(lf, symidx, 1);
if (addr == 0)
return -1;
if (*where != addr)
@@ -194,17 +194,19 @@ elf_reloc_internal(linker_file_t lf, const void *data, int type, int local)
}
int
-elf_reloc(linker_file_t lf, const void *data, int type)
+elf_reloc(linker_file_t lf, Elf_Addr relocbase, const void *data, int type,
+ elf_lookup_fn lookup)
{
- return (elf_reloc_internal(lf, data, type, 0));
+ return (elf_reloc_internal(lf, relocbase, data, type, 0, lookup));
}
int
-elf_reloc_local(linker_file_t lf, const void *data, int type)
+elf_reloc_local(linker_file_t lf, Elf_Addr relocbase, const void *data,
+ int type, elf_lookup_fn lookup)
{
- return (elf_reloc_internal(lf, data, type, 1));
+ return (elf_reloc_internal(lf, relocbase, data, type, 1, lookup));
}
int
diff --git a/sys/ia64/ia64/elf_machdep.c b/sys/ia64/ia64/elf_machdep.c
index 1c7f1d21df66..b40c21e125e6 100644
--- a/sys/ia64/ia64/elf_machdep.c
+++ b/sys/ia64/ia64/elf_machdep.c
@@ -143,7 +143,7 @@ ia64_coredump(struct thread *td, struct vnode *vp, off_t limit)
}
static Elf_Addr
-lookup_fdesc(linker_file_t lf, Elf_Word symidx)
+lookup_fdesc(linker_file_t lf, Elf_Word symidx, elf_lookup_fn lookup)
{
linker_file_t top;
Elf_Addr addr;
@@ -151,7 +151,7 @@ lookup_fdesc(linker_file_t lf, Elf_Word symidx)
int i;
static int eot = 0;
- addr = elf_lookup(lf, symidx, 0);
+ addr = lookup(lf, symidx, 0);
if (addr == 0) {
top = lf;
symname = elf_get_symname(top, symidx);
@@ -191,7 +191,8 @@ lookup_fdesc(linker_file_t lf, Elf_Word symidx)
/* Process one elf relocation with addend. */
static int
-elf_reloc_internal(linker_file_t lf, const void *data, int type, int local)
+elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
+ int type, int local, elf_lookup_fn lookup)
{
Elf_Addr relocbase = (Elf_Addr)lf->address;
Elf_Addr *where;
@@ -238,7 +239,7 @@ elf_reloc_internal(linker_file_t lf, const void *data, int type, int local)
case R_IA64_NONE:
break;
case R_IA64_DIR64LSB: /* word64 LSB S + A */
- addr = elf_lookup(lf, symidx, 1);
+ addr = lookup(lf, symidx, 1);
if (addr == 0)
return (-1);
*where = addr + addend;
@@ -248,7 +249,7 @@ elf_reloc_internal(linker_file_t lf, const void *data, int type, int local)
printf("%s: addend ignored for OPD relocation\n",
__func__);
}
- addr = lookup_fdesc(lf, symidx);
+ addr = lookup_fdesc(lf, symidx, lookup);
if (addr == 0)
return (-1);
*where = addr;
@@ -256,7 +257,7 @@ elf_reloc_internal(linker_file_t lf, const void *data, int type, int local)
case R_IA64_REL64LSB: /* word64 LSB BD + A */
break;
case R_IA64_IPLTLSB:
- addr = lookup_fdesc(lf, symidx);
+ addr = lookup_fdesc(lf, symidx, lookup);
if (addr == 0)
return (-1);
where[0] = *((Elf_Addr*)addr) + addend;
@@ -272,17 +273,19 @@ elf_reloc_internal(linker_file_t lf, const void *data, int type, int local)
}
int
-elf_reloc(linker_file_t lf, const void *data, int type)
+elf_reloc(linker_file_t lf, Elf_Addr relocbase, const void *data, int type,
+ elf_lookup_fn lookup)
{
- return (elf_reloc_internal(lf, data, type, 0));
+ return (elf_reloc_internal(lf, relocbase, data, type, 0, lookup));
}
int
-elf_reloc_local(linker_file_t lf, const void *data, int type)
+elf_reloc_local(linker_file_t lf, Elf_Addr relocbase, const void *data,
+ int type, elf_lookup_fn lookup)
{
- return (elf_reloc_internal(lf, data, type, 1));
+ return (elf_reloc_internal(lf, relocbase, data, type, 1, lookup));
}
int
diff --git a/sys/kern/link_elf.c b/sys/kern/link_elf.c
index f05cab162b1f..a7b7a02d88dc 100644
--- a/sys/kern/link_elf.c
+++ b/sys/kern/link_elf.c
@@ -118,6 +118,7 @@ static int link_elf_each_function_name(linker_file_t,
int (*)(const char *, void *),
void *);
static void link_elf_reloc_local(linker_file_t);
+static Elf_Addr elf_lookup(linker_file_t lf, Elf_Word symidx, int deps);
static kobj_method_t link_elf_methods[] = {
KOBJMETHOD(linker_lookup_symbol, link_elf_lookup_symbol),
@@ -928,7 +929,8 @@ relocate_file(elf_file_t ef)
if (rel) {
rellim = (const Elf_Rel *)((const char *)ef->rel + ef->relsize);
while (rel < rellim) {
- if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL)) {
+ if (elf_reloc(&ef->lf, (Elf_Addr)ef->address, rel, ELF_RELOC_REL,
+ elf_lookup)) {
symname = symbol_name(ef, rel->r_info);
printf("link_elf: symbol %s undefined\n", symname);
return ENOENT;
@@ -942,7 +944,8 @@ relocate_file(elf_file_t ef)
if (rela) {
relalim = (const Elf_Rela *)((const char *)ef->rela + ef->relasize);
while (rela < relalim) {
- if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA)) {
+ if (elf_reloc(&ef->lf, (Elf_Addr)ef->address, rela, ELF_RELOC_RELA,
+ elf_lookup)) {
symname = symbol_name(ef, rela->r_info);
printf("link_elf: symbol %s undefined\n", symname);
return ENOENT;
@@ -956,7 +959,8 @@ relocate_file(elf_file_t ef)
if (rel) {
rellim = (const Elf_Rel *)((const char *)ef->pltrel + ef->pltrelsize);
while (rel < rellim) {
- if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL)) {
+ if (elf_reloc(&ef->lf, (Elf_Addr)ef->address, rel, ELF_RELOC_REL,
+ elf_lookup)) {
symname = symbol_name(ef, rel->r_info);
printf("link_elf: symbol %s undefined\n", symname);
return ENOENT;
@@ -970,7 +974,8 @@ relocate_file(elf_file_t ef)
if (rela) {
relalim = (const Elf_Rela *)((const char *)ef->pltrela + ef->pltrelasize);
while (rela < relalim) {
- if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA)) {
+ if (elf_reloc(&ef->lf, (Elf_Addr)ef->address, rela, ELF_RELOC_RELA,
+ elf_lookup)) {
symname = symbol_name(ef, rela->r_info);
printf("link_elf: symbol %s undefined\n", symname);
return ENOENT;
@@ -1244,7 +1249,7 @@ elf_get_symname(linker_file_t lf, Elf_Word 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.
*/
-Elf_Addr
+static Elf_Addr
elf_lookup(linker_file_t lf, Elf_Word symidx, int deps)
{
elf_file_t ef = (elf_file_t)lf;
@@ -1297,7 +1302,8 @@ link_elf_reloc_local(linker_file_t lf)
if ((rel = ef->rel) != NULL) {
rellim = (const Elf_Rel *)((const char *)ef->rel + ef->relsize);
while (rel < rellim) {
- elf_reloc_local(lf, rel, ELF_RELOC_REL);
+ elf_reloc_local(lf, (Elf_Addr)ef->address, rel, ELF_RELOC_REL,
+ elf_lookup);
rel++;
}
}
@@ -1306,7 +1312,8 @@ link_elf_reloc_local(linker_file_t lf)
if ((rela = ef->rela) != NULL) {
relalim = (const Elf_Rela *)((const char *)ef->rela + ef->relasize);
while (rela < relalim) {
- elf_reloc_local(lf, rela, ELF_RELOC_RELA);
+ elf_reloc_local(lf, (Elf_Addr)ef->address, rela, ELF_RELOC_RELA,
+ elf_lookup);
rela++;
}
}
diff --git a/sys/powerpc/powerpc/elf_machdep.c b/sys/powerpc/powerpc/elf_machdep.c
index 1a4486fadcf1..21c9ca3e96aa 100644
--- a/sys/powerpc/powerpc/elf_machdep.c
+++ b/sys/powerpc/powerpc/elf_machdep.c
@@ -106,9 +106,9 @@ SYSINIT(oelf32, SI_SUB_EXEC, SI_ORDER_ANY,
/* Process one elf relocation with addend. */
static int
-elf_reloc_internal(linker_file_t lf, const void *data, int type, int local)
+elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
+ int type, int local, elf_lookup_fn lookup)
{
- Elf_Addr relocbase = (Elf_Addr) lf->address;
Elf_Addr *where;
Elf_Addr addr;
Elf_Addr addend;
@@ -141,7 +141,7 @@ elf_reloc_internal(linker_file_t lf, const void *data, int type, int local)
break;
case R_PPC_GLOB_DAT:
- addr = elf_lookup(lf, symidx, 1);
+ addr = lookup(lf, symidx, 1);
if (addr == 0)
return -1;
addr += addend;
@@ -151,7 +151,7 @@ elf_reloc_internal(linker_file_t lf, const void *data, int type, int local)
case R_PPC_JMP_SLOT:
/* No point in lazy binding for kernel modules. */
- addr = elf_lookup(lf, symidx, 1);
+ addr = lookup(lf, symidx, 1);
if (addr == 0)
return -1;
if (*where != addr)
@@ -181,17 +181,19 @@ elf_reloc_internal(linker_file_t lf, const void *data, int type, int local)
}
int
-elf_reloc(linker_file_t lf, const void *data, int type)
+elf_reloc(linker_file_t lf, Elf_Addr relocbase, const void *data, int type,
+ elf_lookup_fn lookup)
{
- return (elf_reloc_internal(lf, data, type, 0));
+ return (elf_reloc_internal(lf, relocbase, data, type, 0, lookup));
}
int
-elf_reloc_local(linker_file_t lf, const void *data, int type)
+elf_reloc_local(linker_file_t lf, Elf_Addr relocbase, const void *data,
+ int type, elf_lookup_fn lookup)
{
- return (elf_reloc_internal(lf, data, type, 1));
+ return (elf_reloc_internal(lf, relocbase, data, type, 1, lookup));
}
int
diff --git a/sys/sparc64/sparc64/elf_machdep.c b/sys/sparc64/sparc64/elf_machdep.c
index d9d2974d02a5..a20442ae21c1 100644
--- a/sys/sparc64/sparc64/elf_machdep.c
+++ b/sys/sparc64/sparc64/elf_machdep.c
@@ -252,7 +252,8 @@ static long reloc_target_bitmask[] = {
#define RELOC_VALUE_BITMASK(t) (reloc_target_bitmask[t])
int
-elf_reloc_local(linker_file_t lf, const void *data, int type)
+elf_reloc_local(linker_file_t lf, Elf_Addr relocbase, const void *data,
+ int type, elf_lookup_fn lookup)
{
const Elf_Rela *rela;
Elf_Addr value;
@@ -275,7 +276,8 @@ elf_reloc_local(linker_file_t lf, const void *data, int type)
/* Process one elf relocation with addend. */
int
-elf_reloc(linker_file_t lf, const void *data, int type)
+elf_reloc(linker_file_t lf, Elf_Addr relocbase, const void *data, int type,
+ elf_lookup_fn lookup)
{
const Elf_Rela *rela;
Elf_Addr relocbase;
@@ -289,7 +291,6 @@ elf_reloc(linker_file_t lf, const void *data, int type)
if (type != ELF_RELOC_RELA)
return (-1);
- relocbase = (Elf_Addr)lf->address;
rela = (const Elf_Rela *)data;
where = (Elf_Addr *)(relocbase + rela->r_offset);
where32 = (Elf_Half *)where;
@@ -309,7 +310,7 @@ elf_reloc(linker_file_t lf, const void *data, int type)
value = rela->r_addend;
if (RELOC_RESOLVE_SYMBOL(rtype)) {
- addr = elf_lookup(lf, symidx, 1);
+ addr = lookup(lf, symidx, 1);
if (addr == 0)
return (-1);
value += addr;
diff --git a/sys/sys/linker.h b/sys/sys/linker.h
index 3ea5718c57e6..1815c47a607f 100644
--- a/sys/sys/linker.h
+++ b/sys/sys/linker.h
@@ -241,10 +241,11 @@ extern int kld_debug;
#endif
+typedef Elf_Addr elf_lookup_fn(linker_file_t, Elf_Word, int);
+
/* Support functions */
-int elf_reloc(linker_file_t _lf, const void *_rel, int _type);
-int elf_reloc_local(linker_file_t _lf, const void *_rel, int _type);
-Elf_Addr elf_lookup(linker_file_t, Elf_Word, int);
+int elf_reloc(linker_file_t _lf, Elf_Addr base, const void *_rel, int _type, elf_lookup_fn _lu);
+int elf_reloc_local(linker_file_t _lf, Elf_Addr base, const void *_rel, int _type, elf_lookup_fn _lu);
const Elf_Sym *elf_get_sym(linker_file_t _lf, Elf_Word _symidx);
const char *elf_get_symname(linker_file_t _lf, Elf_Word _symidx);