1 //===- llvm/unittest/DebugInfo/DWARFFormValueTest.cpp ---------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
10 #include "llvm/ADT/ArrayRef.h"
11 #include "llvm/ADT/SmallString.h"
12 #include "llvm/BinaryFormat/Dwarf.h"
13 #include "llvm/Support/Host.h"
14 #include "llvm/Support/LEB128.h"
15 #include "gtest/gtest.h"
18 using namespace dwarf
;
22 bool isFormClass(dwarf::Form Form
, DWARFFormValue::FormClass FC
) {
23 return DWARFFormValue(Form
).isFormClass(FC
);
26 TEST(DWARFFormValue
, FormClass
) {
27 EXPECT_TRUE(isFormClass(DW_FORM_addr
, DWARFFormValue::FC_Address
));
28 EXPECT_FALSE(isFormClass(DW_FORM_data8
, DWARFFormValue::FC_Address
));
29 EXPECT_TRUE(isFormClass(DW_FORM_data8
, DWARFFormValue::FC_Constant
));
30 EXPECT_TRUE(isFormClass(DW_FORM_data8
, DWARFFormValue::FC_SectionOffset
));
32 isFormClass(DW_FORM_sec_offset
, DWARFFormValue::FC_SectionOffset
));
33 EXPECT_TRUE(isFormClass(DW_FORM_GNU_str_index
, DWARFFormValue::FC_String
));
34 EXPECT_TRUE(isFormClass(DW_FORM_GNU_addr_index
, DWARFFormValue::FC_Address
));
35 EXPECT_FALSE(isFormClass(DW_FORM_ref_addr
, DWARFFormValue::FC_Address
));
36 EXPECT_TRUE(isFormClass(DW_FORM_ref_addr
, DWARFFormValue::FC_Reference
));
37 EXPECT_TRUE(isFormClass(DW_FORM_ref_sig8
, DWARFFormValue::FC_Reference
));
40 template<typename RawTypeT
>
41 DWARFFormValue
createDataXFormValue(dwarf::Form Form
, RawTypeT Value
) {
42 char Raw
[sizeof(RawTypeT
)];
43 memcpy(Raw
, &Value
, sizeof(RawTypeT
));
45 DWARFFormValue
Result(Form
);
46 DWARFDataExtractor
Data(StringRef(Raw
, sizeof(RawTypeT
)),
47 sys::IsLittleEndianHost
, sizeof(void *));
48 Result
.extractValue(Data
, &Offset
, {0, 0, dwarf::DwarfFormat::DWARF32
});
52 DWARFFormValue
createULEBFormValue(uint64_t Value
) {
53 SmallString
<10> RawData
;
54 raw_svector_ostream
OS(RawData
);
55 encodeULEB128(Value
, OS
);
57 DWARFFormValue
Result(DW_FORM_udata
);
58 DWARFDataExtractor
Data(OS
.str(), sys::IsLittleEndianHost
, sizeof(void *));
59 Result
.extractValue(Data
, &Offset
, {0, 0, dwarf::DwarfFormat::DWARF32
});
63 DWARFFormValue
createSLEBFormValue(int64_t Value
) {
64 SmallString
<10> RawData
;
65 raw_svector_ostream
OS(RawData
);
66 encodeSLEB128(Value
, OS
);
68 DWARFFormValue
Result(DW_FORM_sdata
);
69 DWARFDataExtractor
Data(OS
.str(), sys::IsLittleEndianHost
, sizeof(void *));
70 Result
.extractValue(Data
, &Offset
, {0, 0, dwarf::DwarfFormat::DWARF32
});
74 TEST(DWARFFormValue
, SignedConstantForms
) {
75 // Check that we correctly sign extend fixed size forms.
76 auto Sign1
= createDataXFormValue
<uint8_t>(DW_FORM_data1
, -123);
77 auto Sign2
= createDataXFormValue
<uint16_t>(DW_FORM_data2
, -12345);
78 auto Sign4
= createDataXFormValue
<uint32_t>(DW_FORM_data4
, -123456789);
79 auto Sign8
= createDataXFormValue
<uint64_t>(DW_FORM_data8
, -1);
80 EXPECT_EQ(Sign1
.getAsSignedConstant().getValue(), -123);
81 EXPECT_EQ(Sign2
.getAsSignedConstant().getValue(), -12345);
82 EXPECT_EQ(Sign4
.getAsSignedConstant().getValue(), -123456789);
83 EXPECT_EQ(Sign8
.getAsSignedConstant().getValue(), -1);
85 // Check that we can handle big positive values, but that we return
86 // an error just over the limit.
87 auto UMax
= createULEBFormValue(LLONG_MAX
);
88 auto TooBig
= createULEBFormValue(uint64_t(LLONG_MAX
) + 1);
89 EXPECT_EQ(UMax
.getAsSignedConstant().getValue(), LLONG_MAX
);
90 EXPECT_EQ(TooBig
.getAsSignedConstant().hasValue(), false);
92 // Sanity check some other forms.
93 auto Data1
= createDataXFormValue
<uint8_t>(DW_FORM_data1
, 120);
94 auto Data2
= createDataXFormValue
<uint16_t>(DW_FORM_data2
, 32000);
95 auto Data4
= createDataXFormValue
<uint32_t>(DW_FORM_data4
, 2000000000);
96 auto Data8
= createDataXFormValue
<uint64_t>(DW_FORM_data8
, 0x1234567812345678LL
);
97 auto LEBMin
= createSLEBFormValue(LLONG_MIN
);
98 auto LEBMax
= createSLEBFormValue(LLONG_MAX
);
99 auto LEB1
= createSLEBFormValue(-42);
100 auto LEB2
= createSLEBFormValue(42);
101 EXPECT_EQ(Data1
.getAsSignedConstant().getValue(), 120);
102 EXPECT_EQ(Data2
.getAsSignedConstant().getValue(), 32000);
103 EXPECT_EQ(Data4
.getAsSignedConstant().getValue(), 2000000000);
104 EXPECT_EQ(Data8
.getAsSignedConstant().getValue(), 0x1234567812345678LL
);
105 EXPECT_EQ(LEBMin
.getAsSignedConstant().getValue(), LLONG_MIN
);
106 EXPECT_EQ(LEBMax
.getAsSignedConstant().getValue(), LLONG_MAX
);
107 EXPECT_EQ(LEB1
.getAsSignedConstant().getValue(), -42);
108 EXPECT_EQ(LEB2
.getAsSignedConstant().getValue(), 42);
110 // Data16 is a little tricky.
111 char Cksum
[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
112 DWARFFormValue
Data16(DW_FORM_data16
);
113 DWARFDataExtractor
DE16(StringRef(Cksum
, 16), sys::IsLittleEndianHost
,
116 Data16
.extractValue(DE16
, &Offset
, {0, 0, dwarf::DwarfFormat::DWARF32
});
118 raw_svector_ostream
Res(Str
);
119 Data16
.dump(Res
, DIDumpOptions());
120 EXPECT_EQ(memcmp(Str
.data(), "000102030405060708090a0b0c0d0e0f", 32), 0);
123 } // end anonymous namespace