@@ -38,7 +38,11 @@
static inline
const char * __pthread_get_ip (const ucontext_t *uc)
{
+# ifdef __powerpc64__
return (char *)uc->uc_mcontext.gp_regs[PT_NIP];
+# else
+ return (char *)uc->uc_mcontext.uc_regs->gregs[PT_NIP];
+# endif
}
#endif
@@ -25,21 +25,9 @@ int
fallocate (int fd, int mode, __off_t offset, __off_t len)
{
#ifdef __NR_fallocate
- if (SINGLE_THREAD_P)
- return INLINE_SYSCALL (fallocate, 6, fd, mode,
- __LONG_LONG_PAIR (offset >> 31, offset),
- __LONG_LONG_PAIR (len >> 31, len));
-
- int result;
- int oldtype = LIBC_CANCEL_ASYNC ();
-
- result = INLINE_SYSCALL (fallocate, 6, fd, mode,
- __LONG_LONG_PAIR (offset >> 31, offset),
- __LONG_LONG_PAIR (len >> 31, len));
-
- LIBC_CANCEL_RESET (oldtype);
-
- return result;
+ return SYSCALL_CANCEL (fallocate, fd, mode,
+ __LONG_LONG_PAIR (offset >> 31, offset),
+ __LONG_LONG_PAIR (len >> 31, len));
#else
__set_errno (ENOSYS);
return -1;
@@ -25,25 +25,11 @@ int
fallocate64 (int fd, int mode, __off64_t offset, __off64_t len)
{
#ifdef __NR_fallocate
- if (SINGLE_THREAD_P)
- return INLINE_SYSCALL (fallocate, 6, fd, mode,
- __LONG_LONG_PAIR ((long int) (offset >> 32),
- (long int) offset),
- __LONG_LONG_PAIR ((long int) (len >> 32),
- (long int) len));
-
- int result;
- int oldtype = LIBC_CANCEL_ASYNC ();
-
- result = INLINE_SYSCALL (fallocate, 6, fd, mode,
- __LONG_LONG_PAIR ((long int) (offset >> 32),
- (long int) offset),
- __LONG_LONG_PAIR ((long int) (len >> 32),
- (long int) len));
-
- LIBC_CANCEL_RESET (oldtype);
-
- return result;
+ return SYSCALL_CANCEL (fallocate, fd, mode,
+ __LONG_LONG_PAIR ((long int) (offset >> 32),
+ (long int) offset),
+ __LONG_LONG_PAIR ((long int) (len >> 32),
+ (long int) len));
#else
__set_errno (ENOSYS);
return -1;
@@ -23,7 +23,7 @@
#include <sys/syscall.h>
-#ifndef NO_CANCELLATION
+#ifndef IS_IN_rtld
int
__fcntl_nocancel (int fd, int cmd, ...)
{
@@ -36,8 +36,7 @@ __fcntl_nocancel (int fd, int cmd, ...)
return INLINE_SYSCALL (fcntl64, 3, fd, cmd, arg);
}
-#endif /* NO_CANCELLATION */
-
+#endif
int
__libc_fcntl (int fd, int cmd, ...)
@@ -49,16 +48,10 @@ __libc_fcntl (int fd, int cmd, ...)
arg = va_arg (ap, void *);
va_end (ap);
- if (SINGLE_THREAD_P || (cmd != F_SETLKW && cmd != F_SETLKW64))
+ if ((cmd != F_SETLKW) && (cmd != F_SETLKW64))
return INLINE_SYSCALL (fcntl64, 3, fd, cmd, arg);
- int oldtype = LIBC_CANCEL_ASYNC ();
-
- int result = INLINE_SYSCALL (fcntl64, 3, fd, cmd, arg);
-
- LIBC_CANCEL_RESET (oldtype);
-
- return result;
+ return SYSCALL_CANCEL (fcntl64, fd, cmd, arg);
}
libc_hidden_def (__libc_fcntl)
@@ -36,16 +36,7 @@ __libc_open64 (const char *file, int oflag, ...)
va_end (arg);
}
- if (SINGLE_THREAD_P)
- return INLINE_SYSCALL (open, 3, file, oflag | O_LARGEFILE, mode);
-
- int oldtype = LIBC_CANCEL_ASYNC ();
-
- int result = INLINE_SYSCALL (open, 3, file, oflag | O_LARGEFILE, mode);
-
- LIBC_CANCEL_RESET (oldtype);
-
- return result;
+ return SYSCALL_CANCEL (open, file, oflag | O_LARGEFILE, mode);
}
weak_alias (__libc_open64, __open64)
libc_hidden_weak (__open64)
@@ -26,26 +26,8 @@
ssize_t
__libc_pread (int fd, void *buf, size_t count, off_t offset)
{
- ssize_t result;
-
- if (SINGLE_THREAD_P)
- {
- /* On PPC32 64bit values are aligned in odd/even register pairs. */
- result = INLINE_SYSCALL (pread, 6, fd, buf, count,
- 0, offset >> 31, offset);
-
- return result;
- }
-
- int oldtype = LIBC_CANCEL_ASYNC ();
-
/* On PPC32 64bit values are aligned in odd/even register pairs. */
- result = INLINE_SYSCALL (pread, 6, fd, buf, count,
- 0, offset >> 31, offset);
-
- LIBC_CANCEL_RESET (oldtype);
-
- return result;
+ return SYSCALL_CANCEL (pread, fd, buf, count, 0, offset >> 31, offset);
}
strong_alias (__libc_pread, __pread)
@@ -26,28 +26,9 @@
ssize_t
__libc_pread64 (int fd, void *buf, size_t count, off64_t offset)
{
- ssize_t result;
-
- if (SINGLE_THREAD_P)
- {
- /* On PPC32 64bit values are aligned in odd/even register pairs. */
- result = INLINE_SYSCALL (pread, 6, fd, buf, count,
- 0, (long) (offset >> 32),
- (long) offset);
-
- return result;
- }
-
- int oldtype = LIBC_CANCEL_ASYNC ();
-
/* On PPC32 64bit values are aligned in odd/even register pairs. */
- result = INLINE_SYSCALL (pread, 6, fd, buf, count,
- 0, (long) (offset >> 32),
- (long) offset);
-
- LIBC_CANCEL_RESET (oldtype);
-
- return result;
+ return SYSCALL_CANCEL (pread, fd, buf, count, 0, (long) (offset >> 32),
+ (long) offset);
}
weak_alias (__libc_pread64, __pread64)
@@ -27,26 +27,8 @@
ssize_t
__libc_pwrite (int fd, const void *buf, size_t count, off_t offset)
{
- ssize_t result;
-
- if (SINGLE_THREAD_P)
- {
- /* On PPC32 64bit values are aligned in odd/even register pairs. */
- result = INLINE_SYSCALL (pwrite, 6, fd, buf, count,
- 0, offset >> 31, offset);
-
- return result;
- }
-
- int oldtype = LIBC_CANCEL_ASYNC ();
-
/* On PPC32 64bit values are aligned in odd/even register pairs. */
- result = INLINE_SYSCALL (pwrite, 6, fd, buf, count,
- 0, offset >> 31, offset);
-
- LIBC_CANCEL_RESET (oldtype);
-
- return result;
+ return SYSCALL_CANCEL (pwrite, fd, buf, count, 0, offset >> 31, offset);
}
strong_alias (__libc_pwrite, __pwrite)
@@ -26,28 +26,9 @@
ssize_t
__libc_pwrite64 (int fd, const void *buf, size_t count, off64_t offset)
{
- ssize_t result;
-
- if (SINGLE_THREAD_P)
- {
/* On PPC32 64bit values are aligned in odd/even register pairs. */
- result = INLINE_SYSCALL (pwrite, 6, fd, buf, count,
- 0, (long) (offset >> 32),
- (long) offset);
-
- return result;
- }
-
- int oldtype = LIBC_CANCEL_ASYNC ();
-
- /* On PPC32 64bit values are aligned in odd/even register pairs. */
- result = INLINE_SYSCALL (pwrite, 6, fd, buf, count,
- 0, (long) (offset >> 32),
- (long) offset);
-
- LIBC_CANCEL_RESET (oldtype);
-
- return result;
+ return SYSCALL_CANCEL (pwrite, fd, buf, count, 0, (long) (offset >> 32),
+ (long) offset);
}
weak_alias (__libc_pwrite64, __pwrite64)
@@ -40,7 +40,7 @@
/* 0(r1) and 4(r1) are reserved by the ABI, 8(r1), 12(r1), 16(r1) are used
for temp saves. 44(r1) is used to save r30. */
-#define stackblock 20
+#define STACKBLOCK 20
#ifndef __socket
# ifndef NO_WEAK_ALIAS
@@ -55,63 +55,42 @@ ENTRY(__socket)
stwu r1,-48(r1)
cfi_adjust_cfa_offset(48)
#if NARGS >= 1
- stw r3,stackblock(r1)
+ stw r3,STACKBLOCK(r1)
#endif
#if NARGS >= 2
- stw r4,4+stackblock(r1)
+ stw r4,4+STACKBLOCK(r1)
#endif
#if NARGS >= 3
- stw r5,8+stackblock(r1)
+ stw r5,8+STACKBLOCK(r1)
#endif
#if NARGS >= 4
- stw r6,12+stackblock(r1)
+ stw r6,12+STACKBLOCK(r1)
#endif
#if NARGS >= 5
- stw r7,16+stackblock(r1)
+ stw r7,16+STACKBLOCK(r1)
#endif
#if NARGS >= 6
- stw r8,20+stackblock(r1)
+ stw r8,20+STACKBLOCK(r1)
#endif
#if NARGS >= 7
#error too many arguments!
#endif
-
-#if defined NEED_CANCELLATION && defined CENABLE
- SINGLE_THREAD_P
- bne- .Lsocket_cancel
-#endif
-
- li r3,P(SOCKOP_,socket)
- addi r4,r1,stackblock
- DO_CALL(SYS_ify(socketcall))
- addi r1,r1,48
- PSEUDO_RET
-
-#if defined NEED_CANCELLATION && defined CENABLE
-.Lsocket_cancel:
mflr r9
+ SETUP_PIC;
stw r9,52(r1)
cfi_offset (lr, 4)
- CENABLE
- stw r3,16(r1)
- li r3,P(SOCKOP_,socket)
- addi r4,r1,stackblock
- DO_CALL(SYS_ify(socketcall))
- mfcr r0
- stw r3,8(r1)
- stw r0,12(r1)
- lwz r3,16(r1)
- CDISABLE
- lwz r4,52(r1)
- lwz r0,12(r1)
- lwz r3,8(r1)
- mtlr r4
- mtcr r0
- addi r1,r1,48
- PSEUDO_RET
-#endif
-PSEUDO_END (__socket)
+ li r3,SYS_ify(socketcall)
+ li r4,P(SOCKOP_,socket)
+ addi r5,r1,STACKBLOCK
+ CANCEL_JUMPTARGET
+ lwz r9,52(r1)
+ addi r1,r1,48
+ cfi_adjust_cfa_offset(-48)
+ mtlr r9
+ cfi_restore(lr)
+ b __syscall_cancel_error@local;
+END (__socket)
#ifndef NO_WEAK_ALIAS
weak_alias (__socket, socket)
@@ -25,89 +25,56 @@
#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+# ifdef NOT_IN_libc
+# define SETUP_PIC \
+ bcl 20,31,got_label; \
+got_label:
+
+# define CANCEL_JUMPTARGET \
+ stw r30,8(r1); \
+ mflr r30; \
+ addis r30,r30,_GLOBAL_OFFSET_TABLE_-got_label@ha; \
+ addi r30,r30,_GLOBAL_OFFSET_TABLE_-got_label@l; \
+ bl __syscall_cancel@plt; \
+ lwz r30,8(r1)
+# else
+# define SETUP_PIC
+# if defined SHARED && defined PIC
+# define CANCEL_JUMPTARGET \
+ bl __GI___syscall_cancel@locaL
+# else
+# define CANCEL_JUMPTARGET \
+ bl __syscall_cancel
+# endif
+# endif
+
# undef PSEUDO
# define PSEUDO(name, syscall_name, args) \
.section ".text"; \
ENTRY (name) \
- SINGLE_THREAD_P; \
- bne- .Lpseudo_cancel; \
- .type __##syscall_name##_nocancel,@function; \
- .globl __##syscall_name##_nocancel; \
- __##syscall_name##_nocancel: \
- DO_CALL (SYS_ify (syscall_name)); \
- PSEUDO_RET; \
- .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \
- .Lpseudo_cancel: \
- stwu 1,-48(1); \
- cfi_adjust_cfa_offset (48); \
- mflr 9; \
- stw 9,52(1); \
+ stwu r1,-16(r1); \
+ cfi_adjust_cfa_offset (16); \
+ mflr r0; \
+ SETUP_PIC; \
+ stw r0,20(r1); \
cfi_offset (lr, 4); \
- DOCARGS_##args; /* save syscall args around CENABLE. */ \
- CENABLE; \
- stw 3,16(1); /* store CENABLE return value (MASK). */ \
- UNDOCARGS_##args; /* restore syscall args. */ \
- DO_CALL (SYS_ify (syscall_name)); \
- mfcr 0; /* save CR/R3 around CDISABLE. */ \
- stw 3,8(1); \
- stw 0,12(1); \
- lwz 3,16(1); /* pass MASK to CDISABLE. */ \
- CDISABLE; \
- lwz 4,52(1); \
- lwz 0,12(1); /* restore CR/R3. */ \
- lwz 3,8(1); \
- mtlr 4; \
- mtcr 0; \
- addi 1,1,48;
-
-# define DOCARGS_0
-# define UNDOCARGS_0
-
-# define DOCARGS_1 stw 3,20(1); DOCARGS_0
-# define UNDOCARGS_1 lwz 3,20(1); UNDOCARGS_0
-
-# define DOCARGS_2 stw 4,24(1); DOCARGS_1
-# define UNDOCARGS_2 lwz 4,24(1); UNDOCARGS_1
-
-# define DOCARGS_3 stw 5,28(1); DOCARGS_2
-# define UNDOCARGS_3 lwz 5,28(1); UNDOCARGS_2
-
-# define DOCARGS_4 stw 6,32(1); DOCARGS_3
-# define UNDOCARGS_4 lwz 6,32(1); UNDOCARGS_3
-
-# define DOCARGS_5 stw 7,36(1); DOCARGS_4
-# define UNDOCARGS_5 lwz 7,36(1); UNDOCARGS_4
-
-# define DOCARGS_6 stw 8,40(1); DOCARGS_5
-# define UNDOCARGS_6 lwz 8,40(1); UNDOCARGS_5
-
-# ifdef IS_IN_libpthread
-# define CENABLE bl __pthread_enable_asynccancel@local
-# define CDISABLE bl __pthread_disable_asynccancel@local
-# elif !defined NOT_IN_libc
-# define CENABLE bl __libc_enable_asynccancel@local
-# define CDISABLE bl __libc_disable_asynccancel@local
-# elif defined IS_IN_librt
-# define CENABLE bl __librt_enable_asynccancel@local
-# define CDISABLE bl __librt_disable_asynccancel@local
-# else
-# error Unsupported library
-# endif
-
-# ifndef __ASSEMBLER__
-# define SINGLE_THREAD_P \
- __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
- header.multiple_threads) == 0, 1)
-# else
-# define SINGLE_THREAD_P \
- lwz 10,MULTIPLE_THREADS_OFFSET(2); \
- cmpwi 10,0
-# endif
-
-#elif !defined __ASSEMBLER__
-
-# define SINGLE_THREAD_P (1)
-# define NO_CANCELLATION 1
+ mr r9,r8; \
+ mr r8,r7; \
+ mr r7,r6; \
+ mr r6,r5; \
+ mr r5,r4; \
+ mr r4,r3; \
+ li r3,SYS_ify (syscall_name); \
+ CANCEL_JUMPTARGET; \
+ lwz r0,20(r1); \
+ addi r1,r1,16; \
+ cfi_adjust_cfa_offset (-16); \
+ mtlr r0; \
+ cfi_restore (lr);
+
+# undef PSEUDO_RET
+# define PSEUDO_RET \
+ b __syscall_cancel_error@local;
#endif
@@ -168,6 +168,14 @@
sc_ret; \
})
+#undef SYSCALL_CANCEL_ERROR
+#define SYSCALL_CANCEL_ERROR(err) \
+ (err > 0xfffffffffffff000UL)
+
+#undef SYSCALL_CANCEL_ERRNO
+#define SYSCALL_CANCEL_ERRNO(err) \
+ (-err)
+
/* Define a macro which expands inline into the wrapper code for a system
call. This use is for internal calls that do not need to handle errors
normally. It will never touch errno.
@@ -53,18 +53,8 @@ PREADV (int fd, const struct iovec *vector, int count, OFF_T offset)
#ifdef __NR_preadv
ssize_t result;
- if (SINGLE_THREAD_P)
- result = INLINE_SYSCALL (preadv, 5, fd, vector, count,
- LO_HI_LONG (offset));
- else
- {
- int oldtype = LIBC_CANCEL_ASYNC ();
-
- result = INLINE_SYSCALL (preadv, 5, fd, vector, count,
- LO_HI_LONG (offset));
-
- LIBC_CANCEL_RESET (oldtype);
- }
+ result = SYSCALL_CANCEL (preadv, fd, vector, count,
+ LO_HI_LONG (offset));
# ifdef __ASSUME_PREADV
return result;
# endif
@@ -53,18 +53,8 @@ PWRITEV (int fd, const struct iovec *vector, int count, OFF_T offset)
#ifdef __NR_pwritev
ssize_t result;
- if (SINGLE_THREAD_P)
- result = INLINE_SYSCALL (pwritev, 5, fd, vector, count,
- LO_HI_LONG (offset));
- else
- {
- int oldtype = LIBC_CANCEL_ASYNC ();
-
- result = INLINE_SYSCALL (pwritev, 5, fd, vector, count,
- LO_HI_LONG (offset));
-
- LIBC_CANCEL_RESET (oldtype);
- }
+ result = INLINE_SYSCALL (pwritev, 5, fd, vector, count,
+ LO_HI_LONG (offset));
# ifdef __ASSUME_PWRITEV
return result;
# endif
@@ -28,43 +28,18 @@
int
sync_file_range (int fd, __off64_t from, __off64_t to, unsigned int flags)
{
- if (SINGLE_THREAD_P)
- return INLINE_SYSCALL (sync_file_range, 6, fd,
- __LONG_LONG_PAIR ((long) (from >> 32), (long) from),
- __LONG_LONG_PAIR ((long) (to >> 32), (long) to),
- flags);
-
- int result;
- int oldtype = LIBC_CANCEL_ASYNC ();
-
- result = INLINE_SYSCALL (sync_file_range, 6, fd,
- __LONG_LONG_PAIR ((long) (from >> 32), (long) from),
- __LONG_LONG_PAIR ((long) (to >> 32), (long) to),
- flags);
-
- LIBC_CANCEL_RESET (oldtype);
-
- return result;
+ return SYSCALL_CANCEL (sync_file_range, fd,
+ __LONG_LONG_PAIR ((long) (from >> 32), (long) from),
+ __LONG_LONG_PAIR ((long) (to >> 32), (long) to),
+ flags);
}
#elif defined __NR_sync_file_range2
int
sync_file_range (int fd, __off64_t from, __off64_t to, unsigned int flags)
{
- if (SINGLE_THREAD_P)
- return INLINE_SYSCALL (sync_file_range2, 6, fd, flags,
- __LONG_LONG_PAIR ((long) (from >> 32), (long) from),
- __LONG_LONG_PAIR ((long) (to >> 32), (long) to));
-
- int result;
- int oldtype = LIBC_CANCEL_ASYNC ();
-
- result = INLINE_SYSCALL (sync_file_range2, 6, fd, flags,
- __LONG_LONG_PAIR ((long) (from >> 32), (long) from),
- __LONG_LONG_PAIR ((long) (to >> 32), (long) to));
-
- LIBC_CANCEL_RESET (oldtype);
-
- return result;
+ return SYSCALL_CANCEL (sync_file_range2, fd, flags,
+ __LONG_LONG_PAIR ((long) (from >> 32), (long) from),
+ __LONG_LONG_PAIR ((long) (to >> 32), (long) to));
}
#else
int