Path: blob/main/contrib/llvm-project/llvm/lib/Object/ELFObjectFile.cpp
35232 views
//===- ELFObjectFile.cpp - ELF object file implementation -----------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// Part of the ELFObjectFile class implementation.9//10//===----------------------------------------------------------------------===//1112#include "llvm/Object/ELFObjectFile.h"13#include "llvm/BinaryFormat/ELF.h"14#include "llvm/MC/MCInstrAnalysis.h"15#include "llvm/MC/TargetRegistry.h"16#include "llvm/Object/ELF.h"17#include "llvm/Object/ELFTypes.h"18#include "llvm/Object/Error.h"19#include "llvm/Support/ARMAttributeParser.h"20#include "llvm/Support/ARMBuildAttributes.h"21#include "llvm/Support/ErrorHandling.h"22#include "llvm/Support/HexagonAttributeParser.h"23#include "llvm/Support/MathExtras.h"24#include "llvm/Support/RISCVAttributeParser.h"25#include "llvm/Support/RISCVAttributes.h"26#include "llvm/TargetParser/RISCVISAInfo.h"27#include "llvm/TargetParser/SubtargetFeature.h"28#include "llvm/TargetParser/Triple.h"29#include <algorithm>30#include <cstddef>31#include <cstdint>32#include <memory>33#include <optional>34#include <string>35#include <utility>3637using namespace llvm;38using namespace object;3940const EnumEntry<unsigned> llvm::object::ElfSymbolTypes[NumElfSymbolTypes] = {41{"None", "NOTYPE", ELF::STT_NOTYPE},42{"Object", "OBJECT", ELF::STT_OBJECT},43{"Function", "FUNC", ELF::STT_FUNC},44{"Section", "SECTION", ELF::STT_SECTION},45{"File", "FILE", ELF::STT_FILE},46{"Common", "COMMON", ELF::STT_COMMON},47{"TLS", "TLS", ELF::STT_TLS},48{"Unknown", "<unknown>: 7", 7},49{"Unknown", "<unknown>: 8", 8},50{"Unknown", "<unknown>: 9", 9},51{"GNU_IFunc", "IFUNC", ELF::STT_GNU_IFUNC},52{"OS Specific", "<OS specific>: 11", 11},53{"OS Specific", "<OS specific>: 12", 12},54{"Proc Specific", "<processor specific>: 13", 13},55{"Proc Specific", "<processor specific>: 14", 14},56{"Proc Specific", "<processor specific>: 15", 15}57};5859ELFObjectFileBase::ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source)60: ObjectFile(Type, Source) {}6162template <class ELFT>63static Expected<std::unique_ptr<ELFObjectFile<ELFT>>>64createPtr(MemoryBufferRef Object, bool InitContent) {65auto Ret = ELFObjectFile<ELFT>::create(Object, InitContent);66if (Error E = Ret.takeError())67return std::move(E);68return std::make_unique<ELFObjectFile<ELFT>>(std::move(*Ret));69}7071Expected<std::unique_ptr<ObjectFile>>72ObjectFile::createELFObjectFile(MemoryBufferRef Obj, bool InitContent) {73std::pair<unsigned char, unsigned char> Ident =74getElfArchType(Obj.getBuffer());75std::size_t MaxAlignment =761ULL << llvm::countr_zero(77reinterpret_cast<uintptr_t>(Obj.getBufferStart()));7879if (MaxAlignment < 2)80return createError("Insufficient alignment");8182if (Ident.first == ELF::ELFCLASS32) {83if (Ident.second == ELF::ELFDATA2LSB)84return createPtr<ELF32LE>(Obj, InitContent);85else if (Ident.second == ELF::ELFDATA2MSB)86return createPtr<ELF32BE>(Obj, InitContent);87else88return createError("Invalid ELF data");89} else if (Ident.first == ELF::ELFCLASS64) {90if (Ident.second == ELF::ELFDATA2LSB)91return createPtr<ELF64LE>(Obj, InitContent);92else if (Ident.second == ELF::ELFDATA2MSB)93return createPtr<ELF64BE>(Obj, InitContent);94else95return createError("Invalid ELF data");96}97return createError("Invalid ELF class");98}99100SubtargetFeatures ELFObjectFileBase::getMIPSFeatures() const {101SubtargetFeatures Features;102unsigned PlatformFlags = getPlatformFlags();103104switch (PlatformFlags & ELF::EF_MIPS_ARCH) {105case ELF::EF_MIPS_ARCH_1:106break;107case ELF::EF_MIPS_ARCH_2:108Features.AddFeature("mips2");109break;110case ELF::EF_MIPS_ARCH_3:111Features.AddFeature("mips3");112break;113case ELF::EF_MIPS_ARCH_4:114Features.AddFeature("mips4");115break;116case ELF::EF_MIPS_ARCH_5:117Features.AddFeature("mips5");118break;119case ELF::EF_MIPS_ARCH_32:120Features.AddFeature("mips32");121break;122case ELF::EF_MIPS_ARCH_64:123Features.AddFeature("mips64");124break;125case ELF::EF_MIPS_ARCH_32R2:126Features.AddFeature("mips32r2");127break;128case ELF::EF_MIPS_ARCH_64R2:129Features.AddFeature("mips64r2");130break;131case ELF::EF_MIPS_ARCH_32R6:132Features.AddFeature("mips32r6");133break;134case ELF::EF_MIPS_ARCH_64R6:135Features.AddFeature("mips64r6");136break;137default:138llvm_unreachable("Unknown EF_MIPS_ARCH value");139}140141switch (PlatformFlags & ELF::EF_MIPS_MACH) {142case ELF::EF_MIPS_MACH_NONE:143// No feature associated with this value.144break;145case ELF::EF_MIPS_MACH_OCTEON:146Features.AddFeature("cnmips");147break;148default:149llvm_unreachable("Unknown EF_MIPS_ARCH value");150}151152if (PlatformFlags & ELF::EF_MIPS_ARCH_ASE_M16)153Features.AddFeature("mips16");154if (PlatformFlags & ELF::EF_MIPS_MICROMIPS)155Features.AddFeature("micromips");156157return Features;158}159160SubtargetFeatures ELFObjectFileBase::getARMFeatures() const {161SubtargetFeatures Features;162ARMAttributeParser Attributes;163if (Error E = getBuildAttributes(Attributes)) {164consumeError(std::move(E));165return SubtargetFeatures();166}167168// both ARMv7-M and R have to support thumb hardware div169bool isV7 = false;170std::optional<unsigned> Attr =171Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch);172if (Attr)173isV7 = *Attr == ARMBuildAttrs::v7;174175Attr = Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch_profile);176if (Attr) {177switch (*Attr) {178case ARMBuildAttrs::ApplicationProfile:179Features.AddFeature("aclass");180break;181case ARMBuildAttrs::RealTimeProfile:182Features.AddFeature("rclass");183if (isV7)184Features.AddFeature("hwdiv");185break;186case ARMBuildAttrs::MicroControllerProfile:187Features.AddFeature("mclass");188if (isV7)189Features.AddFeature("hwdiv");190break;191}192}193194Attr = Attributes.getAttributeValue(ARMBuildAttrs::THUMB_ISA_use);195if (Attr) {196switch (*Attr) {197default:198break;199case ARMBuildAttrs::Not_Allowed:200Features.AddFeature("thumb", false);201Features.AddFeature("thumb2", false);202break;203case ARMBuildAttrs::AllowThumb32:204Features.AddFeature("thumb2");205break;206}207}208209Attr = Attributes.getAttributeValue(ARMBuildAttrs::FP_arch);210if (Attr) {211switch (*Attr) {212default:213break;214case ARMBuildAttrs::Not_Allowed:215Features.AddFeature("vfp2sp", false);216Features.AddFeature("vfp3d16sp", false);217Features.AddFeature("vfp4d16sp", false);218break;219case ARMBuildAttrs::AllowFPv2:220Features.AddFeature("vfp2");221break;222case ARMBuildAttrs::AllowFPv3A:223case ARMBuildAttrs::AllowFPv3B:224Features.AddFeature("vfp3");225break;226case ARMBuildAttrs::AllowFPv4A:227case ARMBuildAttrs::AllowFPv4B:228Features.AddFeature("vfp4");229break;230}231}232233Attr = Attributes.getAttributeValue(ARMBuildAttrs::Advanced_SIMD_arch);234if (Attr) {235switch (*Attr) {236default:237break;238case ARMBuildAttrs::Not_Allowed:239Features.AddFeature("neon", false);240Features.AddFeature("fp16", false);241break;242case ARMBuildAttrs::AllowNeon:243Features.AddFeature("neon");244break;245case ARMBuildAttrs::AllowNeon2:246Features.AddFeature("neon");247Features.AddFeature("fp16");248break;249}250}251252Attr = Attributes.getAttributeValue(ARMBuildAttrs::MVE_arch);253if (Attr) {254switch (*Attr) {255default:256break;257case ARMBuildAttrs::Not_Allowed:258Features.AddFeature("mve", false);259Features.AddFeature("mve.fp", false);260break;261case ARMBuildAttrs::AllowMVEInteger:262Features.AddFeature("mve.fp", false);263Features.AddFeature("mve");264break;265case ARMBuildAttrs::AllowMVEIntegerAndFloat:266Features.AddFeature("mve.fp");267break;268}269}270271Attr = Attributes.getAttributeValue(ARMBuildAttrs::DIV_use);272if (Attr) {273switch (*Attr) {274default:275break;276case ARMBuildAttrs::DisallowDIV:277Features.AddFeature("hwdiv", false);278Features.AddFeature("hwdiv-arm", false);279break;280case ARMBuildAttrs::AllowDIVExt:281Features.AddFeature("hwdiv");282Features.AddFeature("hwdiv-arm");283break;284}285}286287return Features;288}289290static std::optional<std::string> hexagonAttrToFeatureString(unsigned Attr) {291switch (Attr) {292case 5:293return "v5";294case 55:295return "v55";296case 60:297return "v60";298case 62:299return "v62";300case 65:301return "v65";302case 67:303return "v67";304case 68:305return "v68";306case 69:307return "v69";308case 71:309return "v71";310case 73:311return "v73";312default:313return {};314}315}316317SubtargetFeatures ELFObjectFileBase::getHexagonFeatures() const {318SubtargetFeatures Features;319HexagonAttributeParser Parser;320if (Error E = getBuildAttributes(Parser)) {321// Return no attributes if none can be read.322// This behavior is important for backwards compatibility.323consumeError(std::move(E));324return Features;325}326std::optional<unsigned> Attr;327328if ((Attr = Parser.getAttributeValue(HexagonAttrs::ARCH))) {329if (std::optional<std::string> FeatureString =330hexagonAttrToFeatureString(*Attr))331Features.AddFeature(*FeatureString);332}333334if ((Attr = Parser.getAttributeValue(HexagonAttrs::HVXARCH))) {335std::optional<std::string> FeatureString =336hexagonAttrToFeatureString(*Attr);337// There is no corresponding hvx arch for v5 and v55.338if (FeatureString && *Attr >= 60)339Features.AddFeature("hvx" + *FeatureString);340}341342if ((Attr = Parser.getAttributeValue(HexagonAttrs::HVXIEEEFP)))343if (*Attr)344Features.AddFeature("hvx-ieee-fp");345346if ((Attr = Parser.getAttributeValue(HexagonAttrs::HVXQFLOAT)))347if (*Attr)348Features.AddFeature("hvx-qfloat");349350if ((Attr = Parser.getAttributeValue(HexagonAttrs::ZREG)))351if (*Attr)352Features.AddFeature("zreg");353354if ((Attr = Parser.getAttributeValue(HexagonAttrs::AUDIO)))355if (*Attr)356Features.AddFeature("audio");357358if ((Attr = Parser.getAttributeValue(HexagonAttrs::CABAC)))359if (*Attr)360Features.AddFeature("cabac");361362return Features;363}364365Expected<SubtargetFeatures> ELFObjectFileBase::getRISCVFeatures() const {366SubtargetFeatures Features;367unsigned PlatformFlags = getPlatformFlags();368369if (PlatformFlags & ELF::EF_RISCV_RVC) {370Features.AddFeature("zca");371}372373RISCVAttributeParser Attributes;374if (Error E = getBuildAttributes(Attributes)) {375return std::move(E);376}377378std::optional<StringRef> Attr =379Attributes.getAttributeString(RISCVAttrs::ARCH);380if (Attr) {381auto ParseResult = RISCVISAInfo::parseNormalizedArchString(*Attr);382if (!ParseResult)383return ParseResult.takeError();384auto &ISAInfo = *ParseResult;385386if (ISAInfo->getXLen() == 32)387Features.AddFeature("64bit", false);388else if (ISAInfo->getXLen() == 64)389Features.AddFeature("64bit");390else391llvm_unreachable("XLEN should be 32 or 64.");392393Features.addFeaturesVector(ISAInfo->toFeatures());394}395396return Features;397}398399SubtargetFeatures ELFObjectFileBase::getLoongArchFeatures() const {400SubtargetFeatures Features;401402switch (getPlatformFlags() & ELF::EF_LOONGARCH_ABI_MODIFIER_MASK) {403case ELF::EF_LOONGARCH_ABI_SOFT_FLOAT:404break;405case ELF::EF_LOONGARCH_ABI_DOUBLE_FLOAT:406Features.AddFeature("d");407// D implies F according to LoongArch ISA spec.408[[fallthrough]];409case ELF::EF_LOONGARCH_ABI_SINGLE_FLOAT:410Features.AddFeature("f");411break;412}413414return Features;415}416417Expected<SubtargetFeatures> ELFObjectFileBase::getFeatures() const {418switch (getEMachine()) {419case ELF::EM_MIPS:420return getMIPSFeatures();421case ELF::EM_ARM:422return getARMFeatures();423case ELF::EM_RISCV:424return getRISCVFeatures();425case ELF::EM_LOONGARCH:426return getLoongArchFeatures();427case ELF::EM_HEXAGON:428return getHexagonFeatures();429default:430return SubtargetFeatures();431}432}433434std::optional<StringRef> ELFObjectFileBase::tryGetCPUName() const {435switch (getEMachine()) {436case ELF::EM_AMDGPU:437return getAMDGPUCPUName();438case ELF::EM_CUDA:439return getNVPTXCPUName();440case ELF::EM_PPC:441case ELF::EM_PPC64:442return StringRef("future");443default:444return std::nullopt;445}446}447448StringRef ELFObjectFileBase::getAMDGPUCPUName() const {449assert(getEMachine() == ELF::EM_AMDGPU);450unsigned CPU = getPlatformFlags() & ELF::EF_AMDGPU_MACH;451452switch (CPU) {453// Radeon HD 2000/3000 Series (R600).454case ELF::EF_AMDGPU_MACH_R600_R600:455return "r600";456case ELF::EF_AMDGPU_MACH_R600_R630:457return "r630";458case ELF::EF_AMDGPU_MACH_R600_RS880:459return "rs880";460case ELF::EF_AMDGPU_MACH_R600_RV670:461return "rv670";462463// Radeon HD 4000 Series (R700).464case ELF::EF_AMDGPU_MACH_R600_RV710:465return "rv710";466case ELF::EF_AMDGPU_MACH_R600_RV730:467return "rv730";468case ELF::EF_AMDGPU_MACH_R600_RV770:469return "rv770";470471// Radeon HD 5000 Series (Evergreen).472case ELF::EF_AMDGPU_MACH_R600_CEDAR:473return "cedar";474case ELF::EF_AMDGPU_MACH_R600_CYPRESS:475return "cypress";476case ELF::EF_AMDGPU_MACH_R600_JUNIPER:477return "juniper";478case ELF::EF_AMDGPU_MACH_R600_REDWOOD:479return "redwood";480case ELF::EF_AMDGPU_MACH_R600_SUMO:481return "sumo";482483// Radeon HD 6000 Series (Northern Islands).484case ELF::EF_AMDGPU_MACH_R600_BARTS:485return "barts";486case ELF::EF_AMDGPU_MACH_R600_CAICOS:487return "caicos";488case ELF::EF_AMDGPU_MACH_R600_CAYMAN:489return "cayman";490case ELF::EF_AMDGPU_MACH_R600_TURKS:491return "turks";492493// AMDGCN GFX6.494case ELF::EF_AMDGPU_MACH_AMDGCN_GFX600:495return "gfx600";496case ELF::EF_AMDGPU_MACH_AMDGCN_GFX601:497return "gfx601";498case ELF::EF_AMDGPU_MACH_AMDGCN_GFX602:499return "gfx602";500501// AMDGCN GFX7.502case ELF::EF_AMDGPU_MACH_AMDGCN_GFX700:503return "gfx700";504case ELF::EF_AMDGPU_MACH_AMDGCN_GFX701:505return "gfx701";506case ELF::EF_AMDGPU_MACH_AMDGCN_GFX702:507return "gfx702";508case ELF::EF_AMDGPU_MACH_AMDGCN_GFX703:509return "gfx703";510case ELF::EF_AMDGPU_MACH_AMDGCN_GFX704:511return "gfx704";512case ELF::EF_AMDGPU_MACH_AMDGCN_GFX705:513return "gfx705";514515// AMDGCN GFX8.516case ELF::EF_AMDGPU_MACH_AMDGCN_GFX801:517return "gfx801";518case ELF::EF_AMDGPU_MACH_AMDGCN_GFX802:519return "gfx802";520case ELF::EF_AMDGPU_MACH_AMDGCN_GFX803:521return "gfx803";522case ELF::EF_AMDGPU_MACH_AMDGCN_GFX805:523return "gfx805";524case ELF::EF_AMDGPU_MACH_AMDGCN_GFX810:525return "gfx810";526527// AMDGCN GFX9.528case ELF::EF_AMDGPU_MACH_AMDGCN_GFX900:529return "gfx900";530case ELF::EF_AMDGPU_MACH_AMDGCN_GFX902:531return "gfx902";532case ELF::EF_AMDGPU_MACH_AMDGCN_GFX904:533return "gfx904";534case ELF::EF_AMDGPU_MACH_AMDGCN_GFX906:535return "gfx906";536case ELF::EF_AMDGPU_MACH_AMDGCN_GFX908:537return "gfx908";538case ELF::EF_AMDGPU_MACH_AMDGCN_GFX909:539return "gfx909";540case ELF::EF_AMDGPU_MACH_AMDGCN_GFX90A:541return "gfx90a";542case ELF::EF_AMDGPU_MACH_AMDGCN_GFX90C:543return "gfx90c";544case ELF::EF_AMDGPU_MACH_AMDGCN_GFX940:545return "gfx940";546case ELF::EF_AMDGPU_MACH_AMDGCN_GFX941:547return "gfx941";548case ELF::EF_AMDGPU_MACH_AMDGCN_GFX942:549return "gfx942";550551// AMDGCN GFX10.552case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1010:553return "gfx1010";554case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1011:555return "gfx1011";556case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1012:557return "gfx1012";558case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1013:559return "gfx1013";560case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1030:561return "gfx1030";562case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1031:563return "gfx1031";564case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1032:565return "gfx1032";566case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1033:567return "gfx1033";568case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1034:569return "gfx1034";570case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1035:571return "gfx1035";572case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1036:573return "gfx1036";574575// AMDGCN GFX11.576case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1100:577return "gfx1100";578case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1101:579return "gfx1101";580case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1102:581return "gfx1102";582case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1103:583return "gfx1103";584case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1150:585return "gfx1150";586case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1151:587return "gfx1151";588case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1152:589return "gfx1152";590591// AMDGCN GFX12.592case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1200:593return "gfx1200";594case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1201:595return "gfx1201";596597// Generic AMDGCN targets598case ELF::EF_AMDGPU_MACH_AMDGCN_GFX9_GENERIC:599return "gfx9-generic";600case ELF::EF_AMDGPU_MACH_AMDGCN_GFX10_1_GENERIC:601return "gfx10-1-generic";602case ELF::EF_AMDGPU_MACH_AMDGCN_GFX10_3_GENERIC:603return "gfx10-3-generic";604case ELF::EF_AMDGPU_MACH_AMDGCN_GFX11_GENERIC:605return "gfx11-generic";606case ELF::EF_AMDGPU_MACH_AMDGCN_GFX12_GENERIC:607return "gfx12-generic";608default:609llvm_unreachable("Unknown EF_AMDGPU_MACH value");610}611}612613StringRef ELFObjectFileBase::getNVPTXCPUName() const {614assert(getEMachine() == ELF::EM_CUDA);615unsigned SM = getPlatformFlags() & ELF::EF_CUDA_SM;616617switch (SM) {618// Fermi architecture.619case ELF::EF_CUDA_SM20:620return "sm_20";621case ELF::EF_CUDA_SM21:622return "sm_21";623624// Kepler architecture.625case ELF::EF_CUDA_SM30:626return "sm_30";627case ELF::EF_CUDA_SM32:628return "sm_32";629case ELF::EF_CUDA_SM35:630return "sm_35";631case ELF::EF_CUDA_SM37:632return "sm_37";633634// Maxwell architecture.635case ELF::EF_CUDA_SM50:636return "sm_50";637case ELF::EF_CUDA_SM52:638return "sm_52";639case ELF::EF_CUDA_SM53:640return "sm_53";641642// Pascal architecture.643case ELF::EF_CUDA_SM60:644return "sm_60";645case ELF::EF_CUDA_SM61:646return "sm_61";647case ELF::EF_CUDA_SM62:648return "sm_62";649650// Volta architecture.651case ELF::EF_CUDA_SM70:652return "sm_70";653case ELF::EF_CUDA_SM72:654return "sm_72";655656// Turing architecture.657case ELF::EF_CUDA_SM75:658return "sm_75";659660// Ampere architecture.661case ELF::EF_CUDA_SM80:662return "sm_80";663case ELF::EF_CUDA_SM86:664return "sm_86";665case ELF::EF_CUDA_SM87:666return "sm_87";667668// Ada architecture.669case ELF::EF_CUDA_SM89:670return "sm_89";671672// Hopper architecture.673case ELF::EF_CUDA_SM90:674return getPlatformFlags() & ELF::EF_CUDA_ACCELERATORS ? "sm_90a" : "sm_90";675default:676llvm_unreachable("Unknown EF_CUDA_SM value");677}678}679680// FIXME Encode from a tablegen description or target parser.681void ELFObjectFileBase::setARMSubArch(Triple &TheTriple) const {682if (TheTriple.getSubArch() != Triple::NoSubArch)683return;684685ARMAttributeParser Attributes;686if (Error E = getBuildAttributes(Attributes)) {687// TODO Propagate Error.688consumeError(std::move(E));689return;690}691692std::string Triple;693// Default to ARM, but use the triple if it's been set.694if (TheTriple.isThumb())695Triple = "thumb";696else697Triple = "arm";698699std::optional<unsigned> Attr =700Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch);701if (Attr) {702switch (*Attr) {703case ARMBuildAttrs::v4:704Triple += "v4";705break;706case ARMBuildAttrs::v4T:707Triple += "v4t";708break;709case ARMBuildAttrs::v5T:710Triple += "v5t";711break;712case ARMBuildAttrs::v5TE:713Triple += "v5te";714break;715case ARMBuildAttrs::v5TEJ:716Triple += "v5tej";717break;718case ARMBuildAttrs::v6:719Triple += "v6";720break;721case ARMBuildAttrs::v6KZ:722Triple += "v6kz";723break;724case ARMBuildAttrs::v6T2:725Triple += "v6t2";726break;727case ARMBuildAttrs::v6K:728Triple += "v6k";729break;730case ARMBuildAttrs::v7: {731std::optional<unsigned> ArchProfileAttr =732Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch_profile);733if (ArchProfileAttr &&734*ArchProfileAttr == ARMBuildAttrs::MicroControllerProfile)735Triple += "v7m";736else737Triple += "v7";738break;739}740case ARMBuildAttrs::v6_M:741Triple += "v6m";742break;743case ARMBuildAttrs::v6S_M:744Triple += "v6sm";745break;746case ARMBuildAttrs::v7E_M:747Triple += "v7em";748break;749case ARMBuildAttrs::v8_A:750Triple += "v8a";751break;752case ARMBuildAttrs::v8_R:753Triple += "v8r";754break;755case ARMBuildAttrs::v8_M_Base:756Triple += "v8m.base";757break;758case ARMBuildAttrs::v8_M_Main:759Triple += "v8m.main";760break;761case ARMBuildAttrs::v8_1_M_Main:762Triple += "v8.1m.main";763break;764case ARMBuildAttrs::v9_A:765Triple += "v9a";766break;767}768}769if (!isLittleEndian())770Triple += "eb";771772TheTriple.setArchName(Triple);773}774775std::vector<ELFPltEntry> ELFObjectFileBase::getPltEntries() const {776std::string Err;777const auto Triple = makeTriple();778const auto *T = TargetRegistry::lookupTarget(Triple.str(), Err);779if (!T)780return {};781uint32_t JumpSlotReloc = 0, GlobDatReloc = 0;782switch (Triple.getArch()) {783case Triple::x86:784JumpSlotReloc = ELF::R_386_JUMP_SLOT;785GlobDatReloc = ELF::R_386_GLOB_DAT;786break;787case Triple::x86_64:788JumpSlotReloc = ELF::R_X86_64_JUMP_SLOT;789GlobDatReloc = ELF::R_X86_64_GLOB_DAT;790break;791case Triple::aarch64:792case Triple::aarch64_be:793JumpSlotReloc = ELF::R_AARCH64_JUMP_SLOT;794break;795default:796return {};797}798std::unique_ptr<const MCInstrInfo> MII(T->createMCInstrInfo());799std::unique_ptr<const MCInstrAnalysis> MIA(800T->createMCInstrAnalysis(MII.get()));801if (!MIA)802return {};803std::vector<std::pair<uint64_t, uint64_t>> PltEntries;804std::optional<SectionRef> RelaPlt, RelaDyn;805uint64_t GotBaseVA = 0;806for (const SectionRef &Section : sections()) {807Expected<StringRef> NameOrErr = Section.getName();808if (!NameOrErr) {809consumeError(NameOrErr.takeError());810continue;811}812StringRef Name = *NameOrErr;813814if (Name == ".rela.plt" || Name == ".rel.plt") {815RelaPlt = Section;816} else if (Name == ".rela.dyn" || Name == ".rel.dyn") {817RelaDyn = Section;818} else if (Name == ".got.plt") {819GotBaseVA = Section.getAddress();820} else if (Name == ".plt" || Name == ".plt.got") {821Expected<StringRef> PltContents = Section.getContents();822if (!PltContents) {823consumeError(PltContents.takeError());824return {};825}826llvm::append_range(827PltEntries,828MIA->findPltEntries(Section.getAddress(),829arrayRefFromStringRef(*PltContents), Triple));830}831}832833// Build a map from GOT entry virtual address to PLT entry virtual address.834DenseMap<uint64_t, uint64_t> GotToPlt;835for (auto [Plt, GotPlt] : PltEntries) {836uint64_t GotPltEntry = GotPlt;837// An x86-32 PIC PLT uses jmp DWORD PTR [ebx-offset]. Add838// _GLOBAL_OFFSET_TABLE_ (EBX) to get the .got.plt (or .got) entry address.839// See X86MCTargetDesc.cpp:findPltEntries for the 1 << 32 bit.840if (GotPltEntry & (uint64_t(1) << 32) && getEMachine() == ELF::EM_386)841GotPltEntry = static_cast<int32_t>(GotPltEntry) + GotBaseVA;842GotToPlt.insert(std::make_pair(GotPltEntry, Plt));843}844845// Find the relocations in the dynamic relocation table that point to846// locations in the GOT for which we know the corresponding PLT entry.847std::vector<ELFPltEntry> Result;848auto handleRels = [&](iterator_range<relocation_iterator> Rels,849uint32_t RelType, StringRef PltSec) {850for (const auto &R : Rels) {851if (R.getType() != RelType)852continue;853auto PltEntryIter = GotToPlt.find(R.getOffset());854if (PltEntryIter != GotToPlt.end()) {855symbol_iterator Sym = R.getSymbol();856if (Sym == symbol_end())857Result.push_back(858ELFPltEntry{PltSec, std::nullopt, PltEntryIter->second});859else860Result.push_back(ELFPltEntry{PltSec, Sym->getRawDataRefImpl(),861PltEntryIter->second});862}863}864};865866if (RelaPlt)867handleRels(RelaPlt->relocations(), JumpSlotReloc, ".plt");868869// If a symbol needing a PLT entry also needs a GLOB_DAT relocation, GNU ld's870// x86 port places the PLT entry in the .plt.got section.871if (RelaDyn)872handleRels(RelaDyn->relocations(), GlobDatReloc, ".plt.got");873874return Result;875}876877template <class ELFT>878Expected<std::vector<BBAddrMap>> static readBBAddrMapImpl(879const ELFFile<ELFT> &EF, std::optional<unsigned> TextSectionIndex,880std::vector<PGOAnalysisMap> *PGOAnalyses) {881using Elf_Shdr = typename ELFT::Shdr;882bool IsRelocatable = EF.getHeader().e_type == ELF::ET_REL;883std::vector<BBAddrMap> BBAddrMaps;884if (PGOAnalyses)885PGOAnalyses->clear();886887const auto &Sections = cantFail(EF.sections());888auto IsMatch = [&](const Elf_Shdr &Sec) -> Expected<bool> {889if (Sec.sh_type != ELF::SHT_LLVM_BB_ADDR_MAP &&890Sec.sh_type != ELF::SHT_LLVM_BB_ADDR_MAP_V0)891return false;892if (!TextSectionIndex)893return true;894Expected<const Elf_Shdr *> TextSecOrErr = EF.getSection(Sec.sh_link);895if (!TextSecOrErr)896return createError("unable to get the linked-to section for " +897describe(EF, Sec) + ": " +898toString(TextSecOrErr.takeError()));899assert(*TextSecOrErr >= Sections.begin() &&900"Text section pointer outside of bounds");901if (*TextSectionIndex !=902(unsigned)std::distance(Sections.begin(), *TextSecOrErr))903return false;904return true;905};906907Expected<MapVector<const Elf_Shdr *, const Elf_Shdr *>> SectionRelocMapOrErr =908EF.getSectionAndRelocations(IsMatch);909if (!SectionRelocMapOrErr)910return SectionRelocMapOrErr.takeError();911912for (auto const &[Sec, RelocSec] : *SectionRelocMapOrErr) {913if (IsRelocatable && !RelocSec)914return createError("unable to get relocation section for " +915describe(EF, *Sec));916Expected<std::vector<BBAddrMap>> BBAddrMapOrErr =917EF.decodeBBAddrMap(*Sec, RelocSec, PGOAnalyses);918if (!BBAddrMapOrErr) {919if (PGOAnalyses)920PGOAnalyses->clear();921return createError("unable to read " + describe(EF, *Sec) + ": " +922toString(BBAddrMapOrErr.takeError()));923}924std::move(BBAddrMapOrErr->begin(), BBAddrMapOrErr->end(),925std::back_inserter(BBAddrMaps));926}927if (PGOAnalyses)928assert(PGOAnalyses->size() == BBAddrMaps.size() &&929"The same number of BBAddrMaps and PGOAnalysisMaps should be "930"returned when PGO information is requested");931return BBAddrMaps;932}933934template <class ELFT>935static Expected<std::vector<VersionEntry>>936readDynsymVersionsImpl(const ELFFile<ELFT> &EF,937ELFObjectFileBase::elf_symbol_iterator_range Symbols) {938using Elf_Shdr = typename ELFT::Shdr;939const Elf_Shdr *VerSec = nullptr;940const Elf_Shdr *VerNeedSec = nullptr;941const Elf_Shdr *VerDefSec = nullptr;942// The user should ensure sections() can't fail here.943for (const Elf_Shdr &Sec : cantFail(EF.sections())) {944if (Sec.sh_type == ELF::SHT_GNU_versym)945VerSec = &Sec;946else if (Sec.sh_type == ELF::SHT_GNU_verdef)947VerDefSec = &Sec;948else if (Sec.sh_type == ELF::SHT_GNU_verneed)949VerNeedSec = &Sec;950}951if (!VerSec)952return std::vector<VersionEntry>();953954Expected<SmallVector<std::optional<VersionEntry>, 0>> MapOrErr =955EF.loadVersionMap(VerNeedSec, VerDefSec);956if (!MapOrErr)957return MapOrErr.takeError();958959std::vector<VersionEntry> Ret;960size_t I = 0;961for (const ELFSymbolRef &Sym : Symbols) {962++I;963Expected<const typename ELFT::Versym *> VerEntryOrErr =964EF.template getEntry<typename ELFT::Versym>(*VerSec, I);965if (!VerEntryOrErr)966return createError("unable to read an entry with index " + Twine(I) +967" from " + describe(EF, *VerSec) + ": " +968toString(VerEntryOrErr.takeError()));969970Expected<uint32_t> FlagsOrErr = Sym.getFlags();971if (!FlagsOrErr)972return createError("unable to read flags for symbol with index " +973Twine(I) + ": " + toString(FlagsOrErr.takeError()));974975bool IsDefault;976Expected<StringRef> VerOrErr = EF.getSymbolVersionByIndex(977(*VerEntryOrErr)->vs_index, IsDefault, *MapOrErr,978(*FlagsOrErr) & SymbolRef::SF_Undefined);979if (!VerOrErr)980return createError("unable to get a version for entry " + Twine(I) +981" of " + describe(EF, *VerSec) + ": " +982toString(VerOrErr.takeError()));983984Ret.push_back({(*VerOrErr).str(), IsDefault});985}986987return Ret;988}989990Expected<std::vector<VersionEntry>>991ELFObjectFileBase::readDynsymVersions() const {992elf_symbol_iterator_range Symbols = getDynamicSymbolIterators();993if (const auto *Obj = dyn_cast<ELF32LEObjectFile>(this))994return readDynsymVersionsImpl(Obj->getELFFile(), Symbols);995if (const auto *Obj = dyn_cast<ELF32BEObjectFile>(this))996return readDynsymVersionsImpl(Obj->getELFFile(), Symbols);997if (const auto *Obj = dyn_cast<ELF64LEObjectFile>(this))998return readDynsymVersionsImpl(Obj->getELFFile(), Symbols);999return readDynsymVersionsImpl(cast<ELF64BEObjectFile>(this)->getELFFile(),1000Symbols);1001}10021003Expected<std::vector<BBAddrMap>> ELFObjectFileBase::readBBAddrMap(1004std::optional<unsigned> TextSectionIndex,1005std::vector<PGOAnalysisMap> *PGOAnalyses) const {1006if (const auto *Obj = dyn_cast<ELF32LEObjectFile>(this))1007return readBBAddrMapImpl(Obj->getELFFile(), TextSectionIndex, PGOAnalyses);1008if (const auto *Obj = dyn_cast<ELF64LEObjectFile>(this))1009return readBBAddrMapImpl(Obj->getELFFile(), TextSectionIndex, PGOAnalyses);1010if (const auto *Obj = dyn_cast<ELF32BEObjectFile>(this))1011return readBBAddrMapImpl(Obj->getELFFile(), TextSectionIndex, PGOAnalyses);1012return readBBAddrMapImpl(cast<ELF64BEObjectFile>(this)->getELFFile(),1013TextSectionIndex, PGOAnalyses);1014}10151016StringRef ELFObjectFileBase::getCrelDecodeProblem(SectionRef Sec) const {1017auto Data = Sec.getRawDataRefImpl();1018if (const auto *Obj = dyn_cast<ELF32LEObjectFile>(this))1019return Obj->getCrelDecodeProblem(Data);1020if (const auto *Obj = dyn_cast<ELF32BEObjectFile>(this))1021return Obj->getCrelDecodeProblem(Data);1022if (const auto *Obj = dyn_cast<ELF64LEObjectFile>(this))1023return Obj->getCrelDecodeProblem(Data);1024return cast<ELF64BEObjectFile>(this)->getCrelDecodeProblem(Data);1025}102610271028