• R/O
  • HTTP
  • SSH
  • HTTPS

提交

標籤
無標籤

Frequently used words (click to add to your profile)

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

system/core


Commit MetaInfo

修訂e5c4d62ba3fca09fed86ec605542b2be74a59851 (tree)
時間2019-04-12 21:55:50
作者David Srbecky <dsrbecky@goog...>
CommiterDavid Srbecky

Log Message

Revert "Check for data races when reading JIT/DEX entries."

This reverts commit 85b5fecec920208ec43b42488f08d4c2e5aaeda2.

Reason for revert: Breaks ART tests, reverting to investigate.
Exempt-From-Owner-Approval: Revert.

(cherry picked from commit b9cc4fbb268652744c812415cb2e5d1fbe04879a)

Bug: 130406806
Change-Id: I634e37060b97484d627fc544e3b406fd90aaa784

Change Summary

差異

--- a/debuggerd/crash_dump.cpp
+++ b/debuggerd/crash_dump.cpp
@@ -48,6 +48,7 @@
4848 #define ATRACE_TAG ATRACE_TAG_BIONIC
4949 #include <utils/Trace.h>
5050
51+#include <unwindstack/DexFiles.h>
5152 #include <unwindstack/JitDebug.h>
5253 #include <unwindstack/Maps.h>
5354 #include <unwindstack/Memory.h>
@@ -566,7 +567,7 @@ int main(int argc, char** argv) {
566567
567568 // TODO: Use seccomp to lock ourselves down.
568569 unwindstack::UnwinderFromPid unwinder(256, vm_pid);
569- if (!unwinder.Init()) {
570+ if (!unwinder.Init(unwindstack::Regs::CurrentArch())) {
570571 LOG(FATAL) << "Failed to init unwinder object.";
571572 }
572573
--- a/debuggerd/handler/debuggerd_fallback.cpp
+++ b/debuggerd/handler/debuggerd_fallback.cpp
@@ -42,6 +42,7 @@
4242 #include <android-base/file.h>
4343 #include <android-base/unique_fd.h>
4444 #include <async_safe/log.h>
45+#include <unwindstack/DexFiles.h>
4546 #include <unwindstack/JitDebug.h>
4647 #include <unwindstack/Maps.h>
4748 #include <unwindstack/Memory.h>
@@ -80,12 +81,12 @@ static void debuggerd_fallback_trace(int output_fd, ucontext_t* ucontext) {
8081 thread.pid = getpid();
8182 thread.tid = gettid();
8283 thread.thread_name = get_thread_name(gettid());
83- thread.registers.reset(
84- unwindstack::Regs::CreateFromUcontext(unwindstack::Regs::CurrentArch(), ucontext));
84+ unwindstack::ArchEnum arch = unwindstack::Regs::CurrentArch();
85+ thread.registers.reset(unwindstack::Regs::CreateFromUcontext(arch, ucontext));
8586
8687 // TODO: Create this once and store it in a global?
8788 unwindstack::UnwinderFromPid unwinder(kMaxFrames, getpid());
88- if (unwinder.Init()) {
89+ if (unwinder.Init(arch)) {
8990 dump_backtrace_thread(output_fd, &unwinder, thread);
9091 } else {
9192 async_safe_format_log(ANDROID_LOG_ERROR, "libc", "Unable to init unwinder.");
--- a/debuggerd/libdebuggerd/tombstone.cpp
+++ b/debuggerd/libdebuggerd/tombstone.cpp
@@ -45,6 +45,7 @@
4545 #include <log/log.h>
4646 #include <log/logprint.h>
4747 #include <private/android_filesystem_config.h>
48+#include <unwindstack/DexFiles.h>
4849 #include <unwindstack/JitDebug.h>
4950 #include <unwindstack/Maps.h>
5051 #include <unwindstack/Memory.h>
@@ -650,7 +651,7 @@ void engrave_tombstone_ucontext(int tombstone_fd, uint64_t abort_msg_address, si
650651 };
651652
652653 unwindstack::UnwinderFromPid unwinder(kMaxFrames, pid);
653- if (!unwinder.Init()) {
654+ if (!unwinder.Init(unwindstack::Regs::CurrentArch())) {
654655 LOG(FATAL) << "Failed to init unwinder object.";
655656 }
656657
--- a/libbacktrace/UnwindStack.cpp
+++ b/libbacktrace/UnwindStack.cpp
@@ -32,6 +32,9 @@
3232 #include <unwindstack/Regs.h>
3333 #include <unwindstack/RegsGetLocal.h>
3434
35+#if !defined(NO_LIBDEXFILE_SUPPORT)
36+#include <unwindstack/DexFiles.h>
37+#endif
3538 #include <unwindstack/Unwinder.h>
3639
3740 #include "BacktraceLog.h"
@@ -47,6 +50,14 @@ bool Backtrace::Unwind(unwindstack::Regs* regs, BacktraceMap* back_map,
4750 regs, stack_map->process_memory());
4851 unwinder.SetResolveNames(stack_map->ResolveNames());
4952 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
5061 unwinder.Unwind(skip_names, &stack_map->GetSuffixesToIgnore());
5162 if (error != nullptr) {
5263 switch (unwinder.LastErrorCode()) {
--- a/libbacktrace/UnwindStackMap.cpp
+++ b/libbacktrace/UnwindStackMap.cpp
@@ -43,6 +43,13 @@ 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+
4653 if (!stack_maps_->Parse()) {
4754 return false;
4855 }
--- a/libbacktrace/UnwindStackMap.h
+++ b/libbacktrace/UnwindStackMap.h
@@ -27,6 +27,9 @@
2727
2828 #include <backtrace/Backtrace.h>
2929 #include <backtrace/BacktraceMap.h>
30+#if !defined(NO_LIBDEXFILE_SUPPORT)
31+#include <unwindstack/DexFiles.h>
32+#endif
3033 #include <unwindstack/Elf.h>
3134 #include <unwindstack/JitDebug.h>
3235 #include <unwindstack/Maps.h>
@@ -50,6 +53,12 @@ class UnwindStackMap : public BacktraceMap {
5053
5154 const std::shared_ptr<unwindstack::Memory>& process_memory() { return process_memory_; }
5255
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+
5362 void SetArch(unwindstack::ArchEnum arch) { arch_ = arch; }
5463
5564 protected:
@@ -57,6 +66,11 @@ class UnwindStackMap : public BacktraceMap {
5766
5867 std::unique_ptr<unwindstack::Maps> stack_maps_;
5968 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+
6074 unwindstack::ArchEnum arch_ = unwindstack::ARCH_UNKNOWN;
6175 };
6276
--- a/libunwindstack/Android.bp
+++ b/libunwindstack/Android.bp
@@ -49,6 +49,7 @@ cc_library {
4949 srcs: [
5050 "ArmExidx.cpp",
5151 "DexFile.cpp",
52+ "DexFiles.cpp",
5253 "DwarfCfa.cpp",
5354 "DwarfEhFrameWithHdr.cpp",
5455 "DwarfMemory.cpp",
@@ -91,6 +92,7 @@ cc_library {
9192 cflags: ["-DNO_LIBDEXFILE_SUPPORT"],
9293 exclude_srcs: [
9394 "DexFile.cpp",
95+ "DexFiles.cpp",
9496 ],
9597 exclude_shared_libs: [
9698 "libdexfile_support",
@@ -100,6 +102,7 @@ cc_library {
100102 cflags: ["-DNO_LIBDEXFILE_SUPPORT"],
101103 exclude_srcs: [
102104 "DexFile.cpp",
105+ "DexFiles.cpp",
103106 ],
104107 exclude_shared_libs: [
105108 "libdexfile_support",
--- a/libunwindstack/DexFile.cpp
+++ b/libunwindstack/DexFile.cpp
@@ -35,31 +35,22 @@ 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_from_file =
38+ std::unique_ptr<DexFile> dex_file =
3939 DexFileFromFile::Create(dex_file_offset_in_memory - info->start + info->offset, info->name);
40- if (dex_file_from_file) {
41- dex_file_from_file->addr_ = dex_file_offset_in_memory;
42- return dex_file_from_file;
40+ if (dex_file) {
41+ return dex_file;
4342 }
4443 }
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;
44+ return DexFileFromMemory::Create(dex_file_offset_in_memory, memory, info->name);
5245 }
5346
54-bool DexFile::GetFunctionName(uint64_t dex_pc, std::string* method_name, uint64_t* method_offset) {
55- uint64_t dex_offset = dex_pc - addr_;
47+bool DexFile::GetMethodInformation(uint64_t dex_offset, std::string* method_name,
48+ uint64_t* method_offset) {
5649 art_api::dex::MethodInfo method_info = GetMethodInfoForOffset(dex_offset, false);
5750 if (method_info.offset == 0) {
5851 return false;
5952 }
60- if (method_name != nullptr) {
61- *method_name = method_info.name;
62- }
53+ *method_name = method_info.name;
6354 *method_offset = dex_offset - method_info.offset;
6455 return true;
6556 }
--- a/libunwindstack/DexFile.h
+++ b/libunwindstack/DexFile.h
@@ -29,22 +29,17 @@
2929
3030 namespace unwindstack {
3131
32-class Memory;
33-struct MapInfo;
34-
3532 class DexFile : protected art_api::dex::DexFile {
3633 public:
3734 virtual ~DexFile() = default;
3835
39- bool GetFunctionName(uint64_t dex_pc, std::string* method_name, uint64_t* method_offset);
36+ bool GetMethodInformation(uint64_t dex_offset, std::string* method_name, uint64_t* method_offset);
4037
4138 static std::unique_ptr<DexFile> Create(uint64_t dex_file_offset_in_memory, Memory* memory,
4239 MapInfo* info);
4340
4441 protected:
4542 DexFile(art_api::dex::DexFile&& art_dex_file) : art_api::dex::DexFile(std::move(art_dex_file)) {}
46-
47- uint64_t addr_ = 0;
4843 };
4944
5045 class DexFileFromFile : public DexFile {
--- /dev/null
+++ b/libunwindstack/DexFiles.cpp
@@ -0,0 +1,179 @@
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,24 +243,6 @@ 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-
264246 ElfInterface* Elf::CreateInterfaceFromMemory(Memory* memory) {
265247 if (!IsValidElf(memory)) {
266248 return nullptr;
--- a/libunwindstack/ElfInterface.cpp
+++ b/libunwindstack/ElfInterface.cpp
@@ -69,15 +69,6 @@ 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-
8172 Memory* ElfInterface::CreateGnuDebugdataMemory() {
8273 if (gnu_debugdata_offset_ == 0 || gnu_debugdata_size_ == 0) {
8374 return nullptr;
@@ -339,26 +330,29 @@ void ElfInterface::ReadSectionHeaders(const EhdrType& ehdr) {
339330 }
340331 symbols_.push_back(new Symbols(shdr.sh_offset, shdr.sh_size, shdr.sh_entsize,
341332 str_shdr.sh_offset, str_shdr.sh_size));
342- } else if (shdr.sh_type == SHT_PROGBITS || shdr.sh_type == SHT_NOBITS) {
333+ } else if (shdr.sh_type == SHT_PROGBITS && sec_size != 0) {
343334 // Look for the .debug_frame and .gnu_debugdata.
344335 if (shdr.sh_name < sec_size) {
345336 std::string name;
346337 if (memory_->ReadString(sec_offset + shdr.sh_name, &name)) {
338+ uint64_t* offset_ptr = nullptr;
339+ uint64_t* size_ptr = nullptr;
347340 if (name == ".debug_frame") {
348- debug_frame_offset_ = shdr.sh_offset;
349- debug_frame_size_ = shdr.sh_size;
341+ offset_ptr = &debug_frame_offset_;
342+ size_ptr = &debug_frame_size_;
350343 } else if (name == ".gnu_debugdata") {
351- gnu_debugdata_offset_ = shdr.sh_offset;
352- gnu_debugdata_size_ = shdr.sh_size;
344+ offset_ptr = &gnu_debugdata_offset_;
345+ size_ptr = &gnu_debugdata_size_;
353346 } else if (name == ".eh_frame") {
354- eh_frame_offset_ = shdr.sh_offset;
355- eh_frame_size_ = shdr.sh_size;
347+ offset_ptr = &eh_frame_offset_;
348+ size_ptr = &eh_frame_size_;
356349 } else if (eh_frame_hdr_offset_ == 0 && name == ".eh_frame_hdr") {
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;
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;
362356 }
363357 }
364358 }
--- a/libunwindstack/JitDebug.cpp
+++ b/libunwindstack/JitDebug.cpp
@@ -16,13 +16,8 @@
1616
1717 #include <stdint.h>
1818 #include <sys/mman.h>
19-#include <cstddef>
2019
21-#include <atomic>
22-#include <deque>
23-#include <map>
2420 #include <memory>
25-#include <unordered_set>
2621 #include <vector>
2722
2823 #include <unwindstack/Elf.h>
@@ -30,334 +25,197 @@
3025 #include <unwindstack/Maps.h>
3126 #include <unwindstack/Memory.h>
3227
33-#if !defined(NO_LIBDEXFILE_SUPPORT)
34-#include <DexFile.h>
35-#endif
36-
3728 // This implements the JIT Compilation Interface.
3829 // See https://sourceware.org/gdb/onlinedocs/gdb/JIT-Interface.html
3930
4031 namespace unwindstack {
4132
42-// 32-bit platforms may differ in alignment of uint64_t.
43-struct Uint64_P {
44- uint64_t value;
33+struct JITCodeEntry32Pack {
34+ uint32_t next;
35+ uint32_t prev;
36+ uint32_t symfile_addr;
37+ uint64_t symfile_size;
4538 } __attribute__((packed));
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;
60-};
6139
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_;
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+};
6847
69- bool Init(Maps* maps, JitMemory* memory, uint64_t addr, uint64_t size);
48+struct JITCodeEntry64 {
49+ uint64_t next;
50+ uint64_t prev;
51+ uint64_t symfile_addr;
52+ uint64_t symfile_size;
7053 };
7154
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- }
55+struct JITDescriptorHeader {
56+ uint32_t version;
57+ uint32_t action_flag;
58+};
10859
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);
60+struct JITDescriptor32 {
61+ JITDescriptorHeader header;
62+ uint32_t relevant_entry;
63+ uint32_t first_entry;
64+};
11465
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.
66+struct JITDescriptor64 {
67+ JITDescriptorHeader header;
68+ uint64_t relevant_entry;
69+ uint64_t first_entry;
70+};
11971
120- std::deque<JitCacheEntry<Symfile>> entries_;
72+JitDebug::JitDebug(std::shared_ptr<Memory>& memory) : Global(memory) {}
12173
122- std::mutex lock_;
123-};
74+JitDebug::JitDebug(std::shared_ptr<Memory>& memory, std::vector<std::string>& search_libs)
75+ : Global(memory, search_libs) {}
12476
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();
77+JitDebug::~JitDebug() {
78+ for (auto* elf : elf_list_) {
79+ delete elf;
15680 }
15781 }
15882
159-size_t JitMemory::Read(uint64_t addr, void* dst, size_t size) {
160- if (!parent_->ReadFully(addr, dst, size)) {
83+uint64_t JitDebug::ReadDescriptor32(uint64_t addr) {
84+ JITDescriptor32 desc;
85+ if (!memory_->ReadFully(addr, &desc, sizeof(desc))) {
16186 return 0;
16287 }
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)) {
168- return 0;
169- }
170- if (seen_seqlock != expected_seqlock_) {
171- failed_due_to_race_ = true;
88+
89+ if (desc.header.version != 1 || desc.first_entry == 0) {
90+ // Either unknown version, or no jit entries.
17291 return 0;
17392 }
174- return size;
93+
94+ return desc.first_entry;
17595 }
17696
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;
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);
97+uint64_t JitDebug::ReadDescriptor64(uint64_t addr) {
98+ JITDescriptor64 desc;
99+ if (!memory_->ReadFully(addr, &desc, sizeof(desc))) {
100+ return 0;
197101 }
198- return true;
199-}
200102
201-template <typename Symfile>
202-static const char* GetDescriptorName();
103+ if (desc.header.version != 1 || desc.first_entry == 0) {
104+ // Either unknown version, or no jit entries.
105+ return 0;
106+ }
203107
204-template <>
205-const char* GetDescriptorName<Elf>() {
206- return "__jit_debug_descriptor";
108+ return desc.first_entry;
207109 }
208110
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;
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;
215115 }
216116
217- if (descriptor_addr_ == 0) {
218- return nullptr;
219- }
117+ *start = code.symfile_addr;
118+ *size = code.symfile_size;
119+ return code.next;
120+}
220121
221- if (!Update(maps)) {
222- return nullptr;
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;
223126 }
224127
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.
128+ *start = code.symfile_addr;
129+ *size = code.symfile_size;
130+ return code.next;
240131 }
241132
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- }
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;
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;
274137 }
275- return false; // Too many retries.
138+
139+ *start = code.symfile_addr;
140+ *size = code.symfile_size;
141+ return code.next;
276142 }
277143
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;
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;
282150
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- }
151+ case ARCH_ARM:
152+ case ARCH_MIPS:
153+ read_descriptor_func_ = &JitDebug::ReadDescriptor32;
154+ read_entry_func_ = &JitDebug::ReadEntry32Pad;
155+ break;
288156
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- }
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();
165+ }
166+}
296167
297- // Read the entry (while checking for data races).
298- if (!memory->ReadFully(entry_addr, &entry, sizeof(entry))) {
299- return false;
300- }
168+bool JitDebug::ReadVariableData(uint64_t ptr) {
169+ entry_addr_ = (this->*read_descriptor_func_)(ptr);
170+ return entry_addr_ != 0;
171+}
301172
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- }
173+void JitDebug::Init(Maps* maps) {
174+ if (initialized_) {
175+ return;
307176 }
177+ // Regardless of what happens below, consider the init finished.
178+ initialized_ = true;
308179
309- return true;
180+ FindAndReadVariable(maps, "__jit_debug_descriptor");
310181 }
311182
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;
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);
320189 }
321190
322- // Load and validate the ELF file.
323- symfile_.reset(new Elf(buffer.release()));
324- symfile_->Init();
325- if (!symfile_->valid()) {
326- return false;
191+ // Search the existing elf object first.
192+ for (Elf* elf : elf_list_) {
193+ if (elf->IsValidPc(pc)) {
194+ return elf;
195+ }
327196 }
328197
329- symfile_->GetTextRange(&addr_, &size_);
330- return true;
331-}
198+ while (entry_addr_ != 0) {
199+ uint64_t start;
200+ uint64_t size;
201+ entry_addr_ = (this->*read_entry_func_)(&start, &size);
332202
333-template 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-
338-template <>
339-const char* GetDescriptorName<DexFile>() {
340- return "__dex_debug_descriptor";
341-}
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);
342213
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;
214+ if (elf->IsValidPc(pc)) {
215+ return elf;
216+ }
353217 }
354- return true;
218+ return nullptr;
355219 }
356220
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-
363221 } // namespace unwindstack
--- a/libunwindstack/Unwinder.cpp
+++ b/libunwindstack/Unwinder.cpp
@@ -36,38 +36,11 @@
3636 #include <unwindstack/Unwinder.h>
3737
3838 #if !defined(NO_LIBDEXFILE_SUPPORT)
39-#include <DexFile.h>
39+#include <unwindstack/DexFiles.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-
7144 // Inject extra 'virtual' frame that represents the dex pc data.
7245 // The dex pc is a magic register defined in the Mterp interpreter,
7346 // and thus it will be restored/observed in the frame after it.
@@ -111,7 +84,8 @@ void Unwinder::FillInDexFrame() {
11184 return;
11285 }
11386
114- dex_files_->GetFunctionName(maps_, dex_pc, &frame->function_name, &frame->function_offset);
87+ dex_files_->GetMethodInformation(maps_, info, dex_pc, &frame->function_name,
88+ &frame->function_offset);
11589 #endif
11690 }
11791
@@ -211,7 +185,7 @@ void Unwinder::Unwind(const std::vector<std::string>* initial_map_names_to_skip,
211185 // using the jit debug information.
212186 if (!elf->valid() && jit_debug_ != nullptr) {
213187 uint64_t adjusted_jit_pc = regs_->pc() - pc_adjustment;
214- Elf* jit_elf = jit_debug_->Get(maps_, adjusted_jit_pc);
188+ Elf* jit_elf = jit_debug_->GetElf(maps_, adjusted_jit_pc);
215189 if (jit_elf != nullptr) {
216190 // The jit debug information requires a non relative adjusted pc.
217191 step_pc = adjusted_jit_pc;
@@ -356,7 +330,19 @@ std::string Unwinder::FormatFrame(size_t frame_num) {
356330 return FormatFrame(frames_[frame_num]);
357331 }
358332
359-bool UnwinderFromPid::Init() {
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) {
360346 if (pid_ == getpid()) {
361347 maps_ptr_.reset(new LocalMaps());
362348 } else {
@@ -369,6 +355,15 @@ bool UnwinderFromPid::Init() {
369355
370356 process_memory_ = Memory::CreateProcessMemoryCached(pid_);
371357
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+
372367 return true;
373368 }
374369
--- /dev/null
+++ b/libunwindstack/include/unwindstack/DexFiles.h
@@ -0,0 +1,79 @@
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,8 +78,6 @@ class Elf {
7878
7979 bool IsValidPc(uint64_t pc);
8080
81- bool GetTextRange(uint64_t* addr, uint64_t* size);
82-
8381 void GetLastError(ErrorData* data);
8482 ErrorCode GetLastErrorCode();
8583 uint64_t GetLastErrorAddress();
--- a/libunwindstack/include/unwindstack/ElfInterface.h
+++ b/libunwindstack/include/unwindstack/ElfInterface.h
@@ -68,8 +68,6 @@ class ElfInterface {
6868
6969 virtual bool IsValidPc(uint64_t pc);
7070
71- bool GetTextRange(uint64_t* addr, uint64_t* size);
72-
7371 Memory* CreateGnuDebugdataMemory();
7472
7573 Memory* memory() { return memory_; }
@@ -158,9 +156,6 @@ class ElfInterface {
158156 uint64_t gnu_build_id_offset_ = 0;
159157 uint64_t gnu_build_id_size_ = 0;
160158
161- uint64_t text_addr_ = 0;
162- uint64_t text_size_ = 0;
163-
164159 uint8_t soname_type_ = SONAME_UNKNOWN;
165160 std::string soname_;
166161
--- a/libunwindstack/include/unwindstack/JitDebug.h
+++ b/libunwindstack/include/unwindstack/JitDebug.h
@@ -19,7 +19,6 @@
1919
2020 #include <stdint.h>
2121
22-#include <map>
2322 #include <memory>
2423 #include <mutex>
2524 #include <string>
@@ -31,24 +30,40 @@
3130 namespace unwindstack {
3231
3332 // Forward declarations.
33+class Elf;
3434 class Maps;
3535 enum ArchEnum : uint8_t;
3636
37-template <typename Symfile>
38-class JitDebug {
37+class JitDebug : public Global {
3938 public:
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- }
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_;
5267 };
5368
5469 } // namespace unwindstack
--- a/libunwindstack/include/unwindstack/Unwinder.h
+++ b/libunwindstack/include/unwindstack/Unwinder.h
@@ -24,6 +24,7 @@
2424 #include <string>
2525 #include <vector>
2626
27+#include <unwindstack/DexFiles.h>
2728 #include <unwindstack/Error.h>
2829 #include <unwindstack/JitDebug.h>
2930 #include <unwindstack/Maps.h>
@@ -33,7 +34,6 @@
3334 namespace unwindstack {
3435
3536 // 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);
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+ }
6770 Unwinder(size_t max_frames, Maps* maps, std::shared_ptr<Memory> process_memory)
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;
71+ : max_frames_(max_frames), maps_(maps), process_memory_(process_memory) {
72+ frames_.reserve(max_frames);
73+ }
7474
7575 virtual ~Unwinder() = default;
7676
@@ -90,7 +90,9 @@ class Unwinder {
9090 std::string FormatFrame(size_t frame_num);
9191 std::string FormatFrame(const FrameData& frame);
9292
93- void SetRegs(Regs* regs);
93+ void SetJitDebug(JitDebug* jit_debug, ArchEnum arch);
94+
95+ void SetRegs(Regs* regs) { regs_ = regs; }
9496 Maps* GetMaps() { return maps_; }
9597 std::shared_ptr<Memory>& GetProcessMemory() { return process_memory_; }
9698
@@ -105,6 +107,10 @@ class Unwinder {
105107
106108 void SetDisplayBuildID(bool display_build_id) { display_build_id_ = display_build_id; }
107109
110+#if !defined(NO_LIBDEXFILE_SUPPORT)
111+ void SetDexFiles(DexFiles* dex_files, ArchEnum arch);
112+#endif
113+
108114 ErrorCode LastErrorCode() { return last_error_.code; }
109115 uint64_t LastErrorAddress() { return last_error_.address; }
110116
@@ -120,9 +126,9 @@ class Unwinder {
120126 Regs* regs_;
121127 std::vector<FrameData> frames_;
122128 std::shared_ptr<Memory> process_memory_;
123- std::unique_ptr<JitDebug<Elf>> jit_debug_;
129+ JitDebug* jit_debug_ = nullptr;
124130 #if !defined(NO_LIBDEXFILE_SUPPORT)
125- std::unique_ptr<JitDebug<DexFile>> dex_files_;
131+ DexFiles* dex_files_ = nullptr;
126132 #endif
127133 bool resolve_names_ = true;
128134 bool embedded_soname_ = true;
@@ -135,11 +141,15 @@ class UnwinderFromPid : public Unwinder {
135141 UnwinderFromPid(size_t max_frames, pid_t pid) : Unwinder(max_frames), pid_(pid) {}
136142 virtual ~UnwinderFromPid() = default;
137143
138- bool Init();
144+ bool Init(ArchEnum arch);
139145
140146 private:
141147 pid_t pid_;
142148 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
143153 };
144154
145155 } // 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->GetFunctionName(0x4102, &method, &method_offset));
180+ ASSERT_TRUE(dex_file->GetMethodInformation(0x102, &method, &method_offset));
181181 EXPECT_EQ("Main.<init>", method);
182182 EXPECT_EQ(2U, method_offset);
183183
184- ASSERT_TRUE(dex_file->GetFunctionName(0x4118, &method, &method_offset));
184+ ASSERT_TRUE(dex_file->GetMethodInformation(0x118, &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->GetFunctionName(0x100000, &method, &method_offset));
198+ EXPECT_FALSE(dex_file->GetMethodInformation(0x100000, &method, &method_offset));
199199
200- EXPECT_FALSE(dex_file->GetFunctionName(0x98, &method, &method_offset));
200+ EXPECT_FALSE(dex_file->GetMethodInformation(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>
2526 #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,10 +32,6 @@
3232 #include "ElfFake.h"
3333 #include "MemoryFake.h"
3434
35-#if !defined(NO_LIBDEXFILE_SUPPORT)
36-#include <DexFile.h>
37-#endif
38-
3935 namespace unwindstack {
4036
4137 class DexFilesTest : public ::testing::Test {
@@ -52,7 +48,8 @@ class DexFilesTest : public ::testing::Test {
5248 }
5349
5450 void Init(ArchEnum arch) {
55- dex_files_ = JitDebug<DexFile>::Create(arch, process_memory_);
51+ dex_files_.reset(new DexFiles(process_memory_));
52+ dex_files_->SetArch(arch);
5653
5754 maps_.reset(
5855 new BufferMaps("1000-4000 ---s 00000000 00:00 0 /fake/elf\n"
@@ -89,11 +86,10 @@ class DexFilesTest : public ::testing::Test {
8986 Init(ARCH_ARM);
9087 }
9188
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);
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);
9793 void WriteDex(uint64_t dex_file);
9894
9995 static constexpr size_t kMapGlobalNonReadable = 2;
@@ -105,70 +101,40 @@ class DexFilesTest : public ::testing::Test {
105101
106102 std::shared_ptr<Memory> process_memory_;
107103 MemoryFake* memory_;
108- std::unique_ptr<JitDebug<DexFile>> dex_files_;
104+ std::unique_ptr<DexFiles> dex_files_;
109105 std::unique_ptr<BufferMaps> maps_;
110106 };
111107
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);
108+void DexFilesTest::WriteDescriptor32(uint64_t addr, uint32_t head) {
109+ // void* first_entry_
110+ memory_->SetData32(addr + 12, head);
134111 }
135112
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));
113+void DexFilesTest::WriteDescriptor64(uint64_t addr, uint64_t head) {
114+ // void* first_entry_
115+ memory_->SetData64(addr + 16, head);
146116 }
147117
148-void DexFilesTest::WriteEntry32Pad(uint64_t addr, uint32_t next, uint32_t prev, uint32_t dex) {
149- // Format of the 32 bit JITCodeEntry structure:
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:
150121 // uint32_t next
151- memory_->SetData32(addr, next);
122+ memory_->SetData32(entry_addr, next);
152123 // uint32_t prev
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));
124+ memory_->SetData32(entry_addr + 4, prev);
125+ // uint32_t dex_file
126+ memory_->SetData32(entry_addr + 8, dex_file);
160127 }
161128
162-void DexFilesTest::WriteEntry64(uint64_t addr, uint64_t next, uint64_t prev, uint64_t dex) {
163- // Format of the 64 bit JITCodeEntry structure:
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:
164132 // uint64_t next
165- memory_->SetData64(addr, next);
133+ memory_->SetData64(entry_addr, next);
166134 // uint64_t prev
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));
135+ memory_->SetData64(entry_addr + 8, prev);
136+ // uint64_t dex_file
137+ memory_->SetData64(entry_addr + 16, dex_file);
172138 }
173139
174140 void DexFilesTest::WriteDex(uint64_t dex_file) {
@@ -178,8 +144,9 @@ void DexFilesTest::WriteDex(uint64_t dex_file) {
178144 TEST_F(DexFilesTest, get_method_information_invalid) {
179145 std::string method_name = "nothing";
180146 uint64_t method_offset = 0x124;
147+ MapInfo* info = maps_->Get(kMapDexFileEntries);
181148
182- dex_files_->GetFunctionName(maps_.get(), 0, &method_name, &method_offset);
149+ dex_files_->GetMethodInformation(maps_.get(), info, 0, &method_name, &method_offset);
183150 EXPECT_EQ("nothing", method_name);
184151 EXPECT_EQ(0x124U, method_offset);
185152 }
@@ -187,12 +154,13 @@ TEST_F(DexFilesTest, get_method_information_invalid) {
187154 TEST_F(DexFilesTest, get_method_information_32) {
188155 std::string method_name = "nothing";
189156 uint64_t method_offset = 0x124;
157+ MapInfo* info = maps_->Get(kMapDexFiles);
190158
191159 WriteDescriptor32(0xf800, 0x200000);
192- WriteEntry32Pad(0x200000, 0, 0, 0x300000);
160+ WriteEntry32(0x200000, 0, 0, 0x300000);
193161 WriteDex(0x300000);
194162
195- dex_files_->GetFunctionName(maps_.get(), 0x300100, &method_name, &method_offset);
163+ dex_files_->GetMethodInformation(maps_.get(), info, 0x300100, &method_name, &method_offset);
196164 EXPECT_EQ("Main.<init>", method_name);
197165 EXPECT_EQ(0U, method_offset);
198166 }
@@ -202,12 +170,13 @@ TEST_F(DexFilesTest, get_method_information_64) {
202170
203171 std::string method_name = "nothing";
204172 uint64_t method_offset = 0x124;
173+ MapInfo* info = maps_->Get(kMapDexFiles);
205174
206175 WriteDescriptor64(0xf800, 0x200000);
207176 WriteEntry64(0x200000, 0, 0, 0x301000);
208177 WriteDex(0x301000);
209178
210- dex_files_->GetFunctionName(maps_.get(), 0x301102, &method_name, &method_offset);
179+ dex_files_->GetMethodInformation(maps_.get(), info, 0x301102, &method_name, &method_offset);
211180 EXPECT_EQ("Main.<init>", method_name);
212181 EXPECT_EQ(2U, method_offset);
213182 }
@@ -215,14 +184,14 @@ TEST_F(DexFilesTest, get_method_information_64) {
215184 TEST_F(DexFilesTest, get_method_information_not_first_entry_32) {
216185 std::string method_name = "nothing";
217186 uint64_t method_offset = 0x124;
187+ MapInfo* info = maps_->Get(kMapDexFiles);
218188
219189 WriteDescriptor32(0xf800, 0x200000);
220- WriteEntry32Pad(0x200000, 0x200100, 0, 0x100000);
221- WriteDex(0x100000);
222- WriteEntry32Pad(0x200100, 0, 0x200000, 0x300000);
190+ WriteEntry32(0x200000, 0x200100, 0, 0x100000);
191+ WriteEntry32(0x200100, 0, 0x200000, 0x300000);
223192 WriteDex(0x300000);
224193
225- dex_files_->GetFunctionName(maps_.get(), 0x300104, &method_name, &method_offset);
194+ dex_files_->GetMethodInformation(maps_.get(), info, 0x300104, &method_name, &method_offset);
226195 EXPECT_EQ("Main.<init>", method_name);
227196 EXPECT_EQ(4U, method_offset);
228197 }
@@ -232,14 +201,14 @@ TEST_F(DexFilesTest, get_method_information_not_first_entry_64) {
232201
233202 std::string method_name = "nothing";
234203 uint64_t method_offset = 0x124;
204+ MapInfo* info = maps_->Get(kMapDexFiles);
235205
236206 WriteDescriptor64(0xf800, 0x200000);
237207 WriteEntry64(0x200000, 0x200100, 0, 0x100000);
238- WriteDex(0x100000);
239208 WriteEntry64(0x200100, 0, 0x200000, 0x300000);
240209 WriteDex(0x300000);
241210
242- dex_files_->GetFunctionName(maps_.get(), 0x300106, &method_name, &method_offset);
211+ dex_files_->GetMethodInformation(maps_.get(), info, 0x300106, &method_name, &method_offset);
243212 EXPECT_EQ("Main.<init>", method_name);
244213 EXPECT_EQ(6U, method_offset);
245214 }
@@ -247,18 +216,19 @@ TEST_F(DexFilesTest, get_method_information_not_first_entry_64) {
247216 TEST_F(DexFilesTest, get_method_information_cached) {
248217 std::string method_name = "nothing";
249218 uint64_t method_offset = 0x124;
219+ MapInfo* info = maps_->Get(kMapDexFiles);
250220
251221 WriteDescriptor32(0xf800, 0x200000);
252- WriteEntry32Pad(0x200000, 0, 0, 0x300000);
222+ WriteEntry32(0x200000, 0, 0, 0x300000);
253223 WriteDex(0x300000);
254224
255- dex_files_->GetFunctionName(maps_.get(), 0x300100, &method_name, &method_offset);
225+ dex_files_->GetMethodInformation(maps_.get(), info, 0x300100, &method_name, &method_offset);
256226 EXPECT_EQ("Main.<init>", method_name);
257227 EXPECT_EQ(0U, method_offset);
258228
259229 // Clear all memory and make sure that data is acquired from the cache.
260230 memory_->Clear();
261- dex_files_->GetFunctionName(maps_.get(), 0x300100, &method_name, &method_offset);
231+ dex_files_->GetMethodInformation(maps_.get(), info, 0x300100, &method_name, &method_offset);
262232 EXPECT_EQ("Main.<init>", method_name);
263233 EXPECT_EQ(0U, method_offset);
264234 }
@@ -266,24 +236,26 @@ TEST_F(DexFilesTest, get_method_information_cached) {
266236 TEST_F(DexFilesTest, get_method_information_search_libs) {
267237 std::string method_name = "nothing";
268238 uint64_t method_offset = 0x124;
239+ MapInfo* info = maps_->Get(kMapDexFiles);
269240
270241 WriteDescriptor32(0xf800, 0x200000);
271- WriteEntry32Pad(0x200000, 0x200100, 0, 0x100000);
272- WriteDex(0x100000);
273- WriteEntry32Pad(0x200100, 0, 0x200000, 0x300000);
242+ WriteEntry32(0x200000, 0x200100, 0, 0x100000);
243+ WriteEntry32(0x200100, 0, 0x200000, 0x300000);
274244 WriteDex(0x300000);
275245
276246 // Only search a given named list of libs.
277247 std::vector<std::string> libs{"libart.so"};
278- dex_files_ = JitDebug<DexFile>::Create(ARCH_ARM, process_memory_, libs);
248+ dex_files_.reset(new DexFiles(process_memory_, libs));
249+ dex_files_->SetArch(ARCH_ARM);
279250
280- dex_files_->GetFunctionName(maps_.get(), 0x300104, &method_name, &method_offset);
251+ dex_files_->GetMethodInformation(maps_.get(), info, 0x300104, &method_name, &method_offset);
281252 EXPECT_EQ("nothing", method_name);
282253 EXPECT_EQ(0x124U, method_offset);
283254
284255 MapInfo* map_info = maps_->Get(kMapGlobal);
285256 map_info->name = "/system/lib/libart.so";
286- dex_files_ = JitDebug<DexFile>::Create(ARCH_ARM, process_memory_, libs);
257+ dex_files_.reset(new DexFiles(process_memory_, libs));
258+ dex_files_->SetArch(ARCH_ARM);
287259 // Set the rw map to the same name or this will not scan this entry.
288260 map_info = maps_->Get(kMapGlobalRw);
289261 map_info->name = "/system/lib/libart.so";
@@ -291,7 +263,7 @@ TEST_F(DexFilesTest, get_method_information_search_libs) {
291263 // DexFiles object.
292264 libs.clear();
293265
294- dex_files_->GetFunctionName(maps_.get(), 0x300104, &method_name, &method_offset);
266+ dex_files_->GetMethodInformation(maps_.get(), info, 0x300104, &method_name, &method_offset);
295267 EXPECT_EQ("Main.<init>", method_name);
296268 EXPECT_EQ(4U, method_offset);
297269 }
@@ -299,24 +271,26 @@ TEST_F(DexFilesTest, get_method_information_search_libs) {
299271 TEST_F(DexFilesTest, get_method_information_global_skip_zero_32) {
300272 std::string method_name = "nothing";
301273 uint64_t method_offset = 0x124;
274+ MapInfo* info = maps_->Get(kMapDexFiles);
302275
303276 // First global variable found, but value is zero.
304277 WriteDescriptor32(0xa800, 0);
305278
306279 WriteDescriptor32(0xf800, 0x200000);
307- WriteEntry32Pad(0x200000, 0, 0, 0x300000);
280+ WriteEntry32(0x200000, 0, 0, 0x300000);
308281 WriteDex(0x300000);
309282
310- dex_files_->GetFunctionName(maps_.get(), 0x300100, &method_name, &method_offset);
283+ dex_files_->GetMethodInformation(maps_.get(), info, 0x300100, &method_name, &method_offset);
311284 EXPECT_EQ("Main.<init>", method_name);
312285 EXPECT_EQ(0U, method_offset);
313286
314287 // Verify that second is ignored when first is set to non-zero
315- dex_files_ = JitDebug<DexFile>::Create(ARCH_ARM, process_memory_);
288+ dex_files_.reset(new DexFiles(process_memory_));
289+ dex_files_->SetArch(ARCH_ARM);
316290 method_name = "fail";
317291 method_offset = 0x123;
318292 WriteDescriptor32(0xa800, 0x100000);
319- dex_files_->GetFunctionName(maps_.get(), 0x300100, &method_name, &method_offset);
293+ dex_files_->GetMethodInformation(maps_.get(), info, 0x300100, &method_name, &method_offset);
320294 EXPECT_EQ("fail", method_name);
321295 EXPECT_EQ(0x123U, method_offset);
322296 }
@@ -326,6 +300,7 @@ TEST_F(DexFilesTest, get_method_information_global_skip_zero_64) {
326300
327301 std::string method_name = "nothing";
328302 uint64_t method_offset = 0x124;
303+ MapInfo* info = maps_->Get(kMapDexFiles);
329304
330305 // First global variable found, but value is zero.
331306 WriteDescriptor64(0xa800, 0);
@@ -334,16 +309,17 @@ TEST_F(DexFilesTest, get_method_information_global_skip_zero_64) {
334309 WriteEntry64(0x200000, 0, 0, 0x300000);
335310 WriteDex(0x300000);
336311
337- dex_files_->GetFunctionName(maps_.get(), 0x300100, &method_name, &method_offset);
312+ dex_files_->GetMethodInformation(maps_.get(), info, 0x300100, &method_name, &method_offset);
338313 EXPECT_EQ("Main.<init>", method_name);
339314 EXPECT_EQ(0U, method_offset);
340315
341316 // Verify that second is ignored when first is set to non-zero
342- dex_files_ = JitDebug<DexFile>::Create(ARCH_ARM64, process_memory_);
317+ dex_files_.reset(new DexFiles(process_memory_));
318+ dex_files_->SetArch(ARCH_ARM64);
343319 method_name = "fail";
344320 method_offset = 0x123;
345321 WriteDescriptor64(0xa800, 0x100000);
346- dex_files_->GetFunctionName(maps_.get(), 0x300100, &method_name, &method_offset);
322+ dex_files_->GetMethodInformation(maps_.get(), info, 0x300100, &method_name, &method_offset);
347323 EXPECT_EQ("fail", method_name);
348324 EXPECT_EQ(0x123U, method_offset);
349325 }
--- a/libunwindstack/tests/JitDebugTest.cpp
+++ b/libunwindstack/tests/JitDebugTest.cpp
@@ -46,7 +46,8 @@ class JitDebugTest : public ::testing::Test {
4646 }
4747
4848 void Init(ArchEnum arch) {
49- jit_debug_ = JitDebug<Elf>::Create(arch, process_memory_);
49+ jit_debug_.reset(new JitDebug(process_memory_));
50+ jit_debug_->SetArch(arch);
5051
5152 maps_.reset(
5253 new BufferMaps("1000-4000 ---s 00000000 00:00 0 /fake/elf1\n"
@@ -61,12 +62,6 @@ class JitDebugTest : public ::testing::Test {
6162 "200000-210000 rw-p 0002000 00:00 0 /fake/elf4\n"));
6263 ASSERT_TRUE(maps_->Parse());
6364
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-
7065 MapInfo* map_info = maps_->Get(3);
7166 ASSERT_TRUE(map_info != nullptr);
7267 CreateFakeElf(map_info);
@@ -99,7 +94,7 @@ class JitDebugTest : public ::testing::Test {
9994 ehdr.e_shstrndx = 1;
10095 ehdr.e_shoff = sh_offset;
10196 ehdr.e_shentsize = sizeof(ShdrType);
102- ehdr.e_shnum = 4;
97+ ehdr.e_shnum = 3;
10398 memory_->SetMemory(offset, &ehdr, sizeof(ehdr));
10499
105100 ShdrType shdr;
@@ -115,7 +110,6 @@ class JitDebugTest : public ::testing::Test {
115110 shdr.sh_size = 0x100;
116111 memory_->SetMemory(offset + sh_offset, &shdr, sizeof(shdr));
117112 memory_->SetMemory(offset + 0x500, ".debug_frame");
118- memory_->SetMemory(offset + 0x550, ".text");
119113
120114 sh_offset += sizeof(shdr);
121115 memset(&shdr, 0, sizeof(shdr));
@@ -126,15 +120,6 @@ class JitDebugTest : public ::testing::Test {
126120 shdr.sh_size = 0x200;
127121 memory_->SetMemory(offset + sh_offset, &shdr, sizeof(shdr));
128122
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-
138123 // Now add a single cie/fde.
139124 uint64_t dwarf_offset = offset + 0x600;
140125 if (class_type == ELFCLASS32) {
@@ -183,7 +168,7 @@ class JitDebugTest : public ::testing::Test {
183168
184169 std::shared_ptr<Memory> process_memory_;
185170 MemoryFake* memory_;
186- std::unique_ptr<JitDebug<Elf>> jit_debug_;
171+ std::unique_ptr<JitDebug> jit_debug_;
187172 std::unique_ptr<BufferMaps> maps_;
188173 };
189174
@@ -253,20 +238,20 @@ void JitDebugTest::WriteEntry64(uint64_t addr, uint64_t prev, uint64_t next, uin
253238 }
254239
255240 TEST_F(JitDebugTest, get_elf_invalid) {
256- Elf* elf = jit_debug_->Get(maps_.get(), 0x1500);
241+ Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500);
257242 ASSERT_TRUE(elf == nullptr);
258243 }
259244
260245 TEST_F(JitDebugTest, get_elf_no_global_variable) {
261246 maps_.reset(new BufferMaps(""));
262- Elf* elf = jit_debug_->Get(maps_.get(), 0x1500);
247+ Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500);
263248 ASSERT_TRUE(elf == nullptr);
264249 }
265250
266251 TEST_F(JitDebugTest, get_elf_no_valid_descriptor_in_memory) {
267252 CreateElf<Elf32_Ehdr, Elf32_Shdr>(0x4000, ELFCLASS32, EM_ARM, 0x1500, 0x200);
268253
269- Elf* elf = jit_debug_->Get(maps_.get(), 0x1500);
254+ Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500);
270255 ASSERT_TRUE(elf == nullptr);
271256 }
272257
@@ -275,7 +260,7 @@ TEST_F(JitDebugTest, get_elf_no_valid_code_entry) {
275260
276261 WriteDescriptor32(0xf800, 0x200000);
277262
278- Elf* elf = jit_debug_->Get(maps_.get(), 0x1500);
263+ Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500);
279264 ASSERT_TRUE(elf == nullptr);
280265 }
281266
@@ -284,7 +269,7 @@ TEST_F(JitDebugTest, get_elf_invalid_descriptor_first_entry) {
284269
285270 WriteDescriptor32(0xf800, 0);
286271
287- Elf* elf = jit_debug_->Get(maps_.get(), 0x1500);
272+ Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500);
288273 ASSERT_TRUE(elf == nullptr);
289274 }
290275
@@ -295,7 +280,7 @@ TEST_F(JitDebugTest, get_elf_invalid_descriptor_version) {
295280 // Set the version to an invalid value.
296281 memory_->SetData32(0xf800, 2);
297282
298- Elf* elf = jit_debug_->Get(maps_.get(), 0x1500);
283+ Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500);
299284 ASSERT_TRUE(elf == nullptr);
300285 }
301286
@@ -305,18 +290,12 @@ TEST_F(JitDebugTest, get_elf_32) {
305290 WriteDescriptor32(0xf800, 0x200000);
306291 WriteEntry32Pad(0x200000, 0, 0, 0x4000, 0x1000);
307292
308- Elf* elf = jit_debug_->Get(maps_.get(), 0x1500);
293+ Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500);
309294 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);
315295
316296 // Clear the memory and verify all of the data is cached.
317297 memory_->Clear();
318- WriteDescriptor32(0xf800, 0x200000);
319- Elf* elf2 = jit_debug_->Get(maps_.get(), 0x1500);
298+ Elf* elf2 = jit_debug_->GetElf(maps_.get(), 0x1500);
320299 ASSERT_TRUE(elf2 != nullptr);
321300 EXPECT_EQ(elf, elf2);
322301 }
@@ -330,15 +309,16 @@ TEST_F(JitDebugTest, get_multiple_jit_debug_descriptors_valid) {
330309 WriteDescriptor32(0x12800, 0x201000);
331310 WriteEntry32Pad(0x201000, 0, 0, 0x5000, 0x1000);
332311
333- ASSERT_TRUE(jit_debug_->Get(maps_.get(), 0x1500) != nullptr);
334- ASSERT_TRUE(jit_debug_->Get(maps_.get(), 0x2000) == nullptr);
312+ ASSERT_TRUE(jit_debug_->GetElf(maps_.get(), 0x1500) != nullptr);
313+ ASSERT_TRUE(jit_debug_->GetElf(maps_.get(), 0x2000) == nullptr);
335314
336315 // Now clear the descriptor entry for the first one.
337316 WriteDescriptor32(0xf800, 0);
338- jit_debug_ = JitDebug<Elf>::Create(ARCH_ARM, process_memory_);
317+ jit_debug_.reset(new JitDebug(process_memory_));
318+ jit_debug_->SetArch(ARCH_ARM);
339319
340- ASSERT_TRUE(jit_debug_->Get(maps_.get(), 0x1500) == nullptr);
341- ASSERT_TRUE(jit_debug_->Get(maps_.get(), 0x2000) != nullptr);
320+ ASSERT_TRUE(jit_debug_->GetElf(maps_.get(), 0x1500) == nullptr);
321+ ASSERT_TRUE(jit_debug_->GetElf(maps_.get(), 0x2000) != nullptr);
342322 }
343323
344324 TEST_F(JitDebugTest, get_elf_x86) {
@@ -349,14 +329,13 @@ TEST_F(JitDebugTest, get_elf_x86) {
349329 WriteDescriptor32(0xf800, 0x200000);
350330 WriteEntry32Pack(0x200000, 0, 0, 0x4000, 0x1000);
351331
352- jit_debug_ = JitDebug<Elf>::Create(ARCH_X86, process_memory_);
353- Elf* elf = jit_debug_->Get(maps_.get(), 0x1500);
332+ jit_debug_->SetArch(ARCH_X86);
333+ Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500);
354334 ASSERT_TRUE(elf != nullptr);
355335
356336 // Clear the memory and verify all of the data is cached.
357337 memory_->Clear();
358- WriteDescriptor32(0xf800, 0x200000);
359- Elf* elf2 = jit_debug_->Get(maps_.get(), 0x1500);
338+ Elf* elf2 = jit_debug_->GetElf(maps_.get(), 0x1500);
360339 ASSERT_TRUE(elf2 != nullptr);
361340 EXPECT_EQ(elf, elf2);
362341 }
@@ -369,13 +348,12 @@ TEST_F(JitDebugTest, get_elf_64) {
369348 WriteDescriptor64(0xf800, 0x200000);
370349 WriteEntry64(0x200000, 0, 0, 0x4000, 0x1000);
371350
372- Elf* elf = jit_debug_->Get(maps_.get(), 0x1500);
351+ Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500);
373352 ASSERT_TRUE(elf != nullptr);
374353
375354 // Clear the memory and verify all of the data is cached.
376355 memory_->Clear();
377- WriteDescriptor64(0xf800, 0x200000);
378- Elf* elf2 = jit_debug_->Get(maps_.get(), 0x1500);
356+ Elf* elf2 = jit_debug_->GetElf(maps_.get(), 0x1500);
379357 ASSERT_TRUE(elf2 != nullptr);
380358 EXPECT_EQ(elf, elf2);
381359 }
@@ -388,21 +366,20 @@ TEST_F(JitDebugTest, get_elf_multiple_entries) {
388366 WriteEntry32Pad(0x200000, 0, 0x200100, 0x4000, 0x1000);
389367 WriteEntry32Pad(0x200100, 0x200100, 0, 0x5000, 0x1000);
390368
391- Elf* elf_2 = jit_debug_->Get(maps_.get(), 0x2400);
369+ Elf* elf_2 = jit_debug_->GetElf(maps_.get(), 0x2400);
392370 ASSERT_TRUE(elf_2 != nullptr);
393371
394- Elf* elf_1 = jit_debug_->Get(maps_.get(), 0x1600);
372+ Elf* elf_1 = jit_debug_->GetElf(maps_.get(), 0x1600);
395373 ASSERT_TRUE(elf_1 != nullptr);
396374
397375 // Clear the memory and verify all of the data is cached.
398376 memory_->Clear();
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));
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));
406383 }
407384
408385 TEST_F(JitDebugTest, get_elf_search_libs) {
@@ -413,19 +390,21 @@ TEST_F(JitDebugTest, get_elf_search_libs) {
413390
414391 // Only search a given named list of libs.
415392 std::vector<std::string> libs{"libart.so"};
416- jit_debug_ = JitDebug<Elf>::Create(ARCH_ARM, process_memory_, libs);
417- EXPECT_TRUE(jit_debug_->Get(maps_.get(), 0x1500) == nullptr);
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);
418396
419397 // Change the name of the map that includes the value and verify this works.
420398 MapInfo* map_info = maps_->Get(5);
421399 map_info->name = "/system/lib/libart.so";
422400 map_info = maps_->Get(6);
423401 map_info->name = "/system/lib/libart.so";
424- jit_debug_ = JitDebug<Elf>::Create(ARCH_ARM, process_memory_);
402+ jit_debug_.reset(new JitDebug(process_memory_, libs));
425403 // Make sure that clearing our copy of the libs doesn't affect the
426404 // JitDebug object.
427405 libs.clear();
428- EXPECT_TRUE(jit_debug_->Get(maps_.get(), 0x1500) != nullptr);
406+ jit_debug_->SetArch(ARCH_ARM);
407+ EXPECT_TRUE(jit_debug_->GetElf(maps_.get(), 0x1500) != nullptr);
429408 }
430409
431410 } // namespace unwindstack
--- a/libunwindstack/tests/UnwindOfflineTest.cpp
+++ b/libunwindstack/tests/UnwindOfflineTest.cpp
@@ -307,7 +307,9 @@ TEST_F(UnwindOfflineTest, jit_debug_x86) {
307307 }
308308 process_memory_.reset(memory);
309309
310+ JitDebug jit_debug(process_memory_);
310311 Unwinder unwinder(128, maps_.get(), regs_.get(), process_memory_);
312+ unwinder.SetJitDebug(&jit_debug, regs_->Arch());
311313 unwinder.Unwind();
312314
313315 std::string frame_info(DumpFrames(unwinder));
@@ -607,7 +609,9 @@ TEST_F(UnwindOfflineTest, jit_debug_arm) {
607609 }
608610 process_memory_.reset(memory);
609611
612+ JitDebug jit_debug(process_memory_);
610613 Unwinder unwinder(128, maps_.get(), regs_.get(), process_memory_);
614+ unwinder.SetJitDebug(&jit_debug, regs_->Arch());
611615 unwinder.Unwind();
612616
613617 std::string frame_info(DumpFrames(unwinder));
@@ -928,7 +932,9 @@ static void OfflineUnwind(void* data) {
928932 LeakType* leak_data = reinterpret_cast<LeakType*>(data);
929933
930934 std::unique_ptr<Regs> regs_copy(leak_data->regs->Clone());
935+ JitDebug jit_debug(leak_data->process_memory);
931936 Unwinder unwinder(128, leak_data->maps, regs_copy.get(), leak_data->process_memory);
937+ unwinder.SetJitDebug(&jit_debug, regs_copy->Arch());
932938 unwinder.Unwind();
933939 ASSERT_EQ(76U, unwinder.NumFrames());
934940 }
@@ -1049,7 +1055,9 @@ TEST_F(UnwindOfflineTest, art_quick_osr_stub_arm) {
10491055 }
10501056 process_memory_.reset(memory);
10511057
1058+ JitDebug jit_debug(process_memory_);
10521059 Unwinder unwinder(128, maps_.get(), regs_.get(), process_memory_);
1060+ unwinder.SetJitDebug(&jit_debug, regs_->Arch());
10531061 unwinder.Unwind();
10541062
10551063 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());
173+ ASSERT_TRUE(unwinder_from_pid->Init(regs->Arch()));
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());
286+ ASSERT_TRUE(unwinder.Init(regs->Arch()));
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());
338+ ASSERT_TRUE(unwinder.Init(regs->Arch()));
339339 unwinder.SetRegs(regs.get());
340340
341341 VerifyUnwind(&unwinder, kFunctionOrder);
--- a/libunwindstack/tools/unwind.cpp
+++ b/libunwindstack/tools/unwind.cpp
@@ -26,6 +26,7 @@
2626 #include <sys/types.h>
2727 #include <unistd.h>
2828
29+#include <unwindstack/DexFiles.h>
2930 #include <unwindstack/Elf.h>
3031 #include <unwindstack/JitDebug.h>
3132 #include <unwindstack/Maps.h>
@@ -89,7 +90,7 @@ void DoUnwind(pid_t pid) {
8990 printf("\n");
9091
9192 unwindstack::UnwinderFromPid unwinder(1024, pid);
92- if (!unwinder.Init()) {
93+ if (!unwinder.Init(regs->Arch())) {
9394 printf("Failed to init unwinder object.\n");
9495 return;
9596 }
--- 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()) {
251+ if (!unwinder.Init(regs->Arch())) {
252252 printf("Unable to init unwinder object.\n");
253253 return 1;
254254 }