1069 lines · cpp
1//===- ELF.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#include "llvm/Object/ELF.h"10#include "llvm/ADT/StringExtras.h"11#include "llvm/BinaryFormat/ELF.h"12#include "llvm/Object/Decompressor.h"13#include "llvm/Support/Compiler.h"14#include "llvm/Support/DataExtractor.h"15 16using namespace llvm;17using namespace object;18 19#define STRINGIFY_ENUM_CASE(ns, name) \20 case ns::name: \21 return #name;22 23#define ELF_RELOC(name, value) STRINGIFY_ENUM_CASE(ELF, name)24 25StringRef llvm::object::getELFRelocationTypeName(uint32_t Machine,26 uint32_t Type) {27 switch (Machine) {28 case ELF::EM_68K:29 switch (Type) {30#include "llvm/BinaryFormat/ELFRelocs/M68k.def"31 default:32 break;33 }34 break;35 case ELF::EM_X86_64:36 switch (Type) {37#include "llvm/BinaryFormat/ELFRelocs/x86_64.def"38 default:39 break;40 }41 break;42 case ELF::EM_386:43 case ELF::EM_IAMCU:44 switch (Type) {45#include "llvm/BinaryFormat/ELFRelocs/i386.def"46 default:47 break;48 }49 break;50 case ELF::EM_MIPS:51 switch (Type) {52#include "llvm/BinaryFormat/ELFRelocs/Mips.def"53 default:54 break;55 }56 break;57 case ELF::EM_AARCH64:58 switch (Type) {59#include "llvm/BinaryFormat/ELFRelocs/AArch64.def"60 default:61 break;62 }63 break;64 case ELF::EM_ARM:65 switch (Type) {66#include "llvm/BinaryFormat/ELFRelocs/ARM.def"67 default:68 break;69 }70 break;71 case ELF::EM_ARC_COMPACT:72 case ELF::EM_ARC_COMPACT2:73 switch (Type) {74#include "llvm/BinaryFormat/ELFRelocs/ARC.def"75 default:76 break;77 }78 break;79 case ELF::EM_AVR:80 switch (Type) {81#include "llvm/BinaryFormat/ELFRelocs/AVR.def"82 default:83 break;84 }85 break;86 case ELF::EM_HEXAGON:87 switch (Type) {88#include "llvm/BinaryFormat/ELFRelocs/Hexagon.def"89 default:90 break;91 }92 break;93 case ELF::EM_LANAI:94 switch (Type) {95#include "llvm/BinaryFormat/ELFRelocs/Lanai.def"96 default:97 break;98 }99 break;100 case ELF::EM_PPC:101 switch (Type) {102#include "llvm/BinaryFormat/ELFRelocs/PowerPC.def"103 default:104 break;105 }106 break;107 case ELF::EM_PPC64:108 switch (Type) {109#include "llvm/BinaryFormat/ELFRelocs/PowerPC64.def"110 default:111 break;112 }113 break;114 case ELF::EM_RISCV:115 switch (Type) {116#include "llvm/BinaryFormat/ELFRelocs/RISCV.def"117 default:118 break;119 }120 break;121 case ELF::EM_S390:122 switch (Type) {123#include "llvm/BinaryFormat/ELFRelocs/SystemZ.def"124 default:125 break;126 }127 break;128 case ELF::EM_SPARC:129 case ELF::EM_SPARC32PLUS:130 case ELF::EM_SPARCV9:131 switch (Type) {132#include "llvm/BinaryFormat/ELFRelocs/Sparc.def"133 default:134 break;135 }136 break;137 case ELF::EM_AMDGPU:138 switch (Type) {139#include "llvm/BinaryFormat/ELFRelocs/AMDGPU.def"140 default:141 break;142 }143 break;144 case ELF::EM_BPF:145 switch (Type) {146#include "llvm/BinaryFormat/ELFRelocs/BPF.def"147 default:148 break;149 }150 break;151 case ELF::EM_MSP430:152 switch (Type) {153#include "llvm/BinaryFormat/ELFRelocs/MSP430.def"154 default:155 break;156 }157 break;158 case ELF::EM_VE:159 switch (Type) {160#include "llvm/BinaryFormat/ELFRelocs/VE.def"161 default:162 break;163 }164 break;165 case ELF::EM_CSKY:166 switch (Type) {167#include "llvm/BinaryFormat/ELFRelocs/CSKY.def"168 default:169 break;170 }171 break;172 case ELF::EM_LOONGARCH:173 switch (Type) {174#include "llvm/BinaryFormat/ELFRelocs/LoongArch.def"175 default:176 break;177 }178 break;179 case ELF::EM_XTENSA:180 switch (Type) {181#include "llvm/BinaryFormat/ELFRelocs/Xtensa.def"182 default:183 break;184 }185 break;186 default:187 break;188 }189 return "Unknown";190}191 192#undef ELF_RELOC193 194StringRef llvm::object::getRISCVVendorRelocationTypeName(uint32_t Type,195 StringRef Vendor) {196#define ELF_RISCV_NONSTANDARD_RELOC(vendor, name, number) \197 if (Vendor == #vendor && Type == number) \198 return #name;199 200#include "llvm/BinaryFormat/ELFRelocs/RISCV_nonstandard.def"201 202#undef ELF_RISCV_NONSTANDARD_RELOC203 204 return "Unknown";205}206 207uint32_t llvm::object::getELFRelativeRelocationType(uint32_t Machine) {208 switch (Machine) {209 case ELF::EM_X86_64:210 return ELF::R_X86_64_RELATIVE;211 case ELF::EM_386:212 case ELF::EM_IAMCU:213 return ELF::R_386_RELATIVE;214 case ELF::EM_MIPS:215 break;216 case ELF::EM_AARCH64:217 return ELF::R_AARCH64_RELATIVE;218 case ELF::EM_ARM:219 return ELF::R_ARM_RELATIVE;220 case ELF::EM_ARC_COMPACT:221 case ELF::EM_ARC_COMPACT2:222 return ELF::R_ARC_RELATIVE;223 case ELF::EM_AVR:224 break;225 case ELF::EM_HEXAGON:226 return ELF::R_HEX_RELATIVE;227 case ELF::EM_LANAI:228 break;229 case ELF::EM_PPC:230 break;231 case ELF::EM_PPC64:232 return ELF::R_PPC64_RELATIVE;233 case ELF::EM_RISCV:234 return ELF::R_RISCV_RELATIVE;235 case ELF::EM_S390:236 return ELF::R_390_RELATIVE;237 case ELF::EM_SPARC:238 case ELF::EM_SPARC32PLUS:239 case ELF::EM_SPARCV9:240 return ELF::R_SPARC_RELATIVE;241 case ELF::EM_CSKY:242 return ELF::R_CKCORE_RELATIVE;243 case ELF::EM_VE:244 return ELF::R_VE_RELATIVE;245 case ELF::EM_AMDGPU:246 break;247 case ELF::EM_BPF:248 break;249 case ELF::EM_LOONGARCH:250 return ELF::R_LARCH_RELATIVE;251 default:252 break;253 }254 return 0;255}256 257StringRef llvm::object::getELFSectionTypeName(uint32_t Machine, unsigned Type) {258 switch (Machine) {259 case ELF::EM_ARM:260 switch (Type) {261 STRINGIFY_ENUM_CASE(ELF, SHT_ARM_EXIDX);262 STRINGIFY_ENUM_CASE(ELF, SHT_ARM_PREEMPTMAP);263 STRINGIFY_ENUM_CASE(ELF, SHT_ARM_ATTRIBUTES);264 STRINGIFY_ENUM_CASE(ELF, SHT_ARM_DEBUGOVERLAY);265 STRINGIFY_ENUM_CASE(ELF, SHT_ARM_OVERLAYSECTION);266 }267 break;268 case ELF::EM_HEXAGON:269 switch (Type) {270 STRINGIFY_ENUM_CASE(ELF, SHT_HEX_ORDERED);271 STRINGIFY_ENUM_CASE(ELF, SHT_HEXAGON_ATTRIBUTES);272 }273 break;274 case ELF::EM_X86_64:275 switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_X86_64_UNWIND); }276 break;277 case ELF::EM_MIPS:278 case ELF::EM_MIPS_RS3_LE:279 switch (Type) {280 STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_REGINFO);281 STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_OPTIONS);282 STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_DWARF);283 STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_ABIFLAGS);284 }285 break;286 case ELF::EM_MSP430:287 switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_MSP430_ATTRIBUTES); }288 break;289 case ELF::EM_RISCV:290 switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_RISCV_ATTRIBUTES); }291 break;292 case ELF::EM_AARCH64:293 switch (Type) {294 STRINGIFY_ENUM_CASE(ELF, SHT_AARCH64_AUTH_RELR);295 STRINGIFY_ENUM_CASE(ELF, SHT_AARCH64_MEMTAG_GLOBALS_DYNAMIC);296 STRINGIFY_ENUM_CASE(ELF, SHT_AARCH64_MEMTAG_GLOBALS_STATIC);297 }298 default:299 break;300 }301 302 switch (Type) {303 STRINGIFY_ENUM_CASE(ELF, SHT_NULL);304 STRINGIFY_ENUM_CASE(ELF, SHT_PROGBITS);305 STRINGIFY_ENUM_CASE(ELF, SHT_SYMTAB);306 STRINGIFY_ENUM_CASE(ELF, SHT_STRTAB);307 STRINGIFY_ENUM_CASE(ELF, SHT_RELA);308 STRINGIFY_ENUM_CASE(ELF, SHT_HASH);309 STRINGIFY_ENUM_CASE(ELF, SHT_DYNAMIC);310 STRINGIFY_ENUM_CASE(ELF, SHT_NOTE);311 STRINGIFY_ENUM_CASE(ELF, SHT_NOBITS);312 STRINGIFY_ENUM_CASE(ELF, SHT_REL);313 STRINGIFY_ENUM_CASE(ELF, SHT_SHLIB);314 STRINGIFY_ENUM_CASE(ELF, SHT_DYNSYM);315 STRINGIFY_ENUM_CASE(ELF, SHT_INIT_ARRAY);316 STRINGIFY_ENUM_CASE(ELF, SHT_FINI_ARRAY);317 STRINGIFY_ENUM_CASE(ELF, SHT_PREINIT_ARRAY);318 STRINGIFY_ENUM_CASE(ELF, SHT_GROUP);319 STRINGIFY_ENUM_CASE(ELF, SHT_SYMTAB_SHNDX);320 STRINGIFY_ENUM_CASE(ELF, SHT_RELR);321 STRINGIFY_ENUM_CASE(ELF, SHT_CREL);322 STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_REL);323 STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_RELA);324 STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_RELR);325 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_ODRTAB);326 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_LINKER_OPTIONS);327 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_CALL_GRAPH_PROFILE);328 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_ADDRSIG);329 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_DEPENDENT_LIBRARIES);330 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_SYMPART);331 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_PART_EHDR);332 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_PART_PHDR);333 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_BB_ADDR_MAP);334 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_OFFLOADING);335 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_LTO);336 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_JT_SIZES)337 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_CFI_JUMP_TABLE)338 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_CALL_GRAPH);339 STRINGIFY_ENUM_CASE(ELF, SHT_GNU_SFRAME);340 STRINGIFY_ENUM_CASE(ELF, SHT_GNU_ATTRIBUTES);341 STRINGIFY_ENUM_CASE(ELF, SHT_GNU_HASH);342 STRINGIFY_ENUM_CASE(ELF, SHT_GNU_verdef);343 STRINGIFY_ENUM_CASE(ELF, SHT_GNU_verneed);344 STRINGIFY_ENUM_CASE(ELF, SHT_GNU_versym);345 default:346 return "Unknown";347 }348}349 350template <class ELFT>351std::vector<typename ELFT::Rel>352ELFFile<ELFT>::decode_relrs(Elf_Relr_Range relrs) const {353 // This function decodes the contents of an SHT_RELR packed relocation354 // section.355 //356 // Proposal for adding SHT_RELR sections to generic-abi is here:357 // https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg358 //359 // The encoded sequence of Elf64_Relr entries in a SHT_RELR section looks360 // like [ AAAAAAAA BBBBBBB1 BBBBBBB1 ... AAAAAAAA BBBBBB1 ... ]361 //362 // i.e. start with an address, followed by any number of bitmaps. The address363 // entry encodes 1 relocation. The subsequent bitmap entries encode up to 63364 // relocations each, at subsequent offsets following the last address entry.365 //366 // The bitmap entries must have 1 in the least significant bit. The assumption367 // here is that an address cannot have 1 in lsb. Odd addresses are not368 // supported.369 //370 // Excluding the least significant bit in the bitmap, each non-zero bit in371 // the bitmap represents a relocation to be applied to a corresponding machine372 // word that follows the base address word. The second least significant bit373 // represents the machine word immediately following the initial address, and374 // each bit that follows represents the next word, in linear order. As such,375 // a single bitmap can encode up to 31 relocations in a 32-bit object, and376 // 63 relocations in a 64-bit object.377 //378 // This encoding has a couple of interesting properties:379 // 1. Looking at any entry, it is clear whether it's an address or a bitmap:380 // even means address, odd means bitmap.381 // 2. Just a simple list of addresses is a valid encoding.382 383 Elf_Rel Rel;384 Rel.r_info = 0;385 Rel.setType(getRelativeRelocationType(), false);386 std::vector<Elf_Rel> Relocs;387 388 // Word type: uint32_t for Elf32, and uint64_t for Elf64.389 using Addr = typename ELFT::uint;390 391 Addr Base = 0;392 for (Elf_Relr R : relrs) {393 typename ELFT::uint Entry = R;394 if ((Entry & 1) == 0) {395 // Even entry: encodes the offset for next relocation.396 Rel.r_offset = Entry;397 Relocs.push_back(Rel);398 // Set base offset for subsequent bitmap entries.399 Base = Entry + sizeof(Addr);400 } else {401 // Odd entry: encodes bitmap for relocations starting at base.402 for (Addr Offset = Base; (Entry >>= 1) != 0; Offset += sizeof(Addr))403 if ((Entry & 1) != 0) {404 Rel.r_offset = Offset;405 Relocs.push_back(Rel);406 }407 Base += (CHAR_BIT * sizeof(Entry) - 1) * sizeof(Addr);408 }409 }410 411 return Relocs;412}413 414template <class ELFT>415Expected<uint64_t>416ELFFile<ELFT>::getCrelHeader(ArrayRef<uint8_t> Content) const {417 DataExtractor Data(Content, isLE(), sizeof(typename ELFT::Addr));418 Error Err = Error::success();419 uint64_t Hdr = 0;420 Hdr = Data.getULEB128(&Hdr, &Err);421 if (Err)422 return Err;423 return Hdr;424}425 426template <class ELFT>427Expected<typename ELFFile<ELFT>::RelsOrRelas>428ELFFile<ELFT>::decodeCrel(ArrayRef<uint8_t> Content) const {429 std::vector<Elf_Rel> Rels;430 std::vector<Elf_Rela> Relas;431 size_t I = 0;432 bool HasAddend;433 Error Err = object::decodeCrel<ELFT::Is64Bits>(434 Content,435 [&](uint64_t Count, bool HasA) {436 HasAddend = HasA;437 if (HasAddend)438 Relas.resize(Count);439 else440 Rels.resize(Count);441 },442 [&](Elf_Crel Crel) {443 if (HasAddend) {444 Relas[I].r_offset = Crel.r_offset;445 Relas[I].setSymbolAndType(Crel.r_symidx, Crel.r_type, false);446 Relas[I++].r_addend = Crel.r_addend;447 } else {448 Rels[I].r_offset = Crel.r_offset;449 Rels[I++].setSymbolAndType(Crel.r_symidx, Crel.r_type, false);450 }451 });452 if (Err)453 return std::move(Err);454 return std::make_pair(std::move(Rels), std::move(Relas));455}456 457template <class ELFT>458Expected<typename ELFFile<ELFT>::RelsOrRelas>459ELFFile<ELFT>::crels(const Elf_Shdr &Sec) const {460 Expected<ArrayRef<uint8_t>> ContentsOrErr = getSectionContents(Sec);461 if (!ContentsOrErr)462 return ContentsOrErr.takeError();463 return decodeCrel(*ContentsOrErr);464}465 466template <class ELFT>467Expected<std::vector<typename ELFT::Rela>>468ELFFile<ELFT>::android_relas(const Elf_Shdr &Sec) const {469 // This function reads relocations in Android's packed relocation format,470 // which is based on SLEB128 and delta encoding.471 Expected<ArrayRef<uint8_t>> ContentsOrErr = getSectionContents(Sec);472 if (!ContentsOrErr)473 return ContentsOrErr.takeError();474 ArrayRef<uint8_t> Content = *ContentsOrErr;475 if (Content.size() < 4 || Content[0] != 'A' || Content[1] != 'P' ||476 Content[2] != 'S' || Content[3] != '2')477 return createError("invalid packed relocation header");478 DataExtractor Data(Content, isLE(), ELFT::Is64Bits ? 8 : 4);479 DataExtractor::Cursor Cur(/*Offset=*/4);480 481 uint64_t NumRelocs = Data.getSLEB128(Cur);482 uint64_t Offset = Data.getSLEB128(Cur);483 uint64_t Addend = 0;484 485 if (!Cur)486 return std::move(Cur.takeError());487 488 std::vector<Elf_Rela> Relocs;489 Relocs.reserve(NumRelocs);490 while (NumRelocs) {491 uint64_t NumRelocsInGroup = Data.getSLEB128(Cur);492 if (!Cur)493 return std::move(Cur.takeError());494 if (NumRelocsInGroup > NumRelocs)495 return createError("relocation group unexpectedly large");496 NumRelocs -= NumRelocsInGroup;497 498 uint64_t GroupFlags = Data.getSLEB128(Cur);499 bool GroupedByInfo = GroupFlags & ELF::RELOCATION_GROUPED_BY_INFO_FLAG;500 bool GroupedByOffsetDelta = GroupFlags & ELF::RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG;501 bool GroupedByAddend = GroupFlags & ELF::RELOCATION_GROUPED_BY_ADDEND_FLAG;502 bool GroupHasAddend = GroupFlags & ELF::RELOCATION_GROUP_HAS_ADDEND_FLAG;503 504 uint64_t GroupOffsetDelta;505 if (GroupedByOffsetDelta)506 GroupOffsetDelta = Data.getSLEB128(Cur);507 508 uint64_t GroupRInfo;509 if (GroupedByInfo)510 GroupRInfo = Data.getSLEB128(Cur);511 512 if (GroupedByAddend && GroupHasAddend)513 Addend += Data.getSLEB128(Cur);514 515 if (!GroupHasAddend)516 Addend = 0;517 518 for (uint64_t I = 0; Cur && I != NumRelocsInGroup; ++I) {519 Elf_Rela R;520 Offset += GroupedByOffsetDelta ? GroupOffsetDelta : Data.getSLEB128(Cur);521 R.r_offset = Offset;522 R.r_info = GroupedByInfo ? GroupRInfo : Data.getSLEB128(Cur);523 if (GroupHasAddend && !GroupedByAddend)524 Addend += Data.getSLEB128(Cur);525 R.r_addend = Addend;526 Relocs.push_back(R);527 }528 if (!Cur)529 return std::move(Cur.takeError());530 }531 532 return Relocs;533}534 535template <class ELFT>536std::string ELFFile<ELFT>::getDynamicTagAsString(unsigned Arch,537 uint64_t Type) const {538#define DYNAMIC_STRINGIFY_ENUM(tag, value) \539 case value: \540 return #tag;541 542#define DYNAMIC_TAG(n, v)543 switch (Arch) {544 case ELF::EM_AARCH64:545 switch (Type) {546#define AARCH64_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)547#include "llvm/BinaryFormat/DynamicTags.def"548#undef AARCH64_DYNAMIC_TAG549 }550 break;551 552 case ELF::EM_HEXAGON:553 switch (Type) {554#define HEXAGON_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)555#include "llvm/BinaryFormat/DynamicTags.def"556#undef HEXAGON_DYNAMIC_TAG557 }558 break;559 560 case ELF::EM_MIPS:561 switch (Type) {562#define MIPS_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)563#include "llvm/BinaryFormat/DynamicTags.def"564#undef MIPS_DYNAMIC_TAG565 }566 break;567 568 case ELF::EM_PPC:569 switch (Type) {570#define PPC_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)571#include "llvm/BinaryFormat/DynamicTags.def"572#undef PPC_DYNAMIC_TAG573 }574 break;575 576 case ELF::EM_PPC64:577 switch (Type) {578#define PPC64_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)579#include "llvm/BinaryFormat/DynamicTags.def"580#undef PPC64_DYNAMIC_TAG581 }582 break;583 584 case ELF::EM_RISCV:585 switch (Type) {586#define RISCV_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)587#include "llvm/BinaryFormat/DynamicTags.def"588#undef RISCV_DYNAMIC_TAG589 }590 break;591 }592#undef DYNAMIC_TAG593 switch (Type) {594// Now handle all dynamic tags except the architecture specific ones595#define AARCH64_DYNAMIC_TAG(name, value)596#define MIPS_DYNAMIC_TAG(name, value)597#define HEXAGON_DYNAMIC_TAG(name, value)598#define PPC_DYNAMIC_TAG(name, value)599#define PPC64_DYNAMIC_TAG(name, value)600#define RISCV_DYNAMIC_TAG(name, value)601// Also ignore marker tags such as DT_HIOS (maps to DT_VERNEEDNUM), etc.602#define DYNAMIC_TAG_MARKER(name, value)603#define DYNAMIC_TAG(name, value) case value: return #name;604#include "llvm/BinaryFormat/DynamicTags.def"605#undef DYNAMIC_TAG606#undef AARCH64_DYNAMIC_TAG607#undef MIPS_DYNAMIC_TAG608#undef HEXAGON_DYNAMIC_TAG609#undef PPC_DYNAMIC_TAG610#undef PPC64_DYNAMIC_TAG611#undef RISCV_DYNAMIC_TAG612#undef DYNAMIC_TAG_MARKER613#undef DYNAMIC_STRINGIFY_ENUM614 default:615 return "<unknown:>0x" + utohexstr(Type, true);616 }617}618 619template <class ELFT>620std::string ELFFile<ELFT>::getDynamicTagAsString(uint64_t Type) const {621 return getDynamicTagAsString(getHeader().e_machine, Type);622}623 624template <class ELFT>625Expected<typename ELFT::DynRange> ELFFile<ELFT>::dynamicEntries() const {626 ArrayRef<Elf_Dyn> Dyn;627 628 auto ProgramHeadersOrError = program_headers();629 if (!ProgramHeadersOrError)630 return ProgramHeadersOrError.takeError();631 632 for (const Elf_Phdr &Phdr : *ProgramHeadersOrError) {633 if (Phdr.p_type == ELF::PT_DYNAMIC) {634 const uint8_t *DynOffset = base() + Phdr.p_offset;635 if (DynOffset > end())636 return createError(637 "dynamic section offset past file size: corrupted ELF");638 Dyn = ArrayRef(reinterpret_cast<const Elf_Dyn *>(DynOffset),639 Phdr.p_filesz / sizeof(Elf_Dyn));640 break;641 }642 }643 644 // If we can't find the dynamic section in the program headers, we just fall645 // back on the sections.646 if (Dyn.empty()) {647 auto SectionsOrError = sections();648 if (!SectionsOrError)649 return SectionsOrError.takeError();650 651 for (const Elf_Shdr &Sec : *SectionsOrError) {652 if (Sec.sh_type == ELF::SHT_DYNAMIC) {653 Expected<ArrayRef<Elf_Dyn>> DynOrError =654 getSectionContentsAsArray<Elf_Dyn>(Sec);655 if (!DynOrError)656 return DynOrError.takeError();657 Dyn = *DynOrError;658 break;659 }660 }661 662 if (!Dyn.data())663 return ArrayRef<Elf_Dyn>();664 }665 666 if (Dyn.empty())667 return createError("invalid empty dynamic section");668 669 if (Dyn.back().d_tag != ELF::DT_NULL)670 return createError("dynamic sections must be DT_NULL terminated");671 672 return Dyn;673}674 675template <class ELFT>676Expected<const uint8_t *>677ELFFile<ELFT>::toMappedAddr(uint64_t VAddr, WarningHandler WarnHandler) const {678 auto ProgramHeadersOrError = program_headers();679 if (!ProgramHeadersOrError)680 return ProgramHeadersOrError.takeError();681 682 llvm::SmallVector<Elf_Phdr *, 4> LoadSegments;683 684 for (const Elf_Phdr &Phdr : *ProgramHeadersOrError)685 if (Phdr.p_type == ELF::PT_LOAD)686 LoadSegments.push_back(const_cast<Elf_Phdr *>(&Phdr));687 688 auto SortPred = [](const Elf_Phdr_Impl<ELFT> *A,689 const Elf_Phdr_Impl<ELFT> *B) {690 return A->p_vaddr < B->p_vaddr;691 };692 if (!llvm::is_sorted(LoadSegments, SortPred)) {693 if (Error E =694 WarnHandler("loadable segments are unsorted by virtual address"))695 return std::move(E);696 llvm::stable_sort(LoadSegments, SortPred);697 }698 699 const Elf_Phdr *const *I = llvm::upper_bound(700 LoadSegments, VAddr, [](uint64_t VAddr, const Elf_Phdr_Impl<ELFT> *Phdr) {701 return VAddr < Phdr->p_vaddr;702 });703 704 if (I == LoadSegments.begin())705 return createError("virtual address is not in any segment: 0x" +706 Twine::utohexstr(VAddr));707 --I;708 const Elf_Phdr &Phdr = **I;709 uint64_t Delta = VAddr - Phdr.p_vaddr;710 if (Delta >= Phdr.p_filesz)711 return createError("virtual address is not in any segment: 0x" +712 Twine::utohexstr(VAddr));713 714 uint64_t Offset = Phdr.p_offset + Delta;715 if (Offset >= getBufSize())716 return createError("can't map virtual address 0x" +717 Twine::utohexstr(VAddr) + " to the segment with index " +718 Twine(&Phdr - (*ProgramHeadersOrError).data() + 1) +719 ": the segment ends at 0x" +720 Twine::utohexstr(Phdr.p_offset + Phdr.p_filesz) +721 ", which is greater than the file size (0x" +722 Twine::utohexstr(getBufSize()) + ")");723 724 return base() + Offset;725}726 727// Helper to extract and decode the next ULEB128 value as unsigned int.728// Returns zero and sets ULEBSizeErr if the ULEB128 value exceeds the unsigned729// int limit.730// Also returns zero if ULEBSizeErr is already in an error state.731// ULEBSizeErr is an out variable if an error occurs.732template <typename IntTy, std::enable_if_t<std::is_unsigned_v<IntTy>, int> = 0>733static IntTy readULEB128As(DataExtractor &Data, DataExtractor::Cursor &Cur,734 Error &ULEBSizeErr) {735 // Bail out and do not extract data if ULEBSizeErr is already set.736 if (ULEBSizeErr)737 return 0;738 uint64_t Offset = Cur.tell();739 uint64_t Value = Data.getULEB128(Cur);740 if (Value > std::numeric_limits<IntTy>::max()) {741 ULEBSizeErr = createError("ULEB128 value at offset 0x" +742 Twine::utohexstr(Offset) + " exceeds UINT" +743 Twine(std::numeric_limits<IntTy>::digits) +744 "_MAX (0x" + Twine::utohexstr(Value) + ")");745 return 0;746 }747 return static_cast<IntTy>(Value);748}749 750template <typename ELFT>751static Expected<std::vector<BBAddrMap>>752decodeBBAddrMapImpl(const ELFFile<ELFT> &EF,753 const typename ELFFile<ELFT>::Elf_Shdr &Sec,754 const typename ELFFile<ELFT>::Elf_Shdr *RelaSec,755 std::vector<PGOAnalysisMap> *PGOAnalyses) {756 bool IsRelocatable = EF.getHeader().e_type == ELF::ET_REL;757 758 // This DenseMap maps the offset of each function (the location of the759 // reference to the function in the SHT_LLVM_BB_ADDR_MAP section) to the760 // addend (the location of the function in the text section).761 llvm::DenseMap<uint64_t, uint64_t> FunctionOffsetTranslations;762 if (IsRelocatable && RelaSec) {763 assert(RelaSec &&764 "Can't read a SHT_LLVM_BB_ADDR_MAP section in a relocatable "765 "object file without providing a relocation section.");766 if (RelaSec->sh_type == ELF::SHT_CREL) {767 Expected<typename ELFFile<ELFT>::RelsOrRelas> Relas = EF.crels(*RelaSec);768 if (!Relas)769 return createError("unable to read CREL relocations for section " +770 describe(EF, Sec) + ": " +771 toString(Relas.takeError()));772 for (typename ELFFile<ELFT>::Elf_Rela Rela : std::get<1>(*Relas)) {773 FunctionOffsetTranslations[Rela.r_offset] = Rela.r_addend;774 }775 } else {776 Expected<typename ELFFile<ELFT>::Elf_Rela_Range> Relas =777 EF.relas(*RelaSec);778 if (!Relas)779 return createError("unable to read relocations for section " +780 describe(EF, Sec) + ": " +781 toString(Relas.takeError()));782 for (typename ELFFile<ELFT>::Elf_Rela Rela : *Relas)783 FunctionOffsetTranslations[Rela.r_offset] = Rela.r_addend;784 }785 }786 auto GetAddressForRelocation =787 [&](unsigned RelocationOffsetInSection) -> Expected<unsigned> {788 auto FOTIterator =789 FunctionOffsetTranslations.find(RelocationOffsetInSection);790 if (FOTIterator == FunctionOffsetTranslations.end()) {791 return createError("failed to get relocation data for offset: " +792 Twine::utohexstr(RelocationOffsetInSection) +793 " in section " + describe(EF, Sec));794 }795 return FOTIterator->second;796 };797 Expected<ArrayRef<uint8_t>> ContentsOrErr = EF.getSectionContents(Sec);798 if (!ContentsOrErr)799 return ContentsOrErr.takeError();800 ArrayRef<uint8_t> Content = *ContentsOrErr;801 802 // Decompress the section if needed.803 std::unique_ptr<uint8_t[]> DecompressedContent;804 if (Sec.sh_flags & llvm::ELF::SHF_COMPRESSED) {805 Expected<StringRef> SectionNameOrErr = EF.getSectionName(Sec);806 if (!SectionNameOrErr)807 return SectionNameOrErr.takeError();808 auto DecompressorOrErr =809 Decompressor::create(*SectionNameOrErr, toStringRef(*ContentsOrErr),810 EF.isLE(), ELFT::Is64Bits);811 if (!DecompressorOrErr)812 return DecompressorOrErr.takeError();813 size_t DecompressedSize = DecompressorOrErr->getDecompressedSize();814 DecompressedContent = std::make_unique<uint8_t[]>(DecompressedSize);815 MutableArrayRef<uint8_t> DecompressedContentRef(DecompressedContent.get(),816 DecompressedSize);817 if (Error Err = DecompressorOrErr->decompress(DecompressedContentRef))818 return std::move(Err);819 Content = DecompressedContentRef;820 }821 822 DataExtractor Data(Content, EF.isLE(), ELFT::Is64Bits ? 8 : 4);823 std::vector<BBAddrMap> FunctionEntries;824 825 DataExtractor::Cursor Cur(0);826 Error ULEBSizeErr = Error::success();827 Error MetadataDecodeErr = Error::success();828 829 // Helper lampda to extract the (possiblly relocatable) address stored at Cur.830 auto ExtractAddress = [&]() -> Expected<typename ELFFile<ELFT>::uintX_t> {831 uint64_t RelocationOffsetInSection = Cur.tell();832 auto Address =833 static_cast<typename ELFFile<ELFT>::uintX_t>(Data.getAddress(Cur));834 if (!Cur)835 return Cur.takeError();836 if (!IsRelocatable)837 return Address;838 assert(Address == 0);839 Expected<unsigned> AddressOrErr =840 GetAddressForRelocation(RelocationOffsetInSection);841 if (!AddressOrErr)842 return AddressOrErr.takeError();843 return *AddressOrErr;844 };845 846 uint8_t Version = 0;847 uint16_t Feature = 0;848 BBAddrMap::Features FeatEnable{};849 while (!ULEBSizeErr && !MetadataDecodeErr && Cur &&850 Cur.tell() < Content.size()) {851 Version = Data.getU8(Cur);852 if (!Cur)853 break;854 if (Version < 2 || Version > 5)855 return createError("unsupported SHT_LLVM_BB_ADDR_MAP version: " +856 Twine(static_cast<int>(Version)));857 Feature = Version < 5 ? Data.getU8(Cur) : Data.getU16(Cur);858 if (!Cur)859 break;860 auto FeatEnableOrErr = BBAddrMap::Features::decode(Feature);861 if (!FeatEnableOrErr)862 return FeatEnableOrErr.takeError();863 FeatEnable = *FeatEnableOrErr;864 if (FeatEnable.CallsiteEndOffsets && Version < 3)865 return createError("version should be >= 3 for SHT_LLVM_BB_ADDR_MAP when "866 "callsite offsets feature is enabled: version = " +867 Twine(static_cast<int>(Version)) +868 " feature = " + Twine(static_cast<int>(Feature)));869 if (FeatEnable.BBHash && Version < 4)870 return createError("version should be >= 4 for SHT_LLVM_BB_ADDR_MAP when "871 "basic block hash feature is enabled: version = " +872 Twine(static_cast<int>(Version)) +873 " feature = " + Twine(static_cast<int>(Feature)));874 if (FeatEnable.PostLinkCfg && Version < 5)875 return createError("version should be >= 5 for SHT_LLVM_BB_ADDR_MAP when "876 "post link cfg feature is enabled: version = " +877 Twine(static_cast<int>(Version)) +878 " feature = " + Twine(static_cast<int>(Feature)));879 uint32_t NumBlocksInBBRange = 0;880 uint32_t NumBBRanges = 1;881 typename ELFFile<ELFT>::uintX_t RangeBaseAddress = 0;882 if (FeatEnable.MultiBBRange) {883 NumBBRanges = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);884 if (!Cur || ULEBSizeErr)885 break;886 if (!NumBBRanges)887 return createError("invalid zero number of BB ranges at offset " +888 Twine::utohexstr(Cur.tell()) + " in " +889 describe(EF, Sec));890 } else {891 auto AddressOrErr = ExtractAddress();892 if (!AddressOrErr)893 return AddressOrErr.takeError();894 RangeBaseAddress = *AddressOrErr;895 NumBlocksInBBRange = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);896 }897 std::vector<BBAddrMap::BBRangeEntry> BBRangeEntries;898 uint32_t TotalNumBlocks = 0;899 for (uint32_t BBRangeIndex = 0; BBRangeIndex < NumBBRanges;900 ++BBRangeIndex) {901 uint32_t PrevBBEndOffset = 0;902 if (FeatEnable.MultiBBRange) {903 auto AddressOrErr = ExtractAddress();904 if (!AddressOrErr)905 return AddressOrErr.takeError();906 RangeBaseAddress = *AddressOrErr;907 NumBlocksInBBRange = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);908 }909 std::vector<BBAddrMap::BBEntry> BBEntries;910 if (!FeatEnable.OmitBBEntries) {911 for (uint32_t BlockIndex = 0; !MetadataDecodeErr && !ULEBSizeErr &&912 Cur && (BlockIndex < NumBlocksInBBRange);913 ++BlockIndex) {914 uint32_t ID = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);915 uint32_t Offset = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);916 // Read the callsite offsets.917 uint32_t LastCallsiteEndOffset = 0;918 SmallVector<uint32_t, 1> CallsiteEndOffsets;919 if (FeatEnable.CallsiteEndOffsets) {920 uint32_t NumCallsites =921 readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);922 CallsiteEndOffsets.reserve(NumCallsites);923 for (uint32_t CallsiteIndex = 0;924 !ULEBSizeErr && Cur && (CallsiteIndex < NumCallsites);925 ++CallsiteIndex) {926 LastCallsiteEndOffset +=927 readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);928 CallsiteEndOffsets.push_back(LastCallsiteEndOffset);929 }930 }931 uint32_t Size = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr) +932 LastCallsiteEndOffset;933 uint32_t MD = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);934 uint64_t Hash = FeatEnable.BBHash ? Data.getU64(Cur) : 0;935 Expected<BBAddrMap::BBEntry::Metadata> MetadataOrErr =936 BBAddrMap::BBEntry::Metadata::decode(MD);937 if (!MetadataOrErr) {938 MetadataDecodeErr = MetadataOrErr.takeError();939 break;940 }941 BBEntries.push_back({ID, Offset + PrevBBEndOffset, Size,942 *MetadataOrErr, CallsiteEndOffsets, Hash});943 PrevBBEndOffset += Offset + Size;944 }945 TotalNumBlocks += BBEntries.size();946 }947 BBRangeEntries.push_back({RangeBaseAddress, std::move(BBEntries)});948 }949 FunctionEntries.push_back({std::move(BBRangeEntries)});950 951 if (PGOAnalyses || FeatEnable.hasPGOAnalysis()) {952 // Function entry count953 uint64_t FuncEntryCount =954 FeatEnable.FuncEntryCount955 ? readULEB128As<uint64_t>(Data, Cur, ULEBSizeErr)956 : 0;957 958 std::vector<PGOAnalysisMap::PGOBBEntry> PGOBBEntries;959 for (uint32_t BlockIndex = 0;960 FeatEnable.hasPGOAnalysisBBData() && !MetadataDecodeErr &&961 !ULEBSizeErr && Cur && (BlockIndex < TotalNumBlocks);962 ++BlockIndex) {963 // Block frequency964 uint64_t BBF = FeatEnable.BBFreq965 ? readULEB128As<uint64_t>(Data, Cur, ULEBSizeErr)966 : 0;967 uint32_t PostLinkBBFreq =968 FeatEnable.PostLinkCfg969 ? readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr)970 : 0;971 972 // Branch probability973 llvm::SmallVector<PGOAnalysisMap::PGOBBEntry::SuccessorEntry, 2>974 Successors;975 if (FeatEnable.BrProb) {976 auto SuccCount = readULEB128As<uint64_t>(Data, Cur, ULEBSizeErr);977 for (uint64_t I = 0; I < SuccCount; ++I) {978 uint32_t BBID = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);979 uint32_t BrProb = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);980 uint32_t PostLinkFreq =981 FeatEnable.PostLinkCfg982 ? readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr)983 : 0;984 985 if (PGOAnalyses)986 Successors.push_back(987 {BBID, BranchProbability::getRaw(BrProb), PostLinkFreq});988 }989 }990 991 if (PGOAnalyses)992 PGOBBEntries.push_back(993 {BlockFrequency(BBF), PostLinkBBFreq, std::move(Successors)});994 }995 996 if (PGOAnalyses)997 PGOAnalyses->push_back(998 {FuncEntryCount, std::move(PGOBBEntries), FeatEnable});999 }1000 }1001 // Either Cur is in the error state, or we have an error in ULEBSizeErr or1002 // MetadataDecodeErr (but not both), but we join all errors here to be safe.1003 if (!Cur || ULEBSizeErr || MetadataDecodeErr)1004 return joinErrors(joinErrors(Cur.takeError(), std::move(ULEBSizeErr)),1005 std::move(MetadataDecodeErr));1006 return FunctionEntries;1007}1008 1009template <class ELFT>1010Expected<std::vector<BBAddrMap>>1011ELFFile<ELFT>::decodeBBAddrMap(const Elf_Shdr &Sec, const Elf_Shdr *RelaSec,1012 std::vector<PGOAnalysisMap> *PGOAnalyses) const {1013 size_t OriginalPGOSize = PGOAnalyses ? PGOAnalyses->size() : 0;1014 auto AddrMapsOrErr = decodeBBAddrMapImpl(*this, Sec, RelaSec, PGOAnalyses);1015 // remove new analyses when an error occurs1016 if (!AddrMapsOrErr && PGOAnalyses)1017 PGOAnalyses->resize(OriginalPGOSize);1018 return std::move(AddrMapsOrErr);1019}1020 1021template <class ELFT>1022Expected<1023 MapVector<const typename ELFT::Shdr *, const typename ELFT::Shdr *>>1024ELFFile<ELFT>::getSectionAndRelocations(1025 std::function<Expected<bool>(const Elf_Shdr &)> IsMatch) const {1026 MapVector<const Elf_Shdr *, const Elf_Shdr *> SecToRelocMap;1027 Error Errors = Error::success();1028 for (const Elf_Shdr &Sec : cantFail(this->sections())) {1029 Expected<bool> DoesSectionMatch = IsMatch(Sec);1030 if (!DoesSectionMatch) {1031 Errors = joinErrors(std::move(Errors), DoesSectionMatch.takeError());1032 continue;1033 }1034 if (*DoesSectionMatch) {1035 if (SecToRelocMap.try_emplace(&Sec).second)1036 continue;1037 }1038 1039 if (Sec.sh_type != ELF::SHT_RELA && Sec.sh_type != ELF::SHT_REL &&1040 Sec.sh_type != ELF::SHT_CREL)1041 continue;1042 1043 Expected<const Elf_Shdr *> RelSecOrErr = this->getSection(Sec.sh_info);1044 if (!RelSecOrErr) {1045 Errors = joinErrors(std::move(Errors),1046 createError(describe(*this, Sec) +1047 ": failed to get a relocated section: " +1048 toString(RelSecOrErr.takeError())));1049 continue;1050 }1051 const Elf_Shdr *ContentsSec = *RelSecOrErr;1052 Expected<bool> DoesRelTargetMatch = IsMatch(*ContentsSec);1053 if (!DoesRelTargetMatch) {1054 Errors = joinErrors(std::move(Errors), DoesRelTargetMatch.takeError());1055 continue;1056 }1057 if (*DoesRelTargetMatch)1058 SecToRelocMap[ContentsSec] = &Sec;1059 }1060 if(Errors)1061 return std::move(Errors);1062 return SecToRelocMap;1063}1064 1065template class LLVM_EXPORT_TEMPLATE llvm::object::ELFFile<ELF32LE>;1066template class LLVM_EXPORT_TEMPLATE llvm::object::ELFFile<ELF32BE>;1067template class LLVM_EXPORT_TEMPLATE llvm::object::ELFFile<ELF64LE>;1068template class LLVM_EXPORT_TEMPLATE llvm::object::ELFFile<ELF64BE>;1069