diff options
author | Eric Andersen <andersen@codepoet.org> | 2004-07-20 11:43:54 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2004-07-20 11:43:54 +0000 |
commit | ae5d1e62537d415ef375a1b6484c70a6fd270428 (patch) | |
tree | 3d8b961439b344cf2e674100eb90b57137efcb75 /sources | |
parent | bd66295fa1c58b4f0e55eb4c484c3916607c5d91 (diff) | |
download | buildroot-novena-ae5d1e62537d415ef375a1b6484c70a6fd270428.tar.gz buildroot-novena-ae5d1e62537d415ef375a1b6484c70a6fd270428.zip |
Remove the unnecessary USE_UCLIBC_LDSO_0_9_24 option
Diffstat (limited to 'sources')
-rw-r--r-- | sources/uClibc-ldso-0.9.24.patch | 11861 |
1 files changed, 0 insertions, 11861 deletions
diff --git a/sources/uClibc-ldso-0.9.24.patch b/sources/uClibc-ldso-0.9.24.patch deleted file mode 100644 index ee65aa193..000000000 --- a/sources/uClibc-ldso-0.9.24.patch +++ /dev/null @@ -1,11861 +0,0 @@ -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). |