Index: lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.h =================================================================== --- lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.h +++ lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.h @@ -21,9 +21,6 @@ class AArch64TargetRelocationHandler final : public TargetRelocationHandler { public: - AArch64TargetRelocationHandler(ELFLinkingContext &targetInfo) - : TargetRelocationHandler(targetInfo) {} - std::error_code applyRelocation(ELFWriter &, llvm::FileOutputBuffer &, const lld::AtomLayout &, const Reference &) const override; Index: lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.cpp =================================================================== --- lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.cpp +++ lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.cpp @@ -462,7 +462,7 @@ targetVAddress, ref.addend()); break; default: - unhandledReferenceType(*atom._atom, ref); + return make_unhandled_reloc_error(); } return std::error_code(); Index: lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.cpp =================================================================== --- lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.cpp +++ lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.cpp @@ -19,8 +19,7 @@ AArch64TargetHandler::AArch64TargetHandler(AArch64LinkingContext &context) : DefaultTargetHandler(context), _context(context), _AArch64TargetLayout(new AArch64TargetLayout(context)), - _AArch64RelocationHandler( - new AArch64TargetRelocationHandler(context)) {} + _AArch64RelocationHandler(new AArch64TargetRelocationHandler()) {} 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,10 +21,8 @@ class HexagonTargetRelocationHandler final : public TargetRelocationHandler { public: - HexagonTargetRelocationHandler(HexagonTargetLayout &layout, - ELFLinkingContext &targetInfo) - : TargetRelocationHandler(targetInfo), - _hexagonTargetLayout(layout) {} + HexagonTargetRelocationHandler(HexagonTargetLayout &layout) + : _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 @@ -344,7 +344,7 @@ break; default: - unhandledReferenceType(*atom._atom, ref); + return make_unhandled_reloc_error(); } 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,7 @@ _hexagonRuntimeFile(new HexagonRuntimeFile(context)), _hexagonTargetLayout(new HexagonTargetLayout(context)), _hexagonRelocationHandler(new HexagonTargetRelocationHandler( - *_hexagonTargetLayout.get(), context)) {} + *_hexagonTargetLayout.get())) {} 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,10 +19,8 @@ class MipsTargetRelocationHandler final : public TargetRelocationHandler { public: - MipsTargetRelocationHandler(MipsTargetLayout &layout, - ELFLinkingContext &targetInfo) - : TargetRelocationHandler(targetInfo), - _mipsTargetLayout(layout) {} + MipsTargetRelocationHandler(MipsTargetLayout &layout) + : _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 @@ -341,7 +341,7 @@ // Do nothing. break; default: - unhandledReferenceType(*atom._atom, ref); + return make_unhandled_reloc_error(); } if (shuffle) 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, ctx)) {} + _relocationHandler(new MipsTargetRelocationHandler(*_targetLayout)) {} 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,10 +26,8 @@ class PPCTargetRelocationHandler final : public TargetRelocationHandler { public: - PPCTargetRelocationHandler(ELFLinkingContext &context, - PPCTargetLayout &layout) - : TargetRelocationHandler(context), - _ppcTargetLayout(layout) {} + PPCTargetRelocationHandler(PPCTargetLayout &layout) + : _ppcTargetLayout(layout) {} virtual std::error_code applyRelocation(ELFWriter &, llvm::FileOutputBuffer &, const lld::AtomLayout &, Index: lib/ReaderWriter/ELF/PPC/PPCTargetHandler.cpp =================================================================== --- lib/ReaderWriter/ELF/PPC/PPCTargetHandler.cpp +++ lib/ReaderWriter/ELF/PPC/PPCTargetHandler.cpp @@ -52,7 +52,7 @@ break; default: - unhandledReferenceType(*atom._atom, ref); + return make_unhandled_reloc_error(); } return std::error_code(); @@ -62,7 +62,7 @@ : DefaultTargetHandler(context), _ppcLinkingContext(context), _ppcTargetLayout(new PPCTargetLayout(context)), _ppcRelocationHandler( - new PPCTargetRelocationHandler(context, *_ppcTargetLayout.get())) {} + new PPCTargetRelocationHandler(*_ppcTargetLayout.get())) {} void PPCTargetHandler::registerRelocationNames(Registry ®istry) { registry.addKindTable(Reference::KindNamespace::ELF, Index: lib/ReaderWriter/ELF/SectionChunks.h =================================================================== --- lib/ReaderWriter/ELF/SectionChunks.h +++ lib/ReaderWriter/ELF/SectionChunks.h @@ -28,6 +28,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileOutputBuffer.h" #include +#include namespace lld { namespace elf { @@ -269,6 +270,31 @@ int32_t _contentPermissions; bool _isLoadedInMemory; std::vector _atoms; + mutable std::mutex _outputMutex; + + void printError(const std::string &errorStr, const AtomLayout &atom, + const Reference &ref) const { + StringRef kindValStr; + if (!this->_context.registry().referenceKindToString(ref.kindNamespace(), + ref.kindArch(), + ref.kindValue(), + kindValStr)) { + kindValStr = "unknown"; + } + + std::string errStr = (Twine(errorStr) + " in file " + + atom._atom->file().path() + + ": reference from " + atom._atom->name() + + "+" + Twine(ref.offsetInAtom()) + + " to " + ref.target()->name() + + "+" + Twine(ref.addend()) + + " of type " + Twine(ref.kindValue()) + + " (" + kindValStr + ")\n").str(); + + // Take the lock to prevent output getting interleaved between threads + std::lock_guard lock(_outputMutex); + llvm::errs() << errStr; + } }; /// Align the offset to the required modulus defined by the atom alignment @@ -377,6 +403,7 @@ void AtomSection::write(ELFWriter *writer, TargetLayout &layout, llvm::FileOutputBuffer &buffer) { uint8_t *chunkBuffer = buffer.getBufferStart(); + bool success = true; parallel_for_each(_atoms.begin(), _atoms.end(), [&](lld::AtomLayout * ai) { DEBUG_WITH_TYPE("Section", llvm::dbgs() << "Writing atom: " << ai->_atom->name() @@ -393,9 +420,16 @@ std::memcpy(atomContent, content.data(), contentSize); const TargetRelocationHandler &relHandler = this->_context.template getTargetHandler().getRelocationHandler(); - for (const auto ref : *definedAtom) - relHandler.applyRelocation(*writer, buffer, *ai, *ref); + for (const auto ref : *definedAtom) { + if (std::error_code EC = relHandler.applyRelocation(*writer, buffer, + *ai, *ref)) { + printError(EC.message(), *ai, *ref); + success = false; + } + } }); + if (success == false) + llvm::report_fatal_error("relocating output"); } /// \brief A OutputSection represents a set of sections grouped by the same Index: lib/ReaderWriter/ELF/TargetHandler.h =================================================================== --- lib/ReaderWriter/ELF/TargetHandler.h +++ lib/ReaderWriter/ELF/TargetHandler.h @@ -42,35 +42,11 @@ 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 @@ -100,6 +76,15 @@ private: ELFLinkingContext &_context; }; + +inline std::error_code make_unhandled_reloc_error() { + return make_dynamic_error_code(Twine("Unhandled reference type")); +} + +inline std::error_code make_out_of_range_reloc_error() { + return make_dynamic_error_code(Twine("Relocation out of range")); +} + } // end namespace elf } // end namespace lld Index: lib/ReaderWriter/ELF/X86/X86RelocationHandler.h =================================================================== --- lib/ReaderWriter/ELF/X86/X86RelocationHandler.h +++ lib/ReaderWriter/ELF/X86/X86RelocationHandler.h @@ -20,9 +20,6 @@ class X86TargetRelocationHandler final : public TargetRelocationHandler { public: - X86TargetRelocationHandler(ELFLinkingContext &targetInfo) - : TargetRelocationHandler(targetInfo) {} - std::error_code applyRelocation(ELFWriter &, llvm::FileOutputBuffer &, const lld::AtomLayout &, const Reference &) const override; Index: lib/ReaderWriter/ELF/X86/X86RelocationHandler.cpp =================================================================== --- lib/ReaderWriter/ELF/X86/X86RelocationHandler.cpp +++ lib/ReaderWriter/ELF/X86/X86RelocationHandler.cpp @@ -52,7 +52,7 @@ relocPC32(location, relocVAddress, targetVAddress, ref.addend()); break; default: - unhandledReferenceType(*atom._atom, ref); + return make_unhandled_reloc_error(); } return std::error_code(); Index: lib/ReaderWriter/ELF/X86/X86TargetHandler.cpp =================================================================== --- lib/ReaderWriter/ELF/X86/X86TargetHandler.cpp +++ lib/ReaderWriter/ELF/X86/X86TargetHandler.cpp @@ -50,5 +50,4 @@ X86TargetHandler::X86TargetHandler(X86LinkingContext &context) : DefaultTargetHandler(context), _x86LinkingContext(context), _x86TargetLayout(new X86TargetLayout(context)), - _x86RelocationHandler( - new X86TargetRelocationHandler(context)) {} + _x86RelocationHandler(new X86TargetRelocationHandler()) {} 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,10 +21,8 @@ class X86_64TargetRelocationHandler final : public TargetRelocationHandler { public: - X86_64TargetRelocationHandler(X86_64TargetLayout &layout, - ELFLinkingContext &targetInfo) - : TargetRelocationHandler(targetInfo), - _tlsSize(0), _x86_64Layout(layout) {} + X86_64TargetRelocationHandler(X86_64TargetLayout &layout) + : _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 @@ -123,7 +123,7 @@ case R_X86_64_DTPOFF64: break; default: - unhandledReferenceType(*atom._atom, ref); + return make_unhandled_reloc_error(); } 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,8 +20,7 @@ : DefaultTargetHandler(context), _context(context), _x86_64TargetLayout(new X86_64TargetLayout(context)), _x86_64RelocationHandler( - new X86_64TargetRelocationHandler(*_x86_64TargetLayout.get(), - context)) {} + new X86_64TargetRelocationHandler(*_x86_64TargetLayout.get())) {} void X86_64TargetHandler::registerRelocationNames(Registry ®istry) { registry.addKindTable(Reference::KindNamespace::ELF,