[PATCH] D56941: Fix a bug that file size is sometimes silently rounded up to the page size.

Rui Ueyama via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 18 14:33:34 PST 2019


ruiu created this revision.
ruiu added reviewers: zturner, thakis.
Herald added subscribers: hiraditya, arichardson, emaste.
Herald added a reviewer: espindola.

FileOutputBuffer usually uses mmap'ed IO, but if mmap is not available
(e.g. if an output file is /dev/null or /dev/stdout), it switches to
MemoryBlock class to buffer output and write file contents on
destruction.

Previously, when FileOutputBuffer falled back to MemoryBlock, the
generated file size is silently rouded up to the file size.


https://reviews.llvm.org/D56941

Files:
  lld/test/ELF/stdout.s
  llvm/lib/Support/FileOutputBuffer.cpp


Index: llvm/lib/Support/FileOutputBuffer.cpp
===================================================================
--- llvm/lib/Support/FileOutputBuffer.cpp
+++ llvm/lib/Support/FileOutputBuffer.cpp
@@ -77,25 +77,26 @@
 class InMemoryBuffer : public FileOutputBuffer {
 public:
   InMemoryBuffer(StringRef Path, std::unique_ptr<raw_fd_ostream> &OS,
-                 MemoryBlock MB)
-      : FileOutputBuffer(Path), OS(std::move(OS)), MB(MB) {}
+                 MemoryBlock MB, size_t Size)
+      : FileOutputBuffer(Path), OS(std::move(OS)), MB(MB), Size(Size) {}
 
   uint8_t *getBufferStart() const override { return (uint8_t *)MB.base(); }
 
   uint8_t *getBufferEnd() const override {
-    return (uint8_t *)MB.base() + MB.size();
+    return (uint8_t *)MB.base() + Size;
   }
 
-  size_t getBufferSize() const override { return MB.size(); }
+  size_t getBufferSize() const override { return Size; }
 
   Error commit() override {
-    *OS << StringRef((const char *)MB.base(), MB.size());
+    *OS << StringRef((const char *)MB.base(), Size);
     return Error::success();
   }
 
 private:
   std::unique_ptr<raw_fd_ostream> OS;
   OwningMemoryBlock MB;
+  size_t Size;
 };
 } // namespace
 
@@ -114,7 +115,7 @@
   auto OS = make_unique<raw_fd_ostream>(FD, /*shouldClose=*/true,
                                         /*unbuffered=*/true);
 
-  return llvm::make_unique<InMemoryBuffer>(Path, OS, MB);
+  return llvm::make_unique<InMemoryBuffer>(Path, OS, MB, Size);
 }
 
 static Expected<std::unique_ptr<OnDiskBuffer>>
@@ -162,7 +163,7 @@
 
     auto OS = make_unique<raw_fd_ostream>("-", EC, sys::fs::F_None);
     assert(!EC);
-    return llvm::make_unique<InMemoryBuffer>("-", OS, MB);
+    return llvm::make_unique<InMemoryBuffer>("-", OS, MB, Size);
   }
 
   unsigned Mode = fs::all_read | fs::all_write;
Index: lld/test/ELF/stdout.s
===================================================================
--- lld/test/ELF/stdout.s
+++ lld/test/ELF/stdout.s
@@ -1,12 +1,15 @@
 # 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
+# RUN: ld.lld %t.o -o - > %t1
+# RUN: llvm-objdump -d %t1 | FileCheck %s
 
 # CHECK: 0000000000201000 _start:
 # CHECK: 201000: 90 nop
 
+# RUN: ld.lld %t.o -o %t2
+# RUN: diff %t1 %t2
+
 .globl _start
 _start:
   nop


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D56941.182613.patch
Type: text/x-patch
Size: 2365 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190118/e5bf6c3d/attachment.bin>


More information about the llvm-commits mailing list