93dc2d
commit 1d9764aba8c00754fbf8299e48afbe222245ee3e
93dc2d
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
93dc2d
Date:   Wed Aug 4 21:34:12 2021 +0300
93dc2d
93dc2d
    linux: Add sparck brk implementation
93dc2d
    
93dc2d
    It turned that the generic implementation of brk() does not work
93dc2d
    for sparc, since on failure kernel will just return the previous
93dc2d
    input value without setting the conditional register.
93dc2d
    
93dc2d
    This patches adds back a sparc32 and sparc64 implementation removed
93dc2d
    by 720480934ab9107.
93dc2d
    
93dc2d
    Checked on sparc64-linux-gnu and sparcv9-linux-gnu.
93dc2d
    
93dc2d
    (cherry picked from commit 5b86241a032c50462988bdd1439e078384690d34)
93dc2d
93dc2d
diff --git a/sysdeps/unix/sysv/linux/sparc/brk.c b/sysdeps/unix/sysv/linux/sparc/brk.c
93dc2d
new file mode 100644
93dc2d
index 0000000000000000..aafe9673e3062cf8
93dc2d
--- /dev/null
93dc2d
+++ b/sysdeps/unix/sysv/linux/sparc/brk.c
93dc2d
@@ -0,0 +1,58 @@
93dc2d
+/* Change data segment.  Linux SPARC version.
93dc2d
+   Copyright (C) 2021 Free Software Foundation, Inc.
93dc2d
+   This file is part of the GNU C Library.
93dc2d
+
93dc2d
+   The GNU C Library is free software; you can redistribute it and/or
93dc2d
+   modify it under the terms of the GNU Lesser General Public
93dc2d
+   License as published by the Free Software Foundation; either
93dc2d
+   version 2.1 of the License, or (at your option) any later version.
93dc2d
+
93dc2d
+   The GNU C Library is distributed in the hope that it will be useful,
93dc2d
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
93dc2d
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
93dc2d
+   Lesser General Public License for more details.
93dc2d
+
93dc2d
+   You should have received a copy of the GNU Lesser General Public
93dc2d
+   License along with the GNU C Library.  If not, see
93dc2d
+   <https://www.gnu.org/licenses/>.  */
93dc2d
+
93dc2d
+#include <errno.h>
93dc2d
+#include <unistd.h>
93dc2d
+#include <sysdep.h>
93dc2d
+
93dc2d
+/* This must be initialized data because commons can't have aliases.  */
93dc2d
+void *__curbrk = 0;
93dc2d
+
93dc2d
+#if HAVE_INTERNAL_BRK_ADDR_SYMBOL
93dc2d
+/* Old braindamage in GCC's crtstuff.c requires this symbol in an attempt
93dc2d
+   to work around different old braindamage in the old Linux ELF dynamic
93dc2d
+   linker.  */
93dc2d
+weak_alias (__curbrk, ___brk_addr)
93dc2d
+#endif
93dc2d
+
93dc2d
+#ifdef __arch64__
93dc2d
+# define SYSCALL_NUM "0x6d"
93dc2d
+#else
93dc2d
+# define SYSCALL_NUM "0x10"
93dc2d
+#endif
93dc2d
+
93dc2d
+int
93dc2d
+__brk (void *addr)
93dc2d
+{
93dc2d
+  register long int g1 asm ("g1") = __NR_brk;
93dc2d
+  register long int o0 asm ("o0") = (long int) addr;
93dc2d
+  asm volatile ("ta " SYSCALL_NUM
93dc2d
+		: "=r"(o0)
93dc2d
+		: "r"(g1), "0"(o0)
93dc2d
+		: "cc");
93dc2d
+  __curbrk = (void *) o0;
93dc2d
+
93dc2d
+  if (__curbrk < addr)
93dc2d
+    {
93dc2d
+      __set_errno (ENOMEM);
93dc2d
+      return -1;
93dc2d
+    }
93dc2d
+
93dc2d
+  return 0;
93dc2d
+}
93dc2d
+weak_alias (__brk, brk)