xref: /aosp_15_r20/system/unwinding/libunwindstack/include/unwindstack/Elf.h (revision eb293b8f56ee8303637c5595cfcdeef8039e85c6)
1*eb293b8fSAndroid Build Coastguard Worker /*
2*eb293b8fSAndroid Build Coastguard Worker  * Copyright (C) 2016 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 <elf.h>
20*eb293b8fSAndroid Build Coastguard Worker #include <stddef.h>
21*eb293b8fSAndroid Build Coastguard Worker 
22*eb293b8fSAndroid Build Coastguard Worker #include <memory>
23*eb293b8fSAndroid Build Coastguard Worker #include <mutex>
24*eb293b8fSAndroid Build Coastguard Worker #include <string>
25*eb293b8fSAndroid Build Coastguard Worker #include <unordered_map>
26*eb293b8fSAndroid Build Coastguard Worker 
27*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/Arch.h>
28*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/ElfInterface.h>
29*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/Memory.h>
30*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/SharedString.h>
31*eb293b8fSAndroid Build Coastguard Worker 
32*eb293b8fSAndroid Build Coastguard Worker namespace unwindstack {
33*eb293b8fSAndroid Build Coastguard Worker 
34*eb293b8fSAndroid Build Coastguard Worker // Forward declaration.
35*eb293b8fSAndroid Build Coastguard Worker class MapInfo;
36*eb293b8fSAndroid Build Coastguard Worker class Regs;
37*eb293b8fSAndroid Build Coastguard Worker 
38*eb293b8fSAndroid Build Coastguard Worker class Elf {
39*eb293b8fSAndroid Build Coastguard Worker  public:
Elf(std::shared_ptr<Memory> & memory)40*eb293b8fSAndroid Build Coastguard Worker   Elf(std::shared_ptr<Memory>& memory) : memory_(memory) {}
41*eb293b8fSAndroid Build Coastguard Worker   virtual ~Elf() = default;
42*eb293b8fSAndroid Build Coastguard Worker 
43*eb293b8fSAndroid Build Coastguard Worker   bool Init();
44*eb293b8fSAndroid Build Coastguard Worker 
45*eb293b8fSAndroid Build Coastguard Worker   void InitGnuDebugdata();
46*eb293b8fSAndroid Build Coastguard Worker 
47*eb293b8fSAndroid Build Coastguard Worker   void Invalidate();
48*eb293b8fSAndroid Build Coastguard Worker 
49*eb293b8fSAndroid Build Coastguard Worker   std::string GetSoname();
50*eb293b8fSAndroid Build Coastguard Worker 
51*eb293b8fSAndroid Build Coastguard Worker   bool GetFunctionName(uint64_t addr, SharedString* name, uint64_t* func_offset);
52*eb293b8fSAndroid Build Coastguard Worker 
53*eb293b8fSAndroid Build Coastguard Worker   bool GetGlobalVariableOffset(const std::string& name, uint64_t* memory_offset);
54*eb293b8fSAndroid Build Coastguard Worker 
55*eb293b8fSAndroid Build Coastguard Worker   uint64_t GetRelPc(uint64_t pc, MapInfo* map_info);
56*eb293b8fSAndroid Build Coastguard Worker 
57*eb293b8fSAndroid Build Coastguard Worker   bool StepIfSignalHandler(uint64_t rel_pc, Regs* regs, Memory* process_memory);
58*eb293b8fSAndroid Build Coastguard Worker 
59*eb293b8fSAndroid Build Coastguard Worker   bool Step(uint64_t rel_pc, Regs* regs, Memory* process_memory, bool* finished,
60*eb293b8fSAndroid Build Coastguard Worker             bool* is_signal_frame);
61*eb293b8fSAndroid Build Coastguard Worker 
62*eb293b8fSAndroid Build Coastguard Worker   ElfInterface* CreateInterfaceFromMemory(std::shared_ptr<Memory>& memory);
63*eb293b8fSAndroid Build Coastguard Worker 
64*eb293b8fSAndroid Build Coastguard Worker   std::string GetBuildID();
65*eb293b8fSAndroid Build Coastguard Worker 
66*eb293b8fSAndroid Build Coastguard Worker   std::string GetPrintableBuildID();
67*eb293b8fSAndroid Build Coastguard Worker 
GetLoadBias()68*eb293b8fSAndroid Build Coastguard Worker   int64_t GetLoadBias() { return load_bias_; }
69*eb293b8fSAndroid Build Coastguard Worker 
70*eb293b8fSAndroid Build Coastguard Worker   bool IsValidPc(uint64_t pc);
71*eb293b8fSAndroid Build Coastguard Worker 
72*eb293b8fSAndroid Build Coastguard Worker   bool GetTextRange(uint64_t* addr, uint64_t* size);
73*eb293b8fSAndroid Build Coastguard Worker 
74*eb293b8fSAndroid Build Coastguard Worker   void GetLastError(ErrorData* data);
75*eb293b8fSAndroid Build Coastguard Worker   ErrorCode GetLastErrorCode();
76*eb293b8fSAndroid Build Coastguard Worker   uint64_t GetLastErrorAddress();
77*eb293b8fSAndroid Build Coastguard Worker 
valid()78*eb293b8fSAndroid Build Coastguard Worker   bool valid() { return valid_; }
79*eb293b8fSAndroid Build Coastguard Worker 
machine_type()80*eb293b8fSAndroid Build Coastguard Worker   uint32_t machine_type() { return machine_type_; }
81*eb293b8fSAndroid Build Coastguard Worker 
class_type()82*eb293b8fSAndroid Build Coastguard Worker   uint8_t class_type() { return class_type_; }
83*eb293b8fSAndroid Build Coastguard Worker 
arch()84*eb293b8fSAndroid Build Coastguard Worker   ArchEnum arch() { return arch_; }
85*eb293b8fSAndroid Build Coastguard Worker 
memory()86*eb293b8fSAndroid Build Coastguard Worker   std::shared_ptr<Memory> memory() { return memory_; }
87*eb293b8fSAndroid Build Coastguard Worker 
interface()88*eb293b8fSAndroid Build Coastguard Worker   ElfInterface* interface() { return interface_.get(); }
89*eb293b8fSAndroid Build Coastguard Worker 
gnu_debugdata_interface()90*eb293b8fSAndroid Build Coastguard Worker   ElfInterface* gnu_debugdata_interface() { return gnu_debugdata_interface_.get(); }
91*eb293b8fSAndroid Build Coastguard Worker 
92*eb293b8fSAndroid Build Coastguard Worker   static bool IsValidElf(Memory* memory);
93*eb293b8fSAndroid Build Coastguard Worker 
94*eb293b8fSAndroid Build Coastguard Worker   static bool GetInfo(Memory* memory, uint64_t* size);
95*eb293b8fSAndroid Build Coastguard Worker 
96*eb293b8fSAndroid Build Coastguard Worker   static int64_t GetLoadBias(Memory* memory);
97*eb293b8fSAndroid Build Coastguard Worker 
98*eb293b8fSAndroid Build Coastguard Worker   static std::string GetBuildID(Memory* memory);
99*eb293b8fSAndroid Build Coastguard Worker 
100*eb293b8fSAndroid Build Coastguard Worker   // Caching cannot be enabled/disabled while unwinding. It is assumed
101*eb293b8fSAndroid Build Coastguard Worker   // that once enabled, it remains enabled while all unwinds are running.
102*eb293b8fSAndroid Build Coastguard Worker   // If the state of the caching changes while unwinding is occurring,
103*eb293b8fSAndroid Build Coastguard Worker   // it could cause crashes.
104*eb293b8fSAndroid Build Coastguard Worker   static void SetCachingEnabled(bool enable);
105*eb293b8fSAndroid Build Coastguard Worker 
CachingEnabled()106*eb293b8fSAndroid Build Coastguard Worker   static bool CachingEnabled() { return cache_enabled_; }
107*eb293b8fSAndroid Build Coastguard Worker 
108*eb293b8fSAndroid Build Coastguard Worker   static void CacheLock();
109*eb293b8fSAndroid Build Coastguard Worker   static void CacheUnlock();
110*eb293b8fSAndroid Build Coastguard Worker   static void CacheAdd(MapInfo* info);
111*eb293b8fSAndroid Build Coastguard Worker   static bool CacheGet(MapInfo* info);
112*eb293b8fSAndroid Build Coastguard Worker 
113*eb293b8fSAndroid Build Coastguard Worker   static std::string GetPrintableBuildID(std::string& build_id);
114*eb293b8fSAndroid Build Coastguard Worker 
115*eb293b8fSAndroid Build Coastguard Worker  protected:
116*eb293b8fSAndroid Build Coastguard Worker   bool valid_ = false;
117*eb293b8fSAndroid Build Coastguard Worker   int64_t load_bias_ = 0;
118*eb293b8fSAndroid Build Coastguard Worker   std::unique_ptr<ElfInterface> interface_;
119*eb293b8fSAndroid Build Coastguard Worker   std::shared_ptr<Memory> memory_;
120*eb293b8fSAndroid Build Coastguard Worker   uint32_t machine_type_;
121*eb293b8fSAndroid Build Coastguard Worker   uint8_t class_type_;
122*eb293b8fSAndroid Build Coastguard Worker   ArchEnum arch_;
123*eb293b8fSAndroid Build Coastguard Worker   // Protect calls that can modify internal state of the interface object.
124*eb293b8fSAndroid Build Coastguard Worker   std::mutex lock_;
125*eb293b8fSAndroid Build Coastguard Worker 
126*eb293b8fSAndroid Build Coastguard Worker   std::unique_ptr<ElfInterface> gnu_debugdata_interface_;
127*eb293b8fSAndroid Build Coastguard Worker 
128*eb293b8fSAndroid Build Coastguard Worker   static bool cache_enabled_;
129*eb293b8fSAndroid Build Coastguard Worker   static std::unordered_map<std::string, std::unordered_map<uint64_t, std::shared_ptr<Elf>>>*
130*eb293b8fSAndroid Build Coastguard Worker       cache_;
131*eb293b8fSAndroid Build Coastguard Worker   static std::mutex* cache_lock_;
132*eb293b8fSAndroid Build Coastguard Worker };
133*eb293b8fSAndroid Build Coastguard Worker 
134*eb293b8fSAndroid Build Coastguard Worker }  // namespace unwindstack
135