1*eb293b8fSAndroid Build Coastguard Worker /* 2*eb293b8fSAndroid Build Coastguard Worker * Copyright (C) 2016 The Android Open Source Project 3*eb293b8fSAndroid Build Coastguard Worker * 4*eb293b8fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*eb293b8fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*eb293b8fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*eb293b8fSAndroid Build Coastguard Worker * 8*eb293b8fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*eb293b8fSAndroid Build Coastguard Worker * 10*eb293b8fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*eb293b8fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*eb293b8fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*eb293b8fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*eb293b8fSAndroid Build Coastguard Worker * limitations under the License. 15*eb293b8fSAndroid Build Coastguard Worker */ 16*eb293b8fSAndroid Build Coastguard Worker 17*eb293b8fSAndroid Build Coastguard Worker #pragma once 18*eb293b8fSAndroid Build Coastguard Worker 19*eb293b8fSAndroid Build Coastguard Worker #include <stdint.h> 20*eb293b8fSAndroid Build Coastguard Worker 21*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/Elf.h> 22*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/Memory.h> 23*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/Regs.h> 24*eb293b8fSAndroid Build Coastguard Worker 25*eb293b8fSAndroid Build Coastguard Worker #include "Check.h" 26*eb293b8fSAndroid Build Coastguard Worker 27*eb293b8fSAndroid Build Coastguard Worker namespace unwindstack { 28*eb293b8fSAndroid Build Coastguard Worker 29*eb293b8fSAndroid Build Coastguard Worker class RegsFake : public Regs { 30*eb293b8fSAndroid Build Coastguard Worker public: RegsFake(uint16_t total_regs)31*eb293b8fSAndroid Build Coastguard Worker RegsFake(uint16_t total_regs) : Regs(total_regs, Regs::Location(Regs::LOCATION_UNKNOWN, 0)) {} 32*eb293b8fSAndroid Build Coastguard Worker virtual ~RegsFake() = default; 33*eb293b8fSAndroid Build Coastguard Worker Arch()34*eb293b8fSAndroid Build Coastguard Worker ArchEnum Arch() override { return fake_arch_; } RawData()35*eb293b8fSAndroid Build Coastguard Worker void* RawData() override { return nullptr; } pc()36*eb293b8fSAndroid Build Coastguard Worker uint64_t pc() override { return fake_pc_; } sp()37*eb293b8fSAndroid Build Coastguard Worker uint64_t sp() override { return fake_sp_; } set_pc(uint64_t pc)38*eb293b8fSAndroid Build Coastguard Worker void set_pc(uint64_t pc) override { fake_pc_ = pc; } set_sp(uint64_t sp)39*eb293b8fSAndroid Build Coastguard Worker void set_sp(uint64_t sp) override { fake_sp_ = sp; } 40*eb293b8fSAndroid Build Coastguard Worker SetPcFromReturnAddress(Memory *)41*eb293b8fSAndroid Build Coastguard Worker bool SetPcFromReturnAddress(Memory*) override { 42*eb293b8fSAndroid Build Coastguard Worker if (!fake_return_address_valid_) { 43*eb293b8fSAndroid Build Coastguard Worker return false; 44*eb293b8fSAndroid Build Coastguard Worker } 45*eb293b8fSAndroid Build Coastguard Worker fake_pc_ = fake_return_address_; 46*eb293b8fSAndroid Build Coastguard Worker return true; 47*eb293b8fSAndroid Build Coastguard Worker } 48*eb293b8fSAndroid Build Coastguard Worker IterateRegisters(std::function<void (const char *,uint64_t)>)49*eb293b8fSAndroid Build Coastguard Worker void IterateRegisters(std::function<void(const char*, uint64_t)>) override {} 50*eb293b8fSAndroid Build Coastguard Worker Is32Bit()51*eb293b8fSAndroid Build Coastguard Worker bool Is32Bit() { 52*eb293b8fSAndroid Build Coastguard Worker CHECK(fake_arch_ != ARCH_UNKNOWN); 53*eb293b8fSAndroid Build Coastguard Worker return fake_arch_ == ARCH_ARM || fake_arch_ == ARCH_X86; 54*eb293b8fSAndroid Build Coastguard Worker } 55*eb293b8fSAndroid Build Coastguard Worker StepIfSignalHandler(uint64_t,Elf *,Memory *)56*eb293b8fSAndroid Build Coastguard Worker bool StepIfSignalHandler(uint64_t, Elf*, Memory*) override { return false; } 57*eb293b8fSAndroid Build Coastguard Worker FakeSetArch(ArchEnum arch)58*eb293b8fSAndroid Build Coastguard Worker void FakeSetArch(ArchEnum arch) { fake_arch_ = arch; } FakeSetDexPc(uint64_t dex_pc)59*eb293b8fSAndroid Build Coastguard Worker void FakeSetDexPc(uint64_t dex_pc) { dex_pc_ = dex_pc; } FakeSetReturnAddress(uint64_t return_address)60*eb293b8fSAndroid Build Coastguard Worker void FakeSetReturnAddress(uint64_t return_address) { fake_return_address_ = return_address; } FakeSetReturnAddressValid(bool valid)61*eb293b8fSAndroid Build Coastguard Worker void FakeSetReturnAddressValid(bool valid) { fake_return_address_valid_ = valid; } 62*eb293b8fSAndroid Build Coastguard Worker Clone()63*eb293b8fSAndroid Build Coastguard Worker Regs* Clone() override { return nullptr; } 64*eb293b8fSAndroid Build Coastguard Worker 65*eb293b8fSAndroid Build Coastguard Worker private: 66*eb293b8fSAndroid Build Coastguard Worker ArchEnum fake_arch_ = ARCH_UNKNOWN; 67*eb293b8fSAndroid Build Coastguard Worker uint64_t fake_pc_ = 0; 68*eb293b8fSAndroid Build Coastguard Worker uint64_t fake_sp_ = 0; 69*eb293b8fSAndroid Build Coastguard Worker bool fake_return_address_valid_ = false; 70*eb293b8fSAndroid Build Coastguard Worker uint64_t fake_return_address_ = 0; 71*eb293b8fSAndroid Build Coastguard Worker }; 72*eb293b8fSAndroid Build Coastguard Worker 73*eb293b8fSAndroid Build Coastguard Worker template <typename TypeParam> 74*eb293b8fSAndroid Build Coastguard Worker class RegsImplFake : public RegsImpl<TypeParam> { 75*eb293b8fSAndroid Build Coastguard Worker public: RegsImplFake(uint16_t total_regs)76*eb293b8fSAndroid Build Coastguard Worker RegsImplFake(uint16_t total_regs) 77*eb293b8fSAndroid Build Coastguard Worker : RegsImpl<TypeParam>(total_regs, Regs::Location(Regs::LOCATION_UNKNOWN, 0)) {} 78*eb293b8fSAndroid Build Coastguard Worker virtual ~RegsImplFake() = default; 79*eb293b8fSAndroid Build Coastguard Worker Arch()80*eb293b8fSAndroid Build Coastguard Worker ArchEnum Arch() override { return ARCH_UNKNOWN; } pc()81*eb293b8fSAndroid Build Coastguard Worker uint64_t pc() override { return fake_pc_; } sp()82*eb293b8fSAndroid Build Coastguard Worker uint64_t sp() override { return fake_sp_; } set_pc(uint64_t pc)83*eb293b8fSAndroid Build Coastguard Worker void set_pc(uint64_t pc) override { fake_pc_ = pc; } set_sp(uint64_t sp)84*eb293b8fSAndroid Build Coastguard Worker void set_sp(uint64_t sp) override { fake_sp_ = sp; } set_pseudo_reg(uint64_t reg)85*eb293b8fSAndroid Build Coastguard Worker void set_pseudo_reg(uint64_t reg) { fake_pseudo_reg_ = reg; } 86*eb293b8fSAndroid Build Coastguard Worker SetPcFromReturnAddress(Memory *)87*eb293b8fSAndroid Build Coastguard Worker bool SetPcFromReturnAddress(Memory*) override { return false; } StepIfSignalHandler(uint64_t,Elf *,Memory *)88*eb293b8fSAndroid Build Coastguard Worker bool StepIfSignalHandler(uint64_t, Elf*, Memory*) override { return false; } 89*eb293b8fSAndroid Build Coastguard Worker SetPseudoRegister(uint16_t reg,uint64_t value)90*eb293b8fSAndroid Build Coastguard Worker bool SetPseudoRegister(uint16_t reg, uint64_t value) override { 91*eb293b8fSAndroid Build Coastguard Worker if (fake_pseudo_reg_ != reg) { 92*eb293b8fSAndroid Build Coastguard Worker return false; 93*eb293b8fSAndroid Build Coastguard Worker } 94*eb293b8fSAndroid Build Coastguard Worker fake_pseudo_reg_value_ = value; 95*eb293b8fSAndroid Build Coastguard Worker return true; 96*eb293b8fSAndroid Build Coastguard Worker } GetPseudoRegister(uint16_t reg,uint64_t * value)97*eb293b8fSAndroid Build Coastguard Worker bool GetPseudoRegister(uint16_t reg, uint64_t* value) override { 98*eb293b8fSAndroid Build Coastguard Worker if (fake_pseudo_reg_ != reg) { 99*eb293b8fSAndroid Build Coastguard Worker return false; 100*eb293b8fSAndroid Build Coastguard Worker } 101*eb293b8fSAndroid Build Coastguard Worker *value = fake_pseudo_reg_value_; 102*eb293b8fSAndroid Build Coastguard Worker return true; 103*eb293b8fSAndroid Build Coastguard Worker } 104*eb293b8fSAndroid Build Coastguard Worker Clone()105*eb293b8fSAndroid Build Coastguard Worker Regs* Clone() override { return nullptr; } 106*eb293b8fSAndroid Build Coastguard Worker 107*eb293b8fSAndroid Build Coastguard Worker private: 108*eb293b8fSAndroid Build Coastguard Worker uint64_t fake_pc_ = 0; 109*eb293b8fSAndroid Build Coastguard Worker uint64_t fake_sp_ = 0; 110*eb293b8fSAndroid Build Coastguard Worker uint16_t fake_pseudo_reg_ = 0; 111*eb293b8fSAndroid Build Coastguard Worker uint64_t fake_pseudo_reg_value_ = 0; 112*eb293b8fSAndroid Build Coastguard Worker }; 113*eb293b8fSAndroid Build Coastguard Worker 114*eb293b8fSAndroid Build Coastguard Worker } // namespace unwindstack 115