mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-29 11:41:21 +03:00
Update.
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:
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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:
|
||||
|
||||
|
Reference in New Issue
Block a user