From d587d83bd9825c431456774321bfd0d5eabe7fee Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Wed, 8 Dec 1999 23:48:24 +0000 Subject: [PATCH] Update. * sysdeps/unix/sysv/linux/getrlimit.c: Remove K&R compatibility. * sysdeps/unix/sysv/linux/kernel-features.h: Define __ASSUME_TRUNCATE64_SYSCALL and __ASSUME_MMAP2_SYSCALL for 2.3.31 on x86. * sysdeps/unix/sysv/linux/ftruncate64.c: New file. * sysdeps/unix/sysv/linux/truncate64.c: New file. * sysdeps/unix/sysv/linux/i386/mmap.S: Allow using mmap2. * sysdeps/unix/sysv/linux/i386/mmap64.S: New file. --- ChangeLog | 10 ++ sysdeps/unix/sysv/linux/ftruncate64.c | 70 ++++++++++++ sysdeps/unix/sysv/linux/getrlimit.c | 7 +- sysdeps/unix/sysv/linux/i386/mmap.S | 40 ++++++- sysdeps/unix/sysv/linux/i386/mmap64.S | 125 ++++++++++++++++++++++ sysdeps/unix/sysv/linux/kernel-features.h | 10 ++ sysdeps/unix/sysv/linux/truncate64.c | 70 ++++++++++++ 7 files changed, 326 insertions(+), 6 deletions(-) create mode 100644 sysdeps/unix/sysv/linux/ftruncate64.c create mode 100644 sysdeps/unix/sysv/linux/i386/mmap64.S create mode 100644 sysdeps/unix/sysv/linux/truncate64.c diff --git a/ChangeLog b/ChangeLog index 89888a6fc2..e98be9ae49 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,15 @@ 1999-12-08 Ulrich Drepper + * sysdeps/unix/sysv/linux/getrlimit.c: Remove K&R compatibility. + + * sysdeps/unix/sysv/linux/kernel-features.h: Define + __ASSUME_TRUNCATE64_SYSCALL and __ASSUME_MMAP2_SYSCALL for 2.3.31 + on x86. + * sysdeps/unix/sysv/linux/ftruncate64.c: New file. + * sysdeps/unix/sysv/linux/truncate64.c: New file. + * sysdeps/unix/sysv/linux/i386/mmap.S: Allow using mmap2. + * sysdeps/unix/sysv/linux/i386/mmap64.S: New file. + * ctype/Versions: Add __ctype32_tolower and __ctype32_toupper. * ctype/ctype-info.c: Define __ctype32_tolower and __ctype32_toupper. * locale/C-ctype.c: Add _nl_C_LC_CTYPE_toupper32 and diff --git a/sysdeps/unix/sysv/linux/ftruncate64.c b/sysdeps/unix/sysv/linux/ftruncate64.c new file mode 100644 index 0000000000..17a5ab0288 --- /dev/null +++ b/sysdeps/unix/sysv/linux/ftruncate64.c @@ -0,0 +1,70 @@ +/* Copyright (C) 1997, 1998, 1999 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 Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include +#include +#include + +#include +#include + +#include "kernel-features.h" + +#ifdef __NR_ftruncate64 +static int have_no_ftruncate64; + +extern int __syscall_ftruncate64 (int fd, int high_length, int low_length); + + +/* Truncate the file FD refers to to LENGTH bytes. */ +int +ftruncate64 (fd, length) + int fd; + off64_t length; +{ +#ifndef __ASSUME_TRUNCATE64_SYSCALL + if (! have_no_ftruncate64) +#endif + { + int result = INLINE_SYSCALL (ftruncate64, 3, fd, length >> 32, + length & 0xffffffff); + +#ifndef __ASSUME_TRUNCATE64_SYSCALL + if (result != -1 || errno != ENOSYS) +#endif + return result; + +#ifndef __ASSUME_TRUNCATE64_SYSCALL + have_no_ftruncate64 = 1; +#endif + } + +#ifndef __ASSUME_TRUNCATE64_SYSCALL + if ((off_t) length != length) + { + __set_errno (EINVAL); + return -1; + } + return __ftruncate (fd, (off_t) length); +#endif +} + +#else +/* Use the generic implementation. */ +# include +#endif diff --git a/sysdeps/unix/sysv/linux/getrlimit.c b/sysdeps/unix/sysv/linux/getrlimit.c index a929030d2a..14a879c5df 100644 --- a/sysdeps/unix/sysv/linux/getrlimit.c +++ b/sysdeps/unix/sysv/linux/getrlimit.c @@ -24,10 +24,9 @@ #include "kernel-features.h" -extern int __syscall_ugetrlimit __P ((unsigned int resource, - struct rlimit *rlimits)); -extern int __syscall_getrlimit __P ((unsigned int resource, - struct rlimit *rlimits)); +extern int __syscall_ugetrlimit (unsigned int resource, + struct rlimit *rlimits); +extern int __syscall_getrlimit (unsigned int resource, struct rlimit *rlimits); /* Linux 2.3.25 introduced a new system call since the types used for the limits are now unsigned. */ diff --git a/sysdeps/unix/sysv/linux/i386/mmap.S b/sysdeps/unix/sysv/linux/i386/mmap.S index a9929c8be1..0397f841f1 100644 --- a/sysdeps/unix/sysv/linux/i386/mmap.S +++ b/sysdeps/unix/sysv/linux/i386/mmap.S @@ -1,4 +1,4 @@ -/* Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +/* Copyright (C) 1995, 1996, 1997, 1998, 1999 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 @@ -18,10 +18,45 @@ #include +#include "kernel-features.h" + +#define EINVAL 22 + .text ENTRY (__mmap) +/* I don't think it is worthwhile trzing to use mmap2 whenever it + is available. Only use it when we are sure the syscall exists. */ +#ifdef __ASSUME_MMAP2_SYSCALL + + /* Save registers. */ + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + + movl $SYS_ify(mmap2), %eax /* System call number in %eax. */ + + movl 20(%esp), %ebx + movl 24(%esp), %ecx + movl 28(%esp), %edx + movl 32(%esp), %esi + movl 36(%esp), %edi + movl 40(%esp), %ebp + shrl $12, %ebp /* mmap2 takes the offset in pages. */ + + /* Do the system call trap. */ + int $0x80 + + /* Restore registers. */ + popl %edi + popl %esi + popl %ebx + popl %ebp + +#else + /* Save registers. */ movl %ebx, %edx @@ -35,6 +70,8 @@ ENTRY (__mmap) /* Restore registers. */ movl %edx, %ebx +#endif + /* If 0 > %eax > -4096 there was an error. */ cmpl $-4096, %eax ja SYSCALL_ERROR_LABEL @@ -46,4 +83,3 @@ L(pseudo_end): PSEUDO_END (__mmap) weak_alias (__mmap, mmap) -weak_alias (__mmap, mmap64) diff --git a/sysdeps/unix/sysv/linux/i386/mmap64.S b/sysdeps/unix/sysv/linux/i386/mmap64.S new file mode 100644 index 0000000000..075c3f3345 --- /dev/null +++ b/sysdeps/unix/sysv/linux/i386/mmap64.S @@ -0,0 +1,125 @@ +/* Copyright (C) 1995, 1996, 1997, 1998, 1999 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 Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include + +#include "kernel-features.h" + +#define EINVAL 22 + + .text + +ENTRY (__mmap64) + +#ifdef __NR_mmap2 + + /* Save registers. */ + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + + movl $SYS_ify(mmap2), %eax /* System call number in %eax. */ + + movl 40(%esp), %ebp + movl 44(%esp), %ecx + shrld $12, %ecx, %ebp /* mmap2 takes the offset in pages. */ + shrl $12, %ecx + jne L(einval) + + movl 20(%esp), %ebx + movl 24(%esp), %ecx + movl 28(%esp), %edx + movl 32(%esp), %esi + movl 36(%esp), %edi + + /* Do the system call trap. */ +L(do_syscal): + int $0x80 + + /* If 0 > %eax > -4096 there was an error. */ + cmpl $-4096, %eax + ja SYSCALL_ERROR_LABEL + + /* Restore registers. */ + popl %edi + popl %esi + popl %ebx + popl %ebp + + /* Successful; return the syscall's value. */ +L(pseudo_end): + ret + +#ifndef __ASSUME_MMAP2_SYSCALL +2: + cmp $-EINVAL, %eax + je 2f +#endif + + /* This means the offset value is too large. */ +L(einval): + popl %edi + popl %esi + popl %ebx + popl %ebp + movl $-EINVAL, %eax + jmp SYSCALL_ERROR_LABEL +#endif + +#if !defined __ASSUME_MMAP2_SYSCALL || !defined __NR_mmap2 + +# ifndef __NR_mmap2 + /* Save registers. */ + movl %ebx, %edx +# endif + + cmpl $0, 44(%esp) + jne L(einval) + + movl $SYS_ify(mmap), %eax /* System call number in %eax. */ + + lea 4(%esp), %ebx /* Address of args is 1st arg. */ + +# ifdef __NR_mmap2 + jmp L(do_syscall) +# else + + /* Do the system call trap. */ + int $0x80 + + /* Restore registers. */ + movl %edx, %ebx + + /* If 0 > %eax > -4096 there was an error. */ + cmpl $-4096, %eax + ja SYSCALL_ERROR_LABEL + + /* Successful; return the syscall's value. */ +L(pseudo_end): + ret + +L(einval): + movl $-EINVAL, %eax + jmp SYSCALL_ERROR_LABEL +# endif +#endif + +PSEUDO_END (__mmap64) + +weak_alias (__mmap64, mmap64) diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h index f01f2ddaca..b11dc4cce0 100644 --- a/sysdeps/unix/sysv/linux/kernel-features.h +++ b/sysdeps/unix/sysv/linux/kernel-features.h @@ -79,3 +79,13 @@ #if __LINUX_KERNEL_VERSION >= 131865 && defined __i386__ # define __ASSUME_NEW_GETRLIMIT_SYSCALL 1 #endif + +/* On x86 the truncate64/ftruncate64 syscalls were introduced in 2.3.31. */ +#if __LINUX_KERNEL_VERSION >= 131871 && defined __i386__ +# define __ASSUME_TRUNCATE64_SYSCALL 1 +#endif + +/* On x86 the truncate64/ftruncate64 syscalls were introduced in 2.3.31. */ +#if __LINUX_KERNEL_VERSION >= 131871 && defined __i386__ +# define __ASSUME_MMAP2_SYSCALL 1 +#endif diff --git a/sysdeps/unix/sysv/linux/truncate64.c b/sysdeps/unix/sysv/linux/truncate64.c new file mode 100644 index 0000000000..0a20547789 --- /dev/null +++ b/sysdeps/unix/sysv/linux/truncate64.c @@ -0,0 +1,70 @@ +/* Copyright (C) 1997, 1998, 1999 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 Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include +#include +#include + +#include +#include + +#include "kernel-features.h" + +#ifdef __NR_truncate64 +static int have_no_truncate64; + +extern int __syscall_truncate64 (int fd, int high_length, int low_length); + + +/* Truncate the file FD refers to to LENGTH bytes. */ +int +truncate64 (path, length) + const char *path; + off64_t length; +{ +#ifndef __ASSUME_TRUNCATE64_SYSCALL + if (! have_no_truncate64) +#endif + { + int result = INLINE_SYSCALL (truncate64, 3, path, length >> 32, + length & 0xffffffff); + +#ifndef __ASSUME_TRUNCATE64_SYSCALL + if (result != -1 || errno != ENOSYS) +#endif + return result; + +#ifndef __ASSUME_TRUNCATE64_SYSCALL + have_no_truncate64 = 1; +#endif + } + +#ifndef __ASSUME_TRUNCATE64_SYSCALL + if ((off_t) length != length) + { + __set_errno (EINVAL); + return -1; + } + return truncate (path, (off_t) length); +#endif +} + +#else +/* Use the generic implementation. */ +# include +#endif