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" 1006c3fb27SDimitry Andric #include "llvm/ADT/StringExtras.h" 110b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELF.h" 12fe6060f1SDimitry Andric #include "llvm/Support/DataExtractor.h" 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric using namespace llvm; 150b57cec5SDimitry Andric using namespace object; 160b57cec5SDimitry Andric 170b57cec5SDimitry Andric #define STRINGIFY_ENUM_CASE(ns, name) \ 180b57cec5SDimitry Andric case ns::name: \ 190b57cec5SDimitry Andric return #name; 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric #define ELF_RELOC(name, value) STRINGIFY_ENUM_CASE(ELF, name) 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric StringRef llvm::object::getELFRelocationTypeName(uint32_t Machine, 240b57cec5SDimitry Andric uint32_t Type) { 250b57cec5SDimitry Andric switch (Machine) { 26fe6060f1SDimitry Andric case ELF::EM_68K: 27fe6060f1SDimitry Andric switch (Type) { 28fe6060f1SDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/M68k.def" 29fe6060f1SDimitry Andric default: 30fe6060f1SDimitry Andric break; 31fe6060f1SDimitry Andric } 32fe6060f1SDimitry Andric break; 330b57cec5SDimitry Andric case ELF::EM_X86_64: 340b57cec5SDimitry Andric switch (Type) { 350b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/x86_64.def" 360b57cec5SDimitry Andric default: 370b57cec5SDimitry Andric break; 380b57cec5SDimitry Andric } 390b57cec5SDimitry Andric break; 400b57cec5SDimitry Andric case ELF::EM_386: 410b57cec5SDimitry Andric case ELF::EM_IAMCU: 420b57cec5SDimitry Andric switch (Type) { 430b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/i386.def" 440b57cec5SDimitry Andric default: 450b57cec5SDimitry Andric break; 460b57cec5SDimitry Andric } 470b57cec5SDimitry Andric break; 480b57cec5SDimitry Andric case ELF::EM_MIPS: 490b57cec5SDimitry Andric switch (Type) { 500b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/Mips.def" 510b57cec5SDimitry Andric default: 520b57cec5SDimitry Andric break; 530b57cec5SDimitry Andric } 540b57cec5SDimitry Andric break; 550b57cec5SDimitry Andric case ELF::EM_AARCH64: 560b57cec5SDimitry Andric switch (Type) { 570b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/AArch64.def" 580b57cec5SDimitry Andric default: 590b57cec5SDimitry Andric break; 600b57cec5SDimitry Andric } 610b57cec5SDimitry Andric break; 620b57cec5SDimitry Andric case ELF::EM_ARM: 630b57cec5SDimitry Andric switch (Type) { 640b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/ARM.def" 650b57cec5SDimitry Andric default: 660b57cec5SDimitry Andric break; 670b57cec5SDimitry Andric } 680b57cec5SDimitry Andric break; 690b57cec5SDimitry Andric case ELF::EM_ARC_COMPACT: 700b57cec5SDimitry Andric case ELF::EM_ARC_COMPACT2: 710b57cec5SDimitry Andric switch (Type) { 720b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/ARC.def" 730b57cec5SDimitry Andric default: 740b57cec5SDimitry Andric break; 750b57cec5SDimitry Andric } 760b57cec5SDimitry Andric break; 770b57cec5SDimitry Andric case ELF::EM_AVR: 780b57cec5SDimitry Andric switch (Type) { 790b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/AVR.def" 800b57cec5SDimitry Andric default: 810b57cec5SDimitry Andric break; 820b57cec5SDimitry Andric } 830b57cec5SDimitry Andric break; 840b57cec5SDimitry Andric case ELF::EM_HEXAGON: 850b57cec5SDimitry Andric switch (Type) { 860b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/Hexagon.def" 870b57cec5SDimitry Andric default: 880b57cec5SDimitry Andric break; 890b57cec5SDimitry Andric } 900b57cec5SDimitry Andric break; 910b57cec5SDimitry Andric case ELF::EM_LANAI: 920b57cec5SDimitry Andric switch (Type) { 930b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/Lanai.def" 940b57cec5SDimitry Andric default: 950b57cec5SDimitry Andric break; 960b57cec5SDimitry Andric } 970b57cec5SDimitry Andric break; 980b57cec5SDimitry Andric case ELF::EM_PPC: 990b57cec5SDimitry Andric switch (Type) { 1000b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/PowerPC.def" 1010b57cec5SDimitry Andric default: 1020b57cec5SDimitry Andric break; 1030b57cec5SDimitry Andric } 1040b57cec5SDimitry Andric break; 1050b57cec5SDimitry Andric case ELF::EM_PPC64: 1060b57cec5SDimitry Andric switch (Type) { 1070b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/PowerPC64.def" 1080b57cec5SDimitry Andric default: 1090b57cec5SDimitry Andric break; 1100b57cec5SDimitry Andric } 1110b57cec5SDimitry Andric break; 1120b57cec5SDimitry Andric case ELF::EM_RISCV: 1130b57cec5SDimitry Andric switch (Type) { 1140b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/RISCV.def" 1150b57cec5SDimitry Andric default: 1160b57cec5SDimitry Andric break; 1170b57cec5SDimitry Andric } 1180b57cec5SDimitry Andric break; 1190b57cec5SDimitry Andric case ELF::EM_S390: 1200b57cec5SDimitry Andric switch (Type) { 1210b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/SystemZ.def" 1220b57cec5SDimitry Andric default: 1230b57cec5SDimitry Andric break; 1240b57cec5SDimitry Andric } 1250b57cec5SDimitry Andric break; 1260b57cec5SDimitry Andric case ELF::EM_SPARC: 1270b57cec5SDimitry Andric case ELF::EM_SPARC32PLUS: 1280b57cec5SDimitry Andric case ELF::EM_SPARCV9: 1290b57cec5SDimitry Andric switch (Type) { 1300b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/Sparc.def" 1310b57cec5SDimitry Andric default: 1320b57cec5SDimitry Andric break; 1330b57cec5SDimitry Andric } 1340b57cec5SDimitry Andric break; 1350b57cec5SDimitry Andric case ELF::EM_AMDGPU: 1360b57cec5SDimitry Andric switch (Type) { 1370b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/AMDGPU.def" 1380b57cec5SDimitry Andric default: 1390b57cec5SDimitry Andric break; 1400b57cec5SDimitry Andric } 1410b57cec5SDimitry Andric break; 1420b57cec5SDimitry Andric case ELF::EM_BPF: 1430b57cec5SDimitry Andric switch (Type) { 1440b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/BPF.def" 1450b57cec5SDimitry Andric default: 1460b57cec5SDimitry Andric break; 1470b57cec5SDimitry Andric } 1480b57cec5SDimitry Andric break; 1490b57cec5SDimitry Andric case ELF::EM_MSP430: 1500b57cec5SDimitry Andric switch (Type) { 1510b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/MSP430.def" 1520b57cec5SDimitry Andric default: 1530b57cec5SDimitry Andric break; 1540b57cec5SDimitry Andric } 1550b57cec5SDimitry Andric break; 1565ffd83dbSDimitry Andric case ELF::EM_VE: 1575ffd83dbSDimitry Andric switch (Type) { 1585ffd83dbSDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/VE.def" 1595ffd83dbSDimitry Andric default: 1605ffd83dbSDimitry Andric break; 1615ffd83dbSDimitry Andric } 1625ffd83dbSDimitry Andric break; 163e8d8bef9SDimitry Andric case ELF::EM_CSKY: 164e8d8bef9SDimitry Andric switch (Type) { 165e8d8bef9SDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/CSKY.def" 166e8d8bef9SDimitry Andric default: 167e8d8bef9SDimitry Andric break; 168e8d8bef9SDimitry Andric } 169e8d8bef9SDimitry Andric break; 17081ad6265SDimitry Andric case ELF::EM_LOONGARCH: 17181ad6265SDimitry Andric switch (Type) { 17281ad6265SDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/LoongArch.def" 17381ad6265SDimitry Andric default: 17481ad6265SDimitry Andric break; 17581ad6265SDimitry Andric } 17681ad6265SDimitry Andric break; 177bdd1243dSDimitry Andric case ELF::EM_XTENSA: 178bdd1243dSDimitry Andric switch (Type) { 179bdd1243dSDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/Xtensa.def" 180bdd1243dSDimitry Andric default: 181bdd1243dSDimitry Andric break; 182bdd1243dSDimitry Andric } 183bdd1243dSDimitry Andric break; 1840b57cec5SDimitry Andric default: 1850b57cec5SDimitry Andric break; 1860b57cec5SDimitry Andric } 1870b57cec5SDimitry Andric return "Unknown"; 1880b57cec5SDimitry Andric } 1890b57cec5SDimitry Andric 1900b57cec5SDimitry Andric #undef ELF_RELOC 1910b57cec5SDimitry Andric 1920b57cec5SDimitry Andric uint32_t llvm::object::getELFRelativeRelocationType(uint32_t Machine) { 1930b57cec5SDimitry Andric switch (Machine) { 1940b57cec5SDimitry Andric case ELF::EM_X86_64: 1950b57cec5SDimitry Andric return ELF::R_X86_64_RELATIVE; 1960b57cec5SDimitry Andric case ELF::EM_386: 1970b57cec5SDimitry Andric case ELF::EM_IAMCU: 1980b57cec5SDimitry Andric return ELF::R_386_RELATIVE; 1990b57cec5SDimitry Andric case ELF::EM_MIPS: 2000b57cec5SDimitry Andric break; 2010b57cec5SDimitry Andric case ELF::EM_AARCH64: 2020b57cec5SDimitry Andric return ELF::R_AARCH64_RELATIVE; 2030b57cec5SDimitry Andric case ELF::EM_ARM: 2040b57cec5SDimitry Andric return ELF::R_ARM_RELATIVE; 2050b57cec5SDimitry Andric case ELF::EM_ARC_COMPACT: 2060b57cec5SDimitry Andric case ELF::EM_ARC_COMPACT2: 2070b57cec5SDimitry Andric return ELF::R_ARC_RELATIVE; 2080b57cec5SDimitry Andric case ELF::EM_AVR: 2090b57cec5SDimitry Andric break; 2100b57cec5SDimitry Andric case ELF::EM_HEXAGON: 2110b57cec5SDimitry Andric return ELF::R_HEX_RELATIVE; 2120b57cec5SDimitry Andric case ELF::EM_LANAI: 2130b57cec5SDimitry Andric break; 2140b57cec5SDimitry Andric case ELF::EM_PPC: 2150b57cec5SDimitry Andric break; 2160b57cec5SDimitry Andric case ELF::EM_PPC64: 2170b57cec5SDimitry Andric return ELF::R_PPC64_RELATIVE; 2180b57cec5SDimitry Andric case ELF::EM_RISCV: 2190b57cec5SDimitry Andric return ELF::R_RISCV_RELATIVE; 2200b57cec5SDimitry Andric case ELF::EM_S390: 2210b57cec5SDimitry Andric return ELF::R_390_RELATIVE; 2220b57cec5SDimitry Andric case ELF::EM_SPARC: 2230b57cec5SDimitry Andric case ELF::EM_SPARC32PLUS: 2240b57cec5SDimitry Andric case ELF::EM_SPARCV9: 2250b57cec5SDimitry Andric return ELF::R_SPARC_RELATIVE; 226e8d8bef9SDimitry Andric case ELF::EM_CSKY: 227e8d8bef9SDimitry Andric return ELF::R_CKCORE_RELATIVE; 2280eae32dcSDimitry Andric case ELF::EM_VE: 2290eae32dcSDimitry Andric return ELF::R_VE_RELATIVE; 2300b57cec5SDimitry Andric case ELF::EM_AMDGPU: 2310b57cec5SDimitry Andric break; 2320b57cec5SDimitry Andric case ELF::EM_BPF: 2330b57cec5SDimitry Andric break; 234bdd1243dSDimitry Andric case ELF::EM_LOONGARCH: 235bdd1243dSDimitry Andric return ELF::R_LARCH_RELATIVE; 2360b57cec5SDimitry Andric default: 2370b57cec5SDimitry Andric break; 2380b57cec5SDimitry Andric } 2390b57cec5SDimitry Andric return 0; 2400b57cec5SDimitry Andric } 2410b57cec5SDimitry Andric 2420b57cec5SDimitry Andric StringRef llvm::object::getELFSectionTypeName(uint32_t Machine, unsigned Type) { 2430b57cec5SDimitry Andric switch (Machine) { 2440b57cec5SDimitry Andric case ELF::EM_ARM: 2450b57cec5SDimitry Andric switch (Type) { 2460b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_ARM_EXIDX); 2470b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_ARM_PREEMPTMAP); 2480b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_ARM_ATTRIBUTES); 2490b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_ARM_DEBUGOVERLAY); 2500b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_ARM_OVERLAYSECTION); 2510b57cec5SDimitry Andric } 2520b57cec5SDimitry Andric break; 2530b57cec5SDimitry Andric case ELF::EM_HEXAGON: 254*0fca6ea1SDimitry Andric switch (Type) { 255*0fca6ea1SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_HEX_ORDERED); 256*0fca6ea1SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_HEXAGON_ATTRIBUTES); 257*0fca6ea1SDimitry Andric } 2580b57cec5SDimitry Andric break; 2590b57cec5SDimitry Andric case ELF::EM_X86_64: 2600b57cec5SDimitry Andric switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_X86_64_UNWIND); } 2610b57cec5SDimitry Andric break; 2620b57cec5SDimitry Andric case ELF::EM_MIPS: 2630b57cec5SDimitry Andric case ELF::EM_MIPS_RS3_LE: 2640b57cec5SDimitry Andric switch (Type) { 2650b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_REGINFO); 2660b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_OPTIONS); 2670b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_DWARF); 2680b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_ABIFLAGS); 2690b57cec5SDimitry Andric } 2700b57cec5SDimitry Andric break; 271349cc55cSDimitry Andric case ELF::EM_MSP430: 272349cc55cSDimitry Andric switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_MSP430_ATTRIBUTES); } 273349cc55cSDimitry Andric break; 2745ffd83dbSDimitry Andric case ELF::EM_RISCV: 2755ffd83dbSDimitry Andric switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_RISCV_ATTRIBUTES); } 2765ffd83dbSDimitry Andric break; 27706c3fb27SDimitry Andric case ELF::EM_AARCH64: 27806c3fb27SDimitry Andric switch (Type) { 2795f757f3fSDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_AARCH64_AUTH_RELR); 28006c3fb27SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_AARCH64_MEMTAG_GLOBALS_DYNAMIC); 28106c3fb27SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_AARCH64_MEMTAG_GLOBALS_STATIC); 28206c3fb27SDimitry Andric } 2830b57cec5SDimitry Andric default: 2840b57cec5SDimitry Andric break; 2850b57cec5SDimitry Andric } 2860b57cec5SDimitry Andric 2870b57cec5SDimitry Andric switch (Type) { 2880b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_NULL); 2890b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_PROGBITS); 2900b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_SYMTAB); 2910b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_STRTAB); 2920b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_RELA); 2930b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_HASH); 2940b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_DYNAMIC); 2950b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_NOTE); 2960b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_NOBITS); 2970b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_REL); 2980b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_SHLIB); 2990b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_DYNSYM); 3000b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_INIT_ARRAY); 3010b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_FINI_ARRAY); 3020b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_PREINIT_ARRAY); 3030b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_GROUP); 3040b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_SYMTAB_SHNDX); 3050b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_RELR); 306*0fca6ea1SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_CREL); 3070b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_REL); 3080b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_RELA); 3090b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_RELR); 3100b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_ODRTAB); 3110b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_LINKER_OPTIONS); 3120b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_CALL_GRAPH_PROFILE); 3130b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_ADDRSIG); 3140b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_DEPENDENT_LIBRARIES); 3150b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_SYMPART); 3168bcb0991SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_PART_EHDR); 3178bcb0991SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_PART_PHDR); 31881ad6265SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_BB_ADDR_MAP_V0); 319e8d8bef9SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_BB_ADDR_MAP); 320753f127fSDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_OFFLOADING); 32106c3fb27SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_LTO); 3220b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_GNU_ATTRIBUTES); 3230b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_GNU_HASH); 3240b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_GNU_verdef); 3250b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_GNU_verneed); 3260b57cec5SDimitry Andric STRINGIFY_ENUM_CASE(ELF, SHT_GNU_versym); 3270b57cec5SDimitry Andric default: 3280b57cec5SDimitry Andric return "Unknown"; 3290b57cec5SDimitry Andric } 3300b57cec5SDimitry Andric } 3310b57cec5SDimitry Andric 3320b57cec5SDimitry Andric template <class ELFT> 333e8d8bef9SDimitry Andric std::vector<typename ELFT::Rel> 3340b57cec5SDimitry Andric ELFFile<ELFT>::decode_relrs(Elf_Relr_Range relrs) const { 3350b57cec5SDimitry Andric // This function decodes the contents of an SHT_RELR packed relocation 3360b57cec5SDimitry Andric // section. 3370b57cec5SDimitry Andric // 3380b57cec5SDimitry Andric // Proposal for adding SHT_RELR sections to generic-abi is here: 3390b57cec5SDimitry Andric // https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg 3400b57cec5SDimitry Andric // 3410b57cec5SDimitry Andric // The encoded sequence of Elf64_Relr entries in a SHT_RELR section looks 3420b57cec5SDimitry Andric // like [ AAAAAAAA BBBBBBB1 BBBBBBB1 ... AAAAAAAA BBBBBB1 ... ] 3430b57cec5SDimitry Andric // 3440b57cec5SDimitry Andric // i.e. start with an address, followed by any number of bitmaps. The address 3450b57cec5SDimitry Andric // entry encodes 1 relocation. The subsequent bitmap entries encode up to 63 3460b57cec5SDimitry Andric // relocations each, at subsequent offsets following the last address entry. 3470b57cec5SDimitry Andric // 3480b57cec5SDimitry Andric // The bitmap entries must have 1 in the least significant bit. The assumption 3490b57cec5SDimitry Andric // here is that an address cannot have 1 in lsb. Odd addresses are not 3500b57cec5SDimitry Andric // supported. 3510b57cec5SDimitry Andric // 3520b57cec5SDimitry Andric // Excluding the least significant bit in the bitmap, each non-zero bit in 3530b57cec5SDimitry Andric // the bitmap represents a relocation to be applied to a corresponding machine 3540b57cec5SDimitry Andric // word that follows the base address word. The second least significant bit 3550b57cec5SDimitry Andric // represents the machine word immediately following the initial address, and 3560b57cec5SDimitry Andric // each bit that follows represents the next word, in linear order. As such, 3570b57cec5SDimitry Andric // a single bitmap can encode up to 31 relocations in a 32-bit object, and 3580b57cec5SDimitry Andric // 63 relocations in a 64-bit object. 3590b57cec5SDimitry Andric // 3600b57cec5SDimitry Andric // This encoding has a couple of interesting properties: 3610b57cec5SDimitry Andric // 1. Looking at any entry, it is clear whether it's an address or a bitmap: 3620b57cec5SDimitry Andric // even means address, odd means bitmap. 3630b57cec5SDimitry Andric // 2. Just a simple list of addresses is a valid encoding. 3640b57cec5SDimitry Andric 365e8d8bef9SDimitry Andric Elf_Rel Rel; 366e8d8bef9SDimitry Andric Rel.r_info = 0; 367e8d8bef9SDimitry Andric Rel.setType(getRelativeRelocationType(), false); 368e8d8bef9SDimitry Andric std::vector<Elf_Rel> Relocs; 3690b57cec5SDimitry Andric 3700b57cec5SDimitry Andric // Word type: uint32_t for Elf32, and uint64_t for Elf64. 371349cc55cSDimitry Andric using Addr = typename ELFT::uint; 3720b57cec5SDimitry Andric 373349cc55cSDimitry Andric Addr Base = 0; 374349cc55cSDimitry Andric for (Elf_Relr R : relrs) { 375349cc55cSDimitry Andric typename ELFT::uint Entry = R; 3760b57cec5SDimitry Andric if ((Entry & 1) == 0) { 3770b57cec5SDimitry Andric // Even entry: encodes the offset for next relocation. 378e8d8bef9SDimitry Andric Rel.r_offset = Entry; 379e8d8bef9SDimitry Andric Relocs.push_back(Rel); 3800b57cec5SDimitry Andric // Set base offset for subsequent bitmap entries. 381349cc55cSDimitry Andric Base = Entry + sizeof(Addr); 382349cc55cSDimitry Andric } else { 3830b57cec5SDimitry Andric // Odd entry: encodes bitmap for relocations starting at base. 384349cc55cSDimitry Andric for (Addr Offset = Base; (Entry >>= 1) != 0; Offset += sizeof(Addr)) 3850b57cec5SDimitry Andric if ((Entry & 1) != 0) { 386e8d8bef9SDimitry Andric Rel.r_offset = Offset; 387e8d8bef9SDimitry Andric Relocs.push_back(Rel); 3880b57cec5SDimitry Andric } 389349cc55cSDimitry Andric Base += (CHAR_BIT * sizeof(Entry) - 1) * sizeof(Addr); 3900b57cec5SDimitry Andric } 3910b57cec5SDimitry Andric } 3920b57cec5SDimitry Andric 3930b57cec5SDimitry Andric return Relocs; 3940b57cec5SDimitry Andric } 3950b57cec5SDimitry Andric 3960b57cec5SDimitry Andric template <class ELFT> 397*0fca6ea1SDimitry Andric Expected<uint64_t> 398*0fca6ea1SDimitry Andric ELFFile<ELFT>::getCrelHeader(ArrayRef<uint8_t> Content) const { 399*0fca6ea1SDimitry Andric DataExtractor Data(Content, isLE(), sizeof(typename ELFT::Addr)); 400*0fca6ea1SDimitry Andric Error Err = Error::success(); 401*0fca6ea1SDimitry Andric uint64_t Hdr = 0; 402*0fca6ea1SDimitry Andric Hdr = Data.getULEB128(&Hdr, &Err); 403*0fca6ea1SDimitry Andric if (Err) 404*0fca6ea1SDimitry Andric return Err; 405*0fca6ea1SDimitry Andric return Hdr; 406*0fca6ea1SDimitry Andric } 407*0fca6ea1SDimitry Andric 408*0fca6ea1SDimitry Andric template <class ELFT> 409*0fca6ea1SDimitry Andric Expected<typename ELFFile<ELFT>::RelsOrRelas> 410*0fca6ea1SDimitry Andric ELFFile<ELFT>::decodeCrel(ArrayRef<uint8_t> Content) const { 411*0fca6ea1SDimitry Andric std::vector<Elf_Rel> Rels; 412*0fca6ea1SDimitry Andric std::vector<Elf_Rela> Relas; 413*0fca6ea1SDimitry Andric size_t I = 0; 414*0fca6ea1SDimitry Andric bool HasAddend; 415*0fca6ea1SDimitry Andric Error Err = object::decodeCrel<ELFT::Is64Bits>( 416*0fca6ea1SDimitry Andric Content, 417*0fca6ea1SDimitry Andric [&](uint64_t Count, bool HasA) { 418*0fca6ea1SDimitry Andric HasAddend = HasA; 419*0fca6ea1SDimitry Andric if (HasAddend) 420*0fca6ea1SDimitry Andric Relas.resize(Count); 421*0fca6ea1SDimitry Andric else 422*0fca6ea1SDimitry Andric Rels.resize(Count); 423*0fca6ea1SDimitry Andric }, 424*0fca6ea1SDimitry Andric [&](Elf_Crel Crel) { 425*0fca6ea1SDimitry Andric if (HasAddend) { 426*0fca6ea1SDimitry Andric Relas[I].r_offset = Crel.r_offset; 427*0fca6ea1SDimitry Andric Relas[I].setSymbolAndType(Crel.r_symidx, Crel.r_type, false); 428*0fca6ea1SDimitry Andric Relas[I++].r_addend = Crel.r_addend; 429*0fca6ea1SDimitry Andric } else { 430*0fca6ea1SDimitry Andric Rels[I].r_offset = Crel.r_offset; 431*0fca6ea1SDimitry Andric Rels[I++].setSymbolAndType(Crel.r_symidx, Crel.r_type, false); 432*0fca6ea1SDimitry Andric } 433*0fca6ea1SDimitry Andric }); 434*0fca6ea1SDimitry Andric if (Err) 435*0fca6ea1SDimitry Andric return std::move(Err); 436*0fca6ea1SDimitry Andric return std::make_pair(std::move(Rels), std::move(Relas)); 437*0fca6ea1SDimitry Andric } 438*0fca6ea1SDimitry Andric 439*0fca6ea1SDimitry Andric template <class ELFT> 440*0fca6ea1SDimitry Andric Expected<typename ELFFile<ELFT>::RelsOrRelas> 441*0fca6ea1SDimitry Andric ELFFile<ELFT>::crels(const Elf_Shdr &Sec) const { 442*0fca6ea1SDimitry Andric Expected<ArrayRef<uint8_t>> ContentsOrErr = getSectionContents(Sec); 443*0fca6ea1SDimitry Andric if (!ContentsOrErr) 444*0fca6ea1SDimitry Andric return ContentsOrErr.takeError(); 445*0fca6ea1SDimitry Andric return decodeCrel(*ContentsOrErr); 446*0fca6ea1SDimitry Andric } 447*0fca6ea1SDimitry Andric 448*0fca6ea1SDimitry Andric template <class ELFT> 4490b57cec5SDimitry Andric Expected<std::vector<typename ELFT::Rela>> 450e8d8bef9SDimitry Andric ELFFile<ELFT>::android_relas(const Elf_Shdr &Sec) const { 4510b57cec5SDimitry Andric // This function reads relocations in Android's packed relocation format, 4520b57cec5SDimitry Andric // which is based on SLEB128 and delta encoding. 4530b57cec5SDimitry Andric Expected<ArrayRef<uint8_t>> ContentsOrErr = getSectionContents(Sec); 4540b57cec5SDimitry Andric if (!ContentsOrErr) 4550b57cec5SDimitry Andric return ContentsOrErr.takeError(); 456fe6060f1SDimitry Andric ArrayRef<uint8_t> Content = *ContentsOrErr; 457fe6060f1SDimitry Andric if (Content.size() < 4 || Content[0] != 'A' || Content[1] != 'P' || 458fe6060f1SDimitry Andric Content[2] != 'S' || Content[3] != '2') 4590b57cec5SDimitry Andric return createError("invalid packed relocation header"); 460fe6060f1SDimitry Andric DataExtractor Data(Content, isLE(), ELFT::Is64Bits ? 8 : 4); 461fe6060f1SDimitry Andric DataExtractor::Cursor Cur(/*Offset=*/4); 4620b57cec5SDimitry Andric 463fe6060f1SDimitry Andric uint64_t NumRelocs = Data.getSLEB128(Cur); 464fe6060f1SDimitry Andric uint64_t Offset = Data.getSLEB128(Cur); 4650b57cec5SDimitry Andric uint64_t Addend = 0; 4660b57cec5SDimitry Andric 467fe6060f1SDimitry Andric if (!Cur) 468fe6060f1SDimitry Andric return std::move(Cur.takeError()); 4690b57cec5SDimitry Andric 4700b57cec5SDimitry Andric std::vector<Elf_Rela> Relocs; 4710b57cec5SDimitry Andric Relocs.reserve(NumRelocs); 4720b57cec5SDimitry Andric while (NumRelocs) { 473fe6060f1SDimitry Andric uint64_t NumRelocsInGroup = Data.getSLEB128(Cur); 474fe6060f1SDimitry Andric if (!Cur) 475fe6060f1SDimitry Andric return std::move(Cur.takeError()); 4760b57cec5SDimitry Andric if (NumRelocsInGroup > NumRelocs) 4770b57cec5SDimitry Andric return createError("relocation group unexpectedly large"); 4780b57cec5SDimitry Andric NumRelocs -= NumRelocsInGroup; 4790b57cec5SDimitry Andric 480fe6060f1SDimitry Andric uint64_t GroupFlags = Data.getSLEB128(Cur); 4810b57cec5SDimitry Andric bool GroupedByInfo = GroupFlags & ELF::RELOCATION_GROUPED_BY_INFO_FLAG; 4820b57cec5SDimitry Andric bool GroupedByOffsetDelta = GroupFlags & ELF::RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG; 4830b57cec5SDimitry Andric bool GroupedByAddend = GroupFlags & ELF::RELOCATION_GROUPED_BY_ADDEND_FLAG; 4840b57cec5SDimitry Andric bool GroupHasAddend = GroupFlags & ELF::RELOCATION_GROUP_HAS_ADDEND_FLAG; 4850b57cec5SDimitry Andric 4860b57cec5SDimitry Andric uint64_t GroupOffsetDelta; 4870b57cec5SDimitry Andric if (GroupedByOffsetDelta) 488fe6060f1SDimitry Andric GroupOffsetDelta = Data.getSLEB128(Cur); 4890b57cec5SDimitry Andric 4900b57cec5SDimitry Andric uint64_t GroupRInfo; 4910b57cec5SDimitry Andric if (GroupedByInfo) 492fe6060f1SDimitry Andric GroupRInfo = Data.getSLEB128(Cur); 4930b57cec5SDimitry Andric 4940b57cec5SDimitry Andric if (GroupedByAddend && GroupHasAddend) 495fe6060f1SDimitry Andric Addend += Data.getSLEB128(Cur); 4960b57cec5SDimitry Andric 4970b57cec5SDimitry Andric if (!GroupHasAddend) 4980b57cec5SDimitry Andric Addend = 0; 4990b57cec5SDimitry Andric 500fe6060f1SDimitry Andric for (uint64_t I = 0; Cur && I != NumRelocsInGroup; ++I) { 5010b57cec5SDimitry Andric Elf_Rela R; 502fe6060f1SDimitry Andric Offset += GroupedByOffsetDelta ? GroupOffsetDelta : Data.getSLEB128(Cur); 5030b57cec5SDimitry Andric R.r_offset = Offset; 504fe6060f1SDimitry Andric R.r_info = GroupedByInfo ? GroupRInfo : Data.getSLEB128(Cur); 5050b57cec5SDimitry Andric if (GroupHasAddend && !GroupedByAddend) 506fe6060f1SDimitry Andric Addend += Data.getSLEB128(Cur); 5070b57cec5SDimitry Andric R.r_addend = Addend; 5080b57cec5SDimitry Andric Relocs.push_back(R); 5090b57cec5SDimitry Andric } 510fe6060f1SDimitry Andric if (!Cur) 511fe6060f1SDimitry Andric return std::move(Cur.takeError()); 5120b57cec5SDimitry Andric } 5130b57cec5SDimitry Andric 5140b57cec5SDimitry Andric return Relocs; 5150b57cec5SDimitry Andric } 5160b57cec5SDimitry Andric 5170b57cec5SDimitry Andric template <class ELFT> 5180b57cec5SDimitry Andric std::string ELFFile<ELFT>::getDynamicTagAsString(unsigned Arch, 5190b57cec5SDimitry Andric uint64_t Type) const { 5200b57cec5SDimitry Andric #define DYNAMIC_STRINGIFY_ENUM(tag, value) \ 5210b57cec5SDimitry Andric case value: \ 5220b57cec5SDimitry Andric return #tag; 5230b57cec5SDimitry Andric 5240b57cec5SDimitry Andric #define DYNAMIC_TAG(n, v) 5250b57cec5SDimitry Andric switch (Arch) { 5260b57cec5SDimitry Andric case ELF::EM_AARCH64: 5270b57cec5SDimitry Andric switch (Type) { 5280b57cec5SDimitry Andric #define AARCH64_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value) 5290b57cec5SDimitry Andric #include "llvm/BinaryFormat/DynamicTags.def" 5300b57cec5SDimitry Andric #undef AARCH64_DYNAMIC_TAG 5310b57cec5SDimitry Andric } 5320b57cec5SDimitry Andric break; 5330b57cec5SDimitry Andric 5340b57cec5SDimitry Andric case ELF::EM_HEXAGON: 5350b57cec5SDimitry Andric switch (Type) { 5360b57cec5SDimitry Andric #define HEXAGON_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value) 5370b57cec5SDimitry Andric #include "llvm/BinaryFormat/DynamicTags.def" 5380b57cec5SDimitry Andric #undef HEXAGON_DYNAMIC_TAG 5390b57cec5SDimitry Andric } 5400b57cec5SDimitry Andric break; 5410b57cec5SDimitry Andric 5420b57cec5SDimitry Andric case ELF::EM_MIPS: 5430b57cec5SDimitry Andric switch (Type) { 5440b57cec5SDimitry Andric #define MIPS_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value) 5450b57cec5SDimitry Andric #include "llvm/BinaryFormat/DynamicTags.def" 5460b57cec5SDimitry Andric #undef MIPS_DYNAMIC_TAG 5470b57cec5SDimitry Andric } 5480b57cec5SDimitry Andric break; 5490b57cec5SDimitry Andric 550349cc55cSDimitry Andric case ELF::EM_PPC: 551349cc55cSDimitry Andric switch (Type) { 552349cc55cSDimitry Andric #define PPC_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value) 553349cc55cSDimitry Andric #include "llvm/BinaryFormat/DynamicTags.def" 554349cc55cSDimitry Andric #undef PPC_DYNAMIC_TAG 555349cc55cSDimitry Andric } 556349cc55cSDimitry Andric break; 557349cc55cSDimitry Andric 5580b57cec5SDimitry Andric case ELF::EM_PPC64: 5590b57cec5SDimitry Andric switch (Type) { 5600b57cec5SDimitry Andric #define PPC64_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value) 5610b57cec5SDimitry Andric #include "llvm/BinaryFormat/DynamicTags.def" 5620b57cec5SDimitry Andric #undef PPC64_DYNAMIC_TAG 5630b57cec5SDimitry Andric } 5640b57cec5SDimitry Andric break; 565349cc55cSDimitry Andric 566349cc55cSDimitry Andric case ELF::EM_RISCV: 567349cc55cSDimitry Andric switch (Type) { 568349cc55cSDimitry Andric #define RISCV_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value) 569349cc55cSDimitry Andric #include "llvm/BinaryFormat/DynamicTags.def" 570349cc55cSDimitry Andric #undef RISCV_DYNAMIC_TAG 571349cc55cSDimitry Andric } 572349cc55cSDimitry Andric break; 5730b57cec5SDimitry Andric } 5740b57cec5SDimitry Andric #undef DYNAMIC_TAG 5750b57cec5SDimitry Andric switch (Type) { 5760b57cec5SDimitry Andric // Now handle all dynamic tags except the architecture specific ones 5770b57cec5SDimitry Andric #define AARCH64_DYNAMIC_TAG(name, value) 5780b57cec5SDimitry Andric #define MIPS_DYNAMIC_TAG(name, value) 5790b57cec5SDimitry Andric #define HEXAGON_DYNAMIC_TAG(name, value) 580349cc55cSDimitry Andric #define PPC_DYNAMIC_TAG(name, value) 5810b57cec5SDimitry Andric #define PPC64_DYNAMIC_TAG(name, value) 582349cc55cSDimitry Andric #define RISCV_DYNAMIC_TAG(name, value) 5830b57cec5SDimitry Andric // Also ignore marker tags such as DT_HIOS (maps to DT_VERNEEDNUM), etc. 5840b57cec5SDimitry Andric #define DYNAMIC_TAG_MARKER(name, value) 585480093f4SDimitry Andric #define DYNAMIC_TAG(name, value) case value: return #name; 5860b57cec5SDimitry Andric #include "llvm/BinaryFormat/DynamicTags.def" 5870b57cec5SDimitry Andric #undef DYNAMIC_TAG 5880b57cec5SDimitry Andric #undef AARCH64_DYNAMIC_TAG 5890b57cec5SDimitry Andric #undef MIPS_DYNAMIC_TAG 5900b57cec5SDimitry Andric #undef HEXAGON_DYNAMIC_TAG 591349cc55cSDimitry Andric #undef PPC_DYNAMIC_TAG 5920b57cec5SDimitry Andric #undef PPC64_DYNAMIC_TAG 593349cc55cSDimitry Andric #undef RISCV_DYNAMIC_TAG 5940b57cec5SDimitry Andric #undef DYNAMIC_TAG_MARKER 5950b57cec5SDimitry Andric #undef DYNAMIC_STRINGIFY_ENUM 5960b57cec5SDimitry Andric default: 5970b57cec5SDimitry Andric return "<unknown:>0x" + utohexstr(Type, true); 5980b57cec5SDimitry Andric } 5990b57cec5SDimitry Andric } 6000b57cec5SDimitry Andric 6010b57cec5SDimitry Andric template <class ELFT> 6020b57cec5SDimitry Andric std::string ELFFile<ELFT>::getDynamicTagAsString(uint64_t Type) const { 603e8d8bef9SDimitry Andric return getDynamicTagAsString(getHeader().e_machine, Type); 6040b57cec5SDimitry Andric } 6050b57cec5SDimitry Andric 6060b57cec5SDimitry Andric template <class ELFT> 6070b57cec5SDimitry Andric Expected<typename ELFT::DynRange> ELFFile<ELFT>::dynamicEntries() const { 6080b57cec5SDimitry Andric ArrayRef<Elf_Dyn> Dyn; 6090b57cec5SDimitry Andric 6100b57cec5SDimitry Andric auto ProgramHeadersOrError = program_headers(); 6110b57cec5SDimitry Andric if (!ProgramHeadersOrError) 6120b57cec5SDimitry Andric return ProgramHeadersOrError.takeError(); 6130b57cec5SDimitry Andric 6140b57cec5SDimitry Andric for (const Elf_Phdr &Phdr : *ProgramHeadersOrError) { 6150b57cec5SDimitry Andric if (Phdr.p_type == ELF::PT_DYNAMIC) { 616*0fca6ea1SDimitry Andric const uint8_t *DynOffset = base() + Phdr.p_offset; 617*0fca6ea1SDimitry Andric if (DynOffset > end()) 618*0fca6ea1SDimitry Andric return createError( 619*0fca6ea1SDimitry Andric "dynamic section offset past file size: corrupted ELF"); 620*0fca6ea1SDimitry Andric Dyn = ArrayRef(reinterpret_cast<const Elf_Dyn *>(DynOffset), 6210b57cec5SDimitry Andric Phdr.p_filesz / sizeof(Elf_Dyn)); 6220b57cec5SDimitry Andric break; 6230b57cec5SDimitry Andric } 6240b57cec5SDimitry Andric } 6250b57cec5SDimitry Andric 6260b57cec5SDimitry Andric // If we can't find the dynamic section in the program headers, we just fall 6270b57cec5SDimitry Andric // back on the sections. 6280b57cec5SDimitry Andric if (Dyn.empty()) { 6290b57cec5SDimitry Andric auto SectionsOrError = sections(); 6300b57cec5SDimitry Andric if (!SectionsOrError) 6310b57cec5SDimitry Andric return SectionsOrError.takeError(); 6320b57cec5SDimitry Andric 6330b57cec5SDimitry Andric for (const Elf_Shdr &Sec : *SectionsOrError) { 6340b57cec5SDimitry Andric if (Sec.sh_type == ELF::SHT_DYNAMIC) { 6350b57cec5SDimitry Andric Expected<ArrayRef<Elf_Dyn>> DynOrError = 636e8d8bef9SDimitry Andric getSectionContentsAsArray<Elf_Dyn>(Sec); 6370b57cec5SDimitry Andric if (!DynOrError) 6380b57cec5SDimitry Andric return DynOrError.takeError(); 6390b57cec5SDimitry Andric Dyn = *DynOrError; 6400b57cec5SDimitry Andric break; 6410b57cec5SDimitry Andric } 6420b57cec5SDimitry Andric } 6430b57cec5SDimitry Andric 6440b57cec5SDimitry Andric if (!Dyn.data()) 6450b57cec5SDimitry Andric return ArrayRef<Elf_Dyn>(); 6460b57cec5SDimitry Andric } 6470b57cec5SDimitry Andric 6480b57cec5SDimitry Andric if (Dyn.empty()) 6490b57cec5SDimitry Andric return createError("invalid empty dynamic section"); 6500b57cec5SDimitry Andric 6510b57cec5SDimitry Andric if (Dyn.back().d_tag != ELF::DT_NULL) 6520b57cec5SDimitry Andric return createError("dynamic sections must be DT_NULL terminated"); 6530b57cec5SDimitry Andric 6540b57cec5SDimitry Andric return Dyn; 6550b57cec5SDimitry Andric } 6560b57cec5SDimitry Andric 6570b57cec5SDimitry Andric template <class ELFT> 658e8d8bef9SDimitry Andric Expected<const uint8_t *> 659e8d8bef9SDimitry Andric ELFFile<ELFT>::toMappedAddr(uint64_t VAddr, WarningHandler WarnHandler) const { 6600b57cec5SDimitry Andric auto ProgramHeadersOrError = program_headers(); 6610b57cec5SDimitry Andric if (!ProgramHeadersOrError) 6620b57cec5SDimitry Andric return ProgramHeadersOrError.takeError(); 6630b57cec5SDimitry Andric 6640b57cec5SDimitry Andric llvm::SmallVector<Elf_Phdr *, 4> LoadSegments; 6650b57cec5SDimitry Andric 6660b57cec5SDimitry Andric for (const Elf_Phdr &Phdr : *ProgramHeadersOrError) 6670b57cec5SDimitry Andric if (Phdr.p_type == ELF::PT_LOAD) 6680b57cec5SDimitry Andric LoadSegments.push_back(const_cast<Elf_Phdr *>(&Phdr)); 6690b57cec5SDimitry Andric 670e8d8bef9SDimitry Andric auto SortPred = [](const Elf_Phdr_Impl<ELFT> *A, 671e8d8bef9SDimitry Andric const Elf_Phdr_Impl<ELFT> *B) { 672e8d8bef9SDimitry Andric return A->p_vaddr < B->p_vaddr; 673e8d8bef9SDimitry Andric }; 674e8d8bef9SDimitry Andric if (!llvm::is_sorted(LoadSegments, SortPred)) { 675e8d8bef9SDimitry Andric if (Error E = 676e8d8bef9SDimitry Andric WarnHandler("loadable segments are unsorted by virtual address")) 677e8d8bef9SDimitry Andric return std::move(E); 678e8d8bef9SDimitry Andric llvm::stable_sort(LoadSegments, SortPred); 679e8d8bef9SDimitry Andric } 680e8d8bef9SDimitry Andric 681e8d8bef9SDimitry Andric const Elf_Phdr *const *I = llvm::upper_bound( 682e8d8bef9SDimitry Andric LoadSegments, VAddr, [](uint64_t VAddr, const Elf_Phdr_Impl<ELFT> *Phdr) { 6830b57cec5SDimitry Andric return VAddr < Phdr->p_vaddr; 6840b57cec5SDimitry Andric }); 6850b57cec5SDimitry Andric 6860b57cec5SDimitry Andric if (I == LoadSegments.begin()) 6870b57cec5SDimitry Andric return createError("virtual address is not in any segment: 0x" + 6880b57cec5SDimitry Andric Twine::utohexstr(VAddr)); 6890b57cec5SDimitry Andric --I; 6900b57cec5SDimitry Andric const Elf_Phdr &Phdr = **I; 6910b57cec5SDimitry Andric uint64_t Delta = VAddr - Phdr.p_vaddr; 6920b57cec5SDimitry Andric if (Delta >= Phdr.p_filesz) 6930b57cec5SDimitry Andric return createError("virtual address is not in any segment: 0x" + 6940b57cec5SDimitry Andric Twine::utohexstr(VAddr)); 6955ffd83dbSDimitry Andric 6965ffd83dbSDimitry Andric uint64_t Offset = Phdr.p_offset + Delta; 6975ffd83dbSDimitry Andric if (Offset >= getBufSize()) 6985ffd83dbSDimitry Andric return createError("can't map virtual address 0x" + 6995ffd83dbSDimitry Andric Twine::utohexstr(VAddr) + " to the segment with index " + 7005ffd83dbSDimitry Andric Twine(&Phdr - (*ProgramHeadersOrError).data() + 1) + 7015ffd83dbSDimitry Andric ": the segment ends at 0x" + 7025ffd83dbSDimitry Andric Twine::utohexstr(Phdr.p_offset + Phdr.p_filesz) + 7035ffd83dbSDimitry Andric ", which is greater than the file size (0x" + 7045ffd83dbSDimitry Andric Twine::utohexstr(getBufSize()) + ")"); 7055ffd83dbSDimitry Andric 7065ffd83dbSDimitry Andric return base() + Offset; 7070b57cec5SDimitry Andric } 7080b57cec5SDimitry Andric 7095f757f3fSDimitry Andric // Helper to extract and decode the next ULEB128 value as unsigned int. 7105f757f3fSDimitry Andric // Returns zero and sets ULEBSizeErr if the ULEB128 value exceeds the unsigned 7115f757f3fSDimitry Andric // int limit. 7125f757f3fSDimitry Andric // Also returns zero if ULEBSizeErr is already in an error state. 7135f757f3fSDimitry Andric // ULEBSizeErr is an out variable if an error occurs. 7145f757f3fSDimitry Andric template <typename IntTy, std::enable_if_t<std::is_unsigned_v<IntTy>, int> = 0> 7155f757f3fSDimitry Andric static IntTy readULEB128As(DataExtractor &Data, DataExtractor::Cursor &Cur, 7165f757f3fSDimitry Andric Error &ULEBSizeErr) { 7175f757f3fSDimitry Andric // Bail out and do not extract data if ULEBSizeErr is already set. 7185f757f3fSDimitry Andric if (ULEBSizeErr) 7195f757f3fSDimitry Andric return 0; 7205f757f3fSDimitry Andric uint64_t Offset = Cur.tell(); 7215f757f3fSDimitry Andric uint64_t Value = Data.getULEB128(Cur); 7225f757f3fSDimitry Andric if (Value > std::numeric_limits<IntTy>::max()) { 7235f757f3fSDimitry Andric ULEBSizeErr = createError("ULEB128 value at offset 0x" + 7245f757f3fSDimitry Andric Twine::utohexstr(Offset) + " exceeds UINT" + 7255f757f3fSDimitry Andric Twine(std::numeric_limits<IntTy>::digits) + 7265f757f3fSDimitry Andric "_MAX (0x" + Twine::utohexstr(Value) + ")"); 7275f757f3fSDimitry Andric return 0; 7285f757f3fSDimitry Andric } 7295f757f3fSDimitry Andric return static_cast<IntTy>(Value); 7305f757f3fSDimitry Andric } 7315f757f3fSDimitry Andric 7325f757f3fSDimitry Andric template <typename ELFT> 7335f757f3fSDimitry Andric static Expected<std::vector<BBAddrMap>> 7345f757f3fSDimitry Andric decodeBBAddrMapImpl(const ELFFile<ELFT> &EF, 7355f757f3fSDimitry Andric const typename ELFFile<ELFT>::Elf_Shdr &Sec, 7365f757f3fSDimitry Andric const typename ELFFile<ELFT>::Elf_Shdr *RelaSec, 7375f757f3fSDimitry Andric std::vector<PGOAnalysisMap> *PGOAnalyses) { 7385f757f3fSDimitry Andric bool IsRelocatable = EF.getHeader().e_type == ELF::ET_REL; 73906c3fb27SDimitry Andric 74006c3fb27SDimitry Andric // This DenseMap maps the offset of each function (the location of the 74106c3fb27SDimitry Andric // reference to the function in the SHT_LLVM_BB_ADDR_MAP section) to the 74206c3fb27SDimitry Andric // addend (the location of the function in the text section). 74306c3fb27SDimitry Andric llvm::DenseMap<uint64_t, uint64_t> FunctionOffsetTranslations; 74406c3fb27SDimitry Andric if (IsRelocatable && RelaSec) { 74506c3fb27SDimitry Andric assert(RelaSec && 74606c3fb27SDimitry Andric "Can't read a SHT_LLVM_BB_ADDR_MAP section in a relocatable " 74706c3fb27SDimitry Andric "object file without providing a relocation section."); 7485f757f3fSDimitry Andric Expected<typename ELFFile<ELFT>::Elf_Rela_Range> Relas = EF.relas(*RelaSec); 74906c3fb27SDimitry Andric if (!Relas) 75006c3fb27SDimitry Andric return createError("unable to read relocations for section " + 7515f757f3fSDimitry Andric describe(EF, Sec) + ": " + 75206c3fb27SDimitry Andric toString(Relas.takeError())); 7535f757f3fSDimitry Andric for (typename ELFFile<ELFT>::Elf_Rela Rela : *Relas) 75406c3fb27SDimitry Andric FunctionOffsetTranslations[Rela.r_offset] = Rela.r_addend; 75506c3fb27SDimitry Andric } 756*0fca6ea1SDimitry Andric auto GetAddressForRelocation = 757*0fca6ea1SDimitry Andric [&](unsigned RelocationOffsetInSection) -> Expected<unsigned> { 758*0fca6ea1SDimitry Andric auto FOTIterator = 759*0fca6ea1SDimitry Andric FunctionOffsetTranslations.find(RelocationOffsetInSection); 760*0fca6ea1SDimitry Andric if (FOTIterator == FunctionOffsetTranslations.end()) { 761*0fca6ea1SDimitry Andric return createError("failed to get relocation data for offset: " + 762*0fca6ea1SDimitry Andric Twine::utohexstr(RelocationOffsetInSection) + 763*0fca6ea1SDimitry Andric " in section " + describe(EF, Sec)); 764*0fca6ea1SDimitry Andric } 765*0fca6ea1SDimitry Andric return FOTIterator->second; 766*0fca6ea1SDimitry Andric }; 7675f757f3fSDimitry Andric Expected<ArrayRef<uint8_t>> ContentsOrErr = EF.getSectionContents(Sec); 768fe6060f1SDimitry Andric if (!ContentsOrErr) 769fe6060f1SDimitry Andric return ContentsOrErr.takeError(); 770fe6060f1SDimitry Andric ArrayRef<uint8_t> Content = *ContentsOrErr; 7715f757f3fSDimitry Andric DataExtractor Data(Content, EF.isLE(), ELFT::Is64Bits ? 8 : 4); 772349cc55cSDimitry Andric std::vector<BBAddrMap> FunctionEntries; 773fe6060f1SDimitry Andric 774fe6060f1SDimitry Andric DataExtractor::Cursor Cur(0); 775fe6060f1SDimitry Andric Error ULEBSizeErr = Error::success(); 77606c3fb27SDimitry Andric Error MetadataDecodeErr = Error::success(); 777fe6060f1SDimitry Andric 778*0fca6ea1SDimitry Andric // Helper lampda to extract the (possiblly relocatable) address stored at Cur. 779*0fca6ea1SDimitry Andric auto ExtractAddress = [&]() -> Expected<typename ELFFile<ELFT>::uintX_t> { 780*0fca6ea1SDimitry Andric uint64_t RelocationOffsetInSection = Cur.tell(); 781*0fca6ea1SDimitry Andric auto Address = 782*0fca6ea1SDimitry Andric static_cast<typename ELFFile<ELFT>::uintX_t>(Data.getAddress(Cur)); 783*0fca6ea1SDimitry Andric if (!Cur) 784*0fca6ea1SDimitry Andric return Cur.takeError(); 785*0fca6ea1SDimitry Andric if (!IsRelocatable) 786*0fca6ea1SDimitry Andric return Address; 787*0fca6ea1SDimitry Andric assert(Address == 0); 788*0fca6ea1SDimitry Andric Expected<unsigned> AddressOrErr = 789*0fca6ea1SDimitry Andric GetAddressForRelocation(RelocationOffsetInSection); 790*0fca6ea1SDimitry Andric if (!AddressOrErr) 791*0fca6ea1SDimitry Andric return AddressOrErr.takeError(); 792*0fca6ea1SDimitry Andric return *AddressOrErr; 793*0fca6ea1SDimitry Andric }; 794*0fca6ea1SDimitry Andric 79581ad6265SDimitry Andric uint8_t Version = 0; 7965f757f3fSDimitry Andric uint8_t Feature = 0; 797*0fca6ea1SDimitry Andric BBAddrMap::Features FeatEnable{}; 79806c3fb27SDimitry Andric while (!ULEBSizeErr && !MetadataDecodeErr && Cur && 79906c3fb27SDimitry Andric Cur.tell() < Content.size()) { 80081ad6265SDimitry Andric if (Sec.sh_type == ELF::SHT_LLVM_BB_ADDR_MAP) { 80181ad6265SDimitry Andric Version = Data.getU8(Cur); 80281ad6265SDimitry Andric if (!Cur) 80381ad6265SDimitry Andric break; 804bdd1243dSDimitry Andric if (Version > 2) 80581ad6265SDimitry Andric return createError("unsupported SHT_LLVM_BB_ADDR_MAP version: " + 80681ad6265SDimitry Andric Twine(static_cast<int>(Version))); 8075f757f3fSDimitry Andric Feature = Data.getU8(Cur); // Feature byte 8085f757f3fSDimitry Andric if (!Cur) 8095f757f3fSDimitry Andric break; 810*0fca6ea1SDimitry Andric auto FeatEnableOrErr = BBAddrMap::Features::decode(Feature); 8115f757f3fSDimitry Andric if (!FeatEnableOrErr) 8125f757f3fSDimitry Andric return FeatEnableOrErr.takeError(); 813*0fca6ea1SDimitry Andric FeatEnable = *FeatEnableOrErr; 8145f757f3fSDimitry Andric if (Feature != 0 && Version < 2 && Cur) 8155f757f3fSDimitry Andric return createError( 8165f757f3fSDimitry Andric "version should be >= 2 for SHT_LLVM_BB_ADDR_MAP when " 8175f757f3fSDimitry Andric "PGO features are enabled: version = " + 8185f757f3fSDimitry Andric Twine(static_cast<int>(Version)) + 8195f757f3fSDimitry Andric " feature = " + Twine(static_cast<int>(Feature))); 82081ad6265SDimitry Andric } 821*0fca6ea1SDimitry Andric uint32_t NumBlocksInBBRange = 0; 822*0fca6ea1SDimitry Andric uint32_t NumBBRanges = 1; 823*0fca6ea1SDimitry Andric typename ELFFile<ELFT>::uintX_t RangeBaseAddress = 0; 824349cc55cSDimitry Andric std::vector<BBAddrMap::BBEntry> BBEntries; 825*0fca6ea1SDimitry Andric if (FeatEnable.MultiBBRange) { 826*0fca6ea1SDimitry Andric NumBBRanges = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr); 827*0fca6ea1SDimitry Andric if (!Cur || ULEBSizeErr) 828*0fca6ea1SDimitry Andric break; 829*0fca6ea1SDimitry Andric if (!NumBBRanges) 830*0fca6ea1SDimitry Andric return createError("invalid zero number of BB ranges at offset " + 831*0fca6ea1SDimitry Andric Twine::utohexstr(Cur.tell()) + " in " + 832*0fca6ea1SDimitry Andric describe(EF, Sec)); 833*0fca6ea1SDimitry Andric } else { 834*0fca6ea1SDimitry Andric auto AddressOrErr = ExtractAddress(); 835*0fca6ea1SDimitry Andric if (!AddressOrErr) 836*0fca6ea1SDimitry Andric return AddressOrErr.takeError(); 837*0fca6ea1SDimitry Andric RangeBaseAddress = *AddressOrErr; 838*0fca6ea1SDimitry Andric NumBlocksInBBRange = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr); 839*0fca6ea1SDimitry Andric } 840*0fca6ea1SDimitry Andric std::vector<BBAddrMap::BBRangeEntry> BBRangeEntries; 841*0fca6ea1SDimitry Andric uint32_t TotalNumBlocks = 0; 842*0fca6ea1SDimitry Andric for (uint32_t BBRangeIndex = 0; BBRangeIndex < NumBBRanges; 843*0fca6ea1SDimitry Andric ++BBRangeIndex) { 84481ad6265SDimitry Andric uint32_t PrevBBEndOffset = 0; 845*0fca6ea1SDimitry Andric if (FeatEnable.MultiBBRange) { 846*0fca6ea1SDimitry Andric auto AddressOrErr = ExtractAddress(); 847*0fca6ea1SDimitry Andric if (!AddressOrErr) 848*0fca6ea1SDimitry Andric return AddressOrErr.takeError(); 849*0fca6ea1SDimitry Andric RangeBaseAddress = *AddressOrErr; 850*0fca6ea1SDimitry Andric NumBlocksInBBRange = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr); 851*0fca6ea1SDimitry Andric } 852*0fca6ea1SDimitry Andric for (uint32_t BlockIndex = 0; !MetadataDecodeErr && !ULEBSizeErr && Cur && 853*0fca6ea1SDimitry Andric (BlockIndex < NumBlocksInBBRange); 85406c3fb27SDimitry Andric ++BlockIndex) { 8555f757f3fSDimitry Andric uint32_t ID = Version >= 2 8565f757f3fSDimitry Andric ? readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr) 8575f757f3fSDimitry Andric : BlockIndex; 8585f757f3fSDimitry Andric uint32_t Offset = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr); 8595f757f3fSDimitry Andric uint32_t Size = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr); 8605f757f3fSDimitry Andric uint32_t MD = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr); 86181ad6265SDimitry Andric if (Version >= 1) { 86281ad6265SDimitry Andric // Offset is calculated relative to the end of the previous BB. 86381ad6265SDimitry Andric Offset += PrevBBEndOffset; 86481ad6265SDimitry Andric PrevBBEndOffset = Offset + Size; 86581ad6265SDimitry Andric } 86606c3fb27SDimitry Andric Expected<BBAddrMap::BBEntry::Metadata> MetadataOrErr = 86706c3fb27SDimitry Andric BBAddrMap::BBEntry::Metadata::decode(MD); 86806c3fb27SDimitry Andric if (!MetadataOrErr) { 86906c3fb27SDimitry Andric MetadataDecodeErr = MetadataOrErr.takeError(); 87006c3fb27SDimitry Andric break; 87106c3fb27SDimitry Andric } 87206c3fb27SDimitry Andric BBEntries.push_back({ID, Offset, Size, *MetadataOrErr}); 873fe6060f1SDimitry Andric } 874*0fca6ea1SDimitry Andric TotalNumBlocks += BBEntries.size(); 875*0fca6ea1SDimitry Andric BBRangeEntries.push_back({RangeBaseAddress, std::move(BBEntries)}); 876*0fca6ea1SDimitry Andric } 877*0fca6ea1SDimitry Andric FunctionEntries.push_back({std::move(BBRangeEntries)}); 8785f757f3fSDimitry Andric 879*0fca6ea1SDimitry Andric if (PGOAnalyses || FeatEnable.hasPGOAnalysis()) { 8805f757f3fSDimitry Andric // Function entry count 8815f757f3fSDimitry Andric uint64_t FuncEntryCount = 8825f757f3fSDimitry Andric FeatEnable.FuncEntryCount 8835f757f3fSDimitry Andric ? readULEB128As<uint64_t>(Data, Cur, ULEBSizeErr) 8845f757f3fSDimitry Andric : 0; 8855f757f3fSDimitry Andric 8865f757f3fSDimitry Andric std::vector<PGOAnalysisMap::PGOBBEntry> PGOBBEntries; 8871db9f3b2SDimitry Andric for (uint32_t BlockIndex = 0; 888*0fca6ea1SDimitry Andric FeatEnable.hasPGOAnalysisBBData() && !MetadataDecodeErr && 889*0fca6ea1SDimitry Andric !ULEBSizeErr && Cur && (BlockIndex < TotalNumBlocks); 8905f757f3fSDimitry Andric ++BlockIndex) { 8915f757f3fSDimitry Andric // Block frequency 8925f757f3fSDimitry Andric uint64_t BBF = FeatEnable.BBFreq 8935f757f3fSDimitry Andric ? readULEB128As<uint64_t>(Data, Cur, ULEBSizeErr) 8945f757f3fSDimitry Andric : 0; 8955f757f3fSDimitry Andric 8965f757f3fSDimitry Andric // Branch probability 8975f757f3fSDimitry Andric llvm::SmallVector<PGOAnalysisMap::PGOBBEntry::SuccessorEntry, 2> 8985f757f3fSDimitry Andric Successors; 8995f757f3fSDimitry Andric if (FeatEnable.BrProb) { 9005f757f3fSDimitry Andric auto SuccCount = readULEB128As<uint64_t>(Data, Cur, ULEBSizeErr); 9015f757f3fSDimitry Andric for (uint64_t I = 0; I < SuccCount; ++I) { 9025f757f3fSDimitry Andric uint32_t BBID = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr); 9035f757f3fSDimitry Andric uint32_t BrProb = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr); 9045f757f3fSDimitry Andric if (PGOAnalyses) 9055f757f3fSDimitry Andric Successors.push_back({BBID, BranchProbability::getRaw(BrProb)}); 9065f757f3fSDimitry Andric } 9075f757f3fSDimitry Andric } 9085f757f3fSDimitry Andric 9095f757f3fSDimitry Andric if (PGOAnalyses) 9105f757f3fSDimitry Andric PGOBBEntries.push_back({BlockFrequency(BBF), std::move(Successors)}); 9115f757f3fSDimitry Andric } 9125f757f3fSDimitry Andric 9135f757f3fSDimitry Andric if (PGOAnalyses) 9145f757f3fSDimitry Andric PGOAnalyses->push_back( 9155f757f3fSDimitry Andric {FuncEntryCount, std::move(PGOBBEntries), FeatEnable}); 9165f757f3fSDimitry Andric } 917fe6060f1SDimitry Andric } 91806c3fb27SDimitry Andric // Either Cur is in the error state, or we have an error in ULEBSizeErr or 91906c3fb27SDimitry Andric // MetadataDecodeErr (but not both), but we join all errors here to be safe. 92006c3fb27SDimitry Andric if (!Cur || ULEBSizeErr || MetadataDecodeErr) 92106c3fb27SDimitry Andric return joinErrors(joinErrors(Cur.takeError(), std::move(ULEBSizeErr)), 92206c3fb27SDimitry Andric std::move(MetadataDecodeErr)); 923fe6060f1SDimitry Andric return FunctionEntries; 924fe6060f1SDimitry Andric } 925fe6060f1SDimitry Andric 92606c3fb27SDimitry Andric template <class ELFT> 9275f757f3fSDimitry Andric Expected<std::vector<BBAddrMap>> 9285f757f3fSDimitry Andric ELFFile<ELFT>::decodeBBAddrMap(const Elf_Shdr &Sec, const Elf_Shdr *RelaSec, 9295f757f3fSDimitry Andric std::vector<PGOAnalysisMap> *PGOAnalyses) const { 9305f757f3fSDimitry Andric size_t OriginalPGOSize = PGOAnalyses ? PGOAnalyses->size() : 0; 9315f757f3fSDimitry Andric auto AddrMapsOrErr = decodeBBAddrMapImpl(*this, Sec, RelaSec, PGOAnalyses); 9325f757f3fSDimitry Andric // remove new analyses when an error occurs 9335f757f3fSDimitry Andric if (!AddrMapsOrErr && PGOAnalyses) 9345f757f3fSDimitry Andric PGOAnalyses->resize(OriginalPGOSize); 9355f757f3fSDimitry Andric return std::move(AddrMapsOrErr); 9365f757f3fSDimitry Andric } 9375f757f3fSDimitry Andric 9385f757f3fSDimitry Andric template <class ELFT> 93906c3fb27SDimitry Andric Expected< 94006c3fb27SDimitry Andric MapVector<const typename ELFT::Shdr *, const typename ELFT::Shdr *>> 94106c3fb27SDimitry Andric ELFFile<ELFT>::getSectionAndRelocations( 94206c3fb27SDimitry Andric std::function<Expected<bool>(const Elf_Shdr &)> IsMatch) const { 94306c3fb27SDimitry Andric MapVector<const Elf_Shdr *, const Elf_Shdr *> SecToRelocMap; 94406c3fb27SDimitry Andric Error Errors = Error::success(); 94506c3fb27SDimitry Andric for (const Elf_Shdr &Sec : cantFail(this->sections())) { 94606c3fb27SDimitry Andric Expected<bool> DoesSectionMatch = IsMatch(Sec); 94706c3fb27SDimitry Andric if (!DoesSectionMatch) { 94806c3fb27SDimitry Andric Errors = joinErrors(std::move(Errors), DoesSectionMatch.takeError()); 94906c3fb27SDimitry Andric continue; 95006c3fb27SDimitry Andric } 95106c3fb27SDimitry Andric if (*DoesSectionMatch) { 95206c3fb27SDimitry Andric if (SecToRelocMap.insert(std::make_pair(&Sec, (const Elf_Shdr *)nullptr)) 95306c3fb27SDimitry Andric .second) 95406c3fb27SDimitry Andric continue; 95506c3fb27SDimitry Andric } 95606c3fb27SDimitry Andric 95706c3fb27SDimitry Andric if (Sec.sh_type != ELF::SHT_RELA && Sec.sh_type != ELF::SHT_REL) 95806c3fb27SDimitry Andric continue; 95906c3fb27SDimitry Andric 96006c3fb27SDimitry Andric Expected<const Elf_Shdr *> RelSecOrErr = this->getSection(Sec.sh_info); 96106c3fb27SDimitry Andric if (!RelSecOrErr) { 96206c3fb27SDimitry Andric Errors = joinErrors(std::move(Errors), 96306c3fb27SDimitry Andric createError(describe(*this, Sec) + 96406c3fb27SDimitry Andric ": failed to get a relocated section: " + 96506c3fb27SDimitry Andric toString(RelSecOrErr.takeError()))); 96606c3fb27SDimitry Andric continue; 96706c3fb27SDimitry Andric } 96806c3fb27SDimitry Andric const Elf_Shdr *ContentsSec = *RelSecOrErr; 96906c3fb27SDimitry Andric Expected<bool> DoesRelTargetMatch = IsMatch(*ContentsSec); 97006c3fb27SDimitry Andric if (!DoesRelTargetMatch) { 97106c3fb27SDimitry Andric Errors = joinErrors(std::move(Errors), DoesRelTargetMatch.takeError()); 97206c3fb27SDimitry Andric continue; 97306c3fb27SDimitry Andric } 97406c3fb27SDimitry Andric if (*DoesRelTargetMatch) 97506c3fb27SDimitry Andric SecToRelocMap[ContentsSec] = &Sec; 97606c3fb27SDimitry Andric } 97706c3fb27SDimitry Andric if(Errors) 97806c3fb27SDimitry Andric return std::move(Errors); 97906c3fb27SDimitry Andric return SecToRelocMap; 98006c3fb27SDimitry Andric } 98106c3fb27SDimitry Andric 9820b57cec5SDimitry Andric template class llvm::object::ELFFile<ELF32LE>; 9830b57cec5SDimitry Andric template class llvm::object::ELFFile<ELF32BE>; 9840b57cec5SDimitry Andric template class llvm::object::ELFFile<ELF64LE>; 9850b57cec5SDimitry Andric template class llvm::object::ELFFile<ELF64BE>; 986