| /* | 
 |  * Copyright (C) 2017 The Android Open Source Project | 
 |  * | 
 |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
 |  * you may not use this file except in compliance with the License. | 
 |  * You may obtain a copy of the License at | 
 |  * | 
 |  *      http://www.apache.org/licenses/LICENSE-2.0 | 
 |  * | 
 |  * Unless required by applicable law or agreed to in writing, software | 
 |  * distributed under the License is distributed on an "AS IS" BASIS, | 
 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 |  * See the License for the specific language governing permissions and | 
 |  * limitations under the License. | 
 |  */ | 
 |  | 
 | #ifndef _LIBUNWINDSTACK_TESTS_ELF_FAKE_H | 
 | #define _LIBUNWINDSTACK_TESTS_ELF_FAKE_H | 
 |  | 
 | #include <stdint.h> | 
 |  | 
 | #include <deque> | 
 | #include <string> | 
 | #include <unordered_map> | 
 |  | 
 | #include <unwindstack/Elf.h> | 
 | #include <unwindstack/ElfInterface.h> | 
 | #include <unwindstack/Memory.h> | 
 | #include <unwindstack/Regs.h> | 
 |  | 
 | #include "ElfInterfaceArm.h" | 
 |  | 
 | namespace unwindstack { | 
 |  | 
 | struct StepData { | 
 |   StepData(uint64_t pc, uint64_t sp, bool finished) : pc(pc), sp(sp), finished(finished) {} | 
 |   uint64_t pc; | 
 |   uint64_t sp; | 
 |   bool finished; | 
 | }; | 
 |  | 
 | struct FunctionData { | 
 |   FunctionData(std::string name, uint64_t offset) : name(name), offset(offset) {} | 
 |  | 
 |   std::string name; | 
 |   uint64_t offset; | 
 | }; | 
 |  | 
 | class ElfFake : public Elf { | 
 |  public: | 
 |   ElfFake(Memory* memory) : Elf(memory) { valid_ = true; } | 
 |   virtual ~ElfFake() = default; | 
 |  | 
 |   void FakeSetValid(bool valid) { valid_ = valid; } | 
 |  | 
 |   void FakeSetLoadBias(uint64_t load_bias) { load_bias_ = load_bias; } | 
 |  | 
 |   void FakeSetInterface(ElfInterface* interface) { interface_.reset(interface); } | 
 |   void FakeSetGnuDebugdataInterface(ElfInterface* interface) { | 
 |     gnu_debugdata_interface_.reset(interface); | 
 |   } | 
 | }; | 
 |  | 
 | class ElfInterfaceFake : public ElfInterface { | 
 |  public: | 
 |   ElfInterfaceFake(Memory* memory) : ElfInterface(memory) {} | 
 |   virtual ~ElfInterfaceFake() = default; | 
 |  | 
 |   bool Init(uint64_t*) override { return false; } | 
 |   void InitHeaders(uint64_t) override {} | 
 |   std::string GetSoname() override { return fake_soname_; } | 
 |  | 
 |   bool GetFunctionName(uint64_t, std::string*, uint64_t*) override; | 
 |   bool GetGlobalVariable(const std::string&, uint64_t*) override; | 
 |   std::string GetBuildID() override { return fake_build_id_; } | 
 |  | 
 |   bool Step(uint64_t, Regs*, Memory*, bool*) override; | 
 |  | 
 |   void FakeSetGlobalVariable(const std::string& global, uint64_t offset) { | 
 |     globals_[global] = offset; | 
 |   } | 
 |  | 
 |   void FakeSetBuildID(std::string& build_id) { fake_build_id_ = build_id; } | 
 |   void FakeSetBuildID(const char* build_id) { fake_build_id_ = build_id; } | 
 |  | 
 |   void FakeSetSoname(const char* soname) { fake_soname_ = soname; } | 
 |  | 
 |   static void FakePushFunctionData(const FunctionData data) { functions_.push_back(data); } | 
 |   static void FakePushStepData(const StepData data) { steps_.push_back(data); } | 
 |  | 
 |   static void FakeClear() { | 
 |     functions_.clear(); | 
 |     steps_.clear(); | 
 |   } | 
 |  | 
 |   void FakeSetErrorCode(ErrorCode code) { last_error_.code = code; } | 
 |  | 
 |   void FakeSetErrorAddress(uint64_t address) { last_error_.address = address; } | 
 |  | 
 |  private: | 
 |   std::unordered_map<std::string, uint64_t> globals_; | 
 |   std::string fake_build_id_; | 
 |   std::string fake_soname_; | 
 |  | 
 |   static std::deque<FunctionData> functions_; | 
 |   static std::deque<StepData> steps_; | 
 | }; | 
 |  | 
 | class ElfInterface32Fake : public ElfInterface32 { | 
 |  public: | 
 |   ElfInterface32Fake(Memory* memory) : ElfInterface32(memory) {} | 
 |   virtual ~ElfInterface32Fake() = default; | 
 |  | 
 |   void FakeSetEhFrameOffset(uint64_t offset) { eh_frame_offset_ = offset; } | 
 |   void FakeSetEhFrameSize(uint64_t size) { eh_frame_size_ = size; } | 
 |   void FakeSetDebugFrameOffset(uint64_t offset) { debug_frame_offset_ = offset; } | 
 |   void FakeSetDebugFrameSize(uint64_t size) { debug_frame_size_ = size; } | 
 | }; | 
 |  | 
 | class ElfInterface64Fake : public ElfInterface64 { | 
 |  public: | 
 |   ElfInterface64Fake(Memory* memory) : ElfInterface64(memory) {} | 
 |   virtual ~ElfInterface64Fake() = default; | 
 |  | 
 |   void FakeSetEhFrameOffset(uint64_t offset) { eh_frame_offset_ = offset; } | 
 |   void FakeSetEhFrameSize(uint64_t size) { eh_frame_size_ = size; } | 
 |   void FakeSetDebugFrameOffset(uint64_t offset) { debug_frame_offset_ = offset; } | 
 |   void FakeSetDebugFrameSize(uint64_t size) { debug_frame_size_ = size; } | 
 | }; | 
 |  | 
 | class ElfInterfaceArmFake : public ElfInterfaceArm { | 
 |  public: | 
 |   ElfInterfaceArmFake(Memory* memory) : ElfInterfaceArm(memory) {} | 
 |   virtual ~ElfInterfaceArmFake() = default; | 
 |  | 
 |   void FakeSetStartOffset(uint64_t offset) { start_offset_ = offset; } | 
 |   void FakeSetTotalEntries(size_t entries) { total_entries_ = entries; } | 
 | }; | 
 |  | 
 | }  // namespace unwindstack | 
 |  | 
 | #endif  // _LIBUNWINDSTACK_TESTS_ELF_FAKE_H |