diff options
-rw-r--r-- | lld/test/ELF/hexagon-plt.s | 6 | ||||
-rw-r--r-- | lld/test/ELF/hexagon-shared.s | 2 | ||||
-rw-r--r-- | llvm/lib/Object/ELFObjectFile.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp | 36 | ||||
-rw-r--r-- | llvm/test/tools/llvm-objdump/ELF/Hexagon/plt.test | 42 |
5 files changed, 87 insertions, 3 deletions
diff --git a/lld/test/ELF/hexagon-plt.s b/lld/test/ELF/hexagon-plt.s index 9eca0e8..679de82 100644 --- a/lld/test/ELF/hexagon-plt.s +++ b/lld/test/ELF/hexagon-plt.s @@ -71,12 +71,14 @@ # DIS-NEXT: 20054: { r14 = asr(r14,#2) # DIS-NEXT: 20058: jumpr r28 } # DIS-NEXT: 2005c: { trap0(#219) } -## bar's plt slot +# DIS-EMPTY: +# DIS-NEXT: 00020060 <bar@plt>: # DIS-NEXT: 20060: { immext(#131072) # DIS-NEXT: 20064: r14 = add(pc,##131096) } # DIS-NEXT: 20068: { r28 = memw(r14+#0) } # DIS-NEXT: 2006c: { jumpr r28 } -## weak's plt slot +# DIS-EMPTY: +# DIS-NEXT: 00020070 <weak@plt>: # DIS-NEXT: 20070: { immext(#131072) # DIS-NEXT: 20074: r14 = add(pc,##131084) } # DIS-NEXT: 20078: { r28 = memw(r14+#0) } diff --git a/lld/test/ELF/hexagon-shared.s b/lld/test/ELF/hexagon-shared.s index 01f7286..cc62662 100644 --- a/lld/test/ELF/hexagon-shared.s +++ b/lld/test/ELF/hexagon-shared.s @@ -80,6 +80,8 @@ pvar: # PLT-NEXT: { r14 = asr(r14,#2) # PLT-NEXT: jumpr r28 } # PLT-NEXT: { trap0(#219) } +# PLT-EMPTY: +# PLT-NEXT: 000102f0 <foo@plt>: # PLT-NEXT: immext(#131200) # PLT-NEXT: r14 = add(pc,##131252) } # PLT-NEXT: r28 = memw(r14+#0) } diff --git a/llvm/lib/Object/ELFObjectFile.cpp b/llvm/lib/Object/ELFObjectFile.cpp index 1ddfada..2d3d70d 100644 --- a/llvm/lib/Object/ELFObjectFile.cpp +++ b/llvm/lib/Object/ELFObjectFile.cpp @@ -802,6 +802,10 @@ std::vector<ELFPltEntry> ELFObjectFileBase::getPltEntries() const { case Triple::aarch64_be: JumpSlotReloc = ELF::R_AARCH64_JUMP_SLOT; break; + case Triple::hexagon: + JumpSlotReloc = ELF::R_HEX_JMP_SLOT; + GlobDatReloc = ELF::R_HEX_GLOB_DAT; + break; default: return {}; } diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp index a98f604..baa2088 100644 --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp @@ -734,8 +734,42 @@ public: Target = Value; return true; } + + uint32_t getValueFromMask(uint32_t Instruction, uint32_t Mask) const { + uint32_t Result = 0; + uint32_t Offset = 0; + while (Mask) { + if (Instruction & (Mask & -Mask)) + Result |= (1 << Offset); + Mask &= (Mask - 1); + ++Offset; + } + return Result; + } + + std::vector<std::pair<uint64_t, uint64_t>> + findPltEntries(uint64_t PltSectionVA, ArrayRef<uint8_t> PltContents, + const Triple &TargetTriple) const override { + // Do a lightweight parsing of PLT entries. + std::vector<std::pair<uint64_t, uint64_t>> Result; + for (uint64_t Byte = 0x0, End = PltContents.size(); Byte < End; Byte += 4) { + // Recognize immext(##gotpltn) + uint32_t ImmExt = support::endian::read32le(PltContents.data() + Byte); + if ((ImmExt & 0x00004000) != 0x00004000) + continue; + uint32_t LoadGotPlt = + support::endian::read32le(PltContents.data() + Byte + 4); + if ((LoadGotPlt & 0x6a49c00c) != 0x6a49c00c) + continue; + uint32_t Address = (getValueFromMask(ImmExt, 0xfff3fff) << 6) + + getValueFromMask(LoadGotPlt, 0x1f80) + PltSectionVA + + Byte; + Result.emplace_back(PltSectionVA + Byte, Address); + } + return Result; + } }; -} +} // namespace static MCInstrAnalysis *createHexagonMCInstrAnalysis(const MCInstrInfo *Info) { return new HexagonMCInstrAnalysis(Info); diff --git a/llvm/test/tools/llvm-objdump/ELF/Hexagon/plt.test b/llvm/test/tools/llvm-objdump/ELF/Hexagon/plt.test new file mode 100644 index 0000000..5d2b857 --- /dev/null +++ b/llvm/test/tools/llvm-objdump/ELF/Hexagon/plt.test @@ -0,0 +1,42 @@ +# RUN: yaml2obj %s | llvm-objdump -d - | FileCheck %s + +# CHECK: 00000310 <printf@plt>: +# CHECK-NEXT: 310: 36 40 00 00 00004036 { immext(#0xd80) +# CHECK-NEXT: 314: 0e de 49 6a 6a49de0e r14 = add(pc,##0xdbc) } +# CHECK-NEXT: 318: 1c c0 8e 91 918ec01c { r28 = memw(r14+#0x0) } +# CHECK-NEXT: 31c: 00 c0 9c 52 529cc000 { jumpr r28 } + +--- !ELF +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_HEXAGON +Sections: + - Name: .rela.plt + Type: SHT_RELA + Flags: [ SHF_ALLOC ] + Info: .got.plt + Relocations: + - Offset: 0x10CC + Symbol: printf + Type: R_HEX_JMP_SLOT + - Name: .plt + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x2B0 + Content: 384000001CC0496A0E429CE24F409C913CC09C910E420E8C00C09C520000000000000000000000000000000000000000374000000ED0496A1CC08E9100C09C52374000000ECA496A1CC08E9100C09C52374000000EC4496A1CC08E9100C09C52364000000EDE496A1CC08E9100C09C52 + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x320 + Content: 0240096AC97FFF0F01C6007802C221F3FF7FFF0F80C7007800C002F300C0809100C0007500C05F5300C0096ADAFFFF5901C09DA082FFFEBF00C0423C0140000000D4496AD6FFFF5B00C000781EC01E96 + - Name: .got.plt + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x10B0 + Content: 00000000000000000000000000000000B0020000B0020000B0020000B0020000 +Symbols: + - Name: printf + Binding: STB_GLOBAL +... |