[lld] r343320 - [ELF][HEXAGON] Add support for dynamic libraries
Sid Manning via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 28 07:09:17 PDT 2018
Author: sidneym
Date: Fri Sep 28 07:09:16 2018
New Revision: 343320
URL: http://llvm.org/viewvc/llvm-project?rev=343320&view=rev
Log:
[ELF][HEXAGON] Add support for dynamic libraries
Write out the PLT header and stub.
Hexagon uses RELA relocations.
Differential Revision: https://reviews.llvm.org/D52317
Added:
lld/trunk/test/ELF/Inputs/hexagon-shared.s
lld/trunk/test/ELF/hexagon-shared.s
Modified:
lld/trunk/ELF/Arch/Hexagon.cpp
lld/trunk/ELF/Driver.cpp
Modified: lld/trunk/ELF/Arch/Hexagon.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/Hexagon.cpp?rev=343320&r1=343319&r2=343320&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/Hexagon.cpp (original)
+++ lld/trunk/ELF/Arch/Hexagon.cpp Fri Sep 28 07:09:16 2018
@@ -9,6 +9,7 @@
#include "InputFiles.h"
#include "Symbols.h"
+#include "SyntheticSections.h"
#include "Target.h"
#include "lld/Common/ErrorHandler.h"
#include "llvm/BinaryFormat/ELF.h"
@@ -30,10 +31,18 @@ public:
RelExpr getRelExpr(RelType Type, const Symbol &S,
const uint8_t *Loc) const override;
void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
+ void writePltHeader(uint8_t *Buf) const override;
+ void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
+ int32_t Index, unsigned RelOff) const override;
};
} // namespace
Hexagon::Hexagon() {
+ PltRel = R_HEX_JMP_SLOT;
+ RelativeRel = R_HEX_RELATIVE;
+ PltEntrySize = 16;
+ PltHeaderSize = 32;
+
// Hexagon Linux uses 64K pages by default.
DefaultMaxPageSize = 0x10000;
NoneRel = R_HEX_NONE;
@@ -65,11 +74,12 @@ RelExpr Hexagon::getRelExpr(RelType Type
case R_HEX_B13_PCREL:
case R_HEX_B15_PCREL:
case R_HEX_B15_PCREL_X:
+ case R_HEX_6_PCREL_X:
+ return R_PC;
case R_HEX_B22_PCREL:
case R_HEX_B22_PCREL_X:
case R_HEX_B32_PCREL_X:
- case R_HEX_6_PCREL_X:
- return R_PC;
+ return R_PLT_PC;
default:
return R_ABS;
}
@@ -168,7 +178,7 @@ void Hexagon::relocateOne(uint8_t *Loc,
case R_HEX_12_X:
or32le(Loc, applyMask(0x000007e0, Val));
break;
- case R_HEX_16_X: // This reloc only has 6 effective bits.
+ case R_HEX_16_X: // This reloc only has 6 effective bits.
or32le(Loc, applyMask(findMaskR16(read32le(Loc)), Val & 0x3f));
break;
case R_HEX_32:
@@ -213,6 +223,39 @@ void Hexagon::relocateOne(uint8_t *Loc,
}
}
+void Hexagon::writePltHeader(uint8_t *Buf) const {
+ const uint8_t PltData[] = {
+ 0x00, 0x40, 0x00, 0x00, // { immext (#0)
+ 0x1c, 0xc0, 0x49, 0x6a, // r28 = add (pc, ##GOT0 at PCREL) } # @GOT0
+ 0x0e, 0x42, 0x9c, 0xe2, // { r14 -= add (r28, #16) # offset of GOTn
+ 0x4f, 0x40, 0x9c, 0x91, // r15 = memw (r28 + #8) # object ID at GOT2
+ 0x3c, 0xc0, 0x9c, 0x91, // r28 = memw (r28 + #4) }# dynamic link at GOT1
+ 0x0e, 0x42, 0x0e, 0x8c, // { r14 = asr (r14, #2) # index of PLTn
+ 0x00, 0xc0, 0x9c, 0x52, // jumpr r28 } # call dynamic linker
+ 0x0c, 0xdb, 0x00, 0x54, // trap0(#0xdb) # bring plt0 into 16byte alignment
+ };
+ memcpy(Buf, PltData, sizeof(PltData));
+
+ // offset from PLT0 to the GOT.
+ relocateOne(Buf, R_HEX_B32_PCREL_X, In.GotPlt->getVA() - In.Plt->getVA());
+ relocateOne(Buf + 4, R_HEX_6_PCREL_X,
+ In.GotPlt->getVA() - In.Plt->getVA());
+}
+void Hexagon::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
+ uint64_t PltEntryAddr, int32_t Index,
+ unsigned RelOff) const {
+ const uint8_t Inst[] = {
+ 0x00, 0x40, 0x00, 0x00, // { immext (#0)
+ 0x0e, 0xc0, 0x49, 0x6a, // r14 = add (pc, ##GOTn at PCREL) }
+ 0x1c, 0xc0, 0x8e, 0x91, // r28 = memw (r14)
+ 0x00, 0xc0, 0x9c, 0x52, // jumpr r28
+ };
+ memcpy(Buf, Inst, sizeof(Inst));
+
+ relocateOne(Buf, R_HEX_B32_PCREL_X, GotPltEntryAddr - PltEntryAddr);
+ relocateOne(Buf + 4, R_HEX_6_PCREL_X, GotPltEntryAddr - PltEntryAddr);
+}
+
TargetInfo *elf::getHexagonTargetInfo() {
static Hexagon Target;
return &Target;
Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=343320&r1=343319&r2=343320&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Fri Sep 28 07:09:16 2018
@@ -989,8 +989,9 @@ static void setConfigs(opt::InputArgList
// You cannot choose which one, Rel or Rela, you want to use. Instead each
// ABI defines which one you need to use. The following expression expresses
// that.
- Config->IsRela = M == EM_AARCH64 || M == EM_AMDGPU || M == EM_PPC ||
- M == EM_PPC64 || M == EM_RISCV || M == EM_X86_64;
+ Config->IsRela = M == EM_AARCH64 || M == EM_AMDGPU || M == EM_HEXAGON ||
+ M == EM_PPC || M == EM_PPC64 || M == EM_RISCV ||
+ M == EM_X86_64;
// If the output uses REL relocations we must store the dynamic relocation
// addends to the output sections. We also store addends for RELA relocations
Added: lld/trunk/test/ELF/Inputs/hexagon-shared.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/hexagon-shared.s?rev=343320&view=auto
==============================================================================
--- lld/trunk/test/ELF/Inputs/hexagon-shared.s (added)
+++ lld/trunk/test/ELF/Inputs/hexagon-shared.s Fri Sep 28 07:09:16 2018
@@ -0,0 +1,3 @@
+.global bar
+bar:
+ jumpr lr
Added: lld/trunk/test/ELF/hexagon-shared.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/hexagon-shared.s?rev=343320&view=auto
==============================================================================
--- lld/trunk/test/ELF/hexagon-shared.s (added)
+++ lld/trunk/test/ELF/hexagon-shared.s Fri Sep 28 07:09:16 2018
@@ -0,0 +1,23 @@
+# REQUIRES: hexagon
+# RUN: llvm-mc -filetype=obj -triple=hexagon-unknown-elf %s -o %t
+# 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 %s
+
+.global foo
+foo:
+call ##bar
+
+# CHECK: { immext(#65472
+# CHECK: r28 = add(pc,##65520) }
+# CHECK: { r14 -= add(r28,#16)
+# CHECK: r15 = memw(r28+#8)
+# CHECK: r28 = memw(r28+#4) }
+# CHECK: { r14 = asr(r14,#2)
+# CHECK: jumpr r28 }
+# CHECK: { trap0(#219) }
+# CHECK: immext(#65472)
+# CHECK: r14 = add(pc,##65488) }
+# CHECK: r28 = memw(r14+#0) }
+# CHECK: jumpr r28 }
More information about the llvm-commits
mailing list