diff options
author | Fangrui Song <i@maskray.me> | 2023-05-03 19:21:01 -0700 |
---|---|---|
committer | Fangrui Song <i@maskray.me> | 2023-05-03 19:21:01 -0700 |
commit | b05cd680eac0196db73495643e6867c588c253de (patch) | |
tree | efe3b78a953e74998bdc2a671493e430024cb73c /llvm/lib/Object/ELFObjectFile.cpp | |
parent | 3da83fbafef1689de1fc45c2c3fa3d258edda09d (diff) | |
download | llvm-b05cd680eac0196db73495643e6867c588c253de.zip llvm-b05cd680eac0196db73495643e6867c588c253de.tar.gz llvm-b05cd680eac0196db73495643e6867c588c253de.tar.bz2 |
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
Diffstat (limited to 'llvm/lib/Object/ELFObjectFile.cpp')
-rw-r--r-- | llvm/lib/Object/ELFObjectFile.cpp | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/llvm/lib/Object/ELFObjectFile.cpp b/llvm/lib/Object/ELFObjectFile.cpp index 8149df5..be58862 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; |