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