Browse Source

Make a brk/sbrk emulation.

Mac OS X seems to have some difficulties with brk/sbrk (maybe with the
4MB heap limit), and replace all the allocation logic will be prone to
errors, I'll add a new define and lib to emulate brk/sbrk using more
standard allocation methods. By default the heap is 64MB, it should be
enough.
Manoel Trapier 11 years ago
parent
commit
5f00cd2e53
8 changed files with 134 additions and 5 deletions
  1. 16 0
      h/missing_proto.h
  2. 20 0
      modules/src/sbrk/pmfile
  3. 83 0
      modules/src/sbrk/sbrk_emu.c
  4. 1 0
      modules/src/system/break.c
  5. 8 3
      pmfile
  6. 2 0
      util/LLgen/pmfile-ack
  7. 2 1
      util/led/pmfile
  8. 2 1
      util/ncgg/pmfile

+ 16 - 0
h/missing_proto.h

@@ -10,4 +10,20 @@ int   brk(void * addr);
 char *mktemp(char *template);
 #endif
 
+#ifdef EMULATE_BRK
+void *sbrk_emu(int increment);
+int   brk_emu(void * addr);
+
+#ifdef sbrk
+#undef sbrk
+#endif
+#ifdef brk
+#undef brk
+#endif
+
+#define sbrk sbrk_emu
+#define brk brk_emu
+
+#endif
+
 #endif /* H_MISSING_H */

+ 20 - 0
modules/src/sbrk/pmfile

@@ -0,0 +1,20 @@
+-- $Source$
+-- $State$
+
+local d = "modules/src/sbrk/"
+lib_sbrk = file (LIBDIR.."libsbrk.a")
+
+module_sbrk = clibrary {
+	cfile (d.."sbrk_emu.c"),
+	
+	outputs = {"%U%/libsbrk.a"},
+	install = {
+		pm.install(LIBDIR.."libsbrk.a"),
+	}
+}
+
+-- Revision history
+-- $Log$
+-- Revision 1.1  2013/03/27 godzil
+-- First version.
+--

+ 83 - 0
modules/src/sbrk/sbrk_emu.c

@@ -0,0 +1,83 @@
+/*
+ * The Amsterdam Compiler Kit
+ * See the copyright notice in the ACK home directory, in the file "Copyright".
+ */
+/* 
+ * sbrk(), brk() emulation based on calloc() 
+ * Based on version from D A Gwyn
+ * 02-Mar-1990     D A Gwyn 
+ * http://www.linuxmisc.com/10-unix-questions/0875f91c36e18724.htm
+ */
+#include <stdio.h>
+#include <errno.h>                      /* for errno, ENOMEM */
+#if __STDC__
+#include <stdlib.h>                     /* for calloc */
+#else 
+extern char *calloc();
+#endif
+
+/* Allocate 64MB to brk/sbrk should be enough for such application */
+#ifndef HEAP_SIZE                       /* with 32-bit ints, 0x200000 is recommended */
+#define HEAP_SIZE       0x4000000       /* size of simulated heap, in bytes */
+#endif
+#define BRK_OK          0
+#define BRK_ERR         (-1)
+#define SBRK_ERR        ((void *)-1)    /* horrible interface design */
+
+static void *bottom = NULL;             /* bottom of calloc()ed pseudo-heap */
+static void *brkval = NULL;             /* current value of simulated break */
+
+int brk_emu( void *endds )
+{
+	int offset;
+	if ( bottom == NULL )
+	{
+		if ( (bottom = calloc( HEAP_SIZE, 1 )) == 0 )
+		{
+			return BRK_ERR; /* unable to set up pseudo-heap */
+		}
+		else
+		{
+			brkval = bottom;
+		}
+	}
+
+	if ( (offset = endds - bottom) < 0 || offset > HEAP_SIZE )
+	{
+		errno = ENOMEM;
+		return BRK_ERR; /* attempt to set break out of heap */
+	}
+	else
+	{
+		brkval = endds;
+		return BRK_OK;
+	}
+}
+
+void *sbrk_emu(int incr)
+{
+	int offset;
+	if ( bottom == 0 )
+	{
+		if ( (bottom = (char *)calloc( HEAP_SIZE, 1 )) == 0 )
+		{
+			return SBRK_ERR; /* unable to set up heap */
+		}
+		else
+		{
+			brkval = bottom;
+		}
+	}
+
+	if ( (offset = (brkval - bottom) + incr) < 0 || offset > HEAP_SIZE )
+	{
+		errno = ENOMEM;
+		return SBRK_ERR; /* attempt to set break out of heap */
+	}
+	else
+	{
+		char *oldbrk = brkval;
+		brkval += incr;
+		return oldbrk;
+	}
+}

+ 1 - 0
modules/src/system/break.c

@@ -6,6 +6,7 @@
 
 #include "system.h"
 #include <unistd.h>
+#include <missing_proto.h>
 
 char *sys_break(int incr)
 {

+ 8 - 3
pmfile

@@ -19,6 +19,8 @@ CINCLUDES = {
 
 include "util/data/pmfile"
 
+include "modules/src/sbrk/pmfile"
+
 include "util/LLgen/pmfile-ack"
 
 include "modules/src/alloc/pmfile"
@@ -103,7 +105,10 @@ include "plat/nes/pmfile"	            -- NES
 
 default = group {
 	-- Lots of things use LLgen, so we need to build it first.
-	
+
+	-- Need it before anything else! (even LLgen depends on it)
+	module_sbrk,
+
 	tool_LLgen,
 	
 	-- Some of the dependency management across modules isn't entirely
@@ -181,8 +186,8 @@ default = group {
 	-- Build the platforms.
 	
 	platform_pc86,
-	platform_linux386,
-	platform_cpm,
+--	platform_linux386,
+--	platform_cpm,
 --	platform_nes,
 }
 

+ 2 - 0
util/LLgen/pmfile-ack

@@ -26,6 +26,8 @@ tool_LLgen = cprogram {
 	cfile (d.."src/Lpars.c"),
 	cfile (d.."src/tokens.c"),
 
+	lib_sbrk,
+
 	outputs = {"%U%/LLgen"},
 	install = pm.install("%TOOLDIR%LLgen")
 }

+ 2 - 1
util/led/pmfile

@@ -20,7 +20,8 @@ tool_led = cprogram {
 
 	lib_string,
 	lib_object,
-	
+	lib_sbrk,
+
 	outputs = {"%U%/led"},
 	install = {
 		-- FIXME lib.bin in next line needs removing --- pm bug?

+ 2 - 1
util/ncgg/pmfile

@@ -51,7 +51,8 @@ tool_ncgg = cprogram {
 	},
 	
 	lib_em_data,
-	
+	lib_sbrk,
+
 	outputs = {"%U%-ncgg"},
 	install = pm.install(TOOLDIR.."ncgg")
 }