11df42facSEugene Zelenko //===- ELFObjectFile.cpp - ELF object file implementation -----------------===// 2b60a18deSMichael J. Spencer // 3b60a18deSMichael J. Spencer // The LLVM Compiler Infrastructure 4b60a18deSMichael J. Spencer // 5b60a18deSMichael J. Spencer // This file is distributed under the University of Illinois Open Source 6b60a18deSMichael J. Spencer // License. See LICENSE.TXT for details. 7b60a18deSMichael J. Spencer // 8b60a18deSMichael J. Spencer //===----------------------------------------------------------------------===// 9b60a18deSMichael J. Spencer // 10c7d23ddbSEli Bendersky // Part of the ELFObjectFile class implementation. 11b60a18deSMichael J. Spencer // 12b60a18deSMichael J. Spencer //===----------------------------------------------------------------------===// 13b60a18deSMichael J. Spencer 146bda14b3SChandler Carruth #include "llvm/Object/ELFObjectFile.h" 151df42facSEugene Zelenko #include "llvm/ADT/Triple.h" 16264b5d9eSZachary Turner #include "llvm/BinaryFormat/ELF.h" 17d36fb48aSJoel Galenson #include "llvm/MC/MCInstrAnalysis.h" 181df42facSEugene Zelenko #include "llvm/MC/SubtargetFeature.h" 191df42facSEugene Zelenko #include "llvm/Object/ELF.h" 201df42facSEugene Zelenko #include "llvm/Object/ELFTypes.h" 211df42facSEugene Zelenko #include "llvm/Object/Error.h" 22b0de00d5SSam Parker #include "llvm/Support/ARMAttributeParser.h" 236bda14b3SChandler Carruth #include "llvm/Support/ARMBuildAttributes.h" 241df42facSEugene Zelenko #include "llvm/Support/Endian.h" 251df42facSEugene Zelenko #include "llvm/Support/ErrorHandling.h" 26bae14cefSMichael J. Spencer #include "llvm/Support/MathExtras.h" 27d36fb48aSJoel Galenson #include "llvm/Support/TargetRegistry.h" 281df42facSEugene Zelenko #include <algorithm> 291df42facSEugene Zelenko #include <cstddef> 301df42facSEugene Zelenko #include <cstdint> 311df42facSEugene Zelenko #include <memory> 321df42facSEugene Zelenko #include <string> 331df42facSEugene Zelenko #include <system_error> 341df42facSEugene Zelenko #include <utility> 35b60a18deSMichael J. Spencer 361df42facSEugene Zelenko using namespace llvm; 37b60a18deSMichael J. Spencer using namespace object; 38b60a18deSMichael J. Spencer 3948af1c2aSRafael Espindola ELFObjectFileBase::ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source) 4048af1c2aSRafael Espindola : ObjectFile(Type, Source) {} 41ab73774cSRafael Espindola 42ef421f9cSRafael Espindola template <class ELFT> 43ef421f9cSRafael Espindola static Expected<std::unique_ptr<ELFObjectFile<ELFT>>> 44ef421f9cSRafael Espindola createPtr(MemoryBufferRef Object) { 45ef421f9cSRafael Espindola auto Ret = ELFObjectFile<ELFT>::create(Object); 46ef421f9cSRafael Espindola if (Error E = Ret.takeError()) 47ef421f9cSRafael Espindola return std::move(E); 48ef421f9cSRafael Espindola return make_unique<ELFObjectFile<ELFT>>(std::move(*Ret)); 49ef421f9cSRafael Espindola } 50ef421f9cSRafael Espindola 5112db383eSRafael Espindola Expected<std::unique_ptr<ObjectFile>> 5248af1c2aSRafael Espindola ObjectFile::createELFObjectFile(MemoryBufferRef Obj) { 53d5a8efe7SRafael Espindola std::pair<unsigned char, unsigned char> Ident = 5448af1c2aSRafael Espindola getElfArchType(Obj.getBuffer()); 55bae14cefSMichael J. Spencer std::size_t MaxAlignment = 5648af1c2aSRafael Espindola 1ULL << countTrailingZeros(uintptr_t(Obj.getBufferStart())); 57bae14cefSMichael J. Spencer 58ac729b46SRafael Espindola if (MaxAlignment < 2) 5912db383eSRafael Espindola return createError("Insufficient alignment"); 60ac729b46SRafael Espindola 61ac729b46SRafael Espindola if (Ident.first == ELF::ELFCLASS32) { 62ac729b46SRafael Espindola if (Ident.second == ELF::ELFDATA2LSB) 63ef421f9cSRafael Espindola return createPtr<ELF32LE>(Obj); 64ac729b46SRafael Espindola else if (Ident.second == ELF::ELFDATA2MSB) 65ef421f9cSRafael Espindola return createPtr<ELF32BE>(Obj); 66692410efSRafael Espindola else 6712db383eSRafael Espindola return createError("Invalid ELF data"); 6849179ddbSAlexey Samsonov } else if (Ident.first == ELF::ELFCLASS64) { 69ac729b46SRafael Espindola if (Ident.second == ELF::ELFDATA2LSB) 70ef421f9cSRafael Espindola return createPtr<ELF64LE>(Obj); 71ac729b46SRafael Espindola else if (Ident.second == ELF::ELFDATA2MSB) 72ef421f9cSRafael Espindola return createPtr<ELF64BE>(Obj); 73ac729b46SRafael Espindola else 7412db383eSRafael Espindola return createError("Invalid ELF data"); 75ac729b46SRafael Espindola } 76ef421f9cSRafael Espindola return createError("Invalid ELF class"); 77b60a18deSMichael J. Spencer } 78b60a18deSMichael J. Spencer 79b0de00d5SSam Parker SubtargetFeatures ELFObjectFileBase::getMIPSFeatures() const { 801d14864bSDaniel Sanders SubtargetFeatures Features; 81d5f76ad3SRafael Espindola unsigned PlatformFlags = getPlatformFlags(); 821d14864bSDaniel Sanders 831d14864bSDaniel Sanders switch (PlatformFlags & ELF::EF_MIPS_ARCH) { 841d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_1: 851d14864bSDaniel Sanders break; 861d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_2: 871d14864bSDaniel Sanders Features.AddFeature("mips2"); 881d14864bSDaniel Sanders break; 891d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_3: 901d14864bSDaniel Sanders Features.AddFeature("mips3"); 911d14864bSDaniel Sanders break; 921d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_4: 931d14864bSDaniel Sanders Features.AddFeature("mips4"); 941d14864bSDaniel Sanders break; 951d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_5: 961d14864bSDaniel Sanders Features.AddFeature("mips5"); 971d14864bSDaniel Sanders break; 981d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_32: 991d14864bSDaniel Sanders Features.AddFeature("mips32"); 1001d14864bSDaniel Sanders break; 1011d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_64: 1021d14864bSDaniel Sanders Features.AddFeature("mips64"); 1031d14864bSDaniel Sanders break; 1041d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_32R2: 1051d14864bSDaniel Sanders Features.AddFeature("mips32r2"); 1061d14864bSDaniel Sanders break; 1071d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_64R2: 1081d14864bSDaniel Sanders Features.AddFeature("mips64r2"); 1091d14864bSDaniel Sanders break; 1101d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_32R6: 1111d14864bSDaniel Sanders Features.AddFeature("mips32r6"); 1121d14864bSDaniel Sanders break; 1131d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_64R6: 1141d14864bSDaniel Sanders Features.AddFeature("mips64r6"); 1151d14864bSDaniel Sanders break; 1161d14864bSDaniel Sanders default: 1171d14864bSDaniel Sanders llvm_unreachable("Unknown EF_MIPS_ARCH value"); 1181d14864bSDaniel Sanders } 1191d14864bSDaniel Sanders 1201d14864bSDaniel Sanders switch (PlatformFlags & ELF::EF_MIPS_MACH) { 1211d14864bSDaniel Sanders case ELF::EF_MIPS_MACH_NONE: 1221d14864bSDaniel Sanders // No feature associated with this value. 1231d14864bSDaniel Sanders break; 1241d14864bSDaniel Sanders case ELF::EF_MIPS_MACH_OCTEON: 1251d14864bSDaniel Sanders Features.AddFeature("cnmips"); 1261d14864bSDaniel Sanders break; 1271d14864bSDaniel Sanders default: 1281d14864bSDaniel Sanders llvm_unreachable("Unknown EF_MIPS_ARCH value"); 1291d14864bSDaniel Sanders } 1301d14864bSDaniel Sanders 1311d14864bSDaniel Sanders if (PlatformFlags & ELF::EF_MIPS_ARCH_ASE_M16) 1321d14864bSDaniel Sanders Features.AddFeature("mips16"); 1331d14864bSDaniel Sanders if (PlatformFlags & ELF::EF_MIPS_MICROMIPS) 1341d14864bSDaniel Sanders Features.AddFeature("micromips"); 1351d14864bSDaniel Sanders 1361d14864bSDaniel Sanders return Features; 1371d14864bSDaniel Sanders } 138b0de00d5SSam Parker 139b0de00d5SSam Parker SubtargetFeatures ELFObjectFileBase::getARMFeatures() const { 140b0de00d5SSam Parker SubtargetFeatures Features; 141b0de00d5SSam Parker ARMAttributeParser Attributes; 142b0de00d5SSam Parker std::error_code EC = getBuildAttributes(Attributes); 143b0de00d5SSam Parker if (EC) 144b0de00d5SSam Parker return SubtargetFeatures(); 145b0de00d5SSam Parker 146b0de00d5SSam Parker // both ARMv7-M and R have to support thumb hardware div 147b0de00d5SSam Parker bool isV7 = false; 148b0de00d5SSam Parker if (Attributes.hasAttribute(ARMBuildAttrs::CPU_arch)) 149b0de00d5SSam Parker isV7 = Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch) 150b0de00d5SSam Parker == ARMBuildAttrs::v7; 151b0de00d5SSam Parker 152b0de00d5SSam Parker if (Attributes.hasAttribute(ARMBuildAttrs::CPU_arch_profile)) { 153b0de00d5SSam Parker switch(Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch_profile)) { 154b0de00d5SSam Parker case ARMBuildAttrs::ApplicationProfile: 155b0de00d5SSam Parker Features.AddFeature("aclass"); 156b0de00d5SSam Parker break; 157b0de00d5SSam Parker case ARMBuildAttrs::RealTimeProfile: 158b0de00d5SSam Parker Features.AddFeature("rclass"); 159b0de00d5SSam Parker if (isV7) 160b0de00d5SSam Parker Features.AddFeature("hwdiv"); 161b0de00d5SSam Parker break; 162b0de00d5SSam Parker case ARMBuildAttrs::MicroControllerProfile: 163b0de00d5SSam Parker Features.AddFeature("mclass"); 164b0de00d5SSam Parker if (isV7) 165b0de00d5SSam Parker Features.AddFeature("hwdiv"); 166b0de00d5SSam Parker break; 167b0de00d5SSam Parker } 168b0de00d5SSam Parker } 169b0de00d5SSam Parker 170b0de00d5SSam Parker if (Attributes.hasAttribute(ARMBuildAttrs::THUMB_ISA_use)) { 171b0de00d5SSam Parker switch(Attributes.getAttributeValue(ARMBuildAttrs::THUMB_ISA_use)) { 172b0de00d5SSam Parker default: 173b0de00d5SSam Parker break; 174b0de00d5SSam Parker case ARMBuildAttrs::Not_Allowed: 175b0de00d5SSam Parker Features.AddFeature("thumb", false); 176b0de00d5SSam Parker Features.AddFeature("thumb2", false); 177b0de00d5SSam Parker break; 178b0de00d5SSam Parker case ARMBuildAttrs::AllowThumb32: 179b0de00d5SSam Parker Features.AddFeature("thumb2"); 180b0de00d5SSam Parker break; 181b0de00d5SSam Parker } 182b0de00d5SSam Parker } 183b0de00d5SSam Parker 184b0de00d5SSam Parker if (Attributes.hasAttribute(ARMBuildAttrs::FP_arch)) { 185b0de00d5SSam Parker switch(Attributes.getAttributeValue(ARMBuildAttrs::FP_arch)) { 186b0de00d5SSam Parker default: 187b0de00d5SSam Parker break; 188b0de00d5SSam Parker case ARMBuildAttrs::Not_Allowed: 189b0de00d5SSam Parker Features.AddFeature("vfp2", false); 190b0de00d5SSam Parker Features.AddFeature("vfp3", false); 191b0de00d5SSam Parker Features.AddFeature("vfp4", false); 192b0de00d5SSam Parker break; 193b0de00d5SSam Parker case ARMBuildAttrs::AllowFPv2: 194b0de00d5SSam Parker Features.AddFeature("vfp2"); 195b0de00d5SSam Parker break; 196b0de00d5SSam Parker case ARMBuildAttrs::AllowFPv3A: 197b0de00d5SSam Parker case ARMBuildAttrs::AllowFPv3B: 198b0de00d5SSam Parker Features.AddFeature("vfp3"); 199b0de00d5SSam Parker break; 200b0de00d5SSam Parker case ARMBuildAttrs::AllowFPv4A: 201b0de00d5SSam Parker case ARMBuildAttrs::AllowFPv4B: 202b0de00d5SSam Parker Features.AddFeature("vfp4"); 203b0de00d5SSam Parker break; 204b0de00d5SSam Parker } 205b0de00d5SSam Parker } 206b0de00d5SSam Parker 207b0de00d5SSam Parker if (Attributes.hasAttribute(ARMBuildAttrs::Advanced_SIMD_arch)) { 208b0de00d5SSam Parker switch(Attributes.getAttributeValue(ARMBuildAttrs::Advanced_SIMD_arch)) { 209b0de00d5SSam Parker default: 210b0de00d5SSam Parker break; 211b0de00d5SSam Parker case ARMBuildAttrs::Not_Allowed: 212b0de00d5SSam Parker Features.AddFeature("neon", false); 213b0de00d5SSam Parker Features.AddFeature("fp16", false); 214b0de00d5SSam Parker break; 215b0de00d5SSam Parker case ARMBuildAttrs::AllowNeon: 216b0de00d5SSam Parker Features.AddFeature("neon"); 217b0de00d5SSam Parker break; 218b0de00d5SSam Parker case ARMBuildAttrs::AllowNeon2: 219b0de00d5SSam Parker Features.AddFeature("neon"); 220b0de00d5SSam Parker Features.AddFeature("fp16"); 221b0de00d5SSam Parker break; 222b0de00d5SSam Parker } 223b0de00d5SSam Parker } 224b0de00d5SSam Parker 225b0de00d5SSam Parker if (Attributes.hasAttribute(ARMBuildAttrs::DIV_use)) { 226b0de00d5SSam Parker switch(Attributes.getAttributeValue(ARMBuildAttrs::DIV_use)) { 227b0de00d5SSam Parker default: 228b0de00d5SSam Parker break; 229b0de00d5SSam Parker case ARMBuildAttrs::DisallowDIV: 230b0de00d5SSam Parker Features.AddFeature("hwdiv", false); 231b0de00d5SSam Parker Features.AddFeature("hwdiv-arm", false); 232b0de00d5SSam Parker break; 233b0de00d5SSam Parker case ARMBuildAttrs::AllowDIVExt: 234b0de00d5SSam Parker Features.AddFeature("hwdiv"); 235b0de00d5SSam Parker Features.AddFeature("hwdiv-arm"); 236b0de00d5SSam Parker break; 237b0de00d5SSam Parker } 238b0de00d5SSam Parker } 239b0de00d5SSam Parker 240b0de00d5SSam Parker return Features; 241b0de00d5SSam Parker } 242b0de00d5SSam Parker 24353489adaSShiva Chen SubtargetFeatures ELFObjectFileBase::getRISCVFeatures() const { 24453489adaSShiva Chen SubtargetFeatures Features; 24553489adaSShiva Chen unsigned PlatformFlags = getPlatformFlags(); 24653489adaSShiva Chen 24753489adaSShiva Chen if (PlatformFlags & ELF::EF_RISCV_RVC) { 24853489adaSShiva Chen Features.AddFeature("c"); 24953489adaSShiva Chen } 25053489adaSShiva Chen 25153489adaSShiva Chen return Features; 25253489adaSShiva Chen } 25353489adaSShiva Chen 254b0de00d5SSam Parker SubtargetFeatures ELFObjectFileBase::getFeatures() const { 255b0de00d5SSam Parker switch (getEMachine()) { 256b0de00d5SSam Parker case ELF::EM_MIPS: 257b0de00d5SSam Parker return getMIPSFeatures(); 258b0de00d5SSam Parker case ELF::EM_ARM: 259b0de00d5SSam Parker return getARMFeatures(); 26053489adaSShiva Chen case ELF::EM_RISCV: 26153489adaSShiva Chen return getRISCVFeatures(); 2621d14864bSDaniel Sanders default: 2631d14864bSDaniel Sanders return SubtargetFeatures(); 2641d14864bSDaniel Sanders } 2651d14864bSDaniel Sanders } 2661d14864bSDaniel Sanders 267df7c6ef9SSam Parker // FIXME Encode from a tablegen description or target parser. 268df7c6ef9SSam Parker void ELFObjectFileBase::setARMSubArch(Triple &TheTriple) const { 269df7c6ef9SSam Parker if (TheTriple.getSubArch() != Triple::NoSubArch) 270df7c6ef9SSam Parker return; 271df7c6ef9SSam Parker 272df7c6ef9SSam Parker ARMAttributeParser Attributes; 273df7c6ef9SSam Parker std::error_code EC = getBuildAttributes(Attributes); 274df7c6ef9SSam Parker if (EC) 275df7c6ef9SSam Parker return; 276df7c6ef9SSam Parker 277df7c6ef9SSam Parker std::string Triple; 278df7c6ef9SSam Parker // Default to ARM, but use the triple if it's been set. 279a5ba4ee8SFlorian Hahn if (TheTriple.isThumb()) 280df7c6ef9SSam Parker Triple = "thumb"; 281df7c6ef9SSam Parker else 282df7c6ef9SSam Parker Triple = "arm"; 283df7c6ef9SSam Parker 284df7c6ef9SSam Parker if (Attributes.hasAttribute(ARMBuildAttrs::CPU_arch)) { 285df7c6ef9SSam Parker switch(Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch)) { 286df7c6ef9SSam Parker case ARMBuildAttrs::v4: 287df7c6ef9SSam Parker Triple += "v4"; 288df7c6ef9SSam Parker break; 289df7c6ef9SSam Parker case ARMBuildAttrs::v4T: 290df7c6ef9SSam Parker Triple += "v4t"; 291df7c6ef9SSam Parker break; 292df7c6ef9SSam Parker case ARMBuildAttrs::v5T: 293df7c6ef9SSam Parker Triple += "v5t"; 294df7c6ef9SSam Parker break; 295df7c6ef9SSam Parker case ARMBuildAttrs::v5TE: 296df7c6ef9SSam Parker Triple += "v5te"; 297df7c6ef9SSam Parker break; 298df7c6ef9SSam Parker case ARMBuildAttrs::v5TEJ: 299df7c6ef9SSam Parker Triple += "v5tej"; 300df7c6ef9SSam Parker break; 301df7c6ef9SSam Parker case ARMBuildAttrs::v6: 302df7c6ef9SSam Parker Triple += "v6"; 303df7c6ef9SSam Parker break; 304df7c6ef9SSam Parker case ARMBuildAttrs::v6KZ: 305df7c6ef9SSam Parker Triple += "v6kz"; 306df7c6ef9SSam Parker break; 307df7c6ef9SSam Parker case ARMBuildAttrs::v6T2: 308df7c6ef9SSam Parker Triple += "v6t2"; 309df7c6ef9SSam Parker break; 310df7c6ef9SSam Parker case ARMBuildAttrs::v6K: 311df7c6ef9SSam Parker Triple += "v6k"; 312df7c6ef9SSam Parker break; 313df7c6ef9SSam Parker case ARMBuildAttrs::v7: 314df7c6ef9SSam Parker Triple += "v7"; 315df7c6ef9SSam Parker break; 316df7c6ef9SSam Parker case ARMBuildAttrs::v6_M: 317df7c6ef9SSam Parker Triple += "v6m"; 318df7c6ef9SSam Parker break; 319df7c6ef9SSam Parker case ARMBuildAttrs::v6S_M: 320df7c6ef9SSam Parker Triple += "v6sm"; 321df7c6ef9SSam Parker break; 322df7c6ef9SSam Parker case ARMBuildAttrs::v7E_M: 323df7c6ef9SSam Parker Triple += "v7em"; 324df7c6ef9SSam Parker break; 325df7c6ef9SSam Parker } 326df7c6ef9SSam Parker } 327df7c6ef9SSam Parker if (!isLittleEndian()) 328df7c6ef9SSam Parker Triple += "eb"; 329df7c6ef9SSam Parker 330df7c6ef9SSam Parker TheTriple.setArchName(Triple); 331df7c6ef9SSam Parker } 332d36fb48aSJoel Galenson 333d36fb48aSJoel Galenson std::vector<std::pair<DataRefImpl, uint64_t>> 334d36fb48aSJoel Galenson ELFObjectFileBase::getPltAddresses() const { 335d36fb48aSJoel Galenson std::string Err; 336d36fb48aSJoel Galenson const auto Triple = makeTriple(); 337d36fb48aSJoel Galenson const auto *T = TargetRegistry::lookupTarget(Triple.str(), Err); 338d36fb48aSJoel Galenson if (!T) 339d36fb48aSJoel Galenson return {}; 340d36fb48aSJoel Galenson uint64_t JumpSlotReloc = 0; 341d36fb48aSJoel Galenson switch (Triple.getArch()) { 342d36fb48aSJoel Galenson case Triple::x86: 343d36fb48aSJoel Galenson JumpSlotReloc = ELF::R_386_JUMP_SLOT; 344d36fb48aSJoel Galenson break; 345d36fb48aSJoel Galenson case Triple::x86_64: 346d36fb48aSJoel Galenson JumpSlotReloc = ELF::R_X86_64_JUMP_SLOT; 347d36fb48aSJoel Galenson break; 348d36fb48aSJoel Galenson case Triple::aarch64: 349d36fb48aSJoel Galenson JumpSlotReloc = ELF::R_AARCH64_JUMP_SLOT; 350d36fb48aSJoel Galenson break; 351d36fb48aSJoel Galenson default: 352d36fb48aSJoel Galenson return {}; 353d36fb48aSJoel Galenson } 354*96cbeffaSVitaly Buka std::unique_ptr<const MCInstrInfo> MII(T->createMCInstrInfo()); 35590f976a4SJoel Galenson std::unique_ptr<const MCInstrAnalysis> MIA( 356*96cbeffaSVitaly Buka T->createMCInstrAnalysis(MII.get())); 357d36fb48aSJoel Galenson if (!MIA) 358d36fb48aSJoel Galenson return {}; 359d36fb48aSJoel Galenson Optional<SectionRef> Plt = None, RelaPlt = None, GotPlt = None; 360d36fb48aSJoel Galenson for (const SectionRef &Section : sections()) { 361d36fb48aSJoel Galenson StringRef Name; 362d36fb48aSJoel Galenson if (Section.getName(Name)) 363d36fb48aSJoel Galenson continue; 364d36fb48aSJoel Galenson if (Name == ".plt") 365d36fb48aSJoel Galenson Plt = Section; 366d36fb48aSJoel Galenson else if (Name == ".rela.plt" || Name == ".rel.plt") 367d36fb48aSJoel Galenson RelaPlt = Section; 368d36fb48aSJoel Galenson else if (Name == ".got.plt") 369d36fb48aSJoel Galenson GotPlt = Section; 370d36fb48aSJoel Galenson } 371d36fb48aSJoel Galenson if (!Plt || !RelaPlt || !GotPlt) 372d36fb48aSJoel Galenson return {}; 373d36fb48aSJoel Galenson StringRef PltContents; 374d36fb48aSJoel Galenson if (Plt->getContents(PltContents)) 375d36fb48aSJoel Galenson return {}; 376d36fb48aSJoel Galenson ArrayRef<uint8_t> PltBytes((const uint8_t *)PltContents.data(), 377d36fb48aSJoel Galenson Plt->getSize()); 378d36fb48aSJoel Galenson auto PltEntries = MIA->findPltEntries(Plt->getAddress(), PltBytes, 379d36fb48aSJoel Galenson GotPlt->getAddress(), Triple); 380d36fb48aSJoel Galenson // Build a map from GOT entry virtual address to PLT entry virtual address. 381d36fb48aSJoel Galenson DenseMap<uint64_t, uint64_t> GotToPlt; 382d36fb48aSJoel Galenson for (const auto &Entry : PltEntries) 383d36fb48aSJoel Galenson GotToPlt.insert(std::make_pair(Entry.second, Entry.first)); 384d36fb48aSJoel Galenson // Find the relocations in the dynamic relocation table that point to 385d36fb48aSJoel Galenson // locations in the GOT for which we know the corresponding PLT entry. 386d36fb48aSJoel Galenson std::vector<std::pair<DataRefImpl, uint64_t>> Result; 387d36fb48aSJoel Galenson for (const auto &Relocation : RelaPlt->relocations()) { 388d36fb48aSJoel Galenson if (Relocation.getType() != JumpSlotReloc) 389d36fb48aSJoel Galenson continue; 390d36fb48aSJoel Galenson auto PltEntryIter = GotToPlt.find(Relocation.getOffset()); 391d36fb48aSJoel Galenson if (PltEntryIter != GotToPlt.end()) 392d36fb48aSJoel Galenson Result.push_back(std::make_pair( 393d36fb48aSJoel Galenson Relocation.getSymbol()->getRawDataRefImpl(), PltEntryIter->second)); 394d36fb48aSJoel Galenson } 395d36fb48aSJoel Galenson return Result; 396d36fb48aSJoel Galenson } 397