[llvm] b05cd68 - MCInstrAnalysis: make GotPltSectionVA x86-32 specific

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Wed May 3 19:21:07 PDT 2023


Author: Fangrui Song
Date: 2023-05-03T19:21:01-07:00
New Revision: b05cd680eac0196db73495643e6867c588c253de

URL: https://github.com/llvm/llvm-project/commit/b05cd680eac0196db73495643e6867c588c253de
DIFF: https://github.com/llvm/llvm-project/commit/b05cd680eac0196db73495643e6867c588c253de.diff

LOG: MCInstrAnalysis: make GotPltSectionVA x86-32 specific

GotPltSectionVA is specific to x86-32 PIC PLT entries.
Let's remove the argument from the generic interface.

As a side effect of not requiring .got.plt, this simplification
addresses a subset of https://github.com/llvm/llvm-project/issues/62537
by enabling .plt dumping for some ld.bfd -z now linked x86-32/x86-64 images
without .got.plt

Added: 
    

Modified: 
    llvm/include/llvm/MC/MCInstrAnalysis.h
    llvm/lib/Object/ELFObjectFile.cpp
    llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp
    llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/MC/MCInstrAnalysis.h b/llvm/include/llvm/MC/MCInstrAnalysis.h
index 8a6bc371672a0..aca0f4daeeee8 100644
--- a/llvm/include/llvm/MC/MCInstrAnalysis.h
+++ b/llvm/include/llvm/MC/MCInstrAnalysis.h
@@ -168,7 +168,7 @@ class MCInstrAnalysis {
   /// Returns (PLT virtual address, GOT virtual address) pairs for PLT entries.
   virtual std::vector<std::pair<uint64_t, uint64_t>>
   findPltEntries(uint64_t PltSectionVA, ArrayRef<uint8_t> PltContents,
-                 uint64_t GotPltSectionVA, const Triple &TargetTriple) const {
+                 const Triple &TargetTriple) const {
     return {};
   }
 };

diff  --git a/llvm/lib/Object/ELFObjectFile.cpp b/llvm/lib/Object/ELFObjectFile.cpp
index 8149df5ebbfa5..be5886258281b 100644
--- a/llvm/lib/Object/ELFObjectFile.cpp
+++ b/llvm/lib/Object/ELFObjectFile.cpp
@@ -624,7 +624,8 @@ ELFObjectFileBase::getPltAddresses() const {
       T->createMCInstrAnalysis(MII.get()));
   if (!MIA)
     return {};
-  std::optional<SectionRef> Plt, RelaPlt, GotPlt;
+  std::optional<SectionRef> Plt, RelaPlt;
+  uint64_t GotBaseVA = 0;
   for (const SectionRef &Section : sections()) {
     Expected<StringRef> NameOrErr = Section.getName();
     if (!NameOrErr) {
@@ -638,22 +639,27 @@ ELFObjectFileBase::getPltAddresses() const {
     else if (Name == ".rela.plt" || Name == ".rel.plt")
       RelaPlt = Section;
     else if (Name == ".got.plt")
-      GotPlt = Section;
+      GotBaseVA = Section.getAddress();
   }
-  if (!Plt || !RelaPlt || !GotPlt)
+  if (!Plt || !RelaPlt)
     return {};
   Expected<StringRef> PltContents = Plt->getContents();
   if (!PltContents) {
     consumeError(PltContents.takeError());
     return {};
   }
-  auto PltEntries = MIA->findPltEntries(Plt->getAddress(),
-                                        arrayRefFromStringRef(*PltContents),
-                                        GotPlt->getAddress(), Triple);
+  auto PltEntries = MIA->findPltEntries(
+      Plt->getAddress(), arrayRefFromStringRef(*PltContents), Triple);
+
   // Build a map from GOT entry virtual address to PLT entry virtual address.
   DenseMap<uint64_t, uint64_t> GotToPlt;
-  for (const auto &Entry : PltEntries)
-    GotToPlt.insert(std::make_pair(Entry.second, Entry.first));
+  for (auto [Plt, GotPltEntry] : PltEntries) {
+    // An x86-32 PIC PLT uses jmp DWORD PTR [ebx-offset]. Add
+    // _GLOBAL_OFFSET_TABLE_ (EBX) to get the .got.plt (or .got) entry address.
+    if (static_cast<int64_t>(GotPltEntry) < 0 && getEMachine() == ELF::EM_386)
+      GotPltEntry = ~GotPltEntry + GotBaseVA;
+    GotToPlt.insert(std::make_pair(GotPltEntry, Plt));
+  }
   // Find the relocations in the dynamic relocation table that point to
   // locations in the GOT for which we know the corresponding PLT entry.
   std::vector<std::pair<std::optional<DataRefImpl>, uint64_t>> Result;

diff  --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp
index 05a6f8182fe2a..c4d470f278770 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp
@@ -427,7 +427,6 @@ class AArch64MCInstrAnalysis : public MCInstrAnalysis {
 
   std::vector<std::pair<uint64_t, uint64_t>>
   findPltEntries(uint64_t PltSectionVA, ArrayRef<uint8_t> PltContents,
-                 uint64_t GotPltSectionVA,
                  const Triple &TargetTriple) const override {
     // Do a lightweight parsing of PLT entries.
     std::vector<std::pair<uint64_t, uint64_t>> Result;

diff  --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
index 04a918bd93b5e..160384b8ffe75 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
@@ -501,7 +501,6 @@ class X86MCInstrAnalysis : public MCInstrAnalysis {
                             APInt &Mask) const override;
   std::vector<std::pair<uint64_t, uint64_t>>
   findPltEntries(uint64_t PltSectionVA, ArrayRef<uint8_t> PltContents,
-                 uint64_t GotSectionVA,
                  const Triple &TargetTriple) const override;
 
   bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
@@ -570,8 +569,7 @@ bool X86MCInstrAnalysis::clearsSuperRegisters(const MCRegisterInfo &MRI,
 }
 
 static std::vector<std::pair<uint64_t, uint64_t>>
-findX86PltEntries(uint64_t PltSectionVA, ArrayRef<uint8_t> PltContents,
-                  uint64_t GotPltSectionVA) {
+findX86PltEntries(uint64_t PltSectionVA, ArrayRef<uint8_t> PltContents) {
   // Do a lightweight parsing of PLT entries.
   std::vector<std::pair<uint64_t, uint64_t>> Result;
   for (uint64_t Byte = 0, End = PltContents.size(); Byte + 6 < End; ) {
@@ -580,8 +578,7 @@ findX86PltEntries(uint64_t PltSectionVA, ArrayRef<uint8_t> PltContents,
       // The jmp instruction at the beginning of each PLT entry jumps to the
       // address of the base of the .got.plt section plus the immediate.
       uint32_t Imm = support::endian::read32le(PltContents.data() + Byte + 2);
-      Result.push_back(
-          std::make_pair(PltSectionVA + Byte, GotPltSectionVA + Imm));
+      Result.emplace_back(PltSectionVA + Byte, ~static_cast<uint64_t>(Imm));
       Byte += 6;
     } else if (PltContents[Byte] == 0xff && PltContents[Byte + 1] == 0x25) {
       // The jmp instruction at the beginning of each PLT entry jumps to the
@@ -614,17 +611,18 @@ findX86_64PltEntries(uint64_t PltSectionVA, ArrayRef<uint8_t> PltContents) {
   return Result;
 }
 
-std::vector<std::pair<uint64_t, uint64_t>> X86MCInstrAnalysis::findPltEntries(
-    uint64_t PltSectionVA, ArrayRef<uint8_t> PltContents,
-    uint64_t GotPltSectionVA, const Triple &TargetTriple) const {
+std::vector<std::pair<uint64_t, uint64_t>>
+X86MCInstrAnalysis::findPltEntries(uint64_t PltSectionVA,
+                                   ArrayRef<uint8_t> PltContents,
+                                   const Triple &TargetTriple) const {
   switch (TargetTriple.getArch()) {
-    case Triple::x86:
-      return findX86PltEntries(PltSectionVA, PltContents, GotPltSectionVA);
-    case Triple::x86_64:
-      return findX86_64PltEntries(PltSectionVA, PltContents);
-    default:
-      return {};
-    }
+  case Triple::x86:
+    return findX86PltEntries(PltSectionVA, PltContents);
+  case Triple::x86_64:
+    return findX86_64PltEntries(PltSectionVA, PltContents);
+  default:
+    return {};
+  }
 }
 
 bool X86MCInstrAnalysis::evaluateBranch(const MCInst &Inst, uint64_t Addr,


        


More information about the llvm-commits mailing list