brintos

brintos / llvm-project-archived public Read only

0
0
Text · 23.2 KiB · c52e9a7 Raw
668 lines · cpp
1//===-- TestDWARFCallFrameInfo.cpp ----------------------------------------===//2//3//4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.5// See https://llvm.org/LICENSE.txt for license information.6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception7//8//===----------------------------------------------------------------------===//9 10#include "gmock/gmock.h"11#include "gtest/gtest.h"12 13#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"14#include "Plugins/Process/Utility/RegisterContext_x86.h"15#include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h"16#include "TestingSupport/SubsystemRAII.h"17#include "TestingSupport/TestUtilities.h"18 19#include "lldb/Core/Module.h"20#include "lldb/Core/ModuleSpec.h"21#include "lldb/Core/Section.h"22#include "lldb/Host/FileSystem.h"23#include "lldb/Host/HostInfo.h"24#include "lldb/Symbol/DWARFCallFrameInfo.h"25#include "lldb/Utility/StreamString.h"26#include "llvm/Testing/Support/Error.h"27 28#include "llvm/Support/FileUtilities.h"29#include "llvm/Support/Path.h"30#include "llvm/Support/Program.h"31#include "llvm/Support/raw_ostream.h"32 33using namespace lldb_private;34using namespace lldb;35 36class DWARFCallFrameInfoTest : public testing::Test {37  SubsystemRAII<FileSystem, HostInfo, ObjectFileELF, SymbolFileSymtab>38      subsystems;39 40protected:41  void TestBasic(DWARFCallFrameInfo::Type type, llvm::StringRef symbol);42  void TestValOffset(DWARFCallFrameInfo::Type type, llvm::StringRef symbol);43};44 45namespace lldb_private {46static std::ostream &operator<<(std::ostream &OS, const UnwindPlan::Row &row) {47  StreamString SS;48  row.Dump(SS, nullptr, nullptr, 0);49  return OS << SS.GetData();50}51} // namespace lldb_private52 53static UnwindPlan::Row GetExpectedRow0() {54  UnwindPlan::Row row;55  row.SetOffset(0);56  row.GetCFAValue().SetIsRegisterPlusOffset(dwarf_rsp_x86_64, 8);57  row.SetRegisterLocationToAtCFAPlusOffset(dwarf_rip_x86_64, -8, false);58  return row;59}60 61static UnwindPlan::Row GetExpectedRow1() {62  UnwindPlan::Row row;63  row.SetOffset(1);64  row.GetCFAValue().SetIsRegisterPlusOffset(dwarf_rsp_x86_64, 16);65  row.SetRegisterLocationToAtCFAPlusOffset(dwarf_rip_x86_64, -8, false);66  row.SetRegisterLocationToAtCFAPlusOffset(dwarf_rbp_x86_64, -16, false);67  return row;68}69 70static UnwindPlan::Row GetExpectedRow2() {71  UnwindPlan::Row row;72  row.SetOffset(4);73  row.GetCFAValue().SetIsRegisterPlusOffset(dwarf_rbp_x86_64, 16);74  row.SetRegisterLocationToAtCFAPlusOffset(dwarf_rip_x86_64, -8, false);75  row.SetRegisterLocationToAtCFAPlusOffset(dwarf_rbp_x86_64, -16, false);76  return row;77}78 79void DWARFCallFrameInfoTest::TestBasic(DWARFCallFrameInfo::Type type,80                                       llvm::StringRef symbol) {81  auto ExpectedFile = TestFile::fromYaml(R"(82--- !ELF83FileHeader:84  Class:           ELFCLASS6485  Data:            ELFDATA2LSB86  Type:            ET_DYN87  Machine:         EM_X86_6488  Entry:           0x000000000000026089Sections:90  - Name:            .text91    Type:            SHT_PROGBITS92    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]93    Address:         0x000000000000026094    AddressAlign:    0x000000000000001095    Content:         554889E5897DFC8B45FC5DC30F1F4000554889E5897DFC8B45FC5DC30F1F4000554889E5897DFC8B45FC5DC396#0000000000000260 <eh_frame>:97# 260:	55                   	push   %rbp98# 261:	48 89 e5             	mov    %rsp,%rbp99# 264:	89 7d fc             	mov    %edi,-0x4(%rbp)100# 267:	8b 45 fc             	mov    -0x4(%rbp),%eax101# 26a:	5d                   	pop    %rbp102# 26b:	c3                   	retq103# 26c:	0f 1f 40 00          	nopl   0x0(%rax)104#105#0000000000000270 <debug_frame3>:106# 270:	55                   	push   %rbp107# 271:	48 89 e5             	mov    %rsp,%rbp108# 274:	89 7d fc             	mov    %edi,-0x4(%rbp)109# 277:	8b 45 fc             	mov    -0x4(%rbp),%eax110# 27a:	5d                   	pop    %rbp111# 27b:	c3                   	retq112# 27c:	0f 1f 40 00          	nopl   0x0(%rax)113#114#0000000000000280 <debug_frame4>:115# 280:	55                   	push   %rbp116# 281:	48 89 e5             	mov    %rsp,%rbp117# 284:	89 7d fc             	mov    %edi,-0x4(%rbp)118# 287:	8b 45 fc             	mov    -0x4(%rbp),%eax119# 28a:	5d                   	pop    %rbp120# 28b:	c3                   	retq121  - Name:            .eh_frame122    Type:            SHT_X86_64_UNWIND123    Flags:           [ SHF_ALLOC ]124    Address:         0x0000000000000290125    AddressAlign:    0x0000000000000008126    Content:         1400000000000000017A5200017810011B0C0708900100001C0000001C000000B0FFFFFF0C00000000410E108602430D0600000000000000127#00000000 0000000000000014 00000000 CIE128#  Version:               1129#  Augmentation:          "zR"130#  Code alignment factor: 1131#  Data alignment factor: -8132#  Return address column: 16133#  Augmentation data:     1b134#135#  DW_CFA_def_cfa: r7 (rsp) ofs 8136#  DW_CFA_offset: r16 (rip) at cfa-8137#  DW_CFA_nop138#  DW_CFA_nop139#140#00000018 000000000000001c 0000001c FDE cie=00000000 pc=ffffffffffffffd0..ffffffffffffffdc141#  DW_CFA_advance_loc: 1 to ffffffffffffffd1142#  DW_CFA_def_cfa_offset: 16143#  DW_CFA_offset: r6 (rbp) at cfa-16144#  DW_CFA_advance_loc: 3 to ffffffffffffffd4145#  DW_CFA_def_cfa_register: r6 (rbp)146#  DW_CFA_nop147#  DW_CFA_nop148#  DW_CFA_nop149#  DW_CFA_nop150#  DW_CFA_nop151#  DW_CFA_nop152#  DW_CFA_nop153  - Name:            .debug_frame154    Type:            SHT_PROGBITS155    AddressAlign:    0x0000000000000008156    Content:         14000000FFFFFFFF03000178100C070890010000000000001C0000000000000070020000000000000C00000000000000410E108602430D0614000000FFFFFFFF040008000178100C07089001000000001C0000003800000080020000000000000C00000000000000410E108602430D06157#00000000 0000000000000014 ffffffff CIE158#  Version:               3159#  Augmentation:          ""160#  Code alignment factor: 1161#  Data alignment factor: -8162#  Return address column: 16163#164#  DW_CFA_def_cfa: r7 (rsp) ofs 8165#  DW_CFA_offset: r16 (rip) at cfa-8166#  DW_CFA_nop167#  DW_CFA_nop168#  DW_CFA_nop169#  DW_CFA_nop170#  DW_CFA_nop171#  DW_CFA_nop172#173#00000018 000000000000001c 00000000 FDE cie=00000000 pc=0000000000000270..000000000000027c174#  DW_CFA_advance_loc: 1 to 0000000000000271175#  DW_CFA_def_cfa_offset: 16176#  DW_CFA_offset: r6 (rbp) at cfa-16177#  DW_CFA_advance_loc: 3 to 0000000000000274178#  DW_CFA_def_cfa_register: r6 (rbp)179#180#00000038 0000000000000014 ffffffff CIE181#  Version:               4182#  Augmentation:          ""183#  Pointer Size:          8184#  Segment Size:          0185#  Code alignment factor: 1186#  Data alignment factor: -8187#  Return address column: 16188#189#  DW_CFA_def_cfa: r7 (rsp) ofs 8190#  DW_CFA_offset: r16 (rip) at cfa-8191#  DW_CFA_nop192#  DW_CFA_nop193#  DW_CFA_nop194#  DW_CFA_nop195#196#00000050 000000000000001c 00000038 FDE cie=00000038 pc=0000000000000280..000000000000028c197#  DW_CFA_advance_loc: 1 to 0000000000000281198#  DW_CFA_def_cfa_offset: 16199#  DW_CFA_offset: r6 (rbp) at cfa-16200#  DW_CFA_advance_loc: 3 to 0000000000000284201#  DW_CFA_def_cfa_register: r6 (rbp)202Symbols:203  - Name:            eh_frame204    Type:            STT_FUNC205    Section:         .text206    Value:           0x0000000000000260207    Size:            0x000000000000000C208    Binding:         STB_GLOBAL209  - Name:            debug_frame3210    Type:            STT_FUNC211    Section:         .text212    Value:           0x0000000000000270213    Size:            0x000000000000000C214    Binding:         STB_GLOBAL215  - Name:            debug_frame4216    Type:            STT_FUNC217    Section:         .text218    Value:           0x0000000000000280219    Size:            0x000000000000000C220    Binding:         STB_GLOBAL221...222)");223  ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());224 225  auto module_sp = std::make_shared<Module>(ExpectedFile->moduleSpec());226  SectionList *list = module_sp->GetSectionList();227  ASSERT_NE(nullptr, list);228 229  auto section_sp = list->FindSectionByType(type == DWARFCallFrameInfo::EH230                                                ? eSectionTypeEHFrame231                                                : eSectionTypeDWARFDebugFrame,232                                            false);233  ASSERT_NE(nullptr, section_sp);234 235  DWARFCallFrameInfo cfi(*module_sp->GetObjectFile(), section_sp, type);236 237  const Symbol *sym = module_sp->FindFirstSymbolWithNameAndType(238      ConstString(symbol), eSymbolTypeAny);239  ASSERT_NE(nullptr, sym);240 241  std::unique_ptr<UnwindPlan> plan_up = cfi.GetUnwindPlan(sym->GetAddress());242  ASSERT_TRUE(plan_up);243  ASSERT_EQ(3, plan_up->GetRowCount());244  EXPECT_THAT(plan_up->GetRowAtIndex(0), testing::Pointee(GetExpectedRow0()));245  EXPECT_THAT(plan_up->GetRowAtIndex(1), testing::Pointee(GetExpectedRow1()));246  EXPECT_THAT(plan_up->GetRowAtIndex(2), testing::Pointee(GetExpectedRow2()));247}248 249TEST_F(DWARFCallFrameInfoTest, Basic_dwarf3) {250  TestBasic(DWARFCallFrameInfo::DWARF, "debug_frame3");251}252 253TEST_F(DWARFCallFrameInfoTest, Basic_dwarf4) {254  TestBasic(DWARFCallFrameInfo::DWARF, "debug_frame4");255}256 257TEST_F(DWARFCallFrameInfoTest, Basic_eh) {258  TestBasic(DWARFCallFrameInfo::EH, "eh_frame");259}260 261static UnwindPlan::Row GetValOffsetExpectedRow0() {262  UnwindPlan::Row row;263  row.SetOffset(0);264  row.GetCFAValue().SetIsRegisterPlusOffset(dwarf_rsp_x86_64, 16);265  row.SetRegisterLocationToAtCFAPlusOffset(dwarf_rip_x86_64, -8, false);266  row.SetRegisterLocationToIsCFAPlusOffset(dwarf_rbp_x86_64, -16, false);267  return row;268}269 270void DWARFCallFrameInfoTest::TestValOffset(DWARFCallFrameInfo::Type type,271                                           llvm::StringRef symbol) {272  // This test is artificial as X86 does not use DW_CFA_val_offset but this273  // test verifies that we can successfully interpret them if they do occur.274  // Note the distinction between RBP and RIP in this part of the DWARF dump:275  // 0x0: CFA=RSP+16: RBP=CFA-16, RIP=[CFA-8]276  // Whereas RIP is stored in the memory CFA-8 points at, RBP is reconstructed277  // from the CFA without any memory access.278  auto ExpectedFile = TestFile::fromYaml(R"(279--- !ELF280FileHeader:281  Class:           ELFCLASS64282  Data:            ELFDATA2LSB283  Type:            ET_REL284  Machine:         EM_X86_64285  SectionHeaderStringTable: .strtab286Sections:287  - Name:            .text288    Type:            SHT_PROGBITS289    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]290    AddressAlign:    0x4291    Content:         0F1F00292  - Name:            .debug_frame293    Type:            SHT_PROGBITS294    AddressAlign:    0x8295#00000000 00000014 ffffffff CIE296#  Format:                DWARF32297#  Version:               4298#  Augmentation:          ""299#  Address size:          8300#  Segment desc size:     0301#  Code alignment factor: 1302#  Data alignment factor: -8303#  Return address column: 16304#305#  DW_CFA_def_cfa: RSP +8306#  DW_CFA_offset: RIP -8307#  DW_CFA_nop:308#  DW_CFA_nop:309#  DW_CFA_nop:310#  DW_CFA_nop:311#312#  CFA=RSP+8: RIP=[CFA-8]313#314#00000018 0000001c 00000000 FDE cie=00000000 pc=00000000...00000003315#  Format:       DWARF32316#  DW_CFA_def_cfa_offset: +16317#  DW_CFA_val_offset: RBP -16318#  DW_CFA_nop:319#  DW_CFA_nop:320#  DW_CFA_nop:321#322#  0x0: CFA=RSP+16: RBP=CFA-16, RIP=[CFA-8]323    Content:         14000000FFFFFFFF040008000178100C07089001000000001C00000000000000000000000000000003000000000000000E10140602000000324  - Name:            .rela.debug_frame325    Type:            SHT_RELA326    Flags:           [ SHF_INFO_LINK ]327    Link:            .symtab328    AddressAlign:    0x8329    Info:            .debug_frame330    Relocations:331      - Offset:          0x1C332        Symbol:          .debug_frame333        Type:            R_X86_64_32334      - Offset:          0x20335        Symbol:          .text336        Type:            R_X86_64_64337  - Type:            SectionHeaderTable338    Sections:339      - Name:            .strtab340      - Name:            .text341      - Name:            .debug_frame342      - Name:            .rela.debug_frame343      - Name:            .symtab344Symbols:345  - Name:            .text346    Type:            STT_SECTION347    Section:         .text348  - Name:            debug_frame3349    Section:         .text350  - Name:            .debug_frame351    Type:            STT_SECTION352    Section:         .debug_frame353...354)");355  ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());356 357  auto module_sp = std::make_shared<Module>(ExpectedFile->moduleSpec());358  SectionList *list = module_sp->GetSectionList();359  ASSERT_NE(nullptr, list);360 361  auto section_sp = list->FindSectionByType(type == DWARFCallFrameInfo::EH362                                                ? eSectionTypeEHFrame363                                                : eSectionTypeDWARFDebugFrame,364                                            false);365  ASSERT_NE(nullptr, section_sp);366 367  DWARFCallFrameInfo cfi(*module_sp->GetObjectFile(), section_sp, type);368 369  const Symbol *sym = module_sp->FindFirstSymbolWithNameAndType(370      ConstString(symbol), eSymbolTypeAny);371  ASSERT_NE(nullptr, sym);372 373  std::unique_ptr<UnwindPlan> plan_up = cfi.GetUnwindPlan(sym->GetAddress());374  ASSERT_TRUE(plan_up);375  ASSERT_EQ(1, plan_up->GetRowCount());376  EXPECT_THAT(plan_up->GetRowAtIndex(0),377              testing::Pointee(GetValOffsetExpectedRow0()));378}379 380TEST_F(DWARFCallFrameInfoTest, ValOffset_dwarf3) {381  TestValOffset(DWARFCallFrameInfo::DWARF, "debug_frame3");382}383 384// Test that we correctly handle invalid FDE entries that have CIE ID values385TEST_F(DWARFCallFrameInfoTest, InvalidFDEWithCIEID_dwarf32) {386  // Create an FDE with cie_offset of 0xFFFFFFFF (DW_CIE_ID) which is invalid387  auto ExpectedFile = TestFile::fromYaml(R"(388--- !ELF389FileHeader:390  Class:           ELFCLASS64391  Data:            ELFDATA2LSB392  Type:            ET_REL393  Machine:         EM_X86_64394Sections:395  - Name:            .text396    Type:            SHT_PROGBITS397    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]398    Address:         0x0000000000000260399    AddressAlign:    0x0000000000000010400    Content:         554889E5897DFC8B45FC5DC3401  - Name:            .debug_frame402    Type:            SHT_PROGBITS403    AddressAlign:    0x0000000000000008404    # First, a valid CIE405    # 00000000 0000000000000014 ffffffff CIE406    #   Version:               3407    #   Augmentation:          ""408    #   Code alignment factor: 1409    #   Data alignment factor: -8410    #   Return address column: 16411    Content:         14000000FFFFFFFF03000178100C0708900100000000000018000000FFFFFFFF60020000000000000C00000000000000412    # Then an invalid FDE with CIE pointer = 0xFFFFFFFF (which would make it look like a CIE)413    # 00000018 0000000000000018 ffffffff FDE cie=ffffffff pc=0000000000000260..000000000000026c414    # The cie offset of 0xFFFFFFFF is invalid for an FDE in debug_frame415Symbols:416  - Name:            test_invalid417    Type:            STT_FUNC418    Section:         .text419    Value:           0x0000000000000260420    Size:            0x000000000000000C421    Binding:         STB_GLOBAL422...423)");424  ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());425 426  auto module_sp = std::make_shared<Module>(ExpectedFile->moduleSpec());427  SectionList *list = module_sp->GetSectionList();428  ASSERT_NE(nullptr, list);429 430  auto section_sp = list->FindSectionByType(eSectionTypeDWARFDebugFrame, false);431  ASSERT_NE(nullptr, section_sp);432 433  DWARFCallFrameInfo cfi(*module_sp->GetObjectFile(), section_sp,434                         DWARFCallFrameInfo::DWARF);435 436  // This should trigger our assertion or return nullptr because the FDE is437  // invalid438  const Symbol *sym = module_sp->FindFirstSymbolWithNameAndType(439      ConstString("test_invalid"), eSymbolTypeAny);440  ASSERT_NE(nullptr, sym);441 442  std::unique_ptr<UnwindPlan> plan_up = cfi.GetUnwindPlan(sym->GetAddress());443  // The plan should be null because we have an invalid FDE444  EXPECT_EQ(nullptr, plan_up);445}446 447// Test that we correctly handle invalid FDE entries that have CIE ID values448TEST_F(DWARFCallFrameInfoTest, InvalidFDEWithCIEID_dwarf64) {449  // Create an FDE with cie_offset of 0xFFFFFFFFFFFFFFFF (DW64_CIE_ID) which is450  // invalid451  auto ExpectedFile = TestFile::fromYaml(R"(452--- !ELF453FileHeader:454  Class:           ELFCLASS64455  Data:            ELFDATA2LSB456  Type:            ET_REL457  Machine:         EM_X86_64458Sections:459  - Name:            .text460    Type:            SHT_PROGBITS461    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]462    Address:         0x0000000000000260463    AddressAlign:    0x0000000000000010464    Content:         554889E5897DFC8B45FC5DC3465  - Name:            .debug_frame466    Type:            SHT_PROGBITS467    AddressAlign:    0x0000000000000008468    # DWARF64 format CIE469    # Initial length: 0xFFFFFFFF followed by 64-bit length470    # 00000000 ffffffff 0000000000000014 ffffffffffffffff CIE471    Content:         FFFFFFFF1400000000000000FFFFFFFFFFFFFFFF03000178100C0708900100000000FFFFFFFF1800000000000000FFFFFFFFFFFFFFFF60020000000000000C00000000000000472    # DWARF64 FDE with invalid CIE pointer = 0xFFFFFFFFFFFFFFFF473    # Initial length: 0xFFFFFFFF, followed by 64-bit length (0x18)474    # Then 64-bit CIE pointer: 0xFFFFFFFFFFFFFFFF (which is DW64_CIE_ID, invalid for FDE)475Symbols:476  - Name:            test_invalid64477    Type:            STT_FUNC478    Section:         .text479    Value:           0x0000000000000260480    Size:            0x000000000000000C481    Binding:         STB_GLOBAL482...483)");484  ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());485 486  auto module_sp = std::make_shared<Module>(ExpectedFile->moduleSpec());487  SectionList *list = module_sp->GetSectionList();488  ASSERT_NE(nullptr, list);489 490  auto section_sp = list->FindSectionByType(eSectionTypeDWARFDebugFrame, false);491  ASSERT_NE(nullptr, section_sp);492 493  DWARFCallFrameInfo cfi(*module_sp->GetObjectFile(), section_sp,494                         DWARFCallFrameInfo::DWARF);495 496  const Symbol *sym = module_sp->FindFirstSymbolWithNameAndType(497      ConstString("test_invalid64"), eSymbolTypeAny);498  ASSERT_NE(nullptr, sym);499 500  std::unique_ptr<UnwindPlan> plan_up = cfi.GetUnwindPlan(sym->GetAddress());501  // The plan should be null because we have an invalid FDE502  EXPECT_EQ(nullptr, plan_up);503}504 505// Test valid CIE markers in eh_frame format506TEST_F(DWARFCallFrameInfoTest, ValidCIEMarkers_eh_frame) {507  auto ExpectedFile = TestFile::fromYaml(R"(508--- !ELF509FileHeader:510  Class:           ELFCLASS64511  Data:            ELFDATA2LSB512  Type:            ET_DYN513  Machine:         EM_X86_64514  Entry:           0x0000000000000260515Sections:516  - Name:            .text517    Type:            SHT_PROGBITS518    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]519    Address:         0x0000000000000260520    AddressAlign:    0x0000000000000010521    Content:         554889E5897DFC8B45FC5DC3522  - Name:            .eh_frame523    Type:            SHT_X86_64_UNWIND524    Flags:           [ SHF_ALLOC ]525    Address:         0x0000000000000290526    AddressAlign:    0x0000000000000008527    # eh_frame content528    # CIE + FDE that works with address 0x260529    Content:         1400000000000000017A5200017810011B0C0708900100001C0000001C000000B0FFFFFF0C00000000410E108602430D0600000000000000530Symbols:531  - Name:            simple_function532    Type:            STT_FUNC533    Section:         .text534    Value:           0x0000000000000260535    Size:            0x000000000000000F536    Binding:         STB_GLOBAL537...538)");539  ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());540 541  auto module_sp = std::make_shared<Module>(ExpectedFile->moduleSpec());542  SectionList *list = module_sp->GetSectionList();543  ASSERT_NE(nullptr, list);544 545  auto section_sp = list->FindSectionByType(eSectionTypeEHFrame, false);546  ASSERT_NE(nullptr, section_sp);547 548  DWARFCallFrameInfo cfi(*module_sp->GetObjectFile(), section_sp,549                         DWARFCallFrameInfo::EH);550 551  const Symbol *sym = module_sp->FindFirstSymbolWithNameAndType(552      ConstString("simple_function"), eSymbolTypeAny);553  ASSERT_NE(nullptr, sym);554 555  std::unique_ptr<UnwindPlan> plan_up = cfi.GetUnwindPlan(sym->GetAddress());556  // Should succeed with valid CIE and FDE557  ASSERT_NE(nullptr, plan_up);558  EXPECT_GE(plan_up->GetRowCount(), 1);559}560 561// Test valid CIE markers in debug_frame DWARF32 format562TEST_F(DWARFCallFrameInfoTest, ValidCIEMarkers_dwarf32) {563  auto ExpectedFile = TestFile::fromYaml(R"(564--- !ELF565FileHeader:566  Class:           ELFCLASS64567  Data:            ELFDATA2LSB568  Type:            ET_REL569  Machine:         EM_X86_64570Sections:571  - Name:            .text572    Type:            SHT_PROGBITS573    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]574    Address:         0x0000000000001130575    AddressAlign:    0x0000000000000010576    Content:         554889E5897DFC8B45FC83C0015DC3577  - Name:            .debug_frame578    Type:            SHT_PROGBITS579    AddressAlign:    0x0000000000000008580    # debug_frame content in DWARF32 format581    # CIE (length=0x14, CIE_id=0xFFFFFFFF, version=4)582    # FDE (length=0x24, CIE_offset=0)583    Content:         14000000FFFFFFFF040008000178100C0708900100000000240000000000000030110000000000000F00000000000000410E108602430D064A0C070800000000584Symbols:585  - Name:            simple_function586    Type:            STT_FUNC587    Section:         .text588    Value:           0x0000000000001130589    Size:            0x000000000000000F590    Binding:         STB_GLOBAL591...592)");593  ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());594 595  auto module_sp = std::make_shared<Module>(ExpectedFile->moduleSpec());596  SectionList *list = module_sp->GetSectionList();597  ASSERT_NE(nullptr, list);598 599  auto section_sp = list->FindSectionByType(eSectionTypeDWARFDebugFrame, false);600  ASSERT_NE(nullptr, section_sp);601 602  DWARFCallFrameInfo cfi(*module_sp->GetObjectFile(), section_sp,603                         DWARFCallFrameInfo::DWARF);604 605  const Symbol *sym = module_sp->FindFirstSymbolWithNameAndType(606      ConstString("simple_function"), eSymbolTypeAny);607  ASSERT_NE(nullptr, sym);608 609  std::unique_ptr<UnwindPlan> plan_up = cfi.GetUnwindPlan(sym->GetAddress());610  // Should succeed with valid CIE and FDE611  ASSERT_NE(nullptr, plan_up);612  EXPECT_GE(plan_up->GetRowCount(), 1);613}614 615// Test valid CIE markers in debug_frame DWARF64 format616TEST_F(DWARFCallFrameInfoTest, ValidCIEMarkers_dwarf64) {617  auto ExpectedFile = TestFile::fromYaml(R"(618--- !ELF619FileHeader:620  Class:           ELFCLASS64621  Data:            ELFDATA2LSB622  Type:            ET_REL623  Machine:         EM_X86_64624Sections:625  - Name:            .text626    Type:            SHT_PROGBITS627    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]628    Address:         0x0000000000001130629    AddressAlign:    0x0000000000000010630    Content:         554889E5897DFC8B45FC83C0015DC3631  - Name:            .debug_frame632    Type:            SHT_PROGBITS633    AddressAlign:    0x0000000000000008634    # debug_frame content in DWARF64 format635    # CIE: length_marker=0xFFFFFFFF, length=0x14, CIE_id=0xFFFFFFFFFFFFFFFF, version=4636    # FDE: length_marker=0xFFFFFFFF, length=0x24, CIE_offset=0x0 (points to CIE)637    Content:         FFFFFFFF1400000000000000FFFFFFFFFFFFFFFF040008000178100C07089001FFFFFFFF2400000000000000000000000000000030110000000000000F00000000000000410E108602430D064A0C0708638Symbols:639  - Name:            simple_function640    Type:            STT_FUNC641    Section:         .text642    Value:           0x0000000000001130643    Size:            0x000000000000000F644    Binding:         STB_GLOBAL645...646)");647  ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());648 649  auto module_sp = std::make_shared<Module>(ExpectedFile->moduleSpec());650  SectionList *list = module_sp->GetSectionList();651  ASSERT_NE(nullptr, list);652 653  auto section_sp = list->FindSectionByType(eSectionTypeDWARFDebugFrame, false);654  ASSERT_NE(nullptr, section_sp);655 656  DWARFCallFrameInfo cfi(*module_sp->GetObjectFile(), section_sp,657                         DWARFCallFrameInfo::DWARF);658 659  const Symbol *sym = module_sp->FindFirstSymbolWithNameAndType(660      ConstString("simple_function"), eSymbolTypeAny);661  ASSERT_NE(nullptr, sym);662 663  std::unique_ptr<UnwindPlan> plan_up = cfi.GetUnwindPlan(sym->GetAddress());664  // Should succeed with valid CIE and FDE665  ASSERT_NE(nullptr, plan_up);666  EXPECT_GE(plan_up->GetRowCount(), 1);667}668