diff --git a/arch/i386/syscall_arch.h b/arch/i386/syscall_arch.h index 4c9d874a..8fe35424 100644 --- a/arch/i386/syscall_arch.h +++ b/arch/i386/syscall_arch.h @@ -3,52 +3,63 @@ ((union { long long ll; long l[2]; }){ .ll = x }).l[1] #define __SYSCALL_LL_O(x) __SYSCALL_LL_E((x)) +#if SYSCALL_NO_TLS +#define SYSCALL_INSNS "int $128" +#else +#define SYSCALL_INSNS "call *%%gs:16" +#endif + +#define SYSCALL_INSNS_12 "xchg %%ebx,%%edx ; " SYSCALL_INSNS " ; xchg %%ebx,%%edx" +#define SYSCALL_INSNS_34 "xchg %%ebx,%%edi ; " SYSCALL_INSNS " ; xchg %%ebx,%%edi" + static inline long __syscall0(long n) { unsigned long __ret; - __asm__ __volatile__ (".hidden __vsyscall ; call __vsyscall" : "=a"(__ret) : "a"(n) : "memory"); + __asm__ __volatile__ (SYSCALL_INSNS : "=a"(__ret) : "a"(n) : "memory"); return __ret; } static inline long __syscall1(long n, long a1) { unsigned long __ret; - __asm__ __volatile__ (".hidden __vsyscall ; call __vsyscall" : "=a"(__ret) : "a"(n), "d"(a1) : "memory"); + __asm__ __volatile__ (SYSCALL_INSNS_12 : "=a"(__ret) : "a"(n), "d"(a1) : "memory"); return __ret; } static inline long __syscall2(long n, long a1, long a2) { unsigned long __ret; - __asm__ __volatile__ (".hidden __vsyscall ; call __vsyscall" : "=a"(__ret) : "a"(n), "d"(a1), "c"(a2) : "memory"); + __asm__ __volatile__ (SYSCALL_INSNS_12 : "=a"(__ret) : "a"(n), "d"(a1), "c"(a2) : "memory"); return __ret; } static inline long __syscall3(long n, long a1, long a2, long a3) { unsigned long __ret; - __asm__ __volatile__ (".hidden __vsyscall ; call __vsyscall" : "=a"(__ret) : "a"(n), "d"(a1), "c"(a2), "D"(a3) : "memory"); + __asm__ __volatile__ (SYSCALL_INSNS_34 : "=a"(__ret) : "a"(n), "D"(a1), "c"(a2), "d"(a3) : "memory"); return __ret; } static inline long __syscall4(long n, long a1, long a2, long a3, long a4) { unsigned long __ret; - __asm__ __volatile__ (".hidden __vsyscall ; call __vsyscall" : "=a"(__ret) : "a"(n), "d"(a1), "c"(a2), "D"(a3), "S"(a4) : "memory"); + __asm__ __volatile__ (SYSCALL_INSNS_34 : "=a"(__ret) : "a"(n), "D"(a1), "c"(a2), "d"(a3), "S"(a4) : "memory"); return __ret; } static inline long __syscall5(long n, long a1, long a2, long a3, long a4, long a5) { - unsigned long __ret; - __asm__ __volatile__ ("push %6 ; .hidden __vsyscall ; call __vsyscall ; add $4,%%esp" : "=a"(__ret) : "a"(n), "d"(a1), "c"(a2), "D"(a3), "S"(a4), "g"(a5) : "memory"); + unsigned long __ret, __tmp; + __asm__ __volatile__ ("mov %%ebx,%1 ; mov %3,%%ebx ; " SYSCALL_INSNS " ; mov %1,%%ebx" + : "=a"(__ret), "=m"(__tmp) : "a"(n), "g"(a1), "c"(a2), "d"(a3), "S"(a4), "D"(a5) : "memory"); return __ret; } static inline long __syscall6(long n, long a1, long a2, long a3, long a4, long a5, long a6) { - unsigned long __ret; - __asm__ __volatile__ ("push %6 ; .hidden __vsyscall6 ; call __vsyscall6 ; add $4,%%esp" : "=a"(__ret) : "a"(n), "d"(a1), "c"(a2), "D"(a3), "S"(a4), "g"(0+(long[]){a5, a6}) : "memory"); + unsigned long __ret, __tmp1, __tmp2; + __asm__ __volatile__ ("mov %%ebx,%1 ; mov %%ebp,%2 ; mov %4,%%ebx ; mov %9,%%ebp ; " SYSCALL_INSNS " ; mov %2,%%ebp ; mov %1,%%ebx" + : "=a"(__ret), "=m"(__tmp1), "=m"(__tmp2) : "a"(n), "g"(a1), "c"(a2), "d"(a3), "S"(a4), "D"(a5), "g"(a6) : "memory"); return __ret; } diff --git a/ldso/dynlink.c b/ldso/dynlink.c index 7cb66db9..42a5470d 100644 --- a/ldso/dynlink.c +++ b/ldso/dynlink.c @@ -1,4 +1,5 @@ #define _GNU_SOURCE +#define SYSCALL_NO_TLS 1 #include #include #include @@ -1685,6 +1686,8 @@ _Noreturn void __dls3(size_t *sp) libc.auxv = auxv = (void *)(argv+i+1); decode_vec(auxv, aux, AUX_CNT); __hwcap = aux[AT_HWCAP]; + search_vec(auxv, &__sysinfo, AT_SYSINFO); + __pthread_self()->sysinfo = __sysinfo; libc.page_size = aux[AT_PAGESZ]; libc.secure = ((aux[0]&0x7800)!=0x7800 || aux[AT_UID]!=aux[AT_EUID] || aux[AT_GID]!=aux[AT_EGID] || aux[AT_SECURE]); diff --git a/src/env/__init_tls.c b/src/env/__init_tls.c index f1874f2a..5f12500c 100644 --- a/src/env/__init_tls.c +++ b/src/env/__init_tls.c @@ -1,3 +1,4 @@ +#define SYSCALL_NO_TLS 1 #include #include #include @@ -21,6 +22,7 @@ int __init_tp(void *p) td->tid = __syscall(SYS_set_tid_address, &__thread_list_lock); td->locale = &libc.global_locale; td->robust_list.head = &td->robust_list.head; + td->sysinfo = __sysinfo; td->next = td->prev = td; return 0; } diff --git a/src/env/__libc_start_main.c b/src/env/__libc_start_main.c index 7c95f822..8fbe5262 100644 --- a/src/env/__libc_start_main.c +++ b/src/env/__libc_start_main.c @@ -28,7 +28,7 @@ void __init_libc(char **envp, char *pn) libc.auxv = auxv = (void *)(envp+i+1); for (i=0; auxv[i]; i+=2) if (auxv[i]robust_list.head = &new->robust_list.head; new->CANARY = self->CANARY; + new->sysinfo = self->sysinfo; /* Setup argument structure for the new thread on its stack. * It's safe to access from the caller only until the thread