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

Reply via email to