11df42facSEugene Zelenko //===- ELFObjectFile.cpp - ELF object file implementation -----------------===// 2b60a18deSMichael J. Spencer // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6b60a18deSMichael J. Spencer // 7b60a18deSMichael J. Spencer //===----------------------------------------------------------------------===// 8b60a18deSMichael J. Spencer // 9c7d23ddbSEli Bendersky // Part of the ELFObjectFile class implementation. 10b60a18deSMichael J. Spencer // 11b60a18deSMichael J. Spencer //===----------------------------------------------------------------------===// 12b60a18deSMichael J. Spencer 136bda14b3SChandler Carruth #include "llvm/Object/ELFObjectFile.h" 141df42facSEugene Zelenko #include "llvm/ADT/Triple.h" 15264b5d9eSZachary Turner #include "llvm/BinaryFormat/ELF.h" 16d36fb48aSJoel Galenson #include "llvm/MC/MCInstrAnalysis.h" 171df42facSEugene Zelenko #include "llvm/MC/SubtargetFeature.h" 1889b57061SReid Kleckner #include "llvm/MC/TargetRegistry.h" 191df42facSEugene Zelenko #include "llvm/Object/ELF.h" 201df42facSEugene Zelenko #include "llvm/Object/ELFTypes.h" 211df42facSEugene Zelenko #include "llvm/Object/Error.h" 22b0de00d5SSam Parker #include "llvm/Support/ARMAttributeParser.h" 236bda14b3SChandler Carruth #include "llvm/Support/ARMBuildAttributes.h" 241df42facSEugene Zelenko #include "llvm/Support/ErrorHandling.h" 25bae14cefSMichael J. Spencer #include "llvm/Support/MathExtras.h" 26581ba352SKai Wang #include "llvm/Support/RISCVAttributeParser.h" 27581ba352SKai Wang #include "llvm/Support/RISCVAttributes.h" 281df42facSEugene Zelenko #include <algorithm> 291df42facSEugene Zelenko #include <cstddef> 301df42facSEugene Zelenko #include <cstdint> 311df42facSEugene Zelenko #include <memory> 321df42facSEugene Zelenko #include <string> 331df42facSEugene Zelenko #include <utility> 34b60a18deSMichael J. Spencer 351df42facSEugene Zelenko using namespace llvm; 36b60a18deSMichael J. Spencer using namespace object; 37b60a18deSMichael J. Spencer 38ae8fe4e0SSunil Srivastava const EnumEntry<unsigned> llvm::object::ElfSymbolTypes[NumElfSymbolTypes] = { 39ae8fe4e0SSunil Srivastava {"None", "NOTYPE", ELF::STT_NOTYPE}, 40ae8fe4e0SSunil Srivastava {"Object", "OBJECT", ELF::STT_OBJECT}, 41ae8fe4e0SSunil Srivastava {"Function", "FUNC", ELF::STT_FUNC}, 42ae8fe4e0SSunil Srivastava {"Section", "SECTION", ELF::STT_SECTION}, 43ae8fe4e0SSunil Srivastava {"File", "FILE", ELF::STT_FILE}, 44ae8fe4e0SSunil Srivastava {"Common", "COMMON", ELF::STT_COMMON}, 45ae8fe4e0SSunil Srivastava {"TLS", "TLS", ELF::STT_TLS}, 4627f6f2f8SSunil Srivastava {"Unknown", "<unknown>: 7", 7}, 4727f6f2f8SSunil Srivastava {"Unknown", "<unknown>: 8", 8}, 4827f6f2f8SSunil Srivastava {"Unknown", "<unknown>: 9", 9}, 4927f6f2f8SSunil Srivastava {"GNU_IFunc", "IFUNC", ELF::STT_GNU_IFUNC}, 5027f6f2f8SSunil Srivastava {"OS Specific", "<OS specific>: 11", 11}, 5127f6f2f8SSunil Srivastava {"OS Specific", "<OS specific>: 12", 12}, 5227f6f2f8SSunil Srivastava {"Proc Specific", "<processor specific>: 13", 13}, 5327f6f2f8SSunil Srivastava {"Proc Specific", "<processor specific>: 14", 14}, 5427f6f2f8SSunil Srivastava {"Proc Specific", "<processor specific>: 15", 15} 5527f6f2f8SSunil Srivastava }; 56ae8fe4e0SSunil Srivastava 5748af1c2aSRafael Espindola ELFObjectFileBase::ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source) 5848af1c2aSRafael Espindola : ObjectFile(Type, Source) {} 59ab73774cSRafael Espindola 60ef421f9cSRafael Espindola template <class ELFT> 61ef421f9cSRafael Espindola static Expected<std::unique_ptr<ELFObjectFile<ELFT>>> 6299a6401aSGeorgii Rymar createPtr(MemoryBufferRef Object, bool InitContent) { 6399a6401aSGeorgii Rymar auto Ret = ELFObjectFile<ELFT>::create(Object, InitContent); 64ef421f9cSRafael Espindola if (Error E = Ret.takeError()) 65c55cf4afSBill Wendling return std::move(E); 660eaee545SJonas Devlieghere return std::make_unique<ELFObjectFile<ELFT>>(std::move(*Ret)); 67ef421f9cSRafael Espindola } 68ef421f9cSRafael Espindola 6912db383eSRafael Espindola Expected<std::unique_ptr<ObjectFile>> 7099a6401aSGeorgii Rymar ObjectFile::createELFObjectFile(MemoryBufferRef Obj, bool InitContent) { 71d5a8efe7SRafael Espindola std::pair<unsigned char, unsigned char> Ident = 7248af1c2aSRafael Espindola getElfArchType(Obj.getBuffer()); 73bae14cefSMichael J. Spencer std::size_t MaxAlignment = 7422cf54a7SArthur O'Dwyer 1ULL << countTrailingZeros( 7522cf54a7SArthur O'Dwyer reinterpret_cast<uintptr_t>(Obj.getBufferStart())); 76bae14cefSMichael J. Spencer 77ac729b46SRafael Espindola if (MaxAlignment < 2) 7812db383eSRafael Espindola return createError("Insufficient alignment"); 79ac729b46SRafael Espindola 80ac729b46SRafael Espindola if (Ident.first == ELF::ELFCLASS32) { 81ac729b46SRafael Espindola if (Ident.second == ELF::ELFDATA2LSB) 8299a6401aSGeorgii Rymar return createPtr<ELF32LE>(Obj, InitContent); 83ac729b46SRafael Espindola else if (Ident.second == ELF::ELFDATA2MSB) 8499a6401aSGeorgii Rymar return createPtr<ELF32BE>(Obj, InitContent); 85692410efSRafael Espindola else 8612db383eSRafael Espindola return createError("Invalid ELF data"); 8749179ddbSAlexey Samsonov } else if (Ident.first == ELF::ELFCLASS64) { 88ac729b46SRafael Espindola if (Ident.second == ELF::ELFDATA2LSB) 8999a6401aSGeorgii Rymar return createPtr<ELF64LE>(Obj, InitContent); 90ac729b46SRafael Espindola else if (Ident.second == ELF::ELFDATA2MSB) 9199a6401aSGeorgii Rymar return createPtr<ELF64BE>(Obj, InitContent); 92ac729b46SRafael Espindola else 9312db383eSRafael Espindola return createError("Invalid ELF data"); 94ac729b46SRafael Espindola } 95ef421f9cSRafael Espindola return createError("Invalid ELF class"); 96b60a18deSMichael J. Spencer } 97b60a18deSMichael J. Spencer 98b0de00d5SSam Parker SubtargetFeatures ELFObjectFileBase::getMIPSFeatures() const { 991d14864bSDaniel Sanders SubtargetFeatures Features; 100d5f76ad3SRafael Espindola unsigned PlatformFlags = getPlatformFlags(); 1011d14864bSDaniel Sanders 1021d14864bSDaniel Sanders switch (PlatformFlags & ELF::EF_MIPS_ARCH) { 1031d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_1: 1041d14864bSDaniel Sanders break; 1051d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_2: 1061d14864bSDaniel Sanders Features.AddFeature("mips2"); 1071d14864bSDaniel Sanders break; 1081d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_3: 1091d14864bSDaniel Sanders Features.AddFeature("mips3"); 1101d14864bSDaniel Sanders break; 1111d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_4: 1121d14864bSDaniel Sanders Features.AddFeature("mips4"); 1131d14864bSDaniel Sanders break; 1141d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_5: 1151d14864bSDaniel Sanders Features.AddFeature("mips5"); 1161d14864bSDaniel Sanders break; 1171d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_32: 1181d14864bSDaniel Sanders Features.AddFeature("mips32"); 1191d14864bSDaniel Sanders break; 1201d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_64: 1211d14864bSDaniel Sanders Features.AddFeature("mips64"); 1221d14864bSDaniel Sanders break; 1231d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_32R2: 1241d14864bSDaniel Sanders Features.AddFeature("mips32r2"); 1251d14864bSDaniel Sanders break; 1261d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_64R2: 1271d14864bSDaniel Sanders Features.AddFeature("mips64r2"); 1281d14864bSDaniel Sanders break; 1291d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_32R6: 1301d14864bSDaniel Sanders Features.AddFeature("mips32r6"); 1311d14864bSDaniel Sanders break; 1321d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_64R6: 1331d14864bSDaniel Sanders Features.AddFeature("mips64r6"); 1341d14864bSDaniel Sanders break; 1351d14864bSDaniel Sanders default: 1361d14864bSDaniel Sanders llvm_unreachable("Unknown EF_MIPS_ARCH value"); 1371d14864bSDaniel Sanders } 1381d14864bSDaniel Sanders 1391d14864bSDaniel Sanders switch (PlatformFlags & ELF::EF_MIPS_MACH) { 1401d14864bSDaniel Sanders case ELF::EF_MIPS_MACH_NONE: 1411d14864bSDaniel Sanders // No feature associated with this value. 1421d14864bSDaniel Sanders break; 1431d14864bSDaniel Sanders case ELF::EF_MIPS_MACH_OCTEON: 1441d14864bSDaniel Sanders Features.AddFeature("cnmips"); 1451d14864bSDaniel Sanders break; 1461d14864bSDaniel Sanders default: 1471d14864bSDaniel Sanders llvm_unreachable("Unknown EF_MIPS_ARCH value"); 1481d14864bSDaniel Sanders } 1491d14864bSDaniel Sanders 1501d14864bSDaniel Sanders if (PlatformFlags & ELF::EF_MIPS_ARCH_ASE_M16) 1511d14864bSDaniel Sanders Features.AddFeature("mips16"); 1521d14864bSDaniel Sanders if (PlatformFlags & ELF::EF_MIPS_MICROMIPS) 1531d14864bSDaniel Sanders Features.AddFeature("micromips"); 1541d14864bSDaniel Sanders 1551d14864bSDaniel Sanders return Features; 1561d14864bSDaniel Sanders } 157b0de00d5SSam Parker 158b0de00d5SSam Parker SubtargetFeatures ELFObjectFileBase::getARMFeatures() const { 159b0de00d5SSam Parker SubtargetFeatures Features; 160b0de00d5SSam Parker ARMAttributeParser Attributes; 161791efb14SFangrui Song if (Error E = getBuildAttributes(Attributes)) { 162791efb14SFangrui Song consumeError(std::move(E)); 163b0de00d5SSam Parker return SubtargetFeatures(); 164791efb14SFangrui Song } 165b0de00d5SSam Parker 166b0de00d5SSam Parker // both ARMv7-M and R have to support thumb hardware div 167b0de00d5SSam Parker bool isV7 = false; 168581ba352SKai Wang Optional<unsigned> Attr = 169581ba352SKai Wang Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch); 170581ba352SKai Wang if (Attr.hasValue()) 171581ba352SKai Wang isV7 = Attr.getValue() == ARMBuildAttrs::v7; 172b0de00d5SSam Parker 173581ba352SKai Wang Attr = Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch_profile); 174581ba352SKai Wang if (Attr.hasValue()) { 175581ba352SKai Wang switch (Attr.getValue()) { 176b0de00d5SSam Parker case ARMBuildAttrs::ApplicationProfile: 177b0de00d5SSam Parker Features.AddFeature("aclass"); 178b0de00d5SSam Parker break; 179b0de00d5SSam Parker case ARMBuildAttrs::RealTimeProfile: 180b0de00d5SSam Parker Features.AddFeature("rclass"); 181b0de00d5SSam Parker if (isV7) 182b0de00d5SSam Parker Features.AddFeature("hwdiv"); 183b0de00d5SSam Parker break; 184b0de00d5SSam Parker case ARMBuildAttrs::MicroControllerProfile: 185b0de00d5SSam Parker Features.AddFeature("mclass"); 186b0de00d5SSam Parker if (isV7) 187b0de00d5SSam Parker Features.AddFeature("hwdiv"); 188b0de00d5SSam Parker break; 189b0de00d5SSam Parker } 190b0de00d5SSam Parker } 191b0de00d5SSam Parker 192581ba352SKai Wang Attr = Attributes.getAttributeValue(ARMBuildAttrs::THUMB_ISA_use); 193581ba352SKai Wang if (Attr.hasValue()) { 194581ba352SKai Wang switch (Attr.getValue()) { 195b0de00d5SSam Parker default: 196b0de00d5SSam Parker break; 197b0de00d5SSam Parker case ARMBuildAttrs::Not_Allowed: 198b0de00d5SSam Parker Features.AddFeature("thumb", false); 199b0de00d5SSam Parker Features.AddFeature("thumb2", false); 200b0de00d5SSam Parker break; 201b0de00d5SSam Parker case ARMBuildAttrs::AllowThumb32: 202b0de00d5SSam Parker Features.AddFeature("thumb2"); 203b0de00d5SSam Parker break; 204b0de00d5SSam Parker } 205b0de00d5SSam Parker } 206b0de00d5SSam Parker 207581ba352SKai Wang Attr = Attributes.getAttributeValue(ARMBuildAttrs::FP_arch); 208581ba352SKai Wang if (Attr.hasValue()) { 209581ba352SKai Wang switch (Attr.getValue()) { 210b0de00d5SSam Parker default: 211b0de00d5SSam Parker break; 212b0de00d5SSam Parker case ARMBuildAttrs::Not_Allowed: 213ddf5e86cSEli Friedman Features.AddFeature("vfp2sp", false); 214760df47bSSimon Tatham Features.AddFeature("vfp3d16sp", false); 215760df47bSSimon Tatham Features.AddFeature("vfp4d16sp", false); 216b0de00d5SSam Parker break; 217b0de00d5SSam Parker case ARMBuildAttrs::AllowFPv2: 218b0de00d5SSam Parker Features.AddFeature("vfp2"); 219b0de00d5SSam Parker break; 220b0de00d5SSam Parker case ARMBuildAttrs::AllowFPv3A: 221b0de00d5SSam Parker case ARMBuildAttrs::AllowFPv3B: 222b0de00d5SSam Parker Features.AddFeature("vfp3"); 223b0de00d5SSam Parker break; 224b0de00d5SSam Parker case ARMBuildAttrs::AllowFPv4A: 225b0de00d5SSam Parker case ARMBuildAttrs::AllowFPv4B: 226b0de00d5SSam Parker Features.AddFeature("vfp4"); 227b0de00d5SSam Parker break; 228b0de00d5SSam Parker } 229b0de00d5SSam Parker } 230b0de00d5SSam Parker 231581ba352SKai Wang Attr = Attributes.getAttributeValue(ARMBuildAttrs::Advanced_SIMD_arch); 232581ba352SKai Wang if (Attr.hasValue()) { 233581ba352SKai Wang switch (Attr.getValue()) { 234b0de00d5SSam Parker default: 235b0de00d5SSam Parker break; 236b0de00d5SSam Parker case ARMBuildAttrs::Not_Allowed: 237b0de00d5SSam Parker Features.AddFeature("neon", false); 238b0de00d5SSam Parker Features.AddFeature("fp16", false); 239b0de00d5SSam Parker break; 240b0de00d5SSam Parker case ARMBuildAttrs::AllowNeon: 241b0de00d5SSam Parker Features.AddFeature("neon"); 242b0de00d5SSam Parker break; 243b0de00d5SSam Parker case ARMBuildAttrs::AllowNeon2: 244b0de00d5SSam Parker Features.AddFeature("neon"); 245b0de00d5SSam Parker Features.AddFeature("fp16"); 246b0de00d5SSam Parker break; 247b0de00d5SSam Parker } 248b0de00d5SSam Parker } 249b0de00d5SSam Parker 250581ba352SKai Wang Attr = Attributes.getAttributeValue(ARMBuildAttrs::MVE_arch); 251581ba352SKai Wang if (Attr.hasValue()) { 252581ba352SKai Wang switch (Attr.getValue()) { 253930dee2cSSjoerd Meijer default: 254930dee2cSSjoerd Meijer break; 255930dee2cSSjoerd Meijer case ARMBuildAttrs::Not_Allowed: 256930dee2cSSjoerd Meijer Features.AddFeature("mve", false); 257930dee2cSSjoerd Meijer Features.AddFeature("mve.fp", false); 258930dee2cSSjoerd Meijer break; 259930dee2cSSjoerd Meijer case ARMBuildAttrs::AllowMVEInteger: 260930dee2cSSjoerd Meijer Features.AddFeature("mve.fp", false); 261930dee2cSSjoerd Meijer Features.AddFeature("mve"); 262930dee2cSSjoerd Meijer break; 263930dee2cSSjoerd Meijer case ARMBuildAttrs::AllowMVEIntegerAndFloat: 264930dee2cSSjoerd Meijer Features.AddFeature("mve.fp"); 265930dee2cSSjoerd Meijer break; 266930dee2cSSjoerd Meijer } 267930dee2cSSjoerd Meijer } 268930dee2cSSjoerd Meijer 269581ba352SKai Wang Attr = Attributes.getAttributeValue(ARMBuildAttrs::DIV_use); 270581ba352SKai Wang if (Attr.hasValue()) { 271581ba352SKai Wang switch (Attr.getValue()) { 272b0de00d5SSam Parker default: 273b0de00d5SSam Parker break; 274b0de00d5SSam Parker case ARMBuildAttrs::DisallowDIV: 275b0de00d5SSam Parker Features.AddFeature("hwdiv", false); 276b0de00d5SSam Parker Features.AddFeature("hwdiv-arm", false); 277b0de00d5SSam Parker break; 278b0de00d5SSam Parker case ARMBuildAttrs::AllowDIVExt: 279b0de00d5SSam Parker Features.AddFeature("hwdiv"); 280b0de00d5SSam Parker Features.AddFeature("hwdiv-arm"); 281b0de00d5SSam Parker break; 282b0de00d5SSam Parker } 283b0de00d5SSam Parker } 284b0de00d5SSam Parker 285b0de00d5SSam Parker return Features; 286b0de00d5SSam Parker } 287b0de00d5SSam Parker 28853489adaSShiva Chen SubtargetFeatures ELFObjectFileBase::getRISCVFeatures() const { 28953489adaSShiva Chen SubtargetFeatures Features; 29053489adaSShiva Chen unsigned PlatformFlags = getPlatformFlags(); 29153489adaSShiva Chen 29253489adaSShiva Chen if (PlatformFlags & ELF::EF_RISCV_RVC) { 29353489adaSShiva Chen Features.AddFeature("c"); 29453489adaSShiva Chen } 29553489adaSShiva Chen 296581ba352SKai Wang // Add features according to the ELF attribute section. 297581ba352SKai Wang // If there are any unrecognized features, ignore them. 298581ba352SKai Wang RISCVAttributeParser Attributes; 29949e20c4cSJessica Clarke if (Error E = getBuildAttributes(Attributes)) { 30049e20c4cSJessica Clarke // TODO Propagate Error. 30149e20c4cSJessica Clarke consumeError(std::move(E)); 302581ba352SKai Wang return Features; // Keep "c" feature if there is one in PlatformFlags. 30349e20c4cSJessica Clarke } 304581ba352SKai Wang 305581ba352SKai Wang Optional<StringRef> Attr = Attributes.getAttributeString(RISCVAttrs::ARCH); 306581ba352SKai Wang if (Attr.hasValue()) { 307581ba352SKai Wang // The Arch pattern is [rv32|rv64][i|e]version(_[m|a|f|d|c]version)* 308581ba352SKai Wang // Version string pattern is (major)p(minor). Major and minor are optional. 309581ba352SKai Wang // For example, a version number could be 2p0, 2, or p92. 310581ba352SKai Wang StringRef Arch = Attr.getValue(); 311581ba352SKai Wang if (Arch.consume_front("rv32")) 312581ba352SKai Wang Features.AddFeature("64bit", false); 313581ba352SKai Wang else if (Arch.consume_front("rv64")) 314581ba352SKai Wang Features.AddFeature("64bit"); 315581ba352SKai Wang 316581ba352SKai Wang while (!Arch.empty()) { 317581ba352SKai Wang switch (Arch[0]) { 318581ba352SKai Wang default: 319581ba352SKai Wang break; // Ignore unexpected features. 320581ba352SKai Wang case 'i': 321581ba352SKai Wang Features.AddFeature("e", false); 322581ba352SKai Wang break; 323581ba352SKai Wang case 'd': 324581ba352SKai Wang Features.AddFeature("f"); // D-ext will imply F-ext. 325581ba352SKai Wang LLVM_FALLTHROUGH; 326581ba352SKai Wang case 'e': 327581ba352SKai Wang case 'm': 328581ba352SKai Wang case 'a': 329581ba352SKai Wang case 'f': 330581ba352SKai Wang case 'c': 331581ba352SKai Wang Features.AddFeature(Arch.take_front()); 332581ba352SKai Wang break; 333581ba352SKai Wang } 334581ba352SKai Wang 335581ba352SKai Wang // FIXME: Handle version numbers. 336581ba352SKai Wang Arch = Arch.drop_until([](char c) { return c == '_' || c == '\0'; }); 337581ba352SKai Wang Arch = Arch.drop_while([](char c) { return c == '_'; }); 338581ba352SKai Wang } 339581ba352SKai Wang } 340581ba352SKai Wang 34153489adaSShiva Chen return Features; 34253489adaSShiva Chen } 34353489adaSShiva Chen 344b0de00d5SSam Parker SubtargetFeatures ELFObjectFileBase::getFeatures() const { 345b0de00d5SSam Parker switch (getEMachine()) { 346b0de00d5SSam Parker case ELF::EM_MIPS: 347b0de00d5SSam Parker return getMIPSFeatures(); 348b0de00d5SSam Parker case ELF::EM_ARM: 349b0de00d5SSam Parker return getARMFeatures(); 35053489adaSShiva Chen case ELF::EM_RISCV: 35153489adaSShiva Chen return getRISCVFeatures(); 3521d14864bSDaniel Sanders default: 3531d14864bSDaniel Sanders return SubtargetFeatures(); 3541d14864bSDaniel Sanders } 3551d14864bSDaniel Sanders } 3561d14864bSDaniel Sanders 357e760e856SRonak Chauhan Optional<StringRef> ELFObjectFileBase::tryGetCPUName() const { 358e760e856SRonak Chauhan switch (getEMachine()) { 359e760e856SRonak Chauhan case ELF::EM_AMDGPU: 360e760e856SRonak Chauhan return getAMDGPUCPUName(); 361e760e856SRonak Chauhan default: 362e760e856SRonak Chauhan return None; 363e760e856SRonak Chauhan } 364e760e856SRonak Chauhan } 365e760e856SRonak Chauhan 366e760e856SRonak Chauhan StringRef ELFObjectFileBase::getAMDGPUCPUName() const { 367e760e856SRonak Chauhan assert(getEMachine() == ELF::EM_AMDGPU); 368e760e856SRonak Chauhan unsigned CPU = getPlatformFlags() & ELF::EF_AMDGPU_MACH; 369e760e856SRonak Chauhan 370e760e856SRonak Chauhan switch (CPU) { 371e760e856SRonak Chauhan // Radeon HD 2000/3000 Series (R600). 372e760e856SRonak Chauhan case ELF::EF_AMDGPU_MACH_R600_R600: 373e760e856SRonak Chauhan return "r600"; 374e760e856SRonak Chauhan case ELF::EF_AMDGPU_MACH_R600_R630: 375e760e856SRonak Chauhan return "r630"; 376e760e856SRonak Chauhan case ELF::EF_AMDGPU_MACH_R600_RS880: 377e760e856SRonak Chauhan return "rs880"; 378e760e856SRonak Chauhan case ELF::EF_AMDGPU_MACH_R600_RV670: 379e760e856SRonak Chauhan return "rv670"; 380e760e856SRonak Chauhan 381e760e856SRonak Chauhan // Radeon HD 4000 Series (R700). 382e760e856SRonak Chauhan case ELF::EF_AMDGPU_MACH_R600_RV710: 383e760e856SRonak Chauhan return "rv710"; 384e760e856SRonak Chauhan case ELF::EF_AMDGPU_MACH_R600_RV730: 385e760e856SRonak Chauhan return "rv730"; 386e760e856SRonak Chauhan case ELF::EF_AMDGPU_MACH_R600_RV770: 387e760e856SRonak Chauhan return "rv770"; 388e760e856SRonak Chauhan 389e760e856SRonak Chauhan // Radeon HD 5000 Series (Evergreen). 390e760e856SRonak Chauhan case ELF::EF_AMDGPU_MACH_R600_CEDAR: 391e760e856SRonak Chauhan return "cedar"; 392e760e856SRonak Chauhan case ELF::EF_AMDGPU_MACH_R600_CYPRESS: 393e760e856SRonak Chauhan return "cypress"; 394e760e856SRonak Chauhan case ELF::EF_AMDGPU_MACH_R600_JUNIPER: 395e760e856SRonak Chauhan return "juniper"; 396e760e856SRonak Chauhan case ELF::EF_AMDGPU_MACH_R600_REDWOOD: 397e760e856SRonak Chauhan return "redwood"; 398e760e856SRonak Chauhan case ELF::EF_AMDGPU_MACH_R600_SUMO: 399e760e856SRonak Chauhan return "sumo"; 400e760e856SRonak Chauhan 401e760e856SRonak Chauhan // Radeon HD 6000 Series (Northern Islands). 402e760e856SRonak Chauhan case ELF::EF_AMDGPU_MACH_R600_BARTS: 403e760e856SRonak Chauhan return "barts"; 404e760e856SRonak Chauhan case ELF::EF_AMDGPU_MACH_R600_CAICOS: 405e760e856SRonak Chauhan return "caicos"; 406e760e856SRonak Chauhan case ELF::EF_AMDGPU_MACH_R600_CAYMAN: 407e760e856SRonak Chauhan return "cayman"; 408e760e856SRonak Chauhan case ELF::EF_AMDGPU_MACH_R600_TURKS: 409e760e856SRonak Chauhan return "turks"; 410e760e856SRonak Chauhan 411e760e856SRonak Chauhan // AMDGCN GFX6. 412e760e856SRonak Chauhan case ELF::EF_AMDGPU_MACH_AMDGCN_GFX600: 413e760e856SRonak Chauhan return "gfx600"; 414e760e856SRonak Chauhan case ELF::EF_AMDGPU_MACH_AMDGCN_GFX601: 415e760e856SRonak Chauhan return "gfx601"; 416666ef0dbSTim Renouf case ELF::EF_AMDGPU_MACH_AMDGCN_GFX602: 417666ef0dbSTim Renouf return "gfx602"; 418e760e856SRonak Chauhan 419e760e856SRonak Chauhan // AMDGCN GFX7. 420e760e856SRonak Chauhan case ELF::EF_AMDGPU_MACH_AMDGCN_GFX700: 421e760e856SRonak Chauhan return "gfx700"; 422e760e856SRonak Chauhan case ELF::EF_AMDGPU_MACH_AMDGCN_GFX701: 423e760e856SRonak Chauhan return "gfx701"; 424e760e856SRonak Chauhan case ELF::EF_AMDGPU_MACH_AMDGCN_GFX702: 425e760e856SRonak Chauhan return "gfx702"; 426e760e856SRonak Chauhan case ELF::EF_AMDGPU_MACH_AMDGCN_GFX703: 427e760e856SRonak Chauhan return "gfx703"; 428e760e856SRonak Chauhan case ELF::EF_AMDGPU_MACH_AMDGCN_GFX704: 429e760e856SRonak Chauhan return "gfx704"; 430666ef0dbSTim Renouf case ELF::EF_AMDGPU_MACH_AMDGCN_GFX705: 431666ef0dbSTim Renouf return "gfx705"; 432e760e856SRonak Chauhan 433e760e856SRonak Chauhan // AMDGCN GFX8. 434e760e856SRonak Chauhan case ELF::EF_AMDGPU_MACH_AMDGCN_GFX801: 435e760e856SRonak Chauhan return "gfx801"; 436e760e856SRonak Chauhan case ELF::EF_AMDGPU_MACH_AMDGCN_GFX802: 437e760e856SRonak Chauhan return "gfx802"; 438e760e856SRonak Chauhan case ELF::EF_AMDGPU_MACH_AMDGCN_GFX803: 439e760e856SRonak Chauhan return "gfx803"; 440666ef0dbSTim Renouf case ELF::EF_AMDGPU_MACH_AMDGCN_GFX805: 441666ef0dbSTim Renouf return "gfx805"; 442e760e856SRonak Chauhan case ELF::EF_AMDGPU_MACH_AMDGCN_GFX810: 443e760e856SRonak Chauhan return "gfx810"; 444e760e856SRonak Chauhan 445e760e856SRonak Chauhan // AMDGCN GFX9. 446e760e856SRonak Chauhan case ELF::EF_AMDGPU_MACH_AMDGCN_GFX900: 447e760e856SRonak Chauhan return "gfx900"; 448e760e856SRonak Chauhan case ELF::EF_AMDGPU_MACH_AMDGCN_GFX902: 449e760e856SRonak Chauhan return "gfx902"; 450e760e856SRonak Chauhan case ELF::EF_AMDGPU_MACH_AMDGCN_GFX904: 451e760e856SRonak Chauhan return "gfx904"; 452e760e856SRonak Chauhan case ELF::EF_AMDGPU_MACH_AMDGCN_GFX906: 453e760e856SRonak Chauhan return "gfx906"; 454e760e856SRonak Chauhan case ELF::EF_AMDGPU_MACH_AMDGCN_GFX908: 455e760e856SRonak Chauhan return "gfx908"; 456e760e856SRonak Chauhan case ELF::EF_AMDGPU_MACH_AMDGCN_GFX909: 457e760e856SRonak Chauhan return "gfx909"; 458a8d9d507SStanislav Mekhanoshin case ELF::EF_AMDGPU_MACH_AMDGCN_GFX90A: 459a8d9d507SStanislav Mekhanoshin return "gfx90a"; 460ee3e6426STim Renouf case ELF::EF_AMDGPU_MACH_AMDGCN_GFX90C: 461ee3e6426STim Renouf return "gfx90c"; 4622e2e64dfSStanislav Mekhanoshin case ELF::EF_AMDGPU_MACH_AMDGCN_GFX940: 4632e2e64dfSStanislav Mekhanoshin return "gfx940"; 464e760e856SRonak Chauhan 465e760e856SRonak Chauhan // AMDGCN GFX10. 466e760e856SRonak Chauhan case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1010: 467e760e856SRonak Chauhan return "gfx1010"; 468e760e856SRonak Chauhan case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1011: 469e760e856SRonak Chauhan return "gfx1011"; 470e760e856SRonak Chauhan case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1012: 471e760e856SRonak Chauhan return "gfx1012"; 472294efbbdSBrendon Cahoon case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1013: 473294efbbdSBrendon Cahoon return "gfx1013"; 474e760e856SRonak Chauhan case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1030: 475e760e856SRonak Chauhan return "gfx1030"; 47659840978STony case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1031: 47759840978STony return "gfx1031"; 47859840978STony case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1032: 47959840978STony return "gfx1032"; 48089d41f3aSTim Renouf case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1033: 48189d41f3aSTim Renouf return "gfx1033"; 482464e4dc5SAakanksha Patil case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1034: 483464e4dc5SAakanksha Patil return "gfx1034"; 4843453f3ddSAakanksha Patil case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1035: 4853453f3ddSAakanksha Patil return "gfx1035"; 48684069581SAakanksha case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1036: 48784069581SAakanksha return "gfx1036"; 488813e521eSJoe Nash 489813e521eSJoe Nash // AMDGCN GFX11. 490813e521eSJoe Nash case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1100: 491813e521eSJoe Nash return "gfx1100"; 492813e521eSJoe Nash case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1101: 493813e521eSJoe Nash return "gfx1101"; 494813e521eSJoe Nash case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1102: 495813e521eSJoe Nash return "gfx1102"; 496813e521eSJoe Nash case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1103: 497813e521eSJoe Nash return "gfx1103"; 498e760e856SRonak Chauhan default: 499e760e856SRonak Chauhan llvm_unreachable("Unknown EF_AMDGPU_MACH value"); 500e760e856SRonak Chauhan } 501e760e856SRonak Chauhan } 502e760e856SRonak Chauhan 503df7c6ef9SSam Parker // FIXME Encode from a tablegen description or target parser. 504df7c6ef9SSam Parker void ELFObjectFileBase::setARMSubArch(Triple &TheTriple) const { 505df7c6ef9SSam Parker if (TheTriple.getSubArch() != Triple::NoSubArch) 506df7c6ef9SSam Parker return; 507df7c6ef9SSam Parker 508df7c6ef9SSam Parker ARMAttributeParser Attributes; 509791efb14SFangrui Song if (Error E = getBuildAttributes(Attributes)) { 510791efb14SFangrui Song // TODO Propagate Error. 511791efb14SFangrui Song consumeError(std::move(E)); 512df7c6ef9SSam Parker return; 513791efb14SFangrui Song } 514df7c6ef9SSam Parker 515df7c6ef9SSam Parker std::string Triple; 516df7c6ef9SSam Parker // Default to ARM, but use the triple if it's been set. 517a5ba4ee8SFlorian Hahn if (TheTriple.isThumb()) 518df7c6ef9SSam Parker Triple = "thumb"; 519df7c6ef9SSam Parker else 520df7c6ef9SSam Parker Triple = "arm"; 521df7c6ef9SSam Parker 522581ba352SKai Wang Optional<unsigned> Attr = 523581ba352SKai Wang Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch); 524581ba352SKai Wang if (Attr.hasValue()) { 525581ba352SKai Wang switch (Attr.getValue()) { 526df7c6ef9SSam Parker case ARMBuildAttrs::v4: 527df7c6ef9SSam Parker Triple += "v4"; 528df7c6ef9SSam Parker break; 529df7c6ef9SSam Parker case ARMBuildAttrs::v4T: 530df7c6ef9SSam Parker Triple += "v4t"; 531df7c6ef9SSam Parker break; 532df7c6ef9SSam Parker case ARMBuildAttrs::v5T: 533df7c6ef9SSam Parker Triple += "v5t"; 534df7c6ef9SSam Parker break; 535df7c6ef9SSam Parker case ARMBuildAttrs::v5TE: 536df7c6ef9SSam Parker Triple += "v5te"; 537df7c6ef9SSam Parker break; 538df7c6ef9SSam Parker case ARMBuildAttrs::v5TEJ: 539df7c6ef9SSam Parker Triple += "v5tej"; 540df7c6ef9SSam Parker break; 541df7c6ef9SSam Parker case ARMBuildAttrs::v6: 542df7c6ef9SSam Parker Triple += "v6"; 543df7c6ef9SSam Parker break; 544df7c6ef9SSam Parker case ARMBuildAttrs::v6KZ: 545df7c6ef9SSam Parker Triple += "v6kz"; 546df7c6ef9SSam Parker break; 547df7c6ef9SSam Parker case ARMBuildAttrs::v6T2: 548df7c6ef9SSam Parker Triple += "v6t2"; 549df7c6ef9SSam Parker break; 550df7c6ef9SSam Parker case ARMBuildAttrs::v6K: 551df7c6ef9SSam Parker Triple += "v6k"; 552df7c6ef9SSam Parker break; 5534adcff0bSEli Friedman case ARMBuildAttrs::v7: { 5544adcff0bSEli Friedman Optional<unsigned> ArchProfileAttr = 5554adcff0bSEli Friedman Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch_profile); 5564adcff0bSEli Friedman if (ArchProfileAttr.hasValue() && 5574adcff0bSEli Friedman ArchProfileAttr.getValue() == ARMBuildAttrs::MicroControllerProfile) 5584adcff0bSEli Friedman Triple += "v7m"; 5594adcff0bSEli Friedman else 560df7c6ef9SSam Parker Triple += "v7"; 561df7c6ef9SSam Parker break; 5624adcff0bSEli Friedman } 563df7c6ef9SSam Parker case ARMBuildAttrs::v6_M: 564df7c6ef9SSam Parker Triple += "v6m"; 565df7c6ef9SSam Parker break; 566df7c6ef9SSam Parker case ARMBuildAttrs::v6S_M: 567df7c6ef9SSam Parker Triple += "v6sm"; 568df7c6ef9SSam Parker break; 569df7c6ef9SSam Parker case ARMBuildAttrs::v7E_M: 570df7c6ef9SSam Parker Triple += "v7em"; 571df7c6ef9SSam Parker break; 572b9d87b95SYi Kong case ARMBuildAttrs::v8_A: 573b9d87b95SYi Kong Triple += "v8a"; 574b9d87b95SYi Kong break; 575b9d87b95SYi Kong case ARMBuildAttrs::v8_R: 576b9d87b95SYi Kong Triple += "v8r"; 577b9d87b95SYi Kong break; 578b9d87b95SYi Kong case ARMBuildAttrs::v8_M_Base: 579b9d87b95SYi Kong Triple += "v8m.base"; 580b9d87b95SYi Kong break; 581b9d87b95SYi Kong case ARMBuildAttrs::v8_M_Main: 582b9d87b95SYi Kong Triple += "v8m.main"; 583b9d87b95SYi Kong break; 584b9d87b95SYi Kong case ARMBuildAttrs::v8_1_M_Main: 585b9d87b95SYi Kong Triple += "v8.1m.main"; 586b9d87b95SYi Kong break; 587051deb2dSTies Stuij case ARMBuildAttrs::v9_A: 588051deb2dSTies Stuij Triple += "v9a"; 589051deb2dSTies Stuij break; 590df7c6ef9SSam Parker } 591df7c6ef9SSam Parker } 592df7c6ef9SSam Parker if (!isLittleEndian()) 593df7c6ef9SSam Parker Triple += "eb"; 594df7c6ef9SSam Parker 595df7c6ef9SSam Parker TheTriple.setArchName(Triple); 596df7c6ef9SSam Parker } 597d36fb48aSJoel Galenson 5987f8c49b0SFangrui Song std::vector<std::pair<Optional<DataRefImpl>, uint64_t>> 599d36fb48aSJoel Galenson ELFObjectFileBase::getPltAddresses() const { 600d36fb48aSJoel Galenson std::string Err; 601d36fb48aSJoel Galenson const auto Triple = makeTriple(); 602d36fb48aSJoel Galenson const auto *T = TargetRegistry::lookupTarget(Triple.str(), Err); 603d36fb48aSJoel Galenson if (!T) 604d36fb48aSJoel Galenson return {}; 605d36fb48aSJoel Galenson uint64_t JumpSlotReloc = 0; 606d36fb48aSJoel Galenson switch (Triple.getArch()) { 607d36fb48aSJoel Galenson case Triple::x86: 608d36fb48aSJoel Galenson JumpSlotReloc = ELF::R_386_JUMP_SLOT; 609d36fb48aSJoel Galenson break; 610d36fb48aSJoel Galenson case Triple::x86_64: 611d36fb48aSJoel Galenson JumpSlotReloc = ELF::R_X86_64_JUMP_SLOT; 612d36fb48aSJoel Galenson break; 613d36fb48aSJoel Galenson case Triple::aarch64: 614157ac423SFangrui Song case Triple::aarch64_be: 615d36fb48aSJoel Galenson JumpSlotReloc = ELF::R_AARCH64_JUMP_SLOT; 616d36fb48aSJoel Galenson break; 617d36fb48aSJoel Galenson default: 618d36fb48aSJoel Galenson return {}; 619d36fb48aSJoel Galenson } 62096cbeffaSVitaly Buka std::unique_ptr<const MCInstrInfo> MII(T->createMCInstrInfo()); 62190f976a4SJoel Galenson std::unique_ptr<const MCInstrAnalysis> MIA( 62296cbeffaSVitaly Buka T->createMCInstrAnalysis(MII.get())); 623d36fb48aSJoel Galenson if (!MIA) 624d36fb48aSJoel Galenson return {}; 625d36fb48aSJoel Galenson Optional<SectionRef> Plt = None, RelaPlt = None, GotPlt = None; 626d36fb48aSJoel Galenson for (const SectionRef &Section : sections()) { 627bcc00e1aSGeorge Rimar Expected<StringRef> NameOrErr = Section.getName(); 628bcc00e1aSGeorge Rimar if (!NameOrErr) { 629bcc00e1aSGeorge Rimar consumeError(NameOrErr.takeError()); 630d36fb48aSJoel Galenson continue; 631bcc00e1aSGeorge Rimar } 632bcc00e1aSGeorge Rimar StringRef Name = *NameOrErr; 633bcc00e1aSGeorge Rimar 634d36fb48aSJoel Galenson if (Name == ".plt") 635d36fb48aSJoel Galenson Plt = Section; 636d36fb48aSJoel Galenson else if (Name == ".rela.plt" || Name == ".rel.plt") 637d36fb48aSJoel Galenson RelaPlt = Section; 638d36fb48aSJoel Galenson else if (Name == ".got.plt") 639d36fb48aSJoel Galenson GotPlt = Section; 640d36fb48aSJoel Galenson } 641d36fb48aSJoel Galenson if (!Plt || !RelaPlt || !GotPlt) 642d36fb48aSJoel Galenson return {}; 643e183340cSFangrui Song Expected<StringRef> PltContents = Plt->getContents(); 644e183340cSFangrui Song if (!PltContents) { 645e183340cSFangrui Song consumeError(PltContents.takeError()); 646d36fb48aSJoel Galenson return {}; 647e183340cSFangrui Song } 648e183340cSFangrui Song auto PltEntries = MIA->findPltEntries(Plt->getAddress(), 649e183340cSFangrui Song arrayRefFromStringRef(*PltContents), 650d36fb48aSJoel Galenson GotPlt->getAddress(), Triple); 651d36fb48aSJoel Galenson // Build a map from GOT entry virtual address to PLT entry virtual address. 652d36fb48aSJoel Galenson DenseMap<uint64_t, uint64_t> GotToPlt; 653d36fb48aSJoel Galenson for (const auto &Entry : PltEntries) 654d36fb48aSJoel Galenson GotToPlt.insert(std::make_pair(Entry.second, Entry.first)); 655d36fb48aSJoel Galenson // Find the relocations in the dynamic relocation table that point to 656d36fb48aSJoel Galenson // locations in the GOT for which we know the corresponding PLT entry. 6577f8c49b0SFangrui Song std::vector<std::pair<Optional<DataRefImpl>, uint64_t>> Result; 658d36fb48aSJoel Galenson for (const auto &Relocation : RelaPlt->relocations()) { 659d36fb48aSJoel Galenson if (Relocation.getType() != JumpSlotReloc) 660d36fb48aSJoel Galenson continue; 661d36fb48aSJoel Galenson auto PltEntryIter = GotToPlt.find(Relocation.getOffset()); 6627f8c49b0SFangrui Song if (PltEntryIter != GotToPlt.end()) { 6637f8c49b0SFangrui Song symbol_iterator Sym = Relocation.getSymbol(); 6647f8c49b0SFangrui Song if (Sym == symbol_end()) 6657f8c49b0SFangrui Song Result.emplace_back(None, PltEntryIter->second); 6667f8c49b0SFangrui Song else 6677f8c49b0SFangrui Song Result.emplace_back(Sym->getRawDataRefImpl(), PltEntryIter->second); 6687f8c49b0SFangrui Song } 669d36fb48aSJoel Galenson } 670d36fb48aSJoel Galenson return Result; 671d36fb48aSJoel Galenson } 67278cb1adcSFangrui Song 67378cb1adcSFangrui Song template <class ELFT> 674*5f7ef652SRahman Lavaee Expected<std::vector<BBAddrMap>> 675*5f7ef652SRahman Lavaee readBBAddrMapImpl(const ELFFile<ELFT> &EF, 676*5f7ef652SRahman Lavaee Optional<unsigned> TextSectionIndex) { 677*5f7ef652SRahman Lavaee using Elf_Shdr = typename ELFT::Shdr; 678*5f7ef652SRahman Lavaee std::vector<BBAddrMap> BBAddrMaps; 679*5f7ef652SRahman Lavaee const auto &Sections = cantFail(EF.sections()); 680*5f7ef652SRahman Lavaee for (const Elf_Shdr &Sec : Sections) { 681*5f7ef652SRahman Lavaee if (Sec.sh_type != ELF::SHT_LLVM_BB_ADDR_MAP) 682*5f7ef652SRahman Lavaee continue; 683*5f7ef652SRahman Lavaee if (TextSectionIndex) { 684*5f7ef652SRahman Lavaee Expected<const Elf_Shdr *> TextSecOrErr = EF.getSection(Sec.sh_link); 685*5f7ef652SRahman Lavaee if (!TextSecOrErr) 686*5f7ef652SRahman Lavaee return createError("unable to get the linked-to section for " + 687*5f7ef652SRahman Lavaee describe(EF, Sec) + ": " + 688*5f7ef652SRahman Lavaee toString(TextSecOrErr.takeError())); 689*5f7ef652SRahman Lavaee if (*TextSectionIndex != std::distance(Sections.begin(), *TextSecOrErr)) 690*5f7ef652SRahman Lavaee continue; 691*5f7ef652SRahman Lavaee } 692*5f7ef652SRahman Lavaee Expected<std::vector<BBAddrMap>> BBAddrMapOrErr = EF.decodeBBAddrMap(Sec); 693*5f7ef652SRahman Lavaee if (!BBAddrMapOrErr) 694*5f7ef652SRahman Lavaee return createError("unable to read " + describe(EF, Sec) + ": " + 695*5f7ef652SRahman Lavaee toString(BBAddrMapOrErr.takeError())); 696*5f7ef652SRahman Lavaee std::move(BBAddrMapOrErr->begin(), BBAddrMapOrErr->end(), 697*5f7ef652SRahman Lavaee std::back_inserter(BBAddrMaps)); 698*5f7ef652SRahman Lavaee } 699*5f7ef652SRahman Lavaee return BBAddrMaps; 700*5f7ef652SRahman Lavaee } 701*5f7ef652SRahman Lavaee 702*5f7ef652SRahman Lavaee template <class ELFT> 70378cb1adcSFangrui Song static Expected<std::vector<VersionEntry>> 70478cb1adcSFangrui Song readDynsymVersionsImpl(const ELFFile<ELFT> &EF, 70578cb1adcSFangrui Song ELFObjectFileBase::elf_symbol_iterator_range Symbols) { 70678cb1adcSFangrui Song using Elf_Shdr = typename ELFT::Shdr; 70778cb1adcSFangrui Song const Elf_Shdr *VerSec = nullptr; 70878cb1adcSFangrui Song const Elf_Shdr *VerNeedSec = nullptr; 70978cb1adcSFangrui Song const Elf_Shdr *VerDefSec = nullptr; 71078cb1adcSFangrui Song // The user should ensure sections() can't fail here. 71178cb1adcSFangrui Song for (const Elf_Shdr &Sec : cantFail(EF.sections())) { 71278cb1adcSFangrui Song if (Sec.sh_type == ELF::SHT_GNU_versym) 71378cb1adcSFangrui Song VerSec = &Sec; 71478cb1adcSFangrui Song else if (Sec.sh_type == ELF::SHT_GNU_verdef) 71578cb1adcSFangrui Song VerDefSec = &Sec; 71678cb1adcSFangrui Song else if (Sec.sh_type == ELF::SHT_GNU_verneed) 71778cb1adcSFangrui Song VerNeedSec = &Sec; 71878cb1adcSFangrui Song } 71978cb1adcSFangrui Song if (!VerSec) 72078cb1adcSFangrui Song return std::vector<VersionEntry>(); 72178cb1adcSFangrui Song 72278cb1adcSFangrui Song Expected<SmallVector<Optional<VersionEntry>, 0>> MapOrErr = 72378cb1adcSFangrui Song EF.loadVersionMap(VerNeedSec, VerDefSec); 72478cb1adcSFangrui Song if (!MapOrErr) 72578cb1adcSFangrui Song return MapOrErr.takeError(); 72678cb1adcSFangrui Song 72778cb1adcSFangrui Song std::vector<VersionEntry> Ret; 72878cb1adcSFangrui Song size_t I = 0; 729f240e528SKazu Hirata for (const ELFSymbolRef &Sym : Symbols) { 73078cb1adcSFangrui Song ++I; 73178cb1adcSFangrui Song Expected<const typename ELFT::Versym *> VerEntryOrErr = 73278cb1adcSFangrui Song EF.template getEntry<typename ELFT::Versym>(*VerSec, I); 73378cb1adcSFangrui Song if (!VerEntryOrErr) 73478cb1adcSFangrui Song return createError("unable to read an entry with index " + Twine(I) + 73578cb1adcSFangrui Song " from " + describe(EF, *VerSec) + ": " + 73678cb1adcSFangrui Song toString(VerEntryOrErr.takeError())); 73778cb1adcSFangrui Song 738f240e528SKazu Hirata Expected<uint32_t> FlagsOrErr = Sym.getFlags(); 73978cb1adcSFangrui Song if (!FlagsOrErr) 74078cb1adcSFangrui Song return createError("unable to read flags for symbol with index " + 74178cb1adcSFangrui Song Twine(I) + ": " + toString(FlagsOrErr.takeError())); 74278cb1adcSFangrui Song 74378cb1adcSFangrui Song bool IsDefault; 74478cb1adcSFangrui Song Expected<StringRef> VerOrErr = EF.getSymbolVersionByIndex( 74578cb1adcSFangrui Song (*VerEntryOrErr)->vs_index, IsDefault, *MapOrErr, 74678cb1adcSFangrui Song (*FlagsOrErr) & SymbolRef::SF_Undefined); 74778cb1adcSFangrui Song if (!VerOrErr) 74878cb1adcSFangrui Song return createError("unable to get a version for entry " + Twine(I) + 74978cb1adcSFangrui Song " of " + describe(EF, *VerSec) + ": " + 75078cb1adcSFangrui Song toString(VerOrErr.takeError())); 75178cb1adcSFangrui Song 75278cb1adcSFangrui Song Ret.push_back({(*VerOrErr).str(), IsDefault}); 75378cb1adcSFangrui Song } 75478cb1adcSFangrui Song 75578cb1adcSFangrui Song return Ret; 75678cb1adcSFangrui Song } 75778cb1adcSFangrui Song 75878cb1adcSFangrui Song Expected<std::vector<VersionEntry>> 75978cb1adcSFangrui Song ELFObjectFileBase::readDynsymVersions() const { 76078cb1adcSFangrui Song elf_symbol_iterator_range Symbols = getDynamicSymbolIterators(); 76178cb1adcSFangrui Song if (const auto *Obj = dyn_cast<ELF32LEObjectFile>(this)) 76278cb1adcSFangrui Song return readDynsymVersionsImpl(Obj->getELFFile(), Symbols); 76378cb1adcSFangrui Song if (const auto *Obj = dyn_cast<ELF32BEObjectFile>(this)) 76478cb1adcSFangrui Song return readDynsymVersionsImpl(Obj->getELFFile(), Symbols); 76578cb1adcSFangrui Song if (const auto *Obj = dyn_cast<ELF64LEObjectFile>(this)) 76678cb1adcSFangrui Song return readDynsymVersionsImpl(Obj->getELFFile(), Symbols); 76778cb1adcSFangrui Song return readDynsymVersionsImpl(cast<ELF64BEObjectFile>(this)->getELFFile(), 76878cb1adcSFangrui Song Symbols); 76978cb1adcSFangrui Song } 770*5f7ef652SRahman Lavaee 771*5f7ef652SRahman Lavaee Expected<std::vector<BBAddrMap>> 772*5f7ef652SRahman Lavaee ELFObjectFileBase::readBBAddrMap(Optional<unsigned> TextSectionIndex) const { 773*5f7ef652SRahman Lavaee if (const auto *Obj = dyn_cast<ELF32LEObjectFile>(this)) 774*5f7ef652SRahman Lavaee return readBBAddrMapImpl(Obj->getELFFile(), TextSectionIndex); 775*5f7ef652SRahman Lavaee if (const auto *Obj = dyn_cast<ELF64LEObjectFile>(this)) 776*5f7ef652SRahman Lavaee return readBBAddrMapImpl(Obj->getELFFile(), TextSectionIndex); 777*5f7ef652SRahman Lavaee if (const auto *Obj = dyn_cast<ELF32BEObjectFile>(this)) 778*5f7ef652SRahman Lavaee return readBBAddrMapImpl(Obj->getELFFile(), TextSectionIndex); 779*5f7ef652SRahman Lavaee if (const auto *Obj = cast<ELF64BEObjectFile>(this)) 780*5f7ef652SRahman Lavaee return readBBAddrMapImpl(Obj->getELFFile(), TextSectionIndex); 781*5f7ef652SRahman Lavaee else 782*5f7ef652SRahman Lavaee llvm_unreachable("Unsupported binary format"); 783*5f7ef652SRahman Lavaee } 784