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
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits