brintos

brintos / llvm-project-archived public Read only

0
0
Text · 32.2 KiB · 3f0ecbe Raw
1081 lines · cpp
1//===- ELFObjectFile.cpp - ELF object file implementation -----------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// Part of the ELFObjectFile class implementation.10//11//===----------------------------------------------------------------------===//12 13#include "llvm/Object/ELFObjectFile.h"14#include "llvm/BinaryFormat/ELF.h"15#include "llvm/MC/MCInstrAnalysis.h"16#include "llvm/MC/TargetRegistry.h"17#include "llvm/Object/ELF.h"18#include "llvm/Object/ELFTypes.h"19#include "llvm/Object/Error.h"20#include "llvm/Support/ARMAttributeParser.h"21#include "llvm/Support/ARMBuildAttributes.h"22#include "llvm/Support/ErrorHandling.h"23#include "llvm/Support/HexagonAttributeParser.h"24#include "llvm/Support/RISCVAttributeParser.h"25#include "llvm/Support/RISCVAttributes.h"26#include "llvm/TargetParser/RISCVISAInfo.h"27#include "llvm/TargetParser/SubtargetFeature.h"28#include "llvm/TargetParser/Triple.h"29#include <algorithm>30#include <cstddef>31#include <cstdint>32#include <memory>33#include <optional>34#include <string>35#include <utility>36 37using namespace llvm;38using namespace object;39 40const EnumEntry<unsigned> llvm::object::ElfSymbolTypes[NumElfSymbolTypes] = {41    {"None", "NOTYPE", ELF::STT_NOTYPE},42    {"Object", "OBJECT", ELF::STT_OBJECT},43    {"Function", "FUNC", ELF::STT_FUNC},44    {"Section", "SECTION", ELF::STT_SECTION},45    {"File", "FILE", ELF::STT_FILE},46    {"Common", "COMMON", ELF::STT_COMMON},47    {"TLS", "TLS", ELF::STT_TLS},48    {"Unknown", "<unknown>: 7", 7},49    {"Unknown", "<unknown>: 8", 8},50    {"Unknown", "<unknown>: 9", 9},51    {"GNU_IFunc", "IFUNC", ELF::STT_GNU_IFUNC},52    {"OS Specific", "<OS specific>: 11", 11},53    {"OS Specific", "<OS specific>: 12", 12},54    {"Proc Specific", "<processor specific>: 13", 13},55    {"Proc Specific", "<processor specific>: 14", 14},56    {"Proc Specific", "<processor specific>: 15", 15}57};58 59ELFObjectFileBase::ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source)60    : ObjectFile(Type, Source) {}61 62template <class ELFT>63static Expected<std::unique_ptr<ELFObjectFile<ELFT>>>64createPtr(MemoryBufferRef Object, bool InitContent) {65  auto Ret = ELFObjectFile<ELFT>::create(Object, InitContent);66  if (Error E = Ret.takeError())67    return std::move(E);68  return std::make_unique<ELFObjectFile<ELFT>>(std::move(*Ret));69}70 71Expected<std::unique_ptr<ObjectFile>>72ObjectFile::createELFObjectFile(MemoryBufferRef Obj, bool InitContent) {73  std::pair<unsigned char, unsigned char> Ident =74      getElfArchType(Obj.getBuffer());75  std::size_t MaxAlignment =76      1ULL << llvm::countr_zero(77          reinterpret_cast<uintptr_t>(Obj.getBufferStart()));78 79  if (MaxAlignment < 2)80    return createError("Insufficient alignment");81 82  if (Ident.first == ELF::ELFCLASS32) {83    if (Ident.second == ELF::ELFDATA2LSB)84      return createPtr<ELF32LE>(Obj, InitContent);85    else if (Ident.second == ELF::ELFDATA2MSB)86      return createPtr<ELF32BE>(Obj, InitContent);87    else88      return createError("Invalid ELF data");89  } else if (Ident.first == ELF::ELFCLASS64) {90    if (Ident.second == ELF::ELFDATA2LSB)91      return createPtr<ELF64LE>(Obj, InitContent);92    else if (Ident.second == ELF::ELFDATA2MSB)93      return createPtr<ELF64BE>(Obj, InitContent);94    else95      return createError("Invalid ELF data");96  }97  return createError("Invalid ELF class");98}99 100SubtargetFeatures ELFObjectFileBase::getMIPSFeatures() const {101  SubtargetFeatures Features;102  unsigned PlatformFlags = getPlatformFlags();103 104  switch (PlatformFlags & ELF::EF_MIPS_ARCH) {105  case ELF::EF_MIPS_ARCH_1:106    break;107  case ELF::EF_MIPS_ARCH_2:108    Features.AddFeature("mips2");109    break;110  case ELF::EF_MIPS_ARCH_3:111    Features.AddFeature("mips3");112    break;113  case ELF::EF_MIPS_ARCH_4:114    Features.AddFeature("mips4");115    break;116  case ELF::EF_MIPS_ARCH_5:117    Features.AddFeature("mips5");118    break;119  case ELF::EF_MIPS_ARCH_32:120    Features.AddFeature("mips32");121    break;122  case ELF::EF_MIPS_ARCH_64:123    Features.AddFeature("mips64");124    break;125  case ELF::EF_MIPS_ARCH_32R2:126    Features.AddFeature("mips32r2");127    break;128  case ELF::EF_MIPS_ARCH_64R2:129    Features.AddFeature("mips64r2");130    break;131  case ELF::EF_MIPS_ARCH_32R6:132    Features.AddFeature("mips32r6");133    break;134  case ELF::EF_MIPS_ARCH_64R6:135    Features.AddFeature("mips64r6");136    break;137  default:138    llvm_unreachable("Unknown EF_MIPS_ARCH value");139  }140 141  switch (PlatformFlags & ELF::EF_MIPS_MACH) {142  case ELF::EF_MIPS_MACH_NONE:143    // No feature associated with this value.144    break;145  case ELF::EF_MIPS_MACH_OCTEON:146    Features.AddFeature("cnmips");147    break;148  default:149    llvm_unreachable("Unknown EF_MIPS_ARCH value");150  }151 152  if (PlatformFlags & ELF::EF_MIPS_ARCH_ASE_M16)153    Features.AddFeature("mips16");154  if (PlatformFlags & ELF::EF_MIPS_MICROMIPS)155    Features.AddFeature("micromips");156 157  return Features;158}159 160SubtargetFeatures ELFObjectFileBase::getARMFeatures() const {161  SubtargetFeatures Features;162  ARMAttributeParser Attributes;163  if (Error E = getBuildAttributes(Attributes)) {164    consumeError(std::move(E));165    return SubtargetFeatures();166  }167 168  // both ARMv7-M and R have to support thumb hardware div169  bool isV7 = false;170  std::optional<unsigned> Attr =171      Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch);172  if (Attr)173    isV7 = *Attr == ARMBuildAttrs::v7;174 175  Attr = Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch_profile);176  if (Attr) {177    switch (*Attr) {178    case ARMBuildAttrs::ApplicationProfile:179      Features.AddFeature("aclass");180      break;181    case ARMBuildAttrs::RealTimeProfile:182      Features.AddFeature("rclass");183      if (isV7)184        Features.AddFeature("hwdiv");185      break;186    case ARMBuildAttrs::MicroControllerProfile:187      Features.AddFeature("mclass");188      if (isV7)189        Features.AddFeature("hwdiv");190      break;191    }192  }193 194  Attr = Attributes.getAttributeValue(ARMBuildAttrs::THUMB_ISA_use);195  if (Attr) {196    switch (*Attr) {197    default:198      break;199    case ARMBuildAttrs::Not_Allowed:200      Features.AddFeature("thumb", false);201      Features.AddFeature("thumb2", false);202      break;203    case ARMBuildAttrs::AllowThumb32:204      Features.AddFeature("thumb2");205      break;206    }207  }208 209  Attr = Attributes.getAttributeValue(ARMBuildAttrs::FP_arch);210  if (Attr) {211    switch (*Attr) {212    default:213      break;214    case ARMBuildAttrs::Not_Allowed:215      Features.AddFeature("vfp2sp", false);216      Features.AddFeature("vfp3d16sp", false);217      Features.AddFeature("vfp4d16sp", false);218      break;219    case ARMBuildAttrs::AllowFPv2:220      Features.AddFeature("vfp2");221      break;222    case ARMBuildAttrs::AllowFPv3A:223    case ARMBuildAttrs::AllowFPv3B:224      Features.AddFeature("vfp3");225      break;226    case ARMBuildAttrs::AllowFPv4A:227    case ARMBuildAttrs::AllowFPv4B:228      Features.AddFeature("vfp4");229      break;230    }231  }232 233  Attr = Attributes.getAttributeValue(ARMBuildAttrs::Advanced_SIMD_arch);234  if (Attr) {235    switch (*Attr) {236    default:237      break;238    case ARMBuildAttrs::Not_Allowed:239      Features.AddFeature("neon", false);240      Features.AddFeature("fp16", false);241      break;242    case ARMBuildAttrs::AllowNeon:243      Features.AddFeature("neon");244      break;245    case ARMBuildAttrs::AllowNeon2:246      Features.AddFeature("neon");247      Features.AddFeature("fp16");248      break;249    }250  }251 252  Attr = Attributes.getAttributeValue(ARMBuildAttrs::MVE_arch);253  if (Attr) {254    switch (*Attr) {255    default:256      break;257    case ARMBuildAttrs::Not_Allowed:258      Features.AddFeature("mve", false);259      Features.AddFeature("mve.fp", false);260      break;261    case ARMBuildAttrs::AllowMVEInteger:262      Features.AddFeature("mve.fp", false);263      Features.AddFeature("mve");264      break;265    case ARMBuildAttrs::AllowMVEIntegerAndFloat:266      Features.AddFeature("mve.fp");267      break;268    }269  }270 271  Attr = Attributes.getAttributeValue(ARMBuildAttrs::DIV_use);272  if (Attr) {273    switch (*Attr) {274    default:275      break;276    case ARMBuildAttrs::DisallowDIV:277      Features.AddFeature("hwdiv", false);278      Features.AddFeature("hwdiv-arm", false);279      break;280    case ARMBuildAttrs::AllowDIVExt:281      Features.AddFeature("hwdiv");282      Features.AddFeature("hwdiv-arm");283      break;284    }285  }286 287  return Features;288}289 290static std::optional<std::string> hexagonAttrToFeatureString(unsigned Attr) {291  switch (Attr) {292  case 5:293    return "v5";294  case 55:295    return "v55";296  case 60:297    return "v60";298  case 62:299    return "v62";300  case 65:301    return "v65";302  case 67:303    return "v67";304  case 68:305    return "v68";306  case 69:307    return "v69";308  case 71:309    return "v71";310  case 73:311    return "v73";312  case 75:313    return "v75";314  case 79:315    return "v79";316  case 81:317    return "v81";318  default:319    return {};320  }321}322 323SubtargetFeatures ELFObjectFileBase::getHexagonFeatures() const {324  SubtargetFeatures Features;325  HexagonAttributeParser Parser;326  if (Error E = getBuildAttributes(Parser)) {327    // Return no attributes if none can be read.328    // This behavior is important for backwards compatibility.329    consumeError(std::move(E));330    return Features;331  }332  std::optional<unsigned> Attr;333 334  if ((Attr = Parser.getAttributeValue(HexagonAttrs::ARCH))) {335    if (std::optional<std::string> FeatureString =336            hexagonAttrToFeatureString(*Attr))337      Features.AddFeature(*FeatureString);338  }339 340  if ((Attr = Parser.getAttributeValue(HexagonAttrs::HVXARCH))) {341    std::optional<std::string> FeatureString =342        hexagonAttrToFeatureString(*Attr);343    // There is no corresponding hvx arch for v5 and v55.344    if (FeatureString && *Attr >= 60)345      Features.AddFeature("hvx" + *FeatureString);346  }347 348  if ((Attr = Parser.getAttributeValue(HexagonAttrs::HVXIEEEFP)))349    if (*Attr)350      Features.AddFeature("hvx-ieee-fp");351 352  if ((Attr = Parser.getAttributeValue(HexagonAttrs::HVXQFLOAT)))353    if (*Attr)354      Features.AddFeature("hvx-qfloat");355 356  if ((Attr = Parser.getAttributeValue(HexagonAttrs::ZREG)))357    if (*Attr)358      Features.AddFeature("zreg");359 360  if ((Attr = Parser.getAttributeValue(HexagonAttrs::AUDIO)))361    if (*Attr)362      Features.AddFeature("audio");363 364  if ((Attr = Parser.getAttributeValue(HexagonAttrs::CABAC)))365    if (*Attr)366      Features.AddFeature("cabac");367 368  return Features;369}370 371Expected<SubtargetFeatures> ELFObjectFileBase::getRISCVFeatures() const {372  SubtargetFeatures Features;373  unsigned PlatformFlags = getPlatformFlags();374 375  if (PlatformFlags & ELF::EF_RISCV_RVC) {376    Features.AddFeature("zca");377  }378 379  RISCVAttributeParser Attributes;380  if (Error E = getBuildAttributes(Attributes)) {381    return std::move(E);382  }383 384  std::optional<StringRef> Attr =385      Attributes.getAttributeString(RISCVAttrs::ARCH);386  if (Attr) {387    auto ParseResult = RISCVISAInfo::parseNormalizedArchString(*Attr);388    if (!ParseResult)389      return ParseResult.takeError();390    auto &ISAInfo = *ParseResult;391 392    if (ISAInfo->getXLen() == 32)393      Features.AddFeature("64bit", false);394    else if (ISAInfo->getXLen() == 64)395      Features.AddFeature("64bit");396    else397      llvm_unreachable("XLEN should be 32 or 64.");398 399    Features.addFeaturesVector(ISAInfo->toFeatures());400  }401 402  return Features;403}404 405SubtargetFeatures ELFObjectFileBase::getLoongArchFeatures() const {406  SubtargetFeatures Features;407 408  switch (getPlatformFlags() & ELF::EF_LOONGARCH_ABI_MODIFIER_MASK) {409  case ELF::EF_LOONGARCH_ABI_SOFT_FLOAT:410    break;411  case ELF::EF_LOONGARCH_ABI_DOUBLE_FLOAT:412    Features.AddFeature("d");413    // D implies F according to LoongArch ISA spec.414    [[fallthrough]];415  case ELF::EF_LOONGARCH_ABI_SINGLE_FLOAT:416    Features.AddFeature("f");417    break;418  }419 420  return Features;421}422 423Expected<SubtargetFeatures> ELFObjectFileBase::getFeatures() const {424  switch (getEMachine()) {425  case ELF::EM_MIPS:426    return getMIPSFeatures();427  case ELF::EM_ARM:428    return getARMFeatures();429  case ELF::EM_RISCV:430    return getRISCVFeatures();431  case ELF::EM_LOONGARCH:432    return getLoongArchFeatures();433  case ELF::EM_HEXAGON:434    return getHexagonFeatures();435  default:436    return SubtargetFeatures();437  }438}439 440std::optional<StringRef> ELFObjectFileBase::tryGetCPUName() const {441  switch (getEMachine()) {442  case ELF::EM_AMDGPU:443    return getAMDGPUCPUName();444  case ELF::EM_CUDA:445    return getNVPTXCPUName();446  case ELF::EM_PPC:447  case ELF::EM_PPC64:448    return StringRef("future");449  case ELF::EM_BPF:450    return StringRef("v4");451  default:452    return std::nullopt;453  }454}455 456StringRef ELFObjectFileBase::getAMDGPUCPUName() const {457  assert(getEMachine() == ELF::EM_AMDGPU);458  unsigned CPU = getPlatformFlags() & ELF::EF_AMDGPU_MACH;459 460  switch (CPU) {461  // Radeon HD 2000/3000 Series (R600).462  case ELF::EF_AMDGPU_MACH_R600_R600:463    return "r600";464  case ELF::EF_AMDGPU_MACH_R600_R630:465    return "r630";466  case ELF::EF_AMDGPU_MACH_R600_RS880:467    return "rs880";468  case ELF::EF_AMDGPU_MACH_R600_RV670:469    return "rv670";470 471  // Radeon HD 4000 Series (R700).472  case ELF::EF_AMDGPU_MACH_R600_RV710:473    return "rv710";474  case ELF::EF_AMDGPU_MACH_R600_RV730:475    return "rv730";476  case ELF::EF_AMDGPU_MACH_R600_RV770:477    return "rv770";478 479  // Radeon HD 5000 Series (Evergreen).480  case ELF::EF_AMDGPU_MACH_R600_CEDAR:481    return "cedar";482  case ELF::EF_AMDGPU_MACH_R600_CYPRESS:483    return "cypress";484  case ELF::EF_AMDGPU_MACH_R600_JUNIPER:485    return "juniper";486  case ELF::EF_AMDGPU_MACH_R600_REDWOOD:487    return "redwood";488  case ELF::EF_AMDGPU_MACH_R600_SUMO:489    return "sumo";490 491  // Radeon HD 6000 Series (Northern Islands).492  case ELF::EF_AMDGPU_MACH_R600_BARTS:493    return "barts";494  case ELF::EF_AMDGPU_MACH_R600_CAICOS:495    return "caicos";496  case ELF::EF_AMDGPU_MACH_R600_CAYMAN:497    return "cayman";498  case ELF::EF_AMDGPU_MACH_R600_TURKS:499    return "turks";500 501  // AMDGCN GFX6.502  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX600:503    return "gfx600";504  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX601:505    return "gfx601";506  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX602:507    return "gfx602";508 509  // AMDGCN GFX7.510  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX700:511    return "gfx700";512  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX701:513    return "gfx701";514  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX702:515    return "gfx702";516  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX703:517    return "gfx703";518  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX704:519    return "gfx704";520  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX705:521    return "gfx705";522 523  // AMDGCN GFX8.524  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX801:525    return "gfx801";526  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX802:527    return "gfx802";528  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX803:529    return "gfx803";530  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX805:531    return "gfx805";532  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX810:533    return "gfx810";534 535  // AMDGCN GFX9.536  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX900:537    return "gfx900";538  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX902:539    return "gfx902";540  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX904:541    return "gfx904";542  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX906:543    return "gfx906";544  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX908:545    return "gfx908";546  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX909:547    return "gfx909";548  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX90A:549    return "gfx90a";550  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX90C:551    return "gfx90c";552  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX942:553    return "gfx942";554  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX950:555    return "gfx950";556 557  // AMDGCN GFX10.558  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1010:559    return "gfx1010";560  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1011:561    return "gfx1011";562  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1012:563    return "gfx1012";564  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1013:565    return "gfx1013";566  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1030:567    return "gfx1030";568  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1031:569    return "gfx1031";570  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1032:571    return "gfx1032";572  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1033:573    return "gfx1033";574  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1034:575    return "gfx1034";576  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1035:577    return "gfx1035";578  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1036:579    return "gfx1036";580 581  // AMDGCN GFX11.582  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1100:583    return "gfx1100";584  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1101:585    return "gfx1101";586  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1102:587    return "gfx1102";588  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1103:589    return "gfx1103";590  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1150:591    return "gfx1150";592  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1151:593    return "gfx1151";594  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1152:595    return "gfx1152";596  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1153:597    return "gfx1153";598 599  // AMDGCN GFX12.600  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1200:601    return "gfx1200";602  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1201:603    return "gfx1201";604  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1250:605    return "gfx1250";606  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1251:607    return "gfx1251";608 609  // Generic AMDGCN targets610  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX9_GENERIC:611    return "gfx9-generic";612  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX9_4_GENERIC:613    return "gfx9-4-generic";614  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX10_1_GENERIC:615    return "gfx10-1-generic";616  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX10_3_GENERIC:617    return "gfx10-3-generic";618  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX11_GENERIC:619    return "gfx11-generic";620  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX12_GENERIC:621    return "gfx12-generic";622  default:623    llvm_unreachable("Unknown EF_AMDGPU_MACH value");624  }625}626 627StringRef ELFObjectFileBase::getNVPTXCPUName() const {628  assert(getEMachine() == ELF::EM_CUDA);629  unsigned SM = getEIdentABIVersion() == ELF::ELFABIVERSION_CUDA_V1630                    ? getPlatformFlags() & ELF::EF_CUDA_SM631                    : (getPlatformFlags() & ELF::EF_CUDA_SM_MASK) >>632                          ELF::EF_CUDA_SM_OFFSET;633 634  switch (SM) {635  // Fermi architecture.636  case ELF::EF_CUDA_SM20:637    return "sm_20";638  case ELF::EF_CUDA_SM21:639    return "sm_21";640 641  // Kepler architecture.642  case ELF::EF_CUDA_SM30:643    return "sm_30";644  case ELF::EF_CUDA_SM32:645    return "sm_32";646  case ELF::EF_CUDA_SM35:647    return "sm_35";648  case ELF::EF_CUDA_SM37:649    return "sm_37";650 651  // Maxwell architecture.652  case ELF::EF_CUDA_SM50:653    return "sm_50";654  case ELF::EF_CUDA_SM52:655    return "sm_52";656  case ELF::EF_CUDA_SM53:657    return "sm_53";658 659  // Pascal architecture.660  case ELF::EF_CUDA_SM60:661    return "sm_60";662  case ELF::EF_CUDA_SM61:663    return "sm_61";664  case ELF::EF_CUDA_SM62:665    return "sm_62";666 667  // Volta architecture.668  case ELF::EF_CUDA_SM70:669    return "sm_70";670  case ELF::EF_CUDA_SM72:671    return "sm_72";672 673  // Turing architecture.674  case ELF::EF_CUDA_SM75:675    return "sm_75";676 677  // Ampere architecture.678  case ELF::EF_CUDA_SM80:679    return "sm_80";680  case ELF::EF_CUDA_SM86:681    return "sm_86";682  case ELF::EF_CUDA_SM87:683    return "sm_87";684  case ELF::EF_CUDA_SM88:685    return "sm_88";686 687  // Ada architecture.688  case ELF::EF_CUDA_SM89:689    return "sm_89";690 691  // Hopper architecture.692  case ELF::EF_CUDA_SM90:693    return getPlatformFlags() & ELF::EF_CUDA_ACCELERATORS_V1 ? "sm_90a"694                                                             : "sm_90";695 696  // Blackwell architecture.697  case ELF::EF_CUDA_SM100:698    return getPlatformFlags() & ELF::EF_CUDA_ACCELERATORS ? "sm_100a"699                                                          : "sm_100";700  case ELF::EF_CUDA_SM101:701    return getPlatformFlags() & ELF::EF_CUDA_ACCELERATORS ? "sm_101a"702                                                          : "sm_101";703  case ELF::EF_CUDA_SM103:704    return getPlatformFlags() & ELF::EF_CUDA_ACCELERATORS ? "sm_103a"705                                                          : "sm_103";706  case ELF::EF_CUDA_SM110:707    return getPlatformFlags() & ELF::EF_CUDA_ACCELERATORS ? "sm_110a"708                                                          : "sm_110";709 710  // Rubin architecture.711  case ELF::EF_CUDA_SM120:712    return getPlatformFlags() & ELF::EF_CUDA_ACCELERATORS ? "sm_120a"713                                                          : "sm_120";714  case ELF::EF_CUDA_SM121:715    return getPlatformFlags() & ELF::EF_CUDA_ACCELERATORS ? "sm_121a"716                                                          : "sm_121";717  default:718    llvm_unreachable("Unknown EF_CUDA_SM value");719  }720}721 722// FIXME Encode from a tablegen description or target parser.723void ELFObjectFileBase::setARMSubArch(Triple &TheTriple) const {724  if (TheTriple.getSubArch() != Triple::NoSubArch)725    return;726 727  ARMAttributeParser Attributes;728  if (Error E = getBuildAttributes(Attributes)) {729    // TODO Propagate Error.730    consumeError(std::move(E));731    return;732  }733 734  std::string Triple;735  // Default to ARM, but use the triple if it's been set.736  if (TheTriple.isThumb())737    Triple = "thumb";738  else739    Triple = "arm";740 741  std::optional<unsigned> Attr =742      Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch);743  if (Attr) {744    switch (*Attr) {745    case ARMBuildAttrs::v4:746      Triple += "v4";747      break;748    case ARMBuildAttrs::v4T:749      Triple += "v4t";750      break;751    case ARMBuildAttrs::v5T:752      Triple += "v5t";753      break;754    case ARMBuildAttrs::v5TE:755      Triple += "v5te";756      break;757    case ARMBuildAttrs::v5TEJ:758      Triple += "v5tej";759      break;760    case ARMBuildAttrs::v6:761      Triple += "v6";762      break;763    case ARMBuildAttrs::v6KZ:764      Triple += "v6kz";765      break;766    case ARMBuildAttrs::v6T2:767      Triple += "v6t2";768      break;769    case ARMBuildAttrs::v6K:770      Triple += "v6k";771      break;772    case ARMBuildAttrs::v7: {773      std::optional<unsigned> ArchProfileAttr =774          Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch_profile);775      if (ArchProfileAttr == ARMBuildAttrs::MicroControllerProfile)776        Triple += "v7m";777      else778        Triple += "v7";779      break;780    }781    case ARMBuildAttrs::v6_M:782      Triple += "v6m";783      break;784    case ARMBuildAttrs::v6S_M:785      Triple += "v6sm";786      break;787    case ARMBuildAttrs::v7E_M:788      Triple += "v7em";789      break;790    case ARMBuildAttrs::v8_A:791      Triple += "v8a";792      break;793    case ARMBuildAttrs::v8_R:794      Triple += "v8r";795      break;796    case ARMBuildAttrs::v8_M_Base:797      Triple += "v8m.base";798      break;799    case ARMBuildAttrs::v8_M_Main:800      Triple += "v8m.main";801      break;802    case ARMBuildAttrs::v8_1_M_Main:803      Triple += "v8.1m.main";804      break;805    case ARMBuildAttrs::v9_A:806      Triple += "v9a";807      break;808    }809  }810  if (!isLittleEndian())811    Triple += "eb";812 813  TheTriple.setArchName(Triple);814}815 816std::vector<ELFPltEntry>817ELFObjectFileBase::getPltEntries(const MCSubtargetInfo &STI) const {818  std::string Err;819  const auto Triple = makeTriple();820  const auto *T = TargetRegistry::lookupTarget(Triple, Err);821  if (!T)822    return {};823  uint32_t JumpSlotReloc = 0, GlobDatReloc = 0;824  switch (Triple.getArch()) {825    case Triple::x86:826      JumpSlotReloc = ELF::R_386_JUMP_SLOT;827      GlobDatReloc = ELF::R_386_GLOB_DAT;828      break;829    case Triple::x86_64:830      JumpSlotReloc = ELF::R_X86_64_JUMP_SLOT;831      GlobDatReloc = ELF::R_X86_64_GLOB_DAT;832      break;833    case Triple::aarch64:834    case Triple::aarch64_be:835      JumpSlotReloc = ELF::R_AARCH64_JUMP_SLOT;836      break;837    case Triple::arm:838    case Triple::armeb:839    case Triple::thumb:840    case Triple::thumbeb:841      JumpSlotReloc = ELF::R_ARM_JUMP_SLOT;842      break;843    case Triple::hexagon:844      JumpSlotReloc = ELF::R_HEX_JMP_SLOT;845      GlobDatReloc = ELF::R_HEX_GLOB_DAT;846      break;847    case Triple::riscv32:848    case Triple::riscv64:849      JumpSlotReloc = ELF::R_RISCV_JUMP_SLOT;850      break;851    default:852      return {};853  }854  std::unique_ptr<const MCInstrInfo> MII(T->createMCInstrInfo());855  std::unique_ptr<const MCInstrAnalysis> MIA(856      T->createMCInstrAnalysis(MII.get()));857  if (!MIA)858    return {};859  std::vector<std::pair<uint64_t, uint64_t>> PltEntries;860  std::optional<SectionRef> RelaPlt, RelaDyn;861  uint64_t GotBaseVA = 0;862  for (const SectionRef &Section : sections()) {863    Expected<StringRef> NameOrErr = Section.getName();864    if (!NameOrErr) {865      consumeError(NameOrErr.takeError());866      continue;867    }868    StringRef Name = *NameOrErr;869 870    if (Name == ".rela.plt" || Name == ".rel.plt") {871      RelaPlt = Section;872    } else if (Name == ".rela.dyn" || Name == ".rel.dyn") {873      RelaDyn = Section;874    } else if (Name == ".got.plt") {875      GotBaseVA = Section.getAddress();876    } else if (Name == ".plt" || Name == ".plt.got") {877      Expected<StringRef> PltContents = Section.getContents();878      if (!PltContents) {879        consumeError(PltContents.takeError());880        return {};881      }882      llvm::append_range(883          PltEntries,884          MIA->findPltEntries(Section.getAddress(),885                              arrayRefFromStringRef(*PltContents), STI));886    }887  }888 889  // Build a map from GOT entry virtual address to PLT entry virtual address.890  DenseMap<uint64_t, uint64_t> GotToPlt;891  for (auto [Plt, GotPlt] : PltEntries) {892    uint64_t GotPltEntry = GotPlt;893    // An x86-32 PIC PLT uses jmp DWORD PTR [ebx-offset]. Add894    // _GLOBAL_OFFSET_TABLE_ (EBX) to get the .got.plt (or .got) entry address.895    // See X86MCTargetDesc.cpp:findPltEntries for the 1 << 32 bit.896    if (GotPltEntry & (uint64_t(1) << 32) && getEMachine() == ELF::EM_386)897      GotPltEntry = static_cast<int32_t>(GotPltEntry) + GotBaseVA;898    GotToPlt.insert(std::make_pair(GotPltEntry, Plt));899  }900 901  // Find the relocations in the dynamic relocation table that point to902  // locations in the GOT for which we know the corresponding PLT entry.903  std::vector<ELFPltEntry> Result;904  auto handleRels = [&](iterator_range<relocation_iterator> Rels,905                        uint32_t RelType, StringRef PltSec) {906    for (const auto &R : Rels) {907      if (R.getType() != RelType)908        continue;909      auto PltEntryIter = GotToPlt.find(R.getOffset());910      if (PltEntryIter != GotToPlt.end()) {911        symbol_iterator Sym = R.getSymbol();912        if (Sym == symbol_end())913          Result.push_back(914              ELFPltEntry{PltSec, std::nullopt, PltEntryIter->second});915        else916          Result.push_back(ELFPltEntry{PltSec, Sym->getRawDataRefImpl(),917                                       PltEntryIter->second});918      }919    }920  };921 922  if (RelaPlt)923    handleRels(RelaPlt->relocations(), JumpSlotReloc, ".plt");924 925  // If a symbol needing a PLT entry also needs a GLOB_DAT relocation, GNU ld's926  // x86 port places the PLT entry in the .plt.got section.927  if (RelaDyn)928    handleRels(RelaDyn->relocations(), GlobDatReloc, ".plt.got");929 930  return Result;931}932 933template <class ELFT>934Expected<std::vector<BBAddrMap>> static readBBAddrMapImpl(935    const ELFFile<ELFT> &EF, std::optional<unsigned> TextSectionIndex,936    std::vector<PGOAnalysisMap> *PGOAnalyses) {937  using Elf_Shdr = typename ELFT::Shdr;938  bool IsRelocatable = EF.getHeader().e_type == ELF::ET_REL;939  std::vector<BBAddrMap> BBAddrMaps;940  if (PGOAnalyses)941    PGOAnalyses->clear();942 943  const auto &Sections = cantFail(EF.sections());944  auto IsMatch = [&](const Elf_Shdr &Sec) -> Expected<bool> {945    if (Sec.sh_type != ELF::SHT_LLVM_BB_ADDR_MAP)946      return false;947    if (!TextSectionIndex)948      return true;949    Expected<const Elf_Shdr *> TextSecOrErr = EF.getSection(Sec.sh_link);950    if (!TextSecOrErr)951      return createError("unable to get the linked-to section for " +952                         describe(EF, Sec) + ": " +953                         toString(TextSecOrErr.takeError()));954    assert(*TextSecOrErr >= Sections.begin() &&955           "Text section pointer outside of bounds");956    if (*TextSectionIndex !=957        (unsigned)std::distance(Sections.begin(), *TextSecOrErr))958      return false;959    return true;960  };961 962  Expected<MapVector<const Elf_Shdr *, const Elf_Shdr *>> SectionRelocMapOrErr =963      EF.getSectionAndRelocations(IsMatch);964  if (!SectionRelocMapOrErr)965    return SectionRelocMapOrErr.takeError();966 967  for (auto const &[Sec, RelocSec] : *SectionRelocMapOrErr) {968    if (IsRelocatable && !RelocSec)969      return createError("unable to get relocation section for " +970                         describe(EF, *Sec));971    Expected<std::vector<BBAddrMap>> BBAddrMapOrErr =972        EF.decodeBBAddrMap(*Sec, RelocSec, PGOAnalyses);973    if (!BBAddrMapOrErr) {974      if (PGOAnalyses)975        PGOAnalyses->clear();976      return createError("unable to read " + describe(EF, *Sec) + ": " +977                         toString(BBAddrMapOrErr.takeError()));978    }979    std::move(BBAddrMapOrErr->begin(), BBAddrMapOrErr->end(),980              std::back_inserter(BBAddrMaps));981  }982  if (PGOAnalyses)983    assert(PGOAnalyses->size() == BBAddrMaps.size() &&984           "The same number of BBAddrMaps and PGOAnalysisMaps should be "985           "returned when PGO information is requested");986  return BBAddrMaps;987}988 989template <class ELFT>990static Expected<std::vector<VersionEntry>>991readDynsymVersionsImpl(const ELFFile<ELFT> &EF,992                       ELFObjectFileBase::elf_symbol_iterator_range Symbols) {993  using Elf_Shdr = typename ELFT::Shdr;994  const Elf_Shdr *VerSec = nullptr;995  const Elf_Shdr *VerNeedSec = nullptr;996  const Elf_Shdr *VerDefSec = nullptr;997  // The user should ensure sections() can't fail here.998  for (const Elf_Shdr &Sec : cantFail(EF.sections())) {999    if (Sec.sh_type == ELF::SHT_GNU_versym)1000      VerSec = &Sec;1001    else if (Sec.sh_type == ELF::SHT_GNU_verdef)1002      VerDefSec = &Sec;1003    else if (Sec.sh_type == ELF::SHT_GNU_verneed)1004      VerNeedSec = &Sec;1005  }1006  if (!VerSec)1007    return std::vector<VersionEntry>();1008 1009  Expected<SmallVector<std::optional<VersionEntry>, 0>> MapOrErr =1010      EF.loadVersionMap(VerNeedSec, VerDefSec);1011  if (!MapOrErr)1012    return MapOrErr.takeError();1013 1014  std::vector<VersionEntry> Ret;1015  size_t I = 0;1016  for (const ELFSymbolRef &Sym : Symbols) {1017    ++I;1018    Expected<const typename ELFT::Versym *> VerEntryOrErr =1019        EF.template getEntry<typename ELFT::Versym>(*VerSec, I);1020    if (!VerEntryOrErr)1021      return createError("unable to read an entry with index " + Twine(I) +1022                         " from " + describe(EF, *VerSec) + ": " +1023                         toString(VerEntryOrErr.takeError()));1024 1025    Expected<uint32_t> FlagsOrErr = Sym.getFlags();1026    if (!FlagsOrErr)1027      return createError("unable to read flags for symbol with index " +1028                         Twine(I) + ": " + toString(FlagsOrErr.takeError()));1029 1030    bool IsDefault;1031    Expected<StringRef> VerOrErr = EF.getSymbolVersionByIndex(1032        (*VerEntryOrErr)->vs_index, IsDefault, *MapOrErr,1033        (*FlagsOrErr) & SymbolRef::SF_Undefined);1034    if (!VerOrErr)1035      return createError("unable to get a version for entry " + Twine(I) +1036                         " of " + describe(EF, *VerSec) + ": " +1037                         toString(VerOrErr.takeError()));1038 1039    Ret.push_back({(*VerOrErr).str(), IsDefault});1040  }1041 1042  return Ret;1043}1044 1045Expected<std::vector<VersionEntry>>1046ELFObjectFileBase::readDynsymVersions() const {1047  elf_symbol_iterator_range Symbols = getDynamicSymbolIterators();1048  if (const auto *Obj = dyn_cast<ELF32LEObjectFile>(this))1049    return readDynsymVersionsImpl(Obj->getELFFile(), Symbols);1050  if (const auto *Obj = dyn_cast<ELF32BEObjectFile>(this))1051    return readDynsymVersionsImpl(Obj->getELFFile(), Symbols);1052  if (const auto *Obj = dyn_cast<ELF64LEObjectFile>(this))1053    return readDynsymVersionsImpl(Obj->getELFFile(), Symbols);1054  return readDynsymVersionsImpl(cast<ELF64BEObjectFile>(this)->getELFFile(),1055                                Symbols);1056}1057 1058Expected<std::vector<BBAddrMap>> ELFObjectFileBase::readBBAddrMap(1059    std::optional<unsigned> TextSectionIndex,1060    std::vector<PGOAnalysisMap> *PGOAnalyses) const {1061  if (const auto *Obj = dyn_cast<ELF32LEObjectFile>(this))1062    return readBBAddrMapImpl(Obj->getELFFile(), TextSectionIndex, PGOAnalyses);1063  if (const auto *Obj = dyn_cast<ELF64LEObjectFile>(this))1064    return readBBAddrMapImpl(Obj->getELFFile(), TextSectionIndex, PGOAnalyses);1065  if (const auto *Obj = dyn_cast<ELF32BEObjectFile>(this))1066    return readBBAddrMapImpl(Obj->getELFFile(), TextSectionIndex, PGOAnalyses);1067  return readBBAddrMapImpl(cast<ELF64BEObjectFile>(this)->getELFFile(),1068                           TextSectionIndex, PGOAnalyses);1069}1070 1071StringRef ELFObjectFileBase::getCrelDecodeProblem(SectionRef Sec) const {1072  auto Data = Sec.getRawDataRefImpl();1073  if (const auto *Obj = dyn_cast<ELF32LEObjectFile>(this))1074    return Obj->getCrelDecodeProblem(Data);1075  if (const auto *Obj = dyn_cast<ELF32BEObjectFile>(this))1076    return Obj->getCrelDecodeProblem(Data);1077  if (const auto *Obj = dyn_cast<ELF64LEObjectFile>(this))1078    return Obj->getCrelDecodeProblem(Data);1079  return cast<ELF64BEObjectFile>(this)->getCrelDecodeProblem(Data);1080}1081