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