blob: 71665a1351e9bef87c409892990de21409c3f12b [file] [log] [blame]
Christopher Ferris150db122017-12-20 18:49:01 -08001/*
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#include <stdint.h>
18#include <sys/mman.h>
David Srbecky85b5fec2018-02-23 18:06:13 +000019#include <cstddef>
Christopher Ferris150db122017-12-20 18:49:01 -080020
David Srbecky85b5fec2018-02-23 18:06:13 +000021#include <atomic>
22#include <deque>
23#include <map>
Christopher Ferris150db122017-12-20 18:49:01 -080024#include <memory>
David Srbecky85b5fec2018-02-23 18:06:13 +000025#include <unordered_set>
Christopher Ferris150db122017-12-20 18:49:01 -080026#include <vector>
27
28#include <unwindstack/Elf.h>
29#include <unwindstack/JitDebug.h>
30#include <unwindstack/Maps.h>
31#include <unwindstack/Memory.h>
32
David Srbecky85b5fec2018-02-23 18:06:13 +000033#if !defined(NO_LIBDEXFILE_SUPPORT)
34#include <DexFile.h>
35#endif
36
Christopher Ferris150db122017-12-20 18:49:01 -080037// This implements the JIT Compilation Interface.
38// See https://sourceware.org/gdb/onlinedocs/gdb/JIT-Interface.html
39
40namespace unwindstack {
41
David Srbecky85b5fec2018-02-23 18:06:13 +000042// 32-bit platforms may differ in alignment of uint64_t.
43struct Uint64_P {
44 uint64_t value;
Christopher Ferris150db122017-12-20 18:49:01 -080045} __attribute__((packed));
David Srbecky85b5fec2018-02-23 18:06:13 +000046struct Uint64_A {
47 uint64_t value;
48} __attribute__((aligned(8)));
Christopher Ferris150db122017-12-20 18:49:01 -080049
David Srbecky85b5fec2018-02-23 18:06:13 +000050// Wrapper around other memory object which protects us against data races.
51// It will check seqlock after every read, and fail if the seqlock changed.
52// This ensues that the read memory has not been partially modified.
53struct JitMemory : public Memory {
54 size_t Read(uint64_t addr, void* dst, size_t size) override;
55
56 Memory* parent_ = nullptr;
57 uint64_t seqlock_addr_ = 0;
58 uint32_t expected_seqlock_ = 0;
59 bool failed_due_to_race_ = false;
Christopher Ferris150db122017-12-20 18:49:01 -080060};
61
David Srbecky85b5fec2018-02-23 18:06:13 +000062template <typename Symfile>
63struct JitCacheEntry {
64 // PC memory range described by this entry.
65 uint64_t addr_ = 0;
66 uint64_t size_ = 0;
67 std::unique_ptr<Symfile> symfile_;
68
69 bool Init(Maps* maps, JitMemory* memory, uint64_t addr, uint64_t size);
Christopher Ferris150db122017-12-20 18:49:01 -080070};
71
David Srbecky85b5fec2018-02-23 18:06:13 +000072template <typename Symfile, typename PointerT, typename Uint64_T>
73class JitDebugImpl : public JitDebug<Symfile>, public Global {
74 public:
75 static constexpr const char* kDescriptorExtMagic = "Android1";
76 static constexpr int kMaxRaceRetries = 16;
77
78 struct JITCodeEntry {
79 PointerT next;
80 PointerT prev;
81 PointerT symfile_addr;
82 Uint64_T symfile_size;
83 };
84
85 struct JITDescriptor {
86 uint32_t version;
87 uint32_t action_flag;
88 PointerT relevant_entry;
89 PointerT first_entry;
90 };
91
92 // Android-specific extensions.
93 struct JITDescriptorExt {
94 JITDescriptor desc;
95 uint8_t magic[8];
96 uint32_t flags;
97 uint32_t sizeof_descriptor;
98 uint32_t sizeof_entry;
99 uint32_t action_seqlock;
100 uint64_t action_timestamp;
101 };
102
103 JitDebugImpl(ArchEnum arch, std::shared_ptr<Memory>& memory,
104 std::vector<std::string>& search_libs)
105 : Global(memory, search_libs) {
106 SetArch(arch);
107 }
108
109 Symfile* Get(Maps* maps, uint64_t pc) override;
110 virtual bool ReadVariableData(uint64_t offset);
111 virtual void ProcessArch() {}
112 bool Update(Maps* maps);
113 bool Read(Maps* maps, JitMemory* memory);
114
115 bool initialized_ = false;
116 uint64_t descriptor_addr_ = 0; // Non-zero if we have found (non-empty) descriptor.
117 uint64_t seqlock_addr_ = 0; // Re-read entries if the value at this address changes.
118 uint32_t last_seqlock_ = ~0u; // The value of seqlock when we last read the entries.
119
120 std::deque<JitCacheEntry<Symfile>> entries_;
121
122 std::mutex lock_;
Christopher Ferris150db122017-12-20 18:49:01 -0800123};
124
David Srbecky85b5fec2018-02-23 18:06:13 +0000125template <typename Symfile>
126std::unique_ptr<JitDebug<Symfile>> JitDebug<Symfile>::Create(ArchEnum arch,
127 std::shared_ptr<Memory>& memory,
128 std::vector<std::string> search_libs) {
129 typedef JitDebugImpl<Symfile, uint32_t, Uint64_P> JitDebugImpl32P;
130 typedef JitDebugImpl<Symfile, uint32_t, Uint64_A> JitDebugImpl32A;
131 typedef JitDebugImpl<Symfile, uint64_t, Uint64_A> JitDebugImpl64A;
132 switch (arch) {
Christopher Ferris150db122017-12-20 18:49:01 -0800133 case ARCH_X86:
David Srbecky85b5fec2018-02-23 18:06:13 +0000134 static_assert(sizeof(typename JitDebugImpl32P::JITCodeEntry) == 20, "layout");
135 static_assert(sizeof(typename JitDebugImpl32P::JITDescriptor) == 16, "layout");
136 static_assert(sizeof(typename JitDebugImpl32P::JITDescriptorExt) == 48, "layout");
137 return std::unique_ptr<JitDebug>(new JitDebugImpl32P(arch, memory, search_libs));
Christopher Ferris150db122017-12-20 18:49:01 -0800138 break;
Christopher Ferris150db122017-12-20 18:49:01 -0800139 case ARCH_ARM:
140 case ARCH_MIPS:
David Srbecky85b5fec2018-02-23 18:06:13 +0000141 static_assert(sizeof(typename JitDebugImpl32A::JITCodeEntry) == 24, "layout");
142 static_assert(sizeof(typename JitDebugImpl32A::JITDescriptor) == 16, "layout");
143 static_assert(sizeof(typename JitDebugImpl32A::JITDescriptorExt) == 48, "layout");
144 return std::unique_ptr<JitDebug>(new JitDebugImpl32A(arch, memory, search_libs));
Christopher Ferris150db122017-12-20 18:49:01 -0800145 break;
Christopher Ferris150db122017-12-20 18:49:01 -0800146 case ARCH_ARM64:
147 case ARCH_X86_64:
148 case ARCH_MIPS64:
David Srbecky85b5fec2018-02-23 18:06:13 +0000149 static_assert(sizeof(typename JitDebugImpl64A::JITCodeEntry) == 32, "layout");
150 static_assert(sizeof(typename JitDebugImpl64A::JITDescriptor) == 24, "layout");
151 static_assert(sizeof(typename JitDebugImpl64A::JITDescriptorExt) == 56, "layout");
152 return std::unique_ptr<JitDebug>(new JitDebugImpl64A(arch, memory, search_libs));
Christopher Ferris150db122017-12-20 18:49:01 -0800153 break;
David Srbecky85b5fec2018-02-23 18:06:13 +0000154 default:
Christopher Ferris150db122017-12-20 18:49:01 -0800155 abort();
156 }
157}
158
David Srbecky85b5fec2018-02-23 18:06:13 +0000159size_t JitMemory::Read(uint64_t addr, void* dst, size_t size) {
160 if (!parent_->ReadFully(addr, dst, size)) {
161 return 0;
Christopher Ferris150db122017-12-20 18:49:01 -0800162 }
David Srbecky85b5fec2018-02-23 18:06:13 +0000163 // This is required for memory synchronization if the we are working with local memory.
164 // For other types of memory (e.g. remote) this is no-op and has no significant effect.
165 std::atomic_thread_fence(std::memory_order_acquire);
166 uint32_t seen_seqlock;
167 if (!parent_->Read32(seqlock_addr_, &seen_seqlock)) {
168 return 0;
169 }
170 if (seen_seqlock != expected_seqlock_) {
171 failed_due_to_race_ = true;
172 return 0;
173 }
174 return size;
Christopher Ferris150db122017-12-20 18:49:01 -0800175}
176
David Srbecky85b5fec2018-02-23 18:06:13 +0000177template <typename Symfile, typename PointerT, typename Uint64_T>
178bool JitDebugImpl<Symfile, PointerT, Uint64_T>::ReadVariableData(uint64_t addr) {
179 JITDescriptor desc;
180 if (!this->memory_->ReadFully(addr, &desc, sizeof(desc))) {
181 return false;
182 }
183 if (desc.version != 1) {
184 return false;
185 }
186 if (desc.first_entry == 0) {
187 return false; // There could be multiple descriptors. Ignore empty ones.
188 }
189 descriptor_addr_ = addr;
190 JITDescriptorExt desc_ext;
191 if (this->memory_->ReadFully(addr, &desc_ext, sizeof(desc_ext)) &&
192 memcmp(desc_ext.magic, kDescriptorExtMagic, 8) == 0) {
193 seqlock_addr_ = descriptor_addr_ + offsetof(JITDescriptorExt, action_seqlock);
194 } else {
195 // In the absence of Android-specific fields, use the head pointer instead.
196 seqlock_addr_ = descriptor_addr_ + offsetof(JITDescriptor, first_entry);
197 }
198 return true;
199}
200
201template <typename Symfile>
202static const char* GetDescriptorName();
203
204template <>
205const char* GetDescriptorName<Elf>() {
206 return "__jit_debug_descriptor";
207}
208
209template <typename Symfile, typename PointerT, typename Uint64_T>
210Symfile* JitDebugImpl<Symfile, PointerT, Uint64_T>::Get(Maps* maps, uint64_t pc) {
Christopher Ferris150db122017-12-20 18:49:01 -0800211 std::lock_guard<std::mutex> guard(lock_);
212 if (!initialized_) {
David Srbecky85b5fec2018-02-23 18:06:13 +0000213 FindAndReadVariable(maps, GetDescriptorName<Symfile>());
214 initialized_ = true;
Christopher Ferris150db122017-12-20 18:49:01 -0800215 }
216
David Srbecky85b5fec2018-02-23 18:06:13 +0000217 if (descriptor_addr_ == 0) {
218 return nullptr;
Christopher Ferris150db122017-12-20 18:49:01 -0800219 }
220
David Srbecky85b5fec2018-02-23 18:06:13 +0000221 if (!Update(maps)) {
222 return nullptr;
223 }
Christopher Ferris150db122017-12-20 18:49:01 -0800224
David Srbecky85b5fec2018-02-23 18:06:13 +0000225 Symfile* fallback = nullptr;
226 for (auto& entry : entries_) {
227 // Skip entries which are obviously not relevant (if we know the PC range).
228 if (entry.size_ == 0 || (entry.addr_ <= pc && (pc - entry.addr_) < entry.size_)) {
229 // Double check the entry contains the PC in case there are overlapping entries.
230 // This is might happen for native-code due to GC and for DEX due to data sharing.
231 std::string method_name;
232 uint64_t method_offset;
233 if (entry.symfile_->GetFunctionName(pc, &method_name, &method_offset)) {
234 return entry.symfile_.get();
235 }
236 fallback = entry.symfile_.get(); // Tests don't have any symbols.
Christopher Ferris150db122017-12-20 18:49:01 -0800237 }
238 }
David Srbecky85b5fec2018-02-23 18:06:13 +0000239 return fallback; // Not found.
Christopher Ferris150db122017-12-20 18:49:01 -0800240}
241
David Srbecky85b5fec2018-02-23 18:06:13 +0000242// Update JIT entries if needed. It will retry if there are data races.
243template <typename Symfile, typename PointerT, typename Uint64_T>
244bool JitDebugImpl<Symfile, PointerT, Uint64_T>::Update(Maps* maps) {
245 // We might need to retry the whole read in the presence of data races.
246 for (int i = 0; i < kMaxRaceRetries; i++) {
247 // Read the seqlock (counter which is incremented before and after any modification).
248 uint32_t seqlock = 0;
249 if (!this->memory_->Read32(seqlock_addr_, &seqlock)) {
250 return false; // Failed to read seqlock.
251 }
252
253 // Check if anything changed since the last time we checked.
254 if (last_seqlock_ != seqlock) {
255 // Create memory wrapper to allow us to read the entries safely even in a live process.
256 JitMemory safe_memory;
257 safe_memory.parent_ = this->memory_.get();
258 safe_memory.seqlock_addr_ = seqlock_addr_;
259 safe_memory.expected_seqlock_ = seqlock;
260 std::atomic_thread_fence(std::memory_order_acquire);
261
262 // Add all entries to our cache.
263 if (!Read(maps, &safe_memory)) {
264 if (safe_memory.failed_due_to_race_) {
265 sleep(0);
266 continue; // Try again (there was a data race).
267 } else {
268 return false; // Proper failure (we could not read the data).
269 }
270 }
271 last_seqlock_ = seqlock;
272 }
273 return true;
274 }
275 return false; // Too many retries.
276}
277
278// Read all JIT entries. It might randomly fail due to data races.
279template <typename Symfile, typename PointerT, typename Uint64_T>
280bool JitDebugImpl<Symfile, PointerT, Uint64_T>::Read(Maps* maps, JitMemory* memory) {
281 std::unordered_set<uint64_t> seen_entry_addr;
282
283 // Read and verify the descriptor (must be after we have read the initial seqlock).
284 JITDescriptor desc;
285 if (!(memory->ReadFully(descriptor_addr_, &desc, sizeof(desc)))) {
286 return false;
287 }
288
289 entries_.clear();
290 JITCodeEntry entry;
291 for (uint64_t entry_addr = desc.first_entry; entry_addr != 0; entry_addr = entry.next) {
292 // Check for infinite loops in the lined list.
293 if (!seen_entry_addr.emplace(entry_addr).second) {
294 return true; // TODO: Fail when seening infinite loop.
295 }
296
297 // Read the entry (while checking for data races).
298 if (!memory->ReadFully(entry_addr, &entry, sizeof(entry))) {
299 return false;
300 }
301
302 // Copy and load the symfile.
303 entries_.emplace_back(JitCacheEntry<Symfile>());
304 if (!entries_.back().Init(maps, memory, entry.symfile_addr, entry.symfile_size.value)) {
305 return false;
306 }
307 }
308
309 return true;
310}
311
312// Copy and load ELF file.
313template <>
314bool JitCacheEntry<Elf>::Init(Maps*, JitMemory* memory, uint64_t addr, uint64_t size) {
315 // Make a copy of the in-memory symbol file (while checking for data races).
316 std::unique_ptr<MemoryBuffer> buffer(new MemoryBuffer());
317 buffer->Resize(size);
318 if (!memory->ReadFully(addr, buffer->GetPtr(0), buffer->Size())) {
319 return false;
320 }
321
322 // Load and validate the ELF file.
323 symfile_.reset(new Elf(buffer.release()));
324 symfile_->Init();
325 if (!symfile_->valid()) {
326 return false;
327 }
328
329 symfile_->GetTextRange(&addr_, &size_);
330 return true;
331}
332
333template std::unique_ptr<JitDebug<Elf>> JitDebug<Elf>::Create(ArchEnum, std::shared_ptr<Memory>&,
334 std::vector<std::string>);
335
336#if !defined(NO_LIBDEXFILE_SUPPORT)
337
338template <>
339const char* GetDescriptorName<DexFile>() {
340 return "__dex_debug_descriptor";
341}
342
343// Copy and load DEX file.
344template <>
345bool JitCacheEntry<DexFile>::Init(Maps* maps, JitMemory* memory, uint64_t addr, uint64_t) {
346 MapInfo* info = maps->Find(addr);
347 if (info == nullptr) {
348 return false;
349 }
350 symfile_ = DexFile::Create(addr, memory, info);
351 if (symfile_ == nullptr) {
352 return false;
353 }
354 return true;
355}
356
357template std::unique_ptr<JitDebug<DexFile>> JitDebug<DexFile>::Create(ArchEnum,
358 std::shared_ptr<Memory>&,
359 std::vector<std::string>);
360
361#endif
362
Christopher Ferris150db122017-12-20 18:49:01 -0800363} // namespace unwindstack