diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h index 78b5000eeb7..539a1662084 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 00000000000..e050c538157 --- /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 1d8c0c55883..be42a3163b2 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; }