summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSid Manning <sidneym@codeaurora.org>2018-10-04 14:54:17 +0000
committerSid Manning <sidneym@codeaurora.org>2018-10-04 14:54:17 +0000
commit86cc7ca5eb80f48f616d81d824e94720acc329de (patch)
tree312668210f9072589e535f688a3ab942b2581333
parent6d253a8706ac3f4dfe7be416c77d3082f9e684de (diff)
[ELF][HEXAGON] Add support for GOT relocations.
The GOT is referenced through the symbol _GLOBAL_OFFSET_TABLE_ . The relocation added calculates the offset into the global offset table for the entry of a symbol. In order to get the correct TargetVA I needed to create an new relocation expression, HEXAGON_GOT. It does Sym.getGotVA() - In.GotPlt->getVA(). Differential Revision: https://reviews.llvm.org/D52744
-rw-r--r--lld/ELF/Arch/Hexagon.cpp12
-rw-r--r--lld/ELF/InputSection.cpp2
-rw-r--r--lld/ELF/Relocations.cpp18
-rw-r--r--lld/ELF/Relocations.h1
-rw-r--r--lld/test/ELF/hexagon-shared.s23
5 files changed, 41 insertions, 15 deletions
diff --git a/lld/ELF/Arch/Hexagon.cpp b/lld/ELF/Arch/Hexagon.cpp
index b448f612b6f..99331922dff 100644
--- a/lld/ELF/Arch/Hexagon.cpp
+++ b/lld/ELF/Arch/Hexagon.cpp
@@ -40,6 +40,13 @@ public:
Hexagon::Hexagon() {
PltRel = R_HEX_JMP_SLOT;
RelativeRel = R_HEX_RELATIVE;
+ GotRel = R_HEX_GLOB_DAT;
+ GotEntrySize = 4;
+ // The zero'th GOT entry is reserved for the address of _DYNAMIC. The
+ // next 3 are reserved for the dynamic loader.
+ GotPltHeaderEntriesNum = 4;
+ GotPltEntrySize = 4;
+
PltEntrySize = 16;
PltHeaderSize = 32;
@@ -82,6 +89,9 @@ RelExpr Hexagon::getRelExpr(RelType Type, const Symbol &S,
case R_HEX_B22_PCREL_X:
case R_HEX_B32_PCREL_X:
return R_PLT_PC;
+ case R_HEX_GOT_11_X:
+ case R_HEX_GOT_32_6_X:
+ return R_HEXAGON_GOT;
default:
return R_ABS;
}
@@ -175,6 +185,7 @@ void Hexagon::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
or32le(Loc, applyMask(0x00203fe0, Val & 0x3f));
break;
case R_HEX_11_X:
+ case R_HEX_GOT_11_X:
or32le(Loc, applyMask(findMaskR11(read32le(Loc)), Val & 0x3f));
break;
case R_HEX_12_X:
@@ -188,6 +199,7 @@ void Hexagon::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
or32le(Loc, Val);
break;
case R_HEX_32_6_X:
+ case R_HEX_GOT_32_6_X:
or32le(Loc, applyMask(0x0fff3fff, Val >> 6));
break;
case R_HEX_B9_PCREL:
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index ddb968a326c..69d83d09c38 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -545,6 +545,8 @@ static uint64_t getRelocTargetVA(const InputFile *File, RelType Type, int64_t A,
case R_GOT_PC:
case R_RELAX_TLS_GD_TO_IE:
return Sym.getGotVA() + A - P;
+ case R_HEXAGON_GOT:
+ return Sym.getGotVA() - In.GotPlt->getVA();
case R_MIPS_GOTREL:
return Sym.getVA(A) - In.MipsGot->getGp(File);
case R_MIPS_GOT_GP:
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index a902f0f2b50..bbb37e35242 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -331,9 +331,9 @@ static bool needsPlt(RelExpr Expr) {
// returns false for TLS variables even though they need GOT, because
// TLS variables uses GOT differently than the regular variables.
static bool needsGot(RelExpr Expr) {
- return isRelExprOneOf<R_GOT, R_GOT_OFF, R_MIPS_GOT_LOCAL_PAGE, R_MIPS_GOT_OFF,
- R_MIPS_GOT_OFF32, R_GOT_PAGE_PC, R_GOT_PC,
- R_GOT_FROM_END>(Expr);
+ return isRelExprOneOf<R_GOT, R_GOT_OFF, R_HEXAGON_GOT, R_MIPS_GOT_LOCAL_PAGE,
+ R_MIPS_GOT_OFF, R_MIPS_GOT_OFF32, R_GOT_PAGE_PC,
+ R_GOT_PC, R_GOT_FROM_END>(Expr);
}
// True if this expression is of the form Sym - X, where X is a position in the
@@ -357,12 +357,12 @@ static bool isStaticLinkTimeConstant(RelExpr E, RelType Type, const Symbol &Sym,
InputSectionBase &S, uint64_t RelOff) {
// These expressions always compute a constant
if (isRelExprOneOf<
- R_GOT_FROM_END, R_GOT_OFF, R_TLSLD_GOT_OFF, R_MIPS_GOT_LOCAL_PAGE,
- R_MIPS_GOTREL, R_MIPS_GOT_OFF, R_MIPS_GOT_OFF32, R_MIPS_GOT_GP_PC,
- R_MIPS_TLSGD, R_GOT_PAGE_PC, R_GOT_PC, R_GOTONLY_PC,
- R_GOTONLY_PC_FROM_END, R_PLT_PC, R_TLSGD_GOT, R_TLSGD_GOT_FROM_END,
- R_TLSGD_PC, R_PPC_CALL_PLT, R_TLSDESC_CALL, R_TLSDESC_PAGE, R_HINT,
- R_TLSLD_HINT, R_TLSIE_HINT>(E))
+ R_GOT_FROM_END, R_GOT_OFF, R_HEXAGON_GOT, R_TLSLD_GOT_OFF,
+ R_MIPS_GOT_LOCAL_PAGE, R_MIPS_GOTREL, R_MIPS_GOT_OFF,
+ R_MIPS_GOT_OFF32, R_MIPS_GOT_GP_PC, R_MIPS_TLSGD, R_GOT_PAGE_PC,
+ R_GOT_PC, R_GOTONLY_PC, R_GOTONLY_PC_FROM_END, R_PLT_PC, R_TLSGD_GOT,
+ R_TLSGD_GOT_FROM_END, R_TLSGD_PC, R_PPC_CALL_PLT, R_TLSDESC_CALL,
+ R_TLSDESC_PAGE, R_HINT, R_TLSLD_HINT, R_TLSIE_HINT>(E))
return true;
// These never do, except if the entire file is position dependent or if
diff --git a/lld/ELF/Relocations.h b/lld/ELF/Relocations.h
index 081f13bab07..d482b4e5c0e 100644
--- a/lld/ELF/Relocations.h
+++ b/lld/ELF/Relocations.h
@@ -43,6 +43,7 @@ enum RelExpr {
R_GOT_OFF,
R_GOT_PAGE_PC,
R_GOT_PC,
+ R_HEXAGON_GOT,
R_HINT,
R_MIPS_GOTREL,
R_MIPS_GOT_GP,
diff --git a/lld/test/ELF/hexagon-shared.s b/lld/test/ELF/hexagon-shared.s
index 33d9a7ae9ac..9d65b4e0224 100644
--- a/lld/test/ELF/hexagon-shared.s
+++ b/lld/test/ELF/hexagon-shared.s
@@ -3,19 +3,27 @@
# RUN: llvm-mc -filetype=obj -triple=hexagon-unknown-elf %S/Inputs/hexagon-shared.s -o %t2.o
# RUN: ld.lld -shared %t2.o -soname %t3.so -o %t3.so
# RUN: ld.lld -shared %t %t3.so -soname %t4.so -o %t4.so
-# RUN: llvm-objdump -d -j=.plt %t4.so | FileCheck --check-prefix=PLT %s
-# RUN: llvm-objdump -d -j=.text %t4.so | FileCheck --check-prefix=TEXT %s
+# RUN: llvm-objdump -d -j .plt %t4.so | FileCheck --check-prefix=PLT %s
+# RUN: llvm-objdump -d -j .text %t4.so | FileCheck --check-prefix=TEXT %s
+# RUN: llvm-objdump -D -j .got %t4.so | FileCheck --check-prefix=GOT %s
.global foo
foo:
+
# _HEX_32_PCREL
.word _DYNAMIC - .
call ##bar
+
# R_HEX_PLT_B22_PCREL
call bar@PLT
+# R_HEX_GOT_11_X and R_HEX_GOT_32_6_X
+r2=add(pc,##_GLOBAL_OFFSET_TABLE_@PCREL)
+r0 = memw (r2+##bar@GOT)
+jumpr r0
+
# PLT: { immext(#65472
-# PLT: r28 = add(pc,##65520) }
+# PLT: r28 = add(pc,##65488) }
# PLT: { r14 -= add(r28,#16)
# PLT: r15 = memw(r28+#8)
# PLT: r28 = memw(r28+#4) }
@@ -23,9 +31,12 @@ call bar@PLT
# PLT: jumpr r28 }
# PLT: { trap0(#219) }
# PLT: immext(#65472)
-# PLT: r14 = add(pc,##65488) }
+# PLT: r14 = add(pc,##65472) }
# PLT: r28 = memw(r14+#0) }
# PLT: jumpr r28 }
-# TEXT: 10000: 00 00 01 00 00010000
-# TEXT: { call 0x10030 }
+# TEXT: 10000: 00 00 02 00 00020000
+# TEXT: { call 0x10050 }
+
+# GOT: .got:
+# GOT: 30080: 00 00 00 00 00000000 <unknown>