[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