Path: blob/main/contrib/llvm-project/llvm/lib/Object/ELF.cpp
35232 views
//===- ELF.cpp - ELF object file implementation ---------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "llvm/Object/ELF.h"9#include "llvm/ADT/StringExtras.h"10#include "llvm/BinaryFormat/ELF.h"11#include "llvm/Support/DataExtractor.h"1213using namespace llvm;14using namespace object;1516#define STRINGIFY_ENUM_CASE(ns, name) \17case ns::name: \18return #name;1920#define ELF_RELOC(name, value) STRINGIFY_ENUM_CASE(ELF, name)2122StringRef llvm::object::getELFRelocationTypeName(uint32_t Machine,23uint32_t Type) {24switch (Machine) {25case ELF::EM_68K:26switch (Type) {27#include "llvm/BinaryFormat/ELFRelocs/M68k.def"28default:29break;30}31break;32case ELF::EM_X86_64:33switch (Type) {34#include "llvm/BinaryFormat/ELFRelocs/x86_64.def"35default:36break;37}38break;39case ELF::EM_386:40case ELF::EM_IAMCU:41switch (Type) {42#include "llvm/BinaryFormat/ELFRelocs/i386.def"43default:44break;45}46break;47case ELF::EM_MIPS:48switch (Type) {49#include "llvm/BinaryFormat/ELFRelocs/Mips.def"50default:51break;52}53break;54case ELF::EM_AARCH64:55switch (Type) {56#include "llvm/BinaryFormat/ELFRelocs/AArch64.def"57default:58break;59}60break;61case ELF::EM_ARM:62switch (Type) {63#include "llvm/BinaryFormat/ELFRelocs/ARM.def"64default:65break;66}67break;68case ELF::EM_ARC_COMPACT:69case ELF::EM_ARC_COMPACT2:70switch (Type) {71#include "llvm/BinaryFormat/ELFRelocs/ARC.def"72default:73break;74}75break;76case ELF::EM_AVR:77switch (Type) {78#include "llvm/BinaryFormat/ELFRelocs/AVR.def"79default:80break;81}82break;83case ELF::EM_HEXAGON:84switch (Type) {85#include "llvm/BinaryFormat/ELFRelocs/Hexagon.def"86default:87break;88}89break;90case ELF::EM_LANAI:91switch (Type) {92#include "llvm/BinaryFormat/ELFRelocs/Lanai.def"93default:94break;95}96break;97case ELF::EM_PPC:98switch (Type) {99#include "llvm/BinaryFormat/ELFRelocs/PowerPC.def"100default:101break;102}103break;104case ELF::EM_PPC64:105switch (Type) {106#include "llvm/BinaryFormat/ELFRelocs/PowerPC64.def"107default:108break;109}110break;111case ELF::EM_RISCV:112switch (Type) {113#include "llvm/BinaryFormat/ELFRelocs/RISCV.def"114default:115break;116}117break;118case ELF::EM_S390:119switch (Type) {120#include "llvm/BinaryFormat/ELFRelocs/SystemZ.def"121default:122break;123}124break;125case ELF::EM_SPARC:126case ELF::EM_SPARC32PLUS:127case ELF::EM_SPARCV9:128switch (Type) {129#include "llvm/BinaryFormat/ELFRelocs/Sparc.def"130default:131break;132}133break;134case ELF::EM_AMDGPU:135switch (Type) {136#include "llvm/BinaryFormat/ELFRelocs/AMDGPU.def"137default:138break;139}140break;141case ELF::EM_BPF:142switch (Type) {143#include "llvm/BinaryFormat/ELFRelocs/BPF.def"144default:145break;146}147break;148case ELF::EM_MSP430:149switch (Type) {150#include "llvm/BinaryFormat/ELFRelocs/MSP430.def"151default:152break;153}154break;155case ELF::EM_VE:156switch (Type) {157#include "llvm/BinaryFormat/ELFRelocs/VE.def"158default:159break;160}161break;162case ELF::EM_CSKY:163switch (Type) {164#include "llvm/BinaryFormat/ELFRelocs/CSKY.def"165default:166break;167}168break;169case ELF::EM_LOONGARCH:170switch (Type) {171#include "llvm/BinaryFormat/ELFRelocs/LoongArch.def"172default:173break;174}175break;176case ELF::EM_XTENSA:177switch (Type) {178#include "llvm/BinaryFormat/ELFRelocs/Xtensa.def"179default:180break;181}182break;183default:184break;185}186return "Unknown";187}188189#undef ELF_RELOC190191uint32_t llvm::object::getELFRelativeRelocationType(uint32_t Machine) {192switch (Machine) {193case ELF::EM_X86_64:194return ELF::R_X86_64_RELATIVE;195case ELF::EM_386:196case ELF::EM_IAMCU:197return ELF::R_386_RELATIVE;198case ELF::EM_MIPS:199break;200case ELF::EM_AARCH64:201return ELF::R_AARCH64_RELATIVE;202case ELF::EM_ARM:203return ELF::R_ARM_RELATIVE;204case ELF::EM_ARC_COMPACT:205case ELF::EM_ARC_COMPACT2:206return ELF::R_ARC_RELATIVE;207case ELF::EM_AVR:208break;209case ELF::EM_HEXAGON:210return ELF::R_HEX_RELATIVE;211case ELF::EM_LANAI:212break;213case ELF::EM_PPC:214break;215case ELF::EM_PPC64:216return ELF::R_PPC64_RELATIVE;217case ELF::EM_RISCV:218return ELF::R_RISCV_RELATIVE;219case ELF::EM_S390:220return ELF::R_390_RELATIVE;221case ELF::EM_SPARC:222case ELF::EM_SPARC32PLUS:223case ELF::EM_SPARCV9:224return ELF::R_SPARC_RELATIVE;225case ELF::EM_CSKY:226return ELF::R_CKCORE_RELATIVE;227case ELF::EM_VE:228return ELF::R_VE_RELATIVE;229case ELF::EM_AMDGPU:230break;231case ELF::EM_BPF:232break;233case ELF::EM_LOONGARCH:234return ELF::R_LARCH_RELATIVE;235default:236break;237}238return 0;239}240241StringRef llvm::object::getELFSectionTypeName(uint32_t Machine, unsigned Type) {242switch (Machine) {243case ELF::EM_ARM:244switch (Type) {245STRINGIFY_ENUM_CASE(ELF, SHT_ARM_EXIDX);246STRINGIFY_ENUM_CASE(ELF, SHT_ARM_PREEMPTMAP);247STRINGIFY_ENUM_CASE(ELF, SHT_ARM_ATTRIBUTES);248STRINGIFY_ENUM_CASE(ELF, SHT_ARM_DEBUGOVERLAY);249STRINGIFY_ENUM_CASE(ELF, SHT_ARM_OVERLAYSECTION);250}251break;252case ELF::EM_HEXAGON:253switch (Type) {254STRINGIFY_ENUM_CASE(ELF, SHT_HEX_ORDERED);255STRINGIFY_ENUM_CASE(ELF, SHT_HEXAGON_ATTRIBUTES);256}257break;258case ELF::EM_X86_64:259switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_X86_64_UNWIND); }260break;261case ELF::EM_MIPS:262case ELF::EM_MIPS_RS3_LE:263switch (Type) {264STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_REGINFO);265STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_OPTIONS);266STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_DWARF);267STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_ABIFLAGS);268}269break;270case ELF::EM_MSP430:271switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_MSP430_ATTRIBUTES); }272break;273case ELF::EM_RISCV:274switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_RISCV_ATTRIBUTES); }275break;276case ELF::EM_AARCH64:277switch (Type) {278STRINGIFY_ENUM_CASE(ELF, SHT_AARCH64_AUTH_RELR);279STRINGIFY_ENUM_CASE(ELF, SHT_AARCH64_MEMTAG_GLOBALS_DYNAMIC);280STRINGIFY_ENUM_CASE(ELF, SHT_AARCH64_MEMTAG_GLOBALS_STATIC);281}282default:283break;284}285286switch (Type) {287STRINGIFY_ENUM_CASE(ELF, SHT_NULL);288STRINGIFY_ENUM_CASE(ELF, SHT_PROGBITS);289STRINGIFY_ENUM_CASE(ELF, SHT_SYMTAB);290STRINGIFY_ENUM_CASE(ELF, SHT_STRTAB);291STRINGIFY_ENUM_CASE(ELF, SHT_RELA);292STRINGIFY_ENUM_CASE(ELF, SHT_HASH);293STRINGIFY_ENUM_CASE(ELF, SHT_DYNAMIC);294STRINGIFY_ENUM_CASE(ELF, SHT_NOTE);295STRINGIFY_ENUM_CASE(ELF, SHT_NOBITS);296STRINGIFY_ENUM_CASE(ELF, SHT_REL);297STRINGIFY_ENUM_CASE(ELF, SHT_SHLIB);298STRINGIFY_ENUM_CASE(ELF, SHT_DYNSYM);299STRINGIFY_ENUM_CASE(ELF, SHT_INIT_ARRAY);300STRINGIFY_ENUM_CASE(ELF, SHT_FINI_ARRAY);301STRINGIFY_ENUM_CASE(ELF, SHT_PREINIT_ARRAY);302STRINGIFY_ENUM_CASE(ELF, SHT_GROUP);303STRINGIFY_ENUM_CASE(ELF, SHT_SYMTAB_SHNDX);304STRINGIFY_ENUM_CASE(ELF, SHT_RELR);305STRINGIFY_ENUM_CASE(ELF, SHT_CREL);306STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_REL);307STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_RELA);308STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_RELR);309STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_ODRTAB);310STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_LINKER_OPTIONS);311STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_CALL_GRAPH_PROFILE);312STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_ADDRSIG);313STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_DEPENDENT_LIBRARIES);314STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_SYMPART);315STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_PART_EHDR);316STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_PART_PHDR);317STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_BB_ADDR_MAP_V0);318STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_BB_ADDR_MAP);319STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_OFFLOADING);320STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_LTO);321STRINGIFY_ENUM_CASE(ELF, SHT_GNU_ATTRIBUTES);322STRINGIFY_ENUM_CASE(ELF, SHT_GNU_HASH);323STRINGIFY_ENUM_CASE(ELF, SHT_GNU_verdef);324STRINGIFY_ENUM_CASE(ELF, SHT_GNU_verneed);325STRINGIFY_ENUM_CASE(ELF, SHT_GNU_versym);326default:327return "Unknown";328}329}330331template <class ELFT>332std::vector<typename ELFT::Rel>333ELFFile<ELFT>::decode_relrs(Elf_Relr_Range relrs) const {334// This function decodes the contents of an SHT_RELR packed relocation335// section.336//337// Proposal for adding SHT_RELR sections to generic-abi is here:338// https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg339//340// The encoded sequence of Elf64_Relr entries in a SHT_RELR section looks341// like [ AAAAAAAA BBBBBBB1 BBBBBBB1 ... AAAAAAAA BBBBBB1 ... ]342//343// i.e. start with an address, followed by any number of bitmaps. The address344// entry encodes 1 relocation. The subsequent bitmap entries encode up to 63345// relocations each, at subsequent offsets following the last address entry.346//347// The bitmap entries must have 1 in the least significant bit. The assumption348// here is that an address cannot have 1 in lsb. Odd addresses are not349// supported.350//351// Excluding the least significant bit in the bitmap, each non-zero bit in352// the bitmap represents a relocation to be applied to a corresponding machine353// word that follows the base address word. The second least significant bit354// represents the machine word immediately following the initial address, and355// each bit that follows represents the next word, in linear order. As such,356// a single bitmap can encode up to 31 relocations in a 32-bit object, and357// 63 relocations in a 64-bit object.358//359// This encoding has a couple of interesting properties:360// 1. Looking at any entry, it is clear whether it's an address or a bitmap:361// even means address, odd means bitmap.362// 2. Just a simple list of addresses is a valid encoding.363364Elf_Rel Rel;365Rel.r_info = 0;366Rel.setType(getRelativeRelocationType(), false);367std::vector<Elf_Rel> Relocs;368369// Word type: uint32_t for Elf32, and uint64_t for Elf64.370using Addr = typename ELFT::uint;371372Addr Base = 0;373for (Elf_Relr R : relrs) {374typename ELFT::uint Entry = R;375if ((Entry & 1) == 0) {376// Even entry: encodes the offset for next relocation.377Rel.r_offset = Entry;378Relocs.push_back(Rel);379// Set base offset for subsequent bitmap entries.380Base = Entry + sizeof(Addr);381} else {382// Odd entry: encodes bitmap for relocations starting at base.383for (Addr Offset = Base; (Entry >>= 1) != 0; Offset += sizeof(Addr))384if ((Entry & 1) != 0) {385Rel.r_offset = Offset;386Relocs.push_back(Rel);387}388Base += (CHAR_BIT * sizeof(Entry) - 1) * sizeof(Addr);389}390}391392return Relocs;393}394395template <class ELFT>396Expected<uint64_t>397ELFFile<ELFT>::getCrelHeader(ArrayRef<uint8_t> Content) const {398DataExtractor Data(Content, isLE(), sizeof(typename ELFT::Addr));399Error Err = Error::success();400uint64_t Hdr = 0;401Hdr = Data.getULEB128(&Hdr, &Err);402if (Err)403return Err;404return Hdr;405}406407template <class ELFT>408Expected<typename ELFFile<ELFT>::RelsOrRelas>409ELFFile<ELFT>::decodeCrel(ArrayRef<uint8_t> Content) const {410std::vector<Elf_Rel> Rels;411std::vector<Elf_Rela> Relas;412size_t I = 0;413bool HasAddend;414Error Err = object::decodeCrel<ELFT::Is64Bits>(415Content,416[&](uint64_t Count, bool HasA) {417HasAddend = HasA;418if (HasAddend)419Relas.resize(Count);420else421Rels.resize(Count);422},423[&](Elf_Crel Crel) {424if (HasAddend) {425Relas[I].r_offset = Crel.r_offset;426Relas[I].setSymbolAndType(Crel.r_symidx, Crel.r_type, false);427Relas[I++].r_addend = Crel.r_addend;428} else {429Rels[I].r_offset = Crel.r_offset;430Rels[I++].setSymbolAndType(Crel.r_symidx, Crel.r_type, false);431}432});433if (Err)434return std::move(Err);435return std::make_pair(std::move(Rels), std::move(Relas));436}437438template <class ELFT>439Expected<typename ELFFile<ELFT>::RelsOrRelas>440ELFFile<ELFT>::crels(const Elf_Shdr &Sec) const {441Expected<ArrayRef<uint8_t>> ContentsOrErr = getSectionContents(Sec);442if (!ContentsOrErr)443return ContentsOrErr.takeError();444return decodeCrel(*ContentsOrErr);445}446447template <class ELFT>448Expected<std::vector<typename ELFT::Rela>>449ELFFile<ELFT>::android_relas(const Elf_Shdr &Sec) const {450// This function reads relocations in Android's packed relocation format,451// which is based on SLEB128 and delta encoding.452Expected<ArrayRef<uint8_t>> ContentsOrErr = getSectionContents(Sec);453if (!ContentsOrErr)454return ContentsOrErr.takeError();455ArrayRef<uint8_t> Content = *ContentsOrErr;456if (Content.size() < 4 || Content[0] != 'A' || Content[1] != 'P' ||457Content[2] != 'S' || Content[3] != '2')458return createError("invalid packed relocation header");459DataExtractor Data(Content, isLE(), ELFT::Is64Bits ? 8 : 4);460DataExtractor::Cursor Cur(/*Offset=*/4);461462uint64_t NumRelocs = Data.getSLEB128(Cur);463uint64_t Offset = Data.getSLEB128(Cur);464uint64_t Addend = 0;465466if (!Cur)467return std::move(Cur.takeError());468469std::vector<Elf_Rela> Relocs;470Relocs.reserve(NumRelocs);471while (NumRelocs) {472uint64_t NumRelocsInGroup = Data.getSLEB128(Cur);473if (!Cur)474return std::move(Cur.takeError());475if (NumRelocsInGroup > NumRelocs)476return createError("relocation group unexpectedly large");477NumRelocs -= NumRelocsInGroup;478479uint64_t GroupFlags = Data.getSLEB128(Cur);480bool GroupedByInfo = GroupFlags & ELF::RELOCATION_GROUPED_BY_INFO_FLAG;481bool GroupedByOffsetDelta = GroupFlags & ELF::RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG;482bool GroupedByAddend = GroupFlags & ELF::RELOCATION_GROUPED_BY_ADDEND_FLAG;483bool GroupHasAddend = GroupFlags & ELF::RELOCATION_GROUP_HAS_ADDEND_FLAG;484485uint64_t GroupOffsetDelta;486if (GroupedByOffsetDelta)487GroupOffsetDelta = Data.getSLEB128(Cur);488489uint64_t GroupRInfo;490if (GroupedByInfo)491GroupRInfo = Data.getSLEB128(Cur);492493if (GroupedByAddend && GroupHasAddend)494Addend += Data.getSLEB128(Cur);495496if (!GroupHasAddend)497Addend = 0;498499for (uint64_t I = 0; Cur && I != NumRelocsInGroup; ++I) {500Elf_Rela R;501Offset += GroupedByOffsetDelta ? GroupOffsetDelta : Data.getSLEB128(Cur);502R.r_offset = Offset;503R.r_info = GroupedByInfo ? GroupRInfo : Data.getSLEB128(Cur);504if (GroupHasAddend && !GroupedByAddend)505Addend += Data.getSLEB128(Cur);506R.r_addend = Addend;507Relocs.push_back(R);508}509if (!Cur)510return std::move(Cur.takeError());511}512513return Relocs;514}515516template <class ELFT>517std::string ELFFile<ELFT>::getDynamicTagAsString(unsigned Arch,518uint64_t Type) const {519#define DYNAMIC_STRINGIFY_ENUM(tag, value) \520case value: \521return #tag;522523#define DYNAMIC_TAG(n, v)524switch (Arch) {525case ELF::EM_AARCH64:526switch (Type) {527#define AARCH64_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)528#include "llvm/BinaryFormat/DynamicTags.def"529#undef AARCH64_DYNAMIC_TAG530}531break;532533case ELF::EM_HEXAGON:534switch (Type) {535#define HEXAGON_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)536#include "llvm/BinaryFormat/DynamicTags.def"537#undef HEXAGON_DYNAMIC_TAG538}539break;540541case ELF::EM_MIPS:542switch (Type) {543#define MIPS_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)544#include "llvm/BinaryFormat/DynamicTags.def"545#undef MIPS_DYNAMIC_TAG546}547break;548549case ELF::EM_PPC:550switch (Type) {551#define PPC_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)552#include "llvm/BinaryFormat/DynamicTags.def"553#undef PPC_DYNAMIC_TAG554}555break;556557case ELF::EM_PPC64:558switch (Type) {559#define PPC64_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)560#include "llvm/BinaryFormat/DynamicTags.def"561#undef PPC64_DYNAMIC_TAG562}563break;564565case ELF::EM_RISCV:566switch (Type) {567#define RISCV_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)568#include "llvm/BinaryFormat/DynamicTags.def"569#undef RISCV_DYNAMIC_TAG570}571break;572}573#undef DYNAMIC_TAG574switch (Type) {575// Now handle all dynamic tags except the architecture specific ones576#define AARCH64_DYNAMIC_TAG(name, value)577#define MIPS_DYNAMIC_TAG(name, value)578#define HEXAGON_DYNAMIC_TAG(name, value)579#define PPC_DYNAMIC_TAG(name, value)580#define PPC64_DYNAMIC_TAG(name, value)581#define RISCV_DYNAMIC_TAG(name, value)582// Also ignore marker tags such as DT_HIOS (maps to DT_VERNEEDNUM), etc.583#define DYNAMIC_TAG_MARKER(name, value)584#define DYNAMIC_TAG(name, value) case value: return #name;585#include "llvm/BinaryFormat/DynamicTags.def"586#undef DYNAMIC_TAG587#undef AARCH64_DYNAMIC_TAG588#undef MIPS_DYNAMIC_TAG589#undef HEXAGON_DYNAMIC_TAG590#undef PPC_DYNAMIC_TAG591#undef PPC64_DYNAMIC_TAG592#undef RISCV_DYNAMIC_TAG593#undef DYNAMIC_TAG_MARKER594#undef DYNAMIC_STRINGIFY_ENUM595default:596return "<unknown:>0x" + utohexstr(Type, true);597}598}599600template <class ELFT>601std::string ELFFile<ELFT>::getDynamicTagAsString(uint64_t Type) const {602return getDynamicTagAsString(getHeader().e_machine, Type);603}604605template <class ELFT>606Expected<typename ELFT::DynRange> ELFFile<ELFT>::dynamicEntries() const {607ArrayRef<Elf_Dyn> Dyn;608609auto ProgramHeadersOrError = program_headers();610if (!ProgramHeadersOrError)611return ProgramHeadersOrError.takeError();612613for (const Elf_Phdr &Phdr : *ProgramHeadersOrError) {614if (Phdr.p_type == ELF::PT_DYNAMIC) {615const uint8_t *DynOffset = base() + Phdr.p_offset;616if (DynOffset > end())617return createError(618"dynamic section offset past file size: corrupted ELF");619Dyn = ArrayRef(reinterpret_cast<const Elf_Dyn *>(DynOffset),620Phdr.p_filesz / sizeof(Elf_Dyn));621break;622}623}624625// If we can't find the dynamic section in the program headers, we just fall626// back on the sections.627if (Dyn.empty()) {628auto SectionsOrError = sections();629if (!SectionsOrError)630return SectionsOrError.takeError();631632for (const Elf_Shdr &Sec : *SectionsOrError) {633if (Sec.sh_type == ELF::SHT_DYNAMIC) {634Expected<ArrayRef<Elf_Dyn>> DynOrError =635getSectionContentsAsArray<Elf_Dyn>(Sec);636if (!DynOrError)637return DynOrError.takeError();638Dyn = *DynOrError;639break;640}641}642643if (!Dyn.data())644return ArrayRef<Elf_Dyn>();645}646647if (Dyn.empty())648return createError("invalid empty dynamic section");649650if (Dyn.back().d_tag != ELF::DT_NULL)651return createError("dynamic sections must be DT_NULL terminated");652653return Dyn;654}655656template <class ELFT>657Expected<const uint8_t *>658ELFFile<ELFT>::toMappedAddr(uint64_t VAddr, WarningHandler WarnHandler) const {659auto ProgramHeadersOrError = program_headers();660if (!ProgramHeadersOrError)661return ProgramHeadersOrError.takeError();662663llvm::SmallVector<Elf_Phdr *, 4> LoadSegments;664665for (const Elf_Phdr &Phdr : *ProgramHeadersOrError)666if (Phdr.p_type == ELF::PT_LOAD)667LoadSegments.push_back(const_cast<Elf_Phdr *>(&Phdr));668669auto SortPred = [](const Elf_Phdr_Impl<ELFT> *A,670const Elf_Phdr_Impl<ELFT> *B) {671return A->p_vaddr < B->p_vaddr;672};673if (!llvm::is_sorted(LoadSegments, SortPred)) {674if (Error E =675WarnHandler("loadable segments are unsorted by virtual address"))676return std::move(E);677llvm::stable_sort(LoadSegments, SortPred);678}679680const Elf_Phdr *const *I = llvm::upper_bound(681LoadSegments, VAddr, [](uint64_t VAddr, const Elf_Phdr_Impl<ELFT> *Phdr) {682return VAddr < Phdr->p_vaddr;683});684685if (I == LoadSegments.begin())686return createError("virtual address is not in any segment: 0x" +687Twine::utohexstr(VAddr));688--I;689const Elf_Phdr &Phdr = **I;690uint64_t Delta = VAddr - Phdr.p_vaddr;691if (Delta >= Phdr.p_filesz)692return createError("virtual address is not in any segment: 0x" +693Twine::utohexstr(VAddr));694695uint64_t Offset = Phdr.p_offset + Delta;696if (Offset >= getBufSize())697return createError("can't map virtual address 0x" +698Twine::utohexstr(VAddr) + " to the segment with index " +699Twine(&Phdr - (*ProgramHeadersOrError).data() + 1) +700": the segment ends at 0x" +701Twine::utohexstr(Phdr.p_offset + Phdr.p_filesz) +702", which is greater than the file size (0x" +703Twine::utohexstr(getBufSize()) + ")");704705return base() + Offset;706}707708// Helper to extract and decode the next ULEB128 value as unsigned int.709// Returns zero and sets ULEBSizeErr if the ULEB128 value exceeds the unsigned710// int limit.711// Also returns zero if ULEBSizeErr is already in an error state.712// ULEBSizeErr is an out variable if an error occurs.713template <typename IntTy, std::enable_if_t<std::is_unsigned_v<IntTy>, int> = 0>714static IntTy readULEB128As(DataExtractor &Data, DataExtractor::Cursor &Cur,715Error &ULEBSizeErr) {716// Bail out and do not extract data if ULEBSizeErr is already set.717if (ULEBSizeErr)718return 0;719uint64_t Offset = Cur.tell();720uint64_t Value = Data.getULEB128(Cur);721if (Value > std::numeric_limits<IntTy>::max()) {722ULEBSizeErr = createError("ULEB128 value at offset 0x" +723Twine::utohexstr(Offset) + " exceeds UINT" +724Twine(std::numeric_limits<IntTy>::digits) +725"_MAX (0x" + Twine::utohexstr(Value) + ")");726return 0;727}728return static_cast<IntTy>(Value);729}730731template <typename ELFT>732static Expected<std::vector<BBAddrMap>>733decodeBBAddrMapImpl(const ELFFile<ELFT> &EF,734const typename ELFFile<ELFT>::Elf_Shdr &Sec,735const typename ELFFile<ELFT>::Elf_Shdr *RelaSec,736std::vector<PGOAnalysisMap> *PGOAnalyses) {737bool IsRelocatable = EF.getHeader().e_type == ELF::ET_REL;738739// This DenseMap maps the offset of each function (the location of the740// reference to the function in the SHT_LLVM_BB_ADDR_MAP section) to the741// addend (the location of the function in the text section).742llvm::DenseMap<uint64_t, uint64_t> FunctionOffsetTranslations;743if (IsRelocatable && RelaSec) {744assert(RelaSec &&745"Can't read a SHT_LLVM_BB_ADDR_MAP section in a relocatable "746"object file without providing a relocation section.");747Expected<typename ELFFile<ELFT>::Elf_Rela_Range> Relas = EF.relas(*RelaSec);748if (!Relas)749return createError("unable to read relocations for section " +750describe(EF, Sec) + ": " +751toString(Relas.takeError()));752for (typename ELFFile<ELFT>::Elf_Rela Rela : *Relas)753FunctionOffsetTranslations[Rela.r_offset] = Rela.r_addend;754}755auto GetAddressForRelocation =756[&](unsigned RelocationOffsetInSection) -> Expected<unsigned> {757auto FOTIterator =758FunctionOffsetTranslations.find(RelocationOffsetInSection);759if (FOTIterator == FunctionOffsetTranslations.end()) {760return createError("failed to get relocation data for offset: " +761Twine::utohexstr(RelocationOffsetInSection) +762" in section " + describe(EF, Sec));763}764return FOTIterator->second;765};766Expected<ArrayRef<uint8_t>> ContentsOrErr = EF.getSectionContents(Sec);767if (!ContentsOrErr)768return ContentsOrErr.takeError();769ArrayRef<uint8_t> Content = *ContentsOrErr;770DataExtractor Data(Content, EF.isLE(), ELFT::Is64Bits ? 8 : 4);771std::vector<BBAddrMap> FunctionEntries;772773DataExtractor::Cursor Cur(0);774Error ULEBSizeErr = Error::success();775Error MetadataDecodeErr = Error::success();776777// Helper lampda to extract the (possiblly relocatable) address stored at Cur.778auto ExtractAddress = [&]() -> Expected<typename ELFFile<ELFT>::uintX_t> {779uint64_t RelocationOffsetInSection = Cur.tell();780auto Address =781static_cast<typename ELFFile<ELFT>::uintX_t>(Data.getAddress(Cur));782if (!Cur)783return Cur.takeError();784if (!IsRelocatable)785return Address;786assert(Address == 0);787Expected<unsigned> AddressOrErr =788GetAddressForRelocation(RelocationOffsetInSection);789if (!AddressOrErr)790return AddressOrErr.takeError();791return *AddressOrErr;792};793794uint8_t Version = 0;795uint8_t Feature = 0;796BBAddrMap::Features FeatEnable{};797while (!ULEBSizeErr && !MetadataDecodeErr && Cur &&798Cur.tell() < Content.size()) {799if (Sec.sh_type == ELF::SHT_LLVM_BB_ADDR_MAP) {800Version = Data.getU8(Cur);801if (!Cur)802break;803if (Version > 2)804return createError("unsupported SHT_LLVM_BB_ADDR_MAP version: " +805Twine(static_cast<int>(Version)));806Feature = Data.getU8(Cur); // Feature byte807if (!Cur)808break;809auto FeatEnableOrErr = BBAddrMap::Features::decode(Feature);810if (!FeatEnableOrErr)811return FeatEnableOrErr.takeError();812FeatEnable = *FeatEnableOrErr;813if (Feature != 0 && Version < 2 && Cur)814return createError(815"version should be >= 2 for SHT_LLVM_BB_ADDR_MAP when "816"PGO features are enabled: version = " +817Twine(static_cast<int>(Version)) +818" feature = " + Twine(static_cast<int>(Feature)));819}820uint32_t NumBlocksInBBRange = 0;821uint32_t NumBBRanges = 1;822typename ELFFile<ELFT>::uintX_t RangeBaseAddress = 0;823std::vector<BBAddrMap::BBEntry> BBEntries;824if (FeatEnable.MultiBBRange) {825NumBBRanges = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);826if (!Cur || ULEBSizeErr)827break;828if (!NumBBRanges)829return createError("invalid zero number of BB ranges at offset " +830Twine::utohexstr(Cur.tell()) + " in " +831describe(EF, Sec));832} else {833auto AddressOrErr = ExtractAddress();834if (!AddressOrErr)835return AddressOrErr.takeError();836RangeBaseAddress = *AddressOrErr;837NumBlocksInBBRange = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);838}839std::vector<BBAddrMap::BBRangeEntry> BBRangeEntries;840uint32_t TotalNumBlocks = 0;841for (uint32_t BBRangeIndex = 0; BBRangeIndex < NumBBRanges;842++BBRangeIndex) {843uint32_t PrevBBEndOffset = 0;844if (FeatEnable.MultiBBRange) {845auto AddressOrErr = ExtractAddress();846if (!AddressOrErr)847return AddressOrErr.takeError();848RangeBaseAddress = *AddressOrErr;849NumBlocksInBBRange = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);850}851for (uint32_t BlockIndex = 0; !MetadataDecodeErr && !ULEBSizeErr && Cur &&852(BlockIndex < NumBlocksInBBRange);853++BlockIndex) {854uint32_t ID = Version >= 2855? readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr)856: BlockIndex;857uint32_t Offset = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);858uint32_t Size = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);859uint32_t MD = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);860if (Version >= 1) {861// Offset is calculated relative to the end of the previous BB.862Offset += PrevBBEndOffset;863PrevBBEndOffset = Offset + Size;864}865Expected<BBAddrMap::BBEntry::Metadata> MetadataOrErr =866BBAddrMap::BBEntry::Metadata::decode(MD);867if (!MetadataOrErr) {868MetadataDecodeErr = MetadataOrErr.takeError();869break;870}871BBEntries.push_back({ID, Offset, Size, *MetadataOrErr});872}873TotalNumBlocks += BBEntries.size();874BBRangeEntries.push_back({RangeBaseAddress, std::move(BBEntries)});875}876FunctionEntries.push_back({std::move(BBRangeEntries)});877878if (PGOAnalyses || FeatEnable.hasPGOAnalysis()) {879// Function entry count880uint64_t FuncEntryCount =881FeatEnable.FuncEntryCount882? readULEB128As<uint64_t>(Data, Cur, ULEBSizeErr)883: 0;884885std::vector<PGOAnalysisMap::PGOBBEntry> PGOBBEntries;886for (uint32_t BlockIndex = 0;887FeatEnable.hasPGOAnalysisBBData() && !MetadataDecodeErr &&888!ULEBSizeErr && Cur && (BlockIndex < TotalNumBlocks);889++BlockIndex) {890// Block frequency891uint64_t BBF = FeatEnable.BBFreq892? readULEB128As<uint64_t>(Data, Cur, ULEBSizeErr)893: 0;894895// Branch probability896llvm::SmallVector<PGOAnalysisMap::PGOBBEntry::SuccessorEntry, 2>897Successors;898if (FeatEnable.BrProb) {899auto SuccCount = readULEB128As<uint64_t>(Data, Cur, ULEBSizeErr);900for (uint64_t I = 0; I < SuccCount; ++I) {901uint32_t BBID = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);902uint32_t BrProb = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);903if (PGOAnalyses)904Successors.push_back({BBID, BranchProbability::getRaw(BrProb)});905}906}907908if (PGOAnalyses)909PGOBBEntries.push_back({BlockFrequency(BBF), std::move(Successors)});910}911912if (PGOAnalyses)913PGOAnalyses->push_back(914{FuncEntryCount, std::move(PGOBBEntries), FeatEnable});915}916}917// Either Cur is in the error state, or we have an error in ULEBSizeErr or918// MetadataDecodeErr (but not both), but we join all errors here to be safe.919if (!Cur || ULEBSizeErr || MetadataDecodeErr)920return joinErrors(joinErrors(Cur.takeError(), std::move(ULEBSizeErr)),921std::move(MetadataDecodeErr));922return FunctionEntries;923}924925template <class ELFT>926Expected<std::vector<BBAddrMap>>927ELFFile<ELFT>::decodeBBAddrMap(const Elf_Shdr &Sec, const Elf_Shdr *RelaSec,928std::vector<PGOAnalysisMap> *PGOAnalyses) const {929size_t OriginalPGOSize = PGOAnalyses ? PGOAnalyses->size() : 0;930auto AddrMapsOrErr = decodeBBAddrMapImpl(*this, Sec, RelaSec, PGOAnalyses);931// remove new analyses when an error occurs932if (!AddrMapsOrErr && PGOAnalyses)933PGOAnalyses->resize(OriginalPGOSize);934return std::move(AddrMapsOrErr);935}936937template <class ELFT>938Expected<939MapVector<const typename ELFT::Shdr *, const typename ELFT::Shdr *>>940ELFFile<ELFT>::getSectionAndRelocations(941std::function<Expected<bool>(const Elf_Shdr &)> IsMatch) const {942MapVector<const Elf_Shdr *, const Elf_Shdr *> SecToRelocMap;943Error Errors = Error::success();944for (const Elf_Shdr &Sec : cantFail(this->sections())) {945Expected<bool> DoesSectionMatch = IsMatch(Sec);946if (!DoesSectionMatch) {947Errors = joinErrors(std::move(Errors), DoesSectionMatch.takeError());948continue;949}950if (*DoesSectionMatch) {951if (SecToRelocMap.insert(std::make_pair(&Sec, (const Elf_Shdr *)nullptr))952.second)953continue;954}955956if (Sec.sh_type != ELF::SHT_RELA && Sec.sh_type != ELF::SHT_REL)957continue;958959Expected<const Elf_Shdr *> RelSecOrErr = this->getSection(Sec.sh_info);960if (!RelSecOrErr) {961Errors = joinErrors(std::move(Errors),962createError(describe(*this, Sec) +963": failed to get a relocated section: " +964toString(RelSecOrErr.takeError())));965continue;966}967const Elf_Shdr *ContentsSec = *RelSecOrErr;968Expected<bool> DoesRelTargetMatch = IsMatch(*ContentsSec);969if (!DoesRelTargetMatch) {970Errors = joinErrors(std::move(Errors), DoesRelTargetMatch.takeError());971continue;972}973if (*DoesRelTargetMatch)974SecToRelocMap[ContentsSec] = &Sec;975}976if(Errors)977return std::move(Errors);978return SecToRelocMap;979}980981template class llvm::object::ELFFile<ELF32LE>;982template class llvm::object::ELFFile<ELF32BE>;983template class llvm::object::ELFFile<ELF64LE>;984template class llvm::object::ELFFile<ELF64BE>;985986987