[lld] [llvm] [Hexagon] Add support for decoding PLT symbols (PR #123425)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 22 10:59:37 PST 2025
https://github.com/quic-areg updated https://github.com/llvm/llvm-project/pull/123425
>From 334d6b54356cc69f309467869f92cc1c3f948d1f Mon Sep 17 00:00:00 2001
From: quic-areg <aregmi at quicinc.com>
Date: Wed, 15 Jan 2025 12:20:21 -0800
Subject: [PATCH 1/3] [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 1ddfadaf1e2716..2d3d70db50c393 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 a98f6048b051cc..d9fe05d4e1ac3f 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<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.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 00000000000000..5d2b8576b9b848
--- /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 at 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
+...
>From c0a5e43285bb03fb0dbea30e5114e75145dafca5 Mon Sep 17 00:00:00 2001
From: quic-areg <aregmi at quicinc.com>
Date: Wed, 22 Jan 2025 09:45:11 -0800
Subject: [PATCH 2/3] 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 9eca0e83afe6f4..679de82923a729 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 at 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 at 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 01f72865847056..cc62662d278e22 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 at plt>:
# PLT-NEXT: immext(#131200)
# PLT-NEXT: r14 = add(pc,##131252) }
# PLT-NEXT: r28 = memw(r14+#0) }
>From 79b7c019682226069a56975c13d257c402205bd3 Mon Sep 17 00:00:00 2001
From: quic-areg <aregmi at quicinc.com>
Date: Wed, 22 Jan 2025 09:45:34 -0800
Subject: [PATCH 3/3] 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 d9fe05d4e1ac3f..f8384fe49f0f14 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;
}
More information about the llvm-commits
mailing list