10b57cec5SDimitry Andric //===- ELFObjectFile.cpp - ELF object file implementation -----------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // Part of the ELFObjectFile class implementation. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "llvm/Object/ELFObjectFile.h" 140b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELF.h" 150b57cec5SDimitry Andric #include "llvm/MC/MCInstrAnalysis.h" 16349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h" 170b57cec5SDimitry Andric #include "llvm/Object/ELF.h" 180b57cec5SDimitry Andric #include "llvm/Object/ELFTypes.h" 190b57cec5SDimitry Andric #include "llvm/Object/Error.h" 200b57cec5SDimitry Andric #include "llvm/Support/ARMAttributeParser.h" 210b57cec5SDimitry Andric #include "llvm/Support/ARMBuildAttributes.h" 220b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 230b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h" 245ffd83dbSDimitry Andric #include "llvm/Support/RISCVAttributeParser.h" 255ffd83dbSDimitry Andric #include "llvm/Support/RISCVAttributes.h" 26bdd1243dSDimitry Andric #include "llvm/Support/RISCVISAInfo.h" 27*fe013be4SDimitry Andric #include "llvm/TargetParser/SubtargetFeature.h" 28*fe013be4SDimitry Andric #include "llvm/TargetParser/Triple.h" 290b57cec5SDimitry Andric #include <algorithm> 300b57cec5SDimitry Andric #include <cstddef> 310b57cec5SDimitry Andric #include <cstdint> 320b57cec5SDimitry Andric #include <memory> 33bdd1243dSDimitry Andric #include <optional> 340b57cec5SDimitry Andric #include <string> 350b57cec5SDimitry Andric #include <utility> 360b57cec5SDimitry Andric 370b57cec5SDimitry Andric using namespace llvm; 380b57cec5SDimitry Andric using namespace object; 390b57cec5SDimitry Andric 400b57cec5SDimitry Andric const EnumEntry<unsigned> llvm::object::ElfSymbolTypes[NumElfSymbolTypes] = { 410b57cec5SDimitry Andric {"None", "NOTYPE", ELF::STT_NOTYPE}, 420b57cec5SDimitry Andric {"Object", "OBJECT", ELF::STT_OBJECT}, 430b57cec5SDimitry Andric {"Function", "FUNC", ELF::STT_FUNC}, 440b57cec5SDimitry Andric {"Section", "SECTION", ELF::STT_SECTION}, 450b57cec5SDimitry Andric {"File", "FILE", ELF::STT_FILE}, 460b57cec5SDimitry Andric {"Common", "COMMON", ELF::STT_COMMON}, 470b57cec5SDimitry Andric {"TLS", "TLS", ELF::STT_TLS}, 488bcb0991SDimitry Andric {"Unknown", "<unknown>: 7", 7}, 498bcb0991SDimitry Andric {"Unknown", "<unknown>: 8", 8}, 508bcb0991SDimitry Andric {"Unknown", "<unknown>: 9", 9}, 518bcb0991SDimitry Andric {"GNU_IFunc", "IFUNC", ELF::STT_GNU_IFUNC}, 528bcb0991SDimitry Andric {"OS Specific", "<OS specific>: 11", 11}, 538bcb0991SDimitry Andric {"OS Specific", "<OS specific>: 12", 12}, 548bcb0991SDimitry Andric {"Proc Specific", "<processor specific>: 13", 13}, 558bcb0991SDimitry Andric {"Proc Specific", "<processor specific>: 14", 14}, 568bcb0991SDimitry Andric {"Proc Specific", "<processor specific>: 15", 15} 578bcb0991SDimitry Andric }; 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric ELFObjectFileBase::ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source) 600b57cec5SDimitry Andric : ObjectFile(Type, Source) {} 610b57cec5SDimitry Andric 620b57cec5SDimitry Andric template <class ELFT> 630b57cec5SDimitry Andric static Expected<std::unique_ptr<ELFObjectFile<ELFT>>> 64e8d8bef9SDimitry Andric createPtr(MemoryBufferRef Object, bool InitContent) { 65e8d8bef9SDimitry Andric auto Ret = ELFObjectFile<ELFT>::create(Object, InitContent); 660b57cec5SDimitry Andric if (Error E = Ret.takeError()) 670b57cec5SDimitry Andric return std::move(E); 688bcb0991SDimitry Andric return std::make_unique<ELFObjectFile<ELFT>>(std::move(*Ret)); 690b57cec5SDimitry Andric } 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric Expected<std::unique_ptr<ObjectFile>> 72e8d8bef9SDimitry Andric ObjectFile::createELFObjectFile(MemoryBufferRef Obj, bool InitContent) { 730b57cec5SDimitry Andric std::pair<unsigned char, unsigned char> Ident = 740b57cec5SDimitry Andric getElfArchType(Obj.getBuffer()); 750b57cec5SDimitry Andric std::size_t MaxAlignment = 76*fe013be4SDimitry Andric 1ULL << llvm::countr_zero( 77e8d8bef9SDimitry Andric reinterpret_cast<uintptr_t>(Obj.getBufferStart())); 780b57cec5SDimitry Andric 790b57cec5SDimitry Andric if (MaxAlignment < 2) 800b57cec5SDimitry Andric return createError("Insufficient alignment"); 810b57cec5SDimitry Andric 820b57cec5SDimitry Andric if (Ident.first == ELF::ELFCLASS32) { 830b57cec5SDimitry Andric if (Ident.second == ELF::ELFDATA2LSB) 84e8d8bef9SDimitry Andric return createPtr<ELF32LE>(Obj, InitContent); 850b57cec5SDimitry Andric else if (Ident.second == ELF::ELFDATA2MSB) 86e8d8bef9SDimitry Andric return createPtr<ELF32BE>(Obj, InitContent); 870b57cec5SDimitry Andric else 880b57cec5SDimitry Andric return createError("Invalid ELF data"); 890b57cec5SDimitry Andric } else if (Ident.first == ELF::ELFCLASS64) { 900b57cec5SDimitry Andric if (Ident.second == ELF::ELFDATA2LSB) 91e8d8bef9SDimitry Andric return createPtr<ELF64LE>(Obj, InitContent); 920b57cec5SDimitry Andric else if (Ident.second == ELF::ELFDATA2MSB) 93e8d8bef9SDimitry Andric return createPtr<ELF64BE>(Obj, InitContent); 940b57cec5SDimitry Andric else 950b57cec5SDimitry Andric return createError("Invalid ELF data"); 960b57cec5SDimitry Andric } 970b57cec5SDimitry Andric return createError("Invalid ELF class"); 980b57cec5SDimitry Andric } 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric SubtargetFeatures ELFObjectFileBase::getMIPSFeatures() const { 1010b57cec5SDimitry Andric SubtargetFeatures Features; 1020b57cec5SDimitry Andric unsigned PlatformFlags = getPlatformFlags(); 1030b57cec5SDimitry Andric 1040b57cec5SDimitry Andric switch (PlatformFlags & ELF::EF_MIPS_ARCH) { 1050b57cec5SDimitry Andric case ELF::EF_MIPS_ARCH_1: 1060b57cec5SDimitry Andric break; 1070b57cec5SDimitry Andric case ELF::EF_MIPS_ARCH_2: 1080b57cec5SDimitry Andric Features.AddFeature("mips2"); 1090b57cec5SDimitry Andric break; 1100b57cec5SDimitry Andric case ELF::EF_MIPS_ARCH_3: 1110b57cec5SDimitry Andric Features.AddFeature("mips3"); 1120b57cec5SDimitry Andric break; 1130b57cec5SDimitry Andric case ELF::EF_MIPS_ARCH_4: 1140b57cec5SDimitry Andric Features.AddFeature("mips4"); 1150b57cec5SDimitry Andric break; 1160b57cec5SDimitry Andric case ELF::EF_MIPS_ARCH_5: 1170b57cec5SDimitry Andric Features.AddFeature("mips5"); 1180b57cec5SDimitry Andric break; 1190b57cec5SDimitry Andric case ELF::EF_MIPS_ARCH_32: 1200b57cec5SDimitry Andric Features.AddFeature("mips32"); 1210b57cec5SDimitry Andric break; 1220b57cec5SDimitry Andric case ELF::EF_MIPS_ARCH_64: 1230b57cec5SDimitry Andric Features.AddFeature("mips64"); 1240b57cec5SDimitry Andric break; 1250b57cec5SDimitry Andric case ELF::EF_MIPS_ARCH_32R2: 1260b57cec5SDimitry Andric Features.AddFeature("mips32r2"); 1270b57cec5SDimitry Andric break; 1280b57cec5SDimitry Andric case ELF::EF_MIPS_ARCH_64R2: 1290b57cec5SDimitry Andric Features.AddFeature("mips64r2"); 1300b57cec5SDimitry Andric break; 1310b57cec5SDimitry Andric case ELF::EF_MIPS_ARCH_32R6: 1320b57cec5SDimitry Andric Features.AddFeature("mips32r6"); 1330b57cec5SDimitry Andric break; 1340b57cec5SDimitry Andric case ELF::EF_MIPS_ARCH_64R6: 1350b57cec5SDimitry Andric Features.AddFeature("mips64r6"); 1360b57cec5SDimitry Andric break; 1370b57cec5SDimitry Andric default: 1380b57cec5SDimitry Andric llvm_unreachable("Unknown EF_MIPS_ARCH value"); 1390b57cec5SDimitry Andric } 1400b57cec5SDimitry Andric 1410b57cec5SDimitry Andric switch (PlatformFlags & ELF::EF_MIPS_MACH) { 1420b57cec5SDimitry Andric case ELF::EF_MIPS_MACH_NONE: 1430b57cec5SDimitry Andric // No feature associated with this value. 1440b57cec5SDimitry Andric break; 1450b57cec5SDimitry Andric case ELF::EF_MIPS_MACH_OCTEON: 1460b57cec5SDimitry Andric Features.AddFeature("cnmips"); 1470b57cec5SDimitry Andric break; 1480b57cec5SDimitry Andric default: 1490b57cec5SDimitry Andric llvm_unreachable("Unknown EF_MIPS_ARCH value"); 1500b57cec5SDimitry Andric } 1510b57cec5SDimitry Andric 1520b57cec5SDimitry Andric if (PlatformFlags & ELF::EF_MIPS_ARCH_ASE_M16) 1530b57cec5SDimitry Andric Features.AddFeature("mips16"); 1540b57cec5SDimitry Andric if (PlatformFlags & ELF::EF_MIPS_MICROMIPS) 1550b57cec5SDimitry Andric Features.AddFeature("micromips"); 1560b57cec5SDimitry Andric 1570b57cec5SDimitry Andric return Features; 1580b57cec5SDimitry Andric } 1590b57cec5SDimitry Andric 1600b57cec5SDimitry Andric SubtargetFeatures ELFObjectFileBase::getARMFeatures() const { 1610b57cec5SDimitry Andric SubtargetFeatures Features; 1620b57cec5SDimitry Andric ARMAttributeParser Attributes; 1635ffd83dbSDimitry Andric if (Error E = getBuildAttributes(Attributes)) { 1645ffd83dbSDimitry Andric consumeError(std::move(E)); 1650b57cec5SDimitry Andric return SubtargetFeatures(); 1665ffd83dbSDimitry Andric } 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andric // both ARMv7-M and R have to support thumb hardware div 1690b57cec5SDimitry Andric bool isV7 = false; 170bdd1243dSDimitry Andric std::optional<unsigned> Attr = 1715ffd83dbSDimitry Andric Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch); 17281ad6265SDimitry Andric if (Attr) 173bdd1243dSDimitry Andric isV7 = *Attr == ARMBuildAttrs::v7; 1740b57cec5SDimitry Andric 1755ffd83dbSDimitry Andric Attr = Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch_profile); 17681ad6265SDimitry Andric if (Attr) { 177bdd1243dSDimitry Andric switch (*Attr) { 1780b57cec5SDimitry Andric case ARMBuildAttrs::ApplicationProfile: 1790b57cec5SDimitry Andric Features.AddFeature("aclass"); 1800b57cec5SDimitry Andric break; 1810b57cec5SDimitry Andric case ARMBuildAttrs::RealTimeProfile: 1820b57cec5SDimitry Andric Features.AddFeature("rclass"); 1830b57cec5SDimitry Andric if (isV7) 1840b57cec5SDimitry Andric Features.AddFeature("hwdiv"); 1850b57cec5SDimitry Andric break; 1860b57cec5SDimitry Andric case ARMBuildAttrs::MicroControllerProfile: 1870b57cec5SDimitry Andric Features.AddFeature("mclass"); 1880b57cec5SDimitry Andric if (isV7) 1890b57cec5SDimitry Andric Features.AddFeature("hwdiv"); 1900b57cec5SDimitry Andric break; 1910b57cec5SDimitry Andric } 1920b57cec5SDimitry Andric } 1930b57cec5SDimitry Andric 1945ffd83dbSDimitry Andric Attr = Attributes.getAttributeValue(ARMBuildAttrs::THUMB_ISA_use); 19581ad6265SDimitry Andric if (Attr) { 196bdd1243dSDimitry Andric switch (*Attr) { 1970b57cec5SDimitry Andric default: 1980b57cec5SDimitry Andric break; 1990b57cec5SDimitry Andric case ARMBuildAttrs::Not_Allowed: 2000b57cec5SDimitry Andric Features.AddFeature("thumb", false); 2010b57cec5SDimitry Andric Features.AddFeature("thumb2", false); 2020b57cec5SDimitry Andric break; 2030b57cec5SDimitry Andric case ARMBuildAttrs::AllowThumb32: 2040b57cec5SDimitry Andric Features.AddFeature("thumb2"); 2050b57cec5SDimitry Andric break; 2060b57cec5SDimitry Andric } 2070b57cec5SDimitry Andric } 2080b57cec5SDimitry Andric 2095ffd83dbSDimitry Andric Attr = Attributes.getAttributeValue(ARMBuildAttrs::FP_arch); 21081ad6265SDimitry Andric if (Attr) { 211bdd1243dSDimitry Andric switch (*Attr) { 2120b57cec5SDimitry Andric default: 2130b57cec5SDimitry Andric break; 2140b57cec5SDimitry Andric case ARMBuildAttrs::Not_Allowed: 2158bcb0991SDimitry Andric Features.AddFeature("vfp2sp", false); 2160b57cec5SDimitry Andric Features.AddFeature("vfp3d16sp", false); 2170b57cec5SDimitry Andric Features.AddFeature("vfp4d16sp", false); 2180b57cec5SDimitry Andric break; 2190b57cec5SDimitry Andric case ARMBuildAttrs::AllowFPv2: 2200b57cec5SDimitry Andric Features.AddFeature("vfp2"); 2210b57cec5SDimitry Andric break; 2220b57cec5SDimitry Andric case ARMBuildAttrs::AllowFPv3A: 2230b57cec5SDimitry Andric case ARMBuildAttrs::AllowFPv3B: 2240b57cec5SDimitry Andric Features.AddFeature("vfp3"); 2250b57cec5SDimitry Andric break; 2260b57cec5SDimitry Andric case ARMBuildAttrs::AllowFPv4A: 2270b57cec5SDimitry Andric case ARMBuildAttrs::AllowFPv4B: 2280b57cec5SDimitry Andric Features.AddFeature("vfp4"); 2290b57cec5SDimitry Andric break; 2300b57cec5SDimitry Andric } 2310b57cec5SDimitry Andric } 2320b57cec5SDimitry Andric 2335ffd83dbSDimitry Andric Attr = Attributes.getAttributeValue(ARMBuildAttrs::Advanced_SIMD_arch); 23481ad6265SDimitry Andric if (Attr) { 235bdd1243dSDimitry Andric switch (*Attr) { 2360b57cec5SDimitry Andric default: 2370b57cec5SDimitry Andric break; 2380b57cec5SDimitry Andric case ARMBuildAttrs::Not_Allowed: 2390b57cec5SDimitry Andric Features.AddFeature("neon", false); 2400b57cec5SDimitry Andric Features.AddFeature("fp16", false); 2410b57cec5SDimitry Andric break; 2420b57cec5SDimitry Andric case ARMBuildAttrs::AllowNeon: 2430b57cec5SDimitry Andric Features.AddFeature("neon"); 2440b57cec5SDimitry Andric break; 2450b57cec5SDimitry Andric case ARMBuildAttrs::AllowNeon2: 2460b57cec5SDimitry Andric Features.AddFeature("neon"); 2470b57cec5SDimitry Andric Features.AddFeature("fp16"); 2480b57cec5SDimitry Andric break; 2490b57cec5SDimitry Andric } 2500b57cec5SDimitry Andric } 2510b57cec5SDimitry Andric 2525ffd83dbSDimitry Andric Attr = Attributes.getAttributeValue(ARMBuildAttrs::MVE_arch); 25381ad6265SDimitry Andric if (Attr) { 254bdd1243dSDimitry Andric switch (*Attr) { 2550b57cec5SDimitry Andric default: 2560b57cec5SDimitry Andric break; 2570b57cec5SDimitry Andric case ARMBuildAttrs::Not_Allowed: 2580b57cec5SDimitry Andric Features.AddFeature("mve", false); 2590b57cec5SDimitry Andric Features.AddFeature("mve.fp", false); 2600b57cec5SDimitry Andric break; 2610b57cec5SDimitry Andric case ARMBuildAttrs::AllowMVEInteger: 2620b57cec5SDimitry Andric Features.AddFeature("mve.fp", false); 2630b57cec5SDimitry Andric Features.AddFeature("mve"); 2640b57cec5SDimitry Andric break; 2650b57cec5SDimitry Andric case ARMBuildAttrs::AllowMVEIntegerAndFloat: 2660b57cec5SDimitry Andric Features.AddFeature("mve.fp"); 2670b57cec5SDimitry Andric break; 2680b57cec5SDimitry Andric } 2690b57cec5SDimitry Andric } 2700b57cec5SDimitry Andric 2715ffd83dbSDimitry Andric Attr = Attributes.getAttributeValue(ARMBuildAttrs::DIV_use); 27281ad6265SDimitry Andric if (Attr) { 273bdd1243dSDimitry Andric switch (*Attr) { 2740b57cec5SDimitry Andric default: 2750b57cec5SDimitry Andric break; 2760b57cec5SDimitry Andric case ARMBuildAttrs::DisallowDIV: 2770b57cec5SDimitry Andric Features.AddFeature("hwdiv", false); 2780b57cec5SDimitry Andric Features.AddFeature("hwdiv-arm", false); 2790b57cec5SDimitry Andric break; 2800b57cec5SDimitry Andric case ARMBuildAttrs::AllowDIVExt: 2810b57cec5SDimitry Andric Features.AddFeature("hwdiv"); 2820b57cec5SDimitry Andric Features.AddFeature("hwdiv-arm"); 2830b57cec5SDimitry Andric break; 2840b57cec5SDimitry Andric } 2850b57cec5SDimitry Andric } 2860b57cec5SDimitry Andric 2870b57cec5SDimitry Andric return Features; 2880b57cec5SDimitry Andric } 2890b57cec5SDimitry Andric 290bdd1243dSDimitry Andric Expected<SubtargetFeatures> ELFObjectFileBase::getRISCVFeatures() const { 2910b57cec5SDimitry Andric SubtargetFeatures Features; 2920b57cec5SDimitry Andric unsigned PlatformFlags = getPlatformFlags(); 2930b57cec5SDimitry Andric 2940b57cec5SDimitry Andric if (PlatformFlags & ELF::EF_RISCV_RVC) { 2950b57cec5SDimitry Andric Features.AddFeature("c"); 2960b57cec5SDimitry Andric } 2970b57cec5SDimitry Andric 2985ffd83dbSDimitry Andric RISCVAttributeParser Attributes; 2995ffd83dbSDimitry Andric if (Error E = getBuildAttributes(Attributes)) { 300bdd1243dSDimitry Andric return std::move(E); 3015ffd83dbSDimitry Andric } 3025ffd83dbSDimitry Andric 303bdd1243dSDimitry Andric std::optional<StringRef> Attr = 304bdd1243dSDimitry Andric Attributes.getAttributeString(RISCVAttrs::ARCH); 30581ad6265SDimitry Andric if (Attr) { 3061ac55f4cSDimitry Andric auto ParseResult = RISCVISAInfo::parseNormalizedArchString(*Attr); 307bdd1243dSDimitry Andric if (!ParseResult) 308bdd1243dSDimitry Andric return ParseResult.takeError(); 309bdd1243dSDimitry Andric auto &ISAInfo = *ParseResult; 310bdd1243dSDimitry Andric 311bdd1243dSDimitry Andric if (ISAInfo->getXLen() == 32) 3125ffd83dbSDimitry Andric Features.AddFeature("64bit", false); 313bdd1243dSDimitry Andric else if (ISAInfo->getXLen() == 64) 3145ffd83dbSDimitry Andric Features.AddFeature("64bit"); 315bdd1243dSDimitry Andric else 316bdd1243dSDimitry Andric llvm_unreachable("XLEN should be 32 or 64."); 3175ffd83dbSDimitry Andric 318bdd1243dSDimitry Andric Features.addFeaturesVector(ISAInfo->toFeatureVector()); 3195ffd83dbSDimitry Andric } 3205ffd83dbSDimitry Andric 3210b57cec5SDimitry Andric return Features; 3220b57cec5SDimitry Andric } 3230b57cec5SDimitry Andric 324bdd1243dSDimitry Andric SubtargetFeatures ELFObjectFileBase::getLoongArchFeatures() const { 325bdd1243dSDimitry Andric SubtargetFeatures Features; 326bdd1243dSDimitry Andric 327bdd1243dSDimitry Andric switch (getPlatformFlags() & ELF::EF_LOONGARCH_ABI_MODIFIER_MASK) { 328bdd1243dSDimitry Andric case ELF::EF_LOONGARCH_ABI_SOFT_FLOAT: 329bdd1243dSDimitry Andric break; 330bdd1243dSDimitry Andric case ELF::EF_LOONGARCH_ABI_DOUBLE_FLOAT: 331bdd1243dSDimitry Andric Features.AddFeature("d"); 332bdd1243dSDimitry Andric // D implies F according to LoongArch ISA spec. 333bdd1243dSDimitry Andric [[fallthrough]]; 334bdd1243dSDimitry Andric case ELF::EF_LOONGARCH_ABI_SINGLE_FLOAT: 335bdd1243dSDimitry Andric Features.AddFeature("f"); 336bdd1243dSDimitry Andric break; 337bdd1243dSDimitry Andric } 338bdd1243dSDimitry Andric 339bdd1243dSDimitry Andric return Features; 340bdd1243dSDimitry Andric } 341bdd1243dSDimitry Andric 342bdd1243dSDimitry Andric Expected<SubtargetFeatures> ELFObjectFileBase::getFeatures() const { 3430b57cec5SDimitry Andric switch (getEMachine()) { 3440b57cec5SDimitry Andric case ELF::EM_MIPS: 3450b57cec5SDimitry Andric return getMIPSFeatures(); 3460b57cec5SDimitry Andric case ELF::EM_ARM: 3470b57cec5SDimitry Andric return getARMFeatures(); 3480b57cec5SDimitry Andric case ELF::EM_RISCV: 3490b57cec5SDimitry Andric return getRISCVFeatures(); 350bdd1243dSDimitry Andric case ELF::EM_LOONGARCH: 351bdd1243dSDimitry Andric return getLoongArchFeatures(); 3520b57cec5SDimitry Andric default: 3530b57cec5SDimitry Andric return SubtargetFeatures(); 3540b57cec5SDimitry Andric } 3550b57cec5SDimitry Andric } 3560b57cec5SDimitry Andric 357bdd1243dSDimitry Andric std::optional<StringRef> ELFObjectFileBase::tryGetCPUName() const { 358e8d8bef9SDimitry Andric switch (getEMachine()) { 359e8d8bef9SDimitry Andric case ELF::EM_AMDGPU: 360e8d8bef9SDimitry Andric return getAMDGPUCPUName(); 361*fe013be4SDimitry Andric case ELF::EM_PPC: 36281ad6265SDimitry Andric case ELF::EM_PPC64: 36381ad6265SDimitry Andric return StringRef("future"); 364e8d8bef9SDimitry Andric default: 365bdd1243dSDimitry Andric return std::nullopt; 366e8d8bef9SDimitry Andric } 367e8d8bef9SDimitry Andric } 368e8d8bef9SDimitry Andric 369e8d8bef9SDimitry Andric StringRef ELFObjectFileBase::getAMDGPUCPUName() const { 370e8d8bef9SDimitry Andric assert(getEMachine() == ELF::EM_AMDGPU); 371e8d8bef9SDimitry Andric unsigned CPU = getPlatformFlags() & ELF::EF_AMDGPU_MACH; 372e8d8bef9SDimitry Andric 373e8d8bef9SDimitry Andric switch (CPU) { 374e8d8bef9SDimitry Andric // Radeon HD 2000/3000 Series (R600). 375e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_R600_R600: 376e8d8bef9SDimitry Andric return "r600"; 377e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_R600_R630: 378e8d8bef9SDimitry Andric return "r630"; 379e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_R600_RS880: 380e8d8bef9SDimitry Andric return "rs880"; 381e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_R600_RV670: 382e8d8bef9SDimitry Andric return "rv670"; 383e8d8bef9SDimitry Andric 384e8d8bef9SDimitry Andric // Radeon HD 4000 Series (R700). 385e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_R600_RV710: 386e8d8bef9SDimitry Andric return "rv710"; 387e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_R600_RV730: 388e8d8bef9SDimitry Andric return "rv730"; 389e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_R600_RV770: 390e8d8bef9SDimitry Andric return "rv770"; 391e8d8bef9SDimitry Andric 392e8d8bef9SDimitry Andric // Radeon HD 5000 Series (Evergreen). 393e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_R600_CEDAR: 394e8d8bef9SDimitry Andric return "cedar"; 395e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_R600_CYPRESS: 396e8d8bef9SDimitry Andric return "cypress"; 397e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_R600_JUNIPER: 398e8d8bef9SDimitry Andric return "juniper"; 399e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_R600_REDWOOD: 400e8d8bef9SDimitry Andric return "redwood"; 401e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_R600_SUMO: 402e8d8bef9SDimitry Andric return "sumo"; 403e8d8bef9SDimitry Andric 404e8d8bef9SDimitry Andric // Radeon HD 6000 Series (Northern Islands). 405e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_R600_BARTS: 406e8d8bef9SDimitry Andric return "barts"; 407e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_R600_CAICOS: 408e8d8bef9SDimitry Andric return "caicos"; 409e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_R600_CAYMAN: 410e8d8bef9SDimitry Andric return "cayman"; 411e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_R600_TURKS: 412e8d8bef9SDimitry Andric return "turks"; 413e8d8bef9SDimitry Andric 414e8d8bef9SDimitry Andric // AMDGCN GFX6. 415e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX600: 416e8d8bef9SDimitry Andric return "gfx600"; 417e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX601: 418e8d8bef9SDimitry Andric return "gfx601"; 419e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX602: 420e8d8bef9SDimitry Andric return "gfx602"; 421e8d8bef9SDimitry Andric 422e8d8bef9SDimitry Andric // AMDGCN GFX7. 423e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX700: 424e8d8bef9SDimitry Andric return "gfx700"; 425e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX701: 426e8d8bef9SDimitry Andric return "gfx701"; 427e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX702: 428e8d8bef9SDimitry Andric return "gfx702"; 429e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX703: 430e8d8bef9SDimitry Andric return "gfx703"; 431e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX704: 432e8d8bef9SDimitry Andric return "gfx704"; 433e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX705: 434e8d8bef9SDimitry Andric return "gfx705"; 435e8d8bef9SDimitry Andric 436e8d8bef9SDimitry Andric // AMDGCN GFX8. 437e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX801: 438e8d8bef9SDimitry Andric return "gfx801"; 439e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX802: 440e8d8bef9SDimitry Andric return "gfx802"; 441e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX803: 442e8d8bef9SDimitry Andric return "gfx803"; 443e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX805: 444e8d8bef9SDimitry Andric return "gfx805"; 445e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX810: 446e8d8bef9SDimitry Andric return "gfx810"; 447e8d8bef9SDimitry Andric 448e8d8bef9SDimitry Andric // AMDGCN GFX9. 449e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX900: 450e8d8bef9SDimitry Andric return "gfx900"; 451e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX902: 452e8d8bef9SDimitry Andric return "gfx902"; 453e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX904: 454e8d8bef9SDimitry Andric return "gfx904"; 455e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX906: 456e8d8bef9SDimitry Andric return "gfx906"; 457e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX908: 458e8d8bef9SDimitry Andric return "gfx908"; 459e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX909: 460e8d8bef9SDimitry Andric return "gfx909"; 461fe6060f1SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX90A: 462fe6060f1SDimitry Andric return "gfx90a"; 463e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX90C: 464e8d8bef9SDimitry Andric return "gfx90c"; 46581ad6265SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX940: 46681ad6265SDimitry Andric return "gfx940"; 467*fe013be4SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX941: 468*fe013be4SDimitry Andric return "gfx941"; 469*fe013be4SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX942: 470*fe013be4SDimitry Andric return "gfx942"; 471e8d8bef9SDimitry Andric 472e8d8bef9SDimitry Andric // AMDGCN GFX10. 473e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1010: 474e8d8bef9SDimitry Andric return "gfx1010"; 475e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1011: 476e8d8bef9SDimitry Andric return "gfx1011"; 477e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1012: 478e8d8bef9SDimitry Andric return "gfx1012"; 479fe6060f1SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1013: 480fe6060f1SDimitry Andric return "gfx1013"; 481e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1030: 482e8d8bef9SDimitry Andric return "gfx1030"; 483e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1031: 484e8d8bef9SDimitry Andric return "gfx1031"; 485e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1032: 486e8d8bef9SDimitry Andric return "gfx1032"; 487e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1033: 488e8d8bef9SDimitry Andric return "gfx1033"; 489fe6060f1SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1034: 490fe6060f1SDimitry Andric return "gfx1034"; 491fe6060f1SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1035: 492fe6060f1SDimitry Andric return "gfx1035"; 49381ad6265SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1036: 49481ad6265SDimitry Andric return "gfx1036"; 49581ad6265SDimitry Andric 49681ad6265SDimitry Andric // AMDGCN GFX11. 49781ad6265SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1100: 49881ad6265SDimitry Andric return "gfx1100"; 49981ad6265SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1101: 50081ad6265SDimitry Andric return "gfx1101"; 50181ad6265SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1102: 50281ad6265SDimitry Andric return "gfx1102"; 50381ad6265SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1103: 50481ad6265SDimitry Andric return "gfx1103"; 505*fe013be4SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1150: 506*fe013be4SDimitry Andric return "gfx1150"; 507*fe013be4SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1151: 508*fe013be4SDimitry Andric return "gfx1151"; 509e8d8bef9SDimitry Andric default: 510e8d8bef9SDimitry Andric llvm_unreachable("Unknown EF_AMDGPU_MACH value"); 511e8d8bef9SDimitry Andric } 512e8d8bef9SDimitry Andric } 513e8d8bef9SDimitry Andric 5140b57cec5SDimitry Andric // FIXME Encode from a tablegen description or target parser. 5150b57cec5SDimitry Andric void ELFObjectFileBase::setARMSubArch(Triple &TheTriple) const { 5160b57cec5SDimitry Andric if (TheTriple.getSubArch() != Triple::NoSubArch) 5170b57cec5SDimitry Andric return; 5180b57cec5SDimitry Andric 5190b57cec5SDimitry Andric ARMAttributeParser Attributes; 5205ffd83dbSDimitry Andric if (Error E = getBuildAttributes(Attributes)) { 5215ffd83dbSDimitry Andric // TODO Propagate Error. 5225ffd83dbSDimitry Andric consumeError(std::move(E)); 5230b57cec5SDimitry Andric return; 5245ffd83dbSDimitry Andric } 5250b57cec5SDimitry Andric 5260b57cec5SDimitry Andric std::string Triple; 5270b57cec5SDimitry Andric // Default to ARM, but use the triple if it's been set. 5280b57cec5SDimitry Andric if (TheTriple.isThumb()) 5290b57cec5SDimitry Andric Triple = "thumb"; 5300b57cec5SDimitry Andric else 5310b57cec5SDimitry Andric Triple = "arm"; 5320b57cec5SDimitry Andric 533bdd1243dSDimitry Andric std::optional<unsigned> Attr = 5345ffd83dbSDimitry Andric Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch); 53581ad6265SDimitry Andric if (Attr) { 536bdd1243dSDimitry Andric switch (*Attr) { 5370b57cec5SDimitry Andric case ARMBuildAttrs::v4: 5380b57cec5SDimitry Andric Triple += "v4"; 5390b57cec5SDimitry Andric break; 5400b57cec5SDimitry Andric case ARMBuildAttrs::v4T: 5410b57cec5SDimitry Andric Triple += "v4t"; 5420b57cec5SDimitry Andric break; 5430b57cec5SDimitry Andric case ARMBuildAttrs::v5T: 5440b57cec5SDimitry Andric Triple += "v5t"; 5450b57cec5SDimitry Andric break; 5460b57cec5SDimitry Andric case ARMBuildAttrs::v5TE: 5470b57cec5SDimitry Andric Triple += "v5te"; 5480b57cec5SDimitry Andric break; 5490b57cec5SDimitry Andric case ARMBuildAttrs::v5TEJ: 5500b57cec5SDimitry Andric Triple += "v5tej"; 5510b57cec5SDimitry Andric break; 5520b57cec5SDimitry Andric case ARMBuildAttrs::v6: 5530b57cec5SDimitry Andric Triple += "v6"; 5540b57cec5SDimitry Andric break; 5550b57cec5SDimitry Andric case ARMBuildAttrs::v6KZ: 5560b57cec5SDimitry Andric Triple += "v6kz"; 5570b57cec5SDimitry Andric break; 5580b57cec5SDimitry Andric case ARMBuildAttrs::v6T2: 5590b57cec5SDimitry Andric Triple += "v6t2"; 5600b57cec5SDimitry Andric break; 5610b57cec5SDimitry Andric case ARMBuildAttrs::v6K: 5620b57cec5SDimitry Andric Triple += "v6k"; 5630b57cec5SDimitry Andric break; 564349cc55cSDimitry Andric case ARMBuildAttrs::v7: { 565bdd1243dSDimitry Andric std::optional<unsigned> ArchProfileAttr = 566349cc55cSDimitry Andric Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch_profile); 56781ad6265SDimitry Andric if (ArchProfileAttr && 568bdd1243dSDimitry Andric *ArchProfileAttr == ARMBuildAttrs::MicroControllerProfile) 569349cc55cSDimitry Andric Triple += "v7m"; 570349cc55cSDimitry Andric else 5710b57cec5SDimitry Andric Triple += "v7"; 5720b57cec5SDimitry Andric break; 573349cc55cSDimitry Andric } 5740b57cec5SDimitry Andric case ARMBuildAttrs::v6_M: 5750b57cec5SDimitry Andric Triple += "v6m"; 5760b57cec5SDimitry Andric break; 5770b57cec5SDimitry Andric case ARMBuildAttrs::v6S_M: 5780b57cec5SDimitry Andric Triple += "v6sm"; 5790b57cec5SDimitry Andric break; 5800b57cec5SDimitry Andric case ARMBuildAttrs::v7E_M: 5810b57cec5SDimitry Andric Triple += "v7em"; 5820b57cec5SDimitry Andric break; 5838bcb0991SDimitry Andric case ARMBuildAttrs::v8_A: 5848bcb0991SDimitry Andric Triple += "v8a"; 5858bcb0991SDimitry Andric break; 5868bcb0991SDimitry Andric case ARMBuildAttrs::v8_R: 5878bcb0991SDimitry Andric Triple += "v8r"; 5888bcb0991SDimitry Andric break; 5898bcb0991SDimitry Andric case ARMBuildAttrs::v8_M_Base: 5908bcb0991SDimitry Andric Triple += "v8m.base"; 5918bcb0991SDimitry Andric break; 5928bcb0991SDimitry Andric case ARMBuildAttrs::v8_M_Main: 5938bcb0991SDimitry Andric Triple += "v8m.main"; 5948bcb0991SDimitry Andric break; 5958bcb0991SDimitry Andric case ARMBuildAttrs::v8_1_M_Main: 5968bcb0991SDimitry Andric Triple += "v8.1m.main"; 5978bcb0991SDimitry Andric break; 59881ad6265SDimitry Andric case ARMBuildAttrs::v9_A: 59981ad6265SDimitry Andric Triple += "v9a"; 60081ad6265SDimitry Andric break; 6010b57cec5SDimitry Andric } 6020b57cec5SDimitry Andric } 6030b57cec5SDimitry Andric if (!isLittleEndian()) 6040b57cec5SDimitry Andric Triple += "eb"; 6050b57cec5SDimitry Andric 6060b57cec5SDimitry Andric TheTriple.setArchName(Triple); 6070b57cec5SDimitry Andric } 6080b57cec5SDimitry Andric 609*fe013be4SDimitry Andric std::vector<ELFPltEntry> ELFObjectFileBase::getPltEntries() const { 6100b57cec5SDimitry Andric std::string Err; 6110b57cec5SDimitry Andric const auto Triple = makeTriple(); 6120b57cec5SDimitry Andric const auto *T = TargetRegistry::lookupTarget(Triple.str(), Err); 6130b57cec5SDimitry Andric if (!T) 6140b57cec5SDimitry Andric return {}; 615*fe013be4SDimitry Andric uint32_t JumpSlotReloc = 0, GlobDatReloc = 0; 6160b57cec5SDimitry Andric switch (Triple.getArch()) { 6170b57cec5SDimitry Andric case Triple::x86: 6180b57cec5SDimitry Andric JumpSlotReloc = ELF::R_386_JUMP_SLOT; 619*fe013be4SDimitry Andric GlobDatReloc = ELF::R_386_GLOB_DAT; 6200b57cec5SDimitry Andric break; 6210b57cec5SDimitry Andric case Triple::x86_64: 6220b57cec5SDimitry Andric JumpSlotReloc = ELF::R_X86_64_JUMP_SLOT; 623*fe013be4SDimitry Andric GlobDatReloc = ELF::R_X86_64_GLOB_DAT; 6240b57cec5SDimitry Andric break; 6250b57cec5SDimitry Andric case Triple::aarch64: 626fe6060f1SDimitry Andric case Triple::aarch64_be: 6270b57cec5SDimitry Andric JumpSlotReloc = ELF::R_AARCH64_JUMP_SLOT; 6280b57cec5SDimitry Andric break; 6290b57cec5SDimitry Andric default: 6300b57cec5SDimitry Andric return {}; 6310b57cec5SDimitry Andric } 6320b57cec5SDimitry Andric std::unique_ptr<const MCInstrInfo> MII(T->createMCInstrInfo()); 6330b57cec5SDimitry Andric std::unique_ptr<const MCInstrAnalysis> MIA( 6340b57cec5SDimitry Andric T->createMCInstrAnalysis(MII.get())); 6350b57cec5SDimitry Andric if (!MIA) 6360b57cec5SDimitry Andric return {}; 637*fe013be4SDimitry Andric std::vector<std::pair<uint64_t, uint64_t>> PltEntries; 638*fe013be4SDimitry Andric std::optional<SectionRef> RelaPlt, RelaDyn; 639*fe013be4SDimitry Andric uint64_t GotBaseVA = 0; 6400b57cec5SDimitry Andric for (const SectionRef &Section : sections()) { 6418bcb0991SDimitry Andric Expected<StringRef> NameOrErr = Section.getName(); 6428bcb0991SDimitry Andric if (!NameOrErr) { 6438bcb0991SDimitry Andric consumeError(NameOrErr.takeError()); 6440b57cec5SDimitry Andric continue; 6458bcb0991SDimitry Andric } 6468bcb0991SDimitry Andric StringRef Name = *NameOrErr; 6478bcb0991SDimitry Andric 648*fe013be4SDimitry Andric if (Name == ".rela.plt" || Name == ".rel.plt") { 6490b57cec5SDimitry Andric RelaPlt = Section; 650*fe013be4SDimitry Andric } else if (Name == ".rela.dyn" || Name == ".rel.dyn") { 651*fe013be4SDimitry Andric RelaDyn = Section; 652*fe013be4SDimitry Andric } else if (Name == ".got.plt") { 653*fe013be4SDimitry Andric GotBaseVA = Section.getAddress(); 654*fe013be4SDimitry Andric } else if (Name == ".plt" || Name == ".plt.got") { 655*fe013be4SDimitry Andric Expected<StringRef> PltContents = Section.getContents(); 6560b57cec5SDimitry Andric if (!PltContents) { 6570b57cec5SDimitry Andric consumeError(PltContents.takeError()); 6580b57cec5SDimitry Andric return {}; 6590b57cec5SDimitry Andric } 660*fe013be4SDimitry Andric llvm::append_range( 661*fe013be4SDimitry Andric PltEntries, 662*fe013be4SDimitry Andric MIA->findPltEntries(Section.getAddress(), 663*fe013be4SDimitry Andric arrayRefFromStringRef(*PltContents), Triple)); 664*fe013be4SDimitry Andric } 665*fe013be4SDimitry Andric } 666*fe013be4SDimitry Andric 6670b57cec5SDimitry Andric // Build a map from GOT entry virtual address to PLT entry virtual address. 6680b57cec5SDimitry Andric DenseMap<uint64_t, uint64_t> GotToPlt; 669*fe013be4SDimitry Andric for (auto [Plt, GotPlt] : PltEntries) { 670*fe013be4SDimitry Andric uint64_t GotPltEntry = GotPlt; 671*fe013be4SDimitry Andric // An x86-32 PIC PLT uses jmp DWORD PTR [ebx-offset]. Add 672*fe013be4SDimitry Andric // _GLOBAL_OFFSET_TABLE_ (EBX) to get the .got.plt (or .got) entry address. 673*fe013be4SDimitry Andric // See X86MCTargetDesc.cpp:findPltEntries for the 1 << 32 bit. 674*fe013be4SDimitry Andric if (GotPltEntry & (uint64_t(1) << 32) && getEMachine() == ELF::EM_386) 675*fe013be4SDimitry Andric GotPltEntry = static_cast<int32_t>(GotPltEntry) + GotBaseVA; 676*fe013be4SDimitry Andric GotToPlt.insert(std::make_pair(GotPltEntry, Plt)); 677*fe013be4SDimitry Andric } 678*fe013be4SDimitry Andric 6790b57cec5SDimitry Andric // Find the relocations in the dynamic relocation table that point to 6800b57cec5SDimitry Andric // locations in the GOT for which we know the corresponding PLT entry. 681*fe013be4SDimitry Andric std::vector<ELFPltEntry> Result; 682*fe013be4SDimitry Andric auto handleRels = [&](iterator_range<relocation_iterator> Rels, 683*fe013be4SDimitry Andric uint32_t RelType, StringRef PltSec) { 684*fe013be4SDimitry Andric for (const auto &R : Rels) { 685*fe013be4SDimitry Andric if (R.getType() != RelType) 6860b57cec5SDimitry Andric continue; 687*fe013be4SDimitry Andric auto PltEntryIter = GotToPlt.find(R.getOffset()); 688e8d8bef9SDimitry Andric if (PltEntryIter != GotToPlt.end()) { 689*fe013be4SDimitry Andric symbol_iterator Sym = R.getSymbol(); 690e8d8bef9SDimitry Andric if (Sym == symbol_end()) 691*fe013be4SDimitry Andric Result.push_back( 692*fe013be4SDimitry Andric ELFPltEntry{PltSec, std::nullopt, PltEntryIter->second}); 693e8d8bef9SDimitry Andric else 694*fe013be4SDimitry Andric Result.push_back(ELFPltEntry{PltSec, Sym->getRawDataRefImpl(), 695*fe013be4SDimitry Andric PltEntryIter->second}); 696e8d8bef9SDimitry Andric } 6970b57cec5SDimitry Andric } 698*fe013be4SDimitry Andric }; 699*fe013be4SDimitry Andric 700*fe013be4SDimitry Andric if (RelaPlt) 701*fe013be4SDimitry Andric handleRels(RelaPlt->relocations(), JumpSlotReloc, ".plt"); 702*fe013be4SDimitry Andric 703*fe013be4SDimitry Andric // If a symbol needing a PLT entry also needs a GLOB_DAT relocation, GNU ld's 704*fe013be4SDimitry Andric // x86 port places the PLT entry in the .plt.got section. 705*fe013be4SDimitry Andric if (RelaDyn) 706*fe013be4SDimitry Andric handleRels(RelaDyn->relocations(), GlobDatReloc, ".plt.got"); 707*fe013be4SDimitry Andric 7080b57cec5SDimitry Andric return Result; 7090b57cec5SDimitry Andric } 710349cc55cSDimitry Andric 711349cc55cSDimitry Andric template <class ELFT> 712bdd1243dSDimitry Andric Expected<std::vector<BBAddrMap>> static readBBAddrMapImpl( 713bdd1243dSDimitry Andric const ELFFile<ELFT> &EF, std::optional<unsigned> TextSectionIndex) { 71481ad6265SDimitry Andric using Elf_Shdr = typename ELFT::Shdr; 715*fe013be4SDimitry Andric bool IsRelocatable = EF.getHeader().e_type == ELF::ET_REL; 71681ad6265SDimitry Andric std::vector<BBAddrMap> BBAddrMaps; 717*fe013be4SDimitry Andric 71881ad6265SDimitry Andric const auto &Sections = cantFail(EF.sections()); 719*fe013be4SDimitry Andric auto IsMatch = [&](const Elf_Shdr &Sec) -> Expected<bool> { 72081ad6265SDimitry Andric if (Sec.sh_type != ELF::SHT_LLVM_BB_ADDR_MAP && 72181ad6265SDimitry Andric Sec.sh_type != ELF::SHT_LLVM_BB_ADDR_MAP_V0) 722*fe013be4SDimitry Andric return false; 723*fe013be4SDimitry Andric if (!TextSectionIndex) 724*fe013be4SDimitry Andric return true; 72581ad6265SDimitry Andric Expected<const Elf_Shdr *> TextSecOrErr = EF.getSection(Sec.sh_link); 72681ad6265SDimitry Andric if (!TextSecOrErr) 72781ad6265SDimitry Andric return createError("unable to get the linked-to section for " + 72881ad6265SDimitry Andric describe(EF, Sec) + ": " + 72981ad6265SDimitry Andric toString(TextSecOrErr.takeError())); 73081ad6265SDimitry Andric if (*TextSectionIndex != std::distance(Sections.begin(), *TextSecOrErr)) 731*fe013be4SDimitry Andric return false; 732*fe013be4SDimitry Andric return true; 733*fe013be4SDimitry Andric }; 734*fe013be4SDimitry Andric 735*fe013be4SDimitry Andric Expected<MapVector<const Elf_Shdr *, const Elf_Shdr *>> SectionRelocMapOrErr = 736*fe013be4SDimitry Andric EF.getSectionAndRelocations(IsMatch); 737*fe013be4SDimitry Andric if (!SectionRelocMapOrErr) 738*fe013be4SDimitry Andric return SectionRelocMapOrErr.takeError(); 739*fe013be4SDimitry Andric 740*fe013be4SDimitry Andric for (auto const &[Sec, RelocSec] : *SectionRelocMapOrErr) { 741*fe013be4SDimitry Andric if (IsRelocatable && !RelocSec) 742*fe013be4SDimitry Andric return createError("unable to get relocation section for " + 743*fe013be4SDimitry Andric describe(EF, *Sec)); 744*fe013be4SDimitry Andric Expected<std::vector<BBAddrMap>> BBAddrMapOrErr = 745*fe013be4SDimitry Andric EF.decodeBBAddrMap(*Sec, RelocSec); 74681ad6265SDimitry Andric if (!BBAddrMapOrErr) 747*fe013be4SDimitry Andric return createError("unable to read " + describe(EF, *Sec) + ": " + 74881ad6265SDimitry Andric toString(BBAddrMapOrErr.takeError())); 74981ad6265SDimitry Andric std::move(BBAddrMapOrErr->begin(), BBAddrMapOrErr->end(), 75081ad6265SDimitry Andric std::back_inserter(BBAddrMaps)); 75181ad6265SDimitry Andric } 75281ad6265SDimitry Andric return BBAddrMaps; 75381ad6265SDimitry Andric } 75481ad6265SDimitry Andric 75581ad6265SDimitry Andric template <class ELFT> 756349cc55cSDimitry Andric static Expected<std::vector<VersionEntry>> 757349cc55cSDimitry Andric readDynsymVersionsImpl(const ELFFile<ELFT> &EF, 758349cc55cSDimitry Andric ELFObjectFileBase::elf_symbol_iterator_range Symbols) { 759349cc55cSDimitry Andric using Elf_Shdr = typename ELFT::Shdr; 760349cc55cSDimitry Andric const Elf_Shdr *VerSec = nullptr; 761349cc55cSDimitry Andric const Elf_Shdr *VerNeedSec = nullptr; 762349cc55cSDimitry Andric const Elf_Shdr *VerDefSec = nullptr; 763349cc55cSDimitry Andric // The user should ensure sections() can't fail here. 764349cc55cSDimitry Andric for (const Elf_Shdr &Sec : cantFail(EF.sections())) { 765349cc55cSDimitry Andric if (Sec.sh_type == ELF::SHT_GNU_versym) 766349cc55cSDimitry Andric VerSec = &Sec; 767349cc55cSDimitry Andric else if (Sec.sh_type == ELF::SHT_GNU_verdef) 768349cc55cSDimitry Andric VerDefSec = &Sec; 769349cc55cSDimitry Andric else if (Sec.sh_type == ELF::SHT_GNU_verneed) 770349cc55cSDimitry Andric VerNeedSec = &Sec; 771349cc55cSDimitry Andric } 772349cc55cSDimitry Andric if (!VerSec) 773349cc55cSDimitry Andric return std::vector<VersionEntry>(); 774349cc55cSDimitry Andric 775bdd1243dSDimitry Andric Expected<SmallVector<std::optional<VersionEntry>, 0>> MapOrErr = 776349cc55cSDimitry Andric EF.loadVersionMap(VerNeedSec, VerDefSec); 777349cc55cSDimitry Andric if (!MapOrErr) 778349cc55cSDimitry Andric return MapOrErr.takeError(); 779349cc55cSDimitry Andric 780349cc55cSDimitry Andric std::vector<VersionEntry> Ret; 781349cc55cSDimitry Andric size_t I = 0; 7824824e7fdSDimitry Andric for (const ELFSymbolRef &Sym : Symbols) { 783349cc55cSDimitry Andric ++I; 784349cc55cSDimitry Andric Expected<const typename ELFT::Versym *> VerEntryOrErr = 785349cc55cSDimitry Andric EF.template getEntry<typename ELFT::Versym>(*VerSec, I); 786349cc55cSDimitry Andric if (!VerEntryOrErr) 787349cc55cSDimitry Andric return createError("unable to read an entry with index " + Twine(I) + 788349cc55cSDimitry Andric " from " + describe(EF, *VerSec) + ": " + 789349cc55cSDimitry Andric toString(VerEntryOrErr.takeError())); 790349cc55cSDimitry Andric 7914824e7fdSDimitry Andric Expected<uint32_t> FlagsOrErr = Sym.getFlags(); 792349cc55cSDimitry Andric if (!FlagsOrErr) 793349cc55cSDimitry Andric return createError("unable to read flags for symbol with index " + 794349cc55cSDimitry Andric Twine(I) + ": " + toString(FlagsOrErr.takeError())); 795349cc55cSDimitry Andric 796349cc55cSDimitry Andric bool IsDefault; 797349cc55cSDimitry Andric Expected<StringRef> VerOrErr = EF.getSymbolVersionByIndex( 798349cc55cSDimitry Andric (*VerEntryOrErr)->vs_index, IsDefault, *MapOrErr, 799349cc55cSDimitry Andric (*FlagsOrErr) & SymbolRef::SF_Undefined); 800349cc55cSDimitry Andric if (!VerOrErr) 801349cc55cSDimitry Andric return createError("unable to get a version for entry " + Twine(I) + 802349cc55cSDimitry Andric " of " + describe(EF, *VerSec) + ": " + 803349cc55cSDimitry Andric toString(VerOrErr.takeError())); 804349cc55cSDimitry Andric 805349cc55cSDimitry Andric Ret.push_back({(*VerOrErr).str(), IsDefault}); 806349cc55cSDimitry Andric } 807349cc55cSDimitry Andric 808349cc55cSDimitry Andric return Ret; 809349cc55cSDimitry Andric } 810349cc55cSDimitry Andric 811349cc55cSDimitry Andric Expected<std::vector<VersionEntry>> 812349cc55cSDimitry Andric ELFObjectFileBase::readDynsymVersions() const { 813349cc55cSDimitry Andric elf_symbol_iterator_range Symbols = getDynamicSymbolIterators(); 814349cc55cSDimitry Andric if (const auto *Obj = dyn_cast<ELF32LEObjectFile>(this)) 815349cc55cSDimitry Andric return readDynsymVersionsImpl(Obj->getELFFile(), Symbols); 816349cc55cSDimitry Andric if (const auto *Obj = dyn_cast<ELF32BEObjectFile>(this)) 817349cc55cSDimitry Andric return readDynsymVersionsImpl(Obj->getELFFile(), Symbols); 818349cc55cSDimitry Andric if (const auto *Obj = dyn_cast<ELF64LEObjectFile>(this)) 819349cc55cSDimitry Andric return readDynsymVersionsImpl(Obj->getELFFile(), Symbols); 820349cc55cSDimitry Andric return readDynsymVersionsImpl(cast<ELF64BEObjectFile>(this)->getELFFile(), 821349cc55cSDimitry Andric Symbols); 822349cc55cSDimitry Andric } 82381ad6265SDimitry Andric 824bdd1243dSDimitry Andric Expected<std::vector<BBAddrMap>> ELFObjectFileBase::readBBAddrMap( 825bdd1243dSDimitry Andric std::optional<unsigned> TextSectionIndex) const { 82681ad6265SDimitry Andric if (const auto *Obj = dyn_cast<ELF32LEObjectFile>(this)) 82781ad6265SDimitry Andric return readBBAddrMapImpl(Obj->getELFFile(), TextSectionIndex); 82881ad6265SDimitry Andric if (const auto *Obj = dyn_cast<ELF64LEObjectFile>(this)) 82981ad6265SDimitry Andric return readBBAddrMapImpl(Obj->getELFFile(), TextSectionIndex); 83081ad6265SDimitry Andric if (const auto *Obj = dyn_cast<ELF32BEObjectFile>(this)) 83181ad6265SDimitry Andric return readBBAddrMapImpl(Obj->getELFFile(), TextSectionIndex); 832*fe013be4SDimitry Andric return readBBAddrMapImpl(cast<ELF64BEObjectFile>(this)->getELFFile(), 833*fe013be4SDimitry Andric TextSectionIndex); 83481ad6265SDimitry Andric } 835