summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoerg Sonnenberger <joerg@bec.de>2014-03-20 01:23:55 +0000
committerJoerg Sonnenberger <joerg@bec.de>2014-03-20 01:23:55 +0000
commit7dfc5215ff08e992ffe88c577ba15d641e610d75 (patch)
treed06427900994288ecfb7f01742d852d3ae34e0a9
parent4fb4f2286edeef6320baa9b7ad475495f95c8c56 (diff)
downloadlibcxxabi_35a-7dfc5215ff08e992ffe88c577ba15d641e610d75.tar.gz
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 unw_set_reg no longer makes sense. git-svn-id: https://llvm.org/svn/llvm-project/libcxxabi/trunk@204290 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--src/Unwind/UnwindCursor.hpp2
-rw-r--r--src/Unwind/libunwind.cpp3
2 files changed, 2 insertions, 3 deletions
diff --git a/src/Unwind/UnwindCursor.hpp b/src/Unwind/UnwindCursor.hpp
index 256a72d..235922f 100644
--- a/src/Unwind/UnwindCursor.hpp
+++ b/src/Unwind/UnwindCursor.hpp
@@ -1041,6 +1041,8 @@ int UnwindCursor<A, R>::step() {
this->setInfoBasedOnIPRegister(true);
if (_unwindInfoMissing)
return UNW_STEP_END;
+ if (_info.gp)
+ setReg(UNW_REG_SP, getReg(UNW_REG_SP) + _info.gp);
}
return result;
diff --git a/src/Unwind/libunwind.cpp b/src/Unwind/libunwind.cpp
index 2043ac2..59ff4a7 100644
--- a/src/Unwind/libunwind.cpp
+++ b/src/Unwind/libunwind.cpp
@@ -174,9 +174,6 @@ _LIBUNWIND_EXPORT int unw_set_reg(unw_cursor_t *cursor, unw_regnum_t regNum,
pint_t orgArgSize = (pint_t)info.gp;
uint64_t orgFuncStart = info.start_ip;
co->setInfoBasedOnIPRegister(false);
- // and adjust REG_SP if there was a DW_CFA_GNU_args_size
- if ((orgFuncStart == info.start_ip) && (orgArgSize != 0))
- co->setReg(UNW_REG_SP, co->getReg(UNW_REG_SP) + orgArgSize);
}
return UNW_ESUCCESS;
}