[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