joerg updated this revision to Diff 150049. joerg added a comment. After a careful review of newer GCC / libgcc and the assembler annotations from LLVM, I have come to the following conclusions:
(1) The semantics have been somewhat changed by GCC in recent years. There is no actual specification, so we have to go by what behavior actually makes sense. (2) The primary motivation is still that the DW_CFA_GNU_args_size is a call-site specific annotation. It is expected to be applied when the IP is moved by the personality routine to compensate for the call site specific (temporary) adjustment. (3) It is not clear with plain unw_set_ip outside the scope of the Itanium EH handling should have this behavior, so it might need to be split into an internal routine. (4) LLVM does not produce correct CFA annotation for stdcall and similar cases where the callee removes additional stack space. The patch covers the first two items. https://reviews.llvm.org/D38680 Files: src/UnwindCursor.hpp src/libunwind.cpp Index: src/libunwind.cpp =================================================================== --- src/libunwind.cpp +++ src/libunwind.cpp @@ -188,8 +188,13 @@ 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; + co->getInfo(&info); co->setInfoBasedOnIPRegister(false); + if (info.gp) + co->setReg(UNW_REG_SP, co->getReg(UNW_REG_SP) + info.gp); + } return UNW_ESUCCESS; } return UNW_EBADREG; Index: src/UnwindCursor.hpp =================================================================== --- src/UnwindCursor.hpp +++ src/UnwindCursor.hpp @@ -1411,8 +1411,6 @@ this->setInfoBasedOnIPRegister(true); if (_unwindInfoMissing) return UNW_STEP_END; - if (_info.gp) - setReg(UNW_REG_SP, getReg(UNW_REG_SP) + _info.gp); } return result;
Index: src/libunwind.cpp =================================================================== --- src/libunwind.cpp +++ src/libunwind.cpp @@ -188,8 +188,13 @@ 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; + co->getInfo(&info); co->setInfoBasedOnIPRegister(false); + if (info.gp) + co->setReg(UNW_REG_SP, co->getReg(UNW_REG_SP) + info.gp); + } return UNW_ESUCCESS; } return UNW_EBADREG; Index: src/UnwindCursor.hpp =================================================================== --- src/UnwindCursor.hpp +++ src/UnwindCursor.hpp @@ -1411,8 +1411,6 @@ this->setInfoBasedOnIPRegister(true); if (_unwindInfoMissing) return UNW_STEP_END; - if (_info.gp) - setReg(UNW_REG_SP, getReg(UNW_REG_SP) + _info.gp); } return result;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits