brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.2 KiB · 1a528da Raw
259 lines · cpp
1//===-- TestPPC64InstEmulation.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-exception6//7//===----------------------------------------------------------------------===//8 9#include "gtest/gtest.h"10 11#include <vector>12 13#include "Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h"14 15#include "lldb/Core/Address.h"16#include "lldb/Core/AddressRange.h"17#include "lldb/Symbol/UnwindPlan.h"18#include "lldb/Target/UnwindAssembly.h"19#include "lldb/Utility/ArchSpec.h"20 21#include "Plugins/Disassembler/LLVMC/DisassemblerLLVMC.h"22#include "Plugins/Instruction/PPC64/EmulateInstructionPPC64.h"23#include "Plugins/Process/Utility/lldb-ppc64le-register-enums.h"24#include "llvm/Support/TargetSelect.h"25 26using namespace lldb;27using namespace lldb_private;28 29class TestPPC64InstEmulation : public testing::Test {30public:31  static void SetUpTestCase();32  static void TearDownTestCase();33 34  //  virtual void SetUp() override { }35  //  virtual void TearDown() override { }36 37protected:38};39 40void TestPPC64InstEmulation::SetUpTestCase() {41  llvm::InitializeAllTargets();42  llvm::InitializeAllAsmPrinters();43  llvm::InitializeAllTargetMCs();44  llvm::InitializeAllDisassemblers();45  DisassemblerLLVMC::Initialize();46  EmulateInstructionPPC64::Initialize();47}48 49void TestPPC64InstEmulation::TearDownTestCase() {50  DisassemblerLLVMC::Terminate();51  EmulateInstructionPPC64::Terminate();52}53 54TEST_F(TestPPC64InstEmulation, TestSimpleFunction) {55  ArchSpec arch("powerpc64le-linux-gnu");56  std::unique_ptr<UnwindAssemblyInstEmulation> engine(57      static_cast<UnwindAssemblyInstEmulation *>(58          UnwindAssemblyInstEmulation::CreateInstance(arch)));59  ASSERT_NE(nullptr, engine);60 61  const UnwindPlan::Row *row;62  AddressRange sample_range;63  UnwindPlan unwind_plan(eRegisterKindLLDB);64  UnwindPlan::Row::AbstractRegisterLocation regloc;65 66  // prologue and epilogue of:67  // int main() {68  //   int i = test();69  //   return i;70  // }71  //72  // compiled with clang -O0 -g73  uint8_t data[] = {74      // prologue75      0x02, 0x10, 0x40, 0x3c, //  0: lis r2, 409876      0x00, 0x7f, 0x42, 0x38, //  4: addi r2, r2, 3251277      0xa6, 0x02, 0x08, 0x7c, //  8: mflr r078      0xf8, 0xff, 0xe1, 0xfb, // 12: std r31, -8(r1)79      0x10, 0x00, 0x01, 0xf8, // 16: std r0, 16(r1)80      0x91, 0xff, 0x21, 0xf8, // 20: stdu r1, -112(r1)81      0x78, 0x0b, 0x3f, 0x7c, // 24: mr r31, r182      0x00, 0x00, 0x60, 0x38, // 28: li r3, 083      0x64, 0x00, 0x7f, 0x90, // 32: stw r3, 100(r31)84 85      // epilogue86      0x70, 0x00, 0x21, 0x38, // 36: addi r1, r1, 11287      0x10, 0x00, 0x01, 0xe8, // 40: ld r0, 16(r1)88      0xf8, 0xff, 0xe1, 0xeb, // 44: ld r31, -8(r1)89      0xa6, 0x03, 0x08, 0x7c, // 48: mtlr r090      0x20, 0x00, 0x80, 0x4e  // 52: blr91  };92 93  sample_range = AddressRange(0x1000, sizeof(data));94 95  EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly(96      sample_range, data, sizeof(data), unwind_plan));97 98  // 0: CFA=sp+099  row = unwind_plan.GetRowForFunctionOffset(0);100  EXPECT_EQ(0, row->GetOffset());101  EXPECT_TRUE(row->GetCFAValue().GetRegisterNumber() == gpr_r1_ppc64le);102  EXPECT_TRUE(row->GetCFAValue().IsRegisterPlusOffset() == true);103  EXPECT_EQ(0, row->GetCFAValue().GetOffset());104 105  // 1: CFA=sp+0 => fp=[CFA-8]106  row = unwind_plan.GetRowForFunctionOffset(16);107  EXPECT_EQ(16, row->GetOffset());108  EXPECT_TRUE(row->GetCFAValue().GetRegisterNumber() == gpr_r1_ppc64le);109  EXPECT_TRUE(row->GetCFAValue().IsRegisterPlusOffset() == true);110  EXPECT_EQ(0, row->GetCFAValue().GetOffset());111 112  EXPECT_TRUE(row->GetRegisterInfo(gpr_r31_ppc64le, regloc));113  EXPECT_TRUE(regloc.IsAtCFAPlusOffset());114  EXPECT_EQ(-8, regloc.GetOffset());115 116  // 2: CFA=sp+0 => fp=[CFA-8] lr=[CFA+16]117  row = unwind_plan.GetRowForFunctionOffset(20);118  EXPECT_EQ(20, row->GetOffset());119  EXPECT_TRUE(row->GetCFAValue().GetRegisterNumber() == gpr_r1_ppc64le);120  EXPECT_TRUE(row->GetCFAValue().IsRegisterPlusOffset() == true);121  EXPECT_EQ(0, row->GetCFAValue().GetOffset());122 123  EXPECT_TRUE(row->GetRegisterInfo(gpr_lr_ppc64le, regloc));124  EXPECT_TRUE(regloc.IsAtCFAPlusOffset());125  EXPECT_EQ(16, regloc.GetOffset());126 127  // 3: CFA=sp+112 => fp=[CFA-8] lr=[CFA+16]128  row = unwind_plan.GetRowForFunctionOffset(24);129  EXPECT_EQ(24, row->GetOffset());130  EXPECT_TRUE(row->GetCFAValue().GetRegisterNumber() == gpr_r1_ppc64le);131  EXPECT_TRUE(row->GetCFAValue().IsRegisterPlusOffset() == true);132  EXPECT_EQ(112, row->GetCFAValue().GetOffset());133 134  EXPECT_TRUE(row->GetRegisterInfo(gpr_r31_ppc64le, regloc));135  EXPECT_TRUE(regloc.IsAtCFAPlusOffset());136  EXPECT_EQ(-8, regloc.GetOffset());137 138  EXPECT_TRUE(row->GetRegisterInfo(gpr_lr_ppc64le, regloc));139  EXPECT_TRUE(regloc.IsAtCFAPlusOffset());140  EXPECT_EQ(16, regloc.GetOffset());141 142  // 4: CFA=r31+112 => fp=[CFA-8] lr=[CFA+16]143  row = unwind_plan.GetRowForFunctionOffset(28);144  EXPECT_EQ(28, row->GetOffset());145  EXPECT_TRUE(row->GetCFAValue().GetRegisterNumber() == gpr_r31_ppc64le);146  EXPECT_TRUE(row->GetCFAValue().IsRegisterPlusOffset() == true);147  EXPECT_EQ(112, row->GetCFAValue().GetOffset());148 149  EXPECT_TRUE(row->GetRegisterInfo(gpr_r31_ppc64le, regloc));150  EXPECT_TRUE(regloc.IsAtCFAPlusOffset());151  EXPECT_EQ(-8, regloc.GetOffset());152 153  EXPECT_TRUE(row->GetRegisterInfo(gpr_lr_ppc64le, regloc));154  EXPECT_TRUE(regloc.IsAtCFAPlusOffset());155  EXPECT_EQ(16, regloc.GetOffset());156 157  // 5: CFA=sp+0 => fp=[CFA-8] lr=[CFA+16]158  row = unwind_plan.GetRowForFunctionOffset(40);159  EXPECT_EQ(40, row->GetOffset());160  EXPECT_TRUE(row->GetCFAValue().GetRegisterNumber() == gpr_r1_ppc64le);161  EXPECT_TRUE(row->GetCFAValue().IsRegisterPlusOffset() == true);162  EXPECT_EQ(0, row->GetCFAValue().GetOffset());163 164  EXPECT_TRUE(row->GetRegisterInfo(gpr_r31_ppc64le, regloc));165  EXPECT_TRUE(regloc.IsAtCFAPlusOffset());166  EXPECT_EQ(-8, regloc.GetOffset());167 168  EXPECT_TRUE(row->GetRegisterInfo(gpr_lr_ppc64le, regloc));169  EXPECT_TRUE(regloc.IsAtCFAPlusOffset());170  EXPECT_EQ(16, regloc.GetOffset());171}172 173TEST_F(TestPPC64InstEmulation, TestMediumFunction) {174  ArchSpec arch("powerpc64le-linux-gnu");175  std::unique_ptr<UnwindAssemblyInstEmulation> engine(176      static_cast<UnwindAssemblyInstEmulation *>(177          UnwindAssemblyInstEmulation::CreateInstance(arch)));178  ASSERT_NE(nullptr, engine);179 180  const UnwindPlan::Row *row;181  AddressRange sample_range;182  UnwindPlan unwind_plan(eRegisterKindLLDB);183  UnwindPlan::Row::AbstractRegisterLocation regloc;184 185  // prologue and epilogue of main() (call-func.c),186  // with several calls and stack variables.187  //188  // compiled with clang -O0 -g189  uint8_t data[] = {190      // prologue191      0xa6, 0x02, 0x08, 0x7c, //  0: mflr r0192      0xf8, 0xff, 0xe1, 0xfb, //  4: std r31, -8(r1)193      0x10, 0x00, 0x01, 0xf8, //  8: std r0, 16(r1)194      0x78, 0x0b, 0x3e, 0x7c, // 12: mr r30, r1195      0xe0, 0x06, 0x20, 0x78, // 16: clrldi r0, r1, 59196      0xa0, 0xfa, 0x00, 0x20, // 20: subfic r0, r0, -1376197      0x6a, 0x01, 0x21, 0x7c, // 24: stdux r1, r1, r0198      0x78, 0x0b, 0x3f, 0x7c, // 28: mr r31, r1199 200      // epilogue201      0x00, 0x00, 0x21, 0xe8, // 32: ld r1, 0(r1)202      0x20, 0x00, 0x80, 0x4e  // 36: blr203  };204 205  sample_range = AddressRange(0x1000, sizeof(data));206 207  EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly(208      sample_range, data, sizeof(data), unwind_plan));209 210  // 0: CFA=sp+0211  row = unwind_plan.GetRowForFunctionOffset(0);212  EXPECT_EQ(0, row->GetOffset());213  EXPECT_TRUE(row->GetCFAValue().GetRegisterNumber() == gpr_r1_ppc64le);214  EXPECT_TRUE(row->GetCFAValue().IsRegisterPlusOffset() == true);215  EXPECT_EQ(0, row->GetCFAValue().GetOffset());216 217  // 1: CFA=sp+0 => fp=[CFA-8]218  row = unwind_plan.GetRowForFunctionOffset(8);219  EXPECT_EQ(8, row->GetOffset());220  EXPECT_TRUE(row->GetCFAValue().GetRegisterNumber() == gpr_r1_ppc64le);221  EXPECT_TRUE(row->GetCFAValue().IsRegisterPlusOffset() == true);222  EXPECT_EQ(0, row->GetCFAValue().GetOffset());223 224  EXPECT_TRUE(row->GetRegisterInfo(gpr_r31_ppc64le, regloc));225  EXPECT_TRUE(regloc.IsAtCFAPlusOffset());226  EXPECT_EQ(-8, regloc.GetOffset());227 228  // 2: CFA=sp+0 => fp=[CFA-8] lr=[CFA+16]229  row = unwind_plan.GetRowForFunctionOffset(12);230  EXPECT_EQ(12, row->GetOffset());231  EXPECT_TRUE(row->GetCFAValue().GetRegisterNumber() == gpr_r1_ppc64le);232  EXPECT_TRUE(row->GetCFAValue().IsRegisterPlusOffset() == true);233  EXPECT_EQ(0, row->GetCFAValue().GetOffset());234 235  EXPECT_TRUE(row->GetRegisterInfo(gpr_lr_ppc64le, regloc));236  EXPECT_TRUE(regloc.IsAtCFAPlusOffset());237  EXPECT_EQ(16, regloc.GetOffset());238 239  // 3: CFA=r30240  row = unwind_plan.GetRowForFunctionOffset(16);241  EXPECT_EQ(16, row->GetOffset());242  EXPECT_TRUE(row->GetCFAValue().GetRegisterNumber() == gpr_r30_ppc64le);243  EXPECT_TRUE(row->GetCFAValue().IsRegisterPlusOffset() == true);244  EXPECT_EQ(0, row->GetCFAValue().GetOffset());245 246  row = unwind_plan.GetRowForFunctionOffset(32);247  EXPECT_EQ(16, row->GetOffset());248  EXPECT_TRUE(row->GetCFAValue().GetRegisterNumber() == gpr_r30_ppc64le);249  EXPECT_TRUE(row->GetCFAValue().IsRegisterPlusOffset() == true);250  EXPECT_EQ(0, row->GetCFAValue().GetOffset());251 252  // 4: CFA=sp+0253  row = unwind_plan.GetRowForFunctionOffset(36);254  EXPECT_EQ(36, row->GetOffset());255  EXPECT_TRUE(row->GetCFAValue().GetRegisterNumber() == gpr_r1_ppc64le);256  EXPECT_TRUE(row->GetCFAValue().IsRegisterPlusOffset() == true);257  EXPECT_EQ(0, row->GetCFAValue().GetOffset());258}259