Index: ELF/Arch/AArch64.cpp =================================================================== --- ELF/Arch/AArch64.cpp +++ ELF/Arch/AArch64.cpp @@ -337,7 +337,7 @@ or32AArch64Imm(Loc, Val); break; default: - error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type)); + error(getErrorLocation(Loc).Loc + "unrecognized reloc " + Twine(Type)); } } Index: ELF/Arch/AMDGPU.cpp =================================================================== --- ELF/Arch/AMDGPU.cpp +++ ELF/Arch/AMDGPU.cpp @@ -73,7 +73,7 @@ write32le(Loc, Val >> 32); break; default: - error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type)); + error(getErrorLocation(Loc).Loc + "unrecognized reloc " + Twine(Type)); } } Index: ELF/Arch/ARM.cpp =================================================================== --- ELF/Arch/ARM.cpp +++ ELF/Arch/ARM.cpp @@ -440,7 +440,7 @@ (Val & 0x00ff)); // imm8 break; default: - error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type)); + error(getErrorLocation(Loc).Loc + "unrecognized reloc " + Twine(Type)); } } Index: ELF/Arch/AVR.cpp =================================================================== --- ELF/Arch/AVR.cpp +++ ELF/Arch/AVR.cpp @@ -64,7 +64,7 @@ break; } default: - error(getErrorLocation(Loc) + "unrecognized reloc " + toString(Type)); + error(getErrorLocation(Loc).Loc + "unrecognized reloc " + toString(Type)); } } Index: ELF/Arch/Mips.cpp =================================================================== --- ELF/Arch/Mips.cpp +++ ELF/Arch/Mips.cpp @@ -458,7 +458,7 @@ if (Type2 == R_MICROMIPS_SUB && (Type3 == R_MICROMIPS_HI16 || Type3 == R_MICROMIPS_LO16)) return std::make_pair(Type3, -Val); - error(getErrorLocation(Loc) + "unsupported relocations combination " + + error(getErrorLocation(Loc).Loc + "unsupported relocations combination " + Twine(Type)); return std::make_pair(Type & 0xff, Val); } @@ -645,7 +645,7 @@ writeMicroRelocation32(Loc, Val, 23, 2); break; default: - error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type)); + error(getErrorLocation(Loc).Loc +"unrecognized reloc " + Twine(Type)); } } Index: ELF/Arch/PPC.cpp =================================================================== --- ELF/Arch/PPC.cpp +++ ELF/Arch/PPC.cpp @@ -58,7 +58,7 @@ write32be(Loc, read32be(Loc) | (Val & 0x3FFFFFC)); break; default: - error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type)); + error(getErrorLocation(Loc).Loc + "unrecognized reloc " + Twine(Type)); } } Index: ELF/Arch/PPC64.cpp =================================================================== --- ELF/Arch/PPC64.cpp +++ ELF/Arch/PPC64.cpp @@ -207,7 +207,7 @@ break; } default: - error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type)); + error(getErrorLocation(Loc).Loc + "unrecognized reloc " + Twine(Type)); } } Index: ELF/Arch/SPARCV9.cpp =================================================================== --- ELF/Arch/SPARCV9.cpp +++ ELF/Arch/SPARCV9.cpp @@ -118,7 +118,7 @@ write64be(Loc, Val); break; default: - error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type)); + error(getErrorLocation(Loc).Loc + "unrecognized reloc " + Twine(Type)); } } Index: ELF/Arch/X86.cpp =================================================================== --- ELF/Arch/X86.cpp +++ ELF/Arch/X86.cpp @@ -305,7 +305,7 @@ write32le(Loc, Val); break; default: - error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type)); + error(getErrorLocation(Loc).Loc + "unrecognized reloc " + Twine(Type)); } } Index: ELF/Arch/X86_64.cpp =================================================================== --- ELF/Arch/X86_64.cpp +++ ELF/Arch/X86_64.cpp @@ -243,7 +243,7 @@ memcpy(Inst, "\x48\xc7", 2); *RegSlot = 0xc0 | Reg; } else { - error(getErrorLocation(Loc - 3) + + error(getErrorLocation(Loc - 3).Loc + "R_X86_64_GOTTPOFF must be used in MOVQ or ADDQ instructions only"); } @@ -321,7 +321,7 @@ write64le(Loc, Val); break; default: - error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type)); + error(getErrorLocation(Loc).Loc + "unrecognized reloc " + Twine(Type)); } } Index: ELF/Target.h =================================================================== --- ELF/Target.h +++ ELF/Target.h @@ -134,7 +134,11 @@ TargetInfo *getX86_64TargetInfo(); template TargetInfo *getMipsTargetInfo(); -std::string getErrorLocation(const uint8_t *Loc); +struct ErrLoc { + std::string Loc; + InputSection *IS; +}; +ErrLoc getErrorLocation(const uint8_t *Loc); uint64_t getPPC64TocBase(); uint64_t getAArch64Page(uint64_t Expr); @@ -144,31 +148,40 @@ template bool isMipsPIC(const Defined *Sym); +static void reportOutOfRange(uint8_t *Loc, RelType Type) { + ErrLoc L = getErrorLocation(Loc); + std::string Msg = + L.Loc + "relocation " + lld::toString(Type) + " out of range"; + + if (L.IS && L.IS->Name.startswith(".debug")) + Msg += "; it could happen because relocation has too large value for " + "DWARF32 used, consider recompiling with -fdebug-types-section " + "to reduce size of debug sections"; + error(Msg); +} + template static void checkInt(uint8_t *Loc, int64_t V, RelType Type) { if (!llvm::isInt(V)) - error(getErrorLocation(Loc) + "relocation " + lld::toString(Type) + - " out of range"); + reportOutOfRange(Loc, Type); } template static void checkUInt(uint8_t *Loc, uint64_t V, RelType Type) { if (!llvm::isUInt(V)) - error(getErrorLocation(Loc) + "relocation " + lld::toString(Type) + - " out of range"); + reportOutOfRange(Loc, Type); } template static void checkIntUInt(uint8_t *Loc, uint64_t V, RelType Type) { if (!llvm::isInt(V) && !llvm::isUInt(V)) - error(getErrorLocation(Loc) + "relocation " + lld::toString(Type) + - " out of range"); + reportOutOfRange(Loc, Type); } template static void checkAlignment(uint8_t *Loc, uint64_t V, RelType Type) { if ((V & (N - 1)) != 0) - error(getErrorLocation(Loc) + "improper alignment for relocation " + + error(getErrorLocation(Loc).Loc + "improper alignment for relocation " + lld::toString(Type)); } } // namespace elf Index: ELF/Target.cpp =================================================================== --- ELF/Target.cpp +++ ELF/Target.cpp @@ -87,7 +87,7 @@ fatal("unknown target machine"); } -template static std::string getErrorLoc(const uint8_t *Loc) { +template static ErrLoc getErrorLoc(const uint8_t *Loc) { for (InputSectionBase *D : InputSections) { auto *IS = dyn_cast_or_null(D); if (!IS || !IS->getParent()) @@ -95,12 +95,12 @@ uint8_t *ISLoc = IS->getParent()->Loc + IS->OutSecOff; if (ISLoc <= Loc && Loc < ISLoc + IS->getSize()) - return IS->template getLocation(Loc - ISLoc) + ": "; + return {IS->template getLocation(Loc - ISLoc) + ": ", IS}; } - return ""; + return {"", nullptr}; } -std::string elf::getErrorLocation(const uint8_t *Loc) { +ErrLoc elf::getErrorLocation(const uint8_t *Loc) { switch (Config->EKind) { case ELF32LEKind: return getErrorLoc(Loc); 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; it could happen because relocation has too large value for DWARF32 used, consider recompiling with -fdebug-types-section to reduce size of debug sections + +# CHECK: (.debug_info+0x8): relocation R_X86_64_32S out of range; it could happen because relocation has too large value for DWARF32 used, consider recompiling with -fdebug-types-section to reduce size of debug sections + +.section .debug_info,"",@progbits + movl $big, %edx + movq $foo - 0x1000000000000, %rdx