llvm.org GIT mirror llvm / 17b5682
DWARFFormValue: Add getAsSignedConstant method. The implementation accepts explicitely signed forms (DW_FORM_sdata), but also unsigned forms as long as they fit in an int64_t. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@231299 91177308-0d34-0410-b5e6-96231b3b80d8 Frederic Riss 4 years ago
3 changed file(s) with 94 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
7373 /// DWARFFormValue has form class is suitable for representing Foo.
7474 Optional getAsReference(const DWARFUnit *U) const;
7575 Optional getAsUnsignedConstant() const;
76 Optional getAsSignedConstant() const;
7677 Optional getAsCString(const DWARFUnit *U) const;
7778 Optional getAsAddress(const DWARFUnit *U) const;
7879 Optional getAsSectionOffset() const;
1717 #include "llvm/Support/Format.h"
1818 #include "llvm/Support/raw_ostream.h"
1919 #include
20 #include
2021 using namespace llvm;
2122 using namespace dwarf;
2223 using namespace syntax;
556557 return Value.uval;
557558 }
558559
560 Optional DWARFFormValue::getAsSignedConstant() const {
561 if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag)) ||
562 (Form == DW_FORM_udata && uint64_t(LLONG_MAX) < Value.uval))
563 return None;
564 switch (Form) {
565 case DW_FORM_data4:
566 return int32_t(Value.uval);
567 case DW_FORM_data2:
568 return int16_t(Value.uval);
569 case DW_FORM_data1:
570 return int8_t(Value.uval);
571 case DW_FORM_sdata:
572 case DW_FORM_data8:
573 default:
574 return Value.sval;
575 }
576 }
577
559578 Optional> DWARFFormValue::getAsBlock() const {
560579 if (!isFormClass(FC_Block) && !isFormClass(FC_Exprloc))
561580 return None;
77 //===----------------------------------------------------------------------===//
88
99 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
10 #include "llvm/ADT/SmallString.h"
1011 #include "llvm/Support/Dwarf.h"
12 #include "llvm/Support/LEB128.h"
13 #include "llvm/Support/Host.h"
1114 #include "gtest/gtest.h"
1215 using namespace llvm;
1316 using namespace dwarf;
4548 EXPECT_TRUE(isFormClass(DW_FORM_ref_sig8, DWARFFormValue::FC_Reference));
4649 }
4750
51 template
52 DWARFFormValue createDataXFormValue(uint16_t Form, RawTypeT Value) {
53 char Raw[sizeof(RawTypeT)];
54 memcpy(Raw, &Value, sizeof(RawTypeT));
55 uint32_t Offset = 0;
56 DWARFFormValue Result(Form);
57 DataExtractor Data(StringRef(Raw, sizeof(RawTypeT)),
58 sys::IsLittleEndianHost, sizeof(void*));
59 Result.extractValue(Data, &Offset, nullptr);
60 return Result;
61 }
62
63 DWARFFormValue createULEBFormValue(uint64_t Value) {
64 SmallString<10> RawData;
65 raw_svector_ostream OS(RawData);
66 encodeULEB128(Value, OS);
67 uint32_t Offset = 0;
68 DWARFFormValue Result(DW_FORM_udata);
69 DataExtractor Data(OS.str(), sys::IsLittleEndianHost, sizeof(void*));
70 Result.extractValue(Data, &Offset, nullptr);
71 return Result;
72 }
73
74 DWARFFormValue createSLEBFormValue(int64_t Value) {
75 SmallString<10> RawData;
76 raw_svector_ostream OS(RawData);
77 encodeSLEB128(Value, OS);
78 uint32_t Offset = 0;
79 DWARFFormValue Result(DW_FORM_sdata);
80 DataExtractor Data(OS.str(), sys::IsLittleEndianHost, sizeof(void*));
81 Result.extractValue(Data, &Offset, nullptr);
82 return Result;
83 }
84
85 TEST(DWARFFormValue, SignedConstantForms) {
86 // Check that we correctly sign extend fixed size forms.
87 auto Sign1 = createDataXFormValue(DW_FORM_data1, -123);
88 auto Sign2 = createDataXFormValue(DW_FORM_data2, -12345);
89 auto Sign4 = createDataXFormValue(DW_FORM_data4, -123456789);
90 auto Sign8 = createDataXFormValue(DW_FORM_data8, -1);
91 EXPECT_EQ(Sign1.getAsSignedConstant().getValue(), -123);
92 EXPECT_EQ(Sign2.getAsSignedConstant().getValue(), -12345);
93 EXPECT_EQ(Sign4.getAsSignedConstant().getValue(), -123456789);
94 EXPECT_EQ(Sign8.getAsSignedConstant().getValue(), -1);
95
96 // Check that we can handle big positive values, but that we return
97 // an error just over the limit.
98 auto UMax = createULEBFormValue(LLONG_MAX);
99 auto TooBig = createULEBFormValue(LLONG_MAX + 1);
100 EXPECT_EQ(UMax.getAsSignedConstant().getValue(), LLONG_MAX);
101 EXPECT_EQ(TooBig.getAsSignedConstant().hasValue(), false);
102
103 // Sanity check some other forms.
104 auto Data1 = createDataXFormValue(DW_FORM_data1, 120);
105 auto Data2 = createDataXFormValue(DW_FORM_data2, 32000);
106 auto Data4 = createDataXFormValue(DW_FORM_data4, 2000000000);
107 auto Data8 = createDataXFormValue(DW_FORM_data8, 0x1234567812345678LL);
108 auto LEBMin = createSLEBFormValue(LLONG_MIN);
109 auto LEBMax = createSLEBFormValue(LLONG_MAX);
110 auto LEB1 = createSLEBFormValue(-42);
111 auto LEB2 = createSLEBFormValue(42);
112 EXPECT_EQ(Data1.getAsSignedConstant().getValue(), 120);
113 EXPECT_EQ(Data2.getAsSignedConstant().getValue(), 32000);
114 EXPECT_EQ(Data4.getAsSignedConstant().getValue(), 2000000000);
115 EXPECT_EQ(Data8.getAsSignedConstant().getValue(), 0x1234567812345678LL);
116 EXPECT_EQ(LEBMin.getAsSignedConstant().getValue(), LLONG_MIN);
117 EXPECT_EQ(LEBMax.getAsSignedConstant().getValue(), LLONG_MAX);
118 EXPECT_EQ(LEB1.getAsSignedConstant().getValue(), -42);
119 EXPECT_EQ(LEB2.getAsSignedConstant().getValue(), 42);
120 }
121
48122 } // end anonymous namespace