10b57cec5SDimitry Andric //===- ELF.cpp - ELF object file implementation ---------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "llvm/Object/ELF.h" 100b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELF.h" 11fe6060f1SDimitry Andric #include "llvm/Support/DataExtractor.h" 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric using namespace llvm; 140b57cec5SDimitry Andric using namespace object; 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #define STRINGIFY_ENUM_CASE(ns, name) \ 170b57cec5SDimitry Andric case ns::name: \ 180b57cec5SDimitry Andric return #name; 190b57cec5SDimitry Andric 200b57cec5SDimitry Andric #define ELF_RELOC(name, value) STRINGIFY_ENUM_CASE(ELF, name) 210b57cec5SDimitry Andric 220b57cec5SDimitry Andric StringRef llvm::object::getELFRelocationTypeName(uint32_t Machine, 230b57cec5SDimitry Andric uint32_t Type) { 240b57cec5SDimitry Andric switch (Machine) { 25fe6060f1SDimitry Andric case ELF::EM_68K: 26fe6060f1SDimitry Andric switch (Type) { 27fe6060f1SDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/M68k.def" 28fe6060f1SDimitry Andric default: 29fe6060f1SDimitry Andric break; 30fe6060f1SDimitry Andric } 31fe6060f1SDimitry Andric break; 320b57cec5SDimitry Andric case ELF::EM_X86_64: 330b57cec5SDimitry Andric switch (Type) { 340b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/x86_64.def" 350b57cec5SDimitry Andric default: 360b57cec5SDimitry Andric break; 370b57cec5SDimitry Andric } 380b57cec5SDimitry Andric break; 390b57cec5SDimitry Andric case ELF::EM_386: 400b57cec5SDimitry Andric case ELF::EM_IAMCU: 410b57cec5SDimitry Andric switch (Type) { 420b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/i386.def" 430b57cec5SDimitry Andric default: 440b57cec5SDimitry Andric break; 450b57cec5SDimitry Andric } 460b57cec5SDimitry Andric break; 470b57cec5SDimitry Andric case ELF::EM_MIPS: 480b57cec5SDimitry Andric switch (Type) { 490b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/Mips.def" 500b57cec5SDimitry Andric default: 510b57cec5SDimitry Andric break; 520b57cec5SDimitry Andric } 530b57cec5SDimitry Andric break; 540b57cec5SDimitry Andric case ELF::EM_AARCH64: 550b57cec5SDimitry Andric switch (Type) { 560b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/AArch64.def" 570b57cec5SDimitry Andric default: 580b57cec5SDimitry Andric break; 590b57cec5SDimitry Andric } 600b57cec5SDimitry Andric break; 610b57cec5SDimitry Andric case ELF::EM_ARM: 620b57cec5SDimitry Andric switch (Type) { 630b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/ARM.def" 640b57cec5SDimitry Andric default: 650b57cec5SDimitry Andric break; 660b57cec5SDimitry Andric } 670b57cec5SDimitry Andric break; 680b57cec5SDimitry Andric case ELF::EM_ARC_COMPACT: 690b57cec5SDimitry Andric case ELF::EM_ARC_COMPACT2: 700b57cec5SDimitry Andric switch (Type) { 710b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/ARC.def" 720b57cec5SDimitry Andric default: 730b57cec5SDimitry Andric break; 740b57cec5SDimitry Andric } 750b57cec5SDimitry Andric break; 760b57cec5SDimitry Andric case ELF::EM_AVR: 770b57cec5SDimitry Andric switch (Type) { 780b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/AVR.def" 790b57cec5SDimitry Andric default: 800b57cec5SDimitry Andric break; 810b57cec5SDimitry Andric } 820b57cec5SDimitry Andric break; 830b57cec5SDimitry Andric case ELF::EM_HEXAGON: 840b57cec5SDimitry Andric switch (Type) { 850b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/Hexagon.def" 860b57cec5SDimitry Andric default: 870b57cec5SDimitry Andric break; 880b57cec5SDimitry Andric } 890b57cec5SDimitry Andric break; 900b57cec5SDimitry Andric case ELF::EM_LANAI: 910b57cec5SDimitry Andric switch (Type) { 920b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/Lanai.def" 930b57cec5SDimitry Andric default: 940b57cec5SDimitry Andric break; 950b57cec5SDimitry Andric } 960b57cec5SDimitry Andric break; 970b57cec5SDimitry Andric case ELF::EM_PPC: 980b57cec5SDimitry Andric switch (Type) { 990b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/PowerPC.def" 1000b57cec5SDimitry Andric default: 1010b57cec5SDimitry Andric break; 1020b57cec5SDimitry Andric } 1030b57cec5SDimitry Andric break; 1040b57cec5SDimitry Andric case ELF::EM_PPC64: 1050b57cec5SDimitry Andric switch (Type) { 1060b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/PowerPC64.def" 1070b57cec5SDimitry Andric default: 1080b57cec5SDimitry Andric break; 1090b57cec5SDimitry Andric } 1100b57cec5SDimitry Andric break; 1110b57cec5SDimitry Andric case ELF::EM_RISCV: 1120b57cec5SDimitry Andric switch (Type) { 1130b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/RISCV.def" 1140b57cec5SDimitry Andric default: 1150b57cec5SDimitry Andric break; 1160b57cec5SDimitry Andric } 1170b57cec5SDimitry Andric break; 1180b57cec5SDimitry Andric case ELF::EM_S390: 1190b57cec5SDimitry Andric switch (Type) { 1200b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/SystemZ.def" 1210b57cec5SDimitry Andric default: 1220b57cec5SDimitry Andric break; 1230b57cec5SDimitry Andric } 1240b57cec5SDimitry Andric break; 1250b57cec5SDimitry Andric case ELF::EM_SPARC: 1260b57cec5SDimitry Andric case ELF::EM_SPARC32PLUS: 1270b57cec5SDimitry Andric case ELF::EM_SPARCV9: 1280b57cec5SDimitry Andric switch (Type) { 1290b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/Sparc.def" 1300b57cec5SDimitry Andric default: 1310b57cec5SDimitry Andric break; 1320b57cec5SDimitry Andric } 1330b57cec5SDimitry Andric break; 1340b57cec5SDimitry Andric case ELF::EM_AMDGPU: 1350b57cec5SDimitry Andric switch (Type) { 1360b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/AMDGPU.def" 1370b57cec5SDimitry Andric default: 1380b57cec5SDimitry Andric break; 1390b57cec5SDimitry Andric } 1400b57cec5SDimitry Andric break; 1410b57cec5SDimitry Andric case ELF::EM_BPF: 1420b57cec5SDimitry Andric switch (Type) { 1430b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/BPF.def" 1440b57cec5SDimitry Andric default: 1450b57cec5SDimitry Andric break; 1460b57cec5SDimitry Andric } 1470b57cec5SDimitry Andric break; 1480b57cec5SDimitry Andric case ELF::EM_MSP430: 1490b57cec5SDimitry Andric switch (Type) { 1500b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/MSP430.def" 1510b57cec5SDimitry Andric default: 1520b57cec5SDimitry Andric break; 1530b57cec5SDimitry Andric } 1540b57cec5SDimitry Andric break; 1555ffd83dbSDimitry Andric case ELF::EM_VE: 1565ffd83dbSDimitry Andric switch (Type) { 1575ffd83dbSDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/VE.def" 1585ffd83dbSDimitry Andric default: 1595ffd83dbSDimitry Andric break; 1605ffd83dbSDimitry Andric } 1615ffd83dbSDimitry Andric break; 162e8d8bef9SDimitry Andric case ELF::EM_CSKY: 163e8d8bef9SDimitry Andric switch (Type) { 164e8d8bef9SDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/CSKY.def" 165e8d8bef9SDimitry Andric default: 166e8d8bef9SDimitry Andric break; 167e8d8bef9SDimitry Andric } 168e8d8bef9SDimitry Andric break; 16981ad6265SDimitry Andric case ELF::EM_LOONGARCH: 17081ad6265SDimitry Andric switch (Type) { 17181ad6265SDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/LoongArch.def" 17281ad6265SDimitry Andric default: 17381ad6265SDimitry Andric break; 17481ad6265SDimitry Andric } 17581ad6265SDimitry Andric break; 176*bdd1243dSDimitry Andric case ELF::EM_XTENSA: 177*bdd1243dSDimitry Andric switch (Type) { 178*bdd1243dSDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/Xtensa.def" 179*bdd1243dSDimitry Andric default: 180*bdd1243dSDimitry Andric break; 181*bdd1243dSDimitry Andric } 182*bdd1243dSDimitry Andric break; 1830b57cec5SDimitry Andric default: 1840b57cec5SDimitry Andric break; 1850b57cec5SDimitry Andric } 1860b57cec5SDimitry Andric return "Unknown"; 1870b57cec5SDimitry Andric } 1880b57cec5SDimitry Andric 1890b57cec5SDimitry Andric #undef ELF_RELOC 1900b57cec5SDimitry Andric 1910b57cec5SDimitry Andric uint32_t llvm::object::getELFRelativeRelocationType(uint32_t Machine) { 1920b57cec5SDimitry Andric switch (Machine) { 1930b57cec5SDimitry Andric case ELF::EM_X86_64: 1940b57cec5SDimitry Andric return ELF::R_X86_64_RELATIVE; 1950b57cec5SDimitry Andric case ELF::EM_386: 1960b57cec5SDimitry Andric case ELF::EM_IAMCU: 1970b57cec5SDimitry Andric return ELF::R_386_RELATIVE; 1980b57cec5SDimitry Andric case ELF::EM_MIPS: 1990b57cec5SDimitry Andric break; 2000b57cec5SDimitry Andric case ELF::EM_AARCH64: 2010b57cec5SDimitry Andric return ELF::R_AARCH64_RELATIVE; 2020b57cec5SDimitry Andric case ELF::EM_ARM: 2030b57cec5SDimitry Andric return ELF::R_ARM_RELATIVE; 2040b57cec5SDimitry Andric case ELF::EM_ARC_COMPACT: 2050b57cec5SDimitry Andric case ELF::EM_ARC_COMPACT2: 2060b57cec5SDimitry Andric return ELF::R_ARC_RELATIVE; 2070b57cec5SDimitry Andric case ELF::EM_AVR: 2080b57cec5SDimitry Andric break; 2090b57cec5SDimitry Andric case ELF::EM_HEXAGON: 2100b57cec5SDimitry Andric return ELF::R_HEX_RELATIVE; 2110b57cec5SDimitry Andric case ELF::EM_LANAI: 2120b57cec5SDimitry Andric break; 2130b57cec5SDimitry Andric case ELF::EM_PPC: 2140b57cec5SDimitry Andric break; 2150b57cec5SDimitry Andric case ELF::EM_PPC64: 2160b57cec5SDimitry Andric return ELF::R_PPC64_RELATIVE; 2170b57cec5SDimitry Andric case ELF::EM_RISCV: 2180b57cec5SDimitry Andric return ELF::R_RISCV_RELATIVE; 2190b57cec5SDimitry Andric case ELF::EM_S390: 2200b57cec5SDimitry Andric return ELF::R_390_RELATIVE; 2210b57cec5SDimitry Andric case ELF::EM_SPARC: 2220b57cec5SDimitry Andric case ELF::EM_SPARC32PLUS: 2230b57cec5SDimitry Andric case ELF::EM_SPARCV9: 2240b57cec5SDimitry Andric return ELF::R_SPARC_RELATIVE; 225e8d8bef9SDimitry Andric case ELF::EM_CSKY: 226e8d8bef9SDimitry Andric return ELF::R_CKCORE_RELATIVE; 2270eae32dcSDimitry Andric case ELF::EM_VE: 2280eae32dcSDimitry Andric return ELF::R_VE_RELATIVE; 2290b57cec5SDimitry Andric case ELF::EM_AMDGPU: 2300b57cec5SDimitry Andric break; 2310b57cec5SDimitry Andric case ELF::EM_BPF: 2320b57cec5SDimitry Andric break; 233*bdd1243dSDimitry Andric case ELF::EM_LOONGARCH: 234*bdd1243dSDimitry Andric return ELF::R_LARCH_RELATIVE; 2350b57cec5SDimitry Andric default: 2360b57cec5SDimitry Andric break; 2370b57cec5SDimitry Andric } 2380b57cec5SDimitry Andric return 0; 2390b57cec5SDimitry Andric } 2400b57cec5SDimitry Andric 2410b57cec5SDimitry Andric StringRef llvm::object::getELFSectionTypeName(uint32_t Machine, unsigned Type) { 2420b57cec5SDimitry Andric switch (Machine) { 2430b57cec5SDimitry Andric case ELF::EM_ARM: 2440b57cec5SDimitry Andric switch (Type) { 2450b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_ARM_EXIDX); 2460b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_ARM_PREEMPTMAP); 2470b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_ARM_ATTRIBUTES); 2480b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_ARM_DEBUGOVERLAY); 2490b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_ARM_OVERLAYSECTION); 2500b57cec5SDimitry Andric } 2510b57cec5SDimitry Andric break; 2520b57cec5SDimitry Andric case ELF::EM_HEXAGON: 2530b57cec5SDimitry Andric switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_HEX_ORDERED); } 2540b57cec5SDimitry Andric break; 2550b57cec5SDimitry Andric case ELF::EM_X86_64: 2560b57cec5SDimitry Andric switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_X86_64_UNWIND); } 2570b57cec5SDimitry Andric break; 2580b57cec5SDimitry Andric case ELF::EM_MIPS: 2590b57cec5SDimitry Andric case ELF::EM_MIPS_RS3_LE: 2600b57cec5SDimitry Andric switch (Type) { 2610b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_REGINFO); 2620b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_OPTIONS); 2630b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_DWARF); 2640b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_ABIFLAGS); 2650b57cec5SDimitry Andric } 2660b57cec5SDimitry Andric break; 267349cc55cSDimitry Andric case ELF::EM_MSP430: 268349cc55cSDimitry Andric switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_MSP430_ATTRIBUTES); } 269349cc55cSDimitry Andric break; 2705ffd83dbSDimitry Andric case ELF::EM_RISCV: 2715ffd83dbSDimitry Andric switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_RISCV_ATTRIBUTES); } 2725ffd83dbSDimitry Andric break; 2730b57cec5SDimitry Andric default: 2740b57cec5SDimitry Andric break; 2750b57cec5SDimitry Andric } 2760b57cec5SDimitry Andric 2770b57cec5SDimitry Andric switch (Type) { 2780b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_NULL); 2790b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_PROGBITS); 2800b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_SYMTAB); 2810b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_STRTAB); 2820b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_RELA); 2830b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_HASH); 2840b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_DYNAMIC); 2850b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_NOTE); 2860b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_NOBITS); 2870b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_REL); 2880b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_SHLIB); 2890b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_DYNSYM); 2900b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_INIT_ARRAY); 2910b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_FINI_ARRAY); 2920b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_PREINIT_ARRAY); 2930b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_GROUP); 2940b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_SYMTAB_SHNDX); 2950b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_RELR); 2960b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_REL); 2970b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_RELA); 2980b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_RELR); 2990b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_ODRTAB); 3000b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_LINKER_OPTIONS); 3010b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_CALL_GRAPH_PROFILE); 3020b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_ADDRSIG); 3030b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_DEPENDENT_LIBRARIES); 3040b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_SYMPART); 3058bcb0991SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_PART_EHDR); 3068bcb0991SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_PART_PHDR); 30781ad6265SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_BB_ADDR_MAP_V0); 308e8d8bef9SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_BB_ADDR_MAP); 309753f127fSDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_OFFLOADING); 3100b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_GNU_ATTRIBUTES); 3110b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_GNU_HASH); 3120b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_GNU_verdef); 3130b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_GNU_verneed); 3140b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_GNU_versym); 3150b57cec5SDimitry Andric default: 3160b57cec5SDimitry Andric return "Unknown"; 3170b57cec5SDimitry Andric } 3180b57cec5SDimitry Andric } 3190b57cec5SDimitry Andric 3200b57cec5SDimitry Andric template <class ELFT> 321e8d8bef9SDimitry Andric std::vector<typename ELFT::Rel> 3220b57cec5SDimitry Andric ELFFile<ELFT>::decode_relrs(Elf_Relr_Range relrs) const { 3230b57cec5SDimitry Andric // This function decodes the contents of an SHT_RELR packed relocation 3240b57cec5SDimitry Andric // section. 3250b57cec5SDimitry Andric // 3260b57cec5SDimitry Andric // Proposal for adding SHT_RELR sections to generic-abi is here: 3270b57cec5SDimitry Andric // https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg 3280b57cec5SDimitry Andric // 3290b57cec5SDimitry Andric // The encoded sequence of Elf64_Relr entries in a SHT_RELR section looks 3300b57cec5SDimitry Andric // like [ AAAAAAAA BBBBBBB1 BBBBBBB1 ... AAAAAAAA BBBBBB1 ... ] 3310b57cec5SDimitry Andric // 3320b57cec5SDimitry Andric // i.e. start with an address, followed by any number of bitmaps. The address 3330b57cec5SDimitry Andric // entry encodes 1 relocation. The subsequent bitmap entries encode up to 63 3340b57cec5SDimitry Andric // relocations each, at subsequent offsets following the last address entry. 3350b57cec5SDimitry Andric // 3360b57cec5SDimitry Andric // The bitmap entries must have 1 in the least significant bit. The assumption 3370b57cec5SDimitry Andric // here is that an address cannot have 1 in lsb. Odd addresses are not 3380b57cec5SDimitry Andric // supported. 3390b57cec5SDimitry Andric // 3400b57cec5SDimitry Andric // Excluding the least significant bit in the bitmap, each non-zero bit in 3410b57cec5SDimitry Andric // the bitmap represents a relocation to be applied to a corresponding machine 3420b57cec5SDimitry Andric // word that follows the base address word. The second least significant bit 3430b57cec5SDimitry Andric // represents the machine word immediately following the initial address, and 3440b57cec5SDimitry Andric // each bit that follows represents the next word, in linear order. As such, 3450b57cec5SDimitry Andric // a single bitmap can encode up to 31 relocations in a 32-bit object, and 3460b57cec5SDimitry Andric // 63 relocations in a 64-bit object. 3470b57cec5SDimitry Andric // 3480b57cec5SDimitry Andric // This encoding has a couple of interesting properties: 3490b57cec5SDimitry Andric // 1. Looking at any entry, it is clear whether it's an address or a bitmap: 3500b57cec5SDimitry Andric // even means address, odd means bitmap. 3510b57cec5SDimitry Andric // 2. Just a simple list of addresses is a valid encoding. 3520b57cec5SDimitry Andric 353e8d8bef9SDimitry Andric Elf_Rel Rel; 354e8d8bef9SDimitry Andric Rel.r_info = 0; 355e8d8bef9SDimitry Andric Rel.setType(getRelativeRelocationType(), false); 356e8d8bef9SDimitry Andric std::vector<Elf_Rel> Relocs; 3570b57cec5SDimitry Andric 3580b57cec5SDimitry Andric // Word type: uint32_t for Elf32, and uint64_t for Elf64. 359349cc55cSDimitry Andric using Addr = typename ELFT::uint; 3600b57cec5SDimitry Andric 361349cc55cSDimitry Andric Addr Base = 0; 362349cc55cSDimitry Andric for (Elf_Relr R : relrs) { 363349cc55cSDimitry Andric typename ELFT::uint Entry = R; 3640b57cec5SDimitry Andric if ((Entry & 1) == 0) { 3650b57cec5SDimitry Andric // Even entry: encodes the offset for next relocation. 366e8d8bef9SDimitry Andric Rel.r_offset = Entry; 367e8d8bef9SDimitry Andric Relocs.push_back(Rel); 3680b57cec5SDimitry Andric // Set base offset for subsequent bitmap entries. 369349cc55cSDimitry Andric Base = Entry + sizeof(Addr); 370349cc55cSDimitry Andric } else { 3710b57cec5SDimitry Andric // Odd entry: encodes bitmap for relocations starting at base. 372349cc55cSDimitry Andric for (Addr Offset = Base; (Entry >>= 1) != 0; Offset += sizeof(Addr)) 3730b57cec5SDimitry Andric if ((Entry & 1) != 0) { 374e8d8bef9SDimitry Andric Rel.r_offset = Offset; 375e8d8bef9SDimitry Andric Relocs.push_back(Rel); 3760b57cec5SDimitry Andric } 377349cc55cSDimitry Andric Base += (CHAR_BIT * sizeof(Entry) - 1) * sizeof(Addr); 3780b57cec5SDimitry Andric } 3790b57cec5SDimitry Andric } 3800b57cec5SDimitry Andric 3810b57cec5SDimitry Andric return Relocs; 3820b57cec5SDimitry Andric } 3830b57cec5SDimitry Andric 3840b57cec5SDimitry Andric template <class ELFT> 3850b57cec5SDimitry Andric Expected<std::vector<typename ELFT::Rela>> 386e8d8bef9SDimitry Andric ELFFile<ELFT>::android_relas(const Elf_Shdr &Sec) const { 3870b57cec5SDimitry Andric // This function reads relocations in Android's packed relocation format, 3880b57cec5SDimitry Andric // which is based on SLEB128 and delta encoding. 3890b57cec5SDimitry Andric Expected<ArrayRef<uint8_t>> ContentsOrErr = getSectionContents(Sec); 3900b57cec5SDimitry Andric if (!ContentsOrErr) 3910b57cec5SDimitry Andric return ContentsOrErr.takeError(); 392fe6060f1SDimitry Andric ArrayRef<uint8_t> Content = *ContentsOrErr; 393fe6060f1SDimitry Andric if (Content.size() < 4 || Content[0] != 'A' || Content[1] != 'P' || 394fe6060f1SDimitry Andric Content[2] != 'S' || Content[3] != '2') 3950b57cec5SDimitry Andric return createError("invalid packed relocation header"); 396fe6060f1SDimitry Andric DataExtractor Data(Content, isLE(), ELFT::Is64Bits ? 8 : 4); 397fe6060f1SDimitry Andric DataExtractor::Cursor Cur(/*Offset=*/4); 3980b57cec5SDimitry Andric 399fe6060f1SDimitry Andric uint64_t NumRelocs = Data.getSLEB128(Cur); 400fe6060f1SDimitry Andric uint64_t Offset = Data.getSLEB128(Cur); 4010b57cec5SDimitry Andric uint64_t Addend = 0; 4020b57cec5SDimitry Andric 403fe6060f1SDimitry Andric if (!Cur) 404fe6060f1SDimitry Andric return std::move(Cur.takeError()); 4050b57cec5SDimitry Andric 4060b57cec5SDimitry Andric std::vector<Elf_Rela> Relocs; 4070b57cec5SDimitry Andric Relocs.reserve(NumRelocs); 4080b57cec5SDimitry Andric while (NumRelocs) { 409fe6060f1SDimitry Andric uint64_t NumRelocsInGroup = Data.getSLEB128(Cur); 410fe6060f1SDimitry Andric if (!Cur) 411fe6060f1SDimitry Andric return std::move(Cur.takeError()); 4120b57cec5SDimitry Andric if (NumRelocsInGroup > NumRelocs) 4130b57cec5SDimitry Andric return createError("relocation group unexpectedly large"); 4140b57cec5SDimitry Andric NumRelocs -= NumRelocsInGroup; 4150b57cec5SDimitry Andric 416fe6060f1SDimitry Andric uint64_t GroupFlags = Data.getSLEB128(Cur); 4170b57cec5SDimitry Andric bool GroupedByInfo = GroupFlags & ELF::RELOCATION_GROUPED_BY_INFO_FLAG; 4180b57cec5SDimitry Andric bool GroupedByOffsetDelta = GroupFlags & ELF::RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG; 4190b57cec5SDimitry Andric bool GroupedByAddend = GroupFlags & ELF::RELOCATION_GROUPED_BY_ADDEND_FLAG; 4200b57cec5SDimitry Andric bool GroupHasAddend = GroupFlags & ELF::RELOCATION_GROUP_HAS_ADDEND_FLAG; 4210b57cec5SDimitry Andric 4220b57cec5SDimitry Andric uint64_t GroupOffsetDelta; 4230b57cec5SDimitry Andric if (GroupedByOffsetDelta) 424fe6060f1SDimitry Andric GroupOffsetDelta = Data.getSLEB128(Cur); 4250b57cec5SDimitry Andric 4260b57cec5SDimitry Andric uint64_t GroupRInfo; 4270b57cec5SDimitry Andric if (GroupedByInfo) 428fe6060f1SDimitry Andric GroupRInfo = Data.getSLEB128(Cur); 4290b57cec5SDimitry Andric 4300b57cec5SDimitry Andric if (GroupedByAddend && GroupHasAddend) 431fe6060f1SDimitry Andric Addend += Data.getSLEB128(Cur); 4320b57cec5SDimitry Andric 4330b57cec5SDimitry Andric if (!GroupHasAddend) 4340b57cec5SDimitry Andric Addend = 0; 4350b57cec5SDimitry Andric 436fe6060f1SDimitry Andric for (uint64_t I = 0; Cur && I != NumRelocsInGroup; ++I) { 4370b57cec5SDimitry Andric Elf_Rela R; 438fe6060f1SDimitry Andric Offset += GroupedByOffsetDelta ? GroupOffsetDelta : Data.getSLEB128(Cur); 4390b57cec5SDimitry Andric R.r_offset = Offset; 440fe6060f1SDimitry Andric R.r_info = GroupedByInfo ? GroupRInfo : Data.getSLEB128(Cur); 4410b57cec5SDimitry Andric if (GroupHasAddend && !GroupedByAddend) 442fe6060f1SDimitry Andric Addend += Data.getSLEB128(Cur); 4430b57cec5SDimitry Andric R.r_addend = Addend; 4440b57cec5SDimitry Andric Relocs.push_back(R); 4450b57cec5SDimitry Andric } 446fe6060f1SDimitry Andric if (!Cur) 447fe6060f1SDimitry Andric return std::move(Cur.takeError()); 4480b57cec5SDimitry Andric } 4490b57cec5SDimitry Andric 4500b57cec5SDimitry Andric return Relocs; 4510b57cec5SDimitry Andric } 4520b57cec5SDimitry Andric 4530b57cec5SDimitry Andric template <class ELFT> 4540b57cec5SDimitry Andric std::string ELFFile<ELFT>::getDynamicTagAsString(unsigned Arch, 4550b57cec5SDimitry Andric uint64_t Type) const { 4560b57cec5SDimitry Andric #define DYNAMIC_STRINGIFY_ENUM(tag, value) \ 4570b57cec5SDimitry Andric case value: \ 4580b57cec5SDimitry Andric return #tag; 4590b57cec5SDimitry Andric 4600b57cec5SDimitry Andric #define DYNAMIC_TAG(n, v) 4610b57cec5SDimitry Andric switch (Arch) { 4620b57cec5SDimitry Andric case ELF::EM_AARCH64: 4630b57cec5SDimitry Andric switch (Type) { 4640b57cec5SDimitry Andric #define AARCH64_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value) 4650b57cec5SDimitry Andric #include "llvm/BinaryFormat/DynamicTags.def" 4660b57cec5SDimitry Andric #undef AARCH64_DYNAMIC_TAG 4670b57cec5SDimitry Andric } 4680b57cec5SDimitry Andric break; 4690b57cec5SDimitry Andric 4700b57cec5SDimitry Andric case ELF::EM_HEXAGON: 4710b57cec5SDimitry Andric switch (Type) { 4720b57cec5SDimitry Andric #define HEXAGON_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value) 4730b57cec5SDimitry Andric #include "llvm/BinaryFormat/DynamicTags.def" 4740b57cec5SDimitry Andric #undef HEXAGON_DYNAMIC_TAG 4750b57cec5SDimitry Andric } 4760b57cec5SDimitry Andric break; 4770b57cec5SDimitry Andric 4780b57cec5SDimitry Andric case ELF::EM_MIPS: 4790b57cec5SDimitry Andric switch (Type) { 4800b57cec5SDimitry Andric #define MIPS_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value) 4810b57cec5SDimitry Andric #include "llvm/BinaryFormat/DynamicTags.def" 4820b57cec5SDimitry Andric #undef MIPS_DYNAMIC_TAG 4830b57cec5SDimitry Andric } 4840b57cec5SDimitry Andric break; 4850b57cec5SDimitry Andric 486349cc55cSDimitry Andric case ELF::EM_PPC: 487349cc55cSDimitry Andric switch (Type) { 488349cc55cSDimitry Andric #define PPC_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value) 489349cc55cSDimitry Andric #include "llvm/BinaryFormat/DynamicTags.def" 490349cc55cSDimitry Andric #undef PPC_DYNAMIC_TAG 491349cc55cSDimitry Andric } 492349cc55cSDimitry Andric break; 493349cc55cSDimitry Andric 4940b57cec5SDimitry Andric case ELF::EM_PPC64: 4950b57cec5SDimitry Andric switch (Type) { 4960b57cec5SDimitry Andric #define PPC64_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value) 4970b57cec5SDimitry Andric #include "llvm/BinaryFormat/DynamicTags.def" 4980b57cec5SDimitry Andric #undef PPC64_DYNAMIC_TAG 4990b57cec5SDimitry Andric } 5000b57cec5SDimitry Andric break; 501349cc55cSDimitry Andric 502349cc55cSDimitry Andric case ELF::EM_RISCV: 503349cc55cSDimitry Andric switch (Type) { 504349cc55cSDimitry Andric #define RISCV_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value) 505349cc55cSDimitry Andric #include "llvm/BinaryFormat/DynamicTags.def" 506349cc55cSDimitry Andric #undef RISCV_DYNAMIC_TAG 507349cc55cSDimitry Andric } 508349cc55cSDimitry Andric break; 5090b57cec5SDimitry Andric } 5100b57cec5SDimitry Andric #undef DYNAMIC_TAG 5110b57cec5SDimitry Andric switch (Type) { 5120b57cec5SDimitry Andric // Now handle all dynamic tags except the architecture specific ones 5130b57cec5SDimitry Andric #define AARCH64_DYNAMIC_TAG(name, value) 5140b57cec5SDimitry Andric #define MIPS_DYNAMIC_TAG(name, value) 5150b57cec5SDimitry Andric #define HEXAGON_DYNAMIC_TAG(name, value) 516349cc55cSDimitry Andric #define PPC_DYNAMIC_TAG(name, value) 5170b57cec5SDimitry Andric #define PPC64_DYNAMIC_TAG(name, value) 518349cc55cSDimitry Andric #define RISCV_DYNAMIC_TAG(name, value) 5190b57cec5SDimitry Andric // Also ignore marker tags such as DT_HIOS (maps to DT_VERNEEDNUM), etc. 5200b57cec5SDimitry Andric #define DYNAMIC_TAG_MARKER(name, value) 521480093f4SDimitry Andric #define DYNAMIC_TAG(name, value) case value: return #name; 5220b57cec5SDimitry Andric #include "llvm/BinaryFormat/DynamicTags.def" 5230b57cec5SDimitry Andric #undef DYNAMIC_TAG 5240b57cec5SDimitry Andric #undef AARCH64_DYNAMIC_TAG 5250b57cec5SDimitry Andric #undef MIPS_DYNAMIC_TAG 5260b57cec5SDimitry Andric #undef HEXAGON_DYNAMIC_TAG 527349cc55cSDimitry Andric #undef PPC_DYNAMIC_TAG 5280b57cec5SDimitry Andric #undef PPC64_DYNAMIC_TAG 529349cc55cSDimitry Andric #undef RISCV_DYNAMIC_TAG 5300b57cec5SDimitry Andric #undef DYNAMIC_TAG_MARKER 5310b57cec5SDimitry Andric #undef DYNAMIC_STRINGIFY_ENUM 5320b57cec5SDimitry Andric default: 5330b57cec5SDimitry Andric return "<unknown:>0x" + utohexstr(Type, true); 5340b57cec5SDimitry Andric } 5350b57cec5SDimitry Andric } 5360b57cec5SDimitry Andric 5370b57cec5SDimitry Andric template <class ELFT> 5380b57cec5SDimitry Andric std::string ELFFile<ELFT>::getDynamicTagAsString(uint64_t Type) const { 539e8d8bef9SDimitry Andric return getDynamicTagAsString(getHeader().e_machine, Type); 5400b57cec5SDimitry Andric } 5410b57cec5SDimitry Andric 5420b57cec5SDimitry Andric template <class ELFT> 5430b57cec5SDimitry Andric Expected<typename ELFT::DynRange> ELFFile<ELFT>::dynamicEntries() const { 5440b57cec5SDimitry Andric ArrayRef<Elf_Dyn> Dyn; 5450b57cec5SDimitry Andric 5460b57cec5SDimitry Andric auto ProgramHeadersOrError = program_headers(); 5470b57cec5SDimitry Andric if (!ProgramHeadersOrError) 5480b57cec5SDimitry Andric return ProgramHeadersOrError.takeError(); 5490b57cec5SDimitry Andric 5500b57cec5SDimitry Andric for (const Elf_Phdr &Phdr : *ProgramHeadersOrError) { 5510b57cec5SDimitry Andric if (Phdr.p_type == ELF::PT_DYNAMIC) { 552*bdd1243dSDimitry Andric Dyn = ArrayRef(reinterpret_cast<const Elf_Dyn *>(base() + Phdr.p_offset), 5530b57cec5SDimitry Andric Phdr.p_filesz / sizeof(Elf_Dyn)); 5540b57cec5SDimitry Andric break; 5550b57cec5SDimitry Andric } 5560b57cec5SDimitry Andric } 5570b57cec5SDimitry Andric 5580b57cec5SDimitry Andric // If we can't find the dynamic section in the program headers, we just fall 5590b57cec5SDimitry Andric // back on the sections. 5600b57cec5SDimitry Andric if (Dyn.empty()) { 5610b57cec5SDimitry Andric auto SectionsOrError = sections(); 5620b57cec5SDimitry Andric if (!SectionsOrError) 5630b57cec5SDimitry Andric return SectionsOrError.takeError(); 5640b57cec5SDimitry Andric 5650b57cec5SDimitry Andric for (const Elf_Shdr &Sec : *SectionsOrError) { 5660b57cec5SDimitry Andric if (Sec.sh_type == ELF::SHT_DYNAMIC) { 5670b57cec5SDimitry Andric Expected<ArrayRef<Elf_Dyn>> DynOrError = 568e8d8bef9SDimitry Andric getSectionContentsAsArray<Elf_Dyn>(Sec); 5690b57cec5SDimitry Andric if (!DynOrError) 5700b57cec5SDimitry Andric return DynOrError.takeError(); 5710b57cec5SDimitry Andric Dyn = *DynOrError; 5720b57cec5SDimitry Andric break; 5730b57cec5SDimitry Andric } 5740b57cec5SDimitry Andric } 5750b57cec5SDimitry Andric 5760b57cec5SDimitry Andric if (!Dyn.data()) 5770b57cec5SDimitry Andric return ArrayRef<Elf_Dyn>(); 5780b57cec5SDimitry Andric } 5790b57cec5SDimitry Andric 5800b57cec5SDimitry Andric if (Dyn.empty()) 5810b57cec5SDimitry Andric return createError("invalid empty dynamic section"); 5820b57cec5SDimitry Andric 5830b57cec5SDimitry Andric if (Dyn.back().d_tag != ELF::DT_NULL) 5840b57cec5SDimitry Andric return createError("dynamic sections must be DT_NULL terminated"); 5850b57cec5SDimitry Andric 5860b57cec5SDimitry Andric return Dyn; 5870b57cec5SDimitry Andric } 5880b57cec5SDimitry Andric 5890b57cec5SDimitry Andric template <class ELFT> 590e8d8bef9SDimitry Andric Expected<const uint8_t *> 591e8d8bef9SDimitry Andric ELFFile<ELFT>::toMappedAddr(uint64_t VAddr, WarningHandler WarnHandler) const { 5920b57cec5SDimitry Andric auto ProgramHeadersOrError = program_headers(); 5930b57cec5SDimitry Andric if (!ProgramHeadersOrError) 5940b57cec5SDimitry Andric return ProgramHeadersOrError.takeError(); 5950b57cec5SDimitry Andric 5960b57cec5SDimitry Andric llvm::SmallVector<Elf_Phdr *, 4> LoadSegments; 5970b57cec5SDimitry Andric 5980b57cec5SDimitry Andric for (const Elf_Phdr &Phdr : *ProgramHeadersOrError) 5990b57cec5SDimitry Andric if (Phdr.p_type == ELF::PT_LOAD) 6000b57cec5SDimitry Andric LoadSegments.push_back(const_cast<Elf_Phdr *>(&Phdr)); 6010b57cec5SDimitry Andric 602e8d8bef9SDimitry Andric auto SortPred = [](const Elf_Phdr_Impl<ELFT> *A, 603e8d8bef9SDimitry Andric const Elf_Phdr_Impl<ELFT> *B) { 604e8d8bef9SDimitry Andric return A->p_vaddr < B->p_vaddr; 605e8d8bef9SDimitry Andric }; 606e8d8bef9SDimitry Andric if (!llvm::is_sorted(LoadSegments, SortPred)) { 607e8d8bef9SDimitry Andric if (Error E = 608e8d8bef9SDimitry Andric WarnHandler("loadable segments are unsorted by virtual address")) 609e8d8bef9SDimitry Andric return std::move(E); 610e8d8bef9SDimitry Andric llvm::stable_sort(LoadSegments, SortPred); 611e8d8bef9SDimitry Andric } 612e8d8bef9SDimitry Andric 613e8d8bef9SDimitry Andric const Elf_Phdr *const *I = llvm::upper_bound( 614e8d8bef9SDimitry Andric LoadSegments, VAddr, [](uint64_t VAddr, const Elf_Phdr_Impl<ELFT> *Phdr) { 6150b57cec5SDimitry Andric return VAddr < Phdr->p_vaddr; 6160b57cec5SDimitry Andric }); 6170b57cec5SDimitry Andric 6180b57cec5SDimitry Andric if (I == LoadSegments.begin()) 6190b57cec5SDimitry Andric return createError("virtual address is not in any segment: 0x" + 6200b57cec5SDimitry Andric Twine::utohexstr(VAddr)); 6210b57cec5SDimitry Andric --I; 6220b57cec5SDimitry Andric const Elf_Phdr &Phdr = **I; 6230b57cec5SDimitry Andric uint64_t Delta = VAddr - Phdr.p_vaddr; 6240b57cec5SDimitry Andric if (Delta >= Phdr.p_filesz) 6250b57cec5SDimitry Andric return createError("virtual address is not in any segment: 0x" + 6260b57cec5SDimitry Andric Twine::utohexstr(VAddr)); 6275ffd83dbSDimitry Andric 6285ffd83dbSDimitry Andric uint64_t Offset = Phdr.p_offset + Delta; 6295ffd83dbSDimitry Andric if (Offset >= getBufSize()) 6305ffd83dbSDimitry Andric return createError("can't map virtual address 0x" + 6315ffd83dbSDimitry Andric Twine::utohexstr(VAddr) + " to the segment with index " + 6325ffd83dbSDimitry Andric Twine(&Phdr - (*ProgramHeadersOrError).data() + 1) + 6335ffd83dbSDimitry Andric ": the segment ends at 0x" + 6345ffd83dbSDimitry Andric Twine::utohexstr(Phdr.p_offset + Phdr.p_filesz) + 6355ffd83dbSDimitry Andric ", which is greater than the file size (0x" + 6365ffd83dbSDimitry Andric Twine::utohexstr(getBufSize()) + ")"); 6375ffd83dbSDimitry Andric 6385ffd83dbSDimitry Andric return base() + Offset; 6390b57cec5SDimitry Andric } 6400b57cec5SDimitry Andric 641fe6060f1SDimitry Andric template <class ELFT> 642349cc55cSDimitry Andric Expected<std::vector<BBAddrMap>> 643fe6060f1SDimitry Andric ELFFile<ELFT>::decodeBBAddrMap(const Elf_Shdr &Sec) const { 644fe6060f1SDimitry Andric Expected<ArrayRef<uint8_t>> ContentsOrErr = getSectionContents(Sec); 645fe6060f1SDimitry Andric if (!ContentsOrErr) 646fe6060f1SDimitry Andric return ContentsOrErr.takeError(); 647fe6060f1SDimitry Andric ArrayRef<uint8_t> Content = *ContentsOrErr; 648fe6060f1SDimitry Andric DataExtractor Data(Content, isLE(), ELFT::Is64Bits ? 8 : 4); 649349cc55cSDimitry Andric std::vector<BBAddrMap> FunctionEntries; 650fe6060f1SDimitry Andric 651fe6060f1SDimitry Andric DataExtractor::Cursor Cur(0); 652fe6060f1SDimitry Andric Error ULEBSizeErr = Error::success(); 653fe6060f1SDimitry Andric // Helper to extract and decode the next ULEB128 value as uint32_t. 654fe6060f1SDimitry Andric // Returns zero and sets ULEBSizeErr if the ULEB128 value exceeds the uint32_t 655fe6060f1SDimitry Andric // limit. 656fe6060f1SDimitry Andric // Also returns zero if ULEBSizeErr is already in an error state. 657fe6060f1SDimitry Andric auto ReadULEB128AsUInt32 = [&Data, &Cur, &ULEBSizeErr]() -> uint32_t { 658fe6060f1SDimitry Andric // Bail out and do not extract data if ULEBSizeErr is already set. 659fe6060f1SDimitry Andric if (ULEBSizeErr) 660fe6060f1SDimitry Andric return 0; 661fe6060f1SDimitry Andric uint64_t Offset = Cur.tell(); 662fe6060f1SDimitry Andric uint64_t Value = Data.getULEB128(Cur); 663fe6060f1SDimitry Andric if (Value > UINT32_MAX) { 664fe6060f1SDimitry Andric ULEBSizeErr = createError( 665fe6060f1SDimitry Andric "ULEB128 value at offset 0x" + Twine::utohexstr(Offset) + 666fe6060f1SDimitry Andric " exceeds UINT32_MAX (0x" + Twine::utohexstr(Value) + ")"); 667fe6060f1SDimitry Andric return 0; 668fe6060f1SDimitry Andric } 669fe6060f1SDimitry Andric return static_cast<uint32_t>(Value); 670fe6060f1SDimitry Andric }; 671fe6060f1SDimitry Andric 67281ad6265SDimitry Andric uint8_t Version = 0; 673fe6060f1SDimitry Andric while (!ULEBSizeErr && Cur && Cur.tell() < Content.size()) { 67481ad6265SDimitry Andric if (Sec.sh_type == ELF::SHT_LLVM_BB_ADDR_MAP) { 67581ad6265SDimitry Andric Version = Data.getU8(Cur); 67681ad6265SDimitry Andric if (!Cur) 67781ad6265SDimitry Andric break; 678*bdd1243dSDimitry Andric if (Version > 2) 67981ad6265SDimitry Andric return createError("unsupported SHT_LLVM_BB_ADDR_MAP version: " + 68081ad6265SDimitry Andric Twine(static_cast<int>(Version))); 68181ad6265SDimitry Andric Data.getU8(Cur); // Feature byte 68281ad6265SDimitry Andric } 683fe6060f1SDimitry Andric uintX_t Address = static_cast<uintX_t>(Data.getAddress(Cur)); 684fe6060f1SDimitry Andric uint32_t NumBlocks = ReadULEB128AsUInt32(); 685349cc55cSDimitry Andric std::vector<BBAddrMap::BBEntry> BBEntries; 68681ad6265SDimitry Andric uint32_t PrevBBEndOffset = 0; 687*bdd1243dSDimitry Andric for (uint32_t BlockIndex = 0; 688*bdd1243dSDimitry Andric !ULEBSizeErr && Cur && (BlockIndex < NumBlocks); ++BlockIndex) { 689*bdd1243dSDimitry Andric uint32_t ID = Version >= 2 ? ReadULEB128AsUInt32() : BlockIndex; 690fe6060f1SDimitry Andric uint32_t Offset = ReadULEB128AsUInt32(); 691fe6060f1SDimitry Andric uint32_t Size = ReadULEB128AsUInt32(); 692fe6060f1SDimitry Andric uint32_t Metadata = ReadULEB128AsUInt32(); 69381ad6265SDimitry Andric if (Version >= 1) { 69481ad6265SDimitry Andric // Offset is calculated relative to the end of the previous BB. 69581ad6265SDimitry Andric Offset += PrevBBEndOffset; 69681ad6265SDimitry Andric PrevBBEndOffset = Offset + Size; 69781ad6265SDimitry Andric } 698*bdd1243dSDimitry Andric BBEntries.push_back({ID, Offset, Size, Metadata}); 699fe6060f1SDimitry Andric } 70081ad6265SDimitry Andric FunctionEntries.push_back({Address, std::move(BBEntries)}); 701fe6060f1SDimitry Andric } 702fe6060f1SDimitry Andric // Either Cur is in the error state, or ULEBSizeError is set (not both), but 703fe6060f1SDimitry Andric // we join the two errors here to be safe. 704fe6060f1SDimitry Andric if (!Cur || ULEBSizeErr) 705fe6060f1SDimitry Andric return joinErrors(Cur.takeError(), std::move(ULEBSizeErr)); 706fe6060f1SDimitry Andric return FunctionEntries; 707fe6060f1SDimitry Andric } 708fe6060f1SDimitry Andric 7090b57cec5SDimitry Andric template class llvm::object::ELFFile<ELF32LE>; 7100b57cec5SDimitry Andric template class llvm::object::ELFFile<ELF32BE>; 7110b57cec5SDimitry Andric template class llvm::object::ELFFile<ELF64LE>; 7120b57cec5SDimitry Andric template class llvm::object::ELFFile<ELF64BE>; 713