summaryrefslogtreecommitdiff
path: root/unittests
diff options
context:
space:
mode:
authorPavel Labath <labath@google.com>2017-12-19 12:15:50 +0000
committerPavel Labath <labath@google.com>2017-12-19 12:15:50 +0000
commit9524e3f4683938f9291e404b39d00951fd682356 (patch)
tree2f18f46ddea3e6339993c4e48a6158d4871df008 /unittests
parent7466c9c8daacce42074cb636989806a25a3b30f7 (diff)
[Support] Add WritableMemoryBuffer class
Summary: The motivation here is LLDB, where we need to fixup relocations in mmapped files before their contents can be read correctly. The MemoryBuffer class does exactly what we need, *except* that it maps the file in read-only mode. WritableMemoryBuffer reuses the existing machinery for opening and mmapping a file. The only difference is in the argument to the mapped_file_region constructor -- we create a private copy-on-write mapping, so that we can make changes to the mapped data, but the changes aren't carried over to the underlying file. This patch is based on an initial version by Zachary Turner. Reviewers: mehdi_amini, rnk, rafael, dblaikie, zturner Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D40291 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@321071 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'unittests')
-rw-r--r--unittests/Support/MemoryBufferTest.cpp34
1 files changed, 34 insertions, 0 deletions
diff --git a/unittests/Support/MemoryBufferTest.cpp b/unittests/Support/MemoryBufferTest.cpp
index 294581aeb92..0d9578621e0 100644
--- a/unittests/Support/MemoryBufferTest.cpp
+++ b/unittests/Support/MemoryBufferTest.cpp
@@ -15,6 +15,7 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/Testing/Support/Error.h"
#include "gtest/gtest.h"
using namespace llvm;
@@ -226,4 +227,37 @@ TEST_F(MemoryBufferTest, slice) {
EXPECT_TRUE(BufData2.substr(0x1800,8).equals("abcdefgh"));
EXPECT_TRUE(BufData2.substr(0x2FF8,8).equals("abcdefgh"));
}
+
+TEST_F(MemoryBufferTest, writableSlice) {
+ // Create a file initialized with some data
+ int FD;
+ SmallString<64> TestPath;
+ sys::fs::createTemporaryFile("MemoryBufferTest_WritableSlice", "temp", FD,
+ TestPath);
+ FileRemover Cleanup(TestPath);
+ raw_fd_ostream OF(FD, true);
+ for (unsigned i = 0; i < 0x1000; ++i)
+ OF << "0123456789abcdef";
+ OF.close();
+
+ {
+ auto MBOrError =
+ WritableMemoryBuffer::getFileSlice(TestPath.str(), 0x6000, 0x2000);
+ ASSERT_FALSE(MBOrError.getError());
+ // Write some data. It should be mapped private, so that upon completion
+ // the original file contents are not modified.
+ WritableMemoryBuffer &MB = **MBOrError;
+ ASSERT_EQ(0x6000u, MB.getBufferSize());
+ char *Start = MB.getBufferStart();
+ ASSERT_EQ(MB.getBufferEnd(), MB.getBufferStart() + MB.getBufferSize());
+ ::memset(Start, 'x', MB.getBufferSize());
+ }
+
+ auto MBOrError = MemoryBuffer::getFile(TestPath);
+ ASSERT_FALSE(MBOrError.getError());
+ auto &MB = **MBOrError;
+ ASSERT_EQ(0x10000u, MB.getBufferSize());
+ for (size_t i = 0; i < MB.getBufferSize(); i += 0x10)
+ EXPECT_EQ("0123456789abcdef", MB.getBuffer().substr(i, 0x10)) << "i: " << i;
+}
}