1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-29 11:41:21 +03:00
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/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.
This commit is contained in:
Ulrich Drepper
2003-01-28 10:42:28 +00:00
parent 772e3426a7
commit e6ebd2e4db
30 changed files with 1344 additions and 349 deletions

View File

@ -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 @@ ENTRY(__clone)
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

View File

@ -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)

View File

@ -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:

View File

@ -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)

View File

@ -55,7 +55,7 @@ ENTRY(__mmap)
/* 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

View File

@ -93,7 +93,7 @@ ENTRY(__socket)
/* 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

View File

@ -45,7 +45,7 @@ ENTRY (syscall)
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)

View File

@ -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)

View File

@ -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: