summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/alpha/alpha/elf_machdep.c21
-rw-r--r--sys/amd64/amd64/elf_machdep.c18
-rw-r--r--sys/i386/i386/elf_machdep.c18
-rw-r--r--sys/ia64/ia64/elf_machdep.c43
-rw-r--r--sys/kern/link_elf.c63
-rw-r--r--sys/kern/link_elf_obj.c63
-rw-r--r--sys/powerpc/powerpc/elf_machdep.c16
-rw-r--r--sys/sparc64/sparc64/elf_machdep.c7
-rw-r--r--sys/sys/linker.h5
9 files changed, 168 insertions, 86 deletions
diff --git a/sys/alpha/alpha/elf_machdep.c b/sys/alpha/alpha/elf_machdep.c
index cdb27c50955a..ebd3b60d204c 100644
--- a/sys/alpha/alpha/elf_machdep.c
+++ b/sys/alpha/alpha/elf_machdep.c
@@ -38,13 +38,13 @@
/* Process one elf relocation with addend. */
int
-elf_reloc(linker_file_t lf, const void *data, int type, const char *sym)
+elf_reloc(linker_file_t lf, const void *data, int type)
{
Elf_Addr relocbase = (Elf_Addr) lf->address;
Elf_Addr *where;
Elf_Addr addr;
Elf_Addr addend;
- Elf_Word rtype;
+ Elf_Word rtype, symidx;
const Elf_Rel *rel;
const Elf_Rela *rela;
@@ -54,12 +54,14 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *sym)
where = (Elf_Addr *) (relocbase + rel->r_offset);
addend = *where;
rtype = ELF_R_TYPE(rel->r_info);
+ symidx = ELF_R_SYM(rel->r_info);
break;
case ELF_RELOC_RELA:
rela = (const Elf_Rela *)data;
where = (Elf_Addr *) (relocbase + rela->r_offset);
addend = rela->r_addend;
rtype = ELF_R_TYPE(rela->r_info);
+ symidx = ELF_R_SYM(rela->r_info);
break;
default:
panic("elf_reloc: unknown relocation mode %d\n", type);
@@ -71,9 +73,8 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *sym)
break;
case R_ALPHA_REFQUAD:
- addr = (Elf_Addr)
- linker_file_lookup_symbol(lf, sym, 1);
- if (addr == NULL)
+ addr = elf_lookup(lf, symidx, 1);
+ if (addr == 0)
return -1;
addr += addend;
if (*where != addr)
@@ -81,9 +82,8 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *sym)
break;
case R_ALPHA_GLOB_DAT:
- addr = (Elf_Addr)
- linker_file_lookup_symbol(lf, sym, 1);
- if (addr == NULL)
+ addr = elf_lookup(lf, symidx, 1);
+ if (addr == 0)
return -1;
addr += addend;
if (*where != addr)
@@ -92,9 +92,8 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *sym)
case R_ALPHA_JMP_SLOT:
/* No point in lazy binding for kernel modules. */
- addr = (Elf_Addr)
- linker_file_lookup_symbol(lf, sym, 1);
- if (addr == NULL)
+ addr = elf_lookup(lf, symidx, 1);
+ if (addr == 0)
return -1;
if (*where != addr)
*where = addr;
diff --git a/sys/amd64/amd64/elf_machdep.c b/sys/amd64/amd64/elf_machdep.c
index 577aeac1c45c..96d91b00c04d 100644
--- a/sys/amd64/amd64/elf_machdep.c
+++ b/sys/amd64/amd64/elf_machdep.c
@@ -32,13 +32,13 @@
/* Process one elf relocation with addend. */
int
-elf_reloc(linker_file_t lf, const void *data, int type, const char *sym)
+elf_reloc(linker_file_t lf, const void *data, int type)
{
Elf_Addr relocbase = (Elf_Addr) lf->address;
Elf_Addr *where;
Elf_Addr addr;
Elf_Addr addend;
- Elf_Word rtype;
+ Elf_Word rtype, symidx;
const Elf_Rel *rel;
const Elf_Rela *rela;
@@ -48,12 +48,14 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *sym)
where = (Elf_Addr *) (relocbase + rel->r_offset);
addend = *where;
rtype = ELF_R_TYPE(rel->r_info);
+ symidx = ELF_R_SYM(rel->r_info);
break;
case ELF_RELOC_RELA:
rela = (const Elf_Rela *)data;
where = (Elf_Addr *) (relocbase + rela->r_offset);
addend = rela->r_addend;
rtype = ELF_R_TYPE(rela->r_info);
+ symidx = ELF_R_SYM(rela->r_info);
break;
default:
panic("unknown reloc type %d\n", type);
@@ -65,9 +67,7 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *sym)
break;
case R_386_32: /* S + A */
- if (sym == NULL)
- return -1;
- addr = (Elf_Addr)linker_file_lookup_symbol(lf, sym, 1);
+ addr = elf_lookup(lf, symidx, 1);
if (addr == 0)
return -1;
addr += addend;
@@ -76,9 +76,7 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *sym)
break;
case R_386_PC32: /* S + A - P */
- if (sym == NULL)
- return -1;
- addr = (Elf_Addr)linker_file_lookup_symbol(lf, sym, 1);
+ addr = elf_lookup(lf, symidx, 1);
if (addr == 0)
return -1;
addr += addend - (Elf_Addr)where;
@@ -96,9 +94,7 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *sym)
break;
case R_386_GLOB_DAT: /* S */
- if (sym == NULL)
- return -1;
- addr = (Elf_Addr)linker_file_lookup_symbol(lf, sym, 1);
+ addr = elf_lookup(lf, symidx, 1);
if (addr == 0)
return -1;
if (*where != addr)
diff --git a/sys/i386/i386/elf_machdep.c b/sys/i386/i386/elf_machdep.c
index 577aeac1c45c..96d91b00c04d 100644
--- a/sys/i386/i386/elf_machdep.c
+++ b/sys/i386/i386/elf_machdep.c
@@ -32,13 +32,13 @@
/* Process one elf relocation with addend. */
int
-elf_reloc(linker_file_t lf, const void *data, int type, const char *sym)
+elf_reloc(linker_file_t lf, const void *data, int type)
{
Elf_Addr relocbase = (Elf_Addr) lf->address;
Elf_Addr *where;
Elf_Addr addr;
Elf_Addr addend;
- Elf_Word rtype;
+ Elf_Word rtype, symidx;
const Elf_Rel *rel;
const Elf_Rela *rela;
@@ -48,12 +48,14 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *sym)
where = (Elf_Addr *) (relocbase + rel->r_offset);
addend = *where;
rtype = ELF_R_TYPE(rel->r_info);
+ symidx = ELF_R_SYM(rel->r_info);
break;
case ELF_RELOC_RELA:
rela = (const Elf_Rela *)data;
where = (Elf_Addr *) (relocbase + rela->r_offset);
addend = rela->r_addend;
rtype = ELF_R_TYPE(rela->r_info);
+ symidx = ELF_R_SYM(rela->r_info);
break;
default:
panic("unknown reloc type %d\n", type);
@@ -65,9 +67,7 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *sym)
break;
case R_386_32: /* S + A */
- if (sym == NULL)
- return -1;
- addr = (Elf_Addr)linker_file_lookup_symbol(lf, sym, 1);
+ addr = elf_lookup(lf, symidx, 1);
if (addr == 0)
return -1;
addr += addend;
@@ -76,9 +76,7 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *sym)
break;
case R_386_PC32: /* S + A - P */
- if (sym == NULL)
- return -1;
- addr = (Elf_Addr)linker_file_lookup_symbol(lf, sym, 1);
+ addr = elf_lookup(lf, symidx, 1);
if (addr == 0)
return -1;
addr += addend - (Elf_Addr)where;
@@ -96,9 +94,7 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *sym)
break;
case R_386_GLOB_DAT: /* S */
- if (sym == NULL)
- return -1;
- addr = (Elf_Addr)linker_file_lookup_symbol(lf, sym, 1);
+ addr = elf_lookup(lf, symidx, 1);
if (addr == 0)
return -1;
if (*where != addr)
diff --git a/sys/ia64/ia64/elf_machdep.c b/sys/ia64/ia64/elf_machdep.c
index 9ecfe71f1711..dcee3a454739 100644
--- a/sys/ia64/ia64/elf_machdep.c
+++ b/sys/ia64/ia64/elf_machdep.c
@@ -41,24 +41,24 @@ Elf_Addr link_elf_get_gp(linker_file_t);
extern Elf_Addr fptr_storage[];
static Elf_Addr
-lookup_fdesc(linker_file_t lf, const char *sym)
+lookup_fdesc(linker_file_t lf, Elf_Word symidx)
{
Elf_Addr addr;
int i;
static int eot = 0;
- addr = (Elf_Addr)linker_file_lookup_symbol(lf, sym, 0);
- if (addr == NULL) {
+ addr = elf_lookup(lf, symidx, 0);
+ if (addr == 0) {
for (i = 0; i < lf->ndeps; i++) {
- addr = lookup_fdesc(lf->deps[i], sym);
- if (addr != NULL)
+ addr = lookup_fdesc(lf->deps[i], symidx);
+ if (addr != 0)
return (addr);
}
- return (NULL);
+ return (0);
}
if (eot)
- return (NULL);
+ return (0);
/*
* Lookup and/or construct OPD
@@ -77,17 +77,17 @@ lookup_fdesc(linker_file_t lf, const char *sym)
printf("%s: fptr table full\n", __func__);
eot = 1;
- return (NULL);
+ return (0);
}
/* Process one elf relocation with addend. */
int
-elf_reloc(linker_file_t lf, const void *data, int type, const char *sym)
+elf_reloc(linker_file_t lf, const void *data, int type)
{
Elf_Addr relocbase = (Elf_Addr)lf->address;
Elf_Addr *where;
Elf_Addr addend, addr;
- Elf_Word rtype;
+ Elf_Word rtype, symidx;
const Elf_Rel *rel;
const Elf_Rela *rela;
@@ -96,6 +96,7 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *sym)
rel = (const Elf_Rel *)data;
where = (Elf_Addr *)(relocbase + rel->r_offset);
rtype = ELF_R_TYPE(rel->r_info);
+ symidx = ELF_R_SYM(rel->r_info);
switch (rtype) {
case R_IA64_DIR64LSB:
case R_IA64_FPTR64LSB:
@@ -111,6 +112,7 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *sym)
rela = (const Elf_Rela *)data;
where = (Elf_Addr *)(relocbase + rela->r_offset);
rtype = ELF_R_TYPE(rela->r_info);
+ symidx = ELF_R_SYM(rela->r_info);
addend = rela->r_addend;
break;
default:
@@ -121,35 +123,28 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *sym)
case R_IA64_NONE:
break;
case R_IA64_DIR64LSB: /* word64 LSB S + A */
- if (sym == NULL)
- return -1;
- addr = (Elf_Addr)linker_file_lookup_symbol(lf, sym, 1);
+ addr = elf_lookup(lf, symidx, 1);
if (addr == 0)
- return -1;
+ return (-1);
*where = addr + addend;
break;
case R_IA64_FPTR64LSB: /* word64 LSB @fptr(S + A) */
- if (sym == NULL)
- return -1;
if (addend != 0) {
printf("%s: addend ignored for OPD relocation\n",
__func__);
}
- addr = lookup_fdesc(lf, sym);
+ addr = lookup_fdesc(lf, symidx);
if (addr == 0)
- return -1;
+ return (-1);
*where = addr;
break;
case R_IA64_REL64LSB: /* word64 LSB BD + A */
*where = relocbase + addend;
break;
case R_IA64_IPLTLSB:
- if (sym == NULL)
- return -1;
- /* lookup_fdesc() returns the address of the OPD. */
- addr = lookup_fdesc(lf, sym);
+ addr = lookup_fdesc(lf, symidx);
if (addr == 0)
- return -1;
+ return (-1);
where[0] = *((Elf_Addr*)addr) + addend;
where[1] = *((Elf_Addr*)addr + 1);
break;
@@ -159,5 +154,5 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *sym)
return -1;
}
- return(0);
+ return (0);
}
diff --git a/sys/kern/link_elf.c b/sys/kern/link_elf.c
index 8eb7681f95ac..dd594051a998 100644
--- a/sys/kern/link_elf.c
+++ b/sys/kern/link_elf.c
@@ -904,8 +904,8 @@ relocate_file(elf_file_t ef)
if (rel) {
rellim = (const Elf_Rel *)((const char *)ef->rel + ef->relsize);
while (rel < rellim) {
- symname = symbol_name(ef, rel->r_info);
- if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL, symname)) {
+ if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL)) {
+ symname = symbol_name(ef, rel->r_info);
printf("link_elf: symbol %s undefined\n", symname);
return ENOENT;
}
@@ -918,8 +918,8 @@ relocate_file(elf_file_t ef)
if (rela) {
relalim = (const Elf_Rela *)((const char *)ef->rela + ef->relasize);
while (rela < relalim) {
- symname = symbol_name(ef, rela->r_info);
- if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA, symname)) {
+ if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA)) {
+ symname = symbol_name(ef, rela->r_info);
printf("link_elf: symbol %s undefined\n", symname);
return ENOENT;
}
@@ -932,8 +932,8 @@ relocate_file(elf_file_t ef)
if (rel) {
rellim = (const Elf_Rel *)((const char *)ef->pltrel + ef->pltrelsize);
while (rel < rellim) {
- symname = symbol_name(ef, rel->r_info);
- if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL, symname)) {
+ if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL)) {
+ symname = symbol_name(ef, rel->r_info);
printf("link_elf: symbol %s undefined\n", symname);
return ENOENT;
}
@@ -946,8 +946,8 @@ relocate_file(elf_file_t ef)
if (rela) {
relalim = (const Elf_Rela *)((const char *)ef->pltrela + ef->pltrelasize);
while (rela < relalim) {
- symname = symbol_name(ef, rela->r_info);
- if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA, symname)) {
+ if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA)) {
+ symname = symbol_name(ef, rela->r_info);
printf("link_elf: symbol %s undefined\n", symname);
return ENOENT;
}
@@ -1190,3 +1190,50 @@ link_elf_get_gp(linker_file_t lf)
return (Elf_Addr)ef->got;
}
#endif
+
+/*
+ * Symbol lookup function that can be used when the symbol index is known (ie
+ * in relocations). It uses the symbol index instead of doing a fully fledged
+ * hash table based lookup when such is valid. For example for local symbols.
+ * 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
+elf_lookup(linker_file_t lf, Elf_Word symidx, int deps)
+{
+ elf_file_t ef = (elf_file_t)lf;
+ const Elf_Sym *sym;
+ const char *symbol;
+
+ /* Don't even try to lookup the symbol if the index is bogus. */
+ if (symidx >= ef->nchains)
+ return (0);
+
+ sym = ef->symtab + symidx;
+
+ /*
+ * Don't do a full lookup when the symbol is local. It may even
+ * fail because it may not be found through the hash table.
+ */
+ 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);
+ }
+
+ /*
+ * XXX we can avoid doing a hash table based lookup for global
+ * symbols as well. This however is not always valid, so we'll
+ * just do it the hard way for now. Performance tweaks can
+ * always be added.
+ */
+
+ symbol = ef->strtab + sym->st_name;
+
+ /* Force a lookup failure if the symbol name is bogus. */
+ if (*symbol == 0)
+ return (0);
+
+ return ((Elf_Addr)linker_file_lookup_symbol(lf, symbol, deps));
+}
diff --git a/sys/kern/link_elf_obj.c b/sys/kern/link_elf_obj.c
index 8eb7681f95ac..dd594051a998 100644
--- a/sys/kern/link_elf_obj.c
+++ b/sys/kern/link_elf_obj.c
@@ -904,8 +904,8 @@ relocate_file(elf_file_t ef)
if (rel) {
rellim = (const Elf_Rel *)((const char *)ef->rel + ef->relsize);
while (rel < rellim) {
- symname = symbol_name(ef, rel->r_info);
- if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL, symname)) {
+ if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL)) {
+ symname = symbol_name(ef, rel->r_info);
printf("link_elf: symbol %s undefined\n", symname);
return ENOENT;
}
@@ -918,8 +918,8 @@ relocate_file(elf_file_t ef)
if (rela) {
relalim = (const Elf_Rela *)((const char *)ef->rela + ef->relasize);
while (rela < relalim) {
- symname = symbol_name(ef, rela->r_info);
- if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA, symname)) {
+ if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA)) {
+ symname = symbol_name(ef, rela->r_info);
printf("link_elf: symbol %s undefined\n", symname);
return ENOENT;
}
@@ -932,8 +932,8 @@ relocate_file(elf_file_t ef)
if (rel) {
rellim = (const Elf_Rel *)((const char *)ef->pltrel + ef->pltrelsize);
while (rel < rellim) {
- symname = symbol_name(ef, rel->r_info);
- if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL, symname)) {
+ if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL)) {
+ symname = symbol_name(ef, rel->r_info);
printf("link_elf: symbol %s undefined\n", symname);
return ENOENT;
}
@@ -946,8 +946,8 @@ relocate_file(elf_file_t ef)
if (rela) {
relalim = (const Elf_Rela *)((const char *)ef->pltrela + ef->pltrelasize);
while (rela < relalim) {
- symname = symbol_name(ef, rela->r_info);
- if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA, symname)) {
+ if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA)) {
+ symname = symbol_name(ef, rela->r_info);
printf("link_elf: symbol %s undefined\n", symname);
return ENOENT;
}
@@ -1190,3 +1190,50 @@ link_elf_get_gp(linker_file_t lf)
return (Elf_Addr)ef->got;
}
#endif
+
+/*
+ * Symbol lookup function that can be used when the symbol index is known (ie
+ * in relocations). It uses the symbol index instead of doing a fully fledged
+ * hash table based lookup when such is valid. For example for local symbols.
+ * 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
+elf_lookup(linker_file_t lf, Elf_Word symidx, int deps)
+{
+ elf_file_t ef = (elf_file_t)lf;
+ const Elf_Sym *sym;
+ const char *symbol;
+
+ /* Don't even try to lookup the symbol if the index is bogus. */
+ if (symidx >= ef->nchains)
+ return (0);
+
+ sym = ef->symtab + symidx;
+
+ /*
+ * Don't do a full lookup when the symbol is local. It may even
+ * fail because it may not be found through the hash table.
+ */
+ 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);
+ }
+
+ /*
+ * XXX we can avoid doing a hash table based lookup for global
+ * symbols as well. This however is not always valid, so we'll
+ * just do it the hard way for now. Performance tweaks can
+ * always be added.
+ */
+
+ symbol = ef->strtab + sym->st_name;
+
+ /* Force a lookup failure if the symbol name is bogus. */
+ if (*symbol == 0)
+ return (0);
+
+ return ((Elf_Addr)linker_file_lookup_symbol(lf, symbol, deps));
+}
diff --git a/sys/powerpc/powerpc/elf_machdep.c b/sys/powerpc/powerpc/elf_machdep.c
index 44ea9ef4c468..3a39ac6aa614 100644
--- a/sys/powerpc/powerpc/elf_machdep.c
+++ b/sys/powerpc/powerpc/elf_machdep.c
@@ -38,13 +38,13 @@
/* Process one elf relocation with addend. */
int
-elf_reloc(linker_file_t lf, const void *data, int type, const char *sym)
+elf_reloc(linker_file_t lf, const void *data, int type)
{
Elf_Addr relocbase = (Elf_Addr) lf->address;
Elf_Addr *where;
Elf_Addr addr;
Elf_Addr addend;
- Elf_Word rtype;
+ Elf_Word rtype, symidx;
const Elf_Rel *rel;
const Elf_Rela *rela;
@@ -54,12 +54,14 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *sym)
where = (Elf_Addr *) (relocbase + rel->r_offset);
addend = *where;
rtype = ELF_R_TYPE(rel->r_info);
+ symidx = ELF_R_SYM(rel->r_info);
break;
case ELF_RELOC_RELA:
rela = (const Elf_Rela *)data;
where = (Elf_Addr *) (relocbase + rela->r_offset);
addend = rela->r_addend;
rtype = ELF_R_TYPE(rela->r_info);
+ symidx = ELF_R_SYM(rela->r_info);
break;
default:
panic("elf_reloc: unknown relocation mode %d\n", type);
@@ -71,9 +73,8 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *sym)
break;
case R_PPC_GLOB_DAT:
- addr = (Elf_Addr)
- linker_file_lookup_symbol(lf, sym, 1);
- if (addr == NULL)
+ addr = elf_lookup(lf, symidx, 1);
+ if (addr == 0)
return -1;
addr += addend;
if (*where != addr)
@@ -82,9 +83,8 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *sym)
case R_PPC_JMP_SLOT:
/* No point in lazy binding for kernel modules. */
- addr = (Elf_Addr)
- linker_file_lookup_symbol(lf, sym, 1);
- if (addr == NULL)
+ addr = elf_lookup(lf, symidx, 1);
+ if (addr == 0)
return -1;
if (*where != addr)
*where = addr;
diff --git a/sys/sparc64/sparc64/elf_machdep.c b/sys/sparc64/sparc64/elf_machdep.c
index 3e6c79062d9f..592d9fb10155 100644
--- a/sys/sparc64/sparc64/elf_machdep.c
+++ b/sys/sparc64/sparc64/elf_machdep.c
@@ -168,13 +168,13 @@ static long reloc_target_bitmask[] = {
/* Process one elf relocation with addend. */
int
-elf_reloc(linker_file_t lf, const void *data, int type, const char *symname)
+elf_reloc(linker_file_t lf, const void *data, int type)
{
const Elf_Rela *rela;
Elf_Addr relocbase;
Elf_Half *where32;
Elf_Addr *where;
- Elf_Word rtype;
+ Elf_Word rtype, symidx;
Elf_Addr value;
Elf_Addr mask;
caddr_t addr;
@@ -187,6 +187,7 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *symname)
where = (Elf_Addr *)(relocbase + rela->r_offset);
where32 = (Elf_Half *)where;
rtype = ELF_R_TYPE(rela->r_info);
+ symidx = ELF_R_SYM(rela->r_info);
if (rtype == R_SPARC_NONE)
return (0);
@@ -201,7 +202,7 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *symname)
value = rela->r_addend;
if (RELOC_RESOLVE_SYMBOL(rtype)) {
- addr = linker_file_lookup_symbol(lf, symname, 1);
+ addr = elf_lookup(lf, symidx, 1);
if (addr == 0)
return (-1);
value += (Elf_Addr)addr;
diff --git a/sys/sys/linker.h b/sys/sys/linker.h
index f138df7519a8..3b3edca33a0f 100644
--- a/sys/sys/linker.h
+++ b/sys/sys/linker.h
@@ -226,8 +226,9 @@ extern int kld_debug;
#endif
/* Support functions */
-int elf_reloc(linker_file_t _lf, const void *_rel, int _type,
- const char *_sym);
+int elf_reloc(linker_file_t _lf, const void *_rel, int _type);
+Elf_Addr elf_lookup(linker_file_t, Elf_Word, int);
+
/* values for type */
#define ELF_RELOC_REL 1
#define ELF_RELOC_RELA 2