https://github.com/mstorsjo updated 
https://github.com/llvm/llvm-project/pull/137950

From fb51e2b9f4965df52940c7cc672de863f34a1773 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Storsj=C3=B6?= <mar...@martin.st>
Date: Tue, 18 Apr 2023 23:28:20 +0300
Subject: [PATCH] [libunwind] [SEH] Implement parsing of ARM pdata/xdata

This is generally very similar to the aarch64 case.

Contrary to aarch64, the public headers don't contain any definition
of a struct for interpreting this data, so we provide our own.
---
 libunwind/src/UnwindCursor.hpp | 37 ++++++++++++++++++++++++++++------
 1 file changed, 31 insertions(+), 6 deletions(-)

diff --git a/libunwind/src/UnwindCursor.hpp b/libunwind/src/UnwindCursor.hpp
index 240752e09e1ee..bc84c07af0c38 100644
--- a/libunwind/src/UnwindCursor.hpp
+++ b/libunwind/src/UnwindCursor.hpp
@@ -83,6 +83,22 @@ struct UNWIND_INFO {
   uint16_t UnwindCodes[2];
 };
 
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wgnu-anonymous-struct"
+union UNWIND_INFO_ARM {
+  DWORD HeaderData;
+  struct {
+    DWORD FunctionLength : 18;
+    DWORD Version : 2;
+    DWORD ExceptionDataPresent : 1;
+    DWORD EpilogInHeader : 1;
+    DWORD FunctionFragment : 1;
+    DWORD EpilogCount : 5;
+    DWORD CodeWords : 4;
+  };
+};
+#pragma clang diagnostic pop
+
 extern "C" _Unwind_Reason_Code __libunwind_seh_personality(
     int, _Unwind_Action, uint64_t, _Unwind_Exception *,
     struct _Unwind_Context *);
@@ -2018,9 +2034,18 @@ bool UnwindCursor<A, R>::getInfoFromSEH(pint_t pc) {
       _info.handler = 0;
     }
   }
-#elif defined(_LIBUNWIND_TARGET_AARCH64)
+#elif defined(_LIBUNWIND_TARGET_AARCH64) || defined(_LIBUNWIND_TARGET_ARM)
+
+#if defined(_LIBUNWIND_TARGET_AARCH64)
+#define FUNC_LENGTH_UNIT 4
+#define XDATA_TYPE IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA
+#else
+#define FUNC_LENGTH_UNIT 2
+#define XDATA_TYPE UNWIND_INFO_ARM
+#endif
   if (unwindEntry->Flag != 0) { // Packed unwind info
-    _info.end_ip = _info.start_ip + unwindEntry->FunctionLength * 4;
+    _info.end_ip =
+        _info.start_ip + unwindEntry->FunctionLength * FUNC_LENGTH_UNIT;
     // Only fill in the handler and LSDA if they're stale.
     if (pc != getLastPC()) {
       // Packed unwind info doesn't have an exception handler.
@@ -2028,10 +2053,9 @@ bool UnwindCursor<A, R>::getInfoFromSEH(pint_t pc) {
       _info.handler = 0;
     }
   } else {
-    IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA *xdata =
-        reinterpret_cast<IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA *>(
-            base + unwindEntry->UnwindData);
-    _info.end_ip = _info.start_ip + xdata->FunctionLength * 4;
+    XDATA_TYPE *xdata =
+        reinterpret_cast<XDATA_TYPE *>(base + unwindEntry->UnwindData);
+    _info.end_ip = _info.start_ip + xdata->FunctionLength * FUNC_LENGTH_UNIT;
     // Only fill in the handler and LSDA if they're stale.
     if (pc != getLastPC()) {
       if (xdata->ExceptionDataPresent) {
@@ -2039,6 +2063,7 @@ bool UnwindCursor<A, R>::getInfoFromSEH(pint_t pc) {
         uint32_t codeWords = xdata->CodeWords;
         uint32_t epilogScopes = xdata->EpilogCount;
         if (xdata->EpilogCount == 0 && xdata->CodeWords == 0) {
+          // The extension word has got the same layout for both ARM and ARM64
           uint32_t extensionWord = reinterpret_cast<uint32_t *>(xdata)[1];
           codeWords = (extensionWord >> 16) & 0xff;
           epilogScopes = extensionWord & 0xffff;

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to