1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef _LIBUNWINDSTACK_TESTS_ELF_FAKE_H 18 #define _LIBUNWINDSTACK_TESTS_ELF_FAKE_H 19 20 #include <stdint.h> 21 22 #include <deque> 23 #include <string> 24 #include <unordered_map> 25 26 #include <unwindstack/Elf.h> 27 #include <unwindstack/ElfInterface.h> 28 #include <unwindstack/Memory.h> 29 #include <unwindstack/Regs.h> 30 #include <unwindstack/SharedString.h> 31 32 #include "ElfInterfaceArm.h" 33 34 namespace unwindstack { 35 36 struct StepData { StepDataStepData37 StepData(uint64_t pc, uint64_t sp, bool finished) : pc(pc), sp(sp), finished(finished) {} 38 uint64_t pc; 39 uint64_t sp; 40 bool finished; 41 }; 42 43 struct FunctionData { FunctionDataFunctionData44 FunctionData(std::string name, uint64_t offset) : name(name), offset(offset) {} 45 46 std::string name; 47 uint64_t offset; 48 }; 49 50 class ElfFake : public Elf { 51 public: ElfFake(Memory * memory)52 ElfFake(Memory* memory) : Elf(memory) { valid_ = true; } 53 virtual ~ElfFake() = default; 54 FakeSetValid(bool valid)55 void FakeSetValid(bool valid) { valid_ = valid; } 56 FakeSetLoadBias(uint64_t load_bias)57 void FakeSetLoadBias(uint64_t load_bias) { load_bias_ = load_bias; } 58 FakeSetArch(ArchEnum arch)59 void FakeSetArch(ArchEnum arch) { arch_ = arch; } 60 FakeSetInterface(ElfInterface * interface)61 void FakeSetInterface(ElfInterface* interface) { interface_.reset(interface); } FakeSetGnuDebugdataInterface(ElfInterface * interface)62 void FakeSetGnuDebugdataInterface(ElfInterface* interface) { 63 gnu_debugdata_interface_.reset(interface); 64 } 65 }; 66 67 class ElfInterfaceFake : public ElfInterface { 68 public: ElfInterfaceFake(Memory * memory)69 ElfInterfaceFake(Memory* memory) : ElfInterface(memory) {} 70 virtual ~ElfInterfaceFake() = default; 71 Init(int64_t *)72 bool Init(int64_t*) override { return false; } InitHeaders()73 void InitHeaders() override {} GetSoname()74 std::string GetSoname() override { return fake_soname_; } 75 76 bool GetFunctionName(uint64_t, SharedString*, uint64_t*) override; 77 bool GetGlobalVariable(const std::string&, uint64_t*) override; GetBuildID()78 std::string GetBuildID() override { return fake_build_id_; } 79 80 bool Step(uint64_t, Regs*, Memory*, bool*, bool*) override; 81 FakeSetGlobalVariable(const std::string & global,uint64_t offset)82 void FakeSetGlobalVariable(const std::string& global, uint64_t offset) { 83 globals_[global] = offset; 84 } 85 FakeSetBuildID(std::string & build_id)86 void FakeSetBuildID(std::string& build_id) { fake_build_id_ = build_id; } FakeSetBuildID(const char * build_id)87 void FakeSetBuildID(const char* build_id) { fake_build_id_ = build_id; } 88 FakeSetSoname(const char * soname)89 void FakeSetSoname(const char* soname) { fake_soname_ = soname; } 90 FakePushFunctionData(const FunctionData data)91 static void FakePushFunctionData(const FunctionData data) { functions_.push_back(data); } FakePushStepData(const StepData data)92 static void FakePushStepData(const StepData data) { steps_.push_back(data); } 93 FakeClear()94 static void FakeClear() { 95 functions_.clear(); 96 steps_.clear(); 97 } 98 FakeSetErrorCode(ErrorCode code)99 void FakeSetErrorCode(ErrorCode code) { last_error_.code = code; } 100 FakeSetErrorAddress(uint64_t address)101 void FakeSetErrorAddress(uint64_t address) { last_error_.address = address; } 102 FakeSetDataOffset(uint64_t offset)103 void FakeSetDataOffset(uint64_t offset) { data_offset_ = offset; } FakeSetDataVaddrStart(uint64_t vaddr)104 void FakeSetDataVaddrStart(uint64_t vaddr) { data_vaddr_start_ = vaddr; } FakeSetDataVaddrEnd(uint64_t vaddr)105 void FakeSetDataVaddrEnd(uint64_t vaddr) { data_vaddr_end_ = vaddr; } 106 FakeSetDynamicOffset(uint64_t offset)107 void FakeSetDynamicOffset(uint64_t offset) { dynamic_offset_ = offset; } FakeSetDynamicVaddrStart(uint64_t vaddr)108 void FakeSetDynamicVaddrStart(uint64_t vaddr) { dynamic_vaddr_start_ = vaddr; } FakeSetDynamicVaddrEnd(uint64_t vaddr)109 void FakeSetDynamicVaddrEnd(uint64_t vaddr) { dynamic_vaddr_end_ = vaddr; } 110 FakeSetGnuDebugdataOffset(uint64_t offset)111 void FakeSetGnuDebugdataOffset(uint64_t offset) { gnu_debugdata_offset_ = offset; } FakeSetGnuDebugdataSize(uint64_t size)112 void FakeSetGnuDebugdataSize(uint64_t size) { gnu_debugdata_size_ = size; } 113 114 private: 115 std::unordered_map<std::string, uint64_t> globals_; 116 std::string fake_build_id_; 117 std::string fake_soname_; 118 119 static std::deque<FunctionData> functions_; 120 static std::deque<StepData> steps_; 121 }; 122 123 class ElfInterface32Fake : public ElfInterface32 { 124 public: ElfInterface32Fake(Memory * memory)125 ElfInterface32Fake(Memory* memory) : ElfInterface32(memory) {} 126 virtual ~ElfInterface32Fake() = default; 127 FakeSetEhFrameOffset(uint64_t offset)128 void FakeSetEhFrameOffset(uint64_t offset) { eh_frame_offset_ = offset; } FakeSetEhFrameSize(uint64_t size)129 void FakeSetEhFrameSize(uint64_t size) { eh_frame_size_ = size; } FakeSetDebugFrameOffset(uint64_t offset)130 void FakeSetDebugFrameOffset(uint64_t offset) { debug_frame_offset_ = offset; } FakeSetDebugFrameSize(uint64_t size)131 void FakeSetDebugFrameSize(uint64_t size) { debug_frame_size_ = size; } 132 }; 133 134 class ElfInterface64Fake : public ElfInterface64 { 135 public: ElfInterface64Fake(Memory * memory)136 ElfInterface64Fake(Memory* memory) : ElfInterface64(memory) {} 137 virtual ~ElfInterface64Fake() = default; 138 FakeSetEhFrameOffset(uint64_t offset)139 void FakeSetEhFrameOffset(uint64_t offset) { eh_frame_offset_ = offset; } FakeSetEhFrameSize(uint64_t size)140 void FakeSetEhFrameSize(uint64_t size) { eh_frame_size_ = size; } FakeSetDebugFrameOffset(uint64_t offset)141 void FakeSetDebugFrameOffset(uint64_t offset) { debug_frame_offset_ = offset; } FakeSetDebugFrameSize(uint64_t size)142 void FakeSetDebugFrameSize(uint64_t size) { debug_frame_size_ = size; } 143 }; 144 145 class ElfInterfaceArmFake : public ElfInterfaceArm { 146 public: ElfInterfaceArmFake(Memory * memory)147 ElfInterfaceArmFake(Memory* memory) : ElfInterfaceArm(memory) {} 148 virtual ~ElfInterfaceArmFake() = default; 149 FakeSetStartOffset(uint64_t offset)150 void FakeSetStartOffset(uint64_t offset) { start_offset_ = offset; } FakeSetTotalEntries(size_t entries)151 void FakeSetTotalEntries(size_t entries) { total_entries_ = entries; } 152 }; 153 154 } // namespace unwindstack 155 156 #endif // _LIBUNWINDSTACK_TESTS_ELF_FAKE_H 157