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" 23*0fca6ea1SDimitry Andric #include "llvm/Support/HexagonAttributeParser.h" 240b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h" 255ffd83dbSDimitry Andric #include "llvm/Support/RISCVAttributeParser.h" 265ffd83dbSDimitry Andric #include "llvm/Support/RISCVAttributes.h" 27*0fca6ea1SDimitry Andric #include "llvm/TargetParser/RISCVISAInfo.h" 2806c3fb27SDimitry Andric #include "llvm/TargetParser/SubtargetFeature.h" 2906c3fb27SDimitry Andric #include "llvm/TargetParser/Triple.h" 300b57cec5SDimitry Andric #include <algorithm> 310b57cec5SDimitry Andric #include <cstddef> 320b57cec5SDimitry Andric #include <cstdint> 330b57cec5SDimitry Andric #include <memory> 34bdd1243dSDimitry Andric #include <optional> 350b57cec5SDimitry Andric #include <string> 360b57cec5SDimitry Andric #include <utility> 370b57cec5SDimitry Andric 380b57cec5SDimitry Andric using namespace llvm; 390b57cec5SDimitry Andric using namespace object; 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric const EnumEntry<unsigned> llvm::object::ElfSymbolTypes[NumElfSymbolTypes] = { 420b57cec5SDimitry Andric {"None", "NOTYPE", ELF::STT_NOTYPE}, 430b57cec5SDimitry Andric {"Object", "OBJECT", ELF::STT_OBJECT}, 440b57cec5SDimitry Andric {"Function", "FUNC", ELF::STT_FUNC}, 450b57cec5SDimitry Andric {"Section", "SECTION", ELF::STT_SECTION}, 460b57cec5SDimitry Andric {"File", "FILE", ELF::STT_FILE}, 470b57cec5SDimitry Andric {"Common", "COMMON", ELF::STT_COMMON}, 480b57cec5SDimitry Andric {"TLS", "TLS", ELF::STT_TLS}, 498bcb0991SDimitry Andric {"Unknown", "<unknown>: 7", 7}, 508bcb0991SDimitry Andric {"Unknown", "<unknown>: 8", 8}, 518bcb0991SDimitry Andric {"Unknown", "<unknown>: 9", 9}, 528bcb0991SDimitry Andric {"GNU_IFunc", "IFUNC", ELF::STT_GNU_IFUNC}, 538bcb0991SDimitry Andric {"OS Specific", "<OS specific>: 11", 11}, 548bcb0991SDimitry Andric {"OS Specific", "<OS specific>: 12", 12}, 558bcb0991SDimitry Andric {"Proc Specific", "<processor specific>: 13", 13}, 568bcb0991SDimitry Andric {"Proc Specific", "<processor specific>: 14", 14}, 578bcb0991SDimitry Andric {"Proc Specific", "<processor specific>: 15", 15} 588bcb0991SDimitry Andric }; 590b57cec5SDimitry Andric 600b57cec5SDimitry Andric ELFObjectFileBase::ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source) 610b57cec5SDimitry Andric : ObjectFile(Type, Source) {} 620b57cec5SDimitry Andric 630b57cec5SDimitry Andric template <class ELFT> 640b57cec5SDimitry Andric static Expected<std::unique_ptr<ELFObjectFile<ELFT>>> 65e8d8bef9SDimitry Andric createPtr(MemoryBufferRef Object, bool InitContent) { 66e8d8bef9SDimitry Andric auto Ret = ELFObjectFile<ELFT>::create(Object, InitContent); 670b57cec5SDimitry Andric if (Error E = Ret.takeError()) 680b57cec5SDimitry Andric return std::move(E); 698bcb0991SDimitry Andric return std::make_unique<ELFObjectFile<ELFT>>(std::move(*Ret)); 700b57cec5SDimitry Andric } 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric Expected<std::unique_ptr<ObjectFile>> 73e8d8bef9SDimitry Andric ObjectFile::createELFObjectFile(MemoryBufferRef Obj, bool InitContent) { 740b57cec5SDimitry Andric std::pair<unsigned char, unsigned char> Ident = 750b57cec5SDimitry Andric getElfArchType(Obj.getBuffer()); 760b57cec5SDimitry Andric std::size_t MaxAlignment = 7706c3fb27SDimitry Andric 1ULL << llvm::countr_zero( 78e8d8bef9SDimitry Andric reinterpret_cast<uintptr_t>(Obj.getBufferStart())); 790b57cec5SDimitry Andric 800b57cec5SDimitry Andric if (MaxAlignment < 2) 810b57cec5SDimitry Andric return createError("Insufficient alignment"); 820b57cec5SDimitry Andric 830b57cec5SDimitry Andric if (Ident.first == ELF::ELFCLASS32) { 840b57cec5SDimitry Andric if (Ident.second == ELF::ELFDATA2LSB) 85e8d8bef9SDimitry Andric return createPtr<ELF32LE>(Obj, InitContent); 860b57cec5SDimitry Andric else if (Ident.second == ELF::ELFDATA2MSB) 87e8d8bef9SDimitry Andric return createPtr<ELF32BE>(Obj, InitContent); 880b57cec5SDimitry Andric else 890b57cec5SDimitry Andric return createError("Invalid ELF data"); 900b57cec5SDimitry Andric } else if (Ident.first == ELF::ELFCLASS64) { 910b57cec5SDimitry Andric if (Ident.second == ELF::ELFDATA2LSB) 92e8d8bef9SDimitry Andric return createPtr<ELF64LE>(Obj, InitContent); 930b57cec5SDimitry Andric else if (Ident.second == ELF::ELFDATA2MSB) 94e8d8bef9SDimitry Andric return createPtr<ELF64BE>(Obj, InitContent); 950b57cec5SDimitry Andric else 960b57cec5SDimitry Andric return createError("Invalid ELF data"); 970b57cec5SDimitry Andric } 980b57cec5SDimitry Andric return createError("Invalid ELF class"); 990b57cec5SDimitry Andric } 1000b57cec5SDimitry Andric 1010b57cec5SDimitry Andric SubtargetFeatures ELFObjectFileBase::getMIPSFeatures() const { 1020b57cec5SDimitry Andric SubtargetFeatures Features; 1030b57cec5SDimitry Andric unsigned PlatformFlags = getPlatformFlags(); 1040b57cec5SDimitry Andric 1050b57cec5SDimitry Andric switch (PlatformFlags & ELF::EF_MIPS_ARCH) { 1060b57cec5SDimitry Andric case ELF::EF_MIPS_ARCH_1: 1070b57cec5SDimitry Andric break; 1080b57cec5SDimitry Andric case ELF::EF_MIPS_ARCH_2: 1090b57cec5SDimitry Andric Features.AddFeature("mips2"); 1100b57cec5SDimitry Andric break; 1110b57cec5SDimitry Andric case ELF::EF_MIPS_ARCH_3: 1120b57cec5SDimitry Andric Features.AddFeature("mips3"); 1130b57cec5SDimitry Andric break; 1140b57cec5SDimitry Andric case ELF::EF_MIPS_ARCH_4: 1150b57cec5SDimitry Andric Features.AddFeature("mips4"); 1160b57cec5SDimitry Andric break; 1170b57cec5SDimitry Andric case ELF::EF_MIPS_ARCH_5: 1180b57cec5SDimitry Andric Features.AddFeature("mips5"); 1190b57cec5SDimitry Andric break; 1200b57cec5SDimitry Andric case ELF::EF_MIPS_ARCH_32: 1210b57cec5SDimitry Andric Features.AddFeature("mips32"); 1220b57cec5SDimitry Andric break; 1230b57cec5SDimitry Andric case ELF::EF_MIPS_ARCH_64: 1240b57cec5SDimitry Andric Features.AddFeature("mips64"); 1250b57cec5SDimitry Andric break; 1260b57cec5SDimitry Andric case ELF::EF_MIPS_ARCH_32R2: 1270b57cec5SDimitry Andric Features.AddFeature("mips32r2"); 1280b57cec5SDimitry Andric break; 1290b57cec5SDimitry Andric case ELF::EF_MIPS_ARCH_64R2: 1300b57cec5SDimitry Andric Features.AddFeature("mips64r2"); 1310b57cec5SDimitry Andric break; 1320b57cec5SDimitry Andric case ELF::EF_MIPS_ARCH_32R6: 1330b57cec5SDimitry Andric Features.AddFeature("mips32r6"); 1340b57cec5SDimitry Andric break; 1350b57cec5SDimitry Andric case ELF::EF_MIPS_ARCH_64R6: 1360b57cec5SDimitry Andric Features.AddFeature("mips64r6"); 1370b57cec5SDimitry Andric break; 1380b57cec5SDimitry Andric default: 1390b57cec5SDimitry Andric llvm_unreachable("Unknown EF_MIPS_ARCH value"); 1400b57cec5SDimitry Andric } 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andric switch (PlatformFlags & ELF::EF_MIPS_MACH) { 1430b57cec5SDimitry Andric case ELF::EF_MIPS_MACH_NONE: 1440b57cec5SDimitry Andric // No feature associated with this value. 1450b57cec5SDimitry Andric break; 1460b57cec5SDimitry Andric case ELF::EF_MIPS_MACH_OCTEON: 1470b57cec5SDimitry Andric Features.AddFeature("cnmips"); 1480b57cec5SDimitry Andric break; 1490b57cec5SDimitry Andric default: 1500b57cec5SDimitry Andric llvm_unreachable("Unknown EF_MIPS_ARCH value"); 1510b57cec5SDimitry Andric } 1520b57cec5SDimitry Andric 1530b57cec5SDimitry Andric if (PlatformFlags & ELF::EF_MIPS_ARCH_ASE_M16) 1540b57cec5SDimitry Andric Features.AddFeature("mips16"); 1550b57cec5SDimitry Andric if (PlatformFlags & ELF::EF_MIPS_MICROMIPS) 1560b57cec5SDimitry Andric Features.AddFeature("micromips"); 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric return Features; 1590b57cec5SDimitry Andric } 1600b57cec5SDimitry Andric 1610b57cec5SDimitry Andric SubtargetFeatures ELFObjectFileBase::getARMFeatures() const { 1620b57cec5SDimitry Andric SubtargetFeatures Features; 1630b57cec5SDimitry Andric ARMAttributeParser Attributes; 1645ffd83dbSDimitry Andric if (Error E = getBuildAttributes(Attributes)) { 1655ffd83dbSDimitry Andric consumeError(std::move(E)); 1660b57cec5SDimitry Andric return SubtargetFeatures(); 1675ffd83dbSDimitry Andric } 1680b57cec5SDimitry Andric 1690b57cec5SDimitry Andric // both ARMv7-M and R have to support thumb hardware div 1700b57cec5SDimitry Andric bool isV7 = false; 171bdd1243dSDimitry Andric std::optional<unsigned> Attr = 1725ffd83dbSDimitry Andric Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch); 17381ad6265SDimitry Andric if (Attr) 174bdd1243dSDimitry Andric isV7 = *Attr == ARMBuildAttrs::v7; 1750b57cec5SDimitry Andric 1765ffd83dbSDimitry Andric Attr = Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch_profile); 17781ad6265SDimitry Andric if (Attr) { 178bdd1243dSDimitry Andric switch (*Attr) { 1790b57cec5SDimitry Andric case ARMBuildAttrs::ApplicationProfile: 1800b57cec5SDimitry Andric Features.AddFeature("aclass"); 1810b57cec5SDimitry Andric break; 1820b57cec5SDimitry Andric case ARMBuildAttrs::RealTimeProfile: 1830b57cec5SDimitry Andric Features.AddFeature("rclass"); 1840b57cec5SDimitry Andric if (isV7) 1850b57cec5SDimitry Andric Features.AddFeature("hwdiv"); 1860b57cec5SDimitry Andric break; 1870b57cec5SDimitry Andric case ARMBuildAttrs::MicroControllerProfile: 1880b57cec5SDimitry Andric Features.AddFeature("mclass"); 1890b57cec5SDimitry Andric if (isV7) 1900b57cec5SDimitry Andric Features.AddFeature("hwdiv"); 1910b57cec5SDimitry Andric break; 1920b57cec5SDimitry Andric } 1930b57cec5SDimitry Andric } 1940b57cec5SDimitry Andric 1955ffd83dbSDimitry Andric Attr = Attributes.getAttributeValue(ARMBuildAttrs::THUMB_ISA_use); 19681ad6265SDimitry Andric if (Attr) { 197bdd1243dSDimitry Andric switch (*Attr) { 1980b57cec5SDimitry Andric default: 1990b57cec5SDimitry Andric break; 2000b57cec5SDimitry Andric case ARMBuildAttrs::Not_Allowed: 2010b57cec5SDimitry Andric Features.AddFeature("thumb", false); 2020b57cec5SDimitry Andric Features.AddFeature("thumb2", false); 2030b57cec5SDimitry Andric break; 2040b57cec5SDimitry Andric case ARMBuildAttrs::AllowThumb32: 2050b57cec5SDimitry Andric Features.AddFeature("thumb2"); 2060b57cec5SDimitry Andric break; 2070b57cec5SDimitry Andric } 2080b57cec5SDimitry Andric } 2090b57cec5SDimitry Andric 2105ffd83dbSDimitry Andric Attr = Attributes.getAttributeValue(ARMBuildAttrs::FP_arch); 21181ad6265SDimitry Andric if (Attr) { 212bdd1243dSDimitry Andric switch (*Attr) { 2130b57cec5SDimitry Andric default: 2140b57cec5SDimitry Andric break; 2150b57cec5SDimitry Andric case ARMBuildAttrs::Not_Allowed: 2168bcb0991SDimitry Andric Features.AddFeature("vfp2sp", false); 2170b57cec5SDimitry Andric Features.AddFeature("vfp3d16sp", false); 2180b57cec5SDimitry Andric Features.AddFeature("vfp4d16sp", false); 2190b57cec5SDimitry Andric break; 2200b57cec5SDimitry Andric case ARMBuildAttrs::AllowFPv2: 2210b57cec5SDimitry Andric Features.AddFeature("vfp2"); 2220b57cec5SDimitry Andric break; 2230b57cec5SDimitry Andric case ARMBuildAttrs::AllowFPv3A: 2240b57cec5SDimitry Andric case ARMBuildAttrs::AllowFPv3B: 2250b57cec5SDimitry Andric Features.AddFeature("vfp3"); 2260b57cec5SDimitry Andric break; 2270b57cec5SDimitry Andric case ARMBuildAttrs::AllowFPv4A: 2280b57cec5SDimitry Andric case ARMBuildAttrs::AllowFPv4B: 2290b57cec5SDimitry Andric Features.AddFeature("vfp4"); 2300b57cec5SDimitry Andric break; 2310b57cec5SDimitry Andric } 2320b57cec5SDimitry Andric } 2330b57cec5SDimitry Andric 2345ffd83dbSDimitry Andric Attr = Attributes.getAttributeValue(ARMBuildAttrs::Advanced_SIMD_arch); 23581ad6265SDimitry Andric if (Attr) { 236bdd1243dSDimitry Andric switch (*Attr) { 2370b57cec5SDimitry Andric default: 2380b57cec5SDimitry Andric break; 2390b57cec5SDimitry Andric case ARMBuildAttrs::Not_Allowed: 2400b57cec5SDimitry Andric Features.AddFeature("neon", false); 2410b57cec5SDimitry Andric Features.AddFeature("fp16", false); 2420b57cec5SDimitry Andric break; 2430b57cec5SDimitry Andric case ARMBuildAttrs::AllowNeon: 2440b57cec5SDimitry Andric Features.AddFeature("neon"); 2450b57cec5SDimitry Andric break; 2460b57cec5SDimitry Andric case ARMBuildAttrs::AllowNeon2: 2470b57cec5SDimitry Andric Features.AddFeature("neon"); 2480b57cec5SDimitry Andric Features.AddFeature("fp16"); 2490b57cec5SDimitry Andric break; 2500b57cec5SDimitry Andric } 2510b57cec5SDimitry Andric } 2520b57cec5SDimitry Andric 2535ffd83dbSDimitry Andric Attr = Attributes.getAttributeValue(ARMBuildAttrs::MVE_arch); 25481ad6265SDimitry Andric if (Attr) { 255bdd1243dSDimitry Andric switch (*Attr) { 2560b57cec5SDimitry Andric default: 2570b57cec5SDimitry Andric break; 2580b57cec5SDimitry Andric case ARMBuildAttrs::Not_Allowed: 2590b57cec5SDimitry Andric Features.AddFeature("mve", false); 2600b57cec5SDimitry Andric Features.AddFeature("mve.fp", false); 2610b57cec5SDimitry Andric break; 2620b57cec5SDimitry Andric case ARMBuildAttrs::AllowMVEInteger: 2630b57cec5SDimitry Andric Features.AddFeature("mve.fp", false); 2640b57cec5SDimitry Andric Features.AddFeature("mve"); 2650b57cec5SDimitry Andric break; 2660b57cec5SDimitry Andric case ARMBuildAttrs::AllowMVEIntegerAndFloat: 2670b57cec5SDimitry Andric Features.AddFeature("mve.fp"); 2680b57cec5SDimitry Andric break; 2690b57cec5SDimitry Andric } 2700b57cec5SDimitry Andric } 2710b57cec5SDimitry Andric 2725ffd83dbSDimitry Andric Attr = Attributes.getAttributeValue(ARMBuildAttrs::DIV_use); 27381ad6265SDimitry Andric if (Attr) { 274bdd1243dSDimitry Andric switch (*Attr) { 2750b57cec5SDimitry Andric default: 2760b57cec5SDimitry Andric break; 2770b57cec5SDimitry Andric case ARMBuildAttrs::DisallowDIV: 2780b57cec5SDimitry Andric Features.AddFeature("hwdiv", false); 2790b57cec5SDimitry Andric Features.AddFeature("hwdiv-arm", false); 2800b57cec5SDimitry Andric break; 2810b57cec5SDimitry Andric case ARMBuildAttrs::AllowDIVExt: 2820b57cec5SDimitry Andric Features.AddFeature("hwdiv"); 2830b57cec5SDimitry Andric Features.AddFeature("hwdiv-arm"); 2840b57cec5SDimitry Andric break; 2850b57cec5SDimitry Andric } 2860b57cec5SDimitry Andric } 2870b57cec5SDimitry Andric 2880b57cec5SDimitry Andric return Features; 2890b57cec5SDimitry Andric } 2900b57cec5SDimitry Andric 291*0fca6ea1SDimitry Andric static std::optional<std::string> hexagonAttrToFeatureString(unsigned Attr) { 292*0fca6ea1SDimitry Andric switch (Attr) { 293*0fca6ea1SDimitry Andric case 5: 294*0fca6ea1SDimitry Andric return "v5"; 295*0fca6ea1SDimitry Andric case 55: 296*0fca6ea1SDimitry Andric return "v55"; 297*0fca6ea1SDimitry Andric case 60: 298*0fca6ea1SDimitry Andric return "v60"; 299*0fca6ea1SDimitry Andric case 62: 300*0fca6ea1SDimitry Andric return "v62"; 301*0fca6ea1SDimitry Andric case 65: 302*0fca6ea1SDimitry Andric return "v65"; 303*0fca6ea1SDimitry Andric case 67: 304*0fca6ea1SDimitry Andric return "v67"; 305*0fca6ea1SDimitry Andric case 68: 306*0fca6ea1SDimitry Andric return "v68"; 307*0fca6ea1SDimitry Andric case 69: 308*0fca6ea1SDimitry Andric return "v69"; 309*0fca6ea1SDimitry Andric case 71: 310*0fca6ea1SDimitry Andric return "v71"; 311*0fca6ea1SDimitry Andric case 73: 312*0fca6ea1SDimitry Andric return "v73"; 313*0fca6ea1SDimitry Andric default: 314*0fca6ea1SDimitry Andric return {}; 315*0fca6ea1SDimitry Andric } 316*0fca6ea1SDimitry Andric } 317*0fca6ea1SDimitry Andric 318*0fca6ea1SDimitry Andric SubtargetFeatures ELFObjectFileBase::getHexagonFeatures() const { 319*0fca6ea1SDimitry Andric SubtargetFeatures Features; 320*0fca6ea1SDimitry Andric HexagonAttributeParser Parser; 321*0fca6ea1SDimitry Andric if (Error E = getBuildAttributes(Parser)) { 322*0fca6ea1SDimitry Andric // Return no attributes if none can be read. 323*0fca6ea1SDimitry Andric // This behavior is important for backwards compatibility. 324*0fca6ea1SDimitry Andric consumeError(std::move(E)); 325*0fca6ea1SDimitry Andric return Features; 326*0fca6ea1SDimitry Andric } 327*0fca6ea1SDimitry Andric std::optional<unsigned> Attr; 328*0fca6ea1SDimitry Andric 329*0fca6ea1SDimitry Andric if ((Attr = Parser.getAttributeValue(HexagonAttrs::ARCH))) { 330*0fca6ea1SDimitry Andric if (std::optional<std::string> FeatureString = 331*0fca6ea1SDimitry Andric hexagonAttrToFeatureString(*Attr)) 332*0fca6ea1SDimitry Andric Features.AddFeature(*FeatureString); 333*0fca6ea1SDimitry Andric } 334*0fca6ea1SDimitry Andric 335*0fca6ea1SDimitry Andric if ((Attr = Parser.getAttributeValue(HexagonAttrs::HVXARCH))) { 336*0fca6ea1SDimitry Andric std::optional<std::string> FeatureString = 337*0fca6ea1SDimitry Andric hexagonAttrToFeatureString(*Attr); 338*0fca6ea1SDimitry Andric // There is no corresponding hvx arch for v5 and v55. 339*0fca6ea1SDimitry Andric if (FeatureString && *Attr >= 60) 340*0fca6ea1SDimitry Andric Features.AddFeature("hvx" + *FeatureString); 341*0fca6ea1SDimitry Andric } 342*0fca6ea1SDimitry Andric 343*0fca6ea1SDimitry Andric if ((Attr = Parser.getAttributeValue(HexagonAttrs::HVXIEEEFP))) 344*0fca6ea1SDimitry Andric if (*Attr) 345*0fca6ea1SDimitry Andric Features.AddFeature("hvx-ieee-fp"); 346*0fca6ea1SDimitry Andric 347*0fca6ea1SDimitry Andric if ((Attr = Parser.getAttributeValue(HexagonAttrs::HVXQFLOAT))) 348*0fca6ea1SDimitry Andric if (*Attr) 349*0fca6ea1SDimitry Andric Features.AddFeature("hvx-qfloat"); 350*0fca6ea1SDimitry Andric 351*0fca6ea1SDimitry Andric if ((Attr = Parser.getAttributeValue(HexagonAttrs::ZREG))) 352*0fca6ea1SDimitry Andric if (*Attr) 353*0fca6ea1SDimitry Andric Features.AddFeature("zreg"); 354*0fca6ea1SDimitry Andric 355*0fca6ea1SDimitry Andric if ((Attr = Parser.getAttributeValue(HexagonAttrs::AUDIO))) 356*0fca6ea1SDimitry Andric if (*Attr) 357*0fca6ea1SDimitry Andric Features.AddFeature("audio"); 358*0fca6ea1SDimitry Andric 359*0fca6ea1SDimitry Andric if ((Attr = Parser.getAttributeValue(HexagonAttrs::CABAC))) 360*0fca6ea1SDimitry Andric if (*Attr) 361*0fca6ea1SDimitry Andric Features.AddFeature("cabac"); 362*0fca6ea1SDimitry Andric 363*0fca6ea1SDimitry Andric return Features; 364*0fca6ea1SDimitry Andric } 365*0fca6ea1SDimitry Andric 366bdd1243dSDimitry Andric Expected<SubtargetFeatures> ELFObjectFileBase::getRISCVFeatures() const { 3670b57cec5SDimitry Andric SubtargetFeatures Features; 3680b57cec5SDimitry Andric unsigned PlatformFlags = getPlatformFlags(); 3690b57cec5SDimitry Andric 3700b57cec5SDimitry Andric if (PlatformFlags & ELF::EF_RISCV_RVC) { 371*0fca6ea1SDimitry Andric Features.AddFeature("zca"); 3720b57cec5SDimitry Andric } 3730b57cec5SDimitry Andric 3745ffd83dbSDimitry Andric RISCVAttributeParser Attributes; 3755ffd83dbSDimitry Andric if (Error E = getBuildAttributes(Attributes)) { 376bdd1243dSDimitry Andric return std::move(E); 3775ffd83dbSDimitry Andric } 3785ffd83dbSDimitry Andric 379bdd1243dSDimitry Andric std::optional<StringRef> Attr = 380bdd1243dSDimitry Andric Attributes.getAttributeString(RISCVAttrs::ARCH); 38181ad6265SDimitry Andric if (Attr) { 3821ac55f4cSDimitry Andric auto ParseResult = RISCVISAInfo::parseNormalizedArchString(*Attr); 383bdd1243dSDimitry Andric if (!ParseResult) 384bdd1243dSDimitry Andric return ParseResult.takeError(); 385bdd1243dSDimitry Andric auto &ISAInfo = *ParseResult; 386bdd1243dSDimitry Andric 387bdd1243dSDimitry Andric if (ISAInfo->getXLen() == 32) 3885ffd83dbSDimitry Andric Features.AddFeature("64bit", false); 389bdd1243dSDimitry Andric else if (ISAInfo->getXLen() == 64) 3905ffd83dbSDimitry Andric Features.AddFeature("64bit"); 391bdd1243dSDimitry Andric else 392bdd1243dSDimitry Andric llvm_unreachable("XLEN should be 32 or 64."); 3935ffd83dbSDimitry Andric 3941db9f3b2SDimitry Andric Features.addFeaturesVector(ISAInfo->toFeatures()); 3955ffd83dbSDimitry Andric } 3965ffd83dbSDimitry Andric 3970b57cec5SDimitry Andric return Features; 3980b57cec5SDimitry Andric } 3990b57cec5SDimitry Andric 400bdd1243dSDimitry Andric SubtargetFeatures ELFObjectFileBase::getLoongArchFeatures() const { 401bdd1243dSDimitry Andric SubtargetFeatures Features; 402bdd1243dSDimitry Andric 403bdd1243dSDimitry Andric switch (getPlatformFlags() & ELF::EF_LOONGARCH_ABI_MODIFIER_MASK) { 404bdd1243dSDimitry Andric case ELF::EF_LOONGARCH_ABI_SOFT_FLOAT: 405bdd1243dSDimitry Andric break; 406bdd1243dSDimitry Andric case ELF::EF_LOONGARCH_ABI_DOUBLE_FLOAT: 407bdd1243dSDimitry Andric Features.AddFeature("d"); 408bdd1243dSDimitry Andric // D implies F according to LoongArch ISA spec. 409bdd1243dSDimitry Andric [[fallthrough]]; 410bdd1243dSDimitry Andric case ELF::EF_LOONGARCH_ABI_SINGLE_FLOAT: 411bdd1243dSDimitry Andric Features.AddFeature("f"); 412bdd1243dSDimitry Andric break; 413bdd1243dSDimitry Andric } 414bdd1243dSDimitry Andric 415bdd1243dSDimitry Andric return Features; 416bdd1243dSDimitry Andric } 417bdd1243dSDimitry Andric 418bdd1243dSDimitry Andric Expected<SubtargetFeatures> ELFObjectFileBase::getFeatures() const { 4190b57cec5SDimitry Andric switch (getEMachine()) { 4200b57cec5SDimitry Andric case ELF::EM_MIPS: 4210b57cec5SDimitry Andric return getMIPSFeatures(); 4220b57cec5SDimitry Andric case ELF::EM_ARM: 4230b57cec5SDimitry Andric return getARMFeatures(); 4240b57cec5SDimitry Andric case ELF::EM_RISCV: 4250b57cec5SDimitry Andric return getRISCVFeatures(); 426bdd1243dSDimitry Andric case ELF::EM_LOONGARCH: 427bdd1243dSDimitry Andric return getLoongArchFeatures(); 428*0fca6ea1SDimitry Andric case ELF::EM_HEXAGON: 429*0fca6ea1SDimitry Andric return getHexagonFeatures(); 4300b57cec5SDimitry Andric default: 4310b57cec5SDimitry Andric return SubtargetFeatures(); 4320b57cec5SDimitry Andric } 4330b57cec5SDimitry Andric } 4340b57cec5SDimitry Andric 435bdd1243dSDimitry Andric std::optional<StringRef> ELFObjectFileBase::tryGetCPUName() const { 436e8d8bef9SDimitry Andric switch (getEMachine()) { 437e8d8bef9SDimitry Andric case ELF::EM_AMDGPU: 438e8d8bef9SDimitry Andric return getAMDGPUCPUName(); 439cb14a3feSDimitry Andric case ELF::EM_CUDA: 440cb14a3feSDimitry Andric return getNVPTXCPUName(); 44106c3fb27SDimitry Andric case ELF::EM_PPC: 44281ad6265SDimitry Andric case ELF::EM_PPC64: 44381ad6265SDimitry Andric return StringRef("future"); 444e8d8bef9SDimitry Andric default: 445bdd1243dSDimitry Andric return std::nullopt; 446e8d8bef9SDimitry Andric } 447e8d8bef9SDimitry Andric } 448e8d8bef9SDimitry Andric 449e8d8bef9SDimitry Andric StringRef ELFObjectFileBase::getAMDGPUCPUName() const { 450e8d8bef9SDimitry Andric assert(getEMachine() == ELF::EM_AMDGPU); 451e8d8bef9SDimitry Andric unsigned CPU = getPlatformFlags() & ELF::EF_AMDGPU_MACH; 452e8d8bef9SDimitry Andric 453e8d8bef9SDimitry Andric switch (CPU) { 454e8d8bef9SDimitry Andric // Radeon HD 2000/3000 Series (R600). 455e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_R600_R600: 456e8d8bef9SDimitry Andric return "r600"; 457e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_R600_R630: 458e8d8bef9SDimitry Andric return "r630"; 459e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_R600_RS880: 460e8d8bef9SDimitry Andric return "rs880"; 461e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_R600_RV670: 462e8d8bef9SDimitry Andric return "rv670"; 463e8d8bef9SDimitry Andric 464e8d8bef9SDimitry Andric // Radeon HD 4000 Series (R700). 465e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_R600_RV710: 466e8d8bef9SDimitry Andric return "rv710"; 467e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_R600_RV730: 468e8d8bef9SDimitry Andric return "rv730"; 469e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_R600_RV770: 470e8d8bef9SDimitry Andric return "rv770"; 471e8d8bef9SDimitry Andric 472e8d8bef9SDimitry Andric // Radeon HD 5000 Series (Evergreen). 473e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_R600_CEDAR: 474e8d8bef9SDimitry Andric return "cedar"; 475e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_R600_CYPRESS: 476e8d8bef9SDimitry Andric return "cypress"; 477e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_R600_JUNIPER: 478e8d8bef9SDimitry Andric return "juniper"; 479e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_R600_REDWOOD: 480e8d8bef9SDimitry Andric return "redwood"; 481e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_R600_SUMO: 482e8d8bef9SDimitry Andric return "sumo"; 483e8d8bef9SDimitry Andric 484e8d8bef9SDimitry Andric // Radeon HD 6000 Series (Northern Islands). 485e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_R600_BARTS: 486e8d8bef9SDimitry Andric return "barts"; 487e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_R600_CAICOS: 488e8d8bef9SDimitry Andric return "caicos"; 489e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_R600_CAYMAN: 490e8d8bef9SDimitry Andric return "cayman"; 491e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_R600_TURKS: 492e8d8bef9SDimitry Andric return "turks"; 493e8d8bef9SDimitry Andric 494e8d8bef9SDimitry Andric // AMDGCN GFX6. 495e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX600: 496e8d8bef9SDimitry Andric return "gfx600"; 497e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX601: 498e8d8bef9SDimitry Andric return "gfx601"; 499e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX602: 500e8d8bef9SDimitry Andric return "gfx602"; 501e8d8bef9SDimitry Andric 502e8d8bef9SDimitry Andric // AMDGCN GFX7. 503e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX700: 504e8d8bef9SDimitry Andric return "gfx700"; 505e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX701: 506e8d8bef9SDimitry Andric return "gfx701"; 507e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX702: 508e8d8bef9SDimitry Andric return "gfx702"; 509e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX703: 510e8d8bef9SDimitry Andric return "gfx703"; 511e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX704: 512e8d8bef9SDimitry Andric return "gfx704"; 513e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX705: 514e8d8bef9SDimitry Andric return "gfx705"; 515e8d8bef9SDimitry Andric 516e8d8bef9SDimitry Andric // AMDGCN GFX8. 517e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX801: 518e8d8bef9SDimitry Andric return "gfx801"; 519e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX802: 520e8d8bef9SDimitry Andric return "gfx802"; 521e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX803: 522e8d8bef9SDimitry Andric return "gfx803"; 523e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX805: 524e8d8bef9SDimitry Andric return "gfx805"; 525e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX810: 526e8d8bef9SDimitry Andric return "gfx810"; 527e8d8bef9SDimitry Andric 528e8d8bef9SDimitry Andric // AMDGCN GFX9. 529e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX900: 530e8d8bef9SDimitry Andric return "gfx900"; 531e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX902: 532e8d8bef9SDimitry Andric return "gfx902"; 533e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX904: 534e8d8bef9SDimitry Andric return "gfx904"; 535e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX906: 536e8d8bef9SDimitry Andric return "gfx906"; 537e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX908: 538e8d8bef9SDimitry Andric return "gfx908"; 539e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX909: 540e8d8bef9SDimitry Andric return "gfx909"; 541fe6060f1SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX90A: 542fe6060f1SDimitry Andric return "gfx90a"; 543e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX90C: 544e8d8bef9SDimitry Andric return "gfx90c"; 54581ad6265SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX940: 54681ad6265SDimitry Andric return "gfx940"; 54706c3fb27SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX941: 54806c3fb27SDimitry Andric return "gfx941"; 54906c3fb27SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX942: 55006c3fb27SDimitry Andric return "gfx942"; 551e8d8bef9SDimitry Andric 552e8d8bef9SDimitry Andric // AMDGCN GFX10. 553e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1010: 554e8d8bef9SDimitry Andric return "gfx1010"; 555e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1011: 556e8d8bef9SDimitry Andric return "gfx1011"; 557e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1012: 558e8d8bef9SDimitry Andric return "gfx1012"; 559fe6060f1SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1013: 560fe6060f1SDimitry Andric return "gfx1013"; 561e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1030: 562e8d8bef9SDimitry Andric return "gfx1030"; 563e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1031: 564e8d8bef9SDimitry Andric return "gfx1031"; 565e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1032: 566e8d8bef9SDimitry Andric return "gfx1032"; 567e8d8bef9SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1033: 568e8d8bef9SDimitry Andric return "gfx1033"; 569fe6060f1SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1034: 570fe6060f1SDimitry Andric return "gfx1034"; 571fe6060f1SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1035: 572fe6060f1SDimitry Andric return "gfx1035"; 57381ad6265SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1036: 57481ad6265SDimitry Andric return "gfx1036"; 57581ad6265SDimitry Andric 57681ad6265SDimitry Andric // AMDGCN GFX11. 57781ad6265SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1100: 57881ad6265SDimitry Andric return "gfx1100"; 57981ad6265SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1101: 58081ad6265SDimitry Andric return "gfx1101"; 58181ad6265SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1102: 58281ad6265SDimitry Andric return "gfx1102"; 58381ad6265SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1103: 58481ad6265SDimitry Andric return "gfx1103"; 58506c3fb27SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1150: 58606c3fb27SDimitry Andric return "gfx1150"; 58706c3fb27SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1151: 58806c3fb27SDimitry Andric return "gfx1151"; 589*0fca6ea1SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1152: 590*0fca6ea1SDimitry Andric return "gfx1152"; 5915f757f3fSDimitry Andric 5925f757f3fSDimitry Andric // AMDGCN GFX12. 5935f757f3fSDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1200: 5945f757f3fSDimitry Andric return "gfx1200"; 5955f757f3fSDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1201: 5965f757f3fSDimitry Andric return "gfx1201"; 597*0fca6ea1SDimitry Andric 598*0fca6ea1SDimitry Andric // Generic AMDGCN targets 599*0fca6ea1SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX9_GENERIC: 600*0fca6ea1SDimitry Andric return "gfx9-generic"; 601*0fca6ea1SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX10_1_GENERIC: 602*0fca6ea1SDimitry Andric return "gfx10-1-generic"; 603*0fca6ea1SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX10_3_GENERIC: 604*0fca6ea1SDimitry Andric return "gfx10-3-generic"; 605*0fca6ea1SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX11_GENERIC: 606*0fca6ea1SDimitry Andric return "gfx11-generic"; 607*0fca6ea1SDimitry Andric case ELF::EF_AMDGPU_MACH_AMDGCN_GFX12_GENERIC: 608*0fca6ea1SDimitry Andric return "gfx12-generic"; 609e8d8bef9SDimitry Andric default: 610e8d8bef9SDimitry Andric llvm_unreachable("Unknown EF_AMDGPU_MACH value"); 611e8d8bef9SDimitry Andric } 612e8d8bef9SDimitry Andric } 613e8d8bef9SDimitry Andric 614cb14a3feSDimitry Andric StringRef ELFObjectFileBase::getNVPTXCPUName() const { 615cb14a3feSDimitry Andric assert(getEMachine() == ELF::EM_CUDA); 616cb14a3feSDimitry Andric unsigned SM = getPlatformFlags() & ELF::EF_CUDA_SM; 617cb14a3feSDimitry Andric 618cb14a3feSDimitry Andric switch (SM) { 619cb14a3feSDimitry Andric // Fermi architecture. 620cb14a3feSDimitry Andric case ELF::EF_CUDA_SM20: 621cb14a3feSDimitry Andric return "sm_20"; 622cb14a3feSDimitry Andric case ELF::EF_CUDA_SM21: 623cb14a3feSDimitry Andric return "sm_21"; 624cb14a3feSDimitry Andric 625cb14a3feSDimitry Andric // Kepler architecture. 626cb14a3feSDimitry Andric case ELF::EF_CUDA_SM30: 627cb14a3feSDimitry Andric return "sm_30"; 628cb14a3feSDimitry Andric case ELF::EF_CUDA_SM32: 629cb14a3feSDimitry Andric return "sm_32"; 630cb14a3feSDimitry Andric case ELF::EF_CUDA_SM35: 631cb14a3feSDimitry Andric return "sm_35"; 632cb14a3feSDimitry Andric case ELF::EF_CUDA_SM37: 633cb14a3feSDimitry Andric return "sm_37"; 634cb14a3feSDimitry Andric 635cb14a3feSDimitry Andric // Maxwell architecture. 636cb14a3feSDimitry Andric case ELF::EF_CUDA_SM50: 637cb14a3feSDimitry Andric return "sm_50"; 638cb14a3feSDimitry Andric case ELF::EF_CUDA_SM52: 639cb14a3feSDimitry Andric return "sm_52"; 640cb14a3feSDimitry Andric case ELF::EF_CUDA_SM53: 641cb14a3feSDimitry Andric return "sm_53"; 642cb14a3feSDimitry Andric 643cb14a3feSDimitry Andric // Pascal architecture. 644cb14a3feSDimitry Andric case ELF::EF_CUDA_SM60: 645cb14a3feSDimitry Andric return "sm_60"; 646cb14a3feSDimitry Andric case ELF::EF_CUDA_SM61: 647cb14a3feSDimitry Andric return "sm_61"; 648cb14a3feSDimitry Andric case ELF::EF_CUDA_SM62: 649cb14a3feSDimitry Andric return "sm_62"; 650cb14a3feSDimitry Andric 651cb14a3feSDimitry Andric // Volta architecture. 652cb14a3feSDimitry Andric case ELF::EF_CUDA_SM70: 653cb14a3feSDimitry Andric return "sm_70"; 654cb14a3feSDimitry Andric case ELF::EF_CUDA_SM72: 655cb14a3feSDimitry Andric return "sm_72"; 656cb14a3feSDimitry Andric 657cb14a3feSDimitry Andric // Turing architecture. 658cb14a3feSDimitry Andric case ELF::EF_CUDA_SM75: 659cb14a3feSDimitry Andric return "sm_75"; 660cb14a3feSDimitry Andric 661cb14a3feSDimitry Andric // Ampere architecture. 662cb14a3feSDimitry Andric case ELF::EF_CUDA_SM80: 663cb14a3feSDimitry Andric return "sm_80"; 664cb14a3feSDimitry Andric case ELF::EF_CUDA_SM86: 665cb14a3feSDimitry Andric return "sm_86"; 666cb14a3feSDimitry Andric case ELF::EF_CUDA_SM87: 667cb14a3feSDimitry Andric return "sm_87"; 668cb14a3feSDimitry Andric 669cb14a3feSDimitry Andric // Ada architecture. 670cb14a3feSDimitry Andric case ELF::EF_CUDA_SM89: 671cb14a3feSDimitry Andric return "sm_89"; 672cb14a3feSDimitry Andric 673cb14a3feSDimitry Andric // Hopper architecture. 674cb14a3feSDimitry Andric case ELF::EF_CUDA_SM90: 675cb14a3feSDimitry Andric return getPlatformFlags() & ELF::EF_CUDA_ACCELERATORS ? "sm_90a" : "sm_90"; 676cb14a3feSDimitry Andric default: 677cb14a3feSDimitry Andric llvm_unreachable("Unknown EF_CUDA_SM value"); 678cb14a3feSDimitry Andric } 679cb14a3feSDimitry Andric } 680cb14a3feSDimitry Andric 6810b57cec5SDimitry Andric // FIXME Encode from a tablegen description or target parser. 6820b57cec5SDimitry Andric void ELFObjectFileBase::setARMSubArch(Triple &TheTriple) const { 6830b57cec5SDimitry Andric if (TheTriple.getSubArch() != Triple::NoSubArch) 6840b57cec5SDimitry Andric return; 6850b57cec5SDimitry Andric 6860b57cec5SDimitry Andric ARMAttributeParser Attributes; 6875ffd83dbSDimitry Andric if (Error E = getBuildAttributes(Attributes)) { 6885ffd83dbSDimitry Andric // TODO Propagate Error. 6895ffd83dbSDimitry Andric consumeError(std::move(E)); 6900b57cec5SDimitry Andric return; 6915ffd83dbSDimitry Andric } 6920b57cec5SDimitry Andric 6930b57cec5SDimitry Andric std::string Triple; 6940b57cec5SDimitry Andric // Default to ARM, but use the triple if it's been set. 6950b57cec5SDimitry Andric if (TheTriple.isThumb()) 6960b57cec5SDimitry Andric Triple = "thumb"; 6970b57cec5SDimitry Andric else 6980b57cec5SDimitry Andric Triple = "arm"; 6990b57cec5SDimitry Andric 700bdd1243dSDimitry Andric std::optional<unsigned> Attr = 7015ffd83dbSDimitry Andric Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch); 70281ad6265SDimitry Andric if (Attr) { 703bdd1243dSDimitry Andric switch (*Attr) { 7040b57cec5SDimitry Andric case ARMBuildAttrs::v4: 7050b57cec5SDimitry Andric Triple += "v4"; 7060b57cec5SDimitry Andric break; 7070b57cec5SDimitry Andric case ARMBuildAttrs::v4T: 7080b57cec5SDimitry Andric Triple += "v4t"; 7090b57cec5SDimitry Andric break; 7100b57cec5SDimitry Andric case ARMBuildAttrs::v5T: 7110b57cec5SDimitry Andric Triple += "v5t"; 7120b57cec5SDimitry Andric break; 7130b57cec5SDimitry Andric case ARMBuildAttrs::v5TE: 7140b57cec5SDimitry Andric Triple += "v5te"; 7150b57cec5SDimitry Andric break; 7160b57cec5SDimitry Andric case ARMBuildAttrs::v5TEJ: 7170b57cec5SDimitry Andric Triple += "v5tej"; 7180b57cec5SDimitry Andric break; 7190b57cec5SDimitry Andric case ARMBuildAttrs::v6: 7200b57cec5SDimitry Andric Triple += "v6"; 7210b57cec5SDimitry Andric break; 7220b57cec5SDimitry Andric case ARMBuildAttrs::v6KZ: 7230b57cec5SDimitry Andric Triple += "v6kz"; 7240b57cec5SDimitry Andric break; 7250b57cec5SDimitry Andric case ARMBuildAttrs::v6T2: 7260b57cec5SDimitry Andric Triple += "v6t2"; 7270b57cec5SDimitry Andric break; 7280b57cec5SDimitry Andric case ARMBuildAttrs::v6K: 7290b57cec5SDimitry Andric Triple += "v6k"; 7300b57cec5SDimitry Andric break; 731349cc55cSDimitry Andric case ARMBuildAttrs::v7: { 732bdd1243dSDimitry Andric std::optional<unsigned> ArchProfileAttr = 733349cc55cSDimitry Andric Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch_profile); 73481ad6265SDimitry Andric if (ArchProfileAttr && 735bdd1243dSDimitry Andric *ArchProfileAttr == ARMBuildAttrs::MicroControllerProfile) 736349cc55cSDimitry Andric Triple += "v7m"; 737349cc55cSDimitry Andric else 7380b57cec5SDimitry Andric Triple += "v7"; 7390b57cec5SDimitry Andric break; 740349cc55cSDimitry Andric } 7410b57cec5SDimitry Andric case ARMBuildAttrs::v6_M: 7420b57cec5SDimitry Andric Triple += "v6m"; 7430b57cec5SDimitry Andric break; 7440b57cec5SDimitry Andric case ARMBuildAttrs::v6S_M: 7450b57cec5SDimitry Andric Triple += "v6sm"; 7460b57cec5SDimitry Andric break; 7470b57cec5SDimitry Andric case ARMBuildAttrs::v7E_M: 7480b57cec5SDimitry Andric Triple += "v7em"; 7490b57cec5SDimitry Andric break; 7508bcb0991SDimitry Andric case ARMBuildAttrs::v8_A: 7518bcb0991SDimitry Andric Triple += "v8a"; 7528bcb0991SDimitry Andric break; 7538bcb0991SDimitry Andric case ARMBuildAttrs::v8_R: 7548bcb0991SDimitry Andric Triple += "v8r"; 7558bcb0991SDimitry Andric break; 7568bcb0991SDimitry Andric case ARMBuildAttrs::v8_M_Base: 7578bcb0991SDimitry Andric Triple += "v8m.base"; 7588bcb0991SDimitry Andric break; 7598bcb0991SDimitry Andric case ARMBuildAttrs::v8_M_Main: 7608bcb0991SDimitry Andric Triple += "v8m.main"; 7618bcb0991SDimitry Andric break; 7628bcb0991SDimitry Andric case ARMBuildAttrs::v8_1_M_Main: 7638bcb0991SDimitry Andric Triple += "v8.1m.main"; 7648bcb0991SDimitry Andric break; 76581ad6265SDimitry Andric case ARMBuildAttrs::v9_A: 76681ad6265SDimitry Andric Triple += "v9a"; 76781ad6265SDimitry Andric break; 7680b57cec5SDimitry Andric } 7690b57cec5SDimitry Andric } 7700b57cec5SDimitry Andric if (!isLittleEndian()) 7710b57cec5SDimitry Andric Triple += "eb"; 7720b57cec5SDimitry Andric 7730b57cec5SDimitry Andric TheTriple.setArchName(Triple); 7740b57cec5SDimitry Andric } 7750b57cec5SDimitry Andric 77606c3fb27SDimitry Andric std::vector<ELFPltEntry> ELFObjectFileBase::getPltEntries() const { 7770b57cec5SDimitry Andric std::string Err; 7780b57cec5SDimitry Andric const auto Triple = makeTriple(); 7790b57cec5SDimitry Andric const auto *T = TargetRegistry::lookupTarget(Triple.str(), Err); 7800b57cec5SDimitry Andric if (!T) 7810b57cec5SDimitry Andric return {}; 78206c3fb27SDimitry Andric uint32_t JumpSlotReloc = 0, GlobDatReloc = 0; 7830b57cec5SDimitry Andric switch (Triple.getArch()) { 7840b57cec5SDimitry Andric case Triple::x86: 7850b57cec5SDimitry Andric JumpSlotReloc = ELF::R_386_JUMP_SLOT; 78606c3fb27SDimitry Andric GlobDatReloc = ELF::R_386_GLOB_DAT; 7870b57cec5SDimitry Andric break; 7880b57cec5SDimitry Andric case Triple::x86_64: 7890b57cec5SDimitry Andric JumpSlotReloc = ELF::R_X86_64_JUMP_SLOT; 79006c3fb27SDimitry Andric GlobDatReloc = ELF::R_X86_64_GLOB_DAT; 7910b57cec5SDimitry Andric break; 7920b57cec5SDimitry Andric case Triple::aarch64: 793fe6060f1SDimitry Andric case Triple::aarch64_be: 7940b57cec5SDimitry Andric JumpSlotReloc = ELF::R_AARCH64_JUMP_SLOT; 7950b57cec5SDimitry Andric break; 7960b57cec5SDimitry Andric default: 7970b57cec5SDimitry Andric return {}; 7980b57cec5SDimitry Andric } 7990b57cec5SDimitry Andric std::unique_ptr<const MCInstrInfo> MII(T->createMCInstrInfo()); 8000b57cec5SDimitry Andric std::unique_ptr<const MCInstrAnalysis> MIA( 8010b57cec5SDimitry Andric T->createMCInstrAnalysis(MII.get())); 8020b57cec5SDimitry Andric if (!MIA) 8030b57cec5SDimitry Andric return {}; 80406c3fb27SDimitry Andric std::vector<std::pair<uint64_t, uint64_t>> PltEntries; 80506c3fb27SDimitry Andric std::optional<SectionRef> RelaPlt, RelaDyn; 80606c3fb27SDimitry Andric uint64_t GotBaseVA = 0; 8070b57cec5SDimitry Andric for (const SectionRef &Section : sections()) { 8088bcb0991SDimitry Andric Expected<StringRef> NameOrErr = Section.getName(); 8098bcb0991SDimitry Andric if (!NameOrErr) { 8108bcb0991SDimitry Andric consumeError(NameOrErr.takeError()); 8110b57cec5SDimitry Andric continue; 8128bcb0991SDimitry Andric } 8138bcb0991SDimitry Andric StringRef Name = *NameOrErr; 8148bcb0991SDimitry Andric 81506c3fb27SDimitry Andric if (Name == ".rela.plt" || Name == ".rel.plt") { 8160b57cec5SDimitry Andric RelaPlt = Section; 81706c3fb27SDimitry Andric } else if (Name == ".rela.dyn" || Name == ".rel.dyn") { 81806c3fb27SDimitry Andric RelaDyn = Section; 81906c3fb27SDimitry Andric } else if (Name == ".got.plt") { 82006c3fb27SDimitry Andric GotBaseVA = Section.getAddress(); 82106c3fb27SDimitry Andric } else if (Name == ".plt" || Name == ".plt.got") { 82206c3fb27SDimitry Andric Expected<StringRef> PltContents = Section.getContents(); 8230b57cec5SDimitry Andric if (!PltContents) { 8240b57cec5SDimitry Andric consumeError(PltContents.takeError()); 8250b57cec5SDimitry Andric return {}; 8260b57cec5SDimitry Andric } 82706c3fb27SDimitry Andric llvm::append_range( 82806c3fb27SDimitry Andric PltEntries, 82906c3fb27SDimitry Andric MIA->findPltEntries(Section.getAddress(), 83006c3fb27SDimitry Andric arrayRefFromStringRef(*PltContents), Triple)); 83106c3fb27SDimitry Andric } 83206c3fb27SDimitry Andric } 83306c3fb27SDimitry Andric 8340b57cec5SDimitry Andric // Build a map from GOT entry virtual address to PLT entry virtual address. 8350b57cec5SDimitry Andric DenseMap<uint64_t, uint64_t> GotToPlt; 83606c3fb27SDimitry Andric for (auto [Plt, GotPlt] : PltEntries) { 83706c3fb27SDimitry Andric uint64_t GotPltEntry = GotPlt; 83806c3fb27SDimitry Andric // An x86-32 PIC PLT uses jmp DWORD PTR [ebx-offset]. Add 83906c3fb27SDimitry Andric // _GLOBAL_OFFSET_TABLE_ (EBX) to get the .got.plt (or .got) entry address. 84006c3fb27SDimitry Andric // See X86MCTargetDesc.cpp:findPltEntries for the 1 << 32 bit. 84106c3fb27SDimitry Andric if (GotPltEntry & (uint64_t(1) << 32) && getEMachine() == ELF::EM_386) 84206c3fb27SDimitry Andric GotPltEntry = static_cast<int32_t>(GotPltEntry) + GotBaseVA; 84306c3fb27SDimitry Andric GotToPlt.insert(std::make_pair(GotPltEntry, Plt)); 84406c3fb27SDimitry Andric } 84506c3fb27SDimitry Andric 8460b57cec5SDimitry Andric // Find the relocations in the dynamic relocation table that point to 8470b57cec5SDimitry Andric // locations in the GOT for which we know the corresponding PLT entry. 84806c3fb27SDimitry Andric std::vector<ELFPltEntry> Result; 84906c3fb27SDimitry Andric auto handleRels = [&](iterator_range<relocation_iterator> Rels, 85006c3fb27SDimitry Andric uint32_t RelType, StringRef PltSec) { 85106c3fb27SDimitry Andric for (const auto &R : Rels) { 85206c3fb27SDimitry Andric if (R.getType() != RelType) 8530b57cec5SDimitry Andric continue; 85406c3fb27SDimitry Andric auto PltEntryIter = GotToPlt.find(R.getOffset()); 855e8d8bef9SDimitry Andric if (PltEntryIter != GotToPlt.end()) { 85606c3fb27SDimitry Andric symbol_iterator Sym = R.getSymbol(); 857e8d8bef9SDimitry Andric if (Sym == symbol_end()) 85806c3fb27SDimitry Andric Result.push_back( 85906c3fb27SDimitry Andric ELFPltEntry{PltSec, std::nullopt, PltEntryIter->second}); 860e8d8bef9SDimitry Andric else 86106c3fb27SDimitry Andric Result.push_back(ELFPltEntry{PltSec, Sym->getRawDataRefImpl(), 86206c3fb27SDimitry Andric PltEntryIter->second}); 863e8d8bef9SDimitry Andric } 8640b57cec5SDimitry Andric } 86506c3fb27SDimitry Andric }; 86606c3fb27SDimitry Andric 86706c3fb27SDimitry Andric if (RelaPlt) 86806c3fb27SDimitry Andric handleRels(RelaPlt->relocations(), JumpSlotReloc, ".plt"); 86906c3fb27SDimitry Andric 87006c3fb27SDimitry Andric // If a symbol needing a PLT entry also needs a GLOB_DAT relocation, GNU ld's 87106c3fb27SDimitry Andric // x86 port places the PLT entry in the .plt.got section. 87206c3fb27SDimitry Andric if (RelaDyn) 87306c3fb27SDimitry Andric handleRels(RelaDyn->relocations(), GlobDatReloc, ".plt.got"); 87406c3fb27SDimitry Andric 8750b57cec5SDimitry Andric return Result; 8760b57cec5SDimitry Andric } 877349cc55cSDimitry Andric 878349cc55cSDimitry Andric template <class ELFT> 879bdd1243dSDimitry Andric Expected<std::vector<BBAddrMap>> static readBBAddrMapImpl( 8805f757f3fSDimitry Andric const ELFFile<ELFT> &EF, std::optional<unsigned> TextSectionIndex, 8815f757f3fSDimitry Andric std::vector<PGOAnalysisMap> *PGOAnalyses) { 88281ad6265SDimitry Andric using Elf_Shdr = typename ELFT::Shdr; 88306c3fb27SDimitry Andric bool IsRelocatable = EF.getHeader().e_type == ELF::ET_REL; 88481ad6265SDimitry Andric std::vector<BBAddrMap> BBAddrMaps; 8855f757f3fSDimitry Andric if (PGOAnalyses) 8865f757f3fSDimitry Andric PGOAnalyses->clear(); 88706c3fb27SDimitry Andric 88881ad6265SDimitry Andric const auto &Sections = cantFail(EF.sections()); 88906c3fb27SDimitry Andric auto IsMatch = [&](const Elf_Shdr &Sec) -> Expected<bool> { 89081ad6265SDimitry Andric if (Sec.sh_type != ELF::SHT_LLVM_BB_ADDR_MAP && 89181ad6265SDimitry Andric Sec.sh_type != ELF::SHT_LLVM_BB_ADDR_MAP_V0) 89206c3fb27SDimitry Andric return false; 89306c3fb27SDimitry Andric if (!TextSectionIndex) 89406c3fb27SDimitry Andric return true; 89581ad6265SDimitry Andric Expected<const Elf_Shdr *> TextSecOrErr = EF.getSection(Sec.sh_link); 89681ad6265SDimitry Andric if (!TextSecOrErr) 89781ad6265SDimitry Andric return createError("unable to get the linked-to section for " + 89881ad6265SDimitry Andric describe(EF, Sec) + ": " + 89981ad6265SDimitry Andric toString(TextSecOrErr.takeError())); 900*0fca6ea1SDimitry Andric assert(*TextSecOrErr >= Sections.begin() && 901*0fca6ea1SDimitry Andric "Text section pointer outside of bounds"); 902*0fca6ea1SDimitry Andric if (*TextSectionIndex != 903*0fca6ea1SDimitry Andric (unsigned)std::distance(Sections.begin(), *TextSecOrErr)) 90406c3fb27SDimitry Andric return false; 90506c3fb27SDimitry Andric return true; 90606c3fb27SDimitry Andric }; 90706c3fb27SDimitry Andric 90806c3fb27SDimitry Andric Expected<MapVector<const Elf_Shdr *, const Elf_Shdr *>> SectionRelocMapOrErr = 90906c3fb27SDimitry Andric EF.getSectionAndRelocations(IsMatch); 91006c3fb27SDimitry Andric if (!SectionRelocMapOrErr) 91106c3fb27SDimitry Andric return SectionRelocMapOrErr.takeError(); 91206c3fb27SDimitry Andric 91306c3fb27SDimitry Andric for (auto const &[Sec, RelocSec] : *SectionRelocMapOrErr) { 91406c3fb27SDimitry Andric if (IsRelocatable && !RelocSec) 91506c3fb27SDimitry Andric return createError("unable to get relocation section for " + 91606c3fb27SDimitry Andric describe(EF, *Sec)); 91706c3fb27SDimitry Andric Expected<std::vector<BBAddrMap>> BBAddrMapOrErr = 9185f757f3fSDimitry Andric EF.decodeBBAddrMap(*Sec, RelocSec, PGOAnalyses); 9195f757f3fSDimitry Andric if (!BBAddrMapOrErr) { 9205f757f3fSDimitry Andric if (PGOAnalyses) 9215f757f3fSDimitry Andric PGOAnalyses->clear(); 92206c3fb27SDimitry Andric return createError("unable to read " + describe(EF, *Sec) + ": " + 92381ad6265SDimitry Andric toString(BBAddrMapOrErr.takeError())); 9245f757f3fSDimitry Andric } 92581ad6265SDimitry Andric std::move(BBAddrMapOrErr->begin(), BBAddrMapOrErr->end(), 92681ad6265SDimitry Andric std::back_inserter(BBAddrMaps)); 92781ad6265SDimitry Andric } 9287a6dacacSDimitry Andric if (PGOAnalyses) 9297a6dacacSDimitry Andric assert(PGOAnalyses->size() == BBAddrMaps.size() && 9307a6dacacSDimitry Andric "The same number of BBAddrMaps and PGOAnalysisMaps should be " 9317a6dacacSDimitry Andric "returned when PGO information is requested"); 93281ad6265SDimitry Andric return BBAddrMaps; 93381ad6265SDimitry Andric } 93481ad6265SDimitry Andric 93581ad6265SDimitry Andric template <class ELFT> 936349cc55cSDimitry Andric static Expected<std::vector<VersionEntry>> 937349cc55cSDimitry Andric readDynsymVersionsImpl(const ELFFile<ELFT> &EF, 938349cc55cSDimitry Andric ELFObjectFileBase::elf_symbol_iterator_range Symbols) { 939349cc55cSDimitry Andric using Elf_Shdr = typename ELFT::Shdr; 940349cc55cSDimitry Andric const Elf_Shdr *VerSec = nullptr; 941349cc55cSDimitry Andric const Elf_Shdr *VerNeedSec = nullptr; 942349cc55cSDimitry Andric const Elf_Shdr *VerDefSec = nullptr; 943349cc55cSDimitry Andric // The user should ensure sections() can't fail here. 944349cc55cSDimitry Andric for (const Elf_Shdr &Sec : cantFail(EF.sections())) { 945349cc55cSDimitry Andric if (Sec.sh_type == ELF::SHT_GNU_versym) 946349cc55cSDimitry Andric VerSec = &Sec; 947349cc55cSDimitry Andric else if (Sec.sh_type == ELF::SHT_GNU_verdef) 948349cc55cSDimitry Andric VerDefSec = &Sec; 949349cc55cSDimitry Andric else if (Sec.sh_type == ELF::SHT_GNU_verneed) 950349cc55cSDimitry Andric VerNeedSec = &Sec; 951349cc55cSDimitry Andric } 952349cc55cSDimitry Andric if (!VerSec) 953349cc55cSDimitry Andric return std::vector<VersionEntry>(); 954349cc55cSDimitry Andric 955bdd1243dSDimitry Andric Expected<SmallVector<std::optional<VersionEntry>, 0>> MapOrErr = 956349cc55cSDimitry Andric EF.loadVersionMap(VerNeedSec, VerDefSec); 957349cc55cSDimitry Andric if (!MapOrErr) 958349cc55cSDimitry Andric return MapOrErr.takeError(); 959349cc55cSDimitry Andric 960349cc55cSDimitry Andric std::vector<VersionEntry> Ret; 961349cc55cSDimitry Andric size_t I = 0; 9624824e7fdSDimitry Andric for (const ELFSymbolRef &Sym : Symbols) { 963349cc55cSDimitry Andric ++I; 964349cc55cSDimitry Andric Expected<const typename ELFT::Versym *> VerEntryOrErr = 965349cc55cSDimitry Andric EF.template getEntry<typename ELFT::Versym>(*VerSec, I); 966349cc55cSDimitry Andric if (!VerEntryOrErr) 967349cc55cSDimitry Andric return createError("unable to read an entry with index " + Twine(I) + 968349cc55cSDimitry Andric " from " + describe(EF, *VerSec) + ": " + 969349cc55cSDimitry Andric toString(VerEntryOrErr.takeError())); 970349cc55cSDimitry Andric 9714824e7fdSDimitry Andric Expected<uint32_t> FlagsOrErr = Sym.getFlags(); 972349cc55cSDimitry Andric if (!FlagsOrErr) 973349cc55cSDimitry Andric return createError("unable to read flags for symbol with index " + 974349cc55cSDimitry Andric Twine(I) + ": " + toString(FlagsOrErr.takeError())); 975349cc55cSDimitry Andric 976349cc55cSDimitry Andric bool IsDefault; 977349cc55cSDimitry Andric Expected<StringRef> VerOrErr = EF.getSymbolVersionByIndex( 978349cc55cSDimitry Andric (*VerEntryOrErr)->vs_index, IsDefault, *MapOrErr, 979349cc55cSDimitry Andric (*FlagsOrErr) & SymbolRef::SF_Undefined); 980349cc55cSDimitry Andric if (!VerOrErr) 981349cc55cSDimitry Andric return createError("unable to get a version for entry " + Twine(I) + 982349cc55cSDimitry Andric " of " + describe(EF, *VerSec) + ": " + 983349cc55cSDimitry Andric toString(VerOrErr.takeError())); 984349cc55cSDimitry Andric 985349cc55cSDimitry Andric Ret.push_back({(*VerOrErr).str(), IsDefault}); 986349cc55cSDimitry Andric } 987349cc55cSDimitry Andric 988349cc55cSDimitry Andric return Ret; 989349cc55cSDimitry Andric } 990349cc55cSDimitry Andric 991349cc55cSDimitry Andric Expected<std::vector<VersionEntry>> 992349cc55cSDimitry Andric ELFObjectFileBase::readDynsymVersions() const { 993349cc55cSDimitry Andric elf_symbol_iterator_range Symbols = getDynamicSymbolIterators(); 994349cc55cSDimitry Andric if (const auto *Obj = dyn_cast<ELF32LEObjectFile>(this)) 995349cc55cSDimitry Andric return readDynsymVersionsImpl(Obj->getELFFile(), Symbols); 996349cc55cSDimitry Andric if (const auto *Obj = dyn_cast<ELF32BEObjectFile>(this)) 997349cc55cSDimitry Andric return readDynsymVersionsImpl(Obj->getELFFile(), Symbols); 998349cc55cSDimitry Andric if (const auto *Obj = dyn_cast<ELF64LEObjectFile>(this)) 999349cc55cSDimitry Andric return readDynsymVersionsImpl(Obj->getELFFile(), Symbols); 1000349cc55cSDimitry Andric return readDynsymVersionsImpl(cast<ELF64BEObjectFile>(this)->getELFFile(), 1001349cc55cSDimitry Andric Symbols); 1002349cc55cSDimitry Andric } 100381ad6265SDimitry Andric 1004bdd1243dSDimitry Andric Expected<std::vector<BBAddrMap>> ELFObjectFileBase::readBBAddrMap( 10055f757f3fSDimitry Andric std::optional<unsigned> TextSectionIndex, 10065f757f3fSDimitry Andric std::vector<PGOAnalysisMap> *PGOAnalyses) const { 100781ad6265SDimitry Andric if (const auto *Obj = dyn_cast<ELF32LEObjectFile>(this)) 10085f757f3fSDimitry Andric return readBBAddrMapImpl(Obj->getELFFile(), TextSectionIndex, PGOAnalyses); 100981ad6265SDimitry Andric if (const auto *Obj = dyn_cast<ELF64LEObjectFile>(this)) 10105f757f3fSDimitry Andric return readBBAddrMapImpl(Obj->getELFFile(), TextSectionIndex, PGOAnalyses); 101181ad6265SDimitry Andric if (const auto *Obj = dyn_cast<ELF32BEObjectFile>(this)) 10125f757f3fSDimitry Andric return readBBAddrMapImpl(Obj->getELFFile(), TextSectionIndex, PGOAnalyses); 101306c3fb27SDimitry Andric return readBBAddrMapImpl(cast<ELF64BEObjectFile>(this)->getELFFile(), 10145f757f3fSDimitry Andric TextSectionIndex, PGOAnalyses); 101581ad6265SDimitry Andric } 1016*0fca6ea1SDimitry Andric 1017*0fca6ea1SDimitry Andric StringRef ELFObjectFileBase::getCrelDecodeProblem(SectionRef Sec) const { 1018*0fca6ea1SDimitry Andric auto Data = Sec.getRawDataRefImpl(); 1019*0fca6ea1SDimitry Andric if (const auto *Obj = dyn_cast<ELF32LEObjectFile>(this)) 1020*0fca6ea1SDimitry Andric return Obj->getCrelDecodeProblem(Data); 1021*0fca6ea1SDimitry Andric if (const auto *Obj = dyn_cast<ELF32BEObjectFile>(this)) 1022*0fca6ea1SDimitry Andric return Obj->getCrelDecodeProblem(Data); 1023*0fca6ea1SDimitry Andric if (const auto *Obj = dyn_cast<ELF64LEObjectFile>(this)) 1024*0fca6ea1SDimitry Andric return Obj->getCrelDecodeProblem(Data); 1025*0fca6ea1SDimitry Andric return cast<ELF64BEObjectFile>(this)->getCrelDecodeProblem(Data); 1026*0fca6ea1SDimitry Andric } 1027