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 _Unwind_SetIP no longer makes sense.
This commit is contained in:
parent
5c08b734f4
commit
1fad0e91e1
|
@ -61,6 +61,9 @@ public:
|
|||
this->setInfoBasedOnIPRegister(true);
|
||||
if (fUnwindInfoMissing)
|
||||
return UNW_STEP_END;
|
||||
|
||||
if (fInfo.extra_args)
|
||||
setSP(getSP() + fInfo.extra_args);
|
||||
return UNW_STEP_SUCCESS;
|
||||
}
|
||||
__builtin_unreachable();
|
||||
|
|
|
@ -288,12 +288,7 @@ void _Unwind_SetIP(struct _Unwind_Context *context, uintptr_t new_value) {
|
|||
cursor->setIP(new_value);
|
||||
unw_proc_info_t info;
|
||||
cursor->getInfo(&info);
|
||||
uint64_t orgArgSize = info.extra_args;
|
||||
uint64_t orgFuncStart = info.start_ip;
|
||||
cursor->setInfoBasedOnIPRegister(false);
|
||||
// Adjust REG_SP if there was a DW_CFA_GNU_args_size.
|
||||
if (orgFuncStart == info.start_ip && orgArgSize != 0)
|
||||
cursor->setSP(cursor->getSP() + orgArgSize);
|
||||
}
|
||||
|
||||
uintptr_t _Unwind_GetRegionStart(struct _Unwind_Context *context) {
|
||||
|
|
Loading…
Reference in New Issue