From 68a650ba57a446fef31722cc2d5ac0752dc1b531 Mon Sep 17 00:00:00 2001 From: Claudiu Zissulescu Date: Wed, 5 Jan 2022 15:22:10 +0200 Subject: [PATCH] arc: Add DWARF2 alternate CFA column. Add DWARF 2 CFA column which tracks the return address from a signal handler context. This value must not correspond to a hard register and must be out of the range of DWARF_FRAME_REGNUM(). gcc/ * config/arc/arc.h (DWARF_FRAME_REGNUM): Update definition. (DWARF_FRAME_RETURN_COLUMN): Use RETURN_ADDR_REGNUM macro. (INCOMING_RETURN_ADDR_RTX): Likewise. (DWARF_ALT_FRAME_RETURN_COLUMN): Define. gcc/testsuite/ * gcc.target/arc/cancel-1.c: New file. libgcc/ * config/arc/linux-unwind.h (arc_fallback_frame_state): Use DWARF_ALT_FRAME_RETURN_COLUMN macro. Signed-off-by: Claudiu Zissulescu --- gcc/config/arc/arc.h | 11 ++++++++--- gcc/testsuite/gcc.target/arc/cancel-1.c | 31 +++++++++++++++++++++++++++++++ libgcc/config/arc/linux-unwind.h | 9 +++++---- 3 files changed, 44 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gcc.target/arc/cancel-1.c diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h index 78b5000..539a166 100644 --- a/gcc/config/arc/arc.h +++ b/gcc/config/arc/arc.h @@ -1356,7 +1356,7 @@ do { \ : (REGNO)) /* Use gcc hard register numbering for eh_frame. */ -#define DWARF_FRAME_REGNUM(REG) (REG) +#define DWARF_FRAME_REGNUM(REG) ((REG) < 144 ? REG : INVALID_REGNUM) /* Map register numbers held in the call frame info that gcc has collected using DWARF_FRAME_REGNUM to those that should be output @@ -1370,9 +1370,14 @@ do { \ : 57 + !!TARGET_MULMAC_32BY16_SET) /* MLO */ \ : (REGNO)) -#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (31) +/* The DWARF 2 CFA column which tracks the return address. */ +#define DWARF_FRAME_RETURN_COLUMN RETURN_ADDR_REGNUM +#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM) -#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, 31) +/* The DWARF 2 CFA column which tracks the return address from a signal handler + context. This value must not correspond to a hard register and must be out + of the range of DWARF_FRAME_REGNUM(). */ +#define DWARF_ALT_FRAME_RETURN_COLUMN 144 /* Frame info. */ diff --git a/gcc/testsuite/gcc.target/arc/cancel-1.c b/gcc/testsuite/gcc.target/arc/cancel-1.c new file mode 100644 index 0000000..e050c53 --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/cancel-1.c @@ -0,0 +1,31 @@ +/* Test for cleanups with pthread_cancel. Any issue with libgcc's unwinder + will cause this test to spin in pthread_join. */ + +/* { dg-do run } */ +/* { dg-require-effective-target pthread } */ +/* { dg-options "-pthread" } */ + +#include +#include +#include + +void *thread_loop (void *) +{ + while (1) + { + printf("worker: loop\n"); + sleep(1); + } +} + +int main () +{ + pthread_t thread; + + pthread_create (&thread, 0, thread_loop, 0); + sleep(5); + pthread_cancel (thread); + pthread_join (thread, 0); + + return 0; +} diff --git a/libgcc/config/arc/linux-unwind.h b/libgcc/config/arc/linux-unwind.h index 1d8c0c5..be42a31 100644 --- a/libgcc/config/arc/linux-unwind.h +++ b/libgcc/config/arc/linux-unwind.h @@ -120,10 +120,11 @@ arc_fallback_frame_state (struct _Unwind_Context *context, = ((_Unwind_Ptr) &(regs[i])) - new_cfa; } - fs->regs.reg[31].how = REG_SAVED_VAL_OFFSET; - fs->regs.reg[31].loc.offset = ((_Unwind_Ptr) (regs[ret])) - new_cfa; - - fs->retaddr_column = 31; + fs->signal_frame = 1; + fs->retaddr_column = __LIBGCC_DWARF_ALT_FRAME_RETURN_COLUMN__; + fs->regs.reg[fs->retaddr_column].how = REG_SAVED_VAL_OFFSET; + fs->regs.reg[fs->retaddr_column].loc.offset = + ((_Unwind_Ptr) (regs[ret])) - new_cfa; return _URC_NO_REASON; } -- 2.7.4