1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837
|
From: Thomas Schwinge <thomas@schwinge.name>
Subject: [PATCH] tls-threadvar
replace the custom threadvar mechanism with generic TLS.
That will fix sigaltstack.
Note: the added reply_port and _hurd_sigstate fields should be kept last.
---
hurd/Versions | 6 --
hurd/hurd/signal.h | 23 ++++----
hurd/hurd/threadvar.h | 76 ++--------------------------
hurd/hurdsig.c | 51 +++++++++++-------
hurd/hurdstartup.c | 1
hurd/sigunwind.c | 4 -
include/errno.h | 2
sysdeps/mach/hurd/Versions | 4 -
sysdeps/mach/hurd/cthreads.c | 2
sysdeps/mach/hurd/dl-sysdep.c | 19 -------
sysdeps/mach/hurd/errno-loc.c | 22 +++++---
sysdeps/mach/hurd/errno.c | 1
sysdeps/mach/hurd/fork.c | 7 +-
sysdeps/mach/hurd/i386/init-first.c | 35 ------------
sysdeps/mach/hurd/i386/makecontext-helper.c | 2
sysdeps/mach/hurd/i386/makecontext.S | 2
sysdeps/mach/hurd/i386/sigreturn.c | 5 -
sysdeps/mach/hurd/i386/tls.h | 29 ++++++++++
sysdeps/mach/hurd/libc-lock.h | 4 -
sysdeps/mach/hurd/libc-tsd.h | 34 ------------
sysdeps/mach/hurd/mig-reply.c | 39 +++-----------
sysdeps/mach/hurd/profil.c | 6 +-
22 files changed, 126 insertions(+), 248 deletions(-)
--- a/hurd/Versions
+++ b/hurd/Versions
@@ -4,14 +4,9 @@
_end;
# variables used in macros & inline functions
- __hurd_sigthread_stack_base; __hurd_sigthread_stack_end;
- __hurd_sigthread_variables;
__hurd_threadvar_max;
__hurd_threadvar_stack_mask; __hurd_threadvar_stack_offset;
- # functions used in macros & inline functions
- __hurd_errno_location;
-
# functions used in libmachuser and libhurduser
_S_catch_exception_raise;
_S_catch_exception_raise_state;
@@ -133,6 +128,7 @@
HURD_CTHREADS_0.3 {
# weak refs to libthreads functions that libc calls iff libthreads in use
cthread_fork; cthread_detach;
+ pthread_getattr_np; pthread_attr_getstack;
# variables used for detecting cthreads
_cthread_exit_routine; _cthread_init_routine;
--- a/hurd/hurd/signal.h
+++ b/hurd/hurd/signal.h
@@ -40,7 +40,6 @@
#include <cthreads.h> /* For `struct mutex'. */
#include <setjmp.h> /* For `jmp_buf'. */
#include <spin-lock.h>
-#include <hurd/threadvar.h> /* We cache sigstate in a threadvar. */
struct hurd_signal_preemptor; /* <hurd/sigpreempt.h> */
@@ -132,11 +131,9 @@
_HURD_SIGNAL_H_EXTERN_INLINE struct hurd_sigstate *
_hurd_self_sigstate (void)
{
- struct hurd_sigstate **location = (struct hurd_sigstate **)
- (void *) __hurd_threadvar_location (_HURD_THREADVAR_SIGSTATE);
- if (*location == NULL)
- *location = _hurd_thread_sigstate (__mach_thread_self ());
- return *location;
+ if (THREAD_SELF->_hurd_sigstate == NULL)
+ THREAD_SELF->_hurd_sigstate = _hurd_thread_sigstate (__mach_thread_self ());
+ return THREAD_SELF->_hurd_sigstate;
}
/* Thread listening on our message port; also called the "signal thread". */
@@ -167,16 +164,22 @@
_HURD_SIGNAL_H_EXTERN_INLINE void *
_hurd_critical_section_lock (void)
{
- struct hurd_sigstate **location = (struct hurd_sigstate **)
- (void *) __hurd_threadvar_location (_HURD_THREADVAR_SIGSTATE);
- struct hurd_sigstate *ss = *location;
+ struct hurd_sigstate *ss;
+
+#ifdef __LIBC_NO_TLS
+ if (__LIBC_NO_TLS())
+ /* TLS is currently initializing, no need to enter critical section. */
+ return NULL;
+#endif
+
+ ss = THREAD_SELF->_hurd_sigstate;
if (ss == NULL)
{
/* The thread variable is unset; this must be the first time we've
asked for it. In this case, the critical section flag cannot
possible already be set. Look up our sigstate structure the slow
way. */
- ss = *location = _hurd_thread_sigstate (__mach_thread_self ());
+ ss = THREAD_SELF->_hurd_sigstate = _hurd_thread_sigstate (__mach_thread_self ());
}
if (! __spin_try_lock (&ss->critical_section_lock))
--- a/hurd/hurd/threadvar.h
+++ b/hurd/hurd/threadvar.h
@@ -20,6 +20,7 @@
#define _HURD_THREADVAR_H
#include <features.h>
+#include <tls.h>
/* The per-thread variables are found by ANDing this mask
with the value of the stack pointer and then adding this offset.
@@ -30,87 +31,24 @@
__hurd_threadvar_stack_offset to a small offset that skips the data
cthreads itself maintains at the base of each thread's stack.
- In the single-threaded case, __hurd_threadvar_stack_mask is zero, so the
- stack pointer is ignored; and __hurd_threadvar_stack_offset gives the
- address of a small allocated region which contains the variables for the
- single thread. */
+ In the single-threaded or libpthread case, __hurd_threadvar_stack_mask is
+ zero, so the stack pointer is ignored. */
extern unsigned long int __hurd_threadvar_stack_mask;
extern unsigned long int __hurd_threadvar_stack_offset;
-/* A special case must always be made for the signal thread. Even when there
- is only one user thread and an allocated region can be used for the user
- thread's variables, the signal thread needs to have its own location for
- per-thread variables. The variables __hurd_sigthread_stack_base and
+/* The variables __hurd_sigthread_stack_base and
__hurd_sigthread_stack_end define the bounds of the stack used by the
signal thread, so that thread can always be specifically identified. */
extern unsigned long int __hurd_sigthread_stack_base;
extern unsigned long int __hurd_sigthread_stack_end;
-extern unsigned long int *__hurd_sigthread_variables;
-/* At the location described by the two variables above,
- there are __hurd_threadvar_max `unsigned long int's of per-thread data. */
+/* We do not use threadvars any more, this is kept as zero for compatibility with cthreads */
extern unsigned int __hurd_threadvar_max;
-/* These values are the indices for the standard per-thread variables. */
-enum __hurd_threadvar_index
- {
- _HURD_THREADVAR_MIG_REPLY, /* Reply port for MiG user stub functions. */
- _HURD_THREADVAR_ERRNO, /* `errno' value for this thread. */
- _HURD_THREADVAR_SIGSTATE, /* This thread's `struct hurd_sigstate'. */
- _HURD_THREADVAR_DYNAMIC_USER, /* Dynamically-assigned user variables. */
- _HURD_THREADVAR_MALLOC, /* For use of malloc. */
- _HURD_THREADVAR_DL_ERROR, /* For use of -ldl and dynamic linker. */
- _HURD_THREADVAR_RPC_VARS, /* For state of RPC functions. */
- _HURD_THREADVAR_LOCALE, /* For thread-local locale setting. */
- _HURD_THREADVAR_CTYPE_B, /* Cache of thread-local locale data. */
- _HURD_THREADVAR_CTYPE_TOLOWER, /* Cache of thread-local locale data. */
- _HURD_THREADVAR_CTYPE_TOUPPER, /* Cache of thread-local locale data. */
- _HURD_THREADVAR_MAX /* Default value for __hurd_threadvar_max. */
- };
-
-
-#ifndef _HURD_THREADVAR_H_EXTERN_INLINE
-#define _HURD_THREADVAR_H_EXTERN_INLINE __extern_inline
-#endif
-
-/* Return the location of the value for the per-thread variable with index
- INDEX used by the thread whose stack pointer is SP. */
-
-extern unsigned long int *__hurd_threadvar_location_from_sp
- (enum __hurd_threadvar_index __index, void *__sp);
-_HURD_THREADVAR_H_EXTERN_INLINE unsigned long int *
-__hurd_threadvar_location_from_sp (enum __hurd_threadvar_index __index,
- void *__sp)
-{
- unsigned long int __stack = (unsigned long int) __sp;
- return &((__stack >= __hurd_sigthread_stack_base &&
- __stack < __hurd_sigthread_stack_end)
- ? __hurd_sigthread_variables
- : (unsigned long int *) ((__stack & __hurd_threadvar_stack_mask) +
- __hurd_threadvar_stack_offset))[__index];
-}
-
-#include <machine-sp.h> /* Define __thread_stack_pointer. */
-
-/* Return the location of the current thread's value for the
- per-thread variable with index INDEX. */
-
-extern unsigned long int *
-__hurd_threadvar_location (enum __hurd_threadvar_index __index) __THROW
- /* This declaration tells the compiler that the value is constant
- given the same argument. We assume this won't be called twice from
- the same stack frame by different threads. */
- __attribute__ ((__const__));
-
-_HURD_THREADVAR_H_EXTERN_INLINE unsigned long int *
-__hurd_threadvar_location (enum __hurd_threadvar_index __index)
-{
- return __hurd_threadvar_location_from_sp (__index,
- __thread_stack_pointer ());
-}
-
+extern mach_port_t __hurd_reply_port0;
+#define __hurd_local_reply_port (*(__LIBC_NO_TLS() ? &__hurd_reply_port0 : &THREAD_SELF->reply_port))
#endif /* hurd/threadvar.h */
--- a/hurd/hurdsig.c
+++ b/hurd/hurdsig.c
@@ -20,6 +20,7 @@
#include <string.h>
#include <cthreads.h> /* For `struct mutex'. */
+#include <pthread.h>
#include <mach.h>
#include <mach/thread_switch.h>
@@ -48,7 +49,6 @@
/* These are set up by _hurdsig_init. */
unsigned long int __hurd_sigthread_stack_base;
unsigned long int __hurd_sigthread_stack_end;
-unsigned long int *__hurd_sigthread_variables;
/* Linked-list of per-thread signal state. */
struct hurd_sigstate *_hurd_sigstates;
@@ -234,14 +234,14 @@
that this location can be set without faulting, or else return NULL. */
static mach_port_t *
-interrupted_reply_port_location (struct machine_thread_all_state *thread_state,
+interrupted_reply_port_location (thread_t thread,
+ struct machine_thread_all_state *thread_state,
int sigthread)
{
- mach_port_t *portloc = (mach_port_t *) __hurd_threadvar_location_from_sp
- (_HURD_THREADVAR_MIG_REPLY, (void *) thread_state->basic.SP);
+ mach_port_t *portloc = &THREAD_TCB(thread, thread_state)->reply_port;
if (sigthread && _hurdsig_catch_memory_fault (portloc))
- /* Faulted trying to read the stack. */
+ /* Faulted trying to read the TCB. */
return NULL;
/* Fault now if this pointer is bogus. */
@@ -323,7 +323,8 @@
our nonzero return tells the trampoline code to finish the message
receive operation before running the handler. */
- mach_port_t *reply = interrupted_reply_port_location (state,
+ mach_port_t *reply = interrupted_reply_port_location (ss->thread,
+ state,
sigthread);
error_t err = __interrupt_operation (intr_port, _hurdsig_interrupt_timeout);
@@ -835,7 +836,8 @@
if (! machine_get_basic_state (ss->thread, &thread_state))
goto sigbomb;
- loc = interrupted_reply_port_location (&thread_state, 1);
+ loc = interrupted_reply_port_location (ss->thread,
+ &thread_state, 1);
if (loc && *loc != MACH_PORT_NULL)
/* This is the reply port for the context which called
sigreturn. Since we are abandoning that context entirely
@@ -901,7 +903,8 @@
{
/* Fetch the thread variable for the MiG reply port,
and set it to MACH_PORT_NULL. */
- mach_port_t *loc = interrupted_reply_port_location (&thread_state,
+ mach_port_t *loc = interrupted_reply_port_location (ss->thread,
+ &thread_state,
1);
if (loc)
{
@@ -1255,7 +1258,11 @@
/* Start the signal thread listening on the message port. */
- if (__hurd_threadvar_stack_mask == 0)
+#pragma weak cthread_fork
+#pragma weak cthread_detach
+#pragma weak pthread_getattr_np
+#pragma weak pthread_attr_getstack
+ if (!cthread_fork)
{
err = __thread_create (__mach_task_self (), &_hurd_msgport_thread);
assert_perror (err);
@@ -1270,14 +1277,6 @@
assert_perror (err);
__hurd_sigthread_stack_end = __hurd_sigthread_stack_base + stacksize;
- __hurd_sigthread_variables =
- malloc (__hurd_threadvar_max * sizeof (unsigned long int));
- if (__hurd_sigthread_variables == NULL)
- __libc_fatal ("hurd: Can't allocate threadvars for signal thread\n");
- memset (__hurd_sigthread_variables, 0,
- __hurd_threadvar_max * sizeof (unsigned long int));
- __hurd_sigthread_variables[_HURD_THREADVAR_LOCALE]
- = (unsigned long int) &_nl_global_locale;
/* Reinitialize the MiG support routines so they will use a per-thread
variable for the cached reply port. */
@@ -1288,6 +1287,7 @@
}
else
{
+ cthread_t thread;
/* When cthreads is being used, we need to make the signal thread a
proper cthread. Otherwise it cannot use mutex_lock et al, which
will be the cthreads versions. Various of the message port RPC
@@ -1297,9 +1297,20 @@
we'll let the signal thread's per-thread variables be found as for
any normal cthread, and just leave the magic __hurd_sigthread_*
values all zero so they'll be ignored. */
-#pragma weak cthread_fork
-#pragma weak cthread_detach
- cthread_detach (cthread_fork ((cthread_fn_t) &_hurd_msgport_receive, 0));
+ cthread_detach (thread = cthread_fork ((cthread_fn_t) &_hurd_msgport_receive, 0));
+
+ if (pthread_getattr_np)
+ {
+ /* Record stack layout for fork() */
+ pthread_attr_t attr;
+ void *addr;
+ size_t size;
+
+ pthread_getattr_np ((pthread_t) thread, &attr);
+ pthread_attr_getstack (&attr, &addr, &size);
+ __hurd_sigthread_stack_base = (uintptr_t) addr;
+ __hurd_sigthread_stack_end = __hurd_sigthread_stack_base + size;
+ }
/* XXX We need the thread port for the signal thread further on
in this thread (see hurdfault.c:_hurdsigfault_init).
--- a/hurd/hurdstartup.c
+++ b/hurd/hurdstartup.c
@@ -23,7 +23,6 @@
#include <hurd.h>
#include <hurd/exec_startup.h>
#include <sysdep.h>
-#include <hurd/threadvar.h>
#include <unistd.h>
#include <elf.h>
#include <set-hooks.h>
--- a/hurd/sigunwind.c
+++ b/hurd/sigunwind.c
@@ -18,6 +18,7 @@
#include <hurd.h>
#include <thread_state.h>
+#include <hurd/threadvar.h>
#include <jmpbuf-unwind.h>
#include <assert.h>
#include <stdint.h>
@@ -38,8 +39,7 @@
{
/* Destroy the MiG reply port used by the signal handler, and restore
the reply port in use by the thread when interrupted. */
- mach_port_t *reply_port =
- (mach_port_t *) __hurd_threadvar_location (_HURD_THREADVAR_MIG_REPLY);
+ mach_port_t *reply_port = &__hurd_local_reply_port;
if (*reply_port)
{
mach_port_t port = *reply_port;
--- a/include/errno.h
+++ b/include/errno.h
@@ -26,7 +26,7 @@
# include <tls.h>
-# if !defined(__GNU__)
+# if !(defined(__GNU__) && IS_IN (rtld))
# undef errno
# if IS_IN (libc)
# define errno __libc_errno
--- a/sysdeps/mach/hurd/Versions
+++ b/sysdeps/mach/hurd/Versions
@@ -6,6 +6,7 @@
GLIBC_PRIVATE {
# Functions shared with the dynamic linker
__libc_read; __libc_write; __libc_lseek64;
+ __libc_lock_self0;
_dl_init_first;
}
@@ -14,8 +15,6 @@
ld {
GLIBC_2.0 {
# variables that must be shared with libc
- __hurd_sigthread_stack_base; __hurd_sigthread_stack_end;
- __hurd_sigthread_variables;
__hurd_threadvar_stack_mask; __hurd_threadvar_stack_offset;
# functions that must be shared with libc
@@ -33,5 +32,6 @@
# functions that must be shared with libc
__libc_read; __libc_write; __libc_lseek64;
+ __libc_lock_self0;
}
}
--- a/sysdeps/mach/hurd/libc-lock.h
+++ b/sysdeps/mach/hurd/libc-lock.h
@@ -24,7 +24,6 @@
#include <tls.h>
#endif
#include <cthreads.h>
-#include <hurd/threadvar.h>
/* The locking here is very inexpensive, even for inlining. */
#define _IO_lock_inexpensive 1
@@ -38,7 +37,8 @@
} __libc_lock_recursive_t;
typedef __libc_lock_recursive_t __rtld_lock_recursive_t;
-#define __libc_lock_owner_self() ((void *) __hurd_threadvar_location (0))
+extern char __libc_lock_self0[0];
+#define __libc_lock_owner_self() (__LIBC_NO_TLS() ? &__libc_lock_self0 : THREAD_SELF)
#else
typedef struct __libc_lock_opaque__ __libc_lock_t;
--- a/sysdeps/mach/hurd/libc-tsd.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* libc-internal interface for thread-specific data. Hurd version.
- Copyright (C) 1998-2016 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/>. */
-
-#ifndef _LIBC_TSD_H
-#define _LIBC_TSD_H 1
-
-#include <hurd/threadvar.h>
-
-#define __libc_tsd_define(CLASS, TYPE, KEY) /* nothing, always have threadvars */
-
-#define __libc_tsd_address(TYPE, KEY) \
- ((TYPE *) __hurd_threadvar_location (_HURD_THREADVAR_##KEY))
-
-#define __libc_tsd_get(TYPE, KEY) \
- (*__libc_tsd_address (TYPE, KEY))
-#define __libc_tsd_set(TYPE, KEY, VALUE) \
- (*__libc_tsd_address (TYPE, KEY) = (VALUE))
-
-#endif /* libc-tsd.h */
--- a/sysdeps/mach/hurd/cthreads.c
+++ b/sysdeps/mach/hurd/cthreads.c
@@ -19,6 +19,8 @@
#include <errno.h>
#include <stdlib.h>
+char __libc_lock_self0[0];
+
/* Placeholder for key creation routine from Hurd cthreads library. */
int
weak_function
--- a/sysdeps/mach/hurd/dl-sysdep.c
+++ b/sysdeps/mach/hurd/dl-sysdep.c
@@ -65,25 +65,6 @@
struct hurd_startup_data *_dl_hurd_data;
-/* This is used only within ld.so, via dl-minimal.c's __errno_location. */
-#undef errno
-int errno attribute_hidden;
-
-/* Defining these variables here avoids the inclusion of hurdsig.c. */
-unsigned long int __hurd_sigthread_stack_base;
-unsigned long int __hurd_sigthread_stack_end;
-unsigned long int *__hurd_sigthread_variables;
-
-/* Defining these variables here avoids the inclusion of init-first.c.
- We need to provide temporary storage for the per-thread variables
- of the main user thread here, since it is used for storing the
- `errno' variable. Note that this information is lost once we
- relocate the dynamic linker. */
-static unsigned long int threadvars[_HURD_THREADVAR_MAX];
-unsigned long int __hurd_threadvar_stack_offset
- = (unsigned long int) &threadvars;
-unsigned long int __hurd_threadvar_stack_mask;
-
#define FMH defined(__i386__)
#if ! FMH
# define fmh() ((void)0)
--- a/sysdeps/mach/hurd/errno-loc.c
+++ b/sysdeps/mach/hurd/errno-loc.c
@@ -16,13 +16,21 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-#include <errno.h>
-#include <hurd/threadvar.h>
-
-int *
+#if IS_IN (rtld)
+/*
+ * rtld can not access TLS too early, thus rtld_errno.
+ *
+ * Instead of making __open/__close pass errno from TLS to rtld_errno, simply
+ * use a weak __errno_location using rtld_errno, which will be overriden by the
+ * libc definition.
+ */
+static int rtld_errno;
+int * weak_function
__errno_location (void)
{
- return (int *) __hurd_threadvar_location (_HURD_THREADVAR_ERRNO);
+ return &rtld_errno;
}
-strong_alias (__errno_location, __hurd_errno_location)
-libc_hidden_def (__errno_location)
+libc_hidden_weak (__errno_location)
+#else
+#include <../../../csu/errno-loc.c>
+#endif
--- a/sysdeps/mach/hurd/errno.c
+++ /dev/null
@@ -1 +0,0 @@
-/* No definition of `errno' variable on the Hurd. */
--- a/sysdeps/mach/hurd/fork.c
+++ b/sysdeps/mach/hurd/fork.c
@@ -19,6 +19,7 @@
#include <unistd.h>
#include <hurd.h>
#include <hurd/signal.h>
+#include <hurd/threadvar.h>
#include <setjmp.h>
#include <thread_state.h>
#include <sysdep.h> /* For stack growth direction. */
@@ -511,19 +512,17 @@
(natural_t *) &state, &statecount))
LOSE;
#ifdef STACK_GROWTH_UP
-#define THREADVAR_SPACE (__hurd_threadvar_max \
- * sizeof *__hurd_sightread_variables)
if (__hurd_sigthread_stack_base == 0)
{
state.SP &= __hurd_threadvar_stack_mask;
- state.SP += __hurd_threadvar_stack_offset + THREADVAR_SPACE;
+ state.SP += __hurd_threadvar_stack_offset;
}
else
state.SP = __hurd_sigthread_stack_base;
#else
if (__hurd_sigthread_stack_end == 0)
{
- /* The signal thread has a normal stack assigned by cthreads.
+ /* The signal thread has a stack assigned by cthreads.
The threadvar_stack variables conveniently tell us how
to get to the highest address in the stack, just below
the per-thread variables. */
--- a/sysdeps/mach/hurd/i386/init-first.c
+++ b/sysdeps/mach/hurd/i386/init-first.c
@@ -157,15 +157,6 @@
char **argv = (void *) (data + 1);
char **envp = &argv[argc + 1];
struct hurd_startup_data *d;
- unsigned long int threadvars[_HURD_THREADVAR_MAX];
-
- /* Provide temporary storage for thread-specific variables on the
- startup stack so the cthreads initialization code can use them
- for malloc et al, or so we can use malloc below for the real
- threadvars array. */
- memset (threadvars, 0, sizeof threadvars);
- threadvars[_HURD_THREADVAR_LOCALE] = (unsigned long int) &_nl_global_locale;
- __hurd_threadvar_stack_offset = (unsigned long int) threadvars;
/* Since the cthreads initialization code uses malloc, and the
malloc initialization code needs to get at the environment, make
@@ -211,13 +202,6 @@
__pthread_initialize_minimal();
#endif
- /* The user might have defined a value for this, to get more variables.
- Otherwise it will be zero on startup. We must make sure it is set
- properly before before cthreads initialization, so cthreads can know
- how much space to leave for thread variables. */
- if (__hurd_threadvar_max < _HURD_THREADVAR_MAX)
- __hurd_threadvar_max = _HURD_THREADVAR_MAX;
-
/* After possibly switching stacks, call `init1' (above) with the user
code as the return address, and the argument data immediately above
@@ -233,11 +217,6 @@
__libc_stack_end = newsp;
- /* Copy per-thread variables from that temporary
- area onto the new cthread stack. */
- memcpy (__hurd_threadvar_location_from_sp (0, newsp),
- threadvars, sizeof threadvars);
-
/* Copy the argdata from the old stack to the new one. */
newsp = memcpy (newsp - ((char *) &d[1] - (char *) data), data,
(char *) d - (char *) data);
@@ -278,25 +257,10 @@
}
else
{
- /* We are not using cthreads, so we will have just a single allocated
- area for the per-thread variables of the main user thread. */
- unsigned long int *array;
- unsigned int i;
int usercode;
void call_init1 (void);
- array = malloc (__hurd_threadvar_max * sizeof (unsigned long int));
- if (array == NULL)
- __libc_fatal ("Can't allocate single-threaded thread variables.");
-
- /* Copy per-thread variables from the temporary array into the
- newly malloc'd space. */
- memcpy (array, threadvars, sizeof threadvars);
- __hurd_threadvar_stack_offset = (unsigned long int) array;
- for (i = _HURD_THREADVAR_MAX; i < __hurd_threadvar_max; ++i)
- array[i] = 0;
-
/* The argument data is just above the stack frame we will unwind by
returning. Mutate our own return address to run the code below. */
/* The following expression would typically be written as
--- a/sysdeps/mach/hurd/i386/makecontext-helper.c
+++ b/sysdeps/mach/hurd/i386/makecontext-helper.c
@@ -22,6 +22,7 @@
#include <string.h>
#include <ucontext.h>
+#if 0
void
__makecontext_helper (ucontext_t *ucp)
@@ -67,3 +68,4 @@
ucp->uc_stack.ss_size -= t_size;
}
}
+#endif
--- a/sysdeps/mach/hurd/i386/makecontext.S
+++ b/sysdeps/mach/hurd/i386/makecontext.S
@@ -27,7 +27,7 @@
subl $4, %esp
cfi_adjust_cfa_offset (4)
movl %eax, (%esp)
- call HIDDEN_JUMPTARGET (__makecontext_helper)
+ /* call HIDDEN_JUMPTARGET (__makecontext_helper) */
addl $4, %esp
cfi_adjust_cfa_offset (-4)
--- a/sysdeps/mach/hurd/i386/sigreturn.c
+++ b/sysdeps/mach/hurd/i386/sigreturn.c
@@ -68,7 +68,7 @@
if (scp->sc_onstack)
{
- ss->sigaltstack.ss_flags &= ~SS_ONSTACK; /* XXX threadvars */
+ ss->sigaltstack.ss_flags &= ~SS_ONSTACK;
/* XXX cannot unlock until off sigstack */
abort ();
}
@@ -77,8 +77,7 @@
/* Destroy the MiG reply port used by the signal handler, and restore the
reply port in use by the thread when interrupted. */
- reply_port =
- (mach_port_t *) __hurd_threadvar_location (_HURD_THREADVAR_MIG_REPLY);
+ reply_port = &__hurd_local_reply_port;
if (*reply_port)
{
mach_port_t port = *reply_port;
--- a/sysdeps/mach/hurd/i386/tls.h
+++ b/sysdeps/mach/hurd/i386/tls.h
@@ -43,6 +43,10 @@
void *__private_tm[4];
/* GCC split stack support. */
void *__private_ss;
+
+ /* Keep this field last */
+ mach_port_t reply_port; /* This thread's reply port. */
+ struct hurd_sigstate *_hurd_sigstate;
} tcbhead_t;
#endif
@@ -78,6 +82,17 @@
| (((unsigned int) (tcb)) & 0xff000000) /* base 24..31 */ \
}
+# define HURD_DESC_TLS(desc) \
+ ({ \
+ (tcbhead_t *) ( (desc->low_word >> 16) \
+ | ((desc->high_word & 0xff) << 16) \
+ | (desc->high_word & 0xff000000) \
+ );})
+
+#define __LIBC_NO_TLS() \
+ ({ unsigned short ds, gs; \
+ asm ("movw %%ds,%w0; movw %%gs,%w1" : "=q" (ds), "=q" (gs)); \
+ ds == gs; })
static inline const char * __attribute__ ((unused))
_hurd_tls_init (tcbhead_t *tcb)
@@ -128,6 +143,20 @@
: "i" (offsetof (tcbhead_t, tcb))); \
__tcb;})
+/* Return the TCB address of a thread given its state. */
+# define THREAD_TCB(thread, thread_state) \
+ ({ int __sel = (thread_state)->basic.gs; \
+ struct descriptor __desc, *___desc = &__desc; \
+ unsigned int __count = 1; \
+ kern_return_t __err; \
+ if (__builtin_expect (__sel, 0x48) & 4) /* LDT selector */ \
+ __err = __i386_get_ldt ((thread), __sel, 1, &___desc, &__count); \
+ else \
+ __err = __i386_get_gdt ((thread), __sel, &__desc); \
+ assert_perror (__err); \
+ assert (__count == 1); \
+ HURD_DESC_TLS(___desc);})
+
/* Install new dtv for current thread. */
# define INSTALL_NEW_DTV(dtvp) \
({ asm volatile ("movl %0,%%gs:%P1" \
--- a/sysdeps/mach/hurd/mig-reply.c
+++ b/sysdeps/mach/hurd/mig-reply.c
@@ -18,26 +18,20 @@
#include <mach.h>
#include <hurd/threadvar.h>
-#define GETPORT \
- mach_port_t *portloc = \
- (mach_port_t *) __hurd_threadvar_location (_HURD_THREADVAR_MIG_REPLY)
-#define reply_port (*(use_threadvar ? portloc : &global_reply_port))
-
-static int use_threadvar;
-static mach_port_t global_reply_port;
-
/* These functions are called by MiG-generated code. */
+mach_port_t __hurd_reply_port0;
+
/* Called by MiG to get a reply port. */
mach_port_t
__mig_get_reply_port (void)
{
- GETPORT;
-
- if (reply_port == MACH_PORT_NULL)
- reply_port = __mach_reply_port ();
+ if (__hurd_local_reply_port == MACH_PORT_NULL ||
+ (&__hurd_local_reply_port != &__hurd_reply_port0
+ && __hurd_local_reply_port == __hurd_reply_port0))
+ __hurd_local_reply_port = __mach_reply_port ();
- return reply_port;
+ return __hurd_local_reply_port;
}
weak_alias (__mig_get_reply_port, mig_get_reply_port)
@@ -45,12 +39,8 @@
void
__mig_dealloc_reply_port (mach_port_t arg)
{
- mach_port_t port;
-
- GETPORT;
-
- port = reply_port;
- reply_port = MACH_PORT_NULL; /* So the mod_refs RPC won't use it. */
+ mach_port_t port = __hurd_local_reply_port;
+ __hurd_local_reply_port = MACH_PORT_NULL; /* So the mod_refs RPC won't use it. */
if (MACH_PORT_VALID (port))
__mach_port_mod_refs (__mach_task_self (), port,
@@ -73,15 +63,6 @@
void
__mig_init (void *stack)
{
- use_threadvar = stack != 0;
-
- if (use_threadvar)
- {
- /* Recycle the reply port used before multithreading was enabled. */
- mach_port_t *portloc = (mach_port_t *)
- __hurd_threadvar_location_from_sp (_HURD_THREADVAR_MIG_REPLY, stack);
- *portloc = global_reply_port;
- global_reply_port = MACH_PORT_NULL;
- }
+ /* Do nothing. */
}
weak_alias (__mig_init, mig_init)
--- a/sysdeps/mach/hurd/profil.c
+++ b/sysdeps/mach/hurd/profil.c
@@ -141,7 +141,7 @@
weak_alias (__profil, profil)
/* Fetch PC samples. This function must be very careful not to depend
- on Hurd threadvar variables. We arrange that by using a special
+ on Hurd TLS variables. We arrange that by using a special
stub arranged for at the end of this file. */
static void
fetch_samples (void)
@@ -177,7 +177,7 @@
}
-/* This function must be very careful not to depend on Hurd threadvar
+/* This function must be very careful not to depend on Hurd TLS
variables. We arrange that by using special stubs arranged for at the
end of this file. */
static void
@@ -268,7 +268,7 @@
are fatal in profile_waiter anyhow. */
#define __mig_put_reply_port(foo)
-/* Use our static variable instead of the usual threadvar mechanism for
+/* Use our static variable instead of the usual TLS mechanism for
this. */
#define __mig_get_reply_port() profil_reply_port
|