1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef _LIBBACKTRACE_UNWIND_OFFLINE_H 18 #define _LIBBACKTRACE_UNWIND_OFFLINE_H 19 20 #include <libunwind.h> 21 #include <stdint.h> 22 #include <sys/types.h> 23 #include <ucontext.h> 24 25 #include <unordered_map> 26 #include <unordered_set> 27 28 #include <backtrace/Backtrace.h> 29 30 struct Space { 31 uint64_t start; 32 uint64_t end; 33 const uint8_t* data; 34 SpaceSpace35 Space() { 36 Clear(); 37 } 38 39 void Clear(); 40 size_t Read(uint64_t addr, uint8_t* buffer, size_t size); 41 }; 42 43 struct DebugFrameInfo { 44 bool is_eh_frame; 45 struct EhFrame { 46 uint64_t eh_frame_hdr_vaddr; 47 uint64_t eh_frame_vaddr; 48 uint64_t fde_table_offset_in_eh_frame_hdr; 49 std::vector<uint8_t> eh_frame_hdr_data; 50 std::vector<uint8_t> eh_frame_data; 51 struct ProgramHeader { 52 uint64_t vaddr; 53 uint64_t file_offset; 54 uint64_t file_size; 55 }; 56 std::vector<ProgramHeader> program_headers; 57 } eh_frame; 58 }; 59 60 class BacktraceOffline : public Backtrace { 61 public: BacktraceOffline(pid_t pid,pid_t tid,BacktraceMap * map,const backtrace_stackinfo_t & stack,bool cache_file)62 BacktraceOffline(pid_t pid, pid_t tid, BacktraceMap* map, const backtrace_stackinfo_t& stack, 63 bool cache_file) 64 : Backtrace(pid, tid, map), 65 cache_file_(cache_file), 66 context_(nullptr), 67 last_debug_frame_(nullptr) { 68 stack_space_.start = stack.start; 69 stack_space_.end = stack.end; 70 stack_space_.data = stack.data; 71 } 72 ~BacktraceOffline()73 virtual ~BacktraceOffline() { 74 if (last_debug_frame_ != nullptr) { 75 delete last_debug_frame_; 76 } 77 } 78 79 bool Unwind(size_t num_ignore_frames, ucontext_t* context) override; 80 81 bool ReadWord(uintptr_t ptr, word_t* out_value) override; 82 83 size_t Read(uintptr_t addr, uint8_t* buffer, size_t bytes) override; 84 85 bool FindProcInfo(unw_addr_space_t addr_space, uint64_t ip, unw_proc_info_t* proc_info, 86 int need_unwind_info); 87 88 bool ReadReg(size_t reg_index, uint64_t* value); 89 90 protected: 91 std::string GetFunctionNameRaw(uintptr_t pc, uintptr_t* offset) override; 92 DebugFrameInfo* GetDebugFrameInFile(const std::string& filename); 93 94 static std::unordered_map<std::string, std::unique_ptr<DebugFrameInfo>> debug_frames_; 95 static std::unordered_set<std::string> debug_frame_missing_files_; 96 97 bool cache_file_; 98 ucontext_t* context_; 99 Space eh_frame_hdr_space_; 100 Space eh_frame_space_; 101 Space stack_space_; 102 DebugFrameInfo* last_debug_frame_; 103 }; 104 105 #endif // _LIBBACKTRACE_BACKTRACE_OFFLINE_H 106