summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libunwindstack/ElfInterfaceArm.cpp13
-rw-r--r--libunwindstack/ElfInterfaceArm.h3
-rw-r--r--libunwindstack/tests/UnwindOfflineTest.cpp4
-rw-r--r--libunwindstack/tools/unwind_info.cpp3
4 files changed, 19 insertions, 4 deletions
diff --git a/libunwindstack/ElfInterfaceArm.cpp b/libunwindstack/ElfInterfaceArm.cpp
index dfb8e8f91..a5afc7e5d 100644
--- a/libunwindstack/ElfInterfaceArm.cpp
+++ b/libunwindstack/ElfInterfaceArm.cpp
@@ -171,4 +171,17 @@ bool ElfInterfaceArm::StepExidx(uint64_t pc, uint64_t load_bias, Regs* regs, Mem
return return_value;
}
+bool ElfInterfaceArm::GetFunctionName(uint64_t addr, uint64_t load_bias, std::string* name,
+ uint64_t* offset) {
+ // For ARM, thumb function symbols have bit 0 set, but the address passed
+ // in here might not have this bit set and result in a failure to find
+ // the thumb function names. Adjust the address and offset to account
+ // for this possible case.
+ if (ElfInterface32::GetFunctionName(addr | 1, load_bias, name, offset)) {
+ *offset &= ~1;
+ return true;
+ }
+ return false;
+}
+
} // namespace unwindstack
diff --git a/libunwindstack/ElfInterfaceArm.h b/libunwindstack/ElfInterfaceArm.h
index 9c067ba3a..c1597ce3a 100644
--- a/libunwindstack/ElfInterfaceArm.h
+++ b/libunwindstack/ElfInterfaceArm.h
@@ -76,6 +76,9 @@ class ElfInterfaceArm : public ElfInterface32 {
bool StepExidx(uint64_t pc, uint64_t load_bias, Regs* regs, Memory* process_memory,
bool* finished);
+ bool GetFunctionName(uint64_t addr, uint64_t load_bias, std::string* name,
+ uint64_t* offset) override;
+
uint64_t start_offset() { return start_offset_; }
size_t total_entries() { return total_entries_; }
diff --git a/libunwindstack/tests/UnwindOfflineTest.cpp b/libunwindstack/tests/UnwindOfflineTest.cpp
index af4a5b59e..515bc8cc7 100644
--- a/libunwindstack/tests/UnwindOfflineTest.cpp
+++ b/libunwindstack/tests/UnwindOfflineTest.cpp
@@ -188,7 +188,7 @@ TEST_F(UnwindOfflineTest, pc_straddle_arm) {
std::string frame_info(DumpFrames(unwinder));
ASSERT_EQ(4U, unwinder.NumFrames()) << "Unwind:\n" << frame_info;
EXPECT_EQ(
- " #00 pc 0001a9f8 libc.so (abort+63)\n"
+ " #00 pc 0001a9f8 libc.so (abort+64)\n"
" #01 pc 00006a1b libbase.so (_ZN7android4base14DefaultAborterEPKc+6)\n"
" #02 pc 00007441 libbase.so (_ZN7android4base10LogMessageD2Ev+748)\n"
" #03 pc 00015147 /does/not/exist/libhidlbase.so\n",
@@ -575,7 +575,7 @@ TEST_F(UnwindOfflineTest, jit_debug_arm) {
std::string frame_info(DumpFrames(unwinder));
ASSERT_EQ(76U, unwinder.NumFrames()) << "Unwind:\n" << frame_info;
EXPECT_EQ(
- " #00 pc 00018a5e libarttestd.so (Java_Main_unwindInProcess+865)\n"
+ " #00 pc 00018a5e libarttestd.so (Java_Main_unwindInProcess+866)\n"
" #01 pc 0000212d (offset 0x2000) 137-cfi.odex (boolean Main.unwindInProcess(boolean, int, "
"boolean)+92)\n"
" #02 pc 00011cb1 anonymous:e2796000 (boolean Main.bar(boolean)+72)\n"
diff --git a/libunwindstack/tools/unwind_info.cpp b/libunwindstack/tools/unwind_info.cpp
index a0abccae2..5a8edfdf3 100644
--- a/libunwindstack/tools/unwind_info.cpp
+++ b/libunwindstack/tools/unwind_info.cpp
@@ -53,8 +53,7 @@ void DumpArm(ElfInterfaceArm* interface) {
printf(" PC 0x%" PRIx64, addr + load_bias);
uint64_t func_offset;
uint64_t pc = addr + load_bias;
- // This might be a thumb function, so set the low bit.
- if (interface->GetFunctionName(pc | 1, load_bias, &name, &func_offset) && !name.empty()) {
+ if (interface->GetFunctionName(pc, load_bias, &name, &func_offset) && !name.empty()) {
printf(" <%s>", name.c_str());
}
printf("\n");