summaryrefslogtreecommitdiffstats
path: root/sys/powerpc/powerpc
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2015-09-20 01:27:59 +0000
committerkib <kib@FreeBSD.org>2015-09-20 01:27:59 +0000
commit518734671fcba3801baeb67e70a8ba2f134ba44b (patch)
treea3938733f5d6f30948a42db47e8b9ee2521c366d /sys/powerpc/powerpc
parenta3fcca6713520dc0bf112298215886bcceed5a0f (diff)
downloadFreeBSD-src-518734671fcba3801baeb67e70a8ba2f134ba44b.zip
FreeBSD-src-518734671fcba3801baeb67e70a8ba2f134ba44b.tar.gz
Add support for weak symbols to the kernel linkers. It means that
linkers no longer raise an error when undefined weak symbols are found, but relocate as if the symbol value was 0. Note that we do not repeat the mistake of userspace dynamic linker of making the symbol lookup prefer non-weak symbol definition over the weak one, if both are available. In fact, kernel linker uses the first definition found, and ignores duplicates. Signature of the elf_lookup() and elf_obj_lookup() functions changed to split result/error code and the symbol address returned. Otherwise, it is impossible to return zero address as the symbol value, to MD relocation code. This explains the mechanical changes in elf_machdep.c sources. The powerpc64 R_PPC_JMP_SLOT handler did not checked error from the lookup() call, the patch leaves the code as is (untested). Reported by: glebius Sponsored by: The FreeBSD Foundation MFC after: 1 week
Diffstat (limited to 'sys/powerpc/powerpc')
-rw-r--r--sys/powerpc/powerpc/elf32_machdep.c15
-rw-r--r--sys/powerpc/powerpc/elf64_machdep.c9
2 files changed, 13 insertions, 11 deletions
diff --git a/sys/powerpc/powerpc/elf32_machdep.c b/sys/powerpc/powerpc/elf32_machdep.c
index bdcd9ba..d0c3480 100644
--- a/sys/powerpc/powerpc/elf32_machdep.c
+++ b/sys/powerpc/powerpc/elf32_machdep.c
@@ -183,6 +183,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:
@@ -206,15 +207,15 @@ 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;
*where = elf_relocaddr(lf, addr + addend);
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
@@ -228,8 +229,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 47fbbff..72e6efc3 100644
--- a/sys/powerpc/powerpc/elf64_machdep.c
+++ b/sys/powerpc/powerpc/elf64_machdep.c
@@ -154,6 +154,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:
@@ -176,9 +177,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;
@@ -188,7 +189,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;
OpenPOWER on IntegriCloud