Fix exception table for i386 pthread_cond_wait
[BZ #14477] Add an additional entry in the exception table to jump to __condvar_w_cleanup2 instead of __condvar_w_cleanup for PI mutexes when %ebx contains the address of the futex instead of the condition variable.
This commit is contained in:
parent
bec749fda1
commit
55a051c985
6
NEWS
6
NEWS
|
@ -13,9 +13,9 @@ Version 2.17
|
||||||
10038, 11438, 11607, 13412, 13542, 13629, 13679, 13696, 13717, 13741,
|
10038, 11438, 11607, 13412, 13542, 13629, 13679, 13696, 13717, 13741,
|
||||||
13939, 13966, 14042, 14090, 14150, 14151, 14154, 14157, 14166, 14173,
|
13939, 13966, 14042, 14090, 14150, 14151, 14154, 14157, 14166, 14173,
|
||||||
14195, 14237, 14252, 14283, 14298, 14303, 14307, 14328, 14331, 14336,
|
14195, 14237, 14252, 14283, 14298, 14303, 14307, 14328, 14331, 14336,
|
||||||
14337, 14347, 14349, 14376, 14459, 14476, 14505, 14510, 14516, 14518,
|
14337, 14347, 14349, 14376, 14459, 14476, 14477, 14505, 14510, 14516,
|
||||||
14519, 14530, 14532, 14538, 14543, 14544, 14545, 14562, 14576, 14579,
|
14518, 14519, 14530, 14532, 14538, 14543, 14544, 14545, 14562, 14576,
|
||||||
14583, 14587, 14621, 14638, 14645.
|
14579, 14583, 14587, 14621, 14638, 14645.
|
||||||
|
|
||||||
* Support for STT_GNU_IFUNC symbols added for s390 and s390x.
|
* Support for STT_GNU_IFUNC symbols added for s390 and s390x.
|
||||||
Optimized versions of memcpy, memset, and memcmp added for System z10 and
|
Optimized versions of memcpy, memset, and memcmp added for System z10 and
|
||||||
|
|
|
@ -1,3 +1,19 @@
|
||||||
|
2012-10-01 Siddhesh Poyarekar <siddhesh@redhat.com>
|
||||||
|
|
||||||
|
[BZ #14477]
|
||||||
|
* Makefile (tests): Add tst-cond-except.
|
||||||
|
* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
|
||||||
|
(__pthread_cond_timedwait): Mark instructions where %ebx is
|
||||||
|
incremented in PI case.
|
||||||
|
(.gcc_except_table): Add entry to jump to __condvar_tw_cleanup2
|
||||||
|
for the marked PI case instructions.
|
||||||
|
* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
|
||||||
|
(__pthread_cond_wait): Mark instructions where %ebx is
|
||||||
|
incremented in PI case.
|
||||||
|
(.gcc_except_table): Add entry to jump to __condvar_w_cleanup2
|
||||||
|
for the marked PI case instructions.
|
||||||
|
* tst-cond-except.c: New test case.
|
||||||
|
|
||||||
2012-09-24 Dmitry V. Levin <ldv@altlinux.org>
|
2012-09-24 Dmitry V. Levin <ldv@altlinux.org>
|
||||||
|
|
||||||
* tst-tls6.sh: Add "set -e".
|
* tst-tls6.sh: Add "set -e".
|
||||||
|
|
|
@ -206,7 +206,7 @@ tests = tst-typesizes \
|
||||||
tst-cond1 tst-cond2 tst-cond3 tst-cond4 tst-cond5 tst-cond6 tst-cond7 \
|
tst-cond1 tst-cond2 tst-cond3 tst-cond4 tst-cond5 tst-cond6 tst-cond7 \
|
||||||
tst-cond8 tst-cond9 tst-cond10 tst-cond11 tst-cond12 tst-cond13 \
|
tst-cond8 tst-cond9 tst-cond10 tst-cond11 tst-cond12 tst-cond13 \
|
||||||
tst-cond14 tst-cond15 tst-cond16 tst-cond17 tst-cond18 tst-cond19 \
|
tst-cond14 tst-cond15 tst-cond16 tst-cond17 tst-cond18 tst-cond19 \
|
||||||
tst-cond20 tst-cond21 tst-cond22 tst-cond23 \
|
tst-cond20 tst-cond21 tst-cond22 tst-cond23 tst-cond-except \
|
||||||
tst-robust1 tst-robust2 tst-robust3 tst-robust4 tst-robust5 \
|
tst-robust1 tst-robust2 tst-robust3 tst-robust4 tst-robust5 \
|
||||||
tst-robust6 tst-robust7 tst-robust8 tst-robust9 \
|
tst-robust6 tst-robust7 tst-robust8 tst-robust9 \
|
||||||
tst-robustpi1 tst-robustpi2 tst-robustpi3 tst-robustpi4 tst-robustpi5 \
|
tst-robustpi1 tst-robustpi2 tst-robustpi3 tst-robustpi4 tst-robustpi5 \
|
||||||
|
|
|
@ -200,9 +200,11 @@ __pthread_cond_timedwait:
|
||||||
42: leal (%ebp), %esi
|
42: leal (%ebp), %esi
|
||||||
movl 28(%esp), %edx
|
movl 28(%esp), %edx
|
||||||
addl $cond_futex, %ebx
|
addl $cond_futex, %ebx
|
||||||
|
.Ladd_cond_futex_pi:
|
||||||
movl $SYS_futex, %eax
|
movl $SYS_futex, %eax
|
||||||
ENTER_KERNEL
|
ENTER_KERNEL
|
||||||
subl $cond_futex, %ebx
|
subl $cond_futex, %ebx
|
||||||
|
.Lsub_cond_futex_pi:
|
||||||
movl %eax, %esi
|
movl %eax, %esi
|
||||||
/* Set the pi-requeued flag only if the kernel has returned 0. The
|
/* Set the pi-requeued flag only if the kernel has returned 0. The
|
||||||
kernel does not hold the mutex on ETIMEDOUT or any other error. */
|
kernel does not hold the mutex on ETIMEDOUT or any other error. */
|
||||||
|
@ -638,7 +640,15 @@ __condvar_tw_cleanup:
|
||||||
.uleb128 .Lcstend-.Lcstbegin
|
.uleb128 .Lcstend-.Lcstbegin
|
||||||
.Lcstbegin:
|
.Lcstbegin:
|
||||||
.long .LcleanupSTART-.LSTARTCODE
|
.long .LcleanupSTART-.LSTARTCODE
|
||||||
.long .Ladd_cond_futex-.LcleanupSTART
|
.long .Ladd_cond_futex_pi-.LcleanupSTART
|
||||||
|
.long __condvar_tw_cleanup-.LSTARTCODE
|
||||||
|
.uleb128 0
|
||||||
|
.long .Ladd_cond_futex_pi-.LSTARTCODE
|
||||||
|
.long .Lsub_cond_futex_pi-.Ladd_cond_futex_pi
|
||||||
|
.long __condvar_tw_cleanup2-.LSTARTCODE
|
||||||
|
.uleb128 0
|
||||||
|
.long .Lsub_cond_futex_pi-.LSTARTCODE
|
||||||
|
.long .Ladd_cond_futex-.Lsub_cond_futex_pi
|
||||||
.long __condvar_tw_cleanup-.LSTARTCODE
|
.long __condvar_tw_cleanup-.LSTARTCODE
|
||||||
.uleb128 0
|
.uleb128 0
|
||||||
.long .Ladd_cond_futex-.LSTARTCODE
|
.long .Ladd_cond_futex-.LSTARTCODE
|
||||||
|
|
|
@ -141,9 +141,11 @@ __pthread_cond_wait:
|
||||||
movl %ebp, %edx
|
movl %ebp, %edx
|
||||||
xorl %esi, %esi
|
xorl %esi, %esi
|
||||||
addl $cond_futex, %ebx
|
addl $cond_futex, %ebx
|
||||||
|
.Ladd_cond_futex_pi:
|
||||||
movl $SYS_futex, %eax
|
movl $SYS_futex, %eax
|
||||||
ENTER_KERNEL
|
ENTER_KERNEL
|
||||||
subl $cond_futex, %ebx
|
subl $cond_futex, %ebx
|
||||||
|
.Lsub_cond_futex_pi:
|
||||||
/* Set the pi-requeued flag only if the kernel has returned 0. The
|
/* Set the pi-requeued flag only if the kernel has returned 0. The
|
||||||
kernel does not hold the mutex on error. */
|
kernel does not hold the mutex on error. */
|
||||||
cmpl $0, %eax
|
cmpl $0, %eax
|
||||||
|
@ -630,7 +632,15 @@ __condvar_w_cleanup:
|
||||||
.uleb128 .Lcstend-.Lcstbegin
|
.uleb128 .Lcstend-.Lcstbegin
|
||||||
.Lcstbegin:
|
.Lcstbegin:
|
||||||
.long .LcleanupSTART-.LSTARTCODE
|
.long .LcleanupSTART-.LSTARTCODE
|
||||||
.long .Ladd_cond_futex-.LcleanupSTART
|
.long .Ladd_cond_futex_pi-.LcleanupSTART
|
||||||
|
.long __condvar_w_cleanup-.LSTARTCODE
|
||||||
|
.uleb128 0
|
||||||
|
.long .Ladd_cond_futex_pi-.LSTARTCODE
|
||||||
|
.long .Lsub_cond_futex_pi-.Ladd_cond_futex_pi
|
||||||
|
.long __condvar_w_cleanup2-.LSTARTCODE
|
||||||
|
.uleb128 0
|
||||||
|
.long .Lsub_cond_futex_pi-.LSTARTCODE
|
||||||
|
.long .Ladd_cond_futex-.Lsub_cond_futex_pi
|
||||||
.long __condvar_w_cleanup-.LSTARTCODE
|
.long __condvar_w_cleanup-.LSTARTCODE
|
||||||
.uleb128 0
|
.uleb128 0
|
||||||
.long .Ladd_cond_futex-.LSTARTCODE
|
.long .Ladd_cond_futex-.LSTARTCODE
|
||||||
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
/* Verify that exception table for pthread_cond_wait is correct.
|
||||||
|
Copyright (C) 2012 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
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library; if not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
pthread_mutex_t mutex;
|
||||||
|
pthread_cond_t cond;
|
||||||
|
|
||||||
|
#define CHECK_RETURN_VAL_OR_FAIL(ret,str) \
|
||||||
|
({ if ((ret) != 0) \
|
||||||
|
{ \
|
||||||
|
printf ("%s failed: %s\n", (str), strerror (ret)); \
|
||||||
|
ret = 1; \
|
||||||
|
goto out; \
|
||||||
|
} \
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
clean (void *arg)
|
||||||
|
{
|
||||||
|
puts ("clean: Unlocking mutex...");
|
||||||
|
pthread_mutex_unlock ((pthread_mutex_t *) arg);
|
||||||
|
puts ("clean: Mutex unlocked...");
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
thr (void *arg)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
pthread_mutexattr_t mutexAttr;
|
||||||
|
ret = pthread_mutexattr_init (&mutexAttr);
|
||||||
|
CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_mutexattr_init");
|
||||||
|
|
||||||
|
ret = pthread_mutexattr_setprotocol (&mutexAttr, PTHREAD_PRIO_INHERIT);
|
||||||
|
CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_mutexattr_setprotocol");
|
||||||
|
|
||||||
|
ret = pthread_mutex_init (&mutex, &mutexAttr);
|
||||||
|
CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_mutex_init");
|
||||||
|
|
||||||
|
ret = pthread_cond_init (&cond, 0);
|
||||||
|
CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_cond_init");
|
||||||
|
|
||||||
|
puts ("th: Init done, entering wait...");
|
||||||
|
|
||||||
|
pthread_cleanup_push (clean, (void *) &mutex);
|
||||||
|
ret = pthread_mutex_lock (&mutex);
|
||||||
|
CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_mutex_lock");
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
ret = pthread_cond_wait (&cond, &mutex);
|
||||||
|
CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_cond_wait");
|
||||||
|
}
|
||||||
|
pthread_cleanup_pop (1);
|
||||||
|
|
||||||
|
out:
|
||||||
|
return (void *)ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
do_test ()
|
||||||
|
{
|
||||||
|
pthread_t thread;
|
||||||
|
int ret = 0;
|
||||||
|
void *thr_ret = 0;
|
||||||
|
ret = pthread_create (&thread, 0, thr, &thr_ret);
|
||||||
|
CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_create");
|
||||||
|
|
||||||
|
puts ("main: Thread created, waiting a bit...");
|
||||||
|
sleep (2);
|
||||||
|
|
||||||
|
puts ("main: Cancelling thread...");
|
||||||
|
ret = pthread_cancel (thread);
|
||||||
|
CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_cancel");
|
||||||
|
|
||||||
|
puts ("main: Joining th...");
|
||||||
|
ret = pthread_join (thread, NULL);
|
||||||
|
CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_join");
|
||||||
|
|
||||||
|
if (thr_ret != NULL)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
puts ("main: Joined thread, done!");
|
||||||
|
|
||||||
|
out:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define TIMEOUT 5
|
||||||
|
#include "../test-skeleton.c"
|
Loading…
Reference in New Issue