summary refs log tree commit diff
path: root/sysdeps
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/generic/dl-cache.h8
-rw-r--r--sysdeps/i386/Makefile10
-rw-r--r--sysdeps/ia64/Makefile4
-rw-r--r--sysdeps/ia64/ia64libgcc.S350
-rw-r--r--sysdeps/ia64/libgcc-compat.c84
-rw-r--r--sysdeps/powerpc/powerpc64/Makefile1
-rw-r--r--sysdeps/unix/nice.c7
-rw-r--r--sysdeps/unix/sysv/linux/check_pf.c5
-rw-r--r--sysdeps/unix/sysv/linux/dl-osinfo.h29
-rw-r--r--sysdeps/unix/sysv/linux/futimesat.c23
-rw-r--r--sysdeps/unix/sysv/linux/i386/dl-cache.h59
-rw-r--r--sysdeps/unix/sysv/linux/ia64/dl-cache.h27
-rw-r--r--sysdeps/unix/sysv/linux/ia64/dl-procinfo.c5
-rw-r--r--sysdeps/unix/sysv/linux/ia64/dl-procinfo.h5
-rw-r--r--sysdeps/unix/sysv/linux/ia64/ldd-rewrite.sed2
-rw-r--r--sysdeps/unix/sysv/linux/netlinkaccess.h18
-rw-r--r--sysdeps/unix/sysv/linux/paths.h2
-rw-r--r--sysdeps/unix/sysv/linux/tcsetattr.c32
18 files changed, 292 insertions, 379 deletions
diff --git a/sysdeps/generic/dl-cache.h b/sysdeps/generic/dl-cache.h
index c2b72874cf..7cc02d993b 100644
--- a/sysdeps/generic/dl-cache.h
+++ b/sysdeps/generic/dl-cache.h
@@ -36,6 +36,14 @@
 # define add_system_dir(dir) add_dir (dir)
 #endif
 
+#ifndef arch_startup
+# define arch_startup(argc, argv) do { } while (0)
+#endif
+
+#ifndef add_arch_dirs
+# define add_arch_dirs(config_file) do { } while (0)
+#endif
+
 #define CACHEMAGIC "ld.so-1.7.0"
 
 /* libc5 and glibc 2.0/2.1 use the same format.  For glibc 2.2 another
diff --git a/sysdeps/i386/Makefile b/sysdeps/i386/Makefile
index ef45ce6e78..8cac74a6ae 100644
--- a/sysdeps/i386/Makefile
+++ b/sysdeps/i386/Makefile
@@ -2,6 +2,8 @@
 # Every i386 port in use uses gas syntax (I think).
 asm-CPPFLAGS += -DGAS_SYNTAX
 
+sysdep-ASFLAGS += -U__i686
+
 # The i386 `long double' is a distinct type we support.
 long-double-fcts = yes
 
@@ -64,6 +66,14 @@ endif
 
 ifneq (,$(filter -mno-tls-direct-seg-refs,$(CFLAGS)))
 defines += -DNO_TLS_DIRECT_SEG_REFS
+else
+# .a libraries are not performance critical and so we
+# build them without direct TLS segment references
+# always.
+CPPFLAGS-.o += -DNO_TLS_DIRECT_SEG_REFS
+CFLAGS-.o += -mno-tls-direct-seg-refs
+CPPFLAGS-.oS += -DNO_TLS_DIRECT_SEG_REFS
+CFLAGS-.oS += -mno-tls-direct-seg-refs
 endif
 
 ifeq ($(subdir),elf)
diff --git a/sysdeps/ia64/Makefile b/sysdeps/ia64/Makefile
index 2ea937ac9e..bf43c96144 100644
--- a/sysdeps/ia64/Makefile
+++ b/sysdeps/ia64/Makefile
@@ -12,8 +12,8 @@ elide-routines.os += hp-timing
 
 ifeq (yes,$(build-shared))
 # Compatibility
-sysdep_routines += ia64libgcc
-shared-only-routines += ia64libgcc
+sysdep_routines += libgcc-compat
+shared-only-routines += libgcc-compat
 endif
 endif
 
diff --git a/sysdeps/ia64/ia64libgcc.S b/sysdeps/ia64/ia64libgcc.S
index 3f77b06a5a..e69de29bb2 100644
--- a/sysdeps/ia64/ia64libgcc.S
+++ b/sysdeps/ia64/ia64libgcc.S
@@ -1,350 +0,0 @@
-/* From the Intel IA-64 Optimization Guide, choose the minimum latency
-   alternative.  */
-
-#include <sysdep.h>
-#undef ret
-
-#include <shlib-compat.h>
-
-#if SHLIB_COMPAT(libc, GLIBC_2_2, GLIBC_2_2_6)
-
-/* __divtf3
-   Compute a 80-bit IEEE double-extended quotient.
-   farg0 holds the dividend.  farg1 holds the divisor.  */
-
-ENTRY(___divtf3)
-	cmp.eq p7, p0 = r0, r0
-	frcpa.s0 f10, p6 = farg0, farg1
-	;;
-(p6)	cmp.ne p7, p0 = r0, r0
-	.pred.rel.mutex p6, p7
-(p6)	fnma.s1 f11 = farg1, f10, f1
-(p6)	fma.s1 f12 = farg0, f10, f0
-	;;
-(p6)	fma.s1 f13 = f11, f11, f0
-(p6)	fma.s1 f14 = f11, f11, f11
-	;;
-(p6)	fma.s1 f11 = f13, f13, f11
-(p6)	fma.s1 f13 = f14, f10, f10
-	;;
-(p6)	fma.s1 f10 = f13, f11, f10
-(p6)	fnma.s1 f11 = farg1, f12, farg0
-	;;
-(p6)	fma.s1 f11 = f11, f10, f12
-(p6)	fnma.s1 f12 = farg1, f10, f1
-	;;
-(p6)	fma.s1 f10 = f12, f10, f10
-(p6)	fnma.s1 f12 = farg1, f11, farg0
-	;;
-(p6)	fma.s0 fret0 = f12, f10, f11
-(p7)	mov fret0 = f10
-	br.ret.sptk rp
-END(___divtf3)
-	.symver ___divtf3, __divtf3@GLIBC_2.2
-
-/* __divdf3
-   Compute a 64-bit IEEE double quotient.
-   farg0 holds the dividend.  farg1 holds the divisor.  */
-
-ENTRY(___divdf3)
-	cmp.eq p7, p0 = r0, r0
-	frcpa.s0 f10, p6 = farg0, farg1
-	;;
-(p6)	cmp.ne p7, p0 = r0, r0
-	.pred.rel.mutex p6, p7
-(p6)	fmpy.s1 f11 = farg0, f10
-(p6)	fnma.s1 f12 = farg1, f10, f1
-	;;
-(p6)	fma.s1 f11 = f12, f11, f11
-(p6)	fmpy.s1 f13 = f12, f12
-	;;
-(p6)	fma.s1 f10 = f12, f10, f10
-(p6)	fma.s1 f11 = f13, f11, f11
-	;;
-(p6)	fmpy.s1 f12 = f13, f13
-(p6)	fma.s1 f10 = f13, f10, f10
-	;;
-(p6)	fma.d.s1 f11 = f12, f11, f11
-(p6)	fma.s1 f10 = f12, f10, f10
-	;;
-(p6)	fnma.d.s1 f8 = farg1, f11, farg0
-	;;
-(p6)	fma.d fret0 = f8, f10, f11
-(p7)	mov fret0 = f10
-	br.ret.sptk rp
-	;;
-END(___divdf3)
-	.symver	___divdf3, __divdf3@GLIBC_2.2
-
-/* __divsf3
-   Compute a 32-bit IEEE float quotient.
-   farg0 holds the dividend.  farg1 holds the divisor.  */
-
-ENTRY(___divsf3)
-	cmp.eq p7, p0 = r0, r0
-	frcpa.s0 f10, p6 = farg0, farg1
-	;;
-(p6)	cmp.ne p7, p0 = r0, r0
-	.pred.rel.mutex p6, p7
-(p6)	fmpy.s1 f8 = farg0, f10
-(p6)	fnma.s1 f9 = farg1, f10, f1
-	;;
-(p6)	fma.s1 f8 = f9, f8, f8
-(p6)	fmpy.s1 f9 = f9, f9
-	;;
-(p6)	fma.s1 f8 = f9, f8, f8
-(p6)	fmpy.s1 f9 = f9, f9
-	;;
-(p6)	fma.d.s1 f10 = f9, f8, f8
-	;;
-(p6)	fnorm.s.s0 fret0 = f10
-(p7)	mov fret0 = f10
-	br.ret.sptk rp
-	;;
-END(___divsf3)
-	.symver	___divsf3, __divsf3@GLIBC_2.2
-
-/* __divdi3
-   Compute a 64-bit integer quotient.
-   in0 holds the dividend.  in1 holds the divisor.  */
-
-ENTRY(___divdi3)
-	.regstk 2,0,0,0
-	/* Transfer inputs to FP registers.  */
-	setf.sig f8 = in0
-	setf.sig f9 = in1
-	;;
-	/* Convert the inputs to FP, so that they won't be treated as
-	   unsigned.  */
-	fcvt.xf f8 = f8
-	fcvt.xf f9 = f9
-	;;
-	/* Compute the reciprocal approximation.  */
-	frcpa.s1 f10, p6 = f8, f9
-	;;
-	/* 3 Newton-Raphson iterations.  */
-(p6)	fnma.s1 f11 = f9, f10, f1
-(p6)	fmpy.s1 f12 = f8, f10
-	;;
-(p6)	fmpy.s1 f13 = f11, f11
-(p6)	fma.s1 f12 = f11, f12, f12
-	;;
-(p6)	fma.s1 f10 = f11, f10, f10
-(p6)	fma.s1 f11 = f13, f12, f12
-	;;
-(p6)	fma.s1 f10 = f13, f10, f10
-(p6)	fnma.s1 f12 = f9, f11, f8
-	;;
-(p6)	fma.s1 f10 = f12, f10, f11
-	;;
-	/* Round quotient to an integer.  */
-	fcvt.fx.trunc.s1 f10 = f10
-	;;
-	/* Transfer result to GP registers.  */
-	getf.sig ret0 = f10
-	br.ret.sptk rp
-	;;
-END(___divdi3)
-	.symver	___divdi3, __divdi3@GLIBC_2.2
-
-/* __moddi3
-   Compute a 64-bit integer modulus.
-   in0 holds the dividend (a).  in1 holds the divisor (b).  */
-
-ENTRY(___moddi3)
-	.regstk 2,0,0,0
-	/* Transfer inputs to FP registers.  */
-	setf.sig f14 = in0
-	setf.sig f9 = in1
-	;;
-	/* Convert the inputs to FP, so that they won't be treated as
-	   unsigned.  */
-	fcvt.xf f8 = f14
-	fcvt.xf f9 = f9
-	;;
-	/* Compute the reciprocal approximation.  */
-	frcpa.s1 f10, p6 = f8, f9
-	;;
-	/* 3 Newton-Raphson iterations.  */
-(p6)	fmpy.s1 f12 = f8, f10
-(p6)	fnma.s1 f11 = f9, f10, f1
-	;;
-(p6)	fma.s1 f12 = f11, f12, f12
-(p6)	fmpy.s1 f13 = f11, f11
-	;;
-(p6)	fma.s1 f10 = f11, f10, f10
-(p6)	fma.s1 f11 = f13, f12, f12
-	;;
-	sub in1 = r0, in1
-(p6)	fma.s1 f10 = f13, f10, f10
-(p6)	fnma.s1 f12 = f9, f11, f8
-	;;
-	setf.sig f9 = in1
-(p6)	fma.s1 f10 = f12, f10, f11
-	;;
-	fcvt.fx.trunc.s1 f10 = f10
-	;;
-	/* r = q * (-b) + a  */
-	xma.l f10 = f10, f9, f14
-	;;
-	/* Transfer result to GP registers.  */
-	getf.sig ret0 = f10
-	br.ret.sptk rp
-	;;
-END(___moddi3)
-	.symver ___moddi3, __moddi3@GLIBC_2.2
-
-/* __udivdi3
-   Compute a 64-bit unsigned integer quotient.
-   in0 holds the dividend.  in1 holds the divisor.  */
-
-ENTRY(___udivdi3)
-	.regstk 2,0,0,0
-	/* Transfer inputs to FP registers.  */
-	setf.sig f8 = in0
-	setf.sig f9 = in1
-	;;
-	/* Convert the inputs to FP, to avoid FP software-assist faults.  */
-	fcvt.xuf.s1 f8 = f8
-	fcvt.xuf.s1 f9 = f9
-	;;
-	/* Compute the reciprocal approximation.  */
-	frcpa.s1 f10, p6 = f8, f9
-	;;
-	/* 3 Newton-Raphson iterations.  */
-(p6)	fnma.s1 f11 = f9, f10, f1
-(p6)	fmpy.s1 f12 = f8, f10
-	;;
-(p6)	fmpy.s1 f13 = f11, f11
-(p6)	fma.s1 f12 = f11, f12, f12
-	;;
-(p6)	fma.s1 f10 = f11, f10, f10
-(p6)	fma.s1 f11 = f13, f12, f12
-	;;
-(p6)	fma.s1 f10 = f13, f10, f10
-(p6)	fnma.s1 f12 = f9, f11, f8
-	;;
-(p6)	fma.s1 f10 = f12, f10, f11
-	;;
-	/* Round quotient to an unsigned integer.  */
-	fcvt.fxu.trunc.s1 f10 = f10
-	;;
-	/* Transfer result to GP registers.  */
-	getf.sig ret0 = f10
-	br.ret.sptk rp
-	;;
-END(___udivdi3)
-	.symver	___udivdi3, __udivdi3@GLIBC_2.2
-
-/* __umoddi3
-   Compute a 64-bit unsigned integer modulus.
-   in0 holds the dividend (a).  in1 holds the divisor (b).  */
-
-ENTRY(___umoddi3)
-	.regstk 2,0,0,0
-	/* Transfer inputs to FP registers.  */
-	setf.sig f14 = in0
-	setf.sig f9 = in1
-	;;
-	/* Convert the inputs to FP, to avoid FP software assist faults.  */
-	fcvt.xuf.s1 f8 = f14
-	fcvt.xuf.s1 f9 = f9
-	;;
-	/* Compute the reciprocal approximation.  */
-	frcpa.s1 f10, p6 = f8, f9
-	;;
-	/* 3 Newton-Raphson iterations.  */
-(p6)	fmpy.s1 f12 = f8, f10
-(p6)	fnma.s1 f11 = f9, f10, f1
-	;;
-(p6)	fma.s1 f12 = f11, f12, f12
-(p6)	fmpy.s1 f13 = f11, f11
-	;;
-(p6)	fma.s1 f10 = f11, f10, f10
-(p6)	fma.s1 f11 = f13, f12, f12
-	;;
-	sub in1 = r0, in1
-(p6)	fma.s1 f10 = f13, f10, f10
-(p6)	fnma.s1 f12 = f9, f11, f8
-	;;
-	setf.sig f9 = in1
-(p6)	fma.s1 f10 = f12, f10, f11
-	;;
-	/* Round quotient to an unsigned integer.  */
-	fcvt.fxu.trunc.s1 f10 = f10
-	;;
-	/* r = q * (-b) + a  */
-	xma.l f10 = f10, f9, f14
-	;;
-	/* Transfer result to GP registers.  */
-	getf.sig ret0 = f10
-	br.ret.sptk rp
-	;;
-END(___umoddi3)
-	.symver	___umoddi3, __umoddi3@GLIBC_2.2
-
-/* __multi3
-   Compute a 128-bit multiply of 128-bit multiplicands.
-   in0/in1 holds one multiplicand (a), in2/in3 holds the other one (b).  */
-
-ENTRY(___multi3)
-	.regstk 4,0,0,0
-	setf.sig f6 = in1
-	movl r19 = 0xffffffff
-	setf.sig f7 = in2
-	;;
-	and r14 = r19, in0
-	;;
-	setf.sig f10 = r14
-	and r14 = r19, in2
-	xmpy.l f9 = f6, f7
-	;;
-	setf.sig f6 = r14
-	shr.u r14 = in0, 32
-	;;
-	setf.sig f7 = r14
-	shr.u r14 = in2, 32
-	;;
-	setf.sig f8 = r14
-	xmpy.l f11 = f10, f6
-	xmpy.l f6 = f7, f6
-	;;
-	getf.sig r16 = f11
-	xmpy.l f7 = f7, f8
-	;;
-	shr.u r14 = r16, 32
-	and r16 = r19, r16
-	getf.sig r17 = f6
-	setf.sig f6 = in0
-	;;
-	setf.sig f11 = r14
-	getf.sig r21 = f7
-	setf.sig f7 = in3
-	;;
-	xma.l f11 = f10, f8, f11
-	xma.l f6 = f6, f7, f9
-	;;
-	getf.sig r18 = f11
-	;;
-	add r18 = r18, r17
-	;;
-	and r15 = r19, r18
-	cmp.ltu p7, p6 = r18, r17
-	;;
-	getf.sig r22 = f6
-(p7)	adds r14 = 1, r19
-	;;
-(p7)	add r21 = r21, r14
-	shr.u r14 = r18, 32
-	shl r15 = r15, 32
-	;;
-	add r20 = r21, r14
-	;;
-	add ret0 = r15, r16
-	add ret1 = r22, r20
-	br.ret.sptk rp
-	;;
-END(___multi3)
-	.symver	___multi3, __multi3@GLIBC_2.2
-
-#endif
diff --git a/sysdeps/ia64/libgcc-compat.c b/sysdeps/ia64/libgcc-compat.c
new file mode 100644
index 0000000000..0be489757f
--- /dev/null
+++ b/sysdeps/ia64/libgcc-compat.c
@@ -0,0 +1,84 @@
+/* pre-.hidden libgcc compatibility
+   Copyright (C) 2002 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 <stdint.h>
+#include <shlib-compat.h>
+
+#if SHLIB_COMPAT(libc, GLIBC_2_2, GLIBC_2_2_6)
+
+typedef int int128_t __attribute__((__mode__(TI)));
+
+extern long double __divtf3 (long double, long double) attribute_hidden;
+long double INTUSE (__divtf3) (long double x, long double y)
+{
+  return __divtf3 (x, y);
+}
+symbol_version (INTUSE (__divtf3), __divtf3, GLIBC_2.2);
+
+extern double __divdf3 (double, double) attribute_hidden;
+double INTUSE (__divdf3) (double x, double y)
+{
+  return __divdf3 (x, y);
+}
+symbol_version (INTUSE (__divdf3), __divdf3, GLIBC_2.2);
+
+extern float __divsf3 (float, float) attribute_hidden;
+float INTUSE (__divsf3) (float x, float y)
+{
+  return __divsf3 (x, y);
+}
+symbol_version (INTUSE (__divsf3), __divsf3, GLIBC_2.2);
+
+extern int64_t __divdi3 (int64_t, int64_t) attribute_hidden;
+int64_t INTUSE (__divdi3) (int64_t x, int64_t y)
+{
+  return __divdi3 (x, y);
+}
+symbol_version (INTUSE (__divdi3), __divdi3, GLIBC_2.2);
+
+extern int64_t __moddi3 (int64_t, int64_t) attribute_hidden;
+int64_t INTUSE (__moddi3) (int64_t x, int64_t y)
+{
+  return __moddi3 (x, y);
+}
+symbol_version (INTUSE (__moddi3), __moddi3, GLIBC_2.2);
+
+extern uint64_t __udivdi3 (uint64_t, uint64_t) attribute_hidden;
+uint64_t INTUSE (__udivdi3) (uint64_t x, uint64_t y)
+{
+  return __udivdi3 (x, y);
+}
+symbol_version (INTUSE (__udivdi3), __udivdi3, GLIBC_2.2);
+
+extern uint64_t __umoddi3 (uint64_t, uint64_t) attribute_hidden;
+uint64_t INTUSE (__umoddi3) (uint64_t x, uint64_t y)
+{
+  return __umoddi3 (x, y);
+}
+symbol_version (INTUSE (__umoddi3), __umoddi3, GLIBC_2.2);
+
+extern int128_t __multi3 (int128_t, int128_t) attribute_hidden;
+int128_t INTUSE (__multi3) (int128_t x, int128_t y)
+{
+  return __multi3 (x, y);
+}
+symbol_version (INTUSE (__multi3), __multi3, GLIBC_2.2);
+
+#endif
diff --git a/sysdeps/powerpc/powerpc64/Makefile b/sysdeps/powerpc/powerpc64/Makefile
index 78d4f07e57..6396e301de 100644
--- a/sysdeps/powerpc/powerpc64/Makefile
+++ b/sysdeps/powerpc/powerpc64/Makefile
@@ -30,6 +30,7 @@ ifneq ($(elf),no)
 # we use -fpic instead which is much better.
 CFLAGS-initfini.s += -fpic -O1
 endif
+CFLAGS-libc-start.c += -fno-asynchronous-unwind-tables
 endif
 
 ifeq ($(subdir),elf)
diff --git a/sysdeps/unix/nice.c b/sysdeps/unix/nice.c
index eb26c43a60..6e75b0327b 100644
--- a/sysdeps/unix/nice.c
+++ b/sysdeps/unix/nice.c
@@ -42,7 +42,12 @@ nice (int incr)
 	__set_errno (save);
     }
 
-  result = setpriority (PRIO_PROCESS, 0, prio + incr);
+  prio += incr;
+  if (prio < PRIO_MIN)
+    prio = PRIO_MIN;
+  else if (prio >= PRIO_MAX)
+    prio = PRIO_MAX - 1;
+  result = setpriority (PRIO_PROCESS, 0, prio);
   if (result == -1)
     {
       if (errno == EACCES)
diff --git a/sysdeps/unix/sysv/linux/check_pf.c b/sysdeps/unix/sysv/linux/check_pf.c
index e694342998..586f1cb169 100644
--- a/sysdeps/unix/sysv/linux/check_pf.c
+++ b/sysdeps/unix/sysv/linux/check_pf.c
@@ -27,13 +27,10 @@
 #include <unistd.h>
 #include <sys/socket.h>
 
-#include <asm/types.h>
-#include <linux/netlink.h>
-#include <linux/rtnetlink.h>
-
 #include <not-cancel.h>
 #include <kernel-features.h>
 
+#include "netlinkaccess.h"
 
 #ifndef IFA_F_HOMEADDRESS
 # define IFA_F_HOMEADDRESS 0
diff --git a/sysdeps/unix/sysv/linux/dl-osinfo.h b/sysdeps/unix/sysv/linux/dl-osinfo.h
index df07869bc5..430166a578 100644
--- a/sysdeps/unix/sysv/linux/dl-osinfo.h
+++ b/sysdeps/unix/sysv/linux/dl-osinfo.h
@@ -17,10 +17,13 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
+#include <errno.h>
 #include <kernel-features.h>
 #include <dl-sysdep.h>
 #include <fcntl.h>
 #include <stdint.h>
+#include <hp-timing.h>
+#include <endian.h>
 
 #ifndef MIN
 # define MIN(a,b) (((a)<(b))?(a):(b))
@@ -80,6 +83,32 @@ _dl_setup_stack_chk_guard (void *dl_random)
       unsigned char *p = (unsigned char *) &ret;
       p[sizeof (ret) - 1] = 255;
       p[sizeof (ret) - 2] = '\n';
+#ifdef HP_TIMING_NOW
+      hp_timing_t hpt;
+      HP_TIMING_NOW (hpt);
+      hpt = (hpt & 0xffff) << 8;
+      ret ^= hpt;
+#endif
+      uintptr_t stk;
+      /* Avoid GCC being too smart.  */
+      asm ("" : "=r" (stk) : "r" (p));
+      stk &= 0x7ffff0;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+      stk <<= (__WORDSIZE - 23);
+#elif __WORDSIZE == 64
+      stk <<= 31;
+#endif
+      ret ^= stk;
+      /* Avoid GCC being too smart.  */
+      p = (unsigned char *) &errno;
+      asm ("" : "=r" (stk) : "r" (p));
+      stk &= 0x7fff00;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+      stk <<= (__WORDSIZE - 29);
+#else
+      stk >>= 8;
+#endif
+      ret ^= stk;
     }
   else
 #endif
diff --git a/sysdeps/unix/sysv/linux/futimesat.c b/sysdeps/unix/sysv/linux/futimesat.c
index bb83e74faf..8292533afb 100644
--- a/sysdeps/unix/sysv/linux/futimesat.c
+++ b/sysdeps/unix/sysv/linux/futimesat.c
@@ -37,14 +37,14 @@ futimesat (fd, file, tvp)
 {
   int result;
 
+  if (file == NULL)
+    return __futimes (fd, tvp);
+
 #ifdef __NR_futimesat
 # ifndef __ASSUME_ATFCTS
   if (__have_atfcts >= 0)
 # endif
     {
-      if (file == NULL)
-	return __futimes (fd, tvp);
-
       result = INLINE_SYSCALL (futimesat, 3, fd, file, tvp);
 # ifndef __ASSUME_ATFCTS
       if (result == -1 && errno == ENOSYS)
@@ -58,22 +58,7 @@ futimesat (fd, file, tvp)
 #ifndef __ASSUME_ATFCTS
   char *buf = NULL;
 
-  if (file == NULL)
-    {
-      static const char procfd[] = "/proc/self/fd/%d";
-      /* Buffer for the path name we are going to use.  It consists of
-	 - the string /proc/self/fd/
-	 - the file descriptor number.
-	 The final NUL is included in the sizeof.   A bit of overhead
-	 due to the format elements compensates for possible negative
-	 numbers.  */
-      size_t buflen = sizeof (procfd) + sizeof (int) * 3;
-      buf = alloca (buflen);
-
-      __snprintf (buf, buflen, procfd, fd);
-      file = buf;
-    }
-  else if (fd != AT_FDCWD && file[0] != '/')
+  if (fd != AT_FDCWD && file[0] != '/')
     {
       size_t filelen = strlen (file);
       if (__builtin_expect (filelen == 0, 0))
diff --git a/sysdeps/unix/sysv/linux/i386/dl-cache.h b/sysdeps/unix/sysv/linux/i386/dl-cache.h
new file mode 100644
index 0000000000..38a1c7dfb4
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/dl-cache.h
@@ -0,0 +1,59 @@
+/* Support for reading /etc/ld.so.cache files written by Linux ldconfig.
+   Copyright (C) 2004 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.  */
+
+static inline int
+is_ia64 (void)
+{
+  unsigned int fl1, fl2;
+
+  /* See if we can use cpuid.  */
+  __asm__ ("pushfl; pushfl; popl %0; movl %0,%1; xorl %2,%0;"
+           "pushl %0; popfl; pushfl; popl %0; popfl"
+           : "=&r" (fl1), "=&r" (fl2)
+           : "i" (0x00200000));
+  if (((fl1 ^ fl2) & 0x00200000) == 0)
+    return 0;
+
+  /* Host supports cpuid.  See if cpuid gives capabilities, try
+     CPUID(0).  Preserve %ebx and %ecx; cpuid insn clobbers these, we
+     don't need their CPUID values here, and %ebx may be the PIC
+     register.  */
+  __asm__ ("pushl %%ecx; pushl %%ebx; cpuid; popl %%ebx; popl %%ecx"
+           : "=a" (fl1) : "0" (0) : "edx", "cc");
+  if (fl1 == 0)
+    return 0;
+
+  /* Invoke CPUID(1), return %edx; caller can examine bits to
+     determine what's supported.  */
+  __asm__ ("pushl %%ecx; pushl %%ebx; cpuid; popl %%ebx; popl %%ecx"
+           : "=d" (fl2), "=a" (fl1) : "1" (1) : "cc");
+  return (fl2 & (1 << 30)) != 0;
+}
+
+#define arch_startup(argc, argv) \
+  do {									\
+    /* On IA-64, try to execute 64-bit ldconfig if possible.		\
+       This is because the badly designed /emul/ia32-linux hack		\
+       will cause 32-bit ldconfig to do all sorts of weird things.  */	\
+    if (is_ia64 ())							\
+      execv ("/emul/ia32-linux/../../sbin/ldconfig",			\
+	     (char *const *) argv);					\
+  } while (0)
+
+#include_next <dl-cache.h>
diff --git a/sysdeps/unix/sysv/linux/ia64/dl-cache.h b/sysdeps/unix/sysv/linux/ia64/dl-cache.h
index b8e2790589..c2165706c0 100644
--- a/sysdeps/unix/sysv/linux/ia64/dl-cache.h
+++ b/sysdeps/unix/sysv/linux/ia64/dl-cache.h
@@ -22,4 +22,31 @@
 #define _dl_cache_check_flags(flags) \
   ((flags) == _DL_CACHE_DEFAULT_ID)
 
+#define EMUL_HACK "/emul/ia32-linux"
+
+#define arch_startup(argc, argv) unlink (EMUL_HACK LD_SO_CACHE)
+
+#define add_arch_dirs(config_file) \
+  do {							\
+    int save_verbose = opt_verbose;			\
+    opt_verbose = 0;					\
+							\
+    parse_conf (config_file, EMUL_HACK, true);		\
+							\
+    /* Always add the standard search paths.  */	\
+    add_system_dir (EMUL_HACK SLIBDIR);			\
+    if (strcmp (SLIBDIR, LIBDIR))			\
+      add_system_dir (EMUL_HACK LIBDIR);		\
+							\
+    char emul_config_file[strlen (config_file)		\
+			  + sizeof EMUL_HACK];		\
+    strcpy (mempcpy (emul_config_file, EMUL_HACK,	\
+		     strlen (EMUL_HACK)), config_file);	\
+							\
+    if (! access (emul_config_file, R_OK))		\
+      parse_conf (emul_config_file, EMUL_HACK, true);	\
+							\
+    opt_verbose = save_verbose;				\
+  } while (0)
+
 #include_next <dl-cache.h>
diff --git a/sysdeps/unix/sysv/linux/ia64/dl-procinfo.c b/sysdeps/unix/sysv/linux/ia64/dl-procinfo.c
new file mode 100644
index 0000000000..7e26fecb3a
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/ia64/dl-procinfo.c
@@ -0,0 +1,5 @@
+#ifdef IS_IN_ldconfig
+#include <sysdeps/i386/dl-procinfo.c>
+#else
+#include <sysdeps/generic/dl-procinfo.c>
+#endif
diff --git a/sysdeps/unix/sysv/linux/ia64/dl-procinfo.h b/sysdeps/unix/sysv/linux/ia64/dl-procinfo.h
new file mode 100644
index 0000000000..b360b4288a
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/ia64/dl-procinfo.h
@@ -0,0 +1,5 @@
+#ifdef IS_IN_ldconfig
+#include <sysdeps/unix/sysv/linux/i386/dl-procinfo.h>
+#else
+#include <sysdeps/generic/dl-procinfo.h>
+#endif
diff --git a/sysdeps/unix/sysv/linux/ia64/ldd-rewrite.sed b/sysdeps/unix/sysv/linux/ia64/ldd-rewrite.sed
index 535d1671e3..1df27afd2d 100644
--- a/sysdeps/unix/sysv/linux/ia64/ldd-rewrite.sed
+++ b/sysdeps/unix/sysv/linux/ia64/ldd-rewrite.sed
@@ -1 +1 @@
-s_^\(RTLDLIST=\)\([^ 	]*\)-ia64\(\.so\.[0-9.]*\)[ 	]*$_\1"\2-ia64\3 \2\3"_
+s_^\(RTLDLIST=\)\([^ 	]*\)-ia64\(\.so\.[0-9.]*\)[ 	]*$_\1"\2-ia64\3 /emul/ia32-linux\2\3"_
diff --git a/sysdeps/unix/sysv/linux/netlinkaccess.h b/sysdeps/unix/sysv/linux/netlinkaccess.h
index 92310b77df..48903d3725 100644
--- a/sysdeps/unix/sysv/linux/netlinkaccess.h
+++ b/sysdeps/unix/sysv/linux/netlinkaccess.h
@@ -25,6 +25,24 @@
 
 #include <kernel-features.h>
 
+#ifndef IFA_MAX
+/* 2.6.19 kernel headers helpfully removed some macros and
+   moved lots of stuff into new headers, some of which aren't
+   included by linux/rtnetlink.h.  */
+#include <linux/if_addr.h>
+#endif
+
+#ifndef IFA_RTA
+# define IFA_RTA(r) \
+  ((struct rtattr*) ((char*)(r) + NLMSG_ALIGN (sizeof (struct ifaddrmsg))))
+# define IFA_PAYLOAD(n) NLMSG_PAYLOAD (n, sizeof (struct ifaddrmsg))
+#endif
+
+#ifndef IFLA_RTA
+# define IFLA_RTA(r) \
+  ((struct rtattr*) ((char*)(r) + NLMSG_ALIGN (sizeof (struct ifinfomsg))))
+# define IFLA_PAYLOAD(n) NLMSG_PAYLOAD (n, sizeof (struct ifinfomsg))
+#endif
 
 struct netlink_res
 {
diff --git a/sysdeps/unix/sysv/linux/paths.h b/sysdeps/unix/sysv/linux/paths.h
index f4860f24d9..1b01c0d179 100644
--- a/sysdeps/unix/sysv/linux/paths.h
+++ b/sysdeps/unix/sysv/linux/paths.h
@@ -62,7 +62,7 @@
 #define	_PATH_TTY	"/dev/tty"
 #define	_PATH_UNIX	"/boot/vmlinux"
 #define _PATH_UTMP	"/var/run/utmp"
-#define	_PATH_VI	"/usr/bin/vi"
+#define	_PATH_VI	"/bin/vi"
 #define _PATH_WTMP	"/var/log/wtmp"
 
 /* Provide trailing slash, since mostly used for building pathnames. */
diff --git a/sysdeps/unix/sysv/linux/tcsetattr.c b/sysdeps/unix/sysv/linux/tcsetattr.c
index f73ec8883e..21e6ab2ede 100644
--- a/sysdeps/unix/sysv/linux/tcsetattr.c
+++ b/sysdeps/unix/sysv/linux/tcsetattr.c
@@ -49,6 +49,7 @@ tcsetattr (fd, optional_actions, termios_p)
 {
   struct __kernel_termios k_termios;
   unsigned long int cmd;
+  int retval;
 
   switch (optional_actions)
     {
@@ -80,6 +81,35 @@ tcsetattr (fd, optional_actions, termios_p)
   memcpy (&k_termios.c_cc[0], &termios_p->c_cc[0],
 	  __KERNEL_NCCS * sizeof (cc_t));
 
-  return INLINE_SYSCALL (ioctl, 3, fd, cmd, &k_termios);
+  retval = INLINE_SYSCALL (ioctl, 3, fd, cmd, &k_termios);
+
+  if (retval == 0 && cmd == TCSETS)
+    {
+      /* The Linux kernel has a bug which silently ignore the invalid
+        c_cflag on pty. We have to check it here. */
+      int save = errno;
+      retval = INLINE_SYSCALL (ioctl, 3, fd, TCGETS, &k_termios);
+      if (retval)
+       {
+         /* We cannot verify if the setting is ok. We don't return
+            an error (?). */
+         __set_errno (save);
+         retval = 0;
+       }
+      else if ((termios_p->c_cflag & (PARENB | CREAD))
+              != (k_termios.c_cflag & (PARENB | CREAD))
+              || ((termios_p->c_cflag & CSIZE)
+                  && ((termios_p->c_cflag & CSIZE)
+                      != (k_termios.c_cflag & CSIZE))))
+       {
+         /* It looks like the Linux kernel silently changed the
+            PARENB/CREAD/CSIZE bits in c_cflag. Report it as an
+            error. */
+         __set_errno (EINVAL);
+         retval = -1;
+       }
+    }
+
+  return retval;
 }
 libc_hidden_def (tcsetattr)