From a378ce7d5ac32e9f2633d2c798abaeda34b8b7f3 Mon Sep 17 00:00:00 2001 From: Joerg Sonnenberger Date: Fri, 29 Apr 2005 22:00:20 +0000 Subject: [PATCH] Prepare for thread-local errno by implementing full TLS support for static binaries, which does not touch errno before the initial TLS space is created. This code path is *very* sensitive to changes. --- lib/libc/gen/tls.c | 27 +++++++++++++++++++++++---- lib/libc/i386/SYS.h | 7 ++++++- lib/libc/i386/sys/Makefile.inc | 5 +++-- 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/lib/libc/gen/tls.c b/lib/libc/gen/tls.c index 43cd305206..4fa74b1230 100644 --- a/lib/libc/gen/tls.c +++ b/lib/libc/gen/tls.c @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/lib/libc/gen/tls.c,v 1.7 2005/03/01 23:42:00 davidxu Exp $ - * $DragonFly: src/lib/libc/gen/tls.c,v 1.7 2005/04/28 18:29:54 joerg Exp $ + * $DragonFly: src/lib/libc/gen/tls.c,v 1.8 2005/04/29 22:00:20 joerg Exp $ */ /* @@ -111,19 +111,32 @@ __libc_free_tls(struct tls_tcb *tcb) /* * Allocate Static TLS. + * + * !!!WARNING!!! The first run for a static binary is done without valid + * TLS storage. It must not call any system calls which want to change + * errno. */ struct tls_tcb * __libc_allocate_tls(struct tls_tcb *old_tcb) { + static int first_run = 0; size_t data_size; struct tls_tcb *tcb; Elf_Addr *dtv; +retry: data_size = (tls_static_space + RTLD_STATIC_TLS_ALIGN_MASK) & ~RTLD_STATIC_TLS_ALIGN_MASK; - tcb = malloc(data_size + sizeof(*tcb)); + + if (first_run) + tcb = malloc(data_size + sizeof(*tcb)); + else + tcb = alloca(data_size + sizeof(*tcb)); tcb = (struct tls_tcb *)((char *)tcb + data_size); - dtv = malloc(3 * sizeof(Elf_Addr)); + if (first_run) + dtv = malloc(3 * sizeof(Elf_Addr)); + else + dtv = alloca(3 * sizeof(Elf_Addr)); #ifdef RTLD_TCB_HAS_SELF_POINTER tcb->tcb_self = tcb; @@ -154,7 +167,13 @@ __libc_allocate_tls(struct tls_tcb *old_tcb) memset((char *)tcb - tls_static_space + tls_init_size, 0, tls_static_space - tls_init_size); } - return (tcb); + + if (first_run) + return (tcb); + + tls_set_tcb(tcb); + first_run = 1; + goto retry; } #else diff --git a/lib/libc/i386/SYS.h b/lib/libc/i386/SYS.h index 7d6111484b..d985678d2a 100644 --- a/lib/libc/i386/SYS.h +++ b/lib/libc/i386/SYS.h @@ -36,12 +36,17 @@ * from: @(#)SYS.h 5.5 (Berkeley) 5/7/91 * * $FreeBSD: src/lib/libc/i386/SYS.h,v 1.17.2.2 2002/10/15 19:46:46 fjoe Exp $ - * $DragonFly: src/lib/libc/i386/SYS.h,v 1.4 2005/01/31 22:29:20 dillon Exp $ + * $DragonFly: src/lib/libc/i386/SYS.h,v 1.5 2005/04/29 22:00:20 joerg Exp $ */ #include #include "DEFS.h" +#define PURESYSCALL(x) ENTRY(__CONCAT(_,x)); \ + .weak CNAME(x); \ + .set CNAME(x),CNAME(__CONCAT(_,x)); \ + lea __CONCAT(SYS_,x),%eax; KERNCALL; ret + #define SYSCALL(x) 2: PIC_PROLOGUE; jmp PIC_PLT(HIDENAME(cerror)); \ ENTRY(__CONCAT(_,x)); \ .weak CNAME(x); \ diff --git a/lib/libc/i386/sys/Makefile.inc b/lib/libc/i386/sys/Makefile.inc index c8dd113334..04305f4fa2 100644 --- a/lib/libc/i386/sys/Makefile.inc +++ b/lib/libc/i386/sys/Makefile.inc @@ -1,18 +1,19 @@ # from: Makefile.inc,v 1.1 1993/09/03 19:04:23 jtc Exp # $FreeBSD: src/lib/libc/i386/sys/Makefile.inc,v 1.17.2.3 2002/10/15 19:46:46 fjoe Exp $ -# $DragonFly: src/lib/libc/i386/sys/Makefile.inc,v 1.2 2003/06/17 04:26:43 dillon Exp $ +# $DragonFly: src/lib/libc/i386/sys/Makefile.inc,v 1.3 2005/04/29 22:00:20 joerg Exp $ SRCS+= i386_clr_watch.c i386_get_ioperm.c i386_get_ldt.c i386_set_ioperm.c \ i386_set_ldt.c i386_set_watch.c i386_vm86.c MDASM= Ovfork.S brk.S cerror.S exect.S fork.S pipe.S ptrace.S reboot.S \ - rfork.S sbrk.S setlogin.S sigreturn.S syscall.S + rfork.S sbrk.S setlogin.S sigreturn.S syscall.S sys_set_tls_area.S # Don't generate default code for these syscalls: NOASM= __semctl.o break.o exit.o ftruncate.o getdomainname.o getlogin.o \ lseek.o mlockall.o mmap.o msgctl.o msgget.o msgrcv.o msgsnd.o \ munlockall.o openbsd_poll.o pread.o pwrite.o semconfig.o semget.o \ semop.o setdomainname.o shmat.o shmctl.o shmdt.o shmget.o sstk.o \ + sys_set_tls_area.o \ thr_sleep.o thr_wakeup.o truncate.o uname.o vfork.o yield.o PSEUDO= _getlogin.o -- 2.41.0