Properly limit glibc's alloca() (XCC)
authorBarret Rhoden <brho@cs.berkeley.edu>
Tue, 19 Jul 2016 22:39:35 +0000 (18:39 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Thu, 21 Jul 2016 19:44:04 +0000 (15:44 -0400)
The old sysdep wasn't even called.  We'd need nptl to be a feature to get
that sysdep added, I think.

Instead, we'll have to change something outside the sysdeps folder:
alloca.h.

Glibc at least checks that alloca is okay before using it.  I don't think
these same sanity checks go into uses of alloca() by regular programs, so
this may pop up again in the future.

Fixes: df1135d0583e ("Specify a small alloca_cutoff (XCC)")

Rebuild glibc.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
tools/compilers/gcc-glibc/glibc-2.19-akaros/include/alloca.h [new file with mode: 0644]
tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/alloca_cutoff.c [deleted file]

diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/include/alloca.h b/tools/compilers/gcc-glibc/glibc-2.19-akaros/include/alloca.h
new file mode 100644 (file)
index 0000000..0ca1adc
--- /dev/null
@@ -0,0 +1,80 @@
+#ifndef _ALLOCA_H
+
+/* AKAROS: Modified the alloca cutoff */
+
+#include <stdlib/alloca.h>
+#include <stackinfo.h>
+
+#undef __alloca
+
+/* Now define the internal interfaces.  */
+extern void *__alloca (size_t __size);
+
+#ifdef __GNUC__
+# define __alloca(size)        __builtin_alloca (size)
+#endif /* GCC.  */
+
+extern int __libc_use_alloca (size_t size) __attribute__ ((const));
+extern int __libc_alloca_cutoff (size_t size) __attribute__ ((const));
+libc_hidden_proto (__libc_alloca_cutoff)
+
+/* AKAROS: Limit to a small amount, so 2LSs and vcore context can have small
+ * stacks. */
+#define __MAX_ALLOCA_CUTOFF    128
+
+#include <allocalim.h>
+
+#ifndef stackinfo_alloca_round
+# define stackinfo_alloca_round(l) (((l) + 15) & -16)
+#endif
+
+#if _STACK_GROWS_DOWN
+# define extend_alloca(buf, len, newlen) \
+  (__typeof (buf)) ({ size_t __newlen = stackinfo_alloca_round (newlen);      \
+                     char *__newbuf = __alloca (__newlen);                   \
+                     if (__newbuf + __newlen == (char *) buf)                \
+                       len += __newlen;                                      \
+                     else                                                    \
+                       len = __newlen;                                       \
+                     __newbuf; })
+#elif _STACK_GROWS_UP
+# define extend_alloca(buf, len, newlen) \
+  (__typeof (buf)) ({ size_t __newlen = stackinfo_alloca_round (newlen);      \
+                     char *__newbuf = __alloca (__newlen);                   \
+                     char *__buf = (buf);                                    \
+                     if (__buf + len == __newbuf)                            \
+                       {                                                     \
+                         len += __newlen;                                    \
+                         __newbuf = __buf;                                   \
+                       }                                                     \
+                     else                                                    \
+                       len = __newlen;                                       \
+                     __newbuf; })
+#else
+# define extend_alloca(buf, len, newlen) \
+  __alloca (((len) = (newlen)))
+#endif
+
+#if defined stackinfo_get_sp && defined stackinfo_sub_sp
+# define alloca_account(size, avar) \
+  ({ void *old__ = stackinfo_get_sp ();                                              \
+     void *m__ = __alloca (size);                                            \
+     avar += stackinfo_sub_sp (old__);                                       \
+     m__; })
+# define extend_alloca_account(buf, len, newlen, avar) \
+  ({ void *old__ = stackinfo_get_sp ();                                              \
+     void *m__ = extend_alloca (buf, len, newlen);                           \
+     avar += stackinfo_sub_sp (old__);                                       \
+     m__; })
+#else
+# define alloca_account(size, avar) \
+  ({ size_t s__ = (size);                                                    \
+     avar += s__;                                                            \
+     __alloca (s__); })
+# define extend_alloca_account(buf, len, newlen, avar) \
+  ({ size_t s__ = (newlen);                                                  \
+     avar += s__;                                                            \
+     extend_alloca (buf, len, s__); })
+#endif
+
+#endif
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/alloca_cutoff.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/alloca_cutoff.c
deleted file mode 100644 (file)
index a08ab2e..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/* Determine whether block of given size can be allocated on the stack or not.
-   Copyright (C) 2002-2014 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; see the file COPYING.LIB.  If
-   not, see <http://www.gnu.org/licenses/>.  */
-
-#include <alloca.h>
-#include <stdlib.h>
-
-
-int __libc_alloca_cutoff(size_t size)
-{
-       return size <= 128;
-}
-libc_hidden_def(__libc_alloca_cutoff)