From a34ff653b4445549092cb4e2ce17f8e6e4d8135a Mon Sep 17 00:00:00 2001 From: quic-areg Date: Wed, 15 Jan 2025 12:20:21 -0800 Subject: [PATCH 1/4] [Hexagon] Add support for decoding PLT symbols Describes PLT entries for hexagon. --- llvm/lib/Object/ELFObjectFile.cpp | 4 ++ .../MCTargetDesc/HexagonMCTargetDesc.cpp | 38 ++++++++++++++++- .../tools/llvm-objdump/ELF/Hexagon/plt.test | 42 +++++++++++++++++++ 3 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 llvm/test/tools/llvm-objdump/ELF/Hexagon/plt.test diff --git a/llvm/lib/Object/ELFObjectFile.cpp b/llvm/lib/Object/ELFObjectFile.cpp index 1ddfadaf1e271..2d3d70db50c39 100644 --- a/llvm/lib/Object/ELFObjectFile.cpp +++ b/llvm/lib/Object/ELFObjectFile.cpp @@ -802,6 +802,10 @@ std::vector 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 a98f6048b051c..d9fe05d4e1ac3 100644 --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp @@ -734,8 +734,44 @@ class HexagonMCInstrAnalysis : public MCInstrAnalysis { Target = Value; return true; } + + uint32_t getValueFromMask(uint32_t Instruction, uint32_t Mask) const { + uint32_t Result = 0; + size_t Off = 0; + for (uint32_t Bit = 0; Bit != sizeof(uint32_t) * CHAR_BIT; ++Bit) { + const uint8_t ValBit = (Instruction >> Bit) & 1; + const bool MaskBit = (Mask >> Bit) & 1; + if (MaskBit) { + Result |= (ValBit << Off); + ++Off; + } + } + return Result; + } + + std::vector> + findPltEntries(uint64_t PltSectionVA, ArrayRef PltContents, + const Triple &TargetTriple) const override { + // Do a lightweight parsing of PLT entries. + std::vector> 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.push_back(std::make_pair(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 0000000000000..5d2b8576b9b84 --- /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 : +# 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 +... From 63c169ec25b9ad1d16ab21992b00f92d9b39c2ef Mon Sep 17 00:00:00 2001 From: quic-areg Date: Wed, 22 Jan 2025 09:45:11 -0800 Subject: [PATCH 2/4] fix lld tests --- lld/test/ELF/hexagon-plt.s | 6 ++++-- lld/test/ELF/hexagon-shared.s | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lld/test/ELF/hexagon-plt.s b/lld/test/ELF/hexagon-plt.s index 9eca0e83afe6f..679de82923a72 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 : # 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 : # 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 01f7286584705..cc62662d278e2 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 : # PLT-NEXT: immext(#131200) # PLT-NEXT: r14 = add(pc,##131252) } # PLT-NEXT: r28 = memw(r14+#0) } From e3c1804dccc87d77be187f6394dc04eb6ea40e80 Mon Sep 17 00:00:00 2001 From: quic-areg Date: Wed, 22 Jan 2025 09:45:34 -0800 Subject: [PATCH 3/4] make getValueFromMask more efficient --- .../Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp index d9fe05d4e1ac3..f8384fe49f0f1 100644 --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp @@ -737,14 +737,12 @@ class HexagonMCInstrAnalysis : public MCInstrAnalysis { uint32_t getValueFromMask(uint32_t Instruction, uint32_t Mask) const { uint32_t Result = 0; - size_t Off = 0; - for (uint32_t Bit = 0; Bit != sizeof(uint32_t) * CHAR_BIT; ++Bit) { - const uint8_t ValBit = (Instruction >> Bit) & 1; - const bool MaskBit = (Mask >> Bit) & 1; - if (MaskBit) { - Result |= (ValBit << Off); - ++Off; - } + uint32_t Offset = 0; + while (Mask) { + if (Instruction & (Mask & -Mask)) + Result |= (1 << Offset); + Mask &= (Mask - 1); + ++Offset; } return Result; } From 998cdae4708d53eb82e87e11a6c34c2d4cf83331 Mon Sep 17 00:00:00 2001 From: quic-areg Date: Wed, 29 Jan 2025 08:53:08 -0800 Subject: [PATCH 4/4] emplace_back --- llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp index f8384fe49f0f1..baa208816786d 100644 --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp @@ -764,7 +764,7 @@ class HexagonMCInstrAnalysis : public MCInstrAnalysis { uint32_t Address = (getValueFromMask(ImmExt, 0xfff3fff) << 6) + getValueFromMask(LoadGotPlt, 0x1f80) + PltSectionVA + Byte; - Result.push_back(std::make_pair(PltSectionVA + Byte, Address)); + Result.emplace_back(PltSectionVA + Byte, Address); } return Result; }