diff options
Diffstat (limited to 'nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S')
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S | 103 |
1 files changed, 76 insertions, 27 deletions
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S index c292af02c0..9b583a8317 100644 --- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S +++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S @@ -1,4 +1,4 @@ -/* Copyright (C) 2003 Free Software Foundation, Inc. +/* Copyright (C) 2003, 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -16,6 +16,7 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include <unwindbuf.h> #include <sysdep.h> #include "lowlevel-atomic.h" @@ -29,6 +30,7 @@ .globl __pthread_once .type __pthread_once,@function .align 5 + cfi_startproc __pthread_once: mov.l @r4, r0 tst #2, r0 @@ -38,20 +40,27 @@ __pthread_once: 1: mov.l r12, @-r15 + cfi_adjust_cfa_offset (4) + cfi_rel_offset (r12, 0) mov.l r9, @-r15 + cfi_adjust_cfa_offset (4) + cfi_rel_offset (r9, 0) mov.l r8, @-r15 + cfi_adjust_cfa_offset (4) + cfi_rel_offset (r8, 0) sts.l pr, @-r15 + cfi_adjust_cfa_offset (4) + cfi_rel_offset (pr, 0) mov r5, r8 + mov r4, r9 /* Not yet initialized or initialization in progress. Get the fork generation counter now. */ 6: mov.l @r4, r1 -#ifdef PIC mova .Lgot, r0 mov.l .Lgot, r12 add r0, r12 -#endif 5: mov r1, r0 @@ -97,9 +106,9 @@ __pthread_once: nop .align 2 -#ifdef PIC .Lgot: .long _GLOBAL_OFFSET_TABLE_ +#ifdef PIC .Lfgen: .long __fork_generation@GOTOFF #else @@ -109,31 +118,40 @@ __pthread_once: 3: /* Call the initializer function after setting up the - cancellation handler. */ - /* Allocate a _pthread_cleanup_buffer on stack. */ - add #-16, r15 + cancellation handler. Note that it is not possible here + to use the unwind-based cleanup handling. This would require + that the user-provided function and all the code it calls + is compiled with exceptions. Unfortunately this cannot be + guaranteed. */ + add #-UNWINDBUFSIZE, r15 + cfi_adjust_cfa_offset (UNWINDBUFSIZE) + + mov.l .Lsigsetjmp, r1 + mov #UWJMPBUF, r4 + add r15, r4 + bsrf r1 + mov #0, r5 +.Lsigsetjmp0: + tst r0, r0 + bf 7f - /* Push the cleanup handler. */ - mov r4, r9 - mov r15, r4 - mov.l .Lconce, r5 -#ifdef PIC - add r12, r5 -#endif mov.l .Lcpush, r1 bsrf r1 - mov r9, r6 + mov r15, r4 .Lcpush0: + + /* Call the user-provided initialization function. */ jsr @r8 nop /* Pop the cleanup handler. */ - mov r15, r4 mov.l .Lcpop, r1 bsrf r1 - mov #0, r5 + mov r15, r4 .Lcpop0: - add #16, r15 + + add #UNWINDBUFSIZE, r15 + cfi_adjust_cfa_offset (-UNWINDBUFSIZE) /* Sucessful run of the initializer. Signal that we are done. */ INC (@r9, r2) @@ -150,24 +168,55 @@ __pthread_once: 4: lds.l @r15+, pr + cfi_adjust_cfa_offset (-4) + cfi_restore (pr) mov.l @r15+, r8 + cfi_adjust_cfa_offset (-4) + cfi_restore (r8) mov.l @r15+, r9 + cfi_adjust_cfa_offset (-4) + cfi_restore (r9) mov.l @r15+, r12 + cfi_adjust_cfa_offset (-4) + cfi_restore (r12) rts mov #0, r0 +7: + /* __sigsetjmp returned for the second time. */ + cfi_adjust_cfa_offset (UNWINDBUFSIZE+16) + cfi_offset (r12, -4) + cfi_offset (r9, -8) + cfi_offset (r8, -12) + cfi_offset (pr, -16) + mov #0, r7 + mov.l r7, @r9 + mov r9, r4 + mov #FUTEX_WAKE, r5 + mov #-1, r6 + shlr r6 /* r6 = 0x7fffffff */ + mov #SYS_futex, r3 + extu.b r3, r3 + trapa #0x14 + SYSCALL_INST_PAD + + mov.l .Lunext, r1 + bsrf r1 + mov r15, r4 +.Lunext0: + /* NOTREACHED */ + sleep + cfi_endproc + .align 2 -.Lconce: -#ifdef PIC - .long clear_once_control@GOTOFF -#else - .long clear_once_control -#endif +.Lsigsetjmp: + .long __sigsetjmp@PLT-(.Lsigsetjmp0+2-.) .Lcpush: - .long __pthread_cleanup_push - .Lcpush0 /* Note: no @PLT. */ + .long HIDDEN_JUMPTARGET(__pthread_register_cancel)-.Lcpush0 .Lcpop: - .long __pthread_cleanup_pop - .Lcpop0 /* Note: no @PLT. */ - + .long HIDDEN_JUMPTARGET(__pthread_unregister_cancel)-.Lcpop0 +.Lunext: + .long HIDDEN_JUMPTARGET(__pthread_unwind_next)-.Lunext0 .size __pthread_once,.-__pthread_once .globl __pthread_once_internal |