[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/.indent.pro b/ap/build/uClibc/libc/stdlib/.indent.pro
new file mode 100644
index 0000000..492ecf1
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/.indent.pro
@@ -0,0 +1,33 @@
+--blank-lines-after-declarations
+--blank-lines-after-procedures
+--break-before-boolean-operator
+--no-blank-lines-after-commas
+--braces-on-if-line
+--braces-on-struct-decl-line
+--comment-indentation25
+--declaration-comment-column25
+--no-comment-delimiters-on-blank-lines
+--cuddle-else
+--continuation-indentation4
+--case-indentation0
+--else-endif-column33
+--space-after-cast
+--line-comments-indentation0
+--declaration-indentation1
+--dont-format-first-column-comments
+--dont-format-comments
+--honour-newlines
+--indent-level4
+/* changed from 0 to 4 */
+--parameter-indentation4
+--line-length78 /* changed from 75 */
+--continue-at-parentheses
+--no-space-after-function-call-names
+--dont-break-procedure-type
+--dont-star-comments
+--leave-optional-blank-lines
+--dont-space-special-semicolon
+--tab-size4
+/* additions by Mark */
+--case-brace-indentation0
+--leave-preprocessor-space
diff --git a/ap/build/uClibc/libc/stdlib/Makefile b/ap/build/uClibc/libc/stdlib/Makefile
new file mode 100644
index 0000000..11f362a
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/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/Makefile.in b/ap/build/uClibc/libc/stdlib/Makefile.in
new file mode 100644
index 0000000..d927807
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/Makefile.in
@@ -0,0 +1,84 @@
+# Makefile for uClibc
+#
+# 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
+
+include $(top_srcdir)libc/stdlib/malloc/Makefile.in
+include $(top_srcdir)libc/stdlib/malloc-simple/Makefile.in
+include $(top_srcdir)libc/stdlib/malloc-standard/Makefile.in
+
+CSRC-y := \
+ abort.c getenv.c mkdtemp.c realpath.c canonicalize.c mkstemp.c \
+ rand.c random.c random_r.c setenv.c div.c ldiv.c lldiv.c \
+ getpt.c drand48-iter.c jrand48.c \
+ jrand48_r.c lrand48.c lrand48_r.c mrand48.c mrand48_r.c nrand48.c \
+ nrand48_r.c rand_r.c srand48.c srand48_r.c seed48.c seed48_r.c \
+ valloc.c a64l.c l64a.c __uc_malloc.c
+CSRC-$(UCLIBC_HAS_ADVANCED_REALTIME) += posix_memalign.c
+CSRC-$(UCLIBC_HAS_PTY) += grantpt.c unlockpt.c ptsname.c
+CSRC-$(UCLIBC_HAS_ARC4RANDOM) += arc4random.c
+CSRC-$(UCLIBC_HAS_LFS) += mkstemp64.c
+CSRC-$(UCLIBC_HAS_FLOATS) += drand48.c drand48_r.c erand48.c erand48_r.c
+CSRC-$(if $(findstring yy,$(UCLIBC_HAS_FLOATS)$(UCLIBC_SUSV3_LEGACY)),y) += \
+ gcvt.c
+CSRC-$(UCLIBC_SUSV3_LEGACY) += mktemp.c
+
+ifneq ($(UCLIBC_HAS_BACKTRACE),)
+CFLAGS-abort.c = -fasynchronous-unwind-tables
+endif
+
+# multi source stdlib.c
+CSRC-y += abs.c labs.c atoi.c atol.c strtol.c strtoul.c _stdlib_strto_l.c \
+ qsort.c qsort_r.c bsearch.c \
+ llabs.c atoll.c strtoll.c strtoull.c _stdlib_strto_ll.c
+# (aliases) strtoq.o strtouq.o
+CSRC-$(UCLIBC_HAS_FLOATS) += atof.c
+CSRC-$(UCLIBC_HAS_XLOCALE) += strtol_l.c strtoul_l.c _stdlib_strto_l_l.c \
+ strtoll_l.c strtoull_l.c _stdlib_strto_ll_l.c
+
+CSRC-$(UCLIBC_HAS_WCHAR) += mblen.c mbtowc.c wctomb.c mbstowcs.c wcstombs.c \
+ _stdlib_mb_cur_max.c _stdlib_wcsto_l.c _stdlib_wcsto_ll.c \
+ wcstol.c wcstoul.c wcstoll.c wcstoull.c
+CSRC-$(if $(findstring yy,$(UCLIBC_HAS_WCHAR)$(UCLIBC_HAS_XLOCALE)),y) += \
+ _stdlib_wcsto_l_l.c _stdlib_wcsto_ll_l.c \
+ wcstol_l.c wcstoul_l.c wcstoll_l.c wcstoull_l.c
+
+# multi source _strtod.c
+CSRC-$(UCLIBC_HAS_FLOATS) += strtod.c strtof.c strtold.c __strtofpmax.c __fp_range_check.c
+CSRC-$(if $(findstring yy,$(UCLIBC_HAS_FLOATS)$(UCLIBC_HAS_XLOCALE)),y) += \
+ strtod_l.c strtof_l.c strtold_l.c __strtofpmax_l.c
+CSRC-$(if $(findstring yy,$(UCLIBC_HAS_FLOATS)$(UCLIBC_HAS_WCHAR)),y) += \
+ wcstod.c wcstof.c wcstold.c __wcstofpmax.c
+CSRC-$(if $(findstring yyy,$(UCLIBC_HAS_FLOATS)$(UCLIBC_HAS_WCHAR)$(UCLIBC_HAS_XLOCALE)),y) += \
+ wcstod_l.c wcstof_l.c wcstold_l.c __wcstofpmax_l.c
+# (aliases) wcstoq.o wcstouq.o
+# wcstod wcstof wcstold
+
+# multi source _atexit.c
+CSRC-y += __cxa_atexit.c __cxa_finalize.c __exit_handler.c exit.c on_exit.c
+CSRC-$(COMPAT_ATEXIT) += old_atexit.c
+
+STDLIB_DIR := $(top_srcdir)libc/stdlib
+STDLIB_OUT := $(top_builddir)libc/stdlib
+
+STDLIB_SRC := $(patsubst %.c,$(STDLIB_DIR)/%.c,$(CSRC-y))
+STDLIB_OBJ := $(patsubst %.c,$(STDLIB_OUT)/%.o,$(CSRC-y))
+
+libc-y += $(STDLIB_OBJ)
+libc-static-y += $(STDLIB_OUT)/atexit.o $(STDLIB_OUT)/system.o
+libc-shared-y += $(STDLIB_OUT)/system.oS
+
+# this should always be the PIC version, because it could be used in shared libs
+libc-nonshared-y += $(STDLIB_OUT)/atexit.os
+
+libc-nomulti-y += $(STDLIB_OUT)/labs.o $(STDLIB_OUT)/atol.o $(STDLIB_OUT)/_stdlib_strto_l.o $(STDLIB_OUT)/_stdlib_strto_ll.o
+libc-nomulti-$(UCLIBC_HAS_XLOCALE) += $(STDLIB_OUT)/_stdlib_strto_l_l.o $(STDLIB_OUT)/_stdlib_strto_ll_l.o
+
+objclean-y += CLEAN_libc/stdlib
+
+CLEAN_libc/stdlib:
+ $(do_rm) $(addprefix $(STDLIB_OUT)/*., o os oS)
diff --git a/ap/build/uClibc/libc/stdlib/__cxa_atexit.c b/ap/build/uClibc/libc/stdlib/__cxa_atexit.c
new file mode 100644
index 0000000..fbf06e5
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/__cxa_atexit.c
@@ -0,0 +1,8 @@
+/*
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L___cxa_atexit
+#include "_atexit.c"
diff --git a/ap/build/uClibc/libc/stdlib/__cxa_finalize.c b/ap/build/uClibc/libc/stdlib/__cxa_finalize.c
new file mode 100644
index 0000000..4a91626
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/__cxa_finalize.c
@@ -0,0 +1,8 @@
+/*
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L___cxa_finalize
+#include "_atexit.c"
diff --git a/ap/build/uClibc/libc/stdlib/__exit_handler.c b/ap/build/uClibc/libc/stdlib/__exit_handler.c
new file mode 100644
index 0000000..ae4ff84
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/__exit_handler.c
@@ -0,0 +1,8 @@
+/*
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L___exit_handler
+#include "_atexit.c"
diff --git a/ap/build/uClibc/libc/stdlib/__fp_range_check.c b/ap/build/uClibc/libc/stdlib/__fp_range_check.c
new file mode 100644
index 0000000..9c60972
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/__fp_range_check.c
@@ -0,0 +1,8 @@
+/*
+ * Copyright (C) 2000-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L___fp_range_check
+#include "_strtod.c"
diff --git a/ap/build/uClibc/libc/stdlib/__strtofpmax.c b/ap/build/uClibc/libc/stdlib/__strtofpmax.c
new file mode 100644
index 0000000..6b01aca
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/__strtofpmax.c
@@ -0,0 +1,8 @@
+/*
+ * Copyright (C) 2000-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L___strtofpmax
+#include "_strtod.c"
diff --git a/ap/build/uClibc/libc/stdlib/__strtofpmax_l.c b/ap/build/uClibc/libc/stdlib/__strtofpmax_l.c
new file mode 100644
index 0000000..a614132
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/__strtofpmax_l.c
@@ -0,0 +1,9 @@
+/*
+ * Copyright (C) 2000-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L___strtofpmax_l
+#define __UCLIBC_DO_XLOCALE
+#include "_strtod.c"
diff --git a/ap/build/uClibc/libc/stdlib/__uc_malloc.c b/ap/build/uClibc/libc/stdlib/__uc_malloc.c
new file mode 100644
index 0000000..449f014
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/__uc_malloc.c
@@ -0,0 +1,46 @@
+/* vi: set sw=4 ts=4: */
+/* uClibc internal malloc.
+ Copyright (C) 2007 Denys Vlasenko
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License
+version 2 as published by the Free Software Foundation.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.
+
+*/
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <malloc.h>
+
+
+void (*__uc_malloc_failed)(size_t size) = NULL;
+/* Seemingly superfluous assigment of NULL above prevents gas error
+ * ("__uc_malloc_failed can't be equated to common symbol
+ * __GI___uc_malloc_failed") in libc_hidden_data_def: */
+libc_hidden_data_def(__uc_malloc_failed)
+
+void *__uc_malloc(size_t size)
+{
+ void *p;
+
+ while (1) {
+ p = malloc(size);
+ if (!size || p)
+ return p;
+ if (!__uc_malloc_failed)
+ _exit(1);
+ free(p);
+ __uc_malloc_failed(size);
+ }
+}
+libc_hidden_def(__uc_malloc)
diff --git a/ap/build/uClibc/libc/stdlib/__wcstofpmax.c b/ap/build/uClibc/libc/stdlib/__wcstofpmax.c
new file mode 100644
index 0000000..3c3fdcc
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/__wcstofpmax.c
@@ -0,0 +1,8 @@
+/*
+ * Copyright (C) 2000-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L___wcstofpmax
+#include "_strtod.c"
diff --git a/ap/build/uClibc/libc/stdlib/__wcstofpmax_l.c b/ap/build/uClibc/libc/stdlib/__wcstofpmax_l.c
new file mode 100644
index 0000000..909b720
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/__wcstofpmax_l.c
@@ -0,0 +1,9 @@
+/*
+ * Copyright (C) 2000-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L___wcstofpmax_l
+#define __UCLIBC_DO_XLOCALE
+#include "_strtod.c"
diff --git a/ap/build/uClibc/libc/stdlib/_atexit.c b/ap/build/uClibc/libc/stdlib/_atexit.c
new file mode 100644
index 0000000..48b97ff
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/_atexit.c
@@ -0,0 +1,348 @@
+/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk>
+ * This file is part of the Linux-8086 C library and is distributed
+ * under the GNU Library General Public License.
+ */
+
+/*
+ * Dec 2000 Manuel Novoa III
+ *
+ * Made atexit handling conform to standards... i.e. no args.
+ * Removed on_exit since it did not match gnu libc definition.
+ * Combined atexit and __do_exit into one object file.
+ *
+ * Feb 2001 Manuel Novoa III
+ *
+ * Reworked file after addition of __uClibc_main.
+ * Changed name of __do_exit to atexit_handler.
+ * Changed name of __cleanup to __uClibc_cleanup.
+ * Moved declaration of __uClibc_cleanup to __uClibc_main
+ * where it is initialized with (possibly weak alias)
+ * _stdio_term.
+ *
+ * Jul 2001 Steve Thayer
+ *
+ * Added an on_exit implementation (that now matches gnu libc definition.)
+ * Pulled atexit_handler out of the atexit object since it is now required by
+ * on_exit as well. Renamed it to __exit_handler.
+ * Fixed a problem where exit functions stop getting called if one of
+ * them calls exit().
+ * As a side effect of these changes, abort() no longer calls the exit
+ * functions (it now matches the gnu libc definition).
+ *
+ * August 2002 Erik Andersen
+ * Added locking so atexit and friends can be thread safe
+ *
+ * August 2005 Stephen Warren
+ * Added __cxa_atexit and __cxa_finalize support
+ *
+ */
+
+#include <features.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <atomic.h>
+
+#include <bits/uClibc_mutex.h>
+__UCLIBC_MUTEX_EXTERN(__atexit_lock);
+
+
+
+typedef void (*aefuncp)(void); /* atexit function pointer */
+typedef void (*oefuncp)(int, void *); /* on_exit function pointer */
+typedef void (*cxaefuncp)(void *); /* __cxa_atexit function pointer */
+typedef enum {
+ ef_free,
+ ef_in_use,
+ ef_on_exit,
+ ef_cxa_atexit
+} ef_type; /* exit function types */
+
+/* this is in the L_exit object */
+extern void (*__exit_cleanup)(int) attribute_hidden;
+
+/* these are in the L___do_exit object */
+extern int __exit_slots attribute_hidden;
+extern int __exit_count attribute_hidden;
+extern void __exit_handler(int) attribute_hidden;
+struct exit_function {
+ /*
+ * 'type' should be of type of the 'enum ef_type' above but since we
+ * need this element in an atomic operation we have to use 'long int'.
+ */
+ long int type; /* enum ef_type */
+ union {
+ struct {
+ oefuncp func;
+ void *arg;
+ } on_exit;
+ struct {
+ cxaefuncp func;
+ void *arg;
+ void* dso_handle;
+ } cxa_atexit;
+ } funcs;
+};
+#ifdef __UCLIBC_DYNAMIC_ATEXIT__
+extern struct exit_function *__exit_function_table attribute_hidden;
+#else
+extern struct exit_function __exit_function_table[__UCLIBC_MAX_ATEXIT] attribute_hidden;
+#endif
+extern struct exit_function *__new_exitfn(void) attribute_hidden;
+
+/* this is in the L___cxa_atexit object */
+extern int __cxa_atexit(cxaefuncp, void *arg, void *dso_handle);
+
+
+/* remove old_atexit after 0.9.29 */
+#if defined(L_atexit) || defined(L_old_atexit)
+extern void *__dso_handle __attribute__ ((__weak__));
+
+/*
+ * register a function to be called at normal program termination
+ * (the registered function takes no arguments)
+ */
+#ifdef L_atexit
+int attribute_hidden atexit(aefuncp func)
+#else
+int old_atexit(aefuncp func);
+int old_atexit(aefuncp func)
+#endif
+{
+ /*
+ * glibc casts aefuncp to cxaefuncp.
+ * This seems dodgy, but I guess calling a function with more
+ * parameters than it needs will work everywhere?
+ */
+ return __cxa_atexit((cxaefuncp)func, NULL,
+ &__dso_handle == NULL ? NULL : __dso_handle);
+}
+#ifndef L_atexit
+weak_alias(old_atexit,atexit)
+#endif
+#endif
+
+#ifdef L_on_exit
+/*
+ * register a function to be called at normal program termination
+ * the registered function takes two arguments:
+ * status - the exit status that was passed to the exit() function
+ * arg - generic argument
+ */
+int on_exit(oefuncp func, void *arg)
+{
+ struct exit_function *efp;
+
+ if (func == NULL) {
+ return 0;
+ }
+
+ efp = __new_exitfn();
+ if (efp == NULL) {
+ return -1;
+ }
+
+ efp->funcs.on_exit.func = func;
+ efp->funcs.on_exit.arg = arg;
+ /* assign last for thread safety, since we're now unlocked */
+ efp->type = ef_on_exit;
+
+ return 0;
+}
+#endif
+
+#ifdef L___cxa_atexit
+libc_hidden_proto(__cxa_atexit)
+int __cxa_atexit(cxaefuncp func, void *arg, void *dso_handle)
+{
+ struct exit_function *efp;
+
+ if (func == NULL) {
+ return 0;
+ }
+
+ efp = __new_exitfn();
+ if (efp == NULL) {
+ return -1;
+ }
+
+ efp->funcs.cxa_atexit.func = func;
+ efp->funcs.cxa_atexit.arg = arg;
+ efp->funcs.cxa_atexit.dso_handle = dso_handle;
+ /* assign last for thread safety, since we're now unlocked */
+ efp->type = ef_cxa_atexit;
+
+ return 0;
+}
+libc_hidden_def(__cxa_atexit)
+#endif
+
+#ifdef L___cxa_finalize
+/*
+ * If D is non-NULL, call all functions registered with `__cxa_atexit'
+ * with the same dso handle. Otherwise, if D is NULL, call all of the
+ * registered handlers.
+ */
+void __cxa_finalize(void *dso_handle);
+void __cxa_finalize(void *dso_handle)
+{
+ struct exit_function *efp;
+ int exit_count_snapshot = __exit_count;
+
+ /* In reverse order */
+ while (exit_count_snapshot) {
+ efp = &__exit_function_table[--exit_count_snapshot];
+
+ /*
+ * We check dso_handle match before we verify the type of the union entry.
+ * However, the atomic_exchange will validate that we were really "allowed"
+ * to read dso_handle...
+ */
+ if ((dso_handle == NULL || dso_handle == efp->funcs.cxa_atexit.dso_handle)
+ /* We don't want to run this cleanup more than once. */
+ && !atomic_compare_and_exchange_bool_acq(&efp->type, ef_free, ef_cxa_atexit)
+ ) {
+ /* glibc passes status (0) too, but that's not in the prototype */
+ (*efp->funcs.cxa_atexit.func)(efp->funcs.cxa_atexit.arg);
+ }
+ }
+
+#if 0 /* haven't looked into this yet... */
+ /*
+ * Remove the registered fork handlers. We do not have to
+ * unregister anything if the program is going to terminate anyway.
+ */
+#ifdef UNREGISTER_ATFORK
+ if (d != NULL) {
+ UNREGISTER_ATFORK(d);
+ }
+#endif
+#endif
+}
+#endif
+
+#ifdef L___exit_handler
+int __exit_count = 0; /* Number of registered exit functions */
+#ifdef __UCLIBC_DYNAMIC_ATEXIT__
+struct exit_function *__exit_function_table = NULL;
+int __exit_slots = 0; /* Size of __exit_function_table */
+#else
+struct exit_function __exit_function_table[__UCLIBC_MAX_ATEXIT];
+#endif
+
+/*
+ * Find and return a new exit_function pointer, for atexit,
+ * onexit and __cxa_atexit to initialize
+ */
+struct exit_function attribute_hidden *__new_exitfn(void)
+{
+ struct exit_function *efp;
+
+ __UCLIBC_MUTEX_LOCK(__atexit_lock);
+
+#ifdef __UCLIBC_DYNAMIC_ATEXIT__
+ /* If we are out of function table slots, make some more */
+ if (__exit_slots < __exit_count+1) {
+ efp = realloc(__exit_function_table,
+ (__exit_slots+20)*sizeof(struct exit_function));
+ if (efp == NULL) {
+ __set_errno(ENOMEM);
+ goto DONE;
+ }
+ __exit_function_table = efp;
+ __exit_slots += 20;
+ }
+#else
+ if (__exit_count >= __UCLIBC_MAX_ATEXIT) {
+ __set_errno(ENOMEM);
+ efp = NULL;
+ goto DONE;
+ }
+#endif
+
+ __exit_cleanup = __exit_handler; /* enable cleanup */
+ efp = &__exit_function_table[__exit_count++];
+ efp->type = ef_in_use;
+
+DONE:
+ __UCLIBC_MUTEX_UNLOCK(__atexit_lock);
+ return efp;
+}
+
+/*
+ * Handle the work of executing the registered exit functions
+ * This is called while we are locked, so no additional locking
+ * is needed...
+ */
+void __exit_handler(int status)
+{
+ struct exit_function *efp;
+
+ /* In reverse order */
+ while (__exit_count) {
+ efp = &__exit_function_table[--__exit_count];
+ switch (efp->type) {
+ case ef_on_exit:
+ if (efp->funcs.on_exit.func) {
+ (efp->funcs.on_exit.func)(status, efp->funcs.on_exit.arg);
+ }
+ break;
+ case ef_cxa_atexit:
+ if (efp->funcs.cxa_atexit.func) {
+ /* glibc passes status too, but that's not in the prototype */
+ (efp->funcs.cxa_atexit.func)(efp->funcs.cxa_atexit.arg);
+ }
+ break;
+ }
+ }
+#ifdef __UCLIBC_DYNAMIC_ATEXIT__
+ /* Free up memory used by the __exit_function_table structure */
+ free(__exit_function_table);
+#endif
+}
+#endif
+
+#ifdef L_exit
+/* Defeat compiler optimization which assumes function addresses are never NULL */
+static __always_inline int not_null_ptr(const void *p)
+{
+ const void *q;
+ __asm__ (""
+ : "=r" (q) /* output */
+ : "0" (p) /* input */
+ );
+ return q != 0;
+}
+
+extern void weak_function _stdio_term(void) attribute_hidden;
+attribute_hidden void (*__exit_cleanup)(int) = 0;
+__UCLIBC_MUTEX_INIT(__atexit_lock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);
+
+extern void __uClibc_fini(void);
+libc_hidden_proto(__uClibc_fini)
+
+/*
+ * Normal program termination
+ */
+void exit(int rv)
+{
+ /* Perform exit-specific cleanup (atexit and on_exit) */
+ __UCLIBC_MUTEX_LOCK(__atexit_lock);
+ if (not_null_ptr(__exit_cleanup)) {
+ __exit_cleanup(rv);
+ }
+ __UCLIBC_MUTEX_UNLOCK(__atexit_lock);
+
+ __uClibc_fini();
+
+ /* If we are using stdio, try to shut it down. At the very least,
+ * this will attempt to commit all buffered writes. It may also
+ * unbuffer all writable files, or close them outright.
+ * Check the stdio routines for details. */
+ if (not_null_ptr(_stdio_term))
+ _stdio_term();
+
+ _exit(rv);
+}
+libc_hidden_def(exit)
+#endif
diff --git a/ap/build/uClibc/libc/stdlib/_stdlib_mb_cur_max.c b/ap/build/uClibc/libc/stdlib/_stdlib_mb_cur_max.c
new file mode 100644
index 0000000..b87f609
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/_stdlib_mb_cur_max.c
@@ -0,0 +1,7 @@
+/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L__stdlib_mb_cur_max
+#include "stdlib.c"
diff --git a/ap/build/uClibc/libc/stdlib/_stdlib_strto_l.c b/ap/build/uClibc/libc/stdlib/_stdlib_strto_l.c
new file mode 100644
index 0000000..4dfa037
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/_stdlib_strto_l.c
@@ -0,0 +1,7 @@
+/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L__stdlib_strto_l
+#include "stdlib.c"
diff --git a/ap/build/uClibc/libc/stdlib/_stdlib_strto_l_l.c b/ap/build/uClibc/libc/stdlib/_stdlib_strto_l_l.c
new file mode 100644
index 0000000..1692f0c
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/_stdlib_strto_l_l.c
@@ -0,0 +1,8 @@
+/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L__stdlib_strto_l_l
+#define __UCLIBC_DO_XLOCALE
+#include "stdlib.c"
diff --git a/ap/build/uClibc/libc/stdlib/_stdlib_strto_ll.c b/ap/build/uClibc/libc/stdlib/_stdlib_strto_ll.c
new file mode 100644
index 0000000..ce79598
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/_stdlib_strto_ll.c
@@ -0,0 +1,7 @@
+/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L__stdlib_strto_ll
+#include "stdlib.c"
diff --git a/ap/build/uClibc/libc/stdlib/_stdlib_strto_ll_l.c b/ap/build/uClibc/libc/stdlib/_stdlib_strto_ll_l.c
new file mode 100644
index 0000000..b5fb111
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/_stdlib_strto_ll_l.c
@@ -0,0 +1,8 @@
+/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L__stdlib_strto_ll_l
+#define __UCLIBC_DO_XLOCALE
+#include "stdlib.c"
diff --git a/ap/build/uClibc/libc/stdlib/_stdlib_wcsto_l.c b/ap/build/uClibc/libc/stdlib/_stdlib_wcsto_l.c
new file mode 100644
index 0000000..d05a207
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/_stdlib_wcsto_l.c
@@ -0,0 +1,7 @@
+/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L__stdlib_wcsto_l
+#include "stdlib.c"
diff --git a/ap/build/uClibc/libc/stdlib/_stdlib_wcsto_l_l.c b/ap/build/uClibc/libc/stdlib/_stdlib_wcsto_l_l.c
new file mode 100644
index 0000000..26ea5a7
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/_stdlib_wcsto_l_l.c
@@ -0,0 +1,8 @@
+/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L__stdlib_wcsto_l_l
+#define __UCLIBC_DO_XLOCALE
+#include "stdlib.c"
diff --git a/ap/build/uClibc/libc/stdlib/_stdlib_wcsto_ll.c b/ap/build/uClibc/libc/stdlib/_stdlib_wcsto_ll.c
new file mode 100644
index 0000000..e67a577
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/_stdlib_wcsto_ll.c
@@ -0,0 +1,7 @@
+/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L__stdlib_wcsto_ll
+#include "stdlib.c"
diff --git a/ap/build/uClibc/libc/stdlib/_stdlib_wcsto_ll_l.c b/ap/build/uClibc/libc/stdlib/_stdlib_wcsto_ll_l.c
new file mode 100644
index 0000000..9d64712
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/_stdlib_wcsto_ll_l.c
@@ -0,0 +1,8 @@
+/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L__stdlib_wcsto_ll_l
+#define __UCLIBC_DO_XLOCALE
+#include "stdlib.c"
diff --git a/ap/build/uClibc/libc/stdlib/_strtod.c b/ap/build/uClibc/libc/stdlib/_strtod.c
new file mode 100644
index 0000000..1d58258
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/_strtod.c
@@ -0,0 +1,603 @@
+/*
+ * Copyright (C) 2000-2005 Manuel Novoa III
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/* Notes:
+ *
+ * The primary objective of this implementation was minimal size and
+ * portablility, while providing robustness and resonable accuracy.
+ *
+ * This implementation depends on IEEE floating point behavior and expects
+ * to be able to generate +/- infinity as a result.
+ *
+ * There are a number of compile-time options below.
+ */
+
+/* July 27, 2003
+ *
+ * General cleanup and some minor size optimizations.
+ * Change implementation to support __strtofpmax() rather than strtod().
+ * Now all the strto{floating pt}() funcs are implemented in terms of
+ * of the internal __strtofpmax() function.
+ * Support "nan", "inf", and "infinity" strings (case-insensitive).
+ * Support hexadecimal floating point notation.
+ * Support wchar variants.
+ * Support xlocale variants.
+ *
+ * TODO:
+ *
+ * Consider accumulating blocks of digits in longs to save floating pt mults.
+ * This would likely be much better on anything that only supported floats
+ * where DECIMAL_DIG == 9. Actually, if floats have FLT_MAX_10_EXP == 38,
+ * we could calculate almost all the exponent multipliers (p_base) in
+ * long arithmetic as well.
+ */
+
+/**********************************************************************/
+/* OPTIONS */
+/**********************************************************************/
+
+/* Defined if we want to recognize "nan", "inf", and "infinity". (C99) */
+#define _STRTOD_NAN_INF_STRINGS 1
+
+/* Defined if we want support hexadecimal floating point notation. (C99) */
+/* Note! Now controlled by uClibc configuration. See below. */
+#define _STRTOD_HEXADECIMAL_FLOATS 1
+
+/* Defined if we want to scale with a O(log2(exp)) multiplications.
+ * This is generally a good thing to do unless you are really tight
+ * on space and do not expect to convert values of large magnitude. */
+
+#define _STRTOD_LOG_SCALING 1
+
+/* WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!!
+ *
+ * Clearing any of the options below this point is not advised (or tested).
+ *
+ * WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! */
+
+/* Defined if we want strtod to set errno appropriately. */
+/* NOTE: Implies all options below. */
+#define _STRTOD_ERRNO 1
+
+/* Defined if we want support for the endptr arg. */
+/* Implied by _STRTOD_ERRNO. */
+#define _STRTOD_ENDPTR 1
+
+/* Defined if we want to prevent overflow in accumulating the exponent. */
+/* Implied by _STRTOD_ERRNO. */
+#define _STRTOD_RESTRICT_EXP 1
+
+/* Defined if we want to process mantissa digits more intelligently. */
+/* Implied by _STRTOD_ERRNO. */
+#define _STRTOD_RESTRICT_DIGITS 1
+
+/* Defined if we want to skip scaling 0 for the exponent. */
+/* Implied by _STRTOD_ERRNO. */
+#define _STRTOD_ZERO_CHECK 1
+
+/**********************************************************************/
+/* Don't change anything that follows. */
+/**********************************************************************/
+
+#ifdef _STRTOD_ERRNO
+#undef _STRTOD_ENDPTR
+#undef _STRTOD_RESTRICT_EXP
+#undef _STRTOD_RESTRICT_DIGITS
+#undef _STRTOD_ZERO_CHECK
+#define _STRTOD_ENDPTR 1
+#define _STRTOD_RESTRICT_EXP 1
+#define _STRTOD_RESTRICT_DIGITS 1
+#define _STRTOD_ZERO_CHECK 1
+#endif
+
+/**********************************************************************/
+
+#define _ISOC99_SOURCE 1
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+#include <float.h>
+#include <bits/uClibc_fpmax.h>
+
+#include <locale.h>
+
+#ifdef __UCLIBC_HAS_WCHAR__
+# include <wchar.h>
+# include <wctype.h>
+# include <bits/uClibc_uwchar.h>
+#endif
+
+#ifdef __UCLIBC_HAS_XLOCALE__
+# include <xlocale.h>
+#endif
+
+/* Handle _STRTOD_HEXADECIMAL_FLOATS via uClibc config now. */
+#undef _STRTOD_HEXADECIMAL_FLOATS
+#ifdef __UCLIBC_HAS_HEXADECIMAL_FLOATS__
+# define _STRTOD_HEXADECIMAL_FLOATS 1
+#endif
+
+/**********************************************************************/
+
+#undef _STRTOD_FPMAX
+
+#if FPMAX_TYPE == 3
+
+#define NEED_STRTOLD_WRAPPER
+#define NEED_STRTOD_WRAPPER
+#define NEED_STRTOF_WRAPPER
+
+#elif FPMAX_TYPE == 2
+
+#define NEED_STRTOD_WRAPPER
+#define NEED_STRTOF_WRAPPER
+
+#elif FPMAX_TYPE == 1
+
+#define NEED_STRTOF_WRAPPER
+
+#else
+
+#error unknown FPMAX_TYPE!
+
+#endif
+
+extern void __fp_range_check(__fpmax_t y, __fpmax_t x) attribute_hidden;
+
+/**********************************************************************/
+
+#ifdef _STRTOD_RESTRICT_DIGITS
+#define EXP_DENORM_ADJUST DECIMAL_DIG
+#define MAX_ALLOWED_EXP (DECIMAL_DIG + EXP_DENORM_ADJUST - FPMAX_MIN_10_EXP)
+
+#if MAX_ALLOWED_EXP > INT_MAX
+#error size assumption violated for MAX_ALLOWED_EXP
+#endif
+#else
+/* We want some excess if we're not restricting mantissa digits. */
+#define MAX_ALLOWED_EXP ((20 - FPMAX_MIN_10_EXP) * 2)
+#endif
+
+
+#if defined(_STRTOD_RESTRICT_DIGITS) || defined(_STRTOD_ENDPTR) || defined(_STRTOD_HEXADECIMAL_FLOATS)
+#undef _STRTOD_NEED_NUM_DIGITS
+#define _STRTOD_NEED_NUM_DIGITS 1
+#endif
+
+/**********************************************************************/
+#if defined(L___strtofpmax) || defined(L___strtofpmax_l) || defined(L___wcstofpmax) || defined(L___wcstofpmax_l)
+
+#if defined(L___wcstofpmax) || defined(L___wcstofpmax_l)
+
+#define __strtofpmax __wcstofpmax
+#define __strtofpmax_l __wcstofpmax_l
+
+#define Wchar wchar_t
+#ifdef __UCLIBC_DO_XLOCALE
+#define ISSPACE(C) iswspace_l((C), locale_arg)
+#else
+#define ISSPACE(C) iswspace((C))
+#endif
+
+#else /* defined(L___wcstofpmax) || defined(L___wcstofpmax_l) */
+
+#define Wchar char
+#ifdef __UCLIBC_DO_XLOCALE
+#define ISSPACE(C) isspace_l((C), locale_arg)
+#else
+#define ISSPACE(C) isspace((C))
+#endif
+
+#endif /* defined(L___wcstofpmax) || defined(L___wcstofpmax_l) */
+
+
+#if defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE)
+
+__fpmax_t attribute_hidden __strtofpmax(const Wchar *str, Wchar **endptr, int exponent_power)
+{
+ return __strtofpmax_l(str, endptr, exponent_power, __UCLIBC_CURLOCALE);
+}
+
+#else /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
+
+
+__fpmax_t attribute_hidden __XL_NPP(__strtofpmax)(const Wchar *str, Wchar **endptr, int exponent_power
+ __LOCALE_PARAM )
+{
+ __fpmax_t number;
+ __fpmax_t p_base = 10; /* Adjusted to 16 in the hex case. */
+ Wchar *pos0;
+#ifdef _STRTOD_ENDPTR
+ Wchar *pos1;
+#endif
+ Wchar *pos = (Wchar *) str;
+ int exponent_temp;
+ int negative; /* A flag for the number, a multiplier for the exponent. */
+#ifdef _STRTOD_NEED_NUM_DIGITS
+ int num_digits;
+#endif
+#ifdef __UCLIBC_HAS_LOCALE__
+#if defined(L___wcstofpmax) || defined(L___wcstofpmax_l)
+ wchar_t decpt_wc = __LOCALE_PTR->decimal_point_wc;
+#else
+ const char *decpt = __LOCALE_PTR->decimal_point;
+ int decpt_len = __LOCALE_PTR->decimal_point_len;
+#endif
+#endif
+
+#ifdef _STRTOD_HEXADECIMAL_FLOATS
+ Wchar expchar = 'e';
+ Wchar *poshex = NULL;
+ __uint16_t is_mask = _ISdigit;
+#define EXPCHAR expchar
+#define IS_X_DIGIT(C) __isctype((C), is_mask)
+#else /* _STRTOD_HEXADECIMAL_FLOATS */
+#define EXPCHAR 'e'
+#define IS_X_DIGIT(C) isdigit((C))
+#endif /* _STRTOD_HEXADECIMAL_FLOATS */
+
+ while (ISSPACE(*pos)) { /* Skip leading whitespace. */
+ ++pos;
+ }
+
+ negative = 0;
+ switch(*pos) { /* Handle optional sign. */
+ case '-': negative = 1; /* Fall through to increment position. */
+ case '+': ++pos;
+ }
+
+#ifdef _STRTOD_HEXADECIMAL_FLOATS
+ if ((*pos == '0') && (((pos[1])|0x20) == 'x')) {
+ poshex = ++pos; /* Save position of 'x' in case no digits */
+ ++pos; /* and advance past it. */
+ is_mask = _ISxdigit; /* Used by IS_X_DIGIT. */
+ expchar = 'p'; /* Adjust exponent char. */
+ p_base = 16; /* Adjust base multiplier. */
+ }
+#endif
+
+ number = 0.;
+#ifdef _STRTOD_NEED_NUM_DIGITS
+ num_digits = -1;
+#endif
+/* exponent_power = 0; */
+ pos0 = NULL;
+
+ LOOP:
+ while (IS_X_DIGIT(*pos)) { /* Process string of (hex) digits. */
+#ifdef _STRTOD_RESTRICT_DIGITS
+ if (num_digits < 0) { /* First time through? */
+ ++num_digits; /* We've now seen a digit. */
+ }
+ if (num_digits || (*pos != '0')) { /* Had/have nonzero. */
+ ++num_digits;
+ if (num_digits <= DECIMAL_DIG) { /* Is digit significant? */
+#ifdef _STRTOD_HEXADECIMAL_FLOATS
+ number = number * p_base
+ + (isdigit(*pos)
+ ? (*pos - '0')
+ : (((*pos)|0x20) - ('a' - 10)));
+#else /* _STRTOD_HEXADECIMAL_FLOATS */
+ number = number * p_base + (*pos - '0');
+#endif /* _STRTOD_HEXADECIMAL_FLOATS */
+ }
+ }
+#else /* _STRTOD_RESTRICT_DIGITS */
+#ifdef _STRTOD_NEED_NUM_DIGITS
+ ++num_digits;
+#endif
+#ifdef _STRTOD_HEXADECIMAL_FLOATS
+ number = number * p_base
+ + (isdigit(*pos)
+ ? (*pos - '0')
+ : (((*pos)|0x20) - ('a' - 10)));
+#else /* _STRTOD_HEXADECIMAL_FLOATS */
+ number = number * p_base + (*pos - '0');
+#endif /* _STRTOD_HEXADECIMAL_FLOATS */
+#endif /* _STRTOD_RESTRICT_DIGITS */
+ ++pos;
+ }
+
+#ifdef __UCLIBC_HAS_LOCALE__
+#if defined(L___wcstofpmax) || defined(L___wcstofpmax_l)
+ if (!pos0 && (*pos == decpt_wc)) { /* First decimal point? */
+ pos0 = ++pos;
+ goto LOOP;
+ }
+#else
+ if (!pos0 && !memcmp(pos, decpt, decpt_len)) { /* First decimal point? */
+ pos0 = (pos += decpt_len);
+ goto LOOP;
+ }
+#endif
+#else /* __UCLIBC_HAS_LOCALE__ */
+ if ((*pos == '.') && !pos0) { /* First decimal point? */
+ pos0 = ++pos; /* Save position of decimal point */
+ goto LOOP; /* and process rest of digits. */
+ }
+#endif /* __UCLIBC_HAS_LOCALE__ */
+
+#ifdef _STRTOD_NEED_NUM_DIGITS
+ if (num_digits<0) { /* Must have at least one digit. */
+#ifdef _STRTOD_HEXADECIMAL_FLOATS
+ if (poshex) { /* Back up to '0' in '0x' prefix. */
+ pos = poshex;
+ goto DONE;
+ }
+#endif /* _STRTOD_HEXADECIMAL_FLOATS */
+
+#ifdef _STRTOD_NAN_INF_STRINGS
+ if (!pos0) { /* No decimal point, so check for inf/nan. */
+ /* Note: nan is the first string so 'number = i/0.;' works. */
+ static const char nan_inf_str[] = "\05nan\0\012infinity\0\05inf\0";
+ int i = 0;
+
+ do {
+ /* Unfortunately, we have no memcasecmp(). */
+ int j = 0;
+ /* | 0x20 is a cheap lowercasing (valid for ASCII letters and numbers only) */
+ while ((pos[j] | 0x20) == nan_inf_str[i+1+j]) {
+ ++j;
+ if (!nan_inf_str[i+1+j]) {
+ number = i / 0.;
+ if (negative) { /* Correct for sign. */
+ number = -number;
+ }
+ pos += nan_inf_str[i] - 2;
+ goto DONE;
+ }
+ }
+ i += nan_inf_str[i];
+ } while (nan_inf_str[i]);
+ }
+
+#endif /* STRTOD_NAN_INF_STRINGS */
+#ifdef _STRTOD_ENDPTR
+ pos = (Wchar *) str;
+#endif
+ goto DONE;
+ }
+#endif /* _STRTOD_NEED_NUM_DIGITS */
+
+#ifdef _STRTOD_RESTRICT_DIGITS
+ if (num_digits > DECIMAL_DIG) { /* Adjust exponent for skipped digits. */
+ exponent_power += num_digits - DECIMAL_DIG;
+ }
+#endif
+
+ if (pos0) {
+ exponent_power += pos0 - pos; /* Adjust exponent for decimal point. */
+ }
+
+#ifdef _STRTOD_HEXADECIMAL_FLOATS
+ if (poshex) {
+ exponent_power *= 4; /* Above is 2**4, but below is 2. */
+ p_base = 2;
+ }
+#endif /* _STRTOD_HEXADECIMAL_FLOATS */
+
+ if (negative) { /* Correct for sign. */
+ number = -number;
+ }
+
+ /* process an exponent string */
+ if (((*pos)|0x20) == EXPCHAR) {
+#ifdef _STRTOD_ENDPTR
+ pos1 = pos;
+#endif
+ negative = 1;
+ switch(*++pos) { /* Handle optional sign. */
+ case '-': negative = -1; /* Fall through to increment pos. */
+ case '+': ++pos;
+ }
+
+ pos0 = pos;
+ exponent_temp = 0;
+ while (isdigit(*pos)) { /* Process string of digits. */
+#ifdef _STRTOD_RESTRICT_EXP
+ if (exponent_temp < MAX_ALLOWED_EXP) { /* Avoid overflow. */
+ exponent_temp = exponent_temp * 10 + (*pos - '0');
+ }
+#else
+ exponent_temp = exponent_temp * 10 + (*pos - '0');
+#endif
+ ++pos;
+ }
+
+#ifdef _STRTOD_ENDPTR
+ if (pos == pos0) { /* No digits? */
+ pos = pos1; /* Back up to {e|E}/{p|P}. */
+ } /* else */
+#endif
+
+ exponent_power += negative * exponent_temp;
+ }
+
+#ifdef _STRTOD_ZERO_CHECK
+ if (number == 0.) {
+ goto DONE;
+ }
+#endif
+
+ /* scale the result */
+#ifdef _STRTOD_LOG_SCALING
+ exponent_temp = exponent_power;
+
+ if (exponent_temp < 0) {
+ exponent_temp = -exponent_temp;
+ }
+
+ while (exponent_temp) {
+ if (exponent_temp & 1) {
+ if (exponent_power < 0) {
+ /* Warning... caluclating a factor for the exponent and
+ * then dividing could easily be faster. But doing so
+ * might cause problems when dealing with denormals. */
+ number /= p_base;
+ } else {
+ number *= p_base;
+ }
+ }
+ exponent_temp >>= 1;
+ p_base *= p_base;
+ }
+
+#else /* _STRTOD_LOG_SCALING */
+ while (exponent_power) {
+ if (exponent_power < 0) {
+ number /= p_base;
+ exponent_power++;
+ } else {
+ number *= p_base;
+ exponent_power--;
+ }
+ }
+#endif /* _STRTOD_LOG_SCALING */
+
+#ifdef _STRTOD_ERRNO
+ if (__FPMAX_ZERO_OR_INF_CHECK(number)) {
+ __set_errno(ERANGE);
+ }
+#endif
+
+ DONE:
+#ifdef _STRTOD_ENDPTR
+ if (endptr) {
+ *endptr = pos;
+ }
+#endif
+
+ return number;
+}
+
+#endif /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
+
+#endif
+/**********************************************************************/
+#ifdef L___fp_range_check
+#if defined(NEED_STRTOF_WRAPPER) || defined(NEED_STRTOD_WRAPPER)
+
+void attribute_hidden __fp_range_check(__fpmax_t y, __fpmax_t x)
+{
+ if (__FPMAX_ZERO_OR_INF_CHECK(y) /* y is 0 or +/- infinity */
+ && (y != 0) /* y is not 0 (could have x>0, y==0 if underflow) */
+ && !__FPMAX_ZERO_OR_INF_CHECK(x) /* x is not 0 or +/- infinity */
+ ) {
+ __set_errno(ERANGE); /* Then x is not in y's range. */
+ }
+}
+
+#endif
+#endif
+/**********************************************************************/
+#if defined(L_strtof) || defined(L_strtof_l) || defined(L_wcstof) || defined(L_wcstof_l)
+#if defined(NEED_STRTOF_WRAPPER)
+
+#if defined(L_wcstof) || defined(L_wcstof_l)
+#define strtof wcstof
+#define strtof_l wcstof_l
+#define __strtofpmax __wcstofpmax
+#define __strtofpmax_l __wcstofpmax_l
+#define Wchar wchar_t
+#else
+#define Wchar char
+#endif
+
+
+libc_hidden_proto(__XL_NPP(strtof))
+float __XL_NPP(strtof)(const Wchar *str, Wchar **endptr __LOCALE_PARAM )
+{
+#if FPMAX_TYPE == 1
+ return __XL_NPP(__strtofpmax)(str, endptr, 0 __LOCALE_ARG );
+#else
+ __fpmax_t x;
+ float y;
+
+ x = __XL_NPP(__strtofpmax)(str, endptr, 0 __LOCALE_ARG );
+ y = (float) x;
+
+ __fp_range_check(y, x);
+
+ return y;
+#endif
+}
+libc_hidden_def(__XL_NPP(strtof))
+
+#endif
+#endif
+/**********************************************************************/
+#if defined(L_strtod) || defined(L_strtod_l) || defined(L_wcstod) || defined(L_wcstod_l)
+#if defined(NEED_STRTOD_WRAPPER)
+
+#if defined(L_wcstod) || defined(L_wcstod_l)
+#define strtod wcstod
+#define strtod_l wcstod_l
+#define __strtofpmax __wcstofpmax
+#define __strtofpmax_l __wcstofpmax_l
+#define Wchar wchar_t
+#else
+#define Wchar char
+#endif
+
+double __XL_NPP(strtod)(const Wchar *__restrict str,
+ Wchar **__restrict endptr __LOCALE_PARAM )
+{
+#if FPMAX_TYPE == 2
+ return __XL_NPP(__strtofpmax)(str, endptr, 0 __LOCALE_ARG );
+#else
+ __fpmax_t x;
+ double y;
+
+ x = __XL_NPP(__strtofpmax)(str, endptr, 0 __LOCALE_ARG );
+ y = (double) x;
+
+ __fp_range_check(y, x);
+
+ return y;
+#endif
+}
+#ifdef L_strtod
+libc_hidden_def(strtod)
+#endif
+
+#endif
+#endif
+/**********************************************************************/
+#if defined(L_strtold) || defined(L_strtold_l) || defined(L_wcstold) || defined(L_wcstold_l)
+#if defined(NEED_STRTOLD_WRAPPER)
+
+#if defined(L_wcstold) || defined(L_wcstold_l)
+#define strtold wcstold
+#define strtold_l wcstold_l
+#define __strtofpmax __wcstofpmax
+#define __strtofpmax_l __wcstofpmax_l
+#define Wchar wchar_t
+#else
+#define Wchar char
+#endif
+
+long double __XL_NPP(strtold) (const Wchar *str, Wchar **endptr __LOCALE_PARAM )
+{
+#if FPMAX_TYPE == 3
+ return __XL_NPP(__strtofpmax)(str, endptr, 0 __LOCALE_ARG );
+#else
+ __fpmax_t x;
+ long double y;
+
+ x = __XL_NPP(__strtofpmax)(str, endptr, 0 __LOCALE_ARG );
+ y = (long double) x;
+
+ __fp_range_check(y, x);
+
+ return y;
+#endif
+}
+
+#endif
+#endif
+/**********************************************************************/
diff --git a/ap/build/uClibc/libc/stdlib/a64l.c b/ap/build/uClibc/libc/stdlib/a64l.c
new file mode 100644
index 0000000..d09dbf4
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/a64l.c
@@ -0,0 +1,64 @@
+/* Copyright (C) 1995, 1997, 1998, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.org>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdlib.h>
+
+#define TABLE_BASE 0x2e
+#define TABLE_SIZE 0x4d
+
+#define XX ((char)0x40)
+
+
+static const char a64l_table[TABLE_SIZE] =
+{
+ /* 0x2e */ 0, 1,
+ /* 0x30 */ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, XX, XX, XX, XX, XX, XX,
+ /* 0x40 */ XX, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
+ /* 0x50 */ 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, XX, XX, XX, XX, XX,
+ /* 0x60 */ XX, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
+ /* 0x70 */ 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63
+};
+
+
+long int a64l (const char *string)
+{
+ const char *ptr = string;
+ unsigned long int result = 0ul;
+ const char *end = ptr + 6;
+ int shift = 0;
+
+ do
+ {
+ unsigned index;
+ unsigned value;
+
+ index = *ptr - TABLE_BASE;
+ if ((unsigned int) index >= TABLE_SIZE)
+ break;
+ value = (int) a64l_table[index];
+ if (value == (int) XX)
+ break;
+ ++ptr;
+ result |= value << shift;
+ shift += 6;
+ }
+ while (ptr != end);
+
+ return (long int) result;
+}
diff --git a/ap/build/uClibc/libc/stdlib/abort.c b/ap/build/uClibc/libc/stdlib/abort.c
new file mode 100644
index 0000000..0bdff7f
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/abort.c
@@ -0,0 +1,128 @@
+/* Copyright (C) 1991 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA. */
+
+/* Hacked up for uClibc by Erik Andersen */
+
+#include <features.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+#include <errno.h>
+
+
+
+/* Defeat compiler optimization which assumes function addresses are never NULL */
+static __always_inline int not_null_ptr(const void *p)
+{
+ const void *q;
+ __asm__ (""
+ : "=r" (q) /* output */
+ : "0" (p) /* input */
+ );
+ return q != 0;
+}
+
+/* Our last ditch effort to commit suicide */
+#ifdef __UCLIBC_ABORT_INSTRUCTION__
+# define ABORT_INSTRUCTION __asm__(__UCLIBC_ABORT_INSTRUCTION__)
+#else
+# define ABORT_INSTRUCTION
+# warning "no abort instruction defined for your arch"
+#endif
+
+#ifdef __UCLIBC_HAS_STDIO_SHUTDOWN_ON_ABORT__
+extern void weak_function _stdio_term(void) attribute_hidden;
+#endif
+static smallint been_there_done_that = 0;
+
+/* Be prepared in case multiple threads try to abort() */
+#include <bits/uClibc_mutex.h>
+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);
+
+/* Cause an abnormal program termination with core-dump */
+void abort(void)
+{
+ sigset_t sigs;
+ int * p = (int *)(0xffffffff);
+
+ if(*p)
+ printf("zxic abort and assert\n");
+ /* Make sure we acquire the lock before proceeding */
+ __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE(mylock);
+
+ /* Unmask SIGABRT to be sure we can get it */
+ __sigemptyset(&sigs);
+ __sigaddset(&sigs, SIGABRT);
+ sigprocmask(SIG_UNBLOCK, &sigs, NULL);
+
+ while (1) {
+ /* Try to suicide with a SIGABRT */
+ if (been_there_done_that == 0) {
+ been_there_done_that++;
+
+#ifdef __UCLIBC_HAS_STDIO_SHUTDOWN_ON_ABORT__
+ /* If we are using stdio, try to shut it down. At the very least,
+ * this will attempt to commit all buffered writes. It may also
+ * unbuffer all writable files, or close them outright.
+ * Check the stdio routines for details. */
+ if (not_null_ptr(_stdio_term)) {
+ _stdio_term();
+ }
+#endif
+
+abort_it:
+ __UCLIBC_MUTEX_UNLOCK_CANCEL_UNSAFE(mylock);
+ raise(SIGABRT);
+ __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE(mylock);
+ }
+
+ /* Still here? Try to remove any signal handlers */
+ if (been_there_done_that == 1) {
+ struct sigaction act;
+
+ been_there_done_that++;
+ memset(&act, '\0', sizeof(struct sigaction));
+ if (SIG_DFL) /* if it's constant zero, already done */
+ act.sa_handler = SIG_DFL;
+ __sigfillset(&act.sa_mask);
+ sigaction(SIGABRT, &act, NULL);
+
+ goto abort_it;
+ }
+
+ /* Still here? Try to suicide with an illegal instruction */
+ if (been_there_done_that == 2) {
+ been_there_done_that++;
+ ABORT_INSTRUCTION;
+ }
+
+ /* Still here? Try to at least exit */
+ if (been_there_done_that == 3) {
+ been_there_done_that++;
+ _exit(127);
+ }
+
+ /* Still here? We're screwed. Sleepy time. Good night. */
+ while (1)
+ /* Try for ever and ever */
+ ABORT_INSTRUCTION;
+ }
+}
+libc_hidden_def(abort)
diff --git a/ap/build/uClibc/libc/stdlib/abs.c b/ap/build/uClibc/libc/stdlib/abs.c
new file mode 100644
index 0000000..540c020
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/abs.c
@@ -0,0 +1,7 @@
+/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_abs
+#include "stdlib.c"
diff --git a/ap/build/uClibc/libc/stdlib/arc4random.c b/ap/build/uClibc/libc/stdlib/arc4random.c
new file mode 100644
index 0000000..c7aed66
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/arc4random.c
@@ -0,0 +1,197 @@
+/* $$$: arc4random.c 2005/02/08 robert */
+/* $NetBSD: arc4random.c,v 1.5.2.1 2004/03/26 22:52:50 jmc Exp $ */
+/* $OpenBSD: arc4random.c,v 1.6 2001/06/05 05:05:38 pvalchev Exp $ */
+
+/*
+ * Arc4 random number generator for OpenBSD.
+ * Copyright 1996 David Mazieres <dm@lcs.mit.edu>.
+ *
+ * Modification and redistribution in source and binary forms is
+ * permitted provided that due credit is given to the author and the
+ * OpenBSD project by leaving this copyright notice intact.
+ */
+
+/*
+ * This code is derived from section 17.1 of Applied Cryptography,
+ * second edition, which describes a stream cipher allegedly
+ * compatible with RSA Labs "RC4" cipher (the actual description of
+ * which is a trade secret). The same algorithm is used as a stream
+ * cipher called "arcfour" in Tatu Ylonen's ssh package.
+ *
+ * Here the stream cipher has been modified always to include the time
+ * when initializing the state. That makes it impossible to
+ * regenerate the same random sequence twice, so this can't be used
+ * for encryption, but will generate good random numbers.
+ *
+ * RC4 is a registered trademark of RSA Laboratories.
+ */
+
+#include <features.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#ifdef __ARC4RANDOM_USE_ERANDOM__
+#include <sys/sysctl.h>
+#endif
+
+
+struct arc4_stream {
+ uint8_t i;
+ uint8_t j;
+ uint8_t s[256];
+};
+
+static int rs_initialized;
+static struct arc4_stream rs;
+
+static __inline__ void arc4_init(struct arc4_stream *);
+static __inline__ void arc4_addrandom(struct arc4_stream *, u_char *, int);
+static void arc4_stir(struct arc4_stream *);
+static __inline__ uint8_t arc4_getbyte(struct arc4_stream *);
+static __inline__ uint32_t arc4_getword(struct arc4_stream *);
+
+static __inline__ void
+arc4_init(struct arc4_stream *as)
+{
+ int n;
+
+ for (n = 0; n < 256; n++)
+ as->s[n] = n;
+ as->i = 0;
+ as->j = 0;
+}
+
+static __inline__ void
+arc4_addrandom(struct arc4_stream *as, u_char *dat, int datlen)
+{
+ int n;
+ uint8_t si;
+
+ as->i--;
+ for (n = 0; n < 256; n++) {
+ as->i = (as->i + 1);
+ si = as->s[as->i];
+ as->j = (as->j + si + dat[n % datlen]);
+ as->s[as->i] = as->s[as->j];
+ as->s[as->j] = si;
+ }
+ as->j = as->i;
+}
+
+static void
+arc4_stir(struct arc4_stream *as)
+{
+ int fd;
+ struct {
+ struct timeval tv;
+ uint rnd[(128 - sizeof(struct timeval)) / sizeof(uint)];
+ } rdat;
+ int n;
+
+ gettimeofday(&rdat.tv, NULL);
+ fd = open("/dev/urandom", O_RDONLY);
+ if (fd != -1) {
+ read(fd, rdat.rnd, sizeof(rdat.rnd));
+ close(fd);
+ }
+#ifdef __ARC4RANDOM_USE_ERANDOM__
+ else {
+ int mib[3];
+ uint i;
+ size_t len;
+
+ /* Device could not be opened, we might be chrooted, take
+ * randomness from sysctl. */
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_RANDOM;
+ mib[2] = RANDOM_ERANDOM;
+
+ for (i = 0; i < sizeof(rdat.rnd) / sizeof(uint); i++) {
+ len = sizeof(uint);
+ if (sysctl(mib, 3, &rdat.rnd[i], &len, NULL, 0) == -1)
+ break;
+ }
+ }
+#endif
+
+ arc4_addrandom(as, (void *) &rdat, sizeof(rdat));
+
+ /*
+ * Throw away the first N words of output, as suggested in the
+ * paper "Weaknesses in the Key Scheduling Algorithm of RC4"
+ * by Fluher, Mantin, and Shamir.
+ * http://www.wisdom.weizmann.ac.il/~itsik/RC4/Papers/Rc4_ksa.ps
+ * N = 256 in our case.
+ */
+ for (n = 0; n < 256 * 4; n++)
+ arc4_getbyte(as);
+}
+
+static __inline__ uint8_t
+arc4_getbyte(struct arc4_stream *as)
+{
+ uint8_t si, sj;
+
+ as->i = (as->i + 1);
+ si = as->s[as->i];
+ as->j = (as->j + si);
+ sj = as->s[as->j];
+ as->s[as->i] = sj;
+ as->s[as->j] = si;
+ return (as->s[(si + sj) & 0xff]);
+}
+
+static __inline__ uint32_t
+arc4_getword(struct arc4_stream *as)
+{
+ uint32_t val;
+ val = arc4_getbyte(as) << 24;
+ val |= arc4_getbyte(as) << 16;
+ val |= arc4_getbyte(as) << 8;
+ val |= arc4_getbyte(as);
+ return val;
+}
+
+static void
+__arc4random_stir(void)
+{
+ if (!rs_initialized) {
+ arc4_init(&rs);
+ rs_initialized = 1;
+ }
+ arc4_stir(&rs);
+}
+strong_alias(__arc4random_stir,arc4random_stir)
+
+void
+arc4random_addrandom(u_char *dat, int datlen)
+{
+ if (!rs_initialized)
+ __arc4random_stir();
+ arc4_addrandom(&rs, dat, datlen);
+}
+
+uint32_t
+arc4random(void)
+{
+ if (!rs_initialized)
+ __arc4random_stir();
+ return arc4_getword(&rs);
+}
+
+#if 0
+/*-------- Test code --------*/
+#include <stdlib.h>
+#include <stdio.h>
+
+int main(void) {
+ int random_number;
+ random_number = arc4random() % 65536;
+ printf("%d\n", random_number);
+ return 0;
+}
+#endif
diff --git a/ap/build/uClibc/libc/stdlib/atexit.c b/ap/build/uClibc/libc/stdlib/atexit.c
new file mode 100644
index 0000000..158869e
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/atexit.c
@@ -0,0 +1,8 @@
+/*
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_atexit
+#include "_atexit.c"
diff --git a/ap/build/uClibc/libc/stdlib/atof.c b/ap/build/uClibc/libc/stdlib/atof.c
new file mode 100644
index 0000000..2fdd75c
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/atof.c
@@ -0,0 +1,7 @@
+/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_atof
+#include "stdlib.c"
diff --git a/ap/build/uClibc/libc/stdlib/atoi.c b/ap/build/uClibc/libc/stdlib/atoi.c
new file mode 100644
index 0000000..61562bb
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/atoi.c
@@ -0,0 +1,7 @@
+/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_atoi
+#include "stdlib.c"
diff --git a/ap/build/uClibc/libc/stdlib/atol.c b/ap/build/uClibc/libc/stdlib/atol.c
new file mode 100644
index 0000000..3e57720
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/atol.c
@@ -0,0 +1,7 @@
+/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_atol
+#include "stdlib.c"
diff --git a/ap/build/uClibc/libc/stdlib/atoll.c b/ap/build/uClibc/libc/stdlib/atoll.c
new file mode 100644
index 0000000..f6b04a6
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/atoll.c
@@ -0,0 +1,7 @@
+/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_atoll
+#include "stdlib.c"
diff --git a/ap/build/uClibc/libc/stdlib/bsd_getpt.c b/ap/build/uClibc/libc/stdlib/bsd_getpt.c
new file mode 100644
index 0000000..e704e23
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/bsd_getpt.c
@@ -0,0 +1,76 @@
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Zack Weinberg <zack@rabi.phys.columbia.edu>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+
+#if defined __USE_BSD
+
+/* Prefix for master pseudo terminal nodes. */
+#define _PATH_PTY "/dev/pty"
+
+/* Letters indicating a series of pseudo terminals. */
+#ifndef PTYNAME1
+#define PTYNAME1 "pqrsPQRS"
+#endif
+const char __libc_ptyname1[] attribute_hidden = PTYNAME1;
+
+/* Letters indicating the position within a series. */
+#ifndef PTYNAME2
+#define PTYNAME2 "0123456789abcdefghijklmnopqrstuv";
+#endif
+const char __libc_ptyname2[] attribute_hidden = PTYNAME2;
+
+/* Open a master pseudo terminal and return its file descriptor. */
+int
+__getpt (void)
+{
+ char buf[sizeof (_PATH_PTY) + 2];
+ const char *p, *q;
+ char *s;
+
+ s = mempcpy (buf, _PATH_PTY, sizeof (_PATH_PTY) - 1);
+ /* s[0] and s[1] will be filled in the loop. */
+ s[2] = '\0';
+
+ for (p = __libc_ptyname1; *p != '\0'; ++p)
+ {
+ s[0] = *p;
+
+ for (q = __libc_ptyname2; *q != '\0'; ++q)
+ {
+ int fd;
+
+ s[1] = *q;
+
+ fd = open (buf, O_RDWR);
+ if (fd != -1)
+ return fd;
+
+ if (errno == ENOENT)
+ return -1;
+ }
+ }
+
+ __set_errno (ENOENT);
+ return -1;
+}
+#endif /* __USE_BSD */
diff --git a/ap/build/uClibc/libc/stdlib/bsearch.c b/ap/build/uClibc/libc/stdlib/bsearch.c
new file mode 100644
index 0000000..4feceef
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/bsearch.c
@@ -0,0 +1,7 @@
+/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_bsearch
+#include "stdlib.c"
diff --git a/ap/build/uClibc/libc/stdlib/canonicalize.c b/ap/build/uClibc/libc/stdlib/canonicalize.c
new file mode 100644
index 0000000..06e710a
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/canonicalize.c
@@ -0,0 +1,38 @@
+/*
+ * canonicalize.c -- Return a malloc'd string containing the canonical
+ * absolute name of the named file. The last file name component need
+ * not exist, and may be a symlink to a nonexistent file.
+ * Copyright (C) 2009 STMicroelectronics
+ * Author: Salvatore Cro <salvatore.cro@st.com>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <stdlib.h>
+#include <limits.h>
+
+#ifdef __USE_GNU
+
+#ifndef PATH_MAX
+# ifdef _POSIX_VERSION
+# define PATH_MAX _POSIX_PATH_MAX
+# else
+# ifdef MAXPATHLEN
+# define PATH_MAX MAXPATHLEN
+# else
+# define PATH_MAX 1024
+# endif
+# endif
+#endif
+
+char * canonicalize_file_name (const char *name)
+{
+ char *buf = (char *) malloc(PATH_MAX);
+
+ if(unlikely(buf == NULL))
+ return NULL;
+
+ *buf='\0';
+ return realpath (name, buf);
+}
+#endif
diff --git a/ap/build/uClibc/libc/stdlib/div.c b/ap/build/uClibc/libc/stdlib/div.c
new file mode 100644
index 0000000..6c59595
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/div.c
@@ -0,0 +1,17 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * div for uClibc
+ * Copyright (C) 2000-2006 by Erik Andersen <andersen@uclibc.org>
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <stdlib.h>
+
+div_t div(int numer, int denom)
+{
+ div_t result;
+ result.quot = numer / denom;
+ result.rem = numer - (result.quot * denom);
+ return(result);
+}
+
diff --git a/ap/build/uClibc/libc/stdlib/drand48-iter.c b/ap/build/uClibc/libc/stdlib/drand48-iter.c
new file mode 100644
index 0000000..7d705ad
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/drand48-iter.c
@@ -0,0 +1,59 @@
+/* Copyright (C) 1995, 1996, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+/* Global state for non-reentrant functions. */
+struct drand48_data __libc_drand48_data;
+
+#ifdef __UCLIBC_MJN3_ONLY__
+#warning turn int __drand48_iterate into void
+#endif /* __UCLIBC_MJN3_ONLY__ */
+int __drand48_iterate (unsigned short int xsubi[3], struct drand48_data *buffer)
+{
+ uint64_t X;
+ uint64_t result;
+
+ /* Initialize buffer, if not yet done. */
+ if (unlikely(!buffer->__init))
+ {
+ buffer->__a = 0x5deece66dull;
+ buffer->__c = 0xb;
+ buffer->__init = 1;
+ }
+
+ /* Do the real work. We choose a data type which contains at least
+ 48 bits. Because we compute the modulus it does not care how
+ many bits really are computed. */
+
+ X = (uint64_t) xsubi[2] << 32 | (uint32_t) xsubi[1] << 16 | xsubi[0];
+
+ result = X * buffer->__a + buffer->__c;
+
+ xsubi[0] = result & 0xffff;
+ xsubi[1] = (result >> 16) & 0xffff;
+ xsubi[2] = (result >> 32) & 0xffff;
+
+ return 0;
+}
diff --git a/ap/build/uClibc/libc/stdlib/drand48.c b/ap/build/uClibc/libc/stdlib/drand48.c
new file mode 100644
index 0000000..c53dcfb
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/drand48.c
@@ -0,0 +1,29 @@
+/* Copyright (C) 1995,1996,1997,1998,2001,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdlib.h>
+
+double drand48 (void)
+{
+ double result;
+
+ (void) erand48_r (__libc_drand48_data.__x, &__libc_drand48_data, &result);
+
+ return result;
+}
diff --git a/ap/build/uClibc/libc/stdlib/drand48_r.c b/ap/build/uClibc/libc/stdlib/drand48_r.c
new file mode 100644
index 0000000..df07b07
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/drand48_r.c
@@ -0,0 +1,28 @@
+/* Copyright (C) 1995, 1996, 1997, 1998, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <math.h>
+#include <stdlib.h>
+
+
+int drand48_r (struct drand48_data *buffer, double *result)
+{
+ return erand48_r (buffer->__x, buffer, result);
+}
diff --git a/ap/build/uClibc/libc/stdlib/erand48.c b/ap/build/uClibc/libc/stdlib/erand48.c
new file mode 100644
index 0000000..f3603cd
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/erand48.c
@@ -0,0 +1,29 @@
+/* Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu <mailto:drepper@gnu.ai.mit.edu>>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdlib.h>
+
+double erand48 (unsigned short int xsubi[3])
+{
+ double result;
+
+ (void) erand48_r (xsubi, &__libc_drand48_data, &result);
+
+ return result;
+}
diff --git a/ap/build/uClibc/libc/stdlib/erand48_r.c b/ap/build/uClibc/libc/stdlib/erand48_r.c
new file mode 100644
index 0000000..bd40a34
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/erand48_r.c
@@ -0,0 +1,45 @@
+/* Copyright (C) 1995, 1997, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu <mailto:drepper@gnu.ai.mit.edu>>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <ieee754.h>
+#include <stdlib.h>
+#include <limits.h>
+
+int erand48_r (unsigned short int xsubi[3], struct drand48_data *buffer, double *result)
+{
+ union ieee754_double temp;
+
+ /* Compute next state. */
+ if (__drand48_iterate (xsubi, buffer) < 0)
+ return -1;
+
+ /* Construct a positive double with the 48 random bits distributed over
+ its fractional part so the resulting FP number is [0.0,1.0). */
+
+ temp.ieee.negative = 0;
+ temp.ieee.exponent = IEEE754_DOUBLE_BIAS;
+ temp.ieee.mantissa0 = (xsubi[2] << 4) | (xsubi[1] >> 12);
+ temp.ieee.mantissa1 = ((xsubi[1] & 0xfff) << 20) | (xsubi[0] << 4);
+
+ /* Please note the lower 4 bits of mantissa1 are always 0. */
+ *result = temp.d - 1.0;
+
+ return 0;
+}
+libc_hidden_def(erand48_r)
diff --git a/ap/build/uClibc/libc/stdlib/exit.c b/ap/build/uClibc/libc/stdlib/exit.c
new file mode 100644
index 0000000..a2255d2
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/exit.c
@@ -0,0 +1,8 @@
+/*
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_exit
+#include "_atexit.c"
diff --git a/ap/build/uClibc/libc/stdlib/gcvt.c b/ap/build/uClibc/libc/stdlib/gcvt.c
new file mode 100644
index 0000000..3c27b62
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/gcvt.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+
+#ifdef __UCLIBC_HAS_FLOATS__
+#define MAX_NDIGIT 17
+char *gcvt (double number, int ndigit, char *buf)
+{
+ sprintf(buf, "%.*g", (ndigit > MAX_NDIGIT)? MAX_NDIGIT : ndigit, number);
+ return buf;
+}
+#endif
diff --git a/ap/build/uClibc/libc/stdlib/getenv.c b/ap/build/uClibc/libc/stdlib/getenv.c
new file mode 100644
index 0000000..d5db178
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/getenv.c
@@ -0,0 +1,30 @@
+/* getenv.c for uClibc
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+
+/* IEEE Std 1003.1-2001 says getenv need not be thread safe, so
+ * don't bother locking access to __environ */
+char *getenv(const char *var)
+{
+ int len;
+ char **ep;
+
+ if (!(ep=__environ))
+ return NULL;
+ len = strlen(var);
+ while(*ep) {
+ if (memcmp(var, *ep, len) == 0 && (*ep)[len] == '=') {
+ return *ep + len + 1;
+ }
+ ep++;
+ }
+ return NULL;
+}
+libc_hidden_def(getenv)
diff --git a/ap/build/uClibc/libc/stdlib/getpt.c b/ap/build/uClibc/libc/stdlib/getpt.c
new file mode 100644
index 0000000..2d8b207
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/getpt.c
@@ -0,0 +1,132 @@
+/* Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Zack Weinberg <zack@rabi.phys.columbia.edu>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <paths.h>
+#include <sys/statfs.h>
+
+extern __typeof(statfs) __libc_statfs;
+
+
+#if !defined __ASSUME_DEVPTS__
+
+/* Constant that identifies the `devpts' filesystem. */
+# define DEVPTS_SUPER_MAGIC 0x1cd1
+/* Constant that identifies the `devfs' filesystem. */
+# define DEVFS_SUPER_MAGIC 0x1373
+#endif
+
+/* Path to the master pseudo terminal cloning device. */
+#define _PATH_DEVPTMX _PATH_DEV "ptmx"
+/* Directory containing the UNIX98 pseudo terminals. */
+#define _PATH_DEVPTS _PATH_DEV "pts"
+
+#if !defined __UNIX98PTY_ONLY__ && defined __UCLIBC_HAS_GETPT__
+/* Prototype for function that opens BSD-style master pseudo-terminals. */
+extern int __bsd_getpt (void) attribute_hidden;
+#endif
+
+/* Open a master pseudo terminal and return its file descriptor. */
+int
+posix_openpt (int flags)
+{
+#define have_no_dev_ptmx (1<<0)
+#define devpts_mounted (1<<1)
+#if !defined __UNIX98PTY_ONLY__
+ static smallint _state;
+#endif
+ int fd;
+
+#if !defined __UNIX98PTY_ONLY__
+ if (!(_state & have_no_dev_ptmx))
+#endif
+ {
+ fd = open (_PATH_DEVPTMX, flags);
+ if (fd != -1)
+ {
+#if defined __ASSUME_DEVPTS__
+ return fd;
+#else
+ struct statfs fsbuf;
+
+ /* Check that the /dev/pts filesystem is mounted
+ or if /dev is a devfs filesystem (this implies /dev/pts). */
+ if (
+#if !defined __UNIX98PTY_ONLY__
+ (_state & devpts_mounted) ||
+#endif
+ (__libc_statfs (_PATH_DEVPTS, &fsbuf) == 0
+ && fsbuf.f_type == DEVPTS_SUPER_MAGIC)
+ || (__libc_statfs (_PATH_DEV, &fsbuf) == 0
+ && fsbuf.f_type == DEVFS_SUPER_MAGIC))
+ {
+ /* Everything is ok. */
+#if !defined __UNIX98PTY_ONLY__
+ _state |= devpts_mounted;
+#endif
+ return fd;
+ }
+
+ /* If /dev/pts is not mounted then the UNIX98 pseudo terminals
+ are not usable. */
+ close (fd);
+#if !defined __UNIX98PTY_ONLY__
+ _state |= have_no_dev_ptmx;
+#endif
+#endif
+ }
+ else
+ {
+#if !defined __UNIX98PTY_ONLY__
+ if (errno == ENOENT || errno == ENODEV)
+ _state |= have_no_dev_ptmx;
+ else
+#endif
+ return -1;
+ }
+ }
+#if !defined __UNIX98PTY_ONLY__ && defined __UCLIBC_HAS_GETPT__
+ /* If we have no ptmx then ignore flags and use the fallback. */
+ if (_state & have_no_dev_ptmx)
+ return __bsd_getpt();
+#endif
+ return -1;
+}
+libc_hidden_def(posix_openpt)
+#undef have_no_dev_ptmx
+#undef devpts_mounted
+
+#if defined __USE_GNU && defined __UCLIBC_HAS_GETPT__
+int getpt (void)
+{
+ return posix_openpt(O_RDWR);
+}
+
+#if !defined __UNIX98PTY_ONLY__ && defined __UCLIBC_HAS_GETPT__
+# define PTYNAME1 "pqrstuvwxyzabcde";
+# define PTYNAME2 "0123456789abcdef";
+
+# define __getpt __bsd_getpt
+# include "bsd_getpt.c"
+#endif
+#endif /* GNU && __UCLIBC_HAS_GETPT__ */
diff --git a/ap/build/uClibc/libc/stdlib/grantpt.c b/ap/build/uClibc/libc/stdlib/grantpt.c
new file mode 100644
index 0000000..42a64b3
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/grantpt.c
@@ -0,0 +1,76 @@
+/* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <limits.h>
+#include <stdlib.h>
+
+/* If __ASSUME_DEVPTS__ is defined, grantpt() reduces to a stub since we
+ assume that the devfs/devpts filesystem automatically manages the
+ permissions. */
+#if !defined __ASSUME_DEVPTS__
+#include <sys/statfs.h>
+
+/* Constant that identifies the `devpts' filesystem. */
+#define DEVPTS_SUPER_MAGIC 0x1cd1
+/* Constant that identifies the `devfs' filesystem. */
+#define DEVFS_SUPER_MAGIC 0x1373
+
+/* Prototype for function that changes ownership and access permission
+ for slave pseudo terminals that do not live on a `devpts'
+ filesystem. */
+int __unix_grantpt (int fd);
+
+/* Prototype for private function that gets the name of the slave
+ pseudo terminal in a safe way. */
+static int pts_name (int fd, char **pts, size_t buf_len);
+extern __typeof(statfs) __libc_statfs;
+#endif
+
+/* Change the ownership and access permission of the slave pseudo
+ terminal associated with the master pseudo terminal specified
+ by FD. */
+int
+#if !defined __ASSUME_DEVPTS__
+grantpt (int fd)
+#else
+grantpt (attribute_unused int fd)
+#endif
+{
+#if !defined __ASSUME_DEVPTS__
+ struct statfs fsbuf;
+ char _buf[PATH_MAX];
+ char *buf = _buf;
+
+ if (pts_name (fd, &buf, sizeof (_buf)))
+ return -1;
+
+ if (__libc_statfs (buf, &fsbuf) < 0)
+ return -1;
+
+ /* If the slave pseudo terminal lives on a `devpts' filesystem, the
+ ownership and access permission are already set. */
+ if (fsbuf.f_type != DEVPTS_SUPER_MAGIC && fsbuf.f_type != DEVFS_SUPER_MAGIC)
+ return __unix_grantpt (fd);
+#endif
+ return 0;
+}
+
+#if !defined __ASSUME_DEVPTS__
+# define grantpt __unix_grantpt
+# include "unix_grantpt.c"
+#endif
diff --git a/ap/build/uClibc/libc/stdlib/jrand48.c b/ap/build/uClibc/libc/stdlib/jrand48.c
new file mode 100644
index 0000000..8a06ced
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/jrand48.c
@@ -0,0 +1,29 @@
+/* Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu <mailto:drepper@gnu.ai.mit.edu>>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdlib.h>
+
+long int jrand48 (unsigned short int xsubi[3])
+{
+ long int result;
+
+ (void) jrand48_r (xsubi, &__libc_drand48_data, &result);
+
+ return result;
+}
diff --git a/ap/build/uClibc/libc/stdlib/jrand48_r.c b/ap/build/uClibc/libc/stdlib/jrand48_r.c
new file mode 100644
index 0000000..5652d10
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/jrand48_r.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 1995, 1997, 1998, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu <mailto:drepper@gnu.ai.mit.edu>>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdlib.h>
+
+int jrand48_r (unsigned short int xsubi[3], struct drand48_data *buffer, long int *result)
+{
+ /* Compute next state. */
+ if (__drand48_iterate (xsubi, buffer) < 0)
+ return -1;
+
+ /* Store the result. */
+ *result = ((xsubi[2] << 16) | xsubi[1]) & 0xffffffffl;
+
+ return 0;
+}
+libc_hidden_def(jrand48_r)
diff --git a/ap/build/uClibc/libc/stdlib/l64a.c b/ap/build/uClibc/libc/stdlib/l64a.c
new file mode 100644
index 0000000..1f0dfb7
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/l64a.c
@@ -0,0 +1,56 @@
+/* Copyright (C) 1995, 1996, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdlib.h>
+
+/* Conversion table. */
+static const char conv_table[64] =
+{
+ '.', '/', '0', '1', '2', '3', '4', '5',
+ '6', '7', '8', '9', 'A', 'B', 'C', 'D',
+ 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
+ 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
+ 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b',
+ 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
+ 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
+ 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
+};
+
+char * l64a (long int n)
+{
+ unsigned long int m = (unsigned long int) n;
+ static char result[7];
+ char *p;
+
+ /* The standard says that only 32 bits are used. */
+ if (sizeof(m) != 4)
+ m &= 0xffffffff;
+
+ /* The value for N == 0 is defined to be the empty string,
+ * this code provides that as well. */
+ p = result;
+ while (m)
+ {
+ *p++ = conv_table[m & 0x3f];
+ m >>= 6;
+ }
+ *p = '\0';
+
+ return result;
+}
diff --git a/ap/build/uClibc/libc/stdlib/labs.c b/ap/build/uClibc/libc/stdlib/labs.c
new file mode 100644
index 0000000..95196af
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/labs.c
@@ -0,0 +1,7 @@
+/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_labs
+#include "stdlib.c"
diff --git a/ap/build/uClibc/libc/stdlib/ldiv.c b/ap/build/uClibc/libc/stdlib/ldiv.c
new file mode 100644
index 0000000..88a8771
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/ldiv.c
@@ -0,0 +1,61 @@
+
+/* Copyright (C) 1992, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <features.h>
+#include <stdlib.h>
+
+
+/* Return the `ldiv_t' representation of NUMER over DENOM. */
+ldiv_t
+ldiv (long int numer, long int denom)
+{
+ ldiv_t result;
+
+ result.quot = numer / denom;
+ result.rem = numer % denom;
+
+ /* The ANSI standard says that |QUOT| <= |NUMER / DENOM|, where
+ NUMER / DENOM is to be computed in infinite precision. In
+ other words, we should always truncate the quotient towards
+ zero, never -infinity. Machine division and remainer may
+ work either way when one or both of NUMER or DENOM is
+ negative. If only one is negative and QUOT has been
+ truncated towards -infinity, REM will have the same sign as
+ DENOM and the opposite sign of NUMER; if both are negative
+ and QUOT has been truncated towards -infinity, REM will be
+ positive (will have the opposite sign of NUMER). These are
+ considered `wrong'. If both are NUM and DENOM are positive,
+ RESULT will always be positive. This all boils down to: if
+ NUMER >= 0, but REM < 0, we got the wrong answer. In that
+ case, to get the right answer, add 1 to QUOT and subtract
+ DENOM from REM. */
+
+ if (numer >= 0 && result.rem < 0)
+ {
+ ++result.quot;
+ result.rem -= denom;
+ }
+
+ return result;
+}
+
+#if __WORDSIZE == 64
+#undef imaxdiv
+strong_alias(ldiv,imaxdiv)
+#endif
diff --git a/ap/build/uClibc/libc/stdlib/llabs.c b/ap/build/uClibc/libc/stdlib/llabs.c
new file mode 100644
index 0000000..17ec30a
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/llabs.c
@@ -0,0 +1,7 @@
+/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_llabs
+#include "stdlib.c"
diff --git a/ap/build/uClibc/libc/stdlib/lldiv.c b/ap/build/uClibc/libc/stdlib/lldiv.c
new file mode 100644
index 0000000..ff67017
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/lldiv.c
@@ -0,0 +1,61 @@
+/* `long long int' divison with remainder.
+ Copyright (C) 1992, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <features.h>
+#include <stdlib.h>
+
+
+/* Return the `lldiv_t' representation of NUMER over DENOM. */
+lldiv_t
+lldiv (long long int numer, long long int denom)
+{
+ lldiv_t result;
+
+ result.quot = numer / denom;
+ result.rem = numer % denom;
+
+ /* The ANSI standard says that |QUOT| <= |NUMER / DENOM|, where
+ NUMER / DENOM is to be computed in infinite precision. In
+ other words, we should always truncate the quotient towards
+ zero, never -infinity. Machine division and remainer may
+ work either way when one or both of NUMER or DENOM is
+ negative. If only one is negative and QUOT has been
+ truncated towards -infinity, REM will have the same sign as
+ DENOM and the opposite sign of NUMER; if both are negative
+ and QUOT has been truncated towards -infinity, REM will be
+ positive (will have the opposite sign of NUMER). These are
+ considered `wrong'. If both are NUM and DENOM are positive,
+ RESULT will always be positive. This all boils down to: if
+ NUMER >= 0, but REM < 0, we got the wrong answer. In that
+ case, to get the right answer, add 1 to QUOT and subtract
+ DENOM from REM. */
+
+ if (numer >= 0 && result.rem < 0)
+ {
+ ++result.quot;
+ result.rem -= denom;
+ }
+
+ return result;
+}
+
+#if __WORDSIZE != 64
+#undef imaxdiv
+strong_alias(lldiv,imaxdiv)
+#endif
diff --git a/ap/build/uClibc/libc/stdlib/lrand48.c b/ap/build/uClibc/libc/stdlib/lrand48.c
new file mode 100644
index 0000000..915638b
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/lrand48.c
@@ -0,0 +1,29 @@
+/* Copyright (C) 1995, 1996, 1997, 1998, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu <mailto:drepper@gnu.ai.mit.edu>>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdlib.h>
+
+long int lrand48 (void)
+{
+ long int result;
+
+ nrand48_r (__libc_drand48_data.__x, &__libc_drand48_data, &result);
+
+ return result;
+}
diff --git a/ap/build/uClibc/libc/stdlib/lrand48_r.c b/ap/build/uClibc/libc/stdlib/lrand48_r.c
new file mode 100644
index 0000000..5a425d1
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/lrand48_r.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 1995, 1997, 1998, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu <mailto:drepper@gnu.ai.mit.edu>>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdlib.h>
+
+
+int lrand48_r (struct drand48_data *buffer, long int *result)
+{
+ /* Be generous for the arguments, detect some errors. */
+ if (buffer == NULL)
+ return -1;
+
+ return nrand48_r (buffer->__x, buffer, result);
+}
+libc_hidden_def(lrand48_r)
diff --git a/ap/build/uClibc/libc/stdlib/malloc-simple/Makefile b/ap/build/uClibc/libc/stdlib/malloc-simple/Makefile
new file mode 100644
index 0000000..4a8f4a0
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/malloc-simple/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-simple/Makefile.in b/ap/build/uClibc/libc/stdlib/malloc-simple/Makefile.in
new file mode 100644
index 0000000..351504b
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/malloc-simple/Makefile.in
@@ -0,0 +1,24 @@
+# Makefile for uClibc
+#
+# 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-simple
+
+STDLIB_MALLOC_SIMPLE_DIR := $(top_srcdir)libc/stdlib/malloc-simple
+STDLIB_MALLOC_SIMPLE_OUT := $(top_builddir)libc/stdlib/malloc-simple
+
+CSRC := $(notdir $(wildcard $(STDLIB_MALLOC_SIMPLE_DIR)/*.c))
+CSRC := $(filter-out alloc.c,$(CSRC))
+
+STDLIB_MALLOC_SIMPLE_SRC := $(patsubst %.c,$(STDLIB_MALLOC_SIMPLE_DIR)/%.c,$(CSRC))
+STDLIB_MALLOC_SIMPLE_OBJ := $(patsubst %.c,$(STDLIB_MALLOC_SIMPLE_OUT)/%.o,$(CSRC))
+
+libc-$(MALLOC_SIMPLE) += $(STDLIB_MALLOC_SIMPLE_OBJ)
+
+objclean-y += CLEAN_libc/stdlib/malloc-simple
+
+CLEAN_libc/stdlib/malloc-simple:
+ $(do_rm) $(addprefix $(STDLIB_MALLOC_SIMPLE_OUT)/*., o os)
diff --git a/ap/build/uClibc/libc/stdlib/malloc-simple/alloc.c b/ap/build/uClibc/libc/stdlib/malloc-simple/alloc.c
new file mode 100644
index 0000000..914c89d
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/malloc-simple/alloc.c
@@ -0,0 +1,185 @@
+/* alloc.c
+ *
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+/*
+ * Parts of the memalign code were stolen from malloc-930716.
+ */
+
+#include <features.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <malloc.h>
+
+
+#ifdef L_malloc
+void *malloc(size_t size)
+{
+ void *result;
+
+ if (unlikely(size == 0)) {
+#if defined(__MALLOC_GLIBC_COMPAT__)
+ size++;
+#else
+ /* Some programs will call malloc (0). Lets be strict and return NULL */
+ __set_errno(ENOMEM);
+ return NULL;
+#endif
+ }
+
+#ifdef __ARCH_USE_MMU__
+# define MMAP_FLAGS MAP_PRIVATE | MAP_ANONYMOUS
+#else
+# define MMAP_FLAGS MAP_SHARED | MAP_ANONYMOUS | MAP_UNINITIALIZE
+#endif
+
+ result = mmap((void *) 0, size + sizeof(size_t), PROT_READ | PROT_WRITE,
+ MMAP_FLAGS, 0, 0);
+ if (result == MAP_FAILED)
+ return 0;
+ * (size_t *) result = size;
+ return(result + sizeof(size_t));
+}
+#endif
+
+#ifdef L_calloc
+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;
+ }
+ result = malloc(size);
+
+#ifndef __ARCH_USE_MMU__
+ /* mmap'd with MAP_UNINITIALIZE, we have to blank memory ourselves */
+ if (result != NULL) {
+ memset(result, 0, size);
+ }
+#endif
+ return result;
+}
+#endif
+
+#ifdef L_realloc
+void *realloc(void *ptr, size_t size)
+{
+ void *newptr = NULL;
+
+ if (!ptr)
+ return malloc(size);
+ if (!size) {
+ free(ptr);
+ return malloc(0);
+ }
+
+ newptr = malloc(size);
+ if (newptr) {
+ size_t old_size = *((size_t *) (ptr - sizeof(size_t)));
+ memcpy(newptr, ptr, (old_size < size ? old_size : size));
+ free(ptr);
+ }
+ return newptr;
+}
+#endif
+
+#ifdef L_free
+extern int weak_function __libc_free_aligned(void *ptr);
+void free(void *ptr)
+{
+ if (unlikely(ptr == NULL))
+ return;
+ if (unlikely(__libc_free_aligned != NULL)) {
+ if (__libc_free_aligned(ptr))
+ return;
+ }
+ ptr -= sizeof(size_t);
+ munmap(ptr, * (size_t *) ptr + sizeof(size_t));
+}
+#endif
+
+#ifdef L_memalign
+
+#include <bits/uClibc_mutex.h>
+__UCLIBC_MUTEX_INIT(__malloc_lock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);
+#define __MALLOC_LOCK __UCLIBC_MUTEX_LOCK(__malloc_lock)
+#define __MALLOC_UNLOCK __UCLIBC_MUTEX_UNLOCK(__malloc_lock)
+
+/* List of blocks allocated with memalign or valloc */
+struct alignlist
+{
+ struct alignlist *next;
+ __ptr_t aligned; /* The address that memaligned returned. */
+ __ptr_t exact; /* The address that malloc returned. */
+};
+struct alignlist *_aligned_blocks;
+
+/* Return memory to the heap. */
+int __libc_free_aligned(void *ptr)
+{
+ struct alignlist *l;
+
+ if (ptr == NULL)
+ return 0;
+
+ __MALLOC_LOCK;
+ for (l = _aligned_blocks; l != NULL; l = l->next) {
+ if (l->aligned == ptr) {
+ /* Mark the block as free */
+ l->aligned = NULL;
+ ptr = l->exact;
+ ptr -= sizeof(size_t);
+ munmap(ptr, * (size_t *) ptr + sizeof(size_t));
+ return 1;
+ }
+ }
+ __MALLOC_UNLOCK;
+ return 0;
+}
+void * memalign (size_t alignment, size_t size)
+{
+ void * result;
+ unsigned long int adj;
+
+ result = malloc (size + alignment - 1);
+ if (result == NULL)
+ return NULL;
+
+ adj = (unsigned long int) ((unsigned long int) ((char *) result - (char *) NULL)) % alignment;
+ if (adj != 0) {
+ struct alignlist *l;
+ __MALLOC_LOCK;
+ for (l = _aligned_blocks; l != NULL; l = l->next)
+ if (l->aligned == NULL)
+ /* This slot is free. Use it. */
+ break;
+ if (l == NULL) {
+ l = (struct alignlist *) malloc (sizeof (struct alignlist));
+ if (l == NULL) {
+ free(result);
+ result = NULL;
+ goto DONE;
+ }
+ l->next = _aligned_blocks;
+ _aligned_blocks = l;
+ }
+ l->exact = result;
+ result = l->aligned = (char *) result + alignment - adj;
+DONE:
+ __MALLOC_UNLOCK;
+ }
+
+ return result;
+}
+#endif
diff --git a/ap/build/uClibc/libc/stdlib/malloc-simple/calloc.c b/ap/build/uClibc/libc/stdlib/malloc-simple/calloc.c
new file mode 100644
index 0000000..b404896
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/malloc-simple/calloc.c
@@ -0,0 +1,8 @@
+/*
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_calloc
+#include "alloc.c"
diff --git a/ap/build/uClibc/libc/stdlib/malloc-simple/free.c b/ap/build/uClibc/libc/stdlib/malloc-simple/free.c
new file mode 100644
index 0000000..3fc7a96
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/malloc-simple/free.c
@@ -0,0 +1,8 @@
+/*
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_free
+#include "alloc.c"
diff --git a/ap/build/uClibc/libc/stdlib/malloc-simple/malloc.c b/ap/build/uClibc/libc/stdlib/malloc-simple/malloc.c
new file mode 100644
index 0000000..1ad8ca2
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/malloc-simple/malloc.c
@@ -0,0 +1,8 @@
+/*
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_malloc
+#include "alloc.c"
diff --git a/ap/build/uClibc/libc/stdlib/malloc-simple/memalign.c b/ap/build/uClibc/libc/stdlib/malloc-simple/memalign.c
new file mode 100644
index 0000000..d7ee352
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/malloc-simple/memalign.c
@@ -0,0 +1,8 @@
+/*
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_memalign
+#include "alloc.c"
diff --git a/ap/build/uClibc/libc/stdlib/malloc-simple/realloc.c b/ap/build/uClibc/libc/stdlib/malloc-simple/realloc.c
new file mode 100644
index 0000000..b116ab1
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/malloc-simple/realloc.c
@@ -0,0 +1,8 @@
+/*
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_realloc
+#include "alloc.c"
diff --git a/ap/build/uClibc/libc/stdlib/malloc-standard/Makefile b/ap/build/uClibc/libc/stdlib/malloc-standard/Makefile
new file mode 100644
index 0000000..4a8f4a0
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/malloc-standard/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-standard/Makefile.in b/ap/build/uClibc/libc/stdlib/malloc-standard/Makefile.in
new file mode 100644
index 0000000..7da7fe1
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/malloc-standard/Makefile.in
@@ -0,0 +1,25 @@
+# Makefile for uClibc
+#
+# 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-standard
+
+# calloc.c can be found at uClibc/libc/stdlib/calloc.c
+# valloc.c can be found at uClibc/libc/stdlib/valloc.c
+CSRC := malloc.c calloc.c realloc.c free.c memalign.c mallopt.c mallinfo.c
+
+STDLIB_MALLOC_STANDARD_DIR := $(top_srcdir)libc/stdlib/malloc-standard
+STDLIB_MALLOC_STANDARD_OUT := $(top_builddir)libc/stdlib/malloc-standard
+
+STDLIB_MALLOC_STANDARD_SRC := $(patsubst %.c,$(STDLIB_MALLOC_STANDARD_DIR)/%.c,$(CSRC))
+STDLIB_MALLOC_STANDARD_OBJ := $(patsubst %.c,$(STDLIB_MALLOC_STANDARD_OUT)/%.o,$(CSRC))
+
+libc-$(MALLOC_STANDARD) += $(STDLIB_MALLOC_STANDARD_OBJ)
+
+objclean-y += CLEAN_libc/stdlib/malloc-standard
+
+CLEAN_libc/stdlib/malloc-standard:
+ $(do_rm) $(addprefix $(STDLIB_MALLOC_STANDARD_OUT)/*., o os)
diff --git a/ap/build/uClibc/libc/stdlib/malloc-standard/calloc.c b/ap/build/uClibc/libc/stdlib/malloc-standard/calloc.c
new file mode 100644
index 0000000..a70516f
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/malloc-standard/calloc.c
@@ -0,0 +1,93 @@
+/*
+ This is a version (aka dlmalloc) of malloc/free/realloc written by
+ Doug Lea and released to the public domain. Use, modify, and
+ redistribute this code without permission or acknowledgement in any
+ way you wish. Send questions, comments, complaints, performance
+ data, etc to dl@cs.oswego.edu
+
+ VERSION 2.7.2 Sat Aug 17 09:07:30 2002 Doug Lea (dl at gee)
+
+ Note: There may be an updated version of this malloc obtainable at
+ ftp://gee.cs.oswego.edu/pub/misc/malloc.c
+ Check before installing!
+
+ Hacked up for uClibc by Erik Andersen <andersen@codepoet.org>
+*/
+
+#include "malloc.h"
+
+
+/* ------------------------------ calloc ------------------------------ */
+void* calloc(size_t n_elements, size_t elem_size)
+{
+ mchunkptr p;
+ unsigned long clearsize;
+ unsigned long nclears;
+ size_t size, *d;
+ void* mem;
+
+
+ /* guard vs integer overflow, but allow nmemb
+ * to fall through and call malloc(0) */
+ size = n_elements * elem_size;
+ if (n_elements && elem_size != (size / n_elements)) {
+ __set_errno(ENOMEM);
+ return NULL;
+ }
+
+ __MALLOC_LOCK;
+ mem = malloc(size);
+ if (mem != 0) {
+ p = mem2chunk(mem);
+
+ if (!chunk_is_mmapped(p))
+ {
+ /*
+ Unroll clear of <= 36 bytes (72 if 8byte sizes)
+ We know that contents have an odd number of
+ size_t-sized words; minimally 3.
+ */
+
+ d = (size_t*)mem;
+ clearsize = chunksize(p) - (sizeof(size_t));
+ nclears = clearsize / sizeof(size_t);
+ assert(nclears >= 3);
+
+ if (nclears > 9)
+ memset(d, 0, clearsize);
+
+ else {
+ *(d+0) = 0;
+ *(d+1) = 0;
+ *(d+2) = 0;
+ if (nclears > 4) {
+ *(d+3) = 0;
+ *(d+4) = 0;
+ if (nclears > 6) {
+ *(d+5) = 0;
+ *(d+6) = 0;
+ if (nclears > 8) {
+ *(d+7) = 0;
+ *(d+8) = 0;
+ }
+ }
+ }
+ }
+ }
+#if 0
+ else
+ {
+ /* Standard unix mmap using /dev/zero clears memory so calloc
+ * doesn't need to actually zero anything....
+ */
+ d = (size_t*)mem;
+ /* Note the additional (sizeof(size_t)) */
+ clearsize = chunksize(p) - 2*(sizeof(size_t));
+ memset(d, 0, clearsize);
+ }
+#endif
+ }
+ __MALLOC_UNLOCK;
+ return mem;
+}
+
diff --git a/ap/build/uClibc/libc/stdlib/malloc-standard/free.c b/ap/build/uClibc/libc/stdlib/malloc-standard/free.c
new file mode 100644
index 0000000..39e54d6
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/malloc-standard/free.c
@@ -0,0 +1,410 @@
+/*
+ This is a version (aka dlmalloc) of malloc/free/realloc written by
+ Doug Lea and released to the public domain. Use, modify, and
+ redistribute this code without permission or acknowledgement in any
+ way you wish. Send questions, comments, complaints, performance
+ data, etc to dl@cs.oswego.edu
+
+ VERSION 2.7.2 Sat Aug 17 09:07:30 2002 Doug Lea (dl at gee)
+
+ Note: There may be an updated version of this malloc obtainable at
+ ftp://gee.cs.oswego.edu/pub/misc/malloc.c
+ Check before installing!
+
+ Hacked up for uClibc by Erik Andersen <andersen@codepoet.org>
+*/
+
+#include "malloc.h"
+
+
+/* ------------------------- __malloc_trim -------------------------
+ __malloc_trim is an inverse of sorts to __malloc_alloc. It gives memory
+ back to the system (via negative arguments to sbrk) if there is unused
+ memory at the `high' end of the malloc pool. It is called automatically by
+ free() when top space exceeds the trim threshold. It is also called by the
+ public malloc_trim routine. It returns 1 if it actually released any
+ memory, else 0.
+*/
+static int __malloc_trim(size_t pad, mstate av)
+{
+ long top_size; /* Amount of top-most memory */
+ long extra; /* Amount to release */
+ long released; /* Amount actually released */
+ char* current_brk; /* address returned by pre-check sbrk call */
+ char* new_brk; /* address returned by post-check sbrk call */
+ size_t pagesz;
+
+ pagesz = av->pagesize;
+ top_size = chunksize(av->top);
+
+ /* Release in pagesize units, keeping at least one page */
+ extra = ((top_size - pad - MINSIZE + (pagesz-1)) / pagesz - 1) * pagesz;
+
+ if (extra > 0) {
+
+ /*
+ Only proceed if end of memory is where we last set it.
+ This avoids problems if there were foreign sbrk calls.
+ */
+ current_brk = (char*)(MORECORE(0));
+ if (current_brk == (char*)(av->top) + top_size) {
+
+ /*
+ Attempt to release memory. We ignore MORECORE return value,
+ and instead call again to find out where new end of memory is.
+ This avoids problems if first call releases less than we asked,
+ of if failure somehow altered brk value. (We could still
+ encounter problems if it altered brk in some very bad way,
+ but the only thing we can do is adjust anyway, which will cause
+ some downstream failure.)
+ */
+
+ MORECORE(-extra);
+ new_brk = (char*)(MORECORE(0));
+
+ if (new_brk != (char*)MORECORE_FAILURE) {
+ released = (long)(current_brk - new_brk);
+
+ if (released != 0) {
+ /* Success. Adjust top. */
+ av->sbrked_mem -= released;
+ set_head(av->top, (top_size - released) | PREV_INUSE);
+ check_malloc_state();
+ return 1;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+/* ------------------------- malloc_trim -------------------------
+ malloc_trim(size_t pad);
+
+ If possible, gives memory back to the system (via negative
+ arguments to sbrk) if there is unused memory at the `high' end of
+ the malloc pool. You can call this after freeing large blocks of
+ memory to potentially reduce the system-level memory requirements
+ of a program. However, it cannot guarantee to reduce memory. Under
+ some allocation patterns, some large free blocks of memory will be
+ locked between two used chunks, so they cannot be given back to
+ the system.
+
+ The `pad' argument to malloc_trim represents the amount of free
+ trailing space to leave untrimmed. If this argument is zero,
+ only the minimum amount of memory to maintain internal data
+ structures will be left (one page or less). Non-zero arguments
+ can be supplied to maintain enough trailing space to service
+ future expected allocations without having to re-obtain memory
+ from the system.
+
+ Malloc_trim returns 1 if it actually released any memory, else 0.
+ On systems that do not support "negative sbrks", it will always
+ return 0.
+*/
+int malloc_trim(size_t pad)
+{
+ mstate av = get_malloc_state();
+ __malloc_consolidate(av);
+ return __malloc_trim(pad, av);
+}
+
+/*
+ Initialize a malloc_state struct.
+
+ This is called only from within __malloc_consolidate, which needs
+ be called in the same contexts anyway. It is never called directly
+ outside of __malloc_consolidate because some optimizing compilers try
+ to inline it at all call points, which turns out not to be an
+ optimization at all. (Inlining it in __malloc_consolidate is fine though.)
+*/
+static void malloc_init_state(mstate av)
+{
+ int i;
+ mbinptr bin;
+
+ /* Establish circular links for normal bins */
+ for (i = 1; i < NBINS; ++i) {
+ bin = bin_at(av,i);
+ bin->fd = bin->bk = bin;
+ }
+
+ av->top_pad = DEFAULT_TOP_PAD;
+ av->n_mmaps_max = DEFAULT_MMAP_MAX;
+ av->mmap_threshold = DEFAULT_MMAP_THRESHOLD;
+ av->trim_threshold = DEFAULT_TRIM_THRESHOLD;
+
+#if MORECORE_CONTIGUOUS
+ set_contiguous(av);
+#else
+ set_noncontiguous(av);
+#endif
+
+
+ set_max_fast(av, DEFAULT_MXFAST);
+
+ av->top = initial_top(av);
+ av->pagesize = malloc_getpagesize;
+}
+
+
+/* ----------------------------------------------------------------------
+ *
+ * PUBLIC STUFF
+ *
+ * ----------------------------------------------------------------------*/
+
+
+/* ------------------------- __malloc_consolidate -------------------------
+
+ __malloc_consolidate is a specialized version of free() that tears
+ down chunks held in fastbins. Free itself cannot be used for this
+ purpose since, among other things, it might place chunks back onto
+ fastbins. So, instead, we need to use a minor variant of the same
+ code.
+
+ Also, because this routine needs to be called the first time through
+ malloc anyway, it turns out to be the perfect place to trigger
+ initialization code.
+*/
+void attribute_hidden __malloc_consolidate(mstate av)
+{
+ mfastbinptr* fb; /* current fastbin being consolidated */
+ mfastbinptr* maxfb; /* last fastbin (for loop control) */
+ mchunkptr p; /* current chunk being consolidated */
+ mchunkptr nextp; /* next chunk to consolidate */
+ mchunkptr unsorted_bin; /* bin header */
+ mchunkptr first_unsorted; /* chunk to link to */
+
+ /* These have same use as in free() */
+ mchunkptr nextchunk;
+ size_t size;
+ size_t nextsize;
+ size_t prevsize;
+ int nextinuse;
+ mchunkptr bck;
+ mchunkptr fwd;
+
+ /*
+ If max_fast is 0, we know that av hasn't
+ yet been initialized, in which case do so below
+ */
+
+ if (av->max_fast != 0) {
+ clear_fastchunks(av);
+
+ unsorted_bin = unsorted_chunks(av);
+
+ /*
+ Remove each chunk from fast bin and consolidate it, placing it
+ then in unsorted bin. Among other reasons for doing this,
+ placing in unsorted bin avoids needing to calculate actual bins
+ until malloc is sure that chunks aren't immediately going to be
+ reused anyway.
+ */
+
+ maxfb = &(av->fastbins[fastbin_index(av->max_fast)]);
+ fb = &(av->fastbins[0]);
+ do {
+ if ( (p = *fb) != 0) {
+ *fb = 0;
+
+ do {
+ check_inuse_chunk(p);
+ nextp = p->fd;
+
+ /* Slightly streamlined version of consolidation code in free() */
+ size = p->size & ~PREV_INUSE;
+ nextchunk = chunk_at_offset(p, size);
+ nextsize = chunksize(nextchunk);
+
+ if (!prev_inuse(p)) {
+ prevsize = p->prev_size;
+ size += prevsize;
+ p = chunk_at_offset(p, -((long) prevsize));
+ unlink(p, bck, fwd);
+ }
+
+ if (nextchunk != av->top) {
+ nextinuse = inuse_bit_at_offset(nextchunk, nextsize);
+ set_head(nextchunk, nextsize);
+
+ if (!nextinuse) {
+ size += nextsize;
+ unlink(nextchunk, bck, fwd);
+ }
+
+ first_unsorted = unsorted_bin->fd;
+ unsorted_bin->fd = p;
+ first_unsorted->bk = p;
+
+ set_head(p, size | PREV_INUSE);
+ p->bk = unsorted_bin;
+ p->fd = first_unsorted;
+ set_foot(p, size);
+ }
+
+ else {
+ size += nextsize;
+ set_head(p, size | PREV_INUSE);
+ av->top = p;
+ }
+
+ } while ( (p = nextp) != 0);
+
+ }
+ } while (fb++ != maxfb);
+ }
+ else {
+ malloc_init_state(av);
+ check_malloc_state();
+ }
+}
+
+
+/* ------------------------------ free ------------------------------ */
+void free(void* mem)
+{
+ mstate av;
+
+ mchunkptr p; /* chunk corresponding to mem */
+ size_t size; /* its size */
+ mfastbinptr* fb; /* associated fastbin */
+ mchunkptr nextchunk; /* next contiguous chunk */
+ size_t nextsize; /* its size */
+ int nextinuse; /* true if nextchunk is used */
+ size_t prevsize; /* size of previous contiguous chunk */
+ mchunkptr bck; /* misc temp for linking */
+ mchunkptr fwd; /* misc temp for linking */
+
+ /* free(0) has no effect */
+ if (mem == NULL)
+ return;
+
+ __MALLOC_LOCK;
+ av = get_malloc_state();
+ p = mem2chunk(mem);
+ size = chunksize(p);
+
+ check_inuse_chunk(p);
+
+ /*
+ If eligible, place chunk on a fastbin so it can be found
+ and used quickly in malloc.
+ */
+
+ if ((unsigned long)(size) <= (unsigned long)(av->max_fast)
+
+#if TRIM_FASTBINS
+ /* If TRIM_FASTBINS set, don't place chunks
+ bordering top into fastbins */
+ && (chunk_at_offset(p, size) != av->top)
+#endif
+ ) {
+
+ set_fastchunks(av);
+ fb = &(av->fastbins[fastbin_index(size)]);
+ p->fd = *fb;
+ *fb = p;
+ }
+
+ /*
+ Consolidate other non-mmapped chunks as they arrive.
+ */
+
+ else if (!chunk_is_mmapped(p)) {
+ set_anychunks(av);
+
+ nextchunk = chunk_at_offset(p, size);
+ nextsize = chunksize(nextchunk);
+
+ /* consolidate backward */
+ if (!prev_inuse(p)) {
+ prevsize = p->prev_size;
+ size += prevsize;
+ p = chunk_at_offset(p, -((long) prevsize));
+ unlink(p, bck, fwd);
+ }
+
+ if (nextchunk != av->top) {
+ /* get and clear inuse bit */
+ nextinuse = inuse_bit_at_offset(nextchunk, nextsize);
+ set_head(nextchunk, nextsize);
+
+ /* consolidate forward */
+ if (!nextinuse) {
+ unlink(nextchunk, bck, fwd);
+ size += nextsize;
+ }
+
+ /*
+ Place the chunk in unsorted chunk list. Chunks are
+ not placed into regular bins until after they have
+ been given one chance to be used in malloc.
+ */
+
+ bck = unsorted_chunks(av);
+ fwd = bck->fd;
+ p->bk = bck;
+ p->fd = fwd;
+ bck->fd = p;
+ fwd->bk = p;
+
+ set_head(p, size | PREV_INUSE);
+ set_foot(p, size);
+
+ check_free_chunk(p);
+ }
+
+ /*
+ If the chunk borders the current high end of memory,
+ consolidate into top
+ */
+
+ else {
+ size += nextsize;
+ set_head(p, size | PREV_INUSE);
+ av->top = p;
+ check_chunk(p);
+ }
+
+ /*
+ If freeing a large space, consolidate possibly-surrounding
+ chunks. Then, if the total unused topmost memory exceeds trim
+ threshold, ask malloc_trim to reduce top.
+
+ Unless max_fast is 0, we don't know if there are fastbins
+ bordering top, so we cannot tell for sure whether threshold
+ has been reached unless fastbins are consolidated. But we
+ don't want to consolidate on each free. As a compromise,
+ consolidation is performed if FASTBIN_CONSOLIDATION_THRESHOLD
+ is reached.
+ */
+
+ if ((unsigned long)(size) >= FASTBIN_CONSOLIDATION_THRESHOLD) {
+ if (have_fastchunks(av))
+ __malloc_consolidate(av);
+
+ if ((unsigned long)(chunksize(av->top)) >=
+ (unsigned long)(av->trim_threshold))
+ __malloc_trim(av->top_pad, av);
+ }
+
+ }
+ /*
+ If the chunk was allocated via mmap, release via munmap()
+ Note that if HAVE_MMAP is false but chunk_is_mmapped is
+ true, then user must have overwritten memory. There's nothing
+ we can do to catch this error unless DEBUG is set, in which case
+ check_inuse_chunk (above) will have triggered error.
+ */
+
+ else {
+ size_t offset = p->prev_size;
+ av->n_mmaps--;
+ av->mmapped_mem -= (size + offset);
+ munmap((char*)p - offset, size + offset);
+ }
+ __MALLOC_UNLOCK;
+}
+
diff --git a/ap/build/uClibc/libc/stdlib/malloc-standard/mallinfo.c b/ap/build/uClibc/libc/stdlib/malloc-standard/mallinfo.c
new file mode 100644
index 0000000..d60d6d9
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/malloc-standard/mallinfo.c
@@ -0,0 +1,124 @@
+/*
+ This is a version (aka dlmalloc) of malloc/free/realloc written by
+ Doug Lea and released to the public domain. Use, modify, and
+ redistribute this code without permission or acknowledgement in any
+ way you wish. Send questions, comments, complaints, performance
+ data, etc to dl@cs.oswego.edu
+
+ VERSION 2.7.2 Sat Aug 17 09:07:30 2002 Doug Lea (dl at gee)
+
+ Note: There may be an updated version of this malloc obtainable at
+ ftp://gee.cs.oswego.edu/pub/misc/malloc.c
+ Check before installing!
+
+ Hacked up for uClibc by Erik Andersen <andersen@codepoet.org>
+*/
+
+#include "malloc.h"
+
+
+/* ------------------------------ mallinfo ------------------------------ */
+struct mallinfo mallinfo(void)
+{
+ mstate av;
+ struct mallinfo mi;
+ unsigned int i;
+ mbinptr b;
+ mchunkptr p;
+ size_t avail;
+ size_t fastavail;
+ int nblocks;
+ int nfastblocks;
+
+ __MALLOC_LOCK;
+ av = get_malloc_state();
+ /* Ensure initialization */
+ if (av->top == 0) {
+ __malloc_consolidate(av);
+ }
+
+ check_malloc_state();
+
+ /* Account for top */
+ avail = chunksize(av->top);
+ nblocks = 1; /* top always exists */
+
+ /* traverse fastbins */
+ nfastblocks = 0;
+ fastavail = 0;
+
+ for (i = 0; i < NFASTBINS; ++i) {
+ for (p = av->fastbins[i]; p != 0; p = p->fd) {
+ ++nfastblocks;
+ fastavail += chunksize(p);
+ }
+ }
+
+ avail += fastavail;
+
+ /* traverse regular bins */
+ for (i = 1; i < NBINS; ++i) {
+ b = bin_at(av, i);
+ for (p = last(b); p != b; p = p->bk) {
+ ++nblocks;
+ avail += chunksize(p);
+ }
+ }
+
+ mi.smblks = nfastblocks;
+ mi.ordblks = nblocks;
+ mi.fordblks = avail;
+ mi.uordblks = av->sbrked_mem - avail;
+ mi.arena = av->sbrked_mem;
+ mi.hblks = av->n_mmaps;
+ mi.hblkhd = av->mmapped_mem;
+ mi.fsmblks = fastavail;
+ mi.keepcost = chunksize(av->top);
+ mi.usmblks = av->max_total_mem;
+ __MALLOC_UNLOCK;
+ return mi;
+}
+libc_hidden_def(mallinfo)
+
+void malloc_stats(FILE *file)
+{
+ struct mallinfo mi;
+
+ if (file==NULL) {
+ file = stderr;
+ }
+
+ mi = mallinfo();
+ fprintf(file,
+ "total bytes allocated = %10u\n"
+ "total bytes in use bytes = %10u\n"
+ "total non-mmapped bytes allocated = %10d\n"
+ "number of mmapped regions = %10d\n"
+ "total allocated mmap space = %10d\n"
+ "total allocated sbrk space = %10d\n"
+#if 0
+ "number of free chunks = %10d\n"
+ "number of fastbin blocks = %10d\n"
+ "space in freed fastbin blocks = %10d\n"
+#endif
+ "maximum total allocated space = %10d\n"
+ "total free space = %10d\n"
+ "memory releasable via malloc_trim = %10d\n",
+
+ (unsigned int)(mi.arena + mi.hblkhd),
+ (unsigned int)(mi.uordblks + mi.hblkhd),
+ mi.arena,
+ mi.hblks,
+ mi.hblkhd,
+ mi.uordblks,
+#if 0
+ mi.ordblks,
+ mi.smblks,
+ mi.fsmblks,
+#endif
+ mi.usmblks,
+ mi.fordblks,
+ mi.keepcost
+ );
+}
+
diff --git a/ap/build/uClibc/libc/stdlib/malloc-standard/malloc.c b/ap/build/uClibc/libc/stdlib/malloc-standard/malloc.c
new file mode 100644
index 0000000..3253ebd
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/malloc-standard/malloc.c
@@ -0,0 +1,1167 @@
+/*
+ This is a version (aka dlmalloc) of malloc/free/realloc written by
+ Doug Lea and released to the public domain. Use, modify, and
+ redistribute this code without permission or acknowledgement in any
+ way you wish. Send questions, comments, complaints, performance
+ data, etc to dl@cs.oswego.edu
+
+ VERSION 2.7.2 Sat Aug 17 09:07:30 2002 Doug Lea (dl at gee)
+
+ Note: There may be an updated version of this malloc obtainable at
+ ftp://gee.cs.oswego.edu/pub/misc/malloc.c
+ Check before installing!
+
+ Hacked up for uClibc by Erik Andersen <andersen@codepoet.org>
+*/
+
+#include "malloc.h"
+
+
+__UCLIBC_MUTEX_INIT(__malloc_lock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);
+
+/*
+ There is exactly one instance of this struct in this malloc.
+ If you are adapting this malloc in a way that does NOT use a static
+ malloc_state, you MUST explicitly zero-fill it before using. This
+ malloc relies on the property that malloc_state is initialized to
+ all zeroes (as is true of C statics).
+*/
+struct malloc_state __malloc_state; /* never directly referenced */
+
+/* forward declaration */
+static int __malloc_largebin_index(unsigned int sz);
+
+#ifdef __UCLIBC_MALLOC_DEBUGGING__
+
+/*
+ Debugging support
+
+ Because freed chunks may be overwritten with bookkeeping fields, this
+ malloc will often die when freed memory is overwritten by user
+ programs. This can be very effective (albeit in an annoying way)
+ in helping track down dangling pointers.
+
+ If you compile with __UCLIBC_MALLOC_DEBUGGING__, a number of assertion checks are
+ enabled that will catch more memory errors. You probably won't be
+ able to make much sense of the actual assertion errors, but they
+ should help you locate incorrectly overwritten memory. The
+ checking is fairly extensive, and will slow down execution
+ noticeably. Calling malloc_stats or mallinfo with __UCLIBC_MALLOC_DEBUGGING__ set will
+ attempt to check every non-mmapped allocated and free chunk in the
+ course of computing the summmaries. (By nature, mmapped regions
+ cannot be checked very much automatically.)
+
+ Setting __UCLIBC_MALLOC_DEBUGGING__ may also be helpful if you are trying to modify
+ this code. The assertions in the check routines spell out in more
+ detail the assumptions and invariants underlying the algorithms.
+
+ Setting __UCLIBC_MALLOC_DEBUGGING__ does NOT provide an automated mechanism for checking
+ that all accesses to malloced memory stay within their
+ bounds. However, there are several add-ons and adaptations of this
+ or other mallocs available that do this.
+*/
+
+/* Properties of all chunks */
+void __do_check_chunk(mchunkptr p)
+{
+ mstate av = get_malloc_state();
+#ifdef __DOASSERTS__
+ /* min and max possible addresses assuming contiguous allocation */
+ char* max_address = (char*)(av->top) + chunksize(av->top);
+ char* min_address = max_address - av->sbrked_mem;
+ unsigned long sz = chunksize(p);
+#endif
+
+ if (!chunk_is_mmapped(p)) {
+
+ /* Has legal address ... */
+ if (p != av->top) {
+ if (contiguous(av)) {
+ assert(((char*)p) >= min_address);
+ assert(((char*)p + sz) <= ((char*)(av->top)));
+ }
+ }
+ else {
+ /* top size is always at least MINSIZE */
+ assert((unsigned long)(sz) >= MINSIZE);
+ /* top predecessor always marked inuse */
+ assert(prev_inuse(p));
+ }
+
+ }
+ else {
+ /* address is outside main heap */
+ if (contiguous(av) && av->top != initial_top(av)) {
+ assert(((char*)p) < min_address || ((char*)p) > max_address);
+ }
+ /* chunk is page-aligned */
+ assert(((p->prev_size + sz) & (av->pagesize-1)) == 0);
+ /* mem is aligned */
+ assert(aligned_OK(chunk2mem(p)));
+ }
+}
+
+/* Properties of free chunks */
+void __do_check_free_chunk(mchunkptr p)
+{
+ size_t sz = p->size & ~PREV_INUSE;
+#ifdef __DOASSERTS__
+ mstate av = get_malloc_state();
+ mchunkptr next = chunk_at_offset(p, sz);
+#endif
+
+ __do_check_chunk(p);
+
+ /* Chunk must claim to be free ... */
+ assert(!inuse(p));
+ assert (!chunk_is_mmapped(p));
+
+ /* Unless a special marker, must have OK fields */
+ if ((unsigned long)(sz) >= MINSIZE)
+ {
+ assert((sz & MALLOC_ALIGN_MASK) == 0);
+ assert(aligned_OK(chunk2mem(p)));
+ /* ... matching footer field */
+ assert(next->prev_size == sz);
+ /* ... and is fully consolidated */
+ assert(prev_inuse(p));
+ assert (next == av->top || inuse(next));
+
+ /* ... and has minimally sane links */
+ assert(p->fd->bk == p);
+ assert(p->bk->fd == p);
+ }
+ else /* markers are always of size (sizeof(size_t)) */
+ assert(sz == (sizeof(size_t)));
+}
+
+/* Properties of inuse chunks */
+void __do_check_inuse_chunk(mchunkptr p)
+{
+ mstate av = get_malloc_state();
+ mchunkptr next;
+ __do_check_chunk(p);
+
+ if (chunk_is_mmapped(p))
+ return; /* mmapped chunks have no next/prev */
+
+ /* Check whether it claims to be in use ... */
+ assert(inuse(p));
+
+ next = next_chunk(p);
+
+ /* ... and is surrounded by OK chunks.
+ Since more things can be checked with free chunks than inuse ones,
+ if an inuse chunk borders them and debug is on, it's worth doing them.
+ */
+ if (!prev_inuse(p)) {
+ /* Note that we cannot even look at prev unless it is not inuse */
+ mchunkptr prv = prev_chunk(p);
+ assert(next_chunk(prv) == p);
+ __do_check_free_chunk(prv);
+ }
+
+ if (next == av->top) {
+ assert(prev_inuse(next));
+ assert(chunksize(next) >= MINSIZE);
+ }
+ else if (!inuse(next))
+ __do_check_free_chunk(next);
+}
+
+/* Properties of chunks recycled from fastbins */
+void __do_check_remalloced_chunk(mchunkptr p, size_t s)
+{
+#ifdef __DOASSERTS__
+ size_t sz = p->size & ~PREV_INUSE;
+#endif
+
+ __do_check_inuse_chunk(p);
+
+ /* Legal size ... */
+ assert((sz & MALLOC_ALIGN_MASK) == 0);
+ assert((unsigned long)(sz) >= MINSIZE);
+ /* ... and alignment */
+ assert(aligned_OK(chunk2mem(p)));
+ /* chunk is less than MINSIZE more than request */
+ assert((long)(sz) - (long)(s) >= 0);
+ assert((long)(sz) - (long)(s + MINSIZE) < 0);
+}
+
+/* Properties of nonrecycled chunks at the point they are malloced */
+void __do_check_malloced_chunk(mchunkptr p, size_t s)
+{
+ /* same as recycled case ... */
+ __do_check_remalloced_chunk(p, s);
+
+ /*
+ ... plus, must obey implementation invariant that prev_inuse is
+ always true of any allocated chunk; i.e., that each allocated
+ chunk borders either a previously allocated and still in-use
+ chunk, or the base of its memory arena. This is ensured
+ by making all allocations from the the `lowest' part of any found
+ chunk. This does not necessarily hold however for chunks
+ recycled via fastbins.
+ */
+
+ assert(prev_inuse(p));
+}
+
+
+/*
+ Properties of malloc_state.
+
+ This may be useful for debugging malloc, as well as detecting user
+ programmer errors that somehow write into malloc_state.
+
+ If you are extending or experimenting with this malloc, you can
+ probably figure out how to hack this routine to print out or
+ display chunk addresses, sizes, bins, and other instrumentation.
+*/
+void __do_check_malloc_state(void)
+{
+ mstate av = get_malloc_state();
+ int i;
+ mchunkptr p;
+ mchunkptr q;
+ mbinptr b;
+ unsigned int binbit;
+ int empty;
+ unsigned int idx;
+ size_t size;
+ unsigned long total = 0;
+ int max_fast_bin;
+
+ /* internal size_t must be no wider than pointer type */
+ assert(sizeof(size_t) <= sizeof(char*));
+
+ /* alignment is a power of 2 */
+ assert((MALLOC_ALIGNMENT & (MALLOC_ALIGNMENT-1)) == 0);
+
+ /* cannot run remaining checks until fully initialized */
+ if (av->top == 0 || av->top == initial_top(av))
+ return;
+
+ /* pagesize is a power of 2 */
+ assert((av->pagesize & (av->pagesize-1)) == 0);
+
+ /* properties of fastbins */
+
+ /* max_fast is in allowed range */
+ assert(get_max_fast(av) <= request2size(MAX_FAST_SIZE));
+
+ max_fast_bin = fastbin_index(av->max_fast);
+
+ for (i = 0; i < NFASTBINS; ++i) {
+ p = av->fastbins[i];
+
+ /* all bins past max_fast are empty */
+ if (i > max_fast_bin)
+ assert(p == 0);
+
+ while (p != 0) {
+ /* each chunk claims to be inuse */
+ __do_check_inuse_chunk(p);
+ total += chunksize(p);
+ /* chunk belongs in this bin */
+ assert(fastbin_index(chunksize(p)) == i);
+ p = p->fd;
+ }
+ }
+
+ if (total != 0)
+ assert(have_fastchunks(av));
+ else if (!have_fastchunks(av))
+ assert(total == 0);
+
+ /* check normal bins */
+ for (i = 1; i < NBINS; ++i) {
+ b = bin_at(av,i);
+
+ /* binmap is accurate (except for bin 1 == unsorted_chunks) */
+ if (i >= 2) {
+ binbit = get_binmap(av,i);
+ empty = last(b) == b;
+ if (!binbit)
+ assert(empty);
+ else if (!empty)
+ assert(binbit);
+ }
+
+ for (p = last(b); p != b; p = p->bk) {
+ /* each chunk claims to be free */
+ __do_check_free_chunk(p);
+ size = chunksize(p);
+ total += size;
+ if (i >= 2) {
+ /* chunk belongs in bin */
+ idx = bin_index(size);
+ assert(idx == i);
+ /* lists are sorted */
+ if ((unsigned long) size >= (unsigned long)(FIRST_SORTED_BIN_SIZE)) {
+ assert(p->bk == b ||
+ (unsigned long)chunksize(p->bk) >=
+ (unsigned long)chunksize(p));
+ }
+ }
+ /* chunk is followed by a legal chain of inuse chunks */
+ for (q = next_chunk(p);
+ (q != av->top && inuse(q) &&
+ (unsigned long)(chunksize(q)) >= MINSIZE);
+ q = next_chunk(q))
+ __do_check_inuse_chunk(q);
+ }
+ }
+
+ /* top chunk is OK */
+ __do_check_chunk(av->top);
+
+ /* sanity checks for statistics */
+
+ assert(total <= (unsigned long)(av->max_total_mem));
+ assert(av->n_mmaps >= 0);
+ assert(av->n_mmaps <= av->max_n_mmaps);
+
+ assert((unsigned long)(av->sbrked_mem) <=
+ (unsigned long)(av->max_sbrked_mem));
+
+ assert((unsigned long)(av->mmapped_mem) <=
+ (unsigned long)(av->max_mmapped_mem));
+
+ assert((unsigned long)(av->max_total_mem) >=
+ (unsigned long)(av->mmapped_mem) + (unsigned long)(av->sbrked_mem));
+}
+#endif
+
+
+/* ----------- Routines dealing with system allocation -------------- */
+
+/*
+ sysmalloc handles malloc cases requiring more memory from the system.
+ On entry, it is assumed that av->top does not have enough
+ space to service request for nb bytes, thus requiring that av->top
+ be extended or replaced.
+*/
+static void* __malloc_alloc(size_t nb, mstate av)
+{
+ mchunkptr old_top; /* incoming value of av->top */
+ size_t old_size; /* its size */
+ char* old_end; /* its end address */
+
+ long size; /* arg to first MORECORE or mmap call */
+ char* fst_brk; /* return value from MORECORE */
+
+ long correction; /* arg to 2nd MORECORE call */
+ char* snd_brk; /* 2nd return val */
+
+ size_t front_misalign; /* unusable bytes at front of new space */
+ size_t end_misalign; /* partial page left at end of new space */
+ char* aligned_brk; /* aligned offset into brk */
+
+ mchunkptr p; /* the allocated/returned chunk */
+ mchunkptr remainder; /* remainder from allocation */
+ unsigned long remainder_size; /* its size */
+
+ unsigned long sum; /* for updating stats */
+
+ size_t pagemask = av->pagesize - 1;
+
+ /*
+ If there is space available in fastbins, consolidate and retry
+ malloc from scratch rather than getting memory from system. This
+ can occur only if nb is in smallbin range so we didn't consolidate
+ upon entry to malloc. It is much easier to handle this case here
+ than in malloc proper.
+ */
+
+ if (have_fastchunks(av)) {
+ assert(in_smallbin_range(nb));
+ __malloc_consolidate(av);
+ return malloc(nb - MALLOC_ALIGN_MASK);
+ }
+
+
+ /*
+ If have mmap, and the request size meets the mmap threshold, and
+ the system supports mmap, and there are few enough currently
+ allocated mmapped regions, try to directly map this request
+ rather than expanding top.
+ */
+
+ if ((unsigned long)(nb) >= (unsigned long)(av->mmap_threshold) &&
+ (av->n_mmaps < av->n_mmaps_max)) {
+
+ char* mm; /* return value from mmap call*/
+
+ /*
+ Round up size to nearest page. For mmapped chunks, the overhead
+ is one (sizeof(size_t)) unit larger than for normal chunks, because there
+ is no following chunk whose prev_size field could be used.
+ */
+ size = (nb + (sizeof(size_t)) + MALLOC_ALIGN_MASK + pagemask) & ~pagemask;
+
+ /* Don't try if size wraps around 0 */
+ if ((unsigned long)(size) > (unsigned long)(nb)) {
+
+ mm = (char*)(MMAP(0, size, PROT_READ|PROT_WRITE));
+
+ if (mm != (char*)(MORECORE_FAILURE)) {
+
+ /*
+ The offset to the start of the mmapped region is stored
+ in the prev_size field of the chunk. This allows us to adjust
+ returned start address to meet alignment requirements here
+ and in memalign(), and still be able to compute proper
+ address argument for later munmap in free() and realloc().
+ */
+
+ front_misalign = (size_t)chunk2mem(mm) & MALLOC_ALIGN_MASK;
+ if (front_misalign > 0) {
+ correction = MALLOC_ALIGNMENT - front_misalign;
+ p = (mchunkptr)(mm + correction);
+ p->prev_size = correction;
+ set_head(p, (size - correction) |IS_MMAPPED);
+ }
+ else {
+ p = (mchunkptr)mm;
+ p->prev_size = 0;
+ set_head(p, size|IS_MMAPPED);
+ }
+
+ /* update statistics */
+
+ if (++av->n_mmaps > av->max_n_mmaps)
+ av->max_n_mmaps = av->n_mmaps;
+
+ sum = av->mmapped_mem += size;
+ if (sum > (unsigned long)(av->max_mmapped_mem))
+ av->max_mmapped_mem = sum;
+ sum += av->sbrked_mem;
+ if (sum > (unsigned long)(av->max_total_mem))
+ av->max_total_mem = sum;
+
+ check_chunk(p);
+
+ return chunk2mem(p);
+ }
+ }
+ }
+
+ /* Record incoming configuration of top */
+
+ old_top = av->top;
+ old_size = chunksize(old_top);
+ old_end = (char*)(chunk_at_offset(old_top, old_size));
+
+ fst_brk = snd_brk = (char*)(MORECORE_FAILURE);
+
+ /* If not the first time through, we require old_size to
+ * be at least MINSIZE and to have prev_inuse set. */
+
+ assert((old_top == initial_top(av) && old_size == 0) ||
+ ((unsigned long) (old_size) >= MINSIZE &&
+ prev_inuse(old_top)));
+
+ /* Precondition: not enough current space to satisfy nb request */
+ assert((unsigned long)(old_size) < (unsigned long)(nb + MINSIZE));
+
+ /* Precondition: all fastbins are consolidated */
+ assert(!have_fastchunks(av));
+
+
+ /* Request enough space for nb + pad + overhead */
+
+ size = nb + av->top_pad + MINSIZE;
+
+ /*
+ If contiguous, we can subtract out existing space that we hope to
+ combine with new space. We add it back later only if
+ we don't actually get contiguous space.
+ */
+
+ if (contiguous(av))
+ size -= old_size;
+
+ /*
+ Round to a multiple of page size.
+ If MORECORE is not contiguous, this ensures that we only call it
+ with whole-page arguments. And if MORECORE is contiguous and
+ this is not first time through, this preserves page-alignment of
+ previous calls. Otherwise, we correct to page-align below.
+ */
+
+ size = (size + pagemask) & ~pagemask;
+
+ /*
+ Don't try to call MORECORE if argument is so big as to appear
+ negative. Note that since mmap takes size_t arg, it may succeed
+ below even if we cannot call MORECORE.
+ */
+
+ if (size > 0)
+ fst_brk = (char*)(MORECORE(size));
+
+ /*
+ If have mmap, try using it as a backup when MORECORE fails or
+ cannot be used. This is worth doing on systems that have "holes" in
+ address space, so sbrk cannot extend to give contiguous space, but
+ space is available elsewhere. Note that we ignore mmap max count
+ and threshold limits, since the space will not be used as a
+ segregated mmap region.
+ */
+
+ if (fst_brk == (char*)(MORECORE_FAILURE)) {
+
+ /* Cannot merge with old top, so add its size back in */
+ if (contiguous(av))
+ size = (size + old_size + pagemask) & ~pagemask;
+
+ /* If we are relying on mmap as backup, then use larger units */
+ if ((unsigned long)(size) < (unsigned long)(MMAP_AS_MORECORE_SIZE))
+ size = MMAP_AS_MORECORE_SIZE;
+
+ /* Don't try if size wraps around 0 */
+ if ((unsigned long)(size) > (unsigned long)(nb)) {
+
+ fst_brk = (char*)(MMAP(0, size, PROT_READ|PROT_WRITE));
+
+ if (fst_brk != (char*)(MORECORE_FAILURE)) {
+
+ /* We do not need, and cannot use, another sbrk call to find end */
+ snd_brk = fst_brk + size;
+
+ /* Record that we no longer have a contiguous sbrk region.
+ After the first time mmap is used as backup, we do not
+ ever rely on contiguous space since this could incorrectly
+ bridge regions.
+ */
+ set_noncontiguous(av);
+ }
+ }
+ }
+
+ if (fst_brk != (char*)(MORECORE_FAILURE)) {
+ av->sbrked_mem += size;
+
+ /*
+ If MORECORE extends previous space, we can likewise extend top size.
+ */
+
+ if (fst_brk == old_end && snd_brk == (char*)(MORECORE_FAILURE)) {
+ set_head(old_top, (size + old_size) | PREV_INUSE);
+ }
+
+ /*
+ Otherwise, make adjustments:
+
+ * If the first time through or noncontiguous, we need to call sbrk
+ just to find out where the end of memory lies.
+
+ * We need to ensure that all returned chunks from malloc will meet
+ MALLOC_ALIGNMENT
+
+ * If there was an intervening foreign sbrk, we need to adjust sbrk
+ request size to account for fact that we will not be able to
+ combine new space with existing space in old_top.
+
+ * Almost all systems internally allocate whole pages at a time, in
+ which case we might as well use the whole last page of request.
+ So we allocate enough more memory to hit a page boundary now,
+ which in turn causes future contiguous calls to page-align.
+ */
+
+ else {
+ front_misalign = 0;
+ end_misalign = 0;
+ correction = 0;
+ aligned_brk = fst_brk;
+
+ /*
+ If MORECORE returns an address lower than we have seen before,
+ we know it isn't really contiguous. This and some subsequent
+ checks help cope with non-conforming MORECORE functions and
+ the presence of "foreign" calls to MORECORE from outside of
+ malloc or by other threads. We cannot guarantee to detect
+ these in all cases, but cope with the ones we do detect.
+ */
+ if (contiguous(av) && old_size != 0 && fst_brk < old_end) {
+ set_noncontiguous(av);
+ }
+
+ /* handle contiguous cases */
+ if (contiguous(av)) {
+
+ /* We can tolerate forward non-contiguities here (usually due
+ to foreign calls) but treat them as part of our space for
+ stats reporting. */
+ if (old_size != 0)
+ av->sbrked_mem += fst_brk - old_end;
+
+ /* Guarantee alignment of first new chunk made from this space */
+
+ front_misalign = (size_t)chunk2mem(fst_brk) & MALLOC_ALIGN_MASK;
+ if (front_misalign > 0) {
+
+ /*
+ Skip over some bytes to arrive at an aligned position.
+ We don't need to specially mark these wasted front bytes.
+ They will never be accessed anyway because
+ prev_inuse of av->top (and any chunk created from its start)
+ is always true after initialization.
+ */
+
+ correction = MALLOC_ALIGNMENT - front_misalign;
+ aligned_brk += correction;
+ }
+
+ /*
+ If this isn't adjacent to existing space, then we will not
+ be able to merge with old_top space, so must add to 2nd request.
+ */
+
+ correction += old_size;
+
+ /* Extend the end address to hit a page boundary */
+ end_misalign = (size_t)(fst_brk + size + correction);
+ correction += ((end_misalign + pagemask) & ~pagemask) - end_misalign;
+
+ assert(correction >= 0);
+ snd_brk = (char*)(MORECORE(correction));
+
+ if (snd_brk == (char*)(MORECORE_FAILURE)) {
+ /*
+ If can't allocate correction, try to at least find out current
+ brk. It might be enough to proceed without failing.
+ */
+ correction = 0;
+ snd_brk = (char*)(MORECORE(0));
+ }
+ else if (snd_brk < fst_brk) {
+ /*
+ If the second call gives noncontiguous space even though
+ it says it won't, the only course of action is to ignore
+ results of second call, and conservatively estimate where
+ the first call left us. Also set noncontiguous, so this
+ won't happen again, leaving at most one hole.
+
+ Note that this check is intrinsically incomplete. Because
+ MORECORE is allowed to give more space than we ask for,
+ there is no reliable way to detect a noncontiguity
+ producing a forward gap for the second call.
+ */
+ snd_brk = fst_brk + size;
+ correction = 0;
+ set_noncontiguous(av);
+ }
+
+ }
+
+ /* handle non-contiguous cases */
+ else {
+ /* MORECORE/mmap must correctly align */
+ assert(aligned_OK(chunk2mem(fst_brk)));
+
+ /* Find out current end of memory */
+ if (snd_brk == (char*)(MORECORE_FAILURE)) {
+ snd_brk = (char*)(MORECORE(0));
+ av->sbrked_mem += snd_brk - fst_brk - size;
+ }
+ }
+
+ /* Adjust top based on results of second sbrk */
+ if (snd_brk != (char*)(MORECORE_FAILURE)) {
+ av->top = (mchunkptr)aligned_brk;
+ set_head(av->top, (snd_brk - aligned_brk + correction) | PREV_INUSE);
+ av->sbrked_mem += correction;
+
+ /*
+ If not the first time through, we either have a
+ gap due to foreign sbrk or a non-contiguous region. Insert a
+ double fencepost at old_top to prevent consolidation with space
+ we don't own. These fenceposts are artificial chunks that are
+ marked as inuse and are in any case too small to use. We need
+ two to make sizes and alignments work out.
+ */
+
+ if (old_size != 0) {
+ /* Shrink old_top to insert fenceposts, keeping size a
+ multiple of MALLOC_ALIGNMENT. We know there is at least
+ enough space in old_top to do this.
+ */
+ old_size = (old_size - 3*(sizeof(size_t))) & ~MALLOC_ALIGN_MASK;
+ set_head(old_top, old_size | PREV_INUSE);
+
+ /*
+ Note that the following assignments completely overwrite
+ old_top when old_size was previously MINSIZE. This is
+ intentional. We need the fencepost, even if old_top otherwise gets
+ lost.
+ */
+ chunk_at_offset(old_top, old_size )->size =
+ (sizeof(size_t))|PREV_INUSE;
+
+ chunk_at_offset(old_top, old_size + (sizeof(size_t)))->size =
+ (sizeof(size_t))|PREV_INUSE;
+
+ /* If possible, release the rest, suppressing trimming. */
+ if (old_size >= MINSIZE) {
+ size_t tt = av->trim_threshold;
+ av->trim_threshold = (size_t)(-1);
+ free(chunk2mem(old_top));
+ av->trim_threshold = tt;
+ }
+ }
+ }
+ }
+
+ /* Update statistics */
+ sum = av->sbrked_mem;
+ if (sum > (unsigned long)(av->max_sbrked_mem))
+ av->max_sbrked_mem = sum;
+
+ sum += av->mmapped_mem;
+ if (sum > (unsigned long)(av->max_total_mem))
+ av->max_total_mem = sum;
+
+ check_malloc_state();
+
+ /* finally, do the allocation */
+
+ p = av->top;
+ size = chunksize(p);
+
+ /* check that one of the above allocation paths succeeded */
+ if ((unsigned long)(size) >= (unsigned long)(nb + MINSIZE)) {
+ remainder_size = size - nb;
+ remainder = chunk_at_offset(p, nb);
+ av->top = remainder;
+ set_head(p, nb | PREV_INUSE);
+ set_head(remainder, remainder_size | PREV_INUSE);
+ check_malloced_chunk(p, nb);
+ return chunk2mem(p);
+ }
+
+ }
+
+ /* catch all failure paths */
+ errno = ENOMEM;
+ return 0;
+}
+
+
+/*
+ Compute index for size. We expect this to be inlined when
+ compiled with optimization, else not, which works out well.
+*/
+static int __malloc_largebin_index(unsigned int sz)
+{
+ unsigned int x = sz >> SMALLBIN_WIDTH;
+ unsigned int m; /* bit position of highest set bit of m */
+
+ if (x >= 0x10000) return NBINS-1;
+
+ /* On intel, use BSRL instruction to find highest bit */
+#if defined(__GNUC__) && defined(i386)
+
+ __asm__("bsrl %1,%0\n\t"
+ : "=r" (m)
+ : "g" (x));
+
+#else
+ {
+ /*
+ Based on branch-free nlz algorithm in chapter 5 of Henry
+ S. Warren Jr's book "Hacker's Delight".
+ */
+
+ unsigned int n = ((x - 0x100) >> 16) & 8;
+ x <<= n;
+ m = ((x - 0x1000) >> 16) & 4;
+ n += m;
+ x <<= m;
+ m = ((x - 0x4000) >> 16) & 2;
+ n += m;
+ x = (x << m) >> 14;
+ m = 13 - n + (x & ~(x>>1));
+ }
+#endif
+
+ /* Use next 2 bits to create finer-granularity bins */
+ return NSMALLBINS + (m << 2) + ((sz >> (m + 6)) & 3);
+}
+
+
+
+/* ----------------------------------------------------------------------
+ *
+ * PUBLIC STUFF
+ *
+ * ----------------------------------------------------------------------*/
+
+
+/* ------------------------------ malloc ------------------------------ */
+void* malloc(size_t bytes)
+{
+ mstate av;
+
+ size_t nb; /* normalized request size */
+ unsigned int idx; /* associated bin index */
+ mbinptr bin; /* associated bin */
+ mfastbinptr* fb; /* associated fastbin */
+
+ mchunkptr victim; /* inspected/selected chunk */
+ size_t size; /* its size */
+ int victim_index; /* its bin index */
+
+ mchunkptr remainder; /* remainder from a split */
+ unsigned long remainder_size; /* its size */
+
+ unsigned int block; /* bit map traverser */
+ unsigned int bit; /* bit map traverser */
+ unsigned int map; /* current word of binmap */
+
+ mchunkptr fwd; /* misc temp for linking */
+ mchunkptr bck; /* misc temp for linking */
+ void * sysmem;
+ void * retval;
+
+#if !defined(__MALLOC_GLIBC_COMPAT__)
+ if (!bytes) {
+ __set_errno(ENOMEM);
+ return NULL;
+ }
+#endif
+
+ __MALLOC_LOCK;
+ av = get_malloc_state();
+ /*
+ Convert request size to internal form by adding (sizeof(size_t)) bytes
+ overhead plus possibly more to obtain necessary alignment and/or
+ to obtain a size of at least MINSIZE, the smallest allocatable
+ size. Also, checked_request2size traps (returning 0) request sizes
+ that are so large that they wrap around zero when padded and
+ aligned.
+ */
+
+ checked_request2size(bytes, nb);
+
+ /*
+ Bypass search if no frees yet
+ */
+ if (!have_anychunks(av)) {
+ if (av->max_fast == 0) /* initialization check */
+ __malloc_consolidate(av);
+ goto use_top;
+ }
+
+ /*
+ If the size qualifies as a fastbin, first check corresponding bin.
+ */
+
+ if ((unsigned long)(nb) <= (unsigned long)(av->max_fast)) {
+ fb = &(av->fastbins[(fastbin_index(nb))]);
+ if ( (victim = *fb) != 0) {
+ *fb = victim->fd;
+ check_remalloced_chunk(victim, nb);
+ retval = chunk2mem(victim);
+ goto DONE;
+ }
+ }
+
+ /*
+ If a small request, check regular bin. Since these "smallbins"
+ hold one size each, no searching within bins is necessary.
+ (For a large request, we need to wait until unsorted chunks are
+ processed to find best fit. But for small ones, fits are exact
+ anyway, so we can check now, which is faster.)
+ */
+
+ if (in_smallbin_range(nb)) {
+ idx = smallbin_index(nb);
+ bin = bin_at(av,idx);
+
+ if ( (victim = last(bin)) != bin) {
+ bck = victim->bk;
+ set_inuse_bit_at_offset(victim, nb);
+ bin->bk = bck;
+ bck->fd = bin;
+
+ check_malloced_chunk(victim, nb);
+ retval = chunk2mem(victim);
+ goto DONE;
+ }
+ }
+
+ /* If this is a large request, consolidate fastbins before continuing.
+ While it might look excessive to kill all fastbins before
+ even seeing if there is space available, this avoids
+ fragmentation problems normally associated with fastbins.
+ Also, in practice, programs tend to have runs of either small or
+ large requests, but less often mixtures, so consolidation is not
+ invoked all that often in most programs. And the programs that
+ it is called frequently in otherwise tend to fragment.
+ */
+
+ else {
+ idx = __malloc_largebin_index(nb);
+ if (have_fastchunks(av))
+ __malloc_consolidate(av);
+ }
+
+ /*
+ Process recently freed or remaindered chunks, taking one only if
+ it is exact fit, or, if this a small request, the chunk is remainder from
+ the most recent non-exact fit. Place other traversed chunks in
+ bins. Note that this step is the only place in any routine where
+ chunks are placed in bins.
+ */
+
+ while ( (victim = unsorted_chunks(av)->bk) != unsorted_chunks(av)) {
+ bck = victim->bk;
+ size = chunksize(victim);
+
+ /* If a small request, try to use last remainder if it is the
+ only chunk in unsorted bin. This helps promote locality for
+ runs of consecutive small requests. This is the only
+ exception to best-fit, and applies only when there is
+ no exact fit for a small chunk.
+ */
+
+ if (in_smallbin_range(nb) &&
+ bck == unsorted_chunks(av) &&
+ victim == av->last_remainder &&
+ (unsigned long)(size) > (unsigned long)(nb + MINSIZE)) {
+
+ /* split and reattach remainder */
+ remainder_size = size - nb;
+ remainder = chunk_at_offset(victim, nb);
+ unsorted_chunks(av)->bk = unsorted_chunks(av)->fd = remainder;
+ av->last_remainder = remainder;
+ remainder->bk = remainder->fd = unsorted_chunks(av);
+
+ set_head(victim, nb | PREV_INUSE);
+ set_head(remainder, remainder_size | PREV_INUSE);
+ set_foot(remainder, remainder_size);
+
+ check_malloced_chunk(victim, nb);
+ retval = chunk2mem(victim);
+ goto DONE;
+ }
+
+ /* remove from unsorted list */
+ unsorted_chunks(av)->bk = bck;
+ bck->fd = unsorted_chunks(av);
+
+ /* Take now instead of binning if exact fit */
+
+ if (size == nb) {
+ set_inuse_bit_at_offset(victim, size);
+ check_malloced_chunk(victim, nb);
+ retval = chunk2mem(victim);
+ goto DONE;
+ }
+
+ /* place chunk in bin */
+
+ if (in_smallbin_range(size)) {
+ victim_index = smallbin_index(size);
+ bck = bin_at(av, victim_index);
+ fwd = bck->fd;
+ }
+ else {
+ victim_index = __malloc_largebin_index(size);
+ bck = bin_at(av, victim_index);
+ fwd = bck->fd;
+
+ if (fwd != bck) {
+ /* if smaller than smallest, place first */
+ if ((unsigned long)(size) < (unsigned long)(bck->bk->size)) {
+ fwd = bck;
+ bck = bck->bk;
+ }
+ else if ((unsigned long)(size) >=
+ (unsigned long)(FIRST_SORTED_BIN_SIZE)) {
+
+ /* maintain large bins in sorted order */
+ size |= PREV_INUSE; /* Or with inuse bit to speed comparisons */
+ while ((unsigned long)(size) < (unsigned long)(fwd->size))
+ fwd = fwd->fd;
+ bck = fwd->bk;
+ }
+ }
+ }
+
+ mark_bin(av, victim_index);
+ victim->bk = bck;
+ victim->fd = fwd;
+ fwd->bk = victim;
+ bck->fd = victim;
+ }
+
+ /*
+ If a large request, scan through the chunks of current bin to
+ find one that fits. (This will be the smallest that fits unless
+ FIRST_SORTED_BIN_SIZE has been changed from default.) This is
+ the only step where an unbounded number of chunks might be
+ scanned without doing anything useful with them. However the
+ lists tend to be short.
+ */
+
+ if (!in_smallbin_range(nb)) {
+ bin = bin_at(av, idx);
+
+ for (victim = last(bin); victim != bin; victim = victim->bk) {
+ size = chunksize(victim);
+
+ if ((unsigned long)(size) >= (unsigned long)(nb)) {
+ remainder_size = size - nb;
+ unlink(victim, bck, fwd);
+
+ /* Exhaust */
+ if (remainder_size < MINSIZE) {
+ set_inuse_bit_at_offset(victim, size);
+ check_malloced_chunk(victim, nb);
+ retval = chunk2mem(victim);
+ goto DONE;
+ }
+ /* Split */
+ else {
+ remainder = chunk_at_offset(victim, nb);
+ unsorted_chunks(av)->bk = unsorted_chunks(av)->fd = remainder;
+ remainder->bk = remainder->fd = unsorted_chunks(av);
+ set_head(victim, nb | PREV_INUSE);
+ set_head(remainder, remainder_size | PREV_INUSE);
+ set_foot(remainder, remainder_size);
+ check_malloced_chunk(victim, nb);
+ retval = chunk2mem(victim);
+ goto DONE;
+ }
+ }
+ }
+ }
+
+ /*
+ Search for a chunk by scanning bins, starting with next largest
+ bin. This search is strictly by best-fit; i.e., the smallest
+ (with ties going to approximately the least recently used) chunk
+ that fits is selected.
+
+ The bitmap avoids needing to check that most blocks are nonempty.
+ */
+
+ ++idx;
+ bin = bin_at(av,idx);
+ block = idx2block(idx);
+ map = av->binmap[block];
+ bit = idx2bit(idx);
+
+ for (;;) {
+
+ /* Skip rest of block if there are no more set bits in this block. */
+ if (bit > map || bit == 0) {
+ do {
+ if (++block >= BINMAPSIZE) /* out of bins */
+ goto use_top;
+ } while ( (map = av->binmap[block]) == 0);
+
+ bin = bin_at(av, (block << BINMAPSHIFT));
+ bit = 1;
+ }
+
+ /* Advance to bin with set bit. There must be one. */
+ while ((bit & map) == 0) {
+ bin = next_bin(bin);
+ bit <<= 1;
+ assert(bit != 0);
+ }
+
+ /* Inspect the bin. It is likely to be non-empty */
+ victim = last(bin);
+
+ /* If a false alarm (empty bin), clear the bit. */
+ if (victim == bin) {
+ av->binmap[block] = map &= ~bit; /* Write through */
+ bin = next_bin(bin);
+ bit <<= 1;
+ }
+
+ else {
+ size = chunksize(victim);
+
+ /* We know the first chunk in this bin is big enough to use. */
+ assert((unsigned long)(size) >= (unsigned long)(nb));
+
+ remainder_size = size - nb;
+
+ /* unlink */
+ bck = victim->bk;
+ bin->bk = bck;
+ bck->fd = bin;
+
+ /* Exhaust */
+ if (remainder_size < MINSIZE) {
+ set_inuse_bit_at_offset(victim, size);
+ check_malloced_chunk(victim, nb);
+ retval = chunk2mem(victim);
+ goto DONE;
+ }
+
+ /* Split */
+ else {
+ remainder = chunk_at_offset(victim, nb);
+
+ unsorted_chunks(av)->bk = unsorted_chunks(av)->fd = remainder;
+ remainder->bk = remainder->fd = unsorted_chunks(av);
+ /* advertise as last remainder */
+ if (in_smallbin_range(nb))
+ av->last_remainder = remainder;
+
+ set_head(victim, nb | PREV_INUSE);
+ set_head(remainder, remainder_size | PREV_INUSE);
+ set_foot(remainder, remainder_size);
+ check_malloced_chunk(victim, nb);
+ retval = chunk2mem(victim);
+ goto DONE;
+ }
+ }
+ }
+
+use_top:
+ /*
+ If large enough, split off the chunk bordering the end of memory
+ (held in av->top). Note that this is in accord with the best-fit
+ search rule. In effect, av->top is treated as larger (and thus
+ less well fitting) than any other available chunk since it can
+ be extended to be as large as necessary (up to system
+ limitations).
+
+ We require that av->top always exists (i.e., has size >=
+ MINSIZE) after initialization, so if it would otherwise be
+ exhuasted by current request, it is replenished. (The main
+ reason for ensuring it exists is that we may need MINSIZE space
+ to put in fenceposts in sysmalloc.)
+ */
+
+ victim = av->top;
+ size = chunksize(victim);
+
+ if ((unsigned long)(size) >= (unsigned long)(nb + MINSIZE)) {
+ remainder_size = size - nb;
+ remainder = chunk_at_offset(victim, nb);
+ av->top = remainder;
+ set_head(victim, nb | PREV_INUSE);
+ set_head(remainder, remainder_size | PREV_INUSE);
+
+ check_malloced_chunk(victim, nb);
+ retval = chunk2mem(victim);
+ goto DONE;
+ }
+
+ /* If no space in top, relay to handle system-dependent cases */
+ sysmem = __malloc_alloc(nb, av);
+ retval = sysmem;
+DONE:
+ __MALLOC_UNLOCK;
+ return retval;
+}
+
diff --git a/ap/build/uClibc/libc/stdlib/malloc-standard/malloc.h b/ap/build/uClibc/libc/stdlib/malloc-standard/malloc.h
new file mode 100644
index 0000000..73d4b12
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/malloc-standard/malloc.h
@@ -0,0 +1,959 @@
+/*
+ This is a version (aka dlmalloc) of malloc/free/realloc written by
+ Doug Lea and released to the public domain. Use, modify, and
+ redistribute this code without permission or acknowledgement in any
+ way you wish. Send questions, comments, complaints, performance
+ data, etc to dl@cs.oswego.edu
+
+ VERSION 2.7.2 Sat Aug 17 09:07:30 2002 Doug Lea (dl at gee)
+
+ Note: There may be an updated version of this malloc obtainable at
+ ftp://gee.cs.oswego.edu/pub/misc/malloc.c
+ Check before installing!
+
+ Hacked up for uClibc by Erik Andersen <andersen@codepoet.org>
+*/
+
+#include <features.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <malloc.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <bits/uClibc_mutex.h>
+
+
+
+__UCLIBC_MUTEX_EXTERN(__malloc_lock);
+#define __MALLOC_LOCK __UCLIBC_MUTEX_LOCK(__malloc_lock)
+#define __MALLOC_UNLOCK __UCLIBC_MUTEX_UNLOCK(__malloc_lock)
+
+
+
+/*
+ MALLOC_ALIGNMENT is the minimum alignment for malloc'ed chunks.
+ It must be a power of two at least 2 * (sizeof(size_t)), even on machines
+ for which smaller alignments would suffice. It may be defined as
+ larger than this though. Note however that code and data structures
+ are optimized for the case of 8-byte alignment.
+*/
+#ifndef MALLOC_ALIGNMENT
+#define MALLOC_ALIGNMENT (2 * (sizeof(size_t)))
+#endif
+
+/* The corresponding bit mask value */
+#define MALLOC_ALIGN_MASK (MALLOC_ALIGNMENT - 1)
+
+/*
+ TRIM_FASTBINS controls whether free() of a very small chunk can
+ immediately lead to trimming. Setting to true (1) can reduce memory
+ footprint, but will almost always slow down programs that use a lot
+ of small chunks.
+
+ Define this only if you are willing to give up some speed to more
+ aggressively reduce system-level memory footprint when releasing
+ memory in programs that use many small chunks. You can get
+ essentially the same effect by setting MXFAST to 0, but this can
+ lead to even greater slowdowns in programs using many small chunks.
+ TRIM_FASTBINS is an in-between compile-time option, that disables
+ only those chunks bordering topmost memory from being placed in
+ fastbins.
+*/
+#ifndef TRIM_FASTBINS
+#define TRIM_FASTBINS 0
+#endif
+
+
+/*
+ MORECORE-related declarations. By default, rely on sbrk
+*/
+
+
+/*
+ MORECORE is the name of the routine to call to obtain more memory
+ from the system. See below for general guidance on writing
+ alternative MORECORE functions, as well as a version for WIN32 and a
+ sample version for pre-OSX macos.
+*/
+#ifndef MORECORE
+#define MORECORE sbrk
+#endif
+
+/*
+ MORECORE_FAILURE is the value returned upon failure of MORECORE
+ as well as mmap. Since it cannot be an otherwise valid memory address,
+ and must reflect values of standard sys calls, you probably ought not
+ try to redefine it.
+*/
+#ifndef MORECORE_FAILURE
+#define MORECORE_FAILURE (-1)
+#endif
+
+/*
+ If MORECORE_CONTIGUOUS is true, take advantage of fact that
+ consecutive calls to MORECORE with positive arguments always return
+ contiguous increasing addresses. This is true of unix sbrk. Even
+ if not defined, when regions happen to be contiguous, malloc will
+ permit allocations spanning regions obtained from different
+ calls. But defining this when applicable enables some stronger
+ consistency checks and space efficiencies.
+*/
+#ifndef MORECORE_CONTIGUOUS
+#define MORECORE_CONTIGUOUS 1
+#endif
+
+/*
+ MMAP_AS_MORECORE_SIZE is the minimum mmap size argument to use if
+ sbrk fails, and mmap is used as a backup (which is done only if
+ HAVE_MMAP). The value must be a multiple of page size. This
+ backup strategy generally applies only when systems have "holes" in
+ address space, so sbrk cannot perform contiguous expansion, but
+ there is still space available on system. On systems for which
+ this is known to be useful (i.e. most linux kernels), this occurs
+ only when programs allocate huge amounts of memory. Between this,
+ and the fact that mmap regions tend to be limited, the size should
+ be large, to avoid too many mmap calls and thus avoid running out
+ of kernel resources.
+*/
+#ifndef MMAP_AS_MORECORE_SIZE
+#define MMAP_AS_MORECORE_SIZE (1024 * 1024)
+#endif
+
+/*
+ The system page size. To the extent possible, this malloc manages
+ memory from the system in page-size units. Note that this value is
+ cached during initialization into a field of malloc_state. So even
+ if malloc_getpagesize is a function, it is only called once.
+
+ The following mechanics for getpagesize were adapted from bsd/gnu
+ getpagesize.h. If none of the system-probes here apply, a value of
+ 4096 is used, which should be OK: If they don't apply, then using
+ the actual value probably doesn't impact performance.
+*/
+#ifndef malloc_getpagesize
+# include <unistd.h>
+# define malloc_getpagesize sysconf(_SC_PAGESIZE)
+#else /* just guess */
+# define malloc_getpagesize (4096)
+#endif
+
+
+/* mallopt tuning options */
+
+/*
+ M_MXFAST is the maximum request size used for "fastbins", special bins
+ that hold returned chunks without consolidating their spaces. This
+ enables future requests for chunks of the same size to be handled
+ very quickly, but can increase fragmentation, and thus increase the
+ overall memory footprint of a program.
+
+ This malloc manages fastbins very conservatively yet still
+ efficiently, so fragmentation is rarely a problem for values less
+ than or equal to the default. The maximum supported value of MXFAST
+ is 80. You wouldn't want it any higher than this anyway. Fastbins
+ are designed especially for use with many small structs, objects or
+ strings -- the default handles structs/objects/arrays with sizes up
+ to 16 4byte fields, or small strings representing words, tokens,
+ etc. Using fastbins for larger objects normally worsens
+ fragmentation without improving speed.
+
+ M_MXFAST is set in REQUEST size units. It is internally used in
+ chunksize units, which adds padding and alignment. You can reduce
+ M_MXFAST to 0 to disable all use of fastbins. This causes the malloc
+ algorithm to be a closer approximation of fifo-best-fit in all cases,
+ not just for larger requests, but will generally cause it to be
+ slower.
+*/
+
+
+/* M_MXFAST is a standard SVID/XPG tuning option, usually listed in malloc.h */
+#ifndef M_MXFAST
+#define M_MXFAST 1
+#endif
+
+#ifndef DEFAULT_MXFAST
+#define DEFAULT_MXFAST 64
+#endif
+
+
+/*
+ M_TRIM_THRESHOLD is the maximum amount of unused top-most memory
+ to keep before releasing via malloc_trim in free().
+
+ Automatic trimming is mainly useful in long-lived programs.
+ Because trimming via sbrk can be slow on some systems, and can
+ sometimes be wasteful (in cases where programs immediately
+ afterward allocate more large chunks) the value should be high
+ enough so that your overall system performance would improve by
+ releasing this much memory.
+
+ The trim threshold and the mmap control parameters (see below)
+ can be traded off with one another. Trimming and mmapping are
+ two different ways of releasing unused memory back to the
+ system. Between these two, it is often possible to keep
+ system-level demands of a long-lived program down to a bare
+ minimum. For example, in one test suite of sessions measuring
+ the XF86 X server on Linux, using a trim threshold of 128K and a
+ mmap threshold of 192K led to near-minimal long term resource
+ consumption.
+
+ If you are using this malloc in a long-lived program, it should
+ pay to experiment with these values. As a rough guide, you
+ might set to a value close to the average size of a process
+ (program) running on your system. Releasing this much memory
+ would allow such a process to run in memory. Generally, it's
+ worth it to tune for trimming rather tham memory mapping when a
+ program undergoes phases where several large chunks are
+ allocated and released in ways that can reuse each other's
+ storage, perhaps mixed with phases where there are no such
+ chunks at all. And in well-behaved long-lived programs,
+ controlling release of large blocks via trimming versus mapping
+ is usually faster.
+
+ However, in most programs, these parameters serve mainly as
+ protection against the system-level effects of carrying around
+ massive amounts of unneeded memory. Since frequent calls to
+ sbrk, mmap, and munmap otherwise degrade performance, the default
+ parameters are set to relatively high values that serve only as
+ safeguards.
+
+ The trim value must be greater than page size to have any useful
+ effect. To disable trimming completely, you can set to
+ (unsigned long)(-1)
+
+ Trim settings interact with fastbin (MXFAST) settings: Unless
+ TRIM_FASTBINS is defined, automatic trimming never takes place upon
+ freeing a chunk with size less than or equal to MXFAST. Trimming is
+ instead delayed until subsequent freeing of larger chunks. However,
+ you can still force an attempted trim by calling malloc_trim.
+
+ Also, trimming is not generally possible in cases where
+ the main arena is obtained via mmap.
+
+ Note that the trick some people use of mallocing a huge space and
+ then freeing it at program startup, in an attempt to reserve system
+ memory, doesn't have the intended effect under automatic trimming,
+ since that memory will immediately be returned to the system.
+*/
+#define M_TRIM_THRESHOLD -1
+
+#ifndef DEFAULT_TRIM_THRESHOLD
+#define DEFAULT_TRIM_THRESHOLD (256 * 1024)
+#endif
+
+/*
+ M_TOP_PAD is the amount of extra `padding' space to allocate or
+ retain whenever sbrk is called. It is used in two ways internally:
+
+ * When sbrk is called to extend the top of the arena to satisfy
+ a new malloc request, this much padding is added to the sbrk
+ request.
+
+ * When malloc_trim is called automatically from free(),
+ it is used as the `pad' argument.
+
+ In both cases, the actual amount of padding is rounded
+ so that the end of the arena is always a system page boundary.
+
+ The main reason for using padding is to avoid calling sbrk so
+ often. Having even a small pad greatly reduces the likelihood
+ that nearly every malloc request during program start-up (or
+ after trimming) will invoke sbrk, which needlessly wastes
+ time.
+
+ Automatic rounding-up to page-size units is normally sufficient
+ to avoid measurable overhead, so the default is 0. However, in
+ systems where sbrk is relatively slow, it can pay to increase
+ this value, at the expense of carrying around more memory than
+ the program needs.
+*/
+#define M_TOP_PAD -2
+
+#ifndef DEFAULT_TOP_PAD
+#define DEFAULT_TOP_PAD (0)
+#endif
+
+/*
+ M_MMAP_THRESHOLD is the request size threshold for using mmap()
+ to service a request. Requests of at least this size that cannot
+ be allocated using already-existing space will be serviced via mmap.
+ (If enough normal freed space already exists it is used instead.)
+
+ Using mmap segregates relatively large chunks of memory so that
+ they can be individually obtained and released from the host
+ system. A request serviced through mmap is never reused by any
+ other request (at least not directly; the system may just so
+ happen to remap successive requests to the same locations).
+
+ Segregating space in this way has the benefits that:
+
+ 1. Mmapped space can ALWAYS be individually released back
+ to the system, which helps keep the system level memory
+ demands of a long-lived program low.
+ 2. Mapped memory can never become `locked' between
+ other chunks, as can happen with normally allocated chunks, which
+ means that even trimming via malloc_trim would not release them.
+ 3. On some systems with "holes" in address spaces, mmap can obtain
+ memory that sbrk cannot.
+
+ However, it has the disadvantages that:
+
+ 1. The space cannot be reclaimed, consolidated, and then
+ used to service later requests, as happens with normal chunks.
+ 2. It can lead to more wastage because of mmap page alignment
+ requirements
+ 3. It causes malloc performance to be more dependent on host
+ system memory management support routines which may vary in
+ implementation quality and may impose arbitrary
+ limitations. Generally, servicing a request via normal
+ malloc steps is faster than going through a system's mmap.
+
+ The advantages of mmap nearly always outweigh disadvantages for
+ "large" chunks, but the value of "large" varies across systems. The
+ default is an empirically derived value that works well in most
+ systems.
+*/
+#define M_MMAP_THRESHOLD -3
+
+#ifndef DEFAULT_MMAP_THRESHOLD
+#define DEFAULT_MMAP_THRESHOLD (256 * 1024)
+#endif
+
+/*
+ M_MMAP_MAX is the maximum number of requests to simultaneously
+ service using mmap. This parameter exists because
+. Some systems have a limited number of internal tables for
+ use by mmap, and using more than a few of them may degrade
+ performance.
+
+ The default is set to a value that serves only as a safeguard.
+ Setting to 0 disables use of mmap for servicing large requests. If
+ HAVE_MMAP is not set, the default value is 0, and attempts to set it
+ to non-zero values in mallopt will fail.
+*/
+#define M_MMAP_MAX -4
+
+#ifndef DEFAULT_MMAP_MAX
+#define DEFAULT_MMAP_MAX (65536)
+#endif
+
+
+/* ------------------ MMAP support ------------------ */
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+
+#ifdef __ARCH_USE_MMU__
+# define _MAP_UNINITIALIZE 0
+#else
+# define _MAP_UNINITIALIZE MAP_UNINITIALIZE
+#endif
+
+#define MMAP(addr, size, prot) \
+ (mmap((addr), (size), (prot), MAP_PRIVATE|MAP_ANONYMOUS|_MAP_UNINITIALIZE, 0, 0))
+
+
+/* ----------------------- Chunk representations ----------------------- */
+
+
+/*
+ This struct declaration is misleading (but accurate and necessary).
+ It declares a "view" into memory allowing access to necessary
+ fields at known offsets from a given base. See explanation below.
+*/
+
+struct malloc_chunk {
+
+ size_t prev_size; /* Size of previous chunk (if free). */
+ size_t size; /* Size in bytes, including overhead. */
+
+ struct malloc_chunk* fd; /* double links -- used only if free. */
+ struct malloc_chunk* bk;
+};
+
+
+typedef struct malloc_chunk* mchunkptr;
+
+/*
+ malloc_chunk details:
+
+ (The following includes lightly edited explanations by Colin Plumb.)
+
+ Chunks of memory are maintained using a `boundary tag' method as
+ described in e.g., Knuth or Standish. (See the paper by Paul
+ Wilson ftp://ftp.cs.utexas.edu/pub/garbage/allocsrv.ps for a
+ survey of such techniques.) Sizes of free chunks are stored both
+ in the front of each chunk and at the end. This makes
+ consolidating fragmented chunks into bigger chunks very fast. The
+ size fields also hold bits representing whether chunks are free or
+ in use.
+
+ An allocated chunk looks like this:
+
+
+ chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Size of previous chunk, if allocated | |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Size of chunk, in bytes |P|
+ mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | User data starts here... .
+ . .
+ . (malloc_usable_space() bytes) .
+ . |
+nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Size of chunk |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+ Where "chunk" is the front of the chunk for the purpose of most of
+ the malloc code, but "mem" is the pointer that is returned to the
+ user. "Nextchunk" is the beginning of the next contiguous chunk.
+
+ Chunks always begin on even word boundries, so the mem portion
+ (which is returned to the user) is also on an even word boundary, and
+ thus at least double-word aligned.
+
+ Free chunks are stored in circular doubly-linked lists, and look like this:
+
+ chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Size of previous chunk |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ `head:' | Size of chunk, in bytes |P|
+ mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Forward pointer to next chunk in list |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Back pointer to previous chunk in list |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Unused space (may be 0 bytes long) .
+ . .
+ . |
+nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ `foot:' | Size of chunk, in bytes |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ The P (PREV_INUSE) bit, stored in the unused low-order bit of the
+ chunk size (which is always a multiple of two words), is an in-use
+ bit for the *previous* chunk. If that bit is *clear*, then the
+ word before the current chunk size contains the previous chunk
+ size, and can be used to find the front of the previous chunk.
+ The very first chunk allocated always has this bit set,
+ preventing access to non-existent (or non-owned) memory. If
+ prev_inuse is set for any given chunk, then you CANNOT determine
+ the size of the previous chunk, and might even get a memory
+ addressing fault when trying to do so.
+
+ Note that the `foot' of the current chunk is actually represented
+ as the prev_size of the NEXT chunk. This makes it easier to
+ deal with alignments etc but can be very confusing when trying
+ to extend or adapt this code.
+
+ The two exceptions to all this are
+
+ 1. The special chunk `top' doesn't bother using the
+ trailing size field since there is no next contiguous chunk
+ that would have to index off it. After initialization, `top'
+ is forced to always exist. If it would become less than
+ MINSIZE bytes long, it is replenished.
+
+ 2. Chunks allocated via mmap, which have the second-lowest-order
+ bit (IS_MMAPPED) set in their size fields. Because they are
+ allocated one-by-one, each must contain its own trailing size field.
+
+*/
+
+/*
+ ---------- Size and alignment checks and conversions ----------
+*/
+
+/* conversion from malloc headers to user pointers, and back */
+
+#define chunk2mem(p) ((void*)((char*)(p) + 2*(sizeof(size_t))))
+#define mem2chunk(mem) ((mchunkptr)((char*)(mem) - 2*(sizeof(size_t))))
+
+/* The smallest possible chunk */
+#define MIN_CHUNK_SIZE (sizeof(struct malloc_chunk))
+
+/* The smallest size we can malloc is an aligned minimal chunk */
+
+#define MINSIZE \
+ (unsigned long)(((MIN_CHUNK_SIZE+MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK))
+
+/* Check if m has acceptable alignment */
+
+#define aligned_OK(m) (((unsigned long)((m)) & (MALLOC_ALIGN_MASK)) == 0)
+
+
+/* Check if a request is so large that it would wrap around zero when
+ padded and aligned. To simplify some other code, the bound is made
+ low enough so that adding MINSIZE will also not wrap around sero.
+*/
+
+#define REQUEST_OUT_OF_RANGE(req) \
+ ((unsigned long)(req) >= \
+ (unsigned long)(size_t)(-2 * MINSIZE))
+
+/* pad request bytes into a usable size -- internal version */
+
+#define request2size(req) \
+ (((req) + (sizeof(size_t)) + MALLOC_ALIGN_MASK < MINSIZE) ? \
+ MINSIZE : \
+ ((req) + (sizeof(size_t)) + MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK)
+
+/* Same, except also perform argument check */
+
+#define checked_request2size(req, sz) \
+ if (REQUEST_OUT_OF_RANGE(req)) { \
+ errno = ENOMEM; \
+ return 0; \
+ } \
+ (sz) = request2size(req);
+
+/*
+ --------------- Physical chunk operations ---------------
+*/
+
+
+/* size field is or'ed with PREV_INUSE when previous adjacent chunk in use */
+#define PREV_INUSE 0x1
+
+/* extract inuse bit of previous chunk */
+#define prev_inuse(p) ((p)->size & PREV_INUSE)
+
+
+/* size field is or'ed with IS_MMAPPED if the chunk was obtained with mmap() */
+#define IS_MMAPPED 0x2
+
+/* check for mmap()'ed chunk */
+#define chunk_is_mmapped(p) ((p)->size & IS_MMAPPED)
+
+/* Bits to mask off when extracting size
+
+ Note: IS_MMAPPED is intentionally not masked off from size field in
+ macros for which mmapped chunks should never be seen. This should
+ cause helpful core dumps to occur if it is tried by accident by
+ people extending or adapting this malloc.
+*/
+#define SIZE_BITS (PREV_INUSE|IS_MMAPPED)
+
+/* Get size, ignoring use bits */
+#define chunksize(p) ((p)->size & ~(SIZE_BITS))
+
+
+/* Ptr to next physical malloc_chunk. */
+#define next_chunk(p) ((mchunkptr)( ((char*)(p)) + ((p)->size & ~PREV_INUSE) ))
+
+/* Ptr to previous physical malloc_chunk */
+#define prev_chunk(p) ((mchunkptr)( ((char*)(p)) - ((p)->prev_size) ))
+
+/* Treat space at ptr + offset as a chunk */
+#define chunk_at_offset(p, s) ((mchunkptr)(((char*)(p)) + (s)))
+
+/* extract p's inuse bit */
+#define inuse(p)\
+((((mchunkptr)(((char*)(p))+((p)->size & ~PREV_INUSE)))->size) & PREV_INUSE)
+
+/* set/clear chunk as being inuse without otherwise disturbing */
+#define set_inuse(p)\
+((mchunkptr)(((char*)(p)) + ((p)->size & ~PREV_INUSE)))->size |= PREV_INUSE
+
+#define clear_inuse(p)\
+((mchunkptr)(((char*)(p)) + ((p)->size & ~PREV_INUSE)))->size &= ~(PREV_INUSE)
+
+
+/* check/set/clear inuse bits in known places */
+#define inuse_bit_at_offset(p, s)\
+ (((mchunkptr)(((char*)(p)) + (s)))->size & PREV_INUSE)
+
+#define set_inuse_bit_at_offset(p, s)\
+ (((mchunkptr)(((char*)(p)) + (s)))->size |= PREV_INUSE)
+
+#define clear_inuse_bit_at_offset(p, s)\
+ (((mchunkptr)(((char*)(p)) + (s)))->size &= ~(PREV_INUSE))
+
+
+/* Set size at head, without disturbing its use bit */
+#define set_head_size(p, s) ((p)->size = (((p)->size & PREV_INUSE) | (s)))
+
+/* Set size/use field */
+#define set_head(p, s) ((p)->size = (s))
+
+/* Set size at footer (only when chunk is not in use) */
+#define set_foot(p, s) (((mchunkptr)((char*)(p) + (s)))->prev_size = (s))
+
+
+/* -------------------- Internal data structures -------------------- */
+
+/*
+ Bins
+
+ An array of bin headers for free chunks. Each bin is doubly
+ linked. The bins are approximately proportionally (log) spaced.
+ There are a lot of these bins (128). This may look excessive, but
+ works very well in practice. Most bins hold sizes that are
+ unusual as malloc request sizes, but are more usual for fragments
+ and consolidated sets of chunks, which is what these bins hold, so
+ they can be found quickly. All procedures maintain the invariant
+ that no consolidated chunk physically borders another one, so each
+ chunk in a list is known to be preceeded and followed by either
+ inuse chunks or the ends of memory.
+
+ Chunks in bins are kept in size order, with ties going to the
+ approximately least recently used chunk. Ordering isn't needed
+ for the small bins, which all contain the same-sized chunks, but
+ facilitates best-fit allocation for larger chunks. These lists
+ are just sequential. Keeping them in order almost never requires
+ enough traversal to warrant using fancier ordered data
+ structures.
+
+ Chunks of the same size are linked with the most
+ recently freed at the front, and allocations are taken from the
+ back. This results in LRU (FIFO) allocation order, which tends
+ to give each chunk an equal opportunity to be consolidated with
+ adjacent freed chunks, resulting in larger free chunks and less
+ fragmentation.
+
+ To simplify use in double-linked lists, each bin header acts
+ as a malloc_chunk. This avoids special-casing for headers.
+ But to conserve space and improve locality, we allocate
+ only the fd/bk pointers of bins, and then use repositioning tricks
+ to treat these as the fields of a malloc_chunk*.
+*/
+
+typedef struct malloc_chunk* mbinptr;
+
+/* addressing -- note that bin_at(0) does not exist */
+#define bin_at(m, i) ((mbinptr)((char*)&((m)->bins[(i)<<1]) - ((sizeof(size_t))<<1)))
+
+/* analog of ++bin */
+#define next_bin(b) ((mbinptr)((char*)(b) + (sizeof(mchunkptr)<<1)))
+
+/* Reminders about list directionality within bins */
+#define first(b) ((b)->fd)
+#define last(b) ((b)->bk)
+
+/* Take a chunk off a bin list */
+#define unlink(P, BK, FD) { \
+ FD = P->fd; \
+ BK = P->bk; \
+ if (FD->bk != P || BK->fd != P) \
+ abort(); \
+ FD->bk = BK; \
+ BK->fd = FD; \
+}
+
+/*
+ Indexing
+
+ Bins for sizes < 512 bytes contain chunks of all the same size, spaced
+ 8 bytes apart. Larger bins are approximately logarithmically spaced:
+
+ 64 bins of size 8
+ 32 bins of size 64
+ 16 bins of size 512
+ 8 bins of size 4096
+ 4 bins of size 32768
+ 2 bins of size 262144
+ 1 bin of size what's left
+
+ The bins top out around 1MB because we expect to service large
+ requests via mmap.
+*/
+
+#define NBINS 96
+#define NSMALLBINS 32
+#define SMALLBIN_WIDTH 8
+#define MIN_LARGE_SIZE 256
+
+#define in_smallbin_range(sz) \
+ ((unsigned long)(sz) < (unsigned long)MIN_LARGE_SIZE)
+
+#define smallbin_index(sz) (((unsigned)(sz)) >> 3)
+
+#define bin_index(sz) \
+ ((in_smallbin_range(sz)) ? smallbin_index(sz) : __malloc_largebin_index(sz))
+
+/*
+ FIRST_SORTED_BIN_SIZE is the chunk size corresponding to the
+ first bin that is maintained in sorted order. This must
+ be the smallest size corresponding to a given bin.
+
+ Normally, this should be MIN_LARGE_SIZE. But you can weaken
+ best fit guarantees to sometimes speed up malloc by increasing value.
+ Doing this means that malloc may choose a chunk that is
+ non-best-fitting by up to the width of the bin.
+
+ Some useful cutoff values:
+ 512 - all bins sorted
+ 2560 - leaves bins <= 64 bytes wide unsorted
+ 12288 - leaves bins <= 512 bytes wide unsorted
+ 65536 - leaves bins <= 4096 bytes wide unsorted
+ 262144 - leaves bins <= 32768 bytes wide unsorted
+ -1 - no bins sorted (not recommended!)
+*/
+
+#define FIRST_SORTED_BIN_SIZE MIN_LARGE_SIZE
+/* #define FIRST_SORTED_BIN_SIZE 65536 */
+
+/*
+ Unsorted chunks
+
+ All remainders from chunk splits, as well as all returned chunks,
+ are first placed in the "unsorted" bin. They are then placed
+ in regular bins after malloc gives them ONE chance to be used before
+ binning. So, basically, the unsorted_chunks list acts as a queue,
+ with chunks being placed on it in free (and __malloc_consolidate),
+ and taken off (to be either used or placed in bins) in malloc.
+*/
+
+/* The otherwise unindexable 1-bin is used to hold unsorted chunks. */
+#define unsorted_chunks(M) (bin_at(M, 1))
+
+/*
+ Top
+
+ The top-most available chunk (i.e., the one bordering the end of
+ available memory) is treated specially. It is never included in
+ any bin, is used only if no other chunk is available, and is
+ released back to the system if it is very large (see
+ M_TRIM_THRESHOLD). Because top initially
+ points to its own bin with initial zero size, thus forcing
+ extension on the first malloc request, we avoid having any special
+ code in malloc to check whether it even exists yet. But we still
+ need to do so when getting memory from system, so we make
+ initial_top treat the bin as a legal but unusable chunk during the
+ interval between initialization and the first call to
+ __malloc_alloc. (This is somewhat delicate, since it relies on
+ the 2 preceding words to be zero during this interval as well.)
+*/
+
+/* Conveniently, the unsorted bin can be used as dummy top on first call */
+#define initial_top(M) (unsorted_chunks(M))
+
+/*
+ Binmap
+
+ To help compensate for the large number of bins, a one-level index
+ structure is used for bin-by-bin searching. `binmap' is a
+ bitvector recording whether bins are definitely empty so they can
+ be skipped over during during traversals. The bits are NOT always
+ cleared as soon as bins are empty, but instead only
+ when they are noticed to be empty during traversal in malloc.
+*/
+
+/* Conservatively use 32 bits per map word, even if on 64bit system */
+#define BINMAPSHIFT 5
+#define BITSPERMAP (1U << BINMAPSHIFT)
+#define BINMAPSIZE (NBINS / BITSPERMAP)
+
+#define idx2block(i) ((i) >> BINMAPSHIFT)
+#define idx2bit(i) ((1U << ((i) & ((1U << BINMAPSHIFT)-1))))
+
+#define mark_bin(m,i) ((m)->binmap[idx2block(i)] |= idx2bit(i))
+#define unmark_bin(m,i) ((m)->binmap[idx2block(i)] &= ~(idx2bit(i)))
+#define get_binmap(m,i) ((m)->binmap[idx2block(i)] & idx2bit(i))
+
+/*
+ Fastbins
+
+ An array of lists holding recently freed small chunks. Fastbins
+ are not doubly linked. It is faster to single-link them, and
+ since chunks are never removed from the middles of these lists,
+ double linking is not necessary. Also, unlike regular bins, they
+ are not even processed in FIFO order (they use faster LIFO) since
+ ordering doesn't much matter in the transient contexts in which
+ fastbins are normally used.
+
+ Chunks in fastbins keep their inuse bit set, so they cannot
+ be consolidated with other free chunks. __malloc_consolidate
+ releases all chunks in fastbins and consolidates them with
+ other free chunks.
+*/
+
+typedef struct malloc_chunk* mfastbinptr;
+
+/* offset 2 to use otherwise unindexable first 2 bins */
+#define fastbin_index(sz) ((((unsigned int)(sz)) >> 3) - 2)
+
+/* The maximum fastbin request size we support */
+#define MAX_FAST_SIZE 80
+
+#define NFASTBINS (fastbin_index(request2size(MAX_FAST_SIZE))+1)
+
+/*
+ FASTBIN_CONSOLIDATION_THRESHOLD is the size of a chunk in free()
+ that triggers automatic consolidation of possibly-surrounding
+ fastbin chunks. This is a heuristic, so the exact value should not
+ matter too much. It is defined at half the default trim threshold as a
+ compromise heuristic to only attempt consolidation if it is likely
+ to lead to trimming. However, it is not dynamically tunable, since
+ consolidation reduces fragmentation surrounding loarge chunks even
+ if trimming is not used.
+*/
+
+#define FASTBIN_CONSOLIDATION_THRESHOLD \
+ ((unsigned long)(DEFAULT_TRIM_THRESHOLD) >> 1)
+
+/*
+ Since the lowest 2 bits in max_fast don't matter in size comparisons,
+ they are used as flags.
+*/
+
+/*
+ ANYCHUNKS_BIT held in max_fast indicates that there may be any
+ freed chunks at all. It is set true when entering a chunk into any
+ bin.
+*/
+
+#define ANYCHUNKS_BIT (1U)
+
+#define have_anychunks(M) (((M)->max_fast & ANYCHUNKS_BIT))
+#define set_anychunks(M) ((M)->max_fast |= ANYCHUNKS_BIT)
+#define clear_anychunks(M) ((M)->max_fast &= ~ANYCHUNKS_BIT)
+
+/*
+ FASTCHUNKS_BIT held in max_fast indicates that there are probably
+ some fastbin chunks. It is set true on entering a chunk into any
+ fastbin, and cleared only in __malloc_consolidate.
+*/
+
+#define FASTCHUNKS_BIT (2U)
+
+#define have_fastchunks(M) (((M)->max_fast & FASTCHUNKS_BIT))
+#define set_fastchunks(M) ((M)->max_fast |= (FASTCHUNKS_BIT|ANYCHUNKS_BIT))
+#define clear_fastchunks(M) ((M)->max_fast &= ~(FASTCHUNKS_BIT))
+
+/* Set value of max_fast. Use impossibly small value if 0. */
+#define set_max_fast(M, s) \
+ (M)->max_fast = (((s) == 0)? SMALLBIN_WIDTH: request2size(s)) | \
+ ((M)->max_fast & (FASTCHUNKS_BIT|ANYCHUNKS_BIT))
+
+#define get_max_fast(M) \
+ ((M)->max_fast & ~(FASTCHUNKS_BIT | ANYCHUNKS_BIT))
+
+
+/*
+ morecore_properties is a status word holding dynamically discovered
+ or controlled properties of the morecore function
+*/
+
+#define MORECORE_CONTIGUOUS_BIT (1U)
+
+#define contiguous(M) \
+ (((M)->morecore_properties & MORECORE_CONTIGUOUS_BIT))
+#define noncontiguous(M) \
+ (((M)->morecore_properties & MORECORE_CONTIGUOUS_BIT) == 0)
+#define set_contiguous(M) \
+ ((M)->morecore_properties |= MORECORE_CONTIGUOUS_BIT)
+#define set_noncontiguous(M) \
+ ((M)->morecore_properties &= ~MORECORE_CONTIGUOUS_BIT)
+
+
+/*
+ ----------- Internal state representation and initialization -----------
+*/
+
+struct malloc_state {
+
+ /* The maximum chunk size to be eligible for fastbin */
+ size_t max_fast; /* low 2 bits used as flags */
+
+ /* Fastbins */
+ mfastbinptr fastbins[NFASTBINS];
+
+ /* Base of the topmost chunk -- not otherwise kept in a bin */
+ mchunkptr top;
+
+ /* The remainder from the most recent split of a small request */
+ mchunkptr last_remainder;
+
+ /* Normal bins packed as described above */
+ mchunkptr bins[NBINS * 2];
+
+ /* Bitmap of bins. Trailing zero map handles cases of largest binned size */
+ unsigned int binmap[BINMAPSIZE+1];
+
+ /* Tunable parameters */
+ unsigned long trim_threshold;
+ size_t top_pad;
+ size_t mmap_threshold;
+
+ /* Memory map support */
+ int n_mmaps;
+ int n_mmaps_max;
+ int max_n_mmaps;
+
+ /* Cache malloc_getpagesize */
+ unsigned int pagesize;
+
+ /* Track properties of MORECORE */
+ unsigned int morecore_properties;
+
+ /* Statistics */
+ size_t mmapped_mem;
+ size_t sbrked_mem;
+ size_t max_sbrked_mem;
+ size_t max_mmapped_mem;
+ size_t max_total_mem;
+};
+
+typedef struct malloc_state *mstate;
+
+/*
+ There is exactly one instance of this struct in this malloc.
+ If you are adapting this malloc in a way that does NOT use a static
+ malloc_state, you MUST explicitly zero-fill it before using. This
+ malloc relies on the property that malloc_state is initialized to
+ all zeroes (as is true of C statics).
+*/
+extern struct malloc_state __malloc_state; /* never directly referenced */
+
+/*
+ All uses of av_ are via get_malloc_state().
+ At most one "call" to get_malloc_state is made per invocation of
+ the public versions of malloc and free, but other routines
+ that in turn invoke malloc and/or free may call more then once.
+ Also, it is called in check* routines if __UCLIBC_MALLOC_DEBUGGING__ is set.
+*/
+
+#define get_malloc_state() (&(__malloc_state))
+
+/* External internal utilities operating on mstates */
+void __malloc_consolidate(mstate) attribute_hidden;
+
+
+/* Debugging support */
+#ifndef __UCLIBC_MALLOC_DEBUGGING__
+
+#define check_chunk(P)
+#define check_free_chunk(P)
+#define check_inuse_chunk(P)
+#define check_remalloced_chunk(P,N)
+#define check_malloced_chunk(P,N)
+#define check_malloc_state()
+#define assert(x) ((void)0)
+
+
+#else
+
+#define check_chunk(P) __do_check_chunk(P)
+#define check_free_chunk(P) __do_check_free_chunk(P)
+#define check_inuse_chunk(P) __do_check_inuse_chunk(P)
+#define check_remalloced_chunk(P,N) __do_check_remalloced_chunk(P,N)
+#define check_malloced_chunk(P,N) __do_check_malloced_chunk(P,N)
+#define check_malloc_state() __do_check_malloc_state()
+
+extern void __do_check_chunk(mchunkptr p);
+extern void __do_check_free_chunk(mchunkptr p);
+extern void __do_check_inuse_chunk(mchunkptr p);
+extern void __do_check_remalloced_chunk(mchunkptr p, size_t s);
+extern void __do_check_malloced_chunk(mchunkptr p, size_t s);
+extern void __do_check_malloc_state(void);
+
+#include <assert.h>
+
+#endif
diff --git a/ap/build/uClibc/libc/stdlib/malloc-standard/mallopt.c b/ap/build/uClibc/libc/stdlib/malloc-standard/mallopt.c
new file mode 100644
index 0000000..053242d
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/malloc-standard/mallopt.c
@@ -0,0 +1,64 @@
+/*
+ This is a version (aka dlmalloc) of malloc/free/realloc written by
+ Doug Lea and released to the public domain. Use, modify, and
+ redistribute this code without permission or acknowledgement in any
+ way you wish. Send questions, comments, complaints, performance
+ data, etc to dl@cs.oswego.edu
+
+ VERSION 2.7.2 Sat Aug 17 09:07:30 2002 Doug Lea (dl at gee)
+
+ Note: There may be an updated version of this malloc obtainable at
+ ftp://gee.cs.oswego.edu/pub/misc/malloc.c
+ Check before installing!
+
+ Hacked up for uClibc by Erik Andersen <andersen@codepoet.org>
+*/
+
+#include "malloc.h"
+
+
+/* ------------------------------ mallopt ------------------------------ */
+int mallopt(int param_number, int value)
+{
+ int ret;
+ mstate av;
+
+ ret = 0;
+
+ __MALLOC_LOCK;
+ av = get_malloc_state();
+ /* Ensure initialization/consolidation */
+ __malloc_consolidate(av);
+
+ switch(param_number) {
+ case M_MXFAST:
+ if (value >= 0 && value <= MAX_FAST_SIZE) {
+ set_max_fast(av, value);
+ ret = 1;
+ }
+ break;
+
+ case M_TRIM_THRESHOLD:
+ av->trim_threshold = value;
+ ret = 1;
+ break;
+
+ case M_TOP_PAD:
+ av->top_pad = value;
+ ret = 1;
+ break;
+
+ case M_MMAP_THRESHOLD:
+ av->mmap_threshold = value;
+ ret = 1;
+ break;
+
+ case M_MMAP_MAX:
+ av->n_mmaps_max = value;
+ ret = 1;
+ break;
+ }
+ __MALLOC_UNLOCK;
+ return ret;
+}
+
diff --git a/ap/build/uClibc/libc/stdlib/malloc-standard/memalign.c b/ap/build/uClibc/libc/stdlib/malloc-standard/memalign.c
new file mode 100644
index 0000000..7e0674b
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/malloc-standard/memalign.c
@@ -0,0 +1,130 @@
+/*
+ This is a version (aka dlmalloc) of malloc/free/realloc written by
+ Doug Lea and released to the public domain. Use, modify, and
+ redistribute this code without permission or acknowledgement in any
+ way you wish. Send questions, comments, complaints, performance
+ data, etc to dl@cs.oswego.edu
+
+ VERSION 2.7.2 Sat Aug 17 09:07:30 2002 Doug Lea (dl at gee)
+
+ Note: There may be an updated version of this malloc obtainable at
+ ftp://gee.cs.oswego.edu/pub/misc/malloc.c
+ Check before installing!
+
+ Hacked up for uClibc by Erik Andersen <andersen@codepoet.org>
+*/
+
+#include <features.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include "malloc.h"
+
+
+/* ------------------------------ memalign ------------------------------ */
+void* memalign(size_t alignment, size_t bytes)
+{
+ size_t nb; /* padded request size */
+ char* m; /* memory returned by malloc call */
+ mchunkptr p; /* corresponding chunk */
+ char* _brk; /* alignment point within p */
+ mchunkptr newp; /* chunk to return */
+ size_t newsize; /* its size */
+ size_t leadsize; /* leading space before alignment point */
+ mchunkptr remainder; /* spare room at end to split off */
+ unsigned long remainder_size; /* its size */
+ size_t size;
+ void *retval;
+
+ /* If need less alignment than we give anyway, just relay to malloc */
+
+ if (alignment <= MALLOC_ALIGNMENT) return malloc(bytes);
+
+ /* Otherwise, ensure that it is at least a minimum chunk size */
+
+ if (alignment < MINSIZE) alignment = MINSIZE;
+
+ /* Make sure alignment is power of 2 (in case MINSIZE is not). */
+ if ((alignment & (alignment - 1)) != 0) {
+ size_t a = MALLOC_ALIGNMENT * 2;
+ while ((unsigned long)a < (unsigned long)alignment) a <<= 1;
+ alignment = a;
+ }
+
+ __MALLOC_LOCK;
+ checked_request2size(bytes, nb);
+
+ /* Strategy: find a spot within that chunk that meets the alignment
+ * request, and then possibly free the leading and trailing space. */
+
+
+ /* Call malloc with worst case padding to hit alignment. */
+
+ m = (char*)(malloc(nb + alignment + MINSIZE));
+
+ if (m == 0) {
+ retval = 0; /* propagate failure */
+ goto DONE;
+ }
+
+ p = mem2chunk(m);
+
+ if ((((unsigned long)(m)) % alignment) != 0) { /* misaligned */
+
+ /*
+ Find an aligned spot inside chunk. Since we need to give back
+ leading space in a chunk of at least MINSIZE, if the first
+ calculation places us at a spot with less than MINSIZE leader,
+ we can move to the next aligned spot -- we've allocated enough
+ total room so that this is always possible.
+ */
+
+ _brk = (char*)mem2chunk((unsigned long)(((unsigned long)(m + alignment - 1)) &
+ -((signed long) alignment)));
+ if ((unsigned long)(_brk - (char*)(p)) < MINSIZE)
+ _brk += alignment;
+
+ newp = (mchunkptr)_brk;
+ leadsize = _brk - (char*)(p);
+ newsize = chunksize(p) - leadsize;
+
+ /* For mmapped chunks, just adjust offset */
+ if (chunk_is_mmapped(p)) {
+ newp->prev_size = p->prev_size + leadsize;
+ set_head(newp, newsize|IS_MMAPPED);
+ retval = chunk2mem(newp);
+ goto DONE;
+ }
+
+ /* Otherwise, give back leader, use the rest */
+ set_head(newp, newsize | PREV_INUSE);
+ set_inuse_bit_at_offset(newp, newsize);
+ set_head_size(p, leadsize);
+ free(chunk2mem(p));
+ p = newp;
+
+ assert (newsize >= nb &&
+ (((unsigned long)(chunk2mem(p))) % alignment) == 0);
+ }
+
+ /* Also give back spare room at the end */
+ if (!chunk_is_mmapped(p)) {
+ size = chunksize(p);
+ if ((unsigned long)(size) > (unsigned long)(nb + MINSIZE)) {
+ remainder_size = size - nb;
+ remainder = chunk_at_offset(p, nb);
+ set_head(remainder, remainder_size | PREV_INUSE);
+ set_head_size(p, nb);
+ free(chunk2mem(remainder));
+ }
+ }
+
+ check_inuse_chunk(p);
+ retval = chunk2mem(p);
+
+ DONE:
+ __MALLOC_UNLOCK;
+ return retval;
+}
+
diff --git a/ap/build/uClibc/libc/stdlib/malloc-standard/realloc.c b/ap/build/uClibc/libc/stdlib/malloc-standard/realloc.c
new file mode 100644
index 0000000..e060b70
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/malloc-standard/realloc.c
@@ -0,0 +1,240 @@
+/*
+ This is a version (aka dlmalloc) of malloc/free/realloc written by
+ Doug Lea and released to the public domain. Use, modify, and
+ redistribute this code without permission or acknowledgement in any
+ way you wish. Send questions, comments, complaints, performance
+ data, etc to dl@cs.oswego.edu
+
+ VERSION 2.7.2 Sat Aug 17 09:07:30 2002 Doug Lea (dl at gee)
+
+ Note: There may be an updated version of this malloc obtainable at
+ ftp://gee.cs.oswego.edu/pub/misc/malloc.c
+ Check before installing!
+
+ Hacked up for uClibc by Erik Andersen <andersen@codepoet.org>
+*/
+
+#include "malloc.h"
+
+
+/* ------------------------------ realloc ------------------------------ */
+void* realloc(void* oldmem, size_t bytes)
+{
+ mstate av;
+
+ size_t nb; /* padded request size */
+
+ mchunkptr oldp; /* chunk corresponding to oldmem */
+ size_t oldsize; /* its size */
+
+ mchunkptr newp; /* chunk to return */
+ size_t newsize; /* its size */
+ void* newmem; /* corresponding user mem */
+
+ mchunkptr next; /* next contiguous chunk after oldp */
+
+ mchunkptr remainder; /* extra space at end of newp */
+ unsigned long remainder_size; /* its size */
+
+ mchunkptr bck; /* misc temp for linking */
+ mchunkptr fwd; /* misc temp for linking */
+
+ unsigned long copysize; /* bytes to copy */
+ unsigned int ncopies; /* size_t words to copy */
+ size_t* s; /* copy source */
+ size_t* d; /* copy destination */
+
+ void *retval;
+
+ /* Check for special cases. */
+ if (! oldmem)
+ return malloc(bytes);
+ if (! bytes) {
+ free (oldmem);
+ return NULL;
+ }
+
+ __MALLOC_LOCK;
+ av = get_malloc_state();
+ checked_request2size(bytes, nb);
+
+ oldp = mem2chunk(oldmem);
+ oldsize = chunksize(oldp);
+
+ check_inuse_chunk(oldp);
+
+ if (!chunk_is_mmapped(oldp)) {
+
+ if ((unsigned long)(oldsize) >= (unsigned long)(nb)) {
+ /* already big enough; split below */
+ newp = oldp;
+ newsize = oldsize;
+ }
+
+ else {
+ next = chunk_at_offset(oldp, oldsize);
+
+ /* Try to expand forward into top */
+ if (next == av->top &&
+ (unsigned long)(newsize = oldsize + chunksize(next)) >=
+ (unsigned long)(nb + MINSIZE)) {
+ set_head_size(oldp, nb);
+ av->top = chunk_at_offset(oldp, nb);
+ set_head(av->top, (newsize - nb) | PREV_INUSE);
+ retval = chunk2mem(oldp);
+ goto DONE;
+ }
+
+ /* Try to expand forward into next chunk; split off remainder below */
+ else if (next != av->top &&
+ !inuse(next) &&
+ (unsigned long)(newsize = oldsize + chunksize(next)) >=
+ (unsigned long)(nb)) {
+ newp = oldp;
+ unlink(next, bck, fwd);
+ }
+
+ /* allocate, copy, free */
+ else {
+ newmem = malloc(nb - MALLOC_ALIGN_MASK);
+ if (newmem == 0) {
+ retval = 0; /* propagate failure */
+ goto DONE;
+ }
+
+ newp = mem2chunk(newmem);
+ newsize = chunksize(newp);
+
+ /*
+ Avoid copy if newp is next chunk after oldp.
+ */
+ if (newp == next) {
+ newsize += oldsize;
+ newp = oldp;
+ }
+ else {
+ /*
+ Unroll copy of <= 36 bytes (72 if 8byte sizes)
+ We know that contents have an odd number of
+ size_t-sized words; minimally 3.
+ */
+
+ copysize = oldsize - (sizeof(size_t));
+ s = (size_t*)(oldmem);
+ d = (size_t*)(newmem);
+ ncopies = copysize / sizeof(size_t);
+ assert(ncopies >= 3);
+
+ if (ncopies > 9)
+ memcpy(d, s, copysize);
+
+ else {
+ *(d+0) = *(s+0);
+ *(d+1) = *(s+1);
+ *(d+2) = *(s+2);
+ if (ncopies > 4) {
+ *(d+3) = *(s+3);
+ *(d+4) = *(s+4);
+ if (ncopies > 6) {
+ *(d+5) = *(s+5);
+ *(d+6) = *(s+6);
+ if (ncopies > 8) {
+ *(d+7) = *(s+7);
+ *(d+8) = *(s+8);
+ }
+ }
+ }
+ }
+
+ free(oldmem);
+ check_inuse_chunk(newp);
+ retval = chunk2mem(newp);
+ goto DONE;
+ }
+ }
+ }
+
+ /* If possible, free extra space in old or extended chunk */
+
+ assert((unsigned long)(newsize) >= (unsigned long)(nb));
+
+ remainder_size = newsize - nb;
+
+ if (remainder_size < MINSIZE) { /* not enough extra to split off */
+ set_head_size(newp, newsize);
+ set_inuse_bit_at_offset(newp, newsize);
+ }
+ else { /* split remainder */
+ remainder = chunk_at_offset(newp, nb);
+ set_head_size(newp, nb);
+ set_head(remainder, remainder_size | PREV_INUSE);
+ /* Mark remainder as inuse so free() won't complain */
+ set_inuse_bit_at_offset(remainder, remainder_size);
+ free(chunk2mem(remainder));
+ }
+
+ check_inuse_chunk(newp);
+ retval = chunk2mem(newp);
+ goto DONE;
+ }
+
+ /*
+ Handle mmap cases
+ */
+
+ else {
+ size_t offset = oldp->prev_size;
+ size_t pagemask = av->pagesize - 1;
+ char *cp;
+ unsigned long sum;
+
+ /* Note the extra (sizeof(size_t)) overhead */
+ newsize = (nb + offset + (sizeof(size_t)) + pagemask) & ~pagemask;
+
+ /* don't need to remap if still within same page */
+ if (oldsize == newsize - offset) {
+ retval = oldmem;
+ goto DONE;
+ }
+
+ cp = (char*)mremap((char*)oldp - offset, oldsize + offset, newsize, 1);
+
+ if (cp != (char*)MORECORE_FAILURE) {
+
+ newp = (mchunkptr)(cp + offset);
+ set_head(newp, (newsize - offset)|IS_MMAPPED);
+
+ assert(aligned_OK(chunk2mem(newp)));
+ assert((newp->prev_size == offset));
+
+ /* update statistics */
+ sum = av->mmapped_mem += newsize - oldsize;
+ if (sum > (unsigned long)(av->max_mmapped_mem))
+ av->max_mmapped_mem = sum;
+ sum += av->sbrked_mem;
+ if (sum > (unsigned long)(av->max_total_mem))
+ av->max_total_mem = sum;
+
+ retval = chunk2mem(newp);
+ goto DONE;
+ }
+
+ /* Note the extra (sizeof(size_t)) overhead. */
+ if ((unsigned long)(oldsize) >= (unsigned long)(nb + (sizeof(size_t))))
+ newmem = oldmem; /* do nothing */
+ else {
+ /* Must alloc, copy, free. */
+ newmem = malloc(nb - MALLOC_ALIGN_MASK);
+ if (newmem != 0) {
+ memcpy(newmem, oldmem, oldsize - 2*(sizeof(size_t)));
+ free(oldmem);
+ }
+ }
+ retval = newmem;
+ }
+
+ DONE:
+ __MALLOC_UNLOCK;
+ return retval;
+}
+
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;
+}
diff --git a/ap/build/uClibc/libc/stdlib/mblen.c b/ap/build/uClibc/libc/stdlib/mblen.c
new file mode 100644
index 0000000..c7a0ccb
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/mblen.c
@@ -0,0 +1,7 @@
+/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_mblen
+#include "stdlib.c"
diff --git a/ap/build/uClibc/libc/stdlib/mbstowcs.c b/ap/build/uClibc/libc/stdlib/mbstowcs.c
new file mode 100644
index 0000000..f618003
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/mbstowcs.c
@@ -0,0 +1,7 @@
+/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_mbstowcs
+#include "stdlib.c"
diff --git a/ap/build/uClibc/libc/stdlib/mbtowc.c b/ap/build/uClibc/libc/stdlib/mbtowc.c
new file mode 100644
index 0000000..5d888d1
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/mbtowc.c
@@ -0,0 +1,7 @@
+/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_mbtowc
+#include "stdlib.c"
diff --git a/ap/build/uClibc/libc/stdlib/mkdtemp.c b/ap/build/uClibc/libc/stdlib/mkdtemp.c
new file mode 100644
index 0000000..2bf15ae
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/mkdtemp.c
@@ -0,0 +1,38 @@
+/* vi: set sw=4 ts=4: */
+/* Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include "../misc/internals/tempname.h"
+
+#ifdef __USE_BSD
+/* Generate a unique temporary directory name from TEMPLATE.
+ The last six characters of TEMPLATE must be "XXXXXX";
+ they are replaced with a string that makes the filename unique.
+ The directory is created, mode 700, and its name is returned.
+ (This function comes from OpenBSD.) */
+char * mkdtemp (char *template)
+{
+ if (__gen_tempname (template, __GT_DIR, S_IRUSR | S_IWUSR | S_IXUSR))
+ return NULL;
+ else
+ return template;
+}
+#endif
diff --git a/ap/build/uClibc/libc/stdlib/mkstemp.c b/ap/build/uClibc/libc/stdlib/mkstemp.c
new file mode 100644
index 0000000..ce7d7db
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/mkstemp.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include "../misc/internals/tempname.h"
+
+/* Generate a unique temporary file name from TEMPLATE.
+ The last six characters of TEMPLATE must be "XXXXXX";
+ they are replaced with a string that makes the filename unique.
+ Then open the file and return a fd. */
+int mkstemp (char *template)
+{
+ return __gen_tempname (template, __GT_FILE, S_IRUSR | S_IWUSR);
+}
diff --git a/ap/build/uClibc/libc/stdlib/mkstemp64.c b/ap/build/uClibc/libc/stdlib/mkstemp64.c
new file mode 100644
index 0000000..2cdee70
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/mkstemp64.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include "../misc/internals/tempname.h"
+
+/* Generate a unique temporary file name from TEMPLATE.
+ The last six characters of TEMPLATE must be "XXXXXX";
+ they are replaced with a string that makes the filename unique.
+ Then open the file and return a fd. */
+int mkstemp64 (char *template)
+{
+ return __gen_tempname (template, __GT_BIGFILE, S_IRUSR | S_IWUSR);
+}
diff --git a/ap/build/uClibc/libc/stdlib/mktemp.c b/ap/build/uClibc/libc/stdlib/mktemp.c
new file mode 100644
index 0000000..3c922e3
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/mktemp.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "../misc/internals/tempname.h"
+
+/* Generate a unique temporary file name from TEMPLATE.
+ * The last six characters of TEMPLATE must be "XXXXXX";
+ * they are replaced with a string that makes the filename unique. */
+char *mktemp(char *template)
+{
+ if (__gen_tempname (template, __GT_NOCREATE, 0) < 0)
+ /* We return the null string if we can't find a unique file name. */
+ template[0] = '\0';
+
+ return template;
+}
+
+link_warning(mktemp, "the use of `mktemp' is dangerous, better use `mkstemp'")
diff --git a/ap/build/uClibc/libc/stdlib/mrand48.c b/ap/build/uClibc/libc/stdlib/mrand48.c
new file mode 100644
index 0000000..6f7cf73
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/mrand48.c
@@ -0,0 +1,29 @@
+/* Copyright (C) 1995, 1996, 1997, 1998, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu <mailto:drepper@gnu.ai.mit.edu>>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdlib.h>
+
+long int mrand48 (void)
+{
+ long int result;
+
+ jrand48_r (__libc_drand48_data.__x, &__libc_drand48_data, &result);
+
+ return result;
+}
diff --git a/ap/build/uClibc/libc/stdlib/mrand48_r.c b/ap/build/uClibc/libc/stdlib/mrand48_r.c
new file mode 100644
index 0000000..86fd6a2
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/mrand48_r.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 1995, 1997, 1998, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu <mailto:drepper@gnu.ai.mit.edu>>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdlib.h>
+
+
+int mrand48_r (struct drand48_data *buffer, long int *result)
+{
+ /* Be generous for the arguments, detect some errors. */
+ if (buffer == NULL)
+ return -1;
+
+ return jrand48_r (buffer->__x, buffer, result);
+}
diff --git a/ap/build/uClibc/libc/stdlib/nrand48.c b/ap/build/uClibc/libc/stdlib/nrand48.c
new file mode 100644
index 0000000..5183484
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/nrand48.c
@@ -0,0 +1,29 @@
+/* Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu <mailto:drepper@gnu.ai.mit.edu>>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdlib.h>
+
+long int nrand48 (unsigned short int xsubi[3])
+{
+ long int result;
+
+ nrand48_r (xsubi, &__libc_drand48_data, &result);
+
+ return result;
+}
diff --git a/ap/build/uClibc/libc/stdlib/nrand48_r.c b/ap/build/uClibc/libc/stdlib/nrand48_r.c
new file mode 100644
index 0000000..b8ed0eb
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/nrand48_r.c
@@ -0,0 +1,36 @@
+/* Copyright (C) 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu <mailto:drepper@gnu.ai.mit.edu>>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdlib.h>
+
+int nrand48_r (unsigned short int xsubi[3], struct drand48_data *buffer, long int *result)
+{
+ /* Compute next state. */
+ if (__drand48_iterate (xsubi, buffer) < 0)
+ return -1;
+
+ /* Store the result. */
+ if (sizeof (unsigned short int) == 2)
+ *result = xsubi[2] << 15 | xsubi[1] >> 1;
+ else
+ *result = xsubi[2] >> 1;
+
+ return 0;
+}
+libc_hidden_def(nrand48_r)
diff --git a/ap/build/uClibc/libc/stdlib/old_atexit.c b/ap/build/uClibc/libc/stdlib/old_atexit.c
new file mode 100644
index 0000000..b15fd0a
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/old_atexit.c
@@ -0,0 +1,8 @@
+/*
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_old_atexit
+#include "_atexit.c"
diff --git a/ap/build/uClibc/libc/stdlib/on_exit.c b/ap/build/uClibc/libc/stdlib/on_exit.c
new file mode 100644
index 0000000..cb943ac
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/on_exit.c
@@ -0,0 +1,8 @@
+/*
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_on_exit
+#include "_atexit.c"
diff --git a/ap/build/uClibc/libc/stdlib/posix_memalign.c b/ap/build/uClibc/libc/stdlib/posix_memalign.c
new file mode 100644
index 0000000..115fb89
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/posix_memalign.c
@@ -0,0 +1,42 @@
+/* vi: set sw=4 ts=4: */
+/* posix_memalign for uClibc
+ *
+ * Copyright (C) 1996-2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ * Copyright (C) 2005 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 <malloc.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <sys/param.h>
+
+int posix_memalign(void **memptr, size_t alignment, size_t size)
+{
+ /* Make sure alignment is correct. */
+ if (alignment % sizeof(void *) != 0)
+ /* Skip these checks because the memalign() func does them for us
+ || !powerof2(alignment / sizeof(void *)) != 0
+ || alignment == 0
+ */
+ return EINVAL;
+
+ *memptr = memalign(alignment, size);
+
+ return (*memptr != NULL ? 0 : ENOMEM);
+}
diff --git a/ap/build/uClibc/libc/stdlib/ptsname.c b/ap/build/uClibc/libc/stdlib/ptsname.c
new file mode 100644
index 0000000..ff38233
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/ptsname.c
@@ -0,0 +1,192 @@
+/* Copyright (C) 1998, 2000, 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Zack Weinberg <zack@rabi.phys.columbia.edu>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdio.h>
+#include <errno.h>
+#include <paths.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/sysmacros.h>
+#include <termios.h>
+#include <unistd.h>
+#include <bits/uClibc_uintmaxtostr.h>
+
+
+#if !defined __UNIX98PTY_ONLY__
+
+/* Check if DEV corresponds to a master pseudo terminal device. */
+#define MASTER_P(Dev) \
+ (major ((Dev)) == 2 \
+ || (major ((Dev)) == 4 && minor ((Dev)) >= 128 && minor ((Dev)) < 192) \
+ || (major ((Dev)) >= 128 && major ((Dev)) < 136))
+
+/* Check if DEV corresponds to a slave pseudo terminal device. */
+#define SLAVE_P(Dev) \
+ (major ((Dev)) == 3 \
+ || (major ((Dev)) == 4 && minor ((Dev)) >= 192 && minor ((Dev)) < 256) \
+ || (major ((Dev)) >= 136 && major ((Dev)) < 144))
+
+/* Note that major number 4 corresponds to the old BSD style pseudo
+ terminal devices. As of Linux 2.1.115 these are no longer
+ supported. They have been replaced by major numbers 2 (masters)
+ and 3 (slaves). */
+
+/* The are declared in getpt.c. */
+extern const char __libc_ptyname1[] attribute_hidden;
+extern const char __libc_ptyname2[] attribute_hidden;
+
+#endif
+
+/* Directory where we can find the slave pty nodes. */
+#define _PATH_DEVPTS "/dev/pts/"
+
+/* Store at most BUFLEN characters of the pathname of the slave pseudo
+ terminal associated with the master FD is open on in BUF.
+ Return 0 on success, otherwise an error number. */
+int ptsname_r (int fd, char *buf, size_t buflen)
+{
+ int save_errno = errno;
+#if !defined __UNIX98PTY_ONLY__
+ struct stat st;
+#endif
+ int ptyno;
+
+ if (buf == NULL)
+ {
+ errno = EINVAL;
+ return EINVAL;
+ }
+
+#if !defined __UNIX98PTY_ONLY__
+ if (!isatty (fd))
+ {
+ errno = ENOTTY;
+ return ENOTTY;
+ }
+#elif !defined TIOCGPTN
+# error "__UNIX98PTY_ONLY__ enabled but TIOCGPTN ioctl not supported by your kernel."
+#endif
+#ifdef TIOCGPTN
+ if (ioctl (fd, TIOCGPTN, &ptyno) == 0)
+ {
+ /* Buffer we use to print the number in. */
+ char numbuf[__BUFLEN_INT10TOSTR];
+ static const char devpts[] = _PATH_DEVPTS;
+ char *p;
+
+ p = _int10tostr(&numbuf[sizeof numbuf - 1], ptyno);
+
+ if (buflen < sizeof(devpts) + (size_t)(&numbuf[sizeof(numbuf) - 1] - p))
+ {
+ errno = ERANGE;
+ return ERANGE;
+ }
+
+ strcpy (buf, devpts);
+ strcat (buf, p);
+ /* Note: Don't bother with stat on the slave name and checking the
+ driver's major device number - the ioctl above succeeded so
+ we know the fd was a Unix'98 master and the /dev/pts/ prefix
+ is set by definition. If the name isn't really a slave PTY,
+ the system is misconfigured anyway - something else will fail
+ later.
+ */
+ errno = save_errno;
+ return 0;
+ }
+#endif
+#if defined __UNIX98PTY_ONLY__
+ else
+ {
+ /* If the ioctl fails it wasn't a Unix 98 master PTY */
+ errno = ENOTTY;
+ return ENOTTY;
+ }
+#else
+# if defined TIOCGPTN
+ else if (errno == EINVAL)
+# endif
+ {
+ char *p;
+
+ if (buflen < strlen (_PATH_TTY) + 3)
+ {
+ errno = ERANGE;
+ return ERANGE;
+ }
+
+ if (fstat (fd, &st) < 0)
+ return errno;
+
+ /* Check if FD really is a master pseudo terminal. */
+ if (! MASTER_P (st.st_rdev))
+ {
+ errno = ENOTTY;
+ return ENOTTY;
+ }
+
+ ptyno = minor (st.st_rdev);
+ /* This is for the old BSD pseudo terminals. As of Linux
+ 2.1.115 these are no longer supported. */
+ if (major (st.st_rdev) == 4)
+ ptyno -= 128;
+
+ if (ptyno / 16 >= strlen (__libc_ptyname1))
+ {
+ errno = ENOTTY;
+ return ENOTTY;
+ }
+
+ strcpy (buf, _PATH_TTY);
+ p = buf + strlen (buf);
+ p[0] = __libc_ptyname1[ptyno / 16];
+ p[1] = __libc_ptyname2[ptyno % 16];
+ p[2] = '\0';
+ }
+
+ if (stat(buf, &st) < 0)
+ return errno;
+
+ /* Check if the name we're about to return really corresponds to a
+ slave pseudo terminal. */
+ if (! S_ISCHR (st.st_mode) || ! SLAVE_P (st.st_rdev))
+ {
+ /* This really is a configuration problem. */
+ errno = ENOTTY;
+ return ENOTTY;
+ }
+#endif
+
+ errno = save_errno;
+ return 0;
+}
+libc_hidden_def(ptsname_r)
+
+/* Return the pathname of the pseudo terminal slave assoicated with
+ the master FD is open on, or NULL on errors.
+ The returned storage is good until the next call to this function. */
+char *
+ptsname (int fd)
+{
+ static char buffer[sizeof (_PATH_DEVPTS) + 20];
+
+ return ptsname_r (fd, buffer, sizeof (buffer)) != 0 ? NULL : buffer;
+}
diff --git a/ap/build/uClibc/libc/stdlib/pty-private.h b/ap/build/uClibc/libc/stdlib/pty-private.h
new file mode 100644
index 0000000..621dbfd
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/pty-private.h
@@ -0,0 +1,42 @@
+/* Internal defenitions and declarations for pseudo terminal functions.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Zack Weinberg <zack@rabi.phys.columbia.edu>, 1998.
+
+ The GNU C Library 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.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#ifndef _PTY_PRIVATE_H
+#define _PTY_PRIVATE_H 1
+
+/* The group slave pseudo terminals belong to. */
+#define TTY_GROUP "tty"
+
+/* The file descriptor connected to the master pseudo terminal. */
+#define PTY_FILENO 3
+
+/* Path to the helper program that implements `grantpt' in user space. */
+#define _PATH_PT_CHOWN "/sbin/pt_chown"
+
+/* Exit codes for the helper program. */
+enum /* failure modes */
+{
+ FAIL_EBADF = 1,
+ FAIL_EINVAL,
+ FAIL_EACCES,
+ FAIL_EXEC
+};
+
+#endif /* pty-private.h */
diff --git a/ap/build/uClibc/libc/stdlib/qsort.c b/ap/build/uClibc/libc/stdlib/qsort.c
new file mode 100644
index 0000000..31fc2ea
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/qsort.c
@@ -0,0 +1,7 @@
+/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_qsort
+#include "stdlib.c"
diff --git a/ap/build/uClibc/libc/stdlib/qsort_r.c b/ap/build/uClibc/libc/stdlib/qsort_r.c
new file mode 100644
index 0000000..1db270e
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/qsort_r.c
@@ -0,0 +1,7 @@
+/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_qsort_r
+#include "stdlib.c"
diff --git a/ap/build/uClibc/libc/stdlib/rand.c b/ap/build/uClibc/libc/stdlib/rand.c
new file mode 100644
index 0000000..4b899c0
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/rand.c
@@ -0,0 +1,14 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * rand for uClibc
+ * Copyright (C) 2000-2006 by Erik Andersen <andersen@uclibc.org>
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <stdlib.h>
+
+
+int rand(void)
+{
+ return (int)random();
+}
diff --git a/ap/build/uClibc/libc/stdlib/rand_r.c b/ap/build/uClibc/libc/stdlib/rand_r.c
new file mode 100644
index 0000000..6100440
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/rand_r.c
@@ -0,0 +1,48 @@
+/* Reentrant random function frm POSIX.1c.
+ Copyright (C) 1996, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com <mailto:drepper@cygnus.com>>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdlib.h>
+
+
+/* This algorithm is mentioned in the ISO C standard, here extended
+ for 32 bits. */
+int rand_r (unsigned int *seed)
+{
+ unsigned int next = *seed;
+ int result;
+
+ next *= 1103515245;
+ next += 12345;
+ result = (unsigned int) (next / 65536) % 2048;
+
+ next *= 1103515245;
+ next += 12345;
+ result <<= 10;
+ result ^= (unsigned int) (next / 65536) % 1024;
+
+ next *= 1103515245;
+ next += 12345;
+ result <<= 10;
+ result ^= (unsigned int) (next / 65536) % 1024;
+
+ *seed = next;
+
+ return result;
+}
diff --git a/ap/build/uClibc/libc/stdlib/random.c b/ap/build/uClibc/libc/stdlib/random.c
new file mode 100644
index 0000000..b009c43
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/random.c
@@ -0,0 +1,243 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley. The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*
+ * This is derived from the Berkeley source:
+ * @(#)random.c 5.5 (Berkeley) 7/6/88
+ * It was reworked for the GNU C Library by Roland McGrath.
+ * Rewritten to use reentrant functions by Ulrich Drepper, 1995.
+ */
+
+#include <features.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+
+/* POSIX.1c requires that there is mutual exclusion for the `rand' and
+ `srand' functions to prevent concurrent calls from modifying common
+ data. */
+#include <bits/uClibc_mutex.h>
+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);
+
+
+/* An improved random number generation package. In addition to the standard
+ rand()/srand() like interface, this package also has a special state info
+ interface. The initstate() routine is called with a seed, an array of
+ bytes, and a count of how many bytes are being passed in; this array is
+ then initialized to contain information for random number generation with
+ that much state information. Good sizes for the amount of state
+ information are 32, 64, 128, and 256 bytes. The state can be switched by
+ calling the setstate() function with the same array as was initialized
+ with initstate(). By default, the package runs with 128 bytes of state
+ information and generates far better random numbers than a linear
+ congruential generator. If the amount of state information is less than
+ 32 bytes, a simple linear congruential R.N.G. is used. Internally, the
+ state information is treated as an array of longs; the zeroth element of
+ the array is the type of R.N.G. being used (small integer); the remainder
+ of the array is the state information for the R.N.G. Thus, 32 bytes of
+ state information will give 7 longs worth of state information, which will
+ allow a degree seven polynomial. (Note: The zeroth word of state
+ information also has some other information stored in it; see setstate
+ for details). The random number generation technique is a linear feedback
+ shift register approach, employing trinomials (since there are fewer terms
+ to sum up that way). In this approach, the least significant bit of all
+ the numbers in the state table will act as a linear feedback shift register,
+ and will have period 2^deg - 1 (where deg is the degree of the polynomial
+ being used, assuming that the polynomial is irreducible and primitive).
+ The higher order bits will have longer periods, since their values are
+ also influenced by pseudo-random carries out of the lower bits. The
+ total period of the generator is approximately deg*(2**deg - 1); thus
+ doubling the amount of state information has a vast influence on the
+ period of the generator. Note: The deg*(2**deg - 1) is an approximation
+ only good for large deg, when the period of the shift register is the
+ dominant factor. With deg equal to seven, the period is actually much
+ longer than the 7*(2**7 - 1) predicted by this formula. */
+
+
+
+/* Keep constants in sync with random_r.c */
+
+/* Linear congruential. */
+#define TYPE_0 0
+#define BREAK_0 8
+#define DEG_0 0
+#define SEP_0 0
+
+/* x**7 + x**3 + 1. */
+#define TYPE_1 1
+#define BREAK_1 32
+#define DEG_1 7
+#define SEP_1 3
+
+/* x**15 + x + 1. */
+#define TYPE_2 2
+#define BREAK_2 64
+#define DEG_2 15
+#define SEP_2 1
+
+/* x**31 + x**3 + 1. */
+#define TYPE_3 3
+#define BREAK_3 128
+#define DEG_3 31
+#define SEP_3 3
+
+/* x**63 + x + 1. */
+#define TYPE_4 4
+#define BREAK_4 256
+#define DEG_4 63
+#define SEP_4 1
+
+#define MAX_TYPES 5 /* Max number of types above. */
+
+/* Initially, everything is set up as if from:
+ initstate(1, randtbl, 128);
+ Note that this initialization takes advantage of the fact that srandom
+ advances the front and rear pointers 10*rand_deg times, and hence the
+ rear pointer which starts at 0 will also end up at zero; thus the zeroth
+ element of the state information, which contains info about the current
+ position of the rear pointer is just
+ (MAX_TYPES * (rptr - state)) + TYPE_3 == TYPE_3. */
+
+static int32_t randtbl[DEG_3 + 1] =
+{
+ TYPE_3,
+
+ -1726662223, 379960547, 1735697613, 1040273694, 1313901226,
+ 1627687941, -179304937, -2073333483, 1780058412, -1989503057,
+ -615974602, 344556628, 939512070, -1249116260, 1507946756,
+ -812545463, 154635395, 1388815473, -1926676823, 525320961,
+ -1009028674, 968117788, -123449607, 1284210865, 435012392,
+ -2017506339, -911064859, -370259173, 1132637927, 1398500161,
+ -205601318,
+};
+
+
+static struct random_data unsafe_state =
+{
+ /* FPTR and RPTR are two pointers into the state info, a front and a rear
+ pointer. These two pointers are always rand_sep places aparts, as they
+ cycle through the state information. (Yes, this does mean we could get
+ away with just one pointer, but the code for random is more efficient
+ this way). The pointers are left positioned as they would be from the call:
+ initstate(1, randtbl, 128);
+ (The position of the rear pointer, rptr, is really 0 (as explained above
+ in the initialization of randtbl) because the state table pointer is set
+ to point to randtbl[1] (as explained below).) */
+
+ fptr : &randtbl[SEP_3 + 1],
+ rptr : &randtbl[1],
+
+ /* The following things are the pointer to the state information table,
+ the type of the current generator, the degree of the current polynomial
+ being used, and the separation between the two pointers.
+ Note that for efficiency of random, we remember the first location of
+ the state information, not the zeroth. Hence it is valid to access
+ state[-1], which is used to store the type of the R.N.G.
+ Also, we remember the last location, since this is more efficient than
+ indexing every time to find the address of the last element to see if
+ the front and rear pointers have wrapped. */
+
+ state : &randtbl[1],
+
+ rand_type : TYPE_3,
+ rand_deg : DEG_3,
+ rand_sep : SEP_3,
+
+ end_ptr : &randtbl[sizeof (randtbl) / sizeof (randtbl[0])]
+};
+
+
+/* Initialize the random number generator based on the given seed. If the
+ type is the trivial no-state-information type, just remember the seed.
+ Otherwise, initializes state[] based on the given "seed" via a linear
+ congruential generator. Then, the pointers are set to known locations
+ that are exactly rand_sep places apart. Lastly, it cycles the state
+ information a given number of times to get rid of any initial dependencies
+ introduced by the L.C.R.N.G. Note that the initialization of randtbl[]
+ for default usage relies on values produced by this routine. */
+void srandom (unsigned int x)
+{
+ __UCLIBC_MUTEX_LOCK(mylock);
+ srandom_r (x, &unsafe_state);
+ __UCLIBC_MUTEX_UNLOCK(mylock);
+}
+strong_alias(srandom,srand)
+
+/* Initialize the state information in the given array of N bytes for
+ future random number generation. Based on the number of bytes we
+ are given, and the break values for the different R.N.G.'s, we choose
+ the best (largest) one we can and set things up for it. srandom is
+ then called to initialize the state information. Note that on return
+ from srandom, we set state[-1] to be the type multiplexed with the current
+ value of the rear pointer; this is so successive calls to initstate won't
+ lose this information and will be able to restart with setstate.
+ Note: The first thing we do is save the current state, if any, just like
+ setstate so that it doesn't matter when initstate is called.
+ Returns a pointer to the old state. */
+char * initstate (unsigned int seed, char *arg_state, size_t n)
+{
+ int32_t *ostate;
+
+ __UCLIBC_MUTEX_LOCK(mylock);
+ ostate = &unsafe_state.state[-1];
+ initstate_r (seed, arg_state, n, &unsafe_state);
+ __UCLIBC_MUTEX_UNLOCK(mylock);
+ return (char *) ostate;
+}
+
+/* Restore the state from the given state array.
+ Note: It is important that we also remember the locations of the pointers
+ in the current state information, and restore the locations of the pointers
+ from the old state information. This is done by multiplexing the pointer
+ location into the zeroth word of the state information. Note that due
+ to the order in which things are done, it is OK to call setstate with the
+ same state as the current state
+ Returns a pointer to the old state information. */
+char * setstate (char *arg_state)
+{
+ int32_t *ostate;
+
+ __UCLIBC_MUTEX_LOCK(mylock);
+ ostate = &unsafe_state.state[-1];
+ if (setstate_r (arg_state, &unsafe_state) < 0)
+ ostate = NULL;
+ __UCLIBC_MUTEX_UNLOCK(mylock);
+ return (char *) ostate;
+}
+
+/* If we are using the trivial TYPE_0 R.N.G., just do the old linear
+ congruential bit. Otherwise, we do our fancy trinomial stuff, which is the
+ same in all the other cases due to all the global variables that have been
+ set up. The basic operation is to add the number at the rear pointer into
+ the one at the front pointer. Then both pointers are advanced to the next
+ location cyclically in the table. The value returned is the sum generated,
+ reduced to 31 bits by throwing away the "least random" low bit.
+ Note: The code takes advantage of the fact that both the front and
+ rear pointers can't wrap on the same call by not testing the rear
+ pointer if the front one has wrapped. Returns a 31-bit random number. */
+
+long int random (void)
+{
+ int32_t retval;
+
+ __UCLIBC_MUTEX_LOCK(mylock);
+ random_r (&unsafe_state, &retval);
+ __UCLIBC_MUTEX_UNLOCK(mylock);
+ return retval;
+}
+libc_hidden_def(random)
diff --git a/ap/build/uClibc/libc/stdlib/random_r.c b/ap/build/uClibc/libc/stdlib/random_r.c
new file mode 100644
index 0000000..4b2b3f8
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/random_r.c
@@ -0,0 +1,359 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley. The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*
+ * This is derived from the Berkeley source:
+ * @(#)random.c 5.5 (Berkeley) 7/6/88
+ * It was reworked for the GNU C Library by Roland McGrath.
+ * Rewritten to be reentrant by Ulrich Drepper, 1995
+ */
+
+#include <features.h>
+#include <errno.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+/* An improved random number generation package. In addition to the standard
+ rand()/srand() like interface, this package also has a special state info
+ interface. The initstate() routine is called with a seed, an array of
+ bytes, and a count of how many bytes are being passed in; this array is
+ then initialized to contain information for random number generation with
+ that much state information. Good sizes for the amount of state
+ information are 32, 64, 128, and 256 bytes. The state can be switched by
+ calling the setstate() function with the same array as was initialized
+ with initstate(). By default, the package runs with 128 bytes of state
+ information and generates far better random numbers than a linear
+ congruential generator. If the amount of state information is less than
+ 32 bytes, a simple linear congruential R.N.G. is used. Internally, the
+ state information is treated as an array of longs; the zeroth element of
+ the array is the type of R.N.G. being used (small integer); the remainder
+ of the array is the state information for the R.N.G. Thus, 32 bytes of
+ state information will give 7 longs worth of state information, which will
+ allow a degree seven polynomial. (Note: The zeroth word of state
+ information also has some other information stored in it; see setstate
+ for details). The random number generation technique is a linear feedback
+ shift register approach, employing trinomials (since there are fewer terms
+ to sum up that way). In this approach, the least significant bit of all
+ the numbers in the state table will act as a linear feedback shift register,
+ and will have period 2^deg - 1 (where deg is the degree of the polynomial
+ being used, assuming that the polynomial is irreducible and primitive).
+ The higher order bits will have longer periods, since their values are
+ also influenced by pseudo-random carries out of the lower bits. The
+ total period of the generator is approximately deg*(2**deg - 1); thus
+ doubling the amount of state information has a vast influence on the
+ period of the generator. Note: The deg*(2**deg - 1) is an approximation
+ only good for large deg, when the period of the shift register is the
+ dominant factor. With deg equal to seven, the period is actually much
+ longer than the 7*(2**7 - 1) predicted by this formula. */
+
+
+
+/* For each of the currently supported random number generators, we have a
+ break value on the amount of state information (you need at least this many
+ bytes of state info to support this random number generator), a degree for
+ the polynomial (actually a trinomial) that the R.N.G. is based on, and
+ separation between the two lower order coefficients of the trinomial. */
+
+/* Linear congruential. */
+#define TYPE_0 0
+#define BREAK_0 8
+#define DEG_0 0
+#define SEP_0 0
+
+/* x**7 + x**3 + 1. */
+#define TYPE_1 1
+#define BREAK_1 32
+#define DEG_1 7
+#define SEP_1 3
+
+/* x**15 + x + 1. */
+#define TYPE_2 2
+#define BREAK_2 64
+#define DEG_2 15
+#define SEP_2 1
+
+/* x**31 + x**3 + 1. */
+#define TYPE_3 3
+#define BREAK_3 128
+#define DEG_3 31
+#define SEP_3 3
+
+/* x**63 + x + 1. */
+#define TYPE_4 4
+#define BREAK_4 256
+#define DEG_4 63
+#define SEP_4 1
+
+
+/* Array versions of the above information to make code run faster.
+ Relies on fact that TYPE_i == i. */
+
+#define MAX_TYPES 5 /* Max number of types above. */
+
+struct random_poly_info
+{
+ smallint seps[MAX_TYPES];
+ smallint degrees[MAX_TYPES];
+};
+
+static const struct random_poly_info random_poly_info =
+{
+ { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 },
+ { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 }
+};
+
+
+
+/* If we are using the trivial TYPE_0 R.N.G., just do the old linear
+ congruential bit. Otherwise, we do our fancy trinomial stuff, which is the
+ same in all the other cases due to all the global variables that have been
+ set up. The basic operation is to add the number at the rear pointer into
+ the one at the front pointer. Then both pointers are advanced to the next
+ location cyclically in the table. The value returned is the sum generated,
+ reduced to 31 bits by throwing away the "least random" low bit.
+ Note: The code takes advantage of the fact that both the front and
+ rear pointers can't wrap on the same call by not testing the rear
+ pointer if the front one has wrapped. Returns a 31-bit random number. */
+
+int random_r(struct random_data *buf, int32_t *result)
+{
+ int32_t *state;
+
+ if (buf == NULL || result == NULL)
+ goto fail;
+
+ state = buf->state;
+
+ if (buf->rand_type == TYPE_0)
+ {
+ int32_t val = state[0];
+ val = ((state[0] * 1103515245) + 12345) & 0x7fffffff;
+ state[0] = val;
+ *result = val;
+ }
+ else
+ {
+ int32_t *fptr = buf->fptr;
+ int32_t *rptr = buf->rptr;
+ int32_t *end_ptr = buf->end_ptr;
+ int32_t val;
+
+ val = *fptr += *rptr;
+ /* Chucking least random bit. */
+ *result = (val >> 1) & 0x7fffffff;
+ ++fptr;
+ if (fptr >= end_ptr)
+ {
+ fptr = state;
+ ++rptr;
+ }
+ else
+ {
+ ++rptr;
+ if (rptr >= end_ptr)
+ rptr = state;
+ }
+ buf->fptr = fptr;
+ buf->rptr = rptr;
+ }
+ return 0;
+
+fail:
+ __set_errno (EINVAL);
+ return -1;
+}
+libc_hidden_def(random_r)
+
+/* Initialize the random number generator based on the given seed. If the
+ type is the trivial no-state-information type, just remember the seed.
+ Otherwise, initializes state[] based on the given "seed" via a linear
+ congruential generator. Then, the pointers are set to known locations
+ that are exactly rand_sep places apart. Lastly, it cycles the state
+ information a given number of times to get rid of any initial dependencies
+ introduced by the L.C.R.N.G. Note that the initialization of randtbl[]
+ for default usage relies on values produced by this routine. */
+int srandom_r (unsigned int seed, struct random_data *buf)
+{
+ int type;
+ int32_t *state;
+ long int i;
+ long int word;
+ int32_t *dst;
+ int kc;
+
+ if (buf == NULL)
+ goto fail;
+ type = buf->rand_type;
+ if ((unsigned int) type >= MAX_TYPES)
+ goto fail;
+
+ state = buf->state;
+ /* We must make sure the seed is not 0. Take arbitrarily 1 in this case. */
+ if (seed == 0)
+ seed = 1;
+ state[0] = seed;
+ if (type == TYPE_0)
+ goto done;
+
+ dst = state;
+ word = seed;
+ kc = buf->rand_deg;
+ for (i = 1; i < kc; ++i)
+ {
+ /* This does:
+ state[i] = (16807 * state[i - 1]) % 2147483647;
+ but avoids overflowing 31 bits. */
+ long int hi = word / 127773;
+ long int lo = word % 127773;
+ word = 16807 * lo - 2836 * hi;
+ if (word < 0)
+ word += 2147483647;
+ *++dst = word;
+ }
+
+ buf->fptr = &state[buf->rand_sep];
+ buf->rptr = &state[0];
+ kc *= 10;
+ while (--kc >= 0)
+ {
+ int32_t discard;
+ (void) random_r (buf, &discard);
+ }
+
+done:
+ return 0;
+
+fail:
+ return -1;
+}
+libc_hidden_def(srandom_r)
+
+/* Initialize the state information in the given array of N bytes for
+ future random number generation. Based on the number of bytes we
+ are given, and the break values for the different R.N.G.'s, we choose
+ the best (largest) one we can and set things up for it. srandom is
+ then called to initialize the state information. Note that on return
+ from srandom, we set state[-1] to be the type multiplexed with the current
+ value of the rear pointer; this is so successive calls to initstate won't
+ lose this information and will be able to restart with setstate.
+ Note: The first thing we do is save the current state, if any, just like
+ setstate so that it doesn't matter when initstate is called.
+ Returns a pointer to the old state. */
+int initstate_r (unsigned int seed, char *arg_state, size_t n, struct random_data *buf)
+{
+ int type;
+ int degree;
+ int separation;
+ int32_t *state;
+
+ if (buf == NULL)
+ goto fail;
+
+ if (n >= BREAK_3)
+ type = n < BREAK_4 ? TYPE_3 : TYPE_4;
+ else if (n < BREAK_1)
+ {
+ if (n < BREAK_0)
+ {
+ __set_errno (EINVAL);
+ goto fail;
+ }
+ type = TYPE_0;
+ }
+ else
+ type = n < BREAK_2 ? TYPE_1 : TYPE_2;
+
+ degree = random_poly_info.degrees[type];
+ separation = random_poly_info.seps[type];
+
+ buf->rand_type = type;
+ buf->rand_sep = separation;
+ buf->rand_deg = degree;
+ state = &((int32_t *) arg_state)[1]; /* First location. */
+ /* Must set END_PTR before srandom. */
+ buf->end_ptr = &state[degree];
+
+ buf->state = state;
+
+ srandom_r (seed, buf);
+
+ state[-1] = TYPE_0;
+ if (type != TYPE_0)
+ state[-1] = (buf->rptr - state) * MAX_TYPES + type;
+
+ return 0;
+
+fail:
+ __set_errno (EINVAL);
+ return -1;
+}
+libc_hidden_def(initstate_r)
+
+/* Restore the state from the given state array.
+ Note: It is important that we also remember the locations of the pointers
+ in the current state information, and restore the locations of the pointers
+ from the old state information. This is done by multiplexing the pointer
+ location into the zeroth word of the state information. Note that due
+ to the order in which things are done, it is OK to call setstate with the
+ same state as the current state
+ Returns a pointer to the old state information. */
+int setstate_r (char *arg_state, struct random_data *buf)
+{
+ int32_t *new_state = 1 + (int32_t *) arg_state;
+ int type;
+ int old_type;
+ int32_t *old_state;
+ int degree;
+ int separation;
+
+ if (arg_state == NULL || buf == NULL)
+ goto fail;
+
+ old_type = buf->rand_type;
+ old_state = buf->state;
+ if (old_type == TYPE_0)
+ old_state[-1] = TYPE_0;
+ else
+ old_state[-1] = (MAX_TYPES * (buf->rptr - old_state)) + old_type;
+
+ type = new_state[-1] % MAX_TYPES;
+ if (type < TYPE_0 || type > TYPE_4)
+ goto fail;
+
+ buf->rand_deg = degree = random_poly_info.degrees[type];
+ buf->rand_sep = separation = random_poly_info.seps[type];
+ buf->rand_type = type;
+
+ if (type != TYPE_0)
+ {
+ int rear = new_state[-1] / MAX_TYPES;
+ buf->rptr = &new_state[rear];
+ buf->fptr = &new_state[(rear + separation) % degree];
+ }
+ buf->state = new_state;
+ /* Set end_ptr too. */
+ buf->end_ptr = &new_state[degree];
+
+ return 0;
+
+fail:
+ __set_errno (EINVAL);
+ return -1;
+}
+libc_hidden_def(setstate_r)
diff --git a/ap/build/uClibc/libc/stdlib/realpath.c b/ap/build/uClibc/libc/stdlib/realpath.c
new file mode 100644
index 0000000..cf9d45f
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/realpath.c
@@ -0,0 +1,162 @@
+/*
+ * realpath.c -- canonicalize pathname by removing symlinks
+ * Copyright (C) 1993 Rick Sladkey <jrs@world.std.com>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <limits.h> /* for PATH_MAX */
+#include <sys/param.h> /* for MAXPATHLEN */
+#include <errno.h>
+#include <stdlib.h>
+
+#include <sys/stat.h> /* for S_IFLNK */
+
+
+#ifndef PATH_MAX
+#ifdef _POSIX_VERSION
+#define PATH_MAX _POSIX_PATH_MAX
+#else
+#ifdef MAXPATHLEN
+#define PATH_MAX MAXPATHLEN
+#else
+#define PATH_MAX 1024
+#endif
+#endif
+#endif
+
+#define MAX_READLINKS 32
+
+char *realpath(const char *path, char got_path[])
+{
+ char copy_path[PATH_MAX];
+ char *max_path, *new_path, *allocated_path;
+ size_t path_len;
+ int readlinks = 0;
+#ifdef S_IFLNK
+ int link_len;
+#endif
+
+ if (path == NULL) {
+ __set_errno(EINVAL);
+ return NULL;
+ }
+ if (*path == '\0') {
+ __set_errno(ENOENT);
+ return NULL;
+ }
+ /* Make a copy of the source path since we may need to modify it. */
+ path_len = strlen(path);
+ if (path_len >= PATH_MAX - 2) {
+ __set_errno(ENAMETOOLONG);
+ return NULL;
+ }
+ /* Copy so that path is at the end of copy_path[] */
+ strcpy(copy_path + (PATH_MAX-1) - path_len, path);
+ path = copy_path + (PATH_MAX-1) - path_len;
+ allocated_path = got_path ? NULL : (got_path = malloc(PATH_MAX));
+ max_path = got_path + PATH_MAX - 2; /* points to last non-NUL char */
+ new_path = got_path;
+ if (*path != '/') {
+ /* If it's a relative pathname use getcwd for starters. */
+ if (!getcwd(new_path, PATH_MAX - 1))
+ goto err;
+ new_path += strlen(new_path);
+ if (new_path[-1] != '/')
+ *new_path++ = '/';
+ } else {
+ *new_path++ = '/';
+ path++;
+ }
+ /* Expand each slash-separated pathname component. */
+ while (*path != '\0') {
+ /* Ignore stray "/". */
+ if (*path == '/') {
+ path++;
+ continue;
+ }
+ if (*path == '.') {
+ /* Ignore ".". */
+ if (path[1] == '\0' || path[1] == '/') {
+ path++;
+ continue;
+ }
+ if (path[1] == '.') {
+ if (path[2] == '\0' || path[2] == '/') {
+ path += 2;
+ /* Ignore ".." at root. */
+ if (new_path == got_path + 1)
+ continue;
+ /* Handle ".." by backing up. */
+ while ((--new_path)[-1] != '/');
+ continue;
+ }
+ }
+ }
+ /* Safely copy the next pathname component. */
+ while (*path != '\0' && *path != '/') {
+ if (new_path > max_path) {
+ __set_errno(ENAMETOOLONG);
+ err:
+ free(allocated_path);
+ return NULL;
+ }
+ *new_path++ = *path++;
+ }
+#ifdef S_IFLNK
+ /* Protect against infinite loops. */
+ if (readlinks++ > MAX_READLINKS) {
+ __set_errno(ELOOP);
+ goto err;
+ }
+ path_len = strlen(path);
+ /* See if last (so far) pathname component is a symlink. */
+ *new_path = '\0';
+ {
+ int sv_errno = errno;
+ link_len = readlink(got_path, copy_path, PATH_MAX - 1);
+ if (link_len < 0) {
+ /* EINVAL means the file exists but isn't a symlink. */
+ if (errno != EINVAL) {
+ goto err;
+ }
+ } else {
+ /* Safe sex check. */
+ if (path_len + link_len >= PATH_MAX - 2) {
+ __set_errno(ENAMETOOLONG);
+ goto err;
+ }
+ /* Note: readlink doesn't add the null byte. */
+ /* copy_path[link_len] = '\0'; - we don't need it too */
+ if (*copy_path == '/')
+ /* Start over for an absolute symlink. */
+ new_path = got_path;
+ else
+ /* Otherwise back up over this component. */
+ while (*(--new_path) != '/');
+ /* Prepend symlink contents to path. */
+ memmove(copy_path + (PATH_MAX-1) - link_len - path_len, copy_path, link_len);
+ path = copy_path + (PATH_MAX-1) - link_len - path_len;
+ }
+ __set_errno(sv_errno);
+ }
+#endif /* S_IFLNK */
+ *new_path++ = '/';
+ }
+ /* Delete trailing slash but don't whomp a lone slash. */
+ if (new_path != got_path + 1 && new_path[-1] == '/')
+ new_path--;
+ /* Make sure it's null terminated. */
+ *new_path = '\0';
+ return got_path;
+}
+libc_hidden_def(realpath)
diff --git a/ap/build/uClibc/libc/stdlib/seed48.c b/ap/build/uClibc/libc/stdlib/seed48.c
new file mode 100644
index 0000000..a62dc2e
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/seed48.c
@@ -0,0 +1,27 @@
+/* Copyright (C) 1995,1996,1997,1998,2001,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdlib.h>
+
+unsigned short int *
+seed48 (unsigned short int seed16v[3])
+{
+ (void) seed48_r (seed16v, &__libc_drand48_data);
+ return __libc_drand48_data.__old_x;
+}
diff --git a/ap/build/uClibc/libc/stdlib/seed48_r.c b/ap/build/uClibc/libc/stdlib/seed48_r.c
new file mode 100644
index 0000000..0d58722
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/seed48_r.c
@@ -0,0 +1,40 @@
+/* Copyright (C) 1995, 1997, 1998, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; 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 <limits.h>
+
+
+int seed48_r (unsigned short int seed16v[3], struct drand48_data *buffer)
+{
+ /* Save old value at a private place to be used as return value. */
+ memcpy (buffer->__old_x, buffer->__x, sizeof (buffer->__x));
+
+ /* Install new state. */
+ buffer->__x[2] = seed16v[2];
+ buffer->__x[1] = seed16v[1];
+ buffer->__x[0] = seed16v[0];
+ buffer->__a = 0x5deece66dull;
+ buffer->__c = 0xb;
+ buffer->__init = 1;
+
+ return 0;
+}
+libc_hidden_def(seed48_r)
diff --git a/ap/build/uClibc/libc/stdlib/setenv.c b/ap/build/uClibc/libc/stdlib/setenv.c
new file mode 100644
index 0000000..8da2fae
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/setenv.c
@@ -0,0 +1,183 @@
+/* Copyright (C) 1992,95,96,97,98,99,2000,2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA.
+
+ modified for uClibc by Erik Andersen <andersen@codepoet.org>
+*/
+
+#include <features.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+
+#include <bits/uClibc_mutex.h>
+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER);
+
+
+/* If this variable is not a null pointer we allocated the current
+ environment. */
+static char **last_environ;
+
+
+/* This function is used by `setenv' and `putenv'. The difference between
+ the two functions is that for the former must create a new string which
+ is then placed in the environment, while the argument of `putenv'
+ must be used directly. This is all complicated by the fact that we try
+ to reuse values once generated for a `setenv' call since we can never
+ free the strings. [in uclibc, we do not] */
+static int __add_to_environ(const char *name, const char *value,
+ int replace)
+{
+ register char **ep;
+ register size_t size;
+ char *var_val;
+ char **new_environ;
+ /* name may come from putenv() and thus may contain "=VAL" part */
+ const size_t namelen = strchrnul(name, '=') - name;
+ int rv = -1;
+
+ __UCLIBC_MUTEX_LOCK(mylock);
+
+ /* We have to get the pointer now that we have the lock and not earlier
+ since another thread might have created a new environment. */
+ ep = __environ;
+
+ size = 0;
+ if (ep != NULL) {
+ while (*ep != NULL) {
+ if (!strncmp(*ep, name, namelen) && (*ep)[namelen] == '=') {
+ /* Found */
+ if (!replace)
+ goto DONE_OK;
+ goto REPLACE;
+ }
+ ++size;
+ ++ep;
+ }
+ }
+
+ /* Not found, add at the end */
+
+ /* We allocated this space; we can extend it. */
+ new_environ = realloc(last_environ, (size + 2) * sizeof(char *));
+ if (new_environ == NULL) {
+ __set_errno(ENOMEM);
+ goto DONE;
+ }
+ if (__environ != last_environ) {
+ memcpy(new_environ, __environ, size * sizeof(char *));
+ }
+ last_environ = __environ = new_environ;
+
+ ep = &new_environ[size];
+ /* Ensure env is NULL terminated in case malloc below fails */
+ ep[0] = NULL;
+ ep[1] = NULL;
+
+ REPLACE:
+ var_val = (char*) name;
+ /* Build VAR=VAL if we called by setenv, not putenv. */
+ if (value != NULL) {
+ const size_t vallen = strlen(value) + 1;
+
+ var_val = malloc(namelen + 1 + vallen);
+ if (var_val == NULL) {
+ __set_errno(ENOMEM);
+ goto DONE;
+ }
+ memcpy(var_val, name, namelen);
+ var_val[namelen] = '=';
+ memcpy(&var_val[namelen + 1], value, vallen);
+ }
+ *ep = var_val;
+
+ DONE_OK:
+ rv = 0;
+
+ DONE:
+ __UCLIBC_MUTEX_UNLOCK(mylock);
+ return rv;
+}
+
+int setenv(const char *name, const char *value, int replace)
+{
+ /* NB: setenv("VAR", NULL, 1) inserts "VAR=" string */
+ return __add_to_environ(name, value ? value : "", replace);
+}
+libc_hidden_def(setenv)
+
+int unsetenv(const char *name)
+{
+ const char *eq;
+ size_t len;
+ char **ep;
+
+ if (name == NULL || *name == '\0'
+ || *(eq = strchrnul(name, '=')) == '='
+ ) {
+ __set_errno(EINVAL);
+ return -1;
+ }
+ len = eq - name; /* avoiding strlen this way */
+
+ __UCLIBC_MUTEX_LOCK(mylock);
+ ep = __environ;
+ /* NB: clearenv(); unsetenv("foo"); should not segfault */
+ if (ep) while (*ep != NULL) {
+ if (!strncmp(*ep, name, len) && (*ep)[len] == '=') {
+ /* Found it. Remove this pointer by moving later ones back. */
+ char **dp = ep;
+ do {
+ dp[0] = dp[1];
+ } while (*dp++);
+ /* Continue the loop in case NAME appears again. */
+ } else {
+ ++ep;
+ }
+ }
+ __UCLIBC_MUTEX_UNLOCK(mylock);
+ return 0;
+}
+libc_hidden_def(unsetenv)
+
+/* The `clearenv' was planned to be added to POSIX.1 but probably
+ never made it. Nevertheless the POSIX.9 standard (POSIX bindings
+ for Fortran 77) requires this function. */
+int clearenv(void)
+{
+ __UCLIBC_MUTEX_LOCK(mylock);
+ /* If we allocated this environment we can free it.
+ * If we did not allocate this environment, it's NULL already
+ * and is safe to free(). */
+ free(last_environ);
+ last_environ = NULL;
+ /* Clearing environ removes the whole environment. */
+ __environ = NULL;
+ __UCLIBC_MUTEX_UNLOCK(mylock);
+ return 0;
+}
+
+/* Put STRING, which is of the form "NAME=VALUE", in the environment. */
+int putenv(char *string)
+{
+ if (strchr(string, '=') != NULL) {
+ return __add_to_environ(string, NULL, 1);
+ }
+ return unsetenv(string);
+}
diff --git a/ap/build/uClibc/libc/stdlib/srand48.c b/ap/build/uClibc/libc/stdlib/srand48.c
new file mode 100644
index 0000000..f553743
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/srand48.c
@@ -0,0 +1,25 @@
+/* Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu <mailto:drepper@gnu.ai.mit.edu>>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdlib.h>
+
+void srand48 (long seedval)
+{
+ srand48_r (seedval, &__libc_drand48_data);
+}
diff --git a/ap/build/uClibc/libc/stdlib/srand48_r.c b/ap/build/uClibc/libc/stdlib/srand48_r.c
new file mode 100644
index 0000000..4347fef
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/srand48_r.c
@@ -0,0 +1,39 @@
+/* Copyright (C) 1995, 1996, 1997, 1998, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu <mailto:drepper@gnu.ai.mit.edu>>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdlib.h>
+#include <limits.h>
+
+int srand48_r (long int seedval, struct drand48_data *buffer)
+{
+ /* The standards say we only have 32 bits. */
+ if (sizeof (long int) > 4)
+ seedval &= 0xffffffffl;
+
+ buffer->__x[2] = seedval >> 16;
+ buffer->__x[1] = seedval & 0xffffl;
+ buffer->__x[0] = 0x330e;
+
+ buffer->__a = 0x5deece66dull;
+ buffer->__c = 0xb;
+ buffer->__init = 1;
+
+ return 0;
+}
+libc_hidden_def(srand48_r)
diff --git a/ap/build/uClibc/libc/stdlib/stdlib.c b/ap/build/uClibc/libc/stdlib/stdlib.c
new file mode 100644
index 0000000..9e8c347
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/stdlib.c
@@ -0,0 +1,1149 @@
+/* Copyright (C) 2002 Manuel Novoa III
+ * From my (incomplete) stdlib library for linux and (soon) elks.
+ *
+ * This library 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 library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION!
+ *
+ * This code is currently under development. Also, I plan to port
+ * it to elks which is a 16-bit environment with a fairly limited
+ * compiler. Therefore, please refrain from modifying this code
+ * and, instead, pass any bug-fixes, etc. to me. Thanks. Manuel
+ *
+ * ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION! */
+
+/* Oct 29, 2002
+ * Fix a couple of 'restrict' bugs in mbstowcs and wcstombs.
+ *
+ * Nov 21, 2002
+ * Add wscto{inttype} functions.
+ */
+
+#define _ISOC99_SOURCE /* for ULLONG primarily... */
+#include <limits.h>
+#include <stdint.h>
+/* Work around gcc's refusal to create aliases.
+ * TODO: Add in a define to disable the aliases? */
+
+#if UINT_MAX == ULONG_MAX
+#ifdef L_labs
+#define abs __ignore_abs
+#endif
+#ifdef L_atol
+#define atoi __ignore_atoi
+#endif
+#endif
+#if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)
+#ifdef L_labs
+#define llabs __ignore_llabs
+#endif
+#ifdef L_atol
+#define atoll __ignore_atoll
+#endif
+#ifdef L_strtol
+#define strtoll __ignore_strtoll
+#endif
+#ifdef L_strtoul
+#define strtoull __ignore_strtoull
+#endif
+#ifdef L_wcstol
+#define wcstoll __ignore_wcstoll
+#endif
+#ifdef L_wcstoul
+#define wcstoull __ignore_wcstoull
+#endif
+#ifdef L_strtol_l
+#define strtoll_l __ignore_strtoll_l
+#endif
+#ifdef L_strtoul_l
+#define strtoull_l __ignore_strtoull_l
+#endif
+#ifdef L_wcstol_l
+#define wcstoll_l __ignore_wcstoll_l
+#endif
+#ifdef L_wcstoul_l
+#define wcstoull_l __ignore_wcstoull_l
+#endif
+#endif
+#if defined(ULLONG_MAX) && (ULLONG_MAX == UINTMAX_MAX)
+#if defined L_labs || defined L_llabs
+#define imaxabs __ignore_imaxabs
+#endif
+#endif
+
+#include <stdint.h>
+#include <inttypes.h>
+#include <ctype.h>
+#include <errno.h>
+#include <assert.h>
+#include <unistd.h>
+
+#include <stdlib.h>
+#include <locale.h>
+
+#ifdef __UCLIBC_HAS_WCHAR__
+
+#include <wchar.h>
+#include <wctype.h>
+#include <bits/uClibc_uwchar.h>
+
+#ifdef __UCLIBC_HAS_XLOCALE__
+#include <xlocale.h>
+#endif /* __UCLIBC_HAS_XLOCALE__ */
+
+/* TODO: clean up the following... */
+
+#if WCHAR_MAX > 0xffffUL
+#define UTF_8_MAX_LEN 6
+#else
+#define UTF_8_MAX_LEN 3
+#endif
+
+#ifdef __UCLIBC_HAS_LOCALE__
+
+#define ENCODING (__UCLIBC_CURLOCALE->encoding)
+#ifndef __CTYPE_HAS_UTF_8_LOCALES
+#ifdef L_mblen
+/* emit only once */
+#warning __CTYPE_HAS_UTF_8_LOCALES not set!
+#endif
+#endif
+
+#else /* __UCLIBC_HAS_LOCALE__ */
+
+#ifdef __UCLIBC_MJN3_ONLY__
+#ifdef L_mblen
+/* emit only once */
+#warning devel checks
+#endif
+#endif
+#ifdef __CTYPE_HAS_8_BIT_LOCALES
+#error __CTYPE_HAS_8_BIT_LOCALES is defined!
+#endif
+#ifdef __CTYPE_HAS_UTF_8_LOCALES
+#error __CTYPE_HAS_UTF_8_LOCALES is defined!
+#endif
+#endif
+
+#endif /* __UCLIBC_HAS_LOCALE__ */
+
+/**********************************************************************/
+#ifdef __UCLIBC_HAS_XLOCALE__
+
+extern unsigned long
+_stdlib_strto_l_l(register const char * __restrict str,
+ char ** __restrict endptr, int base, int sflag,
+ __locale_t locale_arg) attribute_hidden;
+
+#if defined(ULLONG_MAX)
+extern unsigned long long
+_stdlib_strto_ll_l(register const char * __restrict str,
+ char ** __restrict endptr, int base, int sflag,
+ __locale_t locale_arg) attribute_hidden;
+#endif
+
+#ifdef __UCLIBC_HAS_WCHAR__
+extern unsigned long
+_stdlib_wcsto_l_l(register const wchar_t * __restrict str,
+ wchar_t ** __restrict endptr, int base, int sflag,
+ __locale_t locale_arg) attribute_hidden;
+
+#if defined(ULLONG_MAX)
+extern unsigned long long
+_stdlib_wcsto_ll_l(register const wchar_t * __restrict str,
+ wchar_t ** __restrict endptr, int base, int sflag,
+ __locale_t locale_arg) attribute_hidden;
+#endif
+#endif /* __UCLIBC_HAS_WCHAR__ */
+
+#endif /* __UCLIBC_HAS_XLOCALE__ */
+
+
+
+extern unsigned long
+_stdlib_strto_l(register const char * __restrict str,
+ char ** __restrict endptr, int base, int sflag) attribute_hidden;
+
+#if defined(ULLONG_MAX)
+extern unsigned long long
+_stdlib_strto_ll(register const char * __restrict str,
+ char ** __restrict endptr, int base, int sflag) attribute_hidden;
+#endif
+
+#ifdef __UCLIBC_HAS_WCHAR__
+extern unsigned long
+_stdlib_wcsto_l(register const wchar_t * __restrict str,
+ wchar_t ** __restrict endptr, int base, int sflag) attribute_hidden;
+
+#if defined(ULLONG_MAX)
+extern unsigned long long
+_stdlib_wcsto_ll(register const wchar_t * __restrict str,
+ wchar_t ** __restrict endptr, int base, int sflag) attribute_hidden;
+#endif
+#endif /* __UCLIBC_HAS_WCHAR__ */
+/**********************************************************************/
+#ifdef L_atof
+
+
+double atof(const char *nptr)
+{
+ return strtod(nptr, (char **) NULL);
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_abs
+
+#if INT_MAX < LONG_MAX
+
+int abs(int j)
+{
+ return (j >= 0) ? j : -j;
+}
+
+#endif /* INT_MAX < LONG_MAX */
+
+#endif
+/**********************************************************************/
+#ifdef L_labs
+
+long int labs(long int j)
+{
+ return (j >= 0) ? j : -j;
+}
+
+#if UINT_MAX == ULONG_MAX
+#undef abs
+extern __typeof(labs) abs;
+strong_alias(labs,abs)
+#endif
+
+#if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)
+#undef llabs
+extern __typeof(labs) llabs;
+strong_alias(labs,llabs)
+#endif
+
+#if ULONG_MAX == UINTMAX_MAX
+#undef imaxabs
+extern __typeof(labs) imaxabs;
+strong_alias(labs,imaxabs)
+#endif
+
+#endif
+/**********************************************************************/
+#ifdef L_llabs
+
+#if defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX)
+
+long long int llabs(long long int j)
+{
+ return (j >= 0) ? j : -j;
+}
+
+#if (ULLONG_MAX == UINTMAX_MAX)
+#undef imaxabs
+extern __typeof(llabs) imaxabs;
+strong_alias(llabs,imaxabs)
+#endif
+
+#endif /* defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) */
+
+#endif
+/**********************************************************************/
+#ifdef L_atoi
+
+#if INT_MAX < LONG_MAX
+
+
+int atoi(const char *nptr)
+{
+ return (int) strtol(nptr, (char **) NULL, 10);
+}
+libc_hidden_def(atoi)
+
+#endif /* INT_MAX < LONG_MAX */
+
+#endif
+/**********************************************************************/
+#ifdef L_atol
+
+
+long atol(const char *nptr)
+{
+ return strtol(nptr, (char **) NULL, 10);
+}
+
+#if UINT_MAX == ULONG_MAX
+#undef atoi
+extern __typeof(atol) atoi;
+/* the one in stdlib.h is not enough due to prototype mismatch */
+libc_hidden_proto(atoi)
+strong_alias(atol,atoi)
+libc_hidden_def(atoi)
+#endif
+
+#if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)
+#undef atoll
+extern __typeof(atol) atoll;
+strong_alias(atol,atoll)
+#endif
+
+#endif
+/**********************************************************************/
+#ifdef L_atoll
+
+#if defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX)
+
+
+long long atoll(const char *nptr)
+{
+ return strtoll(nptr, (char **) NULL, 10);
+}
+
+#endif /* defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) */
+
+#endif
+/**********************************************************************/
+#if defined(L_strtol) || defined(L_strtol_l)
+
+libc_hidden_proto(__XL_NPP(strtol))
+long __XL_NPP(strtol)(const char * __restrict str, char ** __restrict endptr,
+ int base __LOCALE_PARAM)
+{
+ return __XL_NPP(_stdlib_strto_l)(str, endptr, base, 1 __LOCALE_ARG);
+}
+libc_hidden_def(__XL_NPP(strtol))
+
+#if (ULONG_MAX == UINTMAX_MAX) && !defined(L_strtol_l)
+strong_alias(strtol,strtoimax)
+#endif
+
+#if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)
+#ifdef L_strtol_l
+#undef strtoll_l
+#else
+#undef strtoll
+#endif
+extern __typeof(__XL_NPP(strtol)) __XL_NPP(strtoll);
+/* the one in stdlib.h is not enough due to prototype mismatch */
+#ifdef L_strtol
+libc_hidden_proto(__XL_NPP(strtoll))
+#endif
+strong_alias(__XL_NPP(strtol),__XL_NPP(strtoll))
+#ifdef L_strtol
+libc_hidden_def(__XL_NPP(strtoll))
+strong_alias(strtol,strtoq)
+#endif
+#endif
+
+#endif
+/**********************************************************************/
+#if defined(L_strtoll) || defined(L_strtoll_l)
+
+#if defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX)
+
+long long __XL_NPP(strtoll)(const char * __restrict str,
+ char ** __restrict endptr, int base
+ __LOCALE_PARAM)
+{
+ return (long long) __XL_NPP(_stdlib_strto_ll)(str, endptr, base, 1 __LOCALE_ARG);
+}
+#ifdef L_strtoll
+libc_hidden_def(__XL_NPP(strtoll))
+#if (ULLONG_MAX == UINTMAX_MAX)
+strong_alias(strtoll,strtoimax)
+#endif
+strong_alias(strtoll,strtoq)
+#endif
+
+#endif /* defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) */
+
+#endif
+/**********************************************************************/
+#if defined(L_strtoul) || defined(L_strtoul_l)
+
+unsigned long __XL_NPP(strtoul)(const char * __restrict str,
+ char ** __restrict endptr, int base
+ __LOCALE_PARAM)
+{
+ return __XL_NPP(_stdlib_strto_l)(str, endptr, base, 0 __LOCALE_ARG);
+}
+libc_hidden_def(__XL_NPP(strtoul))
+
+#if (ULONG_MAX == UINTMAX_MAX) && !defined(L_strtoul_l)
+strong_alias(strtoul,strtoumax)
+#endif
+
+#if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)
+#ifdef L_strtoul_l
+#undef strtoull_l
+#else
+#undef strtoull
+#endif
+extern __typeof(__XL_NPP(strtoul)) __XL_NPP(strtoull);
+strong_alias(__XL_NPP(strtoul),__XL_NPP(strtoull))
+#if !defined(L_strtoul_l)
+strong_alias(strtoul,strtouq)
+#endif
+#endif
+
+
+#endif
+/**********************************************************************/
+#if defined(L_strtoull) || defined(L_strtoull_l)
+
+#if defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX)
+
+unsigned long long __XL_NPP(strtoull)(const char * __restrict str,
+ char ** __restrict endptr, int base
+ __LOCALE_PARAM)
+{
+ return __XL_NPP(_stdlib_strto_ll)(str, endptr, base, 0 __LOCALE_ARG);
+}
+
+#if !defined(L_strtoull_l)
+#if (ULLONG_MAX == UINTMAX_MAX)
+strong_alias(strtoull,strtoumax)
+#endif
+strong_alias(strtoull,strtouq)
+#endif
+
+#endif /* defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) */
+
+#endif
+/**********************************************************************/
+/* Support routines follow */
+/**********************************************************************/
+/* Set if we want errno set appropriately. */
+/* NOTE: Implies _STRTO_ENDPTR below */
+#define _STRTO_ERRNO 1
+
+/* Set if we want support for the endptr arg. */
+/* Implied by _STRTO_ERRNO. */
+#define _STRTO_ENDPTR 1
+
+#if _STRTO_ERRNO
+#undef _STRTO_ENDPTR
+#define _STRTO_ENDPTR 1
+#define SET_ERRNO(X) __set_errno(X)
+#else
+#define SET_ERRNO(X) ((void)(X)) /* keep side effects */
+#endif
+
+/**********************************************************************/
+#if defined(L__stdlib_wcsto_l) || defined(L__stdlib_wcsto_l_l)
+#ifndef L__stdlib_strto_l
+#define L__stdlib_strto_l
+#endif
+#endif
+
+#if defined(L__stdlib_strto_l) || defined(L__stdlib_strto_l_l)
+
+#if defined(L__stdlib_wcsto_l) || defined(L__stdlib_wcsto_l_l)
+
+#define _stdlib_strto_l _stdlib_wcsto_l
+#define _stdlib_strto_l_l _stdlib_wcsto_l_l
+#define Wchar wchar_t
+#define Wuchar __uwchar_t
+#ifdef __UCLIBC_DO_XLOCALE
+#define ISSPACE(C) iswspace_l((C), locale_arg)
+#else
+#define ISSPACE(C) iswspace((C))
+#endif
+
+#else /* defined(L__stdlib_wcsto_l) || defined(L__stdlib_wcsto_l_l) */
+
+#define Wchar char
+#define Wuchar unsigned char
+#ifdef __UCLIBC_DO_XLOCALE
+#define ISSPACE(C) isspace_l((C), locale_arg)
+#else
+#define ISSPACE(C) isspace((C))
+#endif
+
+#endif /* defined(L__stdlib_wcsto_l) || defined(L__stdlib_wcsto_l_l) */
+
+#if defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE)
+
+unsigned long attribute_hidden _stdlib_strto_l(register const Wchar * __restrict str,
+ Wchar ** __restrict endptr, int base,
+ int sflag)
+{
+ return _stdlib_strto_l_l(str, endptr, base, sflag, __UCLIBC_CURLOCALE);
+}
+
+
+#else /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
+
+/* This is the main work fuction which handles both strtol (sflag = 1) and
+ * strtoul (sflag = 0). */
+
+unsigned long attribute_hidden __XL_NPP(_stdlib_strto_l)(register const Wchar * __restrict str,
+ Wchar ** __restrict endptr, int base,
+ int sflag __LOCALE_PARAM)
+{
+ unsigned long number, cutoff;
+#if _STRTO_ENDPTR
+ const Wchar *fail_char;
+#define SET_FAIL(X) fail_char = (X)
+#else
+#define SET_FAIL(X) ((void)(X)) /* Keep side effects. */
+#endif
+ unsigned char negative, digit, cutoff_digit;
+
+ assert(((unsigned int)sflag) <= 1);
+
+ SET_FAIL(str);
+
+ while (ISSPACE(*str)) { /* Skip leading whitespace. */
+ ++str;
+ }
+
+ /* Handle optional sign. */
+ negative = 0;
+ switch (*str) {
+ case '-': negative = 1; /* Fall through to increment str. */
+ case '+': ++str;
+ }
+
+ if (!(base & ~0x10)) { /* Either dynamic (base = 0) or base 16. */
+ base += 10; /* Default is 10 (26). */
+ if (*str == '0') {
+ SET_FAIL(++str);
+ base -= 2; /* Now base is 8 or 16 (24). */
+ if ((0x20|(*str)) == 'x') { /* WARNING: assumes ascii. */
+ ++str;
+ base += base; /* Base is 16 (16 or 48). */
+ }
+ }
+
+ if (base > 16) { /* Adjust in case base wasn't dynamic. */
+ base = 16;
+ }
+ }
+
+ number = 0;
+
+ if (((unsigned)(base - 2)) < 35) { /* Legal base. */
+ cutoff_digit = ULONG_MAX % base;
+ cutoff = ULONG_MAX / base;
+ do {
+ digit = ((Wuchar)(*str - '0') <= 9)
+ ? /* 0..9 */ (*str - '0')
+ : /* else */ (((Wuchar)(0x20 | *str) >= 'a') /* WARNING: assumes ascii. */
+ ? /* >= A/a */ ((Wuchar)(0x20 | *str) - ('a' - 10))
+ : /* else */ 40 /* bad value */);
+
+ if (digit >= base) {
+ break;
+ }
+
+ SET_FAIL(++str);
+
+ if ((number > cutoff)
+ || ((number == cutoff) && (digit > cutoff_digit))) {
+ number = ULONG_MAX;
+ negative &= sflag;
+ SET_ERRNO(ERANGE);
+ } else {
+ number = number * base + digit;
+ }
+ } while (1);
+ }
+
+#if _STRTO_ENDPTR
+ if (endptr) {
+ *endptr = (Wchar *) fail_char;
+ }
+#endif
+
+ {
+ unsigned long tmp = (negative
+ ? ((unsigned long)(-(1+LONG_MIN)))+1
+ : LONG_MAX);
+ if (sflag && (number > tmp)) {
+ number = tmp;
+ SET_ERRNO(ERANGE);
+ }
+ }
+
+ return negative ? (unsigned long)(-((long)number)) : number;
+}
+
+#endif /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
+
+
+#endif
+/**********************************************************************/
+#if defined(L__stdlib_wcsto_ll) || defined(L__stdlib_wcsto_ll_l)
+#ifndef L__stdlib_strto_ll
+#define L__stdlib_strto_ll
+#endif
+#endif
+
+#if defined(L__stdlib_strto_ll) || defined(L__stdlib_strto_ll_l)
+
+#if defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX)
+
+#if defined(L__stdlib_wcsto_ll) || defined(L__stdlib_wcsto_ll_l)
+#define _stdlib_strto_ll _stdlib_wcsto_ll
+#define _stdlib_strto_ll_l _stdlib_wcsto_ll_l
+#define Wchar wchar_t
+#define Wuchar __uwchar_t
+#ifdef __UCLIBC_DO_XLOCALE
+#define ISSPACE(C) iswspace_l((C), locale_arg)
+#else
+#define ISSPACE(C) iswspace((C))
+#endif
+
+#else /* defined(L__stdlib_wcsto_ll) || defined(L__stdlib_wcsto_ll_l) */
+
+#define Wchar char
+#define Wuchar unsigned char
+#ifdef __UCLIBC_DO_XLOCALE
+#define ISSPACE(C) isspace_l((C), locale_arg)
+#else
+#define ISSPACE(C) isspace((C))
+#endif
+
+#endif /* defined(L__stdlib_wcsto_ll) || defined(L__stdlib_wcsto_ll_l) */
+
+#if defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE)
+
+unsigned long long attribute_hidden _stdlib_strto_ll(register const Wchar * __restrict str,
+ Wchar ** __restrict endptr, int base,
+ int sflag)
+{
+ return _stdlib_strto_ll_l(str, endptr, base, sflag, __UCLIBC_CURLOCALE);
+}
+
+
+#else /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
+
+/* This is the main work fuction which handles both strtoll (sflag = 1) and
+ * strtoull (sflag = 0). */
+
+unsigned long long attribute_hidden __XL_NPP(_stdlib_strto_ll)(register const Wchar * __restrict str,
+ Wchar ** __restrict endptr, int base,
+ int sflag __LOCALE_PARAM)
+{
+ unsigned long long number;
+#if _STRTO_ENDPTR
+ const Wchar *fail_char;
+#define SET_FAIL(X) fail_char = (X)
+#else
+#define SET_FAIL(X) ((void)(X)) /* Keep side effects. */
+#endif
+ unsigned int n1;
+ unsigned char negative, digit;
+
+ assert(((unsigned int)sflag) <= 1);
+
+ SET_FAIL(str);
+
+ while (ISSPACE(*str)) { /* Skip leading whitespace. */
+ ++str;
+ }
+
+ /* Handle optional sign. */
+ negative = 0;
+ switch (*str) {
+ case '-': negative = 1; /* Fall through to increment str. */
+ case '+': ++str;
+ }
+
+ if (!(base & ~0x10)) { /* Either dynamic (base = 0) or base 16. */
+ base += 10; /* Default is 10 (26). */
+ if (*str == '0') {
+ SET_FAIL(++str);
+ base -= 2; /* Now base is 8 or 16 (24). */
+ if ((0x20|(*str)) == 'x') { /* WARNING: assumes ascii. */
+ ++str;
+ base += base; /* Base is 16 (16 or 48). */
+ }
+ }
+
+ if (base > 16) { /* Adjust in case base wasn't dynamic. */
+ base = 16;
+ }
+ }
+
+ number = 0;
+
+ if (((unsigned)(base - 2)) < 35) { /* Legal base. */
+ do {
+ digit = ((Wuchar)(*str - '0') <= 9)
+ ? /* 0..9 */ (*str - '0')
+ : /* else */ (((Wuchar)(0x20 | *str) >= 'a') /* WARNING: assumes ascii. */
+ ? /* >= A/a */ ((Wuchar)(0x20 | *str) - ('a' - 10))
+ : /* else */ 40 /* bad value */);
+
+ if (digit >= base) {
+ break;
+ }
+
+ SET_FAIL(++str);
+
+#if 1
+ /* Optional, but speeds things up in the usual case. */
+ if (number <= (ULLONG_MAX >> 6)) {
+ number = number * base + digit;
+ } else
+#endif
+ {
+ n1 = ((unsigned char) number) * base + digit;
+ number = (number >> CHAR_BIT) * base;
+
+ if (number + (n1 >> CHAR_BIT) <= (ULLONG_MAX >> CHAR_BIT)) {
+ number = (number << CHAR_BIT) + n1;
+ } else { /* Overflow. */
+ number = ULLONG_MAX;
+ negative &= sflag;
+ SET_ERRNO(ERANGE);
+ }
+ }
+
+ } while (1);
+ }
+
+#if _STRTO_ENDPTR
+ if (endptr) {
+ *endptr = (Wchar *) fail_char;
+ }
+#endif
+
+ {
+ unsigned long long tmp = ((negative)
+ ? ((unsigned long long)(-(1+LLONG_MIN)))+1
+ : LLONG_MAX);
+ if (sflag && (number > tmp)) {
+ number = tmp;
+ SET_ERRNO(ERANGE);
+ }
+ }
+
+ return negative ? (unsigned long long)(-((long long)number)) : number;
+}
+
+#endif /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
+
+#endif /* defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) */
+
+#endif
+/**********************************************************************/
+/* Made _Exit() an alias for _exit(), as per C99. */
+/* #ifdef L__Exit */
+/* void _Exit(int status) */
+/* { */
+/* _exit(status); */
+/* } */
+
+/* #endif */
+/**********************************************************************/
+#ifdef L_bsearch
+
+void *bsearch(const void *key, const void *base, size_t /* nmemb */ high,
+ size_t size, int (*compar)(const void *, const void *))
+{
+ register char *p;
+ size_t low;
+ size_t mid;
+ int r;
+
+ if (size > 0) { /* TODO: change this to an assert?? */
+ low = 0;
+ while (low < high) {
+ mid = low + ((high - low) >> 1); /* Avoid possible overflow here. */
+ p = ((char *)base) + mid * size; /* Could overflow here... */
+ r = (*compar)(key, p); /* but that's an application problem! */
+ if (r > 0) {
+ low = mid + 1;
+ } else if (r < 0) {
+ high = mid;
+ } else {
+ return p;
+ }
+ }
+ }
+ return NULL;
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_qsort_r
+
+/* This code is derived from a public domain shell sort routine by
+ * Ray Gardner and found in Bob Stout's snippets collection. The
+ * original code is included below in an #if 0/#endif block.
+ *
+ * I modified it to avoid the possibility of overflow in the wgap
+ * calculation, as well as to reduce the generated code size with
+ * bcc and gcc. */
+
+void qsort_r(void *base,
+ size_t nel,
+ size_t width,
+ __compar_d_fn_t comp,
+ void *arg)
+{
+ size_t wgap, i, j, k;
+ char tmp;
+
+ if ((nel > 1) && (width > 0)) {
+ assert(nel <= ((size_t)(-1)) / width); /* check for overflow */
+ wgap = 0;
+ do {
+ wgap = 3 * wgap + 1;
+ } while (wgap < (nel-1)/3);
+ /* From the above, we know that either wgap == 1 < nel or */
+ /* ((wgap-1)/3 < (int) ((nel-1)/3) <= (nel-1)/3 ==> wgap < nel. */
+ wgap *= width; /* So this can not overflow if wnel doesn't. */
+ nel *= width; /* Convert nel to 'wnel' */
+ do {
+ i = wgap;
+ do {
+ j = i;
+ do {
+ register char *a;
+ register char *b;
+
+ j -= wgap;
+ a = j + ((char *)base);
+ b = a + wgap;
+ if ((*comp)(a, b, arg) <= 0) {
+ break;
+ }
+ k = width;
+ do {
+ tmp = *a;
+ *a++ = *b;
+ *b++ = tmp;
+ } while (--k);
+ } while (j >= wgap);
+ i += width;
+ } while (i < nel);
+ wgap = (wgap - width)/3;
+ } while (wgap);
+ }
+}
+libc_hidden_def(qsort_r)
+
+/* ---------- original snippets version below ---------- */
+
+#if 0
+/*
+** ssort() -- Fast, small, qsort()-compatible Shell sort
+**
+** by Ray Gardner, public domain 5/90
+*/
+
+#include <stddef.h>
+
+void ssort(void *base,
+ size_t nel,
+ size_t width,
+ int (*comp)(const void *, const void *))
+{
+ size_t wnel, gap, wgap, i, j, k;
+ char *a, *b, tmp;
+
+ wnel = width * nel;
+ for (gap = 0; ++gap < nel;)
+ gap *= 3;
+ while ((gap /= 3) != 0) {
+ wgap = width * gap;
+ for (i = wgap; i < wnel; i += width) {
+ for (j = i - wgap; ;j -= wgap) {
+ a = j + (char *)base;
+ b = a + wgap;
+ if ((*comp)(a, b) <= 0)
+ break;
+ k = width;
+ do {
+ tmp = *a;
+ *a++ = *b;
+ *b++ = tmp;
+ } while (--k);
+ if (j < wgap)
+ break;
+ }
+ }
+ }
+}
+#endif
+
+#endif
+
+#ifdef L_qsort
+void qsort(void *base,
+ size_t nel,
+ size_t width,
+ __compar_fn_t comp)
+{
+ return qsort_r (base, nel, width, (__compar_d_fn_t) comp, NULL);
+}
+libc_hidden_def(qsort)
+#endif
+
+/**********************************************************************/
+#ifdef L__stdlib_mb_cur_max
+
+size_t _stdlib_mb_cur_max(void)
+{
+#ifdef __CTYPE_HAS_UTF_8_LOCALES
+ return __UCLIBC_CURLOCALE->mb_cur_max;
+#else
+#ifdef __CTYPE_HAS_8_BIT_LOCALES
+#ifdef __UCLIBC_MJN3_ONLY__
+#warning need to change this when/if transliteration is implemented
+#endif
+#endif
+ return 1;
+#endif
+}
+libc_hidden_def(_stdlib_mb_cur_max)
+
+#endif
+
+#ifdef __UCLIBC_HAS_LOCALE__
+/*
+ * The following function return 1 if the encoding is stateful, 0 if stateless.
+ * To note, until now all the supported encoding are stateless.
+ */
+
+static __always_inline int is_stateful(unsigned char encoding)
+{
+ switch (encoding)
+ {
+ case __ctype_encoding_7_bit:
+ case __ctype_encoding_utf8:
+ case __ctype_encoding_8_bit:
+ return 0;
+ default:
+ assert(0);
+ return -1;
+ }
+}
+#else
+#define is_stateful(encoding) 0
+#endif
+
+/**********************************************************************/
+#ifdef L_mblen
+
+
+int mblen(register const char *s, size_t n)
+{
+ static mbstate_t state;
+ size_t r;
+
+ if (!s) {
+ state.__mask = 0;
+ /*
+ In this case we have to return 0 because the only multibyte supported encoding
+ is utf-8, that is a stateless encoding. See mblen() documentation.
+ */
+ return is_stateful(ENCODING);
+ }
+
+ if (*s == '\0')
+ /* According to the ISO C 89 standard this is the expected behaviour. */
+ return 0;
+
+ if ((r = mbrlen(s, n, &state)) == (size_t) -2) {
+ /* TODO: Should we set an error state? */
+ state.__wc = 0xffffU; /* Make sure we're in an error state. */
+ return -1; /* TODO: Change error code above? */
+ }
+ return r;
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_mbtowc
+
+
+int mbtowc(wchar_t *__restrict pwc, register const char *__restrict s, size_t n)
+{
+ static mbstate_t state;
+ size_t r;
+
+ if (!s) {
+ state.__mask = 0;
+ /*
+ In this case we have to return 0 because the only multibyte supported encoding
+ is utf-8, that is a stateless encoding. See mbtowc() documentation.
+ */
+
+ return is_stateful(ENCODING);
+ }
+
+ if (*s == '\0')
+ /* According to the ISO C 89 standard this is the expected behaviour. */
+ return 0;
+
+ if ((r = mbrtowc(pwc, s, n, &state)) == (size_t) -2) {
+ /* TODO: Should we set an error state? */
+ state.__wc = 0xffffU; /* Make sure we're in an error state. */
+ return -1; /* TODO: Change error code above? */
+ }
+ return r;
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_wctomb
+
+/* Note: We completely ignore state in all currently supported conversions. */
+
+
+int wctomb(register char *__restrict s, wchar_t swc)
+{
+ return (!s)
+ ?
+ /*
+ In this case we have to return 0 because the only multibyte supported encoding
+ is utf-8, that is a stateless encoding. See wctomb() documentation.
+ */
+
+ is_stateful(ENCODING)
+ : ((ssize_t) wcrtomb(s, swc, NULL));
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_mbstowcs
+
+
+size_t mbstowcs(wchar_t * __restrict pwcs, const char * __restrict s, size_t n)
+{
+ mbstate_t state;
+ const char *e = s; /* Needed because of restrict. */
+
+ state.__mask = 0; /* Always start in initial shift state. */
+ return mbsrtowcs(pwcs, &e, n, &state);
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_wcstombs
+
+/* Note: We completely ignore state in all currently supported conversions. */
+
+
+size_t wcstombs(char * __restrict s, const wchar_t * __restrict pwcs, size_t n)
+{
+ const wchar_t *e = pwcs; /* Needed because of restrict. */
+
+ return wcsrtombs(s, &e, n, NULL);
+}
+
+#endif
+/**********************************************************************/
+#if defined(L_wcstol) || defined(L_wcstol_l)
+
+long __XL_NPP(wcstol)(const wchar_t * __restrict str,
+ wchar_t ** __restrict endptr, int base __LOCALE_PARAM)
+{
+ return __XL_NPP(_stdlib_wcsto_l)(str, endptr, base, 1 __LOCALE_ARG);
+}
+
+#if (ULONG_MAX == UINTMAX_MAX) && !defined(L_wcstol_l)
+strong_alias(wcstol,wcstoimax)
+#endif
+
+#if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)
+#ifdef L_wcstol_l
+#undef wcstoll_l
+#else
+#undef wcstoll
+#endif
+extern __typeof(__XL_NPP(wcstol)) __XL_NPP(wcstoll);
+strong_alias(__XL_NPP(wcstol),__XL_NPP(wcstoll))
+#endif
+
+#endif
+/**********************************************************************/
+#if defined(L_wcstoll) || defined(L_wcstoll_l)
+
+#if defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX)
+
+long long __XL_NPP(wcstoll)(const wchar_t * __restrict str,
+ wchar_t ** __restrict endptr, int base
+ __LOCALE_PARAM)
+{
+ return (long long) __XL_NPP(_stdlib_wcsto_ll)(str, endptr, base, 1 __LOCALE_ARG);
+}
+
+#if !defined(L_wcstoll_l)
+#if (ULLONG_MAX == UINTMAX_MAX)
+strong_alias(wcstoll,wcstoimax)
+#endif
+strong_alias(wcstoll,wcstoq)
+#endif
+
+#endif /* defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) */
+
+#endif
+/**********************************************************************/
+#if defined(L_wcstoul) || defined(L_wcstoul_l)
+
+unsigned long __XL_NPP(wcstoul)(const wchar_t * __restrict str,
+ wchar_t ** __restrict endptr, int base
+ __LOCALE_PARAM)
+{
+ return __XL_NPP(_stdlib_wcsto_l)(str, endptr, base, 0 __LOCALE_ARG);
+}
+
+#if (ULONG_MAX == UINTMAX_MAX) && !defined(L_wcstoul_l)
+strong_alias(wcstoul,wcstoumax)
+#endif
+
+#if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)
+#ifdef L_wcstoul_l
+#undef wcstoull_l
+#else
+#undef wcstoull
+#endif
+extern __typeof(__XL_NPP(wcstoul)) __XL_NPP(wcstoull);
+strong_alias(__XL_NPP(wcstoul),__XL_NPP(wcstoull))
+#endif
+
+#endif
+/**********************************************************************/
+#if defined(L_wcstoull) || defined(L_wcstoull_l)
+
+#if defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX)
+
+unsigned long long __XL_NPP(wcstoull)(const wchar_t * __restrict str,
+ wchar_t ** __restrict endptr, int base
+ __LOCALE_PARAM)
+{
+ return __XL_NPP(_stdlib_wcsto_ll)(str, endptr, base, 0 __LOCALE_ARG);
+}
+
+#if !defined(L_wcstoull_l)
+#if (ULLONG_MAX == UINTMAX_MAX)
+strong_alias(wcstoull,wcstoumax)
+#endif
+strong_alias(wcstoull,wcstouq)
+#endif
+
+#endif /* defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) */
+
+#endif
+/**********************************************************************/
diff --git a/ap/build/uClibc/libc/stdlib/strtod.c b/ap/build/uClibc/libc/stdlib/strtod.c
new file mode 100644
index 0000000..7f59aef
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/strtod.c
@@ -0,0 +1,8 @@
+/*
+ * Copyright (C) 2000-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_strtod
+#include "_strtod.c"
diff --git a/ap/build/uClibc/libc/stdlib/strtod_l.c b/ap/build/uClibc/libc/stdlib/strtod_l.c
new file mode 100644
index 0000000..4131242
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/strtod_l.c
@@ -0,0 +1,9 @@
+/*
+ * Copyright (C) 2000-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_strtod_l
+#define __UCLIBC_DO_XLOCALE
+#include "_strtod.c"
diff --git a/ap/build/uClibc/libc/stdlib/strtof.c b/ap/build/uClibc/libc/stdlib/strtof.c
new file mode 100644
index 0000000..35e8977
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/strtof.c
@@ -0,0 +1,8 @@
+/*
+ * Copyright (C) 2000-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_strtof
+#include "_strtod.c"
diff --git a/ap/build/uClibc/libc/stdlib/strtof_l.c b/ap/build/uClibc/libc/stdlib/strtof_l.c
new file mode 100644
index 0000000..7b44d1b
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/strtof_l.c
@@ -0,0 +1,9 @@
+/*
+ * Copyright (C) 2000-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_strtof_l
+#define __UCLIBC_DO_XLOCALE
+#include "_strtod.c"
diff --git a/ap/build/uClibc/libc/stdlib/strtol.c b/ap/build/uClibc/libc/stdlib/strtol.c
new file mode 100644
index 0000000..cee4e13
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/strtol.c
@@ -0,0 +1,7 @@
+/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_strtol
+#include "stdlib.c"
diff --git a/ap/build/uClibc/libc/stdlib/strtol_l.c b/ap/build/uClibc/libc/stdlib/strtol_l.c
new file mode 100644
index 0000000..d59c1e5
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/strtol_l.c
@@ -0,0 +1,8 @@
+/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_strtol_l
+#define __UCLIBC_DO_XLOCALE
+#include "stdlib.c"
diff --git a/ap/build/uClibc/libc/stdlib/strtold.c b/ap/build/uClibc/libc/stdlib/strtold.c
new file mode 100644
index 0000000..91a3ba7
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/strtold.c
@@ -0,0 +1,8 @@
+/*
+ * Copyright (C) 2000-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_strtold
+#include "_strtod.c"
diff --git a/ap/build/uClibc/libc/stdlib/strtold_l.c b/ap/build/uClibc/libc/stdlib/strtold_l.c
new file mode 100644
index 0000000..7eccd00
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/strtold_l.c
@@ -0,0 +1,9 @@
+/*
+ * Copyright (C) 2000-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_strtold_l
+#define __UCLIBC_DO_XLOCALE
+#include "_strtod.c"
diff --git a/ap/build/uClibc/libc/stdlib/strtoll.c b/ap/build/uClibc/libc/stdlib/strtoll.c
new file mode 100644
index 0000000..a9c7c83
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/strtoll.c
@@ -0,0 +1,7 @@
+/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_strtoll
+#include "stdlib.c"
diff --git a/ap/build/uClibc/libc/stdlib/strtoll_l.c b/ap/build/uClibc/libc/stdlib/strtoll_l.c
new file mode 100644
index 0000000..9fa46bd
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/strtoll_l.c
@@ -0,0 +1,8 @@
+/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_strtoll_l
+#define __UCLIBC_DO_XLOCALE
+#include "stdlib.c"
diff --git a/ap/build/uClibc/libc/stdlib/strtoul.c b/ap/build/uClibc/libc/stdlib/strtoul.c
new file mode 100644
index 0000000..e92d246
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/strtoul.c
@@ -0,0 +1,7 @@
+/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_strtoul
+#include "stdlib.c"
diff --git a/ap/build/uClibc/libc/stdlib/strtoul_l.c b/ap/build/uClibc/libc/stdlib/strtoul_l.c
new file mode 100644
index 0000000..2aef138
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/strtoul_l.c
@@ -0,0 +1,8 @@
+/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_strtoul_l
+#define __UCLIBC_DO_XLOCALE
+#include "stdlib.c"
diff --git a/ap/build/uClibc/libc/stdlib/strtoull.c b/ap/build/uClibc/libc/stdlib/strtoull.c
new file mode 100644
index 0000000..60b626f
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/strtoull.c
@@ -0,0 +1,7 @@
+/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_strtoull
+#include "stdlib.c"
diff --git a/ap/build/uClibc/libc/stdlib/strtoull_l.c b/ap/build/uClibc/libc/stdlib/strtoull_l.c
new file mode 100644
index 0000000..81e045a
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/strtoull_l.c
@@ -0,0 +1,8 @@
+/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_strtoull_l
+#define __UCLIBC_DO_XLOCALE
+#include "stdlib.c"
diff --git a/ap/build/uClibc/libc/stdlib/system.c b/ap/build/uClibc/libc/stdlib/system.c
new file mode 100644
index 0000000..a92c307
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/system.c
@@ -0,0 +1,273 @@
+/*
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stddef.h>
+#include <signal.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <stdlib.h>
+#ifdef __UCLIBC_HAS_THREADS_NATIVE__
+#include <sched.h>
+#include <errno.h>
+#include <bits/libc-lock.h>
+#include <sysdep-cancel.h>
+#endif
+
+extern __typeof(system) __libc_system;
+
+/* TODO: the cancellable version breaks on sparc currently,
+ * need to figure out why still
+ */
+#if !defined __UCLIBC_HAS_THREADS_NATIVE__ || defined __sparc__
+/* uClinux-2.0 has vfork, but Linux 2.0 doesn't */
+#include <sys/syscall.h>
+#ifndef __NR_vfork
+# define vfork fork
+#endif
+
+int __libc_system(const char *command)
+{
+ int wait_val, pid;
+ struct sigaction sa, save_quit, save_int;
+ sigset_t save_mask;
+
+ if (command == 0)
+ return 1;
+
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = SIG_IGN;
+ /* __sigemptyset(&sa.sa_mask); - done by memset() */
+ /* sa.sa_flags = 0; - done by memset() */
+
+ sigaction(SIGQUIT, &sa, &save_quit);
+ sigaction(SIGINT, &sa, &save_int);
+ __sigaddset(&sa.sa_mask, SIGCHLD);
+ sigprocmask(SIG_BLOCK, &sa.sa_mask, &save_mask);
+
+ if ((pid = vfork()) < 0) {
+ wait_val = -1;
+ goto out;
+ }
+ if (pid == 0) {
+ sigaction(SIGQUIT, &save_quit, NULL);
+ sigaction(SIGINT, &save_int, NULL);
+ sigprocmask(SIG_SETMASK, &save_mask, NULL);
+
+ execl("/bin/sh", "sh", "-c", command, (char *) 0);
+ _exit(127);
+ }
+
+#if 0
+ __printf("Waiting for child %d\n", pid);
+#endif
+
+ if (wait4(pid, &wait_val, 0, 0) == -1)
+ wait_val = -1;
+
+out:
+ sigaction(SIGQUIT, &save_quit, NULL);
+ sigaction(SIGINT, &save_int, NULL);
+ sigprocmask(SIG_SETMASK, &save_mask, NULL);
+ return wait_val;
+}
+#else
+/* We have to and actually can handle cancelable system(). The big
+ problem: we have to kill the child process if necessary. To do
+ this a cleanup handler has to be registered and is has to be able
+ to find the PID of the child. The main problem is to reliable have
+ the PID when needed. It is not necessary for the parent thread to
+ return. It might still be in the kernel when the cancellation
+ request comes. Therefore we have to use the clone() calls ability
+ to have the kernel write the PID into the user-level variable. */
+
+libc_hidden_proto(sigaction)
+libc_hidden_proto(waitpid)
+
+#if defined __ia64__
+# define FORK() \
+ INLINE_SYSCALL (clone2, 6, CLONE_PARENT_SETTID | SIGCHLD, NULL, 0, \
+ &pid, NULL, NULL)
+#elif defined __sparc__
+# define FORK() \
+ INLINE_CLONE_SYSCALL (CLONE_PARENT_SETTID | SIGCHLD, 0, &pid, NULL, NULL)
+#elif defined __s390__
+# define FORK() \
+ INLINE_SYSCALL (clone, 3, 0, CLONE_PARENT_SETTID | SIGCHLD, &pid)
+#else
+# define FORK() \
+ INLINE_SYSCALL (clone, 3, CLONE_PARENT_SETTID | SIGCHLD, 0, &pid)
+#endif
+
+static void cancel_handler (void *arg);
+
+# define CLEANUP_HANDLER \
+ __libc_cleanup_region_start (1, cancel_handler, &pid)
+
+# define CLEANUP_RESET \
+ __libc_cleanup_region_end (0)
+
+static struct sigaction intr, quit;
+static int sa_refcntr;
+__libc_lock_define_initialized (static, lock);
+
+# define DO_LOCK() __libc_lock_lock (lock)
+# define DO_UNLOCK() __libc_lock_unlock (lock)
+# define INIT_LOCK() ({ __libc_lock_init (lock); sa_refcntr = 0; })
+# define ADD_REF() sa_refcntr++
+# define SUB_REF() --sa_refcntr
+
+/* Execute LINE as a shell command, returning its status. */
+static int
+do_system (const char *line)
+{
+ int status, save;
+ pid_t pid;
+ struct sigaction sa;
+ sigset_t omask;
+
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = SIG_IGN;
+ /*sa.sa_flags = 0; - done by memset */
+ /*__sigemptyset (&sa.sa_mask); - done by memset */
+
+ DO_LOCK ();
+ if (ADD_REF () == 0)
+ {
+ if (sigaction (SIGINT, &sa, &intr) < 0)
+ {
+ SUB_REF ();
+ goto out;
+ }
+ if (sigaction (SIGQUIT, &sa, &quit) < 0)
+ {
+ save = errno;
+ SUB_REF ();
+ goto out_restore_sigint;
+ }
+ }
+ DO_UNLOCK ();
+
+ /* We reuse the bitmap in the 'sa' structure. */
+ __sigaddset (&sa.sa_mask, SIGCHLD);
+ save = errno;
+ if (sigprocmask (SIG_BLOCK, &sa.sa_mask, &omask) < 0)
+ {
+ {
+ DO_LOCK ();
+ if (SUB_REF () == 0)
+ {
+ save = errno;
+ (void) sigaction (SIGQUIT, &quit, (struct sigaction *) NULL);
+ out_restore_sigint:
+ (void) sigaction (SIGINT, &intr, (struct sigaction *) NULL);
+ __set_errno (save);
+ }
+ out:
+ DO_UNLOCK ();
+ return -1;
+ }
+ }
+
+ CLEANUP_HANDLER;
+
+ pid = FORK ();
+ if (pid == (pid_t) 0)
+ {
+ /* Child side. */
+ const char *new_argv[4];
+ new_argv[0] = "/bin/sh";
+ new_argv[1] = "-c";
+ new_argv[2] = line;
+ new_argv[3] = NULL;
+
+ /* Restore the signals. */
+ (void) sigaction (SIGINT, &intr, (struct sigaction *) NULL);
+ (void) sigaction (SIGQUIT, &quit, (struct sigaction *) NULL);
+ (void) sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL);
+ INIT_LOCK ();
+
+ /* Exec the shell. */
+ (void) execve ("/bin/sh", (char *const *) new_argv, __environ);
+ _exit (127);
+ }
+ else if (pid < (pid_t) 0)
+ /* The fork failed. */
+ status = -1;
+ else
+ /* Parent side. */
+ {
+ /* Note the system() is a cancellation point. But since we call
+ waitpid() which itself is a cancellation point we do not
+ have to do anything here. */
+ if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid)
+ status = -1;
+ }
+
+ CLEANUP_RESET;
+
+ save = errno;
+ DO_LOCK ();
+ if ((SUB_REF () == 0
+ && (sigaction (SIGINT, &intr, (struct sigaction *) NULL)
+ | sigaction (SIGQUIT, &quit, (struct sigaction *) NULL)) != 0)
+ || sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL) != 0)
+ {
+ status = -1;
+ }
+ DO_UNLOCK ();
+
+ return status;
+}
+
+
+int
+__libc_system (const char *line)
+{
+ if (line == NULL)
+ /* Check that we have a command processor available. It might
+ not be available after a chroot(), for example. */
+ return do_system ("exit 0") == 0;
+
+ if (SINGLE_THREAD_P)
+ return do_system (line);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ int result = do_system (line);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+
+
+/* The cancellation handler. */
+static void
+cancel_handler (void *arg)
+{
+ pid_t child = *(pid_t *) arg;
+
+ INTERNAL_SYSCALL_DECL (err);
+ INTERNAL_SYSCALL (kill, err, 2, child, SIGKILL);
+
+ TEMP_FAILURE_RETRY (waitpid (child, NULL, 0));
+
+ DO_LOCK ();
+
+ if (SUB_REF () == 0)
+ {
+ (void) sigaction (SIGQUIT, &quit, (struct sigaction *) NULL);
+ (void) sigaction (SIGINT, &intr, (struct sigaction *) NULL);
+ }
+
+ DO_UNLOCK ();
+}
+#endif
+#ifdef IS_IN_libc
+weak_alias(__libc_system,system)
+#endif
diff --git a/ap/build/uClibc/libc/stdlib/unix_grantpt.c b/ap/build/uClibc/libc/stdlib/unix_grantpt.c
new file mode 100644
index 0000000..1be0a7d
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/unix_grantpt.c
@@ -0,0 +1,201 @@
+/* Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Zack Weinberg <zack@rabi.phys.columbia.edu>, 1998.
+
+ The GNU C Library 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.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <assert.h>
+#include <errno.h>
+#include <grp.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include "pty-private.h"
+
+
+/* uClinux-2.0 has vfork, but Linux 2.0 doesn't */
+#include <sys/syscall.h>
+#if ! defined __NR_vfork
+#define vfork fork
+#endif
+
+/* Return the result of ptsname_r in the buffer pointed to by PTS,
+ which should be of length BUF_LEN. If it is too long to fit in
+ this buffer, a sufficiently long buffer is allocated using malloc,
+ and returned in PTS. 0 is returned upon success, -1 otherwise. */
+static int
+pts_name (int fd, char **pts, size_t buf_len)
+{
+ int rv;
+ char *buf = *pts;
+
+ for (;;)
+ {
+ char *new_buf;
+
+ if (buf_len)
+ {
+ rv = ptsname_r (fd, buf, buf_len);
+
+ if (rv != 0 || memchr (buf, '\0', buf_len))
+ /* We either got an error, or we succeeded and the
+ returned name fit in the buffer. */
+ break;
+
+ /* Try again with a longer buffer. */
+ buf_len += buf_len; /* Double it */
+ }
+ else
+ /* No initial buffer; start out by mallocing one. */
+ buf_len = 128; /* First time guess. */
+
+ if (buf != *pts)
+ /* We've already malloced another buffer at least once. */
+ new_buf = realloc (buf, buf_len);
+ else
+ new_buf = malloc (buf_len);
+ if (! new_buf)
+ {
+ rv = -1;
+ errno = ENOMEM;
+ break;
+ }
+ buf = new_buf;
+ }
+
+ if (rv == 0)
+ *pts = buf; /* Return buffer to the user. */
+ else if (buf != *pts)
+ free (buf); /* Free what we malloced when returning an error. */
+
+ return rv;
+}
+
+/* Change the ownership and access permission of the slave pseudo
+ terminal associated with the master pseudo terminal specified
+ by FD. */
+int
+grantpt (int fd)
+{
+ int retval = -1;
+#ifdef PATH_MAX
+ char _buf[PATH_MAX];
+#else
+ char _buf[512];
+#endif
+ char *buf = _buf;
+ struct stat st;
+ uid_t uid;
+ gid_t gid;
+ pid_t pid;
+
+ if (pts_name (fd, &buf, sizeof (_buf)))
+ return -1;
+
+ if (stat(buf, &st) < 0)
+ goto cleanup;
+
+ /* Make sure that we own the device. */
+ uid = getuid ();
+ if (st.st_uid != uid)
+ {
+ if (chown (buf, uid, st.st_gid) < 0)
+ goto helper;
+ }
+
+ gid = getgid ();
+
+ /* Make sure the group of the device is that special group. */
+ if (st.st_gid != gid)
+ {
+ if (chown (buf, uid, gid) < 0)
+ goto helper;
+ }
+
+ /* Make sure the permission mode is set to readable and writable by
+ the owner, and writable by the group. */
+ if ((st.st_mode & ACCESSPERMS) != (S_IRUSR|S_IWUSR|S_IWGRP))
+ {
+ if (chmod (buf, S_IRUSR|S_IWUSR|S_IWGRP) < 0)
+ goto helper;
+ }
+
+ retval = 0;
+ goto cleanup;
+
+ /* We have to use the helper program. */
+ helper:
+
+ pid = vfork ();
+ if (pid == -1)
+ goto cleanup;
+ else if (pid == 0)
+ {
+ /* Disable core dumps. */
+ struct rlimit rl = { 0, 0 };
+ setrlimit (RLIMIT_CORE, &rl);
+
+ /* We pase the master pseudo terminal as file descriptor PTY_FILENO. */
+ if (fd != PTY_FILENO)
+ if (dup2 (fd, PTY_FILENO) < 0)
+ _exit (FAIL_EBADF);
+
+ execle (_PATH_PT_CHOWN, _PATH_PT_CHOWN, NULL, NULL);
+ _exit (FAIL_EXEC);
+ }
+ else
+ {
+ int w;
+
+ if (waitpid (pid, &w, 0) == -1)
+ goto cleanup;
+ if (!WIFEXITED (w))
+ errno = ENOEXEC;
+ else
+ switch (WEXITSTATUS(w))
+ {
+ case 0:
+ retval = 0;
+ break;
+ case FAIL_EBADF:
+ errno = EBADF;
+ break;
+ case FAIL_EINVAL:
+ errno = EINVAL;
+ break;
+ case FAIL_EACCES:
+ errno = EACCES;
+ break;
+ case FAIL_EXEC:
+ errno = ENOEXEC;
+ break;
+
+ default:
+ assert(! "getpt: internal error: invalid exit code from pt_chown");
+ }
+ }
+
+ cleanup:
+ if (buf != _buf)
+ free (buf);
+
+ return retval;
+}
diff --git a/ap/build/uClibc/libc/stdlib/unlockpt.c b/ap/build/uClibc/libc/stdlib/unlockpt.c
new file mode 100644
index 0000000..5dfea15
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/unlockpt.c
@@ -0,0 +1,49 @@
+/* Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Zack Weinberg <zack@rabi.phys.columbia.edu>, 1998.
+
+ The GNU C Library 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.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <termios.h>
+
+
+/* Unlock the slave pseudo terminal associated with the master pseudo
+ terminal specified by FD. */
+int
+unlockpt (int fd)
+{
+#ifdef TIOCSPTLCK
+ int save_errno = errno;
+ int unlock = 0;
+
+ if (ioctl (fd, TIOCSPTLCK, &unlock))
+ {
+ if (errno == EINVAL)
+ {
+ errno = save_errno;
+ return 0;
+ }
+ else
+ return -1;
+ }
+#endif
+ /* If we have no TIOCSPTLCK ioctl, all slave pseudo terminals are
+ unlocked by default. */
+ return 0;
+}
diff --git a/ap/build/uClibc/libc/stdlib/valloc.c b/ap/build/uClibc/libc/stdlib/valloc.c
new file mode 100644
index 0000000..c5197b2
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/valloc.c
@@ -0,0 +1,36 @@
+/* vi: set sw=4 ts=4: */
+/* Allocate memory on a page boundary.
+ Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+
+This library 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 library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.
+
+ The author may be reached (Email) at the address mike@@ai.mit.edu,
+ or (US mail) as Mike Haertel c/o Free Software Foundation. */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <malloc.h>
+
+
+static size_t pagesize;
+
+__ptr_t valloc (size_t size)
+{
+ if (pagesize == 0)
+ pagesize = getpagesize ();
+
+ return memalign(pagesize, size);
+}
diff --git a/ap/build/uClibc/libc/stdlib/wcstod.c b/ap/build/uClibc/libc/stdlib/wcstod.c
new file mode 100644
index 0000000..08f8021
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/wcstod.c
@@ -0,0 +1,8 @@
+/*
+ * Copyright (C) 2000-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_wcstod
+#include "_strtod.c"
diff --git a/ap/build/uClibc/libc/stdlib/wcstod_l.c b/ap/build/uClibc/libc/stdlib/wcstod_l.c
new file mode 100644
index 0000000..be0e58e
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/wcstod_l.c
@@ -0,0 +1,9 @@
+/*
+ * Copyright (C) 2000-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_wcstod_l
+#define __UCLIBC_DO_XLOCALE
+#include "_strtod.c"
diff --git a/ap/build/uClibc/libc/stdlib/wcstof.c b/ap/build/uClibc/libc/stdlib/wcstof.c
new file mode 100644
index 0000000..27ad22f
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/wcstof.c
@@ -0,0 +1,8 @@
+/*
+ * Copyright (C) 2000-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_wcstof
+#include "_strtod.c"
diff --git a/ap/build/uClibc/libc/stdlib/wcstof_l.c b/ap/build/uClibc/libc/stdlib/wcstof_l.c
new file mode 100644
index 0000000..953ebe0
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/wcstof_l.c
@@ -0,0 +1,9 @@
+/*
+ * Copyright (C) 2000-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_wcstof_l
+#define __UCLIBC_DO_XLOCALE
+#include "_strtod.c"
diff --git a/ap/build/uClibc/libc/stdlib/wcstol.c b/ap/build/uClibc/libc/stdlib/wcstol.c
new file mode 100644
index 0000000..74462e1
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/wcstol.c
@@ -0,0 +1,7 @@
+/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_wcstol
+#include "stdlib.c"
diff --git a/ap/build/uClibc/libc/stdlib/wcstol_l.c b/ap/build/uClibc/libc/stdlib/wcstol_l.c
new file mode 100644
index 0000000..4282987
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/wcstol_l.c
@@ -0,0 +1,8 @@
+/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_wcstol_l
+#define __UCLIBC_DO_XLOCALE
+#include "stdlib.c"
diff --git a/ap/build/uClibc/libc/stdlib/wcstold.c b/ap/build/uClibc/libc/stdlib/wcstold.c
new file mode 100644
index 0000000..cd879c1
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/wcstold.c
@@ -0,0 +1,8 @@
+/*
+ * Copyright (C) 2000-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_wcstold
+#include "_strtod.c"
diff --git a/ap/build/uClibc/libc/stdlib/wcstold_l.c b/ap/build/uClibc/libc/stdlib/wcstold_l.c
new file mode 100644
index 0000000..2ea23b0
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/wcstold_l.c
@@ -0,0 +1,9 @@
+/*
+ * Copyright (C) 2000-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_wcstold_l
+#define __UCLIBC_DO_XLOCALE
+#include "_strtod.c"
diff --git a/ap/build/uClibc/libc/stdlib/wcstoll.c b/ap/build/uClibc/libc/stdlib/wcstoll.c
new file mode 100644
index 0000000..4cc9b05
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/wcstoll.c
@@ -0,0 +1,7 @@
+/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_wcstoll
+#include "stdlib.c"
diff --git a/ap/build/uClibc/libc/stdlib/wcstoll_l.c b/ap/build/uClibc/libc/stdlib/wcstoll_l.c
new file mode 100644
index 0000000..66c23c2
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/wcstoll_l.c
@@ -0,0 +1,8 @@
+/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_wcstoll_l
+#define __UCLIBC_DO_XLOCALE
+#include "stdlib.c"
diff --git a/ap/build/uClibc/libc/stdlib/wcstombs.c b/ap/build/uClibc/libc/stdlib/wcstombs.c
new file mode 100644
index 0000000..c3d08d8
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/wcstombs.c
@@ -0,0 +1,7 @@
+/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_wcstombs
+#include "stdlib.c"
diff --git a/ap/build/uClibc/libc/stdlib/wcstoul.c b/ap/build/uClibc/libc/stdlib/wcstoul.c
new file mode 100644
index 0000000..5542744
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/wcstoul.c
@@ -0,0 +1,7 @@
+/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_wcstoul
+#include "stdlib.c"
diff --git a/ap/build/uClibc/libc/stdlib/wcstoul_l.c b/ap/build/uClibc/libc/stdlib/wcstoul_l.c
new file mode 100644
index 0000000..529e8e4
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/wcstoul_l.c
@@ -0,0 +1,8 @@
+/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_wcstoul_l
+#define __UCLIBC_DO_XLOCALE
+#include "stdlib.c"
diff --git a/ap/build/uClibc/libc/stdlib/wcstoull.c b/ap/build/uClibc/libc/stdlib/wcstoull.c
new file mode 100644
index 0000000..ea884ef
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/wcstoull.c
@@ -0,0 +1,7 @@
+/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_wcstoull
+#include "stdlib.c"
diff --git a/ap/build/uClibc/libc/stdlib/wcstoull_l.c b/ap/build/uClibc/libc/stdlib/wcstoull_l.c
new file mode 100644
index 0000000..976d103
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/wcstoull_l.c
@@ -0,0 +1,8 @@
+/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_wcstoull_l
+#define __UCLIBC_DO_XLOCALE
+#include "stdlib.c"
diff --git a/ap/build/uClibc/libc/stdlib/wctomb.c b/ap/build/uClibc/libc/stdlib/wctomb.c
new file mode 100644
index 0000000..3f612be
--- /dev/null
+++ b/ap/build/uClibc/libc/stdlib/wctomb.c
@@ -0,0 +1,7 @@
+/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_wctomb
+#include "stdlib.c"