brintos

brintos / llvm-project-archived public Read only

0
0
Text · 12.2 KiB · 264678e Raw
341 lines · cpp
1//===-- TestPECallFrameInfo.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 "gtest/gtest.h"11 12#include "Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h"13#include "Plugins/Process/Utility/lldb-x86-register-enums.h"14#include "TestingSupport/SubsystemRAII.h"15#include "TestingSupport/TestUtilities.h"16 17#include "lldb/Core/Module.h"18#include "lldb/Symbol/CallFrameInfo.h"19#include "lldb/Symbol/UnwindPlan.h"20#include "llvm/Testing/Support/Error.h"21 22using namespace lldb_private;23using namespace lldb;24 25class PECallFrameInfoTest : public testing::Test {26  SubsystemRAII<FileSystem, ObjectFilePECOFF> subsystems;27};28 29static llvm::Expected<std::unique_ptr<UnwindPlan>>30GetUnwindPlan(addr_t file_addr) {31  llvm::Expected<TestFile> ExpectedFile = TestFile::fromYaml(32      R"(33--- !COFF34OptionalHeader:  35  AddressOfEntryPoint: 036  ImageBase:       1677721637  SectionAlignment: 409638  FileAlignment:   51239  MajorOperatingSystemVersion: 640  MinorOperatingSystemVersion: 041  MajorImageVersion: 042  MinorImageVersion: 043  MajorSubsystemVersion: 644  MinorSubsystemVersion: 045  Subsystem:       IMAGE_SUBSYSTEM_WINDOWS_CUI46  DLLCharacteristics: [ IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA, IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE, IMAGE_DLL_CHARACTERISTICS_NX_COMPAT ]47  SizeOfStackReserve: 104857648  SizeOfStackCommit: 409649  SizeOfHeapReserve: 104857650  SizeOfHeapCommit: 409651  ExportTable:     52    RelativeVirtualAddress: 053    Size:            054  ImportTable:     55    RelativeVirtualAddress: 056    Size:            057  ResourceTable:   58    RelativeVirtualAddress: 059    Size:            060  ExceptionTable:  61    RelativeVirtualAddress: 1228862    Size:            6063  CertificateTable: 64    RelativeVirtualAddress: 065    Size:            066  BaseRelocationTable: 67    RelativeVirtualAddress: 068    Size:            069  Debug:           70    RelativeVirtualAddress: 071    Size:            072  Architecture:    73    RelativeVirtualAddress: 074    Size:            075  GlobalPtr:       76    RelativeVirtualAddress: 077    Size:            078  TlsTable:        79    RelativeVirtualAddress: 080    Size:            081  LoadConfigTable: 82    RelativeVirtualAddress: 083    Size:            084  BoundImport:     85    RelativeVirtualAddress: 086    Size:            087  IAT:             88    RelativeVirtualAddress: 089    Size:            090  DelayImportDescriptor: 91    RelativeVirtualAddress: 092    Size:            093  ClrRuntimeHeader: 94    RelativeVirtualAddress: 095    Size:            096header:          97  Machine:         IMAGE_FILE_MACHINE_AMD6498  Characteristics: [ IMAGE_FILE_EXECUTABLE_IMAGE, IMAGE_FILE_LARGE_ADDRESS_AWARE ]99sections:        100  - Name:            .text101    Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]102    VirtualAddress:  4096103    VirtualSize:     4096104  - Name:            .rdata105    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]106    VirtualAddress:  8192107    VirtualSize:     68108    SectionData:     010C06000C3208F006E00470036002302105020005540D0000100000001100000020000019400E352F74670028646600213465001A3315015E000EF00CE00AD008C00650109 110 111# Unwind info at 0x2000:112# 01 0C 06 00    No chained info, prolog size = 0xC, unwind codes size is 6 words, no frame register113# 0C 32          UOP_AllocSmall(2) 3 * 8 + 8 bytes, offset in prolog is 0xC114# 08 F0          UOP_PushNonVol(0) R15(0xF), offset in prolog is 8115# 06 E0          UOP_PushNonVol(0) R14(0xE), offset in prolog is 6116# 04 70          UOP_PushNonVol(0) RDI(7), offset in prolog is 4117# 03 60          UOP_PushNonVol(0) RSI(6), offset in prolog is 3118# 02 30          UOP_PushNonVol(0) RBX(3), offset in prolog is 2119# Corresponding prolog:120# 00    push    rbx121# 02    push    rsi122# 03    push    rdi123# 04    push    r14124# 06    push    r15125# 08    sub     rsp, 20h126 127# Unwind info at 0x2010:128# 21 05 02 00    Has chained info, prolog size = 5, unwind codes size is 2 words, no frame register129# 05 54 0D 00    UOP_SaveNonVol(4) RBP(5) to RSP + 0xD * 8, offset in prolog is 5130# Chained runtime function:131# 00 10 00 00    Start address is 0x1000132# 00 11 00 00    End address is 0x1100133# 00 20 00 00    Unwind info RVA is 0x2000134# Corresponding prolog:135# 00    mov     [rsp+68h], rbp136 137# Unwind info at 0x2024:138# 19 40 0E 35    No chained info, prolog size = 0x40, unwind codes size is 0xE words, frame register is RBP, frame register offset is RSP + 3 * 16139# 2F 74 67 00    UOP_SaveNonVol(4) RDI(7) to RSP + 0x67 * 8, offset in prolog is 0x2F140# 28 64 66 00    UOP_SaveNonVol(4) RSI(6) to RSP + 0x66 * 8, offset in prolog is 0x28141# 21 34 65 00    UOP_SaveNonVol(4) RBX(3) to RSP + 0x65 * 8, offset in prolog is 0x21142# 1A 33          UOP_SetFPReg(3), offset in prolog is 0x1A143# 15 01 5E 00    UOP_AllocLarge(1) 0x5E * 8 bytes, offset in prolog is 0x15144# 0E F0          UOP_PushNonVol(0) R15(0xF), offset in prolog is 0xE145# 0C E0          UOP_PushNonVol(0) R14(0xE), offset in prolog is 0xC146# 0A D0          UOP_PushNonVol(0) R13(0xD), offset in prolog is 0xA147# 08 C0          UOP_PushNonVol(0) R12(0xC), offset in prolog is 8148# 06 50          UOP_PushNonVol(0) RBP(5), offset in prolog is 6149# Corresponding prolog:150# 00    mov     [rsp+8], rcx151# 05    push    rbp152# 06    push    r12153# 08    push    r13154# 0A    push    r14155# 0C    push    r15156# 0E    sub     rsp, 2F0h157# 15    lea     rbp, [rsp+30h]158# 1A    mov     [rbp+2F8h], rbx159# 21    mov     [rbp+300h], rsi160# 28    mov     [rbp+308h], rdi161 162  - Name:            .pdata163    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]164    VirtualAddress:  12288165    VirtualSize:     60166    SectionData:     000000000000000000000000000000000000000000000000001000000011000000200000001100000012000010200000001200000013000024200000167 168# 00 00 00 00169# 00 00 00 00    Test correct processing of empty runtime functions at begin170# 00 00 00 00171 172# 00 00 00 00173# 00 00 00 00    Test correct processing of empty runtime functions at begin174# 00 00 00 00175 176# 00 10 00 00    Start address is 0x1000177# 00 11 00 00    End address is 0x1100178# 00 20 00 00    Unwind info RVA is 0x2000179 180# 00 11 00 00    Start address is 0x1100181# 00 12 00 00    End address is 0x1200182# 10 20 00 00    Unwind info RVA is 0x2010183 184# 00 12 00 00    Start address is 0x1200185# 00 13 00 00    End address is 0x1300186# 24 20 00 00    Unwind info RVA is 0x2024187 188symbols:         []189...190)");191  if (!ExpectedFile)192    return ExpectedFile.takeError();193 194  ModuleSP module_sp = std::make_shared<Module>(ExpectedFile->moduleSpec());195  ObjectFile *object_file = module_sp->GetObjectFile();196  if (!object_file)197    return llvm::createStringError("object file is null");198 199  std::unique_ptr<CallFrameInfo> cfi = object_file->CreateCallFrameInfo();200  if (!cfi)201    return llvm::createStringError("call frame info is null");202 203  SectionList *sect_list = object_file->GetSectionList();204  if (!sect_list)205    return llvm::createStringError("section list is null");206 207  std::unique_ptr<UnwindPlan> plan_up =208      cfi->GetUnwindPlan(Address(file_addr, sect_list));209  if (!plan_up)210    return llvm::createStringError("unwind plan is null");211  return plan_up;212}213 214TEST_F(PECallFrameInfoTest, Basic_eh) {215  llvm::Expected<std::unique_ptr<UnwindPlan>> expected_plan =216      GetUnwindPlan(0x1001080);217  ASSERT_THAT_EXPECTED(expected_plan, llvm::Succeeded());218  UnwindPlan &plan = **expected_plan;219  EXPECT_EQ(plan.GetRowCount(), 7);220 221  UnwindPlan::Row row;222  row.SetOffset(0);223  row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 8);224  row.SetRegisterLocationToIsCFAPlusOffset(lldb_rsp_x86_64, 0, true);225  row.SetRegisterLocationToAtCFAPlusOffset(lldb_rip_x86_64, -8, true);226  EXPECT_EQ(*plan.GetRowAtIndex(0), row);227 228  row.SetOffset(2);229  row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 0x10);230  row.SetRegisterLocationToAtCFAPlusOffset(lldb_rbx_x86_64, -0x10, true);231  EXPECT_EQ(*plan.GetRowAtIndex(1), row);232 233  row.SetOffset(3);234  row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 0x18);235  row.SetRegisterLocationToAtCFAPlusOffset(lldb_rsi_x86_64, -0x18, true);236  EXPECT_EQ(*plan.GetRowAtIndex(2), row);237 238  row.SetOffset(4);239  row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 0x20);240  row.SetRegisterLocationToAtCFAPlusOffset(lldb_rdi_x86_64, -0x20, true);241  EXPECT_EQ(*plan.GetRowAtIndex(3), row);242 243  row.SetOffset(6);244  row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 0x28);245  row.SetRegisterLocationToAtCFAPlusOffset(lldb_r14_x86_64, -0x28, true);246  EXPECT_EQ(*plan.GetRowAtIndex(4), row);247 248  row.SetOffset(8);249  row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 0x30);250  row.SetRegisterLocationToAtCFAPlusOffset(lldb_r15_x86_64, -0x30, true);251  EXPECT_EQ(*plan.GetRowAtIndex(5), row);252 253  row.SetOffset(0xC);254  row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 0x50);255  EXPECT_EQ(*plan.GetRowAtIndex(6), row);256}257 258TEST_F(PECallFrameInfoTest, Chained_eh) {259  llvm::Expected<std::unique_ptr<UnwindPlan>> expected_plan =260      GetUnwindPlan(0x1001180);261  ASSERT_THAT_EXPECTED(expected_plan, llvm::Succeeded());262  UnwindPlan &plan = **expected_plan;263  EXPECT_EQ(plan.GetRowCount(), 2);264 265  UnwindPlan::Row row;266  row.SetOffset(0);267  row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 0x50);268  row.SetRegisterLocationToIsCFAPlusOffset(lldb_rsp_x86_64, 0, true);269  row.SetRegisterLocationToAtCFAPlusOffset(lldb_rip_x86_64, -8, true);270  row.SetRegisterLocationToAtCFAPlusOffset(lldb_rbx_x86_64, -0x10, true);271  row.SetRegisterLocationToAtCFAPlusOffset(lldb_rsi_x86_64, -0x18, true);272  row.SetRegisterLocationToAtCFAPlusOffset(lldb_rdi_x86_64, -0x20, true);273  row.SetRegisterLocationToAtCFAPlusOffset(lldb_r14_x86_64, -0x28, true);274  row.SetRegisterLocationToAtCFAPlusOffset(lldb_r15_x86_64, -0x30, true);275  EXPECT_EQ(*plan.GetRowAtIndex(0), row);276 277  row.SetOffset(5);278  row.SetRegisterLocationToAtCFAPlusOffset(lldb_rbp_x86_64, 0x18, true);279  EXPECT_EQ(*plan.GetRowAtIndex(1), row);280}281 282TEST_F(PECallFrameInfoTest, Frame_reg_eh) {283  llvm::Expected<std::unique_ptr<UnwindPlan>> expected_plan =284      GetUnwindPlan(0x1001280);285  ASSERT_THAT_EXPECTED(expected_plan, llvm::Succeeded());286  UnwindPlan &plan = **expected_plan;287  EXPECT_EQ(plan.GetRowCount(), 11);288 289  UnwindPlan::Row row;290  row.SetOffset(0);291  row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 8);292  row.SetRegisterLocationToIsCFAPlusOffset(lldb_rsp_x86_64, 0, true);293  row.SetRegisterLocationToAtCFAPlusOffset(lldb_rip_x86_64, -8, true);294  EXPECT_EQ(*plan.GetRowAtIndex(0), row);295 296  row.SetOffset(6);297  row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 0x10);298  row.SetRegisterLocationToAtCFAPlusOffset(lldb_rbp_x86_64, -0x10, true);299  EXPECT_EQ(*plan.GetRowAtIndex(1), row);300 301  row.SetOffset(8);302  row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 0x18);303  row.SetRegisterLocationToAtCFAPlusOffset(lldb_r12_x86_64, -0x18, true);304  EXPECT_EQ(*plan.GetRowAtIndex(2), row);305 306  row.SetOffset(0xA);307  row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 0x20);308  row.SetRegisterLocationToAtCFAPlusOffset(lldb_r13_x86_64, -0x20, true);309  EXPECT_EQ(*plan.GetRowAtIndex(3), row);310 311  row.SetOffset(0xC);312  row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 0x28);313  row.SetRegisterLocationToAtCFAPlusOffset(lldb_r14_x86_64, -0x28, true);314  EXPECT_EQ(*plan.GetRowAtIndex(4), row);315 316  row.SetOffset(0xE);317  row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 0x30);318  row.SetRegisterLocationToAtCFAPlusOffset(lldb_r15_x86_64, -0x30, true);319  EXPECT_EQ(*plan.GetRowAtIndex(5), row);320 321  row.SetOffset(0x15);322  row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rsp_x86_64, 0x320);323  EXPECT_EQ(*plan.GetRowAtIndex(6), row);324 325  row.SetOffset(0x1A);326  row.GetCFAValue().SetIsRegisterPlusOffset(lldb_rbp_x86_64, 0x2F0);327  EXPECT_EQ(*plan.GetRowAtIndex(7), row);328 329  row.SetOffset(0x21);330  row.SetRegisterLocationToAtCFAPlusOffset(lldb_rbx_x86_64, 8, true);331  EXPECT_EQ(*plan.GetRowAtIndex(8), row);332 333  row.SetOffset(0x28);334  row.SetRegisterLocationToAtCFAPlusOffset(lldb_rsi_x86_64, 0x10, true);335  EXPECT_EQ(*plan.GetRowAtIndex(9), row);336 337  row.SetOffset(0x2F);338  row.SetRegisterLocationToAtCFAPlusOffset(lldb_rdi_x86_64, 0x18, true);339  EXPECT_EQ(*plan.GetRowAtIndex(10), row);340}341