[ARM] Remove declaration of unimplemented function. NFC.
[llvm-complete.git] / unittests / DebugInfo / GSYM / GSYMTest.cpp
blobf0e488e731bc166c54d3c14ea98e38e1634cb3a5
1 //===- llvm/unittest/DebugInfo/GSYMTest.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 //===----------------------------------------------------------------------===//
10 #include "llvm/ADT/DenseMap.h"
11 #include "llvm/ADT/SmallString.h"
12 #include "llvm/DebugInfo/GSYM/FileEntry.h"
13 #include "llvm/DebugInfo/GSYM/FileWriter.h"
14 #include "llvm/DebugInfo/GSYM/FunctionInfo.h"
15 #include "llvm/DebugInfo/GSYM/InlineInfo.h"
16 #include "llvm/DebugInfo/GSYM/Range.h"
17 #include "llvm/DebugInfo/GSYM/StringTable.h"
18 #include "llvm/Support/DataExtractor.h"
19 #include "llvm/Support/Endian.h"
21 #include "gtest/gtest.h"
22 #include <string>
24 using namespace llvm;
25 using namespace gsym;
27 TEST(GSYMTest, TestFileEntry) {
28 // Make sure default constructed GSYM FileEntry has zeroes in the
29 // directory and basename string table indexes.
30 FileEntry empty1;
31 FileEntry empty2;
32 EXPECT_EQ(empty1.Dir, 0u);
33 EXPECT_EQ(empty1.Base, 0u);
34 // Verify equality operator works
35 FileEntry a1(10, 30);
36 FileEntry a2(10, 30);
37 FileEntry b(10, 40);
38 EXPECT_EQ(empty1, empty2);
39 EXPECT_EQ(a1, a2);
40 EXPECT_NE(a1, b);
41 EXPECT_NE(a1, empty1);
42 // Test we can use llvm::gsym::FileEntry in llvm::DenseMap.
43 DenseMap<FileEntry, uint32_t> EntryToIndex;
44 constexpr uint32_t Index1 = 1;
45 constexpr uint32_t Index2 = 1;
46 auto R = EntryToIndex.insert(std::make_pair(a1, Index1));
47 EXPECT_TRUE(R.second);
48 EXPECT_EQ(R.first->second, Index1);
49 R = EntryToIndex.insert(std::make_pair(a1, Index1));
50 EXPECT_FALSE(R.second);
51 EXPECT_EQ(R.first->second, Index1);
52 R = EntryToIndex.insert(std::make_pair(b, Index2));
53 EXPECT_TRUE(R.second);
54 EXPECT_EQ(R.first->second, Index2);
55 R = EntryToIndex.insert(std::make_pair(a1, Index2));
56 EXPECT_FALSE(R.second);
57 EXPECT_EQ(R.first->second, Index2);
60 TEST(GSYMTest, TestFunctionInfo) {
61 // Test GSYM FunctionInfo structs and functionality.
62 FunctionInfo invalid;
63 EXPECT_FALSE(invalid.isValid());
64 EXPECT_FALSE(invalid.hasRichInfo());
65 const uint64_t StartAddr = 0x1000;
66 const uint64_t EndAddr = 0x1100;
67 const uint64_t Size = EndAddr - StartAddr;
68 const uint32_t NameOffset = 30;
69 FunctionInfo FI(StartAddr, Size, NameOffset);
70 EXPECT_TRUE(FI.isValid());
71 EXPECT_FALSE(FI.hasRichInfo());
72 EXPECT_EQ(FI.startAddress(), StartAddr);
73 EXPECT_EQ(FI.endAddress(), EndAddr);
74 EXPECT_EQ(FI.size(), Size);
75 const uint32_t FileIdx = 1;
76 const uint32_t Line = 12;
77 FI.Lines.push_back(LineEntry(StartAddr, FileIdx, Line));
78 EXPECT_TRUE(FI.hasRichInfo());
79 FI.clear();
80 EXPECT_FALSE(FI.isValid());
81 EXPECT_FALSE(FI.hasRichInfo());
83 FunctionInfo A1(0x1000, 0x100, NameOffset);
84 FunctionInfo A2(0x1000, 0x100, NameOffset);
85 FunctionInfo B;
86 // Check == operator
87 EXPECT_EQ(A1, A2);
88 // Make sure things are not equal if they only differ by start address.
89 B = A2;
90 B.setStartAddress(0x2000);
91 EXPECT_NE(B, A2);
92 // Make sure things are not equal if they only differ by size.
93 B = A2;
94 B.setSize(0x101);
95 EXPECT_NE(B, A2);
96 // Make sure things are not equal if they only differ by name.
97 B = A2;
98 B.Name = 60;
99 EXPECT_NE(B, A2);
100 // Check < operator.
101 // Check less than where address differs.
102 B = A2;
103 B.setStartAddress(A2.startAddress() + 0x1000);
104 EXPECT_LT(A1, B);
106 // We use the < operator to take a variety of different FunctionInfo
107 // structs from a variety of sources: symtab, debug info, runtime info
108 // and we sort them and want the sorting to allow us to quickly get the
109 // best version of a function info.
110 FunctionInfo FISymtab(StartAddr, Size, NameOffset);
111 FunctionInfo FIWithLines(StartAddr, Size, NameOffset);
112 FIWithLines.Lines.push_back(LineEntry(StartAddr, FileIdx, Line));
113 // Test that a FunctionInfo with just a name and size is less than one
114 // that has name, size and any number of line table entries
115 EXPECT_LT(FISymtab, FIWithLines);
117 FunctionInfo FIWithLinesAndInline = FIWithLines;
118 FIWithLinesAndInline.Inline.Ranges.insert(
119 AddressRange(StartAddr, StartAddr + 0x10));
120 // Test that a FunctionInfo with name, size, and line entries is less than
121 // the same one with valid inline info
122 EXPECT_LT(FIWithLines, FIWithLinesAndInline);
124 // Test if we have an entry with lines and one with more lines for the same
125 // range, the ones with more lines is greater than the one with less.
126 FunctionInfo FIWithMoreLines = FIWithLines;
127 FIWithMoreLines.Lines.push_back(LineEntry(StartAddr, FileIdx, Line + 5));
128 EXPECT_LT(FIWithLines, FIWithMoreLines);
130 // Test that if we have the same number of lines we compare the line entries
131 // in the FunctionInfo.Lines vector.
132 FunctionInfo FIWithLinesWithHigherAddress = FIWithLines;
133 FIWithLinesWithHigherAddress.Lines[0].Addr += 0x10;
134 EXPECT_LT(FIWithLines, FIWithLinesWithHigherAddress);
137 void checkError(ArrayRef<std::string> ExpectedMsgs, Error Err) {
138 ASSERT_TRUE(Err.operator bool());
139 size_t WhichMsg = 0;
140 Error Remaining =
141 handleErrors(std::move(Err), [&](const ErrorInfoBase &Actual) {
142 ASSERT_LT(WhichMsg, ExpectedMsgs.size());
143 // Use .str(), because googletest doesn't visualise a StringRef
144 // properly.
145 EXPECT_EQ(Actual.message(), ExpectedMsgs[WhichMsg++]);
147 EXPECT_EQ(WhichMsg, ExpectedMsgs.size());
148 EXPECT_FALSE(Remaining);
151 void checkError(std::string ExpectedMsg, Error Err) {
152 checkError(ArrayRef<std::string>{ExpectedMsg}, std::move(Err));
155 static void TestInlineInfoEncodeDecode(llvm::support::endianness ByteOrder,
156 const InlineInfo &Inline) {
157 // Test encoding and decoding InlineInfo objects
158 SmallString<512> Str;
159 raw_svector_ostream OutStrm(Str);
160 FileWriter FW(OutStrm, ByteOrder);
161 const uint64_t BaseAddr = Inline.Ranges[0].Start;
162 llvm::Error Err = Inline.encode(FW, BaseAddr);
163 ASSERT_FALSE(Err);
164 std::string Bytes(OutStrm.str());
165 uint8_t AddressSize = 4;
166 DataExtractor Data(Bytes, ByteOrder == llvm::support::little, AddressSize);
167 llvm::Expected<InlineInfo> Decoded = InlineInfo::decode(Data, BaseAddr);
168 // Make sure decoding succeeded.
169 ASSERT_TRUE((bool)Decoded);
170 // Make sure decoded object is the same as the one we encoded.
171 EXPECT_EQ(Inline, Decoded.get());
174 static void TestInlineInfoDecodeError(llvm::support::endianness ByteOrder,
175 std::string Bytes,
176 const uint64_t BaseAddr,
177 std::string ExpectedErrorMsg) {
178 uint8_t AddressSize = 4;
179 DataExtractor Data(Bytes, ByteOrder == llvm::support::little, AddressSize);
180 llvm::Expected<InlineInfo> Decoded = InlineInfo::decode(Data, BaseAddr);
181 // Make sure decoding fails.
182 ASSERT_FALSE((bool)Decoded);
183 // Make sure decoded object is the same as the one we encoded.
184 checkError(ExpectedErrorMsg, Decoded.takeError());
187 static void TestInlineInfoEncodeError(llvm::support::endianness ByteOrder,
188 const InlineInfo &Inline,
189 std::string ExpectedErrorMsg) {
190 SmallString<512> Str;
191 raw_svector_ostream OutStrm(Str);
192 FileWriter FW(OutStrm, ByteOrder);
193 const uint64_t BaseAddr = Inline.Ranges.empty() ? 0 : Inline.Ranges[0].Start;
194 llvm::Error Err = Inline.encode(FW, BaseAddr);
195 checkError(ExpectedErrorMsg, std::move(Err));
198 TEST(GSYMTest, TestInlineInfo) {
199 // Test InlineInfo structs.
200 InlineInfo II;
201 EXPECT_FALSE(II.isValid());
202 II.Ranges.insert(AddressRange(0x1000, 0x2000));
203 // Make sure InlineInfo in valid with just an address range since
204 // top level InlineInfo objects have ranges with no name, call file
205 // or call line
206 EXPECT_TRUE(II.isValid());
207 // Make sure InlineInfo isn't after being cleared.
208 II.clear();
209 EXPECT_FALSE(II.isValid());
211 // Create an InlineInfo that contains the following data. The
212 // indentation of the address range indicates the parent child
213 // relationships of the InlineInfo objects:
215 // Variable Range and values
216 // =========== ====================================================
217 // Root [0x100-0x200) (no name, file, or line)
218 // Inline1 [0x150-0x160) Name = 1, File = 1, Line = 11
219 // Inline1Sub1 [0x152-0x155) Name = 2, File = 2, Line = 22
220 // Inline1Sub2 [0x157-0x158) Name = 3, File = 3, Line = 33
221 InlineInfo Root;
222 Root.Ranges.insert(AddressRange(0x100, 0x200));
223 InlineInfo Inline1;
224 Inline1.Ranges.insert(AddressRange(0x150, 0x160));
225 Inline1.Name = 1;
226 Inline1.CallFile = 1;
227 Inline1.CallLine = 11;
228 InlineInfo Inline1Sub1;
229 Inline1Sub1.Ranges.insert(AddressRange(0x152, 0x155));
230 Inline1Sub1.Name = 2;
231 Inline1Sub1.CallFile = 2;
232 Inline1Sub1.CallLine = 22;
233 InlineInfo Inline1Sub2;
234 Inline1Sub2.Ranges.insert(AddressRange(0x157, 0x158));
235 Inline1Sub2.Name = 3;
236 Inline1Sub2.CallFile = 3;
237 Inline1Sub2.CallLine = 33;
238 Inline1.Children.push_back(Inline1Sub1);
239 Inline1.Children.push_back(Inline1Sub2);
240 Root.Children.push_back(Inline1);
242 // Make sure an address that is out of range won't match
243 EXPECT_FALSE(Root.getInlineStack(0x50));
245 // Verify that we get no inline stacks for addresses out of [0x100-0x200)
246 EXPECT_FALSE(Root.getInlineStack(Root.Ranges[0].Start - 1));
247 EXPECT_FALSE(Root.getInlineStack(Root.Ranges[0].End));
249 // Verify we get no inline stack entries for addresses that are in
250 // [0x100-0x200) but not in [0x150-0x160)
251 EXPECT_FALSE(Root.getInlineStack(Inline1.Ranges[0].Start - 1));
252 EXPECT_FALSE(Root.getInlineStack(Inline1.Ranges[0].End));
254 // Verify we get one inline stack entry for addresses that are in
255 // [[0x150-0x160)) but not in [0x152-0x155) or [0x157-0x158)
256 auto InlineInfos = Root.getInlineStack(Inline1.Ranges[0].Start);
257 ASSERT_TRUE(InlineInfos);
258 ASSERT_EQ(InlineInfos->size(), 1u);
259 ASSERT_EQ(*InlineInfos->at(0), Inline1);
260 InlineInfos = Root.getInlineStack(Inline1.Ranges[0].End - 1);
261 EXPECT_TRUE(InlineInfos);
262 ASSERT_EQ(InlineInfos->size(), 1u);
263 ASSERT_EQ(*InlineInfos->at(0), Inline1);
265 // Verify we get two inline stack entries for addresses that are in
266 // [0x152-0x155)
267 InlineInfos = Root.getInlineStack(Inline1Sub1.Ranges[0].Start);
268 EXPECT_TRUE(InlineInfos);
269 ASSERT_EQ(InlineInfos->size(), 2u);
270 ASSERT_EQ(*InlineInfos->at(0), Inline1Sub1);
271 ASSERT_EQ(*InlineInfos->at(1), Inline1);
272 InlineInfos = Root.getInlineStack(Inline1Sub1.Ranges[0].End - 1);
273 EXPECT_TRUE(InlineInfos);
274 ASSERT_EQ(InlineInfos->size(), 2u);
275 ASSERT_EQ(*InlineInfos->at(0), Inline1Sub1);
276 ASSERT_EQ(*InlineInfos->at(1), Inline1);
278 // Verify we get two inline stack entries for addresses that are in
279 // [0x157-0x158)
280 InlineInfos = Root.getInlineStack(Inline1Sub2.Ranges[0].Start);
281 EXPECT_TRUE(InlineInfos);
282 ASSERT_EQ(InlineInfos->size(), 2u);
283 ASSERT_EQ(*InlineInfos->at(0), Inline1Sub2);
284 ASSERT_EQ(*InlineInfos->at(1), Inline1);
285 InlineInfos = Root.getInlineStack(Inline1Sub2.Ranges[0].End - 1);
286 EXPECT_TRUE(InlineInfos);
287 ASSERT_EQ(InlineInfos->size(), 2u);
288 ASSERT_EQ(*InlineInfos->at(0), Inline1Sub2);
289 ASSERT_EQ(*InlineInfos->at(1), Inline1);
291 // Test encoding and decoding InlineInfo objects
292 TestInlineInfoEncodeDecode(llvm::support::little, Root);
293 TestInlineInfoEncodeDecode(llvm::support::big, Root);
296 TEST(GSYMTest, TestInlineInfoEncodeErrors) {
297 // Test InlineInfo encoding errors.
299 // Test that we get an error when trying to encode an InlineInfo object
300 // that has no ranges.
301 InlineInfo Empty;
302 std::string EmptyErr("attempted to encode invalid InlineInfo object");
303 TestInlineInfoEncodeError(llvm::support::little, Empty, EmptyErr);
304 TestInlineInfoEncodeError(llvm::support::big, Empty, EmptyErr);
306 // Verify that we get an error trying to encode an InlineInfo object that has
307 // a child InlineInfo that has no ranges.
308 InlineInfo ContainsEmpty;
309 ContainsEmpty.Ranges.insert({0x100,200});
310 ContainsEmpty.Children.push_back(Empty);
311 TestInlineInfoEncodeError(llvm::support::little, ContainsEmpty, EmptyErr);
312 TestInlineInfoEncodeError(llvm::support::big, ContainsEmpty, EmptyErr);
314 // Verify that we get an error trying to encode an InlineInfo object that has
315 // a child whose address range is not contained in the parent address range.
316 InlineInfo ChildNotContained;
317 std::string ChildNotContainedErr("child range not contained in parent");
318 ChildNotContained.Ranges.insert({0x100,200});
319 InlineInfo ChildNotContainedChild;
320 ChildNotContainedChild.Ranges.insert({0x200,300});
321 ChildNotContained.Children.push_back(ChildNotContainedChild);
322 TestInlineInfoEncodeError(llvm::support::little, ChildNotContained,
323 ChildNotContainedErr);
324 TestInlineInfoEncodeError(llvm::support::big, ChildNotContained,
325 ChildNotContainedErr);
329 TEST(GSYMTest, TestInlineInfoDecodeErrors) {
330 // Test decoding InlineInfo objects that ensure we report an appropriate
331 // error message.
332 const llvm::support::endianness ByteOrder = llvm::support::little;
333 SmallString<512> Str;
334 raw_svector_ostream OutStrm(Str);
335 FileWriter FW(OutStrm, ByteOrder);
336 const uint64_t BaseAddr = 0x100;
337 TestInlineInfoDecodeError(ByteOrder, OutStrm.str(), BaseAddr,
338 "0x00000000: missing InlineInfo address ranges data");
339 AddressRanges Ranges;
340 Ranges.insert({BaseAddr, BaseAddr+0x100});
341 Ranges.encode(FW, BaseAddr);
342 TestInlineInfoDecodeError(ByteOrder, OutStrm.str(), BaseAddr,
343 "0x00000004: missing InlineInfo uint8_t indicating children");
344 FW.writeU8(0);
345 TestInlineInfoDecodeError(ByteOrder, OutStrm.str(), BaseAddr,
346 "0x00000005: missing InlineInfo uint32_t for name");
347 FW.writeU32(0);
348 TestInlineInfoDecodeError(ByteOrder, OutStrm.str(), BaseAddr,
349 "0x00000009: missing ULEB128 for InlineInfo call file");
350 FW.writeU8(0);
351 TestInlineInfoDecodeError(ByteOrder, OutStrm.str(), BaseAddr,
352 "0x0000000a: missing ULEB128 for InlineInfo call line");
355 TEST(GSYMTest, TestLineEntry) {
356 // test llvm::gsym::LineEntry structs.
357 const uint64_t ValidAddr = 0x1000;
358 const uint64_t InvalidFileIdx = 0;
359 const uint32_t ValidFileIdx = 1;
360 const uint32_t ValidLine = 5;
362 LineEntry Invalid;
363 EXPECT_FALSE(Invalid.isValid());
364 // Make sure that an entry is invalid if it has a bad file index.
365 LineEntry BadFile(ValidAddr, InvalidFileIdx, ValidLine);
366 EXPECT_FALSE(BadFile.isValid());
367 // Test operators
368 LineEntry E1(ValidAddr, ValidFileIdx, ValidLine);
369 LineEntry E2(ValidAddr, ValidFileIdx, ValidLine);
370 LineEntry DifferentAddr(ValidAddr + 1, ValidFileIdx, ValidLine);
371 LineEntry DifferentFile(ValidAddr, ValidFileIdx + 1, ValidLine);
372 LineEntry DifferentLine(ValidAddr, ValidFileIdx, ValidLine + 1);
373 EXPECT_TRUE(E1.isValid());
374 EXPECT_EQ(E1, E2);
375 EXPECT_NE(E1, DifferentAddr);
376 EXPECT_NE(E1, DifferentFile);
377 EXPECT_NE(E1, DifferentLine);
378 EXPECT_LT(E1, DifferentAddr);
381 TEST(GSYMTest, TestRanges) {
382 // test llvm::gsym::AddressRange.
383 const uint64_t StartAddr = 0x1000;
384 const uint64_t EndAddr = 0x2000;
385 // Verify constructor and API to ensure it takes start and end address.
386 const AddressRange Range(StartAddr, EndAddr);
387 EXPECT_EQ(Range.size(), EndAddr - StartAddr);
389 // Verify llvm::gsym::AddressRange::contains().
390 EXPECT_FALSE(Range.contains(0));
391 EXPECT_FALSE(Range.contains(StartAddr - 1));
392 EXPECT_TRUE(Range.contains(StartAddr));
393 EXPECT_TRUE(Range.contains(EndAddr - 1));
394 EXPECT_FALSE(Range.contains(EndAddr));
395 EXPECT_FALSE(Range.contains(UINT64_MAX));
397 const AddressRange RangeSame(StartAddr, EndAddr);
398 const AddressRange RangeDifferentStart(StartAddr + 1, EndAddr);
399 const AddressRange RangeDifferentEnd(StartAddr, EndAddr + 1);
400 const AddressRange RangeDifferentStartEnd(StartAddr + 1, EndAddr + 1);
401 // Test == and != with values that are the same
402 EXPECT_EQ(Range, RangeSame);
403 EXPECT_FALSE(Range != RangeSame);
404 // Test == and != with values that are the different
405 EXPECT_NE(Range, RangeDifferentStart);
406 EXPECT_NE(Range, RangeDifferentEnd);
407 EXPECT_NE(Range, RangeDifferentStartEnd);
408 EXPECT_FALSE(Range == RangeDifferentStart);
409 EXPECT_FALSE(Range == RangeDifferentEnd);
410 EXPECT_FALSE(Range == RangeDifferentStartEnd);
412 // Test "bool operator<(const AddressRange &, const AddressRange &)".
413 EXPECT_FALSE(Range < RangeSame);
414 EXPECT_FALSE(RangeSame < Range);
415 EXPECT_LT(Range, RangeDifferentStart);
416 EXPECT_LT(Range, RangeDifferentEnd);
417 EXPECT_LT(Range, RangeDifferentStartEnd);
418 // Test "bool operator<(const AddressRange &, uint64_t)"
419 EXPECT_LT(Range.Start, StartAddr + 1);
420 // Test "bool operator<(uint64_t, const AddressRange &)"
421 EXPECT_LT(StartAddr - 1, Range.Start);
423 // Verify llvm::gsym::AddressRange::isContiguousWith() and
424 // llvm::gsym::AddressRange::intersects().
425 const AddressRange EndsBeforeRangeStart(0, StartAddr - 1);
426 const AddressRange EndsAtRangeStart(0, StartAddr);
427 const AddressRange OverlapsRangeStart(StartAddr - 1, StartAddr + 1);
428 const AddressRange InsideRange(StartAddr + 1, EndAddr - 1);
429 const AddressRange OverlapsRangeEnd(EndAddr - 1, EndAddr + 1);
430 const AddressRange StartsAtRangeEnd(EndAddr, EndAddr + 0x100);
431 const AddressRange StartsAfterRangeEnd(EndAddr + 1, EndAddr + 0x100);
433 EXPECT_FALSE(Range.intersects(EndsBeforeRangeStart));
434 EXPECT_FALSE(Range.intersects(EndsAtRangeStart));
435 EXPECT_TRUE(Range.intersects(OverlapsRangeStart));
436 EXPECT_TRUE(Range.intersects(InsideRange));
437 EXPECT_TRUE(Range.intersects(OverlapsRangeEnd));
438 EXPECT_FALSE(Range.intersects(StartsAtRangeEnd));
439 EXPECT_FALSE(Range.intersects(StartsAfterRangeEnd));
441 // Test the functions that maintain GSYM address ranges:
442 // "bool AddressRange::contains(uint64_t Addr) const;"
443 // "void AddressRanges::insert(const AddressRange &R);"
444 AddressRanges Ranges;
445 Ranges.insert(AddressRange(0x1000, 0x2000));
446 Ranges.insert(AddressRange(0x2000, 0x3000));
447 Ranges.insert(AddressRange(0x4000, 0x5000));
449 EXPECT_FALSE(Ranges.contains(0));
450 EXPECT_FALSE(Ranges.contains(0x1000 - 1));
451 EXPECT_TRUE(Ranges.contains(0x1000));
452 EXPECT_TRUE(Ranges.contains(0x2000));
453 EXPECT_TRUE(Ranges.contains(0x4000));
454 EXPECT_TRUE(Ranges.contains(0x2000 - 1));
455 EXPECT_TRUE(Ranges.contains(0x3000 - 1));
456 EXPECT_FALSE(Ranges.contains(0x3000 + 1));
457 EXPECT_TRUE(Ranges.contains(0x5000 - 1));
458 EXPECT_FALSE(Ranges.contains(0x5000 + 1));
459 EXPECT_FALSE(Ranges.contains(UINT64_MAX));
461 EXPECT_FALSE(Ranges.contains(AddressRange()));
462 EXPECT_FALSE(Ranges.contains(AddressRange(0x1000-1, 0x1000)));
463 EXPECT_FALSE(Ranges.contains(AddressRange(0x1000, 0x1000)));
464 EXPECT_TRUE(Ranges.contains(AddressRange(0x1000, 0x1000+1)));
465 EXPECT_TRUE(Ranges.contains(AddressRange(0x1000, 0x2000)));
466 EXPECT_FALSE(Ranges.contains(AddressRange(0x1000, 0x2001)));
467 EXPECT_TRUE(Ranges.contains(AddressRange(0x2000, 0x3000)));
468 EXPECT_FALSE(Ranges.contains(AddressRange(0x2000, 0x3001)));
469 EXPECT_FALSE(Ranges.contains(AddressRange(0x3000, 0x3001)));
470 EXPECT_FALSE(Ranges.contains(AddressRange(0x1500, 0x4500)));
471 EXPECT_FALSE(Ranges.contains(AddressRange(0x5000, 0x5001)));
473 // Verify that intersecting ranges get combined
474 Ranges.clear();
475 Ranges.insert(AddressRange(0x1100, 0x1F00));
476 // Verify a wholy contained range that is added doesn't do anything.
477 Ranges.insert(AddressRange(0x1500, 0x1F00));
478 EXPECT_EQ(Ranges.size(), 1u);
479 EXPECT_EQ(Ranges[0], AddressRange(0x1100, 0x1F00));
481 // Verify a range that starts before and intersects gets combined.
482 Ranges.insert(AddressRange(0x1000, Ranges[0].Start + 1));
483 EXPECT_EQ(Ranges.size(), 1u);
484 EXPECT_EQ(Ranges[0], AddressRange(0x1000, 0x1F00));
486 // Verify a range that starts inside and extends ranges gets combined.
487 Ranges.insert(AddressRange(Ranges[0].End - 1, 0x2000));
488 EXPECT_EQ(Ranges.size(), 1u);
489 EXPECT_EQ(Ranges[0], AddressRange(0x1000, 0x2000));
491 // Verify that adjacent ranges don't get combined
492 Ranges.insert(AddressRange(0x2000, 0x3000));
493 EXPECT_EQ(Ranges.size(), 2u);
494 EXPECT_EQ(Ranges[0], AddressRange(0x1000, 0x2000));
495 EXPECT_EQ(Ranges[1], AddressRange(0x2000, 0x3000));
496 // Verify if we add an address range that intersects two ranges
497 // that they get combined
498 Ranges.insert(AddressRange(Ranges[0].End - 1, Ranges[1].Start + 1));
499 EXPECT_EQ(Ranges.size(), 1u);
500 EXPECT_EQ(Ranges[0], AddressRange(0x1000, 0x3000));
502 Ranges.insert(AddressRange(0x3000, 0x4000));
503 Ranges.insert(AddressRange(0x4000, 0x5000));
504 Ranges.insert(AddressRange(0x2000, 0x4500));
505 EXPECT_EQ(Ranges.size(), 1u);
506 EXPECT_EQ(Ranges[0], AddressRange(0x1000, 0x5000));
509 TEST(GSYMTest, TestStringTable) {
510 StringTable StrTab(StringRef("\0Hello\0World\0", 13));
511 // Test extracting strings from a string table.
512 EXPECT_EQ(StrTab.getString(0), "");
513 EXPECT_EQ(StrTab.getString(1), "Hello");
514 EXPECT_EQ(StrTab.getString(7), "World");
515 EXPECT_EQ(StrTab.getString(8), "orld");
516 // Test pointing to last NULL terminator gets empty string.
517 EXPECT_EQ(StrTab.getString(12), "");
518 // Test pointing to past end gets empty string.
519 EXPECT_EQ(StrTab.getString(13), "");
522 static void TestFileWriterHelper(llvm::support::endianness ByteOrder) {
523 SmallString<512> Str;
524 raw_svector_ostream OutStrm(Str);
525 FileWriter FW(OutStrm, ByteOrder);
526 const int64_t MinSLEB = INT64_MIN;
527 const int64_t MaxSLEB = INT64_MAX;
528 const uint64_t MinULEB = 0;
529 const uint64_t MaxULEB = UINT64_MAX;
530 const uint8_t U8 = 0x10;
531 const uint16_t U16 = 0x1122;
532 const uint32_t U32 = 0x12345678;
533 const uint64_t U64 = 0x33445566778899aa;
534 const char *Hello = "hello";
535 FW.writeU8(U8);
536 FW.writeU16(U16);
537 FW.writeU32(U32);
538 FW.writeU64(U64);
539 FW.alignTo(16);
540 const off_t FixupOffset = FW.tell();
541 FW.writeU32(0);
542 FW.writeSLEB(MinSLEB);
543 FW.writeSLEB(MaxSLEB);
544 FW.writeULEB(MinULEB);
545 FW.writeULEB(MaxULEB);
546 FW.writeNullTerminated(Hello);
547 // Test Seek, Tell using Fixup32.
548 FW.fixup32(U32, FixupOffset);
550 std::string Bytes(OutStrm.str());
551 uint8_t AddressSize = 4;
552 DataExtractor Data(Bytes, ByteOrder == llvm::support::little, AddressSize);
553 uint64_t Offset = 0;
554 EXPECT_EQ(Data.getU8(&Offset), U8);
555 EXPECT_EQ(Data.getU16(&Offset), U16);
556 EXPECT_EQ(Data.getU32(&Offset), U32);
557 EXPECT_EQ(Data.getU64(&Offset), U64);
558 Offset = alignTo(Offset, 16);
559 EXPECT_EQ(Data.getU32(&Offset), U32);
560 EXPECT_EQ(Data.getSLEB128(&Offset), MinSLEB);
561 EXPECT_EQ(Data.getSLEB128(&Offset), MaxSLEB);
562 EXPECT_EQ(Data.getULEB128(&Offset), MinULEB);
563 EXPECT_EQ(Data.getULEB128(&Offset), MaxULEB);
564 EXPECT_EQ(Data.getCStrRef(&Offset), StringRef(Hello));
567 TEST(GSYMTest, TestFileWriter) {
568 TestFileWriterHelper(llvm::support::little);
569 TestFileWriterHelper(llvm::support::big);
572 TEST(GSYMTest, TestAddressRangeEncodeDecode) {
573 // Test encoding and decoding AddressRange objects. AddressRange objects
574 // are always stored as offsets from the a base address. The base address
575 // is the FunctionInfo's base address for function level ranges, and is
576 // the base address of the parent range for subranges.
577 SmallString<512> Str;
578 raw_svector_ostream OutStrm(Str);
579 const auto ByteOrder = llvm::support::endian::system_endianness();
580 FileWriter FW(OutStrm, ByteOrder);
581 const uint64_t BaseAddr = 0x1000;
582 const AddressRange Range1(0x1000, 0x1010);
583 const AddressRange Range2(0x1020, 0x1030);
584 Range1.encode(FW, BaseAddr);
585 Range2.encode(FW, BaseAddr);
586 std::string Bytes(OutStrm.str());
587 uint8_t AddressSize = 4;
588 DataExtractor Data(Bytes, ByteOrder == llvm::support::little, AddressSize);
590 AddressRange DecodedRange1, DecodedRange2;
591 uint64_t Offset = 0;
592 DecodedRange1.decode(Data, BaseAddr, Offset);
593 DecodedRange2.decode(Data, BaseAddr, Offset);
594 EXPECT_EQ(Range1, DecodedRange1);
595 EXPECT_EQ(Range2, DecodedRange2);
598 static void TestAddressRangeEncodeDecodeHelper(const AddressRanges &Ranges,
599 const uint64_t BaseAddr) {
600 SmallString<512> Str;
601 raw_svector_ostream OutStrm(Str);
602 const auto ByteOrder = llvm::support::endian::system_endianness();
603 FileWriter FW(OutStrm, ByteOrder);
604 Ranges.encode(FW, BaseAddr);
606 std::string Bytes(OutStrm.str());
607 uint8_t AddressSize = 4;
608 DataExtractor Data(Bytes, ByteOrder == llvm::support::little, AddressSize);
610 AddressRanges DecodedRanges;
611 uint64_t Offset = 0;
612 DecodedRanges.decode(Data, BaseAddr, Offset);
613 EXPECT_EQ(Ranges, DecodedRanges);
616 TEST(GSYMTest, TestAddressRangesEncodeDecode) {
617 // Test encoding and decoding AddressRanges. AddressRanges objects contain
618 // ranges that are stored as offsets from the a base address. The base address
619 // is the FunctionInfo's base address for function level ranges, and is the
620 // base address of the parent range for subranges.
621 const uint64_t BaseAddr = 0x1000;
623 // Test encoding and decoding with no ranges.
624 AddressRanges Ranges;
625 TestAddressRangeEncodeDecodeHelper(Ranges, BaseAddr);
627 // Test encoding and decoding with 1 range.
628 Ranges.insert(AddressRange(0x1000, 0x1010));
629 TestAddressRangeEncodeDecodeHelper(Ranges, BaseAddr);
631 // Test encoding and decoding with multiple ranges.
632 Ranges.insert(AddressRange(0x1020, 0x1030));
633 Ranges.insert(AddressRange(0x1050, 0x1070));
634 TestAddressRangeEncodeDecodeHelper(Ranges, BaseAddr);