Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / libc++abi / trunk / src / Unwind / DwarfInstructions.hpp
index 158bad8..dbce2e8 100644 (file)
@@ -63,33 +63,17 @@ private:
   static v128 getSavedVectorRegister(A &addressSpace, const R &registers,
                                   pint_t cfa, const RegisterLocation &savedReg);
 
-  // x86 specific variants
-  static int lastRestoreReg(const Registers_x86 &);
-  static bool isReturnAddressRegister(int regNum, const Registers_x86 &);
   static pint_t getCFA(A &addressSpace, const PrologInfo &prolog,
-                       const Registers_x86 &);
-
-  // x86_64 specific variants
-  static int lastRestoreReg(const Registers_x86_64 &);
-  static bool isReturnAddressRegister(int regNum, const Registers_x86_64 &);
-  static pint_t getCFA(A &addressSpace,
-                       const PrologInfo &prolog,
-                       const Registers_x86_64 &);
-
-  // ppc specific variants
-  static int lastRestoreReg(const Registers_ppc &);
-  static bool isReturnAddressRegister(int regNum, const Registers_ppc &);
-  static pint_t getCFA(A &addressSpace,
-                       const PrologInfo &prolog,
-                       const Registers_ppc &);
-
-  // arm64 specific variants
-  static bool isReturnAddressRegister(int regNum, const Registers_arm64 &);
-  static int lastRestoreReg(const Registers_arm64 &);
-  static pint_t getCFA(A &addressSpace,
-                       const PrologInfo &prolog,
-                       const Registers_arm64 &);
-
+                       const R &registers) {
+    if (prolog.cfaRegister != 0)
+      return (pint_t)((sint_t)registers.getRegister((int)prolog.cfaRegister) +
+             prolog.cfaRegisterOffset);
+    if (prolog.cfaExpression != 0)
+      return evaluateExpression((pint_t)prolog.cfaExpression, addressSpace, 
+                                registers, 0);
+    assert(0 && "getCFA(): unknown location");
+    __builtin_unreachable();
+  }
 };
 
 
@@ -177,17 +161,21 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
     PrologInfo prolog;
     if (CFI_Parser<A>::parseFDEInstructions(addressSpace, fdeInfo, cieInfo, pc,
                                                                      &prolog)) {
-      R newRegisters = registers;
-
       // get pointer to cfa (architecture specific)
       pint_t cfa = getCFA(addressSpace, prolog, registers);
 
-      // restore registers that dwarf says were saved
+       // restore registers that dwarf says were saved
+      R newRegisters = registers;
       pint_t returnAddress = 0;
-      for (int i = 0; i <= lastRestoreReg(newRegisters); ++i) {
-        if (prolog.savedRegisters[i].location !=
-            CFI_Parser<A>::kRegisterUnused) {
-          if (registers.validFloatRegister(i))
+      const int lastReg = R::lastDwarfRegNum();
+      assert((int)CFI_Parser<A>::kMaxRegisterNumber > lastReg
+                                                && "register range too large");
+      assert(lastReg <= (int)cieInfo.returnAddressRegister
+                 && "register range does not contain return address register");
+      for (int i = 0; i <= lastReg; ++i) {
+         if (prolog.savedRegisters[i].location !=
+             CFI_Parser<A>::kRegisterUnused) {
+           if (registers.validFloatRegister(i))
             newRegisters.setFloatRegister(
                 i, getSavedFloatRegister(addressSpace, registers, cfa,
                                          prolog.savedRegisters[i]));
@@ -195,7 +183,7 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
             newRegisters.setVectorRegister(
                 i, getSavedVectorRegister(addressSpace, registers, cfa,
                                           prolog.savedRegisters[i]));
-          else if (isReturnAddressRegister(i, registers))
+          else if (i == (int)cieInfo.returnAddressRegister)
             returnAddress = getSavedRegister(addressSpace, registers, cfa,
                                              prolog.savedRegisters[i]);
           else if (registers.validRegister(i))
@@ -764,123 +752,6 @@ DwarfInstructions<A, R>::evaluateExpression(pint_t expression, A &addressSpace,
   return *sp;
 }
 
-//
-//  x86_64 specific functions
-//
-template <typename A, typename R>
-int DwarfInstructions<A, R>::lastRestoreReg(const Registers_x86_64 &) {
-  static_assert((int)CFI_Parser<A>::kMaxRegisterNumber
-              > (int)DW_X86_64_RET_ADDR, "register number out of range");
-  return DW_X86_64_RET_ADDR;
-}
-
-template <typename A, typename R>
-bool
-DwarfInstructions<A, R>::isReturnAddressRegister(int regNum,
-                                                 const Registers_x86_64 &) {
-  return (regNum == DW_X86_64_RET_ADDR);
-}
-
-template <typename A, typename R>
-typename A::pint_t DwarfInstructions<A, R>::getCFA(
-    A &addressSpace, const PrologInfo &prolog,
-    const Registers_x86_64 &registers) {
-  if (prolog.cfaRegister != 0)
-    return (pint_t)((sint_t)registers.getRegister((int)prolog.cfaRegister)
-                                                    + prolog.cfaRegisterOffset);
-  else if (prolog.cfaExpression != 0)
-    return evaluateExpression((pint_t)prolog.cfaExpression, addressSpace, registers, 0);
-  else
-    _LIBUNWIND_ABORT("getCFA(): unknown location for x86_64 cfa");
-}
-
-
-//
-//  x86 specific functions
-//
-template <typename A, typename R>
-int DwarfInstructions<A, R>::lastRestoreReg(const Registers_x86 &) {
-  static_assert((int)CFI_Parser<A>::kMaxRegisterNumber
-              > (int)DW_X86_RET_ADDR, "register number out of range");
-  return DW_X86_RET_ADDR;
-}
-
-template <typename A, typename R>
-bool DwarfInstructions<A, R>::isReturnAddressRegister(int regNum,
-                                                      const Registers_x86 &) {
-  return (regNum == DW_X86_RET_ADDR);
-}
-
-template <typename A, typename R>
-typename A::pint_t DwarfInstructions<A, R>::getCFA(
-    A &addressSpace, const PrologInfo &prolog,
-    const Registers_x86 &registers) {
-  if (prolog.cfaRegister != 0)
-    return (pint_t)((sint_t)registers.getRegister((int)prolog.cfaRegister)
-                                                    + prolog.cfaRegisterOffset);
-  else if (prolog.cfaExpression != 0)
-    return evaluateExpression((pint_t)prolog.cfaExpression, addressSpace,
-                                                                  registers, 0);
-  else
-    _LIBUNWIND_ABORT("getCFA(): unknown location for x86 cfa");
-}
-
-
-//
-//  ppc specific functions
-//
-template <typename A, typename R>
-int DwarfInstructions<A, R>::lastRestoreReg(const Registers_ppc &) {
-  static_assert((int)CFI_Parser<A>::kMaxRegisterNumber
-              > (int)UNW_PPC_SPEFSCR, "register number out of range");
-  return UNW_PPC_SPEFSCR;
-}
-
-template <typename A, typename R>
-bool DwarfInstructions<A, R>::isReturnAddressRegister(int regNum,
-                                                      const Registers_ppc &) {
-  return (regNum == UNW_PPC_LR);
-}
-
-template <typename A, typename R>
-typename A::pint_t DwarfInstructions<A, R>::getCFA(
-    A &addressSpace, const PrologInfo &prolog,
-    const Registers_ppc &registers) {
-  if (prolog.cfaRegister != 0)
-    return registers.getRegister(prolog.cfaRegister) + prolog.cfaRegisterOffset;
-  else if (prolog.cfaExpression != 0)
-    return evaluateExpression((pint_t)prolog.cfaExpression, addressSpace,
-                                                                  registers, 0);
-  else
-    _LIBUNWIND_ABORT("getCFA(): unknown location for ppc cfa");
-}
-
-
-
-//
-// arm64 specific functions
-//
-template <typename A, typename R>
-bool DwarfInstructions<A, R>::isReturnAddressRegister(int regNum,
-                                                      const Registers_arm64 &) {
-  return (regNum == UNW_ARM64_LR);
-}
-
-template <typename A, typename R>
-int DwarfInstructions<A, R>::lastRestoreReg(const Registers_arm64 &) {
-  static_assert((int)CFI_Parser<A>::kMaxRegisterNumber
-              > (int)UNW_ARM64_D31, "register number out of range");
-  return UNW_ARM64_D31;
-}
-
-template <typename A, typename R>
-typename A::pint_t DwarfInstructions<A, R>::getCFA(A&, const PrologInfo &prolog,
-                                             const Registers_arm64 &registers) {
-  if (prolog.cfaRegister != 0)
-    return registers.getRegister(prolog.cfaRegister) + prolog.cfaRegisterOffset;
-  else
-    _LIBUNWIND_ABORT("getCFA(): unsupported location for arm64 cfa");
-}
 
 
 } // namespace libunwind