1*eb293b8fSAndroid Build Coastguard Worker /* 2*eb293b8fSAndroid Build Coastguard Worker * Copyright (C) 2017 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 <deque> 22*eb293b8fSAndroid Build Coastguard Worker #include <memory> 23*eb293b8fSAndroid Build Coastguard Worker #include <string> 24*eb293b8fSAndroid Build Coastguard Worker #include <unordered_map> 25*eb293b8fSAndroid Build Coastguard Worker 26*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/Elf.h> 27*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/ElfInterface.h> 28*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/Memory.h> 29*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/Regs.h> 30*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/SharedString.h> 31*eb293b8fSAndroid Build Coastguard Worker 32*eb293b8fSAndroid Build Coastguard Worker #include "ElfInterfaceArm.h" 33*eb293b8fSAndroid Build Coastguard Worker 34*eb293b8fSAndroid Build Coastguard Worker namespace unwindstack { 35*eb293b8fSAndroid Build Coastguard Worker 36*eb293b8fSAndroid Build Coastguard Worker struct StepData { StepDataStepData37*eb293b8fSAndroid Build Coastguard Worker StepData(uint64_t pc, uint64_t sp, bool finished) : pc(pc), sp(sp), finished(finished) {} 38*eb293b8fSAndroid Build Coastguard Worker uint64_t pc; 39*eb293b8fSAndroid Build Coastguard Worker uint64_t sp; 40*eb293b8fSAndroid Build Coastguard Worker bool finished; 41*eb293b8fSAndroid Build Coastguard Worker }; 42*eb293b8fSAndroid Build Coastguard Worker 43*eb293b8fSAndroid Build Coastguard Worker struct FunctionData { FunctionDataFunctionData44*eb293b8fSAndroid Build Coastguard Worker FunctionData(std::string name, uint64_t offset) : name(name), offset(offset) {} 45*eb293b8fSAndroid Build Coastguard Worker 46*eb293b8fSAndroid Build Coastguard Worker std::string name; 47*eb293b8fSAndroid Build Coastguard Worker uint64_t offset; 48*eb293b8fSAndroid Build Coastguard Worker }; 49*eb293b8fSAndroid Build Coastguard Worker 50*eb293b8fSAndroid Build Coastguard Worker class ElfFake : public Elf { 51*eb293b8fSAndroid Build Coastguard Worker public: ElfFake(std::shared_ptr<Memory> & memory)52*eb293b8fSAndroid Build Coastguard Worker ElfFake(std::shared_ptr<Memory>& memory) : Elf(memory) { valid_ = true; } 53*eb293b8fSAndroid Build Coastguard Worker virtual ~ElfFake() = default; 54*eb293b8fSAndroid Build Coastguard Worker FakeSetValid(bool valid)55*eb293b8fSAndroid Build Coastguard Worker void FakeSetValid(bool valid) { valid_ = valid; } 56*eb293b8fSAndroid Build Coastguard Worker FakeSetLoadBias(uint64_t load_bias)57*eb293b8fSAndroid Build Coastguard Worker void FakeSetLoadBias(uint64_t load_bias) { load_bias_ = load_bias; } 58*eb293b8fSAndroid Build Coastguard Worker FakeSetArch(ArchEnum arch)59*eb293b8fSAndroid Build Coastguard Worker void FakeSetArch(ArchEnum arch) { arch_ = arch; } 60*eb293b8fSAndroid Build Coastguard Worker FakeSetInterface(ElfInterface * interface)61*eb293b8fSAndroid Build Coastguard Worker void FakeSetInterface(ElfInterface* interface) { interface_.reset(interface); } FakeSetGnuDebugdataInterface(ElfInterface * interface)62*eb293b8fSAndroid Build Coastguard Worker void FakeSetGnuDebugdataInterface(ElfInterface* interface) { 63*eb293b8fSAndroid Build Coastguard Worker gnu_debugdata_interface_.reset(interface); 64*eb293b8fSAndroid Build Coastguard Worker } 65*eb293b8fSAndroid Build Coastguard Worker }; 66*eb293b8fSAndroid Build Coastguard Worker 67*eb293b8fSAndroid Build Coastguard Worker class ElfInterfaceFake : public ElfInterface { 68*eb293b8fSAndroid Build Coastguard Worker public: ElfInterfaceFake(std::shared_ptr<Memory> & memory)69*eb293b8fSAndroid Build Coastguard Worker ElfInterfaceFake(std::shared_ptr<Memory>& memory) : ElfInterface(memory) {} 70*eb293b8fSAndroid Build Coastguard Worker virtual ~ElfInterfaceFake() = default; 71*eb293b8fSAndroid Build Coastguard Worker Init(int64_t *)72*eb293b8fSAndroid Build Coastguard Worker bool Init(int64_t*) override { return false; } InitHeaders()73*eb293b8fSAndroid Build Coastguard Worker void InitHeaders() override {} GetSoname()74*eb293b8fSAndroid Build Coastguard Worker std::string GetSoname() override { return fake_soname_; } 75*eb293b8fSAndroid Build Coastguard Worker 76*eb293b8fSAndroid Build Coastguard Worker bool GetFunctionName(uint64_t, SharedString*, uint64_t*) override; 77*eb293b8fSAndroid Build Coastguard Worker bool GetGlobalVariable(const std::string&, uint64_t*) override; GetBuildID()78*eb293b8fSAndroid Build Coastguard Worker std::string GetBuildID() override { return fake_build_id_; } 79*eb293b8fSAndroid Build Coastguard Worker 80*eb293b8fSAndroid Build Coastguard Worker bool Step(uint64_t, Regs*, Memory*, bool*, bool*) override; 81*eb293b8fSAndroid Build Coastguard Worker FakeSetGlobalVariable(const std::string & global,uint64_t offset)82*eb293b8fSAndroid Build Coastguard Worker void FakeSetGlobalVariable(const std::string& global, uint64_t offset) { 83*eb293b8fSAndroid Build Coastguard Worker globals_[global] = offset; 84*eb293b8fSAndroid Build Coastguard Worker } 85*eb293b8fSAndroid Build Coastguard Worker FakeSetBuildID(std::string & build_id)86*eb293b8fSAndroid Build Coastguard Worker void FakeSetBuildID(std::string& build_id) { fake_build_id_ = build_id; } FakeSetBuildID(const char * build_id)87*eb293b8fSAndroid Build Coastguard Worker void FakeSetBuildID(const char* build_id) { fake_build_id_ = build_id; } 88*eb293b8fSAndroid Build Coastguard Worker FakeSetSoname(const char * soname)89*eb293b8fSAndroid Build Coastguard Worker void FakeSetSoname(const char* soname) { fake_soname_ = soname; } 90*eb293b8fSAndroid Build Coastguard Worker FakePushFunctionData(const FunctionData data)91*eb293b8fSAndroid Build Coastguard Worker static void FakePushFunctionData(const FunctionData data) { functions_.push_back(data); } FakePushStepData(const StepData data)92*eb293b8fSAndroid Build Coastguard Worker static void FakePushStepData(const StepData data) { steps_.push_back(data); } 93*eb293b8fSAndroid Build Coastguard Worker FakeClear()94*eb293b8fSAndroid Build Coastguard Worker static void FakeClear() { 95*eb293b8fSAndroid Build Coastguard Worker functions_.clear(); 96*eb293b8fSAndroid Build Coastguard Worker steps_.clear(); 97*eb293b8fSAndroid Build Coastguard Worker } 98*eb293b8fSAndroid Build Coastguard Worker FakeSetErrorCode(ErrorCode code)99*eb293b8fSAndroid Build Coastguard Worker void FakeSetErrorCode(ErrorCode code) { last_error_.code = code; } 100*eb293b8fSAndroid Build Coastguard Worker FakeSetErrorAddress(uint64_t address)101*eb293b8fSAndroid Build Coastguard Worker void FakeSetErrorAddress(uint64_t address) { last_error_.address = address; } 102*eb293b8fSAndroid Build Coastguard Worker FakeSetDataOffset(uint64_t offset)103*eb293b8fSAndroid Build Coastguard Worker void FakeSetDataOffset(uint64_t offset) { data_offset_ = offset; } FakeSetDataVaddrStart(uint64_t vaddr)104*eb293b8fSAndroid Build Coastguard Worker void FakeSetDataVaddrStart(uint64_t vaddr) { data_vaddr_start_ = vaddr; } FakeSetDataVaddrEnd(uint64_t vaddr)105*eb293b8fSAndroid Build Coastguard Worker void FakeSetDataVaddrEnd(uint64_t vaddr) { data_vaddr_end_ = vaddr; } 106*eb293b8fSAndroid Build Coastguard Worker FakeSetDynamicOffset(uint64_t offset)107*eb293b8fSAndroid Build Coastguard Worker void FakeSetDynamicOffset(uint64_t offset) { dynamic_offset_ = offset; } FakeSetDynamicVaddrStart(uint64_t vaddr)108*eb293b8fSAndroid Build Coastguard Worker void FakeSetDynamicVaddrStart(uint64_t vaddr) { dynamic_vaddr_start_ = vaddr; } FakeSetDynamicVaddrEnd(uint64_t vaddr)109*eb293b8fSAndroid Build Coastguard Worker void FakeSetDynamicVaddrEnd(uint64_t vaddr) { dynamic_vaddr_end_ = vaddr; } 110*eb293b8fSAndroid Build Coastguard Worker FakeSetGnuDebugdataOffset(uint64_t offset)111*eb293b8fSAndroid Build Coastguard Worker void FakeSetGnuDebugdataOffset(uint64_t offset) { gnu_debugdata_offset_ = offset; } FakeSetGnuDebugdataSize(uint64_t size)112*eb293b8fSAndroid Build Coastguard Worker void FakeSetGnuDebugdataSize(uint64_t size) { gnu_debugdata_size_ = size; } 113*eb293b8fSAndroid Build Coastguard Worker 114*eb293b8fSAndroid Build Coastguard Worker private: 115*eb293b8fSAndroid Build Coastguard Worker std::unordered_map<std::string, uint64_t> globals_; 116*eb293b8fSAndroid Build Coastguard Worker std::string fake_build_id_; 117*eb293b8fSAndroid Build Coastguard Worker std::string fake_soname_; 118*eb293b8fSAndroid Build Coastguard Worker 119*eb293b8fSAndroid Build Coastguard Worker static std::deque<FunctionData> functions_; 120*eb293b8fSAndroid Build Coastguard Worker static std::deque<StepData> steps_; 121*eb293b8fSAndroid Build Coastguard Worker }; 122*eb293b8fSAndroid Build Coastguard Worker 123*eb293b8fSAndroid Build Coastguard Worker class ElfInterface32Fake : public ElfInterface32 { 124*eb293b8fSAndroid Build Coastguard Worker public: ElfInterface32Fake(std::shared_ptr<Memory> & memory)125*eb293b8fSAndroid Build Coastguard Worker ElfInterface32Fake(std::shared_ptr<Memory>& memory) : ElfInterface32(memory) {} 126*eb293b8fSAndroid Build Coastguard Worker virtual ~ElfInterface32Fake() = default; 127*eb293b8fSAndroid Build Coastguard Worker FakeSetEhFrameInfo(const SectionInfo & info)128*eb293b8fSAndroid Build Coastguard Worker void FakeSetEhFrameInfo(const SectionInfo& info) { eh_frame_info_ = info; } FakeSetEhFrameHdrInfo(const SectionInfo & info)129*eb293b8fSAndroid Build Coastguard Worker void FakeSetEhFrameHdrInfo(const SectionInfo& info) { eh_frame_hdr_info_ = info; } FakeSetDebugFrameInfo(const SectionInfo & info)130*eb293b8fSAndroid Build Coastguard Worker void FakeSetDebugFrameInfo(const SectionInfo& info) { debug_frame_info_ = info; } 131*eb293b8fSAndroid Build Coastguard Worker }; 132*eb293b8fSAndroid Build Coastguard Worker 133*eb293b8fSAndroid Build Coastguard Worker class ElfInterface64Fake : public ElfInterface64 { 134*eb293b8fSAndroid Build Coastguard Worker public: ElfInterface64Fake(std::shared_ptr<Memory> & memory)135*eb293b8fSAndroid Build Coastguard Worker ElfInterface64Fake(std::shared_ptr<Memory>& memory) : ElfInterface64(memory) {} 136*eb293b8fSAndroid Build Coastguard Worker virtual ~ElfInterface64Fake() = default; 137*eb293b8fSAndroid Build Coastguard Worker FakeSetEhFrameInfo(const SectionInfo & info)138*eb293b8fSAndroid Build Coastguard Worker void FakeSetEhFrameInfo(const SectionInfo& info) { eh_frame_info_ = info; } FakeSetEhFrameHdrInfo(const SectionInfo & info)139*eb293b8fSAndroid Build Coastguard Worker void FakeSetEhFrameHdrInfo(const SectionInfo& info) { eh_frame_hdr_info_ = info; } FakeSetDebugFrameInfo(const SectionInfo & info)140*eb293b8fSAndroid Build Coastguard Worker void FakeSetDebugFrameInfo(const SectionInfo& info) { debug_frame_info_ = info; } 141*eb293b8fSAndroid Build Coastguard Worker }; 142*eb293b8fSAndroid Build Coastguard Worker 143*eb293b8fSAndroid Build Coastguard Worker class ElfInterfaceArmFake : public ElfInterfaceArm { 144*eb293b8fSAndroid Build Coastguard Worker public: ElfInterfaceArmFake(std::shared_ptr<Memory> & memory)145*eb293b8fSAndroid Build Coastguard Worker ElfInterfaceArmFake(std::shared_ptr<Memory>& memory) : ElfInterfaceArm(memory) {} 146*eb293b8fSAndroid Build Coastguard Worker virtual ~ElfInterfaceArmFake() = default; 147*eb293b8fSAndroid Build Coastguard Worker FakeSetStartOffset(uint64_t offset)148*eb293b8fSAndroid Build Coastguard Worker void FakeSetStartOffset(uint64_t offset) { start_offset_ = offset; } FakeSetTotalEntries(size_t entries)149*eb293b8fSAndroid Build Coastguard Worker void FakeSetTotalEntries(size_t entries) { total_entries_ = entries; } 150*eb293b8fSAndroid Build Coastguard Worker }; 151*eb293b8fSAndroid Build Coastguard Worker 152*eb293b8fSAndroid Build Coastguard Worker } // namespace unwindstack 153