[PATCH] D38680: [libunwind] Fix handling of DW_CFA_GNU_args_size

Martin Storsjö via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 9 02:15:31 PDT 2017

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.



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;
+      // 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 @@
     if (_unwindInfoMissing)
       return UNW_STEP_END;
-    if (_info.gp)
-      setReg(UNW_REG_SP, getReg(UNW_REG_SP) + _info.gp);
   return result;

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D38680.118188.patch
Type: text/x-patch
Size: 1179 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20171009/045255c1/attachment.bin>

More information about the cfe-commits mailing list