1 //===-- BreakpadRecordsTest.cpp -------------------------------------------===//
2 //
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "Plugins/ObjectFile/Breakpad/BreakpadRecords.h"
11 #include "gtest/gtest.h"
12 
13 using namespace lldb_private;
14 using namespace lldb_private::breakpad;
15 
16 TEST(Record, classify) {
17   EXPECT_EQ(Record::Module, Record::classify("MODULE"));
18   EXPECT_EQ(Record::Info, Record::classify("INFO"));
19   EXPECT_EQ(Record::File, Record::classify("FILE"));
20   EXPECT_EQ(Record::Func, Record::classify("FUNC"));
21   EXPECT_EQ(Record::Public, Record::classify("PUBLIC"));
22   EXPECT_EQ(Record::StackCFI, Record::classify("STACK CFI"));
23   EXPECT_EQ(Record::StackWin, Record::classify("STACK WIN"));
24 
25   // Any obviously incorrect lines will be classified as such.
26   EXPECT_EQ(llvm::None, Record::classify("STACK"));
27   EXPECT_EQ(llvm::None, Record::classify("STACK CODE_ID"));
28   EXPECT_EQ(llvm::None, Record::classify("CODE_ID"));
29 
30   // Any line which does not start with a known keyword will be classified as a
31   // line record, as those are the only ones that start without a keyword.
32   EXPECT_EQ(Record::Line, Record::classify("deadbeef"));
33   EXPECT_EQ(Record::Line, Record::classify("12"));
34 }
35 
36 TEST(ModuleRecord, parse) {
37   EXPECT_EQ(ModuleRecord(llvm::Triple::Linux, llvm::Triple::x86_64,
38                          UUID::fromData("@ABCDEFGHIJKLMNO", 16)),
39             ModuleRecord::parse(
40                 "MODULE Linux x86_64 404142434445464748494a4b4c4d4e4f0 a.out"));
41 
42   EXPECT_EQ(llvm::None, ModuleRecord::parse("MODULE"));
43   EXPECT_EQ(llvm::None, ModuleRecord::parse("MODULE Linux"));
44   EXPECT_EQ(llvm::None, ModuleRecord::parse("MODULE Linux x86_64"));
45   EXPECT_EQ(llvm::None,
46             ModuleRecord::parse("MODULE Linux x86_64 deadbeefbaadf00d"));
47 }
48 
49 TEST(InfoRecord, parse) {
50   EXPECT_EQ(InfoRecord(UUID::fromData("@ABCDEFGHIJKLMNO", 16)),
51             InfoRecord::parse("INFO CODE_ID 404142434445464748494a4b4c4d4e4f"));
52   EXPECT_EQ(InfoRecord(UUID()), InfoRecord::parse("INFO CODE_ID 47 a.exe"));
53 
54   EXPECT_EQ(llvm::None, InfoRecord::parse("INFO"));
55   EXPECT_EQ(llvm::None, InfoRecord::parse("INFO CODE_ID"));
56 }
57 
58 TEST(FileRecord, parse) {
59   EXPECT_EQ(FileRecord(47, "foo"), FileRecord::parse("FILE 47 foo"));
60   EXPECT_EQ(llvm::None, FileRecord::parse("FILE 47"));
61   EXPECT_EQ(llvm::None, FileRecord::parse("FILE"));
62   EXPECT_EQ(llvm::None, FileRecord::parse(""));
63 }
64 
65 TEST(FuncRecord, parse) {
66   EXPECT_EQ(FuncRecord(true, 0x47, 0x7, 0x8, "foo"),
67             FuncRecord::parse("FUNC m 47 7 8 foo"));
68   EXPECT_EQ(FuncRecord(false, 0x47, 0x7, 0x8, "foo"),
69             FuncRecord::parse("FUNC 47 7 8 foo"));
70 
71   EXPECT_EQ(llvm::None, FuncRecord::parse("PUBLIC 47 7 8 foo"));
72   EXPECT_EQ(llvm::None, FuncRecord::parse("FUNC 47 7 8"));
73   EXPECT_EQ(llvm::None, FuncRecord::parse("FUNC 47 7"));
74   EXPECT_EQ(llvm::None, FuncRecord::parse("FUNC 47"));
75   EXPECT_EQ(llvm::None, FuncRecord::parse("FUNC m"));
76   EXPECT_EQ(llvm::None, FuncRecord::parse("FUNC"));
77 }
78 
79 TEST(LineRecord, parse) {
80   EXPECT_EQ(LineRecord(0x47, 0x74, 47, 74), LineRecord::parse("47 74 47 74"));
81   EXPECT_EQ(llvm::None, LineRecord::parse("47 74 47"));
82   EXPECT_EQ(llvm::None, LineRecord::parse("47 74"));
83   EXPECT_EQ(llvm::None, LineRecord::parse("47"));
84   EXPECT_EQ(llvm::None, LineRecord::parse(""));
85   EXPECT_EQ(llvm::None, LineRecord::parse("FUNC"));
86 }
87 
88 TEST(PublicRecord, parse) {
89   EXPECT_EQ(PublicRecord(true, 0x47, 0x8, "foo"),
90             PublicRecord::parse("PUBLIC m 47 8 foo"));
91   EXPECT_EQ(PublicRecord(false, 0x47, 0x8, "foo"),
92             PublicRecord::parse("PUBLIC 47 8 foo"));
93 
94   EXPECT_EQ(llvm::None, PublicRecord::parse("FUNC 47 8 foo"));
95   EXPECT_EQ(llvm::None, PublicRecord::parse("PUBLIC 47 8"));
96   EXPECT_EQ(llvm::None, PublicRecord::parse("PUBLIC 47"));
97   EXPECT_EQ(llvm::None, PublicRecord::parse("PUBLIC m"));
98   EXPECT_EQ(llvm::None, PublicRecord::parse("PUBLIC"));
99 }
100 
101 TEST(StackCFIRecord, parse) {
102   EXPECT_EQ(StackCFIRecord(0x47, 0x8, ".cfa: $esp 4 + $eip: .cfa 4 - ^"),
103             StackCFIRecord::parse(
104                 "STACK CFI INIT 47 8 .cfa: $esp 4 + $eip: .cfa 4 - ^"));
105 
106   EXPECT_EQ(StackCFIRecord(0x47, 0x8, ".cfa: $esp 4 +"),
107             StackCFIRecord::parse("STACK CFI INIT 47 8 .cfa: $esp 4 +  "));
108 
109   EXPECT_EQ(StackCFIRecord(0x47, llvm::None, ".cfa: $esp 4 +"),
110             StackCFIRecord::parse("STACK CFI 47 .cfa: $esp 4 +"));
111 
112   // The validity of the register value expressions is not checked
113   EXPECT_EQ(StackCFIRecord(0x47, 0x8, ".cfa: ^ ^ ^"),
114             StackCFIRecord::parse("STACK CFI INIT 47 8 .cfa: ^ ^ ^"));
115 
116   EXPECT_EQ(llvm::None, StackCFIRecord::parse("STACK CFI INIT 47"));
117   EXPECT_EQ(llvm::None, StackCFIRecord::parse("STACK CFI INIT"));
118   EXPECT_EQ(llvm::None, StackCFIRecord::parse("STACK CFI"));
119   EXPECT_EQ(llvm::None, StackCFIRecord::parse("STACK"));
120   EXPECT_EQ(llvm::None, StackCFIRecord::parse("FILE 47 foo"));
121   EXPECT_EQ(llvm::None, StackCFIRecord::parse("42 47"));
122 }
123 
124 TEST(StackWinRecord, parse) {
125   EXPECT_EQ(
126       StackWinRecord(0x47, 0x8, 3, 4, 5, llvm::StringRef("$eip $esp ^ =")),
127       StackWinRecord::parse("STACK WIN 4 47 8 1 2 3 4 5 6 1 $eip $esp ^ ="));
128 
129   EXPECT_EQ(llvm::None, StackWinRecord::parse(
130                             "STACK WIN 0 47 8 1 0 0 0 0 0 1 $eip $esp ^ ="));
131   EXPECT_EQ(llvm::None,
132             StackWinRecord::parse("STACK WIN 4 47 8 1 0 0 0 0 0 0 1"));
133   EXPECT_EQ(llvm::None, StackWinRecord::parse(
134                             "STACK WIN 3 47 8 1 0 0 0 0 0 1 $eip $esp ^ ="));
135   EXPECT_EQ(llvm::None,
136             StackWinRecord::parse("STACK WIN 3 47 8 1 0 0 0 0 0 0 1"));
137   EXPECT_EQ(llvm::None, StackWinRecord::parse(
138                             "STACK WIN 4 47 8 1 0 0 0 0 1 $eip $esp ^ ="));
139   EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK WIN 4 47 8 1 0 0 0 0 0"));
140   EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK WIN 4 47 8 1 0 0 0 0"));
141   EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK WIN 4 47 8 1 0 0 0"));
142   EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK WIN 4 47 8 1 0 0"));
143   EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK WIN 4 47 8 1 0"));
144   EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK WIN 4 47 8 1"));
145   EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK WIN 4 47 8"));
146   EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK WIN 4 47"));
147   EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK WIN 4"));
148   EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK WIN"));
149   EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK"));
150   EXPECT_EQ(llvm::None, StackWinRecord::parse(""));
151   EXPECT_EQ(llvm::None, StackCFIRecord::parse("FILE 47 foo"));
152   EXPECT_EQ(llvm::None, StackCFIRecord::parse("42 47"));
153 }
154