diff options
author | jake <jake@FreeBSD.org> | 2003-01-21 02:42:44 +0000 |
---|---|---|
committer | jake <jake@FreeBSD.org> | 2003-01-21 02:42:44 +0000 |
commit | c1e42cc8bb6beb27c070748587d19f1d63fc956a (patch) | |
tree | a6736a5694dc3395d090d1d257e111c315fd88a0 /sys/ia64 | |
parent | 013247cd19dd036ba508021e0edaba94b2a75960 (diff) | |
download | FreeBSD-src-c1e42cc8bb6beb27c070748587d19f1d63fc956a.zip FreeBSD-src-c1e42cc8bb6beb27c070748587d19f1d63fc956a.tar.gz |
Resolve relative relocations in klds before trying to parse the module's
metadata. This fixes module dependency resolution by the kernel linker on
sparc64, where the relocations for the metadata are different than on other
architectures; the relative offset is in the addend of an Elf_Rela record
instead of the original value of the location being patched.
Also fix printf formats in debug code.
Submitted by: Hartmut Brandt <brandt@fokus.gmd.de>
PR: 46732
Tested on: alpha (obrien), i386, sparc64
Diffstat (limited to 'sys/ia64')
-rw-r--r-- | sys/ia64/ia64/elf_machdep.c | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/sys/ia64/ia64/elf_machdep.c b/sys/ia64/ia64/elf_machdep.c index c4a4938..b3c7d90 100644 --- a/sys/ia64/ia64/elf_machdep.c +++ b/sys/ia64/ia64/elf_machdep.c @@ -141,8 +141,8 @@ lookup_fdesc(linker_file_t lf, Elf_Word symidx) } /* Process one elf relocation with addend. */ -int -elf_reloc(linker_file_t lf, const void *data, int type) +static int +elf_reloc_internal(linker_file_t lf, const void *data, int type, int local) { Elf_Addr relocbase = (Elf_Addr)lf->address; Elf_Addr *where; @@ -179,6 +179,12 @@ elf_reloc(linker_file_t lf, const void *data, int type) panic("%s: invalid ELF relocation (0x%x)\n", __func__, type); } + if (local) { + if (rtype == R_IA64_REL64LSB) + *where = relocbase + addend; + return (0); + } + switch (rtype) { case R_IA64_NONE: break; @@ -199,7 +205,6 @@ elf_reloc(linker_file_t lf, const void *data, int type) *where = addr; break; case R_IA64_REL64LSB: /* word64 LSB BD + A */ - *where = relocbase + addend; break; case R_IA64_IPLTLSB: addr = lookup_fdesc(lf, symidx); @@ -218,6 +223,20 @@ elf_reloc(linker_file_t lf, const void *data, int type) } int +elf_reloc(linker_file_t lf, const void *data, int type) +{ + + return (elf_reloc_internal(lf, data, type, 0)); +} + +int +elf_reloc_local(linker_file_t lf, const void *data, int type) +{ + + return (elf_reloc_internal(lf, data, type, 1)); +} + +int elf_cpu_load_file(linker_file_t lf) { Elf_Ehdr *hdr; |