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