xref: /llvm-project/llvm/unittests/BinaryFormat/DwarfTest.cpp (revision 300340f656d762afa8bde5fc398757d2951560bf)
1264b5d9eSZachary Turner //===- unittest/BinaryFormat/DwarfTest.cpp - Dwarf support tests ----------===//
2264b5d9eSZachary Turner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6264b5d9eSZachary Turner //
7264b5d9eSZachary Turner //===----------------------------------------------------------------------===//
8264b5d9eSZachary Turner 
9264b5d9eSZachary Turner #include "llvm/BinaryFormat/Dwarf.h"
10264b5d9eSZachary Turner #include "llvm/ADT/StringRef.h"
119025f955SPavel Labath #include "llvm/Support/FormatVariadic.h"
12264b5d9eSZachary Turner #include "gtest/gtest.h"
13264b5d9eSZachary Turner 
14264b5d9eSZachary Turner using namespace llvm;
15264b5d9eSZachary Turner using namespace llvm::dwarf;
16264b5d9eSZachary Turner 
17264b5d9eSZachary Turner namespace {
18264b5d9eSZachary Turner 
TEST(DwarfTest,TagStringOnInvalid)19264b5d9eSZachary Turner TEST(DwarfTest, TagStringOnInvalid) {
20264b5d9eSZachary Turner   // This is invalid, so it shouldn't be stringified.
21264b5d9eSZachary Turner   EXPECT_EQ(StringRef(), TagString(DW_TAG_invalid));
22264b5d9eSZachary Turner 
23264b5d9eSZachary Turner   // These aren't really tags: they describe ranges within tags.  They
24264b5d9eSZachary Turner   // shouldn't be stringified either.
25264b5d9eSZachary Turner   EXPECT_EQ(StringRef(), TagString(DW_TAG_lo_user));
26264b5d9eSZachary Turner   EXPECT_EQ(StringRef(), TagString(DW_TAG_hi_user));
27264b5d9eSZachary Turner   EXPECT_EQ(StringRef(), TagString(DW_TAG_user_base));
28264b5d9eSZachary Turner }
29264b5d9eSZachary Turner 
TEST(DwarfTest,getTag)30264b5d9eSZachary Turner TEST(DwarfTest, getTag) {
31264b5d9eSZachary Turner   // A couple of valid tags.
32264b5d9eSZachary Turner   EXPECT_EQ(DW_TAG_array_type, getTag("DW_TAG_array_type"));
33264b5d9eSZachary Turner   EXPECT_EQ(DW_TAG_module, getTag("DW_TAG_module"));
34264b5d9eSZachary Turner 
35264b5d9eSZachary Turner   // Invalid tags.
36264b5d9eSZachary Turner   EXPECT_EQ(DW_TAG_invalid, getTag("DW_TAG_invalid"));
37264b5d9eSZachary Turner   EXPECT_EQ(DW_TAG_invalid, getTag("DW_TAG_madeuptag"));
38264b5d9eSZachary Turner   EXPECT_EQ(DW_TAG_invalid, getTag("something else"));
39264b5d9eSZachary Turner 
40264b5d9eSZachary Turner   // Tag range markers should not be recognized.
41264b5d9eSZachary Turner   EXPECT_EQ(DW_TAG_invalid, getTag("DW_TAG_lo_user"));
42264b5d9eSZachary Turner   EXPECT_EQ(DW_TAG_invalid, getTag("DW_TAG_hi_user"));
43264b5d9eSZachary Turner   EXPECT_EQ(DW_TAG_invalid, getTag("DW_TAG_user_base"));
44264b5d9eSZachary Turner }
45264b5d9eSZachary Turner 
TEST(DwarfTest,getOperationEncoding)46264b5d9eSZachary Turner TEST(DwarfTest, getOperationEncoding) {
47264b5d9eSZachary Turner   // Some valid ops.
48264b5d9eSZachary Turner   EXPECT_EQ(DW_OP_deref, getOperationEncoding("DW_OP_deref"));
49264b5d9eSZachary Turner   EXPECT_EQ(DW_OP_bit_piece, getOperationEncoding("DW_OP_bit_piece"));
50264b5d9eSZachary Turner 
51264b5d9eSZachary Turner   // Invalid ops.
52264b5d9eSZachary Turner   EXPECT_EQ(0u, getOperationEncoding("DW_OP_otherthings"));
53264b5d9eSZachary Turner   EXPECT_EQ(0u, getOperationEncoding("other"));
54264b5d9eSZachary Turner 
55264b5d9eSZachary Turner   // Markers shouldn't be recognized.
56264b5d9eSZachary Turner   EXPECT_EQ(0u, getOperationEncoding("DW_OP_lo_user"));
57264b5d9eSZachary Turner   EXPECT_EQ(0u, getOperationEncoding("DW_OP_hi_user"));
58264b5d9eSZachary Turner }
59264b5d9eSZachary Turner 
TEST(DwarfTest,LanguageStringOnInvalid)60264b5d9eSZachary Turner TEST(DwarfTest, LanguageStringOnInvalid) {
61264b5d9eSZachary Turner   // This is invalid, so it shouldn't be stringified.
62264b5d9eSZachary Turner   EXPECT_EQ(StringRef(), LanguageString(0));
63264b5d9eSZachary Turner 
64264b5d9eSZachary Turner   // These aren't really tags: they describe ranges within tags.  They
65264b5d9eSZachary Turner   // shouldn't be stringified either.
66264b5d9eSZachary Turner   EXPECT_EQ(StringRef(), LanguageString(DW_LANG_lo_user));
67264b5d9eSZachary Turner   EXPECT_EQ(StringRef(), LanguageString(DW_LANG_hi_user));
68264b5d9eSZachary Turner }
69264b5d9eSZachary Turner 
TEST(DwarfTest,getLanguage)70264b5d9eSZachary Turner TEST(DwarfTest, getLanguage) {
71264b5d9eSZachary Turner   // A couple of valid languages.
72264b5d9eSZachary Turner   EXPECT_EQ(DW_LANG_C89, getLanguage("DW_LANG_C89"));
73264b5d9eSZachary Turner   EXPECT_EQ(DW_LANG_C_plus_plus_11, getLanguage("DW_LANG_C_plus_plus_11"));
74264b5d9eSZachary Turner   EXPECT_EQ(DW_LANG_OCaml, getLanguage("DW_LANG_OCaml"));
75264b5d9eSZachary Turner   EXPECT_EQ(DW_LANG_Mips_Assembler, getLanguage("DW_LANG_Mips_Assembler"));
76264b5d9eSZachary Turner 
77264b5d9eSZachary Turner   // Invalid languages.
78264b5d9eSZachary Turner   EXPECT_EQ(0u, getLanguage("DW_LANG_invalid"));
79264b5d9eSZachary Turner   EXPECT_EQ(0u, getLanguage("DW_TAG_array_type"));
80264b5d9eSZachary Turner   EXPECT_EQ(0u, getLanguage("something else"));
81264b5d9eSZachary Turner 
82264b5d9eSZachary Turner   // Language range markers should not be recognized.
83264b5d9eSZachary Turner   EXPECT_EQ(0u, getLanguage("DW_LANG_lo_user"));
84264b5d9eSZachary Turner   EXPECT_EQ(0u, getLanguage("DW_LANG_hi_user"));
85264b5d9eSZachary Turner }
86264b5d9eSZachary Turner 
TEST(DwarfTest,AttributeEncodingStringOnInvalid)87264b5d9eSZachary Turner TEST(DwarfTest, AttributeEncodingStringOnInvalid) {
88264b5d9eSZachary Turner   // This is invalid, so it shouldn't be stringified.
89264b5d9eSZachary Turner   EXPECT_EQ(StringRef(), AttributeEncodingString(0));
90264b5d9eSZachary Turner 
91264b5d9eSZachary Turner   // These aren't really tags: they describe ranges within tags.  They
92264b5d9eSZachary Turner   // shouldn't be stringified either.
93264b5d9eSZachary Turner   EXPECT_EQ(StringRef(), AttributeEncodingString(DW_ATE_lo_user));
94264b5d9eSZachary Turner   EXPECT_EQ(StringRef(), AttributeEncodingString(DW_ATE_hi_user));
95264b5d9eSZachary Turner }
96264b5d9eSZachary Turner 
TEST(DwarfTest,getAttributeEncoding)97264b5d9eSZachary Turner TEST(DwarfTest, getAttributeEncoding) {
98264b5d9eSZachary Turner   // A couple of valid languages.
99264b5d9eSZachary Turner   EXPECT_EQ(DW_ATE_boolean, getAttributeEncoding("DW_ATE_boolean"));
100264b5d9eSZachary Turner   EXPECT_EQ(DW_ATE_imaginary_float,
101264b5d9eSZachary Turner             getAttributeEncoding("DW_ATE_imaginary_float"));
102264b5d9eSZachary Turner 
103264b5d9eSZachary Turner   // Invalid languages.
104264b5d9eSZachary Turner   EXPECT_EQ(0u, getAttributeEncoding("DW_ATE_invalid"));
105264b5d9eSZachary Turner   EXPECT_EQ(0u, getAttributeEncoding("DW_TAG_array_type"));
106264b5d9eSZachary Turner   EXPECT_EQ(0u, getAttributeEncoding("something else"));
107264b5d9eSZachary Turner 
108264b5d9eSZachary Turner   // AttributeEncoding range markers should not be recognized.
109264b5d9eSZachary Turner   EXPECT_EQ(0u, getAttributeEncoding("DW_ATE_lo_user"));
110264b5d9eSZachary Turner   EXPECT_EQ(0u, getAttributeEncoding("DW_ATE_hi_user"));
111264b5d9eSZachary Turner }
112264b5d9eSZachary Turner 
TEST(DwarfTest,VirtualityString)113264b5d9eSZachary Turner TEST(DwarfTest, VirtualityString) {
114264b5d9eSZachary Turner   EXPECT_EQ(StringRef("DW_VIRTUALITY_none"),
115264b5d9eSZachary Turner             VirtualityString(DW_VIRTUALITY_none));
116264b5d9eSZachary Turner   EXPECT_EQ(StringRef("DW_VIRTUALITY_virtual"),
117264b5d9eSZachary Turner             VirtualityString(DW_VIRTUALITY_virtual));
118264b5d9eSZachary Turner   EXPECT_EQ(StringRef("DW_VIRTUALITY_pure_virtual"),
119264b5d9eSZachary Turner             VirtualityString(DW_VIRTUALITY_pure_virtual));
120264b5d9eSZachary Turner 
121264b5d9eSZachary Turner   // DW_VIRTUALITY_max should be pure virtual.
122264b5d9eSZachary Turner   EXPECT_EQ(StringRef("DW_VIRTUALITY_pure_virtual"),
123264b5d9eSZachary Turner             VirtualityString(DW_VIRTUALITY_max));
124264b5d9eSZachary Turner 
125264b5d9eSZachary Turner   // Invalid numbers shouldn't be stringified.
126264b5d9eSZachary Turner   EXPECT_EQ(StringRef(), VirtualityString(DW_VIRTUALITY_max + 1));
127264b5d9eSZachary Turner   EXPECT_EQ(StringRef(), VirtualityString(DW_VIRTUALITY_max + 77));
128264b5d9eSZachary Turner }
129264b5d9eSZachary Turner 
TEST(DwarfTest,getVirtuality)130264b5d9eSZachary Turner TEST(DwarfTest, getVirtuality) {
131264b5d9eSZachary Turner   EXPECT_EQ(DW_VIRTUALITY_none, getVirtuality("DW_VIRTUALITY_none"));
132264b5d9eSZachary Turner   EXPECT_EQ(DW_VIRTUALITY_virtual, getVirtuality("DW_VIRTUALITY_virtual"));
133264b5d9eSZachary Turner   EXPECT_EQ(DW_VIRTUALITY_pure_virtual,
134264b5d9eSZachary Turner             getVirtuality("DW_VIRTUALITY_pure_virtual"));
135264b5d9eSZachary Turner 
136264b5d9eSZachary Turner   // Invalid strings.
137264b5d9eSZachary Turner   EXPECT_EQ(DW_VIRTUALITY_invalid, getVirtuality("DW_VIRTUALITY_invalid"));
138264b5d9eSZachary Turner   EXPECT_EQ(DW_VIRTUALITY_invalid, getVirtuality("DW_VIRTUALITY_max"));
139264b5d9eSZachary Turner   EXPECT_EQ(DW_VIRTUALITY_invalid, getVirtuality("something else"));
140264b5d9eSZachary Turner }
141264b5d9eSZachary Turner 
TEST(DwarfTest,FixedFormSizes)142322711f5SPavel Labath TEST(DwarfTest, FixedFormSizes) {
14389fab98eSFangrui Song   std::optional<uint8_t> RefSize;
14489fab98eSFangrui Song   std::optional<uint8_t> AddrSize;
145322711f5SPavel Labath 
146322711f5SPavel Labath   // Test 32 bit DWARF version 2 with 4 byte addresses.
147322711f5SPavel Labath   FormParams Params_2_4_32 = {2, 4, DWARF32};
148322711f5SPavel Labath   RefSize = getFixedFormByteSize(DW_FORM_ref_addr, Params_2_4_32);
149322711f5SPavel Labath   AddrSize = getFixedFormByteSize(DW_FORM_ref_addr, Params_2_4_32);
1503361a364SKazu Hirata   EXPECT_TRUE(RefSize.has_value());
1513361a364SKazu Hirata   EXPECT_TRUE(AddrSize.has_value());
152322711f5SPavel Labath   EXPECT_EQ(*RefSize, *AddrSize);
153322711f5SPavel Labath 
154322711f5SPavel Labath   // Test 32 bit DWARF version 2 with 8 byte addresses.
155322711f5SPavel Labath   FormParams Params_2_8_32 = {2, 8, DWARF32};
156322711f5SPavel Labath   RefSize = getFixedFormByteSize(DW_FORM_ref_addr, Params_2_8_32);
157322711f5SPavel Labath   AddrSize = getFixedFormByteSize(DW_FORM_ref_addr, Params_2_8_32);
1583361a364SKazu Hirata   EXPECT_TRUE(RefSize.has_value());
1593361a364SKazu Hirata   EXPECT_TRUE(AddrSize.has_value());
160322711f5SPavel Labath   EXPECT_EQ(*RefSize, *AddrSize);
161322711f5SPavel Labath 
162322711f5SPavel Labath   // DW_FORM_ref_addr is 4 bytes in DWARF 32 in DWARF version 3 and beyond.
163322711f5SPavel Labath   FormParams Params_3_4_32 = {3, 4, DWARF32};
164322711f5SPavel Labath   RefSize = getFixedFormByteSize(DW_FORM_ref_addr, Params_3_4_32);
1653361a364SKazu Hirata   EXPECT_TRUE(RefSize.has_value());
166322711f5SPavel Labath   EXPECT_EQ(*RefSize, 4);
167322711f5SPavel Labath 
168322711f5SPavel Labath   FormParams Params_4_4_32 = {4, 4, DWARF32};
169322711f5SPavel Labath   RefSize = getFixedFormByteSize(DW_FORM_ref_addr, Params_4_4_32);
1703361a364SKazu Hirata   EXPECT_TRUE(RefSize.has_value());
171322711f5SPavel Labath   EXPECT_EQ(*RefSize, 4);
172322711f5SPavel Labath 
173322711f5SPavel Labath   FormParams Params_5_4_32 = {5, 4, DWARF32};
174322711f5SPavel Labath   RefSize = getFixedFormByteSize(DW_FORM_ref_addr, Params_5_4_32);
1753361a364SKazu Hirata   EXPECT_TRUE(RefSize.has_value());
176322711f5SPavel Labath   EXPECT_EQ(*RefSize, 4);
177322711f5SPavel Labath 
178322711f5SPavel Labath   // DW_FORM_ref_addr is 8 bytes in DWARF 64 in DWARF version 3 and beyond.
179322711f5SPavel Labath   FormParams Params_3_8_64 = {3, 8, DWARF64};
180322711f5SPavel Labath   RefSize = getFixedFormByteSize(DW_FORM_ref_addr, Params_3_8_64);
1813361a364SKazu Hirata   EXPECT_TRUE(RefSize.has_value());
182322711f5SPavel Labath   EXPECT_EQ(*RefSize, 8);
183322711f5SPavel Labath 
184322711f5SPavel Labath   FormParams Params_4_8_64 = {4, 8, DWARF64};
185322711f5SPavel Labath   RefSize = getFixedFormByteSize(DW_FORM_ref_addr, Params_4_8_64);
1863361a364SKazu Hirata   EXPECT_TRUE(RefSize.has_value());
187322711f5SPavel Labath   EXPECT_EQ(*RefSize, 8);
188322711f5SPavel Labath 
189322711f5SPavel Labath   FormParams Params_5_8_64 = {5, 8, DWARF64};
190322711f5SPavel Labath   RefSize = getFixedFormByteSize(DW_FORM_ref_addr, Params_5_8_64);
1913361a364SKazu Hirata   EXPECT_TRUE(RefSize.has_value());
192322711f5SPavel Labath   EXPECT_EQ(*RefSize, 8);
193322711f5SPavel Labath }
194322711f5SPavel Labath 
TEST(DwarfTest,format_provider)1959025f955SPavel Labath TEST(DwarfTest, format_provider) {
1969025f955SPavel Labath   EXPECT_EQ("DW_AT_name", formatv("{0}", DW_AT_name).str());
1979025f955SPavel Labath   EXPECT_EQ("DW_AT_unknown_3fff", formatv("{0}", DW_AT_hi_user).str());
1989025f955SPavel Labath   EXPECT_EQ("DW_FORM_addr", formatv("{0}", DW_FORM_addr).str());
1999025f955SPavel Labath   EXPECT_EQ("DW_FORM_unknown_1f00", formatv("{0}", DW_FORM_lo_user).str());
2009025f955SPavel Labath   EXPECT_EQ("DW_IDX_compile_unit", formatv("{0}", DW_IDX_compile_unit).str());
2019025f955SPavel Labath   EXPECT_EQ("DW_IDX_unknown_3fff", formatv("{0}", DW_IDX_hi_user).str());
2029025f955SPavel Labath   EXPECT_EQ("DW_TAG_compile_unit", formatv("{0}", DW_TAG_compile_unit).str());
2039025f955SPavel Labath   EXPECT_EQ("DW_TAG_unknown_ffff", formatv("{0}", DW_TAG_hi_user).str());
2049456bbddSPavel Labath   EXPECT_EQ("DW_OP_lit0", formatv("{0}", DW_OP_lit0).str());
2059456bbddSPavel Labath   EXPECT_EQ("DW_OP_unknown_ff", formatv("{0}", DW_OP_hi_user).str());
2069025f955SPavel Labath }
207*300340f6SAdrian Prantl 
TEST(DwarfTest,lname)208*300340f6SAdrian Prantl TEST(DwarfTest, lname) {
209*300340f6SAdrian Prantl   auto roundtrip = [](llvm::dwarf::SourceLanguage sl) {
210*300340f6SAdrian Prantl     auto name_version = toDW_LNAME(sl);
211*300340f6SAdrian Prantl     // Ignore ones without a defined mapping.
212*300340f6SAdrian Prantl     if (sl == DW_LANG_Mips_Assembler || sl == DW_LANG_GOOGLE_RenderScript ||
213*300340f6SAdrian Prantl         !name_version.has_value())
214*300340f6SAdrian Prantl       return sl;
215*300340f6SAdrian Prantl     return dwarf::toDW_LANG(name_version->first, name_version->second)
216*300340f6SAdrian Prantl         .value_or(sl);
217*300340f6SAdrian Prantl   };
218*300340f6SAdrian Prantl #define HANDLE_DW_LANG(ID, NAME, LOWER_BOUND, VERSION, VENDOR)                 \
219*300340f6SAdrian Prantl   EXPECT_EQ(roundtrip(DW_LANG_##NAME), DW_LANG_##NAME);
220*300340f6SAdrian Prantl #include "llvm/BinaryFormat/Dwarf.def"
221*300340f6SAdrian Prantl }
222264b5d9eSZachary Turner } // end namespace
223