summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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