summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFangrui Song <i@maskray.me>2021-10-28 09:38:45 -0700
committerFangrui Song <i@maskray.me>2021-10-28 09:38:45 -0700
commit2b1e32410c5234b6245b94a99c25047c0fbf4f13 (patch)
treeafd904ccab4bd7713f4e246081fc82f6724f1ef7
parenta88867a085e0f6cc93dfd291e1f3bdba3a5b4a97 (diff)
downloadllvm-zibi/warnings_from_nanosleep.tar.gz
[ELF] Change common diagnostics to report both object file location and source file locationzibi/warnings_from_nanosleep
Many diagnostics use `getErrorPlace` or `getErrorLocation` to report a location. In the presence of line table debug information, `getErrorPlace` uses a source file location and ignores the object file location. However, the object file location is sometimes more useful. This patch changes "undefined symbol" and "out of range" diagnostics to report both object/source file locations. Other diagnostics can use similar format if needed. The key idea is to let `InputSectionBase::getLocation` report the object file location and use `getSrcMsg` for source file/line information. `getSrcMsg` doesn't leverage `STT_FILE` information yet, but I think the temporary lack of the functionality is ok. For the ARM "branch and link relocation" diagnostic, I arbitrarily place the source file location at the end of the line. The diagnostic is not very common so its formatting doesn't need to be pretty. Differential Revision: https://reviews.llvm.org/D112518
-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