about summary refs log tree commit diff
path: root/sysdeps/unix/sysv/linux
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/unix/sysv/linux')
-rw-r--r--sysdeps/unix/sysv/linux/futimes.c64
-rw-r--r--sysdeps/unix/sysv/linux/i386/clone.S2
-rw-r--r--sysdeps/unix/sysv/linux/i386/sysdep.h33
-rw-r--r--sysdeps/unix/sysv/linux/kernel-features.h5
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S8
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/swapcontext.S8
6 files changed, 92 insertions, 28 deletions
diff --git a/sysdeps/unix/sysv/linux/futimes.c b/sysdeps/unix/sysv/linux/futimes.c
index f43f568ec1..7d79a40aab 100644
--- a/sysdeps/unix/sysv/linux/futimes.c
+++ b/sysdeps/unix/sysv/linux/futimes.c
@@ -23,6 +23,7 @@
 #include <utime.h>
 #include <sys/time.h>
 #include <stdio-common/_itoa.h>
+#include <fcntl.h>
 
 #include "kernel-features.h"
 
@@ -40,31 +41,58 @@ __futimes (int fd, const struct timeval tvp[2])
   char *cp = _itoa_word ((unsigned int) fd, fname + sizeof (fname) - 1, 10, 0);
   cp = memcpy (cp - sizeof (selffd) + 1, selffd, sizeof (selffd) - 1);
 
+  int result;
 #ifdef __NR_utimes
-  int result = INLINE_SYSCALL (utimes, 2, cp, tvp);
+  result = INLINE_SYSCALL (utimes, 2, cp, tvp);
 # ifndef __ASSUME_UTIMES
-  if (result != -1 || errno != ENOSYS)
+  if (result == -1 && errno == ENOSYS)
 # endif
-    return result;
 #endif
-
-  /* The utimes() syscall does not exist or is not available in the
-     used kernel.  Use utime().  For this we have to convert to the
-     data format utime() expects.  */
+    {
+      /* The utimes() syscall does not exist or is not available in the
+	 used kernel.  Use utime().  For this we have to convert to the
+	 data format utime() expects.  */
 #ifndef __ASSUME_UTIMES
-  struct utimbuf buf;
-  struct utimbuf *times;
+      struct utimbuf buf;
+      struct utimbuf *times;
 
-  if (tvp != NULL)
-    {
-      times = &buf;
-      buf.actime = tvp[0].tv_sec + (tvp[0].tv_usec + 500000) / 1000000;
-      buf.modtime = tvp[1].tv_sec + (tvp[1].tv_usec + 500000) / 1000000;
-    }
-  else
-    times = NULL;
+      if (tvp != NULL)
+	{
+	  times = &buf;
+	  buf.actime = tvp[0].tv_sec + (tvp[0].tv_usec + 500000) / 1000000;
+	  buf.modtime = tvp[1].tv_sec + (tvp[1].tv_usec + 500000) / 1000000;
+	}
+      else
+	times = NULL;
 
-  return INLINE_SYSCALL (utime, 2, cp, times);
+      result = INLINE_SYSCALL (utime, 2, cp, times);
 #endif
+    }
+
+  if (result == -1)
+    /* Check for errors that result from failing to find /proc.
+       This means we can't do futimes at all, so return ENOSYS
+       rather than some confusing error.  */
+    switch (errno)
+      {
+      case EACCES:
+	if (tvp == NULL)  /* Could be a path problem or a file problem.  */
+	  break;
+	/*FALLTHROUGH*/
+      case ELOOP:
+      case ENAMETOOLONG:
+      case ENOTDIR:
+	__set_errno (ENOSYS);
+	break;
+
+      case ENOENT:
+	/* Validate the file descriptor by letting fcntl set errno to
+	   EBADF if it's bogus.  Otherwise it's a /proc issue.  */
+	if (INLINE_SYSCALL (fcntl, 3, fd, F_GETFD, 0) != -1)
+	  __set_errno (ENOSYS);
+	break;
+      }
+
+  return result;
 }
 weak_alias (__futimes, futimes)
diff --git a/sysdeps/unix/sysv/linux/i386/clone.S b/sysdeps/unix/sysv/linux/i386/clone.S
index acd43dfb0b..c7d31f7a32 100644
--- a/sysdeps/unix/sysv/linux/i386/clone.S
+++ b/sysdeps/unix/sysv/linux/i386/clone.S
@@ -67,7 +67,7 @@ ENTRY (BP_SYM (__clone))
 	/* Insert the argument onto the new stack.  Make sure the new
 	   thread is started with an alignment of (mod 16).  */
 	andl	$0xfffffff0, %ecx
-	subl	$24,%ecx
+	subl	$28,%ecx
 	movl	ARG(%esp),%eax		/* no negative argument counts */
 	movl	%eax,12(%ecx)
 
diff --git a/sysdeps/unix/sysv/linux/i386/sysdep.h b/sysdeps/unix/sysv/linux/i386/sysdep.h
index af75d4c51a..b91af4007c 100644
--- a/sysdeps/unix/sysv/linux/i386/sysdep.h
+++ b/sysdeps/unix/sysv/linux/i386/sysdep.h
@@ -154,9 +154,17 @@ __i686.get_pc_thunk.reg:						      \
   movl SYSCALL_ERROR_ERRNO@GOTNTPOFF(%ecx), %ecx;			      \
   xorl %edx, %edx;							      \
   subl %eax, %edx;							      \
-  movl %edx, %gs:0(%ecx);						      \
+  SYSCALL_ERROR_HANDLER_TLS_STORE (%edx, %ecx);				      \
   orl $-1, %eax;							      \
   jmp L(pseudo_end);
+#   ifndef NO_TLS_DIRECT_SEG_REFS
+#    define SYSCALL_ERROR_HANDLER_TLS_STORE(src, destoff)		      \
+  movl src, %gs:(destoff)
+#   else
+#    define SYSCALL_ERROR_HANDLER_TLS_STORE(src, destoff)		      \
+  addl %gs:0, destoff;							      \
+  movl src, (destoff)
+#   endif
 #  else
 #   define SYSCALL_ERROR_HANDLER					      \
 0:pushl %ebx;								      \
@@ -532,6 +540,29 @@ asm (".L__X'%ebx = 1\n\t"
 # define EXTRAVAR_5
 #endif
 
+/* Consistency check for position-independent code.  */
+#ifdef __PIC__
+# define check_consistency()						      \
+  ({ int __res;								      \
+     __asm__ __volatile__						      \
+       ("call __i686.get_pc_thunk.cx;"					      \
+	"addl $_GLOBAL_OFFSET_TABLE_, %%ecx;"				      \
+	"subl %%ebx, %%ecx;"						      \
+	"je 1f;"							      \
+	"ud2;"								      \
+	"1:\n"								      \
+	".section .gnu.linkonce.t.__i686.get_pc_thunk.cx,\"ax\",@progbits;"   \
+	".globl __i686.get_pc_thunk.cx;"				      \
+	".hidden __i686.get_pc_thunk.cx;"				      \
+	".type __i686.get_pc_thunk.cx,@function;"			      \
+	"__i686.get_pc_thunk.cx:"					      \
+	"movl (%%esp), %%ecx;"						      \
+	"ret;"								      \
+	".previous"							      \
+	: "=c" (__res));						      \
+     __res; })
+#endif
+
 #endif	/* __ASSEMBLER__ */
 
 #endif /* linux/i386/sysdep.h */
diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h
index f499a712c4..88850cfeac 100644
--- a/sysdeps/unix/sysv/linux/kernel-features.h
+++ b/sysdeps/unix/sysv/linux/kernel-features.h
@@ -79,6 +79,11 @@
 # define __ASSUME_SIOCGIFNAME		1
 #endif
 
+/* MSG_NOSIGNAL was at least available with Linux 2.2.0.  */
+#if __LINUX_KERNEL_VERSION >= 131584
+# define __ASSUME_MSG_NOSIGNAL		1
+#endif
+
 /* On x86 another `getrlimit' syscall was added in 2.3.25.  */
 #if __LINUX_KERNEL_VERSION >= 131865 && defined __i386__
 # define __ASSUME_NEW_GETRLIMIT_SYSCALL	1
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S b/sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S
index 6514f442a6..bdb9473429 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S
@@ -47,7 +47,7 @@ ENTRY(__novec_setcontext)
  * of a procedure call (makecontext), so we don't need to restore
  * msr and ctr.  We don't restore r13 since it will be used as
  * the TLS pointer.  */
-  lwz	  r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r31)
+  ld	  r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r31)
   cmpdi r0,0
   bne	  L(nv_do_sigret)
 
@@ -104,7 +104,7 @@ ENTRY(__novec_setcontext)
   ld   r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r31)
   ld   r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r31)
   ld   r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r31)
-  mfcr r0
+  mtcr r0
   ld   r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r31)
   ld   r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r31)
   ld   r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r31)
@@ -213,7 +213,7 @@ ENTRY(__setcontext)
  * of a procedure call (makecontext), so we don't need to restore
  * msr and ctr.  We don't restore r13 since it will be used as
  * the TLS pointer.  */
-  lwz	  r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r31)
+  ld	  r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r31)
   cmpdi r0,0
   bne	  L(do_sigret)
 
@@ -380,11 +380,11 @@ L(has_no_vec):
   ld   r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r31)
   ld   r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r31)
   ld   r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r31)
-  mfcr r0
   ld   r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r31)
   ld   r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r31)
   ld   r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r31)
   ld   r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r31)
+  mtcr r0
   ld   r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r31)
   ld   r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r31)
   ld   r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r31)
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/swapcontext.S b/sysdeps/unix/sysv/linux/powerpc/powerpc64/swapcontext.S
index f99df951a2..0a4bac58b5 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/swapcontext.S
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/swapcontext.S
@@ -150,7 +150,7 @@ ENTRY(__novec_swapcontext)
  * of a procedure call (makecontext), so we don't need to restore
  * msr and ctr.  We don't restore r13 since it will be used as
  * the TLS pointer.  */
-  lwz	  r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r31)
+  ld	  r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r31)
   cmpdi r0,0
   bne	  L(nv_do_sigret)
 
@@ -199,7 +199,7 @@ ENTRY(__novec_swapcontext)
   ld   r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r31)
   ld   r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r31)
   ld   r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r31)
-  mfcr r0
+  mtcr r0
   ld   r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r31)
   ld   r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r31)
   ld   r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r31)
@@ -521,7 +521,7 @@ L(has_no_vec):
  * of a procedure call (makecontext), so we don't need to restore
  * msr and ctr.  We don't restore r13 since it will be used as
  * the TLS pointer.  */
-  lwz	  r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r31)
+  ld	  r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r31)
   cmpdi r0,0
   bne	  L(do_sigret)
 
@@ -681,11 +681,11 @@ L(has_no_vec2):
   ld   r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r31)
   ld   r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r31)
   ld   r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r31)
-  mfcr r0
   ld   r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r31)
   ld   r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r31)
   ld   r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r31)
   ld   r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r31)
+  mtcr r0
   ld   r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r31)
   ld   r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r31)
   ld   r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r31)