1cada5b88SIgor Kudrin //===- llvm/unittest/DebugInfo/DWARFDebugFrameTest.cpp --------------------===//
2cada5b88SIgor Kudrin //
3cada5b88SIgor Kudrin // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4cada5b88SIgor Kudrin // See https://llvm.org/LICENSE.txt for license information.
5cada5b88SIgor Kudrin // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6cada5b88SIgor Kudrin //
7cada5b88SIgor Kudrin //===----------------------------------------------------------------------===//
8cada5b88SIgor Kudrin 
9*bee8cdcaSGeorgii Rymar #include "llvm/ADT/DenseSet.h"
10cada5b88SIgor Kudrin #include "llvm/ADT/SmallVector.h"
11cada5b88SIgor Kudrin #include "llvm/ADT/StringRef.h"
12cada5b88SIgor Kudrin #include "llvm/BinaryFormat/Dwarf.h"
13cada5b88SIgor Kudrin #include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h"
141e820e82SGeorgii Rymar #include "llvm/Testing/Support/Error.h"
15cada5b88SIgor Kudrin #include "gtest/gtest.h"
16cada5b88SIgor Kudrin 
17cada5b88SIgor Kudrin using namespace llvm;
18cada5b88SIgor Kudrin 
19cada5b88SIgor Kudrin namespace {
20cada5b88SIgor Kudrin 
21cada5b88SIgor Kudrin dwarf::CIE createCIE(bool IsDWARF64, uint64_t Offset, uint64_t Length) {
22cada5b88SIgor Kudrin   return dwarf::CIE(IsDWARF64, Offset, Length,
23cada5b88SIgor Kudrin                     /*Version=*/3,
24cada5b88SIgor Kudrin                     /*Augmentation=*/StringRef(),
25cada5b88SIgor Kudrin                     /*AddressSize=*/8,
26cada5b88SIgor Kudrin                     /*SegmentDescriptorSize=*/0,
27cada5b88SIgor Kudrin                     /*CodeAlignmentFactor=*/1,
28cada5b88SIgor Kudrin                     /*DataAlignmentFactor=*/-8,
29cada5b88SIgor Kudrin                     /*ReturnAddressRegister=*/16,
30cada5b88SIgor Kudrin                     /*AugmentationData=*/StringRef(),
31cada5b88SIgor Kudrin                     /*FDEPointerEncoding=*/dwarf::DW_EH_PE_absptr,
32cada5b88SIgor Kudrin                     /*LSDAPointerEncoding=*/dwarf::DW_EH_PE_omit,
33cada5b88SIgor Kudrin                     /*Personality=*/None,
34cada5b88SIgor Kudrin                     /*PersonalityEnc=*/None,
35cada5b88SIgor Kudrin                     /*Arch=*/Triple::x86_64);
36cada5b88SIgor Kudrin }
37cada5b88SIgor Kudrin 
38cada5b88SIgor Kudrin void expectDumpResult(const dwarf::CIE &TestCIE, bool IsEH,
39cada5b88SIgor Kudrin                       StringRef ExpectedFirstLine) {
40cada5b88SIgor Kudrin   std::string Output;
41cada5b88SIgor Kudrin   raw_string_ostream OS(Output);
42cada5b88SIgor Kudrin   TestCIE.dump(OS, /*MRI=*/nullptr, IsEH);
43cada5b88SIgor Kudrin   OS.flush();
44cada5b88SIgor Kudrin   StringRef FirstLine = StringRef(Output).split('\n').first;
45cada5b88SIgor Kudrin   EXPECT_EQ(FirstLine, ExpectedFirstLine);
46cada5b88SIgor Kudrin }
47cada5b88SIgor Kudrin 
48cada5b88SIgor Kudrin void expectDumpResult(const dwarf::FDE &TestFDE, bool IsEH,
49cada5b88SIgor Kudrin                       StringRef ExpectedFirstLine) {
50cada5b88SIgor Kudrin   std::string Output;
51cada5b88SIgor Kudrin   raw_string_ostream OS(Output);
52cada5b88SIgor Kudrin   TestFDE.dump(OS, /*MRI=*/nullptr, IsEH);
53cada5b88SIgor Kudrin   OS.flush();
54cada5b88SIgor Kudrin   StringRef FirstLine = StringRef(Output).split('\n').first;
55cada5b88SIgor Kudrin   EXPECT_EQ(FirstLine, ExpectedFirstLine);
56cada5b88SIgor Kudrin }
57cada5b88SIgor Kudrin 
58cada5b88SIgor Kudrin TEST(DWARFDebugFrame, DumpDWARF32CIE) {
59cada5b88SIgor Kudrin   dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
60cada5b88SIgor Kudrin                                  /*Offset=*/0x1111abcd,
61cada5b88SIgor Kudrin                                  /*Length=*/0x2222abcd);
62cada5b88SIgor Kudrin   expectDumpResult(TestCIE, /*IsEH=*/false, "1111abcd 2222abcd ffffffff CIE");
63cada5b88SIgor Kudrin }
64cada5b88SIgor Kudrin 
65cada5b88SIgor Kudrin TEST(DWARFDebugFrame, DumpDWARF64CIE) {
66cada5b88SIgor Kudrin   dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/true,
67cada5b88SIgor Kudrin                                  /*Offset=*/0x1111abcdabcd,
68cada5b88SIgor Kudrin                                  /*Length=*/0x2222abcdabcd);
69cada5b88SIgor Kudrin   expectDumpResult(TestCIE, /*IsEH=*/false,
70cada5b88SIgor Kudrin                    "1111abcdabcd 00002222abcdabcd ffffffffffffffff CIE");
71cada5b88SIgor Kudrin }
72cada5b88SIgor Kudrin 
73cada5b88SIgor Kudrin TEST(DWARFDebugFrame, DumpEHCIE) {
74cada5b88SIgor Kudrin   dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
75cada5b88SIgor Kudrin                                  /*Offset=*/0x1000,
76cada5b88SIgor Kudrin                                  /*Length=*/0x20);
77cada5b88SIgor Kudrin   expectDumpResult(TestCIE, /*IsEH=*/true, "00001000 00000020 00000000 CIE");
78cada5b88SIgor Kudrin }
79cada5b88SIgor Kudrin 
80cada5b88SIgor Kudrin TEST(DWARFDebugFrame, DumpEH64CIE) {
81cada5b88SIgor Kudrin   dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/true,
82cada5b88SIgor Kudrin                                  /*Offset=*/0x1000,
83cada5b88SIgor Kudrin                                  /*Length=*/0x20);
84cada5b88SIgor Kudrin   expectDumpResult(TestCIE, /*IsEH=*/true,
85cada5b88SIgor Kudrin                    "00001000 0000000000000020 00000000 CIE");
86cada5b88SIgor Kudrin }
87cada5b88SIgor Kudrin 
88cada5b88SIgor Kudrin TEST(DWARFDebugFrame, DumpDWARF64FDE) {
89cada5b88SIgor Kudrin   dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/true,
90cada5b88SIgor Kudrin                                  /*Offset=*/0x1111abcdabcd,
91cada5b88SIgor Kudrin                                  /*Length=*/0x2222abcdabcd);
92cada5b88SIgor Kudrin   dwarf::FDE TestFDE(/*IsDWARF64=*/true,
93cada5b88SIgor Kudrin                      /*Offset=*/0x3333abcdabcd,
94cada5b88SIgor Kudrin                      /*Length=*/0x4444abcdabcd,
95cada5b88SIgor Kudrin                      /*CIEPointer=*/0x1111abcdabcd,
96cada5b88SIgor Kudrin                      /*InitialLocation=*/0x5555abcdabcd,
97cada5b88SIgor Kudrin                      /*AddressRange=*/0x111111111111,
98cada5b88SIgor Kudrin                      /*Cie=*/&TestCIE,
99cada5b88SIgor Kudrin                      /*LSDAAddress=*/None,
100cada5b88SIgor Kudrin                      /*Arch=*/Triple::x86_64);
101cada5b88SIgor Kudrin   expectDumpResult(TestFDE, /*IsEH=*/false,
102cada5b88SIgor Kudrin                    "3333abcdabcd 00004444abcdabcd 00001111abcdabcd FDE "
103cada5b88SIgor Kudrin                    "cie=1111abcdabcd pc=5555abcdabcd...6666bcdebcde");
104cada5b88SIgor Kudrin }
105cada5b88SIgor Kudrin 
106cada5b88SIgor Kudrin TEST(DWARFDebugFrame, DumpEH64FDE) {
107cada5b88SIgor Kudrin   dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/true,
108cada5b88SIgor Kudrin                                  /*Offset=*/0x1111ab9a000c,
109cada5b88SIgor Kudrin                                  /*Length=*/0x20);
110cada5b88SIgor Kudrin   dwarf::FDE TestFDE(/*IsDWARF64=*/true,
111cada5b88SIgor Kudrin                      /*Offset=*/0x1111abcdabcd,
112cada5b88SIgor Kudrin                      /*Length=*/0x2222abcdabcd,
113cada5b88SIgor Kudrin                      /*CIEPointer=*/0x33abcd,
114cada5b88SIgor Kudrin                      /*InitialLocation=*/0x4444abcdabcd,
115cada5b88SIgor Kudrin                      /*AddressRange=*/0x111111111111,
116cada5b88SIgor Kudrin                      /*Cie=*/&TestCIE,
117cada5b88SIgor Kudrin                      /*LSDAAddress=*/None,
118cada5b88SIgor Kudrin                      /*Arch=*/Triple::x86_64);
119cada5b88SIgor Kudrin   expectDumpResult(TestFDE, /*IsEH=*/true,
120cada5b88SIgor Kudrin                    "1111abcdabcd 00002222abcdabcd 0033abcd FDE "
121cada5b88SIgor Kudrin                    "cie=1111ab9a000c pc=4444abcdabcd...5555bcdebcde");
122cada5b88SIgor Kudrin }
123cada5b88SIgor Kudrin 
124*bee8cdcaSGeorgii Rymar static Error parseCFI(dwarf::CIE &C, ArrayRef<uint8_t> Instructions,
1251e820e82SGeorgii Rymar                       Optional<uint64_t> Size = None) {
1261e820e82SGeorgii Rymar   DWARFDataExtractor Data(Instructions, /*IsLittleEndian=*/true,
1271e820e82SGeorgii Rymar                           /*AddressSize=*/8);
1281e820e82SGeorgii Rymar   uint64_t Offset = 0;
1291e820e82SGeorgii Rymar   const uint64_t EndOffset = Size ? *Size : (uint64_t)Instructions.size();
1301e820e82SGeorgii Rymar   return C.cfis().parse(Data, &Offset, EndOffset);
131*bee8cdcaSGeorgii Rymar }
132*bee8cdcaSGeorgii Rymar 
133*bee8cdcaSGeorgii Rymar TEST(DWARFDebugFrame, InvalidCFIOpcodesTest) {
134*bee8cdcaSGeorgii Rymar   llvm::DenseSet<uint8_t> ValidExtendedOpcodes = {
135*bee8cdcaSGeorgii Rymar       dwarf::DW_CFA_nop,
136*bee8cdcaSGeorgii Rymar       dwarf::DW_CFA_advance_loc,
137*bee8cdcaSGeorgii Rymar       dwarf::DW_CFA_offset,
138*bee8cdcaSGeorgii Rymar       dwarf::DW_CFA_restore,
139*bee8cdcaSGeorgii Rymar       dwarf::DW_CFA_set_loc,
140*bee8cdcaSGeorgii Rymar       dwarf::DW_CFA_advance_loc1,
141*bee8cdcaSGeorgii Rymar       dwarf::DW_CFA_advance_loc2,
142*bee8cdcaSGeorgii Rymar       dwarf::DW_CFA_advance_loc4,
143*bee8cdcaSGeorgii Rymar       dwarf::DW_CFA_offset_extended,
144*bee8cdcaSGeorgii Rymar       dwarf::DW_CFA_restore_extended,
145*bee8cdcaSGeorgii Rymar       dwarf::DW_CFA_undefined,
146*bee8cdcaSGeorgii Rymar       dwarf::DW_CFA_same_value,
147*bee8cdcaSGeorgii Rymar       dwarf::DW_CFA_register,
148*bee8cdcaSGeorgii Rymar       dwarf::DW_CFA_remember_state,
149*bee8cdcaSGeorgii Rymar       dwarf::DW_CFA_restore_state,
150*bee8cdcaSGeorgii Rymar       dwarf::DW_CFA_def_cfa,
151*bee8cdcaSGeorgii Rymar       dwarf::DW_CFA_def_cfa_register,
152*bee8cdcaSGeorgii Rymar       dwarf::DW_CFA_def_cfa_offset,
153*bee8cdcaSGeorgii Rymar       dwarf::DW_CFA_def_cfa_expression,
154*bee8cdcaSGeorgii Rymar       dwarf::DW_CFA_expression,
155*bee8cdcaSGeorgii Rymar       dwarf::DW_CFA_offset_extended_sf,
156*bee8cdcaSGeorgii Rymar       dwarf::DW_CFA_def_cfa_sf,
157*bee8cdcaSGeorgii Rymar       dwarf::DW_CFA_def_cfa_offset_sf,
158*bee8cdcaSGeorgii Rymar       dwarf::DW_CFA_val_offset,
159*bee8cdcaSGeorgii Rymar       dwarf::DW_CFA_val_offset_sf,
160*bee8cdcaSGeorgii Rymar       dwarf::DW_CFA_val_expression,
161*bee8cdcaSGeorgii Rymar       dwarf::DW_CFA_MIPS_advance_loc8,
162*bee8cdcaSGeorgii Rymar       dwarf::DW_CFA_GNU_window_save,
163*bee8cdcaSGeorgii Rymar       dwarf::DW_CFA_AARCH64_negate_ra_state,
164*bee8cdcaSGeorgii Rymar       dwarf::DW_CFA_GNU_args_size};
1651e820e82SGeorgii Rymar 
1661e820e82SGeorgii Rymar   dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
1671e820e82SGeorgii Rymar                                  /*Offset=*/0x0,
1681e820e82SGeorgii Rymar                                  /*Length=*/0xff);
1691e820e82SGeorgii Rymar 
170*bee8cdcaSGeorgii Rymar   // See DWARF standard v3, section 7.23: low 6 bits are used to encode an
171*bee8cdcaSGeorgii Rymar   // extended opcode.
172*bee8cdcaSGeorgii Rymar   for (uint8_t Code = 0; Code <= 63; ++Code) {
173*bee8cdcaSGeorgii Rymar     if (ValidExtendedOpcodes.count(Code))
174*bee8cdcaSGeorgii Rymar       continue;
175*bee8cdcaSGeorgii Rymar 
176*bee8cdcaSGeorgii Rymar     EXPECT_THAT_ERROR(parseCFI(TestCIE, Code),
177*bee8cdcaSGeorgii Rymar                       FailedWithMessage(("invalid extended CFI opcode 0x" +
178*bee8cdcaSGeorgii Rymar                                          Twine::utohexstr(Code))
179*bee8cdcaSGeorgii Rymar                                             .str()
180*bee8cdcaSGeorgii Rymar                                             .c_str()));
181*bee8cdcaSGeorgii Rymar   }
182*bee8cdcaSGeorgii Rymar }
183*bee8cdcaSGeorgii Rymar 
184*bee8cdcaSGeorgii Rymar // Here we test how truncated Call Frame Instructions are parsed.
185*bee8cdcaSGeorgii Rymar TEST(DWARFDebugFrame, ParseTruncatedCFITest) {
186*bee8cdcaSGeorgii Rymar   dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
187*bee8cdcaSGeorgii Rymar                                  /*Offset=*/0x0,
188*bee8cdcaSGeorgii Rymar                                  /*Length=*/0xff);
189*bee8cdcaSGeorgii Rymar 
1901e820e82SGeorgii Rymar   // Having an empty instructions list is fine.
191*bee8cdcaSGeorgii Rymar   EXPECT_THAT_ERROR(parseCFI(TestCIE, {}), Succeeded());
1921e820e82SGeorgii Rymar 
1931e820e82SGeorgii Rymar   // Unable to read an opcode, because the instructions list is empty, but we
1941e820e82SGeorgii Rymar   // say to the parser that it is not.
1951e820e82SGeorgii Rymar   EXPECT_THAT_ERROR(
196*bee8cdcaSGeorgii Rymar       parseCFI(TestCIE, {}, /*Size=*/1),
1971e820e82SGeorgii Rymar       FailedWithMessage(
1981e820e82SGeorgii Rymar           "unexpected end of data at offset 0x0 while reading [0x0, 0x1)"));
1991e820e82SGeorgii Rymar 
2001e820e82SGeorgii Rymar   // Unable to read a truncated DW_CFA_offset instruction.
2011e820e82SGeorgii Rymar   EXPECT_THAT_ERROR(
202*bee8cdcaSGeorgii Rymar       parseCFI(TestCIE, {dwarf::DW_CFA_offset}),
2031e820e82SGeorgii Rymar       FailedWithMessage("unable to decode LEB128 at offset 0x00000001: "
2041e820e82SGeorgii Rymar                         "malformed uleb128, extends past end"));
2051e820e82SGeorgii Rymar 
2061e820e82SGeorgii Rymar   // Unable to read a truncated DW_CFA_set_loc instruction.
2071e820e82SGeorgii Rymar   EXPECT_THAT_ERROR(
208*bee8cdcaSGeorgii Rymar       parseCFI(TestCIE, {dwarf::DW_CFA_set_loc}),
2091e820e82SGeorgii Rymar       FailedWithMessage(
2101e820e82SGeorgii Rymar           "unexpected end of data at offset 0x1 while reading [0x1, 0x9)"));
2111e820e82SGeorgii Rymar 
2121e820e82SGeorgii Rymar   // Unable to read a truncated DW_CFA_advance_loc1 instruction.
2131e820e82SGeorgii Rymar   EXPECT_THAT_ERROR(
214*bee8cdcaSGeorgii Rymar       parseCFI(TestCIE, {dwarf::DW_CFA_advance_loc1}),
2151e820e82SGeorgii Rymar       FailedWithMessage(
2161e820e82SGeorgii Rymar           "unexpected end of data at offset 0x1 while reading [0x1, 0x2)"));
2171e820e82SGeorgii Rymar 
2181e820e82SGeorgii Rymar   // Unable to read a truncated DW_CFA_advance_loc2 instruction.
2191e820e82SGeorgii Rymar   EXPECT_THAT_ERROR(
220*bee8cdcaSGeorgii Rymar       parseCFI(TestCIE, {dwarf::DW_CFA_advance_loc2}),
2211e820e82SGeorgii Rymar       FailedWithMessage(
2221e820e82SGeorgii Rymar           "unexpected end of data at offset 0x1 while reading [0x1, 0x3)"));
2231e820e82SGeorgii Rymar 
2241e820e82SGeorgii Rymar   // Unable to read a truncated DW_CFA_advance_loc4 instruction.
2251e820e82SGeorgii Rymar   EXPECT_THAT_ERROR(
226*bee8cdcaSGeorgii Rymar       parseCFI(TestCIE, {dwarf::DW_CFA_advance_loc4}),
2271e820e82SGeorgii Rymar       FailedWithMessage(
2281e820e82SGeorgii Rymar           "unexpected end of data at offset 0x1 while reading [0x1, 0x5)"));
2291e820e82SGeorgii Rymar 
2301e820e82SGeorgii Rymar   // A test for an instruction with a single ULEB128 operand.
2311e820e82SGeorgii Rymar   auto CheckOp_ULEB128 = [&](uint8_t Inst) {
2321e820e82SGeorgii Rymar     EXPECT_THAT_ERROR(
233*bee8cdcaSGeorgii Rymar         parseCFI(TestCIE, Inst),
2341e820e82SGeorgii Rymar         FailedWithMessage("unable to decode LEB128 at offset 0x00000001: "
2351e820e82SGeorgii Rymar                           "malformed uleb128, extends past end"));
2361e820e82SGeorgii Rymar   };
2371e820e82SGeorgii Rymar 
2381e820e82SGeorgii Rymar   for (uint8_t Inst :
2391e820e82SGeorgii Rymar        {dwarf::DW_CFA_restore_extended, dwarf::DW_CFA_undefined,
2401e820e82SGeorgii Rymar         dwarf::DW_CFA_same_value, dwarf::DW_CFA_def_cfa_register,
2411e820e82SGeorgii Rymar         dwarf::DW_CFA_def_cfa_offset, dwarf::DW_CFA_GNU_args_size})
2421e820e82SGeorgii Rymar     CheckOp_ULEB128(Inst);
2431e820e82SGeorgii Rymar 
2441e820e82SGeorgii Rymar   // Unable to read a truncated DW_CFA_def_cfa_offset_sf instruction.
2451e820e82SGeorgii Rymar   EXPECT_THAT_ERROR(
246*bee8cdcaSGeorgii Rymar       parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa_offset_sf}),
2471e820e82SGeorgii Rymar       FailedWithMessage("unable to decode LEB128 at offset 0x00000001: "
2481e820e82SGeorgii Rymar                         "malformed sleb128, extends past end"));
2491e820e82SGeorgii Rymar 
2501e820e82SGeorgii Rymar   // A test for an instruction with two ULEB128 operands.
2511e820e82SGeorgii Rymar   auto CheckOp_ULEB128_ULEB128 = [&](uint8_t Inst) {
2521e820e82SGeorgii Rymar     EXPECT_THAT_ERROR(
253*bee8cdcaSGeorgii Rymar         parseCFI(TestCIE, Inst),
2541e820e82SGeorgii Rymar         FailedWithMessage("unable to decode LEB128 at offset 0x00000001: "
2551e820e82SGeorgii Rymar                           "malformed uleb128, extends past end"));
2561e820e82SGeorgii Rymar 
2571e820e82SGeorgii Rymar     EXPECT_THAT_ERROR(
258*bee8cdcaSGeorgii Rymar         parseCFI(TestCIE, {Inst, /*Op1=*/0}),
2591e820e82SGeorgii Rymar         FailedWithMessage("unable to decode LEB128 at offset 0x00000002: "
2601e820e82SGeorgii Rymar                           "malformed uleb128, extends past end"));
2611e820e82SGeorgii Rymar   };
2621e820e82SGeorgii Rymar 
2631e820e82SGeorgii Rymar   for (uint8_t Inst : {dwarf::DW_CFA_offset_extended, dwarf::DW_CFA_register,
2641e820e82SGeorgii Rymar                        dwarf::DW_CFA_def_cfa, dwarf::DW_CFA_val_offset})
2651e820e82SGeorgii Rymar     CheckOp_ULEB128_ULEB128(Inst);
2661e820e82SGeorgii Rymar 
2671e820e82SGeorgii Rymar   // A test for an instruction with two operands: ULEB128, SLEB128.
2681e820e82SGeorgii Rymar   auto CheckOp_ULEB128_SLEB128 = [&](uint8_t Inst) {
2691e820e82SGeorgii Rymar     EXPECT_THAT_ERROR(
270*bee8cdcaSGeorgii Rymar         parseCFI(TestCIE, Inst),
2711e820e82SGeorgii Rymar         FailedWithMessage("unable to decode LEB128 at offset 0x00000001: "
2721e820e82SGeorgii Rymar                           "malformed uleb128, extends past end"));
2731e820e82SGeorgii Rymar 
2741e820e82SGeorgii Rymar     EXPECT_THAT_ERROR(
275*bee8cdcaSGeorgii Rymar         parseCFI(TestCIE, {Inst, /*Op1=*/0}),
2761e820e82SGeorgii Rymar         FailedWithMessage("unable to decode LEB128 at offset 0x00000002: "
2771e820e82SGeorgii Rymar                           "malformed sleb128, extends past end"));
2781e820e82SGeorgii Rymar   };
2791e820e82SGeorgii Rymar 
2801e820e82SGeorgii Rymar   for (uint8_t Inst : {dwarf::DW_CFA_offset_extended_sf,
2811e820e82SGeorgii Rymar                        dwarf::DW_CFA_def_cfa_sf, dwarf::DW_CFA_val_offset_sf})
2821e820e82SGeorgii Rymar     CheckOp_ULEB128_SLEB128(Inst);
2831e820e82SGeorgii Rymar 
2841e820e82SGeorgii Rymar   // Unable to read a truncated DW_CFA_def_cfa_expression instruction.
2851e820e82SGeorgii Rymar   EXPECT_THAT_ERROR(
286*bee8cdcaSGeorgii Rymar       parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa_expression}),
2871e820e82SGeorgii Rymar       FailedWithMessage("unable to decode LEB128 at offset 0x00000001: "
2881e820e82SGeorgii Rymar                         "malformed uleb128, extends past end"));
2891e820e82SGeorgii Rymar   EXPECT_THAT_ERROR(
290*bee8cdcaSGeorgii Rymar       parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa_expression,
2911e820e82SGeorgii Rymar                          /*expression length=*/0x1}),
2921e820e82SGeorgii Rymar       FailedWithMessage(
2931e820e82SGeorgii Rymar           "unexpected end of data at offset 0x2 while reading [0x2, 0x3)"));
2941e820e82SGeorgii Rymar   // The DW_CFA_def_cfa_expression can contain a zero length expression.
295*bee8cdcaSGeorgii Rymar   EXPECT_THAT_ERROR(parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa_expression,
2961e820e82SGeorgii Rymar                                        /*ExprLen=*/0}),
2971e820e82SGeorgii Rymar                     Succeeded());
2981e820e82SGeorgii Rymar 
2991e820e82SGeorgii Rymar   // A test for an instruction with three operands: ULEB128, expression length
3001e820e82SGeorgii Rymar   // (ULEB128) and expression bytes.
3011e820e82SGeorgii Rymar   auto CheckOp_ULEB128_Expr = [&](uint8_t Inst) {
3021e820e82SGeorgii Rymar     EXPECT_THAT_ERROR(
303*bee8cdcaSGeorgii Rymar         parseCFI(TestCIE, {Inst}),
3041e820e82SGeorgii Rymar         FailedWithMessage("unable to decode LEB128 at offset 0x00000001: "
3051e820e82SGeorgii Rymar                           "malformed uleb128, extends past end"));
3061e820e82SGeorgii Rymar     EXPECT_THAT_ERROR(
307*bee8cdcaSGeorgii Rymar         parseCFI(TestCIE, {Inst, /*Op1=*/0}),
3081e820e82SGeorgii Rymar         FailedWithMessage("unable to decode LEB128 at offset 0x00000002: "
3091e820e82SGeorgii Rymar                           "malformed uleb128, extends past end"));
3101e820e82SGeorgii Rymar     // A zero length expression is fine
311*bee8cdcaSGeorgii Rymar     EXPECT_THAT_ERROR(parseCFI(TestCIE, {Inst,
3121e820e82SGeorgii Rymar                                          /*Op1=*/0, /*ExprLen=*/0}),
3131e820e82SGeorgii Rymar                       Succeeded());
3141e820e82SGeorgii Rymar     EXPECT_THAT_ERROR(
315*bee8cdcaSGeorgii Rymar         parseCFI(TestCIE, {Inst,
3161e820e82SGeorgii Rymar                            /*Op1=*/0, /*ExprLen=*/1}),
3171e820e82SGeorgii Rymar         FailedWithMessage(
3181e820e82SGeorgii Rymar             "unexpected end of data at offset 0x3 while reading [0x3, 0x4)"));
3191e820e82SGeorgii Rymar   };
3201e820e82SGeorgii Rymar 
3211e820e82SGeorgii Rymar   for (uint8_t Inst : {dwarf::DW_CFA_expression, dwarf::DW_CFA_val_expression})
3221e820e82SGeorgii Rymar     CheckOp_ULEB128_Expr(Inst);
3231e820e82SGeorgii Rymar }
3241e820e82SGeorgii Rymar 
325cada5b88SIgor Kudrin } // end anonymous namespace
326