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