diff --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp index de0f8316a2991..ab04748b76afa 100644 --- a/lld/ELF/LTO.cpp +++ b/lld/ELF/LTO.cpp @@ -301,7 +301,8 @@ static void thinLTOCreateEmptyIndexFiles() { continue; if (linkedBitCodeFiles.contains(f->getName())) continue; - std::string path = replaceThinLTOSuffix(getThinLTOOutputFile(f->getName())); + std::string path = + replaceThinLTOSuffix(getThinLTOOutputFile(f->obj->getName())); std::unique_ptr os = openFile(path + ".thinlto.bc"); if (!os) continue; diff --git a/lld/test/ELF/lto/thinlto-emit-index-thin-archive.ll b/lld/test/ELF/lto/thinlto-emit-index-thin-archive.ll new file mode 100644 index 0000000000000..bcb90e21a8721 --- /dev/null +++ b/lld/test/ELF/lto/thinlto-emit-index-thin-archive.ll @@ -0,0 +1,49 @@ +; REQUIRES: x86 + +; RUN: rm -rf %t.dir && mkdir %t.dir && cd %t.dir +; RUN: mkdir dir1 dir2 +; RUN: llvm-as %s -o ./dir1/main.o +; RUN: llvm-as %p/Inputs/thinlto.ll -o ./dir1/unused.o +; RUN: llvm-as %p/Inputs/thin1.ll -o ./dir1/thin.o +; RUN: llvm-as %p/Inputs/thin2.ll -o ./dir2/thin.o +; RUN: llvm-ar crT ./dir2/lib.a dir1/unused.o dir1/thin.o dir2/thin.o + +;; For a thin archive referencing object files in a different directory, +;; emit index files (lib.a($member at $offset).thinlto.bc) in the directory +;; containing the archive, even in the lazy case. The information about the +;; referenced member's directory is lost. +; RUN: ld.lld --thinlto-emit-index-files ./dir2/lib.a ./dir1/main.o -o c --save-temps +; RUN: ls ./dir2 | FileCheck %s --check-prefix CHECK-UNUSED + +; CHECK-UNUSED: lib.a(unused.o at {{[1-9][0-9]+}}) + +;; Index files emitted from object files in a thin archive should have the +;; offset in the archive specified to avoid collisions +; RUN: FileCheck %s < c.resolution.txt --check-prefix CHECK-COLLISION + +; CHECK-COLLISION: dir1/main.o +; CHECK-COLLISION: dir2/lib.a(thin.o at {{[1-9][0-9]+}}) +; CHECK-COLLISION-NEXT: -r=./dir2/lib.a(thin.o at {{[1-9][0-9]+}}),blah,pl +; CHECK-COLLISION: dir2/lib.a(thin.o at {{[1-9][0-9]+}}) +; CHECK-COLLISION-NEXT: -r=./dir2/lib.a(thin.o at {{[1-9][0-9]+}}),foo,pl + +;; Clean up +; RUN: rm -rf ./dir1/*.thinlto.bc +; RUN: rm -rf ./dir2/*.thinlto.bc +;; Empty index files for unused files in thin archives should still be emitted +;; in the same format when using --whole-archive +; RUN: ld.lld --thinlto-emit-index-files --whole-archive ./dir2/lib.a ./dir1/main.o -o d +; RUN: ls ./dir2 | FileCheck %s --check-prefix CHECK-UNUSED + +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +declare i32 @blah(i32 %meh) +declare i32 @foo(i32 %goo) + +define void @_start() { +entry: + call i32 @foo(i32 0) + call i32 @blah(i32 0) + ret void +} diff --git a/lld/test/ELF/lto/thinlto-thin-archive-collision.ll b/lld/test/ELF/lto/thinlto-thin-archive-collision.ll deleted file mode 100644 index 1a175f29d369a..0000000000000 --- a/lld/test/ELF/lto/thinlto-thin-archive-collision.ll +++ /dev/null @@ -1,27 +0,0 @@ -; REQUIRES: x86 -; RUN: rm -fr %t && mkdir %t && cd %t -; RUN: mkdir thinlto-archives thinlto-archives/a thinlto-archives/b -; RUN: opt -thinlto-bc -o thinlto-archives/main.o %s -; RUN: opt -thinlto-bc -o thinlto-archives/a/thin.o %S/Inputs/thin1.ll -; RUN: opt -thinlto-bc -o thinlto-archives/b/thin.o %S/Inputs/thin2.ll -; RUN: llvm-ar qcT thinlto-archives/thin.a thinlto-archives/a/thin.o thinlto-archives/b/thin.o -; RUN: ld.lld thinlto-archives/main.o thinlto-archives/thin.a -o thinlto-archives/main.exe --save-temps -; RUN: FileCheck %s < thinlto-archives/main.exe.resolution.txt - -; CHECK: thinlto-archives/main.o -; CHECK: thinlto-archives/thin.a(thin.o at {{[1-9][0-9]+}}) -; CHECK-NEXT: -r=thinlto-archives/thin.a(thin.o at {{[1-9][0-9]+}}),foo,pl -; CHECK: thinlto-archives/thin.a(thin.o at {{[1-9][0-9]+}}) -; CHECK-NEXT: -r=thinlto-archives/thin.a(thin.o at {{[1-9][0-9]+}}),blah,pl - -target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" -target triple = "x86_64-scei-ps4" - -declare i32 @blah(i32 %meh) -declare i32 @foo(i32 %goo) - -define i32 @_start() { - call i32 @foo(i32 0) - call i32 @blah(i32 0) - ret i32 0 -}