]> Zhao Yanbai Git Server - minix.git/commitdiff
new libunwind, updated to netbsd b1f513eedd
authorBen Gras <ben@minix3.org>
Mon, 12 May 2014 13:17:14 +0000 (15:17 +0200)
committerLionel Sambuc <lionel@minix3.org>
Mon, 28 Jul 2014 15:06:01 +0000 (17:06 +0200)
existing libunwind used '0' in lsda_encoding as 'not present,'
whereas that is a valid encoding and does occur and would be
ignored. a missing encoding is actually 0xff.

The commit that addresses this is:

commit 8d4b51028d1a12b58d616f4b605254a877caafcf
Author: joerg <joerg>
Date:   Tue Mar 11 23:52:17 2014 +0000

    0 is a valid LSDA encoding and can be seen in statically linked
    programs. Initialize lsdaEncoding to DW_EH_PE_omit and check for that
    value to decide whether a value should be decoded.

more bugfixes are necessary. this update is up to:

commit b1f513eedd332426d88acbb118b6e9070966dcb9
Author: joerg <joerg>
Date:   Wed May 14 22:13:36 2014 +0000

    Lazy VFP processing works a lot better if the functions contain a return
    instruction.

sys/lib/libunwind/AddressSpace.hpp
sys/lib/libunwind/DwarfInstructions.hpp
sys/lib/libunwind/DwarfParser.hpp
sys/lib/libunwind/Makefile.inc
sys/lib/libunwind/Registers.hpp
sys/lib/libunwind/UnwindCursor.hpp
sys/lib/libunwind/libunwind.cxx
sys/lib/libunwind/unwind.h
sys/lib/libunwind/unwind_registers.S

index 31b56191b7eaf7ba107ce8d219856621c4f7bf3b..c655d2dc8fe90dfacbd8f618484e1ee5937eed43 100644 (file)
@@ -48,7 +48,6 @@ struct unw_proc_info_t {
   uintptr_t lsda;            // Address of Language Specific Data Area
   uintptr_t handler;         // Personality routine
   uintptr_t extra_args;      // Extra stack space for frameless routines
-  uint32_t unwind_info_size; // Size of DWARF unwind info
   uintptr_t unwind_info;     // Address of DWARF unwind info
 };
 
@@ -76,13 +75,29 @@ public:
     pthread_rwlock_init(&fdeTreeLock, NULL);
   }
 
-  uint8_t get8(pint_t addr) { return *((uint8_t *)addr); }
+  uint8_t get8(pint_t addr) {
+    uint8_t val;
+    memcpy(&val, (void *)addr, sizeof(val));
+    return val;
+  }
 
-  uint16_t get16(pint_t addr) { return *((uint16_t *)addr); }
+  uint16_t get16(pint_t addr) {
+    uint16_t val;
+    memcpy(&val, (void *)addr, sizeof(val));
+    return val;
+  }
 
-  uint32_t get32(pint_t addr) { return *((uint32_t *)addr); }
+  uint32_t get32(pint_t addr) {
+    uint32_t val;
+    memcpy(&val, (void *)addr, sizeof(val));
+    return val;
+  }
 
-  uint64_t get64(pint_t addr) { return *((uint64_t *)addr); }
+  uint64_t get64(pint_t addr) {
+    uint64_t val;
+    memcpy(&val, (void *)addr, sizeof(val));
+    return val;
+  }
 
   uintptr_t getP(pint_t addr) {
     if (sizeof(uintptr_t) == sizeof(uint32_t))
@@ -249,6 +264,7 @@ public:
       return false;
     if (n->hdr_start == 0) {
       fdeStart = n->hdr_base;
+      data_base = n->data_base;
       return true;
     }
 
@@ -271,6 +287,7 @@ public:
         len = (len + 1) / 2;
     }
     fdeStart = base + (int32_t)get32(first + 4);
+    data_base = n->data_base;
     return true;
   }
 
@@ -336,9 +353,9 @@ public:
 private:
   findPCRange_t findPCRange;
   bool needsReload;
-#if !defined(__minix)
+#ifndef __minix
   pthread_rwlock_t fdeTreeLock;
-#endif /* !defined(__minix) */
+#endif
   rb_tree_t segmentTree;
   rb_tree_t dsoTree;
 
@@ -433,8 +450,8 @@ static int phdr_callback(struct dl_phdr_info *info, size_t size, void *data_) {
 }
 
 static int rangeCmp(void *context, const void *n1_, const void *n2_) {
-  LocalAddressSpace::Range *n1 = (LocalAddressSpace::Range *)n1_;
-  LocalAddressSpace::Range *n2 = (LocalAddressSpace::Range *)n2_;
+  const LocalAddressSpace::Range *n1 = (const LocalAddressSpace::Range *)n1_;
+  const LocalAddressSpace::Range *n2 = (const LocalAddressSpace::Range *)n2_;
 
   if (n1->first_pc < n2->first_pc)
     return -1;
@@ -445,8 +462,8 @@ static int rangeCmp(void *context, const void *n1_, const void *n2_) {
 }
 
 static int rangeCmpKey(void *context, const void *n_, const void *pc_) {
-  LocalAddressSpace::Range *n = (LocalAddressSpace::Range *)n_;
-  LocalAddressSpace::pint_t *pc = (LocalAddressSpace::pint_t *)pc_;
+  const LocalAddressSpace::Range *n = (const LocalAddressSpace::Range *)n_;
+  const LocalAddressSpace::pint_t *pc = (const LocalAddressSpace::pint_t *)pc_;
   if (n->last_pc < *pc)
     return -1;
   if (n->first_pc > *pc)
@@ -455,8 +472,8 @@ static int rangeCmpKey(void *context, const void *n_, const void *pc_) {
 }
 
 static int dsoTableCmp(void *context, const void *n1_, const void *n2_) {
-  LocalAddressSpace::Range *n1 = (LocalAddressSpace::Range *)n1_;
-  LocalAddressSpace::Range *n2 = (LocalAddressSpace::Range *)n2_;
+  const LocalAddressSpace::Range *n1 = (const LocalAddressSpace::Range *)n1_;
+  const LocalAddressSpace::Range *n2 = (const LocalAddressSpace::Range *)n2_;
 
   if (n1->ehframe_base < n2->ehframe_base)
     return -1;
@@ -466,8 +483,8 @@ static int dsoTableCmp(void *context, const void *n1_, const void *n2_) {
 }
 
 static int dsoTableCmpKey(void *context, const void *n_, const void *ptr_) {
-  LocalAddressSpace::Range *n = (LocalAddressSpace::Range *)n_;
-  LocalAddressSpace::pint_t *ptr = (LocalAddressSpace::pint_t *)ptr_;
+  const LocalAddressSpace::Range *n = (const LocalAddressSpace::Range *)n_;
+  const LocalAddressSpace::pint_t *ptr = (const LocalAddressSpace::pint_t *)ptr_;
   if (n->ehframe_base < *ptr)
     return -1;
   if (n->ehframe_base > *ptr)
index 37c0a3c13ef99f137b64998d57d194f74f5a64ef..56fe8466e2f2a46d6dc700c1607ae258a6507c8c 100644 (file)
@@ -39,12 +39,6 @@ public:
   static step_result stepWithDwarf(A &, pint_t, pint_t, R &, unw_proc_info_t *);
 
 private:
-  // Pseudo-register used for return addresses.
-  enum {
-    DW_X86_RET_ADDR = 8,
-    DW_X86_64_RET_ADDR = 16,
-  };
-
   static pint_t evaluateExpression(pint_t, A &, const R &, pint_t);
   static pint_t
   getSavedRegister(A &, const R &, pint_t,
@@ -54,9 +48,6 @@ private:
                           const typename CFI_Parser<A, R>::RegisterLocation &);
 
   static int lastRestoreReg(const R &) { return R::LAST_RESTORE_REG; }
-  static bool isReturnAddressRegister(int regno, const R &) {
-    return regno == R::IP_PSEUDO_REG;
-  }
 
   static pint_t getCFA(A &addressSpace,
                        const typename CFI_Parser<A, R>::PrologInfo &prolog,
@@ -145,7 +136,7 @@ step_result DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
   for (int i = 0; i <= lastRestoreReg(newRegisters); ++i) {
     if (prolog.savedRegisters[i].location == CFI_Parser<A, R>::kRegisterUnused)
       continue;
-    if (isReturnAddressRegister(i, registers))
+    if (i == (int)cieInfo.returnAddressRegister)
       returnAddress = getSavedRegister(addressSpace, registers, cfa,
                                        prolog.savedRegisters[i]);
     else if (registers.validRegister(i))
@@ -162,7 +153,7 @@ step_result DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
   // The CFA is defined as the stack pointer at the call site.
   // Therefore the SP is restored by setting it to the CFA.
   newRegisters.setSP(cfa);
-  newRegisters.setIP(returnAddress);
+  newRegisters.setIP(returnAddress + R::RETURN_OFFSET);
 
   // Now replace register set with the working copy.
   registers = newRegisters;
index 671502022417c33b5595da5f6d808f81e9f53038..6e8ef2cab4c738acac0b20a315e71d7e1b6fea24 100644 (file)
@@ -43,6 +43,7 @@ public:
     uint8_t personalityOffsetInCIE;
     bool isSignalFrame;
     bool fdesHaveAugmentationData;
+    uint8_t returnAddressRegister;
   };
 
   /// Information about an FDE (Frame Description Entry)
@@ -172,7 +173,7 @@ bool CFI_Parser<A, R>::decodeFDE(A &addressSpace, pint_t fdeStart,
   if (cieInfo->fdesHaveAugmentationData) {
     uintptr_t augLen = addressSpace.getULEB128(p, nextCFI);
     pint_t endOfAug = p + augLen;
-    if (cieInfo->lsdaEncoding != 0) {
+    if (cieInfo->lsdaEncoding != DW_EH_PE_omit) {
       // Peek at value (without indirection).  Zero means no LSDA.
       pint_t lsdaStart = p;
       if (addressSpace.getEncodedP(p, nextCFI, cieInfo->lsdaEncoding & 0x0F,
@@ -198,7 +199,7 @@ template <typename A, typename R>
 bool CFI_Parser<A, R>::parseCIE(A &addressSpace, pint_t cie,
                                 CIE_Info *cieInfo) {
   cieInfo->pointerEncoding = 0;
-  cieInfo->lsdaEncoding = 0;
+  cieInfo->lsdaEncoding = DW_EH_PE_omit;
   cieInfo->personalityEncoding = 0;
   cieInfo->personalityOffsetInCIE = 0;
   cieInfo->personality = 0;
@@ -238,7 +239,7 @@ bool CFI_Parser<A, R>::parseCIE(A &addressSpace, pint_t cie,
   // Parse data alignment factor
   cieInfo->dataAlignFactor = addressSpace.getSLEB128(p, cieContentEnd);
   // Parse return address register
-  addressSpace.getULEB128(p, cieContentEnd);
+  cieInfo->returnAddressRegister = (uint8_t)addressSpace.getULEB128(p, cieContentEnd);
   // Parse augmentation data based on augmentation string.
   if (addressSpace.get8(strStart) == 'z') {
     // parse augmentation data length
@@ -460,6 +461,8 @@ CFI_Parser<A, R>::parseInstructions(A &addressSpace, pint_t instructions,
       reg = R::dwarf2regno(addressSpace.getULEB128(p, instructionsEnd));
       offset =
           addressSpace.getULEB128(p, instructionsEnd) * cieInfo.dataAlignFactor;
+      if (reg > kMaxRegisterNumber)
+        return false;
       results->savedRegisters[reg].location = kRegisterOffsetFromCFA;
       results->savedRegisters[reg].value = offset;
       break;
@@ -481,6 +484,20 @@ CFI_Parser<A, R>::parseInstructions(A &addressSpace, pint_t instructions,
       length = addressSpace.getULEB128(p, instructionsEnd);
       p += length;
       break;
+    case DW_CFA_GNU_window_save:
+#if defined(__sparc__)
+      for (reg = 8; reg < 16; ++reg) {
+        results->savedRegisters[reg].location = kRegisterInRegister;
+        results->savedRegisters[reg].value = reg + 16;
+      }
+      for (reg = 16; reg < 32; ++reg) {
+        results->savedRegisters[reg].location = kRegisterInCFA;
+        results->savedRegisters[reg].value = (reg - 16) * sizeof(typename R::reg_t);
+      }
+      break;
+#else
+      return false;
+#endif
     case DW_CFA_GNU_args_size:
       offset = addressSpace.getULEB128(p, instructionsEnd);
       results->spExtraArgSize = offset;
index 4a59407869460da5e9bf6fdea6c5454a04ffaca7..1195ef6a978550637f8968293f44d9dd6a65cad7 100644 (file)
@@ -1,4 +1,4 @@
-#      $NetBSD: Makefile.inc,v 1.1 2013/10/14 01:14:57 joerg Exp $
+#      $NetBSD: Makefile.inc,v 1.5 2014/03/19 16:46:23 joerg Exp $
 
 .PATH: ${NETBSDSRCDIR}/sys/lib/libunwind
 
@@ -7,4 +7,15 @@ SRCS+= libunwind.cxx \
 
 INCS+= unwind.h
 
-COPTS.libuwind.cxx+=   -funwind-tables -fno-rtti -fno-exceptions -fvisibility=hidden -Wno-old-style-cast
+.if ${HAVE_GCC:U48} == "4"
+CLEANFILES+=   cstdint
+DPSRCS+=       cstdint
+
+cstdint:
+       echo '#include <stdint.h>' > ${.TARGET}
+
+COPTS.libunwind.cxx+=  "-D__builtin_unreachable()=abort()"
+.else
+COPTS.libunwind.cxx+=  ${${ACTIVE_CXX} == "gcc":? -std=c++0x : -std=c++11 }
+.endif
+COPTS.libunwind.cxx+=  -funwind-tables -fno-rtti -fno-exceptions -fvisibility=hidden -Wno-old-style-cast
index dc18d076bf3fdd2088c49e03f8ba3278b96063d6..0467525edcb3b6869da4e0631bc6c0c8a146668f 100644 (file)
@@ -32,9 +32,9 @@ enum {
 class Registers_x86 {
 public:
   enum {
-    LAST_RESTORE_REG = REGNO_X86_EIP,
-    IP_PSEUDO_REG = REGNO_X86_EIP,
     LAST_REGISTER = REGNO_X86_EIP,
+    LAST_RESTORE_REG = REGNO_X86_EIP,
+    RETURN_OFFSET = 0,
   };
 
   __dso_hidden Registers_x86();
@@ -97,9 +97,9 @@ enum {
 class Registers_x86_64 {
 public:
   enum {
-    LAST_RESTORE_REG = REGNO_X86_64_RIP,
-    IP_PSEUDO_REG = REGNO_X86_64_RIP,
     LAST_REGISTER = REGNO_X86_64_RIP,
+    LAST_RESTORE_REG = REGNO_X86_64_RIP,
+    RETURN_OFFSET = 0,
   };
 
   __dso_hidden Registers_x86_64();
@@ -144,19 +144,18 @@ enum {
   DWARF_PPC32_R31 = 31,
   DWARF_PPC32_F0 = 32,
   DWARF_PPC32_F31 = 63,
-  DWARF_PPC32_V0 = 1124,
-  DWARF_PPC32_V31 = 1155,
   DWARF_PPC32_LR = 65,
-  DWARF_PPC32_CTR = 66,
-  DWARF_PPC32_XER = 76,
+  DWARF_PPC32_CR = 70,
+  DWARF_PPC32_V0 = 77,
+  DWARF_PPC32_V31 = 108,
+
   REGNO_PPC32_R0 = 0,
-  REGNO_PPC32_R1 = 0,
+  REGNO_PPC32_R1 = 1,
   REGNO_PPC32_R31 = 31,
-  REGNO_PPC32_CR = 32,
-  REGNO_PPC32_LR = 33,
-  REGNO_PPC32_CTR = 34,
-  REGNO_PPC32_XER = 35,
-  REGNO_PPC32_SRR0 = 36,
+  REGNO_PPC32_LR = 32,
+  REGNO_PPC32_CR = 33,
+  REGNO_PPC32_SRR0 = 34,
+
   REGNO_PPC32_F0 = REGNO_PPC32_SRR0 + 1,
   REGNO_PPC32_F31 = REGNO_PPC32_F0 + 31,
   REGNO_PPC32_V0 = REGNO_PPC32_F31 + 1,
@@ -166,9 +165,9 @@ enum {
 class Registers_ppc32 {
 public:
   enum {
-    LAST_RESTORE_REG = REGNO_PPC32_V31,
-    IP_PSEUDO_REG = REGNO_PPC32_SRR0,
     LAST_REGISTER = REGNO_PPC32_V31,
+    LAST_RESTORE_REG = REGNO_PPC32_V31,
+    RETURN_OFFSET = 0,
   };
 
   __dso_hidden Registers_ppc32();
@@ -180,7 +179,14 @@ public:
       return REGNO_PPC32_F0 + (num - DWARF_PPC32_F0);
     if (num >= DWARF_PPC32_V0 && num <= DWARF_PPC32_V31)
       return REGNO_PPC32_V0 + (num - DWARF_PPC32_V0);
-    return LAST_REGISTER + 1;
+    switch (num) {
+    case DWARF_PPC32_LR:
+      return REGNO_PPC32_LR;
+    case DWARF_PPC32_CR:
+      return REGNO_PPC32_CR;
+    default:
+      return LAST_REGISTER + 1;
+    }
   }
 
   bool validRegister(int num) const {
@@ -225,10 +231,747 @@ private:
     uint64_t low, high;
   };
   uint32_t reg[REGNO_PPC32_SRR0 + 1];
+  uint32_t dummy;
   uint64_t fpreg[32];
   vecreg_t vecreg[64];
 };
 
+enum {
+  DWARF_ARM32_R0 = 0,
+  DWARF_ARM32_R15 = 15,
+  DWARF_ARM32_SPSR = 128,
+  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 = 17,
+  REGNO_ARM32_D15 = 32,
+  REGNO_ARM32_D31 = 48,
+};
+
+class Registers_arm32 {
+public:
+  enum {
+    LAST_REGISTER = REGNO_ARM32_D31,
+    LAST_RESTORE_REG = REGNO_ARM32_D31,
+    RETURN_OFFSET = 0,
+  };
+
+  __dso_hidden Registers_arm32();
+
+  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_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 <= REGNO_ARM32_SPSR;
+  }
+
+  uint64_t getRegister(int num) const {
+    assert(validRegister(num));
+    return reg[num];
+  }
+
+  void setRegister(int num, uint64_t value) {
+    assert(validRegister(num));
+    reg[num] = value;
+  }
+
+  uint64_t getIP() const { return reg[REGNO_ARM32_R15]; }
+
+  void setIP(uint64_t value) { reg[REGNO_ARM32_R15] = value; }
+
+  uint64_t getSP() const { return reg[REGNO_ARM32_SP]; }
+
+  void setSP(uint64_t value) { reg[REGNO_ARM32_SP] = value; }
+
+  bool validFloatVectorRegister(int num) const {
+    return (num >= REGNO_ARM32_D0 && num <= REGNO_ARM32_D31);
+  }
+
+  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];
+};
+
+enum {
+  DWARF_VAX_R0 = 0,
+  DWARF_VAX_R15 = 15,
+  DWARF_VAX_PSW = 16,
+
+  REGNO_VAX_R0 = 0,
+  REGNO_VAX_R14 = 14,
+  REGNO_VAX_R15 = 15,
+  REGNO_VAX_PSW = 16,
+};
+
+class Registers_vax {
+public:
+  enum {
+    LAST_REGISTER = REGNO_VAX_PSW,
+    LAST_RESTORE_REG = REGNO_VAX_PSW,
+    RETURN_OFFSET = 0,
+  };
+
+  __dso_hidden Registers_vax();
+
+  static int dwarf2regno(int num) {
+    if (num >= DWARF_VAX_R0 && num <= DWARF_VAX_R15)
+      return REGNO_VAX_R0 + (num - DWARF_VAX_R0);
+    if (num == DWARF_VAX_PSW)
+      return REGNO_VAX_PSW;
+    return LAST_REGISTER + 1;
+  }
+
+  bool validRegister(int num) const {
+    return num >= 0 && num <= LAST_RESTORE_REG;
+  }
+
+  uint64_t getRegister(int num) const {
+    assert(validRegister(num));
+    return reg[num];
+  }
+
+  void setRegister(int num, uint64_t value) {
+    assert(validRegister(num));
+    reg[num] = value;
+  }
+
+  uint64_t getIP() const { return reg[REGNO_VAX_R15]; }
+
+  void setIP(uint64_t value) { reg[REGNO_VAX_R15] = value; }
+
+  uint64_t getSP() const { return reg[REGNO_VAX_R14]; }
+
+  void setSP(uint64_t value) { reg[REGNO_VAX_R14] = value; }
+
+  bool validFloatVectorRegister(int num) const {
+    return false;
+  }
+
+  void copyFloatVectorRegister(int num, uint64_t addr_) {
+  }
+
+  __dso_hidden void jumpto() const __dead;
+
+private:
+  uint32_t reg[REGNO_VAX_PSW + 1];
+};
+
+enum {
+  DWARF_M68K_A0 = 0,
+  DWARF_M68K_A7 = 7,
+  DWARF_M68K_D0 = 8,
+  DWARF_M68K_D7 = 15,
+  DWARF_M68K_FP0 = 16,
+  DWARF_M68K_FP7 = 23,
+  DWARF_M68K_PC = 24,
+
+  REGNO_M68K_A0 = 0,
+  REGNO_M68K_A7 = 7,
+  REGNO_M68K_D0 = 8,
+  REGNO_M68K_D7 = 15,
+  REGNO_M68K_PC = 16,
+  REGNO_M68K_FP0 = 17,
+  REGNO_M68K_FP7 = 24,
+};
+
+class Registers_M68K {
+public:
+  enum {
+    LAST_REGISTER = REGNO_M68K_FP7,
+    LAST_RESTORE_REG = REGNO_M68K_FP7,
+    RETURN_OFFSET = 0,
+  };
+
+  __dso_hidden Registers_M68K();
+
+  static int dwarf2regno(int num) {
+    if (num >= DWARF_M68K_A0 && num <= DWARF_M68K_A7)
+      return REGNO_M68K_A0 + (num - DWARF_M68K_A0);
+    if (num >= DWARF_M68K_D0 && num <= DWARF_M68K_D7)
+      return REGNO_M68K_D0 + (num - DWARF_M68K_D0);
+    if (num >= DWARF_M68K_FP0 && num <= DWARF_M68K_FP7)
+      return REGNO_M68K_FP0 + (num - DWARF_M68K_FP0);
+    if (num == DWARF_M68K_PC)
+      return REGNO_M68K_PC;
+    return LAST_REGISTER + 1;
+  }
+
+  bool validRegister(int num) const {
+    return num >= 0 && num <= REGNO_M68K_PC;
+  }
+
+  uint64_t getRegister(int num) const {
+    assert(validRegister(num));
+    return reg[num];
+  }
+
+  void setRegister(int num, uint64_t value) {
+    assert(validRegister(num));
+    reg[num] = value;
+  }
+
+  uint64_t getIP() const { return reg[REGNO_M68K_PC]; }
+
+  void setIP(uint64_t value) { reg[REGNO_M68K_PC] = value; }
+
+  uint64_t getSP() const { return reg[REGNO_M68K_A7]; }
+
+  void setSP(uint64_t value) { reg[REGNO_M68K_A7] = value; }
+
+  bool validFloatVectorRegister(int num) const {
+    return num >= REGNO_M68K_FP0 && num <= REGNO_M68K_FP7;
+  }
+
+  void copyFloatVectorRegister(int num, uint64_t addr_) {
+    assert(validFloatVectorRegister(num));
+    const void *addr = reinterpret_cast<const void *>(addr_);
+    memcpy(fpreg + (num - REGNO_M68K_FP0), addr, sizeof(fpreg[0]));
+  }
+
+  __dso_hidden void jumpto() const __dead;
+
+private:
+  typedef uint32_t fpreg_t[3];
+
+  uint32_t reg[REGNO_M68K_PC + 1];
+  uint32_t dummy;
+  fpreg_t fpreg[8];
+};
+
+enum {
+  DWARF_SH3_R0 = 0,
+  DWARF_SH3_R15 = 15,
+  DWARF_SH3_PC = 16,
+  DWARF_SH3_PR = 17,
+
+  REGNO_SH3_R0 = 0,
+  REGNO_SH3_R15 = 15,
+  REGNO_SH3_PC = 16,
+  REGNO_SH3_PR = 17,
+};
+
+class Registers_SH3 {
+public:
+  enum {
+    LAST_REGISTER = REGNO_SH3_PR,
+    LAST_RESTORE_REG = REGNO_SH3_PR,
+    RETURN_OFFSET = 0,
+  };
+
+  __dso_hidden Registers_SH3();
+
+  static int dwarf2regno(int num) {
+    if (num >= DWARF_SH3_R0 && num <= DWARF_SH3_R15)
+      return REGNO_SH3_R0 + (num - DWARF_SH3_R0);
+    if (num == DWARF_SH3_PC)
+      return REGNO_SH3_PC;
+    if (num == DWARF_SH3_PR)
+      return REGNO_SH3_PR;
+    return LAST_REGISTER + 1;
+  }
+
+  bool validRegister(int num) const {
+    return num >= 0 && num <= REGNO_SH3_PR;
+  }
+
+  uint64_t getRegister(int num) const {
+    assert(validRegister(num));
+    return reg[num];
+  }
+
+  void setRegister(int num, uint64_t value) {
+    assert(validRegister(num));
+    reg[num] = value;
+  }
+
+  uint64_t getIP() const { return reg[REGNO_SH3_PC]; }
+
+  void setIP(uint64_t value) { reg[REGNO_SH3_PC] = value; }
+
+  uint64_t getSP() const { return reg[REGNO_SH3_R15]; }
+
+  void setSP(uint64_t value) { reg[REGNO_SH3_R15] = value; }
+
+  bool validFloatVectorRegister(int num) const { return false; }
+
+  void copyFloatVectorRegister(int num, uint64_t addr_) {}
+
+  __dso_hidden void jumpto() const __dead;
+
+private:
+  uint32_t reg[REGNO_SH3_PR + 1];
+};
+
+enum {
+  DWARF_SPARC64_R0 = 0,
+  DWARF_SPARC64_R31 = 31,
+  DWARF_SPARC64_PC = 32,
+
+  REGNO_SPARC64_R0 = 0,
+  REGNO_SPARC64_R14 = 14,
+  REGNO_SPARC64_R15 = 15,
+  REGNO_SPARC64_R31 = 31,
+  REGNO_SPARC64_PC = 32,
+};
+
+class Registers_SPARC64 {
+public:
+  enum {
+    LAST_REGISTER = REGNO_SPARC64_PC,
+    LAST_RESTORE_REG = REGNO_SPARC64_PC,
+    RETURN_OFFSET = 8,
+  };
+  typedef uint64_t reg_t;
+
+  __dso_hidden Registers_SPARC64();
+
+  static int dwarf2regno(int num) {
+    if (num >= DWARF_SPARC64_R0 && num <= DWARF_SPARC64_R31)
+      return REGNO_SPARC64_R0 + (num - DWARF_SPARC64_R0);
+    if (num == DWARF_SPARC64_PC)
+      return REGNO_SPARC64_PC;
+    return LAST_REGISTER + 1;
+  }
+
+  bool validRegister(int num) const {
+    return num >= 0 && num <= REGNO_SPARC64_PC;
+  }
+
+  uint64_t getRegister(int num) const {
+    assert(validRegister(num));
+    return reg[num];
+  }
+
+  void setRegister(int num, uint64_t value) {
+    assert(validRegister(num));
+    reg[num] = value;
+  }
+
+  uint64_t getIP() const { return reg[REGNO_SPARC64_PC]; }
+
+  void setIP(uint64_t value) { reg[REGNO_SPARC64_PC] = value; }
+
+  uint64_t getSP() const { return reg[REGNO_SPARC64_R14]; }
+
+  void setSP(uint64_t value) { reg[REGNO_SPARC64_R14] = value; }
+
+  bool validFloatVectorRegister(int num) const { return false; }
+
+  void copyFloatVectorRegister(int num, uint64_t addr_) {}
+
+  __dso_hidden void jumpto() const __dead;
+
+private:
+  uint64_t reg[REGNO_SPARC64_PC + 1];
+};
+
+enum {
+  DWARF_SPARC_R0 = 0,
+  DWARF_SPARC_R31 = 31,
+  DWARF_SPARC_PC = 32,
+
+  REGNO_SPARC_R0 = 0,
+  REGNO_SPARC_R14 = 14,
+  REGNO_SPARC_R15 = 15,
+  REGNO_SPARC_R31 = 31,
+  REGNO_SPARC_PC = 32,
+};
+
+class Registers_SPARC {
+public:
+  enum {
+    LAST_REGISTER = REGNO_SPARC_PC,
+    LAST_RESTORE_REG = REGNO_SPARC_PC,
+    RETURN_OFFSET = 8,
+  };
+  typedef uint32_t reg_t;
+
+  __dso_hidden Registers_SPARC();
+
+  static int dwarf2regno(int num) {
+    if (num >= DWARF_SPARC_R0 && num <= DWARF_SPARC_R31)
+      return REGNO_SPARC_R0 + (num - DWARF_SPARC_R0);
+    if (num == DWARF_SPARC_PC)
+      return REGNO_SPARC_PC;
+    return LAST_REGISTER + 1;
+  }
+
+  bool validRegister(int num) const {
+    return num >= 0 && num <= REGNO_SPARC_PC;
+  }
+
+  uint64_t getRegister(int num) const {
+    assert(validRegister(num));
+    return reg[num];
+  }
+
+  void setRegister(int num, uint64_t value) {
+    assert(validRegister(num));
+    reg[num] = value;
+  }
+
+  uint64_t getIP() const { return reg[REGNO_SPARC_PC]; }
+
+  void setIP(uint64_t value) { reg[REGNO_SPARC_PC] = value; }
+
+  uint64_t getSP() const { return reg[REGNO_SPARC_R14]; }
+
+  void setSP(uint64_t value) { reg[REGNO_SPARC_R14] = value; }
+
+  bool validFloatVectorRegister(int num) const { return false; }
+
+  void copyFloatVectorRegister(int num, uint64_t addr_) {}
+
+  __dso_hidden void jumpto() const __dead;
+
+private:
+  uint32_t reg[REGNO_SPARC_PC + 1];
+};
+
+enum {
+  DWARF_ALPHA_R0 = 0,
+  DWARF_ALPHA_R30 = 30,
+  DWARF_ALPHA_F0 = 32,
+  DWARF_ALPHA_F30 = 62,
+
+  REGNO_ALPHA_R0 = 0,
+  REGNO_ALPHA_R26 = 26,
+  REGNO_ALPHA_R30 = 30,
+  REGNO_ALPHA_PC = 31,
+  REGNO_ALPHA_F0 = 32,
+  REGNO_ALPHA_F30 = 62,
+};
+
+class Registers_Alpha {
+public:
+  enum {
+    LAST_REGISTER = REGNO_ALPHA_F30,
+    LAST_RESTORE_REG = REGNO_ALPHA_F30,
+    RETURN_OFFSET = 0,
+  };
+  typedef uint32_t reg_t;
+
+  __dso_hidden Registers_Alpha();
+
+  static int dwarf2regno(int num) { return num; }
+
+  bool validRegister(int num) const {
+    return num >= 0 && num <= REGNO_ALPHA_PC;
+  }
+
+  uint64_t getRegister(int num) const {
+    assert(validRegister(num));
+    return reg[num];
+  }
+
+  void setRegister(int num, uint64_t value) {
+    assert(validRegister(num));
+    reg[num] = value;
+  }
+
+  uint64_t getIP() const { return reg[REGNO_ALPHA_PC]; }
+
+  void setIP(uint64_t value) { reg[REGNO_ALPHA_PC] = value; }
+
+  uint64_t getSP() const { return reg[REGNO_ALPHA_R30]; }
+
+  void setSP(uint64_t value) { reg[REGNO_ALPHA_R30] = value; }
+
+  bool validFloatVectorRegister(int num) const {
+    return num >= REGNO_ALPHA_F0 && num <= REGNO_ALPHA_F30;
+  }
+
+  void copyFloatVectorRegister(int num, uint64_t addr_) {
+    assert(validFloatVectorRegister(num));
+    const void *addr = reinterpret_cast<const void *>(addr_);
+    memcpy(fpreg + (num - REGNO_ALPHA_F0), addr, sizeof(fpreg[0]));
+  }
+
+  __dso_hidden void jumpto() const __dead;
+
+private:
+  uint64_t reg[REGNO_ALPHA_PC + 1];
+  uint64_t fpreg[31];
+};
+
+enum {
+  DWARF_HPPA_R1 = 1,
+  DWARF_HPPA_R31 = 31,
+  DWARF_HPPA_FR4L = 32,
+  DWARF_HPPA_FR31H = 87,
+
+  REGNO_HPPA_PC = 0,
+  REGNO_HPPA_R1 = 1,
+  REGNO_HPPA_R2 = 2,
+  REGNO_HPPA_R30 = 30,
+  REGNO_HPPA_R31 = 31,
+  REGNO_HPPA_FR4L = 32,
+  REGNO_HPPA_FR31H = 87,
+};
+
+class Registers_HPPA {
+public:
+  enum {
+    LAST_REGISTER = REGNO_HPPA_FR31H,
+    LAST_RESTORE_REG = REGNO_HPPA_FR31H,
+    RETURN_OFFSET = -3, // strictly speaking, this is a mask
+  };
+
+  __dso_hidden Registers_HPPA();
+
+  static int dwarf2regno(int num) {
+    if (num >= DWARF_HPPA_R1 && num <= DWARF_HPPA_R31)
+      return REGNO_HPPA_R1 + (num - DWARF_HPPA_R1);
+    if (num >= DWARF_HPPA_FR4L && num <= DWARF_HPPA_FR31H)
+      return REGNO_HPPA_FR4L + (num - DWARF_HPPA_FR31H);
+    return LAST_REGISTER + 1;
+  }
+
+  bool validRegister(int num) const {
+    return num >= REGNO_HPPA_PC && num <= REGNO_HPPA_R31;
+  }
+
+  uint64_t getRegister(int num) const {
+    assert(validRegister(num));
+    return reg[num];
+  }
+
+  void setRegister(int num, uint64_t value) {
+    assert(validRegister(num));
+    reg[num] = value;
+  }
+
+  uint64_t getIP() const { return reg[REGNO_HPPA_PC]; }
+
+  void setIP(uint64_t value) { reg[REGNO_HPPA_PC] = value; }
+
+  uint64_t getSP() const { return reg[REGNO_HPPA_R30]; }
+
+  void setSP(uint64_t value) { reg[REGNO_HPPA_R30] = value; }
+
+  bool validFloatVectorRegister(int num) const {
+    return num >= REGNO_HPPA_FR4L && num <= REGNO_HPPA_FR31H;
+  }
+
+  void copyFloatVectorRegister(int num, uint64_t addr_) {
+    assert(validFloatVectorRegister(num));
+    const void *addr = reinterpret_cast<const void *>(addr_);
+    memcpy(fpreg + (num - REGNO_HPPA_FR4L), addr, sizeof(fpreg[0]));
+  }
+
+  __dso_hidden void jumpto() const __dead;
+
+private:
+  uint32_t reg[REGNO_HPPA_R31 + 1];
+  uint32_t fpreg[56];
+};
+
+enum {
+  DWARF_MIPS_R1 = 0,
+  DWARF_MIPS_R31 = 31,
+  DWARF_MIPS_F0 = 32,
+  DWARF_MIPS_F31 = 63,
+
+  REGNO_MIPS_PC = 0,
+  REGNO_MIPS_R1 = 0,
+  REGNO_MIPS_R29 = 29,
+  REGNO_MIPS_R31 = 31,
+  REGNO_MIPS_F0 = 33,
+  REGNO_MIPS_F31 = 64
+};
+
+class Registers_MIPS {
+public:
+  enum {
+    LAST_REGISTER = REGNO_MIPS_F31,
+    LAST_RESTORE_REG = REGNO_MIPS_F31,
+    RETURN_OFFSET = 0,
+  };
+
+  __dso_hidden Registers_MIPS();
+
+  static int dwarf2regno(int num) {
+    if (num >= DWARF_MIPS_R1 && num <= DWARF_MIPS_R31)
+      return REGNO_MIPS_R1 + (num - DWARF_MIPS_R1);
+    if (num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31)
+      return REGNO_MIPS_F0 + (num - DWARF_MIPS_F0);
+    return LAST_REGISTER + 1;
+  }
+
+  bool validRegister(int num) const {
+    return num >= REGNO_MIPS_PC && num <= REGNO_MIPS_R31;
+  }
+
+  uint64_t getRegister(int num) const {
+    assert(validRegister(num));
+    return reg[num];
+  }
+
+  void setRegister(int num, uint64_t value) {
+    assert(validRegister(num));
+    reg[num] = value;
+  }
+
+  uint64_t getIP() const { return reg[REGNO_MIPS_PC]; }
+
+  void setIP(uint64_t value) { reg[REGNO_MIPS_PC] = value; }
+
+  uint64_t getSP() const { return reg[REGNO_MIPS_R29]; }
+
+  void setSP(uint64_t value) { reg[REGNO_MIPS_R29] = value; }
+
+  bool validFloatVectorRegister(int num) const {
+    return num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31;
+  }
+
+  void copyFloatVectorRegister(int num, uint64_t addr_) {
+    assert(validFloatVectorRegister(num));
+    const void *addr = reinterpret_cast<const void *>(addr_);
+    memcpy(fpreg + (num - REGNO_MIPS_F0), addr, sizeof(fpreg[0]));
+  }
+
+  __dso_hidden void jumpto() const __dead;
+
+private:
+  uint32_t reg[REGNO_MIPS_R31 + 1];
+  uint64_t fpreg[32];
+};
+
+enum {
+  DWARF_MIPS64_R1 = 0,
+  DWARF_MIPS64_R31 = 31,
+  DWARF_MIPS64_F0 = 32,
+  DWARF_MIPS64_F31 = 63,
+
+  REGNO_MIPS64_PC = 0,
+  REGNO_MIPS64_R1 = 0,
+  REGNO_MIPS64_R29 = 29,
+  REGNO_MIPS64_R31 = 31,
+  REGNO_MIPS64_F0 = 33,
+  REGNO_MIPS64_F31 = 64
+};
+
+class Registers_MIPS64 {
+public:
+  enum {
+    LAST_REGISTER = REGNO_MIPS64_F31,
+    LAST_RESTORE_REG = REGNO_MIPS64_F31,
+    RETURN_OFFSET = 0,
+  };
+
+  __dso_hidden Registers_MIPS64();
+
+  static int dwarf2regno(int num) {
+    if (num >= DWARF_MIPS64_R1 && num <= DWARF_MIPS64_R31)
+      return REGNO_MIPS64_R1 + (num - DWARF_MIPS64_R1);
+    if (num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31)
+      return REGNO_MIPS64_F0 + (num - DWARF_MIPS64_F0);
+    return LAST_REGISTER + 1;
+  }
+
+  bool validRegister(int num) const {
+    return num >= REGNO_MIPS64_PC && num <= REGNO_MIPS64_R31;
+  }
+
+  uint64_t getRegister(int num) const {
+    assert(validRegister(num));
+    return reg[num];
+  }
+
+  void setRegister(int num, uint64_t value) {
+    assert(validRegister(num));
+    reg[num] = value;
+  }
+
+  uint64_t getIP() const { return reg[REGNO_MIPS64_PC]; }
+
+  void setIP(uint64_t value) { reg[REGNO_MIPS64_PC] = value; }
+
+  uint64_t getSP() const { return reg[REGNO_MIPS64_R29]; }
+
+  void setSP(uint64_t value) { reg[REGNO_MIPS64_R29] = value; }
+
+  bool validFloatVectorRegister(int num) const {
+    return num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31;
+  }
+
+  void copyFloatVectorRegister(int num, uint64_t addr_) {
+    assert(validFloatVectorRegister(num));
+    const void *addr = reinterpret_cast<const void *>(addr_);
+    memcpy(fpreg + (num - REGNO_MIPS64_F0), addr, sizeof(fpreg[0]));
+  }
+
+  __dso_hidden void jumpto() const __dead;
+
+private:
+  uint64_t reg[REGNO_MIPS64_R31 + 1];
+  uint64_t fpreg[32];
+};
+
+#if __i386__
+typedef Registers_x86 NativeUnwindRegisters;
+#elif __x86_64__
+typedef Registers_x86_64 NativeUnwindRegisters;
+#elif __powerpc__
+typedef Registers_ppc32 NativeUnwindRegisters;
+#elif __arm__
+typedef Registers_arm32 NativeUnwindRegisters;
+#elif __vax__
+typedef Registers_vax NativeUnwindRegisters;
+#elif __m68k__
+typedef Registers_M68K NativeUnwindRegisters;
+#elif __mips_n64 || __mips_n32
+typedef Registers_MIPS64 NativeUnwindRegisters;
+#elif __mips__
+typedef Registers_MIPS NativeUnwindRegisters;
+#elif __sh3__
+typedef Registers_SH3 NativeUnwindRegisters;
+#elif __sparc64__
+typedef Registers_SPARC64 NativeUnwindRegisters;
+#elif __sparc__
+typedef Registers_SPARC NativeUnwindRegisters;
+#elif __alpha__
+typedef Registers_Alpha NativeUnwindRegisters;
+#elif __hppa__
+typedef Registers_HPPA NativeUnwindRegisters;
+#endif
 } // namespace _Unwind
 
 #endif // __REGISTERS_HPP__
index 2c094674bd4147dbc414e62a83975210cd8bb773..32052f1befffae4602591327a732a0d511671a9d 100644 (file)
@@ -63,6 +63,9 @@ public:
       this->setInfoBasedOnIPRegister(true);
       if (fUnwindInfoMissing)
         return UNW_STEP_END;
+
+      if (fInfo.extra_args)
+        setSP(getSP() + fInfo.extra_args);
       return UNW_STEP_SUCCESS;
     }
     __builtin_unreachable();
@@ -134,7 +137,6 @@ void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) {
   fInfo.handler = cieInfo.personality;
   fInfo.extra_args = prolog.spExtraArgSize;
   fInfo.unwind_info = fdeInfo.fdeStart;
-  fInfo.unwind_info_size = fdeInfo.fdeLength;
 }
 
 }; // namespace _Unwind
index 30f579e86f677c125e9cde01e56333110188d51d..8cdb86371b58616b26417444405d906f1bfc860d 100644 (file)
 
 using namespace _Unwind;
 
-#if __i386__
-typedef Registers_x86 ThisUnwindRegisters;
-#elif __x86_64__
-typedef Registers_x86_64 ThisUnwindRegisters;
-#elif __powerpc__
-typedef Registers_ppc32 ThisUnwindRegisters;
-#else
-#error Unsupported architecture
-#endif
-
-typedef CFI_Parser<LocalAddressSpace, ThisUnwindRegisters> MyCFIParser;
+typedef CFI_Parser<LocalAddressSpace, NativeUnwindRegisters> MyCFIParser;
 
 // Internal object representing the address space of this process.
 static LocalAddressSpace sThisAddressSpace(MyCFIParser::findPCRange);
 
-typedef UnwindCursor<LocalAddressSpace, ThisUnwindRegisters> ThisUnwindCursor;
+typedef UnwindCursor<LocalAddressSpace, NativeUnwindRegisters> ThisUnwindCursor;
 
 static _Unwind_Reason_Code unwind_phase1(ThisUnwindCursor &cursor,
                                          struct _Unwind_Exception *exc) {
@@ -197,7 +187,7 @@ static _Unwind_Reason_Code unwind_phase2_forced(ThisUnwindCursor &cursor,
 }
 
 _Unwind_Reason_Code _Unwind_RaiseException(struct _Unwind_Exception *exc) {
-  ThisUnwindRegisters registers;
+  NativeUnwindRegisters registers;
   ThisUnwindCursor cursor1(registers, sThisAddressSpace);
   ThisUnwindCursor cursor2(registers, sThisAddressSpace);
 
@@ -216,7 +206,7 @@ _Unwind_Reason_Code _Unwind_RaiseException(struct _Unwind_Exception *exc) {
 
 _Unwind_Reason_Code _Unwind_ForcedUnwind(struct _Unwind_Exception *exc,
                                          _Unwind_Stop_Fn stop, void *stop_arg) {
-  ThisUnwindRegisters registers;
+  NativeUnwindRegisters registers;
   ThisUnwindCursor cursor(registers, sThisAddressSpace);
 
   // Mark this as forced unwind for _Unwind_Resume().
@@ -227,7 +217,7 @@ _Unwind_Reason_Code _Unwind_ForcedUnwind(struct _Unwind_Exception *exc,
 }
 
 void _Unwind_Resume(struct _Unwind_Exception *exc) {
-  ThisUnwindRegisters registers;
+  NativeUnwindRegisters registers;
   ThisUnwindCursor cursor(registers, sThisAddressSpace);
 
   if (exc->private_1 != 0)
@@ -273,17 +263,18 @@ uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) {
   return cursor->getIP();
 }
 
+uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context, int *isSignalFrame) {
+  ThisUnwindCursor *cursor = (ThisUnwindCursor *)context;
+  *isSignalFrame = cursor->isSignalFrame() ? 1 : 0;
+  return cursor->getIP();
+}
+
 void _Unwind_SetIP(struct _Unwind_Context *context, uintptr_t new_value) {
   ThisUnwindCursor *cursor = (ThisUnwindCursor *)context;
   cursor->setIP(new_value);
   unw_proc_info_t info;
   cursor->getInfo(&info);
-  uint64_t orgArgSize = info.extra_args;
-  uint64_t orgFuncStart = info.start_ip;
   cursor->setInfoBasedOnIPRegister(false);
-  // Adjust REG_SP if there was a DW_CFA_GNU_args_size.
-  if (orgFuncStart == info.start_ip && orgArgSize != 0)
-    cursor->setSP(cursor->getSP() + orgArgSize);
 }
 
 uintptr_t _Unwind_GetRegionStart(struct _Unwind_Context *context) {
@@ -301,7 +292,7 @@ uintptr_t _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) {
 }
 
 _Unwind_Reason_Code _Unwind_Backtrace(_Unwind_Trace_Fn callback, void *ref) {
-  ThisUnwindRegisters registers;
+  NativeUnwindRegisters registers;
   ThisUnwindCursor cursor(registers, sThisAddressSpace);
   cursor.setInfoBasedOnIPRegister();
 
@@ -327,7 +318,7 @@ uintptr_t _Unwind_GetCFA(struct _Unwind_Context *context) {
 }
 
 void *_Unwind_FindEnclosingFunction(void *pc) {
-  ThisUnwindRegisters registers;
+  NativeUnwindRegisters registers;
   ThisUnwindCursor cursor(registers, sThisAddressSpace);
 
   unw_proc_info_t info;
index c89b01f87ee66587ba7017f98d106945051b2079..498bb75830c93447e973fd8446006ef9eac2031a 100644 (file)
@@ -67,6 +67,7 @@ void _Unwind_DeleteException(struct _Unwind_Exception *);
 uintptr_t _Unwind_GetGR(struct _Unwind_Context *, int);
 void _Unwind_SetGR(struct _Unwind_Context *, int, uintptr_t);
 uintptr_t _Unwind_GetIP(struct _Unwind_Context *);
+uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *, int *);
 uintptr_t _Unwind_GetCFA(struct _Unwind_Context *);
 void _Unwind_SetIP(struct _Unwind_Context *, uintptr_t);
 uintptr_t _Unwind_GetRegionStart(struct _Unwind_Context *);
index b87f1638015dc7bc54b23aeba8052eb12d3a1c74..a4dcfadde63ccf6b1443e65700ed4ddf9372f2ee 100644 (file)
@@ -116,6 +116,7 @@ ENTRY(_ZNK7_Unwind16Registers_x86_646jumptoEv)
 #ifdef __powerpc__
        .hidden _ZN7_Unwind15Registers_ppc32C1Ev
 ENTRY(_ZN7_Unwind15Registers_ppc32C1Ev)
+       /* TODO: skip non-callee-safe registers */
        stw              %r0,  0(%r3)
        stw              %r1,  4(%r3)
        stw              %r2,  8(%r3)
@@ -148,21 +149,82 @@ ENTRY(_ZN7_Unwind15Registers_ppc32C1Ev)
        stw             %r29,116(%r3)
        stw             %r30,120(%r3)
        stw             %r31,124(%r3)
-
-       mfcr            %r0
-       stw             %r0, 128(%r3) /* CR */
        mflr            %r0
-       stw             %r0, 132(%r3) /* LR */
-       stw             %r0, 144(%r3) /* LR */
-       mfctr           %r0
-       stw             %r0, 136(%r3) /* CTR */
-       mfxer           %r0
-       stw             %r0, 140(%r3) /*  XER */
+       stw             %r0, 136(%r3) /* SRR0 */
+       mfcr            %r0
+       stw             %r0, 132(%r3) /* CR */
+
+       stfd             %f0, 144(%r3)
+       stfd             %f1, 152(%r3)
+       stfd             %f2, 160(%r3)
+       stfd             %f3, 168(%r3)
+       stfd             %f4, 176(%r3)
+       stfd             %f5, 184(%r3)
+       stfd             %f6, 192(%r3)
+       stfd             %f7, 200(%r3)
+       stfd             %f8, 208(%r3)
+       stfd             %f9, 216(%r3)
+       stfd            %f10, 224(%r3)
+       stfd            %f11, 232(%r3)
+       stfd            %f12, 240(%r3)
+       stfd            %f13, 248(%r3)
+       stfd            %f14, 256(%r3)
+       stfd            %f15, 264(%r3)
+       stfd            %f16, 272(%r3)
+       stfd            %f17, 280(%r3)
+       stfd            %f18, 288(%r3)
+       stfd            %f19, 296(%r3)
+       stfd            %f20, 304(%r3)
+       stfd            %f21, 312(%r3)
+       stfd            %f22, 320(%r3)
+       stfd            %f23, 328(%r3)
+       stfd            %f24, 336(%r3)
+       stfd            %f25, 344(%r3)
+       stfd            %f26, 352(%r3)
+       stfd            %f27, 360(%r3)
+       stfd            %f28, 368(%r3)
+       stfd            %f29, 376(%r3)
+       stfd            %f30, 384(%r3)
+       stfd            %f31, 392(%r3)
 
+       /* LR is undefined */
        blr
 
        .hidden _ZNK7_Unwind15Registers_ppc326jumptoEv
 ENTRY(_ZNK7_Unwind15Registers_ppc326jumptoEv)
+       lfd              %f0, 144(%r3)
+       lfd              %f1, 152(%r3)
+       lfd              %f2, 160(%r3)
+       lfd              %f3, 168(%r3)
+       lfd              %f4, 176(%r3)
+       lfd              %f5, 184(%r3)
+       lfd              %f6, 192(%r3)
+       lfd              %f7, 200(%r3)
+       lfd              %f8, 208(%r3)
+       lfd              %f9, 216(%r3)
+       lfd             %f10, 224(%r3)
+       lfd             %f11, 232(%r3)
+       lfd             %f12, 240(%r3)
+       lfd             %f13, 248(%r3)
+       lfd             %f14, 256(%r3)
+       lfd             %f15, 264(%r3)
+       lfd             %f16, 272(%r3)
+       lfd             %f17, 280(%r3)
+       lfd             %f18, 288(%r3)
+       lfd             %f19, 296(%r3)
+       lfd             %f20, 304(%r3)
+       lfd             %f21, 312(%r3)
+       lfd             %f22, 320(%r3)
+       lfd             %f23, 328(%r3)
+       lfd             %f24, 336(%r3)
+       lfd             %f25, 344(%r3)
+       lfd             %f26, 352(%r3)
+       lfd             %f27, 360(%r3)
+       lfd             %f28, 368(%r3)
+       lfd             %f29, 376(%r3)
+       lfd             %f30, 384(%r3)
+       lfd             %f31, 392(%r3)
+
        lwz              %r2, 8(%r3)
        /* skip r3 for now */
        lwz              %r4, 16(%r3)
@@ -194,19 +256,931 @@ ENTRY(_ZNK7_Unwind15Registers_ppc326jumptoEv)
        lwz             %r30,120(%r3)
        lwz             %r31,124(%r3)
 
-       lwz             %r0, 128(%r3) /* CR */
-       mtcr            %r0
-       lwz             %r0, 132(%r3) /* LR */
+       lwz             %r0, 128(%r3) /* LR */
        mtlr            %r0
-       lwz             %r0, 136(%r3) /* CTR */
-       mtctr           %r0
-       lwz             %r0, 140(%r3) /*  XER */
-       mtxer           %r0
-       lwz             %r0, 144(%r3) /* SRR0 ? */
+       lwz             %r0, 132(%r3) /* CR */
+       mtcr            %r0
+       lwz             %r0, 136(%r3) /* SRR0 */
        mtctr           %r0
 
-       lwz             %r0, 0(%r3)   /* do r0 now */
-       lwz             %r1,4(%r3)    /* do sp now */
-       lwz             %r3,12(%r3)   /* do r3 last */
+       lwz             %r0,  0(%r3)   /* do r0 now */
+       lwz             %r1,  4(%r3)   /* do sp now */
+       lwz             %r3, 12(%r3)   /* do r3 last */
        bctr
 #endif
+
+#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}
+       RET
+END(_ZN7_Unwind15Registers_arm328lazyVFP1Ev)
+
+       .hidden _ZN7_Unwind15Registers_arm328lazyVFP3Ev
+ENTRY(_ZN7_Unwind15Registers_arm328lazyVFP3Ev)
+       add     r0, #200
+       vstmia  r0, {d16-d31}
+       RET
+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}
+END(_ZNK7_Unwind15Registers_arm326jumptoEv)
+#endif
+
+#if defined(__vax__)
+       .hidden _ZN7_Unwind13Registers_vaxC1Ev
+ENTRY(_ZN7_Unwind13Registers_vaxC1Ev, R0)
+       subl2   $4, %sp
+       movl    4(%ap), %r0
+       movl     %r1,  4(%r0)
+       movl     %r2,  8(%r0)
+       movl     %r3, 12(%r0)
+       movl     %r4, 16(%r0)
+       movl     %r5, 20(%r0)
+       movl     %r6, 24(%r0)
+       movl     %r7, 28(%r0)
+       movl     %r8, 32(%r0)
+       movl     %r9, 36(%r0)
+       movl    %r10, 40(%r0)
+       movl    %r11, 44(%r0)
+       movl    8(%fp), 48(%r0)
+       movl    12(%fp), 52(%r0)
+       addl3   $36, %sp, 56(%r0)
+       /* Return PC */
+       movl    16(%fp), 60(%r0)
+       /* Load saved value of r0 as r1 */
+       movl    20(%fp), 0(%r0)
+       /* Saved PSW */
+       movl    4(%fp), 64(%r0)
+       ret
+END(_ZN7_Unwind13Registers_vaxC1Ev)
+
+       .hidden _ZNK7_Unwind13Registers_vax6jumptoEv
+ENTRY(_ZNK7_Unwind13Registers_vax6jumptoEv, 0)
+       subl2   $4, %sp
+       movl     4(%ap),  %r0
+       movl     4(%r0),  %r1
+       movl     8(%r0),  %r2
+       movl    12(%r0),  %r3
+       movl    16(%r0),  %r4
+       movl    20(%r0),  %r5
+       movl    24(%r0),  %r6
+       movl    28(%r0),  %r7
+       movl    32(%r0),  %r8
+       movl    36(%r0),  %r9
+       movl    40(%r0), %r10
+       movl    44(%r0), %r11
+       movl    48(%r0), %r12
+       movl    52(%r0), %r13
+       movl    56(%r0), %r14
+       movl    60(%r0), -(%sp)
+       movl    0(%r0), %r0
+       /* XXX restore PSW */
+       rsb
+END(_ZNK7_Unwind13Registers_vax6jumptoEv)
+#endif
+
+#if defined(__m68k__)
+ENTRY(_ZN7_Unwind14Registers_M68KC1Ev)
+       move.l  4(%sp), %a0
+       movem.l %d0-%d7/%a0-%a7, (%a0)
+       fmovem  %fp0-%fp7, 72(%a0)
+       move.l  0(%sp), %a1
+       move.l  %a1, 64(%a0)
+       addq.l  #4, 60(%a0)
+       rts
+END(_ZN7_Unwind14Registers_M68KC1Ev)
+
+ENTRY(_ZNK7_Unwind14Registers_M68K6jumptoEv)
+       move.l  4(%sp), %a0
+       subq.l  #4, 60(%a0)
+       move.l  64(%a0), %a1
+       move.l  60(%a0), %a2
+       move.l  %a1, (%a2)
+       fmovem  72(%a0), %fp0-%fp7
+       movem.l (%a0), %d0-%d7/%a0-%a7
+       rts
+END(_ZNK7_Unwind14Registers_M68K6jumptoEv)
+#endif
+
+#if defined(__sh3__)
+       .hidden _ZN7_Unwind13Registers_SH3C1Ev
+ENTRY(_ZN7_Unwind13Registers_SH3C1Ev)
+       add     #64, r4
+       mov.l   r8, @-r15
+       sts.l   pr, @-r15
+       mov.l   @r15+, r8
+       mov.l   r8, @r4
+       mov.l   @r15+, r8
+
+       mov.l   r15, @-r4
+       mov.l   r14, @-r4
+       mov.l   r13, @-r4
+       mov.l   r12, @-r4
+       mov.l   r11, @-r4
+       mov.l   r10, @-r4
+       mov.l   r9, @-r4
+       mov.l   r8, @-r4
+       mov.l   r7, @-r4
+       mov.l   r6, @-r4
+       mov.l   r5, @-r4
+       add     #-4, r4
+       mov.l   r3, @-r4
+       mov.l   r2, @-r4
+       mov.l   r1, @-r4
+       mov.l   r0, @-r4
+       rts
+         mov.l r4, @(16,r4)
+SET_ENTRY_SIZE(_ZN7_Unwind13Registers_SH3C1Ev)
+
+       .hidden _ZNK7_Unwind13Registers_SH36jumptoEv
+ENTRY(_ZNK7_Unwind13Registers_SH36jumptoEv)
+       mov     r4, r0
+       add     #4, r0
+       mov.l   @r0+, r1
+       mov.l   @r0+, r2
+       mov.l   @r0+, r3
+       mov.l   @r0+, r4
+       mov.l   @r0+, r5
+       mov.l   @r0+, r6
+       mov.l   @r0+, r7
+       mov.l   @r0+, r8
+       mov.l   @r0+, r9
+       mov.l   @r0+, r10
+       mov.l   @r0+, r11
+       mov.l   @r0+, r12
+       mov.l   @r0+, r13
+       mov.l   @(12, r0), r14
+       lds     r14, pr
+       mov.l   @r0+, r14
+       mov.l   @r0+, r15
+       mov.l   @r0, r0
+       jmp     @r0
+         nop
+SET_ENTRY_SIZE(_ZNK7_Unwind13Registers_SH36jumptoEv)
+#endif
+
+#if defined(__sparc64__)
+#include <machine/trap.h>
+       .register %g2, #ignore
+       .register %g3, #ignore
+       .register %g6, #ignore
+       .register %g7, #ignore
+       .hidden _ZN7_Unwind17Registers_SPARC64C1Ev
+ENTRY(_ZN7_Unwind17Registers_SPARC64C1Ev)
+       t       ST_FLUSHWIN
+       stx     %g0, [%o0 + 0]
+       stx     %g1, [%o0 + 8]
+       stx     %g2, [%o0 + 16]
+       stx     %g3, [%o0 + 24]
+       stx     %g4, [%o0 + 32]
+       stx     %g5, [%o0 + 40]
+       stx     %g6, [%o0 + 48]
+       stx     %g7, [%o0 + 56]
+       stx     %o0, [%o0 + 64]
+       stx     %o1, [%o0 + 72]
+       stx     %o2, [%o0 + 80]
+       stx     %o3, [%o0 + 88]
+       stx     %o4, [%o0 + 96]
+       stx     %o5, [%o0 + 104]
+       stx     %o6, [%o0 + 112]
+       stx     %o7, [%o0 + 120]
+       stx     %l0, [%o0 + 128]
+       stx     %l1, [%o0 + 136]
+       stx     %l2, [%o0 + 144]
+       stx     %l3, [%o0 + 152]
+       stx     %l4, [%o0 + 160]
+       stx     %l5, [%o0 + 168]
+       stx     %l6, [%o0 + 176]
+       stx     %l7, [%o0 + 184]
+       stx     %i0, [%o0 + 192]
+       stx     %i1, [%o0 + 200]
+       stx     %i2, [%o0 + 208]
+       stx     %i3, [%o0 + 216]
+       stx     %i4, [%o0 + 224]
+       stx     %i5, [%o0 + 232]
+       stx     %i6, [%o0 + 240]
+       stx     %i7, [%o0 + 248]
+       add     %o7, 8, %g1
+       retl
+        stx    %g1, [%o0 + 256]
+END(_ZN7_Unwind17Registers_SPARC64C1Ev)
+
+       .hidden _ZNK7_Unwind17Registers_SPARC646jumptoEv
+ENTRY(_ZNK7_Unwind17Registers_SPARC646jumptoEv)
+       t       ST_FLUSHWIN
+       ldx     [%o0 + 0], %g0
+       ldx     [%o0 + 8], %g1
+       ldx     [%o0 + 16], %g2
+       ldx     [%o0 + 24], %g3
+       ldx     [%o0 + 32], %g4
+       ldx     [%o0 + 40], %g5
+       ldx     [%o0 + 48], %g6
+       ldx     [%o0 + 56], %g7
+       ldx     [%o0 + 72], %o1
+       ldx     [%o0 + 80], %o2
+       ldx     [%o0 + 88], %o3
+       ldx     [%o0 + 96], %o4
+       ldx     [%o0 + 104], %o5
+       ldx     [%o0 + 112], %g1
+       sub     %g1, 2047, %o6
+       ldx     [%o0 + 120], %o7
+       ldx     [%o0 + 128], %l0
+       ldx     [%o0 + 136], %l1
+       ldx     [%o0 + 144], %l2
+       ldx     [%o0 + 152], %l3
+       ldx     [%o0 + 160], %l4
+       ldx     [%o0 + 168], %l5
+       ldx     [%o0 + 176], %l6
+       ldx     [%o0 + 184], %l7
+       ldx     [%o0 + 192], %i0
+       ldx     [%o0 + 200], %i1
+       ldx     [%o0 + 208], %i2
+       ldx     [%o0 + 216], %i3
+       ldx     [%o0 + 224], %i4
+       ldx     [%o0 + 232], %i5
+       ldx     [%o0 + 240], %i6
+       ldx     [%o0 + 248], %i7
+       ldx     [%o0 + 256], %g1
+       jmpl    %g1, %g0
+         ldx   [%o0 + 64], %o0
+END(_ZNK7_Unwind17Registers_SPARC646jumptoEv)
+#elif defined(__sparc__)
+#include <machine/trap.h>
+
+       .hidden _ZN7_Unwind15Registers_SPARCC1Ev
+ENTRY(_ZN7_Unwind15Registers_SPARCC1Ev)
+       t       ST_FLUSHWIN
+       st      %g0, [%o0 + 0]
+       st      %g1, [%o0 + 4]
+       st      %g2, [%o0 + 8]
+       st      %g3, [%o0 + 12]
+       st      %g4, [%o0 + 16]
+       st      %g5, [%o0 + 20]
+       st      %g6, [%o0 + 24]
+       st      %g7, [%o0 + 28]
+       st      %o0, [%o0 + 32]
+       st      %o1, [%o0 + 36]
+       st      %o2, [%o0 + 40]
+       st      %o3, [%o0 + 44]
+       st      %o4, [%o0 + 48]
+       st      %o5, [%o0 + 52]
+       st      %o6, [%o0 + 56]
+       st      %o7, [%o0 + 60]
+       st      %l0, [%o0 + 64]
+       st      %l1, [%o0 + 68]
+       st      %l2, [%o0 + 72]
+       st      %l3, [%o0 + 76]
+       st      %l4, [%o0 + 80]
+       st      %l5, [%o0 + 84]
+       st      %l6, [%o0 + 88]
+       st      %l7, [%o0 + 92]
+       st      %i0, [%o0 + 96]
+       st      %i1, [%o0 + 100]
+       st      %i2, [%o0 + 104]
+       st      %i3, [%o0 + 108]
+       st      %i4, [%o0 + 112]
+       st      %i5, [%o0 + 116]
+       st      %i6, [%o0 + 120]
+       st      %i7, [%o0 + 124 ]
+       add     %o7, 8, %g1
+       retl
+        st     %g1, [%o0 + 128]
+END(_ZN7_Unwind15Registers_SPARCC1Ev)
+
+       .hidden _ZNK7_Unwind15Registers_SPARC6jumptoEv
+ENTRY(_ZNK7_Unwind15Registers_SPARC6jumptoEv)
+       t       ST_FLUSHWIN
+       ld      [%o0 + 0], %g0
+       ld      [%o0 + 4], %g1
+       ld      [%o0 + 8], %g2
+       ld      [%o0 + 12], %g3
+       ld      [%o0 + 16], %g4
+       ld      [%o0 + 20], %g5
+       ld      [%o0 + 24], %g6
+       ld      [%o0 + 28], %g7
+       ld      [%o0 + 36], %o1
+       ld      [%o0 + 40], %o2
+       ld      [%o0 + 44], %o3
+       ld      [%o0 + 48], %o4
+       ld      [%o0 + 52], %o5
+       ld      [%o0 + 56], %o6
+       ld      [%o0 + 60], %o7
+       ld      [%o0 + 64], %l0
+       ld      [%o0 + 68], %l1
+       ld      [%o0 + 72], %l2
+       ld      [%o0 + 76], %l3
+       ld      [%o0 + 80], %l4
+       ld      [%o0 + 84], %l5
+       ld      [%o0 + 88], %l6
+       ld      [%o0 + 92], %l7
+       ld      [%o0 + 96], %i0
+       ld      [%o0 + 100], %i1
+       ld      [%o0 + 104], %i2
+       ld      [%o0 + 108], %i3
+       ld      [%o0 + 112], %i4
+       ld      [%o0 + 116], %i5
+       ld      [%o0 + 120], %i6
+       ld      [%o0 + 124], %i7
+       ld      [%o0 + 128], %g1
+       jmpl    %g1, %g0
+         ld    [%o0 + 32], %o0
+END(_ZNK7_Unwind15Registers_SPARC6jumptoEv)
+#endif
+
+#if defined(__alpha__)
+       .set nomacro
+       .set noat
+       .hidden _ZN7_Unwind15Registers_AlphaC1Ev
+LEAF_NOPROFILE(_ZN7_Unwind15Registers_AlphaC1Ev, 1)
+       stq $0, 0($16)
+       stq $1, 8($16)
+       stq $2, 16($16)
+       stq $3, 24($16)
+       stq $4, 32($16)
+       stq $5, 40($16)
+       stq $6, 48($16)
+       stq $7, 56($16)
+       stq $8, 64($16)
+       stq $9, 72($16)
+       stq $10, 80($16)
+       stq $11, 88($16)
+       stq $12, 96($16)
+       stq $13, 104($16)
+       stq $14, 112($16)
+       stq $15, 120($16)
+       stq $16, 128($16)
+       stq $17, 136($16)
+       stq $18, 144($16)
+       stq $19, 152($16)
+       stq $20, 160($16)
+       stq $21, 168($16)
+       stq $22, 176($16)
+       stq $23, 184($16)
+       stq $24, 192($16)
+       stq $25, 200($16)
+       stq $26, 208($16)
+       stq $27, 216($16)
+       stq $28, 224($16)
+       stq $29, 232($16)
+       stq $30, 240($16)
+       stq $26, 248($16)
+
+       stt $f0, 256($16)
+       stt $f1, 264($16)
+       stt $f2, 272($16)
+       stt $f3, 280($16)
+       stt $f4, 288($16)
+       stt $f5, 296($16)
+       stt $f6, 304($16)
+       stt $f7, 312($16)
+       stt $f8, 320($16)
+       stt $f9, 328($16)
+       stt $f10, 336($16)
+       stt $f11, 344($16)
+       stt $f12, 352($16)
+       stt $f13, 360($16)
+       stt $f14, 368($16)
+       stt $f15, 376($16)
+       stt $f16, 384($16)
+       stt $f17, 392($16)
+       stt $f18, 400($16)
+       stt $f19, 408($16)
+       stt $f20, 416($16)
+       stt $f21, 424($16)
+       stt $f22, 432($16)
+       stt $f23, 440($16)
+       stt $f24, 448($16)
+       stt $f25, 456($16)
+       stt $f26, 464($16)
+       stt $f27, 472($16)
+       stt $f28, 480($16)
+       stt $f29, 488($16)
+       stt $f30, 496($16)
+       ret $31, ($26), 1
+END(_ZN7_Unwind15Registers_AlphaC1Ev)
+
+       .set nomacro
+       .set noat
+       .hidden _ZNK7_Unwind15Registers_Alpha6jumptoEv
+LEAF_NOPROFILE(_ZNK7_Unwind15Registers_Alpha6jumptoEv, 1)
+       ldq $0, 0($16)
+       ldq $1, 8($16)
+       ldq $2, 16($16)
+       ldq $3, 24($16)
+       ldq $4, 32($16)
+       ldq $5, 40($16)
+       ldq $6, 48($16)
+       ldq $7, 56($16)
+       ldq $8, 64($16)
+       ldq $9, 72($16)
+       ldq $10, 80($16)
+       ldq $11, 88($16)
+       ldq $12, 96($16)
+       ldq $13, 104($16)
+       ldq $14, 112($16)
+       ldq $15, 120($16)
+       ldq $17, 136($16)
+       ldq $18, 144($16)
+       ldq $19, 152($16)
+       ldq $20, 160($16)
+       ldq $21, 168($16)
+       ldq $22, 176($16)
+       ldq $23, 184($16)
+       ldq $24, 192($16)
+       ldq $25, 200($16)
+       ldq $27, 216($16)
+       ldq $28, 224($16)
+       ldq $29, 232($16)
+       ldq $30, 240($16)
+       ldq $26, 248($16)
+
+       ldt $f0, 256($16)
+       ldt $f1, 264($16)
+       ldt $f2, 272($16)
+       ldt $f3, 280($16)
+       ldt $f4, 288($16)
+       ldt $f5, 296($16)
+       ldt $f6, 304($16)
+       ldt $f7, 312($16)
+       ldt $f8, 320($16)
+       ldt $f9, 328($16)
+       ldt $f10, 336($16)
+       ldt $f11, 344($16)
+       ldt $f12, 352($16)
+       ldt $f13, 360($16)
+       ldt $f14, 368($16)
+       ldt $f15, 376($16)
+       ldt $f16, 384($16)
+       ldt $f17, 392($16)
+       ldt $f18, 400($16)
+       ldt $f19, 408($16)
+       ldt $f20, 416($16)
+       ldt $f21, 424($16)
+       ldt $f22, 432($16)
+       ldt $f23, 440($16)
+       ldt $f24, 448($16)
+       ldt $f25, 456($16)
+       ldt $f26, 464($16)
+       ldt $f27, 472($16)
+       ldt $f28, 480($16)
+       ldt $f29, 488($16)
+       ldt $f30, 496($16)
+       ldq $16, 128($16)
+       ret $31, ($26), 1
+END(_ZNK7_Unwind15Registers_Alpha6jumptoEv)
+#endif
+
+#if defined(__mips_n64) || defined(__mips_n32)
+       .set noat
+LEAF(_ZN7_Unwind16Registers_MIPS64C1Ev)
+#if 0
+       FP_S    $f0, 256($4)
+       FP_S    $f1, 264($4)
+       FP_S    $f2, 272($4)
+       FP_S    $f3, 280($4)
+       FP_S    $f4, 288($4)
+       FP_S    $f5, 296($4)
+       FP_S    $f6, 304($4)
+       FP_S    $f7, 312($4)
+       FP_S    $f8, 320($4)
+       FP_S    $f9, 328($4)
+       FP_S    $f10, 336($4)
+       FP_S    $f11, 344($4)
+       FP_S    $f12, 352($4)
+       FP_S    $f13, 360($4)
+       FP_S    $f14, 368($4)
+       FP_S    $f15, 376($4)
+       FP_S    $f16, 384($4)
+       FP_S    $f17, 392($4)
+       FP_S    $f18, 400($4)
+       FP_S    $f19, 408($4)
+       FP_S    $f20, 416($4)
+       FP_S    $f21, 424($4)
+       FP_S    $f22, 432($4)
+       FP_S    $f23, 440($4)
+       FP_S    $f24, 448($4)
+       FP_S    $f25, 456($4)
+       FP_S    $f26, 464($4)
+       FP_S    $f27, 472($4)
+       FP_S    $f28, 480($4)
+       FP_S    $f29, 488($4)
+       FP_S    $f30, 496($4)
+       FP_S    $f31, 504($4)
+#endif
+       sd      $31, 0($4)
+       sd      $1, 4($4)
+       sd      $2, 8($4)
+       sd      $3, 12($4)
+       sd      $4, 16($4)
+       sd      $5, 20($4)
+       sd      $6, 24($4)
+       sd      $7, 28($4)
+       sd      $8, 32($4)
+       sd      $9, 36($4)
+       sd      $10, 40($4)
+       sd      $11, 44($4)
+       sd      $12, 48($4)
+       sd      $13, 52($4)
+       sd      $14, 56($4)
+       sd      $15, 60($4)
+       sd      $16, 64($4)
+       sd      $17, 68($4)
+       sd      $18, 72($4)
+       sd      $19, 76($4)
+       sd      $20, 80($4)
+       sd      $21, 84($4)
+       sd      $22, 88($4)
+       sd      $23, 92($4)
+       sd      $24, 96($4)
+       sd      $25, 100($4)
+       sd      $26, 104($4)
+       sd      $27, 108($4)
+       sd      $28, 112($4)
+       sd      $29, 116($4)
+       sd      $30, 120($4)
+       sd      $31, 124($4)
+       jr      $31
+         nop
+END(_ZN7_Unwind16Registers_MIPS64C1Ev)
+
+LEAF(_ZNK7_Unwind16Registers_MIPS646jumptoEv)
+#if 0
+       FP_L    $f0, 256($4)
+       FP_L    $f1, 264($4)
+       FP_L    $f2, 272($4)
+       FP_L    $f3, 280($4)
+       FP_L    $f4, 288($4)
+       FP_L    $f5, 296($4)
+       FP_L    $f6, 304($4)
+       FP_L    $f7, 312($4)
+       FP_L    $f8, 320($4)
+       FP_L    $f9, 328($4)
+       FP_L    $f10, 336($4)
+       FP_L    $f11, 344($4)
+       FP_L    $f12, 352($4)
+       FP_L    $f13, 360($4)
+       FP_L    $f14, 368($4)
+       FP_L    $f15, 376($4)
+       FP_L    $f16, 384($4)
+       FP_L    $f17, 392($4)
+       FP_L    $f18, 400($4)
+       FP_L    $f19, 408($4)
+       FP_L    $f20, 416($4)
+       FP_L    $f21, 424($4)
+       FP_L    $f22, 432($4)
+       FP_L    $f23, 440($4)
+       FP_L    $f24, 448($4)
+       FP_L    $f25, 456($4)
+       FP_L    $f26, 464($4)
+       FP_L    $f27, 472($4)
+       FP_L    $f28, 480($4)
+       FP_L    $f29, 488($4)
+       FP_L    $f30, 496($4)
+       FP_L    $f31, 504($4)
+#endif
+
+       ld      $31, 0($4)
+       ld      $1, 8($4)
+       ld      $2, 16($4)
+       ld      $3, 24($4)
+       ld      $5, 40($4)
+       ld      $6, 48($4)
+       ld      $7, 56($4)
+       ld      $8, 64($4)
+       ld      $9, 72($4)
+       ld      $10, 80($4)
+       ld      $11, 88($4)
+       ld      $12, 96($4)
+       ld      $13, 104($4)
+       ld      $14, 112($4)
+       ld      $15, 120($4)
+       ld      $16, 128($4)
+       ld      $17, 136($4)
+       ld      $18, 144($4)
+       ld      $19, 152($4)
+       ld      $20, 160($4)
+       ld      $21, 168($4)
+       ld      $22, 176($4)
+       ld      $23, 184($4)
+       ld      $24, 192($4)
+       ld      $25, 200($4)
+       ld      $26, 208($4)
+       ld      $27, 216($4)
+       ld      $28, 224($4)
+       ld      $29, 232($4)
+       ld      $30, 240($4)
+        ld     $4, 32($4)
+       jr      $31
+         nop
+END(_ZNK7_Unwind16Registers_MIPS646jumptoEv)
+#elif defined(__mips__)
+       .set noat
+LEAF(_ZN7_Unwind14Registers_MIPSC1Ev)
+#if 0
+#if __mips > 1
+       FP_S    $f0, 128($4)
+       FP_S    $f1, 136($4)
+       FP_S    $f2, 144($4)
+       FP_S    $f3, 152($4)
+       FP_S    $f4, 160($4)
+       FP_S    $f5, 168($4)
+       FP_S    $f6, 176($4)
+       FP_S    $f7, 184($4)
+       FP_S    $f8, 192($4)
+       FP_S    $f9, 200($4)
+       FP_S    $f10, 208($4)
+       FP_S    $f11, 216($4)
+       FP_S    $f12, 224($4)
+       FP_S    $f13, 232($4)
+       FP_S    $f14, 240($4)
+       FP_S    $f15, 248($4)
+       FP_S    $f16, 256($4)
+       FP_S    $f17, 264($4)
+       FP_S    $f18, 272($4)
+       FP_S    $f19, 280($4)
+       FP_S    $f20, 288($4)
+       FP_S    $f21, 296($4)
+       FP_S    $f22, 304($4)
+       FP_S    $f23, 312($4)
+       FP_S    $f24, 320($4)
+       FP_S    $f25, 328($4)
+       FP_S    $f26, 336($4)
+       FP_S    $f27, 344($4)
+       FP_S    $f28, 352($4)
+       FP_S    $f29, 360($4)
+       FP_S    $f30, 368($4)
+       FP_S    $f31, 376($4)
+#endif
+#endif
+       sw      $31, 0($4)
+       sw      $1, 4($4)
+       sw      $2, 8($4)
+       sw      $3, 12($4)
+       sw      $4, 16($4)
+       sw      $5, 20($4)
+       sw      $6, 24($4)
+       sw      $7, 28($4)
+       sw      $8, 32($4)
+       sw      $9, 36($4)
+       sw      $10, 40($4)
+       sw      $11, 44($4)
+       sw      $12, 48($4)
+       sw      $13, 52($4)
+       sw      $14, 56($4)
+       sw      $15, 60($4)
+       sw      $16, 64($4)
+       sw      $17, 68($4)
+       sw      $18, 72($4)
+       sw      $19, 76($4)
+       sw      $20, 80($4)
+       sw      $21, 84($4)
+       sw      $22, 88($4)
+       sw      $23, 92($4)
+       sw      $24, 96($4)
+       sw      $25, 100($4)
+       sw      $26, 104($4)
+       sw      $27, 108($4)
+       sw      $28, 112($4)
+       sw      $29, 116($4)
+       sw      $30, 120($4)
+       sw      $31, 124($4)
+       jr      $31
+         nop
+END(_ZN7_Unwind14Registers_MIPSC1Ev)
+
+LEAF(_ZNK7_Unwind14Registers_MIPS6jumptoEv)
+#if 0
+#if __mips > 1
+       FP_L    $f0, 128($4)
+       FP_L    $f1, 136($4)
+       FP_L    $f2, 144($4)
+       FP_L    $f3, 152($4)
+       FP_L    $f4, 160($4)
+       FP_L    $f5, 168($4)
+       FP_L    $f6, 176($4)
+       FP_L    $f7, 184($4)
+       FP_L    $f8, 192($4)
+       FP_L    $f9, 200($4)
+       FP_L    $f10, 208($4)
+       FP_L    $f11, 216($4)
+       FP_L    $f12, 224($4)
+       FP_L    $f13, 232($4)
+       FP_L    $f14, 240($4)
+       FP_L    $f15, 248($4)
+       FP_L    $f16, 256($4)
+       FP_L    $f17, 264($4)
+       FP_L    $f18, 272($4)
+       FP_L    $f19, 280($4)
+       FP_L    $f20, 288($4)
+       FP_L    $f21, 296($4)
+       FP_L    $f22, 304($4)
+       FP_L    $f23, 312($4)
+       FP_L    $f24, 320($4)
+       FP_L    $f25, 328($4)
+       FP_L    $f26, 336($4)
+       FP_L    $f27, 344($4)
+       FP_L    $f28, 352($4)
+       FP_L    $f29, 360($4)
+       FP_L    $f30, 368($4)
+       FP_L    $f31, 376($4)
+#endif
+#endif
+
+       lw      $31, 0($4)
+       lw      $1, 4($4)
+       lw      $2, 8($4)
+       lw      $3, 12($4)
+       lw      $5, 20($4)
+       lw      $6, 24($4)
+       lw      $7, 28($4)
+       lw      $8, 32($4)
+       lw      $9, 36($4)
+       lw      $10, 40($4)
+       lw      $11, 44($4)
+       lw      $12, 48($4)
+       lw      $13, 52($4)
+       lw      $14, 56($4)
+       lw      $15, 60($4)
+       lw      $16, 64($4)
+       lw      $17, 68($4)
+       lw      $18, 72($4)
+       lw      $19, 76($4)
+       lw      $20, 80($4)
+       lw      $21, 84($4)
+       lw      $22, 88($4)
+       lw      $23, 92($4)
+       lw      $24, 96($4)
+       lw      $25, 100($4)
+       lw      $26, 104($4)
+       lw      $27, 108($4)
+       lw      $28, 112($4)
+       lw      $29, 116($4)
+       lw      $30, 120($4)
+        lw     $4, 16($4)
+       jr      $31
+         nop
+END(_ZNK7_Unwind14Registers_MIPS6jumptoEv)
+#endif
+
+#if defined(__hppa__)
+LEAF_ENTRY_NOPROFILE(_ZN7_Unwind14Registers_HPPAC1Ev)
+       stw %r2, 0(%r26)
+       stw %r1, 4(%r26)
+       stw %r2, 8(%r26)
+       stw %r3, 12(%r26)
+       stw %r4, 16(%r26)
+       stw %r5, 20(%r26)
+       stw %r6, 24(%r26)
+       stw %r7, 28(%r26)
+       stw %r8, 32(%r26)
+       stw %r9, 36(%r26)
+       stw %r10, 40(%r26)
+       stw %r11, 44(%r26)
+       stw %r12, 48(%r26)
+       stw %r13, 52(%r26)
+       stw %r14, 56(%r26)
+       stw %r15, 60(%r26)
+       stw %r16, 64(%r26)
+       stw %r17, 68(%r26)
+       stw %r18, 72(%r26)
+       stw %r19, 76(%r26)
+       stw %r20, 80(%r26)
+       stw %r21, 84(%r26)
+       stw %r22, 88(%r26)
+       stw %r23, 92(%r26)
+       stw %r24, 96(%r26)
+       stw %r25, 100(%r26)
+       stw %r26, 104(%r26)
+       stw %r27, 108(%r26)
+       stw %r28, 112(%r26)
+       stw %r29, 116(%r26)
+       stw %r30, 120(%r26)
+       stw %r31, 124(%r26)
+       ldi 128, %r19
+       addl %r19, %r26, %r19
+       fstds,ma %fr4, 8(%r19)
+       fstds,ma %fr5, 8(%r19)
+       fstds,ma %fr6, 8(%r19)
+       fstds,ma %fr7, 8(%r19)
+       fstds,ma %fr8, 8(%r19)
+       fstds,ma %fr9, 8(%r19)
+       fstds,ma %fr10, 8(%r19)
+       fstds,ma %fr11, 8(%r19)
+       fstds,ma %fr12, 8(%r19)
+       fstds,ma %fr13, 8(%r19)
+       fstds,ma %fr14, 8(%r19)
+       fstds,ma %fr15, 8(%r19)
+       fstds,ma %fr16, 8(%r19)
+       fstds,ma %fr17, 8(%r19)
+       fstds,ma %fr18, 8(%r19)
+       fstds,ma %fr19, 8(%r19)
+       fstds,ma %fr20, 8(%r19)
+       fstds,ma %fr21, 8(%r19)
+       fstds,ma %fr22, 8(%r19)
+       fstds,ma %fr23, 8(%r19)
+       fstds,ma %fr24, 8(%r19)
+       fstds,ma %fr25, 8(%r19)
+       fstds,ma %fr19, 8(%r19)
+       fstds,ma %fr27, 8(%r19)
+       fstds,ma %fr28, 8(%r19)
+       fstds,ma %fr29, 8(%r19)
+       fstds,ma %fr30, 8(%r19)
+       fstds,ma %fr31, 8(%r19)
+       ldw 76(%r26), %r19
+       bv,n %r0(%r2)
+EXIT(_ZN7_Unwind14Registers_HPPAC1Ev)
+
+LEAF_ENTRY_NOPROFILE(_ZNK7_Unwind14Registers_HPPA6jumptoEv)
+       ldi 128, %r19
+       addl %r19, %r26, %r19
+       fldds,ma 8(%r19), %fr4
+       fldds,ma 8(%r19), %fr5
+       fldds,ma 8(%r19), %fr6
+       fldds,ma 8(%r19), %fr7
+       fldds,ma 8(%r19), %fr8
+       fldds,ma 8(%r19), %fr9
+       fldds,ma 8(%r19), %fr10
+       fldds,ma 8(%r19), %fr11
+       fldds,ma 8(%r19), %fr12
+       fldds,ma 8(%r19), %fr13
+       fldds,ma 8(%r19), %fr14
+       fldds,ma 8(%r19), %fr15
+       fldds,ma 8(%r19), %fr16
+       fldds,ma 8(%r19), %fr17
+       fldds,ma 8(%r19), %fr18
+       fldds,ma 8(%r19), %fr19
+       fldds,ma 8(%r19), %fr20
+       fldds,ma 8(%r19), %fr21
+       fldds,ma 8(%r19), %fr22
+       fldds,ma 8(%r19), %fr23
+       fldds,ma 8(%r19), %fr24
+       fldds,ma 8(%r19), %fr25
+       fldds,ma 8(%r19), %fr26
+       fldds,ma 8(%r19), %fr27
+       fldds,ma 8(%r19), %fr28
+       fldds,ma 8(%r19), %fr29
+       fldds,ma 8(%r19), %fr30
+       fldds,ma 8(%r19), %fr31
+       ldw 0(%r26), %r2
+       ldw 4(%r26), %r1
+       ldw 12(%r26), %r3
+       ldw 16(%r26), %r4
+       ldw 20(%r26), %r5
+       ldw 24(%r26), %r6
+       ldw 28(%r26), %r7
+       ldw 32(%r26), %r8
+       ldw 36(%r26), %r9
+       ldw 40(%r26), %r10
+       ldw 44(%r26), %r11
+       ldw 48(%r26), %r12
+       ldw 52(%r26), %r13
+       ldw 56(%r26), %r14
+       ldw 60(%r26), %r15
+       ldw 64(%r26), %r16
+       ldw 68(%r26), %r17
+       ldw 72(%r26), %r18
+       ldw 76(%r26), %r19
+       ldw 80(%r26), %r20
+       ldw 84(%r26), %r21
+       ldw 88(%r26), %r22
+       ldw 92(%r26), %r23
+       ldw 96(%r26), %r24
+       ldw 100(%r26), %r25
+       ldw 108(%r26), %r27
+       ldw 112(%r26), %r28
+       ldw 116(%r26), %r29
+       ldw 120(%r26), %r30
+       ldw 124(%r26), %r31
+       ldw 104(%r26), %r26
+       bv,n %r0(%r2)
+EXIT(_ZNK7_Unwind14Registers_HPPA6jumptoEv)
+#endif