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