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"; 462*2e2e64dfSStanislav Mekhanoshin case ELF::EF_AMDGPU_MACH_AMDGCN_GFX940: 463*2e2e64dfSStanislav 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"; 486e760e856SRonak Chauhan default: 487e760e856SRonak Chauhan llvm_unreachable("Unknown EF_AMDGPU_MACH value"); 488e760e856SRonak Chauhan } 489e760e856SRonak Chauhan } 490e760e856SRonak Chauhan 491df7c6ef9SSam Parker // FIXME Encode from a tablegen description or target parser. 492df7c6ef9SSam Parker void ELFObjectFileBase::setARMSubArch(Triple &TheTriple) const { 493df7c6ef9SSam Parker if (TheTriple.getSubArch() != Triple::NoSubArch) 494df7c6ef9SSam Parker return; 495df7c6ef9SSam Parker 496df7c6ef9SSam Parker ARMAttributeParser Attributes; 497791efb14SFangrui Song if (Error E = getBuildAttributes(Attributes)) { 498791efb14SFangrui Song // TODO Propagate Error. 499791efb14SFangrui Song consumeError(std::move(E)); 500df7c6ef9SSam Parker return; 501791efb14SFangrui Song } 502df7c6ef9SSam Parker 503df7c6ef9SSam Parker std::string Triple; 504df7c6ef9SSam Parker // Default to ARM, but use the triple if it's been set. 505a5ba4ee8SFlorian Hahn if (TheTriple.isThumb()) 506df7c6ef9SSam Parker Triple = "thumb"; 507df7c6ef9SSam Parker else 508df7c6ef9SSam Parker Triple = "arm"; 509df7c6ef9SSam Parker 510581ba352SKai Wang Optional<unsigned> Attr = 511581ba352SKai Wang Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch); 512581ba352SKai Wang if (Attr.hasValue()) { 513581ba352SKai Wang switch (Attr.getValue()) { 514df7c6ef9SSam Parker case ARMBuildAttrs::v4: 515df7c6ef9SSam Parker Triple += "v4"; 516df7c6ef9SSam Parker break; 517df7c6ef9SSam Parker case ARMBuildAttrs::v4T: 518df7c6ef9SSam Parker Triple += "v4t"; 519df7c6ef9SSam Parker break; 520df7c6ef9SSam Parker case ARMBuildAttrs::v5T: 521df7c6ef9SSam Parker Triple += "v5t"; 522df7c6ef9SSam Parker break; 523df7c6ef9SSam Parker case ARMBuildAttrs::v5TE: 524df7c6ef9SSam Parker Triple += "v5te"; 525df7c6ef9SSam Parker break; 526df7c6ef9SSam Parker case ARMBuildAttrs::v5TEJ: 527df7c6ef9SSam Parker Triple += "v5tej"; 528df7c6ef9SSam Parker break; 529df7c6ef9SSam Parker case ARMBuildAttrs::v6: 530df7c6ef9SSam Parker Triple += "v6"; 531df7c6ef9SSam Parker break; 532df7c6ef9SSam Parker case ARMBuildAttrs::v6KZ: 533df7c6ef9SSam Parker Triple += "v6kz"; 534df7c6ef9SSam Parker break; 535df7c6ef9SSam Parker case ARMBuildAttrs::v6T2: 536df7c6ef9SSam Parker Triple += "v6t2"; 537df7c6ef9SSam Parker break; 538df7c6ef9SSam Parker case ARMBuildAttrs::v6K: 539df7c6ef9SSam Parker Triple += "v6k"; 540df7c6ef9SSam Parker break; 5414adcff0bSEli Friedman case ARMBuildAttrs::v7: { 5424adcff0bSEli Friedman Optional<unsigned> ArchProfileAttr = 5434adcff0bSEli Friedman Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch_profile); 5444adcff0bSEli Friedman if (ArchProfileAttr.hasValue() && 5454adcff0bSEli Friedman ArchProfileAttr.getValue() == ARMBuildAttrs::MicroControllerProfile) 5464adcff0bSEli Friedman Triple += "v7m"; 5474adcff0bSEli Friedman else 548df7c6ef9SSam Parker Triple += "v7"; 549df7c6ef9SSam Parker break; 5504adcff0bSEli Friedman } 551df7c6ef9SSam Parker case ARMBuildAttrs::v6_M: 552df7c6ef9SSam Parker Triple += "v6m"; 553df7c6ef9SSam Parker break; 554df7c6ef9SSam Parker case ARMBuildAttrs::v6S_M: 555df7c6ef9SSam Parker Triple += "v6sm"; 556df7c6ef9SSam Parker break; 557df7c6ef9SSam Parker case ARMBuildAttrs::v7E_M: 558df7c6ef9SSam Parker Triple += "v7em"; 559df7c6ef9SSam Parker break; 560b9d87b95SYi Kong case ARMBuildAttrs::v8_A: 561b9d87b95SYi Kong Triple += "v8a"; 562b9d87b95SYi Kong break; 563b9d87b95SYi Kong case ARMBuildAttrs::v8_R: 564b9d87b95SYi Kong Triple += "v8r"; 565b9d87b95SYi Kong break; 566b9d87b95SYi Kong case ARMBuildAttrs::v8_M_Base: 567b9d87b95SYi Kong Triple += "v8m.base"; 568b9d87b95SYi Kong break; 569b9d87b95SYi Kong case ARMBuildAttrs::v8_M_Main: 570b9d87b95SYi Kong Triple += "v8m.main"; 571b9d87b95SYi Kong break; 572b9d87b95SYi Kong case ARMBuildAttrs::v8_1_M_Main: 573b9d87b95SYi Kong Triple += "v8.1m.main"; 574b9d87b95SYi Kong break; 575df7c6ef9SSam Parker } 576df7c6ef9SSam Parker } 577df7c6ef9SSam Parker if (!isLittleEndian()) 578df7c6ef9SSam Parker Triple += "eb"; 579df7c6ef9SSam Parker 580df7c6ef9SSam Parker TheTriple.setArchName(Triple); 581df7c6ef9SSam Parker } 582d36fb48aSJoel Galenson 5837f8c49b0SFangrui Song std::vector<std::pair<Optional<DataRefImpl>, uint64_t>> 584d36fb48aSJoel Galenson ELFObjectFileBase::getPltAddresses() const { 585d36fb48aSJoel Galenson std::string Err; 586d36fb48aSJoel Galenson const auto Triple = makeTriple(); 587d36fb48aSJoel Galenson const auto *T = TargetRegistry::lookupTarget(Triple.str(), Err); 588d36fb48aSJoel Galenson if (!T) 589d36fb48aSJoel Galenson return {}; 590d36fb48aSJoel Galenson uint64_t JumpSlotReloc = 0; 591d36fb48aSJoel Galenson switch (Triple.getArch()) { 592d36fb48aSJoel Galenson case Triple::x86: 593d36fb48aSJoel Galenson JumpSlotReloc = ELF::R_386_JUMP_SLOT; 594d36fb48aSJoel Galenson break; 595d36fb48aSJoel Galenson case Triple::x86_64: 596d36fb48aSJoel Galenson JumpSlotReloc = ELF::R_X86_64_JUMP_SLOT; 597d36fb48aSJoel Galenson break; 598d36fb48aSJoel Galenson case Triple::aarch64: 599157ac423SFangrui Song case Triple::aarch64_be: 600d36fb48aSJoel Galenson JumpSlotReloc = ELF::R_AARCH64_JUMP_SLOT; 601d36fb48aSJoel Galenson break; 602d36fb48aSJoel Galenson default: 603d36fb48aSJoel Galenson return {}; 604d36fb48aSJoel Galenson } 60596cbeffaSVitaly Buka std::unique_ptr<const MCInstrInfo> MII(T->createMCInstrInfo()); 60690f976a4SJoel Galenson std::unique_ptr<const MCInstrAnalysis> MIA( 60796cbeffaSVitaly Buka T->createMCInstrAnalysis(MII.get())); 608d36fb48aSJoel Galenson if (!MIA) 609d36fb48aSJoel Galenson return {}; 610d36fb48aSJoel Galenson Optional<SectionRef> Plt = None, RelaPlt = None, GotPlt = None; 611d36fb48aSJoel Galenson for (const SectionRef &Section : sections()) { 612bcc00e1aSGeorge Rimar Expected<StringRef> NameOrErr = Section.getName(); 613bcc00e1aSGeorge Rimar if (!NameOrErr) { 614bcc00e1aSGeorge Rimar consumeError(NameOrErr.takeError()); 615d36fb48aSJoel Galenson continue; 616bcc00e1aSGeorge Rimar } 617bcc00e1aSGeorge Rimar StringRef Name = *NameOrErr; 618bcc00e1aSGeorge Rimar 619d36fb48aSJoel Galenson if (Name == ".plt") 620d36fb48aSJoel Galenson Plt = Section; 621d36fb48aSJoel Galenson else if (Name == ".rela.plt" || Name == ".rel.plt") 622d36fb48aSJoel Galenson RelaPlt = Section; 623d36fb48aSJoel Galenson else if (Name == ".got.plt") 624d36fb48aSJoel Galenson GotPlt = Section; 625d36fb48aSJoel Galenson } 626d36fb48aSJoel Galenson if (!Plt || !RelaPlt || !GotPlt) 627d36fb48aSJoel Galenson return {}; 628e183340cSFangrui Song Expected<StringRef> PltContents = Plt->getContents(); 629e183340cSFangrui Song if (!PltContents) { 630e183340cSFangrui Song consumeError(PltContents.takeError()); 631d36fb48aSJoel Galenson return {}; 632e183340cSFangrui Song } 633e183340cSFangrui Song auto PltEntries = MIA->findPltEntries(Plt->getAddress(), 634e183340cSFangrui Song arrayRefFromStringRef(*PltContents), 635d36fb48aSJoel Galenson GotPlt->getAddress(), Triple); 636d36fb48aSJoel Galenson // Build a map from GOT entry virtual address to PLT entry virtual address. 637d36fb48aSJoel Galenson DenseMap<uint64_t, uint64_t> GotToPlt; 638d36fb48aSJoel Galenson for (const auto &Entry : PltEntries) 639d36fb48aSJoel Galenson GotToPlt.insert(std::make_pair(Entry.second, Entry.first)); 640d36fb48aSJoel Galenson // Find the relocations in the dynamic relocation table that point to 641d36fb48aSJoel Galenson // locations in the GOT for which we know the corresponding PLT entry. 6427f8c49b0SFangrui Song std::vector<std::pair<Optional<DataRefImpl>, uint64_t>> Result; 643d36fb48aSJoel Galenson for (const auto &Relocation : RelaPlt->relocations()) { 644d36fb48aSJoel Galenson if (Relocation.getType() != JumpSlotReloc) 645d36fb48aSJoel Galenson continue; 646d36fb48aSJoel Galenson auto PltEntryIter = GotToPlt.find(Relocation.getOffset()); 6477f8c49b0SFangrui Song if (PltEntryIter != GotToPlt.end()) { 6487f8c49b0SFangrui Song symbol_iterator Sym = Relocation.getSymbol(); 6497f8c49b0SFangrui Song if (Sym == symbol_end()) 6507f8c49b0SFangrui Song Result.emplace_back(None, PltEntryIter->second); 6517f8c49b0SFangrui Song else 6527f8c49b0SFangrui Song Result.emplace_back(Sym->getRawDataRefImpl(), PltEntryIter->second); 6537f8c49b0SFangrui Song } 654d36fb48aSJoel Galenson } 655d36fb48aSJoel Galenson return Result; 656d36fb48aSJoel Galenson } 65778cb1adcSFangrui Song 65878cb1adcSFangrui Song template <class ELFT> 65978cb1adcSFangrui Song static Expected<std::vector<VersionEntry>> 66078cb1adcSFangrui Song readDynsymVersionsImpl(const ELFFile<ELFT> &EF, 66178cb1adcSFangrui Song ELFObjectFileBase::elf_symbol_iterator_range Symbols) { 66278cb1adcSFangrui Song using Elf_Shdr = typename ELFT::Shdr; 66378cb1adcSFangrui Song const Elf_Shdr *VerSec = nullptr; 66478cb1adcSFangrui Song const Elf_Shdr *VerNeedSec = nullptr; 66578cb1adcSFangrui Song const Elf_Shdr *VerDefSec = nullptr; 66678cb1adcSFangrui Song // The user should ensure sections() can't fail here. 66778cb1adcSFangrui Song for (const Elf_Shdr &Sec : cantFail(EF.sections())) { 66878cb1adcSFangrui Song if (Sec.sh_type == ELF::SHT_GNU_versym) 66978cb1adcSFangrui Song VerSec = &Sec; 67078cb1adcSFangrui Song else if (Sec.sh_type == ELF::SHT_GNU_verdef) 67178cb1adcSFangrui Song VerDefSec = &Sec; 67278cb1adcSFangrui Song else if (Sec.sh_type == ELF::SHT_GNU_verneed) 67378cb1adcSFangrui Song VerNeedSec = &Sec; 67478cb1adcSFangrui Song } 67578cb1adcSFangrui Song if (!VerSec) 67678cb1adcSFangrui Song return std::vector<VersionEntry>(); 67778cb1adcSFangrui Song 67878cb1adcSFangrui Song Expected<SmallVector<Optional<VersionEntry>, 0>> MapOrErr = 67978cb1adcSFangrui Song EF.loadVersionMap(VerNeedSec, VerDefSec); 68078cb1adcSFangrui Song if (!MapOrErr) 68178cb1adcSFangrui Song return MapOrErr.takeError(); 68278cb1adcSFangrui Song 68378cb1adcSFangrui Song std::vector<VersionEntry> Ret; 68478cb1adcSFangrui Song size_t I = 0; 685f240e528SKazu Hirata for (const ELFSymbolRef &Sym : Symbols) { 68678cb1adcSFangrui Song ++I; 68778cb1adcSFangrui Song Expected<const typename ELFT::Versym *> VerEntryOrErr = 68878cb1adcSFangrui Song EF.template getEntry<typename ELFT::Versym>(*VerSec, I); 68978cb1adcSFangrui Song if (!VerEntryOrErr) 69078cb1adcSFangrui Song return createError("unable to read an entry with index " + Twine(I) + 69178cb1adcSFangrui Song " from " + describe(EF, *VerSec) + ": " + 69278cb1adcSFangrui Song toString(VerEntryOrErr.takeError())); 69378cb1adcSFangrui Song 694f240e528SKazu Hirata Expected<uint32_t> FlagsOrErr = Sym.getFlags(); 69578cb1adcSFangrui Song if (!FlagsOrErr) 69678cb1adcSFangrui Song return createError("unable to read flags for symbol with index " + 69778cb1adcSFangrui Song Twine(I) + ": " + toString(FlagsOrErr.takeError())); 69878cb1adcSFangrui Song 69978cb1adcSFangrui Song bool IsDefault; 70078cb1adcSFangrui Song Expected<StringRef> VerOrErr = EF.getSymbolVersionByIndex( 70178cb1adcSFangrui Song (*VerEntryOrErr)->vs_index, IsDefault, *MapOrErr, 70278cb1adcSFangrui Song (*FlagsOrErr) & SymbolRef::SF_Undefined); 70378cb1adcSFangrui Song if (!VerOrErr) 70478cb1adcSFangrui Song return createError("unable to get a version for entry " + Twine(I) + 70578cb1adcSFangrui Song " of " + describe(EF, *VerSec) + ": " + 70678cb1adcSFangrui Song toString(VerOrErr.takeError())); 70778cb1adcSFangrui Song 70878cb1adcSFangrui Song Ret.push_back({(*VerOrErr).str(), IsDefault}); 70978cb1adcSFangrui Song } 71078cb1adcSFangrui Song 71178cb1adcSFangrui Song return Ret; 71278cb1adcSFangrui Song } 71378cb1adcSFangrui Song 71478cb1adcSFangrui Song Expected<std::vector<VersionEntry>> 71578cb1adcSFangrui Song ELFObjectFileBase::readDynsymVersions() const { 71678cb1adcSFangrui Song elf_symbol_iterator_range Symbols = getDynamicSymbolIterators(); 71778cb1adcSFangrui Song if (const auto *Obj = dyn_cast<ELF32LEObjectFile>(this)) 71878cb1adcSFangrui Song return readDynsymVersionsImpl(Obj->getELFFile(), Symbols); 71978cb1adcSFangrui Song if (const auto *Obj = dyn_cast<ELF32BEObjectFile>(this)) 72078cb1adcSFangrui Song return readDynsymVersionsImpl(Obj->getELFFile(), Symbols); 72178cb1adcSFangrui Song if (const auto *Obj = dyn_cast<ELF64LEObjectFile>(this)) 72278cb1adcSFangrui Song return readDynsymVersionsImpl(Obj->getELFFile(), Symbols); 72378cb1adcSFangrui Song return readDynsymVersionsImpl(cast<ELF64BEObjectFile>(this)->getELFFile(), 72478cb1adcSFangrui Song Symbols); 72578cb1adcSFangrui Song } 726