Index: ELF/LTO.cpp =================================================================== --- ELF/LTO.cpp +++ ELF/LTO.cpp @@ -220,6 +220,28 @@ openFile(Path + ".imports"); } +namespace { + +class raw_multi_ostream : public llvm::raw_svector_ostream { + std::unique_ptr OS; + + virtual void anchor() override; + +public: + explicit raw_multi_ostream(SmallString<0> &Buf) + : llvm::raw_svector_ostream(Buf) {} + ~raw_multi_ostream() override { + if (OS) (*OS.get()) << str(); + } + void AddOStream(std::unique_ptr Stream) { + OS = std::move(Stream); + } +}; + +void raw_multi_ostream::anchor() {} + +} + // Merge all the bitcode files we have seen, codegen the result // and return the resulting ObjectFile(s). std::vector BitcodeCompiler::compile() { @@ -240,8 +262,16 @@ checkError(LTOObj->run( [&](size_t Task) { - return llvm::make_unique( - llvm::make_unique(Buf[Task])); + std::unique_ptr OS = + llvm::make_unique(Buf[Task]); + + if (!Config->ThinLTOIndexOnly && !Config->LTOObjPath.empty()) { + std::string Filename = Config->LTOObjPath; + if (Task) Filename += utostr(Task); + OS.get()->AddOStream(openFile(Filename)); + } + + return llvm::make_unique(std::move(OS)); }, Cache)); Index: test/ELF/lto/Inputs/obj-path.ll =================================================================== --- /dev/null +++ test/ELF/lto/Inputs/obj-path.ll @@ -0,0 +1,10 @@ +; SYMBOLS: T g + +; ELF: Format: ELF64-x86-64 +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define void @g() { +entry: + ret void +} Index: test/ELF/lto/obj-path.ll =================================================================== --- /dev/null +++ test/ELF/lto/obj-path.ll @@ -0,0 +1,33 @@ +; REQUIRES: x86 + +; RUN: opt -module-summary %s -o %t1.o +; RUN: opt -module-summary %p/Inputs/obj-path.ll -o %t2.o + +; Test to ensure that obj-path creates the ELF file. +; RUN: rm -f %t4.o +; RUN: ld.lld --plugin-opt=obj-path=%t4.o -shared %t1.o %t2.o -o %t3 +; RUN: llvm-readobj -t %t3 | FileCheck %s +; RUN: llvm-readobj -h %t4.o1 | FileCheck -check-prefix=ELF %s +; RUN: llvm-readobj -h %t4.o2 | FileCheck -check-prefix=ELF %s +; RUN: llvm-nm %t4.o1 2>&1 | FileCheck %s -check-prefix=SYMBOLS +; RUN: llvm-nm %t4.o2 2>&1 | FileCheck %p/Inputs/obj-path.ll -check-prefix=SYMBOLS + +; CHECK: Name: g +; CHECK-NEXT: Value: 0x1010 +; CHECK: Name: f +; CHECK-NEXT: Value: 0x1000 + +; SYMBOLS: T f + +; ELF: Format: ELF64-x86-64 + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +declare void @g(...) + +define void @f() { +entry: + call void (...) @g() + ret void +}