Index: lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.h =================================================================== --- lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.h +++ lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.h @@ -21,7 +21,7 @@ class AArch64TargetRelocationHandler final : public TargetRelocationHandler { public: - AArch64TargetRelocationHandler() {} + using TargetRelocationHandler::TargetRelocationHandler; std::error_code applyRelocation(ELFWriter &, llvm::FileOutputBuffer &, const lld::AtomLayout &, Index: lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.cpp =================================================================== --- lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.cpp +++ lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.cpp @@ -461,15 +461,8 @@ relocR_AARCH64_TLSLE_ADD_TPREL_LO12_NC(location, relocVAddress, targetVAddress, ref.addend()); break; - default: { - std::string str; - llvm::raw_string_ostream s(str); - s << "Unhandled relocation: " << atom._atom->file().path() << ":" - << atom._atom->name() << "@" << ref.offsetInAtom() << " " - << "#" << ref.kindValue(); - s.flush(); - llvm_unreachable(str.c_str()); - } + default: + unhandledReferenceType(*atom._atom, ref); } return std::error_code(); Index: lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.cpp =================================================================== --- lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.cpp +++ lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.cpp @@ -156,8 +156,6 @@ case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: static_cast(this)->handleGOT(ref); break; - default: - llvm_unreachable("Unhandled type in handleReference"); } } Index: lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.cpp =================================================================== --- lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.cpp +++ lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.cpp @@ -20,7 +20,7 @@ : DefaultTargetHandler(context), _context(context), _AArch64TargetLayout(new AArch64TargetLayout(context)), _AArch64RelocationHandler( - new AArch64TargetRelocationHandler()) {} + new AArch64TargetRelocationHandler(context)) {} void AArch64TargetHandler::registerRelocationNames(Registry ®istry) { registry.addKindTable(Reference::KindNamespace::ELF, Index: lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.h =================================================================== --- lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.h +++ lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.h @@ -21,8 +21,10 @@ class HexagonTargetRelocationHandler final : public TargetRelocationHandler { public: - HexagonTargetRelocationHandler(HexagonTargetLayout &layout) - : _hexagonTargetLayout(layout) {} + HexagonTargetRelocationHandler(HexagonTargetLayout &layout, + ELFLinkingContext &targetInfo) + : TargetRelocationHandler(targetInfo), + _hexagonTargetLayout(layout) {} std::error_code applyRelocation(ELFWriter &, llvm::FileOutputBuffer &, const lld::AtomLayout &, Index: lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp =================================================================== --- lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp +++ lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp @@ -343,13 +343,8 @@ ref.addend(), _hexagonTargetLayout.getGOTSymAddr()); break; - default : { - std::string str; - llvm::raw_string_ostream s(str); - s << "Unhandled Hexagon relocation: #" << ref.kindValue(); - s.flush(); - llvm_unreachable(str.c_str()); - } + default: + unhandledReferenceType(*atom._atom, ref); } return std::error_code(); Index: lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp =================================================================== --- lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp +++ lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp @@ -23,7 +23,8 @@ _hexagonRuntimeFile(new HexagonRuntimeFile(context)), _hexagonTargetLayout(new HexagonTargetLayout(context)), _hexagonRelocationHandler( - new HexagonTargetRelocationHandler(*_hexagonTargetLayout.get())) {} + new HexagonTargetRelocationHandler(*_hexagonTargetLayout.get(), + context)) {} std::unique_ptr HexagonTargetHandler::getWriter() { switch (_hexagonLinkingContext.getOutputELFType()) { Index: lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.h =================================================================== --- lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.h +++ lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.h @@ -19,8 +19,10 @@ class MipsTargetRelocationHandler final : public TargetRelocationHandler { public: - MipsTargetRelocationHandler(MipsTargetLayout &layout) - : _mipsTargetLayout(layout) {} + MipsTargetRelocationHandler(MipsTargetLayout &layout, + ELFLinkingContext &targetInfo) + : TargetRelocationHandler(targetInfo), + _mipsTargetLayout(layout) {} std::error_code applyRelocation(ELFWriter &, llvm::FileOutputBuffer &, const lld::AtomLayout &, Index: lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp =================================================================== --- lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp +++ lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp @@ -179,12 +179,8 @@ case LLD_R_MIPS_STO_PLT: // Do nothing. break; - default: { - std::string str; - llvm::raw_string_ostream s(str); - s << "Unhandled Mips relocation: " << ref.kindValue(); - llvm_unreachable(s.str().c_str()); - } + default: + unhandledReferenceType(*atom._atom, ref); } endian::write(location, ins); Index: lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp =================================================================== --- lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp +++ lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp @@ -22,7 +22,7 @@ : DefaultTargetHandler(ctx), _ctx(ctx), _runtimeFile(new MipsRuntimeFile(ctx)), _targetLayout(new MipsTargetLayout(ctx)), - _relocationHandler(new MipsTargetRelocationHandler(*_targetLayout)) {} + _relocationHandler(new MipsTargetRelocationHandler(*_targetLayout, ctx)) {} std::unique_ptr MipsTargetHandler::getWriter() { switch (_ctx.getOutputELFType()) { Index: lib/ReaderWriter/ELF/PPC/PPCTargetHandler.h =================================================================== --- lib/ReaderWriter/ELF/PPC/PPCTargetHandler.h +++ lib/ReaderWriter/ELF/PPC/PPCTargetHandler.h @@ -26,16 +26,16 @@ class PPCTargetRelocationHandler final : public TargetRelocationHandler { public: - PPCTargetRelocationHandler(PPCLinkingContext &context, + PPCTargetRelocationHandler(ELFLinkingContext &context, PPCTargetLayout &layout) - : _ppcContext(context), _ppcTargetLayout(layout) {} + : TargetRelocationHandler(context), + _ppcTargetLayout(layout) {} virtual std::error_code applyRelocation(ELFWriter &, llvm::FileOutputBuffer &, const lld::AtomLayout &, const Reference &) const override; protected: - PPCLinkingContext &_ppcContext; PPCTargetLayout &_ppcTargetLayout; }; Index: lib/ReaderWriter/ELF/PPC/PPCTargetHandler.cpp =================================================================== --- lib/ReaderWriter/ELF/PPC/PPCTargetHandler.cpp +++ lib/ReaderWriter/ELF/PPC/PPCTargetHandler.cpp @@ -51,13 +51,8 @@ relocB24PCREL(location, relocVAddress, targetVAddress, ref.addend()); break; - default : { - std::string str; - llvm::raw_string_ostream s(str); - s << "Unhandled PowerPC relocation: #" << ref.kindValue(); - s.flush(); - llvm_unreachable(str.c_str()); - } + default: + unhandledReferenceType(*atom._atom, ref); } return std::error_code(); Index: lib/ReaderWriter/ELF/TargetHandler.h =================================================================== --- lib/ReaderWriter/ELF/TargetHandler.h +++ lib/ReaderWriter/ELF/TargetHandler.h @@ -17,11 +17,14 @@ #define LLD_READER_WRITER_ELF_TARGET_HANDLER_H #include "Layout.h" +#include "lld/Core/Atom.h" #include "lld/Core/LLVM.h" #include "lld/Core/LinkingContext.h" #include "lld/Core/STDExtras.h" #include "lld/ReaderWriter/ELFLinkingContext.h" #include "llvm/ADT/Hashing.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileOutputBuffer.h" #include #include @@ -39,11 +42,35 @@ template class TargetRelocationHandler { public: + /// Constructor + TargetRelocationHandler(ELFLinkingContext &targetInfo) + : _context(targetInfo) {} + virtual std::error_code applyRelocation(ELFWriter &, llvm::FileOutputBuffer &, const lld::AtomLayout &, const Reference &) const = 0; + void unhandledReferenceType(const Atom &atom, const Reference &ref) const { + llvm::errs() << "Unhandled reference type in file " << atom.file().path() + << ": reference from " << atom.name() << "+" + << ref.offsetInAtom() << " to " << ref.target()->name() + << "+" << ref.addend() << " of type "; + + StringRef kindValStr; + if (!_context.registry().referenceKindToString(ref.kindNamespace(), + ref.kindArch(), + ref.kindValue(), + kindValStr)) { + kindValStr = "unknown"; + } + + llvm::errs() << ref.kindValue() << " (" << kindValStr << ")\n"; + llvm::report_fatal_error("unhandled reference type"); + } + virtual ~TargetRelocationHandler() {} +private: + ELFLinkingContext &_context; }; /// \brief TargetHandler contains all the information responsible to handle a Index: lib/ReaderWriter/ELF/X86/X86RelocationHandler.h =================================================================== --- lib/ReaderWriter/ELF/X86/X86RelocationHandler.h +++ lib/ReaderWriter/ELF/X86/X86RelocationHandler.h @@ -20,7 +20,7 @@ class X86TargetRelocationHandler final : public TargetRelocationHandler { public: - X86TargetRelocationHandler(X86TargetLayout &) {} + using TargetRelocationHandler::TargetRelocationHandler; std::error_code applyRelocation(ELFWriter &, llvm::FileOutputBuffer &, const lld::AtomLayout &, Index: lib/ReaderWriter/ELF/X86/X86RelocationHandler.cpp =================================================================== --- lib/ReaderWriter/ELF/X86/X86RelocationHandler.cpp +++ lib/ReaderWriter/ELF/X86/X86RelocationHandler.cpp @@ -51,13 +51,8 @@ case R_386_PC32: relocPC32(location, relocVAddress, targetVAddress, ref.addend()); break; - default: { - std::string str; - llvm::raw_string_ostream s(str); - s << "Unhandled I386 relocation # " << ref.kindValue(); - s.flush(); - llvm_unreachable(str.c_str()); - } + default: + unhandledReferenceType(*atom._atom, ref); } return std::error_code(); Index: lib/ReaderWriter/ELF/X86/X86TargetHandler.cpp =================================================================== --- lib/ReaderWriter/ELF/X86/X86TargetHandler.cpp +++ lib/ReaderWriter/ELF/X86/X86TargetHandler.cpp @@ -87,4 +87,4 @@ : DefaultTargetHandler(context), _x86LinkingContext(context), _x86TargetLayout(new X86TargetLayout(context)), _x86RelocationHandler( - new X86TargetRelocationHandler(*_x86TargetLayout.get())) {} + new X86TargetRelocationHandler(context)) {} Index: lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.h =================================================================== --- lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.h +++ lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.h @@ -21,8 +21,10 @@ class X86_64TargetRelocationHandler final : public TargetRelocationHandler { public: - X86_64TargetRelocationHandler(X86_64TargetLayout &layout) - : _tlsSize(0), _x86_64Layout(layout) {} + X86_64TargetRelocationHandler(X86_64TargetLayout &layout, + ELFLinkingContext &targetInfo) + : TargetRelocationHandler(targetInfo), + _tlsSize(0), _x86_64Layout(layout) {} std::error_code applyRelocation(ELFWriter &, llvm::FileOutputBuffer &, const lld::AtomLayout &, Index: lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp =================================================================== --- lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp +++ lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp @@ -122,15 +122,8 @@ case R_X86_64_DTPMOD64: case R_X86_64_DTPOFF64: break; - default: { - std::string str; - llvm::raw_string_ostream s(str); - s << "Unhandled relocation: " << atom._atom->file().path() << ":" - << atom._atom->name() << "@" << ref.offsetInAtom() << " " - << "#" << ref.kindValue(); - s.flush(); - llvm_unreachable(str.c_str()); - } + default: + unhandledReferenceType(*atom._atom, ref); } return std::error_code(); Index: lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp =================================================================== --- lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp +++ lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp @@ -20,7 +20,8 @@ : DefaultTargetHandler(context), _context(context), _x86_64TargetLayout(new X86_64TargetLayout(context)), _x86_64RelocationHandler( - new X86_64TargetRelocationHandler(*_x86_64TargetLayout.get())) {} + new X86_64TargetRelocationHandler(*_x86_64TargetLayout.get(), + context)) {} void X86_64TargetHandler::registerRelocationNames(Registry ®istry) { registry.addKindTable(Reference::KindNamespace::ELF, Index: test/elf/AArch64/rel-bad.test =================================================================== --- /dev/null +++ test/elf/AArch64/rel-bad.test @@ -0,0 +1,44 @@ +# Check handling of a bad relocation (in this case dynamic in a static object). +# RUN: yaml2obj -format=elf %s > %t-obj +# RUN: not lld -flavor gnu -target arm64 -o %t-exe %t-obj 2>&1 | FileCheck %s + +# CHECK: Unhandled reference type in file {{.*}}: reference from data1+4 to data1+0 of type 1024 (R_AARCH64_COPY) + +!ELF +FileHeader: !FileHeader + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_AARCH64 + +Sections: +- Name: .text + Type: SHT_PROGBITS + Content: "00000000" + AddressAlign: 16 + Flags: [SHF_ALLOC, SHF_EXECINSTR] +- Name: .data + Type: SHT_PROGBITS + Content: "0000000000000000" + AddressAlign: 16 + Flags: [SHF_ALLOC, SHF_WRITE] + +- Name: .rela.data + Type: SHT_RELA + Info: .data + AddressAlign: 8 + Relocations: + - Offset: 0x4 + Symbol: data1 + Type: R_AARCH64_COPY + Addend: 0 + +Symbols: + Global: + - Name: _start + Section: .text + Value: 0x0 + Size: 4 + - Name: data1 + Section: .data + Size: 8