mstorsjo created this revision. This effectively reverts SVN r204290 and r204292 (back when this code was part of libcxxabi).
According to SVN r204290, the primary architecture using the DW_CFA_GNU_args_size opcode is VAX. However, clang also produces it on X86 when it has done X86CallFrameOptimization, which gets done much more frequently if the stack is aligned to 4 bytes (which is the default when targeting windows). This issue can be tested by building code for x86 linux (at least for 32 bit) with clang with -mstack-alignment=4. I'm not sure if this code should be handled differently for VAX with some ifdef, or what the correct interpretation of this opcode is. I ran into this issue while trying to use libunwind for 32 bit windows (where clang uses a 4 byte stack alignment by default), found this commit, and noticed I got it working by reverting it. And later noticed I could reproduce the same issue on 32 bit x86 linux as well, by forcing -mstack-alignment=4. https://reviews.llvm.org/D38680 Files: src/UnwindCursor.hpp src/libunwind.cpp Index: src/libunwind.cpp =================================================================== --- src/libunwind.cpp +++ src/libunwind.cpp @@ -182,8 +182,16 @@ 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); + 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; } return UNW_EBADREG; Index: src/UnwindCursor.hpp =================================================================== --- src/UnwindCursor.hpp +++ src/UnwindCursor.hpp @@ -1356,8 +1356,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 @@ -182,8 +182,16 @@ 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); + 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; } return UNW_EBADREG; Index: src/UnwindCursor.hpp =================================================================== --- src/UnwindCursor.hpp +++ src/UnwindCursor.hpp @@ -1356,8 +1356,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