[commit: ghc] wip/aarch64-regd: Linker: WIP on supporting Arm64/AArch64 (31682d4)
git at git.haskell.org
git at git.haskell.org
Mon Jan 11 21:04:58 UTC 2016
Repository : ssh://git@git.haskell.org/ghc
On branch : wip/aarch64-regd
Link : http://ghc.haskell.org/trac/ghc/changeset/31682d41f579e49968b924853e69fb0207c50488/ghc
>---------------------------------------------------------------
commit 31682d41f579e49968b924853e69fb0207c50488
Author: Erik de Castro Lopo <erikd at mega-nerd.com>
Date: Fri Oct 23 14:35:20 2015 +1100
Linker: WIP on supporting Arm64/AArch64
>---------------------------------------------------------------
31682d41f579e49968b924853e69fb0207c50488
rts/Linker.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 50 insertions(+), 2 deletions(-)
diff --git a/rts/Linker.c b/rts/Linker.c
index 6e20984..83b9c1e 100644
--- a/rts/Linker.c
+++ b/rts/Linker.c
@@ -4513,6 +4513,10 @@ ocVerifyImage_ELF ( ObjectCode* oc )
#elif defined(EM_AMD64)
case EM_AMD64: IF_DEBUG(linker,debugBelch( "amd64" )); break;
#endif
+#ifdef EM_AARCH64
+ case EM_AARCH64: IF_DEBUG(linker,debugBelch( "aarch64" )); break;
+#endif
+
default: IF_DEBUG(linker,debugBelch( "unknown" ));
errorBelch("%s: unknown architecture (e_machine == %d)"
, oc->fileName, ehdr->e_machine);
@@ -5332,7 +5336,7 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
#if defined(SHN_XINDEX)
Elf_Word* shndx_table = get_shndx_table((Elf_Ehdr*)ehdrC);
#endif
-#if defined(DEBUG) || defined(sparc_HOST_ARCH) || defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH)
+#if defined(DEBUG) || defined(sparc_HOST_ARCH) || defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH) || defined(aarch64_HOST_ARCH)
/* This #ifdef only serves to avoid unused-var warnings. */
Elf_Addr targ = (Elf_Addr) oc->sections[target_shndx].start;
#endif
@@ -5350,7 +5354,7 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
}
for (j = 0; j < nent; j++) {
-#if defined(DEBUG) || defined(sparc_HOST_ARCH) || defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH)
+#if defined(DEBUG) || defined(sparc_HOST_ARCH) || defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH) || defined(aarch64_HOST_ARCH)
/* This #ifdef only serves to avoid unused-var warnings. */
Elf_Addr offset = rtab[j].r_offset;
Elf_Addr P = targ + offset;
@@ -5655,6 +5659,50 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
}
#endif
+ case R_AARCH64_ABS64:
+ puts ("\n\nAArch64: ELF relocation(RelA) R_AARCH64_ABS64");
+ *(Elf64_Xword *)P = S + A;
+ break;
+
+ case R_AARCH64_ADR_PREL_PG_HI21:
+ puts ("\n\nAArch64: ELF relocation(RelA) R_AARCH64_ADR_PREL_PG_HI21");
+ {
+ uint64_t final_address = (uint64_t) rtab + rtab[j].r_offset ;
+ // Operation: Page(S+A) - Page(P)
+ uint64_t result = ((S + A) & ~0xfffULL) - (final_address & ~0xfffULL);
+
+printf ("ehdrC: %p\nrtab : %p\n\n", ehdrC, rtab) ;
+
+printf ("rtab 0x%lx + 0x%lx -> 0x%lx\n", (uint64_t) rtab, (uint64_t) rtab[j].r_offset, final_address) ;
+printf ("S 0x%lx + A 0x%lx : 0x%lx\n", S, A, S + A) ;
+printf ("result 0x%lx\n", result) ;
+
+ // Check that -2^32 <= X < 2^32
+ if (result >> 32)
+ barf ("%s: overflow check failed for relocation", oc->fileName);
+
+ *(Elf64_Xword *)P &= 0x9f00001fU;
+ // Immediate goes in bits 30:29 + 5:23 of ADRP instruction, taken
+ // from bits 32:12 of X.
+ *(Elf64_Xword *)P |= ((result & 0x3000U) << (29 - 12));
+ *(Elf64_Xword *)P |= ((result & 0x1ffffc000ULL) >> (14 - 5));
+ }
+ break;
+
+ case R_AARCH64_CALL26:
+ case R_AARCH64_JUMP26:
+ puts ("\n\nAArch64: ELF relocation(RelA) R_AARCH64_CALL26/JUMP64");
+ {
+ // These two are handled in the same way.
+ }
+ break;
+
+ case R_AARCH64_ADD_ABS_LO12_NC:
+ puts ("\n\nAArch64: ELF relocation(RelA) R_AARCH64_ADD_ABS_LO12_NC");
+ {
+ }
+ break;
+
default:
errorBelch("%s: unhandled ELF relocation(RelA) type %" FMT_Word "\n",
oc->fileName, (W_)ELF_R_TYPE(info));
More information about the ghc-commits
mailing list