From 07bd2a3fda47e7cfa83e808eb99a0da9d1184a30 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Sat, 20 Mar 2004 06:16:26 +0000 Subject: Update. 2004-03-17 Kaz Kojima * sysdeps/unix/sysv/linux/kernel-features.h (__ASSUME_CLONE_THREAD_FLAGS ): Define for newer SH kernel. (__ASSUME_TGKILL, __ASSUME_UTIMES): Likewise. * sysdeps/unix/sysv/linux/sh/socket.S: Add unwind information. --- ChangeLog | 7 + nptl/ChangeLog | 21 + nptl/sysdeps/unix/sysv/linux/sh/lowlevel-atomic.h | 13 +- nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S | 17 +- .../unix/sysv/linux/sh/pthread_barrier_wait.S | 42 +- .../unix/sysv/linux/sh/pthread_cond_broadcast.S | 35 +- .../unix/sysv/linux/sh/pthread_cond_signal.S | 4 +- .../unix/sysv/linux/sh/pthread_cond_timedwait.S | 417 ++++++++++++++---- .../sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S | 464 ++++++++++++++------- nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S | 103 +++-- nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S | 35 +- nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h | 102 ++++- sysdeps/unix/sysv/linux/kernel-features.h | 8 +- sysdeps/unix/sysv/linux/sh/socket.S | 73 +++- 14 files changed, 1023 insertions(+), 318 deletions(-) diff --git a/ChangeLog b/ChangeLog index fdbb56e3ea..7d3376471f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2004-03-17 Kaz Kojima + + * sysdeps/unix/sysv/linux/kernel-features.h + (__ASSUME_CLONE_THREAD_FLAGS ): Define for newer SH kernel. + (__ASSUME_TGKILL, __ASSUME_UTIMES): Likewise. + * sysdeps/unix/sysv/linux/sh/socket.S: Add unwind information. + 2004-03-19 Ulrich Drepper * time/tzfile.c (__tzfile_default): Correct setting of rule_stdoff diff --git a/nptl/ChangeLog b/nptl/ChangeLog index 164a9b38ae..e0d09d5a1e 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -4,6 +4,27 @@ the return value to a safe register. (CDISABLE): Set the function argument correctly. +2004-03-17 Kaz Kojima + + * sysdeps/unix/sysv/linux/sh/lowlevel-atomic.h (XCHG): Define. + * sysdeps/unix/sysv/linux/sh/lowlevellock.S (__lll_mutex_lock_wait): + Rewrite so that only one locked memory operation per round is needed. + * sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S + (pthread_barrier_wait): After wakeup, release lock only when the + last thread stopped using the barrier object. + * sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S + (__pthread_cond_wait): Don't store mutex address if the current + value is ~0l. Add correct cleanup support and unwind info. + * sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S: Likewise. + * sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S + (__pthread_cond_broadcast): Don't use requeue for pshared condvars. + * sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S: Update comment. + * sysdeps/unix/sysv/linux/sh/pthread_once.S (__pthread_once): + Add correct cleanup support and unwind info. + * sysdeps/unix/sysv/linux/sh/sem_wait.S (__new_sem_wait): Likewise. + * sysdeps/unix/sysv/linux/sh/sysdep-cancel.h: Add unwind + information for syscall wrappers. + 2004-03-18 Ulrich Drepper * sysdeps/unix/sysv/linux/internaltypes.h (struct pthread_attr): Add diff --git a/nptl/sysdeps/unix/sysv/linux/sh/lowlevel-atomic.h b/nptl/sysdeps/unix/sysv/linux/sh/lowlevel-atomic.h index 3a80ec8e14..76d22c88f9 100644 --- a/nptl/sysdeps/unix/sysv/linux/sh/lowlevel-atomic.h +++ b/nptl/sysdeps/unix/sysv/linux/sh/lowlevel-atomic.h @@ -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 @@ -20,6 +20,7 @@ #define _IMP1 #1 #define _IMM1 #-1 +#define _IMM4 #-4 #define _IMM6 #-6 #define _IMM8 #-8 @@ -53,6 +54,16 @@ mov.l reg, mem; \ 99: mov r1, r15 +#define XCHG(reg, mem, old) \ + .align 2; \ + mova 99f, r0; \ + nop; \ + mov r15, r1; \ + mov _IMM4, r15; \ +98: mov.l mem, old; \ + mov.l reg, mem; \ +99: mov r1, r15 + #define CMPXCHG(reg, mem, new, old) \ .align 2; \ mova 99f, r0; \ diff --git a/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S b/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S index 936a4e3868..320fe18fe8 100644 --- a/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S +++ b/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.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 @@ -38,17 +38,12 @@ __lll_mutex_lock_wait: mov r5, r8 mov #0, r7 /* No timeout. */ mov #FUTEX_WAIT, r5 -1: + mov #2, r4 cmp/eq r4, r6 - bt 3f - - mov #1, r3 - CMPXCHG (r3, @r8, r4, r2) - tst r2, r2 - bt 2f + bf 2f -3: +1: mov r8, r4 mov #SYS_futex, r3 extu.b r3, r3 @@ -56,9 +51,9 @@ __lll_mutex_lock_wait: SYSCALL_INST_PAD 2: - mov #0, r3 mov #2, r4 - CMPXCHG (r3, @r8, r4, r2) + XCHG (r4, @r8, r2) + tst r2, r2 bf 1b mov.l @r15+, r8 diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S index 6696898c18..1fbb23a5a6 100644 --- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S +++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.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 @@ -80,6 +80,23 @@ pthread_barrier_wait: cmp/eq r0, r6 bt 8b + /* Increment LEFT. If this brings the count back to the + initial count unlock the object. */ + mov #1, r3 + mov.l @(INIT_COUNT,r8), r4 + XADD (r3, @(LEFT,r8), r2) + add #-1, r4 + cmp/eq r2, r4 + bf 10f + + /* Release the mutex. We cannot release the lock before + waking the waiting threads since otherwise a new thread might + arrive and gets waken up, too. */ + DEC (@(MUTEX,r8), r2) + tst r2, r2 + bf 9f + +10: mov #0, r0 /* != PTHREAD_BARRIER_SERIAL_THREAD */ lds.l @r15+, pr mov.l @r15+, r8 @@ -88,8 +105,6 @@ pthread_barrier_wait: 3: /* The necessary number of threads arrived. */ - mov.l @(INIT_COUNT,r8), r0 - mov.l r0, @(LEFT,r8) mov.l @(CURR_EVENT,r8), r1 add #1, r1 mov.l r1, @(CURR_EVENT,r8) @@ -108,6 +123,15 @@ pthread_barrier_wait: trapa #0x14 SYSCALL_INST_PAD + /* Increment LEFT. If this brings the count back to the + initial count unlock the object. */ + mov #1, r3 + mov.l @(INIT_COUNT,r8), r4 + XADD (r3, @(LEFT,r8), r2) + add #-1, r4 + cmp/eq r2, r4 + bf 5f + /* Release the mutex. */ DEC (@(MUTEX,r8), r2) tst r2, r2 @@ -148,6 +172,16 @@ pthread_barrier_wait: bra 7b mov r9, r6 +9: + mov r6, r9 + mov r8, r4 + mov.l .Lwake2, r1 + bsrf r1 + add #MUTEX, r4 +.Lwake2b: + bra 10b + mov r9, r6 + .align 2 .Lall: .long 0x7fffffff @@ -157,4 +191,6 @@ pthread_barrier_wait: .long __lll_mutex_unlock_wake-.Lwake0b .Lwake1: .long __lll_mutex_unlock_wake-.Lwake1b +.Lwake2: + .long __lll_mutex_unlock_wake-.Lwake2b .size pthread_barrier_wait,.-pthread_barrier_wait diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S index 5bcaec09c0..a433ba3c37 100644 --- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S +++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.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 @@ -79,11 +79,16 @@ __pthread_cond_broadcast: #endif tst r2, r2 bf 7f + 8: - /* Wake up all threads. */ + /* Don't use requeue for pshared condvars. */ + mov #-1, r0 + cmp/eq r0, r9 mov r8, r4 - add #wakeup_seq, r4 -#ifdef __ASSUME_FUTEX_REQUEUE + bt/s 9f + add #wakeup_seq, r4 + + /* Wake up all threads. */ mov #FUTEX_REQUEUE, r5 mov #1, r6 mov #-1, r7 @@ -95,17 +100,9 @@ __pthread_cond_broadcast: mov #SYS_futex, r3 extu.b r3, r3 trapa #0x15 -#else - mov #FUTEX_WAKE, r5 - mov #-1, r6 - shlr r6 /* r6 = 0x7fffffff */ - mov #0, r7 - mov #SYS_futex, r3 - extu.b r3, r3 - trapa #0x14 -#endif SYSCALL_INST_PAD +10: mov #0, r0 lds.l @r15+, pr mov.l @r15+, r8 @@ -167,6 +164,18 @@ __pthread_cond_broadcast: bra 8b nop +9: + mov #FUTEX_WAKE, r5 + mov #-1, r6 + shlr r6 /* r6 = 0x7fffffff */ + mov #0, r7 + mov #SYS_futex, r3 + extu.b r3, r3 + trapa #0x14 + SYSCALL_INST_PAD + bra 10b + nop + .align 2 .Lmwait5: .long __lll_mutex_lock_wait-.Lmwait5b diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S index 1a3a3485da..a0d188abb2 100644 --- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S +++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_signal.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 @@ -73,7 +73,7 @@ __pthread_cond_signal: mov.l r0,@(wakeup_seq,r8) mov.l r1,@(wakeup_seq+4,r8) - /* Wake up one thread by moving it to the internal lock futex. */ + /* Wake up one thread. */ mov r8, r4 add #wakeup_seq, r4 mov #FUTEX_WAKE, r5 diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S index 278f695b6e..661caa3fb5 100644 --- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S +++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.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 @@ -36,17 +36,31 @@ .type __pthread_cond_timedwait, @function .align 5 __pthread_cond_timedwait: +.LSTARTCODE: mov.l r8, @-r15 +.Lpush_r8: mov.l r9, @-r15 +.Lpush_r9: mov.l r10, @-r15 +.Lpush_r10: mov.l r11, @-r15 +.Lpush_r11: mov.l r12, @-r15 +.Lpush_r12: mov.l r13, @-r15 +.Lpush_r13: sts.l pr, @-r15 +.Lpush_pr: add #-64, r15 +.Lalloc: mov r4, r8 mov r5, r9 mov r6, r13 +#ifdef PIC + mova .Lgot0, r0 + mov.l .Lgot0, r12 + add r0, r12 +#endif /* Get internal lock. */ mov #0, r3 @@ -59,11 +73,21 @@ __pthread_cond_timedwait: bt 2f bra 1f nop +#ifdef PIC + .align 2 +.Lgot0: + .long _GLOBAL_OFFSET_TABLE_ +#endif + 2: /* Store the reference to the mutex. If there is already a different value in there this is a bad user bug. */ + mov.l @(dep_mutex,r8),r0 + cmp/eq #-1, r0 + bt 17f mov.l r9, @(dep_mutex,r8) - + +17: /* Unlock the mutex. */ mov.l .Lmunlock1, r1 mov #0, r5 @@ -87,50 +111,11 @@ __pthread_cond_timedwait: mov.l r0,@(total_seq,r8) mov.l r1,@(total_seq+4,r8) - /* Install cancellation handler. */ -#ifdef PIC - mova .Lgot1, r0 - mov.l .Lgot1, r12 - add r0, r12 - mov.l .Lccleanup1, r5 - add r12, r5 -#else - mov.l .Lccleanup1, r5 -#endif - mov r15, r4 - add #32, r4 - - /* Prepare structure passed to cancellation handler. */ - mov.l r8, @(4,r15) - mov.l r9, @(8,r15) - - mov.l .Lccpush1, r1 - bsrf r1 - mov r15, r6 -.Lccpush1b: - /* Get and store current wakeup_seq value. */ mov.l @(wakeup_seq,r8), r10 mov.l @(wakeup_seq+4,r8), r11 - /* Unlock. */ -8: -#if cond_lock != 0 - DEC (@(cond_lock,r8), r2) -#else - DEC (@r8, r2) -#endif - tst r2, r2 - bt 4f - bra 3f - nop -4: - mov.l .Lenable1, r1 - bsrf r1 - nop -.Lenable1b: - mov.l r0, @r15 - +8: /* Get current time. */ mov r15, r4 add #16, r4 @@ -162,6 +147,24 @@ __pthread_cond_timedwait: mov.l r2, @(16,r15) mov.l r3, @(20,r15) + /* Unlock. */ +#if cond_lock != 0 + DEC (@(cond_lock,r8), r2) +#else + DEC (@r8, r2) +#endif + tst r2, r2 + bt 4f + bra 3f + nop +4: +.LcleanupSTART: + mov.l .Lenable1, r1 + bsrf r1 + nop +.Lenable1b: + mov.l r0, @r15 + mov r15, r7 add #16, r7 mov #FUTEX_WAIT, r5 @@ -178,6 +181,7 @@ __pthread_cond_timedwait: bsrf r1 mov.l @r15, r4 .Ldisable1b: +.LcleanupEND: /* Lock. */ mov #0, r3 @@ -195,20 +199,15 @@ __pthread_cond_timedwait: mov.l @(wakeup_seq,r8), r2 mov.l @(wakeup_seq+4,r8), r3 - cmp/hi r11, r3 - bt 7f - cmp/hi r3, r11 - bt 15f - - cmp/hs r2, r10 + cmp/eq r3, r11 + bf 7f + cmp/eq r2, r10 bt 15f 7: - cmp/hi r1, r3 - bt 9f - cmp/hi r3, r1 - bt 15f - cmp/hi r0, r2 - bt 9f + cmp/eq r1, r3 + bf 9f + cmp/eq r0, r2 + bf 9f 15: mov.l @(12,r15),r0 cmp/eq #-ETIMEDOUT, r0 @@ -252,14 +251,6 @@ __pthread_cond_timedwait: bf 10f 11: - /* Remove cancellation handler. */ - mov r15, r4 - add #32, r4 - mov.l .Lcpop1, r1 - bsrf r1 - mov #0, r5 -.Lcpop1b: - mov r9, r4 mov.l .Lmlocki1, r1 bsrf r1 @@ -273,44 +264,39 @@ __pthread_cond_timedwait: 18: add #64, r15 +.Lfree: lds.l @r15+, pr +.Lpop_pr: mov.l @r15+, r13 +.Lpop_r13: mov.l @r15+, r12 +.Lpop_r12: mov.l @r15+, r11 +.Lpop_r11: mov.l @r15+, r10 +.Lpop_r10: mov.l @r15+, r9 +.Lpop_r9: rts mov.l @r15+, r8 - ret +.Lpop_r8: .L1k: .word 1000 .align 2 .Lmunlock1: .long __pthread_mutex_unlock_usercnt-.Lmunlock1b -#ifdef PIC -.Lgot1: - .long _GLOBAL_OFFSET_TABLE_ -.Lccleanup1: - .long __condvar_cleanup@GOTOFF -#else -.Lccleanup1: - .long __condvar_cleanup -#endif -.Lccpush1: - .long __pthread_cleanup_push-.Lccpush1b .Lenable1: .long __pthread_enable_asynccancel-.Lenable1b .Ldisable1: .long __pthread_disable_asynccancel-.Ldisable1b -.Lcpop1: - .long __pthread_cleanup_pop-.Lcpop1b .Lmlocki1: .long __pthread_mutex_cond_lock-.Lmlocki1b .L1g: .long 1000000000 1: +.LSblSTART: /* Initial locking failed. */ mov r8, r5 #if cond_lock != 0 @@ -384,6 +370,7 @@ __pthread_cond_timedwait: 17: bra 18b mov.l @(24,r15), r0 +.LSblEND: .align 2 .Lmwait2: @@ -399,3 +386,281 @@ __pthread_cond_timedwait: .size __pthread_cond_timedwait, .-__pthread_cond_timedwait versioned_symbol (libpthread, __pthread_cond_timedwait, pthread_cond_timedwait, GLIBC_2_3_2) + + + .type __condvar_tw_cleanup, @function +__condvar_tw_cleanup: + mov r4, r11 + + /* Get internal lock. */ + mov #0, r3 + mov #1, r4 +#if cond_lock != 0 + CMPXCHG (r3, @(cond_lock,r8), r4, r2) +#else + CMPXCHG (r3, @r8, r4, r2) +#endif + bt 1f + nop + + mov r8, r5 +#if cond_lock != 0 + add #cond_lock, r5 +#endif + mov.l .Lmwait5, r1 + bsrf r1 + mov r2, r4 +.Lmwait5b: + +1: + mov #1, r2 + mov #0, r3 + + clrt + mov.l @(wakeup_seq,r8),r0 + mov.l @(wakeup_seq+4,r8),r1 + addc r2, r0 + addc r3, r1 + mov.l r0,@(wakeup_seq,r8) + mov.l r1,@(wakeup_seq+4,r8) + +#if cond_lock != 0 + DEC (@(cond_lock,r8), r2) +#else + DEC (@r8, r2) +#endif + tst r2, r2 + bt 2f + + mov r8, r4 +#if cond_lock != 0 + add #cond_lock, r4 +#endif + mov.l .Lmwake5, r1 + bsrf r1 + nop +.Lmwake5b: + +2: + /* Wake up all waiters to make sure no signal gets lost. */ + mov r8, r4 + add #wakeup_seq, r4 + mov #FUTEX_WAKE, r5 + mov #-1, r6 + shlr r6 /* r6 = 0x7fffffff */ + mov #0, r7 + mov #SYS_futex, r3 + extu.b r3, r3 + trapa #0x14 + SYSCALL_INST_PAD + + mov.l .Lmlocki5, r1 + bsrf r1 + mov r9, r4 +.Lmlocki5b: + +.LcallUR: + mov.l .Lresume, r1 +#ifdef PIC + add r12, r1 +#endif + jsr @r1 + mov r11, r4 + sleep + + .align 2 +.Lmwait5: + .long __lll_mutex_lock_wait-.Lmwait5b +.Lmwake5: + .long __lll_mutex_unlock_wake-.Lmwake5b +.Lmlocki5: + .long __pthread_mutex_cond_lock-.Lmlocki5b +.Lresume: +#ifdef PIC + .long _Unwind_Resume@GOTOFF +#else + .long _Unwind_Resume +#endif +.LENDCODE: + .size __condvar_tw_cleanup, .-__condvar_tw_cleanup + + + .section .gcc_except_table,"a",@progbits +.LexceptSTART: + .byte 0xff ! @LPStart format (omit) + .byte 0xff ! @TType format (omit) + .byte 0x0b ! call-site format + ! DW_EH_PE_sdata4 + .uleb128 .Lcstend-.Lcstbegin +.Lcstbegin: + .ualong .LcleanupSTART-.LSTARTCODE + .ualong .LcleanupEND-.LcleanupSTART + .ualong __condvar_tw_cleanup-.LSTARTCODE + .uleb128 0 + .ualong .LcallUR-.LSTARTCODE + .ualong .LENDCODE-.LcallUR + .ualong 0 + .uleb128 0 +.Lcstend: + + .section .eh_frame,"a",@progbits +.LSTARTFRAME: + .ualong .LENDCIE-.LSTARTCIE ! Length of the CIE. +.LSTARTCIE: + .ualong 0 ! CIE ID. + .byte 1 ! Version number. +#ifdef SHARED + .string "zPLR" ! NUL-terminated augmentation + ! string. +#else + .string "zPL" ! NUL-terminated augmentation + ! string. +#endif + .uleb128 1 ! Code alignment factor. + .sleb128 -4 ! Data alignment factor. + .byte 0x11 ! Return address register + ! column. +#ifdef SHARED + .uleb128 7 ! Augmentation value length. + .byte 0x9b ! Personality: DW_EH_PE_pcrel + ! + DW_EH_PE_sdata4 + ! + DW_EH_PE_indirect + .ualong DW.ref.__gcc_personality_v0-. + .byte 0x1b ! LSDA Encoding: DW_EH_PE_pcrel + ! + DW_EH_PE_sdata4. + .byte 0x1b ! FDE Encoding: DW_EH_PE_pcrel + ! + DW_EH_PE_sdata4. +#else + .uleb128 6 ! Augmentation value length. + .byte 0x0 ! Personality: absolute + .ualong __gcc_personality_v0 + .byte 0x0 ! LSDA Encoding: absolute +#endif + .byte 0x0c ! DW_CFA_def_cfa + .uleb128 0xf + .uleb128 0 + .align 2 +.LENDCIE: + + .ualong .LENDFDE-.LSTARTFDE ! Length of the FDE. +.LSTARTFDE: + .ualong .LSTARTFDE-.LSTARTFRAME ! CIE pointer. +#ifdef SHARED + .ualong .LSTARTCODE-. ! PC-relative start address + ! of the code. +#else + .ualong .LSTARTCODE ! Start address of the code. +#endif + .ualong .LENDCODE-.LSTARTCODE ! Length of the code. + .uleb128 4 ! Augmentation size +#ifdef SHARED + .ualong .LexceptSTART-. +#else + .ualong .LexceptSTART +#endif + .byte 0x4 + .ualong .Lpush_r8-.LSTARTCODE + .byte 0xe + .uleb128 4 + .byte 0x88 + .uleb128 1 + .byte 0x4 + .ualong .Lpush_r9-.Lpush_r8 + .byte 0xe + .uleb128 8 + .byte 0x89 + .uleb128 2 + .byte 0x4 + .ualong .Lpush_r10-.Lpush_r9 + .byte 0xe + .uleb128 12 + .byte 0x8a + .uleb128 3 + .byte 0x4 + .ualong .Lpush_r11-.Lpush_r10 + .byte 0xe + .uleb128 16 + .byte 0x8b + .uleb128 4 + .byte 0x4 + .ualong .Lpush_r12-.Lpush_r11 + .byte 0xe + .uleb128 20 + .byte 0x8c + .uleb128 5 + .byte 0x4 + .ualong .Lpush_r13-.Lpush_r12 + .byte 0xe + .uleb128 24 + .byte 0x8d + .uleb128 6 + .byte 0x4 + .ualong .Lpush_pr-.Lpush_r13 + .byte 0xe + .uleb128 28 + .byte 0x91 + .uleb128 7 + .byte 0x4 + .ualong .Lalloc-.Lpush_pr + .byte 0xe + .uleb128 92 + .byte 0x4 + .ualong .Lfree-.Lalloc + .byte 0xe + .uleb128 28 + .byte 0x4 + .ualong .Lpop_pr-.Lfree + .byte 0xe + .uleb128 24 + .byte 0xd1 + .byte 0x4 + .ualong .Lpop_r13-.Lpop_pr + .byte 0xe + .uleb128 20 + .byte 0xcd + .byte 0x4 + .ualong .Lpop_r12-.Lpop_r13 + .byte 0xe + .uleb128 16 + .byte 0xcc + .byte 0x4 + .ualong .Lpop_r11-.Lpop_r12 + .byte 0xe + .uleb128 12 + .byte 0xcb + .byte 0x4 + .ualong .Lpop_r10-.Lpop_r11 + .byte 0xe + .uleb128 8 + .byte 0xca + .byte 0x4 + .ualong .Lpop_r9-.Lpop_r10 + .byte 0xe + .uleb128 4 + .byte 0xc9 + .byte 0x4 + .ualong .Lpop_r8-.Lpop_r9 + .byte 0xe + .uleb128 0 + .byte 0xc8 + .byte 0x4 + .ualong .LSblSTART-.Lpop_r8 + .byte 0xe + .uleb128 72 + .byte 0x4 + .ualong .LSblEND-.LSblSTART + .byte 0xe + .uleb128 72 + .align 2 +.LENDFDE: + +#ifdef SHARED + .hidden DW.ref.__gcc_personality_v0 + .weak DW.ref.__gcc_personality_v0 + .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits + .align 4 + .type DW.ref.__gcc_personality_v0, @object + .size DW.ref.__gcc_personality_v0, 4 +DW.ref.__gcc_personality_v0: + .long __gcc_personality_v0 +#endif diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S index a1967f4922..01b906eeed 100644 --- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S +++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.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 @@ -28,119 +28,33 @@ .text - .align 5 - .type __condvar_cleanup, @function - .globl __condvar_cleanup - .hidden __condvar_cleanup -__condvar_cleanup: - mov.l r8, @-r15 - mov.l r9, @-r15 - sts.l pr, @-r15 - mov r4, r9 - mov.l @(4,r9), r8 - - /* Get internal lock. */ - mov #0, r3 - mov #1, r4 -#if cond_lock != 0 - CMPXCHG (r3, @(cond_lock,r8), r4, r2) -#else - CMPXCHG (r3, @r8, r4, r2) -#endif - bt 1f - mov r8, r5 -#if cond_lock != 0 - add #cond_lock, r5 -#endif - mov.l .Lwait0, r1 - bsrf r1 - mov r2, r4 -.Lwait0b: -1: - mov #1, r2 - mov #0, r3 - - clrt - mov.l @(wakeup_seq,r8),r0 - mov.l @(wakeup_seq+4,r8),r1 - addc r2, r0 - addc r3, r1 - mov.l r0,@(wakeup_seq,r8) - mov.l r1,@(wakeup_seq+4,r8) - - clrt - mov.l @(woken_seq,r8),r0 - mov.l @(woken_seq+4,r8),r1 - addc r2, r0 - addc r3, r1 - mov.l r0,@(woken_seq,r8) - mov.l r1,@(woken_seq+4,r8) - - /* Release internal lock. */ -#if cond_lock != 0 - DEC (@(cond_lock,r8), r2) -#else - DEC (@r8, r2) -#endif - tst r2, r2 - bt 2f - - mov r8, r4 -#if cond_lock != 0 - add #cond_lock, r4 -#endif - mov.l .Lwake0, r1 - bsrf r1 - nop -.Lwake0b: -2: - - /* Wake up all waiters to make sure no signal gets lost. */ - mov r8, r4 - add #wakeup_seq, r4 - mov #FUTEX_WAKE, r5 - mov #-1, r6 - shlr r6 /* r6 = 0x7fffffff */ - mov #0, r7 - mov #SYS_futex, r3 - extu.b r3, r3 - trapa #0x14 - SYSCALL_INST_PAD - - mov.l .Lmlocki1, r1 - bsrf r1 - mov.l @(8,r9), r4 -.Lmlocki1b: - - lds.l @r15+, pr - mov.l @r15+, r9 - rts - mov.l @r15+, r8 - - .align 2 -.Lwait0: - .long __lll_mutex_lock_wait-.Lwait0b -.Lwake0: - .long __lll_mutex_unlock_wake-.Lwake0b -.Lmlocki1: - .long __pthread_mutex_cond_lock-.Lmlocki1b - .size __condvar_cleanup, .-__condvar_cleanup - - /* int pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex) */ .globl __pthread_cond_wait .type __pthread_cond_wait, @function .align 5 __pthread_cond_wait: +.LSTARTCODE: mov.l r8, @-r15 +.Lpush_r8: mov.l r9, @-r15 +.Lpush_r9: mov.l r10, @-r15 +.Lpush_r10: mov.l r11, @-r15 +.Lpush_r11: mov.l r12, @-r15 +.Lpush_r12: sts.l pr, @-r15 +.Lpush_pr: add #-48, r15 +.Lalloc: mov r4, r8 mov r5, r9 +#ifdef PIC + mova .Lgot0, r0 + mov.l .Lgot0, r12 + add r0, r12 +#endif /* Get internal lock. */ mov #0, r3 @@ -153,12 +67,21 @@ __pthread_cond_wait: bt 2f bra 1f nop +#ifdef PIC + .align 2 +.Lgot0: + .long _GLOBAL_OFFSET_TABLE_ +#endif 2: /* Store the reference to the mutex. If there is already a different value in there this is a bad user bug. */ + mov.l @(dep_mutex,r8),r0 + cmp/eq #-1, r0 + bt 15f mov.l r9, @(dep_mutex,r8) +15: /* Unlock the mutex. */ mov.l .Lmunlock0, r1 mov #0, r5 @@ -182,28 +105,6 @@ __pthread_cond_wait: mov.l r0,@(total_seq,r8) mov.l r1,@(total_seq+4,r8) - /* Install cancellation handler. */ -#ifdef PIC - mova .Lgot0, r0 - mov.l .Lgot0, r12 - add r0, r12 - mov.l .Lccleanup0, r5 - add r12, r5 -#else - mov.l .Lccleanup0, r5 -#endif - mov r15, r4 - add #16, r4 - - /* Prepare structure passed to cancellation handler. */ - mov.l r8, @(4,r15) - mov.l r9, @(8,r15) - - mov.l .Lccpush0, r1 - bsrf r1 - mov r15, r6 -.Lccpush0b: - /* Get and store current wakeup_seq value. */ mov.l @(wakeup_seq,r8), r10 mov.l @(wakeup_seq+4,r8), r11 @@ -218,6 +119,7 @@ __pthread_cond_wait: tst r2, r2 bf 3f 4: +.LcleanupSTART: mov.l .Lenable0, r1 bsrf r1 nop @@ -238,6 +140,7 @@ __pthread_cond_wait: bsrf r1 mov.l @r15, r4 .Ldisable0b: +.LcleanupEND: /* Lock. */ mov #0, r3 @@ -255,20 +158,15 @@ __pthread_cond_wait: mov.l @(wakeup_seq,r8), r2 mov.l @(wakeup_seq+4,r8), r3 - cmp/hi r11, r3 - bt 7f - cmp/hi r3, r11 - bt 8b - - cmp/hs r2, r10 + cmp/eq r3, r11 + bf 7f + cmp/eq r2, r10 bt 8b 7: - cmp/hi r1, r3 - bt 9f - cmp/hi r3, r1 + cmp/eq r1, r3 + bf 9f + cmp/eq r0, r2 bt 8b - cmp/hi r0, r2 - bf 8b 9: mov #1, r2 mov #0, r3 @@ -290,55 +188,41 @@ __pthread_cond_wait: bf 10f 11: - /* Remove cancellation handler. */ - mov r15, r4 - add #16, r4 - mov.l .Lcpop0, r1 - bsrf r1 - mov #0, r5 -.Lcpop0b: - - mov r9, r4 mov.l .Lmlocki0, r1 bsrf r1 - nop + mov r9, r4 .Lmlocki0b: /* We return the result of the mutex_lock operation. */ 14: add #48, r15 +.Lfree: lds.l @r15+, pr +.Lpop_pr: mov.l @r15+, r12 +.Lpop_r12: mov.l @r15+, r11 +.Lpop_r11: mov.l @r15+, r10 +.Lpop_r10: mov.l @r15+, r9 +.Lpop_r9: rts mov.l @r15+, r8 +.Lpop_r8: .align 2 .Lmunlock0: .long __pthread_mutex_unlock_usercnt-.Lmunlock0b -#ifdef PIC -.Lgot0: - .long _GLOBAL_OFFSET_TABLE_ -.Lccleanup0: - .long __condvar_cleanup@GOTOFF -#else -.Lccleanup0: - .long __condvar_cleanup -#endif -.Lccpush0: - .long __pthread_cleanup_push-.Lccpush0b .Lenable0: .long __pthread_enable_asynccancel-.Lenable0b .Ldisable0: .long __pthread_disable_asynccancel-.Ldisable0b -.Lcpop0: - .long __pthread_cleanup_pop-.Lcpop0b .Lmlocki0: .long __pthread_mutex_cond_lock-.Lmlocki0b 1: +.LSblSTART: /* Initial locking failed. */ mov r8, r5 #if cond_lock != 0 @@ -412,6 +296,7 @@ __pthread_cond_wait: 13: bra 14b mov.l @(12,r15), r0 +.LSblEND: .align 2 .Lmwait0: @@ -427,3 +312,270 @@ __pthread_cond_wait: .size __pthread_cond_wait, .-__pthread_cond_wait versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait, GLIBC_2_3_2) + + + .type __condvar_w_cleanup, @function +__condvar_w_cleanup: + mov r4, r11 + + /* Get internal lock. */ + mov #0, r3 + mov #1, r4 +#if cond_lock != 0 + CMPXCHG (r3, @(cond_lock,r8), r4, r2) +#else + CMPXCHG (r3, @r8, r4, r2) +#endif + bt 1f + nop + + mov r8, r5 +#if cond_lock != 0 + add #cond_lock, r5 +#endif + mov.l .Lmwait3, r1 + bsrf r1 + mov r2, r4 +.Lmwait3b: + +1: + mov #1, r2 + mov #0, r3 + + clrt + mov.l @(wakeup_seq,r8),r0 + mov.l @(wakeup_seq+4,r8),r1 + addc r2, r0 + addc r3, r1 + mov.l r0,@(wakeup_seq,r8) + mov.l r1,@(wakeup_seq+4,r8) + +#if cond_lock != 0 + DEC (@(cond_lock,r8), r2) +#else + DEC (@r8, r2) +#endif + tst r2, r2 + bt 2f + + mov r8, r4 +#if cond_lock != 0 + add #cond_lock, r4 +#endif + mov.l .Lmwake3, r1 + bsrf r1 + nop +.Lmwake3b: + +2: + /* Wake up all waiters to make sure no signal gets lost. */ + mov r8, r4 + add #wakeup_seq, r4 + mov #FUTEX_WAKE, r5 + mov #-1, r6 + shlr r6 /* r6 = 0x7fffffff */ + mov #0, r7 + mov #SYS_futex, r3 + extu.b r3, r3 + trapa #0x14 + SYSCALL_INST_PAD + + mov.l .Lmlocki3, r1 + bsrf r1 + mov r9, r4 +.Lmlocki3b: + +.LcallUR: + mov.l .Lresume, r1 +#ifdef PIC + add r12, r1 +#endif + jsr @r1 + mov r11, r4 + sleep + + .align 2 +.Lmwait3: + .long __lll_mutex_lock_wait-.Lmwait3b +.Lmwake3: + .long __lll_mutex_unlock_wake-.Lmwake3b +.Lmlocki3: + .long __pthread_mutex_cond_lock-.Lmlocki3b +.Lresume: +#ifdef PIC + .long _Unwind_Resume@GOTOFF +#else + .long _Unwind_Resume +#endif +.LENDCODE: + .size __condvar_w_cleanup, .-__condvar_w_cleanup + + + .section .gcc_except_table,"a",@progbits +.LexceptSTART: + .byte 0xff ! @LPStart format (omit) + .byte 0xff ! @TType format (omit) + .byte 0x0b ! call-site format + ! DW_EH_PE_sdata4 + .uleb128 .Lcstend-.Lcstbegin +.Lcstbegin: + .ualong .LcleanupSTART-.LSTARTCODE + .ualong .LcleanupEND-.LcleanupSTART + .ualong __condvar_w_cleanup-.LSTARTCODE + .uleb128 0 + .ualong .LcallUR-.LSTARTCODE + .ualong .LENDCODE-.LcallUR + .ualong 0 + .uleb128 0 +.Lcstend: + + .section .eh_frame,"a",@progbits +.LSTARTFRAME: + .ualong .LENDCIE-.LSTARTCIE ! Length of the CIE. +.LSTARTCIE: + .ualong 0 ! CIE ID. + .byte 1 ! Version number. +#ifdef SHARED + .string "zPLR" ! NUL-terminated augmentation + ! string. +#else + .string "zPL" ! NUL-terminated augmentation + ! string. +#endif + .uleb128 1 ! Code alignment factor. + .sleb128 -4 ! Data alignment factor. + .byte 0x11 ! Return address register + ! column. +#ifdef SHARED + .uleb128 7 ! Augmentation value length. + .byte 0x9b ! Personality: DW_EH_PE_pcrel + ! + DW_EH_PE_sdata4 + ! + DW_EH_PE_indirect + .ualong DW.ref.__gcc_personality_v0-. + .byte 0x1b ! LSDA Encoding: DW_EH_PE_pcrel + ! + DW_EH_PE_sdata4. + .byte 0x1b ! FDE Encoding: DW_EH_PE_pcrel + ! + DW_EH_PE_sdata4. +#else + .uleb128 6 ! Augmentation value length. + .byte 0x0 ! Personality: absolute + .ualong __gcc_personality_v0 + .byte 0x0 ! LSDA Encoding: absolute +#endif + .byte 0x0c ! DW_CFA_def_cfa + .uleb128 0xf + .uleb128 0 + .align 2 +.LENDCIE: + + .ualong .LENDFDE-.LSTARTFDE ! Length of the FDE. +.LSTARTFDE: + .ualong .LSTARTFDE-.LSTARTFRAME ! CIE pointer. +#ifdef SHARED + .ualong .LSTARTCODE-. ! PC-relative start address + ! of the code. +#else + .ualong .LSTARTCODE ! Start address of the code. +#endif + .ualong .LENDCODE-.LSTARTCODE ! Length of the code. + .uleb128 4 ! Augmentation size +#ifdef SHARED + .ualong .LexceptSTART-. +#else + .ualong .LexceptSTART +#endif + .byte 0x4 + .ualong .Lpush_r8-.LSTARTCODE + .byte 0xe + .uleb128 4 + .byte 0x88 + .uleb128 1 + .byte 0x4 + .ualong .Lpush_r9-.Lpush_r8 + .byte 0xe + .uleb128 8 + .byte 0x89 + .uleb128 2 + .byte 0x4 + .ualong .Lpush_r10-.Lpush_r9 + .byte 0xe + .uleb128 12 + .byte 0x8a + .uleb128 3 + .byte 0x4 + .ualong .Lpush_r11-.Lpush_r10 + .byte 0xe + .uleb128 16 + .byte 0x8b + .uleb128 4 + .byte 0x4 + .ualong .Lpush_r12-.Lpush_r11 + .byte 0xe + .uleb128 20 + .byte 0x8c + .uleb128 5 + .byte 0x4 + .ualong .Lpush_pr-.Lpush_r12 + .byte 0xe + .uleb128 24 + .byte 0x91 + .uleb128 6 + .byte 0x4 + .ualong .Lalloc-.Lpush_pr + .byte 0xe + .uleb128 72 + .byte 0x4 + .ualong .Lfree-.Lalloc + .byte 0xe + .uleb128 24 + .byte 0x4 + .ualong .Lpop_pr-.Lfree + .byte 0xe + .uleb128 20 + .byte 0xd1 + .byte 0x4 + .ualong .Lpop_r12-.Lpop_pr + .byte 0xe + .uleb128 16 + .byte 0xcc + .byte 0x4 + .ualong .Lpop_r11-.Lpop_r12 + .byte 0xe + .uleb128 12 + .byte 0xcb + .byte 0x4 + .ualong .Lpop_r10-.Lpop_r11 + .byte 0xe + .uleb128 8 + .byte 0xca + .byte 0x4 + .ualong .Lpop_r9-.Lpop_r10 + .byte 0xe + .uleb128 4 + .byte 0xc9 + .byte 0x4 + .ualong .Lpop_r8-.Lpop_r9 + .byte 0xe + .uleb128 0 + .byte 0xc8 + .byte 0x4 + .ualong .LSblSTART-.Lpop_r8 + .byte 0xe + .uleb128 72 + .byte 0x4 + .ualong .LSblEND-.LSblSTART + .byte 0xe + .uleb128 72 + .align 2 +.LENDFDE: + +#ifdef SHARED + .hidden DW.ref.__gcc_personality_v0 + .weak DW.ref.__gcc_personality_v0 + .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits + .align 4 + .type DW.ref.__gcc_personality_v0, @object + .size DW.ref.__gcc_personality_v0, 4 +DW.ref.__gcc_personality_v0: + .long __gcc_personality_v0 +#endif 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 #include #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 diff --git a/nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S b/nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S index 8a55394c29..28f78b015e 100644 --- a/nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S +++ b/nptl/sysdeps/unix/sysv/linux/sh/sem_wait.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 @@ -33,6 +33,7 @@ .globl __new_sem_wait .type __new_sem_wait,@function .align 5 + cfi_startproc __new_sem_wait: /* First check for cancellation. */ stc gbr, r0 @@ -44,9 +45,17 @@ __new_sem_wait: bt 5f mov.l r8, @-r15 + cfi_adjust_cfa_offset(4) + cfi_rel_offset (r8, 0) mov.l r10, @-r15 + cfi_adjust_cfa_offset(4) + cfi_rel_offset (r10, 0) mov.l r12, @-r15 + cfi_adjust_cfa_offset(4) + cfi_rel_offset (r12, 0) sts.l pr, @-r15 + cfi_adjust_cfa_offset(4) + cfi_rel_offset (pr, 0) mov r4, r8 3: mov.l @r8, r0 @@ -57,12 +66,9 @@ __new_sem_wait: mov r0, r4 add #-1, r3 CMPXCHG (r4, @r8, r3, r2) - bf 2b - lds.l @r15+, pr - mov.l @r15+, r12 - mov.l @r15+, r10 - mov.l @r15+, r8 - rts + bf/s 2b + mov r2, r0 + bra 9f mov #0, r0 1: @@ -112,13 +118,21 @@ __new_sem_wait: .Lerrloc0b: mov.l r8, @r0 #endif + mov #-1, r0 +9: lds.l @r15+, pr + cfi_adjust_cfa_offset (-4) + cfi_restore (pr) mov.l @r15+, r12 + cfi_adjust_cfa_offset (-4) + cfi_restore (r12) mov.l @r15+, r10 - mov.l @r15+, r8 + cfi_adjust_cfa_offset (-4) + cfi_restore (r10) rts - mov #-1, r0 - + mov.l @r15+, r8 + cfi_adjust_cfa_offset (-4) + cfi_restore (r8) 5: /* Canceled. */ stc gbr, r0 @@ -132,6 +146,7 @@ __new_sem_wait: mov.l .Lunwind, r2 jmp @r2 mov.l @(r0,r1), r4 + cfi_endproc .Lchand: .word CANCELHANDLING - TLS_PRE_TCB_SIZE diff --git a/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h b/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h index ba2efbcba9..581046c007 100644 --- a/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h +++ b/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h @@ -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 @@ -31,6 +31,7 @@ # define PSEUDO(name, syscall_name, args) \ .text; \ ENTRY (name); \ + .Lpseudo_start: \ SINGLE_THREAD_P; \ bf .Lpseudo_cancel; \ .type __##syscall_name##_nocancel,@function; \ @@ -48,19 +49,27 @@ .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \ .Lpseudo_cancel: \ sts.l pr,@-r15; \ + .LCFI0: \ add _IMM16,r15; \ SAVE_ARGS_##args; \ + .LCFI1: \ CENABLE; \ LOAD_ARGS_##args; \ add _IMP16,r15; \ + .LCFI2: \ lds.l @r15+,pr; \ + .LCFI3: \ DO_CALL(syscall_name, args); \ SYSCALL_INST_PAD; \ sts.l pr,@-r15; \ + .LCFI4: \ mov.l r0,@-r15; \ + .LCFI5: \ CDISABLE; \ mov.l @r15+,r0; \ + .LCFI6: \ lds.l @r15+,pr; \ + .LCFI7: \ mov r0,r1; \ mov _IMM12,r2; \ shad r2,r1; \ @@ -69,7 +78,96 @@ bf .Lpseudo_end; \ .Lsyscall_error: \ SYSCALL_ERROR_HANDLER; \ - .Lpseudo_end: + .Lpseudo_end: \ + /* Create unwinding information for the syscall wrapper. */ \ + .section .eh_frame,"a",@progbits; \ + .Lframe1: \ + .ualong .LECIE1-.LSCIE1; \ + .LSCIE1: \ + .ualong 0x0; \ + .byte 0x1; \ + AUGMENTATION_STRING; \ + .uleb128 0x1; \ + .sleb128 -4; \ + .byte 0x11; \ + AUGMENTATION_PARAM; \ + .byte 0xc; \ + .uleb128 0xf; \ + .uleb128 0x0; \ + .align 2; \ + .LECIE1: \ + .LSFDE1: \ + .ualong .LEFDE1-.LASFDE1; \ + .LASFDE1: \ + .ualong .LASFDE1-.Lframe1; \ + START_SYMBOL_REF; \ + .ualong .Lpseudo_end - .Lpseudo_start; \ + AUGMENTATION_PARAM_FDE; \ + .byte 0x4; \ + .ualong .LCFI0-.Lpseudo_start; \ + .byte 0xe; \ + .uleb128 0x4; \ + .byte 0x91; \ + .uleb128 0x1; \ + .byte 0x4; \ + .ualong .LCFI1-.LCFI0; \ + .byte 0xe; \ + .uleb128 0x14; \ + FRAME_REG_##args; \ + .byte 0x4; \ + .ualong .LCFI2-.LCFI1; \ + .byte 0xe; \ + .uleb128 0x4; \ + .byte 0x4; \ + .ualong .LCFI3-.LCFI2; \ + .byte 0xe; \ + .uleb128 0x0; \ + .byte 0xd1; \ + .byte 0x4; \ + .ualong .LCFI4-.LCFI3; \ + .byte 0xe; \ + .uleb128 0x4; \ + .byte 0x91; \ + .uleb128 0x1; \ + .byte 0x4; \ + .ualong .LCFI5-.LCFI4; \ + .byte 0xe; \ + .uleb128 0x8; \ + .byte 0x80; \ + .uleb128 0x2; \ + .byte 0x4; \ + .ualong .LCFI6-.LCFI5; \ + .byte 0xe; \ + .uleb128 0x4; \ + .byte 0xc0; \ + .byte 0x4; \ + .ualong .LCFI7-.LCFI6; \ + .byte 0xe; \ + .uleb128 0x0; \ + .byte 0xd1; \ + .align 2; \ + .LEFDE1: \ + .previous + +# ifdef SHARED +# define AUGMENTATION_STRING .string "zR" +# define AUGMENTATION_PARAM .uleb128 1; .byte 0x1b +# define AUGMENTATION_PARAM_FDE .uleb128 0 +# define START_SYMBOL_REF .long .Lpseudo_start-. +# else +# define AUGMENTATION_STRING .ascii "\0" +# define AUGMENTATION_PARAM +# define AUGMENTATION_PARAM_FDE +# define START_SYMBOL_REF .long .Lpseudo_start +# endif + +# define FRAME_REG_0 /* Nothing. */ +# define FRAME_REG_1 FRAME_REG_0; .byte 0x84; .uleb128 5 +# define FRAME_REG_2 FRAME_REG_1; .byte 0x85; .uleb128 4 +# define FRAME_REG_3 FRAME_REG_2; .byte 0x86; .uleb128 3 +# define FRAME_REG_4 FRAME_REG_3; .byte 0x87; .uleb128 2 +# define FRAME_REG_5 FRAME_REG_4 +# define FRAME_REG_6 FRAME_REG_5 # undef PSEUDO_END # define PSEUDO_END(sym) \ diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h index b52fa73e0d..e7afd8efec 100644 --- a/sysdeps/unix/sysv/linux/kernel-features.h +++ b/sysdeps/unix/sysv/linux/kernel-features.h @@ -311,7 +311,7 @@ with support. */ #if __LINUX_KERNEL_VERSION >= 132416 \ && (defined __ia64__ || defined __s390__ || defined __powerpc__ \ - || defined __x86_64__) + || defined __x86_64__ || __sh__) # define __ASSUME_CLONE_THREAD_FLAGS 1 #endif @@ -349,7 +349,8 @@ 2.6.0-test3. */ #if (__LINUX_KERNEL_VERSION >= 132427 && defined __i386__) \ || (__LINUX_KERNEL_VERSION >= 132609 && defined __alpha__) \ - || (__LINUX_KERNEL_VERSION >= 132609 && defined __x86_64__) + || (__LINUX_KERNEL_VERSION >= 132609 && defined __x86_64__) \ + || (__LINUX_KERNEL_VERSION >= 132609 && defined __sh__) # define __ASSUME_TGKILL 1 #endif @@ -359,7 +360,8 @@ #if defined __alpha__ || defined __ia64__ || defined __hppa__ \ || defined __sparc__ \ || (__LINUX_KERNEL_VERSION > 132427 && defined __i386__) \ - || (__LINUX_KERNEL_VERSION > 132609 && defined __x86_64__) + || (__LINUX_KERNEL_VERSION > 132609 && defined __x86_64__) \ + || (__LINUX_KERNEL_VERSION >= 132609 && defined __sh__) # define __ASSUME_UTIMES 1 #endif diff --git a/sysdeps/unix/sysv/linux/sh/socket.S b/sysdeps/unix/sysv/linux/sh/socket.S index ac732a2f44..f1369eb49b 100644 --- a/sysdeps/unix/sysv/linux/sh/socket.S +++ b/sysdeps/unix/sysv/linux/sh/socket.S @@ -1,4 +1,4 @@ -/* Copyright (C) 1999, 2000, 2003 Free Software Foundation, Inc. +/* Copyright (C) 1999, 2000, 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 @@ -36,37 +36,67 @@ #define __socket P(__,socket) #endif -#define PUSHARGS_1 mov.l r4,@-r15 -#define PUSHARGS_2 mov.l r5,@-r15; PUSHARGS_1 -#define PUSHARGS_3 mov.l r6,@-r15; PUSHARGS_2 -#define PUSHARGS_4 mov.l r7,@-r15; PUSHARGS_3 +#define PUSHARGS_1 mov.l r4,@-r15; \ + cfi_adjust_cfa_offset (4); \ + cfi_rel_offset (r4, 0) +#define PUSHARGS_2 mov.l r5,@-r15; \ + cfi_adjust_cfa_offset (4); \ + cfi_rel_offset (r5, 0); \ + PUSHARGS_1 +#define PUSHARGS_3 mov.l r6,@-r15; \ + cfi_adjust_cfa_offset (4); \ + cfi_rel_offset (r6, 0); \ + PUSHARGS_2 +#define PUSHARGS_4 mov.l r7,@-r15; \ + cfi_adjust_cfa_offset (4); \ + cfi_rel_offset (r7, 0); \ + PUSHARGS_3 #define PUSHARGS_5 PUSHARGS_4 /* Caller has already pushed arg 5 */ #define PUSHARGS_6 PUSHARGS_4 /* Caller has already pushed arg 5,6 */ -#define POPARGS_1 add #4,r15 -#define POPARGS_2 add #8,r15 -#define POPARGS_3 add #12,r15 -#define POPARGS_4 add #16,r15 -#define POPARGS_5 add #16,r15 -#define POPARGS_6 add #16,r15 +#define POPARGS_1 add #4,r15; cfi_adjust_cfa_offset (-4) +#define POPARGS_2 add #8,r15; cfi_adjust_cfa_offset (-8) +#define POPARGS_3 add #12,r15; cfi_adjust_cfa_offset (-12) +#define POPARGS_4 add #16,r15; cfi_adjust_cfa_offset (-16) +#define POPARGS_5 POPARGS_4 +#define POPARGS_6 POPARGS_4 + +#define ADJUSTCFI_1 cfi_adjust_cfa_offset (4); \ + cfi_offset (r4, -4) +#define ADJUSTCFI_2 cfi_adjust_cfa_offset (8); \ + cfi_offset (r4, -4); \ + cfi_offset (r5, -8) +#define ADJUSTCFI_3 cfi_adjust_cfa_offset (12); \ + cfi_offset (r4, -4); \ + cfi_offset (r5, -8); \ + cfi_offset (r6, -12) +#define ADJUSTCFI_4 cfi_adjust_cfa_offset (16); \ + cfi_offset (r4, -4); \ + cfi_offset (r5, -8); \ + cfi_offset (r6, -12); \ + cfi_offset (r7, -16) +#define ADJUSTCFI_5 ADJUSTCFI_4 +#define ADJUSTCFI_6 ADJUSTCFI_4 #ifndef NARGS -#define NARGS 3 /* If we were called with no wrapper, this is really socket() */ +/* If we were called with no wrapper, this is really socket(). */ +#define NARGS 3 #endif .globl __socket + cfi_startproc ENTRY (__socket) /* This will not work in the case of a socket call being interrupted by a signal. If the signal handler uses any stack the arguments to socket will be trashed. The results of a restart of any - socket call are then unpredictable. */ + socket call are then unpredictable. */ /* Push args onto the stack. */ P(PUSHARGS_,NARGS) #if defined NEED_CANCELLATION && defined CENABLE SINGLE_THREAD_P - bf .Lsocket_cancel + bf .Lsocket_cancel #endif /* Do the system call trap. */ @@ -94,9 +124,14 @@ ENTRY (__socket) #if defined NEED_CANCELLATION && defined CENABLE .Lsocket_cancel: /* Enable asynchronous cancellation. */ + P(ADJUSTCFI_,NARGS) sts.l pr,@-r15 + cfi_adjust_cfa_offset (4) + cfi_rel_offset (pr, 0) CENABLE lds.l @r15+,pr + cfi_adjust_cfa_offset (-4) + cfi_restore (pr) /* Do the system call trap. */ mov #+P(SOCKOP_,socket), r4 @@ -105,10 +140,18 @@ ENTRY (__socket) trapa #0x12 sts.l pr,@-r15 + cfi_adjust_cfa_offset (4) + cfi_rel_offset (pr, 0) mov.l r0,@-r15 + cfi_adjust_cfa_offset (4) + cfi_rel_offset (r0, 0) CDISABLE mov.l @r15+,r0 + cfi_adjust_cfa_offset (-4) + cfi_restore (r0) lds.l @r15+,pr + cfi_adjust_cfa_offset (-4) + cfi_restore (pr) /* Pop args off the stack */ P(POPARGS_,NARGS) @@ -122,6 +165,8 @@ ENTRY (__socket) bra .Lsyscall_error nop #endif + cfi_endproc + .align 2 .L1: .long SYS_ify(socketcall) -- cgit 1.4.1