Index: lld/test/ELF/stdout.s =================================================================== --- /dev/null +++ lld/test/ELF/stdout.s @@ -0,0 +1,12 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: ld.lld %t.o -o - > %t +# RUN: llvm-objdump -d %t | FileCheck %s + +# CHECK: 0000000000201000 _start: +# CHECK: 201000: 90 nop + +.globl _start +_start: + nop Index: llvm/lib/Support/FileOutputBuffer.cpp =================================================================== --- llvm/lib/Support/FileOutputBuffer.cpp +++ llvm/lib/Support/FileOutputBuffer.cpp @@ -76,32 +76,26 @@ // output file on commit(). This is used only when we cannot use OnDiskBuffer. class InMemoryBuffer : public FileOutputBuffer { public: - InMemoryBuffer(StringRef Path, MemoryBlock Buf, unsigned Mode) - : FileOutputBuffer(Path), Buffer(Buf), Mode(Mode) {} + InMemoryBuffer(StringRef Path, std::unique_ptr &OS, + MemoryBlock MB) + : FileOutputBuffer(Path), OS(std::move(OS)), MB(MB) {} - uint8_t *getBufferStart() const override { return (uint8_t *)Buffer.base(); } + uint8_t *getBufferStart() const override { return (uint8_t *)MB.base(); } uint8_t *getBufferEnd() const override { - return (uint8_t *)Buffer.base() + Buffer.size(); + return (uint8_t *)MB.base() + MB.size(); } - size_t getBufferSize() const override { return Buffer.size(); } + size_t getBufferSize() const override { return MB.size(); } Error commit() override { - using namespace sys::fs; - int FD; - std::error_code EC; - if (auto EC = - openFileForWrite(FinalPath, FD, CD_CreateAlways, OF_None, Mode)) - return errorCodeToError(EC); - raw_fd_ostream OS(FD, /*shouldClose=*/true, /*unbuffered=*/true); - OS << StringRef((const char *)Buffer.base(), Buffer.size()); + *OS << StringRef((const char *)MB.base(), MB.size()); return Error::success(); } private: - OwningMemoryBlock Buffer; - unsigned Mode; + std::unique_ptr OS; + OwningMemoryBlock MB; }; } // namespace @@ -112,7 +106,15 @@ Size, nullptr, sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC); if (EC) return errorCodeToError(EC); - return llvm::make_unique(Path, MB, Mode); + + int FD; + if (auto EC = sys::fs::openFileForWrite(Path, FD, sys::fs::CD_CreateAlways, + sys::fs::OF_None, Mode)) + return errorCodeToError(EC); + auto OS = make_unique(FD, /*shouldClose=*/true, + /*unbuffered=*/true); + + return llvm::make_unique(Path, OS, MB); } static Expected> @@ -150,6 +152,19 @@ // Create an instance of FileOutputBuffer. Expected> FileOutputBuffer::create(StringRef Path, size_t Size, unsigned Flags) { + // Handle "-" as stdout just like llvm::raw_ostream does. + if (Path == "-") { + std::error_code EC; + MemoryBlock MB = Memory::allocateMappedMemory( + Size, nullptr, sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC); + if (EC) + return errorCodeToError(EC); + + auto OS = make_unique(Path, EC, sys::fs::F_None); + assert(!EC); + return llvm::make_unique(Path, OS, MB); + } + unsigned Mode = fs::all_read | fs::all_write; if (Flags & F_executable) Mode |= fs::all_exe;