Module Name:    src
Committed By:   joerg
Date:           Thu Mar 20 01:35:45 UTC 2014

Modified Files:
        src/sys/lib/libunwind: UnwindCursor.hpp libunwind.cxx

Log Message:
Fix DW_CFA_GNU_args_size handling. The primary architecture using this
opcode is VAX. A function call pushes the number of arguments given onto
the stack and "ret" will pop it automatically. The FDE of the caller
contains the amount of stack space used for arguments (and possibly
extra padding), so unwinding has to compensate for this when "returning"
from a function. This is exactly the case when step() is done. The
existing handling in _Unwind_SetIP no longer makes sense.


To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 src/sys/lib/libunwind/UnwindCursor.hpp
cvs rdiff -u -r1.4 -r1.5 src/sys/lib/libunwind/libunwind.cxx

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/lib/libunwind/UnwindCursor.hpp
diff -u src/sys/lib/libunwind/UnwindCursor.hpp:1.1 src/sys/lib/libunwind/UnwindCursor.hpp:1.2
--- src/sys/lib/libunwind/UnwindCursor.hpp:1.1	Mon Oct 14 01:14:57 2013
+++ src/sys/lib/libunwind/UnwindCursor.hpp	Thu Mar 20 01:35:45 2014
@@ -61,6 +61,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();

Index: src/sys/lib/libunwind/libunwind.cxx
diff -u src/sys/lib/libunwind/libunwind.cxx:1.4 src/sys/lib/libunwind/libunwind.cxx:1.5
--- src/sys/lib/libunwind/libunwind.cxx:1.4	Tue Mar 18 13:08:15 2014
+++ src/sys/lib/libunwind/libunwind.cxx	Thu Mar 20 01:35:45 2014
@@ -288,12 +288,7 @@ void _Unwind_SetIP(struct _Unwind_Contex
   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) {

Reply via email to