Index: include/llvm/Object/RelocVisitor.h =================================================================== --- include/llvm/Object/RelocVisitor.h +++ include/llvm/Object/RelocVisitor.h @@ -35,52 +35,58 @@ /// @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 = getELFVisitor(); + 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 Rel, RelocationRef R, uint64_t Value = 0) { - if (isa(ObjToVisit)) - return visitELF(Rel, R, Value); - if (isa(ObjToVisit)) - return visitCOFF(Rel, R, Value); - if (isa(ObjToVisit)) - return visitMachO(Rel, R, Value); - - HasError = true; - return 0; + return (this->*Vis)(Rel, R, Value); } bool error() { return HasError; } + void clearError() { HasError = false; }; private: + typedef uint64_t (RelocVisitor::*Visitor)(uint32_t RelocType, RelocationRef R, + uint64_t Value); + Visitor Vis; + const ObjectFile &ObjToVisit; bool HasError = false; - uint64_t visitELF(uint32_t Rel, RelocationRef R, uint64_t Value) { + Visitor getELFVisitor() { if (ObjToVisit.getBytesInAddress() == 8) { // 64-bit object file switch (ObjToVisit.getArch()) { case Triple::x86_64: - return visitX86_64(Rel, R, Value); + return &RelocVisitor::visitX86_64; case Triple::aarch64: case Triple::aarch64_be: - return visitAarch64(Rel, R, Value); + return &RelocVisitor::visitAarch64; case Triple::bpfel: case Triple::bpfeb: - return visitBpf(Rel, R, Value); + return &RelocVisitor::visitBpf; case Triple::mips64el: case Triple::mips64: - return visitMips64(Rel, R, Value); + return &RelocVisitor::visitMips64; case Triple::ppc64le: case Triple::ppc64: - return visitPPC64(Rel, R, Value); + return &RelocVisitor::visitPPC64; case Triple::systemz: - return visitSystemz(Rel, R, Value); + return &RelocVisitor::visitSystemz; case Triple::sparcv9: - return visitSparc64(Rel, R, Value); + return &RelocVisitor::visitSparc64; case Triple::amdgcn: - return visitAmdgpu(Rel, R, Value); + return &RelocVisitor::visitAmdgpu; default: HasError = true; return 0; @@ -93,21 +99,21 @@ switch (ObjToVisit.getArch()) { case Triple::x86: - return visitX86(Rel, R, Value); + return &RelocVisitor::visitX86; case Triple::ppc: - return visitPPC32(Rel, R, Value); + return &RelocVisitor::visitPPC32; case Triple::arm: case Triple::armeb: - return visitARM(Rel, R, Value); + return &RelocVisitor::visitARM; case Triple::lanai: - return visitLanai(Rel, R, Value); + return &RelocVisitor::visitLanai; case Triple::mipsel: case Triple::mips: - return visitMips32(Rel, R, Value); + return &RelocVisitor::visitMips32; case Triple::sparc: - return visitSparc32(Rel, R, Value); + return &RelocVisitor::visitSparc32; case Triple::hexagon: - return visitHexagon(Rel, R, Value); + return &RelocVisitor::visitHexagon; default: HasError = true; return 0; 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.clearError(); continue; } Map->insert({Reloc.getOffset(), {Val}});