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