This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFC PATCH] SPU malloc


Patch to add a SPU specific malloc implementation that functions better
with a limited amount of memory.

A small test program (that does not call free nor realloc) with this
allocator shows:

[elm3a225 misc]$ spu-size max-mallocs
   text    data     bss     dec     hex filename
   6456     852     160    7468    1d2c max-mallocs

Where base newlib has:

[elm3a225 misc]$ spu-size base-max-mallocs
   text    data     bss     dec     hex filename
  11192    1924     240   13356    342c base-max-mallocs

And with the above test program compared with the newlib malloc (both with
the sbrk stack check change), including use of the extra space available,
we can do:

 size     max number of allocations
(bytes)     base     SPU (new code)
   8        15030       15632
  32         5010        6936
  64         3006        3676
 128         1670        1894
 512          455         484
1024          231         243
4096           57          60

The original design and implementation coded by Joel, with some bug
fixes and cleanups by me.

Newlib ChangeLog:

2007-09-26 Joel Schopp <jschopp@austin.ibm.com>

	* configure.host: Define -DMALLOC_PROVIDED.
	* libc/include/malloc.h: Add #if checks for __SPU__ to map _nnn_r
	malloc functions to nnn.
	* libc/machine/spu/Makefile.am: Add new files.
	* libc/machine/spu/Makefile.in: Regenerate.
	* libc/machine/spu/malloc.c: New file SPU allocator.
	* libc/machine/spu/callocr.c: New file.
	* libc/machine/spu/freer.c: Ditto.
	* libc/machine/spu/malignr.c: Ditto.
	* libc/machine/spu/mallocr.c: Ditto.
	* libc/machine/spu/reallocr.c: Ditto.

Index: quilt/newlib/libc/machine/spu/malloc.c
===================================================================
--- /dev/null
+++ quilt/newlib/libc/machine/spu/malloc.c
@@ -0,0 +1,426 @@
+/*
+  Copyright 2007
+  International Business Machines Corporation,
+  Sony Computer Entertainment, Incorporated,
+  Toshiba Corporation,
+
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+  this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+  notice, this list of conditions and the following disclaimer in the
+  documentation and/or other materials provided with the distribution.
+    * Neither the names of the copyright holders nor the names of their
+  contributors may be used to endorse or promote products derived from
+  this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+  OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+ * SPU specific allocator: implements a best fit allocator designed to
+ * work well within a limited amount of memory (less than 256Kb in the
+ * SPU's Local Store).
+ */
+#include <stddef.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <errno.h>
+
+/* minimum size in bytes to add to free list */
+#define SBRK_SIZE 16
+
+#define SPU_SIZE 262144
+/* ALLOC_MIN >= ALIGN */
+#define ALLOC_MIN 16
+#define ALIGN 16
+
+#define ROUND_UP(x,y) ((x + y - 1) & ~(y - 1))
+
+typedef struct free_node {
+  uint32_t size;
+  struct free_node *prev;
+  struct free_node *next;
+  uint32_t pad;
+} free_node_t;
+
+#define TRACKING_SIZE 512
+#define TRACKING_COUNT (TRACKING_SIZE / sizeof(uint32_t) - 1)
+
+#define SMALL_ALLOC_OFFSET 0x8
+
+typedef struct tracking_node {
+  struct tracking_node *next;
+  uint32_t header[TRACKING_COUNT];
+} tracking_node_t;
+
+#define ADDR_MASK 0x0003FFFC    /* 18 bit address and assume 4 byte alignment */
+#define ADDR_SHIFT 14
+#define SIZE_MASK 0x0003FFFC    /* 18 bit size assume 4 byte increment */
+#define SIZE_SHIFT 2
+#define HEADER_ADDR_MASK 0xFFFF0000
+#define HEADER_SIZE_MASK 0x0000FFFF
+#define ENCODE_HEADER(addr, size) \
+  ((((uint32_t)addr & ADDR_MASK) << ADDR_SHIFT) | \
+   ((size & SIZE_MASK) >> SIZE_SHIFT))
+#define DECODE_HEADER_ADDR(header) ((header & HEADER_ADDR_MASK) >> ADDR_SHIFT)
+#define DECODE_HEADER_SIZE(header) ((header & HEADER_SIZE_MASK) << SIZE_SHIFT)
+
+uint32_t __remove_tracker (free_node_t *node, int remove);
+free_node_t * __coalesce_node (free_node_t *node);
+void __insert_node (free_node_t *node);
+
+#ifdef DEFINE_MALLOC
+
+static free_node_t *head = NULL;
+static tracking_node_t *thead = NULL;
+
+/*
+ * Free areas (free_node_t) are stored in an unsorted link list, as this
+ * decreases code size, but does not give poor performance because of the
+ * small amount of memory and so likely small number of free nodes to
+ * manage.
+ */
+void
+__insert_node (free_node_t *node)
+{
+  node->prev = NULL;
+  node->next = head;
+  if (head)
+    head->prev = node;
+  head = node;
+}
+
+static void
+remove_node (free_node_t *node)
+{
+  if (head == node)
+    head = node->next;
+  if (node->next)
+    node->next->prev = node->prev;
+  if (node->prev)
+    node->prev->next = node->next;
+}
+
+#define IS_BEFORE(x,y) (((uint32_t)x + x->size) == (uint32_t)y)
+
+/*
+ * When adding memory via sbrk() or freeing it via free(), memory is
+ * coalesced in order to form larger free blocks.
+ */
+free_node_t *
+__coalesce_node (free_node_t *node)
+{
+  free_node_t *current = head;
+
+  while (current != NULL) {
+    if (IS_BEFORE (current, node)) {
+      remove_node (current);
+      current->size += node->size;
+      node = current;
+    }
+    if (IS_BEFORE (node, current)) {
+      remove_node (current);
+      node->size += current->size;
+    }
+    current = current->next;
+  }
+  return node;
+}
+
+static int
+add_space (uint32_t size)
+{
+  free_node_t *ptr;
+  free_node_t *node;
+
+  if (size < SBRK_SIZE)
+    size = SBRK_SIZE;
+
+  while (1) {
+    ptr = sbrk (size);
+    if ((uint32_t) ptr != -1) {
+      break;
+    } else {
+      /* If allocation failed try half as much */
+      size = size / 2;
+      if (size < ALLOC_MIN)
+        return -1;
+      size = ROUND_UP(size, ALIGN);
+    }
+  }
+
+  /* FIFO insertion */
+  node = ptr;
+  node->size = size;
+  node = __coalesce_node (node);
+  __insert_node (node);
+
+  return size;
+}
+
+static void *
+extract (free_node_t *ptr, uint32_t size)
+{
+  free_node_t *ptr2;
+
+  remove_node (ptr);
+  ptr2 = (free_node_t *) ((uint32_t) ptr + size);
+  ptr2->size = ptr->size - size;
+  __insert_node (ptr2);
+  ptr->size = size;
+  return ptr;
+}
+
+static void *
+internal_malloc (size_t size)
+{
+  free_node_t *target = NULL;
+  free_node_t *current = head;
+  int ret;
+
+  size = ROUND_UP (size, ALIGN);
+
+  /* if the free list is empty add some to it */
+  if (current == NULL) {
+    ret = add_space (size);
+    current = head;
+    if (ret < 0)
+      return NULL;
+  }
+
+  while (1) {
+    /* find the smallest big enough free block */
+    while (current != NULL) {
+      if (current->size >= size) {
+        if (target == NULL)
+          target = current;
+        else if (target->size > current->size)
+          target = current;
+      }
+      current = current->next;
+    }
+
+    if (target) {
+      break;
+    } else {
+      /*
+       * free blocks, but none big enough. allocate one big enough and go
+       * again
+       */
+      ret = add_space (size);
+      if (ret < 0)
+        return NULL;
+      current = head;
+    }
+  }
+
+  /*
+   * If the node we found has more space than we need we should only
+   * extract as much space as we need and leave the rest on the free list.
+   *
+   * If the node is just right we remove the whole thing.
+   */
+  if (target->size >= (size + ALLOC_MIN))
+    target = extract (target, size);
+  else
+    remove_node (target);
+  return (void *) target;
+}
+
+/*
+ * Headers (trackers) are maintained out of line (not in the allocated
+ * memory) in order to save space: with the standard newlib malloc(), a 32
+ * byte alignment must be used, so a 16 byte allocation must use 32 bytes
+ * (for the header plus the allocated data). Using an out of line header,
+ * a 16 byte allocation can be done using 20 bytes.
+ */
+static void *
+insert_tracker (free_node_t *node)
+{
+  tracking_node_t *current = thead;
+  uint32_t *slot;
+  int i;
+
+  while (1) {
+    while (current) {
+      for (i = 0; i < TRACKING_COUNT; i++) {
+        if (current->header[i] == 0) {
+          slot = &current->header[i];
+          *slot = ENCODE_HEADER (node, node->size);
+          return node;
+        }
+      }
+      /* didn't find one but have more to search */
+      current = current->next;
+    }
+
+    /* still didn't find one try to allocate more */
+    current = internal_malloc (TRACKING_SIZE);
+    if (current == NULL) {
+      node->prev = NULL;
+      node->next = head;
+      head = node;
+      return NULL;
+    }
+
+    /* FIXME, see if there is a faster way to 0 */
+    memset (current->header, 0, TRACKING_COUNT * 4);
+    current->next = thead;
+    thead = current;
+  }
+}
+
+uint32_t
+__remove_tracker (free_node_t *node, int remove)
+{
+  tracking_node_t *current = thead;
+  int i;
+  uint32_t ret;
+
+  while (current) {
+    for (i = 0; i < TRACKING_SIZE; i++) {
+      if ((uint32_t) node == DECODE_HEADER_ADDR (current->header[i])) {
+        ret = DECODE_HEADER_SIZE (current->header[i]);
+        if (remove)
+          current->header[i] = 0;
+        return ret;
+      }
+    }
+    current = current->next;
+  }
+
+  /*
+   * you just freed something not allocated, bad but what are you going to
+   * do?
+   */
+  return 0;
+}
+
+/*
+ * All allocations are in increments of 16 bytes, even if only 1 or 2
+ * bytes were requested. Since the tracker will take another 4 bytes,
+ * that is a minimum of 20 bytes, and is bad for small allocations.
+ *
+ * We don't generally care about smaller allocations as they are a bad
+ * idea to begin with, but as a small concession to the fact that there
+ * are likely to be a few out there anyway we do some magic to avoid doing
+ * the 4 bytes in the header tracker. As a result only 16 bytes are used
+ * for a small allocation (1-8 bytes) and 20 bytes for a large allocation
+ * (9bytes-256KB).
+ */
+
+void *
+malloc (size_t size)
+{
+  void *ret = NULL;
+
+  if (size == 0)
+    size = 1;
+  /*
+   * This check covers negative numbers and numbers that would
+   * overflow if rounded up.
+   */
+  if (size > SPU_SIZE)
+    goto out;
+
+  ret = internal_malloc (size);
+  if (size > 8)
+    ret = insert_tracker (ret);
+  else if (ret)
+    ret = ret + SMALL_ALLOC_OFFSET;
+
+out:
+  if (!ret)
+    errno = ENOMEM;
+  return ret;
+}
+#endif
+
+#ifdef DEFINE_FREE
+void
+free (void *ptr)
+{
+  free_node_t *node;
+
+  if (ptr == NULL)
+    return;
+  if ((uint32_t) ptr & SMALL_ALLOC_OFFSET) {
+    node = (free_node_t *) ((uint32_t) ptr - SMALL_ALLOC_OFFSET);
+    node->size = 16;
+  } else {
+    node = ptr;
+    node->size = __remove_tracker (node, 1);
+  }
+  node = __coalesce_node (node);
+  __insert_node (node);
+}
+#endif
+
+#ifdef DEFINE_REALLOC
+
+#define MIN(a,b) (((a) < (b)) ? (a) : (b))
+
+/*
+ * realloc is not optimized - it does not try to extend previously
+ * malloced space, it is just a malloc-copy-free.
+ */
+
+void *
+realloc (void *ptr, size_t size)
+{
+  void *new_ptr;
+  size_t old_size = 0;
+
+  if (ptr == NULL)
+    return malloc (size);
+
+  new_ptr = malloc (size);
+  if (!new_ptr) {
+    errno = ENOMEM;
+    return 0;
+  }
+
+  if ((uint32_t) ptr & SMALL_ALLOC_OFFSET) {
+    old_size = SMALL_ALLOC_OFFSET;
+  } else {
+    old_size = __remove_tracker (ptr, 0);
+  }
+  memcpy (new_ptr, ptr, MIN (size, old_size));
+  free (ptr);
+  return (new_ptr);
+}
+#endif
+
+#ifdef DEFINE_CALLOC
+void *
+calloc (size_t n, size_t size)
+{
+  void* ret;
+
+  ret = malloc(n * size);
+  if (ret)
+    memset(ret, 0, n * size);
+  return ret;
+}
+#endif
+
+#ifdef DEFINE_MEMALIGN
+/* TODO: add a memalign */
+#endif
Index: quilt/newlib/libc/machine/spu/Makefile.in
===================================================================
--- quilt.orig/newlib/libc/machine/spu/Makefile.in
+++ quilt/newlib/libc/machine/spu/Makefile.in
@@ -73,7 +73,9 @@ DIST_COMMON = $(srcdir)/../../../../conf
 	$(srcdir)/../../../../compile $(srcdir)/../../../../compile \
 	$(srcdir)/../../../../compile $(srcdir)/../../../../compile \
 	$(srcdir)/../../../../compile $(srcdir)/../../../../compile \
-	$(srcdir)/../../../../compile
+	$(srcdir)/../../../../compile $(srcdir)/../../../../compile \
+	$(srcdir)/../../../../compile $(srcdir)/../../../../compile \
+	$(srcdir)/../../../../compile $(srcdir)/../../../../compile
 subdir = .
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/../../../acinclude.m4 \
@@ -87,32 +89,38 @@ CONFIG_CLEAN_FILES =
 LIBRARIES = $(noinst_LIBRARIES)
 ARFLAGS = cru
 lib_a_AR = $(AR) $(ARFLAGS)
-lib_a_LIBADD =
-am_lib_a_OBJECTS = lib_a-setjmp.$(OBJEXT) lib_a-clearerr.$(OBJEXT) \
-	lib_a-creat.$(OBJEXT) lib_a-fclose.$(OBJEXT) \
-	lib_a-feof.$(OBJEXT) lib_a-ferror.$(OBJEXT) \
-	lib_a-fflush.$(OBJEXT) lib_a-fgetc.$(OBJEXT) \
-	lib_a-fgetpos.$(OBJEXT) lib_a-fgets.$(OBJEXT) \
-	lib_a-fileno.$(OBJEXT) lib_a-fiprintf.$(OBJEXT) \
-	lib_a-fiscanf.$(OBJEXT) lib_a-fopen.$(OBJEXT) \
-	lib_a-fprintf.$(OBJEXT) lib_a-fputc.$(OBJEXT) \
-	lib_a-fputs.$(OBJEXT) lib_a-fread.$(OBJEXT) \
+am__DEPENDENCIES_1 = $(lpfx)calloc.$(oext) $(lpfx)free.$(oext) \
+	$(lpfx)malign.$(oext) $(lpfx)malloc.$(oext) \
+	$(lpfx)realloc.$(oext)
+lib_a_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am_lib_a_OBJECTS = lib_a-setjmp.$(OBJEXT) lib_a-callocr.$(OBJEXT) \
+	lib_a-clearerr.$(OBJEXT) lib_a-creat.$(OBJEXT) \
+	lib_a-fclose.$(OBJEXT) lib_a-feof.$(OBJEXT) \
+	lib_a-ferror.$(OBJEXT) lib_a-fflush.$(OBJEXT) \
+	lib_a-fgetc.$(OBJEXT) lib_a-fgetpos.$(OBJEXT) \
+	lib_a-fgets.$(OBJEXT) lib_a-fileno.$(OBJEXT) \
+	lib_a-fiprintf.$(OBJEXT) lib_a-fiscanf.$(OBJEXT) \
+	lib_a-fopen.$(OBJEXT) lib_a-fprintf.$(OBJEXT) \
+	lib_a-fputc.$(OBJEXT) lib_a-fputs.$(OBJEXT) \
+	lib_a-fread.$(OBJEXT) lib_a-freer.$(OBJEXT) \
 	lib_a-freopen.$(OBJEXT) lib_a-fscanf.$(OBJEXT) \
 	lib_a-fseek.$(OBJEXT) lib_a-fsetpos.$(OBJEXT) \
 	lib_a-ftell.$(OBJEXT) lib_a-fwrite.$(OBJEXT) \
 	lib_a-getc.$(OBJEXT) lib_a-getchar.$(OBJEXT) \
 	lib_a-gets.$(OBJEXT) lib_a-iprintf.$(OBJEXT) \
-	lib_a-iscanf.$(OBJEXT) lib_a-memcpy.$(OBJEXT) \
+	lib_a-iscanf.$(OBJEXT) lib_a-malignr.$(OBJEXT) \
+	lib_a-mallocr.$(OBJEXT) lib_a-memcpy.$(OBJEXT) \
 	lib_a-memmove.$(OBJEXT) lib_a-memset.$(OBJEXT) \
 	lib_a-perror.$(OBJEXT) lib_a-printf.$(OBJEXT) \
 	lib_a-putc.$(OBJEXT) lib_a-putchar.$(OBJEXT) \
-	lib_a-puts.$(OBJEXT) lib_a-remove.$(OBJEXT) \
-	lib_a-rename.$(OBJEXT) lib_a-rewind.$(OBJEXT) \
-	lib_a-scanf.$(OBJEXT) lib_a-setbuf.$(OBJEXT) \
-	lib_a-setvbuf.$(OBJEXT) lib_a-siprintf.$(OBJEXT) \
-	lib_a-siscanf.$(OBJEXT) lib_a-sleep.$(OBJEXT) \
-	lib_a-sniprintf.$(OBJEXT) lib_a-snprintf.$(OBJEXT) \
-	lib_a-sprintf.$(OBJEXT) lib_a-sscanf.$(OBJEXT) \
+	lib_a-puts.$(OBJEXT) lib_a-reallocr.$(OBJEXT) \
+	lib_a-remove.$(OBJEXT) lib_a-rename.$(OBJEXT) \
+	lib_a-rewind.$(OBJEXT) lib_a-scanf.$(OBJEXT) \
+	lib_a-setbuf.$(OBJEXT) lib_a-setvbuf.$(OBJEXT) \
+	lib_a-siprintf.$(OBJEXT) lib_a-siscanf.$(OBJEXT) \
+	lib_a-sleep.$(OBJEXT) lib_a-sniprintf.$(OBJEXT) \
+	lib_a-snprintf.$(OBJEXT) lib_a-sprintf.$(OBJEXT) \
+	lib_a-sscanf.$(OBJEXT) lib_a-stack_reg_va.$(OBJEXT) \
 	lib_a-stdio.$(OBJEXT) lib_a-strcat.$(OBJEXT) \
 	lib_a-strchr.$(OBJEXT) lib_a-strcmp.$(OBJEXT) \
 	lib_a-strcpy.$(OBJEXT) lib_a-strcspn.$(OBJEXT) \
@@ -128,8 +136,7 @@ am_lib_a_OBJECTS = lib_a-setjmp.$(OBJEXT
 	lib_a-vprintf.$(OBJEXT) lib_a-vscanf.$(OBJEXT) \
 	lib_a-vsiprintf.$(OBJEXT) lib_a-vsiscanf.$(OBJEXT) \
 	lib_a-vsniprintf.$(OBJEXT) lib_a-vsnprintf.$(OBJEXT) \
-	lib_a-vsprintf.$(OBJEXT) lib_a-vsscanf.$(OBJEXT) \
-	lib_a-stack_reg_va.$(OBJEXT)
+	lib_a-vsprintf.$(OBJEXT) lib_a-vsscanf.$(OBJEXT)
 lib_a_OBJECTS = $(am_lib_a_OBJECTS)
 DEFAULT_INCLUDES = -I. -I$(srcdir)
 depcomp =
@@ -203,11 +210,6 @@ STRIP = @STRIP@
 USE_LIBTOOL_FALSE = @USE_LIBTOOL_FALSE@
 USE_LIBTOOL_TRUE = @USE_LIBTOOL_TRUE@
 VERSION = @VERSION@
-ac_ct_AR = @ac_ct_AR@
-ac_ct_AS = @ac_ct_AS@
-ac_ct_RANLIB = @ac_ct_RANLIB@
-ac_ct_READELF = @ac_ct_READELF@
-ac_ct_STRIP = @ac_ct_STRIP@
 aext = @aext@
 am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
 am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
@@ -223,18 +225,23 @@ build_cpu = @build_cpu@
 build_os = @build_os@
 build_vendor = @build_vendor@
 datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
 exec_prefix = @exec_prefix@
 host = @host@
 host_alias = @host_alias@
 host_cpu = @host_cpu@
 host_os = @host_os@
 host_vendor = @host_vendor@
+htmldir = @htmldir@
 includedir = @includedir@
 infodir = @infodir@
 install_sh = @install_sh@
 libdir = @libdir@
 libexecdir = @libexecdir@
 libm_machine_dir = @libm_machine_dir@
+localedir = @localedir@
 localstatedir = @localstatedir@
 lpfx = @lpfx@
 machine_dir = @machine_dir@
@@ -243,8 +250,10 @@ mkdir_p = @mkdir_p@
 newlib_basedir = @newlib_basedir@
 oext = @oext@
 oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
+psdir = @psdir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 sys_dir = @sys_dir@
@@ -254,22 +263,31 @@ AUTOMAKE_OPTIONS = cygnus
 INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS)
 noinst_LIBRARIES = lib.a
 AM_CCASFLAGS = $(INCLUDES)
-lib_a_SOURCES = setjmp.S clearerr.c creat.c fclose.c feof.c ferror.c fflush.c \
-	fgetc.c fgetpos.c fgets.c fileno.c fiprintf.S fiscanf.S fopen.c \
-	fprintf.S fputc.c fputs.c fread.c freopen.c fscanf.S fseek.c \
-	fsetpos.c ftell.c fwrite.c getc.c getchar.c gets.c iprintf.S \
-	iscanf.S memcpy.c memmove.c memset.c perror.c printf.S \
-	putc.c putchar.c puts.c remove.c rename.c rewind.c scanf.S \
+lib_a_SOURCES = setjmp.S callocr.c clearerr.c creat.c fclose.c \
+	feof.c ferror.c fflush.c fgetc.c fgetpos.c fgets.c fileno.c \
+	fiprintf.S fiscanf.S fopen.c fprintf.S fputc.c fputs.c fread.c \
+	freer.c freopen.c fscanf.S fseek.c fsetpos.c ftell.c fwrite.c \
+	getc.c getchar.c gets.c iprintf.S iscanf.S malignr.c \
+	mallocr.c memcpy.c memmove.c memset.c perror.c printf.S putc.c \
+	putchar.c puts.c reallocr.c remove.c rename.c rewind.c scanf.S \
 	setbuf.c setvbuf.c siprintf.S siscanf.S sleep.c sniprintf.S \
-	snprintf.S sprintf.S sscanf.S stdio.c strcat.c strchr.c strcmp.c \
-	strcpy.c strcspn.c strlen.c strncat.c strncmp.c strncpy.c strpbrk.c \
-	strrchr.c strspn.c strxfrm.c tmpfile.c tmpnam.c ungetc.c usleep.c \
-	vfiprintf.c vfiscanf.c vfprintf.c vfscanf.c viprintf.c viscanf.c \
-	vprintf.c vscanf.c vsiprintf.c vsiscanf.c vsniprintf.c vsnprintf.c \
-	vsprintf.c vsscanf.c stack_reg_va.S
+	snprintf.S sprintf.S sscanf.S stack_reg_va.S stdio.c strcat.c \
+	strchr.c strcmp.c strcpy.c strcspn.c strlen.c strncat.c strncmp.c \
+	strncpy.c strpbrk.c strrchr.c strspn.c strxfrm.c tmpfile.c \
+	tmpnam.c ungetc.c usleep.c vfiprintf.c vfiscanf.c vfprintf.c \
+	vfscanf.c viprintf.c viscanf.c vprintf.c vscanf.c vsiprintf.c \
+	vsiscanf.c vsniprintf.c vsnprintf.c vsprintf.c vsscanf.c
+
+LIBADD_OBJS = \
+	$(lpfx)calloc.$(oext) \
+	$(lpfx)free.$(oext) \
+	$(lpfx)malign.$(oext) \
+	$(lpfx)malloc.$(oext) \
+	$(lpfx)realloc.$(oext)
 
 lib_a_CCASFLAGS = $(AM_CCASFLAGS)
 lib_a_CFLAGS = $(AM_CFLAGS)
+lib_a_LIBADD = $(LIBADD_OBJS)
 ACLOCAL_AMFLAGS = -I ../../.. -I ../../../.. 
 CONFIG_STATUS_DEPENDENCIES = $(newlib_basedir)/configure.host
 all: all-am
@@ -431,6 +449,12 @@ lib_a-stack_reg_va.obj: stack_reg_va.S
 .c.obj:
 	$(COMPILE) -c `$(CYGPATH_W) '$<'`
 
+lib_a-callocr.o: callocr.c
+	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-callocr.o `test -f 'callocr.c' || echo '$(srcdir)/'`callocr.c
+
+lib_a-callocr.obj: callocr.c
+	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-callocr.obj `if test -f 'callocr.c'; then $(CYGPATH_W) 'callocr.c'; else $(CYGPATH_W) '$(srcdir)/callocr.c'; fi`
+
 lib_a-clearerr.o: clearerr.c
 	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-clearerr.o `test -f 'clearerr.c' || echo '$(srcdir)/'`clearerr.c
 
@@ -515,6 +539,12 @@ lib_a-fread.o: fread.c
 lib_a-fread.obj: fread.c
 	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-fread.obj `if test -f 'fread.c'; then $(CYGPATH_W) 'fread.c'; else $(CYGPATH_W) '$(srcdir)/fread.c'; fi`
 
+lib_a-freer.o: freer.c
+	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-freer.o `test -f 'freer.c' || echo '$(srcdir)/'`freer.c
+
+lib_a-freer.obj: freer.c
+	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-freer.obj `if test -f 'freer.c'; then $(CYGPATH_W) 'freer.c'; else $(CYGPATH_W) '$(srcdir)/freer.c'; fi`
+
 lib_a-freopen.o: freopen.c
 	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-freopen.o `test -f 'freopen.c' || echo '$(srcdir)/'`freopen.c
 
@@ -563,6 +593,18 @@ lib_a-gets.o: gets.c
 lib_a-gets.obj: gets.c
 	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-gets.obj `if test -f 'gets.c'; then $(CYGPATH_W) 'gets.c'; else $(CYGPATH_W) '$(srcdir)/gets.c'; fi`
 
+lib_a-malignr.o: malignr.c
+	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-malignr.o `test -f 'malignr.c' || echo '$(srcdir)/'`malignr.c
+
+lib_a-malignr.obj: malignr.c
+	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-malignr.obj `if test -f 'malignr.c'; then $(CYGPATH_W) 'malignr.c'; else $(CYGPATH_W) '$(srcdir)/malignr.c'; fi`
+
+lib_a-mallocr.o: mallocr.c
+	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-mallocr.o `test -f 'mallocr.c' || echo '$(srcdir)/'`mallocr.c
+
+lib_a-mallocr.obj: mallocr.c
+	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-mallocr.obj `if test -f 'mallocr.c'; then $(CYGPATH_W) 'mallocr.c'; else $(CYGPATH_W) '$(srcdir)/mallocr.c'; fi`
+
 lib_a-memcpy.o: memcpy.c
 	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-memcpy.o `test -f 'memcpy.c' || echo '$(srcdir)/'`memcpy.c
 
@@ -605,6 +647,12 @@ lib_a-puts.o: puts.c
 lib_a-puts.obj: puts.c
 	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-puts.obj `if test -f 'puts.c'; then $(CYGPATH_W) 'puts.c'; else $(CYGPATH_W) '$(srcdir)/puts.c'; fi`
 
+lib_a-reallocr.o: reallocr.c
+	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-reallocr.o `test -f 'reallocr.c' || echo '$(srcdir)/'`reallocr.c
+
+lib_a-reallocr.obj: reallocr.c
+	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-reallocr.obj `if test -f 'reallocr.c'; then $(CYGPATH_W) 'reallocr.c'; else $(CYGPATH_W) '$(srcdir)/reallocr.c'; fi`
+
 lib_a-remove.o: remove.c
 	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-remove.o `test -f 'remove.c' || echo '$(srcdir)/'`remove.c
 
@@ -970,6 +1018,21 @@ uninstall-am:
 	mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
 	uninstall-am uninstall-info-am
 
+
+$(lpfx)calloc.$(oext): malloc.c
+	$(COMPILE) -DDEFINE_CALLOC -c $(srcdir)/malloc.c -o $@
+
+$(lpfx)free.$(oext): malloc.c
+	$(COMPILE) -DDEFINE_FREE -c $(srcdir)/malloc.c -o $@
+
+$(lpfx)malign.$(oext): malloc.c
+	$(COMPILE) -DDEFINE_MEMALIGN -c $(srcdir)/malloc.c -o $@
+
+$(lpfx)malloc.$(oext): malloc.c
+	$(COMPILE) -DDEFINE_MALLOC -c $(srcdir)/malloc.c -o $@
+
+$(lpfx)realloc.$(oext): malloc.c
+	$(COMPILE) -DDEFINE_REALLOC -c $(srcdir)/malloc.c -o $@
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
 .NOEXPORT:
Index: quilt/newlib/libc/machine/spu/Makefile.am
===================================================================
--- quilt.orig/newlib/libc/machine/spu/Makefile.am
+++ quilt/newlib/libc/machine/spu/Makefile.am
@@ -8,23 +8,47 @@ noinst_LIBRARIES = lib.a
 
 AM_CCASFLAGS = $(INCLUDES)
 
-lib_a_SOURCES = setjmp.S clearerr.c creat.c fclose.c feof.c ferror.c fflush.c \
-	fgetc.c fgetpos.c fgets.c fileno.c fiprintf.S fiscanf.S fopen.c \
-	fprintf.S fputc.c fputs.c fread.c freopen.c fscanf.S fseek.c \
-	fsetpos.c ftell.c fwrite.c getc.c getchar.c gets.c iprintf.S \
-	iscanf.S memcpy.c memmove.c memset.c perror.c printf.S \
-	putc.c putchar.c puts.c remove.c rename.c rewind.c scanf.S \
+lib_a_SOURCES = setjmp.S callocr.c clearerr.c creat.c fclose.c \
+	feof.c ferror.c fflush.c fgetc.c fgetpos.c fgets.c fileno.c \
+	fiprintf.S fiscanf.S fopen.c fprintf.S fputc.c fputs.c fread.c \
+	freer.c freopen.c fscanf.S fseek.c fsetpos.c ftell.c fwrite.c \
+	getc.c getchar.c gets.c iprintf.S iscanf.S malignr.c \
+	mallocr.c memcpy.c memmove.c memset.c perror.c printf.S putc.c \
+	putchar.c puts.c reallocr.c remove.c rename.c rewind.c scanf.S \
 	setbuf.c setvbuf.c siprintf.S siscanf.S sleep.c sniprintf.S \
-	snprintf.S sprintf.S sscanf.S stdio.c strcat.c strchr.c strcmp.c \
-	strcpy.c strcspn.c strlen.c strncat.c strncmp.c strncpy.c strpbrk.c \
-	strrchr.c strspn.c strxfrm.c tmpfile.c tmpnam.c ungetc.c usleep.c \
-	vfiprintf.c vfiscanf.c vfprintf.c vfscanf.c viprintf.c viscanf.c \
-	vprintf.c vscanf.c vsiprintf.c vsiscanf.c vsniprintf.c vsnprintf.c \
-	vsprintf.c vsscanf.c stack_reg_va.S
+	snprintf.S sprintf.S sscanf.S stack_reg_va.S stdio.c strcat.c \
+	strchr.c strcmp.c strcpy.c strcspn.c strlen.c strncat.c strncmp.c \
+	strncpy.c strpbrk.c strrchr.c strspn.c strxfrm.c tmpfile.c \
+	tmpnam.c ungetc.c usleep.c vfiprintf.c vfiscanf.c vfprintf.c \
+	vfscanf.c viprintf.c viscanf.c vprintf.c vscanf.c vsiprintf.c \
+	vsiscanf.c vsniprintf.c vsnprintf.c vsprintf.c vsscanf.c
+
+LIBADD_OBJS =  \
+	$(lpfx)calloc.$(oext) \
+	$(lpfx)free.$(oext) \
+	$(lpfx)malign.$(oext) \
+	$(lpfx)malloc.$(oext) \
+	$(lpfx)realloc.$(oext)
 
 lib_a_CCASFLAGS = $(AM_CCASFLAGS)
 lib_a_CFLAGS = $(AM_CFLAGS)
 
+lib_a_LIBADD = $(LIBADD_OBJS)
+
 ACLOCAL_AMFLAGS = -I ../../.. -I ../../../.. 
 CONFIG_STATUS_DEPENDENCIES = $(newlib_basedir)/configure.host
 
+$(lpfx)calloc.$(oext): malloc.c
+	$(COMPILE) -DDEFINE_CALLOC -c $(srcdir)/malloc.c -o $@
+
+$(lpfx)free.$(oext): malloc.c
+	$(COMPILE) -DDEFINE_FREE -c $(srcdir)/malloc.c -o $@
+
+$(lpfx)malign.$(oext): malloc.c
+	$(COMPILE) -DDEFINE_MEMALIGN -c $(srcdir)/malloc.c -o $@
+
+$(lpfx)malloc.$(oext): malloc.c
+	$(COMPILE) -DDEFINE_MALLOC -c $(srcdir)/malloc.c -o $@
+
+$(lpfx)realloc.$(oext): malloc.c
+	$(COMPILE) -DDEFINE_REALLOC -c $(srcdir)/malloc.c -o $@
Index: quilt/newlib/libc/machine/spu/callocr.c
===================================================================
--- /dev/null
+++ quilt/newlib/libc/machine/spu/callocr.c
@@ -0,0 +1,46 @@
+/*
+  (C) Copyright 2001,2006,
+  International Business Machines Corporation,
+  Sony Computer Entertainment, Incorporated,
+  Toshiba Corporation,
+
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+  this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+  notice, this list of conditions and the following disclaimer in the
+  documentation and/or other materials provided with the distribution.
+    * Neither the names of the copyright holders nor the names of their
+  contributors may be used to endorse or promote products derived from this
+  software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+  OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <reent.h>
+#include <malloc.h>
+
+/*
+ * For __SPU__, _calloc_r is defined to calloc, but in case malloc.h is
+ * not included, include a function for it.
+ */
+#undef _calloc_r
+void *
+_calloc_r (struct _reent *reent, size_t nmemb, size_t bytes)
+{
+  return calloc (nmemb, bytes);
+}
Index: quilt/newlib/libc/machine/spu/freer.c
===================================================================
--- /dev/null
+++ quilt/newlib/libc/machine/spu/freer.c
@@ -0,0 +1,46 @@
+/*
+  (C) Copyright 2001,2006,
+  International Business Machines Corporation,
+  Sony Computer Entertainment, Incorporated,
+  Toshiba Corporation,
+
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+  this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+  notice, this list of conditions and the following disclaimer in the
+  documentation and/or other materials provided with the distribution.
+    * Neither the names of the copyright holders nor the names of their
+  contributors may be used to endorse or promote products derived from this
+  software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+  OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <reent.h>
+#include <malloc.h>
+
+/*
+ * For __SPU__, _free_r is defined to free, but in case malloc.h is
+ * not included, include a function for it.
+ */
+#undef _free_r
+void
+_free_r (struct _reent *reent, void *ptr)
+{
+  free (ptr);
+}
Index: quilt/newlib/libc/machine/spu/mallocr.c
===================================================================
--- /dev/null
+++ quilt/newlib/libc/machine/spu/mallocr.c
@@ -0,0 +1,46 @@
+/*
+  (C) Copyright 2001,2006,
+  International Business Machines Corporation,
+  Sony Computer Entertainment, Incorporated,
+  Toshiba Corporation,
+
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+  this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+  notice, this list of conditions and the following disclaimer in the
+  documentation and/or other materials provided with the distribution.
+    * Neither the names of the copyright holders nor the names of their
+  contributors may be used to endorse or promote products derived from this
+  software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+  OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <reent.h>
+#include <malloc.h>
+
+/*
+ * For __SPU__, _malloc_r is defined to malloc, but in case malloc.h is
+ * not included, include a function for it.
+ */
+#undef _malloc_r
+void *
+_malloc_r (struct _reent *reent, size_t bytes)
+{
+  return malloc (bytes);
+}
Index: quilt/newlib/libc/machine/spu/reallocr.c
===================================================================
--- /dev/null
+++ quilt/newlib/libc/machine/spu/reallocr.c
@@ -0,0 +1,46 @@
+/*
+  (C) Copyright 2001,2006,
+  International Business Machines Corporation,
+  Sony Computer Entertainment, Incorporated,
+  Toshiba Corporation,
+
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+  this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+  notice, this list of conditions and the following disclaimer in the
+  documentation and/or other materials provided with the distribution.
+    * Neither the names of the copyright holders nor the names of their
+  contributors may be used to endorse or promote products derived from this
+  software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+  OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <reent.h>
+#include <malloc.h>
+
+/*
+ * For __SPU__, _realloc_r is defined to realloc, but in case malloc.h is
+ * not included, include a function for it.
+ */
+#undef _realloc_r
+void *
+_realloc_r (struct _reent *reent, void *ptr, size_t bytes)
+{
+  return realloc (ptr, bytes);
+}
Index: quilt/newlib/libc/include/malloc.h
===================================================================
--- quilt.orig/newlib/libc/include/malloc.h
+++ quilt/newlib/libc/include/malloc.h
@@ -35,7 +35,7 @@ struct mallinfo {
 /* The routines.  */
 
 extern _PTR malloc _PARAMS ((size_t));
-#ifdef __CYGWIN__
+#if defined(__CYGWIN__) || defined(__SPU__)
 #undef _malloc_r
 #define _malloc_r(r, s) malloc (s)
 #else
@@ -43,7 +43,7 @@ extern _PTR _malloc_r _PARAMS ((struct _
 #endif
 
 extern _VOID free _PARAMS ((_PTR));
-#ifdef __CYGWIN__
+#if defined(__CYGWIN__) || defined(__SPU__)
 #undef _free_r
 #define _free_r(r, p) free (p)
 #else
@@ -51,7 +51,7 @@ extern _VOID _free_r _PARAMS ((struct _r
 #endif
 
 extern _PTR realloc _PARAMS ((_PTR, size_t));
-#ifdef __CYGWIN__
+#if defined(__CYGWIN__) || defined(__SPU__)
 #undef _realloc_r
 #define _realloc_r(r, p, s) realloc (p, s)
 #else
@@ -59,7 +59,7 @@ extern _PTR _realloc_r _PARAMS ((struct 
 #endif
 
 extern _PTR calloc _PARAMS ((size_t, size_t));
-#ifdef __CYGWIN__
+#if defined(__CYGWIN__) || defined(__SPU__)
 #undef _calloc_r
 #define _calloc_r(r, s1, s2) calloc (s1, s2);
 #else
@@ -67,7 +67,7 @@ extern _PTR _calloc_r _PARAMS ((struct _
 #endif
 
 extern _PTR memalign _PARAMS ((size_t, size_t));
-#ifdef __CYGWIN__
+#if defined(__CYGWIN__) || defined(__SPU__)
 #undef _memalign_r
 #define _memalign_r(r, s1, s2) memalign (s1, s2);
 #else
Index: quilt/newlib/configure.host
===================================================================
--- quilt.orig/newlib/configure.host
+++ quilt/newlib/configure.host
@@ -265,7 +265,7 @@ case "${host_cpu}" in
 	stdio_dir=
 	libm_machine_dir=spu
 	machine_dir=spu
-	newlib_cflags="${newlib_cflags} -D_POSIX_MODE -ffunction-sections -fdata-sections "
+	newlib_cflags="${newlib_cflags} -DMALLOC_PROVIDED -D_POSIX_MODE -ffunction-sections -fdata-sections "
 	;;
   *)
 	echo '***' "Newlib does not support CPU ${host_cpu}" 1>&2
Index: quilt/newlib/libc/machine/spu/malignr.c
===================================================================
--- /dev/null
+++ quilt/newlib/libc/machine/spu/malignr.c
@@ -0,0 +1,46 @@
+/*
+  (C) Copyright 2001,2006,
+  International Business Machines Corporation,
+  Sony Computer Entertainment, Incorporated,
+  Toshiba Corporation,
+
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+  this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+  notice, this list of conditions and the following disclaimer in the
+  documentation and/or other materials provided with the distribution.
+    * Neither the names of the copyright holders nor the names of their
+  contributors may be used to endorse or promote products derived from this
+  software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+  OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <reent.h>
+#include <malloc.h>
+
+/*
+ * For __SPU__, _memalign_r is defined to memalign, but in case malloc.h
+ * is not included, include a function for it.
+ */
+#undef _memalign_r
+void *
+_memalign_r (struct _reent *reent, size_t alignment, size_t bytes)
+{
+  return memalign (alignment, bytes);
+}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]