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