08c3a6
commit 43d77ef9b87533221890423e491eed1b8ca81f0c
08c3a6
Author: Florian Weimer <fweimer@redhat.com>
08c3a6
Date:   Mon May 16 18:41:43 2022 +0200
08c3a6
08c3a6
    Linux: Introduce __brk_call for invoking the brk system call
08c3a6
    
08c3a6
    Alpha and sparc can now use the generic implementation.
08c3a6
    
08c3a6
    Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
08c3a6
    (cherry picked from commit b57ab258c1140bc45464b4b9908713e3e0ee35aa)
08c3a6
08c3a6
diff --git a/sysdeps/unix/sysv/linux/alpha/brk_call.h b/sysdeps/unix/sysv/linux/alpha/brk_call.h
08c3a6
new file mode 100644
08c3a6
index 0000000000000000..b8088cf13f938c88
08c3a6
--- /dev/null
08c3a6
+++ b/sysdeps/unix/sysv/linux/alpha/brk_call.h
08c3a6
@@ -0,0 +1,28 @@
08c3a6
+/* Invoke the brk system call.  Alpha version.
08c3a6
+   Copyright (C) 2022 Free Software Foundation, Inc.
08c3a6
+   This file is part of the GNU C Library.
08c3a6
+
08c3a6
+   The GNU C Library is free software; you can redistribute it and/or
08c3a6
+   modify it under the terms of the GNU Lesser General Public
08c3a6
+   License as published by the Free Software Foundation; either
08c3a6
+   version 2.1 of the License, or (at your option) any later version.
08c3a6
+
08c3a6
+   The GNU C Library is distributed in the hope that it will be useful,
08c3a6
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
08c3a6
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
08c3a6
+   Lesser General Public License for more details.
08c3a6
+
08c3a6
+   You should have received a copy of the GNU Lesser General Public
08c3a6
+   License along with the GNU C Library.  If not, see
08c3a6
+   <https://www.gnu.org/licenses/>.  */
08c3a6
+
08c3a6
+static inline void *
08c3a6
+__brk_call (void *addr)
08c3a6
+{
08c3a6
+  unsigned long int result = INTERNAL_SYSCALL_CALL (brk, addr);
08c3a6
+  if (result == -ENOMEM)
08c3a6
+    /* Mimic the default error reporting behavior.  */
08c3a6
+    return addr;
08c3a6
+  else
08c3a6
+    return (void *) result;
08c3a6
+}
08c3a6
diff --git a/sysdeps/unix/sysv/linux/brk.c b/sysdeps/unix/sysv/linux/brk.c
08c3a6
index 2d70d824fc72d32d..20b11c15caae148d 100644
08c3a6
--- a/sysdeps/unix/sysv/linux/brk.c
08c3a6
+++ b/sysdeps/unix/sysv/linux/brk.c
08c3a6
@@ -19,6 +19,7 @@
08c3a6
 #include <errno.h>
08c3a6
 #include <unistd.h>
08c3a6
 #include <sysdep.h>
08c3a6
+#include <brk_call.h>
08c3a6
 
08c3a6
 /* This must be initialized data because commons can't have aliases.  */
08c3a6
 void *__curbrk = 0;
08c3a6
@@ -33,7 +34,7 @@ weak_alias (__curbrk, ___brk_addr)
08c3a6
 int
08c3a6
 __brk (void *addr)
08c3a6
 {
08c3a6
-  __curbrk = (void *) INTERNAL_SYSCALL_CALL (brk, addr);
08c3a6
+  __curbrk = __brk_call (addr);
08c3a6
   if (__curbrk < addr)
08c3a6
     {
08c3a6
       __set_errno (ENOMEM);
08c3a6
diff --git a/sysdeps/unix/sysv/linux/brk_call.h b/sysdeps/unix/sysv/linux/brk_call.h
08c3a6
new file mode 100644
08c3a6
index 0000000000000000..72370c25d785a9ab
08c3a6
--- /dev/null
08c3a6
+++ b/sysdeps/unix/sysv/linux/brk_call.h
08c3a6
@@ -0,0 +1,25 @@
08c3a6
+/* Invoke the brk system call.  Generic Linux version.
08c3a6
+   Copyright (C) 2022 Free Software Foundation, Inc.
08c3a6
+   This file is part of the GNU C Library.
08c3a6
+
08c3a6
+   The GNU C Library is free software; you can redistribute it and/or
08c3a6
+   modify it under the terms of the GNU Lesser General Public
08c3a6
+   License as published by the Free Software Foundation; either
08c3a6
+   version 2.1 of the License, or (at your option) any later version.
08c3a6
+
08c3a6
+   The GNU C Library is distributed in the hope that it will be useful,
08c3a6
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
08c3a6
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
08c3a6
+   Lesser General Public License for more details.
08c3a6
+
08c3a6
+   You should have received a copy of the GNU Lesser General Public
08c3a6
+   License along with the GNU C Library.  If not, see
08c3a6
+   <https://www.gnu.org/licenses/>.  */
08c3a6
+
08c3a6
+static inline void *
08c3a6
+__brk_call (void *addr)
08c3a6
+{
08c3a6
+  /* The default implementation reports errors through an unchanged
08c3a6
+     break.  */
08c3a6
+  return (void *) INTERNAL_SYSCALL_CALL (brk, addr);
08c3a6
+}
08c3a6
diff --git a/sysdeps/unix/sysv/linux/alpha/brk.c b/sysdeps/unix/sysv/linux/sparc/brk_call.h
08c3a6
similarity index 61%
08c3a6
rename from sysdeps/unix/sysv/linux/alpha/brk.c
08c3a6
rename to sysdeps/unix/sysv/linux/sparc/brk_call.h
08c3a6
index 074c47e054bfeb11..59ce5216601143fb 100644
08c3a6
--- a/sysdeps/unix/sysv/linux/alpha/brk.c
08c3a6
+++ b/sysdeps/unix/sysv/linux/sparc/brk_call.h
08c3a6
@@ -1,5 +1,5 @@
08c3a6
-/* Change data segment size.  Linux/Alpha.
08c3a6
-   Copyright (C) 2020-2021 Free Software Foundation, Inc.
08c3a6
+/* Invoke the brk system call.  Sparc version.
08c3a6
+   Copyright (C) 2022 Free Software Foundation, Inc.
08c3a6
    This file is part of the GNU C Library.
08c3a6
 
08c3a6
    The GNU C Library is free software; you can redistribute it and/or
08c3a6
@@ -16,23 +16,20 @@
08c3a6
    License along with the GNU C Library.  If not, see
08c3a6
    <https://www.gnu.org/licenses/>.  */
08c3a6
 
08c3a6
-#include <errno.h>
08c3a6
-#include <unistd.h>
08c3a6
-#include <sysdep.h>
08c3a6
+#ifdef __arch64__
08c3a6
+# define SYSCALL_NUM "0x6d"
08c3a6
+#else
08c3a6
+# define SYSCALL_NUM "0x10"
08c3a6
+#endif
08c3a6
 
08c3a6
-void *__curbrk = 0;
08c3a6
-
08c3a6
-int
08c3a6
-__brk (void *addr)
08c3a6
+static inline void *
08c3a6
+__brk_call (void *addr)
08c3a6
 {
08c3a6
-  /* Alpha brk returns -ENOMEM in case of failure.  */
08c3a6
-  __curbrk = (void *) INTERNAL_SYSCALL_CALL (brk, addr);
08c3a6
-  if ((unsigned long) __curbrk == -ENOMEM)
08c3a6
-    {
08c3a6
-      __set_errno (ENOMEM);
08c3a6
-      return -1;
08c3a6
-    }
08c3a6
-
08c3a6
-  return 0;
08c3a6
+  register long int g1 asm ("g1") = __NR_brk;
08c3a6
+  register long int o0 asm ("o0") = (long int) addr;
08c3a6
+  asm volatile ("ta " SYSCALL_NUM
08c3a6
+		: "=r"(o0)
08c3a6
+		: "r"(g1), "0"(o0)
08c3a6
+		: "cc");
08c3a6
+  return (void *) o0;
08c3a6
 }
08c3a6
-weak_alias (__brk, brk)