summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2016-02-02 08:22:41 +0000
committerRui Ueyama <ruiu@google.com>2016-02-02 08:22:41 +0000
commit71c066d8cfd12a696454377c0592f3697ef207f3 (patch)
tree3f609a8276736cdb7b39c5bba884b29f91713918
parent82b4288b1a32a781af50760ad12698b64da233e2 (diff)
downloadbcm5719-llvm-71c066d8cfd12a696454377c0592f3697ef207f3.tar.gz
bcm5719-llvm-71c066d8cfd12a696454377c0592f3697ef207f3.zip
ELF: Include archive names in error messages.
If object files are drawn from archive files, the error message should be something like "conflict symbols in foo.a(bar.o) and baz.o" instead of "conflict symbols in bar.o and baz.o". This patch implements that. llvm-svn: 259475
-rw-r--r--lld/ELF/Driver.cpp3
-rw-r--r--lld/ELF/InputFiles.cpp7
-rw-r--r--lld/ELF/InputFiles.h8
-rw-r--r--lld/ELF/SymbolTable.cpp18
-rw-r--r--lld/ELF/Symbols.cpp2
-rw-r--r--lld/test/ELF/Inputs/conflict.s7
-rw-r--r--lld/test/ELF/conflict.s12
7 files changed, 43 insertions, 14 deletions
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index fe0a3f5a8b9..4fbf202c9d2 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -95,8 +95,9 @@ void LinkerDriver::addFile(StringRef Path) {
return;
case file_magic::archive:
if (WholeArchive) {
+ StringRef S = MBRef.getBufferIdentifier();
for (MemoryBufferRef MB : getArchiveMembers(MBRef))
- Files.push_back(createObjectFile(MB));
+ Files.push_back(createObjectFile(MB, S));
return;
}
Files.push_back(make_unique<ArchiveFile>(MBRef));
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index fa7c339da19..cee398bd8a9 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -452,8 +452,11 @@ static std::unique_ptr<InputFile> createELFFile(MemoryBufferRef MB) {
fatal("Invalid file class: " + MB.getBufferIdentifier());
}
-std::unique_ptr<InputFile> elf2::createObjectFile(MemoryBufferRef MB) {
- return createELFFile<ObjectFile>(MB);
+std::unique_ptr<InputFile> elf2::createObjectFile(MemoryBufferRef MB,
+ StringRef ArchiveName) {
+ std::unique_ptr<InputFile> F = createELFFile<ObjectFile>(MB);
+ F->ArchiveName = ArchiveName;
+ return F;
}
std::unique_ptr<InputFile> elf2::createSharedFile(MemoryBufferRef MB) {
diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h
index e530f7fa70a..8ed49b9d393 100644
--- a/lld/ELF/InputFiles.h
+++ b/lld/ELF/InputFiles.h
@@ -38,6 +38,11 @@ public:
StringRef getName() const { return MB.getBufferIdentifier(); }
+ // Filename of .a which contained this file. If this file was
+ // not in an archive file, it is the empty string. We use this
+ // string for creating error messages.
+ std::string ArchiveName;
+
protected:
InputFile(Kind K, MemoryBufferRef M) : MB(M), FileKind(K) {}
MemoryBufferRef MB;
@@ -208,7 +213,8 @@ public:
bool isNeeded() const { return !AsNeeded || IsUsed; }
};
-std::unique_ptr<InputFile> createObjectFile(MemoryBufferRef MB);
+std::unique_ptr<InputFile> createObjectFile(MemoryBufferRef MB,
+ StringRef ArchiveName = "");
std::unique_ptr<InputFile> createSharedFile(MemoryBufferRef MB);
} // namespace elf2
diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp
index 1e1c8aad589..b5b902d3c5f 100644
--- a/lld/ELF/SymbolTable.cpp
+++ b/lld/ELF/SymbolTable.cpp
@@ -149,17 +149,23 @@ ELFFileBase<ELFT> *SymbolTable<ELFT>::findFile(SymbolBody *B) {
return nullptr;
}
+// Returns "(internal)", "foo.a(bar.o)" or "baz.o".
+template <class ELFT> static std::string getFilename(ELFFileBase<ELFT> *F) {
+ if (!F)
+ return "(internal)";
+ if (!F->ArchiveName.empty())
+ return (F->ArchiveName + "(" + F->getName() + ")").str();
+ return F->getName();
+}
+
// Construct a string in the form of "Sym in File1 and File2".
// Used to construct an error message.
template <class ELFT>
std::string SymbolTable<ELFT>::conflictMsg(SymbolBody *Old, SymbolBody *New) {
- ELFFileBase<ELFT> *OldFile = findFile(Old);
- ELFFileBase<ELFT> *NewFile = findFile(New);
-
+ ELFFileBase<ELFT> *F1 = findFile(Old);
+ ELFFileBase<ELFT> *F2 = findFile(New);
StringRef Sym = Old->getName();
- StringRef F1 = OldFile ? OldFile->getName() : "(internal)";
- StringRef F2 = NewFile ? NewFile->getName() : "(internal)";
- return (demangle(Sym) + " in " + F1 + " and " + F2).str();
+ return demangle(Sym) + " in " + getFilename(F1) + " and " + getFilename(F2);
}
// This function resolves conflicts if there's an existing symbol with
diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp
index 6bc285ce513..c8b8891b6b1 100644
--- a/lld/ELF/Symbols.cpp
+++ b/lld/ELF/Symbols.cpp
@@ -187,7 +187,7 @@ std::unique_ptr<InputFile> Lazy::getMember() {
// read from the library.
if (MBRef.getBuffer().empty())
return std::unique_ptr<InputFile>(nullptr);
- return createObjectFile(MBRef);
+ return createObjectFile(MBRef, File->getName());
}
template <class ELFT> static void doInitSymbols() {
diff --git a/lld/test/ELF/Inputs/conflict.s b/lld/test/ELF/Inputs/conflict.s
new file mode 100644
index 00000000000..545ae99c845
--- /dev/null
+++ b/lld/test/ELF/Inputs/conflict.s
@@ -0,0 +1,7 @@
+.globl _Z3muldd, foo, baz
+_Z3muldd:
+foo:
+baz:
+ mov $60, %rax
+ mov $42, %rdi
+ syscall
diff --git a/lld/test/ELF/conflict.s b/lld/test/ELF/conflict.s
index 96c1c3915b7..1a0b75da44d 100644
--- a/lld/test/ELF/conflict.s
+++ b/lld/test/ELF/conflict.s
@@ -3,15 +3,21 @@
# 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=DEMANGLE %s
-# RUN: not ld.lld %t %t -o %t2 --no-demangle 2>&1 | \
-# RUN: FileCheck -check-prefix=NO_DEMANGLE %s
-
# DEMANGLE: duplicate symbol: {{mul\(double, double\)|_Z3muldd}} in
# DEMANGLE: duplicate symbol: foo in
+# RUN: not ld.lld %t %t -o %t2 --no-demangle 2>&1 | \
+# RUN: FileCheck -check-prefix=NO_DEMANGLE %s
+
# NO_DEMANGLE: duplicate symbol: _Z3muldd in
# NO_DEMANGLE: duplicate symbol: foo in
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/conflict.s -o %t2
+# RUN: llvm-ar rcs %t.a %t2
+# RUN: not ld.lld %t %t.a -u baz -o %t2 2>&1 | FileCheck -check-prefix=ARCHIVE %s
+
+# ARCHIVE: duplicate symbol: foo in {{.*}}conflict.s.tmp and {{.*}}.a(conflict.s.tmp2)
+
.globl _Z3muldd, foo
_Z3muldd:
foo:
OpenPOWER on IntegriCloud