COFF: include archive name in LTO object name
authorBob Haarman <llvm@inglorion.net>
Tue, 28 Mar 2017 21:20:06 +0000 (21:20 +0000)
committerBob Haarman <llvm@inglorion.net>
Tue, 28 Mar 2017 21:20:06 +0000 (21:20 +0000)
Summary: In the ELF linker, we create the buffer identifier for bitcode files by appending the object name to the archive name. This change makes the COFF linker do the same. Without the change, ThinLTO builds can fail with an error message about multiple ThinLTO modules per object file, caused by object files contained in different archives having the same name.

Reviewers: pcc, ruiu

Reviewed By: pcc

Subscribers: mehdi_amini

Differential Revision: https://reviews.llvm.org/D31402

llvm-svn: 298942

lld/COFF/InputFiles.cpp
lld/test/COFF/Inputs/bar.ll [new file with mode: 0644]
lld/test/COFF/thinlto-archives.ll [new file with mode: 0644]
lld/test/ELF/lto/archive-no-index.ll [new file with mode: 0644]

index 78bf346..4632943 100644 (file)
@@ -339,8 +339,8 @@ void ImportFile::parse() {
 }
 
 void BitcodeFile::parse() {
-  Obj = check(lto::InputFile::create(
-      MemoryBufferRef(MB.getBuffer(), Saver.save(MB.getBufferIdentifier()))));
+  Obj = check(lto::InputFile::create(MemoryBufferRef(
+      MB.getBuffer(), Saver.save(ParentName + MB.getBufferIdentifier()))));
   for (const lto::InputFile::Symbol &ObjSym : Obj->symbols()) {
     StringRef SymName = Saver.save(ObjSym.getName());
     auto Flags = ObjSym.getFlags();
diff --git a/lld/test/COFF/Inputs/bar.ll b/lld/test/COFF/Inputs/bar.ll
new file mode 100644 (file)
index 0000000..4aed5d2
--- /dev/null
@@ -0,0 +1,6 @@
+target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-windows-msvc"
+
+define void @bar() {
+  ret void
+}
diff --git a/lld/test/COFF/thinlto-archives.ll b/lld/test/COFF/thinlto-archives.ll
new file mode 100644 (file)
index 0000000..7a5e36a
--- /dev/null
@@ -0,0 +1,22 @@
+; RUN: rm -fr %T/thinlto-archives
+; RUN: mkdir %T/thinlto-archives %T/thinlto-archives/a %T/thinlto-archives/b
+; RUN: opt -thinlto-bc -o %T/thinlto-archives/main.obj %s
+; RUN: opt -thinlto-bc -o %T/thinlto-archives/a/bar.obj %S/Inputs/lto-dep.ll
+; RUN: opt -thinlto-bc -o %T/thinlto-archives/b/bar.obj %S/Inputs/bar.ll
+; RUN: llvm-ar crs %T/thinlto-archives/a.lib %T/thinlto-archives/a/bar.obj
+; RUN: llvm-ar crs %T/thinlto-archives/b.lib %T/thinlto-archives/b/bar.obj
+; RUN: lld-link /out:%T/thinlto-archives/main.exe -entry:main \
+; RUN:     -subsystem:console %T/thinlto-archives/main.obj \
+; RUN:     %T/thinlto-archives/a.lib %T/thinlto-archives/b.lib
+
+target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-windows-msvc"
+
+declare void @bar()
+declare void @foo()
+
+define i32 @main() {
+  call void @foo()
+  call void @bar()
+  ret i32 0
+}
diff --git a/lld/test/ELF/lto/archive-no-index.ll b/lld/test/ELF/lto/archive-no-index.ll
new file mode 100644 (file)
index 0000000..feafd27
--- /dev/null
@@ -0,0 +1,39 @@
+; REQUIRES: x86
+; Tests that we suggest that LTO symbols missing from an archive index
+; may be the cause of undefined references, but only if we both
+; encountered an empty archive index and undefined references (to prevent
+; noisy false alarms).
+
+; RUN: rm -fr %T/archive-no-index
+; RUN: mkdir %T/archive-no-index
+; RUN: llvm-as %S/Inputs/archive.ll -o %T/archive-no-index/f.o
+; RUN: llvm-ar cr %T/archive-no-index/libf.a
+; RUN: llvm-ar qS %T/archive-no-index/libf.a %T/archive-no-index/f.o
+; RUN: llvm-as %s -o %t.o
+; RUN: not ld.lld -emain -m elf_x86_64 %t.o -o %t %T/archive-no-index/libf.a \
+; RUN:     2>&1 | FileCheck --check-prefix=NOTE %s
+
+; RUN: llvm-ar crs %T/archive-no-index/libfs.a %T/archive-no-index/f.o
+; RUN: ld.lld -emain -m elf_x86_64 %t.o -o %t %T/archive-no-index/libf.a \
+; RUN:     %T/archive-no-index/libfs.a
+
+; RUN: llvm-as %S/Inputs/archive-3.ll -o %T/archive-no-index/foo.o
+; RUN: llvm-ar crs %T/archive-no-index/libfoo.a %T/archive-no-index/foo.o
+; RUN: not ld.lld -emain -m elf_x86_64 %t.o -o %t %T/archive-no-index/libfoo.a \
+; RUN:     2>&1 | FileCheck --check-prefix=NO-NOTE %s
+
+; NOTE: undefined symbol 'f'
+; NOTE: archive listed no symbols
+
+; NO-NOTE: undefined symbol 'f'
+; NO-NOTE-NOT: archive listed no symbols
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+declare void @f()
+
+define i32 @main() {
+  call void @f()
+  ret i32 0
+}