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