Source-Changes-HG archive

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

[src/trunk]: src/sys/lib/libunwind Support DWARFish unwind for ARM.



details:   https://anonhg.NetBSD.org/src/rev/78f595d7a5e2
branches:  trunk
changeset: 329146:78f595d7a5e2
user:      joerg <joerg%NetBSD.org@localhost>
date:      Sun May 11 02:07:35 2014 +0000

description:
Support DWARFish unwind for ARM.

diffstat:

 sys/lib/libunwind/Registers.hpp      |  37 ++++++++++++++++++++++++++++-------
 sys/lib/libunwind/unwind_registers.S |  30 ++++++++++++++++++++++++++--
 2 files changed, 56 insertions(+), 11 deletions(-)

diffs (144 lines):

diff -r 5c628834217c -r 78f595d7a5e2 sys/lib/libunwind/Registers.hpp
--- a/sys/lib/libunwind/Registers.hpp   Sun May 11 02:02:14 2014 +0000
+++ b/sys/lib/libunwind/Registers.hpp   Sun May 11 02:07:35 2014 +0000
@@ -240,21 +240,24 @@
   DWARF_ARM32_R0 = 0,
   DWARF_ARM32_R15 = 15,
   DWARF_ARM32_SPSR = 128,
-  DWARF_ARM32_D0 = 256,                // VFP-v3/Neon
+  DWARF_ARM32_OLD_S0 = 64,
+  DWARF_ARM32_OLD_S31 = 91,
+  DWARF_ARM32_D0 = 256,
   DWARF_ARM32_D31 = 287,
   REGNO_ARM32_R0 = 0,
   REGNO_ARM32_SP = 13,
   REGNO_ARM32_R15 = 15,
   REGNO_ARM32_SPSR = 16,
-  REGNO_ARM32_D0 = 0,
-  REGNO_ARM32_D31 = 31,
+  REGNO_ARM32_D0 = 17,
+  REGNO_ARM32_D15 = 32,
+  REGNO_ARM32_D31 = 48,
 };
 
 class Registers_arm32 {
 public:
   enum {
     LAST_REGISTER = REGNO_ARM32_D31,
-    LAST_RESTORE_REG = REGNO_ARM32_SPSR,
+    LAST_RESTORE_REG = REGNO_ARM32_D31,
     RETURN_OFFSET = 0,
   };
 
@@ -263,15 +266,19 @@
   static int dwarf2regno(int num) {
     if (num >= DWARF_ARM32_R0 && num <= DWARF_ARM32_R15)
       return REGNO_ARM32_R0 + (num - DWARF_ARM32_R0);
+    if (num == DWARF_ARM32_SPSR)
+      return REGNO_ARM32_SPSR;
     if (num >= DWARF_ARM32_D0 && num <= DWARF_ARM32_D31)
       return REGNO_ARM32_D0 + (num - DWARF_ARM32_D0);
-    if (num == DWARF_ARM32_SPSR)
-      return REGNO_ARM32_SPSR;
+    if (num >= DWARF_ARM32_OLD_S0 && num <= DWARF_ARM32_OLD_S31) {
+      assert(num % 2 == 0);
+      return REGNO_ARM32_D0 + (num - DWARF_ARM32_OLD_S0) / 2;
+    }
     return LAST_REGISTER + 1;
   }
 
   bool validRegister(int num) const {
-    return num >= 0 && num <= LAST_RESTORE_REG;
+    return num >= 0 && num <= REGNO_ARM32_SPSR;
   }
 
   uint64_t getRegister(int num) const {
@@ -297,14 +304,28 @@
   }
 
   void copyFloatVectorRegister(int num, uint64_t addr_) {
+    if (num <= REGNO_ARM32_D15) {
+      if ((flags & 1) == 0) {
+        lazyVFP1();
+        flags |= 1;
+      }
+    } else {
+      if ((flags & 2) == 0) {
+        lazyVFP3();
+        flags |= 2;
+      }
+    }
     const void *addr = reinterpret_cast<const void *>(addr_);
     memcpy(fpreg + (num - REGNO_ARM32_D0), addr, sizeof(fpreg[0]));
   }
 
+  __dso_hidden void lazyVFP1();
+  __dso_hidden void lazyVFP3();
   __dso_hidden void jumpto() const __dead;
 
 private:
   uint32_t reg[REGNO_ARM32_SPSR + 1];
+  uint32_t flags;
   uint64_t fpreg[32];
 };
 
@@ -930,7 +951,7 @@
 typedef Registers_x86_64 NativeUnwindRegisters;
 #elif __powerpc__
 typedef Registers_ppc32 NativeUnwindRegisters;
-#elif __arm__ && !defined(__ARM_EABI__)
+#elif __arm__
 typedef Registers_arm32 NativeUnwindRegisters;
 #elif __vax__
 typedef Registers_vax NativeUnwindRegisters;
diff -r 5c628834217c -r 78f595d7a5e2 sys/lib/libunwind/unwind_registers.S
--- a/sys/lib/libunwind/unwind_registers.S      Sun May 11 02:02:14 2014 +0000
+++ b/sys/lib/libunwind/unwind_registers.S      Sun May 11 02:07:35 2014 +0000
@@ -269,20 +269,44 @@
        bctr
 #endif
 
-#if defined(__arm__) && !defined(__ARM_EABI__)
+#if defined(__arm__)
+       .fpu vfpv3
        .hidden _ZN7_Unwind15Registers_arm32C1Ev
 ENTRY(_ZN7_Unwind15Registers_arm32C1Ev)
        stmia   r0, {r0-r14}
-
        str     lr, [r0, #60]   /* PC */
        mrs     r1, cpsr
        str     r1, [r0, #64]   /* CPSR */
-
+       mov     r1, #0
+       str     r1, [r0, #68]
        RET
 END(_ZN7_Unwind15Registers_arm32C1Ev)
 
+       .hidden _ZN7_Unwind15Registers_arm328lazyVFP1Ev
+ENTRY(_ZN7_Unwind15Registers_arm328lazyVFP1Ev)
+       add     r0, #72
+       vstmia  r0, {d0-d15}
+END(_ZN7_Unwind15Registers_arm328lazyVFP1Ev)
+
+       .hidden _ZN7_Unwind15Registers_arm328lazyVFP3Ev
+ENTRY(_ZN7_Unwind15Registers_arm328lazyVFP3Ev)
+       add     r0, #200
+       vstmia  r0, {d16-d31}
+END(_ZN7_Unwind15Registers_arm328lazyVFP3Ev)
+
        .hidden _ZNK7_Unwind15Registers_arm326jumptoEv
 ENTRY(_ZNK7_Unwind15Registers_arm326jumptoEv)
+       ldrb    r1, [r0, #68]
+       tst     r1, #1
+       beq     .Lnovfp1
+       add     r2, r0, #72
+       vldmia  r2, {d0-d15}
+.Lnovfp1:
+       tst     r1, #2
+       beq     .Lnovfp3
+       add     r2, r0, #200
+       vldmia  r2, {d16-d31}
+.Lnovfp3:
        ldr     r1, [r0, #64]
        msr     cpsr_sxc, r1
        ldmia   r0, {r0-r15}



Home | Main Index | Thread Index | Old Index