summaryrefslogtreecommitdiff
path: root/sysdeps/x86_64
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/x86_64
parent4ce1a5c9712b4d7616058e708630c33744f983f6 (diff)
Updated to fedora-glibc-20041018T0940
Diffstat (limited to 'sysdeps/x86_64')
-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
8 files changed, 330 insertions, 1 deletions
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)