From b57ab258c1140bc45464b4b9908713e3e0ee35aa Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Mon, 16 May 2022 18:41:43 +0200 Subject: Linux: Introduce __brk_call for invoking the brk system call Alpha and sparc can now use the generic implementation. Reviewed-by: Adhemerval Zanella --- sysdeps/unix/sysv/linux/alpha/brk.c | 38 --------------------- sysdeps/unix/sysv/linux/alpha/brk_call.h | 28 +++++++++++++++ sysdeps/unix/sysv/linux/brk.c | 3 +- sysdeps/unix/sysv/linux/brk_call.h | 25 ++++++++++++++ sysdeps/unix/sysv/linux/sparc/brk.c | 58 -------------------------------- sysdeps/unix/sysv/linux/sparc/brk_call.h | 35 +++++++++++++++++++ 6 files changed, 90 insertions(+), 97 deletions(-) delete mode 100644 sysdeps/unix/sysv/linux/alpha/brk.c create mode 100644 sysdeps/unix/sysv/linux/alpha/brk_call.h create mode 100644 sysdeps/unix/sysv/linux/brk_call.h delete mode 100644 sysdeps/unix/sysv/linux/sparc/brk.c create mode 100644 sysdeps/unix/sysv/linux/sparc/brk_call.h (limited to 'sysdeps/unix/sysv/linux') diff --git a/sysdeps/unix/sysv/linux/alpha/brk.c b/sysdeps/unix/sysv/linux/alpha/brk.c deleted file mode 100644 index 32082a4fae..0000000000 --- a/sysdeps/unix/sysv/linux/alpha/brk.c +++ /dev/null @@ -1,38 +0,0 @@ -/* Change data segment size. Linux/Alpha. - Copyright (C) 2020-2022 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, see - . */ - -#include -#include -#include - -void *__curbrk = 0; - -int -__brk (void *addr) -{ - /* Alpha brk returns -ENOMEM in case of failure. */ - __curbrk = (void *) INTERNAL_SYSCALL_CALL (brk, addr); - if ((unsigned long) __curbrk == -ENOMEM) - { - __set_errno (ENOMEM); - return -1; - } - - return 0; -} -weak_alias (__brk, brk) diff --git a/sysdeps/unix/sysv/linux/alpha/brk_call.h b/sysdeps/unix/sysv/linux/alpha/brk_call.h new file mode 100644 index 0000000000..b8088cf13f --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/brk_call.h @@ -0,0 +1,28 @@ +/* Invoke the brk system call. Alpha version. + Copyright (C) 2022 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, see + . */ + +static inline void * +__brk_call (void *addr) +{ + unsigned long int result = INTERNAL_SYSCALL_CALL (brk, addr); + if (result == -ENOMEM) + /* Mimic the default error reporting behavior. */ + return addr; + else + return (void *) result; +} diff --git a/sysdeps/unix/sysv/linux/brk.c b/sysdeps/unix/sysv/linux/brk.c index abbabc9e8b..9264a5a4a2 100644 --- a/sysdeps/unix/sysv/linux/brk.c +++ b/sysdeps/unix/sysv/linux/brk.c @@ -19,6 +19,7 @@ #include #include #include +#include /* This must be initialized data because commons can't have aliases. */ void *__curbrk = 0; @@ -33,7 +34,7 @@ weak_alias (__curbrk, ___brk_addr) int __brk (void *addr) { - __curbrk = (void *) INTERNAL_SYSCALL_CALL (brk, addr); + __curbrk = __brk_call (addr); if (__curbrk < addr) { __set_errno (ENOMEM); diff --git a/sysdeps/unix/sysv/linux/brk_call.h b/sysdeps/unix/sysv/linux/brk_call.h new file mode 100644 index 0000000000..72370c25d7 --- /dev/null +++ b/sysdeps/unix/sysv/linux/brk_call.h @@ -0,0 +1,25 @@ +/* Invoke the brk system call. Generic Linux version. + Copyright (C) 2022 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, see + . */ + +static inline void * +__brk_call (void *addr) +{ + /* The default implementation reports errors through an unchanged + break. */ + return (void *) INTERNAL_SYSCALL_CALL (brk, addr); +} diff --git a/sysdeps/unix/sysv/linux/sparc/brk.c b/sysdeps/unix/sysv/linux/sparc/brk.c deleted file mode 100644 index c5c1ee0282..0000000000 --- a/sysdeps/unix/sysv/linux/sparc/brk.c +++ /dev/null @@ -1,58 +0,0 @@ -/* Change data segment. Linux SPARC version. - Copyright (C) 2021-2022 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, see - . */ - -#include -#include -#include - -/* This must be initialized data because commons can't have aliases. */ -void *__curbrk = 0; - -#if HAVE_INTERNAL_BRK_ADDR_SYMBOL -/* Old braindamage in GCC's crtstuff.c requires this symbol in an attempt - to work around different old braindamage in the old Linux ELF dynamic - linker. */ -weak_alias (__curbrk, ___brk_addr) -#endif - -#ifdef __arch64__ -# define SYSCALL_NUM "0x6d" -#else -# define SYSCALL_NUM "0x10" -#endif - -int -__brk (void *addr) -{ - register long int g1 asm ("g1") = __NR_brk; - register long int o0 asm ("o0") = (long int) addr; - asm volatile ("ta " SYSCALL_NUM - : "=r"(o0) - : "r"(g1), "0"(o0) - : "cc"); - __curbrk = (void *) o0; - - if (__curbrk < addr) - { - __set_errno (ENOMEM); - return -1; - } - - return 0; -} -weak_alias (__brk, brk) diff --git a/sysdeps/unix/sysv/linux/sparc/brk_call.h b/sysdeps/unix/sysv/linux/sparc/brk_call.h new file mode 100644 index 0000000000..59ce521660 --- /dev/null +++ b/sysdeps/unix/sysv/linux/sparc/brk_call.h @@ -0,0 +1,35 @@ +/* Invoke the brk system call. Sparc version. + Copyright (C) 2022 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, see + . */ + +#ifdef __arch64__ +# define SYSCALL_NUM "0x6d" +#else +# define SYSCALL_NUM "0x10" +#endif + +static inline void * +__brk_call (void *addr) +{ + register long int g1 asm ("g1") = __NR_brk; + register long int o0 asm ("o0") = (long int) addr; + asm volatile ("ta " SYSCALL_NUM + : "=r"(o0) + : "r"(g1), "0"(o0) + : "cc"); + return (void *) o0; +} -- cgit 1.4.1