This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.
Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
Hi Ulrich, the following patch adds TLS support for s390 31-bit and 64-bit. I had trouble with a test-case though. tst-tls9-static fails for 31 bit but succeeds for 64 bit. I debugged this (didn't want to sent the patch with this odd behaviour) and found out that the test case should fail for 64 bit as well ! tst-tls9-static does a dlopen on tst-tlsmod5.so which has a DT_NEEDED for libc.so.6. For s390 the size of the TLS segment of libc.so is 0x224 bytes. The surplus in the static TLS area isn't big enough to dynamically load libc.so. It is initially set to 0x280 but the TCB alone has 0x200 bytes. Therefore it fails for 31 bit. The odd thing is that it succeeds on 64 bit. TLS segment size of the 64 bit libc.so is 0x280, surplus is 0x2c0 bytes and the TCB has 0x340 bytes. After some debugging it turned out that the bug is in allocate_static_tls: static bool allocate_static_tls (struct link_map *map) { size_t offset = roundup (GL(dl_tls_static_used), map->l_tls_align); if (offset + map->l_tls_blocksize > (GL(dl_tls_static_size) # if TLS_TCB_AT_TP - TLS_TCB_SIZE # elif TLS_DTV_AT_TP /* dl_tls_static_used includes the TCB at the beginning. */ # else # error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined" # endif )) return false; map->l_tls_offset = offset; GL(dl_tls_static_used) = offset + map->l_tls_blocksize; return true; } GL(dl_tls_static_size) has 0x2c0 bytes and TLS_TCB_SIZE has 0x340 bytes. The subtraction overflows and the result is something huge (all numbers are unsigned). The TLS_TCB_SIZE should be added to the left side of the comparison. This would make the tst-tls9-static test fail for 64 bit as well which would be at least consistent with 31 bit. That leaves the TLS ABI for s390 and the nptl patch. The ABI is done from my point of view, the nptl patch will take some more time. Several testcases still fail, the worst bug is a race condition in tst-fork1 I haven't found yet. What shall I do with the ABI and the nptl patch (after I found all the remaining bugs)? Send them to the list or to you directly? blue skies, Martin. libc/ChangeLog: 2003-01-27 Martin Schwidefsky <schwidefsky@de.ibm.com> * elf/elf.h: Add new s390 relocs. * elf/tls-macros.h: Add s390 versions. * sysdeps/s390/Versions [GLIBC_2.3] (ld): Export __tls_get_offset. * sysdeps/s390/dl-tls.h: New file. * sysdeps/s390/libc-tls.c: New file. * sysdeps/s390/s390-32/dl-machine.h (elf_machine_type_class): Add TLS relocs for class PLT. (elf_machine_rela): Handle TLS relocs. * sysdeps/s390/s390-64/dl-machine.h: Likewise. * sysdeps/s390/s390-32/elf/configure.in: Add TLS check. * sysdeps/s390/s390-64/elf/configure.in: Likewise. * sysdeps/s390/s390-32/elf/configure: Regenerate. * sysdeps/s390/s390-64/elf/configure: Likewise. * sysdeps/unix/sysv/linux/s390/s390-32/clone.S: Add support for CLONE_CHILD_*TID flags. * sysdeps/unix/sysv/linux/s390/s390-64/clone.S: Likewise. * sysdeps/unix/sysv/linux/s390/s390-64/mmap.S: Use branch with 32 bit offset. * sysdeps/unix/sysv/linux/s390/s390-64/socket.S: Likewise. * sysdeps/unix/sysv/linux/s390/s390-64/syscall.S: Likewise. * sysdeps/unix/sysv/linux/s390/s390-32/sysdep.S (__syscall_error): Support USE___THREAD. Define RTLD_PRIVATE_ERRNO variant. * sysdeps/unix/sysv/linux/s390/s390-64/sysdep.S (__syscall_error): Likewise. * sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h: (SYSCALL_ERROR_LABEL): Move define next to SYSCALL_ERROR_HANDLER. (SYSCALL_ERROR_HANDLER): Add USE___THREAD and RTLD_PRIVATE_ERRNO variants. * sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h: (SYSCALL_ERROR_LABEL): Move define next to SYSCALL_ERROR_HANDLER. Use direct branch to syscall_error for !PIC and PIC && !_LIBC_REENTRANT. (SYSCALL_ERROR_HANDLER): Add USE___THREAD and RTLD_PRIVATE_ERRNO variants. linuxthreads/ChangeLog: 2003-01-27 Martin Schwidefsky <schwidefsky@de.ibm.com> * sysdeps/s390/s390-32/pt-machine.h (THREAD_SELF, INIT_THREAD_SELF): Define TLS versions. * sysdeps/s390/s390-64/pt-machine.h (THREAD_SELF, INIT_THREAD_SELF): Likewise. * sysdeps/s390/tls.h [HAVE_TLS_SUPPORT] (USE_TLS, TLS_INIT_TCB_SIZE, TLS_INIT_TCB_ALIGN, TLS_TCB_SIZE, TLS_TCB_ALIGN, TLS_TCB_AT_TP, INSTALL_DTV, INSTALL_NEW_DTV, GET_DTV, TLS_INIT_TP, THREAD_DTV): Define. * sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h (PSEUDO): Use branch with 32 bit offset. * sysdeps/unix/sysv/linux/s390/s390-64/vfork.S: Likewise. diff -urN libc/elf/elf.h libc-s390/elf/elf.h --- libc/elf/elf.h Wed Dec 18 04:43:38 2002 +++ libc-s390/elf/elf.h Sat Jan 25 18:15:17 2003 @@ -2228,36 +2228,83 @@ /* Additional s390 relocs */ -#define R_390_NONE 0 /* No reloc. */ -#define R_390_8 1 /* Direct 8 bit. */ -#define R_390_12 2 /* Direct 12 bit. */ -#define R_390_16 3 /* Direct 16 bit. */ -#define R_390_32 4 /* Direct 32 bit. */ -#define R_390_PC32 5 /* PC relative 32 bit. */ -#define R_390_GOT12 6 /* 12 bit GOT offset. */ -#define R_390_GOT32 7 /* 32 bit GOT offset. */ -#define R_390_PLT32 8 /* 32 bit PC relative PLT address. */ -#define R_390_COPY 9 /* Copy symbol at runtime. */ -#define R_390_GLOB_DAT 10 /* Create GOT entry. */ -#define R_390_JMP_SLOT 11 /* Create PLT entry. */ -#define R_390_RELATIVE 12 /* Adjust by program base. */ -#define R_390_GOTOFF 13 /* 32 bit offset to GOT. */ -#define R_390_GOTPC 14 /* 32 bit PC relative offset to GOT. */ -#define R_390_GOT16 15 /* 16 bit GOT offset. */ -#define R_390_PC16 16 /* PC relative 16 bit. */ -#define R_390_PC16DBL 17 /* PC relative 16 bit shifted by 1. */ -#define R_390_PLT16DBL 18 /* 16 bit PC rel. PLT shifted by 1. */ -#define R_390_PC32DBL 19 /* PC relative 32 bit shifted by 1. */ -#define R_390_PLT32DBL 20 /* 32 bit PC rel. PLT shifted by 1. */ -#define R_390_GOTPCDBL 21 /* 32 bit PC rel. GOT shifted by 1. */ -#define R_390_64 22 /* Direct 64 bit. */ -#define R_390_PC64 23 /* PC relative 64 bit. */ -#define R_390_GOT64 24 /* 64 bit GOT offset. */ -#define R_390_PLT64 25 /* 64 bit PC relative PLT address. */ -#define R_390_GOTENT 26 /* 32 bit PC rel. to GOT entry >> 1. */ +#define R_390_NONE 0 /* No reloc. */ +#define R_390_8 1 /* Direct 8 bit. */ +#define R_390_12 2 /* Direct 12 bit. */ +#define R_390_16 3 /* Direct 16 bit. */ +#define R_390_32 4 /* Direct 32 bit. */ +#define R_390_PC32 5 /* PC relative 32 bit. */ +#define R_390_GOT12 6 /* 12 bit GOT offset. */ +#define R_390_GOT32 7 /* 32 bit GOT offset. */ +#define R_390_PLT32 8 /* 32 bit PC relative PLT address. */ +#define R_390_COPY 9 /* Copy symbol at runtime. */ +#define R_390_GLOB_DAT 10 /* Create GOT entry. */ +#define R_390_JMP_SLOT 11 /* Create PLT entry. */ +#define R_390_RELATIVE 12 /* Adjust by program base. */ +#define R_390_GOTOFF32 13 /* 32 bit offset to GOT. */ +#define R_390_GOTPC 14 /* 32 bit PC relative offset to GOT. */ +#define R_390_GOT16 15 /* 16 bit GOT offset. */ +#define R_390_PC16 16 /* PC relative 16 bit. */ +#define R_390_PC16DBL 17 /* PC relative 16 bit shifted by 1. */ +#define R_390_PLT16DBL 18 /* 16 bit PC rel. PLT shifted by 1. */ +#define R_390_PC32DBL 19 /* PC relative 32 bit shifted by 1. */ +#define R_390_PLT32DBL 20 /* 32 bit PC rel. PLT shifted by 1. */ +#define R_390_GOTPCDBL 21 /* 32 bit PC rel. GOT shifted by 1. */ +#define R_390_64 22 /* Direct 64 bit. */ +#define R_390_PC64 23 /* PC relative 64 bit. */ +#define R_390_GOT64 24 /* 64 bit GOT offset. */ +#define R_390_PLT64 25 /* 64 bit PC relative PLT address. */ +#define R_390_GOTENT 26 /* 32 bit PC rel. to GOT entry >> 1. */ +#define R_390_GOTOFF16 27 /* 16 bit offset to GOT. */ +#define R_390_GOTOFF64 28 /* 64 bit offset to GOT. */ +#define R_390_GOTPLT12 29 /* 12 bit offset to jump slot. */ +#define R_390_GOTPLT16 30 /* 16 bit offset to jump slot. */ +#define R_390_GOTPLT32 31 /* 32 bit offset to jump slot. */ +#define R_390_GOTPLT64 32 /* 64 bit offset to jump slot. */ +#define R_390_GOTPLTENT 33 /* 32 bit rel. offset to jump slot. */ +#define R_390_PLTOFF16 34 /* 16 bit offset from GOT to PLT. */ +#define R_390_PLTOFF32 35 /* 32 bit offset from GOT to PLT. */ +#define R_390_PLTOFF64 36 /* 16 bit offset from GOT to PLT. */ +#define R_390_TLS_LOAD 37 /* Tag for load insn in TLS code. */ +#define R_390_TLS_GDCALL 38 /* Tag for function call in general + dynamic TLS code. */ +#define R_390_TLS_LDCALL 39 /* Tag for function call in local + dynamic TLS code. */ +#define R_390_TLS_GD32 40 /* Direct 32 bit for general dynamic + thread local data. */ +#define R_390_TLS_GD64 41 /* Direct 64 bit for general dynamic + thread local data. */ +#define R_390_TLS_GOTIE12 42 /* 12 bit GOT offset for static TLS + block offset. */ +#define R_390_TLS_GOTIE32 43 /* 32 bit GOT offset for static TLS + block offset. */ +#define R_390_TLS_GOTIE64 44 /* 64 bit GOT offset for static TLS + block offset. */ +#define R_390_TLS_LDM32 45 /* Direct 32 bit for local dynamic + thread local data in LE code. */ +#define R_390_TLS_LDM64 46 /* Direct 64 bit for local dynamic + thread local data in LE code. */ +#define R_390_TLS_IE32 47 /* 32 bit address of GOT entry for + negated static TLS block offset. */ +#define R_390_TLS_IE64 48 /* 64 bit address of GOT entry for + negated static TLS block offset. */ +#define R_390_TLS_IEENT 49 /* 32 bit rel. offset to GOT entry for + negated static TLS block offset. */ +#define R_390_TLS_LE32 50 /* 32 bit negated offset relative to + static TLS block. */ +#define R_390_TLS_LE64 51 /* 64 bit negated offset relative to + static TLS block. */ +#define R_390_TLS_LDO32 52 /* 32 bit offset relative to TLS + block. */ +#define R_390_TLS_LDO64 53 /* 64 bit offset relative to TLS + block. */ +#define R_390_TLS_DTPMOD 54 /* ID of module containing symbol. */ +#define R_390_TLS_DTPOFF 55 /* Offset in TLS block. */ +#define R_390_TLS_TPOFF 56 /* Negated offset in static TLS + block. */ /* Keep this the last entry. */ -#define R_390_NUM 27 +#define R_390_NUM 57 /* CRIS relocations. */ #define R_CRIS_NONE 0 diff -urN libc/elf/tls-macros.h libc-s390/elf/tls-macros.h --- libc/elf/tls-macros.h Mon Jan 13 10:33:08 2003 +++ libc-s390/elf/tls-macros.h Sat Jan 25 18:15:17 2003 @@ -298,6 +298,196 @@ : "=r" (__l) : : "loc0", __TLS_CALL_CLOBBERS); \ __l; }) +#elif defined __s390x__ + +# define TLS_LE(x) \ + ({ unsigned long __offset; \ + asm ("bras %0,1f\n" \ + "0:\t.quad " #x "@ntpoff\n" \ + "1:\tlg %0,0(%0)" \ + : "=a" (__offset) : : "cc" ); \ + (int *) (__builtin_thread_pointer() + __offset); }) + +# ifdef PIC +# define TLS_IE(x) \ + ({ unsigned long __offset; \ + asm ("bras %0,1f\n" \ + "0:\t.quad " #x "@gotntpoff\n" \ + "1:\tlg %0,0(%0)\n\t" \ + "lg %0,0(%0,%%r12):tls_load:" #x \ + : "=&a" (__offset) : : "cc" ); \ + (int *) (__builtin_thread_pointer() + __offset); }) +# else +# define TLS_IE(x) \ + ({ unsigned long __offset; \ + asm ("bras %0,1f\n" \ + "0:\t.quad " #x "@indntpoff\n" \ + "1:\t lg %0,0(%0)\n\t" \ + "lg %0,0(%0):tls_load:" #x \ + : "=&a" (__offset) : : "cc" ); \ + (int *) (__builtin_thread_pointer() + __offset); }) +# endif + +# ifdef PIC +# define TLS_LD(x) \ + ({ unsigned long __offset, __save12; \ + asm ("bras %0,1f\n" \ + "0:\t.quad " #x "@tlsldm\n\t" \ + ".quad " #x "@dtpoff\n" \ + "1:\tlgr %1,%%r12\n\t" \ + "larl %%r12,_GLOBAL_OFFSET_TABLE_\n\t" \ + "lg %%r2,0(%0)\n\t" \ + "brasl %%r14,__tls_get_offset@plt:tls_ldcall:" #x "\n\t" \ + "lg %0,8(%0)\n\t" \ + "algr %0,%%r2\n\t" \ + "lgr %%r12,%1" \ + : "=&a" (__offset), "=&a" (__save12) \ + : : "cc", "0", "1", "2", "3", "4", "5" ); \ + (int *) (__builtin_thread_pointer() + __offset); }) +# else +# define TLS_LD(x) \ + ({ unsigned long __offset; \ + asm ("bras %0,1f\n" \ + "0:\t.quad " #x "@tlsldm\n\t" \ + ".quad " #x "@dtpoff\n" \ + "1:\tlarl %%r12,_GLOBAL_OFFSET_TABLE_\n\t" \ + "lg %%r2,0(%0)\n\t" \ + "brasl %%r14,__tls_get_offset@plt:tls_ldcall:" #x "\n\t" \ + "lg %0,8(%0)\n\t" \ + "algr %0,%%r2" \ + : "=&a" (__offset) : : "cc", "0", "1", "2", "3", "4", "5", "12" ); \ + (int *) (__builtin_thread_pointer() + __offset); }) +# endif + +# ifdef PIC +# define TLS_GD(x) \ + ({ unsigned long __offset, __save12; \ + asm ("bras %0,1f\n" \ + "0:\t.quad " #x "@tlsgd\n" \ + "1:\tlgr %1,%%r12\n\t" \ + "larl %%r12,_GLOBAL_OFFSET_TABLE_\n\t" \ + "lg %%r2,0(%0)\n\t" \ + "brasl %%r14,__tls_get_offset@plt:tls_gdcall:" #x "\n\t" \ + "lgr %0,%%r2\n\t" \ + "lgr %%r12,%1" \ + : "=&a" (__offset), "=&a" (__save12) \ + : : "cc", "0", "1", "2", "3", "4", "5" ); \ + (int *) (__builtin_thread_pointer() + __offset); }) +# else +# define TLS_GD(x) \ + ({ unsigned long __offset; \ + asm ("bras %0,1f\n" \ + "0:\t.quad " #x "@tlsgd\n" \ + "1:\tlarl %%r12,_GLOBAL_OFFSET_TABLE_\n\t" \ + "lg %%r2,0(%0)\n\t" \ + "brasl %%r14,__tls_get_offset@plt:tls_gdcall:" #x "\n\t" \ + "lgr %0,%%r2" \ + : "=&a" (__offset) : : "cc", "0", "1", "2", "3", "4", "5", "12" ); \ + (int *) (__builtin_thread_pointer() + __offset); }) +# endif + +#elif defined __s390__ + +# define TLS_LE(x) \ + ({ unsigned long __offset; \ + asm ("bras %0,1f\n" \ + "0:\t.long " #x "@ntpoff\n" \ + "1:\tl %0,0(%0)" \ + : "=a" (__offset) : : "cc" ); \ + (int *) (__builtin_thread_pointer() + __offset); }) + +# ifdef PIC +# define TLS_IE(x) \ + ({ unsigned long __offset; \ + asm ("bras %0,1f\n" \ + "0:\t.long " #x "@gotntpoff\n" \ + "1:\tl %0,0(%0)\n\t" \ + "l %0,0(%0,%%r12):tls_load:" #x \ + : "=&a" (__offset) : : "cc" ); \ + (int *) (__builtin_thread_pointer() + __offset); }) +# else +# define TLS_IE(x) \ + ({ unsigned long __offset; \ + asm ("bras %0,1f\n" \ + "0:\t.long " #x "@indntpoff\n" \ + "1:\t l %0,0(%0)\n\t" \ + "l %0,0(%0):tls_load:" #x \ + : "=&a" (__offset) : : "cc" ); \ + (int *) (__builtin_thread_pointer() + __offset); }) +# endif + +# ifdef PIC +# define TLS_LD(x) \ + ({ unsigned long __offset, __save12; \ + asm ("bras %0,1f\n" \ + "0:\t.long _GLOBAL_OFFSET_TABLE_-0b\n\t" \ + ".long __tls_get_offset@plt-0b\n\t" \ + ".long " #x "@tlsldm\n\t" \ + ".long " #x "@dtpoff\n" \ + "1:\tlr %1,%%r12\n\t" \ + "l %%r12,0(%0)\n\t" \ + "la %%r12,0(%%r12,%0)\n\t" \ + "l %%r1,4(%0)\n\t" \ + "l %%r2,8(%0)\n\t" \ + "bas %%r14,0(%%r1,%0):tls_ldcall:" #x "\n\t" \ + "l %0,12(%0)\n\t" \ + "alr %0,%%r2\n\t" \ + "lr %%r12,%1" \ + : "=&a" (__offset), "=&a" (__save12) \ + : : "cc", "0", "1", "2", "3", "4", "5" ); \ + (int *) (__builtin_thread_pointer() + __offset); }) +# else +# define TLS_LD(x) \ + ({ unsigned long __offset; \ + asm ("bras %0,1f\n" \ + "0:\t.long _GLOBAL_OFFSET_TABLE_\n\t" \ + ".long __tls_get_offset@plt\n\t" \ + ".long " #x "@tlsldm\n\t" \ + ".long " #x "@dtpoff\n" \ + "1:\tl %%r12,0(%0)\n\t" \ + "l %%r1,4(%0)\n\t" \ + "l %%r2,8(%0)\n\t" \ + "bas %%r14,0(%%r1):tls_ldcall:" #x "\n\t" \ + "l %0,12(%0)\n\t" \ + "alr %0,%%r2" \ + : "=&a" (__offset) : : "cc", "0", "1", "2", "3", "4", "5", "12" ); \ + (int *) (__builtin_thread_pointer() + __offset); }) +# endif + +# ifdef PIC +# define TLS_GD(x) \ + ({ unsigned long __offset, __save12; \ + asm ("bras %0,1f\n" \ + "0:\t.long _GLOBAL_OFFSET_TABLE_-0b\n\t" \ + ".long __tls_get_offset@plt-0b\n\t" \ + ".long " #x "@tlsgd\n" \ + "1:\tlr %1,%%r12\n\t" \ + "l %%r12,0(%0)\n\t" \ + "la %%r12,0(%%r12,%0)\n\t" \ + "l %%r1,4(%0)\n\t" \ + "l %%r2,8(%0)\n\t" \ + "bas %%r14,0(%%r1,%0):tls_gdcall:" #x "\n\t" \ + "lr %0,%%r2\n\t" \ + "lr %%r12,%1" \ + : "=&a" (__offset), "=&a" (__save12) \ + : : "cc", "0", "1", "2", "3", "4", "5" ); \ + (int *) (__builtin_thread_pointer() + __offset); }) +# else +# define TLS_GD(x) \ + ({ unsigned long __offset; \ + asm ("bras %0,1f\n" \ + "0:\t.long _GLOBAL_OFFSET_TABLE_\n\t" \ + ".long __tls_get_offset@plt\n\t" \ + ".long " #x "@tlsgd\n" \ + "1:\tl %%r12,0(%0)\n\t" \ + "l %%r1,4(%0)\n\t" \ + "l %%r2,8(%0)\n\t" \ + "bas %%r14,0(%%r1):tls_gdcall:" #x "\n\t" \ + "lr %0,%%r2" \ + : "=&a" (__offset) : : "cc", "0", "1", "2", "3", "4", "5", "12" ); \ + (int *) (__builtin_thread_pointer() + __offset); }) +# endif + #else # error "No support for this architecture so far." #endif diff -urN libc/linuxthreads/sysdeps/s390/s390-32/pt-machine.h libc-s390/linuxthreads/sysdeps/s390/s390-32/pt-machine.h --- libc/linuxthreads/sysdeps/s390/s390-32/pt-machine.h Tue Aug 27 00:39:54 2002 +++ libc-s390/linuxthreads/sysdeps/s390/s390-32/pt-machine.h Sat Jan 25 18:15:17 2003 @@ -58,6 +58,13 @@ #define CURRENT_STACK_FRAME stack_pointer register char * stack_pointer __asm__ ("15"); +#ifdef USE_TLS +/* Return the thread descriptor for the current thread. */ +# define THREAD_SELF ((pthread_descr) __builtin_thread_pointer ()) + +/* Initialize the thread-unique value. */ +#define INIT_THREAD_SELF(descr, nr) __builtin_set_thread_pointer (descr) +#else /* Return the thread descriptor for the current thread. S/390 registers uses access register 0 as "thread register". */ #define THREAD_SELF ({ \ @@ -70,6 +77,7 @@ #define INIT_THREAD_SELF(descr, nr) ({ \ __asm__ ("sar %%a0,%0" : : "d" (descr) ); \ }) +#endif /* Access to data in the thread descriptor is easy. */ #define THREAD_GETMEM(descr, member) THREAD_SELF->member diff -urN libc/linuxthreads/sysdeps/s390/s390-64/pt-machine.h libc-s390/linuxthreads/sysdeps/s390/s390-64/pt-machine.h --- libc/linuxthreads/sysdeps/s390/s390-64/pt-machine.h Tue Aug 27 00:39:43 2002 +++ libc-s390/linuxthreads/sysdeps/s390/s390-64/pt-machine.h Sat Jan 25 18:15:17 2003 @@ -58,6 +58,13 @@ #define CURRENT_STACK_FRAME stack_pointer register char * stack_pointer __asm__ ("15"); +#ifdef USE_TLS +/* Return the thread descriptor for the current thread. */ +# define THREAD_SELF ((pthread_descr) __builtin_thread_pointer ()) + +/* Initialize the thread-unique value. */ +#define INIT_THREAD_SELF(descr, nr) __builtin_set_thread_pointer (descr) +#else /* Return the thread descriptor for the current thread. 64 bit S/390 uses access register 0 and 1 as "thread register". */ #define THREAD_SELF ({ \ @@ -76,6 +83,7 @@ " sar %%a0,0\n" \ : : "d" (descr) : "0" ); \ }) +#endif /* Access to data in the thread descriptor is easy. */ #define THREAD_GETMEM(descr, member) THREAD_SELF->member diff -urN libc/linuxthreads/sysdeps/s390/tls.h libc-s390/linuxthreads/sysdeps/s390/tls.h --- libc/linuxthreads/sysdeps/s390/tls.h Sun Jan 5 06:10:50 2003 +++ libc-s390/linuxthreads/sysdeps/s390/tls.h Sat Jan 25 18:15:17 2003 @@ -45,19 +45,99 @@ # include <tcb-offsets.h> #endif /* __ASSEMBLER__ */ -#undef USE_TLS +/* We can support TLS only if the floating-stack support is available. + However, we want to compile in the support and test at runtime whether + the running kernel can support it or not. To avoid bothering with the + TLS support code at all, use configure --without-tls. -#if USE_TLS + We need USE_TLS to be consistently defined, for ldsodefs.h conditionals. + But some of the code below can cause problems in building libpthread + (e.g. useldt.h will defined FLOATING_STACKS when it shouldn't). */ -#else +#if defined HAVE_TLS_SUPPORT \ + && (defined FLOATING_STACKS || !defined IS_IN_libpthread) -#define NONTLS_INIT_TP \ +/* Signal that TLS support is available. */ +# define USE_TLS 1 + +# ifndef __ASSEMBLER__ +/* Get system call information. */ +# include <sysdep.h> + + +/* Get the thread descriptor definition. */ +# include <linuxthreads/descr.h> + +/* This is the size of the initial TCB. */ +# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t) + +/* Alignment requirements for the initial TCB. */ +# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t) + +/* This is the size of the TCB. */ +# define TLS_TCB_SIZE sizeof (struct _pthread_descr_struct) + +/* Alignment requirements for the TCB. */ +# define TLS_TCB_ALIGN __alignof__ (struct _pthread_descr_struct) + +/* The TCB can have any size and the memory following the address the + thread pointer points to is unspecified. Allocate the TCB there. */ +# define TLS_TCB_AT_TP 1 + + +/* Install the dtv pointer. The pointer passed is to the element with + index -1 which contain the length. */ +# define INSTALL_DTV(descr, dtvp) \ + ((tcbhead_t *) (descr))->dtv = (dtvp) + 1 + +/* Install new dtv for current thread. */ +# define INSTALL_NEW_DTV(dtv) \ + (((tcbhead_t *) __builtin_thread_pointer ())->dtv = (dtv)) + +/* Return dtv of given thread descriptor. */ +# define GET_DTV(descr) \ + (((tcbhead_t *) (descr))->dtv) + +/* Code to initially initialize the thread pointer. This might need + special attention since 'errno' is not yet available and if the + operation can cause a failure 'errno' must not be touched. + + The value of this macro is null if successful, or an error string. */ +# define TLS_INIT_TP(descr, secondcall) \ + ({ \ + void *_descr = (descr); \ + tcbhead_t *head = _descr; \ + \ + head->tcb = _descr; \ + /* For now the thread descriptor is at the same address. */ \ + head->self = _descr; \ + \ + __builtin_set_thread_pointer (_descr); \ + 0; \ + }) + +/* Return the address of the dtv for the current thread. */ +# define THREAD_DTV() \ + (((tcbhead_t *) __builtin_thread_pointer ())->dtv) + +# endif /* __ASSEMBLER__ */ + +#else /* HAVE_TLS_SUPPORT && (FLOATING_STACKS || !IS_IN_libpthread) */ + +# ifndef __ASSEMBLER__ + +/* Get the thread descriptor definition. */ +# include <linuxthreads/descr.h> + +# define NONTLS_INIT_TP \ do { \ static const tcbhead_t nontls_init_tp \ = { .multiple_threads = 0 }; \ INIT_THREAD_SELF (&nontls_init_tp, 0); \ } while (0) -#endif /* USE_TLS */ +# endif /* __ASSEMBLER__ */ + +#endif /* HAVE_TLS_SUPPORT && (FLOATING_STACKS || !IS_IN_libpthread) */ #endif /* tls.h */ diff -urN libc/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h libc-s390/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h --- libc/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h Tue Jan 14 09:52:46 2003 +++ libc-s390/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h Sat Jan 25 18:15:17 2003 @@ -51,7 +51,7 @@ L(pseudo_check): \ lghi %r4,-4095; \ clgr %r2,%r4; \ - jnl SYSCALL_ERROR_LABEL; \ + jgnl SYSCALL_ERROR_LABEL; \ L(pseudo_end): # ifdef IS_IN_libpthread diff -urN libc/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/vfork.S libc-s390/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/vfork.S --- libc/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/vfork.S Sun Jan 12 23:58:37 2003 +++ libc-s390/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/vfork.S Sat Jan 25 18:15:17 2003 @@ -36,7 +36,7 @@ /* Check for error. */ lghi %r4,-4095 clgr %r2,%r4 - jnl SYSCALL_ERROR_LABEL + jgnl SYSCALL_ERROR_LABEL /* Normal return. */ br %r14 diff -urN libc/sysdeps/s390/Versions libc-s390/sysdeps/s390/Versions --- libc/sysdeps/s390/Versions Thu Jan 1 01:00:00 1970 +++ libc-s390/sysdeps/s390/Versions Sat Jan 25 18:15:17 2003 @@ -0,0 +1,6 @@ +ld { + GLIBC_2.3 { + # runtime interface to TLS + __tls_get_offset; + } +} \ No newline at end of file diff -urN libc/sysdeps/s390/dl-tls.h libc-s390/sysdeps/s390/dl-tls.h --- libc/sysdeps/s390/dl-tls.h Thu Jan 1 01:00:00 1970 +++ libc-s390/sysdeps/s390/dl-tls.h Sat Jan 25 18:15:17 2003 @@ -0,0 +1,73 @@ +/* Thread-local storage handling in the ELF dynamic linker. s390 version. + Copyright (C) 2003 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + + +/* Type used for the representation of TLS information in the GOT. */ +typedef struct +{ + unsigned long int ti_module; + unsigned long int ti_offset; +} tls_index; + + +#ifdef SHARED +/* This is the prototype for the GNU version. */ +extern void *__tls_get_addr (tls_index *ti) attribute_hidden; +extern unsigned long __tls_get_offset (unsigned long got_offset); + +/* The special thing about the s390 TLS ABI is that we do not have the + standard __tls_get_addr function but the __tls_get_offset function + which differs in two important aspects: + 1) __tls_get_offset gets a got offset instead of a pointer to the + tls_index structure + 2) __tls_get_offset returns the offset of the requested variable to + the thread descriptor instead of a pointer to the variable. + */ +#if defined __s390x__ +asm("\n\ + .text\n\ + .globl __tls_get_offset\n\ + .type __tls_get_offset, @function\n\ + .align 4\n\ +__tls_get_offset:\n\ + la %r2,0(%r2,%r12)\n\ + jg __tls_get_addr\n\ +"); +#elif defined __s390__ +asm("\n\ + .text\n\ + .globl __tls_get_offset\n\ + .type __tls_get_offset, @function\n\ + .align 4\n\ +__tls_get_offset:\n\ + basr %r3,0\n\ +0: la %r2,0(%r2,%r12)\n\ + l %r4,1f-0b(%r3)\n\ + b 0(%r4,%r3)\n\ +1: .long __tls_get_addr - 0b\n\ +"); +#endif + +#define GET_ADDR_OFFSET \ + (ti->ti_offset - (unsigned long) __builtin_thread_pointer ()) + +#define __TLS_GET_ADDR(__ti) \ + (__tls_get_addr(__ti) + (unsigned long) __builtin_thread_pointer ()) + +#endif diff -urN libc/sysdeps/s390/libc-tls.c libc-s390/sysdeps/s390/libc-tls.c --- libc/sysdeps/s390/libc-tls.c Thu Jan 1 01:00:00 1970 +++ libc-s390/sysdeps/s390/libc-tls.c Sat Jan 25 18:15:17 2003 @@ -0,0 +1,37 @@ +/* Thread-local storage handling in the ELF dynamic linker. IA-64 version. + Copyright (C) 2003 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <sysdeps/generic/libc-tls.c> + +#if USE_TLS + +/* On s390, the literal pool entry that refers to __tls_get_offset + is not removed, even if all branches that use the literal pool + entry gets removed by TLS optimizations. To get binaries + statically linked __tls_get_offset is defined here but + aborts if it is used. */ + +void * +__tls_get_offset (size_t m, size_t offset) +{ + abort (); +} + +#endif + diff -urN libc/sysdeps/s390/s390-32/dl-machine.h libc-s390/sysdeps/s390/s390-32/dl-machine.h --- libc/sysdeps/s390/s390-32/dl-machine.h Fri Mar 1 10:43:37 2002 +++ libc-s390/sysdeps/s390/s390-32/dl-machine.h Sat Jan 25 18:15:17 2003 @@ -312,13 +312,22 @@ #define RTLD_START_SPECIAL_INIT /* nothing */ #endif -/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so - PLT entries should not be allowed to define the value. +/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or + TLS variable, so undefined references should not be allowed to + define the value. ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one of the main executable's symbols, as for a COPY reloc. */ -#define elf_machine_type_class(type) \ +#ifdef USE_TLS +# define elf_machine_type_class(type) \ + ((((type) == R_390_JMP_SLOT || (type) == R_390_TLS_DTPMOD \ + || (type) == R_390_TLS_DTPOFF || (type) == R_390_TLS_TPOFF) \ + * ELF_RTYPE_CLASS_PLT) \ + | (((type) == R_390_COPY) * ELF_RTYPE_CLASS_COPY)) +#else +# define elf_machine_type_class(type) \ ((((type) == R_390_JMP_SLOT) * ELF_RTYPE_CLASS_PLT) \ | (((type) == R_390_COPY) * ELF_RTYPE_CLASS_COPY)) +#endif /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */ #define ELF_MACHINE_JMP_SLOT R_390_JMP_SLOT @@ -372,25 +381,90 @@ { const unsigned int r_type = ELF32_R_TYPE (reloc->r_info); +#if !defined RTLD_BOOTSTRAP || !defined HAVE_Z_COMBRELOC if (__builtin_expect (r_type == R_390_RELATIVE, 0)) - *reloc_addr = map->l_addr + reloc->r_addend; -#ifndef RTLD_BOOTSTRAP - else if (__builtin_expect (r_type == R_390_NONE, 0)) - return; + { +# if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC + /* This is defined in rtld.c, but nowhere in the static libc.a; + make the reference weak so static programs can still link. + This declaration cannot be done when compiling rtld.c + (i.e. #ifdef RTLD_BOOTSTRAP) because rtld.c contains the + common defn for _dl_rtld_map, which is incompatible with a + weak decl in the same file. */ +# ifndef SHARED + weak_extern (GL(dl_rtld_map)); +# endif + if (map != &GL(dl_rtld_map)) /* Already done in rtld itself. */ +# endif + *reloc_addr = map->l_addr + reloc->r_addend; + } + else #endif + if (__builtin_expect (r_type == R_390_NONE, 0)) + return; else { const Elf32_Sym *const refsym = sym; +#if defined USE_TLS && !defined RTLD_BOOTSTRAP + struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); + Elf32_Addr value = sym == NULL ? 0 : sym_map->l_addr + sym->st_value; +#else Elf32_Addr value = RESOLVE (&sym, version, r_type); + +# ifndef RTLD_BOOTSTRAP if (sym) +# endif value += sym->st_value; +#endif /* use TLS and !RTLD_BOOTSTRAP */ switch (r_type) { case R_390_GLOB_DAT: case R_390_JMP_SLOT: - *reloc_addr = value; + *reloc_addr = value + reloc->r_addend; break; + +#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) + case R_390_TLS_DTPMOD: +# ifdef RTLD_BOOTSTRAP + /* During startup the dynamic linker is always the module + with index 1. + XXX If this relocation is necessary move before RESOLVE + call. */ + *reloc_addr = 1; +# else + /* Get the information from the link map returned by the + resolv function. */ + if (sym_map != NULL) + *reloc_addr = sym_map->l_tls_modid; +# endif + break; + case R_390_TLS_DTPOFF: +# ifndef RTLD_BOOTSTRAP + /* During relocation all TLS symbols are defined and used. + Therefore the offset is already correct. */ + if (sym != NULL) + *reloc_addr = sym->st_value + reloc->r_addend; +# endif + break; + case R_390_TLS_TPOFF: + /* The offset is negative, forward from the thread pointer. */ +# ifdef RTLD_BOOTSTRAP + *reloc_addr = sym->st_value + reloc->r_addend - map->l_tls_offset; +# else + /* We know the offset of the object the symbol is contained in. + It is a negative value which will be added to the + thread pointer. */ + if (sym != NULL) + { + *reloc_addr = (sym->st_value + reloc->r_addend + - sym_map->l_tls_offset); + CHECK_STATIC_TLS (map, sym_map); + } +#endif + break; +#endif /* use TLS */ + #ifndef RTLD_BOOTSTRAP case R_390_COPY: if (sym == NULL) diff -urN libc/sysdeps/s390/s390-32/elf/configure libc-s390/sysdeps/s390/s390-32/elf/configure --- libc/sysdeps/s390/s390-32/elf/configure Thu Jan 1 01:00:00 1970 +++ libc-s390/sysdeps/s390/s390-32/elf/configure Sat Jan 25 18:15:17 2003 @@ -0,0 +1,52 @@ +# This file is generated from configure.in by Autoconf. DO NOT EDIT! + # Local configure fragment for sysdeps/s390/elf. + +if test "$usetls" != no; then +# Check for support of thread-local storage handling in assembler and +# linker. +echo "$as_me:$LINENO: checking for s390 TLS support" >&5 +echo $ECHO_N "checking for s390 TLS support... $ECHO_C" >&6 +if test "${libc_cv_390_tls+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat > conftest.s <<\EOF + .section ".tdata", "awT", @progbits +foo: .long 25 + .text + .long foo@TLSGD + .long foo@TLSLDM + .long foo@DTPOFF + .long foo@NTPOFF + .long foo@GOTNTPOFF + .long foo@INDNTPOFF + l %r1,foo@GOTNTPOFF(%r12) + l %r1,0(%r1):tls_load:foo + bas %r14,0(%r1,%r13):tls_gdcall:foo + bas %r14,0(%r1,%r13):tls_ldcall:foo +EOF +if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + libc_cv_390_tls=yes +else + libc_cv_390_tls=no +fi +rm -f conftest* +fi +echo "$as_me:$LINENO: result: $libc_cv_390_tls" >&5 +echo "${ECHO_T}$libc_cv_390_tls" >&6 +if test $libc_cv_390_tls = yes; then + cat >>confdefs.h <<\_ACEOF +#define HAVE_TLS_SUPPORT 1 +_ACEOF + +fi +fi + +cat >>confdefs.h <<\_ACEOF +#define PI_STATIC_AND_HIDDEN 1 +_ACEOF + diff -urN libc/sysdeps/s390/s390-32/elf/configure.in libc-s390/sysdeps/s390/s390-32/elf/configure.in --- libc/sysdeps/s390/s390-32/elf/configure.in Thu Jan 1 01:00:00 1970 +++ libc-s390/sysdeps/s390/s390-32/elf/configure.in Sat Jan 25 18:15:17 2003 @@ -0,0 +1,37 @@ +GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. +# Local configure fragment for sysdeps/s390/elf. + +if test "$usetls" != no; then +# Check for support of thread-local storage handling in assembler and +# linker. +AC_CACHE_CHECK(for s390 TLS support, libc_cv_390_tls, [dnl +cat > conftest.S <<\EOF + .section ".tdata", "awT", @progbits +foo: .long 25 + .text + .long foo@TLSGD + .long foo@TLSLDM + .long foo@DTPOFF + .long foo@NTPOFF + .long foo@GOTNTPOFF + .long foo@INDNTPOFF + l %r1,foo@GOTNTPOFF(%r12) + l %r1,0(%r1):tls_load:foo + bas %r14,0(%r1,%r13):tls_gdcall:foo + bas %r14,0(%r1,%r13):tls_ldcall:foo +EOF +dnl +if AC_TRY_COMMAND(${CC-cc} -S $CFLAGS conftest.S 1>&AS_MESSAGE_LOG_FD); then + libc_cv_390_tls=yes +else + libc_cv_390_tls=no +fi +rm -f conftest*]) +if test $libc_cv_390_tls = yes; then + AC_DEFINE(HAVE_TLS_SUPPORT) +fi +fi + +dnl It is always possible to access static and hidden symbols in an +dnl position independent way. +AC_DEFINE(PI_STATIC_AND_HIDDEN) diff -urN libc/sysdeps/s390/s390-64/dl-machine.h libc-s390/sysdeps/s390/s390-64/dl-machine.h --- libc/sysdeps/s390/s390-64/dl-machine.h Wed Aug 28 23:21:23 2002 +++ libc-s390/sysdeps/s390/s390-64/dl-machine.h Sat Jan 25 18:15:17 2003 @@ -284,13 +284,22 @@ #define RTLD_START_SPECIAL_INIT /* nothing */ #endif -/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so - PLT entries should not be allowed to define the value. +/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or + TLS variable, so undefined references should not be allowed to + define the value. ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one of the main executable's symbols, as for a COPY reloc. */ -#define elf_machine_type_class(type) \ +#ifdef USE_TLS +# define elf_machine_type_class(type) \ + ((((type) == R_390_JMP_SLOT || (type) == R_390_TLS_DTPMOD \ + || (type) == R_390_TLS_DTPOFF || (type) == R_390_TLS_TPOFF) \ + * ELF_RTYPE_CLASS_PLT) \ + | (((type) == R_390_COPY) * ELF_RTYPE_CLASS_COPY)) +#else +# define elf_machine_type_class(type) \ ((((type) == R_390_JMP_SLOT) * ELF_RTYPE_CLASS_PLT) \ | (((type) == R_390_COPY) * ELF_RTYPE_CLASS_COPY)) +#endif /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */ #define ELF_MACHINE_JMP_SLOT R_390_JMP_SLOT @@ -340,18 +349,41 @@ { const unsigned int r_type = ELF64_R_TYPE (reloc->r_info); +#if !defined RTLD_BOOTSTRAP || !defined HAVE_Z_COMBRELOC if (__builtin_expect (r_type == R_390_RELATIVE, 0)) - *reloc_addr = map->l_addr + reloc->r_addend; -#ifndef RTLD_BOOTSTRAP - else if (__builtin_expect (r_type == R_390_NONE, 0)) - return; + { +# if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC + /* This is defined in rtld.c, but nowhere in the static libc.a; + make the reference weak so static programs can still link. + This declaration cannot be done when compiling rtld.c + (i.e. #ifdef RTLD_BOOTSTRAP) because rtld.c contains the + common defn for _dl_rtld_map, which is incompatible with a + weak decl in the same file. */ +# ifndef SHARED + weak_extern (GL(dl_rtld_map)); +# endif + if (map != &GL(dl_rtld_map)) /* Already done in rtld itself. */ +# endif + *reloc_addr = map->l_addr + reloc->r_addend; + } + else #endif + if (__builtin_expect (r_type == R_390_NONE, 0)) + return; else { const Elf64_Sym *const refsym = sym; +#if defined USE_TLS && !defined RTLD_BOOTSTRAP + struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); + Elf64_Addr value = sym == NULL ? 0 : sym_map->l_addr + sym->st_value; +#else Elf64_Addr value = RESOLVE (&sym, version, r_type); + +# ifndef RTLD_BOOTSTRAP if (sym) +# endif value += sym->st_value; +#endif /* use TLS and !RTLD_BOOTSTRAP */ switch (r_type) { @@ -359,6 +391,48 @@ case R_390_JMP_SLOT: *reloc_addr = value + reloc->r_addend; break; + +#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) + case R_390_TLS_DTPMOD: +# ifdef RTLD_BOOTSTRAP + /* During startup the dynamic linker is always the module + with index 1. + XXX If this relocation is necessary move before RESOLVE + call. */ + *reloc_addr = 1; +# else + /* Get the information from the link map returned by the + resolv function. */ + if (sym_map != NULL) + *reloc_addr = sym_map->l_tls_modid; +# endif + break; + case R_390_TLS_DTPOFF: +# ifndef RTLD_BOOTSTRAP + /* During relocation all TLS symbols are defined and used. + Therefore the offset is already correct. */ + if (sym != NULL) + *reloc_addr = sym->st_value + reloc->r_addend; +# endif + break; + case R_390_TLS_TPOFF: + /* The offset is negative, forward from the thread pointer. */ +# ifdef RTLD_BOOTSTRAP + *reloc_addr = sym->st_value + reloc->r_addend - map->l_tls_offset; +# else + /* We know the offset of the object the symbol is contained in. + It is a negative value which will be added to the + thread pointer. */ + if (sym != NULL) + { + *reloc_addr = (sym->st_value + reloc->r_addend + - sym_map->l_tls_offset); + CHECK_STATIC_TLS (map, sym_map); + } +#endif + break; +#endif /* use TLS */ + #ifndef RTLD_BOOTSTRAP case R_390_COPY: if (sym == NULL) @@ -439,7 +513,7 @@ Elf64_Addr l_addr, const Elf64_Rela *reloc) { Elf64_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset); - const unsigned int r_type = ELF32_R_TYPE (reloc->r_info); + const unsigned int r_type = ELF64_R_TYPE (reloc->r_info); /* Check for unexpected PLT reloc type. */ if (__builtin_expect (r_type == R_390_JMP_SLOT, 1)) { diff -urN libc/sysdeps/s390/s390-64/elf/configure libc-s390/sysdeps/s390/s390-64/elf/configure --- libc/sysdeps/s390/s390-64/elf/configure Thu Jan 1 01:00:00 1970 +++ libc-s390/sysdeps/s390/s390-64/elf/configure Sat Jan 25 18:15:17 2003 @@ -0,0 +1,52 @@ +# This file is generated from configure.in by Autoconf. DO NOT EDIT! + # Local configure fragment for sysdeps/s390/elf. + +if test "$usetls" != no; then +# Check for support of thread-local storage handling in assembler and +# linker. +echo "$as_me:$LINENO: checking for s390 TLS support" >&5 +echo $ECHO_N "checking for s390 TLS support... $ECHO_C" >&6 +if test "${libc_cv_390_tls+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat > conftest.s <<\EOF + .section ".tdata", "awT", @progbits +foo: .long 25 + .text + .quad foo@TLSGD + .quad foo@TLSLDM + .quad foo@DTPOFF + .quad foo@NTPOFF + .quad foo@GOTNTPOFF + .quad foo@INDNTPOFF + lg %r1,foo@GOTNTPOFF(%r12) + lg %r1,0(%r1):tls_load:foo + brasl %r14,__tls_get_offset@plt:tls_gdcall:foo + brasl %r14,__tls_get_offset@plt:tls_ldcall:foo +EOF +if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + libc_cv_390_tls=yes +else + libc_cv_390_tls=no +fi +rm -f conftest* +fi +echo "$as_me:$LINENO: result: $libc_cv_390_tls" >&5 +echo "${ECHO_T}$libc_cv_390_tls" >&6 +if test $libc_cv_390_tls = yes; then + cat >>confdefs.h <<\_ACEOF +#define HAVE_TLS_SUPPORT 1 +_ACEOF + +fi +fi + +cat >>confdefs.h <<\_ACEOF +#define PI_STATIC_AND_HIDDEN 1 +_ACEOF + diff -urN libc/sysdeps/s390/s390-64/elf/configure.in libc-s390/sysdeps/s390/s390-64/elf/configure.in --- libc/sysdeps/s390/s390-64/elf/configure.in Thu Jan 1 01:00:00 1970 +++ libc-s390/sysdeps/s390/s390-64/elf/configure.in Sat Jan 25 18:15:17 2003 @@ -0,0 +1,37 @@ +GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. +# Local configure fragment for sysdeps/s390/elf. + +if test "$usetls" != no; then +# Check for support of thread-local storage handling in assembler and +# linker. +AC_CACHE_CHECK(for s390 TLS support, libc_cv_390_tls, [dnl +cat > conftest.S <<\EOF + .section ".tdata", "awT", @progbits +foo: .long 25 + .text + .quad foo@TLSGD + .quad foo@TLSLDM + .quad foo@DTPOFF + .quad foo@NTPOFF + .quad foo@GOTNTPOFF + .quad foo@INDNTPOFF + lg %r1,foo@GOTNTPOFF(%r12) + lg %r1,0(%r1):tls_load:foo + brasl %r14,__tls_get_offset@plt:tls_gdcall:foo + brasl %r14,__tls_get_offset@plt:tls_ldcall:foo +EOF +dnl +if AC_TRY_COMMAND(${CC-cc} -S $CFLAGS conftest.S 1>&AS_MESSAGE_LOG_FD); then + libc_cv_390_tls=yes +else + libc_cv_390_tls=no +fi +rm -f conftest*]) +if test $libc_cv_390_tls = yes; then + AC_DEFINE(HAVE_TLS_SUPPORT) +fi +fi + +dnl It is always possible to access static and hidden symbols in an +dnl position independent way. +AC_DEFINE(PI_STATIC_AND_HIDDEN) diff -urN libc/sysdeps/unix/sysv/linux/s390/s390-32/clone.S libc-s390/sysdeps/unix/sysv/linux/s390/s390-32/clone.S --- libc/sysdeps/unix/sysv/linux/s390/s390-32/clone.S Thu Feb 7 18:33:41 2002 +++ libc-s390/sysdeps/unix/sysv/linux/s390/s390-32/clone.S Sat Jan 25 18:15:17 2003 @@ -24,20 +24,24 @@ #define _ERRNO_H 1 #include <bits/errno.h> -/*int __clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg);*/ -/* sys_clone(void *child_stack, unsigned long flags) */ +/* int __clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg, + void *tls, pid_t *parent_tid, pid_t *child_tid); */ +/* sys_clone (void *child_stack, unsigned long flags, + pid_t *parent_tid, pid_t *child_tid, void *tls); */ .text ENTRY(__clone) /* Sanity check arguments & move registers */ + lr %r0,%r5 /* move *arg out of the way */ ltr %r1,%r2 /* no NULL function pointers */ lhi %r2,-EINVAL jz SYSCALL_ERROR_LABEL ltr %r3,%r3 /* no NULL stack pointers */ jz SYSCALL_ERROR_LABEL - /* move child_stack and flags, then call SVC */ + /* set up registers, then call SVC */ lr %r2,%r3 lr %r3,%r4 + lm %r4,%r5,96(%r15) svc SYS_ify(clone) ltr %r2,%r2 /* check return code */ jm SYSCALL_ERROR_LABEL @@ -45,10 +49,10 @@ br %r14 thread_start: - /* fn is in gpr 1, arg in gpr 5 */ - lr %r2,%r5 /* set first parameter to void *arg */ - sr %r11,%r11 /* terminate the stack frame */ + /* fn is in gpr 1, arg in gpr 0 */ + lr %r2,%r0 /* set first parameter to void *arg */ ahi %r15,-96 /* make room on the stack for the save area */ + xc 0(4,%r15),0(%r15) basr %r14,%r1 /* jump to fn */ #ifdef PIC basr %r12,0 diff -urN libc/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.S libc-s390/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.S --- libc/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.S Fri Oct 11 12:51:29 2002 +++ libc-s390/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.S Sat Jan 25 18:15:17 2003 @@ -1,4 +1,4 @@ -/* Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc. +/* Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). This file is part of the GNU C Library. @@ -31,59 +31,94 @@ .text ENTRY(__syscall_error) #ifndef PIC -#ifndef _LIBC_REENTRANT - lcr %r2,%r2 - basr %r1,0 -.L0: l %r1,.L1-.L0(%r1) - st %r2,0(0,%r1) - lhi %r2,-1 - br %r14 -.L1: .long errno -#else - stm %r11,%r15,44(%r15) - lr %r0,%r15 - ahi %r15,-96 - st %r0,0(%r15) - lcr %r11,%r2 - basr %r13,0 -.L0: l %r1,.L1-.L0(%r13) - basr %r14,%r1 - st %r11,0(%r2) - lhi %r2,-1 - l %r15,0(%r15) - lm %r11,%r15,44(%r15) - br %r14 -.L1: .long __errno_location +# if USE___THREAD +# ifndef NOT_IN_libc +# define SYSCALL_ERROR_ERRNO __libc_errno +# else +# define SYSCALL_ERROR_ERRNO errno +# endif + basr %r1,0 +0: l %r1,1f-0b(%r1) + ear %r3,%a0 + lcr %r2,%r2 + st %r2,0(%r1,%r3) + lhi %r2,-1 + br %r14 +1: .long SYSCALL_ERROR_ERRNO@ntpoff +# elif !defined _LIBC_REENTRANT + basr %r1,0 +0: l %r1,1f-0b(%r1) + lcr %r2,%r2 + st %r2,0(%r1) + lhi %r2,-1 + br %r14 +1: .long errno +# else + stm %r13,%r15,52(%r15) + lr %r0,%r15 + ahi %r15,-96 + lcr %r13,%r2 + st %r0,0(%r15) + basr %r1,0 +0: l %r1,1f-0b(%r1) + basr %r14,%r1 + st %r13,0(%r2) + lm %r13,%r15,148(%r15) + lhi %r2,-1 + br %r14 +1: .long __errno_location #endif #else -#ifndef _LIBC_REENTRANT - basr %r1,0 -.L0: al %r1,.L1-.L0(%r1) - l %r1,errno@GOT12(%r1) - lcr %r2,%r2 - st %r2,0(0,%r1) - lhi %r2,-1 - br %r14 -.L1: .long _GLOBAL_OFFSET_TABLE_-0b -#else - stm %r11,%r15,44(%r15) - lr %r0,%r15 - ahi %r15,-96 - st %r0,0(%r15) - lcr %r11,%r2 - basr %r13,0 -.L0: l %r12,.L1-.L0(%r13) - ar %r12,%r13 - l %r14,.L2-.L0(%r13) - bas %r14,0(%r14,%r13) - st %r11,0(0,%r2) - lhi %r2,-1 - l %r15,0(%r15) - lm %r11,%r15,44(%r15) - br %r14 -.L1: .long _GLOBAL_OFFSET_TABLE_ - .L0 -.L2: .long __errno_location@PLT - .L0 -#endif +# if RTLD_PRIVATE_ERRNO + basr %r1,0 +0: al %r1,1f-0b(%r1) + lcr %r2,%r2 + st %r2,0(%r1) + lhi %r2,-1 + br %r14 +1: .long errno - 0b +# elif USE___THREAD +# ifndef NOT_IN_libc +# define SYSCALL_ERROR_ERRNO __libc_errno +# else +# define SYSCALL_ERROR_ERRNO errno +# endif + basr %r1,0 +0: al %r1,1f-0b(%r1) + ear %r3,%a0 + l %r1,SYSCALL_ERROR_ERRNO@gotntpoff(%r1) + lcr %r2,%r2 + st %r2,0(%r1,%r3) + lhi %r2,-1 + br %r14 +1: .long _GLOBAL_OFFSET_TABLE_-0b +# elif !defined _LIBC_REENTRANT + basr %r1,0 +0: al %r1,1f-0b(%r1) + l %r1,errno@GOT(%r1) + lcr %r2,%r2 + st %r2,0(0,%r1) + lhi %r2,-1 + br %r14 +1: .long _GLOBAL_OFFSET_TABLE_-0b +# else + stm %r11,%r15,44(%r15) + lr %r0,%r15 + ahi %r15,-96 + lcr %r11,%r2 + st %r0,0(%r15) + basr %r13,0 +0: l %r12,1f-0b(%r13) + l %r1,2f-0b(%r13) + la %r12,0(%r12,%r13) + bas %r14,0(%r1,%r13) + st %r11,0(%r2) + lm %r11,%r15,140(%r15) + lhi %r2,-1 + br %r14 +1: .long _GLOBAL_OFFSET_TABLE_-0b +2: .long __errno_location@PLT-0b +# endif #endif END (__syscall_error) diff -urN libc/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h libc-s390/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h --- libc/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h Mon Jan 20 20:04:56 2003 +++ libc-s390/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h Sat Jan 25 18:15:17 2003 @@ -45,8 +45,6 @@ number. Linus said he will make sure the no syscall returns a value in -1 .. -4095 as a valid result so we can savely test with -4095. */ -#define SYSCALL_ERROR_LABEL 0f - #undef PSEUDO #define PSEUDO(name, syscall_name, args) \ .text; \ @@ -54,42 +52,70 @@ DO_CALL (syscall_name, args); \ lhi %r4,-4095 ; \ clr %r2,%r4 ; \ - jnl SYSCALL_ERROR_LABEL ; \ - L(pseudo_end): + jnl SYSCALL_ERROR_LABEL #undef PSEUDO_END #define PSEUDO_END(name) \ SYSCALL_ERROR_HANDLER; \ END (name) -#ifndef _LIBC_REENTRANT #ifndef PIC -#define SYSCALL_ERROR_HANDLER \ -0: lcr %r2,%r2 ; \ - basr %r1,0 ; \ -1: l %r1,2f-1b(%r1) \ - st %r2,0(%r1) \ - lhi %r2,-1 \ - br %r14 \ -2: .long errno +# define SYSCALL_ERROR_LABEL 0f +# define SYSCALL_ERROR_HANDLER \ +0: basr %r1,0; \ +1: l %r1,2f-1b(%r1); \ + br %r1; \ +2: .long syscall_error #else -#define SYSCALL_ERROR_HANDLER \ -0: basr %r1,0 ; \ -1: al %r1,2f-1b(%r1) ; \ - l %r1,errno@GOT12(%r1) ; \ - lcr %r2,%r2 ; \ - st %r2,0(%r1) ; \ - lhi %r2,-1 ; \ - br %r14 ; \ -2: .long _GLOBAL_OFFSET_TABLE_-1b +# if RTLD_PRIVATE_ERRNO +# define SYSCALL_ERROR_LABEL 0f +# define SYSCALL_ERROR_HANDLER \ +0: basr %r1,0; \ +1: al %r1,2f-1b(%r1); \ + lcr %r2,%r2; \ + st %r2,0(%r1); \ + lhi %r2,-1; \ + br %r14; \ +2: .long errno-1b +# elif defined _LIBC_REENTRANT +# if USE___THREAD +# ifndef NOT_IN_libc +# define SYSCALL_ERROR_ERRNO __libc_errno +# else +# define SYSCALL_ERROR_ERRNO errno +# endif +# define SYSCALL_ERROR_LABEL 0f +# define SYSCALL_ERROR_HANDLER \ +0: lcr %r0,%r2; \ + basr %r1,0; \ +1: al %r1,2f-1b(%r1); \ + l %r1,SYSCALL_ERROR_ERRNO@gotntpoff(%r1) \ + ear %r2,%a0 \ + st %r0,0(%r1,%r2); \ + lhi %r2,-1; \ + br %r14; \ +2: .long _GLOBAL_OFFSET_TABLE_-1b +# else +# define SYSCALL_ERROR_LABEL 0f +# define SYSCALL_ERROR_HANDLER \ +0: basr %r1,0; \ +1: al %r1,2f-1b(%r1); \ + br %r1; \ +2: .long syscall_error@plt-1b +# endif +# else +# define SYSCALL_ERROR_LABEL 0f +# define SYSCALL_ERROR_HANDLER \ +0: basr %r1,0; \ +1: al %r1,2f-1b(%r1); \ + l %r1,errno@GOT(%r1); \ + lcr %r2,%r2; \ + st %r2,0(%r1); \ + lhi %r2,-1; \ + br %r14; \ +2: .long _GLOBAL_OFFSET_TABLE_-1b +# endif /* _LIBC_REENTRANT */ #endif /* PIC */ -#else -#define SYSCALL_ERROR_HANDLER \ -0: basr %r1,0 ; \ -1: al %r1,2f-1b(%r1) ; \ - br %r1 ; \ -2: .long __syscall_error@PLT-1b -#endif /* _LIBC_REENTRANT */ /* Linux takes system call arguments in registers: diff -urN libc/sysdeps/unix/sysv/linux/s390/s390-64/clone.S libc-s390/sysdeps/unix/sysv/linux/s390/s390-64/clone.S --- libc/sysdeps/unix/sysv/linux/s390/s390-64/clone.S Thu Feb 7 18:33:42 2002 +++ libc-s390/sysdeps/unix/sysv/linux/s390/s390-64/clone.S Sat Jan 25 18:15:17 2003 @@ -25,32 +25,40 @@ #define _ERRNO_H 1 #include <bits/errno.h> +/* int __clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg, + void *tls, pid_t *parent_tid, pid_t *child_tid); */ +/* sys_clone (void *child_stack, unsigned long flags, + pid_t *parent_tid, pid_t *child_tid, void *tls); */ + .text ENTRY(__clone) /* Sanity check arguments & move registers */ + lgr %r0,%r5 /* move *arg out of the way */ ltgr %r1,%r2 /* no NULL function pointers */ lghi %r2,-EINVAL - jz SYSCALL_ERROR_LABEL + jgz SYSCALL_ERROR_LABEL ltgr %r3,%r3 /* no NULL stack pointers */ - jz SYSCALL_ERROR_LABEL - /* move child_stack and flags, then call SVC */ + jgz SYSCALL_ERROR_LABEL + /* set up registers, then call SVC */ lgr %r2,%r3 lgr %r3,%r4 + lmg %r4,%r5,160(%r15) svc SYS_ify(clone) ltgr %r2,%r2 /* check return code */ - jm SYSCALL_ERROR_LABEL + jgm SYSCALL_ERROR_LABEL jz thread_start br %r14 thread_start: - /* fn is in gpr 1, arg in gpr 5 */ - lgr %r2,%r5 /* set first parameter to void *arg */ - sgr %r11,%r11 /* terminate the stack frame */ + /* fn is in gpr 1, arg in gpr 0 */ + lgr %r2,%r0 /* set first parameter to void *arg */ aghi %r15,-160 /* make room on the stack for the save area */ + xc 0(8,%r15),0(%r15) basr %r14,%r1 /* jump to fn */ #ifdef PIC - larl %r12,_GLOBAL_OFFSET_TABLE_ -#endif jg _exit@PLT /* branch to _exit -> thread termination */ +#else + jg _exit /* branch to _exit -> thread termination */ +#endif PSEUDO_END (__clone) weak_alias (__clone, clone) diff -urN libc/sysdeps/unix/sysv/linux/s390/s390-64/mmap.S libc-s390/sysdeps/unix/sysv/linux/s390/s390-64/mmap.S --- libc/sysdeps/unix/sysv/linux/s390/s390-64/mmap.S Thu Feb 7 18:35:50 2002 +++ libc-s390/sysdeps/unix/sysv/linux/s390/s390-64/mmap.S Sat Jan 25 18:15:17 2003 @@ -55,7 +55,7 @@ /* Check gpr 2 for error. */ lghi %r0,-4096 clgr %r2,%r0 - jnl SYSCALL_ERROR_LABEL + jgnl SYSCALL_ERROR_LABEL /* Successful; return the syscall's value. */ br %r14 diff -urN libc/sysdeps/unix/sysv/linux/s390/s390-64/socket.S libc-s390/sysdeps/unix/sysv/linux/s390/s390-64/socket.S --- libc/sysdeps/unix/sysv/linux/s390/s390-64/socket.S Sun Jan 5 08:04:04 2003 +++ libc-s390/sysdeps/unix/sysv/linux/s390/s390-64/socket.S Sat Jan 25 18:15:17 2003 @@ -93,7 +93,7 @@ /* gpr2 is < 0 if there was an error. */ lghi %r0,-125 clgr %r2,%r0 - jnl SYSCALL_ERROR_LABEL + jgnl SYSCALL_ERROR_LABEL /* Successful; return the syscall's value. */ br %r14 diff -urN libc/sysdeps/unix/sysv/linux/s390/s390-64/syscall.S libc-s390/sysdeps/unix/sysv/linux/s390/s390-64/syscall.S --- libc/sysdeps/unix/sysv/linux/s390/s390-64/syscall.S Fri Jul 6 06:56:20 2001 +++ libc-s390/sysdeps/unix/sysv/linux/s390/s390-64/syscall.S Sat Jan 25 18:15:17 2003 @@ -45,7 +45,7 @@ lghi %r0,-4095 clgr %r2,%r0 /* Check R2 for error. */ - jnl SYSCALL_ERROR_LABEL + jgnl SYSCALL_ERROR_LABEL br %r14 /* Return to caller. */ .L1: .word 0x0A00 /* Opcode for SVC 0. */ PSEUDO_END (syscall) diff -urN libc/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.S libc-s390/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.S --- libc/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.S Fri Oct 11 12:51:15 2002 +++ libc-s390/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.S Sat Jan 25 18:15:17 2003 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001, 2002 Free Software Foundation, Inc. +/* Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). This file is part of the GNU C Library. @@ -29,47 +29,84 @@ #undef CALL_MCOUNT #define CALL_MCOUNT - .text +.text ENTRY(__syscall_error) #ifndef PIC -#ifndef _LIBC_REENTRANT - lcr %r2,%r2 - larl %r1,errno - st %r2,0(%r1) - lghi %r2,-1 - br %r14 -#else - stmg %r13,%r15,104(%r15) - lgr %r0,%r15 - aghi %r15,-160 - lcr %r13,%r2 - stg %r0,0(%r15) - brasl %r14,__errno_location - st %r13,0(%r2) - lmg %r13,%r15,264(%r15) - lghi %r2,-1 - br %r14 +# if USE___THREAD +# ifndef NOT_IN_libc +# define SYSCALL_ERROR_ERRNO __libc_errno +# else +# define SYSCALL_ERROR_ERRNO errno +# endif + basr %r1,0 +0: lg %r1,1f-0b(%r1) + ear %r3,%a0 + sllg %r3,%r3,32 + ear %r3,%a1 + lcr %r2,%r2 + st %r2,0(%r1,%r3) + lghi %r2,-1 + br %r14 +1: .quad SYSCALL_ERROR_ERRNO@ntpoff +# elif !defined _LIBC_REENTRANT + larl %r1,errno + lcr %r2,%r2 + st %r2,0(%r1) + lghi %r2,-1 + br %r14 +# else + stmg %r13,%r15,104(%r15) + lgr %r0,%r15 + aghi %r15,-160 + lcr %r13,%r2 + stg %r0,0(%r15) + brasl %r14,__errno_location + st %r13,0(%r2) + lmg %r13,%r15,264(%r15) + lghi %r2,-1 + br %r14 #endif #else -#ifndef _LIBC_REENTRANT - larl %r1,_GLOBAL_OFFSET_TABLE_ - lg %r1,errno@GOT(%r1) - lcr %r2,%r2 - st %r2,0(%r1) - lghi %r2,-1 - br %r14 -#else - stmg %r13,%r15,104(%r15) - lgr %r0,%r15 - aghi %r15,-160 - lcr %r13,%r2 - stg %r0,0(%r15) - brasl %r14,__errno_location@PLT - st %r13,0(%r2) - lmg %r13,%r15,264(%r15) - lghi %r2,-1 - br %r14 -#endif +# if RTLD_PRIVATE_ERRNO + larl %r1,errno + lcr %r2,%r2 + st %r2,0(%r1) + lghi %r2,-1 + br %r14 +# elif USE___THREAD +# ifndef NOT_IN_libc +# define SYSCALL_ERROR_ERRNO __libc_errno +# else +# define SYSCALL_ERROR_ERRNO errno +# endif + larl %r1,_GLOBAL_OFFSET_TABLE_ + lg %r1,SYSCALL_ERROR_ERRNO@gotntpoff(%r1) + ear %r3,%a0 + sllg %r3,%r3,32 + ear %r3,%a1 + lcr %r2,%r2 + st %r2,0(%r1,%r3) + lghi %r2,-1 + br %r14 +# elif !defined _LIBC_REENTRANT + larl %r1,_GLOBAL_OFFSET_TABLE_ + lg %r1,errno@GOT(%r1) + lcr %r2,%r2 + st %r2,0(%r1) + lghi %r2,-1 + br %r14 +# else + stmg %r13,%r15,104(%r15) + lgr %r0,%r15 + aghi %r15,-160 + lcr %r13,%r2 + stg %r0,0(%r15) + brasl %r14,__errno_location@PLT + st %r13,0(%r2) + lmg %r13,%r15,264(%r15) + lghi %r2,-1 + br %r14 +# endif #endif END (__syscall_error) diff -urN libc/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h libc-s390/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h --- libc/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h Mon Jan 20 20:04:56 2003 +++ libc-s390/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h Sat Jan 25 18:15:17 2003 @@ -46,8 +46,6 @@ number. Linus said he will make sure the no syscall returns a value in -1 .. -4095 as a valid result so we can savely test with -4095. */ -#define SYSCALL_ERROR_LABEL 0f - #undef PSEUDO #define PSEUDO(name, syscall_name, args) \ .text; \ @@ -55,35 +53,58 @@ DO_CALL (syscall_name, args); \ lghi %r4,-4095 ; \ clgr %r2,%r4 ; \ - jnl SYSCALL_ERROR_LABEL ; \ - L(pseudo_end): + jgnl SYSCALL_ERROR_LABEL #undef PSEUDO_END #define PSEUDO_END(name) \ SYSCALL_ERROR_HANDLER; \ END (name) -#ifndef _LIBC_REENTRANT #ifndef PIC -#define SYSCALL_ERROR_HANDLER \ -0: lcr %r2,%r2 ; \ - larl %r1,errno ; \ - st %r2,0(%r1) ; \ - lghi %r2,-1 ; \ - br %r14 +# define SYSCALL_ERROR_LABEL syscall_error +# define SYSCALL_ERROR_HANDLER #else -#define SYSCALL_ERROR_HANDLER \ -0: larl %r1,_GLOBAL_OFFSET_TABLE_ ; \ - lg %r1,errno@GOT(%r1) ; \ - lcr %r2,%r2 ; \ - st %r2,0(%r1) ; \ - lghi %r2,-1 ; \ - br %r14 +# if RTLD_PRIVATE_ERRNO +# define SYSCALL_ERROR_LABEL 0f +# define SYSCALL_ERROR_HANDLER \ +0: larl %r1,errno; \ + lcr %r2,%r2; \ + st %r2,0(%r1); \ + lghi %r2,-1; \ + br %r14 +# elif defined _LIBC_REENTRANT +# if USE___THREAD +# ifndef NOT_IN_libc +# define SYSCALL_ERROR_ERRNO __libc_errno +# else +# define SYSCALL_ERROR_ERRNO errno +# endif +# define SYSCALL_ERROR_LABEL 0f +# define SYSCALL_ERROR_HANDLER \ +0: lcr %r0,%r2; \ + larl %r1,SYSCALL_ERROR_ERRNO@indntpoff; \ + lg %r1,0(%r1); \ + ear %r2,%a0; \ + sllg %r2,%r2,32; \ + ear %r2,%a1; \ + st %r0,0(%r1,%r2); \ + lghi %r2,-1; \ + br %r14 +# else +# define SYSCALL_ERROR_LABEL syscall_error@plt +# define SYSCALL_ERROR_HANDLER +# endif +# else +# define SYSCALL_ERROR_LABEL 0f +# define SYSCALL_ERROR_HANDLER \ +0: larl %r1,_GLOBAL_OFFSET_TABLE_; \ + lg %r1,errno@GOT(%r1); \ + lcr %r2,%r2; \ + st %r2,0(%r1); \ + lghi %r2,-1; \ + br %r14 +# endif /* _LIBC_REENTRANT */ #endif /* PIC */ -#else -#define SYSCALL_ERROR_HANDLER \ -0: jg __syscall_error@PLT -#endif /* _LIBC_REENTRANT */ /* Linux takes system call arguments in registers:
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |