summaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
authorAndreas Schwab <schwab@redhat.com>2009-10-30 16:11:14 +0100
committerAndreas Schwab <schwab@redhat.com>2009-10-30 16:11:14 +0100
commit017dd87448e913383a8be5773569f218e8c661c5 (patch)
treed9124fdbb290416e60553c87aa9f9f1750d7acb8 /sysdeps
parentf8e81cec78280ef92014305c1e10a808b1260683 (diff)
parent3a83202db6e5591f2b72974c1ad98602c6620770 (diff)
Merge remote branch 'origin/master' into fedora/master
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/generic/elf/ifunc-sel.h26
-rw-r--r--sysdeps/generic/netinet/ip.h38
-rw-r--r--sysdeps/gnu/getutmp.c10
-rw-r--r--sysdeps/gnu/netinet/udp.h12
-rw-r--r--sysdeps/i386/fpu/s_expm1.S6
-rw-r--r--sysdeps/i386/fpu/s_expm1f.S6
-rw-r--r--sysdeps/i386/fpu/s_expm1l.S3
-rw-r--r--sysdeps/ieee754/dbl-64/w_exp.c1
-rw-r--r--sysdeps/ieee754/flt-32/w_expf.c1
-rw-r--r--sysdeps/ieee754/ldbl-128/w_expl.c1
-rw-r--r--sysdeps/ieee754/ldbl-96/w_expl.c1
-rw-r--r--sysdeps/posix/tempname.c14
-rw-r--r--sysdeps/powerpc/elf/ifunc-sel.h46
-rw-r--r--sysdeps/powerpc/powerpc32/dl-irel.h45
-rw-r--r--sysdeps/powerpc/powerpc32/dl-machine.c6
-rw-r--r--sysdeps/powerpc/powerpc32/dl-machine.h8
-rw-r--r--sysdeps/powerpc/powerpc64/dl-irel.h58
-rw-r--r--sysdeps/powerpc/powerpc64/dl-machine.h39
-rw-r--r--sysdeps/pthread/aio_misc.c26
-rw-r--r--sysdeps/unix/sysv/linux/faccessat.c8
-rw-r--r--sysdeps/unix/sysv/linux/fchmodat.c8
-rw-r--r--sysdeps/unix/sysv/linux/fchownat.c8
-rw-r--r--sysdeps/unix/sysv/linux/fcntl.c42
-rw-r--r--sysdeps/unix/sysv/linux/futimesat.c8
-rw-r--r--sysdeps/unix/sysv/linux/fxstatat.c8
-rw-r--r--sysdeps/unix/sysv/linux/fxstatat64.c8
-rw-r--r--sysdeps/unix/sysv/linux/getpt.c7
-rw-r--r--sysdeps/unix/sysv/linux/i386/bits/fcntl.h19
-rw-r--r--sysdeps/unix/sysv/linux/i386/fchownat.c8
-rw-r--r--sysdeps/unix/sysv/linux/i386/fcntl.c29
-rw-r--r--sysdeps/unix/sysv/linux/i386/fxstatat.c8
-rw-r--r--sysdeps/unix/sysv/linux/ia64/bits/fcntl.h19
-rw-r--r--sysdeps/unix/sysv/linux/ia64/bits/siginfo.h6
-rw-r--r--sysdeps/unix/sysv/linux/kernel-features.h5
-rw-r--r--sysdeps/unix/sysv/linux/linkat.c8
-rw-r--r--sysdeps/unix/sysv/linux/mkdirat.c8
-rw-r--r--sysdeps/unix/sysv/linux/openat.c8
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h19
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/fchownat.c8
-rw-r--r--sysdeps/unix/sysv/linux/readlinkat.c8
-rw-r--r--sysdeps/unix/sysv/linux/renameat.c14
-rw-r--r--sysdeps/unix/sysv/linux/s390/bits/fcntl.h19
-rw-r--r--sysdeps/unix/sysv/linux/s390/bits/siginfo.h10
-rw-r--r--sysdeps/unix/sysv/linux/sh/bits/fcntl.h19
-rw-r--r--sysdeps/unix/sysv/linux/sparc/bits/fcntl.h19
-rw-r--r--sysdeps/unix/sysv/linux/symlinkat.c8
-rw-r--r--sysdeps/unix/sysv/linux/ttyname.c7
-rw-r--r--sysdeps/unix/sysv/linux/unlinkat.c8
-rw-r--r--sysdeps/unix/sysv/linux/wordsize-64/fxstatat.c8
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/bits/fcntl.h19
-rw-r--r--sysdeps/unix/sysv/linux/xmknodat.c8
-rw-r--r--sysdeps/x86_64/multiarch/Makefile3
-rw-r--r--sysdeps/x86_64/multiarch/strchr.S177
-rw-r--r--sysdeps/x86_64/multiarch/strend-sse4.S49
-rw-r--r--sysdeps/x86_64/multiarch/strrchr.S278
55 files changed, 1180 insertions, 63 deletions
diff --git a/sysdeps/generic/elf/ifunc-sel.h b/sysdeps/generic/elf/ifunc-sel.h
new file mode 100644
index 0000000000..6a27b69c5b
--- /dev/null
+++ b/sysdeps/generic/elf/ifunc-sel.h
@@ -0,0 +1,26 @@
+/* Used by the elf ifunc tests. */
+#ifndef ELF_IFUNC_SEL_H
+#define ELF_IFUNC_SEL_H 1
+
+extern int global;
+
+static inline void *
+ifunc_sel (int (*f1) (void), int (*f2) (void), int (*f3) (void))
+{
+ switch (global)
+ {
+ case 1:
+ return f1;
+ case -1:
+ return f2;
+ default:
+ return f3;
+ }
+}
+
+static inline void *
+ifunc_one (int (*f1) (void))
+{
+ return f1;
+}
+#endif
diff --git a/sysdeps/generic/netinet/ip.h b/sysdeps/generic/netinet/ip.h
index fc91440527..38bd7556da 100644
--- a/sysdeps/generic/netinet/ip.h
+++ b/sysdeps/generic/netinet/ip.h
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991,92,93,95,96,97,98,99,2000 Free Software Foundation, Inc.
+/* Copyright (C) 1991,92,93,95,96,97,98,99,2000,2009 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
@@ -153,6 +154,41 @@ struct ip_timestamp
#define IP_MAXPACKET 65535 /* maximum packet size */
/*
+ * Definitions for Explicit Congestion Notification (ECN)
+ *
+ * Taken from RFC-3168, Section 5.
+ */
+
+#define IPTOS_ECN_MASK 0x03
+#define IPTOS_ECN(x) ((x) & IPTOS_ECN_MASK)
+#define IPTOS_ECN_NOT_ECT 0x00
+#define IPTOS_ECN_ECT1 0x01
+#define IPTOS_ECN_ECT0 0x02
+#define IPTOS_ECN_CE 0x03
+
+/*
+ * Definitions for IP differentiated services code points (DSCP)
+ *
+ * Taken from RFC-2597, Section 6 and RFC-2598, Section 2.3.
+ */
+
+#define IPTOS_DSCP_MASK 0xfc
+#define IPTOS_DSCP(x) ((x) & IPTOS_DSCP_MASK)
+#define IPTOS_DSCP_AF11 0x28
+#define IPTOS_DSCP_AF12 0x30
+#define IPTOS_DSCP_AF13 0x38
+#define IPTOS_DSCP_AF21 0x48
+#define IPTOS_DSCP_AF22 0x50
+#define IPTOS_DSCP_AF23 0x58
+#define IPTOS_DSCP_AF31 0x68
+#define IPTOS_DSCP_AF32 0x70
+#define IPTOS_DSCP_AF33 0x78
+#define IPTOS_DSCP_AF41 0x88
+#define IPTOS_DSCP_AF42 0x90
+#define IPTOS_DSCP_AF43 0x98
+#define IPTOS_DSCP_EF 0xb8
+
+/*
* Definitions for IP type of service (ip_tos)
*/
#define IPTOS_TOS_MASK 0x1E
diff --git a/sysdeps/gnu/getutmp.c b/sysdeps/gnu/getutmp.c
index 7b6d7713ea..9647c252e2 100644
--- a/sysdeps/gnu/getutmp.c
+++ b/sysdeps/gnu/getutmp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1999, 2009 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
@@ -19,10 +19,12 @@
#include <assert.h>
#include <string.h>
#include <utmp.h>
+#ifndef _UTMPX_H
/* This is an ugly hack but we must not see the getutmpx declaration. */
-#define getutmpx XXXgetutmpx
-#include <utmpx.h>
-#undef getutmpx
+# define getutmpx XXXgetutmpx
+# include <utmpx.h>
+# undef getutmpx
+#endif
void
getutmp (const struct utmpx *utmpx, struct utmp *utmp)
diff --git a/sysdeps/gnu/netinet/udp.h b/sysdeps/gnu/netinet/udp.h
index 45b69f7499..ae1beb9e1a 100644
--- a/sysdeps/gnu/netinet/udp.h
+++ b/sysdeps/gnu/netinet/udp.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 92, 93, 95, 96, 97, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 1991-1993,1995-1997,2004,2009 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
@@ -74,6 +74,16 @@ struct udphdr
};
#endif
+/* UDP socket options */
+#define UDP_CORK 1 /* Never send partially complete segments. */
+#define UDP_ENCAP 100 /* Set the socket to accept
+ encapsulated packets. */
+
+/* UDP encapsulation types */
+#define UDP_ENCAP_ESPINUDP_NON_IKE 1 /* draft-ietf-ipsec-nat-t-ike-00/01 */
+#define UDP_ENCAP_ESPINUDP 2 /* draft-ietf-ipsec-udp-encaps-06 */
+#define UDP_ENCAP_L2TPINUDP 3 /* rfc2661 */
+
#define SOL_UDP 17 /* sockopt level for UDP */
#endif /* netinet/udp.h */
diff --git a/sysdeps/i386/fpu/s_expm1.S b/sysdeps/i386/fpu/s_expm1.S
index e761183639..c690a458f8 100644
--- a/sysdeps/i386/fpu/s_expm1.S
+++ b/sysdeps/i386/fpu/s_expm1.S
@@ -22,6 +22,7 @@
/* Using: e^x - 1 = 2^(x * log2(e)) - 1 */
+#include <sysdep.h>
#include <machine/asm.h>
#ifdef __ELF__
@@ -48,6 +49,11 @@ l2e: .tfloat 1.442695040888963407359924681002
.text
ENTRY(__expm1)
+ movzwl 4+6(%esp), %eax
+ xorb $0x80, %ah // invert sign bit (now 1 is "positive")
+ cmpl $0xc086, %eax // is num >= 704?
+ jae HIDDEN_JUMPTARGET (__exp)
+
fldl 4(%esp) // x
fxam // Is NaN or +-Inf?
fstsw %ax
diff --git a/sysdeps/i386/fpu/s_expm1f.S b/sysdeps/i386/fpu/s_expm1f.S
index 88adb75b86..8645107274 100644
--- a/sysdeps/i386/fpu/s_expm1f.S
+++ b/sysdeps/i386/fpu/s_expm1f.S
@@ -22,6 +22,7 @@
/* Using: e^x - 1 = 2^(x * log2(e)) - 1 */
+#include <sysdep.h>
#include <machine/asm.h>
#ifdef __ELF__
@@ -48,6 +49,11 @@ l2e: .tfloat 1.442695040888963407359924681002
.text
ENTRY(__expm1f)
+ movzwl 4+2(%esp), %eax
+ xorb $0x80, %ah // invert sign bit (now 1 is "positive")
+ cmpl $0xc2b1, %eax // is num >= 88.5?
+ jae HIDDEN_JUMPTARGET (__expf)
+
flds 4(%esp) // x
fxam // Is NaN or +-Inf?
fstsw %ax
diff --git a/sysdeps/i386/fpu/s_expm1l.S b/sysdeps/i386/fpu/s_expm1l.S
index b69b22bc62..60b5b82e20 100644
--- a/sysdeps/i386/fpu/s_expm1l.S
+++ b/sysdeps/i386/fpu/s_expm1l.S
@@ -22,6 +22,7 @@
/* Using: e^x - 1 = 2^(x * log2(e)) - 1 */
+#include <sysdep.h>
#include <machine/asm.h>
#ifdef __ELF__
@@ -51,7 +52,7 @@ ENTRY(__expm1l)
movzwl 4+8(%esp), %eax // load sign bit and 15-bit exponent
xorb $0x80, %ah // invert sign bit (now 1 is "positive")
cmpl $0xc006, %eax // is num positive and exp >= 6 (number is >= 128.0)?
- jae __ieee754_expl // (if num is denormal, it is at least >= 64.0)
+ jae HIDDEN_JUMPTARGET (__expl) // (if num is denormal, it is at least >= 64.0)
fldt 4(%esp) // x
fxam // Is NaN or +-Inf?
diff --git a/sysdeps/ieee754/dbl-64/w_exp.c b/sysdeps/ieee754/dbl-64/w_exp.c
index 445c5788d2..1216492090 100644
--- a/sysdeps/ieee754/dbl-64/w_exp.c
+++ b/sysdeps/ieee754/dbl-64/w_exp.c
@@ -51,6 +51,7 @@ u_threshold= -7.45133219101941108420e+02; /* 0xc0874910, 0xD52D3051 */
return z;
#endif
}
+hidden_def (__exp)
weak_alias (__exp, exp)
#ifdef NO_LONG_DOUBLE
strong_alias (__exp, __expl)
diff --git a/sysdeps/ieee754/flt-32/w_expf.c b/sysdeps/ieee754/flt-32/w_expf.c
index 4ba21c7c42..83b268f570 100644
--- a/sysdeps/ieee754/flt-32/w_expf.c
+++ b/sysdeps/ieee754/flt-32/w_expf.c
@@ -56,4 +56,5 @@ u_threshold= -1.0397208405e+02; /* 0xc2cff1b5 */
return z;
#endif
}
+hidden_def (__expf)
weak_alias (__expf, expf)
diff --git a/sysdeps/ieee754/ldbl-128/w_expl.c b/sysdeps/ieee754/ldbl-128/w_expl.c
index 816ce3caa6..d6205d3ef8 100644
--- a/sysdeps/ieee754/ldbl-128/w_expl.c
+++ b/sysdeps/ieee754/ldbl-128/w_expl.c
@@ -55,4 +55,5 @@ u_threshold= -1.1433462743336297878837243843452621503410E4;
return z;
#endif
}
+hidden_def (__expl)
weak_alias (__expl, expl)
diff --git a/sysdeps/ieee754/ldbl-96/w_expl.c b/sysdeps/ieee754/ldbl-96/w_expl.c
index b8152cea65..53bb143734 100644
--- a/sysdeps/ieee754/ldbl-96/w_expl.c
+++ b/sysdeps/ieee754/ldbl-96/w_expl.c
@@ -57,4 +57,5 @@ u_threshold= -1.140019167866942050398521670162263001513e4;
return z;
#endif
}
+hidden_def (__expl)
weak_alias (__expl, expl)
diff --git a/sysdeps/posix/tempname.c b/sysdeps/posix/tempname.c
index be979d8c8a..57ce5a942c 100644
--- a/sysdeps/posix/tempname.c
+++ b/sysdeps/posix/tempname.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2001, 2006, 2007 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2001, 2006, 2007, 2009 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
@@ -210,9 +210,9 @@ static const char letters[] =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
/* Generate a temporary file name based on TMPL. TMPL must match the
- rules for mk[s]temp (i.e. end in "XXXXXX"). The name constructed
- does not exist at the time of the call to __gen_tempname. TMPL is
- overwritten with the result.
+ rules for mk[s]temp (i.e. end in "XXXXXX", possibly with a suffix).
+ The name constructed does not exist at the time of the call to
+ __gen_tempname. TMPL is overwritten with the result.
KIND may be one of:
__GT_NOCREATE: simply verify that the name does not exist
@@ -223,7 +223,7 @@ static const char letters[] =
We use a clever algorithm to get hard-to-predict names. */
int
-__gen_tempname (char *tmpl, int flags, int kind)
+__gen_tempname (char *tmpl, int suffixlen, int flags, int kind)
{
int len;
char *XXXXXX;
@@ -251,14 +251,14 @@ __gen_tempname (char *tmpl, int flags, int kind)
#endif
len = strlen (tmpl);
- if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX"))
+ if (len < 6 + suffixlen || memcmp (&tmpl[len - 6 - suffixlen], "XXXXXX", 6))
{
__set_errno (EINVAL);
return -1;
}
/* This is where the Xs start. */
- XXXXXX = &tmpl[len - 6];
+ XXXXXX = &tmpl[len - 6 - suffixlen];
/* Get some more or less random data. */
#ifdef RANDOM_BITS
diff --git a/sysdeps/powerpc/elf/ifunc-sel.h b/sysdeps/powerpc/elf/ifunc-sel.h
new file mode 100644
index 0000000000..526d8ed88b
--- /dev/null
+++ b/sysdeps/powerpc/elf/ifunc-sel.h
@@ -0,0 +1,46 @@
+/* Used by the elf ifunc tests. */
+#ifndef ELF_IFUNC_SEL_H
+#define ELF_IFUNC_SEL_H 1
+
+extern int global;
+
+static inline void *
+ifunc_sel (int (*f1) (void), int (*f2) (void), int (*f3) (void))
+{
+ register void *ret __asm__ ("r3");
+ __asm__ ("mflr 12\n\t"
+ "bcl 20,31,1f\n"
+ "1:\tmflr 11\n\t"
+ "mtlr 12\n\t"
+ "addis 12,11,global-1b@ha\n\t"
+ "lwz 12,global-1b@l(12)\n\t"
+ "addis %0,11,%2-1b@ha\n\t"
+ "addi %0,%0,%2-1b@l\n\t"
+ "cmpwi 12,1\n\t"
+ "beqlr\n\t"
+ "addis %0,11,%3-1b@ha\n\t"
+ "addi %0,%0,%3-1b@l\n\t"
+ "cmpwi 12,-1\n\t"
+ "beqlr\n\t"
+ "addis %0,11,%4-1b@ha\n\t"
+ "addi %0,%0,%4-1b@l"
+ : "=r" (ret)
+ : "X" (&global), "X" (f1), "X" (f2), "X" (f3));
+ return ret;
+}
+
+static inline void *
+ifunc_one (int (*f1) (void))
+{
+ register void *ret __asm__ ("r3");
+ __asm__ ("mflr 12\n\t"
+ "bcl 20,31,1f\n"
+ "1:\tmflr %0\n\t"
+ "mtlr 12\n\t"
+ "addis %0,%0,%1-1b@ha\n\t"
+ "addi %0,%0,%1-1b@l"
+ : "=r" (ret)
+ : "X" (f1));
+ return ret;
+}
+#endif
diff --git a/sysdeps/powerpc/powerpc32/dl-irel.h b/sysdeps/powerpc/powerpc32/dl-irel.h
new file mode 100644
index 0000000000..3f204cd7ae
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/dl-irel.h
@@ -0,0 +1,45 @@
+/* Machine-dependent ELF indirect relocation inline functions.
+ PowerPC version.
+ Copyright (C) 2009 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. */
+
+#ifndef _DL_IREL_H
+#define _DL_IREL_H
+
+#include <stdio.h>
+#include <unistd.h>
+
+#define ELF_MACHINE_IRELA 1
+
+static inline void
+__attribute ((always_inline))
+elf_irela (const Elf32_Rela *reloc)
+{
+ unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
+
+ if (__builtin_expect (r_type == R_PPC_IRELATIVE, 1))
+ {
+ Elf32_Addr *const reloc_addr = (void *) reloc->r_offset;
+ Elf32_Addr value = ((Elf32_Addr (*) (void)) reloc->r_addend) ();
+ *reloc_addr = value;
+ }
+ else
+ __libc_fatal ("unexpected reloc type in static binary");
+}
+
+#endif /* dl-irel.h */
diff --git a/sysdeps/powerpc/powerpc32/dl-machine.c b/sysdeps/powerpc/powerpc32/dl-machine.c
index 71540bd185..ee4c3e0c1c 100644
--- a/sysdeps/powerpc/powerpc32/dl-machine.c
+++ b/sysdeps/powerpc/powerpc32/dl-machine.c
@@ -337,7 +337,7 @@ __elf_machine_runtime_setup (struct link_map *map, int lazy, int profile)
}
Elf32_Addr
-__elf_machine_fixup_plt (struct link_map *map, const Elf32_Rela *reloc,
+__elf_machine_fixup_plt (struct link_map *map,
Elf32_Addr *reloc_addr, Elf32_Addr finaladdr)
{
Elf32_Sword delta = finaladdr - (Elf32_Word) reloc_addr;
@@ -430,6 +430,10 @@ __process_machine_rela (struct link_map *map,
*reloc_addr = finaladdr;
return;
+ case R_PPC_IRELATIVE:
+ *reloc_addr = ((Elf32_Addr (*) (void)) finaladdr) ();
+ return;
+
case R_PPC_UADDR32:
((char *) reloc_addr)[0] = finaladdr >> 24;
((char *) reloc_addr)[1] = finaladdr >> 16;
diff --git a/sysdeps/powerpc/powerpc32/dl-machine.h b/sysdeps/powerpc/powerpc32/dl-machine.h
index a50ffdd1c2..6f8d0f506e 100644
--- a/sysdeps/powerpc/powerpc32/dl-machine.h
+++ b/sysdeps/powerpc/powerpc32/dl-machine.h
@@ -226,7 +226,6 @@ elf_machine_runtime_setup (struct link_map *map,
/* Change the PLT entry whose reloc is 'reloc' to call the actual routine. */
extern Elf32_Addr __elf_machine_fixup_plt (struct link_map *map,
- const Elf32_Rela *reloc,
Elf32_Addr *reloc_addr,
Elf32_Addr finaladdr);
@@ -237,7 +236,7 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t t,
{
if (map->l_info[DT_PPC(GOT)] == 0)
/* Handle old style PLT. */
- return __elf_machine_fixup_plt (map, reloc, reloc_addr, finaladdr);
+ return __elf_machine_fixup_plt (map, reloc_addr, finaladdr);
*reloc_addr = finaladdr;
return finaladdr;
@@ -317,6 +316,11 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
value = reloc->r_addend;
#endif
+ if (sym != NULL
+ && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0)
+ && __builtin_expect (sym->st_shndx != SHN_UNDEF, 1))
+ value = ((Elf32_Addr (*) (void)) value) ();
+
/* A small amount of code is duplicated here for speed. In libc,
more than 90% of the relocs are R_PPC_RELATIVE; in the X11 shared
libraries, 60% are R_PPC_RELATIVE, 24% are R_PPC_GLOB_DAT or
diff --git a/sysdeps/powerpc/powerpc64/dl-irel.h b/sysdeps/powerpc/powerpc64/dl-irel.h
new file mode 100644
index 0000000000..6cded5091d
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/dl-irel.h
@@ -0,0 +1,58 @@
+/* Machine-dependent ELF indirect relocation inline functions.
+ PowerPC64 version.
+ Copyright (C) 2009 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. */
+
+#ifndef _DL_IREL_H
+#define _DL_IREL_H
+
+#include <stdio.h>
+#include <unistd.h>
+
+#define ELF_MACHINE_IRELA 1
+
+typedef struct
+{
+ Elf64_Addr fd_func;
+ Elf64_Addr fd_toc;
+ Elf64_Addr fd_aux;
+} Elf64_FuncDesc;
+
+static inline void
+__attribute ((always_inline))
+elf_irela (const Elf64_Rela *reloc)
+{
+ unsigned int r_type = ELF64_R_TYPE (reloc->r_info);
+
+ if (__builtin_expect (r_type == R_PPC64_IRELATIVE, 1))
+ {
+ Elf64_Addr *const reloc_addr = (void *) reloc->r_offset;
+ Elf64_Addr value = ((Elf64_Addr (*) (void)) reloc->r_addend) ();
+ *reloc_addr = value;
+ }
+ else if (__builtin_expect (r_type == R_PPC64_JMP_IREL, 1))
+ {
+ Elf64_Addr *const reloc_addr = (void *) reloc->r_offset;
+ Elf64_Addr value = ((Elf64_Addr (*) (void)) reloc->r_addend) ();
+ *(Elf64_FuncDesc *) reloc_addr = *(Elf64_FuncDesc *) value;
+ }
+ else
+ __libc_fatal ("unexpected reloc type in static binary");
+}
+
+#endif /* dl-irel.h */
diff --git a/sysdeps/powerpc/powerpc64/dl-machine.h b/sysdeps/powerpc/powerpc64/dl-machine.h
index b674dbef43..8a720ae9c2 100644
--- a/sysdeps/powerpc/powerpc64/dl-machine.h
+++ b/sysdeps/powerpc/powerpc64/dl-machine.h
@@ -526,6 +526,29 @@ elf_machine_tprel (struct link_map *map,
}
#endif
+/* Call function at address VALUE (an OPD entry) to resolve ifunc relocs. */
+auto inline Elf64_Addr __attribute__ ((always_inline))
+resolve_ifunc (Elf64_Addr value,
+ const struct link_map *map, const struct link_map *sym_map)
+{
+ /* The function we are calling may not yet have its opd entry relocated. */
+ Elf64_FuncDesc opd;
+ if (map != sym_map
+#if !defined RTLD_BOOTSTRAP && defined SHARED
+ /* Bootstrap map doesn't have l_relocated set for it. */
+ && sym_map != &GL(dl_rtld_map)
+#endif
+ && !sym_map->l_relocated)
+ {
+ Elf64_FuncDesc *func = (Elf64_FuncDesc *) value;
+ opd.fd_func = func->fd_func + sym_map->l_addr;
+ opd.fd_toc = func->fd_toc + sym_map->l_addr;
+ opd.fd_aux = func->fd_aux;
+ value = (Elf64_Addr) &opd;
+ }
+ return ((Elf64_Addr (*) (void)) value) ();
+}
+
/* Perform the relocation specified by RELOC and SYM (which is fully
resolved). MAP is the object containing the reloc. */
auto inline void __attribute__ ((always_inline))
@@ -550,11 +573,17 @@ elf_machine_rela (struct link_map *map,
if (__builtin_expect (r_type == R_PPC64_NONE, 0))
return;
- /* We need SYM_MAP even in the absence of TLS, for elf_machine_fixup_plt. */
+ /* We need SYM_MAP even in the absence of TLS, for elf_machine_fixup_plt
+ and STT_GNU_IFUNC. */
struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
Elf64_Addr value = ((sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value)
+ reloc->r_addend);
+ if (sym != NULL
+ && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0)
+ && __builtin_expect (sym->st_shndx != SHN_UNDEF, 1))
+ value = resolve_ifunc (value, map, sym_map);
+
/* For relocs that don't edit code, return.
For relocs that might edit instructions, break from the switch. */
switch (r_type)
@@ -564,6 +593,14 @@ elf_machine_rela (struct link_map *map,
*reloc_addr = value;
return;
+ case R_PPC64_IRELATIVE:
+ value = resolve_ifunc (value, map, sym_map);
+ *reloc_addr = value;
+ return;
+
+ case R_PPC64_JMP_IREL:
+ value = resolve_ifunc (value, map, sym_map);
+ /* Fall thru */
case R_PPC64_JMP_SLOT:
#ifdef RESOLVE_CONFLICT_FIND_MAP
elf_machine_plt_conflict (reloc_addr, value);
diff --git a/sysdeps/pthread/aio_misc.c b/sysdeps/pthread/aio_misc.c
index fd3fcbb755..c82acbbc2d 100644
--- a/sysdeps/pthread/aio_misc.c
+++ b/sysdeps/pthread/aio_misc.c
@@ -1,5 +1,5 @@
/* Handle general operations.
- Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2006, 2007
+ Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2006, 2007, 2009
Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -372,9 +372,13 @@ __aio_enqueue_request (aiocb_union *aiocbp, int operation)
/* Simply enqueue it after the running one according to the
priority. */
+ last = NULL;
while (runp->next_prio != NULL
&& runp->next_prio->aiocbp->aiocb.__abs_prio >= prio)
- runp = runp->next_prio;
+ {
+ last = runp;
+ runp = runp->next_prio;
+ }
newp->next_prio = runp->next_prio;
runp->next_prio = newp;
@@ -403,6 +407,7 @@ __aio_enqueue_request (aiocb_union *aiocbp, int operation)
}
newp->next_prio = NULL;
+ last = NULL;
}
if (running == yes)
@@ -423,7 +428,8 @@ __aio_enqueue_request (aiocb_union *aiocbp, int operation)
running = newp->running = allocated;
/* Now try to start a thread. */
- if (aio_create_helper_thread (&thid, handle_fildes_io, newp) == 0)
+ result = aio_create_helper_thread (&thid, handle_fildes_io, newp);
+ if (result == 0)
/* We managed to enqueue the request. All errors which can
happen now can be recognized by calls to `aio_return' and
`aio_error'. */
@@ -434,10 +440,14 @@ __aio_enqueue_request (aiocb_union *aiocbp, int operation)
running = newp->running = yes;
if (nthreads == 0)
- /* We cannot create a thread in the moment and there is
- also no thread running. This is a problem. `errno' is
- set to EAGAIN if this is only a temporary problem. */
- result = -1;
+ {
+ /* We cannot create a thread in the moment and there is
+ also no thread running. This is a problem. `errno' is
+ set to EAGAIN if this is only a temporary problem. */
+ __aio_remove_request (last, newp, 0);
+ }
+ else
+ result = 0;
}
}
}
@@ -459,6 +469,8 @@ __aio_enqueue_request (aiocb_union *aiocbp, int operation)
{
/* Something went wrong. */
__aio_free_request (newp);
+ aiocbp->aiocb.__error_code = result;
+ __set_errno (result);
newp = NULL;
}
diff --git a/sysdeps/unix/sysv/linux/faccessat.c b/sysdeps/unix/sysv/linux/faccessat.c
index 10b903d076..c154deb40f 100644
--- a/sysdeps/unix/sysv/linux/faccessat.c
+++ b/sysdeps/unix/sysv/linux/faccessat.c
@@ -1,5 +1,5 @@
/* Test for access to file, relative to open directory. Linux version.
- Copyright (C) 2006 Free Software Foundation, Inc.
+ Copyright (C) 2006, 2009 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
@@ -72,6 +72,12 @@ faccessat (fd, file, mode, flag)
if (fd != AT_FDCWD && file[0] != '/')
{
size_t filelen = strlen (file);
+ if (__builtin_expect (filelen == 0, 0))
+ {
+ __set_errno (ENOENT);
+ return -1;
+ }
+
static const char procfd[] = "/proc/self/fd/%d/%s";
/* Buffer for the path name we are going to use. It consists of
- the string /proc/self/fd/
diff --git a/sysdeps/unix/sysv/linux/fchmodat.c b/sysdeps/unix/sysv/linux/fchmodat.c
index 8b420153f1..051691230d 100644
--- a/sysdeps/unix/sysv/linux/fchmodat.c
+++ b/sysdeps/unix/sysv/linux/fchmodat.c
@@ -1,5 +1,5 @@
/* Change the protections of file relative to open directory. Linux version.
- Copyright (C) 2006 Free Software Foundation, Inc.
+ Copyright (C) 2006, 2009 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
@@ -71,6 +71,12 @@ fchmodat (fd, file, mode, flag)
if (fd != AT_FDCWD && file[0] != '/')
{
size_t filelen = strlen (file);
+ if (__builtin_expect (filelen == 0, 0))
+ {
+ __set_errno (ENOENT);
+ return -1;
+ }
+
static const char procfd[] = "/proc/self/fd/%d/%s";
/* Buffer for the path name we are going to use. It consists of
- the string /proc/self/fd/
diff --git a/sysdeps/unix/sysv/linux/fchownat.c b/sysdeps/unix/sysv/linux/fchownat.c
index 0f731775b3..db43755694 100644
--- a/sysdeps/unix/sysv/linux/fchownat.c
+++ b/sysdeps/unix/sysv/linux/fchownat.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2006, 2009 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
@@ -66,6 +66,12 @@ fchownat (fd, file, owner, group, flag)
if (fd != AT_FDCWD && file[0] != '/')
{
size_t filelen = strlen (file);
+ if (__builtin_expect (filelen == 0, 0))
+ {
+ __set_errno (ENOENT);
+ return -1;
+ }
+
static const char procfd[] = "/proc/self/fd/%d/%s";
/* Buffer for the path name we are going to use. It consists of
- the string /proc/self/fd/
diff --git a/sysdeps/unix/sysv/linux/fcntl.c b/sysdeps/unix/sysv/linux/fcntl.c
index 1f5aca14a4..b19654c625 100644
--- a/sysdeps/unix/sysv/linux/fcntl.c
+++ b/sysdeps/unix/sysv/linux/fcntl.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2000, 2002, 2003, 2004, 2009 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
@@ -23,6 +23,40 @@
#include <stdarg.h>
#include <sys/syscall.h>
+#include <kernel-features.h>
+
+
+#ifdef __ASSUME_F_GETOWN_EX
+# define miss_F_GETOWN_EX 0
+#else
+static int miss_F_GETOWN_EX;
+#endif
+
+
+static int
+do_fcntl (int fd, int cmd, void *arg)
+{
+ if (cmd != F_GETOWN || miss_F_GETOWN_EX)
+ return INLINE_SYSCALL (fcntl, 3, fd, cmd, arg);
+
+ INTERNAL_SYSCALL_DECL (err);
+ struct f_owner_ex fex;
+ int res = INTERNAL_SYSCALL (fcntl, err, 3, fd, F_GETOWN_EX, &fex);
+ if (!INTERNAL_SYSCALL_ERROR_P (res, err))
+ return fex.type == F_OWNER_GID ? -fex.pid : fex.pid;
+
+#ifndef __ASSUME_F_GETOWN_EX
+ if (INTERNAL_SYSCALL_ERRNO (res, err) == EINVAL)
+ {
+ res = INLINE_SYSCALL (fcntl, 3, fd, F_GETOWN, arg);
+ miss_F_GETOWN_EX = 1;
+ return res;
+ }
+#endif
+
+ __set_errno (INTERNAL_SYSCALL_ERRNO (res, err));
+ return -1;
+}
#ifndef NO_CANCELLATION
@@ -36,7 +70,7 @@ __fcntl_nocancel (int fd, int cmd, ...)
arg = va_arg (ap, void *);
va_end (ap);
- return INLINE_SYSCALL (fcntl, 3, fd, cmd, arg);
+ return do_fcntl (fd, cmd, arg);
}
#endif
@@ -52,11 +86,11 @@ __libc_fcntl (int fd, int cmd, ...)
va_end (ap);
if (SINGLE_THREAD_P || cmd != F_SETLKW)
- return INLINE_SYSCALL (fcntl, 3, fd, cmd, arg);
+ return do_fcntl (fd, cmd, arg);
int oldtype = LIBC_CANCEL_ASYNC ();
- int result = INLINE_SYSCALL (fcntl, 3, fd, cmd, arg);
+ int result = do_fcntl (fd, cmd, arg);
LIBC_CANCEL_RESET (oldtype);
diff --git a/sysdeps/unix/sysv/linux/futimesat.c b/sysdeps/unix/sysv/linux/futimesat.c
index 5f3a3f52f3..8292533afb 100644
--- a/sysdeps/unix/sysv/linux/futimesat.c
+++ b/sysdeps/unix/sysv/linux/futimesat.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2006, 2009 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
@@ -61,6 +61,12 @@ futimesat (fd, file, tvp)
if (fd != AT_FDCWD && file[0] != '/')
{
size_t filelen = strlen (file);
+ if (__builtin_expect (filelen == 0, 0))
+ {
+ __set_errno (ENOENT);
+ return -1;
+ }
+
static const char procfd[] = "/proc/self/fd/%d/%s";
/* Buffer for the path name we are going to use. It consists of
- the string /proc/self/fd/
diff --git a/sysdeps/unix/sysv/linux/fxstatat.c b/sysdeps/unix/sysv/linux/fxstatat.c
index 1b9add40d7..dd5c9bc684 100644
--- a/sysdeps/unix/sysv/linux/fxstatat.c
+++ b/sysdeps/unix/sysv/linux/fxstatat.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2006, 2007, 2009 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
@@ -85,6 +85,12 @@ __fxstatat (int vers, int fd, const char *file, struct stat *st, int flag)
if (fd != AT_FDCWD && file[0] != '/')
{
size_t filelen = strlen (file);
+ if (__builtin_expect (filelen == 0, 0))
+ {
+ __set_errno (ENOENT);
+ return -1;
+ }
+
static const char procfd[] = "/proc/self/fd/%d/%s";
/* Buffer for the path name we are going to use. It consists of
- the string /proc/self/fd/
diff --git a/sysdeps/unix/sysv/linux/fxstatat64.c b/sysdeps/unix/sysv/linux/fxstatat64.c
index cb932b8e59..442e4ca989 100644
--- a/sysdeps/unix/sysv/linux/fxstatat64.c
+++ b/sysdeps/unix/sysv/linux/fxstatat64.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005,2006 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2006, 2009 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
@@ -90,6 +90,12 @@ __fxstatat64 (int vers, int fd, const char *file, struct stat64 *st, int flag)
if (fd != AT_FDCWD && file[0] != '/')
{
size_t filelen = strlen (file);
+ if (__builtin_expect (filelen == 0, 0))
+ {
+ __set_errno (ENOENT);
+ return -1;
+ }
+
static const char procfd[] = "/proc/self/fd/%d/%s";
/* Buffer for the path name we are going to use. It consists of
- the string /proc/self/fd/
diff --git a/sysdeps/unix/sysv/linux/getpt.c b/sysdeps/unix/sysv/linux/getpt.c
index bb1ea47643..6b26fdfcdc 100644
--- a/sysdeps/unix/sysv/linux/getpt.c
+++ b/sysdeps/unix/sysv/linux/getpt.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc.
+/* Copyright (C) 1998, 1999, 2001, 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Zack Weinberg <zack@rabi.phys.columbia.edu>, 1998.
@@ -64,9 +64,10 @@ __posix_openpt (oflag)
}
/* If /dev/pts is not mounted then the UNIX98 pseudo terminals
- are not usable. */
+ are not usable. */
__close (fd);
have_no_dev_ptmx = 1;
+ __set_errno (ENOENT);
}
else
{
@@ -76,6 +77,8 @@ __posix_openpt (oflag)
return -1;
}
}
+ else
+ __set_errno (ENOENT);
return -1;
}
diff --git a/sysdeps/unix/sysv/linux/i386/bits/fcntl.h b/sysdeps/unix/sysv/linux/i386/bits/fcntl.h
index 35ef665998..d1718a17c9 100644
--- a/sysdeps/unix/sysv/linux/i386/bits/fcntl.h
+++ b/sysdeps/unix/sysv/linux/i386/bits/fcntl.h
@@ -1,5 +1,5 @@
/* O_*, F_*, FD_* bit values for Linux.
- Copyright (C) 1995, 1996, 1997, 1998, 2000, 2004, 2006, 2007
+ Copyright (C) 1995, 1996, 1997, 1998, 2000, 2004, 2006, 2007, 2009
Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -166,6 +166,23 @@ struct flock64
};
#endif
+#ifdef __USE_GNU
+/* Owner types. */
+enum __pid_type
+ {
+ F_OWNER_TID = 0, /* Kernel thread. */
+ F_OWNER_PID, /* Process. */
+ F_OWNER_GID /* Process group. */
+ };
+
+/* Structure to use with F_GETOWN_EX and F_SETOWN_EX. */
+struct f_owner_ex
+ {
+ enum __pid_type type; /* Owner type of ID. */
+ __pid_t pid; /* ID of owner. */
+ };
+#endif
+
/* Define some more compatibility macros to be backward compatible with
BSD systems which did not managed to hide these kernel macros. */
#ifdef __USE_BSD
diff --git a/sysdeps/unix/sysv/linux/i386/fchownat.c b/sysdeps/unix/sysv/linux/i386/fchownat.c
index 34acf10c27..1b02fde459 100644
--- a/sysdeps/unix/sysv/linux/i386/fchownat.c
+++ b/sysdeps/unix/sysv/linux/i386/fchownat.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2006, 2009 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
@@ -63,6 +63,12 @@ fchownat (int fd, const char *file, uid_t owner, gid_t group, int flag)
if (fd != AT_FDCWD && file[0] != '/')
{
size_t filelen = strlen (file);
+ if (__builtin_expect (filelen == 0, 0))
+ {
+ __set_errno (ENOENT);
+ return -1;
+ }
+
static const char procfd[] = "/proc/self/fd/%d/%s";
/* Buffer for the path name we are going to use. It consists of
- the string /proc/self/fd/
diff --git a/sysdeps/unix/sysv/linux/i386/fcntl.c b/sysdeps/unix/sysv/linux/i386/fcntl.c
index b27373d24b..5544d6e0d9 100644
--- a/sysdeps/unix/sysv/linux/i386/fcntl.c
+++ b/sysdeps/unix/sysv/linux/i386/fcntl.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000,2002,2003,2004,2006 Free Software Foundation, Inc.
+/* Copyright (C) 2000,2002,2003,2004,2006,2009 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
@@ -30,6 +30,13 @@
int __have_no_fcntl64;
#endif
+#ifdef __ASSUME_F_GETOWN_EX
+# define miss_F_GETOWN_EX 0
+#else
+static int miss_F_GETOWN_EX;
+#endif
+
+
#if defined NO_CANCELLATION && __ASSUME_FCNTL64 == 0
# define __fcntl_nocancel __libc_fcntl
#endif
@@ -119,6 +126,26 @@ __fcntl_nocancel (int fd, int cmd, ...)
assert (F_SETLK - F_SETLKW == F_SETLK64 - F_SETLKW64);
return INLINE_SYSCALL (fcntl, 3, fd, cmd + F_SETLK - F_SETLK64, &fl);
}
+ case F_GETOWN:
+ if (! miss_F_GETOWN_EX)
+ {
+ INTERNAL_SYSCALL_DECL (err);
+ struct f_owner_ex fex;
+ int res = INTERNAL_SYSCALL (fcntl, err, 3, fd, F_GETOWN_EX, &fex);
+ if (!INTERNAL_SYSCALL_ERROR_P (res, err))
+ return fex.type == F_OWNER_GID ? -fex.pid : fex.pid;
+
+#ifndef __ASSUME_F_GETOWN_EX
+ if (INTERNAL_SYSCALL_ERRNO (res, err) == EINVAL)
+ miss_F_GETOWN_EX = 1;
+ else
+#endif
+ {
+ __set_errno (INTERNAL_SYSCALL_ERRNO (res, err));
+ return -1;
+ }
+ }
+ /* FALLTHROUGH */
default:
return INLINE_SYSCALL (fcntl, 3, fd, cmd, arg);
}
diff --git a/sysdeps/unix/sysv/linux/i386/fxstatat.c b/sysdeps/unix/sysv/linux/i386/fxstatat.c
index 94f6e81186..37757937b3 100644
--- a/sysdeps/unix/sysv/linux/i386/fxstatat.c
+++ b/sysdeps/unix/sysv/linux/i386/fxstatat.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2006, 2009 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
@@ -86,6 +86,12 @@ __fxstatat (int vers, int fd, const char *file, struct stat *st, int flag)
if (fd != AT_FDCWD && file[0] != '/')
{
size_t filelen = strlen (file);
+ if (__builtin_expect (filelen == 0, 0))
+ {
+ __set_errno (ENOENT);
+ return -1;
+ }
+
static const char procfd[] = "/proc/self/fd/%d/%s";
/* Buffer for the path name we are going to use. It consists of
- the string /proc/self/fd/
diff --git a/sysdeps/unix/sysv/linux/ia64/bits/fcntl.h b/sysdeps/unix/sysv/linux/ia64/bits/fcntl.h
index 6abc5ced65..9e11f648f8 100644
--- a/sysdeps/unix/sysv/linux/ia64/bits/fcntl.h
+++ b/sysdeps/unix/sysv/linux/ia64/bits/fcntl.h
@@ -1,5 +1,5 @@
/* O_*, F_*, FD_* bit values for Linux/IA64.
- Copyright (C) 1999, 2000, 2004, 2006, 2007 Free Software Foundation, Inc.
+ Copyright (C) 1999,2000,2004,2006,2007,2009 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
@@ -159,6 +159,23 @@ struct flock64
};
#endif
+#ifdef __USE_GNU
+/* Owner types. */
+enum __pid_type
+ {
+ F_OWNER_TID = 0, /* Kernel thread. */
+ F_OWNER_PID, /* Process. */
+ F_OWNER_GID /* Process group. */
+ };
+
+/* Structure to use with F_GETOWN_EX and F_SETOWN_EX. */
+struct f_owner_ex
+ {
+ enum __pid_type type; /* Owner type of ID. */
+ __pid_t pid; /* ID of owner. */
+ };
+#endif
+
/* Define some more compatibility macros to be backward compatible with
BSD systems which did not managed to hide these kernel macros. */
diff --git a/sysdeps/unix/sysv/linux/ia64/bits/siginfo.h b/sysdeps/unix/sysv/linux/ia64/bits/siginfo.h
index 66310c65b3..240ebbc9e1 100644
--- a/sysdeps/unix/sysv/linux/ia64/bits/siginfo.h
+++ b/sysdeps/unix/sysv/linux/ia64/bits/siginfo.h
@@ -1,5 +1,5 @@
/* siginfo_t, sigevent and constants. Linux/ia64 version.
- Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2000-2004, 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>.
@@ -310,6 +310,10 @@ typedef struct sigevent
{
int _pad[__SIGEV_PAD_SIZE];
+ /* When SIGEV_SIGNAL and SIGEV_THREAD_ID set, LWP ID of the
+ thread to receive the signal. */
+ __pid_t _tid;
+
struct
{
void (*_function) (sigval_t); /* Function to start. */
diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h
index ff065effb5..f48e644e09 100644
--- a/sysdeps/unix/sysv/linux/kernel-features.h
+++ b/sysdeps/unix/sysv/linux/kernel-features.h
@@ -542,3 +542,8 @@
# define __ASSUME_PREADV 1
# define __ASSUME_PWRITEV 1
#endif
+
+/* Support for F_GETOWN_EX was introduced in 2.6.32. */
+#if __LINUX_KERNEL_VERSION >= 0x020620
+# define __ASSUME_F_GETOWN_EX 1
+#endif
diff --git a/sysdeps/unix/sysv/linux/linkat.c b/sysdeps/unix/sysv/linux/linkat.c
index cfd0e18223..b2b7b0386b 100644
--- a/sysdeps/unix/sysv/linux/linkat.c
+++ b/sysdeps/unix/sysv/linux/linkat.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2006, 2009 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
@@ -66,6 +66,12 @@ linkat (fromfd, from, tofd, to, flags)
if (fromfd != AT_FDCWD && from[0] != '/')
{
size_t filelen = strlen (from);
+ if (__builtin_expect (filelen == 0, 0))
+ {
+ __set_errno (ENOENT);
+ return -1;
+ }
+
/* Buffer for the path name we are going to use. It consists of
- the string /proc/self/fd/
- the file descriptor number
diff --git a/sysdeps/unix/sysv/linux/mkdirat.c b/sysdeps/unix/sysv/linux/mkdirat.c
index 3c190085ce..aa89d08730 100644
--- a/sysdeps/unix/sysv/linux/mkdirat.c
+++ b/sysdeps/unix/sysv/linux/mkdirat.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2006, 2009 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
@@ -57,6 +57,12 @@ mkdirat (fd, file, mode)
if (fd != AT_FDCWD && file[0] != '/')
{
size_t filelen = strlen (file);
+ if (__builtin_expect (filelen == 0, 0))
+ {
+ __set_errno (ENOENT);
+ return -1;
+ }
+
static const char procfd[] = "/proc/self/fd/%d/%s";
/* Buffer for the path name we are going to use. It consists of
- the string /proc/self/fd/
diff --git a/sysdeps/unix/sysv/linux/openat.c b/sysdeps/unix/sysv/linux/openat.c
index 45b566f2d0..7916c71105 100644
--- a/sysdeps/unix/sysv/linux/openat.c
+++ b/sysdeps/unix/sysv/linux/openat.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2006, 2007, 2009 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
@@ -110,6 +110,12 @@ OPENAT_NOT_CANCEL (fd, file, oflag, mode)
if (fd != AT_FDCWD && file[0] != '/')
{
size_t filelen = strlen (file);
+ if (__builtin_expect (filelen == 0, 0))
+ {
+ __set_errno (ENOENT);
+ return -1;
+ }
+
static const char procfd[] = "/proc/self/fd/%d/%s";
/* Buffer for the path name we are going to use. It consists of
- the string /proc/self/fd/
diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h b/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h
index 90b669ab60..dc2e0e6201 100644
--- a/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h
+++ b/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h
@@ -1,5 +1,5 @@
/* O_*, F_*, FD_* bit values for Linux/PowerPC.
- Copyright (C) 1995, 1996, 1997, 1998, 2000, 2003, 2004, 2006, 2007
+ Copyright (C) 1995, 1996, 1997, 1998, 2000, 2003, 2004, 2006, 2007, 2009
Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -166,6 +166,23 @@ struct flock64
};
#endif
+#ifdef __USE_GNU
+/* Owner types. */
+enum __pid_type
+ {
+ F_OWNER_TID = 0, /* Kernel thread. */
+ F_OWNER_PID, /* Process. */
+ F_OWNER_GID /* Process group. */
+ };
+
+/* Structure to use with F_GETOWN_EX and F_SETOWN_EX. */
+struct f_owner_ex
+ {
+ enum __pid_type type; /* Owner type of ID. */
+ __pid_t pid; /* ID of owner. */
+ };
+#endif
+
/* Define some more compatibility macros to be backward compatible with
BSD systems which did not managed to hide these kernel macros. */
#ifdef __USE_BSD
diff --git a/sysdeps/unix/sysv/linux/powerpc/fchownat.c b/sysdeps/unix/sysv/linux/powerpc/fchownat.c
index 67c570648a..46f6d97c6b 100644
--- a/sysdeps/unix/sysv/linux/powerpc/fchownat.c
+++ b/sysdeps/unix/sysv/linux/powerpc/fchownat.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2006, 2009 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
@@ -66,6 +66,12 @@ fchownat (int fd, const char *file, uid_t owner, gid_t group, int flag)
if (fd != AT_FDCWD && file[0] != '/')
{
size_t filelen = strlen (file);
+ if (__builtin_expect (filelen == 0, 0))
+ {
+ __set_errno (ENOENT);
+ return -1;
+ }
+
static const char procfd[] = "/proc/self/fd/%d/%s";
/* Buffer for the path name we are going to use. It consists of
- the string /proc/self/fd/
diff --git a/sysdeps/unix/sysv/linux/readlinkat.c b/sysdeps/unix/sysv/linux/readlinkat.c
index 1361596503..55abff143d 100644
--- a/sysdeps/unix/sysv/linux/readlinkat.c
+++ b/sysdeps/unix/sysv/linux/readlinkat.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2006, 2009 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
@@ -59,6 +59,12 @@ readlinkat (fd, path, buf, len)
if (fd != AT_FDCWD && path[0] != '/')
{
size_t pathlen = strlen (path);
+ if (__builtin_expect (pathlen == 0, 0))
+ {
+ __set_errno (ENOENT);
+ return -1;
+ }
+
static const char procfd[] = "/proc/self/fd/%d/%s";
/* Buffer for the path name we are going to use. It consists of
- the string /proc/self/fd/
diff --git a/sysdeps/unix/sysv/linux/renameat.c b/sysdeps/unix/sysv/linux/renameat.c
index 86bb75a7b0..160bdc4903 100644
--- a/sysdeps/unix/sysv/linux/renameat.c
+++ b/sysdeps/unix/sysv/linux/renameat.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2006, 2009 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
@@ -135,6 +135,12 @@ renameat (oldfd, old, newfd, new)
if (oldfd != AT_FDCWD && old[0] != '/')
{
size_t filelen = strlen (old);
+ if (__builtin_expect (filelen == 0, 0))
+ {
+ __set_errno (ENOENT);
+ return -1;
+ }
+
/* Buffer for the path name we are going to use. It consists of
- the string /proc/self/fd/
- the file descriptor number
@@ -154,6 +160,12 @@ renameat (oldfd, old, newfd, new)
if (newfd != AT_FDCWD && new[0] != '/')
{
size_t filelen = strlen (new);
+ if (__builtin_expect (filelen == 0, 0))
+ {
+ __set_errno (ENOENT);
+ return -1;
+ }
+
/* Buffer for the path name we are going to use. It consists of
- the string /proc/self/fd/
- the file descriptor number
diff --git a/sysdeps/unix/sysv/linux/s390/bits/fcntl.h b/sysdeps/unix/sysv/linux/s390/bits/fcntl.h
index ff5941df65..b50c00c882 100644
--- a/sysdeps/unix/sysv/linux/s390/bits/fcntl.h
+++ b/sysdeps/unix/sysv/linux/s390/bits/fcntl.h
@@ -1,5 +1,5 @@
/* O_*, F_*, FD_* bit values for Linux.
- Copyright (C) 2000,2001,2002,2004,2006,2007 Free Software Foundation, Inc.
+ Copyright (C) 2000,2001,2002,2004,2006,2007,2009 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
@@ -181,6 +181,23 @@ struct flock64
};
#endif
+#ifdef __USE_GNU
+/* Owner types. */
+enum __pid_type
+ {
+ F_OWNER_TID = 0, /* Kernel thread. */
+ F_OWNER_PID, /* Process. */
+ F_OWNER_GID /* Process group. */
+ };
+
+/* Structure to use with F_GETOWN_EX and F_SETOWN_EX. */
+struct f_owner_ex
+ {
+ enum __pid_type type; /* Owner type of ID. */
+ __pid_t pid; /* ID of owner. */
+ };
+#endif
+
/* Define some more compatibility macros to be backward compatible with
BSD systems which did not managed to hide these kernel macros. */
#ifdef __USE_BSD
diff --git a/sysdeps/unix/sysv/linux/s390/bits/siginfo.h b/sysdeps/unix/sysv/linux/s390/bits/siginfo.h
index 0b79853137..55b3f88c0a 100644
--- a/sysdeps/unix/sysv/linux/s390/bits/siginfo.h
+++ b/sysdeps/unix/sysv/linux/s390/bits/siginfo.h
@@ -1,5 +1,5 @@
/* siginfo_t, sigevent and constants. S/390 version.
- Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2002, 2003, 2009 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
@@ -26,7 +26,7 @@
#if (!defined __have_sigval_t \
&& (defined _SIGNAL_H || defined __need_siginfo_t \
- || defined __need_sigevent_t))
+ || defined __need_sigevent_t))
# define __have_sigval_t 1
/* Type for data associated with a signal. */
@@ -96,7 +96,7 @@ typedef struct siginfo
struct
{
void *si_addr; /* Faulting insn/memory ref. */
- int si_trapno;
+ int si_trapno;
} _sigfault;
/* SIGPOLL. */
@@ -282,6 +282,10 @@ typedef struct sigevent
{
int _pad[__SIGEV_PAD_SIZE];
+ /* When SIGEV_SIGNAL and SIGEV_THREAD_ID set, LWP ID of the
+ thread to receive the signal. */
+ __pid_t _tid;
+
struct
{
void (*_function) (sigval_t); /* Function to start. */
diff --git a/sysdeps/unix/sysv/linux/sh/bits/fcntl.h b/sysdeps/unix/sysv/linux/sh/bits/fcntl.h
index 35ef665998..d1718a17c9 100644
--- a/sysdeps/unix/sysv/linux/sh/bits/fcntl.h
+++ b/sysdeps/unix/sysv/linux/sh/bits/fcntl.h
@@ -1,5 +1,5 @@
/* O_*, F_*, FD_* bit values for Linux.
- Copyright (C) 1995, 1996, 1997, 1998, 2000, 2004, 2006, 2007
+ Copyright (C) 1995, 1996, 1997, 1998, 2000, 2004, 2006, 2007, 2009
Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -166,6 +166,23 @@ struct flock64
};
#endif
+#ifdef __USE_GNU
+/* Owner types. */
+enum __pid_type
+ {
+ F_OWNER_TID = 0, /* Kernel thread. */
+ F_OWNER_PID, /* Process. */
+ F_OWNER_GID /* Process group. */
+ };
+
+/* Structure to use with F_GETOWN_EX and F_SETOWN_EX. */
+struct f_owner_ex
+ {
+ enum __pid_type type; /* Owner type of ID. */
+ __pid_t pid; /* ID of owner. */
+ };
+#endif
+
/* Define some more compatibility macros to be backward compatible with
BSD systems which did not managed to hide these kernel macros. */
#ifdef __USE_BSD
diff --git a/sysdeps/unix/sysv/linux/sparc/bits/fcntl.h b/sysdeps/unix/sysv/linux/sparc/bits/fcntl.h
index d59744a55e..648bea8e58 100644
--- a/sysdeps/unix/sysv/linux/sparc/bits/fcntl.h
+++ b/sysdeps/unix/sysv/linux/sparc/bits/fcntl.h
@@ -1,5 +1,5 @@
/* O_*, F_*, FD_* bit values for Linux/SPARC.
- Copyright (C) 1995, 1996, 1997, 1998, 2000, 2003, 2004, 2006, 2007
+ Copyright (C) 1995, 1996, 1997, 1998, 2000, 2003, 2004, 2006, 2007, 2009
Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -185,6 +185,23 @@ struct flock64
};
#endif
+#ifdef __USE_GNU
+/* Owner types. */
+enum __pid_type
+ {
+ F_OWNER_TID = 0, /* Kernel thread. */
+ F_OWNER_PID, /* Process. */
+ F_OWNER_GID /* Process group. */
+ };
+
+/* Structure to use with F_GETOWN_EX and F_SETOWN_EX. */
+struct f_owner_ex
+ {
+ enum __pid_type type; /* Owner type of ID. */
+ __pid_t pid; /* ID of owner. */
+ };
+#endif
+
/* Define some more compatibility macros to be backward compatible with
BSD systems which did not managed to hide these kernel macros. */
#ifdef __USE_BSD
diff --git a/sysdeps/unix/sysv/linux/symlinkat.c b/sysdeps/unix/sysv/linux/symlinkat.c
index 4cfc924bfc..d2704777bd 100644
--- a/sysdeps/unix/sysv/linux/symlinkat.c
+++ b/sysdeps/unix/sysv/linux/symlinkat.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2006, 2009 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
@@ -57,6 +57,12 @@ symlinkat (from, tofd, to)
if (tofd != AT_FDCWD && to[0] != '/')
{
size_t tolen = strlen (to);
+ if (__builtin_expect (tolen == 0, 0))
+ {
+ __set_errno (ENOENT);
+ return -1;
+ }
+
static const char procfd[] = "/proc/self/fd/%d/%s";
/* Buffer for the path name we are going to use. It consists of
- the string /proc/self/fd/
diff --git a/sysdeps/unix/sysv/linux/ttyname.c b/sysdeps/unix/sysv/linux/ttyname.c
index 1b79787515..69af6adc65 100644
--- a/sysdeps/unix/sysv/linux/ttyname.c
+++ b/sysdeps/unix/sysv/linux/ttyname.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991,92,93,1996-2002,2006 Free Software Foundation, Inc.
+/* Copyright (C) 1991,92,93,1996-2002,2006,2009 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
@@ -59,6 +59,11 @@ getttyname (const char *dev, dev_t mydev, ino64_t myino, int save, int *dostat)
return NULL;
}
+ /* Prepare for the loop. If we already have a buffer copy the directory
+ name we look at into it. */
+ if (devlen < namelen)
+ *((char *) __mempcpy (getttyname_name, dev, devlen - 1)) = '/';
+
while ((d = __readdir64 (dirstream)) != NULL)
if ((d->d_fileno == myino || *dostat)
&& strcmp (d->d_name, "stdin")
diff --git a/sysdeps/unix/sysv/linux/unlinkat.c b/sysdeps/unix/sysv/linux/unlinkat.c
index 0a07a8a875..bb5f89810b 100644
--- a/sysdeps/unix/sysv/linux/unlinkat.c
+++ b/sysdeps/unix/sysv/linux/unlinkat.c
@@ -1,5 +1,5 @@
/* unlinkat -- Remove a link by relative name.
- Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+ Copyright (C) 2005, 2006, 2009 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
@@ -64,6 +64,12 @@ unlinkat (fd, file, flag)
if (fd != AT_FDCWD && file[0] != '/')
{
size_t filelen = strlen (file);
+ if (__builtin_expect (filelen == 0, 0))
+ {
+ __set_errno (ENOENT);
+ return -1;
+ }
+
static const char procfd[] = "/proc/self/fd/%d/%s";
/* Buffer for the path name we are going to use. It consists of
- the string /proc/self/fd/
diff --git a/sysdeps/unix/sysv/linux/wordsize-64/fxstatat.c b/sysdeps/unix/sysv/linux/wordsize-64/fxstatat.c
index 8b1c932ba9..cc41fdedc0 100644
--- a/sysdeps/unix/sysv/linux/wordsize-64/fxstatat.c
+++ b/sysdeps/unix/sysv/linux/wordsize-64/fxstatat.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2006, 2009 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
@@ -72,6 +72,12 @@ __fxstatat (int vers, int fd, const char *file, struct stat *st, int flag)
if (fd != AT_FDCWD && file[0] != '/')
{
size_t filelen = strlen (file);
+ if (__builtin_expect (filelen == 0, 0))
+ {
+ __set_errno (ENOENT);
+ return -1;
+ }
+
static const char procfd[] = "/proc/self/fd/%d/%s";
/* Buffer for the path name we are going to use. It consists of
- the string /proc/self/fd/
diff --git a/sysdeps/unix/sysv/linux/x86_64/bits/fcntl.h b/sysdeps/unix/sysv/linux/x86_64/bits/fcntl.h
index bc0f4d687b..e9806ee004 100644
--- a/sysdeps/unix/sysv/linux/x86_64/bits/fcntl.h
+++ b/sysdeps/unix/sysv/linux/x86_64/bits/fcntl.h
@@ -1,5 +1,5 @@
/* O_*, F_*, FD_* bit values for Linux/x86-64.
- Copyright (C) 2001, 2002, 2004, 2006, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2001,2002,2004,2006,2007,2009 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
@@ -180,6 +180,23 @@ struct flock64
};
#endif
+#ifdef __USE_GNU
+/* Owner types. */
+enum __pid_type
+ {
+ F_OWNER_TID = 0, /* Kernel thread. */
+ F_OWNER_PID, /* Process. */
+ F_OWNER_GID /* Process group. */
+ };
+
+/* Structure to use with F_GETOWN_EX and F_SETOWN_EX. */
+struct f_owner_ex
+ {
+ enum __pid_type type; /* Owner type of ID. */
+ __pid_t pid; /* ID of owner. */
+ };
+#endif
+
/* Define some more compatibility macros to be backward compatible with
BSD systems which did not managed to hide these kernel macros. */
#ifdef __USE_BSD
diff --git a/sysdeps/unix/sysv/linux/xmknodat.c b/sysdeps/unix/sysv/linux/xmknodat.c
index ef27b686cc..177b3db986 100644
--- a/sysdeps/unix/sysv/linux/xmknodat.c
+++ b/sysdeps/unix/sysv/linux/xmknodat.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2006, 2009 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
@@ -72,6 +72,12 @@ __xmknodat (int vers, int fd, const char *file, mode_t mode, dev_t *dev)
if (fd != AT_FDCWD && file[0] != '/')
{
size_t filelen = strlen (file);
+ if (__builtin_expect (filelen == 0, 0))
+ {
+ __set_errno (ENOENT);
+ return -1;
+ }
+
static const char procfd[] = "/proc/self/fd/%d/%s";
/* Buffer for the path name we are going to use. It consists of
- the string /proc/self/fd/
diff --git a/sysdeps/x86_64/multiarch/Makefile b/sysdeps/x86_64/multiarch/Makefile
index 0ded3b3261..364e7bbbd2 100644
--- a/sysdeps/x86_64/multiarch/Makefile
+++ b/sysdeps/x86_64/multiarch/Makefile
@@ -4,7 +4,8 @@ gen-as-const-headers += ifunc-defines.sym
endif
ifeq ($(subdir),string)
-sysdep_routines += stpncpy-c strncpy-c strcmp-ssse3 strncmp-ssse3
+sysdep_routines += stpncpy-c strncpy-c strcmp-ssse3 strncmp-ssse3 \
+ strend-sse4
ifeq (yes,$(config-cflags-sse4))
sysdep_routines += strcspn-c strpbrk-c strspn-c strstr-c strcasestr-c
CFLAGS-strcspn-c.c += -msse4
diff --git a/sysdeps/x86_64/multiarch/strchr.S b/sysdeps/x86_64/multiarch/strchr.S
new file mode 100644
index 0000000000..b35566d1a5
--- /dev/null
+++ b/sysdeps/x86_64/multiarch/strchr.S
@@ -0,0 +1,177 @@
+/* strchr with SSE4.2
+ Copyright (C) 2009 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 <sysdep.h>
+#include <ifunc-defines.h>
+
+
+/* Define multiple versions only for the definition in libc. */
+#ifndef NOT_IN_libc
+ .text
+ENTRY(strchr)
+ .type strchr, @gnu_indirect_function
+ cmpl $0, __cpu_features+KIND_OFFSET(%rip)
+ jne 1f
+ call __init_cpu_features
+1: leaq __strchr_sse2(%rip), %rax
+ testl $(1<<20), __cpu_features+CPUID_OFFSET+COMMON_CPUID_INDEX_1*CPUID_SIZE+CPUID_ECX_OFFSET(%rip)
+ jz 2f
+ leaq __strchr_sse42(%rip), %rax
+2: ret
+END(strchr)
+
+
+/*
+ This implementation uses SSE4 instructions to compare up to 16 bytes
+ at a time looking for the first occurrence of the character c in the
+ string s:
+
+ char *strchr (const char *s, int c);
+
+ We use 0xa:
+ _SIDD_SBYTE_OPS
+ | _SIDD_CMP_EQUAL_EACH
+ | _SIDD_LEAST_SIGNIFICANT
+ on pcmpistri to compare xmm/mem128
+
+ 0 1 2 3 4 5 6 7 8 9 A B C D E F
+ X X X X X X X X X X X X X X X X
+
+ against xmm
+
+ 0 1 2 3 4 5 6 7 8 9 A B C D E F
+ C C C C C C C C C C C C C C C C
+
+ to find out if the first 16byte data element has a byte C and the
+ offset of the first byte. There are 3 cases:
+
+ 1. The first 16byte data element has the byte C at the offset X.
+ 2. The first 16byte data element has EOS and doesn't have the byte C.
+ 3. The first 16byte data element is valid and doesn't have the byte C.
+
+ Here is the table of ECX, CFlag, ZFlag and SFlag for 3 cases:
+
+ case ECX CFlag ZFlag SFlag
+ 1 X 1 0/1 0
+ 2 16 0 1 0
+ 3 16 0 0 0
+
+ We exit from the loop for cases 1 and 2 with jbe which branches
+ when either CFlag or ZFlag is 1. If CFlag == 1, ECX has the offset
+ X for case 1. */
+
+ .section .text.sse4.2,"ax",@progbits
+ .align 16
+ .type __strchr_sse42, @function
+__strchr_sse42:
+ cfi_startproc
+ CALL_MCOUNT
+ testb %sil, %sil
+ je __strend_sse4
+ pxor %xmm2, %xmm2
+ movd %esi, %xmm1
+ movl %edi, %ecx
+ andl $15, %ecx
+ movq %rdi, %r8
+ je L(aligned_start)
+
+/* Handle unaligned string. */
+ andq $-16, %r8
+ pshufb %xmm2, %xmm1
+ movdqa (%r8), %xmm0
+ pcmpeqb %xmm0, %xmm2
+ pcmpeqb %xmm1, %xmm0
+ /* Find where NULL is. */
+ pmovmskb %xmm2, %edx
+ /* Check if there is a match. */
+ pmovmskb %xmm0, %esi
+ /* Remove the leading bytes. */
+ sarl %cl, %edx
+ sarl %cl, %esi
+ testl %esi, %esi
+ je L(unaligned_no_match)
+ /* Check which byte is a match. */
+ bsfl %esi, %eax
+ /* Is there a NULL? */
+ testl %edx, %edx
+ je L(unaligned_match)
+ bsfl %edx, %esi
+ cmpl %esi, %eax
+ /* Return NULL if NULL comes first. */
+ ja L(return_null)
+L(unaligned_match):
+ addq %rdi, %rax
+ ret
+
+ .p2align 4
+L(unaligned_no_match):
+ testl %edx, %edx
+ jne L(return_null)
+
+/* Loop start on aligned string. */
+L(loop):
+ addq $16, %r8
+L(aligned_start):
+ pcmpistri $0x2, (%r8), %xmm1
+ jbe L(wrap)
+ addq $16, %r8
+ pcmpistri $0x2, (%r8), %xmm1
+ jbe L(wrap)
+ addq $16, %r8
+ pcmpistri $0x2, (%r8), %xmm1
+ jbe L(wrap)
+ addq $16, %r8
+ pcmpistri $0x2, (%r8), %xmm1
+ jbe L(wrap)
+ jmp L(loop)
+L(wrap):
+ jc L(loop_exit)
+
+/* Return NULL. */
+L(return_null):
+ xorl %eax, %eax
+ ret
+
+/* Loop exit. */
+ .p2align 4
+L(loop_exit):
+ leaq (%r8,%rcx), %rax
+ ret
+ cfi_endproc
+ .size __strchr_sse42, .-__strchr_sse42
+
+
+# undef ENTRY
+# define ENTRY(name) \
+ .type __strchr_sse2, @function; \
+ .align 16; \
+ __strchr_sse2: cfi_startproc; \
+ CALL_MCOUNT
+# undef END
+# define END(name) \
+ cfi_endproc; .size __strchr_sse2, .-__strchr_sse2
+# undef libc_hidden_builtin_def
+/* It doesn't make sense to send libc-internal strchr calls through a PLT.
+ The speedup we get from using SSE4.2 instruction is likely eaten away
+ by the indirect call in the PLT. */
+# define libc_hidden_builtin_def(name) \
+ .globl __GI_strchr; __GI_strchr = __strchr_sse2
+#endif
+
+#include "../strchr.S"
diff --git a/sysdeps/x86_64/multiarch/strend-sse4.S b/sysdeps/x86_64/multiarch/strend-sse4.S
new file mode 100644
index 0000000000..c3220b3386
--- /dev/null
+++ b/sysdeps/x86_64/multiarch/strend-sse4.S
@@ -0,0 +1,49 @@
+/* Return the pointer to the end of string, using SSE4.2
+ Copyright (C) 2009 Free Software Foundation, Inc.
+ Contributed by Intel Corporation.
+ 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 <sysdep.h>
+#include "asm-syntax.h"
+
+ .section .text.sse4.2,"ax",@progbits
+ENTRY (__strend_sse4)
+ pxor %xmm2, %xmm2
+ movq %rdi, %rcx
+ andq $~15, %rdi
+ movdqa %xmm2, %xmm1
+ pcmpeqb (%rdi), %xmm2
+ orl $0xffffffff, %esi
+ subq %rdi, %rcx
+ shll %cl, %esi
+ pmovmskb %xmm2, %edx
+ andl %esi, %edx
+ jnz 1f
+
+2: pcmpistri $0x08, 16(%rdi), %xmm1
+ leaq 16(%rdi), %rdi
+ jnz 2b
+
+ leaq (%rdi,%rcx), %rax
+ ret
+
+1: bsfl %edx, %eax
+ addq %rdi, %rax
+ ret
+
+END (__strend_sse4)
diff --git a/sysdeps/x86_64/multiarch/strrchr.S b/sysdeps/x86_64/multiarch/strrchr.S
new file mode 100644
index 0000000000..f6665f34b7
--- /dev/null
+++ b/sysdeps/x86_64/multiarch/strrchr.S
@@ -0,0 +1,278 @@
+/* strrchr with SSE4.2
+ Copyright (C) 2009 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 <sysdep.h>
+#include <ifunc-defines.h>
+
+
+/* Define multiple versions only for the definition in libc and for
+ the DSO. In static binaries we need strrchr before the initialization
+ happened. */
+#if defined SHARED && !defined NOT_IN_libc
+ .text
+ENTRY(strrchr)
+ .type strrchr, @gnu_indirect_function
+ cmpl $0, __cpu_features+KIND_OFFSET(%rip)
+ jne 1f
+ call __init_cpu_features
+1: leaq __strrchr_sse2(%rip), %rax
+ testl $(1<<20), __cpu_features+CPUID_OFFSET+COMMON_CPUID_INDEX_1*CPUID_SIZE+CPUID_ECX_OFFSET(%rip)
+ jz 2f
+ leaq __strrchr_sse42(%rip), %rax
+2: ret
+END(strrchr)
+
+/*
+ This implementation uses SSE4 instructions to compare up to 16 bytes
+ at a time looking for the last occurrence of the character c in the
+ string s:
+
+ char *strrchr (const char *s, int c);
+
+ We use 0x4a:
+ _SIDD_SBYTE_OPS
+ | _SIDD_CMP_EQUAL_EACH
+ | _SIDD_MOST_SIGNIFICANT
+ on pcmpistri to compare xmm/mem128
+
+ 0 1 2 3 4 5 6 7 8 9 A B C D E F
+ X X X X X X X X X X X X X X X X
+
+ against xmm
+
+ 0 1 2 3 4 5 6 7 8 9 A B C D E F
+ C C C C C C C C C C C C C C C C
+
+ to find out if the first 16byte data element has a byte C and the
+ last offset. There are 4 cases:
+
+ 1. The first 16byte data element has EOS and has the byte C at the
+ last offset X.
+ 2. The first 16byte data element is valid and has the byte C at the
+ last offset X.
+ 3. The first 16byte data element has EOS and doesn't have the byte C.
+ 4. The first 16byte data element is valid and doesn't have the byte C.
+
+ Here is the table of ECX, CFlag, ZFlag and SFlag for 3 cases:
+
+ case ECX CFlag ZFlag SFlag
+ 1 X 1 1 0
+ 2 X 1 0 0
+ 3 16 0 1 0
+ 4 16 0 0 0
+
+ We exit from the loop for cases 1 and 3 with jz which branches
+ when ZFlag is 1. If CFlag == 1, ECX has the offset X for case 1. */
+
+
+ .section .text.sse4.2,"ax",@progbits
+ .align 16
+ .type __strrchr_sse42, @function
+__strrchr_sse42:
+ cfi_startproc
+ CALL_MCOUNT
+ testb %sil, %sil
+ je __strend_sse4
+ xor %eax,%eax /* RAX has the last occurrence of s. */
+ movd %esi, %xmm1
+ punpcklbw %xmm1, %xmm1
+ movl %edi, %esi
+ punpcklbw %xmm1, %xmm1
+ andl $15, %esi
+ pshufd $0, %xmm1, %xmm1
+ movq %rdi, %r8
+ je L(loop)
+
+/* Handle unaligned string using psrldq. */
+ leaq L(psrldq_table)(%rip), %rdx
+ andq $-16, %r8
+ movslq (%rdx,%rsi,4),%r9
+ movdqa (%r8), %xmm0
+ addq %rdx, %r9
+ jmp *%r9
+
+/* Handle unaligned string with offset 1 using psrldq. */
+ .p2align 4
+L(psrldq_1):
+ psrldq $1, %xmm0
+
+ .p2align 4
+L(unaligned_pcmpistri):
+ pcmpistri $0x4a, %xmm1, %xmm0
+ jnc L(unaligned_no_byte)
+ leaq (%rdi,%rcx), %rax
+L(unaligned_no_byte):
+ /* Find the length of the unaligned string. */
+ pcmpistri $0x3a, %xmm0, %xmm0
+ movl $16, %edx
+ subl %esi, %edx
+ cmpl %ecx, %edx
+ /* Return RAX if the unaligned fragment to next 16B already
+ contain the NULL terminator. */
+ jg L(exit)
+ addq $16, %r8
+
+/* Loop start on aligned string. */
+ .p2align 4
+L(loop):
+ pcmpistri $0x4a, (%r8), %xmm1
+ jbe L(match_or_eos)
+ addq $16, %r8
+ jmp L(loop)
+ .p2align 4
+L(match_or_eos):
+ je L(had_eos)
+L(match_no_eos):
+ leaq (%r8,%rcx), %rax
+ addq $16, %r8
+ jmp L(loop)
+ .p2align 4
+L(had_eos):
+ jnc L(exit)
+ leaq (%r8,%rcx), %rax
+ .p2align 4
+L(exit):
+ ret
+
+/* Handle unaligned string with offset 15 using psrldq. */
+ .p2align 4
+L(psrldq_15):
+ psrldq $15, %xmm0
+ jmp L(unaligned_pcmpistri)
+
+/* Handle unaligned string with offset 14 using psrldq. */
+ .p2align 4
+L(psrldq_14):
+ psrldq $14, %xmm0
+ jmp L(unaligned_pcmpistri)
+
+/* Handle unaligned string with offset 13 using psrldq. */
+ .p2align 4
+L(psrldq_13):
+ psrldq $13, %xmm0
+ jmp L(unaligned_pcmpistri)
+
+/* Handle unaligned string with offset 12 using psrldq. */
+ .p2align 4
+L(psrldq_12):
+ psrldq $12, %xmm0
+ jmp L(unaligned_pcmpistri)
+
+/* Handle unaligned string with offset 11 using psrldq. */
+ .p2align 4
+L(psrldq_11):
+ psrldq $11, %xmm0
+ jmp L(unaligned_pcmpistri)
+
+/* Handle unaligned string with offset 10 using psrldq. */
+ .p2align 4
+L(psrldq_10):
+ psrldq $10, %xmm0
+ jmp L(unaligned_pcmpistri)
+
+/* Handle unaligned string with offset 9 using psrldq. */
+ .p2align 4
+L(psrldq_9):
+ psrldq $9, %xmm0
+ jmp L(unaligned_pcmpistri)
+
+/* Handle unaligned string with offset 8 using psrldq. */
+ .p2align 4
+L(psrldq_8):
+ psrldq $8, %xmm0
+ jmp L(unaligned_pcmpistri)
+
+/* Handle unaligned string with offset 7 using psrldq. */
+ .p2align 4
+L(psrldq_7):
+ psrldq $7, %xmm0
+ jmp L(unaligned_pcmpistri)
+
+/* Handle unaligned string with offset 6 using psrldq. */
+ .p2align 4
+L(psrldq_6):
+ psrldq $6, %xmm0
+ jmp L(unaligned_pcmpistri)
+
+/* Handle unaligned string with offset 5 using psrldq. */
+ .p2align 4
+L(psrldq_5):
+ psrldq $5, %xmm0
+ jmp L(unaligned_pcmpistri)
+
+/* Handle unaligned string with offset 4 using psrldq. */
+ .p2align 4
+L(psrldq_4):
+ psrldq $4, %xmm0
+ jmp L(unaligned_pcmpistri)
+
+/* Handle unaligned string with offset 3 using psrldq. */
+ .p2align 4
+L(psrldq_3):
+ psrldq $3, %xmm0
+ jmp L(unaligned_pcmpistri)
+
+/* Handle unaligned string with offset 2 using psrldq. */
+ .p2align 4
+L(psrldq_2):
+ psrldq $2, %xmm0
+ jmp L(unaligned_pcmpistri)
+
+ cfi_endproc
+ .size __strrchr_sse42, .-__strrchr_sse42
+
+ .section .rodata.sse4.2,"a",@progbits
+ .p2align 4
+L(psrldq_table):
+ .int L(loop) - L(psrldq_table)
+ .int L(psrldq_1) - L(psrldq_table)
+ .int L(psrldq_2) - L(psrldq_table)
+ .int L(psrldq_3) - L(psrldq_table)
+ .int L(psrldq_4) - L(psrldq_table)
+ .int L(psrldq_5) - L(psrldq_table)
+ .int L(psrldq_6) - L(psrldq_table)
+ .int L(psrldq_7) - L(psrldq_table)
+ .int L(psrldq_8) - L(psrldq_table)
+ .int L(psrldq_9) - L(psrldq_table)
+ .int L(psrldq_10) - L(psrldq_table)
+ .int L(psrldq_11) - L(psrldq_table)
+ .int L(psrldq_12) - L(psrldq_table)
+ .int L(psrldq_13) - L(psrldq_table)
+ .int L(psrldq_14) - L(psrldq_table)
+ .int L(psrldq_15) - L(psrldq_table)
+
+
+# undef ENTRY
+# define ENTRY(name) \
+ .type __strrchr_sse2, @function; \
+ .align 16; \
+ __strrchr_sse2: cfi_startproc; \
+ CALL_MCOUNT
+# undef END
+# define END(name) \
+ cfi_endproc; .size __strrchr_sse2, .-__strrchr_sse2
+# undef libc_hidden_builtin_def
+/* It doesn't make sense to send libc-internal strrchr calls through a PLT.
+ The speedup we get from using SSE4.2 instruction is likely eaten away
+ by the indirect call in the PLT. */
+# define libc_hidden_builtin_def(name) \
+ .globl __GI_strrchr; __GI_strrchr = __strrchr_sse2
+#endif
+
+#include "../strrchr.S"