[T106][ZXW-22]7520V3SCV2.01.01.02P42U09_VEC_V0.8_AP_VEC origin source commit
Change-Id: Ic6e05d89ecd62fc34f82b23dcf306c93764aec4b
diff --git a/ap/build/uClibc/libc/stdlib/malloc/Makefile b/ap/build/uClibc/libc/stdlib/malloc/Makefile
new file mode 100644
index 0000000..4a8f4a0
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/malloc/Makefile
@@ -0,0 +1,13 @@
+# Makefile for uClibc
+#
+# Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+#
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+#
+
+top_srcdir=../../../
+top_builddir=../../../
+all: objs
+include $(top_builddir)Rules.mak
+include Makefile.in
+include $(top_srcdir)Makerules
diff --git a/ap/build/uClibc/libc/stdlib/malloc/Makefile.in b/ap/build/uClibc/libc/stdlib/malloc/Makefile.in
new file mode 100644
index 0000000..642570c
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/malloc/Makefile.in
@@ -0,0 +1,39 @@
+# Makefile for uClibc
+#
+# Copyright (C) 2002-2003 NEC Electronics Corporation
+# Copyright (C) 2002-2003 Miles Bader <miles@gnu.org>
+# Copyright (C) 2000-2008 Erik Andersen <andersen@uclibc.org>
+#
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+#
+
+subdirs += libc/stdlib/malloc
+
+CSRC := malloc.c calloc.c free.c realloc.c memalign.c \
+ heap_alloc.c heap_alloc_at.c heap_free.c
+
+# Turn on malloc debugging if requested
+ifeq ($(UCLIBC_MALLOC_DEBUGGING),y)
+CSRC += malloc_debug.c heap_debug.c
+CFLAGS += -DMALLOC_DEBUGGING -DHEAP_DEBUGGING
+ifeq ($(UCLIBC_UCLINUX_BROKEN_MUNMAP),y)
+CFLAGS += -DMALLOC_MMB_DEBUGGING
+endif
+endif
+
+STDLIB_MALLOC_DIR := $(top_srcdir)libc/stdlib/malloc
+STDLIB_MALLOC_OUT := $(top_builddir)libc/stdlib/malloc
+
+STDLIB_MALLOC_SRC := $(patsubst %.c,$(STDLIB_MALLOC_DIR)/%.c,$(CSRC))
+STDLIB_MALLOC_OBJ := $(patsubst %.c,$(STDLIB_MALLOC_OUT)/%.o,$(CSRC))
+
+libc-$(MALLOC) += $(STDLIB_MALLOC_OBJ)
+
+objclean-y += CLEAN_libc/stdlib/malloc
+
+CLEAN_libc/stdlib/malloc:
+ $(do_rm) $(addprefix $(STDLIB_MALLOC_OUT)/*., o os)
+
+malloc.o free.o realloc.o memalign.o: malloc.h
+# Depend on uClinux_config.h to cache changes in __UCLIBC_MALLOC_DEBUGGING__
+$(STDLIB_MALLOC_OBJ): $(STDLIB_MALLOC_DIR)/heap.h $(top_builddir)include/bits/uClibc_config.h
diff --git a/ap/build/uClibc/libc/stdlib/malloc/calloc.c b/ap/build/uClibc/libc/stdlib/malloc/calloc.c
new file mode 100644
index 0000000..7ac94b8
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/malloc/calloc.c
@@ -0,0 +1,42 @@
+/* vi: set sw=4 ts=4: */
+/* calloc for uClibc
+ *
+ * Copyright (C) 2002 by Erik Andersen <andersen@uclibc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program 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 Library General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+
+void * calloc(size_t nmemb, size_t lsize)
+{
+ void *result;
+ size_t size=lsize * nmemb;
+
+ /* guard vs integer overflow, but allow nmemb
+ * to fall through and call malloc(0) */
+ if (nmemb && lsize != (size / nmemb)) {
+ __set_errno(ENOMEM);
+ return NULL;
+ }
+ if ((result=malloc(size)) != NULL) {
+ memset(result, 0, size);
+ }
+ return result;
+}
+
diff --git a/ap/build/uClibc/libc/stdlib/malloc/free.c b/ap/build/uClibc/libc/stdlib/malloc/free.c
new file mode 100644
index 0000000..e7b6a29
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/malloc/free.c
@@ -0,0 +1,272 @@
+/*
+ * libc/stdlib/malloc/free.c -- free function
+ *
+ * Copyright (C) 2002,03 NEC Electronics Corporation
+ * Copyright (C) 2002,03 Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU Lesser
+ * General Public License. See the file COPYING.LIB in the main
+ * directory of this archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+
+#include "malloc.h"
+#include "heap.h"
+
+#ifdef HEAP_USE_LOCKING
+#define free_to_heap(mem, heap, lck) __free_to_heap(mem, heap, lck)
+#else
+#define free_to_heap(mem, heap, lck) __free_to_heap(mem, heap)
+#endif
+
+static void
+__free_to_heap (void *mem, struct heap_free_area **heap
+#ifdef HEAP_USE_LOCKING
+ , malloc_mutex_t *heap_lock
+#endif
+ )
+{
+ size_t size;
+ struct heap_free_area *fa;
+
+ /* Check for special cases. */
+ if (unlikely (! mem))
+ return;
+
+ /* Normal free. */
+
+ MALLOC_DEBUG (1, "free: 0x%lx (base = 0x%lx, total_size = %d)",
+ (long)mem, (long)MALLOC_BASE (mem), MALLOC_SIZE (mem));
+
+ size = MALLOC_SIZE (mem);
+ mem = MALLOC_BASE (mem);
+
+ __heap_lock (heap_lock);
+
+ /* Put MEM back in the heap, and get the free-area it was placed in. */
+ fa = __heap_free (heap, mem, size);
+
+ /* See if the free-area FA has grown big enough that it should be
+ unmapped. */
+ if (HEAP_FREE_AREA_SIZE (fa) < MALLOC_UNMAP_THRESHOLD)
+ /* Nope, nothing left to do, just release the lock. */
+ __heap_unlock (heap_lock);
+ else
+ /* Yup, try to unmap FA. */
+ {
+ unsigned long start = (unsigned long)HEAP_FREE_AREA_START (fa);
+ unsigned long end = (unsigned long)HEAP_FREE_AREA_END (fa);
+#ifndef MALLOC_USE_SBRK
+# ifdef __UCLIBC_UCLINUX_BROKEN_MUNMAP__
+ struct malloc_mmb *mmb, *prev_mmb;
+ unsigned long mmb_start, mmb_end;
+# else /* !__UCLIBC_UCLINUX_BROKEN_MUNMAP__ */
+ unsigned long unmap_start, unmap_end;
+# endif /* __UCLIBC_UCLINUX_BROKEN_MUNMAP__ */
+#endif /* !MALLOC_USE_SBRK */
+
+#ifdef MALLOC_USE_SBRK
+ /* Get the sbrk lock so that the two possible calls to sbrk below
+ are guaranteed to be contiguous. */
+ __malloc_lock_sbrk ();
+ /* When using sbrk, we only shrink the heap from the end. It would
+ be possible to allow _both_ -- shrinking via sbrk when possible,
+ and otherwise shrinking via munmap, but this results in holes in
+ memory that prevent the brk from every growing back down; since
+ we only ever grow the heap via sbrk, this tends to produce a
+ continuously growing brk (though the actual memory is unmapped),
+ which could eventually run out of address space. Note that
+ `sbrk(0)' shouldn't normally do a system call, so this test is
+ reasonably cheap. */
+ if ((void *)end != sbrk (0))
+ {
+ MALLOC_DEBUG (-1, "not unmapping: 0x%lx - 0x%lx (%ld bytes)",
+ start, end, end - start);
+ __malloc_unlock_sbrk ();
+ __heap_unlock (heap_lock);
+ return;
+ }
+#endif
+
+ MALLOC_DEBUG (0, "unmapping: 0x%lx - 0x%lx (%ld bytes)",
+ start, end, end - start);
+
+ /* Remove FA from the heap. */
+ __heap_delete (heap, fa);
+
+ if (__heap_is_empty (heap))
+ /* We want to avoid the heap from losing all memory, so reserve
+ a bit. This test is only a heuristic -- the existance of
+ another free area, even if it's smaller than
+ MALLOC_MIN_SIZE, will cause us not to reserve anything. */
+ {
+ /* Put the reserved memory back in the heap; we assume that
+ MALLOC_UNMAP_THRESHOLD is greater than MALLOC_MIN_SIZE, so
+ we use the latter unconditionally here. */
+ __heap_free (heap, (void *)start, MALLOC_MIN_SIZE);
+ start += MALLOC_MIN_SIZE;
+ }
+
+#ifdef MALLOC_USE_SBRK
+
+ /* Release the heap lock; we're still holding the sbrk lock. */
+ __heap_unlock (heap_lock);
+ /* Lower the brk. */
+ sbrk (start - end);
+ /* Release the sbrk lock too; now we hold no locks. */
+ __malloc_unlock_sbrk ();
+
+#else /* !MALLOC_USE_SBRK */
+
+# ifdef __UCLIBC_UCLINUX_BROKEN_MUNMAP__
+ /* Using the uClinux broken munmap, we have to only munmap blocks
+ exactly as we got them from mmap, so scan through our list of
+ mmapped blocks, and return them in order. */
+
+ MALLOC_MMB_DEBUG (1, "walking mmb list for region 0x%x[%d]...",
+ start, end - start);
+
+ prev_mmb = 0;
+ mmb = __malloc_mmapped_blocks;
+ while (mmb
+ && ((mmb_end = (mmb_start = (unsigned long)mmb->mem) + mmb->size)
+ <= end))
+ {
+ MALLOC_MMB_DEBUG (1, "considering mmb at 0x%x: 0x%x[%d]",
+ (unsigned)mmb, mmb_start, mmb_end - mmb_start);
+
+ if (mmb_start >= start
+ /* If the space between START and MMB_START is non-zero, but
+ too small to return to the heap, we can't unmap MMB. */
+ && (start == mmb_start
+ || mmb_start - start > HEAP_MIN_FREE_AREA_SIZE))
+ {
+ struct malloc_mmb *next_mmb = mmb->next;
+
+ if (mmb_end != end && mmb_end + HEAP_MIN_FREE_AREA_SIZE > end)
+ /* There's too little space left at the end to deallocate
+ this block, so give up. */
+ break;
+
+ MALLOC_MMB_DEBUG (1, "unmapping mmb at 0x%x: 0x%x[%d]",
+ (unsigned)mmb, mmb_start, mmb_end - mmb_start);
+
+ if (mmb_start != start)
+ /* We're going to unmap a part of the heap that begins after
+ start, so put the intervening region back into the heap. */
+ {
+ MALLOC_MMB_DEBUG (0, "putting intervening region back into heap: 0x%x[%d]",
+ start, mmb_start - start);
+ __heap_free (heap, (void *)start, mmb_start - start);
+ }
+
+ MALLOC_MMB_DEBUG_INDENT (-1);
+
+ /* Unlink MMB from the list. */
+ if (prev_mmb)
+ prev_mmb->next = next_mmb;
+ else
+ __malloc_mmapped_blocks = next_mmb;
+
+ /* Start searching again from the end of this block. */
+ start = mmb_end;
+
+ /* Release the descriptor block we used. */
+ free_to_heap (mmb, &__malloc_mmb_heap, &__malloc_mmb_heap_lock);
+
+ /* We have to unlock the heap before we recurse to free the mmb
+ descriptor, because we might be unmapping from the mmb
+ heap. */
+ __heap_unlock (heap_lock);
+
+ /* Do the actual munmap. */
+ munmap ((void *)mmb_start, mmb_end - mmb_start);
+
+ __heap_lock (heap_lock);
+
+# ifdef __UCLIBC_HAS_THREADS__
+ /* In a multi-threaded program, it's possible that PREV_MMB has
+ been invalidated by another thread when we released the
+ heap lock to do the munmap system call, so just start over
+ from the beginning of the list. It sucks, but oh well;
+ it's probably not worth the bother to do better. */
+ prev_mmb = 0;
+ mmb = __malloc_mmapped_blocks;
+# else
+ mmb = next_mmb;
+# endif
+ }
+ else
+ {
+ prev_mmb = mmb;
+ mmb = mmb->next;
+ }
+
+ MALLOC_MMB_DEBUG_INDENT (-1);
+ }
+
+ if (start != end)
+ /* Hmm, well there's something we couldn't unmap, so put it back
+ into the heap. */
+ {
+ MALLOC_MMB_DEBUG (0, "putting tail region back into heap: 0x%x[%d]",
+ start, end - start);
+ __heap_free (heap, (void *)start, end - start);
+ }
+
+ /* Finally release the lock for good. */
+ __heap_unlock (heap_lock);
+
+ MALLOC_MMB_DEBUG_INDENT (-1);
+
+# else /* !__UCLIBC_UCLINUX_BROKEN_MUNMAP__ */
+
+ /* MEM/LEN may not be page-aligned, so we have to page-align them,
+ and return any left-over bits on the end to the heap. */
+ unmap_start = MALLOC_ROUND_UP_TO_PAGE_SIZE (start);
+ unmap_end = MALLOC_ROUND_DOWN_TO_PAGE_SIZE (end);
+
+ /* We have to be careful that any left-over bits are large enough to
+ return. Note that we _don't check_ to make sure there's room to
+ grow/shrink the start/end by another page, we just assume that
+ the unmap threshold is high enough so that this is always safe
+ (i.e., it should probably be at least 3 pages). */
+ if (unmap_start > start)
+ {
+ if (unmap_start - start < HEAP_MIN_FREE_AREA_SIZE)
+ unmap_start += MALLOC_PAGE_SIZE;
+ __heap_free (heap, (void *)start, unmap_start - start);
+ }
+ if (end > unmap_end)
+ {
+ if (end - unmap_end < HEAP_MIN_FREE_AREA_SIZE)
+ unmap_end -= MALLOC_PAGE_SIZE;
+ __heap_free (heap, (void *)unmap_end, end - unmap_end);
+ }
+
+ /* Release the heap lock before we do the system call. */
+ __heap_unlock (heap_lock);
+
+ if (unmap_end > unmap_start)
+ /* Finally, actually unmap the memory. */
+ munmap ((void *)unmap_start, unmap_end - unmap_start);
+
+# endif /* __UCLIBC_UCLINUX_BROKEN_MUNMAP__ */
+
+#endif /* MALLOC_USE_SBRK */
+ }
+
+ MALLOC_DEBUG_INDENT (-1);
+}
+
+void
+free (void *mem)
+{
+ free_to_heap (mem, &__malloc_heap, &__malloc_heap_lock);
+}
diff --git a/ap/build/uClibc/libc/stdlib/malloc/heap.h b/ap/build/uClibc/libc/stdlib/malloc/heap.h
new file mode 100644
index 0000000..2f06ab1
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/malloc/heap.h
@@ -0,0 +1,231 @@
+/*
+ * libc/stdlib/malloc/heap.h -- heap allocator used for malloc
+ *
+ * Copyright (C) 2002,03 NEC Electronics Corporation
+ * Copyright (C) 2002,03 Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU Lesser
+ * General Public License. See the file COPYING.LIB in the main
+ * directory of this archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <features.h>
+
+
+/* On multi-threaded systems, the heap includes a lock. */
+#ifdef __UCLIBC_HAS_THREADS__
+# include <bits/uClibc_mutex.h>
+# define HEAP_USE_LOCKING
+# define __heap_lock(heap_lock) __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE(*(heap_lock))
+# define __heap_unlock(heap_lock) __UCLIBC_MUTEX_UNLOCK_CANCEL_UNSAFE(*(heap_lock))
+#else
+# define __heap_lock(heap_lock)
+# define __heap_unlock(heap_lock)
+#endif
+
+
+/* The heap allocates in multiples of, and aligned to, HEAP_GRANULARITY.
+ HEAP_GRANULARITY must be a power of 2. Malloc depends on this being the
+ same as MALLOC_ALIGNMENT. */
+#define HEAP_GRANULARITY_TYPE double __attribute_aligned__ (HEAP_GRANULARITY)
+#define HEAP_GRANULARITY \
+ (__alignof__ (double) > sizeof (size_t) ? __alignof__ (double) : sizeof (size_t))
+
+
+
+/* The HEAP_INIT macro can be used as a static initializer for a heap
+ variable. The HEAP_INIT_WITH_FA variant is used to initialize a heap
+ with an initial static free-area; its argument FA should be declared
+ using HEAP_DECLARE_STATIC_FREE_AREA. */
+# define HEAP_INIT 0
+# define HEAP_INIT_WITH_FA(fa) &fa._fa
+
+/* A free-list area `header'. These are actually stored at the _ends_ of
+ free areas (to make allocating from the beginning of the area simpler),
+ so one might call it a `footer'. */
+struct heap_free_area
+{
+ size_t size;
+ struct heap_free_area *next, *prev;
+};
+
+/* Return the address of the end of the frea area FA. */
+#define HEAP_FREE_AREA_END(fa) ((void *)(fa + 1))
+/* Return the address of the beginning of the frea area FA. FA is
+ evaulated multiple times. */
+#define HEAP_FREE_AREA_START(fa) ((void *)((char *)(fa + 1) - (fa)->size))
+/* Return the size of the frea area FA. */
+#define HEAP_FREE_AREA_SIZE(fa) ((fa)->size)
+
+/* This rather clumsy macro allows one to declare a static free-area for
+ passing to HEAP_INIT_WITH_FA initializer macro. This is only use for
+ which NAME is allowed. */
+#define HEAP_DECLARE_STATIC_FREE_AREA(name, size) \
+ static struct \
+ { \
+ HEAP_GRANULARITY_TYPE aligned_space; \
+ char space[HEAP_ADJUST_SIZE(size) \
+ - sizeof (struct heap_free_area) \
+ - HEAP_GRANULARITY]; \
+ struct heap_free_area _fa; \
+ } name = { (HEAP_GRANULARITY_TYPE)0, "", { HEAP_ADJUST_SIZE(size), 0, 0 } }
+
+
+/* Rounds SZ up to be a multiple of HEAP_GRANULARITY. */
+#define HEAP_ADJUST_SIZE(sz) \
+ (((sz) + HEAP_GRANULARITY - 1) & ~(HEAP_GRANULARITY - 1))
+
+
+/* The minimum allocatable size. */
+#define HEAP_MIN_SIZE HEAP_ADJUST_SIZE (sizeof (struct heap_free_area))
+
+/* The minimum size of a free area; if allocating memory from a free-area
+ would make the free-area smaller than this, the allocation is simply
+ given the whole free-area instead. It must include at least enough room
+ to hold a struct heap_free_area, plus some extra to avoid excessive heap
+ fragmentation (thus increasing speed). This is only a heuristic -- it's
+ possible for smaller free-areas than this to exist (say, by realloc
+ returning the tail-end of a previous allocation), but __heap_alloc will
+ try to get rid of them when possible. */
+#define HEAP_MIN_FREE_AREA_SIZE \
+ HEAP_ADJUST_SIZE (sizeof (struct heap_free_area) + 32)
+
+
+/* branch-prediction macros; they may already be defined by libc. */
+#ifndef likely
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96)
+#define likely(cond) __builtin_expect(!!(int)(cond), 1)
+#define unlikely(cond) __builtin_expect((int)(cond), 0)
+#else
+#define likely(cond) (cond)
+#define unlikely(cond) (cond)
+#endif
+#endif /* !likely */
+
+
+/* Define HEAP_DEBUGGING to cause the heap routines to emit debugging info
+ to stderr when the variable __heap_debug is set to true. */
+#ifdef HEAP_DEBUGGING
+extern int __heap_debug;
+#define HEAP_DEBUG(heap, str) (__heap_debug ? __heap_dump (heap, str) : 0)
+#else
+#define HEAP_DEBUG(heap, str) (void)0
+#endif
+
+/* Output a text representation of HEAP to stderr, labelling it with STR. */
+extern void __heap_dump (struct heap_free_area *heap, const char *str);
+
+/* Do some consistency checks on HEAP. If they fail, output an error
+ message to stderr, and exit. STR is printed with the failure message. */
+extern void __heap_check (struct heap_free_area *heap, const char *str);
+
+
+/* Delete the free-area FA from HEAP. */
+static __inline__ void
+__heap_delete (struct heap_free_area **heap, struct heap_free_area *fa)
+{
+ if (fa->next)
+ fa->next->prev = fa->prev;
+ if (fa->prev)
+ fa->prev->next = fa->next;
+ else
+ *heap = fa->next;
+}
+
+
+/* Link the free-area FA between the existing free-area's PREV and NEXT in
+ HEAP. PREV and NEXT may be 0; if PREV is 0, FA is installed as the
+ first free-area. */
+static __inline__ void
+__heap_link_free_area (struct heap_free_area **heap, struct heap_free_area *fa,
+ struct heap_free_area *prev,
+ struct heap_free_area *next)
+{
+ fa->next = next;
+ fa->prev = prev;
+
+ if (prev)
+ prev->next = fa;
+ else
+ *heap = fa;
+ if (next)
+ next->prev = fa;
+}
+
+/* Update the mutual links between the free-areas PREV and FA in HEAP.
+ PREV may be 0, in which case FA is installed as the first free-area (but
+ FA may not be 0). */
+static __inline__ void
+__heap_link_free_area_after (struct heap_free_area **heap,
+ struct heap_free_area *fa,
+ struct heap_free_area *prev)
+{
+ if (prev)
+ prev->next = fa;
+ else
+ *heap = fa;
+ fa->prev = prev;
+}
+
+/* Add a new free-area MEM, of length SIZE, in between the existing
+ free-area's PREV and NEXT in HEAP, and return a pointer to its header.
+ PREV and NEXT may be 0; if PREV is 0, MEM is installed as the first
+ free-area. */
+static __inline__ struct heap_free_area *
+__heap_add_free_area (struct heap_free_area **heap, void *mem, size_t size,
+ struct heap_free_area *prev,
+ struct heap_free_area *next)
+{
+ struct heap_free_area *fa = (struct heap_free_area *)
+ ((char *)mem + size - sizeof (struct heap_free_area));
+
+ fa->size = size;
+
+ __heap_link_free_area (heap, fa, prev, next);
+
+ return fa;
+}
+
+
+/* Allocate SIZE bytes from the front of the free-area FA in HEAP, and
+ return the amount actually allocated (which may be more than SIZE). */
+static __inline__ size_t
+__heap_free_area_alloc (struct heap_free_area **heap,
+ struct heap_free_area *fa, size_t size)
+{
+ size_t fa_size = fa->size;
+
+ if (fa_size < size + HEAP_MIN_FREE_AREA_SIZE)
+ /* There's not enough room left over in FA after allocating the block, so
+ just use the whole thing, removing it from the list of free areas. */
+ {
+ __heap_delete (heap, fa);
+ /* Remember that we've alloced the whole area. */
+ size = fa_size;
+ }
+ else
+ /* Reduce size of FA to account for this allocation. */
+ fa->size = fa_size - size;
+
+ return size;
+}
+
+
+/* Allocate and return a block at least *SIZE bytes long from HEAP.
+ *SIZE is adjusted to reflect the actual amount allocated (which may be
+ greater than requested). */
+extern void *__heap_alloc (struct heap_free_area **heap, size_t *size);
+
+/* Allocate SIZE bytes at address MEM in HEAP. Return the actual size
+ allocated, or 0 if we failed. */
+extern size_t __heap_alloc_at (struct heap_free_area **heap, void *mem, size_t size);
+
+/* Return the memory area MEM of size SIZE to HEAP.
+ Returns the heap free area into which the memory was placed. */
+extern struct heap_free_area *__heap_free (struct heap_free_area **heap,
+ void *mem, size_t size);
+
+/* Return true if HEAP contains absolutely no memory. */
+#define __heap_is_empty(heap) (! (heap))
diff --git a/ap/build/uClibc/libc/stdlib/malloc/heap_alloc.c b/ap/build/uClibc/libc/stdlib/malloc/heap_alloc.c
new file mode 100644
index 0000000..77b7d85
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/malloc/heap_alloc.c
@@ -0,0 +1,51 @@
+/*
+ * libc/stdlib/malloc/heap_alloc.c -- allocate memory from a heap
+ *
+ * Copyright (C) 2002 NEC Corporation
+ * Copyright (C) 2002 Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU Lesser
+ * General Public License. See the file COPYING.LIB in the main
+ * directory of this archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <stdlib.h>
+
+#include "heap.h"
+
+
+/* Allocate and return a block at least *SIZE bytes long from HEAP.
+ *SIZE is adjusted to reflect the actual amount allocated (which may be
+ greater than requested). */
+void *
+__heap_alloc (struct heap_free_area **heap, size_t *size)
+{
+ struct heap_free_area *fa;
+ size_t _size = *size;
+ void *mem = 0;
+
+ _size = HEAP_ADJUST_SIZE (_size);
+
+ if (_size < sizeof (struct heap_free_area))
+ /* Because we sometimes must use a freed block to hold a free-area node,
+ we must make sure that every allocated block can hold one. */
+ _size = HEAP_ADJUST_SIZE (sizeof (struct heap_free_area));
+
+ HEAP_DEBUG (*heap, "before __heap_alloc");
+
+ /* Look for a free area that can contain _SIZE bytes. */
+ for (fa = *heap; fa; fa = fa->next)
+ if (fa->size >= _size)
+ {
+ /* Found one! */
+ mem = HEAP_FREE_AREA_START (fa);
+ *size = __heap_free_area_alloc (heap, fa, _size);
+ break;
+ }
+
+ HEAP_DEBUG (*heap, "after __heap_alloc");
+
+ return mem;
+}
diff --git a/ap/build/uClibc/libc/stdlib/malloc/heap_alloc_at.c b/ap/build/uClibc/libc/stdlib/malloc/heap_alloc_at.c
new file mode 100644
index 0000000..45d6859
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/malloc/heap_alloc_at.c
@@ -0,0 +1,47 @@
+/*
+ * libc/stdlib/malloc/heap_alloc_at.c -- allocate at a specific address
+ *
+ * Copyright (C) 2002 NEC Corporation
+ * Copyright (C) 2002 Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU Lesser
+ * General Public License. See the file COPYING.LIB in the main
+ * directory of this archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <stdlib.h>
+
+#include "heap.h"
+
+
+/* Allocate SIZE bytes at address MEM in HEAP. Return the actual size
+ allocated, or 0 if we failed. */
+size_t
+__heap_alloc_at (struct heap_free_area **heap, void *mem, size_t size)
+{
+ struct heap_free_area *fa;
+ size_t alloced = 0;
+
+ size = HEAP_ADJUST_SIZE (size);
+
+ HEAP_DEBUG (*heap, "before __heap_alloc_at");
+
+ /* Look for a free area that can contain SIZE bytes. */
+ for (fa = *heap; fa; fa = fa->next)
+ {
+ void *fa_mem = HEAP_FREE_AREA_START (fa);
+ if (fa_mem <= mem)
+ {
+ if (fa_mem == mem && fa->size >= size)
+ /* FA has the right addr, and is big enough! */
+ alloced = __heap_free_area_alloc (heap, fa, size);
+ break;
+ }
+ }
+
+ HEAP_DEBUG (*heap, "after __heap_alloc_at");
+
+ return alloced;
+}
diff --git a/ap/build/uClibc/libc/stdlib/malloc/heap_debug.c b/ap/build/uClibc/libc/stdlib/malloc/heap_debug.c
new file mode 100644
index 0000000..5f17aae
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/malloc/heap_debug.c
@@ -0,0 +1,144 @@
+/*
+ * libc/stdlib/malloc/heap_debug.c -- optional heap debugging routines
+ *
+ * Copyright (C) 2002 NEC Corporation
+ * Copyright (C) 2002 Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU Lesser
+ * General Public License. See the file COPYING.LIB in the main
+ * directory of this archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+
+
+#include "malloc.h"
+#include "heap.h"
+
+
+#ifdef HEAP_DEBUGGING
+int __heap_debug = 0;
+#endif
+
+
+static void
+__heap_dump_freelist (struct heap_free_area *heap)
+{
+ struct heap_free_area *fa;
+ for (fa = heap; fa; fa = fa->next)
+ __malloc_debug_printf (0,
+ "0x%lx: 0x%lx - 0x%lx (%d)\tP=0x%lx, N=0x%lx",
+ (long)fa,
+ (long)HEAP_FREE_AREA_START (fa),
+ (long)HEAP_FREE_AREA_END (fa),
+ fa->size,
+ (long)fa->prev,
+ (long)fa->next);
+}
+
+/* Output a text representation of HEAP to stderr, labelling it with STR. */
+void
+__heap_dump (struct heap_free_area *heap, const char *str)
+{
+ static smallint recursed;
+
+ if (! recursed)
+ {
+ __heap_check (heap, str);
+
+ recursed = 1;
+
+ __malloc_debug_printf (1, "%s: heap @0x%lx:", str, (long)heap);
+ __heap_dump_freelist (heap);
+ __malloc_debug_indent (-1);
+
+ recursed = 0;
+ }
+}
+
+
+/* Output an error message to stderr, and exit. STR is printed with the
+ failure message. */
+static void attribute_noreturn
+__heap_check_failure (struct heap_free_area *heap, struct heap_free_area *fa,
+ const char *str, char *fmt, ...)
+{
+ va_list val;
+
+ if (str)
+ fprintf (stderr, "\nHEAP CHECK FAILURE %s: ", str);
+ else
+ fprintf (stderr, "\nHEAP CHECK FAILURE: ");
+
+ va_start (val, fmt);
+ vfprintf (stderr, fmt, val);
+ va_end (val);
+
+ fprintf (stderr, "\n");
+
+ __malloc_debug_set_indent (0);
+ __malloc_debug_printf (1, "heap dump:");
+ __heap_dump_freelist (heap);
+
+ _exit (22);
+}
+
+/* Do some consistency checks on HEAP. If they fail, output an error
+ message to stderr, and exit. STR is printed with the failure message. */
+void
+__heap_check (struct heap_free_area *heap, const char *str)
+{
+ typedef unsigned long ul_t;
+ struct heap_free_area *fa, *prev;
+ struct heap_free_area *first_fa = heap;
+
+ if (first_fa && first_fa->prev)
+ __heap_check_failure (heap, first_fa, str,
+"first free-area has non-zero prev pointer:\n\
+ first free-area = 0x%lx\n\
+ (0x%lx)->prev = 0x%lx\n",
+ (ul_t)first_fa,
+ (ul_t)first_fa, (ul_t)first_fa->prev);
+
+ for (prev = 0, fa = first_fa; fa; prev = fa, fa = fa->next)
+ {
+ if (((ul_t)HEAP_FREE_AREA_END (fa) & (HEAP_GRANULARITY - 1))
+ || (fa->size & (HEAP_GRANULARITY - 1)))
+ __heap_check_failure (heap, fa, str, "alignment error:\n\
+ (0x%lx)->start = 0x%lx\n\
+ (0x%lx)->size = 0x%lx\n",
+ (ul_t)fa,
+ (ul_t)HEAP_FREE_AREA_START (fa),
+ (ul_t)fa, fa->size);
+
+ if (fa->prev != prev)
+ __heap_check_failure (heap, fa, str, "prev pointer corrupted:\n\
+ (0x%lx)->next = 0x%lx\n\
+ (0x%lx)->prev = 0x%lx\n",
+ (ul_t)prev, (ul_t)prev->next,
+ (ul_t)fa, (ul_t)fa->prev);
+
+ if (prev)
+ {
+ ul_t start = (ul_t)HEAP_FREE_AREA_START (fa);
+ ul_t prev_end = (ul_t)HEAP_FREE_AREA_END (prev);
+
+ if (prev_end >= start)
+ __heap_check_failure (heap, fa, str,
+ "start %s with prev free-area end:\n\
+ (0x%lx)->prev = 0x%lx\n\
+ (0x%lx)->start = 0x%lx\n\
+ (0x%lx)->end = 0x%lx\n",
+ (prev_end == start ? "unmerged" : "overlaps"),
+ (ul_t)fa, (ul_t)prev,
+ (ul_t)fa, start,
+ (ul_t)prev, prev_end);
+ }
+ }
+}
diff --git a/ap/build/uClibc/libc/stdlib/malloc/heap_free.c b/ap/build/uClibc/libc/stdlib/malloc/heap_free.c
new file mode 100644
index 0000000..15343c0
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/malloc/heap_free.c
@@ -0,0 +1,89 @@
+/*
+ * libc/stdlib/malloc/heap_free.c -- return memory to a heap
+ *
+ * Copyright (C) 2002 NEC Corporation
+ * Copyright (C) 2002 Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU Lesser
+ * General Public License. See the file COPYING.LIB in the main
+ * directory of this archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <stdlib.h>
+
+#include "heap.h"
+
+
+/* Return the block of memory at MEM, of size SIZE, to HEAP. */
+struct heap_free_area *
+__heap_free (struct heap_free_area **heap, void *mem, size_t size)
+{
+ struct heap_free_area *fa, *prev_fa;
+ void *end = (char *)mem + size;
+
+ HEAP_DEBUG (*heap, "before __heap_free");
+
+ /* Find the right position in the free-list entry to place the new block.
+ This is the most speed critical loop in this malloc implementation:
+ since we use a simple linked-list for the free-list, and we keep it in
+ address-sorted order, it can become very expensive to insert something
+ in the free-list when it becomes fragmented and long. [A better
+ implemention would use a balanced tree or something for the free-list,
+ though that bloats the code-size and complexity quite a bit.] */
+ for (prev_fa = 0, fa = *heap; fa; prev_fa = fa, fa = fa->next)
+ if (unlikely (HEAP_FREE_AREA_END (fa) >= mem))
+ break;
+
+ if (fa && HEAP_FREE_AREA_START (fa) <= end)
+ /* The free-area FA is adjacent to the new block, merge them. */
+ {
+ size_t fa_size = fa->size + size;
+
+ if (HEAP_FREE_AREA_START (fa) == end)
+ /* FA is just after the new block, grow down to encompass it. */
+ {
+ /* See if FA can now be merged with its predecessor. */
+ if (prev_fa && mem == HEAP_FREE_AREA_END (prev_fa))
+ /* Yup; merge PREV_FA's info into FA. */
+ {
+ fa_size += prev_fa->size;
+ __heap_link_free_area_after (heap, fa, prev_fa->prev);
+ }
+ }
+ else
+ /* FA is just before the new block, expand to encompass it. */
+ {
+ struct heap_free_area *next_fa = fa->next;
+
+ /* See if FA can now be merged with its successor. */
+ if (next_fa && end == HEAP_FREE_AREA_START (next_fa))
+ /* Yup; merge FA's info into NEXT_FA. */
+ {
+ fa_size += next_fa->size;
+ __heap_link_free_area_after (heap, next_fa, prev_fa);
+ fa = next_fa;
+ }
+ else
+ /* FA can't be merged; move the descriptor for it to the tail-end
+ of the memory block. */
+ {
+ /* The new descriptor is at the end of the extended block,
+ SIZE bytes later than the old descriptor. */
+ fa = (struct heap_free_area *)((char *)fa + size);
+ /* Update links with the neighbors in the list. */
+ __heap_link_free_area (heap, fa, prev_fa, next_fa);
+ }
+ }
+
+ fa->size = fa_size;
+ }
+ else
+ /* Make the new block into a separate free-list entry. */
+ fa = __heap_add_free_area (heap, mem, size, prev_fa, fa);
+
+ HEAP_DEBUG (*heap, "after __heap_free");
+
+ return fa;
+}
diff --git a/ap/build/uClibc/libc/stdlib/malloc/malloc.c b/ap/build/uClibc/libc/stdlib/malloc/malloc.c
new file mode 100644
index 0000000..d58a7d0
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/malloc/malloc.c
@@ -0,0 +1,233 @@
+/*
+ * libc/stdlib/malloc/malloc.c -- malloc function
+ *
+ * Copyright (C) 2002,03 NEC Electronics Corporation
+ * Copyright (C) 2002,03 Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU Lesser
+ * General Public License. See the file COPYING.LIB in the main
+ * directory of this archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/mman.h>
+
+
+#include "malloc.h"
+#include "heap.h"
+
+
+/* The malloc heap. We provide a bit of initial static space so that
+ programs can do a little mallocing without mmaping in more space. */
+HEAP_DECLARE_STATIC_FREE_AREA (initial_fa, 256);
+struct heap_free_area *__malloc_heap = HEAP_INIT_WITH_FA (initial_fa);
+#ifdef HEAP_USE_LOCKING
+malloc_mutex_t __malloc_heap_lock = PTHREAD_MUTEX_INITIALIZER;
+#endif
+
+#if defined(MALLOC_USE_LOCKING) && defined(MALLOC_USE_SBRK)
+/* A lock protecting our use of sbrk. */
+malloc_mutex_t __malloc_sbrk_lock;
+#endif /* MALLOC_USE_LOCKING && MALLOC_USE_SBRK */
+
+
+#ifdef __UCLIBC_UCLINUX_BROKEN_MUNMAP__
+/* A list of all malloc_mmb structures describing blocks that
+ malloc has mmapped, ordered by the block address. */
+struct malloc_mmb *__malloc_mmapped_blocks = 0;
+
+/* A heap used for allocating malloc_mmb structures. We could allocate
+ them from the main heap, but that tends to cause heap fragmentation in
+ annoying ways. */
+HEAP_DECLARE_STATIC_FREE_AREA (initial_mmb_fa, 48); /* enough for 3 mmbs */
+struct heap_free_area *__malloc_mmb_heap = HEAP_INIT_WITH_FA (initial_mmb_fa);
+#ifdef HEAP_USE_LOCKING
+malloc_mutex_t __malloc_mmb_heap_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+#endif
+#endif /* __UCLIBC_UCLINUX_BROKEN_MUNMAP__ */
+
+
+#ifdef HEAP_USE_LOCKING
+#define malloc_from_heap(size, heap, lck) __malloc_from_heap(size, heap, lck)
+#else
+#define malloc_from_heap(size, heap, lck) __malloc_from_heap(size, heap)
+#endif
+static void *
+__malloc_from_heap (size_t size, struct heap_free_area **heap
+#ifdef HEAP_USE_LOCKING
+ , malloc_mutex_t *heap_lock
+#endif
+ )
+{
+ void *mem;
+
+ MALLOC_DEBUG (1, "malloc: %d bytes", size);
+
+ /* Include extra space to record the size of the allocated block. */
+ size += MALLOC_HEADER_SIZE;
+
+ __heap_lock (heap_lock);
+
+ /* First try to get memory that's already in our heap. */
+ mem = __heap_alloc (heap, &size);
+
+ __heap_unlock (heap_lock);
+
+ if (unlikely (! mem))
+ /* We couldn't allocate from the heap, so grab some more
+ from the system, add it to the heap, and try again. */
+ {
+ /* If we're trying to allocate a block bigger than the default
+ MALLOC_HEAP_EXTEND_SIZE, make sure we get enough to hold it. */
+ void *block;
+ size_t block_size
+ = (size < MALLOC_HEAP_EXTEND_SIZE
+ ? MALLOC_HEAP_EXTEND_SIZE
+ : MALLOC_ROUND_UP_TO_PAGE_SIZE (size));
+
+ /* Allocate the new heap block. */
+#ifdef MALLOC_USE_SBRK
+
+ __malloc_lock_sbrk ();
+
+ /* Use sbrk we can, as it's faster than mmap, and guarantees
+ contiguous allocation. */
+ block = sbrk (block_size);
+ if (likely (block != (void *)-1))
+ {
+ /* Because sbrk can return results of arbitrary
+ alignment, align the result to a MALLOC_ALIGNMENT boundary. */
+ long aligned_block = MALLOC_ROUND_UP ((long)block, MALLOC_ALIGNMENT);
+ if (block != (void *)aligned_block)
+ /* Have to adjust. We should only have to actually do this
+ the first time (after which we will have aligned the brk
+ correctly). */
+ {
+ /* Move the brk to reflect the alignment; our next allocation
+ should start on exactly the right alignment. */
+ sbrk (aligned_block - (long)block);
+ block = (void *)aligned_block;
+ }
+ }
+
+ __malloc_unlock_sbrk ();
+
+#else /* !MALLOC_USE_SBRK */
+
+ /* Otherwise, use mmap. */
+#ifdef __ARCH_USE_MMU__
+ block = mmap ((void *)0, block_size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
+#else
+ block = mmap ((void *)0, block_size, PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_ANONYMOUS | MAP_UNINITIALIZE, 0, 0);
+#endif
+
+#endif /* MALLOC_USE_SBRK */
+
+ if (likely (block != (void *)-1))
+ {
+#if !defined(MALLOC_USE_SBRK) && defined(__UCLIBC_UCLINUX_BROKEN_MUNMAP__)
+ struct malloc_mmb *mmb, *prev_mmb, *new_mmb;
+#endif
+
+ MALLOC_DEBUG (1, "adding system memory to heap: 0x%lx - 0x%lx (%d bytes)",
+ (long)block, (long)block + block_size, block_size);
+
+ /* Get back the heap lock. */
+ __heap_lock (heap_lock);
+
+ /* Put BLOCK into the heap. */
+ __heap_free (heap, block, block_size);
+
+ MALLOC_DEBUG_INDENT (-1);
+
+ /* Try again to allocate. */
+ mem = __heap_alloc (heap, &size);
+
+
+#if !defined(MALLOC_USE_SBRK) && defined(__UCLIBC_UCLINUX_BROKEN_MUNMAP__)
+ /* Insert a record of BLOCK in sorted order into the
+ __malloc_mmapped_blocks list. */
+
+ new_mmb = malloc_from_heap (sizeof *new_mmb, &__malloc_mmb_heap, &__malloc_mmb_heap_lock);
+
+ for (prev_mmb = 0, mmb = __malloc_mmapped_blocks;
+ mmb;
+ prev_mmb = mmb, mmb = mmb->next)
+ if (block < mmb->mem)
+ break;
+
+ new_mmb->next = mmb;
+ new_mmb->mem = block;
+ new_mmb->size = block_size;
+
+ if (prev_mmb)
+ prev_mmb->next = new_mmb;
+ else
+ __malloc_mmapped_blocks = new_mmb;
+
+ MALLOC_MMB_DEBUG (0, "new mmb at 0x%x: 0x%x[%d]",
+ (unsigned)new_mmb,
+ (unsigned)new_mmb->mem, block_size);
+#endif /* !MALLOC_USE_SBRK && __UCLIBC_UCLINUX_BROKEN_MUNMAP__ */
+ __heap_unlock (heap_lock);
+ }
+ }
+
+ if (likely (mem))
+ /* Record the size of the block and get the user address. */
+ {
+ mem = MALLOC_SETUP (mem, size);
+
+ MALLOC_DEBUG (-1, "malloc: returning 0x%lx (base:0x%lx, total_size:%ld)",
+ (long)mem, (long)MALLOC_BASE(mem), (long)MALLOC_SIZE(mem));
+ }
+ else
+ MALLOC_DEBUG (-1, "malloc: returning 0");
+
+ return mem;
+}
+
+void *
+malloc (size_t size)
+{
+ void *mem;
+#ifdef MALLOC_DEBUGGING
+ static smallint debugging_initialized;
+ if (! debugging_initialized)
+ {
+ debugging_initialized = 1;
+ __malloc_debug_init ();
+ }
+ if (__malloc_check)
+ __heap_check (__malloc_heap, "malloc");
+#endif
+
+#ifdef __MALLOC_GLIBC_COMPAT__
+ if (unlikely (size == 0))
+ size++;
+#else
+ /* Some programs will call malloc (0). Lets be strict and return NULL */
+ if (unlikely (size == 0))
+ goto oom;
+#endif
+
+ /* Check if they are doing something dumb like malloc(-1) */
+ if (unlikely(((unsigned long)size > (unsigned long)(MALLOC_HEADER_SIZE*-2))))
+ goto oom;
+
+ mem = malloc_from_heap (size, &__malloc_heap, &__malloc_heap_lock);
+ if (unlikely (!mem))
+ {
+ oom:
+ __set_errno (ENOMEM);
+ return 0;
+ }
+
+ return mem;
+}
diff --git a/ap/build/uClibc/libc/stdlib/malloc/malloc.h b/ap/build/uClibc/libc/stdlib/malloc/malloc.h
new file mode 100644
index 0000000..25f7409
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/malloc/malloc.h
@@ -0,0 +1,229 @@
+/*
+ * libc/stdlib/malloc/malloc.h -- small malloc implementation
+ *
+ * Copyright (C) 2002 NEC Corporation
+ * Copyright (C) 2002 Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU Lesser
+ * General Public License. See the file COPYING.LIB in the main
+ * directory of this archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+/* The alignment we guarantee for malloc return values. We prefer this
+ to be at least sizeof (size_t) bytes because (a) we have to allocate
+ that many bytes for the header anyway and (b) guaranteeing word
+ alignment can be a significant win on targets like m68k and Coldfire,
+ where __alignof__(double) == 2. */
+#define MALLOC_ALIGNMENT \
+ (__alignof__ (double) > sizeof (size_t) ? __alignof__ (double) : sizeof (size_t))
+
+/* The system pagesize... */
+extern size_t __pagesize;
+#define MALLOC_PAGE_SIZE __pagesize
+
+/* The minimum size of block we request from the the system to extend the
+ heap for small allocations (we may request a bigger block if necessary to
+ satisfy a particularly big request). */
+#define MALLOC_HEAP_EXTEND_SIZE MALLOC_PAGE_SIZE
+
+/* When a heap free-area grows above this size, try to unmap it, releasing
+ the memory back to the system. */
+#define MALLOC_UNMAP_THRESHOLD (8*MALLOC_PAGE_SIZE)
+/* When unmapping a free-area, retain this many bytes if it's the only one,
+ to avoid completely emptying the heap. This is only a heuristic -- the
+ existance of another free area, even if it's smaller than
+ MALLOC_MIN_SIZE, will cause us not to reserve anything. */
+#define MALLOC_MIN_SIZE (2*MALLOC_PAGE_SIZE)
+
+/* When realloc shrinks an allocation, it only does so if more than this
+ many bytes will be freed; it must at at least HEAP_MIN_SIZE. Larger
+ values increase speed (by reducing heap fragmentation) at the expense of
+ space. */
+#define MALLOC_REALLOC_MIN_FREE_SIZE (HEAP_MIN_SIZE + 16)
+
+
+/* For systems with an MMU, use sbrk to map/unmap memory for the malloc
+ heap, instead of mmap/munmap. This is a tradeoff -- sbrk is faster than
+ mmap/munmap, and guarantees contiguous allocation, but is also less
+ flexible, and causes the heap to only be shrinkable from the end. */
+#ifdef __ARCH_USE_MMU__
+# define MALLOC_USE_SBRK
+#endif
+
+
+/* The current implementation of munmap in uClinux doesn't work correctly:
+ it requires that ever call to munmap exactly match a corresponding call
+ to mmap (that is, it doesn't allow you to unmap only part of a
+ previously allocated block, or to unmap two contiguous blocks with a
+ single call to munmap). This behavior is broken, and uClinux should be
+ fixed; however, until it is, we add code to work around the problem in
+ malloc. */
+#ifdef __UCLIBC_UCLINUX_BROKEN_MUNMAP__
+
+/* A structure recording a block of memory mmapped by malloc. */
+struct malloc_mmb
+{
+ void *mem; /* the mmapped block */
+ size_t size; /* its size */
+ struct malloc_mmb *next;
+};
+
+/* A list of all malloc_mmb structures describing blocks that malloc has
+ mmapped, ordered by the block address. */
+extern struct malloc_mmb *__malloc_mmapped_blocks;
+
+/* A heap used for allocating malloc_mmb structures. We could allocate
+ them from the main heap, but that tends to cause heap fragmentation in
+ annoying ways. */
+extern struct heap_free_area *__malloc_mmb_heap;
+
+/* Define MALLOC_MMB_DEBUGGING to cause malloc to emit debugging info about
+ about mmap block allocation/freeing by the `uclinux broken munmap' code
+ to stderr, when the variable __malloc_mmb_debug is set to true. */
+#ifdef MALLOC_MMB_DEBUGGING
+# include <stdio.h>
+
+extern int __malloc_mmb_debug;
+# define MALLOC_MMB_DEBUG(indent, fmt, args...) \
+ (__malloc_mmb_debug ? __malloc_debug_printf (indent, fmt , ##args) : 0)
+# define MALLOC_MMB_DEBUG_INDENT(indent) \
+ (__malloc_mmb_debug ? __malloc_debug_indent (indent) : 0)
+# ifndef MALLOC_DEBUGGING
+# define MALLOC_DEBUGGING
+# endif
+#else /* !MALLOC_MMB_DEBUGGING */
+# define MALLOC_MMB_DEBUG(fmt, args...) (void)0
+# define MALLOC_MMB_DEBUG_INDENT(indent) (void)0
+#endif /* MALLOC_MMB_DEBUGGING */
+
+#endif /* __UCLIBC_UCLINUX_BROKEN_MUNMAP__ */
+
+
+/* The size of a malloc allocation is stored in a size_t word
+ MALLOC_HEADER_SIZE bytes prior to the start address of the allocation:
+
+ +--------+---------+-------------------+
+ | SIZE |(unused) | allocation ... |
+ +--------+---------+-------------------+
+ ^ BASE ^ ADDR
+ ^ ADDR - MALLOC_HEADER_SIZE
+*/
+
+/* The amount of extra space used by the malloc header. */
+#define MALLOC_HEADER_SIZE \
+ (MALLOC_ALIGNMENT < sizeof (size_t) \
+ ? sizeof (size_t) \
+ : MALLOC_ALIGNMENT)
+
+/* Set up the malloc header, and return the user address of a malloc block. */
+#define MALLOC_SETUP(base, size) \
+ (MALLOC_SET_SIZE (base, size), (void *)((char *)base + MALLOC_HEADER_SIZE))
+/* Set the size of a malloc allocation, given the base address. */
+#define MALLOC_SET_SIZE(base, size) (*(size_t *)(base) = (size))
+
+/* Return base-address of a malloc allocation, given the user address. */
+#define MALLOC_BASE(addr) ((void *)((char *)addr - MALLOC_HEADER_SIZE))
+/* Return the size of a malloc allocation, given the user address. */
+#define MALLOC_SIZE(addr) (*(size_t *)MALLOC_BASE(addr))
+
+
+/* Locking for multithreaded apps. */
+#ifdef __UCLIBC_HAS_THREADS__
+
+# include <bits/uClibc_mutex.h>
+
+# define MALLOC_USE_LOCKING
+
+typedef __UCLIBC_MUTEX_TYPE malloc_mutex_t;
+# define MALLOC_MUTEX_INIT __UCLIBC_MUTEX_INITIALIZER
+
+# ifdef MALLOC_USE_SBRK
+/* This lock is used to serialize uses of the `sbrk' function (in both
+ malloc and free, sbrk may be used several times in succession, and
+ things will break if these multiple calls are interleaved with another
+ thread's use of sbrk!). */
+extern malloc_mutex_t __malloc_sbrk_lock;
+# define __malloc_lock_sbrk() __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE (__malloc_sbrk_lock)
+# define __malloc_unlock_sbrk() __UCLIBC_MUTEX_UNLOCK_CANCEL_UNSAFE (__malloc_sbrk_lock)
+# endif /* MALLOC_USE_SBRK */
+
+#else /* !__UCLIBC_HAS_THREADS__ */
+
+/* Without threads, mutex operations are a nop. */
+# define __malloc_lock_sbrk() (void)0
+# define __malloc_unlock_sbrk() (void)0
+
+#endif /* __UCLIBC_HAS_THREADS__ */
+
+
+/* branch-prediction macros; they may already be defined by libc. */
+#ifndef likely
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96)
+#define likely(cond) __builtin_expect(!!(int)(cond), 1)
+#define unlikely(cond) __builtin_expect((int)(cond), 0)
+#else
+#define likely(cond) (cond)
+#define unlikely(cond) (cond)
+#endif
+#endif /* !likely */
+
+
+/* Define MALLOC_DEBUGGING to cause malloc to emit debugging info to stderr
+ when the variable __malloc_debug is set to true. */
+#ifdef MALLOC_DEBUGGING
+
+extern void __malloc_debug_init (void);
+
+/* The number of spaces in a malloc debug indent level. */
+#define MALLOC_DEBUG_INDENT_SIZE 3
+
+extern int __malloc_debug, __malloc_check;
+
+# define MALLOC_DEBUG(indent, fmt, args...) \
+ (__malloc_debug ? __malloc_debug_printf (indent, fmt , ##args) : 0)
+# define MALLOC_DEBUG_INDENT(indent) \
+ (__malloc_debug ? __malloc_debug_indent (indent) : 0)
+
+extern int __malloc_debug_cur_indent;
+
+/* Print FMT and args indented at the current debug print level, followed
+ by a newline, and change the level by INDENT. */
+extern void __malloc_debug_printf (int indent, const char *fmt, ...);
+
+/* Change the current debug print level by INDENT, and return the value. */
+#define __malloc_debug_indent(indent) (__malloc_debug_cur_indent += indent)
+
+/* Set the current debug print level to LEVEL. */
+#define __malloc_debug_set_indent(level) (__malloc_debug_cur_indent = level)
+
+#else /* !MALLOC_DEBUGGING */
+# define MALLOC_DEBUG(fmt, args...) (void)0
+# define MALLOC_DEBUG_INDENT(indent) (void)0
+#endif /* MALLOC_DEBUGGING */
+
+
+/* Return SZ rounded down to POWER_OF_2_SIZE (which must be power of 2). */
+#define MALLOC_ROUND_DOWN(sz, power_of_2_size) \
+ ((sz) & ~(power_of_2_size - 1))
+/* Return SZ rounded to POWER_OF_2_SIZE (which must be power of 2). */
+#define MALLOC_ROUND_UP(sz, power_of_2_size) \
+ MALLOC_ROUND_DOWN ((sz) + (power_of_2_size - 1), (power_of_2_size))
+
+/* Return SZ rounded down to a multiple MALLOC_PAGE_SIZE. */
+#define MALLOC_ROUND_DOWN_TO_PAGE_SIZE(sz) \
+ MALLOC_ROUND_DOWN (sz, MALLOC_PAGE_SIZE)
+/* Return SZ rounded up to a multiple MALLOC_PAGE_SIZE. */
+#define MALLOC_ROUND_UP_TO_PAGE_SIZE(sz) \
+ MALLOC_ROUND_UP (sz, MALLOC_PAGE_SIZE)
+
+
+/* The malloc heap. */
+extern struct heap_free_area *__malloc_heap;
+#ifdef __UCLIBC_HAS_THREADS__
+extern malloc_mutex_t __malloc_heap_lock;
+#ifdef __UCLIBC_UCLINUX_BROKEN_MUNMAP__
+extern malloc_mutex_t __malloc_mmb_heap_lock;
+#endif
+#endif
diff --git a/ap/build/uClibc/libc/stdlib/malloc/malloc_debug.c b/ap/build/uClibc/libc/stdlib/malloc/malloc_debug.c
new file mode 100644
index 0000000..1a5374f
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/malloc/malloc_debug.c
@@ -0,0 +1,87 @@
+/*
+ * libc/stdlib/malloc/malloc_debug.c -- malloc debugging support
+ *
+ * Copyright (C) 2002 NEC Corporation
+ * Copyright (C) 2002 Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU Lesser
+ * General Public License. See the file COPYING.LIB in the main
+ * directory of this archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdarg.h>
+
+
+#include "malloc.h"
+#include "heap.h"
+
+int __malloc_debug = 0, __malloc_check = 0;
+
+#ifdef MALLOC_MMB_DEBUGGING
+int __malloc_mmb_debug = 0;
+#endif
+
+/* Debugging output is indented this may levels. */
+int __malloc_debug_cur_indent = 0;
+
+
+/* Print FMT and args indented at the current debug print level, followed
+ by a newline, and change the level by INDENT. */
+void
+__malloc_debug_printf (int indent, const char *fmt, ...)
+{
+ unsigned spaces = __malloc_debug_cur_indent * MALLOC_DEBUG_INDENT_SIZE;
+ va_list val;
+
+ while (spaces > 0)
+ {
+ putc (' ', stderr);
+ spaces--;
+ }
+
+ va_start (val, fmt);
+ vfprintf (stderr, fmt, val);
+ va_end (val);
+
+ putc ('\n', stderr);
+
+ __malloc_debug_indent (indent);
+}
+
+void
+__malloc_debug_init (void)
+{
+ char *ev = getenv ("MALLOC_DEBUG");
+ if (ev)
+ {
+ int val = atoi (ev);
+
+ if (val & 1)
+ __malloc_check = 1;
+
+ if (val & 2)
+ __malloc_debug = 1;
+
+#ifdef MALLOC_MMB_DEBUGGING
+ if (val & 4)
+ __malloc_mmb_debug = 1;
+#endif
+
+#ifdef HEAP_DEBUGGING
+ if (val & 8)
+ __heap_debug = 1;
+#endif
+
+ if (val)
+ __malloc_debug_printf
+ (0, "malloc_debug: initialized to %d (check = %d, dump = %d, dump_mmb = %d, dump_heap = %d)",
+ val,
+ !!(val & 1), !!(val & 2),
+ !!(val & 4), !!(val & 8));
+ }
+}
diff --git a/ap/build/uClibc/libc/stdlib/malloc/memalign.c b/ap/build/uClibc/libc/stdlib/malloc/memalign.c
new file mode 100644
index 0000000..5edd6e1
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/malloc/memalign.c
@@ -0,0 +1,94 @@
+/*
+ * libc/stdlib/malloc/memalign.c -- memalign (`aligned malloc') function
+ *
+ * Copyright (C) 2002 NEC Corporation
+ * Copyright (C) 2002 Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU Lesser
+ * General Public License. See the file COPYING.LIB in the main
+ * directory of this archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/param.h> /* MAX */
+
+#include "malloc.h"
+#include "heap.h"
+
+
+/*
+ ______________________ TOTAL _________________________
+ / \
+ +---------------+-------------------------+--------------+
+ | | | |
+ +---------------+-------------------------+--------------+
+ \____ INIT ____/ \______ RETURNED _______/ \____ END ___/
+*/
+
+void *memalign (size_t alignment, size_t size);
+void *
+memalign (size_t alignment, size_t size)
+{
+ void *mem, *base;
+ unsigned long tot_addr, tot_end_addr, addr, end_addr;
+ struct heap_free_area **heap = &__malloc_heap;
+
+ /* Make SIZE something we like. */
+ size = HEAP_ADJUST_SIZE (size);
+
+ /* Use malloc to do the initial allocation, since it deals with getting
+ system memory. We over-allocate enough to be sure that we'll get
+ enough memory to hold a properly aligned block of size SIZE,
+ _somewhere_ in the result. */
+ mem = malloc (size + 2 * alignment);
+ if (! mem)
+ /* Allocation failed, we can't do anything. */
+ return 0;
+ if (alignment < MALLOC_ALIGNMENT)
+ return mem;
+
+ /* Remember the base-address, of the allocation, although we normally
+ use the user-address for calculations, since that's where the
+ alignment matters. */
+ base = MALLOC_BASE (mem);
+
+ /* The bounds of the initial allocation. */
+ tot_addr = (unsigned long)mem;
+ tot_end_addr = (unsigned long)base + MALLOC_SIZE (mem);
+
+ /* Find a likely place inside MEM with the right alignment. */
+ addr = MALLOC_ROUND_UP (tot_addr, alignment);
+
+ /* Unless TOT_ADDR was already aligned correctly, we need to return the
+ initial part of MEM to the heap. */
+ if (addr != tot_addr)
+ {
+ size_t init_size = addr - tot_addr;
+
+ /* Ensure that memory returned to the heap is large enough. */
+ if (init_size < HEAP_MIN_SIZE)
+ {
+ addr = MALLOC_ROUND_UP (tot_addr + HEAP_MIN_SIZE, alignment);
+ init_size = addr - tot_addr;
+ }
+
+ __heap_free (heap, base, init_size);
+
+ /* Remember that we've freed the initial part of MEM. */
+ base += init_size;
+ }
+
+ /* Return the end part of MEM to the heap, unless it's too small. */
+ end_addr = addr + size;
+ if (end_addr + MALLOC_REALLOC_MIN_FREE_SIZE < tot_end_addr)
+ __heap_free (heap, (void *)end_addr, tot_end_addr - end_addr);
+ else
+ /* We didn't free the end, so include it in the size. */
+ end_addr = tot_end_addr;
+
+ return MALLOC_SETUP (base, end_addr - (unsigned long)base);
+}
diff --git a/ap/build/uClibc/libc/stdlib/malloc/realloc.c b/ap/build/uClibc/libc/stdlib/malloc/realloc.c
new file mode 100644
index 0000000..8de0066
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/malloc/realloc.c
@@ -0,0 +1,100 @@
+/*
+ * libc/stdlib/malloc/realloc.c -- realloc function
+ *
+ * Copyright (C) 2002 NEC Corporation
+ * Copyright (C) 2002 Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU Lesser
+ * General Public License. See the file COPYING.LIB in the main
+ * directory of this archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+
+#include "malloc.h"
+#include "heap.h"
+
+
+void *
+realloc (void *mem, size_t new_size)
+{
+ size_t size;
+ char *base_mem;
+
+ /* Check for special cases. */
+ if (! new_size)
+ {
+ free (mem);
+ return malloc (new_size);
+ }
+ if (! mem)
+ return malloc (new_size);
+ /* This matches the check in malloc() */
+ if (unlikely(((unsigned long)new_size > (unsigned long)(MALLOC_HEADER_SIZE*-2))))
+ return NULL;
+
+ /* Normal realloc. */
+
+ base_mem = MALLOC_BASE (mem);
+ size = MALLOC_SIZE (mem);
+
+ /* Include extra space to record the size of the allocated block.
+ Also make sure that we're dealing in a multiple of the heap
+ allocation unit (SIZE is already guaranteed to be so).*/
+ new_size = HEAP_ADJUST_SIZE (new_size + MALLOC_HEADER_SIZE);
+
+ if (new_size < sizeof (struct heap_free_area))
+ /* Because we sometimes must use a freed block to hold a free-area node,
+ we must make sure that every allocated block can hold one. */
+ new_size = HEAP_ADJUST_SIZE (sizeof (struct heap_free_area));
+
+ MALLOC_DEBUG (1, "realloc: 0x%lx, %d (base = 0x%lx, total_size = %d)",
+ (long)mem, new_size, (long)base_mem, size);
+
+ if (new_size > size)
+ /* Grow the block. */
+ {
+ size_t extra = new_size - size;
+
+ __heap_lock (&__malloc_heap_lock);
+ extra = __heap_alloc_at (&__malloc_heap, base_mem + size, extra);
+ __heap_unlock (&__malloc_heap_lock);
+
+ if (extra)
+ /* Record the changed size. */
+ MALLOC_SET_SIZE (base_mem, size + extra);
+ else
+ /* Our attempts to extend MEM in place failed, just
+ allocate-and-copy. */
+ {
+ void *new_mem = malloc (new_size - MALLOC_HEADER_SIZE);
+ if (new_mem)
+ {
+ memcpy (new_mem, mem, size - MALLOC_HEADER_SIZE);
+ free (mem);
+ }
+ mem = new_mem;
+ }
+ }
+ else if (new_size + MALLOC_REALLOC_MIN_FREE_SIZE <= size)
+ /* Shrink the block. */
+ {
+ __heap_lock (&__malloc_heap_lock);
+ __heap_free (&__malloc_heap, base_mem + new_size, size - new_size);
+ __heap_unlock (&__malloc_heap_lock);
+ MALLOC_SET_SIZE (base_mem, new_size);
+ }
+
+ if (mem)
+ MALLOC_DEBUG (-1, "realloc: returning 0x%lx (base:0x%lx, total_size:%d)",
+ (long)mem, (long)MALLOC_BASE(mem), (long)MALLOC_SIZE(mem));
+ else
+ MALLOC_DEBUG (-1, "realloc: returning 0");
+
+ return mem;
+}