Source-Changes-HG archive

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

[src/trunk]: src/sys/lib/libunwind Fix DW_CFA_GNU_args_size handling. The pri...



details:   https://anonhg.NetBSD.org/src/rev/9d2edb7fc227
branches:  trunk
changeset: 327883:9d2edb7fc227
user:      joerg <joerg%NetBSD.org@localhost>
date:      Thu Mar 20 01:35:45 2014 +0000

description:
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.

diffstat:

 sys/lib/libunwind/UnwindCursor.hpp |  3 +++
 sys/lib/libunwind/libunwind.cxx    |  5 -----
 2 files changed, 3 insertions(+), 5 deletions(-)

diffs (29 lines):

diff -r a127545f8a28 -r 9d2edb7fc227 sys/lib/libunwind/UnwindCursor.hpp
--- a/sys/lib/libunwind/UnwindCursor.hpp        Thu Mar 20 01:15:29 2014 +0000
+++ b/sys/lib/libunwind/UnwindCursor.hpp        Thu Mar 20 01:35:45 2014 +0000
@@ -61,6 +61,9 @@
       this->setInfoBasedOnIPRegister(true);
       if (fUnwindInfoMissing)
         return UNW_STEP_END;
+
+      if (fInfo.extra_args)
+        setSP(getSP() + fInfo.extra_args);
       return UNW_STEP_SUCCESS;
     }
     __builtin_unreachable();
diff -r a127545f8a28 -r 9d2edb7fc227 sys/lib/libunwind/libunwind.cxx
--- a/sys/lib/libunwind/libunwind.cxx   Thu Mar 20 01:15:29 2014 +0000
+++ b/sys/lib/libunwind/libunwind.cxx   Thu Mar 20 01:35:45 2014 +0000
@@ -288,12 +288,7 @@
   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) {



Home | Main Index | Thread Index | Old Index