Author: quic-k
Date: 2026-07-13T08:18:51-05:00
New Revision: 7a8b26271b273ea36c1d68c97f4c87b63de4a2bd

URL: 
https://github.com/llvm/llvm-project/commit/7a8b26271b273ea36c1d68c97f4c87b63de4a2bd
DIFF: 
https://github.com/llvm/llvm-project/commit/7a8b26271b273ea36c1d68c97f4c87b63de4a2bd.diff

LOG: [libunwind][Hexagon] Save/restore full r0-r7 in getcontext/jumpto (#208753)

The Hexagon save and restore routines dropped GPRs, producing an
incomplete context.

UnwindRegistersSave.S (__unw_getcontext): save r0-r7 (stores began at
__r[8]), drop a dead "r1 = memw(r30)" before the PC store, and return
UNW_ESUCCESS instead of a stale non-zero value.

UnwindRegistersRestore.S (jumpto): restore the missing r2-r7 (r0/r1 and
r8-r31 were already handled), and fix the stale "pointer is in r2"
comment (it is r0).

Signed-off-by: Kushal Pal <[email protected]>

Added: 
    

Modified: 
    libunwind/src/UnwindRegistersRestore.S
    libunwind/src/UnwindRegistersSave.S

Removed: 
    


################################################################################
diff  --git a/libunwind/src/UnwindRegistersRestore.S 
b/libunwind/src/UnwindRegistersRestore.S
index 8f84f4d456a35..37e8156408cf2 100644
--- a/libunwind/src/UnwindRegistersRestore.S
+++ b/libunwind/src/UnwindRegistersRestore.S
@@ -947,11 +947,22 @@ 
DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind14Registers_or1k6jumptoEv)
 
 #elif defined(__hexagon__)
 # On entry:
-#  thread_state pointer is in r2
+#  thread_state pointer is in r0
 DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind17Registers_hexagon6jumptoEv)
 #
 # void libunwind::Registers_hexagon::jumpto()
 #
+# The context layout is hexagon_thread_state_t: unsigned int __r[35]
+# __r[0..31] = r0..r31, __r[32] = predicates, __r[33] = PC.
+# Offsets: __r[n] is at byte offset n*4.  r0 is the context pointer, so
+# it is restored last; r31 is loaded with the saved PC as the jumpr target.
+  r2 = memw(r0+#8)
+  r3 = memw(r0+#12)
+  r4 = memw(r0+#16)
+  r5 = memw(r0+#20)
+  r6 = memw(r0+#24)
+  r7 = memw(r0+#28)
+
   r8 = memw(r0+#32)
   r9 = memw(r0+#36)
   r10 = memw(r0+#40)

diff  --git a/libunwind/src/UnwindRegistersSave.S 
b/libunwind/src/UnwindRegistersSave.S
index a82ebd1ead23b..f44f6a1331968 100644
--- a/libunwind/src/UnwindRegistersSave.S
+++ b/libunwind/src/UnwindRegistersSave.S
@@ -1103,8 +1103,21 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
 # On entry:
 #  thread_state pointer is in r0
 #
+# The context layout is hexagon_thread_state_t: unsigned int __r[35]
+# __r[0..31] = r0..r31, __r[32] = predicates, __r[33] = PC, __r[34] = unused
+# Offsets: __r[n] is at byte offset n*4.
+#
 #define OFFSET(offset) (offset/4)
 DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
+  // Save r1-r7 first (r0 is the context pointer, saved last)
+  memw(r0+#4)  = r1
+  memw(r0+#8)  = r2
+  memw(r0+#12) = r3
+  memw(r0+#16) = r4
+  memw(r0+#20) = r5
+  memw(r0+#24) = r6
+  memw(r0+#28) = r7
+
   memw(r0+#32) = r8
   memw(r0+#36) = r9
   memw(r0+#40) = r10
@@ -1134,12 +1147,17 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
   memw(r0+#116) = r29
   memw(r0+#120) = r30
   memw(r0+#124) = r31
-  r1 = c4   // Predicate register
+
+  r1 = c4                  // Predicate register
   memw(r0+#128) = r1
-  r1 = memw(r30)           // *FP == Saved FP
-  r1 = r31
+
+  r1 = r31                 // Store return address as PC
   memw(r0+#132) = r1
 
+  // Save r0 (the context pointer itself) last
+  memw(r0+#0) = r0
+
+  r0 = #0                  // return UNW_ESUCCESS
   jumpr r31
 
 #elif defined(__sparc__) && defined(__arch64__)


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to