xref: /aosp_15_r20/system/unwinding/libunwindstack/tests/ElfFake.h (revision eb293b8f56ee8303637c5595cfcdeef8039e85c6)
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