summaryrefslogtreecommitdiffstats
path: root/libcxxabi/src
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
commit1ed1a3d9944121dfe64781e427764012dc3711a2 (patch)
tree6493dbde321c5f414796c25b540c657e7dd0d4c0 /libcxxabi/src
parentfcd974a1ed094ab5d73792c23b45421a428756f1 (diff)
downloadbcm5719-llvm-1ed1a3d9944121dfe64781e427764012dc3711a2.tar.gz
bcm5719-llvm-1ed1a3d9944121dfe64781e427764012dc3711a2.zip
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. llvm-svn: 204290
Diffstat (limited to 'libcxxabi/src')
-rw-r--r--libcxxabi/src/Unwind/UnwindCursor.hpp2
-rw-r--r--libcxxabi/src/Unwind/libunwind.cpp3
2 files changed, 2 insertions, 3 deletions
diff --git a/libcxxabi/src/Unwind/UnwindCursor.hpp b/libcxxabi/src/Unwind/UnwindCursor.hpp
index 256a72da677..235922f7188 100644
--- a/libcxxabi/src/Unwind/UnwindCursor.hpp
+++ b/libcxxabi/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/libcxxabi/src/Unwind/libunwind.cpp b/libcxxabi/src/Unwind/libunwind.cpp
index 2043ac23ed2..59ff4a70f17 100644
--- a/libcxxabi/src/Unwind/libunwind.cpp
+++ b/libcxxabi/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;
}
OpenPOWER on IntegriCloud