This is the mail archive of the
libc-ports@sources.redhat.com
mailing list for the libc-ports project.
LinuxThreads unwind info for MIPS
- From: Daniel Jacobowitz <drow at false dot org>
- To: libc-ports at sourceware dot org
- Date: Wed, 3 Dec 2008 12:09:02 -0500
- Subject: LinuxThreads unwind info for MIPS
I don't anticipate the LinuxThreads module being used again, but
here's a patch I developed for an older toolchain. It applied
cleanly, so I've committed it for posterity. This fixes backtrace()
and GDB backtraces across system calls in multi-threaded MIPS Linux
applications, using LinuxThreads.
--
Daniel Jacobowitz
CodeSourcery
2008-11-24 Daniel Jacobowitz <dan@codesourcery.com>
linuxthreads/
* sysdeps/unix/sysv/linux/mips/mips64/sysdep-cancel.h,
sysdeps/unix/sysv/linux/mips/sysdep-cancel.h: Add CFI data.
---
linuxthreads/sysdeps/unix/sysv/linux/mips/mips64/sysdep-cancel.h | 41 ++++++++--
linuxthreads/sysdeps/unix/sysv/linux/mips/sysdep-cancel.h | 26 ++++--
2 files changed, 50 insertions(+), 17 deletions(-)
Index: glibc-2.3.3/linuxthreads/sysdeps/unix/sysv/linux/mips/mips64/sysdep-cancel.h
===================================================================
--- glibc-2.3.3.orig/linuxthreads/sysdeps/unix/sysv/linux/mips/mips64/sysdep-cancel.h 2004-08-24 22:55:34.000000000 -0700
+++ glibc-2.3.3/linuxthreads/sysdeps/unix/sysv/linux/mips/mips64/sysdep-cancel.h 2008-11-24 08:46:40.000000000 -0800
@@ -25,6 +25,16 @@
#endif
#include <sys/asm.h>
+/* Gas will put the initial save of $gp into the CIE, because it appears to
+ happen before any instructions. So we use cfi_same_value instead of
+ cfi_restore. */
+
+#ifdef HAVE_ASM_CFI_DIRECTIVES
+# define cfi_same_value .cfi_same_value
+#else
+# define cfi_same_value
+#endif
+
#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
#ifdef __PIC__
@@ -32,14 +42,19 @@
# define PSEUDO(name, syscall_name, args) \
.align 2; \
99: \
+ cfi_startproc; \
+ cfi_adjust_cfa_offset (STKSPACE); \
+ cfi_rel_offset (gp, STKOFF_GP); \
PTR_LA t9,__syscall_error; \
/* manual cpreturn. */ \
REG_L gp, STKOFF_GP(sp); \
+ cfi_same_value (gp); \
RESTORESTK ; \
jr t9; \
ENTRY (name) \
SAVESTK ; \
.cpsetup t9, STKOFF_GP, name ; \
+ cfi_rel_offset (gp, STKOFF_GP); \
.set reorder; \
SINGLE_THREAD_P(t0); \
bne zero, t0, L(pseudo_cancel); \
@@ -50,10 +65,14 @@
bne a3, zero, SYSCALL_ERROR_LABEL; \
/* manual cpreturn. */ \
REG_L gp, STKOFF_GP(sp); \
+ cfi_same_value (gp); \
RESTORESTK ; \
ret; \
L(pseudo_cancel): \
+ cfi_adjust_cfa_offset (STKSPACE); \
+ cfi_rel_offset (gp, STKOFF_GP); \
REG_S ra, STKOFF_RA(sp); \
+ cfi_rel_offset (ra, STKOFF_RA); \
PUSHARGS_##args; /* save syscall args */ \
CENABLE; \
REG_S v0, STKOFF_SVMSK(sp); /* save mask */ \
@@ -72,17 +91,23 @@
bne a3, zero, SYSCALL_ERROR_LABEL; \
/* manual cpreturn. */ \
REG_L gp, STKOFF_GP(sp); \
+ cfi_same_value (gp); \
RESTORESTK ; \
L(pseudo_end):
+
+
+# undef PSEUDO_END
+# define PSEUDO_END(sym) cfi_endproc; .end sym; .size sym,.-sym
+
#endif
# define PUSHARGS_0 /* nothing to do */
-# define PUSHARGS_1 PUSHARGS_0 REG_S a0, STKOFF_A0(sp);
-# define PUSHARGS_2 PUSHARGS_1 REG_S a1, STKOFF_A1(sp);
-# define PUSHARGS_3 PUSHARGS_2 REG_S a2, STKOFF_A2(sp);
-# define PUSHARGS_4 PUSHARGS_3 REG_S a3, STKOFF_A3(sp);
-# define PUSHARGS_5 PUSHARGS_4 REG_S a4, STKOFF_A4(sp);
-# define PUSHARGS_6 PUSHARGS_5 REG_S a5, STKOFF_A5(sp);
+# define PUSHARGS_1 PUSHARGS_0 REG_S a0, STKOFF_A0(sp); cfi_rel_offset (a0, STKOFF_A0);
+# define PUSHARGS_2 PUSHARGS_1 REG_S a1, STKOFF_A1(sp); cfi_rel_offset (a1, STKOFF_A1);
+# define PUSHARGS_3 PUSHARGS_2 REG_S a2, STKOFF_A2(sp); cfi_rel_offset (a2, STKOFF_A2);
+# define PUSHARGS_4 PUSHARGS_3 REG_S a3, STKOFF_A3(sp); cfi_rel_offset (a3, STKOFF_A3);
+# define PUSHARGS_5 PUSHARGS_4 REG_S a4, STKOFF_A4(sp); cfi_rel_offset (a3, STKOFF_A4);
+# define PUSHARGS_6 PUSHARGS_5 REG_S a5, STKOFF_A5(sp); cfi_rel_offset (a3, STKOFF_A5);
# define POPARGS_0 /* nothing to do */
# define POPARGS_1 POPARGS_0 REG_L a0, STKOFF_A0(sp);
@@ -112,8 +137,8 @@
# define STKOFF_GP (STKOFF_SVMSK + SZREG) /* Always used. */
# define STKSPACE (STKOFF_GP + SZREG)
-# define SAVESTK PTR_SUBU sp, STKSPACE
-# define RESTORESTK PTR_ADDU sp, STKSPACE
+# define SAVESTK PTR_SUBU sp, STKSPACE; cfi_adjust_cfa_offset(STKSPACE)
+# define RESTORESTK PTR_ADDU sp, STKSPACE; cfi_adjust_cfa_offset(-STKSPACE)
# ifdef IS_IN_libpthread
# define CENABLE PTR_LA t9, __pthread_enable_asynccancel; jalr t9;
Index: glibc-2.3.3/linuxthreads/sysdeps/unix/sysv/linux/mips/sysdep-cancel.h
===================================================================
--- glibc-2.3.3.orig/linuxthreads/sysdeps/unix/sysv/linux/mips/sysdep-cancel.h 2008-11-24 08:27:01.000000000 -0800
+++ glibc-2.3.3/linuxthreads/sysdeps/unix/sysv/linux/mips/sysdep-cancel.h 2008-11-24 08:45:55.000000000 -0800
@@ -28,9 +28,11 @@
# undef PSEUDO
# define PSEUDO(name, syscall_name, args) \
.align 2; \
+ cfi_startproc; \
99: la t9,__syscall_error; \
jr t9; \
ENTRY (name) \
+ cfi_startproc; \
.set noreorder; \
.cpload t9; \
.set reorder; \
@@ -45,7 +47,9 @@
L(pseudo_cancel): \
SAVESTK_##args; \
sw ra, 28(sp); \
+ cfi_rel_offset (ra, 28); \
sw gp, 32(sp); \
+ cfi_rel_offset (gp, 32); \
PUSHARGS_##args; /* save syscall args */ \
CENABLE; \
lw gp, 32(sp); \
@@ -66,13 +70,17 @@
RESTORESTK; \
bne a3, zero, SYSCALL_ERROR_LABEL; \
L(pseudo_end):
+
+# undef PSEUDO_END
+# define PSEUDO_END(sym) cfi_endproc; .end sym; .size sym,.-sym
+
#endif
# define PUSHARGS_0 /* nothing to do */
-# define PUSHARGS_1 PUSHARGS_0 sw a0, 0(sp);
-# define PUSHARGS_2 PUSHARGS_1 sw a1, 4(sp);
-# define PUSHARGS_3 PUSHARGS_2 sw a2, 8(sp);
-# define PUSHARGS_4 PUSHARGS_3 sw a3, 12(sp);
+# define PUSHARGS_1 PUSHARGS_0 sw a0, 0(sp); cfi_rel_offset (a0, 0);
+# define PUSHARGS_2 PUSHARGS_1 sw a1, 4(sp); cfi_rel_offset (a1, 4);
+# define PUSHARGS_3 PUSHARGS_2 sw a2, 8(sp); cfi_rel_offset (a2, 8);
+# define PUSHARGS_4 PUSHARGS_3 sw a3, 12(sp); cfi_rel_offset (a3, 12);
# define PUSHARGS_5 PUSHARGS_4 /* handeld by SAVESTK_## */
# define PUSHARGS_6 PUSHARGS_5
# define PUSHARGS_7 PUSHARGS_6
@@ -88,30 +96,30 @@
# define STKSPACE 48
-# define SAVESTK_0 subu sp, STKSPACE
+# define SAVESTK_0 subu sp, STKSPACE; cfi_adjust_cfa_offset(STKSPACE)
# define SAVESTK_1 SAVESTK_0
# define SAVESTK_2 SAVESTK_1
# define SAVESTK_3 SAVESTK_2
# define SAVESTK_4 SAVESTK_3
# define SAVESTK_5 lw t0, 16(sp); \
- subu sp, STKSPACE; \
+ SAVESTK_0; \
sw t0, 16(sp)
# define SAVESTK_6 lw t0, 16(sp); \
lw t1, 20(sp); \
- subu sp, STKSPACE; \
+ SAVESTK_0; \
sw t0, 16(sp); \
sw t1, 20(sp)
# define SAVESTK_7 lw t0, 16(sp); \
lw t1, 20(sp); \
lw t2, 24(sp); \
- subu sp, STKSPACE; \
+ SAVESTK_0; \
sw t0, 16(sp); \
sw t1, 20(sp); \
sw t2, 24(sp)
-# define RESTORESTK addu sp, STKSPACE
+# define RESTORESTK addu sp, STKSPACE; cfi_adjust_cfa_offset(-STKSPACE)
/* We must use jal rather than jalr so that the assembler will restore $gp