• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

system/core


Commit MetaInfo

Revisión4d03a384c2cd5a8b0cd65b682cf7653aff0b0379 (tree)
Tiempo2019-04-03 17:39:57
AutorDavid Srbecky <dsrbecky@goog...>
Commiterandroid-build-merger

Log Message

Merge "Check for data races when reading JIT/DEX entries." am: 59c70a5b75
am: 9363485979

Change-Id: If702c873330b09020dd701f5e786a03ca4d28ac0

Cambiar Resumen

Diferencia incremental

--- a/debuggerd/crash_dump.cpp
+++ b/debuggerd/crash_dump.cpp
@@ -48,7 +48,6 @@
4848 #define ATRACE_TAG ATRACE_TAG_BIONIC
4949 #include <utils/Trace.h>
5050
51-#include <unwindstack/DexFiles.h>
5251 #include <unwindstack/JitDebug.h>
5352 #include <unwindstack/Maps.h>
5453 #include <unwindstack/Memory.h>
@@ -567,7 +566,7 @@ int main(int argc, char** argv) {
567566
568567 // TODO: Use seccomp to lock ourselves down.
569568 unwindstack::UnwinderFromPid unwinder(256, vm_pid);
570- if (!unwinder.Init(unwindstack::Regs::CurrentArch())) {
569+ if (!unwinder.Init()) {
571570 LOG(FATAL) << "Failed to init unwinder object.";
572571 }
573572
--- a/debuggerd/handler/debuggerd_fallback.cpp
+++ b/debuggerd/handler/debuggerd_fallback.cpp
@@ -42,7 +42,6 @@
4242 #include <android-base/file.h>
4343 #include <android-base/unique_fd.h>
4444 #include <async_safe/log.h>
45-#include <unwindstack/DexFiles.h>
4645 #include <unwindstack/JitDebug.h>
4746 #include <unwindstack/Maps.h>
4847 #include <unwindstack/Memory.h>
@@ -81,12 +80,12 @@ static void debuggerd_fallback_trace(int output_fd, ucontext_t* ucontext) {
8180 thread.pid = getpid();
8281 thread.tid = gettid();
8382 thread.thread_name = get_thread_name(gettid());
84- unwindstack::ArchEnum arch = unwindstack::Regs::CurrentArch();
85- thread.registers.reset(unwindstack::Regs::CreateFromUcontext(arch, ucontext));
83+ thread.registers.reset(
84+ unwindstack::Regs::CreateFromUcontext(unwindstack::Regs::CurrentArch(), ucontext));
8685
8786 // TODO: Create this once and store it in a global?
8887 unwindstack::UnwinderFromPid unwinder(kMaxFrames, getpid());
89- if (unwinder.Init(arch)) {
88+ if (unwinder.Init()) {
9089 dump_backtrace_thread(output_fd, &unwinder, thread);
9190 } else {
9291 async_safe_format_log(ANDROID_LOG_ERROR, "libc", "Unable to init unwinder.");
--- a/debuggerd/libdebuggerd/tombstone.cpp
+++ b/debuggerd/libdebuggerd/tombstone.cpp
@@ -44,7 +44,6 @@
4444 #include <log/log.h>
4545 #include <log/logprint.h>
4646 #include <private/android_filesystem_config.h>
47-#include <unwindstack/DexFiles.h>
4847 #include <unwindstack/JitDebug.h>
4948 #include <unwindstack/Maps.h>
5049 #include <unwindstack/Memory.h>
@@ -650,7 +649,7 @@ void engrave_tombstone_ucontext(int tombstone_fd, uint64_t abort_msg_address, si
650649 };
651650
652651 unwindstack::UnwinderFromPid unwinder(kMaxFrames, pid);
653- if (!unwinder.Init(unwindstack::Regs::CurrentArch())) {
652+ if (!unwinder.Init()) {
654653 LOG(FATAL) << "Failed to init unwinder object.";
655654 }
656655
--- a/libbacktrace/UnwindStack.cpp
+++ b/libbacktrace/UnwindStack.cpp
@@ -32,9 +32,6 @@
3232 #include <unwindstack/Regs.h>
3333 #include <unwindstack/RegsGetLocal.h>
3434
35-#if !defined(NO_LIBDEXFILE_SUPPORT)
36-#include <unwindstack/DexFiles.h>
37-#endif
3835 #include <unwindstack/Unwinder.h>
3936
4037 #include "BacktraceLog.h"
@@ -50,14 +47,6 @@ bool Backtrace::Unwind(unwindstack::Regs* regs, BacktraceMap* back_map,
5047 regs, stack_map->process_memory());
5148 unwinder.SetResolveNames(stack_map->ResolveNames());
5249 stack_map->SetArch(regs->Arch());
53- if (stack_map->GetJitDebug() != nullptr) {
54- unwinder.SetJitDebug(stack_map->GetJitDebug(), regs->Arch());
55- }
56-#if !defined(NO_LIBDEXFILE_SUPPORT)
57- if (stack_map->GetDexFiles() != nullptr) {
58- unwinder.SetDexFiles(stack_map->GetDexFiles(), regs->Arch());
59- }
60-#endif
6150 unwinder.Unwind(skip_names, &stack_map->GetSuffixesToIgnore());
6251 if (error != nullptr) {
6352 switch (unwinder.LastErrorCode()) {
--- a/libbacktrace/UnwindStackMap.cpp
+++ b/libbacktrace/UnwindStackMap.cpp
@@ -43,13 +43,6 @@ bool UnwindStackMap::Build() {
4343 // Create the process memory object.
4444 process_memory_ = unwindstack::Memory::CreateProcessMemory(pid_);
4545
46- // Create a JitDebug object for getting jit unwind information.
47- std::vector<std::string> search_libs_{"libart.so", "libartd.so"};
48- jit_debug_.reset(new unwindstack::JitDebug(process_memory_, search_libs_));
49-#if !defined(NO_LIBDEXFILE_SUPPORT)
50- dex_files_.reset(new unwindstack::DexFiles(process_memory_, search_libs_));
51-#endif
52-
5346 if (!stack_maps_->Parse()) {
5447 return false;
5548 }
--- a/libbacktrace/UnwindStackMap.h
+++ b/libbacktrace/UnwindStackMap.h
@@ -27,9 +27,6 @@
2727
2828 #include <backtrace/Backtrace.h>
2929 #include <backtrace/BacktraceMap.h>
30-#if !defined(NO_LIBDEXFILE_SUPPORT)
31-#include <unwindstack/DexFiles.h>
32-#endif
3330 #include <unwindstack/Elf.h>
3431 #include <unwindstack/JitDebug.h>
3532 #include <unwindstack/Maps.h>
@@ -53,12 +50,6 @@ class UnwindStackMap : public BacktraceMap {
5350
5451 const std::shared_ptr<unwindstack::Memory>& process_memory() { return process_memory_; }
5552
56- unwindstack::JitDebug* GetJitDebug() { return jit_debug_.get(); }
57-
58-#if !defined(NO_LIBDEXFILE_SUPPORT)
59- unwindstack::DexFiles* GetDexFiles() { return dex_files_.get(); }
60-#endif
61-
6253 void SetArch(unwindstack::ArchEnum arch) { arch_ = arch; }
6354
6455 protected:
@@ -66,11 +57,6 @@ class UnwindStackMap : public BacktraceMap {
6657
6758 std::unique_ptr<unwindstack::Maps> stack_maps_;
6859 std::shared_ptr<unwindstack::Memory> process_memory_;
69- std::unique_ptr<unwindstack::JitDebug> jit_debug_;
70-#if !defined(NO_LIBDEXFILE_SUPPORT)
71- std::unique_ptr<unwindstack::DexFiles> dex_files_;
72-#endif
73-
7460 unwindstack::ArchEnum arch_ = unwindstack::ARCH_UNKNOWN;
7561 };
7662
--- a/libunwindstack/Android.bp
+++ b/libunwindstack/Android.bp
@@ -49,7 +49,6 @@ cc_library {
4949 srcs: [
5050 "ArmExidx.cpp",
5151 "DexFile.cpp",
52- "DexFiles.cpp",
5352 "DwarfCfa.cpp",
5453 "DwarfEhFrameWithHdr.cpp",
5554 "DwarfMemory.cpp",
@@ -92,7 +91,6 @@ cc_library {
9291 cflags: ["-DNO_LIBDEXFILE_SUPPORT"],
9392 exclude_srcs: [
9493 "DexFile.cpp",
95- "DexFiles.cpp",
9694 ],
9795 exclude_shared_libs: [
9896 "libdexfile_support",
@@ -102,7 +100,6 @@ cc_library {
102100 cflags: ["-DNO_LIBDEXFILE_SUPPORT"],
103101 exclude_srcs: [
104102 "DexFile.cpp",
105- "DexFiles.cpp",
106103 ],
107104 exclude_shared_libs: [
108105 "libdexfile_support",
--- a/libunwindstack/DexFile.cpp
+++ b/libunwindstack/DexFile.cpp
@@ -35,22 +35,31 @@ namespace unwindstack {
3535 std::unique_ptr<DexFile> DexFile::Create(uint64_t dex_file_offset_in_memory, Memory* memory,
3636 MapInfo* info) {
3737 if (!info->name.empty()) {
38- std::unique_ptr<DexFile> dex_file =
38+ std::unique_ptr<DexFile> dex_file_from_file =
3939 DexFileFromFile::Create(dex_file_offset_in_memory - info->start + info->offset, info->name);
40- if (dex_file) {
41- return dex_file;
40+ if (dex_file_from_file) {
41+ dex_file_from_file->addr_ = dex_file_offset_in_memory;
42+ return dex_file_from_file;
4243 }
4344 }
44- return DexFileFromMemory::Create(dex_file_offset_in_memory, memory, info->name);
45+ std::unique_ptr<DexFile> dex_file_from_memory =
46+ DexFileFromMemory::Create(dex_file_offset_in_memory, memory, info->name);
47+ if (dex_file_from_memory) {
48+ dex_file_from_memory->addr_ = dex_file_offset_in_memory;
49+ return dex_file_from_memory;
50+ }
51+ return nullptr;
4552 }
4653
47-bool DexFile::GetMethodInformation(uint64_t dex_offset, std::string* method_name,
48- uint64_t* method_offset) {
54+bool DexFile::GetFunctionName(uint64_t dex_pc, std::string* method_name, uint64_t* method_offset) {
55+ uint64_t dex_offset = dex_pc - addr_;
4956 art_api::dex::MethodInfo method_info = GetMethodInfoForOffset(dex_offset, false);
5057 if (method_info.offset == 0) {
5158 return false;
5259 }
53- *method_name = method_info.name;
60+ if (method_name != nullptr) {
61+ *method_name = method_info.name;
62+ }
5463 *method_offset = dex_offset - method_info.offset;
5564 return true;
5665 }
--- a/libunwindstack/DexFile.h
+++ b/libunwindstack/DexFile.h
@@ -29,17 +29,22 @@
2929
3030 namespace unwindstack {
3131
32+class Memory;
33+struct MapInfo;
34+
3235 class DexFile : protected art_api::dex::DexFile {
3336 public:
3437 virtual ~DexFile() = default;
3538
36- bool GetMethodInformation(uint64_t dex_offset, std::string* method_name, uint64_t* method_offset);
39+ bool GetFunctionName(uint64_t dex_pc, std::string* method_name, uint64_t* method_offset);
3740
3841 static std::unique_ptr<DexFile> Create(uint64_t dex_file_offset_in_memory, Memory* memory,
3942 MapInfo* info);
4043
4144 protected:
4245 DexFile(art_api::dex::DexFile&& art_dex_file) : art_api::dex::DexFile(std::move(art_dex_file)) {}
46+
47+ uint64_t addr_ = 0;
4348 };
4449
4550 class DexFileFromFile : public DexFile {
--- a/libunwindstack/DexFiles.cpp
+++ /dev/null
@@ -1,179 +0,0 @@
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 <stdint.h>
18-#include <sys/mman.h>
19-#include <sys/stat.h>
20-#include <sys/types.h>
21-#include <unistd.h>
22-
23-#include <memory>
24-
25-#include <unwindstack/DexFiles.h>
26-#include <unwindstack/MapInfo.h>
27-#include <unwindstack/Maps.h>
28-#include <unwindstack/Memory.h>
29-
30-#include "DexFile.h"
31-
32-namespace unwindstack {
33-
34-struct DEXFileEntry32 {
35- uint32_t next;
36- uint32_t prev;
37- uint32_t dex_file;
38-};
39-
40-struct DEXFileEntry64 {
41- uint64_t next;
42- uint64_t prev;
43- uint64_t dex_file;
44-};
45-
46-DexFiles::DexFiles(std::shared_ptr<Memory>& memory) : Global(memory) {}
47-
48-DexFiles::DexFiles(std::shared_ptr<Memory>& memory, std::vector<std::string>& search_libs)
49- : Global(memory, search_libs) {}
50-
51-DexFiles::~DexFiles() {}
52-
53-void DexFiles::ProcessArch() {
54- switch (arch()) {
55- case ARCH_ARM:
56- case ARCH_MIPS:
57- case ARCH_X86:
58- read_entry_ptr_func_ = &DexFiles::ReadEntryPtr32;
59- read_entry_func_ = &DexFiles::ReadEntry32;
60- break;
61-
62- case ARCH_ARM64:
63- case ARCH_MIPS64:
64- case ARCH_X86_64:
65- read_entry_ptr_func_ = &DexFiles::ReadEntryPtr64;
66- read_entry_func_ = &DexFiles::ReadEntry64;
67- break;
68-
69- case ARCH_UNKNOWN:
70- abort();
71- }
72-}
73-
74-uint64_t DexFiles::ReadEntryPtr32(uint64_t addr) {
75- uint32_t entry;
76- const uint32_t field_offset = 12; // offset of first_entry_ in the descriptor struct.
77- if (!memory_->ReadFully(addr + field_offset, &entry, sizeof(entry))) {
78- return 0;
79- }
80- return entry;
81-}
82-
83-uint64_t DexFiles::ReadEntryPtr64(uint64_t addr) {
84- uint64_t entry;
85- const uint32_t field_offset = 16; // offset of first_entry_ in the descriptor struct.
86- if (!memory_->ReadFully(addr + field_offset, &entry, sizeof(entry))) {
87- return 0;
88- }
89- return entry;
90-}
91-
92-bool DexFiles::ReadEntry32() {
93- DEXFileEntry32 entry;
94- if (!memory_->ReadFully(entry_addr_, &entry, sizeof(entry)) || entry.dex_file == 0) {
95- entry_addr_ = 0;
96- return false;
97- }
98-
99- addrs_.push_back(entry.dex_file);
100- entry_addr_ = entry.next;
101- return true;
102-}
103-
104-bool DexFiles::ReadEntry64() {
105- DEXFileEntry64 entry;
106- if (!memory_->ReadFully(entry_addr_, &entry, sizeof(entry)) || entry.dex_file == 0) {
107- entry_addr_ = 0;
108- return false;
109- }
110-
111- addrs_.push_back(entry.dex_file);
112- entry_addr_ = entry.next;
113- return true;
114-}
115-
116-bool DexFiles::ReadVariableData(uint64_t ptr_offset) {
117- entry_addr_ = (this->*read_entry_ptr_func_)(ptr_offset);
118- return entry_addr_ != 0;
119-}
120-
121-void DexFiles::Init(Maps* maps) {
122- if (initialized_) {
123- return;
124- }
125- initialized_ = true;
126- entry_addr_ = 0;
127-
128- FindAndReadVariable(maps, "__dex_debug_descriptor");
129-}
130-
131-DexFile* DexFiles::GetDexFile(uint64_t dex_file_offset, MapInfo* info) {
132- // Lock while processing the data.
133- DexFile* dex_file;
134- auto entry = files_.find(dex_file_offset);
135- if (entry == files_.end()) {
136- std::unique_ptr<DexFile> new_dex_file = DexFile::Create(dex_file_offset, memory_.get(), info);
137- dex_file = new_dex_file.get();
138- files_[dex_file_offset] = std::move(new_dex_file);
139- } else {
140- dex_file = entry->second.get();
141- }
142- return dex_file;
143-}
144-
145-bool DexFiles::GetAddr(size_t index, uint64_t* addr) {
146- if (index < addrs_.size()) {
147- *addr = addrs_[index];
148- return true;
149- }
150- if (entry_addr_ != 0 && (this->*read_entry_func_)()) {
151- *addr = addrs_.back();
152- return true;
153- }
154- return false;
155-}
156-
157-void DexFiles::GetMethodInformation(Maps* maps, MapInfo* info, uint64_t dex_pc,
158- std::string* method_name, uint64_t* method_offset) {
159- std::lock_guard<std::mutex> guard(lock_);
160- if (!initialized_) {
161- Init(maps);
162- }
163-
164- size_t index = 0;
165- uint64_t addr;
166- while (GetAddr(index++, &addr)) {
167- if (addr < info->start || addr >= info->end) {
168- continue;
169- }
170-
171- DexFile* dex_file = GetDexFile(addr, info);
172- if (dex_file != nullptr &&
173- dex_file->GetMethodInformation(dex_pc - addr, method_name, method_offset)) {
174- break;
175- }
176- }
177-}
178-
179-} // namespace unwindstack
--- a/libunwindstack/Elf.cpp
+++ b/libunwindstack/Elf.cpp
@@ -243,6 +243,24 @@ bool Elf::IsValidPc(uint64_t pc) {
243243 return false;
244244 }
245245
246+bool Elf::GetTextRange(uint64_t* addr, uint64_t* size) {
247+ if (!valid_) {
248+ return false;
249+ }
250+
251+ if (interface_->GetTextRange(addr, size)) {
252+ *addr += load_bias_;
253+ return true;
254+ }
255+
256+ if (gnu_debugdata_interface_ != nullptr && gnu_debugdata_interface_->GetTextRange(addr, size)) {
257+ *addr += load_bias_;
258+ return true;
259+ }
260+
261+ return false;
262+}
263+
246264 ElfInterface* Elf::CreateInterfaceFromMemory(Memory* memory) {
247265 if (!IsValidElf(memory)) {
248266 return nullptr;
--- a/libunwindstack/ElfInterface.cpp
+++ b/libunwindstack/ElfInterface.cpp
@@ -69,6 +69,15 @@ bool ElfInterface::IsValidPc(uint64_t pc) {
6969 return false;
7070 }
7171
72+bool ElfInterface::GetTextRange(uint64_t* addr, uint64_t* size) {
73+ if (text_size_ != 0) {
74+ *addr = text_addr_;
75+ *size = text_size_;
76+ return true;
77+ }
78+ return false;
79+}
80+
7281 Memory* ElfInterface::CreateGnuDebugdataMemory() {
7382 if (gnu_debugdata_offset_ == 0 || gnu_debugdata_size_ == 0) {
7483 return nullptr;
@@ -330,29 +339,26 @@ void ElfInterface::ReadSectionHeaders(const EhdrType& ehdr) {
330339 }
331340 symbols_.push_back(new Symbols(shdr.sh_offset, shdr.sh_size, shdr.sh_entsize,
332341 str_shdr.sh_offset, str_shdr.sh_size));
333- } else if (shdr.sh_type == SHT_PROGBITS && sec_size != 0) {
342+ } else if (shdr.sh_type == SHT_PROGBITS || shdr.sh_type == SHT_NOBITS) {
334343 // Look for the .debug_frame and .gnu_debugdata.
335344 if (shdr.sh_name < sec_size) {
336345 std::string name;
337346 if (memory_->ReadString(sec_offset + shdr.sh_name, &name)) {
338- uint64_t* offset_ptr = nullptr;
339- uint64_t* size_ptr = nullptr;
340347 if (name == ".debug_frame") {
341- offset_ptr = &debug_frame_offset_;
342- size_ptr = &debug_frame_size_;
348+ debug_frame_offset_ = shdr.sh_offset;
349+ debug_frame_size_ = shdr.sh_size;
343350 } else if (name == ".gnu_debugdata") {
344- offset_ptr = &gnu_debugdata_offset_;
345- size_ptr = &gnu_debugdata_size_;
351+ gnu_debugdata_offset_ = shdr.sh_offset;
352+ gnu_debugdata_size_ = shdr.sh_size;
346353 } else if (name == ".eh_frame") {
347- offset_ptr = &eh_frame_offset_;
348- size_ptr = &eh_frame_size_;
354+ eh_frame_offset_ = shdr.sh_offset;
355+ eh_frame_size_ = shdr.sh_size;
349356 } else if (eh_frame_hdr_offset_ == 0 && name == ".eh_frame_hdr") {
350- offset_ptr = &eh_frame_hdr_offset_;
351- size_ptr = &eh_frame_hdr_size_;
352- }
353- if (offset_ptr != nullptr) {
354- *offset_ptr = shdr.sh_offset;
355- *size_ptr = shdr.sh_size;
357+ eh_frame_hdr_offset_ = shdr.sh_offset;
358+ eh_frame_hdr_size_ = shdr.sh_size;
359+ } else if (name == ".text") {
360+ text_addr_ = shdr.sh_addr;
361+ text_size_ = shdr.sh_size;
356362 }
357363 }
358364 }
--- a/libunwindstack/JitDebug.cpp
+++ b/libunwindstack/JitDebug.cpp
@@ -16,8 +16,13 @@
1616
1717 #include <stdint.h>
1818 #include <sys/mman.h>
19+#include <cstddef>
1920
21+#include <atomic>
22+#include <deque>
23+#include <map>
2024 #include <memory>
25+#include <unordered_set>
2126 #include <vector>
2227
2328 #include <unwindstack/Elf.h>
@@ -25,197 +30,334 @@
2530 #include <unwindstack/Maps.h>
2631 #include <unwindstack/Memory.h>
2732
33+#if !defined(NO_LIBDEXFILE_SUPPORT)
34+#include <DexFile.h>
35+#endif
36+
2837 // This implements the JIT Compilation Interface.
2938 // See https://sourceware.org/gdb/onlinedocs/gdb/JIT-Interface.html
3039
3140 namespace unwindstack {
3241
33-struct JITCodeEntry32Pack {
34- uint32_t next;
35- uint32_t prev;
36- uint32_t symfile_addr;
37- uint64_t symfile_size;
42+// 32-bit platforms may differ in alignment of uint64_t.
43+struct Uint64_P {
44+ uint64_t value;
3845 } __attribute__((packed));
39-
40-struct JITCodeEntry32Pad {
41- uint32_t next;
42- uint32_t prev;
43- uint32_t symfile_addr;
44- uint32_t pad;
45- uint64_t symfile_size;
46+struct Uint64_A {
47+ uint64_t value;
48+} __attribute__((aligned(8)));
49+
50+// 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.
53+struct 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;
4660 };
4761
48-struct JITCodeEntry64 {
49- uint64_t next;
50- uint64_t prev;
51- uint64_t symfile_addr;
52- uint64_t symfile_size;
53-};
62+template <typename Symfile>
63+struct 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_;
5468
55-struct JITDescriptorHeader {
56- uint32_t version;
57- uint32_t action_flag;
69+ bool Init(Maps* maps, JitMemory* memory, uint64_t addr, uint64_t size);
5870 };
5971
60-struct JITDescriptor32 {
61- JITDescriptorHeader header;
62- uint32_t relevant_entry;
63- uint32_t first_entry;
64-};
72+template <typename Symfile, typename PointerT, typename Uint64_T>
73+class 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+ }
65108
66-struct JITDescriptor64 {
67- JITDescriptorHeader header;
68- uint64_t relevant_entry;
69- uint64_t first_entry;
70-};
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.
71119
72-JitDebug::JitDebug(std::shared_ptr<Memory>& memory) : Global(memory) {}
120+ std::deque<JitCacheEntry<Symfile>> entries_;
73121
74-JitDebug::JitDebug(std::shared_ptr<Memory>& memory, std::vector<std::string>& search_libs)
75- : Global(memory, search_libs) {}
122+ std::mutex lock_;
123+};
76124
77-JitDebug::~JitDebug() {
78- for (auto* elf : elf_list_) {
79- delete elf;
125+template <typename Symfile>
126+std::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) {
133+ case ARCH_X86:
134+ 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));
138+ break;
139+ case ARCH_ARM:
140+ case ARCH_MIPS:
141+ 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));
145+ break;
146+ case ARCH_ARM64:
147+ case ARCH_X86_64:
148+ case ARCH_MIPS64:
149+ 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));
153+ break;
154+ default:
155+ abort();
80156 }
81157 }
82158
83-uint64_t JitDebug::ReadDescriptor32(uint64_t addr) {
84- JITDescriptor32 desc;
85- if (!memory_->ReadFully(addr, &desc, sizeof(desc))) {
159+size_t JitMemory::Read(uint64_t addr, void* dst, size_t size) {
160+ if (!parent_->ReadFully(addr, dst, size)) {
86161 return 0;
87162 }
88-
89- if (desc.header.version != 1 || desc.first_entry == 0) {
90- // Either unknown version, or no jit entries.
163+ // 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)) {
91168 return 0;
92169 }
93-
94- return desc.first_entry;
95-}
96-
97-uint64_t JitDebug::ReadDescriptor64(uint64_t addr) {
98- JITDescriptor64 desc;
99- if (!memory_->ReadFully(addr, &desc, sizeof(desc))) {
170+ if (seen_seqlock != expected_seqlock_) {
171+ failed_due_to_race_ = true;
100172 return 0;
101173 }
174+ return size;
175+}
102176
103- if (desc.header.version != 1 || desc.first_entry == 0) {
104- // Either unknown version, or no jit entries.
105- return 0;
177+template <typename Symfile, typename PointerT, typename Uint64_T>
178+bool JitDebugImpl<Symfile, PointerT, Uint64_T>::ReadVariableData(uint64_t addr) {
179+ JITDescriptor desc;
180+ if (!this->memory_->ReadFully(addr, &desc, sizeof(desc))) {
181+ return false;
106182 }
107-
108- return desc.first_entry;
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;
109199 }
110200
111-uint64_t JitDebug::ReadEntry32Pack(uint64_t* start, uint64_t* size) {
112- JITCodeEntry32Pack code;
113- if (!memory_->ReadFully(entry_addr_, &code, sizeof(code))) {
114- return 0;
115- }
201+template <typename Symfile>
202+static const char* GetDescriptorName();
116203
117- *start = code.symfile_addr;
118- *size = code.symfile_size;
119- return code.next;
204+template <>
205+const char* GetDescriptorName<Elf>() {
206+ return "__jit_debug_descriptor";
120207 }
121208
122-uint64_t JitDebug::ReadEntry32Pad(uint64_t* start, uint64_t* size) {
123- JITCodeEntry32Pad code;
124- if (!memory_->ReadFully(entry_addr_, &code, sizeof(code))) {
125- return 0;
209+template <typename Symfile, typename PointerT, typename Uint64_T>
210+Symfile* JitDebugImpl<Symfile, PointerT, Uint64_T>::Get(Maps* maps, uint64_t pc) {
211+ std::lock_guard<std::mutex> guard(lock_);
212+ if (!initialized_) {
213+ FindAndReadVariable(maps, GetDescriptorName<Symfile>());
214+ initialized_ = true;
126215 }
127216
128- *start = code.symfile_addr;
129- *size = code.symfile_size;
130- return code.next;
131-}
217+ if (descriptor_addr_ == 0) {
218+ return nullptr;
219+ }
132220
133-uint64_t JitDebug::ReadEntry64(uint64_t* start, uint64_t* size) {
134- JITCodeEntry64 code;
135- if (!memory_->ReadFully(entry_addr_, &code, sizeof(code))) {
136- return 0;
221+ if (!Update(maps)) {
222+ return nullptr;
137223 }
138224
139- *start = code.symfile_addr;
140- *size = code.symfile_size;
141- return code.next;
225+ 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.
237+ }
238+ }
239+ return fallback; // Not found.
142240 }
143241
144-void JitDebug::ProcessArch() {
145- switch (arch()) {
146- case ARCH_X86:
147- read_descriptor_func_ = &JitDebug::ReadDescriptor32;
148- read_entry_func_ = &JitDebug::ReadEntry32Pack;
149- break;
150-
151- case ARCH_ARM:
152- case ARCH_MIPS:
153- read_descriptor_func_ = &JitDebug::ReadDescriptor32;
154- read_entry_func_ = &JitDebug::ReadEntry32Pad;
155- break;
242+// Update JIT entries if needed. It will retry if there are data races.
243+template <typename Symfile, typename PointerT, typename Uint64_T>
244+bool 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+ }
156252
157- case ARCH_ARM64:
158- case ARCH_X86_64:
159- case ARCH_MIPS64:
160- read_descriptor_func_ = &JitDebug::ReadDescriptor64;
161- read_entry_func_ = &JitDebug::ReadEntry64;
162- break;
163- case ARCH_UNKNOWN:
164- abort();
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;
165274 }
275+ return false; // Too many retries.
166276 }
167277
168-bool JitDebug::ReadVariableData(uint64_t ptr) {
169- entry_addr_ = (this->*read_descriptor_func_)(ptr);
170- return entry_addr_ != 0;
171-}
278+// Read all JIT entries. It might randomly fail due to data races.
279+template <typename Symfile, typename PointerT, typename Uint64_T>
280+bool JitDebugImpl<Symfile, PointerT, Uint64_T>::Read(Maps* maps, JitMemory* memory) {
281+ std::unordered_set<uint64_t> seen_entry_addr;
172282
173-void JitDebug::Init(Maps* maps) {
174- if (initialized_) {
175- return;
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;
176287 }
177- // Regardless of what happens below, consider the init finished.
178- initialized_ = true;
179288
180- FindAndReadVariable(maps, "__jit_debug_descriptor");
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;
181310 }
182311
183-Elf* JitDebug::GetElf(Maps* maps, uint64_t pc) {
184- // Use a single lock, this object should be used so infrequently that
185- // a fine grain lock is unnecessary.
186- std::lock_guard<std::mutex> guard(lock_);
187- if (!initialized_) {
188- Init(maps);
312+// Copy and load ELF file.
313+template <>
314+bool 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;
189320 }
190321
191- // Search the existing elf object first.
192- for (Elf* elf : elf_list_) {
193- if (elf->IsValidPc(pc)) {
194- return elf;
195- }
322+ // Load and validate the ELF file.
323+ symfile_.reset(new Elf(buffer.release()));
324+ symfile_->Init();
325+ if (!symfile_->valid()) {
326+ return false;
196327 }
197328
198- while (entry_addr_ != 0) {
199- uint64_t start;
200- uint64_t size;
201- entry_addr_ = (this->*read_entry_func_)(&start, &size);
329+ symfile_->GetTextRange(&addr_, &size_);
330+ return true;
331+}
202332
203- Elf* elf = new Elf(new MemoryRange(memory_, start, size, 0));
204- elf->Init();
205- if (!elf->valid()) {
206- // The data is not formatted in a way we understand, do not attempt
207- // to process any other entries.
208- entry_addr_ = 0;
209- delete elf;
210- return nullptr;
211- }
212- elf_list_.push_back(elf);
333+template std::unique_ptr<JitDebug<Elf>> JitDebug<Elf>::Create(ArchEnum, std::shared_ptr<Memory>&,
334+ std::vector<std::string>);
213335
214- if (elf->IsValidPc(pc)) {
215- return elf;
216- }
336+#if !defined(NO_LIBDEXFILE_SUPPORT)
337+
338+template <>
339+const char* GetDescriptorName<DexFile>() {
340+ return "__dex_debug_descriptor";
341+}
342+
343+// Copy and load DEX file.
344+template <>
345+bool 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;
217353 }
218- return nullptr;
354+ return true;
219355 }
220356
357+template std::unique_ptr<JitDebug<DexFile>> JitDebug<DexFile>::Create(ArchEnum,
358+ std::shared_ptr<Memory>&,
359+ std::vector<std::string>);
360+
361+#endif
362+
221363 } // namespace unwindstack
--- a/libunwindstack/Unwinder.cpp
+++ b/libunwindstack/Unwinder.cpp
@@ -36,11 +36,38 @@
3636 #include <unwindstack/Unwinder.h>
3737
3838 #if !defined(NO_LIBDEXFILE_SUPPORT)
39-#include <unwindstack/DexFiles.h>
39+#include <DexFile.h>
4040 #endif
4141
4242 namespace unwindstack {
4343
44+Unwinder::Unwinder(size_t max_frames, Maps* maps, Regs* regs,
45+ std::shared_ptr<Memory> process_memory)
46+ : max_frames_(max_frames), maps_(maps), regs_(regs), process_memory_(process_memory) {
47+ frames_.reserve(max_frames);
48+ if (regs != nullptr) {
49+ ArchEnum arch = regs_->Arch();
50+
51+ jit_debug_ = JitDebug<Elf>::Create(arch, process_memory_);
52+#if !defined(NO_LIBDEXFILE_SUPPORT)
53+ dex_files_ = JitDebug<DexFile>::Create(arch, process_memory_);
54+#endif
55+ }
56+}
57+
58+void Unwinder::SetRegs(Regs* regs) {
59+ regs_ = regs;
60+
61+ if (jit_debug_ == nullptr) {
62+ ArchEnum arch = regs_->Arch();
63+
64+ jit_debug_ = JitDebug<Elf>::Create(arch, process_memory_);
65+#if !defined(NO_LIBDEXFILE_SUPPORT)
66+ dex_files_ = JitDebug<DexFile>::Create(arch, process_memory_);
67+#endif
68+ }
69+}
70+
4471 // Inject extra 'virtual' frame that represents the dex pc data.
4572 // The dex pc is a magic register defined in the Mterp interpreter,
4673 // and thus it will be restored/observed in the frame after it.
@@ -84,8 +111,7 @@ void Unwinder::FillInDexFrame() {
84111 return;
85112 }
86113
87- dex_files_->GetMethodInformation(maps_, info, dex_pc, &frame->function_name,
88- &frame->function_offset);
114+ dex_files_->GetFunctionName(maps_, dex_pc, &frame->function_name, &frame->function_offset);
89115 #endif
90116 }
91117
@@ -185,7 +211,7 @@ void Unwinder::Unwind(const std::vector<std::string>* initial_map_names_to_skip,
185211 // using the jit debug information.
186212 if (!elf->valid() && jit_debug_ != nullptr) {
187213 uint64_t adjusted_jit_pc = regs_->pc() - pc_adjustment;
188- Elf* jit_elf = jit_debug_->GetElf(maps_, adjusted_jit_pc);
214+ Elf* jit_elf = jit_debug_->Get(maps_, adjusted_jit_pc);
189215 if (jit_elf != nullptr) {
190216 // The jit debug information requires a non relative adjusted pc.
191217 step_pc = adjusted_jit_pc;
@@ -330,19 +356,7 @@ std::string Unwinder::FormatFrame(size_t frame_num) {
330356 return FormatFrame(frames_[frame_num]);
331357 }
332358
333-void Unwinder::SetJitDebug(JitDebug* jit_debug, ArchEnum arch) {
334- jit_debug->SetArch(arch);
335- jit_debug_ = jit_debug;
336-}
337-
338-#if !defined(NO_LIBDEXFILE_SUPPORT)
339-void Unwinder::SetDexFiles(DexFiles* dex_files, ArchEnum arch) {
340- dex_files->SetArch(arch);
341- dex_files_ = dex_files;
342-}
343-#endif
344-
345-bool UnwinderFromPid::Init(ArchEnum arch) {
359+bool UnwinderFromPid::Init() {
346360 if (pid_ == getpid()) {
347361 maps_ptr_.reset(new LocalMaps());
348362 } else {
@@ -355,15 +369,6 @@ bool UnwinderFromPid::Init(ArchEnum arch) {
355369
356370 process_memory_ = Memory::CreateProcessMemoryCached(pid_);
357371
358- jit_debug_ptr_.reset(new JitDebug(process_memory_));
359- jit_debug_ = jit_debug_ptr_.get();
360- SetJitDebug(jit_debug_, arch);
361-#if !defined(NO_LIBDEXFILE_SUPPORT)
362- dex_files_ptr_.reset(new DexFiles(process_memory_));
363- dex_files_ = dex_files_ptr_.get();
364- SetDexFiles(dex_files_, arch);
365-#endif
366-
367372 return true;
368373 }
369374
--- a/libunwindstack/include/unwindstack/DexFiles.h
+++ /dev/null
@@ -1,79 +0,0 @@
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-#ifndef _LIBUNWINDSTACK_DEX_FILES_H
18-#define _LIBUNWINDSTACK_DEX_FILES_H
19-
20-#include <stdint.h>
21-
22-#include <memory>
23-#include <mutex>
24-#include <string>
25-#include <unordered_map>
26-#include <vector>
27-
28-#include <unwindstack/Global.h>
29-#include <unwindstack/Memory.h>
30-
31-namespace unwindstack {
32-
33-// Forward declarations.
34-class DexFile;
35-class Maps;
36-struct MapInfo;
37-enum ArchEnum : uint8_t;
38-
39-class DexFiles : public Global {
40- public:
41- explicit DexFiles(std::shared_ptr<Memory>& memory);
42- DexFiles(std::shared_ptr<Memory>& memory, std::vector<std::string>& search_libs);
43- virtual ~DexFiles();
44-
45- DexFile* GetDexFile(uint64_t dex_file_offset, MapInfo* info);
46-
47- void GetMethodInformation(Maps* maps, MapInfo* info, uint64_t dex_pc, std::string* method_name,
48- uint64_t* method_offset);
49-
50- private:
51- void Init(Maps* maps);
52-
53- bool GetAddr(size_t index, uint64_t* addr);
54-
55- uint64_t ReadEntryPtr32(uint64_t addr);
56-
57- uint64_t ReadEntryPtr64(uint64_t addr);
58-
59- bool ReadEntry32();
60-
61- bool ReadEntry64();
62-
63- bool ReadVariableData(uint64_t ptr_offset) override;
64-
65- void ProcessArch() override;
66-
67- std::mutex lock_;
68- bool initialized_ = false;
69- std::unordered_map<uint64_t, std::unique_ptr<DexFile>> files_;
70-
71- uint64_t entry_addr_ = 0;
72- uint64_t (DexFiles::*read_entry_ptr_func_)(uint64_t) = nullptr;
73- bool (DexFiles::*read_entry_func_)() = nullptr;
74- std::vector<uint64_t> addrs_;
75-};
76-
77-} // namespace unwindstack
78-
79-#endif // _LIBUNWINDSTACK_DEX_FILES_H
--- a/libunwindstack/include/unwindstack/Elf.h
+++ b/libunwindstack/include/unwindstack/Elf.h
@@ -78,6 +78,8 @@ class Elf {
7878
7979 bool IsValidPc(uint64_t pc);
8080
81+ bool GetTextRange(uint64_t* addr, uint64_t* size);
82+
8183 void GetLastError(ErrorData* data);
8284 ErrorCode GetLastErrorCode();
8385 uint64_t GetLastErrorAddress();
--- a/libunwindstack/include/unwindstack/ElfInterface.h
+++ b/libunwindstack/include/unwindstack/ElfInterface.h
@@ -68,6 +68,8 @@ class ElfInterface {
6868
6969 virtual bool IsValidPc(uint64_t pc);
7070
71+ bool GetTextRange(uint64_t* addr, uint64_t* size);
72+
7173 Memory* CreateGnuDebugdataMemory();
7274
7375 Memory* memory() { return memory_; }
@@ -156,6 +158,9 @@ class ElfInterface {
156158 uint64_t gnu_build_id_offset_ = 0;
157159 uint64_t gnu_build_id_size_ = 0;
158160
161+ uint64_t text_addr_ = 0;
162+ uint64_t text_size_ = 0;
163+
159164 uint8_t soname_type_ = SONAME_UNKNOWN;
160165 std::string soname_;
161166
--- a/libunwindstack/include/unwindstack/JitDebug.h
+++ b/libunwindstack/include/unwindstack/JitDebug.h
@@ -19,6 +19,7 @@
1919
2020 #include <stdint.h>
2121
22+#include <map>
2223 #include <memory>
2324 #include <mutex>
2425 #include <string>
@@ -30,40 +31,24 @@
3031 namespace unwindstack {
3132
3233 // Forward declarations.
33-class Elf;
3434 class Maps;
3535 enum ArchEnum : uint8_t;
3636
37-class JitDebug : public Global {
37+template <typename Symfile>
38+class JitDebug {
3839 public:
39- explicit JitDebug(std::shared_ptr<Memory>& memory);
40- JitDebug(std::shared_ptr<Memory>& memory, std::vector<std::string>& search_libs);
41- virtual ~JitDebug();
42-
43- Elf* GetElf(Maps* maps, uint64_t pc);
44-
45- private:
46- void Init(Maps* maps);
47-
48- uint64_t (JitDebug::*read_descriptor_func_)(uint64_t) = nullptr;
49- uint64_t (JitDebug::*read_entry_func_)(uint64_t*, uint64_t*) = nullptr;
50-
51- uint64_t ReadDescriptor32(uint64_t);
52- uint64_t ReadDescriptor64(uint64_t);
53-
54- uint64_t ReadEntry32Pack(uint64_t* start, uint64_t* size);
55- uint64_t ReadEntry32Pad(uint64_t* start, uint64_t* size);
56- uint64_t ReadEntry64(uint64_t* start, uint64_t* size);
57-
58- bool ReadVariableData(uint64_t ptr_offset) override;
59-
60- void ProcessArch() override;
61-
62- uint64_t entry_addr_ = 0;
63- bool initialized_ = false;
64- std::vector<Elf*> elf_list_;
65-
66- std::mutex lock_;
40+ static std::unique_ptr<JitDebug> Create(ArchEnum arch, std::shared_ptr<Memory>& memory,
41+ std::vector<std::string> search_libs = {});
42+ virtual ~JitDebug() {}
43+
44+ // Find symbol file for given pc.
45+ virtual Symfile* Get(Maps* maps, uint64_t pc) = 0;
46+
47+ // Find symbol for given pc.
48+ bool GetFunctionName(Maps* maps, uint64_t pc, std::string* name, uint64_t* offset) {
49+ Symfile* file = Get(maps, pc);
50+ return file != nullptr && file->GetFunctionName(pc, name, offset);
51+ }
6752 };
6853
6954 } // namespace unwindstack
--- a/libunwindstack/include/unwindstack/Unwinder.h
+++ b/libunwindstack/include/unwindstack/Unwinder.h
@@ -24,7 +24,6 @@
2424 #include <string>
2525 #include <vector>
2626
27-#include <unwindstack/DexFiles.h>
2827 #include <unwindstack/Error.h>
2928 #include <unwindstack/JitDebug.h>
3029 #include <unwindstack/Maps.h>
@@ -34,6 +33,7 @@
3433 namespace unwindstack {
3534
3635 // Forward declarations.
36+class DexFile;
3737 class Elf;
3838 enum ArchEnum : uint8_t;
3939
@@ -63,14 +63,14 @@ struct FrameData {
6363
6464 class Unwinder {
6565 public:
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- }
66+ Unwinder(size_t max_frames, Maps* maps, Regs* regs, std::shared_ptr<Memory> process_memory);
7067 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- }
68+ : Unwinder(max_frames, maps, nullptr, process_memory) {}
69+
70+ Unwinder(const Unwinder&) = delete;
71+ Unwinder& operator=(const Unwinder&) = delete;
72+ Unwinder(Unwinder&&) = default;
73+ Unwinder& operator=(Unwinder&&) = default;
7474
7575 virtual ~Unwinder() = default;
7676
@@ -90,9 +90,7 @@ class Unwinder {
9090 std::string FormatFrame(size_t frame_num);
9191 std::string FormatFrame(const FrameData& frame);
9292
93- void SetJitDebug(JitDebug* jit_debug, ArchEnum arch);
94-
95- void SetRegs(Regs* regs) { regs_ = regs; }
93+ void SetRegs(Regs* regs);
9694 Maps* GetMaps() { return maps_; }
9795 std::shared_ptr<Memory>& GetProcessMemory() { return process_memory_; }
9896
@@ -107,10 +105,6 @@ class Unwinder {
107105
108106 void SetDisplayBuildID(bool display_build_id) { display_build_id_ = display_build_id; }
109107
110-#if !defined(NO_LIBDEXFILE_SUPPORT)
111- void SetDexFiles(DexFiles* dex_files, ArchEnum arch);
112-#endif
113-
114108 ErrorCode LastErrorCode() { return last_error_.code; }
115109 uint64_t LastErrorAddress() { return last_error_.address; }
116110
@@ -126,9 +120,9 @@ class Unwinder {
126120 Regs* regs_;
127121 std::vector<FrameData> frames_;
128122 std::shared_ptr<Memory> process_memory_;
129- JitDebug* jit_debug_ = nullptr;
123+ std::unique_ptr<JitDebug<Elf>> jit_debug_;
130124 #if !defined(NO_LIBDEXFILE_SUPPORT)
131- DexFiles* dex_files_ = nullptr;
125+ std::unique_ptr<JitDebug<DexFile>> dex_files_;
132126 #endif
133127 bool resolve_names_ = true;
134128 bool embedded_soname_ = true;
@@ -141,15 +135,11 @@ class UnwinderFromPid : public Unwinder {
141135 UnwinderFromPid(size_t max_frames, pid_t pid) : Unwinder(max_frames), pid_(pid) {}
142136 virtual ~UnwinderFromPid() = default;
143137
144- bool Init(ArchEnum arch);
138+ bool Init();
145139
146140 private:
147141 pid_t pid_;
148142 std::unique_ptr<Maps> maps_ptr_;
149- std::unique_ptr<JitDebug> jit_debug_ptr_;
150-#if !defined(NO_LIBDEXFILE_SUPPORT)
151- std::unique_ptr<DexFiles> dex_files_ptr_;
152-#endif
153143 };
154144
155145 } // namespace unwindstack
--- a/libunwindstack/tests/DexFileTest.cpp
+++ b/libunwindstack/tests/DexFileTest.cpp
@@ -177,11 +177,11 @@ TEST(DexFileTest, get_method) {
177177
178178 std::string method;
179179 uint64_t method_offset;
180- ASSERT_TRUE(dex_file->GetMethodInformation(0x102, &method, &method_offset));
180+ ASSERT_TRUE(dex_file->GetFunctionName(0x4102, &method, &method_offset));
181181 EXPECT_EQ("Main.<init>", method);
182182 EXPECT_EQ(2U, method_offset);
183183
184- ASSERT_TRUE(dex_file->GetMethodInformation(0x118, &method, &method_offset));
184+ ASSERT_TRUE(dex_file->GetFunctionName(0x4118, &method, &method_offset));
185185 EXPECT_EQ("Main.main", method);
186186 EXPECT_EQ(0U, method_offset);
187187 }
@@ -195,9 +195,9 @@ TEST(DexFileTest, get_method_empty) {
195195
196196 std::string method;
197197 uint64_t method_offset;
198- EXPECT_FALSE(dex_file->GetMethodInformation(0x100000, &method, &method_offset));
198+ EXPECT_FALSE(dex_file->GetFunctionName(0x100000, &method, &method_offset));
199199
200- EXPECT_FALSE(dex_file->GetMethodInformation(0x98, &method, &method_offset));
200+ EXPECT_FALSE(dex_file->GetFunctionName(0x98, &method, &method_offset));
201201 }
202202
203203 } // namespace unwindstack
--- a/libunwindstack/tests/DexFilesTest.cpp
+++ b/libunwindstack/tests/DexFilesTest.cpp
@@ -22,8 +22,8 @@
2222
2323 #include <gtest/gtest.h>
2424
25-#include <unwindstack/DexFiles.h>
2625 #include <unwindstack/Elf.h>
26+#include <unwindstack/JitDebug.h>
2727 #include <unwindstack/MapInfo.h>
2828 #include <unwindstack/Maps.h>
2929 #include <unwindstack/Memory.h>
@@ -32,6 +32,10 @@
3232 #include "ElfFake.h"
3333 #include "MemoryFake.h"
3434
35+#if !defined(NO_LIBDEXFILE_SUPPORT)
36+#include <DexFile.h>
37+#endif
38+
3539 namespace unwindstack {
3640
3741 class DexFilesTest : public ::testing::Test {
@@ -48,8 +52,7 @@ class DexFilesTest : public ::testing::Test {
4852 }
4953
5054 void Init(ArchEnum arch) {
51- dex_files_.reset(new DexFiles(process_memory_));
52- dex_files_->SetArch(arch);
55+ dex_files_ = JitDebug<DexFile>::Create(arch, process_memory_);
5356
5457 maps_.reset(
5558 new BufferMaps("1000-4000 ---s 00000000 00:00 0 /fake/elf\n"
@@ -86,10 +89,11 @@ class DexFilesTest : public ::testing::Test {
8689 Init(ARCH_ARM);
8790 }
8891
89- void WriteDescriptor32(uint64_t addr, uint32_t head);
90- void WriteDescriptor64(uint64_t addr, uint64_t head);
91- void WriteEntry32(uint64_t entry_addr, uint32_t next, uint32_t prev, uint32_t dex_file);
92- void WriteEntry64(uint64_t entry_addr, uint64_t next, uint64_t prev, uint64_t dex_file);
92+ void WriteDescriptor32(uint64_t addr, uint32_t entry);
93+ void WriteDescriptor64(uint64_t addr, uint64_t entry);
94+ void WriteEntry32Pack(uint64_t addr, uint32_t next, uint32_t prev, uint32_t dex);
95+ void WriteEntry32Pad(uint64_t addr, uint32_t next, uint32_t prev, uint32_t dex);
96+ void WriteEntry64(uint64_t addr, uint64_t next, uint64_t prev, uint64_t dex);
9397 void WriteDex(uint64_t dex_file);
9498
9599 static constexpr size_t kMapGlobalNonReadable = 2;
@@ -101,40 +105,70 @@ class DexFilesTest : public ::testing::Test {
101105
102106 std::shared_ptr<Memory> process_memory_;
103107 MemoryFake* memory_;
104- std::unique_ptr<DexFiles> dex_files_;
108+ std::unique_ptr<JitDebug<DexFile>> dex_files_;
105109 std::unique_ptr<BufferMaps> maps_;
106110 };
107111
108-void DexFilesTest::WriteDescriptor32(uint64_t addr, uint32_t head) {
109- // void* first_entry_
110- memory_->SetData32(addr + 12, head);
112+void DexFilesTest::WriteDescriptor32(uint64_t addr, uint32_t entry) {
113+ // Format of the 32 bit JITDescriptor structure:
114+ // uint32_t version
115+ memory_->SetData32(addr, 1);
116+ // uint32_t action_flag
117+ memory_->SetData32(addr + 4, 0);
118+ // uint32_t relevant_entry
119+ memory_->SetData32(addr + 8, 0);
120+ // uint32_t first_entry
121+ memory_->SetData32(addr + 12, entry);
122+}
123+
124+void DexFilesTest::WriteDescriptor64(uint64_t addr, uint64_t entry) {
125+ // Format of the 64 bit JITDescriptor structure:
126+ // uint32_t version
127+ memory_->SetData32(addr, 1);
128+ // uint32_t action_flag
129+ memory_->SetData32(addr + 4, 0);
130+ // uint64_t relevant_entry
131+ memory_->SetData64(addr + 8, 0);
132+ // uint64_t first_entry
133+ memory_->SetData64(addr + 16, entry);
111134 }
112135
113-void DexFilesTest::WriteDescriptor64(uint64_t addr, uint64_t head) {
114- // void* first_entry_
115- memory_->SetData64(addr + 16, head);
136+void DexFilesTest::WriteEntry32Pack(uint64_t addr, uint32_t next, uint32_t prev, uint32_t dex) {
137+ // Format of the 32 bit JITCodeEntry structure:
138+ // uint32_t next
139+ memory_->SetData32(addr, next);
140+ // uint32_t prev
141+ memory_->SetData32(addr + 4, prev);
142+ // uint32_t dex
143+ memory_->SetData32(addr + 8, dex);
144+ // uint64_t symfile_size
145+ memory_->SetData64(addr + 12, sizeof(kDexData) * sizeof(uint32_t));
116146 }
117147
118-void DexFilesTest::WriteEntry32(uint64_t entry_addr, uint32_t next, uint32_t prev,
119- uint32_t dex_file) {
120- // Format of the 32 bit DEXFileEntry structure:
148+void DexFilesTest::WriteEntry32Pad(uint64_t addr, uint32_t next, uint32_t prev, uint32_t dex) {
149+ // Format of the 32 bit JITCodeEntry structure:
121150 // uint32_t next
122- memory_->SetData32(entry_addr, next);
151+ memory_->SetData32(addr, next);
123152 // uint32_t prev
124- memory_->SetData32(entry_addr + 4, prev);
125- // uint32_t dex_file
126- memory_->SetData32(entry_addr + 8, dex_file);
153+ memory_->SetData32(addr + 4, prev);
154+ // uint32_t dex
155+ memory_->SetData32(addr + 8, dex);
156+ // uint32_t pad
157+ memory_->SetData32(addr + 12, 0);
158+ // uint64_t symfile_size
159+ memory_->SetData64(addr + 16, sizeof(kDexData) * sizeof(uint32_t));
127160 }
128161
129-void DexFilesTest::WriteEntry64(uint64_t entry_addr, uint64_t next, uint64_t prev,
130- uint64_t dex_file) {
131- // Format of the 64 bit DEXFileEntry structure:
162+void DexFilesTest::WriteEntry64(uint64_t addr, uint64_t next, uint64_t prev, uint64_t dex) {
163+ // Format of the 64 bit JITCodeEntry structure:
132164 // uint64_t next
133- memory_->SetData64(entry_addr, next);
165+ memory_->SetData64(addr, next);
134166 // uint64_t prev
135- memory_->SetData64(entry_addr + 8, prev);
136- // uint64_t dex_file
137- memory_->SetData64(entry_addr + 16, dex_file);
167+ memory_->SetData64(addr + 8, prev);
168+ // uint64_t dex
169+ memory_->SetData64(addr + 16, dex);
170+ // uint64_t symfile_size
171+ memory_->SetData64(addr + 24, sizeof(kDexData) * sizeof(uint32_t));
138172 }
139173
140174 void DexFilesTest::WriteDex(uint64_t dex_file) {
@@ -144,9 +178,8 @@ void DexFilesTest::WriteDex(uint64_t dex_file) {
144178 TEST_F(DexFilesTest, get_method_information_invalid) {
145179 std::string method_name = "nothing";
146180 uint64_t method_offset = 0x124;
147- MapInfo* info = maps_->Get(kMapDexFileEntries);
148181
149- dex_files_->GetMethodInformation(maps_.get(), info, 0, &method_name, &method_offset);
182+ dex_files_->GetFunctionName(maps_.get(), 0, &method_name, &method_offset);
150183 EXPECT_EQ("nothing", method_name);
151184 EXPECT_EQ(0x124U, method_offset);
152185 }
@@ -154,13 +187,12 @@ TEST_F(DexFilesTest, get_method_information_invalid) {
154187 TEST_F(DexFilesTest, get_method_information_32) {
155188 std::string method_name = "nothing";
156189 uint64_t method_offset = 0x124;
157- MapInfo* info = maps_->Get(kMapDexFiles);
158190
159191 WriteDescriptor32(0xf800, 0x200000);
160- WriteEntry32(0x200000, 0, 0, 0x300000);
192+ WriteEntry32Pad(0x200000, 0, 0, 0x300000);
161193 WriteDex(0x300000);
162194
163- dex_files_->GetMethodInformation(maps_.get(), info, 0x300100, &method_name, &method_offset);
195+ dex_files_->GetFunctionName(maps_.get(), 0x300100, &method_name, &method_offset);
164196 EXPECT_EQ("Main.<init>", method_name);
165197 EXPECT_EQ(0U, method_offset);
166198 }
@@ -170,13 +202,12 @@ TEST_F(DexFilesTest, get_method_information_64) {
170202
171203 std::string method_name = "nothing";
172204 uint64_t method_offset = 0x124;
173- MapInfo* info = maps_->Get(kMapDexFiles);
174205
175206 WriteDescriptor64(0xf800, 0x200000);
176207 WriteEntry64(0x200000, 0, 0, 0x301000);
177208 WriteDex(0x301000);
178209
179- dex_files_->GetMethodInformation(maps_.get(), info, 0x301102, &method_name, &method_offset);
210+ dex_files_->GetFunctionName(maps_.get(), 0x301102, &method_name, &method_offset);
180211 EXPECT_EQ("Main.<init>", method_name);
181212 EXPECT_EQ(2U, method_offset);
182213 }
@@ -184,14 +215,14 @@ TEST_F(DexFilesTest, get_method_information_64) {
184215 TEST_F(DexFilesTest, get_method_information_not_first_entry_32) {
185216 std::string method_name = "nothing";
186217 uint64_t method_offset = 0x124;
187- MapInfo* info = maps_->Get(kMapDexFiles);
188218
189219 WriteDescriptor32(0xf800, 0x200000);
190- WriteEntry32(0x200000, 0x200100, 0, 0x100000);
191- WriteEntry32(0x200100, 0, 0x200000, 0x300000);
220+ WriteEntry32Pad(0x200000, 0x200100, 0, 0x100000);
221+ WriteDex(0x100000);
222+ WriteEntry32Pad(0x200100, 0, 0x200000, 0x300000);
192223 WriteDex(0x300000);
193224
194- dex_files_->GetMethodInformation(maps_.get(), info, 0x300104, &method_name, &method_offset);
225+ dex_files_->GetFunctionName(maps_.get(), 0x300104, &method_name, &method_offset);
195226 EXPECT_EQ("Main.<init>", method_name);
196227 EXPECT_EQ(4U, method_offset);
197228 }
@@ -201,14 +232,14 @@ TEST_F(DexFilesTest, get_method_information_not_first_entry_64) {
201232
202233 std::string method_name = "nothing";
203234 uint64_t method_offset = 0x124;
204- MapInfo* info = maps_->Get(kMapDexFiles);
205235
206236 WriteDescriptor64(0xf800, 0x200000);
207237 WriteEntry64(0x200000, 0x200100, 0, 0x100000);
238+ WriteDex(0x100000);
208239 WriteEntry64(0x200100, 0, 0x200000, 0x300000);
209240 WriteDex(0x300000);
210241
211- dex_files_->GetMethodInformation(maps_.get(), info, 0x300106, &method_name, &method_offset);
242+ dex_files_->GetFunctionName(maps_.get(), 0x300106, &method_name, &method_offset);
212243 EXPECT_EQ("Main.<init>", method_name);
213244 EXPECT_EQ(6U, method_offset);
214245 }
@@ -216,19 +247,18 @@ TEST_F(DexFilesTest, get_method_information_not_first_entry_64) {
216247 TEST_F(DexFilesTest, get_method_information_cached) {
217248 std::string method_name = "nothing";
218249 uint64_t method_offset = 0x124;
219- MapInfo* info = maps_->Get(kMapDexFiles);
220250
221251 WriteDescriptor32(0xf800, 0x200000);
222- WriteEntry32(0x200000, 0, 0, 0x300000);
252+ WriteEntry32Pad(0x200000, 0, 0, 0x300000);
223253 WriteDex(0x300000);
224254
225- dex_files_->GetMethodInformation(maps_.get(), info, 0x300100, &method_name, &method_offset);
255+ dex_files_->GetFunctionName(maps_.get(), 0x300100, &method_name, &method_offset);
226256 EXPECT_EQ("Main.<init>", method_name);
227257 EXPECT_EQ(0U, method_offset);
228258
229259 // Clear all memory and make sure that data is acquired from the cache.
230260 memory_->Clear();
231- dex_files_->GetMethodInformation(maps_.get(), info, 0x300100, &method_name, &method_offset);
261+ dex_files_->GetFunctionName(maps_.get(), 0x300100, &method_name, &method_offset);
232262 EXPECT_EQ("Main.<init>", method_name);
233263 EXPECT_EQ(0U, method_offset);
234264 }
@@ -236,26 +266,24 @@ TEST_F(DexFilesTest, get_method_information_cached) {
236266 TEST_F(DexFilesTest, get_method_information_search_libs) {
237267 std::string method_name = "nothing";
238268 uint64_t method_offset = 0x124;
239- MapInfo* info = maps_->Get(kMapDexFiles);
240269
241270 WriteDescriptor32(0xf800, 0x200000);
242- WriteEntry32(0x200000, 0x200100, 0, 0x100000);
243- WriteEntry32(0x200100, 0, 0x200000, 0x300000);
271+ WriteEntry32Pad(0x200000, 0x200100, 0, 0x100000);
272+ WriteDex(0x100000);
273+ WriteEntry32Pad(0x200100, 0, 0x200000, 0x300000);
244274 WriteDex(0x300000);
245275
246276 // Only search a given named list of libs.
247277 std::vector<std::string> libs{"libart.so"};
248- dex_files_.reset(new DexFiles(process_memory_, libs));
249- dex_files_->SetArch(ARCH_ARM);
278+ dex_files_ = JitDebug<DexFile>::Create(ARCH_ARM, process_memory_, libs);
250279
251- dex_files_->GetMethodInformation(maps_.get(), info, 0x300104, &method_name, &method_offset);
280+ dex_files_->GetFunctionName(maps_.get(), 0x300104, &method_name, &method_offset);
252281 EXPECT_EQ("nothing", method_name);
253282 EXPECT_EQ(0x124U, method_offset);
254283
255284 MapInfo* map_info = maps_->Get(kMapGlobal);
256285 map_info->name = "/system/lib/libart.so";
257- dex_files_.reset(new DexFiles(process_memory_, libs));
258- dex_files_->SetArch(ARCH_ARM);
286+ dex_files_ = JitDebug<DexFile>::Create(ARCH_ARM, process_memory_, libs);
259287 // Set the rw map to the same name or this will not scan this entry.
260288 map_info = maps_->Get(kMapGlobalRw);
261289 map_info->name = "/system/lib/libart.so";
@@ -263,7 +291,7 @@ TEST_F(DexFilesTest, get_method_information_search_libs) {
263291 // DexFiles object.
264292 libs.clear();
265293
266- dex_files_->GetMethodInformation(maps_.get(), info, 0x300104, &method_name, &method_offset);
294+ dex_files_->GetFunctionName(maps_.get(), 0x300104, &method_name, &method_offset);
267295 EXPECT_EQ("Main.<init>", method_name);
268296 EXPECT_EQ(4U, method_offset);
269297 }
@@ -271,26 +299,24 @@ TEST_F(DexFilesTest, get_method_information_search_libs) {
271299 TEST_F(DexFilesTest, get_method_information_global_skip_zero_32) {
272300 std::string method_name = "nothing";
273301 uint64_t method_offset = 0x124;
274- MapInfo* info = maps_->Get(kMapDexFiles);
275302
276303 // First global variable found, but value is zero.
277304 WriteDescriptor32(0xa800, 0);
278305
279306 WriteDescriptor32(0xf800, 0x200000);
280- WriteEntry32(0x200000, 0, 0, 0x300000);
307+ WriteEntry32Pad(0x200000, 0, 0, 0x300000);
281308 WriteDex(0x300000);
282309
283- dex_files_->GetMethodInformation(maps_.get(), info, 0x300100, &method_name, &method_offset);
310+ dex_files_->GetFunctionName(maps_.get(), 0x300100, &method_name, &method_offset);
284311 EXPECT_EQ("Main.<init>", method_name);
285312 EXPECT_EQ(0U, method_offset);
286313
287314 // Verify that second is ignored when first is set to non-zero
288- dex_files_.reset(new DexFiles(process_memory_));
289- dex_files_->SetArch(ARCH_ARM);
315+ dex_files_ = JitDebug<DexFile>::Create(ARCH_ARM, process_memory_);
290316 method_name = "fail";
291317 method_offset = 0x123;
292318 WriteDescriptor32(0xa800, 0x100000);
293- dex_files_->GetMethodInformation(maps_.get(), info, 0x300100, &method_name, &method_offset);
319+ dex_files_->GetFunctionName(maps_.get(), 0x300100, &method_name, &method_offset);
294320 EXPECT_EQ("fail", method_name);
295321 EXPECT_EQ(0x123U, method_offset);
296322 }
@@ -300,7 +326,6 @@ TEST_F(DexFilesTest, get_method_information_global_skip_zero_64) {
300326
301327 std::string method_name = "nothing";
302328 uint64_t method_offset = 0x124;
303- MapInfo* info = maps_->Get(kMapDexFiles);
304329
305330 // First global variable found, but value is zero.
306331 WriteDescriptor64(0xa800, 0);
@@ -309,17 +334,16 @@ TEST_F(DexFilesTest, get_method_information_global_skip_zero_64) {
309334 WriteEntry64(0x200000, 0, 0, 0x300000);
310335 WriteDex(0x300000);
311336
312- dex_files_->GetMethodInformation(maps_.get(), info, 0x300100, &method_name, &method_offset);
337+ dex_files_->GetFunctionName(maps_.get(), 0x300100, &method_name, &method_offset);
313338 EXPECT_EQ("Main.<init>", method_name);
314339 EXPECT_EQ(0U, method_offset);
315340
316341 // Verify that second is ignored when first is set to non-zero
317- dex_files_.reset(new DexFiles(process_memory_));
318- dex_files_->SetArch(ARCH_ARM64);
342+ dex_files_ = JitDebug<DexFile>::Create(ARCH_ARM64, process_memory_);
319343 method_name = "fail";
320344 method_offset = 0x123;
321345 WriteDescriptor64(0xa800, 0x100000);
322- dex_files_->GetMethodInformation(maps_.get(), info, 0x300100, &method_name, &method_offset);
346+ dex_files_->GetFunctionName(maps_.get(), 0x300100, &method_name, &method_offset);
323347 EXPECT_EQ("fail", method_name);
324348 EXPECT_EQ(0x123U, method_offset);
325349 }
--- a/libunwindstack/tests/JitDebugTest.cpp
+++ b/libunwindstack/tests/JitDebugTest.cpp
@@ -46,8 +46,7 @@ class JitDebugTest : public ::testing::Test {
4646 }
4747
4848 void Init(ArchEnum arch) {
49- jit_debug_.reset(new JitDebug(process_memory_));
50- jit_debug_->SetArch(arch);
49+ jit_debug_ = JitDebug<Elf>::Create(arch, process_memory_);
5150
5251 maps_.reset(
5352 new BufferMaps("1000-4000 ---s 00000000 00:00 0 /fake/elf1\n"
@@ -62,6 +61,12 @@ class JitDebugTest : public ::testing::Test {
6261 "200000-210000 rw-p 0002000 00:00 0 /fake/elf4\n"));
6362 ASSERT_TRUE(maps_->Parse());
6463
64+ // Ensure all memory of the ELF file is initialized,
65+ // otherwise reads within it may fail.
66+ for (uint64_t addr = 0x4000; addr < 0x6000; addr += 8) {
67+ memory_->SetData64(addr, 0);
68+ }
69+
6570 MapInfo* map_info = maps_->Get(3);
6671 ASSERT_TRUE(map_info != nullptr);
6772 CreateFakeElf(map_info);
@@ -94,7 +99,7 @@ class JitDebugTest : public ::testing::Test {
9499 ehdr.e_shstrndx = 1;
95100 ehdr.e_shoff = sh_offset;
96101 ehdr.e_shentsize = sizeof(ShdrType);
97- ehdr.e_shnum = 3;
102+ ehdr.e_shnum = 4;
98103 memory_->SetMemory(offset, &ehdr, sizeof(ehdr));
99104
100105 ShdrType shdr;
@@ -110,6 +115,7 @@ class JitDebugTest : public ::testing::Test {
110115 shdr.sh_size = 0x100;
111116 memory_->SetMemory(offset + sh_offset, &shdr, sizeof(shdr));
112117 memory_->SetMemory(offset + 0x500, ".debug_frame");
118+ memory_->SetMemory(offset + 0x550, ".text");
113119
114120 sh_offset += sizeof(shdr);
115121 memset(&shdr, 0, sizeof(shdr));
@@ -120,6 +126,15 @@ class JitDebugTest : public ::testing::Test {
120126 shdr.sh_size = 0x200;
121127 memory_->SetMemory(offset + sh_offset, &shdr, sizeof(shdr));
122128
129+ sh_offset += sizeof(shdr);
130+ memset(&shdr, 0, sizeof(shdr));
131+ shdr.sh_type = SHT_NOBITS;
132+ shdr.sh_name = 0x50;
133+ shdr.sh_addr = pc;
134+ shdr.sh_offset = 0;
135+ shdr.sh_size = size;
136+ memory_->SetMemory(offset + sh_offset, &shdr, sizeof(shdr));
137+
123138 // Now add a single cie/fde.
124139 uint64_t dwarf_offset = offset + 0x600;
125140 if (class_type == ELFCLASS32) {
@@ -168,7 +183,7 @@ class JitDebugTest : public ::testing::Test {
168183
169184 std::shared_ptr<Memory> process_memory_;
170185 MemoryFake* memory_;
171- std::unique_ptr<JitDebug> jit_debug_;
186+ std::unique_ptr<JitDebug<Elf>> jit_debug_;
172187 std::unique_ptr<BufferMaps> maps_;
173188 };
174189
@@ -238,20 +253,20 @@ void JitDebugTest::WriteEntry64(uint64_t addr, uint64_t prev, uint64_t next, uin
238253 }
239254
240255 TEST_F(JitDebugTest, get_elf_invalid) {
241- Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500);
256+ Elf* elf = jit_debug_->Get(maps_.get(), 0x1500);
242257 ASSERT_TRUE(elf == nullptr);
243258 }
244259
245260 TEST_F(JitDebugTest, get_elf_no_global_variable) {
246261 maps_.reset(new BufferMaps(""));
247- Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500);
262+ Elf* elf = jit_debug_->Get(maps_.get(), 0x1500);
248263 ASSERT_TRUE(elf == nullptr);
249264 }
250265
251266 TEST_F(JitDebugTest, get_elf_no_valid_descriptor_in_memory) {
252267 CreateElf<Elf32_Ehdr, Elf32_Shdr>(0x4000, ELFCLASS32, EM_ARM, 0x1500, 0x200);
253268
254- Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500);
269+ Elf* elf = jit_debug_->Get(maps_.get(), 0x1500);
255270 ASSERT_TRUE(elf == nullptr);
256271 }
257272
@@ -260,7 +275,7 @@ TEST_F(JitDebugTest, get_elf_no_valid_code_entry) {
260275
261276 WriteDescriptor32(0xf800, 0x200000);
262277
263- Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500);
278+ Elf* elf = jit_debug_->Get(maps_.get(), 0x1500);
264279 ASSERT_TRUE(elf == nullptr);
265280 }
266281
@@ -269,7 +284,7 @@ TEST_F(JitDebugTest, get_elf_invalid_descriptor_first_entry) {
269284
270285 WriteDescriptor32(0xf800, 0);
271286
272- Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500);
287+ Elf* elf = jit_debug_->Get(maps_.get(), 0x1500);
273288 ASSERT_TRUE(elf == nullptr);
274289 }
275290
@@ -280,7 +295,7 @@ TEST_F(JitDebugTest, get_elf_invalid_descriptor_version) {
280295 // Set the version to an invalid value.
281296 memory_->SetData32(0xf800, 2);
282297
283- Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500);
298+ Elf* elf = jit_debug_->Get(maps_.get(), 0x1500);
284299 ASSERT_TRUE(elf == nullptr);
285300 }
286301
@@ -290,12 +305,18 @@ TEST_F(JitDebugTest, get_elf_32) {
290305 WriteDescriptor32(0xf800, 0x200000);
291306 WriteEntry32Pad(0x200000, 0, 0, 0x4000, 0x1000);
292307
293- Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500);
308+ Elf* elf = jit_debug_->Get(maps_.get(), 0x1500);
294309 ASSERT_TRUE(elf != nullptr);
310+ uint64_t text_addr;
311+ uint64_t text_size;
312+ ASSERT_TRUE(elf->GetTextRange(&text_addr, &text_size));
313+ ASSERT_EQ(text_addr, 0x1500u);
314+ ASSERT_EQ(text_size, 0x200u);
295315
296316 // Clear the memory and verify all of the data is cached.
297317 memory_->Clear();
298- Elf* elf2 = jit_debug_->GetElf(maps_.get(), 0x1500);
318+ WriteDescriptor32(0xf800, 0x200000);
319+ Elf* elf2 = jit_debug_->Get(maps_.get(), 0x1500);
299320 ASSERT_TRUE(elf2 != nullptr);
300321 EXPECT_EQ(elf, elf2);
301322 }
@@ -309,16 +330,15 @@ TEST_F(JitDebugTest, get_multiple_jit_debug_descriptors_valid) {
309330 WriteDescriptor32(0x12800, 0x201000);
310331 WriteEntry32Pad(0x201000, 0, 0, 0x5000, 0x1000);
311332
312- ASSERT_TRUE(jit_debug_->GetElf(maps_.get(), 0x1500) != nullptr);
313- ASSERT_TRUE(jit_debug_->GetElf(maps_.get(), 0x2000) == nullptr);
333+ ASSERT_TRUE(jit_debug_->Get(maps_.get(), 0x1500) != nullptr);
334+ ASSERT_TRUE(jit_debug_->Get(maps_.get(), 0x2000) == nullptr);
314335
315336 // Now clear the descriptor entry for the first one.
316337 WriteDescriptor32(0xf800, 0);
317- jit_debug_.reset(new JitDebug(process_memory_));
318- jit_debug_->SetArch(ARCH_ARM);
338+ jit_debug_ = JitDebug<Elf>::Create(ARCH_ARM, process_memory_);
319339
320- ASSERT_TRUE(jit_debug_->GetElf(maps_.get(), 0x1500) == nullptr);
321- ASSERT_TRUE(jit_debug_->GetElf(maps_.get(), 0x2000) != nullptr);
340+ ASSERT_TRUE(jit_debug_->Get(maps_.get(), 0x1500) == nullptr);
341+ ASSERT_TRUE(jit_debug_->Get(maps_.get(), 0x2000) != nullptr);
322342 }
323343
324344 TEST_F(JitDebugTest, get_elf_x86) {
@@ -329,13 +349,14 @@ TEST_F(JitDebugTest, get_elf_x86) {
329349 WriteDescriptor32(0xf800, 0x200000);
330350 WriteEntry32Pack(0x200000, 0, 0, 0x4000, 0x1000);
331351
332- jit_debug_->SetArch(ARCH_X86);
333- Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500);
352+ jit_debug_ = JitDebug<Elf>::Create(ARCH_X86, process_memory_);
353+ Elf* elf = jit_debug_->Get(maps_.get(), 0x1500);
334354 ASSERT_TRUE(elf != nullptr);
335355
336356 // Clear the memory and verify all of the data is cached.
337357 memory_->Clear();
338- Elf* elf2 = jit_debug_->GetElf(maps_.get(), 0x1500);
358+ WriteDescriptor32(0xf800, 0x200000);
359+ Elf* elf2 = jit_debug_->Get(maps_.get(), 0x1500);
339360 ASSERT_TRUE(elf2 != nullptr);
340361 EXPECT_EQ(elf, elf2);
341362 }
@@ -348,12 +369,13 @@ TEST_F(JitDebugTest, get_elf_64) {
348369 WriteDescriptor64(0xf800, 0x200000);
349370 WriteEntry64(0x200000, 0, 0, 0x4000, 0x1000);
350371
351- Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500);
372+ Elf* elf = jit_debug_->Get(maps_.get(), 0x1500);
352373 ASSERT_TRUE(elf != nullptr);
353374
354375 // Clear the memory and verify all of the data is cached.
355376 memory_->Clear();
356- Elf* elf2 = jit_debug_->GetElf(maps_.get(), 0x1500);
377+ WriteDescriptor64(0xf800, 0x200000);
378+ Elf* elf2 = jit_debug_->Get(maps_.get(), 0x1500);
357379 ASSERT_TRUE(elf2 != nullptr);
358380 EXPECT_EQ(elf, elf2);
359381 }
@@ -366,20 +388,21 @@ TEST_F(JitDebugTest, get_elf_multiple_entries) {
366388 WriteEntry32Pad(0x200000, 0, 0x200100, 0x4000, 0x1000);
367389 WriteEntry32Pad(0x200100, 0x200100, 0, 0x5000, 0x1000);
368390
369- Elf* elf_2 = jit_debug_->GetElf(maps_.get(), 0x2400);
391+ Elf* elf_2 = jit_debug_->Get(maps_.get(), 0x2400);
370392 ASSERT_TRUE(elf_2 != nullptr);
371393
372- Elf* elf_1 = jit_debug_->GetElf(maps_.get(), 0x1600);
394+ Elf* elf_1 = jit_debug_->Get(maps_.get(), 0x1600);
373395 ASSERT_TRUE(elf_1 != nullptr);
374396
375397 // Clear the memory and verify all of the data is cached.
376398 memory_->Clear();
377- EXPECT_EQ(elf_1, jit_debug_->GetElf(maps_.get(), 0x1500));
378- EXPECT_EQ(elf_1, jit_debug_->GetElf(maps_.get(), 0x16ff));
379- EXPECT_EQ(elf_2, jit_debug_->GetElf(maps_.get(), 0x2300));
380- EXPECT_EQ(elf_2, jit_debug_->GetElf(maps_.get(), 0x26ff));
381- EXPECT_EQ(nullptr, jit_debug_->GetElf(maps_.get(), 0x1700));
382- EXPECT_EQ(nullptr, jit_debug_->GetElf(maps_.get(), 0x2700));
399+ WriteDescriptor32(0xf800, 0x200000);
400+ EXPECT_EQ(elf_1, jit_debug_->Get(maps_.get(), 0x1500));
401+ EXPECT_EQ(elf_1, jit_debug_->Get(maps_.get(), 0x16ff));
402+ EXPECT_EQ(elf_2, jit_debug_->Get(maps_.get(), 0x2300));
403+ EXPECT_EQ(elf_2, jit_debug_->Get(maps_.get(), 0x26ff));
404+ EXPECT_EQ(nullptr, jit_debug_->Get(maps_.get(), 0x1700));
405+ EXPECT_EQ(nullptr, jit_debug_->Get(maps_.get(), 0x2700));
383406 }
384407
385408 TEST_F(JitDebugTest, get_elf_search_libs) {
@@ -390,21 +413,19 @@ TEST_F(JitDebugTest, get_elf_search_libs) {
390413
391414 // Only search a given named list of libs.
392415 std::vector<std::string> libs{"libart.so"};
393- jit_debug_.reset(new JitDebug(process_memory_, libs));
394- jit_debug_->SetArch(ARCH_ARM);
395- EXPECT_TRUE(jit_debug_->GetElf(maps_.get(), 0x1500) == nullptr);
416+ jit_debug_ = JitDebug<Elf>::Create(ARCH_ARM, process_memory_, libs);
417+ EXPECT_TRUE(jit_debug_->Get(maps_.get(), 0x1500) == nullptr);
396418
397419 // Change the name of the map that includes the value and verify this works.
398420 MapInfo* map_info = maps_->Get(5);
399421 map_info->name = "/system/lib/libart.so";
400422 map_info = maps_->Get(6);
401423 map_info->name = "/system/lib/libart.so";
402- jit_debug_.reset(new JitDebug(process_memory_, libs));
424+ jit_debug_ = JitDebug<Elf>::Create(ARCH_ARM, process_memory_);
403425 // Make sure that clearing our copy of the libs doesn't affect the
404426 // JitDebug object.
405427 libs.clear();
406- jit_debug_->SetArch(ARCH_ARM);
407- EXPECT_TRUE(jit_debug_->GetElf(maps_.get(), 0x1500) != nullptr);
428+ EXPECT_TRUE(jit_debug_->Get(maps_.get(), 0x1500) != nullptr);
408429 }
409430
410431 } // namespace unwindstack
--- a/libunwindstack/tests/UnwindOfflineTest.cpp
+++ b/libunwindstack/tests/UnwindOfflineTest.cpp
@@ -290,9 +290,7 @@ TEST_F(UnwindOfflineTest, jit_debug_x86) {
290290 }
291291 process_memory_.reset(memory);
292292
293- JitDebug jit_debug(process_memory_);
294293 Unwinder unwinder(128, maps_.get(), regs_.get(), process_memory_);
295- unwinder.SetJitDebug(&jit_debug, regs_->Arch());
296294 unwinder.Unwind();
297295
298296 std::string frame_info(DumpFrames(unwinder));
@@ -592,9 +590,7 @@ TEST_F(UnwindOfflineTest, jit_debug_arm) {
592590 }
593591 process_memory_.reset(memory);
594592
595- JitDebug jit_debug(process_memory_);
596593 Unwinder unwinder(128, maps_.get(), regs_.get(), process_memory_);
597- unwinder.SetJitDebug(&jit_debug, regs_->Arch());
598594 unwinder.Unwind();
599595
600596 std::string frame_info(DumpFrames(unwinder));
@@ -915,9 +911,7 @@ static void OfflineUnwind(void* data) {
915911 LeakType* leak_data = reinterpret_cast<LeakType*>(data);
916912
917913 std::unique_ptr<Regs> regs_copy(leak_data->regs->Clone());
918- JitDebug jit_debug(leak_data->process_memory);
919914 Unwinder unwinder(128, leak_data->maps, regs_copy.get(), leak_data->process_memory);
920- unwinder.SetJitDebug(&jit_debug, regs_copy->Arch());
921915 unwinder.Unwind();
922916 ASSERT_EQ(76U, unwinder.NumFrames());
923917 }
@@ -1038,9 +1032,7 @@ TEST_F(UnwindOfflineTest, art_quick_osr_stub_arm) {
10381032 }
10391033 process_memory_.reset(memory);
10401034
1041- JitDebug jit_debug(process_memory_);
10421035 Unwinder unwinder(128, maps_.get(), regs_.get(), process_memory_);
1043- unwinder.SetJitDebug(&jit_debug, regs_->Arch());
10441036 unwinder.Unwind();
10451037
10461038 std::string frame_info(DumpFrames(unwinder));
--- a/libunwindstack/tests/UnwindTest.cpp
+++ b/libunwindstack/tests/UnwindTest.cpp
@@ -170,7 +170,7 @@ extern "C" void InnerFunction(TestTypeEnum test_type) {
170170 unwinder.reset(new Unwinder(512, maps.get(), regs.get(), process_memory));
171171 } else {
172172 UnwinderFromPid* unwinder_from_pid = new UnwinderFromPid(512, getpid());
173- ASSERT_TRUE(unwinder_from_pid->Init(regs->Arch()));
173+ ASSERT_TRUE(unwinder_from_pid->Init());
174174 unwinder_from_pid->SetRegs(regs.get());
175175 unwinder.reset(unwinder_from_pid);
176176 }
@@ -283,7 +283,7 @@ TEST_F(UnwindTest, unwind_from_pid_remote) {
283283 ASSERT_TRUE(regs.get() != nullptr);
284284
285285 UnwinderFromPid unwinder(512, pid);
286- ASSERT_TRUE(unwinder.Init(regs->Arch()));
286+ ASSERT_TRUE(unwinder.Init());
287287 unwinder.SetRegs(regs.get());
288288
289289 VerifyUnwind(&unwinder, kFunctionOrder);
@@ -335,7 +335,7 @@ static void RemoteUnwindFromPid(void* data) {
335335 ASSERT_TRUE(regs.get() != nullptr);
336336
337337 UnwinderFromPid unwinder(512, *pid);
338- ASSERT_TRUE(unwinder.Init(regs->Arch()));
338+ ASSERT_TRUE(unwinder.Init());
339339 unwinder.SetRegs(regs.get());
340340
341341 VerifyUnwind(&unwinder, kFunctionOrder);
--- a/libunwindstack/tools/unwind.cpp
+++ b/libunwindstack/tools/unwind.cpp
@@ -26,7 +26,6 @@
2626 #include <sys/types.h>
2727 #include <unistd.h>
2828
29-#include <unwindstack/DexFiles.h>
3029 #include <unwindstack/Elf.h>
3130 #include <unwindstack/JitDebug.h>
3231 #include <unwindstack/Maps.h>
@@ -90,7 +89,7 @@ void DoUnwind(pid_t pid) {
9089 printf("\n");
9190
9291 unwindstack::UnwinderFromPid unwinder(1024, pid);
93- if (!unwinder.Init(regs->Arch())) {
92+ if (!unwinder.Init()) {
9493 printf("Failed to init unwinder object.\n");
9594 return;
9695 }
--- a/libunwindstack/tools/unwind_for_offline.cpp
+++ b/libunwindstack/tools/unwind_for_offline.cpp
@@ -248,7 +248,7 @@ int SaveData(pid_t pid) {
248248 // Do an unwind so we know how much of the stack to save, and what
249249 // elf files are involved.
250250 unwindstack::UnwinderFromPid unwinder(1024, pid);
251- if (!unwinder.Init(regs->Arch())) {
251+ if (!unwinder.Init()) {
252252 printf("Unable to init unwinder object.\n");
253253 return 1;
254254 }