1 | //===- unittest/BinaryFormat/DwarfTest.cpp - Dwarf support tests ----------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "llvm/BinaryFormat/Dwarf.h" |
10 | #include "llvm/ADT/StringRef.h" |
11 | #include "llvm/Support/FormatVariadic.h" |
12 | #include "gtest/gtest.h" |
13 | |
14 | using namespace llvm; |
15 | using namespace llvm::dwarf; |
16 | |
17 | namespace { |
18 | |
19 | TEST(DwarfTest, TagStringOnInvalid) { |
20 | // This is invalid, so it shouldn't be stringified. |
21 | EXPECT_EQ(StringRef(), TagString(DW_TAG_invalid)); |
22 | |
23 | // These aren't really tags: they describe ranges within tags. They |
24 | // shouldn't be stringified either. |
25 | EXPECT_EQ(StringRef(), TagString(DW_TAG_lo_user)); |
26 | EXPECT_EQ(StringRef(), TagString(DW_TAG_hi_user)); |
27 | EXPECT_EQ(StringRef(), TagString(DW_TAG_user_base)); |
28 | } |
29 | |
30 | TEST(DwarfTest, getTag) { |
31 | // A couple of valid tags. |
32 | EXPECT_EQ(DW_TAG_array_type, getTag("DW_TAG_array_type" )); |
33 | EXPECT_EQ(DW_TAG_module, getTag("DW_TAG_module" )); |
34 | |
35 | // Invalid tags. |
36 | EXPECT_EQ(DW_TAG_invalid, getTag("DW_TAG_invalid" )); |
37 | EXPECT_EQ(DW_TAG_invalid, getTag("DW_TAG_madeuptag" )); |
38 | EXPECT_EQ(DW_TAG_invalid, getTag("something else" )); |
39 | |
40 | // Tag range markers should not be recognized. |
41 | EXPECT_EQ(DW_TAG_invalid, getTag("DW_TAG_lo_user" )); |
42 | EXPECT_EQ(DW_TAG_invalid, getTag("DW_TAG_hi_user" )); |
43 | EXPECT_EQ(DW_TAG_invalid, getTag("DW_TAG_user_base" )); |
44 | } |
45 | |
46 | TEST(DwarfTest, getOperationEncoding) { |
47 | // Some valid ops. |
48 | EXPECT_EQ(DW_OP_deref, getOperationEncoding("DW_OP_deref" )); |
49 | EXPECT_EQ(DW_OP_bit_piece, getOperationEncoding("DW_OP_bit_piece" )); |
50 | |
51 | // Invalid ops. |
52 | EXPECT_EQ(0u, getOperationEncoding("DW_OP_otherthings" )); |
53 | EXPECT_EQ(0u, getOperationEncoding("other" )); |
54 | |
55 | // Markers shouldn't be recognized. |
56 | EXPECT_EQ(0u, getOperationEncoding("DW_OP_lo_user" )); |
57 | EXPECT_EQ(0u, getOperationEncoding("DW_OP_hi_user" )); |
58 | } |
59 | |
60 | TEST(DwarfTest, LanguageStringOnInvalid) { |
61 | // This is invalid, so it shouldn't be stringified. |
62 | EXPECT_EQ(StringRef(), LanguageString(0)); |
63 | |
64 | // These aren't really tags: they describe ranges within tags. They |
65 | // shouldn't be stringified either. |
66 | EXPECT_EQ(StringRef(), LanguageString(DW_LANG_lo_user)); |
67 | EXPECT_EQ(StringRef(), LanguageString(DW_LANG_hi_user)); |
68 | } |
69 | |
70 | TEST(DwarfTest, getLanguage) { |
71 | // A couple of valid languages. |
72 | EXPECT_EQ(DW_LANG_C89, getLanguage("DW_LANG_C89" )); |
73 | EXPECT_EQ(DW_LANG_C_plus_plus_11, getLanguage("DW_LANG_C_plus_plus_11" )); |
74 | EXPECT_EQ(DW_LANG_OCaml, getLanguage("DW_LANG_OCaml" )); |
75 | EXPECT_EQ(DW_LANG_Mips_Assembler, getLanguage("DW_LANG_Mips_Assembler" )); |
76 | |
77 | // Invalid languages. |
78 | EXPECT_EQ(0u, getLanguage("DW_LANG_invalid" )); |
79 | EXPECT_EQ(0u, getLanguage("DW_TAG_array_type" )); |
80 | EXPECT_EQ(0u, getLanguage("something else" )); |
81 | |
82 | // Language range markers should not be recognized. |
83 | EXPECT_EQ(0u, getLanguage("DW_LANG_lo_user" )); |
84 | EXPECT_EQ(0u, getLanguage("DW_LANG_hi_user" )); |
85 | } |
86 | |
87 | TEST(DwarfTest, AttributeEncodingStringOnInvalid) { |
88 | // This is invalid, so it shouldn't be stringified. |
89 | EXPECT_EQ(StringRef(), AttributeEncodingString(0)); |
90 | |
91 | // These aren't really tags: they describe ranges within tags. They |
92 | // shouldn't be stringified either. |
93 | EXPECT_EQ(StringRef(), AttributeEncodingString(DW_ATE_lo_user)); |
94 | EXPECT_EQ(StringRef(), AttributeEncodingString(DW_ATE_hi_user)); |
95 | } |
96 | |
97 | TEST(DwarfTest, getAttributeEncoding) { |
98 | // A couple of valid languages. |
99 | EXPECT_EQ(DW_ATE_boolean, getAttributeEncoding("DW_ATE_boolean" )); |
100 | EXPECT_EQ(DW_ATE_imaginary_float, |
101 | getAttributeEncoding("DW_ATE_imaginary_float" )); |
102 | |
103 | // Invalid languages. |
104 | EXPECT_EQ(0u, getAttributeEncoding("DW_ATE_invalid" )); |
105 | EXPECT_EQ(0u, getAttributeEncoding("DW_TAG_array_type" )); |
106 | EXPECT_EQ(0u, getAttributeEncoding("something else" )); |
107 | |
108 | // AttributeEncoding range markers should not be recognized. |
109 | EXPECT_EQ(0u, getAttributeEncoding("DW_ATE_lo_user" )); |
110 | EXPECT_EQ(0u, getAttributeEncoding("DW_ATE_hi_user" )); |
111 | } |
112 | |
113 | TEST(DwarfTest, VirtualityString) { |
114 | EXPECT_EQ(StringRef("DW_VIRTUALITY_none" ), |
115 | VirtualityString(DW_VIRTUALITY_none)); |
116 | EXPECT_EQ(StringRef("DW_VIRTUALITY_virtual" ), |
117 | VirtualityString(DW_VIRTUALITY_virtual)); |
118 | EXPECT_EQ(StringRef("DW_VIRTUALITY_pure_virtual" ), |
119 | VirtualityString(DW_VIRTUALITY_pure_virtual)); |
120 | |
121 | // DW_VIRTUALITY_max should be pure virtual. |
122 | EXPECT_EQ(StringRef("DW_VIRTUALITY_pure_virtual" ), |
123 | VirtualityString(DW_VIRTUALITY_max)); |
124 | |
125 | // Invalid numbers shouldn't be stringified. |
126 | EXPECT_EQ(StringRef(), VirtualityString(DW_VIRTUALITY_max + 1)); |
127 | EXPECT_EQ(StringRef(), VirtualityString(DW_VIRTUALITY_max + 77)); |
128 | } |
129 | |
130 | TEST(DwarfTest, getVirtuality) { |
131 | EXPECT_EQ(DW_VIRTUALITY_none, getVirtuality("DW_VIRTUALITY_none" )); |
132 | EXPECT_EQ(DW_VIRTUALITY_virtual, getVirtuality("DW_VIRTUALITY_virtual" )); |
133 | EXPECT_EQ(DW_VIRTUALITY_pure_virtual, |
134 | getVirtuality("DW_VIRTUALITY_pure_virtual" )); |
135 | |
136 | // Invalid strings. |
137 | EXPECT_EQ(DW_VIRTUALITY_invalid, getVirtuality("DW_VIRTUALITY_invalid" )); |
138 | EXPECT_EQ(DW_VIRTUALITY_invalid, getVirtuality("DW_VIRTUALITY_max" )); |
139 | EXPECT_EQ(DW_VIRTUALITY_invalid, getVirtuality("something else" )); |
140 | } |
141 | |
142 | TEST(DwarfTest, FixedFormSizes) { |
143 | std::optional<uint8_t> RefSize; |
144 | std::optional<uint8_t> AddrSize; |
145 | |
146 | // Test 32 bit DWARF version 2 with 4 byte addresses. |
147 | FormParams Params_2_4_32 = {.Version: 2, .AddrSize: 4, .Format: DWARF32}; |
148 | RefSize = getFixedFormByteSize(Form: DW_FORM_ref_addr, Params: Params_2_4_32); |
149 | AddrSize = getFixedFormByteSize(Form: DW_FORM_ref_addr, Params: Params_2_4_32); |
150 | EXPECT_TRUE(RefSize.has_value()); |
151 | EXPECT_TRUE(AddrSize.has_value()); |
152 | EXPECT_EQ(*RefSize, *AddrSize); |
153 | |
154 | // Test 32 bit DWARF version 2 with 8 byte addresses. |
155 | FormParams Params_2_8_32 = {.Version: 2, .AddrSize: 8, .Format: DWARF32}; |
156 | RefSize = getFixedFormByteSize(Form: DW_FORM_ref_addr, Params: Params_2_8_32); |
157 | AddrSize = getFixedFormByteSize(Form: DW_FORM_ref_addr, Params: Params_2_8_32); |
158 | EXPECT_TRUE(RefSize.has_value()); |
159 | EXPECT_TRUE(AddrSize.has_value()); |
160 | EXPECT_EQ(*RefSize, *AddrSize); |
161 | |
162 | // DW_FORM_ref_addr is 4 bytes in DWARF 32 in DWARF version 3 and beyond. |
163 | FormParams Params_3_4_32 = {.Version: 3, .AddrSize: 4, .Format: DWARF32}; |
164 | RefSize = getFixedFormByteSize(Form: DW_FORM_ref_addr, Params: Params_3_4_32); |
165 | EXPECT_TRUE(RefSize.has_value()); |
166 | EXPECT_EQ(*RefSize, 4); |
167 | |
168 | FormParams Params_4_4_32 = {.Version: 4, .AddrSize: 4, .Format: DWARF32}; |
169 | RefSize = getFixedFormByteSize(Form: DW_FORM_ref_addr, Params: Params_4_4_32); |
170 | EXPECT_TRUE(RefSize.has_value()); |
171 | EXPECT_EQ(*RefSize, 4); |
172 | |
173 | FormParams Params_5_4_32 = {.Version: 5, .AddrSize: 4, .Format: DWARF32}; |
174 | RefSize = getFixedFormByteSize(Form: DW_FORM_ref_addr, Params: Params_5_4_32); |
175 | EXPECT_TRUE(RefSize.has_value()); |
176 | EXPECT_EQ(*RefSize, 4); |
177 | |
178 | // DW_FORM_ref_addr is 8 bytes in DWARF 64 in DWARF version 3 and beyond. |
179 | FormParams Params_3_8_64 = {.Version: 3, .AddrSize: 8, .Format: DWARF64}; |
180 | RefSize = getFixedFormByteSize(Form: DW_FORM_ref_addr, Params: Params_3_8_64); |
181 | EXPECT_TRUE(RefSize.has_value()); |
182 | EXPECT_EQ(*RefSize, 8); |
183 | |
184 | FormParams Params_4_8_64 = {.Version: 4, .AddrSize: 8, .Format: DWARF64}; |
185 | RefSize = getFixedFormByteSize(Form: DW_FORM_ref_addr, Params: Params_4_8_64); |
186 | EXPECT_TRUE(RefSize.has_value()); |
187 | EXPECT_EQ(*RefSize, 8); |
188 | |
189 | FormParams Params_5_8_64 = {.Version: 5, .AddrSize: 8, .Format: DWARF64}; |
190 | RefSize = getFixedFormByteSize(Form: DW_FORM_ref_addr, Params: Params_5_8_64); |
191 | EXPECT_TRUE(RefSize.has_value()); |
192 | EXPECT_EQ(*RefSize, 8); |
193 | } |
194 | |
195 | TEST(DwarfTest, format_provider) { |
196 | EXPECT_EQ("DW_AT_name" , formatv("{0}" , DW_AT_name).str()); |
197 | EXPECT_EQ("DW_AT_unknown_3fff" , formatv("{0}" , DW_AT_hi_user).str()); |
198 | EXPECT_EQ("DW_FORM_addr" , formatv("{0}" , DW_FORM_addr).str()); |
199 | EXPECT_EQ("DW_FORM_unknown_1f00" , formatv("{0}" , DW_FORM_lo_user).str()); |
200 | EXPECT_EQ("DW_IDX_compile_unit" , formatv("{0}" , DW_IDX_compile_unit).str()); |
201 | EXPECT_EQ("DW_IDX_unknown_3fff" , formatv("{0}" , DW_IDX_hi_user).str()); |
202 | EXPECT_EQ("DW_TAG_compile_unit" , formatv("{0}" , DW_TAG_compile_unit).str()); |
203 | EXPECT_EQ("DW_TAG_unknown_ffff" , formatv("{0}" , DW_TAG_hi_user).str()); |
204 | EXPECT_EQ("DW_OP_lit0" , formatv("{0}" , DW_OP_lit0).str()); |
205 | EXPECT_EQ("DW_OP_unknown_ff" , formatv("{0}" , DW_OP_hi_user).str()); |
206 | } |
207 | } // end namespace |
208 | |