blob: f8af3a04986761a9d8d3dc545b2af916c37d6f95 [file] [log] [blame]
Zachary Turner90b8b8d2016-05-31 22:41:52 +00001//===- llvm/unittest/DebugInfo/PDB/MappedBlockStreamTest.cpp --------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include <unordered_map>
11
12#include "llvm/DebugInfo/CodeView/StreamReader.h"
13#include "llvm/DebugInfo/CodeView/StreamRef.h"
14#include "llvm/DebugInfo/PDB/Raw/IPDBFile.h"
15#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
16#include "gtest/gtest.h"
17
18using namespace llvm;
19using namespace llvm::codeview;
20using namespace llvm::pdb;
21
22namespace {
23
24#define EXPECT_NO_ERROR(Err) \
25 { \
Zachary Turnerd665a7f2016-06-01 18:18:55 +000026 auto E = Err; \
Zachary Turner90b8b8d2016-05-31 22:41:52 +000027 EXPECT_FALSE(static_cast<bool>(E)); \
28 if (E) \
29 consumeError(std::move(E)); \
30 }
31
32#define EXPECT_ERROR(Err) \
33 { \
Zachary Turnerd665a7f2016-06-01 18:18:55 +000034 auto E = Err; \
Zachary Turner90b8b8d2016-05-31 22:41:52 +000035 EXPECT_TRUE(static_cast<bool>(E)); \
36 if (E) \
37 consumeError(std::move(E)); \
38 }
39
NAKAMURA Takumi47d1e372016-06-01 14:26:54 +000040static const uint32_t BlocksAry[] = {0, 1, 2, 5, 4, 3, 6, 7, 8, 9};
41static const char DataAry[] = {'A', 'B', 'C', 'F', 'E',
42 'D', 'G', 'H', 'I', 'J'};
43
Zachary Turner90b8b8d2016-05-31 22:41:52 +000044class DiscontiguousFile : public IPDBFile {
45public:
46 DiscontiguousFile()
NAKAMURA Takumi47d1e372016-06-01 14:26:54 +000047 : Blocks(&BlocksAry[0], &BlocksAry[10]), Data(&DataAry[0], &DataAry[10]) {
48 }
Zachary Turner90b8b8d2016-05-31 22:41:52 +000049
50 virtual uint32_t getBlockSize() const override { return 1; }
51 virtual uint32_t getBlockCount() const override { return 10; }
52 virtual uint32_t getNumStreams() const override { return 1; }
53 virtual uint32_t getStreamByteSize(uint32_t StreamIndex) const override {
54 return getBlockCount() * getBlockSize();
55 }
56 virtual ArrayRef<uint32_t>
57 getStreamBlockList(uint32_t StreamIndex) const override {
58 if (StreamIndex != 0)
59 return ArrayRef<uint32_t>();
60 return Blocks;
61 }
62 virtual StringRef getBlockData(uint32_t BlockIndex,
63 uint32_t NumBytes) const override {
64 return StringRef(&Data[BlockIndex], NumBytes);
65 }
66
67private:
68 std::vector<uint32_t> Blocks;
69 std::vector<char> Data;
70};
71
72// Tests that a read which is entirely contained within a single block works
73// and does not allocate.
David Majnemerb6aa8752016-06-01 18:13:06 +000074TEST(MappedBlockStreamTest, ReadBeyondEndOfStreamRef) {
Zachary Turner90b8b8d2016-05-31 22:41:52 +000075 DiscontiguousFile F;
76 MappedBlockStream S(0, F);
77 StreamReader R(S);
David Majnemerb6aa8752016-06-01 18:13:06 +000078 StreamRef SR;
79 EXPECT_NO_ERROR(R.readStreamRef(SR, 0U));
80 ArrayRef<uint8_t> Buffer;
81 EXPECT_ERROR(SR.readBytes(0U, 1U, Buffer));
Zachary Turner90b8b8d2016-05-31 22:41:52 +000082}
83
84// Tests that a read which outputs into a full destination buffer works and
85// does not fail due to the length of the output buffer.
86TEST(MappedBlockStreamTest, ReadOntoNonEmptyBuffer) {
87 DiscontiguousFile F;
88 MappedBlockStream S(0, F);
89 StreamReader R(S);
90 StringRef Str = "ZYXWVUTSRQPONMLKJIHGFEDCBA";
91 EXPECT_NO_ERROR(R.readFixedString(Str, 1));
92 EXPECT_EQ(Str, StringRef("A"));
David Majnemerc0113052016-06-01 18:13:02 +000093 EXPECT_EQ(0U, S.getNumBytesCopied());
Zachary Turner90b8b8d2016-05-31 22:41:52 +000094}
95
96// Tests that a read which crosses a block boundary, but where the subsequent
97// blocks are still contiguous in memory to the previous block works and does
98// not allocate memory.
99TEST(MappedBlockStreamTest, ZeroCopyReadContiguousBreak) {
100 DiscontiguousFile F;
101 MappedBlockStream S(0, F);
102 StreamReader R(S);
103 StringRef Str;
104 EXPECT_NO_ERROR(R.readFixedString(Str, 2));
105 EXPECT_EQ(Str, StringRef("AB"));
David Majnemerc0113052016-06-01 18:13:02 +0000106 EXPECT_EQ(0U, S.getNumBytesCopied());
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000107
108 R.setOffset(6);
109 EXPECT_NO_ERROR(R.readFixedString(Str, 4));
110 EXPECT_EQ(Str, StringRef("GHIJ"));
David Majnemerc0113052016-06-01 18:13:02 +0000111 EXPECT_EQ(0U, S.getNumBytesCopied());
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000112}
113
114// Tests that a read which crosses a block boundary and cannot be referenced
115// contiguously works and allocates only the precise amount of bytes
116// requested.
117TEST(MappedBlockStreamTest, CopyReadNonContiguousBreak) {
118 DiscontiguousFile F;
119 MappedBlockStream S(0, F);
120 StreamReader R(S);
121 StringRef Str;
122 EXPECT_NO_ERROR(R.readFixedString(Str, 10));
123 EXPECT_EQ(Str, StringRef("ABCDEFGHIJ"));
David Majnemerc0113052016-06-01 18:13:02 +0000124 EXPECT_EQ(10U, S.getNumBytesCopied());
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000125}
126
127// Test that an out of bounds read which doesn't cross a block boundary
128// fails and allocates no memory.
129TEST(MappedBlockStreamTest, InvalidReadSizeNoBreak) {
130 DiscontiguousFile F;
131 MappedBlockStream S(0, F);
132 StreamReader R(S);
133 StringRef Str;
134
135 R.setOffset(10);
136 EXPECT_ERROR(R.readFixedString(Str, 1));
David Majnemerc0113052016-06-01 18:13:02 +0000137 EXPECT_EQ(0U, S.getNumBytesCopied());
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000138}
139
140// Test that an out of bounds read which crosses a contiguous block boundary
141// fails and allocates no memory.
142TEST(MappedBlockStreamTest, InvalidReadSizeContiguousBreak) {
143 DiscontiguousFile F;
144 MappedBlockStream S(0, F);
145 StreamReader R(S);
146 StringRef Str;
147
148 R.setOffset(6);
149 EXPECT_ERROR(R.readFixedString(Str, 5));
David Majnemerc0113052016-06-01 18:13:02 +0000150 EXPECT_EQ(0U, S.getNumBytesCopied());
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000151}
152
153// Test that an out of bounds read which crosses a discontiguous block
154// boundary fails and allocates no memory.
155TEST(MappedBlockStreamTest, InvalidReadSizeNonContiguousBreak) {
156 DiscontiguousFile F;
157 MappedBlockStream S(0, F);
158 StreamReader R(S);
159 StringRef Str;
160
161 EXPECT_ERROR(R.readFixedString(Str, 11));
David Majnemerc0113052016-06-01 18:13:02 +0000162 EXPECT_EQ(0U, S.getNumBytesCopied());
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000163}
164
David Majnemerb6aa8752016-06-01 18:13:06 +0000165// Tests that a read which is entirely contained within a single block but
166// beyond the end of a StreamRef fails.
167TEST(MappedBlockStreamTest, ZeroCopyReadNoBreak) {
168 DiscontiguousFile F;
169 MappedBlockStream S(0, F);
170 StreamReader R(S);
171 StringRef Str;
172 EXPECT_NO_ERROR(R.readFixedString(Str, 1));
173 EXPECT_EQ(Str, StringRef("A"));
174 EXPECT_EQ(0U, S.getNumBytesCopied());
175}
176
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000177} // end anonymous namespace