summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/SymbolTable.cpp58
-rw-r--r--lld/test/ELF/abs-conflict.s4
-rw-r--r--lld/test/ELF/basic.s5
-rw-r--r--lld/test/ELF/conflict.s32
-rw-r--r--lld/test/ELF/lto/duplicated.ll6
-rw-r--r--lld/test/ELF/tls-mismatch.s5
6 files changed, 72 insertions, 38 deletions
diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp
index c3179d9cba8..2b0a7a17974 100644
--- a/lld/ELF/SymbolTable.cpp
+++ b/lld/ELF/SymbolTable.cpp
@@ -206,13 +206,6 @@ std::pair<Symbol *, bool> SymbolTable<ELFT>::insert(StringRef Name) {
return {Sym, IsNew};
}
-// Construct a string in the form of "Sym in File1 and File2".
-// Used to construct an error message.
-static std::string conflictMsg(SymbolBody *Existing, InputFile *NewFile) {
- return "'" + toString(*Existing) + "' in " + toString(Existing->File) +
- " and " + toString(NewFile);
-}
-
// Find an existing symbol or create and insert a new one, then apply the given
// attributes.
template <class ELFT>
@@ -226,13 +219,19 @@ SymbolTable<ELFT>::insert(StringRef Name, uint8_t Type, uint8_t Visibility,
// Merge in the new symbol's visibility.
S->Visibility = getMinVisibility(S->Visibility, Visibility);
+
if (!CanOmitFromDynSym && (Config->Shared || Config->ExportDynamic))
S->ExportDynamic = true;
+
if (IsUsedInRegularObj)
S->IsUsedInRegularObj = true;
+
if (!WasInserted && S->body()->Type != SymbolBody::UnknownType &&
- ((Type == STT_TLS) != S->body()->isTls()))
- error("TLS attribute mismatch for symbol " + conflictMsg(S->body(), File));
+ ((Type == STT_TLS) != S->body()->isTls())) {
+ error("TLS attribute mismatch: " + toString(*S->body()) +
+ "\n>>> defined in " + toString(S->body()->File) +
+ "\n>>> defined in " + toString(File));
+ }
return {S, WasInserted};
}
@@ -349,32 +348,49 @@ Symbol *SymbolTable<ELFT>::addCommon(StringRef N, uint64_t Size,
return S;
}
-static void print(const Twine &Msg) {
+static void warnOrError(const Twine &Msg) {
if (Config->AllowMultipleDefinition)
warn(Msg);
else
error(Msg);
}
-static void reportDuplicate(SymbolBody *Existing, InputFile *NewFile) {
- print("duplicate symbol " + conflictMsg(Existing, NewFile));
+static void reportDuplicate(SymbolBody *Sym, InputFile *NewFile) {
+ warnOrError("duplicate symbol: " + toString(*Sym) +
+ "\n>>> defined in " + toString(Sym->File) +
+ "\n>>> defined in " + toString(NewFile));
}
template <class ELFT>
-static void reportDuplicate(SymbolBody *Existing, InputSectionBase *ErrSec,
+static void reportDuplicate(SymbolBody *Sym, InputSectionBase *ErrSec,
typename ELFT::uint ErrOffset) {
- DefinedRegular *D = dyn_cast<DefinedRegular>(Existing);
+ DefinedRegular *D = dyn_cast<DefinedRegular>(Sym);
if (!D || !D->Section || !ErrSec) {
- reportDuplicate(Existing, ErrSec ? ErrSec->getFile<ELFT>() : nullptr);
+ reportDuplicate(Sym, ErrSec ? ErrSec->getFile<ELFT>() : nullptr);
return;
}
- std::string OldLoc =
- cast<InputSectionBase>(D->Section)->template getLocation<ELFT>(D->Value);
- std::string NewLoc = ErrSec->getLocation<ELFT>(ErrOffset);
-
- print(NewLoc + ": duplicate symbol '" + toString(*Existing) + "'");
- print(OldLoc + ": previous definition was here");
+ // Construct and print an error message in the form of:
+ //
+ // ld.lld: error: duplicate symbol: foo
+ // >>> defined at bar.c:30
+ // >>> bar.o (/home/alice/src/bar.o)
+ // >>> defined at baz.c:563
+ // >>> baz.o in archive libbaz.a
+ auto *Sec1 = cast<InputSectionBase>(D->Section);
+ std::string Src1 = Sec1->getSrcMsg<ELFT>(D->Value);
+ std::string Obj1 = Sec1->getObjMsg<ELFT>(D->Value);
+ std::string Src2 = ErrSec->getSrcMsg<ELFT>(ErrOffset);
+ std::string Obj2 = ErrSec->getObjMsg<ELFT>(ErrOffset);
+
+ std::string Msg = "duplicate symbol: " + toString(*Sym) + "\n>>> defined at ";
+ if (!Src1.empty())
+ Msg += Src1 + "\n>>> ";
+ Msg += Obj1 + "\n>>> defined at ";
+ if (!Src2.empty())
+ Msg += Src2 + "\n>>> ";
+ Msg += Obj2;
+ warnOrError(Msg);
}
template <typename ELFT>
diff --git a/lld/test/ELF/abs-conflict.s b/lld/test/ELF/abs-conflict.s
index 7837a6bae50..17a53020003 100644
--- a/lld/test/ELF/abs-conflict.s
+++ b/lld/test/ELF/abs-conflict.s
@@ -13,4 +13,6 @@ foo = 0x123
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %t2.s -o %t2.o
// RUN: not ld.lld %t.o %t2.o -o %t.so -shared 2>&1 | FileCheck --check-prefix=DUP %s
-// DUP: duplicate symbol 'foo'
+// DUP: duplicate symbol: foo
+// DUP-NEXT: >>> defined in {{.*}}.o
+// DUP-NEXT: >>> defined in (internal)
diff --git a/lld/test/ELF/basic.s b/lld/test/ELF/basic.s
index ff812f1f7f4..c62a516c1bf 100644
--- a/lld/test/ELF/basic.s
+++ b/lld/test/ELF/basic.s
@@ -238,8 +238,9 @@ _start:
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
# RUN: not ld.lld %t %t -o %t2 2>&1 | FileCheck --check-prefix=DUP %s
-# DUP: {{.*}}:(.text+0x0): duplicate symbol '_start'
-# DUP: {{.*}}:(.text+0x0): previous definition was here
+# DUP: duplicate symbol: _start
+# DUP-NEXT: >>> defined at {{.*}}:(.text+0x0)
+# DUP-NEXT: >>> defined at {{.*}}:(.text+0x0)
# RUN: not ld.lld %t -o %t -m wrong_emul_fbsd 2>&1 | FileCheck --check-prefix=UNKNOWN_EMUL %s
# UNKNOWN_EMUL: unknown emulation: wrong_emul_fbsd
diff --git a/lld/test/ELF/conflict.s b/lld/test/ELF/conflict.s
index b9bb50515c5..4318759cbc1 100644
--- a/lld/test/ELF/conflict.s
+++ b/lld/test/ELF/conflict.s
@@ -3,18 +3,22 @@
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
# RUN: not ld.lld %t1.o %t1.o -o %t2 2>&1 | FileCheck -check-prefix=DEMANGLE %s
-# DEMANGLE: {{.*}}:(.text+0x0): duplicate symbol 'mul(double, double)'
-# DEMANGLE-NEXT: {{.*}}:(.text+0x0): previous definition was here
-# DEMANGLE-NEXT: {{.*}}:(.text+0x0): duplicate symbol 'foo'
-# DEMANGLE-NEXT: {{.*}}:(.text+0x0): previous definition was here
+# DEMANGLE: duplicate symbol: mul(double, double)
+# DEMANGLE-NEXT: >>> defined at {{.*}}:(.text+0x0)
+# DEMANGLE-NEXT: >>> defined at {{.*}}:(.text+0x0)
+# DEMANGLE: duplicate symbol: foo
+# DEMANGLE-NEXT: >>> defined at {{.*}}:(.text+0x0)
+# DEMANGLE-NEXT: >>> defined at {{.*}}:(.text+0x0)
# RUN: not ld.lld %t1.o %t1.o -o %t2 --no-demangle 2>&1 | \
# RUN: FileCheck -check-prefix=NO_DEMANGLE %s
-# NO_DEMANGLE: {{.*}}:(.text+0x0): duplicate symbol '_Z3muldd'
-# NO_DEMANGLE-NEXT: {{.*}}:(.text+0x0): previous definition was here
-# NO_DEMANGLE-NEXT: {{.*}}:(.text+0x0): duplicate symbol 'foo'
-# NO_DEMANGLE-NEXT: {{.*}}:(.text+0x0): previous definition was here
+# NO_DEMANGLE: duplicate symbol: _Z3muldd
+# NO_DEMANGLE-NEXT: >>> defined at {{.*}}:(.text+0x0)
+# NO_DEMANGLE-NEXT: >>> defined at {{.*}}:(.text+0x0)
+# NO_DEMANGLE: duplicate symbol: foo
+# NO_DEMANGLE-NEXT: >>> defined at {{.*}}:(.text+0x0)
+# NO_DEMANGLE-NEXT: >>> defined at {{.*}}:(.text+0x0)
# RUN: not ld.lld %t1.o %t1.o -o %t2 --demangle --no-demangle 2>&1 | \
# RUN: FileCheck -check-prefix=NO_DEMANGLE %s
@@ -25,14 +29,18 @@
# RUN: llvm-ar rcs %t3.a %t2.o
# RUN: not ld.lld %t1.o %t3.a -u baz -o %t2 2>&1 | FileCheck -check-prefix=ARCHIVE %s
-# ARCHIVE: {{.*}}3.a({{.*}}2.o):(.text+0x0): duplicate symbol 'foo'
-# ARCHIVE-NEXT: {{.*}}1.o:(.text+0x0): previous definition was here
+# ARCHIVE: duplicate symbol: foo
+# ARCHIVE-NEXT: >>> defined at {{.*}}:(.text+0x0)
+# ARCHIVE-NEXT: >>> defined at {{.*}}:(.text+0x0) in archive {{.*}}.a
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/conflict-debug.s -o %t-dbg.o
# RUN: not ld.lld %t-dbg.o %t-dbg.o -o %t-dbg 2>&1 | FileCheck -check-prefix=DBGINFO %s
-# DBGINFO: conflict-debug.s:4: duplicate symbol 'zed'
-# DBGINFO-NEXT: conflict-debug.s:4: previous definition was here
+# DBGINFO: duplicate symbol: zed
+# DBGINFO-NEXT: >>> defined at conflict-debug.s:4
+# DBGINFO-NEXT: >>> {{.*}}:(.text+0x0)
+# DBGINFO-NEXT: >>> defined at conflict-debug.s:4
+# DBGINFO-NEXT: >>> {{.*}}:(.text+0x0)
.globl _Z3muldd, foo
_Z3muldd:
diff --git a/lld/test/ELF/lto/duplicated.ll b/lld/test/ELF/lto/duplicated.ll
index 903592c4606..156748117a2 100644
--- a/lld/test/ELF/lto/duplicated.ll
+++ b/lld/test/ELF/lto/duplicated.ll
@@ -1,7 +1,11 @@
; REQUIRES: x86
; RUN: llvm-as %s -o %t.o
; RUN: not ld.lld -m elf_x86_64 %t.o %t.o -o %t.so -shared 2>&1 | FileCheck %s
-; CHECK: duplicate symbol 'f' in {{.*}}.o and {{.*}}.o
+
+; CHECK: duplicate symbol: f
+; CHECK-NEXT: >>> defined in {{.*}}.o
+; CHECK-NEXT: >>> defined in {{.*}}.o
+
target triple = "x86_64-unknown-linux-gnu"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
diff --git a/lld/test/ELF/tls-mismatch.s b/lld/test/ELF/tls-mismatch.s
index aee1f73dedc..21994d19af3 100644
--- a/lld/test/ELF/tls-mismatch.s
+++ b/lld/test/ELF/tls-mismatch.s
@@ -2,7 +2,10 @@
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/tls-mismatch.s -o %t2
// RUN: not ld.lld %t %t2 -o %t3 2>&1 | FileCheck %s
-// CHECK: TLS attribute mismatch for symbol 'tlsvar'
+
+// CHECK: TLS attribute mismatch: tlsvar
+// CHECK: >>> defined in
+// CHECK: >>> defined in
.globl _start,tlsvar
_start:
OpenPOWER on IntegriCloud