summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/Arch/ARM.cpp15
-rw-r--r--lld/ELF/InputSection.cpp25
-rw-r--r--lld/ELF/Relocations.cpp7
-rw-r--r--lld/ELF/Target.cpp10
-rw-r--r--lld/ELF/Target.h1
-rw-r--r--lld/test/ELF/arm-thumb-interwork-notfunc.s24
-rw-r--r--lld/test/ELF/ppc64-error-toc-local-call.s4
-rw-r--r--lld/test/ELF/x86-64-reloc-error2.s1
-rw-r--r--lld/test/ELF/x86-64-reloc-range-debug-loc.s14
9 files changed, 58 insertions, 43 deletions
diff --git a/lld/ELF/Arch/ARM.cpp b/lld/ELF/Arch/ARM.cpp
index 759fef154154..8b5bd138b3e9 100644
--- a/lld/ELF/Arch/ARM.cpp
+++ b/lld/ELF/Arch/ARM.cpp
@@ -380,20 +380,25 @@ bool ARM::inBranchRange(RelType type, uint64_t src, uint64_t dst) const {
// or Thumb.
static void stateChangeWarning(uint8_t *loc, RelType relt, const Symbol &s) {
assert(!s.isFunc());
+ const ErrorPlace place = getErrorPlace(loc);
+ std::string hint;
+ if (!place.srcLoc.empty())
+ hint = "; " + place.srcLoc;
if (s.isSection()) {
// Section symbols must be defined and in a section. Users cannot change
// the type. Use the section name as getName() returns an empty string.
- warn(getErrorLocation(loc) + "branch and link relocation: " +
- toString(relt) + " to STT_SECTION symbol " +
- cast<Defined>(s).section->name + " ; interworking not performed");
+ warn(place.loc + "branch and link relocation: " + toString(relt) +
+ " to STT_SECTION symbol " + cast<Defined>(s).section->name +
+ " ; interworking not performed" + hint);
} else {
// Warn with hint on how to alter the symbol type.
warn(getErrorLocation(loc) + "branch and link relocation: " +
toString(relt) + " to non STT_FUNC symbol: " + s.getName() +
" interworking not performed; consider using directive '.type " +
s.getName() +
- ", %function' to give symbol type STT_FUNC if"
- " interworking between ARM and Thumb is required");
+ ", %function' to give symbol type STT_FUNC if interworking between "
+ "ARM and Thumb is required" +
+ hint);
}
}
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index 9fe98f5b9f5c..b44791898494 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -284,32 +284,21 @@ Defined *InputSectionBase::getEnclosingFunction(uint64_t offset) {
return nullptr;
}
-// Returns a source location string. Used to construct an error message.
+// Returns an object file location string. Used to construct an error message.
template <class ELFT>
std::string InputSectionBase::getLocation(uint64_t offset) {
- std::string secAndOffset = (name + "+0x" + utohexstr(offset)).str();
+ std::string secAndOffset =
+ (name + "+0x" + Twine::utohexstr(offset) + ")").str();
// We don't have file for synthetic sections.
if (getFile<ELFT>() == nullptr)
- return (config->outputFile + ":(" + secAndOffset + ")")
- .str();
-
- // First check if we can get desired values from debugging information.
- if (Optional<DILineInfo> info = getFile<ELFT>()->getDILineInfo(this, offset))
- return info->FileName + ":" + std::to_string(info->Line) + ":(" +
- secAndOffset + ")";
-
- // File->sourceFile contains STT_FILE symbol that contains a
- // source file name. If it's missing, we use an object file name.
- std::string srcFile = std::string(getFile<ELFT>()->sourceFile);
- if (srcFile.empty())
- srcFile = toString(file);
+ return (config->outputFile + ":(" + secAndOffset).str();
+ std::string file = toString(getFile<ELFT>());
if (Defined *d = getEnclosingFunction<ELFT>(offset))
- return srcFile + ":(function " + toString(*d) + ": " + secAndOffset + ")";
+ return file + ":(function " + toString(*d) + ": " + secAndOffset;
- // If there's no symbol, print out the offset in the section.
- return (srcFile + ":(" + secAndOffset + ")");
+ return file + ":(" + secAndOffset;
}
// This function is intended to be used for constructing an error message.
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index 893e575f983d..6c2076f142b8 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -101,8 +101,11 @@ void elf::reportRangeError(uint8_t *loc, const Relocation &rel, const Twine &v,
ErrorPlace errPlace = getErrorPlace(loc);
std::string hint;
if (rel.sym && !rel.sym->isLocal())
- hint = "; references " + lld::toString(*rel.sym) +
- getDefinedLocation(*rel.sym);
+ hint = "; references " + lld::toString(*rel.sym);
+ if (!errPlace.srcLoc.empty())
+ hint += "\n>>> referenced by " + errPlace.srcLoc;
+ if (rel.sym && !rel.sym->isLocal())
+ hint += getDefinedLocation(*rel.sym);
if (errPlace.isec && errPlace.isec->name.startswith(".debug"))
hint += "; consider recompiling with -fdebug-types-section to reduce size "
diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp
index baf2c1009c3c..88d3006f9a2d 100644
--- a/lld/ELF/Target.cpp
+++ b/lld/ELF/Target.cpp
@@ -106,8 +106,14 @@ template <class ELFT> static ErrorPlace getErrPlace(const uint8_t *loc) {
assert(isa<SyntheticSection>(isec) && "No data but not synthetic?");
continue;
}
- if (isecLoc <= loc && loc < isecLoc + isec->getSize())
- return {isec, isec->template getLocation<ELFT>(loc - isecLoc) + ": "};
+ if (isecLoc <= loc && loc < isecLoc + isec->getSize()) {
+ auto objLoc = isec->template getLocation<ELFT>(loc - isecLoc);
+ // Return object file location and source file location.
+ // TODO: Refactor getSrcMsg not to take a variable.
+ Undefined dummy(nullptr, "", STB_LOCAL, 0, 0);
+ return {isec, objLoc + ": ",
+ isec->file ? isec->getSrcMsg(dummy, loc - isecLoc) : ""};
+ }
}
return {};
}
diff --git a/lld/ELF/Target.h b/lld/ELF/Target.h
index 305edf5fa5d8..abb769b25dfb 100644
--- a/lld/ELF/Target.h
+++ b/lld/ELF/Target.h
@@ -188,6 +188,7 @@ template <class ELFT> TargetInfo *getMipsTargetInfo();
struct ErrorPlace {
InputSectionBase *isec;
std::string loc;
+ std::string srcLoc;
};
// Returns input section and corresponding source string for the given location.
diff --git a/lld/test/ELF/arm-thumb-interwork-notfunc.s b/lld/test/ELF/arm-thumb-interwork-notfunc.s
index d6b6a3190c68..28904a59d0f4 100644
--- a/lld/test/ELF/arm-thumb-interwork-notfunc.s
+++ b/lld/test/ELF/arm-thumb-interwork-notfunc.s
@@ -45,17 +45,17 @@ _start:
bl .thumb_target
bl thumb_func_with_notype
bl thumb_func_with_explicit_notype
-// WARN: {{.*}}.s:[[# @LINE+1]]:(.arm_caller+0x30): branch and link relocation: R_ARM_CALL to STT_SECTION symbol .arm_target ; interworking not performed
+// WARN: {{.*}}.o:(.arm_caller+0x30): branch and link relocation: R_ARM_CALL to STT_SECTION symbol .arm_target ; interworking not performed; {{.*}}.s:[[#@LINE+1]]
blx .arm_target
-// WARN: {{.*}}.s:[[# @LINE+1]]:(.arm_caller+0x34): branch and link relocation: R_ARM_CALL to non STT_FUNC symbol: arm_func_with_notype interworking not performed; consider using directive '.type arm_func_with_notype, %function' to give symbol type STT_FUNC if interworking between ARM and Thumb is required
+// WARN: {{.*}}.o:(.arm_caller+0x34): branch and link relocation: R_ARM_CALL to non STT_FUNC symbol: arm_func_with_notype interworking not performed; consider using directive '.type arm_func_with_notype, %function' to give symbol type STT_FUNC if interworking between ARM and Thumb is required; {{.*}}.s:[[#@LINE+1]]
blx arm_func_with_notype
-// WARN: {{.*}}.s:[[# @LINE+1]]:(.arm_caller+0x38): branch and link relocation: R_ARM_CALL to non STT_FUNC symbol: arm_func_with_explicit_notype interworking not performed; consider using directive '.type arm_func_with_explicit_notype, %function' to give symbol type STT_FUNC if interworking between ARM and Thumb is required
+// WARN: {{.*}}.o:(.arm_caller+0x38): branch and link relocation: R_ARM_CALL to non STT_FUNC symbol: arm_func_with_explicit_notype interworking not performed; consider using directive '.type arm_func_with_explicit_notype, %function' to give symbol type STT_FUNC if interworking between ARM and Thumb is required; {{.*}}.s:[[#@LINE+1]]
blx arm_func_with_explicit_notype
-// WARN: {{.*}}.s:[[# @LINE+1]]:(.arm_caller+0x3C): branch and link relocation: R_ARM_CALL to STT_SECTION symbol .thumb_target ; interworking not performed
+// WARN: {{.*}}.o:(.arm_caller+0x3c): branch and link relocation: R_ARM_CALL to STT_SECTION symbol .thumb_target ; interworking not performed; {{.*}}.s:[[#@LINE+1]]
blx .thumb_target
-// WARN: {{.*}}.s:[[# @LINE+1]]:(.arm_caller+0x40): branch and link relocation: R_ARM_CALL to non STT_FUNC symbol: thumb_func_with_notype interworking not performed; consider using directive '.type thumb_func_with_notype, %function' to give symbol type STT_FUNC if interworking between ARM and Thumb is required
+// WARN: {{.*}}.o:(.arm_caller+0x40): branch and link relocation: R_ARM_CALL to non STT_FUNC symbol: thumb_func_with_notype interworking not performed; consider using directive '.type thumb_func_with_notype, %function' to give symbol type STT_FUNC if interworking between ARM and Thumb is required; {{.*}}.s:[[#@LINE+1]]
blx thumb_func_with_notype
-// WARN: {{.*}}.s:[[# @LINE+1]]:(.arm_caller+0x44): branch and link relocation: R_ARM_CALL to non STT_FUNC symbol: thumb_func_with_explicit_notype interworking not performed; consider using directive '.type thumb_func_with_explicit_notype, %function' to give symbol type STT_FUNC if interworking between ARM and Thumb is required
+// WARN: {{.*}}.o:(.arm_caller+0x44): branch and link relocation: R_ARM_CALL to non STT_FUNC symbol: thumb_func_with_explicit_notype interworking not performed; consider using directive '.type thumb_func_with_explicit_notype, %function' to give symbol type STT_FUNC if interworking between ARM and Thumb is required; {{.*}}.s:[[#@LINE+1]]
blx thumb_func_with_explicit_notype
.section .thumb_caller, "ax", %progbits
@@ -75,17 +75,17 @@ thumb_caller:
beq.w .thumb_target
beq.w thumb_func_with_notype
beq.w thumb_func_with_explicit_notype
-// WARN: {{.*}}.s:[[# @LINE+1]]:(.thumb_caller+0x30): branch and link relocation: R_ARM_THM_CALL to STT_SECTION symbol .arm_target ; interworking not performed
+// WARN: {{.*}}.o:(.thumb_caller+0x30): branch and link relocation: R_ARM_THM_CALL to STT_SECTION symbol .arm_target ; interworking not performed; {{.*}}.s:[[#@LINE+1]]
bl .arm_target
-// WARN: {{.*}}.s:[[# @LINE+1]]:(.thumb_caller+0x34): branch and link relocation: R_ARM_THM_CALL to non STT_FUNC symbol: arm_func_with_notype interworking not performed; consider using directive '.type arm_func_with_notype, %function' to give symbol type STT_FUNC if interworking between ARM and Thumb is required
+// WARN: {{.*}}.o:(.thumb_caller+0x34): branch and link relocation: R_ARM_THM_CALL to non STT_FUNC symbol: arm_func_with_notype interworking not performed; consider using directive '.type arm_func_with_notype, %function' to give symbol type STT_FUNC if interworking between ARM and Thumb is required; {{.*}}.s:[[#@LINE+1]]
bl arm_func_with_notype
- // WARN: {{.*}}.s:[[# @LINE+1]]:(.thumb_caller+0x38): branch and link relocation: R_ARM_THM_CALL to non STT_FUNC symbol: arm_func_with_explicit_notype interworking not performed; consider using directive '.type arm_func_with_explicit_notype, %function' to give symbol type STT_FUNC if interworking between ARM and Thumb is required
+ // WARN: {{.*}}.o:(.thumb_caller+0x38): branch and link relocation: R_ARM_THM_CALL to non STT_FUNC symbol: arm_func_with_explicit_notype interworking not performed; consider using directive '.type arm_func_with_explicit_notype, %function' to give symbol type STT_FUNC if interworking between ARM and Thumb is required; {{.*}}.s:[[#@LINE+1]]
bl arm_func_with_explicit_notype
-// WARN: {{.*}}.s:[[# @LINE+1]]:(.thumb_caller+0x3C): branch and link relocation: R_ARM_THM_CALL to STT_SECTION symbol .thumb_target ; interworking not performed
+// WARN: {{.*}}.o:(.thumb_caller+0x3c): branch and link relocation: R_ARM_THM_CALL to STT_SECTION symbol .thumb_target ; interworking not performed; {{.*}}.s:[[#@LINE+1]]
bl .thumb_target
-// WARN: {{.*}}.s:[[# @LINE+1]]:(.thumb_caller+0x40): branch and link relocation: R_ARM_THM_CALL to non STT_FUNC symbol: thumb_func_with_notype interworking not performed; consider using directive '.type thumb_func_with_notype, %function' to give symbol type STT_FUNC if interworking between ARM and Thumb is required
+// WARN: {{.*}}.o:(.thumb_caller+0x40): branch and link relocation: R_ARM_THM_CALL to non STT_FUNC symbol: thumb_func_with_notype interworking not performed; consider using directive '.type thumb_func_with_notype, %function' to give symbol type STT_FUNC if interworking between ARM and Thumb is required; {{.*}}.s:[[#@LINE+1]]
bl thumb_func_with_notype
-// {{.*}}.s:[[# @LINE+1]]:(.thumb_caller+0x44): branch and link relocation: R_ARM_THM_CALL to non STT_FUNC symbol: thumb_func_with_explicit_notype interworking not performed; consider using directive '.type thumb_func_with_explicit_notype, %function' to give symbol type STT_FUNC if interworking between ARM and Thumb is required
+// {{.*}}.o:(.thumb_caller+0x44): branch and link relocation: R_ARM_THM_CALL to non STT_FUNC symbol: thumb_func_with_explicit_notype interworking not performed; consider using directive '.type thumb_func_with_explicit_notype, %function' to give symbol type STT_FUNC if interworking between ARM and Thumb is required; {{.*}}.s:[[#@LINE+1]]
bl thumb_func_with_explicit_notype
blx .arm_target
blx arm_func_with_notype
diff --git a/lld/test/ELF/ppc64-error-toc-local-call.s b/lld/test/ELF/ppc64-error-toc-local-call.s
index 606f6ead5463..8cb04c149496 100644
--- a/lld/test/ELF/ppc64-error-toc-local-call.s
+++ b/lld/test/ELF/ppc64-error-toc-local-call.s
@@ -8,8 +8,8 @@
## This test checks that the linker produces errors when it is missing the nop
## after a local call to a callee with st_other=1.
-# CHECK: (.text+0xC): call to save_callee lacks nop, can't restore toc
-# CHECK: (.text+0x1C): call to save_callee lacks nop, can't restore toc
+# CHECK: {{.*}}.o:(.text+0xc): call to save_callee lacks nop, can't restore toc
+# CHECK-NEXT: {{.*}}.o:(.text+0x1c): call to save_callee lacks nop, can't restore toc
callee:
.localentry callee, 1
diff --git a/lld/test/ELF/x86-64-reloc-error2.s b/lld/test/ELF/x86-64-reloc-error2.s
index a082a94e6adb..d1803c9e6cff 100644
--- a/lld/test/ELF/x86-64-reloc-error2.s
+++ b/lld/test/ELF/x86-64-reloc-error2.s
@@ -6,6 +6,7 @@
## a given location when reporting error messages.
# CHECK: {{.*}}.o:(function func: .text.func+0x3): relocation R_X86_64_32S out of range: -281474974609120 is not in [-2147483648, 2147483647]; references func
# CHECK-NEXT: >>> defined in {{.*}}.o
+# CHECK-EMPTY:
# This mergeable section will be garbage collected. We had a crash issue in that case. Test it.
.section .rodata.str1,"aMS",@progbits,1
diff --git a/lld/test/ELF/x86-64-reloc-range-debug-loc.s b/lld/test/ELF/x86-64-reloc-range-debug-loc.s
index 08a49607e806..7635870061bb 100644
--- a/lld/test/ELF/x86-64-reloc-range-debug-loc.s
+++ b/lld/test/ELF/x86-64-reloc-range-debug-loc.s
@@ -3,12 +3,22 @@
# RUN: llvm-mc %s -o %t.o -triple x86_64-pc-linux -filetype=obj
# RUN: not ld.lld %tabs %t.o -o /dev/null -shared 2>&1 | FileCheck %s
+# RUN: rm -f %t.a && llvm-ar rc %t.a %t.o
+# RUN: not ld.lld -shared %t.a %tabs -o /dev/null 2>&1 | FileCheck %s --check-prefix=CHECK2
+
## Check we are able to report file and location from debug information
## when reporting such kind of errors.
-# CHECK: error: test.s:3:(.text+0x1): relocation R_X86_64_32 out of range: 68719476736 is not in [0, 4294967295]
+# CHECK: error: {{.*}}.o:(.text+0x1): relocation R_X86_64_32 out of range: 68719476736 is not in [0, 4294967295]; references big
+# CHECK-NEXT: >>> referenced by test.s:3
+# CHECK-NEXT: >>> defined in {{.*}}abs
+
+# CHECK2: error: {{.*}}.a({{.*}}.o):(.text+0x1): relocation R_X86_64_32 out of range: 68719476736 is not in [0, 4294967295]; references big
+# CHECK2-NEXT: >>> referenced by test.s:3
+# CHECK2-NEXT: >>> defined in {{.*}}abs
.section .text,"ax",@progbits
-foo:
+.globl _start
+_start:
.file 1 "test.s"
.loc 1 3
movl $big, %edx