[PATCH] nptl: add libpthread __errno_location wrapper
Roman I Khimov
khimov at altell.ru
Fri Apr 30 14:18:33 UTC 2010
Trivial test case for x86_64:
==============================================================
static void *process(void * arg)
{
void *a = &errno;
printf("thread errno addr: %llx\n", a);
__asm__("movq errno at gottpoff(%%rip), %0;\n"
"add %%fs:0x0,%0;" : "=r"(a) );
printf("thread got errno addr: %llx\n", a);
return NULL;
}
int main() {
void *a = &errno;
pthread_t thread;
printf("errno addr: %llx\n", a);
__asm__("movq errno at gottpoff(%%rip), %0;\n"
"add %%fs:0x0,%0;" : "=r"(a) );
printf("got errno addr: %llx\n", a);
pthread_create(&thread, NULL, process, NULL);
pthread_join(thread, a);
}
==============================================================
lead to different errno addresses. Direct access through the GOT (as
opposed to __errno_location) is used a lot in arch-speficic NPTL routines, so
errno was broken in many cases, for example, it was easily seen in tst-sem1,
tst-sem3, tst-mqueue2 and other nptl tests.
I've not found any better solution than to introduce local __errno_location
wrapper which seems to work fine (fixed 7 nptl tests).
---
libpthread/nptl/Makefile.in | 2 +-
libpthread/nptl/errno.c | 31 +++++++++++++++++++++++++++++++
2 files changed, 32 insertions(+), 1 deletions(-)
create mode 100644 libpthread/nptl/errno.c
diff --git a/libpthread/nptl/Makefile.in b/libpthread/nptl/Makefile.in
index c229673..9b48400 100644
--- a/libpthread/nptl/Makefile.in
+++ b/libpthread/nptl/Makefile.in
@@ -95,7 +95,7 @@ libpthread-routines = init vars events version \
pt-raise pt-system \
flockfile ftrylockfile funlockfile \
sigaction \
- herrno res \
+ herrno errno res \
pthread_kill_other_threads \
pthread_getaffinity pthread_setaffinity \
pthread_attr_getaffinity pthread_attr_setaffinity \
diff --git a/libpthread/nptl/errno.c b/libpthread/nptl/errno.c
new file mode 100644
index 0000000..f66b335
--- /dev/null
+++ b/libpthread/nptl/errno.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 1996,97,98,2002 Free Software Foundation, Inc.
+
+ 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <features.h>
+#include <errno.h>
+#undef errno
+
+#include <tls.h>
+
+extern __thread int errno;
+
+/* When threaded, errno should be a per-thread variable. */
+int *
+__errno_location (void)
+{
+ return &errno;
+}
--
1.5.6.5
More information about the uClibc
mailing list