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