diff -urN uClibc/ldso-0.9.24/COPYRIGHT uClibc.ldso.24/ldso-0.9.24/COPYRIGHT
--- uClibc/ldso-0.9.24/COPYRIGHT	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/COPYRIGHT	2001-04-23 12:43:53.000000000 -0500
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald, David Engel,
+ * Hongjiu Lu and Mitch D'Souza
+ *
+ * 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.
+ */
+
+/* Notice of general intent:
+ *
+ * The linux operating system generally contains large amounts of code
+ * that fall under the GNU General Public License, or GPL for short.
+ * This file contains source code that by it's very nature would always
+ * be linked with an application program, and because of this a GPL
+ * type of copyright on this file would place restrictions upon the
+ * distribution of binary-only commercial software.  Since the goal of
+ * the Linux project as a whole is not to discourage the development and
+ * distribution of commercial software for Linux, this file has been
+ * placed under a more relaxed BSD-style of copyright.
+ *
+ * It is the general understanding of the above contributors that a
+ * program executable linked to a library containing code that falls
+ * under the GPL or GLPL style of license is not subject to the terms of
+ * the GPL or GLPL license if the program executable(s) that are supplied
+ * are linked to a shared library form of the GPL or GLPL library, and as
+ * long as the form of the shared library is such that it is possible for
+ * the end user to modify and rebuild the library and use it in
+ * conjunction with the program executable.
+ */
diff -urN uClibc/ldso-0.9.24/Makefile uClibc.ldso.24/ldso-0.9.24/Makefile
--- uClibc/ldso-0.9.24/Makefile	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/Makefile	2003-11-06 16:38:45.000000000 -0600
@@ -0,0 +1,52 @@
+# Makefile for uClibc
+#
+# Copyright (C) 2000,2001 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
+#
+# 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.
+
+TOPDIR=../
+include $(TOPDIR)Rules.mak
+
+ALL_SUBDIRS = ldso libdl
+
+
+all: headers
+ifeq ($(strip $(BUILD_UCLIBC_LDSO)),y)
+	$(MAKE) -C ldso;
+else
+	echo "Not building ld-uClibc"
+endif
+
+shared:
+ifeq ($(strip $(BUILD_UCLIBC_LDSO)),y)
+	$(MAKE) -C libdl;
+else
+	echo "Not building libdl"
+endif
+
+headers:
+	$(LN) -fs $(TOPDIR)../include/elf.h include/
+	$(LN) -fs ../ldso/$(TARGET_ARCH)/boot1_arch.h include/
+	$(LN) -fs ../ldso/$(TARGET_ARCH)/ld_syscalls.h include/
+	$(LN) -fs ../ldso/$(TARGET_ARCH)/ld_sysdep.h include/
+
+clean:
+	set -e ; for d in $(ALL_SUBDIRS) ; do $(MAKE) -C $$d $@ ; done
+	-find . -name '*~' | xargs $(RM)
+	$(RM) include/elf.h include/boot1_arch.h include/ld_syscalls.h include/ld_sysdep.h
diff -urN uClibc/ldso-0.9.24/README uClibc.ldso.24/ldso-0.9.24/README
--- uClibc/ldso-0.9.24/README	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/README	2001-05-31 16:23:20.000000000 -0500
@@ -0,0 +1,841 @@
+
+Apr 20, 2001 -- Manuel Novoa III
+
+Inital port for uClibc from debian ld.so_1.9.11-9.tar.gz.
+
+Removed a.out support.
+
+****************** original ld.so.lsm file **************************
+Begin3
+Title:          Linux shared, dynamic linker and utilities.
+Version:        1.9.11
+Entered-date:   01MAY99
+Description:    This package contains ld.so, ld-linux.so, ldconfig,
+		ldd and libdl.
+Keywords:       dynamic linker, shared library, ld.so, ld-linux.so,
+		ldconfig, ldd, libdl
+Author:         david@ods.com (David Engel)
+Maintained-by:  david@ods.com (David Engel)
+Primary-site:   tsx-11.mit.edu /pub/linux/packages/GCC
+		ld.so-1.9.11.tar.gz
+Alternate-site: sunsite.unc.edu /pub/Linux/GCC
+		ld.so-1.9.11.tar.gz
+Platform:       Linux 2.0.0 or later.
+Copying-policy: Copyrighted but freely distributable.
+End
+*********************************************************************
+                   Original README starts here
+*********************************************************************
+
+This package contains my ELF dynamic linkers (ld-linux.so.1), dynamic
+linker library (libdl.so.1) and utilities (ldconfig and ldd) for Linux.
+
+You need Linux kernel 2.0.0 or later with ELF support compiled in
+(i.e. not loaded as a module) to use this package.
+
+The dynamic linker is used to bootstrap programs and load shared
+libraries at startup.  The dynamic linker library is used to
+dynamically load shared libraries after a program is running.
+Ldconfig is used to automatically update the symbolic links to shared
+libraries and build the cache file used by the dynamic linker.  Ldd is
+used to list the shared libraries used by a program.
+
+Please see the included manual pages for further details.
+
+To install, simply run "sh instldso.sh" as root.  Ready-to-go versions
+of all end-products are provided so nothing should need to be compiled
+or linked.  If you are still using libc5 as your primary development
+library, you should use the "--devfiles" option when running
+instldso.sh to install the file needed to compile with libdl.
+
+ELF versions of gcc, binutils and libc are now required to compile
+everything, including the old, unsupported, a.out dynamic linker.
+Finally, an optimization level of O2 or higher must be used to compile
+ld-linux.so and libdl.so due the use of inline functions.
+
+Notable contributors to this package include Eric Youngdale, Peter
+MacDonald, Hongjiu Lu, Linus Torvalds, Lars Wirzenius, Mitch D'Souza,
+Rik Faith, Andreas Schwab and Adam Richter (not necessarily in that
+order).
+
+###################### IMPORTANT NOTICES #############################
+
+A.OUT SUPPORT:
+
+As of ld.so-1.9.0, the old, a.out dynamic loader is no longer 
+officially supported.  The code is still included and built, but I 
+make no promises that it will work.  I will accept patches for it, 
+but they will not be tested by me.
+
+GLIBC (AKA LIBC6) SUPPORT:
+
+As of ld.so-1.9.0, the main focus of this package is to ease the
+transition to libc6.  No significant, new features are expected to be
+added.  If you need new features, switch to libc6.
+
+Except for libpthread.so, the sonames of the core libraries provided
+with libc6 have been chosen so they do not conflict with those
+provided by libc5 and ld.so.  However, the current plan is not use
+new, nonconflicting sonames for other libraries such as ncurses and
+X11.  This presents two problems.  First, libraries using the same
+soname for both libc5 and libc6 can not be placed in the same
+directory.  Second, the dynamic linkers need to make sure not to load
+a library for the wrong version of libc.
+
+The first problem is easy.  Just move the old, libc5-based libraries
+to new directories (e.g. /lib/libc5-compat, /usr/lib/libc5-compat,
+etc.) and add those directories to /etc/ld.so.conf.  Then install the
+new, libc6-based versions in the standard places.
+
+The second problem is more difficult.  Ideally, the dynamic linkers
+would be changed to perform a complete dependency analysis on every
+library to be loaded to make sure the wrong versions aren't used.
+This approach doesn't seem worth the added complexity, especially
+since we now have symbol versioning for ELF libraries.  Instead a
+simpler approach will be used, at least initially.
+
+Ldconfig has been modified to perform a (currently simple) dependency
+analysis on libraries and to store an indication in /etc/ld.so.cache
+of whether a library is for libc5, libc6 or an unknown libc.  The
+dynamic linkers then only need to make a simple check at run-time to
+make sure they don't load the wrong version of a library.
+
+The dynamic linker for libc5 provided in this package, has already
+been modified to use the new information in /etc/ld.so.cache.  For
+glibc versions 2.0.1 and earlier, the dynamic linker for libc6 needs
+the patch contained in glibc.patch.  You should apply the patch and
+rebuild glibc before using the new ldconfig.
+
+As stated above, the dependency analysis currently done by ldconfig is
+rather simple.  Basically, it looks for the sonames used by the
+various versions of libc, libm and libdl.  For any approach using a
+dependency analysis such as this to work, it is very important that
+shared libraries be built with complete dependency information.  This
+can be done by using the appropriate -l options when running 'gcc
+-shared'.  For example, when building libfoo.so which depends on libc
+and libbar, you should add -lbar and -lc gcc command line.
+
+######################################################################
+
+Changes in version 1.9.11:
+
+	Fixed a bug in ld-linux.so where a reference to an
+	undefined symbol could cause a segfault.
+
+	Added a clarification for LD_PRELOAD to the ld.so manual 
+	page and added a symlink for ld-linux.so (Bug#33123).
+
+	Don't install ldd for Debian except for the m68k arch
+	because glibc 2.1 now includes it (Bug#35458).
+
+Changes in version 1.9.10:
+
+	Changed ldconfig to issue a warning and not overwrite a
+	regular file with a symlink (Bug#30859).
+
+	Changed Debian packaging to conflict with and replace the
+	ldconfig package (Bug#29398).
+
+Changes in version 1.9.9:
+
+	Changed ld-linux.so and libdl.so to match glibc by not
+	allowing user preloads of system libraries into setu/gid
+	binaries unless the library itself is setuid.
+
+	Fixed problems in ld-linux.so on the sparc architecture
+	(Juan Cespedes).
+
+Changes in version 1.9.8:
+
+	Changed ldconfig to allow the expected type for all
+	libraries in a directory to be optionally specified
+	(Mark Phillips).  See the ldconfig man page.
+
+	Changed ldconfig to use the same type names used in the
+	change above when the -p option is used.
+
+Changes in version 1.9.7:
+
+	Changed ldd for m68k to use /lib/ld.so.1 instead of 
+	/lib/ld-linux.so.2.
+
+	Added support for dladdr to libdl.so (Eduard Gode).
+
+	Fixed a small memory leak in libdl.so (Richard Garnish).
+
+	Fixed a bug in ldconfig when the -l option was used on a
+	filename without a '/' in it.
+
+	Updated the man pages (Bug#6404, Bug#9721, Bug#10652, 
+	Bug#13494 and Bug#14127).  They could still use some work.
+
+	No longer install the info page since it's way out of date.
+
+	Fixed minor Debian packaging problems (Bug#13160, 
+	Bug#15577 and Bug#19345).
+
+Changes in version 1.9.6:
+
+	Changed ldd to not use the glibc dynamic linker when run
+	on a libc5-based shared library.
+
+	Added a -q option to ldconfig which causes warnings not
+	to be printed (Bob Tinsley).
+
+	Dropped support for the Debian libdl1-dev package.
+
+	Changed ld-linux.so to be compilable with gcc 2.8.0 (Sven 
+	Verdoolaege)
+
+Changes in version 1.9.5:
+
+	Fixed a bug in ldd where ld-linux.so.2 was not called
+	correctly when run on shared libraries.
+
+	Fixed a problem in the previous version where some
+	Makefiles were not architecture independent.
+
+Changes in version 1.9.4:
+
+	Fixed a bug in ld.so introduced in the previous version
+	which broke preloads.
+
+	Turned a.out support back on by default, at least for the
+	time being.  There are no promises to keep it.
+
+Changes in version 1.9.3:
+
+	Fixed buffer overflow bugs in ld-linux.so and ld.so.
+
+	Changed the README file a little to clarify a couple of
+	things.
+
+	Changed ldconfig to chroot to the specified directory when
+	the new -r option is used (Bob Tinsley).
+
+Changes in version 1.9.2:
+
+	Removed /usr/local/lib from the default /etc/ld.so.conf
+	for Debian (Bug#8181).
+
+	Changed ldconfig to be 64-bit clean (H.J. Lu).
+
+Changes in version 1.9.1:
+
+	Changed ldconfig to try to determine which libc a
+	library is for even if it doesn't have an soname.
+
+	Fixed a bug in ldconfig where an older library using
+	the glibc naming convention would be used instead of
+	a newer library.
+
+	Changed to ld-linux.so and libdl.so to not require the 
+	libc5 headers in order to compile.
+
+	Changed ldconfig and ldd to be compilable with either
+	libc5 or libc6.
+
+Changes in version 1.9.0:
+
+	Changed to not build the old, a.out dynamic loader by
+	default.
+
+	Changed instldso.sh to require the --force option to
+	make sure users read the README file.
+
+	Changed instldso.sh to not install the libdl.so
+	development files unless the --devfiles option is used.
+
+	Changed instldso.sh to not strip binaries and libraries
+	if the --no-strip option is used.
+
+	Changed the Debian packaging to put the development files 
+	which conflict with glibc in a new libdl1-dev package.
+
+	Changed ldd to use the glibc dynamic linker, if it is
+	available, when run on a shared library.
+
+	Changed ld-linux.so to print the load addresses of
+	libraries, ala glibc, when run by ldd.
+
+	Changed ld-linux.so to allow the libraries listed in 
+	LD_PRELOAD to be separated by white space in addition to 
+	colons.
+
+	Changed ld-linux.so to load the libraries listed in 
+	LD_PRELOAD for setu/gid programs as long as they can be 
+	loaded securely.
+
+	Changed ldconfig to update the symlinks for the dynamic
+	linkers.
+
+	Changed ldconfig to try to determine if an ELF library is
+	intended for libc5 or libc6 and save the infomation in the
+	cache.  The mechanism used is rather simplistic and may
+	need to be enhanced.
+
+	Changed ldconfig to print the type of ELF library when
+	printing the cache.
+
+	Changed ld-linux.so to only load ELF shared libraries for
+	use with libc5 or an unknown libc.
+
+Changes in version 1.8.10:
+
+	Fixed a bug in ldconfig where a symlink could be used
+	instead of a regular file.
+
+	Fixed a Debian packaging problem for the sparc 
+	architecture.
+
+Changes in version 1.8.9:
+
+	Changed ldconfig to only cache the symlinks it creates.
+	This make the behavior of the dynamic linkers consistent
+	with how they would behave if a cache was not used.
+
+	Changed ldconfig to cache the symlinks that it finds but
+	use the name of the symlink as the soname instead of the 
+	actual soname.
+
+Changes in version 1.8.8:
+
+	Minor documentation updates to reflect recent changes.
+
+	Changed ld.so and ld-linux.so to perform more complete
+	validation on ld.so.cache before using it.
+
+	Changed ldconfig to accept libraries with inconsistent
+	sonames since glibc is going to use them.  A warning is
+	still printed in debug mode.
+
+	Changed the install script to not strip _dl_debug_state
+	from ld-linux.so since gdb needs it.
+
+	More sparc fixes (Derrick Brashear).
+
+	Changed ldconfig to not issue a warning when a linker
+	script disguised as a shared library is found.
+
+	Fixed a bug in ld-linux.so where some registers were 
+	not preserved on the first call to a function causing 
+	problems for non-C-like languages (Tim Renouf).
+
+	Fixed a bug in ld-linux.so where global variables were 
+	not always mapped correctly across dynamically loaded 
+	libraries (Mikihiko Nakao).
+
+	Converted to new Debian source packaging format (Shaya
+	Potter).
+
+Changes in version 1.8.6/7:
+
+	Never released as some unofficial patches used these
+	version numbers.
+
+Changes in version 1.8.5:
+
+	Fixed a bug in ld.so introduced in the previous changes.
+
+Changes in version 1.8.4:
+
+	Changed ldconfig to completely ignore symbolic links.
+
+	Changed ldconfig to issue the warning concerning an
+	inconsistent soname in non-verbose mode.
+
+	Changed ld-linux.so back to not keep ld.so.cache mapped
+	at all times.
+
+	Changed Debian packaging to compress man pages, strip all
+	binaries (Bug#5125) and include a shlibs file.
+
+Changes in version 1.8.3:
+
+	Changed ld-linux.so to process LD_PRELOAD before
+	/etc/ld.so.preload.
+
+	Fixed a Debian packaging problem where libdl might not
+	be available if other packages were upgraded at the same
+	time (Debian Bug#4728).
+
+	Changed ldd to always exit with status 1 if any errors
+	occur (Debian Bug#4188).
+
+	Fixed some minor problems in instldso.sh (Mike Castle and
+	Wolfgang Franke).
+
+	Changed ldconfig to issue a warning in verbose mode when 
+	skipping a library because the soname doesn't match.
+
+	More sparc fixes (Miguel de Icaza).
+
+	Don't link with -N when building ld.so (Alan Modra).
+
+	Changed ld-linux.so to better support position-dependant
+	libraries (NIIBE Yutaka).
+
+Changes in version 1.8.2:
+
+	Added a texinfo file for ld.so and libdl (Michael 
+	Deutschmann).
+
+	Minor sparc and installation changes (Elliot Lee).
+
+	Added multiple architecture support for Debian (Leland
+	Lucius).
+
+	Changed libdl to better support RTLD_NEXT (Eric 
+	Youngdale).  Note: the exact meaning of ETLD_NEXT is 
+	still not clear in all cases.
+
+	Removed some libc dependencies from libdl.  Still need
+	to remove malloc and free.
+
+Changes in version 1.8.1:
+
+	Changed ld.so to be compiled as ELF.  This also means
+	that ELF support is now required.  A.out support is 
+	still optional.
+
+	Changed ld-linux.so and libdl.so to use the rpath in the 
+	executable instead of in the invoking shared library.
+
+	More m68k fixes (Andreas Schwab).
+
+	Various sparc fixes (Miguel de Icaza).
+
+	Changed ldcnnfig to ignore libraries ending in '~'.
+
+	Changed ldconfig to allow alternative conf and cache 
+	files to be specified on the command-line.
+
+	Changed libdl.so to work when dlsym is passed a NULL
+	handle pointer.
+
+Changes in version 1.8.0:
+
+	Changed ld-linux.so to be more liberal when checking to
+	see if a library is already loaded.  This should avoid
+	the duplicate loading problem for programs linkeed with
+	the -rpath option.
+
+	Various m68k fixes (Andreas Schwab).
+
+	Changed ld.so to only use LD_AOUT_LIBRARY_PATH and
+	LD_AOUT_PRELOAD and ld-linux.so to only use 
+	LD_LIBRARY_PATH and LD_PRELOAD.  LD_ELF_LIBRARY_PATH
+	and LD_ELF_PRELOAD are no longer supported.
+
+	Changed ld-linux.so to allow debugging of shared and
+	dynamically loaded libraries (H.J. Lu, Andreas Schwab).
+
+	Changed ld-linux.so to preload ELF shared libraries 
+	listed in /etc/ld.so.preload.  This allows secure 
+	preloads, even for setuid/setgid programs.
+
+	Changed ld-linux.so to keep ld.so.cache mapped at all
+	times.
+
+	Changed ldconfig to allow #-style comments in ld.so.conf.
+
+	Removed various compiler warnings (Richard Sladkey and
+	David Engel).
+
+	Changed ldd to work on ELF shared libraries.  This may
+	need a little more work.
+
+Changes in version 1.7.14:
+
+	Changed ldconfig to recognize ELF shared libraries
+	generated by post-2.6 versions of ld (Andreas Schwab).
+
+	Changed ldconfig to not remove stale links that do not
+	have a version number since they may be needed by ld.
+
+Changes in version 1.7.13:
+
+	Fixed a problem in ld-linux.so where a program linked
+	with a shared library that was not used could result in
+	a segmentation fault (H.J. Lu).
+
+Changes in version 1.7.12:
+
+	Fixed a problem in libdl.so where the wrong library
+	could be marked as global when RTLD_GLOBAL was used
+	(Lars Heete).
+
+	Installed dlfcn.h with libdl.so instead of requiring
+	it to be supplied with libc.
+
+	Removed support for libldso.a since it was nearly
+	impossible to use anyway.
+
+	Changed ldd to detect when the program being checked
+	exited abnormally.
+
+Changes in version 1.7.11:
+
+	Changed ld.so and ld-linux.so to delete all variations
+	of LD_PRELOAD and LD_LIBRARY_PATH for set[ug]id programs,
+	This makes it harder for broken set[ug]id programs to be
+	compromised.
+
+	Fixed a problem in libdl.so where dlsym would not accept
+	the handle returned from dlopen(0, *).
+
+Changes in version 1.7.10:
+
+	Changed ld-linux.so and libdl.so to support RTLD_GLOBAL
+	(Eric Youngdale).
+
+Changes in version 1.7.9:
+
+	Fixed a problem in ld-linux.so in detecting when the 
+	new user/group information is provided by the kernel.
+
+	Fixed a problem in ld-linux.so where a buffer could be
+	overflowed if a large number of libraries were loaded
+	(Thomas Moore).
+
+Changes in version 1.7.8:
+
+	Changed the Makefiles and install scripts to support 
+	a.out- and ELF-only configurations.
+
+	Changed ld-linux.so to use the user/group information
+	provided by linux 1.3.23+ instead of making syscalls
+	to get it.
+
+	Changed libdl.so to support RTLD_NEXT (Glenn Fowler).
+
+	Changed libdl.so to only execute the fini sections
+	instead of completely closing libraries at exit (Glenn
+	Fowler).
+
+	Changed ld.so and ld-linux.so to print the required
+	cache version when a mismatch is detected.
+
+	Changed ld-linux.so to not require on /dev/zero (Ralph
+	Loader).
+
+	Minor m68k cleanups (Andreas Schwab).
+
+Changes in version 1.7.7:
+
+	Fixed problems compiling with recent 1.3.x kernels.
+
+	Changed ld-linux.so to not use MAP_DENYWRITE until the
+	permission issue regarding it is resolved.
+
+Changes in version 1.7.6:
+
+	Fixed a bug in ld-linux.so dealing with a zero-length
+	LD_{ELF_}PRELOAD.
+
+	Changed ld.so and ld-linux.so to truncate all variations
+	of LD_PRELOAD and LD_LIBRARY_PATH for set[ug]id programs.
+
+Changes in version 1.7.5:
+
+	Changed ldconfig to recognize libraries without any
+	version number (eg. libXYZ.so).
+
+	Changed ldconfig to not generate a corrupt cache when
+	the disk is full or other write errors occur.
+
+	Changed ld-linux.so to map files with MAP_DENYWRITE to
+	keep them from being changed while the file is in use
+	(Rick Sladkey).
+
+	Changed libdl to not overwrite the scope pointer of a 
+	library if it was already loaded (H.J. Lu).
+
+	Changed ld-linux.so so gdb can be used on constructors
+	(Eric Youngdale).
+
+	Changed ldconfig to ignore ELF libraries where the soname
+	does not match the file name on the assumption that it is
+	a used at compile-time (eg. libcurses.so -> libncruses.so).
+
+Changes in version 1.7.4:
+
+	Changed ld-linux.so and libdl to use the appropriate
+	rpaths when searching for shared libraries (Eric
+	Youngdale).
+
+	Changed ld-linux.so to search rpath before using the
+	cache.  This more closely conforms to the IBCS standard.
+
+Changes in version 1.7.3:
+
+	Changed ld-linux.so to only print a library name the
+	first time it is loaded when run from ldd.
+
+	Fixed a bug in ldconfig where an invalid cache could be
+	generated if a directory was specified multiple times in
+	ld.so.conf.
+
+	Changed ld-linux.so so it will return the address of a
+	weak symbol when called from dlsym in libdl (Eric 
+	Youngdale.
+
+Changes in version 1.7.2:
+
+	Changed libdl.so again to fix the undefined foobar
+	problem.
+
+Changes in version 1.7.1:
+
+	Changed libdl so it will compile at optimization level
+	O3 or higher.
+
+	Changed ldconfig to always create the cache file with 
+	mode 644.
+
+	Changed ldconfig to not ingore valid symlinks.
+
+	Changed ldconfig to use the library name as the soname 
+	for ELF libraries that do not have an soname entry.
+
+	Changed ld-linux.so to print the actual, requested library
+	name at the time it is loaded instead of trying to figure
+	it out after the fact.
+
+Changes in version 1.7.0:
+
+	Changed ldconfig to read the actual soname from the image
+	for ELF libraries and make it available to ld-linux.so.  
+	The soname for DLL libraries is still determined by
+	truncating the minor numbers from the image file name.
+
+	Changed ldconfig to no longer support the undocumented
+	sort options.
+
+	Changed ld.so to require a valid cache to find libraries
+	in directories specified in ld.so.conf.  /usr/lib and /lib
+	are still searched as a last resort.  Ld-linux.so already
+	operated this way.
+
+	Fixed a bug in libldso.a where the arguments to
+	shared_loader were not parsed correctly (Wolfram Gloger).
+
+	Added support for RELA-style relocations under Linux/68k
+	(Andreas Schwab).
+
+	Changed ld-linux.so to only map the cache once for all
+	libraries instead of individually for each library.
+
+	Changed ld-linux.so continue searching the cache instead of
+	giving up when failing to load the first entry found.
+
+	Changed ld-linux.so to produce output similar to ld.so when
+	run from ldd or when errors occur.
+
+Changes in version 1.6.7:
+
+	Changed the install scripts to make sure that ld.so and
+	ld-linux.so are always usable.
+
+	Added support for Linux/Sparc (Eric Youngdale).
+
+	Added support for Linux/68k (Andreas Schwab).
+
+	Fixed various bugs in ld-linux.so dealing with closing
+	files, unmapping memory, dereferencing NULL pointers and 
+	printing library names (David Engel, Eric Youngdale and 
+	Andreas Schwab).
+
+	Replaced the manual page for libdl with a freely
+	distributable one (Adam Richter).
+
+	Fixed a bug in ld-linux.so where LD_LIBRARY_PATH and
+	LD_PRELOAD were not cleared for setuid/setgid programs.
+
+	Fixed a bug in libdl where dlsym would not return the
+	correct address of a symbol if it was redefined in another
+	library (Oleg Kibirev).
+
+	Changed ld-linux.so to use the following order to search 
+	for libraries:  LD_{ELF_}LIBRARY_PATH, ld.so.cache, rpath, 
+	/usr/lib and /lib.
+
+	Changed ld-linux.so to not needlessly allocate memory when
+	using ld.so.cache.
+
+Changes in version 1.6.6:
+
+	Changed ldconfig to not warn about removing stale links
+	unless the -v option is specified.
+
+	Added manual pages for libdl (from FreeBSD/Sun)
+
+	Fixed a bug in ld.so dealing with preloading of objects
+	generated by recent versions of ld (Mitch D'Souza).
+
+	Fixed bugs in ldd where some errors were either not
+	detected or not printed.
+
+	Fixed a bug in ld-linux.so where the trailing nul in a
+	library name was not being copied (Owen Taylor).
+
+Changes in version 1.6.5:
+
+	Changed ldconfig to remove stale symbolic links.
+
+	Added debug hooks in ld-linux.so and libdl.so to be used 
+	by a future version of gdb (Eric Youngdale).
+
+Changes in version 1.6.4:
+
+	Change ld-linux.so to print on stdout instead of stderr
+	when run from ldd.
+
+	Added support for Debian GNU/Linux packaging.
+
+Changes in version 1.6.3:
+
+	Fixed a bug in libdl when closing a library (H.J. Lu).
+
+Changes in version 1.6.2:
+
+	Changed the error message printed by ldd when a file is
+	not a.out or ELF.  It used to only list a.out formats.
+
+	Changed ldconfig to no longer cache and set up links for
+	ld-linux.so.
+
+	Changed ld-linux.so and libdl to not conflict with upcoming
+	changes in kernel header files.
+
+	Changed ld-linux.so to not print preloaded libraries.
+
+Changes in version 1.6.1:
+
+	Updated the installation script.
+
+	Changed ld.so and ld-linux.so to look for LD_AOUT_PRELOAD
+	and LD_ELF_PRELOAD, respectively, before LD_PRELOAD.
+
+	Changed ld.so and ld-linux.so to use LD_AOUT_LIBRARY_PATH
+	and LD_ELF_LIBRARY_PATH, respectively, instead of
+	AOUT_LD_LIBRARY_PATH and ELF_LD_LIBRARY_PATH.
+
+Changes in version 1.6.0:
+
+	Changed ldconfig to process libraries which do not have
+	a minor version or patch level number.
+
+	Incorporated ld-linux.so and libdl.so.
+
+	Changed ld.so and ld-linux.so to not miss entries in the
+	cache when the fully qualified library is requested.
+
+	Changed ldconfig to use stdout instead of stderr when
+	printing the cache.
+
+Changes in version 1.5.3:
+
+	LD_PRELOAD enhancements (Tristan Gigold).
+
+	LD_PRELOAD patch for linux-68k (Andreas Schwab).
+
+Changes in version 1.5.2:
+
+	More ELF changes (Mitch D'Souza).
+
+	Changed ldconfig to also update the link for ld-linux.so.
+
+Changes in version 1.5.1:
+
+	More ELF and LD_PRELOAD changes (Mitch D'Souza).
+
+Changes in version 1.5.0:
+
+	Chnaged all executables to QMAGIC (Mitch D'Souza and Rick
+	Sladkey).
+
+	Added preliminary support for ELF to ldd and ldconfig (Eric 
+	Youndale and H.J. Lu).
+
+	Added support for LD_PRELOAD to ld.so (Mitch D'Souza).
+
+	Removed the "advertising" clause from the copyright notices
+	in all source files.
+
+Changes in version 1.4.4:
+
+	Changed ldconfig to support QMAGIC libraries.
+
+	Fixed a bug in ld.so where some of the error messages had
+	transposed arguments.
+
+Changes in version 1.4.3:
+
+	Fixed an obscure bug in ld.so where an index was not being
+	incremented when a library was not found using the cache.
+
+Changes in version 1.4.2:
+
+	Changed ldconfig to issue a warning and continue instead
+	of an error and exiting when a link can't be updated.  
+	This is useful when some libraries are imported on read-
+	only file systems, such as an NFS mounted /usr.
+
+	Changed ld.so to be more robust in searching for libraries.
+	A library is not considered found unless it can actually be
+	loaded.  If a library is not found using the cache, the
+	standard directories are searched as in pre-cache versions.
+
+Changes in version 1.4.1:
+
+	Fixed minor Makefile problems.
+
+	Added support for linux-68k.
+
+	Fixed a bug in ld.so where libraries with absolute paths
+	were not handled correctly.
+
+	Changed ld.so to ignore the directory in the names of
+	shared libraries by default.  This allows older libraries
+	with absolute paths, such as the XView libraries, to take
+	advantage of the cache support.
+
+	Added a minimal usage message to ldconfig.
+
+Changes in version 1.4:
+
+	Fixed bug in ld.so where minor version numbers were not
+	reported correctly when a minor version incompatibility
+	was found.
+
+	Fixed bug in ldconfig where libraries with subversion
+	numbers greater than 9 were not compared correctly.
+
+	Added Mitch D'Souza's support for suppressing warning
+	messages from ld.so about minor version incompatibilities.
+
+	Added Mitch D'Souza's support for using a cache to speed
+	up searching for libraries in the standard directories.
+
+	Added Mitch D'Souza's support for a debugging version of
+	ld.so.  Link with -lldso if you think you are experiencing
+	dynamic linker problems.
+
+Changes in version 1.3:
+
+	Added support for libraries using absolute pathnames.  If I
+	had known that the XView libraries used them, I would have
+	added this earlier.
+
+	Fixed a bug handling old libraries using a pathname beginning
+	with '/' or '/lib/'.
+
+Changes in version 1.2a:
+
+	Fixed a minor bug in ldd which caused all files, specifically
+	scripts, to be recognized as binaries.  Thanks to Olaf Flebbe
+	for reporting it.
+
+David Engel
+david@sw.ods.com
diff -urN uClibc/ldso-0.9.24/include/.cvsignore uClibc.ldso.24/ldso-0.9.24/include/.cvsignore
--- uClibc/ldso-0.9.24/include/.cvsignore	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/include/.cvsignore	2003-08-19 01:05:30.000000000 -0500
@@ -0,0 +1,4 @@
+elf.h
+ld_syscalls.h
+ld_sysdep.h
+boot1_arch.h
diff -urN uClibc/ldso-0.9.24/include/dlfcn.h uClibc.ldso.24/ldso-0.9.24/include/dlfcn.h
--- uClibc/ldso-0.9.24/include/dlfcn.h	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/include/dlfcn.h	2003-08-19 01:05:30.000000000 -0500
@@ -0,0 +1,22 @@
+/* User functions for run-time dynamic loading.  libdl version */
+#ifndef	_DLFCN_H
+#define	_DLFCN_H 1
+
+#include <features.h>
+#include <bits/dlfcn.h>
+
+#define RTLD_NEXT	((void *) -1l)
+#define RTLD_DEFAULT	((void *) 0)
+
+/* Structure containing information about object searched using
+   `dladdr'.  */
+typedef struct
+{
+	__const char *dli_fname;	/* File name of defining object.  */
+	void *dli_fbase;		/* Load address of that object.  */
+	__const char *dli_sname;	/* Name of nearest symbol.  */
+	void *dli_saddr;		/* Exact value of nearest symbol.  */
+} Dl_info;
+
+
+#endif	/* dlfcn.h */
diff -urN uClibc/ldso-0.9.24/include/ld_elf.h uClibc.ldso.24/ldso-0.9.24/include/ld_elf.h
--- uClibc/ldso-0.9.24/include/ld_elf.h	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/include/ld_elf.h	2003-11-04 07:07:45.000000000 -0600
@@ -0,0 +1,93 @@
+#ifndef LINUXELF_H
+#define LINUXELF_H
+
+#include <ld_sysdep.h> /* before elf.h to get ELF_USES_RELOCA right */
+#include <elf.h>
+#include <link.h>
+
+#ifdef DEBUG
+#  define LDSO_CONF  "../util/ld.so.conf"
+#  define LDSO_CACHE "../util/ld.so.cache"
+#  define LDSO_PRELOAD "../util/ld.so.preload"
+#else
+#  define LDSO_CONF  UCLIBC_RUNTIME_PREFIX "etc/ld.so.conf"
+#  define LDSO_CACHE UCLIBC_RUNTIME_PREFIX "etc/ld.so.cache"
+#  define LDSO_PRELOAD UCLIBC_RUNTIME_PREFIX "etc/ld.so.preload"
+#endif
+
+
+#define LIB_ANY	     -1
+#define LIB_DLL       0
+#define LIB_ELF       1
+#define LIB_ELF64     0x80
+#define LIB_ELF_LIBC5 2
+#define LIB_ELF_LIBC6 3
+#define LIB_ELF_LIBC0 4
+
+/* Forward declarations for stuff defined in ld_hash.h */
+struct dyn_elf;
+struct elf_resolve;
+
+
+/* Definitions and prototypes for cache stuff */
+#ifdef USE_CACHE
+extern int _dl_map_cache(void);
+extern int _dl_unmap_cache(void);
+
+#define LDSO_CACHE_MAGIC "ld.so-"
+#define LDSO_CACHE_MAGIC_LEN (sizeof LDSO_CACHE_MAGIC -1)
+#define LDSO_CACHE_VER "1.7.0"
+#define LDSO_CACHE_VER_LEN (sizeof LDSO_CACHE_VER -1)
+
+typedef struct {
+	char magic   [LDSO_CACHE_MAGIC_LEN];
+	char version [LDSO_CACHE_VER_LEN];
+	int nlibs;
+} header_t;
+
+typedef struct {
+	int flags;
+	int sooffset;
+	int liboffset;
+} libentry_t;
+
+#else
+static inline void _dl_map_cache(void) { }
+static inline void _dl_unmap_cache(void) { }
+#endif	
+
+
+/* Function prototypes for non-static stuff in readelflib1.c */
+int _dl_copy_fixups(struct dyn_elf * tpnt);
+extern int _dl_parse_copy_information(struct dyn_elf *rpnt,
+	unsigned long rel_addr, unsigned long rel_size, int type);
+extern void _dl_parse_lazy_relocation_information(struct elf_resolve *tpnt,
+	unsigned long rel_addr, unsigned long rel_size, int type);
+extern int _dl_parse_relocation_information(struct elf_resolve *tpnt,
+	unsigned long rel_addr, unsigned long rel_size, int type);
+extern struct elf_resolve * _dl_load_shared_library(int secure, 
+	struct dyn_elf **rpnt, struct elf_resolve *tpnt, char *full_libname);
+extern struct elf_resolve * _dl_load_elf_shared_library(int secure, 
+	struct dyn_elf **rpnt, char *libname);
+extern struct elf_resolve *_dl_check_if_named_library_is_loaded(const char *full_libname);
+extern int _dl_linux_resolve(void);
+
+
+/*
+ * Datatype of a relocation on this platform
+ */
+#ifdef ELF_USES_RELOCA
+# define ELF_RELOC	ElfW(Rela)
+#else
+# define ELF_RELOC	ElfW(Rel)
+#endif
+
+
+/* Convert between the Linux flags for page protections and the
+   ones specified in the ELF standard. */
+#define LXFLAGS(X) ( (((X) & PF_R) ? PROT_READ : 0) | \
+		    (((X) & PF_W) ? PROT_WRITE : 0) | \
+		    (((X) & PF_X) ? PROT_EXEC : 0))
+
+
+#endif	/* LINUXELF_H */
diff -urN uClibc/ldso-0.9.24/include/ld_hash.h uClibc.ldso.24/ldso-0.9.24/include/ld_hash.h
--- uClibc/ldso-0.9.24/include/ld_hash.h	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/include/ld_hash.h	2003-08-19 08:11:05.000000000 -0500
@@ -0,0 +1,103 @@
+#ifndef _LD_HASH_H_
+#define _LD_HASH_H_
+
+#ifndef RTLD_NEXT
+#define RTLD_NEXT	((void*)-1)
+#endif
+
+struct dyn_elf{
+  unsigned long flags;
+  struct elf_resolve * dyn;
+  struct dyn_elf * next_handle;  /* Used by dlopen et al. */
+  struct dyn_elf * next;
+  struct dyn_elf * prev;
+};
+
+struct elf_resolve{
+  /* These entries must be in this order to be compatible with the interface used
+     by gdb to obtain the list of symbols. */
+  ElfW(Addr) loadaddr;		/* Base address shared object is loaded at.  */
+  char *libname;		/* Absolute file name object was found in.  */
+  ElfW(Dyn) *dynamic_addr;	/* Dynamic section of the shared object.  */
+  struct elf_resolve * next;
+  struct elf_resolve * prev;
+  /* Nothing after this address is used by gdb. */
+  enum {elf_lib, elf_executable,program_interpreter, loaded_file} libtype;
+  struct dyn_elf * symbol_scope;
+  unsigned short usage_count;
+  unsigned short int init_flag;
+  unsigned int nbucket;
+  unsigned long * elf_buckets;
+  /*
+   * These are only used with ELF style shared libraries
+   */
+  unsigned long nchain;
+  unsigned long * chains;
+  unsigned long dynamic_info[24];
+
+  unsigned long dynamic_size;
+  unsigned long n_phent;
+  Elf32_Phdr * ppnt;
+
+#if defined(__mips__)
+  /* Needed for MIPS relocation */
+  unsigned long mips_gotsym;
+  unsigned long mips_local_gotno;
+  unsigned long mips_symtabno;
+#endif
+
+#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 */
+  unsigned long data_words;
+#endif
+};
+
+#define COPY_RELOCS_DONE    1
+#define RELOCS_DONE         2
+#define JMP_RELOCS_DONE     4
+#define INIT_FUNCS_CALLED   8
+
+extern struct dyn_elf     * _dl_symbol_tables;
+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);
+
+enum caller_type{symbolrel=0,copyrel=1,resolver=2};
+extern char * _dl_find_hash(const char * name, struct dyn_elf * rpnt1, 
+	struct elf_resolve * f_tpnt, enum caller_type);
+
+extern int _dl_linux_dynamic_link(void);
+
+extern char * _dl_library_path;
+extern char * _dl_not_lazy;
+extern unsigned long _dl_elf_hash(const char * name);
+
+static inline int _dl_symbol(char * name)
+{
+  if(name[0] != '_' || name[1] != 'd' || name[2] != 'l' || name[3] != '_')
+    return 0;
+  return 1;
+}
+
+
+#define LD_ERROR_NOFILE 1
+#define LD_ERROR_NOZERO 2
+#define LD_ERROR_NOTELF 3
+#define LD_ERROR_NOTMAGIC 4
+#define LD_ERROR_NOTDYN 5
+#define LD_ERROR_MMAP_FAILED 6
+#define LD_ERROR_NODYNAMIC 7
+#define LD_WRONG_RELOCS 8
+#define LD_BAD_HANDLE 9
+#define LD_NO_SYMBOL 10
+
+
+
+#endif /* _LD_HASH_H_ */
+
+
diff -urN uClibc/ldso-0.9.24/include/ld_string.h uClibc.ldso.24/ldso-0.9.24/include/ld_string.h
--- uClibc/ldso-0.9.24/include/ld_string.h	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/include/ld_string.h	2003-09-29 16:46:00.000000000 -0500
@@ -0,0 +1,281 @@
+#ifndef _LINUX_STRING_H_
+#define _LINUX_STRING_H_
+
+extern void *_dl_malloc(int size);
+extern char *_dl_getenv(const char *symbol, char **envp);
+extern void _dl_unsetenv(const char *symbol, char **envp);
+extern char *_dl_strdup(const char *string);
+extern void _dl_dprintf(int, const char *, ...);
+
+
+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);
+static int _dl_strcmp(const char * s1,const char * s2);
+static int _dl_strncmp(const char * s1,const char * s2,size_t len);
+static char * _dl_strchr(const char * str,int c);
+static char *_dl_strrchr(const char *str, int c);
+static char *_dl_strstr(const char *s1, const char *s2);
+static void * _dl_memcpy(void * dst, const void * src, size_t len);
+static int _dl_memcmp(const void * s1,const void * s2,size_t len);
+static void *_dl_memset(void * str,int c,size_t len);
+static char *_dl_get_last_path_component(char *path);
+static char *_dl_simple_ltoa(char * local, unsigned long i);
+static char *_dl_simple_ltoahex(char * local, unsigned long i);
+
+#ifndef NULL
+#define NULL ((void *) 0)
+#endif
+
+static inline size_t _dl_strlen(const char * str)
+{
+	register char *ptr = (char *) str;
+
+	while (*ptr)
+		ptr++;
+	return (ptr - str);
+}
+
+static inline char *_dl_strcat(char *dst, const char *src)
+{
+	register char *ptr = dst;
+
+	while (*ptr)
+		ptr++;
+
+	while (*src)
+		*ptr++ = *src++;
+	*ptr = '\0';
+
+	return dst;
+}
+
+static inline char * _dl_strcpy(char * dst,const char *src)
+{
+	register char *ptr = dst;
+
+	while (*src)
+		*dst++ = *src++;
+	*dst = '\0';
+
+	return ptr;
+}
+ 
+static inline int _dl_strcmp(const char * s1,const char * s2)
+{
+	register unsigned char c1, c2;
+
+	do {
+		c1 = (unsigned char) *s1++;
+		c2 = (unsigned char) *s2++;
+		if (c1 == '\0')
+			return c1 - c2;
+	}
+	while (c1 == c2);
+
+	return c1 - c2;
+}
+
+static inline int _dl_strncmp(const char * s1,const char * s2,size_t len)
+{
+	register unsigned char c1 = '\0';
+	register unsigned char c2 = '\0';
+
+	while (len > 0) {
+		c1 = (unsigned char) *s1++;
+		c2 = (unsigned char) *s2++;
+		if (c1 == '\0' || c1 != c2)
+			return c1 - c2;
+		len--;
+	}
+
+	return c1 - c2;
+}
+
+static inline char * _dl_strchr(const char * str,int c)
+{
+	register char ch;
+
+	do {
+		if ((ch = *str) == c)
+			return (char *) str;
+		str++;
+	}
+	while (ch);
+
+	return 0;
+}
+
+static inline char *_dl_strrchr(const char *str, int c)
+{
+    register char *prev = 0;
+    register char *ptr = (char *) str;
+
+    while (*ptr != '\0') {
+	if (*ptr == c)
+	    prev = ptr;
+	ptr++;  
+    }   
+    if (c == '\0')
+	return(ptr);
+    return(prev);
+}
+
+
+static inline char *_dl_strstr(const char *s1, const char *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);
+}
+
+static inline void * _dl_memcpy(void * dst, const void * src, size_t len)
+{
+	register char *a = dst;
+	register const char *b = src;
+
+	while (len--)
+		*a++ = *b++;
+
+	return dst;
+}
+
+
+static inline int _dl_memcmp(const void * s1,const void * s2,size_t len)
+{
+	unsigned char *c1 = (unsigned char *)s1;
+	unsigned char *c2 = (unsigned char *)s2;
+
+	while (len--) {
+		if (*c1 != *c2) 
+			return *c1 - *c2;
+		c1++;
+		c2++;
+	}
+	return 0;
+}
+
+static inline void * _dl_memset(void * str,int c,size_t len)
+{
+	register char *a = str;
+
+	while (len--)
+		*a++ = c;
+
+	return str;
+}
+
+static inline char *_dl_get_last_path_component(char *path)
+{
+	char *s;
+	register char *ptr = path;
+	register char *prev = 0;
+
+	while (*ptr)
+		ptr++;
+	s = ptr - 1;
+
+	/* strip trailing slashes */
+	while (s != path && *s == '/') {
+		*s-- = '\0';
+	}
+
+	/* find last component */
+	ptr = path;
+	while (*ptr != '\0') {
+	    if (*ptr == '/')
+		prev = ptr;
+	    ptr++;  
+	}   
+	s = prev;
+
+	if (s == NULL || s[1] == '\0')
+		return path;
+	else
+		return s+1;
+}
+
+/* Early on, we can't call printf, so use this to print out
+ * numbers using the SEND_STDERR() macro */
+static inline char *_dl_simple_ltoa(char * local, unsigned long i)
+{
+	/* 21 digits plus null terminator, good for 64-bit or smaller ints */
+	char *p = &local[22];
+	*p-- = '\0';
+	do {
+		*p-- = '0' + i % 10;
+		i /= 10;
+	} while (i > 0);
+	return p + 1;
+}
+
+static inline char *_dl_simple_ltoahex(char * local, unsigned long i)
+{
+	/* 21 digits plus null terminator, good for 64-bit or smaller ints */
+	char *p = &local[22];
+	*p-- = '\0';
+	do {
+		char temp = i % 0x10;
+		if (temp <= 0x09)
+		    *p-- = '0' + temp;
+		else
+		    *p-- = 'a' - 0x0a + temp;
+		i /= 0x10;
+	} while (i > 0);
+	*p-- = 'x';
+	*p-- = '0';
+	return p + 1;
+}
+
+
+#if defined(mc68000) || defined(__arm__) || defined(__mips__) || defined(__sh__) ||  defined(__powerpc__)
+/* On some arches constant strings are referenced through the GOT. */
+/* XXX Requires load_addr to be defined. */
+#define SEND_STDERR(X)				\
+  { const char *__s = (X);			\
+    if (__s < (const char *) load_addr) __s += load_addr;	\
+    _dl_write (2, __s, _dl_strlen (__s));	\
+  }
+#else
+#define SEND_STDERR(X) _dl_write(2, X, _dl_strlen(X));
+#endif
+
+#define SEND_ADDRESS_STDERR(X, add_a_newline) { \
+    char tmp[22], *tmp1; \
+    _dl_memset(tmp, 0, sizeof(tmp)); \
+    tmp1=_dl_simple_ltoahex( tmp, (unsigned long)(X)); \
+    _dl_write(2, tmp1, _dl_strlen(tmp1)); \
+    if (add_a_newline) { \
+	tmp[0]='\n'; \
+	_dl_write(2, tmp, 1); \
+    } \
+};
+
+#define SEND_NUMBER_STDERR(X, add_a_newline) { \
+    char tmp[22], *tmp1; \
+    _dl_memset(tmp, 0, sizeof(tmp)); \
+    tmp1=_dl_simple_ltoa( tmp, (unsigned long)(X)); \
+    _dl_write(2, tmp1, _dl_strlen(tmp1)); \
+    if (add_a_newline) { \
+	tmp[0]='\n'; \
+	_dl_write(2, tmp, 1); \
+    } \
+};
+
+
+#endif
diff -urN uClibc/ldso-0.9.24/include/ld_syscall.h uClibc.ldso.24/ldso-0.9.24/include/ld_syscall.h
--- uClibc/ldso-0.9.24/include/ld_syscall.h	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/include/ld_syscall.h	2003-08-19 01:05:30.000000000 -0500
@@ -0,0 +1,157 @@
+#ifndef _LD_SYSCALL_H_
+#define _LD_SYSCALL_H_
+
+/* Pull in the arch specific syscall implementation */
+#include <ld_syscalls.h>
+/*  For MAP_ANONYMOUS -- differs between platforms */
+#include <asm/mman.h>			
+/* Pull in whatever this particular arch's kernel thinks the kernel version of
+ * struct stat should look like.  It turns out that each arch has a different
+ * opinion on the subject, and different kernel revs use different names... */
+#define kernel_stat stat
+#include <bits/kernel_stat.h>
+
+
+/* Encoding of the file mode.  */
+#define	S_IFMT		0170000	/* These bits determine file type.  */
+
+/* File types.  */
+#define	S_IFDIR		0040000	/* Directory.  */
+#define	S_IFCHR		0020000	/* Character device.  */
+#define	S_IFBLK		0060000	/* Block device.  */
+#define	S_IFREG		0100000	/* Regular file.  */
+#define	S_IFIFO		0010000	/* FIFO.  */
+#define	S_IFLNK		0120000	/* Symbolic link.  */
+#define	S_IFSOCK	0140000	/* Socket.  */
+
+/* Protection bits.  */
+
+#define	S_ISUID		04000	/* Set user ID on execution.  */
+#define	S_ISGID		02000	/* Set group ID on execution.  */
+#define	S_ISVTX		01000	/* Save swapped text after use (sticky).  */
+#define	S_IREAD		0400	/* Read by owner.  */
+#define	S_IWRITE	0200	/* Write by owner.  */
+#define	S_IEXEC		0100	/* Execute by owner.  */
+
+
+/* Here are the definitions for some syscalls that are used
+   by the dynamic linker.  The idea is that we want to be able
+   to call these before the errno symbol is dynamicly linked, so
+   we use our own version here.  Note that we cannot assume any
+   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);
+
+
+#define __NR__dl_close __NR_close
+static inline _syscall1(int, _dl_close, int, fd);
+
+
+#if defined(__powerpc__) || defined(__mips__) || defined(__sh__)
+/* PowerPC, MIPS and SuperH have a different calling convention for 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);
+#else
+#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];
+
+	buffer[0] = (unsigned long) addr;
+	buffer[1] = (unsigned long) size;
+	buffer[2] = (unsigned long) prot;
+	buffer[3] = (unsigned long) flags;
+	buffer[4] = (unsigned long) fd;
+	buffer[5] = (unsigned long) offset;
+	return (void *) _dl_mmap_real(buffer);
+}
+#endif
+
+#ifndef _dl_MAX_ERRNO
+#define _dl_MAX_ERRNO 4096
+#endif
+#define _dl_mmap_check_error(__res)	\
+	(((int)__res) < 0 && ((int)__res) >= -_dl_MAX_ERRNO)
+#ifndef MAP_ANONYMOUS
+#ifdef __sparc__
+#define MAP_ANONYMOUS 0x20
+#else
+#error MAP_ANONYMOUS not defined and suplementary value not known
+#endif
+#endif
+
+
+#define __NR__dl_open __NR_open
+#define O_RDONLY        0x0000
+#define O_WRONLY	     01
+#define O_RDWR		     02
+#define O_CREAT		   0100	/* not fcntl */
+static inline _syscall2(int, _dl_open, const char *, fn, int, flags);
+
+#define __NR__dl_write __NR_write
+static 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, 
+	    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);
+
+
+
+#define __NR__dl_stat __NR_stat
+static 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);
+
+#define __NR__dl_getuid __NR_getuid
+static inline _syscall0(uid_t, _dl_getuid);
+
+#define __NR__dl_geteuid __NR_geteuid
+static inline _syscall0(uid_t, _dl_geteuid);
+
+#define __NR__dl_getgid __NR_getgid
+static inline _syscall0(gid_t, _dl_getgid);
+
+#define __NR__dl_getegid __NR_getegid
+static inline _syscall0(gid_t, _dl_getegid);
+
+#define __NR__dl_getpid __NR_getpid
+static inline _syscall0(gid_t, _dl_getpid);
+
+/*
+ * Not an actual syscall, but we need something in assembly to say whether
+ * this is OK or not.
+ */
+static inline int _dl_suid_ok(void)
+{
+    uid_t uid, euid, gid, egid;
+
+    uid = _dl_getuid();
+    euid = _dl_geteuid();
+    gid = _dl_getgid();
+    egid = _dl_getegid();
+
+    if(uid == euid && gid == egid)
+	return 1;
+    else
+	return 0;
+}
+
+#define __NR__dl_readlink __NR_readlink
+static inline _syscall3(int, _dl_readlink, const char *, path, char *, buf, size_t, bufsiz);
+
+#endif /* _LD_SYSCALL_H_ */
+
diff -urN uClibc/ldso-0.9.24/include/ldso.h uClibc.ldso.24/ldso-0.9.24/include/ldso.h
--- uClibc/ldso-0.9.24/include/ldso.h	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/include/ldso.h	2003-08-19 01:05:30.000000000 -0500
@@ -0,0 +1,11 @@
+#include <features.h>
+/* Pull in compiler and arch stuff */
+#include <stdlib.h>
+#include <stdarg.h>
+/* Pull in the arch specific type information */
+#include <sys/types.h>
+/* Now the ldso specific headers */
+#include <ld_elf.h>
+#include <ld_syscall.h>
+#include <ld_hash.h>
+#include <ld_string.h>
diff -urN uClibc/ldso-0.9.24/ldso/.cvsignore uClibc.ldso.24/ldso-0.9.24/ldso/.cvsignore
--- uClibc/ldso-0.9.24/ldso/.cvsignore	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/.cvsignore	2003-08-19 01:05:31.000000000 -0500
@@ -0,0 +1,2 @@
+ld-uclibc.so*
+_dl_progname.h
diff -urN uClibc/ldso-0.9.24/ldso/Makefile uClibc.ldso.24/ldso-0.9.24/ldso/Makefile
--- uClibc/ldso-0.9.24/ldso/Makefile	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/Makefile	2004-03-01 02:58:58.000000000 -0600
@@ -0,0 +1,101 @@
+# Makefile 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
+#
+# 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.
+
+
+TOPDIR=../../
+include $(TOPDIR)Rules.mak
+LDSO_FULLNAME=ld-uClibc-$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBLEVEL).so
+
+
+XXFLAGS=$(XWARNINGS) $(OPTIMIZATION) $(XARCH_CFLAGS) $(CPU_CFLAGS) $(PICFLAG) \
+	-DUCLIBC_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" \
+	-fno-builtin -nostdinc -I$(TOPDIR)ldso-0.9.24/include -I. -I$(TOPDIR)include
+
+ifeq ($(SUPPORT_LD_DEBUG),y)
+XXFLAGS=$(XWARNINGS) $(XARCH_CFLAGS) $(CPU_CFLAGS) $(PICFLAG) \
+	-DUCLIBC_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" \
+	-fno-builtin -nostdinc -I$(TOPDIR)ldso-0.9.24/include -I. -I$(TOPDIR)include
+# Not really much point in including debugging info, since gdb
+# can't really debug ldso, since gdb requires help from ldso to
+# debug things....
+XXFLAGS+=-Os #-g3
+endif
+
+# BEWARE!!! At least mips* will die if -O0 is used!!!
+XXFLAGS :=$(XXFLAGS:-O0=-O1)
+
+XXFLAGS+=$(shell $(CC) -print-search-dirs | sed -ne "s/install: *\(.*\)/-I\1include/gp")
+LDFLAGS=$(CPU_LDFLAGS-y) -shared --warn-common --export-dynamic --sort-common \
+	-z combreloc --discard-locals --discard-all --no-undefined
+
+CSRC= ldso.c #hash.c readelflib1.c $(TARGET_ARCH)/elfinterp.c
+COBJS=$(patsubst %.c,%.o, $(CSRC))
+ASRC=$(shell ls $(TARGET_ARCH)/*.S)
+AOBJS=$(patsubst %.S,%.o, $(ASRC))
+OBJS=$(AOBJS) $(COBJS)
+
+ifneq ($(strip $(SUPPORT_LD_DEBUG)),y)
+LDFLAGS+=-s
+endif
+
+ifeq ($(strip $(SUPPORT_LD_DEBUG)),y)
+XXFLAGS+=-D__SUPPORT_LD_DEBUG__
+endif
+
+ifeq ($(strip $(SUPPORT_LD_DEBUG_EARLY)),y)
+XXFLAGS+=-D__SUPPORT_LD_DEBUG_EARLY__
+endif
+
+ifeq ($(strip $(FORCE_SHAREABLE_TEXT_SEGMENTS)),y)
+XXFLAGS+=-DFORCE_SHAREABLE_TEXT_SEGMENTS
+endif
+
+#This stuff will not work with -fomit-frame-pointer
+XXFLAGS := $(XXFLAGS:-fomit-frame-pointer=)
+
+all: lib
+
+lib:: _dl_progname.h $(OBJS) $(DLINK_OBJS)
+	$(LD) $(LDFLAGS) -e _dl_boot -soname=$(UCLIBC_LDSO) \
+		-o $(LDSO_FULLNAME) $(OBJS) $(LIBGCC);
+	$(INSTALL) -d $(TOPDIR)lib
+	$(INSTALL) -m 755 $(LDSO_FULLNAME) $(TOPDIR)lib
+	$(LN) -sf $(LDSO_FULLNAME) $(TOPDIR)lib/$(UCLIBC_LDSO)
+
+_dl_progname.h: Makefile
+	echo "const char *_dl_progname=\""$(UCLIBC_LDSO)"\";" > _dl_progname.h
+	echo "#include \"$(TARGET_ARCH)/elfinterp.c\"" >> _dl_progname.h
+
+
+$(COBJS): %.o : %.c
+	$(CC) $(XXFLAGS) -I../libdl -c $< -o $@
+	$(STRIPTOOL) -x -R .note -R .comment $*.o
+
+$(AOBJS): %.o : %.S
+	$(CC) $(XXFLAGS) -I../libdl -c $< -o $@
+	$(STRIPTOOL) -x -R .note -R .comment $*.o
+
+ldso.o: ldso.c hash.c readelflib1.c $(TARGET_ARCH)/elfinterp.c _dl_progname.h
+
+clean:
+	$(RM) $(UCLIBC_LDSO)* $(OBJS) $(LDSO_FULLNAME)* core *.o *.a *.s *.i _dl_progname.h ldso.h *~
diff -urN uClibc/ldso-0.9.24/ldso/arm/boot1_arch.h uClibc.ldso.24/ldso-0.9.24/ldso/arm/boot1_arch.h
--- uClibc/ldso-0.9.24/ldso/arm/boot1_arch.h	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/arm/boot1_arch.h	2002-11-13 18:53:49.000000000 -0600
@@ -0,0 +1,30 @@
+/* Any assmbly language/system dependent hacks needed to setup boot1.c so it
+ * will work as expected and cope with whatever platform specific wierdness is
+ * needed for this architecture.  */
+
+/* Overrive the default _dl_boot function, and replace it with a bit of asm.
+ * Then call the real _dl_boot function, which is now named _dl_boot2. */
+
+asm("" \
+"	.text\n"			\
+"	.globl	_dl_boot\n"		\
+"_dl_boot:\n"				\
+"	mov	r7, sp\n"		\
+"	@ldr	r0, [sp], #4\n"		\
+"	mov	r0, sp\n"		\
+"	bl	_dl_boot2\n"		\
+"	mov	r6, r0\n"		\
+"	mov	r0, r7\n"		\
+"	mov	pc, r6\n"		\
+);
+
+#define _dl_boot _dl_boot2
+#define LD_BOOT(X)   static void *  __attribute__ ((unused)) _dl_boot (X)
+
+
+ /* It seems ARM needs an offset here */
+#undef ELFMAGIC
+#define	    ELFMAGIC	ELFMAG+load_addr 
+
+
+
diff -urN uClibc/ldso-0.9.24/ldso/arm/elfinterp.c uClibc.ldso.24/ldso-0.9.24/ldso/arm/elfinterp.c
--- uClibc/ldso-0.9.24/ldso/arm/elfinterp.c	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/arm/elfinterp.c	2002-11-07 21:20:59.000000000 -0600
@@ -0,0 +1,462 @@
+/* vi: set sw=4 ts=4: */
+/* ARM ELF shared library loader suppport
+ *
+ * Copyright (C) 2001-2002, Erik Andersen
+ *
+ * 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.
+ */
+
+#if defined (__SUPPORT_LD_DEBUG__)
+static const char *_dl_reltypes_tab[] =
+{
+  [0]	"R_ARM_NONE",	    "R_ARM_PC24",	"R_ARM_ABS32",		"R_ARM_REL32",
+  [4]	"R_ARM_PC13",	    "R_ARM_ABS16",	"R_ARM_ABS12",		"R_ARM_THM_ABS5",
+  [8]	"R_ARM_ABS8",		"R_ARM_SBREL32","R_ARM_THM_PC22",	"R_ARM_THM_PC8",
+  [12]	"R_ARM_AMP_VCALL9",	"R_ARM_SWI24",	"R_ARM_THM_SWI8",	"R_ARM_XPC25",
+  [16]	"R_ARM_THM_XPC22",
+  [20]	"R_ARM_COPY",		"R_ARM_GLOB_DAT","R_ARM_JUMP_SLOT",	"R_ARM_RELATIVE",
+  [24]	"R_ARM_GOTOFF",		"R_ARM_GOTPC",	 "R_ARM_GOT32",		"R_ARM_PLT32",
+  [32]	"R_ARM_ALU_PCREL_7_0","R_ARM_ALU_PCREL_15_8","R_ARM_ALU_PCREL_23_15","R_ARM_LDR_SBREL_11_0",
+  [36]	"R_ARM_ALU_SBREL_19_12","R_ARM_ALU_SBREL_27_20",
+  [100]	"R_ARM_GNU_VTENTRY","R_ARM_GNU_VTINHERIT","R_ARM_THM_PC11","R_ARM_THM_PC9",
+  [249] "R_ARM_RXPC25", "R_ARM_RSBREL32", "R_ARM_THM_RPC22", "R_ARM_RREL32",
+  [253] "R_ARM_RABS22", "R_ARM_RPC24", "R_ARM_RBASE",
+};
+
+static const char *
+_dl_reltypes(int type)
+{
+  static char buf[22];  
+  const char *str;
+  
+  if (type >= (sizeof (_dl_reltypes_tab)/sizeof(_dl_reltypes_tab[0])) ||
+      NULL == (str = _dl_reltypes_tab[type]))
+  {
+    str =_dl_simple_ltoa( buf, (unsigned long)(type));
+  }
+  return str;
+}
+
+static 
+void debug_sym(Elf32_Sym *symtab,char *strtab,int symtab_index)
+{
+  if(_dl_debug_symbols)
+  {
+    if(symtab_index){
+      _dl_dprintf(_dl_debug_file, "\n%s\tvalue=%x\tsize=%x\tinfo=%x\tother=%x\tshndx=%x",
+		  strtab + symtab[symtab_index].st_name,
+		  symtab[symtab_index].st_value,
+		  symtab[symtab_index].st_size,
+		  symtab[symtab_index].st_info,
+		  symtab[symtab_index].st_other,
+		  symtab[symtab_index].st_shndx);
+    }
+  }
+}
+
+static void debug_reloc(Elf32_Sym *symtab,char *strtab, ELF_RELOC *rpnt)
+{
+  if(_dl_debug_reloc)
+  {
+    int symtab_index;
+    const char *sym;
+    symtab_index = ELF32_R_SYM(rpnt->r_info);
+    sym = symtab_index ? strtab + symtab[symtab_index].st_name : "sym=0x0";
+    
+#ifdef ELF_USES_RELOCA
+    _dl_dprintf(_dl_debug_file, "\n%s\toffset=%x\taddend=%x %s",
+		_dl_reltypes(ELF32_R_TYPE(rpnt->r_info)),
+		rpnt->r_offset,
+		rpnt->r_addend,
+		sym);
+#else
+    _dl_dprintf(_dl_debug_file, "\n%s\toffset=%x %s",
+		_dl_reltypes(ELF32_R_TYPE(rpnt->r_info)),
+		rpnt->r_offset,
+		sym);
+#endif
+  }
+}
+#endif
+
+/* Program to load an ELF binary on a linux system, and run it.
+   References to symbols in sharable libraries can be resolved by either
+   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. */
+
+extern int _dl_linux_resolve(void);
+
+unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
+{
+	int reloc_type;
+	ELF_RELOC *this_reloc;
+	char *strtab;
+	Elf32_Sym *symtab;
+	ELF_RELOC *rel_addr;
+	int symtab_index;
+	char *new_addr;
+	char **got_addr;
+	unsigned long instr_addr;
+
+	rel_addr = (ELF_RELOC *) (tpnt->dynamic_info[DT_JMPREL] + tpnt->loadaddr);
+
+	this_reloc = rel_addr + (reloc_entry >> 3);
+	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] + tpnt->loadaddr);
+	strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
+
+
+	if (reloc_type != R_ARM_JUMP_SLOT) {
+		_dl_dprintf(2, "%s: Incorrect relocation type in jump relocations\n", 
+			_dl_progname);
+		_dl_exit(1);
+	};
+
+	/* Address of jump instruction to fix up */
+	instr_addr = ((unsigned long) this_reloc->r_offset + 
+		(unsigned long) tpnt->loadaddr);
+	got_addr = (char **) instr_addr;
+
+	/* Get the address of the GOT entry */
+	new_addr = _dl_find_hash(strtab + symtab[symtab_index].st_name, 
+		tpnt->symbol_scope, tpnt, resolver);
+	if (!new_addr) {
+		_dl_dprintf(2, "%s: can't resolve symbol '%s'\n", 
+			_dl_progname, strtab + symtab[symtab_index].st_name);
+		_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 (!_dl_debug_nofixups) {
+		*got_addr = new_addr;
+	}
+#else
+	*got_addr = new_addr;
+#endif
+
+	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, Elf32_Sym *symtab, char *strtab))
+{
+	int i;
+	char *strtab;
+	int goof = 0;
+	Elf32_Sym *symtab;
+	ELF_RELOC *rpnt;
+	int symtab_index;
+	/* Now parse the relocation information */
+
+	rpnt = (ELF_RELOC *) (rel_addr + tpnt->loadaddr);
+	rel_size = rel_size / sizeof(ELF_RELOC);
+
+	symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
+	strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
+
+	  for (i = 0; i < rel_size; i++, rpnt++) {
+	        int res;
+	    
+		symtab_index = ELF32_R_SYM(rpnt->r_info);
+		
+		/* When the dynamic linker bootstrapped itself, it resolved some symbols.
+		   Make sure we do not do them again */
+		if (!symtab_index && tpnt->libtype == program_interpreter)
+			continue;
+		if (symtab_index && tpnt->libtype == program_interpreter &&
+		    _dl_symbol(strtab + symtab[symtab_index].st_name))
+			continue;
+
+#if defined (__SUPPORT_LD_DEBUG__)
+		debug_sym(symtab,strtab,symtab_index);
+		debug_reloc(symtab,strtab,rpnt);
+#endif
+
+		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 (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 if (res >0)
+		{
+			_dl_dprintf(2, "can't resolve symbol\n");
+			goof += res;
+		}
+	  }
+	  return goof;
+}
+
+static unsigned long
+fix_bad_pc24 (unsigned long *const reloc_addr, unsigned long value)
+{
+  static void *fix_page;
+  static unsigned int fix_offset;
+  unsigned int *fix_address;
+  if (! fix_page)
+    {
+      fix_page = _dl_mmap (NULL,  4096   , PROT_READ | PROT_WRITE | PROT_EXEC,
+                       MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+      fix_offset = 0;
+    }
+
+  fix_address = (unsigned int *)(fix_page + fix_offset);
+  fix_address[0] = 0xe51ff004;  /* ldr pc, [pc, #-4] */
+  fix_address[1] = value;
+
+  fix_offset += 8;
+  if (fix_offset >= 4096)
+    fix_page = NULL;
+
+  return (unsigned long)fix_address;
+}
+
+static int
+_dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope,
+	      ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)
+{
+	int reloc_type;
+	int symtab_index;
+	unsigned long *reloc_addr;
+	unsigned long symbol_addr;
+	int goof = 0;
+
+	reloc_addr = (unsigned long *) (tpnt->loadaddr + (unsigned long) 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 long) _dl_find_hash(strtab + symtab[symtab_index].st_name, 
+				scope, (reloc_type == R_ARM_JUMP_SLOT ? tpnt : NULL), symbolrel);
+
+		/*
+		 * 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_GLOBAL) {
+			goof++;
+		}
+	}
+
+#if defined (__SUPPORT_LD_DEBUG__)
+	{
+		unsigned long old_val = *reloc_addr;
+#endif
+		switch (reloc_type) {
+			case R_ARM_NONE:
+				break;
+			case R_ARM_ABS32:
+				*reloc_addr += symbol_addr;
+				break;
+			case R_ARM_PC24:
+				{
+					unsigned long addend;
+					long newvalue, topbits;
+
+					addend = *reloc_addr & 0x00ffffff;
+					if (addend & 0x00800000) addend |= 0xff000000;
+
+					newvalue = symbol_addr - (unsigned long)reloc_addr + (addend << 2);
+					topbits = newvalue & 0xfe000000;
+					if (topbits != 0xfe000000 && topbits != 0x00000000)
+					{
+						newvalue = fix_bad_pc24(reloc_addr, symbol_addr)
+							- (unsigned long)reloc_addr + (addend << 2);
+						topbits = newvalue & 0xfe000000;
+						if (topbits != 0xfe000000 && topbits != 0x00000000)
+						{
+							_dl_dprintf(2,"symbol '%s': R_ARM_PC24 relocation out of range.", 
+								symtab[symtab_index].st_name);
+							_dl_exit(1);
+						}
+					}
+					newvalue >>= 2;
+					symbol_addr = (*reloc_addr & 0xff000000) | (newvalue & 0x00ffffff);
+					*reloc_addr = symbol_addr;
+					break;
+				}
+			case R_ARM_GLOB_DAT:
+			case R_ARM_JUMP_SLOT:
+				*reloc_addr = symbol_addr;
+				break;
+			case R_ARM_RELATIVE:
+				*reloc_addr += (unsigned long) tpnt->loadaddr;
+				break;
+			case R_ARM_COPY:						
+#if 0							
+				/* Do this later */
+				_dl_dprintf(2, "Doing copy for symbol ");
+				if (symtab_index) _dl_dprintf(2, strtab + symtab[symtab_index].st_name);
+				_dl_dprintf(2, "\n");
+				_dl_memcpy((void *) symtab[symtab_index].st_value, 
+						(void *) symbol_addr, symtab[symtab_index].st_size);
+#endif
+				break;
+			default:
+				return -1; /*call _dl_exit(1) */
+		}
+#if defined (__SUPPORT_LD_DEBUG__)
+		if(_dl_debug_reloc && _dl_debug_detail)
+			_dl_dprintf(_dl_debug_file, "\tpatch: %x ==> %x @ %x", old_val, *reloc_addr, reloc_addr);
+	}
+
+#endif
+
+	return goof;
+}
+
+static int
+_dl_do_lazy_reloc (struct elf_resolve *tpnt, struct dyn_elf *scope,
+		   ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)
+{
+	int reloc_type;
+	unsigned long *reloc_addr;
+
+	reloc_addr = (unsigned long *) (tpnt->loadaddr + (unsigned long) rpnt->r_offset);
+	reloc_type = ELF32_R_TYPE(rpnt->r_info);
+
+#if defined (__SUPPORT_LD_DEBUG__)
+	{
+		unsigned long old_val = *reloc_addr;
+#endif
+		switch (reloc_type) {
+			case R_ARM_NONE:
+				break;
+			case R_ARM_JUMP_SLOT:
+				*reloc_addr += (unsigned long) tpnt->loadaddr;
+				break;
+			default:
+				return -1; /*call _dl_exit(1) */
+		}
+#if defined (__SUPPORT_LD_DEBUG__)
+		if(_dl_debug_reloc && _dl_debug_detail)
+			_dl_dprintf(_dl_debug_file, "\tpatch: %x ==> %x @ %x", old_val, *reloc_addr, reloc_addr);
+	}
+
+#endif
+	return 0;
+
+}
+
+/* This is done as a separate step, because there are cases where
+   information is first copied and later initialized.  This results in
+   the wrong information being copied.  Someone at Sun was complaining about
+   a bug in the handling of _COPY by SVr4, and this may in fact be what he
+   was talking about.  Sigh. */
+
+/* No, there are cases where the SVr4 linker fails to emit COPY relocs
+   at all */
+static int
+_dl_do_copy (struct elf_resolve *tpnt, struct dyn_elf *scope,
+	     ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)
+{
+        int reloc_type;
+	int symtab_index;
+	unsigned long *reloc_addr;
+	unsigned long symbol_addr;
+	int goof = 0;
+	  
+	reloc_addr = (unsigned long *) (tpnt->loadaddr + (unsigned long) rpnt->r_offset);
+	reloc_type = ELF32_R_TYPE(rpnt->r_info);
+	if (reloc_type != R_ARM_COPY) 
+		return 0;
+	symtab_index = ELF32_R_SYM(rpnt->r_info);
+	symbol_addr = 0;
+		
+	if (symtab_index) {
+
+		symbol_addr = (unsigned long) _dl_find_hash(strtab + 
+			symtab[symtab_index].st_name, scope, 
+			NULL, copyrel);
+		if (!symbol_addr) goof++;
+	}
+	if (!goof) {
+#if defined (__SUPPORT_LD_DEBUG__)
+	        if(_dl_debug_move)
+		  _dl_dprintf(_dl_debug_file,"\n%s move %x bytes from %x to %x",
+			     strtab + symtab[symtab_index].st_name,
+			     symtab[symtab_index].st_size,
+			     symbol_addr, symtab[symtab_index].st_value);
+#endif
+		_dl_memcpy((char *) symtab[symtab_index].st_value, 
+			(char *) symbol_addr, symtab[symtab_index].st_size);
+	}
+
+	return goof;
+}
+
+void _dl_parse_lazy_relocation_information(struct elf_resolve *tpnt, 
+	unsigned long rel_addr, unsigned long rel_size, int type)
+{
+  (void)_dl_parse(tpnt, NULL, rel_addr, rel_size, _dl_do_lazy_reloc);
+}
+
+int _dl_parse_relocation_information(struct elf_resolve *tpnt, 
+	unsigned long rel_addr, unsigned long rel_size, int type)
+{
+  return _dl_parse(tpnt, tpnt->symbol_scope, rel_addr, rel_size, _dl_do_reloc);
+}
+
+int _dl_parse_copy_information(struct dyn_elf *xpnt, unsigned long rel_addr, 
+	unsigned long rel_size, int type)
+{
+  return _dl_parse(xpnt->dyn, xpnt->next, rel_addr, rel_size, _dl_do_copy);
+}
+
diff -urN uClibc/ldso-0.9.24/ldso/arm/ld_syscalls.h uClibc.ldso.24/ldso-0.9.24/ldso/arm/ld_syscalls.h
--- uClibc/ldso-0.9.24/ldso/arm/ld_syscalls.h	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/arm/ld_syscalls.h	2003-09-09 01:11:11.000000000 -0500
@@ -0,0 +1,19 @@
+/* Define the __set_errno macro as nothing so that INLINE_SYSCALL
+ * won't set errno, which is important since we make system calls
+ * before the errno symbol is dynamicly linked. */
+
+#define __set_errno(X) {(void)(X);}
+
+/* Prepare for the case that `__builtin_expect' is not available.  */
+#if __GNUC__ == 2 && __GNUC_MINOR__ < 96
+#define __builtin_expect(x, expected_value) (x)
+#endif
+#ifndef likely
+# define likely(x)	__builtin_expect((!!(x)),1)
+#endif
+#ifndef unlikely
+# define unlikely(x)	__builtin_expect((!!(x)),0)
+#endif
+
+#include "sys/syscall.h"
+
diff -urN uClibc/ldso-0.9.24/ldso/arm/ld_sysdep.h uClibc.ldso.24/ldso-0.9.24/ldso/arm/ld_sysdep.h
--- uClibc/ldso-0.9.24/ldso/arm/ld_sysdep.h	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/arm/ld_sysdep.h	2002-08-09 09:41:04.000000000 -0500
@@ -0,0 +1,124 @@
+/*
+ * Various assmbly language/system dependent  hacks that are required
+ * so that we can minimize the amount of platform specific code.
+ */
+
+/* 
+ * Define this if the system uses RELOCA.
+ */
+#undef ELF_USES_RELOCA
+
+/*
+ * 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)
+
+/*
+ * Initialization sequence for a GOT.
+ */
+#define INIT_GOT(GOT_BASE,MODULE) \
+{				\
+  GOT_BASE[2] = (unsigned long) _dl_linux_resolve; \
+  GOT_BASE[1] = (unsigned long) MODULE; \
+}
+
+/*
+ * Here is a macro to perform a relocation.  This is only used when
+ * bootstrapping the dynamic loader.  RELP is the relocation that we
+ * are performing, REL is the pointer to the address we are relocating.
+ * SYMBOL is the symbol involved in the relocation, and LOAD is the
+ * load address.
+ */
+#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD)		\
+	switch(ELF32_R_TYPE((RELP)->r_info)){			\
+	case R_ARM_ABS32:					\
+	  *REL += SYMBOL;					\
+	  break;						\
+        case R_ARM_PC24:					\
+	    { long newvalue, topbits;				\
+	    unsigned long addend = *REL & 0x00ffffff;		\
+	    if (addend & 0x00800000) addend |= 0xff000000;	\
+	    newvalue=SYMBOL-(unsigned long)REL+(addend<<2);	\
+	    topbits = newvalue & 0xfe000000;			\
+	    if (topbits!=0xfe000000&&topbits!=0x00000000){	\
+	    newvalue = fix_bad_pc24(REL, SYMBOL)		\
+		-(unsigned long)REL+(addend<<2);		\
+	    topbits = newvalue & 0xfe000000;			\
+	    if (topbits!=0xfe000000&&topbits!=0x00000000){	\
+	    SEND_STDERR("R_ARM_PC24 relocation out of range\n");\
+	    _dl_exit(1); } }					\
+	    newvalue>>=2;					\
+	    SYMBOL=(*REL&0xff000000)|(newvalue & 0x00ffffff);	\
+	    *REL=SYMBOL;					\
+	    }							\
+	  break;						\
+	case R_ARM_GLOB_DAT:					\
+	case R_ARM_JUMP_SLOT:					\
+	  *REL = SYMBOL;					\
+	  break;						\
+        case R_ARM_RELATIVE:					\
+	  *REL += (unsigned long) LOAD;				\
+	  break;						\
+        case R_ARM_NONE:					\
+	  break;						\
+	default:						\
+	  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.
+ */
+
+#define START()   return _dl_elf_main;      
+
+
+
+/* Here we define the magic numbers that this dynamic loader should accept */
+
+#define MAGIC1 EM_ARM
+#undef  MAGIC2
+/* Used for error messages */
+#define ELF_TARGET "ARM"
+
+struct elf_resolve;
+unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
+
+static inline unsigned long arm_modulus(unsigned long m, unsigned long p) {
+	unsigned long i,t,inc;
+        i=p; t=0;
+        while(!(i&(1<<31))) {
+                i<<=1;
+                t++;
+        }
+        t--;
+        for(inc=t;inc>2;inc--) {
+                i=p<<inc;
+                if(i&(1<<31))
+                        break;
+                while(m>=i) {
+                        m-=i;
+                        i<<=1;
+                        if(i&(1<<31))
+                                break;
+                        if(i<p)
+                                break;
+                }
+        }
+        while(m>=p) {
+                m-=p;
+        }
+        return m;
+}
+
+#define do_rem(result, n, base)  result=arm_modulus(n,base);
+
+/* 4096 bytes alignment */
+#define PAGE_ALIGN 0xfffff000
+#define ADDR_ALIGN 0xfff
+#define OFFS_ALIGN 0x7ffff000
diff -urN uClibc/ldso-0.9.24/ldso/arm/resolve.S uClibc.ldso.24/ldso-0.9.24/ldso/arm/resolve.S
--- uClibc/ldso-0.9.24/ldso/arm/resolve.S	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/arm/resolve.S	2002-08-12 04:03:30.000000000 -0500
@@ -0,0 +1,43 @@
+/*
+ * 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 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
+ */
+
+#define sl r10
+#define fp r11
+#define ip r12
+
+.text
+.globl _dl_linux_resolve
+.type _dl_linux_resolve,%function
+.align 4;
+
+_dl_linux_resolve:
+	stmdb sp!, {r0, r1, r2, r3, sl, fp}
+	sub r1, ip, lr
+	sub r1, r1, #4
+	add r1, r1, r1
+	ldr r0, [lr, #-4]
+	mov r3,r0
+
+	bl _dl_linux_resolver
+
+	mov ip, r0
+	ldmia sp!, {r0, r1, r2, r3, sl, fp, lr}
+	mov pc,ip
+.size _dl_linux_resolve, .-_dl_linux_resolve
diff -urN uClibc/ldso-0.9.24/ldso/cris/boot1_arch.h uClibc.ldso.24/ldso-0.9.24/ldso/cris/boot1_arch.h
--- uClibc/ldso-0.9.24/ldso/cris/boot1_arch.h	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/cris/boot1_arch.h	2003-09-19 07:11:43.000000000 -0500
@@ -0,0 +1,17 @@
+/*
+ * This code fix the stack pointer so that the dynamic linker
+ * can find argc, argv and auxvt (Auxillary Vector Table).
+ */
+asm(""					\
+"	.text\n"			\
+"	.globl _dl_boot\n"		\
+"	.type _dl_boot,@function\n"	\
+"_dl_boot:\n"				\
+"	move.d $sp,$r10\n"		\
+"	move.d $pc,$r9\n"		\
+"	add.d _dl_boot2 - ., $r9\n"	\
+"	jsr $r9\n"			\
+);
+
+#define _dl_boot _dl_boot2
+#define LD_BOOT(X) static void * __attribute__ ((unused)) _dl_boot(X)
diff -urN uClibc/ldso-0.9.24/ldso/cris/elfinterp.c uClibc.ldso.24/ldso-0.9.24/ldso/cris/elfinterp.c
--- uClibc/ldso-0.9.24/ldso/cris/elfinterp.c	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/cris/elfinterp.c	2003-09-30 06:51:11.000000000 -0500
@@ -0,0 +1,414 @@
+/*
+ * CRIS ELF shared library loader support.
+ *
+ * Program to load an elf binary on a linux system, and run it.
+ * References to symbols in sharable libraries can be resolved
+ * by either an ELF sharable library or a linux style of shared
+ * library.
+ *
+ * Copyright (C) 2002, Axis Communications AB
+ * All rights reserved
+ *
+ * Author: Tobias Anderberg, <tobiasa@axis.com>
+ *
+ * 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.
+ */
+
+/* Support for the LD_DEBUG variable. */
+#if defined (__SUPPORT_LD_DEBUG__)
+static const char *_dl_reltypes_tab[] = {
+	[0]		"R_CRIS_NONE", "R_CRIS_8", "R_CRIS_16", "R_CRIS_32",
+	[4]		"R_CRIS_8_PCREL", "R_CRIS_16_PCREL", "R_CRIS_32_PCREL", "R_CRIS_GNU_VTINHERIT",
+	[8]		"R_CRIS_GNU_VTENTRY", "R_CRIS_COPY", "R_CRIS_GLOB_DAT", "R_CRIS_JUMP_SLOT",
+	[16]	"R_CRIS_RELATIVE", "R_CRIS_16_GOT", "R_CRIS_32_GOT", "R_CRIS_16_GOTPLT",
+	[32]	"R_CRIS_32_GOTPLT", "R_CRIS_32_GOTREL", "R_CRIS_32_PLT_GOTREL", "R_CRIS_32_PLT_PCREL",
+
+};
+
+
+static const char *
+_dl_reltypes(int type)
+{
+	const char *str;
+	static char buf[22];
+
+	if (type >= (sizeof(_dl_reltypes_tab)/sizeof(_dl_reltypes_tab[0])) ||
+		NULL == (str = _dl_reltypes_tab[type]))
+		str = _dl_simple_ltoa(buf, (unsigned long) (type));
+	
+	return str;
+}
+
+static void 
+debug_sym(Elf32_Sym *symtab, char *strtab, int symtab_index)
+{ 
+	if (_dl_debug_symbols) { 
+		if (symtab_index) {
+			_dl_dprintf(_dl_debug_file, 
+				"\n%s\tvalue=%x\tsize=%x\tinfo=%x\tother=%x\tshndx=%x",
+				strtab + symtab[symtab_index].st_name,
+				symtab[symtab_index].st_value,
+				symtab[symtab_index].st_size,
+				symtab[symtab_index].st_info,
+				symtab[symtab_index].st_other,
+				symtab[symtab_index].st_shndx);
+		}
+  	}
+}
+
+static void
+debug_reloc(Elf32_Sym *symtab, char *strtab, ELF_RELOC *rpnt)
+{
+	if (_dl_debug_reloc) {
+		int symtab_index;
+		const char *sym;
+
+		symtab_index = ELF32_R_SYM(rpnt->r_info);
+		sym = symtab_index ? strtab + symtab[symtab_index].st_name : "sym=0x0";
+
+		if (_dl_debug_symbols)
+			_dl_dprintf(_dl_debug_file, "\n\t");
+		else
+			_dl_dprintf(_dl_debug_file, "\n%s\n\t", sym);
+
+#ifdef ELF_USES_RELOCA
+		_dl_dprintf(_dl_debug_file, "%s\toffset=%x\taddend=%x",
+			_dl_reltypes(ELF32_R_TYPE(rpnt->r_info)),
+			rpnt->r_offset,
+			rpnt->r_addend);
+#else
+		_dl_dprintf(_dl_debug_file, "%s\toffset%x\n",
+			_dl_reltypes(ELF32_R_TYPE(rpnt->r_info)),
+			rpnt->r_offset);
+#endif
+	}
+}
+#endif /* __SUPPORT_LD_DEBUG__ */
+
+/* Defined in resolve.S. */
+extern int _dl_linux_resolv(void);
+
+unsigned long
+_dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
+{
+	int reloc_type;
+	int symtab_index;
+	char *strtab;
+	char *symname;
+	char *new_addr;
+	char *rel_addr;
+	char **got_addr;
+	Elf32_Sym *symtab;
+	ELF_RELOC *this_reloc;
+	unsigned long instr_addr;
+
+	rel_addr = (char *) (tpnt->dynamic_info[DT_JMPREL] + tpnt->loadaddr);
+
+	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);
+
+	symtab = (Elf32_Sym *) (intptr_t)(tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
+	strtab = (char *)(tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
+	symname = strtab + symtab[symtab_index].st_name;
+
+	if (reloc_type != R_CRIS_JUMP_SLOT) {
+		_dl_dprintf(2, "%s: Incorrect relocation type for jump relocations.\n",
+			_dl_progname);
+		_dl_exit(1);
+	}
+
+	/* Fetch the address of the jump instruction to fix up. */
+	instr_addr = ((unsigned long) this_reloc->r_offset + (unsigned long) tpnt->loadaddr);
+	got_addr = (char **) instr_addr;
+
+	/* Fetch the address of the GOT entry. */
+	new_addr = _dl_find_hash(symname, tpnt->symbol_scope, tpnt, resolver);
+
+	if (!new_addr) {
+		new_addr = _dl_find_hash(symname, NULL, NULL, resolver);
+
+		if (new_addr)
+			return (unsigned long) new_addr;
+
+		_dl_dprintf(2, "%s: Can't resolv symbol '%s'\n", _dl_progname, symname);
+		_dl_exit(1);
+	}
+
+#if defined (__SUPPORT_LD_DEBUG__)
+	if (_dl_debug_bindings) {
+		_dl_dprintf(_dl_debug_file, "\nresolve function: %s", symname);
+		
+		if (_dl_debug_detail)
+			_dl_dprintf(_dl_debug_file, "\tpatch %x ==> %x @ %x", *got_addr, new_addr, got_addr);
+	}
+#endif
+
+	*got_addr = new_addr;
+	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, Elf32_Sym *symtab, char *strtab))
+{
+	int symtab_index;
+	int res;
+	unsigned int i;
+	char *strtab;
+	Elf32_Sym *symtab;
+	ELF_RELOC *rpnt;
+
+	/* Parse the relocation information. */
+	rpnt = (ELF_RELOC *) (intptr_t) (rel_addr + tpnt->loadaddr);
+	rel_size /= sizeof(ELF_RELOC);
+
+	symtab = (Elf32_Sym *) (intptr_t) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
+	strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
+
+	for (i = 0; i < rel_size; i++, rpnt++) {
+		symtab_index = ELF32_R_SYM(rpnt->r_info);
+
+		/* 
+		 * Make sure the same symbols that the linker resolved when it
+		 * bootstapped itself isn't resolved again.
+		 */
+		if (!symtab_index && tpnt->libtype == program_interpreter)
+			continue;
+
+		if (symtab_index && tpnt->libtype == program_interpreter &&
+			_dl_symbol(strtab + symtab[symtab_index].st_name))
+			continue;
+
+#if defined (__SUPPORT_LD_DEBUG__)
+		debug_sym(symtab, strtab, symtab_index);
+		debug_reloc(symtab, strtab, rpnt);
+#endif
+
+		/* Pass over to actual relocation function. */
+		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 (res < 0) {
+			int reloc_type = ELF32_R_TYPE(rpnt->r_info);
+
+#if defined (__SUPPORT_LD_DEBUG__)
+			_dl_dprintf(2, "can't handle relocation type '%s'\n", _dl_reltypes(reloc_type));
+#else
+			_dl_dprintf(2, "can't handle relocation type %x\n", reloc_type);
+#endif
+			_dl_exit(-res);
+		}
+		else if (res > 0) {
+			_dl_dprintf(2, "can't resolv symbol\n");
+			return res;
+		}
+	}
+
+	return 0;
+}
+
+static int
+_dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, ELF_RELOC *rpnt,
+	Elf32_Sym *symtab, char *strtab)
+{
+	int reloc_type;
+	int symtab_index;
+	char *symname;
+	unsigned long *reloc_addr;
+	unsigned symbol_addr;
+#if defined (__SUPPORT_LD_DEBUG__)
+	unsigned long old_val;
+#endif
+
+	reloc_addr = (unsigned long *)(intptr_t)(tpnt->loadaddr + (unsigned long) 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) {
+		if (symtab[symtab_index].st_shndx != SHN_UNDEF && 
+			ELF32_ST_BIND(symtab[symtab_index].st_info) == STB_LOCAL) {
+			symbol_addr = (unsigned long) tpnt->loadaddr;
+		}
+		else {
+			symbol_addr = (unsigned long) _dl_find_hash(symname, scope,
+				(reloc_type == R_CRIS_JUMP_SLOT ? tpnt : NULL), symbolrel);
+		}
+
+		if (!symbol_addr && ELF32_ST_BIND(symtab[symtab_index].st_info) == STB_GLOBAL) {
+#if defined (__SUPPORT_LD_DEBUG__)
+			_dl_dprintf(2, "\tglobal symbol '%s' already defined in '%s'\n",
+				symname, tpnt->libname);
+#endif
+			return 0;
+		}
+
+		symbol_addr += rpnt->r_addend;
+	}
+
+#if defined (__SUPPORT_LD_DEBUG__)
+	old_val = *reloc_addr;
+#endif
+
+	switch (reloc_type) {
+		case R_CRIS_NONE:
+			break;
+		case R_CRIS_GLOB_DAT:
+		case R_CRIS_JUMP_SLOT:
+		case R_CRIS_32:
+		case R_CRIS_COPY:
+			*reloc_addr = symbol_addr;
+			break;
+		case R_CRIS_RELATIVE:
+			*reloc_addr = (unsigned long) tpnt->loadaddr + rpnt->r_addend;
+			break;
+		default:
+			return -1;	/* Call _dl_exit(1). */
+	}
+
+#if defined (__SUPPORT_LD_DEBUG__)
+	if (_dl_debug_reloc && _dl_debug_detail)
+		_dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x", old_val, *reloc_addr, reloc_addr);
+#endif
+
+	return 0;
+}
+
+static int
+_dl_do_lazy_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, ELF_RELOC *rpnt,
+	Elf32_Sym *symtab, char *strtab)
+{
+	int reloc_type;
+	unsigned long *reloc_addr;
+#if defined (__SUPPORT_LD_DEBUG__)
+	unsigned long old_val;
+#endif
+
+	/* Don't care about these, just keep the compiler happy. */
+	(void) scope;
+	(void) symtab;
+	(void) strtab;
+
+	reloc_addr = (unsigned long *)(intptr_t)(tpnt->loadaddr + (unsigned long) rpnt->r_offset);
+	reloc_type = ELF32_R_TYPE(rpnt->r_info);
+
+#if defined (__SUPPORT_LD_DEBUG__)
+	old_val = *reloc_addr;
+#endif
+
+	switch (reloc_type) {
+		case R_CRIS_NONE:
+			break;
+		case R_CRIS_JUMP_SLOT:
+			*reloc_addr += (unsigned long) tpnt->loadaddr;
+			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", old_val, *reloc_addr, reloc_addr);
+#endif
+
+	return 0;
+}
+
+static int
+_dl_do_copy_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, ELF_RELOC *rpnt,
+	Elf32_Sym *symtab, char *strtab)
+{
+	int goof;
+	int reloc_type;
+	int symtab_index;
+	char *symname;
+	unsigned long *reloc_addr;
+	unsigned long symbol_addr;
+
+	reloc_addr = (unsigned long *)(intptr_t) (tpnt->loadaddr + (unsigned long) rpnt->r_offset);
+	reloc_type = ELF32_R_TYPE(rpnt->r_info);
+
+	if (reloc_type != R_CRIS_COPY)
+		return 0;
+	
+	symtab_index = ELF32_R_SYM(rpnt->r_info);
+	symbol_addr = 0;
+	symname = strtab + symtab[symtab_index].st_name;
+	goof = 0;
+
+	if (symtab_index) {
+		symbol_addr = (unsigned long) _dl_find_hash(symname, scope, NULL, copyrel);
+
+		if (!symbol_addr)
+			goof++;
+	}
+
+	if (!goof) {
+#if defined (__SUPPORT_LD_DEBUG__)
+		if (_dl_debug_move)
+			_dl_dprintf(_dl_debug_file, "\n%s move %x bytes from %x to %x",
+				symname, symtab[symtab_index].st_size, symbol_addr, symtab[symtab_index].st_value);
+#endif
+			_dl_memcpy((char *) symtab[symtab_index].st_value,
+				(char *) symbol_addr, symtab[symtab_index].st_size);
+	}
+
+	return goof;
+}
+
+/* External interface to the generic part of the dynamic linker. */
+
+int
+_dl_parse_relocation_information(struct elf_resolve *tpnt, unsigned long rel_addr,
+	unsigned long rel_size, int type)
+{
+	/* Keep the compiler happy. */
+	(void) type;
+	return _dl_parse(tpnt, tpnt->symbol_scope, rel_addr, rel_size, _dl_do_reloc);
+}
+void
+_dl_parse_lazy_relocation_information(struct elf_resolve *tpnt, unsigned long rel_addr,
+	unsigned long rel_size, int type)
+{
+	/* Keep the compiler happy. */
+	(void) type;
+	_dl_parse(tpnt, NULL, rel_addr, rel_size, _dl_do_lazy_reloc);
+}
+
+int
+_dl_parse_copy_information(struct dyn_elf *xpnt, unsigned long rel_addr,
+	unsigned long rel_size, int type)
+{
+	/* Keep the compiler happy. */
+	(void) type;
+	return _dl_parse(xpnt->dyn, xpnt->next, rel_addr, rel_size, _dl_do_copy_reloc);
+}
diff -urN uClibc/ldso-0.9.24/ldso/cris/ld_syscalls.h uClibc.ldso.24/ldso-0.9.24/ldso/cris/ld_syscalls.h
--- uClibc/ldso-0.9.24/ldso/cris/ld_syscalls.h	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/cris/ld_syscalls.h	2002-09-23 05:37:16.000000000 -0500
@@ -0,0 +1,7 @@
+/* 
+ * Define the __set_errno macro as nothing so that INLINE_SYSCALL
+ * won't set errno, which is important since we make system calls
+ * before the errno symbol is dynamicly linked. 
+ */
+#define __set_errno(X) {(void)(X);}
+#include "sys/syscall.h"
diff -urN uClibc/ldso-0.9.24/ldso/cris/ld_sysdep.h uClibc.ldso.24/ldso-0.9.24/ldso/cris/ld_sysdep.h
--- uClibc/ldso-0.9.24/ldso/cris/ld_sysdep.h	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/cris/ld_sysdep.h	2003-08-27 07:59:23.000000000 -0500
@@ -0,0 +1,112 @@
+/* CRIS can never use Elf32_Rel relocations. */
+#define ELF_USES_RELOCA
+
+/*
+ * 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)
+
+/*
+ * Initialization sequence for a GOT.
+ */
+#define INIT_GOT(GOT_BASE,MODULE)				\
+{								\
+	GOT_BASE[1] = (unsigned long) MODULE; 			\
+	GOT_BASE[2] = (unsigned long) _dl_linux_resolve; 	\
+}
+
+/*
+ * Here is a macro to perform a relocation.  This is only used when
+ * bootstrapping the dynamic loader.  RELP is the relocation that we
+ * are performing, REL is the pointer to the address we are relocating.
+ * SYMBOL is the symbol involved in the relocation, and LOAD is the
+ * load address.
+ */
+#define PERFORM_BOOTSTRAP_RELOC(RELP, REL, SYMBOL, LOAD)		\
+	switch (ELF32_R_TYPE((RELP)->r_info)) {				\
+		case R_CRIS_GLOB_DAT:					\
+		case R_CRIS_JUMP_SLOT:					\
+		case R_CRIS_32:						\
+			*REL = SYMBOL;					\
+			break;						\
+		case R_CRIS_16_PCREL:					\
+			*(short *) *REL = SYMBOL + (RELP)->r_addend - *REL - 2;	\
+			break;						\
+		case R_CRIS_32_PCREL:					\
+			*REL = SYMBOL + (RELP)->r_addend - *REL - 4;	\
+			break;						\
+		case R_CRIS_NONE:					\
+			break;						\
+		case R_CRIS_RELATIVE:					\
+			*REL = (unsigned long) LOAD + (RELP)->r_addend;	\
+			break;						\
+		default:						\
+			_dl_exit(1);					\
+			break;						\
+	}
+
+/*
+ * Transfer control to the user's application once the dynamic loader
+ * is done. This routine has to exit the current function, then call
+ * _dl_elf_main.
+ */
+#define START() __asm__ volatile ("moveq 0,$r8\n\t" \
+				  "move $r8,$srp\n\t" \
+				  "move.d %1,$sp\n\t" \
+				  "jump %0\n\t" \
+				  : : "r" (_dl_elf_main), "r" (args))
+
+/* Defined some magic numbers that this ld.so should accept. */
+#define MAGIC1 EM_CRIS
+#undef MAGIC2
+#define ELF_TARGET "CRIS"
+
+struct elf_resolve;
+extern unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry);
+
+/* Cheap modulo implementation, taken from arm/ld_sysdep.h. */
+static inline unsigned long
+cris_mod(unsigned long m, unsigned long p)
+{
+	unsigned long i, t, inc;
+
+	i = p;
+	t = 0;
+
+	while (!(i & (1 << 31))) {
+		i <<= 1;
+		t++;
+	}
+
+	t--;
+
+	for (inc = t; inc > 2; inc--) {
+		i = p << inc;
+
+		if (i & (1 << 31))
+			break;
+
+		while (m >= i) {
+			m -= i;
+			i <<= 1;
+			if (i & (1 << 31))
+				break;
+			if (i < p)
+				break;
+		}
+	}
+
+	while (m >= p)
+		m -= p;
+
+	return m;
+}
+
+#define do_rem(result, n, base) result = cris_mod(n, base);
+
+/* 8192 bytes alignment */
+#define PAGE_ALIGN 0xffffe000
+#define ADDR_ALIGN 0x1fff
+#define OFFS_ALIGN 0xffffe000
diff -urN uClibc/ldso-0.9.24/ldso/cris/resolve.S uClibc.ldso.24/ldso-0.9.24/ldso/cris/resolve.S
--- uClibc/ldso-0.9.24/ldso/cris/resolve.S	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/cris/resolve.S	2002-09-16 03:11:43.000000000 -0500
@@ -0,0 +1,48 @@
+/*
+ * This function is _not_ called directly.  It is jumped to from PLT 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.  When we get called 
+ * the stack contains reloc_offset and tpnt is in MOF.
+ *
+ * We save all the registers, setup R10 and R11 with the right arguments 
+ * then call _dl_linux_resolver(tpnt, reloc_offset). _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.
+ */		  
+
+.globl _dl_linux_resolve
+.type _dl_linux_resolve,@function
+
+_dl_linux_resolve:
+	push $r13
+	push $r12
+	push $r11
+	push $r10
+	push $r9
+	push $srp
+	move.d [$sp+6*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
+#else
+	jsr _dl_linux_resolver
+#endif
+	move.d $r10,[$sp+6*4]
+	pop $srp
+	pop $r9
+	pop $r10
+	pop $r11
+	pop $r12
+	pop $r13
+	jump [$sp+]
+
+	.size _dl_linux_resolve, . - _dl_linux_resolve
diff -urN uClibc/ldso-0.9.24/ldso/hash.c uClibc.ldso.24/ldso-0.9.24/ldso/hash.c
--- uClibc/ldso-0.9.24/ldso/hash.c	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/hash.c	2003-08-19 08:11:06.000000000 -0500
@@ -0,0 +1,327 @@
+/* vi: set sw=4 ts=4: */
+/* Program to load an ELF binary on a linux system, and run it
+ * after resolving ELF shared library symbols
+ *
+ * Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald, 
+ *				David Engel, Hongjiu Lu and Mitch D'Souza
+ * Copyright (C) 2001-2002, Erik Andersen
+ *
+ * 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.
+ */
+
+
+/* Various symbol table handling functions, including symbol lookup */
+
+/*
+ * This is the start of the linked list that describes all of the files present
+ * in the system with pointers to all of the symbol, string, and hash tables, 
+ * as well as all of the other good stuff in the binary.
+ */
+
+struct elf_resolve *_dl_loaded_modules = NULL;
+
+/*
+ * This is the list of modules that are loaded when the image is first
+ * started.  As we add more via dlopen, they get added into other
+ * chains.
+ */
+struct dyn_elf *_dl_symbol_tables = NULL;
+
+/*
+ * This is the list of modules that are loaded via dlopen.  We may need
+ * to search these for RTLD_GLOBAL files.
+ */
+struct dyn_elf *_dl_handles = NULL;
+
+
+/*
+ * 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.
+ */
+
+unsigned long _dl_elf_hash(const char *name)
+{
+	unsigned long hash = 0;
+	unsigned long tmp;
+
+	while (*name) {
+		hash = (hash << 4) + *name++;
+		if ((tmp = hash & 0xf0000000))
+			hash ^= tmp >> 24;
+		hash &= ~tmp;
+	};
+	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
+ * externals properly.
+ */
+
+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)
+{
+	unsigned long *hash_addr;
+	struct elf_resolve *tpnt;
+	int i;
+
+	if (!_dl_loaded_modules) {
+		tpnt = _dl_loaded_modules = 
+		    (struct elf_resolve *) _dl_malloc(sizeof(struct elf_resolve));
+		_dl_memset(tpnt, 0, sizeof(struct elf_resolve));
+	} else {
+		tpnt = _dl_loaded_modules;
+		while (tpnt->next)
+			tpnt = tpnt->next;
+		tpnt->next = (struct elf_resolve *) _dl_malloc(sizeof(struct elf_resolve));
+		_dl_memset(tpnt->next, 0, sizeof(struct elf_resolve));
+		tpnt->next->prev = tpnt;
+		tpnt = tpnt->next;
+	};
+
+	tpnt->next = NULL;
+	tpnt->init_flag = 0;
+	tpnt->libname = _dl_strdup(libname);
+	tpnt->dynamic_addr = (ElfW(Dyn) *)dynamic_addr;
+	tpnt->dynamic_size = dynamic_size;
+	tpnt->libtype = loaded_file;
+
+	if (dynamic_info[DT_HASH] != 0) {
+		hash_addr = (unsigned long *) (intptr_t)(dynamic_info[DT_HASH] + loadaddr);
+		tpnt->nbucket = *hash_addr++;
+		tpnt->nchain = *hash_addr++;
+		tpnt->elf_buckets = hash_addr;
+		hash_addr += tpnt->nbucket;
+		tpnt->chains = hash_addr;
+	}
+	tpnt->loadaddr = (ElfW(Addr))loadaddr;
+	for (i = 0; i < 24; i++)
+		tpnt->dynamic_info[i] = dynamic_info[i];
+#ifdef __mips__
+	{
+		Elf32_Dyn *dpnt = (Elf32_Dyn *) dynamic_addr;
+
+		while(dpnt->d_tag) {
+			if (dpnt->d_tag == DT_MIPS_GOTSYM)
+				tpnt->mips_gotsym = dpnt->d_un.d_val;
+			if (dpnt->d_tag == DT_MIPS_LOCAL_GOTNO)
+				tpnt->mips_local_gotno = dpnt->d_un.d_val;
+			if (dpnt->d_tag == DT_MIPS_SYMTABNO)
+				tpnt->mips_symtabno = dpnt->d_un.d_val;
+			dpnt++;
+		}
+	}
+#endif
+	return tpnt;
+}
+
+
+/*
+ * This function resolves externals, and this is either called when we process
+ * relocations or when we call an entry in the PLT table for the first time.
+ */
+
+char *_dl_find_hash(const char *name, struct dyn_elf *rpnt1, 
+	struct elf_resolve *f_tpnt, enum caller_type caller_type)
+{
+	struct elf_resolve *tpnt;
+	int si;
+	char *pnt;
+	int pass;
+	char *strtab;
+	Elf32_Sym *symtab;
+	unsigned long elf_hash_number, hn;
+	char *weak_result;
+	struct elf_resolve *first_def;
+	struct dyn_elf *rpnt, first;
+	char *data_result = 0;		/* nakao */
+
+	weak_result = 0;
+	elf_hash_number = _dl_elf_hash(name);
+
+	/* A quick little hack to make sure that any symbol in the executable
+	   will be preferred to one in a shared library.  This is necessary so
+	   that any shared library data symbols referenced in the executable
+	   will be seen at the same address by the executable, shared libraries
+	   and dynamically loaded code. -Rob Ryan (robr@cmu.edu) */
+	if (_dl_symbol_tables && !caller_type && rpnt1) {
+		first = (*_dl_symbol_tables);
+		first.next = rpnt1;
+		rpnt1 = (&first);
+	}
+
+	/*
+	 * The passes are so that we can first search the regular symbols
+	 * for whatever module was specified, and then search anything
+	 * loaded with RTLD_GLOBAL.  When pass is 1, it means we are just
+	 * starting the first dlopened module, and anything above that
+	 * is just the next one in the chain.
+	 */
+	for (pass = 0; (1 == 1); pass++) {
+
+		/*
+		 * If we are just starting to search for RTLD_GLOBAL, setup
+		 * the pointer for the start of the search.
+		 */
+		if (pass == 1) {
+			rpnt1 = _dl_handles;
+		}
+
+		/*
+		 * Anything after this, we need to skip to the next module.
+		 */
+		else if (pass >= 2) {
+			rpnt1 = rpnt1->next_handle;
+		}
+
+		/*
+		 * Make sure we still have a module, and make sure that this
+		 * module was loaded with RTLD_GLOBAL.
+		 */
+		if (pass != 0) {
+			if (rpnt1 == NULL)
+				break;
+			if ((rpnt1->flags & RTLD_GLOBAL) == 0)
+				continue;
+		}
+
+		for (rpnt = (rpnt1 ? rpnt1 : _dl_symbol_tables); rpnt; rpnt = rpnt->next) {
+			tpnt = rpnt->dyn;
+
+			/*
+			 * The idea here is that if we are using dlsym, we want to
+			 * first search the entire chain loaded from dlopen, and
+			 * return a result from that if we found anything.  If this
+			 * fails, then we continue the search into the stuff loaded
+			 * when the image was activated.  For normal lookups, we start
+			 * with rpnt == NULL, so we should never hit this.  
+			 */
+			if (tpnt->libtype == elf_executable && weak_result != 0) {
+				break;
+			}
+
+			/*
+			 * Avoid calling .urem here.
+			 */
+			do_rem(hn, elf_hash_number, tpnt->nbucket);
+			symtab = (Elf32_Sym *) (intptr_t) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
+			strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
+			/*
+			 * This crap is required because the first instance of a
+			 * symbol on the chain will be used for all symbol references.
+			 * Thus this instance must be resolved to an address that
+			 * contains the actual function, 
+			 */
+
+			first_def = NULL;
+
+			for (si = tpnt->elf_buckets[hn]; si; si = tpnt->chains[si]) {
+				pnt = strtab + symtab[si].st_name;
+
+				if (_dl_strcmp(pnt, name) == 0 &&
+				    symtab[si].st_value != 0)
+				{
+				  if ((ELF32_ST_TYPE(symtab[si].st_info) == STT_FUNC ||
+				       ELF32_ST_TYPE(symtab[si].st_info) == STT_NOTYPE ||
+				       ELF32_ST_TYPE(symtab[si].st_info) == STT_OBJECT) &&
+				      symtab[si].st_shndx != SHN_UNDEF) {
+
+					/* Here we make sure that we find a module where the symbol is
+					 * actually defined.
+					 */
+
+					if (f_tpnt) {
+						if (!first_def)
+							first_def = tpnt;
+						if (first_def == f_tpnt
+							&& symtab[si].st_shndx == 0)
+							continue;
+					}
+
+					switch (ELF32_ST_BIND(symtab[si].st_info)) {
+					case STB_GLOBAL:
+						if (tpnt->libtype != elf_executable && 
+							ELF32_ST_TYPE(symtab[si].st_info) 
+							== STT_NOTYPE) 
+						{	/* nakao */
+							data_result = (char *)tpnt->loadaddr + 
+							    symtab[si].st_value;	/* nakao */
+							break;	/* nakao */
+						} else	/* nakao */
+							return (char*)tpnt->loadaddr + symtab[si].st_value;
+					case STB_WEAK:
+						if (!weak_result)
+							weak_result = (char *)tpnt->loadaddr + symtab[si].st_value;
+						break;
+					default:	/* Do local symbols need to be examined? */
+						break;
+					}
+				  }
+#ifndef __mips__
+				  /*
+				   * References to the address of a function from an executable file and
+				   * the shared objects associated with it might not resolve to the same
+				   * value. To allow comparisons of function addresses we must resolve
+				   * to the address of the plt entry of the executable instead of the
+				   * real function address.
+				   * see "TIS ELF Specification Version 1.2, Book 3, A-11 (Function
+				   * Adresses) 
+				   */				 
+				  if (resolver != caller_type &&
+				      NULL==f_tpnt && /*trick: don't  handle R_??_JMP_SLOT reloc type*/
+				      tpnt->libtype == elf_executable &&
+				      ELF32_ST_TYPE(symtab[si].st_info) == STT_FUNC &&
+				      symtab[si].st_shndx == SHN_UNDEF)
+				  {
+				      return (char*)symtab[si].st_value;
+				  }
+#endif
+				}
+			}
+		}
+	}
+	if (data_result)
+		return data_result;		/* nakao */
+	return weak_result;
+}
diff -urN uClibc/ldso-0.9.24/ldso/i386/boot1_arch.h uClibc.ldso.24/ldso-0.9.24/ldso/i386/boot1_arch.h
--- uClibc/ldso-0.9.24/ldso/i386/boot1_arch.h	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/i386/boot1_arch.h	2002-08-08 09:35:31.000000000 -0500
@@ -0,0 +1,7 @@
+/* Any assmbly language/system dependent hacks needed to setup boot1.c so it
+ * will work as expected and cope with whatever platform specific wierdness is
+ * needed for this architecture.  See arm/boot1_arch.h for an example of what
+ * can be done.
+ */
+
+#define LD_BOOT(X)   void _dl_boot (X)
diff -urN uClibc/ldso-0.9.24/ldso/i386/elfinterp.c uClibc.ldso.24/ldso-0.9.24/ldso/i386/elfinterp.c
--- uClibc/ldso-0.9.24/ldso/i386/elfinterp.c	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/i386/elfinterp.c	2003-11-06 16:09:38.000000000 -0600
@@ -0,0 +1,415 @@
+/* vi: set sw=4 ts=4: */
+/* i386 ELF shared library loader suppport
+ *
+ * Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald, 
+ *				David Engel, Hongjiu Lu and Mitch D'Souza
+ * Copyright (C) 2001-2002, Erik Andersen
+ *
+ * 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.
+ */
+
+#if defined (__SUPPORT_LD_DEBUG__)
+static const char *_dl_reltypes_tab[] =
+{
+  [0]	"R_386_NONE",	    "R_386_32",	    "R_386_PC32",	"R_386_GOT32",
+  [4]	"R_386_PLT32",	    "R_386_COPY",   "R_386_GLOB_DAT",	"R_386_JMP_SLOT",
+  [8]	"R_386_RELATIVE",   "R_386_GOTOFF", "R_386_GOTPC",
+};
+
+static const char *
+_dl_reltypes(int type)
+{
+  static char buf[22];  
+  const char *str;
+  
+  if (type >= (int)(sizeof (_dl_reltypes_tab)/sizeof(_dl_reltypes_tab[0])) ||
+      NULL == (str = _dl_reltypes_tab[type]))
+  {
+    str =_dl_simple_ltoa( buf, (unsigned long)(type));
+  }
+  return str;
+}
+
+static 
+void debug_sym(Elf32_Sym *symtab,char *strtab,int symtab_index)
+{
+  if(_dl_debug_symbols)
+  {
+    if(symtab_index){
+      _dl_dprintf(_dl_debug_file, "\n%s\n\tvalue=%x\tsize=%x\tinfo=%x\tother=%x\tshndx=%x",
+		  strtab + symtab[symtab_index].st_name,
+		  symtab[symtab_index].st_value,
+		  symtab[symtab_index].st_size,
+		  symtab[symtab_index].st_info,
+		  symtab[symtab_index].st_other,
+		  symtab[symtab_index].st_shndx);
+    }
+  }
+}
+
+static void debug_reloc(Elf32_Sym *symtab,char *strtab, ELF_RELOC *rpnt)
+{
+  if(_dl_debug_reloc)
+  {
+    int symtab_index;
+    const char *sym;
+    symtab_index = ELF32_R_SYM(rpnt->r_info);
+    sym = symtab_index ? strtab + symtab[symtab_index].st_name : "sym=0x0";
+    
+  if(_dl_debug_symbols)
+	  _dl_dprintf(_dl_debug_file, "\n\t");
+  else
+	  _dl_dprintf(_dl_debug_file, "\n%s\n\t", sym);
+#ifdef ELF_USES_RELOCA
+    _dl_dprintf(_dl_debug_file, "%s\toffset=%x\taddend=%x",
+		_dl_reltypes(ELF32_R_TYPE(rpnt->r_info)),
+		rpnt->r_offset,
+		rpnt->r_addend);
+#else
+    _dl_dprintf(_dl_debug_file, "%s\toffset=%x\n",
+		_dl_reltypes(ELF32_R_TYPE(rpnt->r_info)),
+		rpnt->r_offset);
+#endif
+  }
+}
+#endif
+
+/* Program to load an ELF binary on a linux system, and run it.
+   References to symbols in sharable libraries can be resolved by either
+   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. */
+
+extern int _dl_linux_resolve(void);
+
+unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
+{
+	int reloc_type;
+	ELF_RELOC *this_reloc;
+	char *strtab;
+	Elf32_Sym *symtab;
+	int symtab_index;
+	char *rel_addr;
+	char *new_addr;
+	char **got_addr;
+	unsigned long instr_addr;
+	char *symname;
+
+	rel_addr = (char *) (tpnt->dynamic_info[DT_JMPREL] + tpnt->loadaddr);
+
+	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);
+
+	symtab = (Elf32_Sym *)(intptr_t) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
+	strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
+	symname= strtab + symtab[symtab_index].st_name;
+
+	if (reloc_type != R_386_JMP_SLOT) {
+		_dl_dprintf(2, "%s: Incorrect relocation type in jump relocations\n", 
+				_dl_progname);
+		_dl_exit(1);
+	}
+
+	/* Address of jump instruction to fix up */
+	instr_addr = ((unsigned long) this_reloc->r_offset + 
+			(unsigned long) tpnt->loadaddr);
+	got_addr = (char **) instr_addr;
+
+	/* Get the address of the GOT entry */
+	new_addr = _dl_find_hash(symname, tpnt->symbol_scope, tpnt, resolver);
+	if (!new_addr) {
+		new_addr = _dl_find_hash(symname, NULL, NULL, resolver);
+		if (new_addr) {
+			return (unsigned long) 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", symname);
+			if(_dl_debug_detail) _dl_dprintf(_dl_debug_file, 
+					"\n\tpatched %x ==> %x @ %x\n", *got_addr, new_addr, got_addr);
+		}
+	}
+	if (!_dl_debug_nofixups) {
+		*got_addr = new_addr;
+	}
+#else
+	*got_addr = new_addr;
+#endif
+
+	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, Elf32_Sym *symtab, char *strtab))
+{
+	unsigned int i;
+	char *strtab;
+	Elf32_Sym *symtab;
+	ELF_RELOC *rpnt;
+	int symtab_index;
+
+	/* Now parse the relocation information */
+	rpnt = (ELF_RELOC *)(intptr_t) (rel_addr + tpnt->loadaddr);
+	rel_size = rel_size / sizeof(ELF_RELOC);
+
+	symtab = (Elf32_Sym *)(intptr_t) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
+	strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
+
+	  for (i = 0; i < rel_size; i++, rpnt++) {
+	        int res;
+	    
+		symtab_index = ELF32_R_SYM(rpnt->r_info);
+		
+		/* When the dynamic linker bootstrapped itself, it resolved some symbols.
+		   Make sure we do not do them again */
+		if (!symtab_index && tpnt->libtype == program_interpreter)
+			continue;
+		if (symtab_index && tpnt->libtype == program_interpreter &&
+		    _dl_symbol(strtab + symtab[symtab_index].st_name))
+			continue;
+
+#if defined (__SUPPORT_LD_DEBUG__)
+		debug_sym(symtab,strtab,symtab_index);
+		debug_reloc(symtab,strtab,rpnt);
+#endif
+
+		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 (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 if (res >0)
+		{
+			_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,
+	      ELF_RELOC *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 *)(intptr_t) (tpnt->loadaddr + (unsigned long) 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(symname, scope, 
+				(reloc_type == R_386_JMP_SLOT ? tpnt : NULL), symbolrel);
+
+		/*
+		 * 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_GLOBAL) {
+#if defined (__SUPPORT_LD_DEBUG__)
+			_dl_dprintf(2, "\tglobal symbol '%s' already defined in '%s'\n",
+					symname, tpnt->libname);
+#endif
+			return 0;
+		}
+	}
+
+#if defined (__SUPPORT_LD_DEBUG__)
+	old_val = *reloc_addr;
+#endif
+		switch (reloc_type) {
+			case R_386_NONE:
+				break;
+			case R_386_32:
+				*reloc_addr += symbol_addr;
+				break;
+			case R_386_PC32:
+				*reloc_addr += symbol_addr - (unsigned long) reloc_addr;
+				break;
+			case R_386_GLOB_DAT:
+			case R_386_JMP_SLOT:
+				*reloc_addr = symbol_addr;
+				break;
+			case R_386_RELATIVE:
+				*reloc_addr += (unsigned long) tpnt->loadaddr;
+				break;
+			case R_386_COPY:
+				/* handled later on */
+				break;
+			default:
+				return -1; /*call _dl_exit(1) */
+		}
+#if defined (__SUPPORT_LD_DEBUG__)
+	if(_dl_debug_reloc && _dl_debug_detail)
+		_dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x", old_val, *reloc_addr, reloc_addr);
+#endif
+
+	return 0;
+}
+
+static int
+_dl_do_lazy_reloc (struct elf_resolve *tpnt, struct dyn_elf *scope,
+		   ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)
+{
+	int reloc_type;
+	unsigned long *reloc_addr;
+#if defined (__SUPPORT_LD_DEBUG__)
+	unsigned long old_val;
+#endif
+	(void)scope;
+	(void)symtab;
+	(void)strtab;
+
+	reloc_addr = (unsigned long *)(intptr_t) (tpnt->loadaddr + (unsigned long) rpnt->r_offset);
+	reloc_type = ELF32_R_TYPE(rpnt->r_info);
+
+#if defined (__SUPPORT_LD_DEBUG__)
+	old_val = *reloc_addr;
+#endif
+		switch (reloc_type) {
+			case R_386_NONE:
+				break;
+			case R_386_JMP_SLOT:
+				*reloc_addr += (unsigned long) tpnt->loadaddr;
+				break;
+			default:
+				return -1; /*call _dl_exit(1) */
+		}
+#if defined (__SUPPORT_LD_DEBUG__)
+	if(_dl_debug_reloc && _dl_debug_detail)
+		_dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x", old_val, *reloc_addr, reloc_addr);
+#endif
+	return 0;
+
+}
+
+/* This is done as a separate step, because there are cases where
+   information is first copied and later initialized.  This results in
+   the wrong information being copied.  Someone at Sun was complaining about
+   a bug in the handling of _COPY by SVr4, and this may in fact be what he
+   was talking about.  Sigh. */
+
+/* No, there are cases where the SVr4 linker fails to emit COPY relocs
+   at all */
+static int
+_dl_do_copy (struct elf_resolve *tpnt, struct dyn_elf *scope,
+	     ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)
+{
+	int reloc_type;
+	int symtab_index;
+	unsigned long *reloc_addr;
+	unsigned long symbol_addr;
+	int goof = 0;
+	char *symname;
+	  
+	reloc_addr = (unsigned long *)(intptr_t) (tpnt->loadaddr + (unsigned long) rpnt->r_offset);
+	reloc_type = ELF32_R_TYPE(rpnt->r_info);
+	if (reloc_type != R_386_COPY) 
+		return 0;
+	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(symname, scope, NULL, copyrel);
+		if (!symbol_addr) goof++;
+	}
+	if (!goof) {
+#if defined (__SUPPORT_LD_DEBUG__)
+	        if(_dl_debug_move)
+		  _dl_dprintf(_dl_debug_file,"\n%s move %x bytes from %x to %x",
+			     symname, symtab[symtab_index].st_size,
+			     symbol_addr, symtab[symtab_index].st_value);
+#endif
+		_dl_memcpy((char *) symtab[symtab_index].st_value, 
+			(char *) symbol_addr, symtab[symtab_index].st_size);
+	}
+
+	return goof;
+}
+
+void _dl_parse_lazy_relocation_information(struct elf_resolve *tpnt, 
+	unsigned long rel_addr, unsigned long rel_size, int type)
+{
+	(void) type;
+	(void)_dl_parse(tpnt, NULL, rel_addr, rel_size, _dl_do_lazy_reloc);
+}
+
+int _dl_parse_relocation_information(struct elf_resolve *tpnt, 
+	unsigned long rel_addr, unsigned long rel_size, int type)
+{
+	(void) type;
+	return _dl_parse(tpnt, tpnt->symbol_scope, rel_addr, rel_size, _dl_do_reloc);
+}
+
+int _dl_parse_copy_information(struct dyn_elf *xpnt, unsigned long rel_addr, 
+	unsigned long rel_size, int type)
+{
+	(void) type;
+	return _dl_parse(xpnt->dyn, xpnt->next, rel_addr, rel_size, _dl_do_copy);
+}
+
diff -urN uClibc/ldso-0.9.24/ldso/i386/ld_syscalls.h uClibc.ldso.24/ldso-0.9.24/ldso/i386/ld_syscalls.h
--- uClibc/ldso-0.9.24/ldso/i386/ld_syscalls.h	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/i386/ld_syscalls.h	2002-08-09 07:20:21.000000000 -0500
@@ -0,0 +1,7 @@
+/* Define the __set_errno macro as nothing so that INLINE_SYSCALL
+ * won't set errno, which is important since we make system calls
+ * before the errno symbol is dynamicly linked. */
+
+#define __set_errno(X) {(void)(X);}
+#include "sys/syscall.h"
+
diff -urN uClibc/ldso-0.9.24/ldso/i386/ld_sysdep.h uClibc.ldso.24/ldso-0.9.24/ldso/i386/ld_sysdep.h
--- uClibc/ldso-0.9.24/ldso/i386/ld_sysdep.h	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/i386/ld_sysdep.h	2002-05-28 16:33:32.000000000 -0500
@@ -0,0 +1,81 @@
+/*
+ * Various assmbly language/system dependent  hacks that are required
+ * so that we can minimize the amount of platform specific code.
+ */
+
+/*
+ * Define this if the system uses RELOCA.
+ */
+#undef ELF_USES_RELOCA
+
+/*
+ * 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)
+
+/*
+ * Initialization sequence for a GOT.
+ */
+#define INIT_GOT(GOT_BASE,MODULE) \
+{				\
+  GOT_BASE[2] = (unsigned long) _dl_linux_resolve; \
+  GOT_BASE[1] = (unsigned long) MODULE; \
+}
+
+/*
+ * Here is a macro to perform a relocation.  This is only used when
+ * bootstrapping the dynamic loader.  RELP is the relocation that we
+ * are performing, REL is the pointer to the address we are relocating.
+ * SYMBOL is the symbol involved in the relocation, and LOAD is the
+ * load address.
+ */
+#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD) \
+	switch(ELF32_R_TYPE((RELP)->r_info)){		\
+	case R_386_32:		\
+	  *REL += SYMBOL;		\
+	  break;		\
+	case R_386_PC32:		\
+	  *REL += SYMBOL - (unsigned long) REL;		\
+	  break;		\
+	case R_386_GLOB_DAT:		\
+	case R_386_JMP_SLOT:		\
+	  *REL = SYMBOL;		\
+	  break;		\
+	case R_386_RELATIVE:		\
+	  *REL += (unsigned long) LOAD;		\
+	  break;		\
+	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()		\
+	__asm__ volatile ("leave\n\t" \
+		    "jmp *%%eax\n\t"	\
+		    : "=a" (status) :	"a" (_dl_elf_main))
+
+
+
+/* Here we define the magic numbers that this dynamic loader should accept */
+
+#define MAGIC1 EM_386
+#undef  MAGIC2
+/* Used for error messages */
+#define ELF_TARGET "386"
+
+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
+#define OFFS_ALIGN 0x7ffff000
diff -urN uClibc/ldso-0.9.24/ldso/i386/resolve.S uClibc.ldso.24/ldso-0.9.24/ldso/i386/resolve.S
--- uClibc/ldso-0.9.24/ldso/i386/resolve.S	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/i386/resolve.S	2001-06-14 16:51:51.000000000 -0500
@@ -0,0 +1,52 @@
+/*
+ * 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
+ */
+
+.text
+.align 4
+
+.globl _dl_linux_resolve
+.type	_dl_linux_resolve,@function
+
+_dl_linux_resolve:
+	pusha				/* preserve all regs */
+	lea	0x20(%esp),%eax		/* eax = tpnt and reloc_entry params */
+	pushl	4(%eax)			/* push copy of reloc_entry param */
+	pushl	(%eax)			/* push copy of tpnt param */
+					 
+#ifdef __PIC__
+	call	.L24
+.L24:
+	popl	%ebx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-.L24],%ebx
+	movl _dl_linux_resolver@GOT(%ebx),%ebx	/* eax = resolved func */
+	call *%ebx
+#else
+	call _dl_linux_resolver
+#endif
+	movl	%eax,0x28(%esp)		/* store func addr over original
+					 * tpnt param */
+	addl	$0x8,%esp		/* remove copy parameters */
+	popa				/* restore regs */
+	ret	$4			/* jump to func removing original
+					 * reloc_entry param from stack */
+.LFE2:
+	.size _dl_linux_resolve,.LFE2-_dl_linux_resolve
diff -urN uClibc/ldso-0.9.24/ldso/ldso.c uClibc.ldso.24/ldso-0.9.24/ldso/ldso.c
--- uClibc/ldso-0.9.24/ldso/ldso.c	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/ldso.c	2003-12-05 14:24:26.000000000 -0600
@@ -0,0 +1,1296 @@
+/* vi: set sw=4 ts=4: */
+/* Program to load an ELF binary on a linux system, and run it
+ * after resolving ELF shared library symbols
+ *
+ * Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald, 
+ *				David Engel, Hongjiu Lu and Mitch D'Souza
+ * Copyright (C) 2001-2002, Erik Andersen
+ *
+ * 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.
+ */
+
+// Support a list of library preloads in /etc/ld.so.preload
+//#define SUPPORT_LDSO_PRELOAD_FILE
+
+
+/* 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. */
+
+/*
+ * The main trick with this program is that initially, we ourselves are
+ * not dynamicly linked.  This means that we cannot access any global
+ * variables or call any functions.  No globals initially, since the
+ * Global Offset Table (GOT) is initialized by the linker assuming a
+ * virtual address of 0, and no function calls initially since the
+ * Procedure Linkage Table (PLT) is not yet initialized.
+ *
+ * There are additional initial restrictions - we cannot use large
+ * switch statements, since the compiler generates tables of addresses
+ * and jumps through them.  We can use inline functions, because these
+ * do not transfer control to a new address, but they must be static so
+ * that they are not exported from the modules.  We cannot use normal
+ * syscall stubs, because these all reference the errno global variable
+ * which is not yet initialized.  We can use all of the local stack
+ * variables that we want.
+ *
+ * Life is further complicated by the fact that initially we do not
+ * want to do a complete dynamic linking.  We want to allow the user to
+ * supply new functions to override symbols (i.e. weak symbols and/or
+ * LD_PRELOAD).  So initially, we only perform relocations for
+ * variables that start with "_dl_" since ANSI specifies that the user
+ * is not supposed to redefine any of these variables.
+ *
+ * Fortunately, the linker itself leaves a few clues lying around, and
+ * when the kernel starts the image, there are a few further clues.
+ * First of all, there is Auxiliary Vector Table information sitting on
+ * which is provided to us by the kernel, and which includes
+ * information about the load address that the program interpreter was
+ * loaded at, the number of sections, the address the application was
+ * loaded at and so forth.  Here this information is stored in the
+ * array auxvt.  For details see linux/fs/binfmt_elf.c where it calls
+ * NEW_AUX_ENT() a bunch of time....
+ *
+ * Next, we need to find the GOT.  On most arches there is a register
+ * pointing to the GOT, but just in case (and for new ports) I've added
+ * some (slow) C code to locate the GOT for you. 
+ *
+ * This code was originally written for SVr4, and there the kernel
+ * would load all text pages R/O, so they needed to call mprotect a
+ * zillion times to mark all text pages as writable so dynamic linking
+ * would succeed.  Then when they were done, they would change the
+ * protections for all the pages back again.  Well, under Linux
+ * everything is loaded writable (since Linux does copy on write
+ * anyways) so all the mprotect stuff has been disabled.
+ *
+ * Initially, we do not have access to _dl_malloc since we can't yet
+ * make function calls, so we mmap one page to use as scratch space.
+ * Later on, when we can call _dl_malloc we reuse this this memory.
+ * This is also beneficial, since we do not want to use the same memory
+ * pool as malloc anyway - esp if the user redefines malloc to do
+ * something funky.
+ *
+ * Our first task is to perform a minimal linking so that we can call
+ * other portions of the dynamic linker.  Once we have done this, we
+ * then build the list of modules that the application requires, using
+ * LD_LIBRARY_PATH if this is not a suid program (/usr/lib otherwise).
+ * Once this is done, we can do the dynamic linking as required, and we
+ * must omit the things we did to get the dynamic linker up and running
+ * in the first place.  After we have done this, we just have a few
+ * housekeeping chores and we can transfer control to the user's
+ * application.
+ */
+
+#include "ldso.h"
+
+
+#define ALLOW_ZERO_PLTGOT
+
+/*  Some arches may need to override this in boot1_arch.h */
+#define	    ELFMAGIC	ELFMAG
+
+/* This is a poor man's malloc, used prior to resolving our internal poor man's malloc */
+#define LD_MALLOC(SIZE) ((void *) (malloc_buffer += SIZE, malloc_buffer - SIZE)) ;  REALIGN();
+/*
+ * Make sure that the malloc buffer is aligned on 4 byte boundary.  For 64 bit
+ * platforms we may need to increase this to 8, but this is good enough for
+ * now.  This is typically called after LD_MALLOC.
+ */
+#define REALIGN() malloc_buffer = (char *) (((unsigned long) malloc_buffer + 3) & ~(3))
+
+char *_dl_library_path = 0;		/* Where we look for libraries */
+char *_dl_preload = 0;			/* Things to be loaded before the libs. */
+char *_dl_ldsopath = 0;
+static int _dl_be_lazy = RTLD_LAZY;
+#ifdef __SUPPORT_LD_DEBUG__
+char *_dl_debug  = 0;
+char *_dl_debug_symbols = 0;
+char *_dl_debug_move    = 0;
+char *_dl_debug_reloc   = 0;
+char *_dl_debug_detail  = 0;
+char *_dl_debug_nofixups  = 0;
+char *_dl_debug_bindings  = 0;
+int   _dl_debug_file = 2;
+#else
+#define _dl_debug_file 2
+#endif
+static char *_dl_malloc_addr, *_dl_mmap_zero;
+
+static char *_dl_trace_loaded_objects = 0;
+static int (*_dl_elf_main) (int, char **, char **);
+struct r_debug *_dl_debug_addr = NULL;
+unsigned long *_dl_brkp;
+unsigned long *_dl_envp;
+int _dl_fixup(struct elf_resolve *tpnt, int lazy);
+void _dl_debug_state(void);
+char *_dl_get_last_path_component(char *path);
+static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *app_tpnt, 
+		unsigned long load_addr, unsigned long *hash_addr, Elf32_auxv_t auxvt[AT_EGID + 1], 
+		char **envp, struct r_debug *debug_addr);
+
+#include "boot1_arch.h"
+#include "_dl_progname.h"				/* Pull in the value of _dl_progname */
+
+/* When we enter this piece of code, the program stack looks like this:
+        argc            argument counter (integer)
+        argv[0]         program name (pointer)
+        argv[1...N]     program args (pointers)
+        argv[argc-1]    end of args (integer)
+		NULL
+        env[0...N]      environment variables (pointers)
+        NULL
+		auxvt[0...N]   Auxiliary Vector Table elements (mixed types)
+*/
+
+#ifdef __SUPPORT_LD_DEBUG_EARLY__
+/* Debugging is especially tricky on PowerPC, since string literals
+ * require relocations.  Thus, you can't use _dl_dprintf() for
+ * anything until the bootstrap relocations are finished. */
+static inline void hexprint(unsigned long x)
+{
+	int i;
+	char c;
+
+	for (i = 0; i < 8; i++) {
+		c = ((x >> 28) + '0');
+		if (c > '9')
+			c += 'a' - '9' - 1;
+		_dl_write(1, &c, 1);
+		x <<= 4;
+	}
+	c = '\n';
+	_dl_write(1, &c, 1);
+}
+#endif
+
+LD_BOOT(unsigned long args) __attribute__ ((unused));
+
+LD_BOOT(unsigned long args)
+{
+	unsigned int argc;
+	char **argv, **envp;
+	unsigned long load_addr;
+	unsigned long *got;
+	unsigned long *aux_dat;
+	int goof = 0;
+	ElfW(Ehdr) *header;
+	struct elf_resolve *tpnt;
+	struct elf_resolve *app_tpnt;
+	Elf32_auxv_t auxvt[AT_EGID + 1];
+	unsigned char *malloc_buffer, *mmap_zero;
+	Elf32_Dyn *dpnt;
+	unsigned long *hash_addr;
+	struct r_debug *debug_addr = NULL;
+	int indx;
+	int status;
+
+
+	/* WARNING! -- we cannot make _any_ funtion calls until we have
+	 * taken care of fixing up our own relocations.  Making static
+	 * inline calls is ok, but _no_ function calls.  Not yet
+	 * anyways. */
+
+	/* First obtain the information on the stack that tells us more about
+	   what binary is loaded, where it is loaded, etc, etc */
+	GET_ARGV(aux_dat, args);
+#if defined (__arm__) || defined (__mips__) || defined (__cris__)
+	aux_dat += 1;
+#endif
+	argc = *(aux_dat - 1);
+	argv = (char **) aux_dat;
+	aux_dat += argc;			/* Skip over the argv pointers */
+	aux_dat++;					/* Skip over NULL at end of argv */
+	envp = (char **) aux_dat;
+	while (*aux_dat)
+		aux_dat++;				/* Skip over the envp pointers */
+	aux_dat++;					/* Skip over NULL at end of envp */
+
+	/* Place -1 here as a checkpoint.  We later check if it was changed
+	 * when we read in the auxvt */
+	auxvt[AT_UID].a_type = -1;
+
+	/* The junk on the stack immediately following the environment is  
+	 * the Auxiliary Vector Table.  Read out the elements of the auxvt,
+	 * sort and store them in auxvt for later use. */
+	while (*aux_dat) {
+		Elf32_auxv_t *auxv_entry = (Elf32_auxv_t *) aux_dat;
+
+		if (auxv_entry->a_type <= AT_EGID) {
+			_dl_memcpy(&(auxvt[auxv_entry->a_type]), auxv_entry, sizeof(Elf32_auxv_t));
+		}
+		aux_dat += 2;
+	}
+
+	/* locate the ELF header.   We need this done as soon as possible 
+	 * (esp since SEND_STDERR() needs this on some platforms... */
+	load_addr = auxvt[AT_BASE].a_un.a_val;
+	header = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_ptr;
+
+	/* Check the ELF header to make sure everything looks ok.  */
+	if (!header || header->e_ident[EI_CLASS] != ELFCLASS32 ||
+		header->e_ident[EI_VERSION] != EV_CURRENT
+#if !defined(__powerpc__) && !defined(__mips__) && !defined(__sh__)
+		|| _dl_strncmp((void *) header, ELFMAGIC, SELFMAG) != 0
+#else
+	        || header->e_ident[EI_MAG0] != ELFMAG0
+	        || header->e_ident[EI_MAG1] != ELFMAG1
+	        || header->e_ident[EI_MAG2] != ELFMAG2
+	        || header->e_ident[EI_MAG3] != ELFMAG3
+#endif
+		) {
+		SEND_STDERR("Invalid ELF header\n");
+		_dl_exit(0);
+	}
+#ifdef __SUPPORT_LD_DEBUG_EARLY__
+	SEND_STDERR("ELF header=");
+	SEND_ADDRESS_STDERR(load_addr, 1);
+#endif
+
+
+	/* Locate the global offset table.  Since this code must be PIC  
+	 * we can take advantage of the magic offset register, if we
+	 * happen to know what that is for this architecture.  If not,
+	 * we can always read stuff out of the ELF file to find it... */
+#if defined(__i386__)
+  __asm__("\tmovl %%ebx,%0\n\t":"=a"(got));
+#elif defined(__m68k__)
+  __asm__("movel %%a5,%0":"=g"(got))
+#elif defined(__sparc__)
+  __asm__("\tmov %%l7,%0\n\t":"=r"(got))
+#elif defined(__arm__)
+  __asm__("\tmov %0, r10\n\t":"=r"(got));
+#elif defined(__powerpc__)
+  __asm__("\tbl _GLOBAL_OFFSET_TABLE_-4@local\n\t":"=l"(got));
+#elif defined(__mips__)
+  __asm__("\tmove %0, $28\n\tsubu %0,%0,0x7ff0\n\t":"=r"(got));
+#elif defined(__sh__)
+  __asm__(
+"       mov.l    1f, %0\n"
+"       mova     1f, r0\n"
+"       bra      2f\n"
+"       add r0,  %0\n"
+"       .balign  4\n"
+"1:     .long    _GLOBAL_OFFSET_TABLE_\n"
+"2:" : "=r" (got) : : "r0");
+#elif defined(__cris__)
+  __asm__("\tmove.d $pc,%0\n\tsub.d .:GOTOFF,%0\n\t":"=r"(got));
+#else
+	/* Do things the slow way in C */
+	{
+		unsigned long tx_reloc;
+		Elf32_Dyn *dynamic = NULL;
+		Elf32_Shdr *shdr;
+		Elf32_Phdr *pt_load;
+
+#ifdef __SUPPORT_LD_DEBUG_EARLY__
+		SEND_STDERR("Finding the GOT using C code to read the ELF file\n");
+#endif
+		/* Find where the dynamic linking information section is hiding */
+		shdr = (Elf32_Shdr *) (header->e_shoff + (char *) header);
+		for (indx = header->e_shnum; --indx >= 0; ++shdr) {
+			if (shdr->sh_type == SHT_DYNAMIC) {
+				goto found_dynamic;
+			}
+		}
+		SEND_STDERR("missing dynamic linking information section \n");
+		_dl_exit(0);
+
+	  found_dynamic:
+		dynamic = (Elf32_Dyn *) (shdr->sh_offset + (char *) header);
+
+		/* Find where PT_LOAD is hiding */
+		pt_load = (Elf32_Phdr *) (header->e_phoff + (char *) header);
+		for (indx = header->e_phnum; --indx >= 0; ++pt_load) {
+			if (pt_load->p_type == PT_LOAD) {
+				goto found_pt_load;
+			}
+		}
+		SEND_STDERR("missing loadable program segment\n");
+		_dl_exit(0);
+
+	  found_pt_load:
+		/* Now (finally) find where DT_PLTGOT is hiding */
+		tx_reloc = pt_load->p_vaddr - pt_load->p_offset;
+		for (; DT_NULL != dynamic->d_tag; ++dynamic) {
+			if (dynamic->d_tag == DT_PLTGOT) {
+				goto found_got;
+			}
+		}
+		SEND_STDERR("missing global offset table\n");
+		_dl_exit(0);
+
+	  found_got:
+		got = (unsigned long *) (dynamic->d_un.d_val - tx_reloc +
+				(char *) header);
+	}
+#endif
+
+	/* Now, finally, fix up the location of the dynamic stuff */
+	dpnt = (Elf32_Dyn *) (*got + load_addr);
+#ifdef __SUPPORT_LD_DEBUG_EARLY__
+	SEND_STDERR("First Dynamic section entry=");
+	SEND_ADDRESS_STDERR(dpnt, 1);
+#endif
+
+
+	/* Call mmap to get a page of writable memory that can be used 
+	 * for _dl_malloc throughout the shared lib loader. */
+	mmap_zero = malloc_buffer = _dl_mmap((void *) 0, 4096, 
+			PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
+	if (_dl_mmap_check_error(mmap_zero)) {
+		SEND_STDERR("dl_boot: mmap of a spare page failed!\n");
+		_dl_exit(13);
+	}
+
+	tpnt = LD_MALLOC(sizeof(struct elf_resolve));
+	_dl_memset(tpnt, 0, sizeof(struct elf_resolve));
+	app_tpnt = LD_MALLOC(sizeof(struct elf_resolve));
+	_dl_memset(app_tpnt, 0, sizeof(struct elf_resolve));
+
+	/*
+	 * This is used by gdb to locate the chain of shared libraries that are currently loaded.
+	 */
+	debug_addr = LD_MALLOC(sizeof(struct r_debug));
+	_dl_memset(debug_addr, 0, sizeof(struct r_debug));
+
+	/* OK, that was easy.  Next scan the DYNAMIC section of the image.
+	   We are only doing ourself right now - we will have to do the rest later */
+#ifdef __SUPPORT_LD_DEBUG_EARLY__
+	SEND_STDERR("scanning DYNAMIC section\n");
+#endif
+	while (dpnt->d_tag) {
+#if defined(__mips__)
+		if (dpnt->d_tag == DT_MIPS_GOTSYM)
+			tpnt->mips_gotsym = (unsigned long) dpnt->d_un.d_val;
+		if (dpnt->d_tag == DT_MIPS_LOCAL_GOTNO)
+			tpnt->mips_local_gotno = (unsigned long) dpnt->d_un.d_val;
+		if (dpnt->d_tag == DT_MIPS_SYMTABNO)
+			tpnt->mips_symtabno = (unsigned long) dpnt->d_un.d_val;
+#endif
+		if (dpnt->d_tag < 24) {
+			tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
+			if (dpnt->d_tag == DT_TEXTREL) {
+				tpnt->dynamic_info[DT_TEXTREL] = 1;
+			}
+		}
+		dpnt++;
+	}
+
+	{
+		ElfW(Phdr) *ppnt;
+		int i;
+
+		ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_ptr;
+		for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++)
+			if (ppnt->p_type == PT_DYNAMIC) {
+				dpnt = (Elf32_Dyn *) ppnt->p_vaddr;
+				while (dpnt->d_tag) {
+#if defined(__mips__)
+					if (dpnt->d_tag == DT_MIPS_GOTSYM)
+						app_tpnt->mips_gotsym =
+							(unsigned long) dpnt->d_un.d_val;
+					if (dpnt->d_tag == DT_MIPS_LOCAL_GOTNO)
+						app_tpnt->mips_local_gotno =
+							(unsigned long) dpnt->d_un.d_val;
+					if (dpnt->d_tag == DT_MIPS_SYMTABNO)
+						app_tpnt->mips_symtabno =
+							(unsigned long) dpnt->d_un.d_val;
+					if (dpnt->d_tag > DT_JMPREL) {
+						dpnt++;
+						continue;
+					}
+					app_tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
+
+#warning "Debugging threads on mips won't work till someone fixes this..."
+#if 0
+					if (dpnt->d_tag == DT_DEBUG) {
+						dpnt->d_un.d_val = (unsigned long) debug_addr;
+					}
+#endif
+
+#else
+					if (dpnt->d_tag > DT_JMPREL) {
+						dpnt++;
+						continue;
+					}
+					app_tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
+					if (dpnt->d_tag == DT_DEBUG) {
+						dpnt->d_un.d_val = (unsigned long) debug_addr;
+					}
+#endif
+					if (dpnt->d_tag == DT_TEXTREL)
+						app_tpnt->dynamic_info[DT_TEXTREL] = 1;
+					dpnt++;
+				}
+			}
+	}
+
+#ifdef __SUPPORT_LD_DEBUG_EARLY__
+	SEND_STDERR("done scanning DYNAMIC section\n");
+#endif
+
+	/* Get some more of the information that we will need to dynamicly link
+	   this module to itself */
+
+	hash_addr = (unsigned long *) (tpnt->dynamic_info[DT_HASH] + load_addr);
+	tpnt->nbucket = *hash_addr++;
+	tpnt->nchain = *hash_addr++;
+	tpnt->elf_buckets = hash_addr;
+	hash_addr += tpnt->nbucket;
+
+#ifdef __SUPPORT_LD_DEBUG_EARLY__
+	SEND_STDERR("done grabbing link information\n");
+#endif
+
+#ifndef FORCE_SHAREABLE_TEXT_SEGMENTS
+	/* Ugly, ugly.  We need to call mprotect to change the protection of
+	   the text pages so that we can do the dynamic linking.  We can set the
+	   protection back again once we are done */
+
+	{
+		ElfW(Phdr) *ppnt;
+		int i;
+
+#ifdef __SUPPORT_LD_DEBUG_EARLY__
+		SEND_STDERR("calling mprotect on the shared library/dynamic linker\n");
+#endif
+
+		/* First cover the shared library/dynamic linker. */
+		if (tpnt->dynamic_info[DT_TEXTREL]) {
+			header = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_ptr;
+			ppnt = (ElfW(Phdr) *) ((int)auxvt[AT_BASE].a_un.a_ptr + 
+					header->e_phoff);
+			for (i = 0; i < header->e_phnum; i++, ppnt++) {
+				if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W)) {
+					_dl_mprotect((void *) (load_addr + (ppnt->p_vaddr & PAGE_ALIGN)), 
+							(ppnt->p_vaddr & ADDR_ALIGN) + (unsigned long) ppnt->p_filesz, 
+							PROT_READ | PROT_WRITE | PROT_EXEC);
+				}
+			}
+		}
+
+#ifdef __SUPPORT_LD_DEBUG_EARLY__
+		SEND_STDERR("calling mprotect on the application program\n");
+#endif
+		/* Now cover the application program. */
+		if (app_tpnt->dynamic_info[DT_TEXTREL]) {
+			ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_ptr;
+			for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
+				if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
+					_dl_mprotect((void *) (ppnt->p_vaddr & PAGE_ALIGN),
+								 (ppnt->p_vaddr & ADDR_ALIGN) +
+								 (unsigned long) ppnt->p_filesz,
+								 PROT_READ | PROT_WRITE | PROT_EXEC);
+			}
+		}
+	}
+#endif
+	
+#if defined(__mips__)
+#ifdef __SUPPORT_LD_DEBUG_EARLY__
+	SEND_STDERR("About to do MIPS specific GOT bootstrap\n");
+#endif
+	/* For MIPS we have to do stuff to the GOT before we do relocations.  */
+	PERFORM_BOOTSTRAP_GOT(got);
+#endif
+
+	/* OK, now do the relocations.  We do not do a lazy binding here, so
+	   that once we are done, we have considerably more flexibility. */
+#ifdef __SUPPORT_LD_DEBUG_EARLY__
+	SEND_STDERR("About to do library loader relocations\n");
+#endif
+
+	goof = 0;
+	for (indx = 0; indx < 2; indx++) {
+		unsigned int i;
+		ELF_RELOC *rpnt;
+		unsigned long *reloc_addr;
+		unsigned long symbol_addr;
+		int symtab_index;
+		unsigned long rel_addr, rel_size;
+
+
+#ifdef ELF_USES_RELOCA
+		rel_addr = (indx ? tpnt->dynamic_info[DT_JMPREL] : tpnt->
+			 dynamic_info[DT_RELA]);
+		rel_size = (indx ? tpnt->dynamic_info[DT_PLTRELSZ] : tpnt->
+			 dynamic_info[DT_RELASZ]);
+#else
+		rel_addr = (indx ? tpnt->dynamic_info[DT_JMPREL] : tpnt->
+			 dynamic_info[DT_REL]);
+		rel_size = (indx ? tpnt->dynamic_info[DT_PLTRELSZ] : tpnt->
+			 dynamic_info[DT_RELSZ]);
+#endif
+
+		if (!rel_addr)
+			continue;
+
+		/* Now parse the relocation information */
+		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 = ELF32_R_SYM(rpnt->r_info);
+			symbol_addr = 0;
+			if (symtab_index) {
+				char *strtab;
+				Elf32_Sym *symtab;
+
+				symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + load_addr);
+				strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + load_addr);
+
+				/* We only do a partial dynamic linking right now.  The user
+				   is not supposed to redefine any symbols that start with
+				   a '_', so we can do this with confidence. */
+				if (!_dl_symbol(strtab + symtab[symtab_index].st_name))
+					continue;
+				symbol_addr = load_addr + symtab[symtab_index].st_value;
+
+				if (!symbol_addr) {
+					/* This will segfault - you cannot call a function until
+					 * we have finished the relocations.
+					 */
+					SEND_STDERR("ELF dynamic loader - unable to self-bootstrap - symbol ");
+					SEND_STDERR(strtab + symtab[symtab_index].st_name);
+					SEND_STDERR(" undefined.\n");
+					goof++;
+				}
+#ifdef __SUPPORT_LD_DEBUG_EARLY__
+				SEND_STDERR("About to fixup symbol: ");
+				SEND_STDERR(strtab + symtab[symtab_index].st_name);
+				SEND_STDERR("\n");
+#endif  
+			}
+			/*
+			 * Use this machine-specific macro to perform the actual relocation.
+			 */
+			PERFORM_BOOTSTRAP_RELOC(rpnt, reloc_addr, symbol_addr, load_addr);
+		}
+	}
+
+	if (goof) {
+		_dl_exit(14);
+	}
+#ifdef __SUPPORT_LD_DEBUG_EARLY__
+	/* Wahoo!!! */
+	_dl_dprintf(_dl_debug_file, "Done relocating library loader, so we can now\n\tuse globals and make function calls!\n");
+#endif
+
+	if (argv[0]) {
+		_dl_progname = argv[0];
+	}
+
+	/* Start to build the tables of the modules that are required for
+	 * this beast to run.  We start with the basic executable, and then
+	 * go from there.  Eventually we will run across ourself, and we
+	 * will need to properly deal with that as well. */
+
+	/* Make it so _dl_malloc can use the page of memory we have already
+	 * allocated, so we shouldn't need to grab any more memory */
+	_dl_malloc_addr = malloc_buffer;
+	_dl_mmap_zero = mmap_zero;
+
+
+
+	/* Now we have done the mandatory linking of some things.  We are now
+	   free to start using global variables, since these things have all been
+	   fixed up by now.  Still no function calls outside of this library ,
+	   since the dynamic resolver is not yet ready. */
+	_dl_get_ready_to_run(tpnt, app_tpnt, load_addr, hash_addr, auxvt, envp, debug_addr);
+
+
+	/* Notify the debugger that all objects are now mapped in.  */
+	_dl_debug_addr->r_state = RT_CONSISTENT;
+	_dl_debug_state();
+
+
+	/* OK we are done here.  Turn out the lights, and lock up. */
+	_dl_elf_main = (int (*)(int, char **, char **)) auxvt[AT_ENTRY].a_un.a_fcn;
+
+	/*
+	 * Transfer control to the application.
+	 */
+	status = 0;					/* Used on x86, but not on other arches */
+#if defined (__SUPPORT_LD_DEBUG__)
+	if(_dl_debug) _dl_dprintf(_dl_debug_file,"\ntransfering control: %s\n\n", _dl_progname);	
+#endif    
+	START();
+}
+
+#if defined (__SUPPORT_LD_DEBUG__)
+static void debug_fini (int status, void *arg)
+{
+	(void)status;
+	_dl_dprintf(_dl_debug_file,"\ncalling fini: %s\n\n", (const char*)arg);
+}
+#endif    
+
+static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *app_tpnt, 
+		unsigned long load_addr, unsigned long *hash_addr, Elf32_auxv_t auxvt[AT_EGID + 1], 
+		char **envp, struct r_debug *debug_addr)
+{
+	ElfW(Phdr) *ppnt;
+	char *lpntstr;
+	int i, _dl_secure, goof = 0;
+	struct dyn_elf *rpnt;
+	struct elf_resolve *tcurr;
+	struct elf_resolve *tpnt1;
+	unsigned long brk_addr, *lpnt;
+	int (*_dl_atexit) (void *);
+#if defined (__SUPPORT_LD_DEBUG__)
+	int (*_dl_on_exit) (void (*FUNCTION)(int STATUS, void *ARG),void*);
+#endif
+
+	/* Now we have done the mandatory linking of some things.  We are now
+	   free to start using global variables, since these things have all been
+	   fixed up by now.  Still no function calls outside of this library ,
+	   since the dynamic resolver is not yet ready. */
+	lpnt = (unsigned long *) (tpnt->dynamic_info[DT_PLTGOT] + load_addr);
+
+	tpnt->chains = hash_addr;
+	tpnt->next = 0;
+	tpnt->libname = 0;
+	tpnt->libtype = program_interpreter;
+	tpnt->loadaddr = (ElfW(Addr)) load_addr;
+
+#ifdef ALLOW_ZERO_PLTGOT
+	if (tpnt->dynamic_info[DT_PLTGOT])
+#endif
+	{
+		INIT_GOT(lpnt, tpnt);
+#ifdef __SUPPORT_LD_DEBUG_EARLY__
+		_dl_dprintf(_dl_debug_file, "GOT found at %x\n", lpnt);
+#endif
+	}
+
+	/* OK, this was a big step, now we need to scan all of the user images
+	   and load them properly. */
+
+	{
+		ElfW(Ehdr) *epnt;
+		ElfW(Phdr) *myppnt;
+		int j;
+
+		epnt = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_ptr;
+		tpnt->n_phent = epnt->e_phnum;
+		tpnt->ppnt = myppnt = (ElfW(Phdr) *) (load_addr + epnt->e_phoff);
+		for (j = 0; j < epnt->e_phnum; j++, myppnt++) {
+			if (myppnt->p_type == PT_DYNAMIC) {
+				tpnt->dynamic_addr = (ElfW(Dyn) *)myppnt->p_vaddr + load_addr;
+				tpnt->dynamic_size = myppnt->p_filesz;
+			}
+		}
+	}
+
+	brk_addr = 0;
+	rpnt = NULL;
+
+	/* 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 linking */
+
+	ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_ptr;
+	for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
+		if (ppnt->p_type == PT_LOAD) {
+			if (ppnt->p_vaddr + ppnt->p_memsz > brk_addr)
+				brk_addr = ppnt->p_vaddr + ppnt->p_memsz;
+		}
+		if (ppnt->p_type == PT_DYNAMIC) {
+#ifndef ALLOW_ZERO_PLTGOT
+			/* make sure it's really there. */
+			if (app_tpnt->dynamic_info[DT_PLTGOT] == 0)
+				continue;
+#endif
+			/* OK, we have what we need - slip this one into the list. */
+			app_tpnt = _dl_add_elf_hash_table("", 0, 
+					app_tpnt->dynamic_info, ppnt->p_vaddr, ppnt->p_filesz);
+			_dl_loaded_modules->libtype = elf_executable;
+			_dl_loaded_modules->ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_ptr;
+			_dl_loaded_modules->n_phent = auxvt[AT_PHNUM].a_un.a_val;
+			_dl_symbol_tables = rpnt = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
+			_dl_memset(rpnt, 0, sizeof(struct dyn_elf));
+			rpnt->dyn = _dl_loaded_modules;
+			app_tpnt->usage_count++;
+			app_tpnt->symbol_scope = _dl_symbol_tables;
+			lpnt = (unsigned long *) (app_tpnt->dynamic_info[DT_PLTGOT]);
+#ifdef ALLOW_ZERO_PLTGOT
+			if (lpnt)
+#endif
+				INIT_GOT(lpnt, _dl_loaded_modules);
+		}
+
+		/* OK, fill this in - we did not have this before */
+		if (ppnt->p_type == PT_INTERP) {	
+			int readsize = 0;
+			char *pnt, *pnt1, buf[1024];
+			tpnt->libname = _dl_strdup((char *) ppnt->p_offset +
+					(auxvt[AT_PHDR].a_un.a_val & PAGE_ALIGN));
+			
+			/* Determine if the shared lib loader is a symlink */
+			_dl_memset(buf, 0, sizeof(buf));
+			readsize = _dl_readlink(tpnt->libname, buf, sizeof(buf));
+			if (readsize > 0 && readsize < (int)(sizeof(buf)-1)) {
+				pnt1 = _dl_strrchr(buf, '/');
+				if (pnt1 && buf != pnt1) {
+#ifdef __SUPPORT_LD_DEBUG_EARLY__
+					_dl_dprintf(_dl_debug_file, "changing tpnt->libname from '%s' to '%s'\n", tpnt->libname, buf);
+#endif
+					tpnt->libname = _dl_strdup(buf);
+				}
+			}
+
+			/* Store the path where the shared lib loader was found for 
+			 * later use */
+			pnt = _dl_strdup(tpnt->libname);
+			pnt1 = _dl_strrchr(pnt, '/');
+			if (pnt != pnt1) {
+				*pnt1 = '\0';
+				_dl_ldsopath = pnt;
+			} else {
+				_dl_ldsopath = tpnt->libname;
+			}
+#ifdef __SUPPORT_LD_DEBUG_EARLY__
+			_dl_dprintf(_dl_debug_file, "Lib Loader:\t(%x) %s\n", tpnt->loadaddr, tpnt->libname);
+#endif
+		}
+	}
+
+
+	/* Now we need to figure out what kind of options are selected.
+	   Note that for SUID programs we ignore the settings in LD_LIBRARY_PATH */
+	{
+		if (_dl_getenv("LD_BIND_NOW", envp))
+			_dl_be_lazy = 0;
+
+		if ((auxvt[AT_UID].a_un.a_val == -1 && _dl_suid_ok()) ||
+				(auxvt[AT_UID].a_un.a_val != -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;
+			_dl_preload = _dl_getenv("LD_PRELOAD", envp);
+			_dl_library_path = _dl_getenv("LD_LIBRARY_PATH", envp);
+		} else {
+			_dl_secure = 1;
+			_dl_preload = _dl_getenv("LD_PRELOAD", envp);
+			_dl_unsetenv("LD_AOUT_PRELOAD", envp);
+			_dl_unsetenv("LD_LIBRARY_PATH", envp);
+			_dl_unsetenv("LD_AOUT_LIBRARY_PATH", envp);
+			_dl_library_path = NULL;
+		}
+	}
+
+#ifdef __SUPPORT_LD_DEBUG__
+	_dl_debug    = _dl_getenv("LD_DEBUG", envp);
+	if (_dl_debug)
+	{
+	  if (_dl_strstr(_dl_debug, "all")) {
+	  	_dl_debug_detail = _dl_debug_move = _dl_debug_symbols
+			= _dl_debug_reloc = _dl_debug_bindings = _dl_debug_nofixups = _dl_strstr(_dl_debug, "all");
+	  }
+	  else {
+	  	_dl_debug_detail   = _dl_strstr(_dl_debug, "detail");
+	  	_dl_debug_move     = _dl_strstr(_dl_debug, "move");
+	  	_dl_debug_symbols  = _dl_strstr(_dl_debug, "sym");
+	  	_dl_debug_reloc    = _dl_strstr(_dl_debug, "reloc");
+	  	_dl_debug_nofixups = _dl_strstr(_dl_debug, "nofix");
+	  	_dl_debug_bindings = _dl_strstr(_dl_debug, "bind");
+	  }
+	}
+	{
+	  const char *dl_debug_output;
+	  
+	  dl_debug_output = _dl_getenv("LD_DEBUG_OUTPUT", envp);
+
+	  if (dl_debug_output)
+	  {
+	    char tmp[22], *tmp1, *filename;
+	    int len1, len2;
+	    
+	    _dl_memset(tmp, 0, sizeof(tmp));
+	    tmp1=_dl_simple_ltoa( tmp, (unsigned long)_dl_getpid());
+
+	    len1 = _dl_strlen(dl_debug_output);
+	    len2 = _dl_strlen(tmp1);
+
+	    filename = _dl_malloc(len1+len2+2);
+
+	    if (filename)
+	    {
+	      _dl_strcpy (filename, dl_debug_output);
+	      filename[len1] = '.';
+	      _dl_strcpy (&filename[len1+1], tmp1);
+
+	      _dl_debug_file= _dl_open (filename, O_WRONLY|O_CREAT);
+	      if (_dl_debug_file<0)
+	      {
+		_dl_debug_file = 2;
+		_dl_dprintf (2, "can't open file: '%s'\n",filename);
+	      }
+	    }
+	  }
+	}
+	
+	
+#endif	
+	_dl_trace_loaded_objects = _dl_getenv("LD_TRACE_LOADED_OBJECTS", envp);
+#ifndef __LDSO_LDD_SUPPORT__
+	if (_dl_trace_loaded_objects) {
+		_dl_dprintf(_dl_debug_file, "Use the ldd provided by uClibc\n");
+		_dl_exit(1);
+	}
+#endif
+
+	/*
+	 * OK, fix one more thing - set up debug_addr so it will point
+	 * to our chain.  Later we may need to fill in more fields, but this
+	 * should be enough for now.
+	 */
+	debug_addr->r_map = (struct link_map *) _dl_loaded_modules;
+	debug_addr->r_version = 1;
+	debug_addr->r_ldbase = load_addr;
+	debug_addr->r_brk = (unsigned long) &_dl_debug_state;
+	_dl_debug_addr = debug_addr;
+
+	/* Notify the debugger we are in a consistant state */
+	_dl_debug_addr->r_state = RT_CONSISTENT;
+	_dl_debug_state();
+
+	/* OK, we now have the application in the list, and we have some
+	   basic stuff in place.  Now search through the list for other shared
+	   libraries that should be loaded, and insert them on the list in the
+	   correct order. */
+
+	_dl_map_cache();
+
+
+	if (_dl_preload) 
+	{
+		char c, *str, *str2;
+
+		str = _dl_preload;
+		while (*str == ':' || *str == ' ' || *str == '\t')
+			str++;
+		while (*str) 
+		{
+			str2 = str;
+			while (*str2 && *str2 != ':' && *str2 != ' ' && *str2 != '\t')
+				str2++;
+			c = *str2;
+			*str2 = '\0';
+			if (!_dl_secure || _dl_strchr(str, '/') == NULL) 
+			{
+				if ((tpnt1 = _dl_check_if_named_library_is_loaded(str))) 
+				{
+					continue;
+				}
+#if defined (__SUPPORT_LD_DEBUG__)
+				if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tfile='%s';  needed by '%s'\n", 
+						str, _dl_progname);
+#endif
+				tpnt1 = _dl_load_shared_library(_dl_secure, &rpnt, NULL, str);
+				if (!tpnt1) {
+#ifdef __LDSO_LDD_SUPPORT__
+					if (_dl_trace_loaded_objects)
+						_dl_dprintf(1, "\t%s => not found\n", str);
+					else 
+#endif
+					{
+						_dl_dprintf(2, "%s: can't load " "library '%s'\n", _dl_progname, str);
+						_dl_exit(15);
+					}
+				} else {
+#ifdef __SUPPORT_LD_DEBUG_EARLY__
+					_dl_dprintf(_dl_debug_file, "Loading:\t(%x) %s\n", tpnt1->loadaddr, tpnt1->libname);
+#endif
+#ifdef __LDSO_LDD_SUPPORT__
+					if (_dl_trace_loaded_objects && tpnt1->usage_count==1) {
+						/* this is a real hack to make ldd not print 
+						 * the library itself when run on a library. */
+						if (_dl_strcmp(_dl_progname, str) != 0)
+							_dl_dprintf(1, "\t%s => %s (%x)\n", str, tpnt1->libname, 
+									(unsigned) tpnt1->loadaddr);
+					}
+#endif
+				}
+			}
+			*str2 = c;
+			str = str2;
+			while (*str == ':' || *str == ' ' || *str == '\t')
+				str++;
+		}
+	}
+
+#ifdef SUPPORT_LDSO_PRELOAD_FILE
+	{
+		int fd;
+		struct stat st;
+		char *preload;
+		if (!_dl_stat(LDSO_PRELOAD, &st) && st.st_size > 0) {
+			if ((fd = _dl_open(LDSO_PRELOAD, O_RDONLY)) < 0) {
+				_dl_dprintf(2, "%s: can't open file '%s'\n", 
+						_dl_progname, LDSO_PRELOAD);
+			} else {
+				preload = (caddr_t) _dl_mmap(0, st.st_size + 1, 
+						PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+				_dl_close(fd);
+				if (preload == (caddr_t) - 1) {
+					_dl_dprintf(2, "%s: can't map file '%s'\n", 
+							_dl_progname, LDSO_PRELOAD);
+				} else {
+					char c, *cp, *cp2;
+
+					/* convert all separators and comments to spaces */
+					for (cp = preload; *cp; /*nada */ ) {
+						if (*cp == ':' || *cp == '\t' || *cp == '\n') {
+							*cp++ = ' ';
+						} else if (*cp == '#') {
+							do
+								*cp++ = ' ';
+							while (*cp != '\n' && *cp != '\0');
+						} else {
+							cp++;
+						}
+					}
+
+					/* find start of first library */
+					for (cp = preload; *cp && *cp == ' '; cp++)
+						/*nada */ ;
+
+					while (*cp) {
+						/* find end of library */
+						for (cp2 = cp; *cp && *cp != ' '; cp++)
+							/*nada */ ;
+						c = *cp;
+						*cp = '\0';
+
+						if ((tpnt1 = _dl_check_if_named_library_is_loaded(cp2))) 
+						{
+							continue;
+						}
+#if defined (__SUPPORT_LD_DEBUG__)
+						if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tfile='%s';  needed by '%s'\n", 
+								cp2, _dl_progname);
+#endif
+						tpnt1 = _dl_load_shared_library(0, &rpnt, NULL, cp2);
+						if (!tpnt1) {
+#ifdef __LDSO_LDD_SUPPORT__
+							if (_dl_trace_loaded_objects)
+								_dl_dprintf(1, "\t%s => not found\n", cp2);
+							else 
+#endif
+							{
+								_dl_dprintf(2, "%s: can't load library '%s'\n", _dl_progname, cp2);
+								_dl_exit(15);
+							}
+						} else {
+#ifdef __SUPPORT_LD_DEBUG_EARLY__
+							_dl_dprintf(_dl_debug_file, "Loading:\t(%x) %s\n", tpnt1->loadaddr, tpnt1->libname);
+#endif
+#ifdef __LDSO_LDD_SUPPORT__
+							if (_dl_trace_loaded_objects && tpnt1->usage_count==1) {
+								_dl_dprintf(1, "\t%s => %s (%x)\n", cp2, 
+										tpnt1->libname, (unsigned) tpnt1->loadaddr);
+							}
+#endif
+						}
+
+						/* find start of next library */
+						*cp = c;
+						for ( /*nada */ ; *cp && *cp == ' '; cp++)
+							/*nada */ ;
+					}
+
+					_dl_munmap(preload, st.st_size + 1);
+				}
+			}
+		}
+	}
+#endif
+
+	for (tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next) 
+	{
+		Elf32_Dyn *dpnt;
+		for (dpnt = (Elf32_Dyn *) tcurr->dynamic_addr; dpnt->d_tag; dpnt++) 
+		{
+			if (dpnt->d_tag == DT_NEEDED) 
+			{
+				char *name;
+				lpntstr = (char*) (tcurr->loadaddr + tcurr->dynamic_info[DT_STRTAB] + dpnt->d_un.d_val);
+				name = _dl_get_last_path_component(lpntstr);
+
+				if ((tpnt1 = _dl_check_if_named_library_is_loaded(name))) 
+				{
+					continue;
+				}
+#if defined (__SUPPORT_LD_DEBUG__)
+				if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tfile='%s';  needed by '%s'\n", 
+						lpntstr, _dl_progname);
+#endif
+				if (!(tpnt1 = _dl_load_shared_library(0, &rpnt, tcurr, lpntstr)))
+				{
+#ifdef __LDSO_LDD_SUPPORT__
+					if (_dl_trace_loaded_objects) {
+						_dl_dprintf(1, "\t%s => not found\n", lpntstr);
+						continue;
+					} else 
+#endif
+					{
+						_dl_dprintf(2, "%s: can't load library '%s'\n", _dl_progname, lpntstr);
+						_dl_exit(16);
+					}
+				} else {
+#ifdef __SUPPORT_LD_DEBUG_EARLY__
+					_dl_dprintf(_dl_debug_file, "Loading:\t(%x) %s\n", tpnt1->loadaddr, tpnt1->libname);
+#endif
+#ifdef __LDSO_LDD_SUPPORT__
+					if (_dl_trace_loaded_objects && tpnt1->usage_count==1) {
+						_dl_dprintf(1, "\t%s => %s (%x)\n", lpntstr, tpnt1->libname, 
+								(unsigned) tpnt1->loadaddr);
+					}
+#endif
+				}
+			}
+		}
+	}
+
+
+	_dl_unmap_cache();
+
+	/*
+	 * If the program interpreter is not in the module chain, add it.  This will
+	 * be required for dlopen to be able to access the internal functions in the 
+	 * dynamic linker.
+	 */
+	if (tpnt) {
+		tcurr = _dl_loaded_modules;
+		if (tcurr)
+			while (tcurr->next)
+				tcurr = tcurr->next;
+		tpnt->next = NULL;
+		tpnt->usage_count++;
+
+		if (tcurr) {
+			tcurr->next = tpnt;
+			tpnt->prev = tcurr;
+		} else {
+			_dl_loaded_modules = tpnt;
+			tpnt->prev = NULL;
+		}
+		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;
+		} else {
+			rpnt = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
+			_dl_memset(rpnt, 0, sizeof(struct dyn_elf));
+		}
+		rpnt->dyn = tpnt;
+		tpnt = NULL;
+	}
+
+#ifdef __LDSO_LDD_SUPPORT__
+	/* End of the line for ldd.... */
+	if (_dl_trace_loaded_objects) {
+		_dl_dprintf(1, "\t%s => %s (%x)\n", rpnt->dyn->libname + (_dl_strlen(_dl_ldsopath)) + 1, 
+				rpnt->dyn->libname, rpnt->dyn->loadaddr);  
+		_dl_exit(0);
+	}
+#endif
+
+
+#ifdef __mips__
+	/*
+	 * Relocation of the GOT entries for MIPS have to be done
+	 * after all the libraries have been loaded.
+	 */
+	_dl_perform_mips_global_got_relocations(_dl_loaded_modules);
+#endif
+
+#ifdef __SUPPORT_LD_DEBUG_EARLY__
+	_dl_dprintf(_dl_debug_file, "Beginning relocation fixups\n");
+#endif
+	/*
+	 * OK, now all of the kids are tucked into bed in their proper addresses.
+	 * Now we go through and look for REL and RELA records that indicate fixups
+	 * to the GOT tables.  We need to do this in reverse order so that COPY
+	 * directives work correctly */
+	goof = _dl_loaded_modules ? _dl_fixup(_dl_loaded_modules, _dl_be_lazy) : 0;
+
+
+	/* Some flavors of SVr4 do not generate the R_*_COPY directive,
+	   and we have to manually search for entries that require fixups. 
+	   Solaris gets this one right, from what I understand.  */
+
+#ifdef __SUPPORT_LD_DEBUG_EARLY__
+	_dl_dprintf(_dl_debug_file, "Beginning copy fixups\n");
+#endif
+	if (_dl_symbol_tables)
+		goof += _dl_copy_fixups(_dl_symbol_tables);
+
+	/* 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 is not guaranteed to be fully
+	   dynamicly linked if we are using ld.so.1, so we have to look
+	   up each symbol individually. */
+
+
+	_dl_brkp = (unsigned long *) (intptr_t) _dl_find_hash("___brk_addr", NULL, NULL, symbolrel);
+	
+	if (_dl_brkp) {
+		*_dl_brkp = brk_addr;
+	}
+	_dl_envp = (unsigned long *) (intptr_t) _dl_find_hash("__environ", NULL, NULL, symbolrel);
+
+	if (_dl_envp) {
+		*_dl_envp = (unsigned long) envp;
+	}
+
+#ifndef FORCE_SHAREABLE_TEXT_SEGMENTS
+	{
+		unsigned int j;
+		ElfW(Phdr) *myppnt;
+
+		/* We had to set the protections of all pages to R/W for dynamic linking.
+		   Set text pages back to R/O */
+		for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
+			for (myppnt = tpnt->ppnt, j = 0; j < tpnt->n_phent; j++, myppnt++) {
+				if (myppnt->p_type == PT_LOAD && !(myppnt->p_flags & PF_W) && tpnt->dynamic_info[DT_TEXTREL]) {
+					_dl_mprotect((void *) (tpnt->loadaddr + (myppnt->p_vaddr & PAGE_ALIGN)), 
+							(myppnt->p_vaddr & ADDR_ALIGN) + (unsigned long) myppnt->p_filesz, LXFLAGS(myppnt->p_flags));
+				}
+			}
+		}
+
+	}
+#endif
+	_dl_atexit = (int (*)(void *)) (intptr_t) _dl_find_hash("atexit", NULL, NULL, symbolrel);
+#if defined (__SUPPORT_LD_DEBUG__)
+	_dl_on_exit = (int (*)(void (*)(int, void *),void*)) 
+		(intptr_t) _dl_find_hash("on_exit", NULL, NULL, symbolrel);
+#endif
+
+	/* Notify the debugger we have added some objects. */
+	_dl_debug_addr->r_state = RT_ADD;
+	_dl_debug_state();
+
+	for (rpnt = _dl_symbol_tables; rpnt!=NULL&& rpnt->next!=NULL; rpnt=rpnt->next)
+	  ;
+	  
+	for (;rpnt!=NULL; rpnt=rpnt->prev)
+	{
+  	        tpnt = rpnt->dyn;
+
+	        if (tpnt->libtype == program_interpreter)
+			continue;
+
+		/* Apparently crt0/1 for the application is responsible for handling this.
+		 * We only need to run the init/fini for shared libraries
+		 */
+	        if (tpnt->libtype == elf_executable)
+			break;      /* at this point all shared libs are initialized !! */
+
+		if (tpnt->init_flag & INIT_FUNCS_CALLED)
+			continue;
+		tpnt->init_flag |= INIT_FUNCS_CALLED;
+
+		if (tpnt->dynamic_info[DT_INIT]) {
+			void (*dl_elf_func) (void);
+			dl_elf_func = (void (*)(void)) (intptr_t) (tpnt->loadaddr + tpnt->dynamic_info[DT_INIT]);
+#if defined (__SUPPORT_LD_DEBUG__)
+			if(_dl_debug) _dl_dprintf(_dl_debug_file,"\ncalling init: %s\n\n", tpnt->libname);	
+#endif    
+			(*dl_elf_func) ();
+		}
+		if (_dl_atexit && tpnt->dynamic_info[DT_FINI]) {
+			void (*dl_elf_func) (void);
+			dl_elf_func = (void (*)(void)) (intptr_t) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI]);
+			(*_dl_atexit) (dl_elf_func);
+#if defined (__SUPPORT_LD_DEBUG__)
+			if(_dl_debug && _dl_on_exit)
+			{
+				(*_dl_on_exit)(debug_fini, tpnt->libname);
+			}
+#endif
+		}
+#if defined (__SUPPORT_LD_DEBUG__)
+		else {
+			if (!_dl_atexit)
+				_dl_dprintf(_dl_debug_file, "%s: The address of atexit () is 0x0.\n", tpnt->libname);
+#if 0
+			if (!tpnt->dynamic_info[DT_FINI])
+				_dl_dprintf(_dl_debug_file, "%s: Invalid .fini section.\n", tpnt->libname);
+#endif
+		}
+#endif
+	}
+}
+
+/*
+ * This stub function is used by some debuggers.  The idea is that they
+ * 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)
+{
+}
+
+char *_dl_getenv(const char *symbol, char **envp)
+{
+	char *pnt;
+	const char *pnt1;
+
+	while ((pnt = *envp++)) {
+		pnt1 = symbol;
+		while (*pnt && *pnt == *pnt1)
+			pnt1++, pnt++;
+		if (!*pnt || *pnt != '=' || *pnt1)
+			continue;
+		return pnt + 1;
+	}
+	return 0;
+}
+
+void _dl_unsetenv(const char *symbol, char **envp)
+{
+	char *pnt;
+	const char *pnt1;
+	char **newenvp = envp;
+
+	for (pnt = *envp; pnt; pnt = *++envp) {
+		pnt1 = symbol;
+		while (*pnt && *pnt == *pnt1)
+			pnt1++, pnt++;
+		if (!*pnt || *pnt != '=' || *pnt1)
+			*newenvp++ = *envp;
+	}
+	*newenvp++ = *envp;
+	return;
+}
+
+#include "hash.c"
+#include "readelflib1.c"
diff -urN uClibc/ldso-0.9.24/ldso/m68k/boot1_arch.h uClibc.ldso.24/ldso-0.9.24/ldso/m68k/boot1_arch.h
--- uClibc/ldso-0.9.24/ldso/m68k/boot1_arch.h	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/m68k/boot1_arch.h	2002-08-08 09:35:37.000000000 -0500
@@ -0,0 +1,7 @@
+/* Any assmbly language/system dependent hacks needed to setup boot1.c so it
+ * will work as expected and cope with whatever platform specific wierdness is
+ * needed for this architecture.  See arm/boot1_arch.h for an example of what
+ * can be done.
+ */
+
+#define LD_BOOT(X)   void _dl_boot (X)
diff -urN uClibc/ldso-0.9.24/ldso/m68k/elfinterp.c uClibc.ldso.24/ldso-0.9.24/ldso/m68k/elfinterp.c
--- uClibc/ldso-0.9.24/ldso/m68k/elfinterp.c	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/m68k/elfinterp.c	2002-11-05 12:21:04.000000000 -0600
@@ -0,0 +1,359 @@
+/* vi: set sw=4 ts=4: */
+/* m68k ELF shared library loader suppport
+ *
+ * Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald, 
+ *				David Engel, Hongjiu Lu and Mitch D'Souza
+ * Adapted to ELF/68k by Andreas Schwab.
+ *
+ * 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.
+ */
+
+#if defined (__SUPPORT_LD_DEBUG__)
+static const char *_dl_reltypes[] =
+{
+  "R_68K_NONE",
+  "R_68K_32", "R_68K_16", "R_68K_8",
+  "R_68K_PC32", "R_68K_PC16", "R_68K_PC8",
+  "R_68K_GOT32", "R_68K_GOT16", "R_68K_GOT8",
+  "R_68K_GOT32O", "R_68K_GOT16O", "R_68K_GOT8O",
+  "R_68K_PLT32", "R_68K_PLT16", "R_68K_PLT8",
+  "R_68K_PLT32O", "R_68K_PLT16O", "R_68K_PLT8O",
+  "R_68K_COPY", "R_68K_GLOB_DAT", "R_68K_JMP_SLOT", "R_68K_RELATIVE",
+  "R_68K_NUM"
+};
+#endif
+
+/* Program to load an ELF binary on a linux system, and run it.
+   References to symbols in sharable libraries can be resolved by either
+   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. */
+
+
+unsigned int _dl_linux_resolver (int dummy1, int dummy2, 
+	struct elf_resolve *tpnt, int reloc_entry)
+{
+  int reloc_type;
+  Elf32_Rela *this_reloc;
+  char *strtab;
+  Elf32_Sym *symtab;
+  char *rel_addr;
+  int symtab_index;
+  char *new_addr;
+  char **got_addr;
+  unsigned int instr_addr;
+
+  rel_addr = tpnt->loadaddr + tpnt->dynamic_info[DT_JMPREL];
+  this_reloc = (Elf32_Rela *) (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]
+				 + tpnt->loadaddr);
+  strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
+
+
+  if (reloc_type != R_68K_JMP_SLOT)
+    {
+      _dl_dprintf (2, "%s: incorrect relocation type in jump relocations\n",
+		    _dl_progname);
+      _dl_exit (1);
+    }
+
+  /* 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, "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, resolver);
+  if (!new_addr)
+    {
+      _dl_dprintf (2, "%s: can't resolve symbol '%s'\n",
+		    _dl_progname, strtab + symtab[symtab_index].st_name);
+      _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 (!_dl_debug_nofixups) {
+		*got_addr = new_addr;
+	}
+#else
+	*got_addr = new_addr;
+#endif
+
+  return (unsigned int) new_addr;
+}
+
+void
+_dl_parse_lazy_relocation_information (struct elf_resolve *tpnt,
+                       unsigned long rel_addr, unsigned long rel_size, int type)
+{
+  int i;
+  char *strtab;
+  int reloc_type;
+  int symtab_index;
+  Elf32_Sym *symtab;
+  Elf32_Rela *rpnt;
+  unsigned int *reloc_addr;
+
+  /* Now parse the relocation information.  */
+  rpnt = (Elf32_Rela *) (rel_addr + tpnt->loadaddr);
+  rel_size = rel_size / sizeof (Elf32_Rela);
+
+  symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB]
+				 + tpnt->loadaddr);
+  strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
+
+  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);
+
+      /* When the dynamic linker bootstrapped itself, it resolved some symbols.
+         Make sure we do not do them again.  */
+      if (tpnt->libtype == program_interpreter
+	  && (!symtab_index
+	      || _dl_symbol (strtab + symtab[symtab_index].st_name)))
+	continue;
+
+      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);
+#if defined (__SUPPORT_LD_DEBUG__)
+	  _dl_dprintf (2, "%s ", _dl_reltypes[reloc_type]);
+#endif
+	  if (symtab_index)
+	    _dl_dprintf (2, "'%s'", strtab + symtab[symtab_index].st_name);
+	  _dl_dprintf (2, "\n");
+	  _dl_exit (1);
+	}
+    }
+}
+
+int 
+_dl_parse_relocation_information (struct elf_resolve *tpnt,
+                  unsigned long rel_addr, unsigned long rel_size, int type)
+{
+  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;
+  /* Now parse the relocation information */
+
+  rpnt = (Elf32_Rela *) (rel_addr + tpnt->loadaddr);
+  rel_size = rel_size / sizeof (Elf32_Rela);
+
+  symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB]
+				 + tpnt->loadaddr);
+  strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
+
+  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 (tpnt->libtype == program_interpreter
+	  && (!symtab_index
+	      || _dl_symbol (strtab + symtab[symtab_index].st_name)))
+	continue;
+
+      if (symtab_index)
+	{
+	  symbol_addr = (unsigned int)
+	    _dl_find_hash (strtab + symtab[symtab_index].st_name,
+			   tpnt->symbol_scope,
+			   reloc_type == R_68K_JMP_SLOT ? tpnt : NULL, symbolrel);
+
+	  /* 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_GLOBAL)
+	    {
+	      _dl_dprintf (2, "%s: can't resolve symbol '%s'\n",
+			    _dl_progname, strtab + symtab[symtab_index].st_name);
+	      goof++;
+	    }
+	}
+      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:
+#if 0 /* Do this later.  */
+	  _dl_dprintf (2, "Doing copy");
+	  if (symtab_index)
+	    _dl_dprintf (2, " for symbol %s",
+			  strtab + symtab[symtab_index].st_name);
+	  _dl_dprintf (2, "\n");
+	  _dl_memcpy ((void *) symtab[symtab_index].st_value,
+		      (void *) symbol_addr,
+		      symtab[symtab_index].st_size);
+#endif
+	  break;
+	default:
+	  _dl_dprintf (2, "%s: can't handle reloc type ", _dl_progname);
+#if defined (__SUPPORT_LD_DEBUG__)
+	  _dl_dprintf (2, "%s ", _dl_reltypes[reloc_type]);
+#endif
+	  if (symtab_index)
+	    _dl_dprintf (2, "'%s'", strtab + symtab[symtab_index].st_name);
+	  _dl_dprintf (2, "\n");
+	  _dl_exit (1);
+	}
+
+    }
+  return goof;
+}
+
+/* This is done as a separate step, because there are cases where
+   information is first copied and later initialized.  This results in
+   the wrong information being copied.  Someone at Sun was complaining about
+   a bug in the handling of _COPY by SVr4, and this may in fact be what he
+   was talking about.  Sigh.  */
+
+/* No, there are cases where the SVr4 linker fails to emit COPY relocs
+   at all.  */
+
+int 
+_dl_parse_copy_information (struct dyn_elf *xpnt, unsigned long rel_addr,
+			    unsigned long rel_size, int type)
+{
+  int i;
+  char *strtab;
+  int reloc_type;
+  int goof = 0;
+  Elf32_Sym *symtab;
+  Elf32_Rela *rpnt;
+  unsigned int *reloc_addr;
+  unsigned int symbol_addr;
+  struct elf_resolve *tpnt;
+  int symtab_index;
+  /* Now parse the relocation information */
+
+  tpnt = xpnt->dyn;
+
+  rpnt = (Elf32_Rela *) (rel_addr + tpnt->loadaddr);
+  rel_size = rel_size / sizeof (Elf32_Rela);
+
+  symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB]
+				 + tpnt->loadaddr);
+  strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
+
+  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);
+      if (reloc_type != R_68K_COPY)
+	continue;
+      symtab_index = ELF32_R_SYM (rpnt->r_info);
+      symbol_addr = 0;
+      if (tpnt->libtype == program_interpreter
+	  && (!symtab_index
+	      || _dl_symbol (strtab + symtab[symtab_index].st_name)))
+	continue;
+      if (symtab_index)
+	{
+	  symbol_addr = (unsigned int)
+	    _dl_find_hash (strtab + symtab[symtab_index].st_name,
+			   xpnt->next, NULL, copyrel);
+	  if (!symbol_addr)
+	    {
+	      _dl_dprintf (2, "%s: can't resolve symbol '%s'\n",
+			    _dl_progname, strtab + symtab[symtab_index].st_name);
+	      goof++;
+	    }
+	}
+      if (!goof)
+      _dl_memcpy ((void *) symtab[symtab_index].st_value, (void *) symbol_addr,
+		  symtab[symtab_index].st_size);
+    }
+  return goof;
+}
diff -urN uClibc/ldso-0.9.24/ldso/m68k/ld_syscalls.h uClibc.ldso.24/ldso-0.9.24/ldso/m68k/ld_syscalls.h
--- uClibc/ldso-0.9.24/ldso/m68k/ld_syscalls.h	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/m68k/ld_syscalls.h	2002-03-19 04:43:32.000000000 -0600
@@ -0,0 +1,174 @@
+/*
+ * This file contains the system call macros and syscall 
+ * numbers used by the shared library loader.
+ */
+
+#define __NR_exit		  1
+#define __NR_read		  3
+#define __NR_write		  4
+#define __NR_open		  5
+#define __NR_close		  6
+#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
+
+
+/* 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. */
+
+
+#define __syscall_return(type, res) \
+do { \
+	if ((unsigned long)(res) >= (unsigned long)(-125)) { \
+	/* avoid using res which is declared to be in register d0; \
+	   errno might expand to a function call and clobber it.  */ \
+		/* int __err = -(res); \
+		errno = __err; */ \
+		res = -1; \
+	} \
+	return (type) (res); \
+} while (0)
+
+#define _syscall0(type, name)						\
+type name(void)								\
+{									\
+  long __res;								\
+  __asm__ __volatile__ ("movel	%1, %%d0\n\t"				\
+  			"trap	#0\n\t"					\
+  			"movel	%%d0, %0"				\
+			: "=g" (__res)					\
+			: "i" (__NR_##name)				\
+			: "cc", "%d0");					\
+  if ((unsigned long)(__res) >= (unsigned long)(-125)) {			\
+    /* errno = -__res; */							\
+    __res = -1;								\
+  }									\
+  return (type)__res;							\
+}
+
+#define _syscall1(type, name, atype, a)					\
+type name(atype a)							\
+{									\
+  long __res;								\
+  __asm__ __volatile__ ("movel	%2, %%d1\n\t"				\
+  			"movel	%1, %%d0\n\t"				\
+  			"trap	#0\n\t"					\
+  			"movel	%%d0, %0"				\
+			: "=g" (__res)					\
+			: "i" (__NR_##name),				\
+			  "g" ((long)a)					\
+			: "cc", "%d0", "%d1");				\
+  if ((unsigned long)(__res) >= (unsigned long)(-125)) {			\
+    /* errno = -__res; */							\
+    __res = -1;								\
+  }									\
+  return (type)__res;							\
+}
+
+#define _syscall2(type, name, atype, a, btype, b)			\
+type name(atype a, btype b)						\
+{									\
+  long __res;								\
+  __asm__ __volatile__ ("movel	%3, %%d2\n\t"				\
+  			"movel	%2, %%d1\n\t"				\
+			"movel	%1, %%d0\n\t"				\
+  			"trap	#0\n\t"					\
+  			"movel	%%d0, %0"				\
+			: "=g" (__res)					\
+			: "i" (__NR_##name),				\
+			  "a" ((long)a),				\
+			  "g" ((long)b)					\
+			: "cc", "%d0", "%d1", "%d2");			\
+  if ((unsigned long)(__res) >= (unsigned long)(-125)) {			\
+    /* errno = -__res; */							\
+    __res = -1;								\
+  }									\
+  return (type)__res;							\
+}
+
+#define _syscall3(type, name, atype, a, btype, b, ctype, c)		\
+type name(atype a, btype b, ctype c)					\
+{									\
+  long __res;								\
+  __asm__ __volatile__ ("movel	%4, %%d3\n\t"				\
+			"movel	%3, %%d2\n\t"				\
+  			"movel	%2, %%d1\n\t"				\
+			"movel	%1, %%d0\n\t"				\
+  			"trap	#0\n\t"					\
+  			"movel	%%d0, %0"				\
+			: "=g" (__res)					\
+			: "i" (__NR_##name),				\
+			  "a" ((long)a),				\
+			  "a" ((long)b),				\
+			  "g" ((long)c)					\
+			: "cc", "%d0", "%d1", "%d2", "%d3");		\
+  if ((unsigned long)(__res) >= (unsigned long)(-125)) {			\
+    /* errno = -__res; */							\
+    __res = -1;								\
+  }									\
+  return (type)__res;							\
+}
+
+#define _syscall4(type, name, atype, a, btype, b, ctype, c, dtype, d)	\
+type name(atype a, btype b, ctype c, dtype d)				\
+{									\
+  long __res;								\
+  __asm__ __volatile__ ("movel	%5, %%d4\n\t"				\
+			"movel	%4, %%d3\n\t"				\
+			"movel	%3, %%d2\n\t"				\
+  			"movel	%2, %%d1\n\t"				\
+			"movel	%1, %%d0\n\t"				\
+  			"trap	#0\n\t"					\
+  			"movel	%%d0, %0"				\
+			: "=g" (__res)					\
+			: "i" (__NR_##name),				\
+			  "a" ((long)a),				\
+			  "a" ((long)b),				\
+			  "a" ((long)c),				\
+			  "g" ((long)d)					\
+			: "cc", "%d0", "%d1", "%d2", "%d3",		\
+			  "%d4");					\
+  if ((unsigned long)(__res) >= (unsigned long)(-125)) {			\
+    /* errno = -__res; */							\
+    __res = -1;								\
+  }									\
+  return (type)__res;							\
+}
+
+#define _syscall5(type, name, atype, a, btype, b, ctype, c, dtype, d, etype, e)\
+type name(atype a, btype b, ctype c, dtype d, etype e)			\
+{									\
+  long __res;								\
+  __asm__ __volatile__ ("movel	%6, %%d5\n\t"				\
+			"movel	%5, %%d4\n\t"				\
+			"movel	%4, %%d3\n\t"				\
+			"movel	%3, %%d2\n\t"				\
+  			"movel	%2, %%d1\n\t"				\
+			"movel	%1, %%d0\n\t"				\
+  			"trap	#0\n\t"					\
+  			"movel	%%d0, %0"				\
+			: "=g" (__res)					\
+			: "i" (__NR_##name),				\
+			  "a" ((long)a),				\
+			  "a" ((long)b),				\
+			  "a" ((long)c),				\
+			  "a" ((long)d),				\
+			  "g" ((long)e)					\
+			: "cc", "%d0", "%d1", "%d2", "%d3",		\
+			  "%d4", "%d5");				\
+  if ((unsigned long)(__res) >= (unsigned long)(-125)) {			\
+    /* errno = -__res; */							\
+    __res = -1;								\
+  }									\
+  return (type)__res;							\
+}
+
diff -urN uClibc/ldso-0.9.24/ldso/m68k/ld_sysdep.h uClibc.ldso.24/ldso-0.9.24/ldso/m68k/ld_sysdep.h
--- uClibc/ldso-0.9.24/ldso/m68k/ld_sysdep.h	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/m68k/ld_sysdep.h	2002-05-28 16:33:34.000000000 -0500
@@ -0,0 +1,88 @@
+
+/* Various assmbly language/system dependent hacks that are required
+   so that we can minimize the amount of platform specific code. */
+
+/* Define this if the system uses RELOCA.  */
+#define ELF_USES_RELOCA
+
+/* 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)))
+
+/* Initialization sequence for a GOT.  */
+#define INIT_GOT(GOT_BASE,MODULE)		\
+{						\
+  GOT_BASE[2] = (int) _dl_linux_resolve;	\
+  GOT_BASE[1] = (int) (MODULE);			\
+}
+
+/* Here is a macro to perform a relocation.  This is only used when
+   bootstrapping the dynamic loader.  RELP is the relocation that we
+   are performing, REL is the pointer to the address we are
+   relocating.  SYMBOL is the symbol involved in the relocation, and
+   LOAD is the load address. */
+#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD)		\
+  switch (ELF32_R_TYPE ((RELP)->r_info))			\
+    {								\
+    case R_68K_8:						\
+      *(char *) (REL) = (SYMBOL) + (RELP)->r_addend;		\
+      break;							\
+    case R_68K_16:						\
+      *(short *) (REL) = (SYMBOL) + (RELP)->r_addend;		\
+      break;							\
+    case R_68K_32:						\
+      *(REL) = (SYMBOL) + (RELP)->r_addend;			\
+      break;							\
+    case R_68K_PC8:						\
+      *(char *) (REL) = ((SYMBOL) + (RELP)->r_addend		\
+			 - (unsigned int) (REL));		\
+      break;							\
+    case R_68K_PC16:						\
+      *(short *) (REL) = ((SYMBOL) + (RELP)->r_addend		\
+			  - (unsigned int) (REL));		\
+      break;							\
+    case R_68K_PC32:						\
+      *(REL) = ((SYMBOL) + (RELP)->r_addend			\
+		- (unsigned int) (REL));			\
+      break;							\
+    case R_68K_GLOB_DAT:					\
+    case R_68K_JMP_SLOT:					\
+      *(REL) = (SYMBOL);					\
+      break;							\
+    case R_68K_RELATIVE:		/* Compatibility kludge */ \
+      *(REL) = ((unsigned int) (LOAD) + ((RELP)->r_addend ? : *(REL))); \
+      break;							\
+    default:							\
+      _dl_exit (1);						\
+    }
+
+
+/* Transfer control to the user's application, once the dynamic loader
+   is done.  */
+
+#define START()					\
+  __asm__ volatile ("unlk %%a6\n\t"		\
+		    "jmp %0@"			\
+		    : : "a" (_dl_elf_main));
+
+
+
+/* Here we define the magic numbers that this dynamic loader should accept */
+
+#define MAGIC1 EM_68K
+#undef MAGIC2
+/* Used for error messages */
+#define ELF_TARGET "m68k"
+
+struct elf_resolve;
+extern unsigned int _dl_linux_resolver (int, int, 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
+#define OFFS_ALIGN 0x7ffff000
diff -urN uClibc/ldso-0.9.24/ldso/m68k/resolve.S uClibc.ldso.24/ldso-0.9.24/ldso/m68k/resolve.S
--- uClibc/ldso-0.9.24/ldso/m68k/resolve.S	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/m68k/resolve.S	2001-04-27 12:23:26.000000000 -0500
@@ -0,0 +1,21 @@
+/*
+ * These are various helper routines that are needed to run an ELF image.
+ */
+
+.text
+.even
+
+.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
diff -urN uClibc/ldso-0.9.24/ldso/mips/README uClibc.ldso.24/ldso-0.9.24/ldso/mips/README
--- uClibc/ldso-0.9.24/ldso/mips/README	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/mips/README	2002-07-25 16:15:59.000000000 -0500
@@ -0,0 +1,52 @@
+Almost all of the code present in these source files was taken
+from GLIBC. In the descriptions below, all files mentioned are
+with respect to the top level GLIBC source directory accept for
+code taken from the Linux kernel.
+
+boot1_arch.h
+------------
+Contains code to fix up the stack pointer so that the dynamic
+linker can find argc, argv and Auxillary Vector Table (AVT).
+The code is taken from the function 'RTLD_START' in the file
+'sysdeps/mips/dl-machine.h'.
+
+elfinterp.c
+-----------
+Contains the runtime resolver code taken from the function
+'__dl_runtime_resolve' in 'sysdeps/mips/dl-machine.h'. Also
+contains the function to perform relocations for objects
+other than the linker itself. The code was taken from the
+function 'elf_machine_rel' in 'sysdeps/mips/dl-machine.h'.
+
+ld_syscalls.h
+-------------
+Used to contain all the macro functions for the system calls
+as well as the list of system calls supported. We now include
+<sys/syscall.h> but with the __set_errno macro defined empty
+so we can use the same file for the linker as well as userspace.
+Original code was taken from the Linux kernel source 2.4.17 and
+can be found in the file 'include/asm-mips/unistd.h'.
+
+ld_sysdep.h
+-----------
+Contains bootstrap code for the dynamic linker, magic numbers
+for detecting MIPS target types and some macros. The macro
+function 'PERFORM_BOOTSTRAP_GOT' is used to relocate the dynamic
+linker's GOT so that function calls can be made. The code is
+taken from the function 'ELF_MACHINE_BEFORE_RTLD_RELOC' in the
+file 'sysdeps/mips/dl-machine.h'. The other macro function
+'PERFORM_BOOTSTRAP_RELOC' is used to do the relocations for
+the dynamic loader. The code is taken from the function
+'elf_machine_rel' in the file 'sysdeps/mips/dl-machine.h'. The
+final macro function is 'INIT_GOT' which initializes the GOT
+for the application being dynamically linked and loaded. The
+code is taken from the functions 'elf_machine_runtime_setup'
+and 'elf_machine_got_rel' in 'sysdeps/mips/dl-machine.h'.
+
+resolve.S
+---------
+Contains the low-level assembly code for the dynamic runtime
+resolver. The code is taken from the assembly code function
+'_dl_runtime_resolve' in the file 'sysdeps/mips/dl-machine.h'.
+The code looks a bit different since we only need to pass the
+symbol index and the old GP register.
diff -urN uClibc/ldso-0.9.24/ldso/mips/boot1_arch.h uClibc.ldso.24/ldso-0.9.24/ldso/mips/boot1_arch.h
--- uClibc/ldso-0.9.24/ldso/mips/boot1_arch.h	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/mips/boot1_arch.h	2003-06-12 16:39:10.000000000 -0500
@@ -0,0 +1,38 @@
+/* Any assmbly language/system dependent hacks needed to setup boot1.c so it
+ * will work as expected and cope with whatever platform specific wierdness is
+ * needed for this architecture.
+ */
+
+asm("" \
+"	.text\n"			\
+"	.globl	_dl_boot\n"		\
+"_dl_boot:\n"				\
+"	.set noreorder\n"		\
+"	bltzal $0, 0f\n"		\
+"	nop\n"				\
+"0:	.cpload $31\n"			\
+"	.set reorder\n"			\
+"	la $4, _DYNAMIC\n"		\
+"	sw $4, -0x7ff0($28)\n"	        \
+"	move $4, $29\n"			\
+"	la $8, coff\n"			\
+"	.set noreorder\n"		\
+"	bltzal $0, coff\n"		\
+"	nop\n"				\
+"coff:	subu $8, $31, $8\n"		\
+"	.set reorder\n"			\
+"	la $25, _dl_boot2\n"	        \
+"	addu $25, $8\n"			\
+"	jalr $25\n"			\
+"	lw $4, 0($29)\n"		\
+"	la $5, 4($29)\n"		\
+"	sll $6, $4, 2\n"		\
+"	addu $6, $6, $5\n"		\
+"	addu $6, $6, 4\n"		\
+"	la $7, _dl_elf_main\n"		\
+"	lw $25, 0($7)\n"		\
+"	jr $25\n"			\
+);
+
+#define _dl_boot _dl_boot2
+#define LD_BOOT(X)   static void __attribute__ ((unused)) _dl_boot (X)
diff -urN uClibc/ldso-0.9.24/ldso/mips/elfinterp.c uClibc.ldso.24/ldso-0.9.24/ldso/mips/elfinterp.c
--- uClibc/ldso-0.9.24/ldso/mips/elfinterp.c	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/mips/elfinterp.c	2003-08-22 02:04:16.000000000 -0500
@@ -0,0 +1,301 @@
+/* vi: set sw=4 ts=4: */
+/* mips/mipsel ELF shared library loader suppport
+ *
+   Copyright (C) 2002, Steven J. Hill (sjhill@realitydiluted.com)
+ *
+ * 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.
+ */
+
+#if defined (__SUPPORT_LD_DEBUG__)
+static const char *_dl_reltypes_tab[] =
+{
+		[0]		"R_MIPS_NONE",	"R_MIPS_16",	"R_MIPS_32",
+		[3]		"R_MIPS_REL32",	"R_MIPS_26",	"R_MIPS_HI16",
+		[6]		"R_MIPS_LO16",	"R_MIPS_GPREL16",	"R_MIPS_LITERAL",
+		[9]		"R_MIPS_GOT16",	"R_MIPS_PC16",	"R_MIPS_CALL16",
+		[12]	"R_MIPS_GPREL32",
+		[16]	"R_MIPS_SHIFT5",	"R_MIPS_SHIFT6",	"R_MIPS_64",
+		[19]	"R_MIPS_GOT_DISP",	"R_MIPS_GOT_PAGE",	"R_MIPS_GOT_OFST",
+		[22]	"R_MIPS_GOT_HI16",	"R_MIPS_GOT_LO16",	"R_MIPS_SUB",
+		[25]	"R_MIPS_INSERT_A",	"R_MIPS_INSERT_B",	"R_MIPS_DELETE",
+		[28]	"R_MIPS_HIGHER",	"R_MIPS_HIGHEST",	"R_MIPS_CALL_HI16",
+		[31]	"R_MIPS_CALL_LO16",	"R_MIPS_SCN_DISP",	"R_MIPS_REL16",
+		[34]	"R_MIPS_ADD_IMMEDIATE",	"R_MIPS_PJUMP",	"R_MIPS_RELGOT",
+		[37]	"R_MIPS_JALR",
+};
+
+static const char *
+_dl_reltypes(int type)
+{
+  static char buf[22];  
+  const char *str;
+  
+  if (type >= (int)(sizeof (_dl_reltypes_tab)/sizeof(_dl_reltypes_tab[0])) ||
+      NULL == (str = _dl_reltypes_tab[type]))
+  {
+    str =_dl_simple_ltoa( buf, (unsigned long)(type));
+  }
+  return str;
+}
+
+static 
+void debug_sym(Elf32_Sym *symtab,char *strtab,int symtab_index)
+{
+  if(_dl_debug_symbols)
+  {
+    if(symtab_index){
+      _dl_dprintf(_dl_debug_file, "\n%s\n\tvalue=%x\tsize=%x\tinfo=%x\tother=%x\tshndx=%x",
+		  strtab + symtab[symtab_index].st_name,
+		  symtab[symtab_index].st_value,
+		  symtab[symtab_index].st_size,
+		  symtab[symtab_index].st_info,
+		  symtab[symtab_index].st_other,
+		  symtab[symtab_index].st_shndx);
+    }
+  }
+}
+
+static void debug_reloc(Elf32_Sym *symtab,char *strtab, ELF_RELOC *rpnt)
+{
+  if(_dl_debug_reloc)
+  {
+    int symtab_index;
+    const char *sym;
+    symtab_index = ELF32_R_SYM(rpnt->r_info);
+    sym = symtab_index ? strtab + symtab[symtab_index].st_name : "sym=0x0";
+    
+  if(_dl_debug_symbols)
+	  _dl_dprintf(_dl_debug_file, "\n\t");
+  else
+	  _dl_dprintf(_dl_debug_file, "\n%s\n\t", sym);
+#ifdef ELF_USES_RELOCA
+    _dl_dprintf(_dl_debug_file, "%s\toffset=%x\taddend=%x",
+		_dl_reltypes(ELF32_R_TYPE(rpnt->r_info)),
+		rpnt->r_offset,
+		rpnt->r_addend);
+#else
+    _dl_dprintf(_dl_debug_file, "%s\toffset=%x\n",
+		_dl_reltypes(ELF32_R_TYPE(rpnt->r_info)),
+		rpnt->r_offset);
+#endif
+  }
+}
+#endif
+
+extern int _dl_linux_resolve(void);
+
+#define OFFSET_GP_GOT 0x7ff0
+
+unsigned long _dl_linux_resolver(unsigned long sym_index,
+	unsigned long old_gpreg)
+{
+	unsigned long *got = (unsigned long *) (old_gpreg - OFFSET_GP_GOT);
+	struct elf_resolve *tpnt = (struct elf_resolve *) got[1];
+	Elf32_Sym *sym;
+	char *strtab;
+	unsigned long local_gotno;
+	unsigned long gotsym;
+	unsigned long new_addr;
+	unsigned long instr_addr;
+	char **got_addr;
+	char *symname;
+
+	gotsym = tpnt->mips_gotsym;
+	local_gotno = tpnt->mips_local_gotno;
+
+	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;
+
+	new_addr = (unsigned long) _dl_find_hash(strtab + sym->st_name,
+		 tpnt->symbol_scope, tpnt, resolver);
+	 
+	/* Address of jump instruction to fix up */
+	instr_addr = (unsigned long) (got + local_gotno + sym_index - gotsym); 
+	got_addr = (char **) instr_addr;
+	 
+#if defined (__SUPPORT_LD_DEBUG__)
+	if (_dl_debug_bindings)
+	{
+		_dl_dprintf(_dl_debug_file, "\nresolve function: %s", symname);
+		if(_dl_debug_detail) _dl_dprintf(_dl_debug_file, 
+				"\n\tpatched %x ==> %x @ %x\n", *got_addr, new_addr, got_addr);
+	}
+	if (!_dl_debug_nofixups) {
+		*got_addr = (char*)new_addr;
+	}
+#else
+	*got_addr = (char*)new_addr;
+#endif
+
+	return new_addr;
+}
+
+void _dl_parse_lazy_relocation_information(struct elf_resolve *tpnt, 
+	unsigned long rel_addr, unsigned long rel_size, int type)
+{
+	/* Nothing to do */
+	return;
+}
+
+int _dl_parse_copy_information(struct dyn_elf *xpnt, unsigned long rel_addr, 
+	unsigned long rel_size, int type)
+{
+	/* Nothing to do */
+	return 0;
+}
+
+
+int _dl_parse_relocation_information(struct elf_resolve *tpnt, 
+	unsigned long rel_addr, unsigned long rel_size, int type)
+{
+	Elf32_Sym *symtab;
+	Elf32_Rel *rpnt;
+	char *strtab;
+	unsigned long *got;
+	unsigned long *reloc_addr=NULL, old_val=0;
+	unsigned long symbol_addr;
+	int i, reloc_type, symtab_index;
+
+	/* Now parse the relocation information */
+	rel_size = rel_size / sizeof(Elf32_Rel);
+	rpnt = (Elf32_Rel *) (rel_addr + tpnt->loadaddr);
+
+	symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
+	strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
+	got = (unsigned long *) (tpnt->dynamic_info[DT_PLTGOT] + tpnt->loadaddr);
+
+	for (i = 0; i < rel_size; i++, rpnt++) {
+		reloc_addr = (unsigned long *) (tpnt->loadaddr +
+			(unsigned long) 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 && tpnt->libtype == program_interpreter)
+			continue;
+
+#if defined (__SUPPORT_LD_DEBUG__)
+		debug_sym(symtab,strtab,symtab_index);
+		debug_reloc(symtab,strtab,rpnt);
+		old_val = *reloc_addr;
+#endif
+
+		switch (reloc_type) {
+		case R_MIPS_REL32:
+			if (symtab_index) {
+				if (symtab_index < tpnt->mips_gotsym)
+					*reloc_addr +=
+						symtab[symtab_index].st_value +
+						(unsigned long) tpnt->loadaddr;
+				else {
+					*reloc_addr += got[symtab_index + tpnt->mips_local_gotno -
+						tpnt->mips_gotsym];
+				}
+			}
+			else {
+				*reloc_addr += (unsigned long) tpnt->loadaddr;
+			}
+			break;
+		case R_MIPS_NONE:
+			break;
+		default:
+			{
+				int reloc_type = ELF32_R_TYPE(rpnt->r_info);
+				_dl_dprintf(2, "\n%s: ",_dl_progname);
+
+				if (symtab_index)
+					_dl_dprintf(2, "symbol '%s': ", strtab + symtab[symtab_index].st_name);
+
+#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(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;
+}
+
+void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt)
+{
+	Elf32_Sym *sym;
+	char *strtab;
+	unsigned long i;
+	unsigned long *got_entry;
+
+	for (; tpnt ; tpnt = tpnt->next) {
+
+		/* We don't touch the dynamic linker */
+		if (tpnt->libtype == program_interpreter)
+			continue;
+
+		/* Setup the loop variables */
+		got_entry = (unsigned long *) (tpnt->loadaddr +
+			tpnt->dynamic_info[DT_PLTGOT]) + tpnt->mips_local_gotno;
+		sym = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] +
+			(unsigned long) tpnt->loadaddr) + tpnt->mips_gotsym;
+		strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] +
+			(unsigned long) tpnt->loadaddr);
+		i = tpnt->mips_symtabno - tpnt->mips_gotsym;
+
+		/* Relocate the global GOT entries for the object */
+		while(i--) {
+			if (sym->st_shndx == SHN_UNDEF) {
+				if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC && sym->st_value)
+					*got_entry = sym->st_value + (unsigned long) tpnt->loadaddr;
+				else {
+					*got_entry = (unsigned long) _dl_find_hash(strtab +
+						sym->st_name, tpnt->symbol_scope, NULL, copyrel);
+				}
+			}
+			else if (sym->st_shndx == SHN_COMMON) {
+				*got_entry = (unsigned long) _dl_find_hash(strtab +
+					sym->st_name, tpnt->symbol_scope, NULL, copyrel);
+			}
+			else if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC &&
+				*got_entry != sym->st_value)
+				*got_entry += (unsigned long) tpnt->loadaddr;
+			else if (ELF32_ST_TYPE(sym->st_info) == STT_SECTION) {
+				if (sym->st_other == 0)
+					*got_entry += (unsigned long) tpnt->loadaddr;
+			}
+			else {
+				*got_entry = (unsigned long) _dl_find_hash(strtab +
+					sym->st_name, tpnt->symbol_scope, NULL, copyrel);
+			}
+
+			got_entry++;
+			sym++;
+		}
+	}
+}
diff -urN uClibc/ldso-0.9.24/ldso/mips/ld_syscalls.h uClibc.ldso.24/ldso-0.9.24/ldso/mips/ld_syscalls.h
--- uClibc/ldso-0.9.24/ldso/mips/ld_syscalls.h	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/mips/ld_syscalls.h	2002-08-09 07:20:20.000000000 -0500
@@ -0,0 +1,7 @@
+/* Define the __set_errno macro as nothing so that we don't bother
+ * setting errno, which is important since we make system calls
+ * before the errno symbol is dynamicly linked. */
+
+#define __set_errno(X) {(void)(X);}
+#include "sys/syscall.h"
+
diff -urN uClibc/ldso-0.9.24/ldso/mips/ld_sysdep.h uClibc.ldso.24/ldso-0.9.24/ldso/mips/ld_sysdep.h
--- uClibc/ldso-0.9.24/ldso/mips/ld_sysdep.h	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/mips/ld_sysdep.h	2002-05-28 16:33:36.000000000 -0500
@@ -0,0 +1,136 @@
+/* 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.
+ */
+
+/* 
+ * Define this if the system uses RELOCA.
+ */
+#undef ELF_USES_RELOCA
+
+
+/*
+ * 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)
+
+
+/*
+ * Initialization sequence for the application/library GOT.
+ */
+#define INIT_GOT(GOT_BASE,MODULE)										\
+do {																	\
+	unsigned long i;													\
+																		\
+	/* Check if this is the dynamic linker itself */					\
+	if (MODULE->libtype == program_interpreter)							\
+		continue;														\
+																		\
+	/* Fill in first two GOT entries according to the ABI */			\
+	GOT_BASE[0] = (unsigned long) _dl_linux_resolve;					\
+	GOT_BASE[1] = (unsigned long) MODULE;								\
+																		\
+	/* Add load address displacement to all local GOT entries */		\
+	i = 2;																\
+	while (i < MODULE->mips_local_gotno)								\
+		GOT_BASE[i++] += (unsigned long) MODULE->loadaddr;				\
+																		\
+} while (0)
+
+
+/*
+ * Here is a macro to perform the GOT relocation. This is only
+ * used when bootstrapping the dynamic loader.
+ */
+#define PERFORM_BOOTSTRAP_GOT(got)										\
+do {																	\
+	Elf32_Sym *sym;														\
+	unsigned long i;													\
+																		\
+	/* Add load address displacement to all local GOT entries */		\
+	i = 2;																\
+	while (i < tpnt->mips_local_gotno)									\
+		got[i++] += load_addr;											\
+																		\
+	/* Handle global GOT entries */										\
+	got += tpnt->mips_local_gotno;										\
+	sym = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] +				\
+		 load_addr) + tpnt->mips_gotsym;								\
+	i = tpnt->mips_symtabno - tpnt->mips_gotsym;						\
+																		\
+	while (i--) {														\
+		if (sym->st_shndx == SHN_UNDEF ||								\
+			sym->st_shndx == SHN_COMMON)								\
+			*got = load_addr + sym->st_value;							\
+		else if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC &&				\
+			*got != sym->st_value)										\
+			*got += load_addr;											\
+		else if (ELF32_ST_TYPE(sym->st_info) == STT_SECTION) {			\
+			if (sym->st_other == 0)										\
+				*got += load_addr;										\
+		}																\
+		else															\
+			*got = load_addr + sym->st_value;							\
+																		\
+		got++;															\
+		sym++;															\
+	}																	\
+} while (0)
+
+
+/*
+ * 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)					\
+	switch(ELF32_R_TYPE((RELP)->r_info)) {								\
+	case R_MIPS_REL32:													\
+		if (symtab_index) {												\
+			if (symtab_index < tpnt->mips_gotsym)						\
+				*REL += SYMBOL;											\
+		}																\
+		else {															\
+			*REL += LOAD;												\
+		}																\
+		break;															\
+	case R_MIPS_NONE:													\
+		break;															\
+	default:															\
+		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()
+
+
+/* Here we define the magic numbers that this dynamic loader should accept */
+#define MAGIC1 EM_MIPS
+#define MAGIC2 EM_MIPS_RS3_LE
+
+
+/* Used for error messages */
+#define ELF_TARGET "MIPS"
+
+
+unsigned long _dl_linux_resolver(unsigned long sym_index,
+	unsigned long old_gpreg);
+
+
+#define do_rem(result, n, base)  result = (n % base)
+
+/* 4096 bytes alignment */
+#define PAGE_ALIGN 0xfffff000
+#define ADDR_ALIGN 0xfff
+#define OFFS_ALIGN 0x7ffff000
diff -urN uClibc/ldso-0.9.24/ldso/mips/resolve.S uClibc.ldso.24/ldso-0.9.24/ldso/mips/resolve.S
--- uClibc/ldso-0.9.24/ldso/mips/resolve.S	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/mips/resolve.S	2003-01-30 10:40:26.000000000 -0600
@@ -0,0 +1,45 @@
+	/*
+ * Linux dynamic resolving code for MIPS. Fixes up the GOT entry as
+ * indicated in register t8 and jumps to the resolved address. Shamelessly
+ * ripped from 'sysdeps/mips/dl-machine.h' in glibc-2.2.5.
+ *
+ * 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) 1996-2001 Kazumoto Kojima <kkojima@info.kanagawa-u.ac.jp>
+ * Copyright (C) 2002 Steven J. Hill <sjhill@realitydiluted.com>
+ *
+ */
+.text
+.align	2
+.globl	_dl_linux_resolve
+.type	_dl_linux_resolve,@function
+.ent	_dl_linux_resolve
+_dl_linux_resolve:
+	.frame	$29, 40, $31
+	.set noreorder
+	move	$3, $28		# Save GP
+	addu	$25, 8		# t9 ($25) now points at .cpload instruction
+	.cpload	$25		# Compute GP
+	.set reorder
+	subu	$29, 40
+	.cprestore 32
+	sw	$15, 36($29)
+	sw	$4, 16($29)
+	sw	$5, 20($29)
+	sw	$6, 24($29)
+	sw	$7, 28($29)
+	move	$4, $24
+	move	$5, $3
+	jal     _dl_linux_resolver
+	lw	$31, 36($29)
+	lw	$4, 16($29)
+	lw	$5, 20($29)
+	lw	$6, 24($29)
+	lw	$7, 28($29)
+	addu	$29, 40
+	move	$25, $2
+	jr	$25
+.size _dl_linux_resolve,.-_dl_linux_resolve
+.end _dl_linux_resolve
diff -urN uClibc/ldso-0.9.24/ldso/powerpc/boot1_arch.h uClibc.ldso.24/ldso-0.9.24/ldso/powerpc/boot1_arch.h
--- uClibc/ldso-0.9.24/ldso/powerpc/boot1_arch.h	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/powerpc/boot1_arch.h	2003-02-15 19:22:41.000000000 -0600
@@ -0,0 +1,20 @@
+/* Any assmbly language/system dependent hacks needed to setup boot1.c so it
+ * will work as expected and cope with whatever platform specific wierdness is
+ * needed for this architecture.  */
+
+/* Overrive the default _dl_boot function, and replace it with a bit of asm.
+ * Then call the real _dl_boot function, which is now named _dl_boot2. */
+
+asm("" \
+"	.text\n"			\
+"	.globl	_dl_boot\n"		\
+"_dl_boot:\n"				\
+"	mr	3,1\n"			\
+"	addi	1,1,-16\n"		\
+"	bl      _dl_boot2\n"		\
+".previous\n"				\
+);
+
+#define _dl_boot _dl_boot2
+#define LD_BOOT(X)   static void *  __attribute__ ((unused)) _dl_boot (X)
+
diff -urN uClibc/ldso-0.9.24/ldso/powerpc/elfinterp.c uClibc.ldso.24/ldso-0.9.24/ldso/powerpc/elfinterp.c
--- uClibc/ldso-0.9.24/ldso/powerpc/elfinterp.c	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/powerpc/elfinterp.c	2003-12-03 17:28:33.000000000 -0600
@@ -0,0 +1,621 @@
+/* vi: set sw=4 ts=4: */
+/* powerpc shared library loader suppport
+ *
+ * Copyright (C) 2001-2002,  David A. Schleef
+ * Copyright (C) 2003, Erik Andersen
+ *
+ * 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.
+ */
+
+#if defined (__SUPPORT_LD_DEBUG__)
+static const char *_dl_reltypes_tab[] =
+	{ "R_PPC_NONE", "R_PPC_ADDR32", "R_PPC_ADDR24", "R_PPC_ADDR16",
+	"R_PPC_ADDR16_LO", "R_PPC_ADDR16_HI", "R_PPC_ADDR16_HA",
+	"R_PPC_ADDR14", "R_PPC_ADDR14_BRTAKEN", "R_PPC_ADDR14_BRNTAKEN",
+	"R_PPC_REL24", "R_PPC_REL14", "R_PPC_REL14_BRTAKEN",
+	"R_PPC_REL14_BRNTAKEN", "R_PPC_GOT16", "R_PPC_GOT16_LO",
+	"R_PPC_GOT16_HI", "R_PPC_GOT16_HA", "R_PPC_PLTREL24",
+	"R_PPC_COPY", "R_PPC_GLOB_DAT", "R_PPC_JMP_SLOT", "R_PPC_RELATIVE",
+	"R_PPC_LOCAL24PC", "R_PPC_UADDR32", "R_PPC_UADDR16", "R_PPC_REL32",
+	"R_PPC_PLT32", "R_PPC_PLTREL32", "R_PPC_PLT16_LO", "R_PPC_PLT16_HI",
+	"R_PPC_PLT16_HA", "R_PPC_SDAREL16", "R_PPC_SECTOFF",
+	"R_PPC_SECTOFF_LO", "R_PPC_SECTOFF_HI", "R_PPC_SECTOFF_HA",
+};
+
+static const char *
+_dl_reltypes(int type)
+{
+  static char buf[22];  
+  const char *str;
+  
+  if (type >= (int)(sizeof (_dl_reltypes_tab)/sizeof(_dl_reltypes_tab[0])) ||
+      NULL == (str = _dl_reltypes_tab[type]))
+  {
+    str =_dl_simple_ltoa( buf, (unsigned long)(type));
+  }
+  return str;
+}
+
+static 
+void debug_sym(Elf32_Sym *symtab,char *strtab,int symtab_index)
+{
+  if(_dl_debug_symbols)
+  {
+    if(symtab_index){
+      _dl_dprintf(_dl_debug_file, "\n%s\n\tvalue=%x\tsize=%x\tinfo=%x\tother=%x\tshndx=%x",
+		  strtab + symtab[symtab_index].st_name,
+		  symtab[symtab_index].st_value,
+		  symtab[symtab_index].st_size,
+		  symtab[symtab_index].st_info,
+		  symtab[symtab_index].st_other,
+		  symtab[symtab_index].st_shndx);
+    }
+  }
+}
+
+static 
+void debug_reloc(Elf32_Sym *symtab,char *strtab, ELF_RELOC *rpnt)
+{
+  if(_dl_debug_reloc)
+  {
+    int symtab_index;
+    const char *sym;
+    symtab_index = ELF32_R_SYM(rpnt->r_info);
+    sym = symtab_index ? strtab + symtab[symtab_index].st_name : "sym=0x0";
+    
+  if(_dl_debug_symbols)
+	  _dl_dprintf(_dl_debug_file, "\n\t");
+  else
+	  _dl_dprintf(_dl_debug_file, "\n%s\n\t", sym);
+#ifdef ELF_USES_RELOCA
+    _dl_dprintf(_dl_debug_file, "%s\toffset=%x\taddend=%x",
+		_dl_reltypes(ELF32_R_TYPE(rpnt->r_info)),
+		rpnt->r_offset,
+		rpnt->r_addend);
+#else
+    _dl_dprintf(_dl_debug_file, "%s\toffset=%x\n",
+		_dl_reltypes(ELF32_R_TYPE(rpnt->r_info)),
+		rpnt->r_offset);
+#endif
+  }
+}
+#endif
+
+extern int _dl_linux_resolve(void);
+
+void _dl_init_got(unsigned long *plt,struct elf_resolve *tpnt)
+{
+	unsigned long target_addr = (unsigned long)_dl_linux_resolve;
+	unsigned int n_plt_entries;
+	unsigned long *tramp;
+	unsigned long data_words;
+	unsigned int rel_offset_words;
+
+	//DPRINTF("init_got plt=%x, tpnt=%x\n", (unsigned long)plt,(unsigned long)tpnt);
+
+	n_plt_entries = tpnt->dynamic_info[DT_PLTRELSZ] / sizeof(ELF_RELOC);
+	//DPRINTF("n_plt_entries %d\n",n_plt_entries);
+
+	rel_offset_words = PLT_DATA_START_WORDS(n_plt_entries);
+	//DPRINTF("rel_offset_words %x\n",rel_offset_words);
+	data_words = (unsigned long)(plt + rel_offset_words);
+	//DPRINTF("data_words %x\n",data_words);
+
+	tpnt->data_words = data_words;
+
+	plt[PLT_LONGBRANCH_ENTRY_WORDS] = OPCODE_ADDIS_HI(11, 11, data_words);
+	plt[PLT_LONGBRANCH_ENTRY_WORDS+1] = OPCODE_LWZ(11,data_words,11);
+
+	plt[PLT_LONGBRANCH_ENTRY_WORDS+2] = OPCODE_MTCTR(11);
+	plt[PLT_LONGBRANCH_ENTRY_WORDS+3] = OPCODE_BCTR();
+
+	/* [4] */
+	/* [5] */
+
+	tramp = plt + PLT_TRAMPOLINE_ENTRY_WORDS;
+	tramp[0] = OPCODE_ADDIS_HI(11,11,-data_words);
+	tramp[1] = OPCODE_ADDI(11,11,-data_words);
+	tramp[2] = OPCODE_SLWI(12,11,1);
+	tramp[3] = OPCODE_ADD(11,12,11);
+	tramp[4] = OPCODE_LI(12,target_addr);
+	tramp[5] = OPCODE_ADDIS_HI(12,12,target_addr);
+	tramp[6] = OPCODE_MTCTR(12);
+	tramp[7] = OPCODE_LI(12,(unsigned long)tpnt);
+	tramp[8] = OPCODE_ADDIS_HI(12,12,(unsigned long)tpnt);
+	tramp[9] = OPCODE_BCTR();
+
+	/* [16] unused */
+	/* [17] unused */
+
+	/* instructions were modified */
+	PPC_DCBST(plt);
+	PPC_DCBST(plt+4);
+	PPC_DCBST(plt+8);
+	PPC_DCBST(plt+12);
+	PPC_DCBST(plt+16-1);
+	PPC_SYNC;
+	PPC_ICBI(plt);
+	PPC_ICBI(plt+4); /* glibc thinks this is not needed */
+	PPC_ICBI(plt+8); /* glibc thinks this is not needed */
+	PPC_ICBI(plt+12); /* glibc thinks this is not needed */
+	PPC_ICBI(plt+16-1);
+	PPC_ISYNC;
+}
+
+unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
+{
+	int reloc_type;
+	ELF_RELOC *this_reloc;
+	char *strtab;
+	Elf32_Sym *symtab;
+	ELF_RELOC *rel_addr;
+	int symtab_index;
+	char *symname;
+	unsigned long insn_addr;
+	unsigned long *insns;
+	unsigned long new_addr;
+	unsigned long delta;
+
+	rel_addr = (ELF_RELOC *) (tpnt->dynamic_info[DT_JMPREL] + tpnt->loadaddr);
+
+	this_reloc = (void *)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] + tpnt->loadaddr);
+	strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
+	symname      = strtab + symtab[symtab_index].st_name;
+
+#if defined (__SUPPORT_LD_DEBUG__)
+	debug_sym(symtab,strtab,symtab_index);
+	debug_reloc(symtab,strtab,this_reloc);
+#endif
+
+	if (reloc_type != R_PPC_JMP_SLOT) {
+		_dl_dprintf(2, "%s: Incorrect relocation type in jump relocation\n", _dl_progname);
+		_dl_exit(1);
+	};
+
+	/* Address of dump instruction to fix up */
+	insn_addr = (unsigned long) tpnt->loadaddr +
+		(unsigned long) this_reloc->r_offset;
+
+#if defined (__SUPPORT_LD_DEBUG__)
+	if(_dl_debug_reloc && _dl_debug_detail)
+		_dl_dprintf(_dl_debug_file, "\n\tResolving symbol %s %x --> ", symname, insn_addr);
+#endif
+
+	/* Get the address of the GOT entry */
+	new_addr = (unsigned long) _dl_find_hash(
+		strtab + symtab[symtab_index].st_name, 
+		tpnt->symbol_scope, tpnt, resolver);
+	if (!new_addr) {
+		_dl_dprintf(2, "%s: can't resolve symbol '%s'\n", 
+			_dl_progname, symname);
+		_dl_exit(1);
+	};
+
+#if defined (__SUPPORT_LD_DEBUG__)
+	if(_dl_debug_reloc && _dl_debug_detail)
+		_dl_dprintf(_dl_debug_file, "%x\n", new_addr);
+#endif
+
+	insns = (unsigned long *)insn_addr;
+	delta = new_addr - insn_addr;
+
+	if(delta<<6>>6 == delta){
+		insns[0] = OPCODE_B(delta);
+	}else if (new_addr <= 0x01fffffc || new_addr >= 0xfe000000){
+		insns[0] = OPCODE_BA (new_addr);
+	}else{
+		/* Warning: we don't handle double-sized PLT entries */
+		unsigned long plt_addr;
+		unsigned long *ptr;
+		int index;
+
+		plt_addr = (unsigned long)tpnt->dynamic_info[DT_PLTGOT] + 
+			(unsigned long)tpnt->loadaddr;
+
+		delta = PLT_LONGBRANCH_ENTRY_WORDS*4 - (insn_addr-plt_addr+4);
+
+		index = (insn_addr - plt_addr - PLT_INITIAL_ENTRY_WORDS*4)/8;
+
+		ptr = (unsigned long *)tpnt->data_words;
+		//DPRINTF("plt_addr=%x delta=%x index=%x ptr=%x\n", plt_addr, delta, index, ptr);
+		insns += 1;
+
+		ptr[index] = new_addr;
+		PPC_SYNC;
+		/* icache sync is not necessary, since this will be a data load */
+		//PPC_DCBST(ptr+index);
+		//PPC_SYNC;
+		//PPC_ICBI(ptr+index);
+		//PPC_ISYNC;
+
+		insns[0] = OPCODE_B(delta);
+
+	}
+
+	/* instructions were modified */
+	PPC_DCBST(insns);
+	PPC_SYNC;
+	PPC_ICBI(insns);
+	PPC_ISYNC;
+
+	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_fnc) (struct elf_resolve *tpnt, struct dyn_elf *scope,
+			    ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab))
+{
+	unsigned int i;
+	char *strtab;
+	Elf32_Sym *symtab;
+	ELF_RELOC *rpnt;
+	int symtab_index;
+
+	/* Now parse the relocation information */
+	rpnt = (ELF_RELOC *)(intptr_t) (rel_addr + tpnt->loadaddr);
+	rel_size = rel_size / sizeof(ELF_RELOC);
+
+	symtab = (Elf32_Sym *)(intptr_t) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
+	strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
+
+	  for (i = 0; i < rel_size; i++, rpnt++) {
+	        int res;
+	    
+		symtab_index = ELF32_R_SYM(rpnt->r_info);
+		
+		/* When the dynamic linker bootstrapped itself, it resolved some symbols.
+		   Make sure we do not do them again */
+		if (!symtab_index && tpnt->libtype == program_interpreter)
+			continue;
+		if (symtab_index && tpnt->libtype == program_interpreter &&
+		    _dl_symbol(strtab + symtab[symtab_index].st_name))
+			continue;
+
+#if defined (__SUPPORT_LD_DEBUG__)
+		debug_sym(symtab,strtab,symtab_index);
+		debug_reloc(symtab,strtab,rpnt);
+#endif
+
+		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 (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 if (res >0)
+		{
+			_dl_dprintf(2, "can't resolve symbol\n");
+			return res;
+		}
+	  }
+	  return 0;
+}
+
+static int
+_dl_do_lazy_reloc (struct elf_resolve *tpnt, struct dyn_elf *scope,
+		   ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)
+{
+	int reloc_type;
+	unsigned long reloc_addr;
+#if defined (__SUPPORT_LD_DEBUG__)
+	unsigned long old_val;
+#endif
+	(void)scope;
+	(void)symtab;
+	(void)strtab;
+
+	reloc_addr = (unsigned long)tpnt->loadaddr + (unsigned long) rpnt->r_offset;
+	reloc_type = ELF32_R_TYPE(rpnt->r_info);
+
+#if defined (__SUPPORT_LD_DEBUG__)
+	old_val = reloc_addr;
+#endif
+
+	switch (reloc_type) {
+		case R_PPC_NONE:
+			return 0;
+			break;
+		case R_PPC_JMP_SLOT:
+			{
+				int index;
+				unsigned long delta;
+				unsigned long *plt;
+				unsigned long *insns;
+
+				plt = (unsigned long *)(tpnt->dynamic_info[DT_PLTGOT] + tpnt->loadaddr);
+
+				delta = (unsigned long)(plt+PLT_TRAMPOLINE_ENTRY_WORDS+2) - (reloc_addr+4);
+
+				index = (reloc_addr - (unsigned long)(plt+PLT_INITIAL_ENTRY_WORDS)) 
+						/sizeof(unsigned long);
+				index /= 2;
+				//DPRINTF("        index %x delta %x\n",index,delta);
+				insns = (unsigned long *)reloc_addr;
+				insns[0] = OPCODE_LI(11,index*4);
+				insns[1] = OPCODE_B(delta);
+				break;
+			}
+		default:
+#if 0
+			_dl_dprintf(2, "%s: (LAZY) can't handle reloc type ", 
+					_dl_progname);
+#if defined (__SUPPORT_LD_DEBUG__)
+			_dl_dprintf(2, "%s ", _dl_reltypes[reloc_type]);
+#endif
+			if (symtab_index)
+				_dl_dprintf(2, "'%s'\n", strtab + symtab[symtab_index].st_name);
+#endif
+			//_dl_exit(1);
+			return -1;
+	};
+
+	/* instructions were modified */
+	PPC_DCBST(reloc_addr);
+	PPC_DCBST(reloc_addr+4);
+	PPC_SYNC;
+	PPC_ICBI(reloc_addr);
+	PPC_ICBI(reloc_addr+4);
+	PPC_ISYNC;
+
+#if defined (__SUPPORT_LD_DEBUG__)
+	if(_dl_debug_reloc && _dl_debug_detail)
+		_dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x", old_val, reloc_addr);
+#endif
+	return 0;
+
+}
+
+static int
+_dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope,
+	      ELF_RELOC *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 *)(intptr_t) (tpnt->loadaddr + (unsigned long) 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(symname, scope, 
+				(reloc_type == R_PPC_JMP_SLOT ? tpnt : NULL), symbolrel);
+
+		/*
+		 * 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_GLOBAL) {
+#if defined (__SUPPORT_LD_DEBUG__)
+			_dl_dprintf(2, "\tglobal symbol '%s' already defined in '%s'\n",
+					symname, tpnt->libname);
+#endif
+			return 0;
+		}
+	}
+
+#if defined (__SUPPORT_LD_DEBUG__)
+	old_val = *reloc_addr;
+#endif
+		switch (reloc_type) {
+			case R_PPC_NONE:
+				return 0;
+				break;
+			case R_PPC_REL24:
+#if 0
+				{
+					unsigned long delta = symbol_addr - (unsigned long)reloc_addr;
+					if(delta<<6>>6 != delta){
+						_dl_dprintf(2,"R_PPC_REL24: Reloc out of range\n");
+						_dl_exit(1);
+					}
+					*reloc_addr &= 0xfc000003;
+					*reloc_addr |= delta&0x03fffffc;
+				}
+				break;
+#else
+				_dl_dprintf(2, "%s: symbol '%s' is type R_PPC_REL24\n\tCompile shared libraries with -fPIC!\n",
+						_dl_progname, symname);
+				_dl_exit(1);
+#endif
+			case R_PPC_RELATIVE:
+				*reloc_addr = (unsigned long)tpnt->loadaddr + (unsigned long)rpnt->r_addend;
+				break;
+			case R_PPC_ADDR32:
+				*reloc_addr += symbol_addr;
+				break;
+			case R_PPC_ADDR16_HA:
+				/* XXX is this correct? */
+				*(short *)reloc_addr += (symbol_addr+0x8000)>>16;
+				break;
+			case R_PPC_ADDR16_HI:
+				*(short *)reloc_addr += symbol_addr>>16;
+				break;
+			case R_PPC_ADDR16_LO:
+				*(short *)reloc_addr += symbol_addr;
+				break;
+			case R_PPC_JMP_SLOT:
+				{
+					unsigned long targ_addr = (unsigned long)*reloc_addr;
+					unsigned long delta = targ_addr - (unsigned long)reloc_addr;
+					if(delta<<6>>6 == delta){
+						*reloc_addr = OPCODE_B(delta);
+					}else if (targ_addr <= 0x01fffffc || targ_addr >= 0xfe000000){
+						*reloc_addr = OPCODE_BA (targ_addr);
+					}else{
+						{
+							int index;
+							unsigned long delta2;
+							unsigned long *plt, *ptr;
+							plt = (unsigned long *)(tpnt->dynamic_info[DT_PLTGOT] + tpnt->loadaddr);
+
+							delta2 = (unsigned long)(plt+PLT_LONGBRANCH_ENTRY_WORDS)
+								- (unsigned long)(reloc_addr+1);
+
+							index = ((unsigned long)reloc_addr -
+									(unsigned long)(plt+PLT_INITIAL_ENTRY_WORDS))
+								/sizeof(unsigned long);
+							index /= 2;
+							//DPRINTF("        index %x delta %x\n",index,delta2);
+							ptr = (unsigned long *)tpnt->data_words;
+							ptr[index] = targ_addr;
+							reloc_addr[0] = OPCODE_LI(11,index*4);
+							reloc_addr[1] = OPCODE_B(delta2);
+
+							/* instructions were modified */
+							PPC_DCBST(reloc_addr+1);
+							PPC_SYNC;
+							PPC_ICBI(reloc_addr+1);
+						}
+					}
+					break;
+				}
+			case R_PPC_GLOB_DAT:
+				*reloc_addr += symbol_addr;
+				break;
+			case R_PPC_COPY:
+				// handled later
+				return 0;
+				break;
+			default:
+#if 0
+				_dl_dprintf(2, "%s: can't handle reloc type ", _dl_progname);
+#if defined (__SUPPORT_LD_DEBUG__)
+				_dl_dprintf(2, "%s ", _dl_reltypes[reloc_type]);
+#endif
+				if (symtab_index)
+					_dl_dprintf(2, "'%s'\n", strtab + symtab[symtab_index].st_name);
+#endif
+				//_dl_exit(1);
+				return -1;
+		};
+
+		/* instructions were modified */
+		PPC_DCBST(reloc_addr);
+		PPC_SYNC;
+		PPC_ICBI(reloc_addr);
+		PPC_ISYNC;
+
+#if defined (__SUPPORT_LD_DEBUG__)
+	if(_dl_debug_reloc && _dl_debug_detail)
+		_dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x", old_val, *reloc_addr, reloc_addr);
+#endif
+
+	return 0;
+}
+
+
+/* This is done as a separate step, because there are cases where
+   information is first copied and later initialized.  This results in
+   the wrong information being copied.  Someone at Sun was complaining about
+   a bug in the handling of _COPY by SVr4, and this may in fact be what he
+   was talking about.  Sigh. */
+static int
+_dl_do_copy (struct elf_resolve *tpnt, struct dyn_elf *scope,
+	     ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)
+{
+	int reloc_type;
+	int symtab_index;
+	unsigned long *reloc_addr;
+	unsigned long symbol_addr;
+	int goof = 0;
+	char *symname;
+	  
+	reloc_addr = (unsigned long *)(intptr_t) (tpnt->loadaddr + (unsigned long) rpnt->r_offset);
+	reloc_type = ELF32_R_TYPE(rpnt->r_info);
+	if (reloc_type != R_PPC_COPY) 
+		return 0;
+	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(symname, scope, NULL, copyrel);
+		if (!symbol_addr) goof++;
+	}
+	if (!goof) {
+#if defined (__SUPPORT_LD_DEBUG__)
+	        if(_dl_debug_move)
+		  _dl_dprintf(_dl_debug_file,"\n%s move %x bytes from %x to %x",
+			     symname, symtab[symtab_index].st_size,
+			     symbol_addr, symtab[symtab_index].st_value);
+#endif
+			_dl_memcpy((char *) reloc_addr,
+					(char *) symbol_addr, symtab[symtab_index].st_size);
+	}
+
+	return goof;
+}
+
+void _dl_parse_lazy_relocation_information(struct elf_resolve *tpnt, 
+	unsigned long rel_addr, unsigned long rel_size, int type)
+{
+	(void) type;
+	(void)_dl_parse(tpnt, NULL, rel_addr, rel_size, _dl_do_lazy_reloc);
+}
+
+int _dl_parse_relocation_information(struct elf_resolve *tpnt, 
+	unsigned long rel_addr, unsigned long rel_size, int type)
+{
+	(void) type;
+	return _dl_parse(tpnt, tpnt->symbol_scope, rel_addr, rel_size, _dl_do_reloc);
+}
+
+int _dl_parse_copy_information(struct dyn_elf *xpnt, unsigned long rel_addr, 
+	unsigned long rel_size, int type)
+{
+	(void) type;
+	return _dl_parse(xpnt->dyn, xpnt->next, rel_addr, rel_size, _dl_do_copy);
+}
+
+
diff -urN uClibc/ldso-0.9.24/ldso/powerpc/ld_syscalls.h uClibc.ldso.24/ldso-0.9.24/ldso/powerpc/ld_syscalls.h
--- uClibc/ldso-0.9.24/ldso/powerpc/ld_syscalls.h	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/powerpc/ld_syscalls.h	2003-06-14 20:08:43.000000000 -0500
@@ -0,0 +1,244 @@
+/*
+ * This file contains the system call macros and syscall 
+ * numbers used by the shared library loader.
+ */
+
+#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
+
+/* 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 ? /*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);					\
+}
+
+
diff -urN uClibc/ldso-0.9.24/ldso/powerpc/ld_sysdep.h uClibc.ldso.24/ldso-0.9.24/ldso/powerpc/ld_sysdep.h
--- uClibc/ldso-0.9.24/ldso/powerpc/ld_sysdep.h	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/powerpc/ld_sysdep.h	2003-12-03 17:38:43.000000000 -0600
@@ -0,0 +1,136 @@
+/*
+ * Various assmbly language/system dependent  hacks that are required
+ * so that we can minimize the amount of platform specific code.
+ */
+
+/*
+ * Define this if the system uses RELOCA.
+ */
+#define ELF_USES_RELOCA
+
+/*
+ * 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)
+
+/*
+ * Initialization sequence for a GOT.
+ */
+#define INIT_GOT(GOT_BASE,MODULE)  _dl_init_got(GOT_BASE,MODULE)
+
+/* Stuff for the PLT.  */
+#define PLT_INITIAL_ENTRY_WORDS 18
+#define PLT_LONGBRANCH_ENTRY_WORDS 0
+#define PLT_TRAMPOLINE_ENTRY_WORDS 6
+#define PLT_DOUBLE_SIZE (1<<13)
+#define PLT_ENTRY_START_WORDS(entry_number) \
+  (PLT_INITIAL_ENTRY_WORDS + (entry_number)*2				\
+   + ((entry_number) > PLT_DOUBLE_SIZE					\
+      ? ((entry_number) - PLT_DOUBLE_SIZE)*2				\
+      : 0))
+#define PLT_DATA_START_WORDS(num_entries) PLT_ENTRY_START_WORDS(num_entries)
+
+/* Macros to build PowerPC opcode words.  */
+#define OPCODE_ADDI(rd,ra,simm) \
+  (0x38000000 | (rd) << 21 | (ra) << 16 | ((simm) & 0xffff))
+#define OPCODE_ADDIS(rd,ra,simm) \
+  (0x3c000000 | (rd) << 21 | (ra) << 16 | ((simm) & 0xffff))
+#define OPCODE_ADD(rd,ra,rb) \
+  (0x7c000214 | (rd) << 21 | (ra) << 16 | (rb) << 11)
+#define OPCODE_B(target) (0x48000000 | ((target) & 0x03fffffc))
+#define OPCODE_BA(target) (0x48000002 | ((target) & 0x03fffffc))
+#define OPCODE_BCTR() 0x4e800420
+#define OPCODE_LWZ(rd,d,ra) \
+  (0x80000000 | (rd) << 21 | (ra) << 16 | ((d) & 0xffff))
+#define OPCODE_LWZU(rd,d,ra) \
+  (0x84000000 | (rd) << 21 | (ra) << 16 | ((d) & 0xffff))
+#define OPCODE_MTCTR(rd) (0x7C0903A6 | (rd) << 21)
+#define OPCODE_RLWINM(ra,rs,sh,mb,me) \
+  (0x54000000 | (rs) << 21 | (ra) << 16 | (sh) << 11 | (mb) << 6 | (me) << 1)
+
+#define OPCODE_LI(rd,simm)    OPCODE_ADDI(rd,0,simm)
+#define OPCODE_ADDIS_HI(rd,ra,value) \
+  OPCODE_ADDIS(rd,ra,((value) + 0x8000) >> 16)
+#define OPCODE_LIS_HI(rd,value) OPCODE_ADDIS_HI(rd,0,value)
+#define OPCODE_SLWI(ra,rs,sh) OPCODE_RLWINM(ra,rs,sh,0,31-sh)
+
+
+#define PPC_DCBST(where) asm volatile ("dcbst 0,%0" : : "r"(where) : "memory")
+#define PPC_SYNC asm volatile ("sync" : : : "memory")
+#define PPC_ISYNC asm volatile ("sync; isync" : : : "memory")
+#define PPC_ICBI(where) asm volatile ("icbi 0,%0" : : "r"(where) : "memory")
+#define PPC_DIE asm volatile ("tweq 0,0")
+
+/*
+ * Here is a macro to perform a relocation.  This is only used when
+ * bootstrapping the dynamic loader.  RELP is the relocation that we
+ * are performing, REL is the pointer to the address we are relocating.
+ * SYMBOL is the symbol involved in the relocation, and LOAD is the
+ * load address.
+ */
+// finaladdr = LOAD ?
+#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD) \
+	{int type=ELF32_R_TYPE((RELP)->r_info);		\
+	if(type==R_PPC_NONE){				\
+	}else if(type==R_PPC_ADDR32){			\
+		*REL += (SYMBOL);			\
+	}else if(type==R_PPC_RELATIVE){			\
+		*REL = (Elf32_Word)(LOAD) + (RELP)->r_addend;		\
+	}else if(type==R_PPC_REL24){			\
+		Elf32_Sword delta = (Elf32_Word)(SYMBOL) - (Elf32_Word)(REL);	\
+		*REL &= 0xfc000003;			\
+		*REL |= (delta & 0x03fffffc);		\
+	}else if(type==R_PPC_JMP_SLOT){			\
+		Elf32_Sword delta = (Elf32_Word)(SYMBOL) - (Elf32_Word)(REL);	\
+		/*if (delta << 6 >> 6 != delta)_dl_exit(99);*/	\
+		*REL = OPCODE_B(delta);			\
+	}else{						\
+	  _dl_exit(100+ELF32_R_TYPE((RELP)->r_info));	\
+	}						\
+	if(type!=R_PPC_NONE){				\
+		PPC_DCBST(REL); PPC_SYNC; PPC_ICBI(REL);\
+	}						\
+	}
+
+/*
+ * 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.
+ */
+
+/* hgb@ifi.uio.no:
+ * Adding a clobber list consisting of r0 for %1.  addi on PowerPC
+ * takes a register as the second argument, but if the register is
+ * r0, the value 0 is used instead.  If r0 is used here, the stack
+ * pointer (r1) will be zeroed, and the dynamically linked
+ * application will seg.fault immediatly when receiving control.
+ */
+#define START()		\
+	__asm__ volatile ( \
+		    "addi 1,%1,0\n\t" \
+		    "mtlr %0\n\t" \
+		    "blrl\n\t"	\
+		    : : "r" (_dl_elf_main), "r" (args) \
+		    : "r0")
+
+
+/* Here we define the magic numbers that this dynamic loader should accept */
+
+#define MAGIC1 EM_PPC
+#undef  MAGIC2
+/* Used for error messages */
+#define ELF_TARGET "powerpc"
+
+struct elf_resolve;
+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
+#define OFFS_ALIGN 0x7ffff000
diff -urN uClibc/ldso-0.9.24/ldso/powerpc/resolve.S uClibc.ldso.24/ldso-0.9.24/ldso/powerpc/resolve.S
--- uClibc/ldso-0.9.24/ldso/powerpc/resolve.S	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/powerpc/resolve.S	2001-07-12 05:14:09.000000000 -0500
@@ -0,0 +1,82 @@
+/*
+ * Stolen from glibc-2.2.2 by David Schleef <ds@schleef.org>
+ */
+
+.text
+.align 4
+
+.globl _dl_linux_resolver
+
+.globl _dl_linux_resolve
+.type	_dl_linux_resolve,@function
+
+_dl_linux_resolve:
+// We need to save the registers used to pass parameters, and register 0,
+// which is used by _mcount; the registers are saved in a stack frame.
+	stwu 1,-64(1)
+	stw 0,12(1)
+	stw 3,16(1)
+	stw 4,20(1)
+// The code that calls this has put parameters for 'fixup' in r12 and r11.
+	mr 3,12
+	stw 5,24(1)
+	mr 4,11
+	stw 6,28(1)
+	mflr 0
+// We also need to save some of the condition register fields.
+	stw 7,32(1)
+	stw 0,48(1)
+	stw 8,36(1)
+	mfcr 0
+	stw 9,40(1)
+	stw 10,44(1)
+	stw 0,8(1)
+	bl _dl_linux_resolver@local
+// 'fixup' returns the address we want to branch to.
+	mtctr 3
+// Put the registers back...
+	lwz 0,48(1)
+	lwz 10,44(1)
+	lwz 9,40(1)
+	mtlr 0
+	lwz 8,36(1)
+	lwz 0,8(1)
+	lwz 7,32(1)
+	lwz 6,28(1)
+	mtcrf 0xFF,0
+	lwz 5,24(1)
+	lwz 4,20(1)
+	lwz 3,16(1)
+	lwz 0,12(1)
+// ...unwind the stack frame, and jump to the PLT entry we updated.
+	addi 1,1,64
+	bctr
+
+.LFE2:
+	.size _dl_linux_resolve,.LFE2-_dl_linux_resolve
+
+#if 0
+
+	pusha				/* preserve all regs */
+	lea	0x20(%esp),%eax		/* eax = tpnt and reloc_entry params */
+	pushl	4(%eax)			/* push copy of reloc_entry param */
+	pushl	(%eax)			/* push copy of tpnt param */
+					 
+#ifdef __PIC__
+	call	.L24
+.L24:
+	popl	%ebx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-.L24],%ebx
+	movl _dl_linux_resolver@GOT(%ebx),%ebx	/* eax = resolved func */
+	call *%ebx
+#else
+	call _dl_linux_resolver
+#endif
+	movl	%eax,0x28(%esp)		/* store func addr over original
+					 * tpnt param */
+	addl	$0x8,%esp		/* remove copy parameters */
+	popa				/* restore regs */
+	ret	$4			/* jump to func removing original
+					 * reloc_entry param from stack */
+#endif
+
diff -urN uClibc/ldso-0.9.24/ldso/readelflib1.c uClibc.ldso.24/ldso-0.9.24/ldso/readelflib1.c
--- uClibc/ldso-0.9.24/ldso/readelflib1.c	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/readelflib1.c	2003-12-05 14:24:26.000000000 -0600
@@ -0,0 +1,971 @@
+/* vi: set sw=4 ts=4: */
+/* Program to load an ELF binary on a linux system, and run it
+ * after resolving ELF shared library symbols
+ *
+ * Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald, 
+ *				David Engel, Hongjiu Lu and Mitch D'Souza
+ * Copyright (C) 2001-2003, Erik Andersen
+ *
+ * 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.
+ */
+
+
+/* This file contains the helper routines to load an ELF sharable
+   library into memory and add the symbol table info to the chain. */
+
+#ifdef USE_CACHE
+
+static caddr_t _dl_cache_addr = NULL;
+static size_t _dl_cache_size = 0;
+
+int _dl_map_cache(void)
+{
+	int fd;
+	struct stat st;
+	header_t *header;
+	libentry_t *libent;
+	int i, strtabsize;
+
+	if (_dl_cache_addr == (caddr_t) - 1)
+		return -1;
+	else if (_dl_cache_addr != NULL)
+		return 0;
+
+	if (_dl_stat(LDSO_CACHE, &st)
+		|| (fd = _dl_open(LDSO_CACHE, O_RDONLY)) < 0) {
+		_dl_dprintf(2, "%s: can't open cache '%s'\n", _dl_progname, LDSO_CACHE);
+		_dl_cache_addr = (caddr_t) - 1;	/* so we won't try again */
+		return -1;
+	}
+
+	_dl_cache_size = st.st_size;
+	_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);
+		return -1;
+	}
+
+	header = (header_t *) _dl_cache_addr;
+
+	if (_dl_cache_size < sizeof(header_t) ||
+		_dl_memcmp(header->magic, LDSO_CACHE_MAGIC, LDSO_CACHE_MAGIC_LEN)
+		|| _dl_memcmp(header->version, LDSO_CACHE_VER, LDSO_CACHE_VER_LEN)
+		|| _dl_cache_size <
+		(sizeof(header_t) + header->nlibs * sizeof(libentry_t))
+		|| _dl_cache_addr[_dl_cache_size - 1] != '\0') 
+	{
+		_dl_dprintf(2, "%s: cache '%s' is corrupt\n", _dl_progname, 
+			LDSO_CACHE);
+		goto fail;
+	}
+
+	strtabsize = _dl_cache_size - sizeof(header_t) -
+		header->nlibs * sizeof(libentry_t);
+	libent = (libentry_t *) & header[1];
+
+	for (i = 0; i < header->nlibs; i++) {
+		if (libent[i].sooffset >= strtabsize || 
+			libent[i].liboffset >= strtabsize) 
+		{
+			_dl_dprintf(2, "%s: cache '%s' is corrupt\n", _dl_progname, LDSO_CACHE);
+			goto fail;
+		}
+	}
+
+	return 0;
+
+  fail:
+	_dl_munmap(_dl_cache_addr, _dl_cache_size);
+	_dl_cache_addr = (caddr_t) - 1;
+	return -1;
+}
+
+int _dl_unmap_cache(void)
+{
+	if (_dl_cache_addr == NULL || _dl_cache_addr == (caddr_t) - 1)
+		return -1;
+
+#if 1
+	_dl_munmap(_dl_cache_addr, _dl_cache_size);
+	_dl_cache_addr = NULL;
+#endif
+
+	return 0;
+}
+
+#endif
+
+/* This function's behavior must exactly match that 
+ * in uClibc/ldso/util/ldd.c */
+static struct elf_resolve * 
+search_for_named_library(const char *name, int secure, const char *path_list,
+	struct dyn_elf **rpnt)
+{
+	int i, count = 1;
+	char *path, *path_n;
+	char mylibname[2050];
+	struct elf_resolve *tpnt1;
+	
+	if (path_list==NULL)
+		return NULL;
+
+	/* We need a writable copy of this string */
+	path = _dl_strdup(path_list);
+	if (!path) {
+		_dl_dprintf(2, "Out of memory!\n");
+		_dl_exit(0);
+	}
+	
+
+	/* Unlike ldd.c, don't bother to eliminate double //s */
+
+
+	/* Replace colons with zeros in path_list and count them */
+	for(i=_dl_strlen(path); i > 0; i--) {
+		if (path[i]==':') {
+			path[i]=0;
+			count++;
+		}
+	}
+
+	path_n = path;
+	for (i = 0; i < count; i++) {
+		_dl_strcpy(mylibname, path_n); 
+		_dl_strcat(mylibname, "/"); 
+		_dl_strcat(mylibname, name);
+		if ((tpnt1 = _dl_load_elf_shared_library(secure, rpnt, mylibname)) != NULL)
+		{
+			return tpnt1;
+		}
+		path_n += (_dl_strlen(path_n) + 1);
+	}
+	return NULL;
+}
+
+/* Check if the named library is already loaded... */
+struct elf_resolve *_dl_check_if_named_library_is_loaded(const char *full_libname)
+{
+	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;
+
+#if defined (__SUPPORT_LD_DEBUG__)
+	if(_dl_debug) 
+		_dl_dprintf(_dl_debug_file, "Checking if '%s' is already loaded\n", full_libname);
+#endif
+	/* 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 (!_dl_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;
+extern char *_dl_ldsopath;
+
+struct elf_resolve *_dl_load_shared_library(int secure, struct dyn_elf **rpnt,
+	struct elf_resolve *tpnt, char *full_libname)
+{
+	char *pnt, *pnt1;
+	struct elf_resolve *tpnt1;
+	char *libname;
+
+	_dl_internal_error_number = 0;
+	libname = 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)
+		goto goof;
+
+	/* Skip over any initial initial './' and '/' stuff to 
+	 * get the short form libname with no path garbage */ 
+	pnt1 = _dl_strrchr(libname, '/');
+	if (pnt1) {
+		libname = pnt1 + 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))!=NULL)
+		return tpnt1;
+
+#if defined (__SUPPORT_LD_DEBUG__)
+	if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tfind library='%s'; searching\n", libname);
+#endif
+	/* If the filename has any '/', try it straight and leave it at that.
+	   For IBCS2 compatibility under linux, we substitute the string 
+	   /usr/i486-sysv4/lib for /usr/lib in library names. */
+
+	if (libname != full_libname) {
+#if defined (__SUPPORT_LD_DEBUG__)
+		if(_dl_debug) _dl_dprintf(_dl_debug_file, "\ttrying file='%s'\n", full_libname);
+#endif
+		tpnt1 = _dl_load_elf_shared_library(secure, rpnt, full_libname);
+		if (tpnt1) {
+			return tpnt1;
+		}
+		//goto goof;
+	}
+
+	/*
+	 * The ABI specifies that RPATH is searched before LD_*_PATH or
+	 * the default path of /usr/lib.  Check in rpath directories.
+	 */
+	for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
+		if (tpnt->libtype == elf_executable) {
+			pnt = (char *) tpnt->dynamic_info[DT_RPATH];
+			if (pnt) {
+				pnt += (unsigned long) tpnt->loadaddr + tpnt->dynamic_info[DT_STRTAB];
+#if defined (__SUPPORT_LD_DEBUG__)
+				if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tsearching RPATH='%s'\n", pnt);
+#endif
+				if ((tpnt1 = search_for_named_library(libname, secure, pnt, rpnt)) != NULL) 
+				{
+				    return tpnt1;
+				}
+			}
+		}
+	}
+
+	/* Check in LD_{ELF_}LIBRARY_PATH, if specified and allowed */
+	if (_dl_library_path) {
+#if defined (__SUPPORT_LD_DEBUG__)
+		if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tsearching LD_LIBRARY_PATH='%s'\n", _dl_library_path);
+#endif
+	    if ((tpnt1 = search_for_named_library(libname, secure, _dl_library_path, rpnt)) != NULL) 
+	    {
+		return tpnt1;
+	    }
+	}
+
+	/*
+	 * Where should the cache be searched?  There is no such concept in the
+	 * ABI, so we have some flexibility here.  For now, search it before
+	 * the hard coded paths that follow (i.e before /lib and /usr/lib).
+	 */
+#ifdef USE_CACHE
+	if (_dl_cache_addr != NULL && _dl_cache_addr != (caddr_t) - 1) {
+		int i;
+		header_t *header = (header_t *) _dl_cache_addr;
+		libentry_t *libent = (libentry_t *) & header[1];
+		char *strs = (char *) &libent[header->nlibs];
+
+#if defined (__SUPPORT_LD_DEBUG__)
+		if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tsearching cache='%s'\n", LDSO_CACHE);
+#endif
+		for (i = 0; i < header->nlibs; i++) {
+			if ((libent[i].flags == LIB_ELF ||
+				 libent[i].flags == LIB_ELF_LIBC5) &&
+				_dl_strcmp(libname, strs + libent[i].sooffset) == 0 &&
+				(tpnt1 = _dl_load_elf_shared_library(secure, 
+				     rpnt, strs + libent[i].liboffset)))
+				return tpnt1;
+		}
+	}
+#endif
+
+	/* Look for libraries wherever the shared library loader
+	 * was installed */
+#if defined (__SUPPORT_LD_DEBUG__)
+		if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tsearching ldso dir='%s'\n", _dl_ldsopath);
+#endif
+	if ((tpnt1 = search_for_named_library(libname, secure, _dl_ldsopath, rpnt)) != NULL) 
+	{
+	    return tpnt1;
+	}
+
+
+	/* Lastly, search the standard list of paths for the library.
+	   This list must exactly match the list in uClibc/ldso/util/ldd.c */
+#if defined (__SUPPORT_LD_DEBUG__)
+	if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tsearching full lib path list\n");
+#endif
+	if ((tpnt1 = search_for_named_library(libname, secure, 
+			UCLIBC_RUNTIME_PREFIX "usr/X11R6/lib:"
+			UCLIBC_RUNTIME_PREFIX "usr/lib:"
+			UCLIBC_RUNTIME_PREFIX "lib:"
+			"/usr/lib:"
+			"/lib", rpnt)
+		    ) != NULL) 
+	{
+	    return tpnt1;
+	}
+
+goof:
+	/* Well, we shot our wad on that one.  All we can do now is punt */
+	if (_dl_internal_error_number)
+		_dl_error_number = _dl_internal_error_number;
+	else
+		_dl_error_number = LD_ERROR_NOFILE;
+#if defined (__SUPPORT_LD_DEBUG__)
+	if(_dl_debug) _dl_dprintf(2, "Bummer: could not find '%s'!\n", libname);
+#endif
+	return NULL;
+}
+
+
+/*
+ * Read one ELF library into memory, mmap it into the correct locations and
+ * add the symbol info to the symbol chain.  Perform any relocations that
+ * are required.
+ */
+
+struct elf_resolve *_dl_load_elf_shared_library(int secure,
+	struct dyn_elf **rpnt, char *libname)
+{
+	ElfW(Ehdr) *epnt;
+	unsigned long dynamic_addr = 0;
+	unsigned long dynamic_size = 0;
+	Elf32_Dyn *dpnt;
+	struct elf_resolve *tpnt;
+	ElfW(Phdr) *ppnt;
+	char *status, *header;
+	unsigned long dynamic_info[24];
+	unsigned long *lpnt;
+	unsigned long libaddr;
+	unsigned long minvma = 0xffffffff, maxvma = 0;
+	int i, flags, piclib, infile;
+
+	/* 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;
+#if defined (__SUPPORT_LD_DEBUG__)
+		if(_dl_debug) _dl_dprintf(2, "file='%s';  already loaded\n", libname);
+#endif
+		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;
+	}
+
+	libaddr = 0;
+	infile = _dl_open(libname, O_RDONLY);
+	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;
+	}
+
+	 header = _dl_mmap((void *) 0, 4096, PROT_READ | PROT_WRITE,
+	 	MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
+	if (_dl_mmap_check_error(header)) {
+		_dl_dprintf(2, "%s: can't map '%s'\n", _dl_progname, libname);
+		_dl_internal_error_number = LD_ERROR_MMAP_FAILED;
+		_dl_close(infile);
+		return NULL;
+	};
+        
+	_dl_read(infile, header, 4096);
+	epnt = (ElfW(Ehdr) *) (intptr_t) header;
+	if (epnt->e_ident[0] != 0x7f ||
+		epnt->e_ident[1] != 'E' || 
+		epnt->e_ident[2] != 'L' || 
+		epnt->e_ident[3] != 'F') 
+	{
+		_dl_dprintf(2, "%s: '%s' is not an ELF file\n", _dl_progname,
+					 libname);
+		_dl_internal_error_number = LD_ERROR_NOTELF;
+		_dl_close(infile);
+		_dl_munmap(header, 4096);
+		return NULL;
+	};
+
+	if ((epnt->e_type != ET_DYN) || (epnt->e_machine != MAGIC1 
+#ifdef MAGIC2
+		    && epnt->e_machine != MAGIC2
+#endif
+		)) 
+	{
+		_dl_internal_error_number = 
+		    (epnt->e_type != ET_DYN ? LD_ERROR_NOTDYN : LD_ERROR_NOTMAGIC);
+		_dl_dprintf(2, "%s: '%s' is not an ELF executable for " ELF_TARGET 
+			"\n", _dl_progname, libname);
+		_dl_close(infile);
+		_dl_munmap(header, 4096);
+		return NULL;
+	};
+
+	ppnt = (ElfW(Phdr) *)(intptr_t) & header[epnt->e_phoff];
+
+	piclib = 1;
+	for (i = 0; i < epnt->e_phnum; i++) {
+
+		if (ppnt->p_type == PT_DYNAMIC) {
+			if (dynamic_addr)
+				_dl_dprintf(2, "%s: '%s' has more than one dynamic section\n", 
+					_dl_progname, libname);
+			dynamic_addr = ppnt->p_vaddr;
+			dynamic_size = ppnt->p_filesz;
+		};
+
+		if (ppnt->p_type == PT_LOAD) {
+			/* See if this is a PIC library. */
+			if (i == 0 && ppnt->p_vaddr > 0x1000000) {
+				piclib = 0;
+				minvma = ppnt->p_vaddr;
+			}
+			if (piclib && ppnt->p_vaddr < minvma) {
+				minvma = ppnt->p_vaddr;
+			}
+			if (((unsigned long) ppnt->p_vaddr + ppnt->p_memsz) > maxvma) {
+				maxvma = ppnt->p_vaddr + ppnt->p_memsz;
+			}
+		}
+		ppnt++;
+	};
+
+	maxvma = (maxvma + ADDR_ALIGN) & ~ADDR_ALIGN;
+	minvma = minvma & ~0xffffU;
+
+	flags = MAP_PRIVATE /*| MAP_DENYWRITE */ ;
+	if (!piclib)
+		flags |= MAP_FIXED;
+
+	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_internal_error_number = LD_ERROR_MMAP_FAILED;
+		_dl_close(infile);
+		_dl_munmap(header, 4096);
+		return NULL;
+	};
+	libaddr = (unsigned long) status;
+	flags |= MAP_FIXED;
+
+	/* Get the memory to store the library */
+	ppnt = (ElfW(Phdr) *)(intptr_t) & header[epnt->e_phoff];
+
+	for (i = 0; i < epnt->e_phnum; i++) {
+		if (ppnt->p_type == PT_LOAD) {
+
+			/* See if this is a PIC library. */
+			if (i == 0 && ppnt->p_vaddr > 0x1000000) {
+				piclib = 0;
+				/* flags |= MAP_FIXED; */
+			}
+
+
+
+			if (ppnt->p_flags & PF_W) {
+				unsigned long map_size;
+				char *cpnt;
+
+				status = (char *) _dl_mmap((char *) ((piclib ? libaddr : 0) + 
+					(ppnt->p_vaddr & PAGE_ALIGN)), (ppnt->p_vaddr & ADDR_ALIGN) 
+					+ 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_internal_error_number = LD_ERROR_MMAP_FAILED;
+					_dl_munmap((char *) libaddr, maxvma - minvma);
+					_dl_close(infile);
+					_dl_munmap(header, 4096);
+					return NULL;
+				};
+
+				/* Pad the last page with zeroes. */
+				cpnt = (char *) (status + (ppnt->p_vaddr & ADDR_ALIGN) +
+							  ppnt->p_filesz);
+				while (((unsigned long) cpnt) & ADDR_ALIGN)
+					*cpnt++ = 0;
+
+				/* I am not quite sure if this is completely
+				 * correct to do or not, but the basic way that
+				 * we handle bss segments is that we mmap
+				 * /dev/zero if there are any pages left over
+				 * that are not mapped as part of the file */
+
+				map_size = (ppnt->p_vaddr + ppnt->p_filesz + ADDR_ALIGN) & PAGE_ALIGN;
+
+				if (map_size < ppnt->p_vaddr + ppnt->p_memsz)
+					status = (char *) _dl_mmap((char *) map_size + 
+						(piclib ? libaddr : 0), 
+						ppnt->p_vaddr + ppnt->p_memsz - map_size, 
+						LXFLAGS(ppnt->p_flags), flags | MAP_ANONYMOUS, -1, 0);
+			} else
+				status = (char *) _dl_mmap((char *) (ppnt->p_vaddr & PAGE_ALIGN) 
+					+ (piclib ? libaddr : 0), (ppnt->p_vaddr & ADDR_ALIGN) + 
+					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_internal_error_number = LD_ERROR_MMAP_FAILED;
+				_dl_munmap((char *) libaddr, maxvma - minvma);
+				_dl_close(infile);
+				_dl_munmap(header, 4096);
+				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 */
+	if (piclib) {
+		dynamic_addr += (unsigned long) libaddr;
+	}
+
+	/* 
+	 * OK, the ELF library is now loaded into VM in the correct locations
+	 * The next step is to go through and do the dynamic linking (if needed).
+	 */
+
+	/* Start by scanning the dynamic section to get all of the pointers */
+
+	if (!dynamic_addr) {
+		_dl_internal_error_number = LD_ERROR_NODYNAMIC;
+		_dl_dprintf(2, "%s: '%s' is missing a dynamic section\n", 
+			_dl_progname, libname);
+			_dl_munmap(header, 4096);
+		return NULL;
+	}
+
+	dpnt = (Elf32_Dyn *) dynamic_addr;
+
+	dynamic_size = dynamic_size / sizeof(Elf32_Dyn);
+	_dl_memset(dynamic_info, 0, sizeof(dynamic_info));
+
+#if defined(__mips__)
+	{
+		
+		int indx = 1;
+		Elf32_Dyn *dpnt = (Elf32_Dyn *) dynamic_addr;
+
+		while(dpnt->d_tag) {
+			dpnt++;
+			indx++;
+		}
+		dynamic_size = indx;
+	}
+#endif
+
+	{
+		unsigned long indx;
+
+		for (indx = 0; indx < dynamic_size; indx++) 
+		{
+			if (dpnt->d_tag > DT_JMPREL) {
+				dpnt++;
+				continue;
+			}
+			dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
+			if (dpnt->d_tag == DT_TEXTREL)
+				dynamic_info[DT_TEXTREL] = 1;
+			dpnt++;
+		};
+	}
+
+	/* If the TEXTREL is set, this means that we need to make the pages
+	   writable before we perform relocations.  Do this now. They get set
+	   back again later. */
+
+	if (dynamic_info[DT_TEXTREL]) {
+#ifndef FORCE_SHAREABLE_TEXT_SEGMENTS
+		ppnt = (ElfW(Phdr) *)(intptr_t) & header[epnt->e_phoff];
+		for (i = 0; i < epnt->e_phnum; i++, ppnt++) {
+			if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
+				_dl_mprotect((void *) ((piclib ? libaddr : 0) + 
+					    (ppnt->p_vaddr & PAGE_ALIGN)), 
+					(ppnt->p_vaddr & ADDR_ALIGN) + (unsigned long) ppnt->p_filesz, 
+					PROT_READ | PROT_WRITE | PROT_EXEC);
+		}
+#else
+		_dl_dprintf(_dl_debug_file, "Can't modify %s's text section. Use GCC option -fPIC for shared objects, please.\n",libname);
+		_dl_exit(1);
+#endif		
+	}
+
+	tpnt = _dl_add_elf_hash_table(libname, (char *) libaddr, dynamic_info, 
+		dynamic_addr, dynamic_size);
+
+	tpnt->ppnt = (ElfW(Phdr) *)(intptr_t) (tpnt->loadaddr + epnt->e_phoff);
+	tpnt->n_phent = epnt->e_phnum;
+
+	/*
+	 * Add this object into the symbol chain
+	 */
+	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;
+
+	/*
+	 * OK, the next thing we need to do is to insert the dynamic linker into
+	 * the proper entry in the GOT so that the PLT symbols can be properly
+	 * resolved. 
+	 */
+
+	lpnt = (unsigned long *) dynamic_info[DT_PLTGOT];
+
+	if (lpnt) {
+		lpnt = (unsigned long *) (dynamic_info[DT_PLTGOT] +
+			((int) libaddr));
+		INIT_GOT(lpnt, tpnt);
+	};
+
+#if defined (__SUPPORT_LD_DEBUG__)
+	if(_dl_debug) {
+		_dl_dprintf(2, "\n\tfile='%s';  generating link map\n", libname);
+		_dl_dprintf(2, "\t\tdynamic: %x  base: %x   size: %x\n", 
+				dynamic_addr, libaddr, dynamic_size);
+		_dl_dprintf(2, "\t\t  entry: %x  phdr: %x  phnum: %d\n\n", 
+				epnt->e_entry + libaddr, tpnt->ppnt, tpnt->n_phent);
+
+	}
+#endif
+	_dl_munmap(header, 4096);
+
+	return tpnt;
+}
+
+/* Ugly, ugly.  Some versions of the SVr4 linker fail to generate COPY
+   relocations for global variables that are present both in the image and
+   the shared library.  Go through and do it manually.  If the images
+   are guaranteed to be generated by a trustworthy linker, then this
+   step can be skipped. */
+
+int _dl_copy_fixups(struct dyn_elf *rpnt)
+{
+	int goof = 0;
+	struct elf_resolve *tpnt;
+
+	if (rpnt->next)
+		goof += _dl_copy_fixups(rpnt->next);
+	else
+		return 0;
+
+	tpnt = rpnt->dyn;
+
+	if (tpnt->init_flag & COPY_RELOCS_DONE)
+		return goof;
+	tpnt->init_flag |= COPY_RELOCS_DONE;
+
+#if defined (__SUPPORT_LD_DEBUG__)
+	if(_dl_debug) _dl_dprintf(_dl_debug_file,"\nrelocation copy fixups: %s", tpnt->libname);	
+#endif    
+
+#ifdef ELF_USES_RELOCA
+	goof += _dl_parse_copy_information(rpnt, 
+		tpnt->dynamic_info[DT_RELA], tpnt->dynamic_info[DT_RELASZ], 0);
+
+#else
+	goof += _dl_parse_copy_information(rpnt, tpnt->dynamic_info[DT_REL], 
+		tpnt->dynamic_info[DT_RELSZ], 0);
+
+#endif
+#if defined (__SUPPORT_LD_DEBUG__)
+	if(_dl_debug) _dl_dprintf(_dl_debug_file,"\nrelocation copy fixups: %s; finished\n\n", tpnt->libname);	
+#endif    
+	return goof;
+}
+
+/* Minimal printf which handles only %s, %d, and %x */
+void _dl_dprintf(int fd, const char *fmt, ...)
+{
+	int num;
+	va_list args;
+	char *start, *ptr, *string;
+	static char *buf;
+
+	buf = _dl_mmap((void *) 0, 4096, PROT_READ | PROT_WRITE,
+		MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
+	if (_dl_mmap_check_error(buf)) {
+			_dl_dprintf(2, "%s: mmap of a spare page failed!\n", _dl_progname);
+			_dl_exit(20);
+	}
+
+	start = ptr = buf;
+
+	if (!fmt)
+		return;
+
+	if (_dl_strlen(fmt) >= (sizeof(buf) - 1))
+		_dl_write(fd, "(overflow)\n", 10);
+
+	_dl_strcpy(buf, fmt);
+	va_start(args, fmt);
+
+	while (start) {
+		while (*ptr != '%' && *ptr) {
+			ptr++;
+		}
+
+		if (*ptr == '%') {
+			*ptr++ = '\0';
+			_dl_write(fd, start, _dl_strlen(start));
+
+			switch (*ptr++) {
+			case 's':
+				string = va_arg(args, char *);
+
+				if (!string)
+					_dl_write(fd, "(null)", 6);
+				else
+					_dl_write(fd, string, _dl_strlen(string));
+				break;
+
+			case 'i':
+			case 'd':
+			{
+				char tmp[22];
+				num = va_arg(args, int);
+
+				string = _dl_simple_ltoa(tmp, num);
+				_dl_write(fd, string, _dl_strlen(string));
+				break;
+			}
+			case 'x':
+			case 'X':
+			{
+				char tmp[22];
+				num = va_arg(args, int);
+
+				string = _dl_simple_ltoahex(tmp, num);
+				_dl_write(fd, string, _dl_strlen(string));
+				break;
+			}
+			default:
+				_dl_write(fd, "(null)", 6);
+				break;
+			}
+
+			start = ptr;
+		} else {
+			_dl_write(fd, start, _dl_strlen(start));
+			start = NULL;
+		}
+	}
+	_dl_munmap(buf, 4096);
+	return;
+}
+
+char *_dl_strdup(const char *string)
+{
+	char *retval;
+	int len;
+
+	len = _dl_strlen(string);
+	retval = _dl_malloc(len + 1);
+	_dl_strcpy(retval, string);
+	return retval;
+}
+
+void *(*_dl_malloc_function) (size_t size) = NULL;
+void *_dl_malloc(int size)
+{
+	void *retval;
+
+#if 0
+#ifdef __SUPPORT_LD_DEBUG_EARLY__
+	_dl_dprintf(2, "malloc: request for %d bytes\n", size);
+#endif
+#endif
+
+	if (_dl_malloc_function)
+		return (*_dl_malloc_function) (size);
+
+	if (_dl_malloc_addr - _dl_mmap_zero + size > 4096) {
+#ifdef __SUPPORT_LD_DEBUG_EARLY__
+		_dl_dprintf(2, "malloc: mmapping more memory\n");
+#endif
+		_dl_mmap_zero = _dl_malloc_addr = _dl_mmap((void *) 0, size, 
+				PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
+		if (_dl_mmap_check_error(_dl_mmap_zero)) {
+			_dl_dprintf(2, "%s: mmap of a spare page failed!\n", _dl_progname);
+			_dl_exit(20);
+		}
+	}
+	retval = _dl_malloc_addr;
+	_dl_malloc_addr += size;
+
+	/*
+	 * Align memory to 4 byte boundary.  Some platforms require this, others
+	 * simply get better performance.
+	 */
+	_dl_malloc_addr = (char *) (((unsigned long) _dl_malloc_addr + 3) & ~(3));
+	return retval;
+}
+
+int _dl_fixup(struct elf_resolve *tpnt, int flag)
+{
+	int goof = 0;
+
+	if (tpnt->next)
+		goof += _dl_fixup(tpnt->next, flag);
+#if defined (__SUPPORT_LD_DEBUG__)
+	if(_dl_debug) _dl_dprintf(_dl_debug_file,"\nrelocation processing: %s", tpnt->libname);	
+#endif    
+	
+	if (tpnt->dynamic_info[DT_REL]) {
+#ifdef ELF_USES_RELOCA
+#if defined (__SUPPORT_LD_DEBUG__)
+		if(_dl_debug) _dl_dprintf(2, "%s: can't handle REL relocation records\n", _dl_progname);
+#endif    
+		goof++;
+		return goof;
+#else
+		if (tpnt->init_flag & RELOCS_DONE)
+			return goof;
+		tpnt->init_flag |= RELOCS_DONE;
+		goof += _dl_parse_relocation_information(tpnt, 
+				tpnt->dynamic_info[DT_REL], 
+				tpnt->dynamic_info[DT_RELSZ], 0);
+#endif
+	}
+	if (tpnt->dynamic_info[DT_RELA]) {
+#ifndef ELF_USES_RELOCA
+#if defined (__SUPPORT_LD_DEBUG__)
+		if(_dl_debug) _dl_dprintf(2, "%s: can't handle RELA relocation records\n", _dl_progname);
+#endif    
+		goof++;
+		return goof;
+#else
+		if (tpnt->init_flag & RELOCS_DONE)
+			return goof;
+		tpnt->init_flag |= RELOCS_DONE;
+		goof += _dl_parse_relocation_information(tpnt, 
+				tpnt->dynamic_info[DT_RELA], 
+				tpnt->dynamic_info[DT_RELASZ], 0);
+#endif
+	}
+	if (tpnt->dynamic_info[DT_JMPREL]) {
+		if (tpnt->init_flag & JMP_RELOCS_DONE)
+			return goof;
+		tpnt->init_flag |= JMP_RELOCS_DONE;
+		if (flag & RTLD_LAZY) {
+			_dl_parse_lazy_relocation_information(tpnt, 
+					tpnt->dynamic_info[DT_JMPREL], 
+					tpnt->dynamic_info [DT_PLTRELSZ], 0);
+		} else {
+			goof += _dl_parse_relocation_information(tpnt, 
+					tpnt->dynamic_info[DT_JMPREL], 
+					tpnt->dynamic_info[DT_PLTRELSZ], 0);
+		}
+	}
+#if defined (__SUPPORT_LD_DEBUG__)
+	if(_dl_debug) {
+		_dl_dprintf(_dl_debug_file,"\nrelocation processing: %s", tpnt->libname);     
+		_dl_dprintf(_dl_debug_file,"; finished\n\n");
+	}
+#endif    
+	return goof;
+}
+
+
diff -urN uClibc/ldso-0.9.24/ldso/sh/boot1_arch.h uClibc.ldso.24/ldso-0.9.24/ldso/sh/boot1_arch.h
--- uClibc/ldso-0.9.24/ldso/sh/boot1_arch.h	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/sh/boot1_arch.h	2002-11-03 08:12:29.000000000 -0600
@@ -0,0 +1,22 @@
+/* Any assmbly language/system dependent hacks needed to setup boot1.c so it
+ * will work as expected and cope with whatever platform specific wierdness is
+ * needed for this architecture.  */
+
+asm("" \
+"	.text\n"			\
+"	.globl	_dl_boot\n"		\
+"_dl_boot:\n"				\
+"	mov	r15, r4\n"		\
+"	mov.l   .L_dl_boot2, r0\n"	\
+"	bsrf    r0\n"			\
+"	add	#4, r4\n"		\
+".jmp_loc:\n"				\
+"	jmp	@r0\n"			\
+"	 mov    #0, r4 	!call _start with arg == 0\n" \
+".L_dl_boot2:\n"			\
+"	.long   _dl_boot2-.jmp_loc\n"	\
+"	.previous\n"			\
+);
+
+#define _dl_boot _dl_boot2
+#define LD_BOOT(X)   static void *  __attribute__ ((unused)) _dl_boot (X)
diff -urN uClibc/ldso-0.9.24/ldso/sh/elfinterp.c uClibc.ldso.24/ldso-0.9.24/ldso/sh/elfinterp.c
--- uClibc/ldso-0.9.24/ldso/sh/elfinterp.c	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/sh/elfinterp.c	2003-09-11 05:26:16.000000000 -0500
@@ -0,0 +1,427 @@
+/* vi: set sw=4 ts=4: */
+/* SuperH ELF shared library loader suppport
+ *
+ * Copyright (C) 2002, Stefan Allius <allius@atecom.com> and 
+ *                     Eddie C. Dost <ecd@atecom.com>
+ *
+ * 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.
+ */
+
+#if defined (__SUPPORT_LD_DEBUG__)
+static const char *_dl_reltypes_tab[] =
+{
+  [0]	"R_SH_NONE",	"R_SH_DIR32",	"R_SH_REL32",	"R_SH_DIR8WPN",
+  [4]	"R_SH_IND12W",	"R_SH_DIR8WPL",	"R_SH_DIR8WPZ",	"R_SH_DIR8BP",
+  [8]	"R_SH_DIR8W",	"R_SH_DIR8L",
+ [25]	"R_SH_SWITCH16","R_SH_SWITCH32","R_SH_USES",
+ [28]	"R_SH_COUNT",	"R_SH_ALIGN",	"R_SH_CODE",	"R_SH_DATA",
+ [32]	"R_SH_LABEL",	"R_SH_SWITCH8",	"R_SH_GNU_VTINHERIT","R_SH_GNU_VTENTRY",
+[160]	"R_SH_GOT32",	"R_SH_PLT32",	"R_SH_COPY",	"R_SH_GLOB_DAT",
+[164]	"R_SH_JMP_SLOT","R_SH_RELATIVE","R_SH_GOTOFF",	"R_SH_GOTPC",
+};
+
+static const char *
+_dl_reltypes(int type)
+{
+  static char buf[22];  
+  const char *str;
+  
+  if (type >= (int)(sizeof (_dl_reltypes_tab)/sizeof(_dl_reltypes_tab[0])) ||
+      NULL == (str = _dl_reltypes_tab[type]))
+  {
+    str =_dl_simple_ltoa( buf, (unsigned long)(type));
+  }
+  return str;
+}
+
+static 
+void debug_sym(Elf32_Sym *symtab,char *strtab,int symtab_index)
+{
+  if(_dl_debug_symbols)
+  {
+    if(symtab_index){
+      _dl_dprintf(_dl_debug_file, "\n%s\tvalue=%x\tsize=%x\tinfo=%x\tother=%x\tshndx=%x",
+		  strtab + symtab[symtab_index].st_name,
+		  symtab[symtab_index].st_value,
+		  symtab[symtab_index].st_size,
+		  symtab[symtab_index].st_info,
+		  symtab[symtab_index].st_other,
+		  symtab[symtab_index].st_shndx);
+    }
+  }
+}
+
+static void debug_reloc(Elf32_Sym *symtab,char *strtab, ELF_RELOC *rpnt)
+{
+  if(_dl_debug_reloc)
+  {
+    int symtab_index;
+    const char *sym;
+    symtab_index = ELF32_R_SYM(rpnt->r_info);
+    sym = symtab_index ? strtab + symtab[symtab_index].st_name : "sym=0x0";
+    
+  if(_dl_debug_symbols)
+	  _dl_dprintf(_dl_debug_file, "\n\t");
+  else
+	  _dl_dprintf(_dl_debug_file, "\n%s\n\t", sym);
+    
+#ifdef ELF_USES_RELOCA
+    _dl_dprintf(_dl_debug_file, "%s\toffset=%x\taddend=%x",
+		_dl_reltypes(ELF32_R_TYPE(rpnt->r_info)),
+		rpnt->r_offset,
+		rpnt->r_addend);
+#else
+    _dl_dprintf(_dl_debug_file, "%s\toffset=%x\n",
+		_dl_reltypes(ELF32_R_TYPE(rpnt->r_info)),
+		rpnt->r_offset);
+#endif
+  }
+}
+#endif
+
+/* Program to load an ELF binary on a linux system, and run it.
+   References to symbols in sharable libraries can be resolved by either
+   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. */
+
+extern int _dl_linux_resolve(void);
+
+unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
+{
+	int reloc_type;
+	ELF_RELOC *this_reloc;
+	char *strtab;
+	Elf32_Sym *symtab;
+	int symtab_index;
+	char *rel_addr;
+	char *new_addr;
+	char **got_addr;
+	unsigned long instr_addr;
+	char *symname;
+
+	rel_addr = (char *) (tpnt->dynamic_info[DT_JMPREL] + tpnt->loadaddr);
+
+	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);
+
+	symtab = (Elf32_Sym *)(intptr_t) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
+	strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
+	symname = strtab + symtab[symtab_index].st_name;
+
+	if (reloc_type != R_SH_JMP_SLOT) {
+	  _dl_dprintf(2, "%s: Incorrect relocation type in jump relocations\n", 
+		       _dl_progname);
+	  _dl_exit(1);
+	}
+	
+	/* Address of jump instruction to fix up */
+	instr_addr = ((unsigned long) this_reloc->r_offset + 
+			(unsigned long) tpnt->loadaddr);
+	got_addr = (char **) instr_addr;
+
+
+	/* Get the address of the GOT entry */
+	new_addr = _dl_find_hash(symname, tpnt->symbol_scope, tpnt, resolver);
+	if (!new_addr) {
+		new_addr = _dl_find_hash(symname, NULL, NULL, resolver);
+		if (new_addr) {
+			return (unsigned long) 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 < 0x20000000)
+	{
+		if (_dl_debug_bindings)
+		{
+			_dl_dprintf(_dl_debug_file, "\nresolve function: %s", symname);
+			if(_dl_debug_detail) _dl_dprintf(_dl_debug_file, 
+					"\n\tpatched %x ==> %x @ %x\n", *got_addr, new_addr, got_addr);
+		}
+	}
+	if (!_dl_debug_nofixups) {
+		*got_addr = new_addr;
+	}
+#else
+	*got_addr = new_addr;
+#endif
+
+	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, Elf32_Sym *symtab, char *strtab))
+{
+	unsigned int i;
+	char *strtab;
+	Elf32_Sym *symtab;
+	ELF_RELOC *rpnt;
+	int symtab_index;
+	/* Now parse the relocation information */
+
+	rpnt = (ELF_RELOC *)(intptr_t) (rel_addr + tpnt->loadaddr);
+	rel_size = rel_size / sizeof(ELF_RELOC);
+
+	symtab = (Elf32_Sym *)(intptr_t) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
+	strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
+
+	  for (i = 0; i < rel_size; i++, rpnt++) {
+	        int res;
+	    
+		symtab_index = ELF32_R_SYM(rpnt->r_info);
+		
+		/* When the dynamic linker bootstrapped itself, it resolved some symbols.
+		   Make sure we do not do them again */
+		if (!symtab_index && tpnt->libtype == program_interpreter)
+			continue;
+		if (symtab_index && tpnt->libtype == program_interpreter &&
+		    _dl_symbol(strtab + symtab[symtab_index].st_name))
+			continue;
+
+#if defined (__SUPPORT_LD_DEBUG__)
+		debug_sym(symtab,strtab,symtab_index);
+		debug_reloc(symtab,strtab,rpnt);
+#endif
+
+		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 (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 if (res >0)
+		{
+			_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,
+	      ELF_RELOC *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 *)(intptr_t) (tpnt->loadaddr + (unsigned long) 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(symname, scope, 
+				(reloc_type == R_SH_JMP_SLOT ? tpnt : NULL), symbolrel);
+
+		/*
+		 * 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_GLOBAL) {
+#if defined (__SUPPORT_LD_DEBUG__)
+			_dl_dprintf(2, "\tglobal symbol '%s' already defined in '%s'\n",
+					symname, tpnt->libname);
+#endif
+			return 0;
+		}
+	}
+
+
+#if defined (__SUPPORT_LD_DEBUG__)
+	old_val = *reloc_addr;
+#endif
+	    switch (reloc_type) {
+		case R_SH_NONE:
+			break;
+		case R_SH_COPY:
+			/* handled later on */
+			break;
+		case R_SH_DIR32:
+		case R_SH_GLOB_DAT:
+		case R_SH_JMP_SLOT:
+			*reloc_addr = symbol_addr + rpnt->r_addend;
+			break;
+		case R_SH_REL32:
+			*reloc_addr = symbol_addr + rpnt->r_addend -
+					(unsigned long) reloc_addr;
+			break;
+		case R_SH_RELATIVE:
+			*reloc_addr = (unsigned long) tpnt->loadaddr + rpnt->r_addend;
+			break;
+		default:
+			return -1; /*call _dl_exit(1) */
+	    }
+#if defined (__SUPPORT_LD_DEBUG__)
+	    if(_dl_debug_reloc && _dl_debug_detail)
+		_dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x", old_val, *reloc_addr, reloc_addr);
+#endif
+
+	return 0;
+}
+ 
+	  
+static int
+_dl_do_lazy_reloc (struct elf_resolve *tpnt, struct dyn_elf *scope,
+		   ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)
+{
+	int reloc_type;
+	unsigned long *reloc_addr;
+#if defined (__SUPPORT_LD_DEBUG__)
+	unsigned long old_val;
+#endif
+	(void)scope;
+	(void)symtab;
+	(void)strtab;
+
+	reloc_addr = (unsigned long *)(intptr_t) (tpnt->loadaddr + (unsigned long) rpnt->r_offset);
+	reloc_type = ELF32_R_TYPE(rpnt->r_info);
+  
+#if defined (__SUPPORT_LD_DEBUG__)
+	old_val = *reloc_addr;
+#endif
+	    switch (reloc_type) {
+	      case R_SH_NONE:
+		break;
+	      case R_SH_JMP_SLOT:
+		*reloc_addr += (unsigned long) tpnt->loadaddr;
+		break;
+	      default:
+	        return -1; /*call _dl_exit(1) */
+	    }
+#if defined (__SUPPORT_LD_DEBUG__)
+	    if(_dl_debug_reloc && _dl_debug_detail)
+		_dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x", old_val, *reloc_addr, reloc_addr);
+#endif
+	return 0;
+	
+}
+
+/* This is done as a separate step, because there are cases where
+   information is first copied and later initialized.  This results in
+   the wrong information being copied.  Someone at Sun was complaining about
+   a bug in the handling of _COPY by SVr4, and this may in fact be what he
+   was talking about.  Sigh. */
+
+/* No, there are cases where the SVr4 linker fails to emit COPY relocs
+   at all */
+static int
+_dl_do_copy (struct elf_resolve *tpnt, struct dyn_elf *scope,
+	     ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)
+{
+        int reloc_type;
+	int symtab_index;
+	unsigned long *reloc_addr;
+	unsigned long symbol_addr;
+	int goof = 0;
+	char*symname;
+	  
+	reloc_addr = (unsigned long *)(intptr_t) (tpnt->loadaddr + (unsigned long) rpnt->r_offset);
+	reloc_type = ELF32_R_TYPE(rpnt->r_info);
+	if (reloc_type != R_SH_COPY) 
+	    return 0;
+	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(symname, scope, NULL, copyrel);
+		if (!symbol_addr) goof++;
+	}
+	if (!goof) {
+#if defined (__SUPPORT_LD_DEBUG__)
+	        if(_dl_debug_move)
+		  _dl_dprintf(_dl_debug_file,"\n%s move %x bytes from %x to %x",
+			     symname, symtab[symtab_index].st_size,
+			     symbol_addr, symtab[symtab_index].st_value);
+#endif
+		_dl_memcpy((char *) symtab[symtab_index].st_value, 
+			(char *) symbol_addr, symtab[symtab_index].st_size);
+	}
+
+	return goof;
+}
+
+
+void _dl_parse_lazy_relocation_information(struct elf_resolve *tpnt, 
+	unsigned long rel_addr, unsigned long rel_size, int type)
+{
+	(void) type;
+	(void)_dl_parse(tpnt, NULL, rel_addr, rel_size, _dl_do_lazy_reloc);
+}
+
+int _dl_parse_relocation_information(struct elf_resolve *tpnt, 
+	unsigned long rel_addr, unsigned long rel_size, int type)
+{
+	(void) type;
+	return _dl_parse(tpnt, tpnt->symbol_scope, rel_addr, rel_size, _dl_do_reloc);
+}
+
+int _dl_parse_copy_information(struct dyn_elf *xpnt, unsigned long rel_addr, 
+	unsigned long rel_size, int type)
+{
+	(void) type;
+	return _dl_parse(xpnt->dyn, xpnt->next, rel_addr, rel_size, _dl_do_copy);
+}
+
+
diff -urN uClibc/ldso-0.9.24/ldso/sh/ld_syscalls.h uClibc.ldso.24/ldso-0.9.24/ldso/sh/ld_syscalls.h
--- uClibc/ldso-0.9.24/ldso/sh/ld_syscalls.h	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/sh/ld_syscalls.h	2002-08-09 07:20:19.000000000 -0500
@@ -0,0 +1,7 @@
+/* Define the __set_errno macro as nothing so that we don't bother
+ * setting errno, which is important since we make system calls
+ * before the errno symbol is dynamicly linked. */
+
+#define __set_errno(X) {(void)(X);}
+#include "sys/syscall.h"
+
diff -urN uClibc/ldso-0.9.24/ldso/sh/ld_sysdep.h uClibc.ldso.24/ldso-0.9.24/ldso/sh/ld_sysdep.h
--- uClibc/ldso-0.9.24/ldso/sh/ld_sysdep.h	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/sh/ld_sysdep.h	2002-11-07 20:18:16.000000000 -0600
@@ -0,0 +1,144 @@
+/*
+ * Various assmbly language/system dependent  hacks that are required
+ * so that we can minimize the amount of platform specific code.
+ */
+
+/* 
+ * Define this if the system uses RELOCA.
+ */
+#define ELF_USES_RELOCA
+
+/*
+ * 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)
+
+/*
+ * Initialization sequence for a GOT.
+ */
+#define INIT_GOT(GOT_BASE,MODULE) \
+{				\
+  GOT_BASE[2] = (unsigned long) _dl_linux_resolve; \
+  GOT_BASE[1] = (unsigned long) (MODULE); \
+}
+
+/*
+ * Here is a macro to perform a relocation.  This is only used when
+ * bootstrapping the dynamic loader.  RELP is the relocation that we
+ * are performing, REL is the pointer to the address we are relocating.
+ * SYMBOL is the symbol involved in the relocation, and LOAD is the
+ * load address.
+ */
+#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD)		\
+	switch(ELF32_R_TYPE((RELP)->r_info)){			\
+	case R_SH_REL32:					\
+		*(REL)  = (SYMBOL) + (RELP)->r_addend		\
+			    - (unsigned long)(REL);		\
+		break;						\
+	case R_SH_DIR32:					\
+	case R_SH_GLOB_DAT:					\
+	case R_SH_JMP_SLOT:					\
+		*(REL)  = (SYMBOL) + (RELP)->r_addend;		\
+		break;						\
+	case R_SH_RELATIVE:					\
+		*(REL)  = (LOAD) + (RELP)->r_addend;		\
+		break;						\
+	case R_SH_NONE:						\
+		break;						\
+	default:						\
+		SEND_STDERR("BOOTSTRAP_RELOC: unhandled reloc type "); \
+		SEND_NUMBER_STDERR(ELF32_R_TYPE((RELP)->r_info), 1); \
+		SEND_STDERR("REL, SYMBOL, LOAD: ");		\
+		SEND_ADDRESS_STDERR(REL, 0);			\
+		SEND_STDERR(", ");				\
+		SEND_ADDRESS_STDERR(SYMBOL, 0);			\
+		SEND_STDERR(", ");				\
+		SEND_ADDRESS_STDERR(LOAD, 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.
+ */
+
+#define START()   return _dl_elf_main;
+
+
+
+/* Here we define the magic numbers that this dynamic loader should accept */
+
+#define MAGIC1 EM_SH
+#undef  MAGIC2
+/* Used for error messages */
+#define ELF_TARGET "sh"
+
+struct elf_resolve;
+extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
+
+static __inline__ unsigned int
+_dl_urem(unsigned int n, unsigned int base)
+{
+  int res;
+  
+	__asm__ (""\
+		"mov	#0, r0\n\t" \
+		"div0u\n\t" \
+		"" \
+		"! get one bit from the msb of the numerator into the T\n\t" \
+		"! bit and divide it by whats in %2.  Put the answer bit\n\t" \
+		"! into the T bit so it can come out again at the bottom\n\t" \
+		""				\
+		"rotcl	%1 ; div1 %2, r0\n\t"	\
+		"rotcl	%1 ; div1 %2, r0\n\t"	\
+		"rotcl	%1 ; div1 %2, r0\n\t"	\
+		"rotcl	%1 ; div1 %2, r0\n\t"	\
+		"rotcl	%1 ; div1 %2, r0\n\t"	\
+		"rotcl	%1 ; div1 %2, r0\n\t"	\
+		"rotcl	%1 ; div1 %2, r0\n\t"	\
+		"rotcl	%1 ; div1 %2, r0\n\t"	\
+		""				\
+		"rotcl	%1 ; div1 %2, r0\n\t"	\
+		"rotcl	%1 ; div1 %2, r0\n\t"	\
+		"rotcl	%1 ; div1 %2, r0\n\t"	\
+		"rotcl	%1 ; div1 %2, r0\n\t"	\
+		"rotcl	%1 ; div1 %2, r0\n\t"	\
+		"rotcl	%1 ; div1 %2, r0\n\t"	\
+		"rotcl	%1 ; div1 %2, r0\n\t"	\
+		"rotcl	%1 ; div1 %2, r0\n\t"	\
+		""				\
+		"rotcl	%1 ; div1 %2, r0\n\t"	\
+		"rotcl	%1 ; div1 %2, r0\n\t"	\
+		"rotcl	%1 ; div1 %2, r0\n\t"	\
+		"rotcl	%1 ; div1 %2, r0\n\t"	\
+		"rotcl	%1 ; div1 %2, r0\n\t"	\
+		"rotcl	%1 ; div1 %2, r0\n\t"	\
+		"rotcl	%1 ; div1 %2, r0\n\t"	\
+		"rotcl	%1 ; div1 %2, r0\n\t"	\
+ 		""				\
+		"rotcl	%1 ; div1 %2, r0\n\t"	\
+		"rotcl	%1 ; div1 %2, r0\n\t"	\
+		"rotcl	%1 ; div1 %2, r0\n\t"	\
+		"rotcl	%1 ; div1 %2, r0\n\t"	\
+		"rotcl	%1 ; div1 %2, r0\n\t"	\
+		"rotcl	%1 ; div1 %2, r0\n\t"	\
+		"rotcl	%1 ; div1 %2, r0\n\t"	\
+		"rotcl	%1 ; div1 %2, r0\n\t"	\
+		"rotcl	%1\n\t"
+		: "=r" (res)
+		: "0" (n), "r" (base)
+		: "r0","cc");
+
+	return n - (base * res);
+}
+
+#define do_rem(result, n, base)     ((result) = _dl_urem((n), (base)))
+
+/* 4096 bytes alignment */
+#define PAGE_ALIGN 0xfffff000
+#define ADDR_ALIGN 0xfff
+#define OFFS_ALIGN 0x7ffff000
diff -urN uClibc/ldso-0.9.24/ldso/sh/resolve.S uClibc.ldso.24/ldso-0.9.24/ldso/sh/resolve.S
--- uClibc/ldso-0.9.24/ldso/sh/resolve.S	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/sh/resolve.S	2002-11-07 20:18:16.000000000 -0600
@@ -0,0 +1,91 @@
+/*
+ * Stolen from glibc-2.2.2 by Eddie C. Dost <ecd@atecom.com>
+ */
+
+	.text
+	.globl	_dl_linux_resolver
+	.globl	_dl_linux_resolve
+	.type	_dl_linux_resolve, @function
+	.balign	16
+_dl_linux_resolve:
+	mov.l	r3, @-r15
+	mov.l	r4, @-r15
+	mov.l	r5, @-r15
+	mov.l	r6, @-r15
+	mov.l	r7, @-r15
+	mov.l	r12, @-r15
+	movt	r3		! Save T flag
+	mov.l	r3, @-r15
+
+#ifdef HAVE_FPU
+	sts.l	fpscr, @-r15
+	mov	#8,r3
+	swap.w	r3, r3
+	lds	r3, fpscr
+	fmov.s	fr11, @-r15
+	fmov.s	fr10, @-r15
+	fmov.s	fr9, @-r15
+	fmov.s	fr8, @-r15
+	fmov.s	fr7, @-r15
+	fmov.s	fr6, @-r15
+	fmov.s	fr5, @-r15
+	fmov.s	fr4, @-r15
+#endif
+	sts.l	pr, @-r15
+/* Note - The PLT entries have been "optimised" not to use r2.  r2 is used by
+   GCC to return the address of large structures, so it should not be
+   corrupted here.  This does mean however, that those PLTs does not conform
+   to the SH PIC ABI.  That spec says that r0 contains the type of the PLT
+   and r2 contains the GOT id.  The GNU Plt version stores the GOT id in r0 and
+   ignores the type.  We can easily detect this difference however,
+   since the type will always be 0 or 8, and the GOT ids will always be
+   greater than or equal to 12.
+
+   Found in binutils/bfd/elf32-sh.c by Stefan Allius <allius@atecom.com>
+ */
+	mov     #8 ,r5
+	cmp/gt  r5, r0
+	bt      1f
+	mov     r2, r0          ! link map address in r2 (SH PIC ABI)
+1:
+	mov     r0, r4          ! link map address in r0 (GNUs PLT)
+	mova    .LG, r0
+	mov.l   .LG, r5
+	add     r5, r0
+	mov.l   3f, r5
+	mov.l   @(r0, r5),r5
+	jsr     @r5
+	 mov	r1, r5		! Reloc offset
+
+	lds.l	@r15+, pr	! Get register content back
+
+#ifdef HAVE_FPU
+	fmov.s	@r15+, fr4
+	fmov.s	@r15+, fr5
+	fmov.s	@r15+, fr6
+	fmov.s	@r15+, fr7
+	fmov.s	@r15+, fr8
+	fmov.s	@r15+, fr9
+	fmov.s	@r15+, fr10
+	fmov.s	@r15+, fr11
+	lds.l	@r15+, fpscr
+#endif
+
+	mov.l	@r15+, r3
+	shal	r3		! Load T flag
+	mov.l	@r15+, r12
+	mov.l	@r15+, r7
+	mov.l	@r15+, r6
+	mov.l	@r15+, r5
+	mov.l	@r15+, r4
+	jmp	@r0		! Jump to function address
+	 mov.l	@r15+, r3
+
+	.balign	4
+
+3:
+	.long   _dl_linux_resolver@GOT
+.LG:
+	.long	_GLOBAL_OFFSET_TABLE_
+	.size	_dl_linux_resolve, . - _dl_linux_resolve
+
diff -urN uClibc/ldso-0.9.24/ldso/sparc/boot1_arch.h uClibc.ldso.24/ldso-0.9.24/ldso/sparc/boot1_arch.h
--- uClibc/ldso-0.9.24/ldso/sparc/boot1_arch.h	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/sparc/boot1_arch.h	2002-08-08 09:35:49.000000000 -0500
@@ -0,0 +1,7 @@
+/* Any assmbly language/system dependent hacks needed to setup boot1.c so it
+ * will work as expected and cope with whatever platform specific wierdness is
+ * needed for this architecture.  See arm/boot1_arch.h for an example of what
+ * can be done.
+ */
+
+#define LD_BOOT(X)   void _dl_boot (X)
diff -urN uClibc/ldso-0.9.24/ldso/sparc/elfinterp.c uClibc.ldso.24/ldso-0.9.24/ldso/sparc/elfinterp.c
--- uClibc/ldso-0.9.24/ldso/sparc/elfinterp.c	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/sparc/elfinterp.c	2002-11-05 12:21:12.000000000 -0600
@@ -0,0 +1,357 @@
+/* vi: set sw=4 ts=4: */
+/* sparc ELF shared library loader suppport
+ *
+ * Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald, 
+ *				David Engel, Hongjiu Lu and Mitch D'Souza
+ *
+ * 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.
+ */
+
+#if defined (__SUPPORT_LD_DEBUG__)
+static const char * _dl_reltypes[] = { "R_SPARC_NONE", "R_SPARC_8",
+  "R_SPARC_16", "R_SPARC_32", "R_SPARC_DISP8", "R_SPARC_DISP16",
+  "R_SPARC_DISP32", "R_SPARC_WDISP30", "R_SPARC_WDISP22",
+  "R_SPARC_HI22", "R_SPARC_22", "R_SPARC_13", "R_SPARC_LO10",
+  "R_SPARC_GOT10", "R_SPARC_GOT13", "R_SPARC_GOT22", "R_SPARC_PC10",
+  "R_SPARC_PC22", "R_SPARC_WPLT30", "R_SPARC_COPY",
+  "R_SPARC_GLOB_DAT", "R_SPARC_JMP_SLOT", "R_SPARC_RELATIVE",
+  "R_SPARC_UA32"};
+#endif
+
+/* Program to load an ELF binary on a linux system, and run it.
+References to symbols in sharable libraries can be resolved by either
+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. */
+
+extern _dl_linux_resolve(void);
+
+unsigned int _dl_linux_resolver(unsigned int reloc_entry, unsigned int * plt)
+{
+  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] + 
+				   tpnt->loadaddr);
+
+  /*
+   * Generate the correct relocation index into the .rela.plt section.
+   */
+  reloc_entry = (reloc_entry >> 12) - 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] + tpnt->loadaddr);
+  strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
+
+  _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);
+
+
+  if (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;
+
+  _dl_dprintf(2, "symtab_index %d\n", symtab_index);
+
+#ifdef __SUPPORT_LD_DEBUG__
+  if (_dl_debug_symbols) {
+	  _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, resolver);
+  if(!new_addr) {
+    _dl_dprintf(2, "%s: can't resolve symbol '%s'\n",
+	       _dl_progname, strtab + symtab[symtab_index].st_name);
+    _dl_exit(31);
+  };
+
+#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 (!_dl_debug_nofixups) {
+		got_addr[1] = (char *) (0x03000000 | (((unsigned int) new_addr >> 10) & 0x3fffff));
+		got_addr[2] = (char *) (0x81c06000 | ((unsigned int) new_addr & 0x3ff));
+	}
+#else
+	got_addr[1] = (char *) (0x03000000 | (((unsigned int) new_addr >> 10) & 0x3fffff));
+	got_addr[2] = (char *) (0x81c06000 | ((unsigned int) new_addr & 0x3ff));
+#endif
+
+	_dl_dprintf(2, "Address = %x\n",new_addr);
+	_dl_exit(32);
+
+  return (unsigned int) new_addr;
+}
+
+void _dl_parse_lazy_relocation_information(struct elf_resolve * tpnt, int rel_addr,
+       int rel_size, int type){
+  int i;
+  char * strtab;
+  int reloc_type;
+  int symtab_index;
+  Elf32_Sym * symtab; 
+  Elf32_Rela * rpnt;
+  unsigned int * reloc_addr;
+
+  /* Now parse the relocation information */
+  rpnt = (Elf32_Rela *) (rel_addr + tpnt->loadaddr);
+
+  symtab =  (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
+  strtab = ( char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
+
+  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);
+
+    /* When the dynamic linker bootstrapped itself, it resolved some symbols.
+       Make sure we do not do them again */
+    if(!symtab_index && tpnt->libtype == program_interpreter) continue;
+    if(symtab_index && tpnt->libtype == program_interpreter &&
+       _dl_symbol(strtab + symtab[symtab_index].st_name))
+      continue;
+
+    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[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 elf_resolve * tpnt, int rel_addr,
+       int rel_size, int type){
+  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;
+  /* Now parse the relocation information */
+
+  rpnt = (Elf32_Rela *) (rel_addr + tpnt->loadaddr);
+
+  symtab =  (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
+  strtab = ( char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
+
+  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 && tpnt->libtype == program_interpreter) continue;
+
+    if(symtab_index) {
+
+      if(tpnt->libtype == program_interpreter && 
+	 _dl_symbol(strtab + symtab[symtab_index].st_name))
+	continue;
+
+      symbol_addr = (unsigned int) 
+	_dl_find_hash(strtab + symtab[symtab_index].st_name,
+			      tpnt->symbol_scope,
+		      (reloc_type == R_SPARC_JMP_SLOT ? tpnt : NULL), symbolrel);
+
+      if(!symbol_addr &&
+	 ELF32_ST_BIND(symtab [symtab_index].st_info) == STB_GLOBAL) {
+	_dl_dprintf(2, "%s: can't resolve symbol '%s'\n",
+		     _dl_progname, strtab + symtab[symtab_index].st_name);
+	goof++;
+      };
+    };
+    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:
+#if 0 /* This one is done later */
+      _dl_dprintf(2, "Doing copy for symbol ");
+      if(symtab_index) _dl_dprintf(2, strtab + symtab[symtab_index].st_name);
+      _dl_dprintf(2, "\n");
+      _dl_memcpy((void *) symtab[symtab_index].st_value,
+		 (void *) symbol_addr, 
+		 symtab[symtab_index].st_size);
+#endif
+      break;
+    default:
+      _dl_dprintf(2, "%s: can't handle reloc type ", _dl_progname);
+#if defined (__SUPPORT_LD_DEBUG__)
+      _dl_dprintf(2, "%s ", _dl_reltypes[reloc_type]);
+#endif
+      if (symtab_index)
+	_dl_dprintf(2, "'%s'\n", strtab + symtab[symtab_index].st_name);
+      _dl_exit(34);
+    };
+
+  };
+  return goof;
+}
+
+
+/* This is done as a separate step, because there are cases where
+   information is first copied and later initialized.  This results in
+   the wrong information being copied.  Someone at Sun was complaining about
+   a bug in the handling of _COPY by SVr4, and this may in fact be what he
+   was talking about.  Sigh. */
+
+/* No, there are cases where the SVr4 linker fails to emit COPY relocs
+   at all */
+
+int _dl_parse_copy_information(struct dyn_elf * xpnt, int rel_addr,
+       int rel_size, int type)
+{
+  int i;
+  char * strtab;
+  int reloc_type;
+  int goof = 0;
+  Elf32_Sym * symtab; 
+  Elf32_Rela * rpnt;
+  unsigned int * reloc_addr;
+  unsigned int symbol_addr;
+  struct elf_resolve *tpnt;
+  int symtab_index;
+  /* Now parse the relocation information */
+
+  tpnt = xpnt->dyn;
+  
+  rpnt = (Elf32_Rela *) (rel_addr + tpnt->loadaddr);
+
+  symtab =  (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
+  strtab = ( char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
+
+  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);
+    if(reloc_type != R_SPARC_COPY) continue;
+    symtab_index = ELF32_R_SYM(rpnt->r_info);
+    symbol_addr = 0;
+    if(!symtab_index && tpnt->libtype == program_interpreter) continue;
+    if(symtab_index) {
+
+      if(tpnt->libtype == program_interpreter && 
+	 _dl_symbol(strtab + symtab[symtab_index].st_name))
+	continue;
+
+      symbol_addr = (unsigned int) 
+	_dl_find_hash(strtab + symtab[symtab_index].st_name,
+			      xpnt->next, NULL, copyrel);
+      if(!symbol_addr) {
+	_dl_dprintf(2, "%s: can't resolve symbol '%s'\n",
+		   _dl_progname, strtab + symtab[symtab_index].st_name);
+	goof++;
+      };
+    };
+    if (!goof)
+      _dl_memcpy((char *) symtab[symtab_index].st_value, 
+		  (char *) symbol_addr, 
+		  symtab[symtab_index].st_size);
+  };
+  return goof;
+}
+
+
diff -urN uClibc/ldso-0.9.24/ldso/sparc/ld_syscalls.h uClibc.ldso.24/ldso-0.9.24/ldso/sparc/ld_syscalls.h
--- uClibc/ldso-0.9.24/ldso/sparc/ld_syscalls.h	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/sparc/ld_syscalls.h	2002-03-19 04:43:35.000000000 -0600
@@ -0,0 +1,155 @@
+/*
+ * This file contains the system call macros and syscall 
+ * numbers used by the shared library loader.
+ */
+
+#define __NR_exit		  1
+#define __NR_read		  3
+#define __NR_write		  4
+#define __NR_open		  5
+#define __NR_close		  6
+#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
+
+/* 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. */
+
+#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"); \
+if (__res < -255 || __res >= 0) \
+    return (type) __res; \
+/*errno = -__res; */\
+return -1; \
+}
+
+#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"); \
+if (__res < -255 || __res >= 0) \
+	return (type) __res; \
+/*errno = -__res;*/ \
+return -1; \
+}
+
+#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"); \
+if (__res < -255 || __res >= 0) \
+	return (type) __res; \
+/*errno = -__res;*/ \
+return -1; \
+}
+
+#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"); \
+if (__res < -255 || __res>=0) \
+	return (type) __res; \
+/*errno = -__res;*/ \
+return -1; \
+}
+
+#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"); \
+if (__res < -255 || __res>=0) \
+	return (type) __res; \
+/*errno = -__res;*/ \
+return -1; \
+} 
+
+#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"); \
+if (__res < -255 || __res>=0) \
+	return (type) __res; \
+/*errno = -__res; */\
+return -1; \
+}
diff -urN uClibc/ldso-0.9.24/ldso/sparc/ld_sysdep.h uClibc.ldso.24/ldso-0.9.24/ldso/sparc/ld_sysdep.h
--- uClibc/ldso-0.9.24/ldso/sparc/ld_sysdep.h	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/sparc/ld_sysdep.h	2002-08-09 08:05:29.000000000 -0500
@@ -0,0 +1,112 @@
+
+/*
+ * Various assmbly language/system dependent  hacks that are required
+ * so that we can minimize the amount of platform specific code.
+ */
+#define LINUXBIN
+
+/*
+ * Define this if the system uses RELOCA.
+ */
+#define ELF_USES_RELOCA
+
+/*
+ * 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.  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));
+
+/*
+ * Initialization sequence for a GOT.  For the Sparc, this points to the
+ * PLT, and we need to initialize a couple of the slots.  The PLT should
+ * look like:
+ *
+ *		save %sp, -64, %sp
+ *		call _dl_linux_resolve
+ *		nop
+ *		.word implementation_dependent
+ */
+#define INIT_GOT(GOT_BASE,MODULE) \
+{				\
+   GOT_BASE[0] = 0x9de3bfc0;  /* save %sp, -64, %sp */	\
+   GOT_BASE[1] = 0x40000000 | (((unsigned int) _dl_linux_resolve - (unsigned int) GOT_BASE - 4) >> 2);	\
+   GOT_BASE[2] = 0x01000000; /* nop */ 			\
+   GOT_BASE[3] = (int) MODULE;					\
+}
+
+/*
+ * 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) \
+	switch(ELF32_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;					\
+	case R_SPARC_JMP_SLOT:				\
+	  REL[1] = 0x03000000 | ((SYMBOL >> 10) & 0x3fffff);	\
+	  REL[2] = 0x81c06000 | (SYMBOL & 0x3ff);	\
+	  break;					\
+	case R_SPARC_NONE:				\
+	  break;					\
+        case R_SPARC_WDISP30:				\
+          break;                                        \
+	case R_SPARC_RELATIVE:				\
+	  *REL += (unsigned int) LOAD + (RELP)->r_addend; \
+	  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")
+
+
+
+/* Here we define the magic numbers that this dynamic loader should accept */
+
+#define MAGIC1 EM_SPARC
+#undef  MAGIC2
+/* Used for error messages */
+#define ELF_TARGET "Sparc"
+
+#ifndef COMPILE_ASM
+extern unsigned int _dl_linux_resolver(unsigned int reloc_entry,
+					unsigned int * i);
+#endif
+
+/*
+ * Define this if you want a dynamic loader that works on Solaris.
+ */
+#define SOLARIS_COMPATIBLE
+
+#define do_rem(result, n, base)	    result = (n % base)
+
+/*
+ * 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 */
+#define PAGE_ALIGN 0xfffff000
+#define ADDR_ALIGN 0xfff
+#define OFFS_ALIGN 0x7ffff000
diff -urN uClibc/ldso-0.9.24/ldso/sparc/resolve.S uClibc.ldso.24/ldso-0.9.24/ldso/sparc/resolve.S
--- uClibc/ldso-0.9.24/ldso/sparc/resolve.S	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/ldso/sparc/resolve.S	2002-01-11 13:57:41.000000000 -0600
@@ -0,0 +1,25 @@
+/*
+ * These are various helper routines that are needed to run an ELF image.
+ */
+#define COMPILE_ASM
+#include "ld_sysdep.h"
+
+.text
+	.align 16
+
+.globl _dl_linux_resolve
+_dl_linux_resolve:
+	/*
+ 	 * Call the resolver - pass the address of the PLT so that we can
+	 * figure out which module we are in.
+	 */
+	mov %o7,%o1
+	call  _dl_linux_resolver
+	mov %g1,%o0
+
+	jmpl %o0,%o7
+	restore
+.LFE2:
+
+	.type	_dl_linux_resolve,#function
+	.size _dl_linux_resolve,.LFE2-_dl_linux_resolve
diff -urN uClibc/ldso-0.9.24/libdl/.cvsignore uClibc.ldso.24/ldso-0.9.24/libdl/.cvsignore
--- uClibc/ldso-0.9.24/libdl/.cvsignore	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/libdl/.cvsignore	2001-04-26 11:12:47.000000000 -0500
@@ -0,0 +1,2 @@
+libdl.so*
+
diff -urN uClibc/ldso-0.9.24/libdl/Makefile uClibc.ldso.24/ldso-0.9.24/libdl/Makefile
--- uClibc/ldso-0.9.24/libdl/Makefile	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/libdl/Makefile	2004-03-01 03:05:53.000000000 -0600
@@ -0,0 +1,86 @@
+# Makefile 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
+
+
+TOPDIR=../../
+include $(TOPDIR)Rules.mak
+
+XXFLAGS=$(XWARNINGS) $(OPTIMIZATION) $(XARCH_CFLAGS) $(CPU_CFLAGS) \
+	-DUCLIBC_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" \
+	-fno-builtin -nostdinc -D_LIBC -I$(TOPDIR)ldso-0.9.24/include -I. -I$(TOPDIR)include
+
+ifeq ($(DODEBUG),y)
+XXFLAGS=$(XWARNINGS) -O0 -g3 $(XARCH_CFLAGS) $(CPU_CFLAGS) \
+	-DUCLIBC_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" \
+	-fno-builtin -nostdinc -D_LIBC -I$(TOPDIR)ldso-0.9.24/include -I. -I$(TOPDIR)include
+endif
+
+XXFLAGS+=$(shell $(CC) -print-search-dirs | sed -ne "s/install: *\(.*\)/-I\1include/gp")
+XXFLAGS_NOPIC:=$(XXFLAGS)
+ifeq ($(DOPIC),y)
+    XXFLAGS += $(PICFLAG) -D__LIBDL_SHARED__
+endif
+ifeq ($(strip $(SUPPORT_LD_DEBUG)),y)
+XXFLAGS+=-D__SUPPORT_LD_DEBUG__
+endif
+
+LIBDL=libdl.a
+LIBDL_PIC=libdl_pic.a
+LIBDL_SHARED=libdl.so
+LIBDL_SHARED_FULLNAME=libdl-$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBLEVEL).so
+
+CSRC=dlib.c
+OBJS=dlib.o
+PIC_OBJS=dlib_pic.o
+
+all: $(OBJS) $(LIBDL) shared
+
+$(LIBDL): ar-target
+
+ar-target: $(OBJS) $(PIC_OBJS)
+	$(AR) $(ARFLAGS) $(LIBDL) ../ldso/$(TARGET_ARCH)/resolve.o $(OBJS)
+	$(AR) $(ARFLAGS) $(LIBDL_PIC) $(PIC_OBJS)
+	$(INSTALL) -d $(TOPDIR)lib
+	$(RM) $(TOPDIR)lib/$(LIBDL)
+	$(INSTALL) -m 644 $(LIBDL) $(TOPDIR)lib
+
+
+dlib.o: dlib.c
+	$(CC) $(XXFLAGS_NOPIC) -c dlib.c -o dlib.o
+	$(STRIPTOOL) -x -R .note -R .comment $*.o
+
+dlib_pic.o: dlib.c
+	$(CC) $(XXFLAGS) -c dlib.c -o dlib_pic.o
+	$(STRIPTOOL) -x -R .note -R .comment $*.o
+
+$(OBJ): Makefile
+
+shared:
+	$(LD) $(LDFLAGS) -soname=$(LIBDL_SHARED).$(MAJOR_VERSION) \
+		-o $(LIBDL_SHARED_FULLNAME) --whole-archive $(LIBDL_PIC) \
+		--no-whole-archive $(TOPDIR)/libc/misc/internals/interp.o \
+		-L$(TOPDIR)/lib -lc $(LDADD_LIBFLOAT) $(LIBGCC);
+	$(INSTALL) -d $(TOPDIR)lib
+	$(RM) $(TOPDIR)lib/$(LIBDL_SHARED_FULLNAME) $(TOPDIR)lib/$(LIBDL_SHARED).$(MAJOR_VERSION)
+	$(INSTALL) -m 644 $(LIBDL_SHARED_FULLNAME) $(TOPDIR)lib
+	$(LN) -sf $(LIBDL_SHARED_FULLNAME) $(TOPDIR)lib/$(LIBDL_SHARED)
+	$(LN) -sf $(LIBDL_SHARED_FULLNAME) $(TOPDIR)lib/$(LIBDL_SHARED).$(MAJOR_VERSION)
+
+clean:
+	$(RM) .depend $(LIBDL_SHARED)* $(LIBDL_SHARED_FULLNAME) core *.o *.a *.s *.i tmp_make foo *~
diff -urN uClibc/ldso-0.9.24/libdl/dlib.c uClibc.ldso.24/ldso-0.9.24/libdl/dlib.c
--- uClibc/ldso-0.9.24/libdl/dlib.c	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/libdl/dlib.c	2004-03-01 03:04:42.000000000 -0600
@@ -0,0 +1,664 @@
+/*
+ * libdl.c
+ * 
+ * Functions required for dlopen et. al.
+ */
+
+#include <ldso.h>
+
+
+/* The public interfaces */
+void *dlopen(const char *, int) __attribute__ ((__weak__, __alias__ ("_dlopen")));
+int dlclose(void *) __attribute__ ((__weak__, __alias__ ("_dlclose")));
+void *dlsym(void *, const char *) __attribute__ ((__weak__, __alias__ ("_dlsym")));
+const char *dlerror(void) __attribute__ ((__weak__, __alias__ ("_dlerror")));
+int dladdr(void *, Dl_info *) __attribute__ ((__weak__, __alias__ ("_dladdr")));
+void _dlinfo(void);
+
+
+#ifdef __LIBDL_SHARED__
+/* This is a real hack.  We need access to the dynamic linker, but we
+also need to make it possible to link against this library without any
+unresolved externals.  We provide these weak symbols to make the link
+possible, but at run time the normal symbols are accessed. */
+static void __attribute__ ((unused)) foobar(void)
+{
+	const char msg[]="libdl library not correctly linked\n";
+	_dl_write(2, msg, _dl_strlen(msg));
+	_dl_exit(1);
+}
+
+static int __attribute__ ((unused)) foobar1 = (int) foobar;	/* Use as pointer */
+extern void _dl_dprintf(int, const char *, ...) __attribute__ ((__weak__, __alias__ ("foobar")));
+extern char *_dl_find_hash(const char *, struct dyn_elf *, struct elf_resolve *, enum caller_type)
+	__attribute__ ((__weak__, __alias__ ("foobar")));
+extern struct elf_resolve * _dl_load_shared_library(int, struct dyn_elf **, struct elf_resolve *, char *)
+	__attribute__ ((__weak__, __alias__ ("foobar")));
+extern struct elf_resolve * _dl_check_if_named_library_is_loaded(const char *full_libname)
+	__attribute__ ((__weak__, __alias__ ("foobar")));
+extern int _dl_fixup(struct elf_resolve *tpnt, int lazy)
+	 __attribute__ ((__weak__, __alias__ ("foobar")));
+extern int _dl_copy_fixups(struct dyn_elf * tpnt)
+	 __attribute__ ((__weak__, __alias__ ("foobar")));
+#ifdef __mips__
+extern void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt)
+	__attribute__ ((__weak__, __alias__ ("foobar")));
+#endif
+#ifdef USE_CACHE
+int _dl_map_cache(void) __attribute__ ((__weak__, __alias__ ("foobar")));
+int _dl_unmap_cache(void) __attribute__ ((__weak__, __alias__ ("foobar")));
+#endif	
+
+extern struct dyn_elf *_dl_symbol_tables __attribute__ ((__weak__, __alias__ ("foobar1")));
+extern struct dyn_elf *_dl_handles __attribute__ ((__weak__, __alias__ ("foobar1")));
+extern struct elf_resolve *_dl_loaded_modules __attribute__ ((__weak__, __alias__ ("foobar1")));
+extern struct r_debug *_dl_debug_addr __attribute__ ((__weak__, __alias__ ("foobar1")));
+extern unsigned long _dl_error_number __attribute__ ((__weak__, __alias__ ("foobar1")));
+extern void *(*_dl_malloc_function)(size_t) __attribute__ ((__weak__, __alias__ ("foobar1")));
+#ifdef __SUPPORT_LD_DEBUG__
+extern char *_dl_debug __attribute__ ((__weak__, __alias__ ("foobar1")));
+extern char *_dl_debug_symbols __attribute__ ((__weak__, __alias__ ("foobar1")));
+extern char *_dl_debug_move __attribute__ ((__weak__, __alias__ ("foobar1")));
+extern char *_dl_debug_reloc __attribute__ ((__weak__, __alias__ ("foobar1")));
+extern char *_dl_debug_detail __attribute__ ((__weak__, __alias__ ("foobar1")));
+extern char *_dl_debug_nofixups __attribute__ ((__weak__, __alias__ ("foobar1")));
+extern char *_dl_debug_bindings __attribute__ ((__weak__, __alias__ ("foobar1")));
+extern int   _dl_debug_file __attribute__ ((__weak__, __alias__ ("foobar1")));
+#endif
+
+#else	/* __LIBDL_SHARED__ */
+
+#ifdef __SUPPORT_LD_DEBUG__
+char *_dl_debug  = 0;
+char *_dl_debug_symbols = 0;
+char *_dl_debug_move    = 0;
+char *_dl_debug_reloc   = 0;
+char *_dl_debug_detail  = 0;
+char *_dl_debug_nofixups  = 0;
+char *_dl_debug_bindings  = 0;
+int   _dl_debug_file = 2;
+#endif
+char *_dl_library_path = 0;
+char *_dl_ldsopath = 0;
+struct r_debug *_dl_debug_addr = NULL;
+static char *_dl_malloc_addr, *_dl_mmap_zero;
+#include "../ldso/_dl_progname.h"               /* Pull in the name of ld.so */
+#include "../ldso/hash.c"
+#define _dl_trace_loaded_objects    0
+#include "../ldso/readelflib1.c"
+void *(*_dl_malloc_function) (size_t size);
+int _dl_fixup(struct elf_resolve *tpnt, int lazy);
+#endif
+
+static int do_dlclose(void *, int need_fini);
+
+
+static const char *dl_error_names[] = {
+	"",
+	"File not found",
+	"Unable to open /dev/zero",
+	"Not an ELF file",
+#if defined (__i386__)
+	"Not i386 binary",
+#elif defined (__sparc__)
+	"Not sparc binary",
+#elif defined (__mc68000__)
+	"Not m68k binary",
+#else
+	"Unrecognized binary type",
+#endif
+	"Not an ELF shared library",
+	"Unable to mmap file",
+	"No dynamic section",
+#ifdef ELF_USES_RELOCA
+	"Unable to process REL relocs",
+#else
+	"Unable to process RELA relocs",
+#endif
+	"Bad handle",
+	"Unable to resolve symbol"
+};
+
+static void __attribute__ ((destructor)) dl_cleanup(void)
+{
+	struct dyn_elf *d;
+
+	for (d = _dl_handles; d; d = d->next_handle)
+		if (d->dyn->libtype == loaded_file && d->dyn->dynamic_info[DT_FINI]) {
+			(* ((int (*)(void)) (d->dyn->loadaddr + d->dyn->dynamic_info[DT_FINI]))) ();
+			d->dyn->dynamic_info[DT_FINI] = 0;
+		}
+}
+
+void *_dlopen(const char *libname, int flag)
+{
+	struct elf_resolve *tpnt, *tfrom, *tcurr;
+	struct dyn_elf *dyn_chain, *rpnt = NULL;
+	struct dyn_elf *dpnt;
+	static int dl_init = 0;
+	ElfW(Addr) from;
+	struct elf_resolve *tpnt1;
+	void (*dl_brk) (void);
+
+	/* A bit of sanity checking... */
+	if (!(flag & (RTLD_LAZY|RTLD_NOW))) {
+		_dl_error_number = LD_BAD_HANDLE;
+		return NULL;
+	}
+
+	from = (ElfW(Addr)) __builtin_return_address(0);
+
+	/* Have the dynamic linker use the regular malloc function now */
+	if (!dl_init) {
+		dl_init++;
+		_dl_malloc_function = malloc;
+	}
+
+	/* Cover the trivial case first */
+	if (!libname)
+		return _dl_symbol_tables;
+
+	_dl_map_cache();
+
+	/*
+	 * Try and locate the module we were called from - we
+	 * need this so that we get the correct RPATH.  Note that
+	 * this is the current behavior under Solaris, but the
+	 * ABI+ specifies that we should only use the RPATH from
+	 * 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;
+	}
+
+	/* Try to load the specified library */
+#ifdef __SUPPORT_LD_DEBUG__
+	if(_dl_debug) 
+	_dl_dprintf(_dl_debug_file, "Trying to dlopen '%s'\n", (char*)libname);
+#endif
+	tpnt = _dl_load_shared_library(0, &rpnt, tfrom, (char*)libname);
+	if (tpnt == NULL) {
+		_dl_unmap_cache();
+		return NULL;
+	}
+
+	dyn_chain = (struct dyn_elf *) malloc(sizeof(struct dyn_elf));
+	_dl_memset(dyn_chain, 0, sizeof(struct dyn_elf));
+	dyn_chain->dyn = tpnt;
+	dyn_chain->flags = flag;
+	if (!tpnt->symbol_scope)
+		tpnt->symbol_scope = dyn_chain;
+
+	dyn_chain->next_handle = _dl_handles;
+	_dl_handles = rpnt = dyn_chain;
+
+	if (tpnt->init_flag & INIT_FUNCS_CALLED) {
+	    /* If the init and fini stuff has already been run, that means
+	     * the dlopen'd library has already been loaded, and nothing
+	     * further needs to be done. */
+	    return (void *) dyn_chain;
+	}
+
+
+#ifdef __SUPPORT_LD_DEBUG__
+	if(_dl_debug) 
+	_dl_dprintf(_dl_debug_file, "Looking for needed libraries\n");
+#endif
+
+	for (tcurr = tpnt; tcurr; tcurr = tcurr->next)
+	{
+		Elf32_Dyn *dpnt;
+		char *lpntstr;
+		for (dpnt = (Elf32_Dyn *) tcurr->dynamic_addr; dpnt->d_tag; dpnt++) {
+			if (dpnt->d_tag == DT_NEEDED) {
+
+				char *name;
+				lpntstr = (char*) (tcurr->loadaddr + tcurr->dynamic_info[DT_STRTAB] + 
+					dpnt->d_un.d_val);
+				name = _dl_get_last_path_component(lpntstr);
+
+#ifdef __SUPPORT_LD_DEBUG__
+				if(_dl_debug) 
+				_dl_dprintf(_dl_debug_file, "Trying to load '%s', needed by '%s'\n", 
+						lpntstr, tcurr->libname);
+#endif
+
+				if (!(tpnt1 = _dl_load_shared_library(0, &rpnt, tcurr, lpntstr))) {
+					goto oops;
+				}
+
+#if 1
+//FIXME:  Enabling this is _so_ wrong....
+				/* We need global symbol resolution for everything
+				 * in the dependent chain */
+				dyn_chain->flags |= RTLD_GLOBAL;
+#endif
+
+				rpnt->next = (struct dyn_elf *) malloc(sizeof(struct dyn_elf));
+				_dl_memset (rpnt->next, 0, sizeof (struct dyn_elf));
+				rpnt = rpnt->next;
+				if (!tpnt1->symbol_scope) tpnt1->symbol_scope = rpnt;
+				rpnt->dyn = tpnt1;
+
+			}
+		}
+	}
+
+	/*
+	 * OK, now attach the entire chain at the end
+	 */
+	rpnt->next = _dl_symbol_tables;
+
+#ifdef __mips__
+	/*
+	 * Relocation of the GOT entries for MIPS have to be done
+	 * after all the libraries have been loaded.
+	 */
+	_dl_perform_mips_global_got_relocations(tpnt);
+#endif
+
+#ifdef __SUPPORT_LD_DEBUG__
+	if(_dl_debug) 
+	_dl_dprintf(_dl_debug_file, "Beginning dlopen relocation fixups\n");
+#endif
+	/*
+	 * OK, now all of the kids are tucked into bed in their proper addresses.
+	 * Now we go through and look for REL and RELA records that indicate fixups
+	 * to the GOT tables.  We need to do this in reverse order so that COPY
+	 * directives work correctly */
+	if (_dl_fixup(dyn_chain->dyn, dyn_chain->flags))
+		goto oops;
+
+#ifdef __SUPPORT_LD_DEBUG__
+	if(_dl_debug) 
+	_dl_dprintf(_dl_debug_file, "Beginning dlopen copy fixups\n");
+#endif
+	if (_dl_symbol_tables) {
+		if (_dl_copy_fixups(dyn_chain))
+			goto oops;
+	}
+
+
+	/* TODO:  Should we set the protections of all pages back to R/O now ? */
+	
+
+	/* Notify the debugger we have added some objects. */
+	_dl_debug_addr->r_state = RT_ADD;
+	if (_dl_debug_addr) {
+		dl_brk = (void (*)(void)) _dl_debug_addr->r_brk;
+		if (dl_brk != NULL) {
+			_dl_debug_addr->r_state = RT_ADD;
+			(*dl_brk) ();
+
+			_dl_debug_addr->r_state = RT_CONSISTENT;
+			(*dl_brk) ();
+		}
+	}
+
+#if 0 //def __SUPPORT_LD_DEBUG__
+	if(_dl_debug) 
+	_dlinfo();
+#endif
+
+#ifdef __LIBDL_SHARED__
+	/* Find the last library so we can run things in the right order */
+	for (tpnt = dyn_chain->dyn; tpnt->next!=NULL; tpnt = tpnt->next)
+	    ;
+
+	/* Run the ctors and set up the dtors */
+	for (; tpnt != dyn_chain->dyn->prev; tpnt=tpnt->prev)
+	{
+		/* Apparently crt1 for the application is responsible for handling this.
+		 * We only need to run the init/fini for shared libraries
+		 */
+		if (tpnt->libtype == program_interpreter)
+			continue;
+		if (tpnt->libtype == elf_executable)
+			continue;
+		if (tpnt->init_flag & INIT_FUNCS_CALLED)
+			continue;
+		tpnt->init_flag |= INIT_FUNCS_CALLED;
+
+		if (tpnt->dynamic_info[DT_INIT]) {
+		    void (*dl_elf_func) (void);
+		    dl_elf_func = (void (*)(void)) (tpnt->loadaddr + tpnt->dynamic_info[DT_INIT]);
+		    if (dl_elf_func && *dl_elf_func != NULL) {
+#ifdef __SUPPORT_LD_DEBUG__
+			if(_dl_debug) 
+			_dl_dprintf(2, "running ctors for library %s at '%x'\n", tpnt->libname, dl_elf_func);
+#endif
+			(*dl_elf_func) ();
+		    }
+		}
+		if (tpnt->dynamic_info[DT_FINI]) {
+		    void (*dl_elf_func) (void);
+		    dl_elf_func = (void (*)(void)) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI]);
+		    if (dl_elf_func && *dl_elf_func != NULL) {
+#ifdef __SUPPORT_LD_DEBUG__
+			if(_dl_debug) 
+			_dl_dprintf(2, "setting up dtors for library %s at '%x'\n", tpnt->libname, dl_elf_func);
+#endif
+			atexit(dl_elf_func);
+		    }
+		}
+	}
+#endif
+	return (void *) dyn_chain;
+
+oops:
+	/* Something went wrong.  Clean up and return NULL. */
+	_dl_unmap_cache();
+	do_dlclose(dyn_chain, 0);
+	return NULL;
+}
+
+void *_dlsym(void *vhandle, const char *name)
+{
+	struct elf_resolve *tpnt, *tfrom;
+	struct dyn_elf *handle;
+	ElfW(Addr) from;
+	struct dyn_elf *rpnt;
+	void *ret;
+
+	handle = (struct dyn_elf *) vhandle;
+
+	/* First of all verify that we have a real handle
+	   of some kind.  Return NULL if not a valid handle. */
+
+	if (handle == NULL)
+		handle = _dl_symbol_tables;
+	else if (handle != RTLD_NEXT && handle != _dl_symbol_tables) {
+		for (rpnt = _dl_handles; rpnt; rpnt = rpnt->next_handle)
+			if (rpnt == handle)
+				break;
+		if (!rpnt) {
+			_dl_error_number = LD_BAD_HANDLE;
+			return NULL;
+		}
+	} else if (handle == RTLD_NEXT) {
+		/*
+		 * Try and locate the module we were called from - we
+		 * need this so that we know where to start searching
+		 * from.  We never pass RTLD_NEXT down into the actual
+		 * dynamic loader itself, as it doesn't know
+		 * how to properly treat it.
+		 */
+		from = (ElfW(Addr)) __builtin_return_address(0);
+
+		tfrom = NULL;
+		for (rpnt = _dl_symbol_tables; rpnt; rpnt = rpnt->next) {
+			tpnt = rpnt->dyn;
+			if (tpnt->loadaddr < from
+				&& (tfrom == NULL || tfrom->loadaddr < tpnt->loadaddr)) {
+				tfrom = tpnt;
+				handle = rpnt->next;
+			}
+		}
+	}
+
+	ret = _dl_find_hash((char*)name, handle, NULL, copyrel);
+
+	/*
+	 * Nothing found.
+	 */
+	if (!ret)
+		_dl_error_number = LD_NO_SYMBOL;
+	return ret;
+}
+
+int _dlclose(void *vhandle)
+{
+	return do_dlclose(vhandle, 1);
+}
+
+static int do_dlclose(void *vhandle, int need_fini)
+{
+	struct dyn_elf *rpnt, *rpnt1;
+	struct dyn_elf *spnt, *spnt1;
+	ElfW(Phdr) *ppnt;
+	struct elf_resolve *tpnt;
+	int (*dl_elf_fini) (void);
+	void (*dl_brk) (void);
+	struct dyn_elf *handle;
+	unsigned int end;
+	int i = 0;
+
+	handle = (struct dyn_elf *) vhandle;
+	rpnt1 = NULL;
+	for (rpnt = _dl_handles; rpnt; rpnt = rpnt->next_handle) {
+		if (rpnt == handle) {
+			break;
+		}
+		rpnt1 = rpnt;
+	}
+
+	if (!rpnt) {
+		_dl_error_number = LD_BAD_HANDLE;
+		return 1;
+	}
+
+	/* OK, this is a valid handle - now close out the file.
+	 * We check if we need to call fini () on the handle. */
+	spnt = need_fini ? handle : handle->next;
+	for (; spnt; spnt = spnt1) {
+		spnt1 = spnt->next;
+
+		/* We appended the module list to the end - when we get back here, 
+		   quit. The access counts were not adjusted to account for being here. */
+		if (spnt == _dl_symbol_tables)
+			break;
+		if (spnt->dyn->usage_count == 1
+			&& spnt->dyn->libtype == loaded_file) {
+			tpnt = spnt->dyn;
+			/* Apparently crt1 for the application is responsible for handling this.
+			 * We only need to run the init/fini for shared libraries
+			 */
+
+			if (tpnt->dynamic_info[DT_FINI]) {
+				dl_elf_fini = (int (*)(void)) (tpnt->loadaddr + 
+					tpnt->dynamic_info[DT_FINI]);
+				(*dl_elf_fini) ();
+			}
+		}
+	}
+	if (rpnt1)
+		rpnt1->next_handle = rpnt->next_handle;
+	else
+		_dl_handles = rpnt->next_handle;
+
+	/* OK, this is a valid handle - now close out the file */
+	for (rpnt = handle; rpnt; rpnt = rpnt1) {
+		rpnt1 = rpnt->next;
+
+		/* We appended the module list to the end - when we get back here, 
+		   quit. The access counts were not adjusted to account for being here. */
+		if (rpnt == _dl_symbol_tables)
+			break;
+
+		rpnt->dyn->usage_count--;
+		if (rpnt->dyn->usage_count == 0
+			&& rpnt->dyn->libtype == loaded_file) {
+			tpnt = rpnt->dyn;
+			/* Apparently crt1 for the application is responsible for handling this.
+			 * We only need to run the init/fini for shared libraries
+			 */
+#if 0
+
+			/* We have to do this above, before we start closing objects.  
+			 * Otherwise when the needed symbols for _fini handling are 
+			 * resolved a coredump would occur. Rob Ryan (robr@cmu.edu)*/ 
+			if (tpnt->dynamic_info[DT_FINI]) { 
+			    dl_elf_fini = (int (*)(void)) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI]);
+				(*dl_elf_fini) ();
+			}
+#endif
+			end = 0;
+			for (i = 0, ppnt = rpnt->dyn->ppnt;
+				 i < rpnt->dyn->n_phent; ppnt++, i++) {
+				if (ppnt->p_type != PT_LOAD)
+					continue;
+				if (end < ppnt->p_vaddr + ppnt->p_memsz)
+					end = ppnt->p_vaddr + ppnt->p_memsz;
+			}
+			_dl_munmap((void*)rpnt->dyn->loadaddr, end);
+			/* Next, remove rpnt->dyn from the loaded_module list */
+			if (_dl_loaded_modules == rpnt->dyn) {
+				_dl_loaded_modules = rpnt->dyn->next;
+				if (_dl_loaded_modules)
+					_dl_loaded_modules->prev = 0;
+			} else
+				for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next)
+					if (tpnt->next == rpnt->dyn) {
+						tpnt->next = tpnt->next->next;
+						if (tpnt->next)
+							tpnt->next->prev = tpnt;
+						break;
+					}
+			free(rpnt->dyn->libname);
+			free(rpnt->dyn);
+		}
+		free(rpnt);
+	}
+
+
+	if (_dl_debug_addr) {
+	    dl_brk = (void (*)(void)) _dl_debug_addr->r_brk;
+	    if (dl_brk != NULL) {
+		_dl_debug_addr->r_state = RT_DELETE;
+		(*dl_brk) ();
+
+		_dl_debug_addr->r_state = RT_CONSISTENT;
+		(*dl_brk) ();
+	    }
+	}
+
+	return 0;
+}
+
+const char *_dlerror(void)
+{
+	const char *retval;
+
+	if (!_dl_error_number)
+		return NULL;
+	retval = dl_error_names[_dl_error_number];
+	_dl_error_number = 0;
+	return retval;
+}
+
+/*
+ * Dump information to stderrr about the current loaded modules
+ */
+static char *type[] = { "Lib", "Exe", "Int", "Mod" };
+
+void _dlinfo(void)
+{
+	struct elf_resolve *tpnt;
+	struct dyn_elf *rpnt, *hpnt;
+
+	_dl_dprintf(2, "List of loaded modules\n");
+	/* First start with a complete list of all of the loaded files. */
+	for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) { 
+		_dl_dprintf(2, "\t%x %x %x %s %d %s\n", 
+			(unsigned) tpnt->loadaddr, (unsigned) tpnt,
+			(unsigned) tpnt->symbol_scope,
+			type[tpnt->libtype],
+			tpnt->usage_count, tpnt->libname);
+	}
+
+	/* Next dump the module list for the application itself */
+	_dl_dprintf(2, "\nModules for application (%x):\n",
+				 (unsigned) _dl_symbol_tables);
+	for (rpnt = _dl_symbol_tables; rpnt; rpnt = rpnt->next)
+		_dl_dprintf(2, "\t%x %s\n", (unsigned) rpnt->dyn, rpnt->dyn->libname);
+
+	for (hpnt = _dl_handles; hpnt; hpnt = hpnt->next_handle) {
+		_dl_dprintf(2, "Modules for handle %x\n", (unsigned) hpnt);
+		for (rpnt = hpnt; rpnt; rpnt = rpnt->next)
+			_dl_dprintf(2, "\t%x %s\n", (unsigned) rpnt->dyn, 
+				rpnt->dyn->libname);
+	}
+}
+
+int _dladdr(void *__address, Dl_info * __dlip)
+{
+	struct elf_resolve *pelf;
+	struct elf_resolve *rpnt;
+
+	_dl_map_cache();
+
+	/*
+	 * Try and locate the module address is in
+	 */
+	pelf = NULL;
+
+#if 0
+	_dl_dprintf(2, "dladdr( %x, %x )\n", __address, __dlip);
+#endif
+
+	for (rpnt = _dl_loaded_modules; rpnt; rpnt = rpnt->next) {
+		struct elf_resolve *tpnt;
+
+		tpnt = rpnt;
+#if 0
+		_dl_dprintf(2, "Module \"%s\" at %x\n", 
+			tpnt->libname, tpnt->loadaddr);
+#endif
+		if (tpnt->loadaddr < (ElfW(Addr)) __address
+			&& (pelf == NULL || pelf->loadaddr < tpnt->loadaddr)) {
+		    pelf = tpnt;
+		}
+	}
+
+	if (!pelf) {
+		return 0;
+	}
+
+	/*
+	 * Try and locate the symbol of address
+	 */
+
+	{
+		char *strtab;
+		Elf32_Sym *symtab;
+		int hn, si;
+		int sf;
+		int sn = 0;
+		ElfW(Addr) sa;
+
+		sa = 0;
+		symtab = (Elf32_Sym *) (pelf->dynamic_info[DT_SYMTAB] + pelf->loadaddr);
+		strtab = (char *) (pelf->dynamic_info[DT_STRTAB] + pelf->loadaddr);
+
+		sf = 0;
+		for (hn = 0; hn < pelf->nbucket; hn++) {
+			for (si = pelf->elf_buckets[hn]; si; si = pelf->chains[si]) {
+				ElfW(Addr) symbol_addr;
+
+				symbol_addr = pelf->loadaddr + symtab[si].st_value;
+				if (symbol_addr <= (ElfW(Addr))__address && (!sf || sa < symbol_addr)) {
+					sa = symbol_addr;
+					sn = si;
+					sf = 1;
+				}
+#if 0
+				_dl_dprintf(2, "Symbol \"%s\" at %x\n", 
+					strtab + symtab[si].st_name, symbol_addr);
+#endif
+			}
+		}
+
+		if (sf) {
+			__dlip->dli_fname = pelf->libname;
+			__dlip->dli_fbase = (void *)pelf->loadaddr;
+			__dlip->dli_sname = strtab + symtab[sn].st_name;
+			__dlip->dli_saddr = (void *)sa;
+		}
+		return 1;
+	}
+}
diff -urN uClibc/ldso-0.9.24/man/Makefile uClibc.ldso.24/ldso-0.9.24/man/Makefile
--- uClibc/ldso-0.9.24/man/Makefile	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/man/Makefile	2003-10-18 05:18:37.000000000 -0500
@@ -0,0 +1,33 @@
+# Makefile for uClibc
+#
+# Copyright (C) 2000,2001 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
+#
+# 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 ../Config.mk
+
+ALL = #ld.so.info
+
+all:	$(ALL)
+
+ld.so.info: ld.so.texi
+	makeinfo $<
+
+clean:
+	$(RM) $(ALL) *~
diff -urN uClibc/ldso-0.9.24/man/dlopen.3 uClibc.ldso.24/ldso-0.9.24/man/dlopen.3
--- uClibc/ldso-0.9.24/man/dlopen.3	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/man/dlopen.3	2001-04-23 12:43:54.000000000 -0500
@@ -0,0 +1,218 @@
+.\" -*- nroff -*-
+.\" Copyright 1995 Yggdrasil Computing, Incorporated.
+.\" written by Adam J. Richter (adam@yggdrasil.com),
+.\" with typesetting help from Daniel Quinlan (quinlan@yggdrasil.com).
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
+.\" USA.
+.\"
+.TH DLOPEN 3 "16 May 1995" "Linux" "Linux Programmer's Manual"
+.SH NAME
+dlclose, dlerror, dlopen, dlsym \- Programming interface to dynamic linking loader.
+.SH SYNOPSIS
+.B #include <dlfcn.h>
+.sp
+.BI "void *dlopen (const char *" "filename" ", int " flag ");
+.br
+.BI "const char *dlerror(void);"
+.br
+.BI "void *dlsym(void *"handle ", char *"symbol ");"
+.br
+.BI "int dladdr(void *"address ", Dl_info *"dlip ");"
+.br
+.BI "int dlclose (void *"handle ");
+.sp
+Special symbols:
+.BR "_init" ", " "_fini" ". "
+.SH DESCRIPTION
+.B dlopen
+loads a dynamic library from the file named by the null terminated
+string
+.I filename
+and returns an opaque "handle" for the dynamic library.
+If
+.I filename
+is not an absolute path (i.e., it does not begin with a "/"), then the
+file is searched for in the following locations:
+.RS
+.PP
+A colon-separated list of directories in the user's
+\fBLD_LIBRARY\fP path environment variable.
+.PP
+The list of libraries specified in \fI/etc/ld.so.cache\fP.
+.PP
+\fI/usr/lib\fP, followed by \fI/lib\fP.
+.RE
+.PP
+If
+.I filename
+is a NULL pointer, then the returned handle is for the main program.
+.PP
+External references in the library are resolved using the libraries
+in that library's dependency list and any other libraries previously
+opened with the 
+.B RTLD_GLOBAL
+flag.
+If the executable was linked
+with the flag "-rdynamic", then the global symbols in the executable
+will also be used to resolve references in a dynamically loaded
+library.
+.PP
+.I flag
+must be either
+.BR RTLD_LAZY ,
+meaning resolve undefined symbols as code from the dynamic library is
+executed, or
+.BR RTLD_NOW ,
+meaning resolve all undefined symbols before
+.B dlopen
+returns, and fail if this cannot be done.
+Optionally,
+.B RTLD_GLOBAL
+may be or'ed with
+.IR flag,
+in which case the external symbols defined in the library will be
+made available to subsequently loaded libraries.
+.PP
+If the library exports a routine named
+.BR _init ,
+then that code is executed before dlopen returns.
+If the same library is loaded twice with
+.BR dlopen() ,
+the same file handle is returned.  The dl library maintains link
+counts for dynamic file handles, so a dynamic library is not
+deallocated until
+.B dlclose
+has been called on it as many times as
+.B dlopen
+has succeeded on it.
+.PP
+If
+.B dlopen
+fails for any reason, it returns NULL.
+A human readable string describing the most recent error that occurred
+from any of the dl routines (dlopen, dlsym or dlclose) can be
+extracted with
+.BR dlerror() .
+.B dlerror
+returns NULL if no errors have occurred since initialization or since
+it was last called.  (Calling
+.B dlerror()
+twice consecutively, will always result in the second call returning
+NULL.)
+
+.B dlsym
+takes a "handle" of a dynamic library returned by dlopen and the null
+terminated symbol name, returning the address where that symbol is
+loaded.  If the symbol is not found,
+.B dlsym
+returns NULL; however, the correct way to test for an error from
+.B dlsym
+is to save the result of
+.B dlerror
+into a variable, and then check if saved value is not NULL.
+This is because the value of the symbol could actually be NULL.
+It is also necessary to save the results of
+.B dlerror
+into a variable because if
+.B dlerror
+is called again, it will return NULL.
+.PP
+.B dladdr
+returns information about the shared library containing the memory 
+location specified by
+.IR address .
+.B dladdr
+returns zero on success and non-zero on error.
+.PP
+.B dlclose
+decrements the reference count on the dynamic library handle
+.IR handle .
+If the reference count drops to zero and no other loaded libraries use
+symbols in it, then the dynamic library is unloaded.  If the dynamic
+library exports a routine named
+.BR _fini ,
+then that routine is called just before the library is unloaded.
+.SH EXAMPLES
+.B Load the math library, and print the cosine of 2.0:
+.RS
+.nf
+.if t .ft CW
+#include <dlfcn.h>
+
+int main(int argc, char **argv) {
+    void *handle = dlopen ("/lib/libm.so", RTLD_LAZY);
+    double (*cosine)(double) = dlsym(handle, "cos");
+    printf ("%f\\n", (*cosine)(2.0));
+    dlclose(handle);
+}
+.if t .ft P
+.fi
+.PP
+If this program were in a file named "foo.c", you would build the program
+with the following command:
+.RS
+.LP
+gcc -rdynamic -o foo foo.c -ldl
+.RE
+.RE
+.LP
+.B Do the same thing, but check for errors at every step:
+.RS
+.nf
+.if t .ft CW
+#include <stdio.h>
+#include <dlfcn.h>
+
+int main(int argc, char **argv) {
+    void *handle;
+    double (*cosine)(double);
+    char *error;
+
+    handle = dlopen ("/lib/libm.so", RTLD_LAZY);
+    if (!handle) {
+        fputs (dlerror(), stderr);
+        exit(1);
+    }
+
+    cosine = dlsym(handle, "cos");
+    if ((error = dlerror()) != NULL)  {
+        fputs(error, stderr);
+        exit(1);
+    }
+
+    printf ("%f\\n", (*cosine)(2.0));
+    dlclose(handle);
+}
+.if t .ft P
+.fi
+.RE
+.SH ACKNOWLEDGEMENTS
+The dlopen interface standard comes from Solaris.
+The Linux dlopen implementation was primarily written by
+Eric Youngdale with help from Mitch D'Souza, David Engel,
+Hongjiu Lu, Andreas Schwab and others.
+The manual page was written by Adam Richter.
+.SH SEE ALSO
+.BR ld(1) ,
+.BR ld.so(8) ,
+.BR ldconfig(8) ,
+.BR ldd(1) ,
+.BR ld.so.info .
diff -urN uClibc/ldso-0.9.24/man/ld.so.8 uClibc.ldso.24/ldso-0.9.24/man/ld.so.8
--- uClibc/ldso-0.9.24/man/ld.so.8	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/man/ld.so.8	2001-04-23 12:43:54.000000000 -0500
@@ -0,0 +1,113 @@
+.TH ld.so 8 "14 March 1998"
+.SH NAME
+ld.so/ld-linux.so \- dynamic linker/loader
+.SH DESCRIPTION
+.B ld.so
+loads the shared libraries needed by a program, prepares the program
+to run, and then runs it.
+Unless explicitly specified via the
+.B \-static
+option to
+.B ld
+during compilation, all Linux programs are incomplete and require 
+further linking at run time.
+.PP
+The necessary shared libraries needed by the program are searched for 
+in the following order
+.IP o
+Using the environment variable
+.B LD_LIBRARY_PATH
+.RB ( LD_AOUT_LIBRARY_PATH
+for a.out programs).
+Except if the executable is a setuid/setgid binary, in which case it
+is ignored.
+.IP o
+From the cache file
+.BR /etc/ld.so.cache
+which contains a compiled list of candidate libraries previously found
+in the augmented library path.
+.IP o
+In the default path
+.BR /usr/lib ,
+and then
+.BR /lib .
+.SH ENVIRONMENT
+.TP
+.B LD_LIBRARY_PATH
+A colon-separated list of directories in which to search for
+ELF libraries at execution-time.
+Similar to the 
+.B PATH
+environment variable.
+.TP
+.B LD_PRELOAD
+A whitespace-separated list of additional, user-specified, ELF shared 
+libraries to be loaded before all others.
+This can be used to selectively override functions in other shared libraries.
+For setuid/setgid ELF binaries, only libraries in the standard search
+directories that are also setgid will be loaded.
+.TP
+.B LD_TRACE_LOADED_OBJECTS
+If present, causes the program to list its dynamic library dependencies,
+as if run by ldd, instead of running normally.
+.TP
+.B LD_BIND_NOW
+If present, causes the dynamic linker to resolve all symbols at program
+startup instead of when they are first referenced.
+.TP
+.B LD_AOUT_LIBRARY_PATH
+A colon-separated list of directories in which to search for
+a.out libraries at execution-time.
+Similar to the 
+.B PATH
+environment variable.
+.TP
+.B LD_AOUT_PRELOAD
+The name of an additional, user-specified, a.out shared library to be loaded 
+after all others.
+This can be used to selectively override functions in other shared libraries.
+.TP
+.B LD_NOWARN
+Suppress warnings about a.out libraries with incompatible minor 
+version numbers.
+.TP
+.B LD_KEEPDIR
+Don't ignore the directory in the names of a.out libraries to be loaded.
+Use of this option is strongly discouraged.
+.SH FILES
+.PD 0
+.TP 20
+.B /lib/ld.so
+a.out dynamic linker/loader
+.TP 20
+.B /lib/ld-linux.so.*
+ELF dynamic linker/loader
+.TP
+.B /etc/ld.so.cache
+File containing a compiled list of directories in which to search for
+libraries and an ordered list of candidate libraries.
+.TP
+.B /etc/ld.so.preload
+File containing a whitespace separated list of ELF shared libraries to
+be loaded before the program.
+libraries and an ordered list of candidate libraries.
+.TP
+.B lib*.so*
+shared libraries
+.PD
+.SH SEE ALSO
+.BR ldd (1),
+.BR ldconfig (8).
+.SH BUGS
+.LP
+Currently
+.B ld.so
+has no means of unloading and searching for compatible or newer version of
+libraries.
+.PP
+.B ld.so
+functionality is only available for executables compiled using libc version
+4.4.3 or greater.
+.SH AUTHORS
+David Engel, Eric Youngdale, Peter MacDonald, Hongjiu Lu, Linus
+Torvalds, Lars Wirzenius and Mitch D'Souza (not necessarily in that order).
diff -urN uClibc/ldso-0.9.24/man/ld.so.texi uClibc.ldso.24/ldso-0.9.24/man/ld.so.texi
--- uClibc/ldso-0.9.24/man/ld.so.texi	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/man/ld.so.texi	2001-04-23 12:43:54.000000000 -0500
@@ -0,0 +1,411 @@
+\input texinfo @c -*-texinfo-*-
+@c %**start of header
+@setfilename ld.so.info
+@settitle ld.so : Dynamic-Link Library support
+@c %**end of header
+
+@ifinfo
+This file documents the dynamic-link support libraries and utilities for the
+Linux OS, version 1.8.1.
+
+Copyright 1996 Michael Deutschmann
+
+This document is subject to the GNU General Public License as published by 
+the Free Software foundation, version 2 or later (your choice).
+
+Note: The software described in this document is under a different copyright
+and license.
+
+@end ifinfo
+
+@titlepage 
+@title ld.so
+@subtitle Dynamic Link library support for the Linux OS.
+@author David Engel
+@author Eric Youngdale
+@author Peter Macdonald 
+@author Hongjiu Lu 
+@author Mitch D'Souza
+@author Michael Deutschmann (this documentation)
+
+@page
+Copyright @copyright{} 1996 Michael Deutschmann
+
+This document is subject to the GNU General Public License as published by 
+the Free Software foundation, version 2 or later (your choice).
+
+Note: The software described in this document is under a different copyright
+and license.
+@end titlepage
+
+@ifinfo
+@node Top
+@top
+
+The @code{ld.so} module provides dynamic linked library support in Linux.
+This file documents @code{ld.so} and its companion software.
+
+@menu
+* intro::	Introduction
+
+* ld.so::	The dynamic linker core program
+* ldd::		A utility to print out dependencies
+* ldconfig::	A utility to maintain the cache and symlinks
+* libdl::	Manual dynamic linking library
+@end menu
+
+@end ifinfo
+
+@node intro
+@unnumbered Introduction
+
+The @code{ld.so} suite contains special files and utilities needed for linux
+to handle @dfn{dynamic libraries}.
+
+Ordinary static libraries (@file{lib*.a} files) are included into executables
+that use their functions. A file that only uses static libraries needs less
+intelligence to load, but takes up more space. If many executables use the
+same library, there can be much wastage of storage space, since multiple
+copies of the library functions are scattered across the executables.
+However, static libraries are easier to make.
+
+Dynamic libraries (@file{lib*.so*} files) are not copied into executables ---
+the executable is written in such a way that it will automatically load the
+libraries. In linux, the executable will first load the special library 
+@code{ld.so} or @code{ld-linux.so}, which contains the intelligence
+to load further dynamic libraries. Since multiple files end up getting
+executable data from the same file, dynamic libraries are also known as
+shared libraries.
+
+Linux executables come in two flavors, @sc{elf} and a.out.
+
+a.out is the original executable format used by Linux. It has somewhat less 
+overhead than @sc{elf}. However creating shared libraries for a.out is
+@emph{very} involved, and each a.out shared library must be explicitly 
+registered.
+ 
+@sc{elf} is a more recent format, which supports a much simpler method of
+creating libraries. @sc{elf} libraries may also be linked manually
+(@pxref{libdl}).
+
+Since many library authors prefer @sc{elf} and no longer release shared a.out 
+libraries, a.out is moribund on Linux. This version of the @code{ld.so} can
+be compiled to support only @sc{elf}, or to support both formats. (The last
+release of ld.so to support a.out alone was 1.8.0.)
+
+@node ld.so
+@chapter @code{ld.so}: Dynamic linker core
+
+@code{ld.so} works behind the scenes to handle dynamic libraries in Linux.
+Users will almost never have to deal with it directly, but in special cases
+one can send instructions to it through environment variables. Also, if
+something is wrong with your libraries (usually an incorrect version) ld.so
+will give error messages.
+
+Actually @code{ld.so} is the a.out linker. The new @sc{elf} executables are
+handled by a related program @code{ld-linux.so}.
+
+@menu
+* files::	Configuration files used by the suite
+* environment::	Environment settings that tweak @code{ld.so}
+* errors::	Complaints @code{ld.so} might make
+@end menu
+
+@node files
+@section Configuration Files
+
+@table @file
+@item /etc/ld.so.cache
+A file created by @code{ldconfig} and used to speed linking. It's structure
+is private to the suite.
+
+@item /etc/ld.so.conf
+A simple list of directories to scan for libraries, in addition to
+@file{/usr/lib} and @file{/lib}, which are hardwired. It may contain
+comments started with a @samp{#}.
+
+@item /etc/ld.so.preload
+A list of libraries to preload. This allows preloading libraries for
+setuid/setgid executables securely. It may contain comments. 
+@end table
+
+@node environment
+@section Environment Variables
+
+@table @code
+@item LD_AOUT_LIBRARY_PATH
+@itemx LD_LIBRARY_PATH
+These variables supply a library path for finding dynamic libraries, in the
+standard colon seperated format. These variables are ignored when executing 
+setuid/setgid programs, because otherwise they would be a security hazard. 
+@code{ld.so} will use @code{LD_AOUT_LIBRARY_PATH} and @code{ld-linux.so} will 
+use @code{LD_LIBRARY_PATH}.
+
+@item LD_AOUT_PRELOAD
+@itemx LD_PRELOAD
+These variables allow an extra library not specified in the executable to be
+loaded. Generally this is only useful if you want to override a function. 
+These are also ignored when running setuid/setgid executables. @code{ld.so} 
+will use @code{LD_AOUT_PRELOAD} and @code{ld-linux.so} will use 
+@code{LD_PRELOAD}.
+
+@item LD_NOWARN
+If non-empty, errors about incompatible minor revisions are suppressed.
+
+@item LD_KEEPDIR
+If non-empty, allow executables to specify absolute library names. This
+option is deprecated.
+@c FIXME:
+@c The following are things I noticed in the ld-linux.so source.
+@c I don't really understand 'em. Could someone help me?
+@c
+@c @item LD_BIND_NOW
+@c This option is used by the @code{ld-linux.so} only. I don't know 
+@c what it does. (I suspect, looking at the code, that it specifies
+@c "RTLD_NOW" rather than "RTLD_LAZY" mode for the shared libraries.)
+@c 
+@c @item LD_TRACE_LOADED_OBJECTS
+@c @itemx LD_WARN
+@c These seem to have something to do with the communication between the
+@c @code{ld-linux.so} and @code{ldd}. I don't know more.
+@end table
+
+@node errors
+@section Errors
+
+@table @samp
+@item Can't find library @var{library}
+The executable required a dynamically linked library that ld.so cannot find.
+Your symbolic links may be not set right, or you may have not installed a 
+library needed by the program.
+
+@item Can't load library @var{library}
+The library is corrupt. 
+
+@item Incompatible library @var{library}
+@itemx   Require major version @var{x} and found @var{y}
+Your version of the library is incompatible with the executable. Recompiling
+the executable, or upgrading the library will fix the problem.
+
+@item using incompatible library @var{library}
+@itemx   Desire minor version >= @var{x} and found @var{y}.
+Your version of the library is older than that expected by the executable,
+but not so old that the library interface has radically changed, so the
+linker will attempt to run anyway. There is a chance that it will work, but 
+you should upgrade the library or recompile the software. The environment 
+variable @code{LD_NOWARN} can be used to supress this message.
+
+@item too many directories in library path
+The linker only supports up to 32 library directories. You have too many.
+
+@item dynamic linker error in @var{blah}
+The linker is having trouble handling a binary - it is probably corrupt.
+
+@item can't map cache file @var{cache-file}
+@itemx cache file @var{cache-file} @var{blah}
+The linker cache file (generally @file{/etc/ld.so.cache}) is corrupt or
+non-existent. These errors can be ignored, and can be prevented by 
+regenerating the cache file with @code{ldconfig}.
+@end table
+
+@node ldd
+@chapter @code{ldd}: Dependency scanner
+
+@code{ldd} is a utility that prints out the dynamic libraries that an
+executable is linked to. 
+
+Actually @code{ldd} works by signalling ld.so to print the dependencies. 
+For a.out executables this is done by starting the executable with 
+@code{argc} equal to 0. The linker detects this and prints the dependencies. 
+(This can cause problems with @emph{very} old binaries, which would run as 
+normal only with an inappropriate @code{argc}.)
+
+For @sc{elf} executables, special environment variables are used to tell the
+linker to print the dependencies.
+
+@code{ldd} has a few options:
+
+@table @samp
+@item -v
+Print the version number of @code{ldd} itself
+
+@item -V
+Print the version number of the dynamic linker
+
+@item -d
+Report missing functions. This is only supported for @sc{elf} executables.
+
+@item -r
+Report missing objects. This is also only available for @sc{elf}
+executables.
+@end table
+
+@node ldconfig
+@chapter @code{ldconfig}: Setup program 
+
+This utility is used by the system administrator to automatically set up
+symbolic links needed by the libraries, and also to set up the cache file.
+
+@code{ldconfig} is run after new dynamic libraries are installed, and if the 
+cache file or links are damaged. It is also run when upgrading the
+@code{ld.so} suite itself.
+
+The @file{/lib} and @file{/usr/lib} directories, and any listed in the file 
+@file{/etc/ld.so.conf} are scanned by default unless @samp{-n} is used.
+Additional directories may be specified on the command line.
+
+It has the following options:
+
+@table @samp
+@item -D
+Enter debug mode. Implies @samp{-N} and @samp{-X}.
+
+@item -v
+Verbose. Print out links created and directories scanned.
+
+@item -n 
+Check directories specified on the commandline @emph{only}.
+
+@item -N
+Do not regenerate the cache.
+
+@item -X
+Do not rebuild symbolic links.
+
+@item -l
+Set up symbolic links for only libraries presented on the command line.
+
+@item -p
+Print out the library pathnames in the cache file (@file{/etc/ld.so.cache})
+@end table
+
+@node libdl
+@chapter User dynamic linking library
+
+The @code{ld.so} package includes a small library of functions
+(@code{libdl}) to allow manual dynamic linking. Normally programs are linked 
+so that dynamic functions and objects are automagically available. These 
+functions allow one to manually load and access a symbol from a library. 
+They are only available for @sc{elf} executables.
+
+@menu
+* using libdl::	General points
+* functions::	How to use the functions
+* example::	A sample program
+@end menu
+
+@node using libdl
+@section Overview
+
+To access this library, add the flag @samp{-ldl} to your compile command when
+linking the executable. You also must include the header file
+@code{dlfcn.h}. You may also need the flag @samp{-rdynamic}, which enables
+resolving references in the loaded libraries against your executable.
+
+Generally, you will first use @code{dlopen} to open a library. Then you use
+@code{dlsym} one or more times to access symbols. Finally you use
+@code{dlclose} to close the library.
+
+These facilities are most useful for language interpreters that provide
+access to external libraries. Without @code{libdl}, it would be neccessary
+to link the interpreter executable with any and all external libraries
+needed by the programs it runs. With @code{libdl}, the interpreter only 
+needs to be linked with the libraries it uses itself, and can dynamically 
+load in additional ones if programs need it.
+
+@node functions
+@section Functions
+
+@deftypefun void *dlopen ( const char @var{filename}, int @var{flags} )
+
+This function opens the dynamic library specified by @var{filename}
+and returns an abstract handle, which can be used in subsequent calls to 
+@code{dlsym}. The function will respect the @code{LD_ELF_LIBRARY_PATH} and
+@code{LD_LIBRARY_PATH} environment variables.
+
+@end deftypefun
+
+The following flags can be used with @code{dlopen}:
+
+@deftypevr Macro int RTLD_LAZY
+Resolve symbols in the library as they are needed.
+@end deftypevr
+
+@deftypevr Macro int RTLD_NOW
+Resolve all symbols in the library before returning, and fail if not all can
+be resolved. This is mutually exclusive with @code{RTLD_LAZY}.
+@end deftypevr
+
+@deftypevr Macro int RTLD_GLOBAL
+Make symbols in this library available for resolving symbols in other
+libraries loaded with @code{dlopen}.
+@end deftypevr
+
+@deftypefun int dlclose ( void *@var{handle} )
+
+This function releases a library handle.
+
+Note that if a library opened twice, the handle will be the same. However,
+a reference count is used, so you should still close the library as many 
+times as you open it.
+
+@end deftypefun
+
+@deftypefun void *dlsym (void *@var{handle},char *@var{symbol-name})
+
+This function looks up the name @var{symbol-name} in the library and returns
+it in the void pointer.
+
+If there is an error, a null pointer will be returned. However, it is
+possible for a valid name in the library to have a null value, so
+@code{dlerror} should be used to check if there was an error.
+
+@end deftypefun
+
+@deftypefun {libdl function} {const char} *dlerror( void )
+
+This function is used to read the error state. It returns a human-readable
+string describing the last error, or null, meaning no error.
+
+The function resets the error value each time it is called, so the result
+should be copied into a variable. If the function is called more than once
+after an error, the second and subsequent calls will return null.
+
+@end deftypefun
+
+@node example
+@section Example program
+
+Here is an example program that prints the cosine of two by manually linking
+to the math library:
+ 
+@example
+@c The following was snarfed verbatim from the dlopen.3 man file.
+#include <stdio.h>
+#include <dlfcn.h>
+
+int main(int argc, char **argv) @{
+    void *handle;
+    double (*cosine)(double);
+    char *error;
+
+    handle = dlopen ("/lib/libm.so", RTLD_LAZY);
+    if (!handle) @{
+        fputs (dlerror(), stderr);
+        exit(1);
+    @}
+
+    cosine = dlsym(handle, "cos");
+    if ((error = dlerror()) != NULL)  @{
+        fputs(error, stderr);
+        exit(1);
+    @}
+
+    printf ("%f\\n", (*cosine)(2.0));
+    dlclose(handle);
+@}
+@end example
+
+@contents
+
+@bye
diff -urN uClibc/ldso-0.9.24/man/ldconfig.8 uClibc.ldso.24/ldso-0.9.24/man/ldconfig.8
--- uClibc/ldso-0.9.24/man/ldconfig.8	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/man/ldconfig.8	2001-04-23 12:43:54.000000000 -0500
@@ -0,0 +1,189 @@
+.TH ldconfig 8 "14 March 1998"
+.SH NAME
+ldconfig \- determine run-time link bindings
+.SH SYNOPSIS
+ldconfig
+.RB [ \-DvqnNX ]
+.RB [ \-f\ conf ]
+.RB [ \-C\ cache ]
+.RB [ \-r\ root ]
+.IR directory \ ...
+.PD 0
+.PP
+.PD
+ldconfig
+.B \-l
+.RB [ \-Dvq ]
+.IR library \ ...
+.PD 0
+.PP
+.PD
+ldconfig
+.B \-p
+.SH DESCRIPTION
+.B ldconfig
+creates the necessary links and cache (for use by the run-time linker,
+.IR ld.so )
+to the most recent shared libraries found in the directories specified
+on the command line, in the file
+.IR /etc/ld.so.conf ,
+and in the trusted directories
+.RI ( /usr/lib
+and
+.IR /lib ).
+.B ldconfig
+checks the header and file names of the libraries it encounters when
+determining which versions should have their links updated.
+.B ldconfig
+ignores symbolic links when scanning for libraries. 
+.PP
+.B ldconfig
+will attempt to deduce the type of ELF libs (ie. libc5 or libc6/glibc)
+based on what C libs if any the library was linked against, therefore when
+making dynamic libraries, it is wise to explicitly link against libc (use -lc).
+.PP
+Some existing libs do not contain enough information to allow the deduction of 
+their type, therefore the 
+.IR /etc/ld.so.conf 
+file format allows the specification of an expected type.  This is 
+.B only
+used for those ELF libs which we can not work out. The format 
+is like this "dirname=TYPE", where type can be libc4, libc5 or libc6.
+(This syntax also works on the command line).  Spaces are 
+.B not 
+allowed.  Also see the 
+.B -p 
+option.
+.PP 
+Directory names containing an
+.B = are no longer legal
+unless they also have an expected type specifier.
+.PP
+.B ldconfig
+should normally be run by the super-user as it may require write 
+permission on some root owned directories and files.
+It is normally run automatically at bootup, from /etc/rc, or manually
+whenever new DLL's are installed.
+.SH OPTIONS
+.TP
+.B \-D
+Debug mode.
+Implies
+.B \-N
+and
+.BR \-X .
+.TP
+.B \-v
+Verbose mode.
+Print current version number, the name of each directory as it
+is scanned and any links that are created.
+Overrides quiet mode.
+.TP
+.B \-q
+Quiet mode.
+Don't print warnings.
+.TP
+.B \-n
+Only process directories specified on the command line.
+Don't process the trusted directories
+.RI ( /usr/lib
+and
+.IR /lib )
+nor those specified in
+.IR /etc/ld.so.conf .
+Implies
+.BR \-N .
+.TP
+.B \-N
+Don't rebuild the cache.
+Unless
+.B \-X
+is also specified, links are still updated.
+.TP
+.B \-X
+Don't update links.
+Unless
+.B \-N
+is also specified, the cache is still rebuilt.
+.TP
+.B \-f conf
+Use
+.B conf
+instead of
+.IR /etc/ld.so.conf .
+.TP
+.B \-C cache
+Use
+.B cache
+instead of
+.IR /etc/ld.so.cache .
+.TP
+.B \-r root
+Change to and use
+.B root
+as the root directory.
+.TP
+.B \-l
+Library mode.
+Manually link individual libraries.
+Intended for use by experts only.
+.TP
+.B \-p
+Print the lists of directories and candidate libraries stored in
+the current cache.
+.SH EXAMPLES
+In the bootup file
+.I /etc/rc
+having the line
+.RS
+
+/sbin/ldconfig -v
+
+.RE
+will set up the correct links for the shared binaries and rebuild
+the cache.
+.TP
+On the command line
+.RS
+
+# /sbin/ldconfig -n /lib
+
+.RE
+as root after the installation of a new DLL, will properly update the
+shared library symbolic links in /lib.
+
+.SH FILES
+.PD 0
+.TP 20
+.B /lib/ld.so
+execution time linker/loader
+.TP 20
+.B /etc/ld.so.conf
+File containing a list of colon, space, tab, newline, or comma spearated
+directories in which to search for libraries.
+.TP 20
+.B /etc/ld.so.cache
+File containing an ordered list of libraries found in the directories
+specified in
+.BR /etc/ld.so.conf .
+.TP
+.B lib*.so.version
+shared libraries
+.PD
+.SH SEE ALSO
+.BR ldd (1),
+.BR ld.so (8).
+.SH BUGS
+.LP
+.BR ldconfig 's
+functionality, in conjunction with
+.BR ld.so ,
+is only available for executables compiled using libc version 4.4.3 or greater.
+.PP
+.BR ldconfig ,
+being a user process, must be run manually and has no means of dynamically
+determining and relinking shared libraries for use by
+.BR ld.so
+when a new DLL is installed.
+.SH AUTHORS
+David Engel and Mitch D'Souza.
diff -urN uClibc/ldso-0.9.24/man/ldd.1 uClibc.ldso.24/ldso-0.9.24/man/ldd.1
--- uClibc/ldso-0.9.24/man/ldd.1	1969-12-31 18:00:00.000000000 -0600
+++ uClibc.ldso.24/ldso-0.9.24/man/ldd.1	2001-04-23 12:43:54.000000000 -0500
@@ -0,0 +1,59 @@
+.\" Copyright 1995-2000 David Engel (david@ods.com)
+.\" Copyright 1995 Rickard E. Faith (faith@cs.unc.edu)
+.\" Most of this was copied from the README file.  Do not restrict distribution.
+.\" May be distributed under the GNU General Public License
+.TH LDD 1 "14 March 1998"
+.SH NAME
+ldd \- print shared library dependencies
+.SH SYNOPSIS
+.B ldd
+.RB [ \-vVdr ]
+program|library ...
+.SH DESCRIPTION
+.B ldd
+prints the shared libraries required by each program or shared library
+specified on the command line.
+If a shared library name does not contain a '/',
+.B ldd
+attempts to locate the library in the standard locations.
+To run
+.B ldd
+on a shared library in the current directory, a "./" must be prepended
+to its name.
+.SH OPTIONS
+.TP
+.B \-v
+Print the version number of
+.BR ldd .
+.TP
+.B \-V
+Print the version number of the dynamic linker,
+.BR ld.so .
+.TP
+.B \-d
+Perform relocations and report any missing functions (ELF only).
+.TP
+.B \-r
+Perform relocations for both data objects and functions, and
+report any missing objects (ELF only).
+.SH BUGS
+.B ldd
+does not work very well on libc.so.5 itself.
+.PP
+.B ldd
+does not work on a.out shared libraries.
+.PP
+.B ldd
+does not work with some extremely old a.out programs which were 
+built before
+.B ldd
+support was added to the compiler releases.
+If you use
+.B ldd
+on one of these programs, the program will attempt to run with argc = 0 and
+the results will be unpredictable.
+.SH AUTHOR
+David Engel.
+.SH SEE ALSO
+.BR ldconfig (8),
+.BR ld.so (8).
