Index: ELF/Target.h =================================================================== --- ELF/Target.h +++ ELF/Target.h @@ -135,6 +135,7 @@ template TargetInfo *getMipsTargetInfo(); std::string getErrorLocation(const uint8_t *Loc); +InputSectionBase *getErrorSection(const uint8_t *Loc); uint64_t getPPC64TocBase(); uint64_t getAArch64Page(uint64_t Expr); @@ -146,9 +147,17 @@ static inline void reportRangeError(uint8_t *Loc, RelType Type, const Twine &V, int64_t Min, uint64_t Max) { - error(getErrorLocation(Loc) + "relocation " + lld::toString(Type) + - " out of range: " + V + " is not in [" + Twine(Min) + ", " + - Twine(Max) + "]"); + std::string Msg = getErrorLocation(Loc) + + ("relocation " + lld::toString(Type) + " out of range: " + + V + " is not in [" + Twine(Min) + ", " + Twine(Max) + "]") + .str(); + + InputSectionBase *IS = getErrorSection(Loc); + if (IS && IS->Name.startswith(".debug")) + Msg += "; consider recompiling with -fdebug-types-section to reduce size " + "of debug sections"; + + error(Msg); } template Index: ELF/Target.cpp =================================================================== --- ELF/Target.cpp +++ ELF/Target.cpp @@ -87,7 +87,9 @@ fatal("unknown target machine"); } -template static std::string getErrorLoc(const uint8_t *Loc) { +// For given location in output file returns input section and offset. +Optional> +getErrorInfo(const uint8_t *Loc) { for (InputSectionBase *D : InputSections) { auto *IS = dyn_cast(D); if (!IS || !IS->getParent()) @@ -95,11 +97,23 @@ uint8_t *ISLoc = IS->getParent()->Loc + IS->OutSecOff; if (ISLoc <= Loc && Loc < ISLoc + IS->getSize()) - return IS->template getLocation(Loc - ISLoc) + ": "; + return std::make_pair(IS, Loc - ISLoc); } + return None; +} + +template static std::string getErrorLoc(const uint8_t *Loc) { + if (Optional> Err = getErrorInfo(Loc)) + return Err->first->template getLocation(Err->second) + ": "; return ""; } +InputSectionBase *elf::getErrorSection(const uint8_t *Loc) { + if (Optional> Err = getErrorInfo(Loc)) + return Err->first; + return nullptr; +} + std::string elf::getErrorLocation(const uint8_t *Loc) { switch (Config->EKind) { case ELF32LEKind: Index: test/ELF/x86-64-reloc-debug-overflow.s =================================================================== --- test/ELF/x86-64-reloc-debug-overflow.s +++ test/ELF/x86-64-reloc-debug-overflow.s @@ -0,0 +1,12 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/x86-64-reloc-error.s -o %tabs +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t +# RUN: not ld.lld -shared %tabs %t -o %t2 2>&1 | FileCheck %s + +# CHECK: (.debug_info+0x1): relocation R_X86_64_32 out of range: 68719476736 is not in [0, 4294967295]; consider recompiling with -fdebug-types-section to reduce size of debug sections + +# CHECK: (.debug_info+0x8): relocation R_X86_64_32S out of range: -281474976710656 is not in [-2147483648, 2147483647]; consider recompiling with -fdebug-types-section to reduce size of debug sections + +.section .debug_info,"",@progbits + movl $big, %edx + movq $foo - 0x1000000000000, %rdx