summaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2004-10-18 09:58:59 +0000
committerJakub Jelinek <jakub@redhat.com>2004-10-18 09:58:59 +0000
commit56c4396a6e1568a5511ac43873fa3c9e1ebfa8d1 (patch)
treef2d0f6e1aaf9794668b53c6456fcacbbacd63805 /sysdeps
parent4ce1a5c9712b4d7616058e708630c33744f983f6 (diff)
Updated to fedora-glibc-20041018T0940
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/alpha/dl-machine.h6
-rw-r--r--sysdeps/generic/memcpy_chk.c66
-rw-r--r--sysdeps/generic/memmove_chk.c98
-rw-r--r--sysdeps/generic/mempcpy_chk.c67
-rw-r--r--sysdeps/generic/memset_chk.c92
-rw-r--r--sysdeps/generic/readonly-area.c29
-rw-r--r--sysdeps/generic/stpcpy_chk.c45
-rw-r--r--sysdeps/generic/strcat_chk.c58
-rw-r--r--sysdeps/generic/strcpy_chk.c46
-rw-r--r--sysdeps/generic/strncat_chk.c100
-rw-r--r--sysdeps/generic/strncpy_chk.c89
-rw-r--r--sysdeps/i386/i686/memcpy.S9
-rw-r--r--sysdeps/i386/i686/memcpy_chk.S35
-rw-r--r--sysdeps/i386/i686/memmove.S9
-rw-r--r--sysdeps/i386/i686/memmove_chk.S35
-rw-r--r--sysdeps/i386/i686/mempcpy.S7
-rw-r--r--sysdeps/i386/i686/mempcpy_chk.S35
-rw-r--r--sysdeps/i386/i686/memset.S7
-rw-r--r--sysdeps/i386/i686/memset_chk.S35
-rw-r--r--sysdeps/mach/hurd/Makefile6
-rw-r--r--sysdeps/powerpc/powerpc32/dl-machine.c8
-rw-r--r--sysdeps/unix/sysv/linux/adjtime.c7
-rw-r--r--sysdeps/unix/sysv/linux/alpha/adjtime.c11
-rw-r--r--sysdeps/unix/sysv/linux/alpha/register-dump.h161
-rw-r--r--sysdeps/unix/sysv/linux/alpha/sigcontextinfo.h12
-rw-r--r--sysdeps/unix/sysv/linux/i386/syscall.S10
-rw-r--r--sysdeps/unix/sysv/linux/i386/sysdep.h7
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips32/sysdep.h5
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h5
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips64/n64/sysdep.h5
-rw-r--r--sysdeps/unix/sysv/linux/readonly-area.c90
-rw-r--r--sysdeps/x86_64/memcpy.S6
-rw-r--r--sysdeps/x86_64/memcpy_chk.S34
-rw-r--r--sysdeps/x86_64/mempcpy.S1
-rw-r--r--sysdeps/x86_64/mempcpy_chk.S34
-rw-r--r--sysdeps/x86_64/memset.S8
-rw-r--r--sysdeps/x86_64/memset_chk.S34
-rw-r--r--sysdeps/x86_64/stpcpy_chk.S3
-rw-r--r--sysdeps/x86_64/strcpy_chk.S211
39 files changed, 1486 insertions, 40 deletions
diff --git a/sysdeps/alpha/dl-machine.h b/sysdeps/alpha/dl-machine.h
index 7c5f3c1518..780a3a57fd 100644
--- a/sysdeps/alpha/dl-machine.h
+++ b/sysdeps/alpha/dl-machine.h
@@ -507,7 +507,7 @@ elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc,
/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
MAP is the object containing the reloc. */
-static inline void
+auto inline void
elf_machine_rela (struct link_map *map,
const Elf64_Rela *reloc,
const Elf64_Sym *sym,
@@ -645,7 +645,7 @@ elf_machine_rela (struct link_map *map,
can be skipped. */
#define ELF_MACHINE_REL_RELATIVE 1
-static inline void
+auto inline void
elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
void *const reloc_addr_arg)
{
@@ -661,7 +661,7 @@ elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
memcpy (reloc_addr_arg, &reloc_addr_val, 8);
}
-static inline void
+auto inline void
elf_machine_lazy_rel (struct link_map *map,
Elf64_Addr l_addr, const Elf64_Rela *reloc)
{
diff --git a/sysdeps/generic/memcpy_chk.c b/sysdeps/generic/memcpy_chk.c
new file mode 100644
index 0000000000..638cd0e4fb
--- /dev/null
+++ b/sysdeps/generic/memcpy_chk.c
@@ -0,0 +1,66 @@
+/* Copy memory to memory until the specified number of bytes
+ has been copied with error checking. Overlap is NOT handled correctly.
+ Copyright (C) 1991, 1997, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Torbjorn Granlund (tege@sics.se).
+
+ 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 <string.h>
+#include <memcopy.h>
+#include <pagecopy.h>
+
+void *
+__memcpy_chk (dstpp, srcpp, len, dstlen)
+ void *dstpp;
+ const void *srcpp;
+ size_t len;
+ size_t dstlen;
+{
+ if (__builtin_expect (dstlen < len, 0))
+ __chk_fail ();
+
+ unsigned long int dstp = (long int) dstpp;
+ unsigned long int srcp = (long int) srcpp;
+
+ /* Copy from the beginning to the end. */
+
+ /* If there not too few bytes to copy, use word copy. */
+ if (len >= OP_T_THRES)
+ {
+ /* Copy just a few bytes to make DSTP aligned. */
+ len -= (-dstp) % OPSIZ;
+ BYTE_COPY_FWD (dstp, srcp, (-dstp) % OPSIZ);
+
+ /* Copy whole pages from SRCP to DSTP by virtual address manipulation,
+ as much as possible. */
+
+ PAGE_COPY_FWD_MAYBE (dstp, srcp, len, len);
+
+ /* Copy from SRCP to DSTP taking advantage of the known alignment of
+ DSTP. Number of bytes remaining is put in the third argument,
+ i.e. in LEN. This number may vary from machine to machine. */
+
+ WORD_COPY_FWD (dstp, srcp, len, len);
+
+ /* Fall out and copy the tail. */
+ }
+
+ /* There are just a few bytes to copy. Use byte memory operations. */
+ BYTE_COPY_FWD (dstp, srcp, len);
+
+ return dstpp;
+}
diff --git a/sysdeps/generic/memmove_chk.c b/sysdeps/generic/memmove_chk.c
new file mode 100644
index 0000000000..f3b74d23d9
--- /dev/null
+++ b/sysdeps/generic/memmove_chk.c
@@ -0,0 +1,98 @@
+/* Copy memory to memory until the specified number of bytes
+ has been copied with error checking. Overlap is handled correctly.
+ Copyright (C) 1991,1995,1996,1997,2003,2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Torbjorn Granlund (tege@sics.se).
+
+ 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 <string.h>
+#include <memcopy.h>
+#include <pagecopy.h>
+
+void *
+__memmove_chk (dest, src, len, destlen)
+ void *dest;
+ const void *src;
+ size_t len;
+ size_t destlen;
+{
+ if (__builtin_expect (destlen < len, 0))
+ __chk_fail ();
+
+ unsigned long int dstp = (long int) dest;
+ unsigned long int srcp = (long int) src;
+
+ /* This test makes the forward copying code be used whenever possible.
+ Reduces the working set. */
+ if (dstp - srcp >= len) /* *Unsigned* compare! */
+ {
+ /* Copy from the beginning to the end. */
+
+ /* If there not too few bytes to copy, use word copy. */
+ if (len >= OP_T_THRES)
+ {
+ /* Copy just a few bytes to make DSTP aligned. */
+ len -= (-dstp) % OPSIZ;
+ BYTE_COPY_FWD (dstp, srcp, (-dstp) % OPSIZ);
+
+ /* Copy whole pages from SRCP to DSTP by virtual address
+ manipulation, as much as possible. */
+
+ PAGE_COPY_FWD_MAYBE (dstp, srcp, len, len);
+
+ /* Copy from SRCP to DSTP taking advantage of the known
+ alignment of DSTP. Number of bytes remaining is put
+ in the third argument, i.e. in LEN. This number may
+ vary from machine to machine. */
+
+ WORD_COPY_FWD (dstp, srcp, len, len);
+
+ /* Fall out and copy the tail. */
+ }
+
+ /* There are just a few bytes to copy. Use byte memory operations. */
+ BYTE_COPY_FWD (dstp, srcp, len);
+ }
+ else
+ {
+ /* Copy from the end to the beginning. */
+ srcp += len;
+ dstp += len;
+
+ /* If there not too few bytes to copy, use word copy. */
+ if (len >= OP_T_THRES)
+ {
+ /* Copy just a few bytes to make DSTP aligned. */
+ len -= dstp % OPSIZ;
+ BYTE_COPY_BWD (dstp, srcp, dstp % OPSIZ);
+
+ /* Copy from SRCP to DSTP taking advantage of the known
+ alignment of DSTP. Number of bytes remaining is put
+ in the third argument, i.e. in LEN. This number may
+ vary from machine to machine. */
+
+ WORD_COPY_BWD (dstp, srcp, len, len);
+
+ /* Fall out and copy the tail. */
+ }
+
+ /* There are just a few bytes to copy. Use byte memory operations. */
+ BYTE_COPY_BWD (dstp, srcp, len);
+ }
+
+ return dest;
+}
diff --git a/sysdeps/generic/mempcpy_chk.c b/sysdeps/generic/mempcpy_chk.c
new file mode 100644
index 0000000000..5297bbab92
--- /dev/null
+++ b/sysdeps/generic/mempcpy_chk.c
@@ -0,0 +1,67 @@
+/* Copy memory to memory until the specified number of bytes
+ has been copied, return pointer to following byte, with error checking.
+ Overlap is NOT handled correctly.
+ Copyright (C) 1991, 1997, 1998, 2002, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Torbjorn Granlund (tege@sics.se).
+
+ 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 <string.h>
+#include <memcopy.h>
+#include <pagecopy.h>
+
+void *
+__mempcpy_chk (dstpp, srcpp, len, dstlen)
+ void *dstpp;
+ const void *srcpp;
+ size_t len;
+ size_t dstlen;
+{
+ if (__builtin_expect (dstlen < len, 0))
+ __chk_fail ();
+
+ unsigned long int dstp = (long int) dstpp;
+ unsigned long int srcp = (long int) srcpp;
+
+ /* Copy from the beginning to the end. */
+
+ /* If there not too few bytes to copy, use word copy. */
+ if (len >= OP_T_THRES)
+ {
+ /* Copy just a few bytes to make DSTP aligned. */
+ len -= (-dstp) % OPSIZ;
+ BYTE_COPY_FWD (dstp, srcp, (-dstp) % OPSIZ);
+
+ /* Copy whole pages from SRCP to DSTP by virtual address manipulation,
+ as much as possible. */
+
+ PAGE_COPY_FWD_MAYBE (dstp, srcp, len, len);
+
+ /* Copy from SRCP to DSTP taking advantage of the known alignment of
+ DSTP. Number of bytes remaining is put in the third argument,
+ i.e. in LEN. This number may vary from machine to machine. */
+
+ WORD_COPY_FWD (dstp, srcp, len, len);
+
+ /* Fall out and copy the tail. */
+ }
+
+ /* There are just a few bytes to copy. Use byte memory operations. */
+ BYTE_COPY_FWD (dstp, srcp, len);
+
+ return (void *) dstp;
+}
diff --git a/sysdeps/generic/memset_chk.c b/sysdeps/generic/memset_chk.c
new file mode 100644
index 0000000000..c311914395
--- /dev/null
+++ b/sysdeps/generic/memset_chk.c
@@ -0,0 +1,92 @@
+/* Copyright (C) 1991, 1997, 2003, 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. */
+
+#include <string.h>
+#include <memcopy.h>
+
+void *
+__memset_chk (dstpp, c, len, dstlen)
+ void *dstpp;
+ int c;
+ size_t len;
+ size_t dstlen;
+{
+ if (__builtin_expect (dstlen < len, 0))
+ __chk_fail ();
+
+ long int dstp = (long int) dstpp;
+
+ if (len >= 8)
+ {
+ size_t xlen;
+ op_t cccc;
+
+ cccc = (unsigned char) c;
+ cccc |= cccc << 8;
+ cccc |= cccc << 16;
+ if (OPSIZ > 4)
+ /* Do the shift in two steps to avoid warning if long has 32 bits. */
+ cccc |= (cccc << 16) << 16;
+
+ /* There are at least some bytes to set.
+ No need to test for LEN == 0 in this alignment loop. */
+ while (dstp % OPSIZ != 0)
+ {
+ ((byte *) dstp)[0] = c;
+ dstp += 1;
+ len -= 1;
+ }
+
+ /* Write 8 `op_t' per iteration until less than 8 `op_t' remain. */
+ xlen = len / (OPSIZ * 8);
+ while (xlen > 0)
+ {
+ ((op_t *) dstp)[0] = cccc;
+ ((op_t *) dstp)[1] = cccc;
+ ((op_t *) dstp)[2] = cccc;
+ ((op_t *) dstp)[3] = cccc;
+ ((op_t *) dstp)[4] = cccc;
+ ((op_t *) dstp)[5] = cccc;
+ ((op_t *) dstp)[6] = cccc;
+ ((op_t *) dstp)[7] = cccc;
+ dstp += 8 * OPSIZ;
+ xlen -= 1;
+ }
+ len %= OPSIZ * 8;
+
+ /* Write 1 `op_t' per iteration until less than OPSIZ bytes remain. */
+ xlen = len / OPSIZ;
+ while (xlen > 0)
+ {
+ ((op_t *) dstp)[0] = cccc;
+ dstp += OPSIZ;
+ xlen -= 1;
+ }
+ len %= OPSIZ;
+ }
+
+ /* Write the last few bytes. */
+ while (len > 0)
+ {
+ ((byte *) dstp)[0] = c;
+ dstp += 1;
+ len -= 1;
+ }
+
+ return dstpp;
+}
diff --git a/sysdeps/generic/readonly-area.c b/sysdeps/generic/readonly-area.c
new file mode 100644
index 0000000000..df5b96015c
--- /dev/null
+++ b/sysdeps/generic/readonly-area.c
@@ -0,0 +1,29 @@
+/* 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. */
+
+/* Return 1 if the whole area PTR .. PTR+SIZE is not writable.
+ Return -1 if it is writable. */
+
+#include <stdlib.h>
+
+int
+__readonly_str (const void *ptr, size_t size)
+{
+ /* The conservative answer is that all strings are writable. */
+ return -1;
+}
diff --git a/sysdeps/generic/stpcpy_chk.c b/sysdeps/generic/stpcpy_chk.c
new file mode 100644
index 0000000000..dacda0115a
--- /dev/null
+++ b/sysdeps/generic/stpcpy_chk.c
@@ -0,0 +1,45 @@
+/* Copyright (C) 1992, 1995, 1997, 2002, 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. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+
+
+/* Copy SRC to DEST, returning the address of the terminating '\0' in DEST. */
+char *
+__stpcpy_chk (dest, src, destlen)
+ char *dest;
+ const char *src;
+ size_t destlen;
+{
+ register char *d = dest;
+ register const char *s = src;
+
+ do
+ {
+ if (__builtin_expect (destlen-- == 0, 0))
+ __chk_fail ();
+ *d++ = *s;
+ }
+ while (*s++ != '\0');
+
+ return d - 1;
+}
diff --git a/sysdeps/generic/strcat_chk.c b/sysdeps/generic/strcat_chk.c
new file mode 100644
index 0000000000..b3fb3470b7
--- /dev/null
+++ b/sysdeps/generic/strcat_chk.c
@@ -0,0 +1,58 @@
+/* Copyright (C) 1991, 1997, 2003, 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. */
+
+#include <string.h>
+#include <memcopy.h>
+
+
+/* Append SRC on the end of DEST. */
+char *
+__strcat_chk (dest, src, destlen)
+ char *dest;
+ const char *src;
+ size_t destlen;
+{
+ char *s1 = dest;
+ const char *s2 = src;
+ reg_char c;
+
+ /* Find the end of the string. */
+ do
+ {
+ if (__builtin_expect (destlen-- == 0, 0))
+ __chk_fail ();
+ c = *s1++;
+ }
+ while (c != '\0');
+
+ /* Make S1 point before the next character, so we can increment
+ it while memory is read (wins on pipelined cpus). */
+ ++destlen;
+ s1 -= 2;
+
+ do
+ {
+ if (__builtin_expect (destlen-- == 0, 0))
+ __chk_fail ();
+ c = *s2++;
+ *++s1 = c;
+ }
+ while (c != '\0');
+
+ return dest;
+}
diff --git a/sysdeps/generic/strcpy_chk.c b/sysdeps/generic/strcpy_chk.c
new file mode 100644
index 0000000000..5c1ae44cd0
--- /dev/null
+++ b/sysdeps/generic/strcpy_chk.c
@@ -0,0 +1,46 @@
+/* Copyright (C) 1991, 1997, 2000, 2003, 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. */
+
+#include <stddef.h>
+#include <string.h>
+#include <memcopy.h>
+
+#undef strcpy
+
+/* Copy SRC to DEST with checking of destination buffer overflow. */
+char *
+__strcpy_chk (dest, src, destlen)
+ char *dest;
+ const char *src;
+ size_t destlen;
+{
+ reg_char c;
+ char *s = (char *) src;
+ const ptrdiff_t off = dest - s - 1;
+
+ do
+ {
+ if (__builtin_expect (destlen-- == 0, 0))
+ __chk_fail ();
+ c = *s++;
+ s[off] = c;
+ }
+ while (c != '\0');
+
+ return dest;
+}
diff --git a/sysdeps/generic/strncat_chk.c b/sysdeps/generic/strncat_chk.c
new file mode 100644
index 0000000000..953b435a4b
--- /dev/null
+++ b/sysdeps/generic/strncat_chk.c
@@ -0,0 +1,100 @@
+/* Copyright (C) 1991, 1997, 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. */
+
+#include <string.h>
+
+#include <memcopy.h>
+
+
+char *
+__strncat_chk (s1, s2, n, s1len)
+ char *s1;
+ const char *s2;
+ size_t n;
+ size_t s1len;
+{
+ reg_char c;
+ char *s = s1;
+
+ /* Find the end of S1. */
+ do
+ {
+ if (__builtin_expect (s1len-- == 0, 0))
+ __chk_fail ();
+ c = *s1++;
+ }
+ while (c != '\0');
+
+ /* Make S1 point before next character, so we can increment
+ it while memory is read (wins on pipelined cpus). */
+ ++s1len;
+ s1 -= 2;
+
+ if (n >= 4)
+ {
+ size_t n4 = n >> 2;
+ do
+ {
+ if (__builtin_expect (s1len-- == 0, 0))
+ __chk_fail ();
+ c = *s2++;
+ *++s1 = c;
+ if (c == '\0')
+ return s;
+ if (__builtin_expect (s1len-- == 0, 0))
+ __chk_fail ();
+ c = *s2++;
+ *++s1 = c;
+ if (c == '\0')
+ return s;
+ if (__builtin_expect (s1len-- == 0, 0))
+ __chk_fail ();
+ c = *s2++;
+ *++s1 = c;
+ if (c == '\0')
+ return s;
+ if (__builtin_expect (s1len-- == 0, 0))
+ __chk_fail ();
+ c = *s2++;
+ *++s1 = c;
+ if (c == '\0')
+ return s;
+ } while (--n4 > 0);
+ n &= 3;
+ }
+
+ while (n > 0)
+ {
+ if (__builtin_expect (s1len-- == 0, 0))
+ __chk_fail ();
+ c = *s2++;
+ *++s1 = c;
+ if (c == '\0')
+ return s;
+ n--;
+ }
+
+ if (c != '\0')
+ {
+ if (__builtin_expect (s1len-- == 0, 0))
+ __chk_fail ();
+ *++s1 = '\0';
+ }
+
+ return s;
+}
diff --git a/sysdeps/generic/strncpy_chk.c b/sysdeps/generic/strncpy_chk.c
new file mode 100644
index 0000000000..bdede7738b
--- /dev/null
+++ b/sysdeps/generic/strncpy_chk.c
@@ -0,0 +1,89 @@
+/* Copyright (C) 1991, 1997, 2003, 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. */
+
+#include <string.h>
+#include <memcopy.h>
+
+
+char *
+__strncpy_chk (s1, s2, n, s1len)
+ char *s1;
+ const char *s2;
+ size_t n;
+ size_t s1len;
+{
+ reg_char c;
+ char *s = s1;
+
+ if (__builtin_expect (s1len < n, 0))
+ __chk_fail ();
+
+ --s1;
+
+ if (n >= 4)
+ {
+ size_t n4 = n >> 2;
+
+ for (;;)
+ {
+ c = *s2++;
+ *++s1 = c;
+ if (c == '\0')
+ break;
+ c = *s2++;
+ *++s1 = c;
+ if (c == '\0')
+ break;
+ c = *s2++;
+ *++s1 = c;
+ if (c == '\0')
+ break;
+ c = *s2++;
+ *++s1 = c;
+ if (c == '\0')
+ break;
+ if (--n4 == 0)
+ goto last_chars;
+ }
+ n = n - (s1 - s) - 1;
+ if (n == 0)
+ return s;
+ goto zero_fill;
+ }
+
+ last_chars:
+ n &= 3;
+ if (n == 0)
+ return s;
+
+ do
+ {
+ c = *s2++;
+ *++s1 = c;
+ if (--n == 0)
+ return s;
+ }
+ while (c != '\0');
+
+ zero_fill:
+ do
+ *++s1 = '\0';
+ while (--n > 0);
+
+ return s;
+}
diff --git a/sysdeps/i386/i686/memcpy.S b/sysdeps/i386/i686/memcpy.S
index 865967c5c8..00e84ec2e5 100644
--- a/sysdeps/i386/i686/memcpy.S
+++ b/sysdeps/i386/i686/memcpy.S
@@ -1,7 +1,7 @@
/* Copy memory block and return pointer to beginning of destination block
For Intel 80x86, x>=6.
This file is part of the GNU C Library.
- Copyright (C) 1999, 2000, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
The GNU C Library is free software; you can redistribute it and/or
@@ -31,6 +31,13 @@
#define LEN SRC+PTR_SIZE
.text
+#if defined PIC && !defined NOT_IN_libc
+ENTRY (__memcpy_chk)
+ movl 12(%esp), %eax
+ cmpl %eax, 16(%esp)
+ jb HIDDEN_JUMPTARGET (__chk_fail)
+END (__memcpy_chk)
+#endif
ENTRY (BP_SYM (memcpy))
ENTER
diff --git a/sysdeps/i386/i686/memcpy_chk.S b/sysdeps/i386/i686/memcpy_chk.S
new file mode 100644
index 0000000000..561263f9bf
--- /dev/null
+++ b/sysdeps/i386/i686/memcpy_chk.S
@@ -0,0 +1,35 @@
+/* Checking memcpy for x86-64.
+ 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. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+
+#ifndef PIC
+ /* For libc.so this is defined in memcpy.S.
+ For libc.a, this is a separate source to avoid
+ memcpy bringing in __chk_fail and all routines
+ it calls. */
+ .text
+ENTRY (__memcpy_chk)
+ movl 12(%esp), %eax
+ cmpl %eax, 16(%esp)
+ jb __chk_fail
+ jmp memcpy
+END (__memcpy_chk)
+#endif
diff --git a/sysdeps/i386/i686/memmove.S b/sysdeps/i386/i686/memmove.S
index 421b4effda..951e139ad4 100644
--- a/sysdeps/i386/i686/memmove.S
+++ b/sysdeps/i386/i686/memmove.S
@@ -1,7 +1,7 @@
/* Copy memory block and return pointer to beginning of destination block
For Intel 80x86, x>=6.
This file is part of the GNU C Library.
- Copyright (C) 2003 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 2003.
The GNU C Library is free software; you can redistribute it and/or
@@ -31,6 +31,13 @@
#define LEN SRC+PTR_SIZE
.text
+#if defined PIC && !defined NOT_IN_libc
+ENTRY (__memmove_chk)
+ movl 12(%esp), %eax
+ cmpl %eax, 16(%esp)
+ jb HIDDEN_JUMPTARGET (__chk_fail)
+END (__memmove_chk)
+#endif
ENTRY (BP_SYM (memmove))
ENTER
diff --git a/sysdeps/i386/i686/memmove_chk.S b/sysdeps/i386/i686/memmove_chk.S
new file mode 100644
index 0000000000..23382ea8bf
--- /dev/null
+++ b/sysdeps/i386/i686/memmove_chk.S
@@ -0,0 +1,35 @@
+/* Checking memmove for x86-64.
+ 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. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+
+#ifndef PIC
+ /* For libc.so this is defined in memmove.S.
+ For libc.a, this is a separate source to avoid
+ memmove bringing in __chk_fail and all routines
+ it calls. */
+ .text
+ENTRY (__memmove_chk)
+ movl 12(%esp), %eax
+ cmpl %eax, 16(%esp)
+ jb __chk_fail
+ jmp memmove
+END (__memmove_chk)
+#endif
diff --git a/sysdeps/i386/i686/mempcpy.S b/sysdeps/i386/i686/mempcpy.S
index 3ea89d4a17..843a35823a 100644
--- a/sysdeps/i386/i686/mempcpy.S
+++ b/sysdeps/i386/i686/mempcpy.S
@@ -31,6 +31,13 @@
#define LEN SRC+PTR_SIZE
.text
+#if defined PIC && !defined NOT_IN_libc
+ENTRY (__mempcpy_chk)
+ movl 12(%esp), %eax
+ cmpl %eax, 16(%esp)
+ jb HIDDEN_JUMPTARGET (__chk_fail)
+END (__mempcpy_chk)
+#endif
ENTRY (BP_SYM (__mempcpy))
ENTER
diff --git a/sysdeps/i386/i686/mempcpy_chk.S b/sysdeps/i386/i686/mempcpy_chk.S
new file mode 100644
index 0000000000..dc9c6095f0
--- /dev/null
+++ b/sysdeps/i386/i686/mempcpy_chk.S
@@ -0,0 +1,35 @@
+/* Checking mempcpy for x86-64.
+ 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. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+
+#ifndef PIC
+ /* For libc.so this is defined in mempcpy.S.
+ For libc.a, this is a separate source to avoid
+ mempcpy bringing in __chk_fail and all routines
+ it calls. */
+ .text
+ENTRY (__mempcpy_chk)
+ movl 12(%esp), %eax
+ cmpl %eax, 16(%esp)
+ jb __chk_fail
+ jmp mempcpy
+END (__mempcpy_chk)
+#endif
diff --git a/sysdeps/i386/i686/memset.S b/sysdeps/i386/i686/memset.S
index 4ddcb39731..561188ffec 100644
--- a/sysdeps/i386/i686/memset.S
+++ b/sysdeps/i386/i686/memset.S
@@ -39,6 +39,13 @@
#endif
.text
+#if defined PIC && !defined NOT_IN_libc && !BZERO_P
+ENTRY (__memset_chk)
+ movl 12(%esp), %eax
+ cmpl %eax, 16(%esp)
+ jb HIDDEN_JUMPTARGET (__chk_fail)
+END (__memset_chk)
+#endif
ENTRY (BP_SYM (memset))
ENTER
diff --git a/sysdeps/i386/i686/memset_chk.S b/sysdeps/i386/i686/memset_chk.S
new file mode 100644
index 0000000000..d178654994
--- /dev/null
+++ b/sysdeps/i386/i686/memset_chk.S
@@ -0,0 +1,35 @@
+/* Checking memset for x86-64.
+ 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. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+
+#ifndef PIC
+ /* For libc.so this is defined in memset.S.
+ For libc.a, this is a separate source to avoid
+ memset bringing in __chk_fail and all routines
+ it calls. */
+ .text
+ENTRY (__memset_chk)
+ movl 12(%esp), %eax
+ cmpl %eax, 16(%esp)
+ jb __chk_fail
+ jmp memset
+END (__memset_chk)
+#endif
diff --git a/sysdeps/mach/hurd/Makefile b/sysdeps/mach/hurd/Makefile
index 5f3da04b47..8677515cd9 100644
--- a/sysdeps/mach/hurd/Makefile
+++ b/sysdeps/mach/hurd/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1993,94,95,96,97,98,99,2000,2001,2002, 2003
+# Copyright (C) 1993,94,95,96,97,98,99,2000,2001,2002, 2003, 2004
# Free Software Foundation, Inc.
# This file is part of the GNU C Library.
@@ -177,14 +177,14 @@ ifeq (yes,$(build-static))
link-libc-static := -Wl,-\( \
$(patsubst %,$(common-objpfx)%.a,\
libc mach/libmachuser hurd/libhurduser) \
- $(gnulib) -Wl,-\)
+ $(static-gnulib) -Wl,-\)
else
ifeq (yes,$(build-shared))
# We can try to link the programs with lib*_pic.a...
link-libc-static := $(link-libc) -Wl,-\( \
$(patsubst %,$(common-objpfx)%_pic.a,\
libc mach/libmachuser hurd/libhurduser) \
- $(gnulib) -Wl,-\)
+ $(static-gnulib) -Wl,-\)
endif
endif
diff --git a/sysdeps/powerpc/powerpc32/dl-machine.c b/sysdeps/powerpc/powerpc32/dl-machine.c
index 606a1dd043..06960716b9 100644
--- a/sysdeps/powerpc/powerpc32/dl-machine.c
+++ b/sysdeps/powerpc/powerpc32/dl-machine.c
@@ -101,8 +101,8 @@ weak_extern (__cache_line_size)
mapped somewhere else. */
ElfW(Addr)
-__elf_preferred_address(struct link_map *loader, size_t maplength,
- ElfW(Addr) mapstartpref)
+__elf_preferred_address (struct link_map *loader, size_t maplength,
+ ElfW(Addr) mapstartpref)
{
ElfW(Addr) low, high;
struct link_map *l;
@@ -343,8 +343,8 @@ __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,
- Elf32_Addr *reloc_addr, Elf32_Addr finaladdr)
+__elf_machine_fixup_plt (struct link_map *map, const Elf32_Rela *reloc,
+ Elf32_Addr *reloc_addr, Elf32_Addr finaladdr)
{
Elf32_Sword delta = finaladdr - (Elf32_Word) reloc_addr;
if (delta << 6 >> 6 == delta)
diff --git a/sysdeps/unix/sysv/linux/adjtime.c b/sysdeps/unix/sysv/linux/adjtime.c
index 62008f63ca..38ef805cd5 100644
--- a/sysdeps/unix/sysv/linux/adjtime.c
+++ b/sysdeps/unix/sysv/linux/adjtime.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1995, 1996, 1997, 1998, 2002 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1996, 1997, 1998, 2002, 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
@@ -51,9 +52,7 @@ extern int INTUSE(__adjtimex) (struct timex *__ntx);
#endif
LINKAGE int
-ADJTIME (itv, otv)
- const struct TIMEVAL *itv;
- struct TIMEVAL *otv;
+ADJTIME (const struct TIMEVAL *itv, struct TIMEVAL *otv)
{
struct TIMEX tntx;
diff --git a/sysdeps/unix/sysv/linux/alpha/adjtime.c b/sysdeps/unix/sysv/linux/alpha/adjtime.c
index f8b272e9ce..e206cb4727 100644
--- a/sysdeps/unix/sysv/linux/alpha/adjtime.c
+++ b/sysdeps/unix/sysv/linux/alpha/adjtime.c
@@ -87,14 +87,15 @@ compat_symbol (libc, __adjtime_tv32, adjtime, GLIBC_2_0);
#define TIMEVAL timeval
#undef TIMEX
#define TIMEX timex
-#undef ADJTIME
-#define ADJTIME __adjtime_tv64
#undef ADJTIMEX
#define ADJTIMEX(x) INLINE_SYSCALL (adjtimex, 1, x)
+
#undef LINKAGE
+#undef ADJTIME
+#if !defined __ASSUME_TIMEVAL64
#define LINKAGE static
-
-LINKAGE int ADJTIME (const struct TIMEVAL *itv, struct TIMEVAL *otv);
+#define ADJTIME __adjtime_tv64
+#endif
#include <sysdeps/unix/sysv/linux/adjtime.c>
#include <stdbool.h>
@@ -135,8 +136,6 @@ __adjtime (itv, otv)
return ret;
}
-#else
-strong_alias (__adjtime_tv64, __adjtime);
#endif
versioned_symbol (libc, __adjtime, adjtime, GLIBC_2_1);
diff --git a/sysdeps/unix/sysv/linux/alpha/register-dump.h b/sysdeps/unix/sysv/linux/alpha/register-dump.h
new file mode 100644
index 0000000000..d55899a2c1
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/alpha/register-dump.h
@@ -0,0 +1,161 @@
+/* Dump registers.
+ 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. */
+
+#include <stddef.h>
+#include <sys/uio.h>
+
+/* We will print the register dump in this format:
+
+ V0: XXXXXXXXXXXXXXXX T0: XXXXXXXXXXXXXXXX T1: XXXXXXXXXXXXXXXX
+ T2: XXXXXXXXXXXXXXXX T3: XXXXXXXXXXXXXXXX T4: XXXXXXXXXXXXXXXX
+ T5: XXXXXXXXXXXXXXXX T6: XXXXXXXXXXXXXXXX T7: XXXXXXXXXXXXXXXX
+ S0: XXXXXXXXXXXXXXXX S1: XXXXXXXXXXXXXXXX S2: XXXXXXXXXXXXXXXX
+ S3: XXXXXXXXXXXXXXXX S4: XXXXXXXXXXXXXXXX S5: XXXXXXXXXXXXXXXX
+ S6: XXXXXXXXXXXXXXXX A0: XXXXXXXXXXXXXXXX A1: XXXXXXXXXXXXXXXX
+ A2: XXXXXXXXXXXXXXXX A3: XXXXXXXXXXXXXXXX A4: XXXXXXXXXXXXXXXX
+ A5: XXXXXXXXXXXXXXXX T8: XXXXXXXXXXXXXXXX T9: XXXXXXXXXXXXXXXX
+ T10: XXXXXXXXXXXXXXXX T11: XXXXXXXXXXXXXXXX RA: XXXXXXXXXXXXXXXX
+ T12: XXXXXXXXXXXXXXXX AT: XXXXXXXXXXXXXXXX GP: XXXXXXXXXXXXXXXX
+ SP: XXXXXXXXXXXXXXXX PC: XXXXXXXXXXXXXXXX
+
+ FP0: XXXXXXXXXXXXXXXX FP1: XXXXXXXXXXXXXXXX FP2: XXXXXXXXXXXXXXXX
+ FP3: XXXXXXXXXXXXXXXX FP4: XXXXXXXXXXXXXXXX FP5: XXXXXXXXXXXXXXXX
+ FP6: XXXXXXXXXXXXXXXX FP7: XXXXXXXXXXXXXXXX FP8: XXXXXXXXXXXXXXXX
+ FP9: XXXXXXXXXXXXXXXX FP10: XXXXXXXXXXXXXXXX FP11: XXXXXXXXXXXXXXXX
+ FP12: XXXXXXXXXXXXXXXX FP13: XXXXXXXXXXXXXXXX FP14: XXXXXXXXXXXXXXXX
+ FP15: XXXXXXXXXXXXXXXX FP16: XXXXXXXXXXXXXXXX FP17: XXXXXXXXXXXXXXXX
+ FP18: XXXXXXXXXXXXXXXX FP19: XXXXXXXXXXXXXXXX FP20: XXXXXXXXXXXXXXXX
+ FP21: XXXXXXXXXXXXXXXX FP22: XXXXXXXXXXXXXXXX FP23: XXXXXXXXXXXXXXXX
+ FP24: XXXXXXXXXXXXXXXX FP25: XXXXXXXXXXXXXXXX FP26: XXXXXXXXXXXXXXXX
+ FP27: XXXXXXXXXXXXXXXX FP28: XXXXXXXXXXXXXXXX FP29: XXXXXXXXXXXXXXXX
+ FP30: XXXXXXXXXXXXXXXX FPCR: XXXXXXXXXXXXXXXX
+
+ TA0: XXXXXXXXXXXXXXXX TA1: XXXXXXXXXXXXXXXX TA2: XXXXXXXXXXXXXXXX
+*/
+
+#define NREGS (32+32+3)
+
+static const char regnames[NREGS][8] =
+{
+ " V0: ", " T0: ", " T1: ",
+ " T2: ", " T3: ", " T4: ",
+ " T5: ", " T6: ", " T7: ",
+ " S0: ", " S1: ", " S2: ",
+ " S3: ", " S4: ", " S5: ",
+ " S6: ", " A0: ", " A1: ",
+ " A2: ", " A3: ", " A4: ",
+ " A5: ", " T8: ", " T9: ",
+ " T10: ", " T11: ", " RA: ",
+ " T12: ", " AT: ", " GP: ",
+ " SP: ", " PC: ",
+
+ " FP0: ", " FP1: ", " FP2: ",
+ " FP3: ", " FP4: ", " FP5: ",
+ " FP6: ", " FP7: ", " FP8: ",
+ " FP9: ", " FP10: ", " FP11: ",
+ " FP12: ", " FP13: ", " FP14: ",
+ " FP15: ", " FP16: ", " FP17: ",
+ " FP18: ", " FP19: ", " FP20: ",
+ " FP21: ", " FP22: ", " FP23: ",
+ " FP24: ", " FP25: ", " FP26: ",
+ " FP27: ", " FP28: ", " FP29: ",
+ " FP30: ", " FPCR: ",
+
+ " TA0: ", " TA1: ", " TA2: "
+};
+
+#define O(FIELD, LF) offsetof(struct sigcontext, FIELD) + LF
+
+static const int offsets[NREGS] =
+{
+ O(sc_regs[0], 0), O(sc_regs[1], 0), O(sc_regs[2], 1),
+ O(sc_regs[3], 0), O(sc_regs[4], 0), O(sc_regs[5], 1),
+ O(sc_regs[6], 0), O(sc_regs[7], 0), O(sc_regs[8], 1),
+ O(sc_regs[9], 0), O(sc_regs[10], 0), O(sc_regs[11], 1),
+ O(sc_regs[12], 0), O(sc_regs[13], 0), O(sc_regs[14], 1),
+ O(sc_regs[15], 0), O(sc_regs[16], 0), O(sc_regs[17], 1),
+ O(sc_regs[18], 0), O(sc_regs[19], 0), O(sc_regs[20], 1),
+ O(sc_regs[21], 0), O(sc_regs[22], 0), O(sc_regs[23], 1),
+ O(sc_regs[24], 0), O(sc_regs[25], 0), O(sc_regs[26], 1),
+ O(sc_regs[27], 0), O(sc_regs[28], 0), O(sc_regs[29], 1),
+ O(sc_regs[30], 0), O(sc_pc, 2),
+
+ O(sc_fpregs[0], 0), O(sc_fpregs[1], 0), O(sc_fpregs[2], 1),
+ O(sc_fpregs[3], 0), O(sc_fpregs[4], 0), O(sc_fpregs[5], 1),
+ O(sc_fpregs[6], 0), O(sc_fpregs[7], 0), O(sc_fpregs[8], 1),
+ O(sc_fpregs[9], 0), O(sc_fpregs[10], 0), O(sc_fpregs[11], 1),
+ O(sc_fpregs[12], 0), O(sc_fpregs[13], 0), O(sc_fpregs[14], 1),
+ O(sc_fpregs[15], 0), O(sc_fpregs[16], 0), O(sc_fpregs[17], 1),
+ O(sc_fpregs[18], 0), O(sc_fpregs[19], 0), O(sc_fpregs[20], 1),
+ O(sc_fpregs[21], 0), O(sc_fpregs[22], 0), O(sc_fpregs[23], 1),
+ O(sc_fpregs[24], 0), O(sc_fpregs[25], 0), O(sc_fpregs[26], 1),
+ O(sc_fpregs[27], 0), O(sc_fpregs[28], 0), O(sc_fpregs[29], 1),
+ O(sc_fpregs[30], 0), O(sc_fpcr, 2),
+
+ O(sc_traparg_a0, 0), O(sc_traparg_a1, 0), O(sc_traparg_a2, 1)
+};
+
+#undef O
+
+static const char linefeed[2] = "\n\n";
+
+static void
+register_dump (int fd, struct sigcontext *ctx)
+{
+ char regs[NREGS][16];
+ struct iovec iov[2*NREGS+24];
+ size_t iov_i = 0, i, j;
+
+#define ADD_MEM(str, len) \
+ (iov[iov_i].iov_base = (void *)(str), \
+ iov[iov_i].iov_len = len, \
+ ++iov_i)
+
+#define ADD_STRING(str) ADD_MEM(str, strlen(str))
+
+ ADD_STRING ("Register dump:\n\n");
+
+ for (i = 0; i < NREGS; ++i)
+ {
+ int this_offset, this_lf;
+ unsigned long val;
+
+ this_offset = offsets[i];
+ this_lf = this_offset & 7;
+ this_offset &= -8;
+
+ val = *(unsigned long *)((char *)ctx + this_offset);
+
+ for (j = 0; j < 16; ++j)
+ {
+ unsigned long x = (val >> (64 - (j + 1) * 4)) & 15;
+ x += x < 10 ? '0' : 'a' - 10;
+ regs[i][j] = x;
+ }
+
+ ADD_MEM (regnames[i], 8);
+ ADD_MEM (regs[i], 16);
+ if (this_lf)
+ ADD_MEM (linefeed, this_lf);
+ }
+
+ writev (fd, iov, iov_i);
+}
+
+#define REGISTER_DUMP register_dump (fd, ctx)
diff --git a/sysdeps/unix/sysv/linux/alpha/sigcontextinfo.h b/sysdeps/unix/sysv/linux/alpha/sigcontextinfo.h
index eb6f4f0758..16c5dcbc5b 100644
--- a/sysdeps/unix/sysv/linux/alpha/sigcontextinfo.h
+++ b/sysdeps/unix/sysv/linux/alpha/sigcontextinfo.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1999, 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
@@ -16,10 +16,10 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
-#define SIGCONTEXT struct sigcontext
-#define SIGCONTEXT_EXTRA_ARGS
-#define GET_PC(ctx) ((void *) (ctx).sc_pc)
-#define GET_FRAME(ctx) ((void *) (ctx).sc_regs[15])
-#define GET_STACK(ctx) ((void *) (ctx).sc_regs[30])
+#define SIGCONTEXT int _code, struct sigcontext *
+#define SIGCONTEXT_EXTRA_ARGS _code,
+#define GET_PC(ctx) ((void *) (ctx)->sc_pc)
+#define GET_FRAME(ctx) ((void *) (ctx)->sc_regs[15])
+#define GET_STACK(ctx) ((void *) (ctx)->sc_regs[30])
#define CALL_SIGHANDLER(handler, signo, ctx) \
(handler)((signo), SIGCONTEXT_EXTRA_ARGS (ctx))
diff --git a/sysdeps/unix/sysv/linux/i386/syscall.S b/sysdeps/unix/sysv/linux/i386/syscall.S
index cd7dc65a5f..b569650b24 100644
--- a/sysdeps/unix/sysv/linux/i386/syscall.S
+++ b/sysdeps/unix/sysv/linux/i386/syscall.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1998, 2002 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1996, 1998, 2002, 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
@@ -24,11 +24,11 @@
.text
ENTRY (syscall)
- PUSHARGS_5 /* Save register contents. */
- _DOARGS_5(36) /* Load arguments. */
- movl 16(%esp), %eax /* Load syscall number into %eax. */
+ PUSHARGS_6 /* Save register contents. */
+ _DOARGS_6(44) /* Load arguments. */
+ movl 20(%esp), %eax /* Load syscall number into %eax. */
ENTER_KERNEL /* Do the system call. */
- POPARGS_5 /* Restore register contents. */
+ POPARGS_6 /* Restore register contents. */
cmpl $-4095, %eax /* Check %eax for error. */
jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */
L(pseudo_end):
diff --git a/sysdeps/unix/sysv/linux/i386/sysdep.h b/sysdeps/unix/sysv/linux/i386/sysdep.h
index 37e7459a9c..af75d4c51a 100644
--- a/sysdeps/unix/sysv/linux/i386/sysdep.h
+++ b/sysdeps/unix/sysv/linux/i386/sysdep.h
@@ -297,6 +297,13 @@ __i686.get_pc_thunk.reg: \
#define _DOARGS_5(n) movl n(%esp), %edi; _DOARGS_4 (n-4)
#define _POPARGS_5 _POPARGS_4; popl %edi; L(POPDI1):
+#define PUSHARGS_6 _PUSHARGS_6
+#define DOARGS_6 _DOARGS_6 (36)
+#define POPARGS_6 _POPARGS_6
+#define _PUSHARGS_6 pushl %ebp; L(PUSHBP1): _PUSHARGS_5
+#define _DOARGS_6(n) movl n(%esp), %ebp; _DOARGS_5 (n-4)
+#define _POPARGS_6 _POPARGS_5; popl %ebp; L(POPBP1):
+
#else /* !__ASSEMBLER__ */
/* We need some help from the assembler to generate optimal code. We
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h b/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h
index 1f56671ba0..5eaf7a276b 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h
+++ b/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2000, 2002, 2003, 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
@@ -275,7 +275,8 @@
_sys_result; \
})
-#define __SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25"
+#define __SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", \
+ "$14", "$15", "$24", "$25", "memory"
#endif /* __ASSEMBLER__ */
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h b/sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h
index 2b2aefa15d..be343aabca 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2000, 2002, 2003, 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
@@ -235,7 +235,8 @@
_sys_result; \
})
-#define __SYSCALL_CLOBBERS "$1", "$3", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25"
+#define __SYSCALL_CLOBBERS "$1", "$3", "$10", "$11", "$12", "$13", \
+ "$14", "$15", "$24", "$25", "memory"
#endif /* __ASSEMBLER__ */
#endif /* linux/mips/sysdep.h */
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/sysdep.h b/sysdeps/unix/sysv/linux/mips/mips64/n64/sysdep.h
index e2d8707d25..f30a465081 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/sysdep.h
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/sysdep.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2000, 2002, 2003, 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
@@ -235,7 +235,8 @@
_sys_result; \
})
-#define __SYSCALL_CLOBBERS "$1", "$3", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25"
+#define __SYSCALL_CLOBBERS "$1", "$3", "$10", "$11", "$12", "$13", \
+ "$14", "$15", "$24", "$25", "memory"
#endif /* __ASSEMBLER__ */
#endif /* linux/mips/sysdep.h */
diff --git a/sysdeps/unix/sysv/linux/readonly-area.c b/sysdeps/unix/sysv/linux/readonly-area.c
new file mode 100644
index 0000000000..ce5321bcef
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/readonly-area.c
@@ -0,0 +1,90 @@
+/* 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. */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <stdlib.h>
+#include <string.h>
+#include "libio/libioP.h"
+
+/* Return 1 if the whole area PTR .. PTR+SIZE is not writable.
+ Return -1 if it is writable. */
+
+int
+__readonly_area (const char *ptr, size_t size)
+{
+ const void *ptr_end = ptr + size;
+
+ FILE *fp = fopen ("/proc/self/maps", "rc");
+ if (fp == NULL)
+ return -1;
+
+ /* We need no locking. */
+ __fsetlocking (fp, FSETLOCKING_BYCALLER);
+
+ char *line = NULL;
+ size_t linelen = 0;
+
+ while (! feof_unlocked (fp))
+ {
+ if (_IO_getdelim (&line, &linelen, '\n', fp) <= 0)
+ break;
+
+ char *p;
+ uintptr_t from = strtoul (line, &p, 16);
+
+ if (p == line || *p++ != '-')
+ break;
+
+ char *q;
+ uintptr_t to = strtoul (p, &q, 16);
+
+ if (q == p || *q++ != ' ')
+ break;
+
+ if (from < (uintptr_t) ptr_end && to > (uintptr_t) ptr)
+ {
+ /* Found an entry that at least partially covers the area. */
+ if (*q++ != 'r' || *q++ != '-')
+ break;
+
+ if (from <= (uintptr_t) ptr && to >= (uintptr_t) ptr_end)
+ {
+ size = 0;
+ break;
+ }
+ else if (from <= (uintptr_t) ptr)
+ size -= to - (uintptr_t) ptr;
+ else if (to >= (uintptr_t) ptr_end)
+ size -= (uintptr_t) ptr_end - from;
+ else
+ size -= to - from;
+
+ if (!size)
+ break;
+ }
+ }
+
+ fclose (fp);
+ free (line);
+
+ /* If the whole area between ptr and ptr_end is covered by read-only
+ VMAs, return 1. Otherwise return -1. */
+ return size == 0 ? 1 : -1;
+}
diff --git a/sysdeps/x86_64/memcpy.S b/sysdeps/x86_64/memcpy.S
index de47688241..5f06198b5d 100644
--- a/sysdeps/x86_64/memcpy.S
+++ b/sysdeps/x86_64/memcpy.S
@@ -29,6 +29,12 @@
#define MEMPCPY_P (defined memcpy)
.text
+#if defined PIC && !defined NOT_IN_libc
+ENTRY (__memcpy_chk)
+ cmpq %rdx, %rcx
+ jb HIDDEN_JUMPTARGET (__chk_fail)
+END (__memcpy_chk)
+#endif
ENTRY (BP_SYM (memcpy))
/* Cutoff for the big loop is a size of 32 bytes since otherwise
the loop will never be entered. */
diff --git a/sysdeps/x86_64/memcpy_chk.S b/sysdeps/x86_64/memcpy_chk.S
new file mode 100644
index 0000000000..c5251ea2d4
--- /dev/null
+++ b/sysdeps/x86_64/memcpy_chk.S
@@ -0,0 +1,34 @@
+/* Checking memcpy for x86-64.
+ 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. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+
+#ifndef PIC
+ /* For libc.so this is defined in memcpy.S.
+ For libc.a, this is a separate source to avoid
+ memcpy bringing in __chk_fail and all routines
+ it calls. */
+ .text
+ENTRY (__memcpy_chk)
+ cmpq %rdx, %rcx
+ jb __chk_fail
+ jmp memcpy
+END (__memcpy_chk)
+#endif
diff --git a/sysdeps/x86_64/mempcpy.S b/sysdeps/x86_64/mempcpy.S
index 03aa743fba..4558a1699a 100644
--- a/sysdeps/x86_64/mempcpy.S
+++ b/sysdeps/x86_64/mempcpy.S
@@ -1,4 +1,5 @@
#define memcpy __mempcpy
+#define __memcpy_chk __mempcpy_chk
#include <sysdeps/x86_64/memcpy.S>
libc_hidden_def (BP_SYM (__mempcpy))
diff --git a/sysdeps/x86_64/mempcpy_chk.S b/sysdeps/x86_64/mempcpy_chk.S
new file mode 100644
index 0000000000..c333a4adb3
--- /dev/null
+++ b/sysdeps/x86_64/mempcpy_chk.S
@@ -0,0 +1,34 @@
+/* Checking mempcpy for x86-64.
+ 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. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+
+#ifndef PIC
+ /* For libc.so this is defined in memcpy.S.
+ For libc.a, this is a separate source to avoid
+ mempcpy bringing in __chk_fail and all routines
+ it calls. */
+ .text
+ENTRY (__mempcpy_chk)
+ cmpq %rdx, %rcx
+ jb __chk_fail
+ jmp mempcpy
+END (__mempcpy_chk)
+#endif
diff --git a/sysdeps/x86_64/memset.S b/sysdeps/x86_64/memset.S
index 29afa63e7e..6c47f4c863 100644
--- a/sysdeps/x86_64/memset.S
+++ b/sysdeps/x86_64/memset.S
@@ -1,6 +1,6 @@
/* memset/bzero -- set memory area to CH/0
Optimized version for x86-64.
- Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Andreas Jaeger <aj@suse.de>.
@@ -32,6 +32,12 @@
#define LARGE $120000
.text
+#if !BZERO_P && defined PIC && !defined NOT_IN_libc
+ENTRY (__memset_chk)
+ cmpq %rdx, %rcx
+ jb HIDDEN_JUMPTARGET (__chk_fail)
+END (__memset_chk)
+#endif
ENTRY (memset)
#if BZERO_P
mov %rsi,%rdx /* Adjust parameter. */
diff --git a/sysdeps/x86_64/memset_chk.S b/sysdeps/x86_64/memset_chk.S
new file mode 100644
index 0000000000..e62cb58cc0
--- /dev/null
+++ b/sysdeps/x86_64/memset_chk.S
@@ -0,0 +1,34 @@
+/* Checking memset for x86-64.
+ 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. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+
+#ifndef PIC
+ /* For libc.so this is defined in memset.S.
+ For libc.a, this is a separate source to avoid
+ memset bringing in __chk_fail and all routines
+ it calls. */
+ .text
+ENTRY (__memset_chk)
+ cmpq %rdx, %rcx
+ jb __chk_fail
+ jmp memset
+END (__memset_chk)
+#endif
diff --git a/sysdeps/x86_64/stpcpy_chk.S b/sysdeps/x86_64/stpcpy_chk.S
new file mode 100644
index 0000000000..905e8d7ee3
--- /dev/null
+++ b/sysdeps/x86_64/stpcpy_chk.S
@@ -0,0 +1,3 @@
+#define USE_AS_STPCPY_CHK
+#define STRCPY_CHK __stpcpy_chk
+#include <sysdeps/x86_64/strcpy_chk.S>
diff --git a/sysdeps/x86_64/strcpy_chk.S b/sysdeps/x86_64/strcpy_chk.S
new file mode 100644
index 0000000000..364331553a
--- /dev/null
+++ b/sysdeps/x86_64/strcpy_chk.S
@@ -0,0 +1,211 @@
+/* strcpy/stpcpy checking implementation for x86-64.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@suse.de>, 2002.
+ Adopted into checking version by Jakub Jelinek <jakub@redhat.com>.
+
+ 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"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#ifndef USE_AS_STPCPY_CHK
+# define STRCPY_CHK __strcpy_chk
+#endif
+
+ .text
+ENTRY (STRCPY_CHK)
+ movq %rsi, %rcx /* Source register. */
+ andl $7, %ecx /* mask alignment bits */
+#ifndef USE_AS_STPCPY_CHK
+ movq %rdi, %r10 /* Duplicate destination pointer. */
+#endif
+ jz 5f /* aligned => start loop */
+
+ cmpq $8, %rdx /* Check if only few bytes left in
+ destination. */
+ jb 50f
+
+ subq $8, %rcx /* We need to align to 8 bytes. */
+ addq %rcx, %rdx /* Subtract count of stored bytes
+ in the cycle below from destlen. */
+
+ /* Search the first bytes directly. */
+0:
+ movb (%rsi), %al /* Fetch a byte */
+ testb %al, %al /* Is it NUL? */
+ movb %al, (%rdi) /* Store it */
+ jz 4f /* If it was NUL, done! */
+ incq %rsi
+ incq %rdi
+ incl %ecx
+ jnz 0b
+
+5:
+ movq $0xfefefefefefefeff,%r8
+ cmpq $32, %rdx /* Are there enough bytes in destination
+ for the next unrolled round? */
+ jb 60f /* If not, avoid the unrolled loop. */
+
+ /* Now the sources is aligned. Unfortunatly we cannot force
+ to have both source and destination aligned, so ignore the
+ alignment of the destination. */
+ .p2align 4
+1:
+ /* 1st unroll. */
+ movq (%rsi), %rax /* Read double word (8 bytes). */
+ addq $8, %rsi /* Adjust pointer for next word. */
+ movq %rax, %r9 /* Save a copy for NUL finding. */
+ addq %r8, %r9 /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc 3f /* highest byte is NUL => return pointer */
+ xorq %rax, %r9 /* (word+magic)^word */
+ orq %r8, %r9 /* set all non-carry bits */
+ incq %r9 /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+
+ jnz 3f /* found NUL => return pointer */
+
+ movq %rax, (%rdi) /* Write value to destination. */
+ addq $8, %rdi /* Adjust pointer. */
+
+ /* 2nd unroll. */
+ movq (%rsi), %rax /* Read double word (8 bytes). */
+ addq $8, %rsi /* Adjust pointer for next word. */
+ movq %rax, %r9 /* Save a copy for NUL finding. */
+ addq %r8, %r9 /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc 3f /* highest byte is NUL => return pointer */
+ xorq %rax, %r9 /* (word+magic)^word */
+ orq %r8, %r9 /* set all non-carry bits */
+ incq %r9 /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+
+ jnz 3f /* found NUL => return pointer */
+
+ movq %rax, (%rdi) /* Write value to destination. */
+ addq $8, %rdi /* Adjust pointer. */
+
+ /* 3rd unroll. */
+ movq (%rsi), %rax /* Read double word (8 bytes). */
+ addq $8, %rsi /* Adjust pointer for next word. */
+ movq %rax, %r9 /* Save a copy for NUL finding. */
+ addq %r8, %r9 /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc 3f /* highest byte is NUL => return pointer */
+ xorq %rax, %r9 /* (word+magic)^word */
+ orq %r8, %r9 /* set all non-carry bits */
+ incq %r9 /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+
+ jnz 3f /* found NUL => return pointer */
+
+ movq %rax, (%rdi) /* Write value to destination. */
+ addq $8, %rdi /* Adjust pointer. */
+
+ /* 4th unroll. */
+ movq (%rsi), %rax /* Read double word (8 bytes). */
+ addq $8, %rsi /* Adjust pointer for next word. */
+ movq %rax, %r9 /* Save a copy for NUL finding. */
+ addq %r8, %r9 /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc 3f /* highest byte is NUL => return pointer */
+ xorq %rax, %r9 /* (word+magic)^word */
+ orq %r8, %r9 /* set all non-carry bits */
+ incq %r9 /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+
+ jnz 3f /* found NUL => return pointer */
+
+ subq $32, %rdx /* Adjust destlen. */
+ movq %rax, (%rdi) /* Write value to destination. */
+ addq $8, %rdi /* Adjust pointer. */
+ cmpq $32, %rdx /* Are there enough bytes in destination
+ for the next unrolled round? */
+ jae 1b /* Next iteration. */
+
+60:
+ cmpq $8, %rdx /* Are there enough bytes in destination
+ for the next unrolled round? */
+ jb 50f /* Now, copy and check byte by byte. */
+
+ movq (%rsi), %rax /* Read double word (8 bytes). */
+ addq $8, %rsi /* Adjust pointer for next word. */
+ movq %rax, %r9 /* Save a copy for NUL finding. */
+ addq %r8, %r9 /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc 3f /* highest byte is NUL => return pointer */
+ xorq %rax, %r9 /* (word+magic)^word */
+ orq %r8, %r9 /* set all non-carry bits */
+ incq %r9 /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+
+ jnz 3f /* found NUL => return pointer */
+
+ subq $8, %rdx /* Adjust destlen. */
+ movq %rax, (%rdi) /* Write value to destination. */
+ addq $8, %rdi /* Adjust pointer. */
+ jmp 60b /* Next iteration. */
+
+ /* Do the last few bytes. %rax contains the value to write.
+ The loop is unrolled twice. */
+ .p2align 4
+3:
+ /* Note that stpcpy needs to return with the value of the NUL
+ byte. */
+ movb %al, (%rdi) /* 1st byte. */
+ testb %al, %al /* Is it NUL. */
+ jz 4f /* yes, finish. */
+ incq %rdi /* Increment destination. */
+ movb %ah, (%rdi) /* 2nd byte. */
+ testb %ah, %ah /* Is it NUL?. */
+ jz 4f /* yes, finish. */
+ incq %rdi /* Increment destination. */
+ shrq $16, %rax /* Shift... */
+ jmp 3b /* and look at next two bytes in %rax. */
+
+51:
+ /* Search the bytes directly, checking for overflows. */
+ incq %rsi
+ incq %rdi
+ decq %rdx
+ jz HIDDEN_JUMPTARGET (__chk_fail)
+52:
+ movb (%rsi), %al /* Fetch a byte */
+ testb %al, %al /* Is it NUL? */
+ movb %al, (%rdi) /* Store it */
+ jnz 51b /* If it was NUL, done! */
+4:
+#ifdef USE_AS_STPCPY_CHK
+ movq %rdi, %rax /* Destination is return value. */
+#else
+ movq %r10, %rax /* Source is return value. */
+#endif
+ retq
+
+50:
+ testq %rdx, %rdx
+ jnz 52b
+ jmp HIDDEN_JUMPTARGET (__chk_fail)
+
+END (STRCPY_CHK)