diff options
author | Florian Weimer <fweimer@redhat.com> | 2022-05-16 18:41:43 +0200 |
---|---|---|
committer | Florian Weimer <fweimer@redhat.com> | 2022-05-16 18:41:52 +0200 |
commit | b57ab258c1140bc45464b4b9908713e3e0ee35aa (patch) | |
tree | 12fbebff5ad78dfa98c9d59526f0bd8e36c702f1 /sysdeps/unix | |
parent | 21244c70c24db4b3bd7a2169a7a48f637cad5930 (diff) | |
download | glibc-b57ab258c1140bc45464b4b9908713e3e0ee35aa.zip glibc-b57ab258c1140bc45464b4b9908713e3e0ee35aa.tar.gz glibc-b57ab258c1140bc45464b4b9908713e3e0ee35aa.tar.bz2 |
Linux: Introduce __brk_call for invoking the brk system call
Alpha and sparc can now use the generic implementation.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Diffstat (limited to 'sysdeps/unix')
-rw-r--r-- | sysdeps/unix/sysv/linux/alpha/brk_call.h | 28 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/brk.c | 3 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/brk_call.h | 25 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/sparc/brk.c | 58 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/sparc/brk_call.h (renamed from sysdeps/unix/sysv/linux/alpha/brk.c) | 35 |
5 files changed, 71 insertions, 78 deletions
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 0000000..b8088cf --- /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 + <https://www.gnu.org/licenses/>. */ + +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 abbabc9..9264a5a 100644 --- a/sysdeps/unix/sysv/linux/brk.c +++ b/sysdeps/unix/sysv/linux/brk.c @@ -19,6 +19,7 @@ #include <errno.h> #include <unistd.h> #include <sysdep.h> +#include <brk_call.h> /* 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 0000000..72370c2 --- /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 + <https://www.gnu.org/licenses/>. */ + +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 c5c1ee0..0000000 --- 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 - <https://www.gnu.org/licenses/>. */ - -#include <errno.h> -#include <unistd.h> -#include <sysdep.h> - -/* 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/alpha/brk.c b/sysdeps/unix/sysv/linux/sparc/brk_call.h index 32082a4..59ce521 100644 --- a/sysdeps/unix/sysv/linux/alpha/brk.c +++ b/sysdeps/unix/sysv/linux/sparc/brk_call.h @@ -1,5 +1,5 @@ -/* Change data segment size. Linux/Alpha. - Copyright (C) 2020-2022 Free Software Foundation, Inc. +/* 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 @@ -16,23 +16,20 @@ License along with the GNU C Library. If not, see <https://www.gnu.org/licenses/>. */ -#include <errno.h> -#include <unistd.h> -#include <sysdep.h> +#ifdef __arch64__ +# define SYSCALL_NUM "0x6d" +#else +# define SYSCALL_NUM "0x10" +#endif -void *__curbrk = 0; - -int -__brk (void *addr) +static inline void * +__brk_call (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; + 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; } -weak_alias (__brk, brk) |