brintos

brintos / llvm-project-archived public Read only

0
0
Text · 35.7 KiB · 35b5e0f Raw
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