Code drop from //branches/cupcake/...@124589
diff --git a/debuggerd/Android.mk b/debuggerd/Android.mk
index 03046bd..b22e1a8 100644
--- a/debuggerd/Android.mk
+++ b/debuggerd/Android.mk
@@ -1,5 +1,7 @@
 # Copyright 2005 The Android Open Source Project
 
+ifeq ($(TARGET_ARCH),arm)
+
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 
@@ -20,3 +22,5 @@
 #LOCAL_FORCE_STATIC_EXECUTABLE := true
 LOCAL_SHARED_LIBRARIES := libcutils libc
 include $(BUILD_EXECUTABLE)
+
+endif # TARGET_ARCH == arm
diff --git a/debuggerd/unwind-arm.c b/debuggerd/unwind-arm.c
index fdc0a6a..9642d2e 100644
--- a/debuggerd/unwind-arm.c
+++ b/debuggerd/unwind-arm.c
@@ -381,13 +381,15 @@
 }
 
 /* Print out the current call level, pc, and module name in the crash log */
-static _Unwind_Reason_Code log_function(_Unwind_Context *context, int tfd,
+static _Unwind_Reason_Code log_function(_Unwind_Context *context, pid_t pid, 
+                                        int tfd,
                                         int stack_level,
                                         mapinfo *map,
                                         unsigned int sp_list[],
                                         bool at_fault)
 {
     _uw pc;
+    _uw rel_pc; 
     phase2_vrs *vrs = (phase2_vrs*) context;
     const mapinfo *mi;
     bool only_in_tombstone = !at_fault;
@@ -404,19 +406,53 @@
     // For deeper framers, rollback pc by one instruction
     else {
         pc = vrs->core.r[R_PC];
-        // Thumb mode
+        /* Thumb mode - need to check whether the bl(x) has long offset or not.
+         * Examples:
+         *
+         * arm blx in the middle of thumb:
+         * 187ae:       2300            movs    r3, #0
+         * 187b0:       f7fe ee1c       blx     173ec
+         * 187b4:       2c00            cmp     r4, #0
+         *
+         * arm bl in the middle of thumb:
+         * 187d8:       1c20            adds    r0, r4, #0
+         * 187da:       f136 fd15       bl      14f208
+         * 187de:       2800            cmp     r0, #0
+         *
+         * pure thumb:
+         * 18894:       189b            adds    r3, r3, r2
+         * 18896:       4798            blx     r3
+         * 18898:       b001            add     sp, #4
+         */
         if (pc & 1) {
-            pc = (pc & ~1) - 2;
+            _uw prev_word;
+            pc = (pc & ~1);
+            prev_word = get_remote_word(pid, (void *) pc-4);
+            // Long offset 
+            if ((prev_word & 0xf0000000) == 0xf0000000 && 
+                (prev_word & 0x0000e000) == 0x0000e000) {
+                pc -= 4;
+            }
+            else {
+                pc -= 2;
+            }
         }
         else { 
             pc -= 4;
         }
     }
 
-    mi = pc_to_mapinfo(map, pc);
+    /* We used to print the absolute PC in the back trace, and mask out the top
+     * 3 bits to guesstimate the offset in the .so file. This is not working for
+     * non-prelinked libraries since the starting offset may not be aligned on 
+     * 1MB boundaries, and the library may be larger than 1MB. So for .so 
+     * addresses we print the relative offset in back trace.
+     */
+    rel_pc = pc;
+    mi = pc_to_mapinfo(map, pc, &rel_pc);
 
     _LOG(tfd, only_in_tombstone, 
-         "         #%02d  pc %08x  %s\n", stack_level, pc, 
+         "         #%02d  pc %08x  %s\n", stack_level, rel_pc, 
          mi ? mi->name : "");
 
     return _URC_NO_REASON;
@@ -459,7 +495,7 @@
      */
     if (get_eitp(saved_vrs.core.r[R_PC], pid, map, NULL) == NULL) { 
         *frame0_pc_sane = 0;
-        log_function ((_Unwind_Context *) &saved_vrs, tfd, stack_level, 
+        log_function ((_Unwind_Context *) &saved_vrs, pid, tfd, stack_level, 
                       map, sp_list, at_fault);
         saved_vrs.core.r[R_PC] = saved_vrs.core.r[R_LR];
         stack_level++;
@@ -493,7 +529,7 @@
         _Unwind_SetGR((_Unwind_Context *)&saved_vrs, 12, (_Unwind_Ptr) ucbp);
 
         /* Call log function.  */
-        if (log_function ((_Unwind_Context *) &saved_vrs, tfd, stack_level, 
+        if (log_function ((_Unwind_Context *) &saved_vrs, pid, tfd, stack_level,
                           map, sp_list, at_fault) != _URC_NO_REASON) {
             code = _URC_FAILURE;
             break;
diff --git a/debuggerd/utility.c b/debuggerd/utility.c
index 0cb790f..8f3931c 100644
--- a/debuggerd/utility.c
+++ b/debuggerd/utility.c
@@ -18,6 +18,7 @@
 #include <sys/ptrace.h>
 #include <sys/exec_elf.h>
 #include <assert.h>
+#include <string.h>
 #include <errno.h>
 
 #include "utility.h"
@@ -66,10 +67,14 @@
 }
 
 /* Find the containing map info for the pc */
-const mapinfo *pc_to_mapinfo(mapinfo *mi, unsigned pc)
+const mapinfo *pc_to_mapinfo(mapinfo *mi, unsigned pc, unsigned *rel_pc)
 {
     while(mi) {
         if((pc >= mi->start) && (pc < mi->end)){
+            // Only calculate the relative offset for shared libraries
+            if (strstr(mi->name, ".so")) {
+                *rel_pc = pc - mi->start;
+            }
             return mi;
         }
         mi = mi->next;
diff --git a/debuggerd/utility.h b/debuggerd/utility.h
index 802e3ad..49f5951 100644
--- a/debuggerd/utility.h
+++ b/debuggerd/utility.h
@@ -45,7 +45,7 @@
 extern void get_remote_struct(int pid, void *src, void *dst, size_t size);
 
 /* Find the containing map for the pc */
-const mapinfo *pc_to_mapinfo (mapinfo *mi, unsigned pc);
+const mapinfo *pc_to_mapinfo (mapinfo *mi, unsigned pc, unsigned *rel_pc);
 
 /* Map a pc address to the name of the containing ELF file */
 const char *map_to_name(mapinfo *mi, unsigned pc, const char* def);