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

Reply via email to