1 /*
2  * Copyright (C) 2018 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 #include "JITDebugReader.h"
18 
19 #include <inttypes.h>
20 #include <stdio.h>
21 #include <sys/mman.h>
22 #include <sys/uio.h>
23 #include <sys/user.h>
24 #include <unistd.h>
25 
26 #include <algorithm>
27 #include <unordered_map>
28 #include <unordered_set>
29 #include <vector>
30 
31 #include <android-base/file.h>
32 #include <android-base/logging.h>
33 #include <android-base/stringprintf.h>
34 #include <android-base/strings.h>
35 
36 #include "JITDebugReader_impl.h"
37 #include "dso.h"
38 #include "environment.h"
39 #include "read_apk.h"
40 #include "read_dex_file.h"
41 #include "read_elf.h"
42 #include "utils.h"
43 
44 namespace simpleperf {
45 
46 using namespace JITDebugReader_impl;
47 using android::base::StartsWith;
48 using android::base::StringPrintf;
49 
50 // If the size of a symfile is larger than EXPECTED_MAX_SYMFILE_SIZE, we don't want to read it
51 // remotely.
52 static constexpr size_t MAX_JIT_SYMFILE_SIZE = 1 * kMegabyte;
53 
54 // It takes about 30us-130us on Pixel (depending on the cpu frequency) to check if the descriptors
55 // have been updated (most time spent in process_vm_preadv). We want to know if the JIT debug info
56 // changed as soon as possible, while not wasting too much time checking for updates. So use a
57 // period of 100 ms.
58 // In system wide profiling, we may need to check JIT debug info changes for many processes, to
59 // avoid spending all time checking, wait 100 ms between any two checks.
60 static constexpr size_t kUpdateJITDebugInfoIntervalInMs = 100;
61 
62 // map name used for jit zygote cache
63 static const char* kJITZygoteCacheMmapPrefix = "/memfd:jit-zygote-cache";
64 
65 // Match the format of JITDescriptor in art/runtime/jit/debugger_interface.cc.
66 template <typename ADDRT>
67 struct JITDescriptor {
68   uint32_t version;
69   uint32_t action_flag;
70   ADDRT relevant_entry_addr;
71   ADDRT first_entry_addr;
72   uint8_t magic[8];
73   uint32_t flags;
74   uint32_t sizeof_descriptor;
75   uint32_t sizeof_entry;
76   uint32_t action_seqlock;    // incremented before and after any modification
77   uint64_t action_timestamp;  // CLOCK_MONOTONIC time of last action
78 
79   bool Valid() const;
80 
AndroidVersionsimpleperf::JITDescriptor81   int AndroidVersion() const { return magic[7] - '0'; }
82 };
83 
84 // Match the format of JITCodeEntry in art/runtime/jit/debugger_interface.cc
85 // with JITDescriptor.magic == "Android1".
86 template <typename ADDRT>
87 struct JITCodeEntry {
88   ADDRT next_addr;
89   ADDRT prev_addr;
90   ADDRT symfile_addr;
91   uint64_t symfile_size;
92   uint64_t register_timestamp;  // CLOCK_MONOTONIC time of entry registration
93 
Validsimpleperf::JITCodeEntry94   bool Valid() const { return symfile_addr > 0u && symfile_size > 0u; }
95 };
96 
97 // Match the format of JITCodeEntry in art/runtime/jit/debugger_interface.cc
98 // with JITDescriptor.magic == "Android1".
99 template <typename ADDRT>
100 struct __attribute__((packed)) PackedJITCodeEntry {
101   ADDRT next_addr;
102   ADDRT prev_addr;
103   ADDRT symfile_addr;
104   uint64_t symfile_size;
105   uint64_t register_timestamp;
106 
Validsimpleperf::PackedJITCodeEntry107   bool Valid() const { return symfile_addr > 0u && symfile_size > 0u; }
108 };
109 
110 // Match the format of JITCodeEntry in art/runtime/jit/debugger_interface.cc
111 // with JITDescriptor.magic == "Android2".
112 template <typename ADDRT>
113 struct JITCodeEntryV2 {
114   ADDRT next_addr;
115   ADDRT prev_addr;
116   ADDRT symfile_addr;
117   uint64_t symfile_size;
118   uint64_t register_timestamp;  // CLOCK_MONOTONIC time of entry registration
119   uint32_t seqlock;             // even value if valid
120 
Validsimpleperf::JITCodeEntryV2121   bool Valid() const { return (seqlock & 1) == 0; }
122 };
123 
124 // Match the format of JITCodeEntry in art/runtime/jit/debugger_interface.cc
125 // with JITDescriptor.magic == "Android2".
126 template <typename ADDRT>
127 struct __attribute__((packed)) PackedJITCodeEntryV2 {
128   ADDRT next_addr;
129   ADDRT prev_addr;
130   ADDRT symfile_addr;
131   uint64_t symfile_size;
132   uint64_t register_timestamp;
133   uint32_t seqlock;
134 
Validsimpleperf::PackedJITCodeEntryV2135   bool Valid() const { return (seqlock & 1) == 0; }
136 };
137 
138 // Match the format of JITCodeEntry in art/runtime/jit/debugger_interface.cc
139 // with JITDescriptor.magic == "Android2".
140 template <typename ADDRT>
141 struct __attribute__((packed)) PaddedJITCodeEntryV2 {
142   ADDRT next_addr;
143   ADDRT prev_addr;
144   ADDRT symfile_addr;
145   uint64_t symfile_size;
146   uint64_t register_timestamp;
147   uint32_t seqlock;
148   uint32_t pad;
149 
Validsimpleperf::PaddedJITCodeEntryV2150   bool Valid() const { return (seqlock & 1) == 0; }
151 };
152 
153 using JITDescriptor32 = JITDescriptor<uint32_t>;
154 using JITDescriptor64 = JITDescriptor<uint64_t>;
155 
156 #if defined(__x86_64__)
157 // Make sure simpleperf built for i386 and x86_64 see the correct JITCodeEntry layout of i386.
158 using JITCodeEntry32 = PackedJITCodeEntry<uint32_t>;
159 using JITCodeEntry32V2 = PackedJITCodeEntryV2<uint32_t>;
160 #else
161 using JITCodeEntry32 = JITCodeEntry<uint32_t>;
162 using JITCodeEntry32V2 = JITCodeEntryV2<uint32_t>;
163 #endif
164 
165 using JITCodeEntry64 = JITCodeEntry<uint64_t>;
166 #if defined(__i386__)
167 // Make sure simpleperf built for i386 and x86_64 see the correct JITCodeEntry layout of x86_64.
168 using JITCodeEntry64V2 = PaddedJITCodeEntryV2<uint64_t>;
169 #else
170 using JITCodeEntry64V2 = JITCodeEntryV2<uint64_t>;
171 #endif
172 
173 template <typename ADDRT>
Valid() const174 bool JITDescriptor<ADDRT>::Valid() const {
175   const char* magic_str = reinterpret_cast<const char*>(magic);
176   if (version != 1 ||
177       !(strncmp(magic_str, "Android1", 8) == 0 || strncmp(magic_str, "Android2", 8) == 0)) {
178     return false;
179   }
180   if (sizeof(*this) != sizeof_descriptor) {
181     return false;
182   }
183   if (sizeof(ADDRT) == 4) {
184     return sizeof_entry == (AndroidVersion() == 1) ? sizeof(JITCodeEntry32)
185                                                    : sizeof(JITCodeEntry32V2);
186   }
187   return sizeof_entry == (AndroidVersion() == 1) ? sizeof(JITCodeEntry64)
188                                                  : sizeof(JITCodeEntry64V2);
189 }
190 
191 // We want to support both 64-bit and 32-bit simpleperf when profiling either 64-bit or 32-bit
192 // apps. So using static_asserts to make sure that simpleperf on arm and aarch64 having the same
193 // view of structures, and simpleperf on i386 and x86_64 having the same view of structures.
194 static_assert(sizeof(JITDescriptor32) == 48, "");
195 static_assert(sizeof(JITDescriptor64) == 56, "");
196 
197 #if defined(__i386__) or defined(__x86_64__)
198 static_assert(sizeof(JITCodeEntry32) == 28, "");
199 static_assert(sizeof(JITCodeEntry32V2) == 32, "");
200 static_assert(sizeof(JITCodeEntry64) == 40, "");
201 static_assert(sizeof(JITCodeEntry64V2) == 48, "");
202 #else
203 static_assert(sizeof(JITCodeEntry32) == 32, "");
204 static_assert(sizeof(JITCodeEntry32V2) == 40, "");
205 static_assert(sizeof(JITCodeEntry64) == 40, "");
206 static_assert(sizeof(JITCodeEntry64V2) == 48, "");
207 #endif
208 
JITDebugReader(const std::string & symfile_prefix,SymFileOption symfile_option,SyncOption sync_option)209 JITDebugReader::JITDebugReader(const std::string& symfile_prefix, SymFileOption symfile_option,
210                                SyncOption sync_option)
211     : symfile_prefix_(symfile_prefix), symfile_option_(symfile_option), sync_option_(sync_option) {}
212 
~JITDebugReader()213 JITDebugReader::~JITDebugReader() {}
214 
RegisterDebugInfoCallback(IOEventLoop * loop,const debug_info_callback_t & callback)215 bool JITDebugReader::RegisterDebugInfoCallback(IOEventLoop* loop,
216                                                const debug_info_callback_t& callback) {
217   debug_info_callback_ = callback;
218   read_event_ = loop->AddPeriodicEvent(SecondToTimeval(kUpdateJITDebugInfoIntervalInMs / 1000.0),
219                                        [this]() { return ReadAllProcesses(); });
220   return (read_event_ != nullptr && IOEventLoop::DisableEvent(read_event_));
221 }
222 
MonitorProcess(pid_t pid)223 bool JITDebugReader::MonitorProcess(pid_t pid) {
224   if (processes_.find(pid) == processes_.end()) {
225     processes_[pid].pid = pid;
226     LOG(DEBUG) << "Start monitoring process " << pid;
227     if (processes_.size() == 1u) {
228       if (!IOEventLoop::EnableEvent(read_event_)) {
229         return false;
230       }
231     }
232   }
233   return true;
234 }
235 
IsArtLib(const std::string & filename)236 static bool IsArtLib(const std::string& filename) {
237   return android::base::EndsWith(filename, "libart.so") ||
238          android::base::EndsWith(filename, "libartd.so");
239 }
240 
UpdateRecord(const Record * record)241 bool JITDebugReader::UpdateRecord(const Record* record) {
242   if (record->type() == PERF_RECORD_MMAP) {
243     auto r = static_cast<const MmapRecord*>(record);
244     if (IsArtLib(r->filename)) {
245       pids_with_art_lib_.emplace(r->data->pid, false);
246     }
247   } else if (record->type() == PERF_RECORD_MMAP2) {
248     auto r = static_cast<const Mmap2Record*>(record);
249     if (IsArtLib(r->filename)) {
250       pids_with_art_lib_.emplace(r->data->pid, false);
251     }
252   } else if (record->type() == PERF_RECORD_FORK) {
253     auto r = static_cast<const ForkRecord*>(record);
254     if (r->data->pid != r->data->ppid &&
255         pids_with_art_lib_.find(r->data->ppid) != pids_with_art_lib_.end()) {
256       pids_with_art_lib_.emplace(r->data->pid, false);
257     }
258   } else if (record->type() == PERF_RECORD_SAMPLE) {
259     auto r = static_cast<const SampleRecord*>(record);
260     auto it = pids_with_art_lib_.find(r->tid_data.pid);
261     if (it != pids_with_art_lib_.end() && !it->second) {
262       it->second = true;
263       if (!MonitorProcess(r->tid_data.pid)) {
264         return false;
265       }
266       return ReadProcess(r->tid_data.pid);
267     }
268   }
269   return FlushDebugInfo(record->Timestamp());
270 }
271 
FlushDebugInfo(uint64_t timestamp)272 bool JITDebugReader::FlushDebugInfo(uint64_t timestamp) {
273   if (sync_option_ == SyncOption::kSyncWithRecords) {
274     if (!debug_info_q_.empty() && debug_info_q_.top().timestamp < timestamp) {
275       std::vector<JITDebugInfo> debug_info;
276       while (!debug_info_q_.empty() && debug_info_q_.top().timestamp < timestamp) {
277         debug_info.emplace_back(debug_info_q_.top());
278         debug_info_q_.pop();
279       }
280       return debug_info_callback_(debug_info, false);
281     }
282   }
283   return true;
284 }
285 
ReadAllProcesses()286 bool JITDebugReader::ReadAllProcesses() {
287   if (!IOEventLoop::DisableEvent(read_event_)) {
288     return false;
289   }
290   std::vector<JITDebugInfo> debug_info;
291   for (auto it = processes_.begin(); it != processes_.end();) {
292     Process& process = it->second;
293     if (!ReadProcess(process, &debug_info)) {
294       return false;
295     }
296     if (process.died) {
297       LOG(DEBUG) << "Stop monitoring process " << process.pid;
298       it = processes_.erase(it);
299     } else {
300       ++it;
301     }
302   }
303   if (!AddDebugInfo(std::move(debug_info), true)) {
304     return false;
305   }
306   if (!processes_.empty()) {
307     return IOEventLoop::EnableEvent(read_event_);
308   }
309   return true;
310 }
311 
ReadProcess(pid_t pid)312 bool JITDebugReader::ReadProcess(pid_t pid) {
313   auto it = processes_.find(pid);
314   if (it != processes_.end()) {
315     std::vector<JITDebugInfo> debug_info;
316     return ReadProcess(it->second, &debug_info) && AddDebugInfo(std::move(debug_info), false);
317   }
318   return true;
319 }
320 
ReadProcess(Process & process,std::vector<JITDebugInfo> * debug_info)321 bool JITDebugReader::ReadProcess(Process& process, std::vector<JITDebugInfo>* debug_info) {
322   if (process.died || (!process.initialized && !InitializeProcess(process))) {
323     return true;
324   }
325   // 1. Read descriptors.
326   Descriptor jit_descriptor;
327   Descriptor dex_descriptor;
328   if (!ReadDescriptors(process, &jit_descriptor, &dex_descriptor)) {
329     return true;
330   }
331   // 2. Return if descriptors are not changed.
332   if (jit_descriptor.action_seqlock == process.last_jit_descriptor.action_seqlock &&
333       dex_descriptor.action_seqlock == process.last_dex_descriptor.action_seqlock) {
334     return true;
335   }
336 
337   // 3. Read new symfiles.
338   return ReadDebugInfo(process, jit_descriptor, debug_info) &&
339          ReadDebugInfo(process, dex_descriptor, debug_info);
340 }
341 
ReadDebugInfo(Process & process,Descriptor & new_descriptor,std::vector<JITDebugInfo> * debug_info)342 bool JITDebugReader::ReadDebugInfo(Process& process, Descriptor& new_descriptor,
343                                    std::vector<JITDebugInfo>* debug_info) {
344   DescriptorType type = new_descriptor.type;
345   Descriptor* old_descriptor =
346       (type == DescriptorType::kJIT) ? &process.last_jit_descriptor : &process.last_dex_descriptor;
347 
348   bool has_update = new_descriptor.action_seqlock != old_descriptor->action_seqlock &&
349                     (new_descriptor.action_seqlock & 1) == 0;
350   LOG(DEBUG) << (type == DescriptorType::kJIT ? "JIT" : "Dex") << " symfiles of pid " << process.pid
351              << ": old seqlock " << old_descriptor->action_seqlock << ", new seqlock "
352              << new_descriptor.action_seqlock;
353   if (!has_update) {
354     return true;
355   }
356   std::vector<CodeEntry> new_entries;
357   // Adding or removing one code entry will make two increments of action_seqlock. So we should
358   // not read more than (seqlock_diff / 2) new entries.
359   uint32_t read_entry_limit = (new_descriptor.action_seqlock - old_descriptor->action_seqlock) / 2;
360   if (!ReadNewCodeEntries(process, new_descriptor, old_descriptor->action_timestamp,
361                           read_entry_limit, &new_entries)) {
362     return true;
363   }
364   // If the descriptor was changed while we were reading new entries, skip reading debug info this
365   // time.
366   if (IsDescriptorChanged(process, new_descriptor)) {
367     return true;
368   }
369   LOG(DEBUG) << (type == DescriptorType::kJIT ? "JIT" : "Dex") << " symfiles of pid " << process.pid
370              << ": read " << new_entries.size() << " new entries";
371 
372   if (!new_entries.empty()) {
373     if (type == DescriptorType::kJIT) {
374       if (!ReadJITCodeDebugInfo(process, new_entries, debug_info)) {
375         return false;
376       }
377     } else {
378       ReadDexFileDebugInfo(process, new_entries, debug_info);
379     }
380   }
381   *old_descriptor = new_descriptor;
382   return true;
383 }
384 
IsDescriptorChanged(Process & process,Descriptor & prev_descriptor)385 bool JITDebugReader::IsDescriptorChanged(Process& process, Descriptor& prev_descriptor) {
386   Descriptor tmp_jit_descriptor;
387   Descriptor tmp_dex_descriptor;
388   if (!ReadDescriptors(process, &tmp_jit_descriptor, &tmp_dex_descriptor)) {
389     return true;
390   }
391   if (prev_descriptor.type == DescriptorType::kJIT) {
392     return prev_descriptor.action_seqlock != tmp_jit_descriptor.action_seqlock;
393   }
394   return prev_descriptor.action_seqlock != tmp_dex_descriptor.action_seqlock;
395 }
396 
InitializeProcess(Process & process)397 bool JITDebugReader::InitializeProcess(Process& process) {
398   // 1. Read map file to find the location of libart.so.
399   std::vector<ThreadMmap> thread_mmaps;
400   if (!GetThreadMmapsInProcess(process.pid, &thread_mmaps)) {
401     process.died = true;
402     return false;
403   }
404   std::string art_lib_path;
405   uint64_t min_vaddr_in_memory;
406   for (auto& map : thread_mmaps) {
407     if ((map.prot & PROT_EXEC) && IsArtLib(map.name)) {
408       art_lib_path = map.name;
409       min_vaddr_in_memory = map.start_addr;
410       break;
411     }
412   }
413   if (art_lib_path.empty()) {
414     return false;
415   }
416 
417   // 2. Read libart.so to find the addresses of __jit_debug_descriptor and __dex_debug_descriptor.
418   const DescriptorsLocation* location = GetDescriptorsLocation(art_lib_path);
419   if (location == nullptr) {
420     return false;
421   }
422   process.is_64bit = location->is_64bit;
423   process.jit_descriptor_addr = location->jit_descriptor_addr + min_vaddr_in_memory;
424   process.dex_descriptor_addr = location->dex_descriptor_addr + min_vaddr_in_memory;
425 
426   for (auto& map : thread_mmaps) {
427     if (StartsWith(map.name, kJITZygoteCacheMmapPrefix)) {
428       process.jit_zygote_cache_ranges_.emplace_back(map.start_addr, map.start_addr + map.len);
429     }
430   }
431 
432   process.initialized = true;
433   return true;
434 }
435 
GetDescriptorsLocation(const std::string & art_lib_path)436 const JITDebugReader::DescriptorsLocation* JITDebugReader::GetDescriptorsLocation(
437     const std::string& art_lib_path) {
438   auto it = descriptors_location_cache_.find(art_lib_path);
439   if (it != descriptors_location_cache_.end()) {
440     return it->second.jit_descriptor_addr == 0u ? nullptr : &it->second;
441   }
442   DescriptorsLocation& location = descriptors_location_cache_[art_lib_path];
443 
444   // Read libart.so to find the addresses of __jit_debug_descriptor and __dex_debug_descriptor.
445   ElfStatus status;
446   auto elf = ElfFile::Open(art_lib_path, &status);
447   if (!elf) {
448     LOG(ERROR) << "failed to read min_exec_vaddr from " << art_lib_path << ": " << status;
449     return nullptr;
450   }
451 
452   const size_t kPageSize = getpagesize();
453   const size_t kPageMask = ~(kPageSize - 1);
454   uint64_t file_offset;
455   uint64_t min_vaddr_in_file = elf->ReadMinExecutableVaddr(&file_offset);
456   // min_vaddr_in_file is the min vaddr of executable segments. It may not be page aligned.
457   // And dynamic linker will create map mapping to (segment.p_vaddr & kPageMask).
458   uint64_t aligned_segment_vaddr = min_vaddr_in_file & kPageMask;
459   const char* jit_str = "__jit_debug_descriptor";
460   const char* dex_str = "__dex_debug_descriptor";
461   uint64_t jit_addr = 0u;
462   uint64_t dex_addr = 0u;
463 
464   auto callback = [&](const ElfFileSymbol& symbol) {
465     if (symbol.name == jit_str) {
466       jit_addr = symbol.vaddr - aligned_segment_vaddr;
467     } else if (symbol.name == dex_str) {
468       dex_addr = symbol.vaddr - aligned_segment_vaddr;
469     }
470   };
471   elf->ParseDynamicSymbols(callback);
472   if (jit_addr == 0u || dex_addr == 0u) {
473     return nullptr;
474   }
475   location.is_64bit = elf->Is64Bit();
476   location.jit_descriptor_addr = jit_addr;
477   location.dex_descriptor_addr = dex_addr;
478   return &location;
479 }
480 
ReadRemoteMem(Process & process,uint64_t remote_addr,uint64_t size,void * data)481 bool JITDebugReader::ReadRemoteMem(Process& process, uint64_t remote_addr, uint64_t size,
482                                    void* data) {
483   iovec local_iov;
484   local_iov.iov_base = data;
485   local_iov.iov_len = size;
486   iovec remote_iov;
487   remote_iov.iov_base = reinterpret_cast<void*>(static_cast<uintptr_t>(remote_addr));
488   remote_iov.iov_len = size;
489   ssize_t result = process_vm_readv(process.pid, &local_iov, 1, &remote_iov, 1, 0);
490   if (static_cast<size_t>(result) != size) {
491     PLOG(DEBUG) << "ReadRemoteMem("
492                 << " pid " << process.pid << ", addr " << std::hex << remote_addr << ", size "
493                 << size << ") failed";
494     process.died = true;
495     return false;
496   }
497   return true;
498 }
499 
ReadDescriptors(Process & process,Descriptor * jit_descriptor,Descriptor * dex_descriptor)500 bool JITDebugReader::ReadDescriptors(Process& process, Descriptor* jit_descriptor,
501                                      Descriptor* dex_descriptor) {
502   if (process.is_64bit) {
503     return ReadDescriptorsImpl<JITDescriptor64>(process, jit_descriptor, dex_descriptor);
504   }
505   return ReadDescriptorsImpl<JITDescriptor32>(process, jit_descriptor, dex_descriptor);
506 }
507 
508 template <typename DescriptorT>
ReadDescriptorsImpl(Process & process,Descriptor * jit_descriptor,Descriptor * dex_descriptor)509 bool JITDebugReader::ReadDescriptorsImpl(Process& process, Descriptor* jit_descriptor,
510                                          Descriptor* dex_descriptor) {
511   DescriptorT raw_jit_descriptor;
512   DescriptorT raw_dex_descriptor;
513   iovec local_iovs[2];
514   local_iovs[0].iov_base = &raw_jit_descriptor;
515   local_iovs[0].iov_len = sizeof(DescriptorT);
516   local_iovs[1].iov_base = &raw_dex_descriptor;
517   local_iovs[1].iov_len = sizeof(DescriptorT);
518   iovec remote_iovs[2];
519   remote_iovs[0].iov_base =
520       reinterpret_cast<void*>(static_cast<uintptr_t>(process.jit_descriptor_addr));
521   remote_iovs[0].iov_len = sizeof(DescriptorT);
522   remote_iovs[1].iov_base =
523       reinterpret_cast<void*>(static_cast<uintptr_t>(process.dex_descriptor_addr));
524   remote_iovs[1].iov_len = sizeof(DescriptorT);
525   ssize_t result = process_vm_readv(process.pid, local_iovs, 2, remote_iovs, 2, 0);
526   if (static_cast<size_t>(result) != sizeof(DescriptorT) * 2) {
527     PLOG(DEBUG) << "ReadDescriptor(pid " << process.pid << ", jit_addr " << std::hex
528                 << process.jit_descriptor_addr << ", dex_addr " << process.dex_descriptor_addr
529                 << ") failed";
530     process.died = true;
531     return false;
532   }
533 
534   if (!ParseDescriptor(raw_jit_descriptor, jit_descriptor) ||
535       !ParseDescriptor(raw_dex_descriptor, dex_descriptor)) {
536     return false;
537   }
538   jit_descriptor->type = DescriptorType::kJIT;
539   dex_descriptor->type = DescriptorType::kDEX;
540   return true;
541 }
542 
543 template <typename DescriptorT>
ParseDescriptor(const DescriptorT & raw_descriptor,Descriptor * descriptor)544 bool JITDebugReader::ParseDescriptor(const DescriptorT& raw_descriptor, Descriptor* descriptor) {
545   if (!raw_descriptor.Valid()) {
546     return false;
547   }
548   descriptor->action_seqlock = raw_descriptor.action_seqlock;
549   descriptor->action_timestamp = raw_descriptor.action_timestamp;
550   descriptor->first_entry_addr = raw_descriptor.first_entry_addr;
551   descriptor->version = raw_descriptor.AndroidVersion();
552   return true;
553 }
554 
555 // Read new code entries with timestamp > last_action_timestamp.
556 // Since we don't stop the app process while reading code entries, it is possible we are reading
557 // broken data. So return false once we detect that the data is broken.
ReadNewCodeEntries(Process & process,const Descriptor & descriptor,uint64_t last_action_timestamp,uint32_t read_entry_limit,std::vector<CodeEntry> * new_code_entries)558 bool JITDebugReader::ReadNewCodeEntries(Process& process, const Descriptor& descriptor,
559                                         uint64_t last_action_timestamp, uint32_t read_entry_limit,
560                                         std::vector<CodeEntry>* new_code_entries) {
561   if (descriptor.version == 1) {
562     if (process.is_64bit) {
563       return ReadNewCodeEntriesImpl<JITCodeEntry64>(process, descriptor, last_action_timestamp,
564                                                     read_entry_limit, new_code_entries);
565     }
566     return ReadNewCodeEntriesImpl<JITCodeEntry32>(process, descriptor, last_action_timestamp,
567                                                   read_entry_limit, new_code_entries);
568   }
569   if (descriptor.version == 2) {
570     if (process.is_64bit) {
571       return ReadNewCodeEntriesImpl<JITCodeEntry64V2>(process, descriptor, last_action_timestamp,
572                                                       read_entry_limit, new_code_entries);
573     }
574     return ReadNewCodeEntriesImpl<JITCodeEntry32V2>(process, descriptor, last_action_timestamp,
575                                                     read_entry_limit, new_code_entries);
576   }
577   return false;
578 }
579 
580 template <typename CodeEntryT>
ReadNewCodeEntriesImpl(Process & process,const Descriptor & descriptor,uint64_t last_action_timestamp,uint32_t read_entry_limit,std::vector<CodeEntry> * new_code_entries)581 bool JITDebugReader::ReadNewCodeEntriesImpl(Process& process, const Descriptor& descriptor,
582                                             uint64_t last_action_timestamp,
583                                             uint32_t read_entry_limit,
584                                             std::vector<CodeEntry>* new_code_entries) {
585   uint64_t current_entry_addr = descriptor.first_entry_addr;
586   uint64_t prev_entry_addr = 0u;
587   std::unordered_set<uint64_t> entry_addr_set;
588   for (size_t i = 0u; i < read_entry_limit && current_entry_addr != 0u; ++i) {
589     if (entry_addr_set.find(current_entry_addr) != entry_addr_set.end()) {
590       // We enter a loop, which means a broken linked list.
591       return false;
592     }
593     CodeEntryT entry;
594     if (!ReadRemoteMem(process, current_entry_addr, sizeof(entry), &entry)) {
595       return false;
596     }
597     if (entry.prev_addr != prev_entry_addr || !entry.Valid()) {
598       // A broken linked list
599       return false;
600     }
601     if (entry.register_timestamp <= last_action_timestamp) {
602       // The linked list has entries with timestamp in decreasing order. So stop searching
603       // once we hit an entry with timestamp <= last_action_timestmap.
604       break;
605     }
606     if (entry.symfile_size > 0) {
607       CodeEntry code_entry;
608       code_entry.addr = current_entry_addr;
609       code_entry.symfile_addr = entry.symfile_addr;
610       code_entry.symfile_size = entry.symfile_size;
611       code_entry.timestamp = entry.register_timestamp;
612       new_code_entries->push_back(code_entry);
613     }
614     entry_addr_set.insert(current_entry_addr);
615     prev_entry_addr = current_entry_addr;
616     current_entry_addr = entry.next_addr;
617   }
618   return true;
619 }
620 
ReadJITCodeDebugInfo(Process & process,const std::vector<CodeEntry> & jit_entries,std::vector<JITDebugInfo> * debug_info)621 bool JITDebugReader::ReadJITCodeDebugInfo(Process& process,
622                                           const std::vector<CodeEntry>& jit_entries,
623                                           std::vector<JITDebugInfo>* debug_info) {
624   std::vector<char> data;
625 
626   for (auto& jit_entry : jit_entries) {
627     if (jit_entry.symfile_size > MAX_JIT_SYMFILE_SIZE) {
628       continue;
629     }
630     if (data.size() < jit_entry.symfile_size) {
631       data.resize(jit_entry.symfile_size);
632     }
633     if (!ReadRemoteMem(process, jit_entry.symfile_addr, jit_entry.symfile_size, data.data())) {
634       continue;
635     }
636     if (!IsValidElfFileMagic(data.data(), jit_entry.symfile_size)) {
637       continue;
638     }
639     TempSymFile* symfile = GetTempSymFile(process, jit_entry);
640     if (symfile == nullptr) {
641       return false;
642     }
643     uint64_t file_offset = symfile->GetOffset();
644     if (!symfile->WriteEntry(data.data(), jit_entry.symfile_size)) {
645       return false;
646     }
647 
648     auto callback = [&](const ElfFileSymbol& symbol) {
649       if (symbol.len == 0) {  // Some arm labels can have zero length.
650         return;
651       }
652       // Pass out the location of the symfile for unwinding and symbolization.
653       std::string location_in_file =
654           StringPrintf(":%" PRIu64 "-%" PRIu64, file_offset, file_offset + jit_entry.symfile_size);
655       debug_info->emplace_back(process.pid, jit_entry.timestamp, symbol.vaddr, symbol.len,
656                                symfile->GetPath() + location_in_file, file_offset);
657 
658       LOG(VERBOSE) << "JITSymbol " << symbol.name << " at [" << std::hex << symbol.vaddr << " - "
659                    << (symbol.vaddr + symbol.len) << " with size " << symbol.len << " in "
660                    << symfile->GetPath() << location_in_file;
661     };
662     ElfStatus status;
663     auto elf = ElfFile::Open(data.data(), jit_entry.symfile_size, &status);
664     if (elf) {
665       elf->ParseSymbols(callback);
666     }
667   }
668 
669   if (app_symfile_) {
670     app_symfile_->Flush();
671   }
672   if (zygote_symfile_) {
673     zygote_symfile_->Flush();
674   }
675   return true;
676 }
677 
GetTempSymFile(Process & process,const CodeEntry & jit_entry)678 TempSymFile* JITDebugReader::GetTempSymFile(Process& process, const CodeEntry& jit_entry) {
679   bool is_zygote = false;
680   for (const auto& range : process.jit_zygote_cache_ranges_) {
681     if (jit_entry.symfile_addr >= range.first && jit_entry.symfile_addr < range.second) {
682       is_zygote = true;
683       break;
684     }
685   }
686   if (is_zygote) {
687     if (!zygote_symfile_) {
688       std::string path = symfile_prefix_ + "_" + kJITZygoteCacheFile;
689       zygote_symfile_ =
690           TempSymFile::Create(std::move(path), symfile_option_ == SymFileOption::kDropSymFiles);
691     }
692     return zygote_symfile_.get();
693   }
694   if (!app_symfile_) {
695     std::string path = symfile_prefix_ + "_" + kJITAppCacheFile;
696     app_symfile_ =
697         TempSymFile::Create(std::move(path), symfile_option_ == SymFileOption::kDropSymFiles);
698   }
699   return app_symfile_.get();
700 }
701 
ReadDexFileDebugInfo(Process & process,const std::vector<CodeEntry> & dex_entries,std::vector<JITDebugInfo> * debug_info)702 void JITDebugReader::ReadDexFileDebugInfo(Process& process,
703                                           const std::vector<CodeEntry>& dex_entries,
704                                           std::vector<JITDebugInfo>* debug_info) {
705   std::vector<ThreadMmap> thread_mmaps;
706   if (!GetThreadMmapsInProcess(process.pid, &thread_mmaps)) {
707     process.died = true;
708     return;
709   }
710   auto comp = [](const ThreadMmap& map, uint64_t addr) { return map.start_addr <= addr; };
711   for (auto& dex_entry : dex_entries) {
712     auto it =
713         std::lower_bound(thread_mmaps.begin(), thread_mmaps.end(), dex_entry.symfile_addr, comp);
714     if (it == thread_mmaps.begin()) {
715       continue;
716     }
717     --it;
718     if (it->start_addr + it->len < dex_entry.symfile_addr + dex_entry.symfile_size) {
719       continue;
720     }
721     std::string file_path;
722     std::string zip_path;
723     std::string entry_path;
724     std::shared_ptr<ThreadMmap> dex_file_map;
725     std::vector<Symbol> symbols;
726     // Offset of dex file in .vdex file or .apk file.
727     uint64_t dex_file_offset = dex_entry.symfile_addr - it->start_addr + it->pgoff;
728     if (ParseExtractedInMemoryPath(it->name, &zip_path, &entry_path)) {
729       file_path = GetUrlInApk(zip_path, entry_path);
730       dex_file_map = std::make_shared<ThreadMmap>(*it);
731     } else if (IsRegularFile(it->name)) {
732       file_path = it->name;
733     } else {
734       // Read a dex file only existing in memory.
735       file_path = StringPrintf("%s_pid_%d_addr_0x%" PRIx64 "-0x%" PRIx64 "", kDexFileInMemoryPrefix,
736                                process.pid, dex_entry.symfile_addr,
737                                dex_entry.symfile_addr + dex_entry.symfile_size);
738       dex_file_map.reset(new ThreadMmap(dex_entry.symfile_addr, dex_entry.symfile_size, 0,
739                                         file_path.c_str(), PROT_READ));
740       symbols = ReadDexFileSymbolsInMemory(process, dex_entry.symfile_addr, dex_entry.symfile_size);
741       dex_file_offset = 0;
742     }
743 
744     debug_info->emplace_back(process.pid, dex_entry.timestamp, dex_file_offset, file_path,
745                              dex_file_map, std::move(symbols));
746     LOG(VERBOSE) << "DexFile " << file_path << "+" << std::hex << dex_file_offset << " in map ["
747                  << it->start_addr << " - " << (it->start_addr + it->len) << "] with size "
748                  << dex_entry.symfile_size;
749   }
750 }
751 
ReadDexFileSymbolsInMemory(Process & process,uint64_t addr,uint64_t size)752 std::vector<Symbol> JITDebugReader::ReadDexFileSymbolsInMemory(Process& process, uint64_t addr,
753                                                                uint64_t size) {
754   std::vector<Symbol> symbols;
755   std::vector<uint8_t> data(size, 0);
756   if (!ReadRemoteMem(process, addr, size, data.data())) {
757     LOG(DEBUG) << "failed to read dex file in memory for process " << process.pid << ", addr "
758                << std::hex << addr << "-" << (addr + size);
759     return symbols;
760   }
761 
762   auto process_symbol = [&](DexFileSymbol* symbol) {
763     symbols.emplace_back(symbol->name, symbol->addr, symbol->size);
764   };
765   if (!ReadSymbolsFromDexFileInMemory(data.data(), data.size(), "dex_file_in_memory", {0},
766                                       process_symbol)) {
767     LOG(DEBUG) << "failed to parse dex file in memory for process " << process.pid << ", addr "
768                << std::hex << addr << "-" << (addr + size);
769     return symbols;
770   }
771   std::sort(symbols.begin(), symbols.end(), Symbol::CompareValueByAddr);
772   return symbols;
773 }
774 
AddDebugInfo(std::vector<JITDebugInfo> debug_info,bool sync_kernel_records)775 bool JITDebugReader::AddDebugInfo(std::vector<JITDebugInfo> debug_info, bool sync_kernel_records) {
776   if (!debug_info.empty()) {
777     if (sync_option_ == SyncOption::kSyncWithRecords) {
778       for (auto& info : debug_info) {
779         debug_info_q_.push(std::move(info));
780       }
781     } else {
782       return debug_info_callback_(std::move(debug_info), sync_kernel_records);
783     }
784   }
785   return true;
786 }
787 
788 }  // namespace simpleperf
789