xref: /llvm-project/llvm/unittests/DebugInfo/DWARF/DWARFDebugFrameTest.cpp (revision aa8feeefd3ac6c78ee8f67bf033976fc7d68bc6d)
1 //===- llvm/unittest/DebugInfo/DWARFDebugFrameTest.cpp --------------------===//
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/DebugInfo/DWARF/DWARFDebugFrame.h"
10 #include "llvm/ADT/DenseSet.h"
11 #include "llvm/ADT/SmallVector.h"
12 #include "llvm/ADT/StringRef.h"
13 #include "llvm/BinaryFormat/Dwarf.h"
14 #include "llvm/DebugInfo/DIContext.h"
15 #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
16 #include "llvm/Testing/Support/Error.h"
17 #include "gtest/gtest.h"
18 
19 using namespace llvm;
20 
21 namespace {
22 
23 dwarf::CIE createCIE(bool IsDWARF64, uint64_t Offset, uint64_t Length) {
24   return dwarf::CIE(IsDWARF64, Offset, Length,
25                     /*Version=*/3,
26                     /*Augmentation=*/StringRef(),
27                     /*AddressSize=*/8,
28                     /*SegmentDescriptorSize=*/0,
29                     /*CodeAlignmentFactor=*/1,
30                     /*DataAlignmentFactor=*/-8,
31                     /*ReturnAddressRegister=*/16,
32                     /*AugmentationData=*/StringRef(),
33                     /*FDEPointerEncoding=*/dwarf::DW_EH_PE_absptr,
34                     /*LSDAPointerEncoding=*/dwarf::DW_EH_PE_omit,
35                     /*Personality=*/None,
36                     /*PersonalityEnc=*/None,
37                     /*Arch=*/Triple::x86_64);
38 }
39 
40 void expectDumpResult(const dwarf::CIE &TestCIE, bool IsEH,
41                       StringRef ExpectedFirstLine) {
42   std::string Output;
43   raw_string_ostream OS(Output);
44   TestCIE.dump(OS, DIDumpOptions(), /*MRI=*/nullptr, IsEH);
45   OS.flush();
46   StringRef FirstLine = StringRef(Output).split('\n').first;
47   EXPECT_EQ(FirstLine, ExpectedFirstLine);
48 }
49 
50 void expectDumpResult(const dwarf::FDE &TestFDE, bool IsEH,
51                       StringRef ExpectedFirstLine) {
52   std::string Output;
53   raw_string_ostream OS(Output);
54   TestFDE.dump(OS, DIDumpOptions(), /*MRI=*/nullptr, IsEH);
55   OS.flush();
56   StringRef FirstLine = StringRef(Output).split('\n').first;
57   EXPECT_EQ(FirstLine, ExpectedFirstLine);
58 }
59 
60 TEST(DWARFDebugFrame, DumpDWARF32CIE) {
61   dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
62                                  /*Offset=*/0x1111abcd,
63                                  /*Length=*/0x2222abcd);
64   expectDumpResult(TestCIE, /*IsEH=*/false, "1111abcd 2222abcd ffffffff CIE");
65 }
66 
67 TEST(DWARFDebugFrame, DumpDWARF64CIE) {
68   dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/true,
69                                  /*Offset=*/0x1111abcdabcd,
70                                  /*Length=*/0x2222abcdabcd);
71   expectDumpResult(TestCIE, /*IsEH=*/false,
72                    "1111abcdabcd 00002222abcdabcd ffffffffffffffff CIE");
73 }
74 
75 TEST(DWARFDebugFrame, DumpEHCIE) {
76   dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
77                                  /*Offset=*/0x1000,
78                                  /*Length=*/0x20);
79   expectDumpResult(TestCIE, /*IsEH=*/true, "00001000 00000020 00000000 CIE");
80 }
81 
82 TEST(DWARFDebugFrame, DumpEH64CIE) {
83   dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/true,
84                                  /*Offset=*/0x1000,
85                                  /*Length=*/0x20);
86   expectDumpResult(TestCIE, /*IsEH=*/true,
87                    "00001000 0000000000000020 00000000 CIE");
88 }
89 
90 TEST(DWARFDebugFrame, DumpDWARF64FDE) {
91   dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/true,
92                                  /*Offset=*/0x1111abcdabcd,
93                                  /*Length=*/0x2222abcdabcd);
94   dwarf::FDE TestFDE(/*IsDWARF64=*/true,
95                      /*Offset=*/0x3333abcdabcd,
96                      /*Length=*/0x4444abcdabcd,
97                      /*CIEPointer=*/0x1111abcdabcd,
98                      /*InitialLocation=*/0x5555abcdabcd,
99                      /*AddressRange=*/0x111111111111,
100                      /*Cie=*/&TestCIE,
101                      /*LSDAAddress=*/None,
102                      /*Arch=*/Triple::x86_64);
103   expectDumpResult(TestFDE, /*IsEH=*/false,
104                    "3333abcdabcd 00004444abcdabcd 00001111abcdabcd FDE "
105                    "cie=1111abcdabcd pc=5555abcdabcd...6666bcdebcde");
106 }
107 
108 TEST(DWARFDebugFrame, DumpEH64FDE) {
109   dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/true,
110                                  /*Offset=*/0x1111ab9a000c,
111                                  /*Length=*/0x20);
112   dwarf::FDE TestFDE(/*IsDWARF64=*/true,
113                      /*Offset=*/0x1111abcdabcd,
114                      /*Length=*/0x2222abcdabcd,
115                      /*CIEPointer=*/0x33abcd,
116                      /*InitialLocation=*/0x4444abcdabcd,
117                      /*AddressRange=*/0x111111111111,
118                      /*Cie=*/&TestCIE,
119                      /*LSDAAddress=*/None,
120                      /*Arch=*/Triple::x86_64);
121   expectDumpResult(TestFDE, /*IsEH=*/true,
122                    "1111abcdabcd 00002222abcdabcd 0033abcd FDE "
123                    "cie=1111ab9a000c pc=4444abcdabcd...5555bcdebcde");
124 }
125 
126 static Error parseCFI(dwarf::CIE &C, ArrayRef<uint8_t> Instructions,
127                       Optional<uint64_t> Size = None) {
128   DWARFDataExtractor Data(Instructions, /*IsLittleEndian=*/true,
129                           /*AddressSize=*/8);
130   uint64_t Offset = 0;
131   const uint64_t EndOffset = Size ? *Size : (uint64_t)Instructions.size();
132   return C.cfis().parse(Data, &Offset, EndOffset);
133 }
134 
135 static Error parseCFI(dwarf::FDE &FDE, ArrayRef<uint8_t> Instructions) {
136   DWARFDataExtractor Data(Instructions, /*IsLittleEndian=*/true,
137                           /*AddressSize=*/8);
138   uint64_t Offset = 0;
139   return FDE.cfis().parse(Data, &Offset, Instructions.size());
140 }
141 
142 TEST(DWARFDebugFrame, InvalidCFIOpcodesTest) {
143   llvm::DenseSet<uint8_t> ValidExtendedOpcodes = {
144       dwarf::DW_CFA_nop,
145       dwarf::DW_CFA_advance_loc,
146       dwarf::DW_CFA_offset,
147       dwarf::DW_CFA_restore,
148       dwarf::DW_CFA_set_loc,
149       dwarf::DW_CFA_advance_loc1,
150       dwarf::DW_CFA_advance_loc2,
151       dwarf::DW_CFA_advance_loc4,
152       dwarf::DW_CFA_offset_extended,
153       dwarf::DW_CFA_restore_extended,
154       dwarf::DW_CFA_undefined,
155       dwarf::DW_CFA_same_value,
156       dwarf::DW_CFA_register,
157       dwarf::DW_CFA_remember_state,
158       dwarf::DW_CFA_restore_state,
159       dwarf::DW_CFA_def_cfa,
160       dwarf::DW_CFA_def_cfa_register,
161       dwarf::DW_CFA_def_cfa_offset,
162       dwarf::DW_CFA_def_cfa_expression,
163       dwarf::DW_CFA_expression,
164       dwarf::DW_CFA_offset_extended_sf,
165       dwarf::DW_CFA_def_cfa_sf,
166       dwarf::DW_CFA_def_cfa_offset_sf,
167       dwarf::DW_CFA_LLVM_def_aspace_cfa,
168       dwarf::DW_CFA_LLVM_def_aspace_cfa_sf,
169       dwarf::DW_CFA_val_offset,
170       dwarf::DW_CFA_val_offset_sf,
171       dwarf::DW_CFA_val_expression,
172       dwarf::DW_CFA_MIPS_advance_loc8,
173       dwarf::DW_CFA_GNU_window_save,
174       dwarf::DW_CFA_AARCH64_negate_ra_state,
175       dwarf::DW_CFA_GNU_args_size};
176 
177   dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
178                                  /*Offset=*/0x0,
179                                  /*Length=*/0xff);
180 
181   // See DWARF standard v3, section 7.23: low 6 bits are used to encode an
182   // extended opcode.
183   for (uint8_t Code = 0; Code <= 63; ++Code) {
184     if (ValidExtendedOpcodes.count(Code))
185       continue;
186 
187     EXPECT_THAT_ERROR(parseCFI(TestCIE, Code),
188                       FailedWithMessage(("invalid extended CFI opcode 0x" +
189                                          Twine::utohexstr(Code))
190                                             .str()
191                                             .c_str()));
192   }
193 }
194 
195 // Here we test how truncated Call Frame Instructions are parsed.
196 TEST(DWARFDebugFrame, ParseTruncatedCFITest) {
197   dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
198                                  /*Offset=*/0x0,
199                                  /*Length=*/0xff);
200 
201   // Having an empty instructions list is fine.
202   EXPECT_THAT_ERROR(parseCFI(TestCIE, {}), Succeeded());
203 
204   // Unable to read an opcode, because the instructions list is empty, but we
205   // say to the parser that it is not.
206   EXPECT_THAT_ERROR(
207       parseCFI(TestCIE, {}, /*Size=*/1),
208       FailedWithMessage(
209           "unexpected end of data at offset 0x0 while reading [0x0, 0x1)"));
210 
211   // Unable to read a truncated DW_CFA_offset instruction.
212   EXPECT_THAT_ERROR(
213       parseCFI(TestCIE, {dwarf::DW_CFA_offset}),
214       FailedWithMessage("unable to decode LEB128 at offset 0x00000001: "
215                         "malformed uleb128, extends past end"));
216 
217   // Unable to read a truncated DW_CFA_set_loc instruction.
218   EXPECT_THAT_ERROR(
219       parseCFI(TestCIE, {dwarf::DW_CFA_set_loc}),
220       FailedWithMessage(
221           "unexpected end of data at offset 0x1 while reading [0x1, 0x9)"));
222 
223   // Unable to read a truncated DW_CFA_advance_loc1 instruction.
224   EXPECT_THAT_ERROR(
225       parseCFI(TestCIE, {dwarf::DW_CFA_advance_loc1}),
226       FailedWithMessage(
227           "unexpected end of data at offset 0x1 while reading [0x1, 0x2)"));
228 
229   // Unable to read a truncated DW_CFA_advance_loc2 instruction.
230   EXPECT_THAT_ERROR(
231       parseCFI(TestCIE, {dwarf::DW_CFA_advance_loc2}),
232       FailedWithMessage(
233           "unexpected end of data at offset 0x1 while reading [0x1, 0x3)"));
234 
235   // Unable to read a truncated DW_CFA_advance_loc4 instruction.
236   EXPECT_THAT_ERROR(
237       parseCFI(TestCIE, {dwarf::DW_CFA_advance_loc4}),
238       FailedWithMessage(
239           "unexpected end of data at offset 0x1 while reading [0x1, 0x5)"));
240 
241   // A test for an instruction with a single ULEB128 operand.
242   auto CheckOp_ULEB128 = [&](uint8_t Inst) {
243     EXPECT_THAT_ERROR(
244         parseCFI(TestCIE, Inst),
245         FailedWithMessage("unable to decode LEB128 at offset 0x00000001: "
246                           "malformed uleb128, extends past end"));
247   };
248 
249   for (uint8_t Inst :
250        {dwarf::DW_CFA_restore_extended, dwarf::DW_CFA_undefined,
251         dwarf::DW_CFA_same_value, dwarf::DW_CFA_def_cfa_register,
252         dwarf::DW_CFA_def_cfa_offset, dwarf::DW_CFA_GNU_args_size})
253     CheckOp_ULEB128(Inst);
254 
255   // Unable to read a truncated DW_CFA_def_cfa_offset_sf instruction.
256   EXPECT_THAT_ERROR(
257       parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa_offset_sf}),
258       FailedWithMessage("unable to decode LEB128 at offset 0x00000001: "
259                         "malformed sleb128, extends past end"));
260 
261   // A test for an instruction with two ULEB128 operands.
262   auto CheckOp_ULEB128_ULEB128 = [&](uint8_t Inst) {
263     EXPECT_THAT_ERROR(
264         parseCFI(TestCIE, Inst),
265         FailedWithMessage("unable to decode LEB128 at offset 0x00000001: "
266                           "malformed uleb128, extends past end"));
267 
268     EXPECT_THAT_ERROR(
269         parseCFI(TestCIE, {Inst, /*Op1=*/0}),
270         FailedWithMessage("unable to decode LEB128 at offset 0x00000002: "
271                           "malformed uleb128, extends past end"));
272   };
273 
274   for (uint8_t Inst : {dwarf::DW_CFA_offset_extended, dwarf::DW_CFA_register,
275                        dwarf::DW_CFA_def_cfa, dwarf::DW_CFA_LLVM_def_aspace_cfa,
276                        dwarf::DW_CFA_val_offset})
277     CheckOp_ULEB128_ULEB128(Inst);
278 
279   // A test for an instruction with two operands: ULEB128, SLEB128.
280   auto CheckOp_ULEB128_SLEB128 = [&](uint8_t Inst) {
281     EXPECT_THAT_ERROR(
282         parseCFI(TestCIE, Inst),
283         FailedWithMessage("unable to decode LEB128 at offset 0x00000001: "
284                           "malformed uleb128, extends past end"));
285 
286     EXPECT_THAT_ERROR(
287         parseCFI(TestCIE, {Inst, /*Op1=*/0}),
288         FailedWithMessage("unable to decode LEB128 at offset 0x00000002: "
289                           "malformed sleb128, extends past end"));
290   };
291 
292   for (uint8_t Inst :
293        {dwarf::DW_CFA_offset_extended_sf, dwarf::DW_CFA_def_cfa_sf,
294         dwarf::DW_CFA_LLVM_def_aspace_cfa_sf, dwarf::DW_CFA_val_offset_sf})
295     CheckOp_ULEB128_SLEB128(Inst);
296 
297   // Unable to read a truncated DW_CFA_def_cfa_expression instruction.
298   EXPECT_THAT_ERROR(
299       parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa_expression}),
300       FailedWithMessage("unable to decode LEB128 at offset 0x00000001: "
301                         "malformed uleb128, extends past end"));
302   EXPECT_THAT_ERROR(
303       parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa_expression,
304                          /*expression length=*/0x1}),
305       FailedWithMessage(
306           "unexpected end of data at offset 0x2 while reading [0x2, 0x3)"));
307   // The DW_CFA_def_cfa_expression can contain a zero length expression.
308   EXPECT_THAT_ERROR(parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa_expression,
309                                        /*ExprLen=*/0}),
310                     Succeeded());
311 
312   // A test for an instruction with three operands: ULEB128, expression length
313   // (ULEB128) and expression bytes.
314   auto CheckOp_ULEB128_Expr = [&](uint8_t Inst) {
315     EXPECT_THAT_ERROR(
316         parseCFI(TestCIE, {Inst}),
317         FailedWithMessage("unable to decode LEB128 at offset 0x00000001: "
318                           "malformed uleb128, extends past end"));
319     EXPECT_THAT_ERROR(
320         parseCFI(TestCIE, {Inst, /*Op1=*/0}),
321         FailedWithMessage("unable to decode LEB128 at offset 0x00000002: "
322                           "malformed uleb128, extends past end"));
323     // A zero length expression is fine
324     EXPECT_THAT_ERROR(parseCFI(TestCIE, {Inst,
325                                          /*Op1=*/0, /*ExprLen=*/0}),
326                       Succeeded());
327     EXPECT_THAT_ERROR(
328         parseCFI(TestCIE, {Inst,
329                            /*Op1=*/0, /*ExprLen=*/1}),
330         FailedWithMessage(
331             "unexpected end of data at offset 0x3 while reading [0x3, 0x4)"));
332   };
333 
334   for (uint8_t Inst : {dwarf::DW_CFA_expression, dwarf::DW_CFA_val_expression})
335     CheckOp_ULEB128_Expr(Inst);
336 }
337 
338 void expectDumpResult(const dwarf::UnwindLocation &Loc,
339                       StringRef ExpectedFirstLine) {
340   std::string Output;
341   raw_string_ostream OS(Output);
342   OS << Loc;
343   OS.flush();
344   StringRef FirstLine = StringRef(Output).split('\n').first;
345   EXPECT_EQ(FirstLine, ExpectedFirstLine);
346 }
347 
348 TEST(DWARFDebugFrame, DumpUnwindLocations) {
349   // Test constructing unwind locations and dumping each kind.
350   constexpr int32_t PlusOff = 8;
351   constexpr int32_t MinusOff = -8;
352   constexpr uint8_t RegNum = 12;
353   expectDumpResult(dwarf::UnwindLocation::createUnspecified(), "unspecified");
354   expectDumpResult(dwarf::UnwindLocation::createUndefined(), "undefined");
355   expectDumpResult(dwarf::UnwindLocation::createSame(), "same");
356   expectDumpResult(dwarf::UnwindLocation::createIsCFAPlusOffset(PlusOff),
357                    "CFA+8");
358   expectDumpResult(dwarf::UnwindLocation::createIsCFAPlusOffset(MinusOff),
359                    "CFA-8");
360   expectDumpResult(dwarf::UnwindLocation::createAtCFAPlusOffset(PlusOff),
361                    "[CFA+8]");
362   expectDumpResult(dwarf::UnwindLocation::createAtCFAPlusOffset(MinusOff),
363                    "[CFA-8]");
364 
365   expectDumpResult(
366       dwarf::UnwindLocation::createIsRegisterPlusOffset(RegNum, PlusOff),
367       "reg12+8");
368   expectDumpResult(
369       dwarf::UnwindLocation::createIsRegisterPlusOffset(RegNum, MinusOff),
370       "reg12-8");
371   expectDumpResult(
372       dwarf::UnwindLocation::createAtRegisterPlusOffset(RegNum, PlusOff),
373       "[reg12+8]");
374   expectDumpResult(
375       dwarf::UnwindLocation::createAtRegisterPlusOffset(RegNum, MinusOff),
376       "[reg12-8]");
377   expectDumpResult(dwarf::UnwindLocation::createIsConstant(12), "12");
378   expectDumpResult(dwarf::UnwindLocation::createIsConstant(-32), "-32");
379 }
380 
381 void expectDumpResult(const dwarf::RegisterLocations &Locs,
382                       StringRef ExpectedFirstLine) {
383   std::string Output;
384   raw_string_ostream OS(Output);
385   OS << Locs;
386   OS.flush();
387   StringRef FirstLine = StringRef(Output).split('\n').first;
388   EXPECT_EQ(FirstLine, ExpectedFirstLine);
389 }
390 
391 TEST(DWARFDebugFrame, RegisterLocations) {
392   // Test the functionality of the RegisterLocations class.
393   dwarf::RegisterLocations Locs;
394   expectDumpResult(Locs, "");
395   EXPECT_FALSE(Locs.hasLocations());
396   // Set a register location for reg12 to unspecified and verify it dumps
397   // correctly.
398   Locs.setRegisterLocation(12, dwarf::UnwindLocation::createUnspecified());
399   EXPECT_TRUE(Locs.hasLocations());
400   expectDumpResult(Locs, "reg12=unspecified");
401 
402   // Replace the register location for reg12 to "same" and verify it dumps
403   // correctly after it is modified
404   Locs.setRegisterLocation(12, dwarf::UnwindLocation::createSame());
405   EXPECT_TRUE(Locs.hasLocations());
406   expectDumpResult(Locs, "reg12=same");
407 
408   // Remove the register location for reg12 verify it dumps correctly after it
409   // is removed.
410   Locs.removeRegisterLocation(12);
411   EXPECT_FALSE(Locs.hasLocations());
412   expectDumpResult(Locs, "");
413 
414   // Verify multiple registers added to the list dump correctly.
415   auto Reg12Loc = dwarf::UnwindLocation::createAtCFAPlusOffset(4);
416   auto Reg13Loc = dwarf::UnwindLocation::createAtCFAPlusOffset(8);
417   auto Reg14Loc = dwarf::UnwindLocation::createSame();
418   Locs.setRegisterLocation(12, Reg12Loc);
419   Locs.setRegisterLocation(13, Reg13Loc);
420   Locs.setRegisterLocation(14, Reg14Loc);
421   EXPECT_TRUE(Locs.hasLocations());
422   expectDumpResult(Locs, "reg12=[CFA+4], reg13=[CFA+8], reg14=same");
423 
424   // Verify RegisterLocations::getRegisterLocation() works as expected.
425   Optional<dwarf::UnwindLocation> OptionalLoc;
426   OptionalLoc = Locs.getRegisterLocation(0);
427   EXPECT_FALSE(OptionalLoc.has_value());
428 
429   OptionalLoc = Locs.getRegisterLocation(12);
430   EXPECT_TRUE(OptionalLoc.has_value());
431   EXPECT_EQ(*OptionalLoc, Reg12Loc);
432 
433   OptionalLoc = Locs.getRegisterLocation(13);
434   EXPECT_TRUE(OptionalLoc.has_value());
435   EXPECT_EQ(*OptionalLoc, Reg13Loc);
436 
437   OptionalLoc = Locs.getRegisterLocation(14);
438   EXPECT_TRUE(OptionalLoc.has_value());
439   EXPECT_EQ(*OptionalLoc, Reg14Loc);
440 
441   // Verify registers are correctly removed when multiple exist in the list.
442   Locs.removeRegisterLocation(13);
443   EXPECT_FALSE(Locs.getRegisterLocation(13).has_value());
444   EXPECT_TRUE(Locs.hasLocations());
445   expectDumpResult(Locs, "reg12=[CFA+4], reg14=same");
446   Locs.removeRegisterLocation(14);
447   EXPECT_FALSE(Locs.getRegisterLocation(14).has_value());
448   EXPECT_TRUE(Locs.hasLocations());
449   expectDumpResult(Locs, "reg12=[CFA+4]");
450   Locs.removeRegisterLocation(12);
451   EXPECT_FALSE(Locs.getRegisterLocation(12).has_value());
452   EXPECT_FALSE(Locs.hasLocations());
453   expectDumpResult(Locs, "");
454 }
455 
456 // Test that empty rows are not added to UnwindTable when
457 // dwarf::CIE::CFIs or dwarf::FDE::CFIs is empty.
458 TEST(DWARFDebugFrame, UnwindTableEmptyRows) {
459   dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
460                                  /*Offset=*/0x0,
461                                  /*Length=*/0xff);
462 
463   // Having an empty instructions list is fine.
464   EXPECT_THAT_ERROR(parseCFI(TestCIE, {}), Succeeded());
465   EXPECT_TRUE(TestCIE.cfis().empty());
466 
467   // Verify dwarf::UnwindTable::create() won't result in errors and
468   // and empty rows are not added to CIE UnwindTable.
469   Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestCIE);
470   EXPECT_THAT_ERROR(RowsOrErr.takeError(), Succeeded());
471   const size_t ExpectedNumOfRows = 0;
472   EXPECT_EQ(RowsOrErr->size(), ExpectedNumOfRows);
473 
474   dwarf::FDE TestFDE(/*IsDWARF64=*/true,
475                      /*Offset=*/0x3333abcdabcd,
476                      /*Length=*/0x4444abcdabcd,
477                      /*CIEPointer=*/0x1111abcdabcd,
478                      /*InitialLocation=*/0x1000,
479                      /*AddressRange=*/0x1000,
480                      /*Cie=*/&TestCIE,
481                      /*LSDAAddress=*/None,
482                      /*Arch=*/Triple::x86_64);
483 
484   // Having an empty instructions list is fine.
485   EXPECT_THAT_ERROR(parseCFI(TestFDE, {}), Succeeded());
486   EXPECT_TRUE(TestFDE.cfis().empty());
487 
488   // Verify dwarf::UnwindTable::create() won't result in errors and
489   // and empty rows are not added to FDE UnwindTable.
490   RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
491   EXPECT_THAT_ERROR(RowsOrErr.takeError(), Succeeded());
492   EXPECT_EQ(RowsOrErr->size(), ExpectedNumOfRows);
493 }
494 
495 // Test that empty rows are not added to UnwindTable when dwarf::CIE::CFIs
496 // or dwarf::FDE::CFIs is not empty but has only DW_CFA_nop instructions.
497 TEST(DWARFDebugFrame, UnwindTableEmptyRows_NOPs) {
498   dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
499                                  /*Offset=*/0x0,
500                                  /*Length=*/0xff);
501 
502   // Make a CIE that has only DW_CFA_nop instructions.
503   EXPECT_THAT_ERROR(parseCFI(TestCIE, {dwarf::DW_CFA_nop}), Succeeded());
504   EXPECT_TRUE(!TestCIE.cfis().empty());
505 
506   // Verify dwarf::UnwindTable::create() won't result in errors and
507   // and empty rows are not added to CIE UnwindTable.
508   Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestCIE);
509   EXPECT_THAT_ERROR(RowsOrErr.takeError(), Succeeded());
510   const size_t ExpectedNumOfRows = 0;
511   EXPECT_EQ(RowsOrErr->size(), ExpectedNumOfRows);
512 
513   dwarf::FDE TestFDE(/*IsDWARF64=*/true,
514                      /*Offset=*/0x3333abcdabcd,
515                      /*Length=*/0x4444abcdabcd,
516                      /*CIEPointer=*/0x1111abcdabcd,
517                      /*InitialLocation=*/0x1000,
518                      /*AddressRange=*/0x1000,
519                      /*Cie=*/&TestCIE,
520                      /*LSDAAddress=*/None,
521                      /*Arch=*/Triple::x86_64);
522 
523   // Make an FDE that has only DW_CFA_nop instructions.
524   EXPECT_THAT_ERROR(parseCFI(TestFDE, {dwarf::DW_CFA_nop}), Succeeded());
525   EXPECT_TRUE(!TestFDE.cfis().empty());
526 
527   // Verify dwarf::UnwindTable::create() won't result in errors and
528   // and empty rows are not added to FDE UnwindTable.
529   RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
530   EXPECT_THAT_ERROR(RowsOrErr.takeError(), Succeeded());
531   EXPECT_EQ(RowsOrErr->size(), ExpectedNumOfRows);
532 }
533 
534 TEST(DWARFDebugFrame, UnwindTableErrorNonAscendingFDERows) {
535   dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
536                                  /*Offset=*/0x0,
537                                  /*Length=*/0xff);
538 
539   dwarf::FDE TestFDE(/*IsDWARF64=*/true,
540                      /*Offset=*/0x3333abcdabcd,
541                      /*Length=*/0x4444abcdabcd,
542                      /*CIEPointer=*/0x1111abcdabcd,
543                      /*InitialLocation=*/0x1000,
544                      /*AddressRange=*/0x1000,
545                      /*Cie=*/&TestCIE,
546                      /*LSDAAddress=*/None,
547                      /*Arch=*/Triple::x86_64);
548 
549   // Make a CIE that has a valid CFA definition.
550   constexpr uint8_t Reg = 12;
551   constexpr uint8_t Offset = 32;
552   EXPECT_THAT_ERROR(parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa, Reg, Offset}),
553                     Succeeded());
554 
555   // Make a FDE with DWARF call frame instruction opcodes that have valid
556   // syntax, but will cause an error when we parse them into a UnwindTable.
557   // Here we encode two DW_CFA_set_loc opcodes:
558   //   DW_CFA_set_loc(0x1100)
559   //   DW_CFA_set_loc(0x1000)
560   // These opcodes cause a new row to be appended to the rows in a UnwindTable
561   // and the resulting rows are not in ascending address order and should cause
562   // a state machine error.
563   EXPECT_THAT_ERROR(
564       parseCFI(TestFDE, {dwarf::DW_CFA_set_loc, 0x00, 0x11, 0, 0, 0, 0, 0, 0,
565                          dwarf::DW_CFA_set_loc, 0x00, 0x10, 0, 0, 0, 0, 0, 0}),
566       Succeeded());
567 
568   // Verify we catch state machine error.
569   Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
570   EXPECT_THAT_ERROR(RowsOrErr.takeError(),
571                     FailedWithMessage("DW_CFA_set_loc with adrress 0x1000 which"
572                                       " must be greater than the current row "
573                                       "address 0x1100"));
574 }
575 
576 TEST(DWARFDebugFrame, UnwindTableError_DW_CFA_restore_state) {
577   dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
578                                  /*Offset=*/0x0,
579                                  /*Length=*/0xff);
580 
581   dwarf::FDE TestFDE(/*IsDWARF64=*/true,
582                      /*Offset=*/0x3333abcdabcd,
583                      /*Length=*/0x4444abcdabcd,
584                      /*CIEPointer=*/0x1111abcdabcd,
585                      /*InitialLocation=*/0x1000,
586                      /*AddressRange=*/0x1000,
587                      /*Cie=*/&TestCIE,
588                      /*LSDAAddress=*/None,
589                      /*Arch=*/Triple::x86_64);
590 
591   // Make a CIE that has a valid CFA definition.
592   constexpr uint8_t Reg = 12;
593   constexpr uint8_t Offset = 32;
594   EXPECT_THAT_ERROR(parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa, Reg, Offset}),
595                     Succeeded());
596 
597   // Make a FDE with DWARF call frame instruction opcodes that have valid
598   // syntax, but will cause an error when we parse them into a UnwindTable.
599   // Here we encode a DW_CFA_restore_state opcode that was not preceded by a
600   // DW_CFA_remember_state, and an error should be returned.
601   EXPECT_THAT_ERROR(parseCFI(TestFDE, {dwarf::DW_CFA_restore_state}),
602                     Succeeded());
603 
604   // Verify we catch state machine error.
605   Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
606   EXPECT_THAT_ERROR(RowsOrErr.takeError(),
607                     FailedWithMessage("DW_CFA_restore_state without a matching "
608                                       "previous DW_CFA_remember_state"));
609 }
610 
611 TEST(DWARFDebugFrame, UnwindTableError_DW_CFA_GNU_window_save) {
612   dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
613                                  /*Offset=*/0x0,
614                                  /*Length=*/0xff);
615 
616   dwarf::FDE TestFDE(/*IsDWARF64=*/true,
617                      /*Offset=*/0x3333abcdabcd,
618                      /*Length=*/0x4444abcdabcd,
619                      /*CIEPointer=*/0x1111abcdabcd,
620                      /*InitialLocation=*/0x1000,
621                      /*AddressRange=*/0x1000,
622                      /*Cie=*/&TestCIE,
623                      /*LSDAAddress=*/None,
624                      /*Arch=*/Triple::x86_64);
625 
626   // Make a CIE that has a valid CFA definition.
627   constexpr uint8_t Reg = 12;
628   constexpr uint8_t Offset = 32;
629   EXPECT_THAT_ERROR(parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa, Reg, Offset}),
630                     Succeeded());
631 
632   // Make a FDE with DWARF call frame instruction opcodes that have valid
633   // syntax, but will cause an error when we parse them into a UnwindTable.
634   // Here we encode a DW_CFA_GNU_window_save that is not supported. I have not
635   // found any documentation that describes what this does after some brief
636   // searching.
637   EXPECT_THAT_ERROR(parseCFI(TestFDE, {dwarf::DW_CFA_GNU_window_save}),
638                     Succeeded());
639 
640   // Verify we catch state machine error.
641   Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
642   EXPECT_THAT_ERROR(RowsOrErr.takeError(),
643                     FailedWithMessage("DW_CFA opcode 0x2d is not supported for "
644                                       "architecture x86_64"));
645 }
646 
647 TEST(DWARFDebugFrame, UnwindTableError_DW_CFA_def_cfa_offset) {
648   dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
649                                  /*Offset=*/0x0,
650                                  /*Length=*/0xff);
651 
652   dwarf::FDE TestFDE(/*IsDWARF64=*/true,
653                      /*Offset=*/0x3333abcdabcd,
654                      /*Length=*/0x4444abcdabcd,
655                      /*CIEPointer=*/0x1111abcdabcd,
656                      /*InitialLocation=*/0x1000,
657                      /*AddressRange=*/0x1000,
658                      /*Cie=*/&TestCIE,
659                      /*LSDAAddress=*/None,
660                      /*Arch=*/Triple::x86_64);
661 
662   // Make a CIE that has an invalid CFA definition. We do this so we can try
663   // and use a DW_CFA_def_cfa_register opcode in the FDE and get an appropriate
664   // error back.
665   EXPECT_THAT_ERROR(parseCFI(TestCIE, {}), Succeeded());
666 
667   // Make a FDE with DWARF call frame instruction opcodes that have valid
668   // syntax, but will cause an error when we parse them into a UnwindTable.
669   // Here we encode a DW_CFA_def_cfa_offset with a offset of 16, but our CIE
670   // didn't define the CFA in terms of a register plus offset, so this should
671   // cause an error.
672   EXPECT_THAT_ERROR(parseCFI(TestFDE, {dwarf::DW_CFA_def_cfa_offset, 16}),
673                     Succeeded());
674 
675   // Verify we catch state machine error.
676   Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
677   EXPECT_THAT_ERROR(RowsOrErr.takeError(),
678                     FailedWithMessage("DW_CFA_def_cfa_offset found when CFA "
679                                       "rule was not RegPlusOffset"));
680 }
681 
682 TEST(DWARFDebugFrame, UnwindTableDefCFAOffsetSFCFAError) {
683   dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
684                                  /*Offset=*/0x0,
685                                  /*Length=*/0xff);
686 
687   dwarf::FDE TestFDE(/*IsDWARF64=*/true,
688                      /*Offset=*/0x3333abcdabcd,
689                      /*Length=*/0x4444abcdabcd,
690                      /*CIEPointer=*/0x1111abcdabcd,
691                      /*InitialLocation=*/0x1000,
692                      /*AddressRange=*/0x1000,
693                      /*Cie=*/&TestCIE,
694                      /*LSDAAddress=*/None,
695                      /*Arch=*/Triple::x86_64);
696 
697   // Make a CIE that has an invalid CFA definition. We do this so we can try
698   // and use a DW_CFA_def_cfa_offset_sf opcode in the FDE and get an
699   // appropriate error back.
700   EXPECT_THAT_ERROR(parseCFI(TestCIE, {}), Succeeded());
701 
702   // Make a FDE with DWARF call frame instruction opcodes that have valid
703   // syntax, but will cause an error when we parse them into a UnwindTable.
704   // Here we encode a DW_CFA_def_cfa_offset_sf with a offset of 4, but our CIE
705   // didn't define the CFA in terms of a register plus offset, so this should
706   // cause an error.
707   EXPECT_THAT_ERROR(parseCFI(TestFDE, {dwarf::DW_CFA_def_cfa_offset_sf, 4}),
708                     Succeeded());
709 
710   // Verify we catch state machine error.
711   Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
712   EXPECT_THAT_ERROR(RowsOrErr.takeError(),
713                     FailedWithMessage("DW_CFA_def_cfa_offset_sf found when CFA "
714                                       "rule was not RegPlusOffset"));
715 }
716 
717 TEST(DWARFDebugFrame, UnwindTable_DW_CFA_def_cfa_register) {
718   dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
719                                  /*Offset=*/0x0,
720                                  /*Length=*/0xff);
721 
722   dwarf::FDE TestFDE(/*IsDWARF64=*/true,
723                      /*Offset=*/0x3333abcdabcd,
724                      /*Length=*/0x4444abcdabcd,
725                      /*CIEPointer=*/0x1111abcdabcd,
726                      /*InitialLocation=*/0x1000,
727                      /*AddressRange=*/0x1000,
728                      /*Cie=*/&TestCIE,
729                      /*LSDAAddress=*/None,
730                      /*Arch=*/Triple::x86_64);
731 
732   // Make a CIE that has only defines the CFA register with no offset. Some
733   // architectures do this and we must ensure that we set the CFA value to be
734   // equal to that register with no offset.
735   constexpr uint8_t CFAReg = 12;
736   EXPECT_THAT_ERROR(parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa_register, CFAReg}),
737                     Succeeded());
738 
739   // Make a FDE with DWARF call frame instruction opcodes that have valid
740   // syntax, but will cause an error when we parse them into a UnwindTable.
741   // Here we encode a DW_CFA_def_cfa_register with a register number of 12, but
742   // our CIE didn't define the CFA in terms of a register plus offset, so this
743   // should cause an error.
744   EXPECT_THAT_ERROR(parseCFI(TestFDE, {}), Succeeded());
745 
746   // Verify we catch state machine error.
747   Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
748   EXPECT_THAT_ERROR(RowsOrErr.takeError(), Succeeded());
749   const dwarf::UnwindTable &Rows = RowsOrErr.get();
750   EXPECT_EQ(Rows.size(), 1u);
751   EXPECT_EQ(Rows[0].getAddress(), 0x1000u);
752   EXPECT_EQ(Rows[0].getCFAValue(),
753             dwarf::UnwindLocation::createIsRegisterPlusOffset(CFAReg, 0));
754 }
755 
756 TEST(DWARFDebugFrame, UnwindTableRowPushingOpcodes) {
757   // Test all opcodes that should end up pushing a UnwindRow into a UnwindTable.
758   dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
759                                  /*Offset=*/0x0,
760                                  /*Length=*/0xff);
761 
762   dwarf::FDE TestFDE(/*IsDWARF64=*/true,
763                      /*Offset=*/0x3333abcdabcd,
764                      /*Length=*/0x4444abcdabcd,
765                      /*CIEPointer=*/0x1111abcdabcd,
766                      /*InitialLocation=*/0x1000,
767                      /*AddressRange=*/0x1000,
768                      /*Cie=*/&TestCIE,
769                      /*LSDAAddress=*/None,
770                      /*Arch=*/Triple::x86_64);
771 
772   // Make a CIE that has a valid CFA definition and a single register unwind
773   // rule for register that we will verify is in all of the pushed rows.
774   constexpr uint8_t CFAReg = 12;
775   constexpr uint8_t CFAOffset = 32;
776   constexpr uint8_t Reg = 13;
777   constexpr uint8_t InReg = 14;
778 
779   EXPECT_THAT_ERROR(parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa, CFAReg, CFAOffset,
780                                        dwarf::DW_CFA_register, Reg, InReg}),
781                     Succeeded());
782 
783   // Make a FDE with DWARF call frame instruction opcodes that use all of the
784   // row pushing opcodes. This will verify that all opcodes that should create
785   // a row are correctly working. Each opcode will push a row prior to
786   // advancing the address, and then a row will be automatically pushed at the
787   // end of the parsing, so we should end up with 6 rows starting at address
788   // 0x1000 (from the FDE) and incrementing each one by 4 * CodeAlignmentFactor
789   // from the CIE.
790   EXPECT_THAT_ERROR(parseCFI(TestFDE, {dwarf::DW_CFA_advance_loc | 4,
791                                        dwarf::DW_CFA_advance_loc1,
792                                        4,
793                                        dwarf::DW_CFA_advance_loc2,
794                                        4,
795                                        0,
796                                        dwarf::DW_CFA_advance_loc4,
797                                        4,
798                                        0,
799                                        0,
800                                        0,
801                                        dwarf::DW_CFA_set_loc,
802                                        0x14,
803                                        0x10,
804                                        0,
805                                        0,
806                                        0,
807                                        0,
808                                        0,
809                                        0}),
810                     Succeeded());
811 
812   // Create locations that we expect the UnwindRow objects to contain after
813   // parsing the DWARF call frame instructions.
814   dwarf::RegisterLocations VerifyLocs;
815   VerifyLocs.setRegisterLocation(
816       Reg, dwarf::UnwindLocation::createIsRegisterPlusOffset(InReg, 0));
817 
818   // Verify we catch state machine error.
819   Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
820   ASSERT_THAT_ERROR(RowsOrErr.takeError(), Succeeded());
821   const dwarf::UnwindTable &Rows = RowsOrErr.get();
822   EXPECT_EQ(Rows.size(), 6u);
823   EXPECT_EQ(Rows[0].getAddress(), 0x1000u);
824   EXPECT_EQ(Rows[0].getRegisterLocations().size(), 1u);
825   EXPECT_EQ(Rows[0].getRegisterLocations(), VerifyLocs);
826   EXPECT_EQ(Rows[1].getAddress(), 0x1004u);
827   EXPECT_EQ(Rows[1].getRegisterLocations().size(), 1u);
828   EXPECT_EQ(Rows[1].getRegisterLocations(), VerifyLocs);
829   EXPECT_EQ(Rows[2].getAddress(), 0x1008u);
830   EXPECT_EQ(Rows[2].getRegisterLocations().size(), 1u);
831   EXPECT_EQ(Rows[2].getRegisterLocations(), VerifyLocs);
832   EXPECT_EQ(Rows[3].getAddress(), 0x100cu);
833   EXPECT_EQ(Rows[3].getRegisterLocations().size(), 1u);
834   EXPECT_EQ(Rows[3].getRegisterLocations(), VerifyLocs);
835   EXPECT_EQ(Rows[4].getAddress(), 0x1010u);
836   EXPECT_EQ(Rows[4].getRegisterLocations().size(), 1u);
837   EXPECT_EQ(Rows[4].getRegisterLocations(), VerifyLocs);
838   EXPECT_EQ(Rows[5].getAddress(), 0x1014u);
839   EXPECT_EQ(Rows[5].getRegisterLocations().size(), 1u);
840   EXPECT_EQ(Rows[5].getRegisterLocations(), VerifyLocs);
841 }
842 
843 TEST(DWARFDebugFrame, UnwindTable_DW_CFA_restore) {
844   // Test that DW_CFA_restore works as expected when parsed in the state
845   // machine.
846   dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
847                                  /*Offset=*/0x0,
848                                  /*Length=*/0xff);
849 
850   dwarf::FDE TestFDE(/*IsDWARF64=*/true,
851                      /*Offset=*/0x3333abcdabcd,
852                      /*Length=*/0x4444abcdabcd,
853                      /*CIEPointer=*/0x1111abcdabcd,
854                      /*InitialLocation=*/0x1000,
855                      /*AddressRange=*/0x1000,
856                      /*Cie=*/&TestCIE,
857                      /*LSDAAddress=*/None,
858                      /*Arch=*/Triple::x86_64);
859 
860   // Make a CIE that has a valid CFA definition and a single register unwind
861   // rule for register that we will verify is in all of the pushed rows.
862   constexpr uint8_t CFAReg = 12;
863   constexpr uint8_t CFAOffset = 32;
864   constexpr uint8_t Reg = 13;
865   constexpr uint8_t InReg = 14;
866   constexpr int32_t RegCFAOffset = -8;
867 
868   EXPECT_THAT_ERROR(parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa, CFAReg, CFAOffset,
869                                        dwarf::DW_CFA_register, Reg, InReg}),
870                     Succeeded());
871 
872   // Make a FDE with DWARF call frame instruction opcodes that changes the rule
873   // for register "Reg" to be [CFA-8], then push a row, and then restore the
874   // register unwind rule for "Reg" using DW_CFA_restore. We should end up with
875   // two rows:
876   //   - one with Reg = [CFA-8]
877   //   - one with Reg = InReg
878   EXPECT_THAT_ERROR(parseCFI(TestFDE, {dwarf::DW_CFA_offset | Reg, 1,
879                                        dwarf::DW_CFA_advance_loc | 4,
880                                        dwarf::DW_CFA_restore | Reg}),
881                     Succeeded());
882 
883   // Create locations that we expect the UnwindRow objects to contain after
884   // parsing the DWARF call frame instructions.
885   dwarf::RegisterLocations VerifyLocs1;
886   VerifyLocs1.setRegisterLocation(
887       Reg, dwarf::UnwindLocation::createAtCFAPlusOffset(RegCFAOffset));
888 
889   dwarf::RegisterLocations VerifyLocs2;
890   VerifyLocs2.setRegisterLocation(
891       Reg, dwarf::UnwindLocation::createIsRegisterPlusOffset(InReg, 0));
892 
893   // Verify we catch state machine error.
894   Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
895   EXPECT_THAT_ERROR(RowsOrErr.takeError(), Succeeded());
896   const dwarf::UnwindTable &Rows = RowsOrErr.get();
897   EXPECT_EQ(Rows.size(), 2u);
898   EXPECT_EQ(Rows[0].getAddress(), 0x1000u);
899   EXPECT_EQ(Rows[0].getRegisterLocations().size(), 1u);
900   EXPECT_EQ(Rows[0].getRegisterLocations(), VerifyLocs1);
901   EXPECT_EQ(Rows[1].getAddress(), 0x1004u);
902   EXPECT_EQ(Rows[1].getRegisterLocations().size(), 1u);
903   EXPECT_EQ(Rows[1].getRegisterLocations(), VerifyLocs2);
904 }
905 
906 TEST(DWARFDebugFrame, UnwindTable_DW_CFA_restore_extended) {
907   // Test that DW_CFA_restore works as expected when parsed in the state
908   // machine.
909   dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
910                                  /*Offset=*/0x0,
911                                  /*Length=*/0xff);
912 
913   dwarf::FDE TestFDE(/*IsDWARF64=*/true,
914                      /*Offset=*/0x3333abcdabcd,
915                      /*Length=*/0x4444abcdabcd,
916                      /*CIEPointer=*/0x1111abcdabcd,
917                      /*InitialLocation=*/0x1000,
918                      /*AddressRange=*/0x1000,
919                      /*Cie=*/&TestCIE,
920                      /*LSDAAddress=*/None,
921                      /*Arch=*/Triple::x86_64);
922 
923   // Make a CIE that has a valid CFA definition and a single register unwind
924   // rule for register that we will verify is in all of the pushed rows.
925   constexpr uint8_t CFAReg = 12;
926   constexpr uint8_t CFAOffset = 32;
927   constexpr uint8_t Reg = 13;
928   constexpr uint8_t InReg = 14;
929   constexpr int32_t RegCFAOffset = -8;
930 
931   EXPECT_THAT_ERROR(parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa, CFAReg, CFAOffset,
932                                        dwarf::DW_CFA_register, Reg, InReg}),
933                     Succeeded());
934 
935   // Make a FDE with DWARF call frame instruction opcodes that changes the rule
936   // for register "Reg" to be [CFA-8], then push a row, and then restore the
937   // register unwind rule for "Reg" using DW_CFA_restore_extended. We should
938   // end up with two rows:
939   //   - one with Reg = [CFA-8]
940   //   - one with Reg = InReg
941   EXPECT_THAT_ERROR(parseCFI(TestFDE, {dwarf::DW_CFA_offset | Reg, 1,
942                                        dwarf::DW_CFA_advance_loc | 4,
943                                        dwarf::DW_CFA_restore_extended, Reg}),
944                     Succeeded());
945 
946   // Create locations that we expect the UnwindRow objects to contain after
947   // parsing the DWARF call frame instructions.
948   dwarf::RegisterLocations VerifyLocs1;
949   VerifyLocs1.setRegisterLocation(
950       Reg, dwarf::UnwindLocation::createAtCFAPlusOffset(RegCFAOffset));
951 
952   dwarf::RegisterLocations VerifyLocs2;
953   VerifyLocs2.setRegisterLocation(
954       Reg, dwarf::UnwindLocation::createIsRegisterPlusOffset(InReg, 0));
955 
956   // Verify we catch state machine error.
957   Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
958   EXPECT_THAT_ERROR(RowsOrErr.takeError(), Succeeded());
959   const dwarf::UnwindTable &Rows = RowsOrErr.get();
960   EXPECT_EQ(Rows.size(), 2u);
961   EXPECT_EQ(Rows[0].getAddress(), 0x1000u);
962   EXPECT_EQ(Rows[0].getRegisterLocations().size(), 1u);
963   EXPECT_EQ(Rows[0].getRegisterLocations(), VerifyLocs1);
964   EXPECT_EQ(Rows[1].getAddress(), 0x1004u);
965   EXPECT_EQ(Rows[1].getRegisterLocations().size(), 1u);
966   EXPECT_EQ(Rows[1].getRegisterLocations(), VerifyLocs2);
967 }
968 
969 TEST(DWARFDebugFrame, UnwindTable_DW_CFA_offset) {
970   // Test that DW_CFA_offset, DW_CFA_offset_extended and
971   // DW_CFA_offset_extended_sf work as expected when parsed in the state
972   // machine.
973   dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
974                                  /*Offset=*/0x0,
975                                  /*Length=*/0xff);
976 
977   dwarf::FDE TestFDE(/*IsDWARF64=*/true,
978                      /*Offset=*/0x3333abcdabcd,
979                      /*Length=*/0x4444abcdabcd,
980                      /*CIEPointer=*/0x1111abcdabcd,
981                      /*InitialLocation=*/0x1000,
982                      /*AddressRange=*/0x1000,
983                      /*Cie=*/&TestCIE,
984                      /*LSDAAddress=*/None,
985                      /*Arch=*/Triple::x86_64);
986 
987   // Make a CIE that has a valid CFA definition and a single register unwind
988   // rule for register that we will verify is in all of the pushed rows.
989   EXPECT_THAT_ERROR(parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa, 12, 32}),
990                     Succeeded());
991 
992   // Make a FDE with DWARF call frame instruction opcodes that changes the
993   // unwind rules for the follwing registers:
994   //   Reg1 = [CFA-8]
995   //   Reg2 = [CFA-16]
996   //   Reg3 = [CFA+8]
997   constexpr uint8_t Reg1 = 14;
998   constexpr uint8_t Reg2 = 15;
999   constexpr uint8_t Reg3 = 16;
1000   constexpr uint8_t Neg1SLEB = 0x7f;
1001   EXPECT_THAT_ERROR(
1002       parseCFI(TestFDE,
1003                {dwarf::DW_CFA_offset | Reg1, 1, dwarf::DW_CFA_offset_extended,
1004                 Reg2, 2, dwarf::DW_CFA_offset_extended_sf, Reg3, Neg1SLEB}),
1005       Succeeded());
1006 
1007   // Create locations that we expect the UnwindRow objects to contain after
1008   // parsing the DWARF call frame instructions.
1009   dwarf::RegisterLocations VerifyLocs;
1010   VerifyLocs.setRegisterLocation(
1011       Reg1, dwarf::UnwindLocation::createAtCFAPlusOffset(-8));
1012   VerifyLocs.setRegisterLocation(
1013       Reg2, dwarf::UnwindLocation::createAtCFAPlusOffset(-16));
1014   VerifyLocs.setRegisterLocation(
1015       Reg3, dwarf::UnwindLocation::createAtCFAPlusOffset(8));
1016 
1017   // Verify we catch state machine error.
1018   Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
1019   EXPECT_THAT_ERROR(RowsOrErr.takeError(), Succeeded());
1020   const dwarf::UnwindTable &Rows = RowsOrErr.get();
1021   EXPECT_EQ(Rows.size(), 1u);
1022   EXPECT_EQ(Rows[0].getAddress(), 0x1000u);
1023   EXPECT_EQ(Rows[0].getRegisterLocations(), VerifyLocs);
1024 }
1025 
1026 TEST(DWARFDebugFrame, UnwindTable_DW_CFA_val_offset) {
1027   // Test that DW_CFA_val_offset and DW_CFA_val_offset_sf work as expected when
1028   // parsed in the state machine.
1029   dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
1030                                  /*Offset=*/0x0,
1031                                  /*Length=*/0xff);
1032 
1033   dwarf::FDE TestFDE(/*IsDWARF64=*/true,
1034                      /*Offset=*/0x3333abcdabcd,
1035                      /*Length=*/0x4444abcdabcd,
1036                      /*CIEPointer=*/0x1111abcdabcd,
1037                      /*InitialLocation=*/0x1000,
1038                      /*AddressRange=*/0x1000,
1039                      /*Cie=*/&TestCIE,
1040                      /*LSDAAddress=*/None,
1041                      /*Arch=*/Triple::x86_64);
1042 
1043   // Make a CIE that has a valid CFA definition and a single register unwind
1044   // rule for register that we will verify is in all of the pushed rows.
1045   EXPECT_THAT_ERROR(parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa, 12, 32}),
1046                     Succeeded());
1047 
1048   // Make a FDE with DWARF call frame instruction opcodes that changes the
1049   // unwind rules for the follwing registers:
1050   //   Reg1 = [CFA-8]
1051   //   Reg2 = [CFA-16]
1052   //   Reg3 = [CFA+8]
1053   constexpr uint8_t Reg1 = 14;
1054   constexpr uint8_t Reg2 = 15;
1055   constexpr uint8_t Neg1SLEB = 0x7f;
1056   EXPECT_THAT_ERROR(
1057       parseCFI(TestFDE, {dwarf::DW_CFA_val_offset, Reg1, 1,
1058                          dwarf::DW_CFA_val_offset_sf, Reg2, Neg1SLEB}),
1059       Succeeded());
1060 
1061   // Create locations that we expect the UnwindRow objects to contain after
1062   // parsing the DWARF call frame instructions.
1063   dwarf::RegisterLocations VerifyLocs;
1064   VerifyLocs.setRegisterLocation(
1065       Reg1, dwarf::UnwindLocation::createIsCFAPlusOffset(-8));
1066   VerifyLocs.setRegisterLocation(
1067       Reg2, dwarf::UnwindLocation::createIsCFAPlusOffset(8));
1068 
1069   // Verify we catch state machine error.
1070   Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
1071   EXPECT_THAT_ERROR(RowsOrErr.takeError(), Succeeded());
1072   const dwarf::UnwindTable &Rows = RowsOrErr.get();
1073   EXPECT_EQ(Rows.size(), 1u);
1074   EXPECT_EQ(Rows[0].getAddress(), 0x1000u);
1075   EXPECT_EQ(Rows[0].getRegisterLocations(), VerifyLocs);
1076 }
1077 
1078 TEST(DWARFDebugFrame, UnwindTable_DW_CFA_nop) {
1079   // Test that DW_CFA_nop works as expected when parsed in the state machine.
1080   dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
1081                                  /*Offset=*/0x0,
1082                                  /*Length=*/0xff);
1083 
1084   dwarf::FDE TestFDE(/*IsDWARF64=*/true,
1085                      /*Offset=*/0x3333abcdabcd,
1086                      /*Length=*/0x4444abcdabcd,
1087                      /*CIEPointer=*/0x1111abcdabcd,
1088                      /*InitialLocation=*/0x1000,
1089                      /*AddressRange=*/0x1000,
1090                      /*Cie=*/&TestCIE,
1091                      /*LSDAAddress=*/None,
1092                      /*Arch=*/Triple::x86_64);
1093 
1094   // Make a CIE that has a valid CFA definition and a single register unwind
1095   // rule for register that we will verify is in all of the pushed rows.
1096   EXPECT_THAT_ERROR(parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa, 12, 32}),
1097                     Succeeded());
1098 
1099   // Make a FDE with DWARF call frame instruction opcodes that changes the
1100   // unwind rules for the follwing registers:
1101   //   Reg1 = [CFA-8]
1102   // The opcodes for setting Reg1 are preceded by a DW_CFA_nop.
1103   constexpr uint8_t Reg1 = 14;
1104   EXPECT_THAT_ERROR(
1105       parseCFI(TestFDE, {dwarf::DW_CFA_nop, dwarf::DW_CFA_offset | Reg1, 1}),
1106       Succeeded());
1107 
1108   // Create locations that we expect the UnwindRow objects to contain after
1109   // parsing the DWARF call frame instructions.
1110   dwarf::RegisterLocations VerifyLocs;
1111   VerifyLocs.setRegisterLocation(
1112       Reg1, dwarf::UnwindLocation::createAtCFAPlusOffset(-8));
1113 
1114   // Verify we catch state machine error.
1115   Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
1116   EXPECT_THAT_ERROR(RowsOrErr.takeError(), Succeeded());
1117   const dwarf::UnwindTable &Rows = RowsOrErr.get();
1118   EXPECT_EQ(Rows.size(), 1u);
1119   EXPECT_EQ(Rows[0].getAddress(), 0x1000u);
1120   EXPECT_EQ(Rows[0].getRegisterLocations(), VerifyLocs);
1121 }
1122 
1123 TEST(DWARFDebugFrame, UnwindTable_DW_CFA_remember_state) {
1124   // Test that DW_CFA_remember_state and DW_CFA_restore_state work as expected
1125   // when parsed in the state machine.
1126   dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
1127                                  /*Offset=*/0x0,
1128                                  /*Length=*/0xff);
1129 
1130   dwarf::FDE TestFDE(/*IsDWARF64=*/true,
1131                      /*Offset=*/0x3333abcdabcd,
1132                      /*Length=*/0x4444abcdabcd,
1133                      /*CIEPointer=*/0x1111abcdabcd,
1134                      /*InitialLocation=*/0x1000,
1135                      /*AddressRange=*/0x1000,
1136                      /*Cie=*/&TestCIE,
1137                      /*LSDAAddress=*/None,
1138                      /*Arch=*/Triple::x86_64);
1139 
1140   // Make a CIE that has a valid CFA definition and a single register unwind
1141   // rule for register that we will verify is in all of the pushed rows.
1142   EXPECT_THAT_ERROR(parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa, 12, 32}),
1143                     Succeeded());
1144 
1145   // Make a FDE with DWARF call frame instruction opcodes that encodes the
1146   // follwing rows:
1147   // 0x1000: CFA=reg12+32: Reg1=[CFA-8]
1148   // 0x1004: CFA=reg12+32: Reg1=[CFA-8] Reg2=[CFA-16]
1149   // 0x1008: CFA=reg12+32: Reg1=[CFA-8] Reg2=[CFA-16] Reg3=[CFA-24]
1150   // 0x100C: CFA=reg12+32: Reg1=[CFA-8] Reg2=[CFA-16]
1151   // 0x1010: CFA=reg12+32: Reg1=[CFA-8]
1152   // This state machine will:
1153   //  - set Reg1 location
1154   //  - push a row (from DW_CFA_advance_loc)
1155   //  - remember the state
1156   //  - set Reg2 location
1157   //  - push a row (from DW_CFA_advance_loc)
1158   //  - remember the state
1159   //  - set Reg3 location
1160   //  - push a row (from DW_CFA_advance_loc)
1161   //  - remember the state where Reg1 and Reg2 were set
1162   //  - push a row (from DW_CFA_advance_loc)
1163   //  - remember the state where only Reg1 was set
1164   //  - push a row (automatically at the end of instruction parsing)
1165   // Then we verify that all registers are correct in all generated rows.
1166   constexpr uint8_t Reg1 = 14;
1167   constexpr uint8_t Reg2 = 15;
1168   constexpr uint8_t Reg3 = 16;
1169   EXPECT_THAT_ERROR(
1170       parseCFI(TestFDE,
1171                {dwarf::DW_CFA_offset | Reg1, 1, dwarf::DW_CFA_advance_loc | 4,
1172                 dwarf::DW_CFA_remember_state, dwarf::DW_CFA_offset | Reg2, 2,
1173                 dwarf::DW_CFA_advance_loc | 4, dwarf::DW_CFA_remember_state,
1174                 dwarf::DW_CFA_offset | Reg3, 3, dwarf::DW_CFA_advance_loc | 4,
1175                 dwarf::DW_CFA_restore_state, dwarf::DW_CFA_advance_loc | 4,
1176                 dwarf::DW_CFA_restore_state}),
1177       Succeeded());
1178 
1179   // Create locations that we expect the UnwindRow objects to contain after
1180   // parsing the DWARF call frame instructions.
1181   dwarf::RegisterLocations VerifyLocs1;
1182   VerifyLocs1.setRegisterLocation(
1183       Reg1, dwarf::UnwindLocation::createAtCFAPlusOffset(-8));
1184 
1185   dwarf::RegisterLocations VerifyLocs2;
1186   VerifyLocs2.setRegisterLocation(
1187       Reg1, dwarf::UnwindLocation::createAtCFAPlusOffset(-8));
1188   VerifyLocs2.setRegisterLocation(
1189       Reg2, dwarf::UnwindLocation::createAtCFAPlusOffset(-16));
1190 
1191   dwarf::RegisterLocations VerifyLocs3;
1192   VerifyLocs3.setRegisterLocation(
1193       Reg1, dwarf::UnwindLocation::createAtCFAPlusOffset(-8));
1194   VerifyLocs3.setRegisterLocation(
1195       Reg2, dwarf::UnwindLocation::createAtCFAPlusOffset(-16));
1196   VerifyLocs3.setRegisterLocation(
1197       Reg3, dwarf::UnwindLocation::createAtCFAPlusOffset(-24));
1198 
1199   // Verify we catch state machine error.
1200   Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
1201   EXPECT_THAT_ERROR(RowsOrErr.takeError(), Succeeded());
1202   const dwarf::UnwindTable &Rows = RowsOrErr.get();
1203   EXPECT_EQ(Rows.size(), 5u);
1204   EXPECT_EQ(Rows[0].getAddress(), 0x1000u);
1205   EXPECT_EQ(Rows[0].getRegisterLocations(), VerifyLocs1);
1206 
1207   EXPECT_EQ(Rows[1].getAddress(), 0x1004u);
1208   EXPECT_EQ(Rows[1].getRegisterLocations(), VerifyLocs2);
1209 
1210   EXPECT_EQ(Rows[2].getAddress(), 0x1008u);
1211   EXPECT_EQ(Rows[2].getRegisterLocations(), VerifyLocs3);
1212 
1213   EXPECT_EQ(Rows[3].getAddress(), 0x100Cu);
1214   EXPECT_EQ(Rows[3].getRegisterLocations(), VerifyLocs2);
1215 
1216   EXPECT_EQ(Rows[4].getAddress(), 0x1010u);
1217   EXPECT_EQ(Rows[4].getRegisterLocations(), VerifyLocs1);
1218 }
1219 
1220 TEST(DWARFDebugFrame, UnwindTable_DW_CFA_undefined) {
1221   // Test that DW_CFA_undefined works as expected when parsed in the state
1222   // machine.
1223   dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
1224                                  /*Offset=*/0x0,
1225                                  /*Length=*/0xff);
1226 
1227   dwarf::FDE TestFDE(/*IsDWARF64=*/true,
1228                      /*Offset=*/0x3333abcdabcd,
1229                      /*Length=*/0x4444abcdabcd,
1230                      /*CIEPointer=*/0x1111abcdabcd,
1231                      /*InitialLocation=*/0x1000,
1232                      /*AddressRange=*/0x1000,
1233                      /*Cie=*/&TestCIE,
1234                      /*LSDAAddress=*/None,
1235                      /*Arch=*/Triple::x86_64);
1236 
1237   // Make a CIE that has a valid CFA definition and a single register unwind
1238   // rule for register that we will verify is in all of the pushed rows.
1239   EXPECT_THAT_ERROR(parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa, 12, 32}),
1240                     Succeeded());
1241 
1242   // Make a FDE with DWARF call frame instruction opcodes that encodes the
1243   // follwing rows:
1244   // 0x1000: CFA=reg12+32: Reg1=undefined
1245   // Then we verify that all registers are correct in all generated rows.
1246   constexpr uint8_t Reg1 = 14;
1247   EXPECT_THAT_ERROR(parseCFI(TestFDE, {dwarf::DW_CFA_undefined, Reg1}),
1248                     Succeeded());
1249 
1250   // Create locations that we expect the UnwindRow objects to contain after
1251   // parsing the DWARF call frame instructions.
1252   dwarf::RegisterLocations VerifyLocs;
1253   VerifyLocs.setRegisterLocation(Reg1,
1254                                  dwarf::UnwindLocation::createUndefined());
1255 
1256   // Verify we catch state machine error.
1257   Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
1258   EXPECT_THAT_ERROR(RowsOrErr.takeError(), Succeeded());
1259   const dwarf::UnwindTable &Rows = RowsOrErr.get();
1260   EXPECT_EQ(Rows.size(), 1u);
1261   EXPECT_EQ(Rows[0].getAddress(), 0x1000u);
1262   EXPECT_EQ(Rows[0].getRegisterLocations(), VerifyLocs);
1263 }
1264 
1265 TEST(DWARFDebugFrame, UnwindTable_DW_CFA_same_value) {
1266   // Test that DW_CFA_same_value works as expected when parsed in the state
1267   // machine.
1268   dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
1269                                  /*Offset=*/0x0,
1270                                  /*Length=*/0xff);
1271 
1272   dwarf::FDE TestFDE(/*IsDWARF64=*/true,
1273                      /*Offset=*/0x3333abcdabcd,
1274                      /*Length=*/0x4444abcdabcd,
1275                      /*CIEPointer=*/0x1111abcdabcd,
1276                      /*InitialLocation=*/0x1000,
1277                      /*AddressRange=*/0x1000,
1278                      /*Cie=*/&TestCIE,
1279                      /*LSDAAddress=*/None,
1280                      /*Arch=*/Triple::x86_64);
1281 
1282   // Make a CIE that has a valid CFA definition and a single register unwind
1283   // rule for register that we will verify is in all of the pushed rows.
1284   EXPECT_THAT_ERROR(parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa, 12, 32}),
1285                     Succeeded());
1286 
1287   // Make a FDE with DWARF call frame instruction opcodes that encodes the
1288   // follwing rows:
1289   // 0x1000: CFA=reg12+32: Reg1=same
1290   // Then we verify that all registers are correct in all generated rows.
1291   constexpr uint8_t Reg1 = 14;
1292   EXPECT_THAT_ERROR(parseCFI(TestFDE, {dwarf::DW_CFA_same_value, Reg1}),
1293                     Succeeded());
1294 
1295   // Create locations that we expect the UnwindRow objects to contain after
1296   // parsing the DWARF call frame instructions.
1297   dwarf::RegisterLocations VerifyLocs;
1298   VerifyLocs.setRegisterLocation(Reg1, dwarf::UnwindLocation::createSame());
1299 
1300   // Verify we catch state machine error.
1301   Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
1302   EXPECT_THAT_ERROR(RowsOrErr.takeError(), Succeeded());
1303   const dwarf::UnwindTable &Rows = RowsOrErr.get();
1304   EXPECT_EQ(Rows.size(), 1u);
1305   EXPECT_EQ(Rows[0].getAddress(), 0x1000u);
1306   EXPECT_EQ(Rows[0].getRegisterLocations(), VerifyLocs);
1307 }
1308 
1309 TEST(DWARFDebugFrame, UnwindTable_DW_CFA_register) {
1310   // Test that DW_CFA_register works as expected when parsed in the state
1311   // machine.
1312   dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
1313                                  /*Offset=*/0x0,
1314                                  /*Length=*/0xff);
1315 
1316   dwarf::FDE TestFDE(/*IsDWARF64=*/true,
1317                      /*Offset=*/0x3333abcdabcd,
1318                      /*Length=*/0x4444abcdabcd,
1319                      /*CIEPointer=*/0x1111abcdabcd,
1320                      /*InitialLocation=*/0x1000,
1321                      /*AddressRange=*/0x1000,
1322                      /*Cie=*/&TestCIE,
1323                      /*LSDAAddress=*/None,
1324                      /*Arch=*/Triple::x86_64);
1325 
1326   // Make a CIE that has a valid CFA definition and a single register unwind
1327   // rule for register that we will verify is in all of the pushed rows.
1328   EXPECT_THAT_ERROR(parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa, 12, 32}),
1329                     Succeeded());
1330 
1331   // Make a FDE with DWARF call frame instruction opcodes that encodes the
1332   // follwing rows:
1333   // 0x1000: CFA=reg12+32: Reg1=same
1334   // Then we verify that all registers are correct in all generated rows.
1335   constexpr uint8_t Reg = 13;
1336   constexpr uint8_t InReg = 14;
1337   EXPECT_THAT_ERROR(parseCFI(TestFDE, {dwarf::DW_CFA_register, Reg, InReg}),
1338                     Succeeded());
1339 
1340   // Create locations that we expect the UnwindRow objects to contain after
1341   // parsing the DWARF call frame instructions.
1342   dwarf::RegisterLocations VerifyLocs;
1343   VerifyLocs.setRegisterLocation(
1344       Reg, dwarf::UnwindLocation::createIsRegisterPlusOffset(InReg, 0));
1345 
1346   // Verify we catch state machine error.
1347   Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
1348   EXPECT_THAT_ERROR(RowsOrErr.takeError(), Succeeded());
1349   const dwarf::UnwindTable &Rows = RowsOrErr.get();
1350   EXPECT_EQ(Rows.size(), 1u);
1351   EXPECT_EQ(Rows[0].getAddress(), 0x1000u);
1352   EXPECT_EQ(Rows[0].getRegisterLocations(), VerifyLocs);
1353 }
1354 
1355 TEST(DWARFDebugFrame, UnwindTable_DW_CFA_expression) {
1356   // Test that DW_CFA_expression works as expected when parsed in the state
1357   // machine.
1358   dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
1359                                  /*Offset=*/0x0,
1360                                  /*Length=*/0xff);
1361 
1362   dwarf::FDE TestFDE(/*IsDWARF64=*/true,
1363                      /*Offset=*/0x3333abcdabcd,
1364                      /*Length=*/0x4444abcdabcd,
1365                      /*CIEPointer=*/0x1111abcdabcd,
1366                      /*InitialLocation=*/0x1000,
1367                      /*AddressRange=*/0x1000,
1368                      /*Cie=*/&TestCIE,
1369                      /*LSDAAddress=*/None,
1370                      /*Arch=*/Triple::x86_64);
1371 
1372   // Make a CIE that has a valid CFA definition and a single register unwind
1373   // rule for register that we will verify is in all of the pushed rows.
1374   EXPECT_THAT_ERROR(parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa, 12, 32}),
1375                     Succeeded());
1376 
1377   // Make a FDE with DWARF call frame instruction opcodes that encodes the
1378   // follwing rows:
1379   // 0x1000: CFA=reg12+32: Reg1=DWARFExpr(DW_OP_reg12)
1380   // Then we verify that all registers are correct in all generated rows.
1381   constexpr uint8_t Reg = 13;
1382   constexpr uint8_t AddrSize = 8;
1383   std::vector<uint8_t> CFIBytes = {dwarf::DW_CFA_expression, Reg, 1,
1384                                    dwarf::DW_OP_reg12};
1385 
1386   EXPECT_THAT_ERROR(parseCFI(TestFDE, CFIBytes), Succeeded());
1387 
1388   // Create locations that we expect the UnwindRow objects to contain after
1389   // parsing the DWARF call frame instructions.
1390   dwarf::RegisterLocations VerifyLocs;
1391 
1392   std::vector<uint8_t> ExprBytes = {dwarf::DW_OP_reg12};
1393   DataExtractor ExprData(ExprBytes, true, AddrSize);
1394   DWARFExpression Expr(ExprData, AddrSize);
1395   VerifyLocs.setRegisterLocation(
1396       Reg, dwarf::UnwindLocation::createAtDWARFExpression(Expr));
1397 
1398   // Verify we catch state machine error.
1399   Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
1400   EXPECT_THAT_ERROR(RowsOrErr.takeError(), Succeeded());
1401   const dwarf::UnwindTable &Rows = RowsOrErr.get();
1402   EXPECT_EQ(Rows.size(), 1u);
1403   EXPECT_EQ(Rows[0].getAddress(), 0x1000u);
1404   EXPECT_EQ(Rows[0].getRegisterLocations(), VerifyLocs);
1405 }
1406 
1407 TEST(DWARFDebugFrame, UnwindTable_DW_CFA_val_expression) {
1408   // Test that DW_CFA_val_expression works as expected when parsed in the state
1409   // machine.
1410   dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
1411                                  /*Offset=*/0x0,
1412                                  /*Length=*/0xff);
1413 
1414   dwarf::FDE TestFDE(/*IsDWARF64=*/true,
1415                      /*Offset=*/0x3333abcdabcd,
1416                      /*Length=*/0x4444abcdabcd,
1417                      /*CIEPointer=*/0x1111abcdabcd,
1418                      /*InitialLocation=*/0x1000,
1419                      /*AddressRange=*/0x1000,
1420                      /*Cie=*/&TestCIE,
1421                      /*LSDAAddress=*/None,
1422                      /*Arch=*/Triple::x86_64);
1423 
1424   // Make a CIE that has a valid CFA definition and a single register unwind
1425   // rule for register that we will verify is in all of the pushed rows.
1426   EXPECT_THAT_ERROR(parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa, 12, 32}),
1427                     Succeeded());
1428 
1429   // Make a FDE with DWARF call frame instruction opcodes that encodes the
1430   // follwing rows:
1431   // 0x1000: CFA=reg12+32: Reg1=DWARFExpr(DW_OP_reg12)
1432   // Then we verify that all registers are correct in all generated rows.
1433   constexpr uint8_t Reg = 13;
1434   constexpr uint8_t AddrSize = 8;
1435   std::vector<uint8_t> CFIBytes = {dwarf::DW_CFA_val_expression, Reg, 1,
1436                                    dwarf::DW_OP_reg12};
1437 
1438   EXPECT_THAT_ERROR(parseCFI(TestFDE, CFIBytes), Succeeded());
1439 
1440   // Create locations that we expect the UnwindRow objects to contain after
1441   // parsing the DWARF call frame instructions.
1442   dwarf::RegisterLocations VerifyLocs;
1443 
1444   std::vector<uint8_t> ExprBytes = {dwarf::DW_OP_reg12};
1445   DataExtractor ExprData(ExprBytes, true, AddrSize);
1446   DWARFExpression Expr(ExprData, AddrSize);
1447   VerifyLocs.setRegisterLocation(
1448       Reg, dwarf::UnwindLocation::createIsDWARFExpression(Expr));
1449 
1450   // Verify we catch state machine error.
1451   Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
1452   EXPECT_THAT_ERROR(RowsOrErr.takeError(), Succeeded());
1453   const dwarf::UnwindTable &Rows = RowsOrErr.get();
1454   EXPECT_EQ(Rows.size(), 1u);
1455   EXPECT_EQ(Rows[0].getAddress(), 0x1000u);
1456   EXPECT_EQ(Rows[0].getRegisterLocations(), VerifyLocs);
1457 }
1458 
1459 TEST(DWARFDebugFrame, UnwindTable_DW_CFA_def_cfa) {
1460   // Test that DW_CFA_def_cfa, DW_CFA_def_cfa_sf, DW_CFA_def_cfa_register,
1461   // DW_CFA_def_cfa_offset, and DW_CFA_def_cfa_offset_sf works as expected when
1462   // parsed in the state machine.
1463   dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
1464                                  /*Offset=*/0x0,
1465                                  /*Length=*/0xff);
1466 
1467   dwarf::FDE TestFDE(/*IsDWARF64=*/true,
1468                      /*Offset=*/0x3333abcdabcd,
1469                      /*Length=*/0x4444abcdabcd,
1470                      /*CIEPointer=*/0x1111abcdabcd,
1471                      /*InitialLocation=*/0x1000,
1472                      /*AddressRange=*/0x1000,
1473                      /*Cie=*/&TestCIE,
1474                      /*LSDAAddress=*/None,
1475                      /*Arch=*/Triple::x86_64);
1476 
1477   // Make a CIE that has a valid CFA definition and a single register unwind
1478   // rule for register that we will verify is in all of the pushed rows.
1479   constexpr uint8_t CFAReg1 = 12;
1480   constexpr uint8_t CFAOff1 = 32;
1481   constexpr uint8_t CFAReg2 = 13;
1482   constexpr uint8_t CFAOff2 = 48;
1483   constexpr uint8_t Reg = 13;
1484   constexpr uint8_t InReg = 14;
1485 
1486   EXPECT_THAT_ERROR(parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa, CFAReg1, CFAOff1,
1487                                        dwarf::DW_CFA_register, Reg, InReg}),
1488                     Succeeded());
1489 
1490   // Make a FDE with DWARF call frame instruction opcodes that use all of the
1491   // DW_CFA_def_cfa* opcodes. This will verify that all opcodes that should
1492   // create a row are correctly working.
1493   EXPECT_THAT_ERROR(
1494       parseCFI(
1495           TestFDE,
1496           {
1497               dwarf::DW_CFA_advance_loc | 4, dwarf::DW_CFA_def_cfa_register,
1498               CFAReg2, dwarf::DW_CFA_advance_loc | 4,
1499               dwarf::DW_CFA_def_cfa_offset, CFAOff2,
1500               dwarf::DW_CFA_advance_loc | 4, dwarf::DW_CFA_def_cfa_offset_sf,
1501               0x7c, // -4 SLEB to make offset = 32 (CFAOff1)
1502               dwarf::DW_CFA_advance_loc | 4, dwarf::DW_CFA_def_cfa_sf, CFAReg1,
1503               0x7a, // -6 SLEB to make CFA offset 48 (CFAOff2)
1504           }),
1505       Succeeded());
1506 
1507   // Create locations that we expect the UnwindRow objects to contain after
1508   // parsing the DWARF call frame instructions.
1509   dwarf::RegisterLocations VerifyLocs;
1510   VerifyLocs.setRegisterLocation(
1511       Reg, dwarf::UnwindLocation::createIsRegisterPlusOffset(InReg, 0));
1512 
1513   // Verify we catch state machine error.
1514   Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
1515   EXPECT_THAT_ERROR(RowsOrErr.takeError(), Succeeded());
1516   const dwarf::UnwindTable &Rows = RowsOrErr.get();
1517   EXPECT_EQ(Rows.size(), 5u);
1518   EXPECT_EQ(Rows[0].getAddress(), 0x1000u);
1519   EXPECT_EQ(
1520       Rows[0].getCFAValue(),
1521       dwarf::UnwindLocation::createIsRegisterPlusOffset(CFAReg1, CFAOff1));
1522   EXPECT_EQ(Rows[0].getRegisterLocations().size(), 1u);
1523   EXPECT_EQ(Rows[0].getRegisterLocations(), VerifyLocs);
1524 
1525   EXPECT_EQ(Rows[1].getAddress(), 0x1004u);
1526   EXPECT_EQ(
1527       Rows[1].getCFAValue(),
1528       dwarf::UnwindLocation::createIsRegisterPlusOffset(CFAReg2, CFAOff1));
1529   EXPECT_EQ(Rows[1].getRegisterLocations().size(), 1u);
1530   EXPECT_EQ(Rows[1].getRegisterLocations(), VerifyLocs);
1531 
1532   EXPECT_EQ(Rows[2].getAddress(), 0x1008u);
1533   EXPECT_EQ(
1534       Rows[2].getCFAValue(),
1535       dwarf::UnwindLocation::createIsRegisterPlusOffset(CFAReg2, CFAOff2));
1536   EXPECT_EQ(Rows[2].getRegisterLocations().size(), 1u);
1537   EXPECT_EQ(Rows[2].getRegisterLocations(), VerifyLocs);
1538 
1539   EXPECT_EQ(Rows[3].getAddress(), 0x100cu);
1540   EXPECT_EQ(
1541       Rows[3].getCFAValue(),
1542       dwarf::UnwindLocation::createIsRegisterPlusOffset(CFAReg2, CFAOff1));
1543   EXPECT_EQ(Rows[3].getRegisterLocations().size(), 1u);
1544   EXPECT_EQ(Rows[3].getRegisterLocations(), VerifyLocs);
1545 
1546   EXPECT_EQ(Rows[4].getAddress(), 0x1010u);
1547   EXPECT_EQ(
1548       Rows[4].getCFAValue(),
1549       dwarf::UnwindLocation::createIsRegisterPlusOffset(CFAReg1, CFAOff2));
1550   EXPECT_EQ(Rows[4].getRegisterLocations().size(), 1u);
1551   EXPECT_EQ(Rows[4].getRegisterLocations(), VerifyLocs);
1552 }
1553 
1554 TEST(DWARFDebugFrame, UnwindTable_DW_CFA_LLVM_def_aspace_cfa) {
1555   // Test that DW_CFA_LLVM_def_aspace_cfa, DW_CFA_LLVM_def_aspace_cfa_sf,
1556   // DW_CFA_def_cfa_register, DW_CFA_def_cfa_offset, and
1557   // DW_CFA_def_cfa_offset_sf works as expected when parsed in the state
1558   // machine.
1559   dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
1560                                  /*Offset=*/0x0,
1561                                  /*Length=*/0xff);
1562 
1563   dwarf::FDE TestFDE(/*IsDWARF64=*/true,
1564                      /*Offset=*/0x3333abcdabcd,
1565                      /*Length=*/0x4444abcdabcd,
1566                      /*CIEPointer=*/0x1111abcdabcd,
1567                      /*InitialLocation=*/0x1000,
1568                      /*AddressRange=*/0x1000,
1569                      /*Cie=*/&TestCIE,
1570                      /*LSDAAddress=*/None,
1571                      /*Arch=*/Triple::x86_64);
1572 
1573   // Make a CIE that has a valid CFA definition and a single register unwind
1574   // rule for register that we will verify is in all of the pushed rows.
1575   constexpr uint8_t CFAReg1 = 12;
1576   constexpr uint8_t CFAOff1 = 32;
1577   constexpr uint8_t CFAReg2 = 13;
1578   constexpr uint8_t CFAOff2 = 48;
1579   constexpr uint8_t Reg = 13;
1580   constexpr uint8_t InReg = 14;
1581   constexpr uint8_t AddrSpace = 2;
1582 
1583   EXPECT_THAT_ERROR(
1584       parseCFI(TestCIE, {dwarf::DW_CFA_LLVM_def_aspace_cfa, CFAReg1, CFAOff1,
1585                          AddrSpace, dwarf::DW_CFA_register, Reg, InReg}),
1586       Succeeded());
1587 
1588   // Make a FDE with DWARF call frame instruction opcodes that use all of the
1589   // DW_CFA_def_cfa* opcodes. This will verify that all opcodes that should
1590   // create a row are correctly working.
1591   EXPECT_THAT_ERROR(
1592       parseCFI(
1593           TestFDE,
1594           {
1595               dwarf::DW_CFA_advance_loc | 4, dwarf::DW_CFA_def_cfa_register,
1596               CFAReg2, dwarf::DW_CFA_advance_loc | 4,
1597               dwarf::DW_CFA_def_cfa_offset, CFAOff2,
1598               dwarf::DW_CFA_advance_loc | 4, dwarf::DW_CFA_def_cfa_offset_sf,
1599               0x7c, // -4 SLEB to make offset = 32 (CFAOff1)
1600               dwarf::DW_CFA_advance_loc | 4, dwarf::DW_CFA_def_cfa_sf, CFAReg1,
1601               0x7a, // -6 SLEB to make CFA offset 48 (CFAOff2)
1602           }),
1603       Succeeded());
1604 
1605   // Create locations that we expect the UnwindRow objects to contain after
1606   // parsing the DWARF call frame instructions.
1607   dwarf::RegisterLocations VerifyLocs;
1608   VerifyLocs.setRegisterLocation(
1609       Reg, dwarf::UnwindLocation::createIsRegisterPlusOffset(InReg, 0));
1610 
1611   // Verify we catch state machine error.
1612   Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
1613   EXPECT_THAT_ERROR(RowsOrErr.takeError(), Succeeded());
1614   const dwarf::UnwindTable &Rows = RowsOrErr.get();
1615   EXPECT_EQ(Rows.size(), 5u);
1616   EXPECT_EQ(Rows[0].getAddress(), 0x1000u);
1617   EXPECT_EQ(Rows[0].getCFAValue(),
1618             dwarf::UnwindLocation::createIsRegisterPlusOffset(CFAReg1, CFAOff1,
1619                                                               AddrSpace));
1620   EXPECT_EQ(Rows[0].getRegisterLocations().size(), 1u);
1621   EXPECT_EQ(Rows[0].getRegisterLocations(), VerifyLocs);
1622 
1623   EXPECT_EQ(Rows[1].getAddress(), 0x1004u);
1624   EXPECT_EQ(Rows[1].getCFAValue(),
1625             dwarf::UnwindLocation::createIsRegisterPlusOffset(CFAReg2, CFAOff1,
1626                                                               AddrSpace));
1627   EXPECT_EQ(Rows[1].getRegisterLocations().size(), 1u);
1628   EXPECT_EQ(Rows[1].getRegisterLocations(), VerifyLocs);
1629 
1630   EXPECT_EQ(Rows[2].getAddress(), 0x1008u);
1631   EXPECT_EQ(Rows[2].getCFAValue(),
1632             dwarf::UnwindLocation::createIsRegisterPlusOffset(CFAReg2, CFAOff2,
1633                                                               AddrSpace));
1634   EXPECT_EQ(Rows[2].getRegisterLocations().size(), 1u);
1635   EXPECT_EQ(Rows[2].getRegisterLocations(), VerifyLocs);
1636 
1637   EXPECT_EQ(Rows[3].getAddress(), 0x100cu);
1638   EXPECT_EQ(Rows[3].getCFAValue(),
1639             dwarf::UnwindLocation::createIsRegisterPlusOffset(CFAReg2, CFAOff1,
1640                                                               AddrSpace));
1641   EXPECT_EQ(Rows[3].getRegisterLocations().size(), 1u);
1642   EXPECT_EQ(Rows[3].getRegisterLocations(), VerifyLocs);
1643 
1644   EXPECT_EQ(Rows[4].getAddress(), 0x1010u);
1645   EXPECT_EQ(Rows[4].getCFAValue(),
1646             dwarf::UnwindLocation::createIsRegisterPlusOffset(CFAReg1, CFAOff2,
1647                                                               AddrSpace));
1648   EXPECT_EQ(Rows[4].getRegisterLocations().size(), 1u);
1649   EXPECT_EQ(Rows[4].getRegisterLocations(), VerifyLocs);
1650 }
1651 
1652 } // end anonymous namespace
1653