1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/profiler/native_unwinder_android.h"
6 
7 #include <sys/mman.h>
8 
9 #include <string>
10 #include <vector>
11 
12 #include "third_party/libunwindstack/src/libunwindstack/include/unwindstack/Elf.h"
13 #include "third_party/libunwindstack/src/libunwindstack/include/unwindstack/Memory.h"
14 #include "third_party/libunwindstack/src/libunwindstack/include/unwindstack/Regs.h"
15 
16 #include "base/memory/ptr_util.h"
17 #include "base/notreached.h"
18 #include "base/profiler/module_cache.h"
19 #include "base/profiler/native_unwinder.h"
20 #include "base/profiler/profile_builder.h"
21 #include "build/build_config.h"
22 
23 #if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
24 #include "third_party/libunwindstack/src/libunwindstack/include/unwindstack/MachineArm.h"
25 #include "third_party/libunwindstack/src/libunwindstack/include/unwindstack/RegsArm.h"
26 #elif defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_64_BITS)
27 #include "third_party/libunwindstack/src/libunwindstack/include/unwindstack/MachineArm64.h"
28 #include "third_party/libunwindstack/src/libunwindstack/include/unwindstack/RegsArm64.h"
29 #endif  // #if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
30 
31 namespace base {
32 namespace {
33 
34 class NonElfModule : public ModuleCache::Module {
35  public:
NonElfModule(unwindstack::MapInfo * map_info)36   NonElfModule(unwindstack::MapInfo* map_info)
37       : start_(map_info->start),
38         size_(map_info->end - start_),
39         map_info_name_(map_info->name) {}
40   ~NonElfModule() override = default;
41 
GetBaseAddress() const42   uintptr_t GetBaseAddress() const override { return start_; }
43 
GetId() const44   std::string GetId() const override { return std::string(); }
45 
GetDebugBasename() const46   FilePath GetDebugBasename() const override {
47     return FilePath(map_info_name_);
48   }
49 
50   // Gets the size of the module.
GetSize() const51   size_t GetSize() const override { return size_; }
52 
53   // True if this is a native module.
IsNative() const54   bool IsNative() const override { return true; }
55 
56  private:
57   const uintptr_t start_;
58   const size_t size_;
59   const std::string map_info_name_;
60 };
61 
CreateFromRegisterContext(RegisterContext * thread_context)62 std::unique_ptr<unwindstack::Regs> CreateFromRegisterContext(
63     RegisterContext* thread_context) {
64 #if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
65   return WrapUnique<unwindstack::Regs>(unwindstack::RegsArm::Read(
66       reinterpret_cast<void*>(&thread_context->arm_r0)));
67 #elif defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_64_BITS)
68   return WrapUnique<unwindstack::Regs>(unwindstack::RegsArm64::Read(
69       reinterpret_cast<void*>(&thread_context->regs[0])));
70 #else   // #if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
71   NOTREACHED();
72   return nullptr;
73 #endif  // #if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
74 }
75 
CopyToRegisterContext(unwindstack::Regs * regs,RegisterContext * thread_context)76 void CopyToRegisterContext(unwindstack::Regs* regs,
77                            RegisterContext* thread_context) {
78 #if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
79   memcpy(reinterpret_cast<void*>(&thread_context->arm_r0), regs->RawData(),
80          unwindstack::ARM_REG_LAST * sizeof(uintptr_t));
81 #elif defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_64_BITS)
82   memcpy(reinterpret_cast<void*>(&thread_context->regs[0]), regs->RawData(),
83          unwindstack::ARM64_REG_LAST * sizeof(uintptr_t));
84 #else   // #if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
85   NOTREACHED();
86 #endif  // #if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
87 }
88 
89 }  // namespace
90 
UnwindStackMemoryAndroid(uintptr_t stack_ptr,uintptr_t stack_top)91 UnwindStackMemoryAndroid::UnwindStackMemoryAndroid(uintptr_t stack_ptr,
92                                                    uintptr_t stack_top)
93     : stack_ptr_(stack_ptr), stack_top_(stack_top) {
94   DCHECK_LE(stack_ptr_, stack_top_);
95 }
96 
97 UnwindStackMemoryAndroid::~UnwindStackMemoryAndroid() = default;
98 
Read(uint64_t addr,void * dst,size_t size)99 size_t UnwindStackMemoryAndroid::Read(uint64_t addr, void* dst, size_t size) {
100   if (addr < stack_ptr_)
101     return 0;
102   if (size >= stack_top_ || addr > stack_top_ - size)
103     return 0;
104   memcpy(dst, reinterpret_cast<void*>(addr), size);
105   return size;
106 }
107 
108 // static
CreateMaps()109 std::unique_ptr<unwindstack::Maps> NativeUnwinderAndroid::CreateMaps() {
110   auto maps = std::make_unique<unwindstack::LocalMaps>();
111   if (maps->Parse())
112     return maps;
113   return nullptr;
114 }
115 
116 // static
117 std::unique_ptr<unwindstack::Memory>
CreateProcessMemory()118 NativeUnwinderAndroid::CreateProcessMemory() {
119   return unwindstack::Memory::CreateLocalProcessMemory();
120 }
121 
NativeUnwinderAndroid(unwindstack::Maps * memory_regions_map,unwindstack::Memory * process_memory,uintptr_t exclude_module_with_base_address)122 NativeUnwinderAndroid::NativeUnwinderAndroid(
123     unwindstack::Maps* memory_regions_map,
124     unwindstack::Memory* process_memory,
125     uintptr_t exclude_module_with_base_address)
126     : memory_regions_map_(memory_regions_map),
127       process_memory_(process_memory),
128       exclude_module_with_base_address_(exclude_module_with_base_address) {}
129 
130 NativeUnwinderAndroid::~NativeUnwinderAndroid() = default;
131 
AddInitialModules(ModuleCache * module_cache)132 void NativeUnwinderAndroid::AddInitialModules(ModuleCache* module_cache) {
133   AddInitialModulesFromMaps(*memory_regions_map_, module_cache);
134 }
135 
CanUnwindFrom(const Frame & current_frame) const136 bool NativeUnwinderAndroid::CanUnwindFrom(const Frame& current_frame) const {
137   return current_frame.module && current_frame.module->IsNative() &&
138          current_frame.module->GetBaseAddress() !=
139              exclude_module_with_base_address_;
140 }
141 
TryUnwind(RegisterContext * thread_context,uintptr_t stack_top,ModuleCache * module_cache,std::vector<Frame> * stack) const142 UnwindResult NativeUnwinderAndroid::TryUnwind(RegisterContext* thread_context,
143                                               uintptr_t stack_top,
144                                               ModuleCache* module_cache,
145                                               std::vector<Frame>* stack) const {
146   auto regs = CreateFromRegisterContext(thread_context);
147   DCHECK(regs);
148   unwindstack::ArchEnum arch = regs->Arch();
149 
150   do {
151     uint64_t cur_pc = regs->pc();
152     uint64_t cur_sp = regs->sp();
153     unwindstack::MapInfo* map_info = memory_regions_map_->Find(cur_pc);
154     if (map_info == nullptr ||
155         map_info->flags & unwindstack::MAPS_FLAGS_DEVICE_MAP) {
156       break;
157     }
158 
159     unwindstack::Elf* elf =
160         map_info->GetElf({process_memory_, [](unwindstack::Memory*) {}}, arch);
161     if (!elf->valid())
162       break;
163 
164     UnwindStackMemoryAndroid stack_memory(cur_sp, stack_top);
165     uintptr_t rel_pc = elf->GetRelPc(cur_pc, map_info);
166     bool finished = false;
167     bool stepped =
168         elf->StepIfSignalHandler(rel_pc, regs.get(), &stack_memory) ||
169         elf->Step(rel_pc, regs.get(), &stack_memory, &finished);
170     if (stepped && finished)
171       return UnwindResult::COMPLETED;
172 
173     if (!stepped) {
174       // Stepping failed. Try unwinding using return address.
175       if (stack->size() == 1) {
176         if (!regs->SetPcFromReturnAddress(&stack_memory))
177           return UnwindResult::ABORTED;
178       } else {
179         break;
180       }
181     }
182 
183     // If the pc and sp didn't change, then consider everything stopped.
184     if (cur_pc == regs->pc() && cur_sp == regs->sp())
185       return UnwindResult::ABORTED;
186 
187     // Exclusive range of expected stack pointer values after the unwind.
188     struct {
189       uintptr_t start;
190       uintptr_t end;
191     } expected_stack_pointer_range = {cur_sp, stack_top};
192     if (regs->sp() < expected_stack_pointer_range.start ||
193         regs->sp() >= expected_stack_pointer_range.end) {
194       return UnwindResult::ABORTED;
195     }
196 
197     if (regs->dex_pc() != 0) {
198       // Add a frame to represent the dex file.
199       EmitDexFrame(regs->dex_pc(), module_cache, stack);
200 
201       // Clear the dex pc so that we don't repeat this frame later.
202       regs->set_dex_pc(0);
203     }
204 
205     // Add the frame to |stack|. Must use GetModuleForAddress rather than
206     // GetExistingModuleForAddress because the unwound-to address may be in a
207     // module associated with a different unwinder.
208     const ModuleCache::Module* module =
209         module_cache->GetModuleForAddress(regs->pc());
210     stack->emplace_back(regs->pc(), module);
211   } while (CanUnwindFrom(stack->back()));
212 
213   // Restore registers necessary for further unwinding in |thread_context|.
214   CopyToRegisterContext(regs.get(), thread_context);
215   return UnwindResult::UNRECOGNIZED_FRAME;
216 }
217 
218 // static
AddInitialModulesFromMaps(const unwindstack::Maps & memory_regions_map,ModuleCache * module_cache)219 void NativeUnwinderAndroid::AddInitialModulesFromMaps(
220     const unwindstack::Maps& memory_regions_map,
221     ModuleCache* module_cache) {
222   // The effect of this loop is to create modules for the executable regions in
223   // the memory map. Regions composing a mapped ELF file are handled specially
224   // however: for just one module extending from the ELF base address to the
225   // *last* executable region backed by the file is implicitly created by
226   // ModuleCache. This avoids duplicate module instances covering the same
227   // in-memory module in the case that a module has multiple mmapped executable
228   // regions.
229   for (const std::unique_ptr<unwindstack::MapInfo>& region :
230        memory_regions_map) {
231     if (!(region->flags & PROT_EXEC))
232       continue;
233 
234     // Use the standard ModuleCache POSIX module representation for ELF files.
235     // This call returns the containing ELF module for the region, creating it
236     // if it doesn't exist.
237     if (module_cache->GetModuleForAddress(
238             static_cast<uintptr_t>(region->start))) {
239       continue;
240     }
241 
242     // Non-ELF modules are represented with NonElfModule.
243     module_cache->AddCustomNativeModule(
244         std::make_unique<NonElfModule>(region.get()));
245   }
246 }
247 
EmitDexFrame(uintptr_t dex_pc,ModuleCache * module_cache,std::vector<Frame> * stack) const248 void NativeUnwinderAndroid::EmitDexFrame(uintptr_t dex_pc,
249                                          ModuleCache* module_cache,
250                                          std::vector<Frame>* stack) const {
251   const ModuleCache::Module* module =
252       module_cache->GetExistingModuleForAddress(dex_pc);
253   if (!module) {
254     // The region containing |dex_pc| may not be in |module_cache| since it's
255     // usually not executable (.dex file). Since non-executable regions
256     // are used much less commonly, it's lazily added here instead of from
257     // AddInitialModulesFromMaps().
258     unwindstack::MapInfo* map_info = memory_regions_map_->Find(dex_pc);
259     if (map_info) {
260       auto new_module = std::make_unique<NonElfModule>(map_info);
261       module = new_module.get();
262       module_cache->AddCustomNativeModule(std::move(new_module));
263     }
264   }
265   stack->emplace_back(dex_pc, module);
266 }
267 
268 }  // namespace base
269