diff options
| author | Joel Galenson <jgalenson@google.com> | 2018-08-24 15:21:56 +0000 |
|---|---|---|
| committer | Joel Galenson <jgalenson@google.com> | 2018-08-24 15:21:56 +0000 |
| commit | d36fb48a274bd6c53ce289e968be4c53c189e0a7 (patch) | |
| tree | 7b990eb796bb4742421d2d4fdb0013bae3672532 /llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp | |
| parent | 954d4a2235865af388f3d8ce4dc7793ba4703139 (diff) | |
| download | bcm5719-llvm-d36fb48a274bd6c53ce289e968be4c53c189e0a7.tar.gz bcm5719-llvm-d36fb48a274bd6c53ce289e968be4c53c189e0a7.zip | |
Find PLT entries for x86, x86_64, and AArch64.
This adds a new method to ELFObjectFileBase that returns the symbols and addresses of PLT entries.
This design was suggested by pcc and eugenis in https://reviews.llvm.org/D49383.
Differential Revision: https://reviews.llvm.org/D50203
llvm-svn: 340610
Diffstat (limited to 'llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp')
| -rw-r--r-- | llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp index 7a192b72da9..b7aab91d217 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp @@ -384,6 +384,9 @@ public: const MCInst &Inst) const override; bool clearsSuperRegisters(const MCRegisterInfo &MRI, const MCInst &Inst, 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; }; bool X86MCInstrAnalysis::isDependencyBreaking(const MCSubtargetInfo &STI, @@ -510,6 +513,64 @@ bool X86MCInstrAnalysis::clearsSuperRegisters(const MCRegisterInfo &MRI, return Mask.getBoolValue(); } +static std::vector<std::pair<uint64_t, uint64_t>> +findX86PltEntries(uint64_t PltSectionVA, ArrayRef<uint8_t> PltContents, + uint64_t GotPltSectionVA) { + // 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; ) { + // Recognize a jmp. + if (PltContents[Byte] == 0xff && PltContents[Byte + 1] == 0xa3) { + // 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)); + Byte += 6; + } else if (PltContents[Byte] == 0xff && PltContents[Byte + 1] == 0x25) { + // The jmp instruction at the beginning of each PLT entry jumps to the + // immediate. + uint32_t Imm = support::endian::read32le(PltContents.data() + Byte + 2); + Result.push_back(std::make_pair(PltSectionVA + Byte, Imm)); + Byte += 6; + } else + Byte++; + } + return Result; +} + +static std::vector<std::pair<uint64_t, uint64_t>> +findX86_64PltEntries(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; ) { + // Recognize a jmp. + if (PltContents[Byte] == 0xff && PltContents[Byte + 1] == 0x25) { + // The jmp instruction at the beginning of each PLT entry jumps to the + // address of the next instruction plus the immediate. + uint32_t Imm = support::endian::read32le(PltContents.data() + Byte + 2); + Result.push_back( + std::make_pair(PltSectionVA + Byte, PltSectionVA + Byte + 6 + Imm)); + Byte += 6; + } else + Byte++; + } + 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 { + switch (TargetTriple.getArch()) { + case Triple::x86: + return findX86PltEntries(PltSectionVA, PltContents, GotPltSectionVA); + case Triple::x86_64: + return findX86_64PltEntries(PltSectionVA, PltContents); + default: + return {}; + } +} + } // end of namespace X86_MC } // end of namespace llvm |

