Adjust PC value in ARM stack trace.

-2 for Thumb BLX(2) or -4 for the rest.

Change-Id: Ie59351a0012c2267309f63f0462fdba4698846fe
diff --git a/libc/bionic/debug_stacktrace.cpp b/libc/bionic/debug_stacktrace.cpp
index 87dbba3..fb933e6 100644
--- a/libc/bionic/debug_stacktrace.cpp
+++ b/libc/bionic/debug_stacktrace.cpp
@@ -91,6 +91,24 @@
     return _URC_NO_REASON;
   }
 
+#ifdef __arm__
+  /*
+   * The instruction pointer is pointing at the instruction after the bl(x), and
+   * the _Unwind_Backtrace routine already masks the Thumb mode indicator (LSB
+   * in PC). So we need to do a quick check here to find out if the previous
+   * instruction is a Thumb-mode BLX(2). If so subtract 2 otherwise 4 from PC.
+   */
+  if (ip != 0) {
+    short* ptr = reinterpret_cast<short*>(ip);
+    // Thumb BLX(2)
+    if ((*(ptr-1) & 0xff80) == 0x4780) {
+      ip -= 2;
+    } else {
+      ip -= 4;
+    }
+  }
+#endif
+
   state->frames[state->frame_count++] = ip;
   return (state->frame_count >= state->max_depth) ? _URC_END_OF_STACK : _URC_NO_REASON;
 }