From b05cd680eac0196db73495643e6867c588c253de Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Wed, 3 May 2023 19:21:01 -0700 Subject: 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 --- llvm/lib/Object/ELFObjectFile.cpp | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'llvm/lib/Object/ELFObjectFile.cpp') 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 Plt, RelaPlt, GotPlt; + std::optional Plt, RelaPlt; + uint64_t GotBaseVA = 0; for (const SectionRef &Section : sections()) { Expected 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 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 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(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, uint64_t>> Result; -- cgit v1.1