libunwind-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Libunwind-devel] A modification suggestion on MIPS64 N32 on libunwind


From: Deng, Yimin (NSB - CN/Shanghai)
Subject: [Libunwind-devel] A modification suggestion on MIPS64 N32 on libunwind
Date: Mon, 16 Apr 2018 07:15:47 +0000

Hi,
I really appreciate for all your contribution to the libunwind. I mainly used 
the library 'unwind-ptrace' and it's very useful.

But I find that there are some issues when use it on MIPS64 (ABI: N32). After 
doing the modifications(based on libunwind-1.2.1) below, it works well.
I hope this will help you if you are suffering issues on the same arch and ABI.

diff --git a/include/libunwind-mips.h b/include/libunwind-mips.h
--- a/include/libunwind-mips.h
+++ b/include/libunwind-mips.h
@@ -54,7 +54,11 @@ extern "C" {
    addresses and register values.  To allow a single library to support
    multiple ABIs, and to support N32 at all, we must use a 64-bit type
    even when addresses are only 32 bits.  */
+#if _MIPS_SIM == _ABI64
 typedef uint64_t unw_word_t;
+#else
+typedef uint32_t unw_word_t;
+#endif
 typedef int32_t unw_sword_t;
 
 /* FIXME: MIPS ABIs.  */
@@ -95,7 +99,7 @@ typedef enum
     UNW_MIPS_R30,
     UNW_MIPS_R31,
 
-    UNW_MIPS_PC = 34,
+    UNW_MIPS_PC = 64,
 
     /* FIXME: Other registers!  */
 
@@ -103,7 +107,7 @@ typedef enum
        previous frame.  */
     UNW_MIPS_CFA,
 
-    UNW_TDEP_LAST_REG = UNW_MIPS_R31,
+    UNW_TDEP_LAST_REG = UNW_MIPS_PC,
 
     UNW_TDEP_IP = UNW_MIPS_R31,
     UNW_TDEP_SP = UNW_MIPS_R29,
diff --git a/include/tdep-mips/libunwind_i.h b/include/tdep-mips/libunwind_i.h
--- a/include/tdep-mips/libunwind_i.h
+++ b/include/tdep-mips/libunwind_i.h
@@ -247,6 +247,14 @@ dwarf_get (struct dwarf_cursor *c, dwarf
                                      0, c->as_arg);
   else if (c->as->abi == UNW_MIPS_ABI_O32)
     return read_s32 (c, DWARF_GET_LOC (loc), val);
+  else if (c->as->abi == UNW_MIPS_ABI_N32) {
+    if (tdep_big_endian(c->as))
+      return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc) + 4, val,
+                                       0, c->as_arg);
+    else
+      return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val,
+                                       0, c->as_arg);
+  }
   else
     return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val,
                                      0, c->as_arg);
diff --git a/src/mips/Gcreate_addr_space.c b/src/mips/Gcreate_addr_space.c
--- a/src/mips/Gcreate_addr_space.c
+++ b/src/mips/Gcreate_addr_space.c
@@ -58,7 +58,15 @@ unw_create_addr_space (unw_accessors_t *
     as->big_endian = (byte_order == __BIG_ENDIAN);
 
   /* FIXME!  There is no way to specify the ABI.  */
+#if _MIPS_SIM == _ABIO32
   as->abi = UNW_MIPS_ABI_O32;
+#elif _MIPS_SIM == _ABIN32
+  as->abi = UNW_MIPS_ABI_N32;
+#elif _MIPS_SIM == _ABI64
+  as->abi = UNW_MIPS_ABI_N64;
+#else
+# error Unsupported ABI
+#endif
   as->addr_size = 4;
 
   return as;
diff --git a/src/mips/Gregs.c b/src/mips/Gregs.c
--- a/src/mips/Gregs.c
+++ b/src/mips/Gregs.c
@@ -63,7 +63,7 @@ tdep_access_reg (struct cursor *c, unw_r
     case UNW_MIPS_R26:
     case UNW_MIPS_R27:
     case UNW_MIPS_R28:
-    case UNW_MIPS_R29:
+
     case UNW_MIPS_R30:
     case UNW_MIPS_R31:
       loc = c->dwarf.loc[reg - UNW_MIPS_R0];
@@ -73,6 +73,7 @@ tdep_access_reg (struct cursor *c, unw_r
       loc = c->dwarf.loc[reg];
       break;
 
+    case UNW_MIPS_R29:
     case UNW_MIPS_CFA:
       if (write)
         return -UNW_EREADONLYREG;
diff --git a/src/ptrace/_UPT_reg_offset.c b/src/ptrace/_UPT_reg_offset.c
--- a/src/ptrace/_UPT_reg_offset.c
+++ b/src/ptrace/_UPT_reg_offset.c
@@ -501,6 +501,42 @@ const int _UPT_reg_offset[UNW_REG_LAST +
     [UNW_ARM_R14]      = 0x38,
     [UNW_ARM_R15]      = 0x3c,
 #elif defined(UNW_TARGET_MIPS)
+#define UNW_R_OFF(R) [R] = R
+    UNW_R_OFF(UNW_MIPS_R0),
+    UNW_R_OFF(UNW_MIPS_R1),
+    UNW_R_OFF(UNW_MIPS_R2),
+    UNW_R_OFF(UNW_MIPS_R3),
+    UNW_R_OFF(UNW_MIPS_R4),
+    UNW_R_OFF(UNW_MIPS_R5),
+    UNW_R_OFF(UNW_MIPS_R6),
+    UNW_R_OFF(UNW_MIPS_R7),
+    UNW_R_OFF(UNW_MIPS_R8),
+    UNW_R_OFF(UNW_MIPS_R9),
+    UNW_R_OFF(UNW_MIPS_R10),
+    UNW_R_OFF(UNW_MIPS_R11),
+    UNW_R_OFF(UNW_MIPS_R12),
+    UNW_R_OFF(UNW_MIPS_R13),
+    UNW_R_OFF(UNW_MIPS_R14),
+    UNW_R_OFF(UNW_MIPS_R15),
+    UNW_R_OFF(UNW_MIPS_R16),
+    UNW_R_OFF(UNW_MIPS_R17),
+    UNW_R_OFF(UNW_MIPS_R18),
+    UNW_R_OFF(UNW_MIPS_R19),
+    UNW_R_OFF(UNW_MIPS_R20),
+    UNW_R_OFF(UNW_MIPS_R21),
+    UNW_R_OFF(UNW_MIPS_R22),
+    UNW_R_OFF(UNW_MIPS_R23),
+    UNW_R_OFF(UNW_MIPS_R24),
+    UNW_R_OFF(UNW_MIPS_R25),
+    UNW_R_OFF(UNW_MIPS_R26),
+    UNW_R_OFF(UNW_MIPS_R27),
+    UNW_R_OFF(UNW_MIPS_R28),
+    UNW_R_OFF(UNW_MIPS_R29),
+    UNW_R_OFF(UNW_MIPS_R30),
+    UNW_R_OFF(UNW_MIPS_R31),
+    UNW_R_OFF(UNW_MIPS_PC)
+
+#undef UNW_R_OFF
 #elif defined(UNW_TARGET_SH)
 #elif defined(UNW_TARGET_AARCH64)
     [UNW_AARCH64_X0]       = 0x00,

Thx & B.R.
Yimin Deng





reply via email to

[Prev in Thread] Current Thread [Next in Thread]