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