Index: include/llvm/Object/RelocVisitor.h =================================================================== --- include/llvm/Object/RelocVisitor.h +++ include/llvm/Object/RelocVisitor.h @@ -35,48 +35,63 @@ /// @brief Base class for object file relocation visitors. class RelocVisitor { public: - explicit RelocVisitor(const ObjectFile &Obj) : ObjToVisit(Obj) {} + explicit RelocVisitor(const ObjectFile &Obj) : ObjToVisit(Obj) { + if (isa(ObjToVisit)) + Vis = createELFVisitor(); + else if (isa(ObjToVisit)) + Vis = &RelocVisitor::visitCOFF; + else if (isa(ObjToVisit)) + Vis = &RelocVisitor::visitMachO; + else + llvm_unreachable("unable to create relocation visitor"); + } // TODO: Should handle multiple applied relocations via either passing in the // previously computed value or just count paired relocations as a single // visit. uint64_t visit(uint32_t RelocType, RelocationRef R, uint64_t Value = 0) { - if (isa(ObjToVisit)) - return visitELF(RelocType, R, Value); - if (isa(ObjToVisit)) - return visitCOFF(RelocType, R, Value); - if (isa(ObjToVisit)) - return visitMachO(RelocType, R, Value); - - HasError = true; - return 0; + return (this->*Vis)(RelocType, R, Value); } bool error() { return HasError; } + void dropError() { HasError = false; }; private: + typedef uint64_t (RelocVisitor::*Visitor)(uint32_t RelocType, RelocationRef R, + uint64_t Value); + Visitor Vis; + const ObjectFile &ObjToVisit; bool HasError = false; + Visitor createELFVisitor() { + if (ObjToVisit.getArch() == Triple::x86_64) + return &RelocVisitor::visitELF_x86_64; + return &RelocVisitor::visitELF; + } + + uint64_t visitELF_x86_64(uint32_t RelocType, RelocationRef R, + uint64_t Value) { + switch (RelocType) { + case ELF::R_X86_64_NONE: + return 0; + case ELF::R_X86_64_64: + return Value + getELFAddend(R); + case ELF::R_X86_64_PC32: + return Value + getELFAddend(R) - R.getOffset(); + case ELF::R_X86_64_32: + return (Value + getELFAddend(R)) & 0xFFFFFFFF; + case ELF::R_X86_64_32S: + return (Value + getELFAddend(R)) & 0xFFFFFFFF; + default: + HasError = true; + return 0; + } + } + uint64_t visitELF(uint32_t RelocType, RelocationRef R, uint64_t Value) { if (ObjToVisit.getBytesInAddress() == 8) { // 64-bit object file switch (ObjToVisit.getArch()) { - case Triple::x86_64: - switch (RelocType) { - case ELF::R_X86_64_NONE: - return visitELF_X86_64_NONE(R); - case ELF::R_X86_64_64: - return visitELF_X86_64_64(R, Value); - case ELF::R_X86_64_PC32: - return visitELF_X86_64_PC32(R, Value); - case ELF::R_X86_64_32: - return visitELF_X86_64_32(R, Value); - case ELF::R_X86_64_32S: - return visitELF_X86_64_32S(R, Value); - default: - HasError = true; - return 0; - } case Triple::aarch64: case Triple::aarch64_be: switch (RelocType) { @@ -292,27 +307,6 @@ return Value - R.getOffset(); } - /// X86-64 ELF - uint64_t visitELF_X86_64_NONE(RelocationRef R) { - return 0; - } - - uint64_t visitELF_X86_64_64(RelocationRef R, uint64_t Value) { - return Value + getELFAddend(R); - } - - uint64_t visitELF_X86_64_PC32(RelocationRef R, uint64_t Value) { - return Value + getELFAddend(R) - R.getOffset(); - } - - uint64_t visitELF_X86_64_32(RelocationRef R, uint64_t Value) { - return (Value + getELFAddend(R)) & 0xFFFFFFFF; - } - - uint64_t visitELF_X86_64_32S(RelocationRef R, uint64_t Value) { - return (Value + getELFAddend(R)) & 0xFFFFFFFF; - } - /// BPF ELF uint64_t visitELF_BPF_64_32(RelocationRef R, uint64_t Value) { return Value & 0xFFFFFFFF; Index: lib/DebugInfo/DWARF/DWARFContext.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFContext.cpp +++ lib/DebugInfo/DWARF/DWARFContext.cpp @@ -1048,6 +1048,7 @@ const LoadedObjectInfo *L) : FileName(Obj.getFileName()), IsLittleEndian(Obj.isLittleEndian()), AddressSize(Obj.getBytesInAddress()) { + object::RelocVisitor V(Obj); for (const SectionRef &Section : Obj.sections()) { StringRef name; Section.getName(name); @@ -1161,12 +1162,12 @@ continue; } - object::RelocVisitor V(Obj); uint64_t Val = V.visit(Reloc.getType(), Reloc, *SymAddrOrErr); if (V.error()) { SmallString<32> Name; Reloc.getTypeName(Name); errs() << "error: failed to compute relocation: " << Name << "\n"; + V.dropError(); continue; } Map->insert({Reloc.getOffset(), {Val}});