added and removed uclibc patches
authorJohn Voltz <john.voltz@gmail.com>
Thu, 6 Mar 2008 18:50:01 +0000 (18:50 -0000)
committerJohn Voltz <john.voltz@gmail.com>
Thu, 6 Mar 2008 18:50:01 +0000 (18:50 -0000)
25 files changed:
toolchain/uClibc/Config.in
toolchain/uClibc/Glibc_vs_uClibc_Differences.txt [new file with mode: 0644]
toolchain/uClibc/uClibc-0.9.28-100-fix_includes.patch [new file with mode: 0644]
toolchain/uClibc/uClibc-0.9.28-200-host-ldconfig.patch [new file with mode: 0644]
toolchain/uClibc/uClibc-0.9.28-300-ldso.patch [new file with mode: 0644]
toolchain/uClibc/uClibc-0.9.28-400-math-endianness.patch [new file with mode: 0644]
toolchain/uClibc/uClibc-0.9.28-500-mutex-cancel.patch [new file with mode: 0644]
toolchain/uClibc/uClibc-0.9.28-600-new_dst_rules.patch [new file with mode: 0644]
toolchain/uClibc/uClibc-0.9.28-700-rm-whitespace.patch [new file with mode: 0644]
toolchain/uClibc/uClibc-0.9.28-800-avr32-1.patch [new file with mode: 0644]
toolchain/uClibc/uClibc-0.9.28-fix_includes.patch [deleted file]
toolchain/uClibc/uClibc-0.9.28-host-ldconfig.patch [deleted file]
toolchain/uClibc/uClibc-0.9.28-ldso.patch [deleted file]
toolchain/uClibc/uClibc-0.9.28-math-endianness.patch [deleted file]
toolchain/uClibc/uClibc-0.9.28-mutex-cancel.patch [deleted file]
toolchain/uClibc/uClibc-0.9.28-new_dst_rules.patch [deleted file]
toolchain/uClibc/uClibc-0.9.28-rm-whitespace.patch [deleted file]
toolchain/uClibc/uClibc-0.9.28.3-avr32.patch [new file with mode: 0644]
toolchain/uClibc/uClibc-0.9.29-002-atmel.1.patch [new file with mode: 0644]
toolchain/uClibc/uClibc-0.9.29-avr32-fix-sa_onstack.patch [new file with mode: 0644]
toolchain/uClibc/uClibc-0.9.29-avr32.patch [deleted file]
toolchain/uClibc/uClibc-0.9.29-fix-inverted-login-in-compare_and_swap-in-linuxthreads.patch [deleted file]
toolchain/uClibc/uClibc-0.9.29-fix-resolve-in-etc-hosts.patch [deleted file]
toolchain/uClibc/uClibc-0.9.29-linuxthreads.patch [new file with mode: 0644]
toolchain/uClibc/uClibc-0.9.29-load-got-pointer-at-the-beginning-of-init-and-fini.patch [deleted file]

index b463f2bd057ca7c28c2ef62bd301c12bac9d8a8e..6557f1980f734038a292bd4220365f95d8521065 100644 (file)
@@ -10,7 +10,7 @@ choice
          Select the version of uClibc you wish to use.
 
        config BR2_UCLIBC_VERSION_0_9_28_3
-               depends !BR2_avr32 && BR2_DEPRECATED
+               depends BR2_DEPRECATED
                bool "uClibc 0.9.28.3"
                depends BR2_EXT_UCLIBC_VERSION_0_9_28_3
 
@@ -19,7 +19,6 @@ choice
                depends BR2_EXT_UCLIBC_VERSION_0_9_29
 
        config BR2_UCLIBC_VERSION_SNAPSHOT
-               depends !BR2_avr32
                bool "daily snapshot"
 
 endchoice
diff --git a/toolchain/uClibc/Glibc_vs_uClibc_Differences.txt b/toolchain/uClibc/Glibc_vs_uClibc_Differences.txt
new file mode 100644 (file)
index 0000000..4ed2463
--- /dev/null
@@ -0,0 +1,215 @@
+ uClibc and Glibc are not the same -- there are a number of differences which
+may or may not cause you problems.  This document attempts to list these
+differences and, when completed, will contain a full list of all relevant
+differences.
+
+
+1) uClibc is smaller than glibc.  We attempt to maintain a glibc compatible
+interface, allowing applications that compile with glibc to easily compile with
+uClibc.  However, we do not include _everything_ that glibc includes, and
+therefore some applications may not compile.  If this happens to you, please
+report the failure to the uclibc mailing list, with detailed error messages.
+
+2) uClibc is much more configurable then glibc.  This means that a developer
+may have compiled uClibc in such a way that significant amounts of
+functionality have been omitted.
+
+3) uClibc does not even attempt to ensure binary compatibility across releases.
+When a new version of uClibc is released, you may or may not need to recompile
+all your binaries.
+
+4) malloc(0) in glibc returns a valid pointer to something(!?!?) while in
+uClibc calling malloc(0) returns a NULL.  The behavior of malloc(0) is listed
+as implementation-defined by SuSv3, so both libraries are equally correct.
+This difference also applies to realloc(NULL, 0).  I personally feel glibc's
+behavior is not particularly safe.  To enable glibc behavior, one has to
+explicitly enable the MALLOC_GLIBC_COMPAT option.
+
+4.1) glibc's malloc() implementation has behavior that is tunable via the
+MALLOC_CHECK_ environment variable.  This is primarily used to provide extra
+malloc debugging features.  These extended malloc debugging features are not
+available within uClibc.  There are many good malloc debugging libraries
+available for Linux (dmalloc, electric fence, valgrind, etc) that work much
+better than the glibc extended malloc debugging.  So our omitting this
+functionality from uClibc is not a great loss.
+
+5) uClibc does not provide a database library (libdb).
+
+6) uClibc does not support NSS (/lib/libnss_*), which allows glibc to easily
+support various methods of authentication and DNS resolution.  uClibc only
+supports flat password files and shadow password files for storing
+authentication information.  If you need something more complex than this,
+you can compile and install pam.
+
+7) uClibc's libresolv is only a stub.  Some, but not all of the functionality
+provided by glibc's libresolv is provided internal to uClibc.  Other functions
+are not at all implemented.
+
+8) libnsl provides support for Network Information Service (NIS) which was
+originally called "Yellow Pages" or "YP", which is an extension of RPC invented
+by Sun to share Unix password files over the network.  I personally think NIS
+is an evil abomination and should not be used.  These days, using ldap is much
+more effective mechanism for doing the same thing.  uClibc provides a stub
+libnsl, but has no actual support for Network Information Service (NIS).
+We therefore, also do not provide any of the headers files provided by glibc
+under /usr/include/rpcsvc.
+
+9) uClibc's locale support is not 100% complete yet.  We are working on it.
+
+10) uClibc's math library only supports long double as inlines, and even
+then the long double support is quite limited.  Also, very few of the
+float math functions are implemented.  Stick with double and you should
+be just fine.
+
+11) uClibc's libcrypt does not support the reentrant crypt_r, setkey_r and
+encrypt_r, since these are not required by SuSv3.
+
+12) uClibc directly uses kernel types to define most opaque data types.
+
+13) uClibc directly uses the linux kernel's arch specific 'stuct stat'.
+
+14) uClibc's librt library currently lacks all aio routines, all clock
+    routines, and all shm routines (only the timer routines and the mq
+    routines are implemented).
+
+<other things as we notice them>
+
+
+
+******************************  Manuel's Notes  ******************************
+
+Some general comments...
+
+The intended target for all my uClibc code is ANSI/ISO C99 and SUSv3
+compliance.  While some glibc extensions are present, many will eventually
+be configurable.  Also, even when present, the glibc-like extensions may
+differ slightly or be more restrictive than the native glibc counterparts.
+They are primarily meant to be porting _aides_ and not necessarily
+drop-in replacements.
+
+Now for some details...
+
+time functions
+--------------
+1) Leap seconds are not supported.
+2) /etc/timezone and the whole zoneinfo directory tree are not supported.
+   To set the timezone, set the TZ environment variable as specified in
+   http://www.opengroup.org/onlinepubs/007904975/basedefs/xbd_chap08.html
+   or you may also create an /etc/TZ file of a single line, ending with a
+   newline, containing the TZ setting.  For example
+   echo CST6CDT > /etc/TZ
+3) Currently, locale specific eras and alternate digits are not supported.
+   They are on my TODO list.
+
+wide char support
+-----------------
+1) The only multibyte encoding currently supported is UTF-8.  The various
+   ISO-8859-* encodings are (optionally) supported.  The internal
+   representation of wchar's is assumed to be 31 bit unicode values in
+   native endian representation.  Also, the underlying char encoding is
+   assumed to match ASCII in the range 0-0x7f.
+2) In the next iteration of locale support, I plan to add support for
+   (at least some) other multibyte encodings.
+
+locale support
+--------------
+1) The target for support is SUSv3 locale functionality.  While nl_langinfo
+   has been extended, similar to glibc, it only returns values for related
+   locale entries.
+2) Currently, all SUSv3 libc locale functionality should be implemented
+   except for wcsftime and collating item support in regex.
+
+stdio
+-----
+1) Conversion of large magnitude floating-point values by printf suffers a loss
+   of precision due to the algorithm used.
+2) uClibc's printf is much stricter than glibcs, especially regarding positional
+   args.  The entire format string is parsed first and an error is returned if
+   a problem is detected.  In locales other than C, the format string is checked
+   to be a valid multibyte sequence as well.  Also, currently at most 10 positional
+   args are allowed (although this is configurable).
+3) BUFSIZ is configurable, but no attempt is made at automatic tuning of internal
+   buffer sizes for stdio streams.  In fact, the stdio code in general sacrifices
+   sophistication/performace for minimal size.
+4) uClibc allows glibc-like custom printf functions.  However, while not
+   currently checked, the specifier must be <= 0x7f.
+5) uClibc allows glibc-like custom streams.  However, no in-buffer seeking is
+   done.
+6) The functions fcloseall() and __fpending() can behave differently than their
+   glibc counterparts.
+7) uClibc's setvbuf is more restrictive about when it can be called than glibc's
+   is.  The standards specify that setvbuf must occur before any other operations
+   take place on the stream.
+8) Right now, %m is not handled properly by printf when the format uses positional
+   args.
+9) The FILEs created by glibc's fmemopen(), open_memstream(), and fopencookie()
+   are not capable of wide orientation.  The corresponding uClibc routines do
+   not have this limitation.
+10) For scanf, the C99 standard states "The fscanf function returns the value of
+    the macro EOF if an input failure occurs before any conversion."  But glibc's
+    scanf does not respect conversions for which assignment was surpressed, even
+    though the standard states that the value is converted but not stored.
+
+glibc bugs that Ulrich Drepper has refused to acknowledge or comment on
+  ( http://sources.redhat.com/ml/libc-alpha/2003-09/ )
+-----------------------------------------------------------------------
+1) The C99 standard says that for printf, a %s conversion makes no special
+   provisions for multibyte characters.  SUSv3 is even more clear, stating
+   that bytes are written and a specified precision is in bytes.  Yet glibc
+   treats the arg as a multibyte string when a precision is specified and
+   not otherwise.
+2) Both C99 and C89 state that the %c conversion for scanf reads the exact
+   number of bytes specified by the optional field width (or 1 if not specified).
+   uClibc complies with the standard.  There is an argument that perhaps the
+   specified width should be treated as an upper bound, based on some historical
+   use.  However, such behavior should be mentioned in the Conformance document.
+3) glibc's scanf is broken regarding some numeric patterns.  Some invalid
+   strings are accepted as valid ("0x.p", "1e", digit grouped strings).
+   In spite of my posting examples clearly illustrating the bugs, they remain
+   unacknowledged by the glibc developers.
+4) glibc's scanf seems to require a 'p' exponent for hexadecimal float strings.
+   According to the standard, this is optional.
+5) C99 requires that once an EOF is encountered, the stream should be treated
+   as if at end-of-file even if more data becomes available.  Further reading
+   can be attempted by clearing the EOF flag though, via clearerr() or a file
+   positioning function.  For details concerning the original change, see
+   Defect Report #141.  glibc is currently non-compliant, and the developers
+   did not comment when I asked for their official position on this issue.
+6) glibc's collation routines and/or localedef are broken regarding implicit
+   and explicit UNDEFINED rules.
+
+More to follow as I think of it...
+
+
+
+
+Profiling:
+-------------------------------------------------------------------
+
+uClibc no longer supports 'gcc -fprofile-arcs  -pg' style profiling, which
+causes your application to generate a 'gmon.out' file that can then be analyzed
+by 'gprof'.  Not only does this require explicit extra support in uClibc, it
+requires that you rebuild everything with profiling support.  There is both a
+size and performance penalty to profiling your applications this way, as well
+as Heisenberg effects, where the act of measuring changes what is measured.
+
+There exist a number of less invasive alternatives that do not require you to
+specially instrument your application, and recompile and relink everything.
+
+The OProfile system-wide profiler is an excellent alternative:
+      http://oprofile.sourceforge.net/
+
+Many people have had good results using the combination of Valgrind
+to generate profiling information and KCachegrind for analysis:
+      http://developer.kde.org/~sewardj/
+      http://kcachegrind.sourceforge.net/
+
+Prospect is another alternative based on OProfile:
+      http://prospect.sourceforge.net/
+
+And the Linux Trace Toolkit (LTT) is also a fine tool:
+    http://www.opersys.com/LTT/
+
+FunctionCheck:
+       http://www710.univ-lyon1.fr/~yperret/fnccheck/
+
diff --git a/toolchain/uClibc/uClibc-0.9.28-100-fix_includes.patch b/toolchain/uClibc/uClibc-0.9.28-100-fix_includes.patch
new file mode 100644 (file)
index 0000000..52c8967
--- /dev/null
@@ -0,0 +1,327 @@
+--- uClibc-0.9.28/Makefile.orig        2006-12-11 21:06:42.000000000 -0700
++++ uClibc-0.9.28/Makefile     2006-12-11 21:06:53.000000000 -0700
+@@ -158,7 +158,7 @@
+       $(INSTALL) -d $(PREFIX)$(DEVEL_PREFIX)lib
+       $(INSTALL) -d $(PREFIX)$(DEVEL_PREFIX)include
+       -$(INSTALL) -m 644 lib/*.[ao] $(PREFIX)$(DEVEL_PREFIX)lib/
+-      if [ "$(KERNEL_SOURCE)" == "$(DEVEL_PREFIX)" ] ; then \
++      if [ "$(KERNEL_SOURCE)" = "$(DEVEL_PREFIX)" ] ; then \
+               extra_exclude="--exclude include/linux --exclude include/asm'*'" ; \
+       else \
+               extra_exclude="" ; \
+--- uClibc-0.9.28/extra/scripts/fix_includes.sh.orig   2006-12-13 05:44:21.000000000 -0700
++++ uClibc-0.9.28/extra/scripts/fix_includes.sh        2006-12-13 05:44:35.000000000 -0700
+@@ -1,183 +1,155 @@
+ #!/bin/sh
+-# Copyright (C) 2003 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
+-
+-usage () {
+-    echo ""
+-    echo "usage: "`basename $0`" -k KERNEL_SOURCE_DIRECTORY -t TARGET_ARCH"
+-    echo ""
+-    echo "This utility scans the KERNEL_SOURCE_DIRECTORY directory and"
+-    echo "checks that it contains well formed kernel headers suitable"
+-    echo "for inclusion as the include/linux/ directory provided by"
+-    echo "uClibc."
+-    echo ""
+-    echo "If the specified kernel headers are present and already"
+-    echo "configured for the architecture specified by TARGET_ARCH,"
+-    echo "they will be used as-is."
+-    echo ""
+-    echo "If the specified kernel headers are missing entirely, this"
+-    echo "script will return an error."
+-    echo ""
+-    echo "If the specified kernel headers are present, but are either"
+-    echo "not yet configured or are configured for an architecture"
+-    echo "different than that specified by TARGET_ARCH, this script"
+-    echo "will attempt to 'fix' the kernel headers and make them"
+-    echo "suitable for use by uClibc.  This fixing process may fail."
+-    echo "It is therefore best to always provide kernel headers that"
+-    echo "are already configured for the selected architecture."
+-    echo ""
+-    echo "Most Linux distributions provide 'kernel-headers' packages"
+-    echo "that are suitable for use by uClibc."
+-    echo ""
+-    echo ""
+-    exit 1;
++# Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
++#
++# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
++#
++
++usage() {
++      echo ""
++      echo "usage: "`basename $0`" -k KERNEL_SOURCE_DIRECTORY -t TARGET_ARCH"
++      echo ""
++      echo "This utility scans the KERNEL_SOURCE_DIRECTORY directory and"
++      echo "checks that it contains well formed kernel headers suitable"
++      echo "for inclusion as the include/linux/ directory provided by"
++      echo "uClibc."
++      echo ""
++      echo "If the specified kernel headers are present and already"
++      echo "configured for the architecture specified by TARGET_ARCH,"
++      echo "they will be used as-is."
++      echo ""
++      echo "If the specified kernel headers are missing entirely, this"
++      echo "script will return an error."
++      echo ""
++      echo "If the specified kernel headers are present, but are either"
++      echo "not yet configured or are configured for an architecture"
++      echo "different than that specified by TARGET_ARCH, this script"
++      echo "will attempt to 'fix' the kernel headers and make them"
++      echo "suitable for use by uClibc.  This fixing process may fail."
++      echo "It is therefore best to always provide kernel headers that"
++      echo "are already configured for the selected architecture."
++      echo ""
++      echo "Most Linux distributions provide 'kernel-headers' packages"
++      echo "that are suitable for use by uClibc."
++      echo ""
++      echo ""
++      exit 1
+ }
+-HAS_MMU="y";
++
++#
++# Parse our arguments
++#
++HAS_MMU="y"
+ while [ -n "$1" ]; do
+-    case $1 in
+-      -k ) shift; if [ -n "$1" ]; then KERNEL_SOURCE=$1; shift; else usage; fi; ;;
+-      -t ) shift; if [ -n "$1" ]; then TARGET_ARCH=$1; shift; else usage; fi; ;;
+-      -n ) shift; HAS_MMU="n"; ;;
+-      -* ) usage; ;;
+-      * ) usage; ;;
+-    esac;
+-done;
++      case $1 in
++              -k ) shift; if [ -n "$1" ]; then KERNEL_SOURCE=$1; shift; else usage; fi; ;;
++              -t ) shift; if [ -n "$1" ]; then TARGET_ARCH=$1; shift; else usage; fi; ;;
++              -n ) shift; HAS_MMU="n"; ;;
++              -* ) usage; ;;
++              * ) usage; ;;
++      esac
++done
+-if [ ! -f "$KERNEL_SOURCE/Makefile" -a ! -f "$KERNEL_SOURCE/include/linux/version.h" ]; then
+-    echo "";
+-    echo "";
+-    echo "The file $KERNEL_SOURCE/Makefile or $KERNEL_SOURCE/include/linux/version.h is missing!";
+-    echo "Perhaps your kernel source is broken?"
+-    echo "";
+-    echo "";
+-    exit 1;
+-fi;
+-if [ ! -d "$KERNEL_SOURCE" ]; then
+-    echo "";
+-    echo "";
+-    echo "$KERNEL_SOURCE is not a directory";
+-    echo "";
+-    echo "";
+-    exit 1;
+-fi;
+-
+-if [ -f "$KERNEL_SOURCE/Makefile" ] ; then
+-# set current VERSION, PATCHLEVEL, SUBLEVEL, EXTRAVERSION
+-eval `sed -n -e 's/^\([A-Z]*\) = \([0-9]*\)$/\1=\2/p' -e 's/^\([A-Z]*\) = \(-[-a-z0-9]*\)$/\1=\2/p' $KERNEL_SOURCE/Makefile`
+-else
+-ver=`grep UTS_RELEASE $KERNEL_SOURCE/include/linux/version.h | cut -d '"' -f 2`
+-VERSION=`echo "$ver" | cut -d '.' -f 1`
+-PATCHLEVEL=`echo "$ver" | cut -d '.' -f 2`
+-if echo "$ver" | grep -q '-' ; then
+-SUBLEVEL=`echo "$ver" | sed "s/${VERSION}.${PATCHLEVEL}.//" | cut -d '-' -f 1`
+-EXTRAVERSION=`echo "$ver" | sed "s/${VERSION}.${PATCHLEVEL}.${SUBLEVEL}-//"`
+-else
+-SUBLEVEL=`echo "$ver" | cut -d '.' -f 3`
+-#EXTRAVERSION=
+-fi
++#
++# Perform some sanity checks on our kernel sources
++#
++if [ ! -f "$KERNEL_SOURCE/Makefile" -a ! -f "$KERNEL_SOURCE/include/linux/version.h" ]; then
++      echo ""
++      echo ""
++      echo "The file $KERNEL_SOURCE/Makefile or $KERNEL_SOURCE/include/linux/version.h is missing!"
++      echo "Perhaps your kernel source is broken?"
++      echo ""
++      echo ""
++      exit 1
+ fi
+-if [ -z "$VERSION" -o -z "$PATCHLEVEL" -o -z "$SUBLEVEL" ]
+-then
+-    echo "Unable to determine version for kernel headers"
+-    echo -e "\tprovided in directory $KERNEL_SOURCE"
+-    exit 1
++if [ ! -d "$KERNEL_SOURCE" ]; then
++      echo ""
++      echo ""
++      echo "$KERNEL_SOURCE is not a directory"
++      echo ""
++      echo ""
++      exit 1
+ fi
+-if [ "$MAKE_IS_SILENT" != "y" ]; then
+-echo "Current kernel version is $VERSION.$PATCHLEVEL.$SUBLEVEL${EXTRAVERSION}"
+-echo -e "\n"
+-echo "Using kernel headers from $VERSION.$PATCHLEVEL.$SUBLEVEL${EXTRAVERSION} for architecture '$TARGET_ARCH'"
+-echo -e "\tprovided in directory $KERNEL_SOURCE"
+-echo -e "\n"
+-fi
++#
+ # Create a symlink to include/asm
+-
++#
+ rm -f include/asm*
+ if [ ! -d "$KERNEL_SOURCE/include/asm" ]; then
+-    echo "";
+-    echo "";
+-    echo "The symlink $KERNEL_SOURCE/include/asm is missing\!";
+-    echo "Perhaps you forgot to configure your kernel source?";
+-    echo "You really should configure your kernel source tree so I";
+-    echo "do not have to try and guess about this sort of thing.";
+-    echo ""
+-    echo "Attempting to guess a usable value....";
+-    echo ""
+-    echo "";
+-    sleep 1;
+-
+-    if [ "$TARGET_ARCH" = "powerpc" ];then
+-      set -x;
+-      ln -fs $KERNEL_SOURCE/include/asm-ppc include/asm;
+-      set +x;
+-    elif [ "$TARGET_ARCH" = "mips" ];then
+-      set -x;
+-      ln -fs $KERNEL_SOURCE/include/asm-mips include/asm;
+-      set +x;
+-    elif [ "$TARGET_ARCH" = "arm" ];then
+-      set -x;
+-      ln -fs $KERNEL_SOURCE/include/asm-arm include/asm;
+-      set +x;
+-      if [ ! -L $KERNEL_SOURCE/include/asm-arm/proc ] ; then
+-          if [ ! -L proc ] ; then
+-              (cd include/asm;
+-              ln -fs proc-armv proc;
+-              ln -fs arch-ebsa285 arch);
+-          fi
++      echo ""
++      echo ""
++      echo "The symlink $KERNEL_SOURCE/include/asm is missing\!"
++      echo "Perhaps you forgot to configure your kernel source?"
++      echo "You really should configure your kernel source tree so I"
++      echo "do not have to try and guess about this sort of thing."
++      echo ""
++      echo "Attempting to guess a usable value...."
++      echo ""
++      echo ""
++      sleep 1
++
++      if [ "$TARGET_ARCH" = "powerpc" ]; then
++              set -x
++              ln -fs $KERNEL_SOURCE/include/asm-ppc include/asm
++              set +x
++      elif [ "$TARGET_ARCH" = "mips" ]; then
++              set -x
++              ln -fs $KERNEL_SOURCE/include/asm-mips include/asm
++              set +x
++      elif [ "$TARGET_ARCH" = "arm" ]; then
++              set -x
++              ln -fs $KERNEL_SOURCE/include/asm-arm include/asm
++              set +x
++      if [ ! -L $KERNEL_SOURCE/include/asm-arm/proc ]; then
++              if [ ! -L proc ]; then
++                      (
++                              cd include/asm
++                              ln -fs proc-armv proc
++                              ln -fs arch-ebsa285 arch
++                      )
++              fi
++      fi
++      elif [ "$TARGET_ARCH" = "cris" ]; then
++              set -x
++              ln -fs $KERNEL_SOURCE/include/asm-cris include/asm
++              set +x
++      elif [ "$HAS_MMU" != "y" ]; then
++              if [ -d $KERNEL_SOURCE/include/asm-${TARGET_ARCH}nommu ]; then
++                      set -x
++                      ln -fs $KERNEL_SOURCE/include/asm-${TARGET_ARCH}nommu include/asm
++                      set +x
++              else
++                      set -x
++                      ln -fs $KERNEL_SOURCE/include/asm-$TARGET_ARCH include/asm
++                      set +x
++              fi
++      else
++              set -x
++              ln -fs $KERNEL_SOURCE/include/asm-$TARGET_ARCH include/asm
++              set +x
+       fi;
+-    elif [ "$TARGET_ARCH" = "cris" ]; then
+-      set -x;
+-      ln -fs $KERNEL_SOURCE/include/asm-cris include/asm;
+-      set +x;
+-    elif [ "$HAS_MMU" != "y" ]; then
+-          if [ -d $KERNEL_SOURCE/include/asm-${TARGET_ARCH}nommu ] ; then
+-              set -x;
+-              ln -fs $KERNEL_SOURCE/include/asm-${TARGET_ARCH}nommu include/asm;
+-              set +x;
+-          else
+-              set -x;
+-              ln -fs $KERNEL_SOURCE/include/asm-$TARGET_ARCH include/asm;
+-              set +x;
+-          fi;
+-    else
+-      set -x;
+-      ln -fs $KERNEL_SOURCE/include/asm-$TARGET_ARCH include/asm;
+-      set +x;
+-    fi;
+ else
+-# No guessing required.....
+-ln -fs $KERNEL_SOURCE/include/asm include/asm
+-if [ -e $KERNEL_SOURCE/include/asm-$TARGET_ARCH ] ; then
+-ln -fs $KERNEL_SOURCE/include/asm-$TARGET_ARCH include/asm-$TARGET_ARCH
++      # No guessing required.....
++      for x in $KERNEL_SOURCE/include/asm* ; do
++              ln -fs ${x} include/
++      done
+ fi
+-fi;
++#
+ # Annoyingly, 2.6.x kernel headers also need an include/asm-generic/ directory
+-if [ $VERSION -eq 2 ] && [ $PATCHLEVEL -ge 6 ] ; then
+-    ln -fs $KERNEL_SOURCE/include/asm-generic include/asm-generic
+-fi;
++#
++if [ -e $KERNEL_SOURCE/include/asm-generic ]; then
++      rm -f include/asm-generic
++      ln -fs $KERNEL_SOURCE/include/asm-generic include/asm-generic
++fi
++#
+ # Create the include/linux symlink.
++#
+ rm -f include/linux
+ ln -fs $KERNEL_SOURCE/include/linux include/linux
+-
diff --git a/toolchain/uClibc/uClibc-0.9.28-200-host-ldconfig.patch b/toolchain/uClibc/uClibc-0.9.28-200-host-ldconfig.patch
new file mode 100644 (file)
index 0000000..f55c349
--- /dev/null
@@ -0,0 +1,635 @@
+This patch supports cross-development for embedded systems by allowing the
+host version of ldconfig (ldconfig.host) to build ld.so.cache for the target.
+Changes include:
+ 1) LDSO_CACHE_SUPPORT is defined for the host build.
+ 2) A little-endian host can create a big-endian ld.so.cache, and vice versa.
+ 3) Can use -r option without chroot(), so no need to run as superuser.
+
+Dan Howell <dahowell@directv.com>
+
+diff -urN uClibc-orig/utils/chroot_realpath.c uClibc-20050502/utils/chroot_realpath.c
+--- uClibc-orig/utils/chroot_realpath.c        1969-12-31 16:00:00.000000000 -0800
++++ uClibc-20050502/utils/chroot_realpath.c    2005-09-12 18:30:29.000000000 -0700
+@@ -0,0 +1,163 @@
++/*
++ * chroot_realpath.c -- reslove pathname as if inside chroot
++ * Based on realpath.c Copyright (C) 1993 Rick Sladkey <jrs@world.std.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU Library Public License as published by
++ * the Free Software Foundation; either version 2, 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 Public License for more details.
++ *
++ * 2005/09/12: Dan Howell (modified from realpath.c to emulate chroot)
++ */
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include <sys/types.h>
++#include <unistd.h>
++#include <stdio.h>
++#include <string.h>
++#include <strings.h>
++#include <limits.h>                           /* for PATH_MAX */
++#include <sys/param.h>                        /* for MAXPATHLEN */
++#include <errno.h>
++#ifndef __set_errno
++#define __set_errno(val) ((errno) = (val))
++#endif
++
++#include <sys/stat.h>                 /* for S_IFLNK */
++
++#ifndef PATH_MAX
++#define PATH_MAX _POSIX_PATH_MAX
++#endif
++
++#define MAX_READLINKS 32
++
++char *chroot_realpath(const char *chroot, const char *path, char resolved_path[])
++{
++      char copy_path[PATH_MAX];
++      char link_path[PATH_MAX];
++      char got_path[PATH_MAX];
++      char *got_path_root = got_path;
++      char *new_path = got_path;
++      char *max_path;
++      int readlinks = 0;
++      int n;
++      int chroot_len;
++
++      /* Trivial case. */
++      if (chroot == NULL || *chroot == '\0' ||
++          (*chroot == '/' && chroot[1] == '\0')) {
++              strcpy(resolved_path, path);
++              return resolved_path;
++      }
++
++      chroot_len = strlen(chroot);
++
++      if (chroot_len + strlen(path) >= PATH_MAX - 3) {
++              __set_errno(ENAMETOOLONG);
++              return NULL;
++      }
++
++      /* Make a copy of the source path since we may need to modify it. */
++      strcpy(copy_path, path);
++      path = copy_path;
++      max_path = copy_path + PATH_MAX - chroot_len - 3;
++
++      /* Start with the chroot path. */
++      strcpy(new_path, chroot);
++      new_path += chroot_len;
++      while (*new_path == '/' && new_path > got_path)
++              new_path--;
++      got_path_root = new_path;
++      *new_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_root + 1)
++                                              continue;
++                                      /* Handle ".." by backing up. */
++                                      while ((--new_path)[-1] != '/');
++                                      continue;
++                              }
++                      }
++              }
++              /* Safely copy the next pathname component. */
++              while (*path != '\0' && *path != '/') {
++                      if (path > max_path) {
++                              __set_errno(ENAMETOOLONG);
++                              return NULL;
++                      }
++                      *new_path++ = *path++;
++              }
++              if (*path == '\0')
++                      /* Don't follow symlink for last pathname component. */
++                      break;
++#ifdef S_IFLNK
++              /* Protect against infinite loops. */
++              if (readlinks++ > MAX_READLINKS) {
++                      __set_errno(ELOOP);
++                      return NULL;
++              }
++              /* See if latest pathname component is a symlink. */
++              *new_path = '\0';
++              n = readlink(got_path, link_path, PATH_MAX - 1);
++              if (n < 0) {
++                      /* EINVAL means the file exists but isn't a symlink. */
++                      if (errno != EINVAL) {
++                              /* Make sure it's null terminated. */
++                              *new_path = '\0';
++                              strcpy(resolved_path, got_path);
++                              return NULL;
++                      }
++              } else {
++                      /* Note: readlink doesn't add the null byte. */
++                      link_path[n] = '\0';
++                      if (*link_path == '/')
++                              /* Start over for an absolute symlink. */
++                              new_path = got_path_root;
++                      else
++                              /* Otherwise back up over this component. */
++                              while (*(--new_path) != '/');
++                      /* Safe sex check. */
++                      if (strlen(path) + n >= PATH_MAX - 2) {
++                              __set_errno(ENAMETOOLONG);
++                              return NULL;
++                      }
++                      /* Insert symlink contents into path. */
++                      strcat(link_path, path);
++                      strcpy(copy_path, link_path);
++                      path = copy_path;
++              }
++#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';
++      strcpy(resolved_path, got_path);
++      return resolved_path;
++}
+diff -urN uClibc-orig/utils/ldconfig.c uClibc-20050502/utils/ldconfig.c
+--- uClibc-orig/utils/ldconfig.c       2005-05-01 23:10:12.000000000 -0700
++++ uClibc-20050502/utils/ldconfig.c   2005-09-16 19:26:33.000000000 -0700
+@@ -22,6 +22,8 @@
+  *
+  * This program may be used for any purpose as long as this
+  * copyright notice is kept.
++ *
++ * 2005/09/16: Dan Howell (modified for cross-development)
+  */
+ #include <stdio.h>
+@@ -37,6 +39,7 @@
+ #include <errno.h>
+ #include <sys/stat.h>
+ #include <sys/mman.h>
++#include "bswap.h"
+ #include "dl-defs.h"
+ #define BUFFER_SIZE 4096
+@@ -56,6 +59,7 @@
+ #if !defined (N_MAGIC)
+ #define N_MAGIC(exec) ((exec).a_info & 0xffff)
+ #endif
++#define N_MAGIC_SWAP(exec) (bswap_32((exec).a_info) & 0xffff)
+ /* Code indicating object file or impure executable.  */
+ #define OMAGIC 0407
+ /* Code indicating pure executable.  */
+@@ -97,6 +101,8 @@
+ char *conffile = LDSO_CONF;   /* default conf file */
+ char *cachefile = LDSO_CACHE; /* default cache file */
+ #endif
++char *chroot_dir = NULL;
++int byteswap = 0;
+ struct needed_tab
+ {
+@@ -117,6 +123,8 @@
+   { NULL,           LIB_ELF }
+ };
++extern char *chroot_realpath(const char *chroot, const char *path, char resolved_path[]);
++
+ /* These two are used internally -- you shouldn't need to use them */
+ static void verror_msg(const char *s, va_list p)
+@@ -242,6 +250,8 @@
+     ElfW(Ehdr) *elf_hdr;
+     struct stat statbuf;
+     char buff[BUFFER_SIZE];
++    char real[BUFFER_SIZE];
++    static int byteswapflag = -1;     /* start with byte-order unknown */
+     /* see if name is of the form *.so* */
+     if (name[strlen(name)-1] != '~' && (cp = strstr(name, ".so")))
+@@ -256,8 +266,12 @@
+       sprintf(buff, "%s%s%s", dir, (*dir && strcmp(dir, "/")) ?
+               "/" : "", name);
++      /* get real path in case of chroot */
++      if (!chroot_realpath(chroot_dir, buff, real))
++          warn("can't resolve %s in chroot %s", buff, chroot_dir);
++
+       /* first, make sure it's a regular file */
+-      if (lstat(buff, &statbuf))
++      if (lstat(real, &statbuf))
+           warn("skipping %s", buff);
+       else if (!S_ISREG(statbuf.st_mode) && !S_ISLNK(statbuf.st_mode))
+           warnx("%s is not a regular file or symlink, skipping", buff);
+@@ -267,14 +281,15 @@
+           *islink = S_ISLNK(statbuf.st_mode);
+           /* then try opening it */
+-          if (!(file = fopen(buff, "rb")))
++          if (!(file = fopen(real, "rb")))
+               warn("skipping %s", buff);
+           else
+           {
+               /* now make sure it's a shared library */
+               if (fread(&exec, sizeof exec, 1, file) < 1)
+                   warnx("can't read header from %s, skipping", buff);
+-              else if (N_MAGIC(exec) != ZMAGIC && N_MAGIC(exec) != QMAGIC)
++              else if (N_MAGIC(exec) != ZMAGIC && N_MAGIC(exec) != QMAGIC &&
++                       N_MAGIC_SWAP(exec) != ZMAGIC && N_MAGIC_SWAP(exec) != QMAGIC)
+               {
+                   elf_hdr = (ElfW(Ehdr) *) &exec;
+                   if (elf_hdr->e_ident[0] != 0x7f ||
+@@ -294,6 +309,9 @@
+                       *type = LIB_ELF;
+                       good = readsoname(buff, file, expected_type, type, 
+                               elf_hdr->e_ident[EI_CLASS]);
++                      if (byteswapflag == -1)
++                          /* byte-order detected */
++                          byteswapflag = byteswap;
+                       if (good == NULL || *islink)
+                       {
+                           if (good != NULL)
+@@ -313,6 +331,12 @@
+               }
+               else
+               {
++                  /* Determine byte-order */
++                  byteswap = (N_MAGIC(exec) == ZMAGIC || N_MAGIC(exec) == QMAGIC) ? 0 : 1;
++                  if (byteswapflag == -1)
++                      /* byte-order detected */
++                      byteswapflag = byteswap;
++
+                   if (*islink)
+                       good = xstrdup(name);
+                   else
+@@ -330,6 +354,14 @@
+                   *type = LIB_DLL;
+               }
+               fclose(file);
++
++              if (byteswapflag >= 0 && byteswap != byteswapflag)
++              {
++                  byteswapflag = -2;
++                  warnx("mixed byte-order detected, using host byte-order...");
++              }
++              if (byteswapflag == -2)
++                  byteswap = 0;
+           }
+       }
+     }
+@@ -343,18 +375,24 @@
+     int change = 1;
+     char libname[BUFFER_SIZE];
+     char linkname[BUFFER_SIZE];
++    char reallibname[BUFFER_SIZE];
++    char reallinkname[BUFFER_SIZE];
+     struct stat libstat;
+     struct stat linkstat;
+     /* construct the full path names */
+     sprintf(libname, "%s/%s", dir, file);
+     sprintf(linkname, "%s/%s", dir, so);
++    if (!chroot_realpath(chroot_dir, libname, reallibname))
++      warn("can't resolve %s in chroot %s", libname, chroot_dir);
++    if (!chroot_realpath(chroot_dir, linkname, reallinkname))
++      warn("can't resolve %s in chroot %s", linkname, chroot_dir);
+     /* see if a link already exists */
+-    if (!stat(linkname, &linkstat))
++    if (!stat(reallinkname, &linkstat))
+     {
+       /* now see if it's the one we want */
+-      if (stat(libname, &libstat))
++      if (stat(reallibname, &libstat))
+           warn("can't stat %s", libname);
+       else if (libstat.st_dev == linkstat.st_dev &&
+               libstat.st_ino == linkstat.st_ino)
+@@ -364,14 +402,14 @@
+     /* then update the link, if required */
+     if (change > 0 && !nolinks)
+     {
+-      if (!lstat(linkname, &linkstat))
++      if (!lstat(reallinkname, &linkstat))
+       {
+           if (!S_ISLNK(linkstat.st_mode))
+           {
+               warnx("%s is not a symlink", linkname);
+               change = -1;
+           }
+-          else if (remove(linkname))
++          else if (remove(reallinkname))
+           {
+               warn("can't unlink %s", linkname);
+               change = -1;
+@@ -379,7 +417,7 @@
+       }
+       if (change > 0)
+       {
+-          if (symlink(file, linkname))
++          if (symlink(file, reallinkname))
+           {
+               warn("can't link %s to %s", linkname, file);
+               change = -1;
+@@ -441,6 +479,7 @@
+     char *so, *path, *path_n;
+     struct lib *lp, *libs = NULL;
+     int i, libtype, islink, expected_type = LIB_ANY;
++    char realname[BUFFER_SIZE];
+     /* We need a writable copy of this string */
+     path = strdup(rawname);
+@@ -500,8 +539,12 @@
+     if (verbose > 0)
+       printf("%s:\n", name);
++    /* get real path in case of chroot */
++    if (!chroot_realpath(chroot_dir, name, realname))
++      warn("can't resolve %s in chroot %s", name, chroot_dir);
++
+     /* if we can't open it, we can't do anything */
+-    if ((dir = opendir(name)) == NULL)
++    if ((dir = opendir(realname)) == NULL)
+     {
+       warn("skipping %s", name);
+       free(path);
+@@ -596,8 +639,12 @@
+     char *res = NULL, *cp;
+     FILE *file;
+     struct stat stat;
++    char realconffile[BUFFER_SIZE];
++
++    if (!chroot_realpath(chroot_dir, conffile, realconffile))
++      return NULL;
+-    if ((file = fopen(conffile, "r")) != NULL)
++    if ((file = fopen(realconffile, "r")) != NULL)
+     {
+       fstat(fileno(file), &stat);
+       res = xmalloc(stat.st_size + 1);
+@@ -678,22 +725,38 @@
+ {
+     int cachefd;
+     int stroffset = 0;
++    char realcachefile[BUFFER_SIZE];
+     char tempfile[BUFFER_SIZE];
++    header_t swap_magic;
++    header_t *magic_ptr;
++    libentry_t swap_lib;
++    libentry_t *lib_ptr;
+     liblist_t *cur_lib;
+     if (!magic.nlibs)
+       return;
+-    sprintf(tempfile, "%s~", cachefile);
++    if (!chroot_realpath(chroot_dir, cachefile, realcachefile))
++      err(EXIT_FATAL,"can't resolve %s in chroot %s (%s)",
++          cachefile, chroot_dir, strerror(errno));
++
++    sprintf(tempfile, "%s~", realcachefile);
+     if (unlink(tempfile) && errno != ENOENT)
+-      err(EXIT_FATAL,"can't unlink %s (%s)", tempfile, strerror(errno));
++      err(EXIT_FATAL,"can't unlink %s~ (%s)", cachefile, strerror(errno));
+     if ((cachefd = creat(tempfile, 0644)) < 0)
+-      err(EXIT_FATAL,"can't create %s (%s)", tempfile, strerror(errno));
++      err(EXIT_FATAL,"can't create %s~ (%s)", cachefile, strerror(errno));
+-    if (write(cachefd, &magic, sizeof (header_t)) != sizeof (header_t))
+-      err(EXIT_FATAL,"can't write %s (%s)", tempfile, strerror(errno));
++    if (byteswap) {
++      swap_magic = magic;
++      swap_magic.nlibs = bswap_32(swap_magic.nlibs);
++      magic_ptr = &swap_magic;
++    } else {
++      magic_ptr = &magic;
++    }
++    if (write(cachefd, magic_ptr, sizeof (header_t)) != sizeof (header_t))
++      err(EXIT_FATAL,"can't write %s~ (%s)", cachefile, strerror(errno));
+     for (cur_lib = lib_head; cur_lib != NULL; cur_lib = cur_lib->next)
+     {
+@@ -701,29 +764,37 @@
+       stroffset += strlen(cur_lib->soname) + 1;
+       cur_lib->liboffset = stroffset;
+       stroffset += strlen(cur_lib->libname) + 1;
+-      if (write(cachefd, cur_lib, sizeof (libentry_t)) !=
+-              sizeof (libentry_t))
+-          err(EXIT_FATAL,"can't write %s (%s)", tempfile, strerror(errno));
++      if (byteswap) {
++          swap_lib.flags = bswap_32(cur_lib->flags);
++          swap_lib.sooffset = bswap_32(cur_lib->sooffset);
++          swap_lib.liboffset = bswap_32(cur_lib->liboffset);
++          lib_ptr = &swap_lib;
++      } else {
++          lib_ptr = (libentry_t *)cur_lib;
++      }
++      if (write(cachefd, lib_ptr, sizeof (libentry_t)) !=
++          sizeof (libentry_t))
++      err(EXIT_FATAL,"can't write %s~ (%s)", cachefile, strerror(errno));
+     }
+     for (cur_lib = lib_head; cur_lib != NULL; cur_lib = cur_lib->next)
+     {
+       if (write(cachefd, cur_lib->soname, strlen(cur_lib->soname) + 1)
+               != strlen(cur_lib->soname) + 1)
+-          err(EXIT_FATAL,"can't write %s (%s)", tempfile, strerror(errno));
++          err(EXIT_FATAL,"can't write %s~ (%s)", cachefile, strerror(errno));
+       if (write(cachefd, cur_lib->libname, strlen(cur_lib->libname) + 1)
+               != strlen(cur_lib->libname) + 1)
+-          err(EXIT_FATAL,"can't write %s (%s)", tempfile, strerror(errno));
++          err(EXIT_FATAL,"can't write %s~ (%s)", cachefile, strerror(errno));
+     }
+     if (close(cachefd))
+-      err(EXIT_FATAL,"can't close %s (%s)", tempfile, strerror(errno));
++      err(EXIT_FATAL,"can't close %s~ (%s)", cachefile, strerror(errno));
+     if (chmod(tempfile, 0644))
+-      err(EXIT_FATAL,"can't chmod %s (%s)", tempfile, strerror(errno));
++      err(EXIT_FATAL,"can't chmod %s~ (%s)", cachefile, strerror(errno));
+-    if (rename(tempfile, cachefile))
+-      err(EXIT_FATAL,"can't rename %s (%s)", tempfile, strerror(errno));
++    if (rename(tempfile, realcachefile))
++      err(EXIT_FATAL,"can't rename %s~ (%s)", cachefile, strerror(errno));
+ }
+ void cache_print(void)
+@@ -734,8 +805,13 @@
+     char *strs;
+     header_t *header;
+     libentry_t *libent;
++    char realcachefile[BUFFER_SIZE];
++
++    if (!chroot_realpath(chroot_dir, cachefile, realcachefile))
++      err(EXIT_FATAL,"can't resolve %s in chroot %s (%s)",
++          cachefile, chroot_dir, strerror(errno));
+-    if (stat(cachefile, &st) || (fd = open(cachefile, O_RDONLY))<0)
++    if (stat(realcachefile, &st) || (fd = open(realcachefile, O_RDONLY))<0)
+       err(EXIT_FATAL,"can't read %s (%s)", cachefile, strerror(errno));
+     if ((c = mmap(0,st.st_size, PROT_READ, MAP_SHARED ,fd, 0)) == (caddr_t)-1)
+       err(EXIT_FATAL,"can't map %s (%s)", cachefile, strerror(errno));
+@@ -828,7 +904,6 @@
+     int nodefault = 0;
+     char *cp, *dir, *so;
+     int libtype, islink;
+-    char *chroot_dir = NULL;
+     int printcache = 0;
+ #ifdef __LDSO_CACHE_SUPPORT__
+     char *extpath;
+@@ -891,10 +966,16 @@
+       }
+     if (chroot_dir && *chroot_dir) {
+-      if (chroot(chroot_dir) < 0)
+-          err(EXIT_FATAL,"couldn't chroot to %s (%s)", chroot_dir, strerror(errno));
+-      if (chdir("/") < 0)
+-          err(EXIT_FATAL,"couldn't chdir to / (%s)", strerror(errno));
++      if (chroot(chroot_dir) < 0) {
++          if (chdir(chroot_dir) < 0)
++              err(EXIT_FATAL,"couldn't chroot to %s (%s)", chroot_dir, strerror(errno));
++      }
++      else
++      {
++          if (chdir("/") < 0)
++              err(EXIT_FATAL,"couldn't chdir to / (%s)", strerror(errno));
++          chroot_dir = NULL;
++      }
+     }
+     /* allow me to introduce myself, hi, my name is ... */
+diff -urN uClibc-orig/utils/Makefile uClibc-20050502/utils/Makefile
+--- uClibc-orig/utils/Makefile 2005-05-01 23:10:12.000000000 -0700
++++ uClibc-20050502/utils/Makefile     2005-09-16 19:28:55.000000000 -0700
+@@ -29,6 +29,12 @@
+ TARGET_ICONV =
+ endif
++ifeq ($(strip $(LDSO_CACHE_SUPPORT)),y)
++HOST_LDSO_CACHE_FLAG = -D__LDSO_CACHE_SUPPORT__=1
++else
++HOST_LDSO_CACHE_FLAG =
++endif
++
+ # NOTE: We build the utils AFTER we have a uClibc-targeted toolchain.
+ ifeq ($(strip $(HAVE_SHARED)),y)
+@@ -51,7 +57,7 @@
+ else
+ LDCONFIG_CFLAGS := $(PIEFLAG) $(LDPIEFLAG)
+ endif
+-ldconfig: ldconfig.c
++ldconfig: ldconfig.c chroot_realpath.c
+       $(CC) $(CFLAGS) $(LDCONFIG_CFLAGS) \
+               -DUCLIBC_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" \
+               -DUCLIBC_LDSO=$(UCLIBC_LDSO) -I. -I../ldso/include \
+@@ -79,13 +85,13 @@
+ ldd.host: ldd.c
+       $(HOSTCC) $(HOSTCFLAGS) -Wl,-s \
+-              -DUCLIBC_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" \
++              -DUCLIBC_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" $(HOST_LDSO_CACHE_FLAG) \
+               -DUCLIBC_LDSO=$(UCLIBC_LDSO) -I. -I../ldso/include \
+               $^ -o $@
+-ldconfig.host: ldconfig.c
++ldconfig.host: ldconfig.c chroot_realpath.c
+       $(HOSTCC) $(HOSTCFLAGS) -Wl,-s \
+-              -DUCLIBC_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" \
++              -DUCLIBC_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" $(HOST_LDSO_CACHE_FLAG) \
+               -DUCLIBC_LDSO=$(UCLIBC_LDSO) -I. -I../ldso/include \
+               $^ -o $@
+diff -urN uClibc-orig/utils/readsoname2.c uClibc-20050502/utils/readsoname2.c
+--- uClibc-orig/utils/readsoname2.c    2005-05-01 23:10:12.000000000 -0700
++++ uClibc-20050502/utils/readsoname2.c        2005-09-16 17:48:59.000000000 -0700
+@@ -26,7 +26,7 @@
+   if (fstat(fileno(infile), &st))
+     return NULL;
+-  header = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fileno(infile), 0);
++  header = mmap(0, st.st_size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fileno(infile), 0);
+   if (header == (caddr_t)-1)
+     return NULL;
+@@ -34,6 +34,19 @@
+   if ((char *)(epnt+1) > (char *)(header + st.st_size))
+     goto skip;
++#if __BYTE_ORDER == __LITTLE_ENDIAN
++  byteswap = (epnt->e_ident[5] == ELFDATA2MSB) ? 1 : 0;
++#elif __BYTE_ORDER == __BIG_ENDIAN
++  byteswap = (epnt->e_ident[5] == ELFDATA2LSB) ? 1 : 0;
++#else
++#error Unknown host byte order!
++#endif
++  /* Be very lazy, and only byteswap the stuff we use */
++  if (byteswap==1) {
++    epnt->e_phoff=bswap_32(epnt->e_phoff);
++    epnt->e_phnum=bswap_16(epnt->e_phnum);
++  }
++
+   ppnt = (ElfW(Phdr) *)&header[epnt->e_phoff];
+   if ((char *)ppnt < (char *)header ||
+       (char *)(ppnt+epnt->e_phnum) > (char *)(header + st.st_size))
+@@ -41,6 +54,14 @@
+   for(i = 0; i < epnt->e_phnum; i++)
+   {
++    /* Be very lazy, and only byteswap the stuff we use */
++    if (byteswap==1) {
++      ppnt->p_type=bswap_32(ppnt->p_type);
++      ppnt->p_vaddr=bswap_32(ppnt->p_vaddr);
++      ppnt->p_offset=bswap_32(ppnt->p_offset);
++      ppnt->p_filesz=bswap_32(ppnt->p_filesz);
++    }
++
+     if (loadaddr == -1 && ppnt->p_type == PT_LOAD) 
+       loadaddr = (ppnt->p_vaddr & ~(page_size-1)) -
+       (ppnt->p_offset & ~(page_size-1));
+@@ -58,11 +79,20 @@
+       (char *)(dpnt+dynamic_size) > (char *)(header + st.st_size))
+     goto skip;
+   
++  if (byteswap==1) {
++    dpnt->d_tag=bswap_32(dpnt->d_tag);
++    dpnt->d_un.d_val=bswap_32(dpnt->d_un.d_val);
++  }
++
+   while (dpnt->d_tag != DT_NULL)
+   {
+     if (dpnt->d_tag == DT_STRTAB)
+       strtab_val = dpnt->d_un.d_val;
+     dpnt++;
++    if (byteswap==1) {
++      dpnt->d_tag=bswap_32(dpnt->d_tag);
++      dpnt->d_un.d_val=bswap_32(dpnt->d_un.d_val);
++    }
+   };
+   if (!strtab_val)
diff --git a/toolchain/uClibc/uClibc-0.9.28-300-ldso.patch b/toolchain/uClibc/uClibc-0.9.28-300-ldso.patch
new file mode 100644 (file)
index 0000000..4081fc7
--- /dev/null
@@ -0,0 +1,5190 @@
+diff -urN uClibc-0.9.28.orig/include/elf.h uClibc-0.9.28/include/elf.h
+--- uClibc-0.9.28.orig/include/elf.h   2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/include/elf.h        2006-04-28 00:14:35.000000000 -0600
+@@ -142,6 +142,7 @@
+ #define ELFOSABI_HPUX         1       /* HP-UX */
+ #define ELFOSABI_NETBSD               2       /* NetBSD.  */
+ #define ELFOSABI_LINUX                3       /* Linux.  */
++#define ELFOSABI_HURD         4       /* GNU/Hurd */
+ #define ELFOSABI_SOLARIS      6       /* Sun Solaris.  */
+ #define ELFOSABI_AIX          7       /* IBM AIX.  */
+ #define ELFOSABI_IRIX         8       /* SGI Irix.  */
+@@ -149,6 +150,9 @@
+ #define ELFOSABI_TRU64                10      /* Compaq TRU64 UNIX.  */
+ #define ELFOSABI_MODESTO      11      /* Novell Modesto.  */
+ #define ELFOSABI_OPENBSD      12      /* OpenBSD.  */
++#define ELFOSABI_OPENVMS      13      /* OpenVMS */
++#define ELFOSABI_NSK          14      /* Hewlett-Packard Non-Stop Kernel */
++#define ELFOSABI_AROS         15      /* Amiga Research OS */
+ #define ELFOSABI_ARM          97      /* ARM */
+ #define ELFOSABI_STANDALONE   255     /* Standalone (embedded) application */
+@@ -177,6 +181,7 @@
+ #define EM_386                 3              /* Intel 80386 */
+ #define EM_68K                 4              /* Motorola m68k family */
+ #define EM_88K                 5              /* Motorola m88k family */
++#define EM_486                 6              /* Intel 80486 *//* Reserved for future use */
+ #define EM_860                 7              /* Intel 80860 */
+ #define EM_MIPS                8              /* MIPS R3000 big-endian */
+ #define EM_S370                9              /* IBM System/370 */
+@@ -193,7 +198,8 @@
+ #define EM_V800               36              /* NEC V800 series */
+ #define EM_FR20               37              /* Fujitsu FR20 */
+ #define EM_RH32               38              /* TRW RH-32 */
+-#define EM_RCE                39              /* Motorola RCE */
++#define EM_MCORE      39              /* Motorola M*Core */ /* May also be taken by Fujitsu MMA */
++#define EM_RCE                39              /* Old name for MCore */
+ #define EM_ARM                40              /* ARM */
+ #define EM_FAKE_ALPHA 41              /* Digital Alpha */
+ #define EM_SH         42              /* Renesas SH */
+@@ -248,18 +254,105 @@
+ #define EM_OPENRISC   92              /* OpenRISC 32-bit embedded processor */
+ #define EM_ARC_A5     93              /* ARC Cores Tangent-A5 */
+ #define EM_XTENSA     94              /* Tensilica Xtensa Architecture */
++#define EM_IP2K               101             /* Ubicom IP2022 micro controller */
++#define EM_CR         103             /* National Semiconductor CompactRISC */
++#define EM_MSP430     105             /* TI msp430 micro controller */
++#define EM_BLACKFIN   106             /* Analog Devices Blackfin */
++#define EM_ALTERA_NIOS2       113     /* Altera Nios II soft-core processor */
++#define EM_CRX                114             /* National Semiconductor CRX */
+ #define EM_NUM                95
+-/* If it is necessary to assign new unofficial EM_* values, please
+-   pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the
+-   chances of collision with official or non-GNU unofficial values.  */
++/* If it is necessary to assign new unofficial EM_* values, please pick large
++   random numbers (0x8523, 0xa7f2, etc.) to minimize the chances of collision
++   with official or non-GNU unofficial values.
+-/* Fujitsu FR-V.  */
++   NOTE: Do not just increment the most recent number by one.
++   Somebody else somewhere will do exactly the same thing, and you
++   will have a collision.  Instead, pick a random number.
++
++   Normally, each entity or maintainer responsible for a machine with an
++   unofficial e_machine number should eventually ask registry@caldera.com for
++   an officially blessed number to be added to the list above.  */
++
++/* picoJava */
++#define EM_PJ_OLD     99
++
++/* Cygnus PowerPC ELF backend.  Written in the absence of an ABI.  */
++#define EM_CYGNUS_POWERPC 0x9025
++
++/* Old version of Sparc v9, from before the ABI; this should be
++   removed shortly.  */
++#define EM_OLD_SPARCV9        11
++
++/* Old version of PowerPC, this should be removed shortly. */
++#define EM_PPC_OLD    17
++
++/* (Deprecated) Temporary number for the OpenRISC processor.  */
++#define EM_OR32               0x8472
++
++/* Renesas M32C and M16C.  */
++#define EM_M32C                       0xFEB0
++
++/* Cygnus M32R ELF backend.  Written in the absence of an ABI.  */
++#define EM_CYGNUS_M32R        0x9041
++
++/* old S/390 backend magic number. Written in the absence of an ABI.  */
++#define EM_S390_OLD   0xa390
++
++/* D10V backend magic number.  Written in the absence of an ABI.  */
++#define EM_CYGNUS_D10V        0x7650
++
++/* D30V backend magic number.  Written in the absence of an ABI.  */
++#define EM_CYGNUS_D30V        0x7676
++
++/* V850 backend magic number.  Written in the absense of an ABI.  */
++#define EM_CYGNUS_V850        0x9080
++
++/* mn10200 and mn10300 backend magic numbers.
++   Written in the absense of an ABI.  */
++#define EM_CYGNUS_MN10200     0xdead
++#define EM_CYGNUS_MN10300     0xbeef
++
++/* FR30 magic number - no EABI available.  */
++#define EM_CYGNUS_FR30                0x3330
++
++/* AVR magic number
++   Written in the absense of an ABI.  */
++#define EM_AVR_OLD            0x1057
++
++/* OpenRISC magic number
++   Written in the absense of an ABI.  */
++#define EM_OPENRISC_OLD               0x3426
++
++/* DLX magic number
++   Written in the absense of an ABI.  */
++#define EM_DLX                        0x5aa5
++
++#define EM_XSTORMY16          0xad45
++
++/* FRV magic number - no EABI available??.  */
+ #define EM_CYGNUS_FRV 0x5441
++/* Ubicom IP2xxx; no ABI */
++#define EM_IP2K_OLD           0x8217
++
++#define EM_MT                   0x2530  /* Morpho MT; no ABI */
++
++/* MSP430 magic number
++      Written in the absense everything.  */
++#define EM_MSP430_OLD         0x1059
++
++/* Vitesse IQ2000.  */
++#define EM_IQ2000             0xFEBA
++
++/* Old, unofficial value for Xtensa.  */
++#define EM_XTENSA_OLD         0xabc7
++
++/* Alpha backend magic number.  Written in the absence of an ABI.  */
+ #define EM_ALPHA      0x9026
+-#define EM_NIOS32     0xfebb          /* Altera Nios 32 */
+-#define EM_ALTERA_NIOS2  0x9ee5       /* Altera Nios II */
++
++/* NIOS magic number - no EABI available.  */
++#define EM_NIOS32     0xFEBB
+ /* V850 backend magic number.  Written in the absense of an ABI.  */
+ #define EM_CYGNUS_V850 0x9080
+@@ -2498,6 +2591,12 @@
+ #define R_390_NUM             61
++/* CRIS flags.  */
++#define EF_CRIS_VARIANT_MASK           0x0000000e
++#define EF_CRIS_VARIANT_ANY_V0_V10     0x00000000
++#define EF_CRIS_VARIANT_V32            0x00000002
++#define EF_CRIS_VARIANT_COMMON_V10_V32 0x00000004
++
+ /* CRIS relocations.  */
+ #define R_CRIS_NONE           0
+ #define R_CRIS_8              1
+@@ -2688,6 +2787,7 @@
+ #define R_V850_NUM            25
++/* Renesas H8/300 Relocations */
+ #define R_H8_NONE       0
+ #define R_H8_DIR32      1
+ #define R_H8_DIR32_28   2
+@@ -2731,8 +2831,7 @@
+ #define R_H8_DIR32A16  63
+ #define R_H8_ABS32     65
+ #define R_H8_ABS32A16 127
+-
+-/* Altera NIOS specific definitions.  */
++#define R_H8_NUM      128
+ /* NIOS relocations. */
+ #define R_NIOS_NONE                           0
+diff -urN uClibc-0.9.28.orig/include/errno.h uClibc-0.9.28/include/errno.h
+--- uClibc-0.9.28.orig/include/errno.h 2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/include/errno.h      2006-04-28 00:14:35.000000000 -0600
+@@ -43,9 +43,11 @@
+    variable.  This redeclaration using the macro still works, but it
+    will be a function declaration without a prototype and may trigger
+    a -Wstrict-prototypes warning.  */
++#ifndef __ASSEMBLER__
+ #ifndef       errno
+ extern int errno;
+ #endif
++#endif
+ #if 0 /*def __USE_GNU      uClibc note: not supported */
+diff -urN uClibc-0.9.28.orig/ldso/Makefile uClibc-0.9.28/ldso/Makefile
+--- uClibc-0.9.28.orig/ldso/Makefile   2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/Makefile        2006-04-28 00:14:35.000000000 -0600
+@@ -37,15 +37,12 @@
+ LN_HEADERS      := $(patsubst %, include/%, elf.h)
+ LN_ARCH_HEADERS := $(patsubst %, include/%, dl-startup.h dl-syscalls.h dl-sysdep.h dl-debug.h)
+-HEADERS         := $(LN_HEADERS) $(LN_ARCH_HEADERS) include/dl-progname.h
++HEADERS         := $(LN_HEADERS) $(LN_ARCH_HEADERS)
+ headers: $(HEADERS)
+ $(LN_HEADERS):
+       $(LN) -fs $(TOPDIR)../$@ $@
+ $(LN_ARCH_HEADERS):
+       $(LN) -fs ../ldso/$(TARGET_ARCH)/$(patsubst include/%,%,$@) $@
+-include/dl-progname.h:
+-      echo '#include "$(TARGET_ARCH)/elfinterp.c"' \
+-              > include/dl-progname.h
+ clean:
+       set -e ; for d in $(DIRS) ; do $(MAKE) -C $$d $@ ; done
+diff -urN uClibc-0.9.28.orig/ldso/include/dl-defs.h uClibc-0.9.28/ldso/include/dl-defs.h
+--- uClibc-0.9.28.orig/ldso/include/dl-defs.h  2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/include/dl-defs.h       2006-04-28 00:14:35.000000000 -0600
+@@ -1,6 +1,29 @@
++/* vi: set sw=4 ts=4: */
++/*
++ * Copyright (C) 2000-2005 by Erik Andersen <andersen@codepoet.org>
++ *
++ * GNU Lesser General Public License version 2.1 or later.
++ */
++
+ #ifndef _LD_DEFS_H
+ #define _LD_DEFS_H
++#define FLAG_ANY             -1
++#define FLAG_TYPE_MASK       0x00ff
++#define FLAG_LIBC4           0x0000
++#define FLAG_ELF             0x0001
++#define FLAG_ELF_LIBC5       0x0002
++#define FLAG_ELF_LIBC6       0x0003
++#define FLAG_ELF_UCLIBC      0x0004
++#define FLAG_REQUIRED_MASK   0xff00
++#define FLAG_SPARC_LIB64     0x0100
++#define FLAG_IA64_LIB64      0x0200
++#define FLAG_X8664_LIB64     0x0300
++#define FLAG_S390_LIB64      0x0400
++#define FLAG_POWERPC_LIB64   0x0500
++#define FLAG_MIPS64_LIBN32   0x0600
++#define FLAG_MIPS64_LIBN64   0x0700
++
+ #define LIB_ANY            -1
+ #define LIB_DLL       0
+ #define LIB_ELF       1
+diff -urN uClibc-0.9.28.orig/ldso/include/dl-elf.h uClibc-0.9.28/ldso/include/dl-elf.h
+--- uClibc-0.9.28.orig/ldso/include/dl-elf.h   2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/include/dl-elf.h        2006-04-28 00:14:35.000000000 -0600
+@@ -1,3 +1,10 @@
++/* vi: set sw=4 ts=4: */
++/*
++ * Copyright (C) 2000-2005 by Erik Andersen <andersen@codepoet.org>
++ *
++ * GNU Lesser General Public License version 2.1 or later.
++ */
++
+ #ifndef LINUXELF_H
+ #define LINUXELF_H
+diff -urN uClibc-0.9.28.orig/ldso/include/dl-hash.h uClibc-0.9.28/ldso/include/dl-hash.h
+--- uClibc-0.9.28.orig/ldso/include/dl-hash.h  2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/include/dl-hash.h       2006-04-28 00:14:35.000000000 -0600
+@@ -1,3 +1,10 @@
++/* vi: set sw=4 ts=4: */
++/*
++ * Copyright (C) 2000-2005 by Erik Andersen <andersen@codepoet.org>
++ *
++ * GNU Lesser General Public License version 2.1 or later.
++ */
++
+ #ifndef _LD_HASH_H_
+ #define _LD_HASH_H_
+@@ -32,15 +39,15 @@
+   unsigned short usage_count;
+   unsigned short int init_flag;
+   unsigned long rtld_flags; /* RTLD_GLOBAL, RTLD_NOW etc. */
+-  Elf32_Word nbucket;
+-  Elf32_Word *elf_buckets;
++  Elf_Symndx nbucket;
++  Elf_Symndx *elf_buckets;
+   struct init_fini_list *init_fini;
+   struct init_fini_list *rtld_local; /* keep tack of RTLD_LOCAL libs in same group */
+   /*
+    * These are only used with ELF style shared libraries
+    */
+-  Elf32_Word nchain;
+-  Elf32_Word *chains;
++  Elf_Symndx nchain;
++  Elf_Symndx *chains;
+   unsigned long dynamic_info[DYNAMIC_SIZE];
+   unsigned long n_phent;
+@@ -49,6 +56,9 @@
+   ElfW(Addr) relro_addr;
+   size_t relro_size;
++  dev_t st_dev;      /* device */
++  ino_t st_ino;      /* inode */
++
+ #ifdef __powerpc__
+   /* this is used to store the address of relocation data words, so
+    * we don't have to calculate it every time, which requires a divide */
+@@ -66,7 +76,6 @@
+ extern struct elf_resolve * _dl_loaded_modules;
+ extern struct dyn_elf           * _dl_handles;
+-extern struct elf_resolve * _dl_check_hashed_files(const char * libname);
+ extern struct elf_resolve * _dl_add_elf_hash_table(const char * libname, 
+       char * loadaddr, unsigned long * dynamic_info, 
+       unsigned long dynamic_addr, unsigned long dynamic_size);
+diff -urN uClibc-0.9.28.orig/ldso/include/dl-string.h uClibc-0.9.28/ldso/include/dl-string.h
+--- uClibc-0.9.28.orig/ldso/include/dl-string.h        2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/include/dl-string.h     2006-04-28 00:14:35.000000000 -0600
+@@ -1,9 +1,24 @@
++/* vi: set sw=4 ts=4: */
++/*
++ * Copyright (C) 2000-2005 by Erik Andersen <andersen@codepoet.org>
++ *
++ * GNU Lesser General Public License version 2.1 or later.
++ */
++
+ #ifndef _LINUX_STRING_H_
+ #define _LINUX_STRING_H_
+-#include <dl-sysdep.h> // for do_rem
++#include <dl-sysdep.h> /* for do_rem */
+ #include <features.h>
++/* provide some sane defaults */
++#ifndef do_rem
++# define do_rem(result, n, base) ((result) = (n) % (base))
++#endif
++#ifndef do_div_10
++# define do_div_10(result, remain) ((result) /= 10)
++#endif
++
+ static size_t _dl_strlen(const char * str);
+ static char *_dl_strcat(char *dst, const char *src);
+ static char * _dl_strcpy(char * dst,const char *src);
+@@ -26,8 +41,8 @@
+ static __always_inline size_t _dl_strlen(const char * str)
+ {
+       register const char *ptr = (char *) str-1;
+-
+-      while (*++ptr);
++      while (*++ptr)
++              ;/* empty */
+       return (ptr - str);
+ }
+@@ -49,7 +64,8 @@
+       register char *ptr = dst;
+       dst--;src--;
+-      while ((*++dst = *++src) != 0);
++      while ((*++dst = *++src) != 0)
++              ;/* empty */
+       return ptr;
+ }
+@@ -63,8 +79,7 @@
+               c2 = (unsigned char) *++s2;
+               if (c1 == '\0')
+                       return c1 - c2;
+-      }
+-      while (c1 == c2);
++      } while (c1 == c2);
+       return c1 - c2;
+ }
+@@ -98,43 +113,41 @@
+       return 0;
+ }
+-static inline char * _dl_strrchr(const char *str, int c)
++static __always_inline char * _dl_strrchr(const char *str, int c)
+ {
+-    register char *prev = 0;
+-    register char *ptr = (char *) str-1;
++      register char *prev = 0;
++      register char *ptr = (char *) str-1;
+-    while (*++ptr != '\0') {
+-      if (*ptr == c)
+-          prev = ptr;
+-    }
+-    if (c == '\0')
+-      return(ptr);
+-    return(prev);
++      while (*++ptr != '\0') {
++              if (*ptr == c)
++                      prev = ptr;
++      }
++      if (c == '\0')
++              return(ptr);
++      return(prev);
+ }
+-static inline char * _dl_strstr(const char *s1, const char *s2)
++static __always_inline char * _dl_strstr(const char *s1, const char *s2)
+ {
+-    register const char *s = s1;
+-    register const char *p = s2;
++      register const char *s = s1;
++      register const char *p = s2;
+-    do {
+-        if (!*p) {
+-          return (char *) s1;;
+-      }
+-      if (*p == *s) {
+-          ++p;
+-          ++s;
+-      } else {
+-          p = s2;
+-          if (!*s) {
+-            return NULL;
+-          }
+-          s = ++s1;
+-      }
+-    } while (1);
++      do {
++              if (!*p)
++                      return (char *) s1;;
++              if (*p == *s) {
++                      ++p;
++                      ++s;
++              } else {
++                      p = s2;
++                      if (!*s)
++                              return NULL;
++                      s = ++s1;
++              }
++      } while (1);
+ }
+-static inline void * _dl_memcpy(void * dst, const void * src, size_t len)
++static __always_inline void * _dl_memcpy(void * dst, const void * src, size_t len)
+ {
+       register char *a = dst-1;
+       register const char *b = src-1;
+@@ -163,27 +176,28 @@
+ /* Will generate smaller and faster code due to loop unrolling.*/
+ static __always_inline void * _dl_memset(void *to, int c, size_t n)
+ {
+-        unsigned long chunks;
+-        unsigned long *tmp_to;
++      unsigned long chunks;
++      unsigned long *tmp_to;
+       unsigned char *tmp_char;
+-        chunks = n / 4;
+-        tmp_to = to + n;
+-        c = c << 8 | c;
+-        c = c << 16 | c;
+-        if (!chunks)
+-                goto lessthan4;
+-        do {
+-                *--tmp_to = c;
+-        } while (--chunks);
+- lessthan4:
+-        n = n % 4;
+-        if (!n ) return to;
+-        tmp_char = (unsigned char *)tmp_to;
+-        do {
+-                *--tmp_char = c;
+-        } while (--n);
+-        return to;
++      chunks = n / 4;
++      tmp_to = to + n;
++      c = c << 8 | c;
++      c = c << 16 | c;
++      if (!chunks)
++              goto lessthan4;
++      do {
++              *--tmp_to = c;
++      } while (--chunks);
++lessthan4:
++      n = n % 4;
++      if (!n)
++              return to;
++      tmp_char = (unsigned char *)tmp_to;
++      do {
++              *--tmp_char = c;
++      } while (--n);
++      return to;
+ }
+ #else
+ static __always_inline void * _dl_memset(void * str,int c,size_t len)
+@@ -225,10 +239,10 @@
+       char *p = &local[22];
+       *--p = '\0';
+       do {
+-          char temp;
+-          do_rem(temp, i, 10);
+-          *--p = '0' + temp;
+-          i /= 10;
++              char temp;
++              do_rem(temp, i, 10);
++              *--p = '0' + temp;
++              do_div_10(i, temp);
+       } while (i > 0);
+       return p;
+ }
+@@ -242,9 +256,9 @@
+       do {
+               char temp = i & 0xf;
+               if (temp <= 0x09)
+-                  *--p = '0' + temp;
++                      *--p = '0' + temp;
+               else
+-                  *--p = 'a' - 0x0a + temp;
++                      *--p = 'a' - 0x0a + temp;
+               i >>= 4;
+       } while (i > 0);
+       *--p = 'x';
+@@ -270,8 +284,8 @@
+ /* On some arches constant strings are referenced through the GOT.
+  * This requires that load_addr must already be defined... */
+-#if defined(mc68000) || defined(__arm__) || defined(__mips__) \
+-                     || defined(__sh__) ||  defined(__powerpc__)
++#if defined(mc68000)  || defined(__arm__) || defined(__thumb__) || \
++    defined(__mips__) || defined(__sh__)  || defined(__powerpc__)
+ # define CONSTANT_STRING_GOT_FIXUP(X) \
+       if ((X) < (const char *) load_addr) (X) += load_addr
+ # define NO_EARLY_SEND_STDERR
+@@ -318,7 +332,7 @@
+       do { \
+               do_rem(v, (X), 10); \
+               *--tmp2 = '0' + v; \
+-              (X) /= 10; \
++              do_div_10((X), v); \
+       } while ((X) > 0); \
+       _dl_write(2, tmp2, tmp1 - tmp2 + sizeof(tmp) - 1); \
+ }
+diff -urN uClibc-0.9.28.orig/ldso/include/dl-syscall.h uClibc-0.9.28/ldso/include/dl-syscall.h
+--- uClibc-0.9.28.orig/ldso/include/dl-syscall.h       2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/include/dl-syscall.h    2006-04-28 00:14:35.000000000 -0600
+@@ -1,3 +1,10 @@
++/* vi: set sw=4 ts=4: */
++/*
++ * Copyright (C) 2000-2005 by Erik Andersen <andersen@codepoet.org>
++ *
++ * GNU Lesser General Public License version 2.1 or later.
++ */
++
+ #ifndef _LD_SYSCALL_H_
+ #define _LD_SYSCALL_H_
+@@ -12,9 +19,8 @@
+ #include <bits/kernel_stat.h>
+ #include <bits/kernel_types.h>
+-
+ /* _dl_open() parameters */
+-#define O_RDONLY        0x0000
++#define O_RDONLY           00
+ #define O_WRONLY           01
+ #define O_RDWR                     02
+ #define O_CREAT                  0100
+@@ -39,18 +45,6 @@
+ #define       S_IWRITE        0200    /* Write by owner.  */
+ #define       S_IEXEC         0100    /* Execute by owner.  */
+-/* Stuff for _dl_mmap */
+-#if 0
+-#define MAP_FAILED    ((void *) -1)
+-#define _dl_mmap_check_error(X) (((void *)X) == MAP_FAILED)
+-#else
+-#ifndef _dl_MAX_ERRNO
+-#define _dl_MAX_ERRNO 4096
+-#endif
+-#define _dl_mmap_check_error(__res) \
+-      (((long)__res) < 0 && ((long)__res) >= -_dl_MAX_ERRNO)
+-#endif
+-
+ /* Here are the definitions for some syscalls that are used
+@@ -66,54 +60,125 @@
+ static inline _syscall1(int, _dl_close, int, fd);
+ #define __NR__dl_open __NR_open
+-static inline _syscall3(int, _dl_open, const char *, fn, int, flags, __kernel_mode_t, mode);
++static inline _syscall3(int, _dl_open, const char *, fn, int, flags,
++                        __kernel_mode_t, mode);
+ #define __NR__dl_write __NR_write
+ static inline _syscall3(unsigned long, _dl_write, int, fd,
+-          const void *, buf, unsigned long, count);
++                        const void *, buf, unsigned long, count);
+ #define __NR__dl_read __NR_read
+ static inline _syscall3(unsigned long, _dl_read, int, fd,
+-          const void *, buf, unsigned long, count);
++                        const void *, buf, unsigned long, count);
+ #define __NR__dl_mprotect __NR_mprotect
+-static inline _syscall3(int, _dl_mprotect, const void *, addr, unsigned long, len, int, prot);
++static inline _syscall3(int, _dl_mprotect, const void *, addr,
++                        unsigned long, len, int, prot);
+ #define __NR__dl_stat __NR_stat
+-static inline _syscall2(int, _dl_stat, const char *, file_name, struct stat *, buf);
++static inline _syscall2(int, _dl_stat, const char *, file_name,
++                        struct stat *, buf);
++
++#define __NR__dl_fstat __NR_fstat
++static inline _syscall2(int, _dl_fstat, int, fd, struct stat *, buf);
+ #define __NR__dl_munmap __NR_munmap
+ static inline _syscall2(int, _dl_munmap, void *, start, unsigned long, length);
++#ifdef __NR_getxuid
++# define __NR_getuid __NR_getxuid
++#endif
+ #define __NR__dl_getuid __NR_getuid
+ static inline _syscall0(uid_t, _dl_getuid);
++#ifndef __NR_geteuid
++# define __NR_geteuid __NR_getuid
++#endif
+ #define __NR__dl_geteuid __NR_geteuid
+ static inline _syscall0(uid_t, _dl_geteuid);
++#ifdef __NR_getxgid
++# define __NR_getgid __NR_getxgid
++#endif
+ #define __NR__dl_getgid __NR_getgid
+ static inline _syscall0(gid_t, _dl_getgid);
++#ifndef __NR_getegid
++# define __NR_getegid __NR_getgid
++#endif
+ #define __NR__dl_getegid __NR_getegid
+ static inline _syscall0(gid_t, _dl_getegid);
++#ifdef __NR_getxpid
++# define __NR_getpid __NR_getxpid
++#endif
+ #define __NR__dl_getpid __NR_getpid
+ static inline _syscall0(gid_t, _dl_getpid);
+ #define __NR__dl_readlink __NR_readlink
+-static inline _syscall3(int, _dl_readlink, const char *, path, char *, buf, size_t, bufsiz);
++static inline _syscall3(int, _dl_readlink, const char *, path, char *, buf,
++                        size_t, bufsiz);
+-#ifdef __NR_mmap
+-#ifdef MMAP_HAS_6_ARGS
+-#define __NR__dl_mmap __NR_mmap
+-static inline _syscall6(void *, _dl_mmap, void *, start, size_t, length,
+-              int, prot, int, flags, int, fd, off_t, offset);
++#ifdef __UCLIBC_HAS_SSP__
++# include <sys/time.h>
++# define __NR__dl_gettimeofday __NR_gettimeofday
++static inline _syscall2(int, _dl_gettimeofday, struct timeval *, tv,
++# ifdef __USE_BSD
++                        struct timezone *, tz);
++# else
++                        void *, tz);
++# endif
++#endif
++
++
++/* handle all the fun mmap intricacies */
++#if (defined(__UCLIBC_MMAP_HAS_6_ARGS__) && defined(__NR_mmap)) || !defined(__NR_mmap2)
++# define _dl_MAX_ERRNO 4096
++# define _dl_mmap_check_error(__res) \
++      (((long)__res) < 0 && ((long)__res) >= -_dl_MAX_ERRNO)
+ #else
+-#define __NR__dl_mmap_real __NR_mmap
+-static inline _syscall1(void *, _dl_mmap_real, unsigned long *, buffer);
++# define MAP_FAILED ((void *) -1)
++# define _dl_mmap_check_error(X) (((void *)X) == MAP_FAILED)
++#endif
++
++/* first try mmap(), syscall6() style */
++#if defined(__UCLIBC_MMAP_HAS_6_ARGS__) && defined(__NR_mmap)
++
++# define __NR__dl_mmap __NR_mmap
++static inline _syscall6(void *, _dl_mmap, void *, start, size_t, length,
++                        int, prot, int, flags, int, fd, off_t, offset);
++
++/* then try mmap2() */
++#elif defined(__NR_mmap2)
++
++# define __NR___syscall_mmap2       __NR_mmap2
++static inline _syscall6(__ptr_t, __syscall_mmap2, __ptr_t, addr, size_t, len,
++                        int, prot, int, flags, int, fd, off_t, offset);
++
++/* Some architectures always use 12 as page shift for mmap2() eventhough the
++ * real PAGE_SHIFT != 12.  Other architectures use the same value as
++ * PAGE_SHIFT...
++ */
++#ifndef MMAP2_PAGE_SHIFT
++# define MMAP2_PAGE_SHIFT 12
++#endif
+ static inline void * _dl_mmap(void * addr, unsigned long size, int prot,
+-              int flags, int fd, unsigned long offset)
++                              int flags, int fd, unsigned long offset)
++{
++      if (offset & ((1 << MMAP2_PAGE_SHIFT) - 1))
++              return MAP_FAILED;
++      return __syscall_mmap2(addr, size, prot, flags,
++                             fd, (off_t) (offset >> MMAP2_PAGE_SHIFT));
++}
++
++/* finally, fall back to mmap(), syscall1() style */
++#elif defined(__NR_mmap)
++
++# define __NR__dl_mmap_real __NR_mmap
++static inline _syscall1(void *, _dl_mmap_real, unsigned long *, buffer);
++static inline void * _dl_mmap(void * addr, unsigned long size, int prot,
++                              int flags, int fd, unsigned long offset)
+ {
+       unsigned long buffer[6];
+@@ -125,24 +190,9 @@
+       buffer[5] = (unsigned long) offset;
+       return (void *) _dl_mmap_real(buffer);
+ }
+-#endif
+-#elif defined __NR_mmap2
+-#define __NR___syscall_mmap2       __NR_mmap2
+-static inline _syscall6(__ptr_t, __syscall_mmap2, __ptr_t, addr,
+-              size_t, len, int, prot, int, flags, int, fd, off_t, offset);
+-/*always 12, even on architectures where PAGE_SHIFT != 12 */
+-#define MMAP2_PAGE_SHIFT 12
+-static inline void * _dl_mmap(void * addr, unsigned long size, int prot,
+-              int flags, int fd, unsigned long offset)
+-{
+-    if (offset & ((1 << MMAP2_PAGE_SHIFT) - 1))
+-      return MAP_FAILED;
+-    return(__syscall_mmap2(addr, size, prot, flags,
+-              fd, (off_t) (offset >> MMAP2_PAGE_SHIFT)));
+-}
++
+ #else
+-#error "Your architecture doesn't seem to provide mmap() !?"
++# error "Your architecture doesn't seem to provide mmap() !?"
+ #endif
+ #endif /* _LD_SYSCALL_H_ */
+-
+diff -urN uClibc-0.9.28.orig/ldso/include/dlfcn.h uClibc-0.9.28/ldso/include/dlfcn.h
+--- uClibc-0.9.28.orig/ldso/include/dlfcn.h    2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/include/dlfcn.h 2006-04-28 00:14:35.000000000 -0600
+@@ -1,3 +1,10 @@
++/* vi: set sw=4 ts=4: */
++/*
++ * Copyright (C) 2000-2005 by Erik Andersen <andersen@codepoet.org>
++ *
++ * GNU Lesser General Public License version 2.1 or later.
++ */
++
+ /* User functions for run-time dynamic loading.  libdl version */
+ #ifndef       _DLFCN_H
+ #define       _DLFCN_H 1
+diff -urN uClibc-0.9.28.orig/ldso/include/ldso.h uClibc-0.9.28/ldso/include/ldso.h
+--- uClibc-0.9.28.orig/ldso/include/ldso.h     2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/include/ldso.h  2006-04-28 00:14:35.000000000 -0600
+@@ -1,3 +1,10 @@
++/* vi: set sw=4 ts=4: */
++/*
++ * Copyright (C) 2000-2005 by Erik Andersen <andersen@codepoet.org>
++ *
++ * GNU Lesser General Public License version 2.1 or later.
++ */
++
+ #ifndef _LDSO_H_
+ #define _LDSO_H_
+@@ -20,13 +27,15 @@
+ /* Pull in compiler and arch stuff */
+ #include <stdlib.h>
+ #include <stdarg.h>
++#include <bits/wordsize.h>
+ /* Pull in the arch specific type information */
+ #include <sys/types.h>
++/* Pull in the arch specific page size */
++#include <bits/uClibc_page.h>
++#define attribute_unused __attribute__ ((unused))
+ /* Pull in the ldso syscalls and string functions */
+ #include <dl-syscall.h>
+ #include <dl-string.h>
+-/* Pull in the arch specific page size */
+-#include <bits/uClibc_page.h>
+ /* Now the ldso specific headers */
+ #include <dl-elf.h>
+ #include <dl-hash.h>
+diff -urN uClibc-0.9.28.orig/ldso/include/unsecvars.h uClibc-0.9.28/ldso/include/unsecvars.h
+--- uClibc-0.9.28.orig/ldso/include/unsecvars.h        2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/include/unsecvars.h     2006-04-28 00:14:35.000000000 -0600
+@@ -1,3 +1,10 @@
++/* vi: set sw=4 ts=4: */
++/*
++ * Copyright (C) 2000-2005 by Erik Andersen <andersen@codepoet.org>
++ *
++ * GNU Lesser General Public License version 2.1 or later.
++ */
++
+ /* 
+  * Environment variable to be removed for SUID programs.  The names are all
+  * stuffed in a single string which means they have to be terminated with a
+@@ -5,22 +12,21 @@
+  */
+ #define UNSECURE_ENVVARS \
+-      "LD_AOUT_PRELOAD\0" \
+-      "LD_AOUT_LIBRARY_PATH\0" \
+       "LD_PRELOAD\0" \
+       "LD_LIBRARY_PATH\0" \
+       "LD_DEBUG\0" \
+       "LD_DEBUG_OUTPUT\0" \
+       "LD_TRACE_LOADED_OBJECTS\0" \
+-      "HOSTALIASES\0" \
+-      "LOCALDOMAIN\0" \
+-      "RES_OPTIONS\0" \
+       "TMPDIR\0"
+ /* 
++ * LD_TRACE_LOADED_OBJECTS is not in glibc-2.3.5's unsecvars.h
++ * though used by ldd
++ *
+  * These environment variables are defined by glibc but ignored in
+  * uClibc, but may very well have an equivalent in uClibc.
+  *
+- * MALLOC_TRACE, RESOLV_HOST_CONF, TZDIR, GCONV_PATH, LD_USE_LOAD_BIAS,
+- * LD_PROFILE, LD_ORIGIN_PATH, LOCPATH, NLSPATH
++ * LD_ORIGIN_PATH, LD_PROFILE, LD_USE_LOAD_BIAS, LD_DYNAMIC_WEAK, LD_SHOW_AUXV,
++ * GCONV_PATH, GETCONF_DIR, HOSTALIASES, LOCALDOMAIN, LOCPATH, MALLOC_TRACE,
++ * NLSPATH, RESOLV_HOST_CONF, RES_OPTIONS, TZDIR
+  */
+diff -urN uClibc-0.9.28.orig/ldso/ldso/Makefile uClibc-0.9.28/ldso/ldso/Makefile
+--- uClibc-0.9.28.orig/ldso/ldso/Makefile      2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/Makefile   2006-04-28 00:14:35.000000000 -0600
+@@ -42,7 +42,9 @@
+ endif
+ XXFLAGS+= -DUCLIBC_LDSO=\"$(UCLIBC_LDSO)\" $(XARCH_CFLAGS) $(CPU_CFLAGS) $(PICFLAG) \
+       -DUCLIBC_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" \
+-      -fno-builtin -nostdinc -D_LIBC -I$(TOPDIR)ldso/include -I. -I$(TOPDIR)include
++      -fno-builtin -nostdinc -D_LIBC \
++      -DLDSO_ELFINTERP=\"$(TARGET_ARCH)/elfinterp.c\" \
++      -I$(TOPDIR)ldso/ldso/$(TARGET_ARCH) -I$(TOPDIR)ldso/include -I$(TOPDIR)ldso/ldso -I$(TOPDIR)include
+ # BEWARE!!! At least mips* will die if -O0 is used!!!
+ XXFLAGS:=$(XXFLAGS:-O0=-O1)
+diff -urN uClibc-0.9.28.orig/ldso/ldso/arm/dl-startup.h uClibc-0.9.28/ldso/ldso/arm/dl-startup.h
+--- uClibc-0.9.28.orig/ldso/ldso/arm/dl-startup.h      2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/arm/dl-startup.h   2006-04-28 00:14:35.000000000 -0600
+@@ -1,10 +1,15 @@
+ /* vi: set sw=4 ts=4: */
+ /*
+  * Architecture specific code used by dl-startup.c
+- * Copyright (C) 2000-2004 by Erik Andersen <andersen@codepoet.org>
++ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
++ *
++ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+  */
+-asm(
++#include <features.h>
++
++#if !defined(__thumb__)
++__asm__(
+     " .text\n"
+     " .globl  _start\n"
+     " .type   _start,%function\n"
+@@ -40,7 +45,78 @@
+       "       ldr     r0, .L_FINI_PROC\n"
+       "       ldr     r0, [sl, r0]\n"
+       "       @ jump to the user_s entry point\n"
++#if defined(__USE_BX__)
++      "       bx      r6\n"
++#else
++      "       mov     pc, r6\n"
++#endif
++      ".L_GET_GOT:\n"
++      "       .word   _GLOBAL_OFFSET_TABLE_ - .L_GOT_GOT - 4\n"
++      ".L_SKIP_ARGS:\n"
++      "       .word   _dl_skip_args(GOTOFF)\n"
++      ".L_FINI_PROC:\n"
++      "       .word   _dl_fini(GOT)\n"
++      "\n\n"
++    " .size   _start,.-_start\n"
++      ".previous\n"
++);
++#else
++__asm__(
++    " .text\n"
++    " .arm\n"
++    " .globl  _start\n"
++    " .type   _start,%function\n"
++      "_start:\n"
++      "       @ dumb: can't persuade the linker to make the start address\n"
++      "       @ odd, so use an arm function and change to thumb (_dl_start\n"
++      "       @ is thumb)\n"
++      "       adr     r0, __dl_thumb_start+1\n"
++      "       bx      r0\n"
++      "\n\n"
++    " .thumb\n"
++    " .globl  __dl_thumb_start\n"
++    " .thumb_func\n"
++    " .type   __dl_thumb_start,%function\n"
++      "__dl_thumb_start:\n"
++      "       @ at start time, all the args are on the stack\n"
++      "       mov     r0, sp\n"
++      "       bl      _dl_start\n"
++      "       @ returns user entry point in r0\n"
++      "       mov     r6, r0\n"
++      "       @ we are PIC code, so get global offset table\n"
++      "       ldr     r7, .L_GET_GOT\n"
++      ".L_GOT_GOT:\n"
++      "       add     r7, pc\n"
++      "       @ See if we were run as a command with the executable file\n"
++      "       @ name as an extra leading argument.\n"
++      "       ldr     r4, .L_SKIP_ARGS\n"
++      "       ldr     r4, [r7, r4]\n"
++      "       @ get the original arg count\n"
++      "       ldr     r1, [sp]\n"
++      "       @ subtract _dl_skip_args from it\n"
++      "       sub     r1, r1, r4\n"
++      "       @ adjust the stack pointer to skip them\n"
++      "       lsl     r4, r4, #2\n"
++      "       add     sp, r4\n"
++      "       @ get the argv address\n"
++      "       add     r2, sp, #4\n"
++      "       @ store the new argc in the new stack location\n"
++      "       str     r1, [sp]\n"
++      "       @ compute envp\n"
++      "       lsl     r3, r1, #2\n"
++      "       add     r3, r3, r2\n"
++      "       add     r3, #4\n"
++      "\n\n"
++      "       @ load the finalizer function\n"
++      "       ldr     r0, .L_FINI_PROC\n"
++      "       ldr     r0, [r7, r0]\n"
++      "       @ jump to the user_s entry point\n"
++#if defined(__USE_BX__)
++      "       bx      r6\n"
++#else
+       "       mov     pc, r6\n"
++#endif
++      "\n\n"
+       ".L_GET_GOT:\n"
+       "       .word   _GLOBAL_OFFSET_TABLE_ - .L_GOT_GOT - 4\n"
+       ".L_SKIP_ARGS:\n"
+@@ -51,6 +127,7 @@
+     " .size   _start,.-_start\n"
+       ".previous\n"
+ );
++#endif
+ /* Get a pointer to the argv array.  On many platforms this can be just
+@@ -115,9 +192,3 @@
+                       _dl_exit(1);
+       }
+ }
+-
+-
+-/* Transfer control to the user's application, once the dynamic loader is
+- * done.  This routine has to exit the current function, then call the
+- * _dl_elf_main function.  */
+-#define START()   return _dl_elf_main;
+diff -urN uClibc-0.9.28.orig/ldso/ldso/arm/dl-syscalls.h uClibc-0.9.28/ldso/ldso/arm/dl-syscalls.h
+--- uClibc-0.9.28.orig/ldso/ldso/arm/dl-syscalls.h     2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/arm/dl-syscalls.h  2006-04-28 00:14:35.000000000 -0600
+@@ -1,6 +1,7 @@
+ /* We can't use the real errno in ldso, since it has not yet
+  * been dynamicly linked in yet. */
++#include "sys/syscall.h"
+ extern int _dl_errno;
++#undef __set_errno
+ #define __set_errno(X) {(_dl_errno) = (X);}
+-#include "sys/syscall.h"
+diff -urN uClibc-0.9.28.orig/ldso/ldso/arm/dl-sysdep.h uClibc-0.9.28/ldso/ldso/arm/dl-sysdep.h
+--- uClibc-0.9.28.orig/ldso/ldso/arm/dl-sysdep.h       2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/arm/dl-sysdep.h    2006-04-28 00:14:35.000000000 -0600
+@@ -43,6 +43,7 @@
+       return m;
+ }
+ #define do_rem(result, n, base) ((result) = arm_modulus(n, base))
++#define do_div_10(result, remain) ((result) = (((result) - (remain)) / 2) * -(-1ul / 5ul))
+ /* Here we define the magic numbers that this dynamic loader should accept */
+ #define MAGIC1 EM_ARM
+@@ -85,7 +86,25 @@
+       extern void __dl_start asm ("_dl_start");
+       Elf32_Addr got_addr = (Elf32_Addr) &__dl_start;
+       Elf32_Addr pcrel_addr;
++#if !defined __thumb__
+       asm ("adr %0, _dl_start" : "=r" (pcrel_addr));
++#else
++      int tmp;
++      /* The above adr will not work on thumb because it
++       * is negative.  The only safe way is to temporarily
++       * swap to arm.
++       */
++      asm(   ".align  2\n"
++      "       bx      pc\n"
++      "       nop     \n"
++      "       .arm    \n"
++      "       adr     %0, _dl_start\n"
++      "       .align  2\n"
++      "       orr     %1, pc, #1\n"
++      "       bx      %1\n"
++      "       .force_thumb\n"
++      : "=r" (pcrel_addr), "=&r" (tmp));
++#endif
+       return pcrel_addr - got_addr;
+ }
+diff -urN uClibc-0.9.28.orig/ldso/ldso/arm/elfinterp.c uClibc-0.9.28/ldso/ldso/arm/elfinterp.c
+--- uClibc-0.9.28.orig/ldso/ldso/arm/elfinterp.c       2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/arm/elfinterp.c    2006-04-28 00:14:35.000000000 -0600
+@@ -38,6 +38,8 @@
+    a more than adequate job of explaining everything required to get this
+    working. */
++#include "ldso.h"
++
+ extern int _dl_linux_resolve(void);
+ unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
+@@ -63,7 +65,6 @@
+       strtab = (char *) tpnt->dynamic_info[DT_STRTAB];
+       symname = strtab + symtab[symtab_index].st_name;
+-
+       if (unlikely(reloc_type != R_ARM_JUMP_SLOT)) {
+               _dl_dprintf(2, "%s: Incorrect relocation type in jump relocations\n",
+                       _dl_progname);
+diff -urN uClibc-0.9.28.orig/ldso/ldso/cris/dl-startup.h uClibc-0.9.28/ldso/ldso/cris/dl-startup.h
+--- uClibc-0.9.28.orig/ldso/ldso/cris/dl-startup.h     2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/cris/dl-startup.h  2006-04-28 00:14:35.000000000 -0600
+@@ -4,22 +4,43 @@
+ /* This code fixes the stack pointer so that the dynamic linker
+  * can find argc, argv and auxvt (Auxillary Vector Table).  */
++#ifdef __arch_v32
++
++asm(""                                        \
++"     .text\n"                        \
++"     .globl _start\n"                \
++"     .type _start,@function\n"       \
++"_start:\n"                           \
++"     move.d  $sp,$r10\n"             \
++"     lapc    _dl_start,$r9\n"        \
++"     jsr     $r9\n"                  \
++"     nop\n"                          \
++"     moveq   0,$r8\n"                \
++"     jump    $r10\n"                 \
++"     move    $r8,$srp\n"             \
++"     .size _start,.-_start\n"        \
++"     .previous\n"                    \
++);
++
++#else
++
+ asm(""                                        \
+ "     .text\n"                        \
+ "     .globl _start\n"                \
+ "     .type _start,@function\n"       \
+ "_start:\n"                           \
+-"     move.d $sp,$r10\n"              \
+-"     move.d $pc,$r9\n"               \
+-"     add.d _dl_start - ., $r9\n"     \
+-"     jsr $r9\n"                      \
+-"     moveq 0,$r8\n"                  \
+-"     move $r8,$srp\n"                \
+-"     jump $r10\n"                    \
++"     move.d  $sp,$r10\n"             \
++"     move.d  $pc,$r9\n"              \
++"     add.d   _dl_start - ., $r9\n"   \
++"     jsr     $r9\n"                  \
++"     moveq   0,$r8\n"                \
++"     move    $r8,$srp\n"             \
++"     jump    $r10\n"                 \
+ "     .size _start,.-_start\n"        \
+ "     .previous\n"                    \
+ );
++#endif /* __arch_v32 */
+ /* Get a pointer to the argv array.  On many platforms this can be just
+  * the address if the first argument, on other platforms we need to
+@@ -58,8 +79,3 @@
+                       break;
+       }
+ }
+-
+-/* Transfer control to the user's application, once the dynamic loader is
+- * done.  This routine has to exit the current function, then call the
+- * _dl_elf_main function.  */
+-#define START()     return _dl_elf_main
+diff -urN uClibc-0.9.28.orig/ldso/ldso/cris/dl-syscalls.h uClibc-0.9.28/ldso/ldso/cris/dl-syscalls.h
+--- uClibc-0.9.28.orig/ldso/ldso/cris/dl-syscalls.h    2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/cris/dl-syscalls.h 2006-04-28 00:14:35.000000000 -0600
+@@ -1,5 +1,6 @@
+ /* We can't use the real errno in ldso, since it has not yet
+  * been dynamicly linked in yet. */
++#include "sys/syscall.h"
+ extern int _dl_errno;
++#undef __set_errno
+ #define __set_errno(X) {(_dl_errno) = (X);}
+-#include "sys/syscall.h"
+diff -urN uClibc-0.9.28.orig/ldso/ldso/cris/dl-sysdep.h uClibc-0.9.28/ldso/ldso/cris/dl-sysdep.h
+--- uClibc-0.9.28.orig/ldso/ldso/cris/dl-sysdep.h      2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/cris/dl-sysdep.h   2006-04-28 00:14:35.000000000 -0600
+@@ -18,8 +18,6 @@
+ struct elf_resolve;
+ extern unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry);
+-#define do_rem(result, n, base) ((result) = (n) % (base))
+-
+ /* 8192 bytes alignment */
+ #define PAGE_ALIGN 0xffffe000
+ #define ADDR_ALIGN 0x1fff
+@@ -68,8 +66,32 @@
+ {
+       Elf32_Addr gotaddr_diff;
++#ifdef __arch_v32
++      extern char ___CRISv32_dummy[] __asm__ ("_dl_start");
++
++      __asm__ ("addo.w _dl_start:GOT16,$r0,$acr\n\t"
++               "lapc _dl_start,%0\n\t"
++               "sub.d [$acr],%0"
++               /* For v32, we need to force GCC to have R0 loaded with
++                  _GLOBAL_OFFSET_TABLE_ at this point, which might not
++                  otherwise have happened in the caller.  (For v10, it's
++                  loaded for non-global variables too, so we don't need
++                  anything special there.)  We accomplish this by faking the
++                  address of a global variable (as seen by GCC) as input to
++                  the asm; that address calculation goes through the GOT.
++                  Use of this function happens before we've filled in the
++                  GOT, so the address itself will not be correctly
++                  calculated, therefore we don't use any symbol whose
++                  address may be re-used later on.  Let's just reuse the
++                  _dl_start symbol, faking it as a global by renaming it as
++                  another variable through an asm.  */
++               : "=r" (gotaddr_diff)
++               : "g" (___CRISv32_dummy)
++               : "acr");
++#else
+       __asm__ ("sub.d [$r0+_dl_start:GOT16],$r0,%0\n\t"
+                "add.d _dl_start:GOTOFF,%0" : "=r" (gotaddr_diff));
++#endif
+       return gotaddr_diff;
+ }
+diff -urN uClibc-0.9.28.orig/ldso/ldso/cris/resolve.S uClibc-0.9.28/ldso/ldso/cris/resolve.S
+--- uClibc-0.9.28.orig/ldso/ldso/cris/resolve.S        2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/cris/resolve.S     2006-04-28 00:14:35.000000000 -0600
+@@ -17,33 +17,73 @@
+ .globl _dl_linux_resolve
+ .type _dl_linux_resolve,@function
++#ifdef __arch_v32
++
++_dl_linux_resolve:
++      subq    4,$sp
++      move.d  $r0,[$sp]
++      subq    4,$sp
++      move.d  $r13,[$sp]
++      subq    4,$sp
++      move.d  $r12,[$sp]
++      subq    4,$sp
++      move.d  $r11,[$sp]
++      subq    4,$sp
++      addoq   5*4,$sp,$acr
++      move.d  $r10,[$sp]
++      subq    4,$sp
++      move    $mof,$r10
++      move.d  $r9,[$sp]
++      subq    4,$sp
++      move.d  [$acr],$r11
++      move    $srp,[$sp]
++      lapc    _GLOBAL_OFFSET_TABLE_,$r0
++      move.d  _dl_linux_resolver:PLTG,$r9
++      add.d   $r0,$r9
++      jsr     $r9
++      nop
++      move.d  $r10,$acr
++      move    [$sp+],$srp
++      move.d  [$sp+],$r9
++      move.d  [$sp+],$r10
++      move.d  [$sp+],$r11
++      move.d  [$sp+],$r12
++      move.d  [$sp+],$r13
++      move.d  [$sp+],$r0
++      jump    $acr
++      addq    4,$sp
++
++#else
++
+ _dl_linux_resolve:
+-      push $r13
+-      push $r12
+-      push $r11
+-      push $r10
+-      push $r9
+-      push $r0
+-      push $srp
+-      move.d [$sp+7*4],$r11
+-      move $mof,$r10
++      push    $r13
++      push    $r12
++      push    $r11
++      push    $r10
++      push    $r9
++      push    $r0
++      push    $srp
++      move.d  [$sp+7*4],$r11
++      move    $mof,$r10
+ #ifdef __PIC__
+-      move.d $pc,$r0
+-      sub.d .:GOTOFF,$r0
+-      move.d _dl_linux_resolver:PLTG,$r9
+-      add.d $r0,$r9
+-      jsr $r9
++      move.d  $pc,$r0
++      sub.d   .:GOTOFF,$r0
++      move.d  _dl_linux_resolver:PLTG,$r9
++      add.d   $r0,$r9
++      jsr     $r9
+ #else
+-      jsr _dl_linux_resolver
++      jsr     _dl_linux_resolver
+ #endif
+-      move.d $r10,[$sp+7*4]
+-      pop $srp
+-      pop $r0
+-      pop $r9
+-      pop $r10
+-      pop $r11
+-      pop $r12
+-      pop $r13
+-      jump [$sp+]
++      move.d  $r10,[$sp+7*4]
++      pop     $srp
++      pop     $r0
++      pop     $r9
++      pop     $r10
++      pop     $r11
++      pop     $r12
++      pop     $r13
++      jump    [$sp+]
++
++#endif /* __arch_v32 */
+       .size _dl_linux_resolve, . - _dl_linux_resolve
+diff -urN uClibc-0.9.28.orig/ldso/ldso/dl-elf.c uClibc-0.9.28/ldso/ldso/dl-elf.c
+--- uClibc-0.9.28.orig/ldso/ldso/dl-elf.c      2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/dl-elf.c   2006-05-02 13:50:58.000000000 -0600
+@@ -3,7 +3,7 @@
+  * This file contains the helper routines to load an ELF shared
+  * library into memory and add the symbol table info to the chain.
+  *
+- * Copyright (C) 2000-2004 by Erik Andersen <andersen@codepoet.org>
++ * Copyright (C) 2000-2006 by Erik Andersen <andersen@codepoet.org>
+  * Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald,
+  *                            David Engel, Hongjiu Lu and Mitch D'Souza
+  *
+@@ -60,8 +60,8 @@
+       _dl_cache_addr = (caddr_t) _dl_mmap(0, _dl_cache_size, PROT_READ, MAP_SHARED, fd, 0);
+       _dl_close(fd);
+       if (_dl_mmap_check_error(_dl_cache_addr)) {
+-              _dl_dprintf(2, "%s: can't map cache '%s'\n",
+-                              _dl_progname, LDSO_CACHE);
++              _dl_dprintf(2, "%s:%i: can't map '%s'\n",
++                              _dl_progname, __LINE__, LDSO_CACHE);
+               return -1;
+       }
+@@ -115,7 +115,7 @@
+ #endif
+-void 
++void
+ _dl_protect_relro (struct elf_resolve *l)
+ {
+       ElfW(Addr) start = ((l->loadaddr + l->relro_addr)
+@@ -136,27 +136,41 @@
+ search_for_named_library(const char *name, int secure, const char *path_list,
+       struct dyn_elf **rpnt)
+ {
+-      char *path, *path_n;
+-      char mylibname[2050];
++      char *path, *path_n, *mylibname;
+       struct elf_resolve *tpnt;
+-      int done = 0;
++      int done;
+       if (path_list==NULL)
+               return NULL;
+-      /* We need a writable copy of this string */
+-      path = _dl_strdup(path_list);
+-      if (!path) {
++      /* We need a writable copy of this string, but we don't
++       * need this allocated permanently since we don't want
++       * to leak memory, so use alloca to put path on the stack */
++      done = _dl_strlen(path_list);
++      path = alloca(done + 1);
++
++      /* another bit of local storage */
++      mylibname = alloca(2050);
++
++      /* gcc inlines alloca using a single instruction adjusting
++       * the stack pointer and no stack overflow check and thus
++       * no NULL error return.  No point leaving in dead code... */
++#if 0
++      if (!path || !mylibname) {
+               _dl_dprintf(2, "Out of memory!\n");
+               _dl_exit(0);
+       }
++#endif
++
++      _dl_memcpy(path, path_list, done+1);
+       /* Unlike ldd.c, don't bother to eliminate double //s */
+       /* Replace colons with zeros in path_list */
+       /* : at the beginning or end of path maps to CWD */
+       /* :: anywhere maps CWD */
+-      /* "" maps to CWD */ 
++      /* "" maps to CWD */
++      done = 0;
+       path_n = path;
+       do {
+               if (*path == 0) {
+@@ -180,71 +194,6 @@
+       return NULL;
+ }
+-/* Check if the named library is already loaded... */
+-struct elf_resolve *_dl_check_if_named_library_is_loaded(const char *full_libname,
+-              int trace_loaded_objects)
+-{
+-      const char *pnt, *pnt1;
+-      struct elf_resolve *tpnt1;
+-      const char *libname, *libname2;
+-      static const char libc[] = "libc.so.";
+-      static const char aborted_wrong_lib[] = "%s: aborted attempt to load %s!\n";
+-
+-      pnt = libname = full_libname;
+-
+-      _dl_if_debug_dprint("Checking if '%s' is already loaded\n", full_libname);
+-      /* quick hack to ensure mylibname buffer doesn't overflow.  don't
+-         allow full_libname or any directory to be longer than 1024. */
+-      if (_dl_strlen(full_libname) > 1024)
+-              return NULL;
+-
+-      /* Skip over any initial initial './' and '/' stuff to
+-       * get the short form libname with no path garbage */
+-      pnt1 = _dl_strrchr(pnt, '/');
+-      if (pnt1) {
+-              libname = pnt1 + 1;
+-      }
+-
+-      /* Make sure they are not trying to load the wrong C library!
+-       * This sometimes happens esp with shared libraries when the
+-       * library path is somehow wrong! */
+-#define isdigit(c)  (c >= '0' && c <= '9')
+-      if ((_dl_strncmp(libname, libc, 8) == 0) &&  _dl_strlen(libname) >=8 &&
+-                      isdigit(libname[8]))
+-      {
+-              /* Abort attempts to load glibc, libc5, etc */
+-              if ( libname[8]!='0') {
+-                      if (!trace_loaded_objects) {
+-                              _dl_dprintf(2, aborted_wrong_lib, libname, _dl_progname);
+-                              _dl_exit(1);
+-                      }
+-                      return NULL;
+-              }
+-      }
+-
+-      /* Critical step!  Weed out duplicates early to avoid
+-       * function aliasing, which wastes memory, and causes
+-       * really bad things to happen with weaks and globals. */
+-      for (tpnt1 = _dl_loaded_modules; tpnt1; tpnt1 = tpnt1->next) {
+-
+-              /* Skip over any initial initial './' and '/' stuff to
+-               * get the short form libname with no path garbage */
+-              libname2 = tpnt1->libname;
+-              pnt1 = _dl_strrchr(libname2, '/');
+-              if (pnt1) {
+-                      libname2 = pnt1 + 1;
+-              }
+-
+-              if (_dl_strcmp(libname2, libname) == 0) {
+-                      /* Well, that was certainly easy */
+-                      return tpnt1;
+-              }
+-      }
+-
+-      return NULL;
+-}
+-
+-
+ /* Used to return error codes back to dlopen et. al.  */
+ unsigned long _dl_error_number;
+ unsigned long _dl_internal_error_number;
+@@ -271,14 +220,6 @@
+               libname = pnt + 1;
+       }
+-      /* Critical step!  Weed out duplicates early to avoid
+-       * function aliasing, which wastes memory, and causes
+-       * really bad things to happen with weaks and globals. */
+-      if ((tpnt1=_dl_check_if_named_library_is_loaded(libname, trace_loaded_objects))!=NULL) {
+-              tpnt1->usage_count++;
+-              return tpnt1;
+-      }
+-
+       _dl_if_debug_dprint("\tfind library='%s'; searching\n", libname);
+       /* If the filename has any '/', try it straight and leave it at that.
+          For IBCS2 compatibility under linux, we substitute the string
+@@ -290,7 +231,6 @@
+               if (tpnt1) {
+                       return tpnt1;
+               }
+-              //goto goof;
+       }
+       /*
+@@ -411,56 +351,45 @@
+       int i, flags, piclib, infile;
+       ElfW(Addr) relro_addr = 0;
+       size_t relro_size = 0;
+-
+-      /* If this file is already loaded, skip this step */
+-      tpnt = _dl_check_hashed_files(libname);
+-      if (tpnt) {
+-              if (*rpnt) {
+-                      (*rpnt)->next = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
+-                      _dl_memset((*rpnt)->next, 0, sizeof(struct dyn_elf));
+-                      (*rpnt)->next->prev = (*rpnt);
+-                      *rpnt = (*rpnt)->next;
+-                      (*rpnt)->dyn = tpnt;
+-                      tpnt->symbol_scope = _dl_symbol_tables;
+-              }
+-              tpnt->usage_count++;
+-              tpnt->libtype = elf_lib;
+-              _dl_if_debug_dprint("file='%s';  already loaded\n", libname);
+-              return tpnt;
+-      }
+-
+-      /* If we are in secure mode (i.e. a setu/gid binary using LD_PRELOAD),
+-         we don't load the library if it isn't setuid. */
+-
+-      if (secure) {
+-              struct stat st;
+-
+-              if (_dl_stat(libname, &st) || !(st.st_mode & S_ISUID))
+-                      return NULL;
+-      }
++      struct stat st;
+       libaddr = 0;
+       infile = _dl_open(libname, O_RDONLY, 0);
+       if (infile < 0) {
+-#if 0
+-              /*
+-               * NO!  When we open shared libraries we may search several paths.
+-               * it is inappropriate to generate an error here.
+-               */
+-              _dl_dprintf(2, "%s: can't open '%s'\n", _dl_progname, libname);
+-#endif
+               _dl_internal_error_number = LD_ERROR_NOFILE;
+               return NULL;
+       }
++      if (_dl_fstat(infile, &st) < 0) {
++              _dl_internal_error_number = LD_ERROR_NOFILE;
++              _dl_close(infile);
++              return NULL;
++      }
++      /* If we are in secure mode (i.e. a setu/gid binary using LD_PRELOAD),
++         we don't load the library if it isn't setuid. */
++      if (secure)
++              if (!(st.st_mode & S_ISUID)) {
++                      _dl_close(infile);
++                      return NULL;
++              }
++
++      /* Check if file is already loaded */
++      for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
++              if(tpnt->st_dev == st.st_dev && tpnt->st_ino == st.st_ino) {
++                      /* Already loaded */
++                      tpnt->usage_count++;
++                      _dl_close(infile);
++                      return tpnt;
++              }
++      }
+       header = _dl_mmap((void *) 0, _dl_pagesize, PROT_READ | PROT_WRITE,
+                       MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+       if (_dl_mmap_check_error(header)) {
+-              _dl_dprintf(2, "%s: can't map '%s'\n", _dl_progname, libname);
++              _dl_dprintf(2, "%s:%i: can't map '%s'\n", _dl_progname, __LINE__, libname);
+               _dl_internal_error_number = LD_ERROR_MMAP_FAILED;
+               _dl_close(infile);
+               return NULL;
+-      };
++      }
+       _dl_read(infile, header, _dl_pagesize);
+       epnt = (ElfW(Ehdr) *) (intptr_t) header;
+@@ -475,7 +404,7 @@
+               _dl_close(infile);
+               _dl_munmap(header, _dl_pagesize);
+               return NULL;
+-      };
++      }
+       if ((epnt->e_type != ET_DYN) || (epnt->e_machine != MAGIC1
+ #ifdef MAGIC2
+@@ -490,7 +419,7 @@
+               _dl_close(infile);
+               _dl_munmap(header, _dl_pagesize);
+               return NULL;
+-      };
++      }
+       ppnt = (ElfW(Phdr) *)(intptr_t) & header[epnt->e_phoff];
+@@ -502,7 +431,7 @@
+                               _dl_dprintf(2, "%s: '%s' has more than one dynamic section\n",
+                                               _dl_progname, libname);
+                       dynamic_addr = ppnt->p_vaddr;
+-              };
++              }
+               if (ppnt->p_type == PT_LOAD) {
+                       /* See if this is a PIC library. */
+@@ -518,7 +447,7 @@
+                       }
+               }
+               ppnt++;
+-      };
++      }
+       maxvma = (maxvma + ADDR_ALIGN) & ~ADDR_ALIGN;
+       minvma = minvma & ~0xffffU;
+@@ -530,12 +459,12 @@
+       status = (char *) _dl_mmap((char *) (piclib ? 0 : minvma),
+                       maxvma - minvma, PROT_NONE, flags | MAP_ANONYMOUS, -1, 0);
+       if (_dl_mmap_check_error(status)) {
+-              _dl_dprintf(2, "%s: can't map %s\n", _dl_progname, libname);
++              _dl_dprintf(2, "%s:%i: can't map '%s'\n", _dl_progname, __LINE__, libname);
+               _dl_internal_error_number = LD_ERROR_MMAP_FAILED;
+               _dl_close(infile);
+               _dl_munmap(header, _dl_pagesize);
+               return NULL;
+-      };
++      }
+       libaddr = (unsigned long) status;
+       flags |= MAP_FIXED;
+@@ -567,14 +496,14 @@
+                                               ppnt->p_offset & OFFS_ALIGN);
+                               if (_dl_mmap_check_error(status)) {
+-                                      _dl_dprintf(2, "%s: can't map '%s'\n",
+-                                                      _dl_progname, libname);
++                                      _dl_dprintf(2, "%s:%i: can't map '%s'\n",
++                                                      _dl_progname, __LINE__, libname);
+                                       _dl_internal_error_number = LD_ERROR_MMAP_FAILED;
+                                       _dl_munmap((char *) libaddr, maxvma - minvma);
+                                       _dl_close(infile);
+                                       _dl_munmap(header, _dl_pagesize);
+                                       return NULL;
+-                              };
++                              }
+                               /* Pad the last page with zeroes. */
+                               cpnt = (char *) (status + (ppnt->p_vaddr & ADDR_ALIGN) +
+@@ -601,21 +530,21 @@
+                                               ppnt->p_filesz, LXFLAGS(ppnt->p_flags), flags,
+                                               infile, ppnt->p_offset & OFFS_ALIGN);
+                       if (_dl_mmap_check_error(status)) {
+-                              _dl_dprintf(2, "%s: can't map '%s'\n", _dl_progname, libname);
++                              _dl_dprintf(2, "%s:%i: can't map '%s'\n", _dl_progname, __LINE__, libname);
+                               _dl_internal_error_number = LD_ERROR_MMAP_FAILED;
+                               _dl_munmap((char *) libaddr, maxvma - minvma);
+                               _dl_close(infile);
+                               _dl_munmap(header, _dl_pagesize);
+                               return NULL;
+-                      };
++                      }
+                       /* if(libaddr == 0 && piclib) {
+                          libaddr = (unsigned long) status;
+                          flags |= MAP_FIXED;
+-                         }; */
+-              };
++                         } */
++              }
+               ppnt++;
+-      };
++      }
+       _dl_close(infile);
+       /* For a non-PIC library, the addresses are all absolute */
+@@ -665,6 +594,8 @@
+                       dynamic_addr, 0);
+       tpnt->relro_addr = relro_addr;
+       tpnt->relro_size = relro_size;
++      tpnt->st_dev = st.st_dev;
++      tpnt->st_ino = st.st_ino;
+       tpnt->ppnt = (ElfW(Phdr) *)(intptr_t) (tpnt->loadaddr + epnt->e_phoff);
+       tpnt->n_phent = epnt->e_phnum;
+@@ -693,7 +624,7 @@
+       if (lpnt) {
+               lpnt = (unsigned long *) (dynamic_info[DT_PLTGOT]);
+               INIT_GOT(lpnt, tpnt);
+-      };
++      }
+       _dl_if_debug_dprint("\n\tfile='%s';  generating link map\n", libname);
+       _dl_if_debug_dprint("\t\tdynamic: %x  base: %x\n", dynamic_addr, libaddr);
+@@ -714,10 +645,12 @@
+       ElfW(Addr) reloc_addr;
+       if (rpnt->next)
+-              goof += _dl_fixup(rpnt->next, now_flag);
++              goof = _dl_fixup(rpnt->next, now_flag);
++      if (goof)
++              return goof;
+       tpnt = rpnt->dyn;
+-      if(!(tpnt->init_flag & RELOCS_DONE)) 
++      if(!(tpnt->init_flag & RELOCS_DONE))
+               _dl_if_debug_dprint("relocation processing: %s\n", tpnt->libname);
+       if (unlikely(tpnt->dynamic_info[UNSUPPORTED_RELOC_TYPE])) {
+@@ -735,7 +668,6 @@
+ #endif
+       if (tpnt->dynamic_info[DT_RELOC_TABLE_ADDR] &&
+           !(tpnt->init_flag & RELOCS_DONE)) {
+-              tpnt->init_flag |= RELOCS_DONE;
+               reloc_addr = tpnt->dynamic_info[DT_RELOC_TABLE_ADDR];
+               relative_count = tpnt->dynamic_info[DT_RELCONT_IDX];
+               if (relative_count) { /* Optimize the XX_RELATIVE relocations if possible */
+@@ -746,14 +678,14 @@
+               goof += _dl_parse_relocation_information(rpnt,
+                               reloc_addr,
+                               reloc_size);
++              tpnt->init_flag |= RELOCS_DONE;
+       }
+       if (tpnt->dynamic_info[DT_BIND_NOW])
+               now_flag = RTLD_NOW;
+       if (tpnt->dynamic_info[DT_JMPREL] &&
+           (!(tpnt->init_flag & JMP_RELOCS_DONE) ||
+            (now_flag && !(tpnt->rtld_flags & now_flag)))) {
+-              tpnt->rtld_flags |= now_flag; 
+-              tpnt->init_flag |= JMP_RELOCS_DONE;
++              tpnt->rtld_flags |= now_flag;
+               if (!(tpnt->rtld_flags & RTLD_NOW)) {
+                       _dl_parse_lazy_relocation_information(rpnt,
+                                       tpnt->dynamic_info[DT_JMPREL],
+@@ -763,6 +695,7 @@
+                                       tpnt->dynamic_info[DT_JMPREL],
+                                       tpnt->dynamic_info[DT_PLTRELSZ]);
+               }
++              tpnt->init_flag |= JMP_RELOCS_DONE;
+       }
+       return goof;
+ }
+@@ -770,11 +703,18 @@
+ /* Minimal printf which handles only %s, %d, and %x */
+ void _dl_dprintf(int fd, const char *fmt, ...)
+ {
+-      long num;
++#if __WORDSIZE > 32
++      long int num;
++#else
++      int num;
++#endif
+       va_list args;
+       char *start, *ptr, *string;
+       static char *buf;
++      if (!fmt)
++              return;
++
+       buf = _dl_mmap((void *) 0, _dl_pagesize, PROT_READ | PROT_WRITE,
+                       MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+       if (_dl_mmap_check_error(buf)) {
+@@ -784,9 +724,6 @@
+       start = ptr = buf;
+-      if (!fmt)
+-              return;
+-
+       if (_dl_strlen(fmt) >= (_dl_pagesize - 1)) {
+               _dl_write(fd, "overflow\n", 11);
+               _dl_exit(20);
+@@ -818,8 +755,11 @@
+                               case 'd':
+                                       {
+                                               char tmp[22];
+-                                              num = va_arg(args, long);
+-
++#if __WORDSIZE > 32
++                                              num = va_arg(args, long int);
++#else
++                                              num = va_arg(args, int);
++#endif
+                                               string = _dl_simple_ltoa(tmp, num);
+                                               _dl_write(fd, string, _dl_strlen(string));
+                                               break;
+@@ -828,8 +768,11 @@
+                               case 'X':
+                                       {
+                                               char tmp[22];
+-                                              num = va_arg(args, long);
+-
++#if __WORDSIZE > 32
++                                              num = va_arg(args, long int);
++#else
++                                              num = va_arg(args, int);
++#endif
+                                               string = _dl_simple_ltoahex(tmp, num);
+                                               _dl_write(fd, string, _dl_strlen(string));
+                                               break;
+@@ -864,8 +807,10 @@
+ {
+       __dl_parse_dynamic_info(dpnt, dynamic_info, debug_addr, load_off);
+ }
++
++/* we want this in ldso.so and libdl.a but nowhere else */
+ #ifdef __USE_GNU
+-#if ! defined LIBDL || (! defined PIC && ! defined __PIC__)
++#if ! defined SHARED || (! defined PIC && ! defined __PIC__)
+ int
+ __dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info, size_t size, void *data), void *data)
+ {
+@@ -884,6 +829,6 @@
+       }
+       return ret;
+ }
+-strong_alias(__dl_iterate_phdr, dl_iterate_phdr);
++strong_alias(__dl_iterate_phdr, dl_iterate_phdr)
+ #endif
+ #endif
+diff -urN uClibc-0.9.28.orig/ldso/ldso/dl-hash.c uClibc-0.9.28/ldso/ldso/dl-hash.c
+--- uClibc-0.9.28.orig/ldso/ldso/dl-hash.c     2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/dl-hash.c  2006-04-28 00:14:35.000000000 -0600
+@@ -57,7 +57,7 @@
+ /* This is the hash function that is used by the ELF linker to generate the
+  * hash table that each executable and library is required to have.  We need
+  * it to decode the hash table.  */
+-static inline Elf32_Word _dl_elf_hash(const char *name)
++static inline Elf_Symndx _dl_elf_hash(const char *name)
+ {
+       unsigned long hash=0;
+       unsigned long tmp;
+@@ -77,21 +77,6 @@
+       return hash;
+ }
+-/* Check to see if a library has already been added to the hash chain.  */
+-struct elf_resolve *_dl_check_hashed_files(const char *libname)
+-{
+-      struct elf_resolve *tpnt;
+-      int len = _dl_strlen(libname);
+-
+-      for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
+-              if (_dl_strncmp(tpnt->libname, libname, len) == 0 &&
+-                  (tpnt->libname[len] == '\0' || tpnt->libname[len] == '.'))
+-                      return tpnt;
+-      }
+-
+-      return NULL;
+-}
+-
+ /*
+  * We call this function when we have just read an ELF library or executable.
+  * We add the relevant info to the symbol chain, so that we can resolve all
+@@ -99,9 +84,10 @@
+  */
+ struct elf_resolve *_dl_add_elf_hash_table(const char *libname,
+       char *loadaddr, unsigned long *dynamic_info, unsigned long dynamic_addr,
++      //attribute_unused
+       unsigned long dynamic_size)
+ {
+-      Elf32_Word *hash_addr;
++      Elf_Symndx *hash_addr;
+       struct elf_resolve *tpnt;
+       int i;
+@@ -125,7 +111,7 @@
+       tpnt->libtype = loaded_file;
+       if (dynamic_info[DT_HASH] != 0) {
+-              hash_addr = (Elf32_Word*)dynamic_info[DT_HASH];
++              hash_addr = (Elf_Symndx*)dynamic_info[DT_HASH];
+               tpnt->nbucket = *hash_addr++;
+               tpnt->nchain = *hash_addr++;
+               tpnt->elf_buckets = hash_addr;
+diff -urN uClibc-0.9.28.orig/ldso/ldso/dl-startup.c uClibc-0.9.28/ldso/ldso/dl-startup.c
+--- uClibc-0.9.28.orig/ldso/ldso/dl-startup.c  2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/dl-startup.c       2006-04-28 00:14:35.000000000 -0600
+@@ -98,7 +98,7 @@
+ int (*_dl_elf_main) (int, char **, char **);
+ static void* __rtld_stack_end; /* Points to argc on stack, e.g *((long *)__rtld_stackend) == argc */
+-strong_alias(__rtld_stack_end, __libc_stack_end); /* Exported version of __rtld_stack_end */
++strong_alias(__rtld_stack_end, __libc_stack_end) /* Exported version of __rtld_stack_end */
+ /* When we enter this piece of code, the program stack looks like this:
+       argc            argument counter (integer)
+@@ -307,5 +307,11 @@
+       SEND_STDERR_DEBUG("transfering control to application @ ");
+       _dl_elf_main = (int (*)(int, char **, char **)) auxvt[AT_ENTRY].a_un.a_val;
+       SEND_ADDRESS_STDERR_DEBUG(_dl_elf_main, 1);
++
++#ifndef START
++      return _dl_elf_main;
++#else
++#warning You need to update your arch ldso code
+       START();
++#endif
+ }
+diff -urN uClibc-0.9.28.orig/ldso/ldso/frv/dl-syscalls.h uClibc-0.9.28/ldso/ldso/frv/dl-syscalls.h
+--- uClibc-0.9.28.orig/ldso/ldso/frv/dl-syscalls.h     2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/frv/dl-syscalls.h  2006-04-28 00:14:35.000000000 -0600
+@@ -20,9 +20,10 @@
+ /* We can't use the real errno in ldso, since it has not yet
+  * been dynamicly linked in yet. */
++#include "sys/syscall.h"
+ extern int _dl_errno;
++#undef __set_errno
+ #define __set_errno(X) {(_dl_errno) = (X);}
+-#include "sys/syscall.h"
+ #include <sys/mman.h>
+ /* The code below is extracted from libc/sysdeps/linux/frv/_mmap.c */
+diff -urN uClibc-0.9.28.orig/ldso/ldso/frv/dl-sysdep.h uClibc-0.9.28/ldso/ldso/frv/dl-sysdep.h
+--- uClibc-0.9.28.orig/ldso/ldso/frv/dl-sysdep.h       2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/frv/dl-sysdep.h    2006-04-28 00:14:35.000000000 -0600
+@@ -65,8 +65,6 @@
+ extern int _dl_linux_resolve(void) __attribute__((__visibility__("hidden")));
+-#define do_rem(result, n, base) ((result) = (n) % (base))
+-
+ /* 16KiB page alignment.  Should perhaps be made dynamic using
+    getpagesize(), based on AT_PAGESZ from auxvt?  */
+ #define PAGE_ALIGN 0xffffc000
+diff -urN uClibc-0.9.28.orig/ldso/ldso/frv/elfinterp.c uClibc-0.9.28/ldso/ldso/frv/elfinterp.c
+--- uClibc-0.9.28.orig/ldso/ldso/frv/elfinterp.c       2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/frv/elfinterp.c    2006-04-28 00:14:35.000000000 -0600
+@@ -24,7 +24,7 @@
+ the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
+ USA.  */
+-#include <sys/cdefs.h>            /* __attribute_used__ */
++#include <features.h>
+ /* Program to load an ELF binary on a linux system, and run it.
+    References to symbols in sharable libraries can be resolved by either
+@@ -37,7 +37,7 @@
+    a more than adequate job of explaining everything required to get this
+    working. */
+-struct funcdesc_value volatile *__attribute__((__visibility__("hidden")))
++struct funcdesc_value volatile attribute_hidden *
+ _dl_linux_resolver (struct elf_resolve *tpnt, int reloc_entry)
+ {
+       int reloc_type;
+diff -urN uClibc-0.9.28.orig/ldso/ldso/i386/dl-startup.h uClibc-0.9.28/ldso/ldso/i386/dl-startup.h
+--- uClibc-0.9.28.orig/ldso/ldso/i386/dl-startup.h     2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/i386/dl-startup.h  2006-04-28 00:14:35.000000000 -0600
+@@ -3,7 +3,7 @@
+  * Architecture specific code used by dl-startup.c
+  * Copyright (C) 2000-2004 by Erik Andersen <andersen@codepoet.org>
+  */
+-asm(
++__asm__ (
+     " .text\n"
+     " .align 16\n"
+     " .globl  _start\n"
+@@ -41,9 +41,9 @@
+ #define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long*) & ARGS)+1)
+ /* Handle relocation of the symbols in the dynamic loader. */
+-static inline
++static __always_inline
+ void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, unsigned long *reloc_addr,
+-      unsigned long symbol_addr, unsigned long load_addr, Elf32_Sym *symtab)
++      unsigned long symbol_addr, unsigned long load_addr, attribute_unused Elf32_Sym *symtab)
+ {
+       switch (ELF32_R_TYPE(rpnt->r_info))
+       {
+@@ -64,8 +64,3 @@
+                       _dl_exit(1);
+       }
+ }
+-
+-/* Transfer control to the user's application, once the dynamic loader is
+- * done.  This routine has to exit the current function, then call the
+- * _dl_elf_main function.  */
+-#define START() return _dl_elf_main
+diff -urN uClibc-0.9.28.orig/ldso/ldso/i386/dl-syscalls.h uClibc-0.9.28/ldso/ldso/i386/dl-syscalls.h
+--- uClibc-0.9.28.orig/ldso/ldso/i386/dl-syscalls.h    2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/i386/dl-syscalls.h 2006-04-28 00:14:35.000000000 -0600
+@@ -1,5 +1,6 @@
+ /* We can't use the real errno in ldso, since it has not yet
+  * been dynamicly linked in yet. */
++#include "sys/syscall.h"
+ extern int _dl_errno;
++#undef __set_errno
+ #define __set_errno(X) {(_dl_errno) = (X);}
+-#include "sys/syscall.h"
+diff -urN uClibc-0.9.28.orig/ldso/ldso/i386/dl-sysdep.h uClibc-0.9.28/ldso/ldso/i386/dl-sysdep.h
+--- uClibc-0.9.28.orig/ldso/ldso/i386/dl-sysdep.h      2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/i386/dl-sysdep.h   2006-04-28 00:14:35.000000000 -0600
+@@ -25,8 +25,6 @@
+ struct elf_resolve;
+ extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
+-#define do_rem(result, n, base) ((result) = (n) % (base))
+-
+ /* 4096 bytes alignment */
+ #define PAGE_ALIGN 0xfffff000
+ #define ADDR_ALIGN 0xfff
+@@ -44,16 +42,18 @@
+ /* Return the link-time address of _DYNAMIC.  Conveniently, this is the
+    first element of the GOT.  This must be inlined in a function which
+    uses global data.  */
+-static inline Elf32_Addr __attribute__ ((unused))
++static inline Elf32_Addr elf_machine_dynamic (void) attribute_unused;
++static inline Elf32_Addr
+ elf_machine_dynamic (void)
+ {
+-      register Elf32_Addr *got asm ("%ebx");
++      register Elf32_Addr *got __asm__ ("%ebx");
+       return *got;
+ }
+ /* Return the run-time load address of the shared object.  */
+-static inline Elf32_Addr __attribute__ ((unused))
++static inline Elf32_Addr elf_machine_load_address (void) attribute_unused;
++static inline Elf32_Addr
+ elf_machine_load_address (void)
+ {
+       /* It doesn't matter what variable this is, the reference never makes
+@@ -61,7 +61,7 @@
+          via the GOT to make sure the compiler initialized %ebx in time.  */
+       extern int _dl_errno;
+       Elf32_Addr addr;
+-      asm ("leal _dl_start@GOTOFF(%%ebx), %0\n"
++      __asm__ ("leal _dl_start@GOTOFF(%%ebx), %0\n"
+            "subl _dl_start@GOT(%%ebx), %0"
+            : "=r" (addr) : "m" (_dl_errno) : "cc");
+       return addr;
+diff -urN uClibc-0.9.28.orig/ldso/ldso/i386/elfinterp.c uClibc-0.9.28/ldso/ldso/i386/elfinterp.c
+--- uClibc-0.9.28.orig/ldso/ldso/i386/elfinterp.c      2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/i386/elfinterp.c   2006-04-28 00:14:35.000000000 -0600
+@@ -67,12 +67,6 @@
+       strtab = (char *)tpnt->dynamic_info[DT_STRTAB];
+       symname = strtab + symtab[symtab_index].st_name;
+-      if (unlikely(reloc_type != R_386_JMP_SLOT)) {
+-              _dl_dprintf(2, "%s: Incorrect relocation type in jump relocations\n",
+-                          _dl_progname);
+-              _dl_exit(1);
+-      }
+-
+       /* Address of the jump instruction to fix up. */
+       instr_addr = ((unsigned long)this_reloc->r_offset +
+                     (unsigned long)tpnt->loadaddr);
+@@ -81,7 +75,7 @@
+       /* Get the address of the GOT entry. */
+       new_addr = _dl_find_hash(symname, tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT);
+       if (unlikely(!new_addr)) {
+-              _dl_dprintf(2, "%s: Can't resolve symbol '%s'\n", _dl_progname, symname);
++              _dl_dprintf(2, "%s: can't resolve symbol '%s' in lib '%s'.\n", _dl_progname, symname, tpnt->libname);
+               _dl_exit(1);
+       }
+@@ -147,15 +141,15 @@
+                       int reloc_type = ELF32_R_TYPE(rpnt->r_info);
+ #if defined (__SUPPORT_LD_DEBUG__)
+-                      _dl_dprintf(2, "can't handle reloc type %s\n",
+-                                  _dl_reltypes(reloc_type));
++                      _dl_dprintf(2, "can't handle reloc type '%s' in lib '%s'\n",
++                                  _dl_reltypes(reloc_type), tpnt->libname);
+ #else
+-                      _dl_dprintf(2, "can't handle reloc type %x\n",
+-                                  reloc_type);
++                      _dl_dprintf(2, "can't handle reloc type %x in lib '%s'\n",
++                                  reloc_type, tpnt->libname);
+ #endif
+-                      _dl_exit(-res);
++                      return res;
+               } else if (unlikely(res > 0)) {
+-                      _dl_dprintf(2, "can't resolve symbol\n");
++                      _dl_dprintf(2, "can't resolve symbol in lib '%s'.\n", tpnt->libname);
+                       return res;
+               }
+       }
+@@ -191,10 +185,8 @@
+                * might have been intentional.  We should not be linking local
+                * symbols here, so all bases should be covered.
+                */
+-              if (unlikely(!symbol_addr && ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK)) {
+-                      _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname);
+-                      _dl_exit(1);
+-              };
++              if (unlikely(!symbol_addr && ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK))
++                      return 1;
+       }
+ #if defined (__SUPPORT_LD_DEBUG__)
+@@ -233,7 +225,7 @@
+                       }
+                       break;
+               default:
+-                      return -1;      /* Calls _dl_exit(1). */
++                      return -1;
+       }
+ #if defined (__SUPPORT_LD_DEBUG__)
+@@ -273,7 +265,7 @@
+                       *reloc_addr += (unsigned long)tpnt->loadaddr;
+                       break;
+               default:
+-                      return -1;      /* Calls _dl_exit(1). */
++                      return -1;
+       }
+ #if defined (__SUPPORT_LD_DEBUG__)
+diff -urN uClibc-0.9.28.orig/ldso/ldso/ldso.c uClibc-0.9.28/ldso/ldso/ldso.c
+--- uClibc-0.9.28.orig/ldso/ldso/ldso.c        2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/ldso.c     2006-05-02 13:55:54.000000000 -0600
+@@ -39,7 +39,7 @@
+ #define ALLOW_ZERO_PLTGOT
+ /* Pull in the value of _dl_progname */
+-#include "dl-progname.h"
++#include LDSO_ELFINTERP
+ /* Global variables used within the shared library loader */
+ char *_dl_library_path         = 0;   /* Where we look for libraries */
+@@ -74,7 +74,8 @@
+  * can set an internal breakpoint on it, so that we are notified when the
+  * address mapping is changed in some way.
+  */
+-void _dl_debug_state(void)
++void _dl_debug_state(void);
++void _dl_debug_state()
+ {
+ }
+@@ -82,9 +83,78 @@
+ static unsigned char *_dl_mmap_zero   = 0;    /* Also used by _dl_malloc */
+ static struct elf_resolve **init_fini_list;
+-static int nlist; /* # items in init_fini_list */
++static unsigned int nlist; /* # items in init_fini_list */
+ extern void _start(void);
++#ifdef __UCLIBC_HAS_SSP__
++#ifndef __UCLIBC_HAS_SSP_COMPAT__
++#define __UCLIBC_HAS_SSP_COMPAT__ 1
++#endif
++# include <dl-osinfo.h>
++uintptr_t stack_chk_guard;
++# ifndef THREAD_SET_STACK_GUARD
++/* Only exported for architectures that don't store the stack guard canary
++ * in local thread area.  */
++uintptr_t __stack_chk_guard attribute_relro;
++#  ifdef __UCLIBC_HAS_SSP_COMPAT__
++strong_alias(__stack_chk_guard,__guard)
++#  endif
++# elif __UCLIBC_HAS_SSP_COMPAT__
++uintptr_t __guard attribute_relro;
++# endif
++#endif
++
++static void _dl_run_array_forward(unsigned long array, unsigned long size,
++                                ElfW(Addr) loadaddr)
++{
++      if (array != 0) {
++              unsigned int j;
++              unsigned int jm;
++              ElfW(Addr) *addrs;
++              jm = size / sizeof (ElfW(Addr));
++              addrs = (ElfW(Addr) *) (array + loadaddr);
++              for (j = 0; j < jm; ++j) {
++                      void (*dl_elf_func) (void);
++                      dl_elf_func = (void (*)(void)) (intptr_t) addrs[j];
++                      (*dl_elf_func) ();
++              }
++      }
++}
++
++void _dl_run_init_array(struct elf_resolve *tpnt);
++void _dl_run_init_array(struct elf_resolve *tpnt)
++{
++      _dl_run_array_forward(tpnt->dynamic_info[DT_INIT_ARRAY],
++                            tpnt->dynamic_info[DT_INIT_ARRAYSZ],
++                            tpnt->loadaddr);
++}
++
++void _dl_app_init_array(void);
++void _dl_app_init_array(void)
++{
++      _dl_run_init_array(_dl_loaded_modules);
++}
++
++void _dl_run_fini_array(struct elf_resolve *tpnt);
++void _dl_run_fini_array(struct elf_resolve *tpnt)
++{
++      if (tpnt->dynamic_info[DT_FINI_ARRAY]) {
++              ElfW(Addr) *array = (ElfW(Addr) *) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI_ARRAY]);
++              unsigned int i = (tpnt->dynamic_info[DT_FINI_ARRAYSZ] / sizeof(ElfW(Addr)));
++              while (i-- > 0) {
++                      void (*dl_elf_func) (void);
++                      dl_elf_func = (void (*)(void)) (intptr_t) array[i];
++                      (*dl_elf_func) ();
++              }
++      }
++}
++
++void _dl_app_fini_array(void);
++void _dl_app_fini_array(void)
++{
++      _dl_run_fini_array(_dl_loaded_modules);
++}
++
+ static void __attribute__ ((destructor)) __attribute_used__ _dl_fini(void)
+ {
+       int i;
+@@ -95,6 +165,7 @@
+               if (tpnt->init_flag & FINI_FUNCS_CALLED)
+                       continue;
+               tpnt->init_flag |= FINI_FUNCS_CALLED;
++              _dl_run_fini_array(tpnt);
+               if (tpnt->dynamic_info[DT_FINI]) {
+                       void (*dl_elf_func) (void);
+@@ -112,7 +183,8 @@
+       ElfW(Phdr) *ppnt;
+       ElfW(Dyn) *dpnt;
+       char *lpntstr;
+-      int i, goof = 0, unlazy = 0, trace_loaded_objects = 0;
++      unsigned int i;
++      int unlazy = 0, trace_loaded_objects = 0;
+       struct dyn_elf *rpnt;
+       struct elf_resolve *tcurr;
+       struct elf_resolve *tpnt1;
+@@ -128,6 +200,7 @@
+        * setup so we can use _dl_dprintf() to print debug noise
+        * instead of the SEND_STDERR macros used in dl-startup.c */
++      _dl_memset(app_tpnt, 0x00, sizeof(*app_tpnt));
+       /* Store the page size for later use */
+       _dl_pagesize = (auxvt[AT_PAGESZ].a_un.a_val) ? (size_t) auxvt[AT_PAGESZ].a_un.a_val : PAGE_SIZE;
+@@ -168,8 +241,8 @@
+        * Note that for SUID programs we ignore the settings in
+        * LD_LIBRARY_PATH.
+        */
+-      if ((auxvt[AT_UID].a_un.a_val == -1 && _dl_suid_ok()) ||
+-          (auxvt[AT_UID].a_un.a_val != -1 &&
++      if ((auxvt[AT_UID].a_un.a_val == (size_t)-1 && _dl_suid_ok()) ||
++          (auxvt[AT_UID].a_un.a_val != (size_t)-1 &&
+            auxvt[AT_UID].a_un.a_val == auxvt[AT_EUID].a_un.a_val &&
+            auxvt[AT_GID].a_un.a_val == auxvt[AT_EGID].a_un.a_val)) {
+               _dl_secure = 0;
+@@ -196,6 +269,20 @@
+               unlazy = RTLD_NOW;
+       }
++      /* sjhill: your TLS init should go before this */
++#ifdef __UCLIBC_HAS_SSP__
++      /* Set up the stack checker's canary.  */
++      stack_chk_guard = _dl_setup_stack_chk_guard ();
++# ifdef THREAD_SET_STACK_GUARD
++      THREAD_SET_STACK_GUARD (stack_chk_guard);
++#  ifdef __UCLIBC_HAS_SSP_COMPAT__
++      __guard = stack_chk_guard;
++#  endif
++# else
++      __stack_chk_guard = stack_chk_guard;
++# endif
++#endif
++
+       /* At this point we are now free to examine the user application,
+        * and figure out which libraries are supposed to be called.  Until
+        * we have this list, we will not be completely ready for dynamic
+@@ -206,12 +293,12 @@
+        * different from what the ELF header says for ET_DYN/PIE executables.
+        */
+       {
+-              int i;
+-              ElfW(Phdr) *ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
++              unsigned int idx;
++              ElfW(Phdr) *phdr = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
+-              for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++)
+-                      if (ppnt->p_type == PT_PHDR) {
+-                              app_tpnt->loadaddr = (ElfW(Addr)) (auxvt[AT_PHDR].a_un.a_val - ppnt->p_vaddr);
++              for (idx = 0; idx < auxvt[AT_PHNUM].a_un.a_val; idx++, phdr++)
++                      if (phdr->p_type == PT_PHDR) {
++                              app_tpnt->loadaddr = (ElfW(Addr)) (auxvt[AT_PHDR].a_un.a_val - phdr->p_vaddr);
+                               break;
+                       }
+@@ -459,8 +546,8 @@
+                                            PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+               _dl_close(fd);
+               if (preload == (caddr_t) -1) {
+-                      _dl_dprintf(_dl_debug_file, "%s: can't map file '%s'\n",
+-                                  _dl_progname, LDSO_PRELOAD);
++                      _dl_dprintf(_dl_debug_file, "%s:%i: can't map '%s'\n",
++                                  _dl_progname, __LINE__, LDSO_PRELOAD);
+                       break;
+               }
+@@ -528,15 +615,15 @@
+       nlist = 0;
+       for (tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next) {
+-              ElfW(Dyn) *dpnt;
++              ElfW(Dyn) *this_dpnt;
+               nlist++;
+-              for (dpnt = (ElfW(Dyn) *) tcurr->dynamic_addr; dpnt->d_tag; dpnt++) {
+-                      if (dpnt->d_tag == DT_NEEDED) {
++              for (this_dpnt = (ElfW(Dyn) *) tcurr->dynamic_addr; this_dpnt->d_tag; this_dpnt++) {
++                      if (this_dpnt->d_tag == DT_NEEDED) {
+                               char *name;
+                               struct init_fini_list *tmp;
+-                              lpntstr = (char*) (tcurr->dynamic_info[DT_STRTAB] + dpnt->d_un.d_val);
++                              lpntstr = (char*) (tcurr->dynamic_info[DT_STRTAB] + this_dpnt->d_un.d_val);
+                               name = _dl_get_last_path_component(lpntstr);
+                               if (_dl_strcmp(name, UCLIBC_LDSO) == 0)
+                                       continue;
+@@ -633,7 +720,7 @@
+               ElfW(Ehdr) *epnt = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_val;
+               ElfW(Phdr) *myppnt = (ElfW(Phdr) *) (load_addr + epnt->e_phoff);
+               int j;
+-              
++
+               tpnt = _dl_add_elf_hash_table(tpnt->libname, (char *)load_addr,
+                                             tpnt->dynamic_info,
+                                             (unsigned long)tpnt->dynamic_addr,
+@@ -703,16 +790,14 @@
+        * order so that COPY directives work correctly.
+        */
+       if (_dl_symbol_tables)
+-              goof += _dl_fixup(_dl_symbol_tables, unlazy);
++              if (_dl_fixup(_dl_symbol_tables, unlazy))
++                      _dl_exit(-1);
+       for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
+               if (tpnt->relro_size)
+                       _dl_protect_relro (tpnt);
+       }
+-
+-
+-
+       /* OK, at this point things are pretty much ready to run.  Now we need
+        * to touch up a few items that are required, and then we can let the
+        * user application have at it.  Note that the dynamic linker itself
+@@ -746,6 +831,14 @@
+       /* Notify the debugger we have added some objects. */
+       _dl_debug_addr->r_state = RT_ADD;
+       _dl_debug_state();
++
++      /* Run pre-initialization functions for the executable.  */
++      _dl_run_array_forward(_dl_loaded_modules->dynamic_info[DT_PREINIT_ARRAY],
++                            _dl_loaded_modules->dynamic_info[DT_PREINIT_ARRAYSZ],
++                            _dl_loaded_modules->loadaddr);
++
++      /* Run initialization functions for loaded objects.  For the
++         main executable, they will be run from __uClibc_main.  */
+       for (i = nlist; i; --i) {
+               tpnt = init_fini_list[i-1];
+               tpnt->init_fini = NULL; /* Clear, since alloca was used */
+@@ -762,17 +855,9 @@
+                       (*dl_elf_func) ();
+               }
+-      }
+-#ifdef _DL_FINI_CRT_COMPAT
+-      /* arches that have moved their ldso FINI handling should skip this part */
+-      {
+-              int (*_dl_atexit) (void *) = (int (*)(void *)) (intptr_t) _dl_find_hash("atexit",
+-                              _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT);
+-              if (_dl_atexit)
+-                      (*_dl_atexit) (_dl_fini);
++              _dl_run_init_array(tpnt);
+       }
+-#endif
+       /* Find the real malloc function and make ldso functions use that from now on */
+        _dl_malloc_function = (void* (*)(size_t)) (intptr_t) _dl_find_hash("malloc",
+diff -urN uClibc-0.9.28.orig/ldso/ldso/m68k/dl-startup.h uClibc-0.9.28/ldso/ldso/m68k/dl-startup.h
+--- uClibc-0.9.28.orig/ldso/ldso/m68k/dl-startup.h     2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/m68k/dl-startup.h  2006-04-28 00:14:35.000000000 -0600
+@@ -4,23 +4,48 @@
+  * Copyright (C) 2005 by Erik Andersen <andersen@codepoet.org>
+  */
+-asm(
+-    " .text\n"
+-    " .globl  _start\n"
+-    " .type   _start,@function\n"
+-    "_start:\n"
+-    " .set    _start,_dl_start\n"
+-    " .size   _start,.-_start\n"
+-    " .previous\n"
+-);
++asm ("\
++      .text\n\
++      .globl _start\n\
++      .type _start,@function\n\
++_start:\n\
++      move.l %sp, -(%sp)\n\
++      jbsr _dl_start\n\
++      addq.l #4, %sp\n\
++      /* FALLTHRU */\n\
++\n\
++      .globl _dl_start_user\n\
++.type _dl_start_user,@function\n\
++_dl_start_user:\n\
++      # Save the user entry point address in %a4.\n\
++      move.l %d0, %a4\n\
++      # See if we were run as a command with the executable file\n\
++      # name as an extra leading argument.\n\
++      move.l _dl_skip_args(%pc), %d0\n\
++      # Pop the original argument count\n\
++      move.l (%sp)+, %d1\n\
++      # Subtract _dl_skip_args from it.\n\
++      sub.l %d0, %d1\n\
++      # Adjust the stack pointer to skip _dl_skip_args words.\n\
++      lea (%sp, %d0*4), %sp\n\
++      # Push back the modified argument count.\n\
++      move.l %d1, -(%sp)\n\
++      # Pass our finalizer function to the user in %a1.\n\
++      lea _dl_fini(%pc), %a1\n\
++      # Initialize %fp with the stack pointer.\n\
++      move.l %sp, %fp\n\
++      # Jump to the user's entry point.\n\
++      jmp (%a4)\n\
++      .size _dl_start_user, . - _dl_start_user\n\
++      .previous");
+ /* Get a pointer to the argv array.  On many platforms this can be just
+  * the address if the first argument, on other platforms we need to
+  * do something a little more subtle here.  */
+-#define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned int *) & ARGS)
++#define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long *) ARGS) + 1)
+ /* Handle relocation of the symbols in the dynamic loader. */
+-static inline
++static __always_inline
+ void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, unsigned long *reloc_addr,
+       unsigned long symbol_addr, unsigned long load_addr, Elf32_Sym *symtab)
+ {
+@@ -59,12 +84,3 @@
+                       _dl_exit (1);
+       }
+ }
+-
+-/* Transfer control to the user's application, once the dynamic loader is
+- * done.  This routine has to exit the current function, then call the
+- * _dl_elf_main function.  */
+-#define START() \
+-      __asm__ volatile ( \
+-              "unlk %%a6\n\t" \
+-              "jmp %0@" \
+-              : : "a" (_dl_elf_main));
+diff -urN uClibc-0.9.28.orig/ldso/ldso/m68k/dl-syscalls.h uClibc-0.9.28/ldso/ldso/m68k/dl-syscalls.h
+--- uClibc-0.9.28.orig/ldso/ldso/m68k/dl-syscalls.h    2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/m68k/dl-syscalls.h 2006-04-28 00:14:35.000000000 -0600
+@@ -1,5 +1,6 @@
+ /* We can't use the real errno in ldso, since it has not yet
+  * been dynamicly linked in yet. */
++#include "sys/syscall.h"
+ extern int _dl_errno;
++#undef __set_errno
+ #define __set_errno(X) {(_dl_errno) = (X);}
+-#include "sys/syscall.h"
+diff -urN uClibc-0.9.28.orig/ldso/ldso/m68k/dl-sysdep.h uClibc-0.9.28/ldso/ldso/m68k/dl-sysdep.h
+--- uClibc-0.9.28.orig/ldso/ldso/m68k/dl-sysdep.h      2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/m68k/dl-sysdep.h   2006-04-28 00:14:35.000000000 -0600
+@@ -25,10 +25,6 @@
+ struct elf_resolve;
+ extern unsigned int _dl_linux_resolver (struct elf_resolve *, int);
+-/* Define this because we do not want to call .udiv in the library.
+-   Not needed for m68k.  */
+-#define do_rem(result, n, base)  ((result) = (n) % (base))
+-
+ /* 4096 bytes alignment */
+ #define PAGE_ALIGN 0xfffff000
+ #define ADDR_ALIGN 0xfff
+diff -urN uClibc-0.9.28.orig/ldso/ldso/m68k/elfinterp.c uClibc-0.9.28/ldso/ldso/m68k/elfinterp.c
+--- uClibc-0.9.28.orig/ldso/ldso/m68k/elfinterp.c      2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/m68k/elfinterp.c   2006-04-28 00:14:35.000000000 -0600
+@@ -40,6 +40,8 @@
+    a more than adequate job of explaining everything required to get this
+    working. */
++#include "ldso.h"
++
+ extern int _dl_linux_resolve(void);
+ unsigned int
+@@ -48,20 +50,20 @@
+       int reloc_type;
+       ELF_RELOC *this_reloc;
+       char *strtab;
+-      Elf32_Sym *symtab;
++      ElfW(Sym) *symtab;
+       int symtab_index;
+-      ELF_RELOC *rel_addr;
++      char *rel_addr;
+       char *new_addr;
+       char **got_addr;
+-      unsigned int instr_addr;
++      ElfW(Addr) instr_addr;
+       char *symname;
+-      rel_addr = (ELF_RELOC *)tpnt->dynamic_info[DT_JMPREL];
+-      this_reloc = (ELF_RELOC *)(intptr_t)(rel_addr + reloc_entry);
+-      reloc_type = ELF32_R_TYPE(this_reloc->r_info);
+-      symtab_index = ELF32_R_SYM(this_reloc->r_info);
++      rel_addr = (char *)tpnt->dynamic_info[DT_JMPREL];
++      this_reloc = (ELF_RELOC *)(rel_addr + reloc_entry);
++      reloc_type = ELF_R_TYPE(this_reloc->r_info);
++      symtab_index = ELF_R_SYM(this_reloc->r_info);
+-      symtab = (Elf32_Sym *)(intptr_t)tpnt->dynamic_info[DT_SYMTAB];
++      symtab = (ElfW(Sym) *)tpnt->dynamic_info[DT_SYMTAB];
+       strtab = (char *)tpnt->dynamic_info[DT_STRTAB];
+       symname = strtab + symtab[symtab_index].st_name;
+@@ -72,7 +74,7 @@
+       }
+       /* Address of the jump instruction to fix up. */
+-      instr_addr = ((int)this_reloc->r_offset + (int)tpnt->loadaddr);
++      instr_addr = (this_reloc->r_offset + tpnt->loadaddr);
+       got_addr = (char **)instr_addr;
+       /* Get the address of the GOT entry. */
+@@ -88,159 +90,237 @@
+                       _dl_dprintf(_dl_debug_file, "\nresolve function: %s", symname);
+                       if (_dl_debug_detail)
+                               _dl_dprintf(_dl_debug_file,
+-                                          "\n\tpatched: %x ==> %x @ %x",
++                                          "\tpatched: %x ==> %x @ %x\n",
+                                           *got_addr, new_addr, got_addr);
+               }
+       }
+-      if (!_dl_debug_nofixups) {
+-              *got_addr = new_addr;
+-      }
+-#else
+-      *got_addr = new_addr;
++      if (!_dl_debug_nofixups)
+ #endif
++              *got_addr = new_addr;
+-  return (unsigned int)new_addr;
++      return (unsigned int)new_addr;
+ }
+-void
+-_dl_parse_lazy_relocation_information(struct dyn_elf *arg_rpnt,
+-      unsigned long rel_addr, unsigned long rel_size)
++static int
++_dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope,
++        unsigned long rel_addr, unsigned long rel_size,
++        int (*reloc_fnc)(struct elf_resolve *tpnt, struct dyn_elf *scope,
++                         ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab))
+ {
+-      int i;
++      unsigned int i;
+       char *strtab;
+-      int reloc_type;
++      ElfW(Sym) *symtab;
++      ELF_RELOC *rpnt;
+       int symtab_index;
+-      Elf32_Sym *symtab;
+-      Elf32_Rela *rpnt;
+-      unsigned int *reloc_addr;
+-      struct elf_resolve *tpnt = arg_rpnt->dyn;
+-
+-      /* Now parse the relocation information.  */
+-      rpnt = (Elf32_Rela *)rel_addr;
+-      rel_size = rel_size / sizeof (Elf32_Rela);
+-      symtab = (Elf32_Sym *)tpnt->dynamic_info[DT_SYMTAB];
++      /* Parse the relocation information. */
++      rpnt = (ELF_RELOC *)rel_addr;
++      rel_size /= sizeof(ELF_RELOC);
++
++      symtab = (ElfW(Sym) *)tpnt->dynamic_info[DT_SYMTAB];
+       strtab = (char *)tpnt->dynamic_info[DT_STRTAB];
+       for (i = 0; i < rel_size; i++, rpnt++) {
+-              reloc_addr = (int *) (tpnt->loadaddr + (int) rpnt->r_offset);
+-              reloc_type = ELF32_R_TYPE (rpnt->r_info);
+-              symtab_index = ELF32_R_SYM (rpnt->r_info);
++              int res;
+-              switch (reloc_type)
+-              {
+-              case R_68K_NONE:
+-                      break;
+-              case R_68K_JMP_SLOT:
+-                      *reloc_addr += (unsigned int) tpnt->loadaddr;
+-              break;
+-              default:
+-                      _dl_dprintf (2, "%s: (LAZY) can't handle reloc type ", _dl_progname);
++              symtab_index = ELF_R_SYM(rpnt->r_info);
++
++              debug_sym(symtab, strtab, symtab_index);
++              debug_reloc(symtab, strtab, rpnt);
++
++              res = reloc_fnc(tpnt, scope, rpnt, symtab, strtab);
++
++              if (res == 0)
++                      continue;
++
++              _dl_dprintf(2, "\n%s: ", _dl_progname);
++
++              if (symtab_index)
++                      _dl_dprintf(2, "symbol '%s': ",
++                                  strtab + symtab[symtab_index].st_name);
++
++              if (unlikely(res < 0)) {
++                      int reloc_type = ELF_R_TYPE(rpnt->r_info);
++
++                      _dl_dprintf(2, "can't handle reloc type "
+ #if defined (__SUPPORT_LD_DEBUG__)
+-                      _dl_dprintf (2, "%s ", _dl_reltypes_tab[reloc_type]);
++                                  "%s\n", _dl_reltypes(reloc_type));
++#else
++                                  "%x\n", reloc_type);
+ #endif
+-                      if (symtab_index)
+-                              _dl_dprintf (2, "'%s'", strtab + symtab[symtab_index].st_name);
+-                      _dl_dprintf (2, "\n");
+-                      _dl_exit (1);
++                      _dl_exit(-res);
++              } else if (unlikely(res > 0)) {
++                      _dl_dprintf(2, "can't resolve symbol\n");
++                      return res;
+               }
+       }
++
++      return 0;
+ }
+-int
+-_dl_parse_relocation_information(struct dyn_elf *arg_rpnt,
+-      unsigned long rel_addr, unsigned long rel_size)
++static int
++_dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
++           ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab)
+ {
+-      int i;
+-      char *strtab;
+       int reloc_type;
+-      int goof = 0;
+-      Elf32_Sym *symtab;
+-      Elf32_Rela *rpnt;
+-      unsigned int *reloc_addr;
+-      unsigned int symbol_addr;
+       int symtab_index;
+-      struct elf_resolve *tpnt = arg_rpnt->dyn;
+-      /* Now parse the relocation information */
++      char *symname;
++      ElfW(Sym) *sym;
++      ElfW(Addr) *reloc_addr;
++      ElfW(Addr) symbol_addr;
++#if defined (__SUPPORT_LD_DEBUG__)
++      ElfW(Addr) old_val;
++#endif
+-      rpnt = (Elf32_Rela *)rel_addr;
+-      rel_size = rel_size / sizeof (Elf32_Rela);
++      reloc_addr = (ElfW(Addr)*)(tpnt->loadaddr + (unsigned long)rpnt->r_offset);
++      reloc_type = ELF_R_TYPE(rpnt->r_info);
++      symtab_index = ELF_R_SYM(rpnt->r_info);
++      sym = &symtab[symtab_index];
++      symbol_addr = 0;
++      symname = strtab + sym->st_name;
++
++      if (symtab_index) {
++              symbol_addr = (ElfW(Addr))_dl_find_hash(symname, scope, tpnt,
++                                                          elf_machine_type_class(reloc_type));
++              /*
++               * We want to allow undefined references to weak symbols - this
++               * might have been intentional.  We should not be linking local
++               * symbols here, so all bases should be covered.
++               */
++              if (unlikely(!symbol_addr && ELF_ST_BIND(sym->st_info) != STB_WEAK)) {
++                      _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname);
++                      _dl_exit(1);
++              };
++      }
+-      symtab = (Elf32_Sym *)tpnt->dynamic_info[DT_SYMTAB];
+-      strtab = (char *)tpnt->dynamic_info[DT_STRTAB];
++#if defined (__SUPPORT_LD_DEBUG__)
++      old_val = *reloc_addr;
++#endif
+-      for (i = 0; i < rel_size; i++, rpnt++) {
+-              reloc_addr = (int *) (tpnt->loadaddr + (int) rpnt->r_offset);
+-              reloc_type = ELF32_R_TYPE (rpnt->r_info);
+-              symtab_index = ELF32_R_SYM (rpnt->r_info);
+-              symbol_addr = 0;
+-              if (symtab_index) {
+-                      symbol_addr = (unsigned int)
+-                      _dl_find_hash (strtab + symtab[symtab_index].st_name,
+-                                     tpnt->symbol_scope, tpnt,
+-                                     elf_machine_type_class(reloc_type));
+-
+-                      /* We want to allow undefined references to weak symbols -
+-                         this might have been intentional.  We should not be
+-                         linking local symbols here, so all bases should be
+-                         covered.  */
+-                      if (!symbol_addr
+-                          && ELF32_ST_BIND (symtab[symtab_index].st_info) != STB_WEAK)
+-                      {
+-                              _dl_dprintf (2, "%s: can't resolve symbol '%s'\n",
+-                                           _dl_progname, strtab + symtab[symtab_index].st_name);
+-                              _dl_exit (1);
+-                      }
+-              }
+-              switch (reloc_type)
+-              {
+-                      case R_68K_NONE:
+-                              break;
+-                      case R_68K_8:
+-                              *(char *) reloc_addr = symbol_addr + rpnt->r_addend;
+-                              break;
+-                      case R_68K_16:
+-                              *(short *) reloc_addr = symbol_addr + rpnt->r_addend;
+-                              break;
+-                      case R_68K_32:
+-                              *reloc_addr = symbol_addr + rpnt->r_addend;
+-                              break;
+-                      case R_68K_PC8:
+-                              *(char *) reloc_addr = (symbol_addr + rpnt->r_addend
+-                                                     - (unsigned int) reloc_addr);
+-                              break;
+-                      case R_68K_PC16:
+-                              *(short *) reloc_addr = (symbol_addr + rpnt->r_addend
+-                                                      - (unsigned int) reloc_addr);
+-                              break;
+-                      case R_68K_PC32:
+-                              *reloc_addr = (symbol_addr + rpnt->r_addend
+-                                            - (unsigned int) reloc_addr);
+-                              break;
+-                      case R_68K_GLOB_DAT:
+-                      case R_68K_JMP_SLOT:
+-                              *reloc_addr = symbol_addr;
+-                              break;
+-                      case R_68K_RELATIVE:
+-                              *reloc_addr = ((unsigned int) tpnt->loadaddr
+-                                            /* Compatibility kludge.  */
+-                                            + (rpnt->r_addend ? : *reloc_addr));
+-                              break;
+-                      case R_68K_COPY:
++      switch (reloc_type) {
++              case R_68K_NONE:
++                      break;
++              case R_68K_8:
++                      *(char *) reloc_addr = symbol_addr + rpnt->r_addend;
++                      break;
++              case R_68K_16:
++                      *(short *) reloc_addr = symbol_addr + rpnt->r_addend;
++                      break;
++              case R_68K_32:
++                      *reloc_addr = symbol_addr + rpnt->r_addend;
++                      break;
++              case R_68K_PC8:
++                      *(char *) reloc_addr = (symbol_addr + rpnt->r_addend
++                                             - (unsigned int) reloc_addr);
++                      break;
++              case R_68K_PC16:
++                      *(short *) reloc_addr = (symbol_addr + rpnt->r_addend
++                                              - (unsigned int) reloc_addr);
++                      break;
++              case R_68K_PC32:
++                      *reloc_addr = (symbol_addr + rpnt->r_addend
++                                    - (unsigned int) reloc_addr);
++                      break;
++              case R_68K_GLOB_DAT:
++              case R_68K_JMP_SLOT:
++                      *reloc_addr = symbol_addr + rpnt->r_addend;
++                      break;
++              /* handled by elf_machine_relative()
++              case R_68K_RELATIVE:
++                      *reloc_addr = ((unsigned int) tpnt->loadaddr
++                                    / * Compatibility kludge.  * /
++                                    + (rpnt->r_addend ? : *reloc_addr));
++              */
++                      break;
++              case R_68K_COPY:
++                      if (symbol_addr) {
++#if defined (__SUPPORT_LD_DEBUG__)
++                              if (_dl_debug_move)
++                                      _dl_dprintf(_dl_debug_file,
++                                                  "\t%s move %d bytes from %x to %x\n",
++                                                  symname, sym->st_size,
++                                                  symbol_addr, reloc_addr);
++#endif
+                               _dl_memcpy ((void *) reloc_addr,
+                                           (void *) symbol_addr,
+-                                          symtab[symtab_index].st_size);
+-                              break;
+-                      default:
+-                              _dl_dprintf (2, "%s: can't handle reloc type ", _dl_progname);
+-#if defined (__SUPPORT_LD_DEBUG__)
+-                              _dl_dprintf (2, "%s ", _dl_reltypes_tab[reloc_type]);
+-#endif
+-                              if (symtab_index)
+-                                      _dl_dprintf (2, "'%s'", strtab + symtab[symtab_index].st_name);
+-                              _dl_dprintf (2, "\n");
+-                              _dl_exit (1);
+-              }
++                                          sym->st_size);
++                      } else
++                              _dl_dprintf(_dl_debug_file, "no symbol_addr to copy !?\n");
++                      break;
++
++              default:
++                      return -1;      /* Calls _dl_exit(1). */
++      }
++
++#if defined (__SUPPORT_LD_DEBUG__)
++      if (_dl_debug_reloc && _dl_debug_detail)
++              _dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x\n",
++                          old_val, *reloc_addr, reloc_addr);
++#endif
++
++      return 0;
++}
++
++#undef LAZY_RELOC_WORKS
++#ifdef LAZY_RELOC_WORKS
++static int
++_dl_do_lazy_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
++                ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab)
++{
++      int reloc_type;
++      int symtab_index;
++      ElfW(Addr) *reloc_addr;
++#if defined (__SUPPORT_LD_DEBUG__)
++      ElfW(Addr) old_val;
++#endif
++
++      (void)scope;
++      symtab_index = ELF_R_SYM(rpnt->r_info);
++      (void)strtab;
++
++      reloc_addr = (ElfW(Addr)*)(tpnt->loadaddr + rpnt->r_offset);
++      reloc_type = ELF_R_TYPE(rpnt->r_info);
++
++#if defined (__SUPPORT_LD_DEBUG__)
++      old_val = *reloc_addr;
++#endif
++
++      switch (reloc_type) {
++              case R_68K_NONE:
++                      break;
++              case R_68K_JMP_SLOT:
++                      *reloc_addr += (unsigned int) tpnt->loadaddr;
++                      break;
++              default:
++                      _dl_exit(1);
+       }
+-      return goof;
++
++#if defined (__SUPPORT_LD_DEBUG__)
++      if (_dl_debug_reloc && _dl_debug_detail)
++              _dl_dprintf(_dl_debug_file, "\tpatched_lazy: %x ==> %x @ %x\n",
++                          old_val, *reloc_addr, reloc_addr);
++#endif
++
++      return 0;
++}
++#endif
++
++void
++_dl_parse_lazy_relocation_information(struct dyn_elf *rpnt,
++                                    unsigned long rel_addr,
++                                    unsigned long rel_size)
++{
++#ifdef LAZY_RELOC_WORKS
++      (void)_dl_parse(rpnt->dyn, NULL, rel_addr, rel_size, _dl_do_lazy_reloc);
++#else
++      _dl_parse_relocation_information(rpnt, rel_addr, rel_size);
++#endif
++}
++
++int
++_dl_parse_relocation_information(struct dyn_elf *rpnt,
++                               unsigned long rel_addr,
++                               unsigned long rel_size)
++{
++      return _dl_parse(rpnt->dyn, rpnt->dyn->symbol_scope, rel_addr, rel_size, _dl_do_reloc);
+ }
+diff -urN uClibc-0.9.28.orig/ldso/ldso/m68k/resolve.S uClibc-0.9.28/ldso/ldso/m68k/resolve.S
+--- uClibc-0.9.28.orig/ldso/ldso/m68k/resolve.S        2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/m68k/resolve.S     2006-04-28 00:14:35.000000000 -0600
+@@ -8,14 +8,16 @@
+ .globl _dl_linux_resolve
+       .type   _dl_linux_resolve,@function
+ _dl_linux_resolve:
+-      moveml  %a0/%a1,%sp@-
+-#ifdef __PIC__
+-      bsrl    _dl_linux_resolver@PLTPC
+-#else
+-      jbsr    _dl_linux_resolver
+-#endif
+-      moveml  %sp@+,%a0/%a1
+-      addql   #8,%sp
+-      jmp     @(%d0)
+-.LFE2:
+-      .size _dl_linux_resolve,.LFE2-_dl_linux_resolve
++      # Save %a0 (struct return address) and %a1.
++      move.l %a0, -(%sp)
++      move.l %a1, -(%sp)
++      # Call the real address resolver.
++      jbsr _dl_linux_resolver
++      # Restore register %a0 and %a1.
++      move.l (%sp)+, %a1
++      move.l (%sp)+, %a0
++      # Pop parameters
++      addq.l #8, %sp
++      # Call real function.
++      jmp (%d0)
++.size _dl_linux_resolve,.-_dl_linux_resolve
+diff -urN uClibc-0.9.28.orig/ldso/ldso/mips/dl-startup.h uClibc-0.9.28/ldso/ldso/mips/dl-startup.h
+--- uClibc-0.9.28.orig/ldso/ldso/mips/dl-startup.h     2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/mips/dl-startup.h  2006-04-28 00:14:35.000000000 -0600
+@@ -136,13 +136,3 @@
+               SEND_STDERR("Aiieeee!");                                        \
+               _dl_exit(1);                                                    \
+       }
+-
+-
+-/*
+- * Transfer control to the user's application, once the dynamic loader
+- * is done.  This routine has to exit the current function, then
+- * call the _dl_elf_main function. For MIPS, we do it in assembly
+- * because the stack doesn't get properly restored otherwise. Got look
+- * at boot1_arch.h
+- */
+-#define START() return _dl_elf_main
+diff -urN uClibc-0.9.28.orig/ldso/ldso/mips/dl-syscalls.h uClibc-0.9.28/ldso/ldso/mips/dl-syscalls.h
+--- uClibc-0.9.28.orig/ldso/ldso/mips/dl-syscalls.h    2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/mips/dl-syscalls.h 2006-05-02 13:39:25.000000000 -0600
+@@ -1,7 +1,8 @@
+ /* We can't use the real errno in ldso, since it has not yet
+  * been dynamicly linked in yet. */
++#define __UCLIBC_MMAP_HAS_6_ARGS__
++
++#include "sys/syscall.h"
+ extern int _dl_errno;
++#undef __set_errno
+ #define __set_errno(X) {(_dl_errno) = (X);}
+-#include "sys/syscall.h"
+-
+-#define MMAP_HAS_6_ARGS
+diff -urN uClibc-0.9.28.orig/ldso/ldso/mips/dl-sysdep.h uClibc-0.9.28/ldso/ldso/mips/dl-sysdep.h
+--- uClibc-0.9.28.orig/ldso/ldso/mips/dl-sysdep.h      2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/mips/dl-sysdep.h   2006-04-28 00:14:35.000000000 -0600
+@@ -30,7 +30,7 @@
+ /* Initialization sequence for the application/library GOT.  */
+ #define INIT_GOT(GOT_BASE,MODULE)                                             \
+ do {                                                                          \
+-      unsigned long i;                                                        \
++      unsigned long idx;                                                      \
+                                                                               \
+       /* Check if this is the dynamic linker itself */                        \
+       if (MODULE->libtype == program_interpreter)                             \
+@@ -41,9 +41,9 @@
+       GOT_BASE[1] = (unsigned long) MODULE;                                   \
+                                                                               \
+       /* Add load address displacement to all local GOT entries */            \
+-      i = 2;                                                                  \
+-      while (i < MODULE->dynamic_info[DT_MIPS_LOCAL_GOTNO_IDX])               \
+-              GOT_BASE[i++] += (unsigned long) MODULE->loadaddr;              \
++      idx = 2;                                                                        \
++      while (idx < MODULE->dynamic_info[DT_MIPS_LOCAL_GOTNO_IDX])             \
++              GOT_BASE[idx++] += (unsigned long) MODULE->loadaddr;            \
+                                                                               \
+ } while (0)
+@@ -63,8 +63,6 @@
+ struct elf_resolve;
+ void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt, int lazy);
+-#define do_rem(result, n, base) ((result) = (n) % (base))
+-
+ /* 4096 bytes alignment */
+ #define PAGE_ALIGN 0xfffff000
+ #define ADDR_ALIGN 0xfff
+diff -urN uClibc-0.9.28.orig/ldso/ldso/mips/elfinterp.c uClibc-0.9.28/ldso/ldso/mips/elfinterp.c
+--- uClibc-0.9.28.orig/ldso/ldso/mips/elfinterp.c      2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/mips/elfinterp.c   2006-04-28 00:14:35.000000000 -0600
+@@ -27,6 +27,8 @@
+  * SUCH DAMAGE.
+  */
++#include "ldso.h"
++
+ extern int _dl_runtime_resolve(void);
+ #define OFFSET_GP_GOT 0x7ff0
+@@ -146,7 +148,6 @@
+                       break;
+               default:
+                       {
+-                              int reloc_type = ELF32_R_TYPE(rpnt->r_info);
+                               _dl_dprintf(2, "\n%s: ",_dl_progname);
+                               if (symtab_index)
+diff -urN uClibc-0.9.28.orig/ldso/ldso/powerpc/dl-startup.h uClibc-0.9.28/ldso/ldso/powerpc/dl-startup.h
+--- uClibc-0.9.28.orig/ldso/ldso/powerpc/dl-startup.h  2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/powerpc/dl-startup.h       2006-04-28 00:14:35.000000000 -0600
+@@ -42,8 +42,10 @@
+     " bne     2b\n"
+     " addi    6,6,4\n"
+ #endif
+-    /* Pass a termination function pointer (in this case _dl_fini) in r7.  */
+-    " lwz     7,_dl_fini@got(31)\n"
++    /* Pass a termination function pointer (in this case _dl_fini) in r3. */
++    /* Paulus promized he would keep r3 zero in the exec ABI. */
++    " lwz     3,_dl_fini@got(31)\n"
++    " mr      7,3\n"          /* Pass _dl_fini in r7 to maintain compat */
+     " bctr\n" /* Jump to entry point */
+     " .size   _start,.-_start\n"
+     " .previous\n"
+@@ -78,9 +80,3 @@
+               _dl_exit(100+ELF32_R_TYPE((RELP)->r_info));\
+       }                                               \
+       }
+-/*
+- * Transfer control to the user's application, once the dynamic loader
+- * is done.  This routine has to exit the current function, then
+- * call the _dl_elf_main function.
+- */
+-#define START()           return _dl_elf_main
+diff -urN uClibc-0.9.28.orig/ldso/ldso/powerpc/dl-syscalls.h uClibc-0.9.28/ldso/ldso/powerpc/dl-syscalls.h
+--- uClibc-0.9.28.orig/ldso/ldso/powerpc/dl-syscalls.h 2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/powerpc/dl-syscalls.h      2006-05-02 13:39:14.000000000 -0600
+@@ -1,251 +1,8 @@
+-/*
+- * This file contains the system call macros and syscall 
+- * numbers used by the shared library loader.
+- */
+-
+-#define MMAP_HAS_6_ARGS
+-
+-#define __NR_exit               1
+-#define __NR_read               3
+-#define __NR_write              4
+-#define __NR_open               5
+-#define __NR_close              6
+-#define __NR_getpid            20
+-#define __NR_getuid            24
+-#define __NR_geteuid           49
+-#define __NR_getgid            47
+-#define __NR_getegid           50
+-#define __NR_readlink          85
+-#define __NR_mmap              90
+-#define __NR_munmap            91
+-#define __NR_stat             106
+-#define __NR_mprotect         125
+-
+-
+ /* We can't use the real errno in ldso, since it has not yet
+  * been dynamicly linked in yet. */
+-extern int _dl_errno;
+-
+-/* Here are the macros which define how this platform makes
+- * system calls.  This particular variant does _not_ set 
+- * errno (note how it is disabled in __syscall_return) since
+- * these will get called before the errno symbol is dynamicly 
+- * linked. */
+-
+-#undef __syscall_return
+-#define __syscall_return(type) \
+-      return (__sc_err & 0x10000000 ? _dl_errno = __sc_ret, __sc_ret = -1 : 0), \
+-             (type) __sc_ret
+-
+-#undef __syscall_clobbers
+-#define __syscall_clobbers \
+-      "r9", "r10", "r11", "r12"
+-      //"r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"
+-
+-#undef _syscall0
+-#define _syscall0(type,name)                                          \
+-type name(void)                                                               \
+-{                                                                     \
+-      unsigned long __sc_ret, __sc_err;                               \
+-      {                                                               \
+-              register unsigned long __sc_0 __asm__ ("r0");           \
+-              register unsigned long __sc_3 __asm__ ("r3");           \
+-                                                                      \
+-              __sc_0 = __NR_##name;                                   \
+-              __asm__ __volatile__                                    \
+-                      ("sc           \n\t"                            \
+-                       "mfcr %1      "                                \
+-                      : "=&r" (__sc_3), "=&r" (__sc_0)                \
+-                      : "0"   (__sc_3), "1"   (__sc_0)                \
+-                      : "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12" ); \
+-              __sc_ret = __sc_3;                                      \
+-              __sc_err = __sc_0;                                      \
+-      }                                                               \
+-      __syscall_return (type);                                        \
+-}
+-
+-#undef _syscall1
+-#define _syscall1(type,name,type1,arg1)                                       \
+-type name(type1 arg1)                                                 \
+-{                                                                     \
+-      unsigned long __sc_ret, __sc_err;                               \
+-      {                                                               \
+-              register unsigned long __sc_0 __asm__ ("r0");           \
+-              register unsigned long __sc_3 __asm__ ("r3");           \
+-                                                                      \
+-              __sc_3 = (unsigned long) (arg1);                        \
+-              __sc_0 = __NR_##name;                                   \
+-              __asm__ __volatile__                                    \
+-                      ("sc           \n\t"                            \
+-                       "mfcr %1      "                                \
+-                      : "=&r" (__sc_3), "=&r" (__sc_0)                \
+-                      : "0"   (__sc_3), "1"   (__sc_0)                \
+-                      : "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12" ); \
+-              __sc_ret = __sc_3;                                      \
+-              __sc_err = __sc_0;                                      \
+-      }                                                               \
+-      __syscall_return (type);                                        \
+-}
+-
+-#undef _syscall2
+-#define _syscall2(type,name,type1,arg1,type2,arg2)                    \
+-type name(type1 arg1, type2 arg2)                                     \
+-{                                                                     \
+-      unsigned long __sc_ret, __sc_err;                               \
+-      {                                                               \
+-              register unsigned long __sc_0 __asm__ ("r0");           \
+-              register unsigned long __sc_3 __asm__ ("r3");           \
+-              register unsigned long __sc_4 __asm__ ("r4");           \
+-                                                                      \
+-              __sc_3 = (unsigned long) (arg1);                        \
+-              __sc_4 = (unsigned long) (arg2);                        \
+-              __sc_0 = __NR_##name;                                   \
+-              __asm__ __volatile__                                    \
+-                      ("sc           \n\t"                            \
+-                       "mfcr %1      "                                \
+-                      : "=&r" (__sc_3), "=&r" (__sc_0)                \
+-                      : "0"   (__sc_3), "1"   (__sc_0),               \
+-                        "r"   (__sc_4)                                \
+-                      : "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12" ); \
+-              __sc_ret = __sc_3;                                      \
+-              __sc_err = __sc_0;                                      \
+-      }                                                               \
+-      __syscall_return (type);                                        \
+-}
+-
+-#undef _syscall3
+-#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)         \
+-type name(type1 arg1, type2 arg2, type3 arg3)                         \
+-{                                                                     \
+-      unsigned long __sc_ret, __sc_err;                               \
+-      {                                                               \
+-              register unsigned long __sc_0 __asm__ ("r0");           \
+-              register unsigned long __sc_3 __asm__ ("r3");           \
+-              register unsigned long __sc_4 __asm__ ("r4");           \
+-              register unsigned long __sc_5 __asm__ ("r5");           \
+-                                                                      \
+-              __sc_3 = (unsigned long) (arg1);                        \
+-              __sc_4 = (unsigned long) (arg2);                        \
+-              __sc_5 = (unsigned long) (arg3);                        \
+-              __sc_0 = __NR_##name;                                   \
+-              __asm__ __volatile__                                    \
+-                      ("sc           \n\t"                            \
+-                       "mfcr %1      "                                \
+-                      : "=&r" (__sc_3), "=&r" (__sc_0)                \
+-                      : "0"   (__sc_3), "1"   (__sc_0),               \
+-                        "r"   (__sc_4),                               \
+-                        "r"   (__sc_5)                                \
+-                      : "r6", "r7", "r8", "r9", "r10", "r11", "r12" ); \
+-              __sc_ret = __sc_3;                                      \
+-              __sc_err = __sc_0;                                      \
+-      }                                                               \
+-      __syscall_return (type);                                        \
+-}
+-
+-#undef _syscall4
+-#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
+-type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4)             \
+-{                                                                     \
+-      unsigned long __sc_ret, __sc_err;                               \
+-      {                                                               \
+-              register unsigned long __sc_0 __asm__ ("r0");           \
+-              register unsigned long __sc_3 __asm__ ("r3");           \
+-              register unsigned long __sc_4 __asm__ ("r4");           \
+-              register unsigned long __sc_5 __asm__ ("r5");           \
+-              register unsigned long __sc_6 __asm__ ("r6");           \
+-                                                                      \
+-              __sc_3 = (unsigned long) (arg1);                        \
+-              __sc_4 = (unsigned long) (arg2);                        \
+-              __sc_5 = (unsigned long) (arg3);                        \
+-              __sc_6 = (unsigned long) (arg4);                        \
+-              __sc_0 = __NR_##name;                                   \
+-              __asm__ __volatile__                                    \
+-                      ("sc           \n\t"                            \
+-                       "mfcr %1      "                                \
+-                      : "=&r" (__sc_3), "=&r" (__sc_0)                \
+-                      : "0"   (__sc_3), "1"   (__sc_0),               \
+-                        "r"   (__sc_4),                               \
+-                        "r"   (__sc_5),                               \
+-                        "r"   (__sc_6)                                \
+-                      : "r7", "r8", "r9", "r10", "r11", "r12" );      \
+-              __sc_ret = __sc_3;                                      \
+-              __sc_err = __sc_0;                                      \
+-      }                                                               \
+-      __syscall_return (type);                                        \
+-}
+-
+-#undef _syscall5
+-#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
+-type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \
+-{                                                                     \
+-      unsigned long __sc_ret, __sc_err;                               \
+-      {                                                               \
+-              register unsigned long __sc_0 __asm__ ("r0");           \
+-              register unsigned long __sc_3 __asm__ ("r3");           \
+-              register unsigned long __sc_4 __asm__ ("r4");           \
+-              register unsigned long __sc_5 __asm__ ("r5");           \
+-              register unsigned long __sc_6 __asm__ ("r6");           \
+-              register unsigned long __sc_7 __asm__ ("r7");           \
+-                                                                      \
+-              __sc_3 = (unsigned long) (arg1);                        \
+-              __sc_4 = (unsigned long) (arg2);                        \
+-              __sc_5 = (unsigned long) (arg3);                        \
+-              __sc_6 = (unsigned long) (arg4);                        \
+-              __sc_7 = (unsigned long) (arg5);                        \
+-              __sc_0 = __NR_##name;                                   \
+-              __asm__ __volatile__                                    \
+-                      ("sc           \n\t"                            \
+-                       "mfcr %1      "                                \
+-                      : "=&r" (__sc_3), "=&r" (__sc_0)                \
+-                      : "0"   (__sc_3), "1"   (__sc_0),               \
+-                        "r"   (__sc_4),                               \
+-                        "r"   (__sc_5),                               \
+-                        "r"   (__sc_6),                               \
+-                        "r"   (__sc_7)                                \
+-                      : "r8", "r9", "r10", "r11", "r12" );            \
+-              __sc_ret = __sc_3;                                      \
+-              __sc_err = __sc_0;                                      \
+-      }                                                               \
+-      __syscall_return (type);                                        \
+-}
+-
+-
+-#undef _syscall6
+-#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \
+-type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6)     \
+-{                                                                     \
+-      unsigned long __sc_ret, __sc_err;                               \
+-      {                                                               \
+-              register unsigned long __sc_0 __asm__ ("r0");           \
+-              register unsigned long __sc_3 __asm__ ("r3");           \
+-              register unsigned long __sc_4 __asm__ ("r4");           \
+-              register unsigned long __sc_5 __asm__ ("r5");           \
+-              register unsigned long __sc_6 __asm__ ("r6");           \
+-              register unsigned long __sc_7 __asm__ ("r7");           \
+-              register unsigned long __sc_8 __asm__ ("r8");           \
+-                                                                      \
+-              __sc_3 = (unsigned long) (arg1);                        \
+-              __sc_4 = (unsigned long) (arg2);                        \
+-              __sc_5 = (unsigned long) (arg3);                        \
+-              __sc_6 = (unsigned long) (arg4);                        \
+-              __sc_7 = (unsigned long) (arg5);                        \
+-              __sc_8 = (unsigned long) (arg6);                        \
+-              __sc_0 = __NR_##name;                                   \
+-              __asm__ __volatile__                                    \
+-                      ("sc           \n\t"                            \
+-                       "mfcr %1      "                                \
+-                      : "=&r" (__sc_3), "=&r" (__sc_0)                \
+-                      : "0"   (__sc_3), "1"   (__sc_0),               \
+-                        "r"   (__sc_4),                               \
+-                        "r"   (__sc_5),                               \
+-                        "r"   (__sc_6),                               \
+-                        "r"   (__sc_7),                               \
+-                        "r"   (__sc_8)                                \
+-                      : "r9", "r10", "r11", "r12" );                  \
+-              __sc_ret = __sc_3;                                      \
+-              __sc_err = __sc_0;                                      \
+-      }                                                               \
+-      __syscall_return (type);                                        \
+-}
+-
++#define __UCLIBC_MMAP_HAS_6_ARGS__
++#include "sys/syscall.h"
++extern int _dl_errno;
++#undef __set_errno
++#define __set_errno(X) {(_dl_errno) = (X);}
+diff -urN uClibc-0.9.28.orig/ldso/ldso/powerpc/dl-sysdep.h uClibc-0.9.28/ldso/ldso/powerpc/dl-sysdep.h
+--- uClibc-0.9.28.orig/ldso/ldso/powerpc/dl-sysdep.h   2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/powerpc/dl-sysdep.h        2006-04-28 00:14:35.000000000 -0600
+@@ -67,9 +67,6 @@
+ extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
+ void _dl_init_got(unsigned long *lpnt,struct elf_resolve *tpnt);
+-
+-#define do_rem(result, n, base) ((result) = (n) % (base))
+-
+ /* 4096 bytes alignment */
+ #define PAGE_ALIGN 0xfffff000
+ #define ADDR_ALIGN 0xfff
+diff -urN uClibc-0.9.28.orig/ldso/ldso/powerpc/elfinterp.c uClibc-0.9.28/ldso/ldso/powerpc/elfinterp.c
+--- uClibc-0.9.28.orig/ldso/ldso/powerpc/elfinterp.c   2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/powerpc/elfinterp.c        2006-04-28 00:14:35.000000000 -0600
+@@ -29,6 +29,8 @@
+  * SUCH DAMAGE.
+  */
++#include "ldso.h"
++
+ extern int _dl_linux_resolve(void);
+ void _dl_init_got(unsigned long *plt,struct elf_resolve *tpnt)
+@@ -138,7 +140,7 @@
+       finaladdr = (Elf32_Addr) _dl_find_hash(symname,
+                       tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT);
+       if (unlikely(!finaladdr)) {
+-              _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname);
++              _dl_dprintf(2, "%s: can't resolve symbol '%s' in lib '%s'.\n", _dl_progname, symname, tpnt->libname);
+               _dl_exit(1);
+       };
+       finaladdr += this_reloc->r_addend;
+@@ -379,15 +381,15 @@
+               {
+                       int reloc_type = ELF32_R_TYPE(rpnt->r_info);
+ #if defined (__SUPPORT_LD_DEBUG__)
+-                      _dl_dprintf(2, "can't handle reloc type %s\n ", _dl_reltypes(reloc_type));
++                      _dl_dprintf(2, "can't handle reloc type '%s' in lib '%s'\n", _dl_reltypes(reloc_type), tpnt->libname);
+ #else
+-                      _dl_dprintf(2, "can't handle reloc type %x\n", reloc_type);
++                      _dl_dprintf(2, "can't handle reloc type %x in lib '%s'\n", reloc_type, tpnt->libname);
+ #endif
+-                      _dl_exit(-res);
++                      return res;
+               }
+               if (unlikely(res >0))
+               {
+-                      _dl_dprintf(2, "can't resolve symbol\n");
++                      _dl_dprintf(2, "can't resolve symbol in lib '%s'.\n", tpnt->libname);
+                       return res;
+               }
+         }
+diff -urN uClibc-0.9.28.orig/ldso/ldso/sh/dl-startup.h uClibc-0.9.28/ldso/ldso/sh/dl-startup.h
+--- uClibc-0.9.28.orig/ldso/ldso/sh/dl-startup.h       2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/sh/dl-startup.h    2006-04-28 00:14:35.000000000 -0600
+@@ -55,11 +55,3 @@
+       default:                                                \
+               _dl_exit(1);                                    \
+       }
+-
+-
+-/*
+- * Transfer control to the user's application, once the dynamic loader
+- * is done.  This routine has to exit the current function, then
+- * call the _dl_elf_main function.
+- */
+-#define START()   return _dl_elf_main;
+diff -urN uClibc-0.9.28.orig/ldso/ldso/sh/dl-syscalls.h uClibc-0.9.28/ldso/ldso/sh/dl-syscalls.h
+--- uClibc-0.9.28.orig/ldso/ldso/sh/dl-syscalls.h      2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/sh/dl-syscalls.h   2006-05-02 13:39:28.000000000 -0600
+@@ -1,7 +1,8 @@
+ /* We can't use the real errno in ldso, since it has not yet
+  * been dynamicly linked in yet. */
++#define __UCLIBC_MMAP_HAS_6_ARGS__
++
++#include "sys/syscall.h"
+ extern int _dl_errno;
++#undef __set_errno
+ #define __set_errno(X) {(_dl_errno) = (X);}
+-#include "sys/syscall.h"
+-
+-#define MMAP_HAS_6_ARGS
+diff -urN uClibc-0.9.28.orig/ldso/ldso/sh/dl-sysdep.h uClibc-0.9.28/ldso/ldso/sh/dl-sysdep.h
+--- uClibc-0.9.28.orig/ldso/ldso/sh/dl-sysdep.h        2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/sh/dl-sysdep.h     2006-04-28 00:14:35.000000000 -0600
+@@ -25,7 +25,7 @@
+ struct elf_resolve;
+ extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
+-static __inline__ unsigned int
++static inline unsigned int
+ _dl_urem(unsigned int n, unsigned int base)
+ {
+   int res;
+@@ -104,7 +104,7 @@
+ elf_machine_dynamic (void)
+ {
+       register Elf32_Addr *got;
+-      asm ("mov r12,%0" :"=r" (got));
++      __asm__ ("mov r12,%0" :"=r" (got));
+       return *got;
+ }
+@@ -113,7 +113,7 @@
+ elf_machine_load_address (void)
+ {
+       Elf32_Addr addr;
+-      asm ("mov.l 1f,r0\n\
++      __asm__ ("mov.l 1f,r0\n\
+         mov.l 3f,r2\n\
+         add r12,r2\n\
+         mov.l @(r0,r12),r0\n\
+diff -urN uClibc-0.9.28.orig/ldso/ldso/sh/elfinterp.c uClibc-0.9.28/ldso/ldso/sh/elfinterp.c
+--- uClibc-0.9.28.orig/ldso/ldso/sh/elfinterp.c        2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/sh/elfinterp.c     2006-04-28 00:14:35.000000000 -0600
+@@ -39,6 +39,8 @@
+    a more than adequate job of explaining everything required to get this
+    working. */
++#include "ldso.h"
++
+ extern int _dl_linux_resolve(void);
+ unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
+diff -urN uClibc-0.9.28.orig/ldso/ldso/sh64/dl-startup.h uClibc-0.9.28/ldso/ldso/sh64/dl-startup.h
+--- uClibc-0.9.28.orig/ldso/ldso/sh64/dl-startup.h     2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/sh64/dl-startup.h  2006-04-28 00:14:35.000000000 -0600
+@@ -115,12 +115,3 @@
+       default:                                                        \
+               _dl_exit(1);                                            \
+       }
+-
+-/*
+- * Transfer control to the user's application, once the dynamic loader
+- * is done.  This routine has to exit the current function, then
+- * call the _dl_elf_main function.
+- */
+-
+-#define START()   return _dl_elf_main;
+-
+diff -urN uClibc-0.9.28.orig/ldso/ldso/sh64/dl-syscalls.h uClibc-0.9.28/ldso/ldso/sh64/dl-syscalls.h
+--- uClibc-0.9.28.orig/ldso/ldso/sh64/dl-syscalls.h    2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/sh64/dl-syscalls.h 2006-04-28 00:14:35.000000000 -0600
+@@ -1,8 +1,9 @@
+ /* We can't use the real errno in ldso, since it has not yet
+  * been dynamicly linked in yet. */
++#include "sys/syscall.h"
+ extern int _dl_errno;
++#undef __set_errno
+ #define __set_errno(X) {(_dl_errno) = (X);}
+-#include "sys/syscall.h"
+ #undef __syscall_return
+ #define __syscall_return(type, res)                                   \
+diff -urN uClibc-0.9.28.orig/ldso/ldso/sh64/dl-sysdep.h uClibc-0.9.28/ldso/ldso/sh64/dl-sysdep.h
+--- uClibc-0.9.28.orig/ldso/ldso/sh64/dl-sysdep.h      2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/sh64/dl-sysdep.h   2006-04-28 00:14:35.000000000 -0600
+@@ -25,8 +25,6 @@
+ struct elf_resolve;
+ extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
+-#define do_rem(result, n, base) ((result) = (n) % (base))
+-
+ /* 4096 bytes alignment */
+ #define PAGE_ALIGN 0xfffff000
+ #define ADDR_ALIGN 0xfff
+diff -urN uClibc-0.9.28.orig/ldso/ldso/sh64/elfinterp.c uClibc-0.9.28/ldso/ldso/sh64/elfinterp.c
+--- uClibc-0.9.28.orig/ldso/ldso/sh64/elfinterp.c      2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/sh64/elfinterp.c   2006-04-28 00:14:35.000000000 -0600
+@@ -41,6 +41,8 @@
+    a more than adequate job of explaining everything required to get this
+    working. */
++#include "ldso.h"
++
+ extern int _dl_linux_resolve(void);
+ unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
+diff -urN uClibc-0.9.28.orig/ldso/ldso/sparc/dl-startup.h uClibc-0.9.28/ldso/ldso/sparc/dl-startup.h
+--- uClibc-0.9.28.orig/ldso/ldso/sparc/dl-startup.h    2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/sparc/dl-startup.h 2006-04-28 00:14:35.000000000 -0600
+@@ -3,15 +3,46 @@
+  * needed for this architecture.  See arm/boot1_arch.h for an example of what
+  * can be done.
+  */
+-asm(
+-      "       .text\n"
+-      "       .global _start\n"
+-      "       .type   _start,%function\n"
+-      "_start:\n"
+-      "       .set _start,_dl_start\n"
+-      "       .size _start,.-_start\n"
+-      "       .previous\n"
+-);
++
++asm ("\
++      .text\n\
++      .global _start\n\
++      .type   _start,%function\n\
++      .align 32\n\
++_start:\n\
++      /* Allocate space for functions to drop their arguments. */\n\
++      sub     %sp, 6*4, %sp\n\
++      /* Pass pointer to argument block to _dl_start. */\n\
++      call _dl_start\n\
++      add    %sp, 22*4, %o0\n\
++      /* FALTHRU */\n\
++      .globl  _dl_start_user\n\
++      .type   _dl_start_user, @function\n\
++_dl_start_user:\n\
++  /* Load the PIC register.  */\n\
++1:    call    2f\n\
++      sethi  %hi(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7\n\
++2:    or  %l7, %lo(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7\n\
++      add %l7, %o7, %l7\n\
++  /* Save the user entry point address in %l0 */\n\
++      mov %o0, %l0\n\
++  /* See if we were run as a command with the executable file name as an\n\
++       extra leading argument.  If so, adjust the contents of the stack.  */\n\
++      sethi   %hi(_dl_skip_args), %g2\n\
++      or  %g2, %lo(_dl_skip_args), %g2\n\
++      ld  [%l7+%g2], %i0\n\
++      ld  [%i0], %i0\n\
++      tst %i0\n\
++  /* Pass our finalizer function to the user in %g1.  */\n\
++      sethi   %hi(_dl_fini), %g1\n\
++      or      %g1, %lo(_dl_fini), %g1\n\
++      ld      [%l7+%g1], %g1\n\
++  /* Jump to the user's entry point and deallocate the extra stack we got.  */\n\
++      jmp %l0\n\
++       add    %sp, 6*4, %sp\n\
++      .size   _dl_start_user, . - _dl_start_user\n\
++      .previous\n\
++");
+ /*
+  * Get a pointer to the argv array.  On many platforms this can be just
+@@ -19,17 +50,15 @@
+  * do something a little more subtle here.  We assume that argc is stored
+  * at the word just below the argvp that we return here.
+  */
+-#define GET_ARGV(ARGVP, ARGS) __asm__("\tadd %%fp,68,%0\n" : "=r" (ARGVP));
++#define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long *) ARGS) + 1)
+ /*
+  * Here is a macro to perform a relocation.  This is only used when
+  * bootstrapping the dynamic loader.
+  */
+ #define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD,SYMTAB) \
+-      switch(ELF32_R_TYPE((RELP)->r_info)) { \
++switch(ELF_R_TYPE((RELP)->r_info)) { \
+       case R_SPARC_32: \
+-              *REL = SYMBOL + (RELP)->r_addend; \
+-              break; \
+       case R_SPARC_GLOB_DAT: \
+               *REL = SYMBOL + (RELP)->r_addend; \
+               break; \
+@@ -38,7 +67,6 @@
+               REL[2] = 0x81c06000 | (SYMBOL & 0x3ff); \
+               break; \
+       case R_SPARC_NONE: \
+-              break; \
+       case R_SPARC_WDISP30: \
+               break; \
+       case R_SPARC_RELATIVE: \
+@@ -46,18 +74,4 @@
+               break; \
+       default: \
+               _dl_exit(1); \
+-      }
+-
+-/*
+- * Transfer control to the user's application, once the dynamic loader
+- * is done.  The crt calls atexit with $g1 if not null, so we need to
+- * ensure that it contains NULL.
+- */
+-
+-#define START() \
+-      __asm__ volatile ( \
+-              "add %%g0,%%g0,%%g1\n\t" \
+-              "jmpl %0, %%o7\n\t"     \
+-              "restore %%g0,%%g0,%%g0\n\t" \
+-              : /*"=r" (status) */ : \
+-              "r" (_dl_elf_main): "g1", "o0", "o1")
++}
+diff -urN uClibc-0.9.28.orig/ldso/ldso/sparc/dl-syscalls.h uClibc-0.9.28/ldso/ldso/sparc/dl-syscalls.h
+--- uClibc-0.9.28.orig/ldso/ldso/sparc/dl-syscalls.h   2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/sparc/dl-syscalls.h        2006-05-02 13:39:21.000000000 -0600
+@@ -1,187 +1,8 @@
+-/*
+- * This file contains the system call macros and syscall 
+- * numbers used by the shared library loader.
+- *
+- * NOTE: This should be integrated/moved to 
+- *       sysdeps/linux/sparc/bits/syscalls.h at some point ...
+- */
+-
+-#define MMAP_HAS_6_ARGS
+-
+-#define __NR_exit               1
+-#define __NR_read               3
+-#define __NR_write              4
+-#define __NR_open               5
+-#define __NR_close              6
+-#define __NR_getpid            20
+-#define __NR_getuid            24
+-#define __NR_getgid            47
+-#define __NR_geteuid           49
+-#define __NR_getegid           50
+-#define __NR_readlink          58
+-#define __NR_mmap              71
+-#define __NR_munmap            73
+-#define __NR_stat              38
+-#define __NR_mprotect          74
+-
+ /* We can't use the real errno in ldso, since it has not yet
+  * been dynamicly linked in yet. */
++#define __UCLIBC_MMAP_HAS_6_ARGS__
++
++#include "sys/syscall.h"
+ extern int _dl_errno;
++#undef __set_errno
+ #define __set_errno(X) {(_dl_errno) = (X);}
+-
+-/* Here are the macros which define how this platform makes
+- * system calls.  This particular variant does _not_ set 
+- * errno (note how _dl_errno is used in __syscall_return) since
+- * these will get called before the errno symbol is dynamicly 
+- * linked. */
+-
+-#define __syscall_return(type, res) \
+-do { \
+-      if (res < -255 || res >= 0) \
+-              return (type) res; \
+-      __set_errno(-res); \
+-      res = -1; \
+-      return (type) res; \
+-} while (0)
+-
+-#define _syscall0(type,name) \
+-type name(void) \
+-{ \
+-      long __res; \
+-      register long __g1 __asm__ ("g1") = __NR_##name; \
+-      __asm__ __volatile__ ( \
+-              "t 0x10\n\t" \
+-              "bcc 1f\n\t" \
+-              "mov %%o0, %0\n\t" \
+-              "sub %%g0, %%o0, %0\n\t" \
+-              "1:\n\t" \
+-              : "=r" (__res)\
+-              : "r" (__g1) \
+-              : "o0", "cc"); \
+-      __syscall_return(type, __res); \
+-}
+-
+-#define _syscall1(type,name,type1,arg1) \
+-type name(type1 arg1) \
+-{ \
+-      long __res; \
+-      register long __g1 __asm__ ("g1") = __NR_##name; \
+-      register long __o0 __asm__ ("o0") = (long)(arg1); \
+-      __asm__ __volatile__ ( \
+-              "t 0x10\n\t" \
+-              "bcc 1f\n\t" \
+-              "mov %%o0, %0\n\t" \
+-              "sub %%g0, %%o0, %0\n\t" \
+-              "1:\n\t" \
+-              : "=r" (__res), "=&r" (__o0) \
+-              : "1" (__o0), "r" (__g1) \
+-              : "cc"); \
+-      __syscall_return(type, __res); \
+-}
+-
+-#define _syscall2(type,name,type1,arg1,type2,arg2) \
+-type name(type1 arg1,type2 arg2) \
+-{ \
+-      long __res; \
+-      register long __g1 __asm__ ("g1") = __NR_##name; \
+-      register long __o0 __asm__ ("o0") = (long)(arg1); \
+-      register long __o1 __asm__ ("o1") = (long)(arg2); \
+-      __asm__ __volatile__ ( \
+-              "t 0x10\n\t" \
+-              "bcc 1f\n\t" \
+-              "mov %%o0, %0\n\t" \
+-              "sub %%g0, %%o0, %0\n\t" \
+-              "1:\n\t" \
+-              : "=r" (__res), "=&r" (__o0) \
+-              : "1" (__o0), "r" (__o1), "r" (__g1) \
+-              : "cc"); \
+-      __syscall_return(type, __res); \
+-}
+-
+-#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
+-type name(type1 arg1,type2 arg2,type3 arg3) \
+-{ \
+-      long __res; \
+-      register long __g1 __asm__ ("g1") = __NR_##name; \
+-      register long __o0 __asm__ ("o0") = (long)(arg1); \
+-      register long __o1 __asm__ ("o1") = (long)(arg2); \
+-      register long __o2 __asm__ ("o2") = (long)(arg3); \
+-      __asm__ __volatile__ ( \
+-              "t 0x10\n\t" \
+-              "bcc 1f\n\t" \
+-              "mov %%o0, %0\n\t" \
+-              "sub %%g0, %%o0, %0\n\t" \
+-              "1:\n\t" \
+-              : "=r" (__res), "=&r" (__o0) \
+-              : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1) \
+-              : "cc"); \
+-      __syscall_return(type, __res); \
+-}
+-
+-#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
+-type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
+-{ \
+-      long __res; \
+-      register long __g1 __asm__ ("g1") = __NR_##name; \
+-      register long __o0 __asm__ ("o0") = (long)(arg1); \
+-      register long __o1 __asm__ ("o1") = (long)(arg2); \
+-      register long __o2 __asm__ ("o2") = (long)(arg3); \
+-      register long __o3 __asm__ ("o3") = (long)(arg4); \
+-      __asm__ __volatile__ ( \
+-              "t 0x10\n\t" \
+-              "bcc 1f\n\t" \
+-              "mov %%o0, %0\n\t" \
+-              "sub %%g0, %%o0, %0\n\t" \
+-              "1:\n\t" \
+-              : "=r" (__res), "=&r" (__o0) \
+-              : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__g1) \
+-              : "cc"); \
+-      __syscall_return(type, __res); \
+-} 
+-
+-#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+-        type5,arg5) \
+-type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
+-{ \
+-      long __res; \
+-      register long __g1 __asm__ ("g1") = __NR_##name; \
+-      register long __o0 __asm__ ("o0") = (long)(arg1); \
+-      register long __o1 __asm__ ("o1") = (long)(arg2); \
+-      register long __o2 __asm__ ("o2") = (long)(arg3); \
+-      register long __o3 __asm__ ("o3") = (long)(arg4); \
+-      register long __o4 __asm__ ("o4") = (long)(arg5); \
+-      __asm__ __volatile__ ( \
+-              "t 0x10\n\t" \
+-              "bcc 1f\n\t" \
+-              "mov %%o0, %0\n\t" \
+-              "sub %%g0, %%o0, %0\n\t" \
+-              "1:\n\t" \
+-              : "=r" (__res), "=&r" (__o0) \
+-              : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__o4), "r" (__g1) \
+-              : "cc"); \
+-      __syscall_return(type, __res); \
+-}
+-
+-#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+-        type5,arg5,type6,arg6) \
+-type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \
+-{ \
+-      long __res; \
+-      register long __g1 __asm__ ("g1") = __NR_##name; \
+-      register long __o0 __asm__ ("o0") = (long)(arg1); \
+-      register long __o1 __asm__ ("o1") = (long)(arg2); \
+-      register long __o2 __asm__ ("o2") = (long)(arg3); \
+-      register long __o3 __asm__ ("o3") = (long)(arg4); \
+-      register long __o4 __asm__ ("o4") = (long)(arg5); \
+-      register long __o5 __asm__ ("o5") = (long)(arg6); \
+-      __asm__ __volatile__ ( \
+-              "t 0x10\n\t" \
+-              "bcc 1f\n\t" \
+-              "mov %%o0, %0\n\t" \
+-              "sub %%g0, %%o0, %0\n\t" \
+-              "1:\n\t" \
+-              : "=r" (__res), "=&r" (__o0) \
+-              : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__o4), "r" (__o5), "r" (__g1) \
+-              : "cc"); \
+-      __syscall_return(type, __res); \
+-}
+diff -urN uClibc-0.9.28.orig/ldso/ldso/sparc/dl-sysdep.h uClibc-0.9.28/ldso/ldso/sparc/dl-sysdep.h
+--- uClibc-0.9.28.orig/ldso/ldso/sparc/dl-sysdep.h     2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/sparc/dl-sysdep.h  2006-04-28 00:14:35.000000000 -0600
+@@ -1,9 +1,9 @@
+-
++/* vi: set sw=4 ts=4: */
+ /*
+  * Various assmbly language/system dependent  hacks that are required
+  * so that we can minimize the amount of platform specific code.
++ * Copyright (C) 2000-2004 by Erik Andersen <andersen@codepoet.org>
+  */
+-#define LINUXBIN
+ /* Define this if the system uses RELOCA.  */
+ #define ELF_USES_RELOCA
+@@ -31,19 +31,14 @@
+ #undef  MAGIC2
+ /* Used for error messages */
+-#define ELF_TARGET "Sparc"
++#define ELF_TARGET "sparc"
+-#ifndef COMPILE_ASM
+-extern unsigned int _dl_linux_resolver(unsigned int reloc_entry,
+-                                      unsigned int * i);
+-#endif
++struct elf_resolve;
++unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
+ /*
+  * Define this if you want a dynamic loader that works on Solaris.
+  */
+-#ifndef __linux__
+-#define SOLARIS_COMPATIBLE
+-#endif
+ #ifndef COMPILE_ASM
+ /* Cheap modulo implementation, taken from arm/ld_sysdep.h. */
+@@ -87,13 +82,6 @@
+ #define do_rem(result, n, base) ((result) = sparc_mod(n, base))
+ #endif
+-/*
+- * dbx wants the binder to have a specific name.  Mustn't disappoint it.
+- */
+-#ifdef SOLARIS_COMPATIBLE
+-#define _dl_linux_resolve _elf_rtbndr
+-#endif
+-
+ /* 4096 bytes alignment */
+ /* ...but 8192 is required for mmap() on sparc64 kernel */
+ #define PAGE_ALIGN 0xffffe000
+@@ -160,7 +148,7 @@
+ elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr,
+                     Elf32_Word relative_count)
+ {
+-       Elf32_Rela * rpnt = (void *)rel_addr;
++      Elf32_Rela * rpnt = (void *)rel_addr;
+       --rpnt;
+       do {
+               Elf32_Addr *const reloc_addr = (void *) (load_off + (++rpnt)->r_offset);
+diff -urN uClibc-0.9.28.orig/ldso/ldso/sparc/elfinterp.c uClibc-0.9.28/ldso/ldso/sparc/elfinterp.c
+--- uClibc-0.9.28.orig/ldso/ldso/sparc/elfinterp.c     2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/sparc/elfinterp.c  2006-04-28 00:14:35.000000000 -0600
+@@ -33,236 +33,340 @@
+ an ELF sharable library or a linux style of shared library. */
+ /* Disclaimer:  I have never seen any AT&T source code for SVr4, nor have
+-   I ever taken any courses on internals.  This program was developed using
+-   information available through the book "UNIX SYSTEM V RELEASE 4,
+-   Programmers guide: Ansi C and Programming Support Tools", which did
+-   a more than adequate job of explaining everything required to get this
+-   working. */
++       I ever taken any courses on internals.  This program was developed using
++       information available through the book "UNIX SYSTEM V RELEASE 4,
++       Programmers guide: Ansi C and Programming Support Tools", which did
++       a more than adequate job of explaining everything required to get this
++       working. */
++
++/* Some SPARC opcodes we need to use for self-modifying code.  */
++#define OPCODE_NOP    0x01000000 /* nop */
++#define OPCODE_CALL   0x40000000 /* call ?; add PC-rel word address */
++#define OPCODE_SETHI_G1       0x03000000 /* sethi ?, %g1; add value>>10 */
++#define OPCODE_JMP_G1 0x81c06000 /* jmp %g1+?; add lo 10 bits of value */
++#define OPCODE_SAVE_SP        0x9de3bfa8 /* save %sp, -(16+6)*4, %sp */
++#define OPCODE_BA     0x30800000 /* b,a ?; add PC-rel word address */
+ extern int _dl_linux_resolve(void);
+-unsigned int _dl_linux_resolver(unsigned int reloc_entry, unsigned int * plt)
++unsigned long
++_dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
+ {
+-  int reloc_type;
+-  Elf32_Rela * this_reloc;
+-  char * strtab;
+-  Elf32_Sym * symtab;
+-  Elf32_Rela * rel_addr;
+-  struct elf_resolve * tpnt;
+-  int symtab_index;
+-  char * new_addr;
+-  char ** got_addr;
+-  unsigned int instr_addr;
+-  tpnt = (struct elf_resolve *) plt[2];
+-
+-  rel_addr = (Elf32_Rela *)tpnt->dynamic_info[DT_JMPREL];
+-
+-  /*
+-   * Generate the correct relocation index into the .rela.plt section.
+-   */
+-  reloc_entry = (reloc_entry >> 10) - 0xc;
+-
+-  this_reloc = (Elf32_Rela *) ((char *) rel_addr + reloc_entry);
+-
+-  reloc_type = ELF32_R_TYPE(this_reloc->r_info);
+-  symtab_index = ELF32_R_SYM(this_reloc->r_info);
+-
+-  symtab =  (Elf32_Sym *)tpnt->dynamic_info[DT_SYMTAB];
+-  strtab = (char *)tpnt->dynamic_info[DT_STRTAB];
+-
+-#ifdef __SUPPORT_LD_DEBUG__
+-  if (_dl_debug_symbols) {
+-  _dl_dprintf(2, "tpnt = %x\n", tpnt);
+-  _dl_dprintf(2, "reloc = %x\n", this_reloc);
+-  _dl_dprintf(2, "symtab = %x\n", symtab);
+-  _dl_dprintf(2, "strtab = %x\n", strtab);
+-  }
+-#endif
+-
+-
+-  if (unlikely(reloc_type != R_SPARC_JMP_SLOT)) {
+-    _dl_dprintf(2, "%s: incorrect relocation type in jump relocations (%d)\n",
+-                _dl_progname, reloc_type);
+-    _dl_exit(30);
+-  };
+-
+-  /* Address of jump instruction to fix up */
+-  instr_addr  = ((int)this_reloc->r_offset  + (int)tpnt->loadaddr);
+-  got_addr = (char **) instr_addr;
+-
+-#ifdef __SUPPORT_LD_DEBUG__
+-  if (_dl_debug_symbols) {
+-  _dl_dprintf(2, "symtab_index %x\n", symtab_index);
+-
+-        _dl_dprintf(2, "Resolving symbol %s\n",
+-                        strtab + symtab[symtab_index].st_name);
+-  }
+-#endif
+-
+-  /* Get the address of the GOT entry */
+-  new_addr = _dl_find_hash(strtab + symtab[symtab_index].st_name,
+-                      tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT);
+-  if(unlikely(!new_addr)) {
+-    _dl_dprintf(2, "%s: can't resolve symbol '%s'\n",
+-             _dl_progname, strtab + symtab[symtab_index].st_name);
+-    _dl_exit(31);
+-  };
++      int reloc_type;
++      ELF_RELOC *this_reloc;
++      char *strtab;
++      ElfW(Sym) *symtab;
++      int symtab_index;
++      char *rel_addr;
++      char *new_addr;
++      char **got_addr;
++      ElfW(Addr) instr_addr;
++      char *symname;
++
++      rel_addr = (char *)tpnt->dynamic_info[DT_JMPREL];
++      /*
++       * Generate the correct relocation index into the .rela.plt section.
++       */
++      reloc_entry = (reloc_entry >> 10) - 0xc;
++
++      this_reloc = (ELF_RELOC *)(rel_addr + reloc_entry);
++      reloc_type = ELF_R_TYPE(this_reloc->r_info);
++      symtab_index = ELF_R_SYM(this_reloc->r_info);
++
++      symtab = (ElfW(Sym) *)tpnt->dynamic_info[DT_SYMTAB];
++      strtab = (char *)tpnt->dynamic_info[DT_STRTAB];
++      symname = strtab + symtab[symtab_index].st_name;
++
++      if (unlikely(reloc_type != R_SPARC_JMP_SLOT)) {
++              _dl_dprintf(2, "%s: Incorrect relocation type in jump relocations\n",
++                                _dl_progname);
++              _dl_exit(1);
++      }
++
++      /* Address of the jump instruction to fix up. */
++      instr_addr = (this_reloc->r_offset + tpnt->loadaddr);
++      got_addr = (char **)instr_addr;
++
++      /* Get the address of the GOT entry */
++      new_addr = _dl_find_hash(symname, tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT);
++      if (unlikely(!new_addr)) {
++              _dl_dprintf(2, "%s: Can't resolve symbol '%s'\n", _dl_progname, symname);
++              _dl_exit(1);
++      }
+ #if defined (__SUPPORT_LD_DEBUG__)
+-      if ((unsigned long) got_addr < 0x40000000)
+-      {
+-              if (_dl_debug_bindings)
+-              {
+-                      _dl_dprintf(_dl_debug_file, "\nresolve function: %s",
+-                                      strtab + symtab[symtab_index].st_name);
+-                      if(_dl_debug_detail) _dl_dprintf(_dl_debug_file,
+-                                      "\tpatch %x ==> %x @ %x", *got_addr, new_addr, got_addr);
++      if ((unsigned long)got_addr < 0x40000000) {
++              if (_dl_debug_bindings) {
++                      _dl_dprintf(_dl_debug_file, "\nresolve function: %s", symname);
++                      if (_dl_debug_detail)
++                              _dl_dprintf(_dl_debug_file,
++                                          "\tpatched: %x ==> %x @ %x\n",
++                                          *got_addr, new_addr, got_addr);
+               }
+       }
+-      if (!_dl_debug_nofixups) {
++      if (!_dl_debug_nofixups)
++#endif
++      {
+               got_addr[1] = (char *) (0x03000000 | (((unsigned int) new_addr >> 10) & 0x3fffff));
+               got_addr[2] = (char *) (0x81c06000 | ((unsigned int) new_addr & 0x3ff));
+       }
++
++      return (unsigned long)new_addr;
++}
++
++static int
++_dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope,
++              unsigned long rel_addr, unsigned long rel_size,
++              int (*reloc_fnc)(struct elf_resolve *tpnt, struct dyn_elf *scope,
++                         ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab))
++{
++      unsigned int i;
++      char *strtab;
++      ElfW(Sym) *symtab;
++      ELF_RELOC *rpnt;
++      int symtab_index;
++
++      /* Parse the relocation information. */
++      rpnt = (ELF_RELOC *)rel_addr;
++      rel_size /= sizeof(ELF_RELOC);
++
++      symtab = (ElfW(Sym) *)tpnt->dynamic_info[DT_SYMTAB];
++      strtab = (char *)tpnt->dynamic_info[DT_STRTAB];
++
++      for (i = 0; i < rel_size; i++, rpnt++) {
++              int res;
++
++              symtab_index = ELF_R_SYM(rpnt->r_info);
++
++              debug_sym(symtab, strtab, symtab_index);
++              debug_reloc(symtab, strtab, rpnt);
++
++              res = reloc_fnc(tpnt, scope, rpnt, symtab, strtab);
++
++              if (res == 0)
++                      continue;
++
++              _dl_dprintf(2, "\n%s: ", _dl_progname);
++
++              if (symtab_index)
++                      _dl_dprintf(2, "symbol '%s': ",
++                                  strtab + symtab[symtab_index].st_name);
++
++              if (unlikely(res < 0)) {
++                      int reloc_type = ELF_R_TYPE(rpnt->r_info);
++
++                      _dl_dprintf(2, "can't handle reloc type "
++#if defined (__SUPPORT_LD_DEBUG__)
++                                  "%s\n", _dl_reltypes(reloc_type));
+ #else
+-      got_addr[1] = (char *) (0x03000000 | (((unsigned int) new_addr >> 10) & 0x3fffff));
+-      got_addr[2] = (char *) (0x81c06000 | ((unsigned int) new_addr & 0x3ff));
++                                  "%x\n", reloc_type);
+ #endif
++                      _dl_exit(-res);
++              } else if (unlikely(res > 0)) {
++                      _dl_dprintf(2, "can't resolve symbol\n");
++                      return res;
++              }
++      }
++
++      return 0;
++}
+-      _dl_dprintf(2, "Address = %x\n",new_addr);
+-      _dl_exit(32);
++static int
++_dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
++                       ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab)
++{
++      int reloc_type;
++      int symtab_index;
++      char *symname;
++      ElfW(Sym) *sym;
++      ElfW(Addr) *reloc_addr;
++      ElfW(Addr) symbol_addr;
++#if defined (__SUPPORT_LD_DEBUG__)
++      ElfW(Addr) old_val;
++#endif
++
++      reloc_addr = (ElfW(Addr)*)(tpnt->loadaddr + (unsigned long)rpnt->r_offset);
++      reloc_type = ELF_R_TYPE(rpnt->r_info);
++      symtab_index = ELF_R_SYM(rpnt->r_info);
++      sym = &symtab[symtab_index];
++      symbol_addr = 0;
++      symname = strtab + sym->st_name;
++
++      if (symtab_index) {
++              symbol_addr = (ElfW(Addr))_dl_find_hash(symname, scope, tpnt,
++                                                          elf_machine_type_class(reloc_type));
++              /*
++               * We want to allow undefined references to weak symbols - this
++               * might have been intentional.  We should not be linking local
++               * symbols here, so all bases should be covered.
++               */
++              if (unlikely(!symbol_addr && ELF_ST_BIND(sym->st_info) != STB_WEAK)) {
++                      _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname);
++                      _dl_exit(1);
++              }
++      }
++
++#if defined (__SUPPORT_LD_DEBUG__)
++      old_val = *reloc_addr;
++#endif
+-  return (unsigned int) new_addr;
++      symbol_addr += rpnt->r_addend;  /* Assume copy relocs have zero addend.  */
++
++      switch (reloc_type) {
++              case R_SPARC_NONE:
++                      break;
++
++#if 0 /* these dont really seem to be useful */
++              case R_SPARC_8:
++                      *(char *) reloc_addr = symbol_addr;
++                      break;
++              case R_SPARC_16:
++                      *(short *) reloc_addr = symbol_addr;
++                      break;
++              case R_SPARC_DISP8:
++                      *(char *) reloc_addr = (symbol_addr) - (Elf32_Addr) reloc_addr;
++                      break;
++              case R_SPARC_DISP16:
++                      *(short *) reloc_addr = (symbol_addr) - (Elf32_Addr) reloc_addr;
++                      break;
++#endif
++
++              case R_SPARC_DISP32:
++                      *reloc_addr = symbol_addr - (unsigned int) reloc_addr;
++                      break;
++
++              case R_SPARC_LO10:
++                      if (!symbol_addr)
++                              symbol_addr = tpnt->loadaddr + rpnt->r_addend;
++                      else
++                              symbol_addr += rpnt->r_addend;
++                      *reloc_addr = (*reloc_addr & ~0x3ff)|(symbol_addr & 0x3ff);
++                      break;
++
++              case R_SPARC_GLOB_DAT:
++              case R_SPARC_32:
++                      *reloc_addr = symbol_addr;
++                      break;
++
++              case R_SPARC_JMP_SLOT:
++/*
++value = symbol_addr;
++value += reloc->r_addend;
++disp = value - reloc_addr;
++reloc_addr[1] = OPCODE_JMP_G1 | (value & 0x3ff);
++reloc_addr[0] = OPCODE_SETHI_G1 | (value >> 10);
++                      reloc_addr[1] = OPCODE_JMP_G1 | ((symbol_addr-(Elf32_Addr)reloc_addr) & 0x3ff);
++                      reloc_addr[0] = OPCODE_SETHI_G1 | ((symbol_addr-(Elf32_Addr)reloc_addr) >> 10);
++*/
++                      reloc_addr[1] = 0x03000000 | ((symbol_addr >> 10) & 0x3fffff);
++                      reloc_addr[2] = 0x81c06000 | (symbol_addr & 0x3ff);
++                      break;
++
++              case R_SPARC_RELATIVE:
++                      *reloc_addr += tpnt->loadaddr + rpnt->r_addend;
++                      break;
++
++              case R_SPARC_WDISP30:
++                      *reloc_addr = (*reloc_addr & 0xc0000000)|
++                               ((symbol_addr - (unsigned int) reloc_addr) >> 2);
++                      break;
++
++              case R_SPARC_HI22:
++                      if (!symbol_addr)
++                              symbol_addr = tpnt->loadaddr + rpnt->r_addend;
++                      else
++                              symbol_addr += rpnt->r_addend;
++                      *reloc_addr = (*reloc_addr & 0xffc00000) | (symbol_addr >> 10);
++                      break;
++
++              case R_SPARC_COPY:
++                      if (symbol_addr) {
++#if defined (__SUPPORT_LD_DEBUG__)
++                              if (_dl_debug_move)
++                                      _dl_dprintf(_dl_debug_file,
++                                                  "\t%s move %d bytes from %x to %x\n",
++                                                  symname, sym->st_size,
++                                                  symbol_addr, reloc_addr);
++#endif
++
++                              _dl_memcpy((char *)reloc_addr,
++                                         (char *)symbol_addr,
++                                         sym->st_size);
++                      } else
++                              _dl_dprintf(_dl_debug_file, "no symbol_addr to copy !?\n");
++                      break;
++              default:
++                      return -1;      /* Calls _dl_exit(1). */
++      }
++
++#if defined (__SUPPORT_LD_DEBUG__)
++      if (_dl_debug_reloc && _dl_debug_detail)
++              _dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x\n",
++                          old_val, *reloc_addr, reloc_addr);
++#endif
++
++      return 0;
++}
++
++#undef __SPARC_LAZY_RELOC_WORKS
++#ifdef __SPARC_LAZY_RELOC_WORKS
++static int
++_dl_do_lazy_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
++                ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab)
++{
++      int reloc_type;
++      int symtab_index;
++      ElfW(Addr) *reloc_addr;
++#if defined (__SUPPORT_LD_DEBUG__)
++      ElfW(Addr) old_val;
++#endif
++
++      (void)scope;
++      symtab_index = ELF_R_SYM(rpnt->r_info);
++      (void)strtab;
++
++      reloc_addr = (ElfW(Addr)*)(tpnt->loadaddr + rpnt->r_offset);
++      reloc_type = ELF_R_TYPE(rpnt->r_info);
++
++#if defined (__SUPPORT_LD_DEBUG__)
++      old_val = *reloc_addr;
++#endif
++
++      switch (reloc_type) {
++              case R_SPARC_NONE:
++                      break;
++              case R_SPARC_JMP_SLOT:
++                      break;
++              default:
++                      _dl_exit(1);
++      }
++
++#if defined (__SUPPORT_LD_DEBUG__)
++      if (_dl_debug_reloc && _dl_debug_detail)
++              _dl_dprintf(_dl_debug_file, "\tpatched_lazy: %x ==> %x @ %x\n",
++                          old_val, *reloc_addr, reloc_addr);
++#endif
++
++      return 0;
+ }
++#endif
+-void _dl_parse_lazy_relocation_information(struct dyn_elf *arg_rpnt,
+-      unsigned long rel_addr, unsigned long rel_size)
+-{
+-  int i;
+-  char * strtab;
+-  int reloc_type;
+-  int symtab_index;
+-  Elf32_Sym * symtab;
+-  Elf32_Rela * rpnt;
+-  unsigned int * reloc_addr;
+-  struct elf_resolve * tpnt = arg_rpnt->dyn;
+-
+-  /* Now parse the relocation information */
+-  rpnt = (Elf32_Rela *)rel_addr;
+-
+-  symtab =  (Elf32_Sym *)tpnt->dynamic_info[DT_SYMTAB];
+-  strtab = ( char *)tpnt->dynamic_info[DT_STRTAB];
+-
+-  for(i=0; i< rel_size; i += sizeof(Elf32_Rela), rpnt++){
+-    reloc_addr = (int *) (tpnt->loadaddr + (int)rpnt->r_offset);
+-    reloc_type = ELF32_R_TYPE(rpnt->r_info);
+-    symtab_index = ELF32_R_SYM(rpnt->r_info);
+-
+-    switch(reloc_type){
+-    case R_SPARC_NONE:
+-      break;
+-    case R_SPARC_JMP_SLOT:
+-      break;
+-    default:
+-      _dl_dprintf(2, "%s: (LAZY) can't handle reloc type ", _dl_progname);
+-#if defined (__SUPPORT_LD_DEBUG__)
+-      _dl_dprintf(2, "%s ", _dl_reltypes_tab[reloc_type]);
+-#endif
+-      if(symtab_index) _dl_dprintf(2, "'%s'\n",
+-                                strtab + symtab[symtab_index].st_name);
+-      _dl_exit(33);
+-    };
+-  };
+-}
+-
+-int _dl_parse_relocation_information(struct dyn_elf *arg_rpnt,
+-      unsigned long rel_addr, unsigned long rel_size)
+-{
+-  int i;
+-  char * strtab;
+-  int reloc_type;
+-  int goof = 0;
+-  Elf32_Sym * symtab;
+-  Elf32_Rela * rpnt;
+-  unsigned int * reloc_addr;
+-  unsigned int symbol_addr;
+-  int symtab_index;
+-  struct elf_resolve * tpnt = arg_rpnt->dyn;
+-  /* Now parse the relocation information */
+-
+-  rpnt = (Elf32_Rela *)rel_addr;
+-
+-  symtab =  (Elf32_Sym *)tpnt->dynamic_info[DT_SYMTAB];
+-  strtab = ( char *)tpnt->dynamic_info[DT_STRTAB];
+-
+-  for(i=0; i< rel_size; i+= sizeof(Elf32_Rela), rpnt++){
+-    reloc_addr = (int *) (tpnt->loadaddr + (int)rpnt->r_offset);
+-    reloc_type = ELF32_R_TYPE(rpnt->r_info);
+-    symtab_index = ELF32_R_SYM(rpnt->r_info);
+-    symbol_addr = 0;
+-
+-    if(symtab_index) {
+-
+-      symbol_addr = (unsigned int)
+-      _dl_find_hash(strtab + symtab[symtab_index].st_name,
+-                    tpnt->symbol_scope, tpnt, elf_machine_type_class(reloc_type));
+-
+-      if(!symbol_addr &&
+-       ELF32_ST_BIND(symtab [symtab_index].st_info) != STB_WEAK) {
+-                      _dl_dprintf (2, "%s: can't resolve symbol '%s'\n",
+-                                   _dl_progname, strtab + symtab[symtab_index].st_name);
+-                      _dl_exit (1);
+-      };
+-    };
+-    switch(reloc_type){
+-    case R_SPARC_NONE:
+-      break;
+-    case R_SPARC_32:
+-      *reloc_addr = symbol_addr + rpnt->r_addend;
+-      break;
+-    case R_SPARC_DISP32:
+-      *reloc_addr = symbol_addr + rpnt->r_addend - (unsigned int) reloc_addr;
+-      break;
+-    case R_SPARC_GLOB_DAT:
+-      *reloc_addr = symbol_addr + rpnt->r_addend;
+-      break;
+-    case R_SPARC_JMP_SLOT:
+-      reloc_addr[1] = 0x03000000 | ((symbol_addr >> 10) & 0x3fffff);
+-      reloc_addr[2] = 0x81c06000 | (symbol_addr & 0x3ff);
+-      break;
+-    case R_SPARC_RELATIVE:
+-      *reloc_addr += (unsigned int) tpnt->loadaddr + rpnt->r_addend;
+-      break;
+-    case R_SPARC_HI22:
+-      if (!symbol_addr)
+-        symbol_addr = tpnt->loadaddr + rpnt->r_addend;
+-      else
+-      symbol_addr += rpnt->r_addend;
+-      *reloc_addr = (*reloc_addr & 0xffc00000)|(symbol_addr >> 10);
+-      break;
+-    case R_SPARC_LO10:
+-      if (!symbol_addr)
+-        symbol_addr = tpnt->loadaddr + rpnt->r_addend;
+-      else
+-      symbol_addr += rpnt->r_addend;
+-      *reloc_addr = (*reloc_addr & ~0x3ff)|(symbol_addr & 0x3ff);
+-      break;
+-    case R_SPARC_WDISP30:
+-      *reloc_addr = (*reloc_addr & 0xc0000000)|
+-      ((symbol_addr - (unsigned int) reloc_addr) >> 2);
+-      break;
+-    case R_SPARC_COPY:
+-      _dl_memcpy((void *) reloc_addr, (void *) symbol_addr, symtab[symtab_index].st_size);
+-      break;
+-    default:
+-      _dl_dprintf(2, "%s: can't handle reloc type ", _dl_progname);
+-#if defined (__SUPPORT_LD_DEBUG__)
+-      _dl_dprintf(2, "%s ", _dl_reltypes_tab[reloc_type]);
+-#endif
+-      if (symtab_index)
+-      _dl_dprintf(2, "'%s'\n", strtab + symtab[symtab_index].st_name);
+-      _dl_exit(34);
+-    };
++void
++_dl_parse_lazy_relocation_information(struct dyn_elf *rpnt,
++                                    unsigned long rel_addr,
++                                    unsigned long rel_size)
++{
++#ifdef __SPARC_LAZY_RELOC_WORKS
++      (void)_dl_parse(rpnt->dyn, NULL, rel_addr, rel_size, _dl_do_lazy_reloc);
++#else
++      _dl_parse_relocation_information(rpnt, rel_addr, rel_size);
++#endif
++}
+-  };
+-  return goof;
++int
++_dl_parse_relocation_information(struct dyn_elf *rpnt,
++                               unsigned long rel_addr,
++                               unsigned long rel_size)
++{
++      return _dl_parse(rpnt->dyn, rpnt->dyn->symbol_scope, rel_addr, rel_size, _dl_do_reloc);
+ }
+diff -urN uClibc-0.9.28.orig/ldso/ldso/x86_64/dl-debug.h uClibc-0.9.28/ldso/ldso/x86_64/dl-debug.h
+--- uClibc-0.9.28.orig/ldso/ldso/x86_64/dl-debug.h     2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/x86_64/dl-debug.h  2006-04-28 00:14:35.000000000 -0600
+@@ -30,7 +30,10 @@
+  */
+ static const char *_dl_reltypes_tab[] = {
+-      [0] "R_X86_64_NONE",     "R_X86_64_64",       "R_X86_64_PC32",     "R_X86_64_GOT32",
+-      [4] "R_X86_64_PLT32",    "R_X86_64_COPY",     "R_X86_64_GLOB_DAT", "R_X86_64_JUMP_SLOT",
+-      [8] "R_X86_64_RELATIVE", "R_X86_64_GOTPCREL", "R_X86_64_32"
++      [ 0] "R_X86_64_NONE",     "R_X86_64_64",       "R_X86_64_PC32",     "R_X86_64_GOT32",
++      [ 4] "R_X86_64_PLT32",    "R_X86_64_COPY",     "R_X86_64_GLOB_DAT", "R_X86_64_JUMP_SLOT",
++      [ 8] "R_X86_64_RELATIVE", "R_X86_64_GOTPCREL", "R_X86_64_32",       "R_X86_64_32S",
++      [12] "R_X86_64_16",       "R_X86_64_PC16",     "R_X86_64_8",        "R_X86_64_PC8",
++      [16] "R_X86_64_DTPMOD64", "R_X86_64_DTPOFF64", "R_X86_64_TPOFF64",  "R_X86_64_TLSGD",
++      [20] "R_X86_64_TLSLD",    "R_X86_64_DTPOFF32", "R_X86_64_GOTTPOFF", "R_X86_64_TPOFF32"
+ };
+diff -urN uClibc-0.9.28.orig/ldso/ldso/x86_64/dl-startup.h uClibc-0.9.28/ldso/ldso/x86_64/dl-startup.h
+--- uClibc-0.9.28.orig/ldso/ldso/x86_64/dl-startup.h   2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/x86_64/dl-startup.h        2006-04-28 00:14:35.000000000 -0600
+@@ -6,7 +6,7 @@
+  *
+  * Parts taken from glibc/sysdeps/x86_64/dl-machine.h
+  */
+-asm(
++__asm__ (
+       "       .text\n"
+       "       .align 16\n"
+       "       .global _start\n"
+@@ -42,10 +42,10 @@
+ /* Handle relocation of the symbols in the dynamic loader. */
+ static __always_inline
+-void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, unsigned long *reloc_addr,
+-      unsigned long symbol_addr, unsigned long load_addr, Elf64_Sym *sym)
++void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, ElfW(Addr) *reloc_addr,
++      ElfW(Addr) symbol_addr, ElfW(Addr) load_addr, ElfW(Sym) *sym)
+ {
+-      switch (ELF64_R_TYPE(rpnt->r_info)) {
++      switch (ELF_R_TYPE(rpnt->r_info)) {
+               case R_X86_64_GLOB_DAT:
+               case R_X86_64_JUMP_SLOT:
+                       *reloc_addr = symbol_addr + rpnt->r_addend;
+@@ -63,8 +63,3 @@
+                       _dl_exit(1);
+       }
+ }
+-
+-/* Transfer control to the user's application, once the dynamic loader is
+- * done.  This routine has to exit the current function, then call the
+- * _dl_elf_main function.  */
+-#define START() return _dl_elf_main
+diff -urN uClibc-0.9.28.orig/ldso/ldso/x86_64/dl-syscalls.h uClibc-0.9.28/ldso/ldso/x86_64/dl-syscalls.h
+--- uClibc-0.9.28.orig/ldso/ldso/x86_64/dl-syscalls.h  2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/x86_64/dl-syscalls.h       2006-05-02 13:39:17.000000000 -0600
+@@ -1,7 +1,8 @@
+ /* We can't use the real errno in ldso, since it has not yet
+  * been dynamicly linked in yet. */
++#define __UCLIBC_MMAP_HAS_6_ARGS__
++
++#include "sys/syscall.h"
+ extern int _dl_errno;
++#undef __set_errno
+ #define __set_errno(X) {(_dl_errno) = (X);}
+-#include "sys/syscall.h"
+-
+-#define MMAP_HAS_6_ARGS
+diff -urN uClibc-0.9.28.orig/ldso/ldso/x86_64/dl-sysdep.h uClibc-0.9.28/ldso/ldso/x86_64/dl-sysdep.h
+--- uClibc-0.9.28.orig/ldso/ldso/x86_64/dl-sysdep.h    2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/x86_64/dl-sysdep.h 2006-04-28 00:14:35.000000000 -0600
+@@ -41,8 +41,6 @@
+ struct elf_resolve;
+ extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
+-#define do_rem(result, n, base) ((result) = (n) % (base))
+-
+ /* 4096 bytes alignment */
+ #define PAGE_ALIGN 0xfffff000
+ #define ADDR_ALIGN 0xfff
+@@ -90,7 +88,7 @@
+      and compare it with the current value that we can get via
+      an RIP relative addressing mode.  */
+-  asm ("movq 1f(%%rip), %1\n"
++  __asm__ ("movq 1f(%%rip), %1\n"
+        "0:\tleaq _dl_start(%%rip), %0\n\t"
+        "subq %1, %0\n\t"
+        ".section\t.data\n"
+diff -urN uClibc-0.9.28.orig/ldso/ldso/x86_64/elfinterp.c uClibc-0.9.28/ldso/ldso/x86_64/elfinterp.c
+--- uClibc-0.9.28.orig/ldso/ldso/x86_64/elfinterp.c    2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/ldso/x86_64/elfinterp.c 2006-04-28 00:14:35.000000000 -0600
+@@ -165,6 +165,7 @@
+       int reloc_type;
+       int symtab_index;
+       char *symname;
++      ElfW(Sym) *sym;
+       ElfW(Addr) *reloc_addr;
+       ElfW(Addr) symbol_addr;
+ #if defined (__SUPPORT_LD_DEBUG__)
+@@ -174,8 +175,9 @@
+       reloc_addr = (ElfW(Addr)*)(tpnt->loadaddr + (unsigned long)rpnt->r_offset);
+       reloc_type = ELF_R_TYPE(rpnt->r_info);
+       symtab_index = ELF_R_SYM(rpnt->r_info);
++      sym = &symtab[symtab_index];
+       symbol_addr = 0;
+-      symname = strtab + symtab[symtab_index].st_name;
++      symname = strtab + sym->st_name;
+       if (symtab_index) {
+               symbol_addr = (ElfW(Addr))_dl_find_hash(symname, scope, tpnt,
+@@ -185,7 +187,7 @@
+                * might have been intentional.  We should not be linking local
+                * symbols here, so all bases should be covered.
+                */
+-              if (unlikely(!symbol_addr && ELF_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK)) {
++              if (unlikely(!symbol_addr && ELF_ST_BIND(sym->st_info) != STB_WEAK)) {
+                       _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname);
+                       _dl_exit(1);
+               };
+@@ -209,7 +211,7 @@
+               case R_X86_64_GLOB_DAT:
+               case R_X86_64_JUMP_SLOT:
+-                      *reloc_addr = symbol_addr;
++                      *reloc_addr = symbol_addr + rpnt->r_addend;
+                       break;
+               /* handled by elf_machine_relative()
+@@ -217,33 +219,33 @@
+                       *reloc_addr = map->l_addr + rpnt->r_addend;
+                       break;
+               */
+-#if 0
+               case R_X86_64_DTPMOD64:
++                      *reloc_addr = 1;
+                       break;
+               case R_X86_64_DTPOFF64:
+-                      *reloc_addr = symbol_addr + rpnt->r_addend;
++                      *reloc_addr = sym->st_value + rpnt->r_addend;
+                       break;
+               case R_X86_64_TPOFF64:
+-                      *reloc_addr = symbol_addr + rpnt->r_addend;
++                      *reloc_addr = sym->st_value + rpnt->r_addend - symbol_addr;
+                       break;
+               case R_X86_64_32:
+-                      *reloc_addr = symbol_addr + rpnt->r_addend;
++                      *(unsigned int *) reloc_addr = symbol_addr + rpnt->r_addend;
++                      /* XXX: should check for overflow eh ? */
+                       break;
+-#endif
+               case R_X86_64_COPY:
+                       if (symbol_addr) {
+ #if defined (__SUPPORT_LD_DEBUG__)
+                               if (_dl_debug_move)
+                                       _dl_dprintf(_dl_debug_file,
+                                                   "\t%s move %d bytes from %x to %x\n",
+-                                                  symname, symtab[symtab_index].st_size,
++                                                  symname, sym->st_size,
+                                                   symbol_addr, reloc_addr);
+ #endif
+                               _dl_memcpy((char *)reloc_addr,
+                                          (char *)symbol_addr,
+-                                         symtab[symtab_index].st_size);
++                                         sym->st_size);
+                       } else
+                               _dl_dprintf(_dl_debug_file, "no symbol_addr to copy !?\n");
+                       break;
+@@ -261,7 +263,6 @@
+       return 0;
+ }
+-#if 0
+ static int
+ _dl_do_lazy_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
+                 ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab)
+@@ -288,7 +289,7 @@
+               case R_X86_64_NONE:
+                       break;
+               case R_X86_64_JUMP_SLOT:
+-                      *reloc_addr = tpnt->loadaddr + symtab[symtab_index].st_value;
++                      *reloc_addr += (unsigned long)tpnt->loadaddr;
+                       break;
+               default:
+                       _dl_exit(1);
+@@ -302,17 +303,13 @@
+       return 0;
+ }
+-#endif
+ void
+ _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt,
+                                     unsigned long rel_addr,
+                                     unsigned long rel_size)
+ {
+-      _dl_parse_relocation_information(rpnt, rel_addr, rel_size);
+-/*    jump slot isnt working
+       (void)_dl_parse(rpnt->dyn, NULL, rel_addr, rel_size, _dl_do_lazy_reloc);
+-*/
+ }
+ int
+diff -urN uClibc-0.9.28.orig/ldso/ldso/x86_64/resolve.S uClibc-0.9.28/ldso/ldso/x86_64/resolve.S
+--- uClibc-0.9.28.orig/ldso/ldso/x86_64/resolve.S      1969-12-31 17:00:00.000000000 -0700
++++ uClibc-0.9.28/ldso/ldso/x86_64/resolve.S   2006-04-28 00:14:35.000000000 -0600
+@@ -0,0 +1,63 @@
++/*
++ * This function is _not_ called directly.  It is jumped to (so no return
++ * address is on the stack) when attempting to use a symbol that has not yet
++ * been resolved.  The first time a jump symbol (such as a function call inside
++ * a shared library) is used (before it gets resolved) it will jump here to
++ * _dl_linux_resolve.  When we get called the stack looks like this:
++ *    reloc_entry
++ *    tpnt
++ *
++ * This function saves all the registers, puts a copy of reloc_entry and tpnt
++ * on the stack (as function arguments) then make the function call
++ * _dl_linux_resolver(tpnt, reloc_entry).  _dl_linux_resolver() figures out
++ * where the jump symbol is _really_ supposed to have jumped to and returns
++ * that to us.  Once we have that, we overwrite tpnt with this fixed up
++ * address. We then clean up after ourselves, put all the registers back how we
++ * found them, then we jump to where the fixed up address, which is where the
++ * jump symbol that got us here really wanted to jump to in the first place.
++ * found them, then we jump to the fixed up address, which is where the jump
++ * symbol that got us here really wanted to jump to in the first place.
++ *  -Erik Andersen
++ */
++
++/* more info taken from glibc/sysdeps/x86_64/dl-trampoline.S */
++
++.text
++
++.global _dl_linux_resolve
++.type   _dl_linux_resolve,%function
++.align 16
++
++_dl_linux_resolve:
++      subq $56,%rsp
++      /* Preserve registers otherwise clobbered. */
++      movq %rax,   (%rsp)
++      movq %rcx,  8(%rsp)
++      movq %rdx, 16(%rsp)
++      movq %rsi, 24(%rsp)
++      movq %rdi, 32(%rsp)
++      movq %r8,  40(%rsp)
++      movq %r9,  48(%rsp)
++
++      movq 64(%rsp), %rsi  /* Copy args pushed by PLT in register. */
++      movq %rsi, %r11      /* Multiply by 24 */
++      addq %r11, %rsi
++      addq %r11, %rsi
++      shlq $3, %rsi
++      movq 56(%rsp), %rdi  /* %rdi: link_map, %rsi: reloc_offset */
++      call _dl_linux_resolver       /* Call resolver. */
++      movq %rax, %r11      /* Save return value */
++
++      /* Get register content back. */
++      movq 48(%rsp), %r9
++      movq 40(%rsp), %r8
++      movq 32(%rsp), %rdi
++      movq 24(%rsp), %rsi
++      movq 16(%rsp), %rdx
++      movq  8(%rsp), %rcx
++      movq   (%rsp), %rax
++
++      addq $72, %rsp       /* Adjust stack(PLT did 2 pushes) */
++      jmp *%r11            /* Jump to function address. */
++
++.size _dl_linux_resolve,.-_dl_linux_resolve
+diff -urN uClibc-0.9.28.orig/ldso/libdl/Makefile uClibc-0.9.28/ldso/libdl/Makefile
+--- uClibc-0.9.28.orig/ldso/libdl/Makefile     2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/libdl/Makefile  2006-04-28 00:14:35.000000000 -0600
+@@ -29,12 +29,14 @@
+ endif
+ XXFLAGS+= $(XARCH_CFLAGS) $(CPU_CFLAGS) \
+       -DUCLIBC_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" \
+-      -fno-builtin -nostdinc -D_LIBC -I$(TOPDIR)ldso/include -I$(TOPDIR)ldso/ldso -I. -I$(TOPDIR)include
++      -fno-builtin -nostdinc -D_LIBC \
++      -DLDSO_ELFINTERP=\"$(TARGET_ARCH)/elfinterp.c\" \
++      -I$(TOPDIR)ldso/ldso/$(TARGET_ARCH) -I$(TOPDIR)ldso/include -I$(TOPDIR)ldso/ldso -I$(TOPDIR)include
+ XXFLAGS+=-isystem $(shell $(CC) -print-file-name=include)
+ XXFLAGS_NOPIC:=$(XXFLAGS)
+ ifeq ($(DOPIC),y)
+-    XXFLAGS += $(PICFLAG) -D__LIBDL_SHARED__
++    XXFLAGS += $(PICFLAG) -DSHARED
+ endif
+ ifeq ($(strip $(SUPPORT_LD_DEBUG)),y)
+ XXFLAGS+=-D__SUPPORT_LD_DEBUG__
+diff -urN uClibc-0.9.28.orig/ldso/libdl/libdl.c uClibc-0.9.28/ldso/libdl/libdl.c
+--- uClibc-0.9.28.orig/ldso/libdl/libdl.c      2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/ldso/libdl/libdl.c   2006-04-28 00:14:35.000000000 -0600
+@@ -3,7 +3,7 @@
+  * Program to load an ELF binary on a linux system, and run it
+  * after resolving ELF shared library symbols
+  *
+- * Copyright (C) 2000-2004 by Erik Andersen <andersen@codepoet.org>
++ * Copyright (C) 2000-2006 by Erik Andersen <andersen@uclibc.org>
+  * Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald,
+  *                            David Engel, Hongjiu Lu and Mitch D'Souza
+  *
+@@ -30,12 +30,12 @@
+  */
+-#define _GNU_SOURCE
++#define _GNU_SOURCE
+ #include <ldso.h>
+ #include <stdio.h>
+-#if defined (__LIBDL_SHARED__)
++#ifdef SHARED
+ /* When libdl is loaded as a shared library, we need to load in
+  * and use a pile of symbols from ldso... */
+@@ -52,6 +51,8 @@
+ extern struct r_debug *_dl_debug_addr;
+ extern unsigned long _dl_error_number;
+ extern void *(*_dl_malloc_function)(size_t);
++extern void _dl_run_init_array(struct elf_resolve *);
++extern void _dl_run_fini_array(struct elf_resolve *);
+ #ifdef __LDSO_CACHE_SUPPORT__
+ int _dl_map_cache(void);
+ int _dl_unmap_cache(void);
+@@ -64,7 +65,7 @@
+ #endif
+-#else /* __LIBDL_SHARED__ */
++#else /* SHARED */
+ /* When libdl is linked as a static library, we need to replace all
+  * the symbols that otherwise would have been loaded in from ldso... */
+@@ -81,11 +82,11 @@
+ struct r_debug *_dl_debug_addr = NULL;
+ #define _dl_malloc malloc
+ #include "../ldso/dl-debug.c"
+-#include "dl-progname.h"
++#include LDSO_ELFINTERP
+ #include "../ldso/dl-hash.c"
+ #define _dl_trace_loaded_objects    0
+ #include "../ldso/dl-elf.c"
+-#endif /* __LIBDL_SHARED__ */
++#endif /* SHARED */
+ #ifdef __SUPPORT_LD_DEBUG__
+ # define _dl_if_debug_print(fmt, args...) \
+@@ -126,7 +127,8 @@
+       "Unable to resolve symbol"
+ };
+-void __attribute__ ((destructor)) dl_cleanup(void)
++void dl_cleanup(void) __attribute__ ((destructor));
++void dl_cleanup(void)
+ {
+       struct dyn_elf *d;
+       for (d = _dl_handles; d; d = d->next_handle) {
+@@ -138,13 +140,12 @@
+ {
+       struct elf_resolve *tpnt, *tfrom;
+       struct dyn_elf *dyn_chain, *rpnt = NULL, *dyn_ptr, *relro_ptr, *handle;
+-      struct dyn_elf *dpnt;
+       ElfW(Addr) from;
+       struct elf_resolve *tpnt1;
+       void (*dl_brk) (void);
+       int now_flag;
+       struct init_fini_list *tmp, *runp, *runp2, *dep_list;
+-      int nlist, i;
++      unsigned int nlist, i;
+       struct elf_resolve **init_fini_list;
+       /* A bit of sanity checking... */
+@@ -169,12 +170,15 @@
+        * the application.  Thus this may go away at some time
+        * in the future.
+        */
+-      tfrom = NULL;
+-      for (dpnt = _dl_symbol_tables; dpnt; dpnt = dpnt->next) {
+-              tpnt = dpnt->dyn;
+-              if (tpnt->loadaddr < from
+-                              && (tfrom == NULL || tfrom->loadaddr < tpnt->loadaddr))
+-                      tfrom = tpnt;
++      {
++              struct dyn_elf *dpnt;
++              tfrom = NULL;
++              for (dpnt = _dl_symbol_tables; dpnt; dpnt = dpnt->next) {
++                      tpnt = dpnt->dyn;
++                      if (tpnt->loadaddr < from
++                                      && (tfrom == NULL || tfrom->loadaddr < tpnt->loadaddr))
++                              tfrom = tpnt;
++              }
+       }
+       for(rpnt = _dl_symbol_tables; rpnt && rpnt->next; rpnt=rpnt->next);
+@@ -233,11 +237,8 @@
+               runp->tpnt->init_fini = NULL; /* clear any previous dependcies */
+               for (dpnt = (ElfW(Dyn) *) runp->tpnt->dynamic_addr; dpnt->d_tag; dpnt++) {
+                       if (dpnt->d_tag == DT_NEEDED) {
+-                              char *name;
+-
+                               lpntstr = (char*) (runp->tpnt->dynamic_info[DT_STRTAB] +
+                                               dpnt->d_un.d_val);
+-                              name = _dl_get_last_path_component(lpntstr);
+                               _dl_if_debug_print("Trying to load '%s', needed by '%s'\n",
+                                               lpntstr, runp->tpnt->libname);
+                               tpnt1 = _dl_load_shared_library(0, &rpnt, runp->tpnt, lpntstr, 0);
+@@ -297,14 +298,14 @@
+       }
+       /* Sort the INIT/FINI list in dependency order. */
+       for (runp2 = dep_list; runp2; runp2 = runp2->next) {
+-              int j, k;
++              unsigned int j, k;
+               for (j = 0; init_fini_list[j] != runp2->tpnt; ++j)
+                       /* Empty */;
+               for (k = j + 1; k < nlist; ++k) {
+-                      struct init_fini_list *runp = init_fini_list[k]->init_fini;
++                      struct init_fini_list *ele = init_fini_list[k]->init_fini;
+-                      for (; runp; runp = runp->next) {
+-                              if (runp->tpnt == runp2->tpnt) {
++                      for (; ele; ele = ele->next) {
++                              if (ele->tpnt == runp2->tpnt) {
+                                       struct elf_resolve *here = init_fini_list[k];
+                                       _dl_if_debug_print("Move %s from pos %d to %d in INIT/FINI list.\n", here->libname, k, j);
+                                       for (i = (k - j); i; --i)
+@@ -367,7 +368,7 @@
+               }
+       }
+-#if defined (__LIBDL_SHARED__)
++#ifdef SHARED
+       /* Run the ctors and setup the dtors */
+       for (i = nlist; i; --i) {
+               tpnt = init_fini_list[i-1];
+@@ -384,8 +385,11 @@
+                               (*dl_elf_func) ();
+                       }
+               }
++
++              _dl_run_init_array(tpnt);
+       }
+-#endif
++#endif /* SHARED */
++
+       _dl_unmap_cache();
+       return (void *) dyn_chain;
+@@ -450,9 +454,16 @@
+       return ret;
+ }
++#if 0
++void *dlvsym(void *vhandle, const char *name, const char *version)
++{
++      return dlsym(vhandle, name);
++}
++#endif
++
+ static int do_dlclose(void *vhandle, int need_fini)
+ {
+-      struct dyn_elf *rpnt, *rpnt1;
++      struct dyn_elf *rpnt, *rpnt1, *rpnt1_tmp;
+       struct init_fini_list *runp, *tmp;
+       ElfW(Phdr) *ppnt;
+       struct elf_resolve *tpnt, *run_tpnt;
+@@ -460,7 +471,7 @@
+       void (*dl_brk) (void);
+       struct dyn_elf *handle;
+       unsigned int end;
+-      int i = 0, j;
++      unsigned int i, j;
+       handle = (struct dyn_elf *) vhandle;
+       if (handle == _dl_symbol_tables)
+@@ -491,13 +502,21 @@
+       for (j = 0; j < handle->init_fini.nlist; ++j) {
+               tpnt = handle->init_fini.init_fini[j];
+               if (--tpnt->usage_count == 0) {
+-                      if (tpnt->dynamic_info[DT_FINI] && need_fini &&
++                      if ((tpnt->dynamic_info[DT_FINI]
++                           || tpnt->dynamic_info[DT_FINI_ARRAY])
++                          && need_fini &&
+                           !(tpnt->init_flag & FINI_FUNCS_CALLED)) {
+                               tpnt->init_flag |= FINI_FUNCS_CALLED;
+-                              dl_elf_fini = (int (*)(void)) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI]);
+-                              _dl_if_debug_print("running dtors for library %s at '%p'\n",
+-                                              tpnt->libname, dl_elf_fini);
+-                              (*dl_elf_fini) ();
++#ifdef SHARED
++                              _dl_run_fini_array(tpnt);
++#endif
++
++                              if (tpnt->dynamic_info[DT_FINI]) {
++                                      dl_elf_fini = (int (*)(void)) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI]);
++                                      _dl_if_debug_print("running dtors for library %s at '%p'\n",
++                                                      tpnt->libname, dl_elf_fini);
++                                      (*dl_elf_fini) ();
++                              }
+                       }
+                       _dl_if_debug_print("unmapping: %s\n", tpnt->libname);
+@@ -541,8 +560,9 @@
+                                       for (rpnt1 = _dl_symbol_tables; rpnt1->next; rpnt1 = rpnt1->next) {
+                                               if (rpnt1->next->dyn == tpnt) {
+                                                       _dl_if_debug_print("removing symbol_tables: %s\n", tpnt->libname);
++                                                      rpnt1_tmp = rpnt1->next->next;
+                                                       free(rpnt1->next);
+-                                                      rpnt1->next = rpnt1->next->next;
++                                                      rpnt1->next = rpnt1_tmp;
+                                                       if (rpnt1->next)
+                                                               rpnt1->next->prev = rpnt1;
+                                                       break;
+@@ -588,8 +608,9 @@
+ }
+ /*
+- * Dump information to stderrr about the current loaded modules
++ * Dump information to stderr about the current loaded modules
+  */
++#if 1
+ static char *type[] = { "Lib", "Exe", "Int", "Mod" };
+ int dlinfo(void)
+@@ -660,16 +681,14 @@
+       {
+               char *strtab;
+               ElfW(Sym) *symtab;
+-              int hn, si;
+-              int sf;
+-              int sn = 0;
++              unsigned int hn, si, sn, sf;
+               ElfW(Addr) sa;
+               sa = 0;
+               symtab = (ElfW(Sym) *) (pelf->dynamic_info[DT_SYMTAB]);
+               strtab = (char *) (pelf->dynamic_info[DT_STRTAB]);
+-              sf = 0;
++              sf = sn = 0;
+               for (hn = 0; hn < pelf->nbucket; hn++) {
+                       for (si = pelf->elf_buckets[hn]; si; si = pelf->chains[si]) {
+                               ElfW(Addr) symbol_addr;
+@@ -696,3 +715,4 @@
+               return 1;
+       }
+ }
++#endif
+diff -urN uClibc-0.9.28.orig/libc/sysdeps/linux/i386/bits/syscalls.h uClibc-0.9.28/libc/sysdeps/linux/i386/bits/syscalls.h
+--- uClibc-0.9.28.orig/libc/sysdeps/linux/i386/bits/syscalls.h 2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/libc/sysdeps/linux/i386/bits/syscalls.h      2006-04-28 00:14:35.000000000 -0600
+@@ -4,17 +4,15 @@
+ # error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead."
+ #endif
++#include <errno.h>
++
+ /* This includes the `__NR_<name>' syscall numbers taken from the Linux kernel
+  * header files.  It also defines the traditional `SYS_<name>' macros for older
+  * programs.  */
+ #include <bits/sysnum.h>
+-#ifndef __set_errno
+-# define __set_errno(val) (*__errno_location ()) = (val)
+-#endif
+-
+ /*
+-   Some of the sneaky macros in the code were taken from 
++   Some of the sneaky macros in the code were taken from
+    glibc-2.2.5/sysdeps/unix/sysv/linux/i386/sysdep.h
+ */
+@@ -22,7 +20,8 @@
+ /* We need some help from the assembler to generate optimal code.  We
+    define some macros here which later will be used.  */
+-asm (".L__X'%ebx = 1\n\t"
++
++__asm__ (".L__X'%ebx = 1\n\t"
+      ".L__X'%ecx = 2\n\t"
+      ".L__X'%edx = 2\n\t"
+      ".L__X'%eax = 3\n\t"
+@@ -56,7 +55,6 @@
+      ".endif\n\t"
+      ".endm\n\t");
+-
+ #undef _syscall0
+ #define _syscall0(type,name) \
+ type name(void) \
+@@ -90,7 +88,7 @@
+ type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
+ { \
+ return (type) (INLINE_SYSCALL(name, 4, arg1, arg2, arg3, arg4)); \
+-} 
++}
+ #undef _syscall5
+ #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+@@ -100,10 +98,18 @@
+ return (type) (INLINE_SYSCALL(name, 5, arg1, arg2, arg3, arg4, arg5)); \
+ }
++#undef _syscall6
++#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
++        type5,arg5,type6,arg6) \
++type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, type6 arg6) \
++{ \
++return (type) (INLINE_SYSCALL(name, 6, arg1, arg2, arg3, arg4, arg5, arg6)); \
++}
++
+ #define INLINE_SYSCALL(name, nr, args...) \
+   ({                                                                        \
+     unsigned int resultvar;                                                 \
+-    asm volatile (                                                          \
++    __asm__ __volatile__ (                                                          \
+     LOADARGS_##nr                                                           \
+     "movl %1, %%eax\n\t"                                                    \
+     "int $0x80\n\t"                                                         \
+@@ -125,6 +131,7 @@
+ #define LOADARGS_3    LOADARGS_1
+ #define LOADARGS_4    LOADARGS_1
+ #define LOADARGS_5    LOADARGS_1
++#define LOADARGS_6    LOADARGS_1 "push %%ebp ; movl %7, %%ebp\n\t"
+ #define RESTOREARGS_0
+ #define RESTOREARGS_1 \
+@@ -133,6 +140,7 @@
+ #define RESTOREARGS_3 RESTOREARGS_1
+ #define RESTOREARGS_4 RESTOREARGS_1
+ #define RESTOREARGS_5 RESTOREARGS_1
++#define RESTOREARGS_6 "pop %%ebp\n\t" RESTOREARGS_1
+ #define ASMFMT_0()
+ #define ASMFMT_1(arg1) \
+@@ -145,7 +153,8 @@
+       , "aD" (arg1), "c" (arg2), "d" (arg3), "S" (arg4)
+ #define ASMFMT_5(arg1, arg2, arg3, arg4, arg5) \
+       , "a" (arg1), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5)
+-
++#define ASMFMT_6(arg1, arg2, arg3, arg4, arg5, arg6) \
++      , "a" (arg1), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5), "m" (arg6)
+ #endif /* __ASSEMBLER__ */
+ #endif /* _BITS_SYSCALLS_H */
+diff -urN uClibc-0.9.28.orig/libc/sysdeps/linux/powerpc/bits/syscalls.h uClibc-0.9.28/libc/sysdeps/linux/powerpc/bits/syscalls.h
+--- uClibc-0.9.28.orig/libc/sysdeps/linux/powerpc/bits/syscalls.h      2006-05-02 10:47:27.000000000 -0600
++++ uClibc-0.9.28/libc/sysdeps/linux/powerpc/bits/syscalls.h   2006-04-28 00:14:35.000000000 -0600
+@@ -5,67 +5,164 @@
+ # error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead."
+ #endif
++#include <errno.h>
++
+ /* This includes the `__NR_<name>' syscall numbers taken from the Linux kernel
+  * header files.  It also defines the traditional `SYS_<name>' macros for older
+  * programs.  */
+ #include <bits/sysnum.h>
+-
+-#define __STRINGIFY(s) __STRINGIFY2 (s)
+-#define __STRINGIFY2(s) #s
+-
+-#undef JUMPTARGET
+-#ifdef __PIC__
+-#define __MAKE_SYSCALL        __STRINGIFY(__uClibc_syscall@plt)
++/* Define a macro which expands inline into the wrapper code for a system
++   call. This use is for internal calls that do not need to handle errors
++   normally. It will never touch errno.
++   On powerpc a system call basically clobbers the same registers like a
++   function call, with the exception of LR (which is needed for the
++   "sc; bnslr+" sequence) and CR (where only CR0.SO is clobbered to signal
++   an error return status).  */
++
++# undef INLINE_SYSCALL
++#if 1
++# define INLINE_SYSCALL(name, nr, args...)                            \
++  ({                                                                  \
++    INTERNAL_SYSCALL_DECL (sc_err);                                   \
++    long int sc_ret = INTERNAL_SYSCALL (name, sc_err, nr, args);      \
++    if (INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err))                    \
++      {                                                                       \
++      __set_errno (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err));          \
++      sc_ret = -1L;                                                   \
++      }                                                                       \
++    sc_ret;                                                           \
++  })
+ #else
+-#define __MAKE_SYSCALL        __STRINGIFY(__uClibc_syscall)
++# define INLINE_SYSCALL(name, nr, args...)                            \
++  ({                                                                  \
++    INTERNAL_SYSCALL_DECL (sc_err);                                   \
++    long int sc_ret = INTERNAL_SYSCALL (name, sc_err, nr, args);      \
++    if (INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err))                    \
++      {                                                                       \
++      sc_ret = __syscall_error(INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err));\
++      }                                                                       \
++    sc_ret;                                                           \
++  })
+ #endif
+-#define unified_syscall_body(name)                    \
+-      __asm__ (                                       \
+-      ".section \".text\"\n\t"                        \
+-      ".align 2\n\t"                                  \
+-      ".globl " __STRINGIFY(name) "\n\t"              \
+-      ".type " __STRINGIFY(name) ",@function\n\t"     \
+-      #name":\tli 0," __STRINGIFY(__NR_##name) "\n\t" \
+-      "b " __MAKE_SYSCALL "\n\t"              \
+-      ".size\t" __STRINGIFY(name) ",.""-" __STRINGIFY(name) "\n"      \
+-      )
++/* Define a macro which expands inline into the wrapper code for a system
++   call. This use is for internal calls that do not need to handle errors
++   normally. It will never touch errno.
++   On powerpc a system call basically clobbers the same registers like a
++   function call, with the exception of LR (which is needed for the
++   "sc; bnslr+" sequence) and CR (where only CR0.SO is clobbered to signal
++   an error return status).  */
++
++# undef INTERNAL_SYSCALL_DECL
++# define INTERNAL_SYSCALL_DECL(err) long int err
++
++# undef INTERNAL_SYSCALL
++# define INTERNAL_SYSCALL_NCS(name, err, nr, args...)                 \
++  ({                                                                  \
++    register long int r0  __asm__ ("r0");                             \
++    register long int r3  __asm__ ("r3");                             \
++    register long int r4  __asm__ ("r4");                             \
++    register long int r5  __asm__ ("r5");                             \
++    register long int r6  __asm__ ("r6");                             \
++    register long int r7  __asm__ ("r7");                             \
++    register long int r8  __asm__ ("r8");                             \
++    register long int r9  __asm__ ("r9");                             \
++    register long int r10 __asm__ ("r10");                            \
++    register long int r11 __asm__ ("r11");                            \
++    register long int r12 __asm__ ("r12");                            \
++    LOADARGS_##nr(name, args);                                                \
++    __asm__ __volatile__                                              \
++      ("sc   \n\t"                                                    \
++       "mfcr %0"                                                      \
++       : "=&r" (r0),                                                  \
++       "=&r" (r3), "=&r" (r4), "=&r" (r5),  "=&r" (r6),  "=&r" (r7),  \
++       "=&r" (r8), "=&r" (r9), "=&r" (r10), "=&r" (r11), "=&r" (r12)  \
++       : ASM_INPUT_##nr                                                       \
++       : "cr0", "ctr", "memory");                                     \
++    err = r0;                                                         \
++    (int) r3;                                                         \
++  })
++# define INTERNAL_SYSCALL(name, err, nr, args...) \
++  INTERNAL_SYSCALL_NCS (__NR_##name, err, nr, ##args)
++
++# undef INTERNAL_SYSCALL_ERROR_P
++# define INTERNAL_SYSCALL_ERROR_P(val, err) \
++  ((void) (val), __builtin_expect ((err) & (1 << 28), 0))
++
++# undef INTERNAL_SYSCALL_ERRNO
++# define INTERNAL_SYSCALL_ERRNO(val, err)     (val)
++
++# define LOADARGS_0(name, dummy) \
++      r0 = (long int)name
++# define LOADARGS_1(name, __arg1) \
++      LOADARGS_0(name, 0); \
++      r3 = (long int)__arg1
++# define LOADARGS_2(name, __arg1, __arg2) \
++      LOADARGS_1(name, __arg1); \
++      r4 = (long int)__arg2
++# define LOADARGS_3(name, __arg1, __arg2, __arg3) \
++      LOADARGS_2(name, __arg1, __arg2); \
++      r5 = (long int)__arg3
++# define LOADARGS_4(name, __arg1, __arg2, __arg3, __arg4) \
++      LOADARGS_3(name, __arg1, __arg2, __arg3); \
++      r6 = (long int)__arg4
++# define LOADARGS_5(name, __arg1, __arg2, __arg3, __arg4, __arg5) \
++      LOADARGS_4(name, __arg1, __arg2, __arg3, __arg4); \
++      r7 = (long int)__arg5
++# define LOADARGS_6(name, __arg1, __arg2, __arg3, __arg4, __arg5, __arg6) \
++      LOADARGS_5(name, __arg1, __arg2, __arg3, __arg4, __arg5); \
++      r8 = (long int)__arg6
++
++# define ASM_INPUT_0 "0" (r0)
++# define ASM_INPUT_1 ASM_INPUT_0, "1" (r3)
++# define ASM_INPUT_2 ASM_INPUT_1, "2" (r4)
++# define ASM_INPUT_3 ASM_INPUT_2, "3" (r5)
++# define ASM_INPUT_4 ASM_INPUT_3, "4" (r6)
++# define ASM_INPUT_5 ASM_INPUT_4, "5" (r7)
++# define ASM_INPUT_6 ASM_INPUT_5, "6" (r8)
+ #undef _syscall0
+-#define _syscall0(type,name)                          \
+-type name(void);                                      \
+-unified_syscall_body(name)
++#define _syscall0(type,name) \
++type name(void){ \
++  return (type) INLINE_SYSCALL(name, 0); \
++}
+ #undef _syscall1
+ #define _syscall1(type,name,type1,arg1) \
+-type name(type1 arg1);  \
+-unified_syscall_body(name)
++type name(type1 arg1){  \
++  return (type) INLINE_SYSCALL(name, 1, arg1); \
++}
+ #undef _syscall2
+ #define _syscall2(type,name,type1,arg1,type2,arg2) \
+-type name(type1 arg1, type2 arg2);      \
+-unified_syscall_body(name)
++type name(type1 arg1, type2 arg2){      \
++  return (type) INLINE_SYSCALL(name, 2, arg1, arg2); \
++}
+ #undef _syscall3
+ #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
+-type name(type1 arg1, type2 arg2, type3 arg3);  \
+-unified_syscall_body(name)
++type name(type1 arg1, type2 arg2, type3 arg3){  \
++  return (type) INLINE_SYSCALL(name, 3, arg1, arg2, arg3); \
++}
+ #undef _syscall4
+ #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
+-type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4);      \
+-unified_syscall_body(name)
++type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4){      \
++  return (type) INLINE_SYSCALL(name, 4, arg1, arg2, arg3, arg4); \
++}
+ #undef _syscall5
+ #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
+-type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5);  \
+-unified_syscall_body(name)
++type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5){  \
++  return (type) INLINE_SYSCALL(name, 5, arg1, arg2, arg3, arg4, arg5); \
++}
+ #undef _syscall6
+ #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \
+-type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6);      \
+-unified_syscall_body(name)
++type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6){      \
++  return (type) INLINE_SYSCALL(name, 6, arg1, arg2, arg3, arg4, arg5, arg6); \
++}
+ #endif /* _BITS_SYSCALLS_H */
diff --git a/toolchain/uClibc/uClibc-0.9.28-400-math-endianness.patch b/toolchain/uClibc/uClibc-0.9.28-400-math-endianness.patch
new file mode 100644 (file)
index 0000000..015f795
--- /dev/null
@@ -0,0 +1,247 @@
+Index: uclibc/libm/fp_private.h
+===================================================================
+--- uclibc/libm/fp_private.h   (revision 12879)
++++ uclibc/libm/fp_private.h   (working copy)
+@@ -70,10 +70,11 @@
+ *******************************************************************************/
+ #include <stdint.h>
++#include <endian.h>
+ typedef struct                   /*      Hex representation of a double.      */
+       {
+-#if defined(__BIG_ENDIAN__)
++#if (__BYTE_ORDER == __BIG_ENDIAN)
+       uint32_t high;
+       uint32_t low;
+ #else
+Index: uclibc/libm/powerpc/s_ceil.c
+===================================================================
+--- uclibc/libm/powerpc/s_ceil.c       (revision 12879)
++++ uclibc/libm/powerpc/s_ceil.c       (working copy)
+@@ -21,13 +21,15 @@
+ *                                                                              *
+ *******************************************************************************/
++#include <endian.h>
++
+ static const double        twoTo52  = 4503599627370496.0;
+ static const unsigned long signMask = 0x80000000ul;
+ typedef union
+       {
+       struct {
+-#if defined(__BIG_ENDIAN__)
++#if (__BYTE_ORDER == __BIG_ENDIAN)
+       unsigned long int hi;
+       unsigned long int lo;
+ #else
+Index: uclibc/libm/powerpc/s_ldexp.c
+===================================================================
+--- uclibc/libm/powerpc/s_ldexp.c      (revision 12879)
++++ uclibc/libm/powerpc/s_ldexp.c      (working copy)
+@@ -21,11 +21,12 @@
+ #include <limits.h>
+ #include <math.h>
++#include <endian.h>
+ typedef union
+       {
+       struct {
+-#if defined(__BIG_ENDIAN__)
++#if (__BYTE_ORDER == __BIG_ENDIAN)
+         unsigned long int hi;
+         unsigned long int lo;
+ #else
+Index: uclibc/libm/powerpc/s_rint.c
+===================================================================
+--- uclibc/libm/powerpc/s_rint.c       (revision 12879)
++++ uclibc/libm/powerpc/s_rint.c       (working copy)
+@@ -46,13 +46,14 @@
+ #include <limits.h>
+ #include <math.h>
++#include <endian.h>
+ #define      SET_INVALID      0x01000000UL
+ typedef union
+       {
+       struct {
+-#if defined(__BIG_ENDIAN__)
++#if (__BYTE_ORDER == __BIG_ENDIAN)
+         unsigned long int hi;
+         unsigned long int lo;
+ #else
+Index: uclibc/libm/powerpc/s_floor.c
+===================================================================
+--- uclibc/libm/powerpc/s_floor.c      (revision 12879)
++++ uclibc/libm/powerpc/s_floor.c      (working copy)
+@@ -21,13 +21,15 @@
+ *                                                                              *
+ *******************************************************************************/
++#include <endian.h>
++
+ static const double        twoTo52  = 4503599627370496.0;
+ static const unsigned long signMask = 0x80000000ul;
+ typedef union
+       {
+       struct {
+-#if defined(__BIG_ENDIAN__)
++#if (__BYTE_ORDER == __BIG_ENDIAN)
+       unsigned long int hi;
+       unsigned long int lo;
+ #else
+Index: uclibc/libm/powerpc/s_logb.c
+===================================================================
+--- uclibc/libm/powerpc/s_logb.c       (revision 12879)
++++ uclibc/libm/powerpc/s_logb.c       (working copy)
+@@ -32,10 +32,12 @@
+ *     Standard 754.                                                            *
+ *******************************************************************************/
++#include <endian.h>
++
+ typedef union
+       {
+       struct {
+-#if defined(__BIG_ENDIAN__)
++#if (__BYTE_ORDER == __BIG_ENDIAN)
+         unsigned long int hi;
+         unsigned long int lo;
+ #else
+Index: uclibc/libm/powerpc/s_frexp.c
+===================================================================
+--- uclibc/libm/powerpc/s_frexp.c      (revision 12879)
++++ uclibc/libm/powerpc/s_frexp.c      (working copy)
+@@ -21,13 +21,14 @@
+ #include <limits.h>
+ #include <math.h>
++#include <endian.h>
+ static const double two54 =  1.80143985094819840000e+16; /* 0x43500000, 0x00000000 */
+ typedef union
+       {
+       struct {
+-#if defined(__BIG_ENDIAN__)
++#if (__BYTE_ORDER == __BIG_ENDIAN)
+         unsigned long int hi;
+         unsigned long int lo;
+ #else
+Index: uclibc/libm/powerpc/s_modf.c
+===================================================================
+--- uclibc/libm/powerpc/s_modf.c       (revision 12879)
++++ uclibc/libm/powerpc/s_modf.c       (working copy)
+@@ -45,13 +45,14 @@
+ #include <limits.h>
+ #include <math.h>
++#include <endian.h>
+ #define      SET_INVALID      0x01000000UL
+ typedef union
+       {
+       struct {
+-#if defined(__BIG_ENDIAN__)
++#if (__BYTE_ORDER == __BIG_ENDIAN)
+         unsigned long int hi;
+         unsigned long int lo;
+ #else
+Index: uclibc/libm/powerpc/w_scalb.c
+===================================================================
+--- uclibc/libm/powerpc/w_scalb.c      (revision 12879)
++++ uclibc/libm/powerpc/w_scalb.c      (working copy)
+@@ -19,10 +19,12 @@
+ **
+ ***********************************************************************/
++#include <endian.h>
++
+ typedef union
+       {
+       struct {
+-#if defined(__BIG_ENDIAN__)
++#if (__BYTE_ORDER == __BIG_ENDIAN)
+         unsigned long int hi;
+         unsigned long int lo;
+ #else
+Index: uclibc/libc/string/sh64/strcpy.S
+===================================================================
+--- uclibc/libc/string/sh64/strcpy.S   (revision 12879)
++++ uclibc/libc/string/sh64/strcpy.S   (working copy)
+@@ -6,7 +6,9 @@
+ !
+ ! SH5 code Copyright 2002 SuperH Ltd.
+-#ifdef __LITTLE_ENDIAN__
++#include <endian.h>
++
++#if __BYTE_ORDER == __LITTLE_ENDIAN
+ #define SHHI shlld
+ #define SHLO shlrd
+ #else
+@@ -67,7 +69,7 @@
+       add r5, r63, r4
+       addi r0, 8, r0
+ shortstring:
+-#ifndef __LITTLE_ENDIAN__
++#if __BYTE_ORDER != __LITTLE_ENDIAN
+       pta/l shortstring2,tr1
+       byterev r4,r4
+ #endif
+Index: uclibc/libc/string/sh64/memset.S
+===================================================================
+--- uclibc/libc/string/sh64/memset.S   (revision 12879)
++++ uclibc/libc/string/sh64/memset.S   (working copy)
+@@ -9,7 +9,9 @@
+ ! Copyright 2002 SuperH Ltd.
+ !
+-#ifdef __LITTLE_ENDIAN__
++#include <endian.h>
++
++#if __BYTE_ORDER == __LITTLE_ENDIAN
+ #define SHHI shlld
+ #define SHLO shlrd
+ #else
+Index: uclibc/libc/sysdeps/linux/sh/bits/kernel_stat.h
+===================================================================
+--- uclibc/libc/sysdeps/linux/sh/bits/kernel_stat.h    (revision 12879)
++++ uclibc/libc/sysdeps/linux/sh/bits/kernel_stat.h    (working copy)
+@@ -30,10 +30,10 @@
+ };
+ struct kernel_stat64 {
+-#if defined(__BIG_ENDIAN__)
++#if (__BYTE_ORDER == __BIG_ENDIAN)
+       unsigned char   __pad0b[6];
+       unsigned short  st_dev;
+-#elif defined(__LITTLE_ENDIAN__)
++#elif (__BYTE_ORDER == __LITTLE_ENDIAN)
+       unsigned short  st_dev;
+       unsigned char   __pad0b[6];
+ #else
+@@ -48,7 +48,7 @@
+       unsigned long   st_uid;
+       unsigned long   st_gid;
+-#if defined(__BIG_ENDIAN__)
++#if (__BYTE_ORDER == __BIG_ENDIAN)
+       unsigned char   __pad3b[6];
+       unsigned short  st_rdev;
+ #else /* Must be little */
+@@ -60,7 +60,7 @@
+       long long       st_size;
+       unsigned long   st_blksize;
+-#if defined(__BIG_ENDIAN__)
++#if (__BYTE_ORDER == __BIG_ENDIAN)
+       unsigned long   __pad4;         /* Future possible st_blocks hi bits */
+       unsigned long   st_blocks;      /* Number 512-byte blocks allocated. */
+ #else /* Must be little */
diff --git a/toolchain/uClibc/uClibc-0.9.28-500-mutex-cancel.patch b/toolchain/uClibc/uClibc-0.9.28-500-mutex-cancel.patch
new file mode 100644 (file)
index 0000000..5e56a73
--- /dev/null
@@ -0,0 +1,8631 @@
+diff --git a/include/printf.h b/include/printf.h
+index 340b6cb..2dea58f 100644
+--- a/include/printf.h
++++ b/include/printf.h
+@@ -75,6 +75,7 @@ struct printf_info
+   unsigned int is_short:1;    /* h flag.  */
+   unsigned int is_long:1;     /* l flag.  */
+   unsigned int is_long_double:1;/* L flag.  */
++  unsigned int __padding:20;/* non-gnu -- total of 32 bits on 32bit arch */
+ #elif __BYTE_ORDER == __BIG_ENDIAN
+diff --git a/include/pthread.h b/include/pthread.h
+index 8c01172..cee112b 100644
+--- a/include/pthread.h
++++ b/include/pthread.h
+@@ -644,7 +644,8 @@ extern void _pthread_cleanup_pop (struct
+ /* Install a cleanup handler as pthread_cleanup_push does, but also
+    saves the current cancellation type and set it to deferred cancellation.  */
+-#ifdef __USE_GNU
++/* #ifdef __USE_GNU */
++#if defined(__USE_GNU) || defined(_LIBC)
+ # define pthread_cleanup_push_defer_np(routine,arg) \
+   { struct _pthread_cleanup_buffer _buffer;                                 \
+     _pthread_cleanup_push_defer (&_buffer, (routine), (arg));
+diff --git a/libc/inet/getnetent.c b/libc/inet/getnetent.c
+index 181c5ad..659bf5d 100644
+--- a/libc/inet/getnetent.c
++++ b/libc/inet/getnetent.c
+@@ -22,18 +22,9 @@
+ #include <netdb.h>
+ #include <arpa/inet.h>
++#include <bits/uClibc_mutex.h>
+-#ifdef __UCLIBC_HAS_THREADS__
+-#include <pthread.h>
+-static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;
+-# define LOCK __pthread_mutex_lock(&mylock)
+-# define UNLOCK       __pthread_mutex_unlock(&mylock);
+-#else
+-# define LOCK
+-# define UNLOCK
+-#endif
+-
+-
++__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER);
+ #define       MAXALIASES      35
+ static const char NETDB[] = _PATH_NETWORKS;
+@@ -46,25 +37,25 @@ int _net_stayopen;
+ void setnetent(int f)
+ {
+-    LOCK;
++    __UCLIBC_MUTEX_LOCK(mylock);
+     if (netf == NULL)
+-      netf = fopen(NETDB, "r" );
++              netf = fopen(NETDB, "r" );
+     else
+-      rewind(netf);
++              rewind(netf);
+     _net_stayopen |= f;
+-    UNLOCK;
++    __UCLIBC_MUTEX_UNLOCK(mylock);
+     return;
+ }
+ void endnetent(void)
+ {
+-    LOCK;
++    __UCLIBC_MUTEX_LOCK(mylock);
+     if (netf) {
+-      fclose(netf);
+-      netf = NULL;
++              fclose(netf);
++              netf = NULL;
+     }
+     _net_stayopen = 0;
+-    UNLOCK;
++    __UCLIBC_MUTEX_UNLOCK(mylock);
+ }
+ static char * any(register char *cp, char *match)
+@@ -72,10 +63,10 @@ static char * any(register char *cp, cha
+     register char *mp, c;
+     while ((c = *cp)) {
+-      for (mp = match; *mp; mp++)
+-          if (*mp == c)
+-              return (cp);
+-      cp++;
++              for (mp = match; *mp; mp++)
++                      if (*mp == c)
++                              return (cp);
++              cp++;
+     }
+     return ((char *)0);
+ }
+@@ -84,59 +75,62 @@ struct netent * getnetent(void)
+ {
+     char *p;
+     register char *cp, **q;
++      struct netent *rv = NULL;
+-    LOCK;
++    __UCLIBC_MUTEX_LOCK(mylock);
+     if (netf == NULL && (netf = fopen(NETDB, "r" )) == NULL) {
+-      UNLOCK;
+-      return (NULL);
++              goto DONE;
+     }
+-again:
++ again:
+     if (!line) {
+-      line = malloc(BUFSIZ + 1);
+-      if (!line)
+-          abort();
++              line = malloc(BUFSIZ + 1);
++              if (!line)
++                      abort();
+     }
+     p = fgets(line, BUFSIZ, netf);
+     if (p == NULL) {
+-      UNLOCK;
+-      return (NULL);
++              goto DONE;
+     }
+     if (*p == '#')
+-      goto again;
++              goto again;
+     cp = any(p, "#\n");
+     if (cp == NULL)
+-      goto again;
++              goto again;
+     *cp = '\0';
+     net.n_name = p;
+     cp = any(p, " \t");
+     if (cp == NULL)
+-      goto again;
++              goto again;
+     *cp++ = '\0';
+     while (*cp == ' ' || *cp == '\t')
+-      cp++;
++              cp++;
+     p = any(cp, " \t");
+     if (p != NULL)
+-      *p++ = '\0';
++              *p++ = '\0';
+     net.n_net = inet_network(cp);
+     net.n_addrtype = AF_INET;
+     q = net.n_aliases = net_aliases;
+     if (p != NULL)
+-      cp = p;
++              cp = p;
+     while (cp && *cp) {
+-      if (*cp == ' ' || *cp == '\t') {
+-          cp++;
+-          continue;
+-      }
+-      if (q < &net_aliases[MAXALIASES - 1])
+-          *q++ = cp;
+-      cp = any(cp, " \t");
+-      if (cp != NULL)
+-          *cp++ = '\0';
++              if (*cp == ' ' || *cp == '\t') {
++                      cp++;
++                      continue;
++              }
++              if (q < &net_aliases[MAXALIASES - 1])
++                      *q++ = cp;
++              cp = any(cp, " \t");
++              if (cp != NULL)
++                      *cp++ = '\0';
+     }
+     *q = NULL;
+-    UNLOCK;
+-    return (&net);
++
++      rv = &net;
++
++ DONE:
++    __UCLIBC_MUTEX_UNLOCK(mylock);
++    return rv;
+ }
+diff --git a/libc/inet/getproto.c b/libc/inet/getproto.c
+index c9f35f1..3665d89 100644
+--- a/libc/inet/getproto.c
++++ b/libc/inet/getproto.c
+@@ -62,17 +62,9 @@
+ #include <string.h>
+ #include <errno.h>
+-#ifdef __UCLIBC_HAS_THREADS__
+-#include <pthread.h>
+-static pthread_mutex_t mylock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+-# define LOCK __pthread_mutex_lock(&mylock)
+-# define UNLOCK       __pthread_mutex_unlock(&mylock);
+-#else
+-# define LOCK
+-# define UNLOCK
+-#endif
+-
++#include <bits/uClibc_mutex.h>
++__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);
+ #define       MAXALIASES      35
+ #define       SBUFSIZE        (BUFSIZ + 1 + (sizeof(char *) * MAXALIASES))
+@@ -85,109 +77,114 @@ static int proto_stayopen;
+ static void __initbuf(void)
+ {
+     if (!static_aliases) {
+-      static_aliases = malloc(SBUFSIZE);
+-      if (!static_aliases)
+-          abort();
++              static_aliases = malloc(SBUFSIZE);
++              if (!static_aliases)
++                      abort();
+     }
+ }
+ void setprotoent(int f)
+ {
+-    LOCK;
++    __UCLIBC_MUTEX_LOCK(mylock);
+     if (protof == NULL)
+-      protof = fopen(_PATH_PROTOCOLS, "r" );
++              protof = fopen(_PATH_PROTOCOLS, "r" );
+     else
+-      rewind(protof);
++              rewind(protof);
+     proto_stayopen |= f;
+-    UNLOCK;
++    __UCLIBC_MUTEX_UNLOCK(mylock);
+ }
+ void endprotoent(void)
+ {
+-    LOCK;
++    __UCLIBC_MUTEX_LOCK(mylock);
+     if (protof) {
+-      fclose(protof);
+-      protof = NULL;
++              fclose(protof);
++              protof = NULL;
+     }
+     proto_stayopen = 0;
+-    UNLOCK;
++    __UCLIBC_MUTEX_UNLOCK(mylock);
+ }
+ int getprotoent_r(struct protoent *result_buf,
+-                char *buf, size_t buflen,
+-                struct protoent **result)
++                                char *buf, size_t buflen,
++                                struct protoent **result)
+ {
+     char *p;
+     register char *cp, **q;
+     char **proto_aliases;
+     char *line;
++      int rv;
+     *result = NULL;
+     if (buflen < sizeof(*proto_aliases)*MAXALIASES) {
+-      errno=ERANGE;
+-      return errno;
++              errno=ERANGE;
++              return errno;
+     }
+-    LOCK;
++
++    __UCLIBC_MUTEX_LOCK(mylock);
+     proto_aliases=(char **)buf;
+     buf+=sizeof(*proto_aliases)*MAXALIASES;
+     buflen-=sizeof(*proto_aliases)*MAXALIASES;
+     if (buflen < BUFSIZ+1) {
+-      UNLOCK;
+-      errno=ERANGE;
+-      return errno;
++              errno=rv=ERANGE;
++              goto DONE;
+     }
+     line=buf;
+     buf+=BUFSIZ+1;
+     buflen-=BUFSIZ+1;
+     if (protof == NULL && (protof = fopen(_PATH_PROTOCOLS, "r" )) == NULL) {
+-      UNLOCK;
+-      return errno;
++              rv=errno;
++              goto DONE;
+     }
+-again:
++ again:
+     if ((p = fgets(line, BUFSIZ, protof)) == NULL) {
+-      UNLOCK;
+-      return TRY_AGAIN;
++              rv=TRY_AGAIN;
++              goto DONE;
+     }
+     if (*p == '#')
+-      goto again;
++              goto again;
+     cp = strpbrk(p, "#\n");
+     if (cp == NULL)
+-      goto again;
++              goto again;
+     *cp = '\0';
+     result_buf->p_name = p;
+     cp = strpbrk(p, " \t");
+     if (cp == NULL)
+-      goto again;
++              goto again;
+     *cp++ = '\0';
+     while (*cp == ' ' || *cp == '\t')
+-      cp++;
++              cp++;
+     p = strpbrk(cp, " \t");
+     if (p != NULL)
+-      *p++ = '\0';
++              *p++ = '\0';
+     result_buf->p_proto = atoi(cp);
+     q = result_buf->p_aliases = proto_aliases;
+     if (p != NULL) {
+-      cp = p;
+-      while (cp && *cp) {
+-          if (*cp == ' ' || *cp == '\t') {
+-              cp++;
+-              continue;
+-          }
+-          if (q < &proto_aliases[MAXALIASES - 1])
+-              *q++ = cp;
+-          cp = strpbrk(cp, " \t");
+-          if (cp != NULL)
+-              *cp++ = '\0';
+-      }
++              cp = p;
++              while (cp && *cp) {
++                      if (*cp == ' ' || *cp == '\t') {
++                              cp++;
++                              continue;
++                      }
++                      if (q < &proto_aliases[MAXALIASES - 1])
++                              *q++ = cp;
++                      cp = strpbrk(cp, " \t");
++                      if (cp != NULL)
++                              *cp++ = '\0';
++              }
+     }
+     *q = NULL;
+     *result=result_buf;
+-    UNLOCK;
+-    return 0;
++
++      rv = 0;
++
++ DONE:
++    __UCLIBC_MUTEX_UNLOCK(mylock);
++    return rv;
+ }
+ struct protoent * getprotoent(void)
+@@ -201,26 +198,26 @@ struct protoent * getprotoent(void)
+ int getprotobyname_r(const char *name,
+-                  struct protoent *result_buf,
+-                  char *buf, size_t buflen,
+-                  struct protoent **result)
++                                       struct protoent *result_buf,
++                                       char *buf, size_t buflen,
++                                       struct protoent **result)
+ {
+     register char **cp;
+     int ret;
+-    LOCK;
++    __UCLIBC_MUTEX_LOCK(mylock);
+     setprotoent(proto_stayopen);
+     while (!(ret=getprotoent_r(result_buf, buf, buflen, result))) {
+-      if (strcmp(result_buf->p_name, name) == 0)
+-          break;
+-      for (cp = result_buf->p_aliases; *cp != 0; cp++)
+-          if (strcmp(*cp, name) == 0)
+-              goto found;
++              if (strcmp(result_buf->p_name, name) == 0)
++                      break;
++              for (cp = result_buf->p_aliases; *cp != 0; cp++)
++                      if (strcmp(*cp, name) == 0)
++                              goto found;
+     }
+-found:
++ found:
+     if (!proto_stayopen)
+-      endprotoent();
+-    UNLOCK;
++              endprotoent();
++    __UCLIBC_MUTEX_UNLOCK(mylock);
+     return *result?0:ret;
+ }
+@@ -236,20 +233,20 @@ struct protoent * getprotobyname(const c
+ int getprotobynumber_r (int proto_num,
+-                      struct protoent *result_buf,
+-                      char *buf, size_t buflen,
+-                      struct protoent **result)
++                                              struct protoent *result_buf,
++                                              char *buf, size_t buflen,
++                                              struct protoent **result)
+ {
+     int ret;
+-    LOCK;
++    __UCLIBC_MUTEX_LOCK(mylock);
+     setprotoent(proto_stayopen);
+     while (!(ret=getprotoent_r(result_buf, buf, buflen, result)))
+-      if (result_buf->p_proto == proto_num)
+-          break;
++              if (result_buf->p_proto == proto_num)
++                      break;
+     if (!proto_stayopen)
+-      endprotoent();
+-    UNLOCK;
++              endprotoent();
++    __UCLIBC_MUTEX_UNLOCK(mylock);
+     return *result?0:ret;
+ }
+diff --git a/libc/inet/getservice.c b/libc/inet/getservice.c
+index cbe5c50..b666057 100644
+--- a/libc/inet/getservice.c
++++ b/libc/inet/getservice.c
+@@ -65,20 +65,9 @@
+ #include <arpa/inet.h>
+ #include <errno.h>
++#include <bits/uClibc_mutex.h>
+-
+-#ifdef __UCLIBC_HAS_THREADS__
+-#include <pthread.h>
+-static pthread_mutex_t mylock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+-# define LOCK __pthread_mutex_lock(&mylock)
+-# define UNLOCK       __pthread_mutex_unlock(&mylock);
+-#else
+-# define LOCK
+-# define UNLOCK
+-#endif
+-
+-
+-
++__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);
+ #define       MAXALIASES      35
+ #define SBUFSIZE      (BUFSIZ + 1 + (sizeof(char *) * MAXALIASES))
+@@ -91,32 +80,32 @@ static int serv_stayopen;
+ static void __initbuf(void)
+ {
+     if (!servbuf) {
+-      servbuf = malloc(SBUFSIZE);
+-      if (!servbuf)
+-          abort();
++              servbuf = malloc(SBUFSIZE);
++              if (!servbuf)
++                      abort();
+     }
+ }
+ void setservent(int f)
+ {
+-    LOCK;
++    __UCLIBC_MUTEX_LOCK(mylock);
+     if (servf == NULL)
+-      servf = fopen(_PATH_SERVICES, "r" );
++              servf = fopen(_PATH_SERVICES, "r" );
+     else
+-      rewind(servf);
++              rewind(servf);
+     serv_stayopen |= f;
+-    UNLOCK;
++    __UCLIBC_MUTEX_UNLOCK(mylock);
+ }
+ void endservent(void)
+ {
+-    LOCK;
++    __UCLIBC_MUTEX_LOCK(mylock);
+     if (servf) {
+-      fclose(servf);
+-      servf = NULL;
++              fclose(servf);
++              servf = NULL;
+     }
+     serv_stayopen = 0;
+-    UNLOCK;
++    __UCLIBC_MUTEX_UNLOCK(mylock);
+ }
+ struct servent * getservent(void)
+@@ -149,127 +138,129 @@ struct servent * getservbyport(int port,
+ }
+ int getservent_r(struct servent * result_buf,
+-               char * buf, size_t buflen,
+-               struct servent ** result)
++                               char * buf, size_t buflen,
++                               struct servent ** result)
+ {
+     char *p;
+     register char *cp, **q;
+     char **serv_aliases;
+     char *line;
++      int rv;
+     *result=NULL;
+     if (buflen < sizeof(*serv_aliases)*MAXALIASES) {
+-      errno=ERANGE;
+-      return errno;
++              errno=ERANGE;
++              return errno;
+     }
+-    LOCK;
++    __UCLIBC_MUTEX_LOCK(mylock);
+     serv_aliases=(char **)buf;
+     buf+=sizeof(*serv_aliases)*MAXALIASES;
+     buflen-=sizeof(*serv_aliases)*MAXALIASES;
+     if (buflen < BUFSIZ+1) {
+-      UNLOCK;
+-      errno=ERANGE;
+-      return errno;
++              errno=rv=ERANGE;
++              goto DONE;
+     }
+     line=buf;
+     buf+=BUFSIZ+1;
+     buflen-=BUFSIZ+1;
+     if (servf == NULL && (servf = fopen(_PATH_SERVICES, "r" )) == NULL) {
+-      UNLOCK;
+-      errno=EIO;
+-      return errno;
++              errno=rv=EIO;
++              goto DONE;
+     }
+-again:
++ again:
+     if ((p = fgets(line, BUFSIZ, servf)) == NULL) {
+-      UNLOCK;
+-      errno=EIO;
+-      return errno;
++              errno=rv=EIO;
++              goto DONE;
+     }
+     if (*p == '#')
+-      goto again;
++              goto again;
+     cp = strpbrk(p, "#\n");
+     if (cp == NULL)
+-      goto again;
++              goto again;
+     *cp = '\0';
+     result_buf->s_name = p;
+     p = strpbrk(p, " \t");
+     if (p == NULL)
+-      goto again;
++              goto again;
+     *p++ = '\0';
+     while (*p == ' ' || *p == '\t')
+-      p++;
++              p++;
+     cp = strpbrk(p, ",/");
+     if (cp == NULL)
+-      goto again;
++              goto again;
+     *cp++ = '\0';
+     result_buf->s_port = htons((u_short)atoi(p));
+     result_buf->s_proto = cp;
+     q = result_buf->s_aliases = serv_aliases;
+     cp = strpbrk(cp, " \t");
+     if (cp != NULL)
+-      *cp++ = '\0';
++              *cp++ = '\0';
+     while (cp && *cp) {
+-      if (*cp == ' ' || *cp == '\t') {
+-          cp++;
+-          continue;
+-      }
+-      if (q < &serv_aliases[MAXALIASES - 1])
+-          *q++ = cp;
+-      cp = strpbrk(cp, " \t");
+-      if (cp != NULL)
+-          *cp++ = '\0';
++              if (*cp == ' ' || *cp == '\t') {
++                      cp++;
++                      continue;
++              }
++              if (q < &serv_aliases[MAXALIASES - 1])
++                      *q++ = cp;
++              cp = strpbrk(cp, " \t");
++              if (cp != NULL)
++                      *cp++ = '\0';
+     }
+     *q = NULL;
+     *result=result_buf;
+-    UNLOCK;
+-    return 0;
++
++      rv = 0;
++
++ DONE:
++    __UCLIBC_MUTEX_UNLOCK(mylock);
++    return rv;
+ }
+ int getservbyname_r(const char *name, const char *proto,
+-      struct servent * result_buf, char * buf, size_t buflen,
+-      struct servent ** result)
++                                      struct servent * result_buf, char * buf, size_t buflen,
++                                      struct servent ** result)
+ {
+     register char **cp;
+     int ret;
+-    LOCK;
++    __UCLIBC_MUTEX_LOCK(mylock);
+     setservent(serv_stayopen);
+     while (!(ret=getservent_r(result_buf, buf, buflen, result))) {
+-      if (strcmp(name, result_buf->s_name) == 0)
+-          goto gotname;
+-      for (cp = result_buf->s_aliases; *cp; cp++)
+-          if (strcmp(name, *cp) == 0)
+-              goto gotname;
+-      continue;
+-gotname:
+-      if (proto == 0 || strcmp(result_buf->s_proto, proto) == 0)
+-          break;
++              if (strcmp(name, result_buf->s_name) == 0)
++                      goto gotname;
++              for (cp = result_buf->s_aliases; *cp; cp++)
++                      if (strcmp(name, *cp) == 0)
++                              goto gotname;
++              continue;
++      gotname:
++              if (proto == 0 || strcmp(result_buf->s_proto, proto) == 0)
++                      break;
+     }
+     if (!serv_stayopen)
+-      endservent();
+-    UNLOCK;
++              endservent();
++    __UCLIBC_MUTEX_UNLOCK(mylock);
+     return *result?0:ret;
+ }
+ int getservbyport_r(int port, const char *proto,
+-      struct servent * result_buf, char * buf,
+-      size_t buflen, struct servent ** result)
++                                      struct servent * result_buf, char * buf,
++                                      size_t buflen, struct servent ** result)
+ {
+     int ret;
+-    LOCK;
++    __UCLIBC_MUTEX_LOCK(mylock);
+     setservent(serv_stayopen);
+     while (!(ret=getservent_r(result_buf, buf, buflen, result))) {
+-      if (result_buf->s_port != port)
+-          continue;
+-      if (proto == 0 || strcmp(result_buf->s_proto, proto) == 0)
+-          break;
++              if (result_buf->s_port != port)
++                      continue;
++              if (proto == 0 || strcmp(result_buf->s_proto, proto) == 0)
++                      break;
+     }
+     if (!serv_stayopen)
+-      endservent();
+-    UNLOCK;
++              endservent();
++    __UCLIBC_MUTEX_UNLOCK(mylock);
+     return *result?0:ret;
+ }
+diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c
+index 27b60ef..0f583ab 100644
+--- a/libc/inet/resolv.c
++++ b/libc/inet/resolv.c
+@@ -7,7 +7,7 @@
+  * 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.
+-*/
++ */
+ /*
+  * Portions Copyright (c) 1985, 1993
+@@ -153,6 +153,11 @@
+ #include <sys/utsname.h>
+ #include <sys/un.h>
++#include <bits/uClibc_mutex.h>
++
++__UCLIBC_MUTEX_EXTERN(__resolv_lock);
++
++
+ #define MAX_RECURSE 5
+ #define REPLY_TIMEOUT 10
+ #define MAX_RETRIES 3
+@@ -180,18 +185,6 @@ extern char * __nameserver[MAX_SERVERS];
+ extern int __searchdomains;
+ extern char * __searchdomain[MAX_SEARCH];
+-#ifdef __UCLIBC_HAS_THREADS__
+-#include <pthread.h>
+-extern pthread_mutex_t __resolv_lock;
+-# define BIGLOCK      __pthread_mutex_lock(&__resolv_lock)
+-# define BIGUNLOCK    __pthread_mutex_unlock(&__resolv_lock);
+-#else
+-# define BIGLOCK
+-# define BIGUNLOCK
+-#endif
+-
+-
+-
+ /* Structs */
+ struct resolv_header {
+       int id;
+@@ -229,49 +222,49 @@ enum etc_hosts_action {
+ /* function prototypes */
+ extern int __get_hosts_byname_r(const char * name, int type,
+-                            struct hostent * result_buf,
+-                            char * buf, size_t buflen,
+-                            struct hostent ** result,
+-                            int * h_errnop);
++                                                              struct hostent * result_buf,
++                                                              char * buf, size_t buflen,
++                                                              struct hostent ** result,
++                                                              int * h_errnop);
+ extern int __get_hosts_byaddr_r(const char * addr, int len, int type,
+-                            struct hostent * result_buf,
+-                            char * buf, size_t buflen,
+-                            struct hostent ** result,
+-                            int * h_errnop);
++                                                              struct hostent * result_buf,
++                                                              char * buf, size_t buflen,
++                                                              struct hostent ** result,
++                                                              int * h_errnop);
+ extern void __open_etc_hosts(FILE **fp);
+ extern int __read_etc_hosts_r(FILE *fp, const char * name, int type,
+-                          enum etc_hosts_action action,
+-                          struct hostent * result_buf,
+-                          char * buf, size_t buflen,
+-                          struct hostent ** result,
+-                          int * h_errnop);
++                                                        enum etc_hosts_action action,
++                                                        struct hostent * result_buf,
++                                                        char * buf, size_t buflen,
++                                                        struct hostent ** result,
++                                                        int * h_errnop);
+ extern int __dns_lookup(const char * name, int type, int nscount,
+-      char ** nsip, unsigned char ** outpacket, struct resolv_answer * a);
++                                              char ** nsip, unsigned char ** outpacket, struct resolv_answer * a);
+ extern int __encode_dotted(const char * dotted, unsigned char * dest, int maxlen);
+ extern int __decode_dotted(const unsigned char * message, int offset,
+-      char * dest, int maxlen);
++                                                 char * dest, int maxlen);
+ extern int __length_dotted(const unsigned char * message, int offset);
+ extern int __encode_header(struct resolv_header * h, unsigned char * dest, int maxlen);
+ extern int __decode_header(unsigned char * data, struct resolv_header * h);
+ extern int __encode_question(struct resolv_question * q,
+-      unsigned char * dest, int maxlen);
++                                                       unsigned char * dest, int maxlen);
+ extern int __decode_question(unsigned char * message, int offset,
+-      struct resolv_question * q);
++                                                       struct resolv_question * q);
+ extern int __encode_answer(struct resolv_answer * a,
+-      unsigned char * dest, int maxlen);
++                                                 unsigned char * dest, int maxlen);
+ extern int __decode_answer(unsigned char * message, int offset,
+-      struct resolv_answer * a);
++                                                 struct resolv_answer * a);
+ extern int __length_question(unsigned char * message, int offset);
+ extern int __open_nameservers(void);
+ extern void __close_nameservers(void);
+ extern int __dn_expand(const u_char *, const u_char *, const u_char *,
+-      char *, int);
++                                         char *, int);
+ extern int __ns_name_uncompress(const u_char *, const u_char *,
+-              const u_char *, char *, size_t);
++                                                              const u_char *, char *, size_t);
+ extern int __ns_name_ntop(const u_char *, char *, size_t);
+ extern int __ns_name_unpack(const u_char *, const u_char *, const u_char *,
+-               u_char *, size_t);
++                                                      u_char *, size_t);
+ #ifdef L_encodeh
+@@ -361,7 +354,7 @@ int __encode_dotted(const char *dotted, 
+    This routine understands compressed data. */
+ int __decode_dotted(const unsigned char *data, int offset,
+-                                char *dest, int maxlen)
++                                      char *dest, int maxlen)
+ {
+       int l;
+       int measure = 1;
+@@ -435,7 +428,7 @@ int __length_dotted(const unsigned char 
+ #ifdef L_encodeq
+ int __encode_question(struct resolv_question *q,
+-                                      unsigned char *dest, int maxlen)
++                                        unsigned char *dest, int maxlen)
+ {
+       int i;
+@@ -460,7 +453,7 @@ int __encode_question(struct resolv_ques
+ #ifdef L_decodeq
+ int __decode_question(unsigned char *message, int offset,
+-                                      struct resolv_question *q)
++                                        struct resolv_question *q)
+ {
+       char temp[256];
+       int i;
+@@ -525,7 +518,7 @@ int __encode_answer(struct resolv_answer
+ #ifdef L_decodea
+ int __decode_answer(unsigned char *message, int offset,
+-                                struct resolv_answer *a)
++                                      struct resolv_answer *a)
+ {
+       char temp[256];
+       int i;
+@@ -557,11 +550,11 @@ int __decode_answer(unsigned char *messa
+ #ifdef L_encodep
+ int __encode_packet(struct resolv_header *h,
+-      struct resolv_question **q,
+-      struct resolv_answer **an,
+-      struct resolv_answer **ns,
+-      struct resolv_answer **ar,
+-      unsigned char *dest, int maxlen)
++                                      struct resolv_question **q,
++                                      struct resolv_answer **an,
++                                      struct resolv_answer **ns,
++                                      struct resolv_answer **ar,
++                                      unsigned char *dest, int maxlen)
+ {
+       int i, total = 0;
+       int j;
+@@ -621,7 +614,7 @@ int __decode_packet(unsigned char *data,
+ #ifdef L_formquery
+ int __form_query(int id, const char *name, int type, unsigned char *packet,
+-                         int maxlen)
++                               int maxlen)
+ {
+       struct resolv_header h;
+       struct resolv_question q;
+@@ -649,14 +642,7 @@ int __form_query(int id, const char *nam
+ #ifdef L_dnslookup
+-#ifdef __UCLIBC_HAS_THREADS__
+-static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;
+-# define LOCK __pthread_mutex_lock(&mylock)
+-# define UNLOCK       __pthread_mutex_unlock(&mylock);
+-#else
+-# define LOCK
+-# define UNLOCK
+-#endif
++__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER);
+ /* Just for the record, having to lock __dns_lookup() just for these two globals
+  * is pretty lame.  I think these two variables can probably be de-global-ized,
+@@ -665,7 +651,7 @@ static pthread_mutex_t mylock = PTHREAD_
+ static int ns=0, id=1;
+ int __dns_lookup(const char *name, int type, int nscount, char **nsip,
+-                         unsigned char **outpacket, struct resolv_answer *a)
++                               unsigned char **outpacket, struct resolv_answer *a)
+ {
+       int i, j, len, fd, pos, rc;
+       struct timeval tv;
+@@ -693,10 +679,10 @@ int __dns_lookup(const char *name, int t
+       DPRINTF("Looking up type %d answer for '%s'\n", type, name);
+       /* Mess with globals while under lock */
+-      LOCK;
++      __UCLIBC_MUTEX_LOCK(mylock);
+       local_ns = ns % nscount;
+       local_id = id;
+-      UNLOCK;
++      __UCLIBC_MUTEX_UNLOCK(mylock);
+       while (retries < MAX_RETRIES) {
+               if (fd != -1)
+@@ -722,13 +708,13 @@ int __dns_lookup(const char *name, int t
+               strncpy(lookup,name,MAXDNAME);
+               if (variant >= 0) {
+-                        BIGLOCK;
+-                        if (variant < __searchdomains) {
+-                                strncat(lookup,".", MAXDNAME);
+-                                strncat(lookup,__searchdomain[variant], MAXDNAME);
+-                        }
+-                        BIGUNLOCK;
+-                }
++                      __UCLIBC_MUTEX_LOCK(__resolv_lock);
++                      if (variant < __searchdomains) {
++                              strncat(lookup,".", MAXDNAME);
++                              strncat(lookup,__searchdomain[variant], MAXDNAME);
++                      }
++                      __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
++              }
+               DPRINTF("lookup name: %s\n", lookup);
+               q.dotted = (char *)lookup;
+               q.qtype = type;
+@@ -750,7 +736,7 @@ int __dns_lookup(const char *name, int t
+               fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ #endif
+               if (fd < 0) {
+-                    retries++;
++                      retries++;
+                   continue;
+               }
+@@ -772,11 +758,11 @@ int __dns_lookup(const char *name, int t
+ #endif
+               if (rc < 0) {
+                   if (errno == ENETUNREACH) {
+-                      /* routing error, presume not transient */
+-                      goto tryall;
++                              /* routing error, presume not transient */
++                              goto tryall;
+                   } else
+-                      /* retry */
+-                        retries++;
++                              /* retry */
++                              retries++;
+                       continue;
+               }
+@@ -838,55 +824,55 @@ int __dns_lookup(const char *name, int t
+               first_answer = 1;
+               for (j=0;j<h.ancount;j++,pos += i)
+-              {
+-                  i = __decode_answer(packet, pos, &ma);
++                      {
++                              i = __decode_answer(packet, pos, &ma);
+-                  if (i<0) {
+-                      DPRINTF("failed decode %d\n", i);
+-                      goto again;
+-                  }
++                              if (i<0) {
++                                      DPRINTF("failed decode %d\n", i);
++                                      goto again;
++                              }
+-                  if ( first_answer )
+-                  {
+-                      ma.buf = a->buf;
+-                      ma.buflen = a->buflen;
+-                      ma.add_count = a->add_count;
+-                      memcpy(a, &ma, sizeof(ma));
+-                      if (a->atype != T_SIG && (0 == a->buf || (type != T_A && type != T_AAAA)))
+-                      {
+-                          break;
+-                      }
+-                      if (a->atype != type)
+-                      {
+-                          free(a->dotted);
+-                          continue;
+-                      }
+-                      a->add_count = h.ancount - j - 1;
+-                      if ((a->rdlength + sizeof(struct in_addr*)) * a->add_count > a->buflen)
+-                      {
+-                          break;
+-                      }
+-                      a->add_count = 0;
+-                      first_answer = 0;
+-                  }
+-                  else
+-                  {
+-                      free(ma.dotted);
+-                      if (ma.atype != type)
+-                      {
+-                          continue;
+-                      }
+-                      if (a->rdlength != ma.rdlength)
+-                      {
+-                          free(a->dotted);
+-                          DPRINTF("Answer address len(%u) differs from original(%u)\n",
+-                                  ma.rdlength, a->rdlength);
+-                          goto again;
++                              if ( first_answer )
++                                      {
++                                              ma.buf = a->buf;
++                                              ma.buflen = a->buflen;
++                                              ma.add_count = a->add_count;
++                                              memcpy(a, &ma, sizeof(ma));
++                                              if (a->atype != T_SIG && (0 == a->buf || (type != T_A && type != T_AAAA)))
++                                                      {
++                                                              break;
++                                                      }
++                                              if (a->atype != type)
++                                                      {
++                                                              free(a->dotted);
++                                                              continue;
++                                                      }
++                                              a->add_count = h.ancount - j - 1;
++                                              if ((a->rdlength + sizeof(struct in_addr*)) * a->add_count > a->buflen)
++                                                      {
++                                                              break;
++                                                      }
++                                              a->add_count = 0;
++                                              first_answer = 0;
++                                      }
++                              else
++                                      {
++                                              free(ma.dotted);
++                                              if (ma.atype != type)
++                                                      {
++                                                              continue;
++                                                      }
++                                              if (a->rdlength != ma.rdlength)
++                                                      {
++                                                              free(a->dotted);
++                                                              DPRINTF("Answer address len(%u) differs from original(%u)\n",
++                                                                              ma.rdlength, a->rdlength);
++                                                              goto again;
++                                                      }
++                                              memcpy(a->buf + (a->add_count * ma.rdlength), ma.rdata, ma.rdlength);
++                                              ++a->add_count;
++                                      }
+                       }
+-                      memcpy(a->buf + (a->add_count * ma.rdlength), ma.rdata, ma.rdlength);
+-                      ++a->add_count;
+-                  }
+-              }
+               DPRINTF("Answer name = |%s|\n", a->dotted);
+               DPRINTF("Answer type = |%d|\n", a->atype);
+@@ -900,48 +886,48 @@ int __dns_lookup(const char *name, int t
+               free(lookup);
+               /* Mess with globals while under lock */
+-              LOCK;
++              __UCLIBC_MUTEX_LOCK(mylock);
+               ns = local_ns;
+               id = local_id;
+-              UNLOCK;
++              __UCLIBC_MUTEX_UNLOCK(mylock);
+               return (len);                           /* success! */
+-        tryall:
++      tryall:
+               /* if there are other nameservers, give them a go,
+                  otherwise return with error */
+               {
+                   variant = -1;
+-                    local_ns = (local_ns + 1) % nscount;
+-                    if (local_ns == 0)
+-                      retries++;
++                      local_ns = (local_ns + 1) % nscount;
++                      if (local_ns == 0)
++                              retries++;
+-                    continue;
++                      continue;
+               }
+-        again:
++      again:
+               /* if there are searchdomains, try them or fallback as passed */
+               {
+                   int sdomains;
+-                  BIGLOCK;
++                  __UCLIBC_MUTEX_LOCK(__resolv_lock);
+                   sdomains=__searchdomains;
+-                  BIGUNLOCK;
++                  __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
+                   if (variant < sdomains - 1) {
+-                      /* next search */
+-                      variant++;
++                              /* next search */
++                              variant++;
+                   } else {
+-                      /* next server, first search */
+-                      local_ns = (local_ns + 1) % nscount;
+-                        if (local_ns == 0)
+-                          retries++;
++                              /* next server, first search */
++                              local_ns = (local_ns + 1) % nscount;
++                              if (local_ns == 0)
++                                      retries++;
+-                      variant = -1;
++                              variant = -1;
+                   }
+               }
+       }
+-fail:
++ fail:
+       if (fd != -1)
+           close(fd);
+       if (lookup)
+@@ -951,10 +937,10 @@ fail:
+       h_errno = NETDB_INTERNAL;
+       /* Mess with globals while under lock */
+       if (local_ns != -1) {
+-          LOCK;
++          __UCLIBC_MUTEX_LOCK(mylock);
+           ns = local_ns;
+           id = local_id;
+-          UNLOCK;
++          __UCLIBC_MUTEX_UNLOCK(mylock);
+       }
+       return -1;
+ }
+@@ -966,9 +952,8 @@ int __nameservers;
+ char * __nameserver[MAX_SERVERS];
+ int __searchdomains;
+ char * __searchdomain[MAX_SEARCH];
+-#ifdef __UCLIBC_HAS_THREADS__
+-pthread_mutex_t __resolv_lock = PTHREAD_MUTEX_INITIALIZER;
+-#endif
++
++__UCLIBC_MUTEX_INIT(__resolv_lock, PTHREAD_MUTEX_INITIALIZER);
+ /*
+  *    we currently read formats not quite the same as that on normal
+@@ -982,60 +967,63 @@ int __open_nameservers()
+ #define RESOLV_ARGS 5
+       char szBuffer[128], *p, *argv[RESOLV_ARGS];
+       int argc;
++      int rv = 0;
+-      BIGLOCK;
++      __UCLIBC_MUTEX_LOCK(__resolv_lock);
+       if (__nameservers > 0) {
+-          BIGUNLOCK;
+-          return 0;
++              goto DONE;
+       }
+       if ((fp = fopen("/etc/resolv.conf", "r")) ||
+-                      (fp = fopen("/etc/config/resolv.conf", "r")))
+-      {
+-
+-              while (fgets(szBuffer, sizeof(szBuffer), fp) != NULL) {
++              (fp = fopen("/etc/config/resolv.conf", "r")))
++              {
+-                      for (p = szBuffer; *p && isspace(*p); p++)
+-                              /* skip white space */;
+-                      if (*p == '\0' || *p == '\n' || *p == '#') /* skip comments etc */
+-                              continue;
+-                      argc = 0;
+-                      while (*p && argc < RESOLV_ARGS) {
+-                              argv[argc++] = p;
+-                              while (*p && !isspace(*p) && *p != '\n')
+-                                      p++;
+-                              while (*p && (isspace(*p) || *p == '\n')) /* remove spaces */
+-                                      *p++ = '\0';
+-                      }
++                      while (fgets(szBuffer, sizeof(szBuffer), fp) != NULL) {
+-                      if (strcmp(argv[0], "nameserver") == 0) {
+-                              for (i = 1; i < argc && __nameservers < MAX_SERVERS; i++) {
+-                                      __nameserver[__nameservers++] = strdup(argv[i]);
+-                                      DPRINTF("adding nameserver %s\n", argv[i]);
++                              for (p = szBuffer; *p && isspace(*p); p++)
++                                      /* skip white space */;
++                              if (*p == '\0' || *p == '\n' || *p == '#') /* skip comments etc */
++                                      continue;
++                              argc = 0;
++                              while (*p && argc < RESOLV_ARGS) {
++                                      argv[argc++] = p;
++                                      while (*p && !isspace(*p) && *p != '\n')
++                                              p++;
++                                      while (*p && (isspace(*p) || *p == '\n')) /* remove spaces */
++                                              *p++ = '\0';
+                               }
+-                      }
+-                      /* domain and search are mutually exclusive, the last one wins */
+-                      if (strcmp(argv[0],"domain")==0 || strcmp(argv[0],"search")==0) {
+-                              while (__searchdomains > 0) {
+-                                      free(__searchdomain[--__searchdomains]);
+-                                      __searchdomain[__searchdomains] = NULL;
++                              if (strcmp(argv[0], "nameserver") == 0) {
++                                      for (i = 1; i < argc && __nameservers < MAX_SERVERS; i++) {
++                                              __nameserver[__nameservers++] = strdup(argv[i]);
++                                              DPRINTF("adding nameserver %s\n", argv[i]);
++                                      }
+                               }
+-                              for (i=1; i < argc && __searchdomains < MAX_SEARCH; i++) {
+-                                      __searchdomain[__searchdomains++] = strdup(argv[i]);
+-                                      DPRINTF("adding search %s\n", argv[i]);
++
++                              /* domain and search are mutually exclusive, the last one wins */
++                              if (strcmp(argv[0],"domain")==0 || strcmp(argv[0],"search")==0) {
++                                      while (__searchdomains > 0) {
++                                              free(__searchdomain[--__searchdomains]);
++                                              __searchdomain[__searchdomains] = NULL;
++                                      }
++                                      for (i=1; i < argc && __searchdomains < MAX_SEARCH; i++) {
++                                              __searchdomain[__searchdomains++] = strdup(argv[i]);
++                                              DPRINTF("adding search %s\n", argv[i]);
++                                      }
+                               }
+                       }
++                      fclose(fp);
++                      DPRINTF("nameservers = %d\n", __nameservers);
++                      goto DONE;
+               }
+-              fclose(fp);
+-              DPRINTF("nameservers = %d\n", __nameservers);
+-              BIGUNLOCK;
+-              return 0;
+-      }
+       DPRINTF("failed to open %s\n", "resolv.conf");
+       h_errno = NO_RECOVERY;
+-      BIGUNLOCK;
+-      return -1;
++
++      rv = -1;
++
++ DONE:
++      __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
++      return rv;
+ }
+ #endif
+@@ -1044,7 +1032,7 @@ int __open_nameservers()
+ void __close_nameservers(void)
+ {
+-      BIGLOCK;
++      __UCLIBC_MUTEX_LOCK(__resolv_lock);
+       while (__nameservers > 0) {
+               free(__nameserver[--__nameservers]);
+               __nameserver[__nameservers] = NULL;
+@@ -1053,7 +1041,7 @@ void __close_nameservers(void)
+               free(__searchdomain[--__searchdomains]);
+               __searchdomain[__searchdomains] = NULL;
+       }
+-      BIGUNLOCK;
++      __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
+ }
+ #endif
+@@ -1063,8 +1051,8 @@ struct hostent *gethostbyname(const char
+ {
+       static struct hostent h;
+       static char buf[sizeof(struct in_addr) +
+-                      sizeof(struct in_addr *)*2 +
+-                      sizeof(char *)*(ALIAS_DIM) + 384/*namebuffer*/ + 32/* margin */];
++                                      sizeof(struct in_addr *)*2 +
++                                      sizeof(char *)*(ALIAS_DIM) + 384/*namebuffer*/ + 32/* margin */];
+       struct hostent *hp;
+       gethostbyname_r(name, &h, buf, sizeof(buf), &hp, &h_errno);
+@@ -1082,8 +1070,8 @@ struct hostent *gethostbyname2(const cha
+ #else /* __UCLIBC_HAS_IPV6__ */
+       static struct hostent h;
+       static char buf[sizeof(struct in6_addr) +
+-                      sizeof(struct in6_addr *)*2 +
+-                      sizeof(char *)*(ALIAS_DIM) + 384/*namebuffer*/ + 32/* margin */];
++                                      sizeof(struct in6_addr *)*2 +
++                                      sizeof(char *)*(ALIAS_DIM) + 384/*namebuffer*/ + 32/* margin */];
+       struct hostent *hp;
+       gethostbyname2_r(name, family, &h, buf, sizeof(buf), &hp, &h_errno);
+@@ -1119,7 +1107,7 @@ int res_init(void)
+       /** rp->rhook = NULL; **/
+       /** rp->_u._ext.nsinit = 0; **/
+-      BIGLOCK;
++      __UCLIBC_MUTEX_LOCK(__resolv_lock);
+       if(__searchdomains) {
+               int i;
+               for(i=0; i<__searchdomains; i++) {
+@@ -1139,7 +1127,7 @@ int res_init(void)
+               }
+       }
+       rp->nscount = __nameservers;
+-      BIGUNLOCK;
++      __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
+       return(0);
+ }
+@@ -1175,10 +1163,10 @@ int res_query(const char *dname, int cla
+       memset((char *) &a, '\0', sizeof(a));
+-      BIGLOCK;
++      __UCLIBC_MUTEX_LOCK(__resolv_lock);
+       __nameserversXX=__nameservers;
+       __nameserverXX=__nameserver;
+-      BIGUNLOCK;
++      __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
+       i = __dns_lookup(dname, type, __nameserversXX, __nameserverXX, &packet, &a);
+       if (i < 0) {
+@@ -1207,10 +1195,10 @@ int res_query(const char *dname, int cla
+  * is detected.  Error code, if any, is left in h_errno.
+  */
+ int res_search(name, class, type, answer, anslen)
+-      const char *name;       /* domain name */
+-      int class, type;        /* class and type of query */
+-      u_char *answer;         /* buffer to put answer */
+-      int anslen;             /* size of answer */
++       const char *name;      /* domain name */
++       int class, type;       /* class and type of query */
++       u_char *answer;                /* buffer to put answer */
++       int anslen;            /* size of answer */
+ {
+       const char *cp, * const *domain;
+       HEADER *hp = (HEADER *)(void *)answer;
+@@ -1256,11 +1244,11 @@ int res_search(name, class, type, answer
+               int done = 0;
+               for (domain = (const char * const *)_res.dnsrch;
+-                 *domain && !done;
+-                 domain++) {
++                       *domain && !done;
++                       domain++) {
+                       ret = res_querydomain(name, *domain, class, type,
+-                          answer, anslen);
++                                                                answer, anslen);
+                       if (ret > 0)
+                               return (ret);
+@@ -1283,22 +1271,22 @@ int res_search(name, class, type, answer
+                       }
+                       switch (h_errno) {
+-                      case NO_DATA:
+-                              got_nodata++;
+-                              /* FALLTHROUGH */
+-                      case HOST_NOT_FOUND:
+-                              /* keep trying */
+-                              break;
+-                      case TRY_AGAIN:
+-                              if (hp->rcode == SERVFAIL) {
+-                                      /* try next search element, if any */
+-                                      got_servfail++;
++                              case NO_DATA:
++                                      got_nodata++;
++                                      /* FALLTHROUGH */
++                              case HOST_NOT_FOUND:
++                                      /* keep trying */
+                                       break;
+-                              }
+-                              /* FALLTHROUGH */
+-                      default:
+-                              /* anything else implies that we're done */
+-                              done++;
++                              case TRY_AGAIN:
++                                      if (hp->rcode == SERVFAIL) {
++                                              /* try next search element, if any */
++                                              got_servfail++;
++                                              break;
++                                      }
++                                      /* FALLTHROUGH */
++                              default:
++                                      /* anything else implies that we're done */
++                                      done++;
+                       }
+                       /*
+                        * if we got here for some reason other than DNSRCH,
+@@ -1342,10 +1330,10 @@ int res_search(name, class, type, answer
+  * removing a trailing dot from name if domain is NULL.
+  */
+ int res_querydomain(name, domain, class, type, answer, anslen)
+-      const char *name, *domain;
+-      int class, type;        /* class and type of query */
+-      u_char *answer;         /* buffer to put answer */
+-      int anslen;             /* size of answer */
++       const char *name, *domain;
++       int class, type;       /* class and type of query */
++       u_char *answer;                /* buffer to put answer */
++       int anslen;            /* size of answer */
+ {
+       char nbuf[MAXDNAME];
+       const char *longname = nbuf;
+@@ -1359,7 +1347,7 @@ int res_querydomain(name, domain, class,
+ #ifdef DEBUG
+       if (_res.options & RES_DEBUG)
+               printf(";; res_querydomain(%s, %s, %d, %d)\n",
+-                      name, domain?domain:"<Nil>", class, type);
++                         name, domain?domain:"<Nil>", class, type);
+ #endif
+       if (domain == NULL) {
+               /*
+@@ -1400,11 +1388,11 @@ struct hostent *gethostbyaddr (const voi
+       static struct hostent h;
+       static char buf[
+ #ifndef __UCLIBC_HAS_IPV6__
+-              sizeof(struct in_addr) + sizeof(struct in_addr *)*2 +
++                                      sizeof(struct in_addr) + sizeof(struct in_addr *)*2 +
+ #else
+-              sizeof(struct in6_addr) + sizeof(struct in6_addr *)*2 +
++                                      sizeof(struct in6_addr) + sizeof(struct in6_addr *)*2 +
+ #endif /* __UCLIBC_HAS_IPV6__ */
+-              sizeof(char *)*(ALIAS_DIM) + 384/*namebuffer*/ + 32/* margin */];
++                                      sizeof(char *)*(ALIAS_DIM) + 384/*namebuffer*/ + 32/* margin */];
+       struct hostent *hp;
+       gethostbyaddr_r(addr, len, type, &h, buf, sizeof(buf), &hp, &h_errno);
+@@ -1425,11 +1413,11 @@ void __open_etc_hosts(FILE **fp)
+ }
+ int __read_etc_hosts_r(FILE * fp, const char * name, int type,
+-                   enum etc_hosts_action action,
+-                   struct hostent * result_buf,
+-                   char * buf, size_t buflen,
+-                   struct hostent ** result,
+-                   int * h_errnop)
++                                         enum etc_hosts_action action,
++                                         struct hostent * result_buf,
++                                         char * buf, size_t buflen,
++                                         struct hostent ** result,
++                                         int * h_errnop)
+ {
+       struct in_addr  *in=NULL;
+       struct in_addr  **addr_list=NULL;
+@@ -1576,56 +1564,49 @@ int __read_etc_hosts_r(FILE * fp, const 
+ #ifdef L_gethostent
+-#ifdef __UCLIBC_HAS_THREADS__
+-static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;
+-# define LOCK __pthread_mutex_lock(&mylock)
+-# define UNLOCK       __pthread_mutex_unlock(&mylock);
+-#else
+-# define LOCK
+-# define UNLOCK
+-#endif
++__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER);
+ static int __stay_open;
+ static FILE * __gethostent_fp;
+ void endhostent (void)
+ {
+-    LOCK;
++    __UCLIBC_MUTEX_LOCK(mylock);
+     __stay_open = 0;
+     if (__gethostent_fp) {
+-      fclose(__gethostent_fp);
++              fclose(__gethostent_fp);
+     }
+-    UNLOCK;
++    __UCLIBC_MUTEX_UNLOCK(mylock);
+ }
+ void sethostent (int stay_open)
+ {
+-    LOCK;
++    __UCLIBC_MUTEX_LOCK(mylock);
+     __stay_open = stay_open;
+-    UNLOCK;
++    __UCLIBC_MUTEX_UNLOCK(mylock);
+ }
+ int gethostent_r(struct hostent *result_buf, char *buf, size_t buflen,
+-      struct hostent **result, int *h_errnop)
++                               struct hostent **result, int *h_errnop)
+ {
+-    int ret;
++    int ret = 0;
+-    LOCK;
++    __UCLIBC_MUTEX_LOCK(mylock);
+     if (__gethostent_fp == NULL) {
+-      __open_etc_hosts(&__gethostent_fp);
+-      if (__gethostent_fp == NULL) {
+-          UNLOCK;
+-          *result=NULL;
+-          return 0;
+-      }
++              __open_etc_hosts(&__gethostent_fp);
++              if (__gethostent_fp == NULL) {
++                      *result=NULL;
++                      goto DONE;
++              }
+     }
+     ret = __read_etc_hosts_r(__gethostent_fp, NULL, AF_INET, GETHOSTENT,
+-                 result_buf, buf, buflen, result, h_errnop);
++                                                       result_buf, buf, buflen, result, h_errnop);
+     if (__stay_open==0) {
+-      fclose(__gethostent_fp);
++              fclose(__gethostent_fp);
+     }
+-    UNLOCK;
++ DONE:
++    __UCLIBC_MUTEX_UNLOCK(mylock);
+     return(ret);
+ }
+@@ -1634,17 +1615,17 @@ struct hostent *gethostent (void)
+     static struct hostent h;
+     static char buf[
+ #ifndef __UCLIBC_HAS_IPV6__
+-          sizeof(struct in_addr) + sizeof(struct in_addr *)*2 +
++                                      sizeof(struct in_addr) + sizeof(struct in_addr *)*2 +
+ #else
+-          sizeof(struct in6_addr) + sizeof(struct in6_addr *)*2 +
++                                      sizeof(struct in6_addr) + sizeof(struct in6_addr *)*2 +
+ #endif /* __UCLIBC_HAS_IPV6__ */
+-              sizeof(char *)*(ALIAS_DIM) +
+-          80/*namebuffer*/ + 2/* margin */];
++                                      sizeof(char *)*(ALIAS_DIM) +
++                                      80/*namebuffer*/ + 2/* margin */];
+     struct hostent *host;
+-    LOCK;
++    __UCLIBC_MUTEX_LOCK(mylock);
+     gethostent_r(&h, buf, sizeof(buf), &host, &h_errno);
+-    UNLOCK;
++    __UCLIBC_MUTEX_UNLOCK(mylock);
+     return(host);
+ }
+ #endif
+@@ -1652,23 +1633,23 @@ struct hostent *gethostent (void)
+ #ifdef L_get_hosts_byname_r
+ int __get_hosts_byname_r(const char * name, int type,
+-                          struct hostent * result_buf,
+-                          char * buf, size_t buflen,
+-                          struct hostent ** result,
+-                          int * h_errnop)
++                                               struct hostent * result_buf,
++                                               char * buf, size_t buflen,
++                                               struct hostent ** result,
++                                               int * h_errnop)
+ {
+       return(__read_etc_hosts_r(NULL, name, type, GET_HOSTS_BYNAME,
+-                  result_buf, buf, buflen, result, h_errnop));
++                                                        result_buf, buf, buflen, result, h_errnop));
+ }
+ #endif
+ #ifdef L_get_hosts_byaddr_r
+ int __get_hosts_byaddr_r(const char * addr, int len, int type,
+-                          struct hostent * result_buf,
+-                          char * buf, size_t buflen,
+-                          struct hostent ** result,
+-                          int * h_errnop)
++                                               struct hostent * result_buf,
++                                               char * buf, size_t buflen,
++                                               struct hostent ** result,
++                                               int * h_errnop)
+ {
+ #ifndef __UCLIBC_HAS_IPV6__
+       char    ipaddr[INET_ADDRSTRLEN];
+@@ -1677,24 +1658,24 @@ int __get_hosts_byaddr_r(const char * ad
+ #endif /* __UCLIBC_HAS_IPV6__ */
+     switch (type) {
+-      case AF_INET:
+-              if (len != sizeof(struct in_addr))
+-                      return 0;
+-              break;
++              case AF_INET:
++                      if (len != sizeof(struct in_addr))
++                              return 0;
++                      break;
+ #ifdef __UCLIBC_HAS_IPV6__
+-      case AF_INET6:
+-              if (len != sizeof(struct in6_addr))
+-                      return 0;
+-              break;
++              case AF_INET6:
++                      if (len != sizeof(struct in6_addr))
++                              return 0;
++                      break;
+ #endif /* __UCLIBC_HAS_IPV6__ */
+-      default:
+-              return 0;
++              default:
++                      return 0;
+       }
+       inet_ntop(type, addr, ipaddr, sizeof(ipaddr));
+       return(__read_etc_hosts_r(NULL, ipaddr, type, GET_HOSTS_BYADDR,
+-                  result_buf, buf, buflen, result, h_errnop));
++                                                        result_buf, buf, buflen, result, h_errnop));
+ }
+ #endif
+@@ -1705,8 +1686,8 @@ int __get_hosts_byaddr_r(const char * ad
+ #endif /* min */
+ int getnameinfo (const struct sockaddr *sa, socklen_t addrlen, char *host,
+-           socklen_t hostlen, char *serv, socklen_t servlen,
+-           unsigned int flags)
++                               socklen_t hostlen, char *serv, socklen_t servlen,
++                               unsigned int flags)
+ {
+       int serrno = errno;
+       int ok = 0;
+@@ -1720,167 +1701,167 @@ int getnameinfo (const struct sockaddr *
+               return EAI_FAMILY;
+       switch (sa->sa_family) {
+-      case AF_LOCAL:
+-              break;
+-      case AF_INET:
+-              if (addrlen < sizeof (struct sockaddr_in))
+-                      return EAI_FAMILY;
+-              break;
++              case AF_LOCAL:
++                      break;
++              case AF_INET:
++                      if (addrlen < sizeof (struct sockaddr_in))
++                              return EAI_FAMILY;
++                      break;
+ #ifdef __UCLIBC_HAS_IPV6__
+-      case AF_INET6:
+-              if (addrlen < sizeof (struct sockaddr_in6))
+-                      return EAI_FAMILY;
+-              break;
++              case AF_INET6:
++                      if (addrlen < sizeof (struct sockaddr_in6))
++                              return EAI_FAMILY;
++                      break;
+ #endif /* __UCLIBC_HAS_IPV6__ */
+-      default:
+-              return EAI_FAMILY;
++              default:
++                      return EAI_FAMILY;
+       }
+       if (host != NULL && hostlen > 0)
+               switch (sa->sa_family) {
+-              case AF_INET:
++                      case AF_INET:
+ #ifdef __UCLIBC_HAS_IPV6__
+-              case AF_INET6:
++                      case AF_INET6:
+ #endif /* __UCLIBC_HAS_IPV6__ */
+-                      if (!(flags & NI_NUMERICHOST)) {
++                              if (!(flags & NI_NUMERICHOST)) {
+ #ifdef __UCLIBC_HAS_IPV6__
+-                              if (sa->sa_family == AF_INET6)
+-                                      h = gethostbyaddr ((const void *)
+-                                              &(((const struct sockaddr_in6 *) sa)->sin6_addr),
+-                                              sizeof(struct in6_addr), AF_INET6);
+-                              else
+-#endif /* __UCLIBC_HAS_IPV6__ */
+-                    h = gethostbyaddr ((const void *) &(((const struct sockaddr_in *)sa)->sin_addr),
+-                                        sizeof(struct in_addr), AF_INET);
+-
+-                              if (h) {
+-                                      char *c;
+-                                      if ((flags & NI_NOFQDN)
+-                                          && (getdomainname (domain, sizeof(domain)) == 0)
+-                                          && (c = strstr (h->h_name, domain))
+-                                          && (c != h->h_name) && (*(--c) == '.')) {
+-                                              strncpy (host, h->h_name,
+-                                                      min(hostlen, (size_t) (c - h->h_name)));
+-                                              host[min(hostlen - 1, (size_t) (c - h->h_name))] = '\0';
+-                                              ok = 1;
+-                                      } else {
+-                                              strncpy (host, h->h_name, hostlen);
+-                                              ok = 1;
++                                      if (sa->sa_family == AF_INET6)
++                                              h = gethostbyaddr ((const void *)
++                                                                                 &(((const struct sockaddr_in6 *) sa)->sin6_addr),
++                                                                                 sizeof(struct in6_addr), AF_INET6);
++                                      else
++#endif /* __UCLIBC_HAS_IPV6__ */
++                                              h = gethostbyaddr ((const void *) &(((const struct sockaddr_in *)sa)->sin_addr),
++                                                                                 sizeof(struct in_addr), AF_INET);
++
++                                      if (h) {
++                                              char *c;
++                                              if ((flags & NI_NOFQDN)
++                                                      && (getdomainname (domain, sizeof(domain)) == 0)
++                                                      && (c = strstr (h->h_name, domain))
++                                                      && (c != h->h_name) && (*(--c) == '.')) {
++                                                      strncpy (host, h->h_name,
++                                                                       min(hostlen, (size_t) (c - h->h_name)));
++                                                      host[min(hostlen - 1, (size_t) (c - h->h_name))] = '\0';
++                                                      ok = 1;
++                                              } else {
++                                                      strncpy (host, h->h_name, hostlen);
++                                                      ok = 1;
++                                              }
+                                       }
+-                               }
+-                      }
++                              }
+-                      if (!ok) {
+-                              if (flags & NI_NAMEREQD) {
+-                                      errno = serrno;
+-                                      return EAI_NONAME;
+-                              } else {
+-                                      const char *c;
++                              if (!ok) {
++                                      if (flags & NI_NAMEREQD) {
++                                              errno = serrno;
++                                              return EAI_NONAME;
++                                      } else {
++                                              const char *c;
+ #ifdef __UCLIBC_HAS_IPV6__
+-                                      if (sa->sa_family == AF_INET6) {
+-                                              const struct sockaddr_in6 *sin6p;
++                                              if (sa->sa_family == AF_INET6) {
++                                                      const struct sockaddr_in6 *sin6p;
+-                                              sin6p = (const struct sockaddr_in6 *) sa;
++                                                      sin6p = (const struct sockaddr_in6 *) sa;
+-                                              c = inet_ntop (AF_INET6,
+-                                                      (const void *) &sin6p->sin6_addr, host, hostlen);
++                                                      c = inet_ntop (AF_INET6,
++                                                                                 (const void *) &sin6p->sin6_addr, host, hostlen);
+ #if 0
+-                                              /* Does scope id need to be supported? */
+-                                              uint32_t scopeid;
+-                                              scopeid = sin6p->sin6_scope_id;
+-                                              if (scopeid != 0) {
+-                                                      /* Buffer is >= IFNAMSIZ+1.  */
+-                                                      char scopebuf[IFNAMSIZ + 1];
+-                                                      char *scopeptr;
+-                                                      int ni_numericscope = 0;
+-                                                      size_t real_hostlen = __strnlen (host, hostlen);
+-                                                      size_t scopelen = 0;
+-
+-                                                      scopebuf[0] = SCOPE_DELIMITER;
+-                                                      scopebuf[1] = '\0';
+-                                                      scopeptr = &scopebuf[1];
+-
+-                                                      if (IN6_IS_ADDR_LINKLOCAL (&sin6p->sin6_addr)
+-                                                          || IN6_IS_ADDR_MC_LINKLOCAL (&sin6p->sin6_addr)) {
+-                                                              if (if_indextoname (scopeid, scopeptr) == NULL)
++                                                      /* Does scope id need to be supported? */
++                                                      uint32_t scopeid;
++                                                      scopeid = sin6p->sin6_scope_id;
++                                                      if (scopeid != 0) {
++                                                              /* Buffer is >= IFNAMSIZ+1.  */
++                                                              char scopebuf[IFNAMSIZ + 1];
++                                                              char *scopeptr;
++                                                              int ni_numericscope = 0;
++                                                              size_t real_hostlen = __strnlen (host, hostlen);
++                                                              size_t scopelen = 0;
++
++                                                              scopebuf[0] = SCOPE_DELIMITER;
++                                                              scopebuf[1] = '\0';
++                                                              scopeptr = &scopebuf[1];
++
++                                                              if (IN6_IS_ADDR_LINKLOCAL (&sin6p->sin6_addr)
++                                                                      || IN6_IS_ADDR_MC_LINKLOCAL (&sin6p->sin6_addr)) {
++                                                                      if (if_indextoname (scopeid, scopeptr) == NULL)
++                                                                              ++ni_numericscope;
++                                                                      else
++                                                                              scopelen = strlen (scopebuf);
++                                                              } else {
+                                                                       ++ni_numericscope;
+-                                                              else
+-                                                                      scopelen = strlen (scopebuf);
+-                                                      } else {
+-                                                              ++ni_numericscope;
+-                                                      }
++                                                              }
+-                                                      if (ni_numericscope)
+-                                                              scopelen = 1 + snprintf (scopeptr,
+-                                                                      (scopebuf
+-                                                                      + sizeof scopebuf
+-                                                                      - scopeptr),
+-                                                                      "%u", scopeid);
+-
+-                                                      if (real_hostlen + scopelen + 1 > hostlen)
+-                                                              return EAI_SYSTEM;
+-                                                      memcpy (host + real_hostlen, scopebuf, scopelen + 1);
+-                                              }
++                                                              if (ni_numericscope)
++                                                                      scopelen = 1 + snprintf (scopeptr,
++                                                                                                                       (scopebuf
++                                                                                                                        + sizeof scopebuf
++                                                                                                                        - scopeptr),
++                                                                                                                       "%u", scopeid);
++
++                                                              if (real_hostlen + scopelen + 1 > hostlen)
++                                                                      return EAI_SYSTEM;
++                                                              memcpy (host + real_hostlen, scopebuf, scopelen + 1);
++                                                      }
+ #endif
+-                                      } else
++                                              } else
+ #endif /* __UCLIBC_HAS_IPV6__ */
+-                                              c = inet_ntop (AF_INET, (const void *)
+-                                                      &(((const struct sockaddr_in *) sa)->sin_addr),
+-                                                      host, hostlen);
+-
+-                                      if (c == NULL) {
+-                                              errno = serrno;
+-                                              return EAI_SYSTEM;
++                                                      c = inet_ntop (AF_INET, (const void *)
++                                                                                 &(((const struct sockaddr_in *) sa)->sin_addr),
++                                                                                 host, hostlen);
++
++                                              if (c == NULL) {
++                                                      errno = serrno;
++                                                      return EAI_SYSTEM;
++                                              }
+                                       }
++                                      ok = 1;
+                               }
+-                              ok = 1;
+-                      }
+-                      break;
+-
+-              case AF_LOCAL:
+-                      if (!(flags & NI_NUMERICHOST)) {
+-                              struct utsname utsname;
++                              break;
+-                              if (!uname (&utsname)) {
+-                                      strncpy (host, utsname.nodename, hostlen);
+-                                      break;
++                      case AF_LOCAL:
++                              if (!(flags & NI_NUMERICHOST)) {
++                                      struct utsname utsname;
++
++                                      if (!uname (&utsname)) {
++                                              strncpy (host, utsname.nodename, hostlen);
++                                              break;
++                                      };
+                               };
+-                      };
+-                      if (flags & NI_NAMEREQD) {
+-                              errno = serrno;
+-                              return EAI_NONAME;
+-                      }
++                              if (flags & NI_NAMEREQD) {
++                                      errno = serrno;
++                                      return EAI_NONAME;
++                              }
+-                      strncpy (host, "localhost", hostlen);
+-                      break;
++                              strncpy (host, "localhost", hostlen);
++                              break;
+-              default:
+-                      return EAI_FAMILY;
+-      }
++                      default:
++                              return EAI_FAMILY;
++              }
+       if (serv && (servlen > 0)) {
+               switch (sa->sa_family) {
+-              case AF_INET:
++                      case AF_INET:
+ #ifdef __UCLIBC_HAS_IPV6__
+-              case AF_INET6:
++                      case AF_INET6:
+ #endif /* __UCLIBC_HAS_IPV6__ */
+-                      if (!(flags & NI_NUMERICSERV)) {
+-                              struct servent *s;
+-                              s = getservbyport (((const struct sockaddr_in *) sa)->sin_port,
+-                                    ((flags & NI_DGRAM) ? "udp" : "tcp"));
+-                              if (s) {
+-                                      strncpy (serv, s->s_name, servlen);
+-                                      break;
++                              if (!(flags & NI_NUMERICSERV)) {
++                                      struct servent *s;
++                                      s = getservbyport (((const struct sockaddr_in *) sa)->sin_port,
++                                                                         ((flags & NI_DGRAM) ? "udp" : "tcp"));
++                                      if (s) {
++                                              strncpy (serv, s->s_name, servlen);
++                                              break;
++                                      }
+                               }
+-                      }
+-                      snprintf (serv, servlen, "%d",
+-                              ntohs (((const struct sockaddr_in *) sa)->sin_port));
+-                      break;
++                              snprintf (serv, servlen, "%d",
++                                                ntohs (((const struct sockaddr_in *) sa)->sin_port));
++                              break;
+-              case AF_LOCAL:
+-                      strncpy (serv, ((const struct sockaddr_un *) sa)->sun_path, servlen);
+-                      break;
++                      case AF_LOCAL:
++                              strncpy (serv, ((const struct sockaddr_un *) sa)->sun_path, servlen);
++                              break;
+               }
+       }
+       if (host && (hostlen > 0))
+@@ -1896,10 +1877,10 @@ int getnameinfo (const struct sockaddr *
+ #ifdef L_gethostbyname_r
+ int gethostbyname_r(const char * name,
+-                          struct hostent * result_buf,
+-                          char * buf, size_t buflen,
+-                          struct hostent ** result,
+-                          int * h_errnop)
++                                      struct hostent * result_buf,
++                                      char * buf, size_t buflen,
++                                      struct hostent ** result,
++                                      int * h_errnop)
+ {
+       struct in_addr *in;
+       struct in_addr **addr_list;
+@@ -1921,7 +1902,7 @@ int gethostbyname_r(const char * name,
+               __set_errno(0);                 /* to check for missing /etc/hosts. */
+               if ((i=__get_hosts_byname_r(name, AF_INET, result_buf,
+-                              buf, buflen, result, h_errnop))==0)
++                                                                      buf, buflen, result, h_errnop))==0)
+                       return i;
+               switch (*h_errnop) {
+                       case HOST_NOT_FOUND:
+@@ -1983,60 +1964,60 @@ int gethostbyname_r(const char * name,
+       for (;;) {
+-          BIGLOCK;
++          __UCLIBC_MUTEX_LOCK(__resolv_lock);
+           __nameserversXX=__nameservers;
+           __nameserverXX=__nameserver;
+-          BIGUNLOCK;
++          __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
+           a.buf = buf;
+           a.buflen = buflen;
+           a.add_count = 0;
+           i = __dns_lookup(name, T_A, __nameserversXX, __nameserverXX, &packet, &a);
+           if (i < 0) {
+-              *h_errnop = HOST_NOT_FOUND;
+-              DPRINTF("__dns_lookup\n");
+-              return TRY_AGAIN;
++                      *h_errnop = HOST_NOT_FOUND;
++                      DPRINTF("__dns_lookup\n");
++                      return TRY_AGAIN;
+           }
+           if ((a.rdlength + sizeof(struct in_addr*)) * a.add_count + 256 > buflen)
+-          {
+-              free(a.dotted);
+-              free(packet);
+-              *h_errnop = NETDB_INTERNAL;
+-              DPRINTF("buffer too small for all addresses\n");
+-              return ERANGE;
+-          }
++                      {
++                              free(a.dotted);
++                              free(packet);
++                              *h_errnop = NETDB_INTERNAL;
++                              DPRINTF("buffer too small for all addresses\n");
++                              return ERANGE;
++                      }
+           else if(a.add_count > 0)
+-          {
+-              memmove(buf - sizeof(struct in_addr*)*2, buf, a.add_count * a.rdlength);
+-              addr_list = (struct in_addr**)(buf + a.add_count * a.rdlength);
+-              addr_list[0] = in;
+-              for (i = a.add_count-1; i>=0; --i)
+-                  addr_list[i+1] = (struct in_addr*)(buf - sizeof(struct in_addr*)*2 + a.rdlength * i);
+-              addr_list[a.add_count + 1] = 0;
+-              buflen -= (((char*)&(addr_list[a.add_count + 2])) - buf);
+-              buf = (char*)&addr_list[a.add_count + 2];
+-          }
++                      {
++                              memmove(buf - sizeof(struct in_addr*)*2, buf, a.add_count * a.rdlength);
++                              addr_list = (struct in_addr**)(buf + a.add_count * a.rdlength);
++                              addr_list[0] = in;
++                              for (i = a.add_count-1; i>=0; --i)
++                                      addr_list[i+1] = (struct in_addr*)(buf - sizeof(struct in_addr*)*2 + a.rdlength * i);
++                              addr_list[a.add_count + 1] = 0;
++                              buflen -= (((char*)&(addr_list[a.add_count + 2])) - buf);
++                              buf = (char*)&addr_list[a.add_count + 2];
++                      }
+           strncpy(buf, a.dotted, buflen);
+           free(a.dotted);
+           if (a.atype == T_A) { /* ADDRESS */
+-              memcpy(in, a.rdata, sizeof(*in));
+-              result_buf->h_name = buf;
+-              result_buf->h_addrtype = AF_INET;
+-              result_buf->h_length = sizeof(*in);
+-              result_buf->h_addr_list = (char **) addr_list;
++                      memcpy(in, a.rdata, sizeof(*in));
++                      result_buf->h_name = buf;
++                      result_buf->h_addrtype = AF_INET;
++                      result_buf->h_length = sizeof(*in);
++                      result_buf->h_addr_list = (char **) addr_list;
+ #ifdef __UCLIBC_MJN3_ONLY__
+ #warning TODO -- generate the full list
+ #endif
+-              result_buf->h_aliases = alias; /* TODO: generate the full list */
+-              free(packet);
+-              break;
++                      result_buf->h_aliases = alias; /* TODO: generate the full list */
++                      free(packet);
++                      break;
+           } else {
+-              free(packet);
+-              *h_errnop=HOST_NOT_FOUND;
+-              return TRY_AGAIN;
++                      free(packet);
++                      *h_errnop=HOST_NOT_FOUND;
++                      return TRY_AGAIN;
+           }
+       }
+@@ -2049,14 +2030,14 @@ int gethostbyname_r(const char * name,
+ #ifdef L_gethostbyname2_r
+ int gethostbyname2_r(const char *name, int family,
+-                          struct hostent * result_buf,
+-                          char * buf, size_t buflen,
+-                          struct hostent ** result,
+-                          int * h_errnop)
++                                       struct hostent * result_buf,
++                                       char * buf, size_t buflen,
++                                       struct hostent ** result,
++                                       int * h_errnop)
+ {
+ #ifndef __UCLIBC_HAS_IPV6__
+       return family == (AF_INET)? gethostbyname_r(name, result_buf,
+-              buf, buflen, result, h_errnop) : HOST_NOT_FOUND;
++                                                                                              buf, buflen, result, h_errnop) : HOST_NOT_FOUND;
+ #else /* __UCLIBC_HAS_IPV6__ */
+       struct in6_addr *in;
+       struct in6_addr **addr_list;
+@@ -2084,7 +2065,7 @@ int gethostbyname2_r(const char *name, i
+               __set_errno(0);                 /* to check for missing /etc/hosts. */
+               if ((i=__get_hosts_byname_r(name, AF_INET, result_buf,
+-                              buf, buflen, result, h_errnop))==0)
++                                                                      buf, buflen, result, h_errnop))==0)
+                       return i;
+               switch (*h_errnop) {
+                       case HOST_NOT_FOUND:
+@@ -2137,10 +2118,10 @@ int gethostbyname2_r(const char *name, i
+       memset((char *) &a, '\0', sizeof(a));
+       for (;;) {
+-      BIGLOCK;
+-      __nameserversXX=__nameservers;
+-      __nameserverXX=__nameserver;
+-      BIGUNLOCK;
++              __UCLIBC_MUTEX_LOCK(__resolv_lock);
++              __nameserversXX=__nameservers;
++              __nameserverXX=__nameserver;
++              __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
+               i = __dns_lookup(buf, T_AAAA, __nameserversXX, __nameserverXX, &packet, &a);
+@@ -2190,10 +2171,10 @@ int gethostbyname2_r(const char *name, i
+ #ifdef L_gethostbyaddr_r
+ int gethostbyaddr_r (const void *addr, socklen_t len, int type,
+-                          struct hostent * result_buf,
+-                          char * buf, size_t buflen,
+-                          struct hostent ** result,
+-                          int * h_errnop)
++                                       struct hostent * result_buf,
++                                       char * buf, size_t buflen,
++                                       struct hostent ** result,
++                                       int * h_errnop)
+ {
+       struct in_addr *in;
+@@ -2234,7 +2215,7 @@ int gethostbyaddr_r (const void *addr, s
+       /* do /etc/hosts first */
+       if ((i=__get_hosts_byaddr_r(addr, len, type, result_buf,
+-                                buf, buflen, result, h_errnop))==0)
++                                                              buf, buflen, result, h_errnop))==0)
+               return i;
+       switch (*h_errnop) {
+               case HOST_NOT_FOUND:
+@@ -2294,7 +2275,7 @@ int gethostbyaddr_r (const void *addr, s
+               addr_list[0] = in;
+               sprintf(buf, "%u.%u.%u.%u.in-addr.arpa",
+-                      tmp_addr[3], tmp_addr[2], tmp_addr[1], tmp_addr[0]);
++                              tmp_addr[3], tmp_addr[2], tmp_addr[1], tmp_addr[0]);
+ #ifdef __UCLIBC_HAS_IPV6__
+       } else {
+               memcpy(in6->s6_addr, addr, len);
+@@ -2304,7 +2285,7 @@ int gethostbyaddr_r (const void *addr, s
+               for (i = len - 1; i >= 0; i--) {
+                       qp += sprintf(qp, "%x.%x.", in6->s6_addr[i] & 0xf,
+-                              (in6->s6_addr[i] >> 4) & 0xf);
++                                                (in6->s6_addr[i] >> 4) & 0xf);
+       }
+       strcpy(qp, "ip6.int");
+ #endif /* __UCLIBC_HAS_IPV6__ */
+@@ -2314,10 +2295,10 @@ int gethostbyaddr_r (const void *addr, s
+       for (;;) {
+-      BIGLOCK;
+-      __nameserversXX=__nameservers;
+-      __nameserverXX=__nameserver;
+-      BIGUNLOCK;
++              __UCLIBC_MUTEX_LOCK(__resolv_lock);
++              __nameserversXX=__nameservers;
++              __nameserverXX=__nameserver;
++              __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
+               i = __dns_lookup(buf, T_PTR, __nameserversXX, __nameserverXX, &packet, &a);
+               if (i < 0) {
+@@ -2381,7 +2362,7 @@ int gethostbyaddr_r (const void *addr, s
+  * Return size of compressed name or -1 if there was an error.
+  */
+ int __dn_expand(const u_char *msg, const u_char *eom, const u_char *src,
+-          char *dst, int dstsiz)
++                              char *dst, int dstsiz)
+ {
+       int n = ns_name_uncompress(msg, eom, src, dst, (size_t)dstsiz);
+@@ -2401,7 +2382,7 @@ int __dn_expand(const u_char *msg, const
+  */
+ static int printable(int ch)
+ {
+-        return (ch > 0x20 && ch < 0x7f);
++      return (ch > 0x20 && ch < 0x7f);
+ }
+ /*
+@@ -2413,18 +2394,18 @@ static int printable(int ch)
+  */
+ static int special(int ch)
+ {
+-        switch (ch) {
++      switch (ch) {
+         case 0x22: /* '"' */
+         case 0x2E: /* '.' */
+         case 0x3B: /* ';' */
+         case 0x5C: /* '\\' */
+-        /* Special modifiers in zone files. */
++                      /* Special modifiers in zone files. */
+         case 0x40: /* '@' */
+         case 0x24: /* '$' */
+-                return (1);
++                      return (1);
+         default:
+-                return (0);
+-        }
++                      return (0);
++      }
+ }
+ /*
+@@ -2436,7 +2417,7 @@ static int special(int ch)
+  *      Root domain returns as "." not "".
+  */
+ int __ns_name_uncompress(const u_char *msg, const u_char *eom,
+-              const u_char *src, char *dst, size_t dstsiz)
++                                               const u_char *src, char *dst, size_t dstsiz)
+ {
+       u_char tmp[NS_MAXCDNAME];
+       int n;
+@@ -2525,7 +2506,7 @@ int __ns_name_ntop(const u_char *src, ch
+               return (-1);
+       }
+       *dn++ = '\0';
+-        return (dn - dst);
++      return (dn - dst);
+ }
+ /*
+@@ -2535,7 +2516,7 @@ int __ns_name_ntop(const u_char *src, ch
+  *      -1 if it fails, or consumed octets if it succeeds.
+  */
+ int __ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src,
+-               u_char *dst, size_t dstsiz)
++                                       u_char *dst, size_t dstsiz)
+ {
+       const u_char *srcp, *dstlim;
+       u_char *dstp;
+@@ -2554,46 +2535,46 @@ int __ns_name_unpack(const u_char *msg, 
+       while ((n = *srcp++) != 0) {
+               /* Check for indirection. */
+               switch (n & NS_CMPRSFLGS) {
+-              case 0:
+-                      /* Limit checks. */
+-                      if (dstp + n + 1 >= dstlim || srcp + n >= eom) {
+-                              __set_errno (EMSGSIZE);
+-                              return (-1);
+-                      }
+-                      checked += n + 1;
+-                      *dstp++ = n;
+-                      memcpy(dstp, srcp, n);
+-                      dstp += n;
+-                      srcp += n;
+-                      break;
++                      case 0:
++                              /* Limit checks. */
++                              if (dstp + n + 1 >= dstlim || srcp + n >= eom) {
++                                      __set_errno (EMSGSIZE);
++                                      return (-1);
++                              }
++                              checked += n + 1;
++                              *dstp++ = n;
++                              memcpy(dstp, srcp, n);
++                              dstp += n;
++                              srcp += n;
++                              break;
+-              case NS_CMPRSFLGS:
+-                      if (srcp >= eom) {
+-                              __set_errno (EMSGSIZE);
+-                              return (-1);
+-                      }
+-                      if (len < 0)
+-                              len = srcp - src + 1;
+-                      srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff));
+-                      if (srcp < msg || srcp >= eom) {  /* Out of range. */
+-                              __set_errno (EMSGSIZE);
+-                              return (-1);
+-                      }
+-                      checked += 2;
+-                      /*
+-                       * Check for loops in the compressed name;
+-                       * if we've looked at the whole message,
+-                       * there must be a loop.
+-                       */
+-                      if (checked >= eom - msg) {
+-                              __set_errno (EMSGSIZE);
+-                              return (-1);
+-                      }
+-                      break;
++                      case NS_CMPRSFLGS:
++                              if (srcp >= eom) {
++                                      __set_errno (EMSGSIZE);
++                                      return (-1);
++                              }
++                              if (len < 0)
++                                      len = srcp - src + 1;
++                              srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff));
++                              if (srcp < msg || srcp >= eom) {  /* Out of range. */
++                                      __set_errno (EMSGSIZE);
++                                      return (-1);
++                              }
++                              checked += 2;
++                              /*
++                               * Check for loops in the compressed name;
++                               * if we've looked at the whole message,
++                               * there must be a loop.
++                               */
++                              if (checked >= eom - msg) {
++                                      __set_errno (EMSGSIZE);
++                                      return (-1);
++                              }
++                              break;
+-              default:
+-                      __set_errno (EMSGSIZE);
+-                      return (-1);                    /* flag error */
++                      default:
++                              __set_errno (EMSGSIZE);
++                              return (-1);                    /* flag error */
+               }
+       }
+       *dstp = '\0';
+diff --git a/libc/inet/rpc/create_xid.c b/libc/inet/rpc/create_xid.c
+index cbb961e..c86cbb4 100644
+--- a/libc/inet/rpc/create_xid.c
++++ b/libc/inet/rpc/create_xid.c
+@@ -27,15 +27,7 @@
+ /* The RPC code is not threadsafe, but new code should be threadsafe. */
+-#ifdef __UCLIBC_HAS_THREADS__
+-#include <pthread.h>
+-static pthread_mutex_t createxid_lock = PTHREAD_MUTEX_INITIALIZER;
+-# define LOCK __pthread_mutex_lock(&createxid_lock)
+-# define UNLOCK       __pthread_mutex_unlock(&createxid_lock);
+-#else
+-# define LOCK
+-# define UNLOCK
+-#endif
++__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER);
+ static int is_initialized;
+ static struct drand48_data __rpc_lrand48_data;
+@@ -43,22 +35,22 @@ static struct drand48_data __rpc_lrand48
+ unsigned long
+ _create_xid (void)
+ {
+-  unsigned long res;
++      unsigned long res;
+-  LOCK;
++      __UCLIBC_MUTEX_LOCK(mylock);
+-  if (!is_initialized)
+-    {
+-      struct timeval now;
++      if (!is_initialized)
++              {
++                      struct timeval now;
+-      gettimeofday (&now, (struct timezone *) 0);
+-      srand48_r (now.tv_sec ^ now.tv_usec, &__rpc_lrand48_data);
+-      is_initialized = 1;
+-    }
++                      gettimeofday (&now, (struct timezone *) 0);
++                      srand48_r (now.tv_sec ^ now.tv_usec, &__rpc_lrand48_data);
++                      is_initialized = 1;
++              }
+-  lrand48_r (&__rpc_lrand48_data, &res);
++      lrand48_r (&__rpc_lrand48_data, &res);
+-  UNLOCK;
++      __UCLIBC_MUTEX_UNLOCK(mylock);
+-  return res;
++      return res;
+ }
+diff --git a/libc/misc/dirent/closedir.c b/libc/misc/dirent/closedir.c
+index 068e2d3..56adb23 100644
+--- a/libc/misc/dirent/closedir.c
++++ b/libc/misc/dirent/closedir.c
+@@ -4,7 +4,6 @@
+ #include <unistd.h>
+ #include "dirstream.h"
+-
+ int closedir(DIR * dir)
+ {
+       int fd;
+@@ -19,14 +18,10 @@ int closedir(DIR * dir)
+               __set_errno(EBADF);
+               return -1;
+       }
+-#ifdef __UCLIBC_HAS_THREADS__
+-      __pthread_mutex_lock(&(dir->dd_lock));
+-#endif
++      __UCLIBC_MUTEX_LOCK(dir->dd_lock);
+       fd = dir->dd_fd;
+       dir->dd_fd = -1;
+-#ifdef __UCLIBC_HAS_THREADS__
+-      __pthread_mutex_unlock(&(dir->dd_lock));
+-#endif
++      __UCLIBC_MUTEX_UNLOCK(dir->dd_lock);
+       free(dir->dd_buf);
+       free(dir);
+       return close(fd);
+diff --git a/libc/misc/dirent/dirstream.h b/libc/misc/dirent/dirstream.h
+index 2dd0264..bd721c5 100644
+--- a/libc/misc/dirent/dirstream.h
++++ b/libc/misc/dirent/dirstream.h
+@@ -26,9 +26,8 @@ Cambridge, MA 02139, USA.  */
+ #include <features.h>
+ #include <sys/types.h>
+-#ifdef __UCLIBC_HAS_THREADS__
+-#include <pthread.h>
+-#endif
++
++#include <bits/uClibc_mutex.h>
+ /* For now, syscall readdir () only supports one entry at a time. It
+  * will be changed in the future.
+@@ -63,11 +62,7 @@ struct __dirstream {
+   size_t dd_max;
+  
+   /* lock */
+-#ifdef __UCLIBC_HAS_THREADS__
+-  pthread_mutex_t dd_lock;
+-#else
+-  void *dd_lock;
+-#endif
++  __UCLIBC_MUTEX(dd_lock);
+ };                            /* stream data from opendir() */
+diff --git a/libc/misc/dirent/readdir.c b/libc/misc/dirent/readdir.c
+index 1f196e1..c55317a 100644
+--- a/libc/misc/dirent/readdir.c
++++ b/libc/misc/dirent/readdir.c
+@@ -5,7 +5,6 @@
+ #include <dirent.h>
+ #include "dirstream.h"
+-
+ struct dirent *readdir(DIR * dir)
+ {
+       ssize_t bytes;
+@@ -16,9 +15,7 @@ struct dirent *readdir(DIR * dir)
+               return NULL;
+       }
+-#ifdef __UCLIBC_HAS_THREADS__
+-      __pthread_mutex_lock(&(dir->dd_lock));
+-#endif
++      __UCLIBC_MUTEX_LOCK(dir->dd_lock);
+       do {
+           if (dir->dd_size <= dir->dd_nextloc) {
+@@ -44,8 +41,6 @@ struct dirent *readdir(DIR * dir)
+       } while (de->d_ino == 0);
+ all_done:
+-#ifdef __UCLIBC_HAS_THREADS__
+-      __pthread_mutex_unlock(&(dir->dd_lock));
+-#endif
++      __UCLIBC_MUTEX_UNLOCK(dir->dd_lock);
+       return de;
+ }
+diff --git a/libc/misc/dirent/readdir64.c b/libc/misc/dirent/readdir64.c
+index f798c6f..6da3b0d 100644
+--- a/libc/misc/dirent/readdir64.c
++++ b/libc/misc/dirent/readdir64.c
+@@ -20,7 +20,6 @@
+ #include <dirent.h>
+ #include "dirstream.h"
+-
+ struct dirent64 *readdir64(DIR * dir)
+ {
+       ssize_t bytes;
+@@ -31,9 +30,7 @@ struct dirent64 *readdir64(DIR * dir)
+               return NULL;
+       }
+-#ifdef __UCLIBC_HAS_THREADS__
+-      __pthread_mutex_lock(&(dir->dd_lock));
+-#endif
++      __UCLIBC_MUTEX_LOCK(dir->dd_lock);
+       do {
+           if (dir->dd_size <= dir->dd_nextloc) {
+@@ -59,9 +56,7 @@ struct dirent64 *readdir64(DIR * dir)
+       } while (de->d_ino == 0);
+ all_done:
+-#ifdef __UCLIBC_HAS_THREADS__
+-      __pthread_mutex_unlock(&(dir->dd_lock));
+-#endif
++      __UCLIBC_MUTEX_UNLOCK(dir->dd_lock);
+       return de;
+ }
+diff --git a/libc/misc/dirent/readdir64_r.c b/libc/misc/dirent/readdir64_r.c
+index da3564e..cc96eff 100644
+--- a/libc/misc/dirent/readdir64_r.c
++++ b/libc/misc/dirent/readdir64_r.c
+@@ -19,7 +19,6 @@
+ #include <dirent.h>
+ #include "dirstream.h"
+-
+ int readdir64_r(DIR *dir, struct dirent64 *entry, struct dirent64 **result)
+ {
+       int ret;
+@@ -32,21 +31,19 @@ int readdir64_r(DIR *dir, struct dirent6
+       }
+       de = NULL;
+-#ifdef __UCLIBC_HAS_THREADS__
+-      __pthread_mutex_lock(&(dir->dd_lock));
+-#endif
++      __UCLIBC_MUTEX_LOCK(dir->dd_lock);
+       do {
+           if (dir->dd_size <= dir->dd_nextloc) {
+-              /* read dir->dd_max bytes of directory entries. */
+-              bytes = __getdents64(dir->dd_fd, dir->dd_buf, dir->dd_max);
+-              if (bytes <= 0) {
+-                  *result = NULL;
+-                  ret = errno;
+-                  goto all_done;
+-              }
+-              dir->dd_size = bytes;
+-              dir->dd_nextloc = 0;
++                      /* read dir->dd_max bytes of directory entries. */
++                      bytes = __getdents64(dir->dd_fd, dir->dd_buf, dir->dd_max);
++                      if (bytes <= 0) {
++                              *result = NULL;
++                              ret = errno;
++                              goto all_done;
++                      }
++                      dir->dd_size = bytes;
++                      dir->dd_nextloc = 0;
+           }
+           de = (struct dirent64 *) (((char *) dir->dd_buf) + dir->dd_nextloc);
+@@ -66,12 +63,10 @@ int readdir64_r(DIR *dir, struct dirent6
+       }
+       ret = 0;
+-all_done:
++ all_done:
+-#ifdef __UCLIBC_HAS_THREADS__
+-      __pthread_mutex_unlock(&(dir->dd_lock));
+-#endif
+-        return((de != NULL)? 0 : ret);
++      __UCLIBC_MUTEX_UNLOCK(dir->dd_lock);
++      return((de != NULL)? 0 : ret);
+ }
+ #endif /* __UCLIBC_HAS_LFS__ */
+diff --git a/libc/misc/dirent/readdir_r.c b/libc/misc/dirent/readdir_r.c
+index 245dcbd..aeccdd8 100644
+--- a/libc/misc/dirent/readdir_r.c
++++ b/libc/misc/dirent/readdir_r.c
+@@ -5,7 +5,6 @@
+ #include <dirent.h>
+ #include "dirstream.h"
+-
+ int readdir_r(DIR *dir, struct dirent *entry, struct dirent **result)
+ {
+       int ret;
+@@ -18,21 +17,19 @@ int readdir_r(DIR *dir, struct dirent *e
+       }
+       de = NULL;
+-#ifdef __UCLIBC_HAS_THREADS__
+-      __pthread_mutex_lock(&(dir->dd_lock));
+-#endif
++      __UCLIBC_MUTEX_LOCK(dir->dd_lock);
+       do {
+           if (dir->dd_size <= dir->dd_nextloc) {
+-              /* read dir->dd_max bytes of directory entries. */
+-              bytes = __getdents(dir->dd_fd, dir->dd_buf, dir->dd_max);
+-              if (bytes <= 0) {
+-                  *result = NULL;
+-                  ret = errno;
+-                  goto all_done;
+-              }
+-              dir->dd_size = bytes;
+-              dir->dd_nextloc = 0;
++                      /* read dir->dd_max bytes of directory entries. */
++                      bytes = __getdents(dir->dd_fd, dir->dd_buf, dir->dd_max);
++                      if (bytes <= 0) {
++                              *result = NULL;
++                              ret = errno;
++                              goto all_done;
++                      }
++                      dir->dd_size = bytes;
++                      dir->dd_nextloc = 0;
+           }
+           de = (struct dirent *) (((char *) dir->dd_buf) + dir->dd_nextloc);
+@@ -52,10 +49,8 @@ int readdir_r(DIR *dir, struct dirent *e
+       }
+       ret = 0;
+-all_done:
++ all_done:
+-#ifdef __UCLIBC_HAS_THREADS__
+-      __pthread_mutex_unlock(&(dir->dd_lock));
+-#endif
+-        return((de != NULL)? 0 : ret);
++      __UCLIBC_MUTEX_UNLOCK(dir->dd_lock);
++      return((de != NULL)? 0 : ret);
+ }
+diff --git a/libc/misc/dirent/rewinddir.c b/libc/misc/dirent/rewinddir.c
+index 60ef71d..fe8fc2a 100644
+--- a/libc/misc/dirent/rewinddir.c
++++ b/libc/misc/dirent/rewinddir.c
+@@ -3,7 +3,6 @@
+ #include <unistd.h>
+ #include "dirstream.h"
+-
+ /* rewinddir() just does an lseek(fd,0,0) - see close for comments */
+ void rewinddir(DIR * dir)
+ {
+@@ -11,12 +10,8 @@ void rewinddir(DIR * dir)
+               __set_errno(EBADF);
+               return;
+       }
+-#ifdef __UCLIBC_HAS_THREADS__
+-      __pthread_mutex_lock(&(dir->dd_lock));
+-#endif
++      __UCLIBC_MUTEX_LOCK(dir->dd_lock);
+       lseek(dir->dd_fd, 0, SEEK_SET);
+       dir->dd_nextoff = dir->dd_nextloc = dir->dd_size = 0;
+-#ifdef __UCLIBC_HAS_THREADS__
+-      __pthread_mutex_unlock(&(dir->dd_lock));
+-#endif
++      __UCLIBC_MUTEX_UNLOCK(dir->dd_lock);
+ }
+diff --git a/libc/misc/dirent/seekdir.c b/libc/misc/dirent/seekdir.c
+index 139f1e1..6d6f5f0 100644
+--- a/libc/misc/dirent/seekdir.c
++++ b/libc/misc/dirent/seekdir.c
+@@ -3,19 +3,14 @@
+ #include <unistd.h>
+ #include "dirstream.h"
+-
+ void seekdir(DIR * dir, long int offset)
+ {
+       if (!dir) {
+               __set_errno(EBADF);
+               return;
+       }
+-#ifdef __UCLIBC_HAS_THREADS__
+-      __pthread_mutex_lock(&(dir->dd_lock));
+-#endif
++      __UCLIBC_MUTEX_LOCK(dir->dd_lock);
+       dir->dd_nextoff = lseek(dir->dd_fd, offset, SEEK_SET);
+       dir->dd_size = dir->dd_nextloc = 0;
+-#ifdef __UCLIBC_HAS_THREADS__
+-      __pthread_mutex_unlock(&(dir->dd_lock));
+-#endif
++      __UCLIBC_MUTEX_UNLOCK(dir->dd_lock);
+ }
+diff --git a/libc/misc/mntent/mntent.c b/libc/misc/mntent/mntent.c
+index d98a687..af6d848 100644
+--- a/libc/misc/mntent/mntent.c
++++ b/libc/misc/mntent/mntent.c
+@@ -3,15 +3,9 @@
+ #include <string.h>
+ #include <mntent.h>
+-#ifdef __UCLIBC_HAS_THREADS__
+-#include <pthread.h>
+-static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;
+-# define LOCK __pthread_mutex_lock(&mylock)
+-# define UNLOCK       __pthread_mutex_unlock(&mylock);
+-#else
+-# define LOCK
+-# define UNLOCK
+-#endif
++#include <bits/uClibc_mutex.h>
++
++__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER);
+ /* Reentrant version of getmntent.  */
+ struct mntent *getmntent_r (FILE *filep, 
+@@ -67,7 +61,7 @@ struct mntent *getmntent(FILE * filep)
+     struct mntent *tmp;
+     static char *buff = NULL;
+     static struct mntent mnt;
+-    LOCK;
++    __UCLIBC_MUTEX_LOCK(mylock);
+     
+     if (!buff) {
+             buff = malloc(BUFSIZ);
+@@ -76,7 +70,7 @@ struct mntent *getmntent(FILE * filep)
+     }
+     
+     tmp = getmntent_r(filep, &mnt, buff, BUFSIZ);
+-    UNLOCK;
++    __UCLIBC_MUTEX_UNLOCK(mylock);
+     return(tmp);
+ }
+diff --git a/libc/misc/pthread/weaks.c b/libc/misc/pthread/weaks.c
+index 89c2611..c27bd10 100644
+--- a/libc/misc/pthread/weaks.c
++++ b/libc/misc/pthread/weaks.c
+@@ -21,6 +21,7 @@
+ #include <limits.h>
+ #include <stdlib.h>
++static void __pthread_return_void __P ((void));
+ static int __pthread_return_0 __P ((void));
+ static int __pthread_return_1 __P ((void));
+@@ -104,8 +105,17 @@ weak_alias (__pthread_return_0, __pthrea
+ weak_alias (__pthread_return_0, __pthread_mutex_trylock)
+ weak_alias (__pthread_return_0, __pthread_mutex_unlock)
++weak_alias (__pthread_return_void, _pthread_cleanup_push_defer)
++weak_alias (__pthread_return_void, _pthread_cleanup_pop_restore)
++
+ /**********************************************************************/
++static void
++__pthread_return_void (void)
++{
++  return;
++}
++
+ static int
+ __pthread_return_0 (void)
+ {
+diff --git a/libc/misc/syslog/syslog.c b/libc/misc/syslog/syslog.c
+index 2b478e1..9e9ddbf 100644
+--- a/libc/misc/syslog/syslog.c
++++ b/libc/misc/syslog/syslog.c
+@@ -80,17 +80,9 @@
+ #include <ctype.h>
+ #include <signal.h>
++#include <bits/uClibc_mutex.h>
+-#ifdef __UCLIBC_HAS_THREADS__
+-#include <pthread.h>
+-static pthread_mutex_t mylock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+-# define LOCK __pthread_mutex_lock(&mylock)
+-# define UNLOCK       __pthread_mutex_unlock(&mylock);
+-#else
+-# define LOCK
+-# define UNLOCK
+-#endif
+-
++__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);
+ static int    LogFile = -1;           /* fd for log */
+ static int    connected;              /* have done connect */
+@@ -110,26 +102,26 @@ int setlogmask(int pmask);
+ static void 
+ closelog_intern(int to_default)
+ {
+-      LOCK;
++      __UCLIBC_MUTEX_LOCK(mylock);
+       if (LogFile != -1) {
+           (void) close(LogFile);
+       }
+       LogFile = -1;
+       connected = 0;
+       if (to_default)
+-      {
+-              LogStat = 0;
+-              LogTag = "syslog";
+-              LogFacility = LOG_USER;
+-              LogMask = 0xff;
+-      }
+-      UNLOCK;
++              {
++                      LogStat = 0;
++                      LogTag = "syslog";
++                      LogFacility = LOG_USER;
++                      LogMask = 0xff;
++              }
++      __UCLIBC_MUTEX_UNLOCK(mylock);
+ }
+ static void
+ sigpipe_handler (int sig)
+ {
+-  closelog_intern (0);
++      closelog_intern (0);
+ }
+ /*
+@@ -165,7 +157,7 @@ vsyslog( int pri, const char *fmt, va_li
+       saved_errno = errno;
+-      LOCK;
++      __UCLIBC_MUTEX_LOCK(mylock);
+       /* See if we should just throw out this message. */
+       if (!(LogMask & LOG_MASK(LOG_PRI(pri))) || (pri &~ (LOG_PRIMASK|LOG_FACMASK)))
+@@ -208,7 +200,7 @@ vsyslog( int pri, const char *fmt, va_li
+       if (p >= end || p < head_end) { /* Returned -1 in case of error... */
+               static const char truncate_msg[12] = "[truncated] ";
+               memmove(head_end + sizeof(truncate_msg), head_end,
+-                      end - head_end - sizeof(truncate_msg));
++                              end - head_end - sizeof(truncate_msg));
+               memcpy(head_end, truncate_msg, sizeof(truncate_msg));
+               if (p < head_end) {
+                       while (p < end && *p) {
+@@ -261,11 +253,11 @@ vsyslog( int pri, const char *fmt, va_li
+               (void)close(fd);
+       }
+-getout:
+-      UNLOCK;
++ getout:
++      __UCLIBC_MUTEX_UNLOCK(mylock);
+       if (sigpipe == 0)
+               sigaction (SIGPIPE, &oldaction,
+-                      (struct sigaction *) NULL);
++                                 (struct sigaction *) NULL);
+ }
+ /*
+@@ -276,48 +268,48 @@ openlog( const char *ident, int logstat,
+ {
+     int logType = SOCK_DGRAM;
+-    LOCK;
++    __UCLIBC_MUTEX_LOCK(mylock);
+     if (ident != NULL)
+-      LogTag = ident;
++              LogTag = ident;
+     LogStat = logstat;
+     if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0)
+-      LogFacility = logfac;
++              LogFacility = logfac;
+     if (LogFile == -1) {
+-      SyslogAddr.sa_family = AF_UNIX;
+-      (void)strncpy(SyslogAddr.sa_data, _PATH_LOG,
+-                    sizeof(SyslogAddr.sa_data));
+-retry:
+-      if (LogStat & LOG_NDELAY) {
+-          if ((LogFile = socket(AF_UNIX, logType, 0)) == -1){
+-              UNLOCK;
+-              return;
+-          }
+-          /*                  fcntl(LogFile, F_SETFD, 1); */
+-      }
++              SyslogAddr.sa_family = AF_UNIX;
++              (void)strncpy(SyslogAddr.sa_data, _PATH_LOG,
++                                        sizeof(SyslogAddr.sa_data));
++      retry:
++              if (LogStat & LOG_NDELAY) {
++                      if ((LogFile = socket(AF_UNIX, logType, 0)) == -1){
++                              goto DONE;
++                      }
++                      /*                      fcntl(LogFile, F_SETFD, 1); */
++              }
+     }
+     if (LogFile != -1 && !connected) {
+-      if (connect(LogFile, &SyslogAddr, sizeof(SyslogAddr) - 
+-                  sizeof(SyslogAddr.sa_data) + strlen(SyslogAddr.sa_data)) != -1)
+-      {
+-          connected = 1;
+-      } else if (logType == SOCK_DGRAM) {
+-          logType = SOCK_STREAM;
+-          if (LogFile != -1) {
+-              close(LogFile);
+-              LogFile = -1;
+-          }
+-          goto retry;
+-      } else {
+-          if (LogFile != -1) {
+-              close(LogFile);
+-              LogFile = -1;
+-          }
+-      }
++              if (connect(LogFile, &SyslogAddr, sizeof(SyslogAddr) - 
++                                      sizeof(SyslogAddr.sa_data) + strlen(SyslogAddr.sa_data)) != -1)
++                      {
++                              connected = 1;
++                      } else if (logType == SOCK_DGRAM) {
++                              logType = SOCK_STREAM;
++                              if (LogFile != -1) {
++                                      close(LogFile);
++                                      LogFile = -1;
++                              }
++                              goto retry;
++                      } else {
++                              if (LogFile != -1) {
++                                      close(LogFile);
++                                      LogFile = -1;
++                              }
++                      }
+     }
+-    UNLOCK;
++ DONE:
++    __UCLIBC_MUTEX_UNLOCK(mylock);
+ }
+ /*
+@@ -335,10 +327,10 @@ int setlogmask(int pmask)
+     int omask;
+     omask = LogMask;
+-    LOCK;
++    __UCLIBC_MUTEX_LOCK(mylock);
+     if (pmask != 0)
+-      LogMask = pmask;
+-    UNLOCK;
++              LogMask = pmask;
++    __UCLIBC_MUTEX_UNLOCK(mylock);
+     return (omask);
+ }
+diff --git a/libc/misc/time/time.c b/libc/misc/time/time.c
+index f43bb8a..6165a52 100644
+--- a/libc/misc/time/time.c
++++ b/libc/misc/time/time.c
+@@ -143,6 +143,8 @@
+ #include <locale.h>
+ #include <bits/uClibc_uintmaxtostr.h>
++#include <bits/uClibc_mutex.h>
++
+ #ifdef __UCLIBC_HAS_XLOCALE__
+ #include <xlocale.h>
+ #endif
+@@ -191,21 +193,7 @@ typedef struct {
+       char tzname[TZNAME_MAX+1];
+ } rule_struct;
+-#ifdef __UCLIBC_HAS_THREADS__
+-
+-#include <pthread.h>
+-
+-extern pthread_mutex_t _time_tzlock;
+-
+-#define TZLOCK                __pthread_mutex_lock(&_time_tzlock)
+-#define TZUNLOCK      __pthread_mutex_unlock(&_time_tzlock)
+-
+-#else
+-
+-#define TZLOCK                ((void) 0)
+-#define TZUNLOCK      ((void) 0)
+-
+-#endif
++__UCLIBC_MUTEX_EXTERN(_time_tzlock);
+ extern rule_struct _time_tzinfo[2];
+@@ -542,13 +530,13 @@ struct tm *localtime(const time_t *timer
+ struct tm *localtime_r(register const time_t *__restrict timer,
+                                          register struct tm *__restrict result)
+ {
+-      TZLOCK;
++      __UCLIBC_MUTEX_LOCK(_time_tzlock);
+       tzset();
+       __time_localtime_tzi(timer, result, _time_tzinfo);
+-      TZUNLOCK;
++      __UCLIBC_MUTEX_UNLOCK(_time_tzlock);
+       return result;
+ }
+@@ -1037,7 +1025,7 @@ size_t __XL(strftime)(char *__restrict s
+                       goto LOOP;
+               }
+-              o = spec + 26;          /* set to "????" */
++              o = ((const char *) spec) + 26; /* set to "????" */
+               if ((code & MASK_SPEC) == CALC_SPEC) {
+                       if (*p == 's') {
+@@ -1073,17 +1061,15 @@ size_t __XL(strftime)(char *__restrict s
+ #ifdef __UCLIBC_HAS_TM_EXTENSIONS__
+-#define RSP_TZUNLOCK  ((void) 0)
+ #define RSP_TZNAME            timeptr->tm_zone
+ #define RSP_GMT_OFFSET        (-timeptr->tm_gmtoff)
+ #else
+-#define RSP_TZUNLOCK  TZUNLOCK
+ #define RSP_TZNAME            rsp->tzname
+ #define RSP_GMT_OFFSET        rsp->gmt_offset
+-                              TZLOCK;
++                              __UCLIBC_MUTEX_LOCK(_time_tzlock);
+                               rsp = _time_tzinfo;
+                               if (timeptr->tm_isdst > 0) {
+@@ -1114,15 +1100,17 @@ size_t __XL(strftime)(char *__restrict s
+                                       }
+ #endif
+                                       o_count = SIZE_MAX;
+-                                      RSP_TZUNLOCK;
++/*                                    RSP_TZUNLOCK; */
++#ifdef __UCLIBC_HAS_TM_EXTENSIONS__
+                                       goto OUTPUT;
++#endif
+                               } else {                /* z */
+                                       *s = '+';
+                                       if ((tzo = -RSP_GMT_OFFSET) < 0) {
+                                               tzo = -tzo;
+                                               *s = '-';
+                                       }
+-                                      RSP_TZUNLOCK;
++/*                                    RSP_TZUNLOCK; */
+                                       ++s;
+                                       --count;
+@@ -1131,7 +1119,13 @@ size_t __XL(strftime)(char *__restrict s
+                       
+                                       i = 16 + 6;     /* 0-fill, width = 4 */
+                               }
+-
++#ifdef __UCLIBC_HAS_TM_EXTENSIONS__
++#else
++                              __UCLIBC_MUTEX_UNLOCK(_time_tzlock);
++                              if (*p == 'Z') {
++                                      goto OUTPUT;
++                              }
++#endif
+                       } else {
+                               /* TODO: don't need year for U, W */
+                               for (i=0 ; i < 3 ; i++) {
+@@ -1664,9 +1658,7 @@ int daylight = 0;
+ long timezone = 0;
+ char *tzname[2] = { (char *) UTC, (char *) (UTC-1) };
+-#ifdef __UCLIBC_HAS_THREADS__
+-pthread_mutex_t _time_tzlock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+-#endif
++__UCLIBC_MUTEX_INIT(_time_tzlock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);
+ rule_struct _time_tzinfo[2];
+@@ -1796,7 +1788,7 @@ void tzset(void)
+       static char oldval[TZ_BUFLEN]; /* BSS-zero'd. */
+ #endif /* __UCLIBC_HAS_TZ_CACHING__ */
+-      TZLOCK;
++      __UCLIBC_MUTEX_LOCK(_time_tzlock);
+       e = getenv(TZ);                         /* TZ env var always takes precedence. */
+@@ -1962,10 +1954,10 @@ void tzset(void)
+       daylight = !!_time_tzinfo[1].tzname[0];
+       timezone = _time_tzinfo[0].gmt_offset;
+-#if defined(__UCLIBC_HAS_TZ_FILE__)
++#if defined(__UCLIBC_HAS_TZ_FILE__) || defined(__UCLIBC_HAS_TZ_CACHING__)
+  FAST_DONE:
+ #endif
+-      TZUNLOCK;
++      __UCLIBC_MUTEX_UNLOCK(_time_tzlock);
+ }
+ #endif
+@@ -2167,13 +2159,13 @@ time_t _time_mktime(struct tm *timeptr, 
+ {
+       time_t t;
+-      TZLOCK;
++      __UCLIBC_MUTEX_LOCK(_time_tzlock);
+       tzset();
+       t = _time_mktime_tzi(timeptr, store_on_success, _time_tzinfo);
+-      TZUNLOCK;
++      __UCLIBC_MUTEX_UNLOCK(_time_tzlock);
+       return t;
+ }
+diff --git a/libc/misc/ttyent/getttyent.c b/libc/misc/ttyent/getttyent.c
+index 6e2fbd2..c85c73a 100644
+--- a/libc/misc/ttyent/getttyent.c
++++ b/libc/misc/ttyent/getttyent.c
+@@ -35,9 +35,6 @@
+ #include <ctype.h>
+ #include <string.h>
+ #include <stdlib.h>
+-#ifdef __UCLIBC_HAS_THREADS__
+-#include <pthread.h>
+-#endif
+ static char zapchar;
+ static FILE *tf;
+@@ -50,8 +47,8 @@ struct ttyent * getttynam(const char *tt
+     setttyent();
+     while ((t = getttyent()))
+-      if (!strcmp(tty, t->ty_name))
+-          break;
++              if (!strcmp(tty, t->ty_name))
++                      break;
+     endttyent();
+     return (t);
+ }
+@@ -67,27 +64,27 @@ static char * skip(register char *p)
+     register int c, q;
+     for (q = 0, t = p; (c = *p) != '\0'; p++) {
+-      if (c == '"') {
+-          q ^= QUOTED;        /* obscure, but nice */
+-          continue;
+-      }
+-      if (q == QUOTED && *p == '\\' && *(p+1) == '"')
+-          p++;
+-      *t++ = *p;
+-      if (q == QUOTED)
+-          continue;
+-      if (c == '#') {
+-          zapchar = c;
+-          *p = 0;
+-          break;
+-      }
+-      if (c == '\t' || c == ' ' || c == '\n') {
+-          zapchar = c;
+-          *p++ = 0;
+-          while ((c = *p) == '\t' || c == ' ' || c == '\n')
+-              p++;
+-          break;
+-      }
++              if (c == '"') {
++                      q ^= QUOTED;    /* obscure, but nice */
++                      continue;
++              }
++              if (q == QUOTED && *p == '\\' && *(p+1) == '"')
++                      p++;
++              *t++ = *p;
++              if (q == QUOTED)
++                      continue;
++              if (c == '#') {
++                      zapchar = c;
++                      *p = 0;
++                      break;
++              }
++              if (c == '\t' || c == ' ' || c == '\n') {
++                      zapchar = c;
++                      *p++ = 0;
++                      while ((c = *p) == '\t' || c == ' ' || c == '\n')
++                              p++;
++                      break;
++              }
+     }
+     *--t = '\0';
+     return (p);
+@@ -104,46 +101,46 @@ struct ttyent * getttyent(void)
+     register int c;
+     register char *p;
+     static char *line = NULL;
++    struct ttyent *retval = NULL;
+     if (!tf && !setttyent())
+-      return (NULL);
++              return (NULL);
+     if (!line) {
+-            line = malloc(BUFSIZ);
++              line = malloc(BUFSIZ);
+               if (!line)
+                   abort();
+     }
+-      __STDIO_ALWAYS_THREADLOCK(tf);
++    __STDIO_ALWAYS_THREADLOCK(tf);
+     for (;;) {
+-      if (!fgets_unlocked(p = line, BUFSIZ, tf)) {
+-              __STDIO_ALWAYS_THREADUNLOCK(tf);
+-          return (NULL);
+-      }
+-      /* skip lines that are too big */
+-      if (!index(p, '\n')) {
+-          while ((c = getc_unlocked(tf)) != '\n' && c != EOF)
+-              ;
+-          continue;
+-      }
+-      while (isspace(*p))
+-          ++p;
+-      if (*p && *p != '#')
+-          break;
++              if (!fgets_unlocked(p = line, BUFSIZ, tf)) {
++                      goto DONE;
++              }
++              /* skip lines that are too big */
++              if (!index(p, '\n')) {
++                      while ((c = getc_unlocked(tf)) != '\n' && c != EOF)
++                              ;
++                      continue;
++              }
++              while (isspace(*p))
++                      ++p;
++              if (*p && *p != '#')
++                      break;
+     }
+     zapchar = 0;
+     tty.ty_name = p;
+     p = skip(p);
+     if (!*(tty.ty_getty = p))
+-      tty.ty_getty = tty.ty_type = NULL;
++              tty.ty_getty = tty.ty_type = NULL;
+     else {
+-      p = skip(p);
+-      if (!*(tty.ty_type = p))
+-          tty.ty_type = NULL;
+-      else
+-          p = skip(p);
++              p = skip(p);
++              if (!*(tty.ty_type = p))
++                      tty.ty_type = NULL;
++              else
++                      p = skip(p);
+     }
+     tty.ty_status = 0;
+     tty.ty_window = NULL;
+@@ -151,43 +148,45 @@ struct ttyent * getttyent(void)
+ #define       scmp(e) !strncmp(p, e, sizeof(e) - 1) && isspace(p[sizeof(e) - 1])
+ #define       vcmp(e) !strncmp(p, e, sizeof(e) - 1) && p[sizeof(e) - 1] == '='
+     for (; *p; p = skip(p)) {
+-      if (scmp(_TTYS_OFF))
+-          tty.ty_status &= ~TTY_ON;
+-      else if (scmp(_TTYS_ON))
+-          tty.ty_status |= TTY_ON;
+-      else if (scmp(_TTYS_SECURE))
+-          tty.ty_status |= TTY_SECURE;
+-      else if (vcmp(_TTYS_WINDOW))
+-          tty.ty_window = value(p);
+-      else
+-          break;
++              if (scmp(_TTYS_OFF))
++                      tty.ty_status &= ~TTY_ON;
++              else if (scmp(_TTYS_ON))
++                      tty.ty_status |= TTY_ON;
++              else if (scmp(_TTYS_SECURE))
++                      tty.ty_status |= TTY_SECURE;
++              else if (vcmp(_TTYS_WINDOW))
++                      tty.ty_window = value(p);
++              else
++                      break;
+     }
+-    /* We can release the lock only here since `zapchar' is global.  */
+-      __STDIO_ALWAYS_THREADUNLOCK(tf);
+     if (zapchar == '#' || *p == '#')
+-      while ((c = *++p) == ' ' || c == '\t')
+-          ;
++              while ((c = *++p) == ' ' || c == '\t')
++                      ;
+     tty.ty_comment = p;
+     if (*p == 0)
+-      tty.ty_comment = 0;
++              tty.ty_comment = 0;
+     if ((p = index(p, '\n')))
+-      *p = '\0';
+-    return (&tty);
++              *p = '\0';
++    retval = &tty;
++
++ DONE:
++    __STDIO_ALWAYS_THREADUNLOCK(tf);
++    return retval;
+ }
+ int setttyent(void)
+ {
+     if (tf) {
+-      rewind(tf);
+-      return (1);
++              rewind(tf);
++              return (1);
+     } else if ((tf = fopen(_PATH_TTYS, "r"))) {
+-      /* We do the locking ourselves.  */
++              /* We do the locking ourselves.  */
+ #ifdef __UCLIBC_HAS_THREADS__
+-      __fsetlocking (tf, FSETLOCKING_BYCALLER);
++              __fsetlocking (tf, FSETLOCKING_BYCALLER);
+ #endif
+-      return (1);
++              return (1);
+     }
+     return (0);
+ }
+@@ -197,9 +196,9 @@ int endttyent(void)
+     int rval;
+     if (tf) {
+-      rval = !(fclose(tf) == EOF);
+-      tf = NULL;
+-      return (rval);
++              rval = !(fclose(tf) == EOF);
++              tf = NULL;
++              return (rval);
+     }
+     return (1);
+ }
+diff --git a/libc/misc/utmp/utent.c b/libc/misc/utmp/utent.c
+index c1d8d6f..0fc6df4 100644
+--- a/libc/misc/utmp/utent.c
++++ b/libc/misc/utmp/utent.c
+@@ -20,19 +20,9 @@
+ #include <string.h>
+ #include <utmp.h>
++#include <bits/uClibc_mutex.h>
+-
+-#ifdef __UCLIBC_HAS_THREADS__
+-#include <pthread.h>
+-static pthread_mutex_t utmplock = PTHREAD_MUTEX_INITIALIZER;
+-# define LOCK __pthread_mutex_lock(&utmplock)
+-# define UNLOCK       __pthread_mutex_unlock(&utmplock)
+-#else
+-# define LOCK
+-# define UNLOCK
+-#endif
+-
+-
++__UCLIBC_MUTEX_STATIC(utmplock, PTHREAD_MUTEX_INITIALIZER);
+ /* Some global crap */
+ static int static_fd = -1;
+@@ -46,19 +36,19 @@ static struct utmp *__getutent(int utmp_
+ {
+     if (utmp_fd == -1) {
+-      setutent();
++              setutent();
+     }
+     if (utmp_fd == -1) {
+-      return NULL;
++              return NULL;
+     }
+-    LOCK;
++    __UCLIBC_MUTEX_LOCK(utmplock);
+     if (read(utmp_fd, (char *) &static_utmp, sizeof(struct utmp)) != sizeof(struct utmp)) 
+-    {
+-      return NULL;
+-    }
++              {
++                      return NULL;
++              }
+-    UNLOCK;
++    __UCLIBC_MUTEX_UNLOCK(utmplock);
+     return &static_utmp;
+ }
+@@ -66,39 +56,39 @@ void setutent(void)
+ {
+     int ret;
+-    LOCK;
++    __UCLIBC_MUTEX_LOCK(utmplock);
+     if (static_fd == -1) {
+-      if ((static_fd = open(static_ut_name, O_RDWR)) < 0) {
+-          if ((static_fd = open(static_ut_name, O_RDONLY)) < 0) {
+-              goto bummer;
+-          }
+-      }
+-      /* Make sure the file will be closed on exec()  */
+-      ret = fcntl(static_fd, F_GETFD, 0);
+-      if (ret >= 0) {
+-          ret = fcntl(static_fd, F_GETFD, 0);
+-      }
+-      if (ret < 0) {
+-bummer:
+-          UNLOCK;
+-          static_fd = -1;
+-          close(static_fd);
+-          return;
+-      }
++              if ((static_fd = open(static_ut_name, O_RDWR)) < 0) {
++                      if ((static_fd = open(static_ut_name, O_RDONLY)) < 0) {
++                              goto bummer;
++                      }
++              }
++              /* Make sure the file will be closed on exec()  */
++              ret = fcntl(static_fd, F_GETFD, 0);
++              if (ret >= 0) {
++                      ret = fcntl(static_fd, F_GETFD, 0);
++              }
++              if (ret < 0) {
++              bummer:
++                      close(static_fd);
++                      static_fd = -1;
++                      goto DONE;
++              }
+     }
+     lseek(static_fd, 0, SEEK_SET);
+-    UNLOCK;
++ DONE:
++    __UCLIBC_MUTEX_UNLOCK(utmplock);
+     return;
+ }
+ void endutent(void)
+ {
+-    LOCK;
++    __UCLIBC_MUTEX_LOCK(utmplock);
+     if (static_fd != -1) {
+-      close(static_fd);
++              close(static_fd);
+     }
+     static_fd = -1;
+-    UNLOCK;
++    __UCLIBC_MUTEX_UNLOCK(utmplock);
+ }
+ /* Locking is done in __getutent */
+@@ -113,22 +103,22 @@ struct utmp *getutid (const struct utmp 
+     struct utmp *lutmp;
+     while ((lutmp = __getutent(static_fd)) != NULL) {
+-      if (    (utmp_entry->ut_type == RUN_LVL ||
+-               utmp_entry->ut_type == BOOT_TIME ||
+-               utmp_entry->ut_type == NEW_TIME ||
+-               utmp_entry->ut_type == OLD_TIME) &&
+-              lutmp->ut_type == utmp_entry->ut_type)  
+-      {
+-          return lutmp;
+-      }
+-      if (    (utmp_entry->ut_type == INIT_PROCESS ||
+-               utmp_entry->ut_type == DEAD_PROCESS ||
+-               utmp_entry->ut_type == LOGIN_PROCESS ||
+-               utmp_entry->ut_type == USER_PROCESS) &&
+-              !strncmp(lutmp->ut_id, utmp_entry->ut_id, sizeof(lutmp->ut_id))) 
+-      {
+-          return lutmp;
+-      }
++              if (    (utmp_entry->ut_type == RUN_LVL ||
++                               utmp_entry->ut_type == BOOT_TIME ||
++                               utmp_entry->ut_type == NEW_TIME ||
++                               utmp_entry->ut_type == OLD_TIME) &&
++                              lutmp->ut_type == utmp_entry->ut_type)  
++                      {
++                              return lutmp;
++                      }
++              if (    (utmp_entry->ut_type == INIT_PROCESS ||
++                               utmp_entry->ut_type == DEAD_PROCESS ||
++                               utmp_entry->ut_type == LOGIN_PROCESS ||
++                               utmp_entry->ut_type == USER_PROCESS) &&
++                              !strncmp(lutmp->ut_id, utmp_entry->ut_id, sizeof(lutmp->ut_id))) 
++                      {
++                              return lutmp;
++                      }
+     }
+     return NULL;
+@@ -140,11 +130,11 @@ struct utmp *getutline(const struct utmp
+     struct utmp *lutmp;
+     while ((lutmp = __getutent(static_fd)) != NULL) {
+-      if ((lutmp->ut_type == USER_PROCESS || lutmp->ut_type == LOGIN_PROCESS) &&
+-              !strcmp(lutmp->ut_line, utmp_entry->ut_line))
+-      {
+-          return lutmp;
+-      }
++              if ((lutmp->ut_type == USER_PROCESS || lutmp->ut_type == LOGIN_PROCESS) &&
++                      !strcmp(lutmp->ut_line, utmp_entry->ut_line))
++                      {
++                              return lutmp;
++                      }
+     }
+     return NULL;
+@@ -152,42 +142,42 @@ struct utmp *getutline(const struct utmp
+ struct utmp *pututline (const struct utmp *utmp_entry)
+ {
+-    LOCK;
++    __UCLIBC_MUTEX_LOCK(utmplock);
+     /* Ignore the return value.  That way, if they've already positioned
+        the file pointer where they want it, everything will work out. */
+     lseek(static_fd, (off_t) - sizeof(struct utmp), SEEK_CUR);
+     if (getutid(utmp_entry) != NULL) {
+-      lseek(static_fd, (off_t) - sizeof(struct utmp), SEEK_CUR);
+-      if (write(static_fd, utmp_entry, sizeof(struct utmp)) != sizeof(struct utmp))
+-          return NULL;
++              lseek(static_fd, (off_t) - sizeof(struct utmp), SEEK_CUR);
++              if (write(static_fd, utmp_entry, sizeof(struct utmp)) != sizeof(struct utmp))
++                      return NULL;
+     } else {
+-      lseek(static_fd, (off_t) 0, SEEK_END);
+-      if (write(static_fd, utmp_entry, sizeof(struct utmp)) != sizeof(struct utmp))
+-          return NULL;
++              lseek(static_fd, (off_t) 0, SEEK_END);
++              if (write(static_fd, utmp_entry, sizeof(struct utmp)) != sizeof(struct utmp))
++                      return NULL;
+     }
+-    UNLOCK;
++    __UCLIBC_MUTEX_UNLOCK(utmplock);
+     return (struct utmp *)utmp_entry;
+ }
+ int utmpname (const char *new_ut_name)
+ {
+-    LOCK;
++    __UCLIBC_MUTEX_LOCK(utmplock);
+     if (new_ut_name != NULL) {
+-      if (static_ut_name != default_file_name)
+-          free((char *)static_ut_name);
+-      static_ut_name = strdup(new_ut_name);
+-      if (static_ut_name == NULL) {
+-          /* We should probably whine about out-of-memory 
+-           * errors here...  Instead just reset to the default */
+-          static_ut_name = default_file_name;
+-      }
++              if (static_ut_name != default_file_name)
++                      free((char *)static_ut_name);
++              static_ut_name = strdup(new_ut_name);
++              if (static_ut_name == NULL) {
++                      /* We should probably whine about out-of-memory 
++                       * errors here...  Instead just reset to the default */
++                      static_ut_name = default_file_name;
++              }
+     }
+     if (static_fd != -1)
+-      close(static_fd);
+-    UNLOCK;
++              close(static_fd);
++    __UCLIBC_MUTEX_UNLOCK(utmplock);
+     return 0;
+ }
+diff --git a/libc/misc/wchar/wstdio.c b/libc/misc/wchar/wstdio.c
+index b49494f..408c57a 100644
+--- a/libc/misc/wchar/wstdio.c
++++ b/libc/misc/wchar/wstdio.c
+@@ -82,9 +82,6 @@ strong_alias(NAME,NAME##_unlocked) \
+ void NAME PARAMS
+ #endif
+-#define __STDIO_THREADLOCK_OPENLIST
+-#define __STDIO_THREADUNLOCK_OPENLIST
+-
+ #else  /* __UCLIBC_HAS_THREADS__ */
+ #include <pthread.h>
+@@ -112,15 +109,6 @@ void NAME PARAMS \
+ } \
+ void NAME##_unlocked PARAMS
+-#define __STDIO_THREADLOCK_OPENLIST \
+-      __pthread_mutex_lock(&_stdio_openlist_lock)
+-
+-#define __STDIO_THREADUNLOCK_OPENLIST \
+-      __pthread_mutex_unlock(&_stdio_openlist_lock)
+-
+-#define __STDIO_THREADTRYLOCK_OPENLIST \
+-      __pthread_mutex_trylock(&_stdio_openlist_lock)
+-
+ #endif /* __UCLIBC_HAS_THREADS__ */
+ #ifndef __STDIO_BUFFERS
+diff --git a/libc/pwd_grp/lckpwdf.c b/libc/pwd_grp/lckpwdf.c
+index 6b9c251..063fed4 100644
+--- a/libc/pwd_grp/lckpwdf.c
++++ b/libc/pwd_grp/lckpwdf.c
+@@ -27,15 +27,9 @@
+ #include <sys/file.h>
+ #include <paths.h>
+-#ifdef __UCLIBC_HAS_THREADS__
+-#include <pthread.h>
+-static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;
+-# define LOCK   __pthread_mutex_lock(&mylock)
+-# define UNLOCK __pthread_mutex_unlock(&mylock);
+-#else       
+-# define LOCK
+-# define UNLOCK
+-#endif      
++#include <bits/uClibc_mutex.h>
++
++__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER);
+ /* How long to wait for getting the lock before returning with an
+    error.  */
+@@ -57,18 +51,18 @@ int lckpwdf (void)
+       struct sigaction new_act;   /* New signal action.  */
+       struct flock fl;            /* Information struct for locking.  */
+       int result;
++      int rv = -1;
+       if (lock_fd != -1)
+               /* Still locked by own process.  */
+               return -1;
+-      LOCK;
++      __UCLIBC_MUTEX_LOCK(mylock);
+       lock_fd = open (_PATH_PASSWD, O_WRONLY);
+       if (lock_fd == -1) {
+               /* Cannot create lock file.  */
+-              UNLOCK;
+-              return -1;
++              goto DONE;
+       }
+       /* Make sure file gets correctly closed when process finished.  */
+@@ -77,16 +71,14 @@ int lckpwdf (void)
+               /* Cannot get file flags.  */
+               close(lock_fd);
+               lock_fd = -1;
+-              UNLOCK;
+-              return -1;
++              goto DONE;
+       }
+       flags |= FD_CLOEXEC;            /* Close on exit.  */
+       if (fcntl (lock_fd, F_SETFD, flags) < 0) {
+               /* Cannot set new flags.  */
+               close(lock_fd);
+               lock_fd = -1;
+-              UNLOCK;
+-              return -1;
++              goto DONE;
+       }
+       /* Now we have to get exclusive write access.  Since multiple
+@@ -107,8 +99,7 @@ int lckpwdf (void)
+               /* Cannot install signal handler.  */
+               close(lock_fd);
+               lock_fd = -1;
+-              UNLOCK;
+-              return -1;
++              goto DONE;
+       }
+       /* Now make sure the alarm signal is not blocked.  */
+@@ -118,8 +109,7 @@ int lckpwdf (void)
+               sigaction (SIGALRM, &saved_act, NULL);
+               close(lock_fd);
+               lock_fd = -1;
+-              UNLOCK;
+-              return -1;
++              goto DONE;
+       }
+       /* Start timer.  If we cannot get the lock in the specified time we
+@@ -146,12 +136,14 @@ int lckpwdf (void)
+       if (result < 0) {
+               close(lock_fd);
+               lock_fd = -1;
+-              UNLOCK;
+-              return -1;
++              goto DONE;
+       }
+-      UNLOCK;
+-      return 0;
++      rv = 0;
++
++ DONE:
++      __UCLIBC_MUTEX_UNLOCK(mylock);
++      return rv;
+ }
+@@ -164,11 +156,11 @@ int ulckpwdf (void)
+               result = -1;
+       }
+       else {
+-              LOCK;
++              __UCLIBC_MUTEX_LOCK(mylock);
+               result = close (lock_fd);
+               /* Mark descriptor as unused.  */
+               lock_fd = -1;
+-              UNLOCK;
++              __UCLIBC_MUTEX_UNLOCK(mylock);
+       }
+       return result;
+diff --git a/libc/pwd_grp/pwd_grp.c b/libc/pwd_grp/pwd_grp.c
+index 91c0d83..a302c7c 100644
+--- a/libc/pwd_grp/pwd_grp.c
++++ b/libc/pwd_grp/pwd_grp.c
+@@ -42,9 +42,8 @@
+ #include <pwd.h>
+ #include <grp.h>
+ #include <shadow.h>
+-#ifdef __UCLIBC_HAS_THREADS__
+-#include <pthread.h>
+-#endif
++
++#include <bits/uClibc_mutex.h>
+ /**********************************************************************/
+ /* Sizes for staticly allocated buffers. */
+@@ -445,34 +444,27 @@ int getpw(uid_t uid, char *buf)
+ /**********************************************************************/
+ #ifdef L_getpwent_r
+-#ifdef __UCLIBC_HAS_THREADS__
+-static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;
+-# define LOCK         __pthread_mutex_lock(&mylock)
+-# define UNLOCK               __pthread_mutex_unlock(&mylock);
+-#else       
+-# define LOCK         ((void) 0)
+-# define UNLOCK               ((void) 0)
+-#endif      
++__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER);
+ static FILE *pwf /*= NULL*/;
+ void setpwent(void)
+ {
+-      LOCK;
++      __UCLIBC_MUTEX_LOCK(mylock);
+       if (pwf) {
+               rewind(pwf);
+       }
+-      UNLOCK;
++      __UCLIBC_MUTEX_UNLOCK(mylock);
+ }
+ void endpwent(void)
+ {
+-      LOCK;
++      __UCLIBC_MUTEX_LOCK(mylock);
+       if (pwf) {
+               fclose(pwf);
+               pwf = NULL;
+       }
+-      UNLOCK;
++      __UCLIBC_MUTEX_UNLOCK(mylock);
+ }
+@@ -482,7 +474,7 @@ int getpwent_r(struct passwd *__restrict
+ {
+       int rv;
+-      LOCK;
++      __UCLIBC_MUTEX_LOCK(mylock);
+       *result = NULL;                         /* In case of error... */
+@@ -500,7 +492,7 @@ int getpwent_r(struct passwd *__restrict
+       }
+  ERR:
+-      UNLOCK;
++      __UCLIBC_MUTEX_UNLOCK(mylock);
+       return rv;
+ }
+@@ -509,34 +501,27 @@ int getpwent_r(struct passwd *__restrict
+ /**********************************************************************/
+ #ifdef L_getgrent_r
+-#ifdef __UCLIBC_HAS_THREADS__
+-static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;
+-# define LOCK         __pthread_mutex_lock(&mylock)
+-# define UNLOCK               __pthread_mutex_unlock(&mylock);
+-#else       
+-# define LOCK         ((void) 0)
+-# define UNLOCK               ((void) 0)
+-#endif      
++__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER);
+ static FILE *grf /*= NULL*/;
+ void setgrent(void)
+ {
+-      LOCK;
++      __UCLIBC_MUTEX_LOCK(mylock);
+       if (grf) {
+               rewind(grf);
+       }
+-      UNLOCK;
++      __UCLIBC_MUTEX_UNLOCK(mylock);
+ }
+ void endgrent(void)
+ {
+-      LOCK;
++      __UCLIBC_MUTEX_LOCK(mylock);
+       if (grf) {
+               fclose(grf);
+               grf = NULL;
+       }
+-      UNLOCK;
++      __UCLIBC_MUTEX_UNLOCK(mylock);
+ }
+ int getgrent_r(struct group *__restrict resultbuf,
+@@ -545,7 +530,7 @@ int getgrent_r(struct group *__restrict 
+ {
+       int rv;
+-      LOCK;
++      __UCLIBC_MUTEX_LOCK(mylock);
+       *result = NULL;                         /* In case of error... */
+@@ -563,7 +548,7 @@ int getgrent_r(struct group *__restrict 
+       }
+  ERR:
+-      UNLOCK;
++      __UCLIBC_MUTEX_UNLOCK(mylock);
+       return rv;
+ }
+@@ -572,34 +557,27 @@ int getgrent_r(struct group *__restrict 
+ /**********************************************************************/
+ #ifdef L_getspent_r
+-#ifdef __UCLIBC_HAS_THREADS__
+-static pthread_mutex_t mylock =  PTHREAD_MUTEX_INITIALIZER;
+-# define LOCK         __pthread_mutex_lock(&mylock)
+-# define UNLOCK               __pthread_mutex_unlock(&mylock);
+-#else       
+-# define LOCK         ((void) 0)
+-# define UNLOCK               ((void) 0)
+-#endif      
++__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER);
+ static FILE *spf /*= NULL*/;
+ void setspent(void)
+ {
+-      LOCK;
++      __UCLIBC_MUTEX_LOCK(mylock);
+       if (spf) {
+               rewind(spf);
+       }
+-      UNLOCK;
++      __UCLIBC_MUTEX_UNLOCK(mylock);
+ }
+ void endspent(void)
+ {
+-      LOCK;
++      __UCLIBC_MUTEX_LOCK(mylock);
+       if (spf) {
+               fclose(spf);
+               spf = NULL;
+       }
+-      UNLOCK;
++      __UCLIBC_MUTEX_UNLOCK(mylock);
+ }
+ int getspent_r(struct spwd *resultbuf, char *buffer, 
+@@ -607,7 +585,7 @@ int getspent_r(struct spwd *resultbuf, c
+ {
+       int rv;
+-      LOCK;
++      __UCLIBC_MUTEX_LOCK(mylock);
+       *result = NULL;                         /* In case of error... */
+@@ -625,7 +603,7 @@ int getspent_r(struct spwd *resultbuf, c
+       }
+  ERR:
+-      UNLOCK;
++      __UCLIBC_MUTEX_UNLOCK(mylock);
+       return rv;
+ }
+diff --git a/libc/stdio/_READ.c b/libc/stdio/_READ.c
+index 7d3c38c..fe1bc91 100644
+--- a/libc/stdio/_READ.c
++++ b/libc/stdio/_READ.c
+@@ -41,7 +41,7 @@ size_t __stdio_READ(register FILE *strea
+ #warning EINTR?
+ #endif
+ /*    RETRY: */
+-              if ((rv = __READ(stream, buf, bufsize)) <= 0) {
++              if ((rv = __READ(stream, (char *) buf, bufsize)) <= 0) {
+                       if (rv == 0) {
+                               __STDIO_STREAM_SET_EOF(stream);
+                       } else {
+diff --git a/libc/stdio/_WRITE.c b/libc/stdio/_WRITE.c
+index d300d39..4131eb7 100644
+--- a/libc/stdio/_WRITE.c
++++ b/libc/stdio/_WRITE.c
+@@ -47,7 +47,7 @@ size_t __stdio_WRITE(register FILE *stre
+                       return bufsize;
+               }
+               stodo = (todo <= SSIZE_MAX) ? todo : SSIZE_MAX;
+-              if ((rv = __WRITE(stream, buf, stodo)) >= 0) {
++              if ((rv = __WRITE(stream, (char *) buf, stodo)) >= 0) {
+ #ifdef __UCLIBC_MJN3_ONLY__
+ #warning TODO: Make custom stream write return check optional.
+ #endif
+diff --git a/libc/stdio/_fopen.c b/libc/stdio/_fopen.c
+index f7f5bb6..4984f11 100644
+--- a/libc/stdio/_fopen.c
++++ b/libc/stdio/_fopen.c
+@@ -194,10 +194,23 @@ FILE *_stdio_fopen(intptr_t fname_or_mod
+ #endif
+ #ifdef __STDIO_HAS_OPENLIST
+-      __STDIO_THREADLOCK_OPENLIST;
+-      stream->__nextopen = _stdio_openlist; /* New files are inserted at */
+-      _stdio_openlist = stream;                         /*   the head of the list. */
+-      __STDIO_THREADUNLOCK_OPENLIST;
++#if defined(__UCLIBC_HAS_THREADS__) && defined(__STDIO_BUFFERS)
++      if (!(stream->__modeflags & __FLAG_FREEFILE))
++      {
++              /* An freopen call so the file was never removed from the list. */
++      }
++      else
++#endif
++      {
++              /* We have to lock the del mutex in case another thread wants to fclose()
++               * the last file. */
++              __STDIO_THREADLOCK_OPENLIST_DEL;
++              __STDIO_THREADLOCK_OPENLIST_ADD;
++              stream->__nextopen = _stdio_openlist; /* New files are inserted at */
++              _stdio_openlist = stream;                         /*   the head of the list. */
++              __STDIO_THREADUNLOCK_OPENLIST_ADD;
++              __STDIO_THREADUNLOCK_OPENLIST_DEL;
++      }
+ #endif
+       __STDIO_STREAM_VALIDATE(stream);
+diff --git a/libc/stdio/_stdio.c b/libc/stdio/_stdio.c
+index 4aae3c4..9cfe02c 100644
+--- a/libc/stdio/_stdio.c
++++ b/libc/stdio/_stdio.c
+@@ -151,8 +151,12 @@ FILE *__stdout = _stdio_streams + 1; /* 
+ FILE *_stdio_openlist = _stdio_streams;
+ # ifdef __UCLIBC_HAS_THREADS__
+-pthread_mutex_t _stdio_openlist_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+-int _stdio_openlist_delflag = 0;
++__UCLIBC_MUTEX_INIT(_stdio_openlist_add_lock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);
++#ifdef __STDIO_BUFFERS
++__UCLIBC_MUTEX_INIT(_stdio_openlist_del_lock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);
++volatile int _stdio_openlist_use_count = 0;
++int _stdio_openlist_del_count = 0;
++#endif
+ # endif
+ #endif
+@@ -162,10 +166,10 @@ int _stdio_openlist_delflag = 0;
+ /* 2 if threading not initialized and 0 otherwise; */
+ int _stdio_user_locking = 2;
+-void __stdio_init_mutex(pthread_mutex_t *m)
++void __stdio_init_mutex(__UCLIBC_MUTEX_TYPE *m)
+ {
+-      static const pthread_mutex_t __stdio_mutex_initializer
+-              = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
++      const __UCLIBC_MUTEX_STATIC(__stdio_mutex_initializer,
++                                                              PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);
+       memcpy(m, &__stdio_mutex_initializer, sizeof(__stdio_mutex_initializer));
+ }
+@@ -184,7 +188,11 @@ void _stdio_term(void)
+        * locked, then I suppose there is a chance that a pointer in the
+        * chain might be corrupt due to a partial store.
+        */ 
+-      __stdio_init_mutex(&_stdio_openlist_lock);
++      __stdio_init_mutex(&_stdio_openlist_add_lock);
++#warning check
++#ifdef __STDIO_BUFFERS
++      __stdio_init_mutex(&_stdio_openlist_del_lock);
++#endif
+       /* Next we need to worry about the streams themselves.  If a stream
+        * is currently locked, then it may be in an invalid state.  So we
+@@ -192,7 +200,7 @@ void _stdio_term(void)
+        * Then we reinitialize the locks.
+        */
+       for (ptr = _stdio_openlist ; ptr ; ptr = ptr->__nextopen ) {
+-              if (__STDIO_ALWAYS_THREADTRYLOCK(ptr)) {
++              if (__STDIO_ALWAYS_THREADTRYLOCK_CANCEL_UNSAFE(ptr)) {
+                       /* The stream is already locked, so we don't want to touch it.
+                        * However, if we have custom streams, we can't just close it
+                        * or leave it locked since a custom stream may be stacked
+@@ -258,10 +266,6 @@ void _stdio_init(void)
+ #error Assumption violated about __MASK_READING and __FLAG_UNGOT
+ #endif
+-#ifdef __UCLIBC_HAS_THREADS__
+-#include <pthread.h>
+-#endif
+-
+ #ifndef NDEBUG
+ void _stdio_validate_FILE(const FILE *stream)
+diff --git a/libc/stdio/_stdio.h b/libc/stdio/_stdio.h
+index e3c2c58..decf57d 100644
+--- a/libc/stdio/_stdio.h
++++ b/libc/stdio/_stdio.h
+@@ -22,23 +22,57 @@
+ #include <wchar.h>
+ #endif
+-#ifdef __UCLIBC_HAS_THREADS__
+-#include <pthread.h>
++#include <bits/uClibc_mutex.h>
+-#define __STDIO_THREADLOCK_OPENLIST \
+-      __pthread_mutex_lock(&_stdio_openlist_lock)
++#define __STDIO_THREADLOCK_OPENLIST_ADD                                                                               \
++        __UCLIBC_MUTEX_LOCK(_stdio_openlist_add_lock)
+-#define __STDIO_THREADUNLOCK_OPENLIST \
+-      __pthread_mutex_unlock(&_stdio_openlist_lock)
++#define __STDIO_THREADUNLOCK_OPENLIST_ADD                                                                     \
++        __UCLIBC_MUTEX_UNLOCK(_stdio_openlist_add_lock)
+-#define __STDIO_THREADTRYLOCK_OPENLIST \
+-      __pthread_mutex_trylock(&_stdio_openlist_lock)
++#ifdef __STDIO_BUFFERS
+-#else
++#define __STDIO_THREADLOCK_OPENLIST_DEL                                                                               \
++        __UCLIBC_MUTEX_LOCK(_stdio_openlist_del_lock)
++
++#define __STDIO_THREADUNLOCK_OPENLIST_DEL                                                                     \
++        __UCLIBC_MUTEX_UNLOCK(_stdio_openlist_del_lock)
+-#define       __STDIO_THREADLOCK_OPENLIST     ((void)0)
+-#define       __STDIO_THREADUNLOCK_OPENLIST   ((void)0)
++#define __STDIO_OPENLIST_INC_USE \
++do { \
++      __STDIO_THREADLOCK_OPENLIST_DEL; \
++      ++_stdio_openlist_use_count; \
++      __STDIO_THREADUNLOCK_OPENLIST_DEL; \
++} while (0)
++
++extern void _stdio_openlist_dec_use(void);
++
++#define __STDIO_OPENLIST_DEC_USE \
++      _stdio_openlist_dec_use()
++
++#define __STDIO_OPENLIST_INC_DEL_CNT \
++do { \
++      __STDIO_THREADLOCK_OPENLIST_DEL; \
++      ++_stdio_openlist_del_count; \
++      __STDIO_THREADUNLOCK_OPENLIST_DEL; \
++} while (0)
++
++#define __STDIO_OPENLIST_DEC_DEL_CNT \
++do { \
++      __STDIO_THREADLOCK_OPENLIST_DEL; \
++      --_stdio_openlist_del_count; \
++      __STDIO_THREADUNLOCK_OPENLIST_DEL; \
++} while (0)
++
++#endif /* __STDIO_BUFFERS */
++#ifndef __STDIO_THREADLOCK_OPENLIST_DEL
++#define       __STDIO_THREADLOCK_OPENLIST_DEL     ((void)0)
++#define       __STDIO_THREADUNLOCK_OPENLIST_DEL   ((void)0)
++#define __STDIO_OPENLIST_INC_USE            ((void)0)
++#define __STDIO_OPENLIST_DEC_USE            ((void)0)
++#define __STDIO_OPENLIST_INC_DEL_CNT        ((void)0)
++#define __STDIO_OPENLIST_DEC_DEL_CNT        ((void)0)
+ #endif
+ #define __UNDEFINED_OR_NONPORTABLE ((void)0)
+diff --git a/libc/stdio/fclose.c b/libc/stdio/fclose.c
+index 4df2e42..dfababc 100644
+--- a/libc/stdio/fclose.c
++++ b/libc/stdio/fclose.c
+@@ -12,30 +12,34 @@ int fclose(register FILE *stream)
+       int rv = 0;
+       __STDIO_AUTO_THREADLOCK_VAR;
+-      /* First, remove the file from the open file list. */
+-#ifdef __STDIO_HAS_OPENLIST
+-      {
+-              register FILE *ptr;
+-
+-              __STDIO_THREADLOCK_OPENLIST;
+-              if ((ptr = _stdio_openlist) == stream) {
+-                      _stdio_openlist = stream->__nextopen;
+-              } else {
+-                      while (ptr) {
+-                              if (ptr->__nextopen == stream) {
+-                                      ptr->__nextopen = stream->__nextopen;
+-                                      break;
+-                              }
+-                              ptr = ptr->__nextopen;
+-                      }
+-              }
+-              __STDIO_THREADUNLOCK_OPENLIST;
+-
+-              if (!ptr) {       /* Did not find stream in the open file list! */
+-                      return EOF;
+-              }
+-      }
+-#endif
++#warning dead code... but may want to simply check and not remove
++/* #ifdef __STDIO_HAS_OPENLIST */
++/* #if !defined(__UCLIBC_HAS_THREADS__) || !defined(__STDIO_BUFFERS) */
++/*    /\* First, remove the file from the open file list. *\/ */
++/*    { */
++/*            register FILE *ptr; */
++
++/*            __STDIO_THREADLOCK_OPENLIST; */
++/*            if ((ptr = _stdio_openlist) == stream) { */
++/* #warning does a mod!!! */
++/*                    _stdio_openlist = stream->__nextopen; */
++/*            } else { */
++/*                    while (ptr) { */
++/*                            if (ptr->__nextopen == stream) { */
++/*                                    ptr->__nextopen = stream->__nextopen; */
++/*                                    break; */
++/*                            } */
++/*                            ptr = ptr->__nextopen; */
++/*                    } */
++/*            } */
++/*            __STDIO_THREADUNLOCK_OPENLIST; */
++
++/*            if (!ptr) {       /\* Did not find stream in the open file list! *\/ */
++/*                    return EOF; */
++/*            } */
++/*    } */
++/* #endif */
++/* #endif */
+       __STDIO_AUTO_THREADLOCK(stream);
+@@ -80,7 +84,15 @@ int fclose(register FILE *stream)
+       __STDIO_AUTO_THREADUNLOCK(stream);
+       __STDIO_STREAM_FREE_BUFFER(stream);
++#warning... inefficient - locks and unlocks twice and walks whole list
++#if defined(__UCLIBC_HAS_THREADS__) && defined(__STDIO_BUFFERS)
++      /* inefficient - locks/unlocks twice and walks whole list */
++      __STDIO_OPENLIST_INC_USE;
++      __STDIO_OPENLIST_INC_DEL_CNT;
++      __STDIO_OPENLIST_DEC_USE;       /* This with free the file if necessary. */
++#else
+       __STDIO_STREAM_FREE_FILE(stream);
++#endif
+       return rv;
+ }
+diff --git a/libc/stdio/fcloseall.c b/libc/stdio/fcloseall.c
+index dbb6000..f62281a 100644
+--- a/libc/stdio/fcloseall.c
++++ b/libc/stdio/fcloseall.c
+@@ -19,14 +19,34 @@ int fcloseall (void)
+ #ifdef __STDIO_HAS_OPENLIST
+       int retval = 0;
++      FILE *f;
+-      __STDIO_THREADLOCK_OPENLIST;
+-      while (_stdio_openlist) {
+-              if (fclose(_stdio_openlist)) {
++#warning remove dead code
++/*    __STDIO_THREADLOCK_OPENLIST; */
++/*    while (_stdio_openlist) { */
++/*            if (fclose(_stdio_openlist)) { */
++/*                    retval = EOF; */
++/*            } */
++/*    } */
++/*    __STDIO_THREADUNLOCK_OPENLIST; */
++
++      __STDIO_OPENLIST_INC_USE;
++
++#warning should probably have a get_head() operation
++      __STDIO_THREADLOCK_OPENLIST_ADD;
++      f = _stdio_openlist;
++      __STDIO_THREADUNLOCK_OPENLIST_ADD;
++
++      while (f) {
++#warning should probably have a get_next() operation
++              FILE *n = f->__nextopen;
++              if (fclose(f)) {
+                       retval = EOF;
+               }
++              f = n;
+       }
+-      __STDIO_THREADUNLOCK_OPENLIST;
++
++      __STDIO_OPENLIST_DEC_USE;
+       return retval;
+diff --git a/libc/stdio/fflush.c b/libc/stdio/fflush.c
+index 6baa0ec..66b65cd 100644
+--- a/libc/stdio/fflush.c
++++ b/libc/stdio/fflush.c
+@@ -20,23 +20,50 @@ weak_alias(__fflush_unlocked,fflush_unlo
+ weak_alias(__fflush_unlocked,fflush);
+ #endif
+-#ifdef __UCLIBC_HAS_THREADS__
+ /* Even if the stream is set to user-locking, we still need to lock
+  * when all (lbf) writing streams are flushed. */
+-#define MY_STDIO_THREADLOCK(STREAM) \
+-      if (_stdio_user_locking != 2) { \
+-              __STDIO_ALWAYS_THREADLOCK(STREAM); \
+-      }
+-#define MY_STDIO_THREADUNLOCK(STREAM) \
+-      if (_stdio_user_locking != 2) { \
+-              __STDIO_ALWAYS_THREADUNLOCK(STREAM); \
+-      }
+-#else
+-#define MY_STDIO_THREADLOCK(STREAM)           ((void)0)
+-#define MY_STDIO_THREADUNLOCK(STREAM) ((void)0)
+-#endif
++#define __MY_STDIO_THREADLOCK(__stream)                                                                               \
++        __UCLIBC_MUTEX_CONDITIONAL_LOCK((__stream)->__lock,                                   \
++                                                                              (_stdio_user_locking != 2))
++
++#define __MY_STDIO_THREADUNLOCK(__stream)                                                                     \
++        __UCLIBC_MUTEX_CONDITIONAL_UNLOCK((__stream)->__lock,                         \
++                                                                                (_stdio_user_locking != 2))
++#if defined(__UCLIBC_HAS_THREADS__) && defined(__STDIO_BUFFERS)
++void _stdio_openlist_dec_use(void)
++{
++      __STDIO_THREADLOCK_OPENLIST_DEL;
++      if ((_stdio_openlist_use_count == 1) && (_stdio_openlist_del_count > 0)) {
++              FILE *p = NULL;
++              FILE *n;
++              FILE *stream;
++
++              __STDIO_THREADLOCK_OPENLIST_ADD;
++              for (stream = _stdio_openlist; stream; stream = n) {
++#warning walk the list and clear out all fclosed()d files
++                      n = stream->__nextopen;
++#warning fix for nonatomic
++                      if ((stream->__modeflags & (__FLAG_READONLY|__FLAG_WRITEONLY))
++                              == (__FLAG_READONLY|__FLAG_WRITEONLY)
++                              ) {              /* The file was closed so remove from the list. */
++                              if (!p) {
++                                      _stdio_openlist = n;
++                              } else {
++                                      p->__nextopen = n;
++                              }
++                              __STDIO_STREAM_FREE_FILE(stream);
++                      } else {
++                              p = stream;
++                      }
++              }
++              __STDIO_THREADUNLOCK_OPENLIST_DEL;
++      }
++      --_stdio_openlist_use_count;
++      __STDIO_THREADUNLOCK_OPENLIST_DEL;
++}
++#endif
+ int __fflush_unlocked(register FILE *stream)
+ {
+@@ -60,23 +87,39 @@ int __fflush_unlocked(register FILE *str
+       }
+       if (!stream) {                          /* Flush all (lbf) writing streams. */
+-              __STDIO_THREADLOCK_OPENLIST;
+-              for (stream = _stdio_openlist; stream ; stream = stream->__nextopen) {
+-                      MY_STDIO_THREADLOCK(stream);
+-                      if (!(((stream->__modeflags | bufmask)
+-                                 ^ (__FLAG_WRITING|__FLAG_LBF)
+-                                 ) & (__FLAG_WRITING|__MASK_BUFMODE))
+-                              ) {
+-                              if (!__STDIO_COMMIT_WRITE_BUFFER(stream)) {
+-                                      __STDIO_STREAM_DISABLE_PUTC(stream);
+-                                      __STDIO_STREAM_CLEAR_WRITING(stream);
+-                              } else {
+-                                      retval = EOF;
++
++              __STDIO_OPENLIST_INC_USE;
++
++              __STDIO_THREADLOCK_OPENLIST_ADD;
++              stream = _stdio_openlist;
++              __STDIO_THREADUNLOCK_OPENLIST_ADD;
++
++              while(stream) {
++                      /* We only care about currently writing streams and do not want to
++                       * block trying to obtain mutexes on non-writing streams. */
++#warning fix for nonatomic
++#warning unnecessary check if no threads
++                      if (__STDIO_STREAM_IS_WRITING(stream)) { /* ONLY IF ATOMIC!!! */
++                              __MY_STDIO_THREADLOCK(stream);
++                              /* Need to check again once we have the lock. */
++                              if (!(((stream->__modeflags | bufmask)
++                                         ^ (__FLAG_WRITING|__FLAG_LBF)
++                                         ) & (__FLAG_WRITING|__MASK_BUFMODE))
++                                      ) {
++                                      if (!__STDIO_COMMIT_WRITE_BUFFER(stream)) {
++                                              __STDIO_STREAM_DISABLE_PUTC(stream);
++                                              __STDIO_STREAM_CLEAR_WRITING(stream);
++                                      } else {
++                                              retval = EOF;
++                                      }
+                               }
++                              __MY_STDIO_THREADUNLOCK(stream);
+                       }
+-                      MY_STDIO_THREADUNLOCK(stream);
++                      stream = stream->__nextopen;
+               }
+-              __STDIO_THREADUNLOCK_OPENLIST;
++
++              __STDIO_OPENLIST_DEC_USE;
++
+       } else if (__STDIO_STREAM_IS_WRITING(stream)) {
+               if (!__STDIO_COMMIT_WRITE_BUFFER(stream)) {
+                       __STDIO_STREAM_DISABLE_PUTC(stream);
+diff --git a/libc/stdio/flockfile.c b/libc/stdio/flockfile.c
+index 0dcc7c2..3fad711 100644
+--- a/libc/stdio/flockfile.c
++++ b/libc/stdio/flockfile.c
+@@ -11,6 +11,6 @@ void flockfile(FILE *stream)
+ {
+       __STDIO_STREAM_VALIDATE(stream);
+-      __STDIO_ALWAYS_THREADLOCK(stream);
++      __STDIO_ALWAYS_THREADLOCK_CANCEL_UNSAFE(stream);
+ }
+diff --git a/libc/stdio/freopen.c b/libc/stdio/freopen.c
+index 0eccaac..36b8488 100644
+--- a/libc/stdio/freopen.c
++++ b/libc/stdio/freopen.c
+@@ -42,6 +42,8 @@ FILE *freopen(const char * __restrict fi
+       __STDIO_STREAM_VALIDATE(stream);
++      __STDIO_OPENLIST_INC_USE;       /* Do not remove the file from the list. */
++
+       /* First, flush and close, but don't deallocate, the stream. */
+       /* This also removes the stream for the open file list. */
+       dynmode = (stream->__modeflags & (__FLAG_FREEBUF|__FLAG_FREEFILE));
+@@ -57,9 +59,16 @@ FILE *freopen(const char * __restrict fi
+       fp = _stdio_fopen(((intptr_t) filename), mode, stream, FILEDES_ARG);
++#warning if fp is NULL, then we do not free file (but beware stdin,stdout,stderr)
++      if (fp) {
++              __STDIO_OPENLIST_DEC_DEL_CNT;
++      }
++
+       /* Reset the allocation flags. */
+       stream->__modeflags |= dynmode;
++      __STDIO_OPENLIST_DEC_USE;
++
+       __STDIO_AUTO_THREADUNLOCK(stream);
+       return fp;
+diff --git a/libc/stdio/ftello.c b/libc/stdio/ftello.c
+index 7092f34..69385ce 100644
+--- a/libc/stdio/ftello.c
++++ b/libc/stdio/ftello.c
+@@ -48,7 +48,10 @@ OFFSET_TYPE FTELL(register FILE *stream)
+       __STDIO_STREAM_VALIDATE(stream);
+-      if ((__SEEK(stream, &pos, SEEK_CUR) < 0)
++      if ((__SEEK(stream, &pos,
++                              ((__STDIO_STREAM_IS_WRITING(stream)
++                                && (stream->__modeflags & __FLAG_APPEND))
++                               ? SEEK_END : SEEK_CUR)) < 0)
+               || (__stdio_adjust_position(stream, &pos) < 0)) {
+               pos = -1;
+       }
+diff --git a/libc/stdio/ftrylockfile.c b/libc/stdio/ftrylockfile.c
+index d85b8ff..0d2e156 100644
+--- a/libc/stdio/ftrylockfile.c
++++ b/libc/stdio/ftrylockfile.c
+@@ -15,5 +15,5 @@ int ftrylockfile(FILE *stream)
+ {
+       __STDIO_STREAM_VALIDATE(stream);
+-      return __STDIO_ALWAYS_THREADTRYLOCK(stream);
++      return __STDIO_ALWAYS_THREADTRYLOCK_CANCEL_UNSAFE(stream);
+ }
+diff --git a/libc/stdio/funlockfile.c b/libc/stdio/funlockfile.c
+index 048c093..2ddf097 100644
+--- a/libc/stdio/funlockfile.c
++++ b/libc/stdio/funlockfile.c
+@@ -11,5 +11,5 @@ void funlockfile(FILE *stream)
+ {
+       __STDIO_STREAM_VALIDATE(stream);
+-      __STDIO_ALWAYS_THREADUNLOCK(stream);
++      __STDIO_ALWAYS_THREADUNLOCK_CANCEL_UNSAFE(stream);
+ }
+diff --git a/libc/stdio/popen.c b/libc/stdio/popen.c
+index c7887ad..ab8d296 100644
+--- a/libc/stdio/popen.c
++++ b/libc/stdio/popen.c
+@@ -14,6 +14,7 @@
+  *   Fix failure exit code for failed execve().
+  */
++#warning hmm... susv3 says "Pipe streams are byte-oriented."
+ #include <stdio.h>
+ #include <stdlib.h>
+@@ -21,6 +22,8 @@
+ #include <unistd.h>
+ #include <sys/wait.h>
++#include <bits/uClibc_mutex.h>
++
+ /* uClinux-2.0 has vfork, but Linux 2.0 doesn't */
+ #include <sys/syscall.h>
+ #if ! defined __NR_vfork
+@@ -29,19 +32,11 @@
+ # define VFORK_UNLOCK ((void) 0)
+ #endif
+-#ifdef __UCLIBC_HAS_THREADS__
+-#include <pthread.h>
+-static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;
+-# define LOCK                 __pthread_mutex_lock(&mylock)
+-# define UNLOCK                       __pthread_mutex_unlock(&mylock);
+-#else
+-# define LOCK                 ((void) 0)
+-# define UNLOCK                       ((void) 0)
+-#endif      
++__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER);
+ #ifndef VFORK_LOCK
+-# define VFORK_LOCK           LOCK
+-# define VFORK_UNLOCK UNLOCK
++# define VFORK_LOCK           __UCLIBC_MUTEX_LOCK(mylock)
++# define VFORK_UNLOCK __UCLIBC_MUTEX_UNLOCK(mylock)
+ #endif
+ struct popen_list_item {
+@@ -118,10 +113,10 @@ FILE *popen(const char *command, const c
+       if (pid > 0) {                          /* Parent of vfork... */
+               pi->pid = pid;
+               pi->f = fp;
+-              LOCK;
++              __UCLIBC_MUTEX_LOCK(mylock);
+               pi->next = popen_list;
+               popen_list = pi;
+-              UNLOCK;
++              __UCLIBC_MUTEX_UNLOCK(mylock);
+               
+               return fp;
+       }
+@@ -136,6 +131,8 @@ FILE *popen(const char *command, const c
+       return NULL;
+ }
++#warning is pclose correct wrt the new mutex semantics?
++
+ int pclose(FILE *stream)
+ {
+       struct popen_list_item *p;
+@@ -144,7 +141,7 @@ int pclose(FILE *stream)
+       /* First, find the list entry corresponding to stream and remove it
+        * from the list.  Set p to the list item (NULL if not found). */
+-      LOCK;
++      __UCLIBC_MUTEX_LOCK(mylock);
+       if ((p = popen_list) != NULL) {
+               if (p->f == stream) {
+                       popen_list = p->next;
+@@ -163,7 +160,7 @@ int pclose(FILE *stream)
+                       } while (1);
+               }
+       }
+-      UNLOCK;
++      __UCLIBC_MUTEX_UNLOCK(mylock);
+       if (p) {
+               pid = p->pid;                   /* Save the pid we need */
+diff --git a/libc/stdio/setvbuf.c b/libc/stdio/setvbuf.c
+index 3fe62c6..6d53ab1 100644
+--- a/libc/stdio/setvbuf.c
++++ b/libc/stdio/setvbuf.c
+@@ -75,8 +75,8 @@ int setvbuf(register FILE * __restrict s
+       }
+       stream->__modeflags |= alloc_flag;
+-      stream->__bufstart = buf;
+-      stream->__bufend = buf + size;
++      stream->__bufstart = (unsigned char *) buf;
++      stream->__bufend = (unsigned char *) buf + size;
+       __STDIO_STREAM_INIT_BUFREAD_BUFPOS(stream);
+       __STDIO_STREAM_DISABLE_GETC(stream);
+       __STDIO_STREAM_DISABLE_PUTC(stream);
+diff --git a/libc/stdio/vasprintf.c b/libc/stdio/vasprintf.c
+index 688ab7c..6d7664d 100644
+--- a/libc/stdio/vasprintf.c
++++ b/libc/stdio/vasprintf.c
+@@ -63,6 +63,8 @@ int vasprintf(char **__restrict buf, con
+                               free(*buf);
+                               *buf = NULL;
+                       }
++              } else {
++                      rv = -1;
+               }
+       }
+diff --git a/libc/stdio/vdprintf.c b/libc/stdio/vdprintf.c
+index de8362c..7cb707f 100644
+--- a/libc/stdio/vdprintf.c
++++ b/libc/stdio/vdprintf.c
+@@ -15,8 +15,8 @@ int vdprintf(int filedes, const char * _
+ #ifdef __STDIO_BUFFERS
+       char buf[64];                           /* TODO: provide _optional_ buffering? */
+-      f.__bufend = buf + sizeof(buf);
+-      f.__bufstart = buf;
++      f.__bufend = (unsigned char *) buf + sizeof(buf);
++      f.__bufstart = (unsigned char *) buf;
+       __STDIO_STREAM_DISABLE_GETC(&f);
+       __STDIO_STREAM_DISABLE_PUTC(&f);
+       __STDIO_STREAM_INIT_BUFREAD_BUFPOS(&f);
+diff --git a/libc/stdio/vfprintf.c b/libc/stdio/vfprintf.c
+index 10114f0..9214e3b 100644
+--- a/libc/stdio/vfprintf.c
++++ b/libc/stdio/vfprintf.c
+@@ -569,7 +569,7 @@ int _ppfs_init(register ppfs_t *ppfs, co
+               ppfs->fmtpos = fmt0;            /* rewind */
+       }
+-#ifdef NL_MAX_ARG
++#ifdef NL_ARGMAX
+       /* If we have positional args, make sure we know all the types. */
+       {
+               register int *p = ppfs->argtype;
+@@ -581,7 +581,7 @@ int _ppfs_init(register ppfs_t *ppfs, co
+                       ++p;
+               }
+       }
+-#endif /* NL_MAX_ARG */
++#endif /* NL_ARGMAX */
+       return 0;
+ }
+@@ -1214,7 +1214,7 @@ static size_t _fp_out_narrow(FILE *fp, i
+               }
+               len = buflen;
+       }
+-      return r + OUTNSTR(fp, (const char *) buf, len);
++      return r + OUTNSTR(fp, (const unsigned char *) buf, len);
+ }
+ #endif /* __STDIO_PRINTF_FLOAT */
+diff --git a/libc/stdlib/abort.c b/libc/stdlib/abort.c
+index 77c2cdc..9f69918 100644
+--- a/libc/stdlib/abort.c
++++ b/libc/stdlib/abort.c
+@@ -70,16 +70,9 @@ extern void _exit __P((int __status)) __
+ static int been_there_done_that = 0;
+ /* Be prepared in case multiple threads try to abort() */
+-#ifdef __UCLIBC_HAS_THREADS__
+-# include <pthread.h>
+-static pthread_mutex_t mylock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+-# define LOCK __pthread_mutex_lock(&mylock)
+-# define UNLOCK       __pthread_mutex_unlock(&mylock)
+-#else
+-# define LOCK
+-# define UNLOCK
+-#endif
++#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)
+@@ -87,7 +80,7 @@ void abort(void)
+       sigset_t sigset;
+       /* Make sure we acquire the lock before proceeding */
+-      LOCK;
++      __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE(mylock);
+       /* Unmask SIGABRT to be sure we can get it */
+       if (__sigemptyset(&sigset) == 0 && __sigaddset(&sigset, SIGABRT) == 0) {
+@@ -110,9 +103,9 @@ void abort(void)
+ #endif
+ abort_it:
+-                      UNLOCK;
++                      __UCLIBC_MUTEX_UNLOCK_CANCEL_UNSAFE(mylock);
+                       raise(SIGABRT);
+-                      LOCK;
++                      __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE(mylock);
+               }
+               /* Still here?  Try to remove any signal handlers */
+diff --git a/libc/stdlib/atexit.c b/libc/stdlib/atexit.c
+index 280f42c..b028068 100644
+--- a/libc/stdlib/atexit.c
++++ b/libc/stdlib/atexit.c
+@@ -40,17 +40,9 @@
+ #include <stdlib.h>
+ #include <errno.h>
++#include <bits/uClibc_mutex.h>
+-#ifdef __UCLIBC_HAS_THREADS__
+-#include <pthread.h>
+-extern pthread_mutex_t mylock;
+-# define LOCK __pthread_mutex_lock(&mylock)
+-# define UNLOCK       __pthread_mutex_unlock(&mylock);
+-#else
+-# define LOCK
+-# define UNLOCK
+-#endif
+-
++__UCLIBC_MUTEX_EXTERN(__atexit_lock);
+ typedef void (*aefuncp) (void);         /* atexit function pointer */
+ typedef void (*oefuncp) (int, void *);  /* on_exit function pointer */
+@@ -90,8 +82,9 @@ extern struct exit_function __exit_funct
+ int atexit(aefuncp func)
+ {
+     struct exit_function *efp;
++    int rv = -1;
+-    LOCK;
++    __UCLIBC_MUTEX_LOCK(__atexit_lock);
+     if (func) {
+ #ifdef __UCLIBC_DYNAMIC_ATEXIT__
+       /* If we are out of function table slots, make some more */
+@@ -99,18 +92,16 @@ int atexit(aefuncp func)
+           efp=realloc(__exit_function_table, 
+                                       (__exit_slots+20)*sizeof(struct exit_function));
+           if (efp==NULL) {
+-              UNLOCK;
+               __set_errno(ENOMEM);
+-              return -1;
++              goto DONE;
+           }
+               __exit_function_table = efp;
+           __exit_slots+=20;
+       }
+ #else
+       if (__exit_count >= __UCLIBC_MAX_ATEXIT) {
+-          UNLOCK;
+           __set_errno(ENOMEM);
+-          return -1;
++          goto DONE;
+       }
+ #endif
+       __exit_cleanup = __exit_handler; /* enable cleanup */
+@@ -118,8 +109,12 @@ int atexit(aefuncp func)
+       efp->type = ef_atexit;
+       efp->funcs.atexit = func;
+     }
+-    UNLOCK;
+-    return 0;
++
++    rv = 0;
++
++ DONE:
++    __UCLIBC_MUTEX_UNLOCK(__atexit_lock);
++    return rv;
+ }
+ #endif
+@@ -133,8 +128,9 @@ int atexit(aefuncp func)
+ int on_exit(oefuncp func, void *arg)
+ {
+     struct exit_function *efp;
++    int rv = -1;
+-    LOCK;
++    __UCLIBC_MUTEX_LOCK(__atexit_lock);
+     if (func) {
+ #ifdef __UCLIBC_DYNAMIC_ATEXIT__
+       /* If we are out of function table slots, make some more */
+@@ -142,18 +138,16 @@ int on_exit(oefuncp func, void *arg)
+           efp=realloc(__exit_function_table, 
+                                       (__exit_slots+20)*sizeof(struct exit_function));
+           if (efp==NULL) {
+-              UNLOCK;
+               __set_errno(ENOMEM);
+-              return -1;
++              goto DONE;
+           }
+               __exit_function_table=efp;
+           __exit_slots+=20;
+       }
+ #else
+       if (__exit_count >= __UCLIBC_MAX_ATEXIT) {
+-          UNLOCK;
+           __set_errno(ENOMEM);
+-          return -1;
++          goto DONE;
+       }
+ #endif
+@@ -163,8 +157,12 @@ int on_exit(oefuncp func, void *arg)
+       efp->funcs.on_exit.func = func;
+       efp->funcs.on_exit.arg = arg;
+     }
+-    UNLOCK;
+-    return 0;
++
++    rv = 0;
++
++ DONE:
++    __UCLIBC_MUTEX_UNLOCK(__atexit_lock);
++    return rv;
+ }
+ #endif
+@@ -214,9 +212,8 @@ void __exit_handler(int status)
+ #ifdef L_exit
+ extern void weak_function _stdio_term(void);
+ void (*__exit_cleanup) (int) = 0;
+-#ifdef __UCLIBC_HAS_THREADS__
+-pthread_mutex_t mylock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+-#endif
++
++__UCLIBC_MUTEX_INIT(__atexit_lock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);
+ #ifdef __UCLIBC_CTOR_DTOR__
+ extern void (*__app_fini)(void);
+@@ -229,11 +226,11 @@ extern void (*__rtld_fini)(void);
+ void exit(int rv)
+ {
+       /* Perform exit-specific cleanup (atexit and on_exit) */
+-      LOCK;
++      __UCLIBC_MUTEX_LOCK(__atexit_lock);
+       if (__exit_cleanup) {
+               __exit_cleanup(rv);
+       }
+-      UNLOCK;
++      __UCLIBC_MUTEX_UNLOCK(__atexit_lock);
+ #ifdef __UCLIBC_CTOR_DTOR__
+       if (__app_fini != NULL)
+diff --git a/libc/stdlib/malloc-simple/alloc.c b/libc/stdlib/malloc-simple/alloc.c
+index ed14c37..519a875 100644
+--- a/libc/stdlib/malloc-simple/alloc.c
++++ b/libc/stdlib/malloc-simple/alloc.c
+@@ -108,15 +108,14 @@ void free(void *ptr)
+ #endif
+ #ifdef L_memalign
+-#ifdef __UCLIBC_HAS_THREADS__
+-#include <pthread.h>
+-pthread_mutex_t __malloc_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+-# define LOCK __pthread_mutex_lock(&__malloc_lock)
+-# define UNLOCK       __pthread_mutex_unlock(&__malloc_lock);
+-#else
+-# define LOCK
+-# define UNLOCK
+-#endif
++
++#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)
++
+ /* List of blocks allocated with memalign or valloc */
+ struct alignlist
+@@ -135,7 +134,7 @@ int __libc_free_aligned(void *ptr)
+       if (ptr == NULL)
+               return 0;
+-      LOCK;
++      __MALLOC_LOCK;
+       for (l = _aligned_blocks; l != NULL; l = l->next) {
+               if (l->aligned == ptr) {
+                       /* Mark the block as free */
+@@ -146,7 +145,7 @@ int __libc_free_aligned(void *ptr)
+                       return 1;
+               }
+       }
+-      UNLOCK;
++      __MALLOC_UNLOCK;
+       return 0;
+ }
+ void * memalign (size_t alignment, size_t size)
+@@ -159,10 +158,10 @@ void * memalign (size_t alignment, size_
+               return NULL;
+       adj = (unsigned long int) ((unsigned long int) ((char *) result -
+-            (char *) NULL)) % alignment;
++                                                                                                      (char *) NULL)) % alignment;
+       if (adj != 0) {
+               struct alignlist *l;
+-              LOCK;
++              __MALLOC_LOCK;
+               for (l = _aligned_blocks; l != NULL; l = l->next)
+                       if (l->aligned == NULL)
+                               /* This slot is free.  Use it.  */
+@@ -171,15 +170,16 @@ void * memalign (size_t alignment, size_
+                       l = (struct alignlist *) malloc (sizeof (struct alignlist));
+                       if (l == NULL) {
+                               free(result);
+-                              UNLOCK;
+-                              return NULL;
++                              result = NULL;
++                              goto DONE;
+                       }
+                       l->next = _aligned_blocks;
+                       _aligned_blocks = l;
+               }
+               l->exact = result;
+               result = l->aligned = (char *) result + alignment - adj;
+-              UNLOCK;
++      DONE:
++              __MALLOC_UNLOCK;
+       }
+       return result;
+diff --git a/libc/stdlib/malloc-standard/calloc.c b/libc/stdlib/malloc-standard/calloc.c
+index a67dad7..4277954 100644
+--- a/libc/stdlib/malloc-standard/calloc.c
++++ b/libc/stdlib/malloc-standard/calloc.c
+@@ -8,7 +8,7 @@
+   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
++  ftp://gee.cs.oswego.edu/pub/misc/malloc.c
+   Check before installing!
+   Hacked up for uClibc by Erik Andersen <andersen@codepoet.org>
+@@ -31,63 +31,63 @@ void* calloc(size_t n_elements, size_t e
+      * 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;
++              __set_errno(ENOMEM);
++              return NULL;
+     }
+-    LOCK;
++    __MALLOC_LOCK;
+     mem = malloc(size);
+     if (mem != 0) {
+-      p = mem2chunk(mem);
++              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 (!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);
+-      }
++              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
+     }
+-    UNLOCK;
++    __MALLOC_UNLOCK;
+     return mem;
+ }
+diff --git a/libc/stdlib/malloc-standard/free.c b/libc/stdlib/malloc-standard/free.c
+index 94e1d65..4e08ef7 100644
+--- a/libc/stdlib/malloc-standard/free.c
++++ b/libc/stdlib/malloc-standard/free.c
+@@ -8,7 +8,7 @@
+   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
++  ftp://gee.cs.oswego.edu/pub/misc/malloc.c
+   Check before installing!
+   Hacked up for uClibc by Erik Andersen <andersen@codepoet.org>
+@@ -42,71 +42,71 @@ static int __malloc_trim(size_t pad, mst
+     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;
++              /*
++                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);
++   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.
++   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);
++      mstate av = get_malloc_state();
++      __malloc_consolidate(av);
++      return __malloc_trim(pad, av);
+ }
+ /*
+@@ -125,8 +125,8 @@ static void malloc_init_state(mstate av)
+     /* Establish circular links for normal bins */
+     for (i = 1; i < NBINS; ++i) {
+-      bin = bin_at(av,i);
+-      bin->fd = bin->bk = bin;
++              bin = bin_at(av,i);
++              bin->fd = bin->bk = bin;
+     }
+     av->top_pad        = DEFAULT_TOP_PAD;
+@@ -157,15 +157,15 @@ static void malloc_init_state(mstate av)
+ /* ------------------------- __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.
++__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 __malloc_consolidate(mstate av)
+ {
+@@ -186,78 +186,78 @@ void __malloc_consolidate(mstate av)
+     mchunkptr       fwd;
+     /*
+-       If max_fast is 0, we know that av hasn't
+-       yet been initialized, in which case do so below
+-       */
++        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);
++              clear_fastchunks(av);
+-      unsorted_bin = unsorted_chunks(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;
++              /*
++                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 {
+-                  check_inuse_chunk(p);
+-                  nextp = p->fd;
++                      if ( (p = *fb) != 0) {
++                              *fb = 0;
+-                  /* Slightly streamlined version of consolidation code in free() */
+-                  size = p->size & ~PREV_INUSE;
+-                  nextchunk = chunk_at_offset(p, size);
+-                  nextsize = chunksize(nextchunk);
++                              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;
++                                      }
+-                  if (!prev_inuse(p)) {
+-                      prevsize = p->prev_size;
+-                      size += prevsize;
+-                      p = chunk_at_offset(p, -((long) prevsize));
+-                      unlink(p, bck, fwd);
+-                  }
++                              } while ( (p = nextp) != 0);
+-                  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);
++              } while (fb++ != maxfb);
+     }
+     else {
+-      malloc_init_state(av);
+-      check_malloc_state();
++              malloc_init_state(av);
++              check_malloc_state();
+     }
+ }
+@@ -279,9 +279,9 @@ void free(void* mem)
+     /* free(0) has no effect */
+     if (mem == NULL)
+-      return;
++              return;
+-    LOCK;
++    __MALLOC_LOCK;
+     av = get_malloc_state();
+     p = mem2chunk(mem);
+     size = chunksize(p);
+@@ -289,9 +289,9 @@ void free(void* mem)
+     check_inuse_chunk(p);
+     /*
+-       If eligible, place chunk on a fastbin so it can be found
+-       and used quickly in malloc.
+-       */
++        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)
+@@ -300,114 +300,114 @@ void free(void* mem)
+              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;
++              set_fastchunks(av);
++              fb = &(av->fastbins[fastbin_index(size)]);
++              p->fd = *fb;
++              *fb = p;
+     }
+     /*
+-       Consolidate other non-mmapped chunks as they arrive.
+-       */
++        Consolidate other non-mmapped chunks as they arrive.
++      */
+     else if (!chunk_is_mmapped(p)) {
+-      set_anychunks(av);
++              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;
+-      nextchunk = chunk_at_offset(p, size);
+-      nextsize = chunksize(nextchunk);
++                      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
++              */
+-      /* 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);
+-      }
++              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.
+-       */
++        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 {
+-      int ret;
+-      size_t offset = p->prev_size;
+-      av->n_mmaps--;
+-      av->mmapped_mem -= (size + offset);
+-      ret = munmap((char*)p - offset, size + offset);
+-      /* munmap returns non-zero on failure */
+-      assert(ret == 0);
++              int ret;
++              size_t offset = p->prev_size;
++              av->n_mmaps--;
++              av->mmapped_mem -= (size + offset);
++              ret = munmap((char*)p - offset, size + offset);
++              /* munmap returns non-zero on failure */
++              assert(ret == 0);
+     }
+-    UNLOCK;
++    __MALLOC_UNLOCK;
+ }
+diff --git a/libc/stdlib/malloc-standard/mallinfo.c b/libc/stdlib/malloc-standard/mallinfo.c
+index 51ac423..1e0875c 100644
+--- a/libc/stdlib/malloc-standard/mallinfo.c
++++ b/libc/stdlib/malloc-standard/mallinfo.c
+@@ -8,7 +8,7 @@
+   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
++  ftp://gee.cs.oswego.edu/pub/misc/malloc.c
+   Check before installing!
+   Hacked up for uClibc by Erik Andersen <andersen@codepoet.org>
+@@ -30,11 +30,11 @@ struct mallinfo mallinfo(void)
+     int nblocks;
+     int nfastblocks;
+-    LOCK;
++    __MALLOC_LOCK;
+     av = get_malloc_state();
+     /* Ensure initialization */
+     if (av->top == 0)  {
+-      __malloc_consolidate(av);
++              __malloc_consolidate(av);
+     }
+     check_malloc_state();
+@@ -48,21 +48,21 @@ struct mallinfo mallinfo(void)
+     fastavail = 0;
+     for (i = 0; i < NFASTBINS; ++i) {
+-      for (p = av->fastbins[i]; p != 0; p = p->fd) {
+-          ++nfastblocks;
+-          fastavail += chunksize(p);
+-      }
++              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);
+-      }
++              b = bin_at(av, i);
++              for (p = last(b); p != b; p = p->bk) {
++                      ++nblocks;
++                      avail += chunksize(p);
++              }
+     }
+     mi.smblks = nfastblocks;
+@@ -75,7 +75,7 @@ struct mallinfo mallinfo(void)
+     mi.fsmblks = fastavail;
+     mi.keepcost = chunksize(av->top);
+     mi.usmblks = av->max_total_mem;
+-    UNLOCK;
++    __MALLOC_UNLOCK;
+     return mi;
+ }
+@@ -84,23 +84,40 @@ void malloc_stats(FILE *file)
+     struct mallinfo mi;
+     if (file==NULL) {
+-      file = stderr;
++              file = stderr;
+     }
+     mi = mallinfo();
+-    fprintf(file, "total bytes allocated             = %10u\n", (unsigned int)(mi.arena + mi.hblkhd));
+-    fprintf(file, "total bytes in use bytes          = %10u\n", (unsigned int)(mi.uordblks + mi.hblkhd));
+-    fprintf(file, "total non-mmapped bytes allocated = %10d\n", mi.arena);
+-    fprintf(file, "number of mmapped regions         = %10d\n", mi.hblks);
+-    fprintf(file, "total allocated mmap space        = %10d\n", mi.hblkhd);
+-    fprintf(file, "total allocated sbrk space        = %10d\n", mi.uordblks);
++    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
+-    fprintf(file, "number of free chunks             = %10d\n", mi.ordblks);
+-    fprintf(file, "number of fastbin blocks          = %10d\n", mi.smblks);
+-    fprintf(file, "space in freed fastbin blocks     = %10d\n", mi.fsmblks);
++                      "number of free chunks             = %10d\n"
++                      "number of fastbin blocks          = %10d\n"
++                      "space in freed fastbin blocks     = %10d\n"
+ #endif
+-    fprintf(file, "maximum total allocated space     = %10d\n", mi.usmblks);
+-    fprintf(file, "total free space                  = %10d\n", mi.fordblks);
+-    fprintf(file, "memory releasable via malloc_trim = %10d\n", mi.keepcost);
++                      "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/libc/stdlib/malloc-standard/malloc.c b/libc/stdlib/malloc-standard/malloc.c
+index 7025e83..60494a0 100644
+--- a/libc/stdlib/malloc-standard/malloc.c
++++ b/libc/stdlib/malloc-standard/malloc.c
+@@ -8,7 +8,7 @@
+   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
++  ftp://gee.cs.oswego.edu/pub/misc/malloc.c
+   Check before installing!
+   Hacked up for uClibc by Erik Andersen <andersen@codepoet.org>
+@@ -17,17 +17,14 @@
+ #define _GNU_SOURCE
+ #include "malloc.h"
+-
+-#ifdef __UCLIBC_HAS_THREADS__
+-pthread_mutex_t __malloc_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+-#endif
++__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).
++  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 */
+@@ -77,30 +74,30 @@ void __do_check_chunk(mchunkptr p)
+     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));
+-      }
++              /* 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)));
++              /* 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)));
+     }
+ }
+@@ -121,21 +118,21 @@ void __do_check_free_chunk(mchunkptr 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);
+-    }
++              {
++                      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)));
++              assert(sz == (sizeof(size_t)));
+ }
+ /* Properties of inuse chunks */
+@@ -146,7 +143,7 @@ void __do_check_inuse_chunk(mchunkptr p)
+     __do_check_chunk(p);
+     if (chunk_is_mmapped(p))
+-      return; /* mmapped chunks have no next/prev */
++              return; /* mmapped chunks have no next/prev */
+     /* Check whether it claims to be in use ... */
+     assert(inuse(p));
+@@ -156,20 +153,20 @@ void __do_check_inuse_chunk(mchunkptr 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);
++              /* 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);
++              assert(prev_inuse(next));
++              assert(chunksize(next) >= MINSIZE);
+     }
+     else if (!inuse(next))
+-      __do_check_free_chunk(next);
++              __do_check_free_chunk(next);
+ }
+ /* Properties of chunks recycled from fastbins */
+@@ -198,14 +195,14 @@ void __do_check_malloced_chunk(mchunkptr
+     __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.
+-       */
++        ... 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));
+ }
+@@ -243,7 +240,7 @@ void __do_check_malloc_state(void)
+     /* cannot run remaining checks until fully initialized */
+     if (av->top == 0 || av->top == initial_top(av))
+-      return;
++              return;
+     /* pagesize is a power of 2 */
+     assert((av->pagesize & (av->pagesize-1)) == 0);
+@@ -256,64 +253,64 @@ void __do_check_malloc_state(void)
+     max_fast_bin = fastbin_index(av->max_fast);
+     for (i = 0; i < NFASTBINS; ++i) {
+-      p = av->fastbins[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;
+-      }
++              /* 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));
++              assert(have_fastchunks(av));
+     else if (!have_fastchunks(av))
+-      assert(total == 0);
++              assert(total == 0);
+     /* check normal bins */
+     for (i = 1; i < NBINS; ++i) {
+-      b = bin_at(av,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);
+-      }
++              /* 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 */
+@@ -326,13 +323,13 @@ void __do_check_malloc_state(void)
+     assert(av->n_mmaps <= av->max_n_mmaps);
+     assert((unsigned long)(av->sbrked_mem) <=
+-          (unsigned long)(av->max_sbrked_mem));
++                 (unsigned long)(av->max_sbrked_mem));
+     assert((unsigned long)(av->mmapped_mem) <=
+-          (unsigned long)(av->max_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));
++                 (unsigned long)(av->mmapped_mem) + (unsigned long)(av->sbrked_mem));
+ }
+ #endif
+@@ -370,84 +367,84 @@ static void* __malloc_alloc(size_t nb, m
+     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 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);
++              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 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)) {
++              char* mm;             /* return value from mmap call*/
+               /*
+-                 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);
+-              }
++                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;
+-              /* update statistics */
++                              check_chunk(p);
+-              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);
+-          }
+-      }
++                              return chunk2mem(p);
++                      }
++              }
+     }
+     /* Record incoming configuration of top */
+@@ -462,8 +459,8 @@ static void* __malloc_alloc(size_t nb, m
+      * 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)));
++                 ((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));
+@@ -477,272 +474,272 @@ static void* __malloc_alloc(size_t nb, m
+     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, 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;
++              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.
+-       */
++        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.
+-       */
++        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)
+-      brk = (char*)(MORECORE(size));
++              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 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 (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)) {
+-
+-          brk = (char*)(MMAP(0, size, PROT_READ|PROT_WRITE));
+-
+-          if (brk != (char*)(MORECORE_FAILURE)) {
+-
+-              /* We do not need, and cannot use, another sbrk call to find end */
+-              snd_brk = 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);
+-          }
+-      }
++              /* 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)) {
++
++                      brk = (char*)(MMAP(0, size, PROT_READ|PROT_WRITE));
++
++                      if (brk != (char*)(MORECORE_FAILURE)) {
++
++                              /* We do not need, and cannot use, another sbrk call to find end */
++                              snd_brk = 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 (brk != (char*)(MORECORE_FAILURE)) {
+-      av->sbrked_mem += size;
++              av->sbrked_mem += size;
+-      /*
+-         If MORECORE extends previous space, we can likewise extend top size.
+-         */
+-
+-      if (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 = 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 && 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 += brk - old_end;
+-
+-              /* Guarantee alignment of first new chunk made from this space */
+-
+-              front_misalign = (size_t)chunk2mem(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.
+-                     */
++              /*
++                If MORECORE extends previous space, we can likewise extend top size.
++              */
+-                  correction = MALLOC_ALIGNMENT - front_misalign;
+-                  aligned_brk += correction;
++              if (brk == old_end && snd_brk == (char*)(MORECORE_FAILURE)) {
++                      set_head(old_top, (size + old_size) | PREV_INUSE);
+               }
+               /*
+-                 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)(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 < 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 = brk + size;
+-                  correction = 0;
+-                  set_noncontiguous(av);
+-              }
+-
+-          }
+-
+-          /* handle non-contiguous cases */
+-          else {
+-              /* MORECORE/mmap must correctly align */
+-              assert(aligned_OK(chunk2mem(brk)));
+-
+-              /* Find out current end of memory */
+-              if (snd_brk == (char*)(MORECORE_FAILURE)) {
+-                  snd_brk = (char*)(MORECORE(0));
+-                  av->sbrked_mem += snd_brk - 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;
++                Otherwise, make adjustments:
+-              /*
+-                 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);
+-      }
++                * 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 = 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 && 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 += brk - old_end;
++
++                              /* Guarantee alignment of first new chunk made from this space */
++
++                              front_misalign = (size_t)chunk2mem(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)(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 < 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 = brk + size;
++                                      correction = 0;
++                                      set_noncontiguous(av);
++                              }
++
++                      }
++
++                      /* handle non-contiguous cases */
++                      else {
++                              /* MORECORE/mmap must correctly align */
++                              assert(aligned_OK(chunk2mem(brk)));
++
++                              /* Find out current end of memory */
++                              if (snd_brk == (char*)(MORECORE_FAILURE)) {
++                                      snd_brk = (char*)(MORECORE(0));
++                                      av->sbrked_mem += snd_brk - 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);
++              }
+     }
+@@ -767,25 +764,25 @@ static int __malloc_largebin_index(unsig
+ #if defined(__GNUC__) && defined(i386)
+     __asm__("bsrl %1,%0\n\t"
+-          : "=r" (m)
+-          : "g"  (x));
++                      : "=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));
++              /*
++                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
+@@ -826,69 +823,70 @@ void* malloc(size_t bytes)
+     mchunkptr       fwd;              /* misc temp for linking */
+     mchunkptr       bck;              /* misc temp for linking */
+     void *          sysmem;
++      void *          retval;
+ #if !defined(__MALLOC_GLIBC_COMPAT__)
+     if (!bytes) return NULL;
+ #endif
+-    LOCK;
++    __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.
+-       */
++        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
+-       */
++        Bypass search if no frees yet
++      */
+     if (!have_anychunks(av)) {
+-      if (av->max_fast == 0) /* initialization check */
+-          __malloc_consolidate(av);
+-      goto use_top;
++              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 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);
+-          UNLOCK;
+-          return chunk2mem(victim);
+-      }
++              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 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);
++              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);
+-          UNLOCK;
+-          return chunk2mem(victim);
+-      }
++              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.
+@@ -899,154 +897,154 @@ void* malloc(size_t bytes)
+        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);
++              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.
+-       */
++        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);
++              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 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);
+-          UNLOCK;
+-          return chunk2mem(victim);
+-      }
+-
+-      /* 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);
+-          UNLOCK;
+-          return chunk2mem(victim);
+-      }
+-
+-      /* 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 (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 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);
++              bin = bin_at(av, idx);
+-          if ((unsigned long)(size) >= (unsigned long)(nb)) {
+-              remainder_size = size - nb;
+-              unlink(victim, bck, fwd);
++              for (victim = last(bin); victim != bin; victim = victim->bk) {
++                      size = chunksize(victim);
+-              /* Exhaust */
+-              if (remainder_size < MINSIZE)  {
+-                  set_inuse_bit_at_offset(victim, size);
+-                  check_malloced_chunk(victim, nb);
+-                  UNLOCK;
+-                  return chunk2mem(victim);
+-              }
+-              /* 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);
+-                  UNLOCK;
+-                  return chunk2mem(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.
++        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.
+-       */
++        The bitmap avoids needing to check that most blocks are nonempty.
++      */
+     ++idx;
+     bin = bin_at(av,idx);
+@@ -1056,109 +1054,111 @@ void* malloc(size_t bytes)
+     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);
+-              UNLOCK;
+-              return chunk2mem(victim);
+-          }
++              /* 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);
+-          /* Split */
+-          else {
+-              remainder = chunk_at_offset(victim, nb);
++                      bin = bin_at(av, (block << BINMAPSHIFT));
++                      bit = 1;
++              }
+-              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;
++              /* Advance to bin with set bit. There must be one. */
++              while ((bit & map) == 0) {
++                      bin = next_bin(bin);
++                      bit <<= 1;
++                      assert(bit != 0);
++              }
+-              set_head(victim, nb | PREV_INUSE);
+-              set_head(remainder, remainder_size | PREV_INUSE);
+-              set_foot(remainder, remainder_size);
+-              check_malloced_chunk(victim, nb);
+-              UNLOCK;
+-              return chunk2mem(victim);
+-          }
+-      }
++              /* 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:
++ 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.)
+-       */
++        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);
+-      UNLOCK;
+-      return chunk2mem(victim);
++              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);
+-    UNLOCK;
+-    return sysmem;
++    retval = sysmem;
++ DONE:
++      __MALLOC_UNLOCK;
++      return retval;
+ }
+diff --git a/libc/stdlib/malloc-standard/malloc.h b/libc/stdlib/malloc-standard/malloc.h
+index fbc1492..14a0dd9 100644
+--- a/libc/stdlib/malloc-standard/malloc.h
++++ b/libc/stdlib/malloc-standard/malloc.h
+@@ -22,16 +22,12 @@
+ #include <malloc.h>
+ #include <stdlib.h>
++#include <bits/uClibc_mutex.h>
+-#ifdef __UCLIBC_HAS_THREADS__
+-#include <pthread.h>
+-extern pthread_mutex_t __malloc_lock;
+-# define LOCK __pthread_mutex_lock(&__malloc_lock)
+-# define UNLOCK       __pthread_mutex_unlock(&__malloc_lock);
+-#else
+-# define LOCK
+-# define UNLOCK
+-#endif
++__UCLIBC_MUTEX_EXTERN(__malloc_lock);
++
++#define __MALLOC_LOCK         __UCLIBC_MUTEX_LOCK(__malloc_lock)
++#define __MALLOC_UNLOCK               __UCLIBC_MUTEX_UNLOCK(__malloc_lock)
+diff --git a/libc/stdlib/malloc-standard/mallopt.c b/libc/stdlib/malloc-standard/mallopt.c
+index e287920..41aa614 100644
+--- a/libc/stdlib/malloc-standard/mallopt.c
++++ b/libc/stdlib/malloc-standard/mallopt.c
+@@ -8,7 +8,7 @@
+   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
++  ftp://gee.cs.oswego.edu/pub/misc/malloc.c
+   Check before installing!
+   Hacked up for uClibc by Erik Andersen <andersen@codepoet.org>
+@@ -25,40 +25,40 @@ int mallopt(int param_number, int value)
+     ret = 0;
+-    LOCK;
++    __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;
++              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;
+     }
+-    UNLOCK;
++    __MALLOC_UNLOCK;
+     return ret;
+ }
+diff --git a/libc/stdlib/malloc-standard/memalign.c b/libc/stdlib/malloc-standard/memalign.c
+index bd95362..e78d752 100644
+--- a/libc/stdlib/malloc-standard/memalign.c
++++ b/libc/stdlib/malloc-standard/memalign.c
+@@ -8,7 +8,7 @@
+   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
++  ftp://gee.cs.oswego.edu/pub/misc/malloc.c
+   Check before installing!
+   Hacked up for uClibc by Erik Andersen <andersen@codepoet.org>
+@@ -35,6 +35,7 @@ void* memalign(size_t alignment, size_t 
+     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 */
+@@ -46,12 +47,12 @@ void* memalign(size_t alignment, size_t 
+     /* 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;
++              size_t a = MALLOC_ALIGNMENT * 2;
++              while ((unsigned long)a < (unsigned long)alignment) a <<= 1;
++              alignment = a;
+     }
+-    LOCK;
++    __MALLOC_LOCK;
+     checked_request2size(bytes, nb);
+     /* Strategy: find a spot within that chunk that meets the alignment
+@@ -63,64 +64,67 @@ void* memalign(size_t alignment, size_t 
+     m  = (char*)(malloc(nb + alignment + MINSIZE));
+     if (m == 0) {
+-      UNLOCK;
+-      return 0; /* propagate failure */
++              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);
+-          UNLOCK;
+-          return chunk2mem(newp);
+-      }
+-
+-      /* 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;
++              /*
++                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);
++              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));
+-      }
++              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);
+-    UNLOCK;
+-    return chunk2mem(p);
++    retval = chunk2mem(p);
++
++ DONE:
++    __MALLOC_UNLOCK;
++      return retval;
+ }
+diff --git a/libc/stdlib/malloc-standard/realloc.c b/libc/stdlib/malloc-standard/realloc.c
+index 1950130..9ca4b26 100644
+--- a/libc/stdlib/malloc-standard/realloc.c
++++ b/libc/stdlib/malloc-standard/realloc.c
+@@ -8,7 +8,7 @@
+   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
++  ftp://gee.cs.oswego.edu/pub/misc/malloc.c
+   Check before installing!
+   Hacked up for uClibc by Erik Andersen <andersen@codepoet.org>
+@@ -23,14 +23,14 @@ void* realloc(void* oldmem, size_t bytes
+ {
+     mstate av;
+-    size_t  nb;              /* padded request size */
++    size_t  nb;                       /* padded request size */
+     mchunkptr        oldp;            /* chunk corresponding to oldmem */
+-    size_t  oldsize;         /* its size */
++    size_t  oldsize;                  /* its size */
+     mchunkptr        newp;            /* chunk to return */
+-    size_t  newsize;         /* its size */
+-    void*          newmem;          /* corresponding user mem */
++    size_t  newsize;                  /* its size */
++    void*          newmem;            /* corresponding user mem */
+     mchunkptr        next;            /* next contiguous chunk after oldp */
+@@ -40,21 +40,23 @@ void* realloc(void* oldmem, size_t bytes
+     mchunkptr        bck;             /* misc temp for linking */
+     mchunkptr        fwd;             /* misc temp for linking */
+-    unsigned long     copysize;        /* bytes to copy */
++    unsigned long     copysize;       /* bytes to copy */
+     unsigned int     ncopies;         /* size_t words to copy */
+-    size_t* s;               /* copy source */
+-    size_t* d;               /* copy destination */
++    size_t* s;                        /* copy source */
++    size_t* d;                        /* copy destination */
++
++      void *retval;
+     /* Check for special cases.  */
+     if (! oldmem)
+-      return malloc(bytes);
++              return malloc(bytes);
+     if (! bytes) {
+-      free (oldmem);
+-      return malloc(bytes);
++              free (oldmem);
++              return malloc(bytes);
+     }
+-    LOCK;
++    __MALLOC_LOCK;
+     av = get_malloc_state();
+     checked_request2size(bytes, nb);
+@@ -65,173 +67,176 @@ void* realloc(void* oldmem, size_t bytes
+     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);
+-              UNLOCK;
+-              return chunk2mem(oldp);
+-          }
+-
+-          /* 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) {
+-                  UNLOCK;
+-                  return 0; /* propagate failure */
+-              }
+-
+-              newp = mem2chunk(newmem);
+-              newsize = chunksize(newp);
+-
+-              /*
+-                 Avoid copy if newp is next chunk after oldp.
+-                 */
+-              if (newp == next) {
+-                  newsize += oldsize;
+-                  newp = oldp;
++              if ((unsigned long)(oldsize) >= (unsigned long)(nb)) {
++                      /* already big enough; split below */
++                      newp = oldp;
++                      newsize = oldsize;
+               }
++
+               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);
++                      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;
+-                  free(oldmem);
+-                  check_inuse_chunk(newp);
+-                  UNLOCK;
+-                  return chunk2mem(newp);
+-              }
+-          }
+-      }
+-
+-      /* 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);
+-      UNLOCK;
+-      return chunk2mem(newp);
++              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
+-       */
++        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) {
+-          UNLOCK;
+-          return oldmem;
+-      }
+-
+-      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;
+-
+-          UNLOCK;
+-          return chunk2mem(newp);
+-      }
+-
+-      /* 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);
+-          }
+-      }
+-      UNLOCK;
+-      return newmem;
++              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/libc/stdlib/random.c b/libc/stdlib/random.c
+index b0a00e1..1bd63bc 100644
+--- a/libc/stdlib/random.c
++++ b/libc/stdlib/random.c
+@@ -27,16 +27,14 @@
+ #include <limits.h>
+ #include <stddef.h>
+ #include <stdlib.h>
+-#ifdef __UCLIBC_HAS_THREADS__
+-#include <pthread.h>
++
+ /* POSIX.1c requires that there is mutual exclusion for the `rand' and
+    `srand' functions to prevent concurrent calls from modifying common
+    data.  */
+-static pthread_mutex_t lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+-#else
+-#define __pthread_mutex_lock(x)
+-#define __pthread_mutex_unlock(x)
+-#endif
++
++#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
+@@ -184,9 +182,9 @@ static struct random_data unsafe_state =
+    for default usage relies on values produced by this routine.  */
+ void srandom (unsigned int x)
+ {
+-    __pthread_mutex_lock(&lock);
++    __UCLIBC_MUTEX_LOCK(mylock);
+     srandom_r (x, &unsafe_state);
+-    __pthread_mutex_unlock(&lock);
++    __UCLIBC_MUTEX_UNLOCK(mylock);
+ }
+ weak_alias (srandom, srand)
+@@ -205,10 +203,10 @@ char * initstate (unsigned int seed, cha
+ {
+     int32_t *ostate;
+-    __pthread_mutex_lock(&lock);
++    __UCLIBC_MUTEX_LOCK(mylock);
+     ostate = &unsafe_state.state[-1];
+     initstate_r (seed, arg_state, n, &unsafe_state);
+-    __pthread_mutex_unlock(&lock);
++    __UCLIBC_MUTEX_UNLOCK(mylock);
+     return (char *) ostate;
+ }
+@@ -224,11 +222,11 @@ char * setstate (char *arg_state)
+ {
+     int32_t *ostate;
+-    __pthread_mutex_lock(&lock);
++    __UCLIBC_MUTEX_LOCK(mylock);
+     ostate = &unsafe_state.state[-1];
+     if (setstate_r (arg_state, &unsafe_state) < 0)
+       ostate = NULL;
+-    __pthread_mutex_unlock(&lock);
++    __UCLIBC_MUTEX_UNLOCK(mylock);
+     return (char *) ostate;
+ }
+@@ -247,9 +245,9 @@ long int random ()
+ {
+   int32_t retval;
+-  __pthread_mutex_lock(&lock);
++  __UCLIBC_MUTEX_LOCK(mylock);
+   random_r (&unsafe_state, &retval);
+-  __pthread_mutex_unlock(&lock);
++  __UCLIBC_MUTEX_UNLOCK(mylock);
+   return retval;
+ }
+diff --git a/libc/stdlib/setenv.c b/libc/stdlib/setenv.c
+index d0cfe52..2d899cc 100644
+--- a/libc/stdlib/setenv.c
++++ b/libc/stdlib/setenv.c
+@@ -17,7 +17,7 @@
+    02111-1307 USA.  
+    
+    modified for uClibc by Erik Andersen <andersen@codepoet.org>
+-   */
++*/
+ #define _GNU_SOURCE
+ #include <features.h>
+@@ -26,16 +26,9 @@
+ #include <string.h>
+ #include <unistd.h>
+-#ifdef __UCLIBC_HAS_THREADS__
+-#include <pthread.h>
+-static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;
+-# define LOCK __pthread_mutex_lock(&mylock)
+-# define UNLOCK       __pthread_mutex_unlock(&mylock);
+-#else
+-# define LOCK
+-# define UNLOCK
+-#endif
++#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.  */
+@@ -49,14 +42,15 @@ static char **last_environ;
+    to reuse values once generated for a `setenv' call since we can never
+    free the strings.  */
+ int __add_to_environ (const char *name, const char *value, 
+-      const char *combined, int replace)
++                                        const char *combined, int replace)
+ {
+     register char **ep;
+     register size_t size;
+     const size_t namelen = strlen (name);
+     const size_t vallen = value != NULL ? strlen (value) + 1 : 0;
++    int rv = -1;
+-    LOCK;
++    __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.  */
+@@ -64,72 +58,72 @@ int __add_to_environ (const char *name, 
+     size = 0;
+     if (ep != NULL) {
+-      for (; *ep != NULL; ++ep) {
+-          if (!strncmp (*ep, name, namelen) && (*ep)[namelen] == '=')
+-              break;
+-          else
+-              ++size;
+-      }
++              for (; *ep != NULL; ++ep) {
++                      if (!strncmp (*ep, name, namelen) && (*ep)[namelen] == '=')
++                              break;
++                      else
++                              ++size;
++              }
+     }
+     if (ep == NULL || *ep == NULL) {
+-      char **new_environ;
++              char **new_environ;
+-      /* We allocated this space; we can extend it.  */
+-      new_environ = (char **) realloc (last_environ,
+-              (size + 2) * sizeof (char *));
+-      if (new_environ == NULL) {
+-          UNLOCK;
+-          return -1;
+-      }
+-
+-      /* If the whole entry is given add it.  */
+-      if (combined != NULL) {
+-          /* We must not add the string to the search tree since it belongs
+-             to the user.  */
+-          new_environ[size] = (char *) combined;
+-      } else {
+-          /* See whether the value is already known.  */
+-          new_environ[size] = (char *) malloc (namelen + 1 + vallen);
+-          if (new_environ[size] == NULL) {
+-              __set_errno (ENOMEM);
+-              UNLOCK;
+-              return -1;
+-          }
+-
+-          memcpy (new_environ[size], name, namelen);
+-          new_environ[size][namelen] = '=';
+-          memcpy (&new_environ[size][namelen + 1], value, vallen);
+-      }
+-
+-      if (__environ != last_environ) {
+-          memcpy ((char *) new_environ, (char *) __environ,
+-                  size * sizeof (char *));
+-      }
++              /* We allocated this space; we can extend it.  */
++              new_environ = (char **) realloc (last_environ,
++                                                                               (size + 2) * sizeof (char *));
++              if (new_environ == NULL) {
++                      goto DONE;
++              }
++
++              /* If the whole entry is given add it.  */
++              if (combined != NULL) {
++                      /* We must not add the string to the search tree since it belongs
++                         to the user.  */
++                      new_environ[size] = (char *) combined;
++              } else {
++                      /* See whether the value is already known.  */
++                      new_environ[size] = (char *) malloc (namelen + 1 + vallen);
++                      if (new_environ[size] == NULL) {
++                              __set_errno (ENOMEM);
++                              goto DONE;
++                      }
++
++                      memcpy (new_environ[size], name, namelen);
++                      new_environ[size][namelen] = '=';
++                      memcpy (&new_environ[size][namelen + 1], value, vallen);
++              }
++
++              if (__environ != last_environ) {
++                      memcpy ((char *) new_environ, (char *) __environ,
++                                      size * sizeof (char *));
++              }
+-      new_environ[size + 1] = NULL;
+-      last_environ = __environ = new_environ;
++              new_environ[size + 1] = NULL;
++              last_environ = __environ = new_environ;
+     } else if (replace) {
+-      char *np;
++              char *np;
+-      /* Use the user string if given.  */
+-      if (combined != NULL) {
+-          np = (char *) combined;
+-      } else {
+-          np = malloc (namelen + 1 + vallen);
+-          if (np == NULL) {
+-              UNLOCK;
+-              return -1;
+-          }
+-          memcpy (np, name, namelen);
+-          np[namelen] = '=';
+-          memcpy (&np[namelen + 1], value, vallen);
+-      }
+-      *ep = np;
+-    }
+-
+-    UNLOCK;
+-    return 0;
++              /* Use the user string if given.  */
++              if (combined != NULL) {
++                      np = (char *) combined;
++              } else {
++                      np = malloc (namelen + 1 + vallen);
++                      if (np == NULL) {
++                              goto DONE;
++                      }
++                      memcpy (np, name, namelen);
++                      np[namelen] = '=';
++                      memcpy (&np[namelen + 1], value, vallen);
++              }
++              *ep = np;
++    }
++
++    rv = 0;
++
++ DONE:
++    __UCLIBC_MUTEX_UNLOCK(mylock);
++    return rv;
+ }
+ int setenv (const char *name, const char *value, int replace)
+@@ -143,26 +137,26 @@ int unsetenv (const char *name)
+     char **ep;
+     if (name == NULL || *name == '\0' || strchr (name, '=') != NULL) {
+-      __set_errno (EINVAL);
+-      return -1;
++              __set_errno (EINVAL);
++              return -1;
+     }
+     len = strlen (name);
+-    LOCK;
++    __UCLIBC_MUTEX_LOCK(mylock);
+     ep = __environ;
+     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;
+-      }
++              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;
++              }
+     }
+-    UNLOCK;
++    __UCLIBC_MUTEX_UNLOCK(mylock);
+     return 0;
+ }
+@@ -171,15 +165,15 @@ int unsetenv (const char *name)
+    for Fortran 77) requires this function.  */
+ int clearenv (void)
+ {
+-    LOCK;
++    __UCLIBC_MUTEX_LOCK(mylock);
+     if (__environ == last_environ && __environ != NULL) {
+-      /* We allocated this environment so we can free it.  */
+-      free (__environ);
+-      last_environ = NULL;
++              /* We allocated this environment so we can free it.  */
++              free (__environ);
++              last_environ = NULL;
+     }
+     /* Clear the environment pointer removes the whole environment.  */
+     __environ = NULL;
+-    UNLOCK;
++    __UCLIBC_MUTEX_UNLOCK(mylock);
+     return 0;
+ }
+@@ -190,10 +184,10 @@ int putenv (char *string)
+     const char *const name_end = strchr (string, '=');
+     if (name_end != NULL) {
+-      char *name = strndup(string, name_end - string);
+-      result = __add_to_environ (name, NULL, string, 1);
+-      free(name);
+-      return(result);
++              char *name = strndup(string, name_end - string);
++              result = __add_to_environ (name, NULL, string, 1);
++              free(name);
++              return(result);
+     }
+     unsetenv (string);
+     return 0;
+diff --git a/libc/sysdeps/linux/common/bits/uClibc_stdio.h b/libc/sysdeps/linux/common/bits/uClibc_stdio.h
+index 40cd5fe..3c6911e 100644
+--- a/libc/sysdeps/linux/common/bits/uClibc_stdio.h
++++ b/libc/sysdeps/linux/common/bits/uClibc_stdio.h
+@@ -116,9 +116,7 @@
+ #endif
+ /**********************************************************************/
+-#ifdef __UCLIBC_HAS_THREADS__
+-/* Need this for pthread_mutex_t. */
+-#include <bits/pthreadtypes.h>
++#include <bits/uClibc_mutex.h>
+ /* user_locking
+  * 0 : do auto locking/unlocking
+@@ -132,43 +130,37 @@
+  * This way, we avoid calling the weak lock/unlock functions.
+  */
+-#define __STDIO_AUTO_THREADLOCK_VAR                   int __infunc_user_locking
+-
+-#define __STDIO_AUTO_THREADLOCK(__stream)                                                             \
+-      if ((__infunc_user_locking = (__stream)->__user_locking) == 0) {        \
+-              __pthread_mutex_lock(&(__stream)->__lock);                                              \
+-      }
+-
+-#define __STDIO_AUTO_THREADUNLOCK(__stream)                           \
+-      if (__infunc_user_locking == 0) {                                       \
+-              __pthread_mutex_unlock(&(__stream)->__lock);            \
+-      }
++#define __STDIO_AUTO_THREADLOCK_VAR                                                                                   \
++        __UCLIBC_MUTEX_AUTO_LOCK_VAR(__infunc_user_locking)
+-#define __STDIO_SET_USER_LOCKING(__stream)    ((__stream)->__user_locking = 1)
++#define __STDIO_AUTO_THREADLOCK(__stream)                                                                     \
++        __UCLIBC_MUTEX_AUTO_LOCK((__stream)->__lock, __infunc_user_locking,   \
++                                                               (__stream)->__user_locking)
+-#define __STDIO_ALWAYS_THREADLOCK(__stream)   \
+-              __pthread_mutex_lock(&(__stream)->__lock)
++#define __STDIO_AUTO_THREADUNLOCK(__stream)                                                                   \
++        __UCLIBC_MUTEX_AUTO_UNLOCK((__stream)->__lock, __infunc_user_locking)
+-#define __STDIO_ALWAYS_THREADTRYLOCK(__stream)        \
+-              __pthread_mutex_trylock(&(__stream)->__lock)
++#define __STDIO_ALWAYS_THREADLOCK(__stream)                                                                   \
++        __UCLIBC_MUTEX_LOCK((__stream)->__lock)
+-#define __STDIO_ALWAYS_THREADUNLOCK(__stream) \
+-              __pthread_mutex_unlock(&(__stream)->__lock)
++#define __STDIO_ALWAYS_THREADUNLOCK(__stream)                                                         \
++        __UCLIBC_MUTEX_UNLOCK((__stream)->__lock)
+-#else  /* __UCLIBC_HAS_THREADS__ */
++#define __STDIO_ALWAYS_THREADLOCK_CANCEL_UNSAFE(__stream)                                     \
++        __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE((__stream)->__lock)
+-#define __STDIO_AUTO_THREADLOCK_VAR                           ((void)0)
++#define __STDIO_ALWAYS_THREADTRYLOCK_CANCEL_UNSAFE(__stream)                          \
++        __UCLIBC_MUTEX_TRYLOCK_CANCEL_UNSAFE((__stream)->__lock)
+-#define __STDIO_AUTO_THREADLOCK(__stream)             ((void)0)
+-#define __STDIO_AUTO_THREADUNLOCK(__stream)           ((void)0)
++#define __STDIO_ALWAYS_THREADUNLOCK_CANCEL_UNSAFE(__stream)                           \
++        __UCLIBC_MUTEX_UNLOCK_CANCEL_UNSAFE((__stream)->__lock)
++#ifdef __UCLIBC_HAS_THREADS__
++#define __STDIO_SET_USER_LOCKING(__stream)    ((__stream)->__user_locking = 1)
++#else
+ #define __STDIO_SET_USER_LOCKING(__stream)            ((void)0)
++#endif
+-#define __STDIO_ALWAYS_THREADLOCK(__stream)           ((void)0)
+-#define __STDIO_ALWAYS_THREADTRYLOCK(__stream)        (0)     /* Always succeed. */
+-#define __STDIO_ALWAYS_THREADUNLOCK(__stream) ((void)0)
+-
+-#endif /* __UCLIBC_HAS_THREADS__ */
+ /**********************************************************************/
+ #define __STDIO_IOFBF 0               /* Fully buffered.  */
+@@ -283,7 +275,7 @@ struct __STDIO_FILE_STRUCT {
+ #endif
+ #ifdef __UCLIBC_HAS_THREADS__
+       int __user_locking;
+-      pthread_mutex_t __lock;
++      __UCLIBC_MUTEX(__lock);
+ #endif
+ /* Everything after this is unimplemented... and may be trashed. */
+ #if __STDIO_BUILTIN_BUF_SIZE > 0
+@@ -358,10 +350,14 @@ extern void _stdio_term(void);
+ extern struct __STDIO_FILE_STRUCT *_stdio_openlist;
+ #ifdef __UCLIBC_HAS_THREADS__
+-extern pthread_mutex_t _stdio_openlist_lock;
+-extern int _stdio_openlist_delflag;
++__UCLIBC_MUTEX_EXTERN(_stdio_openlist_add_lock);
++#ifdef __STDIO_BUFFERS
++__UCLIBC_MUTEX_EXTERN(_stdio_openlist_del_lock);
++extern volatile int _stdio_openlist_use_count; /* _stdio_openlist_del_lock */
++extern int _stdio_openlist_del_count; /* _stdio_openlist_del_lock */
++#endif
+ extern int _stdio_user_locking;
+-extern void __stdio_init_mutex(pthread_mutex_t *m);
++extern void __stdio_init_mutex(__UCLIBC_MUTEX_TYPE *m);
+ #endif
+ #endif
+diff --git a/libc/sysdeps/linux/common/getdents.c b/libc/sysdeps/linux/common/getdents.c
+index ab6a276..23463e5 100644
+--- a/libc/sysdeps/linux/common/getdents.c
++++ b/libc/sysdeps/linux/common/getdents.c
+@@ -30,8 +30,6 @@
+ #include <sys/syscall.h>
+-#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+-
+ struct kernel_dirent
+ {
+     long              d_ino;
+diff --git a/libc/sysdeps/linux/common/sigprocmask.c b/libc/sysdeps/linux/common/sigprocmask.c
+index 70ff366..565318d 100644
+--- a/libc/sysdeps/linux/common/sigprocmask.c
++++ b/libc/sysdeps/linux/common/sigprocmask.c
+@@ -23,6 +23,8 @@ int sigprocmask(int how, const sigset_t 
+       if (set &&
+ #if (SIG_BLOCK == 0) && (SIG_UNBLOCK == 1) && (SIG_SETMASK == 2)
+               (((unsigned int) how) > 2)
++#elif (SIG_BLOCK == 1) && (SIG_UNBLOCK == 2) && (SIG_SETMASK == 3)
++              (((unsigned int)(how-1)) > 2)
+ #else
+ #warning "compile time assumption violated.. slow path..."
+               ((how != SIG_BLOCK) && (how != SIG_UNBLOCK)
+@@ -48,6 +50,8 @@ int sigprocmask(int how, const sigset_t 
+       if (set &&
+ #if (SIG_BLOCK == 0) && (SIG_UNBLOCK == 1) && (SIG_SETMASK == 2)
+               (((unsigned int) how) > 2)
++#elif (SIG_BLOCK == 1) && (SIG_UNBLOCK == 2) && (SIG_SETMASK == 3)
++              (((unsigned int)(how-1)) > 2)
+ #else
+ #warning "compile time assumption violated.. slow path..."
+               ((how != SIG_BLOCK) && (how != SIG_UNBLOCK)
+diff --git a/libc/sysdeps/linux/mips/bits/kernel_sigaction.h b/libc/sysdeps/linux/mips/bits/kernel_sigaction.h
+index b6f52cc..317e5b3 100644
+--- a/libc/sysdeps/linux/mips/bits/kernel_sigaction.h
++++ b/libc/sysdeps/linux/mips/bits/kernel_sigaction.h
+@@ -38,3 +38,6 @@ struct kernel_sigaction {
+       void            (*sa_restorer)(void);
+       int             s_resv[1]; /* reserved */
+ };
++
++extern int __syscall_rt_sigaction (int, const struct kernel_sigaction *__unbounded,
++      struct kernel_sigaction *__unbounded, size_t);
+diff --git a/libc/sysdeps/linux/mips/pipe.S b/libc/sysdeps/linux/mips/pipe.S
+index c3afae5..cd88074 100644
+--- a/libc/sysdeps/linux/mips/pipe.S
++++ b/libc/sysdeps/linux/mips/pipe.S
+@@ -7,25 +7,36 @@
+ #include <asm/unistd.h>
+ #include <asm/regdef.h>
+-        .globl  pipe
+-        .ent    pipe, 0
++      .globl  pipe
++      .ent    pipe, 0
+ pipe:
+-        addiu   sp,sp,-24
+-        sw      a0,16(sp)
+-        li      v0,__NR_pipe
+-        syscall
+-        beqz    a3, 1f
+-        la      t3, errno
+-        sw      v0, (t3)
+-        li      v0, -1
+-        b       2f
++      .frame  sp, 24, sp
++#ifdef __PIC__
++      .set    noreorder
++      .cpload $25
++      .set    reorder
++      addiu   sp,sp,-24
++      .cprestore      16
++#else
++      addiu   sp,sp,-24
++#endif
++      sw      a0,16(sp)
++      li      v0,__NR_pipe
++      syscall
++      beqz    a3, 1f
++#ifdef __PIC__
++      la      t0, __syscall_error
++      jr      t9
++#else
++      j       __syscall_error
++#endif
+ 1:
+-        lw      a0, 16(sp)
+-        sw      v0, 0(a0)
+-        sw      v1, 4(a0)
+-        li      v0, 0
++      lw      a0, 16(sp)
++      sw      v0, 0(a0)
++      sw      v1, 4(a0)
++      li      v0, 0
+ 2:
+-        addiu   sp,sp,24
+-        j       ra
+-        .end    pipe
+-        .size   pipe,.-pipe
++      addiu   sp,sp,24
++      j       ra
++      .end    pipe
++      .size   pipe,.-pipe
+diff --git a/libcrypt/des.c b/libcrypt/des.c
+index 3b49a7a..f7a6be1 100644
+--- a/libcrypt/des.c
++++ b/libcrypt/des.c
+@@ -504,7 +504,7 @@ do_des(    u_int32_t l_in, u_int32_t r_in, 
+               kl = kl1;
+               kr = kr1;
+               round = 16;
+-              while (round--) {
++              do {
+                       /*
+                        * Expand R to 48 bits (simulate the E-box).
+                        */
+@@ -540,7 +540,7 @@ do_des(    u_int32_t l_in, u_int32_t r_in, 
+                       f ^= l;
+                       l = r;
+                       r = f;
+-              }
++              } while (--round);
+               r = l;
+               l = f;
+       }
+diff --git a/libpthread/linuxthreads/ptfork.c b/libpthread/linuxthreads/ptfork.c
+index eb544f3..cfec2b7 100644
+--- a/libpthread/linuxthreads/ptfork.c
++++ b/libpthread/linuxthreads/ptfork.c
+@@ -26,6 +26,15 @@
+ #include "pthread.h"
+ #include "internals.h"
++#warning hack alert... should be sufficent for system(), but what about other libc mutexes?
++#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)
++#warning hack alert block end
++
+ struct handler_list {
+   void (*handler)(void);
+   struct handler_list * next;
+@@ -91,9 +100,18 @@ pid_t __fork(void)
+   parent = pthread_atfork_parent;
+   pthread_mutex_unlock(&pthread_atfork_lock);
+   pthread_call_handlers(prepare);
++
++#warning hack alert
++  __MALLOC_LOCK;
++
+   pid = __libc_fork();
++
++#warning hack alert
++  __MALLOC_UNLOCK;
++
+   if (pid == 0) {
+     __pthread_reset_main_thread();
++#warning need to reconsider __fresetlockfiles!
+     __fresetlockfiles();
+     pthread_call_handlers(child);
+   } else {
+diff -urN -x .git uClibc-0.9.28/libc/sysdeps/linux/common/bits/uClibc_mutex.h uClibc-mjn3/libc/sysdeps/linux/common/bits/uClibc_mutex.h
+--- uClibc-0.9.28/libc/sysdeps/linux/common/bits/uClibc_mutex.h        1969-12-31 17:00:00.000000000 -0700
++++ uClibc-mjn3/libc/sysdeps/linux/common/bits/uClibc_mutex.h  2006-03-08 11:21:58.000000000 -0700
+@@ -0,0 +1,87 @@
++/* Copyright (C) 2006   Manuel Novoa III    <mjn3@codepoet.org>
++ *
++ * GNU Library General Public License (LGPL) version 2 or later.
++ *
++ * Dedicated to Toni.  See uClibc/DEDICATION.mjn3 for details.
++ */
++
++#ifndef _UCLIBC_MUTEX_H
++#define _UCLIBC_MUTEX_H
++
++#include <features.h>
++
++#ifdef __UCLIBC_HAS_THREADS__
++
++#include <pthread.h>
++
++#define __UCLIBC_MUTEX_TYPE                                   pthread_mutex_t
++
++#define __UCLIBC_MUTEX(M)                                     pthread_mutex_t M
++#define __UCLIBC_MUTEX_INIT(M,I)                      pthread_mutex_t M = I
++#define __UCLIBC_MUTEX_STATIC(M,I)                    static pthread_mutex_t M = I
++#define __UCLIBC_MUTEX_EXTERN(M)                      extern pthread_mutex_t M
++
++#define __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE(M)                                                          \
++              __pthread_mutex_lock(&(M))
++
++#define __UCLIBC_MUTEX_UNLOCK_CANCEL_UNSAFE(M)                                                                \
++              __pthread_mutex_unlock(&(M))
++
++#define __UCLIBC_MUTEX_TRYLOCK_CANCEL_UNSAFE(M)                                                               \
++              __pthread_mutex_trylock(&(M))
++
++#define __UCLIBC_MUTEX_CONDITIONAL_LOCK(M,C)                                                          \
++      do {                                                                                                                                    \
++              struct _pthread_cleanup_buffer __infunc_pthread_cleanup_buffer;         \
++              if (C) {                                                                                                                        \
++                      _pthread_cleanup_push_defer(&__infunc_pthread_cleanup_buffer,   \
++                                                                              __pthread_mutex_unlock,                         \
++                                                                              &(M));                                                          \
++                      __pthread_mutex_lock(&(M));                                                                             \
++              }                                                                                                                                       \
++              ((void)0)
++
++#define __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(M,C)                                                                \
++              if (C) {                                                                                                                        \
++                      _pthread_cleanup_pop_restore(&__infunc_pthread_cleanup_buffer,1);\
++              }                                                                                                                                       \
++      } while (0)
++
++#define __UCLIBC_MUTEX_AUTO_LOCK_VAR(A)               int A
++
++#define __UCLIBC_MUTEX_AUTO_LOCK(M,A,V)                                                                               \
++        __UCLIBC_MUTEX_CONDITIONAL_LOCK(M,((A=(V)) == 0))
++
++#define __UCLIBC_MUTEX_AUTO_UNLOCK(M,A)                                                                               \
++        __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(M,(A == 0))
++
++#define __UCLIBC_MUTEX_LOCK(M)                                                                                                \
++        __UCLIBC_MUTEX_CONDITIONAL_LOCK(M, 1)
++
++#define __UCLIBC_MUTEX_UNLOCK(M)                                                                                      \
++        __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(M, 1)
++
++#else
++
++#define __UCLIBC_MUTEX(M)                     void *__UCLIBC_MUTEX_DUMMY_ ## M
++#define __UCLIBC_MUTEX_INIT(M,I)      extern void *__UCLIBC_MUTEX_DUMMY_ ## M
++#define __UCLIBC_MUTEX_STATIC(M)      extern void *__UCLIBC_MUTEX_DUMMY_ ## M
++#define __UCLIBC_MUTEX_EXTERN(M)      extern void *__UCLIBC_MUTEX_DUMMY_ ## M
++
++#define __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE(M)          ((void)0)
++#define __UCLIBC_MUTEX_UNLOCK_CANCEL_UNSAFE(M)                ((void)0)
++#define __UCLIBC_MUTEX_TRYLOCK_CANCEL_UNSAFE(M)               (0)     /* Always succeed? */
++
++#define __UCLIBC_MUTEX_CONDITIONAL_LOCK(M,C)          ((void)0)
++#define __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(M,C)                ((void)0)
++
++#define __UCLIBC_MUTEX_AUTO_LOCK_VAR(A)                               ((void)0)
++#define __UCLIBC_MUTEX_AUTO_LOCK(M,A,V)                               ((void)0)
++#define __UCLIBC_MUTEX_AUTO_UNLOCK(M,A)                               ((void)0)
++
++#define __UCLIBC_MUTEX_LOCK(M)                                                ((void)0)
++#define __UCLIBC_MUTEX_UNLOCK(M)                                      ((void)0)
++
++#endif
++
++#endif /* _UCLIBC_MUTEX_H */
+diff -urN -x .git uClibc-0.9.28/libc/sysdeps/linux/mips/pipe.c uClibc-mjn3/libc/sysdeps/linux/mips/pipe.c
+--- uClibc-0.9.28/libc/sysdeps/linux/mips/pipe.c       2005-08-17 16:49:44.000000000 -0600
++++ uClibc-mjn3/libc/sysdeps/linux/mips/pipe.c 1969-12-31 17:00:00.000000000 -0700
+@@ -1,23 +0,0 @@
+-/* pipe system call for Linux/MIPS */
+-
+-/*see uClibc's sh/pipe.c and glibc-2.2.4's mips/pipe.S */
+-
+-#include <errno.h>
+-#include <unistd.h>
+-#include <syscall.h>
+-
+-int pipe(int *fd)
+-{
+-    register long int res __asm__ ("$2"); // v0
+-    register long int res2 __asm__ ("$3"); // v1
+-
+-    asm ("move\t$4,%2\n\t"            // $4 = a0
+-       "syscall"              /* Perform the system call.  */
+-       : "=r" (res)
+-       : "0" (__NR_pipe), "r" (fd)
+-       : "$4", "$7");
+-
+-      fd[0] = res;
+-      fd[1] = res2;
+-      return(0);
+-}
diff --git a/toolchain/uClibc/uClibc-0.9.28-600-new_dst_rules.patch b/toolchain/uClibc/uClibc-0.9.28-600-new_dst_rules.patch
new file mode 100644 (file)
index 0000000..8b1a5a9
--- /dev/null
@@ -0,0 +1,101 @@
+--- uClibc/libc/misc/time/time.c       (revision 16488)
++++ uClibc/libc/misc/time/time.c       (working copy)
+@@ -157,6 +157,22 @@
+ #define TZNAME_MAX _POSIX_TZNAME_MAX
+ #endif
++#if defined (L_tzset) || defined (L_localtime_r) || defined(L_strftime) || \
++       defined(L__time_mktime) || defined(L__time_mktime_tzi) || \
++       ((defined(L_strftime) || defined(L_strftime_l)) && \
++        defined(__UCLIBC_HAS_XLOCALE__))
++
++void _time_tzset (int);
++
++#ifndef L__time_mktime
++
++ /* Jan 1, 2007 Z - tm = 0,0,0,1,0,107,1,0,0 */
++
++const static time_t new_rule_starts = 1167609600;
++
++#endif
++#endif
++
+ /**********************************************************************/
+ /* The era code is currently unfinished. */
+ /*  #define ENABLE_ERA_CODE */
+@@ -532,7 +548,7 @@
+ {
+       __UCLIBC_MUTEX_LOCK(_time_tzlock);
+-      tzset();
++      _time_tzset(*timer < new_rule_starts);
+       __time_localtime_tzi(timer, result, _time_tzinfo);
+@@ -956,7 +972,8 @@
+       unsigned char mod;
+       unsigned char code;
+-      tzset();                                        /* We'll, let's get this out of the way. */
++      /* We'll, let's get this out of the way. */
++      _time_tzset(_time_mktime((struct tm *) timeptr, 0) < new_rule_starts);
+       lvl = 0;
+       p = format;
+@@ -1644,7 +1661,9 @@
+       6,  0,  0,                                      /* Note: overloaded for non-M non-J case... */
+       0, 1, 0,                                        /* J */
+       ',', 'M',      '4', '.', '1', '.', '0',
+-      ',', 'M', '1', '0', '.', '5', '.', '0', 0
++      ',', 'M', '1', '0', '.', '5', '.', '0', 0,
++      ',', 'M',      '3', '.', '2', '.', '0',
++      ',', 'M', '1', '1', '.', '1', '.', '0', 0
+ };
+ #define TZ    vals
+@@ -1652,6 +1671,7 @@
+ #define RANGE (vals + 7)
+ #define RULE  (vals + 11 - 1)
+ #define DEFAULT_RULES (vals + 22)
++#define DEFAULT_2007_RULES (vals + 38)
+ /* Initialize to UTC. */
+ int daylight = 0;
+@@ -1774,6 +1794,11 @@
+ void tzset(void)
+ {
++    _time_tzset((time(NULL)) < new_rule_starts);
++}
++
++void _time_tzset(int use_old_rules)
++{
+       register const char *e;
+       register char *s;
+       long off;
+@@ -1896,7 +1921,15 @@
+       } else {                                        /* OK, we have dst, so get some rules. */
+               count = 0;
+               if (!*e) {                              /* No rules so default to US rules. */
+-                      e = DEFAULT_RULES;
++                      e = use_old_rules ? DEFAULT_RULES : DEFAULT_2007_RULES;
++#ifdef DEBUG_TZSET                    
++                      if (e == DEFAULT_RULES)
++                          printf("tzset: Using old rules.\n");
++                      else if (e == DEFAULT_2007_RULES)
++                          printf("tzset: Using new rules\n");
++                      else
++                          printf("tzset: Using undefined rules\n");
++#endif /* DEBUG_TZSET */
+               }
+               do {
+@@ -2230,6 +2263,8 @@
+               --d;
+       }
++      _time_tzset (x.tm_year < 2007); /* tm_year was expanded above */
++
+ #ifdef __BCC__
+       d = p[5] - 1;
+       days = -719163L + ((long)d)*365 + ((d/4) - (d/100) + (d/400) + p[3] + p[7]);
diff --git a/toolchain/uClibc/uClibc-0.9.28-700-rm-whitespace.patch b/toolchain/uClibc/uClibc-0.9.28-700-rm-whitespace.patch
new file mode 100644 (file)
index 0000000..6004f91
--- /dev/null
@@ -0,0 +1,86 @@
+diff -urN uClibc-0.9.29-0rig/include/assert.h uClibc-0.9.29/include/assert.h
+--- uClibc-0.9.29-0rig/include/assert.h        2005-11-03 23:42:46.000000000 +0100
++++ uClibc-0.9.29/include/assert.h     2007-08-13 19:10:57.000000000 +0200
+@@ -31,7 +31,7 @@
+ #define       _ASSERT_H       1
+ #include <features.h>
+-#if defined __cplusplus && __GNUC_PREREQ (2,95)
++#if defined __cplusplus && __GNUC_PREREQ(2,95)
+ # define __ASSERT_VOID_CAST static_cast<void>
+ #else
+ # define __ASSERT_VOID_CAST (void)
+@@ -59,13 +59,17 @@
+   (__ASSERT_VOID_CAST ((expr) ? 0 :                                         \
+                      (__assert (__STRING(expr), __FILE__, __LINE__,    \
+                                      __ASSERT_FUNCTION), 0)))
+-  
++
++/* Define some temporaries to workaround tinyx makedepend bug */
++#define       __GNUC_PREREQ_2_6       __GNUC_PREREQ(2, 6)
++#define       __GNUC_PREREQ_2_4       __GNUC_PREREQ(2, 4)
+ /* Version 2.4 and later of GCC define a magical variable `__PRETTY_FUNCTION__'
+    which contains the name of the function currently being defined.
+    This is broken in G++ before version 2.6.
+    C9x has a similar variable called __func__, but prefer the GCC one since
+    it demangles C++ function names.  */
+-# if defined __cplusplus ? __GNUC_PREREQ (2, 6) : __GNUC_PREREQ (2, 4)
++
++# if defined __cplusplus ? __GNUC_PREREQ_2_6 : __GNUC_PREREQ_2_4
+ #   define __ASSERT_FUNCTION  __PRETTY_FUNCTION__
+ # else
+ #  if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
+diff -urN uClibc-0.9.29-0rig/include/complex.h uClibc-0.9.29/include/complex.h
+--- uClibc-0.9.29-0rig/include/complex.h       2002-05-09 10:15:21.000000000 +0200
++++ uClibc-0.9.29/include/complex.h    2007-08-13 17:55:29.000000000 +0200
+@@ -33,7 +33,7 @@
+ /* We might need to add support for more compilers here.  But since ISO
+    C99 is out hopefully all maintained compilers will soon provide the data
+    types `float complex' and `double complex'.  */
+-#if __GNUC_PREREQ (2, 7) && !__GNUC_PREREQ (2, 97)
++#if __GNUC_PREREQ(2, 7) && !__GNUC_PREREQ(2, 97)
+ # define _Complex __complex__
+ #endif
+diff -urN uClibc-0.9.29-0rig/include/features.h uClibc-0.9.29/include/features.h
+--- uClibc-0.9.29-0rig/include/features.h      2006-11-29 22:10:04.000000000 +0100
++++ uClibc-0.9.29/include/features.h   2007-08-13 17:55:51.000000000 +0200
+@@ -143,7 +143,7 @@
+ /* Convenience macros to test the versions of glibc and gcc.
+    Use them like this:
+-   #if __GNUC_PREREQ (2,8)
++   #if __GNUC_PREREQ(2,8)
+    ... code requiring gcc 2.8 or later ...
+    #endif
+    Note - they won't work for gcc1 or glibc1, since the _MINOR macros
+@@ -297,7 +297,7 @@
+ /* uClibc does not support _FORTIFY_SOURCE */
+ #undef _FORTIFY_SOURCE
+ #if defined _FORTIFY_SOURCE && _FORTIFY_SOURCE > 0 \
+-    && __GNUC_PREREQ (4, 1) && defined __OPTIMIZE__ && __OPTIMIZE__ > 0
++    && __GNUC_PREREQ(4, 1) && defined __OPTIMIZE__ && __OPTIMIZE__ > 0
+ # if _FORTIFY_SOURCE > 1
+ #  define __USE_FORTIFY_LEVEL 2
+ # else
+@@ -366,7 +366,7 @@
+ #endif        /* !ASSEMBLER */
+ /* Decide whether we can define 'extern inline' functions in headers.  */
+-#if __GNUC_PREREQ (2, 7) && defined __OPTIMIZE__ \
++#if __GNUC_PREREQ(2, 7) && defined __OPTIMIZE__ \
+     && !defined __OPTIMIZE_SIZE__ && !defined __NO_INLINE__
+ # define __USE_EXTERN_INLINES 1
+ #endif
+diff -urN uClibc-0.9.29-0rig/include/tgmath.h uClibc-0.9.29/include/tgmath.h
+--- uClibc-0.9.29-0rig/include/tgmath.h        2002-05-09 10:15:21.000000000 +0200
++++ uClibc-0.9.29/include/tgmath.h     2007-08-13 17:56:17.000000000 +0200
+@@ -34,7 +34,7 @@
+    do not try this for now and instead concentrate only on GNU CC.  Once
+    we have more information support for other compilers might follow.  */
+-#if __GNUC_PREREQ (2, 7)
++#if __GNUC_PREREQ(2, 7)
+ # ifdef __NO_LONG_DOUBLE_MATH
+ #  define __tgml(fct) fct
diff --git a/toolchain/uClibc/uClibc-0.9.28-800-avr32-1.patch b/toolchain/uClibc/uClibc-0.9.28-800-avr32-1.patch
new file mode 100644 (file)
index 0000000..14c3b38
--- /dev/null
@@ -0,0 +1,4433 @@
+Index: uclibc/Makefile
+===================================================================
+RCS file: /disk1/ic_group/design/I9980/REPOSITORY/I7413/source/uclibc/Makefile,v
+retrieving revision 1.1.1.3
+diff -u -r1.1.1.3 Makefile
+--- uclibc/Makefile    31 Aug 2005 13:08:25 -0000      1.1.1.3
++++ uclibc/Makefile    7 Dec 2005 06:38:39 -0000
+@@ -163,7 +163,7 @@
+       else \
+               extra_exclude="" ; \
+       fi ; \
+-      tar -chf - include --exclude .svn --exclude CVS $$extra_exclude \
++      tar -chf - --exclude .svn --exclude CVS $$extra_exclude include \
+               | tar -xf - -C $(PREFIX)$(DEVEL_PREFIX)
+ ifneq ($(strip $(UCLIBC_HAS_FLOATS)),y)
+       # Remove floating point related headers since float support is disabled.
+--- a/extra/scripts/fix_includes.sh    2005-08-18 00:49:41.000000000 +0200
++++ b/extra/scripts/fix_includes.sh    2006-09-27 13:23:12.000000000 +0200
+@@ -78,36 +78,6 @@ if [ ! -d "$KERNEL_SOURCE" ]; then
+     exit 1;
+ fi;
+-if [ -f "$KERNEL_SOURCE/Makefile" ] ; then
+-# set current VERSION, PATCHLEVEL, SUBLEVEL, EXTRAVERSION
+-eval `sed -n -e 's/^\([A-Z]*\) = \([0-9]*\)$/\1=\2/p' -e 's/^\([A-Z]*\) = \(-[-a-z0-9]*\)$/\1=\2/p' $KERNEL_SOURCE/Makefile`
+-else
+-ver=`grep UTS_RELEASE $KERNEL_SOURCE/include/linux/version.h | cut -d '"' -f 2`
+-VERSION=`echo "$ver" | cut -d '.' -f 1`
+-PATCHLEVEL=`echo "$ver" | cut -d '.' -f 2`
+-if echo "$ver" | grep -q '-' ; then
+-SUBLEVEL=`echo "$ver" | sed "s/${VERSION}.${PATCHLEVEL}.//" | cut -d '-' -f 1`
+-EXTRAVERSION=`echo "$ver" | sed "s/${VERSION}.${PATCHLEVEL}.${SUBLEVEL}-//"`
+-else
+-SUBLEVEL=`echo "$ver" | cut -d '.' -f 3`
+-#EXTRAVERSION=
+-fi
+-fi
+-if [ -z "$VERSION" -o -z "$PATCHLEVEL" -o -z "$SUBLEVEL" ]
+-then
+-    echo "Unable to determine version for kernel headers"
+-    echo -e "\tprovided in directory $KERNEL_SOURCE"
+-    exit 1
+-fi
+-
+-if [ "$MAKE_IS_SILENT" != "y" ]; then
+-echo "Current kernel version is $VERSION.$PATCHLEVEL.$SUBLEVEL${EXTRAVERSION}"
+-echo -e "\n"
+-echo "Using kernel headers from $VERSION.$PATCHLEVEL.$SUBLEVEL${EXTRAVERSION} for architecture '$TARGET_ARCH'"
+-echo -e "\tprovided in directory $KERNEL_SOURCE"
+-echo -e "\n"
+-fi
+-
+ # Create a symlink to include/asm
+ rm -f include/asm*
+@@ -172,7 +142,7 @@ fi;
+ # Annoyingly, 2.6.x kernel headers also need an include/asm-generic/ directory
+-if [ $VERSION -eq 2 ] && [ $PATCHLEVEL -ge 6 ] ; then
++if [ -d $KERNEL_SOURCE/include/asm-generic ] ; then
+     ln -fs $KERNEL_SOURCE/include/asm-generic include/asm-generic
+ fi;
+From 7b2f125425cf777e7937b533217588e27952b87d Mon Sep 17 00:00:00 2001
+From: Haavard Skinnemoen <hskinnemoen@atmel.com>
+Date: Mon, 7 Aug 2006 11:12:50 +0200
+Subject: [PATCH] Let optimized stringops override default ones
+
+The default, slow stringops must be archived _before_ the optimized
+stringops if there is to be any point doing the optimizations in the
+first place.
+---
+ libc/Makefile |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/libc/Makefile b/libc/Makefile
+index 31e4bab..687eac5 100644
+--- a/libc/Makefile
++++ b/libc/Makefile
+@@ -59,7 +59,7 @@ # will evaluate to no files :(.
+       $(AR) dN 2 $(LIBNAME) $$objs && \
+       $(AR) dN 2 $(LIBNAME) $$objs
+       @for objfile in obj.signal \
+-                      obj.string.generic obj.string.$(TARGET_ARCH) obj.string \
++                      obj.string obj.string.generic obj.string.$(TARGET_ARCH) \
+                       obj.sysdeps.common obj.sysdeps.$(TARGET_ARCH) ; do \
+               if [ -e $$objfile ] ; then \
+                       if [ "$(MAKE_IS_SILENT)" = "n" ] ; then \
+-- 
+1.4.1.1
+
+Subject: [PATCH] Fix getrusage argument type
+
+The first argument to getrusage is of type __rusage_who_t, not int.
+This patch fixes that.
+---
+
+ libc/sysdeps/linux/common/getrusage.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: uClibc-0.9.28/libc/sysdeps/linux/common/getrusage.c
+===================================================================
+--- uClibc-0.9.28.orig/libc/sysdeps/linux/common/getrusage.c   2006-02-07 17:18:22.000000000 +0100
++++ uClibc-0.9.28/libc/sysdeps/linux/common/getrusage.c        2006-02-07 17:18:31.000000000 +0100
+@@ -10,4 +10,4 @@
+ #include "syscalls.h"
+ #include <unistd.h>
+ #include <wait.h>
+-_syscall2(int, getrusage, int, who, struct rusage *, usage);
++_syscall2(int, getrusage, __rusage_who_t, who, struct rusage *, usage);
+Subject: [PATCH] Fix __libc_fcntl64 prototype in __syscall_fcntl.c
+
+__libc_fcntl64 is a varargs function and should be declared as such.
+Otherwise, the gcc compiler for AVR32, and perhaps other architectures,
+will use the wrong calling convention.
+
+---
+
+ libc/sysdeps/linux/common/__syscall_fcntl.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: uClibc-0.9.28/libc/sysdeps/linux/common/__syscall_fcntl.c
+===================================================================
+--- uClibc-0.9.28.orig/libc/sysdeps/linux/common/__syscall_fcntl.c     2006-02-07 16:48:32.000000000 +0100
++++ uClibc-0.9.28/libc/sysdeps/linux/common/__syscall_fcntl.c  2006-02-07 17:19:09.000000000 +0100
+@@ -12,7 +12,7 @@
+ #include <fcntl.h>
+ #if defined __UCLIBC_HAS_LFS__ && defined __NR_fcntl64
+-extern int __libc_fcntl64(int fd, int cmd, long arg);
++extern int __libc_fcntl64(int fd, int cmd, ...);
+ #endif
+ #define __NR___syscall_fcntl __NR_fcntl
+From nobody Mon Sep 17 00:00:00 2001
+From: HÃ¥vard Skinnemoen <hskinnemoen@atmel.com>
+Date: Fri Apr 7 17:10:32 2006 +0200
+Subject: [PATCH] Fix broken __libc_open declaration in open64.c
+
+__libc_open is a vararg function and should therefore be declared as
+such. Fixes bug #4190.
+
+---
+
+ libc/sysdeps/linux/common/open64.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+70f2c81903327a8a346e370830932b80045ab04e
+diff --git a/libc/sysdeps/linux/common/open64.c b/libc/sysdeps/linux/common/open64.c
+index 543aa13..d9a27a7 100644
+--- a/libc/sysdeps/linux/common/open64.c
++++ b/libc/sysdeps/linux/common/open64.c
+@@ -26,7 +26,7 @@
+ #endif
+ #ifdef __UCLIBC_HAS_LFS__
+-extern int __libc_open (__const char *file, int oflag, mode_t mode);
++extern int __libc_open (__const char *file, int oflag, ...);
+ /* Open FILE with access OFLAG.  If OFLAG includes O_CREAT,
+    a third argument is the file protection.  */
+-- 
+1.2.4
+
+Subject: [PATCH] AVR32 Architecture support
+
+Add support for the AVR32 architecture in the core libc and build system.
+This also adds AVR32-ELF definitions to elf.h
+
+---
+
+ Rules.mak                                      |    4 
+ extra/Configs/Config.avr32                     |   38 +++++
+ extra/Configs/Config.in                        |    7 +
+ include/elf.h                                  |   51 +++++++
+ libc/sysdeps/linux/avr32/Makefile              |   93 +++++++++++++
+ libc/sysdeps/linux/avr32/__longjmp.S           |   17 ++
+ libc/sysdeps/linux/avr32/_mmap.c               |   33 ++++
+ libc/sysdeps/linux/avr32/bits/atomicity.h      |   86 ++++++++++++
+ libc/sysdeps/linux/avr32/bits/byteswap.h       |   80 +++++++++++
+ libc/sysdeps/linux/avr32/bits/endian.h         |    7 +
+ libc/sysdeps/linux/avr32/bits/fcntl.h          |  167 +++++++++++++++++++++++++
+ libc/sysdeps/linux/avr32/bits/kernel_stat.h    |   63 +++++++++
+ libc/sysdeps/linux/avr32/bits/kernel_types.h   |   56 ++++++++
+ libc/sysdeps/linux/avr32/bits/machine-gmon.h   |   69 ++++++++++
+ libc/sysdeps/linux/avr32/bits/mman.h           |   95 ++++++++++++++
+ libc/sysdeps/linux/avr32/bits/profil-counter.h |   26 +++
+ libc/sysdeps/linux/avr32/bits/setjmp.h         |   21 +++
+ libc/sysdeps/linux/avr32/bits/syscalls.h       |  143 +++++++++++++++++++++
+ libc/sysdeps/linux/avr32/bits/wordsize.h       |    1 
+ libc/sysdeps/linux/avr32/brk.c                 |   23 +++
+ libc/sysdeps/linux/avr32/bsd-_setjmp.S         |   12 +
+ libc/sysdeps/linux/avr32/bsd-setjmp.S          |   12 +
+ libc/sysdeps/linux/avr32/clone.c               |   37 +++++
+ libc/sysdeps/linux/avr32/crt1.S                |   93 +++++++++++++
+ libc/sysdeps/linux/avr32/crti.S                |   17 ++
+ libc/sysdeps/linux/avr32/crtn.S                |   14 ++
+ libc/sysdeps/linux/avr32/mmap.c                |   31 ++++
+ libc/sysdeps/linux/avr32/setjmp.S              |   43 ++++++
+ libc/sysdeps/linux/avr32/sigaction.c           |   49 +++++++
+ libc/sysdeps/linux/avr32/sigrestorer.S         |   11 +
+ libc/sysdeps/linux/avr32/sys/elf.h             |   26 +++
+ libc/sysdeps/linux/avr32/sys/io.h              |   48 +++++++
+ libc/sysdeps/linux/avr32/sys/procfs.h          |  123 ++++++++++++++++++
+ libc/sysdeps/linux/avr32/sys/ucontext.h        |   94 ++++++++++++++
+ libc/sysdeps/linux/avr32/sys/user.h            |   46 ++++++
+ libc/sysdeps/linux/avr32/syscall.S             |   81 ++++++++++++
+ libc/sysdeps/linux/avr32/vfork.S               |   55 ++++++++
+ 37 files changed, 1872 insertions(+)
+
+Index: uClibc-0.9.28/extra/Configs/Config.avr32
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/extra/Configs/Config.avr32   2006-05-05 09:27:17.000000000 +0200
+@@ -0,0 +1,38 @@
++#
++# For a description of the syntax of this configuration file,
++# see extra/config/Kconfig-language.txt
++#
++
++config HAVE_ELF
++      bool
++      default y
++
++config TARGET_ARCH
++      default "avr32"
++
++config ARCH_CFLAGS
++      string
++
++config ARCH_LDFLAGS
++      string
++
++config LIBGCC_CFLAGS
++      string
++
++config ARCH_SUPPORTS_BIG_ENDIAN
++      bool
++      default y
++
++config UCLIBC_COMPLETELY_PIC
++      select FORCE_SHAREABLE_TEXT_SEGMENTS
++      bool
++      default y
++
++choice
++      prompt "Target CPU Type"
++      default CONFIG_AP7000
++
++config CONFIG_AP7000
++      bool "AP7000"
++
++endchoice
+Index: uClibc-0.9.28/extra/Configs/Config.in
+===================================================================
+--- uClibc-0.9.28.orig/extra/Configs/Config.in 2006-04-19 12:47:48.000000000 +0200
++++ uClibc-0.9.28/extra/Configs/Config.in      2006-04-19 12:48:33.000000000 +0200
+@@ -16,6 +16,9 @@ config TARGET_alpha
+ config TARGET_arm
+       bool "arm"
++config TARGET_avr32
++      bool "avr32"
++
+ config TARGET_bfin
+       bool "bfin"
+@@ -83,6 +86,10 @@ if TARGET_arm
+ source "extra/Configs/Config.arm"
+ endif
++if TARGET_avr32
++source "extra/Configs/Config.avr32"
++endif
++
+ if TARGET_bfin
+ source "extra/Configs/Config.bfin"
+ endif
+Index: uClibc-0.9.28/include/elf.h
+===================================================================
+--- uClibc-0.9.28.orig/include/elf.h   2006-04-19 12:47:48.000000000 +0200
++++ uClibc-0.9.28/include/elf.h        2006-05-05 09:28:38.000000000 +0200
+@@ -261,6 +261,8 @@ typedef struct
+ #define EM_NIOS32     0xfebb          /* Altera Nios 32 */
+ #define EM_ALTERA_NIOS2  0x9ee5       /* Altera Nios II */
++#define EM_AVR32      0x18ad
++
+ /* V850 backend magic number.  Written in the absense of an ABI.  */
+ #define EM_CYGNUS_V850 0x9080
+@@ -2687,6 +2689,55 @@ typedef Elf32_Addr Elf32_Conflict;
+ /* Keep this the last entry.  */
+ #define R_V850_NUM            25
++/* Atmel AVR32 relocations.  */
++#define R_AVR32_NONE          0
++#define R_AVR32_32            1
++#define R_AVR32_16            2
++#define R_AVR32_8             3
++#define R_AVR32_32_PCREL      4
++#define R_AVR32_16_PCREL      5
++#define R_AVR32_8_PCREL               6
++#define R_AVR32_DIFF32                7
++#define R_AVR32_DIFF16                8
++#define R_AVR32_DIFF8         9
++#define R_AVR32_GOT32         10
++#define R_AVR32_GOT16         11
++#define R_AVR32_GOT8          12
++#define R_AVR32_21S           13
++#define R_AVR32_16U           14
++#define R_AVR32_16S           15
++#define R_AVR32_8S            16
++#define R_AVR32_8S_EXT                17
++#define R_AVR32_22H_PCREL     18
++#define R_AVR32_18W_PCREL     19
++#define R_AVR32_16B_PCREL     20
++#define R_AVR32_16N_PCREL     21
++#define R_AVR32_14UW_PCREL    22
++#define R_AVR32_11H_PCREL     23
++#define R_AVR32_10UW_PCREL    24
++#define R_AVR32_9H_PCREL      25
++#define R_AVR32_9UW_PCREL     26
++#define R_AVR32_HI16          27
++#define R_AVR32_LO16          28
++#define R_AVR32_GOTPC         29
++#define R_AVR32_GOTCALL               30
++#define R_AVR32_LDA_GOT               31
++#define R_AVR32_GOT21S                32
++#define R_AVR32_GOT18SW               33
++#define R_AVR32_GOT16S                34
++#define R_AVR32_GOT7UW                35
++#define R_AVR32_32_CPENT      36
++#define R_AVR32_CPCALL                37
++#define R_AVR32_16_CP         38
++#define R_AVR32_9W_CP         39
++#define R_AVR32_RELATIVE      40
++#define R_AVR32_GLOB_DAT      41
++#define R_AVR32_JMP_SLOT      42
++#define R_AVR32_ALIGN         43
++#define R_AVR32_NUM           44
++
++/* AVR32 dynamic tags */
++#define DT_AVR32_GOTSZ                0x70000001 /* Total size of GOT in bytes */
+ #define R_H8_NONE       0
+ #define R_H8_DIR32      1
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/Makefile
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/Makefile    2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,93 @@
++# Makefile for uClibc
++#
++# Copyright (C) 2000-2003 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
++
++TOPDIR=../../../../
++include $(TOPDIR)Rules.mak
++ASFLAGS=$(CFLAGS)
++
++CRT_SRC       = crt1.S
++CRT_OBJ = crt1.o
++SCRT_OBJ = $(patsubst %,S%, $(CRT_OBJ))
++CTOR_TARGETS=$(TOPDIR)lib/crti.o $(TOPDIR)lib/crtn.o
++
++SSRC=__longjmp.S setjmp.S bsd-setjmp.S vfork.S \
++      bsd-_setjmp.S sigrestorer.S syscall.S
++SOBJS=$(patsubst %.S,%.o, $(SSRC))
++
++CSRC=clone.c brk.c sigaction.c mmap.c
++COBJS=$(patsubst %.c,%.o, $(CSRC))
++
++OBJS=$(SOBJS) $(COBJS)
++
++OBJ_LIST=../../../obj.sysdeps.$(TARGET_ARCH)
++
++all: $(OBJ_LIST)
++
++$(OBJ_LIST): $(OBJS) $(CRT_OBJ) $(SCRT_OBJ) $(CTOR_TARGETS)
++      echo $(patsubst %, sysdeps/linux/$(TARGET_ARCH)/%, $(OBJS)) > $(OBJ_LIST)
++      $(INSTALL) -d $(TOPDIR)lib/
++      cp $(CRT_OBJ) $(SCRT_OBJ) $(TOPDIR)lib/
++
++$(CRT_OBJ): $(CRT_SRC)
++      $(CC) $(ASFLAGS) -DL_$* $< -c -o $*.o
++      $(STRIPTOOL) -x -R .note -R .comment $*.o
++
++$(SCRT_OBJ): $(CRT_SRC)
++      $(CC) $(ASFLAGS) $(PIEFLAG) -DL_$* $< -c -o $*.o
++      $(STRIPTOOL) -x -R .note -R .comment $*.o
++
++$(SOBJS): %.o : %.S
++      $(CC) $(ASFLAGS) -c $< -o $@
++      $(STRIPTOOL) -x -R .note -R .comment $*.o
++
++$(COBJS): %.o : %.c
++      $(CC) $(CFLAGS) -c $< -o $@
++      $(STRIPTOOL) -x -R .note -R .comment $*.o
++
++ifeq ($(strip $(UCLIBC_CTOR_DTOR)),y)
++crti.o: crti.S
++      $(CC) $(ASFLAGS) -c crti.S -o crti.o
++
++$(TOPDIR)lib/crti.o: crti.o
++      $(INSTALL) -d $(TOPDIR)lib/
++      cp crti.o $(TOPDIR)lib/
++
++crtn.o: crtn.S
++      $(CC) $(ASFLAGS) -c crtn.S -o crtn.o
++
++$(TOPDIR)lib/crtn.o: crtn.o
++      $(INSTALL) -d $(TOPDIR)lib/
++      cp crtn.o $(TOPDIR)lib/
++else
++$(TOPDIR)lib/crti.o:
++      $(INSTALL) -d $(TOPDIR)lib/
++      $(AR) $(ARFLAGS) $(TOPDIR)lib/crti.o
++$(TOPDIR)lib/crtn.o:
++      $(INSTALL) -d $(TOPDIR)lib/
++      $(AR) $(ARFLAGS) $(TOPDIR)lib/crtn.o
++endif
++
++
++headers:
++#     $(LN) -fs ../libc/sysdeps/linux/avr32/fpu_control.h $(TOPDIR)/include/
++
++clean:
++      $(RM) *.[oa] *~ core
++      $(RM) bits/sysnum.h
++      $(RM) gmon-start.S
++
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/__longjmp.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/__longjmp.S 2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,17 @@
++/* longjmp for AVR32
++ *
++ * Copyright (C) 2004 Atmel Norway AS
++ */
++
++      .global __longjmp
++      .type   __longjmp,"function"
++      .align  1
++__longjmp:
++      ldm     r12++, r0,r1,r2,r3,r4,r5,r6,r7,r8,sp,lr
++      mov     r12, r11        /* get the return value right */
++      mustr   r8              /* restore status register (lower half) */
++      cp      r12, 0          /* can't return zero */
++      frs
++      moveq   r12, 1
++      mov     pc,lr
++      .size   __longjmp, . - __longjmp
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/_mmap.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/_mmap.c     2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,33 @@
++/* Copyright (C) 2005 Atmel Norway
++
++   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
++
++   Derived in part from the Linux-8086 C library, the GNU C Library, and several
++   other sundry sources.  Files within this library are copyright by their
++   respective copyright holders.
++ */
++
++#include <errno.h>
++#include <sys/mman.h>
++#include <sys/syscall.h>
++
++#define __NR_mmap2 __NR_mmap
++
++static _syscall6(__ptr_t, mmap2, __ptr_t, addr, size_t, len, int, prot, int, flags, int, fd, __off_t, pgoff);
++
++__ptr_t mmap(__ptr_t addr, size_t len, int prot, int flags, int fd, __off_t offset)
++{
++      return mmap2(addr, len, prot, flags, fd, offset >> 12);
++}
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/atomicity.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/atomicity.h    2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,86 @@
++/* Low-level functions for atomic operations.  AVR32 version.
++   Copyright (C) 1997, 1998, 1999, 2000 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.  */
++
++#ifndef _ATOMICITY_H
++#define _ATOMICITY_H 1
++
++#include <inttypes.h>
++
++static inline int
++__attribute__((unused))
++exchange_and_add (volatile uint32_t *mem, int val)
++{
++      int tmp, result;
++
++      __asm__ __volatile__(
++              "/* Inline exchange and add */\n"
++              "1:     ssrf    5\n"
++              "       ld.w    %0, %3\n"
++              "       add     %1, %0, %4\n"
++              "       stcond  %2, %1\n"
++              "       brne    1b"
++              : "=&r"(result), "=&r"(tmp), "=m"(*mem)
++              : "m"(*mem), "r"(val)
++              : "cc", "memory");
++
++      return result;
++}
++
++static inline void
++__attribute__((unused))
++atomic_add (volatile uin32_t *mem, int val)
++{
++      int result;
++
++      __asm__ __volatile__(
++              "/* Inline atomic add */\n"
++              "1:     ssrf    5\n"
++              "       ld.w    %0, %2\n"
++              "       add     %0, %3\n"
++              "       stcond  %2, %0\n"
++              "       brne    1b"
++              : "=&r"(result), "=m"(*mem)
++              : "m"(*mem), "r"(val)
++              : "cc", "memory");
++}
++
++static inline int
++__attribute__((unused))
++compare_and_swap(volatile long int *p, long int oldval, long int newval)
++{
++      long int result, tmp;
++
++      __asm__ __volatile__(
++              "/* Inline compare and swap */\n"
++              "1:     ssrf    5\n"
++              "       ld.w    %1, %3\n"
++              "       cp.w    %1, %5\n"
++              "       sreq    %0\n"
++              "       brne    2f\n"
++              "       stcond  %2, %4\n"
++              "       brne    1b\n"
++              "2:"
++              : "=&r"(result), "=&r"(tmp), "=m"(*p)
++              : "m"(*p), "r"(newval), "r"(oldval)
++              : "cc", "memory");
++
++      return result;
++}
++
++#endif /* atomicity.h */
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/byteswap.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/byteswap.h     2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,80 @@
++/* Macros to swap the order of bytes in integer values.
++   Copyright (C) 2005 Atmel Norway.
++
++   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.  */
++
++#if !defined _BYTESWAP_H && !defined _NETINET_IN_H
++# error "Never use <bits/byteswap.h> directly; include <byteswap.h> instead."
++#endif
++
++#ifndef _BITS_BYTESWAP_H
++#define _BITS_BYTESWAP_H 1
++
++/* Swap bytes in 16 bit value.  */
++#if defined __GNUC__
++# define __bswap_16(x) (__extension__ __builtin_bswap_16(x))
++#else
++/* This is better than nothing.  */
++static __inline unsigned short int
++__bswap_16 (unsigned short int __bsx)
++{
++      return ((((__bsx) >> 8) & 0xff) | (((__bsx) & 0xff) << 8));
++}
++#endif
++
++/* Swap bytes in 32 bit value.  */
++#if defined __GNUC__
++# define __bswap_32(x) (__extension__ __builtin_bswap_32(x))
++#else
++static __inline unsigned int
++__bswap_32 (unsigned int __bsx)
++{
++  return ((((__bsx) & 0xff000000) >> 24) | (((__bsx) & 0x00ff0000) >>  8) |
++        (((__bsx) & 0x0000ff00) <<  8) | (((__bsx) & 0x000000ff) << 24));
++}
++#endif
++
++#if defined __GNUC__
++/* Swap bytes in 64 bit value.  */
++# define __bswap_constant_64(x)                               \
++      ((((x) & 0xff00000000000000ull) >> 56)          \
++       | (((x) & 0x00ff000000000000ull) >> 40)        \
++       | (((x) & 0x0000ff0000000000ull) >> 24)        \
++       | (((x) & 0x000000ff00000000ull) >> 8)         \
++       | (((x) & 0x00000000ff000000ull) << 8)         \
++       | (((x) & 0x0000000000ff0000ull) << 24)        \
++       | (((x) & 0x000000000000ff00ull) << 40)        \
++       | (((x) & 0x00000000000000ffull) << 56))
++
++# define __bswap_64(x)                                                        \
++      (__extension__                                                  \
++       ({                                                             \
++               union {                                                \
++                       __extension__ unsigned long long int __ll;     \
++                       unsigned int __l[2];                           \
++               } __w, __r;                                            \
++               if (__builtin_constant_p(x))                           \
++                       __r.__ll = __bswap_constant_64(x);             \
++               else {                                                 \
++                       __w.__ll = (x);                                \
++                       __r.__l[0] = __bswap_32(__w.__l[1]);           \
++                       __r.__l[1] = __bswap_32(__w.__l[0]);           \
++               }                                                      \
++               __r.__ll;                                              \
++       }))
++#endif
++
++#endif /* _BITS_BYTESWAP_H */
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/endian.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/endian.h       2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,7 @@
++/* AVR32 is big-endian */
++
++#ifndef _ENDIAN_H
++# error "Never use <bits/endian.h> directly; include <endian.h> instead."
++#endif
++
++#define __BYTE_ORDER __BIG_ENDIAN
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/fcntl.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/fcntl.h        2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,167 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ *
++ * This file is part of the Linux kernel
++ */
++#ifndef _FCNTL_H
++# error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead."
++#endif
++
++#include <sys/types.h>
++
++/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
++   located on an ext2 file system */
++#define O_ACCMODE       0003
++#define O_RDONLY          00
++#define O_WRONLY          01
++#define O_RDWR                    02
++#define O_CREAT                 0100  /* not fcntl */
++#define O_EXCL                  0200  /* not fcntl */
++#define O_NOCTTY        0400  /* not fcntl */
++#define O_TRUNC                01000  /* not fcntl */
++#define O_APPEND       02000
++#define O_NONBLOCK     04000
++#define O_NDELAY      O_NONBLOCK
++#define O_SYNC                010000
++#define O_ASYNC               020000
++
++#ifdef __USE_GNU
++# define O_DIRECTORY  040000  /* must be a directory */
++# define O_NOFOLLOW   0100000 /* don't follow links */
++# define O_DIRECT     0200000 /* direct disk access */
++#endif
++
++#ifdef __USE_LARGEFILE64
++# define O_LARGEFILE  0400000
++#endif
++
++/* For now Linux has synchronisity options for data and read operations.
++   We define the symbols here but let them do the same as O_SYNC since
++   this is a superset.        */
++#if defined __USE_POSIX199309 || defined __USE_UNIX98
++# define O_DSYNC      O_SYNC  /* Synchronize data.  */
++# define O_RSYNC      O_SYNC  /* Synchronize read operations.  */
++#endif
++
++#define F_DUPFD               0       /* dup */
++#define F_GETFD               1       /* get close_on_exec */
++#define F_SETFD               2       /* set/clear close_on_exec */
++#define F_GETFL               3       /* get file->f_flags */
++#define F_SETFL               4       /* set file->f_flags */
++
++#ifndef __USE_FILE_OFFSET64
++# define F_GETLK      5
++# define F_SETLK      6
++# define F_SETLKW     7
++#else
++# define F_GETLK      F_GETLK64
++# define F_SETLK      F_SETLK64
++# define F_SETLKW     F_SETLKW64
++#endif
++#define F_GETLK64     12      /*  using 'struct flock64' */
++#define F_SETLK64     13
++#define F_SETLKW64    14
++
++#if defined __USE_BSD || defined __USE_XOPEN2K
++# define F_SETOWN     8       /*  for sockets. */
++# define F_GETOWN     9       /*  for sockets. */
++#endif
++
++#ifdef __USE_GNU
++# define F_SETSIG     10      /*  for sockets. */
++# define F_GETSIG     11      /*  for sockets. */
++#endif
++
++#ifdef __USE_GNU
++# define F_SETLEASE   1024    /* Set a lease.  */
++# define F_GETLEASE   1025    /* Enquire what lease is active.  */
++# define F_NOTIFY     1026    /* Request notfications on a directory.  */
++#endif
++
++/* for F_[GET|SET]FL */
++#define FD_CLOEXEC    1       /* actually anything with low bit set goes */
++
++/* for posix fcntl() and lockf() */
++#define F_RDLCK               0
++#define F_WRLCK               1
++#define F_UNLCK               2
++
++/* for old implementation of bsd flock () */
++#define F_EXLCK               4       /* or 3 */
++#define F_SHLCK               8       /* or 4 */
++
++/* for leases */
++#define F_INPROGRESS  16
++
++#ifdef __USE_BSD
++/* operations for bsd flock(), also used by the kernel implementation */
++# define LOCK_SH      1       /* shared lock */
++# define LOCK_EX      2       /* exclusive lock */
++# define LOCK_NB      4       /* or'd with one of the above to prevent
++                                 blocking */
++# define LOCK_UN      8       /* remove lock */
++#endif
++
++#ifdef __USE_GNU
++# define LOCK_MAND    32      /* This is a mandatory flock */
++# define LOCK_READ    64      /* ... Which allows concurrent
++                                     read operations */
++# define LOCK_WRITE   128     /* ... Which allows concurrent
++                                     write operations */
++# define LOCK_RW      192     /* ... Which allows concurrent
++                                     read & write ops */
++#endif
++
++#ifdef __USE_GNU
++/* Types of directory notifications that may be requested with F_NOTIFY.  */
++# define DN_ACCESS    0x00000001      /* File accessed.  */
++# define DN_MODIFY    0x00000002      /* File modified.  */
++# define DN_CREATE    0x00000004      /* File created.  */
++# define DN_DELETE    0x00000008      /* File removed.  */
++# define DN_RENAME    0x00000010      /* File renamed.  */
++# define DN_ATTRIB    0x00000020      /* File changed attibutes.  */
++# define DN_MULTISHOT 0x80000000      /* Don't remove notifier.  */
++#endif
++
++struct flock {
++      short l_type;
++      short l_whence;
++#ifndef __USE_FILE_OFFSET64
++      __off_t l_start;
++      __off_t l_len;
++#else
++      __off64_t l_start;
++      __off64_t l_len;
++#endif
++      __pid_t l_pid;
++};
++
++#ifdef __USE_LARGEFILE64
++struct flock64 {
++      short  l_type;
++      short  l_whence;
++      __off64_t l_start;
++      __off64_t l_len;
++      __pid_t  l_pid;
++};
++#endif
++
++/* Define some more compatibility macros to be backward compatible with
++ *    BSD systems which did not managed to hide these kernel macros.  */
++#ifdef  __USE_BSD
++# define FAPPEND        O_APPEND
++# define FFSYNC         O_FSYNC
++# define FASYNC         O_ASYNC
++# define FNONBLOCK      O_NONBLOCK
++# define FNDELAY        O_NDELAY
++#endif /* Use BSD.  */
++
++/* Advise to `posix_fadvise'.  */
++#ifdef __USE_XOPEN2K
++# define POSIX_FADV_NORMAL      0 /* No further special treatment.  */
++# define POSIX_FADV_RANDOM      1 /* Expect random page references.  */
++# define POSIX_FADV_SEQUENTIAL  2 /* Expect sequential page references.  */
++# define POSIX_FADV_WILLNEED    3 /* Will need these pages.  */
++# define POSIX_FADV_DONTNEED    4 /* Don't need these pages.  */
++# define POSIX_FADV_NOREUSE     5 /* Data will be accessed once.  */
++#endif
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/kernel_stat.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/kernel_stat.h  2006-05-05 09:28:32.000000000 +0200
+@@ -0,0 +1,63 @@
++#ifndef _BITS_STAT_STRUCT_H
++#define _BITS_STAT_STRUCT_H
++
++/*
++ * This file provides struct stat, taken from kernel 2.6.4
++ * (include/asm-avr32/stat.h revision 1.1).
++ */
++
++struct kernel_stat {
++        unsigned long st_dev;
++        unsigned long st_ino;
++        unsigned short st_mode;
++        unsigned short st_nlink;
++        unsigned short st_uid;
++        unsigned short st_gid;
++        unsigned long  st_rdev;
++        unsigned long  st_size;
++        unsigned long  st_blksize;
++        unsigned long  st_blocks;
++        unsigned long  st_atime;
++        unsigned long  st_atime_nsec;
++        unsigned long  st_mtime;
++        unsigned long  st_mtime_nsec;
++        unsigned long  st_ctime;
++        unsigned long  st_ctime_nsec;
++        unsigned long  __unused4;
++        unsigned long  __unused5;
++};
++
++#define STAT_HAVE_NSEC 1
++
++struct kernel_stat64 {
++      unsigned long long st_dev;
++
++      unsigned long long st_ino;
++      unsigned int    st_mode;
++      unsigned int    st_nlink;
++
++      unsigned long   st_uid;
++      unsigned long   st_gid;
++
++      unsigned long long st_rdev;
++
++      long long       st_size;
++      unsigned long   __pad1;
++      unsigned long   st_blksize;
++
++      unsigned long long st_blocks;
++
++      unsigned long   st_atime;
++      unsigned long   st_atime_nsec;
++
++      unsigned long   st_mtime;
++      unsigned long   st_mtime_nsec;
++
++      unsigned long   st_ctime;
++      unsigned long   st_ctime_nsec;
++
++      unsigned long   __unused1;
++      unsigned long   __unused2;
++};
++
++#endif /* _BITS_STAT_STRUCT_H */
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/kernel_types.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/kernel_types.h 2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,56 @@
++/* Note that we use the exact same include guard #define names
++ * as asm/posix_types.h.  This will avoid gratuitous conflicts
++ * with the posix_types.h kernel header, and will ensure that
++ * our private content, and not the kernel header, will win.
++ *  -Erik
++ */
++#ifndef __ASM_AVR32_POSIX_TYPES_H
++#define __ASM_AVR32_POSIX_TYPES_H
++
++/*
++ * This file is generally used by user-level software, so you need to
++ * be a little careful about namespace pollution etc.  Also, we cannot
++ * assume GCC is being used.
++ */
++
++typedef unsigned long __kernel_dev_t;
++typedef unsigned long   __kernel_ino_t;
++typedef unsigned short  __kernel_mode_t;
++typedef unsigned short  __kernel_nlink_t;
++typedef long            __kernel_off_t;
++typedef int             __kernel_pid_t;
++typedef unsigned short  __kernel_ipc_pid_t;
++typedef unsigned int  __kernel_uid_t;
++typedef unsigned int  __kernel_gid_t;
++typedef unsigned long __kernel_size_t;
++typedef int             __kernel_ssize_t;
++typedef int             __kernel_ptrdiff_t;
++typedef long            __kernel_time_t;
++typedef long            __kernel_suseconds_t;
++typedef long            __kernel_clock_t;
++typedef int             __kernel_timer_t;
++typedef int             __kernel_clockid_t;
++typedef int             __kernel_daddr_t;
++typedef char *          __kernel_caddr_t;
++typedef unsigned short  __kernel_uid16_t;
++typedef unsigned short  __kernel_gid16_t;
++typedef unsigned int    __kernel_uid32_t;
++typedef unsigned int    __kernel_gid32_t;
++
++typedef unsigned short  __kernel_old_uid_t;
++typedef unsigned short  __kernel_old_gid_t;
++typedef unsigned short  __kernel_old_dev_t;
++
++#ifdef __GNUC__
++typedef long long       __kernel_loff_t;
++#endif
++
++typedef struct {
++#if defined(__USE_ALL)
++    int     val[2];
++#else
++    int     __val[2];
++#endif
++} __kernel_fsid_t;
++
++#endif /* __ASM_AVR32_POSIX_TYPES_H */
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/machine-gmon.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/machine-gmon.h 2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,69 @@
++/* Machine-dependent definitions for profiling support.  AVR32 version.
++   Copyright (C) 1996, 1997, 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 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.  */
++
++#define mcount_internal __mcount_internal
++
++#define _MCOUNT_DECL(frompc, selfpc) \
++static void __attribute((used)) mcount_internal(unsigned long frompc, unsigned long selfpc)
++
++/*
++ * This mcount implementation expects to get called after the prologue
++ * has been run. It also expects that r7 contains a valid frame
++ * pointer.
++ *
++ * When profiling, the compiler should generate something like this at
++ * each function entry:
++ *
++ *    pushm   r0-r7,lr        // lr mandatory, others optional
++ *    mov     r7, sp
++ *    // rest of prologue goes here
++ *    mcall   pc[.LC1 - .]
++ *      // rest of function goes here
++ * .LC1:
++ *    .long   mcount
++ *
++ * or for PIC:
++ *
++ *    pushm   r0-r7,lr
++ *    mov     r7, sp
++ *    // rest of prologue goes here
++ *    lddpc   r0, .LC1
++ * .L1: rsub  r0, pc
++ *    mcall   r0[mcount@GOT]
++ *    // rest of function goes here
++ * .LC1:
++ *    .long   .L1 - _GLOBAL_OFFSET_TABLE_
++ *
++ * This way, when mcount() is called, r7 points to the calling
++ * function's return address. It is guaranteed that calling mcount
++ * will clobber no registers except LR, which is unavoidable.
++ */
++#define MCOUNT asm(                           \
++      "       .align  4\n"                    \
++      "       .global _mcount\n"              \
++      "       .type   _mcount,@function\n"    \
++      "_mcount:\n"                            \
++      "       pushm   r8-r12,lr\n"            \
++      "       mov     r11, lr\n"              \
++      "       ld.w    r12, r7[0]\n"           \
++      "       rcall   __mcount_internal\n"    \
++      "       popm    r8-r12,pc\n"            \
++      "       .size   _mcount, . - _mcount\n" \
++      "       .weak   mcount\n"               \
++      "       mcount = _mcount");
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/mman.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/mman.h 2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,95 @@
++/* Definitions for POSIX memory map interface.  Linux/AVR32 version.
++   Copyright (C) 1997, 2000 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.  */
++
++#ifndef _SYS_MMAN_H
++# error "Never include this file directly.  Use <sys/mman.h> instead"
++#endif
++
++/* The following definitions basically come from the kernel headers.
++   But the kernel header is not namespace clean.  */
++
++
++/* Protections are chosen from these bits, OR'd together.  The
++   implementation does not necessarily support PROT_EXEC or PROT_WRITE
++   without PROT_READ.  The only guarantees are that no writing will be
++   allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */
++
++#define PROT_READ     0x1             /* Page can be read.  */
++#define PROT_WRITE    0x2             /* Page can be written.  */
++#define PROT_EXEC     0x4             /* Page can be executed.  */
++#define PROT_NONE     0x0             /* Page can not be accessed.  */
++
++/* Sharing types (must choose one and only one of these).  */
++#define MAP_SHARED    0x01            /* Share changes.  */
++#define MAP_PRIVATE   0x02            /* Changes are private.  */
++#ifdef __USE_MISC
++# define MAP_TYPE     0x0f            /* Mask for type of mapping.  */
++#endif
++
++/* Other flags.  */
++#define MAP_FIXED     0x10            /* Interpret addr exactly.  */
++#ifdef __USE_MISC
++# define MAP_FILE     0
++# define MAP_ANONYMOUS        0x20            /* Don't use a file.  */
++# define MAP_ANON     MAP_ANONYMOUS
++#endif
++
++/* These are Linux-specific.  */
++#ifdef __USE_MISC
++# define MAP_GROWSDOWN        0x0100          /* Stack-like segment.  */
++# define MAP_DENYWRITE        0x0800          /* ETXTBSY */
++# define MAP_EXECUTABLE       0x1000          /* Mark it as an executable.  */
++# define MAP_LOCKED   0x2000          /* Lock the mapping.  */
++# define MAP_NORESERVE        0x4000          /* Don't check for reservations.  */
++# define MAP_POPULATE 0x8000          /* populate (prefault) pagetables */
++# define MAP_NONBLOCK 0x10000         /* do not block on IO */
++#endif
++
++/* Flags to `msync'.  */
++#define MS_ASYNC      1               /* Sync memory asynchronously.  */
++#define MS_SYNC               4               /* Synchronous memory sync.  */
++#define MS_INVALIDATE 2               /* Invalidate the caches.  */
++
++/* Flags for `mlockall'.  */
++#define MCL_CURRENT   1               /* Lock all currently mapped pages.  */
++#define MCL_FUTURE    2               /* Lock all additions to address
++                                         space.  */
++
++/* Flags for `mremap'.  */
++#ifdef __USE_GNU
++# define MREMAP_MAYMOVE       1
++#endif
++
++/* Advise to `madvise'.  */
++#ifdef __USE_BSD
++# define MADV_NORMAL   0      /* No further special treatment.  */
++# define MADV_RANDOM   1      /* Expect random page references.  */
++# define MADV_SEQUENTIAL 2    /* Expect sequential page references.  */
++# define MADV_WILLNEED         3      /* Will need these pages.  */
++# define MADV_DONTNEED         4      /* Don't need these pages.  */
++#endif
++
++/* The POSIX people had to invent similar names for the same things.  */
++#ifdef __USE_XOPEN2K
++# define POSIX_MADV_NORMAL    0 /* No further special treatment.  */
++# define POSIX_MADV_RANDOM    1 /* Expect random page references.  */
++# define POSIX_MADV_SEQUENTIAL        2 /* Expect sequential page references.  */
++# define POSIX_MADV_WILLNEED  3 /* Will need these pages.  */
++# define POSIX_MADV_DONTNEED  4 /* Don't need these pages.  */
++#endif
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/profil-counter.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/profil-counter.h       2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,26 @@
++/* Low-level statistical profiling support function.  Linux/AVR32 version.
++   Copyright (C) 1996, 1997, 1998, 2002 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 <signal.h>
++
++void
++profil_counter(int signo, siginfo_t *si, struct sigcontext *sc)
++{
++      profil_count((void *)sc->pc);
++}
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/setjmp.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/setjmp.h       2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,21 @@
++/*
++ * Copyright (C) 2004-2005 Atmel Norway
++ */
++#ifndef _SETJMP_H
++# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
++#endif
++
++#ifndef _ASM
++/*
++ * The jump buffer contains r0-r7, sr, sp and lr. Other registers are
++ * not saved.
++ */
++typedef int __jmp_buf[11];
++#endif
++
++#define __JMP_BUF_SP  4
++
++/* Test if longjmp to JMPBUF would unwind the frame containing a local
++   variable at ADDRESS.  */
++#define _JMPBUF_UNWINDS(jmpbuf, address) \
++  ((void *)(address) < (void *)(jmpbuf[__JMP_BUF_SP]))
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/syscalls.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/syscalls.h     2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,143 @@
++#ifndef _SYSCALL_H
++# error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead."
++#endif
++
++/*
++ * This includes the `__NR_<name>' syscall numbers taken from the
++ * Linux kernel header files. It also defines the traditional
++ * `SYS_<name>' macros for older programs.
++ */
++#include <bits/sysnum.h>
++
++#ifndef __set_errno
++# define __set_errno(val) (*__errno_location()) = (val)
++#endif
++#ifndef SYS_ify
++# define SYS_ify(syscall_name) (__NR_##syscall_name)
++#endif
++
++#ifndef __ASSEMBLER__
++
++#undef _syscall0
++#define _syscall0(type,name)                          \
++      type name(void)                                 \
++      {                                               \
++              return (type)(INLINE_SYSCALL(name, 0)); \
++      }
++
++#undef _syscall1
++#define _syscall1(type,name,type1,arg1)                               \
++      type name(type1 arg1)                                   \
++      {                                                       \
++              return (type)(INLINE_SYSCALL(name, 1, arg1));   \
++      }
++
++#undef _syscall2
++#define _syscall2(type,name,type1,arg1,type2,arg2)                    \
++      type name(type1 arg1, type2 arg2)                               \
++      {                                                               \
++              return (type)(INLINE_SYSCALL(name, 2, arg1, arg2));     \
++      }
++
++#undef _syscall3
++#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)         \
++      type name(type1 arg1, type2 arg2, type3 arg3)                   \
++      {                                                               \
++              return (type)(INLINE_SYSCALL(name, 3, arg1,             \
++                                           arg2, arg3));              \
++      }
++
++#undef _syscall4
++#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,         \
++                type4,arg4)                                           \
++      type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4)       \
++      {                                                               \
++              return (type)(INLINE_SYSCALL(name, 4, arg1, arg2,       \
++                                           arg3, arg4));              \
++      }
++
++#undef _syscall5
++#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,         \
++                type4,arg4,type5,arg5)                                \
++      type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4,       \
++                type5 arg5)                                           \
++      {                                                               \
++              return (type)(INLINE_SYSCALL(name, 5, arg1, arg2,       \
++                                           arg3, arg4, arg5));        \
++      }
++
++#undef _syscall6
++#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,         \
++                type4,arg4,type5,arg5,type6,arg6)                     \
++      type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4,       \
++                type5 arg5, type6 arg6)                               \
++      {                                                               \
++              return (type)(INLINE_SYSCALL(name, 6, arg1, arg2, arg3, \
++                                           arg4, arg5, arg6));        \
++      }
++
++#undef unlikely
++#define unlikely(x) __builtin_expect((x), 0)
++
++#undef INLINE_SYSCALL
++#define INLINE_SYSCALL(name, nr, args...)                             \
++      ({                                                              \
++              unsigned _sys_result = INTERNAL_SYSCALL(name, , nr, args); \
++              if (unlikely(INTERNAL_SYSCALL_ERROR_P(_sys_result, ))) { \
++                      __set_errno(INTERNAL_SYSCALL_ERRNO(_sys_result, )); \
++                      _sys_result = (unsigned int) -1;                \
++              }                                                       \
++              (int) _sys_result;                                      \
++      })
++
++#undef INTERNAL_SYSCALL_DECL
++#define INTERNAL_SYSCALL_DECL(err) do { } while(0)
++
++#undef INTERNAL_SYSCALL
++#define INTERNAL_SYSCALL(name, err, nr, args...)                      \
++      ({                                                              \
++              register int _a1 asm ("r12");                           \
++              register int _scno asm("r8") = SYS_ify(name);           \
++              LOAD_ARGS_##nr (args);                                  \
++              asm volatile ("scall    /* syscall " #name " */"        \
++                            : "=r" (_a1)                              \
++                            : "r"(_scno) ASM_ARGS_##nr                \
++                            : "lr", "cc", "memory");                  \
++              _a1;                                                    \
++      })
++
++#undef INTERNAL_SYSCALL_ERROR_P
++#define INTERNAL_SYSCALL_ERROR_P(val, err)            \
++      ((unsigned int)(val) >= 0xfffff001U)
++
++#undef INTERNAL_SYSCALL_ERRNO
++#define INTERNAL_SYSCALL_ERRNO(val, errr) (-(val))
++
++#define LOAD_ARGS_0() do { } while(0)
++#define ASM_ARGS_0
++#define LOAD_ARGS_1(a1)                                       \
++      _a1 = (int) (a1);                               \
++      LOAD_ARGS_0()
++#define ASM_ARGS_1    ASM_ARGS_0, "r"(_a1)
++#define LOAD_ARGS_2(a1, a2)                           \
++      register int _a2 asm("r11") = (int)(a2);        \
++      LOAD_ARGS_1(a1)
++#define ASM_ARGS_2    ASM_ARGS_1, "r"(_a2)
++#define LOAD_ARGS_3(a1, a2, a3)                               \
++      register int _a3 asm("r10") = (int)(a3);        \
++      LOAD_ARGS_2(a1, a2)
++#define ASM_ARGS_3    ASM_ARGS_2, "r"(_a3)
++#define LOAD_ARGS_4(a1, a2, a3, a4)                   \
++      register int _a4 asm("r9") = (int)(a4);         \
++      LOAD_ARGS_3(a1, a2, a3)
++#define ASM_ARGS_4    ASM_ARGS_3, "r"(_a4)
++#define LOAD_ARGS_5(a1, a2, a3, a4, a5)                       \
++      register int _a5 asm("r5") = (int)(a5);         \
++      LOAD_ARGS_4(a1, a2, a3, a4)
++#define ASM_ARGS_5    ASM_ARGS_4, "r"(_a5)
++#define LOAD_ARGS_6(a1, a2, a3, a4, a5, a6)           \
++      register int _a6 asm("r3") = (int)(a6);         \
++      LOAD_ARGS_5(a1, a2, a3, a4, a5)
++#define ASM_ARGS_6    ASM_ARGS_5, "r"(_a6)
++
++#endif /* __ASSEMBLER__ */
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/wordsize.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/wordsize.h     2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1 @@
++#define __WORDSIZE    32
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/brk.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/brk.c       2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,23 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ */
++#include <errno.h>
++#include <sys/syscall.h>
++
++void *__curbrk = 0;
++
++int brk (void *addr)
++{
++      void *newbrk;
++
++      newbrk = INLINE_SYSCALL(brk, 1, addr);
++
++      __curbrk = newbrk;
++
++      if (newbrk < addr) {
++              __set_errno (ENOMEM);
++              return -1;
++      }
++
++      return 0;
++}
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bsd-_setjmp.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bsd-_setjmp.S       2006-05-05 09:26:42.000000000 +0200
+@@ -0,0 +1,12 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ */
++
++      /* This just does a tail-call to __sigsetjmp(env, 0) */
++      .global _setjmp
++      .type   _setjmp,"function"
++      .align  1
++_setjmp:
++      mov     r11, 0
++      bral    __sigsetjmp_internal
++      .size   _setjmp, . - _setjmp
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bsd-setjmp.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bsd-setjmp.S        2006-05-05 09:26:42.000000000 +0200
+@@ -0,0 +1,12 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ */
++
++      /* This just does a tail-call to __sigsetjmp(env, 1) */
++      .global setjmp
++      .type   setjmp,"function"
++      .align  1
++setjmp:
++      mov     r11, 1
++      bral    __sigsetjmp_internal
++      .size   setjmp, . - setjmp
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/clone.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/clone.c     2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,37 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ */
++#include <errno.h>
++#include <sys/syscall.h>
++#include <unistd.h>
++
++/*
++ * I don't know if we can be absolutely certain that the fn and arg
++ * parameters are preserved when returning as the child. If the
++ * compiler stores them in registers (r0-r7), they should be.
++ */
++int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg)
++{
++      register int (*_fn)(void *arg) = fn;
++      register void *_arg = arg;
++      int err;
++
++      /* Sanity check the arguments */
++      err = -EINVAL;
++      if (!fn)
++              goto syscall_error;
++      if (!child_stack)
++              goto syscall_error;
++
++      err = INLINE_SYSCALL(clone, 2, flags, child_stack);
++      if (err < 0)
++              goto syscall_error;
++      else if (err != 0)
++              return err;
++
++      _exit(_fn(_arg));
++
++syscall_error:
++      __set_errno (-err);
++      return -1;
++}
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/crt1.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/crt1.S      2006-05-05 09:28:23.000000000 +0200
+@@ -0,0 +1,93 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ *
++ * When we enter _start, the stack looks like this:
++ *    argc            argument counter
++ *    argv[0]         pointer to program name
++ *    argv[1..argc-1] pointers to program args
++ *    NULL
++ *    env[0..N]       pointers to environment variables
++ *    NULL
++ *
++ * r12 contains a function pointer to be registered with `atexit'.
++ * This is how the dynamic linker arranges to have DT_FINI functions
++ * called for shared libraries that have been loaded before this
++ * code runs.
++ *
++ * We're going to call the following function:
++ * __uClibc_main(int (*main)(int, char **, char **), int argc,
++ *             char **argv, void (*app_init)(void), void (*app_fini)(void),
++ *             void (*rtld_fini)(void), void *stack_end)
++ *
++ * So we need to set up things as follows:
++ *    r12 = address of main
++ *    r11 = argc
++ *    r10 = &argv[0]
++ *    r9  = address of _init
++ *    r8  = address of _fini
++ *    sp[0] = whatever we got passed in r12
++ */
++
++#include <features.h>
++
++      .text
++      .global _start
++      .type   _start, @function
++_start:
++      /* Clear the frame pointer and link register since this is the outermost frame.  */
++      mov     r7, 0
++      mov     lr, 0
++
++      ld.w    r11, sp++               /* argc         */
++      mov     r10, sp                 /* &argv[0]     */
++
++      st.w    --sp, r10               /* stack_end */
++      st.w    --sp, r12               /* rtld_fini */
++
++#ifdef __PIC__
++      lddpc   r6, .L_GOT
++.L_RGOT:
++      rsub    r6, pc
++      lda.w   r9, _init
++      lda.w   r8, _fini
++      lda.w   r12, main
++
++      /* Ok, now run uClibc's main() -- should not return */
++      call    __uClibc_main
++
++      .align  2
++.L_GOT:
++      .long   .L_RGOT - _GLOBAL_OFFSET_TABLE_
++#else
++      lddpc   r9, __init_addr         /* app_init */
++      lddpc   r8, __fini_addr         /* app_fini */
++      lddpc   r12, __main_addr        /* main */
++
++      /* Ok, now run uClibc's main() -- should not return */
++      lddpc   pc, ___uClibc_main_addr
++
++      .align  2
++__init_addr:
++      .long   _init
++__fini_addr:
++      .long   _fini
++__main_addr:
++      .long   main
++___uClibc_main_addr:
++      .long   __uClibc_main
++#endif
++      .size   _start, . - _start
++
++      /*
++       * The LSB says we need this.
++       */
++      .section ".note.ABI-tag", "a"
++      .align  4
++      .long   2f - 1f         /* namesz */
++      .long   4f - 3f         /* descsz */
++      .long   1               /* type   */
++1:    .asciz  "GNU"           /* name */
++2:    .align  4
++3:    .long   0               /* Linux executable */
++      .long   2,6,0           /* Earliest compatible kernel */
++4:    .align  4
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/crti.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/crti.S      2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,17 @@
++
++      .section .init
++      .align  2
++      .global _init
++      .type   _init, @function
++_init:
++      /* Use a four-byte instruction to avoid NOPs */
++      stm     --sp, r0-r7,lr
++      .align  2
++
++      .section .fini
++      .align  2
++      .global _fini
++      .type   _fini, @function
++_fini:
++      stm     --sp, r0-r7,lr
++      .align  2
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/crtn.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/crtn.S      2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,14 @@
++
++      .section .init
++      .align  2
++      .global _init
++      .type   _init, @function
++      ldm     sp++, r0-r7,pc
++      .size   _init, . - _init
++
++      .section .fini
++      .align  2
++      .global _fini
++      .type   _fini, @function
++      ldm     sp++, r0-r7,pc
++      .size   _fini, . - _fini
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/mmap.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/mmap.c      2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,31 @@
++/* Copyright (C) 2005 Atmel Norway
++
++   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
++
++   Derived in part from the Linux-8086 C library, the GNU C Library, and several
++   other sundry sources.  Files within this library are copyright by their
++   respective copyright holders.
++ */
++
++#include <errno.h>
++#include <sys/mman.h>
++#include <sys/syscall.h>
++
++static _syscall6(__ptr_t, mmap2, __ptr_t, addr, size_t, len, int, prot, int, flags, int, fd, __off_t, pgoff);
++
++__ptr_t mmap(__ptr_t addr, size_t len, int prot, int flags, int fd, __off_t offset)
++{
++      return mmap2(addr, len, prot, flags, fd, offset >> 12);
++}
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/setjmp.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/setjmp.S    2006-05-05 09:28:28.000000000 +0200
+@@ -0,0 +1,43 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ */
++#define _SETJMP_H
++#define _ASM
++#include <bits/setjmp.h>
++
++      .text
++
++      .global __sigsetjmp
++      .type   __sigsetjmp,"function"
++
++      /* Create a global, hidden symbol for use by setjmp() and _setjmp().
++         If it's not hidden, the linker will complain about a relative
++         jump to a dynamic symbol when building a shared library.
++
++         Also, if a user overrides the __sigsetjmp function, he might not
++         expect the setjmp() and _setjmp() function to effectively be
++         overridden as well.  */
++      .global __sigsetjmp_internal
++      .hidden __sigsetjmp_internal
++      .type   __sigsetjmp_internal,"function"
++      .align  1
++__sigsetjmp:
++__sigsetjmp_internal:
++      mustr   r8
++      stm     r12, r0,r1,r2,r3,r4,r5,r6,r7,r8,sp,lr
++
++      /* Make a tail call to __sigjmp_save; it takes the same args.  */
++#ifdef __PIC__
++      mov     r9, r6
++      lddpc   r6, .LG
++.L1:  rsub    r6, pc
++      ld.w    r8, r6[__sigjmp_save@got]
++      mov     r6, r9
++      mov     pc, r8
++
++      .align  2
++.LG:  .long   .L1 - _GLOBAL_OFFSET_TABLE_
++#else
++      rjmp    __sigjmp_save
++#endif
++      .size   __sigsetjmp, . - __sigsetjmp
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/sigaction.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/sigaction.c 2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,49 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ */
++#include <errno.h>
++#include <signal.h>
++#include <string.h>
++#include <sys/syscall.h>
++#include <bits/kernel_sigaction.h>
++
++#define SA_RESTORER   0x04000000
++extern void __default_rt_sa_restorer(void);
++
++/*
++ * If act is not NULL, change the action for sig to *act.
++ * If oact is not NULL, put the old action for sig in *oact.
++ */
++int __libc_sigaction(int signum, const struct sigaction *act,
++                   struct sigaction *oldact)
++{
++      struct kernel_sigaction kact, koact;
++      int result;
++
++      if (act) {
++              kact.k_sa_handler = act->sa_handler;
++              memcpy(&kact.sa_mask, &act->sa_mask, sizeof (kact.sa_mask));
++              kact.sa_flags = act->sa_flags;
++              if (kact.sa_flags & (SA_RESTORER | SA_ONSTACK))
++                      kact.sa_restorer = act->sa_restorer;
++              else
++                      kact.sa_restorer = __default_rt_sa_restorer;
++              kact.sa_flags |= SA_RESTORER;
++      }
++
++      result = __syscall_rt_sigaction(signum, act ? __ptrvalue(&kact) : NULL,
++                                      oldact ? __ptrvalue(&koact) : NULL,
++                                      _NSIG / 8);
++
++      if (oldact && result >= 0) {
++              oldact->sa_handler = koact.k_sa_handler;
++              memcpy(&oldact->sa_mask, &koact.sa_mask,
++                     sizeof(oldact->sa_mask));
++              oldact->sa_flags = koact.sa_flags;
++              oldact->sa_restorer = koact.sa_restorer;
++      }
++
++      return result;
++}
++
++weak_alias(__libc_sigaction, sigaction)
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/sigrestorer.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/sigrestorer.S       2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,11 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ */
++#include <sys/syscall.h>
++
++      .global __default_rt_sa_restorer
++      .type   __default_rt_sa_restorer,"function"
++      .align  1
++__default_rt_sa_restorer:
++      mov     r8, __NR_rt_sigreturn
++      scall
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/sys/elf.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/sys/elf.h   2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,26 @@
++/* Copyright (C) 1996, 1997, 1999, 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.  */
++
++#ifndef _SYS_ELF_H
++#define _SYS_ELF_H    1
++
++#warning "This header is obsolete; use <sys/procfs.h> instead."
++
++#include <sys/procfs.h>
++
++#endif        /* sys/elf.h */
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/sys/io.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/sys/io.h    2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,48 @@
++/* Copyright (C) 1996, 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 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.  */
++
++#ifndef       _SYS_IO_H
++
++#define       _SYS_IO_H       1
++#include <features.h>
++
++__BEGIN_DECLS
++
++/* If TURN_ON is TRUE, request for permission to do direct i/o on the
++   port numbers in the range [FROM,FROM+NUM-1].  Otherwise, turn I/O
++   permission off for that range.  This call requires root privileges.  */
++extern int ioperm (unsigned long int __from, unsigned long int __num,
++                 int __turn_on) __THROW;
++
++/* Set the I/O privilege level to LEVEL.  If LEVEL is nonzero,
++   permission to access any I/O port is granted.  This call requires
++   root privileges. */
++extern int iopl (int __level) __THROW;
++
++/* The functions that actually perform reads and writes.  */
++extern unsigned char inb (unsigned long int port) __THROW;
++extern unsigned short int inw (unsigned long int port) __THROW;
++extern unsigned long int inl (unsigned long int port) __THROW;
++
++extern void outb (unsigned char value, unsigned long int port) __THROW;
++extern void outw (unsigned short value, unsigned long int port) __THROW;
++extern void outl (unsigned long value, unsigned long int port) __THROW;
++
++__END_DECLS
++
++#endif /* _SYS_IO_H */
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/sys/procfs.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/sys/procfs.h        2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,123 @@
++/* Copyright (C) 1996, 1997, 1999, 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.  */
++
++#ifndef _SYS_PROCFS_H
++#define _SYS_PROCFS_H 1
++
++/* This is somewhat modelled after the file of the same name on SVR4
++   systems.  It provides a definition of the core file format for ELF
++   used on Linux.  It doesn't have anything to do with the /proc file
++   system, even though Linux has one.
++
++   Anyway, the whole purpose of this file is for GDB and GDB only.
++   Don't read too much into it.  Don't use it for anything other than
++   GDB unless you know what you are doing.  */
++
++#include <features.h>
++#include <sys/time.h>
++#include <sys/types.h>
++#include <sys/user.h>
++
++__BEGIN_DECLS
++
++/* Type for a general-purpose register.  */
++typedef unsigned long elf_greg_t;
++
++/* And the whole bunch of them.  We could have used `struct
++   user_regs' directly in the typedef, but tradition says that
++   the register set is an array, which does have some peculiar
++   semantics, so leave it that way.  */
++#define ELF_NGREG (sizeof (struct user_regs) / sizeof(elf_greg_t))
++typedef elf_greg_t elf_gregset_t[ELF_NGREG];
++
++/* Register set for the floating-point registers.  */
++typedef struct user_fpregs elf_fpregset_t;
++
++/* Signal info.  */
++struct elf_siginfo
++  {
++    int si_signo;                     /* Signal number.  */
++    int si_code;                      /* Extra code.  */
++    int si_errno;                     /* Errno.  */
++  };
++
++/* Definitions to generate Intel SVR4-like core files.  These mostly
++   have the same names as the SVR4 types with "elf_" tacked on the
++   front to prevent clashes with Linux definitions, and the typedef
++   forms have been avoided.  This is mostly like the SVR4 structure,
++   but more Linuxy, with things that Linux does not support and which
++   GDB doesn't really use excluded.  */
++
++struct elf_prstatus
++  {
++    struct elf_siginfo pr_info;               /* Info associated with signal.  */
++    short int pr_cursig;              /* Current signal.  */
++    unsigned long int pr_sigpend;     /* Set of pending signals.  */
++    unsigned long int pr_sighold;     /* Set of held signals.  */
++    __pid_t pr_pid;
++    __pid_t pr_ppid;
++    __pid_t pr_pgrp;
++    __pid_t pr_sid;
++    struct timeval pr_utime;          /* User time.  */
++    struct timeval pr_stime;          /* System time.  */
++    struct timeval pr_cutime;         /* Cumulative user time.  */
++    struct timeval pr_cstime;         /* Cumulative system time.  */
++    elf_gregset_t pr_reg;             /* GP registers.  */
++    int pr_fpvalid;                   /* True if math copro being used.  */
++  };
++
++
++#define ELF_PRARGSZ     (80)    /* Number of chars for args.  */
++
++struct elf_prpsinfo
++  {
++    char pr_state;                    /* Numeric process state.  */
++    char pr_sname;                    /* Char for pr_state.  */
++    char pr_zomb;                     /* Zombie.  */
++    char pr_nice;                     /* Nice val.  */
++    unsigned long int pr_flag;                /* Flags.  */
++    unsigned short int pr_uid;
++    unsigned short int pr_gid;
++    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
++    /* Lots missing */
++    char pr_fname[16];                        /* Filename of executable.  */
++    char pr_psargs[ELF_PRARGSZ];      /* Initial part of arg list.  */
++  };
++
++/* The rest of this file provides the types for emulation of the
++   Solaris <proc_service.h> interfaces that should be implemented by
++   users of libthread_db.  */
++
++/* Addresses.  */
++typedef void *psaddr_t;
++
++/* Register sets.  Linux has different names.  */
++typedef elf_gregset_t prgregset_t;
++typedef elf_fpregset_t prfpregset_t;
++
++/* We don't have any differences between processes and threads,
++   therefore have only one PID type.  */
++typedef __pid_t lwpid_t;
++
++/* Process status and info.  In the end we do provide typedefs for them.  */
++typedef struct elf_prstatus prstatus_t;
++typedef struct elf_prpsinfo prpsinfo_t;
++
++__END_DECLS
++
++#endif        /* sys/procfs.h */
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/sys/ucontext.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/sys/ucontext.h      2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,94 @@
++/* Copyright (C) 1998, 1999, 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.  */
++
++/* Linux/AVR32 ABI compliant context switching support.  */
++
++#ifndef _SYS_UCONTEXT_H
++#define _SYS_UCONTEXT_H       1
++
++#include <features.h>
++#include <signal.h>
++#include <sys/procfs.h>
++#include <bits/sigcontext.h>
++
++typedef int greg_t;
++
++/* Number of general registers.  */
++#define NGREG 16
++
++/* Container for all general registers.  */
++typedef elf_gregset_t gregset_t;
++
++/* Number of each register is the `gregset_t' array.  */
++enum
++{
++  R0 = 0,
++#define R0    R0
++  R1 = 1,
++#define R1    R1
++  R2 = 2,
++#define R2    R2
++  R3 = 3,
++#define R3    R3
++  R4 = 4,
++#define R4    R4
++  R5 = 5,
++#define R5    R5
++  R6 = 6,
++#define R6    R6
++  R7 = 7,
++#define R7    R7
++  R8 = 8,
++#define R8    R8
++  R9 = 9,
++#define R9    R9
++  R10 = 10,
++#define R10   R10
++  R11 = 11,
++#define R11   R11
++  R12 = 12,
++#define R12   R12
++  R13 = 13,
++#define R13   R13
++  R14 = 14,
++#define R14   R14
++  R15 = 15
++#define R15   R15
++};
++
++/* Structure to describe FPU registers.  */
++typedef elf_fpregset_t        fpregset_t;
++
++/* Context to describe whole processor state.  */
++typedef struct
++  {
++    gregset_t gregs;
++    fpregset_t fpregs;
++  } mcontext_t;
++
++/* Userlevel context.  */
++typedef struct ucontext
++{
++    unsigned long     uc_flags;
++    struct ucontext  *uc_link;
++    stack_t           uc_stack;
++    struct sigcontext uc_mcontext;
++    sigset_t          uc_sigmask;   /* mask last for extensibility */
++} ucontext_t;
++
++#endif /* sys/ucontext.h */
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/sys/user.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/sys/user.h  2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,46 @@
++#ifndef _SYS_USER_H
++#define _SYS_USER_H
++
++struct user_fpregs
++{
++
++};
++
++struct user_regs
++{
++      unsigned long sr;
++      unsigned long pc;
++      unsigned long lr;
++      unsigned long sp;
++      unsigned long r12;
++      unsigned long r11;
++      unsigned long r10;
++      unsigned long r9;
++      unsigned long r8;
++      unsigned long r7;
++      unsigned long r6;
++      unsigned long r5;
++      unsigned long r4;
++      unsigned long r3;
++      unsigned long r2;
++      unsigned long r1;
++      unsigned long r0;
++      unsigned long r12_orig;
++};
++
++struct user
++{
++      struct user_regs        regs;           /* general registers */
++      size_t                  u_tsize;        /* text size (pages) */
++      size_t                  u_dsize;        /* data size (pages) */
++      size_t                  u_ssize;        /* stack size (pages) */
++      unsigned long           start_code;     /* text starting address */
++      unsigned long           start_data;     /* data starting address */
++      unsigned long           start_stack;    /* stack starting address */
++      long int                signal;         /* signal causing core dump */
++      struct user_regs *      u_ar0;          /* help gdb find registers */
++      unsigned long           magic;          /* identifies a core file */
++      char                    u_comm[32];     /* user command name */
++};
++
++#endif /* _SYS_USER_H */
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/syscall.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/syscall.S   2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,81 @@
++/*
++ * syscall for AVR32/uClibc
++ *
++ * Copyright (C) 2004 Atmel Norway
++ *
++ * 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 <features.h>
++
++      .text
++
++      /*
++       * long int syscall(long int sysno, ...)
++       */
++      .global syscall
++      .type   syscall, @function
++      .align  2
++syscall:
++      stm     --sp, r3,r5,lr
++      sub     lr, sp, -12
++      mov     r8, r12
++      ldm     lr, r3,r5,r9-r12
++      scall
++      cp.w    r12, -4095
++      brlo    .Ldone
++
++#ifdef __PIC__
++      lddpc   r5, .Lgot
++.Lgotcalc:
++      rsub    r5, pc
++# ifdef __UCLIBC_HAS_THREADS__
++      mov     r3, r12
++      mcall   r5[__errno_location@got]
++      st.w    r12[0], r3
++# else
++      ld.w    r3, r5[errno@got]
++      st.w    r3[0], r12
++# endif
++#else
++# ifdef __UCLIBC_HAS_THREADS__
++      mov     r3, r12
++      mcall   .Lerrno_location
++      st.w    r12[0], r3
++# else
++      lddpc   r3, .Lerrno
++      st.w    r3[0], r12
++# endif
++#endif
++      mov     r12, -1
++
++.Ldone:
++      ldm     sp++, r3,r5,pc
++
++      .align  2
++#ifdef __PIC__
++.Lgot:
++      .long   .Lgotcalc - _GLOBAL_OFFSET_TABLE_
++#else
++# ifdef __UCLIBC_HAS_THREADS__
++.Lerrno_location:
++      .long   __errno_location
++# else
++.Lerrno:
++      .long   errno
++# endif
++#endif
++
++
++      .size   syscall, . - syscall
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/vfork.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/vfork.S     2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,55 @@
++      /*
++       * vfork for uClibc
++       *
++       * Copyright (C) 2005 Atmel Norway
++       */
++
++      /*
++       * Clone the process without copying the address space.  The
++       * calling process is suspended until the child either exits
++       * or calls execve.
++       *
++       * This all means that we cannot rely on the stack to store
++       * away registers, since they will be overwritten by the child
++       * as soon as it makes another function call (e.g. execve()).
++       * Fortunately, the Linux kernel preserves LR across system calls.
++       */
++#include <features.h>
++#include <sys/syscall.h>
++
++      .global __vfork
++      .type   __vfork,@function
++      .align  1
++__vfork:
++      mov     r8, __NR_vfork
++      scall
++      cp.w    r12, -4096
++      retls   r12
++
++      /* vfork failed, so we may use the stack freely */
++      pushm   r4-r7,lr
++#ifdef __PIC__
++      lddpc   r6, .L_GOT
++      rsub    r4, r12, 0
++.L_RGOT:
++      rsub    r6, pc
++      mcall   r6[__errno_location@got]
++#else
++      rsub    r4, r12, 0
++      mcall   .L__errno_location
++#endif
++      st.w    r12[0], r4
++      popm    r4-r7,pc,r12=-1
++
++      .align  2
++#ifdef __PIC__
++.L_GOT:
++      .long   .L_RGOT - _GLOBAL_OFFSET_TABLE_
++#else
++.L__errno_location:
++      .long   __errno_location
++#endif
++      .size   __vfork, . - __vfork
++
++      .weak   vfork
++      vfork   = __vfork
+Index: uClibc-0.9.28/Rules.mak
+===================================================================
+--- uClibc-0.9.28.orig/Rules.mak       2006-05-05 09:26:01.000000000 +0200
++++ uClibc-0.9.28/Rules.mak    2006-05-05 09:27:17.000000000 +0200
+@@ -231,6 +231,10 @@ ifeq ($(strip $(TARGET_ARCH)),frv)
+       UCLIBC_LDSO=ld.so.1
+ endif
++ifeq ($(strip $(TARGET_ARCH)),avr32)
++      CPU_CFLAGS-$(CONFIG_AP7000)     += -mcpu=ap7000
++endif
++
+ # Keep the check_gcc from being needlessly executed
+ ifndef PIEFLAG
+ ifneq ($(UCLIBC_BUILD_PIE),y)
+From nobody Mon Sep 17 00:00:00 2001
+Subject: [PATCH] Make linkrelax configurable
+From: HÃ¥vard Skinnemoen <hskinnemoen@atmel.com>
+Date: 1133951618 +0100
+
+Add a linkrelax option to the configure system which will give
+appropriate options to the compiler, assembler and linker to enable
+link-time optimizations.
+
+---
+
+ Rules.mak                  |    2 ++
+ extra/Configs/Config.avr32 |    4 ++++
+ 2 files changed, 6 insertions(+)
+
+Index: uClibc-0.9.28/Rules.mak
+===================================================================
+--- uClibc-0.9.28.orig/Rules.mak       2006-02-08 17:58:53.000000000 +0100
++++ uClibc-0.9.28/Rules.mak    2006-02-08 17:59:07.000000000 +0100
+@@ -233,6 +233,8 @@ endif
+ ifeq ($(strip $(TARGET_ARCH)),avr32)
+       CPU_CFLAGS-$(CONFIG_AP7000)     += -mcpu=ap7000
++      CPU_CFLAGS-$(LINKRELAX)         += -masm-addr-pseudos -Wa,--pic,--linkrelax
++      CPU_LDFLAGS-$(LINKRELAX)        += --relax
+ endif
+ # Keep the check_gcc from being needlessly executed
+Index: uClibc-0.9.28/extra/Configs/Config.avr32
+===================================================================
+--- uClibc-0.9.28.orig/extra/Configs/Config.avr32      2006-02-08 17:58:53.000000000 +0100
++++ uClibc-0.9.28/extra/Configs/Config.avr32   2006-02-08 17:59:07.000000000 +0100
+@@ -36,3 +36,7 @@ config CONFIG_AP7000
+       bool "AP7000"
+ endchoice
++
++config LINKRELAX
++      bool "Enable linker optimizations"
++      default n
+Subject: [PATCH] AVR32-optimized string operations
+
+Add hand-optimized AVR32-specific string operations. Some of them
+need a bit more testing, though.
+
+---
+
+ libc/string/avr32/Makefile      |   40 +++++++++++
+ libc/string/avr32/bcopy.S       |   15 ++++
+ libc/string/avr32/bzero.S       |   12 +++
+ libc/string/avr32/memchr.S      |   62 +++++++++++++++++
+ libc/string/avr32/memcmp.S      |   50 +++++++++++++
+ libc/string/avr32/memcpy.S      |  110 ++++++++++++++++++++++++++++++
+ libc/string/avr32/memmove.S     |  114 +++++++++++++++++++++++++++++++
+ libc/string/avr32/memset.S      |   60 ++++++++++++++++
+ libc/string/avr32/strcat.S      |   95 ++++++++++++++++++++++++++
+ libc/string/avr32/strcmp.S      |   80 ++++++++++++++++++++++
+ libc/string/avr32/strcpy.S      |   63 +++++++++++++++++
+ libc/string/avr32/stringtest.c  |  144 ++++++++++++++++++++++++++++++++++++++++
+ libc/string/avr32/strlen.S      |   52 ++++++++++++++
+ libc/string/avr32/strncpy.S     |   77 +++++++++++++++++++++
+ libc/string/avr32/test_memcpy.c |   66 ++++++++++++++++++
+ 15 files changed, 1040 insertions(+)
+
+Index: uClibc-0.9.28-avr32/libc/string/avr32/bcopy.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/bcopy.S      2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,15 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++      .text
++      .global bcopy
++      .type   bcopy, @function
++      .align  1
++bcopy:
++      /* Swap the first two arguments */
++      eor     r11, r12
++      eor     r12, r11
++      eor     r11, r12
++      rjmp    __memmove
++      .size   bcopy, . - bcopy
+Index: uClibc-0.9.28-avr32/libc/string/avr32/bzero.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/bzero.S      2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,12 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++      .text
++      .global bzero
++      .type   bzero, @function
++      .align  1
++bzero:
++      mov     r10, r11
++      mov     r11, 0
++      rjmp    __memset
+Index: uClibc-0.9.28-avr32/libc/string/avr32/Makefile
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/Makefile     2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,40 @@
++# Makefile for uClibc
++#
++# Copyright (C) 2000-2003 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
++
++TOPDIR=../../../
++include $(TOPDIR)Rules.mak
++
++SSRC  := bcopy.S bzero.S memcmp.S memcpy.S memmove.S
++SSRC  += memset.S strcmp.S strlen.S
++# memchr.S, strcat.S, strcpy.S, strncpy.S is broken
++SOBJS := $(patsubst %.S,%.o, $(SSRC))
++OBJS  := $(SOBJS)
++
++OBJ_LIST:= ../../obj.string.$(TARGET_ARCH)
++
++all: $(OBJ_LIST)
++
++$(OBJ_LIST): $(OBJS)
++      echo $(addprefix string/$(TARGET_ARCH)/, $(OBJS)) > $@
++
++$(SOBJS): %.o: %.S
++      $(CC) $(ASFLAGS) -c $< -o $@
++      $(STRIPTOOL) -x -R .note -R .comment $@
++
++clean:
++      $(RM) *.[oa] *~ core
+Index: uClibc-0.9.28-avr32/libc/string/avr32/memchr.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/memchr.S     2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,62 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++#define str r12
++#define chr r11
++#define len r10
++
++      .text
++      .global memchr
++      .type   memchr, @function
++memchr:
++      or      chr, chr, chr << 8
++      or      chr, chr, chr << 16
++
++      mov     r9, str
++      andl    r9, 3, COH
++      brne    .Lunaligned_str
++
++1:    sub     len, 4
++      brlt    2f
++      ld.w    r8, str++
++      psub.b  r9, r8, r11
++      tnbz    r9
++      brne    1b
++
++      sub     str, 4
++      bfextu  r9, r8, 24, 8
++      cp.b    r9, r11
++      reteq   str
++      sub     str, -1
++      bfextu  r9, r8, 16, 8
++      cp.b    r9, r11
++      reteq   str
++      sub     str, -1
++      bfextu  r9, r8, 8, 8
++      cp.b    r9, r11
++      reteq   str
++      sub     str, -1
++      retal   str
++
++2:    sub     len, -4
++      reteq   0
++
++3:    ld.ub   r8, str++
++      cp.w    r8, 0
++      reteq   str
++      sub     len, 1
++      brne    3b
++
++      retal   0
++
++.Lunaligned_str:
++1:    sub     len, 1
++      retlt   0
++      ld.ub   r8, str++
++      cp.b    r8, r11
++      reteq   str
++      sub     r9, 1
++      brge    1b
++
++      rjmp    .Laligned_search
+Index: uClibc-0.9.28-avr32/libc/string/avr32/memcmp.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/memcmp.S     2006-10-20 10:42:09.000000000 +0200
+@@ -0,0 +1,50 @@
++/*
++ * Copyright (C) 2004 Atmel Norway.
++ */
++
++#define s1 r12
++#define s2 r11
++#define len r10
++
++      .text
++      .global memcmp
++      .type   memcmp, @function
++      .align  1
++memcmp:
++      sub     len, 4
++      brlt    .Lless_than_4
++
++1:    ld.w    r8, s1++
++      ld.w    r9, s2++
++      cp.w    r8, r9
++      brne    .Lfound_word
++      sub     len, 4
++      brge    1b
++
++.Lless_than_4:
++      sub     len, -4
++      reteq   0
++
++1:    ld.ub   r8, s1++
++      ld.ub   r9, s2++
++      sub     r8, r9
++      retne   r8
++      sub     len, 1
++      brgt    1b
++
++      retal   0
++
++.Lfound_word:
++      psub.b  r9, r8, r9
++      bfextu  r8, r9, 24, 8
++      retne   r8
++      bfextu  r8, r9, 16, 8
++      retne   r8
++      bfextu  r8, r9, 8, 8
++      retne   r8
++      retal   r9
++
++      .size   memcmp, . - memcmp
++
++      .weak   bcmp
++      bcmp = memcmp
+Index: uClibc-0.9.28-avr32/libc/string/avr32/memcpy.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/memcpy.S     2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,110 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++/* Don't use r12 as dst since we must return it unmodified */
++#define dst r9
++#define src r11
++#define len r10
++
++      .text
++      .global memcpy
++      .type   memcpy, @function
++
++      .global __memcpy
++      .hidden __memcpy
++      .type   __memcpy, @function
++memcpy:
++__memcpy:
++      pref    src[0]
++      mov     dst, r12
++
++      /* If we have less than 32 bytes, don't do anything fancy */
++      cp.w    len, 32
++      brge    .Lmore_than_31
++
++      sub     len, 1
++      retlt   r12
++1:    ld.ub   r8, src++
++      st.b    dst++, r8
++      sub     len, 1
++      brge    1b
++      retal   r12
++
++.Lmore_than_31:
++      pushm   r0-r7, lr
++
++      /* Check alignment */
++      mov     r8, src
++      andl    r8, 31, COH
++      brne    .Lunaligned_src
++      mov     r8, dst
++      andl    r8, 3, COH
++      brne    .Lunaligned_dst
++
++.Laligned_copy:
++      sub     len, 32
++      brlt    .Lless_than_32
++
++1:    /* Copy 32 bytes at a time */
++      ldm     src, r0-r7
++      sub     src, -32
++      stm     dst, r0-r7
++      sub     dst, -32
++      sub     len, 32
++      brge    1b
++
++.Lless_than_32:
++      /* Copy 16 more bytes if possible */
++      sub     len, -16
++      brlt    .Lless_than_16
++      ldm     src, r0-r3
++      sub     src, -16
++      sub     len, 16
++      stm     dst, r0-r3
++      sub     dst, -16
++
++.Lless_than_16:
++      /* Do the remaining as byte copies */
++      neg     len
++      add     pc, pc, len << 2
++      .rept   15
++      ld.ub   r0, src++
++      st.b    dst++, r0
++      .endr
++
++      popm    r0-r7, pc
++
++.Lunaligned_src:
++      /* Make src cacheline-aligned. r8 = (src & 31) */
++      rsub    r8, r8, 32
++      sub     len, r8
++1:    ld.ub   r0, src++
++      st.b    dst++, r0
++      sub     r8, 1
++      brne    1b
++
++      /* If dst is word-aligned, we're ready to go */
++      pref    src[0]
++      mov     r8, 3
++      tst     dst, r8
++      breq    .Laligned_copy
++
++.Lunaligned_dst:
++      /* src is aligned, but dst is not. Expect bad performance */
++      sub     len, 4
++      brlt    2f
++1:    ld.w    r0, src++
++      st.w    dst++, r0
++      sub     len, 4
++      brge    1b
++
++2:    neg     len
++      add     pc, pc, len << 2
++      .rept   3
++      ld.ub   r0, src++
++      st.b    dst++, r0
++      .endr
++
++      popm    r0-r7, pc
++      .size   memcpy, . - memcpy
+Index: uClibc-0.9.28-avr32/libc/string/avr32/memmove.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/memmove.S    2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,114 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++#define dst r12
++#define src r11
++#define len r10
++
++      .text
++      .global memmove
++      .type   memmove, @function
++
++      .global __memmove
++      .hidden __memmove
++      .type   __memmove, @function
++memmove:
++__memmove:
++      cp.w    src, dst
++      brge    __memcpy
++
++      add     dst, len
++      add     src, len
++      pref    src[-1]
++
++      /*
++       * The rest is basically the same as in memcpy.S except that
++       * the direction is reversed.
++       */
++      cp.w    len, 32
++      brge    .Lmore_than_31
++
++      sub     len, 1
++      retlt   r12
++1:    ld.ub   r8, --src
++      st.b    --dst, r8
++      sub     len, 1
++      brge    1b
++      retal   r12
++
++.Lmore_than_31:
++      pushm   r0-r7, lr
++
++      /* Check alignment */
++      mov     r8, src
++      andl    r8, 31, COH
++      brne    .Lunaligned_src
++      mov     r8, r12
++      andl    r8, 3, COH
++      brne    .Lunaligned_dst
++
++.Laligned_copy:
++      sub     len, 32
++      brlt    .Lless_than_32
++
++1:    /* Copy 32 bytes at a time */
++      sub     src, 32
++      ldm     src, r0-r7
++      sub     dst, 32
++      sub     len, 32
++      stm     dst, r0-r7
++      brge    1b
++
++.Lless_than_32:
++      /* Copy 16 more bytes if possible */
++      sub     len, -16
++      brlt    .Lless_than_16
++      sub     src, 16
++      ldm     src, r0-r3
++      sub     dst, 16
++      sub     len, 16
++      stm     dst, r0-r3
++
++.Lless_than_16:
++      /* Do the remaining as byte copies */
++      sub     len, -16
++      breq    2f
++1:    ld.ub   r0, --src
++      st.b    --dst, r0
++      sub     len, 1
++      brne    1b
++
++2:    popm    r0-r7, pc
++
++.Lunaligned_src:
++      /* Make src cacheline-aligned. r8 = (src & 31) */
++      sub     len, r8
++1:    ld.ub   r0, --src
++      st.b    --dst, r0
++      sub     r8, 1
++      brne    1b
++
++      /* If dst is word-aligned, we're ready to go */
++      pref    src[-4]
++      mov     r8, 3
++      tst     dst, r8
++      breq    .Laligned_copy
++
++.Lunaligned_dst:
++      /* src is aligned, but dst is not. Expect bad performance */
++      sub     len, 4
++      brlt    2f
++1:    ld.w    r0, --src
++      st.w    --dst, r0
++      sub     len, 4
++      brge    1b
++
++2:    neg     len
++      add     pc, pc, len << 2
++      .rept   3
++      ld.ub   r0, --src
++      st.b    --dst, r0
++      .endr
++
++      popm    r0-r7, pc
+Index: uClibc-0.9.28-avr32/libc/string/avr32/memset.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/memset.S     2006-10-20 10:42:15.000000000 +0200
+@@ -0,0 +1,60 @@
++/*
++ * Copyright (C) 2004 Atmel Norway.
++ */
++
++#define s r12
++#define c r11
++#define n r10
++
++      .text
++      .global memset
++      .type   memset, @function
++
++      .global __memset
++      .hidden __memset
++      .type   __memset, @function
++
++      .align  1
++memset:
++__memset:
++      cp.w    n, 32
++      mov     r9, s
++      brge    .Llarge_memset
++
++      sub     n, 1
++      retlt   s
++1:    st.b    s++, c
++      sub     n, 1
++      brge    1b
++
++      retal   r9
++
++.Llarge_memset:
++      mov     r8, r11
++      mov     r11, 3
++      bfins   r8, r8, 8, 8
++      bfins   r8, r8, 16, 16
++      tst     s, r11
++      breq    2f
++
++1:    st.b    s++, r8
++      sub     n, 1
++      tst     s, r11
++      brne    1b
++
++2:    mov     r11, r9
++      mov     r9, r8
++      sub     n, 8
++
++3:    st.d    s++, r8
++      sub     n, 8
++      brge    3b
++
++      /* If we are done, n == -8 and we'll skip all st.b insns below */
++      neg     n
++      lsl     n, 1
++      add     pc, n
++      .rept   7
++      st.b    s++, r8
++      .endr
++      retal   r11
+Index: uClibc-0.9.28-avr32/libc/string/avr32/strcat.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/strcat.S     2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,95 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++#define s1 r9
++#define s2 r11
++
++      .text
++      .global strcat
++      .type   strcat, @function
++      .align  1
++strcat:
++      mov     s1, r12
++
++      /* Make sure s1 is word-aligned */
++      mov     r10, s1
++      andl    r10, 3, COH
++      breq    2f
++
++      add     pc, pc, r10 << 3
++      sub     r0, r0, 0       /* 4-byte nop */
++      ld.ub   r8, s1++
++      sub     r8, r8, 0
++      breq    2f
++      ld.ub   r8, s1++
++      sub     r8, r8, 0
++      breq    3f
++      ld.ub   r8, s1++
++      sub     r8, r8, 0
++      breq    4f
++
++      /* Find the end of the first string */
++5:    ld.w    r8, s1++
++      tnbz    r8
++      brne    5b
++
++      sub     s1, 4
++
++      bfextu  r10, r8, 24, 8
++      cp.w    r10, 0
++      breq    1f
++      sub     s1, -1
++      bfextu  r10, r8, 16, 8
++      cp.w    r10, 0
++      breq    2f
++      sub     s1, -1
++      bfextu  r10, r8, 8, 8
++      cp.w    r10, 0
++      breq    3f
++      sub     s1, -1
++      rjmp    4f
++
++      /* Now, append s2 */
++1:    ld.ub   r8, s2++
++      st.b    s1++, r8
++      cp.w    r8, 0
++      reteq   r12
++2:    ld.ub   r8, s2++
++      st.b    s1++, r8
++      cp.w    r8, 0
++      reteq   r12
++3:    ld.ub   r8, s2++
++      st.b    s1++, r8
++      cp.w    r8, 0
++      reteq   r12
++4:    ld.ub   r8, s2++
++      st.b    s1++, r8
++      cp.w    r8, 0
++      reteq   r12
++
++      /* Copy one word at a time */
++      ld.w    r8, s2++
++      tnbz    r8
++      breq    2f
++1:    st.w    r8, s2++
++      ld.w    r8, s2++
++      tnbz    r8
++      brne    1b
++
++      /* Copy the remaining bytes */
++      bfextu  r10, r8, 24, 8
++      st.b    s1++, r10
++      cp.w    r10, 0
++      reteq   r12
++      bfextu  r10, r8, 16, 8
++      st.b    s1++, r10
++      cp.w    r10, 0
++      reteq   r12
++      bfextu  r10, r8, 8, 8
++      st.b    s1++, r10
++      cp.w    r10, 0
++      reteq   r12
++      st.b    s1++, r8
++      retal   r12
++      .size   strcat, . - strcat
+Index: uClibc-0.9.28-avr32/libc/string/avr32/strcmp.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/strcmp.S     2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,80 @@
++/*
++ * Copyright (C) 2004 Atmel Norway.
++ */
++
++#define s1 r12
++#define s2 r11
++#define len r10
++
++      .text
++      .global strcmp
++      .type   strcmp, @function
++      .align  1
++strcmp:
++      mov     r8, 3
++      tst     s1, r8
++      brne    .Lunaligned_s1
++      tst     s2, r8
++      brne    .Lunaligned_s2
++
++1:    ld.w    r8, s1++
++      ld.w    r9, s2++
++      cp.w    r8, r9
++      brne    2f
++      tnbz    r8
++      brne    1b
++      retal   0
++
++2:    bfextu  r12, r8, 24, 8
++      bfextu  r11, r9, 24, 8
++      sub     r12, r11
++      retne   r12
++      cp.w    r11, 0
++      reteq   0
++      bfextu  r12, r8, 16, 8
++      bfextu  r11, r9, 16, 8
++      sub     r12, r11
++      retne   r12
++      cp.w    r11, 0
++      reteq   0
++      bfextu  r12, r8, 8, 8
++      bfextu  r11, r9, 8, 8
++      sub     r12, r11
++      retne   r12
++      cp.w    r11, 0
++      reteq   0
++      bfextu  r12, r8, 0, 8
++      bfextu  r11, r9, 0, 8
++      sub     r12, r11
++      retal   r12
++
++.Lunaligned_s1:
++3:    tst     s1, r8
++      breq    4f
++      ld.ub   r10, s1++
++      ld.ub   r9, s2++
++      sub     r10, r9
++      retne   r10
++      cp.w    r9, 0
++      brne    3b
++      retal   r10
++
++4:    tst     s2, r8
++      breq    1b
++
++.Lunaligned_s2:
++      /*
++       * s1 and s2 can't both be aligned, and unaligned word loads
++       * can trigger spurious exceptions if we cross a page boundary.
++       * Do it the slow way...
++       */
++1:    ld.ub   r8, s1++
++      ld.ub   r9, s2++
++      sub     r8, r9
++      retne   r8
++      cp.w    r9, 0
++      brne    1b
++      retal   0
++
++      .weak   strcoll
++      strcoll = strcmp
+Index: uClibc-0.9.28-avr32/libc/string/avr32/strcpy.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/strcpy.S     2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,63 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ *
++ * To reduce the size, this one might simply call strncpy with len = -1.
++ */
++
++#define dst r9
++#define src r11
++
++      .text
++      .global strcpy
++      .type   strcpy, @function
++strcpy:
++      mov     dst, r12
++
++      pref    src[0]
++
++      /*
++       * Check alignment. If src is aligned but dst isn't, we can't
++       * do much about it...
++       */
++      mov     r8, src
++      andl    r8, 3 COH
++      brne    .Lunaligned_src
++
++.Laligned_copy:
++1:    ld.w    r8, src++
++      tnbz    r8
++      breq    2f
++      st.w    dst++, r8
++      rjmp    1b
++
++2:    /*
++       * Ok, r8 now contains the terminating '\0'. Copy the
++       * remaining bytes individually.
++       */
++      bfextu  r10, r8, 24, 8
++      st.b    dst++, r10
++      cp.w    r10, 0
++      reteq   r12
++      bfextu  r10, r8, 16, 8
++      st.b    dst++, r10
++      cp.w    r10, 0
++      reteq   r12
++      bfextu  r10, r8, 8, 8
++      st.b    dst++, r10
++      cp.w    r10, 0
++      reteq   r12
++      st.b    dst++, r8
++      retal   r12
++
++.Lunaligned_src:
++      /* Copy bytes until we're aligned */
++      rsub    r8, r8, 4
++      add     pc, pc, r8 << 3
++      nop
++      nop
++      ld.ub   r10, src++
++      st.b    dst++, r10
++      cp.w    r10, 0
++      reteq   r12
++
++      rjmp    .Laligned_copy
+Index: uClibc-0.9.28-avr32/libc/string/avr32/stringtest.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/stringtest.c 2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,144 @@
++
++#include <stdio.h>
++#include <string.h>
++#include <time.h>
++#include <sys/mman.h>
++
++#define BUF_SIZE (8 * 1024)
++
++static char *buf1;
++static char *buf1_ref;
++static char *buf2;
++
++extern void *optimized_memcpy(void *dest, void *src, size_t len);
++extern void *optimized_memmove(void *dest, void *src, size_t len);
++extern char *optimized_strcpy(char *dest, char *src);
++extern char *optimized_strncpy(char *dest, char *src, size_t len);
++
++void dump_mismatch(char *buf, char *ref, size_t len)
++{
++      int i, j;
++
++      for (i = 0; i < len; i += 16) {
++              if (memcmp(buf + i, ref + i, 16) == 0)
++                      continue;
++
++              printf("%4x buf:", i);
++              for (j = i; j < (i + 16); j++)
++                      printf(" %02x", buf[j]);
++              printf("\n     ref:");
++              for (j = i; j < (i + 16); j++)
++                      printf(" %02x", ref[j]);
++              printf("\n");
++      }
++}
++
++static void test_memcpy(int src_offset, int dst_offset, int len)
++{
++      clock_t start, old, new;
++      int i;
++
++      memset(buf1, 0x55, BUF_SIZE);
++      memset(buf1_ref, 0x55, BUF_SIZE);
++      memset(buf2, 0xaa, BUF_SIZE);
++
++      printf("Testing memcpy with offsets %d => %d and len %d...",
++             src_offset, dst_offset, len);
++
++      start = clock();
++      for (i = 0; i < 8192; i++)
++              optimized_memcpy(buf1 + dst_offset, buf2 + src_offset, len);
++      new = clock() - start;
++      start = clock();
++      for ( i = 0; i < 8192; i++)
++              memcpy(buf1_ref + dst_offset, buf2 + src_offset, len);
++      old = clock() - start;
++
++      if (memcmp(buf1, buf1_ref, BUF_SIZE) == 0)
++              printf("OK\n");
++      else {
++              printf("FAILED\n");
++              dump_mismatch(buf1, buf1_ref, BUF_SIZE);
++      }
++      printf("CPU time used: %d vs. %d\n", new, old);
++}
++
++static void test_memmove(int src_offset, int dst_offset, int len)
++{
++      clock_t start, old, new;
++
++      memset(buf1, 0x55, BUF_SIZE);
++      memset(buf1_ref, 0x55, BUF_SIZE);
++      memset(buf2, 0xaa, BUF_SIZE);
++
++      printf("Testing memmove with offsets %d => %d and len %d...",
++             src_offset, dst_offset, len);
++
++      start = clock();
++      optimized_memmove(buf1 + dst_offset, buf2 + src_offset, len);
++      new = clock() - start;
++      start = clock();
++      memmove(buf1_ref + dst_offset, buf2 + src_offset, len);
++      old = clock() - start;
++
++      if (memcmp(buf1, buf1_ref, BUF_SIZE) == 0)
++              printf("OK\n");
++      else {
++              printf("FAILED\n");
++              dump_mismatch(buf1, buf1_ref, BUF_SIZE);
++      }
++      printf("CPU time used: %d vs. %d\n", new, old);
++}
++
++int main(int argc, char *argv[])
++{
++      buf2 = mmap(NULL, BUF_SIZE, PROT_READ | PROT_WRITE,
++                  MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
++      if (buf2 == MAP_FAILED) {
++              perror("Failed to allocate memory for buf2");
++              return 1;
++      }
++      buf1 = mmap(NULL, BUF_SIZE, PROT_READ | PROT_WRITE,
++                  MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
++      if (buf1 == MAP_FAILED) {
++              perror("Failed to allocate memory for buf1");
++              return 1;
++      }
++      buf1_ref = mmap(NULL, BUF_SIZE, PROT_READ | PROT_WRITE,
++                      MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
++      if (buf1_ref == MAP_FAILED) {
++              perror("Failed to allocate memory for buf1_ref");
++              return 1;
++      }
++      printf("\n === MEMCPY ===\n\n");
++
++      test_memcpy(0, 0, BUF_SIZE - 32);
++      test_memcpy(0, 0, 1);
++      test_memcpy(0, 0, 31);
++      test_memcpy(0, 0, 32);
++      test_memcpy(0, 0, 127);
++      test_memcpy(0, 0, 128);
++      test_memcpy(4, 4, BUF_SIZE - 32 - 4);
++      test_memcpy(1, 1, BUF_SIZE - 32 - 1);
++      test_memcpy(1, 1, 126);
++      test_memcpy(0, 3, 128);
++      test_memcpy(1, 4, 128);
++      test_memcpy(0, 0, 0);
++
++      printf("\n === MEMMOVE ===\n\n");
++
++      test_memmove(0, 0, BUF_SIZE - 32);
++      test_memmove(0, 0, 1);
++      test_memmove(0, 0, 31);
++      test_memmove(0, 0, 32);
++      test_memmove(0, 0, BUF_SIZE - 33);
++      test_memmove(0, 0, 128);
++      test_memmove(4, 4, BUF_SIZE - 32 - 4);
++      test_memmove(1, 1, BUF_SIZE - 32 - 1);
++      test_memmove(1, 1, BUF_SIZE - 130);
++      test_memmove(0, 3, BUF_SIZE - 128);
++      test_memmove(1, 4, BUF_SIZE - 128);
++      test_memmove(0, 0, 0);
++
++      return 0;
++}
+Index: uClibc-0.9.28-avr32/libc/string/avr32/strlen.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/strlen.S     2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,52 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++#define str r12
++
++      .text
++      .global strlen
++      .type   strlen, @function
++strlen:
++      mov     r11, r12
++
++      mov     r9, str
++      andl    r9, 3, COH
++      brne    .Lunaligned_str
++
++1:    ld.w    r8, str++
++      tnbz    r8
++      brne    1b
++
++      sub     r12, r11
++      bfextu  r9, r8, 24, 8
++      cp.w    r9, 0
++      subeq   r12, 4
++      reteq   r12
++      bfextu  r9, r8, 16, 8
++      cp.w    r9, 0
++      subeq   r12, 3
++      reteq   r12
++      bfextu  r9, r8, 8, 8
++      cp.w    r9, 0
++      subeq   r12, 2
++      reteq   r12
++      sub     r12, 1
++      retal   r12
++
++.Lunaligned_str:
++      add     pc, pc, r9 << 3
++      sub     r0, r0, 0       /* 4-byte nop */
++      ld.ub   r8, str++
++      sub     r8, r8, 0
++      breq    1f
++      ld.ub   r8, str++
++      sub     r8, r8, 0
++      breq    1f
++      ld.ub   r8, str++
++      sub     r8, r8, 0
++      brne    1b
++
++1:    sub     r12, 1
++      sub     r12, r11
++      retal   r12
+Index: uClibc-0.9.28-avr32/libc/string/avr32/strncpy.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/strncpy.S    2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,77 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++#define dst r9
++#define src r11
++
++      .text
++      .global strcpy
++      .type   strncpy, @function
++strncpy:
++      mov     dst, r12
++
++      pref    src[0]
++      mov     dst, r12
++
++      /*
++       * Check alignment. If src is aligned but dst isn't, we can't
++       * do much about it...
++       */
++      mov     r8, src
++      andl    r8, 3 COH
++      brne    .Lunaligned_src
++
++.Laligned_copy:
++      sub     r10, 4
++      brlt    3f
++1:    ld.w    r8, src++
++      tnbz    r8
++      breq    2f
++      st.w    dst++, r8
++      sub     r10, 4
++      brne    1b
++
++3:    sub     r10, -4
++      reteq   r12
++
++      /* This is safe as long as src is word-aligned and r10 > 0 */
++      ld.w    r8, src++
++
++2:    /*
++       * Ok, r8 now contains the terminating '\0'. Copy the
++       * remaining bytes individually.
++       */
++      bfextu  r11, r8, 24, 8
++      st.b    dst++, r11
++      cp.w    r11, 0
++      reteq   r12
++      sub     r10, 1
++      reteq   r12
++      bfextu  r11, r8, 16, 8
++      st.b    dst++, r11
++      cp.w    r11, 0
++      reteq   r12
++      sub     r10, 1
++      reteq   r12
++      bfextu  r11, r8, 8, 8
++      st.b    dst++, r11
++      cp.w    r11, 0
++      reteq   r12
++      sub     r10, 1
++      reteq   r12
++      st.b    dst++, r8
++      retal   r12
++
++.Lunaligned_src:
++      /* Copy bytes until we're aligned */
++      min     r8, r8, r10
++      sub     r10, r8
++      sub     r8, 1
++      retlt   r12
++1:    ld.ub   r10, src++
++      st.b    dst++, r10
++      sub     r8, 1
++      brge    1b
++
++      rjmp    .Laligned_copy
+Index: uClibc-0.9.28-avr32/libc/string/avr32/test_memcpy.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/test_memcpy.c        2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,66 @@
++
++#include <stdio.h>
++#include <string.h>
++
++#define BUF_SIZE 32768
++
++static char buf1[BUF_SIZE] __attribute__((aligned(32)));
++static char buf1_ref[BUF_SIZE] __attribute__((aligned(32)));
++static char buf2[BUF_SIZE] __attribute__((aligned(32)));
++
++extern void *new_memcpy(void *dest, void *src, size_t len);
++
++void dump_mismatch(char *buf, char *ref, size_t len)
++{
++      int i, j;
++
++      for (i = 0; i < len; i += 16) {
++              if (memcmp(buf + i, ref + i, 16) == 0)
++                      continue;
++
++              printf("% 4x buf:", i);
++              for (j = i; j < (i + 16); j++)
++                      printf(" %02x", buf[j]);
++              printf("\n     ref:");
++              for (j = i; j < (i + 16); j++)
++                      printf(" %02x", ref[j]);
++              printf("\n");
++      }
++}
++
++void test(int src_offset, int dst_offset, int len)
++{
++      memset(buf1, 0x55, sizeof(buf1));
++      memset(buf1_ref, 0x55, sizeof(buf1_ref));
++      memset(buf2, 0xaa, sizeof(buf2));
++
++      printf("Testing with offsets %d => %d and len %d...",
++             src_offset, dst_offset, len);
++
++      new_memcpy(buf1 + dst_offset, buf2 + src_offset, len);
++      memcpy(buf1_ref + dst_offset, buf2 + src_offset, len);
++
++      if (memcmp(buf1, buf1_ref, sizeof(buf1)) == 0)
++              printf("OK\n");
++      else {
++              printf("FAILED\n");
++              dump_mismatch(buf1, buf1_ref, sizeof(buf1));
++      }
++}
++
++int main(int argc, char *argv[])
++{
++      test(0, 0, BUF_SIZE);
++      test(0, 0, 1);
++      test(0, 0, 31);
++      test(0, 0, 32);
++      test(0, 0, 127);
++      test(0, 0, 128);
++      test(4, 4, BUF_SIZE - 4);
++      test(1, 1, BUF_SIZE - 1);
++      test(1, 1, 126);
++      test(0, 3, 128);
++      test(1, 4, 128);
++
++      return 0;
++}
+Subject: [PATCH] Don't include create_module() for AVR32
+
+The create_module() system call is obsolete in Linux 2.6, so the
+AVR32 kernel doesn't even have it.
+
+Come to think about it, this should be completely unnecessary as the
+create_module function is only a stub when __NR_create_module is
+undefined.
+---
+
+ libc/sysdeps/linux/common/create_module.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+Index: uClibc-0.9.28/libc/sysdeps/linux/common/create_module.c
+===================================================================
+--- uClibc-0.9.28.orig/libc/sysdeps/linux/common/create_module.c       2006-02-07 16:48:38.000000000 +0100
++++ uClibc-0.9.28/libc/sysdeps/linux/common/create_module.c    2006-02-07 17:17:14.000000000 +0100
+@@ -61,7 +61,8 @@ unsigned long create_module(const char *
+ {
+   return __create_module(name, size, 0, 0);
+ }
+-#else
++/* create_module is obsolete in Linux 2.6, so AVR32 doesn't have it */
++#elif !defined(__avr32__)
+ /* Sparc, MIPS, etc don't mistake return values for errors. */ 
+ _syscall2(unsigned long, create_module, const char *, name, size_t, size);
+ #endif
+Subject: [PATCH] ldso: Always inline _dl_memcpy()
+
+On some gcc versions, inline is merely a hint. AVR32 depends on this
+function actually getting inlined, so we need to use __always_inline
+instead of just inline.
+
+---
+
+ ldso/include/dl-string.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: uClibc-0.9.28/ldso/include/dl-string.h
+===================================================================
+--- uClibc-0.9.28.orig/ldso/include/dl-string.h        2006-02-07 17:01:28.000000000 +0100
++++ uClibc-0.9.28/ldso/include/dl-string.h     2006-02-07 17:03:02.000000000 +0100
+@@ -134,7 +134,7 @@ static inline char * _dl_strstr(const ch
+     } while (1);
+ }
+-static inline void * _dl_memcpy(void * dst, const void * src, size_t len)
++static __always_inline void * _dl_memcpy(void * dst, const void * src, size_t len)
+ {
+       register char *a = dst-1;
+       register const char *b = src-1;
+Subject: [PATCH] ldso: Define MAP_FAILED for _dl_mmap()
+
+When using mmap2() to emulate mmap(), _dl_mmap() uses MAP_FAILED to
+indicate failure. MAP_FAILED is not defined anywhere, so this patch
+defines it.
+
+---
+
+ ldso/include/dl-syscall.h |    1 +
+ 1 file changed, 1 insertion(+)
+
+Index: uClibc-0.9.28/ldso/include/dl-syscall.h
+===================================================================
+--- uClibc-0.9.28.orig/ldso/include/dl-syscall.h       2006-02-07 16:49:27.000000000 +0100
++++ uClibc-0.9.28/ldso/include/dl-syscall.h    2006-02-07 17:07:06.000000000 +0100
+@@ -132,6 +132,7 @@ static inline _syscall6(__ptr_t, __sysca
+               size_t, len, int, prot, int, flags, int, fd, off_t, offset);
+ /*always 12, even on architectures where PAGE_SHIFT != 12 */
+ #define MMAP2_PAGE_SHIFT 12
++#define MAP_FAILED ((void *) -1)
+ static inline void * _dl_mmap(void * addr, unsigned long size, int prot,
+               int flags, int fd, unsigned long offset)
+ {
+Subject: [PATCH] ldso: Always inline system calls
+
+Some versions of gcc consider inline merely a hint. AVR32 depends on
+the system calls actually being inlined, so we need to use
+__always_inline instead of just inline.
+
+---
+
+ ldso/include/dl-syscall.h |   38 +++++++++++++++++++-------------------
+ 1 file changed, 19 insertions(+), 19 deletions(-)
+
+Index: uClibc-0.9.28/ldso/include/dl-syscall.h
+===================================================================
+--- uClibc-0.9.28.orig/ldso/include/dl-syscall.h       2006-02-07 17:07:06.000000000 +0100
++++ uClibc-0.9.28/ldso/include/dl-syscall.h    2006-02-07 17:08:47.000000000 +0100
+@@ -60,59 +60,59 @@
+    dynamic linking at all, so we cannot return any error codes.
+    We just punt if there is an error. */
+ #define __NR__dl_exit __NR_exit
+-static inline _syscall1(void, _dl_exit, int, status);
++static __always_inline _syscall1(void, _dl_exit, int, status);
+ #define __NR__dl_close __NR_close
+-static inline _syscall1(int, _dl_close, int, fd);
++static __always_inline _syscall1(int, _dl_close, int, fd);
+ #define __NR__dl_open __NR_open
+-static inline _syscall3(int, _dl_open, const char *, fn, int, flags, __kernel_mode_t, mode);
++static __always_inline _syscall3(int, _dl_open, const char *, fn, int, flags, __kernel_mode_t, mode);
+ #define __NR__dl_write __NR_write
+-static inline _syscall3(unsigned long, _dl_write, int, fd,
++static __always_inline _syscall3(unsigned long, _dl_write, int, fd,
+           const void *, buf, unsigned long, count);
+ #define __NR__dl_read __NR_read
+-static inline _syscall3(unsigned long, _dl_read, int, fd,
++static __always_inline _syscall3(unsigned long, _dl_read, int, fd,
+           const void *, buf, unsigned long, count);
+ #define __NR__dl_mprotect __NR_mprotect
+-static inline _syscall3(int, _dl_mprotect, const void *, addr, unsigned long, len, int, prot);
++static __always_inline _syscall3(int, _dl_mprotect, const void *, addr, unsigned long, len, int, prot);
+ #define __NR__dl_stat __NR_stat
+-static inline _syscall2(int, _dl_stat, const char *, file_name, struct stat *, buf);
++static __always_inline _syscall2(int, _dl_stat, const char *, file_name, struct stat *, buf);
+ #define __NR__dl_munmap __NR_munmap
+-static inline _syscall2(int, _dl_munmap, void *, start, unsigned long, length);
++static __always_inline _syscall2(int, _dl_munmap, void *, start, unsigned long, length);
+ #define __NR__dl_getuid __NR_getuid
+-static inline _syscall0(uid_t, _dl_getuid);
++static __always_inline _syscall0(uid_t, _dl_getuid);
+ #define __NR__dl_geteuid __NR_geteuid
+-static inline _syscall0(uid_t, _dl_geteuid);
++static __always_inline _syscall0(uid_t, _dl_geteuid);
+ #define __NR__dl_getgid __NR_getgid
+-static inline _syscall0(gid_t, _dl_getgid);
++static __always_inline _syscall0(gid_t, _dl_getgid);
+ #define __NR__dl_getegid __NR_getegid
+-static inline _syscall0(gid_t, _dl_getegid);
++static __always_inline _syscall0(gid_t, _dl_getegid);
+ #define __NR__dl_getpid __NR_getpid
+-static inline _syscall0(gid_t, _dl_getpid);
++static __always_inline _syscall0(gid_t, _dl_getpid);
+ #define __NR__dl_readlink __NR_readlink
+-static inline _syscall3(int, _dl_readlink, const char *, path, char *, buf, size_t, bufsiz);
++static __always_inline _syscall3(int, _dl_readlink, const char *, path, char *, buf, size_t, bufsiz);
+ #ifdef __NR_mmap
+ #ifdef MMAP_HAS_6_ARGS
+ #define __NR__dl_mmap __NR_mmap
+-static inline _syscall6(void *, _dl_mmap, void *, start, size_t, length,
++static __always_inline _syscall6(void *, _dl_mmap, void *, start, size_t, length,
+               int, prot, int, flags, int, fd, off_t, offset);
+ #else
+ #define __NR__dl_mmap_real __NR_mmap
+-static inline _syscall1(void *, _dl_mmap_real, unsigned long *, buffer);
++static __always_inline _syscall1(void *, _dl_mmap_real, unsigned long *, buffer);
+-static inline void * _dl_mmap(void * addr, unsigned long size, int prot,
++static __always_inline void * _dl_mmap(void * addr, unsigned long size, int prot,
+               int flags, int fd, unsigned long offset)
+ {
+       unsigned long buffer[6];
+@@ -128,12 +128,12 @@ static inline void * _dl_mmap(void * add
+ #endif
+ #elif defined __NR_mmap2
+ #define __NR___syscall_mmap2       __NR_mmap2
+-static inline _syscall6(__ptr_t, __syscall_mmap2, __ptr_t, addr,
++static __always_inline _syscall6(__ptr_t, __syscall_mmap2, __ptr_t, addr,
+               size_t, len, int, prot, int, flags, int, fd, off_t, offset);
+ /*always 12, even on architectures where PAGE_SHIFT != 12 */
+ #define MMAP2_PAGE_SHIFT 12
+ #define MAP_FAILED ((void *) -1)
+-static inline void * _dl_mmap(void * addr, unsigned long size, int prot,
++static __always_inline void * _dl_mmap(void * addr, unsigned long size, int prot,
+               int flags, int fd, unsigned long offset)
+ {
+     if (offset & ((1 << MMAP2_PAGE_SHIFT) - 1))
+Subject: [PATCH] ldso: AVR32 support
+
+This implements the AVR32-specific parts of the dynamic linker.
+
+---
+
+ ldso/ldso/avr32/dl-debug.h    |   45 +++++++++
+ ldso/ldso/avr32/dl-startup.h  |  110 ++++++++++++++++++++++++
+ ldso/ldso/avr32/dl-syscalls.h |    5 +
+ ldso/ldso/avr32/dl-sysdep.h   |  103 ++++++++++++++++++++++
+ ldso/ldso/avr32/elfinterp.c   |  191 ++++++++++++++++++++++++++++++++++++++++++
+ ldso/ldso/avr32/resolve.S     |   28 ++++++
+ 6 files changed, 482 insertions(+)
+
+Index: uClibc-0.9.28/ldso/ldso/avr32/dl-debug.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/ldso/ldso/avr32/dl-debug.h   2006-05-05 09:30:43.000000000 +0200
+@@ -0,0 +1,45 @@
++/*
++ * AVR32 ELF shared libary loader support
++ *
++ * Copyright (C) 2005 Atmel Norway
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. The name of the above contributors may not be
++ *    used to endorse or promote products derived from this software
++ *    without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ */
++
++static const char *_dl_reltypes_tab[] = {
++    "R_AVR32_NONE",
++    "R_AVR32_32", "R_AVR32_16", "R_AVR32_8",
++    "R_AVR32_32_PCREL", "R_AVR32_16_PCREL", "R_AVR32_8_PCREL",
++    "R_AVR32_DIFF32", "R_AVR32_DIFF16", "R_AVR32_DIFF8",
++    "R_AVR32_GOT32", "R_AVR32_GOT16", "R_AVR32_GOT8",
++    "R_AVR32_21S", "R_AVR32_16U", "R_AVR32_16S", "R_AVR32_8S", "R_AVR32_8S_EXT",
++    "R_AVR32_22H_PCREL", "R_AVR32_18W_PCREL", "R_AVR32_16B_PCREL",
++    "R_AVR32_16N_PCREL", "R_AVR32_14UW_PCREL", "R_AVR32_11H_PCREL",
++    "R_AVR32_10UW_PCREL", "R_AVR32_9H_PCREL", "R_AVR32_9UW_PCREL",
++    "R_AVR32_HI16", "R_AVR32_LO16",
++    "R_AVR32_GOTPC", "R_AVR32_GOTCALL", "R_AVR32_LDA_GOT",
++    "R_AVR32_GOT21S", "R_AVR32_GOT18SW", "R_AVR32_GOT16S", "R_AVR32_GOT7UW",
++    "R_AVR32_32_CPENT", "R_AVR32_CPCALL", "R_AVR32_16_CP", "R_AVR32_9W_CP",
++    "R_AVR32_RELATIVE", "R_AVR32_GLOB_DAT", "R_AVR32_JMP_SLOT",
++    "R_AVR32_ALIGN",
++};
+Index: uClibc-0.9.28/ldso/ldso/avr32/dl-startup.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/ldso/ldso/avr32/dl-startup.h 2006-05-05 09:29:45.000000000 +0200
+@@ -0,0 +1,110 @@
++/* vi: set sw=4 ts=4: */
++/*
++ * Architecture specific code used by dl-startup.c
++ * Copyright (C) 2005 Atmel Norway
++ */
++
++/* This is the library loader's main entry point. Let _dl_boot2 do its
++ * initializations and jump to the application's entry point
++ * afterwards. */
++asm(  "       .text\n"
++      "       .global _start\n"
++      "       .type   _start,@function\n"
++      "_start:\n"
++      /* All arguments are on the stack initially */
++      "       mov     r12, sp\n"
++      "       rcall   _dl_start\n"
++      /* Returns user entry point in r12. Save it. */
++      "       mov     r0, r12\n"
++      /* We're PIC, so get the Global Offset Table */
++      "       lddpc   r6, .L_GOT\n"
++      ".L_RGOT:\n"
++      "       rsub    r6, pc\n"
++      /* Adjust argc and argv according to _dl_skip_args */
++      "       ld.w    r1, r6[_dl_skip_args@got]\n"
++      "       ld.w    r1, r1[0]\n"
++      "       ld.w    r2, sp++\n"
++      "       sub     r2, r1\n"
++      "       add     sp, sp, r1 << 2\n"
++      "       st.w    --sp, r2\n"
++      /* Load the finalizer function */
++      "       ld.w    r12, r6[_dl_fini@got]\n"
++      /* Jump to the user's entry point */
++      "       mov     pc, r0\n\n"
++
++      "       .align  2\n"
++      ".L_GOT:"
++      "       .long   .L_RGOT - _GLOBAL_OFFSET_TABLE_\n"
++      "       .size   _start, . - _start\n"
++      "       .previous\n");
++
++/* Get a pointer to the argv array.  On many platforms this can be just
++ * the address if the first argument, on other platforms we need to
++ * do something a little more subtle here. */
++#define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned long *)ARGS + 1)
++
++
++/* We can't call functions before the GOT has been initialized */
++#define NO_FUNCS_BEFORE_BOOTSTRAP
++
++/*
++ * Relocate the GOT during dynamic loader bootstrap.  This will add
++ * the load address to all entries in the GOT, which is necessary
++ * because the linker doesn't generate R_AVR32_RELATIVE relocs for the
++ * GOT.
++ */
++static __always_inline
++void PERFORM_BOOTSTRAP_GOT(struct elf_resolve *tpnt)
++{
++      Elf32_Addr i, nr_got;
++      register Elf32_Addr *__r6 __asm__("r6");
++      Elf32_Addr *got = __r6;
++
++      nr_got = tpnt->dynamic_info[DT_AVR32_GOTSZ_IDX] / sizeof(*got);
++      for (i = 2; i < nr_got; i++)
++              got[i] += tpnt->loadaddr;
++}
++
++#define PERFORM_BOOTSTRAP_GOT(tpnt) PERFORM_BOOTSTRAP_GOT(tpnt)
++
++/* Handle relocation of the symbols in the dynamic loader. */
++static __always_inline
++void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, unsigned long *reloc_addr,
++                           unsigned long symbol_addr,
++                           unsigned long load_addr, Elf32_Sym *symtab)
++{
++      switch(ELF32_R_TYPE(rpnt->r_info)) {
++      case R_AVR32_NONE:
++              break;
++      case R_AVR32_GLOB_DAT:
++      case R_AVR32_JMP_SLOT:
++              *reloc_addr = symbol_addr;
++              break;
++      case R_AVR32_RELATIVE:
++              SEND_STDERR_DEBUG("Applying RELATIVE relocation: ");
++              SEND_ADDRESS_STDERR_DEBUG(load_addr, 0);
++              SEND_STDERR_DEBUG(" + ");
++              SEND_ADDRESS_STDERR_DEBUG(rpnt->r_addend, 1);
++              *reloc_addr = load_addr + rpnt->r_addend;
++              break;
++      default:
++              SEND_STDERR("BOOTSTRAP_RELOC: unhandled reloc_type ");
++              SEND_NUMBER_STDERR(ELF32_R_TYPE(rpnt->r_info), 1);
++              SEND_STDERR("REL, SYMBOL, LOAD: ");
++              SEND_ADDRESS_STDERR(reloc_addr, 0);
++              SEND_STDERR(", ");
++              SEND_ADDRESS_STDERR(symbol_addr, 0);
++              SEND_STDERR(", ");
++              SEND_ADDRESS_STDERR(load_addr, 1);
++              _dl_exit(1);
++      }
++}
++
++/* Transfer control to the user's application, once the dynamic loader
++ * is done. This routine has to exit the current function, then call
++ * the _dl_elf_main function.
++ *
++ * Since our _dl_boot will simply call whatever is returned by
++ * _dl_boot2, we can just return the address we're supposed to
++ * call.  */
++#define START()       return _dl_elf_main;
+Index: uClibc-0.9.28/ldso/ldso/avr32/dl-syscalls.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/ldso/ldso/avr32/dl-syscalls.h        2006-05-05 09:29:25.000000000 +0200
+@@ -0,0 +1,5 @@
++/* We can't use the real errno in ldso, since it has not yet
++ * been dynamicly linked in yet. */
++extern int _dl_errno;
++#define __set_errno(X) {(_dl_errno) = (X);}
++#include "sys/syscall.h"
+Index: uClibc-0.9.28/ldso/ldso/avr32/dl-sysdep.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/ldso/ldso/avr32/dl-sysdep.h  2006-05-05 09:30:43.000000000 +0200
+@@ -0,0 +1,103 @@
++/* vi: set sw=4 ts=4: */
++/*
++ * Various assembly language/system dependent hacks that are required
++ * so that we can minimize the amount of platform specific code.
++ * Copyright (C) 2004-2005 Atmel Norway
++ */
++
++/* Define this if the system uses RELOCA. */
++#define ELF_USES_RELOCA
++
++#include <elf.h>
++
++#define ARCH_NUM 1
++#define DT_AVR32_GOTSZ_IDX    (DT_NUM + OS_NUM)
++
++#define ARCH_DYNAMIC_INFO(dpnt, dynamic, debug_addr)                  \
++      do {                                                            \
++              if (dpnt->d_tag == DT_AVR32_GOTSZ)                      \
++                      dynamic[DT_AVR32_GOTSZ_IDX] = dpnt->d_un.d_val; \
++      } while (0)
++
++/* Initialization sequence for the application/library GOT. */
++#define INIT_GOT(GOT_BASE,MODULE)                                     \
++      do {                                                            \
++              unsigned long i, nr_got;                                \
++                                                                      \
++              GOT_BASE[0] = (unsigned long) _dl_linux_resolve;        \
++              GOT_BASE[1] = (unsigned long) MODULE;                   \
++                                                                      \
++              /* Add load address displacement to all GOT entries */  \
++              nr_got = MODULE->dynamic_info[DT_AVR32_GOTSZ_IDX] / 4;  \
++              for (i = 2; i < nr_got; i++)                            \
++                      GOT_BASE[i] += (unsigned long)MODULE->loadaddr; \
++      } while (0)
++
++#define do_rem(result, n, base)       ((result) = (n) % (base))
++
++/* Here we define the magic numbers that this dynamic loader should accept */
++#define MAGIC1 EM_AVR32
++#undef MAGIC2
++
++/* Used for error messages */
++#define ELF_TARGET "AVR32"
++
++unsigned long _dl_linux_resolver(unsigned long got_offset, unsigned long *got);
++
++/* 4096 bytes alignment */
++#define PAGE_ALIGN 0xfffff000
++#define ADDR_ALIGN 0xfff
++#define OFFS_ALIGN 0x7ffff000
++
++#define elf_machine_type_class(type)                          \
++      ((type == R_AVR32_JMP_SLOT) * ELF_RTYPE_CLASS_PLT)
++
++/* AVR32 doesn't need any COPY relocs */
++#define DL_NO_COPY_RELOCS
++
++/* Return the link-time address of _DYNAMIC.  Conveniently, this is the
++   first element of the GOT.  This must be inlined in a function which
++   uses global data.  */
++static inline Elf32_Addr
++elf_machine_dynamic (void)
++{
++      register Elf32_Addr *got asm ("r6");
++      return *got;
++}
++
++/* Return the run-time load address of the shared object.  */
++static inline Elf32_Addr
++elf_machine_load_address (void)
++{
++      extern void __dl_start asm("_dl_start");
++      Elf32_Addr got_addr = (Elf32_Addr) &__dl_start;
++      Elf32_Addr pcrel_addr;
++
++      asm   ("        lddpc   %0, 2f\n"
++             "1:      add     %0, pc\n"
++             "        rjmp    3f\n"
++             "        .align  2\n"
++             "2:      .long   _dl_start - 1b\n"
++             "3:\n"
++             : "=r"(pcrel_addr) : : "cc");
++
++      return pcrel_addr - got_addr;
++}
++
++/*
++ * Perform any RELATIVE relocations specified by DT_RELCOUNT.
++ * Currently, we don't use that tag, but we might in the future as
++ * this would reduce the startup time somewhat (although probably not by much).
++ */
++static inline void
++elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr,
++                    Elf32_Word relative_count)
++{
++      Elf32_Rela *rpnt = (void *)rel_addr;
++
++      do {
++              Elf32_Addr *reloc_addr;
++              reloc_addr = (void *)(load_off + (rpnt++)->r_offset);
++              *reloc_addr = load_off + rpnt->r_addend;
++      } while (--relative_count);
++}
+Index: uClibc-0.9.28/ldso/ldso/avr32/elfinterp.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/ldso/ldso/avr32/elfinterp.c  2006-05-05 09:30:43.000000000 +0200
+@@ -0,0 +1,191 @@
++/*
++ * AVR32 ELF shared library loader suppport
++ *
++ * Copyright (C) 2004-2006 Atmel Corporation
++ *
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. The name of the above contributors may not be
++ *    used to endorse or promote products derived from this software
++ *    without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ */
++
++unsigned long _dl_linux_resolver(unsigned long got_offset, unsigned long *got)
++{
++      struct elf_resolve *tpnt = (struct elf_resolve *)got[1];
++      Elf32_Sym *sym;
++      unsigned long local_gotno;
++      unsigned long gotsym;
++      unsigned long new_addr;
++      char *strtab, *symname;
++      unsigned long *entry;
++      unsigned long sym_index = got_offset / 4;
++
++#if 0
++      local_gotno = tpnt->dynamic_info[DT_AVR32_LOCAL_GOTNO];
++      gotsym = tpnt->dynamic_info[DT_AVR32_GOTSYM];
++
++      sym = ((Elf32_Sym *)(tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr))
++              + sym_index;
++      strtab = (char *)(tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
++      symname = strtab + sym->st_name;
++
++#if 0
++      new_addr = (unsigned long) _dl_find_hash(strtab + sym->st_name,
++                                               tpnt->symbol_scope, tpnt,
++                                               resolver);
++#endif
++
++      entry = (unsigned long *)(got + local_gotno + sym_index - gotsym);
++      *entry = new_addr;
++#endif
++
++      return new_addr;
++}
++
++static int
++_dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope,
++        unsigned long rel_addr, unsigned long rel_size,
++        int (*reloc_func)(struct elf_resolve *tpnt, struct dyn_elf *scope,
++                          Elf32_Rela *rpnt, Elf32_Sym *symtab, char *strtab))
++{
++      Elf32_Sym *symtab;
++      Elf32_Rela *rpnt;
++      char *strtab;
++      int i;
++
++      rpnt = (Elf32_Rela *)rel_addr;
++      rel_size /= sizeof(Elf32_Rela);
++      symtab = (Elf32_Sym *)tpnt->dynamic_info[DT_SYMTAB];
++      strtab = (char *)tpnt->dynamic_info[DT_STRTAB];
++
++      for (i = 0; i < rel_size; i++, rpnt++) {
++              int symtab_index, res;
++
++              symtab_index = ELF32_R_SYM(rpnt->r_info);
++
++              debug_sym(symtab, strtab, symtab_index);
++              debug_reloc(symtab, strtab, rpnt);
++
++              res = reloc_func(tpnt, scope, rpnt, symtab, strtab);
++
++              if (res == 0)
++                      continue;
++
++              _dl_dprintf(2, "\n%s: ", _dl_progname);
++
++              if (symtab_index)
++                      _dl_dprintf(2, "symbol '%s': ",
++                                  strtab + symtab[symtab_index].st_name);
++
++              if (res < 0) {
++                      int reloc_type = ELF32_R_TYPE(rpnt->r_info);
++#if defined(__SUPPORT_LD_DEBUG__)
++                      _dl_dprintf(2, "can't handle reloc type %s\n",
++                                  _dl_reltypes(reloc_type));
++#else
++                      _dl_dprintf(2, "can't handle reloc type %x\n",
++                                  reloc_type);
++#endif
++                      _dl_exit(-res);
++              } else {
++                      _dl_dprintf(2, "can't resolve symbol\n");
++                      return res;
++              }
++      }
++
++      return 0;
++}
++
++static int _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
++                      Elf32_Rela *rpnt, Elf32_Sym *symtab, char *strtab)
++{
++      int reloc_type;
++      int symtab_index;
++      char *symname;
++      unsigned long *reloc_addr;
++      unsigned long symbol_addr;
++#if defined(__SUPPORT_LD_DEBUG__)
++      unsigned long old_val;
++#endif
++
++      reloc_addr = (unsigned long *)(tpnt->loadaddr + rpnt->r_offset);
++      reloc_type = ELF32_R_TYPE(rpnt->r_info);
++      symtab_index = ELF32_R_SYM(rpnt->r_info);
++      symbol_addr = 0;
++      symname = strtab + symtab[symtab_index].st_name;
++
++      if (symtab_index) {
++              symbol_addr = (unsigned long)
++                      _dl_find_hash(strtab + symtab[symtab_index].st_name,
++                                    tpnt->symbol_scope, tpnt,
++                                    elf_machine_type_class(reloc_type));
++
++              /* Allow undefined references to weak symbols */
++              if (!symbol_addr &&
++                  ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK) {
++                      _dl_dprintf(2, "%s: can't resolve symbol '%s'\n",
++                                  _dl_progname, symname);
++                      return 0;
++              }
++      }
++
++#if defined(__SUPPORT_LD_DEBUG__)
++      old_val = *reloc_addr;
++#endif
++      switch (reloc_type) {
++      case R_AVR32_NONE:
++              break;
++      case R_AVR32_GLOB_DAT:
++      case R_AVR32_JMP_SLOT:
++              *reloc_addr = symbol_addr + rpnt->r_addend;
++              break;
++      case R_AVR32_RELATIVE:
++              *reloc_addr = (unsigned long)tpnt->loadaddr
++                      + rpnt->r_addend;
++              break;
++      default:
++              return -1;
++      }
++
++#if defined(__SUPPORT_LD_DEBUG__)
++      if (_dl_debug_reloc && _dl_debug_detail)
++              _dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x\n",
++                          old_val, *reloc_addr);
++#endif
++
++      return 0;
++}
++
++void _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt,
++                                         unsigned long rel_addr,
++                                         unsigned long rel_size)
++{
++      /* TODO: Might want to support this in order to get faster
++       * startup times... */
++}
++
++int _dl_parse_relocation_information(struct dyn_elf *rpnt,
++                                   unsigned long rel_addr,
++                                   unsigned long rel_size)
++{
++      return _dl_parse(rpnt->dyn, rpnt->dyn->symbol_scope, rel_addr, rel_size,
++                       _dl_do_reloc);
++}
+Index: uClibc-0.9.28/ldso/ldso/avr32/resolve.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/ldso/ldso/avr32/resolve.S    2006-05-05 09:29:25.000000000 +0200
+@@ -0,0 +1,28 @@
++/*
++ * Linux dynamic resolving code for AVR32. Fixes up the GOT entry as
++ * indicated in register r12 and jumps to the resolved address.
++ *
++ * 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.
++ *
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++#define ip r5
++
++      .text
++      .global _dl_linux_resolve
++      .type   _dl_linux_resolve,@function
++_dl_linux_resolve:
++      /* The PLT code pushed r8 for us. It contains the address of this
++         function's GOT entry, that is entry 0. ip contains the address
++         of the GOT entry of the function we wanted to call. */
++      stm     --sp, r9-r12, lr
++      mov     r11, r8
++      sub     r12, ip, r8
++      rcall   _dl_linux_resolver
++      mov     ip, r12
++      popm    r8-r12,lr
++      mov     pc, ip
++      .size   _dl_linux_resolve, . - _dl_linux_resolve
+Subject: [PATCH] ldso: AVR32 needs CONSTANT_STRING_GOT_FIXUP
+
+Add AVR32 to the list of architectures needing CONSTANT_STRING_GOT_FIXUP.
+
+---
+
+ ldso/include/dl-string.h |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+Index: uClibc-0.9.28/ldso/include/dl-string.h
+===================================================================
+--- uClibc-0.9.28.orig/ldso/include/dl-string.h        2006-02-07 16:58:58.000000000 +0100
++++ uClibc-0.9.28/ldso/include/dl-string.h     2006-02-07 16:59:28.000000000 +0100
+@@ -271,7 +271,8 @@ static __always_inline char * _dl_simple
+ /* On some arches constant strings are referenced through the GOT.
+  * This requires that load_addr must already be defined... */
+ #if defined(mc68000) || defined(__arm__) || defined(__mips__) \
+-                     || defined(__sh__) ||  defined(__powerpc__)
++                     || defined(__sh__) ||  defined(__powerpc__) \
++                   || defined(__avr32__)
+ # define CONSTANT_STRING_GOT_FIXUP(X) \
+       if ((X) < (const char *) load_addr) (X) += load_addr
+ # define NO_EARLY_SEND_STDERR
+Subject: [PATCH] ldso: AVR32 startup hack
+
+AVR32 needs to do both PERFORM_BOOTSTRAP_GOT and a full relocation of
+the GOT. I don't quite remember why, but I think it's because some GOT
+entries just need the load address added to them, while the rest need
+the full relocation code.
+
+This patch should be revisited to figure out whether we're processing
+relocations against undefined symbols and whether that's something we
+should be doing...
+
+---
+
+ ldso/ldso/dl-startup.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+Index: uClibc-0.9.28/ldso/ldso/dl-startup.c
+===================================================================
+--- uClibc-0.9.28.orig/ldso/ldso/dl-startup.c  2006-02-07 16:49:27.000000000 +0100
++++ uClibc-0.9.28/ldso/ldso/dl-startup.c       2006-02-07 17:12:09.000000000 +0100
+@@ -217,7 +217,9 @@ static void * __attribute_used__ _dl_sta
+       /* some arches (like MIPS) we have to tweak the GOT before relocations */
+       PERFORM_BOOTSTRAP_GOT(tpnt);
+-#else
++#endif
++
++#if !defined(PERFORM_BOOTSTRAP_GOT) || defined(__avr32__)
+       /* OK, now do the relocations.  We do not do a lazy binding here, so
+          that once we are done, we have considerably more flexibility. */
+@@ -259,7 +261,7 @@ static void * __attribute_used__ _dl_sta
+                               rel_addr += relative_count * sizeof(ELF_RELOC);;
+                       }
+-                      rpnt = (ELF_RELOC *) (rel_addr + load_addr);
++                      rpnt = (ELF_RELOC *) (rel_addr /* + load_addr */);
+                       for (i = 0; i < rel_size; i += sizeof(ELF_RELOC), rpnt++) {
+                               reloc_addr = (unsigned long *) (load_addr + (unsigned long) rpnt->r_offset);
+                               symtab_index = ELF_R_SYM(rpnt->r_info);
+Subject: [PATCH] ldd: AVR32 support
+
+Add AVR32-specific definitions to ldd.
+
+---
+
+ utils/ldd.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+Index: uClibc-0.9.28/utils/ldd.c
+===================================================================
+--- uClibc-0.9.28.orig/utils/ldd.c     2006-02-07 16:48:02.000000000 +0100
++++ uClibc-0.9.28/utils/ldd.c  2006-02-07 17:13:00.000000000 +0100
+@@ -56,6 +56,11 @@
+ #define ELFCLASSM     ELFCLASS32
+ #endif
++#if defined(__avr32__)
++#define MATCH_MACHINE(x) (x == EM_AVR32)
++#define ELFCLASSM     ELFCLASS32
++#endif
++
+ #if defined(__s390__)
+ #define MATCH_MACHINE(x) (x == EM_S390)
+ #define ELFCLASSM     ELFCLASS32
+Subject: [PATCH] libpthread: AVR32 support
+
+Implement pt-machine.h for AVR32.
+---
+
+ libpthread/linuxthreads/sysdeps/avr32/pt-machine.h |   92 +++++++++++++++++++++
+ 1 file changed, 92 insertions(+)
+
+Index: uClibc-0.9.28/libpthread/linuxthreads/sysdeps/avr32/pt-machine.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libpthread/linuxthreads/sysdeps/avr32/pt-machine.h   2006-02-07 17:14:47.000000000 +0100
+@@ -0,0 +1,92 @@
++/* Machine-dependent pthreads configuration and inline functions.
++
++   Copyright (C) 2005 Atmel Norway
++   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; 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 _PT_MACHINE_H
++#define _PT_MACHINE_H   1
++
++#include <features.h>
++
++static inline int
++_test_and_set (int *p, int v) __THROW
++{
++      int result;
++
++      __asm__ __volatile__(
++              "/* Inline test and set */\n"
++              "1:     ssrf    5\n"
++              "       ld.w    %0, %2\n"
++              "       tst     %0, %3\n"
++              "       breq    2f\n"
++              "       stcond  %1, %3\n"
++              "       brne    1b\n"
++              "2:"
++              : "=&r"(result), "=m"(*p)
++              : "m"(*p), "r"(v)
++              : "memory", "cc");
++
++      return result;
++}
++
++#ifndef PT_EI
++# define PT_EI extern inline
++#endif
++
++extern long int testandset (int *spinlock);
++extern int __compare_and_swap (long int *p, long int oldval, long int newval);
++
++/* Spinlock implementation; required.  */
++PT_EI long int
++testandset (int *spinlock)
++{
++      return _test_and_set(spinlock, 1);
++}
++
++
++/* Get some notion of the current stack.  Need not be exactly the top
++   of the stack, just something somewhere in the current frame.  */
++#define CURRENT_STACK_FRAME  stack_pointer
++register char * stack_pointer __asm__ ("sp");
++
++/* Compare-and-swap for semaphores. */
++
++#define HAS_COMPARE_AND_SWAP
++PT_EI int
++__compare_and_swap(long int *p, long int oldval, long int newval)
++{
++      long int result, tmp;
++
++      __asm__ __volatile__(
++              "/* Inline compare and swap */\n"
++              "1:     ssrf    5\n"
++              "       ld.w    %1, %3\n"
++              "       cp.w    %1, %5\n"
++              "       sreq    %0\n"
++              "       brne    2f\n"
++              "       stcond  %2, %4\n"
++              "       brne    1b\n"
++              "2:"
++              : "=&r"(result), "=&r"(tmp), "=m"(*p)
++              : "m"(*p), "r"(newval), "r"(oldval)
++              : "cc", "memory");
++
++      return result;
++}
++
++#endif /* pt-machine.h */
+---
+ libc/sysdeps/linux/avr32/bits/fcntl.h |   33 +++++++++++++++++----------------
+ 1 file changed, 17 insertions(+), 16 deletions(-)
+
+Index: uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/bits/fcntl.h
+===================================================================
+--- uClibc-0.9.28-avr32.orig/libc/sysdeps/linux/avr32/bits/fcntl.h     2006-11-23 17:38:30.000000000 +0100
++++ uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/bits/fcntl.h  2006-11-23 17:52:15.000000000 +0100
+@@ -11,28 +11,29 @@
+ /* open/fcntl - O_SYNC is only implemented on blocks devices and on files
+    located on an ext2 file system */
+-#define O_ACCMODE       0003
+-#define O_RDONLY          00
+-#define O_WRONLY          01
+-#define O_RDWR                    02
+-#define O_CREAT                 0100  /* not fcntl */
+-#define O_EXCL                  0200  /* not fcntl */
+-#define O_NOCTTY        0400  /* not fcntl */
+-#define O_TRUNC                01000  /* not fcntl */
+-#define O_APPEND       02000
+-#define O_NONBLOCK     04000
++#define O_ACCMODE     00000003
++#define O_RDONLY      00000000
++#define O_WRONLY      00000001
++#define O_RDWR                00000002
++#define O_CREAT               00000100        /* not fcntl */
++#define O_EXCL                00000200        /* not fcntl */
++#define O_NOCTTY      00000400        /* not fcntl */
++#define O_TRUNC               00001000        /* not fcntl */
++#define O_APPEND      00002000
++#define O_NONBLOCK    00004000
+ #define O_NDELAY      O_NONBLOCK
+-#define O_SYNC                010000
+-#define O_ASYNC               020000
++#define O_SYNC                00010000
++#define O_ASYNC               00020000
+ #ifdef __USE_GNU
+-# define O_DIRECTORY  040000  /* must be a directory */
+-# define O_NOFOLLOW   0100000 /* don't follow links */
+-# define O_DIRECT     0200000 /* direct disk access */
++# define O_DIRECT     00040000        /* must be a directory */
++# define O_DIRECTORY  00200000        /* direct disk access */
++# define O_NOFOLLOW   00400000        /* don't follow links */
++# define O_NOATIME    01000000        /* don't set atime */
+ #endif
+ #ifdef __USE_LARGEFILE64
+-# define O_LARGEFILE  0400000
++# define O_LARGEFILE  00100000
+ #endif
+ /* For now Linux has synchronisity options for data and read operations.
diff --git a/toolchain/uClibc/uClibc-0.9.28-fix_includes.patch b/toolchain/uClibc/uClibc-0.9.28-fix_includes.patch
deleted file mode 100644 (file)
index 52c8967..0000000
+++ /dev/null
@@ -1,327 +0,0 @@
---- uClibc-0.9.28/Makefile.orig        2006-12-11 21:06:42.000000000 -0700
-+++ uClibc-0.9.28/Makefile     2006-12-11 21:06:53.000000000 -0700
-@@ -158,7 +158,7 @@
-       $(INSTALL) -d $(PREFIX)$(DEVEL_PREFIX)lib
-       $(INSTALL) -d $(PREFIX)$(DEVEL_PREFIX)include
-       -$(INSTALL) -m 644 lib/*.[ao] $(PREFIX)$(DEVEL_PREFIX)lib/
--      if [ "$(KERNEL_SOURCE)" == "$(DEVEL_PREFIX)" ] ; then \
-+      if [ "$(KERNEL_SOURCE)" = "$(DEVEL_PREFIX)" ] ; then \
-               extra_exclude="--exclude include/linux --exclude include/asm'*'" ; \
-       else \
-               extra_exclude="" ; \
---- uClibc-0.9.28/extra/scripts/fix_includes.sh.orig   2006-12-13 05:44:21.000000000 -0700
-+++ uClibc-0.9.28/extra/scripts/fix_includes.sh        2006-12-13 05:44:35.000000000 -0700
-@@ -1,183 +1,155 @@
- #!/bin/sh
--# Copyright (C) 2003 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
--
--usage () {
--    echo ""
--    echo "usage: "`basename $0`" -k KERNEL_SOURCE_DIRECTORY -t TARGET_ARCH"
--    echo ""
--    echo "This utility scans the KERNEL_SOURCE_DIRECTORY directory and"
--    echo "checks that it contains well formed kernel headers suitable"
--    echo "for inclusion as the include/linux/ directory provided by"
--    echo "uClibc."
--    echo ""
--    echo "If the specified kernel headers are present and already"
--    echo "configured for the architecture specified by TARGET_ARCH,"
--    echo "they will be used as-is."
--    echo ""
--    echo "If the specified kernel headers are missing entirely, this"
--    echo "script will return an error."
--    echo ""
--    echo "If the specified kernel headers are present, but are either"
--    echo "not yet configured or are configured for an architecture"
--    echo "different than that specified by TARGET_ARCH, this script"
--    echo "will attempt to 'fix' the kernel headers and make them"
--    echo "suitable for use by uClibc.  This fixing process may fail."
--    echo "It is therefore best to always provide kernel headers that"
--    echo "are already configured for the selected architecture."
--    echo ""
--    echo "Most Linux distributions provide 'kernel-headers' packages"
--    echo "that are suitable for use by uClibc."
--    echo ""
--    echo ""
--    exit 1;
-+# Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
-+#
-+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
-+#
-+
-+usage() {
-+      echo ""
-+      echo "usage: "`basename $0`" -k KERNEL_SOURCE_DIRECTORY -t TARGET_ARCH"
-+      echo ""
-+      echo "This utility scans the KERNEL_SOURCE_DIRECTORY directory and"
-+      echo "checks that it contains well formed kernel headers suitable"
-+      echo "for inclusion as the include/linux/ directory provided by"
-+      echo "uClibc."
-+      echo ""
-+      echo "If the specified kernel headers are present and already"
-+      echo "configured for the architecture specified by TARGET_ARCH,"
-+      echo "they will be used as-is."
-+      echo ""
-+      echo "If the specified kernel headers are missing entirely, this"
-+      echo "script will return an error."
-+      echo ""
-+      echo "If the specified kernel headers are present, but are either"
-+      echo "not yet configured or are configured for an architecture"
-+      echo "different than that specified by TARGET_ARCH, this script"
-+      echo "will attempt to 'fix' the kernel headers and make them"
-+      echo "suitable for use by uClibc.  This fixing process may fail."
-+      echo "It is therefore best to always provide kernel headers that"
-+      echo "are already configured for the selected architecture."
-+      echo ""
-+      echo "Most Linux distributions provide 'kernel-headers' packages"
-+      echo "that are suitable for use by uClibc."
-+      echo ""
-+      echo ""
-+      exit 1
- }
--HAS_MMU="y";
-+
-+#
-+# Parse our arguments
-+#
-+HAS_MMU="y"
- while [ -n "$1" ]; do
--    case $1 in
--      -k ) shift; if [ -n "$1" ]; then KERNEL_SOURCE=$1; shift; else usage; fi; ;;
--      -t ) shift; if [ -n "$1" ]; then TARGET_ARCH=$1; shift; else usage; fi; ;;
--      -n ) shift; HAS_MMU="n"; ;;
--      -* ) usage; ;;
--      * ) usage; ;;
--    esac;
--done;
-+      case $1 in
-+              -k ) shift; if [ -n "$1" ]; then KERNEL_SOURCE=$1; shift; else usage; fi; ;;
-+              -t ) shift; if [ -n "$1" ]; then TARGET_ARCH=$1; shift; else usage; fi; ;;
-+              -n ) shift; HAS_MMU="n"; ;;
-+              -* ) usage; ;;
-+              * ) usage; ;;
-+      esac
-+done
--if [ ! -f "$KERNEL_SOURCE/Makefile" -a ! -f "$KERNEL_SOURCE/include/linux/version.h" ]; then
--    echo "";
--    echo "";
--    echo "The file $KERNEL_SOURCE/Makefile or $KERNEL_SOURCE/include/linux/version.h is missing!";
--    echo "Perhaps your kernel source is broken?"
--    echo "";
--    echo "";
--    exit 1;
--fi;
--if [ ! -d "$KERNEL_SOURCE" ]; then
--    echo "";
--    echo "";
--    echo "$KERNEL_SOURCE is not a directory";
--    echo "";
--    echo "";
--    exit 1;
--fi;
--
--if [ -f "$KERNEL_SOURCE/Makefile" ] ; then
--# set current VERSION, PATCHLEVEL, SUBLEVEL, EXTRAVERSION
--eval `sed -n -e 's/^\([A-Z]*\) = \([0-9]*\)$/\1=\2/p' -e 's/^\([A-Z]*\) = \(-[-a-z0-9]*\)$/\1=\2/p' $KERNEL_SOURCE/Makefile`
--else
--ver=`grep UTS_RELEASE $KERNEL_SOURCE/include/linux/version.h | cut -d '"' -f 2`
--VERSION=`echo "$ver" | cut -d '.' -f 1`
--PATCHLEVEL=`echo "$ver" | cut -d '.' -f 2`
--if echo "$ver" | grep -q '-' ; then
--SUBLEVEL=`echo "$ver" | sed "s/${VERSION}.${PATCHLEVEL}.//" | cut -d '-' -f 1`
--EXTRAVERSION=`echo "$ver" | sed "s/${VERSION}.${PATCHLEVEL}.${SUBLEVEL}-//"`
--else
--SUBLEVEL=`echo "$ver" | cut -d '.' -f 3`
--#EXTRAVERSION=
--fi
-+#
-+# Perform some sanity checks on our kernel sources
-+#
-+if [ ! -f "$KERNEL_SOURCE/Makefile" -a ! -f "$KERNEL_SOURCE/include/linux/version.h" ]; then
-+      echo ""
-+      echo ""
-+      echo "The file $KERNEL_SOURCE/Makefile or $KERNEL_SOURCE/include/linux/version.h is missing!"
-+      echo "Perhaps your kernel source is broken?"
-+      echo ""
-+      echo ""
-+      exit 1
- fi
--if [ -z "$VERSION" -o -z "$PATCHLEVEL" -o -z "$SUBLEVEL" ]
--then
--    echo "Unable to determine version for kernel headers"
--    echo -e "\tprovided in directory $KERNEL_SOURCE"
--    exit 1
-+if [ ! -d "$KERNEL_SOURCE" ]; then
-+      echo ""
-+      echo ""
-+      echo "$KERNEL_SOURCE is not a directory"
-+      echo ""
-+      echo ""
-+      exit 1
- fi
--if [ "$MAKE_IS_SILENT" != "y" ]; then
--echo "Current kernel version is $VERSION.$PATCHLEVEL.$SUBLEVEL${EXTRAVERSION}"
--echo -e "\n"
--echo "Using kernel headers from $VERSION.$PATCHLEVEL.$SUBLEVEL${EXTRAVERSION} for architecture '$TARGET_ARCH'"
--echo -e "\tprovided in directory $KERNEL_SOURCE"
--echo -e "\n"
--fi
-+#
- # Create a symlink to include/asm
--
-+#
- rm -f include/asm*
- if [ ! -d "$KERNEL_SOURCE/include/asm" ]; then
--    echo "";
--    echo "";
--    echo "The symlink $KERNEL_SOURCE/include/asm is missing\!";
--    echo "Perhaps you forgot to configure your kernel source?";
--    echo "You really should configure your kernel source tree so I";
--    echo "do not have to try and guess about this sort of thing.";
--    echo ""
--    echo "Attempting to guess a usable value....";
--    echo ""
--    echo "";
--    sleep 1;
--
--    if [ "$TARGET_ARCH" = "powerpc" ];then
--      set -x;
--      ln -fs $KERNEL_SOURCE/include/asm-ppc include/asm;
--      set +x;
--    elif [ "$TARGET_ARCH" = "mips" ];then
--      set -x;
--      ln -fs $KERNEL_SOURCE/include/asm-mips include/asm;
--      set +x;
--    elif [ "$TARGET_ARCH" = "arm" ];then
--      set -x;
--      ln -fs $KERNEL_SOURCE/include/asm-arm include/asm;
--      set +x;
--      if [ ! -L $KERNEL_SOURCE/include/asm-arm/proc ] ; then
--          if [ ! -L proc ] ; then
--              (cd include/asm;
--              ln -fs proc-armv proc;
--              ln -fs arch-ebsa285 arch);
--          fi
-+      echo ""
-+      echo ""
-+      echo "The symlink $KERNEL_SOURCE/include/asm is missing\!"
-+      echo "Perhaps you forgot to configure your kernel source?"
-+      echo "You really should configure your kernel source tree so I"
-+      echo "do not have to try and guess about this sort of thing."
-+      echo ""
-+      echo "Attempting to guess a usable value...."
-+      echo ""
-+      echo ""
-+      sleep 1
-+
-+      if [ "$TARGET_ARCH" = "powerpc" ]; then
-+              set -x
-+              ln -fs $KERNEL_SOURCE/include/asm-ppc include/asm
-+              set +x
-+      elif [ "$TARGET_ARCH" = "mips" ]; then
-+              set -x
-+              ln -fs $KERNEL_SOURCE/include/asm-mips include/asm
-+              set +x
-+      elif [ "$TARGET_ARCH" = "arm" ]; then
-+              set -x
-+              ln -fs $KERNEL_SOURCE/include/asm-arm include/asm
-+              set +x
-+      if [ ! -L $KERNEL_SOURCE/include/asm-arm/proc ]; then
-+              if [ ! -L proc ]; then
-+                      (
-+                              cd include/asm
-+                              ln -fs proc-armv proc
-+                              ln -fs arch-ebsa285 arch
-+                      )
-+              fi
-+      fi
-+      elif [ "$TARGET_ARCH" = "cris" ]; then
-+              set -x
-+              ln -fs $KERNEL_SOURCE/include/asm-cris include/asm
-+              set +x
-+      elif [ "$HAS_MMU" != "y" ]; then
-+              if [ -d $KERNEL_SOURCE/include/asm-${TARGET_ARCH}nommu ]; then
-+                      set -x
-+                      ln -fs $KERNEL_SOURCE/include/asm-${TARGET_ARCH}nommu include/asm
-+                      set +x
-+              else
-+                      set -x
-+                      ln -fs $KERNEL_SOURCE/include/asm-$TARGET_ARCH include/asm
-+                      set +x
-+              fi
-+      else
-+              set -x
-+              ln -fs $KERNEL_SOURCE/include/asm-$TARGET_ARCH include/asm
-+              set +x
-       fi;
--    elif [ "$TARGET_ARCH" = "cris" ]; then
--      set -x;
--      ln -fs $KERNEL_SOURCE/include/asm-cris include/asm;
--      set +x;
--    elif [ "$HAS_MMU" != "y" ]; then
--          if [ -d $KERNEL_SOURCE/include/asm-${TARGET_ARCH}nommu ] ; then
--              set -x;
--              ln -fs $KERNEL_SOURCE/include/asm-${TARGET_ARCH}nommu include/asm;
--              set +x;
--          else
--              set -x;
--              ln -fs $KERNEL_SOURCE/include/asm-$TARGET_ARCH include/asm;
--              set +x;
--          fi;
--    else
--      set -x;
--      ln -fs $KERNEL_SOURCE/include/asm-$TARGET_ARCH include/asm;
--      set +x;
--    fi;
- else
--# No guessing required.....
--ln -fs $KERNEL_SOURCE/include/asm include/asm
--if [ -e $KERNEL_SOURCE/include/asm-$TARGET_ARCH ] ; then
--ln -fs $KERNEL_SOURCE/include/asm-$TARGET_ARCH include/asm-$TARGET_ARCH
-+      # No guessing required.....
-+      for x in $KERNEL_SOURCE/include/asm* ; do
-+              ln -fs ${x} include/
-+      done
- fi
--fi;
-+#
- # Annoyingly, 2.6.x kernel headers also need an include/asm-generic/ directory
--if [ $VERSION -eq 2 ] && [ $PATCHLEVEL -ge 6 ] ; then
--    ln -fs $KERNEL_SOURCE/include/asm-generic include/asm-generic
--fi;
-+#
-+if [ -e $KERNEL_SOURCE/include/asm-generic ]; then
-+      rm -f include/asm-generic
-+      ln -fs $KERNEL_SOURCE/include/asm-generic include/asm-generic
-+fi
-+#
- # Create the include/linux symlink.
-+#
- rm -f include/linux
- ln -fs $KERNEL_SOURCE/include/linux include/linux
--
diff --git a/toolchain/uClibc/uClibc-0.9.28-host-ldconfig.patch b/toolchain/uClibc/uClibc-0.9.28-host-ldconfig.patch
deleted file mode 100644 (file)
index f55c349..0000000
+++ /dev/null
@@ -1,635 +0,0 @@
-This patch supports cross-development for embedded systems by allowing the
-host version of ldconfig (ldconfig.host) to build ld.so.cache for the target.
-Changes include:
- 1) LDSO_CACHE_SUPPORT is defined for the host build.
- 2) A little-endian host can create a big-endian ld.so.cache, and vice versa.
- 3) Can use -r option without chroot(), so no need to run as superuser.
-
-Dan Howell <dahowell@directv.com>
-
-diff -urN uClibc-orig/utils/chroot_realpath.c uClibc-20050502/utils/chroot_realpath.c
---- uClibc-orig/utils/chroot_realpath.c        1969-12-31 16:00:00.000000000 -0800
-+++ uClibc-20050502/utils/chroot_realpath.c    2005-09-12 18:30:29.000000000 -0700
-@@ -0,0 +1,163 @@
-+/*
-+ * chroot_realpath.c -- reslove pathname as if inside chroot
-+ * Based on realpath.c Copyright (C) 1993 Rick Sladkey <jrs@world.std.com>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU Library Public License as published by
-+ * the Free Software Foundation; either version 2, 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 Public License for more details.
-+ *
-+ * 2005/09/12: Dan Howell (modified from realpath.c to emulate chroot)
-+ */
-+
-+#ifdef HAVE_CONFIG_H
-+#include <config.h>
-+#endif
-+
-+#include <sys/types.h>
-+#include <unistd.h>
-+#include <stdio.h>
-+#include <string.h>
-+#include <strings.h>
-+#include <limits.h>                           /* for PATH_MAX */
-+#include <sys/param.h>                        /* for MAXPATHLEN */
-+#include <errno.h>
-+#ifndef __set_errno
-+#define __set_errno(val) ((errno) = (val))
-+#endif
-+
-+#include <sys/stat.h>                 /* for S_IFLNK */
-+
-+#ifndef PATH_MAX
-+#define PATH_MAX _POSIX_PATH_MAX
-+#endif
-+
-+#define MAX_READLINKS 32
-+
-+char *chroot_realpath(const char *chroot, const char *path, char resolved_path[])
-+{
-+      char copy_path[PATH_MAX];
-+      char link_path[PATH_MAX];
-+      char got_path[PATH_MAX];
-+      char *got_path_root = got_path;
-+      char *new_path = got_path;
-+      char *max_path;
-+      int readlinks = 0;
-+      int n;
-+      int chroot_len;
-+
-+      /* Trivial case. */
-+      if (chroot == NULL || *chroot == '\0' ||
-+          (*chroot == '/' && chroot[1] == '\0')) {
-+              strcpy(resolved_path, path);
-+              return resolved_path;
-+      }
-+
-+      chroot_len = strlen(chroot);
-+
-+      if (chroot_len + strlen(path) >= PATH_MAX - 3) {
-+              __set_errno(ENAMETOOLONG);
-+              return NULL;
-+      }
-+
-+      /* Make a copy of the source path since we may need to modify it. */
-+      strcpy(copy_path, path);
-+      path = copy_path;
-+      max_path = copy_path + PATH_MAX - chroot_len - 3;
-+
-+      /* Start with the chroot path. */
-+      strcpy(new_path, chroot);
-+      new_path += chroot_len;
-+      while (*new_path == '/' && new_path > got_path)
-+              new_path--;
-+      got_path_root = new_path;
-+      *new_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_root + 1)
-+                                              continue;
-+                                      /* Handle ".." by backing up. */
-+                                      while ((--new_path)[-1] != '/');
-+                                      continue;
-+                              }
-+                      }
-+              }
-+              /* Safely copy the next pathname component. */
-+              while (*path != '\0' && *path != '/') {
-+                      if (path > max_path) {
-+                              __set_errno(ENAMETOOLONG);
-+                              return NULL;
-+                      }
-+                      *new_path++ = *path++;
-+              }
-+              if (*path == '\0')
-+                      /* Don't follow symlink for last pathname component. */
-+                      break;
-+#ifdef S_IFLNK
-+              /* Protect against infinite loops. */
-+              if (readlinks++ > MAX_READLINKS) {
-+                      __set_errno(ELOOP);
-+                      return NULL;
-+              }
-+              /* See if latest pathname component is a symlink. */
-+              *new_path = '\0';
-+              n = readlink(got_path, link_path, PATH_MAX - 1);
-+              if (n < 0) {
-+                      /* EINVAL means the file exists but isn't a symlink. */
-+                      if (errno != EINVAL) {
-+                              /* Make sure it's null terminated. */
-+                              *new_path = '\0';
-+                              strcpy(resolved_path, got_path);
-+                              return NULL;
-+                      }
-+              } else {
-+                      /* Note: readlink doesn't add the null byte. */
-+                      link_path[n] = '\0';
-+                      if (*link_path == '/')
-+                              /* Start over for an absolute symlink. */
-+                              new_path = got_path_root;
-+                      else
-+                              /* Otherwise back up over this component. */
-+                              while (*(--new_path) != '/');
-+                      /* Safe sex check. */
-+                      if (strlen(path) + n >= PATH_MAX - 2) {
-+                              __set_errno(ENAMETOOLONG);
-+                              return NULL;
-+                      }
-+                      /* Insert symlink contents into path. */
-+                      strcat(link_path, path);
-+                      strcpy(copy_path, link_path);
-+                      path = copy_path;
-+              }
-+#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';
-+      strcpy(resolved_path, got_path);
-+      return resolved_path;
-+}
-diff -urN uClibc-orig/utils/ldconfig.c uClibc-20050502/utils/ldconfig.c
---- uClibc-orig/utils/ldconfig.c       2005-05-01 23:10:12.000000000 -0700
-+++ uClibc-20050502/utils/ldconfig.c   2005-09-16 19:26:33.000000000 -0700
-@@ -22,6 +22,8 @@
-  *
-  * This program may be used for any purpose as long as this
-  * copyright notice is kept.
-+ *
-+ * 2005/09/16: Dan Howell (modified for cross-development)
-  */
- #include <stdio.h>
-@@ -37,6 +39,7 @@
- #include <errno.h>
- #include <sys/stat.h>
- #include <sys/mman.h>
-+#include "bswap.h"
- #include "dl-defs.h"
- #define BUFFER_SIZE 4096
-@@ -56,6 +59,7 @@
- #if !defined (N_MAGIC)
- #define N_MAGIC(exec) ((exec).a_info & 0xffff)
- #endif
-+#define N_MAGIC_SWAP(exec) (bswap_32((exec).a_info) & 0xffff)
- /* Code indicating object file or impure executable.  */
- #define OMAGIC 0407
- /* Code indicating pure executable.  */
-@@ -97,6 +101,8 @@
- char *conffile = LDSO_CONF;   /* default conf file */
- char *cachefile = LDSO_CACHE; /* default cache file */
- #endif
-+char *chroot_dir = NULL;
-+int byteswap = 0;
- struct needed_tab
- {
-@@ -117,6 +123,8 @@
-   { NULL,           LIB_ELF }
- };
-+extern char *chroot_realpath(const char *chroot, const char *path, char resolved_path[]);
-+
- /* These two are used internally -- you shouldn't need to use them */
- static void verror_msg(const char *s, va_list p)
-@@ -242,6 +250,8 @@
-     ElfW(Ehdr) *elf_hdr;
-     struct stat statbuf;
-     char buff[BUFFER_SIZE];
-+    char real[BUFFER_SIZE];
-+    static int byteswapflag = -1;     /* start with byte-order unknown */
-     /* see if name is of the form *.so* */
-     if (name[strlen(name)-1] != '~' && (cp = strstr(name, ".so")))
-@@ -256,8 +266,12 @@
-       sprintf(buff, "%s%s%s", dir, (*dir && strcmp(dir, "/")) ?
-               "/" : "", name);
-+      /* get real path in case of chroot */
-+      if (!chroot_realpath(chroot_dir, buff, real))
-+          warn("can't resolve %s in chroot %s", buff, chroot_dir);
-+
-       /* first, make sure it's a regular file */
--      if (lstat(buff, &statbuf))
-+      if (lstat(real, &statbuf))
-           warn("skipping %s", buff);
-       else if (!S_ISREG(statbuf.st_mode) && !S_ISLNK(statbuf.st_mode))
-           warnx("%s is not a regular file or symlink, skipping", buff);
-@@ -267,14 +281,15 @@
-           *islink = S_ISLNK(statbuf.st_mode);
-           /* then try opening it */
--          if (!(file = fopen(buff, "rb")))
-+          if (!(file = fopen(real, "rb")))
-               warn("skipping %s", buff);
-           else
-           {
-               /* now make sure it's a shared library */
-               if (fread(&exec, sizeof exec, 1, file) < 1)
-                   warnx("can't read header from %s, skipping", buff);
--              else if (N_MAGIC(exec) != ZMAGIC && N_MAGIC(exec) != QMAGIC)
-+              else if (N_MAGIC(exec) != ZMAGIC && N_MAGIC(exec) != QMAGIC &&
-+                       N_MAGIC_SWAP(exec) != ZMAGIC && N_MAGIC_SWAP(exec) != QMAGIC)
-               {
-                   elf_hdr = (ElfW(Ehdr) *) &exec;
-                   if (elf_hdr->e_ident[0] != 0x7f ||
-@@ -294,6 +309,9 @@
-                       *type = LIB_ELF;
-                       good = readsoname(buff, file, expected_type, type, 
-                               elf_hdr->e_ident[EI_CLASS]);
-+                      if (byteswapflag == -1)
-+                          /* byte-order detected */
-+                          byteswapflag = byteswap;
-                       if (good == NULL || *islink)
-                       {
-                           if (good != NULL)
-@@ -313,6 +331,12 @@
-               }
-               else
-               {
-+                  /* Determine byte-order */
-+                  byteswap = (N_MAGIC(exec) == ZMAGIC || N_MAGIC(exec) == QMAGIC) ? 0 : 1;
-+                  if (byteswapflag == -1)
-+                      /* byte-order detected */
-+                      byteswapflag = byteswap;
-+
-                   if (*islink)
-                       good = xstrdup(name);
-                   else
-@@ -330,6 +354,14 @@
-                   *type = LIB_DLL;
-               }
-               fclose(file);
-+
-+              if (byteswapflag >= 0 && byteswap != byteswapflag)
-+              {
-+                  byteswapflag = -2;
-+                  warnx("mixed byte-order detected, using host byte-order...");
-+              }
-+              if (byteswapflag == -2)
-+                  byteswap = 0;
-           }
-       }
-     }
-@@ -343,18 +375,24 @@
-     int change = 1;
-     char libname[BUFFER_SIZE];
-     char linkname[BUFFER_SIZE];
-+    char reallibname[BUFFER_SIZE];
-+    char reallinkname[BUFFER_SIZE];
-     struct stat libstat;
-     struct stat linkstat;
-     /* construct the full path names */
-     sprintf(libname, "%s/%s", dir, file);
-     sprintf(linkname, "%s/%s", dir, so);
-+    if (!chroot_realpath(chroot_dir, libname, reallibname))
-+      warn("can't resolve %s in chroot %s", libname, chroot_dir);
-+    if (!chroot_realpath(chroot_dir, linkname, reallinkname))
-+      warn("can't resolve %s in chroot %s", linkname, chroot_dir);
-     /* see if a link already exists */
--    if (!stat(linkname, &linkstat))
-+    if (!stat(reallinkname, &linkstat))
-     {
-       /* now see if it's the one we want */
--      if (stat(libname, &libstat))
-+      if (stat(reallibname, &libstat))
-           warn("can't stat %s", libname);
-       else if (libstat.st_dev == linkstat.st_dev &&
-               libstat.st_ino == linkstat.st_ino)
-@@ -364,14 +402,14 @@
-     /* then update the link, if required */
-     if (change > 0 && !nolinks)
-     {
--      if (!lstat(linkname, &linkstat))
-+      if (!lstat(reallinkname, &linkstat))
-       {
-           if (!S_ISLNK(linkstat.st_mode))
-           {
-               warnx("%s is not a symlink", linkname);
-               change = -1;
-           }
--          else if (remove(linkname))
-+          else if (remove(reallinkname))
-           {
-               warn("can't unlink %s", linkname);
-               change = -1;
-@@ -379,7 +417,7 @@
-       }
-       if (change > 0)
-       {
--          if (symlink(file, linkname))
-+          if (symlink(file, reallinkname))
-           {
-               warn("can't link %s to %s", linkname, file);
-               change = -1;
-@@ -441,6 +479,7 @@
-     char *so, *path, *path_n;
-     struct lib *lp, *libs = NULL;
-     int i, libtype, islink, expected_type = LIB_ANY;
-+    char realname[BUFFER_SIZE];
-     /* We need a writable copy of this string */
-     path = strdup(rawname);
-@@ -500,8 +539,12 @@
-     if (verbose > 0)
-       printf("%s:\n", name);
-+    /* get real path in case of chroot */
-+    if (!chroot_realpath(chroot_dir, name, realname))
-+      warn("can't resolve %s in chroot %s", name, chroot_dir);
-+
-     /* if we can't open it, we can't do anything */
--    if ((dir = opendir(name)) == NULL)
-+    if ((dir = opendir(realname)) == NULL)
-     {
-       warn("skipping %s", name);
-       free(path);
-@@ -596,8 +639,12 @@
-     char *res = NULL, *cp;
-     FILE *file;
-     struct stat stat;
-+    char realconffile[BUFFER_SIZE];
-+
-+    if (!chroot_realpath(chroot_dir, conffile, realconffile))
-+      return NULL;
--    if ((file = fopen(conffile, "r")) != NULL)
-+    if ((file = fopen(realconffile, "r")) != NULL)
-     {
-       fstat(fileno(file), &stat);
-       res = xmalloc(stat.st_size + 1);
-@@ -678,22 +725,38 @@
- {
-     int cachefd;
-     int stroffset = 0;
-+    char realcachefile[BUFFER_SIZE];
-     char tempfile[BUFFER_SIZE];
-+    header_t swap_magic;
-+    header_t *magic_ptr;
-+    libentry_t swap_lib;
-+    libentry_t *lib_ptr;
-     liblist_t *cur_lib;
-     if (!magic.nlibs)
-       return;
--    sprintf(tempfile, "%s~", cachefile);
-+    if (!chroot_realpath(chroot_dir, cachefile, realcachefile))
-+      err(EXIT_FATAL,"can't resolve %s in chroot %s (%s)",
-+          cachefile, chroot_dir, strerror(errno));
-+
-+    sprintf(tempfile, "%s~", realcachefile);
-     if (unlink(tempfile) && errno != ENOENT)
--      err(EXIT_FATAL,"can't unlink %s (%s)", tempfile, strerror(errno));
-+      err(EXIT_FATAL,"can't unlink %s~ (%s)", cachefile, strerror(errno));
-     if ((cachefd = creat(tempfile, 0644)) < 0)
--      err(EXIT_FATAL,"can't create %s (%s)", tempfile, strerror(errno));
-+      err(EXIT_FATAL,"can't create %s~ (%s)", cachefile, strerror(errno));
--    if (write(cachefd, &magic, sizeof (header_t)) != sizeof (header_t))
--      err(EXIT_FATAL,"can't write %s (%s)", tempfile, strerror(errno));
-+    if (byteswap) {
-+      swap_magic = magic;
-+      swap_magic.nlibs = bswap_32(swap_magic.nlibs);
-+      magic_ptr = &swap_magic;
-+    } else {
-+      magic_ptr = &magic;
-+    }
-+    if (write(cachefd, magic_ptr, sizeof (header_t)) != sizeof (header_t))
-+      err(EXIT_FATAL,"can't write %s~ (%s)", cachefile, strerror(errno));
-     for (cur_lib = lib_head; cur_lib != NULL; cur_lib = cur_lib->next)
-     {
-@@ -701,29 +764,37 @@
-       stroffset += strlen(cur_lib->soname) + 1;
-       cur_lib->liboffset = stroffset;
-       stroffset += strlen(cur_lib->libname) + 1;
--      if (write(cachefd, cur_lib, sizeof (libentry_t)) !=
--              sizeof (libentry_t))
--          err(EXIT_FATAL,"can't write %s (%s)", tempfile, strerror(errno));
-+      if (byteswap) {
-+          swap_lib.flags = bswap_32(cur_lib->flags);
-+          swap_lib.sooffset = bswap_32(cur_lib->sooffset);
-+          swap_lib.liboffset = bswap_32(cur_lib->liboffset);
-+          lib_ptr = &swap_lib;
-+      } else {
-+          lib_ptr = (libentry_t *)cur_lib;
-+      }
-+      if (write(cachefd, lib_ptr, sizeof (libentry_t)) !=
-+          sizeof (libentry_t))
-+      err(EXIT_FATAL,"can't write %s~ (%s)", cachefile, strerror(errno));
-     }
-     for (cur_lib = lib_head; cur_lib != NULL; cur_lib = cur_lib->next)
-     {
-       if (write(cachefd, cur_lib->soname, strlen(cur_lib->soname) + 1)
-               != strlen(cur_lib->soname) + 1)
--          err(EXIT_FATAL,"can't write %s (%s)", tempfile, strerror(errno));
-+          err(EXIT_FATAL,"can't write %s~ (%s)", cachefile, strerror(errno));
-       if (write(cachefd, cur_lib->libname, strlen(cur_lib->libname) + 1)
-               != strlen(cur_lib->libname) + 1)
--          err(EXIT_FATAL,"can't write %s (%s)", tempfile, strerror(errno));
-+          err(EXIT_FATAL,"can't write %s~ (%s)", cachefile, strerror(errno));
-     }
-     if (close(cachefd))
--      err(EXIT_FATAL,"can't close %s (%s)", tempfile, strerror(errno));
-+      err(EXIT_FATAL,"can't close %s~ (%s)", cachefile, strerror(errno));
-     if (chmod(tempfile, 0644))
--      err(EXIT_FATAL,"can't chmod %s (%s)", tempfile, strerror(errno));
-+      err(EXIT_FATAL,"can't chmod %s~ (%s)", cachefile, strerror(errno));
--    if (rename(tempfile, cachefile))
--      err(EXIT_FATAL,"can't rename %s (%s)", tempfile, strerror(errno));
-+    if (rename(tempfile, realcachefile))
-+      err(EXIT_FATAL,"can't rename %s~ (%s)", cachefile, strerror(errno));
- }
- void cache_print(void)
-@@ -734,8 +805,13 @@
-     char *strs;
-     header_t *header;
-     libentry_t *libent;
-+    char realcachefile[BUFFER_SIZE];
-+
-+    if (!chroot_realpath(chroot_dir, cachefile, realcachefile))
-+      err(EXIT_FATAL,"can't resolve %s in chroot %s (%s)",
-+          cachefile, chroot_dir, strerror(errno));
--    if (stat(cachefile, &st) || (fd = open(cachefile, O_RDONLY))<0)
-+    if (stat(realcachefile, &st) || (fd = open(realcachefile, O_RDONLY))<0)
-       err(EXIT_FATAL,"can't read %s (%s)", cachefile, strerror(errno));
-     if ((c = mmap(0,st.st_size, PROT_READ, MAP_SHARED ,fd, 0)) == (caddr_t)-1)
-       err(EXIT_FATAL,"can't map %s (%s)", cachefile, strerror(errno));
-@@ -828,7 +904,6 @@
-     int nodefault = 0;
-     char *cp, *dir, *so;
-     int libtype, islink;
--    char *chroot_dir = NULL;
-     int printcache = 0;
- #ifdef __LDSO_CACHE_SUPPORT__
-     char *extpath;
-@@ -891,10 +966,16 @@
-       }
-     if (chroot_dir && *chroot_dir) {
--      if (chroot(chroot_dir) < 0)
--          err(EXIT_FATAL,"couldn't chroot to %s (%s)", chroot_dir, strerror(errno));
--      if (chdir("/") < 0)
--          err(EXIT_FATAL,"couldn't chdir to / (%s)", strerror(errno));
-+      if (chroot(chroot_dir) < 0) {
-+          if (chdir(chroot_dir) < 0)
-+              err(EXIT_FATAL,"couldn't chroot to %s (%s)", chroot_dir, strerror(errno));
-+      }
-+      else
-+      {
-+          if (chdir("/") < 0)
-+              err(EXIT_FATAL,"couldn't chdir to / (%s)", strerror(errno));
-+          chroot_dir = NULL;
-+      }
-     }
-     /* allow me to introduce myself, hi, my name is ... */
-diff -urN uClibc-orig/utils/Makefile uClibc-20050502/utils/Makefile
---- uClibc-orig/utils/Makefile 2005-05-01 23:10:12.000000000 -0700
-+++ uClibc-20050502/utils/Makefile     2005-09-16 19:28:55.000000000 -0700
-@@ -29,6 +29,12 @@
- TARGET_ICONV =
- endif
-+ifeq ($(strip $(LDSO_CACHE_SUPPORT)),y)
-+HOST_LDSO_CACHE_FLAG = -D__LDSO_CACHE_SUPPORT__=1
-+else
-+HOST_LDSO_CACHE_FLAG =
-+endif
-+
- # NOTE: We build the utils AFTER we have a uClibc-targeted toolchain.
- ifeq ($(strip $(HAVE_SHARED)),y)
-@@ -51,7 +57,7 @@
- else
- LDCONFIG_CFLAGS := $(PIEFLAG) $(LDPIEFLAG)
- endif
--ldconfig: ldconfig.c
-+ldconfig: ldconfig.c chroot_realpath.c
-       $(CC) $(CFLAGS) $(LDCONFIG_CFLAGS) \
-               -DUCLIBC_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" \
-               -DUCLIBC_LDSO=$(UCLIBC_LDSO) -I. -I../ldso/include \
-@@ -79,13 +85,13 @@
- ldd.host: ldd.c
-       $(HOSTCC) $(HOSTCFLAGS) -Wl,-s \
--              -DUCLIBC_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" \
-+              -DUCLIBC_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" $(HOST_LDSO_CACHE_FLAG) \
-               -DUCLIBC_LDSO=$(UCLIBC_LDSO) -I. -I../ldso/include \
-               $^ -o $@
--ldconfig.host: ldconfig.c
-+ldconfig.host: ldconfig.c chroot_realpath.c
-       $(HOSTCC) $(HOSTCFLAGS) -Wl,-s \
--              -DUCLIBC_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" \
-+              -DUCLIBC_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" $(HOST_LDSO_CACHE_FLAG) \
-               -DUCLIBC_LDSO=$(UCLIBC_LDSO) -I. -I../ldso/include \
-               $^ -o $@
-diff -urN uClibc-orig/utils/readsoname2.c uClibc-20050502/utils/readsoname2.c
---- uClibc-orig/utils/readsoname2.c    2005-05-01 23:10:12.000000000 -0700
-+++ uClibc-20050502/utils/readsoname2.c        2005-09-16 17:48:59.000000000 -0700
-@@ -26,7 +26,7 @@
-   if (fstat(fileno(infile), &st))
-     return NULL;
--  header = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fileno(infile), 0);
-+  header = mmap(0, st.st_size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fileno(infile), 0);
-   if (header == (caddr_t)-1)
-     return NULL;
-@@ -34,6 +34,19 @@
-   if ((char *)(epnt+1) > (char *)(header + st.st_size))
-     goto skip;
-+#if __BYTE_ORDER == __LITTLE_ENDIAN
-+  byteswap = (epnt->e_ident[5] == ELFDATA2MSB) ? 1 : 0;
-+#elif __BYTE_ORDER == __BIG_ENDIAN
-+  byteswap = (epnt->e_ident[5] == ELFDATA2LSB) ? 1 : 0;
-+#else
-+#error Unknown host byte order!
-+#endif
-+  /* Be very lazy, and only byteswap the stuff we use */
-+  if (byteswap==1) {
-+    epnt->e_phoff=bswap_32(epnt->e_phoff);
-+    epnt->e_phnum=bswap_16(epnt->e_phnum);
-+  }
-+
-   ppnt = (ElfW(Phdr) *)&header[epnt->e_phoff];
-   if ((char *)ppnt < (char *)header ||
-       (char *)(ppnt+epnt->e_phnum) > (char *)(header + st.st_size))
-@@ -41,6 +54,14 @@
-   for(i = 0; i < epnt->e_phnum; i++)
-   {
-+    /* Be very lazy, and only byteswap the stuff we use */
-+    if (byteswap==1) {
-+      ppnt->p_type=bswap_32(ppnt->p_type);
-+      ppnt->p_vaddr=bswap_32(ppnt->p_vaddr);
-+      ppnt->p_offset=bswap_32(ppnt->p_offset);
-+      ppnt->p_filesz=bswap_32(ppnt->p_filesz);
-+    }
-+
-     if (loadaddr == -1 && ppnt->p_type == PT_LOAD) 
-       loadaddr = (ppnt->p_vaddr & ~(page_size-1)) -
-       (ppnt->p_offset & ~(page_size-1));
-@@ -58,11 +79,20 @@
-       (char *)(dpnt+dynamic_size) > (char *)(header + st.st_size))
-     goto skip;
-   
-+  if (byteswap==1) {
-+    dpnt->d_tag=bswap_32(dpnt->d_tag);
-+    dpnt->d_un.d_val=bswap_32(dpnt->d_un.d_val);
-+  }
-+
-   while (dpnt->d_tag != DT_NULL)
-   {
-     if (dpnt->d_tag == DT_STRTAB)
-       strtab_val = dpnt->d_un.d_val;
-     dpnt++;
-+    if (byteswap==1) {
-+      dpnt->d_tag=bswap_32(dpnt->d_tag);
-+      dpnt->d_un.d_val=bswap_32(dpnt->d_un.d_val);
-+    }
-   };
-   if (!strtab_val)
diff --git a/toolchain/uClibc/uClibc-0.9.28-ldso.patch b/toolchain/uClibc/uClibc-0.9.28-ldso.patch
deleted file mode 100644 (file)
index 4081fc7..0000000
+++ /dev/null
@@ -1,5190 +0,0 @@
-diff -urN uClibc-0.9.28.orig/include/elf.h uClibc-0.9.28/include/elf.h
---- uClibc-0.9.28.orig/include/elf.h   2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/include/elf.h        2006-04-28 00:14:35.000000000 -0600
-@@ -142,6 +142,7 @@
- #define ELFOSABI_HPUX         1       /* HP-UX */
- #define ELFOSABI_NETBSD               2       /* NetBSD.  */
- #define ELFOSABI_LINUX                3       /* Linux.  */
-+#define ELFOSABI_HURD         4       /* GNU/Hurd */
- #define ELFOSABI_SOLARIS      6       /* Sun Solaris.  */
- #define ELFOSABI_AIX          7       /* IBM AIX.  */
- #define ELFOSABI_IRIX         8       /* SGI Irix.  */
-@@ -149,6 +150,9 @@
- #define ELFOSABI_TRU64                10      /* Compaq TRU64 UNIX.  */
- #define ELFOSABI_MODESTO      11      /* Novell Modesto.  */
- #define ELFOSABI_OPENBSD      12      /* OpenBSD.  */
-+#define ELFOSABI_OPENVMS      13      /* OpenVMS */
-+#define ELFOSABI_NSK          14      /* Hewlett-Packard Non-Stop Kernel */
-+#define ELFOSABI_AROS         15      /* Amiga Research OS */
- #define ELFOSABI_ARM          97      /* ARM */
- #define ELFOSABI_STANDALONE   255     /* Standalone (embedded) application */
-@@ -177,6 +181,7 @@
- #define EM_386                 3              /* Intel 80386 */
- #define EM_68K                 4              /* Motorola m68k family */
- #define EM_88K                 5              /* Motorola m88k family */
-+#define EM_486                 6              /* Intel 80486 *//* Reserved for future use */
- #define EM_860                 7              /* Intel 80860 */
- #define EM_MIPS                8              /* MIPS R3000 big-endian */
- #define EM_S370                9              /* IBM System/370 */
-@@ -193,7 +198,8 @@
- #define EM_V800               36              /* NEC V800 series */
- #define EM_FR20               37              /* Fujitsu FR20 */
- #define EM_RH32               38              /* TRW RH-32 */
--#define EM_RCE                39              /* Motorola RCE */
-+#define EM_MCORE      39              /* Motorola M*Core */ /* May also be taken by Fujitsu MMA */
-+#define EM_RCE                39              /* Old name for MCore */
- #define EM_ARM                40              /* ARM */
- #define EM_FAKE_ALPHA 41              /* Digital Alpha */
- #define EM_SH         42              /* Renesas SH */
-@@ -248,18 +254,105 @@
- #define EM_OPENRISC   92              /* OpenRISC 32-bit embedded processor */
- #define EM_ARC_A5     93              /* ARC Cores Tangent-A5 */
- #define EM_XTENSA     94              /* Tensilica Xtensa Architecture */
-+#define EM_IP2K               101             /* Ubicom IP2022 micro controller */
-+#define EM_CR         103             /* National Semiconductor CompactRISC */
-+#define EM_MSP430     105             /* TI msp430 micro controller */
-+#define EM_BLACKFIN   106             /* Analog Devices Blackfin */
-+#define EM_ALTERA_NIOS2       113     /* Altera Nios II soft-core processor */
-+#define EM_CRX                114             /* National Semiconductor CRX */
- #define EM_NUM                95
--/* If it is necessary to assign new unofficial EM_* values, please
--   pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the
--   chances of collision with official or non-GNU unofficial values.  */
-+/* If it is necessary to assign new unofficial EM_* values, please pick large
-+   random numbers (0x8523, 0xa7f2, etc.) to minimize the chances of collision
-+   with official or non-GNU unofficial values.
--/* Fujitsu FR-V.  */
-+   NOTE: Do not just increment the most recent number by one.
-+   Somebody else somewhere will do exactly the same thing, and you
-+   will have a collision.  Instead, pick a random number.
-+
-+   Normally, each entity or maintainer responsible for a machine with an
-+   unofficial e_machine number should eventually ask registry@caldera.com for
-+   an officially blessed number to be added to the list above.  */
-+
-+/* picoJava */
-+#define EM_PJ_OLD     99
-+
-+/* Cygnus PowerPC ELF backend.  Written in the absence of an ABI.  */
-+#define EM_CYGNUS_POWERPC 0x9025
-+
-+/* Old version of Sparc v9, from before the ABI; this should be
-+   removed shortly.  */
-+#define EM_OLD_SPARCV9        11
-+
-+/* Old version of PowerPC, this should be removed shortly. */
-+#define EM_PPC_OLD    17
-+
-+/* (Deprecated) Temporary number for the OpenRISC processor.  */
-+#define EM_OR32               0x8472
-+
-+/* Renesas M32C and M16C.  */
-+#define EM_M32C                       0xFEB0
-+
-+/* Cygnus M32R ELF backend.  Written in the absence of an ABI.  */
-+#define EM_CYGNUS_M32R        0x9041
-+
-+/* old S/390 backend magic number. Written in the absence of an ABI.  */
-+#define EM_S390_OLD   0xa390
-+
-+/* D10V backend magic number.  Written in the absence of an ABI.  */
-+#define EM_CYGNUS_D10V        0x7650
-+
-+/* D30V backend magic number.  Written in the absence of an ABI.  */
-+#define EM_CYGNUS_D30V        0x7676
-+
-+/* V850 backend magic number.  Written in the absense of an ABI.  */
-+#define EM_CYGNUS_V850        0x9080
-+
-+/* mn10200 and mn10300 backend magic numbers.
-+   Written in the absense of an ABI.  */
-+#define EM_CYGNUS_MN10200     0xdead
-+#define EM_CYGNUS_MN10300     0xbeef
-+
-+/* FR30 magic number - no EABI available.  */
-+#define EM_CYGNUS_FR30                0x3330
-+
-+/* AVR magic number
-+   Written in the absense of an ABI.  */
-+#define EM_AVR_OLD            0x1057
-+
-+/* OpenRISC magic number
-+   Written in the absense of an ABI.  */
-+#define EM_OPENRISC_OLD               0x3426
-+
-+/* DLX magic number
-+   Written in the absense of an ABI.  */
-+#define EM_DLX                        0x5aa5
-+
-+#define EM_XSTORMY16          0xad45
-+
-+/* FRV magic number - no EABI available??.  */
- #define EM_CYGNUS_FRV 0x5441
-+/* Ubicom IP2xxx; no ABI */
-+#define EM_IP2K_OLD           0x8217
-+
-+#define EM_MT                   0x2530  /* Morpho MT; no ABI */
-+
-+/* MSP430 magic number
-+      Written in the absense everything.  */
-+#define EM_MSP430_OLD         0x1059
-+
-+/* Vitesse IQ2000.  */
-+#define EM_IQ2000             0xFEBA
-+
-+/* Old, unofficial value for Xtensa.  */
-+#define EM_XTENSA_OLD         0xabc7
-+
-+/* Alpha backend magic number.  Written in the absence of an ABI.  */
- #define EM_ALPHA      0x9026
--#define EM_NIOS32     0xfebb          /* Altera Nios 32 */
--#define EM_ALTERA_NIOS2  0x9ee5       /* Altera Nios II */
-+
-+/* NIOS magic number - no EABI available.  */
-+#define EM_NIOS32     0xFEBB
- /* V850 backend magic number.  Written in the absense of an ABI.  */
- #define EM_CYGNUS_V850 0x9080
-@@ -2498,6 +2591,12 @@
- #define R_390_NUM             61
-+/* CRIS flags.  */
-+#define EF_CRIS_VARIANT_MASK           0x0000000e
-+#define EF_CRIS_VARIANT_ANY_V0_V10     0x00000000
-+#define EF_CRIS_VARIANT_V32            0x00000002
-+#define EF_CRIS_VARIANT_COMMON_V10_V32 0x00000004
-+
- /* CRIS relocations.  */
- #define R_CRIS_NONE           0
- #define R_CRIS_8              1
-@@ -2688,6 +2787,7 @@
- #define R_V850_NUM            25
-+/* Renesas H8/300 Relocations */
- #define R_H8_NONE       0
- #define R_H8_DIR32      1
- #define R_H8_DIR32_28   2
-@@ -2731,8 +2831,7 @@
- #define R_H8_DIR32A16  63
- #define R_H8_ABS32     65
- #define R_H8_ABS32A16 127
--
--/* Altera NIOS specific definitions.  */
-+#define R_H8_NUM      128
- /* NIOS relocations. */
- #define R_NIOS_NONE                           0
-diff -urN uClibc-0.9.28.orig/include/errno.h uClibc-0.9.28/include/errno.h
---- uClibc-0.9.28.orig/include/errno.h 2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/include/errno.h      2006-04-28 00:14:35.000000000 -0600
-@@ -43,9 +43,11 @@
-    variable.  This redeclaration using the macro still works, but it
-    will be a function declaration without a prototype and may trigger
-    a -Wstrict-prototypes warning.  */
-+#ifndef __ASSEMBLER__
- #ifndef       errno
- extern int errno;
- #endif
-+#endif
- #if 0 /*def __USE_GNU      uClibc note: not supported */
-diff -urN uClibc-0.9.28.orig/ldso/Makefile uClibc-0.9.28/ldso/Makefile
---- uClibc-0.9.28.orig/ldso/Makefile   2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/Makefile        2006-04-28 00:14:35.000000000 -0600
-@@ -37,15 +37,12 @@
- LN_HEADERS      := $(patsubst %, include/%, elf.h)
- LN_ARCH_HEADERS := $(patsubst %, include/%, dl-startup.h dl-syscalls.h dl-sysdep.h dl-debug.h)
--HEADERS         := $(LN_HEADERS) $(LN_ARCH_HEADERS) include/dl-progname.h
-+HEADERS         := $(LN_HEADERS) $(LN_ARCH_HEADERS)
- headers: $(HEADERS)
- $(LN_HEADERS):
-       $(LN) -fs $(TOPDIR)../$@ $@
- $(LN_ARCH_HEADERS):
-       $(LN) -fs ../ldso/$(TARGET_ARCH)/$(patsubst include/%,%,$@) $@
--include/dl-progname.h:
--      echo '#include "$(TARGET_ARCH)/elfinterp.c"' \
--              > include/dl-progname.h
- clean:
-       set -e ; for d in $(DIRS) ; do $(MAKE) -C $$d $@ ; done
-diff -urN uClibc-0.9.28.orig/ldso/include/dl-defs.h uClibc-0.9.28/ldso/include/dl-defs.h
---- uClibc-0.9.28.orig/ldso/include/dl-defs.h  2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/include/dl-defs.h       2006-04-28 00:14:35.000000000 -0600
-@@ -1,6 +1,29 @@
-+/* vi: set sw=4 ts=4: */
-+/*
-+ * Copyright (C) 2000-2005 by Erik Andersen <andersen@codepoet.org>
-+ *
-+ * GNU Lesser General Public License version 2.1 or later.
-+ */
-+
- #ifndef _LD_DEFS_H
- #define _LD_DEFS_H
-+#define FLAG_ANY             -1
-+#define FLAG_TYPE_MASK       0x00ff
-+#define FLAG_LIBC4           0x0000
-+#define FLAG_ELF             0x0001
-+#define FLAG_ELF_LIBC5       0x0002
-+#define FLAG_ELF_LIBC6       0x0003
-+#define FLAG_ELF_UCLIBC      0x0004
-+#define FLAG_REQUIRED_MASK   0xff00
-+#define FLAG_SPARC_LIB64     0x0100
-+#define FLAG_IA64_LIB64      0x0200
-+#define FLAG_X8664_LIB64     0x0300
-+#define FLAG_S390_LIB64      0x0400
-+#define FLAG_POWERPC_LIB64   0x0500
-+#define FLAG_MIPS64_LIBN32   0x0600
-+#define FLAG_MIPS64_LIBN64   0x0700
-+
- #define LIB_ANY            -1
- #define LIB_DLL       0
- #define LIB_ELF       1
-diff -urN uClibc-0.9.28.orig/ldso/include/dl-elf.h uClibc-0.9.28/ldso/include/dl-elf.h
---- uClibc-0.9.28.orig/ldso/include/dl-elf.h   2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/include/dl-elf.h        2006-04-28 00:14:35.000000000 -0600
-@@ -1,3 +1,10 @@
-+/* vi: set sw=4 ts=4: */
-+/*
-+ * Copyright (C) 2000-2005 by Erik Andersen <andersen@codepoet.org>
-+ *
-+ * GNU Lesser General Public License version 2.1 or later.
-+ */
-+
- #ifndef LINUXELF_H
- #define LINUXELF_H
-diff -urN uClibc-0.9.28.orig/ldso/include/dl-hash.h uClibc-0.9.28/ldso/include/dl-hash.h
---- uClibc-0.9.28.orig/ldso/include/dl-hash.h  2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/include/dl-hash.h       2006-04-28 00:14:35.000000000 -0600
-@@ -1,3 +1,10 @@
-+/* vi: set sw=4 ts=4: */
-+/*
-+ * Copyright (C) 2000-2005 by Erik Andersen <andersen@codepoet.org>
-+ *
-+ * GNU Lesser General Public License version 2.1 or later.
-+ */
-+
- #ifndef _LD_HASH_H_
- #define _LD_HASH_H_
-@@ -32,15 +39,15 @@
-   unsigned short usage_count;
-   unsigned short int init_flag;
-   unsigned long rtld_flags; /* RTLD_GLOBAL, RTLD_NOW etc. */
--  Elf32_Word nbucket;
--  Elf32_Word *elf_buckets;
-+  Elf_Symndx nbucket;
-+  Elf_Symndx *elf_buckets;
-   struct init_fini_list *init_fini;
-   struct init_fini_list *rtld_local; /* keep tack of RTLD_LOCAL libs in same group */
-   /*
-    * These are only used with ELF style shared libraries
-    */
--  Elf32_Word nchain;
--  Elf32_Word *chains;
-+  Elf_Symndx nchain;
-+  Elf_Symndx *chains;
-   unsigned long dynamic_info[DYNAMIC_SIZE];
-   unsigned long n_phent;
-@@ -49,6 +56,9 @@
-   ElfW(Addr) relro_addr;
-   size_t relro_size;
-+  dev_t st_dev;      /* device */
-+  ino_t st_ino;      /* inode */
-+
- #ifdef __powerpc__
-   /* this is used to store the address of relocation data words, so
-    * we don't have to calculate it every time, which requires a divide */
-@@ -66,7 +76,6 @@
- extern struct elf_resolve * _dl_loaded_modules;
- extern struct dyn_elf           * _dl_handles;
--extern struct elf_resolve * _dl_check_hashed_files(const char * libname);
- extern struct elf_resolve * _dl_add_elf_hash_table(const char * libname, 
-       char * loadaddr, unsigned long * dynamic_info, 
-       unsigned long dynamic_addr, unsigned long dynamic_size);
-diff -urN uClibc-0.9.28.orig/ldso/include/dl-string.h uClibc-0.9.28/ldso/include/dl-string.h
---- uClibc-0.9.28.orig/ldso/include/dl-string.h        2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/include/dl-string.h     2006-04-28 00:14:35.000000000 -0600
-@@ -1,9 +1,24 @@
-+/* vi: set sw=4 ts=4: */
-+/*
-+ * Copyright (C) 2000-2005 by Erik Andersen <andersen@codepoet.org>
-+ *
-+ * GNU Lesser General Public License version 2.1 or later.
-+ */
-+
- #ifndef _LINUX_STRING_H_
- #define _LINUX_STRING_H_
--#include <dl-sysdep.h> // for do_rem
-+#include <dl-sysdep.h> /* for do_rem */
- #include <features.h>
-+/* provide some sane defaults */
-+#ifndef do_rem
-+# define do_rem(result, n, base) ((result) = (n) % (base))
-+#endif
-+#ifndef do_div_10
-+# define do_div_10(result, remain) ((result) /= 10)
-+#endif
-+
- static size_t _dl_strlen(const char * str);
- static char *_dl_strcat(char *dst, const char *src);
- static char * _dl_strcpy(char * dst,const char *src);
-@@ -26,8 +41,8 @@
- static __always_inline size_t _dl_strlen(const char * str)
- {
-       register const char *ptr = (char *) str-1;
--
--      while (*++ptr);
-+      while (*++ptr)
-+              ;/* empty */
-       return (ptr - str);
- }
-@@ -49,7 +64,8 @@
-       register char *ptr = dst;
-       dst--;src--;
--      while ((*++dst = *++src) != 0);
-+      while ((*++dst = *++src) != 0)
-+              ;/* empty */
-       return ptr;
- }
-@@ -63,8 +79,7 @@
-               c2 = (unsigned char) *++s2;
-               if (c1 == '\0')
-                       return c1 - c2;
--      }
--      while (c1 == c2);
-+      } while (c1 == c2);
-       return c1 - c2;
- }
-@@ -98,43 +113,41 @@
-       return 0;
- }
--static inline char * _dl_strrchr(const char *str, int c)
-+static __always_inline char * _dl_strrchr(const char *str, int c)
- {
--    register char *prev = 0;
--    register char *ptr = (char *) str-1;
-+      register char *prev = 0;
-+      register char *ptr = (char *) str-1;
--    while (*++ptr != '\0') {
--      if (*ptr == c)
--          prev = ptr;
--    }
--    if (c == '\0')
--      return(ptr);
--    return(prev);
-+      while (*++ptr != '\0') {
-+              if (*ptr == c)
-+                      prev = ptr;
-+      }
-+      if (c == '\0')
-+              return(ptr);
-+      return(prev);
- }
--static inline char * _dl_strstr(const char *s1, const char *s2)
-+static __always_inline char * _dl_strstr(const char *s1, const char *s2)
- {
--    register const char *s = s1;
--    register const char *p = s2;
-+      register const char *s = s1;
-+      register const char *p = s2;
--    do {
--        if (!*p) {
--          return (char *) s1;;
--      }
--      if (*p == *s) {
--          ++p;
--          ++s;
--      } else {
--          p = s2;
--          if (!*s) {
--            return NULL;
--          }
--          s = ++s1;
--      }
--    } while (1);
-+      do {
-+              if (!*p)
-+                      return (char *) s1;;
-+              if (*p == *s) {
-+                      ++p;
-+                      ++s;
-+              } else {
-+                      p = s2;
-+                      if (!*s)
-+                              return NULL;
-+                      s = ++s1;
-+              }
-+      } while (1);
- }
--static inline void * _dl_memcpy(void * dst, const void * src, size_t len)
-+static __always_inline void * _dl_memcpy(void * dst, const void * src, size_t len)
- {
-       register char *a = dst-1;
-       register const char *b = src-1;
-@@ -163,27 +176,28 @@
- /* Will generate smaller and faster code due to loop unrolling.*/
- static __always_inline void * _dl_memset(void *to, int c, size_t n)
- {
--        unsigned long chunks;
--        unsigned long *tmp_to;
-+      unsigned long chunks;
-+      unsigned long *tmp_to;
-       unsigned char *tmp_char;
--        chunks = n / 4;
--        tmp_to = to + n;
--        c = c << 8 | c;
--        c = c << 16 | c;
--        if (!chunks)
--                goto lessthan4;
--        do {
--                *--tmp_to = c;
--        } while (--chunks);
-- lessthan4:
--        n = n % 4;
--        if (!n ) return to;
--        tmp_char = (unsigned char *)tmp_to;
--        do {
--                *--tmp_char = c;
--        } while (--n);
--        return to;
-+      chunks = n / 4;
-+      tmp_to = to + n;
-+      c = c << 8 | c;
-+      c = c << 16 | c;
-+      if (!chunks)
-+              goto lessthan4;
-+      do {
-+              *--tmp_to = c;
-+      } while (--chunks);
-+lessthan4:
-+      n = n % 4;
-+      if (!n)
-+              return to;
-+      tmp_char = (unsigned char *)tmp_to;
-+      do {
-+              *--tmp_char = c;
-+      } while (--n);
-+      return to;
- }
- #else
- static __always_inline void * _dl_memset(void * str,int c,size_t len)
-@@ -225,10 +239,10 @@
-       char *p = &local[22];
-       *--p = '\0';
-       do {
--          char temp;
--          do_rem(temp, i, 10);
--          *--p = '0' + temp;
--          i /= 10;
-+              char temp;
-+              do_rem(temp, i, 10);
-+              *--p = '0' + temp;
-+              do_div_10(i, temp);
-       } while (i > 0);
-       return p;
- }
-@@ -242,9 +256,9 @@
-       do {
-               char temp = i & 0xf;
-               if (temp <= 0x09)
--                  *--p = '0' + temp;
-+                      *--p = '0' + temp;
-               else
--                  *--p = 'a' - 0x0a + temp;
-+                      *--p = 'a' - 0x0a + temp;
-               i >>= 4;
-       } while (i > 0);
-       *--p = 'x';
-@@ -270,8 +284,8 @@
- /* On some arches constant strings are referenced through the GOT.
-  * This requires that load_addr must already be defined... */
--#if defined(mc68000) || defined(__arm__) || defined(__mips__) \
--                     || defined(__sh__) ||  defined(__powerpc__)
-+#if defined(mc68000)  || defined(__arm__) || defined(__thumb__) || \
-+    defined(__mips__) || defined(__sh__)  || defined(__powerpc__)
- # define CONSTANT_STRING_GOT_FIXUP(X) \
-       if ((X) < (const char *) load_addr) (X) += load_addr
- # define NO_EARLY_SEND_STDERR
-@@ -318,7 +332,7 @@
-       do { \
-               do_rem(v, (X), 10); \
-               *--tmp2 = '0' + v; \
--              (X) /= 10; \
-+              do_div_10((X), v); \
-       } while ((X) > 0); \
-       _dl_write(2, tmp2, tmp1 - tmp2 + sizeof(tmp) - 1); \
- }
-diff -urN uClibc-0.9.28.orig/ldso/include/dl-syscall.h uClibc-0.9.28/ldso/include/dl-syscall.h
---- uClibc-0.9.28.orig/ldso/include/dl-syscall.h       2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/include/dl-syscall.h    2006-04-28 00:14:35.000000000 -0600
-@@ -1,3 +1,10 @@
-+/* vi: set sw=4 ts=4: */
-+/*
-+ * Copyright (C) 2000-2005 by Erik Andersen <andersen@codepoet.org>
-+ *
-+ * GNU Lesser General Public License version 2.1 or later.
-+ */
-+
- #ifndef _LD_SYSCALL_H_
- #define _LD_SYSCALL_H_
-@@ -12,9 +19,8 @@
- #include <bits/kernel_stat.h>
- #include <bits/kernel_types.h>
--
- /* _dl_open() parameters */
--#define O_RDONLY        0x0000
-+#define O_RDONLY           00
- #define O_WRONLY           01
- #define O_RDWR                     02
- #define O_CREAT                  0100
-@@ -39,18 +45,6 @@
- #define       S_IWRITE        0200    /* Write by owner.  */
- #define       S_IEXEC         0100    /* Execute by owner.  */
--/* Stuff for _dl_mmap */
--#if 0
--#define MAP_FAILED    ((void *) -1)
--#define _dl_mmap_check_error(X) (((void *)X) == MAP_FAILED)
--#else
--#ifndef _dl_MAX_ERRNO
--#define _dl_MAX_ERRNO 4096
--#endif
--#define _dl_mmap_check_error(__res) \
--      (((long)__res) < 0 && ((long)__res) >= -_dl_MAX_ERRNO)
--#endif
--
- /* Here are the definitions for some syscalls that are used
-@@ -66,54 +60,125 @@
- static inline _syscall1(int, _dl_close, int, fd);
- #define __NR__dl_open __NR_open
--static inline _syscall3(int, _dl_open, const char *, fn, int, flags, __kernel_mode_t, mode);
-+static inline _syscall3(int, _dl_open, const char *, fn, int, flags,
-+                        __kernel_mode_t, mode);
- #define __NR__dl_write __NR_write
- static inline _syscall3(unsigned long, _dl_write, int, fd,
--          const void *, buf, unsigned long, count);
-+                        const void *, buf, unsigned long, count);
- #define __NR__dl_read __NR_read
- static inline _syscall3(unsigned long, _dl_read, int, fd,
--          const void *, buf, unsigned long, count);
-+                        const void *, buf, unsigned long, count);
- #define __NR__dl_mprotect __NR_mprotect
--static inline _syscall3(int, _dl_mprotect, const void *, addr, unsigned long, len, int, prot);
-+static inline _syscall3(int, _dl_mprotect, const void *, addr,
-+                        unsigned long, len, int, prot);
- #define __NR__dl_stat __NR_stat
--static inline _syscall2(int, _dl_stat, const char *, file_name, struct stat *, buf);
-+static inline _syscall2(int, _dl_stat, const char *, file_name,
-+                        struct stat *, buf);
-+
-+#define __NR__dl_fstat __NR_fstat
-+static inline _syscall2(int, _dl_fstat, int, fd, struct stat *, buf);
- #define __NR__dl_munmap __NR_munmap
- static inline _syscall2(int, _dl_munmap, void *, start, unsigned long, length);
-+#ifdef __NR_getxuid
-+# define __NR_getuid __NR_getxuid
-+#endif
- #define __NR__dl_getuid __NR_getuid
- static inline _syscall0(uid_t, _dl_getuid);
-+#ifndef __NR_geteuid
-+# define __NR_geteuid __NR_getuid
-+#endif
- #define __NR__dl_geteuid __NR_geteuid
- static inline _syscall0(uid_t, _dl_geteuid);
-+#ifdef __NR_getxgid
-+# define __NR_getgid __NR_getxgid
-+#endif
- #define __NR__dl_getgid __NR_getgid
- static inline _syscall0(gid_t, _dl_getgid);
-+#ifndef __NR_getegid
-+# define __NR_getegid __NR_getgid
-+#endif
- #define __NR__dl_getegid __NR_getegid
- static inline _syscall0(gid_t, _dl_getegid);
-+#ifdef __NR_getxpid
-+# define __NR_getpid __NR_getxpid
-+#endif
- #define __NR__dl_getpid __NR_getpid
- static inline _syscall0(gid_t, _dl_getpid);
- #define __NR__dl_readlink __NR_readlink
--static inline _syscall3(int, _dl_readlink, const char *, path, char *, buf, size_t, bufsiz);
-+static inline _syscall3(int, _dl_readlink, const char *, path, char *, buf,
-+                        size_t, bufsiz);
--#ifdef __NR_mmap
--#ifdef MMAP_HAS_6_ARGS
--#define __NR__dl_mmap __NR_mmap
--static inline _syscall6(void *, _dl_mmap, void *, start, size_t, length,
--              int, prot, int, flags, int, fd, off_t, offset);
-+#ifdef __UCLIBC_HAS_SSP__
-+# include <sys/time.h>
-+# define __NR__dl_gettimeofday __NR_gettimeofday
-+static inline _syscall2(int, _dl_gettimeofday, struct timeval *, tv,
-+# ifdef __USE_BSD
-+                        struct timezone *, tz);
-+# else
-+                        void *, tz);
-+# endif
-+#endif
-+
-+
-+/* handle all the fun mmap intricacies */
-+#if (defined(__UCLIBC_MMAP_HAS_6_ARGS__) && defined(__NR_mmap)) || !defined(__NR_mmap2)
-+# define _dl_MAX_ERRNO 4096
-+# define _dl_mmap_check_error(__res) \
-+      (((long)__res) < 0 && ((long)__res) >= -_dl_MAX_ERRNO)
- #else
--#define __NR__dl_mmap_real __NR_mmap
--static inline _syscall1(void *, _dl_mmap_real, unsigned long *, buffer);
-+# define MAP_FAILED ((void *) -1)
-+# define _dl_mmap_check_error(X) (((void *)X) == MAP_FAILED)
-+#endif
-+
-+/* first try mmap(), syscall6() style */
-+#if defined(__UCLIBC_MMAP_HAS_6_ARGS__) && defined(__NR_mmap)
-+
-+# define __NR__dl_mmap __NR_mmap
-+static inline _syscall6(void *, _dl_mmap, void *, start, size_t, length,
-+                        int, prot, int, flags, int, fd, off_t, offset);
-+
-+/* then try mmap2() */
-+#elif defined(__NR_mmap2)
-+
-+# define __NR___syscall_mmap2       __NR_mmap2
-+static inline _syscall6(__ptr_t, __syscall_mmap2, __ptr_t, addr, size_t, len,
-+                        int, prot, int, flags, int, fd, off_t, offset);
-+
-+/* Some architectures always use 12 as page shift for mmap2() eventhough the
-+ * real PAGE_SHIFT != 12.  Other architectures use the same value as
-+ * PAGE_SHIFT...
-+ */
-+#ifndef MMAP2_PAGE_SHIFT
-+# define MMAP2_PAGE_SHIFT 12
-+#endif
- static inline void * _dl_mmap(void * addr, unsigned long size, int prot,
--              int flags, int fd, unsigned long offset)
-+                              int flags, int fd, unsigned long offset)
-+{
-+      if (offset & ((1 << MMAP2_PAGE_SHIFT) - 1))
-+              return MAP_FAILED;
-+      return __syscall_mmap2(addr, size, prot, flags,
-+                             fd, (off_t) (offset >> MMAP2_PAGE_SHIFT));
-+}
-+
-+/* finally, fall back to mmap(), syscall1() style */
-+#elif defined(__NR_mmap)
-+
-+# define __NR__dl_mmap_real __NR_mmap
-+static inline _syscall1(void *, _dl_mmap_real, unsigned long *, buffer);
-+static inline void * _dl_mmap(void * addr, unsigned long size, int prot,
-+                              int flags, int fd, unsigned long offset)
- {
-       unsigned long buffer[6];
-@@ -125,24 +190,9 @@
-       buffer[5] = (unsigned long) offset;
-       return (void *) _dl_mmap_real(buffer);
- }
--#endif
--#elif defined __NR_mmap2
--#define __NR___syscall_mmap2       __NR_mmap2
--static inline _syscall6(__ptr_t, __syscall_mmap2, __ptr_t, addr,
--              size_t, len, int, prot, int, flags, int, fd, off_t, offset);
--/*always 12, even on architectures where PAGE_SHIFT != 12 */
--#define MMAP2_PAGE_SHIFT 12
--static inline void * _dl_mmap(void * addr, unsigned long size, int prot,
--              int flags, int fd, unsigned long offset)
--{
--    if (offset & ((1 << MMAP2_PAGE_SHIFT) - 1))
--      return MAP_FAILED;
--    return(__syscall_mmap2(addr, size, prot, flags,
--              fd, (off_t) (offset >> MMAP2_PAGE_SHIFT)));
--}
-+
- #else
--#error "Your architecture doesn't seem to provide mmap() !?"
-+# error "Your architecture doesn't seem to provide mmap() !?"
- #endif
- #endif /* _LD_SYSCALL_H_ */
--
-diff -urN uClibc-0.9.28.orig/ldso/include/dlfcn.h uClibc-0.9.28/ldso/include/dlfcn.h
---- uClibc-0.9.28.orig/ldso/include/dlfcn.h    2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/include/dlfcn.h 2006-04-28 00:14:35.000000000 -0600
-@@ -1,3 +1,10 @@
-+/* vi: set sw=4 ts=4: */
-+/*
-+ * Copyright (C) 2000-2005 by Erik Andersen <andersen@codepoet.org>
-+ *
-+ * GNU Lesser General Public License version 2.1 or later.
-+ */
-+
- /* User functions for run-time dynamic loading.  libdl version */
- #ifndef       _DLFCN_H
- #define       _DLFCN_H 1
-diff -urN uClibc-0.9.28.orig/ldso/include/ldso.h uClibc-0.9.28/ldso/include/ldso.h
---- uClibc-0.9.28.orig/ldso/include/ldso.h     2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/include/ldso.h  2006-04-28 00:14:35.000000000 -0600
-@@ -1,3 +1,10 @@
-+/* vi: set sw=4 ts=4: */
-+/*
-+ * Copyright (C) 2000-2005 by Erik Andersen <andersen@codepoet.org>
-+ *
-+ * GNU Lesser General Public License version 2.1 or later.
-+ */
-+
- #ifndef _LDSO_H_
- #define _LDSO_H_
-@@ -20,13 +27,15 @@
- /* Pull in compiler and arch stuff */
- #include <stdlib.h>
- #include <stdarg.h>
-+#include <bits/wordsize.h>
- /* Pull in the arch specific type information */
- #include <sys/types.h>
-+/* Pull in the arch specific page size */
-+#include <bits/uClibc_page.h>
-+#define attribute_unused __attribute__ ((unused))
- /* Pull in the ldso syscalls and string functions */
- #include <dl-syscall.h>
- #include <dl-string.h>
--/* Pull in the arch specific page size */
--#include <bits/uClibc_page.h>
- /* Now the ldso specific headers */
- #include <dl-elf.h>
- #include <dl-hash.h>
-diff -urN uClibc-0.9.28.orig/ldso/include/unsecvars.h uClibc-0.9.28/ldso/include/unsecvars.h
---- uClibc-0.9.28.orig/ldso/include/unsecvars.h        2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/include/unsecvars.h     2006-04-28 00:14:35.000000000 -0600
-@@ -1,3 +1,10 @@
-+/* vi: set sw=4 ts=4: */
-+/*
-+ * Copyright (C) 2000-2005 by Erik Andersen <andersen@codepoet.org>
-+ *
-+ * GNU Lesser General Public License version 2.1 or later.
-+ */
-+
- /* 
-  * Environment variable to be removed for SUID programs.  The names are all
-  * stuffed in a single string which means they have to be terminated with a
-@@ -5,22 +12,21 @@
-  */
- #define UNSECURE_ENVVARS \
--      "LD_AOUT_PRELOAD\0" \
--      "LD_AOUT_LIBRARY_PATH\0" \
-       "LD_PRELOAD\0" \
-       "LD_LIBRARY_PATH\0" \
-       "LD_DEBUG\0" \
-       "LD_DEBUG_OUTPUT\0" \
-       "LD_TRACE_LOADED_OBJECTS\0" \
--      "HOSTALIASES\0" \
--      "LOCALDOMAIN\0" \
--      "RES_OPTIONS\0" \
-       "TMPDIR\0"
- /* 
-+ * LD_TRACE_LOADED_OBJECTS is not in glibc-2.3.5's unsecvars.h
-+ * though used by ldd
-+ *
-  * These environment variables are defined by glibc but ignored in
-  * uClibc, but may very well have an equivalent in uClibc.
-  *
-- * MALLOC_TRACE, RESOLV_HOST_CONF, TZDIR, GCONV_PATH, LD_USE_LOAD_BIAS,
-- * LD_PROFILE, LD_ORIGIN_PATH, LOCPATH, NLSPATH
-+ * LD_ORIGIN_PATH, LD_PROFILE, LD_USE_LOAD_BIAS, LD_DYNAMIC_WEAK, LD_SHOW_AUXV,
-+ * GCONV_PATH, GETCONF_DIR, HOSTALIASES, LOCALDOMAIN, LOCPATH, MALLOC_TRACE,
-+ * NLSPATH, RESOLV_HOST_CONF, RES_OPTIONS, TZDIR
-  */
-diff -urN uClibc-0.9.28.orig/ldso/ldso/Makefile uClibc-0.9.28/ldso/ldso/Makefile
---- uClibc-0.9.28.orig/ldso/ldso/Makefile      2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/Makefile   2006-04-28 00:14:35.000000000 -0600
-@@ -42,7 +42,9 @@
- endif
- XXFLAGS+= -DUCLIBC_LDSO=\"$(UCLIBC_LDSO)\" $(XARCH_CFLAGS) $(CPU_CFLAGS) $(PICFLAG) \
-       -DUCLIBC_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" \
--      -fno-builtin -nostdinc -D_LIBC -I$(TOPDIR)ldso/include -I. -I$(TOPDIR)include
-+      -fno-builtin -nostdinc -D_LIBC \
-+      -DLDSO_ELFINTERP=\"$(TARGET_ARCH)/elfinterp.c\" \
-+      -I$(TOPDIR)ldso/ldso/$(TARGET_ARCH) -I$(TOPDIR)ldso/include -I$(TOPDIR)ldso/ldso -I$(TOPDIR)include
- # BEWARE!!! At least mips* will die if -O0 is used!!!
- XXFLAGS:=$(XXFLAGS:-O0=-O1)
-diff -urN uClibc-0.9.28.orig/ldso/ldso/arm/dl-startup.h uClibc-0.9.28/ldso/ldso/arm/dl-startup.h
---- uClibc-0.9.28.orig/ldso/ldso/arm/dl-startup.h      2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/arm/dl-startup.h   2006-04-28 00:14:35.000000000 -0600
-@@ -1,10 +1,15 @@
- /* vi: set sw=4 ts=4: */
- /*
-  * Architecture specific code used by dl-startup.c
-- * Copyright (C) 2000-2004 by Erik Andersen <andersen@codepoet.org>
-+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
-+ *
-+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
-  */
--asm(
-+#include <features.h>
-+
-+#if !defined(__thumb__)
-+__asm__(
-     " .text\n"
-     " .globl  _start\n"
-     " .type   _start,%function\n"
-@@ -40,7 +45,78 @@
-       "       ldr     r0, .L_FINI_PROC\n"
-       "       ldr     r0, [sl, r0]\n"
-       "       @ jump to the user_s entry point\n"
-+#if defined(__USE_BX__)
-+      "       bx      r6\n"
-+#else
-+      "       mov     pc, r6\n"
-+#endif
-+      ".L_GET_GOT:\n"
-+      "       .word   _GLOBAL_OFFSET_TABLE_ - .L_GOT_GOT - 4\n"
-+      ".L_SKIP_ARGS:\n"
-+      "       .word   _dl_skip_args(GOTOFF)\n"
-+      ".L_FINI_PROC:\n"
-+      "       .word   _dl_fini(GOT)\n"
-+      "\n\n"
-+    " .size   _start,.-_start\n"
-+      ".previous\n"
-+);
-+#else
-+__asm__(
-+    " .text\n"
-+    " .arm\n"
-+    " .globl  _start\n"
-+    " .type   _start,%function\n"
-+      "_start:\n"
-+      "       @ dumb: can't persuade the linker to make the start address\n"
-+      "       @ odd, so use an arm function and change to thumb (_dl_start\n"
-+      "       @ is thumb)\n"
-+      "       adr     r0, __dl_thumb_start+1\n"
-+      "       bx      r0\n"
-+      "\n\n"
-+    " .thumb\n"
-+    " .globl  __dl_thumb_start\n"
-+    " .thumb_func\n"
-+    " .type   __dl_thumb_start,%function\n"
-+      "__dl_thumb_start:\n"
-+      "       @ at start time, all the args are on the stack\n"
-+      "       mov     r0, sp\n"
-+      "       bl      _dl_start\n"
-+      "       @ returns user entry point in r0\n"
-+      "       mov     r6, r0\n"
-+      "       @ we are PIC code, so get global offset table\n"
-+      "       ldr     r7, .L_GET_GOT\n"
-+      ".L_GOT_GOT:\n"
-+      "       add     r7, pc\n"
-+      "       @ See if we were run as a command with the executable file\n"
-+      "       @ name as an extra leading argument.\n"
-+      "       ldr     r4, .L_SKIP_ARGS\n"
-+      "       ldr     r4, [r7, r4]\n"
-+      "       @ get the original arg count\n"
-+      "       ldr     r1, [sp]\n"
-+      "       @ subtract _dl_skip_args from it\n"
-+      "       sub     r1, r1, r4\n"
-+      "       @ adjust the stack pointer to skip them\n"
-+      "       lsl     r4, r4, #2\n"
-+      "       add     sp, r4\n"
-+      "       @ get the argv address\n"
-+      "       add     r2, sp, #4\n"
-+      "       @ store the new argc in the new stack location\n"
-+      "       str     r1, [sp]\n"
-+      "       @ compute envp\n"
-+      "       lsl     r3, r1, #2\n"
-+      "       add     r3, r3, r2\n"
-+      "       add     r3, #4\n"
-+      "\n\n"
-+      "       @ load the finalizer function\n"
-+      "       ldr     r0, .L_FINI_PROC\n"
-+      "       ldr     r0, [r7, r0]\n"
-+      "       @ jump to the user_s entry point\n"
-+#if defined(__USE_BX__)
-+      "       bx      r6\n"
-+#else
-       "       mov     pc, r6\n"
-+#endif
-+      "\n\n"
-       ".L_GET_GOT:\n"
-       "       .word   _GLOBAL_OFFSET_TABLE_ - .L_GOT_GOT - 4\n"
-       ".L_SKIP_ARGS:\n"
-@@ -51,6 +127,7 @@
-     " .size   _start,.-_start\n"
-       ".previous\n"
- );
-+#endif
- /* Get a pointer to the argv array.  On many platforms this can be just
-@@ -115,9 +192,3 @@
-                       _dl_exit(1);
-       }
- }
--
--
--/* Transfer control to the user's application, once the dynamic loader is
-- * done.  This routine has to exit the current function, then call the
-- * _dl_elf_main function.  */
--#define START()   return _dl_elf_main;
-diff -urN uClibc-0.9.28.orig/ldso/ldso/arm/dl-syscalls.h uClibc-0.9.28/ldso/ldso/arm/dl-syscalls.h
---- uClibc-0.9.28.orig/ldso/ldso/arm/dl-syscalls.h     2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/arm/dl-syscalls.h  2006-04-28 00:14:35.000000000 -0600
-@@ -1,6 +1,7 @@
- /* We can't use the real errno in ldso, since it has not yet
-  * been dynamicly linked in yet. */
-+#include "sys/syscall.h"
- extern int _dl_errno;
-+#undef __set_errno
- #define __set_errno(X) {(_dl_errno) = (X);}
--#include "sys/syscall.h"
-diff -urN uClibc-0.9.28.orig/ldso/ldso/arm/dl-sysdep.h uClibc-0.9.28/ldso/ldso/arm/dl-sysdep.h
---- uClibc-0.9.28.orig/ldso/ldso/arm/dl-sysdep.h       2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/arm/dl-sysdep.h    2006-04-28 00:14:35.000000000 -0600
-@@ -43,6 +43,7 @@
-       return m;
- }
- #define do_rem(result, n, base) ((result) = arm_modulus(n, base))
-+#define do_div_10(result, remain) ((result) = (((result) - (remain)) / 2) * -(-1ul / 5ul))
- /* Here we define the magic numbers that this dynamic loader should accept */
- #define MAGIC1 EM_ARM
-@@ -85,7 +86,25 @@
-       extern void __dl_start asm ("_dl_start");
-       Elf32_Addr got_addr = (Elf32_Addr) &__dl_start;
-       Elf32_Addr pcrel_addr;
-+#if !defined __thumb__
-       asm ("adr %0, _dl_start" : "=r" (pcrel_addr));
-+#else
-+      int tmp;
-+      /* The above adr will not work on thumb because it
-+       * is negative.  The only safe way is to temporarily
-+       * swap to arm.
-+       */
-+      asm(   ".align  2\n"
-+      "       bx      pc\n"
-+      "       nop     \n"
-+      "       .arm    \n"
-+      "       adr     %0, _dl_start\n"
-+      "       .align  2\n"
-+      "       orr     %1, pc, #1\n"
-+      "       bx      %1\n"
-+      "       .force_thumb\n"
-+      : "=r" (pcrel_addr), "=&r" (tmp));
-+#endif
-       return pcrel_addr - got_addr;
- }
-diff -urN uClibc-0.9.28.orig/ldso/ldso/arm/elfinterp.c uClibc-0.9.28/ldso/ldso/arm/elfinterp.c
---- uClibc-0.9.28.orig/ldso/ldso/arm/elfinterp.c       2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/arm/elfinterp.c    2006-04-28 00:14:35.000000000 -0600
-@@ -38,6 +38,8 @@
-    a more than adequate job of explaining everything required to get this
-    working. */
-+#include "ldso.h"
-+
- extern int _dl_linux_resolve(void);
- unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
-@@ -63,7 +65,6 @@
-       strtab = (char *) tpnt->dynamic_info[DT_STRTAB];
-       symname = strtab + symtab[symtab_index].st_name;
--
-       if (unlikely(reloc_type != R_ARM_JUMP_SLOT)) {
-               _dl_dprintf(2, "%s: Incorrect relocation type in jump relocations\n",
-                       _dl_progname);
-diff -urN uClibc-0.9.28.orig/ldso/ldso/cris/dl-startup.h uClibc-0.9.28/ldso/ldso/cris/dl-startup.h
---- uClibc-0.9.28.orig/ldso/ldso/cris/dl-startup.h     2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/cris/dl-startup.h  2006-04-28 00:14:35.000000000 -0600
-@@ -4,22 +4,43 @@
- /* This code fixes the stack pointer so that the dynamic linker
-  * can find argc, argv and auxvt (Auxillary Vector Table).  */
-+#ifdef __arch_v32
-+
-+asm(""                                        \
-+"     .text\n"                        \
-+"     .globl _start\n"                \
-+"     .type _start,@function\n"       \
-+"_start:\n"                           \
-+"     move.d  $sp,$r10\n"             \
-+"     lapc    _dl_start,$r9\n"        \
-+"     jsr     $r9\n"                  \
-+"     nop\n"                          \
-+"     moveq   0,$r8\n"                \
-+"     jump    $r10\n"                 \
-+"     move    $r8,$srp\n"             \
-+"     .size _start,.-_start\n"        \
-+"     .previous\n"                    \
-+);
-+
-+#else
-+
- asm(""                                        \
- "     .text\n"                        \
- "     .globl _start\n"                \
- "     .type _start,@function\n"       \
- "_start:\n"                           \
--"     move.d $sp,$r10\n"              \
--"     move.d $pc,$r9\n"               \
--"     add.d _dl_start - ., $r9\n"     \
--"     jsr $r9\n"                      \
--"     moveq 0,$r8\n"                  \
--"     move $r8,$srp\n"                \
--"     jump $r10\n"                    \
-+"     move.d  $sp,$r10\n"             \
-+"     move.d  $pc,$r9\n"              \
-+"     add.d   _dl_start - ., $r9\n"   \
-+"     jsr     $r9\n"                  \
-+"     moveq   0,$r8\n"                \
-+"     move    $r8,$srp\n"             \
-+"     jump    $r10\n"                 \
- "     .size _start,.-_start\n"        \
- "     .previous\n"                    \
- );
-+#endif /* __arch_v32 */
- /* Get a pointer to the argv array.  On many platforms this can be just
-  * the address if the first argument, on other platforms we need to
-@@ -58,8 +79,3 @@
-                       break;
-       }
- }
--
--/* Transfer control to the user's application, once the dynamic loader is
-- * done.  This routine has to exit the current function, then call the
-- * _dl_elf_main function.  */
--#define START()     return _dl_elf_main
-diff -urN uClibc-0.9.28.orig/ldso/ldso/cris/dl-syscalls.h uClibc-0.9.28/ldso/ldso/cris/dl-syscalls.h
---- uClibc-0.9.28.orig/ldso/ldso/cris/dl-syscalls.h    2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/cris/dl-syscalls.h 2006-04-28 00:14:35.000000000 -0600
-@@ -1,5 +1,6 @@
- /* We can't use the real errno in ldso, since it has not yet
-  * been dynamicly linked in yet. */
-+#include "sys/syscall.h"
- extern int _dl_errno;
-+#undef __set_errno
- #define __set_errno(X) {(_dl_errno) = (X);}
--#include "sys/syscall.h"
-diff -urN uClibc-0.9.28.orig/ldso/ldso/cris/dl-sysdep.h uClibc-0.9.28/ldso/ldso/cris/dl-sysdep.h
---- uClibc-0.9.28.orig/ldso/ldso/cris/dl-sysdep.h      2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/cris/dl-sysdep.h   2006-04-28 00:14:35.000000000 -0600
-@@ -18,8 +18,6 @@
- struct elf_resolve;
- extern unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry);
--#define do_rem(result, n, base) ((result) = (n) % (base))
--
- /* 8192 bytes alignment */
- #define PAGE_ALIGN 0xffffe000
- #define ADDR_ALIGN 0x1fff
-@@ -68,8 +66,32 @@
- {
-       Elf32_Addr gotaddr_diff;
-+#ifdef __arch_v32
-+      extern char ___CRISv32_dummy[] __asm__ ("_dl_start");
-+
-+      __asm__ ("addo.w _dl_start:GOT16,$r0,$acr\n\t"
-+               "lapc _dl_start,%0\n\t"
-+               "sub.d [$acr],%0"
-+               /* For v32, we need to force GCC to have R0 loaded with
-+                  _GLOBAL_OFFSET_TABLE_ at this point, which might not
-+                  otherwise have happened in the caller.  (For v10, it's
-+                  loaded for non-global variables too, so we don't need
-+                  anything special there.)  We accomplish this by faking the
-+                  address of a global variable (as seen by GCC) as input to
-+                  the asm; that address calculation goes through the GOT.
-+                  Use of this function happens before we've filled in the
-+                  GOT, so the address itself will not be correctly
-+                  calculated, therefore we don't use any symbol whose
-+                  address may be re-used later on.  Let's just reuse the
-+                  _dl_start symbol, faking it as a global by renaming it as
-+                  another variable through an asm.  */
-+               : "=r" (gotaddr_diff)
-+               : "g" (___CRISv32_dummy)
-+               : "acr");
-+#else
-       __asm__ ("sub.d [$r0+_dl_start:GOT16],$r0,%0\n\t"
-                "add.d _dl_start:GOTOFF,%0" : "=r" (gotaddr_diff));
-+#endif
-       return gotaddr_diff;
- }
-diff -urN uClibc-0.9.28.orig/ldso/ldso/cris/resolve.S uClibc-0.9.28/ldso/ldso/cris/resolve.S
---- uClibc-0.9.28.orig/ldso/ldso/cris/resolve.S        2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/cris/resolve.S     2006-04-28 00:14:35.000000000 -0600
-@@ -17,33 +17,73 @@
- .globl _dl_linux_resolve
- .type _dl_linux_resolve,@function
-+#ifdef __arch_v32
-+
-+_dl_linux_resolve:
-+      subq    4,$sp
-+      move.d  $r0,[$sp]
-+      subq    4,$sp
-+      move.d  $r13,[$sp]
-+      subq    4,$sp
-+      move.d  $r12,[$sp]
-+      subq    4,$sp
-+      move.d  $r11,[$sp]
-+      subq    4,$sp
-+      addoq   5*4,$sp,$acr
-+      move.d  $r10,[$sp]
-+      subq    4,$sp
-+      move    $mof,$r10
-+      move.d  $r9,[$sp]
-+      subq    4,$sp
-+      move.d  [$acr],$r11
-+      move    $srp,[$sp]
-+      lapc    _GLOBAL_OFFSET_TABLE_,$r0
-+      move.d  _dl_linux_resolver:PLTG,$r9
-+      add.d   $r0,$r9
-+      jsr     $r9
-+      nop
-+      move.d  $r10,$acr
-+      move    [$sp+],$srp
-+      move.d  [$sp+],$r9
-+      move.d  [$sp+],$r10
-+      move.d  [$sp+],$r11
-+      move.d  [$sp+],$r12
-+      move.d  [$sp+],$r13
-+      move.d  [$sp+],$r0
-+      jump    $acr
-+      addq    4,$sp
-+
-+#else
-+
- _dl_linux_resolve:
--      push $r13
--      push $r12
--      push $r11
--      push $r10
--      push $r9
--      push $r0
--      push $srp
--      move.d [$sp+7*4],$r11
--      move $mof,$r10
-+      push    $r13
-+      push    $r12
-+      push    $r11
-+      push    $r10
-+      push    $r9
-+      push    $r0
-+      push    $srp
-+      move.d  [$sp+7*4],$r11
-+      move    $mof,$r10
- #ifdef __PIC__
--      move.d $pc,$r0
--      sub.d .:GOTOFF,$r0
--      move.d _dl_linux_resolver:PLTG,$r9
--      add.d $r0,$r9
--      jsr $r9
-+      move.d  $pc,$r0
-+      sub.d   .:GOTOFF,$r0
-+      move.d  _dl_linux_resolver:PLTG,$r9
-+      add.d   $r0,$r9
-+      jsr     $r9
- #else
--      jsr _dl_linux_resolver
-+      jsr     _dl_linux_resolver
- #endif
--      move.d $r10,[$sp+7*4]
--      pop $srp
--      pop $r0
--      pop $r9
--      pop $r10
--      pop $r11
--      pop $r12
--      pop $r13
--      jump [$sp+]
-+      move.d  $r10,[$sp+7*4]
-+      pop     $srp
-+      pop     $r0
-+      pop     $r9
-+      pop     $r10
-+      pop     $r11
-+      pop     $r12
-+      pop     $r13
-+      jump    [$sp+]
-+
-+#endif /* __arch_v32 */
-       .size _dl_linux_resolve, . - _dl_linux_resolve
-diff -urN uClibc-0.9.28.orig/ldso/ldso/dl-elf.c uClibc-0.9.28/ldso/ldso/dl-elf.c
---- uClibc-0.9.28.orig/ldso/ldso/dl-elf.c      2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/dl-elf.c   2006-05-02 13:50:58.000000000 -0600
-@@ -3,7 +3,7 @@
-  * This file contains the helper routines to load an ELF shared
-  * library into memory and add the symbol table info to the chain.
-  *
-- * Copyright (C) 2000-2004 by Erik Andersen <andersen@codepoet.org>
-+ * Copyright (C) 2000-2006 by Erik Andersen <andersen@codepoet.org>
-  * Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald,
-  *                            David Engel, Hongjiu Lu and Mitch D'Souza
-  *
-@@ -60,8 +60,8 @@
-       _dl_cache_addr = (caddr_t) _dl_mmap(0, _dl_cache_size, PROT_READ, MAP_SHARED, fd, 0);
-       _dl_close(fd);
-       if (_dl_mmap_check_error(_dl_cache_addr)) {
--              _dl_dprintf(2, "%s: can't map cache '%s'\n",
--                              _dl_progname, LDSO_CACHE);
-+              _dl_dprintf(2, "%s:%i: can't map '%s'\n",
-+                              _dl_progname, __LINE__, LDSO_CACHE);
-               return -1;
-       }
-@@ -115,7 +115,7 @@
- #endif
--void 
-+void
- _dl_protect_relro (struct elf_resolve *l)
- {
-       ElfW(Addr) start = ((l->loadaddr + l->relro_addr)
-@@ -136,27 +136,41 @@
- search_for_named_library(const char *name, int secure, const char *path_list,
-       struct dyn_elf **rpnt)
- {
--      char *path, *path_n;
--      char mylibname[2050];
-+      char *path, *path_n, *mylibname;
-       struct elf_resolve *tpnt;
--      int done = 0;
-+      int done;
-       if (path_list==NULL)
-               return NULL;
--      /* We need a writable copy of this string */
--      path = _dl_strdup(path_list);
--      if (!path) {
-+      /* We need a writable copy of this string, but we don't
-+       * need this allocated permanently since we don't want
-+       * to leak memory, so use alloca to put path on the stack */
-+      done = _dl_strlen(path_list);
-+      path = alloca(done + 1);
-+
-+      /* another bit of local storage */
-+      mylibname = alloca(2050);
-+
-+      /* gcc inlines alloca using a single instruction adjusting
-+       * the stack pointer and no stack overflow check and thus
-+       * no NULL error return.  No point leaving in dead code... */
-+#if 0
-+      if (!path || !mylibname) {
-               _dl_dprintf(2, "Out of memory!\n");
-               _dl_exit(0);
-       }
-+#endif
-+
-+      _dl_memcpy(path, path_list, done+1);
-       /* Unlike ldd.c, don't bother to eliminate double //s */
-       /* Replace colons with zeros in path_list */
-       /* : at the beginning or end of path maps to CWD */
-       /* :: anywhere maps CWD */
--      /* "" maps to CWD */ 
-+      /* "" maps to CWD */
-+      done = 0;
-       path_n = path;
-       do {
-               if (*path == 0) {
-@@ -180,71 +194,6 @@
-       return NULL;
- }
--/* Check if the named library is already loaded... */
--struct elf_resolve *_dl_check_if_named_library_is_loaded(const char *full_libname,
--              int trace_loaded_objects)
--{
--      const char *pnt, *pnt1;
--      struct elf_resolve *tpnt1;
--      const char *libname, *libname2;
--      static const char libc[] = "libc.so.";
--      static const char aborted_wrong_lib[] = "%s: aborted attempt to load %s!\n";
--
--      pnt = libname = full_libname;
--
--      _dl_if_debug_dprint("Checking if '%s' is already loaded\n", full_libname);
--      /* quick hack to ensure mylibname buffer doesn't overflow.  don't
--         allow full_libname or any directory to be longer than 1024. */
--      if (_dl_strlen(full_libname) > 1024)
--              return NULL;
--
--      /* Skip over any initial initial './' and '/' stuff to
--       * get the short form libname with no path garbage */
--      pnt1 = _dl_strrchr(pnt, '/');
--      if (pnt1) {
--              libname = pnt1 + 1;
--      }
--
--      /* Make sure they are not trying to load the wrong C library!
--       * This sometimes happens esp with shared libraries when the
--       * library path is somehow wrong! */
--#define isdigit(c)  (c >= '0' && c <= '9')
--      if ((_dl_strncmp(libname, libc, 8) == 0) &&  _dl_strlen(libname) >=8 &&
--                      isdigit(libname[8]))
--      {
--              /* Abort attempts to load glibc, libc5, etc */
--              if ( libname[8]!='0') {
--                      if (!trace_loaded_objects) {
--                              _dl_dprintf(2, aborted_wrong_lib, libname, _dl_progname);
--                              _dl_exit(1);
--                      }
--                      return NULL;
--              }
--      }
--
--      /* Critical step!  Weed out duplicates early to avoid
--       * function aliasing, which wastes memory, and causes
--       * really bad things to happen with weaks and globals. */
--      for (tpnt1 = _dl_loaded_modules; tpnt1; tpnt1 = tpnt1->next) {
--
--              /* Skip over any initial initial './' and '/' stuff to
--               * get the short form libname with no path garbage */
--              libname2 = tpnt1->libname;
--              pnt1 = _dl_strrchr(libname2, '/');
--              if (pnt1) {
--                      libname2 = pnt1 + 1;
--              }
--
--              if (_dl_strcmp(libname2, libname) == 0) {
--                      /* Well, that was certainly easy */
--                      return tpnt1;
--              }
--      }
--
--      return NULL;
--}
--
--
- /* Used to return error codes back to dlopen et. al.  */
- unsigned long _dl_error_number;
- unsigned long _dl_internal_error_number;
-@@ -271,14 +220,6 @@
-               libname = pnt + 1;
-       }
--      /* Critical step!  Weed out duplicates early to avoid
--       * function aliasing, which wastes memory, and causes
--       * really bad things to happen with weaks and globals. */
--      if ((tpnt1=_dl_check_if_named_library_is_loaded(libname, trace_loaded_objects))!=NULL) {
--              tpnt1->usage_count++;
--              return tpnt1;
--      }
--
-       _dl_if_debug_dprint("\tfind library='%s'; searching\n", libname);
-       /* If the filename has any '/', try it straight and leave it at that.
-          For IBCS2 compatibility under linux, we substitute the string
-@@ -290,7 +231,6 @@
-               if (tpnt1) {
-                       return tpnt1;
-               }
--              //goto goof;
-       }
-       /*
-@@ -411,56 +351,45 @@
-       int i, flags, piclib, infile;
-       ElfW(Addr) relro_addr = 0;
-       size_t relro_size = 0;
--
--      /* If this file is already loaded, skip this step */
--      tpnt = _dl_check_hashed_files(libname);
--      if (tpnt) {
--              if (*rpnt) {
--                      (*rpnt)->next = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
--                      _dl_memset((*rpnt)->next, 0, sizeof(struct dyn_elf));
--                      (*rpnt)->next->prev = (*rpnt);
--                      *rpnt = (*rpnt)->next;
--                      (*rpnt)->dyn = tpnt;
--                      tpnt->symbol_scope = _dl_symbol_tables;
--              }
--              tpnt->usage_count++;
--              tpnt->libtype = elf_lib;
--              _dl_if_debug_dprint("file='%s';  already loaded\n", libname);
--              return tpnt;
--      }
--
--      /* If we are in secure mode (i.e. a setu/gid binary using LD_PRELOAD),
--         we don't load the library if it isn't setuid. */
--
--      if (secure) {
--              struct stat st;
--
--              if (_dl_stat(libname, &st) || !(st.st_mode & S_ISUID))
--                      return NULL;
--      }
-+      struct stat st;
-       libaddr = 0;
-       infile = _dl_open(libname, O_RDONLY, 0);
-       if (infile < 0) {
--#if 0
--              /*
--               * NO!  When we open shared libraries we may search several paths.
--               * it is inappropriate to generate an error here.
--               */
--              _dl_dprintf(2, "%s: can't open '%s'\n", _dl_progname, libname);
--#endif
-               _dl_internal_error_number = LD_ERROR_NOFILE;
-               return NULL;
-       }
-+      if (_dl_fstat(infile, &st) < 0) {
-+              _dl_internal_error_number = LD_ERROR_NOFILE;
-+              _dl_close(infile);
-+              return NULL;
-+      }
-+      /* If we are in secure mode (i.e. a setu/gid binary using LD_PRELOAD),
-+         we don't load the library if it isn't setuid. */
-+      if (secure)
-+              if (!(st.st_mode & S_ISUID)) {
-+                      _dl_close(infile);
-+                      return NULL;
-+              }
-+
-+      /* Check if file is already loaded */
-+      for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
-+              if(tpnt->st_dev == st.st_dev && tpnt->st_ino == st.st_ino) {
-+                      /* Already loaded */
-+                      tpnt->usage_count++;
-+                      _dl_close(infile);
-+                      return tpnt;
-+              }
-+      }
-       header = _dl_mmap((void *) 0, _dl_pagesize, PROT_READ | PROT_WRITE,
-                       MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-       if (_dl_mmap_check_error(header)) {
--              _dl_dprintf(2, "%s: can't map '%s'\n", _dl_progname, libname);
-+              _dl_dprintf(2, "%s:%i: can't map '%s'\n", _dl_progname, __LINE__, libname);
-               _dl_internal_error_number = LD_ERROR_MMAP_FAILED;
-               _dl_close(infile);
-               return NULL;
--      };
-+      }
-       _dl_read(infile, header, _dl_pagesize);
-       epnt = (ElfW(Ehdr) *) (intptr_t) header;
-@@ -475,7 +404,7 @@
-               _dl_close(infile);
-               _dl_munmap(header, _dl_pagesize);
-               return NULL;
--      };
-+      }
-       if ((epnt->e_type != ET_DYN) || (epnt->e_machine != MAGIC1
- #ifdef MAGIC2
-@@ -490,7 +419,7 @@
-               _dl_close(infile);
-               _dl_munmap(header, _dl_pagesize);
-               return NULL;
--      };
-+      }
-       ppnt = (ElfW(Phdr) *)(intptr_t) & header[epnt->e_phoff];
-@@ -502,7 +431,7 @@
-                               _dl_dprintf(2, "%s: '%s' has more than one dynamic section\n",
-                                               _dl_progname, libname);
-                       dynamic_addr = ppnt->p_vaddr;
--              };
-+              }
-               if (ppnt->p_type == PT_LOAD) {
-                       /* See if this is a PIC library. */
-@@ -518,7 +447,7 @@
-                       }
-               }
-               ppnt++;
--      };
-+      }
-       maxvma = (maxvma + ADDR_ALIGN) & ~ADDR_ALIGN;
-       minvma = minvma & ~0xffffU;
-@@ -530,12 +459,12 @@
-       status = (char *) _dl_mmap((char *) (piclib ? 0 : minvma),
-                       maxvma - minvma, PROT_NONE, flags | MAP_ANONYMOUS, -1, 0);
-       if (_dl_mmap_check_error(status)) {
--              _dl_dprintf(2, "%s: can't map %s\n", _dl_progname, libname);
-+              _dl_dprintf(2, "%s:%i: can't map '%s'\n", _dl_progname, __LINE__, libname);
-               _dl_internal_error_number = LD_ERROR_MMAP_FAILED;
-               _dl_close(infile);
-               _dl_munmap(header, _dl_pagesize);
-               return NULL;
--      };
-+      }
-       libaddr = (unsigned long) status;
-       flags |= MAP_FIXED;
-@@ -567,14 +496,14 @@
-                                               ppnt->p_offset & OFFS_ALIGN);
-                               if (_dl_mmap_check_error(status)) {
--                                      _dl_dprintf(2, "%s: can't map '%s'\n",
--                                                      _dl_progname, libname);
-+                                      _dl_dprintf(2, "%s:%i: can't map '%s'\n",
-+                                                      _dl_progname, __LINE__, libname);
-                                       _dl_internal_error_number = LD_ERROR_MMAP_FAILED;
-                                       _dl_munmap((char *) libaddr, maxvma - minvma);
-                                       _dl_close(infile);
-                                       _dl_munmap(header, _dl_pagesize);
-                                       return NULL;
--                              };
-+                              }
-                               /* Pad the last page with zeroes. */
-                               cpnt = (char *) (status + (ppnt->p_vaddr & ADDR_ALIGN) +
-@@ -601,21 +530,21 @@
-                                               ppnt->p_filesz, LXFLAGS(ppnt->p_flags), flags,
-                                               infile, ppnt->p_offset & OFFS_ALIGN);
-                       if (_dl_mmap_check_error(status)) {
--                              _dl_dprintf(2, "%s: can't map '%s'\n", _dl_progname, libname);
-+                              _dl_dprintf(2, "%s:%i: can't map '%s'\n", _dl_progname, __LINE__, libname);
-                               _dl_internal_error_number = LD_ERROR_MMAP_FAILED;
-                               _dl_munmap((char *) libaddr, maxvma - minvma);
-                               _dl_close(infile);
-                               _dl_munmap(header, _dl_pagesize);
-                               return NULL;
--                      };
-+                      }
-                       /* if(libaddr == 0 && piclib) {
-                          libaddr = (unsigned long) status;
-                          flags |= MAP_FIXED;
--                         }; */
--              };
-+                         } */
-+              }
-               ppnt++;
--      };
-+      }
-       _dl_close(infile);
-       /* For a non-PIC library, the addresses are all absolute */
-@@ -665,6 +594,8 @@
-                       dynamic_addr, 0);
-       tpnt->relro_addr = relro_addr;
-       tpnt->relro_size = relro_size;
-+      tpnt->st_dev = st.st_dev;
-+      tpnt->st_ino = st.st_ino;
-       tpnt->ppnt = (ElfW(Phdr) *)(intptr_t) (tpnt->loadaddr + epnt->e_phoff);
-       tpnt->n_phent = epnt->e_phnum;
-@@ -693,7 +624,7 @@
-       if (lpnt) {
-               lpnt = (unsigned long *) (dynamic_info[DT_PLTGOT]);
-               INIT_GOT(lpnt, tpnt);
--      };
-+      }
-       _dl_if_debug_dprint("\n\tfile='%s';  generating link map\n", libname);
-       _dl_if_debug_dprint("\t\tdynamic: %x  base: %x\n", dynamic_addr, libaddr);
-@@ -714,10 +645,12 @@
-       ElfW(Addr) reloc_addr;
-       if (rpnt->next)
--              goof += _dl_fixup(rpnt->next, now_flag);
-+              goof = _dl_fixup(rpnt->next, now_flag);
-+      if (goof)
-+              return goof;
-       tpnt = rpnt->dyn;
--      if(!(tpnt->init_flag & RELOCS_DONE)) 
-+      if(!(tpnt->init_flag & RELOCS_DONE))
-               _dl_if_debug_dprint("relocation processing: %s\n", tpnt->libname);
-       if (unlikely(tpnt->dynamic_info[UNSUPPORTED_RELOC_TYPE])) {
-@@ -735,7 +668,6 @@
- #endif
-       if (tpnt->dynamic_info[DT_RELOC_TABLE_ADDR] &&
-           !(tpnt->init_flag & RELOCS_DONE)) {
--              tpnt->init_flag |= RELOCS_DONE;
-               reloc_addr = tpnt->dynamic_info[DT_RELOC_TABLE_ADDR];
-               relative_count = tpnt->dynamic_info[DT_RELCONT_IDX];
-               if (relative_count) { /* Optimize the XX_RELATIVE relocations if possible */
-@@ -746,14 +678,14 @@
-               goof += _dl_parse_relocation_information(rpnt,
-                               reloc_addr,
-                               reloc_size);
-+              tpnt->init_flag |= RELOCS_DONE;
-       }
-       if (tpnt->dynamic_info[DT_BIND_NOW])
-               now_flag = RTLD_NOW;
-       if (tpnt->dynamic_info[DT_JMPREL] &&
-           (!(tpnt->init_flag & JMP_RELOCS_DONE) ||
-            (now_flag && !(tpnt->rtld_flags & now_flag)))) {
--              tpnt->rtld_flags |= now_flag; 
--              tpnt->init_flag |= JMP_RELOCS_DONE;
-+              tpnt->rtld_flags |= now_flag;
-               if (!(tpnt->rtld_flags & RTLD_NOW)) {
-                       _dl_parse_lazy_relocation_information(rpnt,
-                                       tpnt->dynamic_info[DT_JMPREL],
-@@ -763,6 +695,7 @@
-                                       tpnt->dynamic_info[DT_JMPREL],
-                                       tpnt->dynamic_info[DT_PLTRELSZ]);
-               }
-+              tpnt->init_flag |= JMP_RELOCS_DONE;
-       }
-       return goof;
- }
-@@ -770,11 +703,18 @@
- /* Minimal printf which handles only %s, %d, and %x */
- void _dl_dprintf(int fd, const char *fmt, ...)
- {
--      long num;
-+#if __WORDSIZE > 32
-+      long int num;
-+#else
-+      int num;
-+#endif
-       va_list args;
-       char *start, *ptr, *string;
-       static char *buf;
-+      if (!fmt)
-+              return;
-+
-       buf = _dl_mmap((void *) 0, _dl_pagesize, PROT_READ | PROT_WRITE,
-                       MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-       if (_dl_mmap_check_error(buf)) {
-@@ -784,9 +724,6 @@
-       start = ptr = buf;
--      if (!fmt)
--              return;
--
-       if (_dl_strlen(fmt) >= (_dl_pagesize - 1)) {
-               _dl_write(fd, "overflow\n", 11);
-               _dl_exit(20);
-@@ -818,8 +755,11 @@
-                               case 'd':
-                                       {
-                                               char tmp[22];
--                                              num = va_arg(args, long);
--
-+#if __WORDSIZE > 32
-+                                              num = va_arg(args, long int);
-+#else
-+                                              num = va_arg(args, int);
-+#endif
-                                               string = _dl_simple_ltoa(tmp, num);
-                                               _dl_write(fd, string, _dl_strlen(string));
-                                               break;
-@@ -828,8 +768,11 @@
-                               case 'X':
-                                       {
-                                               char tmp[22];
--                                              num = va_arg(args, long);
--
-+#if __WORDSIZE > 32
-+                                              num = va_arg(args, long int);
-+#else
-+                                              num = va_arg(args, int);
-+#endif
-                                               string = _dl_simple_ltoahex(tmp, num);
-                                               _dl_write(fd, string, _dl_strlen(string));
-                                               break;
-@@ -864,8 +807,10 @@
- {
-       __dl_parse_dynamic_info(dpnt, dynamic_info, debug_addr, load_off);
- }
-+
-+/* we want this in ldso.so and libdl.a but nowhere else */
- #ifdef __USE_GNU
--#if ! defined LIBDL || (! defined PIC && ! defined __PIC__)
-+#if ! defined SHARED || (! defined PIC && ! defined __PIC__)
- int
- __dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info, size_t size, void *data), void *data)
- {
-@@ -884,6 +829,6 @@
-       }
-       return ret;
- }
--strong_alias(__dl_iterate_phdr, dl_iterate_phdr);
-+strong_alias(__dl_iterate_phdr, dl_iterate_phdr)
- #endif
- #endif
-diff -urN uClibc-0.9.28.orig/ldso/ldso/dl-hash.c uClibc-0.9.28/ldso/ldso/dl-hash.c
---- uClibc-0.9.28.orig/ldso/ldso/dl-hash.c     2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/dl-hash.c  2006-04-28 00:14:35.000000000 -0600
-@@ -57,7 +57,7 @@
- /* This is the hash function that is used by the ELF linker to generate the
-  * hash table that each executable and library is required to have.  We need
-  * it to decode the hash table.  */
--static inline Elf32_Word _dl_elf_hash(const char *name)
-+static inline Elf_Symndx _dl_elf_hash(const char *name)
- {
-       unsigned long hash=0;
-       unsigned long tmp;
-@@ -77,21 +77,6 @@
-       return hash;
- }
--/* Check to see if a library has already been added to the hash chain.  */
--struct elf_resolve *_dl_check_hashed_files(const char *libname)
--{
--      struct elf_resolve *tpnt;
--      int len = _dl_strlen(libname);
--
--      for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
--              if (_dl_strncmp(tpnt->libname, libname, len) == 0 &&
--                  (tpnt->libname[len] == '\0' || tpnt->libname[len] == '.'))
--                      return tpnt;
--      }
--
--      return NULL;
--}
--
- /*
-  * We call this function when we have just read an ELF library or executable.
-  * We add the relevant info to the symbol chain, so that we can resolve all
-@@ -99,9 +84,10 @@
-  */
- struct elf_resolve *_dl_add_elf_hash_table(const char *libname,
-       char *loadaddr, unsigned long *dynamic_info, unsigned long dynamic_addr,
-+      //attribute_unused
-       unsigned long dynamic_size)
- {
--      Elf32_Word *hash_addr;
-+      Elf_Symndx *hash_addr;
-       struct elf_resolve *tpnt;
-       int i;
-@@ -125,7 +111,7 @@
-       tpnt->libtype = loaded_file;
-       if (dynamic_info[DT_HASH] != 0) {
--              hash_addr = (Elf32_Word*)dynamic_info[DT_HASH];
-+              hash_addr = (Elf_Symndx*)dynamic_info[DT_HASH];
-               tpnt->nbucket = *hash_addr++;
-               tpnt->nchain = *hash_addr++;
-               tpnt->elf_buckets = hash_addr;
-diff -urN uClibc-0.9.28.orig/ldso/ldso/dl-startup.c uClibc-0.9.28/ldso/ldso/dl-startup.c
---- uClibc-0.9.28.orig/ldso/ldso/dl-startup.c  2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/dl-startup.c       2006-04-28 00:14:35.000000000 -0600
-@@ -98,7 +98,7 @@
- int (*_dl_elf_main) (int, char **, char **);
- static void* __rtld_stack_end; /* Points to argc on stack, e.g *((long *)__rtld_stackend) == argc */
--strong_alias(__rtld_stack_end, __libc_stack_end); /* Exported version of __rtld_stack_end */
-+strong_alias(__rtld_stack_end, __libc_stack_end) /* Exported version of __rtld_stack_end */
- /* When we enter this piece of code, the program stack looks like this:
-       argc            argument counter (integer)
-@@ -307,5 +307,11 @@
-       SEND_STDERR_DEBUG("transfering control to application @ ");
-       _dl_elf_main = (int (*)(int, char **, char **)) auxvt[AT_ENTRY].a_un.a_val;
-       SEND_ADDRESS_STDERR_DEBUG(_dl_elf_main, 1);
-+
-+#ifndef START
-+      return _dl_elf_main;
-+#else
-+#warning You need to update your arch ldso code
-       START();
-+#endif
- }
-diff -urN uClibc-0.9.28.orig/ldso/ldso/frv/dl-syscalls.h uClibc-0.9.28/ldso/ldso/frv/dl-syscalls.h
---- uClibc-0.9.28.orig/ldso/ldso/frv/dl-syscalls.h     2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/frv/dl-syscalls.h  2006-04-28 00:14:35.000000000 -0600
-@@ -20,9 +20,10 @@
- /* We can't use the real errno in ldso, since it has not yet
-  * been dynamicly linked in yet. */
-+#include "sys/syscall.h"
- extern int _dl_errno;
-+#undef __set_errno
- #define __set_errno(X) {(_dl_errno) = (X);}
--#include "sys/syscall.h"
- #include <sys/mman.h>
- /* The code below is extracted from libc/sysdeps/linux/frv/_mmap.c */
-diff -urN uClibc-0.9.28.orig/ldso/ldso/frv/dl-sysdep.h uClibc-0.9.28/ldso/ldso/frv/dl-sysdep.h
---- uClibc-0.9.28.orig/ldso/ldso/frv/dl-sysdep.h       2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/frv/dl-sysdep.h    2006-04-28 00:14:35.000000000 -0600
-@@ -65,8 +65,6 @@
- extern int _dl_linux_resolve(void) __attribute__((__visibility__("hidden")));
--#define do_rem(result, n, base) ((result) = (n) % (base))
--
- /* 16KiB page alignment.  Should perhaps be made dynamic using
-    getpagesize(), based on AT_PAGESZ from auxvt?  */
- #define PAGE_ALIGN 0xffffc000
-diff -urN uClibc-0.9.28.orig/ldso/ldso/frv/elfinterp.c uClibc-0.9.28/ldso/ldso/frv/elfinterp.c
---- uClibc-0.9.28.orig/ldso/ldso/frv/elfinterp.c       2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/frv/elfinterp.c    2006-04-28 00:14:35.000000000 -0600
-@@ -24,7 +24,7 @@
- the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
- USA.  */
--#include <sys/cdefs.h>            /* __attribute_used__ */
-+#include <features.h>
- /* Program to load an ELF binary on a linux system, and run it.
-    References to symbols in sharable libraries can be resolved by either
-@@ -37,7 +37,7 @@
-    a more than adequate job of explaining everything required to get this
-    working. */
--struct funcdesc_value volatile *__attribute__((__visibility__("hidden")))
-+struct funcdesc_value volatile attribute_hidden *
- _dl_linux_resolver (struct elf_resolve *tpnt, int reloc_entry)
- {
-       int reloc_type;
-diff -urN uClibc-0.9.28.orig/ldso/ldso/i386/dl-startup.h uClibc-0.9.28/ldso/ldso/i386/dl-startup.h
---- uClibc-0.9.28.orig/ldso/ldso/i386/dl-startup.h     2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/i386/dl-startup.h  2006-04-28 00:14:35.000000000 -0600
-@@ -3,7 +3,7 @@
-  * Architecture specific code used by dl-startup.c
-  * Copyright (C) 2000-2004 by Erik Andersen <andersen@codepoet.org>
-  */
--asm(
-+__asm__ (
-     " .text\n"
-     " .align 16\n"
-     " .globl  _start\n"
-@@ -41,9 +41,9 @@
- #define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long*) & ARGS)+1)
- /* Handle relocation of the symbols in the dynamic loader. */
--static inline
-+static __always_inline
- void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, unsigned long *reloc_addr,
--      unsigned long symbol_addr, unsigned long load_addr, Elf32_Sym *symtab)
-+      unsigned long symbol_addr, unsigned long load_addr, attribute_unused Elf32_Sym *symtab)
- {
-       switch (ELF32_R_TYPE(rpnt->r_info))
-       {
-@@ -64,8 +64,3 @@
-                       _dl_exit(1);
-       }
- }
--
--/* Transfer control to the user's application, once the dynamic loader is
-- * done.  This routine has to exit the current function, then call the
-- * _dl_elf_main function.  */
--#define START() return _dl_elf_main
-diff -urN uClibc-0.9.28.orig/ldso/ldso/i386/dl-syscalls.h uClibc-0.9.28/ldso/ldso/i386/dl-syscalls.h
---- uClibc-0.9.28.orig/ldso/ldso/i386/dl-syscalls.h    2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/i386/dl-syscalls.h 2006-04-28 00:14:35.000000000 -0600
-@@ -1,5 +1,6 @@
- /* We can't use the real errno in ldso, since it has not yet
-  * been dynamicly linked in yet. */
-+#include "sys/syscall.h"
- extern int _dl_errno;
-+#undef __set_errno
- #define __set_errno(X) {(_dl_errno) = (X);}
--#include "sys/syscall.h"
-diff -urN uClibc-0.9.28.orig/ldso/ldso/i386/dl-sysdep.h uClibc-0.9.28/ldso/ldso/i386/dl-sysdep.h
---- uClibc-0.9.28.orig/ldso/ldso/i386/dl-sysdep.h      2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/i386/dl-sysdep.h   2006-04-28 00:14:35.000000000 -0600
-@@ -25,8 +25,6 @@
- struct elf_resolve;
- extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
--#define do_rem(result, n, base) ((result) = (n) % (base))
--
- /* 4096 bytes alignment */
- #define PAGE_ALIGN 0xfffff000
- #define ADDR_ALIGN 0xfff
-@@ -44,16 +42,18 @@
- /* Return the link-time address of _DYNAMIC.  Conveniently, this is the
-    first element of the GOT.  This must be inlined in a function which
-    uses global data.  */
--static inline Elf32_Addr __attribute__ ((unused))
-+static inline Elf32_Addr elf_machine_dynamic (void) attribute_unused;
-+static inline Elf32_Addr
- elf_machine_dynamic (void)
- {
--      register Elf32_Addr *got asm ("%ebx");
-+      register Elf32_Addr *got __asm__ ("%ebx");
-       return *got;
- }
- /* Return the run-time load address of the shared object.  */
--static inline Elf32_Addr __attribute__ ((unused))
-+static inline Elf32_Addr elf_machine_load_address (void) attribute_unused;
-+static inline Elf32_Addr
- elf_machine_load_address (void)
- {
-       /* It doesn't matter what variable this is, the reference never makes
-@@ -61,7 +61,7 @@
-          via the GOT to make sure the compiler initialized %ebx in time.  */
-       extern int _dl_errno;
-       Elf32_Addr addr;
--      asm ("leal _dl_start@GOTOFF(%%ebx), %0\n"
-+      __asm__ ("leal _dl_start@GOTOFF(%%ebx), %0\n"
-            "subl _dl_start@GOT(%%ebx), %0"
-            : "=r" (addr) : "m" (_dl_errno) : "cc");
-       return addr;
-diff -urN uClibc-0.9.28.orig/ldso/ldso/i386/elfinterp.c uClibc-0.9.28/ldso/ldso/i386/elfinterp.c
---- uClibc-0.9.28.orig/ldso/ldso/i386/elfinterp.c      2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/i386/elfinterp.c   2006-04-28 00:14:35.000000000 -0600
-@@ -67,12 +67,6 @@
-       strtab = (char *)tpnt->dynamic_info[DT_STRTAB];
-       symname = strtab + symtab[symtab_index].st_name;
--      if (unlikely(reloc_type != R_386_JMP_SLOT)) {
--              _dl_dprintf(2, "%s: Incorrect relocation type in jump relocations\n",
--                          _dl_progname);
--              _dl_exit(1);
--      }
--
-       /* Address of the jump instruction to fix up. */
-       instr_addr = ((unsigned long)this_reloc->r_offset +
-                     (unsigned long)tpnt->loadaddr);
-@@ -81,7 +75,7 @@
-       /* Get the address of the GOT entry. */
-       new_addr = _dl_find_hash(symname, tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT);
-       if (unlikely(!new_addr)) {
--              _dl_dprintf(2, "%s: Can't resolve symbol '%s'\n", _dl_progname, symname);
-+              _dl_dprintf(2, "%s: can't resolve symbol '%s' in lib '%s'.\n", _dl_progname, symname, tpnt->libname);
-               _dl_exit(1);
-       }
-@@ -147,15 +141,15 @@
-                       int reloc_type = ELF32_R_TYPE(rpnt->r_info);
- #if defined (__SUPPORT_LD_DEBUG__)
--                      _dl_dprintf(2, "can't handle reloc type %s\n",
--                                  _dl_reltypes(reloc_type));
-+                      _dl_dprintf(2, "can't handle reloc type '%s' in lib '%s'\n",
-+                                  _dl_reltypes(reloc_type), tpnt->libname);
- #else
--                      _dl_dprintf(2, "can't handle reloc type %x\n",
--                                  reloc_type);
-+                      _dl_dprintf(2, "can't handle reloc type %x in lib '%s'\n",
-+                                  reloc_type, tpnt->libname);
- #endif
--                      _dl_exit(-res);
-+                      return res;
-               } else if (unlikely(res > 0)) {
--                      _dl_dprintf(2, "can't resolve symbol\n");
-+                      _dl_dprintf(2, "can't resolve symbol in lib '%s'.\n", tpnt->libname);
-                       return res;
-               }
-       }
-@@ -191,10 +185,8 @@
-                * might have been intentional.  We should not be linking local
-                * symbols here, so all bases should be covered.
-                */
--              if (unlikely(!symbol_addr && ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK)) {
--                      _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname);
--                      _dl_exit(1);
--              };
-+              if (unlikely(!symbol_addr && ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK))
-+                      return 1;
-       }
- #if defined (__SUPPORT_LD_DEBUG__)
-@@ -233,7 +225,7 @@
-                       }
-                       break;
-               default:
--                      return -1;      /* Calls _dl_exit(1). */
-+                      return -1;
-       }
- #if defined (__SUPPORT_LD_DEBUG__)
-@@ -273,7 +265,7 @@
-                       *reloc_addr += (unsigned long)tpnt->loadaddr;
-                       break;
-               default:
--                      return -1;      /* Calls _dl_exit(1). */
-+                      return -1;
-       }
- #if defined (__SUPPORT_LD_DEBUG__)
-diff -urN uClibc-0.9.28.orig/ldso/ldso/ldso.c uClibc-0.9.28/ldso/ldso/ldso.c
---- uClibc-0.9.28.orig/ldso/ldso/ldso.c        2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/ldso.c     2006-05-02 13:55:54.000000000 -0600
-@@ -39,7 +39,7 @@
- #define ALLOW_ZERO_PLTGOT
- /* Pull in the value of _dl_progname */
--#include "dl-progname.h"
-+#include LDSO_ELFINTERP
- /* Global variables used within the shared library loader */
- char *_dl_library_path         = 0;   /* Where we look for libraries */
-@@ -74,7 +74,8 @@
-  * can set an internal breakpoint on it, so that we are notified when the
-  * address mapping is changed in some way.
-  */
--void _dl_debug_state(void)
-+void _dl_debug_state(void);
-+void _dl_debug_state()
- {
- }
-@@ -82,9 +83,78 @@
- static unsigned char *_dl_mmap_zero   = 0;    /* Also used by _dl_malloc */
- static struct elf_resolve **init_fini_list;
--static int nlist; /* # items in init_fini_list */
-+static unsigned int nlist; /* # items in init_fini_list */
- extern void _start(void);
-+#ifdef __UCLIBC_HAS_SSP__
-+#ifndef __UCLIBC_HAS_SSP_COMPAT__
-+#define __UCLIBC_HAS_SSP_COMPAT__ 1
-+#endif
-+# include <dl-osinfo.h>
-+uintptr_t stack_chk_guard;
-+# ifndef THREAD_SET_STACK_GUARD
-+/* Only exported for architectures that don't store the stack guard canary
-+ * in local thread area.  */
-+uintptr_t __stack_chk_guard attribute_relro;
-+#  ifdef __UCLIBC_HAS_SSP_COMPAT__
-+strong_alias(__stack_chk_guard,__guard)
-+#  endif
-+# elif __UCLIBC_HAS_SSP_COMPAT__
-+uintptr_t __guard attribute_relro;
-+# endif
-+#endif
-+
-+static void _dl_run_array_forward(unsigned long array, unsigned long size,
-+                                ElfW(Addr) loadaddr)
-+{
-+      if (array != 0) {
-+              unsigned int j;
-+              unsigned int jm;
-+              ElfW(Addr) *addrs;
-+              jm = size / sizeof (ElfW(Addr));
-+              addrs = (ElfW(Addr) *) (array + loadaddr);
-+              for (j = 0; j < jm; ++j) {
-+                      void (*dl_elf_func) (void);
-+                      dl_elf_func = (void (*)(void)) (intptr_t) addrs[j];
-+                      (*dl_elf_func) ();
-+              }
-+      }
-+}
-+
-+void _dl_run_init_array(struct elf_resolve *tpnt);
-+void _dl_run_init_array(struct elf_resolve *tpnt)
-+{
-+      _dl_run_array_forward(tpnt->dynamic_info[DT_INIT_ARRAY],
-+                            tpnt->dynamic_info[DT_INIT_ARRAYSZ],
-+                            tpnt->loadaddr);
-+}
-+
-+void _dl_app_init_array(void);
-+void _dl_app_init_array(void)
-+{
-+      _dl_run_init_array(_dl_loaded_modules);
-+}
-+
-+void _dl_run_fini_array(struct elf_resolve *tpnt);
-+void _dl_run_fini_array(struct elf_resolve *tpnt)
-+{
-+      if (tpnt->dynamic_info[DT_FINI_ARRAY]) {
-+              ElfW(Addr) *array = (ElfW(Addr) *) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI_ARRAY]);
-+              unsigned int i = (tpnt->dynamic_info[DT_FINI_ARRAYSZ] / sizeof(ElfW(Addr)));
-+              while (i-- > 0) {
-+                      void (*dl_elf_func) (void);
-+                      dl_elf_func = (void (*)(void)) (intptr_t) array[i];
-+                      (*dl_elf_func) ();
-+              }
-+      }
-+}
-+
-+void _dl_app_fini_array(void);
-+void _dl_app_fini_array(void)
-+{
-+      _dl_run_fini_array(_dl_loaded_modules);
-+}
-+
- static void __attribute__ ((destructor)) __attribute_used__ _dl_fini(void)
- {
-       int i;
-@@ -95,6 +165,7 @@
-               if (tpnt->init_flag & FINI_FUNCS_CALLED)
-                       continue;
-               tpnt->init_flag |= FINI_FUNCS_CALLED;
-+              _dl_run_fini_array(tpnt);
-               if (tpnt->dynamic_info[DT_FINI]) {
-                       void (*dl_elf_func) (void);
-@@ -112,7 +183,8 @@
-       ElfW(Phdr) *ppnt;
-       ElfW(Dyn) *dpnt;
-       char *lpntstr;
--      int i, goof = 0, unlazy = 0, trace_loaded_objects = 0;
-+      unsigned int i;
-+      int unlazy = 0, trace_loaded_objects = 0;
-       struct dyn_elf *rpnt;
-       struct elf_resolve *tcurr;
-       struct elf_resolve *tpnt1;
-@@ -128,6 +200,7 @@
-        * setup so we can use _dl_dprintf() to print debug noise
-        * instead of the SEND_STDERR macros used in dl-startup.c */
-+      _dl_memset(app_tpnt, 0x00, sizeof(*app_tpnt));
-       /* Store the page size for later use */
-       _dl_pagesize = (auxvt[AT_PAGESZ].a_un.a_val) ? (size_t) auxvt[AT_PAGESZ].a_un.a_val : PAGE_SIZE;
-@@ -168,8 +241,8 @@
-        * Note that for SUID programs we ignore the settings in
-        * LD_LIBRARY_PATH.
-        */
--      if ((auxvt[AT_UID].a_un.a_val == -1 && _dl_suid_ok()) ||
--          (auxvt[AT_UID].a_un.a_val != -1 &&
-+      if ((auxvt[AT_UID].a_un.a_val == (size_t)-1 && _dl_suid_ok()) ||
-+          (auxvt[AT_UID].a_un.a_val != (size_t)-1 &&
-            auxvt[AT_UID].a_un.a_val == auxvt[AT_EUID].a_un.a_val &&
-            auxvt[AT_GID].a_un.a_val == auxvt[AT_EGID].a_un.a_val)) {
-               _dl_secure = 0;
-@@ -196,6 +269,20 @@
-               unlazy = RTLD_NOW;
-       }
-+      /* sjhill: your TLS init should go before this */
-+#ifdef __UCLIBC_HAS_SSP__
-+      /* Set up the stack checker's canary.  */
-+      stack_chk_guard = _dl_setup_stack_chk_guard ();
-+# ifdef THREAD_SET_STACK_GUARD
-+      THREAD_SET_STACK_GUARD (stack_chk_guard);
-+#  ifdef __UCLIBC_HAS_SSP_COMPAT__
-+      __guard = stack_chk_guard;
-+#  endif
-+# else
-+      __stack_chk_guard = stack_chk_guard;
-+# endif
-+#endif
-+
-       /* At this point we are now free to examine the user application,
-        * and figure out which libraries are supposed to be called.  Until
-        * we have this list, we will not be completely ready for dynamic
-@@ -206,12 +293,12 @@
-        * different from what the ELF header says for ET_DYN/PIE executables.
-        */
-       {
--              int i;
--              ElfW(Phdr) *ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
-+              unsigned int idx;
-+              ElfW(Phdr) *phdr = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
--              for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++)
--                      if (ppnt->p_type == PT_PHDR) {
--                              app_tpnt->loadaddr = (ElfW(Addr)) (auxvt[AT_PHDR].a_un.a_val - ppnt->p_vaddr);
-+              for (idx = 0; idx < auxvt[AT_PHNUM].a_un.a_val; idx++, phdr++)
-+                      if (phdr->p_type == PT_PHDR) {
-+                              app_tpnt->loadaddr = (ElfW(Addr)) (auxvt[AT_PHDR].a_un.a_val - phdr->p_vaddr);
-                               break;
-                       }
-@@ -459,8 +546,8 @@
-                                            PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
-               _dl_close(fd);
-               if (preload == (caddr_t) -1) {
--                      _dl_dprintf(_dl_debug_file, "%s: can't map file '%s'\n",
--                                  _dl_progname, LDSO_PRELOAD);
-+                      _dl_dprintf(_dl_debug_file, "%s:%i: can't map '%s'\n",
-+                                  _dl_progname, __LINE__, LDSO_PRELOAD);
-                       break;
-               }
-@@ -528,15 +615,15 @@
-       nlist = 0;
-       for (tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next) {
--              ElfW(Dyn) *dpnt;
-+              ElfW(Dyn) *this_dpnt;
-               nlist++;
--              for (dpnt = (ElfW(Dyn) *) tcurr->dynamic_addr; dpnt->d_tag; dpnt++) {
--                      if (dpnt->d_tag == DT_NEEDED) {
-+              for (this_dpnt = (ElfW(Dyn) *) tcurr->dynamic_addr; this_dpnt->d_tag; this_dpnt++) {
-+                      if (this_dpnt->d_tag == DT_NEEDED) {
-                               char *name;
-                               struct init_fini_list *tmp;
--                              lpntstr = (char*) (tcurr->dynamic_info[DT_STRTAB] + dpnt->d_un.d_val);
-+                              lpntstr = (char*) (tcurr->dynamic_info[DT_STRTAB] + this_dpnt->d_un.d_val);
-                               name = _dl_get_last_path_component(lpntstr);
-                               if (_dl_strcmp(name, UCLIBC_LDSO) == 0)
-                                       continue;
-@@ -633,7 +720,7 @@
-               ElfW(Ehdr) *epnt = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_val;
-               ElfW(Phdr) *myppnt = (ElfW(Phdr) *) (load_addr + epnt->e_phoff);
-               int j;
--              
-+
-               tpnt = _dl_add_elf_hash_table(tpnt->libname, (char *)load_addr,
-                                             tpnt->dynamic_info,
-                                             (unsigned long)tpnt->dynamic_addr,
-@@ -703,16 +790,14 @@
-        * order so that COPY directives work correctly.
-        */
-       if (_dl_symbol_tables)
--              goof += _dl_fixup(_dl_symbol_tables, unlazy);
-+              if (_dl_fixup(_dl_symbol_tables, unlazy))
-+                      _dl_exit(-1);
-       for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
-               if (tpnt->relro_size)
-                       _dl_protect_relro (tpnt);
-       }
--
--
--
-       /* OK, at this point things are pretty much ready to run.  Now we need
-        * to touch up a few items that are required, and then we can let the
-        * user application have at it.  Note that the dynamic linker itself
-@@ -746,6 +831,14 @@
-       /* Notify the debugger we have added some objects. */
-       _dl_debug_addr->r_state = RT_ADD;
-       _dl_debug_state();
-+
-+      /* Run pre-initialization functions for the executable.  */
-+      _dl_run_array_forward(_dl_loaded_modules->dynamic_info[DT_PREINIT_ARRAY],
-+                            _dl_loaded_modules->dynamic_info[DT_PREINIT_ARRAYSZ],
-+                            _dl_loaded_modules->loadaddr);
-+
-+      /* Run initialization functions for loaded objects.  For the
-+         main executable, they will be run from __uClibc_main.  */
-       for (i = nlist; i; --i) {
-               tpnt = init_fini_list[i-1];
-               tpnt->init_fini = NULL; /* Clear, since alloca was used */
-@@ -762,17 +855,9 @@
-                       (*dl_elf_func) ();
-               }
--      }
--#ifdef _DL_FINI_CRT_COMPAT
--      /* arches that have moved their ldso FINI handling should skip this part */
--      {
--              int (*_dl_atexit) (void *) = (int (*)(void *)) (intptr_t) _dl_find_hash("atexit",
--                              _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT);
--              if (_dl_atexit)
--                      (*_dl_atexit) (_dl_fini);
-+              _dl_run_init_array(tpnt);
-       }
--#endif
-       /* Find the real malloc function and make ldso functions use that from now on */
-        _dl_malloc_function = (void* (*)(size_t)) (intptr_t) _dl_find_hash("malloc",
-diff -urN uClibc-0.9.28.orig/ldso/ldso/m68k/dl-startup.h uClibc-0.9.28/ldso/ldso/m68k/dl-startup.h
---- uClibc-0.9.28.orig/ldso/ldso/m68k/dl-startup.h     2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/m68k/dl-startup.h  2006-04-28 00:14:35.000000000 -0600
-@@ -4,23 +4,48 @@
-  * Copyright (C) 2005 by Erik Andersen <andersen@codepoet.org>
-  */
--asm(
--    " .text\n"
--    " .globl  _start\n"
--    " .type   _start,@function\n"
--    "_start:\n"
--    " .set    _start,_dl_start\n"
--    " .size   _start,.-_start\n"
--    " .previous\n"
--);
-+asm ("\
-+      .text\n\
-+      .globl _start\n\
-+      .type _start,@function\n\
-+_start:\n\
-+      move.l %sp, -(%sp)\n\
-+      jbsr _dl_start\n\
-+      addq.l #4, %sp\n\
-+      /* FALLTHRU */\n\
-+\n\
-+      .globl _dl_start_user\n\
-+.type _dl_start_user,@function\n\
-+_dl_start_user:\n\
-+      # Save the user entry point address in %a4.\n\
-+      move.l %d0, %a4\n\
-+      # See if we were run as a command with the executable file\n\
-+      # name as an extra leading argument.\n\
-+      move.l _dl_skip_args(%pc), %d0\n\
-+      # Pop the original argument count\n\
-+      move.l (%sp)+, %d1\n\
-+      # Subtract _dl_skip_args from it.\n\
-+      sub.l %d0, %d1\n\
-+      # Adjust the stack pointer to skip _dl_skip_args words.\n\
-+      lea (%sp, %d0*4), %sp\n\
-+      # Push back the modified argument count.\n\
-+      move.l %d1, -(%sp)\n\
-+      # Pass our finalizer function to the user in %a1.\n\
-+      lea _dl_fini(%pc), %a1\n\
-+      # Initialize %fp with the stack pointer.\n\
-+      move.l %sp, %fp\n\
-+      # Jump to the user's entry point.\n\
-+      jmp (%a4)\n\
-+      .size _dl_start_user, . - _dl_start_user\n\
-+      .previous");
- /* Get a pointer to the argv array.  On many platforms this can be just
-  * the address if the first argument, on other platforms we need to
-  * do something a little more subtle here.  */
--#define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned int *) & ARGS)
-+#define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long *) ARGS) + 1)
- /* Handle relocation of the symbols in the dynamic loader. */
--static inline
-+static __always_inline
- void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, unsigned long *reloc_addr,
-       unsigned long symbol_addr, unsigned long load_addr, Elf32_Sym *symtab)
- {
-@@ -59,12 +84,3 @@
-                       _dl_exit (1);
-       }
- }
--
--/* Transfer control to the user's application, once the dynamic loader is
-- * done.  This routine has to exit the current function, then call the
-- * _dl_elf_main function.  */
--#define START() \
--      __asm__ volatile ( \
--              "unlk %%a6\n\t" \
--              "jmp %0@" \
--              : : "a" (_dl_elf_main));
-diff -urN uClibc-0.9.28.orig/ldso/ldso/m68k/dl-syscalls.h uClibc-0.9.28/ldso/ldso/m68k/dl-syscalls.h
---- uClibc-0.9.28.orig/ldso/ldso/m68k/dl-syscalls.h    2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/m68k/dl-syscalls.h 2006-04-28 00:14:35.000000000 -0600
-@@ -1,5 +1,6 @@
- /* We can't use the real errno in ldso, since it has not yet
-  * been dynamicly linked in yet. */
-+#include "sys/syscall.h"
- extern int _dl_errno;
-+#undef __set_errno
- #define __set_errno(X) {(_dl_errno) = (X);}
--#include "sys/syscall.h"
-diff -urN uClibc-0.9.28.orig/ldso/ldso/m68k/dl-sysdep.h uClibc-0.9.28/ldso/ldso/m68k/dl-sysdep.h
---- uClibc-0.9.28.orig/ldso/ldso/m68k/dl-sysdep.h      2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/m68k/dl-sysdep.h   2006-04-28 00:14:35.000000000 -0600
-@@ -25,10 +25,6 @@
- struct elf_resolve;
- extern unsigned int _dl_linux_resolver (struct elf_resolve *, int);
--/* Define this because we do not want to call .udiv in the library.
--   Not needed for m68k.  */
--#define do_rem(result, n, base)  ((result) = (n) % (base))
--
- /* 4096 bytes alignment */
- #define PAGE_ALIGN 0xfffff000
- #define ADDR_ALIGN 0xfff
-diff -urN uClibc-0.9.28.orig/ldso/ldso/m68k/elfinterp.c uClibc-0.9.28/ldso/ldso/m68k/elfinterp.c
---- uClibc-0.9.28.orig/ldso/ldso/m68k/elfinterp.c      2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/m68k/elfinterp.c   2006-04-28 00:14:35.000000000 -0600
-@@ -40,6 +40,8 @@
-    a more than adequate job of explaining everything required to get this
-    working. */
-+#include "ldso.h"
-+
- extern int _dl_linux_resolve(void);
- unsigned int
-@@ -48,20 +50,20 @@
-       int reloc_type;
-       ELF_RELOC *this_reloc;
-       char *strtab;
--      Elf32_Sym *symtab;
-+      ElfW(Sym) *symtab;
-       int symtab_index;
--      ELF_RELOC *rel_addr;
-+      char *rel_addr;
-       char *new_addr;
-       char **got_addr;
--      unsigned int instr_addr;
-+      ElfW(Addr) instr_addr;
-       char *symname;
--      rel_addr = (ELF_RELOC *)tpnt->dynamic_info[DT_JMPREL];
--      this_reloc = (ELF_RELOC *)(intptr_t)(rel_addr + reloc_entry);
--      reloc_type = ELF32_R_TYPE(this_reloc->r_info);
--      symtab_index = ELF32_R_SYM(this_reloc->r_info);
-+      rel_addr = (char *)tpnt->dynamic_info[DT_JMPREL];
-+      this_reloc = (ELF_RELOC *)(rel_addr + reloc_entry);
-+      reloc_type = ELF_R_TYPE(this_reloc->r_info);
-+      symtab_index = ELF_R_SYM(this_reloc->r_info);
--      symtab = (Elf32_Sym *)(intptr_t)tpnt->dynamic_info[DT_SYMTAB];
-+      symtab = (ElfW(Sym) *)tpnt->dynamic_info[DT_SYMTAB];
-       strtab = (char *)tpnt->dynamic_info[DT_STRTAB];
-       symname = strtab + symtab[symtab_index].st_name;
-@@ -72,7 +74,7 @@
-       }
-       /* Address of the jump instruction to fix up. */
--      instr_addr = ((int)this_reloc->r_offset + (int)tpnt->loadaddr);
-+      instr_addr = (this_reloc->r_offset + tpnt->loadaddr);
-       got_addr = (char **)instr_addr;
-       /* Get the address of the GOT entry. */
-@@ -88,159 +90,237 @@
-                       _dl_dprintf(_dl_debug_file, "\nresolve function: %s", symname);
-                       if (_dl_debug_detail)
-                               _dl_dprintf(_dl_debug_file,
--                                          "\n\tpatched: %x ==> %x @ %x",
-+                                          "\tpatched: %x ==> %x @ %x\n",
-                                           *got_addr, new_addr, got_addr);
-               }
-       }
--      if (!_dl_debug_nofixups) {
--              *got_addr = new_addr;
--      }
--#else
--      *got_addr = new_addr;
-+      if (!_dl_debug_nofixups)
- #endif
-+              *got_addr = new_addr;
--  return (unsigned int)new_addr;
-+      return (unsigned int)new_addr;
- }
--void
--_dl_parse_lazy_relocation_information(struct dyn_elf *arg_rpnt,
--      unsigned long rel_addr, unsigned long rel_size)
-+static int
-+_dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope,
-+        unsigned long rel_addr, unsigned long rel_size,
-+        int (*reloc_fnc)(struct elf_resolve *tpnt, struct dyn_elf *scope,
-+                         ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab))
- {
--      int i;
-+      unsigned int i;
-       char *strtab;
--      int reloc_type;
-+      ElfW(Sym) *symtab;
-+      ELF_RELOC *rpnt;
-       int symtab_index;
--      Elf32_Sym *symtab;
--      Elf32_Rela *rpnt;
--      unsigned int *reloc_addr;
--      struct elf_resolve *tpnt = arg_rpnt->dyn;
--
--      /* Now parse the relocation information.  */
--      rpnt = (Elf32_Rela *)rel_addr;
--      rel_size = rel_size / sizeof (Elf32_Rela);
--      symtab = (Elf32_Sym *)tpnt->dynamic_info[DT_SYMTAB];
-+      /* Parse the relocation information. */
-+      rpnt = (ELF_RELOC *)rel_addr;
-+      rel_size /= sizeof(ELF_RELOC);
-+
-+      symtab = (ElfW(Sym) *)tpnt->dynamic_info[DT_SYMTAB];
-       strtab = (char *)tpnt->dynamic_info[DT_STRTAB];
-       for (i = 0; i < rel_size; i++, rpnt++) {
--              reloc_addr = (int *) (tpnt->loadaddr + (int) rpnt->r_offset);
--              reloc_type = ELF32_R_TYPE (rpnt->r_info);
--              symtab_index = ELF32_R_SYM (rpnt->r_info);
-+              int res;
--              switch (reloc_type)
--              {
--              case R_68K_NONE:
--                      break;
--              case R_68K_JMP_SLOT:
--                      *reloc_addr += (unsigned int) tpnt->loadaddr;
--              break;
--              default:
--                      _dl_dprintf (2, "%s: (LAZY) can't handle reloc type ", _dl_progname);
-+              symtab_index = ELF_R_SYM(rpnt->r_info);
-+
-+              debug_sym(symtab, strtab, symtab_index);
-+              debug_reloc(symtab, strtab, rpnt);
-+
-+              res = reloc_fnc(tpnt, scope, rpnt, symtab, strtab);
-+
-+              if (res == 0)
-+                      continue;
-+
-+              _dl_dprintf(2, "\n%s: ", _dl_progname);
-+
-+              if (symtab_index)
-+                      _dl_dprintf(2, "symbol '%s': ",
-+                                  strtab + symtab[symtab_index].st_name);
-+
-+              if (unlikely(res < 0)) {
-+                      int reloc_type = ELF_R_TYPE(rpnt->r_info);
-+
-+                      _dl_dprintf(2, "can't handle reloc type "
- #if defined (__SUPPORT_LD_DEBUG__)
--                      _dl_dprintf (2, "%s ", _dl_reltypes_tab[reloc_type]);
-+                                  "%s\n", _dl_reltypes(reloc_type));
-+#else
-+                                  "%x\n", reloc_type);
- #endif
--                      if (symtab_index)
--                              _dl_dprintf (2, "'%s'", strtab + symtab[symtab_index].st_name);
--                      _dl_dprintf (2, "\n");
--                      _dl_exit (1);
-+                      _dl_exit(-res);
-+              } else if (unlikely(res > 0)) {
-+                      _dl_dprintf(2, "can't resolve symbol\n");
-+                      return res;
-               }
-       }
-+
-+      return 0;
- }
--int
--_dl_parse_relocation_information(struct dyn_elf *arg_rpnt,
--      unsigned long rel_addr, unsigned long rel_size)
-+static int
-+_dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
-+           ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab)
- {
--      int i;
--      char *strtab;
-       int reloc_type;
--      int goof = 0;
--      Elf32_Sym *symtab;
--      Elf32_Rela *rpnt;
--      unsigned int *reloc_addr;
--      unsigned int symbol_addr;
-       int symtab_index;
--      struct elf_resolve *tpnt = arg_rpnt->dyn;
--      /* Now parse the relocation information */
-+      char *symname;
-+      ElfW(Sym) *sym;
-+      ElfW(Addr) *reloc_addr;
-+      ElfW(Addr) symbol_addr;
-+#if defined (__SUPPORT_LD_DEBUG__)
-+      ElfW(Addr) old_val;
-+#endif
--      rpnt = (Elf32_Rela *)rel_addr;
--      rel_size = rel_size / sizeof (Elf32_Rela);
-+      reloc_addr = (ElfW(Addr)*)(tpnt->loadaddr + (unsigned long)rpnt->r_offset);
-+      reloc_type = ELF_R_TYPE(rpnt->r_info);
-+      symtab_index = ELF_R_SYM(rpnt->r_info);
-+      sym = &symtab[symtab_index];
-+      symbol_addr = 0;
-+      symname = strtab + sym->st_name;
-+
-+      if (symtab_index) {
-+              symbol_addr = (ElfW(Addr))_dl_find_hash(symname, scope, tpnt,
-+                                                          elf_machine_type_class(reloc_type));
-+              /*
-+               * We want to allow undefined references to weak symbols - this
-+               * might have been intentional.  We should not be linking local
-+               * symbols here, so all bases should be covered.
-+               */
-+              if (unlikely(!symbol_addr && ELF_ST_BIND(sym->st_info) != STB_WEAK)) {
-+                      _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname);
-+                      _dl_exit(1);
-+              };
-+      }
--      symtab = (Elf32_Sym *)tpnt->dynamic_info[DT_SYMTAB];
--      strtab = (char *)tpnt->dynamic_info[DT_STRTAB];
-+#if defined (__SUPPORT_LD_DEBUG__)
-+      old_val = *reloc_addr;
-+#endif
--      for (i = 0; i < rel_size; i++, rpnt++) {
--              reloc_addr = (int *) (tpnt->loadaddr + (int) rpnt->r_offset);
--              reloc_type = ELF32_R_TYPE (rpnt->r_info);
--              symtab_index = ELF32_R_SYM (rpnt->r_info);
--              symbol_addr = 0;
--              if (symtab_index) {
--                      symbol_addr = (unsigned int)
--                      _dl_find_hash (strtab + symtab[symtab_index].st_name,
--                                     tpnt->symbol_scope, tpnt,
--                                     elf_machine_type_class(reloc_type));
--
--                      /* We want to allow undefined references to weak symbols -
--                         this might have been intentional.  We should not be
--                         linking local symbols here, so all bases should be
--                         covered.  */
--                      if (!symbol_addr
--                          && ELF32_ST_BIND (symtab[symtab_index].st_info) != STB_WEAK)
--                      {
--                              _dl_dprintf (2, "%s: can't resolve symbol '%s'\n",
--                                           _dl_progname, strtab + symtab[symtab_index].st_name);
--                              _dl_exit (1);
--                      }
--              }
--              switch (reloc_type)
--              {
--                      case R_68K_NONE:
--                              break;
--                      case R_68K_8:
--                              *(char *) reloc_addr = symbol_addr + rpnt->r_addend;
--                              break;
--                      case R_68K_16:
--                              *(short *) reloc_addr = symbol_addr + rpnt->r_addend;
--                              break;
--                      case R_68K_32:
--                              *reloc_addr = symbol_addr + rpnt->r_addend;
--                              break;
--                      case R_68K_PC8:
--                              *(char *) reloc_addr = (symbol_addr + rpnt->r_addend
--                                                     - (unsigned int) reloc_addr);
--                              break;
--                      case R_68K_PC16:
--                              *(short *) reloc_addr = (symbol_addr + rpnt->r_addend
--                                                      - (unsigned int) reloc_addr);
--                              break;
--                      case R_68K_PC32:
--                              *reloc_addr = (symbol_addr + rpnt->r_addend
--                                            - (unsigned int) reloc_addr);
--                              break;
--                      case R_68K_GLOB_DAT:
--                      case R_68K_JMP_SLOT:
--                              *reloc_addr = symbol_addr;
--                              break;
--                      case R_68K_RELATIVE:
--                              *reloc_addr = ((unsigned int) tpnt->loadaddr
--                                            /* Compatibility kludge.  */
--                                            + (rpnt->r_addend ? : *reloc_addr));
--                              break;
--                      case R_68K_COPY:
-+      switch (reloc_type) {
-+              case R_68K_NONE:
-+                      break;
-+              case R_68K_8:
-+                      *(char *) reloc_addr = symbol_addr + rpnt->r_addend;
-+                      break;
-+              case R_68K_16:
-+                      *(short *) reloc_addr = symbol_addr + rpnt->r_addend;
-+                      break;
-+              case R_68K_32:
-+                      *reloc_addr = symbol_addr + rpnt->r_addend;
-+                      break;
-+              case R_68K_PC8:
-+                      *(char *) reloc_addr = (symbol_addr + rpnt->r_addend
-+                                             - (unsigned int) reloc_addr);
-+                      break;
-+              case R_68K_PC16:
-+                      *(short *) reloc_addr = (symbol_addr + rpnt->r_addend
-+                                              - (unsigned int) reloc_addr);
-+                      break;
-+              case R_68K_PC32:
-+                      *reloc_addr = (symbol_addr + rpnt->r_addend
-+                                    - (unsigned int) reloc_addr);
-+                      break;
-+              case R_68K_GLOB_DAT:
-+              case R_68K_JMP_SLOT:
-+                      *reloc_addr = symbol_addr + rpnt->r_addend;
-+                      break;
-+              /* handled by elf_machine_relative()
-+              case R_68K_RELATIVE:
-+                      *reloc_addr = ((unsigned int) tpnt->loadaddr
-+                                    / * Compatibility kludge.  * /
-+                                    + (rpnt->r_addend ? : *reloc_addr));
-+              */
-+                      break;
-+              case R_68K_COPY:
-+                      if (symbol_addr) {
-+#if defined (__SUPPORT_LD_DEBUG__)
-+                              if (_dl_debug_move)
-+                                      _dl_dprintf(_dl_debug_file,
-+                                                  "\t%s move %d bytes from %x to %x\n",
-+                                                  symname, sym->st_size,
-+                                                  symbol_addr, reloc_addr);
-+#endif
-                               _dl_memcpy ((void *) reloc_addr,
-                                           (void *) symbol_addr,
--                                          symtab[symtab_index].st_size);
--                              break;
--                      default:
--                              _dl_dprintf (2, "%s: can't handle reloc type ", _dl_progname);
--#if defined (__SUPPORT_LD_DEBUG__)
--                              _dl_dprintf (2, "%s ", _dl_reltypes_tab[reloc_type]);
--#endif
--                              if (symtab_index)
--                                      _dl_dprintf (2, "'%s'", strtab + symtab[symtab_index].st_name);
--                              _dl_dprintf (2, "\n");
--                              _dl_exit (1);
--              }
-+                                          sym->st_size);
-+                      } else
-+                              _dl_dprintf(_dl_debug_file, "no symbol_addr to copy !?\n");
-+                      break;
-+
-+              default:
-+                      return -1;      /* Calls _dl_exit(1). */
-+      }
-+
-+#if defined (__SUPPORT_LD_DEBUG__)
-+      if (_dl_debug_reloc && _dl_debug_detail)
-+              _dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x\n",
-+                          old_val, *reloc_addr, reloc_addr);
-+#endif
-+
-+      return 0;
-+}
-+
-+#undef LAZY_RELOC_WORKS
-+#ifdef LAZY_RELOC_WORKS
-+static int
-+_dl_do_lazy_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
-+                ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab)
-+{
-+      int reloc_type;
-+      int symtab_index;
-+      ElfW(Addr) *reloc_addr;
-+#if defined (__SUPPORT_LD_DEBUG__)
-+      ElfW(Addr) old_val;
-+#endif
-+
-+      (void)scope;
-+      symtab_index = ELF_R_SYM(rpnt->r_info);
-+      (void)strtab;
-+
-+      reloc_addr = (ElfW(Addr)*)(tpnt->loadaddr + rpnt->r_offset);
-+      reloc_type = ELF_R_TYPE(rpnt->r_info);
-+
-+#if defined (__SUPPORT_LD_DEBUG__)
-+      old_val = *reloc_addr;
-+#endif
-+
-+      switch (reloc_type) {
-+              case R_68K_NONE:
-+                      break;
-+              case R_68K_JMP_SLOT:
-+                      *reloc_addr += (unsigned int) tpnt->loadaddr;
-+                      break;
-+              default:
-+                      _dl_exit(1);
-       }
--      return goof;
-+
-+#if defined (__SUPPORT_LD_DEBUG__)
-+      if (_dl_debug_reloc && _dl_debug_detail)
-+              _dl_dprintf(_dl_debug_file, "\tpatched_lazy: %x ==> %x @ %x\n",
-+                          old_val, *reloc_addr, reloc_addr);
-+#endif
-+
-+      return 0;
-+}
-+#endif
-+
-+void
-+_dl_parse_lazy_relocation_information(struct dyn_elf *rpnt,
-+                                    unsigned long rel_addr,
-+                                    unsigned long rel_size)
-+{
-+#ifdef LAZY_RELOC_WORKS
-+      (void)_dl_parse(rpnt->dyn, NULL, rel_addr, rel_size, _dl_do_lazy_reloc);
-+#else
-+      _dl_parse_relocation_information(rpnt, rel_addr, rel_size);
-+#endif
-+}
-+
-+int
-+_dl_parse_relocation_information(struct dyn_elf *rpnt,
-+                               unsigned long rel_addr,
-+                               unsigned long rel_size)
-+{
-+      return _dl_parse(rpnt->dyn, rpnt->dyn->symbol_scope, rel_addr, rel_size, _dl_do_reloc);
- }
-diff -urN uClibc-0.9.28.orig/ldso/ldso/m68k/resolve.S uClibc-0.9.28/ldso/ldso/m68k/resolve.S
---- uClibc-0.9.28.orig/ldso/ldso/m68k/resolve.S        2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/m68k/resolve.S     2006-04-28 00:14:35.000000000 -0600
-@@ -8,14 +8,16 @@
- .globl _dl_linux_resolve
-       .type   _dl_linux_resolve,@function
- _dl_linux_resolve:
--      moveml  %a0/%a1,%sp@-
--#ifdef __PIC__
--      bsrl    _dl_linux_resolver@PLTPC
--#else
--      jbsr    _dl_linux_resolver
--#endif
--      moveml  %sp@+,%a0/%a1
--      addql   #8,%sp
--      jmp     @(%d0)
--.LFE2:
--      .size _dl_linux_resolve,.LFE2-_dl_linux_resolve
-+      # Save %a0 (struct return address) and %a1.
-+      move.l %a0, -(%sp)
-+      move.l %a1, -(%sp)
-+      # Call the real address resolver.
-+      jbsr _dl_linux_resolver
-+      # Restore register %a0 and %a1.
-+      move.l (%sp)+, %a1
-+      move.l (%sp)+, %a0
-+      # Pop parameters
-+      addq.l #8, %sp
-+      # Call real function.
-+      jmp (%d0)
-+.size _dl_linux_resolve,.-_dl_linux_resolve
-diff -urN uClibc-0.9.28.orig/ldso/ldso/mips/dl-startup.h uClibc-0.9.28/ldso/ldso/mips/dl-startup.h
---- uClibc-0.9.28.orig/ldso/ldso/mips/dl-startup.h     2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/mips/dl-startup.h  2006-04-28 00:14:35.000000000 -0600
-@@ -136,13 +136,3 @@
-               SEND_STDERR("Aiieeee!");                                        \
-               _dl_exit(1);                                                    \
-       }
--
--
--/*
-- * Transfer control to the user's application, once the dynamic loader
-- * is done.  This routine has to exit the current function, then
-- * call the _dl_elf_main function. For MIPS, we do it in assembly
-- * because the stack doesn't get properly restored otherwise. Got look
-- * at boot1_arch.h
-- */
--#define START() return _dl_elf_main
-diff -urN uClibc-0.9.28.orig/ldso/ldso/mips/dl-syscalls.h uClibc-0.9.28/ldso/ldso/mips/dl-syscalls.h
---- uClibc-0.9.28.orig/ldso/ldso/mips/dl-syscalls.h    2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/mips/dl-syscalls.h 2006-05-02 13:39:25.000000000 -0600
-@@ -1,7 +1,8 @@
- /* We can't use the real errno in ldso, since it has not yet
-  * been dynamicly linked in yet. */
-+#define __UCLIBC_MMAP_HAS_6_ARGS__
-+
-+#include "sys/syscall.h"
- extern int _dl_errno;
-+#undef __set_errno
- #define __set_errno(X) {(_dl_errno) = (X);}
--#include "sys/syscall.h"
--
--#define MMAP_HAS_6_ARGS
-diff -urN uClibc-0.9.28.orig/ldso/ldso/mips/dl-sysdep.h uClibc-0.9.28/ldso/ldso/mips/dl-sysdep.h
---- uClibc-0.9.28.orig/ldso/ldso/mips/dl-sysdep.h      2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/mips/dl-sysdep.h   2006-04-28 00:14:35.000000000 -0600
-@@ -30,7 +30,7 @@
- /* Initialization sequence for the application/library GOT.  */
- #define INIT_GOT(GOT_BASE,MODULE)                                             \
- do {                                                                          \
--      unsigned long i;                                                        \
-+      unsigned long idx;                                                      \
-                                                                               \
-       /* Check if this is the dynamic linker itself */                        \
-       if (MODULE->libtype == program_interpreter)                             \
-@@ -41,9 +41,9 @@
-       GOT_BASE[1] = (unsigned long) MODULE;                                   \
-                                                                               \
-       /* Add load address displacement to all local GOT entries */            \
--      i = 2;                                                                  \
--      while (i < MODULE->dynamic_info[DT_MIPS_LOCAL_GOTNO_IDX])               \
--              GOT_BASE[i++] += (unsigned long) MODULE->loadaddr;              \
-+      idx = 2;                                                                        \
-+      while (idx < MODULE->dynamic_info[DT_MIPS_LOCAL_GOTNO_IDX])             \
-+              GOT_BASE[idx++] += (unsigned long) MODULE->loadaddr;            \
-                                                                               \
- } while (0)
-@@ -63,8 +63,6 @@
- struct elf_resolve;
- void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt, int lazy);
--#define do_rem(result, n, base) ((result) = (n) % (base))
--
- /* 4096 bytes alignment */
- #define PAGE_ALIGN 0xfffff000
- #define ADDR_ALIGN 0xfff
-diff -urN uClibc-0.9.28.orig/ldso/ldso/mips/elfinterp.c uClibc-0.9.28/ldso/ldso/mips/elfinterp.c
---- uClibc-0.9.28.orig/ldso/ldso/mips/elfinterp.c      2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/mips/elfinterp.c   2006-04-28 00:14:35.000000000 -0600
-@@ -27,6 +27,8 @@
-  * SUCH DAMAGE.
-  */
-+#include "ldso.h"
-+
- extern int _dl_runtime_resolve(void);
- #define OFFSET_GP_GOT 0x7ff0
-@@ -146,7 +148,6 @@
-                       break;
-               default:
-                       {
--                              int reloc_type = ELF32_R_TYPE(rpnt->r_info);
-                               _dl_dprintf(2, "\n%s: ",_dl_progname);
-                               if (symtab_index)
-diff -urN uClibc-0.9.28.orig/ldso/ldso/powerpc/dl-startup.h uClibc-0.9.28/ldso/ldso/powerpc/dl-startup.h
---- uClibc-0.9.28.orig/ldso/ldso/powerpc/dl-startup.h  2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/powerpc/dl-startup.h       2006-04-28 00:14:35.000000000 -0600
-@@ -42,8 +42,10 @@
-     " bne     2b\n"
-     " addi    6,6,4\n"
- #endif
--    /* Pass a termination function pointer (in this case _dl_fini) in r7.  */
--    " lwz     7,_dl_fini@got(31)\n"
-+    /* Pass a termination function pointer (in this case _dl_fini) in r3. */
-+    /* Paulus promized he would keep r3 zero in the exec ABI. */
-+    " lwz     3,_dl_fini@got(31)\n"
-+    " mr      7,3\n"          /* Pass _dl_fini in r7 to maintain compat */
-     " bctr\n" /* Jump to entry point */
-     " .size   _start,.-_start\n"
-     " .previous\n"
-@@ -78,9 +80,3 @@
-               _dl_exit(100+ELF32_R_TYPE((RELP)->r_info));\
-       }                                               \
-       }
--/*
-- * Transfer control to the user's application, once the dynamic loader
-- * is done.  This routine has to exit the current function, then
-- * call the _dl_elf_main function.
-- */
--#define START()           return _dl_elf_main
-diff -urN uClibc-0.9.28.orig/ldso/ldso/powerpc/dl-syscalls.h uClibc-0.9.28/ldso/ldso/powerpc/dl-syscalls.h
---- uClibc-0.9.28.orig/ldso/ldso/powerpc/dl-syscalls.h 2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/powerpc/dl-syscalls.h      2006-05-02 13:39:14.000000000 -0600
-@@ -1,251 +1,8 @@
--/*
-- * This file contains the system call macros and syscall 
-- * numbers used by the shared library loader.
-- */
--
--#define MMAP_HAS_6_ARGS
--
--#define __NR_exit               1
--#define __NR_read               3
--#define __NR_write              4
--#define __NR_open               5
--#define __NR_close              6
--#define __NR_getpid            20
--#define __NR_getuid            24
--#define __NR_geteuid           49
--#define __NR_getgid            47
--#define __NR_getegid           50
--#define __NR_readlink          85
--#define __NR_mmap              90
--#define __NR_munmap            91
--#define __NR_stat             106
--#define __NR_mprotect         125
--
--
- /* We can't use the real errno in ldso, since it has not yet
-  * been dynamicly linked in yet. */
--extern int _dl_errno;
--
--/* Here are the macros which define how this platform makes
-- * system calls.  This particular variant does _not_ set 
-- * errno (note how it is disabled in __syscall_return) since
-- * these will get called before the errno symbol is dynamicly 
-- * linked. */
--
--#undef __syscall_return
--#define __syscall_return(type) \
--      return (__sc_err & 0x10000000 ? _dl_errno = __sc_ret, __sc_ret = -1 : 0), \
--             (type) __sc_ret
--
--#undef __syscall_clobbers
--#define __syscall_clobbers \
--      "r9", "r10", "r11", "r12"
--      //"r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"
--
--#undef _syscall0
--#define _syscall0(type,name)                                          \
--type name(void)                                                               \
--{                                                                     \
--      unsigned long __sc_ret, __sc_err;                               \
--      {                                                               \
--              register unsigned long __sc_0 __asm__ ("r0");           \
--              register unsigned long __sc_3 __asm__ ("r3");           \
--                                                                      \
--              __sc_0 = __NR_##name;                                   \
--              __asm__ __volatile__                                    \
--                      ("sc           \n\t"                            \
--                       "mfcr %1      "                                \
--                      : "=&r" (__sc_3), "=&r" (__sc_0)                \
--                      : "0"   (__sc_3), "1"   (__sc_0)                \
--                      : "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12" ); \
--              __sc_ret = __sc_3;                                      \
--              __sc_err = __sc_0;                                      \
--      }                                                               \
--      __syscall_return (type);                                        \
--}
--
--#undef _syscall1
--#define _syscall1(type,name,type1,arg1)                                       \
--type name(type1 arg1)                                                 \
--{                                                                     \
--      unsigned long __sc_ret, __sc_err;                               \
--      {                                                               \
--              register unsigned long __sc_0 __asm__ ("r0");           \
--              register unsigned long __sc_3 __asm__ ("r3");           \
--                                                                      \
--              __sc_3 = (unsigned long) (arg1);                        \
--              __sc_0 = __NR_##name;                                   \
--              __asm__ __volatile__                                    \
--                      ("sc           \n\t"                            \
--                       "mfcr %1      "                                \
--                      : "=&r" (__sc_3), "=&r" (__sc_0)                \
--                      : "0"   (__sc_3), "1"   (__sc_0)                \
--                      : "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12" ); \
--              __sc_ret = __sc_3;                                      \
--              __sc_err = __sc_0;                                      \
--      }                                                               \
--      __syscall_return (type);                                        \
--}
--
--#undef _syscall2
--#define _syscall2(type,name,type1,arg1,type2,arg2)                    \
--type name(type1 arg1, type2 arg2)                                     \
--{                                                                     \
--      unsigned long __sc_ret, __sc_err;                               \
--      {                                                               \
--              register unsigned long __sc_0 __asm__ ("r0");           \
--              register unsigned long __sc_3 __asm__ ("r3");           \
--              register unsigned long __sc_4 __asm__ ("r4");           \
--                                                                      \
--              __sc_3 = (unsigned long) (arg1);                        \
--              __sc_4 = (unsigned long) (arg2);                        \
--              __sc_0 = __NR_##name;                                   \
--              __asm__ __volatile__                                    \
--                      ("sc           \n\t"                            \
--                       "mfcr %1      "                                \
--                      : "=&r" (__sc_3), "=&r" (__sc_0)                \
--                      : "0"   (__sc_3), "1"   (__sc_0),               \
--                        "r"   (__sc_4)                                \
--                      : "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12" ); \
--              __sc_ret = __sc_3;                                      \
--              __sc_err = __sc_0;                                      \
--      }                                                               \
--      __syscall_return (type);                                        \
--}
--
--#undef _syscall3
--#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)         \
--type name(type1 arg1, type2 arg2, type3 arg3)                         \
--{                                                                     \
--      unsigned long __sc_ret, __sc_err;                               \
--      {                                                               \
--              register unsigned long __sc_0 __asm__ ("r0");           \
--              register unsigned long __sc_3 __asm__ ("r3");           \
--              register unsigned long __sc_4 __asm__ ("r4");           \
--              register unsigned long __sc_5 __asm__ ("r5");           \
--                                                                      \
--              __sc_3 = (unsigned long) (arg1);                        \
--              __sc_4 = (unsigned long) (arg2);                        \
--              __sc_5 = (unsigned long) (arg3);                        \
--              __sc_0 = __NR_##name;                                   \
--              __asm__ __volatile__                                    \
--                      ("sc           \n\t"                            \
--                       "mfcr %1      "                                \
--                      : "=&r" (__sc_3), "=&r" (__sc_0)                \
--                      : "0"   (__sc_3), "1"   (__sc_0),               \
--                        "r"   (__sc_4),                               \
--                        "r"   (__sc_5)                                \
--                      : "r6", "r7", "r8", "r9", "r10", "r11", "r12" ); \
--              __sc_ret = __sc_3;                                      \
--              __sc_err = __sc_0;                                      \
--      }                                                               \
--      __syscall_return (type);                                        \
--}
--
--#undef _syscall4
--#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
--type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4)             \
--{                                                                     \
--      unsigned long __sc_ret, __sc_err;                               \
--      {                                                               \
--              register unsigned long __sc_0 __asm__ ("r0");           \
--              register unsigned long __sc_3 __asm__ ("r3");           \
--              register unsigned long __sc_4 __asm__ ("r4");           \
--              register unsigned long __sc_5 __asm__ ("r5");           \
--              register unsigned long __sc_6 __asm__ ("r6");           \
--                                                                      \
--              __sc_3 = (unsigned long) (arg1);                        \
--              __sc_4 = (unsigned long) (arg2);                        \
--              __sc_5 = (unsigned long) (arg3);                        \
--              __sc_6 = (unsigned long) (arg4);                        \
--              __sc_0 = __NR_##name;                                   \
--              __asm__ __volatile__                                    \
--                      ("sc           \n\t"                            \
--                       "mfcr %1      "                                \
--                      : "=&r" (__sc_3), "=&r" (__sc_0)                \
--                      : "0"   (__sc_3), "1"   (__sc_0),               \
--                        "r"   (__sc_4),                               \
--                        "r"   (__sc_5),                               \
--                        "r"   (__sc_6)                                \
--                      : "r7", "r8", "r9", "r10", "r11", "r12" );      \
--              __sc_ret = __sc_3;                                      \
--              __sc_err = __sc_0;                                      \
--      }                                                               \
--      __syscall_return (type);                                        \
--}
--
--#undef _syscall5
--#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
--type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \
--{                                                                     \
--      unsigned long __sc_ret, __sc_err;                               \
--      {                                                               \
--              register unsigned long __sc_0 __asm__ ("r0");           \
--              register unsigned long __sc_3 __asm__ ("r3");           \
--              register unsigned long __sc_4 __asm__ ("r4");           \
--              register unsigned long __sc_5 __asm__ ("r5");           \
--              register unsigned long __sc_6 __asm__ ("r6");           \
--              register unsigned long __sc_7 __asm__ ("r7");           \
--                                                                      \
--              __sc_3 = (unsigned long) (arg1);                        \
--              __sc_4 = (unsigned long) (arg2);                        \
--              __sc_5 = (unsigned long) (arg3);                        \
--              __sc_6 = (unsigned long) (arg4);                        \
--              __sc_7 = (unsigned long) (arg5);                        \
--              __sc_0 = __NR_##name;                                   \
--              __asm__ __volatile__                                    \
--                      ("sc           \n\t"                            \
--                       "mfcr %1      "                                \
--                      : "=&r" (__sc_3), "=&r" (__sc_0)                \
--                      : "0"   (__sc_3), "1"   (__sc_0),               \
--                        "r"   (__sc_4),                               \
--                        "r"   (__sc_5),                               \
--                        "r"   (__sc_6),                               \
--                        "r"   (__sc_7)                                \
--                      : "r8", "r9", "r10", "r11", "r12" );            \
--              __sc_ret = __sc_3;                                      \
--              __sc_err = __sc_0;                                      \
--      }                                                               \
--      __syscall_return (type);                                        \
--}
--
--
--#undef _syscall6
--#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \
--type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6)     \
--{                                                                     \
--      unsigned long __sc_ret, __sc_err;                               \
--      {                                                               \
--              register unsigned long __sc_0 __asm__ ("r0");           \
--              register unsigned long __sc_3 __asm__ ("r3");           \
--              register unsigned long __sc_4 __asm__ ("r4");           \
--              register unsigned long __sc_5 __asm__ ("r5");           \
--              register unsigned long __sc_6 __asm__ ("r6");           \
--              register unsigned long __sc_7 __asm__ ("r7");           \
--              register unsigned long __sc_8 __asm__ ("r8");           \
--                                                                      \
--              __sc_3 = (unsigned long) (arg1);                        \
--              __sc_4 = (unsigned long) (arg2);                        \
--              __sc_5 = (unsigned long) (arg3);                        \
--              __sc_6 = (unsigned long) (arg4);                        \
--              __sc_7 = (unsigned long) (arg5);                        \
--              __sc_8 = (unsigned long) (arg6);                        \
--              __sc_0 = __NR_##name;                                   \
--              __asm__ __volatile__                                    \
--                      ("sc           \n\t"                            \
--                       "mfcr %1      "                                \
--                      : "=&r" (__sc_3), "=&r" (__sc_0)                \
--                      : "0"   (__sc_3), "1"   (__sc_0),               \
--                        "r"   (__sc_4),                               \
--                        "r"   (__sc_5),                               \
--                        "r"   (__sc_6),                               \
--                        "r"   (__sc_7),                               \
--                        "r"   (__sc_8)                                \
--                      : "r9", "r10", "r11", "r12" );                  \
--              __sc_ret = __sc_3;                                      \
--              __sc_err = __sc_0;                                      \
--      }                                                               \
--      __syscall_return (type);                                        \
--}
--
-+#define __UCLIBC_MMAP_HAS_6_ARGS__
-+#include "sys/syscall.h"
-+extern int _dl_errno;
-+#undef __set_errno
-+#define __set_errno(X) {(_dl_errno) = (X);}
-diff -urN uClibc-0.9.28.orig/ldso/ldso/powerpc/dl-sysdep.h uClibc-0.9.28/ldso/ldso/powerpc/dl-sysdep.h
---- uClibc-0.9.28.orig/ldso/ldso/powerpc/dl-sysdep.h   2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/powerpc/dl-sysdep.h        2006-04-28 00:14:35.000000000 -0600
-@@ -67,9 +67,6 @@
- extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
- void _dl_init_got(unsigned long *lpnt,struct elf_resolve *tpnt);
--
--#define do_rem(result, n, base) ((result) = (n) % (base))
--
- /* 4096 bytes alignment */
- #define PAGE_ALIGN 0xfffff000
- #define ADDR_ALIGN 0xfff
-diff -urN uClibc-0.9.28.orig/ldso/ldso/powerpc/elfinterp.c uClibc-0.9.28/ldso/ldso/powerpc/elfinterp.c
---- uClibc-0.9.28.orig/ldso/ldso/powerpc/elfinterp.c   2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/powerpc/elfinterp.c        2006-04-28 00:14:35.000000000 -0600
-@@ -29,6 +29,8 @@
-  * SUCH DAMAGE.
-  */
-+#include "ldso.h"
-+
- extern int _dl_linux_resolve(void);
- void _dl_init_got(unsigned long *plt,struct elf_resolve *tpnt)
-@@ -138,7 +140,7 @@
-       finaladdr = (Elf32_Addr) _dl_find_hash(symname,
-                       tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT);
-       if (unlikely(!finaladdr)) {
--              _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname);
-+              _dl_dprintf(2, "%s: can't resolve symbol '%s' in lib '%s'.\n", _dl_progname, symname, tpnt->libname);
-               _dl_exit(1);
-       };
-       finaladdr += this_reloc->r_addend;
-@@ -379,15 +381,15 @@
-               {
-                       int reloc_type = ELF32_R_TYPE(rpnt->r_info);
- #if defined (__SUPPORT_LD_DEBUG__)
--                      _dl_dprintf(2, "can't handle reloc type %s\n ", _dl_reltypes(reloc_type));
-+                      _dl_dprintf(2, "can't handle reloc type '%s' in lib '%s'\n", _dl_reltypes(reloc_type), tpnt->libname);
- #else
--                      _dl_dprintf(2, "can't handle reloc type %x\n", reloc_type);
-+                      _dl_dprintf(2, "can't handle reloc type %x in lib '%s'\n", reloc_type, tpnt->libname);
- #endif
--                      _dl_exit(-res);
-+                      return res;
-               }
-               if (unlikely(res >0))
-               {
--                      _dl_dprintf(2, "can't resolve symbol\n");
-+                      _dl_dprintf(2, "can't resolve symbol in lib '%s'.\n", tpnt->libname);
-                       return res;
-               }
-         }
-diff -urN uClibc-0.9.28.orig/ldso/ldso/sh/dl-startup.h uClibc-0.9.28/ldso/ldso/sh/dl-startup.h
---- uClibc-0.9.28.orig/ldso/ldso/sh/dl-startup.h       2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/sh/dl-startup.h    2006-04-28 00:14:35.000000000 -0600
-@@ -55,11 +55,3 @@
-       default:                                                \
-               _dl_exit(1);                                    \
-       }
--
--
--/*
-- * Transfer control to the user's application, once the dynamic loader
-- * is done.  This routine has to exit the current function, then
-- * call the _dl_elf_main function.
-- */
--#define START()   return _dl_elf_main;
-diff -urN uClibc-0.9.28.orig/ldso/ldso/sh/dl-syscalls.h uClibc-0.9.28/ldso/ldso/sh/dl-syscalls.h
---- uClibc-0.9.28.orig/ldso/ldso/sh/dl-syscalls.h      2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/sh/dl-syscalls.h   2006-05-02 13:39:28.000000000 -0600
-@@ -1,7 +1,8 @@
- /* We can't use the real errno in ldso, since it has not yet
-  * been dynamicly linked in yet. */
-+#define __UCLIBC_MMAP_HAS_6_ARGS__
-+
-+#include "sys/syscall.h"
- extern int _dl_errno;
-+#undef __set_errno
- #define __set_errno(X) {(_dl_errno) = (X);}
--#include "sys/syscall.h"
--
--#define MMAP_HAS_6_ARGS
-diff -urN uClibc-0.9.28.orig/ldso/ldso/sh/dl-sysdep.h uClibc-0.9.28/ldso/ldso/sh/dl-sysdep.h
---- uClibc-0.9.28.orig/ldso/ldso/sh/dl-sysdep.h        2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/sh/dl-sysdep.h     2006-04-28 00:14:35.000000000 -0600
-@@ -25,7 +25,7 @@
- struct elf_resolve;
- extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
--static __inline__ unsigned int
-+static inline unsigned int
- _dl_urem(unsigned int n, unsigned int base)
- {
-   int res;
-@@ -104,7 +104,7 @@
- elf_machine_dynamic (void)
- {
-       register Elf32_Addr *got;
--      asm ("mov r12,%0" :"=r" (got));
-+      __asm__ ("mov r12,%0" :"=r" (got));
-       return *got;
- }
-@@ -113,7 +113,7 @@
- elf_machine_load_address (void)
- {
-       Elf32_Addr addr;
--      asm ("mov.l 1f,r0\n\
-+      __asm__ ("mov.l 1f,r0\n\
-         mov.l 3f,r2\n\
-         add r12,r2\n\
-         mov.l @(r0,r12),r0\n\
-diff -urN uClibc-0.9.28.orig/ldso/ldso/sh/elfinterp.c uClibc-0.9.28/ldso/ldso/sh/elfinterp.c
---- uClibc-0.9.28.orig/ldso/ldso/sh/elfinterp.c        2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/sh/elfinterp.c     2006-04-28 00:14:35.000000000 -0600
-@@ -39,6 +39,8 @@
-    a more than adequate job of explaining everything required to get this
-    working. */
-+#include "ldso.h"
-+
- extern int _dl_linux_resolve(void);
- unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
-diff -urN uClibc-0.9.28.orig/ldso/ldso/sh64/dl-startup.h uClibc-0.9.28/ldso/ldso/sh64/dl-startup.h
---- uClibc-0.9.28.orig/ldso/ldso/sh64/dl-startup.h     2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/sh64/dl-startup.h  2006-04-28 00:14:35.000000000 -0600
-@@ -115,12 +115,3 @@
-       default:                                                        \
-               _dl_exit(1);                                            \
-       }
--
--/*
-- * Transfer control to the user's application, once the dynamic loader
-- * is done.  This routine has to exit the current function, then
-- * call the _dl_elf_main function.
-- */
--
--#define START()   return _dl_elf_main;
--
-diff -urN uClibc-0.9.28.orig/ldso/ldso/sh64/dl-syscalls.h uClibc-0.9.28/ldso/ldso/sh64/dl-syscalls.h
---- uClibc-0.9.28.orig/ldso/ldso/sh64/dl-syscalls.h    2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/sh64/dl-syscalls.h 2006-04-28 00:14:35.000000000 -0600
-@@ -1,8 +1,9 @@
- /* We can't use the real errno in ldso, since it has not yet
-  * been dynamicly linked in yet. */
-+#include "sys/syscall.h"
- extern int _dl_errno;
-+#undef __set_errno
- #define __set_errno(X) {(_dl_errno) = (X);}
--#include "sys/syscall.h"
- #undef __syscall_return
- #define __syscall_return(type, res)                                   \
-diff -urN uClibc-0.9.28.orig/ldso/ldso/sh64/dl-sysdep.h uClibc-0.9.28/ldso/ldso/sh64/dl-sysdep.h
---- uClibc-0.9.28.orig/ldso/ldso/sh64/dl-sysdep.h      2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/sh64/dl-sysdep.h   2006-04-28 00:14:35.000000000 -0600
-@@ -25,8 +25,6 @@
- struct elf_resolve;
- extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
--#define do_rem(result, n, base) ((result) = (n) % (base))
--
- /* 4096 bytes alignment */
- #define PAGE_ALIGN 0xfffff000
- #define ADDR_ALIGN 0xfff
-diff -urN uClibc-0.9.28.orig/ldso/ldso/sh64/elfinterp.c uClibc-0.9.28/ldso/ldso/sh64/elfinterp.c
---- uClibc-0.9.28.orig/ldso/ldso/sh64/elfinterp.c      2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/sh64/elfinterp.c   2006-04-28 00:14:35.000000000 -0600
-@@ -41,6 +41,8 @@
-    a more than adequate job of explaining everything required to get this
-    working. */
-+#include "ldso.h"
-+
- extern int _dl_linux_resolve(void);
- unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
-diff -urN uClibc-0.9.28.orig/ldso/ldso/sparc/dl-startup.h uClibc-0.9.28/ldso/ldso/sparc/dl-startup.h
---- uClibc-0.9.28.orig/ldso/ldso/sparc/dl-startup.h    2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/sparc/dl-startup.h 2006-04-28 00:14:35.000000000 -0600
-@@ -3,15 +3,46 @@
-  * needed for this architecture.  See arm/boot1_arch.h for an example of what
-  * can be done.
-  */
--asm(
--      "       .text\n"
--      "       .global _start\n"
--      "       .type   _start,%function\n"
--      "_start:\n"
--      "       .set _start,_dl_start\n"
--      "       .size _start,.-_start\n"
--      "       .previous\n"
--);
-+
-+asm ("\
-+      .text\n\
-+      .global _start\n\
-+      .type   _start,%function\n\
-+      .align 32\n\
-+_start:\n\
-+      /* Allocate space for functions to drop their arguments. */\n\
-+      sub     %sp, 6*4, %sp\n\
-+      /* Pass pointer to argument block to _dl_start. */\n\
-+      call _dl_start\n\
-+      add    %sp, 22*4, %o0\n\
-+      /* FALTHRU */\n\
-+      .globl  _dl_start_user\n\
-+      .type   _dl_start_user, @function\n\
-+_dl_start_user:\n\
-+  /* Load the PIC register.  */\n\
-+1:    call    2f\n\
-+      sethi  %hi(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7\n\
-+2:    or  %l7, %lo(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7\n\
-+      add %l7, %o7, %l7\n\
-+  /* Save the user entry point address in %l0 */\n\
-+      mov %o0, %l0\n\
-+  /* See if we were run as a command with the executable file name as an\n\
-+       extra leading argument.  If so, adjust the contents of the stack.  */\n\
-+      sethi   %hi(_dl_skip_args), %g2\n\
-+      or  %g2, %lo(_dl_skip_args), %g2\n\
-+      ld  [%l7+%g2], %i0\n\
-+      ld  [%i0], %i0\n\
-+      tst %i0\n\
-+  /* Pass our finalizer function to the user in %g1.  */\n\
-+      sethi   %hi(_dl_fini), %g1\n\
-+      or      %g1, %lo(_dl_fini), %g1\n\
-+      ld      [%l7+%g1], %g1\n\
-+  /* Jump to the user's entry point and deallocate the extra stack we got.  */\n\
-+      jmp %l0\n\
-+       add    %sp, 6*4, %sp\n\
-+      .size   _dl_start_user, . - _dl_start_user\n\
-+      .previous\n\
-+");
- /*
-  * Get a pointer to the argv array.  On many platforms this can be just
-@@ -19,17 +50,15 @@
-  * do something a little more subtle here.  We assume that argc is stored
-  * at the word just below the argvp that we return here.
-  */
--#define GET_ARGV(ARGVP, ARGS) __asm__("\tadd %%fp,68,%0\n" : "=r" (ARGVP));
-+#define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long *) ARGS) + 1)
- /*
-  * Here is a macro to perform a relocation.  This is only used when
-  * bootstrapping the dynamic loader.
-  */
- #define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD,SYMTAB) \
--      switch(ELF32_R_TYPE((RELP)->r_info)) { \
-+switch(ELF_R_TYPE((RELP)->r_info)) { \
-       case R_SPARC_32: \
--              *REL = SYMBOL + (RELP)->r_addend; \
--              break; \
-       case R_SPARC_GLOB_DAT: \
-               *REL = SYMBOL + (RELP)->r_addend; \
-               break; \
-@@ -38,7 +67,6 @@
-               REL[2] = 0x81c06000 | (SYMBOL & 0x3ff); \
-               break; \
-       case R_SPARC_NONE: \
--              break; \
-       case R_SPARC_WDISP30: \
-               break; \
-       case R_SPARC_RELATIVE: \
-@@ -46,18 +74,4 @@
-               break; \
-       default: \
-               _dl_exit(1); \
--      }
--
--/*
-- * Transfer control to the user's application, once the dynamic loader
-- * is done.  The crt calls atexit with $g1 if not null, so we need to
-- * ensure that it contains NULL.
-- */
--
--#define START() \
--      __asm__ volatile ( \
--              "add %%g0,%%g0,%%g1\n\t" \
--              "jmpl %0, %%o7\n\t"     \
--              "restore %%g0,%%g0,%%g0\n\t" \
--              : /*"=r" (status) */ : \
--              "r" (_dl_elf_main): "g1", "o0", "o1")
-+}
-diff -urN uClibc-0.9.28.orig/ldso/ldso/sparc/dl-syscalls.h uClibc-0.9.28/ldso/ldso/sparc/dl-syscalls.h
---- uClibc-0.9.28.orig/ldso/ldso/sparc/dl-syscalls.h   2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/sparc/dl-syscalls.h        2006-05-02 13:39:21.000000000 -0600
-@@ -1,187 +1,8 @@
--/*
-- * This file contains the system call macros and syscall 
-- * numbers used by the shared library loader.
-- *
-- * NOTE: This should be integrated/moved to 
-- *       sysdeps/linux/sparc/bits/syscalls.h at some point ...
-- */
--
--#define MMAP_HAS_6_ARGS
--
--#define __NR_exit               1
--#define __NR_read               3
--#define __NR_write              4
--#define __NR_open               5
--#define __NR_close              6
--#define __NR_getpid            20
--#define __NR_getuid            24
--#define __NR_getgid            47
--#define __NR_geteuid           49
--#define __NR_getegid           50
--#define __NR_readlink          58
--#define __NR_mmap              71
--#define __NR_munmap            73
--#define __NR_stat              38
--#define __NR_mprotect          74
--
- /* We can't use the real errno in ldso, since it has not yet
-  * been dynamicly linked in yet. */
-+#define __UCLIBC_MMAP_HAS_6_ARGS__
-+
-+#include "sys/syscall.h"
- extern int _dl_errno;
-+#undef __set_errno
- #define __set_errno(X) {(_dl_errno) = (X);}
--
--/* Here are the macros which define how this platform makes
-- * system calls.  This particular variant does _not_ set 
-- * errno (note how _dl_errno is used in __syscall_return) since
-- * these will get called before the errno symbol is dynamicly 
-- * linked. */
--
--#define __syscall_return(type, res) \
--do { \
--      if (res < -255 || res >= 0) \
--              return (type) res; \
--      __set_errno(-res); \
--      res = -1; \
--      return (type) res; \
--} while (0)
--
--#define _syscall0(type,name) \
--type name(void) \
--{ \
--      long __res; \
--      register long __g1 __asm__ ("g1") = __NR_##name; \
--      __asm__ __volatile__ ( \
--              "t 0x10\n\t" \
--              "bcc 1f\n\t" \
--              "mov %%o0, %0\n\t" \
--              "sub %%g0, %%o0, %0\n\t" \
--              "1:\n\t" \
--              : "=r" (__res)\
--              : "r" (__g1) \
--              : "o0", "cc"); \
--      __syscall_return(type, __res); \
--}
--
--#define _syscall1(type,name,type1,arg1) \
--type name(type1 arg1) \
--{ \
--      long __res; \
--      register long __g1 __asm__ ("g1") = __NR_##name; \
--      register long __o0 __asm__ ("o0") = (long)(arg1); \
--      __asm__ __volatile__ ( \
--              "t 0x10\n\t" \
--              "bcc 1f\n\t" \
--              "mov %%o0, %0\n\t" \
--              "sub %%g0, %%o0, %0\n\t" \
--              "1:\n\t" \
--              : "=r" (__res), "=&r" (__o0) \
--              : "1" (__o0), "r" (__g1) \
--              : "cc"); \
--      __syscall_return(type, __res); \
--}
--
--#define _syscall2(type,name,type1,arg1,type2,arg2) \
--type name(type1 arg1,type2 arg2) \
--{ \
--      long __res; \
--      register long __g1 __asm__ ("g1") = __NR_##name; \
--      register long __o0 __asm__ ("o0") = (long)(arg1); \
--      register long __o1 __asm__ ("o1") = (long)(arg2); \
--      __asm__ __volatile__ ( \
--              "t 0x10\n\t" \
--              "bcc 1f\n\t" \
--              "mov %%o0, %0\n\t" \
--              "sub %%g0, %%o0, %0\n\t" \
--              "1:\n\t" \
--              : "=r" (__res), "=&r" (__o0) \
--              : "1" (__o0), "r" (__o1), "r" (__g1) \
--              : "cc"); \
--      __syscall_return(type, __res); \
--}
--
--#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
--type name(type1 arg1,type2 arg2,type3 arg3) \
--{ \
--      long __res; \
--      register long __g1 __asm__ ("g1") = __NR_##name; \
--      register long __o0 __asm__ ("o0") = (long)(arg1); \
--      register long __o1 __asm__ ("o1") = (long)(arg2); \
--      register long __o2 __asm__ ("o2") = (long)(arg3); \
--      __asm__ __volatile__ ( \
--              "t 0x10\n\t" \
--              "bcc 1f\n\t" \
--              "mov %%o0, %0\n\t" \
--              "sub %%g0, %%o0, %0\n\t" \
--              "1:\n\t" \
--              : "=r" (__res), "=&r" (__o0) \
--              : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1) \
--              : "cc"); \
--      __syscall_return(type, __res); \
--}
--
--#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
--type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
--{ \
--      long __res; \
--      register long __g1 __asm__ ("g1") = __NR_##name; \
--      register long __o0 __asm__ ("o0") = (long)(arg1); \
--      register long __o1 __asm__ ("o1") = (long)(arg2); \
--      register long __o2 __asm__ ("o2") = (long)(arg3); \
--      register long __o3 __asm__ ("o3") = (long)(arg4); \
--      __asm__ __volatile__ ( \
--              "t 0x10\n\t" \
--              "bcc 1f\n\t" \
--              "mov %%o0, %0\n\t" \
--              "sub %%g0, %%o0, %0\n\t" \
--              "1:\n\t" \
--              : "=r" (__res), "=&r" (__o0) \
--              : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__g1) \
--              : "cc"); \
--      __syscall_return(type, __res); \
--} 
--
--#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
--        type5,arg5) \
--type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
--{ \
--      long __res; \
--      register long __g1 __asm__ ("g1") = __NR_##name; \
--      register long __o0 __asm__ ("o0") = (long)(arg1); \
--      register long __o1 __asm__ ("o1") = (long)(arg2); \
--      register long __o2 __asm__ ("o2") = (long)(arg3); \
--      register long __o3 __asm__ ("o3") = (long)(arg4); \
--      register long __o4 __asm__ ("o4") = (long)(arg5); \
--      __asm__ __volatile__ ( \
--              "t 0x10\n\t" \
--              "bcc 1f\n\t" \
--              "mov %%o0, %0\n\t" \
--              "sub %%g0, %%o0, %0\n\t" \
--              "1:\n\t" \
--              : "=r" (__res), "=&r" (__o0) \
--              : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__o4), "r" (__g1) \
--              : "cc"); \
--      __syscall_return(type, __res); \
--}
--
--#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
--        type5,arg5,type6,arg6) \
--type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \
--{ \
--      long __res; \
--      register long __g1 __asm__ ("g1") = __NR_##name; \
--      register long __o0 __asm__ ("o0") = (long)(arg1); \
--      register long __o1 __asm__ ("o1") = (long)(arg2); \
--      register long __o2 __asm__ ("o2") = (long)(arg3); \
--      register long __o3 __asm__ ("o3") = (long)(arg4); \
--      register long __o4 __asm__ ("o4") = (long)(arg5); \
--      register long __o5 __asm__ ("o5") = (long)(arg6); \
--      __asm__ __volatile__ ( \
--              "t 0x10\n\t" \
--              "bcc 1f\n\t" \
--              "mov %%o0, %0\n\t" \
--              "sub %%g0, %%o0, %0\n\t" \
--              "1:\n\t" \
--              : "=r" (__res), "=&r" (__o0) \
--              : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__o4), "r" (__o5), "r" (__g1) \
--              : "cc"); \
--      __syscall_return(type, __res); \
--}
-diff -urN uClibc-0.9.28.orig/ldso/ldso/sparc/dl-sysdep.h uClibc-0.9.28/ldso/ldso/sparc/dl-sysdep.h
---- uClibc-0.9.28.orig/ldso/ldso/sparc/dl-sysdep.h     2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/sparc/dl-sysdep.h  2006-04-28 00:14:35.000000000 -0600
-@@ -1,9 +1,9 @@
--
-+/* vi: set sw=4 ts=4: */
- /*
-  * Various assmbly language/system dependent  hacks that are required
-  * so that we can minimize the amount of platform specific code.
-+ * Copyright (C) 2000-2004 by Erik Andersen <andersen@codepoet.org>
-  */
--#define LINUXBIN
- /* Define this if the system uses RELOCA.  */
- #define ELF_USES_RELOCA
-@@ -31,19 +31,14 @@
- #undef  MAGIC2
- /* Used for error messages */
--#define ELF_TARGET "Sparc"
-+#define ELF_TARGET "sparc"
--#ifndef COMPILE_ASM
--extern unsigned int _dl_linux_resolver(unsigned int reloc_entry,
--                                      unsigned int * i);
--#endif
-+struct elf_resolve;
-+unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
- /*
-  * Define this if you want a dynamic loader that works on Solaris.
-  */
--#ifndef __linux__
--#define SOLARIS_COMPATIBLE
--#endif
- #ifndef COMPILE_ASM
- /* Cheap modulo implementation, taken from arm/ld_sysdep.h. */
-@@ -87,13 +82,6 @@
- #define do_rem(result, n, base) ((result) = sparc_mod(n, base))
- #endif
--/*
-- * dbx wants the binder to have a specific name.  Mustn't disappoint it.
-- */
--#ifdef SOLARIS_COMPATIBLE
--#define _dl_linux_resolve _elf_rtbndr
--#endif
--
- /* 4096 bytes alignment */
- /* ...but 8192 is required for mmap() on sparc64 kernel */
- #define PAGE_ALIGN 0xffffe000
-@@ -160,7 +148,7 @@
- elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr,
-                     Elf32_Word relative_count)
- {
--       Elf32_Rela * rpnt = (void *)rel_addr;
-+      Elf32_Rela * rpnt = (void *)rel_addr;
-       --rpnt;
-       do {
-               Elf32_Addr *const reloc_addr = (void *) (load_off + (++rpnt)->r_offset);
-diff -urN uClibc-0.9.28.orig/ldso/ldso/sparc/elfinterp.c uClibc-0.9.28/ldso/ldso/sparc/elfinterp.c
---- uClibc-0.9.28.orig/ldso/ldso/sparc/elfinterp.c     2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/sparc/elfinterp.c  2006-04-28 00:14:35.000000000 -0600
-@@ -33,236 +33,340 @@
- an ELF sharable library or a linux style of shared library. */
- /* Disclaimer:  I have never seen any AT&T source code for SVr4, nor have
--   I ever taken any courses on internals.  This program was developed using
--   information available through the book "UNIX SYSTEM V RELEASE 4,
--   Programmers guide: Ansi C and Programming Support Tools", which did
--   a more than adequate job of explaining everything required to get this
--   working. */
-+       I ever taken any courses on internals.  This program was developed using
-+       information available through the book "UNIX SYSTEM V RELEASE 4,
-+       Programmers guide: Ansi C and Programming Support Tools", which did
-+       a more than adequate job of explaining everything required to get this
-+       working. */
-+
-+/* Some SPARC opcodes we need to use for self-modifying code.  */
-+#define OPCODE_NOP    0x01000000 /* nop */
-+#define OPCODE_CALL   0x40000000 /* call ?; add PC-rel word address */
-+#define OPCODE_SETHI_G1       0x03000000 /* sethi ?, %g1; add value>>10 */
-+#define OPCODE_JMP_G1 0x81c06000 /* jmp %g1+?; add lo 10 bits of value */
-+#define OPCODE_SAVE_SP        0x9de3bfa8 /* save %sp, -(16+6)*4, %sp */
-+#define OPCODE_BA     0x30800000 /* b,a ?; add PC-rel word address */
- extern int _dl_linux_resolve(void);
--unsigned int _dl_linux_resolver(unsigned int reloc_entry, unsigned int * plt)
-+unsigned long
-+_dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
- {
--  int reloc_type;
--  Elf32_Rela * this_reloc;
--  char * strtab;
--  Elf32_Sym * symtab;
--  Elf32_Rela * rel_addr;
--  struct elf_resolve * tpnt;
--  int symtab_index;
--  char * new_addr;
--  char ** got_addr;
--  unsigned int instr_addr;
--  tpnt = (struct elf_resolve *) plt[2];
--
--  rel_addr = (Elf32_Rela *)tpnt->dynamic_info[DT_JMPREL];
--
--  /*
--   * Generate the correct relocation index into the .rela.plt section.
--   */
--  reloc_entry = (reloc_entry >> 10) - 0xc;
--
--  this_reloc = (Elf32_Rela *) ((char *) rel_addr + reloc_entry);
--
--  reloc_type = ELF32_R_TYPE(this_reloc->r_info);
--  symtab_index = ELF32_R_SYM(this_reloc->r_info);
--
--  symtab =  (Elf32_Sym *)tpnt->dynamic_info[DT_SYMTAB];
--  strtab = (char *)tpnt->dynamic_info[DT_STRTAB];
--
--#ifdef __SUPPORT_LD_DEBUG__
--  if (_dl_debug_symbols) {
--  _dl_dprintf(2, "tpnt = %x\n", tpnt);
--  _dl_dprintf(2, "reloc = %x\n", this_reloc);
--  _dl_dprintf(2, "symtab = %x\n", symtab);
--  _dl_dprintf(2, "strtab = %x\n", strtab);
--  }
--#endif
--
--
--  if (unlikely(reloc_type != R_SPARC_JMP_SLOT)) {
--    _dl_dprintf(2, "%s: incorrect relocation type in jump relocations (%d)\n",
--                _dl_progname, reloc_type);
--    _dl_exit(30);
--  };
--
--  /* Address of jump instruction to fix up */
--  instr_addr  = ((int)this_reloc->r_offset  + (int)tpnt->loadaddr);
--  got_addr = (char **) instr_addr;
--
--#ifdef __SUPPORT_LD_DEBUG__
--  if (_dl_debug_symbols) {
--  _dl_dprintf(2, "symtab_index %x\n", symtab_index);
--
--        _dl_dprintf(2, "Resolving symbol %s\n",
--                        strtab + symtab[symtab_index].st_name);
--  }
--#endif
--
--  /* Get the address of the GOT entry */
--  new_addr = _dl_find_hash(strtab + symtab[symtab_index].st_name,
--                      tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT);
--  if(unlikely(!new_addr)) {
--    _dl_dprintf(2, "%s: can't resolve symbol '%s'\n",
--             _dl_progname, strtab + symtab[symtab_index].st_name);
--    _dl_exit(31);
--  };
-+      int reloc_type;
-+      ELF_RELOC *this_reloc;
-+      char *strtab;
-+      ElfW(Sym) *symtab;
-+      int symtab_index;
-+      char *rel_addr;
-+      char *new_addr;
-+      char **got_addr;
-+      ElfW(Addr) instr_addr;
-+      char *symname;
-+
-+      rel_addr = (char *)tpnt->dynamic_info[DT_JMPREL];
-+      /*
-+       * Generate the correct relocation index into the .rela.plt section.
-+       */
-+      reloc_entry = (reloc_entry >> 10) - 0xc;
-+
-+      this_reloc = (ELF_RELOC *)(rel_addr + reloc_entry);
-+      reloc_type = ELF_R_TYPE(this_reloc->r_info);
-+      symtab_index = ELF_R_SYM(this_reloc->r_info);
-+
-+      symtab = (ElfW(Sym) *)tpnt->dynamic_info[DT_SYMTAB];
-+      strtab = (char *)tpnt->dynamic_info[DT_STRTAB];
-+      symname = strtab + symtab[symtab_index].st_name;
-+
-+      if (unlikely(reloc_type != R_SPARC_JMP_SLOT)) {
-+              _dl_dprintf(2, "%s: Incorrect relocation type in jump relocations\n",
-+                                _dl_progname);
-+              _dl_exit(1);
-+      }
-+
-+      /* Address of the jump instruction to fix up. */
-+      instr_addr = (this_reloc->r_offset + tpnt->loadaddr);
-+      got_addr = (char **)instr_addr;
-+
-+      /* Get the address of the GOT entry */
-+      new_addr = _dl_find_hash(symname, tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT);
-+      if (unlikely(!new_addr)) {
-+              _dl_dprintf(2, "%s: Can't resolve symbol '%s'\n", _dl_progname, symname);
-+              _dl_exit(1);
-+      }
- #if defined (__SUPPORT_LD_DEBUG__)
--      if ((unsigned long) got_addr < 0x40000000)
--      {
--              if (_dl_debug_bindings)
--              {
--                      _dl_dprintf(_dl_debug_file, "\nresolve function: %s",
--                                      strtab + symtab[symtab_index].st_name);
--                      if(_dl_debug_detail) _dl_dprintf(_dl_debug_file,
--                                      "\tpatch %x ==> %x @ %x", *got_addr, new_addr, got_addr);
-+      if ((unsigned long)got_addr < 0x40000000) {
-+              if (_dl_debug_bindings) {
-+                      _dl_dprintf(_dl_debug_file, "\nresolve function: %s", symname);
-+                      if (_dl_debug_detail)
-+                              _dl_dprintf(_dl_debug_file,
-+                                          "\tpatched: %x ==> %x @ %x\n",
-+                                          *got_addr, new_addr, got_addr);
-               }
-       }
--      if (!_dl_debug_nofixups) {
-+      if (!_dl_debug_nofixups)
-+#endif
-+      {
-               got_addr[1] = (char *) (0x03000000 | (((unsigned int) new_addr >> 10) & 0x3fffff));
-               got_addr[2] = (char *) (0x81c06000 | ((unsigned int) new_addr & 0x3ff));
-       }
-+
-+      return (unsigned long)new_addr;
-+}
-+
-+static int
-+_dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope,
-+              unsigned long rel_addr, unsigned long rel_size,
-+              int (*reloc_fnc)(struct elf_resolve *tpnt, struct dyn_elf *scope,
-+                         ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab))
-+{
-+      unsigned int i;
-+      char *strtab;
-+      ElfW(Sym) *symtab;
-+      ELF_RELOC *rpnt;
-+      int symtab_index;
-+
-+      /* Parse the relocation information. */
-+      rpnt = (ELF_RELOC *)rel_addr;
-+      rel_size /= sizeof(ELF_RELOC);
-+
-+      symtab = (ElfW(Sym) *)tpnt->dynamic_info[DT_SYMTAB];
-+      strtab = (char *)tpnt->dynamic_info[DT_STRTAB];
-+
-+      for (i = 0; i < rel_size; i++, rpnt++) {
-+              int res;
-+
-+              symtab_index = ELF_R_SYM(rpnt->r_info);
-+
-+              debug_sym(symtab, strtab, symtab_index);
-+              debug_reloc(symtab, strtab, rpnt);
-+
-+              res = reloc_fnc(tpnt, scope, rpnt, symtab, strtab);
-+
-+              if (res == 0)
-+                      continue;
-+
-+              _dl_dprintf(2, "\n%s: ", _dl_progname);
-+
-+              if (symtab_index)
-+                      _dl_dprintf(2, "symbol '%s': ",
-+                                  strtab + symtab[symtab_index].st_name);
-+
-+              if (unlikely(res < 0)) {
-+                      int reloc_type = ELF_R_TYPE(rpnt->r_info);
-+
-+                      _dl_dprintf(2, "can't handle reloc type "
-+#if defined (__SUPPORT_LD_DEBUG__)
-+                                  "%s\n", _dl_reltypes(reloc_type));
- #else
--      got_addr[1] = (char *) (0x03000000 | (((unsigned int) new_addr >> 10) & 0x3fffff));
--      got_addr[2] = (char *) (0x81c06000 | ((unsigned int) new_addr & 0x3ff));
-+                                  "%x\n", reloc_type);
- #endif
-+                      _dl_exit(-res);
-+              } else if (unlikely(res > 0)) {
-+                      _dl_dprintf(2, "can't resolve symbol\n");
-+                      return res;
-+              }
-+      }
-+
-+      return 0;
-+}
--      _dl_dprintf(2, "Address = %x\n",new_addr);
--      _dl_exit(32);
-+static int
-+_dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
-+                       ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab)
-+{
-+      int reloc_type;
-+      int symtab_index;
-+      char *symname;
-+      ElfW(Sym) *sym;
-+      ElfW(Addr) *reloc_addr;
-+      ElfW(Addr) symbol_addr;
-+#if defined (__SUPPORT_LD_DEBUG__)
-+      ElfW(Addr) old_val;
-+#endif
-+
-+      reloc_addr = (ElfW(Addr)*)(tpnt->loadaddr + (unsigned long)rpnt->r_offset);
-+      reloc_type = ELF_R_TYPE(rpnt->r_info);
-+      symtab_index = ELF_R_SYM(rpnt->r_info);
-+      sym = &symtab[symtab_index];
-+      symbol_addr = 0;
-+      symname = strtab + sym->st_name;
-+
-+      if (symtab_index) {
-+              symbol_addr = (ElfW(Addr))_dl_find_hash(symname, scope, tpnt,
-+                                                          elf_machine_type_class(reloc_type));
-+              /*
-+               * We want to allow undefined references to weak symbols - this
-+               * might have been intentional.  We should not be linking local
-+               * symbols here, so all bases should be covered.
-+               */
-+              if (unlikely(!symbol_addr && ELF_ST_BIND(sym->st_info) != STB_WEAK)) {
-+                      _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname);
-+                      _dl_exit(1);
-+              }
-+      }
-+
-+#if defined (__SUPPORT_LD_DEBUG__)
-+      old_val = *reloc_addr;
-+#endif
--  return (unsigned int) new_addr;
-+      symbol_addr += rpnt->r_addend;  /* Assume copy relocs have zero addend.  */
-+
-+      switch (reloc_type) {
-+              case R_SPARC_NONE:
-+                      break;
-+
-+#if 0 /* these dont really seem to be useful */
-+              case R_SPARC_8:
-+                      *(char *) reloc_addr = symbol_addr;
-+                      break;
-+              case R_SPARC_16:
-+                      *(short *) reloc_addr = symbol_addr;
-+                      break;
-+              case R_SPARC_DISP8:
-+                      *(char *) reloc_addr = (symbol_addr) - (Elf32_Addr) reloc_addr;
-+                      break;
-+              case R_SPARC_DISP16:
-+                      *(short *) reloc_addr = (symbol_addr) - (Elf32_Addr) reloc_addr;
-+                      break;
-+#endif
-+
-+              case R_SPARC_DISP32:
-+                      *reloc_addr = symbol_addr - (unsigned int) reloc_addr;
-+                      break;
-+
-+              case R_SPARC_LO10:
-+                      if (!symbol_addr)
-+                              symbol_addr = tpnt->loadaddr + rpnt->r_addend;
-+                      else
-+                              symbol_addr += rpnt->r_addend;
-+                      *reloc_addr = (*reloc_addr & ~0x3ff)|(symbol_addr & 0x3ff);
-+                      break;
-+
-+              case R_SPARC_GLOB_DAT:
-+              case R_SPARC_32:
-+                      *reloc_addr = symbol_addr;
-+                      break;
-+
-+              case R_SPARC_JMP_SLOT:
-+/*
-+value = symbol_addr;
-+value += reloc->r_addend;
-+disp = value - reloc_addr;
-+reloc_addr[1] = OPCODE_JMP_G1 | (value & 0x3ff);
-+reloc_addr[0] = OPCODE_SETHI_G1 | (value >> 10);
-+                      reloc_addr[1] = OPCODE_JMP_G1 | ((symbol_addr-(Elf32_Addr)reloc_addr) & 0x3ff);
-+                      reloc_addr[0] = OPCODE_SETHI_G1 | ((symbol_addr-(Elf32_Addr)reloc_addr) >> 10);
-+*/
-+                      reloc_addr[1] = 0x03000000 | ((symbol_addr >> 10) & 0x3fffff);
-+                      reloc_addr[2] = 0x81c06000 | (symbol_addr & 0x3ff);
-+                      break;
-+
-+              case R_SPARC_RELATIVE:
-+                      *reloc_addr += tpnt->loadaddr + rpnt->r_addend;
-+                      break;
-+
-+              case R_SPARC_WDISP30:
-+                      *reloc_addr = (*reloc_addr & 0xc0000000)|
-+                               ((symbol_addr - (unsigned int) reloc_addr) >> 2);
-+                      break;
-+
-+              case R_SPARC_HI22:
-+                      if (!symbol_addr)
-+                              symbol_addr = tpnt->loadaddr + rpnt->r_addend;
-+                      else
-+                              symbol_addr += rpnt->r_addend;
-+                      *reloc_addr = (*reloc_addr & 0xffc00000) | (symbol_addr >> 10);
-+                      break;
-+
-+              case R_SPARC_COPY:
-+                      if (symbol_addr) {
-+#if defined (__SUPPORT_LD_DEBUG__)
-+                              if (_dl_debug_move)
-+                                      _dl_dprintf(_dl_debug_file,
-+                                                  "\t%s move %d bytes from %x to %x\n",
-+                                                  symname, sym->st_size,
-+                                                  symbol_addr, reloc_addr);
-+#endif
-+
-+                              _dl_memcpy((char *)reloc_addr,
-+                                         (char *)symbol_addr,
-+                                         sym->st_size);
-+                      } else
-+                              _dl_dprintf(_dl_debug_file, "no symbol_addr to copy !?\n");
-+                      break;
-+              default:
-+                      return -1;      /* Calls _dl_exit(1). */
-+      }
-+
-+#if defined (__SUPPORT_LD_DEBUG__)
-+      if (_dl_debug_reloc && _dl_debug_detail)
-+              _dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x\n",
-+                          old_val, *reloc_addr, reloc_addr);
-+#endif
-+
-+      return 0;
-+}
-+
-+#undef __SPARC_LAZY_RELOC_WORKS
-+#ifdef __SPARC_LAZY_RELOC_WORKS
-+static int
-+_dl_do_lazy_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
-+                ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab)
-+{
-+      int reloc_type;
-+      int symtab_index;
-+      ElfW(Addr) *reloc_addr;
-+#if defined (__SUPPORT_LD_DEBUG__)
-+      ElfW(Addr) old_val;
-+#endif
-+
-+      (void)scope;
-+      symtab_index = ELF_R_SYM(rpnt->r_info);
-+      (void)strtab;
-+
-+      reloc_addr = (ElfW(Addr)*)(tpnt->loadaddr + rpnt->r_offset);
-+      reloc_type = ELF_R_TYPE(rpnt->r_info);
-+
-+#if defined (__SUPPORT_LD_DEBUG__)
-+      old_val = *reloc_addr;
-+#endif
-+
-+      switch (reloc_type) {
-+              case R_SPARC_NONE:
-+                      break;
-+              case R_SPARC_JMP_SLOT:
-+                      break;
-+              default:
-+                      _dl_exit(1);
-+      }
-+
-+#if defined (__SUPPORT_LD_DEBUG__)
-+      if (_dl_debug_reloc && _dl_debug_detail)
-+              _dl_dprintf(_dl_debug_file, "\tpatched_lazy: %x ==> %x @ %x\n",
-+                          old_val, *reloc_addr, reloc_addr);
-+#endif
-+
-+      return 0;
- }
-+#endif
--void _dl_parse_lazy_relocation_information(struct dyn_elf *arg_rpnt,
--      unsigned long rel_addr, unsigned long rel_size)
--{
--  int i;
--  char * strtab;
--  int reloc_type;
--  int symtab_index;
--  Elf32_Sym * symtab;
--  Elf32_Rela * rpnt;
--  unsigned int * reloc_addr;
--  struct elf_resolve * tpnt = arg_rpnt->dyn;
--
--  /* Now parse the relocation information */
--  rpnt = (Elf32_Rela *)rel_addr;
--
--  symtab =  (Elf32_Sym *)tpnt->dynamic_info[DT_SYMTAB];
--  strtab = ( char *)tpnt->dynamic_info[DT_STRTAB];
--
--  for(i=0; i< rel_size; i += sizeof(Elf32_Rela), rpnt++){
--    reloc_addr = (int *) (tpnt->loadaddr + (int)rpnt->r_offset);
--    reloc_type = ELF32_R_TYPE(rpnt->r_info);
--    symtab_index = ELF32_R_SYM(rpnt->r_info);
--
--    switch(reloc_type){
--    case R_SPARC_NONE:
--      break;
--    case R_SPARC_JMP_SLOT:
--      break;
--    default:
--      _dl_dprintf(2, "%s: (LAZY) can't handle reloc type ", _dl_progname);
--#if defined (__SUPPORT_LD_DEBUG__)
--      _dl_dprintf(2, "%s ", _dl_reltypes_tab[reloc_type]);
--#endif
--      if(symtab_index) _dl_dprintf(2, "'%s'\n",
--                                strtab + symtab[symtab_index].st_name);
--      _dl_exit(33);
--    };
--  };
--}
--
--int _dl_parse_relocation_information(struct dyn_elf *arg_rpnt,
--      unsigned long rel_addr, unsigned long rel_size)
--{
--  int i;
--  char * strtab;
--  int reloc_type;
--  int goof = 0;
--  Elf32_Sym * symtab;
--  Elf32_Rela * rpnt;
--  unsigned int * reloc_addr;
--  unsigned int symbol_addr;
--  int symtab_index;
--  struct elf_resolve * tpnt = arg_rpnt->dyn;
--  /* Now parse the relocation information */
--
--  rpnt = (Elf32_Rela *)rel_addr;
--
--  symtab =  (Elf32_Sym *)tpnt->dynamic_info[DT_SYMTAB];
--  strtab = ( char *)tpnt->dynamic_info[DT_STRTAB];
--
--  for(i=0; i< rel_size; i+= sizeof(Elf32_Rela), rpnt++){
--    reloc_addr = (int *) (tpnt->loadaddr + (int)rpnt->r_offset);
--    reloc_type = ELF32_R_TYPE(rpnt->r_info);
--    symtab_index = ELF32_R_SYM(rpnt->r_info);
--    symbol_addr = 0;
--
--    if(symtab_index) {
--
--      symbol_addr = (unsigned int)
--      _dl_find_hash(strtab + symtab[symtab_index].st_name,
--                    tpnt->symbol_scope, tpnt, elf_machine_type_class(reloc_type));
--
--      if(!symbol_addr &&
--       ELF32_ST_BIND(symtab [symtab_index].st_info) != STB_WEAK) {
--                      _dl_dprintf (2, "%s: can't resolve symbol '%s'\n",
--                                   _dl_progname, strtab + symtab[symtab_index].st_name);
--                      _dl_exit (1);
--      };
--    };
--    switch(reloc_type){
--    case R_SPARC_NONE:
--      break;
--    case R_SPARC_32:
--      *reloc_addr = symbol_addr + rpnt->r_addend;
--      break;
--    case R_SPARC_DISP32:
--      *reloc_addr = symbol_addr + rpnt->r_addend - (unsigned int) reloc_addr;
--      break;
--    case R_SPARC_GLOB_DAT:
--      *reloc_addr = symbol_addr + rpnt->r_addend;
--      break;
--    case R_SPARC_JMP_SLOT:
--      reloc_addr[1] = 0x03000000 | ((symbol_addr >> 10) & 0x3fffff);
--      reloc_addr[2] = 0x81c06000 | (symbol_addr & 0x3ff);
--      break;
--    case R_SPARC_RELATIVE:
--      *reloc_addr += (unsigned int) tpnt->loadaddr + rpnt->r_addend;
--      break;
--    case R_SPARC_HI22:
--      if (!symbol_addr)
--        symbol_addr = tpnt->loadaddr + rpnt->r_addend;
--      else
--      symbol_addr += rpnt->r_addend;
--      *reloc_addr = (*reloc_addr & 0xffc00000)|(symbol_addr >> 10);
--      break;
--    case R_SPARC_LO10:
--      if (!symbol_addr)
--        symbol_addr = tpnt->loadaddr + rpnt->r_addend;
--      else
--      symbol_addr += rpnt->r_addend;
--      *reloc_addr = (*reloc_addr & ~0x3ff)|(symbol_addr & 0x3ff);
--      break;
--    case R_SPARC_WDISP30:
--      *reloc_addr = (*reloc_addr & 0xc0000000)|
--      ((symbol_addr - (unsigned int) reloc_addr) >> 2);
--      break;
--    case R_SPARC_COPY:
--      _dl_memcpy((void *) reloc_addr, (void *) symbol_addr, symtab[symtab_index].st_size);
--      break;
--    default:
--      _dl_dprintf(2, "%s: can't handle reloc type ", _dl_progname);
--#if defined (__SUPPORT_LD_DEBUG__)
--      _dl_dprintf(2, "%s ", _dl_reltypes_tab[reloc_type]);
--#endif
--      if (symtab_index)
--      _dl_dprintf(2, "'%s'\n", strtab + symtab[symtab_index].st_name);
--      _dl_exit(34);
--    };
-+void
-+_dl_parse_lazy_relocation_information(struct dyn_elf *rpnt,
-+                                    unsigned long rel_addr,
-+                                    unsigned long rel_size)
-+{
-+#ifdef __SPARC_LAZY_RELOC_WORKS
-+      (void)_dl_parse(rpnt->dyn, NULL, rel_addr, rel_size, _dl_do_lazy_reloc);
-+#else
-+      _dl_parse_relocation_information(rpnt, rel_addr, rel_size);
-+#endif
-+}
--  };
--  return goof;
-+int
-+_dl_parse_relocation_information(struct dyn_elf *rpnt,
-+                               unsigned long rel_addr,
-+                               unsigned long rel_size)
-+{
-+      return _dl_parse(rpnt->dyn, rpnt->dyn->symbol_scope, rel_addr, rel_size, _dl_do_reloc);
- }
-diff -urN uClibc-0.9.28.orig/ldso/ldso/x86_64/dl-debug.h uClibc-0.9.28/ldso/ldso/x86_64/dl-debug.h
---- uClibc-0.9.28.orig/ldso/ldso/x86_64/dl-debug.h     2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/x86_64/dl-debug.h  2006-04-28 00:14:35.000000000 -0600
-@@ -30,7 +30,10 @@
-  */
- static const char *_dl_reltypes_tab[] = {
--      [0] "R_X86_64_NONE",     "R_X86_64_64",       "R_X86_64_PC32",     "R_X86_64_GOT32",
--      [4] "R_X86_64_PLT32",    "R_X86_64_COPY",     "R_X86_64_GLOB_DAT", "R_X86_64_JUMP_SLOT",
--      [8] "R_X86_64_RELATIVE", "R_X86_64_GOTPCREL", "R_X86_64_32"
-+      [ 0] "R_X86_64_NONE",     "R_X86_64_64",       "R_X86_64_PC32",     "R_X86_64_GOT32",
-+      [ 4] "R_X86_64_PLT32",    "R_X86_64_COPY",     "R_X86_64_GLOB_DAT", "R_X86_64_JUMP_SLOT",
-+      [ 8] "R_X86_64_RELATIVE", "R_X86_64_GOTPCREL", "R_X86_64_32",       "R_X86_64_32S",
-+      [12] "R_X86_64_16",       "R_X86_64_PC16",     "R_X86_64_8",        "R_X86_64_PC8",
-+      [16] "R_X86_64_DTPMOD64", "R_X86_64_DTPOFF64", "R_X86_64_TPOFF64",  "R_X86_64_TLSGD",
-+      [20] "R_X86_64_TLSLD",    "R_X86_64_DTPOFF32", "R_X86_64_GOTTPOFF", "R_X86_64_TPOFF32"
- };
-diff -urN uClibc-0.9.28.orig/ldso/ldso/x86_64/dl-startup.h uClibc-0.9.28/ldso/ldso/x86_64/dl-startup.h
---- uClibc-0.9.28.orig/ldso/ldso/x86_64/dl-startup.h   2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/x86_64/dl-startup.h        2006-04-28 00:14:35.000000000 -0600
-@@ -6,7 +6,7 @@
-  *
-  * Parts taken from glibc/sysdeps/x86_64/dl-machine.h
-  */
--asm(
-+__asm__ (
-       "       .text\n"
-       "       .align 16\n"
-       "       .global _start\n"
-@@ -42,10 +42,10 @@
- /* Handle relocation of the symbols in the dynamic loader. */
- static __always_inline
--void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, unsigned long *reloc_addr,
--      unsigned long symbol_addr, unsigned long load_addr, Elf64_Sym *sym)
-+void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, ElfW(Addr) *reloc_addr,
-+      ElfW(Addr) symbol_addr, ElfW(Addr) load_addr, ElfW(Sym) *sym)
- {
--      switch (ELF64_R_TYPE(rpnt->r_info)) {
-+      switch (ELF_R_TYPE(rpnt->r_info)) {
-               case R_X86_64_GLOB_DAT:
-               case R_X86_64_JUMP_SLOT:
-                       *reloc_addr = symbol_addr + rpnt->r_addend;
-@@ -63,8 +63,3 @@
-                       _dl_exit(1);
-       }
- }
--
--/* Transfer control to the user's application, once the dynamic loader is
-- * done.  This routine has to exit the current function, then call the
-- * _dl_elf_main function.  */
--#define START() return _dl_elf_main
-diff -urN uClibc-0.9.28.orig/ldso/ldso/x86_64/dl-syscalls.h uClibc-0.9.28/ldso/ldso/x86_64/dl-syscalls.h
---- uClibc-0.9.28.orig/ldso/ldso/x86_64/dl-syscalls.h  2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/x86_64/dl-syscalls.h       2006-05-02 13:39:17.000000000 -0600
-@@ -1,7 +1,8 @@
- /* We can't use the real errno in ldso, since it has not yet
-  * been dynamicly linked in yet. */
-+#define __UCLIBC_MMAP_HAS_6_ARGS__
-+
-+#include "sys/syscall.h"
- extern int _dl_errno;
-+#undef __set_errno
- #define __set_errno(X) {(_dl_errno) = (X);}
--#include "sys/syscall.h"
--
--#define MMAP_HAS_6_ARGS
-diff -urN uClibc-0.9.28.orig/ldso/ldso/x86_64/dl-sysdep.h uClibc-0.9.28/ldso/ldso/x86_64/dl-sysdep.h
---- uClibc-0.9.28.orig/ldso/ldso/x86_64/dl-sysdep.h    2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/x86_64/dl-sysdep.h 2006-04-28 00:14:35.000000000 -0600
-@@ -41,8 +41,6 @@
- struct elf_resolve;
- extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
--#define do_rem(result, n, base) ((result) = (n) % (base))
--
- /* 4096 bytes alignment */
- #define PAGE_ALIGN 0xfffff000
- #define ADDR_ALIGN 0xfff
-@@ -90,7 +88,7 @@
-      and compare it with the current value that we can get via
-      an RIP relative addressing mode.  */
--  asm ("movq 1f(%%rip), %1\n"
-+  __asm__ ("movq 1f(%%rip), %1\n"
-        "0:\tleaq _dl_start(%%rip), %0\n\t"
-        "subq %1, %0\n\t"
-        ".section\t.data\n"
-diff -urN uClibc-0.9.28.orig/ldso/ldso/x86_64/elfinterp.c uClibc-0.9.28/ldso/ldso/x86_64/elfinterp.c
---- uClibc-0.9.28.orig/ldso/ldso/x86_64/elfinterp.c    2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/ldso/x86_64/elfinterp.c 2006-04-28 00:14:35.000000000 -0600
-@@ -165,6 +165,7 @@
-       int reloc_type;
-       int symtab_index;
-       char *symname;
-+      ElfW(Sym) *sym;
-       ElfW(Addr) *reloc_addr;
-       ElfW(Addr) symbol_addr;
- #if defined (__SUPPORT_LD_DEBUG__)
-@@ -174,8 +175,9 @@
-       reloc_addr = (ElfW(Addr)*)(tpnt->loadaddr + (unsigned long)rpnt->r_offset);
-       reloc_type = ELF_R_TYPE(rpnt->r_info);
-       symtab_index = ELF_R_SYM(rpnt->r_info);
-+      sym = &symtab[symtab_index];
-       symbol_addr = 0;
--      symname = strtab + symtab[symtab_index].st_name;
-+      symname = strtab + sym->st_name;
-       if (symtab_index) {
-               symbol_addr = (ElfW(Addr))_dl_find_hash(symname, scope, tpnt,
-@@ -185,7 +187,7 @@
-                * might have been intentional.  We should not be linking local
-                * symbols here, so all bases should be covered.
-                */
--              if (unlikely(!symbol_addr && ELF_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK)) {
-+              if (unlikely(!symbol_addr && ELF_ST_BIND(sym->st_info) != STB_WEAK)) {
-                       _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname);
-                       _dl_exit(1);
-               };
-@@ -209,7 +211,7 @@
-               case R_X86_64_GLOB_DAT:
-               case R_X86_64_JUMP_SLOT:
--                      *reloc_addr = symbol_addr;
-+                      *reloc_addr = symbol_addr + rpnt->r_addend;
-                       break;
-               /* handled by elf_machine_relative()
-@@ -217,33 +219,33 @@
-                       *reloc_addr = map->l_addr + rpnt->r_addend;
-                       break;
-               */
--#if 0
-               case R_X86_64_DTPMOD64:
-+                      *reloc_addr = 1;
-                       break;
-               case R_X86_64_DTPOFF64:
--                      *reloc_addr = symbol_addr + rpnt->r_addend;
-+                      *reloc_addr = sym->st_value + rpnt->r_addend;
-                       break;
-               case R_X86_64_TPOFF64:
--                      *reloc_addr = symbol_addr + rpnt->r_addend;
-+                      *reloc_addr = sym->st_value + rpnt->r_addend - symbol_addr;
-                       break;
-               case R_X86_64_32:
--                      *reloc_addr = symbol_addr + rpnt->r_addend;
-+                      *(unsigned int *) reloc_addr = symbol_addr + rpnt->r_addend;
-+                      /* XXX: should check for overflow eh ? */
-                       break;
--#endif
-               case R_X86_64_COPY:
-                       if (symbol_addr) {
- #if defined (__SUPPORT_LD_DEBUG__)
-                               if (_dl_debug_move)
-                                       _dl_dprintf(_dl_debug_file,
-                                                   "\t%s move %d bytes from %x to %x\n",
--                                                  symname, symtab[symtab_index].st_size,
-+                                                  symname, sym->st_size,
-                                                   symbol_addr, reloc_addr);
- #endif
-                               _dl_memcpy((char *)reloc_addr,
-                                          (char *)symbol_addr,
--                                         symtab[symtab_index].st_size);
-+                                         sym->st_size);
-                       } else
-                               _dl_dprintf(_dl_debug_file, "no symbol_addr to copy !?\n");
-                       break;
-@@ -261,7 +263,6 @@
-       return 0;
- }
--#if 0
- static int
- _dl_do_lazy_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
-                 ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab)
-@@ -288,7 +289,7 @@
-               case R_X86_64_NONE:
-                       break;
-               case R_X86_64_JUMP_SLOT:
--                      *reloc_addr = tpnt->loadaddr + symtab[symtab_index].st_value;
-+                      *reloc_addr += (unsigned long)tpnt->loadaddr;
-                       break;
-               default:
-                       _dl_exit(1);
-@@ -302,17 +303,13 @@
-       return 0;
- }
--#endif
- void
- _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt,
-                                     unsigned long rel_addr,
-                                     unsigned long rel_size)
- {
--      _dl_parse_relocation_information(rpnt, rel_addr, rel_size);
--/*    jump slot isnt working
-       (void)_dl_parse(rpnt->dyn, NULL, rel_addr, rel_size, _dl_do_lazy_reloc);
--*/
- }
- int
-diff -urN uClibc-0.9.28.orig/ldso/ldso/x86_64/resolve.S uClibc-0.9.28/ldso/ldso/x86_64/resolve.S
---- uClibc-0.9.28.orig/ldso/ldso/x86_64/resolve.S      1969-12-31 17:00:00.000000000 -0700
-+++ uClibc-0.9.28/ldso/ldso/x86_64/resolve.S   2006-04-28 00:14:35.000000000 -0600
-@@ -0,0 +1,63 @@
-+/*
-+ * This function is _not_ called directly.  It is jumped to (so no return
-+ * address is on the stack) when attempting to use a symbol that has not yet
-+ * been resolved.  The first time a jump symbol (such as a function call inside
-+ * a shared library) is used (before it gets resolved) it will jump here to
-+ * _dl_linux_resolve.  When we get called the stack looks like this:
-+ *    reloc_entry
-+ *    tpnt
-+ *
-+ * This function saves all the registers, puts a copy of reloc_entry and tpnt
-+ * on the stack (as function arguments) then make the function call
-+ * _dl_linux_resolver(tpnt, reloc_entry).  _dl_linux_resolver() figures out
-+ * where the jump symbol is _really_ supposed to have jumped to and returns
-+ * that to us.  Once we have that, we overwrite tpnt with this fixed up
-+ * address. We then clean up after ourselves, put all the registers back how we
-+ * found them, then we jump to where the fixed up address, which is where the
-+ * jump symbol that got us here really wanted to jump to in the first place.
-+ * found them, then we jump to the fixed up address, which is where the jump
-+ * symbol that got us here really wanted to jump to in the first place.
-+ *  -Erik Andersen
-+ */
-+
-+/* more info taken from glibc/sysdeps/x86_64/dl-trampoline.S */
-+
-+.text
-+
-+.global _dl_linux_resolve
-+.type   _dl_linux_resolve,%function
-+.align 16
-+
-+_dl_linux_resolve:
-+      subq $56,%rsp
-+      /* Preserve registers otherwise clobbered. */
-+      movq %rax,   (%rsp)
-+      movq %rcx,  8(%rsp)
-+      movq %rdx, 16(%rsp)
-+      movq %rsi, 24(%rsp)
-+      movq %rdi, 32(%rsp)
-+      movq %r8,  40(%rsp)
-+      movq %r9,  48(%rsp)
-+
-+      movq 64(%rsp), %rsi  /* Copy args pushed by PLT in register. */
-+      movq %rsi, %r11      /* Multiply by 24 */
-+      addq %r11, %rsi
-+      addq %r11, %rsi
-+      shlq $3, %rsi
-+      movq 56(%rsp), %rdi  /* %rdi: link_map, %rsi: reloc_offset */
-+      call _dl_linux_resolver       /* Call resolver. */
-+      movq %rax, %r11      /* Save return value */
-+
-+      /* Get register content back. */
-+      movq 48(%rsp), %r9
-+      movq 40(%rsp), %r8
-+      movq 32(%rsp), %rdi
-+      movq 24(%rsp), %rsi
-+      movq 16(%rsp), %rdx
-+      movq  8(%rsp), %rcx
-+      movq   (%rsp), %rax
-+
-+      addq $72, %rsp       /* Adjust stack(PLT did 2 pushes) */
-+      jmp *%r11            /* Jump to function address. */
-+
-+.size _dl_linux_resolve,.-_dl_linux_resolve
-diff -urN uClibc-0.9.28.orig/ldso/libdl/Makefile uClibc-0.9.28/ldso/libdl/Makefile
---- uClibc-0.9.28.orig/ldso/libdl/Makefile     2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/libdl/Makefile  2006-04-28 00:14:35.000000000 -0600
-@@ -29,12 +29,14 @@
- endif
- XXFLAGS+= $(XARCH_CFLAGS) $(CPU_CFLAGS) \
-       -DUCLIBC_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" \
--      -fno-builtin -nostdinc -D_LIBC -I$(TOPDIR)ldso/include -I$(TOPDIR)ldso/ldso -I. -I$(TOPDIR)include
-+      -fno-builtin -nostdinc -D_LIBC \
-+      -DLDSO_ELFINTERP=\"$(TARGET_ARCH)/elfinterp.c\" \
-+      -I$(TOPDIR)ldso/ldso/$(TARGET_ARCH) -I$(TOPDIR)ldso/include -I$(TOPDIR)ldso/ldso -I$(TOPDIR)include
- XXFLAGS+=-isystem $(shell $(CC) -print-file-name=include)
- XXFLAGS_NOPIC:=$(XXFLAGS)
- ifeq ($(DOPIC),y)
--    XXFLAGS += $(PICFLAG) -D__LIBDL_SHARED__
-+    XXFLAGS += $(PICFLAG) -DSHARED
- endif
- ifeq ($(strip $(SUPPORT_LD_DEBUG)),y)
- XXFLAGS+=-D__SUPPORT_LD_DEBUG__
-diff -urN uClibc-0.9.28.orig/ldso/libdl/libdl.c uClibc-0.9.28/ldso/libdl/libdl.c
---- uClibc-0.9.28.orig/ldso/libdl/libdl.c      2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/ldso/libdl/libdl.c   2006-04-28 00:14:35.000000000 -0600
-@@ -3,7 +3,7 @@
-  * Program to load an ELF binary on a linux system, and run it
-  * after resolving ELF shared library symbols
-  *
-- * Copyright (C) 2000-2004 by Erik Andersen <andersen@codepoet.org>
-+ * Copyright (C) 2000-2006 by Erik Andersen <andersen@uclibc.org>
-  * Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald,
-  *                            David Engel, Hongjiu Lu and Mitch D'Souza
-  *
-@@ -30,12 +30,12 @@
-  */
--#define _GNU_SOURCE
-+#define _GNU_SOURCE
- #include <ldso.h>
- #include <stdio.h>
--#if defined (__LIBDL_SHARED__)
-+#ifdef SHARED
- /* When libdl is loaded as a shared library, we need to load in
-  * and use a pile of symbols from ldso... */
-@@ -52,6 +51,8 @@
- extern struct r_debug *_dl_debug_addr;
- extern unsigned long _dl_error_number;
- extern void *(*_dl_malloc_function)(size_t);
-+extern void _dl_run_init_array(struct elf_resolve *);
-+extern void _dl_run_fini_array(struct elf_resolve *);
- #ifdef __LDSO_CACHE_SUPPORT__
- int _dl_map_cache(void);
- int _dl_unmap_cache(void);
-@@ -64,7 +65,7 @@
- #endif
--#else /* __LIBDL_SHARED__ */
-+#else /* SHARED */
- /* When libdl is linked as a static library, we need to replace all
-  * the symbols that otherwise would have been loaded in from ldso... */
-@@ -81,11 +82,11 @@
- struct r_debug *_dl_debug_addr = NULL;
- #define _dl_malloc malloc
- #include "../ldso/dl-debug.c"
--#include "dl-progname.h"
-+#include LDSO_ELFINTERP
- #include "../ldso/dl-hash.c"
- #define _dl_trace_loaded_objects    0
- #include "../ldso/dl-elf.c"
--#endif /* __LIBDL_SHARED__ */
-+#endif /* SHARED */
- #ifdef __SUPPORT_LD_DEBUG__
- # define _dl_if_debug_print(fmt, args...) \
-@@ -126,7 +127,8 @@
-       "Unable to resolve symbol"
- };
--void __attribute__ ((destructor)) dl_cleanup(void)
-+void dl_cleanup(void) __attribute__ ((destructor));
-+void dl_cleanup(void)
- {
-       struct dyn_elf *d;
-       for (d = _dl_handles; d; d = d->next_handle) {
-@@ -138,13 +140,12 @@
- {
-       struct elf_resolve *tpnt, *tfrom;
-       struct dyn_elf *dyn_chain, *rpnt = NULL, *dyn_ptr, *relro_ptr, *handle;
--      struct dyn_elf *dpnt;
-       ElfW(Addr) from;
-       struct elf_resolve *tpnt1;
-       void (*dl_brk) (void);
-       int now_flag;
-       struct init_fini_list *tmp, *runp, *runp2, *dep_list;
--      int nlist, i;
-+      unsigned int nlist, i;
-       struct elf_resolve **init_fini_list;
-       /* A bit of sanity checking... */
-@@ -169,12 +170,15 @@
-        * the application.  Thus this may go away at some time
-        * in the future.
-        */
--      tfrom = NULL;
--      for (dpnt = _dl_symbol_tables; dpnt; dpnt = dpnt->next) {
--              tpnt = dpnt->dyn;
--              if (tpnt->loadaddr < from
--                              && (tfrom == NULL || tfrom->loadaddr < tpnt->loadaddr))
--                      tfrom = tpnt;
-+      {
-+              struct dyn_elf *dpnt;
-+              tfrom = NULL;
-+              for (dpnt = _dl_symbol_tables; dpnt; dpnt = dpnt->next) {
-+                      tpnt = dpnt->dyn;
-+                      if (tpnt->loadaddr < from
-+                                      && (tfrom == NULL || tfrom->loadaddr < tpnt->loadaddr))
-+                              tfrom = tpnt;
-+              }
-       }
-       for(rpnt = _dl_symbol_tables; rpnt && rpnt->next; rpnt=rpnt->next);
-@@ -233,11 +237,8 @@
-               runp->tpnt->init_fini = NULL; /* clear any previous dependcies */
-               for (dpnt = (ElfW(Dyn) *) runp->tpnt->dynamic_addr; dpnt->d_tag; dpnt++) {
-                       if (dpnt->d_tag == DT_NEEDED) {
--                              char *name;
--
-                               lpntstr = (char*) (runp->tpnt->dynamic_info[DT_STRTAB] +
-                                               dpnt->d_un.d_val);
--                              name = _dl_get_last_path_component(lpntstr);
-                               _dl_if_debug_print("Trying to load '%s', needed by '%s'\n",
-                                               lpntstr, runp->tpnt->libname);
-                               tpnt1 = _dl_load_shared_library(0, &rpnt, runp->tpnt, lpntstr, 0);
-@@ -297,14 +298,14 @@
-       }
-       /* Sort the INIT/FINI list in dependency order. */
-       for (runp2 = dep_list; runp2; runp2 = runp2->next) {
--              int j, k;
-+              unsigned int j, k;
-               for (j = 0; init_fini_list[j] != runp2->tpnt; ++j)
-                       /* Empty */;
-               for (k = j + 1; k < nlist; ++k) {
--                      struct init_fini_list *runp = init_fini_list[k]->init_fini;
-+                      struct init_fini_list *ele = init_fini_list[k]->init_fini;
--                      for (; runp; runp = runp->next) {
--                              if (runp->tpnt == runp2->tpnt) {
-+                      for (; ele; ele = ele->next) {
-+                              if (ele->tpnt == runp2->tpnt) {
-                                       struct elf_resolve *here = init_fini_list[k];
-                                       _dl_if_debug_print("Move %s from pos %d to %d in INIT/FINI list.\n", here->libname, k, j);
-                                       for (i = (k - j); i; --i)
-@@ -367,7 +368,7 @@
-               }
-       }
--#if defined (__LIBDL_SHARED__)
-+#ifdef SHARED
-       /* Run the ctors and setup the dtors */
-       for (i = nlist; i; --i) {
-               tpnt = init_fini_list[i-1];
-@@ -384,8 +385,11 @@
-                               (*dl_elf_func) ();
-                       }
-               }
-+
-+              _dl_run_init_array(tpnt);
-       }
--#endif
-+#endif /* SHARED */
-+
-       _dl_unmap_cache();
-       return (void *) dyn_chain;
-@@ -450,9 +454,16 @@
-       return ret;
- }
-+#if 0
-+void *dlvsym(void *vhandle, const char *name, const char *version)
-+{
-+      return dlsym(vhandle, name);
-+}
-+#endif
-+
- static int do_dlclose(void *vhandle, int need_fini)
- {
--      struct dyn_elf *rpnt, *rpnt1;
-+      struct dyn_elf *rpnt, *rpnt1, *rpnt1_tmp;
-       struct init_fini_list *runp, *tmp;
-       ElfW(Phdr) *ppnt;
-       struct elf_resolve *tpnt, *run_tpnt;
-@@ -460,7 +471,7 @@
-       void (*dl_brk) (void);
-       struct dyn_elf *handle;
-       unsigned int end;
--      int i = 0, j;
-+      unsigned int i, j;
-       handle = (struct dyn_elf *) vhandle;
-       if (handle == _dl_symbol_tables)
-@@ -491,13 +502,21 @@
-       for (j = 0; j < handle->init_fini.nlist; ++j) {
-               tpnt = handle->init_fini.init_fini[j];
-               if (--tpnt->usage_count == 0) {
--                      if (tpnt->dynamic_info[DT_FINI] && need_fini &&
-+                      if ((tpnt->dynamic_info[DT_FINI]
-+                           || tpnt->dynamic_info[DT_FINI_ARRAY])
-+                          && need_fini &&
-                           !(tpnt->init_flag & FINI_FUNCS_CALLED)) {
-                               tpnt->init_flag |= FINI_FUNCS_CALLED;
--                              dl_elf_fini = (int (*)(void)) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI]);
--                              _dl_if_debug_print("running dtors for library %s at '%p'\n",
--                                              tpnt->libname, dl_elf_fini);
--                              (*dl_elf_fini) ();
-+#ifdef SHARED
-+                              _dl_run_fini_array(tpnt);
-+#endif
-+
-+                              if (tpnt->dynamic_info[DT_FINI]) {
-+                                      dl_elf_fini = (int (*)(void)) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI]);
-+                                      _dl_if_debug_print("running dtors for library %s at '%p'\n",
-+                                                      tpnt->libname, dl_elf_fini);
-+                                      (*dl_elf_fini) ();
-+                              }
-                       }
-                       _dl_if_debug_print("unmapping: %s\n", tpnt->libname);
-@@ -541,8 +560,9 @@
-                                       for (rpnt1 = _dl_symbol_tables; rpnt1->next; rpnt1 = rpnt1->next) {
-                                               if (rpnt1->next->dyn == tpnt) {
-                                                       _dl_if_debug_print("removing symbol_tables: %s\n", tpnt->libname);
-+                                                      rpnt1_tmp = rpnt1->next->next;
-                                                       free(rpnt1->next);
--                                                      rpnt1->next = rpnt1->next->next;
-+                                                      rpnt1->next = rpnt1_tmp;
-                                                       if (rpnt1->next)
-                                                               rpnt1->next->prev = rpnt1;
-                                                       break;
-@@ -588,8 +608,9 @@
- }
- /*
-- * Dump information to stderrr about the current loaded modules
-+ * Dump information to stderr about the current loaded modules
-  */
-+#if 1
- static char *type[] = { "Lib", "Exe", "Int", "Mod" };
- int dlinfo(void)
-@@ -660,16 +681,14 @@
-       {
-               char *strtab;
-               ElfW(Sym) *symtab;
--              int hn, si;
--              int sf;
--              int sn = 0;
-+              unsigned int hn, si, sn, sf;
-               ElfW(Addr) sa;
-               sa = 0;
-               symtab = (ElfW(Sym) *) (pelf->dynamic_info[DT_SYMTAB]);
-               strtab = (char *) (pelf->dynamic_info[DT_STRTAB]);
--              sf = 0;
-+              sf = sn = 0;
-               for (hn = 0; hn < pelf->nbucket; hn++) {
-                       for (si = pelf->elf_buckets[hn]; si; si = pelf->chains[si]) {
-                               ElfW(Addr) symbol_addr;
-@@ -696,3 +715,4 @@
-               return 1;
-       }
- }
-+#endif
-diff -urN uClibc-0.9.28.orig/libc/sysdeps/linux/i386/bits/syscalls.h uClibc-0.9.28/libc/sysdeps/linux/i386/bits/syscalls.h
---- uClibc-0.9.28.orig/libc/sysdeps/linux/i386/bits/syscalls.h 2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/libc/sysdeps/linux/i386/bits/syscalls.h      2006-04-28 00:14:35.000000000 -0600
-@@ -4,17 +4,15 @@
- # error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead."
- #endif
-+#include <errno.h>
-+
- /* This includes the `__NR_<name>' syscall numbers taken from the Linux kernel
-  * header files.  It also defines the traditional `SYS_<name>' macros for older
-  * programs.  */
- #include <bits/sysnum.h>
--#ifndef __set_errno
--# define __set_errno(val) (*__errno_location ()) = (val)
--#endif
--
- /*
--   Some of the sneaky macros in the code were taken from 
-+   Some of the sneaky macros in the code were taken from
-    glibc-2.2.5/sysdeps/unix/sysv/linux/i386/sysdep.h
- */
-@@ -22,7 +20,8 @@
- /* We need some help from the assembler to generate optimal code.  We
-    define some macros here which later will be used.  */
--asm (".L__X'%ebx = 1\n\t"
-+
-+__asm__ (".L__X'%ebx = 1\n\t"
-      ".L__X'%ecx = 2\n\t"
-      ".L__X'%edx = 2\n\t"
-      ".L__X'%eax = 3\n\t"
-@@ -56,7 +55,6 @@
-      ".endif\n\t"
-      ".endm\n\t");
--
- #undef _syscall0
- #define _syscall0(type,name) \
- type name(void) \
-@@ -90,7 +88,7 @@
- type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
- { \
- return (type) (INLINE_SYSCALL(name, 4, arg1, arg2, arg3, arg4)); \
--} 
-+}
- #undef _syscall5
- #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
-@@ -100,10 +98,18 @@
- return (type) (INLINE_SYSCALL(name, 5, arg1, arg2, arg3, arg4, arg5)); \
- }
-+#undef _syscall6
-+#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
-+        type5,arg5,type6,arg6) \
-+type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, type6 arg6) \
-+{ \
-+return (type) (INLINE_SYSCALL(name, 6, arg1, arg2, arg3, arg4, arg5, arg6)); \
-+}
-+
- #define INLINE_SYSCALL(name, nr, args...) \
-   ({                                                                        \
-     unsigned int resultvar;                                                 \
--    asm volatile (                                                          \
-+    __asm__ __volatile__ (                                                          \
-     LOADARGS_##nr                                                           \
-     "movl %1, %%eax\n\t"                                                    \
-     "int $0x80\n\t"                                                         \
-@@ -125,6 +131,7 @@
- #define LOADARGS_3    LOADARGS_1
- #define LOADARGS_4    LOADARGS_1
- #define LOADARGS_5    LOADARGS_1
-+#define LOADARGS_6    LOADARGS_1 "push %%ebp ; movl %7, %%ebp\n\t"
- #define RESTOREARGS_0
- #define RESTOREARGS_1 \
-@@ -133,6 +140,7 @@
- #define RESTOREARGS_3 RESTOREARGS_1
- #define RESTOREARGS_4 RESTOREARGS_1
- #define RESTOREARGS_5 RESTOREARGS_1
-+#define RESTOREARGS_6 "pop %%ebp\n\t" RESTOREARGS_1
- #define ASMFMT_0()
- #define ASMFMT_1(arg1) \
-@@ -145,7 +153,8 @@
-       , "aD" (arg1), "c" (arg2), "d" (arg3), "S" (arg4)
- #define ASMFMT_5(arg1, arg2, arg3, arg4, arg5) \
-       , "a" (arg1), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5)
--
-+#define ASMFMT_6(arg1, arg2, arg3, arg4, arg5, arg6) \
-+      , "a" (arg1), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5), "m" (arg6)
- #endif /* __ASSEMBLER__ */
- #endif /* _BITS_SYSCALLS_H */
-diff -urN uClibc-0.9.28.orig/libc/sysdeps/linux/powerpc/bits/syscalls.h uClibc-0.9.28/libc/sysdeps/linux/powerpc/bits/syscalls.h
---- uClibc-0.9.28.orig/libc/sysdeps/linux/powerpc/bits/syscalls.h      2006-05-02 10:47:27.000000000 -0600
-+++ uClibc-0.9.28/libc/sysdeps/linux/powerpc/bits/syscalls.h   2006-04-28 00:14:35.000000000 -0600
-@@ -5,67 +5,164 @@
- # error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead."
- #endif
-+#include <errno.h>
-+
- /* This includes the `__NR_<name>' syscall numbers taken from the Linux kernel
-  * header files.  It also defines the traditional `SYS_<name>' macros for older
-  * programs.  */
- #include <bits/sysnum.h>
--
--#define __STRINGIFY(s) __STRINGIFY2 (s)
--#define __STRINGIFY2(s) #s
--
--#undef JUMPTARGET
--#ifdef __PIC__
--#define __MAKE_SYSCALL        __STRINGIFY(__uClibc_syscall@plt)
-+/* Define a macro which expands inline into the wrapper code for a system
-+   call. This use is for internal calls that do not need to handle errors
-+   normally. It will never touch errno.
-+   On powerpc a system call basically clobbers the same registers like a
-+   function call, with the exception of LR (which is needed for the
-+   "sc; bnslr+" sequence) and CR (where only CR0.SO is clobbered to signal
-+   an error return status).  */
-+
-+# undef INLINE_SYSCALL
-+#if 1
-+# define INLINE_SYSCALL(name, nr, args...)                            \
-+  ({                                                                  \
-+    INTERNAL_SYSCALL_DECL (sc_err);                                   \
-+    long int sc_ret = INTERNAL_SYSCALL (name, sc_err, nr, args);      \
-+    if (INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err))                    \
-+      {                                                                       \
-+      __set_errno (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err));          \
-+      sc_ret = -1L;                                                   \
-+      }                                                                       \
-+    sc_ret;                                                           \
-+  })
- #else
--#define __MAKE_SYSCALL        __STRINGIFY(__uClibc_syscall)
-+# define INLINE_SYSCALL(name, nr, args...)                            \
-+  ({                                                                  \
-+    INTERNAL_SYSCALL_DECL (sc_err);                                   \
-+    long int sc_ret = INTERNAL_SYSCALL (name, sc_err, nr, args);      \
-+    if (INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err))                    \
-+      {                                                                       \
-+      sc_ret = __syscall_error(INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err));\
-+      }                                                                       \
-+    sc_ret;                                                           \
-+  })
- #endif
--#define unified_syscall_body(name)                    \
--      __asm__ (                                       \
--      ".section \".text\"\n\t"                        \
--      ".align 2\n\t"                                  \
--      ".globl " __STRINGIFY(name) "\n\t"              \
--      ".type " __STRINGIFY(name) ",@function\n\t"     \
--      #name":\tli 0," __STRINGIFY(__NR_##name) "\n\t" \
--      "b " __MAKE_SYSCALL "\n\t"              \
--      ".size\t" __STRINGIFY(name) ",.""-" __STRINGIFY(name) "\n"      \
--      )
-+/* Define a macro which expands inline into the wrapper code for a system
-+   call. This use is for internal calls that do not need to handle errors
-+   normally. It will never touch errno.
-+   On powerpc a system call basically clobbers the same registers like a
-+   function call, with the exception of LR (which is needed for the
-+   "sc; bnslr+" sequence) and CR (where only CR0.SO is clobbered to signal
-+   an error return status).  */
-+
-+# undef INTERNAL_SYSCALL_DECL
-+# define INTERNAL_SYSCALL_DECL(err) long int err
-+
-+# undef INTERNAL_SYSCALL
-+# define INTERNAL_SYSCALL_NCS(name, err, nr, args...)                 \
-+  ({                                                                  \
-+    register long int r0  __asm__ ("r0");                             \
-+    register long int r3  __asm__ ("r3");                             \
-+    register long int r4  __asm__ ("r4");                             \
-+    register long int r5  __asm__ ("r5");                             \
-+    register long int r6  __asm__ ("r6");                             \
-+    register long int r7  __asm__ ("r7");                             \
-+    register long int r8  __asm__ ("r8");                             \
-+    register long int r9  __asm__ ("r9");                             \
-+    register long int r10 __asm__ ("r10");                            \
-+    register long int r11 __asm__ ("r11");                            \
-+    register long int r12 __asm__ ("r12");                            \
-+    LOADARGS_##nr(name, args);                                                \
-+    __asm__ __volatile__                                              \
-+      ("sc   \n\t"                                                    \
-+       "mfcr %0"                                                      \
-+       : "=&r" (r0),                                                  \
-+       "=&r" (r3), "=&r" (r4), "=&r" (r5),  "=&r" (r6),  "=&r" (r7),  \
-+       "=&r" (r8), "=&r" (r9), "=&r" (r10), "=&r" (r11), "=&r" (r12)  \
-+       : ASM_INPUT_##nr                                                       \
-+       : "cr0", "ctr", "memory");                                     \
-+    err = r0;                                                         \
-+    (int) r3;                                                         \
-+  })
-+# define INTERNAL_SYSCALL(name, err, nr, args...) \
-+  INTERNAL_SYSCALL_NCS (__NR_##name, err, nr, ##args)
-+
-+# undef INTERNAL_SYSCALL_ERROR_P
-+# define INTERNAL_SYSCALL_ERROR_P(val, err) \
-+  ((void) (val), __builtin_expect ((err) & (1 << 28), 0))
-+
-+# undef INTERNAL_SYSCALL_ERRNO
-+# define INTERNAL_SYSCALL_ERRNO(val, err)     (val)
-+
-+# define LOADARGS_0(name, dummy) \
-+      r0 = (long int)name
-+# define LOADARGS_1(name, __arg1) \
-+      LOADARGS_0(name, 0); \
-+      r3 = (long int)__arg1
-+# define LOADARGS_2(name, __arg1, __arg2) \
-+      LOADARGS_1(name, __arg1); \
-+      r4 = (long int)__arg2
-+# define LOADARGS_3(name, __arg1, __arg2, __arg3) \
-+      LOADARGS_2(name, __arg1, __arg2); \
-+      r5 = (long int)__arg3
-+# define LOADARGS_4(name, __arg1, __arg2, __arg3, __arg4) \
-+      LOADARGS_3(name, __arg1, __arg2, __arg3); \
-+      r6 = (long int)__arg4
-+# define LOADARGS_5(name, __arg1, __arg2, __arg3, __arg4, __arg5) \
-+      LOADARGS_4(name, __arg1, __arg2, __arg3, __arg4); \
-+      r7 = (long int)__arg5
-+# define LOADARGS_6(name, __arg1, __arg2, __arg3, __arg4, __arg5, __arg6) \
-+      LOADARGS_5(name, __arg1, __arg2, __arg3, __arg4, __arg5); \
-+      r8 = (long int)__arg6
-+
-+# define ASM_INPUT_0 "0" (r0)
-+# define ASM_INPUT_1 ASM_INPUT_0, "1" (r3)
-+# define ASM_INPUT_2 ASM_INPUT_1, "2" (r4)
-+# define ASM_INPUT_3 ASM_INPUT_2, "3" (r5)
-+# define ASM_INPUT_4 ASM_INPUT_3, "4" (r6)
-+# define ASM_INPUT_5 ASM_INPUT_4, "5" (r7)
-+# define ASM_INPUT_6 ASM_INPUT_5, "6" (r8)
- #undef _syscall0
--#define _syscall0(type,name)                          \
--type name(void);                                      \
--unified_syscall_body(name)
-+#define _syscall0(type,name) \
-+type name(void){ \
-+  return (type) INLINE_SYSCALL(name, 0); \
-+}
- #undef _syscall1
- #define _syscall1(type,name,type1,arg1) \
--type name(type1 arg1);  \
--unified_syscall_body(name)
-+type name(type1 arg1){  \
-+  return (type) INLINE_SYSCALL(name, 1, arg1); \
-+}
- #undef _syscall2
- #define _syscall2(type,name,type1,arg1,type2,arg2) \
--type name(type1 arg1, type2 arg2);      \
--unified_syscall_body(name)
-+type name(type1 arg1, type2 arg2){      \
-+  return (type) INLINE_SYSCALL(name, 2, arg1, arg2); \
-+}
- #undef _syscall3
- #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
--type name(type1 arg1, type2 arg2, type3 arg3);  \
--unified_syscall_body(name)
-+type name(type1 arg1, type2 arg2, type3 arg3){  \
-+  return (type) INLINE_SYSCALL(name, 3, arg1, arg2, arg3); \
-+}
- #undef _syscall4
- #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
--type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4);      \
--unified_syscall_body(name)
-+type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4){      \
-+  return (type) INLINE_SYSCALL(name, 4, arg1, arg2, arg3, arg4); \
-+}
- #undef _syscall5
- #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
--type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5);  \
--unified_syscall_body(name)
-+type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5){  \
-+  return (type) INLINE_SYSCALL(name, 5, arg1, arg2, arg3, arg4, arg5); \
-+}
- #undef _syscall6
- #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \
--type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6);      \
--unified_syscall_body(name)
-+type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6){      \
-+  return (type) INLINE_SYSCALL(name, 6, arg1, arg2, arg3, arg4, arg5, arg6); \
-+}
- #endif /* _BITS_SYSCALLS_H */
diff --git a/toolchain/uClibc/uClibc-0.9.28-math-endianness.patch b/toolchain/uClibc/uClibc-0.9.28-math-endianness.patch
deleted file mode 100644 (file)
index 015f795..0000000
+++ /dev/null
@@ -1,247 +0,0 @@
-Index: uclibc/libm/fp_private.h
-===================================================================
---- uclibc/libm/fp_private.h   (revision 12879)
-+++ uclibc/libm/fp_private.h   (working copy)
-@@ -70,10 +70,11 @@
- *******************************************************************************/
- #include <stdint.h>
-+#include <endian.h>
- typedef struct                   /*      Hex representation of a double.      */
-       {
--#if defined(__BIG_ENDIAN__)
-+#if (__BYTE_ORDER == __BIG_ENDIAN)
-       uint32_t high;
-       uint32_t low;
- #else
-Index: uclibc/libm/powerpc/s_ceil.c
-===================================================================
---- uclibc/libm/powerpc/s_ceil.c       (revision 12879)
-+++ uclibc/libm/powerpc/s_ceil.c       (working copy)
-@@ -21,13 +21,15 @@
- *                                                                              *
- *******************************************************************************/
-+#include <endian.h>
-+
- static const double        twoTo52  = 4503599627370496.0;
- static const unsigned long signMask = 0x80000000ul;
- typedef union
-       {
-       struct {
--#if defined(__BIG_ENDIAN__)
-+#if (__BYTE_ORDER == __BIG_ENDIAN)
-       unsigned long int hi;
-       unsigned long int lo;
- #else
-Index: uclibc/libm/powerpc/s_ldexp.c
-===================================================================
---- uclibc/libm/powerpc/s_ldexp.c      (revision 12879)
-+++ uclibc/libm/powerpc/s_ldexp.c      (working copy)
-@@ -21,11 +21,12 @@
- #include <limits.h>
- #include <math.h>
-+#include <endian.h>
- typedef union
-       {
-       struct {
--#if defined(__BIG_ENDIAN__)
-+#if (__BYTE_ORDER == __BIG_ENDIAN)
-         unsigned long int hi;
-         unsigned long int lo;
- #else
-Index: uclibc/libm/powerpc/s_rint.c
-===================================================================
---- uclibc/libm/powerpc/s_rint.c       (revision 12879)
-+++ uclibc/libm/powerpc/s_rint.c       (working copy)
-@@ -46,13 +46,14 @@
- #include <limits.h>
- #include <math.h>
-+#include <endian.h>
- #define      SET_INVALID      0x01000000UL
- typedef union
-       {
-       struct {
--#if defined(__BIG_ENDIAN__)
-+#if (__BYTE_ORDER == __BIG_ENDIAN)
-         unsigned long int hi;
-         unsigned long int lo;
- #else
-Index: uclibc/libm/powerpc/s_floor.c
-===================================================================
---- uclibc/libm/powerpc/s_floor.c      (revision 12879)
-+++ uclibc/libm/powerpc/s_floor.c      (working copy)
-@@ -21,13 +21,15 @@
- *                                                                              *
- *******************************************************************************/
-+#include <endian.h>
-+
- static const double        twoTo52  = 4503599627370496.0;
- static const unsigned long signMask = 0x80000000ul;
- typedef union
-       {
-       struct {
--#if defined(__BIG_ENDIAN__)
-+#if (__BYTE_ORDER == __BIG_ENDIAN)
-       unsigned long int hi;
-       unsigned long int lo;
- #else
-Index: uclibc/libm/powerpc/s_logb.c
-===================================================================
---- uclibc/libm/powerpc/s_logb.c       (revision 12879)
-+++ uclibc/libm/powerpc/s_logb.c       (working copy)
-@@ -32,10 +32,12 @@
- *     Standard 754.                                                            *
- *******************************************************************************/
-+#include <endian.h>
-+
- typedef union
-       {
-       struct {
--#if defined(__BIG_ENDIAN__)
-+#if (__BYTE_ORDER == __BIG_ENDIAN)
-         unsigned long int hi;
-         unsigned long int lo;
- #else
-Index: uclibc/libm/powerpc/s_frexp.c
-===================================================================
---- uclibc/libm/powerpc/s_frexp.c      (revision 12879)
-+++ uclibc/libm/powerpc/s_frexp.c      (working copy)
-@@ -21,13 +21,14 @@
- #include <limits.h>
- #include <math.h>
-+#include <endian.h>
- static const double two54 =  1.80143985094819840000e+16; /* 0x43500000, 0x00000000 */
- typedef union
-       {
-       struct {
--#if defined(__BIG_ENDIAN__)
-+#if (__BYTE_ORDER == __BIG_ENDIAN)
-         unsigned long int hi;
-         unsigned long int lo;
- #else
-Index: uclibc/libm/powerpc/s_modf.c
-===================================================================
---- uclibc/libm/powerpc/s_modf.c       (revision 12879)
-+++ uclibc/libm/powerpc/s_modf.c       (working copy)
-@@ -45,13 +45,14 @@
- #include <limits.h>
- #include <math.h>
-+#include <endian.h>
- #define      SET_INVALID      0x01000000UL
- typedef union
-       {
-       struct {
--#if defined(__BIG_ENDIAN__)
-+#if (__BYTE_ORDER == __BIG_ENDIAN)
-         unsigned long int hi;
-         unsigned long int lo;
- #else
-Index: uclibc/libm/powerpc/w_scalb.c
-===================================================================
---- uclibc/libm/powerpc/w_scalb.c      (revision 12879)
-+++ uclibc/libm/powerpc/w_scalb.c      (working copy)
-@@ -19,10 +19,12 @@
- **
- ***********************************************************************/
-+#include <endian.h>
-+
- typedef union
-       {
-       struct {
--#if defined(__BIG_ENDIAN__)
-+#if (__BYTE_ORDER == __BIG_ENDIAN)
-         unsigned long int hi;
-         unsigned long int lo;
- #else
-Index: uclibc/libc/string/sh64/strcpy.S
-===================================================================
---- uclibc/libc/string/sh64/strcpy.S   (revision 12879)
-+++ uclibc/libc/string/sh64/strcpy.S   (working copy)
-@@ -6,7 +6,9 @@
- !
- ! SH5 code Copyright 2002 SuperH Ltd.
--#ifdef __LITTLE_ENDIAN__
-+#include <endian.h>
-+
-+#if __BYTE_ORDER == __LITTLE_ENDIAN
- #define SHHI shlld
- #define SHLO shlrd
- #else
-@@ -67,7 +69,7 @@
-       add r5, r63, r4
-       addi r0, 8, r0
- shortstring:
--#ifndef __LITTLE_ENDIAN__
-+#if __BYTE_ORDER != __LITTLE_ENDIAN
-       pta/l shortstring2,tr1
-       byterev r4,r4
- #endif
-Index: uclibc/libc/string/sh64/memset.S
-===================================================================
---- uclibc/libc/string/sh64/memset.S   (revision 12879)
-+++ uclibc/libc/string/sh64/memset.S   (working copy)
-@@ -9,7 +9,9 @@
- ! Copyright 2002 SuperH Ltd.
- !
--#ifdef __LITTLE_ENDIAN__
-+#include <endian.h>
-+
-+#if __BYTE_ORDER == __LITTLE_ENDIAN
- #define SHHI shlld
- #define SHLO shlrd
- #else
-Index: uclibc/libc/sysdeps/linux/sh/bits/kernel_stat.h
-===================================================================
---- uclibc/libc/sysdeps/linux/sh/bits/kernel_stat.h    (revision 12879)
-+++ uclibc/libc/sysdeps/linux/sh/bits/kernel_stat.h    (working copy)
-@@ -30,10 +30,10 @@
- };
- struct kernel_stat64 {
--#if defined(__BIG_ENDIAN__)
-+#if (__BYTE_ORDER == __BIG_ENDIAN)
-       unsigned char   __pad0b[6];
-       unsigned short  st_dev;
--#elif defined(__LITTLE_ENDIAN__)
-+#elif (__BYTE_ORDER == __LITTLE_ENDIAN)
-       unsigned short  st_dev;
-       unsigned char   __pad0b[6];
- #else
-@@ -48,7 +48,7 @@
-       unsigned long   st_uid;
-       unsigned long   st_gid;
--#if defined(__BIG_ENDIAN__)
-+#if (__BYTE_ORDER == __BIG_ENDIAN)
-       unsigned char   __pad3b[6];
-       unsigned short  st_rdev;
- #else /* Must be little */
-@@ -60,7 +60,7 @@
-       long long       st_size;
-       unsigned long   st_blksize;
--#if defined(__BIG_ENDIAN__)
-+#if (__BYTE_ORDER == __BIG_ENDIAN)
-       unsigned long   __pad4;         /* Future possible st_blocks hi bits */
-       unsigned long   st_blocks;      /* Number 512-byte blocks allocated. */
- #else /* Must be little */
diff --git a/toolchain/uClibc/uClibc-0.9.28-mutex-cancel.patch b/toolchain/uClibc/uClibc-0.9.28-mutex-cancel.patch
deleted file mode 100644 (file)
index 5e56a73..0000000
+++ /dev/null
@@ -1,8631 +0,0 @@
-diff --git a/include/printf.h b/include/printf.h
-index 340b6cb..2dea58f 100644
---- a/include/printf.h
-+++ b/include/printf.h
-@@ -75,6 +75,7 @@ struct printf_info
-   unsigned int is_short:1;    /* h flag.  */
-   unsigned int is_long:1;     /* l flag.  */
-   unsigned int is_long_double:1;/* L flag.  */
-+  unsigned int __padding:20;/* non-gnu -- total of 32 bits on 32bit arch */
- #elif __BYTE_ORDER == __BIG_ENDIAN
-diff --git a/include/pthread.h b/include/pthread.h
-index 8c01172..cee112b 100644
---- a/include/pthread.h
-+++ b/include/pthread.h
-@@ -644,7 +644,8 @@ extern void _pthread_cleanup_pop (struct
- /* Install a cleanup handler as pthread_cleanup_push does, but also
-    saves the current cancellation type and set it to deferred cancellation.  */
--#ifdef __USE_GNU
-+/* #ifdef __USE_GNU */
-+#if defined(__USE_GNU) || defined(_LIBC)
- # define pthread_cleanup_push_defer_np(routine,arg) \
-   { struct _pthread_cleanup_buffer _buffer;                                 \
-     _pthread_cleanup_push_defer (&_buffer, (routine), (arg));
-diff --git a/libc/inet/getnetent.c b/libc/inet/getnetent.c
-index 181c5ad..659bf5d 100644
---- a/libc/inet/getnetent.c
-+++ b/libc/inet/getnetent.c
-@@ -22,18 +22,9 @@
- #include <netdb.h>
- #include <arpa/inet.h>
-+#include <bits/uClibc_mutex.h>
--#ifdef __UCLIBC_HAS_THREADS__
--#include <pthread.h>
--static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;
--# define LOCK __pthread_mutex_lock(&mylock)
--# define UNLOCK       __pthread_mutex_unlock(&mylock);
--#else
--# define LOCK
--# define UNLOCK
--#endif
--
--
-+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER);
- #define       MAXALIASES      35
- static const char NETDB[] = _PATH_NETWORKS;
-@@ -46,25 +37,25 @@ int _net_stayopen;
- void setnetent(int f)
- {
--    LOCK;
-+    __UCLIBC_MUTEX_LOCK(mylock);
-     if (netf == NULL)
--      netf = fopen(NETDB, "r" );
-+              netf = fopen(NETDB, "r" );
-     else
--      rewind(netf);
-+              rewind(netf);
-     _net_stayopen |= f;
--    UNLOCK;
-+    __UCLIBC_MUTEX_UNLOCK(mylock);
-     return;
- }
- void endnetent(void)
- {
--    LOCK;
-+    __UCLIBC_MUTEX_LOCK(mylock);
-     if (netf) {
--      fclose(netf);
--      netf = NULL;
-+              fclose(netf);
-+              netf = NULL;
-     }
-     _net_stayopen = 0;
--    UNLOCK;
-+    __UCLIBC_MUTEX_UNLOCK(mylock);
- }
- static char * any(register char *cp, char *match)
-@@ -72,10 +63,10 @@ static char * any(register char *cp, cha
-     register char *mp, c;
-     while ((c = *cp)) {
--      for (mp = match; *mp; mp++)
--          if (*mp == c)
--              return (cp);
--      cp++;
-+              for (mp = match; *mp; mp++)
-+                      if (*mp == c)
-+                              return (cp);
-+              cp++;
-     }
-     return ((char *)0);
- }
-@@ -84,59 +75,62 @@ struct netent * getnetent(void)
- {
-     char *p;
-     register char *cp, **q;
-+      struct netent *rv = NULL;
--    LOCK;
-+    __UCLIBC_MUTEX_LOCK(mylock);
-     if (netf == NULL && (netf = fopen(NETDB, "r" )) == NULL) {
--      UNLOCK;
--      return (NULL);
-+              goto DONE;
-     }
--again:
-+ again:
-     if (!line) {
--      line = malloc(BUFSIZ + 1);
--      if (!line)
--          abort();
-+              line = malloc(BUFSIZ + 1);
-+              if (!line)
-+                      abort();
-     }
-     p = fgets(line, BUFSIZ, netf);
-     if (p == NULL) {
--      UNLOCK;
--      return (NULL);
-+              goto DONE;
-     }
-     if (*p == '#')
--      goto again;
-+              goto again;
-     cp = any(p, "#\n");
-     if (cp == NULL)
--      goto again;
-+              goto again;
-     *cp = '\0';
-     net.n_name = p;
-     cp = any(p, " \t");
-     if (cp == NULL)
--      goto again;
-+              goto again;
-     *cp++ = '\0';
-     while (*cp == ' ' || *cp == '\t')
--      cp++;
-+              cp++;
-     p = any(cp, " \t");
-     if (p != NULL)
--      *p++ = '\0';
-+              *p++ = '\0';
-     net.n_net = inet_network(cp);
-     net.n_addrtype = AF_INET;
-     q = net.n_aliases = net_aliases;
-     if (p != NULL)
--      cp = p;
-+              cp = p;
-     while (cp && *cp) {
--      if (*cp == ' ' || *cp == '\t') {
--          cp++;
--          continue;
--      }
--      if (q < &net_aliases[MAXALIASES - 1])
--          *q++ = cp;
--      cp = any(cp, " \t");
--      if (cp != NULL)
--          *cp++ = '\0';
-+              if (*cp == ' ' || *cp == '\t') {
-+                      cp++;
-+                      continue;
-+              }
-+              if (q < &net_aliases[MAXALIASES - 1])
-+                      *q++ = cp;
-+              cp = any(cp, " \t");
-+              if (cp != NULL)
-+                      *cp++ = '\0';
-     }
-     *q = NULL;
--    UNLOCK;
--    return (&net);
-+
-+      rv = &net;
-+
-+ DONE:
-+    __UCLIBC_MUTEX_UNLOCK(mylock);
-+    return rv;
- }
-diff --git a/libc/inet/getproto.c b/libc/inet/getproto.c
-index c9f35f1..3665d89 100644
---- a/libc/inet/getproto.c
-+++ b/libc/inet/getproto.c
-@@ -62,17 +62,9 @@
- #include <string.h>
- #include <errno.h>
--#ifdef __UCLIBC_HAS_THREADS__
--#include <pthread.h>
--static pthread_mutex_t mylock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
--# define LOCK __pthread_mutex_lock(&mylock)
--# define UNLOCK       __pthread_mutex_unlock(&mylock);
--#else
--# define LOCK
--# define UNLOCK
--#endif
--
-+#include <bits/uClibc_mutex.h>
-+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);
- #define       MAXALIASES      35
- #define       SBUFSIZE        (BUFSIZ + 1 + (sizeof(char *) * MAXALIASES))
-@@ -85,109 +77,114 @@ static int proto_stayopen;
- static void __initbuf(void)
- {
-     if (!static_aliases) {
--      static_aliases = malloc(SBUFSIZE);
--      if (!static_aliases)
--          abort();
-+              static_aliases = malloc(SBUFSIZE);
-+              if (!static_aliases)
-+                      abort();
-     }
- }
- void setprotoent(int f)
- {
--    LOCK;
-+    __UCLIBC_MUTEX_LOCK(mylock);
-     if (protof == NULL)
--      protof = fopen(_PATH_PROTOCOLS, "r" );
-+              protof = fopen(_PATH_PROTOCOLS, "r" );
-     else
--      rewind(protof);
-+              rewind(protof);
-     proto_stayopen |= f;
--    UNLOCK;
-+    __UCLIBC_MUTEX_UNLOCK(mylock);
- }
- void endprotoent(void)
- {
--    LOCK;
-+    __UCLIBC_MUTEX_LOCK(mylock);
-     if (protof) {
--      fclose(protof);
--      protof = NULL;
-+              fclose(protof);
-+              protof = NULL;
-     }
-     proto_stayopen = 0;
--    UNLOCK;
-+    __UCLIBC_MUTEX_UNLOCK(mylock);
- }
- int getprotoent_r(struct protoent *result_buf,
--                char *buf, size_t buflen,
--                struct protoent **result)
-+                                char *buf, size_t buflen,
-+                                struct protoent **result)
- {
-     char *p;
-     register char *cp, **q;
-     char **proto_aliases;
-     char *line;
-+      int rv;
-     *result = NULL;
-     if (buflen < sizeof(*proto_aliases)*MAXALIASES) {
--      errno=ERANGE;
--      return errno;
-+              errno=ERANGE;
-+              return errno;
-     }
--    LOCK;
-+
-+    __UCLIBC_MUTEX_LOCK(mylock);
-     proto_aliases=(char **)buf;
-     buf+=sizeof(*proto_aliases)*MAXALIASES;
-     buflen-=sizeof(*proto_aliases)*MAXALIASES;
-     if (buflen < BUFSIZ+1) {
--      UNLOCK;
--      errno=ERANGE;
--      return errno;
-+              errno=rv=ERANGE;
-+              goto DONE;
-     }
-     line=buf;
-     buf+=BUFSIZ+1;
-     buflen-=BUFSIZ+1;
-     if (protof == NULL && (protof = fopen(_PATH_PROTOCOLS, "r" )) == NULL) {
--      UNLOCK;
--      return errno;
-+              rv=errno;
-+              goto DONE;
-     }
--again:
-+ again:
-     if ((p = fgets(line, BUFSIZ, protof)) == NULL) {
--      UNLOCK;
--      return TRY_AGAIN;
-+              rv=TRY_AGAIN;
-+              goto DONE;
-     }
-     if (*p == '#')
--      goto again;
-+              goto again;
-     cp = strpbrk(p, "#\n");
-     if (cp == NULL)
--      goto again;
-+              goto again;
-     *cp = '\0';
-     result_buf->p_name = p;
-     cp = strpbrk(p, " \t");
-     if (cp == NULL)
--      goto again;
-+              goto again;
-     *cp++ = '\0';
-     while (*cp == ' ' || *cp == '\t')
--      cp++;
-+              cp++;
-     p = strpbrk(cp, " \t");
-     if (p != NULL)
--      *p++ = '\0';
-+              *p++ = '\0';
-     result_buf->p_proto = atoi(cp);
-     q = result_buf->p_aliases = proto_aliases;
-     if (p != NULL) {
--      cp = p;
--      while (cp && *cp) {
--          if (*cp == ' ' || *cp == '\t') {
--              cp++;
--              continue;
--          }
--          if (q < &proto_aliases[MAXALIASES - 1])
--              *q++ = cp;
--          cp = strpbrk(cp, " \t");
--          if (cp != NULL)
--              *cp++ = '\0';
--      }
-+              cp = p;
-+              while (cp && *cp) {
-+                      if (*cp == ' ' || *cp == '\t') {
-+                              cp++;
-+                              continue;
-+                      }
-+                      if (q < &proto_aliases[MAXALIASES - 1])
-+                              *q++ = cp;
-+                      cp = strpbrk(cp, " \t");
-+                      if (cp != NULL)
-+                              *cp++ = '\0';
-+              }
-     }
-     *q = NULL;
-     *result=result_buf;
--    UNLOCK;
--    return 0;
-+
-+      rv = 0;
-+
-+ DONE:
-+    __UCLIBC_MUTEX_UNLOCK(mylock);
-+    return rv;
- }
- struct protoent * getprotoent(void)
-@@ -201,26 +198,26 @@ struct protoent * getprotoent(void)
- int getprotobyname_r(const char *name,
--                  struct protoent *result_buf,
--                  char *buf, size_t buflen,
--                  struct protoent **result)
-+                                       struct protoent *result_buf,
-+                                       char *buf, size_t buflen,
-+                                       struct protoent **result)
- {
-     register char **cp;
-     int ret;
--    LOCK;
-+    __UCLIBC_MUTEX_LOCK(mylock);
-     setprotoent(proto_stayopen);
-     while (!(ret=getprotoent_r(result_buf, buf, buflen, result))) {
--      if (strcmp(result_buf->p_name, name) == 0)
--          break;
--      for (cp = result_buf->p_aliases; *cp != 0; cp++)
--          if (strcmp(*cp, name) == 0)
--              goto found;
-+              if (strcmp(result_buf->p_name, name) == 0)
-+                      break;
-+              for (cp = result_buf->p_aliases; *cp != 0; cp++)
-+                      if (strcmp(*cp, name) == 0)
-+                              goto found;
-     }
--found:
-+ found:
-     if (!proto_stayopen)
--      endprotoent();
--    UNLOCK;
-+              endprotoent();
-+    __UCLIBC_MUTEX_UNLOCK(mylock);
-     return *result?0:ret;
- }
-@@ -236,20 +233,20 @@ struct protoent * getprotobyname(const c
- int getprotobynumber_r (int proto_num,
--                      struct protoent *result_buf,
--                      char *buf, size_t buflen,
--                      struct protoent **result)
-+                                              struct protoent *result_buf,
-+                                              char *buf, size_t buflen,
-+                                              struct protoent **result)
- {
-     int ret;
--    LOCK;
-+    __UCLIBC_MUTEX_LOCK(mylock);
-     setprotoent(proto_stayopen);
-     while (!(ret=getprotoent_r(result_buf, buf, buflen, result)))
--      if (result_buf->p_proto == proto_num)
--          break;
-+              if (result_buf->p_proto == proto_num)
-+                      break;
-     if (!proto_stayopen)
--      endprotoent();
--    UNLOCK;
-+              endprotoent();
-+    __UCLIBC_MUTEX_UNLOCK(mylock);
-     return *result?0:ret;
- }
-diff --git a/libc/inet/getservice.c b/libc/inet/getservice.c
-index cbe5c50..b666057 100644
---- a/libc/inet/getservice.c
-+++ b/libc/inet/getservice.c
-@@ -65,20 +65,9 @@
- #include <arpa/inet.h>
- #include <errno.h>
-+#include <bits/uClibc_mutex.h>
--
--#ifdef __UCLIBC_HAS_THREADS__
--#include <pthread.h>
--static pthread_mutex_t mylock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
--# define LOCK __pthread_mutex_lock(&mylock)
--# define UNLOCK       __pthread_mutex_unlock(&mylock);
--#else
--# define LOCK
--# define UNLOCK
--#endif
--
--
--
-+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);
- #define       MAXALIASES      35
- #define SBUFSIZE      (BUFSIZ + 1 + (sizeof(char *) * MAXALIASES))
-@@ -91,32 +80,32 @@ static int serv_stayopen;
- static void __initbuf(void)
- {
-     if (!servbuf) {
--      servbuf = malloc(SBUFSIZE);
--      if (!servbuf)
--          abort();
-+              servbuf = malloc(SBUFSIZE);
-+              if (!servbuf)
-+                      abort();
-     }
- }
- void setservent(int f)
- {
--    LOCK;
-+    __UCLIBC_MUTEX_LOCK(mylock);
-     if (servf == NULL)
--      servf = fopen(_PATH_SERVICES, "r" );
-+              servf = fopen(_PATH_SERVICES, "r" );
-     else
--      rewind(servf);
-+              rewind(servf);
-     serv_stayopen |= f;
--    UNLOCK;
-+    __UCLIBC_MUTEX_UNLOCK(mylock);
- }
- void endservent(void)
- {
--    LOCK;
-+    __UCLIBC_MUTEX_LOCK(mylock);
-     if (servf) {
--      fclose(servf);
--      servf = NULL;
-+              fclose(servf);
-+              servf = NULL;
-     }
-     serv_stayopen = 0;
--    UNLOCK;
-+    __UCLIBC_MUTEX_UNLOCK(mylock);
- }
- struct servent * getservent(void)
-@@ -149,127 +138,129 @@ struct servent * getservbyport(int port,
- }
- int getservent_r(struct servent * result_buf,
--               char * buf, size_t buflen,
--               struct servent ** result)
-+                               char * buf, size_t buflen,
-+                               struct servent ** result)
- {
-     char *p;
-     register char *cp, **q;
-     char **serv_aliases;
-     char *line;
-+      int rv;
-     *result=NULL;
-     if (buflen < sizeof(*serv_aliases)*MAXALIASES) {
--      errno=ERANGE;
--      return errno;
-+              errno=ERANGE;
-+              return errno;
-     }
--    LOCK;
-+    __UCLIBC_MUTEX_LOCK(mylock);
-     serv_aliases=(char **)buf;
-     buf+=sizeof(*serv_aliases)*MAXALIASES;
-     buflen-=sizeof(*serv_aliases)*MAXALIASES;
-     if (buflen < BUFSIZ+1) {
--      UNLOCK;
--      errno=ERANGE;
--      return errno;
-+              errno=rv=ERANGE;
-+              goto DONE;
-     }
-     line=buf;
-     buf+=BUFSIZ+1;
-     buflen-=BUFSIZ+1;
-     if (servf == NULL && (servf = fopen(_PATH_SERVICES, "r" )) == NULL) {
--      UNLOCK;
--      errno=EIO;
--      return errno;
-+              errno=rv=EIO;
-+              goto DONE;
-     }
--again:
-+ again:
-     if ((p = fgets(line, BUFSIZ, servf)) == NULL) {
--      UNLOCK;
--      errno=EIO;
--      return errno;
-+              errno=rv=EIO;
-+              goto DONE;
-     }
-     if (*p == '#')
--      goto again;
-+              goto again;
-     cp = strpbrk(p, "#\n");
-     if (cp == NULL)
--      goto again;
-+              goto again;
-     *cp = '\0';
-     result_buf->s_name = p;
-     p = strpbrk(p, " \t");
-     if (p == NULL)
--      goto again;
-+              goto again;
-     *p++ = '\0';
-     while (*p == ' ' || *p == '\t')
--      p++;
-+              p++;
-     cp = strpbrk(p, ",/");
-     if (cp == NULL)
--      goto again;
-+              goto again;
-     *cp++ = '\0';
-     result_buf->s_port = htons((u_short)atoi(p));
-     result_buf->s_proto = cp;
-     q = result_buf->s_aliases = serv_aliases;
-     cp = strpbrk(cp, " \t");
-     if (cp != NULL)
--      *cp++ = '\0';
-+              *cp++ = '\0';
-     while (cp && *cp) {
--      if (*cp == ' ' || *cp == '\t') {
--          cp++;
--          continue;
--      }
--      if (q < &serv_aliases[MAXALIASES - 1])
--          *q++ = cp;
--      cp = strpbrk(cp, " \t");
--      if (cp != NULL)
--          *cp++ = '\0';
-+              if (*cp == ' ' || *cp == '\t') {
-+                      cp++;
-+                      continue;
-+              }
-+              if (q < &serv_aliases[MAXALIASES - 1])
-+                      *q++ = cp;
-+              cp = strpbrk(cp, " \t");
-+              if (cp != NULL)
-+                      *cp++ = '\0';
-     }
-     *q = NULL;
-     *result=result_buf;
--    UNLOCK;
--    return 0;
-+
-+      rv = 0;
-+
-+ DONE:
-+    __UCLIBC_MUTEX_UNLOCK(mylock);
-+    return rv;
- }
- int getservbyname_r(const char *name, const char *proto,
--      struct servent * result_buf, char * buf, size_t buflen,
--      struct servent ** result)
-+                                      struct servent * result_buf, char * buf, size_t buflen,
-+                                      struct servent ** result)
- {
-     register char **cp;
-     int ret;
--    LOCK;
-+    __UCLIBC_MUTEX_LOCK(mylock);
-     setservent(serv_stayopen);
-     while (!(ret=getservent_r(result_buf, buf, buflen, result))) {
--      if (strcmp(name, result_buf->s_name) == 0)
--          goto gotname;
--      for (cp = result_buf->s_aliases; *cp; cp++)
--          if (strcmp(name, *cp) == 0)
--              goto gotname;
--      continue;
--gotname:
--      if (proto == 0 || strcmp(result_buf->s_proto, proto) == 0)
--          break;
-+              if (strcmp(name, result_buf->s_name) == 0)
-+                      goto gotname;
-+              for (cp = result_buf->s_aliases; *cp; cp++)
-+                      if (strcmp(name, *cp) == 0)
-+                              goto gotname;
-+              continue;
-+      gotname:
-+              if (proto == 0 || strcmp(result_buf->s_proto, proto) == 0)
-+                      break;
-     }
-     if (!serv_stayopen)
--      endservent();
--    UNLOCK;
-+              endservent();
-+    __UCLIBC_MUTEX_UNLOCK(mylock);
-     return *result?0:ret;
- }
- int getservbyport_r(int port, const char *proto,
--      struct servent * result_buf, char * buf,
--      size_t buflen, struct servent ** result)
-+                                      struct servent * result_buf, char * buf,
-+                                      size_t buflen, struct servent ** result)
- {
-     int ret;
--    LOCK;
-+    __UCLIBC_MUTEX_LOCK(mylock);
-     setservent(serv_stayopen);
-     while (!(ret=getservent_r(result_buf, buf, buflen, result))) {
--      if (result_buf->s_port != port)
--          continue;
--      if (proto == 0 || strcmp(result_buf->s_proto, proto) == 0)
--          break;
-+              if (result_buf->s_port != port)
-+                      continue;
-+              if (proto == 0 || strcmp(result_buf->s_proto, proto) == 0)
-+                      break;
-     }
-     if (!serv_stayopen)
--      endservent();
--    UNLOCK;
-+              endservent();
-+    __UCLIBC_MUTEX_UNLOCK(mylock);
-     return *result?0:ret;
- }
-diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c
-index 27b60ef..0f583ab 100644
---- a/libc/inet/resolv.c
-+++ b/libc/inet/resolv.c
-@@ -7,7 +7,7 @@
-  * 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.
--*/
-+ */
- /*
-  * Portions Copyright (c) 1985, 1993
-@@ -153,6 +153,11 @@
- #include <sys/utsname.h>
- #include <sys/un.h>
-+#include <bits/uClibc_mutex.h>
-+
-+__UCLIBC_MUTEX_EXTERN(__resolv_lock);
-+
-+
- #define MAX_RECURSE 5
- #define REPLY_TIMEOUT 10
- #define MAX_RETRIES 3
-@@ -180,18 +185,6 @@ extern char * __nameserver[MAX_SERVERS];
- extern int __searchdomains;
- extern char * __searchdomain[MAX_SEARCH];
--#ifdef __UCLIBC_HAS_THREADS__
--#include <pthread.h>
--extern pthread_mutex_t __resolv_lock;
--# define BIGLOCK      __pthread_mutex_lock(&__resolv_lock)
--# define BIGUNLOCK    __pthread_mutex_unlock(&__resolv_lock);
--#else
--# define BIGLOCK
--# define BIGUNLOCK
--#endif
--
--
--
- /* Structs */
- struct resolv_header {
-       int id;
-@@ -229,49 +222,49 @@ enum etc_hosts_action {
- /* function prototypes */
- extern int __get_hosts_byname_r(const char * name, int type,
--                            struct hostent * result_buf,
--                            char * buf, size_t buflen,
--                            struct hostent ** result,
--                            int * h_errnop);
-+                                                              struct hostent * result_buf,
-+                                                              char * buf, size_t buflen,
-+                                                              struct hostent ** result,
-+                                                              int * h_errnop);
- extern int __get_hosts_byaddr_r(const char * addr, int len, int type,
--                            struct hostent * result_buf,
--                            char * buf, size_t buflen,
--                            struct hostent ** result,
--                            int * h_errnop);
-+                                                              struct hostent * result_buf,
-+                                                              char * buf, size_t buflen,
-+                                                              struct hostent ** result,
-+                                                              int * h_errnop);
- extern void __open_etc_hosts(FILE **fp);
- extern int __read_etc_hosts_r(FILE *fp, const char * name, int type,
--                          enum etc_hosts_action action,
--                          struct hostent * result_buf,
--                          char * buf, size_t buflen,
--                          struct hostent ** result,
--                          int * h_errnop);
-+                                                        enum etc_hosts_action action,
-+                                                        struct hostent * result_buf,
-+                                                        char * buf, size_t buflen,
-+                                                        struct hostent ** result,
-+                                                        int * h_errnop);
- extern int __dns_lookup(const char * name, int type, int nscount,
--      char ** nsip, unsigned char ** outpacket, struct resolv_answer * a);
-+                                              char ** nsip, unsigned char ** outpacket, struct resolv_answer * a);
- extern int __encode_dotted(const char * dotted, unsigned char * dest, int maxlen);
- extern int __decode_dotted(const unsigned char * message, int offset,
--      char * dest, int maxlen);
-+                                                 char * dest, int maxlen);
- extern int __length_dotted(const unsigned char * message, int offset);
- extern int __encode_header(struct resolv_header * h, unsigned char * dest, int maxlen);
- extern int __decode_header(unsigned char * data, struct resolv_header * h);
- extern int __encode_question(struct resolv_question * q,
--      unsigned char * dest, int maxlen);
-+                                                       unsigned char * dest, int maxlen);
- extern int __decode_question(unsigned char * message, int offset,
--      struct resolv_question * q);
-+                                                       struct resolv_question * q);
- extern int __encode_answer(struct resolv_answer * a,
--      unsigned char * dest, int maxlen);
-+                                                 unsigned char * dest, int maxlen);
- extern int __decode_answer(unsigned char * message, int offset,
--      struct resolv_answer * a);
-+                                                 struct resolv_answer * a);
- extern int __length_question(unsigned char * message, int offset);
- extern int __open_nameservers(void);
- extern void __close_nameservers(void);
- extern int __dn_expand(const u_char *, const u_char *, const u_char *,
--      char *, int);
-+                                         char *, int);
- extern int __ns_name_uncompress(const u_char *, const u_char *,
--              const u_char *, char *, size_t);
-+                                                              const u_char *, char *, size_t);
- extern int __ns_name_ntop(const u_char *, char *, size_t);
- extern int __ns_name_unpack(const u_char *, const u_char *, const u_char *,
--               u_char *, size_t);
-+                                                      u_char *, size_t);
- #ifdef L_encodeh
-@@ -361,7 +354,7 @@ int __encode_dotted(const char *dotted, 
-    This routine understands compressed data. */
- int __decode_dotted(const unsigned char *data, int offset,
--                                char *dest, int maxlen)
-+                                      char *dest, int maxlen)
- {
-       int l;
-       int measure = 1;
-@@ -435,7 +428,7 @@ int __length_dotted(const unsigned char 
- #ifdef L_encodeq
- int __encode_question(struct resolv_question *q,
--                                      unsigned char *dest, int maxlen)
-+                                        unsigned char *dest, int maxlen)
- {
-       int i;
-@@ -460,7 +453,7 @@ int __encode_question(struct resolv_ques
- #ifdef L_decodeq
- int __decode_question(unsigned char *message, int offset,
--                                      struct resolv_question *q)
-+                                        struct resolv_question *q)
- {
-       char temp[256];
-       int i;
-@@ -525,7 +518,7 @@ int __encode_answer(struct resolv_answer
- #ifdef L_decodea
- int __decode_answer(unsigned char *message, int offset,
--                                struct resolv_answer *a)
-+                                      struct resolv_answer *a)
- {
-       char temp[256];
-       int i;
-@@ -557,11 +550,11 @@ int __decode_answer(unsigned char *messa
- #ifdef L_encodep
- int __encode_packet(struct resolv_header *h,
--      struct resolv_question **q,
--      struct resolv_answer **an,
--      struct resolv_answer **ns,
--      struct resolv_answer **ar,
--      unsigned char *dest, int maxlen)
-+                                      struct resolv_question **q,
-+                                      struct resolv_answer **an,
-+                                      struct resolv_answer **ns,
-+                                      struct resolv_answer **ar,
-+                                      unsigned char *dest, int maxlen)
- {
-       int i, total = 0;
-       int j;
-@@ -621,7 +614,7 @@ int __decode_packet(unsigned char *data,
- #ifdef L_formquery
- int __form_query(int id, const char *name, int type, unsigned char *packet,
--                         int maxlen)
-+                               int maxlen)
- {
-       struct resolv_header h;
-       struct resolv_question q;
-@@ -649,14 +642,7 @@ int __form_query(int id, const char *nam
- #ifdef L_dnslookup
--#ifdef __UCLIBC_HAS_THREADS__
--static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;
--# define LOCK __pthread_mutex_lock(&mylock)
--# define UNLOCK       __pthread_mutex_unlock(&mylock);
--#else
--# define LOCK
--# define UNLOCK
--#endif
-+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER);
- /* Just for the record, having to lock __dns_lookup() just for these two globals
-  * is pretty lame.  I think these two variables can probably be de-global-ized,
-@@ -665,7 +651,7 @@ static pthread_mutex_t mylock = PTHREAD_
- static int ns=0, id=1;
- int __dns_lookup(const char *name, int type, int nscount, char **nsip,
--                         unsigned char **outpacket, struct resolv_answer *a)
-+                               unsigned char **outpacket, struct resolv_answer *a)
- {
-       int i, j, len, fd, pos, rc;
-       struct timeval tv;
-@@ -693,10 +679,10 @@ int __dns_lookup(const char *name, int t
-       DPRINTF("Looking up type %d answer for '%s'\n", type, name);
-       /* Mess with globals while under lock */
--      LOCK;
-+      __UCLIBC_MUTEX_LOCK(mylock);
-       local_ns = ns % nscount;
-       local_id = id;
--      UNLOCK;
-+      __UCLIBC_MUTEX_UNLOCK(mylock);
-       while (retries < MAX_RETRIES) {
-               if (fd != -1)
-@@ -722,13 +708,13 @@ int __dns_lookup(const char *name, int t
-               strncpy(lookup,name,MAXDNAME);
-               if (variant >= 0) {
--                        BIGLOCK;
--                        if (variant < __searchdomains) {
--                                strncat(lookup,".", MAXDNAME);
--                                strncat(lookup,__searchdomain[variant], MAXDNAME);
--                        }
--                        BIGUNLOCK;
--                }
-+                      __UCLIBC_MUTEX_LOCK(__resolv_lock);
-+                      if (variant < __searchdomains) {
-+                              strncat(lookup,".", MAXDNAME);
-+                              strncat(lookup,__searchdomain[variant], MAXDNAME);
-+                      }
-+                      __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
-+              }
-               DPRINTF("lookup name: %s\n", lookup);
-               q.dotted = (char *)lookup;
-               q.qtype = type;
-@@ -750,7 +736,7 @@ int __dns_lookup(const char *name, int t
-               fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
- #endif
-               if (fd < 0) {
--                    retries++;
-+                      retries++;
-                   continue;
-               }
-@@ -772,11 +758,11 @@ int __dns_lookup(const char *name, int t
- #endif
-               if (rc < 0) {
-                   if (errno == ENETUNREACH) {
--                      /* routing error, presume not transient */
--                      goto tryall;
-+                              /* routing error, presume not transient */
-+                              goto tryall;
-                   } else
--                      /* retry */
--                        retries++;
-+                              /* retry */
-+                              retries++;
-                       continue;
-               }
-@@ -838,55 +824,55 @@ int __dns_lookup(const char *name, int t
-               first_answer = 1;
-               for (j=0;j<h.ancount;j++,pos += i)
--              {
--                  i = __decode_answer(packet, pos, &ma);
-+                      {
-+                              i = __decode_answer(packet, pos, &ma);
--                  if (i<0) {
--                      DPRINTF("failed decode %d\n", i);
--                      goto again;
--                  }
-+                              if (i<0) {
-+                                      DPRINTF("failed decode %d\n", i);
-+                                      goto again;
-+                              }
--                  if ( first_answer )
--                  {
--                      ma.buf = a->buf;
--                      ma.buflen = a->buflen;
--                      ma.add_count = a->add_count;
--                      memcpy(a, &ma, sizeof(ma));
--                      if (a->atype != T_SIG && (0 == a->buf || (type != T_A && type != T_AAAA)))
--                      {
--                          break;
--                      }
--                      if (a->atype != type)
--                      {
--                          free(a->dotted);
--                          continue;
--                      }
--                      a->add_count = h.ancount - j - 1;
--                      if ((a->rdlength + sizeof(struct in_addr*)) * a->add_count > a->buflen)
--                      {
--                          break;
--                      }
--                      a->add_count = 0;
--                      first_answer = 0;
--                  }
--                  else
--                  {
--                      free(ma.dotted);
--                      if (ma.atype != type)
--                      {
--                          continue;
--                      }
--                      if (a->rdlength != ma.rdlength)
--                      {
--                          free(a->dotted);
--                          DPRINTF("Answer address len(%u) differs from original(%u)\n",
--                                  ma.rdlength, a->rdlength);
--                          goto again;
-+                              if ( first_answer )
-+                                      {
-+                                              ma.buf = a->buf;
-+                                              ma.buflen = a->buflen;
-+                                              ma.add_count = a->add_count;
-+                                              memcpy(a, &ma, sizeof(ma));
-+                                              if (a->atype != T_SIG && (0 == a->buf || (type != T_A && type != T_AAAA)))
-+                                                      {
-+                                                              break;
-+                                                      }
-+                                              if (a->atype != type)
-+                                                      {
-+                                                              free(a->dotted);
-+                                                              continue;
-+                                                      }
-+                                              a->add_count = h.ancount - j - 1;
-+                                              if ((a->rdlength + sizeof(struct in_addr*)) * a->add_count > a->buflen)
-+                                                      {
-+                                                              break;
-+                                                      }
-+                                              a->add_count = 0;
-+                                              first_answer = 0;
-+                                      }
-+                              else
-+                                      {
-+                                              free(ma.dotted);
-+                                              if (ma.atype != type)
-+                                                      {
-+                                                              continue;
-+                                                      }
-+                                              if (a->rdlength != ma.rdlength)
-+                                                      {
-+                                                              free(a->dotted);
-+                                                              DPRINTF("Answer address len(%u) differs from original(%u)\n",
-+                                                                              ma.rdlength, a->rdlength);
-+                                                              goto again;
-+                                                      }
-+                                              memcpy(a->buf + (a->add_count * ma.rdlength), ma.rdata, ma.rdlength);
-+                                              ++a->add_count;
-+                                      }
-                       }
--                      memcpy(a->buf + (a->add_count * ma.rdlength), ma.rdata, ma.rdlength);
--                      ++a->add_count;
--                  }
--              }
-               DPRINTF("Answer name = |%s|\n", a->dotted);
-               DPRINTF("Answer type = |%d|\n", a->atype);
-@@ -900,48 +886,48 @@ int __dns_lookup(const char *name, int t
-               free(lookup);
-               /* Mess with globals while under lock */
--              LOCK;
-+              __UCLIBC_MUTEX_LOCK(mylock);
-               ns = local_ns;
-               id = local_id;
--              UNLOCK;
-+              __UCLIBC_MUTEX_UNLOCK(mylock);
-               return (len);                           /* success! */
--        tryall:
-+      tryall:
-               /* if there are other nameservers, give them a go,
-                  otherwise return with error */
-               {
-                   variant = -1;
--                    local_ns = (local_ns + 1) % nscount;
--                    if (local_ns == 0)
--                      retries++;
-+                      local_ns = (local_ns + 1) % nscount;
-+                      if (local_ns == 0)
-+                              retries++;
--                    continue;
-+                      continue;
-               }
--        again:
-+      again:
-               /* if there are searchdomains, try them or fallback as passed */
-               {
-                   int sdomains;
--                  BIGLOCK;
-+                  __UCLIBC_MUTEX_LOCK(__resolv_lock);
-                   sdomains=__searchdomains;
--                  BIGUNLOCK;
-+                  __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
-                   if (variant < sdomains - 1) {
--                      /* next search */
--                      variant++;
-+                              /* next search */
-+                              variant++;
-                   } else {
--                      /* next server, first search */
--                      local_ns = (local_ns + 1) % nscount;
--                        if (local_ns == 0)
--                          retries++;
-+                              /* next server, first search */
-+                              local_ns = (local_ns + 1) % nscount;
-+                              if (local_ns == 0)
-+                                      retries++;
--                      variant = -1;
-+                              variant = -1;
-                   }
-               }
-       }
--fail:
-+ fail:
-       if (fd != -1)
-           close(fd);
-       if (lookup)
-@@ -951,10 +937,10 @@ fail:
-       h_errno = NETDB_INTERNAL;
-       /* Mess with globals while under lock */
-       if (local_ns != -1) {
--          LOCK;
-+          __UCLIBC_MUTEX_LOCK(mylock);
-           ns = local_ns;
-           id = local_id;
--          UNLOCK;
-+          __UCLIBC_MUTEX_UNLOCK(mylock);
-       }
-       return -1;
- }
-@@ -966,9 +952,8 @@ int __nameservers;
- char * __nameserver[MAX_SERVERS];
- int __searchdomains;
- char * __searchdomain[MAX_SEARCH];
--#ifdef __UCLIBC_HAS_THREADS__
--pthread_mutex_t __resolv_lock = PTHREAD_MUTEX_INITIALIZER;
--#endif
-+
-+__UCLIBC_MUTEX_INIT(__resolv_lock, PTHREAD_MUTEX_INITIALIZER);
- /*
-  *    we currently read formats not quite the same as that on normal
-@@ -982,60 +967,63 @@ int __open_nameservers()
- #define RESOLV_ARGS 5
-       char szBuffer[128], *p, *argv[RESOLV_ARGS];
-       int argc;
-+      int rv = 0;
--      BIGLOCK;
-+      __UCLIBC_MUTEX_LOCK(__resolv_lock);
-       if (__nameservers > 0) {
--          BIGUNLOCK;
--          return 0;
-+              goto DONE;
-       }
-       if ((fp = fopen("/etc/resolv.conf", "r")) ||
--                      (fp = fopen("/etc/config/resolv.conf", "r")))
--      {
--
--              while (fgets(szBuffer, sizeof(szBuffer), fp) != NULL) {
-+              (fp = fopen("/etc/config/resolv.conf", "r")))
-+              {
--                      for (p = szBuffer; *p && isspace(*p); p++)
--                              /* skip white space */;
--                      if (*p == '\0' || *p == '\n' || *p == '#') /* skip comments etc */
--                              continue;
--                      argc = 0;
--                      while (*p && argc < RESOLV_ARGS) {
--                              argv[argc++] = p;
--                              while (*p && !isspace(*p) && *p != '\n')
--                                      p++;
--                              while (*p && (isspace(*p) || *p == '\n')) /* remove spaces */
--                                      *p++ = '\0';
--                      }
-+                      while (fgets(szBuffer, sizeof(szBuffer), fp) != NULL) {
--                      if (strcmp(argv[0], "nameserver") == 0) {
--                              for (i = 1; i < argc && __nameservers < MAX_SERVERS; i++) {
--                                      __nameserver[__nameservers++] = strdup(argv[i]);
--                                      DPRINTF("adding nameserver %s\n", argv[i]);
-+                              for (p = szBuffer; *p && isspace(*p); p++)
-+                                      /* skip white space */;
-+                              if (*p == '\0' || *p == '\n' || *p == '#') /* skip comments etc */
-+                                      continue;
-+                              argc = 0;
-+                              while (*p && argc < RESOLV_ARGS) {
-+                                      argv[argc++] = p;
-+                                      while (*p && !isspace(*p) && *p != '\n')
-+                                              p++;
-+                                      while (*p && (isspace(*p) || *p == '\n')) /* remove spaces */
-+                                              *p++ = '\0';
-                               }
--                      }
--                      /* domain and search are mutually exclusive, the last one wins */
--                      if (strcmp(argv[0],"domain")==0 || strcmp(argv[0],"search")==0) {
--                              while (__searchdomains > 0) {
--                                      free(__searchdomain[--__searchdomains]);
--                                      __searchdomain[__searchdomains] = NULL;
-+                              if (strcmp(argv[0], "nameserver") == 0) {
-+                                      for (i = 1; i < argc && __nameservers < MAX_SERVERS; i++) {
-+                                              __nameserver[__nameservers++] = strdup(argv[i]);
-+                                              DPRINTF("adding nameserver %s\n", argv[i]);
-+                                      }
-                               }
--                              for (i=1; i < argc && __searchdomains < MAX_SEARCH; i++) {
--                                      __searchdomain[__searchdomains++] = strdup(argv[i]);
--                                      DPRINTF("adding search %s\n", argv[i]);
-+
-+                              /* domain and search are mutually exclusive, the last one wins */
-+                              if (strcmp(argv[0],"domain")==0 || strcmp(argv[0],"search")==0) {
-+                                      while (__searchdomains > 0) {
-+                                              free(__searchdomain[--__searchdomains]);
-+                                              __searchdomain[__searchdomains] = NULL;
-+                                      }
-+                                      for (i=1; i < argc && __searchdomains < MAX_SEARCH; i++) {
-+                                              __searchdomain[__searchdomains++] = strdup(argv[i]);
-+                                              DPRINTF("adding search %s\n", argv[i]);
-+                                      }
-                               }
-                       }
-+                      fclose(fp);
-+                      DPRINTF("nameservers = %d\n", __nameservers);
-+                      goto DONE;
-               }
--              fclose(fp);
--              DPRINTF("nameservers = %d\n", __nameservers);
--              BIGUNLOCK;
--              return 0;
--      }
-       DPRINTF("failed to open %s\n", "resolv.conf");
-       h_errno = NO_RECOVERY;
--      BIGUNLOCK;
--      return -1;
-+
-+      rv = -1;
-+
-+ DONE:
-+      __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
-+      return rv;
- }
- #endif
-@@ -1044,7 +1032,7 @@ int __open_nameservers()
- void __close_nameservers(void)
- {
--      BIGLOCK;
-+      __UCLIBC_MUTEX_LOCK(__resolv_lock);
-       while (__nameservers > 0) {
-               free(__nameserver[--__nameservers]);
-               __nameserver[__nameservers] = NULL;
-@@ -1053,7 +1041,7 @@ void __close_nameservers(void)
-               free(__searchdomain[--__searchdomains]);
-               __searchdomain[__searchdomains] = NULL;
-       }
--      BIGUNLOCK;
-+      __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
- }
- #endif
-@@ -1063,8 +1051,8 @@ struct hostent *gethostbyname(const char
- {
-       static struct hostent h;
-       static char buf[sizeof(struct in_addr) +
--                      sizeof(struct in_addr *)*2 +
--                      sizeof(char *)*(ALIAS_DIM) + 384/*namebuffer*/ + 32/* margin */];
-+                                      sizeof(struct in_addr *)*2 +
-+                                      sizeof(char *)*(ALIAS_DIM) + 384/*namebuffer*/ + 32/* margin */];
-       struct hostent *hp;
-       gethostbyname_r(name, &h, buf, sizeof(buf), &hp, &h_errno);
-@@ -1082,8 +1070,8 @@ struct hostent *gethostbyname2(const cha
- #else /* __UCLIBC_HAS_IPV6__ */
-       static struct hostent h;
-       static char buf[sizeof(struct in6_addr) +
--                      sizeof(struct in6_addr *)*2 +
--                      sizeof(char *)*(ALIAS_DIM) + 384/*namebuffer*/ + 32/* margin */];
-+                                      sizeof(struct in6_addr *)*2 +
-+                                      sizeof(char *)*(ALIAS_DIM) + 384/*namebuffer*/ + 32/* margin */];
-       struct hostent *hp;
-       gethostbyname2_r(name, family, &h, buf, sizeof(buf), &hp, &h_errno);
-@@ -1119,7 +1107,7 @@ int res_init(void)
-       /** rp->rhook = NULL; **/
-       /** rp->_u._ext.nsinit = 0; **/
--      BIGLOCK;
-+      __UCLIBC_MUTEX_LOCK(__resolv_lock);
-       if(__searchdomains) {
-               int i;
-               for(i=0; i<__searchdomains; i++) {
-@@ -1139,7 +1127,7 @@ int res_init(void)
-               }
-       }
-       rp->nscount = __nameservers;
--      BIGUNLOCK;
-+      __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
-       return(0);
- }
-@@ -1175,10 +1163,10 @@ int res_query(const char *dname, int cla
-       memset((char *) &a, '\0', sizeof(a));
--      BIGLOCK;
-+      __UCLIBC_MUTEX_LOCK(__resolv_lock);
-       __nameserversXX=__nameservers;
-       __nameserverXX=__nameserver;
--      BIGUNLOCK;
-+      __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
-       i = __dns_lookup(dname, type, __nameserversXX, __nameserverXX, &packet, &a);
-       if (i < 0) {
-@@ -1207,10 +1195,10 @@ int res_query(const char *dname, int cla
-  * is detected.  Error code, if any, is left in h_errno.
-  */
- int res_search(name, class, type, answer, anslen)
--      const char *name;       /* domain name */
--      int class, type;        /* class and type of query */
--      u_char *answer;         /* buffer to put answer */
--      int anslen;             /* size of answer */
-+       const char *name;      /* domain name */
-+       int class, type;       /* class and type of query */
-+       u_char *answer;                /* buffer to put answer */
-+       int anslen;            /* size of answer */
- {
-       const char *cp, * const *domain;
-       HEADER *hp = (HEADER *)(void *)answer;
-@@ -1256,11 +1244,11 @@ int res_search(name, class, type, answer
-               int done = 0;
-               for (domain = (const char * const *)_res.dnsrch;
--                 *domain && !done;
--                 domain++) {
-+                       *domain && !done;
-+                       domain++) {
-                       ret = res_querydomain(name, *domain, class, type,
--                          answer, anslen);
-+                                                                answer, anslen);
-                       if (ret > 0)
-                               return (ret);
-@@ -1283,22 +1271,22 @@ int res_search(name, class, type, answer
-                       }
-                       switch (h_errno) {
--                      case NO_DATA:
--                              got_nodata++;
--                              /* FALLTHROUGH */
--                      case HOST_NOT_FOUND:
--                              /* keep trying */
--                              break;
--                      case TRY_AGAIN:
--                              if (hp->rcode == SERVFAIL) {
--                                      /* try next search element, if any */
--                                      got_servfail++;
-+                              case NO_DATA:
-+                                      got_nodata++;
-+                                      /* FALLTHROUGH */
-+                              case HOST_NOT_FOUND:
-+                                      /* keep trying */
-                                       break;
--                              }
--                              /* FALLTHROUGH */
--                      default:
--                              /* anything else implies that we're done */
--                              done++;
-+                              case TRY_AGAIN:
-+                                      if (hp->rcode == SERVFAIL) {
-+                                              /* try next search element, if any */
-+                                              got_servfail++;
-+                                              break;
-+                                      }
-+                                      /* FALLTHROUGH */
-+                              default:
-+                                      /* anything else implies that we're done */
-+                                      done++;
-                       }
-                       /*
-                        * if we got here for some reason other than DNSRCH,
-@@ -1342,10 +1330,10 @@ int res_search(name, class, type, answer
-  * removing a trailing dot from name if domain is NULL.
-  */
- int res_querydomain(name, domain, class, type, answer, anslen)
--      const char *name, *domain;
--      int class, type;        /* class and type of query */
--      u_char *answer;         /* buffer to put answer */
--      int anslen;             /* size of answer */
-+       const char *name, *domain;
-+       int class, type;       /* class and type of query */
-+       u_char *answer;                /* buffer to put answer */
-+       int anslen;            /* size of answer */
- {
-       char nbuf[MAXDNAME];
-       const char *longname = nbuf;
-@@ -1359,7 +1347,7 @@ int res_querydomain(name, domain, class,
- #ifdef DEBUG
-       if (_res.options & RES_DEBUG)
-               printf(";; res_querydomain(%s, %s, %d, %d)\n",
--                      name, domain?domain:"<Nil>", class, type);
-+                         name, domain?domain:"<Nil>", class, type);
- #endif
-       if (domain == NULL) {
-               /*
-@@ -1400,11 +1388,11 @@ struct hostent *gethostbyaddr (const voi
-       static struct hostent h;
-       static char buf[
- #ifndef __UCLIBC_HAS_IPV6__
--              sizeof(struct in_addr) + sizeof(struct in_addr *)*2 +
-+                                      sizeof(struct in_addr) + sizeof(struct in_addr *)*2 +
- #else
--              sizeof(struct in6_addr) + sizeof(struct in6_addr *)*2 +
-+                                      sizeof(struct in6_addr) + sizeof(struct in6_addr *)*2 +
- #endif /* __UCLIBC_HAS_IPV6__ */
--              sizeof(char *)*(ALIAS_DIM) + 384/*namebuffer*/ + 32/* margin */];
-+                                      sizeof(char *)*(ALIAS_DIM) + 384/*namebuffer*/ + 32/* margin */];
-       struct hostent *hp;
-       gethostbyaddr_r(addr, len, type, &h, buf, sizeof(buf), &hp, &h_errno);
-@@ -1425,11 +1413,11 @@ void __open_etc_hosts(FILE **fp)
- }
- int __read_etc_hosts_r(FILE * fp, const char * name, int type,
--                   enum etc_hosts_action action,
--                   struct hostent * result_buf,
--                   char * buf, size_t buflen,
--                   struct hostent ** result,
--                   int * h_errnop)
-+                                         enum etc_hosts_action action,
-+                                         struct hostent * result_buf,
-+                                         char * buf, size_t buflen,
-+                                         struct hostent ** result,
-+                                         int * h_errnop)
- {
-       struct in_addr  *in=NULL;
-       struct in_addr  **addr_list=NULL;
-@@ -1576,56 +1564,49 @@ int __read_etc_hosts_r(FILE * fp, const 
- #ifdef L_gethostent
--#ifdef __UCLIBC_HAS_THREADS__
--static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;
--# define LOCK __pthread_mutex_lock(&mylock)
--# define UNLOCK       __pthread_mutex_unlock(&mylock);
--#else
--# define LOCK
--# define UNLOCK
--#endif
-+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER);
- static int __stay_open;
- static FILE * __gethostent_fp;
- void endhostent (void)
- {
--    LOCK;
-+    __UCLIBC_MUTEX_LOCK(mylock);
-     __stay_open = 0;
-     if (__gethostent_fp) {
--      fclose(__gethostent_fp);
-+              fclose(__gethostent_fp);
-     }
--    UNLOCK;
-+    __UCLIBC_MUTEX_UNLOCK(mylock);
- }
- void sethostent (int stay_open)
- {
--    LOCK;
-+    __UCLIBC_MUTEX_LOCK(mylock);
-     __stay_open = stay_open;
--    UNLOCK;
-+    __UCLIBC_MUTEX_UNLOCK(mylock);
- }
- int gethostent_r(struct hostent *result_buf, char *buf, size_t buflen,
--      struct hostent **result, int *h_errnop)
-+                               struct hostent **result, int *h_errnop)
- {
--    int ret;
-+    int ret = 0;
--    LOCK;
-+    __UCLIBC_MUTEX_LOCK(mylock);
-     if (__gethostent_fp == NULL) {
--      __open_etc_hosts(&__gethostent_fp);
--      if (__gethostent_fp == NULL) {
--          UNLOCK;
--          *result=NULL;
--          return 0;
--      }
-+              __open_etc_hosts(&__gethostent_fp);
-+              if (__gethostent_fp == NULL) {
-+                      *result=NULL;
-+                      goto DONE;
-+              }
-     }
-     ret = __read_etc_hosts_r(__gethostent_fp, NULL, AF_INET, GETHOSTENT,
--                 result_buf, buf, buflen, result, h_errnop);
-+                                                       result_buf, buf, buflen, result, h_errnop);
-     if (__stay_open==0) {
--      fclose(__gethostent_fp);
-+              fclose(__gethostent_fp);
-     }
--    UNLOCK;
-+ DONE:
-+    __UCLIBC_MUTEX_UNLOCK(mylock);
-     return(ret);
- }
-@@ -1634,17 +1615,17 @@ struct hostent *gethostent (void)
-     static struct hostent h;
-     static char buf[
- #ifndef __UCLIBC_HAS_IPV6__
--          sizeof(struct in_addr) + sizeof(struct in_addr *)*2 +
-+                                      sizeof(struct in_addr) + sizeof(struct in_addr *)*2 +
- #else
--          sizeof(struct in6_addr) + sizeof(struct in6_addr *)*2 +
-+                                      sizeof(struct in6_addr) + sizeof(struct in6_addr *)*2 +
- #endif /* __UCLIBC_HAS_IPV6__ */
--              sizeof(char *)*(ALIAS_DIM) +
--          80/*namebuffer*/ + 2/* margin */];
-+                                      sizeof(char *)*(ALIAS_DIM) +
-+                                      80/*namebuffer*/ + 2/* margin */];
-     struct hostent *host;
--    LOCK;
-+    __UCLIBC_MUTEX_LOCK(mylock);
-     gethostent_r(&h, buf, sizeof(buf), &host, &h_errno);
--    UNLOCK;
-+    __UCLIBC_MUTEX_UNLOCK(mylock);
-     return(host);
- }
- #endif
-@@ -1652,23 +1633,23 @@ struct hostent *gethostent (void)
- #ifdef L_get_hosts_byname_r
- int __get_hosts_byname_r(const char * name, int type,
--                          struct hostent * result_buf,
--                          char * buf, size_t buflen,
--                          struct hostent ** result,
--                          int * h_errnop)
-+                                               struct hostent * result_buf,
-+                                               char * buf, size_t buflen,
-+                                               struct hostent ** result,
-+                                               int * h_errnop)
- {
-       return(__read_etc_hosts_r(NULL, name, type, GET_HOSTS_BYNAME,
--                  result_buf, buf, buflen, result, h_errnop));
-+                                                        result_buf, buf, buflen, result, h_errnop));
- }
- #endif
- #ifdef L_get_hosts_byaddr_r
- int __get_hosts_byaddr_r(const char * addr, int len, int type,
--                          struct hostent * result_buf,
--                          char * buf, size_t buflen,
--                          struct hostent ** result,
--                          int * h_errnop)
-+                                               struct hostent * result_buf,
-+                                               char * buf, size_t buflen,
-+                                               struct hostent ** result,
-+                                               int * h_errnop)
- {
- #ifndef __UCLIBC_HAS_IPV6__
-       char    ipaddr[INET_ADDRSTRLEN];
-@@ -1677,24 +1658,24 @@ int __get_hosts_byaddr_r(const char * ad
- #endif /* __UCLIBC_HAS_IPV6__ */
-     switch (type) {
--      case AF_INET:
--              if (len != sizeof(struct in_addr))
--                      return 0;
--              break;
-+              case AF_INET:
-+                      if (len != sizeof(struct in_addr))
-+                              return 0;
-+                      break;
- #ifdef __UCLIBC_HAS_IPV6__
--      case AF_INET6:
--              if (len != sizeof(struct in6_addr))
--                      return 0;
--              break;
-+              case AF_INET6:
-+                      if (len != sizeof(struct in6_addr))
-+                              return 0;
-+                      break;
- #endif /* __UCLIBC_HAS_IPV6__ */
--      default:
--              return 0;
-+              default:
-+                      return 0;
-       }
-       inet_ntop(type, addr, ipaddr, sizeof(ipaddr));
-       return(__read_etc_hosts_r(NULL, ipaddr, type, GET_HOSTS_BYADDR,
--                  result_buf, buf, buflen, result, h_errnop));
-+                                                        result_buf, buf, buflen, result, h_errnop));
- }
- #endif
-@@ -1705,8 +1686,8 @@ int __get_hosts_byaddr_r(const char * ad
- #endif /* min */
- int getnameinfo (const struct sockaddr *sa, socklen_t addrlen, char *host,
--           socklen_t hostlen, char *serv, socklen_t servlen,
--           unsigned int flags)
-+                               socklen_t hostlen, char *serv, socklen_t servlen,
-+                               unsigned int flags)
- {
-       int serrno = errno;
-       int ok = 0;
-@@ -1720,167 +1701,167 @@ int getnameinfo (const struct sockaddr *
-               return EAI_FAMILY;
-       switch (sa->sa_family) {
--      case AF_LOCAL:
--              break;
--      case AF_INET:
--              if (addrlen < sizeof (struct sockaddr_in))
--                      return EAI_FAMILY;
--              break;
-+              case AF_LOCAL:
-+                      break;
-+              case AF_INET:
-+                      if (addrlen < sizeof (struct sockaddr_in))
-+                              return EAI_FAMILY;
-+                      break;
- #ifdef __UCLIBC_HAS_IPV6__
--      case AF_INET6:
--              if (addrlen < sizeof (struct sockaddr_in6))
--                      return EAI_FAMILY;
--              break;
-+              case AF_INET6:
-+                      if (addrlen < sizeof (struct sockaddr_in6))
-+                              return EAI_FAMILY;
-+                      break;
- #endif /* __UCLIBC_HAS_IPV6__ */
--      default:
--              return EAI_FAMILY;
-+              default:
-+                      return EAI_FAMILY;
-       }
-       if (host != NULL && hostlen > 0)
-               switch (sa->sa_family) {
--              case AF_INET:
-+                      case AF_INET:
- #ifdef __UCLIBC_HAS_IPV6__
--              case AF_INET6:
-+                      case AF_INET6:
- #endif /* __UCLIBC_HAS_IPV6__ */
--                      if (!(flags & NI_NUMERICHOST)) {
-+                              if (!(flags & NI_NUMERICHOST)) {
- #ifdef __UCLIBC_HAS_IPV6__
--                              if (sa->sa_family == AF_INET6)
--                                      h = gethostbyaddr ((const void *)
--                                              &(((const struct sockaddr_in6 *) sa)->sin6_addr),
--                                              sizeof(struct in6_addr), AF_INET6);
--                              else
--#endif /* __UCLIBC_HAS_IPV6__ */
--                    h = gethostbyaddr ((const void *) &(((const struct sockaddr_in *)sa)->sin_addr),
--                                        sizeof(struct in_addr), AF_INET);
--
--                              if (h) {
--                                      char *c;
--                                      if ((flags & NI_NOFQDN)
--                                          && (getdomainname (domain, sizeof(domain)) == 0)
--                                          && (c = strstr (h->h_name, domain))
--                                          && (c != h->h_name) && (*(--c) == '.')) {
--                                              strncpy (host, h->h_name,
--                                                      min(hostlen, (size_t) (c - h->h_name)));
--                                              host[min(hostlen - 1, (size_t) (c - h->h_name))] = '\0';
--                                              ok = 1;
--                                      } else {
--                                              strncpy (host, h->h_name, hostlen);
--                                              ok = 1;
-+                                      if (sa->sa_family == AF_INET6)
-+                                              h = gethostbyaddr ((const void *)
-+                                                                                 &(((const struct sockaddr_in6 *) sa)->sin6_addr),
-+                                                                                 sizeof(struct in6_addr), AF_INET6);
-+                                      else
-+#endif /* __UCLIBC_HAS_IPV6__ */
-+                                              h = gethostbyaddr ((const void *) &(((const struct sockaddr_in *)sa)->sin_addr),
-+                                                                                 sizeof(struct in_addr), AF_INET);
-+
-+                                      if (h) {
-+                                              char *c;
-+                                              if ((flags & NI_NOFQDN)
-+                                                      && (getdomainname (domain, sizeof(domain)) == 0)
-+                                                      && (c = strstr (h->h_name, domain))
-+                                                      && (c != h->h_name) && (*(--c) == '.')) {
-+                                                      strncpy (host, h->h_name,
-+                                                                       min(hostlen, (size_t) (c - h->h_name)));
-+                                                      host[min(hostlen - 1, (size_t) (c - h->h_name))] = '\0';
-+                                                      ok = 1;
-+                                              } else {
-+                                                      strncpy (host, h->h_name, hostlen);
-+                                                      ok = 1;
-+                                              }
-                                       }
--                               }
--                      }
-+                              }
--                      if (!ok) {
--                              if (flags & NI_NAMEREQD) {
--                                      errno = serrno;
--                                      return EAI_NONAME;
--                              } else {
--                                      const char *c;
-+                              if (!ok) {
-+                                      if (flags & NI_NAMEREQD) {
-+                                              errno = serrno;
-+                                              return EAI_NONAME;
-+                                      } else {
-+                                              const char *c;
- #ifdef __UCLIBC_HAS_IPV6__
--                                      if (sa->sa_family == AF_INET6) {
--                                              const struct sockaddr_in6 *sin6p;
-+                                              if (sa->sa_family == AF_INET6) {
-+                                                      const struct sockaddr_in6 *sin6p;
--                                              sin6p = (const struct sockaddr_in6 *) sa;
-+                                                      sin6p = (const struct sockaddr_in6 *) sa;
--                                              c = inet_ntop (AF_INET6,
--                                                      (const void *) &sin6p->sin6_addr, host, hostlen);
-+                                                      c = inet_ntop (AF_INET6,
-+                                                                                 (const void *) &sin6p->sin6_addr, host, hostlen);
- #if 0
--                                              /* Does scope id need to be supported? */
--                                              uint32_t scopeid;
--                                              scopeid = sin6p->sin6_scope_id;
--                                              if (scopeid != 0) {
--                                                      /* Buffer is >= IFNAMSIZ+1.  */
--                                                      char scopebuf[IFNAMSIZ + 1];
--                                                      char *scopeptr;
--                                                      int ni_numericscope = 0;
--                                                      size_t real_hostlen = __strnlen (host, hostlen);
--                                                      size_t scopelen = 0;
--
--                                                      scopebuf[0] = SCOPE_DELIMITER;
--                                                      scopebuf[1] = '\0';
--                                                      scopeptr = &scopebuf[1];
--
--                                                      if (IN6_IS_ADDR_LINKLOCAL (&sin6p->sin6_addr)
--                                                          || IN6_IS_ADDR_MC_LINKLOCAL (&sin6p->sin6_addr)) {
--                                                              if (if_indextoname (scopeid, scopeptr) == NULL)
-+                                                      /* Does scope id need to be supported? */
-+                                                      uint32_t scopeid;
-+                                                      scopeid = sin6p->sin6_scope_id;
-+                                                      if (scopeid != 0) {
-+                                                              /* Buffer is >= IFNAMSIZ+1.  */
-+                                                              char scopebuf[IFNAMSIZ + 1];
-+                                                              char *scopeptr;
-+                                                              int ni_numericscope = 0;
-+                                                              size_t real_hostlen = __strnlen (host, hostlen);
-+                                                              size_t scopelen = 0;
-+
-+                                                              scopebuf[0] = SCOPE_DELIMITER;
-+                                                              scopebuf[1] = '\0';
-+                                                              scopeptr = &scopebuf[1];
-+
-+                                                              if (IN6_IS_ADDR_LINKLOCAL (&sin6p->sin6_addr)
-+                                                                      || IN6_IS_ADDR_MC_LINKLOCAL (&sin6p->sin6_addr)) {
-+                                                                      if (if_indextoname (scopeid, scopeptr) == NULL)
-+                                                                              ++ni_numericscope;
-+                                                                      else
-+                                                                              scopelen = strlen (scopebuf);
-+                                                              } else {
-                                                                       ++ni_numericscope;
--                                                              else
--                                                                      scopelen = strlen (scopebuf);
--                                                      } else {
--                                                              ++ni_numericscope;
--                                                      }
-+                                                              }
--                                                      if (ni_numericscope)
--                                                              scopelen = 1 + snprintf (scopeptr,
--                                                                      (scopebuf
--                                                                      + sizeof scopebuf
--                                                                      - scopeptr),
--                                                                      "%u", scopeid);
--
--                                                      if (real_hostlen + scopelen + 1 > hostlen)
--                                                              return EAI_SYSTEM;
--                                                      memcpy (host + real_hostlen, scopebuf, scopelen + 1);
--                                              }
-+                                                              if (ni_numericscope)
-+                                                                      scopelen = 1 + snprintf (scopeptr,
-+                                                                                                                       (scopebuf
-+                                                                                                                        + sizeof scopebuf
-+                                                                                                                        - scopeptr),
-+                                                                                                                       "%u", scopeid);
-+
-+                                                              if (real_hostlen + scopelen + 1 > hostlen)
-+                                                                      return EAI_SYSTEM;
-+                                                              memcpy (host + real_hostlen, scopebuf, scopelen + 1);
-+                                                      }
- #endif
--                                      } else
-+                                              } else
- #endif /* __UCLIBC_HAS_IPV6__ */
--                                              c = inet_ntop (AF_INET, (const void *)
--                                                      &(((const struct sockaddr_in *) sa)->sin_addr),
--                                                      host, hostlen);
--
--                                      if (c == NULL) {
--                                              errno = serrno;
--                                              return EAI_SYSTEM;
-+                                                      c = inet_ntop (AF_INET, (const void *)
-+                                                                                 &(((const struct sockaddr_in *) sa)->sin_addr),
-+                                                                                 host, hostlen);
-+
-+                                              if (c == NULL) {
-+                                                      errno = serrno;
-+                                                      return EAI_SYSTEM;
-+                                              }
-                                       }
-+                                      ok = 1;
-                               }
--                              ok = 1;
--                      }
--                      break;
--
--              case AF_LOCAL:
--                      if (!(flags & NI_NUMERICHOST)) {
--                              struct utsname utsname;
-+                              break;
--                              if (!uname (&utsname)) {
--                                      strncpy (host, utsname.nodename, hostlen);
--                                      break;
-+                      case AF_LOCAL:
-+                              if (!(flags & NI_NUMERICHOST)) {
-+                                      struct utsname utsname;
-+
-+                                      if (!uname (&utsname)) {
-+                                              strncpy (host, utsname.nodename, hostlen);
-+                                              break;
-+                                      };
-                               };
--                      };
--                      if (flags & NI_NAMEREQD) {
--                              errno = serrno;
--                              return EAI_NONAME;
--                      }
-+                              if (flags & NI_NAMEREQD) {
-+                                      errno = serrno;
-+                                      return EAI_NONAME;
-+                              }
--                      strncpy (host, "localhost", hostlen);
--                      break;
-+                              strncpy (host, "localhost", hostlen);
-+                              break;
--              default:
--                      return EAI_FAMILY;
--      }
-+                      default:
-+                              return EAI_FAMILY;
-+              }
-       if (serv && (servlen > 0)) {
-               switch (sa->sa_family) {
--              case AF_INET:
-+                      case AF_INET:
- #ifdef __UCLIBC_HAS_IPV6__
--              case AF_INET6:
-+                      case AF_INET6:
- #endif /* __UCLIBC_HAS_IPV6__ */
--                      if (!(flags & NI_NUMERICSERV)) {
--                              struct servent *s;
--                              s = getservbyport (((const struct sockaddr_in *) sa)->sin_port,
--                                    ((flags & NI_DGRAM) ? "udp" : "tcp"));
--                              if (s) {
--                                      strncpy (serv, s->s_name, servlen);
--                                      break;
-+                              if (!(flags & NI_NUMERICSERV)) {
-+                                      struct servent *s;
-+                                      s = getservbyport (((const struct sockaddr_in *) sa)->sin_port,
-+                                                                         ((flags & NI_DGRAM) ? "udp" : "tcp"));
-+                                      if (s) {
-+                                              strncpy (serv, s->s_name, servlen);
-+                                              break;
-+                                      }
-                               }
--                      }
--                      snprintf (serv, servlen, "%d",
--                              ntohs (((const struct sockaddr_in *) sa)->sin_port));
--                      break;
-+                              snprintf (serv, servlen, "%d",
-+                                                ntohs (((const struct sockaddr_in *) sa)->sin_port));
-+                              break;
--              case AF_LOCAL:
--                      strncpy (serv, ((const struct sockaddr_un *) sa)->sun_path, servlen);
--                      break;
-+                      case AF_LOCAL:
-+                              strncpy (serv, ((const struct sockaddr_un *) sa)->sun_path, servlen);
-+                              break;
-               }
-       }
-       if (host && (hostlen > 0))
-@@ -1896,10 +1877,10 @@ int getnameinfo (const struct sockaddr *
- #ifdef L_gethostbyname_r
- int gethostbyname_r(const char * name,
--                          struct hostent * result_buf,
--                          char * buf, size_t buflen,
--                          struct hostent ** result,
--                          int * h_errnop)
-+                                      struct hostent * result_buf,
-+                                      char * buf, size_t buflen,
-+                                      struct hostent ** result,
-+                                      int * h_errnop)
- {
-       struct in_addr *in;
-       struct in_addr **addr_list;
-@@ -1921,7 +1902,7 @@ int gethostbyname_r(const char * name,
-               __set_errno(0);                 /* to check for missing /etc/hosts. */
-               if ((i=__get_hosts_byname_r(name, AF_INET, result_buf,
--                              buf, buflen, result, h_errnop))==0)
-+                                                                      buf, buflen, result, h_errnop))==0)
-                       return i;
-               switch (*h_errnop) {
-                       case HOST_NOT_FOUND:
-@@ -1983,60 +1964,60 @@ int gethostbyname_r(const char * name,
-       for (;;) {
--          BIGLOCK;
-+          __UCLIBC_MUTEX_LOCK(__resolv_lock);
-           __nameserversXX=__nameservers;
-           __nameserverXX=__nameserver;
--          BIGUNLOCK;
-+          __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
-           a.buf = buf;
-           a.buflen = buflen;
-           a.add_count = 0;
-           i = __dns_lookup(name, T_A, __nameserversXX, __nameserverXX, &packet, &a);
-           if (i < 0) {
--              *h_errnop = HOST_NOT_FOUND;
--              DPRINTF("__dns_lookup\n");
--              return TRY_AGAIN;
-+                      *h_errnop = HOST_NOT_FOUND;
-+                      DPRINTF("__dns_lookup\n");
-+                      return TRY_AGAIN;
-           }
-           if ((a.rdlength + sizeof(struct in_addr*)) * a.add_count + 256 > buflen)
--          {
--              free(a.dotted);
--              free(packet);
--              *h_errnop = NETDB_INTERNAL;
--              DPRINTF("buffer too small for all addresses\n");
--              return ERANGE;
--          }
-+                      {
-+                              free(a.dotted);
-+                              free(packet);
-+                              *h_errnop = NETDB_INTERNAL;
-+                              DPRINTF("buffer too small for all addresses\n");
-+                              return ERANGE;
-+                      }
-           else if(a.add_count > 0)
--          {
--              memmove(buf - sizeof(struct in_addr*)*2, buf, a.add_count * a.rdlength);
--              addr_list = (struct in_addr**)(buf + a.add_count * a.rdlength);
--              addr_list[0] = in;
--              for (i = a.add_count-1; i>=0; --i)
--                  addr_list[i+1] = (struct in_addr*)(buf - sizeof(struct in_addr*)*2 + a.rdlength * i);
--              addr_list[a.add_count + 1] = 0;
--              buflen -= (((char*)&(addr_list[a.add_count + 2])) - buf);
--              buf = (char*)&addr_list[a.add_count + 2];
--          }
-+                      {
-+                              memmove(buf - sizeof(struct in_addr*)*2, buf, a.add_count * a.rdlength);
-+                              addr_list = (struct in_addr**)(buf + a.add_count * a.rdlength);
-+                              addr_list[0] = in;
-+                              for (i = a.add_count-1; i>=0; --i)
-+                                      addr_list[i+1] = (struct in_addr*)(buf - sizeof(struct in_addr*)*2 + a.rdlength * i);
-+                              addr_list[a.add_count + 1] = 0;
-+                              buflen -= (((char*)&(addr_list[a.add_count + 2])) - buf);
-+                              buf = (char*)&addr_list[a.add_count + 2];
-+                      }
-           strncpy(buf, a.dotted, buflen);
-           free(a.dotted);
-           if (a.atype == T_A) { /* ADDRESS */
--              memcpy(in, a.rdata, sizeof(*in));
--              result_buf->h_name = buf;
--              result_buf->h_addrtype = AF_INET;
--              result_buf->h_length = sizeof(*in);
--              result_buf->h_addr_list = (char **) addr_list;
-+                      memcpy(in, a.rdata, sizeof(*in));
-+                      result_buf->h_name = buf;
-+                      result_buf->h_addrtype = AF_INET;
-+                      result_buf->h_length = sizeof(*in);
-+                      result_buf->h_addr_list = (char **) addr_list;
- #ifdef __UCLIBC_MJN3_ONLY__
- #warning TODO -- generate the full list
- #endif
--              result_buf->h_aliases = alias; /* TODO: generate the full list */
--              free(packet);
--              break;
-+                      result_buf->h_aliases = alias; /* TODO: generate the full list */
-+                      free(packet);
-+                      break;
-           } else {
--              free(packet);
--              *h_errnop=HOST_NOT_FOUND;
--              return TRY_AGAIN;
-+                      free(packet);
-+                      *h_errnop=HOST_NOT_FOUND;
-+                      return TRY_AGAIN;
-           }
-       }
-@@ -2049,14 +2030,14 @@ int gethostbyname_r(const char * name,
- #ifdef L_gethostbyname2_r
- int gethostbyname2_r(const char *name, int family,
--                          struct hostent * result_buf,
--                          char * buf, size_t buflen,
--                          struct hostent ** result,
--                          int * h_errnop)
-+                                       struct hostent * result_buf,
-+                                       char * buf, size_t buflen,
-+                                       struct hostent ** result,
-+                                       int * h_errnop)
- {
- #ifndef __UCLIBC_HAS_IPV6__
-       return family == (AF_INET)? gethostbyname_r(name, result_buf,
--              buf, buflen, result, h_errnop) : HOST_NOT_FOUND;
-+                                                                                              buf, buflen, result, h_errnop) : HOST_NOT_FOUND;
- #else /* __UCLIBC_HAS_IPV6__ */
-       struct in6_addr *in;
-       struct in6_addr **addr_list;
-@@ -2084,7 +2065,7 @@ int gethostbyname2_r(const char *name, i
-               __set_errno(0);                 /* to check for missing /etc/hosts. */
-               if ((i=__get_hosts_byname_r(name, AF_INET, result_buf,
--                              buf, buflen, result, h_errnop))==0)
-+                                                                      buf, buflen, result, h_errnop))==0)
-                       return i;
-               switch (*h_errnop) {
-                       case HOST_NOT_FOUND:
-@@ -2137,10 +2118,10 @@ int gethostbyname2_r(const char *name, i
-       memset((char *) &a, '\0', sizeof(a));
-       for (;;) {
--      BIGLOCK;
--      __nameserversXX=__nameservers;
--      __nameserverXX=__nameserver;
--      BIGUNLOCK;
-+              __UCLIBC_MUTEX_LOCK(__resolv_lock);
-+              __nameserversXX=__nameservers;
-+              __nameserverXX=__nameserver;
-+              __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
-               i = __dns_lookup(buf, T_AAAA, __nameserversXX, __nameserverXX, &packet, &a);
-@@ -2190,10 +2171,10 @@ int gethostbyname2_r(const char *name, i
- #ifdef L_gethostbyaddr_r
- int gethostbyaddr_r (const void *addr, socklen_t len, int type,
--                          struct hostent * result_buf,
--                          char * buf, size_t buflen,
--                          struct hostent ** result,
--                          int * h_errnop)
-+                                       struct hostent * result_buf,
-+                                       char * buf, size_t buflen,
-+                                       struct hostent ** result,
-+                                       int * h_errnop)
- {
-       struct in_addr *in;
-@@ -2234,7 +2215,7 @@ int gethostbyaddr_r (const void *addr, s
-       /* do /etc/hosts first */
-       if ((i=__get_hosts_byaddr_r(addr, len, type, result_buf,
--                                buf, buflen, result, h_errnop))==0)
-+                                                              buf, buflen, result, h_errnop))==0)
-               return i;
-       switch (*h_errnop) {
-               case HOST_NOT_FOUND:
-@@ -2294,7 +2275,7 @@ int gethostbyaddr_r (const void *addr, s
-               addr_list[0] = in;
-               sprintf(buf, "%u.%u.%u.%u.in-addr.arpa",
--                      tmp_addr[3], tmp_addr[2], tmp_addr[1], tmp_addr[0]);
-+                              tmp_addr[3], tmp_addr[2], tmp_addr[1], tmp_addr[0]);
- #ifdef __UCLIBC_HAS_IPV6__
-       } else {
-               memcpy(in6->s6_addr, addr, len);
-@@ -2304,7 +2285,7 @@ int gethostbyaddr_r (const void *addr, s
-               for (i = len - 1; i >= 0; i--) {
-                       qp += sprintf(qp, "%x.%x.", in6->s6_addr[i] & 0xf,
--                              (in6->s6_addr[i] >> 4) & 0xf);
-+                                                (in6->s6_addr[i] >> 4) & 0xf);
-       }
-       strcpy(qp, "ip6.int");
- #endif /* __UCLIBC_HAS_IPV6__ */
-@@ -2314,10 +2295,10 @@ int gethostbyaddr_r (const void *addr, s
-       for (;;) {
--      BIGLOCK;
--      __nameserversXX=__nameservers;
--      __nameserverXX=__nameserver;
--      BIGUNLOCK;
-+              __UCLIBC_MUTEX_LOCK(__resolv_lock);
-+              __nameserversXX=__nameservers;
-+              __nameserverXX=__nameserver;
-+              __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
-               i = __dns_lookup(buf, T_PTR, __nameserversXX, __nameserverXX, &packet, &a);
-               if (i < 0) {
-@@ -2381,7 +2362,7 @@ int gethostbyaddr_r (const void *addr, s
-  * Return size of compressed name or -1 if there was an error.
-  */
- int __dn_expand(const u_char *msg, const u_char *eom, const u_char *src,
--          char *dst, int dstsiz)
-+                              char *dst, int dstsiz)
- {
-       int n = ns_name_uncompress(msg, eom, src, dst, (size_t)dstsiz);
-@@ -2401,7 +2382,7 @@ int __dn_expand(const u_char *msg, const
-  */
- static int printable(int ch)
- {
--        return (ch > 0x20 && ch < 0x7f);
-+      return (ch > 0x20 && ch < 0x7f);
- }
- /*
-@@ -2413,18 +2394,18 @@ static int printable(int ch)
-  */
- static int special(int ch)
- {
--        switch (ch) {
-+      switch (ch) {
-         case 0x22: /* '"' */
-         case 0x2E: /* '.' */
-         case 0x3B: /* ';' */
-         case 0x5C: /* '\\' */
--        /* Special modifiers in zone files. */
-+                      /* Special modifiers in zone files. */
-         case 0x40: /* '@' */
-         case 0x24: /* '$' */
--                return (1);
-+                      return (1);
-         default:
--                return (0);
--        }
-+                      return (0);
-+      }
- }
- /*
-@@ -2436,7 +2417,7 @@ static int special(int ch)
-  *      Root domain returns as "." not "".
-  */
- int __ns_name_uncompress(const u_char *msg, const u_char *eom,
--              const u_char *src, char *dst, size_t dstsiz)
-+                                               const u_char *src, char *dst, size_t dstsiz)
- {
-       u_char tmp[NS_MAXCDNAME];
-       int n;
-@@ -2525,7 +2506,7 @@ int __ns_name_ntop(const u_char *src, ch
-               return (-1);
-       }
-       *dn++ = '\0';
--        return (dn - dst);
-+      return (dn - dst);
- }
- /*
-@@ -2535,7 +2516,7 @@ int __ns_name_ntop(const u_char *src, ch
-  *      -1 if it fails, or consumed octets if it succeeds.
-  */
- int __ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src,
--               u_char *dst, size_t dstsiz)
-+                                       u_char *dst, size_t dstsiz)
- {
-       const u_char *srcp, *dstlim;
-       u_char *dstp;
-@@ -2554,46 +2535,46 @@ int __ns_name_unpack(const u_char *msg, 
-       while ((n = *srcp++) != 0) {
-               /* Check for indirection. */
-               switch (n & NS_CMPRSFLGS) {
--              case 0:
--                      /* Limit checks. */
--                      if (dstp + n + 1 >= dstlim || srcp + n >= eom) {
--                              __set_errno (EMSGSIZE);
--                              return (-1);
--                      }
--                      checked += n + 1;
--                      *dstp++ = n;
--                      memcpy(dstp, srcp, n);
--                      dstp += n;
--                      srcp += n;
--                      break;
-+                      case 0:
-+                              /* Limit checks. */
-+                              if (dstp + n + 1 >= dstlim || srcp + n >= eom) {
-+                                      __set_errno (EMSGSIZE);
-+                                      return (-1);
-+                              }
-+                              checked += n + 1;
-+                              *dstp++ = n;
-+                              memcpy(dstp, srcp, n);
-+                              dstp += n;
-+                              srcp += n;
-+                              break;
--              case NS_CMPRSFLGS:
--                      if (srcp >= eom) {
--                              __set_errno (EMSGSIZE);
--                              return (-1);
--                      }
--                      if (len < 0)
--                              len = srcp - src + 1;
--                      srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff));
--                      if (srcp < msg || srcp >= eom) {  /* Out of range. */
--                              __set_errno (EMSGSIZE);
--                              return (-1);
--                      }
--                      checked += 2;
--                      /*
--                       * Check for loops in the compressed name;
--                       * if we've looked at the whole message,
--                       * there must be a loop.
--                       */
--                      if (checked >= eom - msg) {
--                              __set_errno (EMSGSIZE);
--                              return (-1);
--                      }
--                      break;
-+                      case NS_CMPRSFLGS:
-+                              if (srcp >= eom) {
-+                                      __set_errno (EMSGSIZE);
-+                                      return (-1);
-+                              }
-+                              if (len < 0)
-+                                      len = srcp - src + 1;
-+                              srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff));
-+                              if (srcp < msg || srcp >= eom) {  /* Out of range. */
-+                                      __set_errno (EMSGSIZE);
-+                                      return (-1);
-+                              }
-+                              checked += 2;
-+                              /*
-+                               * Check for loops in the compressed name;
-+                               * if we've looked at the whole message,
-+                               * there must be a loop.
-+                               */
-+                              if (checked >= eom - msg) {
-+                                      __set_errno (EMSGSIZE);
-+                                      return (-1);
-+                              }
-+                              break;
--              default:
--                      __set_errno (EMSGSIZE);
--                      return (-1);                    /* flag error */
-+                      default:
-+                              __set_errno (EMSGSIZE);
-+                              return (-1);                    /* flag error */
-               }
-       }
-       *dstp = '\0';
-diff --git a/libc/inet/rpc/create_xid.c b/libc/inet/rpc/create_xid.c
-index cbb961e..c86cbb4 100644
---- a/libc/inet/rpc/create_xid.c
-+++ b/libc/inet/rpc/create_xid.c
-@@ -27,15 +27,7 @@
- /* The RPC code is not threadsafe, but new code should be threadsafe. */
--#ifdef __UCLIBC_HAS_THREADS__
--#include <pthread.h>
--static pthread_mutex_t createxid_lock = PTHREAD_MUTEX_INITIALIZER;
--# define LOCK __pthread_mutex_lock(&createxid_lock)
--# define UNLOCK       __pthread_mutex_unlock(&createxid_lock);
--#else
--# define LOCK
--# define UNLOCK
--#endif
-+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER);
- static int is_initialized;
- static struct drand48_data __rpc_lrand48_data;
-@@ -43,22 +35,22 @@ static struct drand48_data __rpc_lrand48
- unsigned long
- _create_xid (void)
- {
--  unsigned long res;
-+      unsigned long res;
--  LOCK;
-+      __UCLIBC_MUTEX_LOCK(mylock);
--  if (!is_initialized)
--    {
--      struct timeval now;
-+      if (!is_initialized)
-+              {
-+                      struct timeval now;
--      gettimeofday (&now, (struct timezone *) 0);
--      srand48_r (now.tv_sec ^ now.tv_usec, &__rpc_lrand48_data);
--      is_initialized = 1;
--    }
-+                      gettimeofday (&now, (struct timezone *) 0);
-+                      srand48_r (now.tv_sec ^ now.tv_usec, &__rpc_lrand48_data);
-+                      is_initialized = 1;
-+              }
--  lrand48_r (&__rpc_lrand48_data, &res);
-+      lrand48_r (&__rpc_lrand48_data, &res);
--  UNLOCK;
-+      __UCLIBC_MUTEX_UNLOCK(mylock);
--  return res;
-+      return res;
- }
-diff --git a/libc/misc/dirent/closedir.c b/libc/misc/dirent/closedir.c
-index 068e2d3..56adb23 100644
---- a/libc/misc/dirent/closedir.c
-+++ b/libc/misc/dirent/closedir.c
-@@ -4,7 +4,6 @@
- #include <unistd.h>
- #include "dirstream.h"
--
- int closedir(DIR * dir)
- {
-       int fd;
-@@ -19,14 +18,10 @@ int closedir(DIR * dir)
-               __set_errno(EBADF);
-               return -1;
-       }
--#ifdef __UCLIBC_HAS_THREADS__
--      __pthread_mutex_lock(&(dir->dd_lock));
--#endif
-+      __UCLIBC_MUTEX_LOCK(dir->dd_lock);
-       fd = dir->dd_fd;
-       dir->dd_fd = -1;
--#ifdef __UCLIBC_HAS_THREADS__
--      __pthread_mutex_unlock(&(dir->dd_lock));
--#endif
-+      __UCLIBC_MUTEX_UNLOCK(dir->dd_lock);
-       free(dir->dd_buf);
-       free(dir);
-       return close(fd);
-diff --git a/libc/misc/dirent/dirstream.h b/libc/misc/dirent/dirstream.h
-index 2dd0264..bd721c5 100644
---- a/libc/misc/dirent/dirstream.h
-+++ b/libc/misc/dirent/dirstream.h
-@@ -26,9 +26,8 @@ Cambridge, MA 02139, USA.  */
- #include <features.h>
- #include <sys/types.h>
--#ifdef __UCLIBC_HAS_THREADS__
--#include <pthread.h>
--#endif
-+
-+#include <bits/uClibc_mutex.h>
- /* For now, syscall readdir () only supports one entry at a time. It
-  * will be changed in the future.
-@@ -63,11 +62,7 @@ struct __dirstream {
-   size_t dd_max;
-  
-   /* lock */
--#ifdef __UCLIBC_HAS_THREADS__
--  pthread_mutex_t dd_lock;
--#else
--  void *dd_lock;
--#endif
-+  __UCLIBC_MUTEX(dd_lock);
- };                            /* stream data from opendir() */
-diff --git a/libc/misc/dirent/readdir.c b/libc/misc/dirent/readdir.c
-index 1f196e1..c55317a 100644
---- a/libc/misc/dirent/readdir.c
-+++ b/libc/misc/dirent/readdir.c
-@@ -5,7 +5,6 @@
- #include <dirent.h>
- #include "dirstream.h"
--
- struct dirent *readdir(DIR * dir)
- {
-       ssize_t bytes;
-@@ -16,9 +15,7 @@ struct dirent *readdir(DIR * dir)
-               return NULL;
-       }
--#ifdef __UCLIBC_HAS_THREADS__
--      __pthread_mutex_lock(&(dir->dd_lock));
--#endif
-+      __UCLIBC_MUTEX_LOCK(dir->dd_lock);
-       do {
-           if (dir->dd_size <= dir->dd_nextloc) {
-@@ -44,8 +41,6 @@ struct dirent *readdir(DIR * dir)
-       } while (de->d_ino == 0);
- all_done:
--#ifdef __UCLIBC_HAS_THREADS__
--      __pthread_mutex_unlock(&(dir->dd_lock));
--#endif
-+      __UCLIBC_MUTEX_UNLOCK(dir->dd_lock);
-       return de;
- }
-diff --git a/libc/misc/dirent/readdir64.c b/libc/misc/dirent/readdir64.c
-index f798c6f..6da3b0d 100644
---- a/libc/misc/dirent/readdir64.c
-+++ b/libc/misc/dirent/readdir64.c
-@@ -20,7 +20,6 @@
- #include <dirent.h>
- #include "dirstream.h"
--
- struct dirent64 *readdir64(DIR * dir)
- {
-       ssize_t bytes;
-@@ -31,9 +30,7 @@ struct dirent64 *readdir64(DIR * dir)
-               return NULL;
-       }
--#ifdef __UCLIBC_HAS_THREADS__
--      __pthread_mutex_lock(&(dir->dd_lock));
--#endif
-+      __UCLIBC_MUTEX_LOCK(dir->dd_lock);
-       do {
-           if (dir->dd_size <= dir->dd_nextloc) {
-@@ -59,9 +56,7 @@ struct dirent64 *readdir64(DIR * dir)
-       } while (de->d_ino == 0);
- all_done:
--#ifdef __UCLIBC_HAS_THREADS__
--      __pthread_mutex_unlock(&(dir->dd_lock));
--#endif
-+      __UCLIBC_MUTEX_UNLOCK(dir->dd_lock);
-       return de;
- }
-diff --git a/libc/misc/dirent/readdir64_r.c b/libc/misc/dirent/readdir64_r.c
-index da3564e..cc96eff 100644
---- a/libc/misc/dirent/readdir64_r.c
-+++ b/libc/misc/dirent/readdir64_r.c
-@@ -19,7 +19,6 @@
- #include <dirent.h>
- #include "dirstream.h"
--
- int readdir64_r(DIR *dir, struct dirent64 *entry, struct dirent64 **result)
- {
-       int ret;
-@@ -32,21 +31,19 @@ int readdir64_r(DIR *dir, struct dirent6
-       }
-       de = NULL;
--#ifdef __UCLIBC_HAS_THREADS__
--      __pthread_mutex_lock(&(dir->dd_lock));
--#endif
-+      __UCLIBC_MUTEX_LOCK(dir->dd_lock);
-       do {
-           if (dir->dd_size <= dir->dd_nextloc) {
--              /* read dir->dd_max bytes of directory entries. */
--              bytes = __getdents64(dir->dd_fd, dir->dd_buf, dir->dd_max);
--              if (bytes <= 0) {
--                  *result = NULL;
--                  ret = errno;
--                  goto all_done;
--              }
--              dir->dd_size = bytes;
--              dir->dd_nextloc = 0;
-+                      /* read dir->dd_max bytes of directory entries. */
-+                      bytes = __getdents64(dir->dd_fd, dir->dd_buf, dir->dd_max);
-+                      if (bytes <= 0) {
-+                              *result = NULL;
-+                              ret = errno;
-+                              goto all_done;
-+                      }
-+                      dir->dd_size = bytes;
-+                      dir->dd_nextloc = 0;
-           }
-           de = (struct dirent64 *) (((char *) dir->dd_buf) + dir->dd_nextloc);
-@@ -66,12 +63,10 @@ int readdir64_r(DIR *dir, struct dirent6
-       }
-       ret = 0;
--all_done:
-+ all_done:
--#ifdef __UCLIBC_HAS_THREADS__
--      __pthread_mutex_unlock(&(dir->dd_lock));
--#endif
--        return((de != NULL)? 0 : ret);
-+      __UCLIBC_MUTEX_UNLOCK(dir->dd_lock);
-+      return((de != NULL)? 0 : ret);
- }
- #endif /* __UCLIBC_HAS_LFS__ */
-diff --git a/libc/misc/dirent/readdir_r.c b/libc/misc/dirent/readdir_r.c
-index 245dcbd..aeccdd8 100644
---- a/libc/misc/dirent/readdir_r.c
-+++ b/libc/misc/dirent/readdir_r.c
-@@ -5,7 +5,6 @@
- #include <dirent.h>
- #include "dirstream.h"
--
- int readdir_r(DIR *dir, struct dirent *entry, struct dirent **result)
- {
-       int ret;
-@@ -18,21 +17,19 @@ int readdir_r(DIR *dir, struct dirent *e
-       }
-       de = NULL;
--#ifdef __UCLIBC_HAS_THREADS__
--      __pthread_mutex_lock(&(dir->dd_lock));
--#endif
-+      __UCLIBC_MUTEX_LOCK(dir->dd_lock);
-       do {
-           if (dir->dd_size <= dir->dd_nextloc) {
--              /* read dir->dd_max bytes of directory entries. */
--              bytes = __getdents(dir->dd_fd, dir->dd_buf, dir->dd_max);
--              if (bytes <= 0) {
--                  *result = NULL;
--                  ret = errno;
--                  goto all_done;
--              }
--              dir->dd_size = bytes;
--              dir->dd_nextloc = 0;
-+                      /* read dir->dd_max bytes of directory entries. */
-+                      bytes = __getdents(dir->dd_fd, dir->dd_buf, dir->dd_max);
-+                      if (bytes <= 0) {
-+                              *result = NULL;
-+                              ret = errno;
-+                              goto all_done;
-+                      }
-+                      dir->dd_size = bytes;
-+                      dir->dd_nextloc = 0;
-           }
-           de = (struct dirent *) (((char *) dir->dd_buf) + dir->dd_nextloc);
-@@ -52,10 +49,8 @@ int readdir_r(DIR *dir, struct dirent *e
-       }
-       ret = 0;
--all_done:
-+ all_done:
--#ifdef __UCLIBC_HAS_THREADS__
--      __pthread_mutex_unlock(&(dir->dd_lock));
--#endif
--        return((de != NULL)? 0 : ret);
-+      __UCLIBC_MUTEX_UNLOCK(dir->dd_lock);
-+      return((de != NULL)? 0 : ret);
- }
-diff --git a/libc/misc/dirent/rewinddir.c b/libc/misc/dirent/rewinddir.c
-index 60ef71d..fe8fc2a 100644
---- a/libc/misc/dirent/rewinddir.c
-+++ b/libc/misc/dirent/rewinddir.c
-@@ -3,7 +3,6 @@
- #include <unistd.h>
- #include "dirstream.h"
--
- /* rewinddir() just does an lseek(fd,0,0) - see close for comments */
- void rewinddir(DIR * dir)
- {
-@@ -11,12 +10,8 @@ void rewinddir(DIR * dir)
-               __set_errno(EBADF);
-               return;
-       }
--#ifdef __UCLIBC_HAS_THREADS__
--      __pthread_mutex_lock(&(dir->dd_lock));
--#endif
-+      __UCLIBC_MUTEX_LOCK(dir->dd_lock);
-       lseek(dir->dd_fd, 0, SEEK_SET);
-       dir->dd_nextoff = dir->dd_nextloc = dir->dd_size = 0;
--#ifdef __UCLIBC_HAS_THREADS__
--      __pthread_mutex_unlock(&(dir->dd_lock));
--#endif
-+      __UCLIBC_MUTEX_UNLOCK(dir->dd_lock);
- }
-diff --git a/libc/misc/dirent/seekdir.c b/libc/misc/dirent/seekdir.c
-index 139f1e1..6d6f5f0 100644
---- a/libc/misc/dirent/seekdir.c
-+++ b/libc/misc/dirent/seekdir.c
-@@ -3,19 +3,14 @@
- #include <unistd.h>
- #include "dirstream.h"
--
- void seekdir(DIR * dir, long int offset)
- {
-       if (!dir) {
-               __set_errno(EBADF);
-               return;
-       }
--#ifdef __UCLIBC_HAS_THREADS__
--      __pthread_mutex_lock(&(dir->dd_lock));
--#endif
-+      __UCLIBC_MUTEX_LOCK(dir->dd_lock);
-       dir->dd_nextoff = lseek(dir->dd_fd, offset, SEEK_SET);
-       dir->dd_size = dir->dd_nextloc = 0;
--#ifdef __UCLIBC_HAS_THREADS__
--      __pthread_mutex_unlock(&(dir->dd_lock));
--#endif
-+      __UCLIBC_MUTEX_UNLOCK(dir->dd_lock);
- }
-diff --git a/libc/misc/mntent/mntent.c b/libc/misc/mntent/mntent.c
-index d98a687..af6d848 100644
---- a/libc/misc/mntent/mntent.c
-+++ b/libc/misc/mntent/mntent.c
-@@ -3,15 +3,9 @@
- #include <string.h>
- #include <mntent.h>
--#ifdef __UCLIBC_HAS_THREADS__
--#include <pthread.h>
--static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;
--# define LOCK __pthread_mutex_lock(&mylock)
--# define UNLOCK       __pthread_mutex_unlock(&mylock);
--#else
--# define LOCK
--# define UNLOCK
--#endif
-+#include <bits/uClibc_mutex.h>
-+
-+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER);
- /* Reentrant version of getmntent.  */
- struct mntent *getmntent_r (FILE *filep, 
-@@ -67,7 +61,7 @@ struct mntent *getmntent(FILE * filep)
-     struct mntent *tmp;
-     static char *buff = NULL;
-     static struct mntent mnt;
--    LOCK;
-+    __UCLIBC_MUTEX_LOCK(mylock);
-     
-     if (!buff) {
-             buff = malloc(BUFSIZ);
-@@ -76,7 +70,7 @@ struct mntent *getmntent(FILE * filep)
-     }
-     
-     tmp = getmntent_r(filep, &mnt, buff, BUFSIZ);
--    UNLOCK;
-+    __UCLIBC_MUTEX_UNLOCK(mylock);
-     return(tmp);
- }
-diff --git a/libc/misc/pthread/weaks.c b/libc/misc/pthread/weaks.c
-index 89c2611..c27bd10 100644
---- a/libc/misc/pthread/weaks.c
-+++ b/libc/misc/pthread/weaks.c
-@@ -21,6 +21,7 @@
- #include <limits.h>
- #include <stdlib.h>
-+static void __pthread_return_void __P ((void));
- static int __pthread_return_0 __P ((void));
- static int __pthread_return_1 __P ((void));
-@@ -104,8 +105,17 @@ weak_alias (__pthread_return_0, __pthrea
- weak_alias (__pthread_return_0, __pthread_mutex_trylock)
- weak_alias (__pthread_return_0, __pthread_mutex_unlock)
-+weak_alias (__pthread_return_void, _pthread_cleanup_push_defer)
-+weak_alias (__pthread_return_void, _pthread_cleanup_pop_restore)
-+
- /**********************************************************************/
-+static void
-+__pthread_return_void (void)
-+{
-+  return;
-+}
-+
- static int
- __pthread_return_0 (void)
- {
-diff --git a/libc/misc/syslog/syslog.c b/libc/misc/syslog/syslog.c
-index 2b478e1..9e9ddbf 100644
---- a/libc/misc/syslog/syslog.c
-+++ b/libc/misc/syslog/syslog.c
-@@ -80,17 +80,9 @@
- #include <ctype.h>
- #include <signal.h>
-+#include <bits/uClibc_mutex.h>
--#ifdef __UCLIBC_HAS_THREADS__
--#include <pthread.h>
--static pthread_mutex_t mylock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
--# define LOCK __pthread_mutex_lock(&mylock)
--# define UNLOCK       __pthread_mutex_unlock(&mylock);
--#else
--# define LOCK
--# define UNLOCK
--#endif
--
-+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);
- static int    LogFile = -1;           /* fd for log */
- static int    connected;              /* have done connect */
-@@ -110,26 +102,26 @@ int setlogmask(int pmask);
- static void 
- closelog_intern(int to_default)
- {
--      LOCK;
-+      __UCLIBC_MUTEX_LOCK(mylock);
-       if (LogFile != -1) {
-           (void) close(LogFile);
-       }
-       LogFile = -1;
-       connected = 0;
-       if (to_default)
--      {
--              LogStat = 0;
--              LogTag = "syslog";
--              LogFacility = LOG_USER;
--              LogMask = 0xff;
--      }
--      UNLOCK;
-+              {
-+                      LogStat = 0;
-+                      LogTag = "syslog";
-+                      LogFacility = LOG_USER;
-+                      LogMask = 0xff;
-+              }
-+      __UCLIBC_MUTEX_UNLOCK(mylock);
- }
- static void
- sigpipe_handler (int sig)
- {
--  closelog_intern (0);
-+      closelog_intern (0);
- }
- /*
-@@ -165,7 +157,7 @@ vsyslog( int pri, const char *fmt, va_li
-       saved_errno = errno;
--      LOCK;
-+      __UCLIBC_MUTEX_LOCK(mylock);
-       /* See if we should just throw out this message. */
-       if (!(LogMask & LOG_MASK(LOG_PRI(pri))) || (pri &~ (LOG_PRIMASK|LOG_FACMASK)))
-@@ -208,7 +200,7 @@ vsyslog( int pri, const char *fmt, va_li
-       if (p >= end || p < head_end) { /* Returned -1 in case of error... */
-               static const char truncate_msg[12] = "[truncated] ";
-               memmove(head_end + sizeof(truncate_msg), head_end,
--                      end - head_end - sizeof(truncate_msg));
-+                              end - head_end - sizeof(truncate_msg));
-               memcpy(head_end, truncate_msg, sizeof(truncate_msg));
-               if (p < head_end) {
-                       while (p < end && *p) {
-@@ -261,11 +253,11 @@ vsyslog( int pri, const char *fmt, va_li
-               (void)close(fd);
-       }
--getout:
--      UNLOCK;
-+ getout:
-+      __UCLIBC_MUTEX_UNLOCK(mylock);
-       if (sigpipe == 0)
-               sigaction (SIGPIPE, &oldaction,
--                      (struct sigaction *) NULL);
-+                                 (struct sigaction *) NULL);
- }
- /*
-@@ -276,48 +268,48 @@ openlog( const char *ident, int logstat,
- {
-     int logType = SOCK_DGRAM;
--    LOCK;
-+    __UCLIBC_MUTEX_LOCK(mylock);
-     if (ident != NULL)
--      LogTag = ident;
-+              LogTag = ident;
-     LogStat = logstat;
-     if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0)
--      LogFacility = logfac;
-+              LogFacility = logfac;
-     if (LogFile == -1) {
--      SyslogAddr.sa_family = AF_UNIX;
--      (void)strncpy(SyslogAddr.sa_data, _PATH_LOG,
--                    sizeof(SyslogAddr.sa_data));
--retry:
--      if (LogStat & LOG_NDELAY) {
--          if ((LogFile = socket(AF_UNIX, logType, 0)) == -1){
--              UNLOCK;
--              return;
--          }
--          /*                  fcntl(LogFile, F_SETFD, 1); */
--      }
-+              SyslogAddr.sa_family = AF_UNIX;
-+              (void)strncpy(SyslogAddr.sa_data, _PATH_LOG,
-+                                        sizeof(SyslogAddr.sa_data));
-+      retry:
-+              if (LogStat & LOG_NDELAY) {
-+                      if ((LogFile = socket(AF_UNIX, logType, 0)) == -1){
-+                              goto DONE;
-+                      }
-+                      /*                      fcntl(LogFile, F_SETFD, 1); */
-+              }
-     }
-     if (LogFile != -1 && !connected) {
--      if (connect(LogFile, &SyslogAddr, sizeof(SyslogAddr) - 
--                  sizeof(SyslogAddr.sa_data) + strlen(SyslogAddr.sa_data)) != -1)
--      {
--          connected = 1;
--      } else if (logType == SOCK_DGRAM) {
--          logType = SOCK_STREAM;
--          if (LogFile != -1) {
--              close(LogFile);
--              LogFile = -1;
--          }
--          goto retry;
--      } else {
--          if (LogFile != -1) {
--              close(LogFile);
--              LogFile = -1;
--          }
--      }
-+              if (connect(LogFile, &SyslogAddr, sizeof(SyslogAddr) - 
-+                                      sizeof(SyslogAddr.sa_data) + strlen(SyslogAddr.sa_data)) != -1)
-+                      {
-+                              connected = 1;
-+                      } else if (logType == SOCK_DGRAM) {
-+                              logType = SOCK_STREAM;
-+                              if (LogFile != -1) {
-+                                      close(LogFile);
-+                                      LogFile = -1;
-+                              }
-+                              goto retry;
-+                      } else {
-+                              if (LogFile != -1) {
-+                                      close(LogFile);
-+                                      LogFile = -1;
-+                              }
-+                      }
-     }
--    UNLOCK;
-+ DONE:
-+    __UCLIBC_MUTEX_UNLOCK(mylock);
- }
- /*
-@@ -335,10 +327,10 @@ int setlogmask(int pmask)
-     int omask;
-     omask = LogMask;
--    LOCK;
-+    __UCLIBC_MUTEX_LOCK(mylock);
-     if (pmask != 0)
--      LogMask = pmask;
--    UNLOCK;
-+              LogMask = pmask;
-+    __UCLIBC_MUTEX_UNLOCK(mylock);
-     return (omask);
- }
-diff --git a/libc/misc/time/time.c b/libc/misc/time/time.c
-index f43bb8a..6165a52 100644
---- a/libc/misc/time/time.c
-+++ b/libc/misc/time/time.c
-@@ -143,6 +143,8 @@
- #include <locale.h>
- #include <bits/uClibc_uintmaxtostr.h>
-+#include <bits/uClibc_mutex.h>
-+
- #ifdef __UCLIBC_HAS_XLOCALE__
- #include <xlocale.h>
- #endif
-@@ -191,21 +193,7 @@ typedef struct {
-       char tzname[TZNAME_MAX+1];
- } rule_struct;
--#ifdef __UCLIBC_HAS_THREADS__
--
--#include <pthread.h>
--
--extern pthread_mutex_t _time_tzlock;
--
--#define TZLOCK                __pthread_mutex_lock(&_time_tzlock)
--#define TZUNLOCK      __pthread_mutex_unlock(&_time_tzlock)
--
--#else
--
--#define TZLOCK                ((void) 0)
--#define TZUNLOCK      ((void) 0)
--
--#endif
-+__UCLIBC_MUTEX_EXTERN(_time_tzlock);
- extern rule_struct _time_tzinfo[2];
-@@ -542,13 +530,13 @@ struct tm *localtime(const time_t *timer
- struct tm *localtime_r(register const time_t *__restrict timer,
-                                          register struct tm *__restrict result)
- {
--      TZLOCK;
-+      __UCLIBC_MUTEX_LOCK(_time_tzlock);
-       tzset();
-       __time_localtime_tzi(timer, result, _time_tzinfo);
--      TZUNLOCK;
-+      __UCLIBC_MUTEX_UNLOCK(_time_tzlock);
-       return result;
- }
-@@ -1037,7 +1025,7 @@ size_t __XL(strftime)(char *__restrict s
-                       goto LOOP;
-               }
--              o = spec + 26;          /* set to "????" */
-+              o = ((const char *) spec) + 26; /* set to "????" */
-               if ((code & MASK_SPEC) == CALC_SPEC) {
-                       if (*p == 's') {
-@@ -1073,17 +1061,15 @@ size_t __XL(strftime)(char *__restrict s
- #ifdef __UCLIBC_HAS_TM_EXTENSIONS__
--#define RSP_TZUNLOCK  ((void) 0)
- #define RSP_TZNAME            timeptr->tm_zone
- #define RSP_GMT_OFFSET        (-timeptr->tm_gmtoff)
- #else
--#define RSP_TZUNLOCK  TZUNLOCK
- #define RSP_TZNAME            rsp->tzname
- #define RSP_GMT_OFFSET        rsp->gmt_offset
--                              TZLOCK;
-+                              __UCLIBC_MUTEX_LOCK(_time_tzlock);
-                               rsp = _time_tzinfo;
-                               if (timeptr->tm_isdst > 0) {
-@@ -1114,15 +1100,17 @@ size_t __XL(strftime)(char *__restrict s
-                                       }
- #endif
-                                       o_count = SIZE_MAX;
--                                      RSP_TZUNLOCK;
-+/*                                    RSP_TZUNLOCK; */
-+#ifdef __UCLIBC_HAS_TM_EXTENSIONS__
-                                       goto OUTPUT;
-+#endif
-                               } else {                /* z */
-                                       *s = '+';
-                                       if ((tzo = -RSP_GMT_OFFSET) < 0) {
-                                               tzo = -tzo;
-                                               *s = '-';
-                                       }
--                                      RSP_TZUNLOCK;
-+/*                                    RSP_TZUNLOCK; */
-                                       ++s;
-                                       --count;
-@@ -1131,7 +1119,13 @@ size_t __XL(strftime)(char *__restrict s
-                       
-                                       i = 16 + 6;     /* 0-fill, width = 4 */
-                               }
--
-+#ifdef __UCLIBC_HAS_TM_EXTENSIONS__
-+#else
-+                              __UCLIBC_MUTEX_UNLOCK(_time_tzlock);
-+                              if (*p == 'Z') {
-+                                      goto OUTPUT;
-+                              }
-+#endif
-                       } else {
-                               /* TODO: don't need year for U, W */
-                               for (i=0 ; i < 3 ; i++) {
-@@ -1664,9 +1658,7 @@ int daylight = 0;
- long timezone = 0;
- char *tzname[2] = { (char *) UTC, (char *) (UTC-1) };
--#ifdef __UCLIBC_HAS_THREADS__
--pthread_mutex_t _time_tzlock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
--#endif
-+__UCLIBC_MUTEX_INIT(_time_tzlock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);
- rule_struct _time_tzinfo[2];
-@@ -1796,7 +1788,7 @@ void tzset(void)
-       static char oldval[TZ_BUFLEN]; /* BSS-zero'd. */
- #endif /* __UCLIBC_HAS_TZ_CACHING__ */
--      TZLOCK;
-+      __UCLIBC_MUTEX_LOCK(_time_tzlock);
-       e = getenv(TZ);                         /* TZ env var always takes precedence. */
-@@ -1962,10 +1954,10 @@ void tzset(void)
-       daylight = !!_time_tzinfo[1].tzname[0];
-       timezone = _time_tzinfo[0].gmt_offset;
--#if defined(__UCLIBC_HAS_TZ_FILE__)
-+#if defined(__UCLIBC_HAS_TZ_FILE__) || defined(__UCLIBC_HAS_TZ_CACHING__)
-  FAST_DONE:
- #endif
--      TZUNLOCK;
-+      __UCLIBC_MUTEX_UNLOCK(_time_tzlock);
- }
- #endif
-@@ -2167,13 +2159,13 @@ time_t _time_mktime(struct tm *timeptr, 
- {
-       time_t t;
--      TZLOCK;
-+      __UCLIBC_MUTEX_LOCK(_time_tzlock);
-       tzset();
-       t = _time_mktime_tzi(timeptr, store_on_success, _time_tzinfo);
--      TZUNLOCK;
-+      __UCLIBC_MUTEX_UNLOCK(_time_tzlock);
-       return t;
- }
-diff --git a/libc/misc/ttyent/getttyent.c b/libc/misc/ttyent/getttyent.c
-index 6e2fbd2..c85c73a 100644
---- a/libc/misc/ttyent/getttyent.c
-+++ b/libc/misc/ttyent/getttyent.c
-@@ -35,9 +35,6 @@
- #include <ctype.h>
- #include <string.h>
- #include <stdlib.h>
--#ifdef __UCLIBC_HAS_THREADS__
--#include <pthread.h>
--#endif
- static char zapchar;
- static FILE *tf;
-@@ -50,8 +47,8 @@ struct ttyent * getttynam(const char *tt
-     setttyent();
-     while ((t = getttyent()))
--      if (!strcmp(tty, t->ty_name))
--          break;
-+              if (!strcmp(tty, t->ty_name))
-+                      break;
-     endttyent();
-     return (t);
- }
-@@ -67,27 +64,27 @@ static char * skip(register char *p)
-     register int c, q;
-     for (q = 0, t = p; (c = *p) != '\0'; p++) {
--      if (c == '"') {
--          q ^= QUOTED;        /* obscure, but nice */
--          continue;
--      }
--      if (q == QUOTED && *p == '\\' && *(p+1) == '"')
--          p++;
--      *t++ = *p;
--      if (q == QUOTED)
--          continue;
--      if (c == '#') {
--          zapchar = c;
--          *p = 0;
--          break;
--      }
--      if (c == '\t' || c == ' ' || c == '\n') {
--          zapchar = c;
--          *p++ = 0;
--          while ((c = *p) == '\t' || c == ' ' || c == '\n')
--              p++;
--          break;
--      }
-+              if (c == '"') {
-+                      q ^= QUOTED;    /* obscure, but nice */
-+                      continue;
-+              }
-+              if (q == QUOTED && *p == '\\' && *(p+1) == '"')
-+                      p++;
-+              *t++ = *p;
-+              if (q == QUOTED)
-+                      continue;
-+              if (c == '#') {
-+                      zapchar = c;
-+                      *p = 0;
-+                      break;
-+              }
-+              if (c == '\t' || c == ' ' || c == '\n') {
-+                      zapchar = c;
-+                      *p++ = 0;
-+                      while ((c = *p) == '\t' || c == ' ' || c == '\n')
-+                              p++;
-+                      break;
-+              }
-     }
-     *--t = '\0';
-     return (p);
-@@ -104,46 +101,46 @@ struct ttyent * getttyent(void)
-     register int c;
-     register char *p;
-     static char *line = NULL;
-+    struct ttyent *retval = NULL;
-     if (!tf && !setttyent())
--      return (NULL);
-+              return (NULL);
-     if (!line) {
--            line = malloc(BUFSIZ);
-+              line = malloc(BUFSIZ);
-               if (!line)
-                   abort();
-     }
--      __STDIO_ALWAYS_THREADLOCK(tf);
-+    __STDIO_ALWAYS_THREADLOCK(tf);
-     for (;;) {
--      if (!fgets_unlocked(p = line, BUFSIZ, tf)) {
--              __STDIO_ALWAYS_THREADUNLOCK(tf);
--          return (NULL);
--      }
--      /* skip lines that are too big */
--      if (!index(p, '\n')) {
--          while ((c = getc_unlocked(tf)) != '\n' && c != EOF)
--              ;
--          continue;
--      }
--      while (isspace(*p))
--          ++p;
--      if (*p && *p != '#')
--          break;
-+              if (!fgets_unlocked(p = line, BUFSIZ, tf)) {
-+                      goto DONE;
-+              }
-+              /* skip lines that are too big */
-+              if (!index(p, '\n')) {
-+                      while ((c = getc_unlocked(tf)) != '\n' && c != EOF)
-+                              ;
-+                      continue;
-+              }
-+              while (isspace(*p))
-+                      ++p;
-+              if (*p && *p != '#')
-+                      break;
-     }
-     zapchar = 0;
-     tty.ty_name = p;
-     p = skip(p);
-     if (!*(tty.ty_getty = p))
--      tty.ty_getty = tty.ty_type = NULL;
-+              tty.ty_getty = tty.ty_type = NULL;
-     else {
--      p = skip(p);
--      if (!*(tty.ty_type = p))
--          tty.ty_type = NULL;
--      else
--          p = skip(p);
-+              p = skip(p);
-+              if (!*(tty.ty_type = p))
-+                      tty.ty_type = NULL;
-+              else
-+                      p = skip(p);
-     }
-     tty.ty_status = 0;
-     tty.ty_window = NULL;
-@@ -151,43 +148,45 @@ struct ttyent * getttyent(void)
- #define       scmp(e) !strncmp(p, e, sizeof(e) - 1) && isspace(p[sizeof(e) - 1])
- #define       vcmp(e) !strncmp(p, e, sizeof(e) - 1) && p[sizeof(e) - 1] == '='
-     for (; *p; p = skip(p)) {
--      if (scmp(_TTYS_OFF))
--          tty.ty_status &= ~TTY_ON;
--      else if (scmp(_TTYS_ON))
--          tty.ty_status |= TTY_ON;
--      else if (scmp(_TTYS_SECURE))
--          tty.ty_status |= TTY_SECURE;
--      else if (vcmp(_TTYS_WINDOW))
--          tty.ty_window = value(p);
--      else
--          break;
-+              if (scmp(_TTYS_OFF))
-+                      tty.ty_status &= ~TTY_ON;
-+              else if (scmp(_TTYS_ON))
-+                      tty.ty_status |= TTY_ON;
-+              else if (scmp(_TTYS_SECURE))
-+                      tty.ty_status |= TTY_SECURE;
-+              else if (vcmp(_TTYS_WINDOW))
-+                      tty.ty_window = value(p);
-+              else
-+                      break;
-     }
--    /* We can release the lock only here since `zapchar' is global.  */
--      __STDIO_ALWAYS_THREADUNLOCK(tf);
-     if (zapchar == '#' || *p == '#')
--      while ((c = *++p) == ' ' || c == '\t')
--          ;
-+              while ((c = *++p) == ' ' || c == '\t')
-+                      ;
-     tty.ty_comment = p;
-     if (*p == 0)
--      tty.ty_comment = 0;
-+              tty.ty_comment = 0;
-     if ((p = index(p, '\n')))
--      *p = '\0';
--    return (&tty);
-+              *p = '\0';
-+    retval = &tty;
-+
-+ DONE:
-+    __STDIO_ALWAYS_THREADUNLOCK(tf);
-+    return retval;
- }
- int setttyent(void)
- {
-     if (tf) {
--      rewind(tf);
--      return (1);
-+              rewind(tf);
-+              return (1);
-     } else if ((tf = fopen(_PATH_TTYS, "r"))) {
--      /* We do the locking ourselves.  */
-+              /* We do the locking ourselves.  */
- #ifdef __UCLIBC_HAS_THREADS__
--      __fsetlocking (tf, FSETLOCKING_BYCALLER);
-+              __fsetlocking (tf, FSETLOCKING_BYCALLER);
- #endif
--      return (1);
-+              return (1);
-     }
-     return (0);
- }
-@@ -197,9 +196,9 @@ int endttyent(void)
-     int rval;
-     if (tf) {
--      rval = !(fclose(tf) == EOF);
--      tf = NULL;
--      return (rval);
-+              rval = !(fclose(tf) == EOF);
-+              tf = NULL;
-+              return (rval);
-     }
-     return (1);
- }
-diff --git a/libc/misc/utmp/utent.c b/libc/misc/utmp/utent.c
-index c1d8d6f..0fc6df4 100644
---- a/libc/misc/utmp/utent.c
-+++ b/libc/misc/utmp/utent.c
-@@ -20,19 +20,9 @@
- #include <string.h>
- #include <utmp.h>
-+#include <bits/uClibc_mutex.h>
--
--#ifdef __UCLIBC_HAS_THREADS__
--#include <pthread.h>
--static pthread_mutex_t utmplock = PTHREAD_MUTEX_INITIALIZER;
--# define LOCK __pthread_mutex_lock(&utmplock)
--# define UNLOCK       __pthread_mutex_unlock(&utmplock)
--#else
--# define LOCK
--# define UNLOCK
--#endif
--
--
-+__UCLIBC_MUTEX_STATIC(utmplock, PTHREAD_MUTEX_INITIALIZER);
- /* Some global crap */
- static int static_fd = -1;
-@@ -46,19 +36,19 @@ static struct utmp *__getutent(int utmp_
- {
-     if (utmp_fd == -1) {
--      setutent();
-+              setutent();
-     }
-     if (utmp_fd == -1) {
--      return NULL;
-+              return NULL;
-     }
--    LOCK;
-+    __UCLIBC_MUTEX_LOCK(utmplock);
-     if (read(utmp_fd, (char *) &static_utmp, sizeof(struct utmp)) != sizeof(struct utmp)) 
--    {
--      return NULL;
--    }
-+              {
-+                      return NULL;
-+              }
--    UNLOCK;
-+    __UCLIBC_MUTEX_UNLOCK(utmplock);
-     return &static_utmp;
- }
-@@ -66,39 +56,39 @@ void setutent(void)
- {
-     int ret;
--    LOCK;
-+    __UCLIBC_MUTEX_LOCK(utmplock);
-     if (static_fd == -1) {
--      if ((static_fd = open(static_ut_name, O_RDWR)) < 0) {
--          if ((static_fd = open(static_ut_name, O_RDONLY)) < 0) {
--              goto bummer;
--          }
--      }
--      /* Make sure the file will be closed on exec()  */
--      ret = fcntl(static_fd, F_GETFD, 0);
--      if (ret >= 0) {
--          ret = fcntl(static_fd, F_GETFD, 0);
--      }
--      if (ret < 0) {
--bummer:
--          UNLOCK;
--          static_fd = -1;
--          close(static_fd);
--          return;
--      }
-+              if ((static_fd = open(static_ut_name, O_RDWR)) < 0) {
-+                      if ((static_fd = open(static_ut_name, O_RDONLY)) < 0) {
-+                              goto bummer;
-+                      }
-+              }
-+              /* Make sure the file will be closed on exec()  */
-+              ret = fcntl(static_fd, F_GETFD, 0);
-+              if (ret >= 0) {
-+                      ret = fcntl(static_fd, F_GETFD, 0);
-+              }
-+              if (ret < 0) {
-+              bummer:
-+                      close(static_fd);
-+                      static_fd = -1;
-+                      goto DONE;
-+              }
-     }
-     lseek(static_fd, 0, SEEK_SET);
--    UNLOCK;
-+ DONE:
-+    __UCLIBC_MUTEX_UNLOCK(utmplock);
-     return;
- }
- void endutent(void)
- {
--    LOCK;
-+    __UCLIBC_MUTEX_LOCK(utmplock);
-     if (static_fd != -1) {
--      close(static_fd);
-+              close(static_fd);
-     }
-     static_fd = -1;
--    UNLOCK;
-+    __UCLIBC_MUTEX_UNLOCK(utmplock);
- }
- /* Locking is done in __getutent */
-@@ -113,22 +103,22 @@ struct utmp *getutid (const struct utmp 
-     struct utmp *lutmp;
-     while ((lutmp = __getutent(static_fd)) != NULL) {
--      if (    (utmp_entry->ut_type == RUN_LVL ||
--               utmp_entry->ut_type == BOOT_TIME ||
--               utmp_entry->ut_type == NEW_TIME ||
--               utmp_entry->ut_type == OLD_TIME) &&
--              lutmp->ut_type == utmp_entry->ut_type)  
--      {
--          return lutmp;
--      }
--      if (    (utmp_entry->ut_type == INIT_PROCESS ||
--               utmp_entry->ut_type == DEAD_PROCESS ||
--               utmp_entry->ut_type == LOGIN_PROCESS ||
--               utmp_entry->ut_type == USER_PROCESS) &&
--              !strncmp(lutmp->ut_id, utmp_entry->ut_id, sizeof(lutmp->ut_id))) 
--      {
--          return lutmp;
--      }
-+              if (    (utmp_entry->ut_type == RUN_LVL ||
-+                               utmp_entry->ut_type == BOOT_TIME ||
-+                               utmp_entry->ut_type == NEW_TIME ||
-+                               utmp_entry->ut_type == OLD_TIME) &&
-+                              lutmp->ut_type == utmp_entry->ut_type)  
-+                      {
-+                              return lutmp;
-+                      }
-+              if (    (utmp_entry->ut_type == INIT_PROCESS ||
-+                               utmp_entry->ut_type == DEAD_PROCESS ||
-+                               utmp_entry->ut_type == LOGIN_PROCESS ||
-+                               utmp_entry->ut_type == USER_PROCESS) &&
-+                              !strncmp(lutmp->ut_id, utmp_entry->ut_id, sizeof(lutmp->ut_id))) 
-+                      {
-+                              return lutmp;
-+                      }
-     }
-     return NULL;
-@@ -140,11 +130,11 @@ struct utmp *getutline(const struct utmp
-     struct utmp *lutmp;
-     while ((lutmp = __getutent(static_fd)) != NULL) {
--      if ((lutmp->ut_type == USER_PROCESS || lutmp->ut_type == LOGIN_PROCESS) &&
--              !strcmp(lutmp->ut_line, utmp_entry->ut_line))
--      {
--          return lutmp;
--      }
-+              if ((lutmp->ut_type == USER_PROCESS || lutmp->ut_type == LOGIN_PROCESS) &&
-+                      !strcmp(lutmp->ut_line, utmp_entry->ut_line))
-+                      {
-+                              return lutmp;
-+                      }
-     }
-     return NULL;
-@@ -152,42 +142,42 @@ struct utmp *getutline(const struct utmp
- struct utmp *pututline (const struct utmp *utmp_entry)
- {
--    LOCK;
-+    __UCLIBC_MUTEX_LOCK(utmplock);
-     /* Ignore the return value.  That way, if they've already positioned
-        the file pointer where they want it, everything will work out. */
-     lseek(static_fd, (off_t) - sizeof(struct utmp), SEEK_CUR);
-     if (getutid(utmp_entry) != NULL) {
--      lseek(static_fd, (off_t) - sizeof(struct utmp), SEEK_CUR);
--      if (write(static_fd, utmp_entry, sizeof(struct utmp)) != sizeof(struct utmp))
--          return NULL;
-+              lseek(static_fd, (off_t) - sizeof(struct utmp), SEEK_CUR);
-+              if (write(static_fd, utmp_entry, sizeof(struct utmp)) != sizeof(struct utmp))
-+                      return NULL;
-     } else {
--      lseek(static_fd, (off_t) 0, SEEK_END);
--      if (write(static_fd, utmp_entry, sizeof(struct utmp)) != sizeof(struct utmp))
--          return NULL;
-+              lseek(static_fd, (off_t) 0, SEEK_END);
-+              if (write(static_fd, utmp_entry, sizeof(struct utmp)) != sizeof(struct utmp))
-+                      return NULL;
-     }
--    UNLOCK;
-+    __UCLIBC_MUTEX_UNLOCK(utmplock);
-     return (struct utmp *)utmp_entry;
- }
- int utmpname (const char *new_ut_name)
- {
--    LOCK;
-+    __UCLIBC_MUTEX_LOCK(utmplock);
-     if (new_ut_name != NULL) {
--      if (static_ut_name != default_file_name)
--          free((char *)static_ut_name);
--      static_ut_name = strdup(new_ut_name);
--      if (static_ut_name == NULL) {
--          /* We should probably whine about out-of-memory 
--           * errors here...  Instead just reset to the default */
--          static_ut_name = default_file_name;
--      }
-+              if (static_ut_name != default_file_name)
-+                      free((char *)static_ut_name);
-+              static_ut_name = strdup(new_ut_name);
-+              if (static_ut_name == NULL) {
-+                      /* We should probably whine about out-of-memory 
-+                       * errors here...  Instead just reset to the default */
-+                      static_ut_name = default_file_name;
-+              }
-     }
-     if (static_fd != -1)
--      close(static_fd);
--    UNLOCK;
-+              close(static_fd);
-+    __UCLIBC_MUTEX_UNLOCK(utmplock);
-     return 0;
- }
-diff --git a/libc/misc/wchar/wstdio.c b/libc/misc/wchar/wstdio.c
-index b49494f..408c57a 100644
---- a/libc/misc/wchar/wstdio.c
-+++ b/libc/misc/wchar/wstdio.c
-@@ -82,9 +82,6 @@ strong_alias(NAME,NAME##_unlocked) \
- void NAME PARAMS
- #endif
--#define __STDIO_THREADLOCK_OPENLIST
--#define __STDIO_THREADUNLOCK_OPENLIST
--
- #else  /* __UCLIBC_HAS_THREADS__ */
- #include <pthread.h>
-@@ -112,15 +109,6 @@ void NAME PARAMS \
- } \
- void NAME##_unlocked PARAMS
--#define __STDIO_THREADLOCK_OPENLIST \
--      __pthread_mutex_lock(&_stdio_openlist_lock)
--
--#define __STDIO_THREADUNLOCK_OPENLIST \
--      __pthread_mutex_unlock(&_stdio_openlist_lock)
--
--#define __STDIO_THREADTRYLOCK_OPENLIST \
--      __pthread_mutex_trylock(&_stdio_openlist_lock)
--
- #endif /* __UCLIBC_HAS_THREADS__ */
- #ifndef __STDIO_BUFFERS
-diff --git a/libc/pwd_grp/lckpwdf.c b/libc/pwd_grp/lckpwdf.c
-index 6b9c251..063fed4 100644
---- a/libc/pwd_grp/lckpwdf.c
-+++ b/libc/pwd_grp/lckpwdf.c
-@@ -27,15 +27,9 @@
- #include <sys/file.h>
- #include <paths.h>
--#ifdef __UCLIBC_HAS_THREADS__
--#include <pthread.h>
--static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;
--# define LOCK   __pthread_mutex_lock(&mylock)
--# define UNLOCK __pthread_mutex_unlock(&mylock);
--#else       
--# define LOCK
--# define UNLOCK
--#endif      
-+#include <bits/uClibc_mutex.h>
-+
-+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER);
- /* How long to wait for getting the lock before returning with an
-    error.  */
-@@ -57,18 +51,18 @@ int lckpwdf (void)
-       struct sigaction new_act;   /* New signal action.  */
-       struct flock fl;            /* Information struct for locking.  */
-       int result;
-+      int rv = -1;
-       if (lock_fd != -1)
-               /* Still locked by own process.  */
-               return -1;
--      LOCK;
-+      __UCLIBC_MUTEX_LOCK(mylock);
-       lock_fd = open (_PATH_PASSWD, O_WRONLY);
-       if (lock_fd == -1) {
-               /* Cannot create lock file.  */
--              UNLOCK;
--              return -1;
-+              goto DONE;
-       }
-       /* Make sure file gets correctly closed when process finished.  */
-@@ -77,16 +71,14 @@ int lckpwdf (void)
-               /* Cannot get file flags.  */
-               close(lock_fd);
-               lock_fd = -1;
--              UNLOCK;
--              return -1;
-+              goto DONE;
-       }
-       flags |= FD_CLOEXEC;            /* Close on exit.  */
-       if (fcntl (lock_fd, F_SETFD, flags) < 0) {
-               /* Cannot set new flags.  */
-               close(lock_fd);
-               lock_fd = -1;
--              UNLOCK;
--              return -1;
-+              goto DONE;
-       }
-       /* Now we have to get exclusive write access.  Since multiple
-@@ -107,8 +99,7 @@ int lckpwdf (void)
-               /* Cannot install signal handler.  */
-               close(lock_fd);
-               lock_fd = -1;
--              UNLOCK;
--              return -1;
-+              goto DONE;
-       }
-       /* Now make sure the alarm signal is not blocked.  */
-@@ -118,8 +109,7 @@ int lckpwdf (void)
-               sigaction (SIGALRM, &saved_act, NULL);
-               close(lock_fd);
-               lock_fd = -1;
--              UNLOCK;
--              return -1;
-+              goto DONE;
-       }
-       /* Start timer.  If we cannot get the lock in the specified time we
-@@ -146,12 +136,14 @@ int lckpwdf (void)
-       if (result < 0) {
-               close(lock_fd);
-               lock_fd = -1;
--              UNLOCK;
--              return -1;
-+              goto DONE;
-       }
--      UNLOCK;
--      return 0;
-+      rv = 0;
-+
-+ DONE:
-+      __UCLIBC_MUTEX_UNLOCK(mylock);
-+      return rv;
- }
-@@ -164,11 +156,11 @@ int ulckpwdf (void)
-               result = -1;
-       }
-       else {
--              LOCK;
-+              __UCLIBC_MUTEX_LOCK(mylock);
-               result = close (lock_fd);
-               /* Mark descriptor as unused.  */
-               lock_fd = -1;
--              UNLOCK;
-+              __UCLIBC_MUTEX_UNLOCK(mylock);
-       }
-       return result;
-diff --git a/libc/pwd_grp/pwd_grp.c b/libc/pwd_grp/pwd_grp.c
-index 91c0d83..a302c7c 100644
---- a/libc/pwd_grp/pwd_grp.c
-+++ b/libc/pwd_grp/pwd_grp.c
-@@ -42,9 +42,8 @@
- #include <pwd.h>
- #include <grp.h>
- #include <shadow.h>
--#ifdef __UCLIBC_HAS_THREADS__
--#include <pthread.h>
--#endif
-+
-+#include <bits/uClibc_mutex.h>
- /**********************************************************************/
- /* Sizes for staticly allocated buffers. */
-@@ -445,34 +444,27 @@ int getpw(uid_t uid, char *buf)
- /**********************************************************************/
- #ifdef L_getpwent_r
--#ifdef __UCLIBC_HAS_THREADS__
--static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;
--# define LOCK         __pthread_mutex_lock(&mylock)
--# define UNLOCK               __pthread_mutex_unlock(&mylock);
--#else       
--# define LOCK         ((void) 0)
--# define UNLOCK               ((void) 0)
--#endif      
-+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER);
- static FILE *pwf /*= NULL*/;
- void setpwent(void)
- {
--      LOCK;
-+      __UCLIBC_MUTEX_LOCK(mylock);
-       if (pwf) {
-               rewind(pwf);
-       }
--      UNLOCK;
-+      __UCLIBC_MUTEX_UNLOCK(mylock);
- }
- void endpwent(void)
- {
--      LOCK;
-+      __UCLIBC_MUTEX_LOCK(mylock);
-       if (pwf) {
-               fclose(pwf);
-               pwf = NULL;
-       }
--      UNLOCK;
-+      __UCLIBC_MUTEX_UNLOCK(mylock);
- }
-@@ -482,7 +474,7 @@ int getpwent_r(struct passwd *__restrict
- {
-       int rv;
--      LOCK;
-+      __UCLIBC_MUTEX_LOCK(mylock);
-       *result = NULL;                         /* In case of error... */
-@@ -500,7 +492,7 @@ int getpwent_r(struct passwd *__restrict
-       }
-  ERR:
--      UNLOCK;
-+      __UCLIBC_MUTEX_UNLOCK(mylock);
-       return rv;
- }
-@@ -509,34 +501,27 @@ int getpwent_r(struct passwd *__restrict
- /**********************************************************************/
- #ifdef L_getgrent_r
--#ifdef __UCLIBC_HAS_THREADS__
--static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;
--# define LOCK         __pthread_mutex_lock(&mylock)
--# define UNLOCK               __pthread_mutex_unlock(&mylock);
--#else       
--# define LOCK         ((void) 0)
--# define UNLOCK               ((void) 0)
--#endif      
-+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER);
- static FILE *grf /*= NULL*/;
- void setgrent(void)
- {
--      LOCK;
-+      __UCLIBC_MUTEX_LOCK(mylock);
-       if (grf) {
-               rewind(grf);
-       }
--      UNLOCK;
-+      __UCLIBC_MUTEX_UNLOCK(mylock);
- }
- void endgrent(void)
- {
--      LOCK;
-+      __UCLIBC_MUTEX_LOCK(mylock);
-       if (grf) {
-               fclose(grf);
-               grf = NULL;
-       }
--      UNLOCK;
-+      __UCLIBC_MUTEX_UNLOCK(mylock);
- }
- int getgrent_r(struct group *__restrict resultbuf,
-@@ -545,7 +530,7 @@ int getgrent_r(struct group *__restrict 
- {
-       int rv;
--      LOCK;
-+      __UCLIBC_MUTEX_LOCK(mylock);
-       *result = NULL;                         /* In case of error... */
-@@ -563,7 +548,7 @@ int getgrent_r(struct group *__restrict 
-       }
-  ERR:
--      UNLOCK;
-+      __UCLIBC_MUTEX_UNLOCK(mylock);
-       return rv;
- }
-@@ -572,34 +557,27 @@ int getgrent_r(struct group *__restrict 
- /**********************************************************************/
- #ifdef L_getspent_r
--#ifdef __UCLIBC_HAS_THREADS__
--static pthread_mutex_t mylock =  PTHREAD_MUTEX_INITIALIZER;
--# define LOCK         __pthread_mutex_lock(&mylock)
--# define UNLOCK               __pthread_mutex_unlock(&mylock);
--#else       
--# define LOCK         ((void) 0)
--# define UNLOCK               ((void) 0)
--#endif      
-+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER);
- static FILE *spf /*= NULL*/;
- void setspent(void)
- {
--      LOCK;
-+      __UCLIBC_MUTEX_LOCK(mylock);
-       if (spf) {
-               rewind(spf);
-       }
--      UNLOCK;
-+      __UCLIBC_MUTEX_UNLOCK(mylock);
- }
- void endspent(void)
- {
--      LOCK;
-+      __UCLIBC_MUTEX_LOCK(mylock);
-       if (spf) {
-               fclose(spf);
-               spf = NULL;
-       }
--      UNLOCK;
-+      __UCLIBC_MUTEX_UNLOCK(mylock);
- }
- int getspent_r(struct spwd *resultbuf, char *buffer, 
-@@ -607,7 +585,7 @@ int getspent_r(struct spwd *resultbuf, c
- {
-       int rv;
--      LOCK;
-+      __UCLIBC_MUTEX_LOCK(mylock);
-       *result = NULL;                         /* In case of error... */
-@@ -625,7 +603,7 @@ int getspent_r(struct spwd *resultbuf, c
-       }
-  ERR:
--      UNLOCK;
-+      __UCLIBC_MUTEX_UNLOCK(mylock);
-       return rv;
- }
-diff --git a/libc/stdio/_READ.c b/libc/stdio/_READ.c
-index 7d3c38c..fe1bc91 100644
---- a/libc/stdio/_READ.c
-+++ b/libc/stdio/_READ.c
-@@ -41,7 +41,7 @@ size_t __stdio_READ(register FILE *strea
- #warning EINTR?
- #endif
- /*    RETRY: */
--              if ((rv = __READ(stream, buf, bufsize)) <= 0) {
-+              if ((rv = __READ(stream, (char *) buf, bufsize)) <= 0) {
-                       if (rv == 0) {
-                               __STDIO_STREAM_SET_EOF(stream);
-                       } else {
-diff --git a/libc/stdio/_WRITE.c b/libc/stdio/_WRITE.c
-index d300d39..4131eb7 100644
---- a/libc/stdio/_WRITE.c
-+++ b/libc/stdio/_WRITE.c
-@@ -47,7 +47,7 @@ size_t __stdio_WRITE(register FILE *stre
-                       return bufsize;
-               }
-               stodo = (todo <= SSIZE_MAX) ? todo : SSIZE_MAX;
--              if ((rv = __WRITE(stream, buf, stodo)) >= 0) {
-+              if ((rv = __WRITE(stream, (char *) buf, stodo)) >= 0) {
- #ifdef __UCLIBC_MJN3_ONLY__
- #warning TODO: Make custom stream write return check optional.
- #endif
-diff --git a/libc/stdio/_fopen.c b/libc/stdio/_fopen.c
-index f7f5bb6..4984f11 100644
---- a/libc/stdio/_fopen.c
-+++ b/libc/stdio/_fopen.c
-@@ -194,10 +194,23 @@ FILE *_stdio_fopen(intptr_t fname_or_mod
- #endif
- #ifdef __STDIO_HAS_OPENLIST
--      __STDIO_THREADLOCK_OPENLIST;
--      stream->__nextopen = _stdio_openlist; /* New files are inserted at */
--      _stdio_openlist = stream;                         /*   the head of the list. */
--      __STDIO_THREADUNLOCK_OPENLIST;
-+#if defined(__UCLIBC_HAS_THREADS__) && defined(__STDIO_BUFFERS)
-+      if (!(stream->__modeflags & __FLAG_FREEFILE))
-+      {
-+              /* An freopen call so the file was never removed from the list. */
-+      }
-+      else
-+#endif
-+      {
-+              /* We have to lock the del mutex in case another thread wants to fclose()
-+               * the last file. */
-+              __STDIO_THREADLOCK_OPENLIST_DEL;
-+              __STDIO_THREADLOCK_OPENLIST_ADD;
-+              stream->__nextopen = _stdio_openlist; /* New files are inserted at */
-+              _stdio_openlist = stream;                         /*   the head of the list. */
-+              __STDIO_THREADUNLOCK_OPENLIST_ADD;
-+              __STDIO_THREADUNLOCK_OPENLIST_DEL;
-+      }
- #endif
-       __STDIO_STREAM_VALIDATE(stream);
-diff --git a/libc/stdio/_stdio.c b/libc/stdio/_stdio.c
-index 4aae3c4..9cfe02c 100644
---- a/libc/stdio/_stdio.c
-+++ b/libc/stdio/_stdio.c
-@@ -151,8 +151,12 @@ FILE *__stdout = _stdio_streams + 1; /* 
- FILE *_stdio_openlist = _stdio_streams;
- # ifdef __UCLIBC_HAS_THREADS__
--pthread_mutex_t _stdio_openlist_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
--int _stdio_openlist_delflag = 0;
-+__UCLIBC_MUTEX_INIT(_stdio_openlist_add_lock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);
-+#ifdef __STDIO_BUFFERS
-+__UCLIBC_MUTEX_INIT(_stdio_openlist_del_lock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);
-+volatile int _stdio_openlist_use_count = 0;
-+int _stdio_openlist_del_count = 0;
-+#endif
- # endif
- #endif
-@@ -162,10 +166,10 @@ int _stdio_openlist_delflag = 0;
- /* 2 if threading not initialized and 0 otherwise; */
- int _stdio_user_locking = 2;
--void __stdio_init_mutex(pthread_mutex_t *m)
-+void __stdio_init_mutex(__UCLIBC_MUTEX_TYPE *m)
- {
--      static const pthread_mutex_t __stdio_mutex_initializer
--              = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
-+      const __UCLIBC_MUTEX_STATIC(__stdio_mutex_initializer,
-+                                                              PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);
-       memcpy(m, &__stdio_mutex_initializer, sizeof(__stdio_mutex_initializer));
- }
-@@ -184,7 +188,11 @@ void _stdio_term(void)
-        * locked, then I suppose there is a chance that a pointer in the
-        * chain might be corrupt due to a partial store.
-        */ 
--      __stdio_init_mutex(&_stdio_openlist_lock);
-+      __stdio_init_mutex(&_stdio_openlist_add_lock);
-+#warning check
-+#ifdef __STDIO_BUFFERS
-+      __stdio_init_mutex(&_stdio_openlist_del_lock);
-+#endif
-       /* Next we need to worry about the streams themselves.  If a stream
-        * is currently locked, then it may be in an invalid state.  So we
-@@ -192,7 +200,7 @@ void _stdio_term(void)
-        * Then we reinitialize the locks.
-        */
-       for (ptr = _stdio_openlist ; ptr ; ptr = ptr->__nextopen ) {
--              if (__STDIO_ALWAYS_THREADTRYLOCK(ptr)) {
-+              if (__STDIO_ALWAYS_THREADTRYLOCK_CANCEL_UNSAFE(ptr)) {
-                       /* The stream is already locked, so we don't want to touch it.
-                        * However, if we have custom streams, we can't just close it
-                        * or leave it locked since a custom stream may be stacked
-@@ -258,10 +266,6 @@ void _stdio_init(void)
- #error Assumption violated about __MASK_READING and __FLAG_UNGOT
- #endif
--#ifdef __UCLIBC_HAS_THREADS__
--#include <pthread.h>
--#endif
--
- #ifndef NDEBUG
- void _stdio_validate_FILE(const FILE *stream)
-diff --git a/libc/stdio/_stdio.h b/libc/stdio/_stdio.h
-index e3c2c58..decf57d 100644
---- a/libc/stdio/_stdio.h
-+++ b/libc/stdio/_stdio.h
-@@ -22,23 +22,57 @@
- #include <wchar.h>
- #endif
--#ifdef __UCLIBC_HAS_THREADS__
--#include <pthread.h>
-+#include <bits/uClibc_mutex.h>
--#define __STDIO_THREADLOCK_OPENLIST \
--      __pthread_mutex_lock(&_stdio_openlist_lock)
-+#define __STDIO_THREADLOCK_OPENLIST_ADD                                                                               \
-+        __UCLIBC_MUTEX_LOCK(_stdio_openlist_add_lock)
--#define __STDIO_THREADUNLOCK_OPENLIST \
--      __pthread_mutex_unlock(&_stdio_openlist_lock)
-+#define __STDIO_THREADUNLOCK_OPENLIST_ADD                                                                     \
-+        __UCLIBC_MUTEX_UNLOCK(_stdio_openlist_add_lock)
--#define __STDIO_THREADTRYLOCK_OPENLIST \
--      __pthread_mutex_trylock(&_stdio_openlist_lock)
-+#ifdef __STDIO_BUFFERS
--#else
-+#define __STDIO_THREADLOCK_OPENLIST_DEL                                                                               \
-+        __UCLIBC_MUTEX_LOCK(_stdio_openlist_del_lock)
-+
-+#define __STDIO_THREADUNLOCK_OPENLIST_DEL                                                                     \
-+        __UCLIBC_MUTEX_UNLOCK(_stdio_openlist_del_lock)
--#define       __STDIO_THREADLOCK_OPENLIST     ((void)0)
--#define       __STDIO_THREADUNLOCK_OPENLIST   ((void)0)
-+#define __STDIO_OPENLIST_INC_USE \
-+do { \
-+      __STDIO_THREADLOCK_OPENLIST_DEL; \
-+      ++_stdio_openlist_use_count; \
-+      __STDIO_THREADUNLOCK_OPENLIST_DEL; \
-+} while (0)
-+
-+extern void _stdio_openlist_dec_use(void);
-+
-+#define __STDIO_OPENLIST_DEC_USE \
-+      _stdio_openlist_dec_use()
-+
-+#define __STDIO_OPENLIST_INC_DEL_CNT \
-+do { \
-+      __STDIO_THREADLOCK_OPENLIST_DEL; \
-+      ++_stdio_openlist_del_count; \
-+      __STDIO_THREADUNLOCK_OPENLIST_DEL; \
-+} while (0)
-+
-+#define __STDIO_OPENLIST_DEC_DEL_CNT \
-+do { \
-+      __STDIO_THREADLOCK_OPENLIST_DEL; \
-+      --_stdio_openlist_del_count; \
-+      __STDIO_THREADUNLOCK_OPENLIST_DEL; \
-+} while (0)
-+
-+#endif /* __STDIO_BUFFERS */
-+#ifndef __STDIO_THREADLOCK_OPENLIST_DEL
-+#define       __STDIO_THREADLOCK_OPENLIST_DEL     ((void)0)
-+#define       __STDIO_THREADUNLOCK_OPENLIST_DEL   ((void)0)
-+#define __STDIO_OPENLIST_INC_USE            ((void)0)
-+#define __STDIO_OPENLIST_DEC_USE            ((void)0)
-+#define __STDIO_OPENLIST_INC_DEL_CNT        ((void)0)
-+#define __STDIO_OPENLIST_DEC_DEL_CNT        ((void)0)
- #endif
- #define __UNDEFINED_OR_NONPORTABLE ((void)0)
-diff --git a/libc/stdio/fclose.c b/libc/stdio/fclose.c
-index 4df2e42..dfababc 100644
---- a/libc/stdio/fclose.c
-+++ b/libc/stdio/fclose.c
-@@ -12,30 +12,34 @@ int fclose(register FILE *stream)
-       int rv = 0;
-       __STDIO_AUTO_THREADLOCK_VAR;
--      /* First, remove the file from the open file list. */
--#ifdef __STDIO_HAS_OPENLIST
--      {
--              register FILE *ptr;
--
--              __STDIO_THREADLOCK_OPENLIST;
--              if ((ptr = _stdio_openlist) == stream) {
--                      _stdio_openlist = stream->__nextopen;
--              } else {
--                      while (ptr) {
--                              if (ptr->__nextopen == stream) {
--                                      ptr->__nextopen = stream->__nextopen;
--                                      break;
--                              }
--                              ptr = ptr->__nextopen;
--                      }
--              }
--              __STDIO_THREADUNLOCK_OPENLIST;
--
--              if (!ptr) {       /* Did not find stream in the open file list! */
--                      return EOF;
--              }
--      }
--#endif
-+#warning dead code... but may want to simply check and not remove
-+/* #ifdef __STDIO_HAS_OPENLIST */
-+/* #if !defined(__UCLIBC_HAS_THREADS__) || !defined(__STDIO_BUFFERS) */
-+/*    /\* First, remove the file from the open file list. *\/ */
-+/*    { */
-+/*            register FILE *ptr; */
-+
-+/*            __STDIO_THREADLOCK_OPENLIST; */
-+/*            if ((ptr = _stdio_openlist) == stream) { */
-+/* #warning does a mod!!! */
-+/*                    _stdio_openlist = stream->__nextopen; */
-+/*            } else { */
-+/*                    while (ptr) { */
-+/*                            if (ptr->__nextopen == stream) { */
-+/*                                    ptr->__nextopen = stream->__nextopen; */
-+/*                                    break; */
-+/*                            } */
-+/*                            ptr = ptr->__nextopen; */
-+/*                    } */
-+/*            } */
-+/*            __STDIO_THREADUNLOCK_OPENLIST; */
-+
-+/*            if (!ptr) {       /\* Did not find stream in the open file list! *\/ */
-+/*                    return EOF; */
-+/*            } */
-+/*    } */
-+/* #endif */
-+/* #endif */
-       __STDIO_AUTO_THREADLOCK(stream);
-@@ -80,7 +84,15 @@ int fclose(register FILE *stream)
-       __STDIO_AUTO_THREADUNLOCK(stream);
-       __STDIO_STREAM_FREE_BUFFER(stream);
-+#warning... inefficient - locks and unlocks twice and walks whole list
-+#if defined(__UCLIBC_HAS_THREADS__) && defined(__STDIO_BUFFERS)
-+      /* inefficient - locks/unlocks twice and walks whole list */
-+      __STDIO_OPENLIST_INC_USE;
-+      __STDIO_OPENLIST_INC_DEL_CNT;
-+      __STDIO_OPENLIST_DEC_USE;       /* This with free the file if necessary. */
-+#else
-       __STDIO_STREAM_FREE_FILE(stream);
-+#endif
-       return rv;
- }
-diff --git a/libc/stdio/fcloseall.c b/libc/stdio/fcloseall.c
-index dbb6000..f62281a 100644
---- a/libc/stdio/fcloseall.c
-+++ b/libc/stdio/fcloseall.c
-@@ -19,14 +19,34 @@ int fcloseall (void)
- #ifdef __STDIO_HAS_OPENLIST
-       int retval = 0;
-+      FILE *f;
--      __STDIO_THREADLOCK_OPENLIST;
--      while (_stdio_openlist) {
--              if (fclose(_stdio_openlist)) {
-+#warning remove dead code
-+/*    __STDIO_THREADLOCK_OPENLIST; */
-+/*    while (_stdio_openlist) { */
-+/*            if (fclose(_stdio_openlist)) { */
-+/*                    retval = EOF; */
-+/*            } */
-+/*    } */
-+/*    __STDIO_THREADUNLOCK_OPENLIST; */
-+
-+      __STDIO_OPENLIST_INC_USE;
-+
-+#warning should probably have a get_head() operation
-+      __STDIO_THREADLOCK_OPENLIST_ADD;
-+      f = _stdio_openlist;
-+      __STDIO_THREADUNLOCK_OPENLIST_ADD;
-+
-+      while (f) {
-+#warning should probably have a get_next() operation
-+              FILE *n = f->__nextopen;
-+              if (fclose(f)) {
-                       retval = EOF;
-               }
-+              f = n;
-       }
--      __STDIO_THREADUNLOCK_OPENLIST;
-+
-+      __STDIO_OPENLIST_DEC_USE;
-       return retval;
-diff --git a/libc/stdio/fflush.c b/libc/stdio/fflush.c
-index 6baa0ec..66b65cd 100644
---- a/libc/stdio/fflush.c
-+++ b/libc/stdio/fflush.c
-@@ -20,23 +20,50 @@ weak_alias(__fflush_unlocked,fflush_unlo
- weak_alias(__fflush_unlocked,fflush);
- #endif
--#ifdef __UCLIBC_HAS_THREADS__
- /* Even if the stream is set to user-locking, we still need to lock
-  * when all (lbf) writing streams are flushed. */
--#define MY_STDIO_THREADLOCK(STREAM) \
--      if (_stdio_user_locking != 2) { \
--              __STDIO_ALWAYS_THREADLOCK(STREAM); \
--      }
--#define MY_STDIO_THREADUNLOCK(STREAM) \
--      if (_stdio_user_locking != 2) { \
--              __STDIO_ALWAYS_THREADUNLOCK(STREAM); \
--      }
--#else
--#define MY_STDIO_THREADLOCK(STREAM)           ((void)0)
--#define MY_STDIO_THREADUNLOCK(STREAM) ((void)0)
--#endif
-+#define __MY_STDIO_THREADLOCK(__stream)                                                                               \
-+        __UCLIBC_MUTEX_CONDITIONAL_LOCK((__stream)->__lock,                                   \
-+                                                                              (_stdio_user_locking != 2))
-+
-+#define __MY_STDIO_THREADUNLOCK(__stream)                                                                     \
-+        __UCLIBC_MUTEX_CONDITIONAL_UNLOCK((__stream)->__lock,                         \
-+                                                                                (_stdio_user_locking != 2))
-+#if defined(__UCLIBC_HAS_THREADS__) && defined(__STDIO_BUFFERS)
-+void _stdio_openlist_dec_use(void)
-+{
-+      __STDIO_THREADLOCK_OPENLIST_DEL;
-+      if ((_stdio_openlist_use_count == 1) && (_stdio_openlist_del_count > 0)) {
-+              FILE *p = NULL;
-+              FILE *n;
-+              FILE *stream;
-+
-+              __STDIO_THREADLOCK_OPENLIST_ADD;
-+              for (stream = _stdio_openlist; stream; stream = n) {
-+#warning walk the list and clear out all fclosed()d files
-+                      n = stream->__nextopen;
-+#warning fix for nonatomic
-+                      if ((stream->__modeflags & (__FLAG_READONLY|__FLAG_WRITEONLY))
-+                              == (__FLAG_READONLY|__FLAG_WRITEONLY)
-+                              ) {              /* The file was closed so remove from the list. */
-+                              if (!p) {
-+                                      _stdio_openlist = n;
-+                              } else {
-+                                      p->__nextopen = n;
-+                              }
-+                              __STDIO_STREAM_FREE_FILE(stream);
-+                      } else {
-+                              p = stream;
-+                      }
-+              }
-+              __STDIO_THREADUNLOCK_OPENLIST_DEL;
-+      }
-+      --_stdio_openlist_use_count;
-+      __STDIO_THREADUNLOCK_OPENLIST_DEL;
-+}
-+#endif
- int __fflush_unlocked(register FILE *stream)
- {
-@@ -60,23 +87,39 @@ int __fflush_unlocked(register FILE *str
-       }
-       if (!stream) {                          /* Flush all (lbf) writing streams. */
--              __STDIO_THREADLOCK_OPENLIST;
--              for (stream = _stdio_openlist; stream ; stream = stream->__nextopen) {
--                      MY_STDIO_THREADLOCK(stream);
--                      if (!(((stream->__modeflags | bufmask)
--                                 ^ (__FLAG_WRITING|__FLAG_LBF)
--                                 ) & (__FLAG_WRITING|__MASK_BUFMODE))
--                              ) {
--                              if (!__STDIO_COMMIT_WRITE_BUFFER(stream)) {
--                                      __STDIO_STREAM_DISABLE_PUTC(stream);
--                                      __STDIO_STREAM_CLEAR_WRITING(stream);
--                              } else {
--                                      retval = EOF;
-+
-+              __STDIO_OPENLIST_INC_USE;
-+
-+              __STDIO_THREADLOCK_OPENLIST_ADD;
-+              stream = _stdio_openlist;
-+              __STDIO_THREADUNLOCK_OPENLIST_ADD;
-+
-+              while(stream) {
-+                      /* We only care about currently writing streams and do not want to
-+                       * block trying to obtain mutexes on non-writing streams. */
-+#warning fix for nonatomic
-+#warning unnecessary check if no threads
-+                      if (__STDIO_STREAM_IS_WRITING(stream)) { /* ONLY IF ATOMIC!!! */
-+                              __MY_STDIO_THREADLOCK(stream);
-+                              /* Need to check again once we have the lock. */
-+                              if (!(((stream->__modeflags | bufmask)
-+                                         ^ (__FLAG_WRITING|__FLAG_LBF)
-+                                         ) & (__FLAG_WRITING|__MASK_BUFMODE))
-+                                      ) {
-+                                      if (!__STDIO_COMMIT_WRITE_BUFFER(stream)) {
-+                                              __STDIO_STREAM_DISABLE_PUTC(stream);
-+                                              __STDIO_STREAM_CLEAR_WRITING(stream);
-+                                      } else {
-+                                              retval = EOF;
-+                                      }
-                               }
-+                              __MY_STDIO_THREADUNLOCK(stream);
-                       }
--                      MY_STDIO_THREADUNLOCK(stream);
-+                      stream = stream->__nextopen;
-               }
--              __STDIO_THREADUNLOCK_OPENLIST;
-+
-+              __STDIO_OPENLIST_DEC_USE;
-+
-       } else if (__STDIO_STREAM_IS_WRITING(stream)) {
-               if (!__STDIO_COMMIT_WRITE_BUFFER(stream)) {
-                       __STDIO_STREAM_DISABLE_PUTC(stream);
-diff --git a/libc/stdio/flockfile.c b/libc/stdio/flockfile.c
-index 0dcc7c2..3fad711 100644
---- a/libc/stdio/flockfile.c
-+++ b/libc/stdio/flockfile.c
-@@ -11,6 +11,6 @@ void flockfile(FILE *stream)
- {
-       __STDIO_STREAM_VALIDATE(stream);
--      __STDIO_ALWAYS_THREADLOCK(stream);
-+      __STDIO_ALWAYS_THREADLOCK_CANCEL_UNSAFE(stream);
- }
-diff --git a/libc/stdio/freopen.c b/libc/stdio/freopen.c
-index 0eccaac..36b8488 100644
---- a/libc/stdio/freopen.c
-+++ b/libc/stdio/freopen.c
-@@ -42,6 +42,8 @@ FILE *freopen(const char * __restrict fi
-       __STDIO_STREAM_VALIDATE(stream);
-+      __STDIO_OPENLIST_INC_USE;       /* Do not remove the file from the list. */
-+
-       /* First, flush and close, but don't deallocate, the stream. */
-       /* This also removes the stream for the open file list. */
-       dynmode = (stream->__modeflags & (__FLAG_FREEBUF|__FLAG_FREEFILE));
-@@ -57,9 +59,16 @@ FILE *freopen(const char * __restrict fi
-       fp = _stdio_fopen(((intptr_t) filename), mode, stream, FILEDES_ARG);
-+#warning if fp is NULL, then we do not free file (but beware stdin,stdout,stderr)
-+      if (fp) {
-+              __STDIO_OPENLIST_DEC_DEL_CNT;
-+      }
-+
-       /* Reset the allocation flags. */
-       stream->__modeflags |= dynmode;
-+      __STDIO_OPENLIST_DEC_USE;
-+
-       __STDIO_AUTO_THREADUNLOCK(stream);
-       return fp;
-diff --git a/libc/stdio/ftello.c b/libc/stdio/ftello.c
-index 7092f34..69385ce 100644
---- a/libc/stdio/ftello.c
-+++ b/libc/stdio/ftello.c
-@@ -48,7 +48,10 @@ OFFSET_TYPE FTELL(register FILE *stream)
-       __STDIO_STREAM_VALIDATE(stream);
--      if ((__SEEK(stream, &pos, SEEK_CUR) < 0)
-+      if ((__SEEK(stream, &pos,
-+                              ((__STDIO_STREAM_IS_WRITING(stream)
-+                                && (stream->__modeflags & __FLAG_APPEND))
-+                               ? SEEK_END : SEEK_CUR)) < 0)
-               || (__stdio_adjust_position(stream, &pos) < 0)) {
-               pos = -1;
-       }
-diff --git a/libc/stdio/ftrylockfile.c b/libc/stdio/ftrylockfile.c
-index d85b8ff..0d2e156 100644
---- a/libc/stdio/ftrylockfile.c
-+++ b/libc/stdio/ftrylockfile.c
-@@ -15,5 +15,5 @@ int ftrylockfile(FILE *stream)
- {
-       __STDIO_STREAM_VALIDATE(stream);
--      return __STDIO_ALWAYS_THREADTRYLOCK(stream);
-+      return __STDIO_ALWAYS_THREADTRYLOCK_CANCEL_UNSAFE(stream);
- }
-diff --git a/libc/stdio/funlockfile.c b/libc/stdio/funlockfile.c
-index 048c093..2ddf097 100644
---- a/libc/stdio/funlockfile.c
-+++ b/libc/stdio/funlockfile.c
-@@ -11,5 +11,5 @@ void funlockfile(FILE *stream)
- {
-       __STDIO_STREAM_VALIDATE(stream);
--      __STDIO_ALWAYS_THREADUNLOCK(stream);
-+      __STDIO_ALWAYS_THREADUNLOCK_CANCEL_UNSAFE(stream);
- }
-diff --git a/libc/stdio/popen.c b/libc/stdio/popen.c
-index c7887ad..ab8d296 100644
---- a/libc/stdio/popen.c
-+++ b/libc/stdio/popen.c
-@@ -14,6 +14,7 @@
-  *   Fix failure exit code for failed execve().
-  */
-+#warning hmm... susv3 says "Pipe streams are byte-oriented."
- #include <stdio.h>
- #include <stdlib.h>
-@@ -21,6 +22,8 @@
- #include <unistd.h>
- #include <sys/wait.h>
-+#include <bits/uClibc_mutex.h>
-+
- /* uClinux-2.0 has vfork, but Linux 2.0 doesn't */
- #include <sys/syscall.h>
- #if ! defined __NR_vfork
-@@ -29,19 +32,11 @@
- # define VFORK_UNLOCK ((void) 0)
- #endif
--#ifdef __UCLIBC_HAS_THREADS__
--#include <pthread.h>
--static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;
--# define LOCK                 __pthread_mutex_lock(&mylock)
--# define UNLOCK                       __pthread_mutex_unlock(&mylock);
--#else
--# define LOCK                 ((void) 0)
--# define UNLOCK                       ((void) 0)
--#endif      
-+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER);
- #ifndef VFORK_LOCK
--# define VFORK_LOCK           LOCK
--# define VFORK_UNLOCK UNLOCK
-+# define VFORK_LOCK           __UCLIBC_MUTEX_LOCK(mylock)
-+# define VFORK_UNLOCK __UCLIBC_MUTEX_UNLOCK(mylock)
- #endif
- struct popen_list_item {
-@@ -118,10 +113,10 @@ FILE *popen(const char *command, const c
-       if (pid > 0) {                          /* Parent of vfork... */
-               pi->pid = pid;
-               pi->f = fp;
--              LOCK;
-+              __UCLIBC_MUTEX_LOCK(mylock);
-               pi->next = popen_list;
-               popen_list = pi;
--              UNLOCK;
-+              __UCLIBC_MUTEX_UNLOCK(mylock);
-               
-               return fp;
-       }
-@@ -136,6 +131,8 @@ FILE *popen(const char *command, const c
-       return NULL;
- }
-+#warning is pclose correct wrt the new mutex semantics?
-+
- int pclose(FILE *stream)
- {
-       struct popen_list_item *p;
-@@ -144,7 +141,7 @@ int pclose(FILE *stream)
-       /* First, find the list entry corresponding to stream and remove it
-        * from the list.  Set p to the list item (NULL if not found). */
--      LOCK;
-+      __UCLIBC_MUTEX_LOCK(mylock);
-       if ((p = popen_list) != NULL) {
-               if (p->f == stream) {
-                       popen_list = p->next;
-@@ -163,7 +160,7 @@ int pclose(FILE *stream)
-                       } while (1);
-               }
-       }
--      UNLOCK;
-+      __UCLIBC_MUTEX_UNLOCK(mylock);
-       if (p) {
-               pid = p->pid;                   /* Save the pid we need */
-diff --git a/libc/stdio/setvbuf.c b/libc/stdio/setvbuf.c
-index 3fe62c6..6d53ab1 100644
---- a/libc/stdio/setvbuf.c
-+++ b/libc/stdio/setvbuf.c
-@@ -75,8 +75,8 @@ int setvbuf(register FILE * __restrict s
-       }
-       stream->__modeflags |= alloc_flag;
--      stream->__bufstart = buf;
--      stream->__bufend = buf + size;
-+      stream->__bufstart = (unsigned char *) buf;
-+      stream->__bufend = (unsigned char *) buf + size;
-       __STDIO_STREAM_INIT_BUFREAD_BUFPOS(stream);
-       __STDIO_STREAM_DISABLE_GETC(stream);
-       __STDIO_STREAM_DISABLE_PUTC(stream);
-diff --git a/libc/stdio/vasprintf.c b/libc/stdio/vasprintf.c
-index 688ab7c..6d7664d 100644
---- a/libc/stdio/vasprintf.c
-+++ b/libc/stdio/vasprintf.c
-@@ -63,6 +63,8 @@ int vasprintf(char **__restrict buf, con
-                               free(*buf);
-                               *buf = NULL;
-                       }
-+              } else {
-+                      rv = -1;
-               }
-       }
-diff --git a/libc/stdio/vdprintf.c b/libc/stdio/vdprintf.c
-index de8362c..7cb707f 100644
---- a/libc/stdio/vdprintf.c
-+++ b/libc/stdio/vdprintf.c
-@@ -15,8 +15,8 @@ int vdprintf(int filedes, const char * _
- #ifdef __STDIO_BUFFERS
-       char buf[64];                           /* TODO: provide _optional_ buffering? */
--      f.__bufend = buf + sizeof(buf);
--      f.__bufstart = buf;
-+      f.__bufend = (unsigned char *) buf + sizeof(buf);
-+      f.__bufstart = (unsigned char *) buf;
-       __STDIO_STREAM_DISABLE_GETC(&f);
-       __STDIO_STREAM_DISABLE_PUTC(&f);
-       __STDIO_STREAM_INIT_BUFREAD_BUFPOS(&f);
-diff --git a/libc/stdio/vfprintf.c b/libc/stdio/vfprintf.c
-index 10114f0..9214e3b 100644
---- a/libc/stdio/vfprintf.c
-+++ b/libc/stdio/vfprintf.c
-@@ -569,7 +569,7 @@ int _ppfs_init(register ppfs_t *ppfs, co
-               ppfs->fmtpos = fmt0;            /* rewind */
-       }
--#ifdef NL_MAX_ARG
-+#ifdef NL_ARGMAX
-       /* If we have positional args, make sure we know all the types. */
-       {
-               register int *p = ppfs->argtype;
-@@ -581,7 +581,7 @@ int _ppfs_init(register ppfs_t *ppfs, co
-                       ++p;
-               }
-       }
--#endif /* NL_MAX_ARG */
-+#endif /* NL_ARGMAX */
-       return 0;
- }
-@@ -1214,7 +1214,7 @@ static size_t _fp_out_narrow(FILE *fp, i
-               }
-               len = buflen;
-       }
--      return r + OUTNSTR(fp, (const char *) buf, len);
-+      return r + OUTNSTR(fp, (const unsigned char *) buf, len);
- }
- #endif /* __STDIO_PRINTF_FLOAT */
-diff --git a/libc/stdlib/abort.c b/libc/stdlib/abort.c
-index 77c2cdc..9f69918 100644
---- a/libc/stdlib/abort.c
-+++ b/libc/stdlib/abort.c
-@@ -70,16 +70,9 @@ extern void _exit __P((int __status)) __
- static int been_there_done_that = 0;
- /* Be prepared in case multiple threads try to abort() */
--#ifdef __UCLIBC_HAS_THREADS__
--# include <pthread.h>
--static pthread_mutex_t mylock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
--# define LOCK __pthread_mutex_lock(&mylock)
--# define UNLOCK       __pthread_mutex_unlock(&mylock)
--#else
--# define LOCK
--# define UNLOCK
--#endif
-+#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)
-@@ -87,7 +80,7 @@ void abort(void)
-       sigset_t sigset;
-       /* Make sure we acquire the lock before proceeding */
--      LOCK;
-+      __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE(mylock);
-       /* Unmask SIGABRT to be sure we can get it */
-       if (__sigemptyset(&sigset) == 0 && __sigaddset(&sigset, SIGABRT) == 0) {
-@@ -110,9 +103,9 @@ void abort(void)
- #endif
- abort_it:
--                      UNLOCK;
-+                      __UCLIBC_MUTEX_UNLOCK_CANCEL_UNSAFE(mylock);
-                       raise(SIGABRT);
--                      LOCK;
-+                      __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE(mylock);
-               }
-               /* Still here?  Try to remove any signal handlers */
-diff --git a/libc/stdlib/atexit.c b/libc/stdlib/atexit.c
-index 280f42c..b028068 100644
---- a/libc/stdlib/atexit.c
-+++ b/libc/stdlib/atexit.c
-@@ -40,17 +40,9 @@
- #include <stdlib.h>
- #include <errno.h>
-+#include <bits/uClibc_mutex.h>
--#ifdef __UCLIBC_HAS_THREADS__
--#include <pthread.h>
--extern pthread_mutex_t mylock;
--# define LOCK __pthread_mutex_lock(&mylock)
--# define UNLOCK       __pthread_mutex_unlock(&mylock);
--#else
--# define LOCK
--# define UNLOCK
--#endif
--
-+__UCLIBC_MUTEX_EXTERN(__atexit_lock);
- typedef void (*aefuncp) (void);         /* atexit function pointer */
- typedef void (*oefuncp) (int, void *);  /* on_exit function pointer */
-@@ -90,8 +82,9 @@ extern struct exit_function __exit_funct
- int atexit(aefuncp func)
- {
-     struct exit_function *efp;
-+    int rv = -1;
--    LOCK;
-+    __UCLIBC_MUTEX_LOCK(__atexit_lock);
-     if (func) {
- #ifdef __UCLIBC_DYNAMIC_ATEXIT__
-       /* If we are out of function table slots, make some more */
-@@ -99,18 +92,16 @@ int atexit(aefuncp func)
-           efp=realloc(__exit_function_table, 
-                                       (__exit_slots+20)*sizeof(struct exit_function));
-           if (efp==NULL) {
--              UNLOCK;
-               __set_errno(ENOMEM);
--              return -1;
-+              goto DONE;
-           }
-               __exit_function_table = efp;
-           __exit_slots+=20;
-       }
- #else
-       if (__exit_count >= __UCLIBC_MAX_ATEXIT) {
--          UNLOCK;
-           __set_errno(ENOMEM);
--          return -1;
-+          goto DONE;
-       }
- #endif
-       __exit_cleanup = __exit_handler; /* enable cleanup */
-@@ -118,8 +109,12 @@ int atexit(aefuncp func)
-       efp->type = ef_atexit;
-       efp->funcs.atexit = func;
-     }
--    UNLOCK;
--    return 0;
-+
-+    rv = 0;
-+
-+ DONE:
-+    __UCLIBC_MUTEX_UNLOCK(__atexit_lock);
-+    return rv;
- }
- #endif
-@@ -133,8 +128,9 @@ int atexit(aefuncp func)
- int on_exit(oefuncp func, void *arg)
- {
-     struct exit_function *efp;
-+    int rv = -1;
--    LOCK;
-+    __UCLIBC_MUTEX_LOCK(__atexit_lock);
-     if (func) {
- #ifdef __UCLIBC_DYNAMIC_ATEXIT__
-       /* If we are out of function table slots, make some more */
-@@ -142,18 +138,16 @@ int on_exit(oefuncp func, void *arg)
-           efp=realloc(__exit_function_table, 
-                                       (__exit_slots+20)*sizeof(struct exit_function));
-           if (efp==NULL) {
--              UNLOCK;
-               __set_errno(ENOMEM);
--              return -1;
-+              goto DONE;
-           }
-               __exit_function_table=efp;
-           __exit_slots+=20;
-       }
- #else
-       if (__exit_count >= __UCLIBC_MAX_ATEXIT) {
--          UNLOCK;
-           __set_errno(ENOMEM);
--          return -1;
-+          goto DONE;
-       }
- #endif
-@@ -163,8 +157,12 @@ int on_exit(oefuncp func, void *arg)
-       efp->funcs.on_exit.func = func;
-       efp->funcs.on_exit.arg = arg;
-     }
--    UNLOCK;
--    return 0;
-+
-+    rv = 0;
-+
-+ DONE:
-+    __UCLIBC_MUTEX_UNLOCK(__atexit_lock);
-+    return rv;
- }
- #endif
-@@ -214,9 +212,8 @@ void __exit_handler(int status)
- #ifdef L_exit
- extern void weak_function _stdio_term(void);
- void (*__exit_cleanup) (int) = 0;
--#ifdef __UCLIBC_HAS_THREADS__
--pthread_mutex_t mylock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
--#endif
-+
-+__UCLIBC_MUTEX_INIT(__atexit_lock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);
- #ifdef __UCLIBC_CTOR_DTOR__
- extern void (*__app_fini)(void);
-@@ -229,11 +226,11 @@ extern void (*__rtld_fini)(void);
- void exit(int rv)
- {
-       /* Perform exit-specific cleanup (atexit and on_exit) */
--      LOCK;
-+      __UCLIBC_MUTEX_LOCK(__atexit_lock);
-       if (__exit_cleanup) {
-               __exit_cleanup(rv);
-       }
--      UNLOCK;
-+      __UCLIBC_MUTEX_UNLOCK(__atexit_lock);
- #ifdef __UCLIBC_CTOR_DTOR__
-       if (__app_fini != NULL)
-diff --git a/libc/stdlib/malloc-simple/alloc.c b/libc/stdlib/malloc-simple/alloc.c
-index ed14c37..519a875 100644
---- a/libc/stdlib/malloc-simple/alloc.c
-+++ b/libc/stdlib/malloc-simple/alloc.c
-@@ -108,15 +108,14 @@ void free(void *ptr)
- #endif
- #ifdef L_memalign
--#ifdef __UCLIBC_HAS_THREADS__
--#include <pthread.h>
--pthread_mutex_t __malloc_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
--# define LOCK __pthread_mutex_lock(&__malloc_lock)
--# define UNLOCK       __pthread_mutex_unlock(&__malloc_lock);
--#else
--# define LOCK
--# define UNLOCK
--#endif
-+
-+#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)
-+
- /* List of blocks allocated with memalign or valloc */
- struct alignlist
-@@ -135,7 +134,7 @@ int __libc_free_aligned(void *ptr)
-       if (ptr == NULL)
-               return 0;
--      LOCK;
-+      __MALLOC_LOCK;
-       for (l = _aligned_blocks; l != NULL; l = l->next) {
-               if (l->aligned == ptr) {
-                       /* Mark the block as free */
-@@ -146,7 +145,7 @@ int __libc_free_aligned(void *ptr)
-                       return 1;
-               }
-       }
--      UNLOCK;
-+      __MALLOC_UNLOCK;
-       return 0;
- }
- void * memalign (size_t alignment, size_t size)
-@@ -159,10 +158,10 @@ void * memalign (size_t alignment, size_
-               return NULL;
-       adj = (unsigned long int) ((unsigned long int) ((char *) result -
--            (char *) NULL)) % alignment;
-+                                                                                                      (char *) NULL)) % alignment;
-       if (adj != 0) {
-               struct alignlist *l;
--              LOCK;
-+              __MALLOC_LOCK;
-               for (l = _aligned_blocks; l != NULL; l = l->next)
-                       if (l->aligned == NULL)
-                               /* This slot is free.  Use it.  */
-@@ -171,15 +170,16 @@ void * memalign (size_t alignment, size_
-                       l = (struct alignlist *) malloc (sizeof (struct alignlist));
-                       if (l == NULL) {
-                               free(result);
--                              UNLOCK;
--                              return NULL;
-+                              result = NULL;
-+                              goto DONE;
-                       }
-                       l->next = _aligned_blocks;
-                       _aligned_blocks = l;
-               }
-               l->exact = result;
-               result = l->aligned = (char *) result + alignment - adj;
--              UNLOCK;
-+      DONE:
-+              __MALLOC_UNLOCK;
-       }
-       return result;
-diff --git a/libc/stdlib/malloc-standard/calloc.c b/libc/stdlib/malloc-standard/calloc.c
-index a67dad7..4277954 100644
---- a/libc/stdlib/malloc-standard/calloc.c
-+++ b/libc/stdlib/malloc-standard/calloc.c
-@@ -8,7 +8,7 @@
-   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
-+  ftp://gee.cs.oswego.edu/pub/misc/malloc.c
-   Check before installing!
-   Hacked up for uClibc by Erik Andersen <andersen@codepoet.org>
-@@ -31,63 +31,63 @@ void* calloc(size_t n_elements, size_t e
-      * 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;
-+              __set_errno(ENOMEM);
-+              return NULL;
-     }
--    LOCK;
-+    __MALLOC_LOCK;
-     mem = malloc(size);
-     if (mem != 0) {
--      p = mem2chunk(mem);
-+              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 (!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);
--      }
-+              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
-     }
--    UNLOCK;
-+    __MALLOC_UNLOCK;
-     return mem;
- }
-diff --git a/libc/stdlib/malloc-standard/free.c b/libc/stdlib/malloc-standard/free.c
-index 94e1d65..4e08ef7 100644
---- a/libc/stdlib/malloc-standard/free.c
-+++ b/libc/stdlib/malloc-standard/free.c
-@@ -8,7 +8,7 @@
-   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
-+  ftp://gee.cs.oswego.edu/pub/misc/malloc.c
-   Check before installing!
-   Hacked up for uClibc by Erik Andersen <andersen@codepoet.org>
-@@ -42,71 +42,71 @@ static int __malloc_trim(size_t pad, mst
-     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;
-+              /*
-+                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);
-+   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.
-+   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);
-+      mstate av = get_malloc_state();
-+      __malloc_consolidate(av);
-+      return __malloc_trim(pad, av);
- }
- /*
-@@ -125,8 +125,8 @@ static void malloc_init_state(mstate av)
-     /* Establish circular links for normal bins */
-     for (i = 1; i < NBINS; ++i) {
--      bin = bin_at(av,i);
--      bin->fd = bin->bk = bin;
-+              bin = bin_at(av,i);
-+              bin->fd = bin->bk = bin;
-     }
-     av->top_pad        = DEFAULT_TOP_PAD;
-@@ -157,15 +157,15 @@ static void malloc_init_state(mstate av)
- /* ------------------------- __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.
-+__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 __malloc_consolidate(mstate av)
- {
-@@ -186,78 +186,78 @@ void __malloc_consolidate(mstate av)
-     mchunkptr       fwd;
-     /*
--       If max_fast is 0, we know that av hasn't
--       yet been initialized, in which case do so below
--       */
-+        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);
-+              clear_fastchunks(av);
--      unsorted_bin = unsorted_chunks(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;
-+              /*
-+                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 {
--                  check_inuse_chunk(p);
--                  nextp = p->fd;
-+                      if ( (p = *fb) != 0) {
-+                              *fb = 0;
--                  /* Slightly streamlined version of consolidation code in free() */
--                  size = p->size & ~PREV_INUSE;
--                  nextchunk = chunk_at_offset(p, size);
--                  nextsize = chunksize(nextchunk);
-+                              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;
-+                                      }
--                  if (!prev_inuse(p)) {
--                      prevsize = p->prev_size;
--                      size += prevsize;
--                      p = chunk_at_offset(p, -((long) prevsize));
--                      unlink(p, bck, fwd);
--                  }
-+                              } while ( (p = nextp) != 0);
--                  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);
-+              } while (fb++ != maxfb);
-     }
-     else {
--      malloc_init_state(av);
--      check_malloc_state();
-+              malloc_init_state(av);
-+              check_malloc_state();
-     }
- }
-@@ -279,9 +279,9 @@ void free(void* mem)
-     /* free(0) has no effect */
-     if (mem == NULL)
--      return;
-+              return;
--    LOCK;
-+    __MALLOC_LOCK;
-     av = get_malloc_state();
-     p = mem2chunk(mem);
-     size = chunksize(p);
-@@ -289,9 +289,9 @@ void free(void* mem)
-     check_inuse_chunk(p);
-     /*
--       If eligible, place chunk on a fastbin so it can be found
--       and used quickly in malloc.
--       */
-+        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)
-@@ -300,114 +300,114 @@ void free(void* mem)
-              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;
-+              set_fastchunks(av);
-+              fb = &(av->fastbins[fastbin_index(size)]);
-+              p->fd = *fb;
-+              *fb = p;
-     }
-     /*
--       Consolidate other non-mmapped chunks as they arrive.
--       */
-+        Consolidate other non-mmapped chunks as they arrive.
-+      */
-     else if (!chunk_is_mmapped(p)) {
--      set_anychunks(av);
-+              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;
--      nextchunk = chunk_at_offset(p, size);
--      nextsize = chunksize(nextchunk);
-+                      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
-+              */
--      /* 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);
--      }
-+              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.
--       */
-+        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 {
--      int ret;
--      size_t offset = p->prev_size;
--      av->n_mmaps--;
--      av->mmapped_mem -= (size + offset);
--      ret = munmap((char*)p - offset, size + offset);
--      /* munmap returns non-zero on failure */
--      assert(ret == 0);
-+              int ret;
-+              size_t offset = p->prev_size;
-+              av->n_mmaps--;
-+              av->mmapped_mem -= (size + offset);
-+              ret = munmap((char*)p - offset, size + offset);
-+              /* munmap returns non-zero on failure */
-+              assert(ret == 0);
-     }
--    UNLOCK;
-+    __MALLOC_UNLOCK;
- }
-diff --git a/libc/stdlib/malloc-standard/mallinfo.c b/libc/stdlib/malloc-standard/mallinfo.c
-index 51ac423..1e0875c 100644
---- a/libc/stdlib/malloc-standard/mallinfo.c
-+++ b/libc/stdlib/malloc-standard/mallinfo.c
-@@ -8,7 +8,7 @@
-   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
-+  ftp://gee.cs.oswego.edu/pub/misc/malloc.c
-   Check before installing!
-   Hacked up for uClibc by Erik Andersen <andersen@codepoet.org>
-@@ -30,11 +30,11 @@ struct mallinfo mallinfo(void)
-     int nblocks;
-     int nfastblocks;
--    LOCK;
-+    __MALLOC_LOCK;
-     av = get_malloc_state();
-     /* Ensure initialization */
-     if (av->top == 0)  {
--      __malloc_consolidate(av);
-+              __malloc_consolidate(av);
-     }
-     check_malloc_state();
-@@ -48,21 +48,21 @@ struct mallinfo mallinfo(void)
-     fastavail = 0;
-     for (i = 0; i < NFASTBINS; ++i) {
--      for (p = av->fastbins[i]; p != 0; p = p->fd) {
--          ++nfastblocks;
--          fastavail += chunksize(p);
--      }
-+              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);
--      }
-+              b = bin_at(av, i);
-+              for (p = last(b); p != b; p = p->bk) {
-+                      ++nblocks;
-+                      avail += chunksize(p);
-+              }
-     }
-     mi.smblks = nfastblocks;
-@@ -75,7 +75,7 @@ struct mallinfo mallinfo(void)
-     mi.fsmblks = fastavail;
-     mi.keepcost = chunksize(av->top);
-     mi.usmblks = av->max_total_mem;
--    UNLOCK;
-+    __MALLOC_UNLOCK;
-     return mi;
- }
-@@ -84,23 +84,40 @@ void malloc_stats(FILE *file)
-     struct mallinfo mi;
-     if (file==NULL) {
--      file = stderr;
-+              file = stderr;
-     }
-     mi = mallinfo();
--    fprintf(file, "total bytes allocated             = %10u\n", (unsigned int)(mi.arena + mi.hblkhd));
--    fprintf(file, "total bytes in use bytes          = %10u\n", (unsigned int)(mi.uordblks + mi.hblkhd));
--    fprintf(file, "total non-mmapped bytes allocated = %10d\n", mi.arena);
--    fprintf(file, "number of mmapped regions         = %10d\n", mi.hblks);
--    fprintf(file, "total allocated mmap space        = %10d\n", mi.hblkhd);
--    fprintf(file, "total allocated sbrk space        = %10d\n", mi.uordblks);
-+    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
--    fprintf(file, "number of free chunks             = %10d\n", mi.ordblks);
--    fprintf(file, "number of fastbin blocks          = %10d\n", mi.smblks);
--    fprintf(file, "space in freed fastbin blocks     = %10d\n", mi.fsmblks);
-+                      "number of free chunks             = %10d\n"
-+                      "number of fastbin blocks          = %10d\n"
-+                      "space in freed fastbin blocks     = %10d\n"
- #endif
--    fprintf(file, "maximum total allocated space     = %10d\n", mi.usmblks);
--    fprintf(file, "total free space                  = %10d\n", mi.fordblks);
--    fprintf(file, "memory releasable via malloc_trim = %10d\n", mi.keepcost);
-+                      "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/libc/stdlib/malloc-standard/malloc.c b/libc/stdlib/malloc-standard/malloc.c
-index 7025e83..60494a0 100644
---- a/libc/stdlib/malloc-standard/malloc.c
-+++ b/libc/stdlib/malloc-standard/malloc.c
-@@ -8,7 +8,7 @@
-   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
-+  ftp://gee.cs.oswego.edu/pub/misc/malloc.c
-   Check before installing!
-   Hacked up for uClibc by Erik Andersen <andersen@codepoet.org>
-@@ -17,17 +17,14 @@
- #define _GNU_SOURCE
- #include "malloc.h"
--
--#ifdef __UCLIBC_HAS_THREADS__
--pthread_mutex_t __malloc_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
--#endif
-+__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).
-+  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 */
-@@ -77,30 +74,30 @@ void __do_check_chunk(mchunkptr p)
-     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));
--      }
-+              /* 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)));
-+              /* 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)));
-     }
- }
-@@ -121,21 +118,21 @@ void __do_check_free_chunk(mchunkptr 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);
--    }
-+              {
-+                      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)));
-+              assert(sz == (sizeof(size_t)));
- }
- /* Properties of inuse chunks */
-@@ -146,7 +143,7 @@ void __do_check_inuse_chunk(mchunkptr p)
-     __do_check_chunk(p);
-     if (chunk_is_mmapped(p))
--      return; /* mmapped chunks have no next/prev */
-+              return; /* mmapped chunks have no next/prev */
-     /* Check whether it claims to be in use ... */
-     assert(inuse(p));
-@@ -156,20 +153,20 @@ void __do_check_inuse_chunk(mchunkptr 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);
-+              /* 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);
-+              assert(prev_inuse(next));
-+              assert(chunksize(next) >= MINSIZE);
-     }
-     else if (!inuse(next))
--      __do_check_free_chunk(next);
-+              __do_check_free_chunk(next);
- }
- /* Properties of chunks recycled from fastbins */
-@@ -198,14 +195,14 @@ void __do_check_malloced_chunk(mchunkptr
-     __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.
--       */
-+        ... 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));
- }
-@@ -243,7 +240,7 @@ void __do_check_malloc_state(void)
-     /* cannot run remaining checks until fully initialized */
-     if (av->top == 0 || av->top == initial_top(av))
--      return;
-+              return;
-     /* pagesize is a power of 2 */
-     assert((av->pagesize & (av->pagesize-1)) == 0);
-@@ -256,64 +253,64 @@ void __do_check_malloc_state(void)
-     max_fast_bin = fastbin_index(av->max_fast);
-     for (i = 0; i < NFASTBINS; ++i) {
--      p = av->fastbins[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;
--      }
-+              /* 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));
-+              assert(have_fastchunks(av));
-     else if (!have_fastchunks(av))
--      assert(total == 0);
-+              assert(total == 0);
-     /* check normal bins */
-     for (i = 1; i < NBINS; ++i) {
--      b = bin_at(av,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);
--      }
-+              /* 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 */
-@@ -326,13 +323,13 @@ void __do_check_malloc_state(void)
-     assert(av->n_mmaps <= av->max_n_mmaps);
-     assert((unsigned long)(av->sbrked_mem) <=
--          (unsigned long)(av->max_sbrked_mem));
-+                 (unsigned long)(av->max_sbrked_mem));
-     assert((unsigned long)(av->mmapped_mem) <=
--          (unsigned long)(av->max_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));
-+                 (unsigned long)(av->mmapped_mem) + (unsigned long)(av->sbrked_mem));
- }
- #endif
-@@ -370,84 +367,84 @@ static void* __malloc_alloc(size_t nb, m
-     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 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);
-+              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 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)) {
-+              char* mm;             /* return value from mmap call*/
-               /*
--                 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);
--              }
-+                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;
--              /* update statistics */
-+                              check_chunk(p);
--              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);
--          }
--      }
-+                              return chunk2mem(p);
-+                      }
-+              }
-     }
-     /* Record incoming configuration of top */
-@@ -462,8 +459,8 @@ static void* __malloc_alloc(size_t nb, m
-      * 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)));
-+                 ((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));
-@@ -477,272 +474,272 @@ static void* __malloc_alloc(size_t nb, m
-     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, 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;
-+              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.
--       */
-+        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.
--       */
-+        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)
--      brk = (char*)(MORECORE(size));
-+              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 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 (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)) {
--
--          brk = (char*)(MMAP(0, size, PROT_READ|PROT_WRITE));
--
--          if (brk != (char*)(MORECORE_FAILURE)) {
--
--              /* We do not need, and cannot use, another sbrk call to find end */
--              snd_brk = 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);
--          }
--      }
-+              /* 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)) {
-+
-+                      brk = (char*)(MMAP(0, size, PROT_READ|PROT_WRITE));
-+
-+                      if (brk != (char*)(MORECORE_FAILURE)) {
-+
-+                              /* We do not need, and cannot use, another sbrk call to find end */
-+                              snd_brk = 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 (brk != (char*)(MORECORE_FAILURE)) {
--      av->sbrked_mem += size;
-+              av->sbrked_mem += size;
--      /*
--         If MORECORE extends previous space, we can likewise extend top size.
--         */
--
--      if (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 = 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 && 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 += brk - old_end;
--
--              /* Guarantee alignment of first new chunk made from this space */
--
--              front_misalign = (size_t)chunk2mem(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.
--                     */
-+              /*
-+                If MORECORE extends previous space, we can likewise extend top size.
-+              */
--                  correction = MALLOC_ALIGNMENT - front_misalign;
--                  aligned_brk += correction;
-+              if (brk == old_end && snd_brk == (char*)(MORECORE_FAILURE)) {
-+                      set_head(old_top, (size + old_size) | PREV_INUSE);
-               }
-               /*
--                 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)(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 < 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 = brk + size;
--                  correction = 0;
--                  set_noncontiguous(av);
--              }
--
--          }
--
--          /* handle non-contiguous cases */
--          else {
--              /* MORECORE/mmap must correctly align */
--              assert(aligned_OK(chunk2mem(brk)));
--
--              /* Find out current end of memory */
--              if (snd_brk == (char*)(MORECORE_FAILURE)) {
--                  snd_brk = (char*)(MORECORE(0));
--                  av->sbrked_mem += snd_brk - 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;
-+                Otherwise, make adjustments:
--              /*
--                 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);
--      }
-+                * 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 = 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 && 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 += brk - old_end;
-+
-+                              /* Guarantee alignment of first new chunk made from this space */
-+
-+                              front_misalign = (size_t)chunk2mem(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)(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 < 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 = brk + size;
-+                                      correction = 0;
-+                                      set_noncontiguous(av);
-+                              }
-+
-+                      }
-+
-+                      /* handle non-contiguous cases */
-+                      else {
-+                              /* MORECORE/mmap must correctly align */
-+                              assert(aligned_OK(chunk2mem(brk)));
-+
-+                              /* Find out current end of memory */
-+                              if (snd_brk == (char*)(MORECORE_FAILURE)) {
-+                                      snd_brk = (char*)(MORECORE(0));
-+                                      av->sbrked_mem += snd_brk - 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);
-+              }
-     }
-@@ -767,25 +764,25 @@ static int __malloc_largebin_index(unsig
- #if defined(__GNUC__) && defined(i386)
-     __asm__("bsrl %1,%0\n\t"
--          : "=r" (m)
--          : "g"  (x));
-+                      : "=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));
-+              /*
-+                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
-@@ -826,69 +823,70 @@ void* malloc(size_t bytes)
-     mchunkptr       fwd;              /* misc temp for linking */
-     mchunkptr       bck;              /* misc temp for linking */
-     void *          sysmem;
-+      void *          retval;
- #if !defined(__MALLOC_GLIBC_COMPAT__)
-     if (!bytes) return NULL;
- #endif
--    LOCK;
-+    __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.
--       */
-+        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
--       */
-+        Bypass search if no frees yet
-+      */
-     if (!have_anychunks(av)) {
--      if (av->max_fast == 0) /* initialization check */
--          __malloc_consolidate(av);
--      goto use_top;
-+              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 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);
--          UNLOCK;
--          return chunk2mem(victim);
--      }
-+              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 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);
-+              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);
--          UNLOCK;
--          return chunk2mem(victim);
--      }
-+              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.
-@@ -899,154 +897,154 @@ void* malloc(size_t bytes)
-        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);
-+              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.
--       */
-+        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);
-+              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 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);
--          UNLOCK;
--          return chunk2mem(victim);
--      }
--
--      /* 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);
--          UNLOCK;
--          return chunk2mem(victim);
--      }
--
--      /* 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 (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 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);
-+              bin = bin_at(av, idx);
--          if ((unsigned long)(size) >= (unsigned long)(nb)) {
--              remainder_size = size - nb;
--              unlink(victim, bck, fwd);
-+              for (victim = last(bin); victim != bin; victim = victim->bk) {
-+                      size = chunksize(victim);
--              /* Exhaust */
--              if (remainder_size < MINSIZE)  {
--                  set_inuse_bit_at_offset(victim, size);
--                  check_malloced_chunk(victim, nb);
--                  UNLOCK;
--                  return chunk2mem(victim);
--              }
--              /* 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);
--                  UNLOCK;
--                  return chunk2mem(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.
-+        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.
--       */
-+        The bitmap avoids needing to check that most blocks are nonempty.
-+      */
-     ++idx;
-     bin = bin_at(av,idx);
-@@ -1056,109 +1054,111 @@ void* malloc(size_t bytes)
-     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);
--              UNLOCK;
--              return chunk2mem(victim);
--          }
-+              /* 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);
--          /* Split */
--          else {
--              remainder = chunk_at_offset(victim, nb);
-+                      bin = bin_at(av, (block << BINMAPSHIFT));
-+                      bit = 1;
-+              }
--              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;
-+              /* Advance to bin with set bit. There must be one. */
-+              while ((bit & map) == 0) {
-+                      bin = next_bin(bin);
-+                      bit <<= 1;
-+                      assert(bit != 0);
-+              }
--              set_head(victim, nb | PREV_INUSE);
--              set_head(remainder, remainder_size | PREV_INUSE);
--              set_foot(remainder, remainder_size);
--              check_malloced_chunk(victim, nb);
--              UNLOCK;
--              return chunk2mem(victim);
--          }
--      }
-+              /* 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:
-+ 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.)
--       */
-+        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);
--      UNLOCK;
--      return chunk2mem(victim);
-+              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);
--    UNLOCK;
--    return sysmem;
-+    retval = sysmem;
-+ DONE:
-+      __MALLOC_UNLOCK;
-+      return retval;
- }
-diff --git a/libc/stdlib/malloc-standard/malloc.h b/libc/stdlib/malloc-standard/malloc.h
-index fbc1492..14a0dd9 100644
---- a/libc/stdlib/malloc-standard/malloc.h
-+++ b/libc/stdlib/malloc-standard/malloc.h
-@@ -22,16 +22,12 @@
- #include <malloc.h>
- #include <stdlib.h>
-+#include <bits/uClibc_mutex.h>
--#ifdef __UCLIBC_HAS_THREADS__
--#include <pthread.h>
--extern pthread_mutex_t __malloc_lock;
--# define LOCK __pthread_mutex_lock(&__malloc_lock)
--# define UNLOCK       __pthread_mutex_unlock(&__malloc_lock);
--#else
--# define LOCK
--# define UNLOCK
--#endif
-+__UCLIBC_MUTEX_EXTERN(__malloc_lock);
-+
-+#define __MALLOC_LOCK         __UCLIBC_MUTEX_LOCK(__malloc_lock)
-+#define __MALLOC_UNLOCK               __UCLIBC_MUTEX_UNLOCK(__malloc_lock)
-diff --git a/libc/stdlib/malloc-standard/mallopt.c b/libc/stdlib/malloc-standard/mallopt.c
-index e287920..41aa614 100644
---- a/libc/stdlib/malloc-standard/mallopt.c
-+++ b/libc/stdlib/malloc-standard/mallopt.c
-@@ -8,7 +8,7 @@
-   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
-+  ftp://gee.cs.oswego.edu/pub/misc/malloc.c
-   Check before installing!
-   Hacked up for uClibc by Erik Andersen <andersen@codepoet.org>
-@@ -25,40 +25,40 @@ int mallopt(int param_number, int value)
-     ret = 0;
--    LOCK;
-+    __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;
-+              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;
-     }
--    UNLOCK;
-+    __MALLOC_UNLOCK;
-     return ret;
- }
-diff --git a/libc/stdlib/malloc-standard/memalign.c b/libc/stdlib/malloc-standard/memalign.c
-index bd95362..e78d752 100644
---- a/libc/stdlib/malloc-standard/memalign.c
-+++ b/libc/stdlib/malloc-standard/memalign.c
-@@ -8,7 +8,7 @@
-   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
-+  ftp://gee.cs.oswego.edu/pub/misc/malloc.c
-   Check before installing!
-   Hacked up for uClibc by Erik Andersen <andersen@codepoet.org>
-@@ -35,6 +35,7 @@ void* memalign(size_t alignment, size_t 
-     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 */
-@@ -46,12 +47,12 @@ void* memalign(size_t alignment, size_t 
-     /* 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;
-+              size_t a = MALLOC_ALIGNMENT * 2;
-+              while ((unsigned long)a < (unsigned long)alignment) a <<= 1;
-+              alignment = a;
-     }
--    LOCK;
-+    __MALLOC_LOCK;
-     checked_request2size(bytes, nb);
-     /* Strategy: find a spot within that chunk that meets the alignment
-@@ -63,64 +64,67 @@ void* memalign(size_t alignment, size_t 
-     m  = (char*)(malloc(nb + alignment + MINSIZE));
-     if (m == 0) {
--      UNLOCK;
--      return 0; /* propagate failure */
-+              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);
--          UNLOCK;
--          return chunk2mem(newp);
--      }
--
--      /* 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;
-+              /*
-+                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);
-+              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));
--      }
-+              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);
--    UNLOCK;
--    return chunk2mem(p);
-+    retval = chunk2mem(p);
-+
-+ DONE:
-+    __MALLOC_UNLOCK;
-+      return retval;
- }
-diff --git a/libc/stdlib/malloc-standard/realloc.c b/libc/stdlib/malloc-standard/realloc.c
-index 1950130..9ca4b26 100644
---- a/libc/stdlib/malloc-standard/realloc.c
-+++ b/libc/stdlib/malloc-standard/realloc.c
-@@ -8,7 +8,7 @@
-   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
-+  ftp://gee.cs.oswego.edu/pub/misc/malloc.c
-   Check before installing!
-   Hacked up for uClibc by Erik Andersen <andersen@codepoet.org>
-@@ -23,14 +23,14 @@ void* realloc(void* oldmem, size_t bytes
- {
-     mstate av;
--    size_t  nb;              /* padded request size */
-+    size_t  nb;                       /* padded request size */
-     mchunkptr        oldp;            /* chunk corresponding to oldmem */
--    size_t  oldsize;         /* its size */
-+    size_t  oldsize;                  /* its size */
-     mchunkptr        newp;            /* chunk to return */
--    size_t  newsize;         /* its size */
--    void*          newmem;          /* corresponding user mem */
-+    size_t  newsize;                  /* its size */
-+    void*          newmem;            /* corresponding user mem */
-     mchunkptr        next;            /* next contiguous chunk after oldp */
-@@ -40,21 +40,23 @@ void* realloc(void* oldmem, size_t bytes
-     mchunkptr        bck;             /* misc temp for linking */
-     mchunkptr        fwd;             /* misc temp for linking */
--    unsigned long     copysize;        /* bytes to copy */
-+    unsigned long     copysize;       /* bytes to copy */
-     unsigned int     ncopies;         /* size_t words to copy */
--    size_t* s;               /* copy source */
--    size_t* d;               /* copy destination */
-+    size_t* s;                        /* copy source */
-+    size_t* d;                        /* copy destination */
-+
-+      void *retval;
-     /* Check for special cases.  */
-     if (! oldmem)
--      return malloc(bytes);
-+              return malloc(bytes);
-     if (! bytes) {
--      free (oldmem);
--      return malloc(bytes);
-+              free (oldmem);
-+              return malloc(bytes);
-     }
--    LOCK;
-+    __MALLOC_LOCK;
-     av = get_malloc_state();
-     checked_request2size(bytes, nb);
-@@ -65,173 +67,176 @@ void* realloc(void* oldmem, size_t bytes
-     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);
--              UNLOCK;
--              return chunk2mem(oldp);
--          }
--
--          /* 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) {
--                  UNLOCK;
--                  return 0; /* propagate failure */
--              }
--
--              newp = mem2chunk(newmem);
--              newsize = chunksize(newp);
--
--              /*
--                 Avoid copy if newp is next chunk after oldp.
--                 */
--              if (newp == next) {
--                  newsize += oldsize;
--                  newp = oldp;
-+              if ((unsigned long)(oldsize) >= (unsigned long)(nb)) {
-+                      /* already big enough; split below */
-+                      newp = oldp;
-+                      newsize = oldsize;
-               }
-+
-               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);
-+                      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;
--                  free(oldmem);
--                  check_inuse_chunk(newp);
--                  UNLOCK;
--                  return chunk2mem(newp);
--              }
--          }
--      }
--
--      /* 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);
--      UNLOCK;
--      return chunk2mem(newp);
-+              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
--       */
-+        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) {
--          UNLOCK;
--          return oldmem;
--      }
--
--      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;
--
--          UNLOCK;
--          return chunk2mem(newp);
--      }
--
--      /* 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);
--          }
--      }
--      UNLOCK;
--      return newmem;
-+              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/libc/stdlib/random.c b/libc/stdlib/random.c
-index b0a00e1..1bd63bc 100644
---- a/libc/stdlib/random.c
-+++ b/libc/stdlib/random.c
-@@ -27,16 +27,14 @@
- #include <limits.h>
- #include <stddef.h>
- #include <stdlib.h>
--#ifdef __UCLIBC_HAS_THREADS__
--#include <pthread.h>
-+
- /* POSIX.1c requires that there is mutual exclusion for the `rand' and
-    `srand' functions to prevent concurrent calls from modifying common
-    data.  */
--static pthread_mutex_t lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
--#else
--#define __pthread_mutex_lock(x)
--#define __pthread_mutex_unlock(x)
--#endif
-+
-+#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
-@@ -184,9 +182,9 @@ static struct random_data unsafe_state =
-    for default usage relies on values produced by this routine.  */
- void srandom (unsigned int x)
- {
--    __pthread_mutex_lock(&lock);
-+    __UCLIBC_MUTEX_LOCK(mylock);
-     srandom_r (x, &unsafe_state);
--    __pthread_mutex_unlock(&lock);
-+    __UCLIBC_MUTEX_UNLOCK(mylock);
- }
- weak_alias (srandom, srand)
-@@ -205,10 +203,10 @@ char * initstate (unsigned int seed, cha
- {
-     int32_t *ostate;
--    __pthread_mutex_lock(&lock);
-+    __UCLIBC_MUTEX_LOCK(mylock);
-     ostate = &unsafe_state.state[-1];
-     initstate_r (seed, arg_state, n, &unsafe_state);
--    __pthread_mutex_unlock(&lock);
-+    __UCLIBC_MUTEX_UNLOCK(mylock);
-     return (char *) ostate;
- }
-@@ -224,11 +222,11 @@ char * setstate (char *arg_state)
- {
-     int32_t *ostate;
--    __pthread_mutex_lock(&lock);
-+    __UCLIBC_MUTEX_LOCK(mylock);
-     ostate = &unsafe_state.state[-1];
-     if (setstate_r (arg_state, &unsafe_state) < 0)
-       ostate = NULL;
--    __pthread_mutex_unlock(&lock);
-+    __UCLIBC_MUTEX_UNLOCK(mylock);
-     return (char *) ostate;
- }
-@@ -247,9 +245,9 @@ long int random ()
- {
-   int32_t retval;
--  __pthread_mutex_lock(&lock);
-+  __UCLIBC_MUTEX_LOCK(mylock);
-   random_r (&unsafe_state, &retval);
--  __pthread_mutex_unlock(&lock);
-+  __UCLIBC_MUTEX_UNLOCK(mylock);
-   return retval;
- }
-diff --git a/libc/stdlib/setenv.c b/libc/stdlib/setenv.c
-index d0cfe52..2d899cc 100644
---- a/libc/stdlib/setenv.c
-+++ b/libc/stdlib/setenv.c
-@@ -17,7 +17,7 @@
-    02111-1307 USA.  
-    
-    modified for uClibc by Erik Andersen <andersen@codepoet.org>
--   */
-+*/
- #define _GNU_SOURCE
- #include <features.h>
-@@ -26,16 +26,9 @@
- #include <string.h>
- #include <unistd.h>
--#ifdef __UCLIBC_HAS_THREADS__
--#include <pthread.h>
--static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;
--# define LOCK __pthread_mutex_lock(&mylock)
--# define UNLOCK       __pthread_mutex_unlock(&mylock);
--#else
--# define LOCK
--# define UNLOCK
--#endif
-+#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.  */
-@@ -49,14 +42,15 @@ static char **last_environ;
-    to reuse values once generated for a `setenv' call since we can never
-    free the strings.  */
- int __add_to_environ (const char *name, const char *value, 
--      const char *combined, int replace)
-+                                        const char *combined, int replace)
- {
-     register char **ep;
-     register size_t size;
-     const size_t namelen = strlen (name);
-     const size_t vallen = value != NULL ? strlen (value) + 1 : 0;
-+    int rv = -1;
--    LOCK;
-+    __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.  */
-@@ -64,72 +58,72 @@ int __add_to_environ (const char *name, 
-     size = 0;
-     if (ep != NULL) {
--      for (; *ep != NULL; ++ep) {
--          if (!strncmp (*ep, name, namelen) && (*ep)[namelen] == '=')
--              break;
--          else
--              ++size;
--      }
-+              for (; *ep != NULL; ++ep) {
-+                      if (!strncmp (*ep, name, namelen) && (*ep)[namelen] == '=')
-+                              break;
-+                      else
-+                              ++size;
-+              }
-     }
-     if (ep == NULL || *ep == NULL) {
--      char **new_environ;
-+              char **new_environ;
--      /* We allocated this space; we can extend it.  */
--      new_environ = (char **) realloc (last_environ,
--              (size + 2) * sizeof (char *));
--      if (new_environ == NULL) {
--          UNLOCK;
--          return -1;
--      }
--
--      /* If the whole entry is given add it.  */
--      if (combined != NULL) {
--          /* We must not add the string to the search tree since it belongs
--             to the user.  */
--          new_environ[size] = (char *) combined;
--      } else {
--          /* See whether the value is already known.  */
--          new_environ[size] = (char *) malloc (namelen + 1 + vallen);
--          if (new_environ[size] == NULL) {
--              __set_errno (ENOMEM);
--              UNLOCK;
--              return -1;
--          }
--
--          memcpy (new_environ[size], name, namelen);
--          new_environ[size][namelen] = '=';
--          memcpy (&new_environ[size][namelen + 1], value, vallen);
--      }
--
--      if (__environ != last_environ) {
--          memcpy ((char *) new_environ, (char *) __environ,
--                  size * sizeof (char *));
--      }
-+              /* We allocated this space; we can extend it.  */
-+              new_environ = (char **) realloc (last_environ,
-+                                                                               (size + 2) * sizeof (char *));
-+              if (new_environ == NULL) {
-+                      goto DONE;
-+              }
-+
-+              /* If the whole entry is given add it.  */
-+              if (combined != NULL) {
-+                      /* We must not add the string to the search tree since it belongs
-+                         to the user.  */
-+                      new_environ[size] = (char *) combined;
-+              } else {
-+                      /* See whether the value is already known.  */
-+                      new_environ[size] = (char *) malloc (namelen + 1 + vallen);
-+                      if (new_environ[size] == NULL) {
-+                              __set_errno (ENOMEM);
-+                              goto DONE;
-+                      }
-+
-+                      memcpy (new_environ[size], name, namelen);
-+                      new_environ[size][namelen] = '=';
-+                      memcpy (&new_environ[size][namelen + 1], value, vallen);
-+              }
-+
-+              if (__environ != last_environ) {
-+                      memcpy ((char *) new_environ, (char *) __environ,
-+                                      size * sizeof (char *));
-+              }
--      new_environ[size + 1] = NULL;
--      last_environ = __environ = new_environ;
-+              new_environ[size + 1] = NULL;
-+              last_environ = __environ = new_environ;
-     } else if (replace) {
--      char *np;
-+              char *np;
--      /* Use the user string if given.  */
--      if (combined != NULL) {
--          np = (char *) combined;
--      } else {
--          np = malloc (namelen + 1 + vallen);
--          if (np == NULL) {
--              UNLOCK;
--              return -1;
--          }
--          memcpy (np, name, namelen);
--          np[namelen] = '=';
--          memcpy (&np[namelen + 1], value, vallen);
--      }
--      *ep = np;
--    }
--
--    UNLOCK;
--    return 0;
-+              /* Use the user string if given.  */
-+              if (combined != NULL) {
-+                      np = (char *) combined;
-+              } else {
-+                      np = malloc (namelen + 1 + vallen);
-+                      if (np == NULL) {
-+                              goto DONE;
-+                      }
-+                      memcpy (np, name, namelen);
-+                      np[namelen] = '=';
-+                      memcpy (&np[namelen + 1], value, vallen);
-+              }
-+              *ep = np;
-+    }
-+
-+    rv = 0;
-+
-+ DONE:
-+    __UCLIBC_MUTEX_UNLOCK(mylock);
-+    return rv;
- }
- int setenv (const char *name, const char *value, int replace)
-@@ -143,26 +137,26 @@ int unsetenv (const char *name)
-     char **ep;
-     if (name == NULL || *name == '\0' || strchr (name, '=') != NULL) {
--      __set_errno (EINVAL);
--      return -1;
-+              __set_errno (EINVAL);
-+              return -1;
-     }
-     len = strlen (name);
--    LOCK;
-+    __UCLIBC_MUTEX_LOCK(mylock);
-     ep = __environ;
-     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;
--      }
-+              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;
-+              }
-     }
--    UNLOCK;
-+    __UCLIBC_MUTEX_UNLOCK(mylock);
-     return 0;
- }
-@@ -171,15 +165,15 @@ int unsetenv (const char *name)
-    for Fortran 77) requires this function.  */
- int clearenv (void)
- {
--    LOCK;
-+    __UCLIBC_MUTEX_LOCK(mylock);
-     if (__environ == last_environ && __environ != NULL) {
--      /* We allocated this environment so we can free it.  */
--      free (__environ);
--      last_environ = NULL;
-+              /* We allocated this environment so we can free it.  */
-+              free (__environ);
-+              last_environ = NULL;
-     }
-     /* Clear the environment pointer removes the whole environment.  */
-     __environ = NULL;
--    UNLOCK;
-+    __UCLIBC_MUTEX_UNLOCK(mylock);
-     return 0;
- }
-@@ -190,10 +184,10 @@ int putenv (char *string)
-     const char *const name_end = strchr (string, '=');
-     if (name_end != NULL) {
--      char *name = strndup(string, name_end - string);
--      result = __add_to_environ (name, NULL, string, 1);
--      free(name);
--      return(result);
-+              char *name = strndup(string, name_end - string);
-+              result = __add_to_environ (name, NULL, string, 1);
-+              free(name);
-+              return(result);
-     }
-     unsetenv (string);
-     return 0;
-diff --git a/libc/sysdeps/linux/common/bits/uClibc_stdio.h b/libc/sysdeps/linux/common/bits/uClibc_stdio.h
-index 40cd5fe..3c6911e 100644
---- a/libc/sysdeps/linux/common/bits/uClibc_stdio.h
-+++ b/libc/sysdeps/linux/common/bits/uClibc_stdio.h
-@@ -116,9 +116,7 @@
- #endif
- /**********************************************************************/
--#ifdef __UCLIBC_HAS_THREADS__
--/* Need this for pthread_mutex_t. */
--#include <bits/pthreadtypes.h>
-+#include <bits/uClibc_mutex.h>
- /* user_locking
-  * 0 : do auto locking/unlocking
-@@ -132,43 +130,37 @@
-  * This way, we avoid calling the weak lock/unlock functions.
-  */
--#define __STDIO_AUTO_THREADLOCK_VAR                   int __infunc_user_locking
--
--#define __STDIO_AUTO_THREADLOCK(__stream)                                                             \
--      if ((__infunc_user_locking = (__stream)->__user_locking) == 0) {        \
--              __pthread_mutex_lock(&(__stream)->__lock);                                              \
--      }
--
--#define __STDIO_AUTO_THREADUNLOCK(__stream)                           \
--      if (__infunc_user_locking == 0) {                                       \
--              __pthread_mutex_unlock(&(__stream)->__lock);            \
--      }
-+#define __STDIO_AUTO_THREADLOCK_VAR                                                                                   \
-+        __UCLIBC_MUTEX_AUTO_LOCK_VAR(__infunc_user_locking)
--#define __STDIO_SET_USER_LOCKING(__stream)    ((__stream)->__user_locking = 1)
-+#define __STDIO_AUTO_THREADLOCK(__stream)                                                                     \
-+        __UCLIBC_MUTEX_AUTO_LOCK((__stream)->__lock, __infunc_user_locking,   \
-+                                                               (__stream)->__user_locking)
--#define __STDIO_ALWAYS_THREADLOCK(__stream)   \
--              __pthread_mutex_lock(&(__stream)->__lock)
-+#define __STDIO_AUTO_THREADUNLOCK(__stream)                                                                   \
-+        __UCLIBC_MUTEX_AUTO_UNLOCK((__stream)->__lock, __infunc_user_locking)
--#define __STDIO_ALWAYS_THREADTRYLOCK(__stream)        \
--              __pthread_mutex_trylock(&(__stream)->__lock)
-+#define __STDIO_ALWAYS_THREADLOCK(__stream)                                                                   \
-+        __UCLIBC_MUTEX_LOCK((__stream)->__lock)
--#define __STDIO_ALWAYS_THREADUNLOCK(__stream) \
--              __pthread_mutex_unlock(&(__stream)->__lock)
-+#define __STDIO_ALWAYS_THREADUNLOCK(__stream)                                                         \
-+        __UCLIBC_MUTEX_UNLOCK((__stream)->__lock)
--#else  /* __UCLIBC_HAS_THREADS__ */
-+#define __STDIO_ALWAYS_THREADLOCK_CANCEL_UNSAFE(__stream)                                     \
-+        __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE((__stream)->__lock)
--#define __STDIO_AUTO_THREADLOCK_VAR                           ((void)0)
-+#define __STDIO_ALWAYS_THREADTRYLOCK_CANCEL_UNSAFE(__stream)                          \
-+        __UCLIBC_MUTEX_TRYLOCK_CANCEL_UNSAFE((__stream)->__lock)
--#define __STDIO_AUTO_THREADLOCK(__stream)             ((void)0)
--#define __STDIO_AUTO_THREADUNLOCK(__stream)           ((void)0)
-+#define __STDIO_ALWAYS_THREADUNLOCK_CANCEL_UNSAFE(__stream)                           \
-+        __UCLIBC_MUTEX_UNLOCK_CANCEL_UNSAFE((__stream)->__lock)
-+#ifdef __UCLIBC_HAS_THREADS__
-+#define __STDIO_SET_USER_LOCKING(__stream)    ((__stream)->__user_locking = 1)
-+#else
- #define __STDIO_SET_USER_LOCKING(__stream)            ((void)0)
-+#endif
--#define __STDIO_ALWAYS_THREADLOCK(__stream)           ((void)0)
--#define __STDIO_ALWAYS_THREADTRYLOCK(__stream)        (0)     /* Always succeed. */
--#define __STDIO_ALWAYS_THREADUNLOCK(__stream) ((void)0)
--
--#endif /* __UCLIBC_HAS_THREADS__ */
- /**********************************************************************/
- #define __STDIO_IOFBF 0               /* Fully buffered.  */
-@@ -283,7 +275,7 @@ struct __STDIO_FILE_STRUCT {
- #endif
- #ifdef __UCLIBC_HAS_THREADS__
-       int __user_locking;
--      pthread_mutex_t __lock;
-+      __UCLIBC_MUTEX(__lock);
- #endif
- /* Everything after this is unimplemented... and may be trashed. */
- #if __STDIO_BUILTIN_BUF_SIZE > 0
-@@ -358,10 +350,14 @@ extern void _stdio_term(void);
- extern struct __STDIO_FILE_STRUCT *_stdio_openlist;
- #ifdef __UCLIBC_HAS_THREADS__
--extern pthread_mutex_t _stdio_openlist_lock;
--extern int _stdio_openlist_delflag;
-+__UCLIBC_MUTEX_EXTERN(_stdio_openlist_add_lock);
-+#ifdef __STDIO_BUFFERS
-+__UCLIBC_MUTEX_EXTERN(_stdio_openlist_del_lock);
-+extern volatile int _stdio_openlist_use_count; /* _stdio_openlist_del_lock */
-+extern int _stdio_openlist_del_count; /* _stdio_openlist_del_lock */
-+#endif
- extern int _stdio_user_locking;
--extern void __stdio_init_mutex(pthread_mutex_t *m);
-+extern void __stdio_init_mutex(__UCLIBC_MUTEX_TYPE *m);
- #endif
- #endif
-diff --git a/libc/sysdeps/linux/common/getdents.c b/libc/sysdeps/linux/common/getdents.c
-index ab6a276..23463e5 100644
---- a/libc/sysdeps/linux/common/getdents.c
-+++ b/libc/sysdeps/linux/common/getdents.c
-@@ -30,8 +30,6 @@
- #include <sys/syscall.h>
--#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
--
- struct kernel_dirent
- {
-     long              d_ino;
-diff --git a/libc/sysdeps/linux/common/sigprocmask.c b/libc/sysdeps/linux/common/sigprocmask.c
-index 70ff366..565318d 100644
---- a/libc/sysdeps/linux/common/sigprocmask.c
-+++ b/libc/sysdeps/linux/common/sigprocmask.c
-@@ -23,6 +23,8 @@ int sigprocmask(int how, const sigset_t 
-       if (set &&
- #if (SIG_BLOCK == 0) && (SIG_UNBLOCK == 1) && (SIG_SETMASK == 2)
-               (((unsigned int) how) > 2)
-+#elif (SIG_BLOCK == 1) && (SIG_UNBLOCK == 2) && (SIG_SETMASK == 3)
-+              (((unsigned int)(how-1)) > 2)
- #else
- #warning "compile time assumption violated.. slow path..."
-               ((how != SIG_BLOCK) && (how != SIG_UNBLOCK)
-@@ -48,6 +50,8 @@ int sigprocmask(int how, const sigset_t 
-       if (set &&
- #if (SIG_BLOCK == 0) && (SIG_UNBLOCK == 1) && (SIG_SETMASK == 2)
-               (((unsigned int) how) > 2)
-+#elif (SIG_BLOCK == 1) && (SIG_UNBLOCK == 2) && (SIG_SETMASK == 3)
-+              (((unsigned int)(how-1)) > 2)
- #else
- #warning "compile time assumption violated.. slow path..."
-               ((how != SIG_BLOCK) && (how != SIG_UNBLOCK)
-diff --git a/libc/sysdeps/linux/mips/bits/kernel_sigaction.h b/libc/sysdeps/linux/mips/bits/kernel_sigaction.h
-index b6f52cc..317e5b3 100644
---- a/libc/sysdeps/linux/mips/bits/kernel_sigaction.h
-+++ b/libc/sysdeps/linux/mips/bits/kernel_sigaction.h
-@@ -38,3 +38,6 @@ struct kernel_sigaction {
-       void            (*sa_restorer)(void);
-       int             s_resv[1]; /* reserved */
- };
-+
-+extern int __syscall_rt_sigaction (int, const struct kernel_sigaction *__unbounded,
-+      struct kernel_sigaction *__unbounded, size_t);
-diff --git a/libc/sysdeps/linux/mips/pipe.S b/libc/sysdeps/linux/mips/pipe.S
-index c3afae5..cd88074 100644
---- a/libc/sysdeps/linux/mips/pipe.S
-+++ b/libc/sysdeps/linux/mips/pipe.S
-@@ -7,25 +7,36 @@
- #include <asm/unistd.h>
- #include <asm/regdef.h>
--        .globl  pipe
--        .ent    pipe, 0
-+      .globl  pipe
-+      .ent    pipe, 0
- pipe:
--        addiu   sp,sp,-24
--        sw      a0,16(sp)
--        li      v0,__NR_pipe
--        syscall
--        beqz    a3, 1f
--        la      t3, errno
--        sw      v0, (t3)
--        li      v0, -1
--        b       2f
-+      .frame  sp, 24, sp
-+#ifdef __PIC__
-+      .set    noreorder
-+      .cpload $25
-+      .set    reorder
-+      addiu   sp,sp,-24
-+      .cprestore      16
-+#else
-+      addiu   sp,sp,-24
-+#endif
-+      sw      a0,16(sp)
-+      li      v0,__NR_pipe
-+      syscall
-+      beqz    a3, 1f
-+#ifdef __PIC__
-+      la      t0, __syscall_error
-+      jr      t9
-+#else
-+      j       __syscall_error
-+#endif
- 1:
--        lw      a0, 16(sp)
--        sw      v0, 0(a0)
--        sw      v1, 4(a0)
--        li      v0, 0
-+      lw      a0, 16(sp)
-+      sw      v0, 0(a0)
-+      sw      v1, 4(a0)
-+      li      v0, 0
- 2:
--        addiu   sp,sp,24
--        j       ra
--        .end    pipe
--        .size   pipe,.-pipe
-+      addiu   sp,sp,24
-+      j       ra
-+      .end    pipe
-+      .size   pipe,.-pipe
-diff --git a/libcrypt/des.c b/libcrypt/des.c
-index 3b49a7a..f7a6be1 100644
---- a/libcrypt/des.c
-+++ b/libcrypt/des.c
-@@ -504,7 +504,7 @@ do_des(    u_int32_t l_in, u_int32_t r_in, 
-               kl = kl1;
-               kr = kr1;
-               round = 16;
--              while (round--) {
-+              do {
-                       /*
-                        * Expand R to 48 bits (simulate the E-box).
-                        */
-@@ -540,7 +540,7 @@ do_des(    u_int32_t l_in, u_int32_t r_in, 
-                       f ^= l;
-                       l = r;
-                       r = f;
--              }
-+              } while (--round);
-               r = l;
-               l = f;
-       }
-diff --git a/libpthread/linuxthreads/ptfork.c b/libpthread/linuxthreads/ptfork.c
-index eb544f3..cfec2b7 100644
---- a/libpthread/linuxthreads/ptfork.c
-+++ b/libpthread/linuxthreads/ptfork.c
-@@ -26,6 +26,15 @@
- #include "pthread.h"
- #include "internals.h"
-+#warning hack alert... should be sufficent for system(), but what about other libc mutexes?
-+#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)
-+#warning hack alert block end
-+
- struct handler_list {
-   void (*handler)(void);
-   struct handler_list * next;
-@@ -91,9 +100,18 @@ pid_t __fork(void)
-   parent = pthread_atfork_parent;
-   pthread_mutex_unlock(&pthread_atfork_lock);
-   pthread_call_handlers(prepare);
-+
-+#warning hack alert
-+  __MALLOC_LOCK;
-+
-   pid = __libc_fork();
-+
-+#warning hack alert
-+  __MALLOC_UNLOCK;
-+
-   if (pid == 0) {
-     __pthread_reset_main_thread();
-+#warning need to reconsider __fresetlockfiles!
-     __fresetlockfiles();
-     pthread_call_handlers(child);
-   } else {
-diff -urN -x .git uClibc-0.9.28/libc/sysdeps/linux/common/bits/uClibc_mutex.h uClibc-mjn3/libc/sysdeps/linux/common/bits/uClibc_mutex.h
---- uClibc-0.9.28/libc/sysdeps/linux/common/bits/uClibc_mutex.h        1969-12-31 17:00:00.000000000 -0700
-+++ uClibc-mjn3/libc/sysdeps/linux/common/bits/uClibc_mutex.h  2006-03-08 11:21:58.000000000 -0700
-@@ -0,0 +1,87 @@
-+/* Copyright (C) 2006   Manuel Novoa III    <mjn3@codepoet.org>
-+ *
-+ * GNU Library General Public License (LGPL) version 2 or later.
-+ *
-+ * Dedicated to Toni.  See uClibc/DEDICATION.mjn3 for details.
-+ */
-+
-+#ifndef _UCLIBC_MUTEX_H
-+#define _UCLIBC_MUTEX_H
-+
-+#include <features.h>
-+
-+#ifdef __UCLIBC_HAS_THREADS__
-+
-+#include <pthread.h>
-+
-+#define __UCLIBC_MUTEX_TYPE                                   pthread_mutex_t
-+
-+#define __UCLIBC_MUTEX(M)                                     pthread_mutex_t M
-+#define __UCLIBC_MUTEX_INIT(M,I)                      pthread_mutex_t M = I
-+#define __UCLIBC_MUTEX_STATIC(M,I)                    static pthread_mutex_t M = I
-+#define __UCLIBC_MUTEX_EXTERN(M)                      extern pthread_mutex_t M
-+
-+#define __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE(M)                                                          \
-+              __pthread_mutex_lock(&(M))
-+
-+#define __UCLIBC_MUTEX_UNLOCK_CANCEL_UNSAFE(M)                                                                \
-+              __pthread_mutex_unlock(&(M))
-+
-+#define __UCLIBC_MUTEX_TRYLOCK_CANCEL_UNSAFE(M)                                                               \
-+              __pthread_mutex_trylock(&(M))
-+
-+#define __UCLIBC_MUTEX_CONDITIONAL_LOCK(M,C)                                                          \
-+      do {                                                                                                                                    \
-+              struct _pthread_cleanup_buffer __infunc_pthread_cleanup_buffer;         \
-+              if (C) {                                                                                                                        \
-+                      _pthread_cleanup_push_defer(&__infunc_pthread_cleanup_buffer,   \
-+                                                                              __pthread_mutex_unlock,                         \
-+                                                                              &(M));                                                          \
-+                      __pthread_mutex_lock(&(M));                                                                             \
-+              }                                                                                                                                       \
-+              ((void)0)
-+
-+#define __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(M,C)                                                                \
-+              if (C) {                                                                                                                        \
-+                      _pthread_cleanup_pop_restore(&__infunc_pthread_cleanup_buffer,1);\
-+              }                                                                                                                                       \
-+      } while (0)
-+
-+#define __UCLIBC_MUTEX_AUTO_LOCK_VAR(A)               int A
-+
-+#define __UCLIBC_MUTEX_AUTO_LOCK(M,A,V)                                                                               \
-+        __UCLIBC_MUTEX_CONDITIONAL_LOCK(M,((A=(V)) == 0))
-+
-+#define __UCLIBC_MUTEX_AUTO_UNLOCK(M,A)                                                                               \
-+        __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(M,(A == 0))
-+
-+#define __UCLIBC_MUTEX_LOCK(M)                                                                                                \
-+        __UCLIBC_MUTEX_CONDITIONAL_LOCK(M, 1)
-+
-+#define __UCLIBC_MUTEX_UNLOCK(M)                                                                                      \
-+        __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(M, 1)
-+
-+#else
-+
-+#define __UCLIBC_MUTEX(M)                     void *__UCLIBC_MUTEX_DUMMY_ ## M
-+#define __UCLIBC_MUTEX_INIT(M,I)      extern void *__UCLIBC_MUTEX_DUMMY_ ## M
-+#define __UCLIBC_MUTEX_STATIC(M)      extern void *__UCLIBC_MUTEX_DUMMY_ ## M
-+#define __UCLIBC_MUTEX_EXTERN(M)      extern void *__UCLIBC_MUTEX_DUMMY_ ## M
-+
-+#define __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE(M)          ((void)0)
-+#define __UCLIBC_MUTEX_UNLOCK_CANCEL_UNSAFE(M)                ((void)0)
-+#define __UCLIBC_MUTEX_TRYLOCK_CANCEL_UNSAFE(M)               (0)     /* Always succeed? */
-+
-+#define __UCLIBC_MUTEX_CONDITIONAL_LOCK(M,C)          ((void)0)
-+#define __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(M,C)                ((void)0)
-+
-+#define __UCLIBC_MUTEX_AUTO_LOCK_VAR(A)                               ((void)0)
-+#define __UCLIBC_MUTEX_AUTO_LOCK(M,A,V)                               ((void)0)
-+#define __UCLIBC_MUTEX_AUTO_UNLOCK(M,A)                               ((void)0)
-+
-+#define __UCLIBC_MUTEX_LOCK(M)                                                ((void)0)
-+#define __UCLIBC_MUTEX_UNLOCK(M)                                      ((void)0)
-+
-+#endif
-+
-+#endif /* _UCLIBC_MUTEX_H */
-diff -urN -x .git uClibc-0.9.28/libc/sysdeps/linux/mips/pipe.c uClibc-mjn3/libc/sysdeps/linux/mips/pipe.c
---- uClibc-0.9.28/libc/sysdeps/linux/mips/pipe.c       2005-08-17 16:49:44.000000000 -0600
-+++ uClibc-mjn3/libc/sysdeps/linux/mips/pipe.c 1969-12-31 17:00:00.000000000 -0700
-@@ -1,23 +0,0 @@
--/* pipe system call for Linux/MIPS */
--
--/*see uClibc's sh/pipe.c and glibc-2.2.4's mips/pipe.S */
--
--#include <errno.h>
--#include <unistd.h>
--#include <syscall.h>
--
--int pipe(int *fd)
--{
--    register long int res __asm__ ("$2"); // v0
--    register long int res2 __asm__ ("$3"); // v1
--
--    asm ("move\t$4,%2\n\t"            // $4 = a0
--       "syscall"              /* Perform the system call.  */
--       : "=r" (res)
--       : "0" (__NR_pipe), "r" (fd)
--       : "$4", "$7");
--
--      fd[0] = res;
--      fd[1] = res2;
--      return(0);
--}
diff --git a/toolchain/uClibc/uClibc-0.9.28-new_dst_rules.patch b/toolchain/uClibc/uClibc-0.9.28-new_dst_rules.patch
deleted file mode 100644 (file)
index 8b1a5a9..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
---- uClibc/libc/misc/time/time.c       (revision 16488)
-+++ uClibc/libc/misc/time/time.c       (working copy)
-@@ -157,6 +157,22 @@
- #define TZNAME_MAX _POSIX_TZNAME_MAX
- #endif
-+#if defined (L_tzset) || defined (L_localtime_r) || defined(L_strftime) || \
-+       defined(L__time_mktime) || defined(L__time_mktime_tzi) || \
-+       ((defined(L_strftime) || defined(L_strftime_l)) && \
-+        defined(__UCLIBC_HAS_XLOCALE__))
-+
-+void _time_tzset (int);
-+
-+#ifndef L__time_mktime
-+
-+ /* Jan 1, 2007 Z - tm = 0,0,0,1,0,107,1,0,0 */
-+
-+const static time_t new_rule_starts = 1167609600;
-+
-+#endif
-+#endif
-+
- /**********************************************************************/
- /* The era code is currently unfinished. */
- /*  #define ENABLE_ERA_CODE */
-@@ -532,7 +548,7 @@
- {
-       __UCLIBC_MUTEX_LOCK(_time_tzlock);
--      tzset();
-+      _time_tzset(*timer < new_rule_starts);
-       __time_localtime_tzi(timer, result, _time_tzinfo);
-@@ -956,7 +972,8 @@
-       unsigned char mod;
-       unsigned char code;
--      tzset();                                        /* We'll, let's get this out of the way. */
-+      /* We'll, let's get this out of the way. */
-+      _time_tzset(_time_mktime((struct tm *) timeptr, 0) < new_rule_starts);
-       lvl = 0;
-       p = format;
-@@ -1644,7 +1661,9 @@
-       6,  0,  0,                                      /* Note: overloaded for non-M non-J case... */
-       0, 1, 0,                                        /* J */
-       ',', 'M',      '4', '.', '1', '.', '0',
--      ',', 'M', '1', '0', '.', '5', '.', '0', 0
-+      ',', 'M', '1', '0', '.', '5', '.', '0', 0,
-+      ',', 'M',      '3', '.', '2', '.', '0',
-+      ',', 'M', '1', '1', '.', '1', '.', '0', 0
- };
- #define TZ    vals
-@@ -1652,6 +1671,7 @@
- #define RANGE (vals + 7)
- #define RULE  (vals + 11 - 1)
- #define DEFAULT_RULES (vals + 22)
-+#define DEFAULT_2007_RULES (vals + 38)
- /* Initialize to UTC. */
- int daylight = 0;
-@@ -1774,6 +1794,11 @@
- void tzset(void)
- {
-+    _time_tzset((time(NULL)) < new_rule_starts);
-+}
-+
-+void _time_tzset(int use_old_rules)
-+{
-       register const char *e;
-       register char *s;
-       long off;
-@@ -1896,7 +1921,15 @@
-       } else {                                        /* OK, we have dst, so get some rules. */
-               count = 0;
-               if (!*e) {                              /* No rules so default to US rules. */
--                      e = DEFAULT_RULES;
-+                      e = use_old_rules ? DEFAULT_RULES : DEFAULT_2007_RULES;
-+#ifdef DEBUG_TZSET                    
-+                      if (e == DEFAULT_RULES)
-+                          printf("tzset: Using old rules.\n");
-+                      else if (e == DEFAULT_2007_RULES)
-+                          printf("tzset: Using new rules\n");
-+                      else
-+                          printf("tzset: Using undefined rules\n");
-+#endif /* DEBUG_TZSET */
-               }
-               do {
-@@ -2230,6 +2263,8 @@
-               --d;
-       }
-+      _time_tzset (x.tm_year < 2007); /* tm_year was expanded above */
-+
- #ifdef __BCC__
-       d = p[5] - 1;
-       days = -719163L + ((long)d)*365 + ((d/4) - (d/100) + (d/400) + p[3] + p[7]);
diff --git a/toolchain/uClibc/uClibc-0.9.28-rm-whitespace.patch b/toolchain/uClibc/uClibc-0.9.28-rm-whitespace.patch
deleted file mode 100644 (file)
index 6004f91..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-diff -urN uClibc-0.9.29-0rig/include/assert.h uClibc-0.9.29/include/assert.h
---- uClibc-0.9.29-0rig/include/assert.h        2005-11-03 23:42:46.000000000 +0100
-+++ uClibc-0.9.29/include/assert.h     2007-08-13 19:10:57.000000000 +0200
-@@ -31,7 +31,7 @@
- #define       _ASSERT_H       1
- #include <features.h>
--#if defined __cplusplus && __GNUC_PREREQ (2,95)
-+#if defined __cplusplus && __GNUC_PREREQ(2,95)
- # define __ASSERT_VOID_CAST static_cast<void>
- #else
- # define __ASSERT_VOID_CAST (void)
-@@ -59,13 +59,17 @@
-   (__ASSERT_VOID_CAST ((expr) ? 0 :                                         \
-                      (__assert (__STRING(expr), __FILE__, __LINE__,    \
-                                      __ASSERT_FUNCTION), 0)))
--  
-+
-+/* Define some temporaries to workaround tinyx makedepend bug */
-+#define       __GNUC_PREREQ_2_6       __GNUC_PREREQ(2, 6)
-+#define       __GNUC_PREREQ_2_4       __GNUC_PREREQ(2, 4)
- /* Version 2.4 and later of GCC define a magical variable `__PRETTY_FUNCTION__'
-    which contains the name of the function currently being defined.
-    This is broken in G++ before version 2.6.
-    C9x has a similar variable called __func__, but prefer the GCC one since
-    it demangles C++ function names.  */
--# if defined __cplusplus ? __GNUC_PREREQ (2, 6) : __GNUC_PREREQ (2, 4)
-+
-+# if defined __cplusplus ? __GNUC_PREREQ_2_6 : __GNUC_PREREQ_2_4
- #   define __ASSERT_FUNCTION  __PRETTY_FUNCTION__
- # else
- #  if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
-diff -urN uClibc-0.9.29-0rig/include/complex.h uClibc-0.9.29/include/complex.h
---- uClibc-0.9.29-0rig/include/complex.h       2002-05-09 10:15:21.000000000 +0200
-+++ uClibc-0.9.29/include/complex.h    2007-08-13 17:55:29.000000000 +0200
-@@ -33,7 +33,7 @@
- /* We might need to add support for more compilers here.  But since ISO
-    C99 is out hopefully all maintained compilers will soon provide the data
-    types `float complex' and `double complex'.  */
--#if __GNUC_PREREQ (2, 7) && !__GNUC_PREREQ (2, 97)
-+#if __GNUC_PREREQ(2, 7) && !__GNUC_PREREQ(2, 97)
- # define _Complex __complex__
- #endif
-diff -urN uClibc-0.9.29-0rig/include/features.h uClibc-0.9.29/include/features.h
---- uClibc-0.9.29-0rig/include/features.h      2006-11-29 22:10:04.000000000 +0100
-+++ uClibc-0.9.29/include/features.h   2007-08-13 17:55:51.000000000 +0200
-@@ -143,7 +143,7 @@
- /* Convenience macros to test the versions of glibc and gcc.
-    Use them like this:
--   #if __GNUC_PREREQ (2,8)
-+   #if __GNUC_PREREQ(2,8)
-    ... code requiring gcc 2.8 or later ...
-    #endif
-    Note - they won't work for gcc1 or glibc1, since the _MINOR macros
-@@ -297,7 +297,7 @@
- /* uClibc does not support _FORTIFY_SOURCE */
- #undef _FORTIFY_SOURCE
- #if defined _FORTIFY_SOURCE && _FORTIFY_SOURCE > 0 \
--    && __GNUC_PREREQ (4, 1) && defined __OPTIMIZE__ && __OPTIMIZE__ > 0
-+    && __GNUC_PREREQ(4, 1) && defined __OPTIMIZE__ && __OPTIMIZE__ > 0
- # if _FORTIFY_SOURCE > 1
- #  define __USE_FORTIFY_LEVEL 2
- # else
-@@ -366,7 +366,7 @@
- #endif        /* !ASSEMBLER */
- /* Decide whether we can define 'extern inline' functions in headers.  */
--#if __GNUC_PREREQ (2, 7) && defined __OPTIMIZE__ \
-+#if __GNUC_PREREQ(2, 7) && defined __OPTIMIZE__ \
-     && !defined __OPTIMIZE_SIZE__ && !defined __NO_INLINE__
- # define __USE_EXTERN_INLINES 1
- #endif
-diff -urN uClibc-0.9.29-0rig/include/tgmath.h uClibc-0.9.29/include/tgmath.h
---- uClibc-0.9.29-0rig/include/tgmath.h        2002-05-09 10:15:21.000000000 +0200
-+++ uClibc-0.9.29/include/tgmath.h     2007-08-13 17:56:17.000000000 +0200
-@@ -34,7 +34,7 @@
-    do not try this for now and instead concentrate only on GNU CC.  Once
-    we have more information support for other compilers might follow.  */
--#if __GNUC_PREREQ (2, 7)
-+#if __GNUC_PREREQ(2, 7)
- # ifdef __NO_LONG_DOUBLE_MATH
- #  define __tgml(fct) fct
diff --git a/toolchain/uClibc/uClibc-0.9.28.3-avr32.patch b/toolchain/uClibc/uClibc-0.9.28.3-avr32.patch
new file mode 100644 (file)
index 0000000..2e0f541
--- /dev/null
@@ -0,0 +1,7650 @@
+diff -Nrup a/extra/Configs/Config.avr32 b/extra/Configs/Config.avr32
+--- a/extra/Configs/Config.avr32       1969-12-31 19:00:00.000000000 -0500
++++ b/extra/Configs/Config.avr32       2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,42 @@
++#
++# For a description of the syntax of this configuration file,
++# see extra/config/Kconfig-language.txt
++#
++
++config HAVE_ELF
++      bool
++      default y
++
++config TARGET_ARCH
++      default "avr32"
++
++config ARCH_CFLAGS
++      string
++
++config ARCH_LDFLAGS
++      string
++
++config LIBGCC_CFLAGS
++      string
++
++config ARCH_SUPPORTS_BIG_ENDIAN
++      bool
++      default y
++
++config UCLIBC_COMPLETELY_PIC
++      select FORCE_SHAREABLE_TEXT_SEGMENTS
++      bool
++      default y
++
++choice
++      prompt "Target CPU Type"
++      default CONFIG_AP7000
++
++config CONFIG_AP7000
++      bool "AP7000"
++
++endchoice
++
++config LINKRELAX
++      bool "Enable linker optimizations"
++      default n
+diff -Nrup a/extra/Configs/Config.in b/extra/Configs/Config.in
+--- a/extra/Configs/Config.in  2007-01-25 19:01:55.000000000 -0500
++++ b/extra/Configs/Config.in  2008-02-28 19:02:10.000000000 -0500
+@@ -16,6 +16,9 @@ config TARGET_alpha
+ config TARGET_arm
+       bool "arm"
++config TARGET_avr32
++      bool "avr32"
++
+ config TARGET_bfin
+       bool "bfin"
+@@ -83,6 +86,10 @@ if TARGET_arm
+ source "extra/Configs/Config.arm"
+ endif
++if TARGET_avr32
++source "extra/Configs/Config.avr32"
++endif
++
+ if TARGET_bfin
+ source "extra/Configs/Config.bfin"
+ endif
+diff -Nrup a/include/elf.h b/include/elf.h
+--- a/include/elf.h    2007-01-25 19:22:03.000000000 -0500
++++ b/include/elf.h    2008-02-28 19:02:10.000000000 -0500
+@@ -305,6 +305,8 @@ typedef struct
+ /* D30V backend magic number.  Written in the absence of an ABI.  */
+ #define EM_CYGNUS_D30V        0x7676
++#define EM_AVR32      0x18ad
++
+ /* V850 backend magic number.  Written in the absense of an ABI.  */
+ #define EM_CYGNUS_V850        0x9080
+@@ -2751,6 +2753,55 @@ typedef Elf32_Addr Elf32_Conflict;
+ /* Keep this the last entry.  */
+ #define R_960_NUM     8
++/* Atmel AVR32 relocations.  */
++#define R_AVR32_NONE          0
++#define R_AVR32_32            1
++#define R_AVR32_16            2
++#define R_AVR32_8             3
++#define R_AVR32_32_PCREL      4
++#define R_AVR32_16_PCREL      5
++#define R_AVR32_8_PCREL               6
++#define R_AVR32_DIFF32                7
++#define R_AVR32_DIFF16                8
++#define R_AVR32_DIFF8         9
++#define R_AVR32_GOT32         10
++#define R_AVR32_GOT16         11
++#define R_AVR32_GOT8          12
++#define R_AVR32_21S           13
++#define R_AVR32_16U           14
++#define R_AVR32_16S           15
++#define R_AVR32_8S            16
++#define R_AVR32_8S_EXT                17
++#define R_AVR32_22H_PCREL     18
++#define R_AVR32_18W_PCREL     19
++#define R_AVR32_16B_PCREL     20
++#define R_AVR32_16N_PCREL     21
++#define R_AVR32_14UW_PCREL    22
++#define R_AVR32_11H_PCREL     23
++#define R_AVR32_10UW_PCREL    24
++#define R_AVR32_9H_PCREL      25
++#define R_AVR32_9UW_PCREL     26
++#define R_AVR32_HI16          27
++#define R_AVR32_LO16          28
++#define R_AVR32_GOTPC         29
++#define R_AVR32_GOTCALL               30
++#define R_AVR32_LDA_GOT               31
++#define R_AVR32_GOT21S                32
++#define R_AVR32_GOT18SW               33
++#define R_AVR32_GOT16S                34
++#define R_AVR32_GOT7UW                35
++#define R_AVR32_32_CPENT      36
++#define R_AVR32_CPCALL                37
++#define R_AVR32_16_CP         38
++#define R_AVR32_9W_CP         39
++#define R_AVR32_RELATIVE      40
++#define R_AVR32_GLOB_DAT      41
++#define R_AVR32_JMP_SLOT      42
++#define R_AVR32_ALIGN         43
++#define R_AVR32_NUM           44
++
++/* AVR32 dynamic tags */
++#define DT_AVR32_GOTSZ                0x70000001 /* Total size of GOT in bytes */
+ /* v850 relocations.  */
+ #define R_V850_NONE           0
+diff -Nrup a/include/elf.h.orig b/include/elf.h.orig
+--- a/include/elf.h.orig       1969-12-31 19:00:00.000000000 -0500
++++ b/include/elf.h.orig       2007-01-25 19:22:03.000000000 -0500
+@@ -0,0 +1,2886 @@
++/* This file defines standard ELF types, structures, and macros.
++   Copyright (C) 1995-2003, 2004, 2005 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.  */
++
++#ifndef _ELF_H
++#define       _ELF_H 1
++
++#include <features.h>
++
++__BEGIN_DECLS
++
++/* Standard ELF types.  */
++
++#include <stdint.h>
++
++/* Type for a 16-bit quantity.  */
++typedef uint16_t Elf32_Half;
++typedef uint16_t Elf64_Half;
++
++/* Types for signed and unsigned 32-bit quantities.  */
++typedef uint32_t Elf32_Word;
++typedef       int32_t  Elf32_Sword;
++typedef uint32_t Elf64_Word;
++typedef       int32_t  Elf64_Sword;
++
++/* Types for signed and unsigned 64-bit quantities.  */
++typedef uint64_t Elf32_Xword;
++typedef       int64_t  Elf32_Sxword;
++typedef uint64_t Elf64_Xword;
++typedef       int64_t  Elf64_Sxword;
++
++/* Type of addresses.  */
++typedef uint32_t Elf32_Addr;
++typedef uint64_t Elf64_Addr;
++
++/* Type of file offsets.  */
++typedef uint32_t Elf32_Off;
++typedef uint64_t Elf64_Off;
++
++/* Type for section indices, which are 16-bit quantities.  */
++typedef uint16_t Elf32_Section;
++typedef uint16_t Elf64_Section;
++
++/* Type for version symbol information.  */
++typedef Elf32_Half Elf32_Versym;
++typedef Elf64_Half Elf64_Versym;
++
++
++/* The ELF file header.  This appears at the start of every ELF file.  */
++
++#define EI_NIDENT (16)
++
++typedef struct
++{
++  unsigned char       e_ident[EI_NIDENT];     /* Magic number and other info */
++  Elf32_Half  e_type;                 /* Object file type */
++  Elf32_Half  e_machine;              /* Architecture */
++  Elf32_Word  e_version;              /* Object file version */
++  Elf32_Addr  e_entry;                /* Entry point virtual address */
++  Elf32_Off   e_phoff;                /* Program header table file offset */
++  Elf32_Off   e_shoff;                /* Section header table file offset */
++  Elf32_Word  e_flags;                /* Processor-specific flags */
++  Elf32_Half  e_ehsize;               /* ELF header size in bytes */
++  Elf32_Half  e_phentsize;            /* Program header table entry size */
++  Elf32_Half  e_phnum;                /* Program header table entry count */
++  Elf32_Half  e_shentsize;            /* Section header table entry size */
++  Elf32_Half  e_shnum;                /* Section header table entry count */
++  Elf32_Half  e_shstrndx;             /* Section header string table index */
++} Elf32_Ehdr;
++
++typedef struct
++{
++  unsigned char       e_ident[EI_NIDENT];     /* Magic number and other info */
++  Elf64_Half  e_type;                 /* Object file type */
++  Elf64_Half  e_machine;              /* Architecture */
++  Elf64_Word  e_version;              /* Object file version */
++  Elf64_Addr  e_entry;                /* Entry point virtual address */
++  Elf64_Off   e_phoff;                /* Program header table file offset */
++  Elf64_Off   e_shoff;                /* Section header table file offset */
++  Elf64_Word  e_flags;                /* Processor-specific flags */
++  Elf64_Half  e_ehsize;               /* ELF header size in bytes */
++  Elf64_Half  e_phentsize;            /* Program header table entry size */
++  Elf64_Half  e_phnum;                /* Program header table entry count */
++  Elf64_Half  e_shentsize;            /* Section header table entry size */
++  Elf64_Half  e_shnum;                /* Section header table entry count */
++  Elf64_Half  e_shstrndx;             /* Section header string table index */
++} Elf64_Ehdr;
++
++/* Fields in the e_ident array.  The EI_* macros are indices into the
++   array.  The macros under each EI_* macro are the values the byte
++   may have.  */
++
++#define EI_MAG0               0               /* File identification byte 0 index */
++#define ELFMAG0               0x7f            /* Magic number byte 0 */
++
++#define EI_MAG1               1               /* File identification byte 1 index */
++#define ELFMAG1               'E'             /* Magic number byte 1 */
++
++#define EI_MAG2               2               /* File identification byte 2 index */
++#define ELFMAG2               'L'             /* Magic number byte 2 */
++
++#define EI_MAG3               3               /* File identification byte 3 index */
++#define ELFMAG3               'F'             /* Magic number byte 3 */
++
++/* Conglomeration of the identification bytes, for easy testing as a word.  */
++#define       ELFMAG          "\177ELF"
++#define       SELFMAG         4
++
++#define EI_CLASS      4               /* File class byte index */
++#define ELFCLASSNONE  0               /* Invalid class */
++#define ELFCLASS32    1               /* 32-bit objects */
++#define ELFCLASS64    2               /* 64-bit objects */
++#define ELFCLASSNUM   3
++
++#define EI_DATA               5               /* Data encoding byte index */
++#define ELFDATANONE   0               /* Invalid data encoding */
++#define ELFDATA2LSB   1               /* 2's complement, little endian */
++#define ELFDATA2MSB   2               /* 2's complement, big endian */
++#define ELFDATANUM    3
++
++#define EI_VERSION    6               /* File version byte index */
++                                      /* Value must be EV_CURRENT */
++
++#define EI_OSABI      7               /* OS ABI identification */
++#define ELFOSABI_NONE         0       /* UNIX System V ABI */
++#define ELFOSABI_SYSV         0       /* Alias.  */
++#define ELFOSABI_HPUX         1       /* HP-UX */
++#define ELFOSABI_NETBSD               2       /* NetBSD.  */
++#define ELFOSABI_LINUX                3       /* Linux.  */
++#define ELFOSABI_HURD         4       /* GNU/Hurd */
++#define ELFOSABI_SOLARIS      6       /* Sun Solaris.  */
++#define ELFOSABI_AIX          7       /* IBM AIX.  */
++#define ELFOSABI_IRIX         8       /* SGI Irix.  */
++#define ELFOSABI_FREEBSD      9       /* FreeBSD.  */
++#define ELFOSABI_TRU64                10      /* Compaq TRU64 UNIX.  */
++#define ELFOSABI_MODESTO      11      /* Novell Modesto.  */
++#define ELFOSABI_OPENBSD      12      /* OpenBSD.  */
++#define ELFOSABI_OPENVMS      13      /* OpenVMS */
++#define ELFOSABI_NSK          14      /* Hewlett-Packard Non-Stop Kernel */
++#define ELFOSABI_AROS         15      /* Amiga Research OS */
++#define ELFOSABI_ARM          97      /* ARM */
++#define ELFOSABI_STANDALONE   255     /* Standalone (embedded) application */
++
++#define EI_ABIVERSION 8               /* ABI version */
++
++#define EI_PAD                9               /* Byte index of padding bytes */
++
++/* Legal values for e_type (object file type).  */
++
++#define ET_NONE               0               /* No file type */
++#define ET_REL                1               /* Relocatable file */
++#define ET_EXEC               2               /* Executable file */
++#define ET_DYN                3               /* Shared object file */
++#define ET_CORE               4               /* Core file */
++#define       ET_NUM          5               /* Number of defined types */
++#define ET_LOOS               0xfe00          /* OS-specific range start */
++#define ET_HIOS               0xfeff          /* OS-specific range end */
++#define ET_LOPROC     0xff00          /* Processor-specific range start */
++#define ET_HIPROC     0xffff          /* Processor-specific range end */
++
++/* Legal values for e_machine (architecture).  */
++
++#define EM_NONE                0              /* No machine */
++#define EM_M32                 1              /* AT&T WE 32100 */
++#define EM_SPARC       2              /* SUN SPARC */
++#define EM_386                 3              /* Intel 80386 */
++#define EM_68K                 4              /* Motorola m68k family */
++#define EM_88K                 5              /* Motorola m88k family */
++#define EM_486                 6              /* Intel 80486 *//* Reserved for future use */
++#define EM_860                 7              /* Intel 80860 */
++#define EM_MIPS                8              /* MIPS R3000 big-endian */
++#define EM_S370                9              /* IBM System/370 */
++#define EM_MIPS_RS3_LE        10              /* MIPS R3000 little-endian */
++
++#define EM_PARISC     15              /* HPPA */
++#define EM_VPP500     17              /* Fujitsu VPP500 */
++#define EM_SPARC32PLUS        18              /* Sun's "v8plus" */
++#define EM_960                19              /* Intel 80960 */
++#define EM_PPC                20              /* PowerPC */
++#define EM_PPC64      21              /* PowerPC 64-bit */
++#define EM_S390               22              /* IBM S390 */
++
++#define EM_V800               36              /* NEC V800 series */
++#define EM_FR20               37              /* Fujitsu FR20 */
++#define EM_RH32               38              /* TRW RH-32 */
++#define EM_MCORE      39              /* Motorola M*Core */ /* May also be taken by Fujitsu MMA */
++#define EM_RCE                39              /* Old name for MCore */
++#define EM_ARM                40              /* ARM */
++#define EM_FAKE_ALPHA 41              /* Digital Alpha */
++#define EM_SH         42              /* Renesas SH */
++#define EM_SPARCV9    43              /* SPARC v9 64-bit */
++#define EM_TRICORE    44              /* Siemens Tricore */
++#define EM_ARC                45              /* Argonaut RISC Core */
++#define EM_H8_300     46              /* Renesas H8/300 */
++#define EM_H8_300H    47              /* Renesas H8/300H */
++#define EM_H8S                48              /* Renesas H8S */
++#define EM_H8_500     49              /* Renesas H8/500 */
++#define EM_IA_64      50              /* Intel Merced */
++#define EM_MIPS_X     51              /* Stanford MIPS-X */
++#define EM_COLDFIRE   52              /* Motorola Coldfire */
++#define EM_68HC12     53              /* Motorola M68HC12 */
++#define EM_MMA                54              /* Fujitsu MMA Multimedia Accelerator*/
++#define EM_PCP                55              /* Siemens PCP */
++#define EM_NCPU               56              /* Sony nCPU embeeded RISC */
++#define EM_NDR1               57              /* Denso NDR1 microprocessor */
++#define EM_STARCORE   58              /* Motorola Start*Core processor */
++#define EM_ME16               59              /* Toyota ME16 processor */
++#define EM_ST100      60              /* STMicroelectronic ST100 processor */
++#define EM_TINYJ      61              /* Advanced Logic Corp. Tinyj emb.fam*/
++#define EM_X86_64     62              /* AMD x86-64 architecture */
++#define EM_PDSP               63              /* Sony DSP Processor */
++
++#define EM_FX66               66              /* Siemens FX66 microcontroller */
++#define EM_ST9PLUS    67              /* STMicroelectronics ST9+ 8/16 mc */
++#define EM_ST7                68              /* STmicroelectronics ST7 8 bit mc */
++#define EM_68HC16     69              /* Motorola MC68HC16 microcontroller */
++#define EM_68HC11     70              /* Motorola MC68HC11 microcontroller */
++#define EM_68HC08     71              /* Motorola MC68HC08 microcontroller */
++#define EM_68HC05     72              /* Motorola MC68HC05 microcontroller */
++#define EM_SVX                73              /* Silicon Graphics SVx */
++#define EM_ST19               74              /* STMicroelectronics ST19 8 bit mc */
++#define EM_VAX                75              /* Digital VAX */
++#define EM_CRIS               76              /* Axis Communications 32-bit embedded processor */
++#define EM_JAVELIN    77              /* Infineon Technologies 32-bit embedded processor */
++#define EM_FIREPATH   78              /* Element 14 64-bit DSP Processor */
++#define EM_ZSP                79              /* LSI Logic 16-bit DSP Processor */
++#define EM_MMIX               80              /* Donald Knuth's educational 64-bit processor */
++#define EM_HUANY      81              /* Harvard University machine-independent object files */
++#define EM_PRISM      82              /* SiTera Prism */
++#define EM_AVR                83              /* Atmel AVR 8-bit microcontroller */
++#define EM_FR30               84              /* Fujitsu FR30 */
++#define EM_D10V               85              /* Mitsubishi D10V */
++#define EM_D30V               86              /* Mitsubishi D30V */
++#define EM_V850               87              /* NEC v850 */
++#define EM_M32R               88              /* Renesas M32R */
++#define EM_MN10300    89              /* Matsushita MN10300 */
++#define EM_MN10200    90              /* Matsushita MN10200 */
++#define EM_PJ         91              /* picoJava */
++#define EM_OPENRISC   92              /* OpenRISC 32-bit embedded processor */
++#define EM_ARC_A5     93              /* ARC Cores Tangent-A5 */
++#define EM_XTENSA     94              /* Tensilica Xtensa Architecture */
++#define EM_IP2K               101             /* Ubicom IP2022 micro controller */
++#define EM_CR         103             /* National Semiconductor CompactRISC */
++#define EM_MSP430     105             /* TI msp430 micro controller */
++#define EM_BLACKFIN   106             /* Analog Devices Blackfin */
++#define EM_ALTERA_NIOS2       113     /* Altera Nios II soft-core processor */
++#define EM_CRX                114             /* National Semiconductor CRX */
++#define EM_NUM                95
++
++/* If it is necessary to assign new unofficial EM_* values, please pick large
++   random numbers (0x8523, 0xa7f2, etc.) to minimize the chances of collision
++   with official or non-GNU unofficial values.
++
++   NOTE: Do not just increment the most recent number by one.
++   Somebody else somewhere will do exactly the same thing, and you
++   will have a collision.  Instead, pick a random number.
++
++   Normally, each entity or maintainer responsible for a machine with an
++   unofficial e_machine number should eventually ask registry@caldera.com for
++   an officially blessed number to be added to the list above.  */
++
++/* picoJava */
++#define EM_PJ_OLD     99
++
++/* Cygnus PowerPC ELF backend.  Written in the absence of an ABI.  */
++#define EM_CYGNUS_POWERPC 0x9025
++
++/* Old version of Sparc v9, from before the ABI; this should be
++   removed shortly.  */
++#define EM_OLD_SPARCV9        11
++
++/* Old version of PowerPC, this should be removed shortly. */
++#define EM_PPC_OLD    17
++
++/* (Deprecated) Temporary number for the OpenRISC processor.  */
++#define EM_OR32               0x8472
++
++/* Renesas M32C and M16C.  */
++#define EM_M32C                       0xFEB0
++
++/* Cygnus M32R ELF backend.  Written in the absence of an ABI.  */
++#define EM_CYGNUS_M32R        0x9041
++
++/* old S/390 backend magic number. Written in the absence of an ABI.  */
++#define EM_S390_OLD   0xa390
++
++/* D10V backend magic number.  Written in the absence of an ABI.  */
++#define EM_CYGNUS_D10V        0x7650
++
++/* D30V backend magic number.  Written in the absence of an ABI.  */
++#define EM_CYGNUS_D30V        0x7676
++
++/* V850 backend magic number.  Written in the absense of an ABI.  */
++#define EM_CYGNUS_V850        0x9080
++
++/* mn10200 and mn10300 backend magic numbers.
++   Written in the absense of an ABI.  */
++#define EM_CYGNUS_MN10200     0xdead
++#define EM_CYGNUS_MN10300     0xbeef
++
++/* FR30 magic number - no EABI available.  */
++#define EM_CYGNUS_FR30                0x3330
++
++/* AVR magic number
++   Written in the absense of an ABI.  */
++#define EM_AVR_OLD            0x1057
++
++/* OpenRISC magic number
++   Written in the absense of an ABI.  */
++#define EM_OPENRISC_OLD               0x3426
++
++/* DLX magic number
++   Written in the absense of an ABI.  */
++#define EM_DLX                        0x5aa5
++
++#define EM_XSTORMY16          0xad45
++
++/* FRV magic number - no EABI available??.  */
++#define EM_CYGNUS_FRV 0x5441
++
++/* Ubicom IP2xxx; no ABI */
++#define EM_IP2K_OLD           0x8217
++
++#define EM_MT                   0x2530  /* Morpho MT; no ABI */
++
++/* MSP430 magic number
++      Written in the absense everything.  */
++#define EM_MSP430_OLD         0x1059
++
++/* Vitesse IQ2000.  */
++#define EM_IQ2000             0xFEBA
++
++/* Old, unofficial value for Xtensa.  */
++#define EM_XTENSA_OLD         0xabc7
++
++/* Alpha backend magic number.  Written in the absence of an ABI.  */
++#define EM_ALPHA      0x9026
++
++/* NIOS magic number - no EABI available.  */
++#define EM_NIOS32     0xFEBB
++
++/* V850 backend magic number.  Written in the absense of an ABI.  */
++#define EM_CYGNUS_V850 0x9080
++
++/* Legal values for e_version (version).  */
++
++#define EV_NONE               0               /* Invalid ELF version */
++#define EV_CURRENT    1               /* Current version */
++#define EV_NUM                2
++
++/* Section header.  */
++
++typedef struct
++{
++  Elf32_Word  sh_name;                /* Section name (string tbl index) */
++  Elf32_Word  sh_type;                /* Section type */
++  Elf32_Word  sh_flags;               /* Section flags */
++  Elf32_Addr  sh_addr;                /* Section virtual addr at execution */
++  Elf32_Off   sh_offset;              /* Section file offset */
++  Elf32_Word  sh_size;                /* Section size in bytes */
++  Elf32_Word  sh_link;                /* Link to another section */
++  Elf32_Word  sh_info;                /* Additional section information */
++  Elf32_Word  sh_addralign;           /* Section alignment */
++  Elf32_Word  sh_entsize;             /* Entry size if section holds table */
++} Elf32_Shdr;
++
++typedef struct
++{
++  Elf64_Word  sh_name;                /* Section name (string tbl index) */
++  Elf64_Word  sh_type;                /* Section type */
++  Elf64_Xword sh_flags;               /* Section flags */
++  Elf64_Addr  sh_addr;                /* Section virtual addr at execution */
++  Elf64_Off   sh_offset;              /* Section file offset */
++  Elf64_Xword sh_size;                /* Section size in bytes */
++  Elf64_Word  sh_link;                /* Link to another section */
++  Elf64_Word  sh_info;                /* Additional section information */
++  Elf64_Xword sh_addralign;           /* Section alignment */
++  Elf64_Xword sh_entsize;             /* Entry size if section holds table */
++} Elf64_Shdr;
++
++/* Special section indices.  */
++
++#define SHN_UNDEF     0               /* Undefined section */
++#define SHN_LORESERVE 0xff00          /* Start of reserved indices */
++#define SHN_LOPROC    0xff00          /* Start of processor-specific */
++#define SHN_BEFORE    0xff00          /* Order section before all others
++                                         (Solaris).  */
++#define SHN_AFTER     0xff01          /* Order section after all others
++                                         (Solaris).  */
++#define SHN_HIPROC    0xff1f          /* End of processor-specific */
++#define SHN_LOOS      0xff20          /* Start of OS-specific */
++#define SHN_HIOS      0xff3f          /* End of OS-specific */
++#define SHN_ABS               0xfff1          /* Associated symbol is absolute */
++#define SHN_COMMON    0xfff2          /* Associated symbol is common */
++#define SHN_XINDEX    0xffff          /* Index is in extra table.  */
++#define SHN_HIRESERVE 0xffff          /* End of reserved indices */
++
++/* Legal values for sh_type (section type).  */
++
++#define SHT_NULL        0             /* Section header table entry unused */
++#define SHT_PROGBITS    1             /* Program data */
++#define SHT_SYMTAB      2             /* Symbol table */
++#define SHT_STRTAB      3             /* String table */
++#define SHT_RELA        4             /* Relocation entries with addends */
++#define SHT_HASH        5             /* Symbol hash table */
++#define SHT_DYNAMIC     6             /* Dynamic linking information */
++#define SHT_NOTE        7             /* Notes */
++#define SHT_NOBITS      8             /* Program space with no data (bss) */
++#define SHT_REL                 9             /* Relocation entries, no addends */
++#define SHT_SHLIB       10            /* Reserved */
++#define SHT_DYNSYM      11            /* Dynamic linker symbol table */
++#define SHT_INIT_ARRAY          14            /* Array of constructors */
++#define SHT_FINI_ARRAY          15            /* Array of destructors */
++#define SHT_PREINIT_ARRAY 16          /* Array of pre-constructors */
++#define SHT_GROUP       17            /* Section group */
++#define SHT_SYMTAB_SHNDX  18          /* Extended section indeces */
++#define       SHT_NUM           19            /* Number of defined types.  */
++#define SHT_LOOS        0x60000000    /* Start OS-specific */
++#define SHT_GNU_LIBLIST         0x6ffffff7    /* Prelink library list */
++#define SHT_CHECKSUM    0x6ffffff8    /* Checksum for DSO content.  */
++#define SHT_LOSUNW      0x6ffffffa    /* Sun-specific low bound.  */
++#define SHT_SUNW_move   0x6ffffffa
++#define SHT_SUNW_COMDAT   0x6ffffffb
++#define SHT_SUNW_syminfo  0x6ffffffc
++#define SHT_GNU_verdef          0x6ffffffd    /* Version definition section.  */
++#define SHT_GNU_verneed         0x6ffffffe    /* Version needs section.  */
++#define SHT_GNU_versym          0x6fffffff    /* Version symbol table.  */
++#define SHT_HISUNW      0x6fffffff    /* Sun-specific high bound.  */
++#define SHT_HIOS        0x6fffffff    /* End OS-specific type */
++#define SHT_LOPROC      0x70000000    /* Start of processor-specific */
++#define SHT_HIPROC      0x7fffffff    /* End of processor-specific */
++#define SHT_LOUSER      0x80000000    /* Start of application-specific */
++#define SHT_HIUSER      0x8fffffff    /* End of application-specific */
++
++/* Legal values for sh_flags (section flags).  */
++
++#define SHF_WRITE          (1 << 0)   /* Writable */
++#define SHF_ALLOC          (1 << 1)   /* Occupies memory during execution */
++#define SHF_EXECINSTR      (1 << 2)   /* Executable */
++#define SHF_MERGE          (1 << 4)   /* Might be merged */
++#define SHF_STRINGS        (1 << 5)   /* Contains nul-terminated strings */
++#define SHF_INFO_LINK      (1 << 6)   /* `sh_info' contains SHT index */
++#define SHF_LINK_ORDER             (1 << 7)   /* Preserve order after combining */
++#define SHF_OS_NONCONFORMING (1 << 8) /* Non-standard OS specific handling
++                                         required */
++#define SHF_GROUP          (1 << 9)   /* Section is member of a group.  */
++#define SHF_TLS                    (1 << 10)  /* Section hold thread-local data.  */
++#define SHF_MASKOS         0x0ff00000 /* OS-specific.  */
++#define SHF_MASKPROC       0xf0000000 /* Processor-specific */
++#define SHF_ORDERED        (1 << 30)  /* Special ordering requirement
++                                         (Solaris).  */
++#define SHF_EXCLUDE        (1 << 31)  /* Section is excluded unless
++                                         referenced or allocated (Solaris).*/
++
++/* Section group handling.  */
++#define GRP_COMDAT    0x1             /* Mark group as COMDAT.  */
++
++/* Symbol table entry.  */
++
++typedef struct
++{
++  Elf32_Word  st_name;                /* Symbol name (string tbl index) */
++  Elf32_Addr  st_value;               /* Symbol value */
++  Elf32_Word  st_size;                /* Symbol size */
++  unsigned char       st_info;                /* Symbol type and binding */
++  unsigned char       st_other;               /* Symbol visibility */
++  Elf32_Section       st_shndx;               /* Section index */
++} Elf32_Sym;
++
++typedef struct
++{
++  Elf64_Word  st_name;                /* Symbol name (string tbl index) */
++  unsigned char       st_info;                /* Symbol type and binding */
++  unsigned char st_other;             /* Symbol visibility */
++  Elf64_Section       st_shndx;               /* Section index */
++  Elf64_Addr  st_value;               /* Symbol value */
++  Elf64_Xword st_size;                /* Symbol size */
++} Elf64_Sym;
++
++/* The syminfo section if available contains additional information about
++   every dynamic symbol.  */
++
++typedef struct
++{
++  Elf32_Half si_boundto;              /* Direct bindings, symbol bound to */
++  Elf32_Half si_flags;                        /* Per symbol flags */
++} Elf32_Syminfo;
++
++typedef struct
++{
++  Elf64_Half si_boundto;              /* Direct bindings, symbol bound to */
++  Elf64_Half si_flags;                        /* Per symbol flags */
++} Elf64_Syminfo;
++
++/* Possible values for si_boundto.  */
++#define SYMINFO_BT_SELF               0xffff  /* Symbol bound to self */
++#define SYMINFO_BT_PARENT     0xfffe  /* Symbol bound to parent */
++#define SYMINFO_BT_LOWRESERVE 0xff00  /* Beginning of reserved entries */
++
++/* Possible bitmasks for si_flags.  */
++#define SYMINFO_FLG_DIRECT    0x0001  /* Direct bound symbol */
++#define SYMINFO_FLG_PASSTHRU  0x0002  /* Pass-thru symbol for translator */
++#define SYMINFO_FLG_COPY      0x0004  /* Symbol is a copy-reloc */
++#define SYMINFO_FLG_LAZYLOAD  0x0008  /* Symbol bound to object to be lazy
++                                         loaded */
++/* Syminfo version values.  */
++#define SYMINFO_NONE          0
++#define SYMINFO_CURRENT               1
++#define SYMINFO_NUM           2
++
++
++/* How to extract and insert information held in the st_info field.  */
++
++#define ELF32_ST_BIND(val)            (((unsigned char) (val)) >> 4)
++#define ELF32_ST_TYPE(val)            ((val) & 0xf)
++#define ELF32_ST_INFO(bind, type)     (((bind) << 4) + ((type) & 0xf))
++
++/* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field.  */
++#define ELF64_ST_BIND(val)            ELF32_ST_BIND (val)
++#define ELF64_ST_TYPE(val)            ELF32_ST_TYPE (val)
++#define ELF64_ST_INFO(bind, type)     ELF32_ST_INFO ((bind), (type))
++
++/* Legal values for ST_BIND subfield of st_info (symbol binding).  */
++
++#define STB_LOCAL     0               /* Local symbol */
++#define STB_GLOBAL    1               /* Global symbol */
++#define STB_WEAK      2               /* Weak symbol */
++#define       STB_NUM         3               /* Number of defined types.  */
++#define STB_LOOS      10              /* Start of OS-specific */
++#define STB_HIOS      12              /* End of OS-specific */
++#define STB_LOPROC    13              /* Start of processor-specific */
++#define STB_HIPROC    15              /* End of processor-specific */
++
++/* Legal values for ST_TYPE subfield of st_info (symbol type).  */
++
++#define STT_NOTYPE    0               /* Symbol type is unspecified */
++#define STT_OBJECT    1               /* Symbol is a data object */
++#define STT_FUNC      2               /* Symbol is a code object */
++#define STT_SECTION   3               /* Symbol associated with a section */
++#define STT_FILE      4               /* Symbol's name is file name */
++#define STT_COMMON    5               /* Symbol is a common data object */
++#define STT_TLS               6               /* Symbol is thread-local data object*/
++#define       STT_NUM         7               /* Number of defined types.  */
++#define STT_LOOS      10              /* Start of OS-specific */
++#define STT_HIOS      12              /* End of OS-specific */
++#define STT_LOPROC    13              /* Start of processor-specific */
++#define STT_HIPROC    15              /* End of processor-specific */
++
++
++/* Symbol table indices are found in the hash buckets and chain table
++   of a symbol hash table section.  This special index value indicates
++   the end of a chain, meaning no further symbols are found in that bucket.  */
++
++#define STN_UNDEF     0               /* End of a chain.  */
++
++
++/* How to extract and insert information held in the st_other field.  */
++
++#define ELF32_ST_VISIBILITY(o)        ((o) & 0x03)
++
++/* For ELF64 the definitions are the same.  */
++#define ELF64_ST_VISIBILITY(o)        ELF32_ST_VISIBILITY (o)
++
++/* Symbol visibility specification encoded in the st_other field.  */
++#define STV_DEFAULT   0               /* Default symbol visibility rules */
++#define STV_INTERNAL  1               /* Processor specific hidden class */
++#define STV_HIDDEN    2               /* Sym unavailable in other modules */
++#define STV_PROTECTED 3               /* Not preemptible, not exported */
++
++
++/* Relocation table entry without addend (in section of type SHT_REL).  */
++
++typedef struct
++{
++  Elf32_Addr  r_offset;               /* Address */
++  Elf32_Word  r_info;                 /* Relocation type and symbol index */
++} Elf32_Rel;
++
++/* I have seen two different definitions of the Elf64_Rel and
++   Elf64_Rela structures, so we'll leave them out until Novell (or
++   whoever) gets their act together.  */
++/* The following, at least, is used on Sparc v9, MIPS, and Alpha.  */
++
++typedef struct
++{
++  Elf64_Addr  r_offset;               /* Address */
++  Elf64_Xword r_info;                 /* Relocation type and symbol index */
++} Elf64_Rel;
++
++/* Relocation table entry with addend (in section of type SHT_RELA).  */
++
++typedef struct
++{
++  Elf32_Addr  r_offset;               /* Address */
++  Elf32_Word  r_info;                 /* Relocation type and symbol index */
++  Elf32_Sword r_addend;               /* Addend */
++} Elf32_Rela;
++
++typedef struct
++{
++  Elf64_Addr  r_offset;               /* Address */
++  Elf64_Xword r_info;                 /* Relocation type and symbol index */
++  Elf64_Sxword        r_addend;               /* Addend */
++} Elf64_Rela;
++
++/* How to extract and insert information held in the r_info field.  */
++
++#define ELF32_R_SYM(val)              ((val) >> 8)
++#define ELF32_R_TYPE(val)             ((val) & 0xff)
++#define ELF32_R_INFO(sym, type)               (((sym) << 8) + ((type) & 0xff))
++
++#define ELF64_R_SYM(i)                        ((i) >> 32)
++#define ELF64_R_TYPE(i)                       ((i) & 0xffffffff)
++#define ELF64_R_INFO(sym,type)                ((((Elf64_Xword) (sym)) << 32) + (type))
++
++/* Program segment header.  */
++
++typedef struct
++{
++  Elf32_Word  p_type;                 /* Segment type */
++  Elf32_Off   p_offset;               /* Segment file offset */
++  Elf32_Addr  p_vaddr;                /* Segment virtual address */
++  Elf32_Addr  p_paddr;                /* Segment physical address */
++  Elf32_Word  p_filesz;               /* Segment size in file */
++  Elf32_Word  p_memsz;                /* Segment size in memory */
++  Elf32_Word  p_flags;                /* Segment flags */
++  Elf32_Word  p_align;                /* Segment alignment */
++} Elf32_Phdr;
++
++typedef struct
++{
++  Elf64_Word  p_type;                 /* Segment type */
++  Elf64_Word  p_flags;                /* Segment flags */
++  Elf64_Off   p_offset;               /* Segment file offset */
++  Elf64_Addr  p_vaddr;                /* Segment virtual address */
++  Elf64_Addr  p_paddr;                /* Segment physical address */
++  Elf64_Xword p_filesz;               /* Segment size in file */
++  Elf64_Xword p_memsz;                /* Segment size in memory */
++  Elf64_Xword p_align;                /* Segment alignment */
++} Elf64_Phdr;
++
++/* Legal values for p_type (segment type).  */
++
++#define       PT_NULL         0               /* Program header table entry unused */
++#define PT_LOAD               1               /* Loadable program segment */
++#define PT_DYNAMIC    2               /* Dynamic linking information */
++#define PT_INTERP     3               /* Program interpreter */
++#define PT_NOTE               4               /* Auxiliary information */
++#define PT_SHLIB      5               /* Reserved */
++#define PT_PHDR               6               /* Entry for header table itself */
++#define PT_TLS                7               /* Thread-local storage segment */
++#define       PT_NUM          8               /* Number of defined types */
++#define PT_LOOS               0x60000000      /* Start of OS-specific */
++#define PT_GNU_EH_FRAME       0x6474e550      /* GCC .eh_frame_hdr segment */
++#define PT_GNU_STACK  0x6474e551      /* Indicates stack executability */
++#define PT_GNU_RELRO  0x6474e552      /* Read-only after relocation */
++#define PT_PAX_FLAGS  0x65041580      /* Indicates PaX flag markings */
++#define PT_LOSUNW     0x6ffffffa
++#define PT_SUNWBSS    0x6ffffffa      /* Sun Specific segment */
++#define PT_SUNWSTACK  0x6ffffffb      /* Stack segment */
++#define PT_HISUNW     0x6fffffff
++#define PT_HIOS               0x6fffffff      /* End of OS-specific */
++#define PT_LOPROC     0x70000000      /* Start of processor-specific */
++#define PT_HIPROC     0x7fffffff      /* End of processor-specific */
++
++/* Legal values for p_flags (segment flags).  */
++
++#define PF_X          (1 << 0)        /* Segment is executable */
++#define PF_W          (1 << 1)        /* Segment is writable */
++#define PF_R          (1 << 2)        /* Segment is readable */
++#define PF_PAGEEXEC   (1 << 4)        /* Enable  PAGEEXEC */
++#define PF_NOPAGEEXEC (1 << 5)        /* Disable PAGEEXEC */
++#define PF_SEGMEXEC   (1 << 6)        /* Enable  SEGMEXEC */
++#define PF_NOSEGMEXEC (1 << 7)        /* Disable SEGMEXEC */
++#define PF_MPROTECT   (1 << 8)        /* Enable  MPROTECT */
++#define PF_NOMPROTECT (1 << 9)        /* Disable MPROTECT */
++#define PF_RANDEXEC   (1 << 10)       /* Enable  RANDEXEC */
++#define PF_NORANDEXEC (1 << 11)       /* Disable RANDEXEC */
++#define PF_EMUTRAMP   (1 << 12)       /* Enable  EMUTRAMP */
++#define PF_NOEMUTRAMP (1 << 13)       /* Disable EMUTRAMP */
++#define PF_RANDMMAP   (1 << 14)       /* Enable  RANDMMAP */
++#define PF_NORANDMMAP (1 << 15)       /* Disable RANDMMAP */
++#define PF_MASKOS     0x0ff00000      /* OS-specific */
++#define PF_MASKPROC   0xf0000000      /* Processor-specific */
++
++/* Legal values for note segment descriptor types for core files. */
++
++#define NT_PRSTATUS   1               /* Contains copy of prstatus struct */
++#define NT_FPREGSET   2               /* Contains copy of fpregset struct */
++#define NT_PRPSINFO   3               /* Contains copy of prpsinfo struct */
++#define NT_PRXREG     4               /* Contains copy of prxregset struct */
++#define NT_TASKSTRUCT 4               /* Contains copy of task structure */
++#define NT_PLATFORM   5               /* String from sysinfo(SI_PLATFORM) */
++#define NT_AUXV               6               /* Contains copy of auxv array */
++#define NT_GWINDOWS   7               /* Contains copy of gwindows struct */
++#define NT_ASRS               8               /* Contains copy of asrset struct */
++#define NT_PSTATUS    10              /* Contains copy of pstatus struct */
++#define NT_PSINFO     13              /* Contains copy of psinfo struct */
++#define NT_PRCRED     14              /* Contains copy of prcred struct */
++#define NT_UTSNAME    15              /* Contains copy of utsname struct */
++#define NT_LWPSTATUS  16              /* Contains copy of lwpstatus struct */
++#define NT_LWPSINFO   17              /* Contains copy of lwpinfo struct */
++#define NT_PRFPXREG   20              /* Contains copy of fprxregset struct*/
++
++/* Legal values for the note segment descriptor types for object files.  */
++
++#define NT_VERSION    1               /* Contains a version string.  */
++
++
++/* Dynamic section entry.  */
++
++typedef struct
++{
++  Elf32_Sword d_tag;                  /* Dynamic entry type */
++  union
++    {
++      Elf32_Word d_val;                       /* Integer value */
++      Elf32_Addr d_ptr;                       /* Address value */
++    } d_un;
++} Elf32_Dyn;
++
++typedef struct
++{
++  Elf64_Sxword        d_tag;                  /* Dynamic entry type */
++  union
++    {
++      Elf64_Xword d_val;              /* Integer value */
++      Elf64_Addr d_ptr;                       /* Address value */
++    } d_un;
++} Elf64_Dyn;
++
++/* Legal values for d_tag (dynamic entry type).  */
++
++#define DT_NULL               0               /* Marks end of dynamic section */
++#define DT_NEEDED     1               /* Name of needed library */
++#define DT_PLTRELSZ   2               /* Size in bytes of PLT relocs */
++#define DT_PLTGOT     3               /* Processor defined value */
++#define DT_HASH               4               /* Address of symbol hash table */
++#define DT_STRTAB     5               /* Address of string table */
++#define DT_SYMTAB     6               /* Address of symbol table */
++#define DT_RELA               7               /* Address of Rela relocs */
++#define DT_RELASZ     8               /* Total size of Rela relocs */
++#define DT_RELAENT    9               /* Size of one Rela reloc */
++#define DT_STRSZ      10              /* Size of string table */
++#define DT_SYMENT     11              /* Size of one symbol table entry */
++#define DT_INIT               12              /* Address of init function */
++#define DT_FINI               13              /* Address of termination function */
++#define DT_SONAME     14              /* Name of shared object */
++#define DT_RPATH      15              /* Library search path (deprecated) */
++#define DT_SYMBOLIC   16              /* Start symbol search here */
++#define DT_REL                17              /* Address of Rel relocs */
++#define DT_RELSZ      18              /* Total size of Rel relocs */
++#define DT_RELENT     19              /* Size of one Rel reloc */
++#define DT_PLTREL     20              /* Type of reloc in PLT */
++#define DT_DEBUG      21              /* For debugging; unspecified */
++#define DT_TEXTREL    22              /* Reloc might modify .text */
++#define DT_JMPREL     23              /* Address of PLT relocs */
++#define       DT_BIND_NOW     24              /* Process relocations of object */
++#define       DT_INIT_ARRAY   25              /* Array with addresses of init fct */
++#define       DT_FINI_ARRAY   26              /* Array with addresses of fini fct */
++#define       DT_INIT_ARRAYSZ 27              /* Size in bytes of DT_INIT_ARRAY */
++#define       DT_FINI_ARRAYSZ 28              /* Size in bytes of DT_FINI_ARRAY */
++#define DT_RUNPATH    29              /* Library search path */
++#define DT_FLAGS      30              /* Flags for the object being loaded */
++#define DT_ENCODING   32              /* Start of encoded range */
++#define DT_PREINIT_ARRAY 32           /* Array with addresses of preinit fct*/
++#define DT_PREINIT_ARRAYSZ 33         /* size in bytes of DT_PREINIT_ARRAY */
++#define       DT_NUM          34              /* Number used */
++#define DT_LOOS               0x6000000d      /* Start of OS-specific */
++#define DT_HIOS               0x6ffff000      /* End of OS-specific */
++#define DT_LOPROC     0x70000000      /* Start of processor-specific */
++#define DT_HIPROC     0x7fffffff      /* End of processor-specific */
++#define       DT_PROCNUM      DT_MIPS_NUM     /* Most used by any processor */
++
++/* DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the
++   Dyn.d_un.d_val field of the Elf*_Dyn structure.  This follows Sun's
++   approach.  */
++#define DT_VALRNGLO   0x6ffffd00
++#define DT_GNU_PRELINKED 0x6ffffdf5   /* Prelinking timestamp */
++#define DT_GNU_CONFLICTSZ 0x6ffffdf6  /* Size of conflict section */
++#define DT_GNU_LIBLISTSZ 0x6ffffdf7   /* Size of library list */
++#define DT_CHECKSUM   0x6ffffdf8
++#define DT_PLTPADSZ   0x6ffffdf9
++#define DT_MOVEENT    0x6ffffdfa
++#define DT_MOVESZ     0x6ffffdfb
++#define DT_FEATURE_1  0x6ffffdfc      /* Feature selection (DTF_*).  */
++#define DT_POSFLAG_1  0x6ffffdfd      /* Flags for DT_* entries, effecting
++                                         the following DT_* entry.  */
++#define DT_SYMINSZ    0x6ffffdfe      /* Size of syminfo table (in bytes) */
++#define DT_SYMINENT   0x6ffffdff      /* Entry size of syminfo */
++#define DT_VALRNGHI   0x6ffffdff
++#define DT_VALTAGIDX(tag)     (DT_VALRNGHI - (tag))   /* Reverse order! */
++#define DT_VALNUM 12
++
++/* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the
++   Dyn.d_un.d_ptr field of the Elf*_Dyn structure.
++
++   If any adjustment is made to the ELF object after it has been
++   built these entries will need to be adjusted.  */
++#define DT_ADDRRNGLO  0x6ffffe00
++#define DT_GNU_CONFLICT       0x6ffffef8      /* Start of conflict section */
++#define DT_GNU_LIBLIST        0x6ffffef9      /* Library list */
++#define DT_CONFIG     0x6ffffefa      /* Configuration information.  */
++#define DT_DEPAUDIT   0x6ffffefb      /* Dependency auditing.  */
++#define DT_AUDIT      0x6ffffefc      /* Object auditing.  */
++#define       DT_PLTPAD       0x6ffffefd      /* PLT padding.  */
++#define       DT_MOVETAB      0x6ffffefe      /* Move table.  */
++#define DT_SYMINFO    0x6ffffeff      /* Syminfo table.  */
++#define DT_ADDRRNGHI  0x6ffffeff
++#define DT_ADDRTAGIDX(tag)    (DT_ADDRRNGHI - (tag))  /* Reverse order! */
++#define DT_ADDRNUM 10
++
++/* The versioning entry types.  The next are defined as part of the
++   GNU extension.  */
++#define DT_VERSYM     0x6ffffff0
++
++#define DT_RELACOUNT  0x6ffffff9
++#define DT_RELCOUNT   0x6ffffffa
++
++/* These were chosen by Sun.  */
++#define DT_FLAGS_1    0x6ffffffb      /* State flags, see DF_1_* below.  */
++#define       DT_VERDEF       0x6ffffffc      /* Address of version definition
++                                         table */
++#define       DT_VERDEFNUM    0x6ffffffd      /* Number of version definitions */
++#define       DT_VERNEED      0x6ffffffe      /* Address of table with needed
++                                         versions */
++#define       DT_VERNEEDNUM   0x6fffffff      /* Number of needed versions */
++#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
++#define DT_VERSIONTAGNUM 16
++
++/* Sun added these machine-independent extensions in the "processor-specific"
++   range.  Be compatible.  */
++#define DT_AUXILIARY    0x7ffffffd      /* Shared object to load before self */
++#define DT_FILTER       0x7fffffff      /* Shared object to get values from */
++#define DT_EXTRATAGIDX(tag)   ((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1)
++#define DT_EXTRANUM   3
++
++/* Values of `d_un.d_val' in the DT_FLAGS entry.  */
++#define DF_ORIGIN     0x00000001      /* Object may use DF_ORIGIN */
++#define DF_SYMBOLIC   0x00000002      /* Symbol resolutions starts here */
++#define DF_TEXTREL    0x00000004      /* Object contains text relocations */
++#define DF_BIND_NOW   0x00000008      /* No lazy binding for this object */
++#define DF_STATIC_TLS 0x00000010      /* Module uses the static TLS model */
++
++/* State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1
++   entry in the dynamic section.  */
++#define DF_1_NOW      0x00000001      /* Set RTLD_NOW for this object.  */
++#define DF_1_GLOBAL   0x00000002      /* Set RTLD_GLOBAL for this object.  */
++#define DF_1_GROUP    0x00000004      /* Set RTLD_GROUP for this object.  */
++#define DF_1_NODELETE 0x00000008      /* Set RTLD_NODELETE for this object.*/
++#define DF_1_LOADFLTR 0x00000010      /* Trigger filtee loading at runtime.*/
++#define DF_1_INITFIRST        0x00000020      /* Set RTLD_INITFIRST for this object*/
++#define DF_1_NOOPEN   0x00000040      /* Set RTLD_NOOPEN for this object.  */
++#define DF_1_ORIGIN   0x00000080      /* $ORIGIN must be handled.  */
++#define DF_1_DIRECT   0x00000100      /* Direct binding enabled.  */
++#define DF_1_TRANS    0x00000200
++#define DF_1_INTERPOSE        0x00000400      /* Object is used to interpose.  */
++#define DF_1_NODEFLIB 0x00000800      /* Ignore default lib search path.  */
++#define DF_1_NODUMP   0x00001000      /* Object can't be dldump'ed.  */
++#define DF_1_CONFALT  0x00002000      /* Configuration alternative created.*/
++#define DF_1_ENDFILTEE        0x00004000      /* Filtee terminates filters search. */
++#define       DF_1_DISPRELDNE 0x00008000      /* Disp reloc applied at build time. */
++#define       DF_1_DISPRELPND 0x00010000      /* Disp reloc applied at run-time.  */
++
++/* Flags for the feature selection in DT_FEATURE_1.  */
++#define DTF_1_PARINIT 0x00000001
++#define DTF_1_CONFEXP 0x00000002
++
++/* Flags in the DT_POSFLAG_1 entry effecting only the next DT_* entry.  */
++#define DF_P1_LAZYLOAD        0x00000001      /* Lazyload following object.  */
++#define DF_P1_GROUPPERM       0x00000002      /* Symbols from next object are not
++                                         generally available.  */
++
++/* Version definition sections.  */
++
++typedef struct
++{
++  Elf32_Half  vd_version;             /* Version revision */
++  Elf32_Half  vd_flags;               /* Version information */
++  Elf32_Half  vd_ndx;                 /* Version Index */
++  Elf32_Half  vd_cnt;                 /* Number of associated aux entries */
++  Elf32_Word  vd_hash;                /* Version name hash value */
++  Elf32_Word  vd_aux;                 /* Offset in bytes to verdaux array */
++  Elf32_Word  vd_next;                /* Offset in bytes to next verdef
++                                         entry */
++} Elf32_Verdef;
++
++typedef struct
++{
++  Elf64_Half  vd_version;             /* Version revision */
++  Elf64_Half  vd_flags;               /* Version information */
++  Elf64_Half  vd_ndx;                 /* Version Index */
++  Elf64_Half  vd_cnt;                 /* Number of associated aux entries */
++  Elf64_Word  vd_hash;                /* Version name hash value */
++  Elf64_Word  vd_aux;                 /* Offset in bytes to verdaux array */
++  Elf64_Word  vd_next;                /* Offset in bytes to next verdef
++                                         entry */
++} Elf64_Verdef;
++
++
++/* Legal values for vd_version (version revision).  */
++#define VER_DEF_NONE  0               /* No version */
++#define VER_DEF_CURRENT       1               /* Current version */
++#define VER_DEF_NUM   2               /* Given version number */
++
++/* Legal values for vd_flags (version information flags).  */
++#define VER_FLG_BASE  0x1             /* Version definition of file itself */
++#define VER_FLG_WEAK  0x2             /* Weak version identifier */
++
++/* Versym symbol index values.  */
++#define       VER_NDX_LOCAL           0       /* Symbol is local.  */
++#define       VER_NDX_GLOBAL          1       /* Symbol is global.  */
++#define       VER_NDX_LORESERVE       0xff00  /* Beginning of reserved entries.  */
++#define       VER_NDX_ELIMINATE       0xff01  /* Symbol is to be eliminated.  */
++
++/* Auxialiary version information.  */
++
++typedef struct
++{
++  Elf32_Word  vda_name;               /* Version or dependency names */
++  Elf32_Word  vda_next;               /* Offset in bytes to next verdaux
++                                         entry */
++} Elf32_Verdaux;
++
++typedef struct
++{
++  Elf64_Word  vda_name;               /* Version or dependency names */
++  Elf64_Word  vda_next;               /* Offset in bytes to next verdaux
++                                         entry */
++} Elf64_Verdaux;
++
++
++/* Version dependency section.  */
++
++typedef struct
++{
++  Elf32_Half  vn_version;             /* Version of structure */
++  Elf32_Half  vn_cnt;                 /* Number of associated aux entries */
++  Elf32_Word  vn_file;                /* Offset of filename for this
++                                         dependency */
++  Elf32_Word  vn_aux;                 /* Offset in bytes to vernaux array */
++  Elf32_Word  vn_next;                /* Offset in bytes to next verneed
++                                         entry */
++} Elf32_Verneed;
++
++typedef struct
++{
++  Elf64_Half  vn_version;             /* Version of structure */
++  Elf64_Half  vn_cnt;                 /* Number of associated aux entries */
++  Elf64_Word  vn_file;                /* Offset of filename for this
++                                         dependency */
++  Elf64_Word  vn_aux;                 /* Offset in bytes to vernaux array */
++  Elf64_Word  vn_next;                /* Offset in bytes to next verneed
++                                         entry */
++} Elf64_Verneed;
++
++
++/* Legal values for vn_version (version revision).  */
++#define VER_NEED_NONE  0              /* No version */
++#define VER_NEED_CURRENT 1            /* Current version */
++#define VER_NEED_NUM   2              /* Given version number */
++
++/* Auxiliary needed version information.  */
++
++typedef struct
++{
++  Elf32_Word  vna_hash;               /* Hash value of dependency name */
++  Elf32_Half  vna_flags;              /* Dependency specific information */
++  Elf32_Half  vna_other;              /* Unused */
++  Elf32_Word  vna_name;               /* Dependency name string offset */
++  Elf32_Word  vna_next;               /* Offset in bytes to next vernaux
++                                         entry */
++} Elf32_Vernaux;
++
++typedef struct
++{
++  Elf64_Word  vna_hash;               /* Hash value of dependency name */
++  Elf64_Half  vna_flags;              /* Dependency specific information */
++  Elf64_Half  vna_other;              /* Unused */
++  Elf64_Word  vna_name;               /* Dependency name string offset */
++  Elf64_Word  vna_next;               /* Offset in bytes to next vernaux
++                                         entry */
++} Elf64_Vernaux;
++
++
++/* Legal values for vna_flags.  */
++#define VER_FLG_WEAK  0x2             /* Weak version identifier */
++
++
++/* Auxiliary vector.  */
++
++/* This vector is normally only used by the program interpreter.  The
++   usual definition in an ABI supplement uses the name auxv_t.  The
++   vector is not usually defined in a standard <elf.h> file, but it
++   can't hurt.  We rename it to avoid conflicts.  The sizes of these
++   types are an arrangement between the exec server and the program
++   interpreter, so we don't fully specify them here.  */
++
++typedef struct
++{
++  uint32_t a_type;            /* Entry type */
++  union
++    {
++      uint32_t a_val;         /* Integer value */
++      /* We use to have pointer elements added here.  We cannot do that,
++       though, since it does not work when using 32-bit definitions
++       on 64-bit platforms and vice versa.  */
++    } a_un;
++} Elf32_auxv_t;
++
++typedef struct
++{
++  uint64_t a_type;            /* Entry type */
++  union
++    {
++      uint64_t a_val;         /* Integer value */
++      /* We use to have pointer elements added here.  We cannot do that,
++       though, since it does not work when using 32-bit definitions
++       on 64-bit platforms and vice versa.  */
++    } a_un;
++} Elf64_auxv_t;
++
++/* Legal values for a_type (entry type).  */
++
++#define AT_NULL               0               /* End of vector */
++#define AT_IGNORE     1               /* Entry should be ignored */
++#define AT_EXECFD     2               /* File descriptor of program */
++#define AT_PHDR               3               /* Program headers for program */
++#define AT_PHENT      4               /* Size of program header entry */
++#define AT_PHNUM      5               /* Number of program headers */
++#define AT_PAGESZ     6               /* System page size */
++#define AT_BASE               7               /* Base address of interpreter */
++#define AT_FLAGS      8               /* Flags */
++#define AT_ENTRY      9               /* Entry point of program */
++#define AT_NOTELF     10              /* Program is not ELF */
++#define AT_UID                11              /* Real uid */
++#define AT_EUID               12              /* Effective uid */
++#define AT_GID                13              /* Real gid */
++#define AT_EGID               14              /* Effective gid */
++#define AT_CLKTCK     17              /* Frequency of times() */
++
++/* Some more special a_type values describing the hardware.  */
++#define AT_PLATFORM   15              /* String identifying platform.  */
++#define AT_HWCAP      16              /* Machine dependent hints about
++                                         processor capabilities.  */
++
++/* This entry gives some information about the FPU initialization
++   performed by the kernel.  */
++#define AT_FPUCW      18              /* Used FPU control word.  */
++
++/* Cache block sizes.  */
++#define AT_DCACHEBSIZE        19              /* Data cache block size.  */
++#define AT_ICACHEBSIZE        20              /* Instruction cache block size.  */
++#define AT_UCACHEBSIZE        21              /* Unified cache block size.  */
++
++/* A special ignored value for PPC, used by the kernel to control the
++   interpretation of the AUXV. Must be > 16.  */
++#define AT_IGNOREPPC  22              /* Entry should be ignored.  */
++
++#define       AT_SECURE       23              /* Boolean, was exec setuid-like?  */
++
++/* Pointer to the global system page used for system calls and other
++   nice things.  */
++#define AT_SYSINFO    32
++#define AT_SYSINFO_EHDR       33
++
++/* Shapes of the caches.  Bits 0-3 contains associativity; bits 4-7 contains
++   log2 of line size; mask those to get cache size.  */
++#define AT_L1I_CACHESHAPE     34
++#define AT_L1D_CACHESHAPE     35
++#define AT_L2_CACHESHAPE      36
++#define AT_L3_CACHESHAPE      37
++
++/* Note section contents.  Each entry in the note section begins with
++   a header of a fixed form.  */
++
++typedef struct
++{
++  Elf32_Word n_namesz;                        /* Length of the note's name.  */
++  Elf32_Word n_descsz;                        /* Length of the note's descriptor.  */
++  Elf32_Word n_type;                  /* Type of the note.  */
++} Elf32_Nhdr;
++
++typedef struct
++{
++  Elf64_Word n_namesz;                        /* Length of the note's name.  */
++  Elf64_Word n_descsz;                        /* Length of the note's descriptor.  */
++  Elf64_Word n_type;                  /* Type of the note.  */
++} Elf64_Nhdr;
++
++/* Known names of notes.  */
++
++/* Solaris entries in the note section have this name.  */
++#define ELF_NOTE_SOLARIS      "SUNW Solaris"
++
++/* Note entries for GNU systems have this name.  */
++#define ELF_NOTE_GNU          "GNU"
++
++
++/* Defined types of notes for Solaris.  */
++
++/* Value of descriptor (one word) is desired pagesize for the binary.  */
++#define ELF_NOTE_PAGESIZE_HINT        1
++
++
++/* Defined note types for GNU systems.  */
++
++/* ABI information.  The descriptor consists of words:
++   word 0: OS descriptor
++   word 1: major version of the ABI
++   word 2: minor version of the ABI
++   word 3: subminor version of the ABI
++*/
++#define ELF_NOTE_ABI          1
++
++/* Known OSes.  These value can appear in word 0 of an ELF_NOTE_ABI
++   note section entry.  */
++#define ELF_NOTE_OS_LINUX     0
++#define ELF_NOTE_OS_GNU               1
++#define ELF_NOTE_OS_SOLARIS2  2
++#define ELF_NOTE_OS_FREEBSD   3
++
++
++/* Move records.  */
++typedef struct
++{
++  Elf32_Xword m_value;                /* Symbol value.  */
++  Elf32_Word m_info;          /* Size and index.  */
++  Elf32_Word m_poffset;               /* Symbol offset.  */
++  Elf32_Half m_repeat;                /* Repeat count.  */
++  Elf32_Half m_stride;                /* Stride info.  */
++} Elf32_Move;
++
++typedef struct
++{
++  Elf64_Xword m_value;                /* Symbol value.  */
++  Elf64_Xword m_info;         /* Size and index.  */
++  Elf64_Xword m_poffset;      /* Symbol offset.  */
++  Elf64_Half m_repeat;                /* Repeat count.  */
++  Elf64_Half m_stride;                /* Stride info.  */
++} Elf64_Move;
++
++/* Macro to construct move records.  */
++#define ELF32_M_SYM(info)     ((info) >> 8)
++#define ELF32_M_SIZE(info)    ((unsigned char) (info))
++#define ELF32_M_INFO(sym, size)       (((sym) << 8) + (unsigned char) (size))
++
++#define ELF64_M_SYM(info)     ELF32_M_SYM (info)
++#define ELF64_M_SIZE(info)    ELF32_M_SIZE (info)
++#define ELF64_M_INFO(sym, size)       ELF32_M_INFO (sym, size)
++
++
++/* Motorola 68k specific definitions.  */
++
++/* Values for Elf32_Ehdr.e_flags.  */
++#define EF_CPU32      0x00810000
++
++/* m68k relocs.  */
++
++#define R_68K_NONE    0               /* No reloc */
++#define R_68K_32      1               /* Direct 32 bit  */
++#define R_68K_16      2               /* Direct 16 bit  */
++#define R_68K_8               3               /* Direct 8 bit  */
++#define R_68K_PC32    4               /* PC relative 32 bit */
++#define R_68K_PC16    5               /* PC relative 16 bit */
++#define R_68K_PC8     6               /* PC relative 8 bit */
++#define R_68K_GOT32   7               /* 32 bit PC relative GOT entry */
++#define R_68K_GOT16   8               /* 16 bit PC relative GOT entry */
++#define R_68K_GOT8    9               /* 8 bit PC relative GOT entry */
++#define R_68K_GOT32O  10              /* 32 bit GOT offset */
++#define R_68K_GOT16O  11              /* 16 bit GOT offset */
++#define R_68K_GOT8O   12              /* 8 bit GOT offset */
++#define R_68K_PLT32   13              /* 32 bit PC relative PLT address */
++#define R_68K_PLT16   14              /* 16 bit PC relative PLT address */
++#define R_68K_PLT8    15              /* 8 bit PC relative PLT address */
++#define R_68K_PLT32O  16              /* 32 bit PLT offset */
++#define R_68K_PLT16O  17              /* 16 bit PLT offset */
++#define R_68K_PLT8O   18              /* 8 bit PLT offset */
++#define R_68K_COPY    19              /* Copy symbol at runtime */
++#define R_68K_GLOB_DAT        20              /* Create GOT entry */
++#define R_68K_JMP_SLOT        21              /* Create PLT entry */
++#define R_68K_RELATIVE        22              /* Adjust by program base */
++/* Keep this the last entry.  */
++#define R_68K_NUM     23
++
++/* Intel 80386 specific definitions.  */
++
++/* i386 relocs.  */
++
++#define R_386_NONE       0            /* No reloc */
++#define R_386_32         1            /* Direct 32 bit  */
++#define R_386_PC32       2            /* PC relative 32 bit */
++#define R_386_GOT32      3            /* 32 bit GOT entry */
++#define R_386_PLT32      4            /* 32 bit PLT address */
++#define R_386_COPY       5            /* Copy symbol at runtime */
++#define R_386_GLOB_DAT           6            /* Create GOT entry */
++#define R_386_JMP_SLOT           7            /* Create PLT entry */
++#define R_386_RELATIVE           8            /* Adjust by program base */
++#define R_386_GOTOFF     9            /* 32 bit offset to GOT */
++#define R_386_GOTPC      10           /* 32 bit PC relative offset to GOT */
++#define R_386_32PLT      11
++#define R_386_TLS_TPOFF          14           /* Offset in static TLS block */
++#define R_386_TLS_IE     15           /* Address of GOT entry for static TLS
++                                         block offset */
++#define R_386_TLS_GOTIE          16           /* GOT entry for static TLS block
++                                         offset */
++#define R_386_TLS_LE     17           /* Offset relative to static TLS
++                                         block */
++#define R_386_TLS_GD     18           /* Direct 32 bit for GNU version of
++                                         general dynamic thread local data */
++#define R_386_TLS_LDM    19           /* Direct 32 bit for GNU version of
++                                         local dynamic thread local data
++                                         in LE code */
++#define R_386_16         20
++#define R_386_PC16       21
++#define R_386_8                  22
++#define R_386_PC8        23
++#define R_386_TLS_GD_32          24           /* Direct 32 bit for general dynamic
++                                         thread local data */
++#define R_386_TLS_GD_PUSH  25         /* Tag for pushl in GD TLS code */
++#define R_386_TLS_GD_CALL  26         /* Relocation for call to
++                                         __tls_get_addr() */
++#define R_386_TLS_GD_POP   27         /* Tag for popl in GD TLS code */
++#define R_386_TLS_LDM_32   28         /* Direct 32 bit for local dynamic
++                                         thread local data in LE code */
++#define R_386_TLS_LDM_PUSH 29         /* Tag for pushl in LDM TLS code */
++#define R_386_TLS_LDM_CALL 30         /* Relocation for call to
++                                         __tls_get_addr() in LDM code */
++#define R_386_TLS_LDM_POP  31         /* Tag for popl in LDM TLS code */
++#define R_386_TLS_LDO_32   32         /* Offset relative to TLS block */
++#define R_386_TLS_IE_32          33           /* GOT entry for negated static TLS
++                                         block offset */
++#define R_386_TLS_LE_32          34           /* Negated offset relative to static
++                                         TLS block */
++#define R_386_TLS_DTPMOD32 35         /* ID of module containing symbol */
++#define R_386_TLS_DTPOFF32 36         /* Offset in TLS block */
++#define R_386_TLS_TPOFF32  37         /* Negated offset in static TLS block */
++/* Keep this the last entry.  */
++#define R_386_NUM        38
++
++/* FR-V specific definitions.  */
++#define R_FRV_NONE            0       /* No reloc.  */
++#define R_FRV_32              1       /* Direct 32 bit.  */
++/* Canonical function descriptor address.  */
++#define R_FRV_FUNCDESC                14
++/* Private function descriptor initialization.  */
++#define R_FRV_FUNCDESC_VALUE  18
++
++                                              /* gpr support */
++#define EF_FRV_GPR_MASK               0x00000003      /* mask for # of gprs */
++#define EF_FRV_GPR_32         0x00000001      /* -mgpr-32 */
++#define EF_FRV_GPR_64         0x00000002      /* -mgpr-64 */
++
++                                              /* fpr support */
++#define EF_FRV_FPR_MASK               0x0000000c      /* mask for # of fprs */
++#define EF_FRV_FPR_32         0x00000004      /* -mfpr-32 */
++#define EF_FRV_FPR_64         0x00000008      /* -mfpr-64 */
++#define EF_FRV_FPR_NONE               0x0000000c      /* -msoft-float */
++
++#define EF_FRV_PIC   0x00000100
++#define EF_FRV_FDPIC 0x00008000
++
++/* SUN SPARC specific definitions.  */
++
++/* Legal values for ST_TYPE subfield of st_info (symbol type).  */
++
++#define STT_SPARC_REGISTER    13      /* Global register reserved to app. */
++
++/* Values for Elf64_Ehdr.e_flags.  */
++
++#define EF_SPARCV9_MM         3
++#define EF_SPARCV9_TSO                0
++#define EF_SPARCV9_PSO                1
++#define EF_SPARCV9_RMO                2
++#define EF_SPARC_LEDATA               0x800000 /* little endian data */
++#define EF_SPARC_EXT_MASK     0xFFFF00
++#define EF_SPARC_32PLUS               0x000100 /* generic V8+ features */
++#define EF_SPARC_SUN_US1      0x000200 /* Sun UltraSPARC1 extensions */
++#define EF_SPARC_HAL_R1               0x000400 /* HAL R1 extensions */
++#define EF_SPARC_SUN_US3      0x000800 /* Sun UltraSPARCIII extensions */
++
++/* SPARC relocs.  */
++
++#define R_SPARC_NONE          0       /* No reloc */
++#define R_SPARC_8             1       /* Direct 8 bit */
++#define R_SPARC_16            2       /* Direct 16 bit */
++#define R_SPARC_32            3       /* Direct 32 bit */
++#define R_SPARC_DISP8         4       /* PC relative 8 bit */
++#define R_SPARC_DISP16                5       /* PC relative 16 bit */
++#define R_SPARC_DISP32                6       /* PC relative 32 bit */
++#define R_SPARC_WDISP30               7       /* PC relative 30 bit shifted */
++#define R_SPARC_WDISP22               8       /* PC relative 22 bit shifted */
++#define R_SPARC_HI22          9       /* High 22 bit */
++#define R_SPARC_22            10      /* Direct 22 bit */
++#define R_SPARC_13            11      /* Direct 13 bit */
++#define R_SPARC_LO10          12      /* Truncated 10 bit */
++#define R_SPARC_GOT10         13      /* Truncated 10 bit GOT entry */
++#define R_SPARC_GOT13         14      /* 13 bit GOT entry */
++#define R_SPARC_GOT22         15      /* 22 bit GOT entry shifted */
++#define R_SPARC_PC10          16      /* PC relative 10 bit truncated */
++#define R_SPARC_PC22          17      /* PC relative 22 bit shifted */
++#define R_SPARC_WPLT30                18      /* 30 bit PC relative PLT address */
++#define R_SPARC_COPY          19      /* Copy symbol at runtime */
++#define R_SPARC_GLOB_DAT      20      /* Create GOT entry */
++#define R_SPARC_JMP_SLOT      21      /* Create PLT entry */
++#define R_SPARC_RELATIVE      22      /* Adjust by program base */
++#define R_SPARC_UA32          23      /* Direct 32 bit unaligned */
++
++/* Additional Sparc64 relocs.  */
++
++#define R_SPARC_PLT32         24      /* Direct 32 bit ref to PLT entry */
++#define R_SPARC_HIPLT22               25      /* High 22 bit PLT entry */
++#define R_SPARC_LOPLT10               26      /* Truncated 10 bit PLT entry */
++#define R_SPARC_PCPLT32               27      /* PC rel 32 bit ref to PLT entry */
++#define R_SPARC_PCPLT22               28      /* PC rel high 22 bit PLT entry */
++#define R_SPARC_PCPLT10               29      /* PC rel trunc 10 bit PLT entry */
++#define R_SPARC_10            30      /* Direct 10 bit */
++#define R_SPARC_11            31      /* Direct 11 bit */
++#define R_SPARC_64            32      /* Direct 64 bit */
++#define R_SPARC_OLO10         33      /* 10bit with secondary 13bit addend */
++#define R_SPARC_HH22          34      /* Top 22 bits of direct 64 bit */
++#define R_SPARC_HM10          35      /* High middle 10 bits of ... */
++#define R_SPARC_LM22          36      /* Low middle 22 bits of ... */
++#define R_SPARC_PC_HH22               37      /* Top 22 bits of pc rel 64 bit */
++#define R_SPARC_PC_HM10               38      /* High middle 10 bit of ... */
++#define R_SPARC_PC_LM22               39      /* Low miggle 22 bits of ... */
++#define R_SPARC_WDISP16               40      /* PC relative 16 bit shifted */
++#define R_SPARC_WDISP19               41      /* PC relative 19 bit shifted */
++#define R_SPARC_7             43      /* Direct 7 bit */
++#define R_SPARC_5             44      /* Direct 5 bit */
++#define R_SPARC_6             45      /* Direct 6 bit */
++#define R_SPARC_DISP64                46      /* PC relative 64 bit */
++#define R_SPARC_PLT64         47      /* Direct 64 bit ref to PLT entry */
++#define R_SPARC_HIX22         48      /* High 22 bit complemented */
++#define R_SPARC_LOX10         49      /* Truncated 11 bit complemented */
++#define R_SPARC_H44           50      /* Direct high 12 of 44 bit */
++#define R_SPARC_M44           51      /* Direct mid 22 of 44 bit */
++#define R_SPARC_L44           52      /* Direct low 10 of 44 bit */
++#define R_SPARC_REGISTER      53      /* Global register usage */
++#define R_SPARC_UA64          54      /* Direct 64 bit unaligned */
++#define R_SPARC_UA16          55      /* Direct 16 bit unaligned */
++#define R_SPARC_TLS_GD_HI22   56
++#define R_SPARC_TLS_GD_LO10   57
++#define R_SPARC_TLS_GD_ADD    58
++#define R_SPARC_TLS_GD_CALL   59
++#define R_SPARC_TLS_LDM_HI22  60
++#define R_SPARC_TLS_LDM_LO10  61
++#define R_SPARC_TLS_LDM_ADD   62
++#define R_SPARC_TLS_LDM_CALL  63
++#define R_SPARC_TLS_LDO_HIX22 64
++#define R_SPARC_TLS_LDO_LOX10 65
++#define R_SPARC_TLS_LDO_ADD   66
++#define R_SPARC_TLS_IE_HI22   67
++#define R_SPARC_TLS_IE_LO10   68
++#define R_SPARC_TLS_IE_LD     69
++#define R_SPARC_TLS_IE_LDX    70
++#define R_SPARC_TLS_IE_ADD    71
++#define R_SPARC_TLS_LE_HIX22  72
++#define R_SPARC_TLS_LE_LOX10  73
++#define R_SPARC_TLS_DTPMOD32  74
++#define R_SPARC_TLS_DTPMOD64  75
++#define R_SPARC_TLS_DTPOFF32  76
++#define R_SPARC_TLS_DTPOFF64  77
++#define R_SPARC_TLS_TPOFF32   78
++#define R_SPARC_TLS_TPOFF64   79
++/* Keep this the last entry.  */
++#define R_SPARC_NUM           80
++
++/* For Sparc64, legal values for d_tag of Elf64_Dyn.  */
++
++#define DT_SPARC_REGISTER 0x70000001
++#define DT_SPARC_NUM  2
++
++/* Bits present in AT_HWCAP, primarily for Sparc32.  */
++
++#define HWCAP_SPARC_FLUSH     1       /* The cpu supports flush insn.  */
++#define HWCAP_SPARC_STBAR     2
++#define HWCAP_SPARC_SWAP      4
++#define HWCAP_SPARC_MULDIV    8
++#define HWCAP_SPARC_V9                16      /* The cpu is v9, so v8plus is ok.  */
++#define HWCAP_SPARC_ULTRA3    32
++
++/* MIPS R3000 specific definitions.  */
++
++/* Legal values for e_flags field of Elf32_Ehdr.  */
++
++#define EF_MIPS_NOREORDER   1         /* A .noreorder directive was used */
++#define EF_MIPS_PIC       2           /* Contains PIC code */
++#define EF_MIPS_CPIC      4           /* Uses PIC calling sequence */
++#define EF_MIPS_XGOT      8
++#define EF_MIPS_64BIT_WHIRL 16
++#define EF_MIPS_ABI2      32
++#define EF_MIPS_ABI_ON32    64
++#define EF_MIPS_ARCH      0xf0000000  /* MIPS architecture level */
++
++/* Legal values for MIPS architecture level.  */
++
++#define EF_MIPS_ARCH_1            0x00000000  /* -mips1 code.  */
++#define EF_MIPS_ARCH_2            0x10000000  /* -mips2 code.  */
++#define EF_MIPS_ARCH_3            0x20000000  /* -mips3 code.  */
++#define EF_MIPS_ARCH_4            0x30000000  /* -mips4 code.  */
++#define EF_MIPS_ARCH_5            0x40000000  /* -mips5 code.  */
++#define EF_MIPS_ARCH_32           0x60000000  /* MIPS32 code.  */
++#define EF_MIPS_ARCH_64           0x70000000  /* MIPS64 code.  */
++
++/* The following are non-official names and should not be used.  */
++
++#define E_MIPS_ARCH_1   0x00000000    /* -mips1 code.  */
++#define E_MIPS_ARCH_2   0x10000000    /* -mips2 code.  */
++#define E_MIPS_ARCH_3   0x20000000    /* -mips3 code.  */
++#define E_MIPS_ARCH_4   0x30000000    /* -mips4 code.  */
++#define E_MIPS_ARCH_5   0x40000000    /* -mips5 code.  */
++#define E_MIPS_ARCH_32          0x60000000    /* MIPS32 code.  */
++#define E_MIPS_ARCH_64          0x70000000    /* MIPS64 code.  */
++
++/* Special section indices.  */
++
++#define SHN_MIPS_ACOMMON    0xff00    /* Allocated common symbols */
++#define SHN_MIPS_TEXT     0xff01      /* Allocated test symbols.  */
++#define SHN_MIPS_DATA     0xff02      /* Allocated data symbols.  */
++#define SHN_MIPS_SCOMMON    0xff03    /* Small common symbols */
++#define SHN_MIPS_SUNDEFINED 0xff04    /* Small undefined symbols */
++
++/* Legal values for sh_type field of Elf32_Shdr.  */
++
++#define SHT_MIPS_LIBLIST       0x70000000 /* Shared objects used in link */
++#define SHT_MIPS_MSYM        0x70000001
++#define SHT_MIPS_CONFLICT      0x70000002 /* Conflicting symbols */
++#define SHT_MIPS_GPTAB               0x70000003 /* Global data area sizes */
++#define SHT_MIPS_UCODE               0x70000004 /* Reserved for SGI/MIPS compilers */
++#define SHT_MIPS_DEBUG               0x70000005 /* MIPS ECOFF debugging information*/
++#define SHT_MIPS_REGINFO       0x70000006 /* Register usage information */
++#define SHT_MIPS_PACKAGE       0x70000007
++#define SHT_MIPS_PACKSYM       0x70000008
++#define SHT_MIPS_RELD        0x70000009
++#define SHT_MIPS_IFACE         0x7000000b
++#define SHT_MIPS_CONTENT       0x7000000c
++#define SHT_MIPS_OPTIONS       0x7000000d /* Miscellaneous options.  */
++#define SHT_MIPS_SHDR        0x70000010
++#define SHT_MIPS_FDESC               0x70000011
++#define SHT_MIPS_EXTSYM              0x70000012
++#define SHT_MIPS_DENSE               0x70000013
++#define SHT_MIPS_PDESC               0x70000014
++#define SHT_MIPS_LOCSYM              0x70000015
++#define SHT_MIPS_AUXSYM              0x70000016
++#define SHT_MIPS_OPTSYM              0x70000017
++#define SHT_MIPS_LOCSTR              0x70000018
++#define SHT_MIPS_LINE        0x70000019
++#define SHT_MIPS_RFDESC              0x7000001a
++#define SHT_MIPS_DELTASYM      0x7000001b
++#define SHT_MIPS_DELTAINST     0x7000001c
++#define SHT_MIPS_DELTACLASS    0x7000001d
++#define SHT_MIPS_DWARF         0x7000001e /* DWARF debugging information.  */
++#define SHT_MIPS_DELTADECL     0x7000001f
++#define SHT_MIPS_SYMBOL_LIB    0x70000020
++#define SHT_MIPS_EVENTS              0x70000021 /* Event section.  */
++#define SHT_MIPS_TRANSLATE     0x70000022
++#define SHT_MIPS_PIXIE               0x70000023
++#define SHT_MIPS_XLATE               0x70000024
++#define SHT_MIPS_XLATE_DEBUG   0x70000025
++#define SHT_MIPS_WHIRL               0x70000026
++#define SHT_MIPS_EH_REGION     0x70000027
++#define SHT_MIPS_XLATE_OLD     0x70000028
++#define SHT_MIPS_PDR_EXCEPTION 0x70000029
++
++/* Legal values for sh_flags field of Elf32_Shdr.  */
++
++#define SHF_MIPS_GPREL         0x10000000     /* Must be part of global data area */
++#define SHF_MIPS_MERGE         0x20000000
++#define SHF_MIPS_ADDR  0x40000000
++#define SHF_MIPS_STRINGS 0x80000000
++#define SHF_MIPS_NOSTRIP 0x08000000
++#define SHF_MIPS_LOCAL         0x04000000
++#define SHF_MIPS_NAMES         0x02000000
++#define SHF_MIPS_NODUPE        0x01000000
++
++
++/* Symbol tables.  */
++
++/* MIPS specific values for `st_other'.  */
++#define STO_MIPS_DEFAULT              0x0
++#define STO_MIPS_INTERNAL             0x1
++#define STO_MIPS_HIDDEN                       0x2
++#define STO_MIPS_PROTECTED            0x3
++#define STO_MIPS_SC_ALIGN_UNUSED      0xff
++
++/* MIPS specific values for `st_info'.  */
++#define STB_MIPS_SPLIT_COMMON         13
++
++/* Entries found in sections of type SHT_MIPS_GPTAB.  */
++
++typedef union
++{
++  struct
++    {
++      Elf32_Word gt_current_g_value;  /* -G value used for compilation */
++      Elf32_Word gt_unused;           /* Not used */
++    } gt_header;                      /* First entry in section */
++  struct
++    {
++      Elf32_Word gt_g_value;          /* If this value were used for -G */
++      Elf32_Word gt_bytes;            /* This many bytes would be used */
++    } gt_entry;                               /* Subsequent entries in section */
++} Elf32_gptab;
++
++/* Entry found in sections of type SHT_MIPS_REGINFO.  */
++
++typedef struct
++{
++  Elf32_Word  ri_gprmask;             /* General registers used */
++  Elf32_Word  ri_cprmask[4];          /* Coprocessor registers used */
++  Elf32_Sword ri_gp_value;            /* $gp register value */
++} Elf32_RegInfo;
++
++/* Entries found in sections of type SHT_MIPS_OPTIONS.  */
++
++typedef struct
++{
++  unsigned char kind;         /* Determines interpretation of the
++                                 variable part of descriptor.  */
++  unsigned char size;         /* Size of descriptor, including header.  */
++  Elf32_Section section;      /* Section header index of section affected,
++                                 0 for global options.  */
++  Elf32_Word info;            /* Kind-specific information.  */
++} Elf_Options;
++
++/* Values for `kind' field in Elf_Options.  */
++
++#define ODK_NULL      0       /* Undefined.  */
++#define ODK_REGINFO   1       /* Register usage information.  */
++#define ODK_EXCEPTIONS        2       /* Exception processing options.  */
++#define ODK_PAD               3       /* Section padding options.  */
++#define ODK_HWPATCH   4       /* Hardware workarounds performed */
++#define ODK_FILL      5       /* record the fill value used by the linker. */
++#define ODK_TAGS      6       /* reserve space for desktop tools to write. */
++#define ODK_HWAND     7       /* HW workarounds.  'AND' bits when merging. */
++#define ODK_HWOR      8       /* HW workarounds.  'OR' bits when merging.  */
++
++/* Values for `info' in Elf_Options for ODK_EXCEPTIONS entries.  */
++
++#define OEX_FPU_MIN   0x1f    /* FPE's which MUST be enabled.  */
++#define OEX_FPU_MAX   0x1f00  /* FPE's which MAY be enabled.  */
++#define OEX_PAGE0     0x10000 /* page zero must be mapped.  */
++#define OEX_SMM               0x20000 /* Force sequential memory mode?  */
++#define OEX_FPDBUG    0x40000 /* Force floating point debug mode?  */
++#define OEX_PRECISEFP OEX_FPDBUG
++#define OEX_DISMISS   0x80000 /* Dismiss invalid address faults?  */
++
++#define OEX_FPU_INVAL 0x10
++#define OEX_FPU_DIV0  0x08
++#define OEX_FPU_OFLO  0x04
++#define OEX_FPU_UFLO  0x02
++#define OEX_FPU_INEX  0x01
++
++/* Masks for `info' in Elf_Options for an ODK_HWPATCH entry.  */
++
++#define OHW_R4KEOP    0x1     /* R4000 end-of-page patch.  */
++#define OHW_R8KPFETCH 0x2     /* may need R8000 prefetch patch.  */
++#define OHW_R5KEOP    0x4     /* R5000 end-of-page patch.  */
++#define OHW_R5KCVTL   0x8     /* R5000 cvt.[ds].l bug.  clean=1.  */
++
++#define OPAD_PREFIX   0x1
++#define OPAD_POSTFIX  0x2
++#define OPAD_SYMBOL   0x4
++
++/* Entry found in `.options' section.  */
++
++typedef struct
++{
++  Elf32_Word hwp_flags1;      /* Extra flags.  */
++  Elf32_Word hwp_flags2;      /* Extra flags.  */
++} Elf_Options_Hw;
++
++/* Masks for `info' in ElfOptions for ODK_HWAND and ODK_HWOR entries.  */
++
++#define OHWA0_R4KEOP_CHECKED  0x00000001
++#define OHWA1_R4KEOP_CLEAN    0x00000002
++
++/* MIPS relocs.  */
++
++#define R_MIPS_NONE           0       /* No reloc */
++#define R_MIPS_16             1       /* Direct 16 bit */
++#define R_MIPS_32             2       /* Direct 32 bit */
++#define R_MIPS_REL32          3       /* PC relative 32 bit */
++#define R_MIPS_26             4       /* Direct 26 bit shifted */
++#define R_MIPS_HI16           5       /* High 16 bit */
++#define R_MIPS_LO16           6       /* Low 16 bit */
++#define R_MIPS_GPREL16                7       /* GP relative 16 bit */
++#define R_MIPS_LITERAL                8       /* 16 bit literal entry */
++#define R_MIPS_GOT16          9       /* 16 bit GOT entry */
++#define R_MIPS_PC16           10      /* PC relative 16 bit */
++#define R_MIPS_CALL16         11      /* 16 bit GOT entry for function */
++#define R_MIPS_GPREL32                12      /* GP relative 32 bit */
++
++#define R_MIPS_SHIFT5         16
++#define R_MIPS_SHIFT6         17
++#define R_MIPS_64             18
++#define R_MIPS_GOT_DISP               19
++#define R_MIPS_GOT_PAGE               20
++#define R_MIPS_GOT_OFST               21
++#define R_MIPS_GOT_HI16               22
++#define R_MIPS_GOT_LO16               23
++#define R_MIPS_SUB            24
++#define R_MIPS_INSERT_A               25
++#define R_MIPS_INSERT_B               26
++#define R_MIPS_DELETE         27
++#define R_MIPS_HIGHER         28
++#define R_MIPS_HIGHEST                29
++#define R_MIPS_CALL_HI16      30
++#define R_MIPS_CALL_LO16      31
++#define R_MIPS_SCN_DISP               32
++#define R_MIPS_REL16          33
++#define R_MIPS_ADD_IMMEDIATE  34
++#define R_MIPS_PJUMP          35
++#define R_MIPS_RELGOT         36
++#define R_MIPS_JALR           37
++#define R_MIPS_TLS_DTPMOD32   38      /* Module number 32 bit */
++#define R_MIPS_TLS_DTPREL32   39      /* Module-relative offset 32 bit */
++#define R_MIPS_TLS_DTPMOD64   40      /* Module number 64 bit */
++#define R_MIPS_TLS_DTPREL64   41      /* Module-relative offset 64 bit */
++#define R_MIPS_TLS_GD         42      /* 16 bit GOT offset for GD */
++#define R_MIPS_TLS_LDM                43      /* 16 bit GOT offset for LDM */
++#define R_MIPS_TLS_DTPREL_HI16        44      /* Module-relative offset, high 16 bits */
++#define R_MIPS_TLS_DTPREL_LO16        45      /* Module-relative offset, low 16 bits */
++#define R_MIPS_TLS_GOTTPREL   46      /* 16 bit GOT offset for IE */
++#define R_MIPS_TLS_TPREL32    47      /* TP-relative offset, 32 bit */
++#define R_MIPS_TLS_TPREL64    48      /* TP-relative offset, 64 bit */
++#define R_MIPS_TLS_TPREL_HI16 49      /* TP-relative offset, high 16 bits */
++#define R_MIPS_TLS_TPREL_LO16 50      /* TP-relative offset, low 16 bits */
++/* Keep this the last entry.  */
++#define R_MIPS_NUM            51
++
++/* Legal values for p_type field of Elf32_Phdr.  */
++
++#define PT_MIPS_REGINFO       0x70000000      /* Register usage information */
++#define PT_MIPS_RTPROC  0x70000001    /* Runtime procedure table. */
++#define PT_MIPS_OPTIONS 0x70000002
++
++/* Special program header types.  */
++
++#define PF_MIPS_LOCAL 0x10000000
++
++/* Legal values for d_tag field of Elf32_Dyn.  */
++
++#define DT_MIPS_RLD_VERSION  0x70000001       /* Runtime linker interface version */
++#define DT_MIPS_TIME_STAMP   0x70000002       /* Timestamp */
++#define DT_MIPS_ICHECKSUM    0x70000003       /* Checksum */
++#define DT_MIPS_IVERSION     0x70000004       /* Version string (string tbl index) */
++#define DT_MIPS_FLAGS      0x70000005 /* Flags */
++#define DT_MIPS_BASE_ADDRESS 0x70000006       /* Base address */
++#define DT_MIPS_MSYM       0x70000007
++#define DT_MIPS_CONFLICT     0x70000008       /* Address of CONFLICT section */
++#define DT_MIPS_LIBLIST            0x70000009 /* Address of LIBLIST section */
++#define DT_MIPS_LOCAL_GOTNO  0x7000000a       /* Number of local GOT entries */
++#define DT_MIPS_CONFLICTNO   0x7000000b       /* Number of CONFLICT entries */
++#define DT_MIPS_LIBLISTNO    0x70000010       /* Number of LIBLIST entries */
++#define DT_MIPS_SYMTABNO     0x70000011       /* Number of DYNSYM entries */
++#define DT_MIPS_UNREFEXTNO   0x70000012       /* First external DYNSYM */
++#define DT_MIPS_GOTSYM             0x70000013 /* First GOT entry in DYNSYM */
++#define DT_MIPS_HIPAGENO     0x70000014       /* Number of GOT page table entries */
++#define DT_MIPS_RLD_MAP            0x70000016 /* Address of run time loader map.  */
++#define DT_MIPS_DELTA_CLASS  0x70000017       /* Delta C++ class definition.  */
++#define DT_MIPS_DELTA_CLASS_NO    0x70000018 /* Number of entries in
++                                              DT_MIPS_DELTA_CLASS.  */
++#define DT_MIPS_DELTA_INSTANCE    0x70000019 /* Delta C++ class instances.  */
++#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a /* Number of entries in
++                                              DT_MIPS_DELTA_INSTANCE.  */
++#define DT_MIPS_DELTA_RELOC  0x7000001b /* Delta relocations.  */
++#define DT_MIPS_DELTA_RELOC_NO 0x7000001c /* Number of entries in
++                                           DT_MIPS_DELTA_RELOC.  */
++#define DT_MIPS_DELTA_SYM    0x7000001d /* Delta symbols that Delta
++                                         relocations refer to.  */
++#define DT_MIPS_DELTA_SYM_NO 0x7000001e /* Number of entries in
++                                         DT_MIPS_DELTA_SYM.  */
++#define DT_MIPS_DELTA_CLASSSYM 0x70000020 /* Delta symbols that hold the
++                                           class declaration.  */
++#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 /* Number of entries in
++                                              DT_MIPS_DELTA_CLASSSYM.  */
++#define DT_MIPS_CXX_FLAGS    0x70000022 /* Flags indicating for C++ flavor.  */
++#define DT_MIPS_PIXIE_INIT   0x70000023
++#define DT_MIPS_SYMBOL_LIB   0x70000024
++#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025
++#define DT_MIPS_LOCAL_GOTIDX 0x70000026
++#define DT_MIPS_HIDDEN_GOTIDX 0x70000027
++#define DT_MIPS_PROTECTED_GOTIDX 0x70000028
++#define DT_MIPS_OPTIONS            0x70000029 /* Address of .options.  */
++#define DT_MIPS_INTERFACE    0x7000002a /* Address of .interface.  */
++#define DT_MIPS_DYNSTR_ALIGN 0x7000002b
++#define DT_MIPS_INTERFACE_SIZE 0x7000002c /* Size of the .interface section. */
++#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d /* Address of rld_text_rsolve
++                                                  function stored in GOT.  */
++#define DT_MIPS_PERF_SUFFIX  0x7000002e /* Default suffix of dso to be added
++                                         by rld on dlopen() calls.  */
++#define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */
++#define DT_MIPS_GP_VALUE     0x70000030 /* GP value for aux GOTs.  */
++#define DT_MIPS_AUX_DYNAMIC  0x70000031 /* Address of aux .dynamic.  */
++#define DT_MIPS_NUM        0x32
++
++/* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry.  */
++
++#define RHF_NONE                 0            /* No flags */
++#define RHF_QUICKSTART                   (1 << 0)     /* Use quickstart */
++#define RHF_NOTPOT               (1 << 1)     /* Hash size not power of 2 */
++#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2)   /* Ignore LD_LIBRARY_PATH */
++#define RHF_NO_MOVE              (1 << 3)
++#define RHF_SGI_ONLY             (1 << 4)
++#define RHF_GUARANTEE_INIT       (1 << 5)
++#define RHF_DELTA_C_PLUS_PLUS    (1 << 6)
++#define RHF_GUARANTEE_START_INIT   (1 << 7)
++#define RHF_PIXIE                (1 << 8)
++#define RHF_DEFAULT_DELAY_LOAD           (1 << 9)
++#define RHF_REQUICKSTART         (1 << 10)
++#define RHF_REQUICKSTARTED       (1 << 11)
++#define RHF_CORD                 (1 << 12)
++#define RHF_NO_UNRES_UNDEF       (1 << 13)
++#define RHF_RLD_ORDER_SAFE       (1 << 14)
++
++/* Entries found in sections of type SHT_MIPS_LIBLIST.  */
++
++typedef struct
++{
++  Elf32_Word l_name;          /* Name (string table index) */
++  Elf32_Word l_time_stamp;    /* Timestamp */
++  Elf32_Word l_checksum;      /* Checksum */
++  Elf32_Word l_version;               /* Interface version */
++  Elf32_Word l_flags;         /* Flags */
++} Elf32_Lib;
++
++typedef struct
++{
++  Elf64_Word l_name;          /* Name (string table index) */
++  Elf64_Word l_time_stamp;    /* Timestamp */
++  Elf64_Word l_checksum;      /* Checksum */
++  Elf64_Word l_version;               /* Interface version */
++  Elf64_Word l_flags;         /* Flags */
++} Elf64_Lib;
++
++
++/* Legal values for l_flags.  */
++
++#define LL_NONE                 0
++#define LL_EXACT_MATCH          (1 << 0)      /* Require exact match */
++#define LL_IGNORE_INT_VER (1 << 1)    /* Ignore interface version */
++#define LL_REQUIRE_MINOR  (1 << 2)
++#define LL_EXPORTS      (1 << 3)
++#define LL_DELAY_LOAD   (1 << 4)
++#define LL_DELTA        (1 << 5)
++
++/* Entries found in sections of type SHT_MIPS_CONFLICT.  */
++
++typedef Elf32_Addr Elf32_Conflict;
++
++
++/* HPPA specific definitions.  */
++
++/* Legal values for e_flags field of Elf32_Ehdr.  */
++
++#define EF_PARISC_TRAPNIL     0x00010000 /* Trap nil pointer dereference.  */
++#define EF_PARISC_EXT         0x00020000 /* Program uses arch. extensions. */
++#define EF_PARISC_LSB         0x00040000 /* Program expects little endian. */
++#define EF_PARISC_WIDE                0x00080000 /* Program expects wide mode.  */
++#define EF_PARISC_NO_KABP     0x00100000 /* No kernel assisted branch
++                                            prediction.  */
++#define EF_PARISC_LAZYSWAP    0x00400000 /* Allow lazy swapping.  */
++#define EF_PARISC_ARCH                0x0000ffff /* Architecture version.  */
++
++/* Defined values for `e_flags & EF_PARISC_ARCH' are:  */
++
++#define EFA_PARISC_1_0                    0x020b /* PA-RISC 1.0 big-endian.  */
++#define EFA_PARISC_1_1                    0x0210 /* PA-RISC 1.1 big-endian.  */
++#define EFA_PARISC_2_0                    0x0214 /* PA-RISC 2.0 big-endian.  */
++
++/* Additional section indeces.  */
++
++#define SHN_PARISC_ANSI_COMMON        0xff00     /* Section for tenatively declared
++                                            symbols in ANSI C.  */
++#define SHN_PARISC_HUGE_COMMON        0xff01     /* Common blocks in huge model.  */
++
++/* Legal values for sh_type field of Elf32_Shdr.  */
++
++#define SHT_PARISC_EXT                0x70000000 /* Contains product specific ext. */
++#define SHT_PARISC_UNWIND     0x70000001 /* Unwind information.  */
++#define SHT_PARISC_DOC                0x70000002 /* Debug info for optimized code. */
++
++/* Legal values for sh_flags field of Elf32_Shdr.  */
++
++#define SHF_PARISC_SHORT      0x20000000 /* Section with short addressing. */
++#define SHF_PARISC_HUGE               0x40000000 /* Section far from gp.  */
++#define SHF_PARISC_SBP                0x80000000 /* Static branch prediction code. */
++
++/* Legal values for ST_TYPE subfield of st_info (symbol type).  */
++
++#define STT_PARISC_MILLICODE  13      /* Millicode function entry point.  */
++
++#define STT_HP_OPAQUE         (STT_LOOS + 0x1)
++#define STT_HP_STUB           (STT_LOOS + 0x2)
++
++/* HPPA relocs.  */
++
++#define R_PARISC_NONE         0       /* No reloc.  */
++#define R_PARISC_DIR32                1       /* Direct 32-bit reference.  */
++#define R_PARISC_DIR21L               2       /* Left 21 bits of eff. address.  */
++#define R_PARISC_DIR17R               3       /* Right 17 bits of eff. address.  */
++#define R_PARISC_DIR17F               4       /* 17 bits of eff. address.  */
++#define R_PARISC_DIR14R               6       /* Right 14 bits of eff. address.  */
++#define R_PARISC_PCREL32      9       /* 32-bit rel. address.  */
++#define R_PARISC_PCREL21L     10      /* Left 21 bits of rel. address.  */
++#define R_PARISC_PCREL17R     11      /* Right 17 bits of rel. address.  */
++#define R_PARISC_PCREL17F     12      /* 17 bits of rel. address.  */
++#define R_PARISC_PCREL14R     14      /* Right 14 bits of rel. address.  */
++#define R_PARISC_DPREL21L     18      /* Left 21 bits of rel. address.  */
++#define R_PARISC_DPREL14R     22      /* Right 14 bits of rel. address.  */
++#define R_PARISC_GPREL21L     26      /* GP-relative, left 21 bits.  */
++#define R_PARISC_GPREL14R     30      /* GP-relative, right 14 bits.  */
++#define R_PARISC_LTOFF21L     34      /* LT-relative, left 21 bits.  */
++#define R_PARISC_LTOFF14R     38      /* LT-relative, right 14 bits.  */
++#define R_PARISC_SECREL32     41      /* 32 bits section rel. address.  */
++#define R_PARISC_SEGBASE      48      /* No relocation, set segment base.  */
++#define R_PARISC_SEGREL32     49      /* 32 bits segment rel. address.  */
++#define R_PARISC_PLTOFF21L    50      /* PLT rel. address, left 21 bits.  */
++#define R_PARISC_PLTOFF14R    54      /* PLT rel. address, right 14 bits.  */
++#define R_PARISC_LTOFF_FPTR32 57      /* 32 bits LT-rel. function pointer. */
++#define R_PARISC_LTOFF_FPTR21L        58      /* LT-rel. fct ptr, left 21 bits. */
++#define R_PARISC_LTOFF_FPTR14R        62      /* LT-rel. fct ptr, right 14 bits. */
++#define R_PARISC_FPTR64               64      /* 64 bits function address.  */
++#define R_PARISC_PLABEL32     65      /* 32 bits function address.  */
++#define R_PARISC_PCREL64      72      /* 64 bits PC-rel. address.  */
++#define R_PARISC_PCREL22F     74      /* 22 bits PC-rel. address.  */
++#define R_PARISC_PCREL14WR    75      /* PC-rel. address, right 14 bits.  */
++#define R_PARISC_PCREL14DR    76      /* PC rel. address, right 14 bits.  */
++#define R_PARISC_PCREL16F     77      /* 16 bits PC-rel. address.  */
++#define R_PARISC_PCREL16WF    78      /* 16 bits PC-rel. address.  */
++#define R_PARISC_PCREL16DF    79      /* 16 bits PC-rel. address.  */
++#define R_PARISC_DIR64                80      /* 64 bits of eff. address.  */
++#define R_PARISC_DIR14WR      83      /* 14 bits of eff. address.  */
++#define R_PARISC_DIR14DR      84      /* 14 bits of eff. address.  */
++#define R_PARISC_DIR16F               85      /* 16 bits of eff. address.  */
++#define R_PARISC_DIR16WF      86      /* 16 bits of eff. address.  */
++#define R_PARISC_DIR16DF      87      /* 16 bits of eff. address.  */
++#define R_PARISC_GPREL64      88      /* 64 bits of GP-rel. address.  */
++#define R_PARISC_GPREL14WR    91      /* GP-rel. address, right 14 bits.  */
++#define R_PARISC_GPREL14DR    92      /* GP-rel. address, right 14 bits.  */
++#define R_PARISC_GPREL16F     93      /* 16 bits GP-rel. address.  */
++#define R_PARISC_GPREL16WF    94      /* 16 bits GP-rel. address.  */
++#define R_PARISC_GPREL16DF    95      /* 16 bits GP-rel. address.  */
++#define R_PARISC_LTOFF64      96      /* 64 bits LT-rel. address.  */
++#define R_PARISC_LTOFF14WR    99      /* LT-rel. address, right 14 bits.  */
++#define R_PARISC_LTOFF14DR    100     /* LT-rel. address, right 14 bits.  */
++#define R_PARISC_LTOFF16F     101     /* 16 bits LT-rel. address.  */
++#define R_PARISC_LTOFF16WF    102     /* 16 bits LT-rel. address.  */
++#define R_PARISC_LTOFF16DF    103     /* 16 bits LT-rel. address.  */
++#define R_PARISC_SECREL64     104     /* 64 bits section rel. address.  */
++#define R_PARISC_SEGREL64     112     /* 64 bits segment rel. address.  */
++#define R_PARISC_PLTOFF14WR   115     /* PLT-rel. address, right 14 bits.  */
++#define R_PARISC_PLTOFF14DR   116     /* PLT-rel. address, right 14 bits.  */
++#define R_PARISC_PLTOFF16F    117     /* 16 bits LT-rel. address.  */
++#define R_PARISC_PLTOFF16WF   118     /* 16 bits PLT-rel. address.  */
++#define R_PARISC_PLTOFF16DF   119     /* 16 bits PLT-rel. address.  */
++#define R_PARISC_LTOFF_FPTR64 120     /* 64 bits LT-rel. function ptr.  */
++#define R_PARISC_LTOFF_FPTR14WR       123     /* LT-rel. fct. ptr., right 14 bits. */
++#define R_PARISC_LTOFF_FPTR14DR       124     /* LT-rel. fct. ptr., right 14 bits. */
++#define R_PARISC_LTOFF_FPTR16F        125     /* 16 bits LT-rel. function ptr.  */
++#define R_PARISC_LTOFF_FPTR16WF       126     /* 16 bits LT-rel. function ptr.  */
++#define R_PARISC_LTOFF_FPTR16DF       127     /* 16 bits LT-rel. function ptr.  */
++#define R_PARISC_LORESERVE    128
++#define R_PARISC_COPY         128     /* Copy relocation.  */
++#define R_PARISC_IPLT         129     /* Dynamic reloc, imported PLT */
++#define R_PARISC_EPLT         130     /* Dynamic reloc, exported PLT */
++#define R_PARISC_TPREL32      153     /* 32 bits TP-rel. address.  */
++#define R_PARISC_TPREL21L     154     /* TP-rel. address, left 21 bits.  */
++#define R_PARISC_TPREL14R     158     /* TP-rel. address, right 14 bits.  */
++#define R_PARISC_LTOFF_TP21L  162     /* LT-TP-rel. address, left 21 bits. */
++#define R_PARISC_LTOFF_TP14R  166     /* LT-TP-rel. address, right 14 bits.*/
++#define R_PARISC_LTOFF_TP14F  167     /* 14 bits LT-TP-rel. address.  */
++#define R_PARISC_TPREL64      216     /* 64 bits TP-rel. address.  */
++#define R_PARISC_TPREL14WR    219     /* TP-rel. address, right 14 bits.  */
++#define R_PARISC_TPREL14DR    220     /* TP-rel. address, right 14 bits.  */
++#define R_PARISC_TPREL16F     221     /* 16 bits TP-rel. address.  */
++#define R_PARISC_TPREL16WF    222     /* 16 bits TP-rel. address.  */
++#define R_PARISC_TPREL16DF    223     /* 16 bits TP-rel. address.  */
++#define R_PARISC_LTOFF_TP64   224     /* 64 bits LT-TP-rel. address.  */
++#define R_PARISC_LTOFF_TP14WR 227     /* LT-TP-rel. address, right 14 bits.*/
++#define R_PARISC_LTOFF_TP14DR 228     /* LT-TP-rel. address, right 14 bits.*/
++#define R_PARISC_LTOFF_TP16F  229     /* 16 bits LT-TP-rel. address.  */
++#define R_PARISC_LTOFF_TP16WF 230     /* 16 bits LT-TP-rel. address.  */
++#define R_PARISC_LTOFF_TP16DF 231     /* 16 bits LT-TP-rel. address.  */
++#define R_PARISC_HIRESERVE    255
++
++/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr.  */
++
++#define PT_HP_TLS             (PT_LOOS + 0x0)
++#define PT_HP_CORE_NONE               (PT_LOOS + 0x1)
++#define PT_HP_CORE_VERSION    (PT_LOOS + 0x2)
++#define PT_HP_CORE_KERNEL     (PT_LOOS + 0x3)
++#define PT_HP_CORE_COMM               (PT_LOOS + 0x4)
++#define PT_HP_CORE_PROC               (PT_LOOS + 0x5)
++#define PT_HP_CORE_LOADABLE   (PT_LOOS + 0x6)
++#define PT_HP_CORE_STACK      (PT_LOOS + 0x7)
++#define PT_HP_CORE_SHM                (PT_LOOS + 0x8)
++#define PT_HP_CORE_MMF                (PT_LOOS + 0x9)
++#define PT_HP_PARALLEL                (PT_LOOS + 0x10)
++#define PT_HP_FASTBIND                (PT_LOOS + 0x11)
++#define PT_HP_OPT_ANNOT               (PT_LOOS + 0x12)
++#define PT_HP_HSL_ANNOT               (PT_LOOS + 0x13)
++#define PT_HP_STACK           (PT_LOOS + 0x14)
++
++#define PT_PARISC_ARCHEXT     0x70000000
++#define PT_PARISC_UNWIND      0x70000001
++
++/* Legal values for p_flags field of Elf32_Phdr/Elf64_Phdr.  */
++
++#define PF_PARISC_SBP         0x08000000
++
++#define PF_HP_PAGE_SIZE               0x00100000
++#define PF_HP_FAR_SHARED      0x00200000
++#define PF_HP_NEAR_SHARED     0x00400000
++#define PF_HP_CODE            0x01000000
++#define PF_HP_MODIFY          0x02000000
++#define PF_HP_LAZYSWAP                0x04000000
++#define PF_HP_SBP             0x08000000
++
++
++/* Alpha specific definitions.  */
++
++/* Legal values for e_flags field of Elf64_Ehdr.  */
++
++#define EF_ALPHA_32BIT                1       /* All addresses must be < 2GB.  */
++#define EF_ALPHA_CANRELAX     2       /* Relocations for relaxing exist.  */
++
++/* Legal values for sh_type field of Elf64_Shdr.  */
++
++/* These two are primerily concerned with ECOFF debugging info.  */
++#define SHT_ALPHA_DEBUG               0x70000001
++#define SHT_ALPHA_REGINFO     0x70000002
++
++/* Legal values for sh_flags field of Elf64_Shdr.  */
++
++#define SHF_ALPHA_GPREL               0x10000000
++
++/* Legal values for st_other field of Elf64_Sym.  */
++#define STO_ALPHA_NOPV                0x80    /* No PV required.  */
++#define STO_ALPHA_STD_GPLOAD  0x88    /* PV only used for initial ldgp.  */
++
++/* Alpha relocs.  */
++
++#define R_ALPHA_NONE          0       /* No reloc */
++#define R_ALPHA_REFLONG               1       /* Direct 32 bit */
++#define R_ALPHA_REFQUAD               2       /* Direct 64 bit */
++#define R_ALPHA_GPREL32               3       /* GP relative 32 bit */
++#define R_ALPHA_LITERAL               4       /* GP relative 16 bit w/optimization */
++#define R_ALPHA_LITUSE                5       /* Optimization hint for LITERAL */
++#define R_ALPHA_GPDISP                6       /* Add displacement to GP */
++#define R_ALPHA_BRADDR                7       /* PC+4 relative 23 bit shifted */
++#define R_ALPHA_HINT          8       /* PC+4 relative 16 bit shifted */
++#define R_ALPHA_SREL16                9       /* PC relative 16 bit */
++#define R_ALPHA_SREL32                10      /* PC relative 32 bit */
++#define R_ALPHA_SREL64                11      /* PC relative 64 bit */
++#define R_ALPHA_GPRELHIGH     17      /* GP relative 32 bit, high 16 bits */
++#define R_ALPHA_GPRELLOW      18      /* GP relative 32 bit, low 16 bits */
++#define R_ALPHA_GPREL16               19      /* GP relative 16 bit */
++#define R_ALPHA_COPY          24      /* Copy symbol at runtime */
++#define R_ALPHA_GLOB_DAT      25      /* Create GOT entry */
++#define R_ALPHA_JMP_SLOT      26      /* Create PLT entry */
++#define R_ALPHA_RELATIVE      27      /* Adjust by program base */
++#define R_ALPHA_TLS_GD_HI     28
++#define R_ALPHA_TLSGD         29
++#define R_ALPHA_TLS_LDM               30
++#define R_ALPHA_DTPMOD64      31
++#define R_ALPHA_GOTDTPREL     32
++#define R_ALPHA_DTPREL64      33
++#define R_ALPHA_DTPRELHI      34
++#define R_ALPHA_DTPRELLO      35
++#define R_ALPHA_DTPREL16      36
++#define R_ALPHA_GOTTPREL      37
++#define R_ALPHA_TPREL64               38
++#define R_ALPHA_TPRELHI               39
++#define R_ALPHA_TPRELLO               40
++#define R_ALPHA_TPREL16               41
++/* Keep this the last entry.  */
++#define R_ALPHA_NUM           46
++
++/* Magic values of the LITUSE relocation addend.  */
++#define LITUSE_ALPHA_ADDR     0
++#define LITUSE_ALPHA_BASE     1
++#define LITUSE_ALPHA_BYTOFF   2
++#define LITUSE_ALPHA_JSR      3
++#define LITUSE_ALPHA_TLS_GD   4
++#define LITUSE_ALPHA_TLS_LDM  5
++
++/* Legal values for d_tag of Elf64_Dyn.  */
++#define DT_ALPHA_PLTRO                (DT_LOPROC + 0)
++#define DT_ALPHA_NUM          1
++
++/* PowerPC specific declarations */
++
++/* Values for Elf32/64_Ehdr.e_flags.  */
++#define EF_PPC_EMB            0x80000000      /* PowerPC embedded flag */
++
++/* Cygnus local bits below */
++#define EF_PPC_RELOCATABLE    0x00010000      /* PowerPC -mrelocatable flag*/
++#define EF_PPC_RELOCATABLE_LIB        0x00008000      /* PowerPC -mrelocatable-lib
++                                                 flag */
++
++/* PowerPC relocations defined by the ABIs */
++#define R_PPC_NONE            0
++#define R_PPC_ADDR32          1       /* 32bit absolute address */
++#define R_PPC_ADDR24          2       /* 26bit address, 2 bits ignored.  */
++#define R_PPC_ADDR16          3       /* 16bit absolute address */
++#define R_PPC_ADDR16_LO               4       /* lower 16bit of absolute address */
++#define R_PPC_ADDR16_HI               5       /* high 16bit of absolute address */
++#define R_PPC_ADDR16_HA               6       /* adjusted high 16bit */
++#define R_PPC_ADDR14          7       /* 16bit address, 2 bits ignored */
++#define R_PPC_ADDR14_BRTAKEN  8
++#define R_PPC_ADDR14_BRNTAKEN 9
++#define R_PPC_REL24           10      /* PC relative 26 bit */
++#define R_PPC_REL14           11      /* PC relative 16 bit */
++#define R_PPC_REL14_BRTAKEN   12
++#define R_PPC_REL14_BRNTAKEN  13
++#define R_PPC_GOT16           14
++#define R_PPC_GOT16_LO                15
++#define R_PPC_GOT16_HI                16
++#define R_PPC_GOT16_HA                17
++#define R_PPC_PLTREL24                18
++#define R_PPC_COPY            19
++#define R_PPC_GLOB_DAT                20
++#define R_PPC_JMP_SLOT                21
++#define R_PPC_RELATIVE                22
++#define R_PPC_LOCAL24PC               23
++#define R_PPC_UADDR32         24
++#define R_PPC_UADDR16         25
++#define R_PPC_REL32           26
++#define R_PPC_PLT32           27
++#define R_PPC_PLTREL32                28
++#define R_PPC_PLT16_LO                29
++#define R_PPC_PLT16_HI                30
++#define R_PPC_PLT16_HA                31
++#define R_PPC_SDAREL16                32
++#define R_PPC_SECTOFF         33
++#define R_PPC_SECTOFF_LO      34
++#define R_PPC_SECTOFF_HI      35
++#define R_PPC_SECTOFF_HA      36
++
++/* PowerPC relocations defined for the TLS access ABI.  */
++#define R_PPC_TLS             67 /* none      (sym+add)@tls */
++#define R_PPC_DTPMOD32                68 /* word32    (sym+add)@dtpmod */
++#define R_PPC_TPREL16         69 /* half16*   (sym+add)@tprel */
++#define R_PPC_TPREL16_LO      70 /* half16    (sym+add)@tprel@l */
++#define R_PPC_TPREL16_HI      71 /* half16    (sym+add)@tprel@h */
++#define R_PPC_TPREL16_HA      72 /* half16    (sym+add)@tprel@ha */
++#define R_PPC_TPREL32         73 /* word32    (sym+add)@tprel */
++#define R_PPC_DTPREL16                74 /* half16*   (sym+add)@dtprel */
++#define R_PPC_DTPREL16_LO     75 /* half16    (sym+add)@dtprel@l */
++#define R_PPC_DTPREL16_HI     76 /* half16    (sym+add)@dtprel@h */
++#define R_PPC_DTPREL16_HA     77 /* half16    (sym+add)@dtprel@ha */
++#define R_PPC_DTPREL32                78 /* word32    (sym+add)@dtprel */
++#define R_PPC_GOT_TLSGD16     79 /* half16*   (sym+add)@got@tlsgd */
++#define R_PPC_GOT_TLSGD16_LO  80 /* half16    (sym+add)@got@tlsgd@l */
++#define R_PPC_GOT_TLSGD16_HI  81 /* half16    (sym+add)@got@tlsgd@h */
++#define R_PPC_GOT_TLSGD16_HA  82 /* half16    (sym+add)@got@tlsgd@ha */
++#define R_PPC_GOT_TLSLD16     83 /* half16*   (sym+add)@got@tlsld */
++#define R_PPC_GOT_TLSLD16_LO  84 /* half16    (sym+add)@got@tlsld@l */
++#define R_PPC_GOT_TLSLD16_HI  85 /* half16    (sym+add)@got@tlsld@h */
++#define R_PPC_GOT_TLSLD16_HA  86 /* half16    (sym+add)@got@tlsld@ha */
++#define R_PPC_GOT_TPREL16     87 /* half16*   (sym+add)@got@tprel */
++#define R_PPC_GOT_TPREL16_LO  88 /* half16    (sym+add)@got@tprel@l */
++#define R_PPC_GOT_TPREL16_HI  89 /* half16    (sym+add)@got@tprel@h */
++#define R_PPC_GOT_TPREL16_HA  90 /* half16    (sym+add)@got@tprel@ha */
++#define R_PPC_GOT_DTPREL16    91 /* half16*   (sym+add)@got@dtprel */
++#define R_PPC_GOT_DTPREL16_LO 92 /* half16*   (sym+add)@got@dtprel@l */
++#define R_PPC_GOT_DTPREL16_HI 93 /* half16*   (sym+add)@got@dtprel@h */
++#define R_PPC_GOT_DTPREL16_HA 94 /* half16*   (sym+add)@got@dtprel@ha */
++
++/* Keep this the last entry.  */
++#define R_PPC_NUM             95
++
++/* The remaining relocs are from the Embedded ELF ABI, and are not
++   in the SVR4 ELF ABI.  */
++#define R_PPC_EMB_NADDR32     101
++#define R_PPC_EMB_NADDR16     102
++#define R_PPC_EMB_NADDR16_LO  103
++#define R_PPC_EMB_NADDR16_HI  104
++#define R_PPC_EMB_NADDR16_HA  105
++#define R_PPC_EMB_SDAI16      106
++#define R_PPC_EMB_SDA2I16     107
++#define R_PPC_EMB_SDA2REL     108
++#define R_PPC_EMB_SDA21               109     /* 16 bit offset in SDA */
++#define R_PPC_EMB_MRKREF      110
++#define R_PPC_EMB_RELSEC16    111
++#define R_PPC_EMB_RELST_LO    112
++#define R_PPC_EMB_RELST_HI    113
++#define R_PPC_EMB_RELST_HA    114
++#define R_PPC_EMB_BIT_FLD     115
++#define R_PPC_EMB_RELSDA      116     /* 16 bit relative offset in SDA */
++
++/* Diab tool relocations.  */
++#define R_PPC_DIAB_SDA21_LO   180     /* like EMB_SDA21, but lower 16 bit */
++#define R_PPC_DIAB_SDA21_HI   181     /* like EMB_SDA21, but high 16 bit */
++#define R_PPC_DIAB_SDA21_HA   182     /* like EMB_SDA21, adjusted high 16 */
++#define R_PPC_DIAB_RELSDA_LO  183     /* like EMB_RELSDA, but lower 16 bit */
++#define R_PPC_DIAB_RELSDA_HI  184     /* like EMB_RELSDA, but high 16 bit */
++#define R_PPC_DIAB_RELSDA_HA  185     /* like EMB_RELSDA, adjusted high 16 */
++
++/* GNU relocs used in PIC code sequences.  */
++#define R_PPC_REL16           249     /* word32   (sym-.) */
++#define R_PPC_REL16_LO                250     /* half16   (sym-.)@l */
++#define R_PPC_REL16_HI                251     /* half16   (sym-.)@h */
++#define R_PPC_REL16_HA                252     /* half16   (sym-.)@ha */
++
++/* This is a phony reloc to handle any old fashioned TOC16 references
++   that may still be in object files.  */
++#define R_PPC_TOC16           255
++
++/* PowerPC specific values for the Dyn d_tag field.  */
++#define DT_PPC_GOT            (DT_LOPROC + 0)
++#define DT_PPC_NUM            1
++
++/* PowerPC64 relocations defined by the ABIs */
++#define R_PPC64_NONE          R_PPC_NONE
++#define R_PPC64_ADDR32                R_PPC_ADDR32 /* 32bit absolute address */
++#define R_PPC64_ADDR24                R_PPC_ADDR24 /* 26bit address, word aligned */
++#define R_PPC64_ADDR16                R_PPC_ADDR16 /* 16bit absolute address */
++#define R_PPC64_ADDR16_LO     R_PPC_ADDR16_LO /* lower 16bits of address */
++#define R_PPC64_ADDR16_HI     R_PPC_ADDR16_HI /* high 16bits of address. */
++#define R_PPC64_ADDR16_HA     R_PPC_ADDR16_HA /* adjusted high 16bits.  */
++#define R_PPC64_ADDR14                R_PPC_ADDR14 /* 16bit address, word aligned */
++#define R_PPC64_ADDR14_BRTAKEN        R_PPC_ADDR14_BRTAKEN
++#define R_PPC64_ADDR14_BRNTAKEN       R_PPC_ADDR14_BRNTAKEN
++#define R_PPC64_REL24         R_PPC_REL24 /* PC-rel. 26 bit, word aligned */
++#define R_PPC64_REL14         R_PPC_REL14 /* PC relative 16 bit */
++#define R_PPC64_REL14_BRTAKEN R_PPC_REL14_BRTAKEN
++#define R_PPC64_REL14_BRNTAKEN        R_PPC_REL14_BRNTAKEN
++#define R_PPC64_GOT16         R_PPC_GOT16
++#define R_PPC64_GOT16_LO      R_PPC_GOT16_LO
++#define R_PPC64_GOT16_HI      R_PPC_GOT16_HI
++#define R_PPC64_GOT16_HA      R_PPC_GOT16_HA
++
++#define R_PPC64_COPY          R_PPC_COPY
++#define R_PPC64_GLOB_DAT      R_PPC_GLOB_DAT
++#define R_PPC64_JMP_SLOT      R_PPC_JMP_SLOT
++#define R_PPC64_RELATIVE      R_PPC_RELATIVE
++
++#define R_PPC64_UADDR32               R_PPC_UADDR32
++#define R_PPC64_UADDR16               R_PPC_UADDR16
++#define R_PPC64_REL32         R_PPC_REL32
++#define R_PPC64_PLT32         R_PPC_PLT32
++#define R_PPC64_PLTREL32      R_PPC_PLTREL32
++#define R_PPC64_PLT16_LO      R_PPC_PLT16_LO
++#define R_PPC64_PLT16_HI      R_PPC_PLT16_HI
++#define R_PPC64_PLT16_HA      R_PPC_PLT16_HA
++
++#define R_PPC64_SECTOFF               R_PPC_SECTOFF
++#define R_PPC64_SECTOFF_LO    R_PPC_SECTOFF_LO
++#define R_PPC64_SECTOFF_HI    R_PPC_SECTOFF_HI
++#define R_PPC64_SECTOFF_HA    R_PPC_SECTOFF_HA
++#define R_PPC64_ADDR30                37 /* word30 (S + A - P) >> 2 */
++#define R_PPC64_ADDR64                38 /* doubleword64 S + A */
++#define R_PPC64_ADDR16_HIGHER 39 /* half16 #higher(S + A) */
++#define R_PPC64_ADDR16_HIGHERA        40 /* half16 #highera(S + A) */
++#define R_PPC64_ADDR16_HIGHEST        41 /* half16 #highest(S + A) */
++#define R_PPC64_ADDR16_HIGHESTA       42 /* half16 #highesta(S + A) */
++#define R_PPC64_UADDR64               43 /* doubleword64 S + A */
++#define R_PPC64_REL64         44 /* doubleword64 S + A - P */
++#define R_PPC64_PLT64         45 /* doubleword64 L + A */
++#define R_PPC64_PLTREL64      46 /* doubleword64 L + A - P */
++#define R_PPC64_TOC16         47 /* half16* S + A - .TOC */
++#define R_PPC64_TOC16_LO      48 /* half16 #lo(S + A - .TOC.) */
++#define R_PPC64_TOC16_HI      49 /* half16 #hi(S + A - .TOC.) */
++#define R_PPC64_TOC16_HA      50 /* half16 #ha(S + A - .TOC.) */
++#define R_PPC64_TOC           51 /* doubleword64 .TOC */
++#define R_PPC64_PLTGOT16      52 /* half16* M + A */
++#define R_PPC64_PLTGOT16_LO   53 /* half16 #lo(M + A) */
++#define R_PPC64_PLTGOT16_HI   54 /* half16 #hi(M + A) */
++#define R_PPC64_PLTGOT16_HA   55 /* half16 #ha(M + A) */
++
++#define R_PPC64_ADDR16_DS     56 /* half16ds* (S + A) >> 2 */
++#define R_PPC64_ADDR16_LO_DS  57 /* half16ds  #lo(S + A) >> 2 */
++#define R_PPC64_GOT16_DS      58 /* half16ds* (G + A) >> 2 */
++#define R_PPC64_GOT16_LO_DS   59 /* half16ds  #lo(G + A) >> 2 */
++#define R_PPC64_PLT16_LO_DS   60 /* half16ds  #lo(L + A) >> 2 */
++#define R_PPC64_SECTOFF_DS    61 /* half16ds* (R + A) >> 2 */
++#define R_PPC64_SECTOFF_LO_DS 62 /* half16ds  #lo(R + A) >> 2 */
++#define R_PPC64_TOC16_DS      63 /* half16ds* (S + A - .TOC.) >> 2 */
++#define R_PPC64_TOC16_LO_DS   64 /* half16ds  #lo(S + A - .TOC.) >> 2 */
++#define R_PPC64_PLTGOT16_DS   65 /* half16ds* (M + A) >> 2 */
++#define R_PPC64_PLTGOT16_LO_DS        66 /* half16ds  #lo(M + A) >> 2 */
++
++/* PowerPC64 relocations defined for the TLS access ABI.  */
++#define R_PPC64_TLS           67 /* none      (sym+add)@tls */
++#define R_PPC64_DTPMOD64      68 /* doubleword64 (sym+add)@dtpmod */
++#define R_PPC64_TPREL16               69 /* half16*   (sym+add)@tprel */
++#define R_PPC64_TPREL16_LO    70 /* half16    (sym+add)@tprel@l */
++#define R_PPC64_TPREL16_HI    71 /* half16    (sym+add)@tprel@h */
++#define R_PPC64_TPREL16_HA    72 /* half16    (sym+add)@tprel@ha */
++#define R_PPC64_TPREL64               73 /* doubleword64 (sym+add)@tprel */
++#define R_PPC64_DTPREL16      74 /* half16*   (sym+add)@dtprel */
++#define R_PPC64_DTPREL16_LO   75 /* half16    (sym+add)@dtprel@l */
++#define R_PPC64_DTPREL16_HI   76 /* half16    (sym+add)@dtprel@h */
++#define R_PPC64_DTPREL16_HA   77 /* half16    (sym+add)@dtprel@ha */
++#define R_PPC64_DTPREL64      78 /* doubleword64 (sym+add)@dtprel */
++#define R_PPC64_GOT_TLSGD16   79 /* half16*   (sym+add)@got@tlsgd */
++#define R_PPC64_GOT_TLSGD16_LO        80 /* half16    (sym+add)@got@tlsgd@l */
++#define R_PPC64_GOT_TLSGD16_HI        81 /* half16    (sym+add)@got@tlsgd@h */
++#define R_PPC64_GOT_TLSGD16_HA        82 /* half16    (sym+add)@got@tlsgd@ha */
++#define R_PPC64_GOT_TLSLD16   83 /* half16*   (sym+add)@got@tlsld */
++#define R_PPC64_GOT_TLSLD16_LO        84 /* half16    (sym+add)@got@tlsld@l */
++#define R_PPC64_GOT_TLSLD16_HI        85 /* half16    (sym+add)@got@tlsld@h */
++#define R_PPC64_GOT_TLSLD16_HA        86 /* half16    (sym+add)@got@tlsld@ha */
++#define R_PPC64_GOT_TPREL16_DS        87 /* half16ds* (sym+add)@got@tprel */
++#define R_PPC64_GOT_TPREL16_LO_DS 88 /* half16ds (sym+add)@got@tprel@l */
++#define R_PPC64_GOT_TPREL16_HI        89 /* half16    (sym+add)@got@tprel@h */
++#define R_PPC64_GOT_TPREL16_HA        90 /* half16    (sym+add)@got@tprel@ha */
++#define R_PPC64_GOT_DTPREL16_DS       91 /* half16ds* (sym+add)@got@dtprel */
++#define R_PPC64_GOT_DTPREL16_LO_DS 92 /* half16ds (sym+add)@got@dtprel@l */
++#define R_PPC64_GOT_DTPREL16_HI       93 /* half16    (sym+add)@got@dtprel@h */
++#define R_PPC64_GOT_DTPREL16_HA       94 /* half16    (sym+add)@got@dtprel@ha */
++#define R_PPC64_TPREL16_DS    95 /* half16ds* (sym+add)@tprel */
++#define R_PPC64_TPREL16_LO_DS 96 /* half16ds  (sym+add)@tprel@l */
++#define R_PPC64_TPREL16_HIGHER        97 /* half16    (sym+add)@tprel@higher */
++#define R_PPC64_TPREL16_HIGHERA       98 /* half16    (sym+add)@tprel@highera */
++#define R_PPC64_TPREL16_HIGHEST       99 /* half16    (sym+add)@tprel@highest */
++#define R_PPC64_TPREL16_HIGHESTA 100 /* half16        (sym+add)@tprel@highesta */
++#define R_PPC64_DTPREL16_DS   101 /* half16ds* (sym+add)@dtprel */
++#define R_PPC64_DTPREL16_LO_DS        102 /* half16ds (sym+add)@dtprel@l */
++#define R_PPC64_DTPREL16_HIGHER       103 /* half16   (sym+add)@dtprel@higher */
++#define R_PPC64_DTPREL16_HIGHERA 104 /* half16        (sym+add)@dtprel@highera */
++#define R_PPC64_DTPREL16_HIGHEST 105 /* half16        (sym+add)@dtprel@highest */
++#define R_PPC64_DTPREL16_HIGHESTA 106 /* half16       (sym+add)@dtprel@highesta */
++
++/* Keep this the last entry.  */
++#define R_PPC64_NUM           107
++
++/* PowerPC64 specific values for the Dyn d_tag field.  */
++#define DT_PPC64_GLINK  (DT_LOPROC + 0)
++#define DT_PPC64_OPD  (DT_LOPROC + 1)
++#define DT_PPC64_OPDSZ        (DT_LOPROC + 2)
++#define DT_PPC64_NUM    3
++
++
++/* ARM specific declarations */
++
++/* Processor specific flags for the ELF header e_flags field.  */
++#define EF_ARM_RELEXEC     0x01
++#define EF_ARM_HASENTRY    0x02
++#define EF_ARM_INTERWORK   0x04
++#define EF_ARM_APCS_26     0x08
++#define EF_ARM_APCS_FLOAT  0x10
++#define EF_ARM_PIC         0x20
++#define EF_ARM_ALIGN8      0x40               /* 8-bit structure alignment is in use */
++#define EF_ARM_NEW_ABI     0x80
++#define EF_ARM_OLD_ABI     0x100
++
++/* Other constants defined in the ARM ELF spec. version B-01.  */
++/* NB. These conflict with values defined above.  */
++#define EF_ARM_SYMSARESORTED  0x04
++#define EF_ARM_DYNSYMSUSESEGIDX 0x08
++#define EF_ARM_MAPSYMSFIRST   0x10
++#define EF_ARM_EABIMASK               0XFF000000
++
++#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK)
++#define EF_ARM_EABI_UNKNOWN  0x00000000
++#define EF_ARM_EABI_VER1     0x01000000
++#define EF_ARM_EABI_VER2     0x02000000
++
++/* Additional symbol types for Thumb */
++#define STT_ARM_TFUNC      0xd
++
++/* ARM-specific values for sh_flags */
++#define SHF_ARM_ENTRYSECT  0x10000000   /* Section contains an entry point */
++#define SHF_ARM_COMDEF     0x80000000   /* Section may be multiply defined
++                                         in the input to a link step */
++
++/* ARM-specific program header flags */
++#define PF_ARM_SB          0x10000000   /* Segment contains the location
++                                         addressed by the static base */
++
++/* Processor specific values for the Phdr p_type field.  */
++#define PT_ARM_EXIDX  0x70000001      /* .ARM.exidx segment */
++
++/* ARM relocs.  */
++
++#define R_ARM_NONE            0       /* No reloc */
++#define R_ARM_PC24            1       /* PC relative 26 bit branch */
++#define R_ARM_ABS32           2       /* Direct 32 bit  */
++#define R_ARM_REL32           3       /* PC relative 32 bit */
++#define R_ARM_PC13            4
++#define R_ARM_ABS16           5       /* Direct 16 bit */
++#define R_ARM_ABS12           6       /* Direct 12 bit */
++#define R_ARM_THM_ABS5                7
++#define R_ARM_ABS8            8       /* Direct 8 bit */
++#define R_ARM_SBREL32         9
++#define R_ARM_THM_PC22                10
++#define R_ARM_THM_PC8         11
++#define R_ARM_AMP_VCALL9      12
++#define R_ARM_SWI24           13
++#define R_ARM_THM_SWI8                14
++#define R_ARM_XPC25           15
++#define R_ARM_THM_XPC22               16
++#define R_ARM_COPY            20      /* Copy symbol at runtime */
++#define R_ARM_GLOB_DAT                21      /* Create GOT entry */
++#define R_ARM_JUMP_SLOT               22      /* Create PLT entry */
++#define R_ARM_RELATIVE                23      /* Adjust by program base */
++#define R_ARM_GOTOFF          24      /* 32 bit offset to GOT */
++#define R_ARM_GOTPC           25      /* 32 bit PC relative offset to GOT */
++#define R_ARM_GOT32           26      /* 32 bit GOT entry */
++#define R_ARM_PLT32           27      /* 32 bit PLT address */
++#define R_ARM_ALU_PCREL_7_0   32
++#define R_ARM_ALU_PCREL_15_8  33
++#define R_ARM_ALU_PCREL_23_15 34
++#define R_ARM_LDR_SBREL_11_0  35
++#define R_ARM_ALU_SBREL_19_12 36
++#define R_ARM_ALU_SBREL_27_20 37
++#define R_ARM_GNU_VTENTRY     100
++#define R_ARM_GNU_VTINHERIT   101
++#define R_ARM_THM_PC11                102     /* thumb unconditional branch */
++#define R_ARM_THM_PC9         103     /* thumb conditional branch */
++#define R_ARM_RXPC25          249
++#define R_ARM_RSBREL32                250
++#define R_ARM_THM_RPC22               251
++#define R_ARM_RREL32          252
++#define R_ARM_RABS22          253
++#define R_ARM_RPC24           254
++#define R_ARM_RBASE           255
++/* Keep this the last entry.  */
++#define R_ARM_NUM             256
++
++/* IA-64 specific declarations.  */
++
++/* Processor specific flags for the Ehdr e_flags field.  */
++#define EF_IA_64_MASKOS               0x0000000f      /* os-specific flags */
++#define EF_IA_64_ABI64                0x00000010      /* 64-bit ABI */
++#define EF_IA_64_ARCH         0xff000000      /* arch. version mask */
++
++/* Processor specific values for the Phdr p_type field.  */
++#define PT_IA_64_ARCHEXT      (PT_LOPROC + 0) /* arch extension bits */
++#define PT_IA_64_UNWIND               (PT_LOPROC + 1) /* ia64 unwind bits */
++#define PT_IA_64_HP_OPT_ANOT  (PT_LOOS + 0x12)
++#define PT_IA_64_HP_HSL_ANOT  (PT_LOOS + 0x13)
++#define PT_IA_64_HP_STACK     (PT_LOOS + 0x14)
++
++/* Processor specific flags for the Phdr p_flags field.  */
++#define PF_IA_64_NORECOV      0x80000000      /* spec insns w/o recovery */
++
++/* Processor specific values for the Shdr sh_type field.  */
++#define SHT_IA_64_EXT         (SHT_LOPROC + 0) /* extension bits */
++#define SHT_IA_64_UNWIND      (SHT_LOPROC + 1) /* unwind bits */
++
++/* Processor specific flags for the Shdr sh_flags field.  */
++#define SHF_IA_64_SHORT               0x10000000      /* section near gp */
++#define SHF_IA_64_NORECOV     0x20000000      /* spec insns w/o recovery */
++
++/* Processor specific values for the Dyn d_tag field.  */
++#define DT_IA_64_PLT_RESERVE  (DT_LOPROC + 0)
++#define DT_IA_64_NUM          1
++
++/* IA-64 relocations.  */
++#define R_IA64_NONE           0x00    /* none */
++#define R_IA64_IMM14          0x21    /* symbol + addend, add imm14 */
++#define R_IA64_IMM22          0x22    /* symbol + addend, add imm22 */
++#define R_IA64_IMM64          0x23    /* symbol + addend, mov imm64 */
++#define R_IA64_DIR32MSB               0x24    /* symbol + addend, data4 MSB */
++#define R_IA64_DIR32LSB               0x25    /* symbol + addend, data4 LSB */
++#define R_IA64_DIR64MSB               0x26    /* symbol + addend, data8 MSB */
++#define R_IA64_DIR64LSB               0x27    /* symbol + addend, data8 LSB */
++#define R_IA64_GPREL22                0x2a    /* @gprel(sym + add), add imm22 */
++#define R_IA64_GPREL64I               0x2b    /* @gprel(sym + add), mov imm64 */
++#define R_IA64_GPREL32MSB     0x2c    /* @gprel(sym + add), data4 MSB */
++#define R_IA64_GPREL32LSB     0x2d    /* @gprel(sym + add), data4 LSB */
++#define R_IA64_GPREL64MSB     0x2e    /* @gprel(sym + add), data8 MSB */
++#define R_IA64_GPREL64LSB     0x2f    /* @gprel(sym + add), data8 LSB */
++#define R_IA64_LTOFF22                0x32    /* @ltoff(sym + add), add imm22 */
++#define R_IA64_LTOFF64I               0x33    /* @ltoff(sym + add), mov imm64 */
++#define R_IA64_PLTOFF22               0x3a    /* @pltoff(sym + add), add imm22 */
++#define R_IA64_PLTOFF64I      0x3b    /* @pltoff(sym + add), mov imm64 */
++#define R_IA64_PLTOFF64MSB    0x3e    /* @pltoff(sym + add), data8 MSB */
++#define R_IA64_PLTOFF64LSB    0x3f    /* @pltoff(sym + add), data8 LSB */
++#define R_IA64_FPTR64I                0x43    /* @fptr(sym + add), mov imm64 */
++#define R_IA64_FPTR32MSB      0x44    /* @fptr(sym + add), data4 MSB */
++#define R_IA64_FPTR32LSB      0x45    /* @fptr(sym + add), data4 LSB */
++#define R_IA64_FPTR64MSB      0x46    /* @fptr(sym + add), data8 MSB */
++#define R_IA64_FPTR64LSB      0x47    /* @fptr(sym + add), data8 LSB */
++#define R_IA64_PCREL60B               0x48    /* @pcrel(sym + add), brl */
++#define R_IA64_PCREL21B               0x49    /* @pcrel(sym + add), ptb, call */
++#define R_IA64_PCREL21M               0x4a    /* @pcrel(sym + add), chk.s */
++#define R_IA64_PCREL21F               0x4b    /* @pcrel(sym + add), fchkf */
++#define R_IA64_PCREL32MSB     0x4c    /* @pcrel(sym + add), data4 MSB */
++#define R_IA64_PCREL32LSB     0x4d    /* @pcrel(sym + add), data4 LSB */
++#define R_IA64_PCREL64MSB     0x4e    /* @pcrel(sym + add), data8 MSB */
++#define R_IA64_PCREL64LSB     0x4f    /* @pcrel(sym + add), data8 LSB */
++#define R_IA64_LTOFF_FPTR22   0x52    /* @ltoff(@fptr(s+a)), imm22 */
++#define R_IA64_LTOFF_FPTR64I  0x53    /* @ltoff(@fptr(s+a)), imm64 */
++#define R_IA64_LTOFF_FPTR32MSB        0x54    /* @ltoff(@fptr(s+a)), data4 MSB */
++#define R_IA64_LTOFF_FPTR32LSB        0x55    /* @ltoff(@fptr(s+a)), data4 LSB */
++#define R_IA64_LTOFF_FPTR64MSB        0x56    /* @ltoff(@fptr(s+a)), data8 MSB */
++#define R_IA64_LTOFF_FPTR64LSB        0x57    /* @ltoff(@fptr(s+a)), data8 LSB */
++#define R_IA64_SEGREL32MSB    0x5c    /* @segrel(sym + add), data4 MSB */
++#define R_IA64_SEGREL32LSB    0x5d    /* @segrel(sym + add), data4 LSB */
++#define R_IA64_SEGREL64MSB    0x5e    /* @segrel(sym + add), data8 MSB */
++#define R_IA64_SEGREL64LSB    0x5f    /* @segrel(sym + add), data8 LSB */
++#define R_IA64_SECREL32MSB    0x64    /* @secrel(sym + add), data4 MSB */
++#define R_IA64_SECREL32LSB    0x65    /* @secrel(sym + add), data4 LSB */
++#define R_IA64_SECREL64MSB    0x66    /* @secrel(sym + add), data8 MSB */
++#define R_IA64_SECREL64LSB    0x67    /* @secrel(sym + add), data8 LSB */
++#define R_IA64_REL32MSB               0x6c    /* data 4 + REL */
++#define R_IA64_REL32LSB               0x6d    /* data 4 + REL */
++#define R_IA64_REL64MSB               0x6e    /* data 8 + REL */
++#define R_IA64_REL64LSB               0x6f    /* data 8 + REL */
++#define R_IA64_LTV32MSB               0x74    /* symbol + addend, data4 MSB */
++#define R_IA64_LTV32LSB               0x75    /* symbol + addend, data4 LSB */
++#define R_IA64_LTV64MSB               0x76    /* symbol + addend, data8 MSB */
++#define R_IA64_LTV64LSB               0x77    /* symbol + addend, data8 LSB */
++#define R_IA64_PCREL21BI      0x79    /* @pcrel(sym + add), 21bit inst */
++#define R_IA64_PCREL22                0x7a    /* @pcrel(sym + add), 22bit inst */
++#define R_IA64_PCREL64I               0x7b    /* @pcrel(sym + add), 64bit inst */
++#define R_IA64_IPLTMSB                0x80    /* dynamic reloc, imported PLT, MSB */
++#define R_IA64_IPLTLSB                0x81    /* dynamic reloc, imported PLT, LSB */
++#define R_IA64_COPY           0x84    /* copy relocation */
++#define R_IA64_SUB            0x85    /* Addend and symbol difference */
++#define R_IA64_LTOFF22X               0x86    /* LTOFF22, relaxable.  */
++#define R_IA64_LDXMOV         0x87    /* Use of LTOFF22X.  */
++#define R_IA64_TPREL14                0x91    /* @tprel(sym + add), imm14 */
++#define R_IA64_TPREL22                0x92    /* @tprel(sym + add), imm22 */
++#define R_IA64_TPREL64I               0x93    /* @tprel(sym + add), imm64 */
++#define R_IA64_TPREL64MSB     0x96    /* @tprel(sym + add), data8 MSB */
++#define R_IA64_TPREL64LSB     0x97    /* @tprel(sym + add), data8 LSB */
++#define R_IA64_LTOFF_TPREL22  0x9a    /* @ltoff(@tprel(s+a)), imm2 */
++#define R_IA64_DTPMOD64MSB    0xa6    /* @dtpmod(sym + add), data8 MSB */
++#define R_IA64_DTPMOD64LSB    0xa7    /* @dtpmod(sym + add), data8 LSB */
++#define R_IA64_LTOFF_DTPMOD22 0xaa    /* @ltoff(@dtpmod(sym + add)), imm22 */
++#define R_IA64_DTPREL14               0xb1    /* @dtprel(sym + add), imm14 */
++#define R_IA64_DTPREL22               0xb2    /* @dtprel(sym + add), imm22 */
++#define R_IA64_DTPREL64I      0xb3    /* @dtprel(sym + add), imm64 */
++#define R_IA64_DTPREL32MSB    0xb4    /* @dtprel(sym + add), data4 MSB */
++#define R_IA64_DTPREL32LSB    0xb5    /* @dtprel(sym + add), data4 LSB */
++#define R_IA64_DTPREL64MSB    0xb6    /* @dtprel(sym + add), data8 MSB */
++#define R_IA64_DTPREL64LSB    0xb7    /* @dtprel(sym + add), data8 LSB */
++#define R_IA64_LTOFF_DTPREL22 0xba    /* @ltoff(@dtprel(s+a)), imm22 */
++
++/* SH specific declarations */
++
++/* SH specific values for `st_other'.  */
++
++/* If set, this is a symbol pointing to SHmedia code, which will be branched
++   to, so need to add 1 to the symbol value. */
++#define STO_SH5_ISA32 (1 << 2)
++
++/* SH relocs.  */
++#define       R_SH_NONE               0
++#define       R_SH_DIR32              1
++#define       R_SH_REL32              2
++#define       R_SH_DIR8WPN            3
++#define       R_SH_IND12W             4
++#define       R_SH_DIR8WPL            5
++#define       R_SH_DIR8WPZ            6
++#define       R_SH_DIR8BP             7
++#define       R_SH_DIR8W              8
++#define       R_SH_DIR8L              9
++#define       R_SH_SWITCH16           25
++#define       R_SH_SWITCH32           26
++#define       R_SH_USES               27
++#define       R_SH_COUNT              28
++#define       R_SH_ALIGN              29
++#define       R_SH_CODE               30
++#define       R_SH_DATA               31
++#define       R_SH_LABEL              32
++#define       R_SH_SWITCH8            33
++#define       R_SH_GNU_VTINHERIT      34
++#define       R_SH_GNU_VTENTRY        35
++#define       R_SH_TLS_GD_32          144
++#define       R_SH_TLS_LD_32          145
++#define       R_SH_TLS_LDO_32         146
++#define       R_SH_TLS_IE_32          147
++#define       R_SH_TLS_LE_32          148
++#define       R_SH_TLS_DTPMOD32       149
++#define       R_SH_TLS_DTPOFF32       150
++#define       R_SH_TLS_TPOFF32        151
++#define       R_SH_GOT32              160
++#define       R_SH_PLT32              161
++#define       R_SH_COPY               162
++#define       R_SH_GLOB_DAT           163
++#define       R_SH_JMP_SLOT           164
++#define       R_SH_RELATIVE           165
++#define       R_SH_GOTOFF             166
++#define       R_SH_GOTPC              167
++#define       R_SH_RELATIVE_LOW16     197
++#define       R_SH_RELATIVE_MEDLOW16  198
++#define       R_SH_IMM_LOW16          246
++#define       R_SH_IMM_LOW16_PCREL    247
++#define       R_SH_IMM_MEDLOW16       248
++#define       R_SH_IMM_MEDLOW16_PCREL 249
++
++/* Keep this the last entry.  */
++#define       R_SH_NUM                256
++
++/* Additional s390 relocs */
++
++#define R_390_NONE            0       /* No reloc.  */
++#define R_390_8                       1       /* Direct 8 bit.  */
++#define R_390_12              2       /* Direct 12 bit.  */
++#define R_390_16              3       /* Direct 16 bit.  */
++#define R_390_32              4       /* Direct 32 bit.  */
++#define R_390_PC32            5       /* PC relative 32 bit.  */
++#define R_390_GOT12           6       /* 12 bit GOT offset.  */
++#define R_390_GOT32           7       /* 32 bit GOT offset.  */
++#define R_390_PLT32           8       /* 32 bit PC relative PLT address.  */
++#define R_390_COPY            9       /* Copy symbol at runtime.  */
++#define R_390_GLOB_DAT                10      /* Create GOT entry.  */
++#define R_390_JMP_SLOT                11      /* Create PLT entry.  */
++#define R_390_RELATIVE                12      /* Adjust by program base.  */
++#define R_390_GOTOFF32                13      /* 32 bit offset to GOT.         */
++#define R_390_GOTPC           14      /* 32 bit PC relative offset to GOT.  */
++#define R_390_GOT16           15      /* 16 bit GOT offset.  */
++#define R_390_PC16            16      /* PC relative 16 bit.  */
++#define R_390_PC16DBL         17      /* PC relative 16 bit shifted by 1.  */
++#define R_390_PLT16DBL                18      /* 16 bit PC rel. PLT shifted by 1.  */
++#define R_390_PC32DBL         19      /* PC relative 32 bit shifted by 1.  */
++#define R_390_PLT32DBL                20      /* 32 bit PC rel. PLT shifted by 1.  */
++#define R_390_GOTPCDBL                21      /* 32 bit PC rel. GOT shifted by 1.  */
++#define R_390_64              22      /* Direct 64 bit.  */
++#define R_390_PC64            23      /* PC relative 64 bit.  */
++#define R_390_GOT64           24      /* 64 bit GOT offset.  */
++#define R_390_PLT64           25      /* 64 bit PC relative PLT address.  */
++#define R_390_GOTENT          26      /* 32 bit PC rel. to GOT entry >> 1. */
++#define R_390_GOTOFF16                27      /* 16 bit offset to GOT. */
++#define R_390_GOTOFF64                28      /* 64 bit offset to GOT. */
++#define R_390_GOTPLT12                29      /* 12 bit offset to jump slot.  */
++#define R_390_GOTPLT16                30      /* 16 bit offset to jump slot.  */
++#define R_390_GOTPLT32                31      /* 32 bit offset to jump slot.  */
++#define R_390_GOTPLT64                32      /* 64 bit offset to jump slot.  */
++#define R_390_GOTPLTENT               33      /* 32 bit rel. offset to jump slot.  */
++#define R_390_PLTOFF16                34      /* 16 bit offset from GOT to PLT. */
++#define R_390_PLTOFF32                35      /* 32 bit offset from GOT to PLT. */
++#define R_390_PLTOFF64                36      /* 16 bit offset from GOT to PLT. */
++#define R_390_TLS_LOAD                37      /* Tag for load insn in TLS code.  */
++#define R_390_TLS_GDCALL      38      /* Tag for function call in general
++                                         dynamic TLS code. */
++#define R_390_TLS_LDCALL      39      /* Tag for function call in local
++                                         dynamic TLS code. */
++#define R_390_TLS_GD32                40      /* Direct 32 bit for general dynamic
++                                         thread local data.  */
++#define R_390_TLS_GD64                41      /* Direct 64 bit for general dynamic
++                                        thread local data.  */
++#define R_390_TLS_GOTIE12     42      /* 12 bit GOT offset for static TLS
++                                         block offset.  */
++#define R_390_TLS_GOTIE32     43      /* 32 bit GOT offset for static TLS
++                                         block offset.  */
++#define R_390_TLS_GOTIE64     44      /* 64 bit GOT offset for static TLS
++                                         block offset. */
++#define R_390_TLS_LDM32               45      /* Direct 32 bit for local dynamic
++                                         thread local data in LE code.  */
++#define R_390_TLS_LDM64               46      /* Direct 64 bit for local dynamic
++                                         thread local data in LE code.  */
++#define R_390_TLS_IE32                47      /* 32 bit address of GOT entry for
++                                         negated static TLS block offset.  */
++#define R_390_TLS_IE64                48      /* 64 bit address of GOT entry for
++                                         negated static TLS block offset.  */
++#define R_390_TLS_IEENT               49      /* 32 bit rel. offset to GOT entry for
++                                         negated static TLS block offset.  */
++#define R_390_TLS_LE32                50      /* 32 bit negated offset relative to
++                                         static TLS block.  */
++#define R_390_TLS_LE64                51      /* 64 bit negated offset relative to
++                                         static TLS block.  */
++#define R_390_TLS_LDO32               52      /* 32 bit offset relative to TLS
++                                         block.  */
++#define R_390_TLS_LDO64               53      /* 64 bit offset relative to TLS
++                                         block.  */
++#define R_390_TLS_DTPMOD      54      /* ID of module containing symbol.  */
++#define R_390_TLS_DTPOFF      55      /* Offset in TLS block.  */
++#define R_390_TLS_TPOFF               56      /* Negated offset in static TLS
++                                         block.  */
++#define R_390_20              57      /* Direct 20 bit.  */
++#define R_390_GOT20           58      /* 20 bit GOT offset.  */
++#define R_390_GOTPLT20                59      /* 20 bit offset to jump slot.  */
++#define R_390_TLS_GOTIE20     60      /* 20 bit GOT offset for static TLS
++                                         block offset.  */
++/* Keep this the last entry.  */
++#define R_390_NUM             61
++
++
++/* CRIS flags.  */
++#define EF_CRIS_VARIANT_MASK           0x0000000e
++#define EF_CRIS_VARIANT_ANY_V0_V10     0x00000000
++#define EF_CRIS_VARIANT_V32            0x00000002
++#define EF_CRIS_VARIANT_COMMON_V10_V32 0x00000004
++
++/* CRIS relocations.  */
++#define R_CRIS_NONE           0
++#define R_CRIS_8              1
++#define R_CRIS_16             2
++#define R_CRIS_32             3
++#define R_CRIS_8_PCREL                4
++#define R_CRIS_16_PCREL               5
++#define R_CRIS_32_PCREL               6
++#define R_CRIS_GNU_VTINHERIT  7
++#define R_CRIS_GNU_VTENTRY    8
++#define R_CRIS_COPY           9
++#define R_CRIS_GLOB_DAT               10
++#define R_CRIS_JUMP_SLOT      11
++#define R_CRIS_RELATIVE               12
++#define R_CRIS_16_GOT         13
++#define R_CRIS_32_GOT         14
++#define R_CRIS_16_GOTPLT      15
++#define R_CRIS_32_GOTPLT      16
++#define R_CRIS_32_GOTREL      17
++#define R_CRIS_32_PLT_GOTREL  18
++#define R_CRIS_32_PLT_PCREL   19
++
++/* Keep this the last entry.  */
++#define R_CRIS_NUM            20
++
++
++/* AMD x86-64 relocations.  */
++#define R_X86_64_NONE         0       /* No reloc */
++#define R_X86_64_64           1       /* Direct 64 bit  */
++#define R_X86_64_PC32         2       /* PC relative 32 bit signed */
++#define R_X86_64_GOT32                3       /* 32 bit GOT entry */
++#define R_X86_64_PLT32                4       /* 32 bit PLT address */
++#define R_X86_64_COPY         5       /* Copy symbol at runtime */
++#define R_X86_64_GLOB_DAT     6       /* Create GOT entry */
++#define R_X86_64_JUMP_SLOT    7       /* Create PLT entry */
++#define R_X86_64_RELATIVE     8       /* Adjust by program base */
++#define R_X86_64_GOTPCREL     9       /* 32 bit signed PC relative
++                                         offset to GOT */
++#define R_X86_64_32           10      /* Direct 32 bit zero extended */
++#define R_X86_64_32S          11      /* Direct 32 bit sign extended */
++#define R_X86_64_16           12      /* Direct 16 bit zero extended */
++#define R_X86_64_PC16         13      /* 16 bit sign extended pc relative */
++#define R_X86_64_8            14      /* Direct 8 bit sign extended  */
++#define R_X86_64_PC8          15      /* 8 bit sign extended pc relative */
++#define R_X86_64_DTPMOD64     16      /* ID of module containing symbol */
++#define R_X86_64_DTPOFF64     17      /* Offset in module's TLS block */
++#define R_X86_64_TPOFF64      18      /* Offset in initial TLS block */
++#define R_X86_64_TLSGD                19      /* 32 bit signed PC relative offset
++                                         to two GOT entries for GD symbol */
++#define R_X86_64_TLSLD                20      /* 32 bit signed PC relative offset
++                                         to two GOT entries for LD symbol */
++#define R_X86_64_DTPOFF32     21      /* Offset in TLS block */
++#define R_X86_64_GOTTPOFF     22      /* 32 bit signed PC relative offset
++                                         to GOT entry for IE symbol */
++#define R_X86_64_TPOFF32      23      /* Offset in initial TLS block */
++
++#define R_X86_64_NUM          24
++
++
++/* AM33 relocations.  */
++#define R_MN10300_NONE                0       /* No reloc.  */
++#define R_MN10300_32          1       /* Direct 32 bit.  */
++#define R_MN10300_16          2       /* Direct 16 bit.  */
++#define R_MN10300_8           3       /* Direct 8 bit.  */
++#define R_MN10300_PCREL32     4       /* PC-relative 32-bit.  */
++#define R_MN10300_PCREL16     5       /* PC-relative 16-bit signed.  */
++#define R_MN10300_PCREL8      6       /* PC-relative 8-bit signed.  */
++#define R_MN10300_GNU_VTINHERIT       7       /* Ancient C++ vtable garbage... */
++#define R_MN10300_GNU_VTENTRY 8       /* ... collection annotation.  */
++#define R_MN10300_24          9       /* Direct 24 bit.  */
++#define R_MN10300_GOTPC32     10      /* 32-bit PCrel offset to GOT.  */
++#define R_MN10300_GOTPC16     11      /* 16-bit PCrel offset to GOT.  */
++#define R_MN10300_GOTOFF32    12      /* 32-bit offset from GOT.  */
++#define R_MN10300_GOTOFF24    13      /* 24-bit offset from GOT.  */
++#define R_MN10300_GOTOFF16    14      /* 16-bit offset from GOT.  */
++#define R_MN10300_PLT32               15      /* 32-bit PCrel to PLT entry.  */
++#define R_MN10300_PLT16               16      /* 16-bit PCrel to PLT entry.  */
++#define R_MN10300_GOT32               17      /* 32-bit offset to GOT entry.  */
++#define R_MN10300_GOT24               18      /* 24-bit offset to GOT entry.  */
++#define R_MN10300_GOT16               19      /* 16-bit offset to GOT entry.  */
++#define R_MN10300_COPY                20      /* Copy symbol at runtime.  */
++#define R_MN10300_GLOB_DAT    21      /* Create GOT entry.  */
++#define R_MN10300_JMP_SLOT    22      /* Create PLT entry.  */
++#define R_MN10300_RELATIVE    23      /* Adjust by program base.  */
++
++#define R_MN10300_NUM         24
++
++
++/* M32R relocs.  */
++#define R_M32R_NONE           0       /* No reloc. */
++#define R_M32R_16             1       /* Direct 16 bit. */
++#define R_M32R_32             2       /* Direct 32 bit. */
++#define R_M32R_24             3       /* Direct 24 bit. */
++#define R_M32R_10_PCREL               4       /* PC relative 10 bit shifted. */
++#define R_M32R_18_PCREL               5       /* PC relative 18 bit shifted. */
++#define R_M32R_26_PCREL               6       /* PC relative 26 bit shifted. */
++#define R_M32R_HI16_ULO               7       /* High 16 bit with unsigned low. */
++#define R_M32R_HI16_SLO               8       /* High 16 bit with signed low. */
++#define R_M32R_LO16           9       /* Low 16 bit. */
++#define R_M32R_SDA16          10      /* 16 bit offset in SDA. */
++#define R_M32R_GNU_VTINHERIT  11
++#define R_M32R_GNU_VTENTRY    12
++/* M32R relocs use SHT_RELA.  */
++#define R_M32R_16_RELA                33      /* Direct 16 bit. */
++#define R_M32R_32_RELA                34      /* Direct 32 bit. */
++#define R_M32R_24_RELA                35      /* Direct 24 bit. */
++#define R_M32R_10_PCREL_RELA  36      /* PC relative 10 bit shifted. */
++#define R_M32R_18_PCREL_RELA  37      /* PC relative 18 bit shifted. */
++#define R_M32R_26_PCREL_RELA  38      /* PC relative 26 bit shifted. */
++#define R_M32R_HI16_ULO_RELA  39      /* High 16 bit with unsigned low */
++#define R_M32R_HI16_SLO_RELA  40      /* High 16 bit with signed low */
++#define R_M32R_LO16_RELA      41      /* Low 16 bit */
++#define R_M32R_SDA16_RELA     42      /* 16 bit offset in SDA */
++#define R_M32R_RELA_GNU_VTINHERIT     43
++#define R_M32R_RELA_GNU_VTENTRY       44
++
++#define R_M32R_GOT24          48      /* 24 bit GOT entry */
++#define R_M32R_26_PLTREL      49      /* 26 bit PC relative to PLT shifted */
++#define R_M32R_COPY           50      /* Copy symbol at runtime */
++#define R_M32R_GLOB_DAT               51      /* Create GOT entry */
++#define R_M32R_JMP_SLOT               52      /* Create PLT entry */
++#define R_M32R_RELATIVE               53      /* Adjust by program base */
++#define R_M32R_GOTOFF         54      /* 24 bit offset to GOT */
++#define R_M32R_GOTPC24                55      /* 24 bit PC relative offset to GOT */
++#define R_M32R_GOT16_HI_ULO   56      /* High 16 bit GOT entry with unsigned
++                                         low */
++#define R_M32R_GOT16_HI_SLO   57      /* High 16 bit GOT entry with signed
++                                         low */
++#define R_M32R_GOT16_LO               58      /* Low 16 bit GOT entry */
++#define R_M32R_GOTPC_HI_ULO   59      /* High 16 bit PC relative offset to
++                                         GOT with unsigned low */
++#define R_M32R_GOTPC_HI_SLO   60      /* High 16 bit PC relative offset to
++                                         GOT with signed low */
++#define R_M32R_GOTPC_LO               61      /* Low 16 bit PC relative offset to
++                                         GOT */
++#define R_M32R_GOTOFF_HI_ULO  62      /* High 16 bit offset to GOT
++                                         with unsigned low */
++#define R_M32R_GOTOFF_HI_SLO  63      /* High 16 bit offset to GOT
++                                         with signed low */
++#define R_M32R_GOTOFF_LO      64      /* Low 16 bit offset to GOT */
++#define R_M32R_NUM            256     /* Keep this the last entry. */
++
++/* i960 Relocations */
++#define R_960_NONE      0
++#define R_960_12        1
++#define R_960_32        2
++#define R_960_IP24      3
++#define R_960_SUB       4
++#define R_960_OPTCALL   5
++#define R_960_OPTCALLX  6
++#define R_960_OPTCALLXA 7
++/* Keep this the last entry.  */
++#define R_960_NUM     8
++
++
++/* v850 relocations.  */
++#define R_V850_NONE           0
++#define R_V850_9_PCREL                1
++#define R_V850_22_PCREL               2
++#define R_V850_HI16_S         3
++#define R_V850_HI16           4
++#define R_V850_LO16           5
++#define R_V850_32             6
++#define R_V850_16             7
++#define R_V850_8              8
++#define R_V850_SDA_16_16_OFFSET       9       /* For ld.b, st.b, set1, clr1,
++                                         not1, tst1, movea, movhi */
++#define R_V850_SDA_15_16_OFFSET       10      /* For ld.w, ld.h, ld.hu, st.w, st.h */
++#define R_V850_ZDA_16_16_OFFSET       11      /* For ld.b, st.b, set1, clr1,
++                                         not1, tst1, movea, movhi */
++#define R_V850_ZDA_15_16_OFFSET       12      /* For ld.w, ld.h, ld.hu, st.w, st.h */
++#define R_V850_TDA_6_8_OFFSET 13      /* For sst.w, sld.w */
++#define R_V850_TDA_7_8_OFFSET 14      /* For sst.h, sld.h */
++#define R_V850_TDA_7_7_OFFSET 15      /* For sst.b, sld.b */
++#define R_V850_TDA_16_16_OFFSET       16      /* For set1, clr1, not1, tst1,
++                                         movea, movhi */
++/* CYGNUS LOCAL v850e */
++#define R_V850_TDA_4_5_OFFSET         17      /* For sld.hu */
++#define R_V850_TDA_4_4_OFFSET         18      /* For sld.bu */
++#define R_V850_SDA_16_16_SPLIT_OFFSET 19      /* For ld.bu */
++#define R_V850_ZDA_16_16_SPLIT_OFFSET 20      /* For ld.bu */
++#define R_V850_CALLT_6_7_OFFSET               21      /* For callt */
++#define R_V850_CALLT_16_16_OFFSET     22      /* For callt */
++/* END CYGNUS LOCAL */
++#define R_V850_GNU_VTINHERIT  23
++#define R_V850_GNU_VTENTRY    24
++/* Keep this the last entry.  */
++#define R_V850_NUM            25
++
++
++/* Renesas H8/300 Relocations */
++#define R_H8_NONE       0
++#define R_H8_DIR32      1
++#define R_H8_DIR32_28   2
++#define R_H8_DIR32_24   3
++#define R_H8_DIR32_16   4
++#define R_H8_DIR32U     6
++#define R_H8_DIR32U_28  7
++#define R_H8_DIR32U_24  8
++#define R_H8_DIR32U_20  9
++#define R_H8_DIR32U_16 10
++#define R_H8_DIR24     11
++#define R_H8_DIR24_20  12
++#define R_H8_DIR24_16  13
++#define R_H8_DIR24U    14
++#define R_H8_DIR24U_20 15
++#define R_H8_DIR24U_16 16
++#define R_H8_DIR16     17
++#define R_H8_DIR16U    18
++#define R_H8_DIR16S_32 19
++#define R_H8_DIR16S_28 20
++#define R_H8_DIR16S_24 21
++#define R_H8_DIR16S_20 22
++#define R_H8_DIR16S    23
++#define R_H8_DIR8      24
++#define R_H8_DIR8U     25
++#define R_H8_DIR8Z_32  26
++#define R_H8_DIR8Z_28  27
++#define R_H8_DIR8Z_24  28
++#define R_H8_DIR8Z_20  29
++#define R_H8_DIR8Z_16  30
++#define R_H8_PCREL16   31
++#define R_H8_PCREL8    32
++#define R_H8_BPOS      33
++#define R_H8_PCREL32   34
++#define R_H8_GOT32O    35
++#define R_H8_GOT16O    36
++#define R_H8_DIR16A8   59
++#define R_H8_DIR16R8   60
++#define R_H8_DIR24A8   61
++#define R_H8_DIR24R8   62
++#define R_H8_DIR32A16  63
++#define R_H8_ABS32     65
++#define R_H8_ABS32A16 127
++#define R_H8_NUM      128
++
++/* NIOS relocations. */
++#define R_NIOS_NONE                           0
++#define R_NIOS_32                             1       /* A 32 bit absolute relocation.*/
++#define R_NIOS_LO16_LO5                       2       /* A LO-16 5 bit absolute relocation.  */
++#define R_NIOS_LO16_HI11              3       /* A LO-16 top 11 bit absolute relocation.  */
++#define R_NIOS_HI16_LO5                       4       /* A HI-16 5 bit absolute relocation.  */
++#define R_NIOS_HI16_HI11              5       /* A HI-16 top 11 bit absolute relocation.  */
++#define R_NIOS_PCREL6                 6       /* A 6 bit relative relocation.  */
++#define R_NIOS_PCREL8                 7       /* An 8 bit relative relocation.  */
++#define R_NIOS_PCREL11                        8       /* An 11 bit relative relocation.  */
++#define R_NIOS_16                             9       /* A 16 bit absolute relocation.  */
++#define R_NIOS_H_LO5                  10      /* Low 5-bits of absolute relocation in halfwords.  */
++#define R_NIOS_H_HI11                 11      /* Top 11 bits of 16-bit absolute relocation in halfwords.  */
++#define R_NIOS_H_XLO5                 12      /* Low 5 bits of top 16-bits of 32-bit absolute relocation in halfwords.  */
++#define R_NIOS_H_XHI11                        13      /* Top 11 bits of top 16-bits of 32-bit absolute relocation in halfwords.  */
++#define R_NIOS_H_16                           14      /* Half-word @h value */
++#define R_NIOS_H_32                           15      /* Word @h value */
++#define R_NIOS_GNU_VTINHERIT  200     /* GNU extension to record C++ vtable hierarchy */
++#define R_NIOS_GNU_VTENTRY            201     /* GNU extension to record C++ vtable member usage */
++/* Keep this the last entry.  */
++#define R_NIOS_NUM                            202
++
++/* NIOS II relocations */
++#define R_NIOS2_NONE                  0
++#define R_NIOS2_S16                           1
++#define R_NIOS2_U16                           2
++#define R_NIOS2_PCREL16                       3
++#define R_NIOS2_CALL26                        4
++#define R_NIOS2_IMM5                  5
++#define R_NIOS2_CACHE_OPX             6
++#define R_NIOS2_IMM6                  7
++#define R_NIOS2_IMM8                  8
++#define R_NIOS2_HI16                  9
++#define R_NIOS2_LO16                  10
++#define R_NIOS2_HIADJ16               11
++#define R_NIOS2_BFD_RELOC_32  12
++#define R_NIOS2_BFD_RELOC_16  13
++#define R_NIOS2_BFD_RELOC_8   14
++#define R_NIOS2_GPREL                 15
++#define R_NIOS2_GNU_VTINHERIT         16
++#define R_NIOS2_GNU_VTENTRY   17
++#define R_NIOS2_UJMP                  18
++#define R_NIOS2_CJMP                  19
++#define R_NIOS2_CALLR                 20
++#define R_NIOS2_ALIGN                 21
++/* Keep this the last entry.  */
++#define R_NIOS2_NUM                           22
++
++__END_DECLS
++
++#endif        /* elf.h */
+diff -Nrup a/ldso/include/dl-string.h b/ldso/include/dl-string.h
+--- a/ldso/include/dl-string.h 2007-01-25 19:22:03.000000000 -0500
++++ b/ldso/include/dl-string.h 2008-02-28 19:03:13.000000000 -0500
+@@ -285,7 +285,9 @@ static __always_inline char * _dl_simple
+ /* On some arches constant strings are referenced through the GOT.
+  * This requires that load_addr must already be defined... */
+ #if defined(mc68000)  || defined(__arm__) || defined(__thumb__) || \
+-    defined(__mips__) || defined(__sh__)  || defined(__powerpc__)
++    defined(__mips__) || defined(__sh__)  || defined(__powerpc__) || \
++      defined(__avr32__)
++
+ # define CONSTANT_STRING_GOT_FIXUP(X) \
+       if ((X) < (const char *) load_addr) (X) += load_addr
+ # define NO_EARLY_SEND_STDERR
+diff -Nrup a/ldso/include/dl-syscall.h b/ldso/include/dl-syscall.h
+--- a/ldso/include/dl-syscall.h        2007-01-28 00:51:31.000000000 -0500
++++ b/ldso/include/dl-syscall.h        2008-02-28 19:06:04.000000000 -0500
+@@ -54,69 +54,69 @@
+    dynamic linking at all, so we cannot return any error codes.
+    We just punt if there is an error. */
+ #define __NR__dl_exit __NR_exit
+-static inline _syscall1(void, _dl_exit, int, status);
++static __always_inline _syscall1(void, _dl_exit, int, status);
+ #define __NR__dl_close __NR_close
+-static inline _syscall1(int, _dl_close, int, fd);
++static __always_inline _syscall1(int, _dl_close, int, fd);
+ #define __NR__dl_open __NR_open
+-static inline _syscall3(int, _dl_open, const char *, fn, int, flags,
++static __always_inline _syscall3(int, _dl_open, const char *, fn, int, flags,
+                         __kernel_mode_t, mode);
+ #define __NR__dl_write __NR_write
+-static inline _syscall3(unsigned long, _dl_write, int, fd,
++static __always_inline _syscall3(unsigned long, _dl_write, int, fd,
+                         const void *, buf, unsigned long, count);
+ #define __NR__dl_read __NR_read
+-static inline _syscall3(unsigned long, _dl_read, int, fd,
++static __always_inline _syscall3(unsigned long, _dl_read, int, fd,
+                         const void *, buf, unsigned long, count);
+ #define __NR__dl_mprotect __NR_mprotect
+-static inline _syscall3(int, _dl_mprotect, const void *, addr,
++static __always_inline _syscall3(int, _dl_mprotect, const void *, addr,
+                         unsigned long, len, int, prot);
+ #define __NR__dl_stat __NR_stat
+-static inline _syscall2(int, _dl_stat, const char *, file_name,
++static __always_inline _syscall2(int, _dl_stat, const char *, file_name,
+                         struct stat *, buf);
+ #define __NR__dl_fstat __NR_fstat
+-static inline _syscall2(int, _dl_fstat, int, fd, struct stat *, buf);
++static __always_inline _syscall2(int, _dl_fstat, int, fd, struct stat *, buf);
+ #define __NR__dl_munmap __NR_munmap
+-static inline _syscall2(int, _dl_munmap, void *, start, unsigned long, length);
++static __always_inline _syscall2(int, _dl_munmap, void *, start, unsigned long, length);
+ #ifdef __NR_getxuid
+ # define __NR_getuid __NR_getxuid
+ #endif
+ #define __NR__dl_getuid __NR_getuid
+-static inline _syscall0(uid_t, _dl_getuid);
++static __always_inline _syscall0(uid_t, _dl_getuid);
+ #ifndef __NR_geteuid
+ # define __NR_geteuid __NR_getuid
+ #endif
+ #define __NR__dl_geteuid __NR_geteuid
+-static inline _syscall0(uid_t, _dl_geteuid);
++static __always_inline _syscall0(uid_t, _dl_geteuid);
+ #ifdef __NR_getxgid
+ # define __NR_getgid __NR_getxgid
+ #endif
+ #define __NR__dl_getgid __NR_getgid
+-static inline _syscall0(gid_t, _dl_getgid);
++static __always_inline _syscall0(gid_t, _dl_getgid);
+ #ifndef __NR_getegid
+ # define __NR_getegid __NR_getgid
+ #endif
+ #define __NR__dl_getegid __NR_getegid
+-static inline _syscall0(gid_t, _dl_getegid);
++static __always_inline _syscall0(gid_t, _dl_getegid);
+ #ifdef __NR_getxpid
+ # define __NR_getpid __NR_getxpid
+ #endif
+ #define __NR__dl_getpid __NR_getpid
+-static inline _syscall0(gid_t, _dl_getpid);
++static __always_inline _syscall0(gid_t, _dl_getpid);
+ #define __NR__dl_readlink __NR_readlink
+-static inline _syscall3(int, _dl_readlink, const char *, path, char *, buf,
++static __always_inline _syscall3(int, _dl_readlink, const char *, path, char *, buf,
+                         size_t, bufsiz);
+@@ -134,14 +134,14 @@ static inline _syscall3(int, _dl_readlin
+ #if defined(__UCLIBC_MMAP_HAS_6_ARGS__) && defined(__NR_mmap)
+ # define __NR__dl_mmap __NR_mmap
+-static inline _syscall6(void *, _dl_mmap, void *, start, size_t, length,
++static __always_inline _syscall6(void *, _dl_mmap, void *, start, size_t, length,
+                         int, prot, int, flags, int, fd, off_t, offset);
+ /* then try mmap2() */
+ #elif defined(__NR_mmap2)
+ # define __NR___syscall_mmap2       __NR_mmap2
+-static inline _syscall6(__ptr_t, __syscall_mmap2, __ptr_t, addr, size_t, len,
++static __always_inline _syscall6(__ptr_t, __syscall_mmap2, __ptr_t, addr, size_t, len,
+                         int, prot, int, flags, int, fd, off_t, offset);
+ /* Some architectures always use 12 as page shift for mmap2() eventhough the
+@@ -152,7 +152,7 @@ static inline _syscall6(__ptr_t, __sysca
+ # define MMAP2_PAGE_SHIFT 12
+ #endif
+-static inline void * _dl_mmap(void * addr, unsigned long size, int prot,
++static __always_inline void * _dl_mmap(void * addr, unsigned long size, int prot,
+                               int flags, int fd, unsigned long offset)
+ {
+       if (offset & ((1 << MMAP2_PAGE_SHIFT) - 1))
+@@ -165,8 +165,8 @@ static inline void * _dl_mmap(void * add
+ #elif defined(__NR_mmap)
+ # define __NR__dl_mmap_real __NR_mmap
+-static inline _syscall1(void *, _dl_mmap_real, unsigned long *, buffer);
+-static inline void * _dl_mmap(void * addr, unsigned long size, int prot,
++static __always_inline _syscall1(void *, _dl_mmap_real, unsigned long *, buffer);
++static __always_inline void * _dl_mmap(void * addr, unsigned long size, int prot,
+                               int flags, int fd, unsigned long offset)
+ {
+       unsigned long buffer[6];
+diff -Nrup a/ldso/ldso/avr32/dl-debug.h b/ldso/ldso/avr32/dl-debug.h
+--- a/ldso/ldso/avr32/dl-debug.h       1969-12-31 19:00:00.000000000 -0500
++++ b/ldso/ldso/avr32/dl-debug.h       2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,45 @@
++/*
++ * AVR32 ELF shared libary loader support
++ *
++ * Copyright (C) 2005 Atmel Norway
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. The name of the above contributors may not be
++ *    used to endorse or promote products derived from this software
++ *    without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ */
++
++static const char *_dl_reltypes_tab[] = {
++    "R_AVR32_NONE",
++    "R_AVR32_32", "R_AVR32_16", "R_AVR32_8",
++    "R_AVR32_32_PCREL", "R_AVR32_16_PCREL", "R_AVR32_8_PCREL",
++    "R_AVR32_DIFF32", "R_AVR32_DIFF16", "R_AVR32_DIFF8",
++    "R_AVR32_GOT32", "R_AVR32_GOT16", "R_AVR32_GOT8",
++    "R_AVR32_21S", "R_AVR32_16U", "R_AVR32_16S", "R_AVR32_8S", "R_AVR32_8S_EXT",
++    "R_AVR32_22H_PCREL", "R_AVR32_18W_PCREL", "R_AVR32_16B_PCREL",
++    "R_AVR32_16N_PCREL", "R_AVR32_14UW_PCREL", "R_AVR32_11H_PCREL",
++    "R_AVR32_10UW_PCREL", "R_AVR32_9H_PCREL", "R_AVR32_9UW_PCREL",
++    "R_AVR32_HI16", "R_AVR32_LO16",
++    "R_AVR32_GOTPC", "R_AVR32_GOTCALL", "R_AVR32_LDA_GOT",
++    "R_AVR32_GOT21S", "R_AVR32_GOT18SW", "R_AVR32_GOT16S", "R_AVR32_GOT7UW",
++    "R_AVR32_32_CPENT", "R_AVR32_CPCALL", "R_AVR32_16_CP", "R_AVR32_9W_CP",
++    "R_AVR32_RELATIVE", "R_AVR32_GLOB_DAT", "R_AVR32_JMP_SLOT",
++    "R_AVR32_ALIGN",
++};
+diff -Nrup a/ldso/ldso/avr32/dl-startup.h b/ldso/ldso/avr32/dl-startup.h
+--- a/ldso/ldso/avr32/dl-startup.h     1969-12-31 19:00:00.000000000 -0500
++++ b/ldso/ldso/avr32/dl-startup.h     2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,110 @@
++/* vi: set sw=4 ts=4: */
++/*
++ * Architecture specific code used by dl-startup.c
++ * Copyright (C) 2005 Atmel Norway
++ */
++
++/* This is the library loader's main entry point. Let _dl_boot2 do its
++ * initializations and jump to the application's entry point
++ * afterwards. */
++asm(  "       .text\n"
++      "       .global _start\n"
++      "       .type   _start,@function\n"
++      "_start:\n"
++      /* All arguments are on the stack initially */
++      "       mov     r12, sp\n"
++      "       rcall   _dl_start\n"
++      /* Returns user entry point in r12. Save it. */
++      "       mov     r0, r12\n"
++      /* We're PIC, so get the Global Offset Table */
++      "       lddpc   r6, .L_GOT\n"
++      ".L_RGOT:\n"
++      "       rsub    r6, pc\n"
++      /* Adjust argc and argv according to _dl_skip_args */
++      "       ld.w    r1, r6[_dl_skip_args@got]\n"
++      "       ld.w    r1, r1[0]\n"
++      "       ld.w    r2, sp++\n"
++      "       sub     r2, r1\n"
++      "       add     sp, sp, r1 << 2\n"
++      "       st.w    --sp, r2\n"
++      /* Load the finalizer function */
++      "       ld.w    r12, r6[_dl_fini@got]\n"
++      /* Jump to the user's entry point */
++      "       mov     pc, r0\n\n"
++
++      "       .align  2\n"
++      ".L_GOT:"
++      "       .long   .L_RGOT - _GLOBAL_OFFSET_TABLE_\n"
++      "       .size   _start, . - _start\n"
++      "       .previous\n");
++
++/* Get a pointer to the argv array.  On many platforms this can be just
++ * the address if the first argument, on other platforms we need to
++ * do something a little more subtle here. */
++#define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned long *)ARGS + 1)
++
++
++/* We can't call functions before the GOT has been initialized */
++#define NO_FUNCS_BEFORE_BOOTSTRAP
++
++/*
++ * Relocate the GOT during dynamic loader bootstrap.  This will add
++ * the load address to all entries in the GOT, which is necessary
++ * because the linker doesn't generate R_AVR32_RELATIVE relocs for the
++ * GOT.
++ */
++static __always_inline
++void PERFORM_BOOTSTRAP_GOT(struct elf_resolve *tpnt)
++{
++      Elf32_Addr i, nr_got;
++      register Elf32_Addr *__r6 __asm__("r6");
++      Elf32_Addr *got = __r6;
++
++      nr_got = tpnt->dynamic_info[DT_AVR32_GOTSZ_IDX] / sizeof(*got);
++      for (i = 2; i < nr_got; i++)
++              got[i] += tpnt->loadaddr;
++}
++
++#define PERFORM_BOOTSTRAP_GOT(tpnt) PERFORM_BOOTSTRAP_GOT(tpnt)
++
++/* Handle relocation of the symbols in the dynamic loader. */
++static __always_inline
++void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, unsigned long *reloc_addr,
++                           unsigned long symbol_addr,
++                           unsigned long load_addr, Elf32_Sym *symtab)
++{
++      switch(ELF32_R_TYPE(rpnt->r_info)) {
++      case R_AVR32_NONE:
++              break;
++      case R_AVR32_GLOB_DAT:
++      case R_AVR32_JMP_SLOT:
++              *reloc_addr = symbol_addr;
++              break;
++      case R_AVR32_RELATIVE:
++              SEND_STDERR_DEBUG("Applying RELATIVE relocation: ");
++              SEND_ADDRESS_STDERR_DEBUG(load_addr, 0);
++              SEND_STDERR_DEBUG(" + ");
++              SEND_ADDRESS_STDERR_DEBUG(rpnt->r_addend, 1);
++              *reloc_addr = load_addr + rpnt->r_addend;
++              break;
++      default:
++              SEND_STDERR("BOOTSTRAP_RELOC: unhandled reloc_type ");
++              SEND_NUMBER_STDERR(ELF32_R_TYPE(rpnt->r_info), 1);
++              SEND_STDERR("REL, SYMBOL, LOAD: ");
++              SEND_ADDRESS_STDERR(reloc_addr, 0);
++              SEND_STDERR(", ");
++              SEND_ADDRESS_STDERR(symbol_addr, 0);
++              SEND_STDERR(", ");
++              SEND_ADDRESS_STDERR(load_addr, 1);
++              _dl_exit(1);
++      }
++}
++
++/* Transfer control to the user's application, once the dynamic loader
++ * is done. This routine has to exit the current function, then call
++ * the _dl_elf_main function.
++ *
++ * Since our _dl_boot will simply call whatever is returned by
++ * _dl_boot2, we can just return the address we're supposed to
++ * call.  */
++#define START()       return _dl_elf_main;
+diff -Nrup a/ldso/ldso/avr32/dl-syscalls.h b/ldso/ldso/avr32/dl-syscalls.h
+--- a/ldso/ldso/avr32/dl-syscalls.h    1969-12-31 19:00:00.000000000 -0500
++++ b/ldso/ldso/avr32/dl-syscalls.h    2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,5 @@
++/* We can't use the real errno in ldso, since it has not yet
++ * been dynamicly linked in yet. */
++extern int _dl_errno;
++#define __set_errno(X) {(_dl_errno) = (X);}
++#include "sys/syscall.h"
+diff -Nrup a/ldso/ldso/avr32/dl-sysdep.h b/ldso/ldso/avr32/dl-sysdep.h
+--- a/ldso/ldso/avr32/dl-sysdep.h      1969-12-31 19:00:00.000000000 -0500
++++ b/ldso/ldso/avr32/dl-sysdep.h      2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,103 @@
++/* vi: set sw=4 ts=4: */
++/*
++ * Various assembly language/system dependent hacks that are required
++ * so that we can minimize the amount of platform specific code.
++ * Copyright (C) 2004-2005 Atmel Norway
++ */
++
++/* Define this if the system uses RELOCA. */
++#define ELF_USES_RELOCA
++
++#include <elf.h>
++
++#define ARCH_NUM 1
++#define DT_AVR32_GOTSZ_IDX    (DT_NUM + OS_NUM)
++
++#define ARCH_DYNAMIC_INFO(dpnt, dynamic, debug_addr)                  \
++      do {                                                            \
++              if (dpnt->d_tag == DT_AVR32_GOTSZ)                      \
++                      dynamic[DT_AVR32_GOTSZ_IDX] = dpnt->d_un.d_val; \
++      } while (0)
++
++/* Initialization sequence for the application/library GOT. */
++#define INIT_GOT(GOT_BASE,MODULE)                                     \
++      do {                                                            \
++              unsigned long i, nr_got;                                \
++                                                                      \
++              GOT_BASE[0] = (unsigned long) _dl_linux_resolve;        \
++              GOT_BASE[1] = (unsigned long) MODULE;                   \
++                                                                      \
++              /* Add load address displacement to all GOT entries */  \
++              nr_got = MODULE->dynamic_info[DT_AVR32_GOTSZ_IDX] / 4;  \
++              for (i = 2; i < nr_got; i++)                            \
++                      GOT_BASE[i] += (unsigned long)MODULE->loadaddr; \
++      } while (0)
++
++#define do_rem(result, n, base)       ((result) = (n) % (base))
++
++/* Here we define the magic numbers that this dynamic loader should accept */
++#define MAGIC1 EM_AVR32
++#undef MAGIC2
++
++/* Used for error messages */
++#define ELF_TARGET "AVR32"
++
++unsigned long _dl_linux_resolver(unsigned long got_offset, unsigned long *got);
++
++/* 4096 bytes alignment */
++#define PAGE_ALIGN 0xfffff000
++#define ADDR_ALIGN 0xfff
++#define OFFS_ALIGN 0x7ffff000
++
++#define elf_machine_type_class(type)                          \
++      ((type == R_AVR32_JMP_SLOT) * ELF_RTYPE_CLASS_PLT)
++
++/* AVR32 doesn't need any COPY relocs */
++#define DL_NO_COPY_RELOCS
++
++/* Return the link-time address of _DYNAMIC.  Conveniently, this is the
++   first element of the GOT.  This must be inlined in a function which
++   uses global data.  */
++static inline Elf32_Addr
++elf_machine_dynamic (void)
++{
++      register Elf32_Addr *got asm ("r6");
++      return *got;
++}
++
++/* Return the run-time load address of the shared object.  */
++static inline Elf32_Addr
++elf_machine_load_address (void)
++{
++      extern void __dl_start asm("_dl_start");
++      Elf32_Addr got_addr = (Elf32_Addr) &__dl_start;
++      Elf32_Addr pcrel_addr;
++
++      asm   ("        lddpc   %0, 2f\n"
++             "1:      add     %0, pc\n"
++             "        rjmp    3f\n"
++             "        .align  2\n"
++             "2:      .long   _dl_start - 1b\n"
++             "3:\n"
++             : "=r"(pcrel_addr) : : "cc");
++
++      return pcrel_addr - got_addr;
++}
++
++/*
++ * Perform any RELATIVE relocations specified by DT_RELCOUNT.
++ * Currently, we don't use that tag, but we might in the future as
++ * this would reduce the startup time somewhat (although probably not by much).
++ */
++static inline void
++elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr,
++                    Elf32_Word relative_count)
++{
++      Elf32_Rela *rpnt = (void *)rel_addr;
++
++      do {
++              Elf32_Addr *reloc_addr;
++              reloc_addr = (void *)(load_off + (rpnt++)->r_offset);
++              *reloc_addr = load_off + rpnt->r_addend;
++      } while (--relative_count);
++}
+diff -Nrup a/ldso/ldso/avr32/elfinterp.c b/ldso/ldso/avr32/elfinterp.c
+--- a/ldso/ldso/avr32/elfinterp.c      1969-12-31 19:00:00.000000000 -0500
++++ b/ldso/ldso/avr32/elfinterp.c      2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,191 @@
++/*
++ * AVR32 ELF shared library loader suppport
++ *
++ * Copyright (C) 2004-2006 Atmel Corporation
++ *
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. The name of the above contributors may not be
++ *    used to endorse or promote products derived from this software
++ *    without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ */
++
++unsigned long _dl_linux_resolver(unsigned long got_offset, unsigned long *got)
++{
++      struct elf_resolve *tpnt = (struct elf_resolve *)got[1];
++      Elf32_Sym *sym;
++      unsigned long local_gotno;
++      unsigned long gotsym;
++      unsigned long new_addr;
++      char *strtab, *symname;
++      unsigned long *entry;
++      unsigned long sym_index = got_offset / 4;
++
++#if 0
++      local_gotno = tpnt->dynamic_info[DT_AVR32_LOCAL_GOTNO];
++      gotsym = tpnt->dynamic_info[DT_AVR32_GOTSYM];
++
++      sym = ((Elf32_Sym *)(tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr))
++              + sym_index;
++      strtab = (char *)(tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
++      symname = strtab + sym->st_name;
++
++#if 0
++      new_addr = (unsigned long) _dl_find_hash(strtab + sym->st_name,
++                                               tpnt->symbol_scope, tpnt,
++                                               resolver);
++#endif
++
++      entry = (unsigned long *)(got + local_gotno + sym_index - gotsym);
++      *entry = new_addr;
++#endif
++
++      return new_addr;
++}
++
++static int
++_dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope,
++        unsigned long rel_addr, unsigned long rel_size,
++        int (*reloc_func)(struct elf_resolve *tpnt, struct dyn_elf *scope,
++                          Elf32_Rela *rpnt, Elf32_Sym *symtab, char *strtab))
++{
++      Elf32_Sym *symtab;
++      Elf32_Rela *rpnt;
++      char *strtab;
++      int i;
++
++      rpnt = (Elf32_Rela *)rel_addr;
++      rel_size /= sizeof(Elf32_Rela);
++      symtab = (Elf32_Sym *)tpnt->dynamic_info[DT_SYMTAB];
++      strtab = (char *)tpnt->dynamic_info[DT_STRTAB];
++
++      for (i = 0; i < rel_size; i++, rpnt++) {
++              int symtab_index, res;
++
++              symtab_index = ELF32_R_SYM(rpnt->r_info);
++
++              debug_sym(symtab, strtab, symtab_index);
++              debug_reloc(symtab, strtab, rpnt);
++
++              res = reloc_func(tpnt, scope, rpnt, symtab, strtab);
++
++              if (res == 0)
++                      continue;
++
++              _dl_dprintf(2, "\n%s: ", _dl_progname);
++
++              if (symtab_index)
++                      _dl_dprintf(2, "symbol '%s': ",
++                                  strtab + symtab[symtab_index].st_name);
++
++              if (res < 0) {
++                      int reloc_type = ELF32_R_TYPE(rpnt->r_info);
++#if defined(__SUPPORT_LD_DEBUG__)
++                      _dl_dprintf(2, "can't handle reloc type %s\n",
++                                  _dl_reltypes(reloc_type));
++#else
++                      _dl_dprintf(2, "can't handle reloc type %x\n",
++                                  reloc_type);
++#endif
++                      _dl_exit(-res);
++              } else {
++                      _dl_dprintf(2, "can't resolve symbol\n");
++                      return res;
++              }
++      }
++
++      return 0;
++}
++
++static int _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
++                      Elf32_Rela *rpnt, Elf32_Sym *symtab, char *strtab)
++{
++      int reloc_type;
++      int symtab_index;
++      char *symname;
++      unsigned long *reloc_addr;
++      unsigned long symbol_addr;
++#if defined(__SUPPORT_LD_DEBUG__)
++      unsigned long old_val;
++#endif
++
++      reloc_addr = (unsigned long *)(tpnt->loadaddr + rpnt->r_offset);
++      reloc_type = ELF32_R_TYPE(rpnt->r_info);
++      symtab_index = ELF32_R_SYM(rpnt->r_info);
++      symbol_addr = 0;
++      symname = strtab + symtab[symtab_index].st_name;
++
++      if (symtab_index) {
++              symbol_addr = (unsigned long)
++                      _dl_find_hash(strtab + symtab[symtab_index].st_name,
++                                    tpnt->symbol_scope, tpnt,
++                                    elf_machine_type_class(reloc_type));
++
++              /* Allow undefined references to weak symbols */
++              if (!symbol_addr &&
++                  ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK) {
++                      _dl_dprintf(2, "%s: can't resolve symbol '%s'\n",
++                                  _dl_progname, symname);
++                      return 0;
++              }
++      }
++
++#if defined(__SUPPORT_LD_DEBUG__)
++      old_val = *reloc_addr;
++#endif
++      switch (reloc_type) {
++      case R_AVR32_NONE:
++              break;
++      case R_AVR32_GLOB_DAT:
++      case R_AVR32_JMP_SLOT:
++              *reloc_addr = symbol_addr + rpnt->r_addend;
++              break;
++      case R_AVR32_RELATIVE:
++              *reloc_addr = (unsigned long)tpnt->loadaddr
++                      + rpnt->r_addend;
++              break;
++      default:
++              return -1;
++      }
++
++#if defined(__SUPPORT_LD_DEBUG__)
++      if (_dl_debug_reloc && _dl_debug_detail)
++              _dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x\n",
++                          old_val, *reloc_addr);
++#endif
++
++      return 0;
++}
++
++void _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt,
++                                         unsigned long rel_addr,
++                                         unsigned long rel_size)
++{
++      /* TODO: Might want to support this in order to get faster
++       * startup times... */
++}
++
++int _dl_parse_relocation_information(struct dyn_elf *rpnt,
++                                   unsigned long rel_addr,
++                                   unsigned long rel_size)
++{
++      return _dl_parse(rpnt->dyn, rpnt->dyn->symbol_scope, rel_addr, rel_size,
++                       _dl_do_reloc);
++}
+diff -Nrup a/ldso/ldso/avr32/resolve.S b/ldso/ldso/avr32/resolve.S
+--- a/ldso/ldso/avr32/resolve.S        1969-12-31 19:00:00.000000000 -0500
++++ b/ldso/ldso/avr32/resolve.S        2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,28 @@
++/*
++ * Linux dynamic resolving code for AVR32. Fixes up the GOT entry as
++ * indicated in register r12 and jumps to the resolved address.
++ *
++ * 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.
++ *
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++#define ip r5
++
++      .text
++      .global _dl_linux_resolve
++      .type   _dl_linux_resolve,@function
++_dl_linux_resolve:
++      /* The PLT code pushed r8 for us. It contains the address of this
++         function's GOT entry, that is entry 0. ip contains the address
++         of the GOT entry of the function we wanted to call. */
++      stm     --sp, r9-r12, lr
++      mov     r11, r8
++      sub     r12, ip, r8
++      rcall   _dl_linux_resolver
++      mov     ip, r12
++      popm    r8-r12,lr
++      mov     pc, ip
++      .size   _dl_linux_resolve, . - _dl_linux_resolve
+diff -Nrup a/ldso/ldso/dl-startup.c b/ldso/ldso/dl-startup.c
+--- a/ldso/ldso/dl-startup.c   2007-01-25 19:22:03.000000000 -0500
++++ b/ldso/ldso/dl-startup.c   2008-02-28 19:02:10.000000000 -0500
+@@ -217,7 +217,9 @@ static void * __attribute_used__ _dl_sta
+       /* some arches (like MIPS) we have to tweak the GOT before relocations */
+       PERFORM_BOOTSTRAP_GOT(tpnt);
+-#else
++#endif
++
++#if !defined(PERFORM_BOOTSTRAP_GOT) || defined(__avr32__)
+       /* OK, now do the relocations.  We do not do a lazy binding here, so
+          that once we are done, we have considerably more flexibility. */
+@@ -259,7 +261,7 @@ static void * __attribute_used__ _dl_sta
+                               rel_addr += relative_count * sizeof(ELF_RELOC);;
+                       }
+-                      rpnt = (ELF_RELOC *) (rel_addr + load_addr);
++                      rpnt = (ELF_RELOC *) (rel_addr /* + load_addr */);
+                       for (i = 0; i < rel_size; i += sizeof(ELF_RELOC), rpnt++) {
+                               reloc_addr = (unsigned long *) (load_addr + (unsigned long) rpnt->r_offset);
+                               symtab_index = ELF_R_SYM(rpnt->r_info);
+diff -Nrup a/libc/Makefile b/libc/Makefile
+--- a/libc/Makefile    2007-02-28 16:23:09.000000000 -0500
++++ b/libc/Makefile    2008-02-28 19:02:10.000000000 -0500
+@@ -59,7 +59,7 @@ $(LIBNAME) shared_$(LIBNAME) ar-target: 
+       $(AR) dN 2 $(LIBNAME) $$objs && \
+       $(AR) dN 2 $(LIBNAME) $$objs
+       @for objfile in obj.signal \
+-                      obj.string.generic obj.string.$(TARGET_ARCH) obj.string \
++                      obj.string obj.string.generic obj.string.$(TARGET_ARCH) \
+                       obj.sysdeps.common obj.sysdeps.$(TARGET_ARCH) ; do \
+               if [ -e $$objfile ] ; then \
+                       if [ "$(MAKE_IS_SILENT)" = "n" ] ; then \
+diff -Nrup a/libc/string/avr32/bcopy.S b/libc/string/avr32/bcopy.S
+--- a/libc/string/avr32/bcopy.S        1969-12-31 19:00:00.000000000 -0500
++++ b/libc/string/avr32/bcopy.S        2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,15 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++      .text
++      .global bcopy
++      .type   bcopy, @function
++      .align  1
++bcopy:
++      /* Swap the first two arguments */
++      eor     r11, r12
++      eor     r12, r11
++      eor     r11, r12
++      rjmp    __memmove
++      .size   bcopy, . - bcopy
+diff -Nrup a/libc/string/avr32/bzero.S b/libc/string/avr32/bzero.S
+--- a/libc/string/avr32/bzero.S        1969-12-31 19:00:00.000000000 -0500
++++ b/libc/string/avr32/bzero.S        2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,12 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++      .text
++      .global bzero
++      .type   bzero, @function
++      .align  1
++bzero:
++      mov     r10, r11
++      mov     r11, 0
++      rjmp    __memset
+diff -Nrup a/libc/string/avr32/Makefile b/libc/string/avr32/Makefile
+--- a/libc/string/avr32/Makefile       1969-12-31 19:00:00.000000000 -0500
++++ b/libc/string/avr32/Makefile       2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,40 @@
++# Makefile for uClibc
++#
++# Copyright (C) 2000-2003 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
++
++TOPDIR=../../../
++include $(TOPDIR)Rules.mak
++
++SSRC  := bcopy.S bzero.S memcmp.S memcpy.S memmove.S
++SSRC  += memset.S strcmp.S strlen.S
++# memchr.S, strcat.S, strcpy.S, strncpy.S is broken
++SOBJS := $(patsubst %.S,%.o, $(SSRC))
++OBJS  := $(SOBJS)
++
++OBJ_LIST:= ../../obj.string.$(TARGET_ARCH)
++
++all: $(OBJ_LIST)
++
++$(OBJ_LIST): $(OBJS)
++      echo $(addprefix string/$(TARGET_ARCH)/, $(OBJS)) > $@
++
++$(SOBJS): %.o: %.S
++      $(CC) $(ASFLAGS) -c $< -o $@
++      $(STRIPTOOL) -x -R .note -R .comment $@
++
++clean:
++      $(RM) *.[oa] *~ core
+diff -Nrup a/libc/string/avr32/memchr.S b/libc/string/avr32/memchr.S
+--- a/libc/string/avr32/memchr.S       1969-12-31 19:00:00.000000000 -0500
++++ b/libc/string/avr32/memchr.S       2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,62 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++#define str r12
++#define chr r11
++#define len r10
++
++      .text
++      .global memchr
++      .type   memchr, @function
++memchr:
++      or      chr, chr, chr << 8
++      or      chr, chr, chr << 16
++
++      mov     r9, str
++      andl    r9, 3, COH
++      brne    .Lunaligned_str
++
++1:    sub     len, 4
++      brlt    2f
++      ld.w    r8, str++
++      psub.b  r9, r8, r11
++      tnbz    r9
++      brne    1b
++
++      sub     str, 4
++      bfextu  r9, r8, 24, 8
++      cp.b    r9, r11
++      reteq   str
++      sub     str, -1
++      bfextu  r9, r8, 16, 8
++      cp.b    r9, r11
++      reteq   str
++      sub     str, -1
++      bfextu  r9, r8, 8, 8
++      cp.b    r9, r11
++      reteq   str
++      sub     str, -1
++      retal   str
++
++2:    sub     len, -4
++      reteq   0
++
++3:    ld.ub   r8, str++
++      cp.w    r8, 0
++      reteq   str
++      sub     len, 1
++      brne    3b
++
++      retal   0
++
++.Lunaligned_str:
++1:    sub     len, 1
++      retlt   0
++      ld.ub   r8, str++
++      cp.b    r8, r11
++      reteq   str
++      sub     r9, 1
++      brge    1b
++
++      rjmp    .Laligned_search
+diff -Nrup a/libc/string/avr32/memcmp.S b/libc/string/avr32/memcmp.S
+--- a/libc/string/avr32/memcmp.S       1969-12-31 19:00:00.000000000 -0500
++++ b/libc/string/avr32/memcmp.S       2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,50 @@
++/*
++ * Copyright (C) 2004 Atmel Norway.
++ */
++
++#define s1 r12
++#define s2 r11
++#define len r10
++
++      .text
++      .global memcmp
++      .type   memcmp, @function
++      .align  1
++memcmp:
++      sub     len, 4
++      brlt    .Lless_than_4
++
++1:    ld.w    r8, s1++
++      ld.w    r9, s2++
++      cp.w    r8, r9
++      brne    .Lfound_word
++      sub     len, 4
++      brge    1b
++
++.Lless_than_4:
++      sub     len, -4
++      reteq   0
++
++1:    ld.ub   r8, s1++
++      ld.ub   r9, s2++
++      sub     r8, r9
++      retne   r8
++      sub     len, 1
++      brgt    1b
++
++      retal   0
++
++.Lfound_word:
++      psub.b  r9, r8, r9
++      bfextu  r8, r9, 24, 8
++      retne   r8
++      bfextu  r8, r9, 16, 8
++      retne   r8
++      bfextu  r8, r9, 8, 8
++      retne   r8
++      retal   r9
++
++      .size   memcmp, . - memcmp
++
++      .weak   bcmp
++      bcmp = memcmp
+diff -Nrup a/libc/string/avr32/memcpy.S b/libc/string/avr32/memcpy.S
+--- a/libc/string/avr32/memcpy.S       1969-12-31 19:00:00.000000000 -0500
++++ b/libc/string/avr32/memcpy.S       2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,110 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++/* Don't use r12 as dst since we must return it unmodified */
++#define dst r9
++#define src r11
++#define len r10
++
++      .text
++      .global memcpy
++      .type   memcpy, @function
++
++      .global __memcpy
++      .hidden __memcpy
++      .type   __memcpy, @function
++memcpy:
++__memcpy:
++      pref    src[0]
++      mov     dst, r12
++
++      /* If we have less than 32 bytes, don't do anything fancy */
++      cp.w    len, 32
++      brge    .Lmore_than_31
++
++      sub     len, 1
++      retlt   r12
++1:    ld.ub   r8, src++
++      st.b    dst++, r8
++      sub     len, 1
++      brge    1b
++      retal   r12
++
++.Lmore_than_31:
++      pushm   r0-r7, lr
++
++      /* Check alignment */
++      mov     r8, src
++      andl    r8, 31, COH
++      brne    .Lunaligned_src
++      mov     r8, dst
++      andl    r8, 3, COH
++      brne    .Lunaligned_dst
++
++.Laligned_copy:
++      sub     len, 32
++      brlt    .Lless_than_32
++
++1:    /* Copy 32 bytes at a time */
++      ldm     src, r0-r7
++      sub     src, -32
++      stm     dst, r0-r7
++      sub     dst, -32
++      sub     len, 32
++      brge    1b
++
++.Lless_than_32:
++      /* Copy 16 more bytes if possible */
++      sub     len, -16
++      brlt    .Lless_than_16
++      ldm     src, r0-r3
++      sub     src, -16
++      sub     len, 16
++      stm     dst, r0-r3
++      sub     dst, -16
++
++.Lless_than_16:
++      /* Do the remaining as byte copies */
++      neg     len
++      add     pc, pc, len << 2
++      .rept   15
++      ld.ub   r0, src++
++      st.b    dst++, r0
++      .endr
++
++      popm    r0-r7, pc
++
++.Lunaligned_src:
++      /* Make src cacheline-aligned. r8 = (src & 31) */
++      rsub    r8, r8, 32
++      sub     len, r8
++1:    ld.ub   r0, src++
++      st.b    dst++, r0
++      sub     r8, 1
++      brne    1b
++
++      /* If dst is word-aligned, we're ready to go */
++      pref    src[0]
++      mov     r8, 3
++      tst     dst, r8
++      breq    .Laligned_copy
++
++.Lunaligned_dst:
++      /* src is aligned, but dst is not. Expect bad performance */
++      sub     len, 4
++      brlt    2f
++1:    ld.w    r0, src++
++      st.w    dst++, r0
++      sub     len, 4
++      brge    1b
++
++2:    neg     len
++      add     pc, pc, len << 2
++      .rept   3
++      ld.ub   r0, src++
++      st.b    dst++, r0
++      .endr
++
++      popm    r0-r7, pc
++      .size   memcpy, . - memcpy
+diff -Nrup a/libc/string/avr32/memmove.S b/libc/string/avr32/memmove.S
+--- a/libc/string/avr32/memmove.S      1969-12-31 19:00:00.000000000 -0500
++++ b/libc/string/avr32/memmove.S      2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,114 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++#define dst r12
++#define src r11
++#define len r10
++
++      .text
++      .global memmove
++      .type   memmove, @function
++
++      .global __memmove
++      .hidden __memmove
++      .type   __memmove, @function
++memmove:
++__memmove:
++      cp.w    src, dst
++      brge    __memcpy
++
++      add     dst, len
++      add     src, len
++      pref    src[-1]
++
++      /*
++       * The rest is basically the same as in memcpy.S except that
++       * the direction is reversed.
++       */
++      cp.w    len, 32
++      brge    .Lmore_than_31
++
++      sub     len, 1
++      retlt   r12
++1:    ld.ub   r8, --src
++      st.b    --dst, r8
++      sub     len, 1
++      brge    1b
++      retal   r12
++
++.Lmore_than_31:
++      pushm   r0-r7, lr
++
++      /* Check alignment */
++      mov     r8, src
++      andl    r8, 31, COH
++      brne    .Lunaligned_src
++      mov     r8, r12
++      andl    r8, 3, COH
++      brne    .Lunaligned_dst
++
++.Laligned_copy:
++      sub     len, 32
++      brlt    .Lless_than_32
++
++1:    /* Copy 32 bytes at a time */
++      sub     src, 32
++      ldm     src, r0-r7
++      sub     dst, 32
++      sub     len, 32
++      stm     dst, r0-r7
++      brge    1b
++
++.Lless_than_32:
++      /* Copy 16 more bytes if possible */
++      sub     len, -16
++      brlt    .Lless_than_16
++      sub     src, 16
++      ldm     src, r0-r3
++      sub     dst, 16
++      sub     len, 16
++      stm     dst, r0-r3
++
++.Lless_than_16:
++      /* Do the remaining as byte copies */
++      sub     len, -16
++      breq    2f
++1:    ld.ub   r0, --src
++      st.b    --dst, r0
++      sub     len, 1
++      brne    1b
++
++2:    popm    r0-r7, pc
++
++.Lunaligned_src:
++      /* Make src cacheline-aligned. r8 = (src & 31) */
++      sub     len, r8
++1:    ld.ub   r0, --src
++      st.b    --dst, r0
++      sub     r8, 1
++      brne    1b
++
++      /* If dst is word-aligned, we're ready to go */
++      pref    src[-4]
++      mov     r8, 3
++      tst     dst, r8
++      breq    .Laligned_copy
++
++.Lunaligned_dst:
++      /* src is aligned, but dst is not. Expect bad performance */
++      sub     len, 4
++      brlt    2f
++1:    ld.w    r0, --src
++      st.w    --dst, r0
++      sub     len, 4
++      brge    1b
++
++2:    neg     len
++      add     pc, pc, len << 2
++      .rept   3
++      ld.ub   r0, --src
++      st.b    --dst, r0
++      .endr
++
++      popm    r0-r7, pc
+diff -Nrup a/libc/string/avr32/memset.S b/libc/string/avr32/memset.S
+--- a/libc/string/avr32/memset.S       1969-12-31 19:00:00.000000000 -0500
++++ b/libc/string/avr32/memset.S       2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,60 @@
++/*
++ * Copyright (C) 2004 Atmel Norway.
++ */
++
++#define s r12
++#define c r11
++#define n r10
++
++      .text
++      .global memset
++      .type   memset, @function
++
++      .global __memset
++      .hidden __memset
++      .type   __memset, @function
++
++      .align  1
++memset:
++__memset:
++      cp.w    n, 32
++      mov     r9, s
++      brge    .Llarge_memset
++
++      sub     n, 1
++      retlt   s
++1:    st.b    s++, c
++      sub     n, 1
++      brge    1b
++
++      retal   r9
++
++.Llarge_memset:
++      mov     r8, r11
++      mov     r11, 3
++      bfins   r8, r8, 8, 8
++      bfins   r8, r8, 16, 16
++      tst     s, r11
++      breq    2f
++
++1:    st.b    s++, r8
++      sub     n, 1
++      tst     s, r11
++      brne    1b
++
++2:    mov     r11, r9
++      mov     r9, r8
++      sub     n, 8
++
++3:    st.d    s++, r8
++      sub     n, 8
++      brge    3b
++
++      /* If we are done, n == -8 and we'll skip all st.b insns below */
++      neg     n
++      lsl     n, 1
++      add     pc, n
++      .rept   7
++      st.b    s++, r8
++      .endr
++      retal   r11
+diff -Nrup a/libc/string/avr32/strcat.S b/libc/string/avr32/strcat.S
+--- a/libc/string/avr32/strcat.S       1969-12-31 19:00:00.000000000 -0500
++++ b/libc/string/avr32/strcat.S       2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,95 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++#define s1 r9
++#define s2 r11
++
++      .text
++      .global strcat
++      .type   strcat, @function
++      .align  1
++strcat:
++      mov     s1, r12
++
++      /* Make sure s1 is word-aligned */
++      mov     r10, s1
++      andl    r10, 3, COH
++      breq    2f
++
++      add     pc, pc, r10 << 3
++      sub     r0, r0, 0       /* 4-byte nop */
++      ld.ub   r8, s1++
++      sub     r8, r8, 0
++      breq    2f
++      ld.ub   r8, s1++
++      sub     r8, r8, 0
++      breq    3f
++      ld.ub   r8, s1++
++      sub     r8, r8, 0
++      breq    4f
++
++      /* Find the end of the first string */
++5:    ld.w    r8, s1++
++      tnbz    r8
++      brne    5b
++
++      sub     s1, 4
++
++      bfextu  r10, r8, 24, 8
++      cp.w    r10, 0
++      breq    1f
++      sub     s1, -1
++      bfextu  r10, r8, 16, 8
++      cp.w    r10, 0
++      breq    2f
++      sub     s1, -1
++      bfextu  r10, r8, 8, 8
++      cp.w    r10, 0
++      breq    3f
++      sub     s1, -1
++      rjmp    4f
++
++      /* Now, append s2 */
++1:    ld.ub   r8, s2++
++      st.b    s1++, r8
++      cp.w    r8, 0
++      reteq   r12
++2:    ld.ub   r8, s2++
++      st.b    s1++, r8
++      cp.w    r8, 0
++      reteq   r12
++3:    ld.ub   r8, s2++
++      st.b    s1++, r8
++      cp.w    r8, 0
++      reteq   r12
++4:    ld.ub   r8, s2++
++      st.b    s1++, r8
++      cp.w    r8, 0
++      reteq   r12
++
++      /* Copy one word at a time */
++      ld.w    r8, s2++
++      tnbz    r8
++      breq    2f
++1:    st.w    r8, s2++
++      ld.w    r8, s2++
++      tnbz    r8
++      brne    1b
++
++      /* Copy the remaining bytes */
++      bfextu  r10, r8, 24, 8
++      st.b    s1++, r10
++      cp.w    r10, 0
++      reteq   r12
++      bfextu  r10, r8, 16, 8
++      st.b    s1++, r10
++      cp.w    r10, 0
++      reteq   r12
++      bfextu  r10, r8, 8, 8
++      st.b    s1++, r10
++      cp.w    r10, 0
++      reteq   r12
++      st.b    s1++, r8
++      retal   r12
++      .size   strcat, . - strcat
+diff -Nrup a/libc/string/avr32/strcmp.S b/libc/string/avr32/strcmp.S
+--- a/libc/string/avr32/strcmp.S       1969-12-31 19:00:00.000000000 -0500
++++ b/libc/string/avr32/strcmp.S       2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,80 @@
++/*
++ * Copyright (C) 2004 Atmel Norway.
++ */
++
++#define s1 r12
++#define s2 r11
++#define len r10
++
++      .text
++      .global strcmp
++      .type   strcmp, @function
++      .align  1
++strcmp:
++      mov     r8, 3
++      tst     s1, r8
++      brne    .Lunaligned_s1
++      tst     s2, r8
++      brne    .Lunaligned_s2
++
++1:    ld.w    r8, s1++
++      ld.w    r9, s2++
++      cp.w    r8, r9
++      brne    2f
++      tnbz    r8
++      brne    1b
++      retal   0
++
++2:    bfextu  r12, r8, 24, 8
++      bfextu  r11, r9, 24, 8
++      sub     r12, r11
++      retne   r12
++      cp.w    r11, 0
++      reteq   0
++      bfextu  r12, r8, 16, 8
++      bfextu  r11, r9, 16, 8
++      sub     r12, r11
++      retne   r12
++      cp.w    r11, 0
++      reteq   0
++      bfextu  r12, r8, 8, 8
++      bfextu  r11, r9, 8, 8
++      sub     r12, r11
++      retne   r12
++      cp.w    r11, 0
++      reteq   0
++      bfextu  r12, r8, 0, 8
++      bfextu  r11, r9, 0, 8
++      sub     r12, r11
++      retal   r12
++
++.Lunaligned_s1:
++3:    tst     s1, r8
++      breq    4f
++      ld.ub   r10, s1++
++      ld.ub   r9, s2++
++      sub     r10, r9
++      retne   r10
++      cp.w    r9, 0
++      brne    3b
++      retal   r10
++
++4:    tst     s2, r8
++      breq    1b
++
++.Lunaligned_s2:
++      /*
++       * s1 and s2 can't both be aligned, and unaligned word loads
++       * can trigger spurious exceptions if we cross a page boundary.
++       * Do it the slow way...
++       */
++1:    ld.ub   r8, s1++
++      ld.ub   r9, s2++
++      sub     r8, r9
++      retne   r8
++      cp.w    r9, 0
++      brne    1b
++      retal   0
++
++      .weak   strcoll
++      strcoll = strcmp
+diff -Nrup a/libc/string/avr32/strcpy.S b/libc/string/avr32/strcpy.S
+--- a/libc/string/avr32/strcpy.S       1969-12-31 19:00:00.000000000 -0500
++++ b/libc/string/avr32/strcpy.S       2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,63 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ *
++ * To reduce the size, this one might simply call strncpy with len = -1.
++ */
++
++#define dst r9
++#define src r11
++
++      .text
++      .global strcpy
++      .type   strcpy, @function
++strcpy:
++      mov     dst, r12
++
++      pref    src[0]
++
++      /*
++       * Check alignment. If src is aligned but dst isn't, we can't
++       * do much about it...
++       */
++      mov     r8, src
++      andl    r8, 3 COH
++      brne    .Lunaligned_src
++
++.Laligned_copy:
++1:    ld.w    r8, src++
++      tnbz    r8
++      breq    2f
++      st.w    dst++, r8
++      rjmp    1b
++
++2:    /*
++       * Ok, r8 now contains the terminating '\0'. Copy the
++       * remaining bytes individually.
++       */
++      bfextu  r10, r8, 24, 8
++      st.b    dst++, r10
++      cp.w    r10, 0
++      reteq   r12
++      bfextu  r10, r8, 16, 8
++      st.b    dst++, r10
++      cp.w    r10, 0
++      reteq   r12
++      bfextu  r10, r8, 8, 8
++      st.b    dst++, r10
++      cp.w    r10, 0
++      reteq   r12
++      st.b    dst++, r8
++      retal   r12
++
++.Lunaligned_src:
++      /* Copy bytes until we're aligned */
++      rsub    r8, r8, 4
++      add     pc, pc, r8 << 3
++      nop
++      nop
++      ld.ub   r10, src++
++      st.b    dst++, r10
++      cp.w    r10, 0
++      reteq   r12
++
++      rjmp    .Laligned_copy
+diff -Nrup a/libc/string/avr32/stringtest.c b/libc/string/avr32/stringtest.c
+--- a/libc/string/avr32/stringtest.c   1969-12-31 19:00:00.000000000 -0500
++++ b/libc/string/avr32/stringtest.c   2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,144 @@
++
++#include <stdio.h>
++#include <string.h>
++#include <time.h>
++#include <sys/mman.h>
++
++#define BUF_SIZE (8 * 1024)
++
++static char *buf1;
++static char *buf1_ref;
++static char *buf2;
++
++extern void *optimized_memcpy(void *dest, void *src, size_t len);
++extern void *optimized_memmove(void *dest, void *src, size_t len);
++extern char *optimized_strcpy(char *dest, char *src);
++extern char *optimized_strncpy(char *dest, char *src, size_t len);
++
++void dump_mismatch(char *buf, char *ref, size_t len)
++{
++      int i, j;
++
++      for (i = 0; i < len; i += 16) {
++              if (memcmp(buf + i, ref + i, 16) == 0)
++                      continue;
++
++              printf("%4x buf:", i);
++              for (j = i; j < (i + 16); j++)
++                      printf(" %02x", buf[j]);
++              printf("\n     ref:");
++              for (j = i; j < (i + 16); j++)
++                      printf(" %02x", ref[j]);
++              printf("\n");
++      }
++}
++
++static void test_memcpy(int src_offset, int dst_offset, int len)
++{
++      clock_t start, old, new;
++      int i;
++
++      memset(buf1, 0x55, BUF_SIZE);
++      memset(buf1_ref, 0x55, BUF_SIZE);
++      memset(buf2, 0xaa, BUF_SIZE);
++
++      printf("Testing memcpy with offsets %d => %d and len %d...",
++             src_offset, dst_offset, len);
++
++      start = clock();
++      for (i = 0; i < 8192; i++)
++              optimized_memcpy(buf1 + dst_offset, buf2 + src_offset, len);
++      new = clock() - start;
++      start = clock();
++      for ( i = 0; i < 8192; i++)
++              memcpy(buf1_ref + dst_offset, buf2 + src_offset, len);
++      old = clock() - start;
++
++      if (memcmp(buf1, buf1_ref, BUF_SIZE) == 0)
++              printf("OK\n");
++      else {
++              printf("FAILED\n");
++              dump_mismatch(buf1, buf1_ref, BUF_SIZE);
++      }
++      printf("CPU time used: %d vs. %d\n", new, old);
++}
++
++static void test_memmove(int src_offset, int dst_offset, int len)
++{
++      clock_t start, old, new;
++
++      memset(buf1, 0x55, BUF_SIZE);
++      memset(buf1_ref, 0x55, BUF_SIZE);
++      memset(buf2, 0xaa, BUF_SIZE);
++
++      printf("Testing memmove with offsets %d => %d and len %d...",
++             src_offset, dst_offset, len);
++
++      start = clock();
++      optimized_memmove(buf1 + dst_offset, buf2 + src_offset, len);
++      new = clock() - start;
++      start = clock();
++      memmove(buf1_ref + dst_offset, buf2 + src_offset, len);
++      old = clock() - start;
++
++      if (memcmp(buf1, buf1_ref, BUF_SIZE) == 0)
++              printf("OK\n");
++      else {
++              printf("FAILED\n");
++              dump_mismatch(buf1, buf1_ref, BUF_SIZE);
++      }
++      printf("CPU time used: %d vs. %d\n", new, old);
++}
++
++int main(int argc, char *argv[])
++{
++      buf2 = mmap(NULL, BUF_SIZE, PROT_READ | PROT_WRITE,
++                  MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
++      if (buf2 == MAP_FAILED) {
++              perror("Failed to allocate memory for buf2");
++              return 1;
++      }
++      buf1 = mmap(NULL, BUF_SIZE, PROT_READ | PROT_WRITE,
++                  MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
++      if (buf1 == MAP_FAILED) {
++              perror("Failed to allocate memory for buf1");
++              return 1;
++      }
++      buf1_ref = mmap(NULL, BUF_SIZE, PROT_READ | PROT_WRITE,
++                      MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
++      if (buf1_ref == MAP_FAILED) {
++              perror("Failed to allocate memory for buf1_ref");
++              return 1;
++      }
++      printf("\n === MEMCPY ===\n\n");
++
++      test_memcpy(0, 0, BUF_SIZE - 32);
++      test_memcpy(0, 0, 1);
++      test_memcpy(0, 0, 31);
++      test_memcpy(0, 0, 32);
++      test_memcpy(0, 0, 127);
++      test_memcpy(0, 0, 128);
++      test_memcpy(4, 4, BUF_SIZE - 32 - 4);
++      test_memcpy(1, 1, BUF_SIZE - 32 - 1);
++      test_memcpy(1, 1, 126);
++      test_memcpy(0, 3, 128);
++      test_memcpy(1, 4, 128);
++      test_memcpy(0, 0, 0);
++
++      printf("\n === MEMMOVE ===\n\n");
++
++      test_memmove(0, 0, BUF_SIZE - 32);
++      test_memmove(0, 0, 1);
++      test_memmove(0, 0, 31);
++      test_memmove(0, 0, 32);
++      test_memmove(0, 0, BUF_SIZE - 33);
++      test_memmove(0, 0, 128);
++      test_memmove(4, 4, BUF_SIZE - 32 - 4);
++      test_memmove(1, 1, BUF_SIZE - 32 - 1);
++      test_memmove(1, 1, BUF_SIZE - 130);
++      test_memmove(0, 3, BUF_SIZE - 128);
++      test_memmove(1, 4, BUF_SIZE - 128);
++      test_memmove(0, 0, 0);
++
++      return 0;
++}
+diff -Nrup a/libc/string/avr32/strlen.S b/libc/string/avr32/strlen.S
+--- a/libc/string/avr32/strlen.S       1969-12-31 19:00:00.000000000 -0500
++++ b/libc/string/avr32/strlen.S       2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,52 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++#define str r12
++
++      .text
++      .global strlen
++      .type   strlen, @function
++strlen:
++      mov     r11, r12
++
++      mov     r9, str
++      andl    r9, 3, COH
++      brne    .Lunaligned_str
++
++1:    ld.w    r8, str++
++      tnbz    r8
++      brne    1b
++
++      sub     r12, r11
++      bfextu  r9, r8, 24, 8
++      cp.w    r9, 0
++      subeq   r12, 4
++      reteq   r12
++      bfextu  r9, r8, 16, 8
++      cp.w    r9, 0
++      subeq   r12, 3
++      reteq   r12
++      bfextu  r9, r8, 8, 8
++      cp.w    r9, 0
++      subeq   r12, 2
++      reteq   r12
++      sub     r12, 1
++      retal   r12
++
++.Lunaligned_str:
++      add     pc, pc, r9 << 3
++      sub     r0, r0, 0       /* 4-byte nop */
++      ld.ub   r8, str++
++      sub     r8, r8, 0
++      breq    1f
++      ld.ub   r8, str++
++      sub     r8, r8, 0
++      breq    1f
++      ld.ub   r8, str++
++      sub     r8, r8, 0
++      brne    1b
++
++1:    sub     r12, 1
++      sub     r12, r11
++      retal   r12
+diff -Nrup a/libc/string/avr32/strncpy.S b/libc/string/avr32/strncpy.S
+--- a/libc/string/avr32/strncpy.S      1969-12-31 19:00:00.000000000 -0500
++++ b/libc/string/avr32/strncpy.S      2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,77 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++#define dst r9
++#define src r11
++
++      .text
++      .global strcpy
++      .type   strncpy, @function
++strncpy:
++      mov     dst, r12
++
++      pref    src[0]
++      mov     dst, r12
++
++      /*
++       * Check alignment. If src is aligned but dst isn't, we can't
++       * do much about it...
++       */
++      mov     r8, src
++      andl    r8, 3 COH
++      brne    .Lunaligned_src
++
++.Laligned_copy:
++      sub     r10, 4
++      brlt    3f
++1:    ld.w    r8, src++
++      tnbz    r8
++      breq    2f
++      st.w    dst++, r8
++      sub     r10, 4
++      brne    1b
++
++3:    sub     r10, -4
++      reteq   r12
++
++      /* This is safe as long as src is word-aligned and r10 > 0 */
++      ld.w    r8, src++
++
++2:    /*
++       * Ok, r8 now contains the terminating '\0'. Copy the
++       * remaining bytes individually.
++       */
++      bfextu  r11, r8, 24, 8
++      st.b    dst++, r11
++      cp.w    r11, 0
++      reteq   r12
++      sub     r10, 1
++      reteq   r12
++      bfextu  r11, r8, 16, 8
++      st.b    dst++, r11
++      cp.w    r11, 0
++      reteq   r12
++      sub     r10, 1
++      reteq   r12
++      bfextu  r11, r8, 8, 8
++      st.b    dst++, r11
++      cp.w    r11, 0
++      reteq   r12
++      sub     r10, 1
++      reteq   r12
++      st.b    dst++, r8
++      retal   r12
++
++.Lunaligned_src:
++      /* Copy bytes until we're aligned */
++      min     r8, r8, r10
++      sub     r10, r8
++      sub     r8, 1
++      retlt   r12
++1:    ld.ub   r10, src++
++      st.b    dst++, r10
++      sub     r8, 1
++      brge    1b
++
++      rjmp    .Laligned_copy
+diff -Nrup a/libc/string/avr32/test_memcpy.c b/libc/string/avr32/test_memcpy.c
+--- a/libc/string/avr32/test_memcpy.c  1969-12-31 19:00:00.000000000 -0500
++++ b/libc/string/avr32/test_memcpy.c  2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,66 @@
++
++#include <stdio.h>
++#include <string.h>
++
++#define BUF_SIZE 32768
++
++static char buf1[BUF_SIZE] __attribute__((aligned(32)));
++static char buf1_ref[BUF_SIZE] __attribute__((aligned(32)));
++static char buf2[BUF_SIZE] __attribute__((aligned(32)));
++
++extern void *new_memcpy(void *dest, void *src, size_t len);
++
++void dump_mismatch(char *buf, char *ref, size_t len)
++{
++      int i, j;
++
++      for (i = 0; i < len; i += 16) {
++              if (memcmp(buf + i, ref + i, 16) == 0)
++                      continue;
++
++              printf("% 4x buf:", i);
++              for (j = i; j < (i + 16); j++)
++                      printf(" %02x", buf[j]);
++              printf("\n     ref:");
++              for (j = i; j < (i + 16); j++)
++                      printf(" %02x", ref[j]);
++              printf("\n");
++      }
++}
++
++void test(int src_offset, int dst_offset, int len)
++{
++      memset(buf1, 0x55, sizeof(buf1));
++      memset(buf1_ref, 0x55, sizeof(buf1_ref));
++      memset(buf2, 0xaa, sizeof(buf2));
++
++      printf("Testing with offsets %d => %d and len %d...",
++             src_offset, dst_offset, len);
++
++      new_memcpy(buf1 + dst_offset, buf2 + src_offset, len);
++      memcpy(buf1_ref + dst_offset, buf2 + src_offset, len);
++
++      if (memcmp(buf1, buf1_ref, sizeof(buf1)) == 0)
++              printf("OK\n");
++      else {
++              printf("FAILED\n");
++              dump_mismatch(buf1, buf1_ref, sizeof(buf1));
++      }
++}
++
++int main(int argc, char *argv[])
++{
++      test(0, 0, BUF_SIZE);
++      test(0, 0, 1);
++      test(0, 0, 31);
++      test(0, 0, 32);
++      test(0, 0, 127);
++      test(0, 0, 128);
++      test(4, 4, BUF_SIZE - 4);
++      test(1, 1, BUF_SIZE - 1);
++      test(1, 1, 126);
++      test(0, 3, 128);
++      test(1, 4, 128);
++
++      return 0;
++}
+diff -Nrup a/libc/sysdeps/linux/avr32/bits/atomicity.h b/libc/sysdeps/linux/avr32/bits/atomicity.h
+--- a/libc/sysdeps/linux/avr32/bits/atomicity.h        1969-12-31 19:00:00.000000000 -0500
++++ b/libc/sysdeps/linux/avr32/bits/atomicity.h        2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,86 @@
++/* Low-level functions for atomic operations.  AVR32 version.
++   Copyright (C) 1997, 1998, 1999, 2000 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.  */
++
++#ifndef _ATOMICITY_H
++#define _ATOMICITY_H 1
++
++#include <inttypes.h>
++
++static inline int
++__attribute__((unused))
++exchange_and_add (volatile uint32_t *mem, int val)
++{
++      int tmp, result;
++
++      __asm__ __volatile__(
++              "/* Inline exchange and add */\n"
++              "1:     ssrf    5\n"
++              "       ld.w    %0, %3\n"
++              "       add     %1, %0, %4\n"
++              "       stcond  %2, %1\n"
++              "       brne    1b"
++              : "=&r"(result), "=&r"(tmp), "=m"(*mem)
++              : "m"(*mem), "r"(val)
++              : "cc", "memory");
++
++      return result;
++}
++
++static inline void
++__attribute__((unused))
++atomic_add (volatile uin32_t *mem, int val)
++{
++      int result;
++
++      __asm__ __volatile__(
++              "/* Inline atomic add */\n"
++              "1:     ssrf    5\n"
++              "       ld.w    %0, %2\n"
++              "       add     %0, %3\n"
++              "       stcond  %2, %0\n"
++              "       brne    1b"
++              : "=&r"(result), "=m"(*mem)
++              : "m"(*mem), "r"(val)
++              : "cc", "memory");
++}
++
++static inline int
++__attribute__((unused))
++compare_and_swap(volatile long int *p, long int oldval, long int newval)
++{
++      long int result, tmp;
++
++      __asm__ __volatile__(
++              "/* Inline compare and swap */\n"
++              "1:     ssrf    5\n"
++              "       ld.w    %1, %3\n"
++              "       cp.w    %1, %5\n"
++              "       sreq    %0\n"
++              "       brne    2f\n"
++              "       stcond  %2, %4\n"
++              "       brne    1b\n"
++              "2:"
++              : "=&r"(result), "=&r"(tmp), "=m"(*p)
++              : "m"(*p), "r"(newval), "r"(oldval)
++              : "cc", "memory");
++
++      return result;
++}
++
++#endif /* atomicity.h */
+diff -Nrup a/libc/sysdeps/linux/avr32/bits/byteswap.h b/libc/sysdeps/linux/avr32/bits/byteswap.h
+--- a/libc/sysdeps/linux/avr32/bits/byteswap.h 1969-12-31 19:00:00.000000000 -0500
++++ b/libc/sysdeps/linux/avr32/bits/byteswap.h 2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,80 @@
++/* Macros to swap the order of bytes in integer values.
++   Copyright (C) 2005 Atmel Norway.
++
++   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.  */
++
++#if !defined _BYTESWAP_H && !defined _NETINET_IN_H
++# error "Never use <bits/byteswap.h> directly; include <byteswap.h> instead."
++#endif
++
++#ifndef _BITS_BYTESWAP_H
++#define _BITS_BYTESWAP_H 1
++
++/* Swap bytes in 16 bit value.  */
++#if defined __GNUC__
++# define __bswap_16(x) (__extension__ __builtin_bswap_16(x))
++#else
++/* This is better than nothing.  */
++static __inline unsigned short int
++__bswap_16 (unsigned short int __bsx)
++{
++      return ((((__bsx) >> 8) & 0xff) | (((__bsx) & 0xff) << 8));
++}
++#endif
++
++/* Swap bytes in 32 bit value.  */
++#if defined __GNUC__
++# define __bswap_32(x) (__extension__ __builtin_bswap_32(x))
++#else
++static __inline unsigned int
++__bswap_32 (unsigned int __bsx)
++{
++  return ((((__bsx) & 0xff000000) >> 24) | (((__bsx) & 0x00ff0000) >>  8) |
++        (((__bsx) & 0x0000ff00) <<  8) | (((__bsx) & 0x000000ff) << 24));
++}
++#endif
++
++#if defined __GNUC__
++/* Swap bytes in 64 bit value.  */
++# define __bswap_constant_64(x)                               \
++      ((((x) & 0xff00000000000000ull) >> 56)          \
++       | (((x) & 0x00ff000000000000ull) >> 40)        \
++       | (((x) & 0x0000ff0000000000ull) >> 24)        \
++       | (((x) & 0x000000ff00000000ull) >> 8)         \
++       | (((x) & 0x00000000ff000000ull) << 8)         \
++       | (((x) & 0x0000000000ff0000ull) << 24)        \
++       | (((x) & 0x000000000000ff00ull) << 40)        \
++       | (((x) & 0x00000000000000ffull) << 56))
++
++# define __bswap_64(x)                                                        \
++      (__extension__                                                  \
++       ({                                                             \
++               union {                                                \
++                       __extension__ unsigned long long int __ll;     \
++                       unsigned int __l[2];                           \
++               } __w, __r;                                            \
++               if (__builtin_constant_p(x))                           \
++                       __r.__ll = __bswap_constant_64(x);             \
++               else {                                                 \
++                       __w.__ll = (x);                                \
++                       __r.__l[0] = __bswap_32(__w.__l[1]);           \
++                       __r.__l[1] = __bswap_32(__w.__l[0]);           \
++               }                                                      \
++               __r.__ll;                                              \
++       }))
++#endif
++
++#endif /* _BITS_BYTESWAP_H */
+diff -Nrup a/libc/sysdeps/linux/avr32/bits/endian.h b/libc/sysdeps/linux/avr32/bits/endian.h
+--- a/libc/sysdeps/linux/avr32/bits/endian.h   1969-12-31 19:00:00.000000000 -0500
++++ b/libc/sysdeps/linux/avr32/bits/endian.h   2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,7 @@
++/* AVR32 is big-endian */
++
++#ifndef _ENDIAN_H
++# error "Never use <bits/endian.h> directly; include <endian.h> instead."
++#endif
++
++#define __BYTE_ORDER __BIG_ENDIAN
+diff -Nrup a/libc/sysdeps/linux/avr32/bits/fcntl.h b/libc/sysdeps/linux/avr32/bits/fcntl.h
+--- a/libc/sysdeps/linux/avr32/bits/fcntl.h    1969-12-31 19:00:00.000000000 -0500
++++ b/libc/sysdeps/linux/avr32/bits/fcntl.h    2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,168 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ *
++ * This file is part of the Linux kernel
++ */
++#ifndef _FCNTL_H
++# error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead."
++#endif
++
++#include <sys/types.h>
++
++/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
++   located on an ext2 file system */
++#define O_ACCMODE     00000003
++#define O_RDONLY      00000000
++#define O_WRONLY      00000001
++#define O_RDWR                00000002
++#define O_CREAT               00000100        /* not fcntl */
++#define O_EXCL                00000200        /* not fcntl */
++#define O_NOCTTY      00000400        /* not fcntl */
++#define O_TRUNC               00001000        /* not fcntl */
++#define O_APPEND      00002000
++#define O_NONBLOCK    00004000
++#define O_NDELAY      O_NONBLOCK
++#define O_SYNC                00010000
++#define O_ASYNC               00020000
++
++#ifdef __USE_GNU
++# define O_DIRECT     00040000        /* must be a directory */
++# define O_DIRECTORY  00200000        /* direct disk access */
++# define O_NOFOLLOW   00400000        /* don't follow links */
++# define O_NOATIME    01000000        /* don't set atime */
++#endif
++
++#ifdef __USE_LARGEFILE64
++# define O_LARGEFILE  00100000
++#endif
++
++/* For now Linux has synchronisity options for data and read operations.
++   We define the symbols here but let them do the same as O_SYNC since
++   this is a superset.        */
++#if defined __USE_POSIX199309 || defined __USE_UNIX98
++# define O_DSYNC      O_SYNC  /* Synchronize data.  */
++# define O_RSYNC      O_SYNC  /* Synchronize read operations.  */
++#endif
++
++#define F_DUPFD               0       /* dup */
++#define F_GETFD               1       /* get close_on_exec */
++#define F_SETFD               2       /* set/clear close_on_exec */
++#define F_GETFL               3       /* get file->f_flags */
++#define F_SETFL               4       /* set file->f_flags */
++
++#ifndef __USE_FILE_OFFSET64
++# define F_GETLK      5
++# define F_SETLK      6
++# define F_SETLKW     7
++#else
++# define F_GETLK      F_GETLK64
++# define F_SETLK      F_SETLK64
++# define F_SETLKW     F_SETLKW64
++#endif
++#define F_GETLK64     12      /*  using 'struct flock64' */
++#define F_SETLK64     13
++#define F_SETLKW64    14
++
++#if defined __USE_BSD || defined __USE_XOPEN2K
++# define F_SETOWN     8       /*  for sockets. */
++# define F_GETOWN     9       /*  for sockets. */
++#endif
++
++#ifdef __USE_GNU
++# define F_SETSIG     10      /*  for sockets. */
++# define F_GETSIG     11      /*  for sockets. */
++#endif
++
++#ifdef __USE_GNU
++# define F_SETLEASE   1024    /* Set a lease.  */
++# define F_GETLEASE   1025    /* Enquire what lease is active.  */
++# define F_NOTIFY     1026    /* Request notfications on a directory.  */
++#endif
++
++/* for F_[GET|SET]FL */
++#define FD_CLOEXEC    1       /* actually anything with low bit set goes */
++
++/* for posix fcntl() and lockf() */
++#define F_RDLCK               0
++#define F_WRLCK               1
++#define F_UNLCK               2
++
++/* for old implementation of bsd flock () */
++#define F_EXLCK               4       /* or 3 */
++#define F_SHLCK               8       /* or 4 */
++
++/* for leases */
++#define F_INPROGRESS  16
++
++#ifdef __USE_BSD
++/* operations for bsd flock(), also used by the kernel implementation */
++# define LOCK_SH      1       /* shared lock */
++# define LOCK_EX      2       /* exclusive lock */
++# define LOCK_NB      4       /* or'd with one of the above to prevent
++                                 blocking */
++# define LOCK_UN      8       /* remove lock */
++#endif
++
++#ifdef __USE_GNU
++# define LOCK_MAND    32      /* This is a mandatory flock */
++# define LOCK_READ    64      /* ... Which allows concurrent
++                                     read operations */
++# define LOCK_WRITE   128     /* ... Which allows concurrent
++                                     write operations */
++# define LOCK_RW      192     /* ... Which allows concurrent
++                                     read & write ops */
++#endif
++
++#ifdef __USE_GNU
++/* Types of directory notifications that may be requested with F_NOTIFY.  */
++# define DN_ACCESS    0x00000001      /* File accessed.  */
++# define DN_MODIFY    0x00000002      /* File modified.  */
++# define DN_CREATE    0x00000004      /* File created.  */
++# define DN_DELETE    0x00000008      /* File removed.  */
++# define DN_RENAME    0x00000010      /* File renamed.  */
++# define DN_ATTRIB    0x00000020      /* File changed attibutes.  */
++# define DN_MULTISHOT 0x80000000      /* Don't remove notifier.  */
++#endif
++
++struct flock {
++      short l_type;
++      short l_whence;
++#ifndef __USE_FILE_OFFSET64
++      __off_t l_start;
++      __off_t l_len;
++#else
++      __off64_t l_start;
++      __off64_t l_len;
++#endif
++      __pid_t l_pid;
++};
++
++#ifdef __USE_LARGEFILE64
++struct flock64 {
++      short  l_type;
++      short  l_whence;
++      __off64_t l_start;
++      __off64_t l_len;
++      __pid_t  l_pid;
++};
++#endif
++
++/* Define some more compatibility macros to be backward compatible with
++ *    BSD systems which did not managed to hide these kernel macros.  */
++#ifdef  __USE_BSD
++# define FAPPEND        O_APPEND
++# define FFSYNC         O_FSYNC
++# define FASYNC         O_ASYNC
++# define FNONBLOCK      O_NONBLOCK
++# define FNDELAY        O_NDELAY
++#endif /* Use BSD.  */
++
++/* Advise to `posix_fadvise'.  */
++#ifdef __USE_XOPEN2K
++# define POSIX_FADV_NORMAL      0 /* No further special treatment.  */
++# define POSIX_FADV_RANDOM      1 /* Expect random page references.  */
++# define POSIX_FADV_SEQUENTIAL  2 /* Expect sequential page references.  */
++# define POSIX_FADV_WILLNEED    3 /* Will need these pages.  */
++# define POSIX_FADV_DONTNEED    4 /* Don't need these pages.  */
++# define POSIX_FADV_NOREUSE     5 /* Data will be accessed once.  */
++#endif
+diff -Nrup a/libc/sysdeps/linux/avr32/bits/kernel_stat.h b/libc/sysdeps/linux/avr32/bits/kernel_stat.h
+--- a/libc/sysdeps/linux/avr32/bits/kernel_stat.h      1969-12-31 19:00:00.000000000 -0500
++++ b/libc/sysdeps/linux/avr32/bits/kernel_stat.h      2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,63 @@
++#ifndef _BITS_STAT_STRUCT_H
++#define _BITS_STAT_STRUCT_H
++
++/*
++ * This file provides struct stat, taken from kernel 2.6.4
++ * (include/asm-avr32/stat.h revision 1.1).
++ */
++
++struct kernel_stat {
++        unsigned long st_dev;
++        unsigned long st_ino;
++        unsigned short st_mode;
++        unsigned short st_nlink;
++        unsigned short st_uid;
++        unsigned short st_gid;
++        unsigned long  st_rdev;
++        unsigned long  st_size;
++        unsigned long  st_blksize;
++        unsigned long  st_blocks;
++        unsigned long  st_atime;
++        unsigned long  st_atime_nsec;
++        unsigned long  st_mtime;
++        unsigned long  st_mtime_nsec;
++        unsigned long  st_ctime;
++        unsigned long  st_ctime_nsec;
++        unsigned long  __unused4;
++        unsigned long  __unused5;
++};
++
++#define STAT_HAVE_NSEC 1
++
++struct kernel_stat64 {
++      unsigned long long st_dev;
++
++      unsigned long long st_ino;
++      unsigned int    st_mode;
++      unsigned int    st_nlink;
++
++      unsigned long   st_uid;
++      unsigned long   st_gid;
++
++      unsigned long long st_rdev;
++
++      long long       st_size;
++      unsigned long   __pad1;
++      unsigned long   st_blksize;
++
++      unsigned long long st_blocks;
++
++      unsigned long   st_atime;
++      unsigned long   st_atime_nsec;
++
++      unsigned long   st_mtime;
++      unsigned long   st_mtime_nsec;
++
++      unsigned long   st_ctime;
++      unsigned long   st_ctime_nsec;
++
++      unsigned long   __unused1;
++      unsigned long   __unused2;
++};
++
++#endif /* _BITS_STAT_STRUCT_H */
+diff -Nrup a/libc/sysdeps/linux/avr32/bits/kernel_types.h b/libc/sysdeps/linux/avr32/bits/kernel_types.h
+--- a/libc/sysdeps/linux/avr32/bits/kernel_types.h     1969-12-31 19:00:00.000000000 -0500
++++ b/libc/sysdeps/linux/avr32/bits/kernel_types.h     2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,56 @@
++/* Note that we use the exact same include guard #define names
++ * as asm/posix_types.h.  This will avoid gratuitous conflicts
++ * with the posix_types.h kernel header, and will ensure that
++ * our private content, and not the kernel header, will win.
++ *  -Erik
++ */
++#ifndef __ASM_AVR32_POSIX_TYPES_H
++#define __ASM_AVR32_POSIX_TYPES_H
++
++/*
++ * This file is generally used by user-level software, so you need to
++ * be a little careful about namespace pollution etc.  Also, we cannot
++ * assume GCC is being used.
++ */
++
++typedef unsigned long __kernel_dev_t;
++typedef unsigned long   __kernel_ino_t;
++typedef unsigned short  __kernel_mode_t;
++typedef unsigned short  __kernel_nlink_t;
++typedef long            __kernel_off_t;
++typedef int             __kernel_pid_t;
++typedef unsigned short  __kernel_ipc_pid_t;
++typedef unsigned int  __kernel_uid_t;
++typedef unsigned int  __kernel_gid_t;
++typedef unsigned long __kernel_size_t;
++typedef int             __kernel_ssize_t;
++typedef int             __kernel_ptrdiff_t;
++typedef long            __kernel_time_t;
++typedef long            __kernel_suseconds_t;
++typedef long            __kernel_clock_t;
++typedef int             __kernel_timer_t;
++typedef int             __kernel_clockid_t;
++typedef int             __kernel_daddr_t;
++typedef char *          __kernel_caddr_t;
++typedef unsigned short  __kernel_uid16_t;
++typedef unsigned short  __kernel_gid16_t;
++typedef unsigned int    __kernel_uid32_t;
++typedef unsigned int    __kernel_gid32_t;
++
++typedef unsigned short  __kernel_old_uid_t;
++typedef unsigned short  __kernel_old_gid_t;
++typedef unsigned short  __kernel_old_dev_t;
++
++#ifdef __GNUC__
++typedef long long       __kernel_loff_t;
++#endif
++
++typedef struct {
++#if defined(__USE_ALL)
++    int     val[2];
++#else
++    int     __val[2];
++#endif
++} __kernel_fsid_t;
++
++#endif /* __ASM_AVR32_POSIX_TYPES_H */
+diff -Nrup a/libc/sysdeps/linux/avr32/bits/machine-gmon.h b/libc/sysdeps/linux/avr32/bits/machine-gmon.h
+--- a/libc/sysdeps/linux/avr32/bits/machine-gmon.h     1969-12-31 19:00:00.000000000 -0500
++++ b/libc/sysdeps/linux/avr32/bits/machine-gmon.h     2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,69 @@
++/* Machine-dependent definitions for profiling support.  AVR32 version.
++   Copyright (C) 1996, 1997, 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 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.  */
++
++#define mcount_internal __mcount_internal
++
++#define _MCOUNT_DECL(frompc, selfpc) \
++static void __attribute((used)) mcount_internal(unsigned long frompc, unsigned long selfpc)
++
++/*
++ * This mcount implementation expects to get called after the prologue
++ * has been run. It also expects that r7 contains a valid frame
++ * pointer.
++ *
++ * When profiling, the compiler should generate something like this at
++ * each function entry:
++ *
++ *    pushm   r0-r7,lr        // lr mandatory, others optional
++ *    mov     r7, sp
++ *    // rest of prologue goes here
++ *    mcall   pc[.LC1 - .]
++ *      // rest of function goes here
++ * .LC1:
++ *    .long   mcount
++ *
++ * or for PIC:
++ *
++ *    pushm   r0-r7,lr
++ *    mov     r7, sp
++ *    // rest of prologue goes here
++ *    lddpc   r0, .LC1
++ * .L1: rsub  r0, pc
++ *    mcall   r0[mcount@GOT]
++ *    // rest of function goes here
++ * .LC1:
++ *    .long   .L1 - _GLOBAL_OFFSET_TABLE_
++ *
++ * This way, when mcount() is called, r7 points to the calling
++ * function's return address. It is guaranteed that calling mcount
++ * will clobber no registers except LR, which is unavoidable.
++ */
++#define MCOUNT asm(                           \
++      "       .align  4\n"                    \
++      "       .global _mcount\n"              \
++      "       .type   _mcount,@function\n"    \
++      "_mcount:\n"                            \
++      "       pushm   r8-r12,lr\n"            \
++      "       mov     r11, lr\n"              \
++      "       ld.w    r12, r7[0]\n"           \
++      "       rcall   __mcount_internal\n"    \
++      "       popm    r8-r12,pc\n"            \
++      "       .size   _mcount, . - _mcount\n" \
++      "       .weak   mcount\n"               \
++      "       mcount = _mcount");
+diff -Nrup a/libc/sysdeps/linux/avr32/bits/mman.h b/libc/sysdeps/linux/avr32/bits/mman.h
+--- a/libc/sysdeps/linux/avr32/bits/mman.h     1969-12-31 19:00:00.000000000 -0500
++++ b/libc/sysdeps/linux/avr32/bits/mman.h     2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,95 @@
++/* Definitions for POSIX memory map interface.  Linux/AVR32 version.
++   Copyright (C) 1997, 2000 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.  */
++
++#ifndef _SYS_MMAN_H
++# error "Never include this file directly.  Use <sys/mman.h> instead"
++#endif
++
++/* The following definitions basically come from the kernel headers.
++   But the kernel header is not namespace clean.  */
++
++
++/* Protections are chosen from these bits, OR'd together.  The
++   implementation does not necessarily support PROT_EXEC or PROT_WRITE
++   without PROT_READ.  The only guarantees are that no writing will be
++   allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */
++
++#define PROT_READ     0x1             /* Page can be read.  */
++#define PROT_WRITE    0x2             /* Page can be written.  */
++#define PROT_EXEC     0x4             /* Page can be executed.  */
++#define PROT_NONE     0x0             /* Page can not be accessed.  */
++
++/* Sharing types (must choose one and only one of these).  */
++#define MAP_SHARED    0x01            /* Share changes.  */
++#define MAP_PRIVATE   0x02            /* Changes are private.  */
++#ifdef __USE_MISC
++# define MAP_TYPE     0x0f            /* Mask for type of mapping.  */
++#endif
++
++/* Other flags.  */
++#define MAP_FIXED     0x10            /* Interpret addr exactly.  */
++#ifdef __USE_MISC
++# define MAP_FILE     0
++# define MAP_ANONYMOUS        0x20            /* Don't use a file.  */
++# define MAP_ANON     MAP_ANONYMOUS
++#endif
++
++/* These are Linux-specific.  */
++#ifdef __USE_MISC
++# define MAP_GROWSDOWN        0x0100          /* Stack-like segment.  */
++# define MAP_DENYWRITE        0x0800          /* ETXTBSY */
++# define MAP_EXECUTABLE       0x1000          /* Mark it as an executable.  */
++# define MAP_LOCKED   0x2000          /* Lock the mapping.  */
++# define MAP_NORESERVE        0x4000          /* Don't check for reservations.  */
++# define MAP_POPULATE 0x8000          /* populate (prefault) pagetables */
++# define MAP_NONBLOCK 0x10000         /* do not block on IO */
++#endif
++
++/* Flags to `msync'.  */
++#define MS_ASYNC      1               /* Sync memory asynchronously.  */
++#define MS_SYNC               4               /* Synchronous memory sync.  */
++#define MS_INVALIDATE 2               /* Invalidate the caches.  */
++
++/* Flags for `mlockall'.  */
++#define MCL_CURRENT   1               /* Lock all currently mapped pages.  */
++#define MCL_FUTURE    2               /* Lock all additions to address
++                                         space.  */
++
++/* Flags for `mremap'.  */
++#ifdef __USE_GNU
++# define MREMAP_MAYMOVE       1
++#endif
++
++/* Advise to `madvise'.  */
++#ifdef __USE_BSD
++# define MADV_NORMAL   0      /* No further special treatment.  */
++# define MADV_RANDOM   1      /* Expect random page references.  */
++# define MADV_SEQUENTIAL 2    /* Expect sequential page references.  */
++# define MADV_WILLNEED         3      /* Will need these pages.  */
++# define MADV_DONTNEED         4      /* Don't need these pages.  */
++#endif
++
++/* The POSIX people had to invent similar names for the same things.  */
++#ifdef __USE_XOPEN2K
++# define POSIX_MADV_NORMAL    0 /* No further special treatment.  */
++# define POSIX_MADV_RANDOM    1 /* Expect random page references.  */
++# define POSIX_MADV_SEQUENTIAL        2 /* Expect sequential page references.  */
++# define POSIX_MADV_WILLNEED  3 /* Will need these pages.  */
++# define POSIX_MADV_DONTNEED  4 /* Don't need these pages.  */
++#endif
+diff -Nrup a/libc/sysdeps/linux/avr32/bits/profil-counter.h b/libc/sysdeps/linux/avr32/bits/profil-counter.h
+--- a/libc/sysdeps/linux/avr32/bits/profil-counter.h   1969-12-31 19:00:00.000000000 -0500
++++ b/libc/sysdeps/linux/avr32/bits/profil-counter.h   2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,26 @@
++/* Low-level statistical profiling support function.  Linux/AVR32 version.
++   Copyright (C) 1996, 1997, 1998, 2002 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 <signal.h>
++
++void
++profil_counter(int signo, siginfo_t *si, struct sigcontext *sc)
++{
++      profil_count((void *)sc->pc);
++}
+diff -Nrup a/libc/sysdeps/linux/avr32/bits/setjmp.h b/libc/sysdeps/linux/avr32/bits/setjmp.h
+--- a/libc/sysdeps/linux/avr32/bits/setjmp.h   1969-12-31 19:00:00.000000000 -0500
++++ b/libc/sysdeps/linux/avr32/bits/setjmp.h   2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,21 @@
++/*
++ * Copyright (C) 2004-2005 Atmel Norway
++ */
++#ifndef _SETJMP_H
++# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
++#endif
++
++#ifndef _ASM
++/*
++ * The jump buffer contains r0-r7, sr, sp and lr. Other registers are
++ * not saved.
++ */
++typedef int __jmp_buf[11];
++#endif
++
++#define __JMP_BUF_SP  4
++
++/* Test if longjmp to JMPBUF would unwind the frame containing a local
++   variable at ADDRESS.  */
++#define _JMPBUF_UNWINDS(jmpbuf, address) \
++  ((void *)(address) < (void *)(jmpbuf[__JMP_BUF_SP]))
+diff -Nrup a/libc/sysdeps/linux/avr32/bits/syscalls.h b/libc/sysdeps/linux/avr32/bits/syscalls.h
+--- a/libc/sysdeps/linux/avr32/bits/syscalls.h 1969-12-31 19:00:00.000000000 -0500
++++ b/libc/sysdeps/linux/avr32/bits/syscalls.h 2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,143 @@
++#ifndef _SYSCALL_H
++# error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead."
++#endif
++
++/*
++ * This includes the `__NR_<name>' syscall numbers taken from the
++ * Linux kernel header files. It also defines the traditional
++ * `SYS_<name>' macros for older programs.
++ */
++#include <bits/sysnum.h>
++
++#ifndef __set_errno
++# define __set_errno(val) (*__errno_location()) = (val)
++#endif
++#ifndef SYS_ify
++# define SYS_ify(syscall_name) (__NR_##syscall_name)
++#endif
++
++#ifndef __ASSEMBLER__
++
++#undef _syscall0
++#define _syscall0(type,name)                          \
++      type name(void)                                 \
++      {                                               \
++              return (type)(INLINE_SYSCALL(name, 0)); \
++      }
++
++#undef _syscall1
++#define _syscall1(type,name,type1,arg1)                               \
++      type name(type1 arg1)                                   \
++      {                                                       \
++              return (type)(INLINE_SYSCALL(name, 1, arg1));   \
++      }
++
++#undef _syscall2
++#define _syscall2(type,name,type1,arg1,type2,arg2)                    \
++      type name(type1 arg1, type2 arg2)                               \
++      {                                                               \
++              return (type)(INLINE_SYSCALL(name, 2, arg1, arg2));     \
++      }
++
++#undef _syscall3
++#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)         \
++      type name(type1 arg1, type2 arg2, type3 arg3)                   \
++      {                                                               \
++              return (type)(INLINE_SYSCALL(name, 3, arg1,             \
++                                           arg2, arg3));              \
++      }
++
++#undef _syscall4
++#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,         \
++                type4,arg4)                                           \
++      type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4)       \
++      {                                                               \
++              return (type)(INLINE_SYSCALL(name, 4, arg1, arg2,       \
++                                           arg3, arg4));              \
++      }
++
++#undef _syscall5
++#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,         \
++                type4,arg4,type5,arg5)                                \
++      type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4,       \
++                type5 arg5)                                           \
++      {                                                               \
++              return (type)(INLINE_SYSCALL(name, 5, arg1, arg2,       \
++                                           arg3, arg4, arg5));        \
++      }
++
++#undef _syscall6
++#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,         \
++                type4,arg4,type5,arg5,type6,arg6)                     \
++      type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4,       \
++                type5 arg5, type6 arg6)                               \
++      {                                                               \
++              return (type)(INLINE_SYSCALL(name, 6, arg1, arg2, arg3, \
++                                           arg4, arg5, arg6));        \
++      }
++
++#undef unlikely
++#define unlikely(x) __builtin_expect((x), 0)
++
++#undef INLINE_SYSCALL
++#define INLINE_SYSCALL(name, nr, args...)                             \
++      ({                                                              \
++              unsigned _sys_result = INTERNAL_SYSCALL(name, , nr, args); \
++              if (unlikely(INTERNAL_SYSCALL_ERROR_P(_sys_result, ))) { \
++                      __set_errno(INTERNAL_SYSCALL_ERRNO(_sys_result, )); \
++                      _sys_result = (unsigned int) -1;                \
++              }                                                       \
++              (int) _sys_result;                                      \
++      })
++
++#undef INTERNAL_SYSCALL_DECL
++#define INTERNAL_SYSCALL_DECL(err) do { } while(0)
++
++#undef INTERNAL_SYSCALL
++#define INTERNAL_SYSCALL(name, err, nr, args...)                      \
++      ({                                                              \
++              register int _a1 asm ("r12");                           \
++              register int _scno asm("r8") = SYS_ify(name);           \
++              LOAD_ARGS_##nr (args);                                  \
++              asm volatile ("scall    /* syscall " #name " */"        \
++                            : "=r" (_a1)                              \
++                            : "r"(_scno) ASM_ARGS_##nr                \
++                            : "lr", "cc", "memory");                  \
++              _a1;                                                    \
++      })
++
++#undef INTERNAL_SYSCALL_ERROR_P
++#define INTERNAL_SYSCALL_ERROR_P(val, err)            \
++      ((unsigned int)(val) >= 0xfffff001U)
++
++#undef INTERNAL_SYSCALL_ERRNO
++#define INTERNAL_SYSCALL_ERRNO(val, errr) (-(val))
++
++#define LOAD_ARGS_0() do { } while(0)
++#define ASM_ARGS_0
++#define LOAD_ARGS_1(a1)                                       \
++      _a1 = (int) (a1);                               \
++      LOAD_ARGS_0()
++#define ASM_ARGS_1    ASM_ARGS_0, "r"(_a1)
++#define LOAD_ARGS_2(a1, a2)                           \
++      register int _a2 asm("r11") = (int)(a2);        \
++      LOAD_ARGS_1(a1)
++#define ASM_ARGS_2    ASM_ARGS_1, "r"(_a2)
++#define LOAD_ARGS_3(a1, a2, a3)                               \
++      register int _a3 asm("r10") = (int)(a3);        \
++      LOAD_ARGS_2(a1, a2)
++#define ASM_ARGS_3    ASM_ARGS_2, "r"(_a3)
++#define LOAD_ARGS_4(a1, a2, a3, a4)                   \
++      register int _a4 asm("r9") = (int)(a4);         \
++      LOAD_ARGS_3(a1, a2, a3)
++#define ASM_ARGS_4    ASM_ARGS_3, "r"(_a4)
++#define LOAD_ARGS_5(a1, a2, a3, a4, a5)                       \
++      register int _a5 asm("r5") = (int)(a5);         \
++      LOAD_ARGS_4(a1, a2, a3, a4)
++#define ASM_ARGS_5    ASM_ARGS_4, "r"(_a5)
++#define LOAD_ARGS_6(a1, a2, a3, a4, a5, a6)           \
++      register int _a6 asm("r3") = (int)(a6);         \
++      LOAD_ARGS_5(a1, a2, a3, a4, a5)
++#define ASM_ARGS_6    ASM_ARGS_5, "r"(_a6)
++
++#endif /* __ASSEMBLER__ */
+diff -Nrup a/libc/sysdeps/linux/avr32/bits/wordsize.h b/libc/sysdeps/linux/avr32/bits/wordsize.h
+--- a/libc/sysdeps/linux/avr32/bits/wordsize.h 1969-12-31 19:00:00.000000000 -0500
++++ b/libc/sysdeps/linux/avr32/bits/wordsize.h 2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1 @@
++#define __WORDSIZE    32
+diff -Nrup a/libc/sysdeps/linux/avr32/brk.c b/libc/sysdeps/linux/avr32/brk.c
+--- a/libc/sysdeps/linux/avr32/brk.c   1969-12-31 19:00:00.000000000 -0500
++++ b/libc/sysdeps/linux/avr32/brk.c   2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,23 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ */
++#include <errno.h>
++#include <sys/syscall.h>
++
++void *__curbrk = 0;
++
++int brk (void *addr)
++{
++      void *newbrk;
++
++      newbrk = INLINE_SYSCALL(brk, 1, addr);
++
++      __curbrk = newbrk;
++
++      if (newbrk < addr) {
++              __set_errno (ENOMEM);
++              return -1;
++      }
++
++      return 0;
++}
+diff -Nrup a/libc/sysdeps/linux/avr32/bsd-_setjmp.S b/libc/sysdeps/linux/avr32/bsd-_setjmp.S
+--- a/libc/sysdeps/linux/avr32/bsd-_setjmp.S   1969-12-31 19:00:00.000000000 -0500
++++ b/libc/sysdeps/linux/avr32/bsd-_setjmp.S   2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,12 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ */
++
++      /* This just does a tail-call to __sigsetjmp(env, 0) */
++      .global _setjmp
++      .type   _setjmp,"function"
++      .align  1
++_setjmp:
++      mov     r11, 0
++      bral    __sigsetjmp_internal
++      .size   _setjmp, . - _setjmp
+diff -Nrup a/libc/sysdeps/linux/avr32/bsd-setjmp.S b/libc/sysdeps/linux/avr32/bsd-setjmp.S
+--- a/libc/sysdeps/linux/avr32/bsd-setjmp.S    1969-12-31 19:00:00.000000000 -0500
++++ b/libc/sysdeps/linux/avr32/bsd-setjmp.S    2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,12 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ */
++
++      /* This just does a tail-call to __sigsetjmp(env, 1) */
++      .global setjmp
++      .type   setjmp,"function"
++      .align  1
++setjmp:
++      mov     r11, 1
++      bral    __sigsetjmp_internal
++      .size   setjmp, . - setjmp
+diff -Nrup a/libc/sysdeps/linux/avr32/clone.c b/libc/sysdeps/linux/avr32/clone.c
+--- a/libc/sysdeps/linux/avr32/clone.c 1969-12-31 19:00:00.000000000 -0500
++++ b/libc/sysdeps/linux/avr32/clone.c 2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,37 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ */
++#include <errno.h>
++#include <sys/syscall.h>
++#include <unistd.h>
++
++/*
++ * I don't know if we can be absolutely certain that the fn and arg
++ * parameters are preserved when returning as the child. If the
++ * compiler stores them in registers (r0-r7), they should be.
++ */
++int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg)
++{
++      register int (*_fn)(void *arg) = fn;
++      register void *_arg = arg;
++      int err;
++
++      /* Sanity check the arguments */
++      err = -EINVAL;
++      if (!fn)
++              goto syscall_error;
++      if (!child_stack)
++              goto syscall_error;
++
++      err = INLINE_SYSCALL(clone, 2, flags, child_stack);
++      if (err < 0)
++              goto syscall_error;
++      else if (err != 0)
++              return err;
++
++      _exit(_fn(_arg));
++
++syscall_error:
++      __set_errno (-err);
++      return -1;
++}
+diff -Nrup a/libc/sysdeps/linux/avr32/crt1.S b/libc/sysdeps/linux/avr32/crt1.S
+--- a/libc/sysdeps/linux/avr32/crt1.S  1969-12-31 19:00:00.000000000 -0500
++++ b/libc/sysdeps/linux/avr32/crt1.S  2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,93 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ *
++ * When we enter _start, the stack looks like this:
++ *    argc            argument counter
++ *    argv[0]         pointer to program name
++ *    argv[1..argc-1] pointers to program args
++ *    NULL
++ *    env[0..N]       pointers to environment variables
++ *    NULL
++ *
++ * r12 contains a function pointer to be registered with `atexit'.
++ * This is how the dynamic linker arranges to have DT_FINI functions
++ * called for shared libraries that have been loaded before this
++ * code runs.
++ *
++ * We're going to call the following function:
++ * __uClibc_main(int (*main)(int, char **, char **), int argc,
++ *             char **argv, void (*app_init)(void), void (*app_fini)(void),
++ *             void (*rtld_fini)(void), void *stack_end)
++ *
++ * So we need to set up things as follows:
++ *    r12 = address of main
++ *    r11 = argc
++ *    r10 = &argv[0]
++ *    r9  = address of _init
++ *    r8  = address of _fini
++ *    sp[0] = whatever we got passed in r12
++ */
++
++#include <features.h>
++
++      .text
++      .global _start
++      .type   _start, @function
++_start:
++      /* Clear the frame pointer and link register since this is the outermost frame.  */
++      mov     r7, 0
++      mov     lr, 0
++
++      ld.w    r11, sp++               /* argc         */
++      mov     r10, sp                 /* &argv[0]     */
++
++      st.w    --sp, r10               /* stack_end */
++      st.w    --sp, r12               /* rtld_fini */
++
++#ifdef __PIC__
++      lddpc   r6, .L_GOT
++.L_RGOT:
++      rsub    r6, pc
++      lda.w   r9, _init
++      lda.w   r8, _fini
++      lda.w   r12, main
++
++      /* Ok, now run uClibc's main() -- should not return */
++      call    __uClibc_main
++
++      .align  2
++.L_GOT:
++      .long   .L_RGOT - _GLOBAL_OFFSET_TABLE_
++#else
++      lddpc   r9, __init_addr         /* app_init */
++      lddpc   r8, __fini_addr         /* app_fini */
++      lddpc   r12, __main_addr        /* main */
++
++      /* Ok, now run uClibc's main() -- should not return */
++      lddpc   pc, ___uClibc_main_addr
++
++      .align  2
++__init_addr:
++      .long   _init
++__fini_addr:
++      .long   _fini
++__main_addr:
++      .long   main
++___uClibc_main_addr:
++      .long   __uClibc_main
++#endif
++      .size   _start, . - _start
++
++      /*
++       * The LSB says we need this.
++       */
++      .section ".note.ABI-tag", "a"
++      .align  4
++      .long   2f - 1f         /* namesz */
++      .long   4f - 3f         /* descsz */
++      .long   1               /* type   */
++1:    .asciz  "GNU"           /* name */
++2:    .align  4
++3:    .long   0               /* Linux executable */
++      .long   2,6,0           /* Earliest compatible kernel */
++4:    .align  4
+diff -Nrup a/libc/sysdeps/linux/avr32/crti.S b/libc/sysdeps/linux/avr32/crti.S
+--- a/libc/sysdeps/linux/avr32/crti.S  1969-12-31 19:00:00.000000000 -0500
++++ b/libc/sysdeps/linux/avr32/crti.S  2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,17 @@
++
++      .section .init
++      .align  2
++      .global _init
++      .type   _init, @function
++_init:
++      /* Use a four-byte instruction to avoid NOPs */
++      stm     --sp, r0-r7,lr
++      .align  2
++
++      .section .fini
++      .align  2
++      .global _fini
++      .type   _fini, @function
++_fini:
++      stm     --sp, r0-r7,lr
++      .align  2
+diff -Nrup a/libc/sysdeps/linux/avr32/crtn.S b/libc/sysdeps/linux/avr32/crtn.S
+--- a/libc/sysdeps/linux/avr32/crtn.S  1969-12-31 19:00:00.000000000 -0500
++++ b/libc/sysdeps/linux/avr32/crtn.S  2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,14 @@
++
++      .section .init
++      .align  2
++      .global _init
++      .type   _init, @function
++      ldm     sp++, r0-r7,pc
++      .size   _init, . - _init
++
++      .section .fini
++      .align  2
++      .global _fini
++      .type   _fini, @function
++      ldm     sp++, r0-r7,pc
++      .size   _fini, . - _fini
+diff -Nrup a/libc/sysdeps/linux/avr32/__longjmp.S b/libc/sysdeps/linux/avr32/__longjmp.S
+--- a/libc/sysdeps/linux/avr32/__longjmp.S     1969-12-31 19:00:00.000000000 -0500
++++ b/libc/sysdeps/linux/avr32/__longjmp.S     2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,17 @@
++/* longjmp for AVR32
++ *
++ * Copyright (C) 2004 Atmel Norway AS
++ */
++
++      .global __longjmp
++      .type   __longjmp,"function"
++      .align  1
++__longjmp:
++      ldm     r12++, r0,r1,r2,r3,r4,r5,r6,r7,r8,sp,lr
++      mov     r12, r11        /* get the return value right */
++      mustr   r8              /* restore status register (lower half) */
++      cp      r12, 0          /* can't return zero */
++      frs
++      moveq   r12, 1
++      mov     pc,lr
++      .size   __longjmp, . - __longjmp
+diff -Nrup a/libc/sysdeps/linux/avr32/Makefile b/libc/sysdeps/linux/avr32/Makefile
+--- a/libc/sysdeps/linux/avr32/Makefile        1969-12-31 19:00:00.000000000 -0500
++++ b/libc/sysdeps/linux/avr32/Makefile        2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,93 @@
++# Makefile for uClibc
++#
++# Copyright (C) 2000-2003 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
++
++TOPDIR=../../../../
++include $(TOPDIR)Rules.mak
++ASFLAGS=$(CFLAGS)
++
++CRT_SRC       = crt1.S
++CRT_OBJ = crt1.o
++SCRT_OBJ = $(patsubst %,S%, $(CRT_OBJ))
++CTOR_TARGETS=$(TOPDIR)lib/crti.o $(TOPDIR)lib/crtn.o
++
++SSRC=__longjmp.S setjmp.S bsd-setjmp.S vfork.S \
++      bsd-_setjmp.S sigrestorer.S syscall.S
++SOBJS=$(patsubst %.S,%.o, $(SSRC))
++
++CSRC=clone.c brk.c sigaction.c mmap.c
++COBJS=$(patsubst %.c,%.o, $(CSRC))
++
++OBJS=$(SOBJS) $(COBJS)
++
++OBJ_LIST=../../../obj.sysdeps.$(TARGET_ARCH)
++
++all: $(OBJ_LIST)
++
++$(OBJ_LIST): $(OBJS) $(CRT_OBJ) $(SCRT_OBJ) $(CTOR_TARGETS)
++      echo $(patsubst %, sysdeps/linux/$(TARGET_ARCH)/%, $(OBJS)) > $(OBJ_LIST)
++      $(INSTALL) -d $(TOPDIR)lib/
++      cp $(CRT_OBJ) $(SCRT_OBJ) $(TOPDIR)lib/
++
++$(CRT_OBJ): $(CRT_SRC)
++      $(CC) $(ASFLAGS) -DL_$* $< -c -o $*.o
++      $(STRIPTOOL) -x -R .note -R .comment $*.o
++
++$(SCRT_OBJ): $(CRT_SRC)
++      $(CC) $(ASFLAGS) $(PIEFLAG) -DL_$* $< -c -o $*.o
++      $(STRIPTOOL) -x -R .note -R .comment $*.o
++
++$(SOBJS): %.o : %.S
++      $(CC) $(ASFLAGS) -c $< -o $@
++      $(STRIPTOOL) -x -R .note -R .comment $*.o
++
++$(COBJS): %.o : %.c
++      $(CC) $(CFLAGS) -c $< -o $@
++      $(STRIPTOOL) -x -R .note -R .comment $*.o
++
++ifeq ($(strip $(UCLIBC_CTOR_DTOR)),y)
++crti.o: crti.S
++      $(CC) $(ASFLAGS) -c crti.S -o crti.o
++
++$(TOPDIR)lib/crti.o: crti.o
++      $(INSTALL) -d $(TOPDIR)lib/
++      cp crti.o $(TOPDIR)lib/
++
++crtn.o: crtn.S
++      $(CC) $(ASFLAGS) -c crtn.S -o crtn.o
++
++$(TOPDIR)lib/crtn.o: crtn.o
++      $(INSTALL) -d $(TOPDIR)lib/
++      cp crtn.o $(TOPDIR)lib/
++else
++$(TOPDIR)lib/crti.o:
++      $(INSTALL) -d $(TOPDIR)lib/
++      $(AR) $(ARFLAGS) $(TOPDIR)lib/crti.o
++$(TOPDIR)lib/crtn.o:
++      $(INSTALL) -d $(TOPDIR)lib/
++      $(AR) $(ARFLAGS) $(TOPDIR)lib/crtn.o
++endif
++
++
++headers:
++#     $(LN) -fs ../libc/sysdeps/linux/avr32/fpu_control.h $(TOPDIR)/include/
++
++clean:
++      $(RM) *.[oa] *~ core
++      $(RM) bits/sysnum.h
++      $(RM) gmon-start.S
++
+diff -Nrup a/libc/sysdeps/linux/avr32/_mmap.c b/libc/sysdeps/linux/avr32/_mmap.c
+--- a/libc/sysdeps/linux/avr32/_mmap.c 1969-12-31 19:00:00.000000000 -0500
++++ b/libc/sysdeps/linux/avr32/_mmap.c 2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,33 @@
++/* Copyright (C) 2005 Atmel Norway
++
++   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
++
++   Derived in part from the Linux-8086 C library, the GNU C Library, and several
++   other sundry sources.  Files within this library are copyright by their
++   respective copyright holders.
++ */
++
++#include <errno.h>
++#include <sys/mman.h>
++#include <sys/syscall.h>
++
++#define __NR_mmap2 __NR_mmap
++
++static _syscall6(__ptr_t, mmap2, __ptr_t, addr, size_t, len, int, prot, int, flags, int, fd, __off_t, pgoff);
++
++__ptr_t mmap(__ptr_t addr, size_t len, int prot, int flags, int fd, __off_t offset)
++{
++      return mmap2(addr, len, prot, flags, fd, offset >> 12);
++}
+diff -Nrup a/libc/sysdeps/linux/avr32/mmap.c b/libc/sysdeps/linux/avr32/mmap.c
+--- a/libc/sysdeps/linux/avr32/mmap.c  1969-12-31 19:00:00.000000000 -0500
++++ b/libc/sysdeps/linux/avr32/mmap.c  2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,31 @@
++/* Copyright (C) 2005 Atmel Norway
++
++   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
++
++   Derived in part from the Linux-8086 C library, the GNU C Library, and several
++   other sundry sources.  Files within this library are copyright by their
++   respective copyright holders.
++ */
++
++#include <errno.h>
++#include <sys/mman.h>
++#include <sys/syscall.h>
++
++static _syscall6(__ptr_t, mmap2, __ptr_t, addr, size_t, len, int, prot, int, flags, int, fd, __off_t, pgoff);
++
++__ptr_t mmap(__ptr_t addr, size_t len, int prot, int flags, int fd, __off_t offset)
++{
++      return mmap2(addr, len, prot, flags, fd, offset >> 12);
++}
+diff -Nrup a/libc/sysdeps/linux/avr32/setjmp.S b/libc/sysdeps/linux/avr32/setjmp.S
+--- a/libc/sysdeps/linux/avr32/setjmp.S        1969-12-31 19:00:00.000000000 -0500
++++ b/libc/sysdeps/linux/avr32/setjmp.S        2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,43 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ */
++#define _SETJMP_H
++#define _ASM
++#include <bits/setjmp.h>
++
++      .text
++
++      .global __sigsetjmp
++      .type   __sigsetjmp,"function"
++
++      /* Create a global, hidden symbol for use by setjmp() and _setjmp().
++         If it's not hidden, the linker will complain about a relative
++         jump to a dynamic symbol when building a shared library.
++
++         Also, if a user overrides the __sigsetjmp function, he might not
++         expect the setjmp() and _setjmp() function to effectively be
++         overridden as well.  */
++      .global __sigsetjmp_internal
++      .hidden __sigsetjmp_internal
++      .type   __sigsetjmp_internal,"function"
++      .align  1
++__sigsetjmp:
++__sigsetjmp_internal:
++      mustr   r8
++      stm     r12, r0,r1,r2,r3,r4,r5,r6,r7,r8,sp,lr
++
++      /* Make a tail call to __sigjmp_save; it takes the same args.  */
++#ifdef __PIC__
++      mov     r9, r6
++      lddpc   r6, .LG
++.L1:  rsub    r6, pc
++      ld.w    r8, r6[__sigjmp_save@got]
++      mov     r6, r9
++      mov     pc, r8
++
++      .align  2
++.LG:  .long   .L1 - _GLOBAL_OFFSET_TABLE_
++#else
++      rjmp    __sigjmp_save
++#endif
++      .size   __sigsetjmp, . - __sigsetjmp
+diff -Nrup a/libc/sysdeps/linux/avr32/sigaction.c b/libc/sysdeps/linux/avr32/sigaction.c
+--- a/libc/sysdeps/linux/avr32/sigaction.c     1969-12-31 19:00:00.000000000 -0500
++++ b/libc/sysdeps/linux/avr32/sigaction.c     2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,49 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ */
++#include <errno.h>
++#include <signal.h>
++#include <string.h>
++#include <sys/syscall.h>
++#include <bits/kernel_sigaction.h>
++
++#define SA_RESTORER   0x04000000
++extern void __default_rt_sa_restorer(void);
++
++/*
++ * If act is not NULL, change the action for sig to *act.
++ * If oact is not NULL, put the old action for sig in *oact.
++ */
++int __libc_sigaction(int signum, const struct sigaction *act,
++                   struct sigaction *oldact)
++{
++      struct kernel_sigaction kact, koact;
++      int result;
++
++      if (act) {
++              kact.k_sa_handler = act->sa_handler;
++              memcpy(&kact.sa_mask, &act->sa_mask, sizeof (kact.sa_mask));
++              kact.sa_flags = act->sa_flags;
++              if (kact.sa_flags & (SA_RESTORER | SA_ONSTACK))
++                      kact.sa_restorer = act->sa_restorer;
++              else
++                      kact.sa_restorer = __default_rt_sa_restorer;
++              kact.sa_flags |= SA_RESTORER;
++      }
++
++      result = __syscall_rt_sigaction(signum, act ? __ptrvalue(&kact) : NULL,
++                                      oldact ? __ptrvalue(&koact) : NULL,
++                                      _NSIG / 8);
++
++      if (oldact && result >= 0) {
++              oldact->sa_handler = koact.k_sa_handler;
++              memcpy(&oldact->sa_mask, &koact.sa_mask,
++                     sizeof(oldact->sa_mask));
++              oldact->sa_flags = koact.sa_flags;
++              oldact->sa_restorer = koact.sa_restorer;
++      }
++
++      return result;
++}
++
++weak_alias(__libc_sigaction, sigaction)
+diff -Nrup a/libc/sysdeps/linux/avr32/sigrestorer.S b/libc/sysdeps/linux/avr32/sigrestorer.S
+--- a/libc/sysdeps/linux/avr32/sigrestorer.S   1969-12-31 19:00:00.000000000 -0500
++++ b/libc/sysdeps/linux/avr32/sigrestorer.S   2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,11 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ */
++#include <sys/syscall.h>
++
++      .global __default_rt_sa_restorer
++      .type   __default_rt_sa_restorer,"function"
++      .align  1
++__default_rt_sa_restorer:
++      mov     r8, __NR_rt_sigreturn
++      scall
+diff -Nrup a/libc/sysdeps/linux/avr32/sys/elf.h b/libc/sysdeps/linux/avr32/sys/elf.h
+--- a/libc/sysdeps/linux/avr32/sys/elf.h       1969-12-31 19:00:00.000000000 -0500
++++ b/libc/sysdeps/linux/avr32/sys/elf.h       2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,26 @@
++/* Copyright (C) 1996, 1997, 1999, 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.  */
++
++#ifndef _SYS_ELF_H
++#define _SYS_ELF_H    1
++
++#warning "This header is obsolete; use <sys/procfs.h> instead."
++
++#include <sys/procfs.h>
++
++#endif        /* sys/elf.h */
+diff -Nrup a/libc/sysdeps/linux/avr32/sys/io.h b/libc/sysdeps/linux/avr32/sys/io.h
+--- a/libc/sysdeps/linux/avr32/sys/io.h        1969-12-31 19:00:00.000000000 -0500
++++ b/libc/sysdeps/linux/avr32/sys/io.h        2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,48 @@
++/* Copyright (C) 1996, 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 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.  */
++
++#ifndef       _SYS_IO_H
++
++#define       _SYS_IO_H       1
++#include <features.h>
++
++__BEGIN_DECLS
++
++/* If TURN_ON is TRUE, request for permission to do direct i/o on the
++   port numbers in the range [FROM,FROM+NUM-1].  Otherwise, turn I/O
++   permission off for that range.  This call requires root privileges.  */
++extern int ioperm (unsigned long int __from, unsigned long int __num,
++                 int __turn_on) __THROW;
++
++/* Set the I/O privilege level to LEVEL.  If LEVEL is nonzero,
++   permission to access any I/O port is granted.  This call requires
++   root privileges. */
++extern int iopl (int __level) __THROW;
++
++/* The functions that actually perform reads and writes.  */
++extern unsigned char inb (unsigned long int port) __THROW;
++extern unsigned short int inw (unsigned long int port) __THROW;
++extern unsigned long int inl (unsigned long int port) __THROW;
++
++extern void outb (unsigned char value, unsigned long int port) __THROW;
++extern void outw (unsigned short value, unsigned long int port) __THROW;
++extern void outl (unsigned long value, unsigned long int port) __THROW;
++
++__END_DECLS
++
++#endif /* _SYS_IO_H */
+diff -Nrup a/libc/sysdeps/linux/avr32/sys/procfs.h b/libc/sysdeps/linux/avr32/sys/procfs.h
+--- a/libc/sysdeps/linux/avr32/sys/procfs.h    1969-12-31 19:00:00.000000000 -0500
++++ b/libc/sysdeps/linux/avr32/sys/procfs.h    2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,123 @@
++/* Copyright (C) 1996, 1997, 1999, 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.  */
++
++#ifndef _SYS_PROCFS_H
++#define _SYS_PROCFS_H 1
++
++/* This is somewhat modelled after the file of the same name on SVR4
++   systems.  It provides a definition of the core file format for ELF
++   used on Linux.  It doesn't have anything to do with the /proc file
++   system, even though Linux has one.
++
++   Anyway, the whole purpose of this file is for GDB and GDB only.
++   Don't read too much into it.  Don't use it for anything other than
++   GDB unless you know what you are doing.  */
++
++#include <features.h>
++#include <sys/time.h>
++#include <sys/types.h>
++#include <sys/user.h>
++
++__BEGIN_DECLS
++
++/* Type for a general-purpose register.  */
++typedef unsigned long elf_greg_t;
++
++/* And the whole bunch of them.  We could have used `struct
++   user_regs' directly in the typedef, but tradition says that
++   the register set is an array, which does have some peculiar
++   semantics, so leave it that way.  */
++#define ELF_NGREG (sizeof (struct user_regs) / sizeof(elf_greg_t))
++typedef elf_greg_t elf_gregset_t[ELF_NGREG];
++
++/* Register set for the floating-point registers.  */
++typedef struct user_fpregs elf_fpregset_t;
++
++/* Signal info.  */
++struct elf_siginfo
++  {
++    int si_signo;                     /* Signal number.  */
++    int si_code;                      /* Extra code.  */
++    int si_errno;                     /* Errno.  */
++  };
++
++/* Definitions to generate Intel SVR4-like core files.  These mostly
++   have the same names as the SVR4 types with "elf_" tacked on the
++   front to prevent clashes with Linux definitions, and the typedef
++   forms have been avoided.  This is mostly like the SVR4 structure,
++   but more Linuxy, with things that Linux does not support and which
++   GDB doesn't really use excluded.  */
++
++struct elf_prstatus
++  {
++    struct elf_siginfo pr_info;               /* Info associated with signal.  */
++    short int pr_cursig;              /* Current signal.  */
++    unsigned long int pr_sigpend;     /* Set of pending signals.  */
++    unsigned long int pr_sighold;     /* Set of held signals.  */
++    __pid_t pr_pid;
++    __pid_t pr_ppid;
++    __pid_t pr_pgrp;
++    __pid_t pr_sid;
++    struct timeval pr_utime;          /* User time.  */
++    struct timeval pr_stime;          /* System time.  */
++    struct timeval pr_cutime;         /* Cumulative user time.  */
++    struct timeval pr_cstime;         /* Cumulative system time.  */
++    elf_gregset_t pr_reg;             /* GP registers.  */
++    int pr_fpvalid;                   /* True if math copro being used.  */
++  };
++
++
++#define ELF_PRARGSZ     (80)    /* Number of chars for args.  */
++
++struct elf_prpsinfo
++  {
++    char pr_state;                    /* Numeric process state.  */
++    char pr_sname;                    /* Char for pr_state.  */
++    char pr_zomb;                     /* Zombie.  */
++    char pr_nice;                     /* Nice val.  */
++    unsigned long int pr_flag;                /* Flags.  */
++    unsigned short int pr_uid;
++    unsigned short int pr_gid;
++    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
++    /* Lots missing */
++    char pr_fname[16];                        /* Filename of executable.  */
++    char pr_psargs[ELF_PRARGSZ];      /* Initial part of arg list.  */
++  };
++
++/* The rest of this file provides the types for emulation of the
++   Solaris <proc_service.h> interfaces that should be implemented by
++   users of libthread_db.  */
++
++/* Addresses.  */
++typedef void *psaddr_t;
++
++/* Register sets.  Linux has different names.  */
++typedef elf_gregset_t prgregset_t;
++typedef elf_fpregset_t prfpregset_t;
++
++/* We don't have any differences between processes and threads,
++   therefore have only one PID type.  */
++typedef __pid_t lwpid_t;
++
++/* Process status and info.  In the end we do provide typedefs for them.  */
++typedef struct elf_prstatus prstatus_t;
++typedef struct elf_prpsinfo prpsinfo_t;
++
++__END_DECLS
++
++#endif        /* sys/procfs.h */
+diff -Nrup a/libc/sysdeps/linux/avr32/sys/ucontext.h b/libc/sysdeps/linux/avr32/sys/ucontext.h
+--- a/libc/sysdeps/linux/avr32/sys/ucontext.h  1969-12-31 19:00:00.000000000 -0500
++++ b/libc/sysdeps/linux/avr32/sys/ucontext.h  2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,94 @@
++/* Copyright (C) 1998, 1999, 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.  */
++
++/* Linux/AVR32 ABI compliant context switching support.  */
++
++#ifndef _SYS_UCONTEXT_H
++#define _SYS_UCONTEXT_H       1
++
++#include <features.h>
++#include <signal.h>
++#include <sys/procfs.h>
++#include <bits/sigcontext.h>
++
++typedef int greg_t;
++
++/* Number of general registers.  */
++#define NGREG 16
++
++/* Container for all general registers.  */
++typedef elf_gregset_t gregset_t;
++
++/* Number of each register is the `gregset_t' array.  */
++enum
++{
++  R0 = 0,
++#define R0    R0
++  R1 = 1,
++#define R1    R1
++  R2 = 2,
++#define R2    R2
++  R3 = 3,
++#define R3    R3
++  R4 = 4,
++#define R4    R4
++  R5 = 5,
++#define R5    R5
++  R6 = 6,
++#define R6    R6
++  R7 = 7,
++#define R7    R7
++  R8 = 8,
++#define R8    R8
++  R9 = 9,
++#define R9    R9
++  R10 = 10,
++#define R10   R10
++  R11 = 11,
++#define R11   R11
++  R12 = 12,
++#define R12   R12
++  R13 = 13,
++#define R13   R13
++  R14 = 14,
++#define R14   R14
++  R15 = 15
++#define R15   R15
++};
++
++/* Structure to describe FPU registers.  */
++typedef elf_fpregset_t        fpregset_t;
++
++/* Context to describe whole processor state.  */
++typedef struct
++  {
++    gregset_t gregs;
++    fpregset_t fpregs;
++  } mcontext_t;
++
++/* Userlevel context.  */
++typedef struct ucontext
++{
++    unsigned long     uc_flags;
++    struct ucontext  *uc_link;
++    stack_t           uc_stack;
++    struct sigcontext uc_mcontext;
++    sigset_t          uc_sigmask;   /* mask last for extensibility */
++} ucontext_t;
++
++#endif /* sys/ucontext.h */
+diff -Nrup a/libc/sysdeps/linux/avr32/sys/user.h b/libc/sysdeps/linux/avr32/sys/user.h
+--- a/libc/sysdeps/linux/avr32/sys/user.h      1969-12-31 19:00:00.000000000 -0500
++++ b/libc/sysdeps/linux/avr32/sys/user.h      2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,46 @@
++#ifndef _SYS_USER_H
++#define _SYS_USER_H
++
++struct user_fpregs
++{
++
++};
++
++struct user_regs
++{
++      unsigned long sr;
++      unsigned long pc;
++      unsigned long lr;
++      unsigned long sp;
++      unsigned long r12;
++      unsigned long r11;
++      unsigned long r10;
++      unsigned long r9;
++      unsigned long r8;
++      unsigned long r7;
++      unsigned long r6;
++      unsigned long r5;
++      unsigned long r4;
++      unsigned long r3;
++      unsigned long r2;
++      unsigned long r1;
++      unsigned long r0;
++      unsigned long r12_orig;
++};
++
++struct user
++{
++      struct user_regs        regs;           /* general registers */
++      size_t                  u_tsize;        /* text size (pages) */
++      size_t                  u_dsize;        /* data size (pages) */
++      size_t                  u_ssize;        /* stack size (pages) */
++      unsigned long           start_code;     /* text starting address */
++      unsigned long           start_data;     /* data starting address */
++      unsigned long           start_stack;    /* stack starting address */
++      long int                signal;         /* signal causing core dump */
++      struct user_regs *      u_ar0;          /* help gdb find registers */
++      unsigned long           magic;          /* identifies a core file */
++      char                    u_comm[32];     /* user command name */
++};
++
++#endif /* _SYS_USER_H */
+diff -Nrup a/libc/sysdeps/linux/avr32/syscall.S b/libc/sysdeps/linux/avr32/syscall.S
+--- a/libc/sysdeps/linux/avr32/syscall.S       1969-12-31 19:00:00.000000000 -0500
++++ b/libc/sysdeps/linux/avr32/syscall.S       2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,81 @@
++/*
++ * syscall for AVR32/uClibc
++ *
++ * Copyright (C) 2004 Atmel Norway
++ *
++ * 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 <features.h>
++
++      .text
++
++      /*
++       * long int syscall(long int sysno, ...)
++       */
++      .global syscall
++      .type   syscall, @function
++      .align  2
++syscall:
++      stm     --sp, r3,r5,lr
++      sub     lr, sp, -12
++      mov     r8, r12
++      ldm     lr, r3,r5,r9-r12
++      scall
++      cp.w    r12, -4095
++      brlo    .Ldone
++
++#ifdef __PIC__
++      lddpc   r5, .Lgot
++.Lgotcalc:
++      rsub    r5, pc
++# ifdef __UCLIBC_HAS_THREADS__
++      mov     r3, r12
++      mcall   r5[__errno_location@got]
++      st.w    r12[0], r3
++# else
++      ld.w    r3, r5[errno@got]
++      st.w    r3[0], r12
++# endif
++#else
++# ifdef __UCLIBC_HAS_THREADS__
++      mov     r3, r12
++      mcall   .Lerrno_location
++      st.w    r12[0], r3
++# else
++      lddpc   r3, .Lerrno
++      st.w    r3[0], r12
++# endif
++#endif
++      mov     r12, -1
++
++.Ldone:
++      ldm     sp++, r3,r5,pc
++
++      .align  2
++#ifdef __PIC__
++.Lgot:
++      .long   .Lgotcalc - _GLOBAL_OFFSET_TABLE_
++#else
++# ifdef __UCLIBC_HAS_THREADS__
++.Lerrno_location:
++      .long   __errno_location
++# else
++.Lerrno:
++      .long   errno
++# endif
++#endif
++
++
++      .size   syscall, . - syscall
+diff -Nrup a/libc/sysdeps/linux/avr32/vfork.S b/libc/sysdeps/linux/avr32/vfork.S
+--- a/libc/sysdeps/linux/avr32/vfork.S 1969-12-31 19:00:00.000000000 -0500
++++ b/libc/sysdeps/linux/avr32/vfork.S 2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,55 @@
++      /*
++       * vfork for uClibc
++       *
++       * Copyright (C) 2005 Atmel Norway
++       */
++
++      /*
++       * Clone the process without copying the address space.  The
++       * calling process is suspended until the child either exits
++       * or calls execve.
++       *
++       * This all means that we cannot rely on the stack to store
++       * away registers, since they will be overwritten by the child
++       * as soon as it makes another function call (e.g. execve()).
++       * Fortunately, the Linux kernel preserves LR across system calls.
++       */
++#include <features.h>
++#include <sys/syscall.h>
++
++      .global __vfork
++      .type   __vfork,@function
++      .align  1
++__vfork:
++      mov     r8, __NR_vfork
++      scall
++      cp.w    r12, -4096
++      retls   r12
++
++      /* vfork failed, so we may use the stack freely */
++      pushm   r4-r7,lr
++#ifdef __PIC__
++      lddpc   r6, .L_GOT
++      rsub    r4, r12, 0
++.L_RGOT:
++      rsub    r6, pc
++      mcall   r6[__errno_location@got]
++#else
++      rsub    r4, r12, 0
++      mcall   .L__errno_location
++#endif
++      st.w    r12[0], r4
++      popm    r4-r7,pc,r12=-1
++
++      .align  2
++#ifdef __PIC__
++.L_GOT:
++      .long   .L_RGOT - _GLOBAL_OFFSET_TABLE_
++#else
++.L__errno_location:
++      .long   __errno_location
++#endif
++      .size   __vfork, . - __vfork
++
++      .weak   vfork
++      vfork   = __vfork
+diff -Nrup a/libc/sysdeps/linux/common/create_module.c b/libc/sysdeps/linux/common/create_module.c
+--- a/libc/sysdeps/linux/common/create_module.c        2004-03-11 19:21:20.000000000 -0500
++++ b/libc/sysdeps/linux/common/create_module.c        2008-02-28 19:02:10.000000000 -0500
+@@ -61,7 +61,8 @@ unsigned long create_module(const char *
+ {
+   return __create_module(name, size, 0, 0);
+ }
+-#else
++/* create_module is obsolete in Linux 2.6, so AVR32 doesn't have it */
++#elif !defined(__avr32__)
+ /* Sparc, MIPS, etc don't mistake return values for errors. */ 
+ _syscall2(unsigned long, create_module, const char *, name, size_t, size);
+ #endif
+diff -Nrup a/libc/sysdeps/linux/common/getrusage.c b/libc/sysdeps/linux/common/getrusage.c
+--- a/libc/sysdeps/linux/common/getrusage.c    2005-01-05 18:11:28.000000000 -0500
++++ b/libc/sysdeps/linux/common/getrusage.c    2008-02-28 19:02:10.000000000 -0500
+@@ -10,4 +10,4 @@
+ #include "syscalls.h"
+ #include <unistd.h>
+ #include <wait.h>
+-_syscall2(int, getrusage, int, who, struct rusage *, usage);
++_syscall2(int, getrusage, __rusage_who_t, who, struct rusage *, usage);
+diff -Nrup a/libc/sysdeps/linux/common/open64.c b/libc/sysdeps/linux/common/open64.c
+--- a/libc/sysdeps/linux/common/open64.c       2002-10-31 13:20:21.000000000 -0500
++++ b/libc/sysdeps/linux/common/open64.c       2008-02-28 19:02:10.000000000 -0500
+@@ -26,7 +26,7 @@
+ #endif
+ #ifdef __UCLIBC_HAS_LFS__
+-extern int __libc_open (__const char *file, int oflag, mode_t mode);
++extern int __libc_open (__const char *file, int oflag, ...);
+ /* Open FILE with access OFLAG.  If OFLAG includes O_CREAT,
+    a third argument is the file protection.  */
+diff -Nrup a/libc/sysdeps/linux/common/__syscall_fcntl.c b/libc/sysdeps/linux/common/__syscall_fcntl.c
+--- a/libc/sysdeps/linux/common/__syscall_fcntl.c      2005-07-30 10:02:24.000000000 -0400
++++ b/libc/sysdeps/linux/common/__syscall_fcntl.c      2008-02-28 19:02:10.000000000 -0500
+@@ -12,7 +12,7 @@
+ #include <fcntl.h>
+ #if defined __UCLIBC_HAS_LFS__ && defined __NR_fcntl64
+-extern int __libc_fcntl64(int fd, int cmd, long arg);
++extern int __libc_fcntl64(int fd, int cmd, ...);
+ #endif
+ #define __NR___syscall_fcntl __NR_fcntl
+diff -Nrup a/libpthread/linuxthreads/sysdeps/avr32/pt-machine.h b/libpthread/linuxthreads/sysdeps/avr32/pt-machine.h
+--- a/libpthread/linuxthreads/sysdeps/avr32/pt-machine.h       1969-12-31 19:00:00.000000000 -0500
++++ b/libpthread/linuxthreads/sysdeps/avr32/pt-machine.h       2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,92 @@
++/* Machine-dependent pthreads configuration and inline functions.
++
++   Copyright (C) 2005 Atmel Norway
++   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; 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 _PT_MACHINE_H
++#define _PT_MACHINE_H   1
++
++#include <features.h>
++
++static inline int
++_test_and_set (int *p, int v) __THROW
++{
++      int result;
++
++      __asm__ __volatile__(
++              "/* Inline test and set */\n"
++              "1:     ssrf    5\n"
++              "       ld.w    %0, %2\n"
++              "       tst     %0, %3\n"
++              "       breq    2f\n"
++              "       stcond  %1, %3\n"
++              "       brne    1b\n"
++              "2:"
++              : "=&r"(result), "=m"(*p)
++              : "m"(*p), "r"(v)
++              : "memory", "cc");
++
++      return result;
++}
++
++#ifndef PT_EI
++# define PT_EI extern inline
++#endif
++
++extern long int testandset (int *spinlock);
++extern int __compare_and_swap (long int *p, long int oldval, long int newval);
++
++/* Spinlock implementation; required.  */
++PT_EI long int
++testandset (int *spinlock)
++{
++      return _test_and_set(spinlock, 1);
++}
++
++
++/* Get some notion of the current stack.  Need not be exactly the top
++   of the stack, just something somewhere in the current frame.  */
++#define CURRENT_STACK_FRAME  stack_pointer
++register char * stack_pointer __asm__ ("sp");
++
++/* Compare-and-swap for semaphores. */
++
++#define HAS_COMPARE_AND_SWAP
++PT_EI int
++__compare_and_swap(long int *p, long int oldval, long int newval)
++{
++      long int result, tmp;
++
++      __asm__ __volatile__(
++              "/* Inline compare and swap */\n"
++              "1:     ssrf    5\n"
++              "       ld.w    %1, %3\n"
++              "       cp.w    %1, %5\n"
++              "       sreq    %0\n"
++              "       brne    2f\n"
++              "       stcond  %2, %4\n"
++              "       brne    1b\n"
++              "2:"
++              : "=&r"(result), "=&r"(tmp), "=m"(*p)
++              : "m"(*p), "r"(newval), "r"(oldval)
++              : "cc", "memory");
++
++      return result;
++}
++
++#endif /* pt-machine.h */
+diff -Nrup a/Makefile b/Makefile
+--- a/Makefile 2007-02-01 21:24:29.000000000 -0500
++++ b/Makefile 2008-02-28 19:02:10.000000000 -0500
+@@ -163,7 +163,7 @@ install_dev:
+       else \
+               extra_exclude="" ; \
+       fi ; \
+-      tar -chf - include --exclude .svn --exclude CVS $$extra_exclude \
++      tar -chf - --exclude .svn --exclude CVS $$extra_exclude include \
+               | tar -xf - -C $(PREFIX)$(DEVEL_PREFIX)
+       echo '/* Dont use _syscall#() macros; use the syscall() function */' > \
+               $(PREFIX)$(DEVEL_PREFIX)include/bits/syscalls.h
+diff -Nrup a/Makefile.orig b/Makefile.orig
+--- a/Makefile.orig    1969-12-31 19:00:00.000000000 -0500
++++ b/Makefile.orig    2007-02-01 21:24:29.000000000 -0500
+@@ -0,0 +1,383 @@
++# Makefile for uClibc
++#
++# Copyright (C) 2000-2003 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
++
++
++#--------------------------------------------------------------
++# You shouldn't need to mess with anything beyond this point...
++#--------------------------------------------------------------
++noconfig_targets := menuconfig config oldconfig randconfig \
++      defconfig allyesconfig allnoconfig clean distclean \
++      release tags TAGS
++TOPDIR=./
++include Rules.mak
++
++DIRS = ldso libc libcrypt libresolv libnsl libutil libm libpthread librt
++ifeq ($(strip $(UCLIBC_HAS_GETTEXT_AWARENESS)),y)
++      DIRS += libintl
++endif
++
++ifeq ($(strip $(HAVE_DOT_CONFIG)),y)
++
++all: headers pregen subdirs shared finished
++
++# In this section, we need .config
++-include .config.cmd
++
++shared: subdirs
++ifeq ($(strip $(HAVE_SHARED)),y)
++      $(SECHO)
++      $(SECHO) Building shared libraries ...
++      $(SECHO)
++      @$(MAKE) -C libc shared
++      @$(MAKE) -C ldso shared
++      @$(MAKE) -C libcrypt shared
++      @$(MAKE) -C libresolv shared
++      @$(MAKE) -C libnsl shared
++      @$(MAKE) -C libutil shared
++      @$(MAKE) -C libm shared
++      @$(MAKE) -C libpthread shared
++      @$(MAKE) -C librt shared
++ifeq ($(strip $(UCLIBC_HAS_GETTEXT_AWARENESS)),y)
++      @$(MAKE) -C libintl shared
++endif
++else
++      $(SECHO)
++      $(SECHO) Not building shared libraries ...
++      $(SECHO)
++endif
++
++finished: shared
++      $(SECHO)
++      $(SECHO) Finally finished compiling ...
++      $(SECHO)
++
++include/bits/uClibc_config.h: .config
++      @if [ ! -x ./extra/config/conf ] ; then \
++          $(MAKE) -C extra/config conf; \
++      fi;
++      $(RM) -r include/bits
++      $(INSTALL) -d include/bits
++      @./extra/config/conf -o extra/Configs/Config.in
++
++# For the moment, we have to keep re-running this target 
++# because the fix includes scripts rely on pre-processers 
++# in order to generate the headers correctly :(.  That 
++# means we can't use the $(HOSTCC) in order to get the 
++# correct output.
++ifeq ($(strip $(ARCH_HAS_MMU)),y)
++export header_extra_args = 
++else
++export header_extra_args = -n
++endif
++headers: include/bits/uClibc_config.h
++      @$(SHELL_SET_X); \
++      ./extra/scripts/fix_includes.sh \
++              -k $(KERNEL_SOURCE) -t $(TARGET_ARCH) \
++              $(header_extra_args)
++      @cd include/bits; \
++      set -e; \
++      for i in `ls ../../libc/sysdeps/linux/common/bits/*.h` ; do \
++              $(LN) -fs $$i .; \
++      done; \
++      if [ -d ../../libc/sysdeps/linux/$(TARGET_ARCH)/bits ] ; then \
++              for i in `ls ../../libc/sysdeps/linux/$(TARGET_ARCH)/bits/*.h` ; do \
++                      $(LN) -fs $$i .; \
++              done; \
++      fi
++      @cd include/sys; \
++      set -e; \
++      for i in `ls ../../libc/sysdeps/linux/common/sys/*.h` ; do \
++              $(LN) -fs $$i .; \
++      done; \
++      if [ -d ../../libc/sysdeps/linux/$(TARGET_ARCH)/sys ] ; then \
++              for i in `ls ../../libc/sysdeps/linux/$(TARGET_ARCH)/sys/*.h` ; do \
++                      $(LN) -fs $$i .; \
++              done; \
++      fi
++      @cd $(TOPDIR); \
++      set -e; \
++      $(SHELL_SET_X); \
++      TOPDIR=. CC="$(CC)" /bin/sh extra/scripts/gen_bits_syscall_h.sh > include/bits/sysnum.h.new; \
++      if cmp include/bits/sysnum.h include/bits/sysnum.h.new >/dev/null 2>&1; then \
++              $(RM) include/bits/sysnum.h.new; \
++      else \
++              mv -f include/bits/sysnum.h.new include/bits/sysnum.h; \
++      fi
++      $(MAKE) -C libc/sysdeps/linux/common headers
++      $(MAKE) -C libc/sysdeps/linux/$(TARGET_ARCH) headers
++
++# Command used to download source code
++WGET:=wget --passive-ftp
++
++LOCALE_DATA_FILENAME:=uClibc-locale-030818.tgz
++
++pregen: headers
++ifeq ($(strip $(UCLIBC_DOWNLOAD_PREGENERATED_LOCALE_DATA)),y)
++      (cd extra/locale; \
++      if [ ! -f $(LOCALE_DATA_FILENAME) ] ; then \
++      $(WGET) http://www.uclibc.org/downloads/$(LOCALE_DATA_FILENAME) ; \
++      fi );
++endif
++ifeq ($(strip $(UCLIBC_PREGENERATED_LOCALE_DATA)),y)
++      (cd extra/locale; zcat $(LOCALE_DATA_FILENAME) | tar -xvf -)
++      $(MAKE) -C extra/locale pregen
++endif
++
++
++subdirs: $(patsubst %, _dir_%, $(DIRS))
++$(patsubst %, _dir_%, $(DIRS)): headers
++      $(MAKE) -C $(patsubst _dir_%, %, $@)
++
++tags:
++      ctags -R
++
++install: install_runtime install_dev finished2
++
++
++RUNTIME_PREFIX_LIB_FROM_DEVEL_PREFIX_LIB=$(shell extra/scripts/relative_path.sh $(DEVEL_PREFIX)lib $(RUNTIME_PREFIX)lib)
++
++# Installs header files and development library links.
++install_dev:
++      $(INSTALL) -d $(PREFIX)$(DEVEL_PREFIX)lib
++      $(INSTALL) -d $(PREFIX)$(DEVEL_PREFIX)include
++      -$(INSTALL) -m 644 lib/*.[ao] $(PREFIX)$(DEVEL_PREFIX)lib/
++      if [ "$(KERNEL_SOURCE)" = "$(DEVEL_PREFIX)" ] ; then \
++              extra_exclude="--exclude include/linux --exclude include/asm'*'" ; \
++      else \
++              extra_exclude="" ; \
++      fi ; \
++      tar -chf - include --exclude .svn --exclude CVS $$extra_exclude \
++              | tar -xf - -C $(PREFIX)$(DEVEL_PREFIX)
++      echo '/* Dont use _syscall#() macros; use the syscall() function */' > \
++              $(PREFIX)$(DEVEL_PREFIX)include/bits/syscalls.h
++ifneq ($(strip $(UCLIBC_HAS_FLOATS)),y)
++      # Remove floating point related headers since float support is disabled.
++      $(RM) $(PREFIX)$(DEVEL_PREFIX)include/complex.h
++      $(RM) $(PREFIX)$(DEVEL_PREFIX)include/fpu_control.h
++      $(RM) $(PREFIX)$(DEVEL_PREFIX)include/ieee754.h
++      $(RM) $(PREFIX)$(DEVEL_PREFIX)include/math.h
++      $(RM) $(PREFIX)$(DEVEL_PREFIX)include/tgmath.h
++endif
++ifneq ($(strip $(UCLIBC_HAS_WCHAR)),y)
++      # Remove wide char headers since wide char support is disabled.
++      $(RM) $(PREFIX)$(DEVEL_PREFIX)include/wctype.h
++      $(RM) $(PREFIX)$(DEVEL_PREFIX)include/wchar.h
++endif
++ifneq ($(strip $(UCLIBC_HAS_LOCALE)),y)
++      # Remove iconv header since locale support is disabled.
++      $(RM) $(PREFIX)$(DEVEL_PREFIX)include/iconv.h
++endif
++ifneq ($(strip $(UCLIBC_HAS_GLIBC_CUSTOM_PRINTF)),y)
++      # Remove printf header since custom print specifier support is disabled.
++      $(RM) $(PREFIX)$(DEVEL_PREFIX)include/printf.h
++endif
++ifneq ($(strip $(UCLIBC_HAS_XLOCALE)),y)
++      # Remove xlocale header since extended locale support is disabled.
++      $(RM) $(PREFIX)$(DEVEL_PREFIX)include/xlocale.h
++endif
++ifneq ($(strip $(UCLIBC_HAS_GETTEXT_AWARENESS)),y)
++      # Remove libintl header since gettext support is disabled.
++      $(RM) $(PREFIX)$(DEVEL_PREFIX)include/libintl.h
++endif
++ifneq ($(strip $(UCLIBC_HAS_REGEX)),y)
++      # Remove regex headers since regex support is disabled.
++      $(RM) $(PREFIX)$(DEVEL_PREFIX)include/regex.h
++      $(RM) $(PREFIX)$(DEVEL_PREFIX)include/regexp.h
++endif
++ifneq ($(strip $(UCLIBC_HAS_WORDEXP)),y)
++      # Remove wordexp header since wordexp support is disabled.
++      $(RM) $(PREFIX)$(DEVEL_PREFIX)include/wordexp.h
++endif
++ifneq ($(strip $(UCLIBC_HAS_FTW)),y)
++      # Remove ftw header since ftw support is disabled.
++      $(RM) $(PREFIX)$(DEVEL_PREFIX)include/ftw.h
++endif
++ifneq ($(strip $(UCLIBC_HAS_GLOB)),y)
++      # Remove glob header since glob support is disabled.
++      $(RM) $(PREFIX)$(DEVEL_PREFIX)include/glob.h
++endif
++ifneq ($(strip $(UCLIBC_HAS_GNU_GETOPT)),y)
++      # Remove getopt header since gnu getopt support is disabled.
++      $(RM) $(PREFIX)$(DEVEL_PREFIX)include/getopt.h
++endif
++ifneq ($(strip $(HAS_SHADOW)),y)
++      # Remove getopt header since shadow password support is disabled.
++      $(RM) $(PREFIX)$(DEVEL_PREFIX)include/shadow.h
++endif
++      -@for i in `find  $(PREFIX)$(DEVEL_PREFIX) -type d` ; do \
++          chmod 755 $$i; chmod 644 $$i/*.h > /dev/null 2>&1; \
++      done;
++      -find $(PREFIX)$(DEVEL_PREFIX) -name .svn | xargs $(RM) -r;
++      -chown -R `id | sed 's/^uid=\([0-9]*\).*gid=\([0-9]*\).*$$/\1:\2/'` $(PREFIX)$(DEVEL_PREFIX)
++ifeq ($(strip $(HAVE_SHARED)),y)
++      for i in `find lib/ -type l -name 'lib[a-zA-Z]*.so' | \
++      sed -e 's/lib\///'` ; do \
++              $(LN) -sf $(RUNTIME_PREFIX_LIB_FROM_DEVEL_PREFIX_LIB)$$i.$(MAJOR_VERSION) \
++              $(PREFIX)$(DEVEL_PREFIX)lib/$$i; \
++      done;
++ifeq ($(strip $(PTHREADS_DEBUG_SUPPORT)),y)
++      $(LN) -sf $(RUNTIME_PREFIX_LIB_FROM_DEVEL_PREFIX_LIB)libthread_db.so.1 \
++              $(PREFIX)$(DEVEL_PREFIX)lib/libthread_db.so
++endif
++#     # If we build shared libraries then the static libs are PIC...
++#     # Make _pic.a symlinks to make mklibs.py and similar tools happy.
++      for i in `find lib/  -type f -name '*.a' | sed -e 's/lib\///'` ; do \
++              $(LN) -sf $$i $(PREFIX)$(DEVEL_PREFIX)lib/`echo $$i \
++                      | sed -e 's/\.a$$/_pic.a/'`; \
++      done;
++      # Ugh!!! Remember that libdl.a and libdl_pic.a are different.  Since
++      # libdl is pretty small, and not likely to benefit from mklibs.py and
++      # similar, lets just remove libdl_pic.a and avoid the issue
++      rm -f $(PREFIX)$(DEVEL_PREFIX)lib/libdl_pic.a
++endif
++
++
++# Installs run-time libraries
++install_runtime:
++ifeq ($(strip $(HAVE_SHARED)),y)
++      $(INSTALL) -d $(PREFIX)$(RUNTIME_PREFIX)lib
++      $(INSTALL) -m 644 lib/lib*-$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBLEVEL).so \
++              $(PREFIX)$(RUNTIME_PREFIX)lib
++      cp -dRf lib/*.so.* $(PREFIX)$(RUNTIME_PREFIX)lib
++      @if [ -x lib/ld-uClibc-$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBLEVEL).so ] ; then \
++          set -e; \
++              $(SHELL_SET_X); \
++          $(INSTALL) -m 755 lib/ld-uClibc-$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBLEVEL).so \
++                      $(PREFIX)$(RUNTIME_PREFIX)lib; \
++      fi;
++endif
++
++.PHONY: utils
++ifeq ($(strip $(HAVE_SHARED)),y)
++utils:
++      $(MAKE) CROSS="$(CROSS)" CC="$(CC)" -C utils
++else
++utils: dummy
++endif
++
++# Installs helper applications, such as 'ldd' and 'ldconfig'
++install_utils: utils
++      $(MAKE) CROSS="$(CROSS)" CC="$(CC)" -C utils install
++#ifeq ($(strip $(UCLIBC_HAS_LOCALE)),y)
++#     @$(MAKE) -C libc/misc/wchar iconv.target
++#     $(INSTALL) -d $(PREFIX)$(RUNTIME_PREFIX)/usr/bin;
++#     $(INSTALL) -m 755 libc/misc/wchar/iconv.target $(PREFIX)$(RUNTIME_PREFIX)/usr/bin/iconv
++#endif
++
++finished2:
++      $(SECHO)
++      $(SECHO) Finished installing ...
++      $(SECHO)
++
++else # ifeq ($(strip $(HAVE_DOT_CONFIG)),y)
++
++all: menuconfig
++
++# configuration
++# ---------------------------------------------------------------------------
++extra/config/conf:
++      $(MAKE) -C extra/config conf
++
++extra/config/mconf:
++      $(MAKE) -C extra/config ncurses mconf
++
++menuconfig: extra/config/mconf
++      $(RM) -r include/bits
++      $(INSTALL) -d include/bits
++      @./extra/config/mconf extra/Configs/Config.in
++
++config: extra/config/conf
++      $(RM) -r include/bits
++      $(INSTALL) -d include/bits
++      @./extra/config/conf extra/Configs/Config.in
++
++oldconfig: extra/config/conf
++      $(RM) -r include/bits
++      $(INSTALL) -d include/bits
++      @./extra/config/conf -o extra/Configs/Config.in
++
++randconfig: extra/config/conf
++      $(RM) -r include/bits
++      $(INSTALL) -d include/bits
++      @./extra/config/conf -r extra/Configs/Config.in
++
++allyesconfig: extra/config/conf
++      $(RM) -r include/bits
++      $(INSTALL) -d include/bits
++      @./extra/config/conf -y extra/Configs/Config.in
++      sed -i -e "s/^DODEBUG=.*/# DODEBUG is not set/" .config
++      sed -i -e "s/^DOASSERTS=.*/# DOASSERTS is not set/" .config
++      sed -i -e "s/^SUPPORT_LD_DEBUG_EARLY=.*/# SUPPORT_LD_DEBUG_EARLY is not set/" .config
++      sed -i -e "s/^SUPPORT_LD_DEBUG=.*/# SUPPORT_LD_DEBUG is not set/" .config
++      sed -i -e "s/^UCLIBC_MJN3_ONLY=.*/# UCLIBC_MJN3_ONLY is not set/" .config
++      @./extra/config/conf -o extra/Configs/Config.in
++
++allnoconfig: extra/config/conf
++      $(RM) -r include/bits
++      $(INSTALL) -d include/bits
++      @./extra/config/conf -n extra/Configs/Config.in
++
++defconfig: extra/config/conf
++      $(RM) -r include/bits
++      $(INSTALL) -d include/bits
++      @./extra/config/conf -d extra/Configs/Config.in
++
++clean:
++      - find . \( -name \*.o -o -name \*.a -o -name \*.so -o -name core -o -name .\#\* \) -exec $(RM) {} \;
++      @$(RM) -r tmp lib include/bits libc/tmp _install
++      $(RM) libc/obj.* headers
++      $(MAKE) -C test clean
++      $(MAKE) -C ldso clean
++      $(MAKE) -C libc/misc/internals clean
++      $(MAKE) -C libc/misc/wchar clean
++      $(MAKE) -C libc/unistd clean
++      $(MAKE) -C libc/sysdeps/linux/common clean
++      $(MAKE) -C extra/locale clean
++      $(MAKE) -C utils clean
++      @set -e; \
++      for i in `(cd $(TOPDIR)/libc/sysdeps/linux/common/sys; ls *.h)` ; do \
++              $(RM) include/sys/$$i; \
++      done; \
++      if [ -d libc/sysdeps/linux/$(TARGET_ARCH)/sys ] ; then \
++              for i in `(cd libc/sysdeps/linux/$(TARGET_ARCH)/sys; ls *.h)` ; do \
++                      $(RM) include/sys/$$i; \
++              done; \
++      fi;
++      @$(RM) include/linux include/asm*
++      @if [ -d libc/sysdeps/linux/$(TARGET_ARCH) ]; then              \
++          $(MAKE) -C libc/sysdeps/linux/$(TARGET_ARCH) clean;         \
++      fi;
++
++distclean: clean
++      $(RM) .config .config.old .config.cmd
++      $(MAKE) -C extra clean
++
++dist release:
++      $(RM) -r ../uClibc-$(VERSION) ../uClibc-$(VERSION).tar.bz2
++      svn -q export . ../uClibc-$(VERSION)
++      tar cjf ../uClibc-$(VERSION).tar.bz2 -C .. uClibc-$(VERSION)
++      du -b ../uClibc-$(VERSION).tar.bz2
++
++endif # ifeq ($(strip $(HAVE_DOT_CONFIG)),y)
++
++check:
++      $(MAKE) -C test
++
++.PHONY: dummy subdirs release distclean clean config oldconfig menuconfig
+diff -Nrup a/Rules.mak b/Rules.mak
+--- a/Rules.mak        2007-02-28 16:12:06.000000000 -0500
++++ b/Rules.mak        2008-02-28 19:02:10.000000000 -0500
+@@ -234,6 +234,12 @@ ifeq ($(strip $(TARGET_ARCH)),frv)
+       UCLIBC_LDSO=ld.so.1
+ endif
++ifeq ($(strip $(TARGET_ARCH)),avr32)
++      CPU_CFLAGS-$(CONFIG_AP7000)     += -mcpu=ap7000
++      CPU_CFLAGS-$(LINKRELAX)         += -masm-addr-pseudos -Wa,--pic,--linkrelax
++      CPU_LDFLAGS-$(LINKRELAX)        += --relax
++endif
++
+ # Keep the check_gcc from being needlessly executed
+ ifndef PIEFLAG
+ ifneq ($(UCLIBC_BUILD_PIE),y)
+diff -Nrup a/Rules.mak.orig b/Rules.mak.orig
+--- a/Rules.mak.orig   1969-12-31 19:00:00.000000000 -0500
++++ b/Rules.mak.orig   2008-02-28 19:02:10.000000000 -0500
+@@ -0,0 +1,361 @@
++# Rules.make for uClibc
++#
++# Copyright (C) 2000 by Lineo, inc.
++# Copyright (C) 2000-2002 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
++
++
++#-----------------------------------------------------------
++# This file contains rules which are shared between multiple
++# Makefiles.  All normal configuration options live in the 
++# file named ".config".  Don't mess with this file unless 
++# you know what you are doing.
++
++
++#-----------------------------------------------------------
++# If you are running a cross compiler, you will want to set 
++# 'CROSS' to something more interesting ...  Target 
++# architecture is determined by asking the CC compiler what 
++# arch it compiles things for, so unless your compiler is 
++# broken, you should not need to specify TARGET_ARCH.
++#
++# Most people will set this stuff on the command line, i.e.
++#        make CROSS=arm-linux-
++# will build uClibc for 'arm'.
++
++ifndef CROSS
++CROSS=
++endif
++CC         = $(CROSS)gcc
++AR         = $(CROSS)ar
++LD         = $(CROSS)ld
++NM         = $(CROSS)nm
++RANLIB     = $(CROSS)ranlib
++STRIPTOOL  = $(CROSS)strip
++
++INSTALL    = install
++LN         = ln
++RM         = rm -f
++
++# Select the compiler needed to build binaries for your development system
++HOSTCC     = gcc
++HOSTCFLAGS = -O2 -Wall
++
++
++#---------------------------------------------------------
++# Nothing beyond this point should ever be touched by mere
++# mortals.  Unless you hang out with the gods, you should
++# probably leave all this stuff alone.
++MAJOR_VERSION := 0
++MINOR_VERSION := 9
++SUBLEVEL      := 28
++EXTRAVERSION  := 3
++VERSION       := $(MAJOR_VERSION).$(MINOR_VERSION).$(SUBLEVEL).$(EXTRAVERSION)
++# Ensure consistent sort order, 'gcc -print-search-dirs' behavior, etc.
++LC_ALL := C
++export MAJOR_VERSION MINOR_VERSION SUBLEVEL VERSION LC_ALL
++
++SHARED_FULLNAME:=libuClibc-$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBLEVEL).so
++SHARED_MAJORNAME:=libc.so.$(MAJOR_VERSION)
++UCLIBC_LDSO:=ld-uClibc.so.$(MAJOR_VERSION)
++LIBNAME:=libc.a
++LIBC:=$(TOPDIR)libc/$(LIBNAME)
++
++# Make sure DESTDIR and PREFIX can be used to install
++# PREFIX is a uClibcism while DESTDIR is a common GNUism
++ifndef PREFIX
++PREFIX = $(DESTDIR)
++endif
++
++# Pull in the user's uClibc configuration
++ifeq ($(filter $(noconfig_targets),$(MAKECMDGOALS)),)
++-include $(TOPDIR).config
++endif
++
++ifndef CROSS
++CROSS=$(subst ",, $(strip $(CROSS_COMPILER_PREFIX)))
++endif
++
++# A nifty macro to make testing gcc features easier
++check_gcc=$(shell \
++      if $(CC) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; \
++      then echo "$(1)"; else echo "$(2)"; fi)
++check_as=$(shell \
++      if $(CC) -Wa,$(1) -Wa,-Z -c -o /dev/null -xassembler /dev/null > /dev/null 2>&1; \
++      then echo "-Wa,$(1)"; fi)
++
++# Setup some shortcuts so that silent mode is silent like it should be
++ifeq ($(subst s,,$(MAKEFLAGS)),$(MAKEFLAGS))
++export MAKE_IS_SILENT=n
++SECHO=@echo
++SHELL_SET_X=set -x
++else
++export MAKE_IS_SILENT=y
++SECHO=-@false
++SHELL_SET_X=set +x
++endif
++
++# Make certain these contain a final "/", but no "//"s.
++TARGET_ARCH:=$(shell grep -s ^TARGET_ARCH $(TOPDIR)/.config | sed -e 's/^TARGET_ARCH=//' -e 's/"//g')
++RUNTIME_PREFIX:=$(strip $(subst //,/, $(subst ,/, $(subst ",, $(strip $(RUNTIME_PREFIX))))))
++DEVEL_PREFIX:=$(strip $(subst //,/, $(subst ,/, $(subst ",, $(strip $(DEVEL_PREFIX))))))
++export RUNTIME_PREFIX DEVEL_PREFIX
++
++ARFLAGS:=cr
++
++OPTIMIZATION:=
++PICFLAG:=-fPIC
++PIEFLAG_NAME:=-fPIE
++
++# Some nice CPU specific optimizations
++ifeq ($(strip $(TARGET_ARCH)),i386)
++      OPTIMIZATION+=$(call check_gcc,-mpreferred-stack-boundary=2,)
++      OPTIMIZATION+=$(call check_gcc,-falign-jumps=0 -falign-loops=0,-malign-jumps=0 -malign-loops=0)
++      CPU_CFLAGS-$(CONFIG_386)+=-march=i386
++      CPU_CFLAGS-$(CONFIG_486)+=-march=i486
++      CPU_CFLAGS-$(CONFIG_ELAN)+=-march=i486
++      CPU_CFLAGS-$(CONFIG_586)+=-march=i586
++      CPU_CFLAGS-$(CONFIG_586MMX)+=$(call check_gcc,-march=pentium-mmx,-march=i586)
++      CPU_CFLAGS-$(CONFIG_686)+=-march=i686
++      CPU_CFLAGS-$(CONFIG_PENTIUMII)+=$(call check_gcc,-march=pentium2,-march=i686)
++      CPU_CFLAGS-$(CONFIG_PENTIUMIII)+=$(call check_gcc,-march=pentium3,-march=i686)
++      CPU_CFLAGS-$(CONFIG_PENTIUM4)+=$(call check_gcc,-march=pentium4,-march=i686)
++      CPU_CFLAGS-$(CONFIG_K6)+=$(call check_gcc,-march=k6,-march=i586)
++      CPU_CFLAGS-$(CONFIG_K7)+=$(call check_gcc,-march=athlon,-malign-functions=4 -march=i686)
++      CPU_CFLAGS-$(CONFIG_CRUSOE)+=-march=i686 -malign-functions=0 -malign-jumps=0 -malign-loops=0
++      CPU_CFLAGS-$(CONFIG_WINCHIPC6)+=$(call check_gcc,-march=winchip-c6,-march=i586)
++      CPU_CFLAGS-$(CONFIG_WINCHIP2)+=$(call check_gcc,-march=winchip2,-march=i586)
++      CPU_CFLAGS-$(CONFIG_CYRIXIII)+=$(call check_gcc,-march=c3,-march=i486) -malign-functions=0 -malign-jumps=0 -malign-loops=0
++      CPU_CFLAGS-$(CONFIG_NEHEMIAH)+=$(call check_gcc,-march=c3-2,-march=i686)
++endif
++
++ifeq ($(strip $(TARGET_ARCH)),arm)
++      OPTIMIZATION+=-fstrict-aliasing
++      CPU_LDFLAGS-$(ARCH_LITTLE_ENDIAN)+=-EL
++      CPU_LDFLAGS-$(ARCH_BIG_ENDIAN)+=-EB
++      CPU_CFLAGS-$(ARCH_LITTLE_ENDIAN)+=-mlittle-endian
++      CPU_CFLAGS-$(ARCH_BIG_ENDIAN)+=-mbig-endian
++      CPU_CFLAGS-$(CONFIG_GENERIC_ARM)+=
++      CPU_CFLAGS-$(CONFIG_ARM610)+=-mtune=arm610 -march=armv3
++      CPU_CFLAGS-$(CONFIG_ARM710)+=-mtune=arm710 -march=armv3
++      CPU_CFLAGS-$(CONFIG_ARM720T)+=-mtune=arm7tdmi -march=armv4
++      CPU_CFLAGS-$(CONFIG_ARM920T)+=-mtune=arm9tdmi -march=armv4
++      CPU_CFLAGS-$(CONFIG_ARM922T)+=-mtune=arm9tdmi -march=armv4
++      CPU_CFLAGS-$(CONFIG_ARM926T)+=-mtune=arm9tdmi -march=armv5
++      CPU_CFLAGS-$(CONFIG_ARM1136JF_S)+=-mtune=arm1136jf-s -march=armv6
++      CPU_CFLAGS-$(CONFIG_ARM_SA110)+=-mtune=strongarm110 -march=armv4
++      CPU_CFLAGS-$(CONFIG_ARM_SA1100)+=-mtune=strongarm1100 -march=armv4
++      CPU_CFLAGS-$(CONFIG_ARM_XSCALE)+=$(call check_gcc,-mtune=xscale,-mtune=strongarm110)
++      CPU_CFLAGS-$(CONFIG_ARM_XSCALE)+=-march=armv4 -Wa,-mcpu=xscale
++endif
++
++ifeq ($(strip $(TARGET_ARCH)),mips)
++      CPU_CFLAGS-$(CONFIG_MIPS_ISA_1)+=-mips1
++      CPU_CFLAGS-$(CONFIG_MIPS_ISA_2)+=-mips2 -mtune=mips2
++      CPU_CFLAGS-$(CONFIG_MIPS_ISA_3)+=-mips3 -mtune=mips3
++      CPU_CFLAGS-$(CONFIG_MIPS_ISA_4)+=-mips4 -mtune=mips4
++      CPU_CFLAGS-$(CONFIG_MIPS_ISA_MIPS32)+=-mips32 -mtune=mips32
++      CPU_CFLAGS-$(CONFIG_MIPS_ISA_MIPS64)+=-mips64 -mtune=mips32
++endif
++
++ifeq ($(strip $(TARGET_ARCH)),sh)
++      OPTIMIZATION+=-fstrict-aliasing
++      OPTIMIZATION+= $(call check_gcc,-mprefergot,)
++      CPU_LDFLAGS-$(ARCH_LITTLE_ENDIAN)+=-EL
++      CPU_LDFLAGS-$(ARCH_BIG_ENDIAN)+=-EB
++      CPU_CFLAGS-$(ARCH_LITTLE_ENDIAN)+=-ml
++      CPU_CFLAGS-$(ARCH_BIG_ENDIAN)+=-mb
++      CPU_CFLAGS-$(CONFIG_SH2)+=-m2
++      CPU_CFLAGS-$(CONFIG_SH3)+=-m3
++ifeq ($(strip $(UCLIBC_HAS_FLOATS)),y)
++      CPU_CFLAGS-$(CONFIG_SH2A)+=-m2a
++      CPU_CFLAGS-$(CONFIG_SH4)+=-m4
++else
++      CPU_CFLAGS-$(CONFIG_SH2A)+=-m2a-nofpu
++      CPU_CFLAGS-$(CONFIG_SH4)+=-m4-nofpu
++endif
++endif
++
++ifeq ($(strip $(TARGET_ARCH)),sh64)
++      OPTIMIZATION+=-fstrict-aliasing
++      CPU_LDFLAGS-$(ARCH_LITTLE_ENDIAN):=-EL
++      CPU_LDFLAGS-$(ARCH_BIG_ENDIAN):=-EB
++      CPU_CFLAGS-$(ARCH_LITTLE_ENDIAN):=-ml
++      CPU_CFLAGS-$(ARCH_BIG_ENDIAN):=-mb
++      CPU_CFLAGS-$(CONFIG_SH5)+=-m5-32media
++endif
++
++ifeq ($(strip $(TARGET_ARCH)),h8300)
++      CPU_LDFLAGS-$(CONFIG_H8300H)+= -ms8300h
++      CPU_LDFLAGS-$(CONFIG_H8S)   += -ms8300s
++      CPU_CFLAGS-$(CONFIG_H8300H) += -mh -mint32 -fsigned-char
++      CPU_CFLAGS-$(CONFIG_H8S)    += -ms -mint32 -fsigned-char
++endif
++
++ifeq ($(strip $(TARGET_ARCH)),cris)
++      CPU_LDFLAGS-$(CONFIG_CRIS)+=-mcrislinux
++      CPU_CFLAGS-$(CONFIG_CRIS)+=-mlinux
++      PICFLAG:=-fpic
++      PIEFLAG_NAME:=-fpie
++endif
++
++ifeq ($(strip $(TARGET_ARCH)),powerpc)
++# PowerPC can hold 8192 entries in its GOT with -fpic which is more than
++# enough. Therefore use -fpic which will reduce code size and generates
++# faster code.
++      PICFLAG:=-fpic
++      PIEFLAG_NAME:=-fpie
++      PPC_HAS_REL16:=$(shell echo -e "\t.text\n\taddis 11,30,_GLOBAL_OFFSET_TABLE_-.@ha" | $(CC) -c -x assembler -o /dev/null -  2> /dev/null && echo -n y || echo -n n)
++      CPU_CFLAGS-$(PPC_HAS_REL16)+= -DHAVE_ASM_PPC_REL16
++endif
++
++ifeq ($(strip $(TARGET_ARCH)),frv)
++      CPU_LDFLAGS-$(CONFIG_FRV)+=-melf32frvfd
++      CPU_CFLAGS-$(CONFIG_FRV)+=-mfdpic
++      # Using -pie causes the program to have an interpreter, which is
++      # forbidden, so we must make do with -shared.  Unfortunately,
++      # -shared by itself would get us global function descriptors
++      # and calls through PLTs, dynamic resolution of symbols, etc,
++      # which would break as well, but -Bsymbolic comes to the rescue.
++      export LDPIEFLAG:=-shared -Bsymbolic
++      UCLIBC_LDSO=ld.so.1
++endif
++
++ifeq ($(strip $(TARGET_ARCH)),avr32)
++      CPU_CFLAGS-$(CONFIG_AP7000)     += -mcpu=ap7000
++endif
++
++# Keep the check_gcc from being needlessly executed
++ifndef PIEFLAG
++ifneq ($(UCLIBC_BUILD_PIE),y)
++export PIEFLAG:=
++else
++export PIEFLAG:=$(call check_gcc,$(PIEFLAG_NAME),$(PICFLAG))
++endif
++endif
++# We need to keep track of both the CC PIE flag (above) as 
++# well as the LD PIE flag (below) because we can't rely on 
++# gcc passing -pie if we used -fPIE
++ifndef LDPIEFLAG
++ifneq ($(UCLIBC_BUILD_PIE),y)
++export LDPIEFLAG:=
++else
++export LDPIEFLAG:=$(shell $(LD) --help | grep -q pie && echo "-Wl,-pie")
++endif
++endif
++
++# Use '-Os' optimization if available, else use -O2, allow Config to override
++OPTIMIZATION+=$(call check_gcc,-Os,-O2)
++# Use the gcc 3.4 -funit-at-a-time optimization when available
++OPTIMIZATION+=$(call check_gcc,-funit-at-a-time,)
++
++# Add a bunch of extra pedantic annoyingly strict checks
++XWARNINGS=$(subst ",, $(strip $(WARNINGS))) -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing
++XARCH_CFLAGS=$(subst ",, $(strip $(ARCH_CFLAGS)))
++CPU_CFLAGS=$(subst ",, $(strip $(CPU_CFLAGS-y)))
++
++LDADD_LIBFLOAT=
++ifeq ($(strip $(UCLIBC_HAS_SOFT_FLOAT)),y)
++# Add -msoft-float to the CPU_FLAGS since ldso and libdl ignore CFLAGS.
++# If -msoft-float isn't supported, we want an error anyway.
++# Hmm... might need to revisit this for arm since it has 2 different
++# soft float encodings.
++    CPU_CFLAGS += -msoft-float
++ifeq ($(strip $(TARGET_ARCH)),arm)
++# No longer needed with current toolchains, but leave it here for now.
++# If anyone is actually still using gcc 2.95 (say), they can uncomment it.
++#    LDADD_LIBFLOAT=-lfloat
++endif
++endif
++
++SSP_DISABLE_FLAGS:=$(call check_gcc,-fno-stack-protector,)
++ifeq ($(UCLIBC_BUILD_SSP),y)
++SSP_CFLAGS:=$(call check_gcc,-fno-stack-protector-all,)
++SSP_CFLAGS+=$(call check_gcc,-fstack-protector,)
++SSP_ALL_CFLAGS:=$(call check_gcc,-fstack-protector-all,)
++else
++SSP_CFLAGS:=$(SSP_DISABLE_FLAGS)
++endif
++
++# Some nice CFLAGS to work with
++CFLAGS:=$(XWARNINGS) $(CPU_CFLAGS) $(SSP_CFLAGS) \
++      -fno-builtin -nostdinc -D_LIBC -I$(TOPDIR)include -I.
++LDFLAGS_NOSTRIP:=$(CPU_LDFLAGS-y) -shared --warn-common --warn-once -z combreloc -z defs
++
++ifeq ($(DODEBUG),y)
++    #CFLAGS += -g3
++    CFLAGS += -O0 -g3
++    LDFLAGS := $(LDFLAGS_NOSTRIP)
++    STRIPTOOL:= true -Since_we_are_debugging
++else
++    CFLAGS += $(OPTIMIZATION) $(XARCH_CFLAGS)
++    LDFLAGS := $(LDFLAGS_NOSTRIP) -s
++endif
++
++ifeq ($(UCLIBC_BUILD_RELRO),y)
++LDFLAGS+=-z relro
++endif
++
++ifeq ($(UCLIBC_BUILD_NOW),y)
++LDFLAGS+=-z now
++endif
++
++# Sigh, some stupid versions of gcc can't seem to cope with '-iwithprefix include'
++#CFLAGS+=-iwithprefix include
++CFLAGS+=-isystem $(shell $(CC) -print-file-name=include)
++
++ifneq ($(DOASSERTS),y)
++    CFLAGS += -DNDEBUG
++endif
++
++CFLAGS_NOPIC:=$(CFLAGS)
++ifeq ($(DOPIC),y)
++    CFLAGS += $(PICFLAG)
++endif
++
++ifeq ($(DL_FINI_CRT_COMPAT),y)
++CFLAGS += -D_DL_FINI_CRT_COMPAT
++endif
++
++# Keep the check_as from being needlessly executed
++ASFLAGS = $(CFLAGS)
++ifndef ASFLAGS_NOEXEC
++ifeq ($(UCLIBC_BUILD_NOEXECSTACK),y)
++export ASFLAGS_NOEXEC := $(call check_as,--noexecstack)
++else
++export ASFLAGS_NOEXEC :=
++endif
++endif
++ASFLAGS += $(ASFLAGS_NOEXEC)
++
++LIBGCC_CFLAGS ?= $(CFLAGS) $(CPU_CFLAGS-y)
++LIBGCC:=$(shell $(CC) $(LIBGCC_CFLAGS) -print-libgcc-file-name)
++LIBGCC_DIR:=$(dir $(LIBGCC))
++
++########################################
++#
++# uClinux shared lib support
++#
++
++ifeq ($(CONFIG_BINFMT_SHARED_FLAT),y)
++  # For the shared version of this, we specify no stack and its library ID
++  FLTFLAGS += -s 0
++  LIBID=1
++  export LIBID FLTFLAGS
++  SHARED_TARGET = lib/libc
++endif
++
++TARGET_ARCH:=$(strip $(subst ",, $(strip $(TARGET_ARCH))))
+diff -Nrup a/utils/ldd.c b/utils/ldd.c
+--- a/utils/ldd.c      2004-10-06 03:34:17.000000000 -0400
++++ b/utils/ldd.c      2008-02-28 19:02:10.000000000 -0500
+@@ -56,6 +56,11 @@
+ #define ELFCLASSM     ELFCLASS32
+ #endif
++#if defined(__avr32__)
++#define MATCH_MACHINE(x) (x == EM_AVR32)
++#define ELFCLASSM     ELFCLASS32
++#endif
++
+ #if defined(__s390__)
+ #define MATCH_MACHINE(x) (x == EM_S390)
+ #define ELFCLASSM     ELFCLASS32
diff --git a/toolchain/uClibc/uClibc-0.9.29-002-atmel.1.patch b/toolchain/uClibc/uClibc-0.9.29-002-atmel.1.patch
new file mode 100644 (file)
index 0000000..d275ac2
--- /dev/null
@@ -0,0 +1,3546 @@
+diff --git a/Rules.mak b/Rules.mak
+index d054bbb..55381cf 100644
+--- a/Rules.mak
++++ b/Rules.mak
+@@ -313,6 +313,12 @@ ifeq ($(TARGET_ARCH),frv)
+       UCLIBC_LDSO=ld.so.1
+ endif
++ifeq ($(strip $(TARGET_ARCH)),avr32)
++      CPU_CFLAGS-$(CONFIG_AVR32_AP7)  += -march=ap
++      CPU_CFLAGS-$(CONFIG_LINKRELAX)  += -mrelax
++      CPU_LDFLAGS-$(CONFIG_LINKRELAX) += --relax
++endif
++
+ # Keep the check_gcc from being needlessly executed
+ ifndef PIEFLAG
+ ifneq ($(UCLIBC_BUILD_PIE),y)
+diff --git a/extra/Configs/Config.avr32 b/extra/Configs/Config.avr32
+new file mode 100644
+index 0000000..8d70e6e
+--- /dev/null
++++ b/extra/Configs/Config.avr32
+@@ -0,0 +1,31 @@
++#
++# For a description of the syntax of this configuration file,
++# see extra/config/Kconfig-language.txt
++#
++
++config TARGET_ARCH
++      string
++      default "avr32"
++
++config FORCE_OPTIONS_FOR_ARCH
++      bool
++      default y
++      select ARCH_BIG_ENDIAN
++      select FORCE_SHAREABLE_TEXT_SEGMENTS
++
++config ARCH_CFLAGS
++      string
++
++choice
++      prompt "Target CPU Type"
++      default CONFIG_AVR32_AP7
++
++config CONFIG_AVR32_AP7
++      bool "AVR32 AP7"
++      select ARCH_HAS_MMU
++
++endchoice
++
++config LINKRELAX
++      bool "Enable linker optimizations"
++      default y
+diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in
+index 8eab394..10c9f7b 100644
+--- a/extra/Configs/Config.in
++++ b/extra/Configs/Config.in
+@@ -16,6 +16,9 @@ config TARGET_alpha
+ config TARGET_arm
+       bool "arm"
++config TARGET_avr32
++      bool "avr32"
++
+ config TARGET_bfin
+       bool "bfin"
+@@ -92,6 +95,10 @@ if TARGET_arm
+ source "extra/Configs/Config.arm"
+ endif
++if TARGET_avr32
++source "extra/Configs/Config.avr32"
++endif
++
+ if TARGET_bfin
+ source "extra/Configs/Config.bfin"
+ endif
+diff --git a/extra/Configs/defconfigs/avr32 b/extra/Configs/defconfigs/avr32
+new file mode 100644
+index 0000000..0b890a2
+--- /dev/null
++++ b/extra/Configs/defconfigs/avr32
+@@ -0,0 +1 @@
++TARGET_avr32=y
+diff --git a/include/elf.h b/include/elf.h
+index 19805d7..ab90160 100644
+--- a/include/elf.h
++++ b/include/elf.h
+@@ -354,6 +354,8 @@ typedef struct
+ /* NIOS magic number - no EABI available.  */
+ #define EM_NIOS32     0xFEBB
++#define EM_AVR32      0x18ad
++
+ /* V850 backend magic number.  Written in the absense of an ABI.  */
+ #define EM_CYGNUS_V850 0x9080
+@@ -2828,6 +2830,55 @@ typedef Elf32_Addr Elf32_Conflict;
+ /* Keep this the last entry.  */
+ #define R_V850_NUM            25
++/* Atmel AVR32 relocations.  */
++#define R_AVR32_NONE          0
++#define R_AVR32_32            1
++#define R_AVR32_16            2
++#define R_AVR32_8             3
++#define R_AVR32_32_PCREL      4
++#define R_AVR32_16_PCREL      5
++#define R_AVR32_8_PCREL               6
++#define R_AVR32_DIFF32                7
++#define R_AVR32_DIFF16                8
++#define R_AVR32_DIFF8         9
++#define R_AVR32_GOT32         10
++#define R_AVR32_GOT16         11
++#define R_AVR32_GOT8          12
++#define R_AVR32_21S           13
++#define R_AVR32_16U           14
++#define R_AVR32_16S           15
++#define R_AVR32_8S            16
++#define R_AVR32_8S_EXT                17
++#define R_AVR32_22H_PCREL     18
++#define R_AVR32_18W_PCREL     19
++#define R_AVR32_16B_PCREL     20
++#define R_AVR32_16N_PCREL     21
++#define R_AVR32_14UW_PCREL    22
++#define R_AVR32_11H_PCREL     23
++#define R_AVR32_10UW_PCREL    24
++#define R_AVR32_9H_PCREL      25
++#define R_AVR32_9UW_PCREL     26
++#define R_AVR32_HI16          27
++#define R_AVR32_LO16          28
++#define R_AVR32_GOTPC         29
++#define R_AVR32_GOTCALL               30
++#define R_AVR32_LDA_GOT               31
++#define R_AVR32_GOT21S                32
++#define R_AVR32_GOT18SW               33
++#define R_AVR32_GOT16S                34
++#define R_AVR32_GOT7UW                35
++#define R_AVR32_32_CPENT      36
++#define R_AVR32_CPCALL                37
++#define R_AVR32_16_CP         38
++#define R_AVR32_9W_CP         39
++#define R_AVR32_RELATIVE      40
++#define R_AVR32_GLOB_DAT      41
++#define R_AVR32_JMP_SLOT      42
++#define R_AVR32_ALIGN         43
++#define R_AVR32_NUM           44
++
++/* AVR32 dynamic tags */
++#define DT_AVR32_GOTSZ                0x70000001 /* Total size of GOT in bytes */
+ /* Renesas H8/300 Relocations */
+ #define R_H8_NONE       0
+diff --git a/ldso/include/dl-string.h b/ldso/include/dl-string.h
+index 32c5bf8..eb43bd9 100644
+--- a/ldso/include/dl-string.h
++++ b/ldso/include/dl-string.h
+@@ -285,7 +285,8 @@ static __always_inline char * _dl_simple_ltoahex(char * local, unsigned long i)
+ /* On some arches constant strings are referenced through the GOT.
+  * This requires that load_addr must already be defined... */
+ #if defined(mc68000)  || defined(__arm__) || defined(__thumb__) || \
+-    defined(__mips__) || defined(__sh__)  || defined(__powerpc__)
++    defined(__mips__) || defined(__sh__)  || defined(__powerpc__) || \
++      defined(__avr32__)
+ # define CONSTANT_STRING_GOT_FIXUP(X) \
+       if ((X) < (const char *) load_addr) (X) += load_addr
+ # define NO_EARLY_SEND_STDERR
+diff --git a/ldso/include/dl-syscall.h b/ldso/include/dl-syscall.h
+index b42416a..4404219 100644
+--- a/ldso/include/dl-syscall.h
++++ b/ldso/include/dl-syscall.h
+@@ -55,69 +55,69 @@
+    dynamic linking at all, so we cannot return any error codes.
+    We just punt if there is an error. */
+ #define __NR__dl_exit __NR_exit
+-static inline _syscall1(void, _dl_exit, int, status);
++static __always_inline _syscall1(void, _dl_exit, int, status);
+ #define __NR__dl_close __NR_close
+-static inline _syscall1(int, _dl_close, int, fd);
++static __always_inline _syscall1(int, _dl_close, int, fd);
+ #define __NR__dl_open __NR_open
+-static inline _syscall3(int, _dl_open, const char *, fn, int, flags,
++static __always_inline _syscall3(int, _dl_open, const char *, fn, int, flags,
+                         __kernel_mode_t, mode);
+ #define __NR__dl_write __NR_write
+-static inline _syscall3(unsigned long, _dl_write, int, fd,
++static __always_inline _syscall3(unsigned long, _dl_write, int, fd,
+                         const void *, buf, unsigned long, count);
+ #define __NR__dl_read __NR_read
+-static inline _syscall3(unsigned long, _dl_read, int, fd,
++static __always_inline _syscall3(unsigned long, _dl_read, int, fd,
+                         const void *, buf, unsigned long, count);
+ #define __NR__dl_mprotect __NR_mprotect
+-static inline _syscall3(int, _dl_mprotect, const void *, addr,
++static __always_inline _syscall3(int, _dl_mprotect, const void *, addr,
+                         unsigned long, len, int, prot);
+ #define __NR__dl_stat __NR_stat
+-static inline _syscall2(int, _dl_stat, const char *, file_name,
++static __always_inline _syscall2(int, _dl_stat, const char *, file_name,
+                         struct stat *, buf);
+ #define __NR__dl_fstat __NR_fstat
+-static inline _syscall2(int, _dl_fstat, int, fd, struct stat *, buf);
++static __always_inline _syscall2(int, _dl_fstat, int, fd, struct stat *, buf);
+ #define __NR__dl_munmap __NR_munmap
+-static inline _syscall2(int, _dl_munmap, void *, start, unsigned long, length);
++static __always_inline _syscall2(int, _dl_munmap, void *, start, unsigned long, length);
+ #ifdef __NR_getxuid
+ # define __NR_getuid __NR_getxuid
+ #endif
+ #define __NR__dl_getuid __NR_getuid
+-static inline _syscall0(uid_t, _dl_getuid);
++static __always_inline _syscall0(uid_t, _dl_getuid);
+ #ifndef __NR_geteuid
+ # define __NR_geteuid __NR_getuid
+ #endif
+ #define __NR__dl_geteuid __NR_geteuid
+-static inline _syscall0(uid_t, _dl_geteuid);
++static __always_inline _syscall0(uid_t, _dl_geteuid);
+ #ifdef __NR_getxgid
+ # define __NR_getgid __NR_getxgid
+ #endif
+ #define __NR__dl_getgid __NR_getgid
+-static inline _syscall0(gid_t, _dl_getgid);
++static __always_inline _syscall0(gid_t, _dl_getgid);
+ #ifndef __NR_getegid
+ # define __NR_getegid __NR_getgid
+ #endif
+ #define __NR__dl_getegid __NR_getegid
+-static inline _syscall0(gid_t, _dl_getegid);
++static __always_inline _syscall0(gid_t, _dl_getegid);
+ #ifdef __NR_getxpid
+ # define __NR_getpid __NR_getxpid
+ #endif
+ #define __NR__dl_getpid __NR_getpid
+-static inline _syscall0(gid_t, _dl_getpid);
++static __always_inline _syscall0(gid_t, _dl_getpid);
+ #define __NR__dl_readlink __NR_readlink
+-static inline _syscall3(int, _dl_readlink, const char *, path, char *, buf,
++static __always_inline _syscall3(int, _dl_readlink, const char *, path, char *, buf,
+                         size_t, bufsiz);
+ #ifdef __UCLIBC_HAS_SSP__
+@@ -146,14 +146,14 @@ static inline _syscall2(int, _dl_gettimeofday, struct timeval *, tv,
+ #if defined(__UCLIBC_MMAP_HAS_6_ARGS__) && defined(__NR_mmap)
+ # define __NR__dl_mmap __NR_mmap
+-static inline _syscall6(void *, _dl_mmap, void *, start, size_t, length,
++static __always_inline _syscall6(void *, _dl_mmap, void *, start, size_t, length,
+                         int, prot, int, flags, int, fd, off_t, offset);
+ /* then try mmap2() */
+ #elif defined(__NR_mmap2)
+ # define __NR___syscall_mmap2       __NR_mmap2
+-static inline _syscall6(__ptr_t, __syscall_mmap2, __ptr_t, addr, size_t, len,
++static __always_inline _syscall6(__ptr_t, __syscall_mmap2, __ptr_t, addr, size_t, len,
+                         int, prot, int, flags, int, fd, off_t, offset);
+ /* Some architectures always use 12 as page shift for mmap2() eventhough the
+@@ -164,7 +164,7 @@ static inline _syscall6(__ptr_t, __syscall_mmap2, __ptr_t, addr, size_t, len,
+ # define MMAP2_PAGE_SHIFT 12
+ #endif
+-static inline void * _dl_mmap(void * addr, unsigned long size, int prot,
++static __always_inline void * _dl_mmap(void * addr, unsigned long size, int prot,
+                               int flags, int fd, unsigned long offset)
+ {
+       if (offset & ((1 << MMAP2_PAGE_SHIFT) - 1))
+@@ -177,8 +177,8 @@ static inline void * _dl_mmap(void * addr, unsigned long size, int prot,
+ #elif defined(__NR_mmap)
+ # define __NR__dl_mmap_real __NR_mmap
+-static inline _syscall1(void *, _dl_mmap_real, unsigned long *, buffer);
+-static inline void * _dl_mmap(void * addr, unsigned long size, int prot,
++static __always_inline _syscall1(void *, _dl_mmap_real, unsigned long *, buffer);
++static __always_inline void * _dl_mmap(void * addr, unsigned long size, int prot,
+                               int flags, int fd, unsigned long offset)
+ {
+       unsigned long buffer[6];
+diff --git a/ldso/ldso/avr32/dl-debug.h b/ldso/ldso/avr32/dl-debug.h
+new file mode 100644
+index 0000000..fe35539
+--- /dev/null
++++ b/ldso/ldso/avr32/dl-debug.h
+@@ -0,0 +1,45 @@
++/*
++ * AVR32 ELF shared libary loader support
++ *
++ * Copyright (C) 2005-2007 Atmel Corporation
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. The name of the above contributors may not be
++ *    used to endorse or promote products derived from this software
++ *    without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ */
++
++static const char *_dl_reltypes_tab[] = {
++    "R_AVR32_NONE",
++    "R_AVR32_32", "R_AVR32_16", "R_AVR32_8",
++    "R_AVR32_32_PCREL", "R_AVR32_16_PCREL", "R_AVR32_8_PCREL",
++    "R_AVR32_DIFF32", "R_AVR32_DIFF16", "R_AVR32_DIFF8",
++    "R_AVR32_GOT32", "R_AVR32_GOT16", "R_AVR32_GOT8",
++    "R_AVR32_21S", "R_AVR32_16U", "R_AVR32_16S", "R_AVR32_8S", "R_AVR32_8S_EXT",
++    "R_AVR32_22H_PCREL", "R_AVR32_18W_PCREL", "R_AVR32_16B_PCREL",
++    "R_AVR32_16N_PCREL", "R_AVR32_14UW_PCREL", "R_AVR32_11H_PCREL",
++    "R_AVR32_10UW_PCREL", "R_AVR32_9H_PCREL", "R_AVR32_9UW_PCREL",
++    "R_AVR32_HI16", "R_AVR32_LO16",
++    "R_AVR32_GOTPC", "R_AVR32_GOTCALL", "R_AVR32_LDA_GOT",
++    "R_AVR32_GOT21S", "R_AVR32_GOT18SW", "R_AVR32_GOT16S", "R_AVR32_GOT7UW",
++    "R_AVR32_32_CPENT", "R_AVR32_CPCALL", "R_AVR32_16_CP", "R_AVR32_9W_CP",
++    "R_AVR32_RELATIVE", "R_AVR32_GLOB_DAT", "R_AVR32_JMP_SLOT",
++    "R_AVR32_ALIGN",
++};
+diff --git a/ldso/ldso/avr32/dl-startup.h b/ldso/ldso/avr32/dl-startup.h
+new file mode 100644
+index 0000000..3b9a641
+--- /dev/null
++++ b/ldso/ldso/avr32/dl-startup.h
+@@ -0,0 +1,112 @@
++/*
++ * Architecture specific code used by dl-startup.c
++ *
++ * Copyright (C) 2005-2007 Atmel Corporation
++ *
++ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
++ */
++
++/* This is the library loader's main entry point. Let _dl_boot2 do its
++ * initializations and jump to the application's entry point
++ * afterwards. */
++asm(  "       .text\n"
++      "       .global _start\n"
++      "       .type   _start,@function\n"
++      "_start:\n"
++      /* All arguments are on the stack initially */
++      "       mov     r12, sp\n"
++      "       rcall   _dl_start\n"
++      /* Returns user entry point in r12. Save it. */
++      "       mov     r0, r12\n"
++      /* We're PIC, so get the Global Offset Table */
++      "       lddpc   r6, .L_GOT\n"
++      ".L_RGOT:\n"
++      "       rsub    r6, pc\n"
++      /* Adjust argc and argv according to _dl_skip_args */
++      "       ld.w    r1, r6[_dl_skip_args@got]\n"
++      "       ld.w    r1, r1[0]\n"
++      "       ld.w    r2, sp++\n"
++      "       sub     r2, r1\n"
++      "       add     sp, sp, r1 << 2\n"
++      "       st.w    --sp, r2\n"
++      /* Load the finalizer function */
++      "       ld.w    r12, r6[_dl_fini@got]\n"
++      /* Jump to the user's entry point */
++      "       mov     pc, r0\n\n"
++
++      "       .align  2\n"
++      ".L_GOT:"
++      "       .long   .L_RGOT - _GLOBAL_OFFSET_TABLE_\n"
++      "       .size   _start, . - _start\n"
++      "       .previous\n");
++
++/* Get a pointer to the argv array.  On many platforms this can be just
++ * the address if the first argument, on other platforms we need to
++ * do something a little more subtle here. */
++#define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned long *)ARGS + 1)
++
++
++/* We can't call functions before the GOT has been initialized */
++#define NO_FUNCS_BEFORE_BOOTSTRAP
++
++/*
++ * Relocate the GOT during dynamic loader bootstrap.  This will add
++ * the load address to all entries in the GOT, which is necessary
++ * because the linker doesn't generate R_AVR32_RELATIVE relocs for the
++ * GOT.
++ */
++static __always_inline
++void PERFORM_BOOTSTRAP_GOT(struct elf_resolve *tpnt)
++{
++      Elf32_Addr i, nr_got;
++      register Elf32_Addr *__r6 __asm__("r6");
++      Elf32_Addr *got = __r6;
++
++      nr_got = tpnt->dynamic_info[DT_AVR32_GOTSZ_IDX] / sizeof(*got);
++      for (i = 2; i < nr_got; i++)
++              got[i] += tpnt->loadaddr;
++}
++
++#define PERFORM_BOOTSTRAP_GOT(tpnt) PERFORM_BOOTSTRAP_GOT(tpnt)
++
++/* Handle relocation of the symbols in the dynamic loader. */
++static __always_inline
++void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, unsigned long *reloc_addr,
++                           unsigned long symbol_addr,
++                           unsigned long load_addr, Elf32_Sym *symtab)
++{
++      switch(ELF32_R_TYPE(rpnt->r_info)) {
++      case R_AVR32_NONE:
++              break;
++      case R_AVR32_GLOB_DAT:
++      case R_AVR32_JMP_SLOT:
++              *reloc_addr = symbol_addr;
++              break;
++      case R_AVR32_RELATIVE:
++              SEND_STDERR_DEBUG("Applying RELATIVE relocation: ");
++              SEND_ADDRESS_STDERR_DEBUG(load_addr, 0);
++              SEND_STDERR_DEBUG(" + ");
++              SEND_ADDRESS_STDERR_DEBUG(rpnt->r_addend, 1);
++              *reloc_addr = load_addr + rpnt->r_addend;
++              break;
++      default:
++              SEND_STDERR("BOOTSTRAP_RELOC: unhandled reloc_type ");
++              SEND_NUMBER_STDERR(ELF32_R_TYPE(rpnt->r_info), 1);
++              SEND_STDERR("REL, SYMBOL, LOAD: ");
++              SEND_ADDRESS_STDERR(reloc_addr, 0);
++              SEND_STDERR(", ");
++              SEND_ADDRESS_STDERR(symbol_addr, 0);
++              SEND_STDERR(", ");
++              SEND_ADDRESS_STDERR(load_addr, 1);
++              _dl_exit(1);
++      }
++}
++
++/* Transfer control to the user's application, once the dynamic loader
++ * is done. This routine has to exit the current function, then call
++ * the _dl_elf_main function.
++ *
++ * Since our _dl_boot will simply call whatever is returned by
++ * _dl_boot2, we can just return the address we're supposed to
++ * call.  */
++#define START()       return _dl_elf_main;
+diff --git a/ldso/ldso/avr32/dl-syscalls.h b/ldso/ldso/avr32/dl-syscalls.h
+new file mode 100644
+index 0000000..996bb87
+--- /dev/null
++++ b/ldso/ldso/avr32/dl-syscalls.h
+@@ -0,0 +1,6 @@
++/* We can't use the real errno in ldso, since it has not yet
++ * been dynamicly linked in yet. */
++#include "sys/syscall.h"
++extern int _dl_errno;
++#undef __set_errno
++#define __set_errno(X) {(_dl_errno) = (X);}
+diff --git a/ldso/ldso/avr32/dl-sysdep.h b/ldso/ldso/avr32/dl-sysdep.h
+new file mode 100644
+index 0000000..1a30172
+--- /dev/null
++++ b/ldso/ldso/avr32/dl-sysdep.h
+@@ -0,0 +1,105 @@
++/*
++ * Various assembly language/system dependent hacks that are required
++ * so that we can minimize the amount of platform specific code.
++ *
++ * Copyright (C) 2004-2007 Atmel Corporation
++ *
++ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
++ */
++
++/* Define this if the system uses RELOCA. */
++#define ELF_USES_RELOCA
++
++#include <elf.h>
++
++#define ARCH_NUM 1
++#define DT_AVR32_GOTSZ_IDX    (DT_NUM + OS_NUM)
++
++#define ARCH_DYNAMIC_INFO(dpnt, dynamic, debug_addr)                  \
++      do {                                                            \
++              if (dpnt->d_tag == DT_AVR32_GOTSZ)                      \
++                      dynamic[DT_AVR32_GOTSZ_IDX] = dpnt->d_un.d_val; \
++      } while (0)
++
++/* Initialization sequence for the application/library GOT. */
++#define INIT_GOT(GOT_BASE,MODULE)                                     \
++      do {                                                            \
++              unsigned long i, nr_got;                                \
++                                                                      \
++              GOT_BASE[0] = (unsigned long) _dl_linux_resolve;        \
++              GOT_BASE[1] = (unsigned long) MODULE;                   \
++                                                                      \
++              /* Add load address displacement to all GOT entries */  \
++              nr_got = MODULE->dynamic_info[DT_AVR32_GOTSZ_IDX] / 4;  \
++              for (i = 2; i < nr_got; i++)                            \
++                      GOT_BASE[i] += (unsigned long)MODULE->loadaddr; \
++      } while (0)
++
++#define do_rem(result, n, base)       ((result) = (n) % (base))
++
++/* Here we define the magic numbers that this dynamic loader should accept */
++#define MAGIC1 EM_AVR32
++#undef MAGIC2
++
++/* Used for error messages */
++#define ELF_TARGET "AVR32"
++
++unsigned long _dl_linux_resolver(unsigned long got_offset, unsigned long *got);
++
++/* 4096 bytes alignment */
++#define PAGE_ALIGN 0xfffff000
++#define ADDR_ALIGN 0xfff
++#define OFFS_ALIGN 0x7ffff000
++
++#define elf_machine_type_class(type)                          \
++      ((type == R_AVR32_JMP_SLOT) * ELF_RTYPE_CLASS_PLT)
++
++/* AVR32 doesn't need any COPY relocs */
++#define DL_NO_COPY_RELOCS
++
++/* Return the link-time address of _DYNAMIC.  Conveniently, this is the
++   first element of the GOT.  This must be inlined in a function which
++   uses global data.  */
++static inline Elf32_Addr
++elf_machine_dynamic (void)
++{
++      register Elf32_Addr *got asm ("r6");
++      return *got;
++}
++
++/* Return the run-time load address of the shared object.  */
++static inline Elf32_Addr
++elf_machine_load_address (void)
++{
++      extern void __dl_start asm("_dl_start");
++      Elf32_Addr got_addr = (Elf32_Addr) &__dl_start;
++      Elf32_Addr pcrel_addr;
++
++      asm   ("        lddpc   %0, 2f\n"
++             "1:      add     %0, pc\n"
++             "        rjmp    3f\n"
++             "        .align  2\n"
++             "2:      .long   _dl_start - 1b\n"
++             "3:\n"
++             : "=r"(pcrel_addr) : : "cc");
++
++      return pcrel_addr - got_addr;
++}
++
++/*
++ * Perform any RELATIVE relocations specified by DT_RELCOUNT.
++ * Currently, we don't use that tag, but we might in the future as
++ * this would reduce the startup time somewhat (although probably not by much).
++ */
++static inline void
++elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr,
++                    Elf32_Word relative_count)
++{
++      Elf32_Rela *rpnt = (void *)rel_addr;
++
++      do {
++              Elf32_Addr *reloc_addr;
++              reloc_addr = (void *)(load_off + (rpnt++)->r_offset);
++              *reloc_addr = load_off + rpnt->r_addend;
++      } while (--relative_count);
++}
+diff --git a/ldso/ldso/avr32/elfinterp.c b/ldso/ldso/avr32/elfinterp.c
+new file mode 100644
+index 0000000..196292b
+--- /dev/null
++++ b/ldso/ldso/avr32/elfinterp.c
+@@ -0,0 +1,191 @@
++/*
++ * AVR32 ELF shared library loader suppport
++ *
++ * Copyright (C) 2004-2006 Atmel Corporation
++ *
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. The name of the above contributors may not be
++ *    used to endorse or promote products derived from this software
++ *    without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ */
++
++unsigned long _dl_linux_resolver(unsigned long got_offset, unsigned long *got)
++{
++      struct elf_resolve *tpnt = (struct elf_resolve *)got[1];
++      Elf32_Sym *sym;
++      unsigned long local_gotno;
++      unsigned long gotsym;
++      unsigned long new_addr;
++      char *strtab, *symname;
++      unsigned long *entry;
++      unsigned long sym_index = got_offset / 4;
++
++#if 0
++      local_gotno = tpnt->dynamic_info[DT_AVR32_LOCAL_GOTNO];
++      gotsym = tpnt->dynamic_info[DT_AVR32_GOTSYM];
++
++      sym = ((Elf32_Sym *)(tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr))
++              + sym_index;
++      strtab = (char *)(tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
++      symname = strtab + sym->st_name;
++
++#if 0
++      new_addr = (unsigned long) _dl_find_hash(strtab + sym->st_name,
++                                               tpnt->symbol_scope, tpnt,
++                                               resolver);
++#endif
++
++      entry = (unsigned long *)(got + local_gotno + sym_index - gotsym);
++      *entry = new_addr;
++#endif
++
++      return new_addr;
++}
++
++static int
++_dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope,
++        unsigned long rel_addr, unsigned long rel_size,
++        int (*reloc_func)(struct elf_resolve *tpnt, struct dyn_elf *scope,
++                          Elf32_Rela *rpnt, Elf32_Sym *symtab, char *strtab))
++{
++      Elf32_Sym *symtab;
++      Elf32_Rela *rpnt;
++      char *strtab;
++      int i;
++
++      rpnt = (Elf32_Rela *)rel_addr;
++      rel_size /= sizeof(Elf32_Rela);
++      symtab = (Elf32_Sym *)tpnt->dynamic_info[DT_SYMTAB];
++      strtab = (char *)tpnt->dynamic_info[DT_STRTAB];
++
++      for (i = 0; i < rel_size; i++, rpnt++) {
++              int symtab_index, res;
++
++              symtab_index = ELF32_R_SYM(rpnt->r_info);
++
++              debug_sym(symtab, strtab, symtab_index);
++              debug_reloc(symtab, strtab, rpnt);
++
++              res = reloc_func(tpnt, scope, rpnt, symtab, strtab);
++
++              if (res == 0)
++                      continue;
++
++              _dl_dprintf(2, "\n%s: ", _dl_progname);
++
++              if (symtab_index)
++                      _dl_dprintf(2, "symbol '%s': ",
++                                  strtab + symtab[symtab_index].st_name);
++
++              if (res < 0) {
++                      int reloc_type = ELF32_R_TYPE(rpnt->r_info);
++#if defined(__SUPPORT_LD_DEBUG__)
++                      _dl_dprintf(2, "can't handle reloc type %s\n",
++                                  _dl_reltypes(reloc_type));
++#else
++                      _dl_dprintf(2, "can't handle reloc type %x\n",
++                                  reloc_type);
++#endif
++                      _dl_exit(-res);
++              } else {
++                      _dl_dprintf(2, "can't resolve symbol\n");
++                      return res;
++              }
++      }
++
++      return 0;
++}
++
++static int _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
++                      Elf32_Rela *rpnt, Elf32_Sym *symtab, char *strtab)
++{
++      int reloc_type;
++      int symtab_index;
++      char *symname;
++      unsigned long *reloc_addr;
++      unsigned long symbol_addr;
++#if defined(__SUPPORT_LD_DEBUG__)
++      unsigned long old_val;
++#endif
++
++      reloc_addr = (unsigned long *)(tpnt->loadaddr + rpnt->r_offset);
++      reloc_type = ELF32_R_TYPE(rpnt->r_info);
++      symtab_index = ELF32_R_SYM(rpnt->r_info);
++      symbol_addr = 0;
++      symname = strtab + symtab[symtab_index].st_name;
++
++      if (symtab_index) {
++              symbol_addr = (unsigned long)
++                      _dl_find_hash(strtab + symtab[symtab_index].st_name,
++                                    tpnt->symbol_scope, tpnt,
++                                    elf_machine_type_class(reloc_type));
++
++              /* Allow undefined references to weak symbols */
++              if (!symbol_addr &&
++                  ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK) {
++                      _dl_dprintf(2, "%s: can't resolve symbol '%s'\n",
++                                  _dl_progname, symname);
++                      return 0;
++              }
++      }
++
++#if defined(__SUPPORT_LD_DEBUG__)
++      old_val = *reloc_addr;
++#endif
++      switch (reloc_type) {
++      case R_AVR32_NONE:
++              break;
++      case R_AVR32_GLOB_DAT:
++      case R_AVR32_JMP_SLOT:
++              *reloc_addr = symbol_addr + rpnt->r_addend;
++              break;
++      case R_AVR32_RELATIVE:
++              *reloc_addr = (unsigned long)tpnt->loadaddr
++                      + rpnt->r_addend;
++              break;
++      default:
++              return -1;
++      }
++
++#if defined(__SUPPORT_LD_DEBUG__)
++      if (_dl_debug_reloc && _dl_debug_detail)
++              _dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x\n",
++                          old_val, *reloc_addr);
++#endif
++
++      return 0;
++}
++
++void _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt,
++                                         unsigned long rel_addr,
++                                         unsigned long rel_size)
++{
++      /* TODO: Might want to support this in order to get faster
++       * startup times... */
++}
++
++int _dl_parse_relocation_information(struct dyn_elf *rpnt,
++                                   unsigned long rel_addr,
++                                   unsigned long rel_size)
++{
++      return _dl_parse(rpnt->dyn, rpnt->dyn->symbol_scope, rel_addr, rel_size,
++                       _dl_do_reloc);
++}
+diff --git a/ldso/ldso/avr32/resolve.S b/ldso/ldso/avr32/resolve.S
+new file mode 100644
+index 0000000..e3cb7f4
+--- /dev/null
++++ b/ldso/ldso/avr32/resolve.S
+@@ -0,0 +1,28 @@
++/*
++ * Linux dynamic resolving code for AVR32. Fixes up the GOT entry as
++ * indicated in register r12 and jumps to the resolved address.
++ *
++ * 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.
++ *
++ * Copyright (C) 2004-2007 Atmel Corporation
++ */
++
++#define ip r5
++
++      .text
++      .global _dl_linux_resolve
++      .type   _dl_linux_resolve,@function
++_dl_linux_resolve:
++      /* The PLT code pushed r8 for us. It contains the address of this
++         function's GOT entry, that is entry 0. ip contains the address
++         of the GOT entry of the function we wanted to call. */
++      stm     --sp, r9-r12, lr
++      mov     r11, r8
++      sub     r12, ip, r8
++      rcall   _dl_linux_resolver
++      mov     ip, r12
++      popm    r8-r12,lr
++      mov     pc, ip
++      .size   _dl_linux_resolve, . - _dl_linux_resolve
+diff --git a/ldso/ldso/dl-startup.c b/ldso/ldso/dl-startup.c
+index 5cf1d04..d4294ec 100644
+--- a/ldso/ldso/dl-startup.c
++++ b/ldso/ldso/dl-startup.c
+@@ -217,7 +217,9 @@ DL_START(unsigned long args)
+       /* some arches (like MIPS) we have to tweak the GOT before relocations */
+       PERFORM_BOOTSTRAP_GOT(tpnt);
+-#else
++#endif
++
++#if !defined(PERFORM_BOOTSTRAP_GOT) || defined(__avr32__)
+       /* OK, now do the relocations.  We do not do a lazy binding here, so
+          that once we are done, we have considerably more flexibility. */
+diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c
+index f4e6cac..9cdc3fe 100644
+--- a/libc/inet/resolv.c
++++ b/libc/inet/resolv.c
+@@ -1643,7 +1643,7 @@ int attribute_hidden __read_etc_hosts_r(FILE * fp, const char * name, int type,
+                       *result=result_buf;
+                       ret=NETDB_SUCCESS;
+ #ifdef __UCLIBC_HAS_IPV6__
+-        } else if (type == AF_INET6 && inet_pton(AF_INET6, alias[0], in6) > 0) {
++              } else if (type == AF_INET6 && inet_pton(AF_INET6, alias[0], in6) > 0) {
+                       DPRINTF("Found INET6\n");
+                       addr_list6[0] = in6;
+                       addr_list6[1] = 0;
+@@ -1658,8 +1658,8 @@ int attribute_hidden __read_etc_hosts_r(FILE * fp, const char * name, int type,
+               } else {
+                       DPRINTF("Error\n");
+                       ret=TRY_AGAIN;
+-                      break; /* bad ip address */
+-        }
++                      continue; /* bad ip address, keep searching */
++              }
+               if (action!=GETHOSTENT) {
+                       fclose(fp);
+diff --git a/libc/string/avr32/Makefile b/libc/string/avr32/Makefile
+new file mode 100644
+index 0000000..e19e9d9
+--- /dev/null
++++ b/libc/string/avr32/Makefile
+@@ -0,0 +1,26 @@
++# Makefile for uClibc
++#
++# Copyright (C) 2000-2003 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
++
++top_srcdir    := ../../../
++top_builddir  := ../../../
++
++all: objs
++
++include $(top_builddir)Rules.mak
++include ../Makefile.in
++include $(top_srcdir)Makerules
+diff --git a/libc/string/avr32/bcopy.S b/libc/string/avr32/bcopy.S
+new file mode 100644
+index 0000000..87c1e04
+--- /dev/null
++++ b/libc/string/avr32/bcopy.S
+@@ -0,0 +1,26 @@
++/*
++ * Copyright (C) 2004-2007 Atmel Corporation
++ *
++ * 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.
++ */
++
++#include <features.h>
++
++#ifdef __UCLIBC_SUSV3_LEGACY__
++
++      .text
++      .global bcopy
++      .type   bcopy, @function
++      .align  1
++bcopy:
++      /* Swap the first two arguments */
++      eor     r11, r12
++      eor     r12, r11
++      eor     r11, r12
++      rjmp    __GI_memmove
++
++      .size   bcopy, . - bcopy
++
++#endif /* __UCLIBC_SUSV3_LEGACY__ */
+diff --git a/libc/string/avr32/bzero.S b/libc/string/avr32/bzero.S
+new file mode 100644
+index 0000000..c999e65
+--- /dev/null
++++ b/libc/string/avr32/bzero.S
+@@ -0,0 +1,22 @@
++/*
++ * Copyright (C) 2004-2007 Atmel Corporation
++ *
++ * 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.
++ */
++
++#ifdef __UCLIBC_SUSV3_LEGACY__
++
++      .text
++      .global bzero
++      .type   bzero, @function
++      .align  1
++bzero:
++      mov     r10, r11
++      mov     r11, 0
++      rjmp    __memset
++
++      .size   bzero, . - bzero
++
++#endif /* __UCLIBC_SUSV3_LEGACY__ */
+diff --git a/libc/string/avr32/memcmp.S b/libc/string/avr32/memcmp.S
+new file mode 100644
+index 0000000..ae6cc91
+--- /dev/null
++++ b/libc/string/avr32/memcmp.S
+@@ -0,0 +1,61 @@
++/*
++ * Copyright (C) 2004-2007 Atmel Corporation
++ *
++ * 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.
++ */
++
++#include <features.h>
++
++#define s1 r12
++#define s2 r11
++#define len r10
++
++      .text
++      .global memcmp
++      .type   memcmp, @function
++      .align  1
++memcmp:
++      sub     len, 4
++      brlt    .Lless_than_4
++
++1:    ld.w    r8, s1++
++      ld.w    r9, s2++
++      cp.w    r8, r9
++      brne    .Lfound_word
++      sub     len, 4
++      brge    1b
++
++.Lless_than_4:
++      sub     len, -4
++      reteq   0
++
++1:    ld.ub   r8, s1++
++      ld.ub   r9, s2++
++      sub     r8, r9
++      retne   r8
++      sub     len, 1
++      brgt    1b
++
++      retal   0
++
++.Lfound_word:
++      mov     len, 4
++
++2:    bfextu  r11, r9, 24, 8
++      bfextu  r12, r8, 24, 8
++      sub     r12, r11
++      retne   r12
++      lsl     r8, 8
++      lsl     r9, 8
++      sub     len, 1
++      brne    2b
++      retal   r12
++
++      .size   memcmp, . - memcmp
++
++libc_hidden_def(memcmp)
++#ifdef __UCLIBC_SUSV3_LEGACY__
++strong_alias(memcmp,bcmp)
++#endif
+diff --git a/libc/string/avr32/memcpy.S b/libc/string/avr32/memcpy.S
+new file mode 100644
+index 0000000..bf091ab
+--- /dev/null
++++ b/libc/string/avr32/memcpy.S
+@@ -0,0 +1,111 @@
++/*
++ * Copyright (C) 2004-2007 Atmel Corporation
++ *
++ * 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.
++ */
++
++/* Don't use r12 as dst since we must return it unmodified */
++#define dst r9
++#define src r11
++#define len r10
++
++      .text
++      .global memcpy
++      .type   memcpy, @function
++memcpy:
++      pref    src[0]
++      mov     dst, r12
++
++      /* If we have less than 32 bytes, don't do anything fancy */
++      cp.w    len, 32
++      brge    .Lmore_than_31
++
++      sub     len, 1
++      retlt   r12
++1:    ld.ub   r8, src++
++      st.b    dst++, r8
++      sub     len, 1
++      brge    1b
++      retal   r12
++
++.Lmore_than_31:
++      pushm   r0-r7, lr
++
++      /* Check alignment */
++      mov     r8, src
++      andl    r8, 31, COH
++      brne    .Lunaligned_src
++      mov     r8, dst
++      andl    r8, 3, COH
++      brne    .Lunaligned_dst
++
++.Laligned_copy:
++      sub     len, 32
++      brlt    .Lless_than_32
++
++1:    /* Copy 32 bytes at a time */
++      ldm     src, r0-r7
++      sub     src, -32
++      stm     dst, r0-r7
++      sub     dst, -32
++      sub     len, 32
++      brge    1b
++
++.Lless_than_32:
++      /* Copy 16 more bytes if possible */
++      sub     len, -16
++      brlt    .Lless_than_16
++      ldm     src, r0-r3
++      sub     src, -16
++      sub     len, 16
++      stm     dst, r0-r3
++      sub     dst, -16
++
++.Lless_than_16:
++      /* Do the remaining as byte copies */
++      neg     len
++      add     pc, pc, len << 2
++      .rept   15
++      ld.ub   r0, src++
++      st.b    dst++, r0
++      .endr
++
++      popm    r0-r7, pc
++
++.Lunaligned_src:
++      /* Make src cacheline-aligned. r8 = (src & 31) */
++      rsub    r8, r8, 32
++      sub     len, r8
++1:    ld.ub   r0, src++
++      st.b    dst++, r0
++      sub     r8, 1
++      brne    1b
++
++      /* If dst is word-aligned, we're ready to go */
++      pref    src[0]
++      mov     r8, 3
++      tst     dst, r8
++      breq    .Laligned_copy
++
++.Lunaligned_dst:
++      /* src is aligned, but dst is not. Expect bad performance */
++      sub     len, 4
++      brlt    2f
++1:    ld.w    r0, src++
++      st.w    dst++, r0
++      sub     len, 4
++      brge    1b
++
++2:    neg     len
++      add     pc, pc, len << 2
++      .rept   3
++      ld.ub   r0, src++
++      st.b    dst++, r0
++      .endr
++
++      popm    r0-r7, pc
++      .size   memcpy, . - memcpy
++
++libc_hidden_def(memcpy)
+diff --git a/libc/string/avr32/memmove.S b/libc/string/avr32/memmove.S
+new file mode 100644
+index 0000000..98287c5
+--- /dev/null
++++ b/libc/string/avr32/memmove.S
+@@ -0,0 +1,116 @@
++/*
++ * Copyright (C) 2004-2007 Atmel Corporation
++ *
++ * 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.
++ */
++
++#define dst r12
++#define src r11
++#define len r10
++
++      .text
++      .global memmove
++      .type   memmove, @function
++memmove:
++      cp.w    src, dst
++      brge    __GI_memcpy
++
++      add     dst, len
++      add     src, len
++      pref    src[-1]
++
++      /*
++       * The rest is basically the same as in memcpy.S except that
++       * the direction is reversed.
++       */
++      cp.w    len, 32
++      brge    .Lmore_than_31
++
++      sub     len, 1
++      retlt   r12
++1:    ld.ub   r8, --src
++      st.b    --dst, r8
++      sub     len, 1
++      brge    1b
++      retal   r12
++
++.Lmore_than_31:
++      pushm   r0-r7, lr
++
++      /* Check alignment */
++      mov     r8, src
++      andl    r8, 31, COH
++      brne    .Lunaligned_src
++      mov     r8, r12
++      andl    r8, 3, COH
++      brne    .Lunaligned_dst
++
++.Laligned_copy:
++      sub     len, 32
++      brlt    .Lless_than_32
++
++1:    /* Copy 32 bytes at a time */
++      sub     src, 32
++      ldm     src, r0-r7
++      sub     dst, 32
++      sub     len, 32
++      stm     dst, r0-r7
++      brge    1b
++
++.Lless_than_32:
++      /* Copy 16 more bytes if possible */
++      sub     len, -16
++      brlt    .Lless_than_16
++      sub     src, 16
++      ldm     src, r0-r3
++      sub     dst, 16
++      sub     len, 16
++      stm     dst, r0-r3
++
++.Lless_than_16:
++      /* Do the remaining as byte copies */
++      sub     len, -16
++      breq    2f
++1:    ld.ub   r0, --src
++      st.b    --dst, r0
++      sub     len, 1
++      brne    1b
++
++2:    popm    r0-r7, pc
++
++.Lunaligned_src:
++      /* Make src cacheline-aligned. r8 = (src & 31) */
++      sub     len, r8
++1:    ld.ub   r0, --src
++      st.b    --dst, r0
++      sub     r8, 1
++      brne    1b
++
++      /* If dst is word-aligned, we're ready to go */
++      pref    src[-4]
++      mov     r8, 3
++      tst     dst, r8
++      breq    .Laligned_copy
++
++.Lunaligned_dst:
++      /* src is aligned, but dst is not. Expect bad performance */
++      sub     len, 4
++      brlt    2f
++1:    ld.w    r0, --src
++      st.w    --dst, r0
++      sub     len, 4
++      brge    1b
++
++2:    neg     len
++      add     pc, pc, len << 2
++      .rept   3
++      ld.ub   r0, --src
++      st.b    --dst, r0
++      .endr
++
++      popm    r0-r7, pc
++      .size   memmove, . - memmove
++
++libc_hidden_def(memmove)
+diff --git a/libc/string/avr32/memset.S b/libc/string/avr32/memset.S
+new file mode 100644
+index 0000000..33cfaed
+--- /dev/null
++++ b/libc/string/avr32/memset.S
+@@ -0,0 +1,70 @@
++/*
++ * Copyright (C) 2004-2007 Atmel Corporation
++ *
++ * 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.
++ */
++
++#include <features.h>
++
++#define s r12
++#define c r11
++#define n r10
++
++      .text
++      .global memset
++      .type   memset, @function
++
++      .global __memset
++      .hidden __memset
++      .type   __memset, @function
++
++      .align  1
++memset:
++__memset:
++      cp.w    n, 32
++      mov     r9, s
++      brge    .Llarge_memset
++
++      sub     n, 1
++      retlt   s
++1:    st.b    s++, c
++      sub     n, 1
++      brge    1b
++
++      retal   r9
++
++.Llarge_memset:
++      mov     r8, r11
++      mov     r11, 3
++      bfins   r8, r8, 8, 8
++      bfins   r8, r8, 16, 16
++      tst     s, r11
++      breq    2f
++
++1:    st.b    s++, r8
++      sub     n, 1
++      tst     s, r11
++      brne    1b
++
++2:    mov     r11, r9
++      mov     r9, r8
++      sub     n, 8
++
++3:    st.d    s++, r8
++      sub     n, 8
++      brge    3b
++
++      /* If we are done, n == -8 and we'll skip all st.b insns below */
++      neg     n
++      lsl     n, 1
++      add     pc, n
++      .rept   7
++      st.b    s++, r8
++      .endr
++      retal   r11
++
++      .size   memset, . - memset
++
++libc_hidden_def(memset)
+diff --git a/libc/string/avr32/strcmp.S b/libc/string/avr32/strcmp.S
+new file mode 100644
+index 0000000..f73bd43
+--- /dev/null
++++ b/libc/string/avr32/strcmp.S
+@@ -0,0 +1,91 @@
++/*
++ * Copyright (C) 2004-2007 Atmel Corporation
++ *
++ * 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.
++ */
++
++#include <features.h>
++
++#define s1 r12
++#define s2 r11
++#define len r10
++
++      .text
++      .global strcmp
++      .type   strcmp, @function
++      .align  1
++strcmp:
++      mov     r8, 3
++      tst     s1, r8
++      brne    .Lunaligned_s1
++      tst     s2, r8
++      brne    .Lunaligned_s2
++
++1:    ld.w    r8, s1++
++      ld.w    r9, s2++
++      cp.w    r8, r9
++      brne    2f
++      tnbz    r8
++      brne    1b
++      retal   0
++
++2:    bfextu  r12, r8, 24, 8
++      bfextu  r11, r9, 24, 8
++      sub     r12, r11
++      retne   r12
++      cp.w    r11, 0
++      reteq   0
++      bfextu  r12, r8, 16, 8
++      bfextu  r11, r9, 16, 8
++      sub     r12, r11
++      retne   r12
++      cp.w    r11, 0
++      reteq   0
++      bfextu  r12, r8, 8, 8
++      bfextu  r11, r9, 8, 8
++      sub     r12, r11
++      retne   r12
++      cp.w    r11, 0
++      reteq   0
++      bfextu  r12, r8, 0, 8
++      bfextu  r11, r9, 0, 8
++      sub     r12, r11
++      retal   r12
++
++.Lunaligned_s1:
++3:    tst     s1, r8
++      breq    4f
++      ld.ub   r10, s1++
++      ld.ub   r9, s2++
++      sub     r10, r9
++      retne   r10
++      cp.w    r9, 0
++      brne    3b
++      retal   r10
++
++4:    tst     s2, r8
++      breq    1b
++
++.Lunaligned_s2:
++      /*
++       * s1 and s2 can't both be aligned, and unaligned word loads
++       * can trigger spurious exceptions if we cross a page boundary.
++       * Do it the slow way...
++       */
++1:    ld.ub   r8, s1++
++      ld.ub   r9, s2++
++      sub     r8, r9
++      retne   r8
++      cp.w    r9, 0
++      brne    1b
++      retal   0
++
++      .size   strcmp, . - strcmp
++
++libc_hidden_def(strcmp)
++#ifndef __UCLIBC_HAS_LOCALE__
++strong_alias(strcmp, strcoll)
++libc_hidden_def(strcoll)
++#endif
+diff --git a/libc/string/avr32/strlen.S b/libc/string/avr32/strlen.S
+new file mode 100644
+index 0000000..5223e53
+--- /dev/null
++++ b/libc/string/avr32/strlen.S
+@@ -0,0 +1,62 @@
++/*
++ * Copyright (C) 2004-2007 Atmel Corporation
++ *
++ * 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.
++ */
++
++#include <features.h>
++
++#define str r12
++
++      .text
++      .global strlen
++      .type   strlen, @function
++strlen:
++      mov     r11, r12
++
++      mov     r9, str
++      andl    r9, 3, COH
++      brne    .Lunaligned_str
++
++1:    ld.w    r8, str++
++      tnbz    r8
++      brne    1b
++
++      sub     r12, r11
++      bfextu  r9, r8, 24, 8
++      cp.w    r9, 0
++      subeq   r12, 4
++      reteq   r12
++      bfextu  r9, r8, 16, 8
++      cp.w    r9, 0
++      subeq   r12, 3
++      reteq   r12
++      bfextu  r9, r8, 8, 8
++      cp.w    r9, 0
++      subeq   r12, 2
++      reteq   r12
++      sub     r12, 1
++      retal   r12
++
++.Lunaligned_str:
++      add     pc, pc, r9 << 3
++      sub     r0, r0, 0       /* 4-byte nop */
++      ld.ub   r8, str++
++      sub     r8, r8, 0
++      breq    1f
++      ld.ub   r8, str++
++      sub     r8, r8, 0
++      breq    1f
++      ld.ub   r8, str++
++      sub     r8, r8, 0
++      brne    1b
++
++1:    sub     r12, 1
++      sub     r12, r11
++      retal   r12
++
++      .size   strlen, . - strlen
++
++libc_hidden_def(strlen)
+diff --git a/libc/sysdeps/linux/avr32/Makefile b/libc/sysdeps/linux/avr32/Makefile
+new file mode 100644
+index 0000000..338abc0
+--- /dev/null
++++ b/libc/sysdeps/linux/avr32/Makefile
+@@ -0,0 +1,25 @@
++# Makefile for uClibc
++#
++# Copyright (C) 2000-2003 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
++
++top_srcdir=../../../../
++top_builddir=../../../../
++all: objs
++
++include $(top_builddir)Rules.mak
++include Makefile.arch
++include $(top_srcdir)Makerules
+diff --git a/libc/sysdeps/linux/avr32/Makefile.arch b/libc/sysdeps/linux/avr32/Makefile.arch
+new file mode 100644
+index 0000000..44fc01e
+--- /dev/null
++++ b/libc/sysdeps/linux/avr32/Makefile.arch
+@@ -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.
++#
++
++CSRC  := brk.c clone.c mmap.c sigaction.c
++
++SSRC  := __longjmp.S setjmp.S bsd-setjmp.S bsd-_setjmp.S      \
++              sigrestorer.S syscall.S vfork.S
++
++include $(top_srcdir)/libc/sysdeps/linux/Makefile.commonarch
+diff --git a/libc/sysdeps/linux/avr32/__longjmp.S b/libc/sysdeps/linux/avr32/__longjmp.S
+new file mode 100644
+index 0000000..6154bb2
+--- /dev/null
++++ b/libc/sysdeps/linux/avr32/__longjmp.S
+@@ -0,0 +1,21 @@
++/*
++ * Copyright (C) 2004-2007 Atmel Corporation
++ *
++ * 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.
++ */
++
++      .global __longjmp
++      .type   __longjmp,"function"
++      .align  1
++__longjmp:
++      ldm     r12++, r0-r8,sp,lr
++      mustr   r8              /* restore status register (lower half) */
++      cp      r11, 0          /* can't return zero */
++      frs
++      moveq   r11, 1
++      retal   r11
++      .size   __longjmp, . - __longjmp
++
++libc_hidden_def(__longjmp)
+diff --git a/libc/sysdeps/linux/avr32/bits/atomic.h b/libc/sysdeps/linux/avr32/bits/atomic.h
+new file mode 100644
+index 0000000..e6be41f
+--- /dev/null
++++ b/libc/sysdeps/linux/avr32/bits/atomic.h
+@@ -0,0 +1,120 @@
++/*
++ * Copyright (C) 2007 Atmel Corporation
++ *
++ * 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.
++ */
++#ifndef _AVR32_BITS_ATOMIC_H
++#define _AVR32_BITS_ATOMIC_H 1
++
++#include <inttypes.h>
++
++typedef int32_t atomic32_t;
++typedef uint32_t uatomic32_t;
++typedef int_fast32_t atomic_fast32_t;
++typedef uint_fast32_t uatomic_fast32_t;
++
++typedef intptr_t atomicptr_t;
++typedef uintptr_t uatomicptr_t;
++typedef intmax_t atomic_max_t;
++typedef uintmax_t uatomic_max_t;
++
++#define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval)    \
++      (abort(), 0)
++
++#define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval)   \
++      (abort(), 0)
++
++#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval)   \
++      ({                                                              \
++              __typeof__(*(mem)) __prev;                              \
++              __asm__ __volatile__(                                   \
++                      "/* __arch_compare_and_exchange_val_32_acq */\n" \
++                      "1:     ssrf    5\n"                            \
++                      "       ld.w    %[result], %[m]\n"              \
++                      "       cp.w    %[result], %[old]\n"            \
++                      "       brne    2f\n"                           \
++                      "       stcond  %[m], %[new]\n"                 \
++                      "       brne    1b\n"                           \
++                      "2:"                                            \
++                      : [result] "=&r"(__result), [m] "=m"(*(mem))    \
++                      : "m"(*(mem)), [old] "ir"(oldval),              \
++                        [new] "r"(newval)                             \
++                      : "memory", "cc");                              \
++              __prev;                                                 \
++      })
++
++#define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval)   \
++      (abort(), 0)
++
++#define __arch_exchange_32_acq(mem, newval)                           \
++      ({                                                              \
++              __typeof__(*(mem)) __oldval;                            \
++              __asm__ __volatile__(                                   \
++                      "/*__arch_exchange_32_acq */\n"                 \
++                      "       xchg    %[old], %[m], %[new]"           \
++                      : [old] "=&r"(__oldval)                         \
++                      : [m] "r"(mem), [new] "r"(newval)               \
++                      : "memory");                                    \
++              __oldval;                                               \
++      })
++
++#define __arch_atomic_exchange_and_add_32(mem, value)                 \
++      ({                                                              \
++              __typeof__(*(mem)) __oldval, __tmp;                     \
++              __asm__ __volatile__(                                   \
++                      "/* __arch_atomic_exchange_and_add_32 */\n"     \
++                      "1:     ssrf    5\n"                            \
++                      "       ld.w    %[old], %[m]\n"                 \
++                      "       add     %[tmp], %[old], %[val]\n"       \
++                      "       stcond  %[m], %[tmp]\n"                 \
++                      "       brne    1b"                             \
++                      : [old] "=&r"(__oldval), [tmp] "=&r"(__tmp),    \
++                        [m] "=m"(*(mem))                              \
++                      : "m"(*(mem)), [val] "r"(value)                 \
++                      : "memory", "cc");                              \
++              __oldval;                                               \
++      })
++
++#define __arch_atomic_decrement_if_positive_32(mem)                   \
++      ({                                                              \
++              __typeof__(*(mem)) __oldval, __tmp;                     \
++              __asm__ __volatile__(                                   \
++                      "/* __arch_atomic_decrement_if_positive_32 */\n" \
++                      "1:     ssrf    5\n"                            \
++                      "       ld.w    %[old], %[m]\n"                 \
++                      "       sub     %[tmp], %[old], 1\n"            \
++                      "       brlt    2f\n"                           \
++                      "       stcond  %[m], %[tmp]\n"                 \
++                      "       brne    1b"                             \
++                      "2:"                                            \
++                      : [old] "=&r"(__oldval), [tmp] "=&r"(__tmp),    \
++                        [m] "=m"(*(mem))                              \
++                      : "m"(*(mem))                                   \
++                      : "memory", "cc");                              \
++              __oldval;                                               \
++      })
++
++#define atomic_exchange_acq(mem, newval)                              \
++      ({                                                              \
++              if (sizeof(*(mem)) != 4)                                \
++                      abort();                                        \
++              __arch_exchange_32_acq(mem, newval);                    \
++      })
++
++#define atomic_exchange_and_add(mem, newval)                          \
++      ({                                                              \
++              if (sizeof(*(mem)) != 4)                                \
++                      abort();                                        \
++              __arch_atomic_exchange_and_add_32(mem, newval);         \
++      })
++
++#define atomic_decrement_if_positive(mem)                             \
++      ({                                                              \
++              if (sizeof(*(mem)) != 4)                                \
++                      abort();                                        \
++              __arch_atomic_decrement_if_positive_32(mem);            \
++      })
++
++#endif /* _AVR32_BITS_ATOMIC_H */
+diff --git a/libc/sysdeps/linux/avr32/bits/byteswap.h b/libc/sysdeps/linux/avr32/bits/byteswap.h
+new file mode 100644
+index 0000000..1c030b9
+--- /dev/null
++++ b/libc/sysdeps/linux/avr32/bits/byteswap.h
+@@ -0,0 +1,70 @@
++/*
++ * Copyright (C) 2005 Atmel Corporation
++ *
++ * 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.
++ */
++
++#if !defined _BYTESWAP_H && !defined _NETINET_IN_H
++# error "Never use <bits/byteswap.h> directly; include <byteswap.h> instead."
++#endif
++
++#ifndef _BITS_BYTESWAP_H
++#define _BITS_BYTESWAP_H 1
++
++/* Swap bytes in 16 bit value.  */
++#if defined __GNUC__
++# define __bswap_16(x) (__extension__ __builtin_bswap_16(x))
++#else
++/* This is better than nothing.  */
++static __inline unsigned short int
++__bswap_16 (unsigned short int __bsx)
++{
++      return ((((__bsx) >> 8) & 0xff) | (((__bsx) & 0xff) << 8));
++}
++#endif
++
++/* Swap bytes in 32 bit value.  */
++#if defined __GNUC__
++# define __bswap_32(x) (__extension__ __builtin_bswap_32(x))
++#else
++static __inline unsigned int
++__bswap_32 (unsigned int __bsx)
++{
++  return ((((__bsx) & 0xff000000) >> 24) | (((__bsx) & 0x00ff0000) >>  8) |
++        (((__bsx) & 0x0000ff00) <<  8) | (((__bsx) & 0x000000ff) << 24));
++}
++#endif
++
++#if defined __GNUC__
++/* Swap bytes in 64 bit value.  */
++# define __bswap_constant_64(x)                               \
++      ((((x) & 0xff00000000000000ull) >> 56)          \
++       | (((x) & 0x00ff000000000000ull) >> 40)        \
++       | (((x) & 0x0000ff0000000000ull) >> 24)        \
++       | (((x) & 0x000000ff00000000ull) >> 8)         \
++       | (((x) & 0x00000000ff000000ull) << 8)         \
++       | (((x) & 0x0000000000ff0000ull) << 24)        \
++       | (((x) & 0x000000000000ff00ull) << 40)        \
++       | (((x) & 0x00000000000000ffull) << 56))
++
++# define __bswap_64(x)                                                        \
++      (__extension__                                                  \
++       ({                                                             \
++               union {                                                \
++                       __extension__ unsigned long long int __ll;     \
++                       unsigned int __l[2];                           \
++               } __w, __r;                                            \
++               if (__builtin_constant_p(x))                           \
++                       __r.__ll = __bswap_constant_64(x);             \
++               else {                                                 \
++                       __w.__ll = (x);                                \
++                       __r.__l[0] = __bswap_32(__w.__l[1]);           \
++                       __r.__l[1] = __bswap_32(__w.__l[0]);           \
++               }                                                      \
++               __r.__ll;                                              \
++       }))
++#endif
++
++#endif /* _BITS_BYTESWAP_H */
+diff --git a/libc/sysdeps/linux/avr32/bits/endian.h b/libc/sysdeps/linux/avr32/bits/endian.h
+new file mode 100644
+index 0000000..7bb6358
+--- /dev/null
++++ b/libc/sysdeps/linux/avr32/bits/endian.h
+@@ -0,0 +1,7 @@
++/* AVR32 is big-endian */
++
++#ifndef _ENDIAN_H
++# error "Never use <bits/endian.h> directly; include <endian.h> instead."
++#endif
++
++#define __BYTE_ORDER __BIG_ENDIAN
+diff --git a/libc/sysdeps/linux/avr32/bits/fcntl.h b/libc/sysdeps/linux/avr32/bits/fcntl.h
+new file mode 100644
+index 0000000..1abff17
+--- /dev/null
++++ b/libc/sysdeps/linux/avr32/bits/fcntl.h
+@@ -0,0 +1,165 @@
++#ifndef _FCNTL_H
++# error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead."
++#endif
++
++#include <sys/types.h>
++
++/*
++ * open/fcntl - O_SYNC is only implemented on blocks devices and on files
++ * located on an ext2 file system
++ */
++#define O_ACCMODE     00000003
++#define O_RDONLY      00000000
++#define O_WRONLY      00000001
++#define O_RDWR                00000002
++#define O_CREAT               00000100        /* not fcntl */
++#define O_EXCL                00000200        /* not fcntl */
++#define O_NOCTTY      00000400        /* not fcntl */
++#define O_TRUNC               00001000        /* not fcntl */
++#define O_APPEND      00002000
++#define O_NONBLOCK    00004000
++#define O_NDELAY      O_NONBLOCK
++#define O_SYNC                00010000
++#define O_ASYNC               00020000
++
++#ifdef __USE_GNU
++# define O_DIRECT     00040000        /* must be a directory */
++# define O_DIRECTORY  00200000        /* direct disk access */
++# define O_NOFOLLOW   00400000        /* don't follow links */
++# define O_NOATIME    01000000        /* don't set atime */
++#endif
++
++#ifdef __USE_LARGEFILE64
++# define O_LARGEFILE  00100000
++#endif
++
++/* For now Linux has synchronisity options for data and read operations.
++   We define the symbols here but let them do the same as O_SYNC since
++   this is a superset.        */
++#if defined __USE_POSIX199309 || defined __USE_UNIX98
++# define O_DSYNC      O_SYNC  /* Synchronize data.  */
++# define O_RSYNC      O_SYNC  /* Synchronize read operations.  */
++#endif
++
++#define F_DUPFD               0       /* dup */
++#define F_GETFD               1       /* get close_on_exec */
++#define F_SETFD               2       /* set/clear close_on_exec */
++#define F_GETFL               3       /* get file->f_flags */
++#define F_SETFL               4       /* set file->f_flags */
++
++#ifndef __USE_FILE_OFFSET64
++# define F_GETLK      5
++# define F_SETLK      6
++# define F_SETLKW     7
++#else
++# define F_GETLK      F_GETLK64
++# define F_SETLK      F_SETLK64
++# define F_SETLKW     F_SETLKW64
++#endif
++#define F_GETLK64     12      /*  using 'struct flock64' */
++#define F_SETLK64     13
++#define F_SETLKW64    14
++
++#if defined __USE_BSD || defined __USE_XOPEN2K
++# define F_SETOWN     8       /*  for sockets. */
++# define F_GETOWN     9       /*  for sockets. */
++#endif
++
++#ifdef __USE_GNU
++# define F_SETSIG     10      /*  for sockets. */
++# define F_GETSIG     11      /*  for sockets. */
++#endif
++
++#ifdef __USE_GNU
++# define F_SETLEASE   1024    /* Set a lease.  */
++# define F_GETLEASE   1025    /* Enquire what lease is active.  */
++# define F_NOTIFY     1026    /* Request notfications on a directory.  */
++#endif
++
++/* for F_[GET|SET]FL */
++#define FD_CLOEXEC    1       /* actually anything with low bit set goes */
++
++/* for posix fcntl() and lockf() */
++#define F_RDLCK               0
++#define F_WRLCK               1
++#define F_UNLCK               2
++
++/* for old implementation of bsd flock () */
++#define F_EXLCK               4       /* or 3 */
++#define F_SHLCK               8       /* or 4 */
++
++/* for leases */
++#define F_INPROGRESS  16
++
++#ifdef __USE_BSD
++/* operations for bsd flock(), also used by the kernel implementation */
++# define LOCK_SH      1       /* shared lock */
++# define LOCK_EX      2       /* exclusive lock */
++# define LOCK_NB      4       /* or'd with one of the above to prevent
++                                 blocking */
++# define LOCK_UN      8       /* remove lock */
++#endif
++
++#ifdef __USE_GNU
++# define LOCK_MAND    32      /* This is a mandatory flock */
++# define LOCK_READ    64      /* ... Which allows concurrent
++                                     read operations */
++# define LOCK_WRITE   128     /* ... Which allows concurrent
++                                     write operations */
++# define LOCK_RW      192     /* ... Which allows concurrent
++                                     read & write ops */
++#endif
++
++#ifdef __USE_GNU
++/* Types of directory notifications that may be requested with F_NOTIFY.  */
++# define DN_ACCESS    0x00000001      /* File accessed.  */
++# define DN_MODIFY    0x00000002      /* File modified.  */
++# define DN_CREATE    0x00000004      /* File created.  */
++# define DN_DELETE    0x00000008      /* File removed.  */
++# define DN_RENAME    0x00000010      /* File renamed.  */
++# define DN_ATTRIB    0x00000020      /* File changed attibutes.  */
++# define DN_MULTISHOT 0x80000000      /* Don't remove notifier.  */
++#endif
++
++struct flock {
++      short           l_type;
++      short           l_whence;
++#ifndef __USE_FILE_OFFSET64
++      __off_t         l_start;
++      __off_t         l_len;
++#else
++      __off64_t       l_start;
++      __off64_t       l_len;
++#endif
++      __pid_t         l_pid;
++};
++
++#ifdef __USE_LARGEFILE64
++struct flock64 {
++      short           l_type;
++      short           l_whence;
++      __off64_t       l_start;
++      __off64_t       l_len;
++      __pid_t         l_pid;
++};
++#endif
++
++/* Define some more compatibility macros to be backward compatible with
++ *    BSD systems which did not managed to hide these kernel macros.  */
++#ifdef  __USE_BSD
++# define FAPPEND        O_APPEND
++# define FFSYNC         O_FSYNC
++# define FASYNC         O_ASYNC
++# define FNONBLOCK      O_NONBLOCK
++# define FNDELAY        O_NDELAY
++#endif /* Use BSD.  */
++
++/* Advise to `posix_fadvise'.  */
++#ifdef __USE_XOPEN2K
++# define POSIX_FADV_NORMAL      0 /* No further special treatment.  */
++# define POSIX_FADV_RANDOM      1 /* Expect random page references.  */
++# define POSIX_FADV_SEQUENTIAL  2 /* Expect sequential page references.  */
++# define POSIX_FADV_WILLNEED    3 /* Will need these pages.  */
++# define POSIX_FADV_DONTNEED    4 /* Don't need these pages.  */
++# define POSIX_FADV_NOREUSE     5 /* Data will be accessed once.  */
++#endif
+diff --git a/libc/sysdeps/linux/avr32/bits/kernel_stat.h b/libc/sysdeps/linux/avr32/bits/kernel_stat.h
+new file mode 100644
+index 0000000..f97d23b
+--- /dev/null
++++ b/libc/sysdeps/linux/avr32/bits/kernel_stat.h
+@@ -0,0 +1,67 @@
++#ifndef _BITS_STAT_STRUCT_H
++#define _BITS_STAT_STRUCT_H
++
++#ifndef _LIBC
++#error bits/kernel_stat.h is for internal uClibc use only!
++#endif
++
++/*
++ * This file provides struct stat, taken from kernel 2.6.4. Verified
++ * to match kernel 2.6.22.
++ */
++
++struct kernel_stat {
++        unsigned long         st_dev;
++        unsigned long         st_ino;
++        unsigned short                st_mode;
++        unsigned short                st_nlink;
++        unsigned short                st_uid;
++        unsigned short                st_gid;
++        unsigned long         st_rdev;
++        unsigned long         st_size;
++        unsigned long         st_blksize;
++        unsigned long         st_blocks;
++        unsigned long         st_atime;
++        unsigned long         st_atime_nsec;
++        unsigned long         st_mtime;
++        unsigned long         st_mtime_nsec;
++        unsigned long         st_ctime;
++        unsigned long         st_ctime_nsec;
++        unsigned long         __unused4;
++        unsigned long         __unused5;
++};
++
++#define STAT_HAVE_NSEC 1
++
++struct kernel_stat64 {
++      unsigned long long      st_dev;
++
++      unsigned long long      st_ino;
++      unsigned int            st_mode;
++      unsigned int            st_nlink;
++
++      unsigned long           st_uid;
++      unsigned long           st_gid;
++
++      unsigned long long      st_rdev;
++
++      long long               st_size;
++      unsigned long           __pad1;
++      unsigned long           st_blksize;
++
++      unsigned long long      st_blocks;
++
++      unsigned long           st_atime;
++      unsigned long           st_atime_nsec;
++
++      unsigned long           st_mtime;
++      unsigned long           st_mtime_nsec;
++
++      unsigned long           st_ctime;
++      unsigned long           st_ctime_nsec;
++
++      unsigned long           __unused1;
++      unsigned long           __unused2;
++};
++
++#endif /* _BITS_STAT_STRUCT_H */
+diff --git a/libc/sysdeps/linux/avr32/bits/kernel_types.h b/libc/sysdeps/linux/avr32/bits/kernel_types.h
+new file mode 100644
+index 0000000..f7d8b52
+--- /dev/null
++++ b/libc/sysdeps/linux/avr32/bits/kernel_types.h
+@@ -0,0 +1,55 @@
++/* Note that we use the exact same include guard #define names
++ * as asm/posix_types.h.  This will avoid gratuitous conflicts
++ * with the posix_types.h kernel header, and will ensure that
++ * our private content, and not the kernel header, will win.
++ *  -Erik
++ */
++#ifndef __ASM_AVR32_POSIX_TYPES_H
++#define __ASM_AVR32_POSIX_TYPES_H
++
++/*
++ * This file is generally used by user-level software, so you need to
++ * be a little careful about namespace pollution etc.  Also, we cannot
++ * assume GCC is being used.
++ */
++
++typedef unsigned long         __kernel_dev_t;
++typedef unsigned long         __kernel_ino_t;
++typedef unsigned short                __kernel_mode_t;
++typedef unsigned short                __kernel_nlink_t;
++typedef long                  __kernel_off_t;
++typedef int                   __kernel_pid_t;
++typedef unsigned short                __kernel_ipc_pid_t;
++typedef unsigned int          __kernel_uid_t;
++typedef unsigned int          __kernel_gid_t;
++typedef unsigned long         __kernel_size_t;
++typedef long                  __kernel_ssize_t;
++typedef int                   __kernel_ptrdiff_t;
++typedef long                  __kernel_time_t;
++typedef long                  __kernel_suseconds_t;
++typedef long                  __kernel_clock_t;
++typedef int                   __kernel_timer_t;
++typedef int                   __kernel_clockid_t;
++typedef int                   __kernel_daddr_t;
++typedef char *                        __kernel_caddr_t;
++typedef unsigned short                __kernel_uid16_t;
++typedef unsigned short                __kernel_gid16_t;
++typedef unsigned int          __kernel_uid32_t;
++typedef unsigned int          __kernel_gid32_t;
++typedef unsigned short                __kernel_old_uid_t;
++typedef unsigned short                __kernel_old_gid_t;
++typedef unsigned short                __kernel_old_dev_t;
++
++#ifdef __GNUC__
++typedef long long             __kernel_loff_t;
++#endif
++
++typedef struct {
++#if defined(__USE_ALL)
++      int     val[2];
++#else
++      int     __val[2];
++#endif
++} __kernel_fsid_t;
++
++#endif /* __ASM_AVR32_POSIX_TYPES_H */
+diff --git a/libc/sysdeps/linux/avr32/bits/mman.h b/libc/sysdeps/linux/avr32/bits/mman.h
+new file mode 100644
+index 0000000..5f6e3c3
+--- /dev/null
++++ b/libc/sysdeps/linux/avr32/bits/mman.h
+@@ -0,0 +1,103 @@
++/* Definitions for POSIX memory map interface.  Linux/AVR32 version.
++   Copyright (C) 1997, 2000 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.  */
++
++#ifndef _SYS_MMAN_H
++# error "Never include this file directly.  Use <sys/mman.h> instead"
++#endif
++
++/* The following definitions basically come from the kernel headers.
++   But the kernel header is not namespace clean.  */
++
++
++/* Protections are chosen from these bits, OR'd together.  The
++   implementation does not necessarily support PROT_EXEC or PROT_WRITE
++   without PROT_READ.  The only guarantees are that no writing will be
++   allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */
++
++#define PROT_READ     0x1             /* Page can be read.  */
++#define PROT_WRITE    0x2             /* Page can be written.  */
++#define PROT_EXEC     0x4             /* Page can be executed.  */
++#define PROT_NONE     0x0             /* Page can not be accessed.  */
++#define PROT_GROWSDOWN        0x01000000      /* Extend change to start of
++                                         growsdown vma (mprotect only).  */
++#define PROT_GROWSUP  0x02000000      /* Extend change to start of
++                                         growsup vma (mprotect only).  */
++
++/* Sharing types (must choose one and only one of these).  */
++#define MAP_SHARED    0x01            /* Share changes.  */
++#define MAP_PRIVATE   0x02            /* Changes are private.  */
++#ifdef __USE_MISC
++# define MAP_TYPE     0x0f            /* Mask for type of mapping.  */
++#endif
++
++/* Other flags.  */
++#define MAP_FIXED     0x10            /* Interpret addr exactly.  */
++#ifdef __USE_MISC
++# define MAP_FILE     0
++# define MAP_ANONYMOUS        0x20            /* Don't use a file.  */
++# define MAP_ANON     MAP_ANONYMOUS
++#endif
++
++/* These are Linux-specific.  */
++#ifdef __USE_MISC
++# define MAP_GROWSDOWN        0x0100          /* Stack-like segment.  */
++# define MAP_DENYWRITE        0x0800          /* ETXTBSY */
++# define MAP_EXECUTABLE       0x1000          /* Mark it as an executable.  */
++# define MAP_LOCKED   0x2000          /* Lock the mapping.  */
++# define MAP_NORESERVE        0x4000          /* Don't check for reservations.  */
++# define MAP_POPULATE 0x8000          /* populate (prefault) pagetables */
++# define MAP_NONBLOCK 0x10000         /* do not block on IO */
++#endif
++
++/* Flags to `msync'.  */
++#define MS_ASYNC      1               /* Sync memory asynchronously.  */
++#define MS_SYNC               4               /* Synchronous memory sync.  */
++#define MS_INVALIDATE 2               /* Invalidate the caches.  */
++
++/* Flags for `mlockall'.  */
++#define MCL_CURRENT   1               /* Lock all currently mapped pages.  */
++#define MCL_FUTURE    2               /* Lock all additions to address
++                                         space.  */
++
++/* Flags for `mremap'.  */
++#ifdef __USE_GNU
++# define MREMAP_MAYMOVE       1
++# define MREMAP_FIXED 2
++#endif
++
++/* Advise to `madvise'.  */
++#ifdef __USE_BSD
++# define MADV_NORMAL   0      /* No further special treatment.  */
++# define MADV_RANDOM   1      /* Expect random page references.  */
++# define MADV_SEQUENTIAL 2    /* Expect sequential page references.  */
++# define MADV_WILLNEED         3      /* Will need these pages.  */
++# define MADV_DONTNEED         4      /* Don't need these pages.  */
++# define MADV_REMOVE   9      /* Remove these pages and resources.  */
++# define MADV_DONTFORK         10     /* Do not inherit across fork.  */
++# define MADV_DOFORK   11     /* Do inherit across fork.  */
++#endif
++
++/* The POSIX people had to invent similar names for the same things.  */
++#ifdef __USE_XOPEN2K
++# define POSIX_MADV_NORMAL    0 /* No further special treatment.  */
++# define POSIX_MADV_RANDOM    1 /* Expect random page references.  */
++# define POSIX_MADV_SEQUENTIAL        2 /* Expect sequential page references.  */
++# define POSIX_MADV_WILLNEED  3 /* Will need these pages.  */
++# define POSIX_MADV_DONTNEED  4 /* Don't need these pages.  */
++#endif
+diff --git a/libc/sysdeps/linux/avr32/bits/setjmp.h b/libc/sysdeps/linux/avr32/bits/setjmp.h
+new file mode 100644
+index 0000000..78348a3
+--- /dev/null
++++ b/libc/sysdeps/linux/avr32/bits/setjmp.h
+@@ -0,0 +1,30 @@
++/*
++ * Copyright (C) 2004-2005 Atmel Corporation
++ *
++ * 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.
++ */
++#ifndef _BITS_SETJMP_H
++#define _BITS_SETJMP_H        1
++
++#if !defined _SETJMP_H && !defined _PTHREAD_H
++# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
++#endif
++
++#ifndef _ASM
++/*
++ * The jump buffer contains r0-r7, sr, sp and lr. Other registers are
++ * not saved.
++ */
++typedef int __jmp_buf[11];
++#endif
++
++#define __JMP_BUF_SP  4
++
++/* Test if longjmp to JMPBUF would unwind the frame containing a local
++   variable at ADDRESS.  */
++#define _JMPBUF_UNWINDS(jmpbuf, address) \
++  ((void *)(address) < (void *)(jmpbuf[__JMP_BUF_SP]))
++
++#endif /* _BITS_SETJMP_H */
+diff --git a/libc/sysdeps/linux/avr32/bits/stackinfo.h b/libc/sysdeps/linux/avr32/bits/stackinfo.h
+new file mode 100644
+index 0000000..29b8452
+--- /dev/null
++++ b/libc/sysdeps/linux/avr32/bits/stackinfo.h
+@@ -0,0 +1,28 @@
++/* Copyright (C) 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 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.  */
++
++/* This file contains a bit of information about the stack allocation
++   of the processor.  */
++
++#ifndef _STACKINFO_H
++#define _STACKINFO_H  1
++
++/* On AVR32 the stack grows down. */
++#define _STACK_GROWS_DOWN     1
++
++#endif        /* stackinfo.h */
+diff --git a/libc/sysdeps/linux/avr32/bits/syscalls.h b/libc/sysdeps/linux/avr32/bits/syscalls.h
+new file mode 100644
+index 0000000..22ac059
+--- /dev/null
++++ b/libc/sysdeps/linux/avr32/bits/syscalls.h
+@@ -0,0 +1,143 @@
++#ifndef _BITS_SYSCALLS_H
++#define _BITS_SYSCALLS_H
++#ifndef _SYSCALL_H
++# error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead."
++#endif
++
++/*
++ * This includes the `__NR_<name>' syscall numbers taken from the
++ * Linux kernel header files. It also defines the traditional
++ * `SYS_<name>' macros for older programs.
++ */
++#include <bits/sysnum.h>
++
++#ifndef __ASSEMBLER__
++
++#include <errno.h>
++
++#define SYS_ify(syscall_name) (__NR_##syscall_name)
++
++#undef _syscall0
++#define _syscall0(type,name)                          \
++      type name(void)                                 \
++      {                                               \
++              return (type)(INLINE_SYSCALL(name, 0)); \
++      }
++
++#undef _syscall1
++#define _syscall1(type,name,type1,arg1)                               \
++      type name(type1 arg1)                                   \
++      {                                                       \
++              return (type)(INLINE_SYSCALL(name, 1, arg1));   \
++      }
++
++#undef _syscall2
++#define _syscall2(type,name,type1,arg1,type2,arg2)                    \
++      type name(type1 arg1, type2 arg2)                               \
++      {                                                               \
++              return (type)(INLINE_SYSCALL(name, 2, arg1, arg2));     \
++      }
++
++#undef _syscall3
++#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)         \
++      type name(type1 arg1, type2 arg2, type3 arg3)                   \
++      {                                                               \
++              return (type)(INLINE_SYSCALL(name, 3, arg1,             \
++                                           arg2, arg3));              \
++      }
++
++#undef _syscall4
++#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,         \
++                type4,arg4)                                           \
++      type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4)       \
++      {                                                               \
++              return (type)(INLINE_SYSCALL(name, 4, arg1, arg2,       \
++                                           arg3, arg4));              \
++      }
++
++#undef _syscall5
++#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,         \
++                type4,arg4,type5,arg5)                                \
++      type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4,       \
++                type5 arg5)                                           \
++      {                                                               \
++              return (type)(INLINE_SYSCALL(name, 5, arg1, arg2,       \
++                                           arg3, arg4, arg5));        \
++      }
++
++#undef _syscall6
++#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,         \
++                type4,arg4,type5,arg5,type6,arg6)                     \
++      type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4,       \
++                type5 arg5, type6 arg6)                               \
++      {                                                               \
++              return (type)(INLINE_SYSCALL(name, 6, arg1, arg2, arg3, \
++                                           arg4, arg5, arg6));        \
++      }
++
++#undef unlikely
++#define unlikely(x) __builtin_expect((x), 0)
++
++#undef INLINE_SYSCALL
++#define INLINE_SYSCALL(name, nr, args...)                             \
++      ({                                                              \
++              unsigned _sys_result = INTERNAL_SYSCALL(name, , nr, args); \
++              if (unlikely(INTERNAL_SYSCALL_ERROR_P(_sys_result, ))) { \
++                      __set_errno(INTERNAL_SYSCALL_ERRNO(_sys_result, )); \
++                      _sys_result = (unsigned int) -1;                \
++              }                                                       \
++              (int) _sys_result;                                      \
++      })
++
++#undef INTERNAL_SYSCALL_DECL
++#define INTERNAL_SYSCALL_DECL(err) do { } while(0)
++
++#undef INTERNAL_SYSCALL
++#define INTERNAL_SYSCALL(name, err, nr, args...)                      \
++      ({                                                              \
++              register int _a1 asm ("r12");                           \
++              register int _scno asm("r8") = SYS_ify(name);           \
++              LOAD_ARGS_##nr (args);                                  \
++              asm volatile ("scall    /* syscall " #name " */"        \
++                            : "=r" (_a1)                              \
++                            : "r"(_scno) ASM_ARGS_##nr                \
++                            : "cc", "memory");                        \
++              _a1;                                                    \
++      })
++
++#undef INTERNAL_SYSCALL_ERROR_P
++#define INTERNAL_SYSCALL_ERROR_P(val, err)            \
++      ((unsigned int)(val) >= 0xfffff001U)
++
++#undef INTERNAL_SYSCALL_ERRNO
++#define INTERNAL_SYSCALL_ERRNO(val, errr) (-(val))
++
++#define LOAD_ARGS_0() do { } while(0)
++#define ASM_ARGS_0
++#define LOAD_ARGS_1(a1)                                       \
++      _a1 = (int) (a1);                               \
++      LOAD_ARGS_0()
++#define ASM_ARGS_1    ASM_ARGS_0, "r"(_a1)
++#define LOAD_ARGS_2(a1, a2)                           \
++      register int _a2 asm("r11") = (int)(a2);        \
++      LOAD_ARGS_1(a1)
++#define ASM_ARGS_2    ASM_ARGS_1, "r"(_a2)
++#define LOAD_ARGS_3(a1, a2, a3)                               \
++      register int _a3 asm("r10") = (int)(a3);        \
++      LOAD_ARGS_2(a1, a2)
++#define ASM_ARGS_3    ASM_ARGS_2, "r"(_a3)
++#define LOAD_ARGS_4(a1, a2, a3, a4)                   \
++      register int _a4 asm("r9") = (int)(a4);         \
++      LOAD_ARGS_3(a1, a2, a3)
++#define ASM_ARGS_4    ASM_ARGS_3, "r"(_a4)
++#define LOAD_ARGS_5(a1, a2, a3, a4, a5)                       \
++      register int _a5 asm("r5") = (int)(a5);         \
++      LOAD_ARGS_4(a1, a2, a3, a4)
++#define ASM_ARGS_5    ASM_ARGS_4, "r"(_a5)
++#define LOAD_ARGS_6(a1, a2, a3, a4, a5, a6)           \
++      register int _a6 asm("r3") = (int)(a6);         \
++      LOAD_ARGS_5(a1, a2, a3, a4, a5)
++#define ASM_ARGS_6    ASM_ARGS_5, "r"(_a6)
++
++#endif /* __ASSEMBLER__ */
++#endif /* _BITS_SYSCALLS_H */
+diff --git a/libc/sysdeps/linux/avr32/bits/uClibc_arch_features.h b/libc/sysdeps/linux/avr32/bits/uClibc_arch_features.h
+new file mode 100644
+index 0000000..e95e8a5
+--- /dev/null
++++ b/libc/sysdeps/linux/avr32/bits/uClibc_arch_features.h
+@@ -0,0 +1,45 @@
++/*
++ * Track misc arch-specific features that aren't config options
++ */
++
++#ifndef _BITS_UCLIBC_ARCH_FEATURES_H
++#define _BITS_UCLIBC_ARCH_FEATURES_H
++
++/* instruction used when calling abort() to kill yourself */
++/* trigger illegal instruction exception, same as BUG in Linux */
++#define __UCLIBC_ABORT_INSTRUCTION__ ".short 0x5df0"
++
++/* can your target use syscall6() for mmap ? */
++#define __UCLIBC_MMAP_HAS_6_ARGS__
++
++/* does your target use syscall4() for truncate64 ? (32bit arches only) */
++#undef __UCLIBC_TRUNCATE64_HAS_4_ARGS__
++
++/* does your target have a broken create_module() ? */
++#undef __UCLIBC_BROKEN_CREATE_MODULE__
++
++/* does your target have to worry about older [gs]etrlimit() ? */
++#undef __UCLIBC_HANDLE_OLDER_RLIMIT__
++
++/* does your target prefix all symbols with an _ ? */
++#define __UCLIBC_NO_UNDERSCORES__
++
++/* does your target have an asm .set ? */
++#define __UCLIBC_HAVE_ASM_SET_DIRECTIVE__
++
++/* define if target doesn't like .global */
++#undef __UCLIBC_ASM_GLOBAL_DIRECTIVE__
++
++/* define if target supports .weak */
++#define __UCLIBC_HAVE_ASM_WEAK_DIRECTIVE__
++
++/* define if target supports .weakext */
++#undef __UCLIBC_HAVE_ASM_WEAKEXT_DIRECTIVE__
++
++/* needed probably only for ppc64 */
++#undef __UCLIBC_HAVE_ASM_GLOBAL_DOT_NAME__
++
++/* define if target supports IEEE signed zero floats */
++#define __UCLIBC_HAVE_SIGNED_ZERO__
++
++#endif /* _BITS_UCLIBC_ARCH_FEATURES_H */
+diff --git a/libc/sysdeps/linux/avr32/bits/wordsize.h b/libc/sysdeps/linux/avr32/bits/wordsize.h
+new file mode 100644
+index 0000000..1b5842a
+--- /dev/null
++++ b/libc/sysdeps/linux/avr32/bits/wordsize.h
+@@ -0,0 +1 @@
++#define __WORDSIZE    32
+diff --git a/libc/sysdeps/linux/avr32/brk.c b/libc/sysdeps/linux/avr32/brk.c
+new file mode 100644
+index 0000000..a54b49a
+--- /dev/null
++++ b/libc/sysdeps/linux/avr32/brk.c
+@@ -0,0 +1,31 @@
++/*
++ * Copyright (C) 2004-2007 Atmel Corporation
++ *
++ * 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.
++ */
++#include <errno.h>
++#include <unistd.h>
++#include <sys/syscall.h>
++
++libc_hidden_proto(brk)
++
++void *__curbrk attribute_hidden = 0;
++
++int brk (void *addr)
++{
++      void *newbrk;
++
++      newbrk = (void *)INLINE_SYSCALL(brk, 1, addr);
++
++      __curbrk = newbrk;
++
++      if (newbrk < addr) {
++              __set_errno (ENOMEM);
++              return -1;
++      }
++
++      return 0;
++}
++libc_hidden_def(brk)
+diff --git a/libc/sysdeps/linux/avr32/bsd-_setjmp.S b/libc/sysdeps/linux/avr32/bsd-_setjmp.S
+new file mode 100644
+index 0000000..be66a10
+--- /dev/null
++++ b/libc/sysdeps/linux/avr32/bsd-_setjmp.S
+@@ -0,0 +1,16 @@
++/*
++ * Copyright (C) 2004-2007 Atmel Corporation
++ *
++ * 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.
++ */
++
++      /* This just does a tail-call to __sigsetjmp(env, 0) */
++      .global _setjmp
++      .type   _setjmp,"function"
++      .align  1
++_setjmp:
++      mov     r11, 0
++      bral    __GI___sigsetjmp
++      .size   _setjmp, . - _setjmp
+diff --git a/libc/sysdeps/linux/avr32/bsd-setjmp.S b/libc/sysdeps/linux/avr32/bsd-setjmp.S
+new file mode 100644
+index 0000000..4635eeb
+--- /dev/null
++++ b/libc/sysdeps/linux/avr32/bsd-setjmp.S
+@@ -0,0 +1,16 @@
++/*
++ * Copyright (C) 2004-2007 Atmel Corporation
++ *
++ * 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.
++ */
++
++      /* This just does a tail-call to __sigsetjmp(env, 1) */
++      .global setjmp
++      .type   setjmp,"function"
++      .align  1
++setjmp:
++      mov     r11, 1
++      bral    __GI___sigsetjmp
++      .size   setjmp, . - setjmp
+diff --git a/libc/sysdeps/linux/avr32/clone.c b/libc/sysdeps/linux/avr32/clone.c
+new file mode 100644
+index 0000000..e43b0f3
+--- /dev/null
++++ b/libc/sysdeps/linux/avr32/clone.c
+@@ -0,0 +1,41 @@
++/*
++ * Copyright (C) 2004 Atmel Corporation
++ *
++ * 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.
++ */
++#include <errno.h>
++#include <sys/syscall.h>
++#include <unistd.h>
++
++/*
++ * I don't know if we can be absolutely certain that the fn and arg
++ * parameters are preserved when returning as the child. If the
++ * compiler stores them in registers (r0-r7), they should be.
++ */
++int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg)
++{
++      register int (*_fn)(void *arg) = fn;
++      register void *_arg = arg;
++      int err;
++
++      /* Sanity check the arguments */
++      err = -EINVAL;
++      if (!fn)
++              goto syscall_error;
++      if (!child_stack)
++              goto syscall_error;
++
++      err = INLINE_SYSCALL(clone, 2, flags, child_stack);
++      if (err < 0)
++              goto syscall_error;
++      else if (err != 0)
++              return err;
++
++      _exit(_fn(_arg));
++
++syscall_error:
++      __set_errno (-err);
++      return -1;
++}
+diff --git a/libc/sysdeps/linux/avr32/crt1.S b/libc/sysdeps/linux/avr32/crt1.S
+new file mode 100644
+index 0000000..ca1fa7a
+--- /dev/null
++++ b/libc/sysdeps/linux/avr32/crt1.S
+@@ -0,0 +1,97 @@
++/*
++ * Copyright (C) 2004-2007 Atmel Corporation
++ *
++ * 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.
++ *
++ * When we enter _start, the stack looks like this:
++ *    argc            argument counter
++ *    argv[0]         pointer to program name
++ *    argv[1..argc-1] pointers to program args
++ *    NULL
++ *    env[0..N]       pointers to environment variables
++ *    NULL
++ *
++ * r12 contains a function pointer to be registered with `atexit'.
++ * This is how the dynamic linker arranges to have DT_FINI functions
++ * called for shared libraries that have been loaded before this
++ * code runs.
++ *
++ * We're going to call the following function:
++ * __uClibc_main(int (*main)(int, char **, char **), int argc,
++ *             char **argv, void (*app_init)(void), void (*app_fini)(void),
++ *             void (*rtld_fini)(void), void *stack_end)
++ *
++ * So we need to set up things as follows:
++ *    r12 = address of main
++ *    r11 = argc
++ *    r10 = &argv[0]
++ *    r9  = address of _init
++ *    r8  = address of _fini
++ *    sp[0] = whatever we got passed in r12
++ */
++
++#include <features.h>
++
++      .text
++      .global _start
++      .type   _start, @function
++_start:
++      /* Clear the frame pointer and link register since this is the outermost frame.  */
++      mov     r7, 0
++      mov     lr, 0
++
++      ld.w    r11, sp++               /* argc         */
++      mov     r10, sp                 /* &argv[0]     */
++
++      st.w    --sp, r10               /* stack_end */
++      st.w    --sp, r12               /* rtld_fini */
++
++#ifdef __PIC__
++      lddpc   r6, .L_GOT
++.L_RGOT:
++      rsub    r6, pc
++      lda.w   r9, _init
++      lda.w   r8, _fini
++      lda.w   r12, main
++
++      /* Ok, now run uClibc's main() -- should not return */
++      call    __uClibc_main
++
++      .align  2
++.L_GOT:
++      .long   .L_RGOT - _GLOBAL_OFFSET_TABLE_
++#else
++      lddpc   r9, __init_addr         /* app_init */
++      lddpc   r8, __fini_addr         /* app_fini */
++      lddpc   r12, __main_addr        /* main */
++
++      /* Ok, now run uClibc's main() -- should not return */
++      lddpc   pc, ___uClibc_main_addr
++
++      .align  2
++__init_addr:
++      .long   _init
++__fini_addr:
++      .long   _fini
++__main_addr:
++      .long   main
++___uClibc_main_addr:
++      .long   __uClibc_main
++#endif
++      .size   _start, . - _start
++
++      /*
++       * The LSB says we need this.
++       */
++      .section ".note.ABI-tag", "a"
++      .align  4
++      .long   2f - 1f         /* namesz */
++      .long   4f - 3f         /* descsz */
++      .long   1               /* type   */
++1:    .asciz  "GNU"           /* name */
++2:    .align  4
++3:    .long   0               /* Linux executable */
++      .long   2,6,0           /* Earliest compatible kernel */
++4:    .align  4
+diff --git a/libc/sysdeps/linux/avr32/crti.S b/libc/sysdeps/linux/avr32/crti.S
+new file mode 100644
+index 0000000..660f47c
+--- /dev/null
++++ b/libc/sysdeps/linux/avr32/crti.S
+@@ -0,0 +1,26 @@
++
++      .section .init
++      .align  2
++      .global _init
++      .type   _init, @function
++_init:
++      stm     --sp, r6, lr
++      lddpc   r6, 2f
++1:    rsub    r6, pc
++      rjmp    3f
++      .align  2
++2:    .long   1b - _GLOBAL_OFFSET_TABLE_
++3:
++
++      .section .fini
++      .align  2
++      .global _fini
++      .type   _fini, @function
++_fini:
++      stm     --sp, r6, lr
++      lddpc   r6, 2f
++1:    rsub    r6, pc
++      rjmp    3f
++      .align  2
++2:    .long   1b - _GLOBAL_OFFSET_TABLE_
++3:
+diff --git a/libc/sysdeps/linux/avr32/crtn.S b/libc/sysdeps/linux/avr32/crtn.S
+new file mode 100644
+index 0000000..f7d1040
+--- /dev/null
++++ b/libc/sysdeps/linux/avr32/crtn.S
+@@ -0,0 +1,14 @@
++
++      .section .init
++      .align  2
++      .global _init
++      .type   _init, @function
++      ldm     sp++, r6, pc
++      .size   _init, . - _init
++
++      .section .fini
++      .align  2
++      .global _fini
++      .type   _fini, @function
++      ldm     sp++, r6, pc
++      .size   _fini, . - _fini
+diff --git a/libc/sysdeps/linux/avr32/mmap.c b/libc/sysdeps/linux/avr32/mmap.c
+new file mode 100644
+index 0000000..2ee025a
+--- /dev/null
++++ b/libc/sysdeps/linux/avr32/mmap.c
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (C) 2004-2007 Atmel Corporation
++ *
++ * 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.
++ */
++
++#include <errno.h>
++#include <unistd.h>
++#include <sys/mman.h>
++#include <sys/syscall.h>
++
++libc_hidden_proto(mmap)
++
++static _syscall6(__ptr_t, mmap2, __ptr_t, addr, size_t, len, int, prot,
++               int, flags, int, fd, __off_t, pgoff);
++
++__ptr_t mmap(__ptr_t addr, size_t len, int prot, int flags, int fd, __off_t offset)
++{
++      unsigned long page_size = sysconf(_SC_PAGESIZE);
++      unsigned long pgoff;
++
++      if (offset & (page_size - 1)) {
++              __set_errno(EINVAL);
++              return MAP_FAILED;
++      }
++
++      pgoff = (unsigned long)offset >> (31 - __builtin_clz(page_size));
++
++      return mmap2(addr, len, prot, flags, fd, pgoff);
++}
++libc_hidden_def(mmap)
+diff --git a/libc/sysdeps/linux/avr32/setjmp.S b/libc/sysdeps/linux/avr32/setjmp.S
+new file mode 100644
+index 0000000..7d0354b
+--- /dev/null
++++ b/libc/sysdeps/linux/avr32/setjmp.S
+@@ -0,0 +1,29 @@
++/*
++ * Copyright (C) 2004-2007 Atmel Corporation
++ *
++ * 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.
++ */
++#define _SETJMP_H
++#define _ASM
++#include <bits/setjmp.h>
++
++      .text
++
++      .global __sigsetjmp
++      .type   __sigsetjmp,"function"
++
++      .align  1
++__sigsetjmp:
++      mustr   r8
++      stm     r12, r0,r1,r2,r3,r4,r5,r6,r7,r8,sp,lr
++
++      /*
++       * Make a tail call to __sigjmp_save; it takes the same args
++       * and is hidden so we don't need to mess around with the GOT.
++       */
++      rjmp    __sigjmp_save
++      .size   __sigsetjmp, . - __sigsetjmp
++
++libc_hidden_def(__sigsetjmp)
+diff --git a/libc/sysdeps/linux/avr32/sigaction.c b/libc/sysdeps/linux/avr32/sigaction.c
+new file mode 100644
+index 0000000..a97ff3d
+--- /dev/null
++++ b/libc/sysdeps/linux/avr32/sigaction.c
+@@ -0,0 +1,59 @@
++/*
++ * Copyright (C) 2004-2007 Atmel Corporation
++ *
++ * 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.
++ */
++#include <errno.h>
++#include <signal.h>
++#include <string.h>
++#include <sys/syscall.h>
++#include <bits/kernel_sigaction.h>
++
++#define SA_RESTORER   0x04000000
++extern void __default_rt_sa_restorer(void);
++
++libc_hidden_proto(memcpy)
++
++/*
++ * If act is not NULL, change the action for sig to *act.
++ * If oact is not NULL, put the old action for sig in *oact.
++ */
++int __libc_sigaction(int signum, const struct sigaction *act,
++                   struct sigaction *oldact)
++{
++      struct kernel_sigaction kact, koact;
++      int result;
++
++      if (act) {
++              kact.k_sa_handler = act->sa_handler;
++              memcpy(&kact.sa_mask, &act->sa_mask, sizeof (kact.sa_mask));
++              kact.sa_flags = act->sa_flags;
++              if (kact.sa_flags & (SA_RESTORER | SA_ONSTACK))
++                      kact.sa_restorer = act->sa_restorer;
++              else
++                      kact.sa_restorer = __default_rt_sa_restorer;
++              kact.sa_flags |= SA_RESTORER;
++      }
++
++      result = __syscall_rt_sigaction(signum, act ? __ptrvalue(&kact) : NULL,
++                                      oldact ? __ptrvalue(&koact) : NULL,
++                                      _NSIG / 8);
++
++      if (oldact && result >= 0) {
++              oldact->sa_handler = koact.k_sa_handler;
++              memcpy(&oldact->sa_mask, &koact.sa_mask,
++                     sizeof(oldact->sa_mask));
++              oldact->sa_flags = koact.sa_flags;
++              oldact->sa_restorer = koact.sa_restorer;
++      }
++
++      return result;
++}
++
++#ifndef LIBC_SIGACTION
++libc_hidden_proto(sigaction)
++weak_alias(__libc_sigaction, sigaction)
++libc_hidden_weak(sigaction)
++#endif
+diff --git a/libc/sysdeps/linux/avr32/sigrestorer.S b/libc/sysdeps/linux/avr32/sigrestorer.S
+new file mode 100644
+index 0000000..df6a1ba
+--- /dev/null
++++ b/libc/sysdeps/linux/avr32/sigrestorer.S
+@@ -0,0 +1,15 @@
++/*
++ * Copyright (C) 2004 Atmel Corporation
++ *
++ * 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.
++ */
++#include <sys/syscall.h>
++
++      .global __default_rt_sa_restorer
++      .type   __default_rt_sa_restorer,"function"
++      .align  1
++__default_rt_sa_restorer:
++      mov     r8, __NR_rt_sigreturn
++      scall
+diff --git a/libc/sysdeps/linux/avr32/sys/elf.h b/libc/sysdeps/linux/avr32/sys/elf.h
+new file mode 100644
+index 0000000..faa7310
+--- /dev/null
++++ b/libc/sysdeps/linux/avr32/sys/elf.h
+@@ -0,0 +1,26 @@
++/* Copyright (C) 1996, 1997, 1999, 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.  */
++
++#ifndef _SYS_ELF_H
++#define _SYS_ELF_H    1
++
++#warning "This header is obsolete; use <sys/procfs.h> instead."
++
++#include <sys/procfs.h>
++
++#endif        /* sys/elf.h */
+diff --git a/libc/sysdeps/linux/avr32/sys/procfs.h b/libc/sysdeps/linux/avr32/sys/procfs.h
+new file mode 100644
+index 0000000..3b37363
+--- /dev/null
++++ b/libc/sysdeps/linux/avr32/sys/procfs.h
+@@ -0,0 +1,123 @@
++/* Copyright (C) 1996, 1997, 1999, 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.  */
++
++#ifndef _SYS_PROCFS_H
++#define _SYS_PROCFS_H 1
++
++/* This is somewhat modelled after the file of the same name on SVR4
++   systems.  It provides a definition of the core file format for ELF
++   used on Linux.  It doesn't have anything to do with the /proc file
++   system, even though Linux has one.
++
++   Anyway, the whole purpose of this file is for GDB and GDB only.
++   Don't read too much into it.  Don't use it for anything other than
++   GDB unless you know what you are doing.  */
++
++#include <features.h>
++#include <sys/time.h>
++#include <sys/types.h>
++#include <sys/user.h>
++
++__BEGIN_DECLS
++
++/* Type for a general-purpose register.  */
++typedef unsigned long elf_greg_t;
++
++/* And the whole bunch of them.  We could have used `struct
++   user_regs' directly in the typedef, but tradition says that
++   the register set is an array, which does have some peculiar
++   semantics, so leave it that way.  */
++#define ELF_NGREG (sizeof (struct user_regs) / sizeof(elf_greg_t))
++typedef elf_greg_t elf_gregset_t[ELF_NGREG];
++
++/* Register set for the floating-point registers.  */
++typedef struct user_fpregs elf_fpregset_t;
++
++/* Signal info.  */
++struct elf_siginfo
++  {
++    int si_signo;                     /* Signal number.  */
++    int si_code;                      /* Extra code.  */
++    int si_errno;                     /* Errno.  */
++  };
++
++/* Definitions to generate Intel SVR4-like core files.  These mostly
++   have the same names as the SVR4 types with "elf_" tacked on the
++   front to prevent clashes with Linux definitions, and the typedef
++   forms have been avoided.  This is mostly like the SVR4 structure,
++   but more Linuxy, with things that Linux does not support and which
++   GDB doesn't really use excluded.  */
++
++struct elf_prstatus
++  {
++    struct elf_siginfo pr_info;               /* Info associated with signal.  */
++    short int pr_cursig;              /* Current signal.  */
++    unsigned long int pr_sigpend;     /* Set of pending signals.  */
++    unsigned long int pr_sighold;     /* Set of held signals.  */
++    __pid_t pr_pid;
++    __pid_t pr_ppid;
++    __pid_t pr_pgrp;
++    __pid_t pr_sid;
++    struct timeval pr_utime;          /* User time.  */
++    struct timeval pr_stime;          /* System time.  */
++    struct timeval pr_cutime;         /* Cumulative user time.  */
++    struct timeval pr_cstime;         /* Cumulative system time.  */
++    elf_gregset_t pr_reg;             /* GP registers.  */
++    int pr_fpvalid;                   /* True if math copro being used.  */
++  };
++
++
++#define ELF_PRARGSZ     (80)    /* Number of chars for args.  */
++
++struct elf_prpsinfo
++  {
++    char pr_state;                    /* Numeric process state.  */
++    char pr_sname;                    /* Char for pr_state.  */
++    char pr_zomb;                     /* Zombie.  */
++    char pr_nice;                     /* Nice val.  */
++    unsigned long int pr_flag;                /* Flags.  */
++    unsigned short int pr_uid;
++    unsigned short int pr_gid;
++    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
++    /* Lots missing */
++    char pr_fname[16];                        /* Filename of executable.  */
++    char pr_psargs[ELF_PRARGSZ];      /* Initial part of arg list.  */
++  };
++
++/* The rest of this file provides the types for emulation of the
++   Solaris <proc_service.h> interfaces that should be implemented by
++   users of libthread_db.  */
++
++/* Addresses.  */
++typedef void *psaddr_t;
++
++/* Register sets.  Linux has different names.  */
++typedef elf_gregset_t prgregset_t;
++typedef elf_fpregset_t prfpregset_t;
++
++/* We don't have any differences between processes and threads,
++   therefore have only one PID type.  */
++typedef __pid_t lwpid_t;
++
++/* Process status and info.  In the end we do provide typedefs for them.  */
++typedef struct elf_prstatus prstatus_t;
++typedef struct elf_prpsinfo prpsinfo_t;
++
++__END_DECLS
++
++#endif        /* sys/procfs.h */
+diff --git a/libc/sysdeps/linux/avr32/sys/ucontext.h b/libc/sysdeps/linux/avr32/sys/ucontext.h
+new file mode 100644
+index 0000000..82c7fe2
+--- /dev/null
++++ b/libc/sysdeps/linux/avr32/sys/ucontext.h
+@@ -0,0 +1,90 @@
++/* Copyright (C) 1998, 1999, 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.  */
++
++/* Linux/AVR32 ABI compliant context switching support.  */
++
++#ifndef _SYS_UCONTEXT_H
++#define _SYS_UCONTEXT_H       1
++
++#include <features.h>
++#include <signal.h>
++#include <sys/procfs.h>
++#include <bits/sigcontext.h>
++
++typedef int greg_t;
++
++/* Number of general registers.  */
++#define NGREG 16
++
++/* Container for all general registers.  */
++typedef elf_gregset_t gregset_t;
++
++/* Number of each register is the `gregset_t' array.  */
++enum
++{
++  R0 = 0,
++#define R0    R0
++  R1 = 1,
++#define R1    R1
++  R2 = 2,
++#define R2    R2
++  R3 = 3,
++#define R3    R3
++  R4 = 4,
++#define R4    R4
++  R5 = 5,
++#define R5    R5
++  R6 = 6,
++#define R6    R6
++  R7 = 7,
++#define R7    R7
++  R8 = 8,
++#define R8    R8
++  R9 = 9,
++#define R9    R9
++  R10 = 10,
++#define R10   R10
++  R11 = 11,
++#define R11   R11
++  R12 = 12,
++#define R12   R12
++  R13 = 13,
++#define R13   R13
++  R14 = 14,
++#define R14   R14
++  R15 = 15
++#define R15   R15
++};
++
++/* Structure to describe FPU registers.  */
++typedef elf_fpregset_t        fpregset_t;
++
++/* Context to describe whole processor state.  */
++typedef struct sigcontext mcontext_t;
++
++/* Userlevel context.  */
++typedef struct ucontext
++{
++      unsigned long   uc_flags;
++      struct ucontext *uc_link;
++      stack_t         uc_stack;
++      mcontext_t      uc_mcontext;
++      sigset_t        uc_sigmask;   /* mask last for extensibility */
++} ucontext_t;
++
++#endif /* sys/ucontext.h */
+diff --git a/libc/sysdeps/linux/avr32/sys/user.h b/libc/sysdeps/linux/avr32/sys/user.h
+new file mode 100644
+index 0000000..c0b3d38
+--- /dev/null
++++ b/libc/sysdeps/linux/avr32/sys/user.h
+@@ -0,0 +1,46 @@
++#ifndef _SYS_USER_H
++#define _SYS_USER_H
++
++struct user_fpregs
++{
++
++};
++
++struct user_regs
++{
++      unsigned long sr;
++      unsigned long pc;
++      unsigned long lr;
++      unsigned long sp;
++      unsigned long r12;
++      unsigned long r11;
++      unsigned long r10;
++      unsigned long r9;
++      unsigned long r8;
++      unsigned long r7;
++      unsigned long r6;
++      unsigned long r5;
++      unsigned long r4;
++      unsigned long r3;
++      unsigned long r2;
++      unsigned long r1;
++      unsigned long r0;
++      unsigned long r12_orig;
++};
++
++struct user
++{
++      struct user_regs        regs;           /* general registers */
++      size_t                  u_tsize;        /* text size (pages) */
++      size_t                  u_dsize;        /* data size (pages) */
++      size_t                  u_ssize;        /* stack size (pages) */
++      unsigned long           start_code;     /* text starting address */
++      unsigned long           start_data;     /* data starting address */
++      unsigned long           start_stack;    /* stack starting address */
++      long int                signal;         /* signal causing core dump */
++      struct user_regs *      u_ar0;          /* help gdb find registers */
++      unsigned long           magic;          /* identifies a core file */
++      char                    u_comm[32];     /* user command name */
++};
++
++#endif /* _SYS_USER_H */
+diff --git a/libc/sysdeps/linux/avr32/syscall.S b/libc/sysdeps/linux/avr32/syscall.S
+new file mode 100644
+index 0000000..55c1b1f
+--- /dev/null
++++ b/libc/sysdeps/linux/avr32/syscall.S
+@@ -0,0 +1,71 @@
++/*
++ * Copyright (C) 2004-2007 Atmel Corporation
++ *
++ * 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.
++ */
++#include <features.h>
++
++      .text
++
++      /*
++       * long int syscall(long int sysno, ...)
++       */
++      .global syscall
++      .type   syscall, @function
++      .align  2
++syscall:
++      stm     --sp, r3,r5,r6,lr
++      sub     lr, sp, -16
++      mov     r8, r12
++      ldm     lr, r3,r5,r9-r12
++      scall
++      cp.w    r12, -4095
++      brlo    .Ldone
++
++#ifdef __PIC__
++      lddpc   r6, .Lgot
++.Lgotcalc:
++      rsub    r6, pc
++# ifdef __UCLIBC_HAS_THREADS__
++      rsub    r3, r12, 0
++      mcall   r6[__errno_location@got]
++      st.w    r12[0], r3
++# else
++      ld.w    r3, r6[errno@got]
++      neg     r12
++      st.w    r3[0], r12
++# endif
++#else
++# ifdef __UCLIBC_HAS_THREADS__
++      rsub    r3, r12, 0
++      mcall   .Lerrno_location
++      st.w    r12[0], r3
++# else
++      lddpc   r3, .Lerrno
++      neg     r12
++      st.w    r3[0], r12
++# endif
++#endif
++      mov     r12, -1
++
++.Ldone:
++      ldm     sp++, r3,r5,r6,pc
++
++      .align  2
++#ifdef __PIC__
++.Lgot:
++      .long   .Lgotcalc - _GLOBAL_OFFSET_TABLE_
++#else
++# ifdef __UCLIBC_HAS_THREADS__
++.Lerrno_location:
++      .long   __errno_location
++# else
++.Lerrno:
++      .long   errno
++# endif
++#endif
++
++
++      .size   syscall, . - syscall
+diff --git a/libc/sysdeps/linux/avr32/vfork.S b/libc/sysdeps/linux/avr32/vfork.S
+new file mode 100644
+index 0000000..03ca99f
+--- /dev/null
++++ b/libc/sysdeps/linux/avr32/vfork.S
+@@ -0,0 +1,58 @@
++/*
++ * Copyright (C) 2005 Atmel Corporation
++ *
++ * 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.
++ */
++
++/*
++ * Clone the process without copying the address space.  The
++ * calling process is suspended until the child either exits
++ * or calls execve.
++ *
++ * This all means that we cannot rely on the stack to store
++ * away registers, since they will be overwritten by the child
++ * as soon as it makes another function call (e.g. execve()).
++ * Fortunately, the Linux kernel preserves LR across system calls.
++ */
++
++#include <features.h>
++#include <sys/syscall.h>
++
++      .global __vfork
++      .type   __vfork,@function
++      .align  1
++__vfork:
++      mov     r8, __NR_vfork
++      scall
++      cp.w    r12, -4096
++      retls   r12
++
++      /* vfork failed, so we may use the stack freely */
++      pushm   r4-r7,lr
++#ifdef __PIC__
++      lddpc   r6, .L_GOT
++      rsub    r4, r12, 0
++.L_RGOT:
++      rsub    r6, pc
++      mcall   r6[__errno_location@got]
++#else
++      rsub    r4, r12, 0
++      mcall   .L__errno_location
++#endif
++      st.w    r12[0], r4
++      popm    r4-r7,pc,r12=-1
++
++      .align  2
++#ifdef __PIC__
++.L_GOT:
++      .long   .L_RGOT - _GLOBAL_OFFSET_TABLE_
++#else
++.L__errno_location:
++      .long   __errno_location
++#endif
++      .size   __vfork, . - __vfork
++
++weak_alias(__vfork,vfork)
++libc_hidden_weak(vfork)
+diff --git a/libpthread/linuxthreads.old/sysdeps/avr32/pt-machine.h b/libpthread/linuxthreads.old/sysdeps/avr32/pt-machine.h
+new file mode 100644
+index 0000000..eccf329
+--- /dev/null
++++ b/libpthread/linuxthreads.old/sysdeps/avr32/pt-machine.h
+@@ -0,0 +1,73 @@
++/* Machine-dependent pthreads configuration and inline functions.
++ *
++ * Copyright (C) 2005-2007 Atmel Corporation
++ *
++ * 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.
++ */
++#ifndef _PT_MACHINE_H
++#define _PT_MACHINE_H   1
++
++#include <features.h>
++
++static inline int
++_test_and_set (int *p, int v)
++{
++      int result;
++
++      __asm__ __volatile__(
++              "/* Inline test and set */\n"
++              "       xchg    %[old], %[mem], %[new]"
++              : [old] "=&r"(result)
++              : [mem] "r"(p), [new] "r"(v)
++              : "memory");
++
++      return result;
++}
++
++#ifndef PT_EI
++# define PT_EI extern inline
++#endif
++
++extern long int testandset (int *spinlock);
++extern int __compare_and_swap (long int *p, long int oldval, long int newval);
++
++/* Spinlock implementation; required.  */
++PT_EI long int
++testandset (int *spinlock)
++{
++      return _test_and_set(spinlock, 1);
++}
++
++
++/* Get some notion of the current stack.  Need not be exactly the top
++   of the stack, just something somewhere in the current frame.  */
++#define CURRENT_STACK_FRAME  stack_pointer
++register char * stack_pointer __asm__ ("sp");
++
++/* Compare-and-swap for semaphores. */
++
++#define HAS_COMPARE_AND_SWAP
++PT_EI int
++__compare_and_swap(long int *p, long int oldval, long int newval)
++{
++      long int result;
++
++      __asm__ __volatile__(
++              "/* Inline compare and swap */\n"
++              "1:     ssrf    5\n"
++              "       ld.w    %[result], %[mem]\n"
++              "       eor     %[result], %[old]\n"
++              "       brne    2f\n"
++              "       stcond  %[mem], %[new]\n"
++              "       brne    1b\n"
++              "2:"
++              : [result] "=&r"(result), [mem] "=m"(*p)
++              : "m"(*p), [new] "r"(newval), [old] "r"(oldval)
++              : "cc", "memory");
++
++      return result == 0;
++}
++
++#endif /* pt-machine.h */
+diff --git a/libpthread/linuxthreads/sysdeps/avr32/pt-machine.h b/libpthread/linuxthreads/sysdeps/avr32/pt-machine.h
+new file mode 100644
+index 0000000..fe12bf8
+--- /dev/null
++++ b/libpthread/linuxthreads/sysdeps/avr32/pt-machine.h
+@@ -0,0 +1,73 @@
++/* Machine-dependent pthreads configuration and inline functions.
++ *
++ * Copyright (C) 2005-2007 Atmel Corporation
++ *
++ * 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.
++ */
++#ifndef _PT_MACHINE_H
++#define _PT_MACHINE_H   1
++
++#include <features.h>
++
++static inline int
++_test_and_set (int *p, int v) __THROW
++{
++      int result;
++
++      __asm__ __volatile__(
++              "/* Inline test and set */\n"
++              "       xchg    %[old], %[mem], %[new]"
++              : [old] "=&r"(result)
++              : [mem] "r"(p), [new] "r"(v)
++              : "memory");
++
++      return result;
++}
++
++#ifndef PT_EI
++# define PT_EI extern inline
++#endif
++
++extern long int testandset (int *spinlock);
++extern int __compare_and_swap (long int *p, long int oldval, long int newval);
++
++/* Spinlock implementation; required.  */
++PT_EI long int
++testandset (int *spinlock)
++{
++      return _test_and_set(spinlock, 1);
++}
++
++
++/* Get some notion of the current stack.  Need not be exactly the top
++   of the stack, just something somewhere in the current frame.  */
++#define CURRENT_STACK_FRAME  stack_pointer
++register char * stack_pointer __asm__ ("sp");
++
++/* Compare-and-swap for semaphores. */
++
++#define HAS_COMPARE_AND_SWAP
++PT_EI int
++__compare_and_swap(long int *p, long int oldval, long int newval)
++{
++      int result;
++
++      __asm__ __volatile__(
++              "/* Inline compare and swap */\n"
++              "1:     ssrf    5\n"
++              "       ld.w    %[result], %[mem]\n"
++              "       eor     %[result], %[old]\n"
++              "       brne    2f\n"
++              "       stcond  %[mem], %[new]\n"
++              "       brne    1b\n"
++              "2:"
++              : [result] "=&r"(result), [mem] "=m"(*p)
++              : "m"(*p), [new] "r"(newval), [old] "r"(oldval)
++              : "cc", "memory");
++
++      return result == 0;
++}
++
++#endif /* pt-machine.h */
+diff --git a/utils/ldd.c b/utils/ldd.c
+index 75ad628..e34acd9 100644
+--- a/utils/ldd.c
++++ b/utils/ldd.c
+@@ -44,6 +44,11 @@
+ #define ELFCLASSM     ELFCLASS32
+ #endif
++#if defined(__avr32__)
++#define MATCH_MACHINE(x) (x == EM_AVR32)
++#define ELFCLASSM     ELFCLASS32
++#endif
++
+ #if defined(__s390__)
+ #define MATCH_MACHINE(x) (x == EM_S390)
+ #define ELFCLASSM     ELFCLASS32
diff --git a/toolchain/uClibc/uClibc-0.9.29-avr32-fix-sa_onstack.patch b/toolchain/uClibc/uClibc-0.9.29-avr32-fix-sa_onstack.patch
new file mode 100644 (file)
index 0000000..722decd
--- /dev/null
@@ -0,0 +1,31 @@
+From 974a769cc135bcfb1ea751db34a84ed6b5ceb509 Mon Sep 17 00:00:00 2001
+From: Haavard Skinnemoen <hskinnemoen@atmel.com>
+Date: Fri, 7 Dec 2007 14:02:19 +0100
+Subject: [PATCH] AVR32: Fix sa_restorer when SA_ONSTACK is set
+
+I don't remember exactly why we decided to pick the caller's value of
+sa_restorer when SA_ONSTACK is set, but it seems to break LTP's
+sigaltstack testcase. Some users have reported problems with
+sigaltstack as well; hopefully this will fix it.
+
+Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
+---
+ libc/sysdeps/linux/avr32/sigaction.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/libc/sysdeps/linux/avr32/sigaction.c b/libc/sysdeps/linux/avr32/sigaction.c
+index a97ff3d..6dcca91 100644
+--- a/libc/sysdeps/linux/avr32/sigaction.c
++++ b/libc/sysdeps/linux/avr32/sigaction.c
+@@ -30,7 +30,7 @@ int __libc_sigaction(int signum, const struct sigaction *act,
+               kact.k_sa_handler = act->sa_handler;
+               memcpy(&kact.sa_mask, &act->sa_mask, sizeof (kact.sa_mask));
+               kact.sa_flags = act->sa_flags;
+-              if (kact.sa_flags & (SA_RESTORER | SA_ONSTACK))
++              if (kact.sa_flags & SA_RESTORER)
+                       kact.sa_restorer = act->sa_restorer;
+               else
+                       kact.sa_restorer = __default_rt_sa_restorer;
+-- 
+1.5.3.4
+
diff --git a/toolchain/uClibc/uClibc-0.9.29-avr32.patch b/toolchain/uClibc/uClibc-0.9.29-avr32.patch
deleted file mode 100644 (file)
index 4c6addf..0000000
+++ /dev/null
@@ -1,3579 +0,0 @@
-diff --git a/.gitignore b/.gitignore
-new file mode 100644
-index 0000000..f474699
---- /dev/null
-+++ b/.gitignore
-@@ -0,0 +1,63 @@
-+#
-+# NOTE! Don't add files that are generated in specific
-+# subdirectories here. Add them in the ".gitignore" file
-+# in that subdirectory instead.
-+#
-+# Normal rules
-+#
-+.*
-+*.o
-+*.a
-+*.so
-+*.os
-+*.oS
-+.config*
-+
-+#
-+# Top-level generic files
-+#
-+obj.*
-+
-+#
-+# Generated files
-+#
-+extra/config/conf
-+extra/config/lex.zconf.c
-+extra/config/lkc_defs.h
-+extra/config/mconf
-+extra/config/zconf.hash.c
-+extra/config/zconf.tab.c
-+extra/config/zconf.tab.h
-+
-+lib
-+
-+include/asm
-+include/asm-*
-+include/bits
-+include/linux
-+
-+include/sys/acct.h
-+include/sys/elf.h
-+include/sys/epoll.h
-+include/sys/inotify.h
-+include/sys/io.h
-+include/sys/prctl.h
-+include/sys/procfs.h
-+include/sys/ptrace.h
-+include/sys/ucontext.h
-+include/sys/user.h
-+
-+include/dl-osinfo.h
-+include/fpu_control.h
-+include/hp-timing.h
-+include/pthread.h
-+include/semaphore.h
-+include/thread_db.h
-+
-+ldso/include/dl-debug.h
-+ldso/include/dl-startup.h
-+ldso/include/dl-syscalls.h
-+ldso/include/dl-sysdep.h
-+ldso/include/elf.h
-+
-+libc/misc/internals/interp.c
-diff --git a/Rules.mak b/Rules.mak
-index d054bbb..55381cf 100644
---- a/Rules.mak
-+++ b/Rules.mak
-@@ -313,6 +313,12 @@ ifeq ($(TARGET_ARCH),frv)
-       UCLIBC_LDSO=ld.so.1
- endif
-+ifeq ($(strip $(TARGET_ARCH)),avr32)
-+      CPU_CFLAGS-$(CONFIG_AVR32_AP7)  += -march=ap
-+      CPU_CFLAGS-$(CONFIG_LINKRELAX)  += -mrelax
-+      CPU_LDFLAGS-$(CONFIG_LINKRELAX) += --relax
-+endif
-+
- # Keep the check_gcc from being needlessly executed
- ifndef PIEFLAG
- ifneq ($(UCLIBC_BUILD_PIE),y)
-diff --git a/extra/Configs/Config.avr32 b/extra/Configs/Config.avr32
-new file mode 100644
-index 0000000..8d70e6e
---- /dev/null
-+++ b/extra/Configs/Config.avr32
-@@ -0,0 +1,31 @@
-+#
-+# For a description of the syntax of this configuration file,
-+# see extra/config/Kconfig-language.txt
-+#
-+
-+config TARGET_ARCH
-+      string
-+      default "avr32"
-+
-+config FORCE_OPTIONS_FOR_ARCH
-+      bool
-+      default y
-+      select ARCH_BIG_ENDIAN
-+      select FORCE_SHAREABLE_TEXT_SEGMENTS
-+
-+config ARCH_CFLAGS
-+      string
-+
-+choice
-+      prompt "Target CPU Type"
-+      default CONFIG_AVR32_AP7
-+
-+config CONFIG_AVR32_AP7
-+      bool "AVR32 AP7"
-+      select ARCH_HAS_MMU
-+
-+endchoice
-+
-+config LINKRELAX
-+      bool "Enable linker optimizations"
-+      default y
-diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in
-index 8eab394..10c9f7b 100644
---- a/extra/Configs/Config.in
-+++ b/extra/Configs/Config.in
-@@ -16,6 +16,9 @@ config TARGET_alpha
- config TARGET_arm
-       bool "arm"
-+config TARGET_avr32
-+      bool "avr32"
-+
- config TARGET_bfin
-       bool "bfin"
-@@ -92,6 +95,10 @@ if TARGET_arm
- source "extra/Configs/Config.arm"
- endif
-+if TARGET_avr32
-+source "extra/Configs/Config.avr32"
-+endif
-+
- if TARGET_bfin
- source "extra/Configs/Config.bfin"
- endif
-diff --git a/extra/Configs/defconfigs/avr32 b/extra/Configs/defconfigs/avr32
-new file mode 100644
-index 0000000..0b890a2
---- /dev/null
-+++ b/extra/Configs/defconfigs/avr32
-@@ -0,0 +1 @@
-+TARGET_avr32=y
-diff --git a/include/elf.h b/include/elf.h
-index 19805d7..ab90160 100644
---- a/include/elf.h
-+++ b/include/elf.h
-@@ -354,6 +354,8 @@ typedef struct
- /* NIOS magic number - no EABI available.  */
- #define EM_NIOS32     0xFEBB
-+#define EM_AVR32      0x18ad
-+
- /* V850 backend magic number.  Written in the absense of an ABI.  */
- #define EM_CYGNUS_V850 0x9080
-@@ -2828,6 +2830,55 @@ typedef Elf32_Addr Elf32_Conflict;
- /* Keep this the last entry.  */
- #define R_V850_NUM            25
-+/* Atmel AVR32 relocations.  */
-+#define R_AVR32_NONE          0
-+#define R_AVR32_32            1
-+#define R_AVR32_16            2
-+#define R_AVR32_8             3
-+#define R_AVR32_32_PCREL      4
-+#define R_AVR32_16_PCREL      5
-+#define R_AVR32_8_PCREL               6
-+#define R_AVR32_DIFF32                7
-+#define R_AVR32_DIFF16                8
-+#define R_AVR32_DIFF8         9
-+#define R_AVR32_GOT32         10
-+#define R_AVR32_GOT16         11
-+#define R_AVR32_GOT8          12
-+#define R_AVR32_21S           13
-+#define R_AVR32_16U           14
-+#define R_AVR32_16S           15
-+#define R_AVR32_8S            16
-+#define R_AVR32_8S_EXT                17
-+#define R_AVR32_22H_PCREL     18
-+#define R_AVR32_18W_PCREL     19
-+#define R_AVR32_16B_PCREL     20
-+#define R_AVR32_16N_PCREL     21
-+#define R_AVR32_14UW_PCREL    22
-+#define R_AVR32_11H_PCREL     23
-+#define R_AVR32_10UW_PCREL    24
-+#define R_AVR32_9H_PCREL      25
-+#define R_AVR32_9UW_PCREL     26
-+#define R_AVR32_HI16          27
-+#define R_AVR32_LO16          28
-+#define R_AVR32_GOTPC         29
-+#define R_AVR32_GOTCALL               30
-+#define R_AVR32_LDA_GOT               31
-+#define R_AVR32_GOT21S                32
-+#define R_AVR32_GOT18SW               33
-+#define R_AVR32_GOT16S                34
-+#define R_AVR32_GOT7UW                35
-+#define R_AVR32_32_CPENT      36
-+#define R_AVR32_CPCALL                37
-+#define R_AVR32_16_CP         38
-+#define R_AVR32_9W_CP         39
-+#define R_AVR32_RELATIVE      40
-+#define R_AVR32_GLOB_DAT      41
-+#define R_AVR32_JMP_SLOT      42
-+#define R_AVR32_ALIGN         43
-+#define R_AVR32_NUM           44
-+
-+/* AVR32 dynamic tags */
-+#define DT_AVR32_GOTSZ                0x70000001 /* Total size of GOT in bytes */
- /* Renesas H8/300 Relocations */
- #define R_H8_NONE       0
-diff --git a/ldso/include/dl-string.h b/ldso/include/dl-string.h
-index 32c5bf8..eb43bd9 100644
---- a/ldso/include/dl-string.h
-+++ b/ldso/include/dl-string.h
-@@ -285,7 +285,8 @@ static __always_inline char * _dl_simple_ltoahex(char * local, unsigned long i)
- /* On some arches constant strings are referenced through the GOT.
-  * This requires that load_addr must already be defined... */
- #if defined(mc68000)  || defined(__arm__) || defined(__thumb__) || \
--    defined(__mips__) || defined(__sh__)  || defined(__powerpc__)
-+    defined(__mips__) || defined(__sh__)  || defined(__powerpc__) || \
-+      defined(__avr32__)
- # define CONSTANT_STRING_GOT_FIXUP(X) \
-       if ((X) < (const char *) load_addr) (X) += load_addr
- # define NO_EARLY_SEND_STDERR
-diff --git a/ldso/include/dl-syscall.h b/ldso/include/dl-syscall.h
-index b42416a..4404219 100644
---- a/ldso/include/dl-syscall.h
-+++ b/ldso/include/dl-syscall.h
-@@ -55,69 +55,69 @@
-    dynamic linking at all, so we cannot return any error codes.
-    We just punt if there is an error. */
- #define __NR__dl_exit __NR_exit
--static inline _syscall1(void, _dl_exit, int, status);
-+static __always_inline _syscall1(void, _dl_exit, int, status);
- #define __NR__dl_close __NR_close
--static inline _syscall1(int, _dl_close, int, fd);
-+static __always_inline _syscall1(int, _dl_close, int, fd);
- #define __NR__dl_open __NR_open
--static inline _syscall3(int, _dl_open, const char *, fn, int, flags,
-+static __always_inline _syscall3(int, _dl_open, const char *, fn, int, flags,
-                         __kernel_mode_t, mode);
- #define __NR__dl_write __NR_write
--static inline _syscall3(unsigned long, _dl_write, int, fd,
-+static __always_inline _syscall3(unsigned long, _dl_write, int, fd,
-                         const void *, buf, unsigned long, count);
- #define __NR__dl_read __NR_read
--static inline _syscall3(unsigned long, _dl_read, int, fd,
-+static __always_inline _syscall3(unsigned long, _dl_read, int, fd,
-                         const void *, buf, unsigned long, count);
- #define __NR__dl_mprotect __NR_mprotect
--static inline _syscall3(int, _dl_mprotect, const void *, addr,
-+static __always_inline _syscall3(int, _dl_mprotect, const void *, addr,
-                         unsigned long, len, int, prot);
- #define __NR__dl_stat __NR_stat
--static inline _syscall2(int, _dl_stat, const char *, file_name,
-+static __always_inline _syscall2(int, _dl_stat, const char *, file_name,
-                         struct stat *, buf);
- #define __NR__dl_fstat __NR_fstat
--static inline _syscall2(int, _dl_fstat, int, fd, struct stat *, buf);
-+static __always_inline _syscall2(int, _dl_fstat, int, fd, struct stat *, buf);
- #define __NR__dl_munmap __NR_munmap
--static inline _syscall2(int, _dl_munmap, void *, start, unsigned long, length);
-+static __always_inline _syscall2(int, _dl_munmap, void *, start, unsigned long, length);
- #ifdef __NR_getxuid
- # define __NR_getuid __NR_getxuid
- #endif
- #define __NR__dl_getuid __NR_getuid
--static inline _syscall0(uid_t, _dl_getuid);
-+static __always_inline _syscall0(uid_t, _dl_getuid);
- #ifndef __NR_geteuid
- # define __NR_geteuid __NR_getuid
- #endif
- #define __NR__dl_geteuid __NR_geteuid
--static inline _syscall0(uid_t, _dl_geteuid);
-+static __always_inline _syscall0(uid_t, _dl_geteuid);
- #ifdef __NR_getxgid
- # define __NR_getgid __NR_getxgid
- #endif
- #define __NR__dl_getgid __NR_getgid
--static inline _syscall0(gid_t, _dl_getgid);
-+static __always_inline _syscall0(gid_t, _dl_getgid);
- #ifndef __NR_getegid
- # define __NR_getegid __NR_getgid
- #endif
- #define __NR__dl_getegid __NR_getegid
--static inline _syscall0(gid_t, _dl_getegid);
-+static __always_inline _syscall0(gid_t, _dl_getegid);
- #ifdef __NR_getxpid
- # define __NR_getpid __NR_getxpid
- #endif
- #define __NR__dl_getpid __NR_getpid
--static inline _syscall0(gid_t, _dl_getpid);
-+static __always_inline _syscall0(gid_t, _dl_getpid);
- #define __NR__dl_readlink __NR_readlink
--static inline _syscall3(int, _dl_readlink, const char *, path, char *, buf,
-+static __always_inline _syscall3(int, _dl_readlink, const char *, path, char *, buf,
-                         size_t, bufsiz);
- #ifdef __UCLIBC_HAS_SSP__
-@@ -146,14 +146,14 @@ static inline _syscall2(int, _dl_gettimeofday, struct timeval *, tv,
- #if defined(__UCLIBC_MMAP_HAS_6_ARGS__) && defined(__NR_mmap)
- # define __NR__dl_mmap __NR_mmap
--static inline _syscall6(void *, _dl_mmap, void *, start, size_t, length,
-+static __always_inline _syscall6(void *, _dl_mmap, void *, start, size_t, length,
-                         int, prot, int, flags, int, fd, off_t, offset);
- /* then try mmap2() */
- #elif defined(__NR_mmap2)
- # define __NR___syscall_mmap2       __NR_mmap2
--static inline _syscall6(__ptr_t, __syscall_mmap2, __ptr_t, addr, size_t, len,
-+static __always_inline _syscall6(__ptr_t, __syscall_mmap2, __ptr_t, addr, size_t, len,
-                         int, prot, int, flags, int, fd, off_t, offset);
- /* Some architectures always use 12 as page shift for mmap2() eventhough the
-@@ -164,7 +164,7 @@ static inline _syscall6(__ptr_t, __syscall_mmap2, __ptr_t, addr, size_t, len,
- # define MMAP2_PAGE_SHIFT 12
- #endif
--static inline void * _dl_mmap(void * addr, unsigned long size, int prot,
-+static __always_inline void * _dl_mmap(void * addr, unsigned long size, int prot,
-                               int flags, int fd, unsigned long offset)
- {
-       if (offset & ((1 << MMAP2_PAGE_SHIFT) - 1))
-@@ -177,8 +177,8 @@ static inline void * _dl_mmap(void * addr, unsigned long size, int prot,
- #elif defined(__NR_mmap)
- # define __NR__dl_mmap_real __NR_mmap
--static inline _syscall1(void *, _dl_mmap_real, unsigned long *, buffer);
--static inline void * _dl_mmap(void * addr, unsigned long size, int prot,
-+static __always_inline _syscall1(void *, _dl_mmap_real, unsigned long *, buffer);
-+static __always_inline void * _dl_mmap(void * addr, unsigned long size, int prot,
-                               int flags, int fd, unsigned long offset)
- {
-       unsigned long buffer[6];
-diff --git a/ldso/ldso/avr32/dl-debug.h b/ldso/ldso/avr32/dl-debug.h
-new file mode 100644
-index 0000000..fe35539
---- /dev/null
-+++ b/ldso/ldso/avr32/dl-debug.h
-@@ -0,0 +1,45 @@
-+/*
-+ * AVR32 ELF shared libary loader support
-+ *
-+ * Copyright (C) 2005-2007 Atmel Corporation
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice, this list of conditions and the following disclaimer.
-+ * 2. The name of the above contributors may not be
-+ *    used to endorse or promote products derived from this software
-+ *    without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ */
-+
-+static const char *_dl_reltypes_tab[] = {
-+    "R_AVR32_NONE",
-+    "R_AVR32_32", "R_AVR32_16", "R_AVR32_8",
-+    "R_AVR32_32_PCREL", "R_AVR32_16_PCREL", "R_AVR32_8_PCREL",
-+    "R_AVR32_DIFF32", "R_AVR32_DIFF16", "R_AVR32_DIFF8",
-+    "R_AVR32_GOT32", "R_AVR32_GOT16", "R_AVR32_GOT8",
-+    "R_AVR32_21S", "R_AVR32_16U", "R_AVR32_16S", "R_AVR32_8S", "R_AVR32_8S_EXT",
-+    "R_AVR32_22H_PCREL", "R_AVR32_18W_PCREL", "R_AVR32_16B_PCREL",
-+    "R_AVR32_16N_PCREL", "R_AVR32_14UW_PCREL", "R_AVR32_11H_PCREL",
-+    "R_AVR32_10UW_PCREL", "R_AVR32_9H_PCREL", "R_AVR32_9UW_PCREL",
-+    "R_AVR32_HI16", "R_AVR32_LO16",
-+    "R_AVR32_GOTPC", "R_AVR32_GOTCALL", "R_AVR32_LDA_GOT",
-+    "R_AVR32_GOT21S", "R_AVR32_GOT18SW", "R_AVR32_GOT16S", "R_AVR32_GOT7UW",
-+    "R_AVR32_32_CPENT", "R_AVR32_CPCALL", "R_AVR32_16_CP", "R_AVR32_9W_CP",
-+    "R_AVR32_RELATIVE", "R_AVR32_GLOB_DAT", "R_AVR32_JMP_SLOT",
-+    "R_AVR32_ALIGN",
-+};
-diff --git a/ldso/ldso/avr32/dl-startup.h b/ldso/ldso/avr32/dl-startup.h
-new file mode 100644
-index 0000000..3b9a641
---- /dev/null
-+++ b/ldso/ldso/avr32/dl-startup.h
-@@ -0,0 +1,112 @@
-+/*
-+ * Architecture specific code used by dl-startup.c
-+ *
-+ * Copyright (C) 2005-2007 Atmel Corporation
-+ *
-+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
-+ */
-+
-+/* This is the library loader's main entry point. Let _dl_boot2 do its
-+ * initializations and jump to the application's entry point
-+ * afterwards. */
-+asm(  "       .text\n"
-+      "       .global _start\n"
-+      "       .type   _start,@function\n"
-+      "_start:\n"
-+      /* All arguments are on the stack initially */
-+      "       mov     r12, sp\n"
-+      "       rcall   _dl_start\n"
-+      /* Returns user entry point in r12. Save it. */
-+      "       mov     r0, r12\n"
-+      /* We're PIC, so get the Global Offset Table */
-+      "       lddpc   r6, .L_GOT\n"
-+      ".L_RGOT:\n"
-+      "       rsub    r6, pc\n"
-+      /* Adjust argc and argv according to _dl_skip_args */
-+      "       ld.w    r1, r6[_dl_skip_args@got]\n"
-+      "       ld.w    r1, r1[0]\n"
-+      "       ld.w    r2, sp++\n"
-+      "       sub     r2, r1\n"
-+      "       add     sp, sp, r1 << 2\n"
-+      "       st.w    --sp, r2\n"
-+      /* Load the finalizer function */
-+      "       ld.w    r12, r6[_dl_fini@got]\n"
-+      /* Jump to the user's entry point */
-+      "       mov     pc, r0\n\n"
-+
-+      "       .align  2\n"
-+      ".L_GOT:"
-+      "       .long   .L_RGOT - _GLOBAL_OFFSET_TABLE_\n"
-+      "       .size   _start, . - _start\n"
-+      "       .previous\n");
-+
-+/* Get a pointer to the argv array.  On many platforms this can be just
-+ * the address if the first argument, on other platforms we need to
-+ * do something a little more subtle here. */
-+#define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned long *)ARGS + 1)
-+
-+
-+/* We can't call functions before the GOT has been initialized */
-+#define NO_FUNCS_BEFORE_BOOTSTRAP
-+
-+/*
-+ * Relocate the GOT during dynamic loader bootstrap.  This will add
-+ * the load address to all entries in the GOT, which is necessary
-+ * because the linker doesn't generate R_AVR32_RELATIVE relocs for the
-+ * GOT.
-+ */
-+static __always_inline
-+void PERFORM_BOOTSTRAP_GOT(struct elf_resolve *tpnt)
-+{
-+      Elf32_Addr i, nr_got;
-+      register Elf32_Addr *__r6 __asm__("r6");
-+      Elf32_Addr *got = __r6;
-+
-+      nr_got = tpnt->dynamic_info[DT_AVR32_GOTSZ_IDX] / sizeof(*got);
-+      for (i = 2; i < nr_got; i++)
-+              got[i] += tpnt->loadaddr;
-+}
-+
-+#define PERFORM_BOOTSTRAP_GOT(tpnt) PERFORM_BOOTSTRAP_GOT(tpnt)
-+
-+/* Handle relocation of the symbols in the dynamic loader. */
-+static __always_inline
-+void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, unsigned long *reloc_addr,
-+                           unsigned long symbol_addr,
-+                           unsigned long load_addr, Elf32_Sym *symtab)
-+{
-+      switch(ELF32_R_TYPE(rpnt->r_info)) {
-+      case R_AVR32_NONE:
-+              break;
-+      case R_AVR32_GLOB_DAT:
-+      case R_AVR32_JMP_SLOT:
-+              *reloc_addr = symbol_addr;
-+              break;
-+      case R_AVR32_RELATIVE:
-+              SEND_STDERR_DEBUG("Applying RELATIVE relocation: ");
-+              SEND_ADDRESS_STDERR_DEBUG(load_addr, 0);
-+              SEND_STDERR_DEBUG(" + ");
-+              SEND_ADDRESS_STDERR_DEBUG(rpnt->r_addend, 1);
-+              *reloc_addr = load_addr + rpnt->r_addend;
-+              break;
-+      default:
-+              SEND_STDERR("BOOTSTRAP_RELOC: unhandled reloc_type ");
-+              SEND_NUMBER_STDERR(ELF32_R_TYPE(rpnt->r_info), 1);
-+              SEND_STDERR("REL, SYMBOL, LOAD: ");
-+              SEND_ADDRESS_STDERR(reloc_addr, 0);
-+              SEND_STDERR(", ");
-+              SEND_ADDRESS_STDERR(symbol_addr, 0);
-+              SEND_STDERR(", ");
-+              SEND_ADDRESS_STDERR(load_addr, 1);
-+              _dl_exit(1);
-+      }
-+}
-+
-+/* Transfer control to the user's application, once the dynamic loader
-+ * is done. This routine has to exit the current function, then call
-+ * the _dl_elf_main function.
-+ *
-+ * Since our _dl_boot will simply call whatever is returned by
-+ * _dl_boot2, we can just return the address we're supposed to
-+ * call.  */
-+#define START()       return _dl_elf_main;
-diff --git a/ldso/ldso/avr32/dl-syscalls.h b/ldso/ldso/avr32/dl-syscalls.h
-new file mode 100644
-index 0000000..996bb87
---- /dev/null
-+++ b/ldso/ldso/avr32/dl-syscalls.h
-@@ -0,0 +1,6 @@
-+/* We can't use the real errno in ldso, since it has not yet
-+ * been dynamicly linked in yet. */
-+#include "sys/syscall.h"
-+extern int _dl_errno;
-+#undef __set_errno
-+#define __set_errno(X) {(_dl_errno) = (X);}
-diff --git a/ldso/ldso/avr32/dl-sysdep.h b/ldso/ldso/avr32/dl-sysdep.h
-new file mode 100644
-index 0000000..1a30172
---- /dev/null
-+++ b/ldso/ldso/avr32/dl-sysdep.h
-@@ -0,0 +1,105 @@
-+/*
-+ * Various assembly language/system dependent hacks that are required
-+ * so that we can minimize the amount of platform specific code.
-+ *
-+ * Copyright (C) 2004-2007 Atmel Corporation
-+ *
-+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
-+ */
-+
-+/* Define this if the system uses RELOCA. */
-+#define ELF_USES_RELOCA
-+
-+#include <elf.h>
-+
-+#define ARCH_NUM 1
-+#define DT_AVR32_GOTSZ_IDX    (DT_NUM + OS_NUM)
-+
-+#define ARCH_DYNAMIC_INFO(dpnt, dynamic, debug_addr)                  \
-+      do {                                                            \
-+              if (dpnt->d_tag == DT_AVR32_GOTSZ)                      \
-+                      dynamic[DT_AVR32_GOTSZ_IDX] = dpnt->d_un.d_val; \
-+      } while (0)
-+
-+/* Initialization sequence for the application/library GOT. */
-+#define INIT_GOT(GOT_BASE,MODULE)                                     \
-+      do {                                                            \
-+              unsigned long i, nr_got;                                \
-+                                                                      \
-+              GOT_BASE[0] = (unsigned long) _dl_linux_resolve;        \
-+              GOT_BASE[1] = (unsigned long) MODULE;                   \
-+                                                                      \
-+              /* Add load address displacement to all GOT entries */  \
-+              nr_got = MODULE->dynamic_info[DT_AVR32_GOTSZ_IDX] / 4;  \
-+              for (i = 2; i < nr_got; i++)                            \
-+                      GOT_BASE[i] += (unsigned long)MODULE->loadaddr; \
-+      } while (0)
-+
-+#define do_rem(result, n, base)       ((result) = (n) % (base))
-+
-+/* Here we define the magic numbers that this dynamic loader should accept */
-+#define MAGIC1 EM_AVR32
-+#undef MAGIC2
-+
-+/* Used for error messages */
-+#define ELF_TARGET "AVR32"
-+
-+unsigned long _dl_linux_resolver(unsigned long got_offset, unsigned long *got);
-+
-+/* 4096 bytes alignment */
-+#define PAGE_ALIGN 0xfffff000
-+#define ADDR_ALIGN 0xfff
-+#define OFFS_ALIGN 0x7ffff000
-+
-+#define elf_machine_type_class(type)                          \
-+      ((type == R_AVR32_JMP_SLOT) * ELF_RTYPE_CLASS_PLT)
-+
-+/* AVR32 doesn't need any COPY relocs */
-+#define DL_NO_COPY_RELOCS
-+
-+/* Return the link-time address of _DYNAMIC.  Conveniently, this is the
-+   first element of the GOT.  This must be inlined in a function which
-+   uses global data.  */
-+static inline Elf32_Addr
-+elf_machine_dynamic (void)
-+{
-+      register Elf32_Addr *got asm ("r6");
-+      return *got;
-+}
-+
-+/* Return the run-time load address of the shared object.  */
-+static inline Elf32_Addr
-+elf_machine_load_address (void)
-+{
-+      extern void __dl_start asm("_dl_start");
-+      Elf32_Addr got_addr = (Elf32_Addr) &__dl_start;
-+      Elf32_Addr pcrel_addr;
-+
-+      asm   ("        lddpc   %0, 2f\n"
-+             "1:      add     %0, pc\n"
-+             "        rjmp    3f\n"
-+             "        .align  2\n"
-+             "2:      .long   _dl_start - 1b\n"
-+             "3:\n"
-+             : "=r"(pcrel_addr) : : "cc");
-+
-+      return pcrel_addr - got_addr;
-+}
-+
-+/*
-+ * Perform any RELATIVE relocations specified by DT_RELCOUNT.
-+ * Currently, we don't use that tag, but we might in the future as
-+ * this would reduce the startup time somewhat (although probably not by much).
-+ */
-+static inline void
-+elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr,
-+                    Elf32_Word relative_count)
-+{
-+      Elf32_Rela *rpnt = (void *)rel_addr;
-+
-+      do {
-+              Elf32_Addr *reloc_addr;
-+              reloc_addr = (void *)(load_off + (rpnt++)->r_offset);
-+              *reloc_addr = load_off + rpnt->r_addend;
-+      } while (--relative_count);
-+}
-diff --git a/ldso/ldso/avr32/elfinterp.c b/ldso/ldso/avr32/elfinterp.c
-new file mode 100644
-index 0000000..196292b
---- /dev/null
-+++ b/ldso/ldso/avr32/elfinterp.c
-@@ -0,0 +1,191 @@
-+/*
-+ * AVR32 ELF shared library loader suppport
-+ *
-+ * Copyright (C) 2004-2006 Atmel Corporation
-+ *
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice, this list of conditions and the following disclaimer.
-+ * 2. The name of the above contributors may not be
-+ *    used to endorse or promote products derived from this software
-+ *    without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ */
-+
-+unsigned long _dl_linux_resolver(unsigned long got_offset, unsigned long *got)
-+{
-+      struct elf_resolve *tpnt = (struct elf_resolve *)got[1];
-+      Elf32_Sym *sym;
-+      unsigned long local_gotno;
-+      unsigned long gotsym;
-+      unsigned long new_addr;
-+      char *strtab, *symname;
-+      unsigned long *entry;
-+      unsigned long sym_index = got_offset / 4;
-+
-+#if 0
-+      local_gotno = tpnt->dynamic_info[DT_AVR32_LOCAL_GOTNO];
-+      gotsym = tpnt->dynamic_info[DT_AVR32_GOTSYM];
-+
-+      sym = ((Elf32_Sym *)(tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr))
-+              + sym_index;
-+      strtab = (char *)(tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
-+      symname = strtab + sym->st_name;
-+
-+#if 0
-+      new_addr = (unsigned long) _dl_find_hash(strtab + sym->st_name,
-+                                               tpnt->symbol_scope, tpnt,
-+                                               resolver);
-+#endif
-+
-+      entry = (unsigned long *)(got + local_gotno + sym_index - gotsym);
-+      *entry = new_addr;
-+#endif
-+
-+      return new_addr;
-+}
-+
-+static int
-+_dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope,
-+        unsigned long rel_addr, unsigned long rel_size,
-+        int (*reloc_func)(struct elf_resolve *tpnt, struct dyn_elf *scope,
-+                          Elf32_Rela *rpnt, Elf32_Sym *symtab, char *strtab))
-+{
-+      Elf32_Sym *symtab;
-+      Elf32_Rela *rpnt;
-+      char *strtab;
-+      int i;
-+
-+      rpnt = (Elf32_Rela *)rel_addr;
-+      rel_size /= sizeof(Elf32_Rela);
-+      symtab = (Elf32_Sym *)tpnt->dynamic_info[DT_SYMTAB];
-+      strtab = (char *)tpnt->dynamic_info[DT_STRTAB];
-+
-+      for (i = 0; i < rel_size; i++, rpnt++) {
-+              int symtab_index, res;
-+
-+              symtab_index = ELF32_R_SYM(rpnt->r_info);
-+
-+              debug_sym(symtab, strtab, symtab_index);
-+              debug_reloc(symtab, strtab, rpnt);
-+
-+              res = reloc_func(tpnt, scope, rpnt, symtab, strtab);
-+
-+              if (res == 0)
-+                      continue;
-+
-+              _dl_dprintf(2, "\n%s: ", _dl_progname);
-+
-+              if (symtab_index)
-+                      _dl_dprintf(2, "symbol '%s': ",
-+                                  strtab + symtab[symtab_index].st_name);
-+
-+              if (res < 0) {
-+                      int reloc_type = ELF32_R_TYPE(rpnt->r_info);
-+#if defined(__SUPPORT_LD_DEBUG__)
-+                      _dl_dprintf(2, "can't handle reloc type %s\n",
-+                                  _dl_reltypes(reloc_type));
-+#else
-+                      _dl_dprintf(2, "can't handle reloc type %x\n",
-+                                  reloc_type);
-+#endif
-+                      _dl_exit(-res);
-+              } else {
-+                      _dl_dprintf(2, "can't resolve symbol\n");
-+                      return res;
-+              }
-+      }
-+
-+      return 0;
-+}
-+
-+static int _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
-+                      Elf32_Rela *rpnt, Elf32_Sym *symtab, char *strtab)
-+{
-+      int reloc_type;
-+      int symtab_index;
-+      char *symname;
-+      unsigned long *reloc_addr;
-+      unsigned long symbol_addr;
-+#if defined(__SUPPORT_LD_DEBUG__)
-+      unsigned long old_val;
-+#endif
-+
-+      reloc_addr = (unsigned long *)(tpnt->loadaddr + rpnt->r_offset);
-+      reloc_type = ELF32_R_TYPE(rpnt->r_info);
-+      symtab_index = ELF32_R_SYM(rpnt->r_info);
-+      symbol_addr = 0;
-+      symname = strtab + symtab[symtab_index].st_name;
-+
-+      if (symtab_index) {
-+              symbol_addr = (unsigned long)
-+                      _dl_find_hash(strtab + symtab[symtab_index].st_name,
-+                                    tpnt->symbol_scope, tpnt,
-+                                    elf_machine_type_class(reloc_type));
-+
-+              /* Allow undefined references to weak symbols */
-+              if (!symbol_addr &&
-+                  ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK) {
-+                      _dl_dprintf(2, "%s: can't resolve symbol '%s'\n",
-+                                  _dl_progname, symname);
-+                      return 0;
-+              }
-+      }
-+
-+#if defined(__SUPPORT_LD_DEBUG__)
-+      old_val = *reloc_addr;
-+#endif
-+      switch (reloc_type) {
-+      case R_AVR32_NONE:
-+              break;
-+      case R_AVR32_GLOB_DAT:
-+      case R_AVR32_JMP_SLOT:
-+              *reloc_addr = symbol_addr + rpnt->r_addend;
-+              break;
-+      case R_AVR32_RELATIVE:
-+              *reloc_addr = (unsigned long)tpnt->loadaddr
-+                      + rpnt->r_addend;
-+              break;
-+      default:
-+              return -1;
-+      }
-+
-+#if defined(__SUPPORT_LD_DEBUG__)
-+      if (_dl_debug_reloc && _dl_debug_detail)
-+              _dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x\n",
-+                          old_val, *reloc_addr);
-+#endif
-+
-+      return 0;
-+}
-+
-+void _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt,
-+                                         unsigned long rel_addr,
-+                                         unsigned long rel_size)
-+{
-+      /* TODO: Might want to support this in order to get faster
-+       * startup times... */
-+}
-+
-+int _dl_parse_relocation_information(struct dyn_elf *rpnt,
-+                                   unsigned long rel_addr,
-+                                   unsigned long rel_size)
-+{
-+      return _dl_parse(rpnt->dyn, rpnt->dyn->symbol_scope, rel_addr, rel_size,
-+                       _dl_do_reloc);
-+}
-diff --git a/ldso/ldso/avr32/resolve.S b/ldso/ldso/avr32/resolve.S
-new file mode 100644
-index 0000000..e3cb7f4
---- /dev/null
-+++ b/ldso/ldso/avr32/resolve.S
-@@ -0,0 +1,28 @@
-+/*
-+ * Linux dynamic resolving code for AVR32. Fixes up the GOT entry as
-+ * indicated in register r12 and jumps to the resolved address.
-+ *
-+ * 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.
-+ *
-+ * Copyright (C) 2004-2007 Atmel Corporation
-+ */
-+
-+#define ip r5
-+
-+      .text
-+      .global _dl_linux_resolve
-+      .type   _dl_linux_resolve,@function
-+_dl_linux_resolve:
-+      /* The PLT code pushed r8 for us. It contains the address of this
-+         function's GOT entry, that is entry 0. ip contains the address
-+         of the GOT entry of the function we wanted to call. */
-+      stm     --sp, r9-r12, lr
-+      mov     r11, r8
-+      sub     r12, ip, r8
-+      rcall   _dl_linux_resolver
-+      mov     ip, r12
-+      popm    r8-r12,lr
-+      mov     pc, ip
-+      .size   _dl_linux_resolve, . - _dl_linux_resolve
-diff --git a/ldso/ldso/dl-startup.c b/ldso/ldso/dl-startup.c
-index 5cf1d04..d4294ec 100644
---- a/ldso/ldso/dl-startup.c
-+++ b/ldso/ldso/dl-startup.c
-@@ -217,7 +217,9 @@ DL_START(unsigned long args)
-       /* some arches (like MIPS) we have to tweak the GOT before relocations */
-       PERFORM_BOOTSTRAP_GOT(tpnt);
--#else
-+#endif
-+
-+#if !defined(PERFORM_BOOTSTRAP_GOT) || defined(__avr32__)
-       /* OK, now do the relocations.  We do not do a lazy binding here, so
-          that once we are done, we have considerably more flexibility. */
-diff --git a/libc/string/avr32/Makefile b/libc/string/avr32/Makefile
-new file mode 100644
-index 0000000..e19e9d9
---- /dev/null
-+++ b/libc/string/avr32/Makefile
-@@ -0,0 +1,26 @@
-+# Makefile for uClibc
-+#
-+# Copyright (C) 2000-2003 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
-+
-+top_srcdir    := ../../../
-+top_builddir  := ../../../
-+
-+all: objs
-+
-+include $(top_builddir)Rules.mak
-+include ../Makefile.in
-+include $(top_srcdir)Makerules
-diff --git a/libc/string/avr32/bcopy.S b/libc/string/avr32/bcopy.S
-new file mode 100644
-index 0000000..87c1e04
---- /dev/null
-+++ b/libc/string/avr32/bcopy.S
-@@ -0,0 +1,26 @@
-+/*
-+ * Copyright (C) 2004-2007 Atmel Corporation
-+ *
-+ * 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.
-+ */
-+
-+#include <features.h>
-+
-+#ifdef __UCLIBC_SUSV3_LEGACY__
-+
-+      .text
-+      .global bcopy
-+      .type   bcopy, @function
-+      .align  1
-+bcopy:
-+      /* Swap the first two arguments */
-+      eor     r11, r12
-+      eor     r12, r11
-+      eor     r11, r12
-+      rjmp    __GI_memmove
-+
-+      .size   bcopy, . - bcopy
-+
-+#endif /* __UCLIBC_SUSV3_LEGACY__ */
-diff --git a/libc/string/avr32/bzero.S b/libc/string/avr32/bzero.S
-new file mode 100644
-index 0000000..c999e65
---- /dev/null
-+++ b/libc/string/avr32/bzero.S
-@@ -0,0 +1,22 @@
-+/*
-+ * Copyright (C) 2004-2007 Atmel Corporation
-+ *
-+ * 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.
-+ */
-+
-+#ifdef __UCLIBC_SUSV3_LEGACY__
-+
-+      .text
-+      .global bzero
-+      .type   bzero, @function
-+      .align  1
-+bzero:
-+      mov     r10, r11
-+      mov     r11, 0
-+      rjmp    __memset
-+
-+      .size   bzero, . - bzero
-+
-+#endif /* __UCLIBC_SUSV3_LEGACY__ */
-diff --git a/libc/string/avr32/memcmp.S b/libc/string/avr32/memcmp.S
-new file mode 100644
-index 0000000..7359a64
---- /dev/null
-+++ b/libc/string/avr32/memcmp.S
-@@ -0,0 +1,58 @@
-+/*
-+ * Copyright (C) 2004-2007 Atmel Corporation
-+ *
-+ * 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.
-+ */
-+
-+#include <features.h>
-+
-+#define s1 r12
-+#define s2 r11
-+#define len r10
-+
-+      .text
-+      .global memcmp
-+      .type   memcmp, @function
-+      .align  1
-+memcmp:
-+      sub     len, 4
-+      brlt    .Lless_than_4
-+
-+1:    ld.w    r8, s1++
-+      ld.w    r9, s2++
-+      cp.w    r8, r9
-+      brne    .Lfound_word
-+      sub     len, 4
-+      brge    1b
-+
-+.Lless_than_4:
-+      sub     len, -4
-+      reteq   0
-+
-+1:    ld.ub   r8, s1++
-+      ld.ub   r9, s2++
-+      sub     r8, r9
-+      retne   r8
-+      sub     len, 1
-+      brgt    1b
-+
-+      retal   0
-+
-+.Lfound_word:
-+      psub.b  r9, r8, r9
-+      bfextu  r8, r9, 24, 8
-+      retne   r8
-+      bfextu  r8, r9, 16, 8
-+      retne   r8
-+      bfextu  r8, r9, 8, 8
-+      retne   r8
-+      retal   r9
-+
-+      .size   memcmp, . - memcmp
-+
-+libc_hidden_def(memcmp)
-+#ifdef __UCLIBC_SUSV3_LEGACY__
-+strong_alias(memcmp,bcmp)
-+#endif
-diff --git a/libc/string/avr32/memcpy.S b/libc/string/avr32/memcpy.S
-new file mode 100644
-index 0000000..bf091ab
---- /dev/null
-+++ b/libc/string/avr32/memcpy.S
-@@ -0,0 +1,111 @@
-+/*
-+ * Copyright (C) 2004-2007 Atmel Corporation
-+ *
-+ * 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.
-+ */
-+
-+/* Don't use r12 as dst since we must return it unmodified */
-+#define dst r9
-+#define src r11
-+#define len r10
-+
-+      .text
-+      .global memcpy
-+      .type   memcpy, @function
-+memcpy:
-+      pref    src[0]
-+      mov     dst, r12
-+
-+      /* If we have less than 32 bytes, don't do anything fancy */
-+      cp.w    len, 32
-+      brge    .Lmore_than_31
-+
-+      sub     len, 1
-+      retlt   r12
-+1:    ld.ub   r8, src++
-+      st.b    dst++, r8
-+      sub     len, 1
-+      brge    1b
-+      retal   r12
-+
-+.Lmore_than_31:
-+      pushm   r0-r7, lr
-+
-+      /* Check alignment */
-+      mov     r8, src
-+      andl    r8, 31, COH
-+      brne    .Lunaligned_src
-+      mov     r8, dst
-+      andl    r8, 3, COH
-+      brne    .Lunaligned_dst
-+
-+.Laligned_copy:
-+      sub     len, 32
-+      brlt    .Lless_than_32
-+
-+1:    /* Copy 32 bytes at a time */
-+      ldm     src, r0-r7
-+      sub     src, -32
-+      stm     dst, r0-r7
-+      sub     dst, -32
-+      sub     len, 32
-+      brge    1b
-+
-+.Lless_than_32:
-+      /* Copy 16 more bytes if possible */
-+      sub     len, -16
-+      brlt    .Lless_than_16
-+      ldm     src, r0-r3
-+      sub     src, -16
-+      sub     len, 16
-+      stm     dst, r0-r3
-+      sub     dst, -16
-+
-+.Lless_than_16:
-+      /* Do the remaining as byte copies */
-+      neg     len
-+      add     pc, pc, len << 2
-+      .rept   15
-+      ld.ub   r0, src++
-+      st.b    dst++, r0
-+      .endr
-+
-+      popm    r0-r7, pc
-+
-+.Lunaligned_src:
-+      /* Make src cacheline-aligned. r8 = (src & 31) */
-+      rsub    r8, r8, 32
-+      sub     len, r8
-+1:    ld.ub   r0, src++
-+      st.b    dst++, r0
-+      sub     r8, 1
-+      brne    1b
-+
-+      /* If dst is word-aligned, we're ready to go */
-+      pref    src[0]
-+      mov     r8, 3
-+      tst     dst, r8
-+      breq    .Laligned_copy
-+
-+.Lunaligned_dst:
-+      /* src is aligned, but dst is not. Expect bad performance */
-+      sub     len, 4
-+      brlt    2f
-+1:    ld.w    r0, src++
-+      st.w    dst++, r0
-+      sub     len, 4
-+      brge    1b
-+
-+2:    neg     len
-+      add     pc, pc, len << 2
-+      .rept   3
-+      ld.ub   r0, src++
-+      st.b    dst++, r0
-+      .endr
-+
-+      popm    r0-r7, pc
-+      .size   memcpy, . - memcpy
-+
-+libc_hidden_def(memcpy)
-diff --git a/libc/string/avr32/memmove.S b/libc/string/avr32/memmove.S
-new file mode 100644
-index 0000000..98287c5
---- /dev/null
-+++ b/libc/string/avr32/memmove.S
-@@ -0,0 +1,116 @@
-+/*
-+ * Copyright (C) 2004-2007 Atmel Corporation
-+ *
-+ * 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.
-+ */
-+
-+#define dst r12
-+#define src r11
-+#define len r10
-+
-+      .text
-+      .global memmove
-+      .type   memmove, @function
-+memmove:
-+      cp.w    src, dst
-+      brge    __GI_memcpy
-+
-+      add     dst, len
-+      add     src, len
-+      pref    src[-1]
-+
-+      /*
-+       * The rest is basically the same as in memcpy.S except that
-+       * the direction is reversed.
-+       */
-+      cp.w    len, 32
-+      brge    .Lmore_than_31
-+
-+      sub     len, 1
-+      retlt   r12
-+1:    ld.ub   r8, --src
-+      st.b    --dst, r8
-+      sub     len, 1
-+      brge    1b
-+      retal   r12
-+
-+.Lmore_than_31:
-+      pushm   r0-r7, lr
-+
-+      /* Check alignment */
-+      mov     r8, src
-+      andl    r8, 31, COH
-+      brne    .Lunaligned_src
-+      mov     r8, r12
-+      andl    r8, 3, COH
-+      brne    .Lunaligned_dst
-+
-+.Laligned_copy:
-+      sub     len, 32
-+      brlt    .Lless_than_32
-+
-+1:    /* Copy 32 bytes at a time */
-+      sub     src, 32
-+      ldm     src, r0-r7
-+      sub     dst, 32
-+      sub     len, 32
-+      stm     dst, r0-r7
-+      brge    1b
-+
-+.Lless_than_32:
-+      /* Copy 16 more bytes if possible */
-+      sub     len, -16
-+      brlt    .Lless_than_16
-+      sub     src, 16
-+      ldm     src, r0-r3
-+      sub     dst, 16
-+      sub     len, 16
-+      stm     dst, r0-r3
-+
-+.Lless_than_16:
-+      /* Do the remaining as byte copies */
-+      sub     len, -16
-+      breq    2f
-+1:    ld.ub   r0, --src
-+      st.b    --dst, r0
-+      sub     len, 1
-+      brne    1b
-+
-+2:    popm    r0-r7, pc
-+
-+.Lunaligned_src:
-+      /* Make src cacheline-aligned. r8 = (src & 31) */
-+      sub     len, r8
-+1:    ld.ub   r0, --src
-+      st.b    --dst, r0
-+      sub     r8, 1
-+      brne    1b
-+
-+      /* If dst is word-aligned, we're ready to go */
-+      pref    src[-4]
-+      mov     r8, 3
-+      tst     dst, r8
-+      breq    .Laligned_copy
-+
-+.Lunaligned_dst:
-+      /* src is aligned, but dst is not. Expect bad performance */
-+      sub     len, 4
-+      brlt    2f
-+1:    ld.w    r0, --src
-+      st.w    --dst, r0
-+      sub     len, 4
-+      brge    1b
-+
-+2:    neg     len
-+      add     pc, pc, len << 2
-+      .rept   3
-+      ld.ub   r0, --src
-+      st.b    --dst, r0
-+      .endr
-+
-+      popm    r0-r7, pc
-+      .size   memmove, . - memmove
-+
-+libc_hidden_def(memmove)
-diff --git a/libc/string/avr32/memset.S b/libc/string/avr32/memset.S
-new file mode 100644
-index 0000000..33cfaed
---- /dev/null
-+++ b/libc/string/avr32/memset.S
-@@ -0,0 +1,70 @@
-+/*
-+ * Copyright (C) 2004-2007 Atmel Corporation
-+ *
-+ * 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.
-+ */
-+
-+#include <features.h>
-+
-+#define s r12
-+#define c r11
-+#define n r10
-+
-+      .text
-+      .global memset
-+      .type   memset, @function
-+
-+      .global __memset
-+      .hidden __memset
-+      .type   __memset, @function
-+
-+      .align  1
-+memset:
-+__memset:
-+      cp.w    n, 32
-+      mov     r9, s
-+      brge    .Llarge_memset
-+
-+      sub     n, 1
-+      retlt   s
-+1:    st.b    s++, c
-+      sub     n, 1
-+      brge    1b
-+
-+      retal   r9
-+
-+.Llarge_memset:
-+      mov     r8, r11
-+      mov     r11, 3
-+      bfins   r8, r8, 8, 8
-+      bfins   r8, r8, 16, 16
-+      tst     s, r11
-+      breq    2f
-+
-+1:    st.b    s++, r8
-+      sub     n, 1
-+      tst     s, r11
-+      brne    1b
-+
-+2:    mov     r11, r9
-+      mov     r9, r8
-+      sub     n, 8
-+
-+3:    st.d    s++, r8
-+      sub     n, 8
-+      brge    3b
-+
-+      /* If we are done, n == -8 and we'll skip all st.b insns below */
-+      neg     n
-+      lsl     n, 1
-+      add     pc, n
-+      .rept   7
-+      st.b    s++, r8
-+      .endr
-+      retal   r11
-+
-+      .size   memset, . - memset
-+
-+libc_hidden_def(memset)
-diff --git a/libc/string/avr32/strcmp.S b/libc/string/avr32/strcmp.S
-new file mode 100644
-index 0000000..f73bd43
---- /dev/null
-+++ b/libc/string/avr32/strcmp.S
-@@ -0,0 +1,91 @@
-+/*
-+ * Copyright (C) 2004-2007 Atmel Corporation
-+ *
-+ * 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.
-+ */
-+
-+#include <features.h>
-+
-+#define s1 r12
-+#define s2 r11
-+#define len r10
-+
-+      .text
-+      .global strcmp
-+      .type   strcmp, @function
-+      .align  1
-+strcmp:
-+      mov     r8, 3
-+      tst     s1, r8
-+      brne    .Lunaligned_s1
-+      tst     s2, r8
-+      brne    .Lunaligned_s2
-+
-+1:    ld.w    r8, s1++
-+      ld.w    r9, s2++
-+      cp.w    r8, r9
-+      brne    2f
-+      tnbz    r8
-+      brne    1b
-+      retal   0
-+
-+2:    bfextu  r12, r8, 24, 8
-+      bfextu  r11, r9, 24, 8
-+      sub     r12, r11
-+      retne   r12
-+      cp.w    r11, 0
-+      reteq   0
-+      bfextu  r12, r8, 16, 8
-+      bfextu  r11, r9, 16, 8
-+      sub     r12, r11
-+      retne   r12
-+      cp.w    r11, 0
-+      reteq   0
-+      bfextu  r12, r8, 8, 8
-+      bfextu  r11, r9, 8, 8
-+      sub     r12, r11
-+      retne   r12
-+      cp.w    r11, 0
-+      reteq   0
-+      bfextu  r12, r8, 0, 8
-+      bfextu  r11, r9, 0, 8
-+      sub     r12, r11
-+      retal   r12
-+
-+.Lunaligned_s1:
-+3:    tst     s1, r8
-+      breq    4f
-+      ld.ub   r10, s1++
-+      ld.ub   r9, s2++
-+      sub     r10, r9
-+      retne   r10
-+      cp.w    r9, 0
-+      brne    3b
-+      retal   r10
-+
-+4:    tst     s2, r8
-+      breq    1b
-+
-+.Lunaligned_s2:
-+      /*
-+       * s1 and s2 can't both be aligned, and unaligned word loads
-+       * can trigger spurious exceptions if we cross a page boundary.
-+       * Do it the slow way...
-+       */
-+1:    ld.ub   r8, s1++
-+      ld.ub   r9, s2++
-+      sub     r8, r9
-+      retne   r8
-+      cp.w    r9, 0
-+      brne    1b
-+      retal   0
-+
-+      .size   strcmp, . - strcmp
-+
-+libc_hidden_def(strcmp)
-+#ifndef __UCLIBC_HAS_LOCALE__
-+strong_alias(strcmp, strcoll)
-+libc_hidden_def(strcoll)
-+#endif
-diff --git a/libc/string/avr32/strlen.S b/libc/string/avr32/strlen.S
-new file mode 100644
-index 0000000..5223e53
---- /dev/null
-+++ b/libc/string/avr32/strlen.S
-@@ -0,0 +1,62 @@
-+/*
-+ * Copyright (C) 2004-2007 Atmel Corporation
-+ *
-+ * 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.
-+ */
-+
-+#include <features.h>
-+
-+#define str r12
-+
-+      .text
-+      .global strlen
-+      .type   strlen, @function
-+strlen:
-+      mov     r11, r12
-+
-+      mov     r9, str
-+      andl    r9, 3, COH
-+      brne    .Lunaligned_str
-+
-+1:    ld.w    r8, str++
-+      tnbz    r8
-+      brne    1b
-+
-+      sub     r12, r11
-+      bfextu  r9, r8, 24, 8
-+      cp.w    r9, 0
-+      subeq   r12, 4
-+      reteq   r12
-+      bfextu  r9, r8, 16, 8
-+      cp.w    r9, 0
-+      subeq   r12, 3
-+      reteq   r12
-+      bfextu  r9, r8, 8, 8
-+      cp.w    r9, 0
-+      subeq   r12, 2
-+      reteq   r12
-+      sub     r12, 1
-+      retal   r12
-+
-+.Lunaligned_str:
-+      add     pc, pc, r9 << 3
-+      sub     r0, r0, 0       /* 4-byte nop */
-+      ld.ub   r8, str++
-+      sub     r8, r8, 0
-+      breq    1f
-+      ld.ub   r8, str++
-+      sub     r8, r8, 0
-+      breq    1f
-+      ld.ub   r8, str++
-+      sub     r8, r8, 0
-+      brne    1b
-+
-+1:    sub     r12, 1
-+      sub     r12, r11
-+      retal   r12
-+
-+      .size   strlen, . - strlen
-+
-+libc_hidden_def(strlen)
-diff --git a/libc/sysdeps/linux/avr32/Makefile b/libc/sysdeps/linux/avr32/Makefile
-new file mode 100644
-index 0000000..338abc0
---- /dev/null
-+++ b/libc/sysdeps/linux/avr32/Makefile
-@@ -0,0 +1,25 @@
-+# Makefile for uClibc
-+#
-+# Copyright (C) 2000-2003 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
-+
-+top_srcdir=../../../../
-+top_builddir=../../../../
-+all: objs
-+
-+include $(top_builddir)Rules.mak
-+include Makefile.arch
-+include $(top_srcdir)Makerules
-diff --git a/libc/sysdeps/linux/avr32/Makefile.arch b/libc/sysdeps/linux/avr32/Makefile.arch
-new file mode 100644
-index 0000000..44fc01e
---- /dev/null
-+++ b/libc/sysdeps/linux/avr32/Makefile.arch
-@@ -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.
-+#
-+
-+CSRC  := brk.c clone.c mmap.c sigaction.c
-+
-+SSRC  := __longjmp.S setjmp.S bsd-setjmp.S bsd-_setjmp.S      \
-+              sigrestorer.S syscall.S vfork.S
-+
-+include $(top_srcdir)/libc/sysdeps/linux/Makefile.commonarch
-diff --git a/libc/sysdeps/linux/avr32/__longjmp.S b/libc/sysdeps/linux/avr32/__longjmp.S
-new file mode 100644
-index 0000000..6154bb2
---- /dev/null
-+++ b/libc/sysdeps/linux/avr32/__longjmp.S
-@@ -0,0 +1,21 @@
-+/*
-+ * Copyright (C) 2004-2007 Atmel Corporation
-+ *
-+ * 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.
-+ */
-+
-+      .global __longjmp
-+      .type   __longjmp,"function"
-+      .align  1
-+__longjmp:
-+      ldm     r12++, r0-r8,sp,lr
-+      mustr   r8              /* restore status register (lower half) */
-+      cp      r11, 0          /* can't return zero */
-+      frs
-+      moveq   r11, 1
-+      retal   r11
-+      .size   __longjmp, . - __longjmp
-+
-+libc_hidden_def(__longjmp)
-diff --git a/libc/sysdeps/linux/avr32/bits/atomic.h b/libc/sysdeps/linux/avr32/bits/atomic.h
-new file mode 100644
-index 0000000..e6be41f
---- /dev/null
-+++ b/libc/sysdeps/linux/avr32/bits/atomic.h
-@@ -0,0 +1,120 @@
-+/*
-+ * Copyright (C) 2007 Atmel Corporation
-+ *
-+ * 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.
-+ */
-+#ifndef _AVR32_BITS_ATOMIC_H
-+#define _AVR32_BITS_ATOMIC_H 1
-+
-+#include <inttypes.h>
-+
-+typedef int32_t atomic32_t;
-+typedef uint32_t uatomic32_t;
-+typedef int_fast32_t atomic_fast32_t;
-+typedef uint_fast32_t uatomic_fast32_t;
-+
-+typedef intptr_t atomicptr_t;
-+typedef uintptr_t uatomicptr_t;
-+typedef intmax_t atomic_max_t;
-+typedef uintmax_t uatomic_max_t;
-+
-+#define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval)    \
-+      (abort(), 0)
-+
-+#define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval)   \
-+      (abort(), 0)
-+
-+#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval)   \
-+      ({                                                              \
-+              __typeof__(*(mem)) __prev;                              \
-+              __asm__ __volatile__(                                   \
-+                      "/* __arch_compare_and_exchange_val_32_acq */\n" \
-+                      "1:     ssrf    5\n"                            \
-+                      "       ld.w    %[result], %[m]\n"              \
-+                      "       cp.w    %[result], %[old]\n"            \
-+                      "       brne    2f\n"                           \
-+                      "       stcond  %[m], %[new]\n"                 \
-+                      "       brne    1b\n"                           \
-+                      "2:"                                            \
-+                      : [result] "=&r"(__result), [m] "=m"(*(mem))    \
-+                      : "m"(*(mem)), [old] "ir"(oldval),              \
-+                        [new] "r"(newval)                             \
-+                      : "memory", "cc");                              \
-+              __prev;                                                 \
-+      })
-+
-+#define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval)   \
-+      (abort(), 0)
-+
-+#define __arch_exchange_32_acq(mem, newval)                           \
-+      ({                                                              \
-+              __typeof__(*(mem)) __oldval;                            \
-+              __asm__ __volatile__(                                   \
-+                      "/*__arch_exchange_32_acq */\n"                 \
-+                      "       xchg    %[old], %[m], %[new]"           \
-+                      : [old] "=&r"(__oldval)                         \
-+                      : [m] "r"(mem), [new] "r"(newval)               \
-+                      : "memory");                                    \
-+              __oldval;                                               \
-+      })
-+
-+#define __arch_atomic_exchange_and_add_32(mem, value)                 \
-+      ({                                                              \
-+              __typeof__(*(mem)) __oldval, __tmp;                     \
-+              __asm__ __volatile__(                                   \
-+                      "/* __arch_atomic_exchange_and_add_32 */\n"     \
-+                      "1:     ssrf    5\n"                            \
-+                      "       ld.w    %[old], %[m]\n"                 \
-+                      "       add     %[tmp], %[old], %[val]\n"       \
-+                      "       stcond  %[m], %[tmp]\n"                 \
-+                      "       brne    1b"                             \
-+                      : [old] "=&r"(__oldval), [tmp] "=&r"(__tmp),    \
-+                        [m] "=m"(*(mem))                              \
-+                      : "m"(*(mem)), [val] "r"(value)                 \
-+                      : "memory", "cc");                              \
-+              __oldval;                                               \
-+      })
-+
-+#define __arch_atomic_decrement_if_positive_32(mem)                   \
-+      ({                                                              \
-+              __typeof__(*(mem)) __oldval, __tmp;                     \
-+              __asm__ __volatile__(                                   \
-+                      "/* __arch_atomic_decrement_if_positive_32 */\n" \
-+                      "1:     ssrf    5\n"                            \
-+                      "       ld.w    %[old], %[m]\n"                 \
-+                      "       sub     %[tmp], %[old], 1\n"            \
-+                      "       brlt    2f\n"                           \
-+                      "       stcond  %[m], %[tmp]\n"                 \
-+                      "       brne    1b"                             \
-+                      "2:"                                            \
-+                      : [old] "=&r"(__oldval), [tmp] "=&r"(__tmp),    \
-+                        [m] "=m"(*(mem))                              \
-+                      : "m"(*(mem))                                   \
-+                      : "memory", "cc");                              \
-+              __oldval;                                               \
-+      })
-+
-+#define atomic_exchange_acq(mem, newval)                              \
-+      ({                                                              \
-+              if (sizeof(*(mem)) != 4)                                \
-+                      abort();                                        \
-+              __arch_exchange_32_acq(mem, newval);                    \
-+      })
-+
-+#define atomic_exchange_and_add(mem, newval)                          \
-+      ({                                                              \
-+              if (sizeof(*(mem)) != 4)                                \
-+                      abort();                                        \
-+              __arch_atomic_exchange_and_add_32(mem, newval);         \
-+      })
-+
-+#define atomic_decrement_if_positive(mem)                             \
-+      ({                                                              \
-+              if (sizeof(*(mem)) != 4)                                \
-+                      abort();                                        \
-+              __arch_atomic_decrement_if_positive_32(mem);            \
-+      })
-+
-+#endif /* _AVR32_BITS_ATOMIC_H */
-diff --git a/libc/sysdeps/linux/avr32/bits/byteswap.h b/libc/sysdeps/linux/avr32/bits/byteswap.h
-new file mode 100644
-index 0000000..1c030b9
---- /dev/null
-+++ b/libc/sysdeps/linux/avr32/bits/byteswap.h
-@@ -0,0 +1,70 @@
-+/*
-+ * Copyright (C) 2005 Atmel Corporation
-+ *
-+ * 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.
-+ */
-+
-+#if !defined _BYTESWAP_H && !defined _NETINET_IN_H
-+# error "Never use <bits/byteswap.h> directly; include <byteswap.h> instead."
-+#endif
-+
-+#ifndef _BITS_BYTESWAP_H
-+#define _BITS_BYTESWAP_H 1
-+
-+/* Swap bytes in 16 bit value.  */
-+#if defined __GNUC__
-+# define __bswap_16(x) (__extension__ __builtin_bswap_16(x))
-+#else
-+/* This is better than nothing.  */
-+static __inline unsigned short int
-+__bswap_16 (unsigned short int __bsx)
-+{
-+      return ((((__bsx) >> 8) & 0xff) | (((__bsx) & 0xff) << 8));
-+}
-+#endif
-+
-+/* Swap bytes in 32 bit value.  */
-+#if defined __GNUC__
-+# define __bswap_32(x) (__extension__ __builtin_bswap_32(x))
-+#else
-+static __inline unsigned int
-+__bswap_32 (unsigned int __bsx)
-+{
-+  return ((((__bsx) & 0xff000000) >> 24) | (((__bsx) & 0x00ff0000) >>  8) |
-+        (((__bsx) & 0x0000ff00) <<  8) | (((__bsx) & 0x000000ff) << 24));
-+}
-+#endif
-+
-+#if defined __GNUC__
-+/* Swap bytes in 64 bit value.  */
-+# define __bswap_constant_64(x)                               \
-+      ((((x) & 0xff00000000000000ull) >> 56)          \
-+       | (((x) & 0x00ff000000000000ull) >> 40)        \
-+       | (((x) & 0x0000ff0000000000ull) >> 24)        \
-+       | (((x) & 0x000000ff00000000ull) >> 8)         \
-+       | (((x) & 0x00000000ff000000ull) << 8)         \
-+       | (((x) & 0x0000000000ff0000ull) << 24)        \
-+       | (((x) & 0x000000000000ff00ull) << 40)        \
-+       | (((x) & 0x00000000000000ffull) << 56))
-+
-+# define __bswap_64(x)                                                        \
-+      (__extension__                                                  \
-+       ({                                                             \
-+               union {                                                \
-+                       __extension__ unsigned long long int __ll;     \
-+                       unsigned int __l[2];                           \
-+               } __w, __r;                                            \
-+               if (__builtin_constant_p(x))                           \
-+                       __r.__ll = __bswap_constant_64(x);             \
-+               else {                                                 \
-+                       __w.__ll = (x);                                \
-+                       __r.__l[0] = __bswap_32(__w.__l[1]);           \
-+                       __r.__l[1] = __bswap_32(__w.__l[0]);           \
-+               }                                                      \
-+               __r.__ll;                                              \
-+       }))
-+#endif
-+
-+#endif /* _BITS_BYTESWAP_H */
-diff --git a/libc/sysdeps/linux/avr32/bits/endian.h b/libc/sysdeps/linux/avr32/bits/endian.h
-new file mode 100644
-index 0000000..7bb6358
---- /dev/null
-+++ b/libc/sysdeps/linux/avr32/bits/endian.h
-@@ -0,0 +1,7 @@
-+/* AVR32 is big-endian */
-+
-+#ifndef _ENDIAN_H
-+# error "Never use <bits/endian.h> directly; include <endian.h> instead."
-+#endif
-+
-+#define __BYTE_ORDER __BIG_ENDIAN
-diff --git a/libc/sysdeps/linux/avr32/bits/fcntl.h b/libc/sysdeps/linux/avr32/bits/fcntl.h
-new file mode 100644
-index 0000000..1abff17
---- /dev/null
-+++ b/libc/sysdeps/linux/avr32/bits/fcntl.h
-@@ -0,0 +1,165 @@
-+#ifndef _FCNTL_H
-+# error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead."
-+#endif
-+
-+#include <sys/types.h>
-+
-+/*
-+ * open/fcntl - O_SYNC is only implemented on blocks devices and on files
-+ * located on an ext2 file system
-+ */
-+#define O_ACCMODE     00000003
-+#define O_RDONLY      00000000
-+#define O_WRONLY      00000001
-+#define O_RDWR                00000002
-+#define O_CREAT               00000100        /* not fcntl */
-+#define O_EXCL                00000200        /* not fcntl */
-+#define O_NOCTTY      00000400        /* not fcntl */
-+#define O_TRUNC               00001000        /* not fcntl */
-+#define O_APPEND      00002000
-+#define O_NONBLOCK    00004000
-+#define O_NDELAY      O_NONBLOCK
-+#define O_SYNC                00010000
-+#define O_ASYNC               00020000
-+
-+#ifdef __USE_GNU
-+# define O_DIRECT     00040000        /* must be a directory */
-+# define O_DIRECTORY  00200000        /* direct disk access */
-+# define O_NOFOLLOW   00400000        /* don't follow links */
-+# define O_NOATIME    01000000        /* don't set atime */
-+#endif
-+
-+#ifdef __USE_LARGEFILE64
-+# define O_LARGEFILE  00100000
-+#endif
-+
-+/* For now Linux has synchronisity options for data and read operations.
-+   We define the symbols here but let them do the same as O_SYNC since
-+   this is a superset.        */
-+#if defined __USE_POSIX199309 || defined __USE_UNIX98
-+# define O_DSYNC      O_SYNC  /* Synchronize data.  */
-+# define O_RSYNC      O_SYNC  /* Synchronize read operations.  */
-+#endif
-+
-+#define F_DUPFD               0       /* dup */
-+#define F_GETFD               1       /* get close_on_exec */
-+#define F_SETFD               2       /* set/clear close_on_exec */
-+#define F_GETFL               3       /* get file->f_flags */
-+#define F_SETFL               4       /* set file->f_flags */
-+
-+#ifndef __USE_FILE_OFFSET64
-+# define F_GETLK      5
-+# define F_SETLK      6
-+# define F_SETLKW     7
-+#else
-+# define F_GETLK      F_GETLK64
-+# define F_SETLK      F_SETLK64
-+# define F_SETLKW     F_SETLKW64
-+#endif
-+#define F_GETLK64     12      /*  using 'struct flock64' */
-+#define F_SETLK64     13
-+#define F_SETLKW64    14
-+
-+#if defined __USE_BSD || defined __USE_XOPEN2K
-+# define F_SETOWN     8       /*  for sockets. */
-+# define F_GETOWN     9       /*  for sockets. */
-+#endif
-+
-+#ifdef __USE_GNU
-+# define F_SETSIG     10      /*  for sockets. */
-+# define F_GETSIG     11      /*  for sockets. */
-+#endif
-+
-+#ifdef __USE_GNU
-+# define F_SETLEASE   1024    /* Set a lease.  */
-+# define F_GETLEASE   1025    /* Enquire what lease is active.  */
-+# define F_NOTIFY     1026    /* Request notfications on a directory.  */
-+#endif
-+
-+/* for F_[GET|SET]FL */
-+#define FD_CLOEXEC    1       /* actually anything with low bit set goes */
-+
-+/* for posix fcntl() and lockf() */
-+#define F_RDLCK               0
-+#define F_WRLCK               1
-+#define F_UNLCK               2
-+
-+/* for old implementation of bsd flock () */
-+#define F_EXLCK               4       /* or 3 */
-+#define F_SHLCK               8       /* or 4 */
-+
-+/* for leases */
-+#define F_INPROGRESS  16
-+
-+#ifdef __USE_BSD
-+/* operations for bsd flock(), also used by the kernel implementation */
-+# define LOCK_SH      1       /* shared lock */
-+# define LOCK_EX      2       /* exclusive lock */
-+# define LOCK_NB      4       /* or'd with one of the above to prevent
-+                                 blocking */
-+# define LOCK_UN      8       /* remove lock */
-+#endif
-+
-+#ifdef __USE_GNU
-+# define LOCK_MAND    32      /* This is a mandatory flock */
-+# define LOCK_READ    64      /* ... Which allows concurrent
-+                                     read operations */
-+# define LOCK_WRITE   128     /* ... Which allows concurrent
-+                                     write operations */
-+# define LOCK_RW      192     /* ... Which allows concurrent
-+                                     read & write ops */
-+#endif
-+
-+#ifdef __USE_GNU
-+/* Types of directory notifications that may be requested with F_NOTIFY.  */
-+# define DN_ACCESS    0x00000001      /* File accessed.  */
-+# define DN_MODIFY    0x00000002      /* File modified.  */
-+# define DN_CREATE    0x00000004      /* File created.  */
-+# define DN_DELETE    0x00000008      /* File removed.  */
-+# define DN_RENAME    0x00000010      /* File renamed.  */
-+# define DN_ATTRIB    0x00000020      /* File changed attibutes.  */
-+# define DN_MULTISHOT 0x80000000      /* Don't remove notifier.  */
-+#endif
-+
-+struct flock {
-+      short           l_type;
-+      short           l_whence;
-+#ifndef __USE_FILE_OFFSET64
-+      __off_t         l_start;
-+      __off_t         l_len;
-+#else
-+      __off64_t       l_start;
-+      __off64_t       l_len;
-+#endif
-+      __pid_t         l_pid;
-+};
-+
-+#ifdef __USE_LARGEFILE64
-+struct flock64 {
-+      short           l_type;
-+      short           l_whence;
-+      __off64_t       l_start;
-+      __off64_t       l_len;
-+      __pid_t         l_pid;
-+};
-+#endif
-+
-+/* Define some more compatibility macros to be backward compatible with
-+ *    BSD systems which did not managed to hide these kernel macros.  */
-+#ifdef  __USE_BSD
-+# define FAPPEND        O_APPEND
-+# define FFSYNC         O_FSYNC
-+# define FASYNC         O_ASYNC
-+# define FNONBLOCK      O_NONBLOCK
-+# define FNDELAY        O_NDELAY
-+#endif /* Use BSD.  */
-+
-+/* Advise to `posix_fadvise'.  */
-+#ifdef __USE_XOPEN2K
-+# define POSIX_FADV_NORMAL      0 /* No further special treatment.  */
-+# define POSIX_FADV_RANDOM      1 /* Expect random page references.  */
-+# define POSIX_FADV_SEQUENTIAL  2 /* Expect sequential page references.  */
-+# define POSIX_FADV_WILLNEED    3 /* Will need these pages.  */
-+# define POSIX_FADV_DONTNEED    4 /* Don't need these pages.  */
-+# define POSIX_FADV_NOREUSE     5 /* Data will be accessed once.  */
-+#endif
-diff --git a/libc/sysdeps/linux/avr32/bits/kernel_stat.h b/libc/sysdeps/linux/avr32/bits/kernel_stat.h
-new file mode 100644
-index 0000000..f97d23b
---- /dev/null
-+++ b/libc/sysdeps/linux/avr32/bits/kernel_stat.h
-@@ -0,0 +1,67 @@
-+#ifndef _BITS_STAT_STRUCT_H
-+#define _BITS_STAT_STRUCT_H
-+
-+#ifndef _LIBC
-+#error bits/kernel_stat.h is for internal uClibc use only!
-+#endif
-+
-+/*
-+ * This file provides struct stat, taken from kernel 2.6.4. Verified
-+ * to match kernel 2.6.22.
-+ */
-+
-+struct kernel_stat {
-+        unsigned long         st_dev;
-+        unsigned long         st_ino;
-+        unsigned short                st_mode;
-+        unsigned short                st_nlink;
-+        unsigned short                st_uid;
-+        unsigned short                st_gid;
-+        unsigned long         st_rdev;
-+        unsigned long         st_size;
-+        unsigned long         st_blksize;
-+        unsigned long         st_blocks;
-+        unsigned long         st_atime;
-+        unsigned long         st_atime_nsec;
-+        unsigned long         st_mtime;
-+        unsigned long         st_mtime_nsec;
-+        unsigned long         st_ctime;
-+        unsigned long         st_ctime_nsec;
-+        unsigned long         __unused4;
-+        unsigned long         __unused5;
-+};
-+
-+#define STAT_HAVE_NSEC 1
-+
-+struct kernel_stat64 {
-+      unsigned long long      st_dev;
-+
-+      unsigned long long      st_ino;
-+      unsigned int            st_mode;
-+      unsigned int            st_nlink;
-+
-+      unsigned long           st_uid;
-+      unsigned long           st_gid;
-+
-+      unsigned long long      st_rdev;
-+
-+      long long               st_size;
-+      unsigned long           __pad1;
-+      unsigned long           st_blksize;
-+
-+      unsigned long long      st_blocks;
-+
-+      unsigned long           st_atime;
-+      unsigned long           st_atime_nsec;
-+
-+      unsigned long           st_mtime;
-+      unsigned long           st_mtime_nsec;
-+
-+      unsigned long           st_ctime;
-+      unsigned long           st_ctime_nsec;
-+
-+      unsigned long           __unused1;
-+      unsigned long           __unused2;
-+};
-+
-+#endif /* _BITS_STAT_STRUCT_H */
-diff --git a/libc/sysdeps/linux/avr32/bits/kernel_types.h b/libc/sysdeps/linux/avr32/bits/kernel_types.h
-new file mode 100644
-index 0000000..f7d8b52
---- /dev/null
-+++ b/libc/sysdeps/linux/avr32/bits/kernel_types.h
-@@ -0,0 +1,55 @@
-+/* Note that we use the exact same include guard #define names
-+ * as asm/posix_types.h.  This will avoid gratuitous conflicts
-+ * with the posix_types.h kernel header, and will ensure that
-+ * our private content, and not the kernel header, will win.
-+ *  -Erik
-+ */
-+#ifndef __ASM_AVR32_POSIX_TYPES_H
-+#define __ASM_AVR32_POSIX_TYPES_H
-+
-+/*
-+ * This file is generally used by user-level software, so you need to
-+ * be a little careful about namespace pollution etc.  Also, we cannot
-+ * assume GCC is being used.
-+ */
-+
-+typedef unsigned long         __kernel_dev_t;
-+typedef unsigned long         __kernel_ino_t;
-+typedef unsigned short                __kernel_mode_t;
-+typedef unsigned short                __kernel_nlink_t;
-+typedef long                  __kernel_off_t;
-+typedef int                   __kernel_pid_t;
-+typedef unsigned short                __kernel_ipc_pid_t;
-+typedef unsigned int          __kernel_uid_t;
-+typedef unsigned int          __kernel_gid_t;
-+typedef unsigned long         __kernel_size_t;
-+typedef long                  __kernel_ssize_t;
-+typedef int                   __kernel_ptrdiff_t;
-+typedef long                  __kernel_time_t;
-+typedef long                  __kernel_suseconds_t;
-+typedef long                  __kernel_clock_t;
-+typedef int                   __kernel_timer_t;
-+typedef int                   __kernel_clockid_t;
-+typedef int                   __kernel_daddr_t;
-+typedef char *                        __kernel_caddr_t;
-+typedef unsigned short                __kernel_uid16_t;
-+typedef unsigned short                __kernel_gid16_t;
-+typedef unsigned int          __kernel_uid32_t;
-+typedef unsigned int          __kernel_gid32_t;
-+typedef unsigned short                __kernel_old_uid_t;
-+typedef unsigned short                __kernel_old_gid_t;
-+typedef unsigned short                __kernel_old_dev_t;
-+
-+#ifdef __GNUC__
-+typedef long long             __kernel_loff_t;
-+#endif
-+
-+typedef struct {
-+#if defined(__USE_ALL)
-+      int     val[2];
-+#else
-+      int     __val[2];
-+#endif
-+} __kernel_fsid_t;
-+
-+#endif /* __ASM_AVR32_POSIX_TYPES_H */
-diff --git a/libc/sysdeps/linux/avr32/bits/mman.h b/libc/sysdeps/linux/avr32/bits/mman.h
-new file mode 100644
-index 0000000..5f6e3c3
---- /dev/null
-+++ b/libc/sysdeps/linux/avr32/bits/mman.h
-@@ -0,0 +1,103 @@
-+/* Definitions for POSIX memory map interface.  Linux/AVR32 version.
-+   Copyright (C) 1997, 2000 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.  */
-+
-+#ifndef _SYS_MMAN_H
-+# error "Never include this file directly.  Use <sys/mman.h> instead"
-+#endif
-+
-+/* The following definitions basically come from the kernel headers.
-+   But the kernel header is not namespace clean.  */
-+
-+
-+/* Protections are chosen from these bits, OR'd together.  The
-+   implementation does not necessarily support PROT_EXEC or PROT_WRITE
-+   without PROT_READ.  The only guarantees are that no writing will be
-+   allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */
-+
-+#define PROT_READ     0x1             /* Page can be read.  */
-+#define PROT_WRITE    0x2             /* Page can be written.  */
-+#define PROT_EXEC     0x4             /* Page can be executed.  */
-+#define PROT_NONE     0x0             /* Page can not be accessed.  */
-+#define PROT_GROWSDOWN        0x01000000      /* Extend change to start of
-+                                         growsdown vma (mprotect only).  */
-+#define PROT_GROWSUP  0x02000000      /* Extend change to start of
-+                                         growsup vma (mprotect only).  */
-+
-+/* Sharing types (must choose one and only one of these).  */
-+#define MAP_SHARED    0x01            /* Share changes.  */
-+#define MAP_PRIVATE   0x02            /* Changes are private.  */
-+#ifdef __USE_MISC
-+# define MAP_TYPE     0x0f            /* Mask for type of mapping.  */
-+#endif
-+
-+/* Other flags.  */
-+#define MAP_FIXED     0x10            /* Interpret addr exactly.  */
-+#ifdef __USE_MISC
-+# define MAP_FILE     0
-+# define MAP_ANONYMOUS        0x20            /* Don't use a file.  */
-+# define MAP_ANON     MAP_ANONYMOUS
-+#endif
-+
-+/* These are Linux-specific.  */
-+#ifdef __USE_MISC
-+# define MAP_GROWSDOWN        0x0100          /* Stack-like segment.  */
-+# define MAP_DENYWRITE        0x0800          /* ETXTBSY */
-+# define MAP_EXECUTABLE       0x1000          /* Mark it as an executable.  */
-+# define MAP_LOCKED   0x2000          /* Lock the mapping.  */
-+# define MAP_NORESERVE        0x4000          /* Don't check for reservations.  */
-+# define MAP_POPULATE 0x8000          /* populate (prefault) pagetables */
-+# define MAP_NONBLOCK 0x10000         /* do not block on IO */
-+#endif
-+
-+/* Flags to `msync'.  */
-+#define MS_ASYNC      1               /* Sync memory asynchronously.  */
-+#define MS_SYNC               4               /* Synchronous memory sync.  */
-+#define MS_INVALIDATE 2               /* Invalidate the caches.  */
-+
-+/* Flags for `mlockall'.  */
-+#define MCL_CURRENT   1               /* Lock all currently mapped pages.  */
-+#define MCL_FUTURE    2               /* Lock all additions to address
-+                                         space.  */
-+
-+/* Flags for `mremap'.  */
-+#ifdef __USE_GNU
-+# define MREMAP_MAYMOVE       1
-+# define MREMAP_FIXED 2
-+#endif
-+
-+/* Advise to `madvise'.  */
-+#ifdef __USE_BSD
-+# define MADV_NORMAL   0      /* No further special treatment.  */
-+# define MADV_RANDOM   1      /* Expect random page references.  */
-+# define MADV_SEQUENTIAL 2    /* Expect sequential page references.  */
-+# define MADV_WILLNEED         3      /* Will need these pages.  */
-+# define MADV_DONTNEED         4      /* Don't need these pages.  */
-+# define MADV_REMOVE   9      /* Remove these pages and resources.  */
-+# define MADV_DONTFORK         10     /* Do not inherit across fork.  */
-+# define MADV_DOFORK   11     /* Do inherit across fork.  */
-+#endif
-+
-+/* The POSIX people had to invent similar names for the same things.  */
-+#ifdef __USE_XOPEN2K
-+# define POSIX_MADV_NORMAL    0 /* No further special treatment.  */
-+# define POSIX_MADV_RANDOM    1 /* Expect random page references.  */
-+# define POSIX_MADV_SEQUENTIAL        2 /* Expect sequential page references.  */
-+# define POSIX_MADV_WILLNEED  3 /* Will need these pages.  */
-+# define POSIX_MADV_DONTNEED  4 /* Don't need these pages.  */
-+#endif
-diff --git a/libc/sysdeps/linux/avr32/bits/setjmp.h b/libc/sysdeps/linux/avr32/bits/setjmp.h
-new file mode 100644
-index 0000000..78348a3
---- /dev/null
-+++ b/libc/sysdeps/linux/avr32/bits/setjmp.h
-@@ -0,0 +1,30 @@
-+/*
-+ * Copyright (C) 2004-2005 Atmel Corporation
-+ *
-+ * 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.
-+ */
-+#ifndef _BITS_SETJMP_H
-+#define _BITS_SETJMP_H        1
-+
-+#if !defined _SETJMP_H && !defined _PTHREAD_H
-+# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
-+#endif
-+
-+#ifndef _ASM
-+/*
-+ * The jump buffer contains r0-r7, sr, sp and lr. Other registers are
-+ * not saved.
-+ */
-+typedef int __jmp_buf[11];
-+#endif
-+
-+#define __JMP_BUF_SP  4
-+
-+/* Test if longjmp to JMPBUF would unwind the frame containing a local
-+   variable at ADDRESS.  */
-+#define _JMPBUF_UNWINDS(jmpbuf, address) \
-+  ((void *)(address) < (void *)(jmpbuf[__JMP_BUF_SP]))
-+
-+#endif /* _BITS_SETJMP_H */
-diff --git a/libc/sysdeps/linux/avr32/bits/stackinfo.h b/libc/sysdeps/linux/avr32/bits/stackinfo.h
-new file mode 100644
-index 0000000..29b8452
---- /dev/null
-+++ b/libc/sysdeps/linux/avr32/bits/stackinfo.h
-@@ -0,0 +1,28 @@
-+/* Copyright (C) 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 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.  */
-+
-+/* This file contains a bit of information about the stack allocation
-+   of the processor.  */
-+
-+#ifndef _STACKINFO_H
-+#define _STACKINFO_H  1
-+
-+/* On AVR32 the stack grows down. */
-+#define _STACK_GROWS_DOWN     1
-+
-+#endif        /* stackinfo.h */
-diff --git a/libc/sysdeps/linux/avr32/bits/syscalls.h b/libc/sysdeps/linux/avr32/bits/syscalls.h
-new file mode 100644
-index 0000000..22ac059
---- /dev/null
-+++ b/libc/sysdeps/linux/avr32/bits/syscalls.h
-@@ -0,0 +1,143 @@
-+#ifndef _BITS_SYSCALLS_H
-+#define _BITS_SYSCALLS_H
-+#ifndef _SYSCALL_H
-+# error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead."
-+#endif
-+
-+/*
-+ * This includes the `__NR_<name>' syscall numbers taken from the
-+ * Linux kernel header files. It also defines the traditional
-+ * `SYS_<name>' macros for older programs.
-+ */
-+#include <bits/sysnum.h>
-+
-+#ifndef __ASSEMBLER__
-+
-+#include <errno.h>
-+
-+#define SYS_ify(syscall_name) (__NR_##syscall_name)
-+
-+#undef _syscall0
-+#define _syscall0(type,name)                          \
-+      type name(void)                                 \
-+      {                                               \
-+              return (type)(INLINE_SYSCALL(name, 0)); \
-+      }
-+
-+#undef _syscall1
-+#define _syscall1(type,name,type1,arg1)                               \
-+      type name(type1 arg1)                                   \
-+      {                                                       \
-+              return (type)(INLINE_SYSCALL(name, 1, arg1));   \
-+      }
-+
-+#undef _syscall2
-+#define _syscall2(type,name,type1,arg1,type2,arg2)                    \
-+      type name(type1 arg1, type2 arg2)                               \
-+      {                                                               \
-+              return (type)(INLINE_SYSCALL(name, 2, arg1, arg2));     \
-+      }
-+
-+#undef _syscall3
-+#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)         \
-+      type name(type1 arg1, type2 arg2, type3 arg3)                   \
-+      {                                                               \
-+              return (type)(INLINE_SYSCALL(name, 3, arg1,             \
-+                                           arg2, arg3));              \
-+      }
-+
-+#undef _syscall4
-+#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,         \
-+                type4,arg4)                                           \
-+      type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4)       \
-+      {                                                               \
-+              return (type)(INLINE_SYSCALL(name, 4, arg1, arg2,       \
-+                                           arg3, arg4));              \
-+      }
-+
-+#undef _syscall5
-+#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,         \
-+                type4,arg4,type5,arg5)                                \
-+      type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4,       \
-+                type5 arg5)                                           \
-+      {                                                               \
-+              return (type)(INLINE_SYSCALL(name, 5, arg1, arg2,       \
-+                                           arg3, arg4, arg5));        \
-+      }
-+
-+#undef _syscall6
-+#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,         \
-+                type4,arg4,type5,arg5,type6,arg6)                     \
-+      type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4,       \
-+                type5 arg5, type6 arg6)                               \
-+      {                                                               \
-+              return (type)(INLINE_SYSCALL(name, 6, arg1, arg2, arg3, \
-+                                           arg4, arg5, arg6));        \
-+      }
-+
-+#undef unlikely
-+#define unlikely(x) __builtin_expect((x), 0)
-+
-+#undef INLINE_SYSCALL
-+#define INLINE_SYSCALL(name, nr, args...)                             \
-+      ({                                                              \
-+              unsigned _sys_result = INTERNAL_SYSCALL(name, , nr, args); \
-+              if (unlikely(INTERNAL_SYSCALL_ERROR_P(_sys_result, ))) { \
-+                      __set_errno(INTERNAL_SYSCALL_ERRNO(_sys_result, )); \
-+                      _sys_result = (unsigned int) -1;                \
-+              }                                                       \
-+              (int) _sys_result;                                      \
-+      })
-+
-+#undef INTERNAL_SYSCALL_DECL
-+#define INTERNAL_SYSCALL_DECL(err) do { } while(0)
-+
-+#undef INTERNAL_SYSCALL
-+#define INTERNAL_SYSCALL(name, err, nr, args...)                      \
-+      ({                                                              \
-+              register int _a1 asm ("r12");                           \
-+              register int _scno asm("r8") = SYS_ify(name);           \
-+              LOAD_ARGS_##nr (args);                                  \
-+              asm volatile ("scall    /* syscall " #name " */"        \
-+                            : "=r" (_a1)                              \
-+                            : "r"(_scno) ASM_ARGS_##nr                \
-+                            : "cc", "memory");                        \
-+              _a1;                                                    \
-+      })
-+
-+#undef INTERNAL_SYSCALL_ERROR_P
-+#define INTERNAL_SYSCALL_ERROR_P(val, err)            \
-+      ((unsigned int)(val) >= 0xfffff001U)
-+
-+#undef INTERNAL_SYSCALL_ERRNO
-+#define INTERNAL_SYSCALL_ERRNO(val, errr) (-(val))
-+
-+#define LOAD_ARGS_0() do { } while(0)
-+#define ASM_ARGS_0
-+#define LOAD_ARGS_1(a1)                                       \
-+      _a1 = (int) (a1);                               \
-+      LOAD_ARGS_0()
-+#define ASM_ARGS_1    ASM_ARGS_0, "r"(_a1)
-+#define LOAD_ARGS_2(a1, a2)                           \
-+      register int _a2 asm("r11") = (int)(a2);        \
-+      LOAD_ARGS_1(a1)
-+#define ASM_ARGS_2    ASM_ARGS_1, "r"(_a2)
-+#define LOAD_ARGS_3(a1, a2, a3)                               \
-+      register int _a3 asm("r10") = (int)(a3);        \
-+      LOAD_ARGS_2(a1, a2)
-+#define ASM_ARGS_3    ASM_ARGS_2, "r"(_a3)
-+#define LOAD_ARGS_4(a1, a2, a3, a4)                   \
-+      register int _a4 asm("r9") = (int)(a4);         \
-+      LOAD_ARGS_3(a1, a2, a3)
-+#define ASM_ARGS_4    ASM_ARGS_3, "r"(_a4)
-+#define LOAD_ARGS_5(a1, a2, a3, a4, a5)                       \
-+      register int _a5 asm("r5") = (int)(a5);         \
-+      LOAD_ARGS_4(a1, a2, a3, a4)
-+#define ASM_ARGS_5    ASM_ARGS_4, "r"(_a5)
-+#define LOAD_ARGS_6(a1, a2, a3, a4, a5, a6)           \
-+      register int _a6 asm("r3") = (int)(a6);         \
-+      LOAD_ARGS_5(a1, a2, a3, a4, a5)
-+#define ASM_ARGS_6    ASM_ARGS_5, "r"(_a6)
-+
-+#endif /* __ASSEMBLER__ */
-+#endif /* _BITS_SYSCALLS_H */
-diff --git a/libc/sysdeps/linux/avr32/bits/uClibc_arch_features.h b/libc/sysdeps/linux/avr32/bits/uClibc_arch_features.h
-new file mode 100644
-index 0000000..e95e8a5
---- /dev/null
-+++ b/libc/sysdeps/linux/avr32/bits/uClibc_arch_features.h
-@@ -0,0 +1,45 @@
-+/*
-+ * Track misc arch-specific features that aren't config options
-+ */
-+
-+#ifndef _BITS_UCLIBC_ARCH_FEATURES_H
-+#define _BITS_UCLIBC_ARCH_FEATURES_H
-+
-+/* instruction used when calling abort() to kill yourself */
-+/* trigger illegal instruction exception, same as BUG in Linux */
-+#define __UCLIBC_ABORT_INSTRUCTION__ ".short 0x5df0"
-+
-+/* can your target use syscall6() for mmap ? */
-+#define __UCLIBC_MMAP_HAS_6_ARGS__
-+
-+/* does your target use syscall4() for truncate64 ? (32bit arches only) */
-+#undef __UCLIBC_TRUNCATE64_HAS_4_ARGS__
-+
-+/* does your target have a broken create_module() ? */
-+#undef __UCLIBC_BROKEN_CREATE_MODULE__
-+
-+/* does your target have to worry about older [gs]etrlimit() ? */
-+#undef __UCLIBC_HANDLE_OLDER_RLIMIT__
-+
-+/* does your target prefix all symbols with an _ ? */
-+#define __UCLIBC_NO_UNDERSCORES__
-+
-+/* does your target have an asm .set ? */
-+#define __UCLIBC_HAVE_ASM_SET_DIRECTIVE__
-+
-+/* define if target doesn't like .global */
-+#undef __UCLIBC_ASM_GLOBAL_DIRECTIVE__
-+
-+/* define if target supports .weak */
-+#define __UCLIBC_HAVE_ASM_WEAK_DIRECTIVE__
-+
-+/* define if target supports .weakext */
-+#undef __UCLIBC_HAVE_ASM_WEAKEXT_DIRECTIVE__
-+
-+/* needed probably only for ppc64 */
-+#undef __UCLIBC_HAVE_ASM_GLOBAL_DOT_NAME__
-+
-+/* define if target supports IEEE signed zero floats */
-+#define __UCLIBC_HAVE_SIGNED_ZERO__
-+
-+#endif /* _BITS_UCLIBC_ARCH_FEATURES_H */
-diff --git a/libc/sysdeps/linux/avr32/bits/wordsize.h b/libc/sysdeps/linux/avr32/bits/wordsize.h
-new file mode 100644
-index 0000000..1b5842a
---- /dev/null
-+++ b/libc/sysdeps/linux/avr32/bits/wordsize.h
-@@ -0,0 +1 @@
-+#define __WORDSIZE    32
-diff --git a/libc/sysdeps/linux/avr32/brk.c b/libc/sysdeps/linux/avr32/brk.c
-new file mode 100644
-index 0000000..a54b49a
---- /dev/null
-+++ b/libc/sysdeps/linux/avr32/brk.c
-@@ -0,0 +1,31 @@
-+/*
-+ * Copyright (C) 2004-2007 Atmel Corporation
-+ *
-+ * 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.
-+ */
-+#include <errno.h>
-+#include <unistd.h>
-+#include <sys/syscall.h>
-+
-+libc_hidden_proto(brk)
-+
-+void *__curbrk attribute_hidden = 0;
-+
-+int brk (void *addr)
-+{
-+      void *newbrk;
-+
-+      newbrk = (void *)INLINE_SYSCALL(brk, 1, addr);
-+
-+      __curbrk = newbrk;
-+
-+      if (newbrk < addr) {
-+              __set_errno (ENOMEM);
-+              return -1;
-+      }
-+
-+      return 0;
-+}
-+libc_hidden_def(brk)
-diff --git a/libc/sysdeps/linux/avr32/bsd-_setjmp.S b/libc/sysdeps/linux/avr32/bsd-_setjmp.S
-new file mode 100644
-index 0000000..be66a10
---- /dev/null
-+++ b/libc/sysdeps/linux/avr32/bsd-_setjmp.S
-@@ -0,0 +1,16 @@
-+/*
-+ * Copyright (C) 2004-2007 Atmel Corporation
-+ *
-+ * 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.
-+ */
-+
-+      /* This just does a tail-call to __sigsetjmp(env, 0) */
-+      .global _setjmp
-+      .type   _setjmp,"function"
-+      .align  1
-+_setjmp:
-+      mov     r11, 0
-+      bral    __GI___sigsetjmp
-+      .size   _setjmp, . - _setjmp
-diff --git a/libc/sysdeps/linux/avr32/bsd-setjmp.S b/libc/sysdeps/linux/avr32/bsd-setjmp.S
-new file mode 100644
-index 0000000..4635eeb
---- /dev/null
-+++ b/libc/sysdeps/linux/avr32/bsd-setjmp.S
-@@ -0,0 +1,16 @@
-+/*
-+ * Copyright (C) 2004-2007 Atmel Corporation
-+ *
-+ * 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.
-+ */
-+
-+      /* This just does a tail-call to __sigsetjmp(env, 1) */
-+      .global setjmp
-+      .type   setjmp,"function"
-+      .align  1
-+setjmp:
-+      mov     r11, 1
-+      bral    __GI___sigsetjmp
-+      .size   setjmp, . - setjmp
-diff --git a/libc/sysdeps/linux/avr32/clone.c b/libc/sysdeps/linux/avr32/clone.c
-new file mode 100644
-index 0000000..e43b0f3
---- /dev/null
-+++ b/libc/sysdeps/linux/avr32/clone.c
-@@ -0,0 +1,41 @@
-+/*
-+ * Copyright (C) 2004 Atmel Corporation
-+ *
-+ * 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.
-+ */
-+#include <errno.h>
-+#include <sys/syscall.h>
-+#include <unistd.h>
-+
-+/*
-+ * I don't know if we can be absolutely certain that the fn and arg
-+ * parameters are preserved when returning as the child. If the
-+ * compiler stores them in registers (r0-r7), they should be.
-+ */
-+int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg)
-+{
-+      register int (*_fn)(void *arg) = fn;
-+      register void *_arg = arg;
-+      int err;
-+
-+      /* Sanity check the arguments */
-+      err = -EINVAL;
-+      if (!fn)
-+              goto syscall_error;
-+      if (!child_stack)
-+              goto syscall_error;
-+
-+      err = INLINE_SYSCALL(clone, 2, flags, child_stack);
-+      if (err < 0)
-+              goto syscall_error;
-+      else if (err != 0)
-+              return err;
-+
-+      _exit(_fn(_arg));
-+
-+syscall_error:
-+      __set_errno (-err);
-+      return -1;
-+}
-diff --git a/libc/sysdeps/linux/avr32/crt1.S b/libc/sysdeps/linux/avr32/crt1.S
-new file mode 100644
-index 0000000..ca1fa7a
---- /dev/null
-+++ b/libc/sysdeps/linux/avr32/crt1.S
-@@ -0,0 +1,97 @@
-+/*
-+ * Copyright (C) 2004-2007 Atmel Corporation
-+ *
-+ * 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.
-+ *
-+ * When we enter _start, the stack looks like this:
-+ *    argc            argument counter
-+ *    argv[0]         pointer to program name
-+ *    argv[1..argc-1] pointers to program args
-+ *    NULL
-+ *    env[0..N]       pointers to environment variables
-+ *    NULL
-+ *
-+ * r12 contains a function pointer to be registered with `atexit'.
-+ * This is how the dynamic linker arranges to have DT_FINI functions
-+ * called for shared libraries that have been loaded before this
-+ * code runs.
-+ *
-+ * We're going to call the following function:
-+ * __uClibc_main(int (*main)(int, char **, char **), int argc,
-+ *             char **argv, void (*app_init)(void), void (*app_fini)(void),
-+ *             void (*rtld_fini)(void), void *stack_end)
-+ *
-+ * So we need to set up things as follows:
-+ *    r12 = address of main
-+ *    r11 = argc
-+ *    r10 = &argv[0]
-+ *    r9  = address of _init
-+ *    r8  = address of _fini
-+ *    sp[0] = whatever we got passed in r12
-+ */
-+
-+#include <features.h>
-+
-+      .text
-+      .global _start
-+      .type   _start, @function
-+_start:
-+      /* Clear the frame pointer and link register since this is the outermost frame.  */
-+      mov     r7, 0
-+      mov     lr, 0
-+
-+      ld.w    r11, sp++               /* argc         */
-+      mov     r10, sp                 /* &argv[0]     */
-+
-+      st.w    --sp, r10               /* stack_end */
-+      st.w    --sp, r12               /* rtld_fini */
-+
-+#ifdef __PIC__
-+      lddpc   r6, .L_GOT
-+.L_RGOT:
-+      rsub    r6, pc
-+      lda.w   r9, _init
-+      lda.w   r8, _fini
-+      lda.w   r12, main
-+
-+      /* Ok, now run uClibc's main() -- should not return */
-+      call    __uClibc_main
-+
-+      .align  2
-+.L_GOT:
-+      .long   .L_RGOT - _GLOBAL_OFFSET_TABLE_
-+#else
-+      lddpc   r9, __init_addr         /* app_init */
-+      lddpc   r8, __fini_addr         /* app_fini */
-+      lddpc   r12, __main_addr        /* main */
-+
-+      /* Ok, now run uClibc's main() -- should not return */
-+      lddpc   pc, ___uClibc_main_addr
-+
-+      .align  2
-+__init_addr:
-+      .long   _init
-+__fini_addr:
-+      .long   _fini
-+__main_addr:
-+      .long   main
-+___uClibc_main_addr:
-+      .long   __uClibc_main
-+#endif
-+      .size   _start, . - _start
-+
-+      /*
-+       * The LSB says we need this.
-+       */
-+      .section ".note.ABI-tag", "a"
-+      .align  4
-+      .long   2f - 1f         /* namesz */
-+      .long   4f - 3f         /* descsz */
-+      .long   1               /* type   */
-+1:    .asciz  "GNU"           /* name */
-+2:    .align  4
-+3:    .long   0               /* Linux executable */
-+      .long   2,6,0           /* Earliest compatible kernel */
-+4:    .align  4
-diff --git a/libc/sysdeps/linux/avr32/crti.S b/libc/sysdeps/linux/avr32/crti.S
-new file mode 100644
-index 0000000..3e132d0
---- /dev/null
-+++ b/libc/sysdeps/linux/avr32/crti.S
-@@ -0,0 +1,17 @@
-+
-+      .section .init
-+      .align  2
-+      .global _init
-+      .type   _init, @function
-+_init:
-+      /* Use a four-byte instruction to avoid NOPs */
-+      stm     --sp, r0-r7,lr
-+      .align  2
-+
-+      .section .fini
-+      .align  2
-+      .global _fini
-+      .type   _fini, @function
-+_fini:
-+      stm     --sp, r0-r7,lr
-+      .align  2
-diff --git a/libc/sysdeps/linux/avr32/crtn.S b/libc/sysdeps/linux/avr32/crtn.S
-new file mode 100644
-index 0000000..577adcc
---- /dev/null
-+++ b/libc/sysdeps/linux/avr32/crtn.S
-@@ -0,0 +1,14 @@
-+
-+      .section .init
-+      .align  2
-+      .global _init
-+      .type   _init, @function
-+      ldm     sp++, r0-r7,pc
-+      .size   _init, . - _init
-+
-+      .section .fini
-+      .align  2
-+      .global _fini
-+      .type   _fini, @function
-+      ldm     sp++, r0-r7,pc
-+      .size   _fini, . - _fini
-diff --git a/libc/sysdeps/linux/avr32/mmap.c b/libc/sysdeps/linux/avr32/mmap.c
-new file mode 100644
-index 0000000..2ee025a
---- /dev/null
-+++ b/libc/sysdeps/linux/avr32/mmap.c
-@@ -0,0 +1,33 @@
-+/*
-+ * Copyright (C) 2004-2007 Atmel Corporation
-+ *
-+ * 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.
-+ */
-+
-+#include <errno.h>
-+#include <unistd.h>
-+#include <sys/mman.h>
-+#include <sys/syscall.h>
-+
-+libc_hidden_proto(mmap)
-+
-+static _syscall6(__ptr_t, mmap2, __ptr_t, addr, size_t, len, int, prot,
-+               int, flags, int, fd, __off_t, pgoff);
-+
-+__ptr_t mmap(__ptr_t addr, size_t len, int prot, int flags, int fd, __off_t offset)
-+{
-+      unsigned long page_size = sysconf(_SC_PAGESIZE);
-+      unsigned long pgoff;
-+
-+      if (offset & (page_size - 1)) {
-+              __set_errno(EINVAL);
-+              return MAP_FAILED;
-+      }
-+
-+      pgoff = (unsigned long)offset >> (31 - __builtin_clz(page_size));
-+
-+      return mmap2(addr, len, prot, flags, fd, pgoff);
-+}
-+libc_hidden_def(mmap)
-diff --git a/libc/sysdeps/linux/avr32/setjmp.S b/libc/sysdeps/linux/avr32/setjmp.S
-new file mode 100644
-index 0000000..7d0354b
---- /dev/null
-+++ b/libc/sysdeps/linux/avr32/setjmp.S
-@@ -0,0 +1,29 @@
-+/*
-+ * Copyright (C) 2004-2007 Atmel Corporation
-+ *
-+ * 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.
-+ */
-+#define _SETJMP_H
-+#define _ASM
-+#include <bits/setjmp.h>
-+
-+      .text
-+
-+      .global __sigsetjmp
-+      .type   __sigsetjmp,"function"
-+
-+      .align  1
-+__sigsetjmp:
-+      mustr   r8
-+      stm     r12, r0,r1,r2,r3,r4,r5,r6,r7,r8,sp,lr
-+
-+      /*
-+       * Make a tail call to __sigjmp_save; it takes the same args
-+       * and is hidden so we don't need to mess around with the GOT.
-+       */
-+      rjmp    __sigjmp_save
-+      .size   __sigsetjmp, . - __sigsetjmp
-+
-+libc_hidden_def(__sigsetjmp)
-diff --git a/libc/sysdeps/linux/avr32/sigaction.c b/libc/sysdeps/linux/avr32/sigaction.c
-new file mode 100644
-index 0000000..a97ff3d
---- /dev/null
-+++ b/libc/sysdeps/linux/avr32/sigaction.c
-@@ -0,0 +1,59 @@
-+/*
-+ * Copyright (C) 2004-2007 Atmel Corporation
-+ *
-+ * 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.
-+ */
-+#include <errno.h>
-+#include <signal.h>
-+#include <string.h>
-+#include <sys/syscall.h>
-+#include <bits/kernel_sigaction.h>
-+
-+#define SA_RESTORER   0x04000000
-+extern void __default_rt_sa_restorer(void);
-+
-+libc_hidden_proto(memcpy)
-+
-+/*
-+ * If act is not NULL, change the action for sig to *act.
-+ * If oact is not NULL, put the old action for sig in *oact.
-+ */
-+int __libc_sigaction(int signum, const struct sigaction *act,
-+                   struct sigaction *oldact)
-+{
-+      struct kernel_sigaction kact, koact;
-+      int result;
-+
-+      if (act) {
-+              kact.k_sa_handler = act->sa_handler;
-+              memcpy(&kact.sa_mask, &act->sa_mask, sizeof (kact.sa_mask));
-+              kact.sa_flags = act->sa_flags;
-+              if (kact.sa_flags & (SA_RESTORER | SA_ONSTACK))
-+                      kact.sa_restorer = act->sa_restorer;
-+              else
-+                      kact.sa_restorer = __default_rt_sa_restorer;
-+              kact.sa_flags |= SA_RESTORER;
-+      }
-+
-+      result = __syscall_rt_sigaction(signum, act ? __ptrvalue(&kact) : NULL,
-+                                      oldact ? __ptrvalue(&koact) : NULL,
-+                                      _NSIG / 8);
-+
-+      if (oldact && result >= 0) {
-+              oldact->sa_handler = koact.k_sa_handler;
-+              memcpy(&oldact->sa_mask, &koact.sa_mask,
-+                     sizeof(oldact->sa_mask));
-+              oldact->sa_flags = koact.sa_flags;
-+              oldact->sa_restorer = koact.sa_restorer;
-+      }
-+
-+      return result;
-+}
-+
-+#ifndef LIBC_SIGACTION
-+libc_hidden_proto(sigaction)
-+weak_alias(__libc_sigaction, sigaction)
-+libc_hidden_weak(sigaction)
-+#endif
-diff --git a/libc/sysdeps/linux/avr32/sigrestorer.S b/libc/sysdeps/linux/avr32/sigrestorer.S
-new file mode 100644
-index 0000000..df6a1ba
---- /dev/null
-+++ b/libc/sysdeps/linux/avr32/sigrestorer.S
-@@ -0,0 +1,15 @@
-+/*
-+ * Copyright (C) 2004 Atmel Corporation
-+ *
-+ * 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.
-+ */
-+#include <sys/syscall.h>
-+
-+      .global __default_rt_sa_restorer
-+      .type   __default_rt_sa_restorer,"function"
-+      .align  1
-+__default_rt_sa_restorer:
-+      mov     r8, __NR_rt_sigreturn
-+      scall
-diff --git a/libc/sysdeps/linux/avr32/sys/elf.h b/libc/sysdeps/linux/avr32/sys/elf.h
-new file mode 100644
-index 0000000..faa7310
---- /dev/null
-+++ b/libc/sysdeps/linux/avr32/sys/elf.h
-@@ -0,0 +1,26 @@
-+/* Copyright (C) 1996, 1997, 1999, 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.  */
-+
-+#ifndef _SYS_ELF_H
-+#define _SYS_ELF_H    1
-+
-+#warning "This header is obsolete; use <sys/procfs.h> instead."
-+
-+#include <sys/procfs.h>
-+
-+#endif        /* sys/elf.h */
-diff --git a/libc/sysdeps/linux/avr32/sys/procfs.h b/libc/sysdeps/linux/avr32/sys/procfs.h
-new file mode 100644
-index 0000000..3b37363
---- /dev/null
-+++ b/libc/sysdeps/linux/avr32/sys/procfs.h
-@@ -0,0 +1,123 @@
-+/* Copyright (C) 1996, 1997, 1999, 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.  */
-+
-+#ifndef _SYS_PROCFS_H
-+#define _SYS_PROCFS_H 1
-+
-+/* This is somewhat modelled after the file of the same name on SVR4
-+   systems.  It provides a definition of the core file format for ELF
-+   used on Linux.  It doesn't have anything to do with the /proc file
-+   system, even though Linux has one.
-+
-+   Anyway, the whole purpose of this file is for GDB and GDB only.
-+   Don't read too much into it.  Don't use it for anything other than
-+   GDB unless you know what you are doing.  */
-+
-+#include <features.h>
-+#include <sys/time.h>
-+#include <sys/types.h>
-+#include <sys/user.h>
-+
-+__BEGIN_DECLS
-+
-+/* Type for a general-purpose register.  */
-+typedef unsigned long elf_greg_t;
-+
-+/* And the whole bunch of them.  We could have used `struct
-+   user_regs' directly in the typedef, but tradition says that
-+   the register set is an array, which does have some peculiar
-+   semantics, so leave it that way.  */
-+#define ELF_NGREG (sizeof (struct user_regs) / sizeof(elf_greg_t))
-+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
-+
-+/* Register set for the floating-point registers.  */
-+typedef struct user_fpregs elf_fpregset_t;
-+
-+/* Signal info.  */
-+struct elf_siginfo
-+  {
-+    int si_signo;                     /* Signal number.  */
-+    int si_code;                      /* Extra code.  */
-+    int si_errno;                     /* Errno.  */
-+  };
-+
-+/* Definitions to generate Intel SVR4-like core files.  These mostly
-+   have the same names as the SVR4 types with "elf_" tacked on the
-+   front to prevent clashes with Linux definitions, and the typedef
-+   forms have been avoided.  This is mostly like the SVR4 structure,
-+   but more Linuxy, with things that Linux does not support and which
-+   GDB doesn't really use excluded.  */
-+
-+struct elf_prstatus
-+  {
-+    struct elf_siginfo pr_info;               /* Info associated with signal.  */
-+    short int pr_cursig;              /* Current signal.  */
-+    unsigned long int pr_sigpend;     /* Set of pending signals.  */
-+    unsigned long int pr_sighold;     /* Set of held signals.  */
-+    __pid_t pr_pid;
-+    __pid_t pr_ppid;
-+    __pid_t pr_pgrp;
-+    __pid_t pr_sid;
-+    struct timeval pr_utime;          /* User time.  */
-+    struct timeval pr_stime;          /* System time.  */
-+    struct timeval pr_cutime;         /* Cumulative user time.  */
-+    struct timeval pr_cstime;         /* Cumulative system time.  */
-+    elf_gregset_t pr_reg;             /* GP registers.  */
-+    int pr_fpvalid;                   /* True if math copro being used.  */
-+  };
-+
-+
-+#define ELF_PRARGSZ     (80)    /* Number of chars for args.  */
-+
-+struct elf_prpsinfo
-+  {
-+    char pr_state;                    /* Numeric process state.  */
-+    char pr_sname;                    /* Char for pr_state.  */
-+    char pr_zomb;                     /* Zombie.  */
-+    char pr_nice;                     /* Nice val.  */
-+    unsigned long int pr_flag;                /* Flags.  */
-+    unsigned short int pr_uid;
-+    unsigned short int pr_gid;
-+    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
-+    /* Lots missing */
-+    char pr_fname[16];                        /* Filename of executable.  */
-+    char pr_psargs[ELF_PRARGSZ];      /* Initial part of arg list.  */
-+  };
-+
-+/* The rest of this file provides the types for emulation of the
-+   Solaris <proc_service.h> interfaces that should be implemented by
-+   users of libthread_db.  */
-+
-+/* Addresses.  */
-+typedef void *psaddr_t;
-+
-+/* Register sets.  Linux has different names.  */
-+typedef elf_gregset_t prgregset_t;
-+typedef elf_fpregset_t prfpregset_t;
-+
-+/* We don't have any differences between processes and threads,
-+   therefore have only one PID type.  */
-+typedef __pid_t lwpid_t;
-+
-+/* Process status and info.  In the end we do provide typedefs for them.  */
-+typedef struct elf_prstatus prstatus_t;
-+typedef struct elf_prpsinfo prpsinfo_t;
-+
-+__END_DECLS
-+
-+#endif        /* sys/procfs.h */
-diff --git a/libc/sysdeps/linux/avr32/sys/ucontext.h b/libc/sysdeps/linux/avr32/sys/ucontext.h
-new file mode 100644
-index 0000000..82c7fe2
---- /dev/null
-+++ b/libc/sysdeps/linux/avr32/sys/ucontext.h
-@@ -0,0 +1,90 @@
-+/* Copyright (C) 1998, 1999, 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.  */
-+
-+/* Linux/AVR32 ABI compliant context switching support.  */
-+
-+#ifndef _SYS_UCONTEXT_H
-+#define _SYS_UCONTEXT_H       1
-+
-+#include <features.h>
-+#include <signal.h>
-+#include <sys/procfs.h>
-+#include <bits/sigcontext.h>
-+
-+typedef int greg_t;
-+
-+/* Number of general registers.  */
-+#define NGREG 16
-+
-+/* Container for all general registers.  */
-+typedef elf_gregset_t gregset_t;
-+
-+/* Number of each register is the `gregset_t' array.  */
-+enum
-+{
-+  R0 = 0,
-+#define R0    R0
-+  R1 = 1,
-+#define R1    R1
-+  R2 = 2,
-+#define R2    R2
-+  R3 = 3,
-+#define R3    R3
-+  R4 = 4,
-+#define R4    R4
-+  R5 = 5,
-+#define R5    R5
-+  R6 = 6,
-+#define R6    R6
-+  R7 = 7,
-+#define R7    R7
-+  R8 = 8,
-+#define R8    R8
-+  R9 = 9,
-+#define R9    R9
-+  R10 = 10,
-+#define R10   R10
-+  R11 = 11,
-+#define R11   R11
-+  R12 = 12,
-+#define R12   R12
-+  R13 = 13,
-+#define R13   R13
-+  R14 = 14,
-+#define R14   R14
-+  R15 = 15
-+#define R15   R15
-+};
-+
-+/* Structure to describe FPU registers.  */
-+typedef elf_fpregset_t        fpregset_t;
-+
-+/* Context to describe whole processor state.  */
-+typedef struct sigcontext mcontext_t;
-+
-+/* Userlevel context.  */
-+typedef struct ucontext
-+{
-+      unsigned long   uc_flags;
-+      struct ucontext *uc_link;
-+      stack_t         uc_stack;
-+      mcontext_t      uc_mcontext;
-+      sigset_t        uc_sigmask;   /* mask last for extensibility */
-+} ucontext_t;
-+
-+#endif /* sys/ucontext.h */
-diff --git a/libc/sysdeps/linux/avr32/sys/user.h b/libc/sysdeps/linux/avr32/sys/user.h
-new file mode 100644
-index 0000000..c0b3d38
---- /dev/null
-+++ b/libc/sysdeps/linux/avr32/sys/user.h
-@@ -0,0 +1,46 @@
-+#ifndef _SYS_USER_H
-+#define _SYS_USER_H
-+
-+struct user_fpregs
-+{
-+
-+};
-+
-+struct user_regs
-+{
-+      unsigned long sr;
-+      unsigned long pc;
-+      unsigned long lr;
-+      unsigned long sp;
-+      unsigned long r12;
-+      unsigned long r11;
-+      unsigned long r10;
-+      unsigned long r9;
-+      unsigned long r8;
-+      unsigned long r7;
-+      unsigned long r6;
-+      unsigned long r5;
-+      unsigned long r4;
-+      unsigned long r3;
-+      unsigned long r2;
-+      unsigned long r1;
-+      unsigned long r0;
-+      unsigned long r12_orig;
-+};
-+
-+struct user
-+{
-+      struct user_regs        regs;           /* general registers */
-+      size_t                  u_tsize;        /* text size (pages) */
-+      size_t                  u_dsize;        /* data size (pages) */
-+      size_t                  u_ssize;        /* stack size (pages) */
-+      unsigned long           start_code;     /* text starting address */
-+      unsigned long           start_data;     /* data starting address */
-+      unsigned long           start_stack;    /* stack starting address */
-+      long int                signal;         /* signal causing core dump */
-+      struct user_regs *      u_ar0;          /* help gdb find registers */
-+      unsigned long           magic;          /* identifies a core file */
-+      char                    u_comm[32];     /* user command name */
-+};
-+
-+#endif /* _SYS_USER_H */
-diff --git a/libc/sysdeps/linux/avr32/syscall.S b/libc/sysdeps/linux/avr32/syscall.S
-new file mode 100644
-index 0000000..55c1b1f
---- /dev/null
-+++ b/libc/sysdeps/linux/avr32/syscall.S
-@@ -0,0 +1,71 @@
-+/*
-+ * Copyright (C) 2004-2007 Atmel Corporation
-+ *
-+ * 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.
-+ */
-+#include <features.h>
-+
-+      .text
-+
-+      /*
-+       * long int syscall(long int sysno, ...)
-+       */
-+      .global syscall
-+      .type   syscall, @function
-+      .align  2
-+syscall:
-+      stm     --sp, r3,r5,r6,lr
-+      sub     lr, sp, -16
-+      mov     r8, r12
-+      ldm     lr, r3,r5,r9-r12
-+      scall
-+      cp.w    r12, -4095
-+      brlo    .Ldone
-+
-+#ifdef __PIC__
-+      lddpc   r6, .Lgot
-+.Lgotcalc:
-+      rsub    r6, pc
-+# ifdef __UCLIBC_HAS_THREADS__
-+      rsub    r3, r12, 0
-+      mcall   r6[__errno_location@got]
-+      st.w    r12[0], r3
-+# else
-+      ld.w    r3, r6[errno@got]
-+      neg     r12
-+      st.w    r3[0], r12
-+# endif
-+#else
-+# ifdef __UCLIBC_HAS_THREADS__
-+      rsub    r3, r12, 0
-+      mcall   .Lerrno_location
-+      st.w    r12[0], r3
-+# else
-+      lddpc   r3, .Lerrno
-+      neg     r12
-+      st.w    r3[0], r12
-+# endif
-+#endif
-+      mov     r12, -1
-+
-+.Ldone:
-+      ldm     sp++, r3,r5,r6,pc
-+
-+      .align  2
-+#ifdef __PIC__
-+.Lgot:
-+      .long   .Lgotcalc - _GLOBAL_OFFSET_TABLE_
-+#else
-+# ifdef __UCLIBC_HAS_THREADS__
-+.Lerrno_location:
-+      .long   __errno_location
-+# else
-+.Lerrno:
-+      .long   errno
-+# endif
-+#endif
-+
-+
-+      .size   syscall, . - syscall
-diff --git a/libc/sysdeps/linux/avr32/vfork.S b/libc/sysdeps/linux/avr32/vfork.S
-new file mode 100644
-index 0000000..03ca99f
---- /dev/null
-+++ b/libc/sysdeps/linux/avr32/vfork.S
-@@ -0,0 +1,58 @@
-+/*
-+ * Copyright (C) 2005 Atmel Corporation
-+ *
-+ * 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.
-+ */
-+
-+/*
-+ * Clone the process without copying the address space.  The
-+ * calling process is suspended until the child either exits
-+ * or calls execve.
-+ *
-+ * This all means that we cannot rely on the stack to store
-+ * away registers, since they will be overwritten by the child
-+ * as soon as it makes another function call (e.g. execve()).
-+ * Fortunately, the Linux kernel preserves LR across system calls.
-+ */
-+
-+#include <features.h>
-+#include <sys/syscall.h>
-+
-+      .global __vfork
-+      .type   __vfork,@function
-+      .align  1
-+__vfork:
-+      mov     r8, __NR_vfork
-+      scall
-+      cp.w    r12, -4096
-+      retls   r12
-+
-+      /* vfork failed, so we may use the stack freely */
-+      pushm   r4-r7,lr
-+#ifdef __PIC__
-+      lddpc   r6, .L_GOT
-+      rsub    r4, r12, 0
-+.L_RGOT:
-+      rsub    r6, pc
-+      mcall   r6[__errno_location@got]
-+#else
-+      rsub    r4, r12, 0
-+      mcall   .L__errno_location
-+#endif
-+      st.w    r12[0], r4
-+      popm    r4-r7,pc,r12=-1
-+
-+      .align  2
-+#ifdef __PIC__
-+.L_GOT:
-+      .long   .L_RGOT - _GLOBAL_OFFSET_TABLE_
-+#else
-+.L__errno_location:
-+      .long   __errno_location
-+#endif
-+      .size   __vfork, . - __vfork
-+
-+weak_alias(__vfork,vfork)
-+libc_hidden_weak(vfork)
-diff --git a/libpthread/linuxthreads.old/sysdeps/avr32/pt-machine.h b/libpthread/linuxthreads.old/sysdeps/avr32/pt-machine.h
-new file mode 100644
-index 0000000..2e8a33b
---- /dev/null
-+++ b/libpthread/linuxthreads.old/sysdeps/avr32/pt-machine.h
-@@ -0,0 +1,73 @@
-+/* Machine-dependent pthreads configuration and inline functions.
-+ *
-+ * Copyright (C) 2005-2007 Atmel Corporation
-+ *
-+ * 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.
-+ */
-+#ifndef _PT_MACHINE_H
-+#define _PT_MACHINE_H   1
-+
-+#include <features.h>
-+
-+static inline int
-+_test_and_set (int *p, int v)
-+{
-+      int result;
-+
-+      __asm__ __volatile__(
-+              "/* Inline test and set */\n"
-+              "       xchg    %[old], %[mem], %[new]"
-+              : [old] "=&r"(result)
-+              : [mem] "r"(p), [new] "r"(v)
-+              : "memory");
-+
-+      return result;
-+}
-+
-+#ifndef PT_EI
-+# define PT_EI extern inline
-+#endif
-+
-+extern long int testandset (int *spinlock);
-+extern int __compare_and_swap (long int *p, long int oldval, long int newval);
-+
-+/* Spinlock implementation; required.  */
-+PT_EI long int
-+testandset (int *spinlock)
-+{
-+      return _test_and_set(spinlock, 1);
-+}
-+
-+
-+/* Get some notion of the current stack.  Need not be exactly the top
-+   of the stack, just something somewhere in the current frame.  */
-+#define CURRENT_STACK_FRAME  stack_pointer
-+register char * stack_pointer __asm__ ("sp");
-+
-+/* Compare-and-swap for semaphores. */
-+
-+#define HAS_COMPARE_AND_SWAP
-+PT_EI int
-+__compare_and_swap(long int *p, long int oldval, long int newval)
-+{
-+      long int result;
-+
-+      __asm__ __volatile__(
-+              "/* Inline compare and swap */\n"
-+              "1:     ssrf    5\n"
-+              "       ld.w    %[result], %[mem]\n"
-+              "       eor     %[result], %[old]\n"
-+              "       brne    2f\n"
-+              "       stcond  %[mem], %[new]\n"
-+              "       brne    1b\n"
-+              "2:"
-+              : [result] "=&r"(result), [mem] "=m"(*p)
-+              : "m"(*p), [new] "r"(newval), [old] "r"(oldval)
-+              : "cc", "memory");
-+
-+      return result;
-+}
-+
-+#endif /* pt-machine.h */
-diff --git a/libpthread/linuxthreads/sysdeps/avr32/pt-machine.h b/libpthread/linuxthreads/sysdeps/avr32/pt-machine.h
-new file mode 100644
-index 0000000..fe12bf8
---- /dev/null
-+++ b/libpthread/linuxthreads/sysdeps/avr32/pt-machine.h
-@@ -0,0 +1,73 @@
-+/* Machine-dependent pthreads configuration and inline functions.
-+ *
-+ * Copyright (C) 2005-2007 Atmel Corporation
-+ *
-+ * 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.
-+ */
-+#ifndef _PT_MACHINE_H
-+#define _PT_MACHINE_H   1
-+
-+#include <features.h>
-+
-+static inline int
-+_test_and_set (int *p, int v) __THROW
-+{
-+      int result;
-+
-+      __asm__ __volatile__(
-+              "/* Inline test and set */\n"
-+              "       xchg    %[old], %[mem], %[new]"
-+              : [old] "=&r"(result)
-+              : [mem] "r"(p), [new] "r"(v)
-+              : "memory");
-+
-+      return result;
-+}
-+
-+#ifndef PT_EI
-+# define PT_EI extern inline
-+#endif
-+
-+extern long int testandset (int *spinlock);
-+extern int __compare_and_swap (long int *p, long int oldval, long int newval);
-+
-+/* Spinlock implementation; required.  */
-+PT_EI long int
-+testandset (int *spinlock)
-+{
-+      return _test_and_set(spinlock, 1);
-+}
-+
-+
-+/* Get some notion of the current stack.  Need not be exactly the top
-+   of the stack, just something somewhere in the current frame.  */
-+#define CURRENT_STACK_FRAME  stack_pointer
-+register char * stack_pointer __asm__ ("sp");
-+
-+/* Compare-and-swap for semaphores. */
-+
-+#define HAS_COMPARE_AND_SWAP
-+PT_EI int
-+__compare_and_swap(long int *p, long int oldval, long int newval)
-+{
-+      int result;
-+
-+      __asm__ __volatile__(
-+              "/* Inline compare and swap */\n"
-+              "1:     ssrf    5\n"
-+              "       ld.w    %[result], %[mem]\n"
-+              "       eor     %[result], %[old]\n"
-+              "       brne    2f\n"
-+              "       stcond  %[mem], %[new]\n"
-+              "       brne    1b\n"
-+              "2:"
-+              : [result] "=&r"(result), [mem] "=m"(*p)
-+              : "m"(*p), [new] "r"(newval), [old] "r"(oldval)
-+              : "cc", "memory");
-+
-+      return result == 0;
-+}
-+
-+#endif /* pt-machine.h */
-diff --git a/utils/ldd.c b/utils/ldd.c
-index 75ad628..e34acd9 100644
---- a/utils/ldd.c
-+++ b/utils/ldd.c
-@@ -44,6 +44,11 @@
- #define ELFCLASSM     ELFCLASS32
- #endif
-+#if defined(__avr32__)
-+#define MATCH_MACHINE(x) (x == EM_AVR32)
-+#define ELFCLASSM     ELFCLASS32
-+#endif
-+
- #if defined(__s390__)
- #define MATCH_MACHINE(x) (x == EM_S390)
- #define ELFCLASSM     ELFCLASS32
diff --git a/toolchain/uClibc/uClibc-0.9.29-fix-inverted-login-in-compare_and_swap-in-linuxthreads.patch b/toolchain/uClibc/uClibc-0.9.29-fix-inverted-login-in-compare_and_swap-in-linuxthreads.patch
deleted file mode 100644 (file)
index 0cb0d17..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-From: Haavard Skinnemoen <hskinnemoen@atmel.com>
-Date: Wed, 19 Sep 2007 10:03:36 +0200
-Subject: [Avr-gnu-toolchain] [uClibc PATCH] Fix inverted logic in
-       __compare_and_swap in linuxthreads.old
-
-If the old value equals the value in memory, the result should be
-TRUE, not FALSE.
-
-Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
----
- .../linuxthreads.old/sysdeps/avr32/pt-machine.h    |    2 +-
- 1 files changed, 1 insertions(+), 1 deletions(-)
-
-diff --git a/libpthread/linuxthreads.old/sysdeps/avr32/pt-machine.h b/libpthread/linuxthreads.old/sysdeps/avr32/pt-machine.h
-index 2e8a33b..eccf329 100644
---- a/libpthread/linuxthreads.old/sysdeps/avr32/pt-machine.h
-+++ b/libpthread/linuxthreads.old/sysdeps/avr32/pt-machine.h
-@@ -67,7 +67,7 @@ __compare_and_swap(long int *p, long int oldval, long int newval)
-               : "m"(*p), [new] "r"(newval), [old] "r"(oldval)
-               : "cc", "memory");
--      return result;
-+      return result == 0;
- }
- #endif /* pt-machine.h */
--- 
-1.5.3.1
diff --git a/toolchain/uClibc/uClibc-0.9.29-fix-resolve-in-etc-hosts.patch b/toolchain/uClibc/uClibc-0.9.29-fix-resolve-in-etc-hosts.patch
deleted file mode 100644 (file)
index a64bd4c..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-From 91cb4bb00e4d9463c0d41015152daa4b39acf762 Mon Sep 17 00:00:00 2001
-From: Hans-Christian Egtvedt <hcegtvedt@atmel.com>
-Date: Tue, 18 Sep 2007 10:15:05 +0200
-Subject: [PATCH] Fix resolve when identical IPv4 and IPv6 hosts are defined in /etc/hosts
-
-This patch will fix a problem when the same host is defined with both IPv4 and
-IPv6 entries in /etc/hosts. Previous only the first of these host would work,
-as uClibc would read the /etc/hosts file from top to bottom, failing if the
-first hit did not match the IP type.
-
-Now uClibc will continue reading, even if the first correct entry name, but wrong IP
-type fails. Thus, allowing a second correct entry name with correct IP type
-will result in a name resolve.
-
-Signed-off-by: Hans-Christian Egtvedt <hcegtvedt@atmel.com>
----
- libc/inet/resolv.c |    6 +++---
- 1 files changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c
-index f4e6cac..9cdc3fe 100644
---- a/libc/inet/resolv.c
-+++ b/libc/inet/resolv.c
-@@ -1643,7 +1643,7 @@ int attribute_hidden __read_etc_hosts_r(FILE * fp, const char * name, int type,
-                       *result=result_buf;
-                       ret=NETDB_SUCCESS;
- #ifdef __UCLIBC_HAS_IPV6__
--        } else if (type == AF_INET6 && inet_pton(AF_INET6, alias[0], in6) > 0) {
-+              } else if (type == AF_INET6 && inet_pton(AF_INET6, alias[0], in6) > 0) {
-                       DPRINTF("Found INET6\n");
-                       addr_list6[0] = in6;
-                       addr_list6[1] = 0;
-@@ -1658,8 +1658,8 @@ int attribute_hidden __read_etc_hosts_r(FILE * fp, const char * name, int type,
-               } else {
-                       DPRINTF("Error\n");
-                       ret=TRY_AGAIN;
--                      break; /* bad ip address */
--        }
-+                      continue; /* bad ip address, keep searching */
-+              }
-               if (action!=GETHOSTENT) {
-                       fclose(fp);
--- 
-1.5.2.5
-
diff --git a/toolchain/uClibc/uClibc-0.9.29-linuxthreads.patch b/toolchain/uClibc/uClibc-0.9.29-linuxthreads.patch
new file mode 100644 (file)
index 0000000..8ce2439
--- /dev/null
@@ -0,0 +1,145 @@
+--- a/libpthread/linuxthreads.old/attr.c       2006-01-24 12:41:01.000000000 -0500
++++ b/libpthread/linuxthreads.old/attr.c       2008-02-10 11:35:32.000000000 -0500
+@@ -25,6 +25,14 @@
+ #include "pthread.h"
+ #include "internals.h"
++#include <sys/resource.h>
++#include <inttypes.h>
++#include <stdio.h>
++#include <stdio_ext.h>
++#include <stdlib.h>
++#include <sys/resource.h>
++
++
+ /* NOTE: With uClibc I don't think we need this versioning stuff.
+  * Therefore, define the function pthread_attr_init() here using
+  * a strong symbol. */
+@@ -209,4 +217,94 @@ int __pthread_attr_getstacksize(const pt
+   *stacksize = attr->__stacksize;
+   return 0;
+ }
++
++
++extern int *__libc_stack_end;
++
+ weak_alias (__pthread_attr_getstacksize, pthread_attr_getstacksize)
++void* pthread_getattr_np(pthread_t thread, pthread_attr_t *attr)
++{
++    static void *stackBase = 0;
++    static size_t stackSize = 0;
++    int ret = 0;
++    /* Stack size limit.  */
++    struct rlimit rl;
++
++    /* The safest way to get the top of the stack is to read
++    /proc/self/maps and locate the line into which
++    __libc_stack_end falls.  */
++    FILE *fp = fopen("/proc/self/maps", "rc");
++    if (fp == NULL)
++        ret = errno;
++    /* We need the limit of the stack in any case.  */
++    else if (getrlimit (RLIMIT_STACK, &rl) != 0)
++        ret = errno;
++    else {
++        /* We need no locking.  */
++        __fsetlocking (fp, FSETLOCKING_BYCALLER);
++
++        /* Until we found an entry (which should always be the case)
++        mark the result as a failure.  */
++        ret = ENOENT;
++
++        char *line = NULL;
++        size_t linelen = 0;
++        uintptr_t last_to = 0;
++
++        while (! feof_unlocked (fp)) {
++            if (getdelim (&line, &linelen, '\n', fp) <= 0)
++                break;
++
++            uintptr_t from;
++            uintptr_t to;
++            if (sscanf (line, "%x-%x", &from, &to) != 2)
++                continue;
++            if (from <= (uintptr_t) __libc_stack_end
++            && (uintptr_t) __libc_stack_end < to) {
++                /* Found the entry.  Now we have the info we need.  */
++                attr->__stacksize = rl.rlim_cur;
++#ifdef _STACK_GROWS_UP
++                /* Don't check to enforce a limit on the __stacksize */
++                attr->__stackaddr = (void *) from;
++#else
++                attr->__stackaddr = (void *) to;
++
++                /* The limit might be too high.  */
++                if ((size_t) attr->__stacksize > (size_t) attr->__stackaddr - last_to)
++                    attr->__stacksize = (size_t) attr->__stackaddr - last_to;
++#endif
++
++                /* We succeed and no need to look further.  */
++                ret = 0;
++                break;
++            }
++            last_to = to;
++        }
++
++        fclose (fp);
++        free (line);
++    }
++#ifndef _STACK_GROWS_UP
++    stackBase = (char *) attr->__stackaddr - attr->__stacksize;
++#else
++    stackBase = attr->__stackaddr;
++#endif
++    stackSize = attr->__stacksize;
++    return (void*)(stackBase + stackSize);
++}
++
++int __pthread_attr_getstack (const pthread_attr_t *attr, void **stackaddr,
++                           size_t *stacksize)
++{
++  /* XXX This function has a stupid definition.  The standard specifies
++     no error value but what is if no stack address was set?  We simply
++     return the value we have in the member.  */
++#ifndef _STACK_GROWS_UP
++  *stackaddr = (char *) attr->__stackaddr - attr->__stacksize;
++#else
++  *stackaddr = attr->__stackaddr;
++#endif
++  *stacksize = attr->__stacksize;
++  return 0;
++}
++weak_alias (__pthread_attr_getstack, pthread_attr_getstack)
+
+--- a/libpthread/linuxthreads.old/sysdeps/pthread/pthread.h    2006-12-07 22:19:36.000000000 -0500
++++ b/libpthread/linuxthreads.old/sysdeps/pthread/pthread.h    2008-02-10 11:42:35.000000000 -0500
+@@ -288,15 +288,11 @@ extern int pthread_attr_getstacksize (__
+                                     __attr, size_t *__restrict __stacksize)
+      __THROW;
+-#if 0
+-/* Not yet implemented in uClibc! */
+-
+ #ifdef __USE_GNU
+ /* Initialize thread attribute *ATTR with attributes corresponding to the
+    already running thread TH.  It shall be called on unitialized ATTR
+    and destroyed with pthread_attr_destroy when no longer needed.  */
+-extern int pthread_getattr_np (pthread_t __th, pthread_attr_t *__attr) __THROW;
+-#endif
++extern void* pthread_getattr_np(pthread_t thread, pthread_attr_t *attr);
+ #endif
+ /* Functions for scheduling control.  */
+@@ -599,6 +595,11 @@ extern int pthread_cancel (pthread_t __c
+    cancelled.  */
+ extern void pthread_testcancel (void);
++/* Return the previously set address for the stack.  */
++extern int pthread_attr_getstack (__const pthread_attr_t *__restrict __attr,
++                                void **__restrict __stackaddr,
++                                size_t *__restrict __stacksize) __THROW;
++
+ /* Install a cleanup handler: ROUTINE will be called with arguments ARG
+    when the thread is cancelled or calls pthread_exit.  ROUTINE will also
+
diff --git a/toolchain/uClibc/uClibc-0.9.29-load-got-pointer-at-the-beginning-of-init-and-fini.patch b/toolchain/uClibc/uClibc-0.9.29-load-got-pointer-at-the-beginning-of-init-and-fini.patch
deleted file mode 100644 (file)
index 27aa5a5..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-From: Haavard Skinnemoen <hskinnemoen@atmel.com>
-Date: Wed, 19 Sep 2007 10:03:35 +0200
-Subject: [Avr-gnu-toolchain] [uClibc PATCH] Load GOT pointer at the
-       beginning of .init and .fini
-
-I don't know why this seems to have worked before, but the .init and
-.fini sections typically consist of a bunch of mcalls using r6 as the
-base pointer. This can cause "interesting" behaviour when r6 hasn't
-been initialized to point to the GOT.
-
-Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
----
- libc/sysdeps/linux/avr32/crti.S |   15 ++++++++++++---
- libc/sysdeps/linux/avr32/crtn.S |    4 ++--
- 2 files changed, 14 insertions(+), 5 deletions(-)
-
-diff --git a/libc/sysdeps/linux/avr32/crti.S b/libc/sysdeps/linux/avr32/crti.S
-index 3e132d0..660f47c 100644
---- a/libc/sysdeps/linux/avr32/crti.S
-+++ b/libc/sysdeps/linux/avr32/crti.S
-@@ -4,14 +4,23 @@
-       .global _init
-       .type   _init, @function
- _init:
--      /* Use a four-byte instruction to avoid NOPs */
--      stm     --sp, r0-r7,lr
-+      stm     --sp, r6, lr
-+      lddpc   r6, 2f
-+1:    rsub    r6, pc
-+      rjmp    3f
-       .align  2
-+2:    .long   1b - _GLOBAL_OFFSET_TABLE_
-+3:
-       .section .fini
-       .align  2
-       .global _fini
-       .type   _fini, @function
- _fini:
--      stm     --sp, r0-r7,lr
-+      stm     --sp, r6, lr
-+      lddpc   r6, 2f
-+1:    rsub    r6, pc
-+      rjmp    3f
-       .align  2
-+2:    .long   1b - _GLOBAL_OFFSET_TABLE_
-+3:
-diff --git a/libc/sysdeps/linux/avr32/crtn.S b/libc/sysdeps/linux/avr32/crtn.S
-index 577adcc..f7d1040 100644
---- a/libc/sysdeps/linux/avr32/crtn.S
-+++ b/libc/sysdeps/linux/avr32/crtn.S
-@@ -3,12 +3,12 @@
-       .align  2
-       .global _init
-       .type   _init, @function
--      ldm     sp++, r0-r7,pc
-+      ldm     sp++, r6, pc
-       .size   _init, . - _init
-       .section .fini
-       .align  2
-       .global _fini
-       .type   _fini, @function
--      ldm     sp++, r0-r7,pc
-+      ldm     sp++, r6, pc
-       .size   _fini, . - _fini
--- 
-1.5.3.1