Index: lld/ELF/DWARF.cpp =================================================================== --- lld/ELF/DWARF.cpp +++ lld/ELF/DWARF.cpp @@ -77,18 +77,20 @@ namespace { template struct LLDRelocationResolver { // In the ELF ABIs, S sepresents the value of the symbol in the relocation - // entry. For Rela, the addend is stored as part of the relocation entry. - static uint64_t resolve(object::RelocationRef ref, uint64_t s, - uint64_t /* A */) { - return s + ref.getRawDataRefImpl().p; + // entry. For Rela, the addend is stored as part of the relocation entry and + // is provided by the `findAux` method. + static uint64_t resolve(uint64_t /*type*/, uint64_t /*offset*/, uint64_t s, + uint64_t /*locData*/, int64_t addend) { + return s + addend; } }; template struct LLDRelocationResolver> { - // For Rel, the addend A is supplied by the caller. - static uint64_t resolve(object::RelocationRef /*Ref*/, uint64_t s, - uint64_t a) { - return s + a; + // For Rel, the addend is stored in the object data and is supplied by the + // caller. + static uint64_t resolve(uint64_t /*type*/, uint64_t /*offset*/, uint64_t s, + uint64_t locData, int64_t /*addend*/) { + return s + locData; } }; } // namespace Index: llvm/include/llvm/Object/ELFObjectFile.h =================================================================== --- llvm/include/llvm/Object/ELFObjectFile.h +++ llvm/include/llvm/Object/ELFObjectFile.h @@ -313,14 +313,6 @@ uint64_t getSectionOffset(DataRefImpl Sec) const override; StringRef getRelocationTypeName(uint32_t Type) const; - /// Get the relocation section that contains \a Rel. - const Elf_Shdr *getRelSection(DataRefImpl Rel) const { - auto RelSecOrErr = EF.getSection(Rel.d.a); - if (!RelSecOrErr) - report_fatal_error(errorToErrorCode(RelSecOrErr.takeError()).message()); - return *RelSecOrErr; - } - DataRefImpl toDRI(const Elf_Shdr *SymTable, unsigned SymbolNum) const { DataRefImpl DRI; if (!SymTable) { @@ -419,6 +411,14 @@ return *Ret; } + /// Get the relocation section that contains \a Rel. + const Elf_Shdr *getRelSection(DataRefImpl Rel) const { + auto RelSecOrErr = EF.getSection(Rel.d.a); + if (!RelSecOrErr) + report_fatal_error(errorToErrorCode(RelSecOrErr.takeError()).message()); + return *RelSecOrErr; + } + const Elf_Shdr *getSection(DataRefImpl Sec) const { return reinterpret_cast(Sec.p); } Index: llvm/include/llvm/Object/RelocationResolver.h =================================================================== --- llvm/include/llvm/Object/RelocationResolver.h +++ llvm/include/llvm/Object/RelocationResolver.h @@ -31,11 +31,17 @@ namespace llvm { namespace object { -using RelocationResolver = uint64_t (*)(RelocationRef R, uint64_t S, uint64_t A); +using SupportsRelocation = bool (*)(uint64_t); +using RelocationResolver = uint64_t (*)(uint64_t Type, uint64_t Offset, + uint64_t S, uint64_t LocData, + int64_t Addend); -std::pair +std::pair getRelocationResolver(const ObjectFile &Obj); +uint64_t resolveRelocation(RelocationResolver Resolver, const RelocationRef &R, + uint64_t S, uint64_t LocData); + } // end namespace object } // end namespace llvm Index: llvm/lib/DebugInfo/DWARF/DWARFContext.cpp =================================================================== --- llvm/lib/DebugInfo/DWARF/DWARFContext.cpp +++ llvm/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -1780,7 +1780,7 @@ // Symbol to [address, section index] cache mapping. std::map AddrCache; - bool (*Supports)(uint64_t); + SupportsRelocation Supports; RelocationResolver Resolver; std::tie(Supports, Resolver) = getRelocationResolver(Obj); for (const RelocationRef &Reloc : Section.relocations()) { Index: llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp =================================================================== --- llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp +++ llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp @@ -53,14 +53,16 @@ ErrorAsOutParameter ErrAsOut(Err); Optional E = Obj->find(*Section, *Off); - uint64_t A = getUnsigned(Off, Size, Err); + uint64_t LocData = getUnsigned(Off, Size, Err); if (!E || (Err && *Err)) - return A; + return LocData; if (SecNdx) *SecNdx = E->SectionIndex; - uint64_t R = E->Resolver(E->Reloc, E->SymbolValue, A); + + uint64_t R = + object::resolveRelocation(E->Resolver, E->Reloc, E->SymbolValue, LocData); if (E->Reloc2) - R = E->Resolver(*E->Reloc2, E->SymbolValue2, R); + R = object::resolveRelocation(E->Resolver, *E->Reloc2, E->SymbolValue2, R); return R; } Index: llvm/lib/Object/RelocationResolver.cpp =================================================================== --- llvm/lib/Object/RelocationResolver.cpp +++ llvm/lib/Object/RelocationResolver.cpp @@ -39,20 +39,21 @@ } } -static uint64_t resolveX86_64(RelocationRef R, uint64_t S, uint64_t A) { - switch (R.getType()) { +static uint64_t resolveX86_64(uint64_t Type, uint64_t Offset, uint64_t S, + uint64_t LocData, int64_t Addend) { + switch (Type) { case ELF::R_X86_64_NONE: - return A; + return LocData; case ELF::R_X86_64_64: case ELF::R_X86_64_DTPOFF32: case ELF::R_X86_64_DTPOFF64: - return S + getELFAddend(R); + return S + Addend; case ELF::R_X86_64_PC32: case ELF::R_X86_64_PC64: - return S + getELFAddend(R) - R.getOffset(); + return S + Addend - Offset; case ELF::R_X86_64_32: case ELF::R_X86_64_32S: - return (S + getELFAddend(R)) & 0xFFFFFFFF; + return (S + Addend) & 0xFFFFFFFF; default: llvm_unreachable("Invalid relocation type"); } @@ -70,16 +71,17 @@ } } -static uint64_t resolveAArch64(RelocationRef R, uint64_t S, uint64_t A) { - switch (R.getType()) { +static uint64_t resolveAArch64(uint64_t Type, uint64_t Offset, uint64_t S, + uint64_t /*LocData*/, int64_t Addend) { + switch (Type) { case ELF::R_AARCH64_ABS32: - return (S + getELFAddend(R)) & 0xFFFFFFFF; + return (S + Addend) & 0xFFFFFFFF; case ELF::R_AARCH64_ABS64: - return S + getELFAddend(R); + return S + Addend; case ELF::R_AARCH64_PREL32: - return (S + getELFAddend(R) - R.getOffset()) & 0xFFFFFFFF; + return (S + Addend - Offset) & 0xFFFFFFFF; case ELF::R_AARCH64_PREL64: - return S + getELFAddend(R) - R.getOffset(); + return S + Addend - Offset; default: llvm_unreachable("Invalid relocation type"); } @@ -95,12 +97,13 @@ } } -static uint64_t resolveBPF(RelocationRef R, uint64_t S, uint64_t A) { - switch (R.getType()) { +static uint64_t resolveBPF(uint64_t Type, uint64_t Offset, uint64_t S, + uint64_t LocData, int64_t /*Addend*/) { + switch (Type) { case ELF::R_BPF_64_32: - return (S + A) & 0xFFFFFFFF; + return (S + LocData) & 0xFFFFFFFF; case ELF::R_BPF_64_64: - return S + A; + return S + LocData; default: llvm_unreachable("Invalid relocation type"); } @@ -118,16 +121,17 @@ } } -static uint64_t resolveMips64(RelocationRef R, uint64_t S, uint64_t A) { - switch (R.getType()) { +static uint64_t resolveMips64(uint64_t Type, uint64_t Offset, uint64_t S, + uint64_t /*LocData*/, int64_t Addend) { + switch (Type) { case ELF::R_MIPS_32: - return (S + getELFAddend(R)) & 0xFFFFFFFF; + return (S + Addend) & 0xFFFFFFFF; case ELF::R_MIPS_64: - return S + getELFAddend(R); + return S + Addend; case ELF::R_MIPS_TLS_DTPREL64: - return S + getELFAddend(R) - 0x8000; + return S + Addend - 0x8000; case ELF::R_MIPS_PC32: - return S + getELFAddend(R) - R.getOffset(); + return S + Addend - Offset; default: llvm_unreachable("Invalid relocation type"); } @@ -143,12 +147,13 @@ } } -static uint64_t resolveMSP430(RelocationRef R, uint64_t S, uint64_t A) { - switch (R.getType()) { +static uint64_t resolveMSP430(uint64_t Type, uint64_t Offset, uint64_t S, + uint64_t /*LocData*/, int64_t Addend) { + switch (Type) { case ELF::R_MSP430_32: - return (S + getELFAddend(R)) & 0xFFFFFFFF; + return (S + Addend) & 0xFFFFFFFF; case ELF::R_MSP430_16_BYTE: - return (S + getELFAddend(R)) & 0xFFFF; + return (S + Addend) & 0xFFFF; default: llvm_unreachable("Invalid relocation type"); } @@ -166,16 +171,17 @@ } } -static uint64_t resolvePPC64(RelocationRef R, uint64_t S, uint64_t A) { - switch (R.getType()) { +static uint64_t resolvePPC64(uint64_t Type, uint64_t Offset, uint64_t S, + uint64_t /*LocData*/, int64_t Addend) { + switch (Type) { case ELF::R_PPC64_ADDR32: - return (S + getELFAddend(R)) & 0xFFFFFFFF; + return (S + Addend) & 0xFFFFFFFF; case ELF::R_PPC64_ADDR64: - return S + getELFAddend(R); + return S + Addend; case ELF::R_PPC64_REL32: - return (S + getELFAddend(R) - R.getOffset()) & 0xFFFFFFFF; + return (S + Addend - Offset) & 0xFFFFFFFF; case ELF::R_PPC64_REL64: - return S + getELFAddend(R) - R.getOffset(); + return S + Addend - Offset; default: llvm_unreachable("Invalid relocation type"); } @@ -191,12 +197,13 @@ } } -static uint64_t resolveSystemZ(RelocationRef R, uint64_t S, uint64_t A) { - switch (R.getType()) { +static uint64_t resolveSystemZ(uint64_t Type, uint64_t Offset, uint64_t S, + uint64_t /*LocData*/, int64_t Addend) { + switch (Type) { case ELF::R_390_32: - return (S + getELFAddend(R)) & 0xFFFFFFFF; + return (S + Addend) & 0xFFFFFFFF; case ELF::R_390_64: - return S + getELFAddend(R); + return S + Addend; default: llvm_unreachable("Invalid relocation type"); } @@ -214,13 +221,14 @@ } } -static uint64_t resolveSparc64(RelocationRef R, uint64_t S, uint64_t A) { - switch (R.getType()) { +static uint64_t resolveSparc64(uint64_t Type, uint64_t Offset, uint64_t S, + uint64_t /*LocData*/, int64_t Addend) { + switch (Type) { case ELF::R_SPARC_32: case ELF::R_SPARC_64: case ELF::R_SPARC_UA32: case ELF::R_SPARC_UA64: - return S + getELFAddend(R); + return S + Addend; default: llvm_unreachable("Invalid relocation type"); } @@ -236,11 +244,12 @@ } } -static uint64_t resolveAmdgpu(RelocationRef R, uint64_t S, uint64_t A) { - switch (R.getType()) { +static uint64_t resolveAmdgpu(uint64_t Type, uint64_t Offset, uint64_t S, + uint64_t /*LocData*/, int64_t Addend) { + switch (Type) { case ELF::R_AMDGPU_ABS32: case ELF::R_AMDGPU_ABS64: - return S + getELFAddend(R); + return S + Addend; default: llvm_unreachable("Invalid relocation type"); } @@ -257,14 +266,15 @@ } } -static uint64_t resolveX86(RelocationRef R, uint64_t S, uint64_t A) { - switch (R.getType()) { +static uint64_t resolveX86(uint64_t Type, uint64_t Offset, uint64_t S, + uint64_t LocData, int64_t /*Addend*/) { + switch (Type) { case ELF::R_386_NONE: - return A; + return LocData; case ELF::R_386_32: - return S + A; + return S + LocData; case ELF::R_386_PC32: - return S - R.getOffset() + A; + return S - Offset + LocData; default: llvm_unreachable("Invalid relocation type"); } @@ -280,12 +290,13 @@ } } -static uint64_t resolvePPC32(RelocationRef R, uint64_t S, uint64_t A) { - switch (R.getType()) { +static uint64_t resolvePPC32(uint64_t Type, uint64_t Offset, uint64_t S, + uint64_t /*LocData*/, int64_t Addend) { + switch (Type) { case ELF::R_PPC_ADDR32: - return (S + getELFAddend(R)) & 0xFFFFFFFF; + return (S + Addend) & 0xFFFFFFFF; case ELF::R_PPC_REL32: - return (S + getELFAddend(R) - R.getOffset()) & 0xFFFFFFFF; + return (S + Addend - Offset) & 0xFFFFFFFF; } llvm_unreachable("Invalid relocation type"); } @@ -300,12 +311,13 @@ } } -static uint64_t resolveARM(RelocationRef R, uint64_t S, uint64_t A) { - switch (R.getType()) { +static uint64_t resolveARM(uint64_t Type, uint64_t Offset, uint64_t S, + uint64_t LocData, int64_t /*Addend*/) { + switch (Type) { case ELF::R_ARM_ABS32: - return (S + A) & 0xFFFFFFFF; + return (S + LocData) & 0xFFFFFFFF; case ELF::R_ARM_REL32: - return (S + A - R.getOffset()) & 0xFFFFFFFF; + return (S + LocData - Offset) & 0xFFFFFFFF; } llvm_unreachable("Invalid relocation type"); } @@ -320,12 +332,13 @@ } } -static uint64_t resolveAVR(RelocationRef R, uint64_t S, uint64_t A) { - switch (R.getType()) { +static uint64_t resolveAVR(uint64_t Type, uint64_t Offset, uint64_t S, + uint64_t /*LocData*/, int64_t Addend) { + switch (Type) { case ELF::R_AVR_16: - return (S + getELFAddend(R)) & 0xFFFF; + return (S + Addend) & 0xFFFF; case ELF::R_AVR_32: - return (S + getELFAddend(R)) & 0xFFFFFFFF; + return (S + Addend) & 0xFFFFFFFF; default: llvm_unreachable("Invalid relocation type"); } @@ -335,9 +348,10 @@ return Type == ELF::R_LANAI_32; } -static uint64_t resolveLanai(RelocationRef R, uint64_t S, uint64_t A) { - if (R.getType() == ELF::R_LANAI_32) - return (S + getELFAddend(R)) & 0xFFFFFFFF; +static uint64_t resolveLanai(uint64_t Type, uint64_t Offset, uint64_t S, + uint64_t /*LocData*/, int64_t Addend) { + if (Type == ELF::R_LANAI_32) + return (S + Addend) & 0xFFFFFFFF; llvm_unreachable("Invalid relocation type"); } @@ -351,13 +365,13 @@ } } -static uint64_t resolveMips32(RelocationRef R, uint64_t S, uint64_t A) { +static uint64_t resolveMips32(uint64_t Type, uint64_t Offset, uint64_t S, + uint64_t LocData, int64_t /*Addend*/) { // FIXME: Take in account implicit addends to get correct results. - uint32_t Rel = R.getType(); - if (Rel == ELF::R_MIPS_32) - return (S + A) & 0xFFFFFFFF; - if (Rel == ELF::R_MIPS_TLS_DTPREL32) - return (S + A) & 0xFFFFFFFF; + if (Type == ELF::R_MIPS_32) + return (S + LocData) & 0xFFFFFFFF; + if (Type == ELF::R_MIPS_TLS_DTPREL32) + return (S + LocData) & 0xFFFFFFFF; llvm_unreachable("Invalid relocation type"); } @@ -371,20 +385,21 @@ } } -static uint64_t resolveSparc32(RelocationRef R, uint64_t S, uint64_t A) { - uint32_t Rel = R.getType(); - if (Rel == ELF::R_SPARC_32 || Rel == ELF::R_SPARC_UA32) - return S + getELFAddend(R); - return A; +static uint64_t resolveSparc32(uint64_t Type, uint64_t Offset, uint64_t S, + uint64_t LocData, int64_t Addend) { + if (Type == ELF::R_SPARC_32 || Type == ELF::R_SPARC_UA32) + return S + Addend; + return LocData; } static bool supportsHexagon(uint64_t Type) { return Type == ELF::R_HEX_32; } -static uint64_t resolveHexagon(RelocationRef R, uint64_t S, uint64_t A) { - if (R.getType() == ELF::R_HEX_32) - return S + getELFAddend(R); +static uint64_t resolveHexagon(uint64_t Type, uint64_t Offset, uint64_t S, + uint64_t /*LocData*/, int64_t Addend) { + if (Type == ELF::R_HEX_32) + return S + Addend; llvm_unreachable("Invalid relocation type"); } @@ -410,15 +425,17 @@ } } -static uint64_t resolveRISCV(RelocationRef R, uint64_t S, uint64_t A) { - int64_t RA = getELFAddend(R); - switch (R.getType()) { +static uint64_t resolveRISCV(uint64_t Type, uint64_t Offset, uint64_t S, + uint64_t LocData, int64_t Addend) { + int64_t RA = Addend; + uint64_t A = LocData; + switch (Type) { case ELF::R_RISCV_NONE: - return A; + return LocData; case ELF::R_RISCV_32: return (S + RA) & 0xFFFFFFFF; case ELF::R_RISCV_32_PCREL: - return (S + RA - R.getOffset()) & 0xFFFFFFFF; + return (S + RA - Offset) & 0xFFFFFFFF; case ELF::R_RISCV_64: return S + RA; case ELF::R_RISCV_SET6: @@ -456,11 +473,12 @@ } } -static uint64_t resolveCOFFX86(RelocationRef R, uint64_t S, uint64_t A) { - switch (R.getType()) { +static uint64_t resolveCOFFX86(uint64_t Type, uint64_t Offset, uint64_t S, + uint64_t LocData, int64_t /*Addend*/) { + switch (Type) { case COFF::IMAGE_REL_I386_SECREL: case COFF::IMAGE_REL_I386_DIR32: - return (S + A) & 0xFFFFFFFF; + return (S + LocData) & 0xFFFFFFFF; default: llvm_unreachable("Invalid relocation type"); } @@ -476,12 +494,13 @@ } } -static uint64_t resolveCOFFX86_64(RelocationRef R, uint64_t S, uint64_t A) { - switch (R.getType()) { +static uint64_t resolveCOFFX86_64(uint64_t Type, uint64_t Offset, uint64_t S, + uint64_t LocData, int64_t /*Addend*/) { + switch (Type) { case COFF::IMAGE_REL_AMD64_SECREL: - return (S + A) & 0xFFFFFFFF; + return (S + LocData) & 0xFFFFFFFF; case COFF::IMAGE_REL_AMD64_ADDR64: - return S + A; + return S + LocData; default: llvm_unreachable("Invalid relocation type"); } @@ -497,11 +516,12 @@ } } -static uint64_t resolveCOFFARM(RelocationRef R, uint64_t S, uint64_t A) { - switch (R.getType()) { +static uint64_t resolveCOFFARM(uint64_t Type, uint64_t Offset, uint64_t S, + uint64_t LocData, int64_t /*Addend*/) { + switch (Type) { case COFF::IMAGE_REL_ARM_SECREL: case COFF::IMAGE_REL_ARM_ADDR32: - return (S + A) & 0xFFFFFFFF; + return (S + LocData) & 0xFFFFFFFF; default: llvm_unreachable("Invalid relocation type"); } @@ -517,12 +537,13 @@ } } -static uint64_t resolveCOFFARM64(RelocationRef R, uint64_t S, uint64_t A) { - switch (R.getType()) { +static uint64_t resolveCOFFARM64(uint64_t Type, uint64_t Offset, uint64_t S, + uint64_t LocData, int64_t /*Addend*/) { + switch (Type) { case COFF::IMAGE_REL_ARM64_SECREL: - return (S + A) & 0xFFFFFFFF; + return (S + LocData) & 0xFFFFFFFF; case COFF::IMAGE_REL_ARM64_ADDR64: - return S + A; + return S + LocData; default: llvm_unreachable("Invalid relocation type"); } @@ -532,8 +553,9 @@ return Type == MachO::X86_64_RELOC_UNSIGNED; } -static uint64_t resolveMachOX86_64(RelocationRef R, uint64_t S, uint64_t A) { - if (R.getType() == MachO::X86_64_RELOC_UNSIGNED) +static uint64_t resolveMachOX86_64(uint64_t Type, uint64_t Offset, uint64_t S, + uint64_t LocData, int64_t /*Addend*/) { + if (Type == MachO::X86_64_RELOC_UNSIGNED) return S; llvm_unreachable("Invalid relocation type"); } @@ -573,8 +595,9 @@ } } -static uint64_t resolveWasm32(RelocationRef R, uint64_t S, uint64_t A) { - switch (R.getType()) { +static uint64_t resolveWasm32(uint64_t Type, uint64_t Offset, uint64_t S, + uint64_t LocData, int64_t /*Addend*/) { + switch (Type) { case wasm::R_WASM_FUNCTION_INDEX_LEB: case wasm::R_WASM_TABLE_INDEX_SLEB: case wasm::R_WASM_TABLE_INDEX_I32: @@ -589,14 +612,15 @@ case wasm::R_WASM_GLOBAL_INDEX_I32: case wasm::R_WASM_TABLE_NUMBER_LEB: // For wasm section, its offset at 0 -- ignoring Value - return A; + return LocData; default: llvm_unreachable("Invalid relocation type"); } } -static uint64_t resolveWasm64(RelocationRef R, uint64_t S, uint64_t A) { - switch (R.getType()) { +static uint64_t resolveWasm64(uint64_t Type, uint64_t Offset, uint64_t S, + uint64_t LocData, int64_t Addend) { + switch (Type) { case wasm::R_WASM_MEMORY_ADDR_LEB64: case wasm::R_WASM_MEMORY_ADDR_SLEB64: case wasm::R_WASM_MEMORY_ADDR_I64: @@ -604,13 +628,13 @@ case wasm::R_WASM_TABLE_INDEX_I64: case wasm::R_WASM_FUNCTION_OFFSET_I64: // For wasm section, its offset at 0 -- ignoring Value - return A; + return LocData; default: - return resolveWasm32(R, S, A); + return resolveWasm32(Type, Offset, S, LocData, Addend); } } -std::pair +std::pair getRelocationResolver(const ObjectFile &Obj) { if (Obj.isCOFF()) { switch (Obj.getArch()) { @@ -701,5 +725,38 @@ llvm_unreachable("Invalid object file"); } +uint64_t resolveRelocation(RelocationResolver Resolver, const RelocationRef &R, + uint64_t S, uint64_t LocData) { + if (const ObjectFile *Obj = R.getObject()) { + int64_t Addend = 0; + if (Obj->isELF()) { + auto GetRelSectionType = [&]() -> unsigned { + if (auto *Elf32LEObj = dyn_cast(Obj)) + return Elf32LEObj->getRelSection(R.getRawDataRefImpl())->sh_type; + if (auto *Elf64LEObj = dyn_cast(Obj)) + return Elf64LEObj->getRelSection(R.getRawDataRefImpl())->sh_type; + if (auto *Elf32BEObj = dyn_cast(Obj)) + return Elf32BEObj->getRelSection(R.getRawDataRefImpl())->sh_type; + auto *Elf64BEObj = cast(Obj); + return Elf64BEObj->getRelSection(R.getRawDataRefImpl())->sh_type; + }; + + if (GetRelSectionType() == ELF::SHT_RELA) + Addend = getELFAddend(R); + } + + return Resolver(R.getType(), R.getOffset(), S, LocData, Addend); + } + + // Sometimes the caller might want to use its own specific implementation of + // the resolver function. E.g. this is used by LLD when it resolves debug + // relocations and assumes that all of them have the same computation (S + A). + // The relocation R have no owner object in this case and we don't need to + // provide Type and Offset fields. It is also assumed the DataRefImpl.p + // contains the addend, provided by the caller. + return Resolver(/*Type=*/0, /*Offset=*/0, S, LocData, + R.getRawDataRefImpl().p); +} + } // namespace object } // namespace llvm Index: llvm/lib/XRay/InstrumentationMap.cpp =================================================================== --- llvm/lib/XRay/InstrumentationMap.cpp +++ llvm/lib/XRay/InstrumentationMap.cpp @@ -109,28 +109,32 @@ return static_cast(0); }(ObjFile.getBinary()); - bool (*SupportsRelocation)(uint64_t); + object::SupportsRelocation Supports; object::RelocationResolver Resolver; - std::tie(SupportsRelocation, Resolver) = + std::tie(Supports, Resolver) = object::getRelocationResolver(*ObjFile.getBinary()); for (const object::SectionRef &Section : Sections) { for (const object::RelocationRef &Reloc : Section.relocations()) { if (ObjFile.getBinary()->getArch() == Triple::arm) { - if (SupportsRelocation && SupportsRelocation(Reloc.getType())) { + if (Supports && Supports(Reloc.getType())) { Expected ValueOrErr = Reloc.getSymbol()->getValue(); if (!ValueOrErr) return ValueOrErr.takeError(); - Relocs.insert({Reloc.getOffset(), Resolver(Reloc, *ValueOrErr, 0)}); + Relocs.insert( + {Reloc.getOffset(), + object::resolveRelocation(Resolver, Reloc, *ValueOrErr, 0)}); } - } else if (SupportsRelocation && SupportsRelocation(Reloc.getType())) { + } else if (Supports && Supports(Reloc.getType())) { auto AddendOrErr = object::ELFRelocationRef(Reloc).getAddend(); auto A = AddendOrErr ? *AddendOrErr : 0; Expected ValueOrErr = Reloc.getSymbol()->getValue(); if (!ValueOrErr) // TODO: Test this error. return ValueOrErr.takeError(); - Relocs.insert({Reloc.getOffset(), Resolver(Reloc, *ValueOrErr, A)}); + Relocs.insert( + {Reloc.getOffset(), + object::resolveRelocation(Resolver, Reloc, *ValueOrErr, A)}); } else if (Reloc.getType() == RelativeRelocation) { if (auto AddendOrErr = object::ELFRelocationRef(Reloc).getAddend()) Relocs.insert({Reloc.getOffset(), *AddendOrErr}); Index: llvm/test/Object/invalid.test =================================================================== --- llvm/test/Object/invalid.test +++ llvm/test/Object/invalid.test @@ -43,13 +43,14 @@ # INVALID-STRTAB-SIZE: error: '[[FILE]]': section [index 1] has a sh_offset (0x70) + sh_size (0xffffff) that is greater than the file size (0x218) -## Check that llvm-dwarfdump reports an error during relocation resolution -## when instead of expected SHT_RELA section it locates a section of a different type. +## Document that llvm-dwarfdump doesn't reports errors/warnings during relocation resolution +## when instead of SHT_RELA section we have a SHT_REL section in an object. +## In this case it just doesn't try to read relocation addends and assumes they are 0. +## Note: we don't check the output, because the intention of this test is just to check the +## exit code and to document the fact that no warnings are reported. # RUN: yaml2obj %s --docnum=3 -o %t3 -# RUN: not --crash llvm-dwarfdump -debug-line %t3 2>&1 | FileCheck --check-prefix=RELA %s - -# RELA: LLVM ERROR: Section is not SHT_RELA +# RUN: llvm-dwarfdump -debug-line %t3 2>&1 | FileCheck --implicit-check-not=warning: %s --- !ELF FileHeader: Index: llvm/tools/llvm-readobj/ELFDumper.cpp =================================================================== --- llvm/tools/llvm-readobj/ELFDumper.cpp +++ llvm/tools/llvm-readobj/ELFDumper.cpp @@ -781,7 +781,12 @@ const Elf_Shdr &Sec, const Elf_Shdr *SymTab) = 0; virtual void printRelrReloc(const Elf_Relr &R) = 0; virtual void printDynamicReloc(const Relocation &R) = 0; - void printRelocationsHelper(const Elf_Shdr &Sec); + void forEachRelocationDo( + const Elf_Shdr &Sec, bool RawRelr, + llvm::function_ref &, unsigned, + const Elf_Shdr &, const Elf_Shdr *)> + RelRelaFn, + llvm::function_ref RelrFn); void printDynamicRelocationsHelper(); virtual void printDynamicRelocHeader(unsigned Type, StringRef Name, const DynRegionInfo &Reg){}; @@ -3782,7 +3787,11 @@ << to_hexString(Offset, false) << " contains " << EntriesNum << " entries:\n"; printRelocHeaderFields(OS, Sec.sh_type); - this->printRelocationsHelper(Sec); + this->forEachRelocationDo( + Sec, opts::RawRelr, + [&](const Relocation &R, unsigned Ndx, const Elf_Shdr &Sec, + const Elf_Shdr *SymTab) { printReloc(R, Ndx, Sec, SymTab); }, + [&](const Elf_Relr &R) { printRelrReloc(R); }); } if (!HasRelocSections) OS << "\nThere are no relocations in this file.\n"; @@ -5610,7 +5619,12 @@ } template -void DumpStyle::printRelocationsHelper(const Elf_Shdr &Sec) { +void DumpStyle::forEachRelocationDo( + const Elf_Shdr &Sec, bool RawRelr, + llvm::function_ref &, unsigned, + const Elf_Shdr &, const Elf_Shdr *)> + RelRelaFn, + llvm::function_ref RelrFn) { auto Warn = [&](Error &&E, const Twine &Prefix = "unable to read relocations from") { this->reportUniqueWarning(createError(Prefix + " " + describe(Obj, Sec) + @@ -5636,7 +5650,7 @@ case ELF::SHT_REL: if (Expected RangeOrErr = Obj.rels(Sec)) { for (const Elf_Rel &R : *RangeOrErr) - printReloc(Relocation(R, IsMips64EL), ++RelNdx, Sec, SymTab); + RelRelaFn(Relocation(R, IsMips64EL), ++RelNdx, Sec, SymTab); } else { Warn(RangeOrErr.takeError()); } @@ -5644,7 +5658,7 @@ case ELF::SHT_RELA: if (Expected RangeOrErr = Obj.relas(Sec)) { for (const Elf_Rela &R : *RangeOrErr) - printReloc(Relocation(R, IsMips64EL), ++RelNdx, Sec, SymTab); + RelRelaFn(Relocation(R, IsMips64EL), ++RelNdx, Sec, SymTab); } else { Warn(RangeOrErr.takeError()); } @@ -5656,22 +5670,22 @@ Warn(RangeOrErr.takeError()); break; } - if (opts::RawRelr) { + if (RawRelr) { for (const Elf_Relr &R : *RangeOrErr) - printRelrReloc(R); + RelrFn(R); break; } for (const Elf_Rel &R : Obj.decode_relrs(*RangeOrErr)) - printReloc(Relocation(R, IsMips64EL), ++RelNdx, Sec, - /*SymTab=*/nullptr); + RelRelaFn(Relocation(R, IsMips64EL), ++RelNdx, Sec, + /*SymTab=*/nullptr); break; } case ELF::SHT_ANDROID_REL: case ELF::SHT_ANDROID_RELA: if (Expected> RelasOrErr = Obj.android_relas(Sec)) { for (const Elf_Rela &R : *RelasOrErr) - printReloc(Relocation(R, IsMips64EL), ++RelNdx, Sec, SymTab); + RelRelaFn(Relocation(R, IsMips64EL), ++RelNdx, Sec, SymTab); } else { Warn(RelasOrErr.takeError()); } @@ -5849,7 +5863,7 @@ } uint64_t Addend = Data.getAddress(&Offset); - uint64_t SymValue = Resolver(Reloc, RelocSymValue, Addend); + uint64_t SymValue = resolveRelocation(Resolver, Reloc, RelocSymValue, Addend); this->printFunctionStackSize(SymValue, FunctionSec, StackSizeSec, Data, &Offset); } @@ -5947,7 +5961,8 @@ // described in it. const Elf_Shdr *FunctionSec = unwrapOrError( this->FileName, Obj.getSection(StackSizesELFSec->sh_link)); - bool (*IsSupportedFn)(uint64_t); + + SupportsRelocation IsSupportedFn; RelocationResolver Resolver; std::tie(IsSupportedFn, Resolver) = getRelocationResolver(ElfObj); ArrayRef Contents = @@ -6275,7 +6290,11 @@ unsigned SecNdx = &Sec - &cantFail(this->Obj.sections()).front(); W.startLine() << "Section (" << SecNdx << ") " << Name << " {\n"; W.indent(); - this->printRelocationsHelper(Sec); + this->forEachRelocationDo( + Sec, opts::RawRelr, + [&](const Relocation &R, unsigned Ndx, const Elf_Shdr &Sec, + const Elf_Shdr *SymTab) { printReloc(R, Ndx, Sec, SymTab); }, + [&](const Elf_Relr &R) { printRelrReloc(R); }); W.unindent(); W.startLine() << "}\n"; } @@ -6346,7 +6365,11 @@ if (opts::SectionRelocations) { ListScope D(W, "Relocations"); - this->printRelocationsHelper(Sec); + this->forEachRelocationDo( + Sec, opts::RawRelr, + [&](const Relocation &R, unsigned Ndx, const Elf_Shdr &Sec, + const Elf_Shdr *SymTab) { printReloc(R, Ndx, Sec, SymTab); }, + [&](const Elf_Relr &R) { printRelrReloc(R); }); } if (opts::SectionSymbols) {