summaryrefslogtreecommitdiffstats
path: root/libunwind/src
diff options
context:
space:
mode:
authorJoerg Sonnenberger <joerg@bec.de>2018-07-17 19:00:51 +0000
committerJoerg Sonnenberger <joerg@bec.de>2018-07-17 19:00:51 +0000
commitd0166a0a9377cb3861210e9d5f2b629d77f1a97e (patch)
tree288a72952d3eb9a37762f9696954ed1b251f6e78 /libunwind/src
parent97ba3b64ddb63b216561b44ea62c0ac8c413feb7 (diff)
downloadbcm5719-llvm-d0166a0a9377cb3861210e9d5f2b629d77f1a97e.tar.gz
bcm5719-llvm-d0166a0a9377cb3861210e9d5f2b629d77f1a97e.zip
The semantics of DW_CFA_GNU_args_size have changed subtile over the
years. Adopt the new convention that it is call-site specific and that it should be applied before moving the IP by personality routines, but not during normal unwinding. Differential Revision: https://reviews.llvm.org/D38680 llvm-svn: 337312
Diffstat (limited to 'libunwind/src')
-rw-r--r--libunwind/src/UnwindCursor.hpp2
-rw-r--r--libunwind/src/libunwind.cpp14
2 files changed, 13 insertions, 3 deletions
diff --git a/libunwind/src/UnwindCursor.hpp b/libunwind/src/UnwindCursor.hpp
index 6b99c38a6cc..0be4cd98944 100644
--- a/libunwind/src/UnwindCursor.hpp
+++ b/libunwind/src/UnwindCursor.hpp
@@ -1411,8 +1411,6 @@ 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/libunwind/src/libunwind.cpp b/libunwind/src/libunwind.cpp
index a3bcfb5db1d..3bd8ef15ac6 100644
--- a/libunwind/src/libunwind.cpp
+++ b/libunwind/src/libunwind.cpp
@@ -188,8 +188,20 @@ _LIBUNWIND_EXPORT int unw_set_reg(unw_cursor_t *cursor, unw_regnum_t regNum,
co->setReg(regNum, (pint_t)value);
// specical case altering IP to re-find info (being called by personality
// function)
- if (regNum == UNW_REG_IP)
+ if (regNum == UNW_REG_IP) {
+ unw_proc_info_t info;
+ // First, get the FDE for the old location and then update it.
+ co->getInfo(&info);
co->setInfoBasedOnIPRegister(false);
+ // If the original call expects stack adjustment, perform this now.
+ // Normal frame unwinding would have included the offset already in the
+ // CFA computation.
+ // Note: for PA-RISC and other platforms where the stack grows up,
+ // this should actually be - info.gp. LLVM doesn't currently support
+ // any such platforms and Clang doesn't export a macro for them.
+ if (info.gp)
+ co->setReg(UNW_REG_SP, co->getReg(UNW_REG_SP) + info.gp);
+ }
return UNW_ESUCCESS;
}
return UNW_EBADREG;
OpenPOWER on IntegriCloud