aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--nptl/ChangeLog21
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/lowlevel-atomic.h13
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S17
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S42
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S35
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S4
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S417
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S464
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S103
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S35
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h102
-rw-r--r--sysdeps/unix/sysv/linux/kernel-features.h8
-rw-r--r--sysdeps/unix/sysv/linux/sh/socket.S73
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 <kkojima@rr.iij4u.or.jp>
+
+ * 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 <drepper@redhat.com>
* 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 <kkojima@rr.iij4u.or.jp>
+
+ * 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 <drepper@redhat.com>
* 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 <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
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)