Browse Source

gcc: add a csky patch from Ramin, fixes uClibc-ng testsuite failures

Waldemar Brodkorb 3 months ago
parent
commit
d4521837fa

+ 46 - 0
toolchain/gcc/patches/13.4.0/0001-gcc-csky-define-DWARF_ALT_FRAME_RETURN_COLUMN.patch

@@ -0,0 +1,46 @@
+From: Ramin Moussavi <lordrasmus@gmail.com>
+Subject: [PATCH] gcc: csky: define DWARF_ALT_FRAME_RETURN_COLUMN for signal-frame unwinding
+
+The csky signal-frame unwinder (gcc/config/csky/linux-unwind.h) restores
+the interrupted PC into DWARF column 32. That column is not a hard
+register, so init_dwarf_reg_size_table() leaves its size as 0 in
+dwarf_reg_size_table. When the unwinder later walks through a signal
+frame, _Unwind_GetGR() reads the size of column 32, finds 0 and aborts.
+
+In practice this makes any forced unwind through a signal frame abort
+with SIGABRT. The most visible case is pthread cancellation: a thread
+cancelled while blocked in a syscall is resumed via a signal frame, and
+the cleanup unwind dies in _Unwind_GetGR() instead of running the
+cancellation handlers. All NPTL cancellation tests of the uClibc-ng test
+suite fail this way on csky.
+
+Declare column 32 as the alternate return column so
+init_dwarf_reg_size_table() sizes it. This is the same mechanism arm,
+aarch64, riscv and others already use for their signal return address
+column. With this patch the 8 cancellation tests pass on csky.
+
+The macro has never been defined for csky, so this affects every gcc
+version; the patch applies cleanly to 13.x/14.x/15.x. Reproduced and
+verified with gcc 15.2.0 (uclibcabiv2, soft-float) on qemu-system-cskyv2.
+
+Signed-off-by: Ramin Moussavi <lordrasmus@gmail.com>
+---
+ gcc/config/csky/csky.h | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/gcc/config/csky/csky.h
++++ b/gcc/config/csky/csky.h
+@@ -1007,6 +1007,13 @@
+    define DWARF_FRAME_RETURN_COLUMN to DWARF_FRAME_REGNUM.  */
+ #define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (CSKY_LR_REGNUM)
+ 
++/* Signal frames (config/csky/linux-unwind.h) put the interrupted PC in
++   DWARF column 32, which is not a hard register and thus is left unsized
++   in dwarf_reg_size_table.  Declare it as the alternate return column so
++   init_dwarf_reg_size_table sizes it; otherwise _Unwind_GetGR aborts when
++   unwinding through a signal frame (e.g. pthread cancellation).  */
++#define DWARF_ALT_FRAME_RETURN_COLUMN 32
++
+ /* Use r0 and r1 to pass exception handling information.  */
+ #define EH_RETURN_DATA_REGNO(N) ((N) < 2 ? N : INVALID_REGNUM)
+ 

+ 46 - 0
toolchain/gcc/patches/14.3.0/0001-gcc-csky-define-DWARF_ALT_FRAME_RETURN_COLUMN.patch

@@ -0,0 +1,46 @@
+From: Ramin Moussavi <lordrasmus@gmail.com>
+Subject: [PATCH] gcc: csky: define DWARF_ALT_FRAME_RETURN_COLUMN for signal-frame unwinding
+
+The csky signal-frame unwinder (gcc/config/csky/linux-unwind.h) restores
+the interrupted PC into DWARF column 32. That column is not a hard
+register, so init_dwarf_reg_size_table() leaves its size as 0 in
+dwarf_reg_size_table. When the unwinder later walks through a signal
+frame, _Unwind_GetGR() reads the size of column 32, finds 0 and aborts.
+
+In practice this makes any forced unwind through a signal frame abort
+with SIGABRT. The most visible case is pthread cancellation: a thread
+cancelled while blocked in a syscall is resumed via a signal frame, and
+the cleanup unwind dies in _Unwind_GetGR() instead of running the
+cancellation handlers. All NPTL cancellation tests of the uClibc-ng test
+suite fail this way on csky.
+
+Declare column 32 as the alternate return column so
+init_dwarf_reg_size_table() sizes it. This is the same mechanism arm,
+aarch64, riscv and others already use for their signal return address
+column. With this patch the 8 cancellation tests pass on csky.
+
+The macro has never been defined for csky, so this affects every gcc
+version; the patch applies cleanly to 13.x/14.x/15.x. Reproduced and
+verified with gcc 15.2.0 (uclibcabiv2, soft-float) on qemu-system-cskyv2.
+
+Signed-off-by: Ramin Moussavi <lordrasmus@gmail.com>
+---
+ gcc/config/csky/csky.h | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/gcc/config/csky/csky.h
++++ b/gcc/config/csky/csky.h
+@@ -1007,6 +1007,13 @@
+    define DWARF_FRAME_RETURN_COLUMN to DWARF_FRAME_REGNUM.  */
+ #define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (CSKY_LR_REGNUM)
+ 
++/* Signal frames (config/csky/linux-unwind.h) put the interrupted PC in
++   DWARF column 32, which is not a hard register and thus is left unsized
++   in dwarf_reg_size_table.  Declare it as the alternate return column so
++   init_dwarf_reg_size_table sizes it; otherwise _Unwind_GetGR aborts when
++   unwinding through a signal frame (e.g. pthread cancellation).  */
++#define DWARF_ALT_FRAME_RETURN_COLUMN 32
++
+ /* Use r0 and r1 to pass exception handling information.  */
+ #define EH_RETURN_DATA_REGNO(N) ((N) < 2 ? N : INVALID_REGNUM)
+ 

+ 46 - 0
toolchain/gcc/patches/15.2.0/0001-gcc-csky-define-DWARF_ALT_FRAME_RETURN_COLUMN.patch

@@ -0,0 +1,46 @@
+From: Ramin Moussavi <lordrasmus@gmail.com>
+Subject: [PATCH] gcc: csky: define DWARF_ALT_FRAME_RETURN_COLUMN for signal-frame unwinding
+
+The csky signal-frame unwinder (gcc/config/csky/linux-unwind.h) restores
+the interrupted PC into DWARF column 32. That column is not a hard
+register, so init_dwarf_reg_size_table() leaves its size as 0 in
+dwarf_reg_size_table. When the unwinder later walks through a signal
+frame, _Unwind_GetGR() reads the size of column 32, finds 0 and aborts.
+
+In practice this makes any forced unwind through a signal frame abort
+with SIGABRT. The most visible case is pthread cancellation: a thread
+cancelled while blocked in a syscall is resumed via a signal frame, and
+the cleanup unwind dies in _Unwind_GetGR() instead of running the
+cancellation handlers. All NPTL cancellation tests of the uClibc-ng test
+suite fail this way on csky.
+
+Declare column 32 as the alternate return column so
+init_dwarf_reg_size_table() sizes it. This is the same mechanism arm,
+aarch64, riscv and others already use for their signal return address
+column. With this patch the 8 cancellation tests pass on csky.
+
+The macro has never been defined for csky, so this affects every gcc
+version; the patch applies cleanly to 13.x/14.x/15.x. Reproduced and
+verified with gcc 15.2.0 (uclibcabiv2, soft-float) on qemu-system-cskyv2.
+
+Signed-off-by: Ramin Moussavi <lordrasmus@gmail.com>
+---
+ gcc/config/csky/csky.h | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/gcc/config/csky/csky.h
++++ b/gcc/config/csky/csky.h
+@@ -1007,6 +1007,13 @@
+    define DWARF_FRAME_RETURN_COLUMN to DWARF_FRAME_REGNUM.  */
+ #define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (CSKY_LR_REGNUM)
+ 
++/* Signal frames (config/csky/linux-unwind.h) put the interrupted PC in
++   DWARF column 32, which is not a hard register and thus is left unsized
++   in dwarf_reg_size_table.  Declare it as the alternate return column so
++   init_dwarf_reg_size_table sizes it; otherwise _Unwind_GetGR aborts when
++   unwinding through a signal frame (e.g. pthread cancellation).  */
++#define DWARF_ALT_FRAME_RETURN_COLUMN 32
++
+ /* Use r0 and r1 to pass exception handling information.  */
+ #define EH_RETURN_DATA_REGNO(N) ((N) < 2 ? N : INVALID_REGNUM)
+