summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/libc/arch/alpha/gen/Makefile.inc6
-rw-r--r--lib/libc/arch/hppa/gen/Makefile.inc3
-rw-r--r--lib/libc/arch/m88k/gen/Makefile.inc3
-rw-r--r--lib/libc/arch/mips/gen/Makefile.inc3
-rw-r--r--lib/libc/arch/powerpc/gen/Makefile.inc1
-rw-r--r--lib/libc/arch/sparc/gen/Makefile.inc3
-rw-r--r--lib/libc/arch/sparc64/gen/Makefile.inc3
-rw-r--r--lib/libc/gen/alloca.c133
8 files changed, 147 insertions, 8 deletions
diff --git a/lib/libc/arch/alpha/gen/Makefile.inc b/lib/libc/arch/alpha/gen/Makefile.inc
index b9df181ef49..67af127a822 100644
--- a/lib/libc/arch/alpha/gen/Makefile.inc
+++ b/lib/libc/arch/alpha/gen/Makefile.inc
@@ -1,8 +1,8 @@
-# $OpenBSD: Makefile.inc,v 1.4 2001/09/10 22:38:11 millert Exp $
+# $OpenBSD: Makefile.inc,v 1.5 2003/05/02 19:20:26 millert Exp $
# $NetBSD: Makefile.inc,v 1.3 1995/04/29 05:09:14 cgd Exp $
-SRCS+= _setjmp.S fabs.S frexp.c infinity.c isinf.c isnan.c ldexp.c modf.c \
- setjmp.S
+SRCS+= _setjmp.S alloca.c fabs.S frexp.c infinity.c isinf.c isnan.c ldexp.c \
+ modf.c setjmp.S
SRCS+= flt_rounds.c fpgetmask.c fpgetround.c fpgetsticky.c fpsetmask.c \
fpsetround.c fpsetsticky.c
SRCS+= sigsetjmp.S
diff --git a/lib/libc/arch/hppa/gen/Makefile.inc b/lib/libc/arch/hppa/gen/Makefile.inc
index 26a255cdba7..e59f0cd20ff 100644
--- a/lib/libc/arch/hppa/gen/Makefile.inc
+++ b/lib/libc/arch/hppa/gen/Makefile.inc
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile.inc,v 1.5 2002/05/17 18:41:02 mickey Exp $
+# $OpenBSD: Makefile.inc,v 1.6 2003/05/02 19:20:26 millert Exp $
SRCS+= setjmp.S
SRCS+= fabs.c frexp.c ldexp.c
@@ -6,3 +6,4 @@ SRCS+= isnan.c isinf.c infinity.c setjmp.S
SRCS+= flt_rounds.c fpgetmask.c fpgetround.c fpgetsticky.c fpsetmask.c \
fpsetround.c fpsetsticky.c
SRCS+= modf.c
+SRCS+= alloca.c
diff --git a/lib/libc/arch/m88k/gen/Makefile.inc b/lib/libc/arch/m88k/gen/Makefile.inc
index c89d6e16a5a..a21dd5d2966 100644
--- a/lib/libc/arch/m88k/gen/Makefile.inc
+++ b/lib/libc/arch/m88k/gen/Makefile.inc
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile.inc,v 1.2 2001/09/21 14:49:15 miod Exp $
+# $OpenBSD: Makefile.inc,v 1.3 2003/05/02 19:20:26 millert Exp $
# $NetBSD: Makefile.inc,v 1.3 1995/04/10 21:09:06 jtc Exp $
#SRCS+= _setjmp.S fabs.S frexp.c infinity.c isinf.c isnan.c ldexp.c modf.S
@@ -11,3 +11,4 @@ SRCS+= flt_rounds.c fpgetmask.c fpgetround.c fpgetsticky.c fpsetmask.c \
fpsetround.c fpsetsticky.c
SRCS+= setjmp.S sigsetjmp.S
SRCS+= modf.c
+SRCS+= alloca.c
diff --git a/lib/libc/arch/mips/gen/Makefile.inc b/lib/libc/arch/mips/gen/Makefile.inc
index d2afa4040a2..27d23fc3e9b 100644
--- a/lib/libc/arch/mips/gen/Makefile.inc
+++ b/lib/libc/arch/mips/gen/Makefile.inc
@@ -1,6 +1,7 @@
-# $OpenBSD: Makefile.inc,v 1.3 1996/08/19 08:15:50 tholo Exp $
+# $OpenBSD: Makefile.inc,v 1.4 2003/05/02 19:20:26 millert Exp $
SRCS+= _setjmp.S fabs.S frexp.c infinity.c isinf.S ldexp.S modf.S
SRCS+= flt_rounds.c fpgetmask.c fpgetround.c fpgetsticky.c fpsetmask.c \
fpsetround.c fpsetsticky.c
SRCS+= setjmp.S sigsetjmp.S
+SRCS+= alloca.c
diff --git a/lib/libc/arch/powerpc/gen/Makefile.inc b/lib/libc/arch/powerpc/gen/Makefile.inc
index 3e0e5091c31..7f9092c3dc4 100644
--- a/lib/libc/arch/powerpc/gen/Makefile.inc
+++ b/lib/libc/arch/powerpc/gen/Makefile.inc
@@ -3,3 +3,4 @@ SRCS+= ldexp.c fabs.c frexp.c
SRCS+= fpgetmask.c fpsetmask.c
SRCS+= fpgetround.c fpsetround.c
SRCS+= fpgetsticky.c fpsetsticky.c
+SRCS+= alloca.c
diff --git a/lib/libc/arch/sparc/gen/Makefile.inc b/lib/libc/arch/sparc/gen/Makefile.inc
index d0fa7366173..95e1b4011ef 100644
--- a/lib/libc/arch/sparc/gen/Makefile.inc
+++ b/lib/libc/arch/sparc/gen/Makefile.inc
@@ -1,6 +1,7 @@
-# $OpenBSD: Makefile.inc,v 1.2 1996/08/19 08:17:24 tholo Exp $
+# $OpenBSD: Makefile.inc,v 1.3 2003/05/02 19:20:26 millert Exp $
SRCS+= _setjmp.S fabs.S frexp.c infinity.c isinf.c isnan.c ldexp.c modf.S
SRCS+= flt_rounds.c fpgetmask.c fpgetround.c fpgetsticky.c fpsetmask.c \
fpsetround.c fpsetsticky.c
SRCS+= fixunsdfsi.S mul.S umul.S saveregs.S setjmp.S sigsetjmp.S
+SRCS+= alloca.c
diff --git a/lib/libc/arch/sparc64/gen/Makefile.inc b/lib/libc/arch/sparc64/gen/Makefile.inc
index fc594a5525e..227469f6920 100644
--- a/lib/libc/arch/sparc64/gen/Makefile.inc
+++ b/lib/libc/arch/sparc64/gen/Makefile.inc
@@ -1,6 +1,7 @@
-# $OpenBSD: Makefile.inc,v 1.1 2001/08/29 01:48:12 art Exp $
+# $OpenBSD: Makefile.inc,v 1.2 2003/05/02 19:20:26 millert Exp $
SRCS+= _setjmp.S fabs.S frexp.c infinity.c isinf.c isnan.c ldexp.c modf.S
SRCS+= flt_rounds.c fpgetmask.c fpgetround.c fpgetsticky.c fpsetmask.c \
fpsetround.c fpsetsticky.c
SRCS+= fixunsdfsi.S mul.S umul.S saveregs.S setjmp.S sigsetjmp.S
+SRCS+= alloca.c
diff --git a/lib/libc/gen/alloca.c b/lib/libc/gen/alloca.c
new file mode 100644
index 00000000000..0855700596a
--- /dev/null
+++ b/lib/libc/gen/alloca.c
@@ -0,0 +1,133 @@
+/* alloca.c -- allocate automatically reclaimed memory
+ (Mostly) portable public-domain implementation -- D A Gwyn
+
+ This implementation of the PWB library alloca function,
+ which is used to allocate space off the run-time stack so
+ that it is automatically reclaimed upon procedure exit,
+ was inspired by discussions with J. Q. Johnson of Cornell.
+
+ There are some preprocessor constants that can
+ be defined when compiling for your specific system, for
+ improved efficiency; however, the defaults should be okay.
+
+ The general concept of this implementation is to keep
+ track of all alloca-allocated blocks, and reclaim any
+ that are found to be deeper in the stack than the current
+ invocation. This heuristic does not reclaim storage as
+ soon as it becomes invalid, but it will do so eventually.
+
+ As a special case, alloca(0) reclaims storage without
+ allocating any. It is a good idea to use alloca(0) in
+ your main control loop, etc. to force garbage collection. */
+
+/* If someone has defined alloca as a macro,
+ there must be some other way alloca is supposed to work. */
+#ifndef alloca
+
+#include <string.h>
+#include <stdlib.h>
+
+/* If your stack is a linked list of frames, you have to
+ provide an "address metric" ADDRESS_FUNCTION macro. */
+
+#define ADDRESS_FUNCTION(arg) &(arg)
+
+typedef void *pointer;
+
+/* Define STACK_DIRECTION for your cpu:
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses */
+
+#if defined(__alpha__) || defined(__m68k__) || defined(__i386__) || \
+ defined(__m88k__) || defined(__mips__) || defined(__powerpc__) || \
+ defined(__sparc__) || defined(__sparc64__) || defined(__vax__)
+# define STACK_DIRECTION -1
+#elif defined(__hppa__)
+# define STACK_DIRECTION 1
+#else
+# error must specify stack direction
+#endif
+
+/* An "alloca header" is used to:
+ (a) chain together all alloca'ed blocks;
+ (b) keep track of stack depth.
+
+ It is very important that sizeof(header) agree with malloc
+ alignment chunk size. The following default should work okay. */
+
+#ifndef ALIGN_SIZE
+#define ALIGN_SIZE sizeof(double)
+#endif
+
+typedef union hdr
+{
+ char align[ALIGN_SIZE]; /* To force sizeof(header). */
+ struct
+ {
+ union hdr *next; /* For chaining headers. */
+ char *deep; /* For stack depth measure. */
+ } h;
+} header;
+
+static header *last_alloca_header = NULL; /* -> last alloca header. */
+
+/* Return a pointer to at least SIZE bytes of storage,
+ which will be automatically reclaimed upon exit from
+ the procedure that called alloca. Originally, this space
+ was supposed to be taken from the current stack frame of the
+ caller, but that method cannot be made to work for some
+ implementations of C, for example under Gould's UTX/32. */
+
+pointer
+alloca (size)
+ unsigned size;
+{
+ auto char probe; /* Probes stack depth: */
+ register char *depth = ADDRESS_FUNCTION (probe);
+
+ /* Reclaim garbage, defined as all alloca'd storage that
+ was allocated from deeper in the stack than currently. */
+
+ {
+ register header *hp; /* Traverses linked list. */
+
+ for (hp = last_alloca_header; hp != NULL;)
+ if ((STACK_DIRECTION > 0 && hp->h.deep > depth)
+ || (STACK_DIRECTION < 0 && hp->h.deep < depth))
+ {
+ register header *np = hp->h.next;
+
+ free ((pointer) hp); /* Collect garbage. */
+
+ hp = np; /* -> next header. */
+ }
+ else
+ break; /* Rest are not deeper. */
+
+ last_alloca_header = hp; /* -> last valid storage. */
+ }
+
+ if (size == 0)
+ return NULL; /* No allocation required. */
+
+ /* Allocate combined header + user data storage. */
+
+ {
+ register pointer new = malloc (sizeof (header) + size);
+ /* Address of header. */
+
+ if (new == 0)
+ abort();
+
+ ((header *) new)->h.next = last_alloca_header;
+ ((header *) new)->h.deep = depth;
+
+ last_alloca_header = (header *) new;
+
+ /* User storage begins just after header. */
+
+ return (pointer) ((char *) new + sizeof (header));
+ }
+}
+
+#endif /* no alloca */