Merge "Adjust DEX file reading to follow layout changes in ART." am: 8fbdbba9f5
am: 1f2daf1b79
Change-Id: I25c5d81c5803b920f7e4d68cc6aebe023b439ea6
diff --git a/libunwindstack/DexFiles.cpp b/libunwindstack/DexFiles.cpp
index c5f8138..430f6c5 100644
--- a/libunwindstack/DexFiles.cpp
+++ b/libunwindstack/DexFiles.cpp
@@ -77,7 +77,8 @@
uint64_t DexFiles::ReadEntryPtr32(uint64_t addr) {
uint32_t entry;
- if (!memory_->ReadFully(addr, &entry, sizeof(entry))) {
+ const uint32_t field_offset = 12; // offset of first_entry_ in the descriptor struct.
+ if (!memory_->ReadFully(addr + field_offset, &entry, sizeof(entry))) {
return 0;
}
return entry;
@@ -85,7 +86,8 @@
uint64_t DexFiles::ReadEntryPtr64(uint64_t addr) {
uint64_t entry;
- if (!memory_->ReadFully(addr, &entry, sizeof(entry))) {
+ const uint32_t field_offset = 16; // offset of first_entry_ in the descriptor struct.
+ if (!memory_->ReadFully(addr + field_offset, &entry, sizeof(entry))) {
return 0;
}
return entry;
@@ -122,7 +124,7 @@
initialized_ = true;
entry_addr_ = 0;
- const std::string dex_debug_name("__art_debug_dexfiles");
+ const std::string dex_debug_name("__dex_debug_descriptor");
for (MapInfo* info : *maps) {
if (!(info->flags & PROT_EXEC) || !(info->flags & PROT_READ) || info->offset != 0) {
continue;
diff --git a/libunwindstack/tests/DexFilesTest.cpp b/libunwindstack/tests/DexFilesTest.cpp
index dca5605..d029bb0 100644
--- a/libunwindstack/tests/DexFilesTest.cpp
+++ b/libunwindstack/tests/DexFilesTest.cpp
@@ -63,7 +63,7 @@
elf->FakeSetValid(true);
ElfInterfaceFake* interface = new ElfInterfaceFake(memory);
elf->FakeSetInterface(interface);
- interface->FakeSetGlobalVariable("__art_debug_dexfiles", 0x800);
+ interface->FakeSetGlobalVariable("__dex_debug_descriptor", 0x800);
map_info->elf.reset(elf);
// Global variable not set by default.
@@ -74,7 +74,7 @@
elf->FakeSetValid(true);
interface = new ElfInterfaceFake(memory);
elf->FakeSetInterface(interface);
- interface->FakeSetGlobalVariable("__art_debug_dexfiles", 0x800);
+ interface->FakeSetGlobalVariable("__dex_debug_descriptor", 0x800);
map_info->elf.reset(elf);
// Global variable set in this map.
@@ -85,10 +85,12 @@
elf->FakeSetValid(true);
interface = new ElfInterfaceFake(memory);
elf->FakeSetInterface(interface);
- interface->FakeSetGlobalVariable("__art_debug_dexfiles", 0x800);
+ interface->FakeSetGlobalVariable("__dex_debug_descriptor", 0x800);
map_info->elf.reset(elf);
}
+ void WriteDescriptor32(uint64_t addr, uint32_t head);
+ void WriteDescriptor64(uint64_t addr, uint64_t head);
void WriteEntry32(uint64_t entry_addr, uint32_t next, uint32_t prev, uint32_t dex_file);
void WriteEntry64(uint64_t entry_addr, uint64_t next, uint64_t prev, uint64_t dex_file);
void WriteDex(uint64_t dex_file);
@@ -105,6 +107,16 @@
std::unique_ptr<BufferMaps> maps_;
};
+void DexFilesTest::WriteDescriptor32(uint64_t addr, uint32_t head) {
+ // void* first_entry_
+ memory_->SetData32(addr + 12, head);
+}
+
+void DexFilesTest::WriteDescriptor64(uint64_t addr, uint64_t head) {
+ // void* first_entry_
+ memory_->SetData64(addr + 16, head);
+}
+
void DexFilesTest::WriteEntry32(uint64_t entry_addr, uint32_t next, uint32_t prev,
uint32_t dex_file) {
// Format of the 32 bit DEXFileEntry structure:
@@ -146,7 +158,7 @@
uint64_t method_offset = 0x124;
MapInfo* info = maps_->Get(kMapDexFiles);
- memory_->SetData32(0xf800, 0x200000);
+ WriteDescriptor32(0xf800, 0x200000);
WriteEntry32(0x200000, 0, 0, 0x300000);
WriteDex(0x300000);
@@ -161,7 +173,7 @@
MapInfo* info = maps_->Get(kMapDexFiles);
dex_files_->SetArch(ARCH_ARM64);
- memory_->SetData64(0xf800, 0x200000);
+ WriteDescriptor64(0xf800, 0x200000);
WriteEntry64(0x200000, 0, 0, 0x301000);
WriteDex(0x301000);
@@ -175,7 +187,7 @@
uint64_t method_offset = 0x124;
MapInfo* info = maps_->Get(kMapDexFiles);
- memory_->SetData32(0xf800, 0x200000);
+ WriteDescriptor32(0xf800, 0x200000);
WriteEntry32(0x200000, 0x200100, 0, 0x100000);
WriteEntry32(0x200100, 0, 0x200000, 0x300000);
WriteDex(0x300000);
@@ -191,7 +203,7 @@
MapInfo* info = maps_->Get(kMapDexFiles);
dex_files_->SetArch(ARCH_ARM64);
- memory_->SetData64(0xf800, 0x200000);
+ WriteDescriptor64(0xf800, 0x200000);
WriteEntry64(0x200000, 0x200100, 0, 0x100000);
WriteEntry64(0x200100, 0, 0x200000, 0x300000);
WriteDex(0x300000);
@@ -206,7 +218,7 @@
uint64_t method_offset = 0x124;
MapInfo* info = maps_->Get(kMapDexFiles);
- memory_->SetData32(0xf800, 0x200000);
+ WriteDescriptor32(0xf800, 0x200000);
WriteEntry32(0x200000, 0, 0, 0x300000);
WriteDex(0x300000);
@@ -226,7 +238,7 @@
uint64_t method_offset = 0x124;
MapInfo* info = maps_->Get(kMapDexFiles);
- memory_->SetData32(0xf800, 0x200000);
+ WriteDescriptor32(0xf800, 0x200000);
WriteEntry32(0x200000, 0x200100, 0, 0x100000);
WriteEntry32(0x200100, 0, 0x200000, 0x300000);
WriteDex(0x300000);
@@ -259,9 +271,9 @@
MapInfo* info = maps_->Get(kMapDexFiles);
// First global variable found, but value is zero.
- memory_->SetData32(0xc800, 0);
+ WriteDescriptor32(0xc800, 0);
- memory_->SetData32(0xf800, 0x200000);
+ WriteDescriptor32(0xf800, 0x200000);
WriteEntry32(0x200000, 0, 0, 0x300000);
WriteDex(0x300000);
@@ -274,7 +286,7 @@
dex_files_->SetArch(ARCH_ARM);
method_name = "fail";
method_offset = 0x123;
- memory_->SetData32(0xc800, 0x100000);
+ WriteDescriptor32(0xc800, 0x100000);
dex_files_->GetMethodInformation(maps_.get(), info, 0x300100, &method_name, &method_offset);
EXPECT_EQ("fail", method_name);
EXPECT_EQ(0x123U, method_offset);
@@ -286,9 +298,9 @@
MapInfo* info = maps_->Get(kMapDexFiles);
// First global variable found, but value is zero.
- memory_->SetData64(0xc800, 0);
+ WriteDescriptor64(0xc800, 0);
- memory_->SetData64(0xf800, 0x200000);
+ WriteDescriptor64(0xf800, 0x200000);
WriteEntry64(0x200000, 0, 0, 0x300000);
WriteDex(0x300000);
@@ -302,7 +314,7 @@
dex_files_->SetArch(ARCH_ARM64);
method_name = "fail";
method_offset = 0x123;
- memory_->SetData32(0xc800, 0x100000);
+ WriteDescriptor64(0xc800, 0x100000);
dex_files_->GetMethodInformation(maps_.get(), info, 0x300100, &method_name, &method_offset);
EXPECT_EQ("fail", method_name);
EXPECT_EQ(0x123U, method_offset);