1 /* 2 * Copyright (C) 2017 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 _LIBUNWINDSTACK_UNWINDER_H 18 #define _LIBUNWINDSTACK_UNWINDER_H 19 20 #include <stdint.h> 21 #include <sys/types.h> 22 23 #include <memory> 24 #include <string> 25 #include <vector> 26 27 #include <unwindstack/DexFiles.h> 28 #include <unwindstack/Error.h> 29 #include <unwindstack/JitDebug.h> 30 #include <unwindstack/Maps.h> 31 #include <unwindstack/Memory.h> 32 #include <unwindstack/Regs.h> 33 34 namespace unwindstack { 35 36 // Forward declarations. 37 class Elf; 38 enum ArchEnum : uint8_t; 39 40 struct FrameData { 41 size_t num; 42 43 uint64_t rel_pc; 44 uint64_t pc; 45 uint64_t sp; 46 47 std::string function_name; 48 uint64_t function_offset = 0; 49 50 std::string map_name; 51 // The offset from the first map representing the frame. When there are 52 // two maps (read-only and read-execute) this will be the offset from 53 // the read-only map. When there is only one map, this will be the 54 // same as the actual offset of the map and match map_exact_offset. 55 uint64_t map_elf_start_offset = 0; 56 // The actual offset from the map where the pc lies. 57 uint64_t map_exact_offset = 0; 58 uint64_t map_start = 0; 59 uint64_t map_end = 0; 60 uint64_t map_load_bias = 0; 61 int map_flags = 0; 62 }; 63 64 class Unwinder { 65 public: Unwinder(size_t max_frames,Maps * maps,Regs * regs,std::shared_ptr<Memory> process_memory)66 Unwinder(size_t max_frames, Maps* maps, Regs* regs, std::shared_ptr<Memory> process_memory) 67 : max_frames_(max_frames), maps_(maps), regs_(regs), process_memory_(process_memory) { 68 frames_.reserve(max_frames); 69 } Unwinder(size_t max_frames,Maps * maps,std::shared_ptr<Memory> process_memory)70 Unwinder(size_t max_frames, Maps* maps, std::shared_ptr<Memory> process_memory) 71 : max_frames_(max_frames), maps_(maps), process_memory_(process_memory) { 72 frames_.reserve(max_frames); 73 } 74 75 virtual ~Unwinder() = default; 76 77 void Unwind(const std::vector<std::string>* initial_map_names_to_skip = nullptr, 78 const std::vector<std::string>* map_suffixes_to_ignore = nullptr); 79 NumFrames()80 size_t NumFrames() const { return frames_.size(); } 81 frames()82 const std::vector<FrameData>& frames() { return frames_; } 83 ConsumeFrames()84 std::vector<FrameData> ConsumeFrames() { 85 std::vector<FrameData> frames = std::move(frames_); 86 frames_.clear(); 87 return frames; 88 } 89 90 std::string FormatFrame(size_t frame_num) const; 91 std::string FormatFrame(const FrameData& frame) const; 92 93 void SetJitDebug(JitDebug* jit_debug, ArchEnum arch); 94 SetRegs(Regs * regs)95 void SetRegs(Regs* regs) { regs_ = regs; } GetMaps()96 Maps* GetMaps() { return maps_; } GetProcessMemory()97 std::shared_ptr<Memory>& GetProcessMemory() { return process_memory_; } 98 99 // Disabling the resolving of names results in the function name being 100 // set to an empty string and the function offset being set to zero. SetResolveNames(bool resolve)101 void SetResolveNames(bool resolve) { resolve_names_ = resolve; } 102 103 // Enable/disable soname printing the soname for a map name if the elf is 104 // embedded in a file. This is enabled by default. 105 // NOTE: This does nothing unless resolving names is enabled. SetEmbeddedSoname(bool embedded_soname)106 void SetEmbeddedSoname(bool embedded_soname) { embedded_soname_ = embedded_soname; } 107 SetDisplayBuildID(bool display_build_id)108 void SetDisplayBuildID(bool display_build_id) { display_build_id_ = display_build_id; } 109 110 void SetDexFiles(DexFiles* dex_files, ArchEnum arch); 111 elf_from_memory_not_file()112 bool elf_from_memory_not_file() { return elf_from_memory_not_file_; } 113 LastErrorCode()114 ErrorCode LastErrorCode() { return last_error_.code; } LastErrorAddress()115 uint64_t LastErrorAddress() { return last_error_.address; } 116 117 // Builds a frame for symbolization using the maps from this unwinder. The 118 // constructed frame contains just enough information to be used to symbolize 119 // frames collected by frame-pointer unwinding that's done outside of 120 // libunwindstack. This is used by tombstoned to symbolize frame pointer-based 121 // stack traces that are collected by tools such as GWP-ASan and MTE. 122 FrameData BuildFrameFromPcOnly(uint64_t pc); 123 124 protected: Unwinder(size_t max_frames)125 Unwinder(size_t max_frames) : max_frames_(max_frames) { frames_.reserve(max_frames); } 126 127 void FillInDexFrame(); 128 FrameData* FillInFrame(MapInfo* map_info, Elf* elf, uint64_t rel_pc, uint64_t pc_adjustment); 129 130 size_t max_frames_; 131 Maps* maps_; 132 Regs* regs_; 133 std::vector<FrameData> frames_; 134 std::shared_ptr<Memory> process_memory_; 135 JitDebug* jit_debug_ = nullptr; 136 DexFiles* dex_files_ = nullptr; 137 bool resolve_names_ = true; 138 bool embedded_soname_ = true; 139 bool display_build_id_ = false; 140 // True if at least one elf file is coming from memory and not the related 141 // file. This is only true if there is an actual file backing up the elf. 142 bool elf_from_memory_not_file_ = false; 143 ErrorData last_error_; 144 }; 145 146 class UnwinderFromPid : public Unwinder { 147 public: UnwinderFromPid(size_t max_frames,pid_t pid)148 UnwinderFromPid(size_t max_frames, pid_t pid) : Unwinder(max_frames), pid_(pid) {} 149 virtual ~UnwinderFromPid() = default; 150 151 bool Init(ArchEnum arch); 152 153 private: 154 pid_t pid_; 155 std::unique_ptr<Maps> maps_ptr_; 156 std::unique_ptr<JitDebug> jit_debug_ptr_; 157 std::unique_ptr<DexFiles> dex_files_ptr_; 158 }; 159 160 } // namespace unwindstack 161 162 #endif // _LIBUNWINDSTACK_UNWINDER_H 163