brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.3 KiB · 009b9cd Raw
189 lines · cpp
1//===-- TestRiscvInstEmulation.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 "Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h"12 13#include "lldb/Core/AddressRange.h"14#include "lldb/Symbol/UnwindPlan.h"15#include "lldb/Utility/ArchSpec.h"16 17#include "Plugins/Disassembler/LLVMC/DisassemblerLLVMC.h"18#include "Plugins/Instruction/RISCV/EmulateInstructionRISCV.h"19#include "Plugins/Process/Utility/lldb-riscv-register-enums.h"20#include "llvm/Support/TargetSelect.h"21 22using namespace lldb;23using namespace lldb_private;24 25class TestRiscvInstEmulation : public testing::Test {26public:27  static void SetUpTestCase();28  static void TearDownTestCase();29 30protected:31};32 33void TestRiscvInstEmulation::SetUpTestCase() {34  llvm::InitializeAllTargets();35  llvm::InitializeAllAsmPrinters();36  llvm::InitializeAllTargetMCs();37  llvm::InitializeAllDisassemblers();38  DisassemblerLLVMC::Initialize();39  EmulateInstructionRISCV::Initialize();40}41 42void TestRiscvInstEmulation::TearDownTestCase() {43  DisassemblerLLVMC::Terminate();44  EmulateInstructionRISCV::Terminate();45}46 47TEST_F(TestRiscvInstEmulation, TestSimpleRiscvFunction) {48  ArchSpec arch("riscv64-unknown-linux-gnu");49  // Enable compressed instruction support (RVC extension).50  arch.SetFlags(ArchSpec::eRISCV_rvc);51  std::unique_ptr<UnwindAssemblyInstEmulation> engine(52      static_cast<UnwindAssemblyInstEmulation *>(53          UnwindAssemblyInstEmulation::CreateInstance(arch)));54  ASSERT_NE(nullptr, engine);55 56  // RISC-V function with compressed and uncompressed instructions57  //   0x0000: 1141          addi    sp, sp, -0x1058  //   0x0002: e406          sd      ra, 0x8(sp)59  //   0x0004: e022          sd      s0, 0x0(sp)60  //   0x0006: 0800          addi    s0, sp, 0x1061  //   0x0008: 00000537      lui     a0, 0x062  //   0x000C: 00050513      mv      a0, a063  //   0x0010: 00000097      auipc   ra, 0x064  //   0x0014: 000080e7      jalr    ra <main+0x10>65  //   0x0018: 4501          li      a0, 0x066  //   0x001A: ff040113      addi    sp, s0, -0x1067  //   0x001E: 60a2          ld      ra, 0x8(sp)68  //   0x0020: 6402          ld      s0, 0x0(sp)69  //   0x0022: 0141          addi    sp, sp, 0x1070  //   0x0024: 8082          ret71  uint8_t data[] = {// 0x0000: 1141          addi sp, sp, -0x1072                    0x41, 0x11,73                    // 0x0002: e406          sd ra, 0x8(sp)74                    0x06, 0xE4,75                    // 0x0004: e022          sd s0, 0x0(sp)76                    0x22, 0xE0,77                    // 0x0006: 0800          addi s0, sp, 0x1078                    0x00, 0x08,79                    // 0x0008: 00000537      lui a0, 0x080                    0x37, 0x05, 0x00, 0x00,81                    // 0x000C: 00050513      mv a0, a082                    0x13, 0x05, 0x05, 0x00,83                    // 0x0010: 00000097      auipc ra, 0x084                    0x97, 0x00, 0x00, 0x00,85                    // 0x0014: 000080e7      jalr ra <main+0x10>86                    0xE7, 0x80, 0x00, 0x00,87                    // 0x0018: 4501          li a0, 0x088                    0x01, 0x45,89                    // 0x001A: ff040113      addi sp, s0, -0x1090                    0x13, 0x01, 0x04, 0xFF,91                    // 0x001E: 60a2          ld ra, 0x8(sp)92                    0xA2, 0x60,93                    // 0x0020: 6402          ld s0, 0x0(sp)94                    0x02, 0x64,95                    // 0x0022: 0141          addi sp, sp, 0x1096                    0x41, 0x01,97                    // 0x0024: 8082          ret98                    0x82, 0x80};99 100  // Expected UnwindPlan (prologue only - emulation stops after frame setup):101  // row[0]:    0:  CFA=sp+0   => fp= <same>        ra= <same>102  // row[1]:    2:  CFA=sp+16  => fp= <same>        ra= <same>      (after stack103  // allocation) row[2]:    4:  CFA=sp+16  => fp= <same>        ra=[CFA-8]104  // (after saving ra) row[3]:    6:  CFA=sp+16  => fp=[CFA-16]       ra=[CFA-8]105  // (after saving s0/fp) row[4]:    8:  CFA=s0+0   => fp=[CFA-16] ra=[CFA-8]106  // (after setting frame pointer: s0=sp+16)107 108  const UnwindPlan::Row *row;109  AddressRange sample_range;110  UnwindPlan unwind_plan(eRegisterKindLLDB);111  UnwindPlan::Row::AbstractRegisterLocation regloc;112  sample_range = AddressRange(0x1000, sizeof(data));113 114  EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly(115      sample_range, data, sizeof(data), unwind_plan));116 117  // CFA=sp+0 => fp=<same> ra=<same>.118  row = unwind_plan.GetRowForFunctionOffset(0);119  EXPECT_EQ(0, row->GetOffset());120  EXPECT_TRUE(row->GetCFAValue().GetRegisterNumber() == gpr_sp_riscv);121  EXPECT_TRUE(row->GetCFAValue().IsRegisterPlusOffset() == true);122  EXPECT_EQ(0, row->GetCFAValue().GetOffset());123 124  EXPECT_TRUE(row->GetRegisterInfo(gpr_fp_riscv, regloc));125  EXPECT_TRUE(regloc.IsSame());126 127  EXPECT_TRUE(row->GetRegisterInfo(gpr_ra_riscv, regloc));128  EXPECT_TRUE(regloc.IsSame());129 130  // CFA=sp+16 => fp=<same> ra=<same>.131  row = unwind_plan.GetRowForFunctionOffset(2);132  EXPECT_EQ(2, row->GetOffset());133  EXPECT_TRUE(row->GetCFAValue().GetRegisterNumber() == gpr_sp_riscv);134  EXPECT_TRUE(row->GetCFAValue().IsRegisterPlusOffset() == true);135  EXPECT_EQ(16, row->GetCFAValue().GetOffset());136 137  EXPECT_TRUE(row->GetRegisterInfo(gpr_fp_riscv, regloc));138  EXPECT_TRUE(regloc.IsSame());139 140  EXPECT_TRUE(row->GetRegisterInfo(gpr_ra_riscv, regloc));141  EXPECT_TRUE(regloc.IsSame());142 143  // CFA=sp+16 => fp=<same> ra=[CFA-8].144  row = unwind_plan.GetRowForFunctionOffset(4);145  EXPECT_EQ(4, row->GetOffset());146  EXPECT_TRUE(row->GetCFAValue().GetRegisterNumber() == gpr_sp_riscv);147  EXPECT_TRUE(row->GetCFAValue().IsRegisterPlusOffset() == true);148  EXPECT_EQ(16, row->GetCFAValue().GetOffset());149 150  EXPECT_TRUE(row->GetRegisterInfo(gpr_fp_riscv, regloc));151  EXPECT_TRUE(regloc.IsSame());152 153  EXPECT_TRUE(row->GetRegisterInfo(gpr_ra_riscv, regloc));154  EXPECT_TRUE(regloc.IsAtCFAPlusOffset());155  EXPECT_EQ(-8, regloc.GetOffset());156 157  // CFA=sp+16 => fp=[CFA-16] ra=[CFA-8]158  row = unwind_plan.GetRowForFunctionOffset(6);159  EXPECT_EQ(6, row->GetOffset());160  EXPECT_TRUE(row->GetCFAValue().GetRegisterNumber() == gpr_sp_riscv);161  EXPECT_TRUE(row->GetCFAValue().IsRegisterPlusOffset() == true);162  EXPECT_EQ(16, row->GetCFAValue().GetOffset());163 164  EXPECT_TRUE(row->GetRegisterInfo(gpr_fp_riscv, regloc));165  EXPECT_TRUE(regloc.IsAtCFAPlusOffset());166  EXPECT_EQ(-16, regloc.GetOffset());167 168  EXPECT_TRUE(row->GetRegisterInfo(gpr_ra_riscv, regloc));169  EXPECT_TRUE(regloc.IsAtCFAPlusOffset());170  EXPECT_EQ(-8, regloc.GetOffset());171 172  // CFA=s0+0 => fp=[CFA-16] ra=[CFA-8]173  // s0 = sp + 16, so switching CFA to s0 does not change the effective174  // locations.175  row = unwind_plan.GetRowForFunctionOffset(8);176  EXPECT_EQ(8, row->GetOffset());177  EXPECT_TRUE(row->GetCFAValue().GetRegisterNumber() == gpr_fp_riscv);178  EXPECT_TRUE(row->GetCFAValue().IsRegisterPlusOffset() == true);179  EXPECT_EQ(0, row->GetCFAValue().GetOffset());180 181  EXPECT_TRUE(row->GetRegisterInfo(gpr_fp_riscv, regloc));182  EXPECT_TRUE(regloc.IsAtCFAPlusOffset());183  EXPECT_EQ(-16, regloc.GetOffset());184 185  EXPECT_TRUE(row->GetRegisterInfo(gpr_ra_riscv, regloc));186  EXPECT_TRUE(regloc.IsAtCFAPlusOffset());187  EXPECT_EQ(-8, regloc.GetOffset());188}189