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 <stdint.h> 21*eb293b8fSAndroid Build Coastguard Worker 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 #include <utility> 26*eb293b8fSAndroid Build Coastguard Worker #include <vector> 27*eb293b8fSAndroid Build Coastguard Worker 28*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/DwarfSection.h> 29*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/Error.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 declarations. 35*eb293b8fSAndroid Build Coastguard Worker class Memory; 36*eb293b8fSAndroid Build Coastguard Worker class Regs; 37*eb293b8fSAndroid Build Coastguard Worker class Symbols; 38*eb293b8fSAndroid Build Coastguard Worker 39*eb293b8fSAndroid Build Coastguard Worker struct LoadInfo { 40*eb293b8fSAndroid Build Coastguard Worker uint64_t offset; 41*eb293b8fSAndroid Build Coastguard Worker uint64_t table_offset; 42*eb293b8fSAndroid Build Coastguard Worker size_t table_size; 43*eb293b8fSAndroid Build Coastguard Worker }; 44*eb293b8fSAndroid Build Coastguard Worker 45*eb293b8fSAndroid Build Coastguard Worker struct SectionInfo { 46*eb293b8fSAndroid Build Coastguard Worker uint64_t offset; 47*eb293b8fSAndroid Build Coastguard Worker uint64_t size; 48*eb293b8fSAndroid Build Coastguard Worker uint64_t flags; 49*eb293b8fSAndroid Build Coastguard Worker int64_t bias; 50*eb293b8fSAndroid Build Coastguard Worker }; 51*eb293b8fSAndroid Build Coastguard Worker 52*eb293b8fSAndroid Build Coastguard Worker enum : uint8_t { 53*eb293b8fSAndroid Build Coastguard Worker SONAME_UNKNOWN = 0, 54*eb293b8fSAndroid Build Coastguard Worker SONAME_VALID, 55*eb293b8fSAndroid Build Coastguard Worker SONAME_INVALID, 56*eb293b8fSAndroid Build Coastguard Worker }; 57*eb293b8fSAndroid Build Coastguard Worker 58*eb293b8fSAndroid Build Coastguard Worker struct ElfTypes32 { 59*eb293b8fSAndroid Build Coastguard Worker using AddressType = uint32_t; 60*eb293b8fSAndroid Build Coastguard Worker using Chdr = Elf32_Chdr; 61*eb293b8fSAndroid Build Coastguard Worker using Dyn = Elf32_Dyn; 62*eb293b8fSAndroid Build Coastguard Worker using Ehdr = Elf32_Ehdr; 63*eb293b8fSAndroid Build Coastguard Worker using Nhdr = Elf32_Nhdr; 64*eb293b8fSAndroid Build Coastguard Worker using Phdr = Elf32_Phdr; 65*eb293b8fSAndroid Build Coastguard Worker using Shdr = Elf32_Shdr; 66*eb293b8fSAndroid Build Coastguard Worker using Sym = Elf32_Sym; 67*eb293b8fSAndroid Build Coastguard Worker }; 68*eb293b8fSAndroid Build Coastguard Worker 69*eb293b8fSAndroid Build Coastguard Worker struct ElfTypes64 { 70*eb293b8fSAndroid Build Coastguard Worker using AddressType = uint64_t; 71*eb293b8fSAndroid Build Coastguard Worker using Chdr = Elf64_Chdr; 72*eb293b8fSAndroid Build Coastguard Worker using Dyn = Elf64_Dyn; 73*eb293b8fSAndroid Build Coastguard Worker using Ehdr = Elf64_Ehdr; 74*eb293b8fSAndroid Build Coastguard Worker using Nhdr = Elf64_Nhdr; 75*eb293b8fSAndroid Build Coastguard Worker using Phdr = Elf64_Phdr; 76*eb293b8fSAndroid Build Coastguard Worker using Shdr = Elf64_Shdr; 77*eb293b8fSAndroid Build Coastguard Worker using Sym = Elf64_Sym; 78*eb293b8fSAndroid Build Coastguard Worker }; 79*eb293b8fSAndroid Build Coastguard Worker 80*eb293b8fSAndroid Build Coastguard Worker class ElfInterface { 81*eb293b8fSAndroid Build Coastguard Worker public: ElfInterface(std::shared_ptr<Memory> & memory)82*eb293b8fSAndroid Build Coastguard Worker ElfInterface(std::shared_ptr<Memory>& memory) : memory_(memory) {} 83*eb293b8fSAndroid Build Coastguard Worker virtual ~ElfInterface(); 84*eb293b8fSAndroid Build Coastguard Worker 85*eb293b8fSAndroid Build Coastguard Worker virtual bool Init(int64_t* load_bias) = 0; 86*eb293b8fSAndroid Build Coastguard Worker 87*eb293b8fSAndroid Build Coastguard Worker virtual void InitHeaders() = 0; 88*eb293b8fSAndroid Build Coastguard Worker 89*eb293b8fSAndroid Build Coastguard Worker virtual std::string GetSoname() = 0; 90*eb293b8fSAndroid Build Coastguard Worker 91*eb293b8fSAndroid Build Coastguard Worker virtual bool GetFunctionName(uint64_t addr, SharedString* name, uint64_t* offset) = 0; 92*eb293b8fSAndroid Build Coastguard Worker 93*eb293b8fSAndroid Build Coastguard Worker virtual bool GetGlobalVariable(const std::string& name, uint64_t* memory_address) = 0; 94*eb293b8fSAndroid Build Coastguard Worker 95*eb293b8fSAndroid Build Coastguard Worker virtual std::string GetBuildID() = 0; 96*eb293b8fSAndroid Build Coastguard Worker 97*eb293b8fSAndroid Build Coastguard Worker virtual bool Step(uint64_t rel_pc, Regs* regs, Memory* process_memory, bool* finished, 98*eb293b8fSAndroid Build Coastguard Worker bool* is_signal_frame); 99*eb293b8fSAndroid Build Coastguard Worker 100*eb293b8fSAndroid Build Coastguard Worker virtual bool IsValidPc(uint64_t pc); 101*eb293b8fSAndroid Build Coastguard Worker 102*eb293b8fSAndroid Build Coastguard Worker bool GetTextRange(uint64_t* addr, uint64_t* size); 103*eb293b8fSAndroid Build Coastguard Worker 104*eb293b8fSAndroid Build Coastguard Worker std::shared_ptr<Memory> CreateGnuDebugdataMemory(); 105*eb293b8fSAndroid Build Coastguard Worker memory()106*eb293b8fSAndroid Build Coastguard Worker std::shared_ptr<Memory> memory() { return memory_; } 107*eb293b8fSAndroid Build Coastguard Worker pt_loads()108*eb293b8fSAndroid Build Coastguard Worker const std::unordered_map<uint64_t, LoadInfo>& pt_loads() { return pt_loads_; } 109*eb293b8fSAndroid Build Coastguard Worker SetGnuDebugdataInterface(ElfInterface * interface)110*eb293b8fSAndroid Build Coastguard Worker void SetGnuDebugdataInterface(ElfInterface* interface) { gnu_debugdata_interface_ = interface; } 111*eb293b8fSAndroid Build Coastguard Worker dynamic_offset()112*eb293b8fSAndroid Build Coastguard Worker uint64_t dynamic_offset() { return dynamic_offset_; } dynamic_vaddr_start()113*eb293b8fSAndroid Build Coastguard Worker uint64_t dynamic_vaddr_start() { return dynamic_vaddr_start_; } dynamic_vaddr_end()114*eb293b8fSAndroid Build Coastguard Worker uint64_t dynamic_vaddr_end() { return dynamic_vaddr_end_; } 115*eb293b8fSAndroid Build Coastguard Worker data_offset()116*eb293b8fSAndroid Build Coastguard Worker uint64_t data_offset() { return data_offset_; } data_vaddr_start()117*eb293b8fSAndroid Build Coastguard Worker uint64_t data_vaddr_start() { return data_vaddr_start_; } data_vaddr_end()118*eb293b8fSAndroid Build Coastguard Worker uint64_t data_vaddr_end() { return data_vaddr_end_; } 119*eb293b8fSAndroid Build Coastguard Worker eh_frame_hdr_info()120*eb293b8fSAndroid Build Coastguard Worker const SectionInfo& eh_frame_hdr_info() { return eh_frame_hdr_info_; } eh_frame_info()121*eb293b8fSAndroid Build Coastguard Worker const SectionInfo& eh_frame_info() { return eh_frame_info_; } debug_frame_info()122*eb293b8fSAndroid Build Coastguard Worker const SectionInfo& debug_frame_info() { return debug_frame_info_; } 123*eb293b8fSAndroid Build Coastguard Worker gnu_debugdata_offset()124*eb293b8fSAndroid Build Coastguard Worker uint64_t gnu_debugdata_offset() { return gnu_debugdata_offset_; } gnu_debugdata_size()125*eb293b8fSAndroid Build Coastguard Worker uint64_t gnu_debugdata_size() { return gnu_debugdata_size_; } 126*eb293b8fSAndroid Build Coastguard Worker gnu_build_id_offset()127*eb293b8fSAndroid Build Coastguard Worker uint64_t gnu_build_id_offset() { return gnu_build_id_offset_; } gnu_build_id_size()128*eb293b8fSAndroid Build Coastguard Worker uint64_t gnu_build_id_size() { return gnu_build_id_size_; } 129*eb293b8fSAndroid Build Coastguard Worker eh_frame()130*eb293b8fSAndroid Build Coastguard Worker DwarfSection* eh_frame() { return eh_frame_.get(); } debug_frame()131*eb293b8fSAndroid Build Coastguard Worker DwarfSection* debug_frame() { return debug_frame_.get(); } 132*eb293b8fSAndroid Build Coastguard Worker last_error()133*eb293b8fSAndroid Build Coastguard Worker const ErrorData& last_error() { return last_error_; } LastErrorCode()134*eb293b8fSAndroid Build Coastguard Worker ErrorCode LastErrorCode() { return last_error_.code; } LastErrorAddress()135*eb293b8fSAndroid Build Coastguard Worker uint64_t LastErrorAddress() { return last_error_.address; } 136*eb293b8fSAndroid Build Coastguard Worker 137*eb293b8fSAndroid Build Coastguard Worker template <typename EhdrType, typename PhdrType> 138*eb293b8fSAndroid Build Coastguard Worker static int64_t GetLoadBias(Memory* memory); 139*eb293b8fSAndroid Build Coastguard Worker 140*eb293b8fSAndroid Build Coastguard Worker template <typename EhdrType, typename ShdrType, typename NhdrType> 141*eb293b8fSAndroid Build Coastguard Worker static std::string ReadBuildIDFromMemory(Memory* memory); 142*eb293b8fSAndroid Build Coastguard Worker 143*eb293b8fSAndroid Build Coastguard Worker protected: HandleUnknownType(uint32_t,uint64_t,uint64_t)144*eb293b8fSAndroid Build Coastguard Worker virtual void HandleUnknownType(uint32_t, uint64_t, uint64_t) {} 145*eb293b8fSAndroid Build Coastguard Worker 146*eb293b8fSAndroid Build Coastguard Worker std::shared_ptr<Memory> memory_; 147*eb293b8fSAndroid Build Coastguard Worker std::unordered_map<uint64_t, LoadInfo> pt_loads_; 148*eb293b8fSAndroid Build Coastguard Worker 149*eb293b8fSAndroid Build Coastguard Worker // Stored elf data. 150*eb293b8fSAndroid Build Coastguard Worker uint64_t dynamic_offset_ = 0; 151*eb293b8fSAndroid Build Coastguard Worker uint64_t dynamic_vaddr_start_ = 0; 152*eb293b8fSAndroid Build Coastguard Worker uint64_t dynamic_vaddr_end_ = 0; 153*eb293b8fSAndroid Build Coastguard Worker 154*eb293b8fSAndroid Build Coastguard Worker uint64_t data_offset_ = 0; 155*eb293b8fSAndroid Build Coastguard Worker uint64_t data_vaddr_start_ = 0; 156*eb293b8fSAndroid Build Coastguard Worker uint64_t data_vaddr_end_ = 0; 157*eb293b8fSAndroid Build Coastguard Worker 158*eb293b8fSAndroid Build Coastguard Worker SectionInfo eh_frame_hdr_info_ = {}; 159*eb293b8fSAndroid Build Coastguard Worker SectionInfo eh_frame_info_ = {}; 160*eb293b8fSAndroid Build Coastguard Worker SectionInfo debug_frame_info_ = {}; 161*eb293b8fSAndroid Build Coastguard Worker 162*eb293b8fSAndroid Build Coastguard Worker uint64_t gnu_debugdata_offset_ = 0; 163*eb293b8fSAndroid Build Coastguard Worker uint64_t gnu_debugdata_size_ = 0; 164*eb293b8fSAndroid Build Coastguard Worker 165*eb293b8fSAndroid Build Coastguard Worker uint64_t gnu_build_id_offset_ = 0; 166*eb293b8fSAndroid Build Coastguard Worker uint64_t gnu_build_id_size_ = 0; 167*eb293b8fSAndroid Build Coastguard Worker 168*eb293b8fSAndroid Build Coastguard Worker uint64_t text_addr_ = 0; 169*eb293b8fSAndroid Build Coastguard Worker uint64_t text_size_ = 0; 170*eb293b8fSAndroid Build Coastguard Worker 171*eb293b8fSAndroid Build Coastguard Worker uint8_t soname_type_ = SONAME_UNKNOWN; 172*eb293b8fSAndroid Build Coastguard Worker std::string soname_; 173*eb293b8fSAndroid Build Coastguard Worker 174*eb293b8fSAndroid Build Coastguard Worker ErrorData last_error_{ERROR_NONE, 0}; 175*eb293b8fSAndroid Build Coastguard Worker 176*eb293b8fSAndroid Build Coastguard Worker std::unique_ptr<DwarfSection> eh_frame_; 177*eb293b8fSAndroid Build Coastguard Worker std::unique_ptr<DwarfSection> debug_frame_; 178*eb293b8fSAndroid Build Coastguard Worker // The Elf object owns the gnu_debugdata interface object. 179*eb293b8fSAndroid Build Coastguard Worker ElfInterface* gnu_debugdata_interface_ = nullptr; 180*eb293b8fSAndroid Build Coastguard Worker 181*eb293b8fSAndroid Build Coastguard Worker std::vector<Symbols*> symbols_; 182*eb293b8fSAndroid Build Coastguard Worker std::vector<std::pair<uint64_t, uint64_t>> strtabs_; 183*eb293b8fSAndroid Build Coastguard Worker }; 184*eb293b8fSAndroid Build Coastguard Worker 185*eb293b8fSAndroid Build Coastguard Worker template <typename ElfTypes> 186*eb293b8fSAndroid Build Coastguard Worker class ElfInterfaceImpl : public ElfInterface { 187*eb293b8fSAndroid Build Coastguard Worker public: 188*eb293b8fSAndroid Build Coastguard Worker using AddressType = typename ElfTypes::AddressType; 189*eb293b8fSAndroid Build Coastguard Worker using ChdrType = typename ElfTypes::Chdr; 190*eb293b8fSAndroid Build Coastguard Worker using DynType = typename ElfTypes::Dyn; 191*eb293b8fSAndroid Build Coastguard Worker using EhdrType = typename ElfTypes::Ehdr; 192*eb293b8fSAndroid Build Coastguard Worker using NhdrType = typename ElfTypes::Nhdr; 193*eb293b8fSAndroid Build Coastguard Worker using PhdrType = typename ElfTypes::Phdr; 194*eb293b8fSAndroid Build Coastguard Worker using ShdrType = typename ElfTypes::Shdr; 195*eb293b8fSAndroid Build Coastguard Worker using SymType = typename ElfTypes::Sym; 196*eb293b8fSAndroid Build Coastguard Worker ElfInterfaceImpl(std::shared_ptr<Memory> & memory)197*eb293b8fSAndroid Build Coastguard Worker ElfInterfaceImpl(std::shared_ptr<Memory>& memory) : ElfInterface(memory) {} 198*eb293b8fSAndroid Build Coastguard Worker virtual ~ElfInterfaceImpl() = default; 199*eb293b8fSAndroid Build Coastguard Worker Init(int64_t * load_bias)200*eb293b8fSAndroid Build Coastguard Worker bool Init(int64_t* load_bias) override { return ReadAllHeaders(load_bias); } 201*eb293b8fSAndroid Build Coastguard Worker 202*eb293b8fSAndroid Build Coastguard Worker void InitHeaders() override; 203*eb293b8fSAndroid Build Coastguard Worker 204*eb293b8fSAndroid Build Coastguard Worker std::string GetSoname() override; 205*eb293b8fSAndroid Build Coastguard Worker 206*eb293b8fSAndroid Build Coastguard Worker bool GetFunctionName(uint64_t addr, SharedString* name, uint64_t* func_offset) override; 207*eb293b8fSAndroid Build Coastguard Worker 208*eb293b8fSAndroid Build Coastguard Worker bool GetGlobalVariable(const std::string& name, uint64_t* memory_address) override; 209*eb293b8fSAndroid Build Coastguard Worker GetBuildID()210*eb293b8fSAndroid Build Coastguard Worker std::string GetBuildID() override { return ReadBuildID(); } 211*eb293b8fSAndroid Build Coastguard Worker 212*eb293b8fSAndroid Build Coastguard Worker static void GetMaxSize(Memory* memory, uint64_t* size); 213*eb293b8fSAndroid Build Coastguard Worker 214*eb293b8fSAndroid Build Coastguard Worker protected: 215*eb293b8fSAndroid Build Coastguard Worker bool ReadAllHeaders(int64_t* load_bias); 216*eb293b8fSAndroid Build Coastguard Worker 217*eb293b8fSAndroid Build Coastguard Worker void ReadProgramHeaders(const EhdrType& ehdr, int64_t* load_bias); 218*eb293b8fSAndroid Build Coastguard Worker 219*eb293b8fSAndroid Build Coastguard Worker void ReadSectionHeaders(const EhdrType& ehdr); 220*eb293b8fSAndroid Build Coastguard Worker 221*eb293b8fSAndroid Build Coastguard Worker std::string ReadBuildID(); 222*eb293b8fSAndroid Build Coastguard Worker }; 223*eb293b8fSAndroid Build Coastguard Worker 224*eb293b8fSAndroid Build Coastguard Worker using ElfInterface32 = ElfInterfaceImpl<ElfTypes32>; 225*eb293b8fSAndroid Build Coastguard Worker using ElfInterface64 = ElfInterfaceImpl<ElfTypes64>; 226*eb293b8fSAndroid Build Coastguard Worker 227*eb293b8fSAndroid Build Coastguard Worker } // namespace unwindstack 228