1 diff -urN uClibc/ldso-0.9.24/COPYRIGHT uClibc.ldso.24/ldso-0.9.24/COPYRIGHT
2 --- uClibc/ldso-0.9.24/COPYRIGHT 1969-12-31 18:00:00.000000000 -0600
3 +++ uClibc.ldso.24/ldso-0.9.24/COPYRIGHT 2001-04-23 12:43:53.000000000 -0500
6 + * Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald, David Engel,
7 + * Hongjiu Lu and Mitch D'Souza
9 + * All rights reserved.
11 + * Redistribution and use in source and binary forms, with or without
12 + * modification, are permitted provided that the following conditions
14 + * 1. Redistributions of source code must retain the above copyright
15 + * notice, this list of conditions and the following disclaimer.
16 + * 2. The name of the above contributors may not be
17 + * used to endorse or promote products derived from this software
18 + * without specific prior written permission.
20 + * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
21 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 + * ARE DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE
24 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 +/* Notice of general intent:
35 + * The linux operating system generally contains large amounts of code
36 + * that fall under the GNU General Public License, or GPL for short.
37 + * This file contains source code that by it's very nature would always
38 + * be linked with an application program, and because of this a GPL
39 + * type of copyright on this file would place restrictions upon the
40 + * distribution of binary-only commercial software. Since the goal of
41 + * the Linux project as a whole is not to discourage the development and
42 + * distribution of commercial software for Linux, this file has been
43 + * placed under a more relaxed BSD-style of copyright.
45 + * It is the general understanding of the above contributors that a
46 + * program executable linked to a library containing code that falls
47 + * under the GPL or GLPL style of license is not subject to the terms of
48 + * the GPL or GLPL license if the program executable(s) that are supplied
49 + * are linked to a shared library form of the GPL or GLPL library, and as
50 + * long as the form of the shared library is such that it is possible for
51 + * the end user to modify and rebuild the library and use it in
52 + * conjunction with the program executable.
54 diff -urN uClibc/ldso-0.9.24/Makefile uClibc.ldso.24/ldso-0.9.24/Makefile
55 --- uClibc/ldso-0.9.24/Makefile 1969-12-31 18:00:00.000000000 -0600
56 +++ uClibc.ldso.24/ldso-0.9.24/Makefile 2003-11-06 16:38:45.000000000 -0600
58 +# Makefile for uClibc
60 +# Copyright (C) 2000,2001 Erik Andersen <andersen@uclibc.org>
62 +# This program is free software; you can redistribute it and/or modify it under
63 +# the terms of the GNU Library General Public License as published by the Free
64 +# Software Foundation; either version 2 of the License, or (at your option) any
67 +# This program is distributed in the hope that it will be useful, but WITHOUT
68 +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
69 +# FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more
72 +# You should have received a copy of the GNU Library General Public License
73 +# along with this program; if not, write to the Free Software Foundation, Inc.,
74 +# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
76 +# Derived in part from the Linux-8086 C library, the GNU C Library, and several
77 +# other sundry sources. Files within this library are copyright by their
78 +# respective copyright holders.
81 +include $(TOPDIR)Rules.mak
83 +ALL_SUBDIRS = ldso libdl
87 +ifeq ($(strip $(BUILD_UCLIBC_LDSO)),y)
90 + echo "Not building ld-uClibc"
94 +ifeq ($(strip $(BUILD_UCLIBC_LDSO)),y)
97 + echo "Not building libdl"
101 + $(LN) -fs $(TOPDIR)../include/elf.h include/
102 + $(LN) -fs ../ldso/$(TARGET_ARCH)/boot1_arch.h include/
103 + $(LN) -fs ../ldso/$(TARGET_ARCH)/ld_syscalls.h include/
104 + $(LN) -fs ../ldso/$(TARGET_ARCH)/ld_sysdep.h include/
107 + set -e ; for d in $(ALL_SUBDIRS) ; do $(MAKE) -C $$d $@ ; done
108 + -find . -name '*~' | xargs $(RM)
109 + $(RM) include/elf.h include/boot1_arch.h include/ld_syscalls.h include/ld_sysdep.h
110 diff -urN uClibc/ldso-0.9.24/README uClibc.ldso.24/ldso-0.9.24/README
111 --- uClibc/ldso-0.9.24/README 1969-12-31 18:00:00.000000000 -0600
112 +++ uClibc.ldso.24/ldso-0.9.24/README 2001-05-31 16:23:20.000000000 -0500
115 +Apr 20, 2001 -- Manuel Novoa III
117 +Inital port for uClibc from debian ld.so_1.9.11-9.tar.gz.
119 +Removed a.out support.
121 +****************** original ld.so.lsm file **************************
123 +Title: Linux shared, dynamic linker and utilities.
125 +Entered-date: 01MAY99
126 +Description: This package contains ld.so, ld-linux.so, ldconfig,
128 +Keywords: dynamic linker, shared library, ld.so, ld-linux.so,
129 + ldconfig, ldd, libdl
130 +Author: david@ods.com (David Engel)
131 +Maintained-by: david@ods.com (David Engel)
132 +Primary-site: tsx-11.mit.edu /pub/linux/packages/GCC
133 + ld.so-1.9.11.tar.gz
134 +Alternate-site: sunsite.unc.edu /pub/Linux/GCC
135 + ld.so-1.9.11.tar.gz
136 +Platform: Linux 2.0.0 or later.
137 +Copying-policy: Copyrighted but freely distributable.
139 +*********************************************************************
140 + Original README starts here
141 +*********************************************************************
143 +This package contains my ELF dynamic linkers (ld-linux.so.1), dynamic
144 +linker library (libdl.so.1) and utilities (ldconfig and ldd) for Linux.
146 +You need Linux kernel 2.0.0 or later with ELF support compiled in
147 +(i.e. not loaded as a module) to use this package.
149 +The dynamic linker is used to bootstrap programs and load shared
150 +libraries at startup. The dynamic linker library is used to
151 +dynamically load shared libraries after a program is running.
152 +Ldconfig is used to automatically update the symbolic links to shared
153 +libraries and build the cache file used by the dynamic linker. Ldd is
154 +used to list the shared libraries used by a program.
156 +Please see the included manual pages for further details.
158 +To install, simply run "sh instldso.sh" as root. Ready-to-go versions
159 +of all end-products are provided so nothing should need to be compiled
160 +or linked. If you are still using libc5 as your primary development
161 +library, you should use the "--devfiles" option when running
162 +instldso.sh to install the file needed to compile with libdl.
164 +ELF versions of gcc, binutils and libc are now required to compile
165 +everything, including the old, unsupported, a.out dynamic linker.
166 +Finally, an optimization level of O2 or higher must be used to compile
167 +ld-linux.so and libdl.so due the use of inline functions.
169 +Notable contributors to this package include Eric Youngdale, Peter
170 +MacDonald, Hongjiu Lu, Linus Torvalds, Lars Wirzenius, Mitch D'Souza,
171 +Rik Faith, Andreas Schwab and Adam Richter (not necessarily in that
174 +###################### IMPORTANT NOTICES #############################
178 +As of ld.so-1.9.0, the old, a.out dynamic loader is no longer
179 +officially supported. The code is still included and built, but I
180 +make no promises that it will work. I will accept patches for it,
181 +but they will not be tested by me.
183 +GLIBC (AKA LIBC6) SUPPORT:
185 +As of ld.so-1.9.0, the main focus of this package is to ease the
186 +transition to libc6. No significant, new features are expected to be
187 +added. If you need new features, switch to libc6.
189 +Except for libpthread.so, the sonames of the core libraries provided
190 +with libc6 have been chosen so they do not conflict with those
191 +provided by libc5 and ld.so. However, the current plan is not use
192 +new, nonconflicting sonames for other libraries such as ncurses and
193 +X11. This presents two problems. First, libraries using the same
194 +soname for both libc5 and libc6 can not be placed in the same
195 +directory. Second, the dynamic linkers need to make sure not to load
196 +a library for the wrong version of libc.
198 +The first problem is easy. Just move the old, libc5-based libraries
199 +to new directories (e.g. /lib/libc5-compat, /usr/lib/libc5-compat,
200 +etc.) and add those directories to /etc/ld.so.conf. Then install the
201 +new, libc6-based versions in the standard places.
203 +The second problem is more difficult. Ideally, the dynamic linkers
204 +would be changed to perform a complete dependency analysis on every
205 +library to be loaded to make sure the wrong versions aren't used.
206 +This approach doesn't seem worth the added complexity, especially
207 +since we now have symbol versioning for ELF libraries. Instead a
208 +simpler approach will be used, at least initially.
210 +Ldconfig has been modified to perform a (currently simple) dependency
211 +analysis on libraries and to store an indication in /etc/ld.so.cache
212 +of whether a library is for libc5, libc6 or an unknown libc. The
213 +dynamic linkers then only need to make a simple check at run-time to
214 +make sure they don't load the wrong version of a library.
216 +The dynamic linker for libc5 provided in this package, has already
217 +been modified to use the new information in /etc/ld.so.cache. For
218 +glibc versions 2.0.1 and earlier, the dynamic linker for libc6 needs
219 +the patch contained in glibc.patch. You should apply the patch and
220 +rebuild glibc before using the new ldconfig.
222 +As stated above, the dependency analysis currently done by ldconfig is
223 +rather simple. Basically, it looks for the sonames used by the
224 +various versions of libc, libm and libdl. For any approach using a
225 +dependency analysis such as this to work, it is very important that
226 +shared libraries be built with complete dependency information. This
227 +can be done by using the appropriate -l options when running 'gcc
228 +-shared'. For example, when building libfoo.so which depends on libc
229 +and libbar, you should add -lbar and -lc gcc command line.
231 +######################################################################
233 +Changes in version 1.9.11:
235 + Fixed a bug in ld-linux.so where a reference to an
236 + undefined symbol could cause a segfault.
238 + Added a clarification for LD_PRELOAD to the ld.so manual
239 + page and added a symlink for ld-linux.so (Bug#33123).
241 + Don't install ldd for Debian except for the m68k arch
242 + because glibc 2.1 now includes it (Bug#35458).
244 +Changes in version 1.9.10:
246 + Changed ldconfig to issue a warning and not overwrite a
247 + regular file with a symlink (Bug#30859).
249 + Changed Debian packaging to conflict with and replace the
250 + ldconfig package (Bug#29398).
252 +Changes in version 1.9.9:
254 + Changed ld-linux.so and libdl.so to match glibc by not
255 + allowing user preloads of system libraries into setu/gid
256 + binaries unless the library itself is setuid.
258 + Fixed problems in ld-linux.so on the sparc architecture
261 +Changes in version 1.9.8:
263 + Changed ldconfig to allow the expected type for all
264 + libraries in a directory to be optionally specified
265 + (Mark Phillips). See the ldconfig man page.
267 + Changed ldconfig to use the same type names used in the
268 + change above when the -p option is used.
270 +Changes in version 1.9.7:
272 + Changed ldd for m68k to use /lib/ld.so.1 instead of
273 + /lib/ld-linux.so.2.
275 + Added support for dladdr to libdl.so (Eduard Gode).
277 + Fixed a small memory leak in libdl.so (Richard Garnish).
279 + Fixed a bug in ldconfig when the -l option was used on a
280 + filename without a '/' in it.
282 + Updated the man pages (Bug#6404, Bug#9721, Bug#10652,
283 + Bug#13494 and Bug#14127). They could still use some work.
285 + No longer install the info page since it's way out of date.
287 + Fixed minor Debian packaging problems (Bug#13160,
288 + Bug#15577 and Bug#19345).
290 +Changes in version 1.9.6:
292 + Changed ldd to not use the glibc dynamic linker when run
293 + on a libc5-based shared library.
295 + Added a -q option to ldconfig which causes warnings not
296 + to be printed (Bob Tinsley).
298 + Dropped support for the Debian libdl1-dev package.
300 + Changed ld-linux.so to be compilable with gcc 2.8.0 (Sven
303 +Changes in version 1.9.5:
305 + Fixed a bug in ldd where ld-linux.so.2 was not called
306 + correctly when run on shared libraries.
308 + Fixed a problem in the previous version where some
309 + Makefiles were not architecture independent.
311 +Changes in version 1.9.4:
313 + Fixed a bug in ld.so introduced in the previous version
314 + which broke preloads.
316 + Turned a.out support back on by default, at least for the
317 + time being. There are no promises to keep it.
319 +Changes in version 1.9.3:
321 + Fixed buffer overflow bugs in ld-linux.so and ld.so.
323 + Changed the README file a little to clarify a couple of
326 + Changed ldconfig to chroot to the specified directory when
327 + the new -r option is used (Bob Tinsley).
329 +Changes in version 1.9.2:
331 + Removed /usr/local/lib from the default /etc/ld.so.conf
332 + for Debian (Bug#8181).
334 + Changed ldconfig to be 64-bit clean (H.J. Lu).
336 +Changes in version 1.9.1:
338 + Changed ldconfig to try to determine which libc a
339 + library is for even if it doesn't have an soname.
341 + Fixed a bug in ldconfig where an older library using
342 + the glibc naming convention would be used instead of
345 + Changed to ld-linux.so and libdl.so to not require the
346 + libc5 headers in order to compile.
348 + Changed ldconfig and ldd to be compilable with either
351 +Changes in version 1.9.0:
353 + Changed to not build the old, a.out dynamic loader by
356 + Changed instldso.sh to require the --force option to
357 + make sure users read the README file.
359 + Changed instldso.sh to not install the libdl.so
360 + development files unless the --devfiles option is used.
362 + Changed instldso.sh to not strip binaries and libraries
363 + if the --no-strip option is used.
365 + Changed the Debian packaging to put the development files
366 + which conflict with glibc in a new libdl1-dev package.
368 + Changed ldd to use the glibc dynamic linker, if it is
369 + available, when run on a shared library.
371 + Changed ld-linux.so to print the load addresses of
372 + libraries, ala glibc, when run by ldd.
374 + Changed ld-linux.so to allow the libraries listed in
375 + LD_PRELOAD to be separated by white space in addition to
378 + Changed ld-linux.so to load the libraries listed in
379 + LD_PRELOAD for setu/gid programs as long as they can be
382 + Changed ldconfig to update the symlinks for the dynamic
385 + Changed ldconfig to try to determine if an ELF library is
386 + intended for libc5 or libc6 and save the infomation in the
387 + cache. The mechanism used is rather simplistic and may
388 + need to be enhanced.
390 + Changed ldconfig to print the type of ELF library when
391 + printing the cache.
393 + Changed ld-linux.so to only load ELF shared libraries for
394 + use with libc5 or an unknown libc.
396 +Changes in version 1.8.10:
398 + Fixed a bug in ldconfig where a symlink could be used
399 + instead of a regular file.
401 + Fixed a Debian packaging problem for the sparc
404 +Changes in version 1.8.9:
406 + Changed ldconfig to only cache the symlinks it creates.
407 + This make the behavior of the dynamic linkers consistent
408 + with how they would behave if a cache was not used.
410 + Changed ldconfig to cache the symlinks that it finds but
411 + use the name of the symlink as the soname instead of the
414 +Changes in version 1.8.8:
416 + Minor documentation updates to reflect recent changes.
418 + Changed ld.so and ld-linux.so to perform more complete
419 + validation on ld.so.cache before using it.
421 + Changed ldconfig to accept libraries with inconsistent
422 + sonames since glibc is going to use them. A warning is
423 + still printed in debug mode.
425 + Changed the install script to not strip _dl_debug_state
426 + from ld-linux.so since gdb needs it.
428 + More sparc fixes (Derrick Brashear).
430 + Changed ldconfig to not issue a warning when a linker
431 + script disguised as a shared library is found.
433 + Fixed a bug in ld-linux.so where some registers were
434 + not preserved on the first call to a function causing
435 + problems for non-C-like languages (Tim Renouf).
437 + Fixed a bug in ld-linux.so where global variables were
438 + not always mapped correctly across dynamically loaded
439 + libraries (Mikihiko Nakao).
441 + Converted to new Debian source packaging format (Shaya
444 +Changes in version 1.8.6/7:
446 + Never released as some unofficial patches used these
449 +Changes in version 1.8.5:
451 + Fixed a bug in ld.so introduced in the previous changes.
453 +Changes in version 1.8.4:
455 + Changed ldconfig to completely ignore symbolic links.
457 + Changed ldconfig to issue the warning concerning an
458 + inconsistent soname in non-verbose mode.
460 + Changed ld-linux.so back to not keep ld.so.cache mapped
463 + Changed Debian packaging to compress man pages, strip all
464 + binaries (Bug#5125) and include a shlibs file.
466 +Changes in version 1.8.3:
468 + Changed ld-linux.so to process LD_PRELOAD before
469 + /etc/ld.so.preload.
471 + Fixed a Debian packaging problem where libdl might not
472 + be available if other packages were upgraded at the same
473 + time (Debian Bug#4728).
475 + Changed ldd to always exit with status 1 if any errors
476 + occur (Debian Bug#4188).
478 + Fixed some minor problems in instldso.sh (Mike Castle and
481 + Changed ldconfig to issue a warning in verbose mode when
482 + skipping a library because the soname doesn't match.
484 + More sparc fixes (Miguel de Icaza).
486 + Don't link with -N when building ld.so (Alan Modra).
488 + Changed ld-linux.so to better support position-dependant
489 + libraries (NIIBE Yutaka).
491 +Changes in version 1.8.2:
493 + Added a texinfo file for ld.so and libdl (Michael
496 + Minor sparc and installation changes (Elliot Lee).
498 + Added multiple architecture support for Debian (Leland
501 + Changed libdl to better support RTLD_NEXT (Eric
502 + Youngdale). Note: the exact meaning of ETLD_NEXT is
503 + still not clear in all cases.
505 + Removed some libc dependencies from libdl. Still need
506 + to remove malloc and free.
508 +Changes in version 1.8.1:
510 + Changed ld.so to be compiled as ELF. This also means
511 + that ELF support is now required. A.out support is
514 + Changed ld-linux.so and libdl.so to use the rpath in the
515 + executable instead of in the invoking shared library.
517 + More m68k fixes (Andreas Schwab).
519 + Various sparc fixes (Miguel de Icaza).
521 + Changed ldcnnfig to ignore libraries ending in '~'.
523 + Changed ldconfig to allow alternative conf and cache
524 + files to be specified on the command-line.
526 + Changed libdl.so to work when dlsym is passed a NULL
529 +Changes in version 1.8.0:
531 + Changed ld-linux.so to be more liberal when checking to
532 + see if a library is already loaded. This should avoid
533 + the duplicate loading problem for programs linkeed with
536 + Various m68k fixes (Andreas Schwab).
538 + Changed ld.so to only use LD_AOUT_LIBRARY_PATH and
539 + LD_AOUT_PRELOAD and ld-linux.so to only use
540 + LD_LIBRARY_PATH and LD_PRELOAD. LD_ELF_LIBRARY_PATH
541 + and LD_ELF_PRELOAD are no longer supported.
543 + Changed ld-linux.so to allow debugging of shared and
544 + dynamically loaded libraries (H.J. Lu, Andreas Schwab).
546 + Changed ld-linux.so to preload ELF shared libraries
547 + listed in /etc/ld.so.preload. This allows secure
548 + preloads, even for setuid/setgid programs.
550 + Changed ld-linux.so to keep ld.so.cache mapped at all
553 + Changed ldconfig to allow #-style comments in ld.so.conf.
555 + Removed various compiler warnings (Richard Sladkey and
558 + Changed ldd to work on ELF shared libraries. This may
559 + need a little more work.
561 +Changes in version 1.7.14:
563 + Changed ldconfig to recognize ELF shared libraries
564 + generated by post-2.6 versions of ld (Andreas Schwab).
566 + Changed ldconfig to not remove stale links that do not
567 + have a version number since they may be needed by ld.
569 +Changes in version 1.7.13:
571 + Fixed a problem in ld-linux.so where a program linked
572 + with a shared library that was not used could result in
573 + a segmentation fault (H.J. Lu).
575 +Changes in version 1.7.12:
577 + Fixed a problem in libdl.so where the wrong library
578 + could be marked as global when RTLD_GLOBAL was used
581 + Installed dlfcn.h with libdl.so instead of requiring
582 + it to be supplied with libc.
584 + Removed support for libldso.a since it was nearly
585 + impossible to use anyway.
587 + Changed ldd to detect when the program being checked
590 +Changes in version 1.7.11:
592 + Changed ld.so and ld-linux.so to delete all variations
593 + of LD_PRELOAD and LD_LIBRARY_PATH for set[ug]id programs,
594 + This makes it harder for broken set[ug]id programs to be
597 + Fixed a problem in libdl.so where dlsym would not accept
598 + the handle returned from dlopen(0, *).
600 +Changes in version 1.7.10:
602 + Changed ld-linux.so and libdl.so to support RTLD_GLOBAL
605 +Changes in version 1.7.9:
607 + Fixed a problem in ld-linux.so in detecting when the
608 + new user/group information is provided by the kernel.
610 + Fixed a problem in ld-linux.so where a buffer could be
611 + overflowed if a large number of libraries were loaded
614 +Changes in version 1.7.8:
616 + Changed the Makefiles and install scripts to support
617 + a.out- and ELF-only configurations.
619 + Changed ld-linux.so to use the user/group information
620 + provided by linux 1.3.23+ instead of making syscalls
623 + Changed libdl.so to support RTLD_NEXT (Glenn Fowler).
625 + Changed libdl.so to only execute the fini sections
626 + instead of completely closing libraries at exit (Glenn
629 + Changed ld.so and ld-linux.so to print the required
630 + cache version when a mismatch is detected.
632 + Changed ld-linux.so to not require on /dev/zero (Ralph
635 + Minor m68k cleanups (Andreas Schwab).
637 +Changes in version 1.7.7:
639 + Fixed problems compiling with recent 1.3.x kernels.
641 + Changed ld-linux.so to not use MAP_DENYWRITE until the
642 + permission issue regarding it is resolved.
644 +Changes in version 1.7.6:
646 + Fixed a bug in ld-linux.so dealing with a zero-length
649 + Changed ld.so and ld-linux.so to truncate all variations
650 + of LD_PRELOAD and LD_LIBRARY_PATH for set[ug]id programs.
652 +Changes in version 1.7.5:
654 + Changed ldconfig to recognize libraries without any
655 + version number (eg. libXYZ.so).
657 + Changed ldconfig to not generate a corrupt cache when
658 + the disk is full or other write errors occur.
660 + Changed ld-linux.so to map files with MAP_DENYWRITE to
661 + keep them from being changed while the file is in use
664 + Changed libdl to not overwrite the scope pointer of a
665 + library if it was already loaded (H.J. Lu).
667 + Changed ld-linux.so so gdb can be used on constructors
670 + Changed ldconfig to ignore ELF libraries where the soname
671 + does not match the file name on the assumption that it is
672 + a used at compile-time (eg. libcurses.so -> libncruses.so).
674 +Changes in version 1.7.4:
676 + Changed ld-linux.so and libdl to use the appropriate
677 + rpaths when searching for shared libraries (Eric
680 + Changed ld-linux.so to search rpath before using the
681 + cache. This more closely conforms to the IBCS standard.
683 +Changes in version 1.7.3:
685 + Changed ld-linux.so to only print a library name the
686 + first time it is loaded when run from ldd.
688 + Fixed a bug in ldconfig where an invalid cache could be
689 + generated if a directory was specified multiple times in
692 + Changed ld-linux.so so it will return the address of a
693 + weak symbol when called from dlsym in libdl (Eric
696 +Changes in version 1.7.2:
698 + Changed libdl.so again to fix the undefined foobar
701 +Changes in version 1.7.1:
703 + Changed libdl so it will compile at optimization level
706 + Changed ldconfig to always create the cache file with
709 + Changed ldconfig to not ingore valid symlinks.
711 + Changed ldconfig to use the library name as the soname
712 + for ELF libraries that do not have an soname entry.
714 + Changed ld-linux.so to print the actual, requested library
715 + name at the time it is loaded instead of trying to figure
716 + it out after the fact.
718 +Changes in version 1.7.0:
720 + Changed ldconfig to read the actual soname from the image
721 + for ELF libraries and make it available to ld-linux.so.
722 + The soname for DLL libraries is still determined by
723 + truncating the minor numbers from the image file name.
725 + Changed ldconfig to no longer support the undocumented
728 + Changed ld.so to require a valid cache to find libraries
729 + in directories specified in ld.so.conf. /usr/lib and /lib
730 + are still searched as a last resort. Ld-linux.so already
733 + Fixed a bug in libldso.a where the arguments to
734 + shared_loader were not parsed correctly (Wolfram Gloger).
736 + Added support for RELA-style relocations under Linux/68k
739 + Changed ld-linux.so to only map the cache once for all
740 + libraries instead of individually for each library.
742 + Changed ld-linux.so continue searching the cache instead of
743 + giving up when failing to load the first entry found.
745 + Changed ld-linux.so to produce output similar to ld.so when
746 + run from ldd or when errors occur.
748 +Changes in version 1.6.7:
750 + Changed the install scripts to make sure that ld.so and
751 + ld-linux.so are always usable.
753 + Added support for Linux/Sparc (Eric Youngdale).
755 + Added support for Linux/68k (Andreas Schwab).
757 + Fixed various bugs in ld-linux.so dealing with closing
758 + files, unmapping memory, dereferencing NULL pointers and
759 + printing library names (David Engel, Eric Youngdale and
762 + Replaced the manual page for libdl with a freely
763 + distributable one (Adam Richter).
765 + Fixed a bug in ld-linux.so where LD_LIBRARY_PATH and
766 + LD_PRELOAD were not cleared for setuid/setgid programs.
768 + Fixed a bug in libdl where dlsym would not return the
769 + correct address of a symbol if it was redefined in another
770 + library (Oleg Kibirev).
772 + Changed ld-linux.so to use the following order to search
773 + for libraries: LD_{ELF_}LIBRARY_PATH, ld.so.cache, rpath,
776 + Changed ld-linux.so to not needlessly allocate memory when
779 +Changes in version 1.6.6:
781 + Changed ldconfig to not warn about removing stale links
782 + unless the -v option is specified.
784 + Added manual pages for libdl (from FreeBSD/Sun)
786 + Fixed a bug in ld.so dealing with preloading of objects
787 + generated by recent versions of ld (Mitch D'Souza).
789 + Fixed bugs in ldd where some errors were either not
790 + detected or not printed.
792 + Fixed a bug in ld-linux.so where the trailing nul in a
793 + library name was not being copied (Owen Taylor).
795 +Changes in version 1.6.5:
797 + Changed ldconfig to remove stale symbolic links.
799 + Added debug hooks in ld-linux.so and libdl.so to be used
800 + by a future version of gdb (Eric Youngdale).
802 +Changes in version 1.6.4:
804 + Change ld-linux.so to print on stdout instead of stderr
807 + Added support for Debian GNU/Linux packaging.
809 +Changes in version 1.6.3:
811 + Fixed a bug in libdl when closing a library (H.J. Lu).
813 +Changes in version 1.6.2:
815 + Changed the error message printed by ldd when a file is
816 + not a.out or ELF. It used to only list a.out formats.
818 + Changed ldconfig to no longer cache and set up links for
821 + Changed ld-linux.so and libdl to not conflict with upcoming
822 + changes in kernel header files.
824 + Changed ld-linux.so to not print preloaded libraries.
826 +Changes in version 1.6.1:
828 + Updated the installation script.
830 + Changed ld.so and ld-linux.so to look for LD_AOUT_PRELOAD
831 + and LD_ELF_PRELOAD, respectively, before LD_PRELOAD.
833 + Changed ld.so and ld-linux.so to use LD_AOUT_LIBRARY_PATH
834 + and LD_ELF_LIBRARY_PATH, respectively, instead of
835 + AOUT_LD_LIBRARY_PATH and ELF_LD_LIBRARY_PATH.
837 +Changes in version 1.6.0:
839 + Changed ldconfig to process libraries which do not have
840 + a minor version or patch level number.
842 + Incorporated ld-linux.so and libdl.so.
844 + Changed ld.so and ld-linux.so to not miss entries in the
845 + cache when the fully qualified library is requested.
847 + Changed ldconfig to use stdout instead of stderr when
848 + printing the cache.
850 +Changes in version 1.5.3:
852 + LD_PRELOAD enhancements (Tristan Gigold).
854 + LD_PRELOAD patch for linux-68k (Andreas Schwab).
856 +Changes in version 1.5.2:
858 + More ELF changes (Mitch D'Souza).
860 + Changed ldconfig to also update the link for ld-linux.so.
862 +Changes in version 1.5.1:
864 + More ELF and LD_PRELOAD changes (Mitch D'Souza).
866 +Changes in version 1.5.0:
868 + Chnaged all executables to QMAGIC (Mitch D'Souza and Rick
871 + Added preliminary support for ELF to ldd and ldconfig (Eric
872 + Youndale and H.J. Lu).
874 + Added support for LD_PRELOAD to ld.so (Mitch D'Souza).
876 + Removed the "advertising" clause from the copyright notices
877 + in all source files.
879 +Changes in version 1.4.4:
881 + Changed ldconfig to support QMAGIC libraries.
883 + Fixed a bug in ld.so where some of the error messages had
884 + transposed arguments.
886 +Changes in version 1.4.3:
888 + Fixed an obscure bug in ld.so where an index was not being
889 + incremented when a library was not found using the cache.
891 +Changes in version 1.4.2:
893 + Changed ldconfig to issue a warning and continue instead
894 + of an error and exiting when a link can't be updated.
895 + This is useful when some libraries are imported on read-
896 + only file systems, such as an NFS mounted /usr.
898 + Changed ld.so to be more robust in searching for libraries.
899 + A library is not considered found unless it can actually be
900 + loaded. If a library is not found using the cache, the
901 + standard directories are searched as in pre-cache versions.
903 +Changes in version 1.4.1:
905 + Fixed minor Makefile problems.
907 + Added support for linux-68k.
909 + Fixed a bug in ld.so where libraries with absolute paths
910 + were not handled correctly.
912 + Changed ld.so to ignore the directory in the names of
913 + shared libraries by default. This allows older libraries
914 + with absolute paths, such as the XView libraries, to take
915 + advantage of the cache support.
917 + Added a minimal usage message to ldconfig.
919 +Changes in version 1.4:
921 + Fixed bug in ld.so where minor version numbers were not
922 + reported correctly when a minor version incompatibility
925 + Fixed bug in ldconfig where libraries with subversion
926 + numbers greater than 9 were not compared correctly.
928 + Added Mitch D'Souza's support for suppressing warning
929 + messages from ld.so about minor version incompatibilities.
931 + Added Mitch D'Souza's support for using a cache to speed
932 + up searching for libraries in the standard directories.
934 + Added Mitch D'Souza's support for a debugging version of
935 + ld.so. Link with -lldso if you think you are experiencing
936 + dynamic linker problems.
938 +Changes in version 1.3:
940 + Added support for libraries using absolute pathnames. If I
941 + had known that the XView libraries used them, I would have
942 + added this earlier.
944 + Fixed a bug handling old libraries using a pathname beginning
945 + with '/' or '/lib/'.
947 +Changes in version 1.2a:
949 + Fixed a minor bug in ldd which caused all files, specifically
950 + scripts, to be recognized as binaries. Thanks to Olaf Flebbe
955 diff -urN uClibc/ldso-0.9.24/include/.cvsignore uClibc.ldso.24/ldso-0.9.24/include/.cvsignore
956 --- uClibc/ldso-0.9.24/include/.cvsignore 1969-12-31 18:00:00.000000000 -0600
957 +++ uClibc.ldso.24/ldso-0.9.24/include/.cvsignore 2003-08-19 01:05:30.000000000 -0500
963 diff -urN uClibc/ldso-0.9.24/include/dlfcn.h uClibc.ldso.24/ldso-0.9.24/include/dlfcn.h
964 --- uClibc/ldso-0.9.24/include/dlfcn.h 1969-12-31 18:00:00.000000000 -0600
965 +++ uClibc.ldso.24/ldso-0.9.24/include/dlfcn.h 2003-08-19 01:05:30.000000000 -0500
967 +/* User functions for run-time dynamic loading. libdl version */
971 +#include <features.h>
972 +#include <bits/dlfcn.h>
974 +#define RTLD_NEXT ((void *) -1l)
975 +#define RTLD_DEFAULT ((void *) 0)
977 +/* Structure containing information about object searched using
981 + __const char *dli_fname; /* File name of defining object. */
982 + void *dli_fbase; /* Load address of that object. */
983 + __const char *dli_sname; /* Name of nearest symbol. */
984 + void *dli_saddr; /* Exact value of nearest symbol. */
988 +#endif /* dlfcn.h */
989 diff -urN uClibc/ldso-0.9.24/include/ld_elf.h uClibc.ldso.24/ldso-0.9.24/include/ld_elf.h
990 --- uClibc/ldso-0.9.24/include/ld_elf.h 1969-12-31 18:00:00.000000000 -0600
991 +++ uClibc.ldso.24/ldso-0.9.24/include/ld_elf.h 2003-11-04 07:07:45.000000000 -0600
996 +#include <ld_sysdep.h> /* before elf.h to get ELF_USES_RELOCA right */
1001 +# define LDSO_CONF "../util/ld.so.conf"
1002 +# define LDSO_CACHE "../util/ld.so.cache"
1003 +# define LDSO_PRELOAD "../util/ld.so.preload"
1005 +# define LDSO_CONF UCLIBC_RUNTIME_PREFIX "etc/ld.so.conf"
1006 +# define LDSO_CACHE UCLIBC_RUNTIME_PREFIX "etc/ld.so.cache"
1007 +# define LDSO_PRELOAD UCLIBC_RUNTIME_PREFIX "etc/ld.so.preload"
1014 +#define LIB_ELF64 0x80
1015 +#define LIB_ELF_LIBC5 2
1016 +#define LIB_ELF_LIBC6 3
1017 +#define LIB_ELF_LIBC0 4
1019 +/* Forward declarations for stuff defined in ld_hash.h */
1021 +struct elf_resolve;
1024 +/* Definitions and prototypes for cache stuff */
1026 +extern int _dl_map_cache(void);
1027 +extern int _dl_unmap_cache(void);
1029 +#define LDSO_CACHE_MAGIC "ld.so-"
1030 +#define LDSO_CACHE_MAGIC_LEN (sizeof LDSO_CACHE_MAGIC -1)
1031 +#define LDSO_CACHE_VER "1.7.0"
1032 +#define LDSO_CACHE_VER_LEN (sizeof LDSO_CACHE_VER -1)
1035 + char magic [LDSO_CACHE_MAGIC_LEN];
1036 + char version [LDSO_CACHE_VER_LEN];
1047 +static inline void _dl_map_cache(void) { }
1048 +static inline void _dl_unmap_cache(void) { }
1052 +/* Function prototypes for non-static stuff in readelflib1.c */
1053 +int _dl_copy_fixups(struct dyn_elf * tpnt);
1054 +extern int _dl_parse_copy_information(struct dyn_elf *rpnt,
1055 + unsigned long rel_addr, unsigned long rel_size, int type);
1056 +extern void _dl_parse_lazy_relocation_information(struct elf_resolve *tpnt,
1057 + unsigned long rel_addr, unsigned long rel_size, int type);
1058 +extern int _dl_parse_relocation_information(struct elf_resolve *tpnt,
1059 + unsigned long rel_addr, unsigned long rel_size, int type);
1060 +extern struct elf_resolve * _dl_load_shared_library(int secure,
1061 + struct dyn_elf **rpnt, struct elf_resolve *tpnt, char *full_libname);
1062 +extern struct elf_resolve * _dl_load_elf_shared_library(int secure,
1063 + struct dyn_elf **rpnt, char *libname);
1064 +extern struct elf_resolve *_dl_check_if_named_library_is_loaded(const char *full_libname);
1065 +extern int _dl_linux_resolve(void);
1069 + * Datatype of a relocation on this platform
1071 +#ifdef ELF_USES_RELOCA
1072 +# define ELF_RELOC ElfW(Rela)
1074 +# define ELF_RELOC ElfW(Rel)
1078 +/* Convert between the Linux flags for page protections and the
1079 + ones specified in the ELF standard. */
1080 +#define LXFLAGS(X) ( (((X) & PF_R) ? PROT_READ : 0) | \
1081 + (((X) & PF_W) ? PROT_WRITE : 0) | \
1082 + (((X) & PF_X) ? PROT_EXEC : 0))
1085 +#endif /* LINUXELF_H */
1086 diff -urN uClibc/ldso-0.9.24/include/ld_hash.h uClibc.ldso.24/ldso-0.9.24/include/ld_hash.h
1087 --- uClibc/ldso-0.9.24/include/ld_hash.h 1969-12-31 18:00:00.000000000 -0600
1088 +++ uClibc.ldso.24/ldso-0.9.24/include/ld_hash.h 2003-08-19 08:11:05.000000000 -0500
1090 +#ifndef _LD_HASH_H_
1091 +#define _LD_HASH_H_
1094 +#define RTLD_NEXT ((void*)-1)
1098 + unsigned long flags;
1099 + struct elf_resolve * dyn;
1100 + struct dyn_elf * next_handle; /* Used by dlopen et al. */
1101 + struct dyn_elf * next;
1102 + struct dyn_elf * prev;
1105 +struct elf_resolve{
1106 + /* These entries must be in this order to be compatible with the interface used
1107 + by gdb to obtain the list of symbols. */
1108 + ElfW(Addr) loadaddr; /* Base address shared object is loaded at. */
1109 + char *libname; /* Absolute file name object was found in. */
1110 + ElfW(Dyn) *dynamic_addr; /* Dynamic section of the shared object. */
1111 + struct elf_resolve * next;
1112 + struct elf_resolve * prev;
1113 + /* Nothing after this address is used by gdb. */
1114 + enum {elf_lib, elf_executable,program_interpreter, loaded_file} libtype;
1115 + struct dyn_elf * symbol_scope;
1116 + unsigned short usage_count;
1117 + unsigned short int init_flag;
1118 + unsigned int nbucket;
1119 + unsigned long * elf_buckets;
1121 + * These are only used with ELF style shared libraries
1123 + unsigned long nchain;
1124 + unsigned long * chains;
1125 + unsigned long dynamic_info[24];
1127 + unsigned long dynamic_size;
1128 + unsigned long n_phent;
1129 + Elf32_Phdr * ppnt;
1131 +#if defined(__mips__)
1132 + /* Needed for MIPS relocation */
1133 + unsigned long mips_gotsym;
1134 + unsigned long mips_local_gotno;
1135 + unsigned long mips_symtabno;
1139 + /* this is used to store the address of relocation data words, so
1140 + * we don't have to calculate it every time, which requires a divide */
1141 + unsigned long data_words;
1145 +#define COPY_RELOCS_DONE 1
1146 +#define RELOCS_DONE 2
1147 +#define JMP_RELOCS_DONE 4
1148 +#define INIT_FUNCS_CALLED 8
1150 +extern struct dyn_elf * _dl_symbol_tables;
1151 +extern struct elf_resolve * _dl_loaded_modules;
1152 +extern struct dyn_elf * _dl_handles;
1154 +extern struct elf_resolve * _dl_check_hashed_files(const char * libname);
1155 +extern struct elf_resolve * _dl_add_elf_hash_table(const char * libname,
1156 + char * loadaddr, unsigned long * dynamic_info,
1157 + unsigned long dynamic_addr, unsigned long dynamic_size);
1159 +enum caller_type{symbolrel=0,copyrel=1,resolver=2};
1160 +extern char * _dl_find_hash(const char * name, struct dyn_elf * rpnt1,
1161 + struct elf_resolve * f_tpnt, enum caller_type);
1163 +extern int _dl_linux_dynamic_link(void);
1165 +extern char * _dl_library_path;
1166 +extern char * _dl_not_lazy;
1167 +extern unsigned long _dl_elf_hash(const char * name);
1169 +static inline int _dl_symbol(char * name)
1171 + if(name[0] != '_' || name[1] != 'd' || name[2] != 'l' || name[3] != '_')
1177 +#define LD_ERROR_NOFILE 1
1178 +#define LD_ERROR_NOZERO 2
1179 +#define LD_ERROR_NOTELF 3
1180 +#define LD_ERROR_NOTMAGIC 4
1181 +#define LD_ERROR_NOTDYN 5
1182 +#define LD_ERROR_MMAP_FAILED 6
1183 +#define LD_ERROR_NODYNAMIC 7
1184 +#define LD_WRONG_RELOCS 8
1185 +#define LD_BAD_HANDLE 9
1186 +#define LD_NO_SYMBOL 10
1190 +#endif /* _LD_HASH_H_ */
1193 diff -urN uClibc/ldso-0.9.24/include/ld_string.h uClibc.ldso.24/ldso-0.9.24/include/ld_string.h
1194 --- uClibc/ldso-0.9.24/include/ld_string.h 1969-12-31 18:00:00.000000000 -0600
1195 +++ uClibc.ldso.24/ldso-0.9.24/include/ld_string.h 2003-09-29 16:46:00.000000000 -0500
1197 +#ifndef _LINUX_STRING_H_
1198 +#define _LINUX_STRING_H_
1200 +extern void *_dl_malloc(int size);
1201 +extern char *_dl_getenv(const char *symbol, char **envp);
1202 +extern void _dl_unsetenv(const char *symbol, char **envp);
1203 +extern char *_dl_strdup(const char *string);
1204 +extern void _dl_dprintf(int, const char *, ...);
1207 +static size_t _dl_strlen(const char * str);
1208 +static char *_dl_strcat(char *dst, const char *src);
1209 +static char * _dl_strcpy(char * dst,const char *src);
1210 +static int _dl_strcmp(const char * s1,const char * s2);
1211 +static int _dl_strncmp(const char * s1,const char * s2,size_t len);
1212 +static char * _dl_strchr(const char * str,int c);
1213 +static char *_dl_strrchr(const char *str, int c);
1214 +static char *_dl_strstr(const char *s1, const char *s2);
1215 +static void * _dl_memcpy(void * dst, const void * src, size_t len);
1216 +static int _dl_memcmp(const void * s1,const void * s2,size_t len);
1217 +static void *_dl_memset(void * str,int c,size_t len);
1218 +static char *_dl_get_last_path_component(char *path);
1219 +static char *_dl_simple_ltoa(char * local, unsigned long i);
1220 +static char *_dl_simple_ltoahex(char * local, unsigned long i);
1223 +#define NULL ((void *) 0)
1226 +static inline size_t _dl_strlen(const char * str)
1228 + register char *ptr = (char *) str;
1232 + return (ptr - str);
1235 +static inline char *_dl_strcat(char *dst, const char *src)
1237 + register char *ptr = dst;
1249 +static inline char * _dl_strcpy(char * dst,const char *src)
1251 + register char *ptr = dst;
1260 +static inline int _dl_strcmp(const char * s1,const char * s2)
1262 + register unsigned char c1, c2;
1265 + c1 = (unsigned char) *s1++;
1266 + c2 = (unsigned char) *s2++;
1275 +static inline int _dl_strncmp(const char * s1,const char * s2,size_t len)
1277 + register unsigned char c1 = '\0';
1278 + register unsigned char c2 = '\0';
1281 + c1 = (unsigned char) *s1++;
1282 + c2 = (unsigned char) *s2++;
1283 + if (c1 == '\0' || c1 != c2)
1291 +static inline char * _dl_strchr(const char * str,int c)
1296 + if ((ch = *str) == c)
1297 + return (char *) str;
1305 +static inline char *_dl_strrchr(const char *str, int c)
1307 + register char *prev = 0;
1308 + register char *ptr = (char *) str;
1310 + while (*ptr != '\0') {
1321 +static inline char *_dl_strstr(const char *s1, const char *s2)
1323 + register const char *s = s1;
1324 + register const char *p = s2;
1328 + return (char *) s1;;
1343 +static inline void * _dl_memcpy(void * dst, const void * src, size_t len)
1345 + register char *a = dst;
1346 + register const char *b = src;
1355 +static inline int _dl_memcmp(const void * s1,const void * s2,size_t len)
1357 + unsigned char *c1 = (unsigned char *)s1;
1358 + unsigned char *c2 = (unsigned char *)s2;
1369 +static inline void * _dl_memset(void * str,int c,size_t len)
1371 + register char *a = str;
1379 +static inline char *_dl_get_last_path_component(char *path)
1382 + register char *ptr = path;
1383 + register char *prev = 0;
1389 + /* strip trailing slashes */
1390 + while (s != path && *s == '/') {
1394 + /* find last component */
1396 + while (*ptr != '\0') {
1403 + if (s == NULL || s[1] == '\0')
1409 +/* Early on, we can't call printf, so use this to print out
1410 + * numbers using the SEND_STDERR() macro */
1411 +static inline char *_dl_simple_ltoa(char * local, unsigned long i)
1413 + /* 21 digits plus null terminator, good for 64-bit or smaller ints */
1414 + char *p = &local[22];
1417 + *p-- = '0' + i % 10;
1423 +static inline char *_dl_simple_ltoahex(char * local, unsigned long i)
1425 + /* 21 digits plus null terminator, good for 64-bit or smaller ints */
1426 + char *p = &local[22];
1429 + char temp = i % 0x10;
1431 + *p-- = '0' + temp;
1433 + *p-- = 'a' - 0x0a + temp;
1442 +#if defined(mc68000) || defined(__arm__) || defined(__mips__) || defined(__sh__) || defined(__powerpc__)
1443 +/* On some arches constant strings are referenced through the GOT. */
1444 +/* XXX Requires load_addr to be defined. */
1445 +#define SEND_STDERR(X) \
1446 + { const char *__s = (X); \
1447 + if (__s < (const char *) load_addr) __s += load_addr; \
1448 + _dl_write (2, __s, _dl_strlen (__s)); \
1451 +#define SEND_STDERR(X) _dl_write(2, X, _dl_strlen(X));
1454 +#define SEND_ADDRESS_STDERR(X, add_a_newline) { \
1455 + char tmp[22], *tmp1; \
1456 + _dl_memset(tmp, 0, sizeof(tmp)); \
1457 + tmp1=_dl_simple_ltoahex( tmp, (unsigned long)(X)); \
1458 + _dl_write(2, tmp1, _dl_strlen(tmp1)); \
1459 + if (add_a_newline) { \
1461 + _dl_write(2, tmp, 1); \
1465 +#define SEND_NUMBER_STDERR(X, add_a_newline) { \
1466 + char tmp[22], *tmp1; \
1467 + _dl_memset(tmp, 0, sizeof(tmp)); \
1468 + tmp1=_dl_simple_ltoa( tmp, (unsigned long)(X)); \
1469 + _dl_write(2, tmp1, _dl_strlen(tmp1)); \
1470 + if (add_a_newline) { \
1472 + _dl_write(2, tmp, 1); \
1478 diff -urN uClibc/ldso-0.9.24/include/ld_syscall.h uClibc.ldso.24/ldso-0.9.24/include/ld_syscall.h
1479 --- uClibc/ldso-0.9.24/include/ld_syscall.h 1969-12-31 18:00:00.000000000 -0600
1480 +++ uClibc.ldso.24/ldso-0.9.24/include/ld_syscall.h 2003-08-19 01:05:30.000000000 -0500
1482 +#ifndef _LD_SYSCALL_H_
1483 +#define _LD_SYSCALL_H_
1485 +/* Pull in the arch specific syscall implementation */
1486 +#include <ld_syscalls.h>
1487 +/* For MAP_ANONYMOUS -- differs between platforms */
1488 +#include <asm/mman.h>
1489 +/* Pull in whatever this particular arch's kernel thinks the kernel version of
1490 + * struct stat should look like. It turns out that each arch has a different
1491 + * opinion on the subject, and different kernel revs use different names... */
1492 +#define kernel_stat stat
1493 +#include <bits/kernel_stat.h>
1496 +/* Encoding of the file mode. */
1497 +#define S_IFMT 0170000 /* These bits determine file type. */
1500 +#define S_IFDIR 0040000 /* Directory. */
1501 +#define S_IFCHR 0020000 /* Character device. */
1502 +#define S_IFBLK 0060000 /* Block device. */
1503 +#define S_IFREG 0100000 /* Regular file. */
1504 +#define S_IFIFO 0010000 /* FIFO. */
1505 +#define S_IFLNK 0120000 /* Symbolic link. */
1506 +#define S_IFSOCK 0140000 /* Socket. */
1508 +/* Protection bits. */
1510 +#define S_ISUID 04000 /* Set user ID on execution. */
1511 +#define S_ISGID 02000 /* Set group ID on execution. */
1512 +#define S_ISVTX 01000 /* Save swapped text after use (sticky). */
1513 +#define S_IREAD 0400 /* Read by owner. */
1514 +#define S_IWRITE 0200 /* Write by owner. */
1515 +#define S_IEXEC 0100 /* Execute by owner. */
1518 +/* Here are the definitions for some syscalls that are used
1519 + by the dynamic linker. The idea is that we want to be able
1520 + to call these before the errno symbol is dynamicly linked, so
1521 + we use our own version here. Note that we cannot assume any
1522 + dynamic linking at all, so we cannot return any error codes.
1523 + We just punt if there is an error. */
1526 +#define __NR__dl_exit __NR_exit
1527 +static inline _syscall1(void, _dl_exit, int, status);
1530 +#define __NR__dl_close __NR_close
1531 +static inline _syscall1(int, _dl_close, int, fd);
1534 +#if defined(__powerpc__) || defined(__mips__) || defined(__sh__)
1535 +/* PowerPC, MIPS and SuperH have a different calling convention for mmap(). */
1536 +#define __NR__dl_mmap __NR_mmap
1537 +static inline _syscall6(void *, _dl_mmap, void *, start, size_t, length,
1538 + int, prot, int, flags, int, fd, off_t, offset);
1540 +#define __NR__dl_mmap_real __NR_mmap
1541 +static inline _syscall1(void *, _dl_mmap_real, unsigned long *, buffer);
1543 +static inline void * _dl_mmap(void * addr, unsigned long size, int prot,
1544 + int flags, int fd, unsigned long offset)
1546 + unsigned long buffer[6];
1548 + buffer[0] = (unsigned long) addr;
1549 + buffer[1] = (unsigned long) size;
1550 + buffer[2] = (unsigned long) prot;
1551 + buffer[3] = (unsigned long) flags;
1552 + buffer[4] = (unsigned long) fd;
1553 + buffer[5] = (unsigned long) offset;
1554 + return (void *) _dl_mmap_real(buffer);
1558 +#ifndef _dl_MAX_ERRNO
1559 +#define _dl_MAX_ERRNO 4096
1561 +#define _dl_mmap_check_error(__res) \
1562 + (((int)__res) < 0 && ((int)__res) >= -_dl_MAX_ERRNO)
1563 +#ifndef MAP_ANONYMOUS
1565 +#define MAP_ANONYMOUS 0x20
1567 +#error MAP_ANONYMOUS not defined and suplementary value not known
1572 +#define __NR__dl_open __NR_open
1573 +#define O_RDONLY 0x0000
1574 +#define O_WRONLY 01
1576 +#define O_CREAT 0100 /* not fcntl */
1577 +static inline _syscall2(int, _dl_open, const char *, fn, int, flags);
1579 +#define __NR__dl_write __NR_write
1580 +static inline _syscall3(unsigned long, _dl_write, int, fd,
1581 + const void *, buf, unsigned long, count);
1584 +#define __NR__dl_read __NR_read
1585 +static inline _syscall3(unsigned long, _dl_read, int, fd,
1586 + const void *, buf, unsigned long, count);
1588 +#define __NR__dl_mprotect __NR_mprotect
1589 +static inline _syscall3(int, _dl_mprotect, const void *, addr, unsigned long, len, int, prot);
1593 +#define __NR__dl_stat __NR_stat
1594 +static inline _syscall2(int, _dl_stat, const char *, file_name, struct stat *, buf);
1597 +#define __NR__dl_munmap __NR_munmap
1598 +static inline _syscall2(int, _dl_munmap, void *, start, unsigned long, length);
1600 +#define __NR__dl_getuid __NR_getuid
1601 +static inline _syscall0(uid_t, _dl_getuid);
1603 +#define __NR__dl_geteuid __NR_geteuid
1604 +static inline _syscall0(uid_t, _dl_geteuid);
1606 +#define __NR__dl_getgid __NR_getgid
1607 +static inline _syscall0(gid_t, _dl_getgid);
1609 +#define __NR__dl_getegid __NR_getegid
1610 +static inline _syscall0(gid_t, _dl_getegid);
1612 +#define __NR__dl_getpid __NR_getpid
1613 +static inline _syscall0(gid_t, _dl_getpid);
1616 + * Not an actual syscall, but we need something in assembly to say whether
1617 + * this is OK or not.
1619 +static inline int _dl_suid_ok(void)
1621 + uid_t uid, euid, gid, egid;
1623 + uid = _dl_getuid();
1624 + euid = _dl_geteuid();
1625 + gid = _dl_getgid();
1626 + egid = _dl_getegid();
1628 + if(uid == euid && gid == egid)
1634 +#define __NR__dl_readlink __NR_readlink
1635 +static inline _syscall3(int, _dl_readlink, const char *, path, char *, buf, size_t, bufsiz);
1637 +#endif /* _LD_SYSCALL_H_ */
1639 diff -urN uClibc/ldso-0.9.24/include/ldso.h uClibc.ldso.24/ldso-0.9.24/include/ldso.h
1640 --- uClibc/ldso-0.9.24/include/ldso.h 1969-12-31 18:00:00.000000000 -0600
1641 +++ uClibc.ldso.24/ldso-0.9.24/include/ldso.h 2003-08-19 01:05:30.000000000 -0500
1643 +#include <features.h>
1644 +/* Pull in compiler and arch stuff */
1645 +#include <stdlib.h>
1646 +#include <stdarg.h>
1647 +/* Pull in the arch specific type information */
1648 +#include <sys/types.h>
1649 +/* Now the ldso specific headers */
1650 +#include <ld_elf.h>
1651 +#include <ld_syscall.h>
1652 +#include <ld_hash.h>
1653 +#include <ld_string.h>
1654 diff -urN uClibc/ldso-0.9.24/ldso/.cvsignore uClibc.ldso.24/ldso-0.9.24/ldso/.cvsignore
1655 --- uClibc/ldso-0.9.24/ldso/.cvsignore 1969-12-31 18:00:00.000000000 -0600
1656 +++ uClibc.ldso.24/ldso-0.9.24/ldso/.cvsignore 2003-08-19 01:05:31.000000000 -0500
1660 diff -urN uClibc/ldso-0.9.24/ldso/Makefile uClibc.ldso.24/ldso-0.9.24/ldso/Makefile
1661 --- uClibc/ldso-0.9.24/ldso/Makefile 1969-12-31 18:00:00.000000000 -0600
1662 +++ uClibc.ldso.24/ldso-0.9.24/ldso/Makefile 2004-03-01 02:58:58.000000000 -0600
1664 +# Makefile for uClibc
1666 +# Copyright (C) 2000 by Lineo, inc.
1667 +# Copyright (C) 2000-2002 Erik Andersen <andersen@uclibc.org>
1669 +# This program is free software; you can redistribute it and/or modify it under
1670 +# the terms of the GNU Library General Public License as published by the Free
1671 +# Software Foundation; either version 2 of the License, or (at your option) any
1674 +# This program is distributed in the hope that it will be useful, but WITHOUT
1675 +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1676 +# FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more
1679 +# You should have received a copy of the GNU Library General Public License
1680 +# along with this program; if not, write to the Free Software Foundation, Inc.,
1681 +# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1683 +# Derived in part from the Linux-8086 C library, the GNU C Library, and several
1684 +# other sundry sources. Files within this library are copyright by their
1685 +# respective copyright holders.
1689 +include $(TOPDIR)Rules.mak
1690 +LDSO_FULLNAME=ld-uClibc-$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBLEVEL).so
1693 +XXFLAGS=$(XWARNINGS) $(OPTIMIZATION) $(XARCH_CFLAGS) $(CPU_CFLAGS) $(PICFLAG) \
1694 + -DUCLIBC_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" \
1695 + -fno-builtin -nostdinc -I$(TOPDIR)ldso-0.9.24/include -I. -I$(TOPDIR)include
1697 +ifeq ($(SUPPORT_LD_DEBUG),y)
1698 +XXFLAGS=$(XWARNINGS) $(XARCH_CFLAGS) $(CPU_CFLAGS) $(PICFLAG) \
1699 + -DUCLIBC_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" \
1700 + -fno-builtin -nostdinc -I$(TOPDIR)ldso-0.9.24/include -I. -I$(TOPDIR)include
1701 +# Not really much point in including debugging info, since gdb
1702 +# can't really debug ldso, since gdb requires help from ldso to
1707 +# BEWARE!!! At least mips* will die if -O0 is used!!!
1708 +XXFLAGS :=$(XXFLAGS:-O0=-O1)
1710 +XXFLAGS+=$(shell $(CC) -print-search-dirs | sed -ne "s/install: *\(.*\)/-I\1include/gp")
1711 +LDFLAGS=$(CPU_LDFLAGS-y) -shared --warn-common --export-dynamic --sort-common \
1712 + -z combreloc --discard-locals --discard-all --no-undefined
1714 +CSRC= ldso.c #hash.c readelflib1.c $(TARGET_ARCH)/elfinterp.c
1715 +COBJS=$(patsubst %.c,%.o, $(CSRC))
1716 +ASRC=$(shell ls $(TARGET_ARCH)/*.S)
1717 +AOBJS=$(patsubst %.S,%.o, $(ASRC))
1718 +OBJS=$(AOBJS) $(COBJS)
1720 +ifneq ($(strip $(SUPPORT_LD_DEBUG)),y)
1724 +ifeq ($(strip $(SUPPORT_LD_DEBUG)),y)
1725 +XXFLAGS+=-D__SUPPORT_LD_DEBUG__
1728 +ifeq ($(strip $(SUPPORT_LD_DEBUG_EARLY)),y)
1729 +XXFLAGS+=-D__SUPPORT_LD_DEBUG_EARLY__
1732 +ifeq ($(strip $(FORCE_SHAREABLE_TEXT_SEGMENTS)),y)
1733 +XXFLAGS+=-DFORCE_SHAREABLE_TEXT_SEGMENTS
1736 +#This stuff will not work with -fomit-frame-pointer
1737 +XXFLAGS := $(XXFLAGS:-fomit-frame-pointer=)
1741 +lib:: _dl_progname.h $(OBJS) $(DLINK_OBJS)
1742 + $(LD) $(LDFLAGS) -e _dl_boot -soname=$(UCLIBC_LDSO) \
1743 + -o $(LDSO_FULLNAME) $(OBJS) $(LIBGCC);
1744 + $(INSTALL) -d $(TOPDIR)lib
1745 + $(INSTALL) -m 755 $(LDSO_FULLNAME) $(TOPDIR)lib
1746 + $(LN) -sf $(LDSO_FULLNAME) $(TOPDIR)lib/$(UCLIBC_LDSO)
1748 +_dl_progname.h: Makefile
1749 + echo "const char *_dl_progname=\""$(UCLIBC_LDSO)"\";" > _dl_progname.h
1750 + echo "#include \"$(TARGET_ARCH)/elfinterp.c\"" >> _dl_progname.h
1753 +$(COBJS): %.o : %.c
1754 + $(CC) $(XXFLAGS) -I../libdl -c $< -o $@
1755 + $(STRIPTOOL) -x -R .note -R .comment $*.o
1757 +$(AOBJS): %.o : %.S
1758 + $(CC) $(XXFLAGS) -I../libdl -c $< -o $@
1759 + $(STRIPTOOL) -x -R .note -R .comment $*.o
1761 +ldso.o: ldso.c hash.c readelflib1.c $(TARGET_ARCH)/elfinterp.c _dl_progname.h
1764 + $(RM) $(UCLIBC_LDSO)* $(OBJS) $(LDSO_FULLNAME)* core *.o *.a *.s *.i _dl_progname.h ldso.h *~
1765 diff -urN uClibc/ldso-0.9.24/ldso/arm/boot1_arch.h uClibc.ldso.24/ldso-0.9.24/ldso/arm/boot1_arch.h
1766 --- uClibc/ldso-0.9.24/ldso/arm/boot1_arch.h 1969-12-31 18:00:00.000000000 -0600
1767 +++ uClibc.ldso.24/ldso-0.9.24/ldso/arm/boot1_arch.h 2002-11-13 18:53:49.000000000 -0600
1769 +/* Any assmbly language/system dependent hacks needed to setup boot1.c so it
1770 + * will work as expected and cope with whatever platform specific wierdness is
1771 + * needed for this architecture. */
1773 +/* Overrive the default _dl_boot function, and replace it with a bit of asm.
1774 + * Then call the real _dl_boot function, which is now named _dl_boot2. */
1778 +" .globl _dl_boot\n" \
1781 +" @ldr r0, [sp], #4\n" \
1783 +" bl _dl_boot2\n" \
1789 +#define _dl_boot _dl_boot2
1790 +#define LD_BOOT(X) static void * __attribute__ ((unused)) _dl_boot (X)
1793 + /* It seems ARM needs an offset here */
1795 +#define ELFMAGIC ELFMAG+load_addr
1799 diff -urN uClibc/ldso-0.9.24/ldso/arm/elfinterp.c uClibc.ldso.24/ldso-0.9.24/ldso/arm/elfinterp.c
1800 --- uClibc/ldso-0.9.24/ldso/arm/elfinterp.c 1969-12-31 18:00:00.000000000 -0600
1801 +++ uClibc.ldso.24/ldso-0.9.24/ldso/arm/elfinterp.c 2002-11-07 21:20:59.000000000 -0600
1803 +/* vi: set sw=4 ts=4: */
1804 +/* ARM ELF shared library loader suppport
1806 + * Copyright (C) 2001-2002, Erik Andersen
1808 + * All rights reserved.
1810 + * Redistribution and use in source and binary forms, with or without
1811 + * modification, are permitted provided that the following conditions
1813 + * 1. Redistributions of source code must retain the above copyright
1814 + * notice, this list of conditions and the following disclaimer.
1815 + * 2. The name of the above contributors may not be
1816 + * used to endorse or promote products derived from this software
1817 + * without specific prior written permission.
1819 + * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
1820 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1821 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1822 + * ARE DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE
1823 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1824 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1825 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1826 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1827 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1828 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1832 +#if defined (__SUPPORT_LD_DEBUG__)
1833 +static const char *_dl_reltypes_tab[] =
1835 + [0] "R_ARM_NONE", "R_ARM_PC24", "R_ARM_ABS32", "R_ARM_REL32",
1836 + [4] "R_ARM_PC13", "R_ARM_ABS16", "R_ARM_ABS12", "R_ARM_THM_ABS5",
1837 + [8] "R_ARM_ABS8", "R_ARM_SBREL32","R_ARM_THM_PC22", "R_ARM_THM_PC8",
1838 + [12] "R_ARM_AMP_VCALL9", "R_ARM_SWI24", "R_ARM_THM_SWI8", "R_ARM_XPC25",
1839 + [16] "R_ARM_THM_XPC22",
1840 + [20] "R_ARM_COPY", "R_ARM_GLOB_DAT","R_ARM_JUMP_SLOT", "R_ARM_RELATIVE",
1841 + [24] "R_ARM_GOTOFF", "R_ARM_GOTPC", "R_ARM_GOT32", "R_ARM_PLT32",
1842 + [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",
1843 + [36] "R_ARM_ALU_SBREL_19_12","R_ARM_ALU_SBREL_27_20",
1844 + [100] "R_ARM_GNU_VTENTRY","R_ARM_GNU_VTINHERIT","R_ARM_THM_PC11","R_ARM_THM_PC9",
1845 + [249] "R_ARM_RXPC25", "R_ARM_RSBREL32", "R_ARM_THM_RPC22", "R_ARM_RREL32",
1846 + [253] "R_ARM_RABS22", "R_ARM_RPC24", "R_ARM_RBASE",
1849 +static const char *
1850 +_dl_reltypes(int type)
1852 + static char buf[22];
1855 + if (type >= (sizeof (_dl_reltypes_tab)/sizeof(_dl_reltypes_tab[0])) ||
1856 + NULL == (str = _dl_reltypes_tab[type]))
1858 + str =_dl_simple_ltoa( buf, (unsigned long)(type));
1864 +void debug_sym(Elf32_Sym *symtab,char *strtab,int symtab_index)
1866 + if(_dl_debug_symbols)
1869 + _dl_dprintf(_dl_debug_file, "\n%s\tvalue=%x\tsize=%x\tinfo=%x\tother=%x\tshndx=%x",
1870 + strtab + symtab[symtab_index].st_name,
1871 + symtab[symtab_index].st_value,
1872 + symtab[symtab_index].st_size,
1873 + symtab[symtab_index].st_info,
1874 + symtab[symtab_index].st_other,
1875 + symtab[symtab_index].st_shndx);
1880 +static void debug_reloc(Elf32_Sym *symtab,char *strtab, ELF_RELOC *rpnt)
1882 + if(_dl_debug_reloc)
1886 + symtab_index = ELF32_R_SYM(rpnt->r_info);
1887 + sym = symtab_index ? strtab + symtab[symtab_index].st_name : "sym=0x0";
1889 +#ifdef ELF_USES_RELOCA
1890 + _dl_dprintf(_dl_debug_file, "\n%s\toffset=%x\taddend=%x %s",
1891 + _dl_reltypes(ELF32_R_TYPE(rpnt->r_info)),
1896 + _dl_dprintf(_dl_debug_file, "\n%s\toffset=%x %s",
1897 + _dl_reltypes(ELF32_R_TYPE(rpnt->r_info)),
1905 +/* Program to load an ELF binary on a linux system, and run it.
1906 + References to symbols in sharable libraries can be resolved by either
1907 + an ELF sharable library or a linux style of shared library. */
1909 +/* Disclaimer: I have never seen any AT&T source code for SVr4, nor have
1910 + I ever taken any courses on internals. This program was developed using
1911 + information available through the book "UNIX SYSTEM V RELEASE 4,
1912 + Programmers guide: Ansi C and Programming Support Tools", which did
1913 + a more than adequate job of explaining everything required to get this
1916 +extern int _dl_linux_resolve(void);
1918 +unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
1921 + ELF_RELOC *this_reloc;
1923 + Elf32_Sym *symtab;
1924 + ELF_RELOC *rel_addr;
1928 + unsigned long instr_addr;
1930 + rel_addr = (ELF_RELOC *) (tpnt->dynamic_info[DT_JMPREL] + tpnt->loadaddr);
1932 + this_reloc = rel_addr + (reloc_entry >> 3);
1933 + reloc_type = ELF32_R_TYPE(this_reloc->r_info);
1934 + symtab_index = ELF32_R_SYM(this_reloc->r_info);
1936 + symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
1937 + strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
1940 + if (reloc_type != R_ARM_JUMP_SLOT) {
1941 + _dl_dprintf(2, "%s: Incorrect relocation type in jump relocations\n",
1946 + /* Address of jump instruction to fix up */
1947 + instr_addr = ((unsigned long) this_reloc->r_offset +
1948 + (unsigned long) tpnt->loadaddr);
1949 + got_addr = (char **) instr_addr;
1951 + /* Get the address of the GOT entry */
1952 + new_addr = _dl_find_hash(strtab + symtab[symtab_index].st_name,
1953 + tpnt->symbol_scope, tpnt, resolver);
1955 + _dl_dprintf(2, "%s: can't resolve symbol '%s'\n",
1956 + _dl_progname, strtab + symtab[symtab_index].st_name);
1959 +#if defined (__SUPPORT_LD_DEBUG__)
1960 + if ((unsigned long) got_addr < 0x40000000)
1962 + if (_dl_debug_bindings)
1964 + _dl_dprintf(_dl_debug_file, "\nresolve function: %s",
1965 + strtab + symtab[symtab_index].st_name);
1966 + if(_dl_debug_detail) _dl_dprintf(_dl_debug_file,
1967 + "\tpatch %x ==> %x @ %x", *got_addr, new_addr, got_addr);
1970 + if (!_dl_debug_nofixups) {
1971 + *got_addr = new_addr;
1974 + *got_addr = new_addr;
1977 + return (unsigned long) new_addr;
1981 +_dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope,
1982 + unsigned long rel_addr, unsigned long rel_size,
1983 + int (*reloc_fnc) (struct elf_resolve *tpnt, struct dyn_elf *scope,
1984 + ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab))
1989 + Elf32_Sym *symtab;
1992 + /* Now parse the relocation information */
1994 + rpnt = (ELF_RELOC *) (rel_addr + tpnt->loadaddr);
1995 + rel_size = rel_size / sizeof(ELF_RELOC);
1997 + symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
1998 + strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
2000 + for (i = 0; i < rel_size; i++, rpnt++) {
2003 + symtab_index = ELF32_R_SYM(rpnt->r_info);
2005 + /* When the dynamic linker bootstrapped itself, it resolved some symbols.
2006 + Make sure we do not do them again */
2007 + if (!symtab_index && tpnt->libtype == program_interpreter)
2009 + if (symtab_index && tpnt->libtype == program_interpreter &&
2010 + _dl_symbol(strtab + symtab[symtab_index].st_name))
2013 +#if defined (__SUPPORT_LD_DEBUG__)
2014 + debug_sym(symtab,strtab,symtab_index);
2015 + debug_reloc(symtab,strtab,rpnt);
2018 + res = reloc_fnc (tpnt, scope, rpnt, symtab, strtab);
2020 + if (res==0) continue;
2022 + _dl_dprintf(2, "\n%s: ",_dl_progname);
2025 + _dl_dprintf(2, "symbol '%s': ", strtab + symtab[symtab_index].st_name);
2029 + int reloc_type = ELF32_R_TYPE(rpnt->r_info);
2030 +#if defined (__SUPPORT_LD_DEBUG__)
2031 + _dl_dprintf(2, "can't handle reloc type %s\n ", _dl_reltypes(reloc_type));
2033 + _dl_dprintf(2, "can't handle reloc type %x\n", reloc_type);
2039 + _dl_dprintf(2, "can't resolve symbol\n");
2046 +static unsigned long
2047 +fix_bad_pc24 (unsigned long *const reloc_addr, unsigned long value)
2049 + static void *fix_page;
2050 + static unsigned int fix_offset;
2051 + unsigned int *fix_address;
2054 + fix_page = _dl_mmap (NULL, 4096 , PROT_READ | PROT_WRITE | PROT_EXEC,
2055 + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
2059 + fix_address = (unsigned int *)(fix_page + fix_offset);
2060 + fix_address[0] = 0xe51ff004; /* ldr pc, [pc, #-4] */
2061 + fix_address[1] = value;
2064 + if (fix_offset >= 4096)
2067 + return (unsigned long)fix_address;
2071 +_dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope,
2072 + ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)
2076 + unsigned long *reloc_addr;
2077 + unsigned long symbol_addr;
2080 + reloc_addr = (unsigned long *) (tpnt->loadaddr + (unsigned long) rpnt->r_offset);
2081 + reloc_type = ELF32_R_TYPE(rpnt->r_info);
2082 + symtab_index = ELF32_R_SYM(rpnt->r_info);
2085 + if (symtab_index) {
2087 + symbol_addr = (unsigned long) _dl_find_hash(strtab + symtab[symtab_index].st_name,
2088 + scope, (reloc_type == R_ARM_JUMP_SLOT ? tpnt : NULL), symbolrel);
2091 + * We want to allow undefined references to weak symbols - this might
2092 + * have been intentional. We should not be linking local symbols
2093 + * here, so all bases should be covered.
2095 + if (!symbol_addr && ELF32_ST_BIND(symtab[symtab_index].st_info) == STB_GLOBAL) {
2100 +#if defined (__SUPPORT_LD_DEBUG__)
2102 + unsigned long old_val = *reloc_addr;
2104 + switch (reloc_type) {
2108 + *reloc_addr += symbol_addr;
2112 + unsigned long addend;
2113 + long newvalue, topbits;
2115 + addend = *reloc_addr & 0x00ffffff;
2116 + if (addend & 0x00800000) addend |= 0xff000000;
2118 + newvalue = symbol_addr - (unsigned long)reloc_addr + (addend << 2);
2119 + topbits = newvalue & 0xfe000000;
2120 + if (topbits != 0xfe000000 && topbits != 0x00000000)
2122 + newvalue = fix_bad_pc24(reloc_addr, symbol_addr)
2123 + - (unsigned long)reloc_addr + (addend << 2);
2124 + topbits = newvalue & 0xfe000000;
2125 + if (topbits != 0xfe000000 && topbits != 0x00000000)
2127 + _dl_dprintf(2,"symbol '%s': R_ARM_PC24 relocation out of range.",
2128 + symtab[symtab_index].st_name);
2133 + symbol_addr = (*reloc_addr & 0xff000000) | (newvalue & 0x00ffffff);
2134 + *reloc_addr = symbol_addr;
2137 + case R_ARM_GLOB_DAT:
2138 + case R_ARM_JUMP_SLOT:
2139 + *reloc_addr = symbol_addr;
2141 + case R_ARM_RELATIVE:
2142 + *reloc_addr += (unsigned long) tpnt->loadaddr;
2146 + /* Do this later */
2147 + _dl_dprintf(2, "Doing copy for symbol ");
2148 + if (symtab_index) _dl_dprintf(2, strtab + symtab[symtab_index].st_name);
2149 + _dl_dprintf(2, "\n");
2150 + _dl_memcpy((void *) symtab[symtab_index].st_value,
2151 + (void *) symbol_addr, symtab[symtab_index].st_size);
2155 + return -1; /*call _dl_exit(1) */
2157 +#if defined (__SUPPORT_LD_DEBUG__)
2158 + if(_dl_debug_reloc && _dl_debug_detail)
2159 + _dl_dprintf(_dl_debug_file, "\tpatch: %x ==> %x @ %x", old_val, *reloc_addr, reloc_addr);
2168 +_dl_do_lazy_reloc (struct elf_resolve *tpnt, struct dyn_elf *scope,
2169 + ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)
2172 + unsigned long *reloc_addr;
2174 + reloc_addr = (unsigned long *) (tpnt->loadaddr + (unsigned long) rpnt->r_offset);
2175 + reloc_type = ELF32_R_TYPE(rpnt->r_info);
2177 +#if defined (__SUPPORT_LD_DEBUG__)
2179 + unsigned long old_val = *reloc_addr;
2181 + switch (reloc_type) {
2184 + case R_ARM_JUMP_SLOT:
2185 + *reloc_addr += (unsigned long) tpnt->loadaddr;
2188 + return -1; /*call _dl_exit(1) */
2190 +#if defined (__SUPPORT_LD_DEBUG__)
2191 + if(_dl_debug_reloc && _dl_debug_detail)
2192 + _dl_dprintf(_dl_debug_file, "\tpatch: %x ==> %x @ %x", old_val, *reloc_addr, reloc_addr);
2200 +/* This is done as a separate step, because there are cases where
2201 + information is first copied and later initialized. This results in
2202 + the wrong information being copied. Someone at Sun was complaining about
2203 + a bug in the handling of _COPY by SVr4, and this may in fact be what he
2204 + was talking about. Sigh. */
2206 +/* No, there are cases where the SVr4 linker fails to emit COPY relocs
2209 +_dl_do_copy (struct elf_resolve *tpnt, struct dyn_elf *scope,
2210 + ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)
2214 + unsigned long *reloc_addr;
2215 + unsigned long symbol_addr;
2218 + reloc_addr = (unsigned long *) (tpnt->loadaddr + (unsigned long) rpnt->r_offset);
2219 + reloc_type = ELF32_R_TYPE(rpnt->r_info);
2220 + if (reloc_type != R_ARM_COPY)
2222 + symtab_index = ELF32_R_SYM(rpnt->r_info);
2225 + if (symtab_index) {
2227 + symbol_addr = (unsigned long) _dl_find_hash(strtab +
2228 + symtab[symtab_index].st_name, scope,
2230 + if (!symbol_addr) goof++;
2233 +#if defined (__SUPPORT_LD_DEBUG__)
2234 + if(_dl_debug_move)
2235 + _dl_dprintf(_dl_debug_file,"\n%s move %x bytes from %x to %x",
2236 + strtab + symtab[symtab_index].st_name,
2237 + symtab[symtab_index].st_size,
2238 + symbol_addr, symtab[symtab_index].st_value);
2240 + _dl_memcpy((char *) symtab[symtab_index].st_value,
2241 + (char *) symbol_addr, symtab[symtab_index].st_size);
2247 +void _dl_parse_lazy_relocation_information(struct elf_resolve *tpnt,
2248 + unsigned long rel_addr, unsigned long rel_size, int type)
2250 + (void)_dl_parse(tpnt, NULL, rel_addr, rel_size, _dl_do_lazy_reloc);
2253 +int _dl_parse_relocation_information(struct elf_resolve *tpnt,
2254 + unsigned long rel_addr, unsigned long rel_size, int type)
2256 + return _dl_parse(tpnt, tpnt->symbol_scope, rel_addr, rel_size, _dl_do_reloc);
2259 +int _dl_parse_copy_information(struct dyn_elf *xpnt, unsigned long rel_addr,
2260 + unsigned long rel_size, int type)
2262 + return _dl_parse(xpnt->dyn, xpnt->next, rel_addr, rel_size, _dl_do_copy);
2265 diff -urN uClibc/ldso-0.9.24/ldso/arm/ld_syscalls.h uClibc.ldso.24/ldso-0.9.24/ldso/arm/ld_syscalls.h
2266 --- uClibc/ldso-0.9.24/ldso/arm/ld_syscalls.h 1969-12-31 18:00:00.000000000 -0600
2267 +++ uClibc.ldso.24/ldso-0.9.24/ldso/arm/ld_syscalls.h 2003-09-09 01:11:11.000000000 -0500
2269 +/* Define the __set_errno macro as nothing so that INLINE_SYSCALL
2270 + * won't set errno, which is important since we make system calls
2271 + * before the errno symbol is dynamicly linked. */
2273 +#define __set_errno(X) {(void)(X);}
2275 +/* Prepare for the case that `__builtin_expect' is not available. */
2276 +#if __GNUC__ == 2 && __GNUC_MINOR__ < 96
2277 +#define __builtin_expect(x, expected_value) (x)
2280 +# define likely(x) __builtin_expect((!!(x)),1)
2283 +# define unlikely(x) __builtin_expect((!!(x)),0)
2286 +#include "sys/syscall.h"
2288 diff -urN uClibc/ldso-0.9.24/ldso/arm/ld_sysdep.h uClibc.ldso.24/ldso-0.9.24/ldso/arm/ld_sysdep.h
2289 --- uClibc/ldso-0.9.24/ldso/arm/ld_sysdep.h 1969-12-31 18:00:00.000000000 -0600
2290 +++ uClibc.ldso.24/ldso-0.9.24/ldso/arm/ld_sysdep.h 2002-08-09 09:41:04.000000000 -0500
2293 + * Various assmbly language/system dependent hacks that are required
2294 + * so that we can minimize the amount of platform specific code.
2298 + * Define this if the system uses RELOCA.
2300 +#undef ELF_USES_RELOCA
2303 + * Get a pointer to the argv array. On many platforms this can be just
2304 + * the address if the first argument, on other platforms we need to
2305 + * do something a little more subtle here.
2307 +#define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned long*) ARGS)
2310 + * Initialization sequence for a GOT.
2312 +#define INIT_GOT(GOT_BASE,MODULE) \
2314 + GOT_BASE[2] = (unsigned long) _dl_linux_resolve; \
2315 + GOT_BASE[1] = (unsigned long) MODULE; \
2319 + * Here is a macro to perform a relocation. This is only used when
2320 + * bootstrapping the dynamic loader. RELP is the relocation that we
2321 + * are performing, REL is the pointer to the address we are relocating.
2322 + * SYMBOL is the symbol involved in the relocation, and LOAD is the
2325 +#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD) \
2326 + switch(ELF32_R_TYPE((RELP)->r_info)){ \
2327 + case R_ARM_ABS32: \
2330 + case R_ARM_PC24: \
2331 + { long newvalue, topbits; \
2332 + unsigned long addend = *REL & 0x00ffffff; \
2333 + if (addend & 0x00800000) addend |= 0xff000000; \
2334 + newvalue=SYMBOL-(unsigned long)REL+(addend<<2); \
2335 + topbits = newvalue & 0xfe000000; \
2336 + if (topbits!=0xfe000000&&topbits!=0x00000000){ \
2337 + newvalue = fix_bad_pc24(REL, SYMBOL) \
2338 + -(unsigned long)REL+(addend<<2); \
2339 + topbits = newvalue & 0xfe000000; \
2340 + if (topbits!=0xfe000000&&topbits!=0x00000000){ \
2341 + SEND_STDERR("R_ARM_PC24 relocation out of range\n");\
2342 + _dl_exit(1); } } \
2344 + SYMBOL=(*REL&0xff000000)|(newvalue & 0x00ffffff); \
2348 + case R_ARM_GLOB_DAT: \
2349 + case R_ARM_JUMP_SLOT: \
2352 + case R_ARM_RELATIVE: \
2353 + *REL += (unsigned long) LOAD; \
2355 + case R_ARM_NONE: \
2358 + SEND_STDERR("Aiieeee!"); \
2364 + * Transfer control to the user's application, once the dynamic loader
2365 + * is done. This routine has to exit the current function, then
2366 + * call the _dl_elf_main function.
2369 +#define START() return _dl_elf_main;
2373 +/* Here we define the magic numbers that this dynamic loader should accept */
2375 +#define MAGIC1 EM_ARM
2377 +/* Used for error messages */
2378 +#define ELF_TARGET "ARM"
2380 +struct elf_resolve;
2381 +unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
2383 +static inline unsigned long arm_modulus(unsigned long m, unsigned long p) {
2384 + unsigned long i,t,inc;
2386 + while(!(i&(1<<31))) {
2391 + for(inc=t;inc>2;inc--) {
2410 +#define do_rem(result, n, base) result=arm_modulus(n,base);
2412 +/* 4096 bytes alignment */
2413 +#define PAGE_ALIGN 0xfffff000
2414 +#define ADDR_ALIGN 0xfff
2415 +#define OFFS_ALIGN 0x7ffff000
2416 diff -urN uClibc/ldso-0.9.24/ldso/arm/resolve.S uClibc.ldso.24/ldso-0.9.24/ldso/arm/resolve.S
2417 --- uClibc/ldso-0.9.24/ldso/arm/resolve.S 1969-12-31 18:00:00.000000000 -0600
2418 +++ uClibc.ldso.24/ldso-0.9.24/ldso/arm/resolve.S 2002-08-12 04:03:30.000000000 -0500
2421 + * This function is _not_ called directly. It is jumped to (so no return
2422 + * address is on the stack) when attempting to use a symbol that has not yet
2423 + * been resolved. The first time a jump symbol (such as a function call inside
2424 + * a shared library) is used (before it gets resolved) it will jump here to
2425 + * _dl_linux_resolve. When we get called the stack looks like this:
2429 + * This function saves all the registers, puts a copy of reloc_entry and tpnt
2430 + * on the stack (as function arguments) then make the function call
2431 + * _dl_linux_resolver(tpnt, reloc_entry). _dl_linux_resolver() figures out
2432 + * where the jump symbol is _really_ supposed to have jumped to and returns
2433 + * that to us. Once we have that, we overwrite tpnt with this fixed up
2434 + * address. We then clean up after ourselves, put all the registers back how we
2435 + * found them, then we jump to the fixed up address, which is where the jump
2436 + * symbol that got us here really wanted to jump to in the first place.
2445 +.globl _dl_linux_resolve
2446 +.type _dl_linux_resolve,%function
2450 + stmdb sp!, {r0, r1, r2, r3, sl, fp}
2457 + bl _dl_linux_resolver
2460 + ldmia sp!, {r0, r1, r2, r3, sl, fp, lr}
2462 +.size _dl_linux_resolve, .-_dl_linux_resolve
2463 diff -urN uClibc/ldso-0.9.24/ldso/cris/boot1_arch.h uClibc.ldso.24/ldso-0.9.24/ldso/cris/boot1_arch.h
2464 --- uClibc/ldso-0.9.24/ldso/cris/boot1_arch.h 1969-12-31 18:00:00.000000000 -0600
2465 +++ uClibc.ldso.24/ldso-0.9.24/ldso/cris/boot1_arch.h 2003-09-19 07:11:43.000000000 -0500
2468 + * This code fix the stack pointer so that the dynamic linker
2469 + * can find argc, argv and auxvt (Auxillary Vector Table).
2473 +" .globl _dl_boot\n" \
2474 +" .type _dl_boot,@function\n" \
2476 +" move.d $sp,$r10\n" \
2477 +" move.d $pc,$r9\n" \
2478 +" add.d _dl_boot2 - ., $r9\n" \
2482 +#define _dl_boot _dl_boot2
2483 +#define LD_BOOT(X) static void * __attribute__ ((unused)) _dl_boot(X)
2484 diff -urN uClibc/ldso-0.9.24/ldso/cris/elfinterp.c uClibc.ldso.24/ldso-0.9.24/ldso/cris/elfinterp.c
2485 --- uClibc/ldso-0.9.24/ldso/cris/elfinterp.c 1969-12-31 18:00:00.000000000 -0600
2486 +++ uClibc.ldso.24/ldso-0.9.24/ldso/cris/elfinterp.c 2003-09-30 06:51:11.000000000 -0500
2489 + * CRIS ELF shared library loader support.
2491 + * Program to load an elf binary on a linux system, and run it.
2492 + * References to symbols in sharable libraries can be resolved
2493 + * by either an ELF sharable library or a linux style of shared
2496 + * Copyright (C) 2002, Axis Communications AB
2497 + * All rights reserved
2499 + * Author: Tobias Anderberg, <tobiasa@axis.com>
2501 + * Redistribution and use in source and binary forms, with or without
2502 + * modification, are permitted provided that the following conditions
2504 + * 1. Redistributions of source code must retain the above copyright
2505 + * notice, this list of conditions and the following disclaimer.
2506 + * 2. The name of the above contributors may not be
2507 + * used to endorse or promote products derived from this software
2508 + * without specific prior written permission.
2510 + * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
2511 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2512 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2513 + * ARE DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE
2514 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2515 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2516 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2517 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2518 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2519 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2523 +/* Support for the LD_DEBUG variable. */
2524 +#if defined (__SUPPORT_LD_DEBUG__)
2525 +static const char *_dl_reltypes_tab[] = {
2526 + [0] "R_CRIS_NONE", "R_CRIS_8", "R_CRIS_16", "R_CRIS_32",
2527 + [4] "R_CRIS_8_PCREL", "R_CRIS_16_PCREL", "R_CRIS_32_PCREL", "R_CRIS_GNU_VTINHERIT",
2528 + [8] "R_CRIS_GNU_VTENTRY", "R_CRIS_COPY", "R_CRIS_GLOB_DAT", "R_CRIS_JUMP_SLOT",
2529 + [16] "R_CRIS_RELATIVE", "R_CRIS_16_GOT", "R_CRIS_32_GOT", "R_CRIS_16_GOTPLT",
2530 + [32] "R_CRIS_32_GOTPLT", "R_CRIS_32_GOTREL", "R_CRIS_32_PLT_GOTREL", "R_CRIS_32_PLT_PCREL",
2535 +static const char *
2536 +_dl_reltypes(int type)
2539 + static char buf[22];
2541 + if (type >= (sizeof(_dl_reltypes_tab)/sizeof(_dl_reltypes_tab[0])) ||
2542 + NULL == (str = _dl_reltypes_tab[type]))
2543 + str = _dl_simple_ltoa(buf, (unsigned long) (type));
2549 +debug_sym(Elf32_Sym *symtab, char *strtab, int symtab_index)
2551 + if (_dl_debug_symbols) {
2552 + if (symtab_index) {
2553 + _dl_dprintf(_dl_debug_file,
2554 + "\n%s\tvalue=%x\tsize=%x\tinfo=%x\tother=%x\tshndx=%x",
2555 + strtab + symtab[symtab_index].st_name,
2556 + symtab[symtab_index].st_value,
2557 + symtab[symtab_index].st_size,
2558 + symtab[symtab_index].st_info,
2559 + symtab[symtab_index].st_other,
2560 + symtab[symtab_index].st_shndx);
2566 +debug_reloc(Elf32_Sym *symtab, char *strtab, ELF_RELOC *rpnt)
2568 + if (_dl_debug_reloc) {
2572 + symtab_index = ELF32_R_SYM(rpnt->r_info);
2573 + sym = symtab_index ? strtab + symtab[symtab_index].st_name : "sym=0x0";
2575 + if (_dl_debug_symbols)
2576 + _dl_dprintf(_dl_debug_file, "\n\t");
2578 + _dl_dprintf(_dl_debug_file, "\n%s\n\t", sym);
2580 +#ifdef ELF_USES_RELOCA
2581 + _dl_dprintf(_dl_debug_file, "%s\toffset=%x\taddend=%x",
2582 + _dl_reltypes(ELF32_R_TYPE(rpnt->r_info)),
2586 + _dl_dprintf(_dl_debug_file, "%s\toffset%x\n",
2587 + _dl_reltypes(ELF32_R_TYPE(rpnt->r_info)),
2592 +#endif /* __SUPPORT_LD_DEBUG__ */
2594 +/* Defined in resolve.S. */
2595 +extern int _dl_linux_resolv(void);
2598 +_dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
2607 + Elf32_Sym *symtab;
2608 + ELF_RELOC *this_reloc;
2609 + unsigned long instr_addr;
2611 + rel_addr = (char *) (tpnt->dynamic_info[DT_JMPREL] + tpnt->loadaddr);
2613 + this_reloc = (ELF_RELOC *) (intptr_t)(rel_addr + reloc_entry);
2614 + reloc_type = ELF32_R_TYPE(this_reloc->r_info);
2615 + symtab_index = ELF32_R_SYM(this_reloc->r_info);
2617 + symtab = (Elf32_Sym *) (intptr_t)(tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
2618 + strtab = (char *)(tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
2619 + symname = strtab + symtab[symtab_index].st_name;
2621 + if (reloc_type != R_CRIS_JUMP_SLOT) {
2622 + _dl_dprintf(2, "%s: Incorrect relocation type for jump relocations.\n",
2627 + /* Fetch the address of the jump instruction to fix up. */
2628 + instr_addr = ((unsigned long) this_reloc->r_offset + (unsigned long) tpnt->loadaddr);
2629 + got_addr = (char **) instr_addr;
2631 + /* Fetch the address of the GOT entry. */
2632 + new_addr = _dl_find_hash(symname, tpnt->symbol_scope, tpnt, resolver);
2635 + new_addr = _dl_find_hash(symname, NULL, NULL, resolver);
2638 + return (unsigned long) new_addr;
2640 + _dl_dprintf(2, "%s: Can't resolv symbol '%s'\n", _dl_progname, symname);
2644 +#if defined (__SUPPORT_LD_DEBUG__)
2645 + if (_dl_debug_bindings) {
2646 + _dl_dprintf(_dl_debug_file, "\nresolve function: %s", symname);
2648 + if (_dl_debug_detail)
2649 + _dl_dprintf(_dl_debug_file, "\tpatch %x ==> %x @ %x", *got_addr, new_addr, got_addr);
2653 + *got_addr = new_addr;
2654 + return (unsigned long) new_addr;
2658 +_dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope, unsigned long rel_addr,
2659 + unsigned long rel_size, int (*reloc_fnc)(struct elf_resolve *tpnt, struct dyn_elf *scope,
2660 + ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab))
2666 + Elf32_Sym *symtab;
2669 + /* Parse the relocation information. */
2670 + rpnt = (ELF_RELOC *) (intptr_t) (rel_addr + tpnt->loadaddr);
2671 + rel_size /= sizeof(ELF_RELOC);
2673 + symtab = (Elf32_Sym *) (intptr_t) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
2674 + strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
2676 + for (i = 0; i < rel_size; i++, rpnt++) {
2677 + symtab_index = ELF32_R_SYM(rpnt->r_info);
2680 + * Make sure the same symbols that the linker resolved when it
2681 + * bootstapped itself isn't resolved again.
2683 + if (!symtab_index && tpnt->libtype == program_interpreter)
2686 + if (symtab_index && tpnt->libtype == program_interpreter &&
2687 + _dl_symbol(strtab + symtab[symtab_index].st_name))
2690 +#if defined (__SUPPORT_LD_DEBUG__)
2691 + debug_sym(symtab, strtab, symtab_index);
2692 + debug_reloc(symtab, strtab, rpnt);
2695 + /* Pass over to actual relocation function. */
2696 + res = reloc_fnc(tpnt, scope, rpnt, symtab, strtab);
2701 + _dl_dprintf(2, "\n%s: ", _dl_progname);
2704 + _dl_dprintf(2, "symbol '%s': ", strtab + symtab[symtab_index].st_name);
2707 + int reloc_type = ELF32_R_TYPE(rpnt->r_info);
2709 +#if defined (__SUPPORT_LD_DEBUG__)
2710 + _dl_dprintf(2, "can't handle relocation type '%s'\n", _dl_reltypes(reloc_type));
2712 + _dl_dprintf(2, "can't handle relocation type %x\n", reloc_type);
2716 + else if (res > 0) {
2717 + _dl_dprintf(2, "can't resolv symbol\n");
2726 +_dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, ELF_RELOC *rpnt,
2727 + Elf32_Sym *symtab, char *strtab)
2732 + unsigned long *reloc_addr;
2733 + unsigned symbol_addr;
2734 +#if defined (__SUPPORT_LD_DEBUG__)
2735 + unsigned long old_val;
2738 + reloc_addr = (unsigned long *)(intptr_t)(tpnt->loadaddr + (unsigned long) rpnt->r_offset);
2739 + reloc_type = ELF32_R_TYPE(rpnt->r_info);
2740 + symtab_index = ELF32_R_SYM(rpnt->r_info);
2742 + symname = strtab + symtab[symtab_index].st_name;
2744 + if (symtab_index) {
2745 + if (symtab[symtab_index].st_shndx != SHN_UNDEF &&
2746 + ELF32_ST_BIND(symtab[symtab_index].st_info) == STB_LOCAL) {
2747 + symbol_addr = (unsigned long) tpnt->loadaddr;
2750 + symbol_addr = (unsigned long) _dl_find_hash(symname, scope,
2751 + (reloc_type == R_CRIS_JUMP_SLOT ? tpnt : NULL), symbolrel);
2754 + if (!symbol_addr && ELF32_ST_BIND(symtab[symtab_index].st_info) == STB_GLOBAL) {
2755 +#if defined (__SUPPORT_LD_DEBUG__)
2756 + _dl_dprintf(2, "\tglobal symbol '%s' already defined in '%s'\n",
2757 + symname, tpnt->libname);
2762 + symbol_addr += rpnt->r_addend;
2765 +#if defined (__SUPPORT_LD_DEBUG__)
2766 + old_val = *reloc_addr;
2769 + switch (reloc_type) {
2772 + case R_CRIS_GLOB_DAT:
2773 + case R_CRIS_JUMP_SLOT:
2776 + *reloc_addr = symbol_addr;
2778 + case R_CRIS_RELATIVE:
2779 + *reloc_addr = (unsigned long) tpnt->loadaddr + rpnt->r_addend;
2782 + return -1; /* Call _dl_exit(1). */
2785 +#if defined (__SUPPORT_LD_DEBUG__)
2786 + if (_dl_debug_reloc && _dl_debug_detail)
2787 + _dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x", old_val, *reloc_addr, reloc_addr);
2794 +_dl_do_lazy_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, ELF_RELOC *rpnt,
2795 + Elf32_Sym *symtab, char *strtab)
2798 + unsigned long *reloc_addr;
2799 +#if defined (__SUPPORT_LD_DEBUG__)
2800 + unsigned long old_val;
2803 + /* Don't care about these, just keep the compiler happy. */
2808 + reloc_addr = (unsigned long *)(intptr_t)(tpnt->loadaddr + (unsigned long) rpnt->r_offset);
2809 + reloc_type = ELF32_R_TYPE(rpnt->r_info);
2811 +#if defined (__SUPPORT_LD_DEBUG__)
2812 + old_val = *reloc_addr;
2815 + switch (reloc_type) {
2818 + case R_CRIS_JUMP_SLOT:
2819 + *reloc_addr += (unsigned long) tpnt->loadaddr;
2822 + return -1; /* Calls _dl_exit(1). */
2825 +#if defined (__SUPPORT_LD_DEBUG__)
2826 + if (_dl_debug_reloc && _dl_debug_detail)
2827 + _dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x", old_val, *reloc_addr, reloc_addr);
2834 +_dl_do_copy_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, ELF_RELOC *rpnt,
2835 + Elf32_Sym *symtab, char *strtab)
2841 + unsigned long *reloc_addr;
2842 + unsigned long symbol_addr;
2844 + reloc_addr = (unsigned long *)(intptr_t) (tpnt->loadaddr + (unsigned long) rpnt->r_offset);
2845 + reloc_type = ELF32_R_TYPE(rpnt->r_info);
2847 + if (reloc_type != R_CRIS_COPY)
2850 + symtab_index = ELF32_R_SYM(rpnt->r_info);
2852 + symname = strtab + symtab[symtab_index].st_name;
2855 + if (symtab_index) {
2856 + symbol_addr = (unsigned long) _dl_find_hash(symname, scope, NULL, copyrel);
2863 +#if defined (__SUPPORT_LD_DEBUG__)
2864 + if (_dl_debug_move)
2865 + _dl_dprintf(_dl_debug_file, "\n%s move %x bytes from %x to %x",
2866 + symname, symtab[symtab_index].st_size, symbol_addr, symtab[symtab_index].st_value);
2868 + _dl_memcpy((char *) symtab[symtab_index].st_value,
2869 + (char *) symbol_addr, symtab[symtab_index].st_size);
2875 +/* External interface to the generic part of the dynamic linker. */
2878 +_dl_parse_relocation_information(struct elf_resolve *tpnt, unsigned long rel_addr,
2879 + unsigned long rel_size, int type)
2881 + /* Keep the compiler happy. */
2883 + return _dl_parse(tpnt, tpnt->symbol_scope, rel_addr, rel_size, _dl_do_reloc);
2886 +_dl_parse_lazy_relocation_information(struct elf_resolve *tpnt, unsigned long rel_addr,
2887 + unsigned long rel_size, int type)
2889 + /* Keep the compiler happy. */
2891 + _dl_parse(tpnt, NULL, rel_addr, rel_size, _dl_do_lazy_reloc);
2895 +_dl_parse_copy_information(struct dyn_elf *xpnt, unsigned long rel_addr,
2896 + unsigned long rel_size, int type)
2898 + /* Keep the compiler happy. */
2900 + return _dl_parse(xpnt->dyn, xpnt->next, rel_addr, rel_size, _dl_do_copy_reloc);
2902 diff -urN uClibc/ldso-0.9.24/ldso/cris/ld_syscalls.h uClibc.ldso.24/ldso-0.9.24/ldso/cris/ld_syscalls.h
2903 --- uClibc/ldso-0.9.24/ldso/cris/ld_syscalls.h 1969-12-31 18:00:00.000000000 -0600
2904 +++ uClibc.ldso.24/ldso-0.9.24/ldso/cris/ld_syscalls.h 2002-09-23 05:37:16.000000000 -0500
2907 + * Define the __set_errno macro as nothing so that INLINE_SYSCALL
2908 + * won't set errno, which is important since we make system calls
2909 + * before the errno symbol is dynamicly linked.
2911 +#define __set_errno(X) {(void)(X);}
2912 +#include "sys/syscall.h"
2913 diff -urN uClibc/ldso-0.9.24/ldso/cris/ld_sysdep.h uClibc.ldso.24/ldso-0.9.24/ldso/cris/ld_sysdep.h
2914 --- uClibc/ldso-0.9.24/ldso/cris/ld_sysdep.h 1969-12-31 18:00:00.000000000 -0600
2915 +++ uClibc.ldso.24/ldso-0.9.24/ldso/cris/ld_sysdep.h 2003-08-27 07:59:23.000000000 -0500
2917 +/* CRIS can never use Elf32_Rel relocations. */
2918 +#define ELF_USES_RELOCA
2921 + * Get a pointer to the argv array. On many platforms this can be just
2922 + * the address if the first argument, on other platforms we need to
2923 + * do something a little more subtle here.
2925 +#define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned long *) ARGS)
2928 + * Initialization sequence for a GOT.
2930 +#define INIT_GOT(GOT_BASE,MODULE) \
2932 + GOT_BASE[1] = (unsigned long) MODULE; \
2933 + GOT_BASE[2] = (unsigned long) _dl_linux_resolve; \
2937 + * Here is a macro to perform a relocation. This is only used when
2938 + * bootstrapping the dynamic loader. RELP is the relocation that we
2939 + * are performing, REL is the pointer to the address we are relocating.
2940 + * SYMBOL is the symbol involved in the relocation, and LOAD is the
2943 +#define PERFORM_BOOTSTRAP_RELOC(RELP, REL, SYMBOL, LOAD) \
2944 + switch (ELF32_R_TYPE((RELP)->r_info)) { \
2945 + case R_CRIS_GLOB_DAT: \
2946 + case R_CRIS_JUMP_SLOT: \
2950 + case R_CRIS_16_PCREL: \
2951 + *(short *) *REL = SYMBOL + (RELP)->r_addend - *REL - 2; \
2953 + case R_CRIS_32_PCREL: \
2954 + *REL = SYMBOL + (RELP)->r_addend - *REL - 4; \
2956 + case R_CRIS_NONE: \
2958 + case R_CRIS_RELATIVE: \
2959 + *REL = (unsigned long) LOAD + (RELP)->r_addend; \
2967 + * Transfer control to the user's application once the dynamic loader
2968 + * is done. This routine has to exit the current function, then call
2971 +#define START() __asm__ volatile ("moveq 0,$r8\n\t" \
2972 + "move $r8,$srp\n\t" \
2973 + "move.d %1,$sp\n\t" \
2975 + : : "r" (_dl_elf_main), "r" (args))
2977 +/* Defined some magic numbers that this ld.so should accept. */
2978 +#define MAGIC1 EM_CRIS
2980 +#define ELF_TARGET "CRIS"
2982 +struct elf_resolve;
2983 +extern unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry);
2985 +/* Cheap modulo implementation, taken from arm/ld_sysdep.h. */
2986 +static inline unsigned long
2987 +cris_mod(unsigned long m, unsigned long p)
2989 + unsigned long i, t, inc;
2994 + while (!(i & (1 << 31))) {
3001 + for (inc = t; inc > 2; inc--) {
3004 + if (i & (1 << 31))
3010 + if (i & (1 << 31))
3023 +#define do_rem(result, n, base) result = cris_mod(n, base);
3025 +/* 8192 bytes alignment */
3026 +#define PAGE_ALIGN 0xffffe000
3027 +#define ADDR_ALIGN 0x1fff
3028 +#define OFFS_ALIGN 0xffffe000
3029 diff -urN uClibc/ldso-0.9.24/ldso/cris/resolve.S uClibc.ldso.24/ldso-0.9.24/ldso/cris/resolve.S
3030 --- uClibc/ldso-0.9.24/ldso/cris/resolve.S 1969-12-31 18:00:00.000000000 -0600
3031 +++ uClibc.ldso.24/ldso-0.9.24/ldso/cris/resolve.S 2002-09-16 03:11:43.000000000 -0500
3034 + * This function is _not_ called directly. It is jumped to from PLT when
3035 + * attempting to use a symbol that has not yet been resolved. The first
3036 + * time a jump symbol (such as a function call inside a shared library)
3037 + * is used (before it gets resolved) it will jump here. When we get called
3038 + * the stack contains reloc_offset and tpnt is in MOF.
3040 + * We save all the registers, setup R10 and R11 with the right arguments
3041 + * then call _dl_linux_resolver(tpnt, reloc_offset). _dl_linux_resolver()
3042 + * figures out where the jump symbol is _really_ supposed to have jumped to
3043 + * and returns that to us. Once we have that, we overwrite tpnt with this
3044 + * fixed up address. We then clean up after ourselves, put all the registers
3045 + * back how we found them, then we jump to where the fixed up address, which
3046 + * is where the jump symbol that got us here really wanted to jump to in the
3050 +.globl _dl_linux_resolve
3051 +.type _dl_linux_resolve,@function
3060 + move.d [$sp+6*4],$r11
3064 + sub.d .:GOTOFF,$r0
3065 + move.d _dl_linux_resolver:PLTG,$r9
3069 + jsr _dl_linux_resolver
3071 + move.d $r10,[$sp+6*4]
3080 + .size _dl_linux_resolve, . - _dl_linux_resolve
3081 diff -urN uClibc/ldso-0.9.24/ldso/hash.c uClibc.ldso.24/ldso-0.9.24/ldso/hash.c
3082 --- uClibc/ldso-0.9.24/ldso/hash.c 1969-12-31 18:00:00.000000000 -0600
3083 +++ uClibc.ldso.24/ldso-0.9.24/ldso/hash.c 2003-08-19 08:11:06.000000000 -0500
3085 +/* vi: set sw=4 ts=4: */
3086 +/* Program to load an ELF binary on a linux system, and run it
3087 + * after resolving ELF shared library symbols
3089 + * Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald,
3090 + * David Engel, Hongjiu Lu and Mitch D'Souza
3091 + * Copyright (C) 2001-2002, Erik Andersen
3093 + * All rights reserved.
3095 + * Redistribution and use in source and binary forms, with or without
3096 + * modification, are permitted provided that the following conditions
3098 + * 1. Redistributions of source code must retain the above copyright
3099 + * notice, this list of conditions and the following disclaimer.
3100 + * 2. The name of the above contributors may not be
3101 + * used to endorse or promote products derived from this software
3102 + * without specific prior written permission.
3104 + * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
3105 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
3106 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
3107 + * ARE DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE
3108 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3109 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3110 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3111 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3112 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3113 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3118 +/* Various symbol table handling functions, including symbol lookup */
3121 + * This is the start of the linked list that describes all of the files present
3122 + * in the system with pointers to all of the symbol, string, and hash tables,
3123 + * as well as all of the other good stuff in the binary.
3126 +struct elf_resolve *_dl_loaded_modules = NULL;
3129 + * This is the list of modules that are loaded when the image is first
3130 + * started. As we add more via dlopen, they get added into other
3133 +struct dyn_elf *_dl_symbol_tables = NULL;
3136 + * This is the list of modules that are loaded via dlopen. We may need
3137 + * to search these for RTLD_GLOBAL files.
3139 +struct dyn_elf *_dl_handles = NULL;
3143 + * This is the hash function that is used by the ELF linker to generate
3144 + * the hash table that each executable and library is required to
3145 + * have. We need it to decode the hash table.
3148 +unsigned long _dl_elf_hash(const char *name)
3150 + unsigned long hash = 0;
3151 + unsigned long tmp;
3154 + hash = (hash << 4) + *name++;
3155 + if ((tmp = hash & 0xf0000000))
3156 + hash ^= tmp >> 24;
3163 + * Check to see if a library has already been added to the hash chain.
3165 +struct elf_resolve *_dl_check_hashed_files(const char *libname)
3167 + struct elf_resolve *tpnt;
3168 + int len = _dl_strlen(libname);
3170 + for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
3171 + if (_dl_strncmp(tpnt->libname, libname, len) == 0 &&
3172 + (tpnt->libname[len] == '\0' || tpnt->libname[len] == '.'))
3180 + * We call this function when we have just read an ELF library or executable.
3181 + * We add the relevant info to the symbol chain, so that we can resolve all
3182 + * externals properly.
3185 +struct elf_resolve *_dl_add_elf_hash_table(const char *libname,
3186 + char *loadaddr, unsigned long *dynamic_info, unsigned long dynamic_addr,
3187 + unsigned long dynamic_size)
3189 + unsigned long *hash_addr;
3190 + struct elf_resolve *tpnt;
3193 + if (!_dl_loaded_modules) {
3194 + tpnt = _dl_loaded_modules =
3195 + (struct elf_resolve *) _dl_malloc(sizeof(struct elf_resolve));
3196 + _dl_memset(tpnt, 0, sizeof(struct elf_resolve));
3198 + tpnt = _dl_loaded_modules;
3199 + while (tpnt->next)
3200 + tpnt = tpnt->next;
3201 + tpnt->next = (struct elf_resolve *) _dl_malloc(sizeof(struct elf_resolve));
3202 + _dl_memset(tpnt->next, 0, sizeof(struct elf_resolve));
3203 + tpnt->next->prev = tpnt;
3204 + tpnt = tpnt->next;
3207 + tpnt->next = NULL;
3208 + tpnt->init_flag = 0;
3209 + tpnt->libname = _dl_strdup(libname);
3210 + tpnt->dynamic_addr = (ElfW(Dyn) *)dynamic_addr;
3211 + tpnt->dynamic_size = dynamic_size;
3212 + tpnt->libtype = loaded_file;
3214 + if (dynamic_info[DT_HASH] != 0) {
3215 + hash_addr = (unsigned long *) (intptr_t)(dynamic_info[DT_HASH] + loadaddr);
3216 + tpnt->nbucket = *hash_addr++;
3217 + tpnt->nchain = *hash_addr++;
3218 + tpnt->elf_buckets = hash_addr;
3219 + hash_addr += tpnt->nbucket;
3220 + tpnt->chains = hash_addr;
3222 + tpnt->loadaddr = (ElfW(Addr))loadaddr;
3223 + for (i = 0; i < 24; i++)
3224 + tpnt->dynamic_info[i] = dynamic_info[i];
3227 + Elf32_Dyn *dpnt = (Elf32_Dyn *) dynamic_addr;
3229 + while(dpnt->d_tag) {
3230 + if (dpnt->d_tag == DT_MIPS_GOTSYM)
3231 + tpnt->mips_gotsym = dpnt->d_un.d_val;
3232 + if (dpnt->d_tag == DT_MIPS_LOCAL_GOTNO)
3233 + tpnt->mips_local_gotno = dpnt->d_un.d_val;
3234 + if (dpnt->d_tag == DT_MIPS_SYMTABNO)
3235 + tpnt->mips_symtabno = dpnt->d_un.d_val;
3245 + * This function resolves externals, and this is either called when we process
3246 + * relocations or when we call an entry in the PLT table for the first time.
3249 +char *_dl_find_hash(const char *name, struct dyn_elf *rpnt1,
3250 + struct elf_resolve *f_tpnt, enum caller_type caller_type)
3252 + struct elf_resolve *tpnt;
3257 + Elf32_Sym *symtab;
3258 + unsigned long elf_hash_number, hn;
3259 + char *weak_result;
3260 + struct elf_resolve *first_def;
3261 + struct dyn_elf *rpnt, first;
3262 + char *data_result = 0; /* nakao */
3265 + elf_hash_number = _dl_elf_hash(name);
3267 + /* A quick little hack to make sure that any symbol in the executable
3268 + will be preferred to one in a shared library. This is necessary so
3269 + that any shared library data symbols referenced in the executable
3270 + will be seen at the same address by the executable, shared libraries
3271 + and dynamically loaded code. -Rob Ryan (robr@cmu.edu) */
3272 + if (_dl_symbol_tables && !caller_type && rpnt1) {
3273 + first = (*_dl_symbol_tables);
3274 + first.next = rpnt1;
3279 + * The passes are so that we can first search the regular symbols
3280 + * for whatever module was specified, and then search anything
3281 + * loaded with RTLD_GLOBAL. When pass is 1, it means we are just
3282 + * starting the first dlopened module, and anything above that
3283 + * is just the next one in the chain.
3285 + for (pass = 0; (1 == 1); pass++) {
3288 + * If we are just starting to search for RTLD_GLOBAL, setup
3289 + * the pointer for the start of the search.
3292 + rpnt1 = _dl_handles;
3296 + * Anything after this, we need to skip to the next module.
3298 + else if (pass >= 2) {
3299 + rpnt1 = rpnt1->next_handle;
3303 + * Make sure we still have a module, and make sure that this
3304 + * module was loaded with RTLD_GLOBAL.
3307 + if (rpnt1 == NULL)
3309 + if ((rpnt1->flags & RTLD_GLOBAL) == 0)
3313 + for (rpnt = (rpnt1 ? rpnt1 : _dl_symbol_tables); rpnt; rpnt = rpnt->next) {
3317 + * The idea here is that if we are using dlsym, we want to
3318 + * first search the entire chain loaded from dlopen, and
3319 + * return a result from that if we found anything. If this
3320 + * fails, then we continue the search into the stuff loaded
3321 + * when the image was activated. For normal lookups, we start
3322 + * with rpnt == NULL, so we should never hit this.
3324 + if (tpnt->libtype == elf_executable && weak_result != 0) {
3329 + * Avoid calling .urem here.
3331 + do_rem(hn, elf_hash_number, tpnt->nbucket);
3332 + symtab = (Elf32_Sym *) (intptr_t) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
3333 + strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
3335 + * This crap is required because the first instance of a
3336 + * symbol on the chain will be used for all symbol references.
3337 + * Thus this instance must be resolved to an address that
3338 + * contains the actual function,
3343 + for (si = tpnt->elf_buckets[hn]; si; si = tpnt->chains[si]) {
3344 + pnt = strtab + symtab[si].st_name;
3346 + if (_dl_strcmp(pnt, name) == 0 &&
3347 + symtab[si].st_value != 0)
3349 + if ((ELF32_ST_TYPE(symtab[si].st_info) == STT_FUNC ||
3350 + ELF32_ST_TYPE(symtab[si].st_info) == STT_NOTYPE ||
3351 + ELF32_ST_TYPE(symtab[si].st_info) == STT_OBJECT) &&
3352 + symtab[si].st_shndx != SHN_UNDEF) {
3354 + /* Here we make sure that we find a module where the symbol is
3355 + * actually defined.
3361 + if (first_def == f_tpnt
3362 + && symtab[si].st_shndx == 0)
3366 + switch (ELF32_ST_BIND(symtab[si].st_info)) {
3368 + if (tpnt->libtype != elf_executable &&
3369 + ELF32_ST_TYPE(symtab[si].st_info)
3372 + data_result = (char *)tpnt->loadaddr +
3373 + symtab[si].st_value; /* nakao */
3374 + break; /* nakao */
3375 + } else /* nakao */
3376 + return (char*)tpnt->loadaddr + symtab[si].st_value;
3379 + weak_result = (char *)tpnt->loadaddr + symtab[si].st_value;
3381 + default: /* Do local symbols need to be examined? */
3387 + * References to the address of a function from an executable file and
3388 + * the shared objects associated with it might not resolve to the same
3389 + * value. To allow comparisons of function addresses we must resolve
3390 + * to the address of the plt entry of the executable instead of the
3391 + * real function address.
3392 + * see "TIS ELF Specification Version 1.2, Book 3, A-11 (Function
3395 + if (resolver != caller_type &&
3396 + NULL==f_tpnt && /*trick: don't handle R_??_JMP_SLOT reloc type*/
3397 + tpnt->libtype == elf_executable &&
3398 + ELF32_ST_TYPE(symtab[si].st_info) == STT_FUNC &&
3399 + symtab[si].st_shndx == SHN_UNDEF)
3401 + return (char*)symtab[si].st_value;
3409 + return data_result; /* nakao */
3410 + return weak_result;
3412 diff -urN uClibc/ldso-0.9.24/ldso/i386/boot1_arch.h uClibc.ldso.24/ldso-0.9.24/ldso/i386/boot1_arch.h
3413 --- uClibc/ldso-0.9.24/ldso/i386/boot1_arch.h 1969-12-31 18:00:00.000000000 -0600
3414 +++ uClibc.ldso.24/ldso-0.9.24/ldso/i386/boot1_arch.h 2002-08-08 09:35:31.000000000 -0500
3416 +/* Any assmbly language/system dependent hacks needed to setup boot1.c so it
3417 + * will work as expected and cope with whatever platform specific wierdness is
3418 + * needed for this architecture. See arm/boot1_arch.h for an example of what
3422 +#define LD_BOOT(X) void _dl_boot (X)
3423 diff -urN uClibc/ldso-0.9.24/ldso/i386/elfinterp.c uClibc.ldso.24/ldso-0.9.24/ldso/i386/elfinterp.c
3424 --- uClibc/ldso-0.9.24/ldso/i386/elfinterp.c 1969-12-31 18:00:00.000000000 -0600
3425 +++ uClibc.ldso.24/ldso-0.9.24/ldso/i386/elfinterp.c 2003-11-06 16:09:38.000000000 -0600
3427 +/* vi: set sw=4 ts=4: */
3428 +/* i386 ELF shared library loader suppport
3430 + * Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald,
3431 + * David Engel, Hongjiu Lu and Mitch D'Souza
3432 + * Copyright (C) 2001-2002, Erik Andersen
3434 + * All rights reserved.
3436 + * Redistribution and use in source and binary forms, with or without
3437 + * modification, are permitted provided that the following conditions
3439 + * 1. Redistributions of source code must retain the above copyright
3440 + * notice, this list of conditions and the following disclaimer.
3441 + * 2. The name of the above contributors may not be
3442 + * used to endorse or promote products derived from this software
3443 + * without specific prior written permission.
3445 + * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
3446 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
3447 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
3448 + * ARE DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE
3449 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3450 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3451 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3452 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3453 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3454 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3458 +#if defined (__SUPPORT_LD_DEBUG__)
3459 +static const char *_dl_reltypes_tab[] =
3461 + [0] "R_386_NONE", "R_386_32", "R_386_PC32", "R_386_GOT32",
3462 + [4] "R_386_PLT32", "R_386_COPY", "R_386_GLOB_DAT", "R_386_JMP_SLOT",
3463 + [8] "R_386_RELATIVE", "R_386_GOTOFF", "R_386_GOTPC",
3466 +static const char *
3467 +_dl_reltypes(int type)
3469 + static char buf[22];
3472 + if (type >= (int)(sizeof (_dl_reltypes_tab)/sizeof(_dl_reltypes_tab[0])) ||
3473 + NULL == (str = _dl_reltypes_tab[type]))
3475 + str =_dl_simple_ltoa( buf, (unsigned long)(type));
3481 +void debug_sym(Elf32_Sym *symtab,char *strtab,int symtab_index)
3483 + if(_dl_debug_symbols)
3486 + _dl_dprintf(_dl_debug_file, "\n%s\n\tvalue=%x\tsize=%x\tinfo=%x\tother=%x\tshndx=%x",
3487 + strtab + symtab[symtab_index].st_name,
3488 + symtab[symtab_index].st_value,
3489 + symtab[symtab_index].st_size,
3490 + symtab[symtab_index].st_info,
3491 + symtab[symtab_index].st_other,
3492 + symtab[symtab_index].st_shndx);
3497 +static void debug_reloc(Elf32_Sym *symtab,char *strtab, ELF_RELOC *rpnt)
3499 + if(_dl_debug_reloc)
3503 + symtab_index = ELF32_R_SYM(rpnt->r_info);
3504 + sym = symtab_index ? strtab + symtab[symtab_index].st_name : "sym=0x0";
3506 + if(_dl_debug_symbols)
3507 + _dl_dprintf(_dl_debug_file, "\n\t");
3509 + _dl_dprintf(_dl_debug_file, "\n%s\n\t", sym);
3510 +#ifdef ELF_USES_RELOCA
3511 + _dl_dprintf(_dl_debug_file, "%s\toffset=%x\taddend=%x",
3512 + _dl_reltypes(ELF32_R_TYPE(rpnt->r_info)),
3516 + _dl_dprintf(_dl_debug_file, "%s\toffset=%x\n",
3517 + _dl_reltypes(ELF32_R_TYPE(rpnt->r_info)),
3524 +/* Program to load an ELF binary on a linux system, and run it.
3525 + References to symbols in sharable libraries can be resolved by either
3526 + an ELF sharable library or a linux style of shared library. */
3528 +/* Disclaimer: I have never seen any AT&T source code for SVr4, nor have
3529 + I ever taken any courses on internals. This program was developed using
3530 + information available through the book "UNIX SYSTEM V RELEASE 4,
3531 + Programmers guide: Ansi C and Programming Support Tools", which did
3532 + a more than adequate job of explaining everything required to get this
3535 +extern int _dl_linux_resolve(void);
3537 +unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
3540 + ELF_RELOC *this_reloc;
3542 + Elf32_Sym *symtab;
3547 + unsigned long instr_addr;
3550 + rel_addr = (char *) (tpnt->dynamic_info[DT_JMPREL] + tpnt->loadaddr);
3552 + this_reloc = (ELF_RELOC *)(intptr_t)(rel_addr + reloc_entry);
3553 + reloc_type = ELF32_R_TYPE(this_reloc->r_info);
3554 + symtab_index = ELF32_R_SYM(this_reloc->r_info);
3556 + symtab = (Elf32_Sym *)(intptr_t) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
3557 + strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
3558 + symname= strtab + symtab[symtab_index].st_name;
3560 + if (reloc_type != R_386_JMP_SLOT) {
3561 + _dl_dprintf(2, "%s: Incorrect relocation type in jump relocations\n",
3566 + /* Address of jump instruction to fix up */
3567 + instr_addr = ((unsigned long) this_reloc->r_offset +
3568 + (unsigned long) tpnt->loadaddr);
3569 + got_addr = (char **) instr_addr;
3571 + /* Get the address of the GOT entry */
3572 + new_addr = _dl_find_hash(symname, tpnt->symbol_scope, tpnt, resolver);
3574 + new_addr = _dl_find_hash(symname, NULL, NULL, resolver);
3576 + return (unsigned long) new_addr;
3578 + _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname);
3582 +#if defined (__SUPPORT_LD_DEBUG__)
3583 + if ((unsigned long) got_addr < 0x40000000)
3585 + if (_dl_debug_bindings)
3587 + _dl_dprintf(_dl_debug_file, "\nresolve function: %s", symname);
3588 + if(_dl_debug_detail) _dl_dprintf(_dl_debug_file,
3589 + "\n\tpatched %x ==> %x @ %x\n", *got_addr, new_addr, got_addr);
3592 + if (!_dl_debug_nofixups) {
3593 + *got_addr = new_addr;
3596 + *got_addr = new_addr;
3599 + return (unsigned long) new_addr;
3603 +_dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope,
3604 + unsigned long rel_addr, unsigned long rel_size,
3605 + int (*reloc_fnc) (struct elf_resolve *tpnt, struct dyn_elf *scope,
3606 + ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab))
3610 + Elf32_Sym *symtab;
3614 + /* Now parse the relocation information */
3615 + rpnt = (ELF_RELOC *)(intptr_t) (rel_addr + tpnt->loadaddr);
3616 + rel_size = rel_size / sizeof(ELF_RELOC);
3618 + symtab = (Elf32_Sym *)(intptr_t) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
3619 + strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
3621 + for (i = 0; i < rel_size; i++, rpnt++) {
3624 + symtab_index = ELF32_R_SYM(rpnt->r_info);
3626 + /* When the dynamic linker bootstrapped itself, it resolved some symbols.
3627 + Make sure we do not do them again */
3628 + if (!symtab_index && tpnt->libtype == program_interpreter)
3630 + if (symtab_index && tpnt->libtype == program_interpreter &&
3631 + _dl_symbol(strtab + symtab[symtab_index].st_name))
3634 +#if defined (__SUPPORT_LD_DEBUG__)
3635 + debug_sym(symtab,strtab,symtab_index);
3636 + debug_reloc(symtab,strtab,rpnt);
3639 + res = reloc_fnc (tpnt, scope, rpnt, symtab, strtab);
3641 + if (res==0) continue;
3643 + _dl_dprintf(2, "\n%s: ",_dl_progname);
3646 + _dl_dprintf(2, "symbol '%s': ", strtab + symtab[symtab_index].st_name);
3650 + int reloc_type = ELF32_R_TYPE(rpnt->r_info);
3651 +#if defined (__SUPPORT_LD_DEBUG__)
3652 + _dl_dprintf(2, "can't handle reloc type %s\n ", _dl_reltypes(reloc_type));
3654 + _dl_dprintf(2, "can't handle reloc type %x\n", reloc_type);
3660 + _dl_dprintf(2, "can't resolve symbol\n");
3669 +_dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope,
3670 + ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)
3675 + unsigned long *reloc_addr;
3676 + unsigned long symbol_addr;
3677 +#if defined (__SUPPORT_LD_DEBUG__)
3678 + unsigned long old_val;
3681 + reloc_addr = (unsigned long *)(intptr_t) (tpnt->loadaddr + (unsigned long) rpnt->r_offset);
3682 + reloc_type = ELF32_R_TYPE(rpnt->r_info);
3683 + symtab_index = ELF32_R_SYM(rpnt->r_info);
3685 + symname = strtab + symtab[symtab_index].st_name;
3687 + if (symtab_index) {
3689 + symbol_addr = (unsigned long) _dl_find_hash(symname, scope,
3690 + (reloc_type == R_386_JMP_SLOT ? tpnt : NULL), symbolrel);
3693 + * We want to allow undefined references to weak symbols - this might
3694 + * have been intentional. We should not be linking local symbols
3695 + * here, so all bases should be covered.
3698 + if (!symbol_addr && ELF32_ST_BIND(symtab[symtab_index].st_info) == STB_GLOBAL) {
3699 +#if defined (__SUPPORT_LD_DEBUG__)
3700 + _dl_dprintf(2, "\tglobal symbol '%s' already defined in '%s'\n",
3701 + symname, tpnt->libname);
3707 +#if defined (__SUPPORT_LD_DEBUG__)
3708 + old_val = *reloc_addr;
3710 + switch (reloc_type) {
3714 + *reloc_addr += symbol_addr;
3717 + *reloc_addr += symbol_addr - (unsigned long) reloc_addr;
3719 + case R_386_GLOB_DAT:
3720 + case R_386_JMP_SLOT:
3721 + *reloc_addr = symbol_addr;
3723 + case R_386_RELATIVE:
3724 + *reloc_addr += (unsigned long) tpnt->loadaddr;
3727 + /* handled later on */
3730 + return -1; /*call _dl_exit(1) */
3732 +#if defined (__SUPPORT_LD_DEBUG__)
3733 + if(_dl_debug_reloc && _dl_debug_detail)
3734 + _dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x", old_val, *reloc_addr, reloc_addr);
3741 +_dl_do_lazy_reloc (struct elf_resolve *tpnt, struct dyn_elf *scope,
3742 + ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)
3745 + unsigned long *reloc_addr;
3746 +#if defined (__SUPPORT_LD_DEBUG__)
3747 + unsigned long old_val;
3753 + reloc_addr = (unsigned long *)(intptr_t) (tpnt->loadaddr + (unsigned long) rpnt->r_offset);
3754 + reloc_type = ELF32_R_TYPE(rpnt->r_info);
3756 +#if defined (__SUPPORT_LD_DEBUG__)
3757 + old_val = *reloc_addr;
3759 + switch (reloc_type) {
3762 + case R_386_JMP_SLOT:
3763 + *reloc_addr += (unsigned long) tpnt->loadaddr;
3766 + return -1; /*call _dl_exit(1) */
3768 +#if defined (__SUPPORT_LD_DEBUG__)
3769 + if(_dl_debug_reloc && _dl_debug_detail)
3770 + _dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x", old_val, *reloc_addr, reloc_addr);
3776 +/* This is done as a separate step, because there are cases where
3777 + information is first copied and later initialized. This results in
3778 + the wrong information being copied. Someone at Sun was complaining about
3779 + a bug in the handling of _COPY by SVr4, and this may in fact be what he
3780 + was talking about. Sigh. */
3782 +/* No, there are cases where the SVr4 linker fails to emit COPY relocs
3785 +_dl_do_copy (struct elf_resolve *tpnt, struct dyn_elf *scope,
3786 + ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)
3790 + unsigned long *reloc_addr;
3791 + unsigned long symbol_addr;
3795 + reloc_addr = (unsigned long *)(intptr_t) (tpnt->loadaddr + (unsigned long) rpnt->r_offset);
3796 + reloc_type = ELF32_R_TYPE(rpnt->r_info);
3797 + if (reloc_type != R_386_COPY)
3799 + symtab_index = ELF32_R_SYM(rpnt->r_info);
3801 + symname = strtab + symtab[symtab_index].st_name;
3803 + if (symtab_index) {
3804 + symbol_addr = (unsigned long) _dl_find_hash(symname, scope, NULL, copyrel);
3805 + if (!symbol_addr) goof++;
3808 +#if defined (__SUPPORT_LD_DEBUG__)
3809 + if(_dl_debug_move)
3810 + _dl_dprintf(_dl_debug_file,"\n%s move %x bytes from %x to %x",
3811 + symname, symtab[symtab_index].st_size,
3812 + symbol_addr, symtab[symtab_index].st_value);
3814 + _dl_memcpy((char *) symtab[symtab_index].st_value,
3815 + (char *) symbol_addr, symtab[symtab_index].st_size);
3821 +void _dl_parse_lazy_relocation_information(struct elf_resolve *tpnt,
3822 + unsigned long rel_addr, unsigned long rel_size, int type)
3825 + (void)_dl_parse(tpnt, NULL, rel_addr, rel_size, _dl_do_lazy_reloc);
3828 +int _dl_parse_relocation_information(struct elf_resolve *tpnt,
3829 + unsigned long rel_addr, unsigned long rel_size, int type)
3832 + return _dl_parse(tpnt, tpnt->symbol_scope, rel_addr, rel_size, _dl_do_reloc);
3835 +int _dl_parse_copy_information(struct dyn_elf *xpnt, unsigned long rel_addr,
3836 + unsigned long rel_size, int type)
3839 + return _dl_parse(xpnt->dyn, xpnt->next, rel_addr, rel_size, _dl_do_copy);
3842 diff -urN uClibc/ldso-0.9.24/ldso/i386/ld_syscalls.h uClibc.ldso.24/ldso-0.9.24/ldso/i386/ld_syscalls.h
3843 --- uClibc/ldso-0.9.24/ldso/i386/ld_syscalls.h 1969-12-31 18:00:00.000000000 -0600
3844 +++ uClibc.ldso.24/ldso-0.9.24/ldso/i386/ld_syscalls.h 2002-08-09 07:20:21.000000000 -0500
3846 +/* Define the __set_errno macro as nothing so that INLINE_SYSCALL
3847 + * won't set errno, which is important since we make system calls
3848 + * before the errno symbol is dynamicly linked. */
3850 +#define __set_errno(X) {(void)(X);}
3851 +#include "sys/syscall.h"
3853 diff -urN uClibc/ldso-0.9.24/ldso/i386/ld_sysdep.h uClibc.ldso.24/ldso-0.9.24/ldso/i386/ld_sysdep.h
3854 --- uClibc/ldso-0.9.24/ldso/i386/ld_sysdep.h 1969-12-31 18:00:00.000000000 -0600
3855 +++ uClibc.ldso.24/ldso-0.9.24/ldso/i386/ld_sysdep.h 2002-05-28 16:33:32.000000000 -0500
3858 + * Various assmbly language/system dependent hacks that are required
3859 + * so that we can minimize the amount of platform specific code.
3863 + * Define this if the system uses RELOCA.
3865 +#undef ELF_USES_RELOCA
3868 + * Get a pointer to the argv array. On many platforms this can be just
3869 + * the address if the first argument, on other platforms we need to
3870 + * do something a little more subtle here.
3872 +#define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned long*) & ARGS)
3875 + * Initialization sequence for a GOT.
3877 +#define INIT_GOT(GOT_BASE,MODULE) \
3879 + GOT_BASE[2] = (unsigned long) _dl_linux_resolve; \
3880 + GOT_BASE[1] = (unsigned long) MODULE; \
3884 + * Here is a macro to perform a relocation. This is only used when
3885 + * bootstrapping the dynamic loader. RELP is the relocation that we
3886 + * are performing, REL is the pointer to the address we are relocating.
3887 + * SYMBOL is the symbol involved in the relocation, and LOAD is the
3890 +#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD) \
3891 + switch(ELF32_R_TYPE((RELP)->r_info)){ \
3895 + case R_386_PC32: \
3896 + *REL += SYMBOL - (unsigned long) REL; \
3898 + case R_386_GLOB_DAT: \
3899 + case R_386_JMP_SLOT: \
3902 + case R_386_RELATIVE: \
3903 + *REL += (unsigned long) LOAD; \
3911 + * Transfer control to the user's application, once the dynamic loader
3912 + * is done. This routine has to exit the current function, then
3913 + * call the _dl_elf_main function.
3916 + __asm__ volatile ("leave\n\t" \
3917 + "jmp *%%eax\n\t" \
3918 + : "=a" (status) : "a" (_dl_elf_main))
3922 +/* Here we define the magic numbers that this dynamic loader should accept */
3924 +#define MAGIC1 EM_386
3926 +/* Used for error messages */
3927 +#define ELF_TARGET "386"
3929 +struct elf_resolve;
3930 +extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
3932 +#define do_rem(result, n, base) result = (n % base)
3934 +/* 4096 bytes alignment */
3935 +#define PAGE_ALIGN 0xfffff000
3936 +#define ADDR_ALIGN 0xfff
3937 +#define OFFS_ALIGN 0x7ffff000
3938 diff -urN uClibc/ldso-0.9.24/ldso/i386/resolve.S uClibc.ldso.24/ldso-0.9.24/ldso/i386/resolve.S
3939 --- uClibc/ldso-0.9.24/ldso/i386/resolve.S 1969-12-31 18:00:00.000000000 -0600
3940 +++ uClibc.ldso.24/ldso-0.9.24/ldso/i386/resolve.S 2001-06-14 16:51:51.000000000 -0500
3943 + * This function is _not_ called directly. It is jumped to (so no return
3944 + * address is on the stack) when attempting to use a symbol that has not yet
3945 + * been resolved. The first time a jump symbol (such as a function call inside
3946 + * a shared library) is used (before it gets resolved) it will jump here to
3947 + * _dl_linux_resolve. When we get called the stack looks like this:
3951 + * This function saves all the registers, puts a copy of reloc_entry and tpnt
3952 + * on the stack (as function arguments) then make the function call
3953 + * _dl_linux_resolver(tpnt, reloc_entry). _dl_linux_resolver() figures out
3954 + * where the jump symbol is _really_ supposed to have jumped to and returns
3955 + * that to us. Once we have that, we overwrite tpnt with this fixed up
3956 + * address. We then clean up after ourselves, put all the registers back how we
3957 + * found them, then we jump to where the fixed up address, which is where the
3958 + * jump symbol that got us here really wanted to jump to in the first place.
3959 + * found them, then we jump to the fixed up address, which is where the jump
3960 + * symbol that got us here really wanted to jump to in the first place.
3967 +.globl _dl_linux_resolve
3968 +.type _dl_linux_resolve,@function
3971 + pusha /* preserve all regs */
3972 + lea 0x20(%esp),%eax /* eax = tpnt and reloc_entry params */
3973 + pushl 4(%eax) /* push copy of reloc_entry param */
3974 + pushl (%eax) /* push copy of tpnt param */
3980 + addl $_GLOBAL_OFFSET_TABLE_+[.-.L24],%ebx
3981 + movl _dl_linux_resolver@GOT(%ebx),%ebx /* eax = resolved func */
3984 + call _dl_linux_resolver
3986 + movl %eax,0x28(%esp) /* store func addr over original
3988 + addl $0x8,%esp /* remove copy parameters */
3989 + popa /* restore regs */
3990 + ret $4 /* jump to func removing original
3991 + * reloc_entry param from stack */
3993 + .size _dl_linux_resolve,.LFE2-_dl_linux_resolve
3994 diff -urN uClibc/ldso-0.9.24/ldso/ldso.c uClibc.ldso.24/ldso-0.9.24/ldso/ldso.c
3995 --- uClibc/ldso-0.9.24/ldso/ldso.c 1969-12-31 18:00:00.000000000 -0600
3996 +++ uClibc.ldso.24/ldso-0.9.24/ldso/ldso.c 2003-12-05 14:24:26.000000000 -0600
3998 +/* vi: set sw=4 ts=4: */
3999 +/* Program to load an ELF binary on a linux system, and run it
4000 + * after resolving ELF shared library symbols
4002 + * Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald,
4003 + * David Engel, Hongjiu Lu and Mitch D'Souza
4004 + * Copyright (C) 2001-2002, Erik Andersen
4006 + * All rights reserved.
4008 + * Redistribution and use in source and binary forms, with or without
4009 + * modification, are permitted provided that the following conditions
4011 + * 1. Redistributions of source code must retain the above copyright
4012 + * notice, this list of conditions and the following disclaimer.
4013 + * 2. The name of the above contributors may not be
4014 + * used to endorse or promote products derived from this software
4015 + * without specific prior written permission.
4017 + * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
4018 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4019 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4020 + * ARE DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE
4021 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4022 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4023 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4024 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4025 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
4026 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
4030 +// Support a list of library preloads in /etc/ld.so.preload
4031 +//#define SUPPORT_LDSO_PRELOAD_FILE
4034 +/* Disclaimer: I have never seen any AT&T source code for SVr4, nor have
4035 + I ever taken any courses on internals. This program was developed using
4036 + information available through the book "UNIX SYSTEM V RELEASE 4,
4037 + Programmers guide: Ansi C and Programming Support Tools", which did
4038 + a more than adequate job of explaining everything required to get this
4042 + * The main trick with this program is that initially, we ourselves are
4043 + * not dynamicly linked. This means that we cannot access any global
4044 + * variables or call any functions. No globals initially, since the
4045 + * Global Offset Table (GOT) is initialized by the linker assuming a
4046 + * virtual address of 0, and no function calls initially since the
4047 + * Procedure Linkage Table (PLT) is not yet initialized.
4049 + * There are additional initial restrictions - we cannot use large
4050 + * switch statements, since the compiler generates tables of addresses
4051 + * and jumps through them. We can use inline functions, because these
4052 + * do not transfer control to a new address, but they must be static so
4053 + * that they are not exported from the modules. We cannot use normal
4054 + * syscall stubs, because these all reference the errno global variable
4055 + * which is not yet initialized. We can use all of the local stack
4056 + * variables that we want.
4058 + * Life is further complicated by the fact that initially we do not
4059 + * want to do a complete dynamic linking. We want to allow the user to
4060 + * supply new functions to override symbols (i.e. weak symbols and/or
4061 + * LD_PRELOAD). So initially, we only perform relocations for
4062 + * variables that start with "_dl_" since ANSI specifies that the user
4063 + * is not supposed to redefine any of these variables.
4065 + * Fortunately, the linker itself leaves a few clues lying around, and
4066 + * when the kernel starts the image, there are a few further clues.
4067 + * First of all, there is Auxiliary Vector Table information sitting on
4068 + * which is provided to us by the kernel, and which includes
4069 + * information about the load address that the program interpreter was
4070 + * loaded at, the number of sections, the address the application was
4071 + * loaded at and so forth. Here this information is stored in the
4072 + * array auxvt. For details see linux/fs/binfmt_elf.c where it calls
4073 + * NEW_AUX_ENT() a bunch of time....
4075 + * Next, we need to find the GOT. On most arches there is a register
4076 + * pointing to the GOT, but just in case (and for new ports) I've added
4077 + * some (slow) C code to locate the GOT for you.
4079 + * This code was originally written for SVr4, and there the kernel
4080 + * would load all text pages R/O, so they needed to call mprotect a
4081 + * zillion times to mark all text pages as writable so dynamic linking
4082 + * would succeed. Then when they were done, they would change the
4083 + * protections for all the pages back again. Well, under Linux
4084 + * everything is loaded writable (since Linux does copy on write
4085 + * anyways) so all the mprotect stuff has been disabled.
4087 + * Initially, we do not have access to _dl_malloc since we can't yet
4088 + * make function calls, so we mmap one page to use as scratch space.
4089 + * Later on, when we can call _dl_malloc we reuse this this memory.
4090 + * This is also beneficial, since we do not want to use the same memory
4091 + * pool as malloc anyway - esp if the user redefines malloc to do
4092 + * something funky.
4094 + * Our first task is to perform a minimal linking so that we can call
4095 + * other portions of the dynamic linker. Once we have done this, we
4096 + * then build the list of modules that the application requires, using
4097 + * LD_LIBRARY_PATH if this is not a suid program (/usr/lib otherwise).
4098 + * Once this is done, we can do the dynamic linking as required, and we
4099 + * must omit the things we did to get the dynamic linker up and running
4100 + * in the first place. After we have done this, we just have a few
4101 + * housekeeping chores and we can transfer control to the user's
4108 +#define ALLOW_ZERO_PLTGOT
4110 +/* Some arches may need to override this in boot1_arch.h */
4111 +#define ELFMAGIC ELFMAG
4113 +/* This is a poor man's malloc, used prior to resolving our internal poor man's malloc */
4114 +#define LD_MALLOC(SIZE) ((void *) (malloc_buffer += SIZE, malloc_buffer - SIZE)) ; REALIGN();
4116 + * Make sure that the malloc buffer is aligned on 4 byte boundary. For 64 bit
4117 + * platforms we may need to increase this to 8, but this is good enough for
4118 + * now. This is typically called after LD_MALLOC.
4120 +#define REALIGN() malloc_buffer = (char *) (((unsigned long) malloc_buffer + 3) & ~(3))
4122 +char *_dl_library_path = 0; /* Where we look for libraries */
4123 +char *_dl_preload = 0; /* Things to be loaded before the libs. */
4124 +char *_dl_ldsopath = 0;
4125 +static int _dl_be_lazy = RTLD_LAZY;
4126 +#ifdef __SUPPORT_LD_DEBUG__
4127 +char *_dl_debug = 0;
4128 +char *_dl_debug_symbols = 0;
4129 +char *_dl_debug_move = 0;
4130 +char *_dl_debug_reloc = 0;
4131 +char *_dl_debug_detail = 0;
4132 +char *_dl_debug_nofixups = 0;
4133 +char *_dl_debug_bindings = 0;
4134 +int _dl_debug_file = 2;
4136 +#define _dl_debug_file 2
4138 +static char *_dl_malloc_addr, *_dl_mmap_zero;
4140 +static char *_dl_trace_loaded_objects = 0;
4141 +static int (*_dl_elf_main) (int, char **, char **);
4142 +struct r_debug *_dl_debug_addr = NULL;
4143 +unsigned long *_dl_brkp;
4144 +unsigned long *_dl_envp;
4145 +int _dl_fixup(struct elf_resolve *tpnt, int lazy);
4146 +void _dl_debug_state(void);
4147 +char *_dl_get_last_path_component(char *path);
4148 +static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *app_tpnt,
4149 + unsigned long load_addr, unsigned long *hash_addr, Elf32_auxv_t auxvt[AT_EGID + 1],
4150 + char **envp, struct r_debug *debug_addr);
4152 +#include "boot1_arch.h"
4153 +#include "_dl_progname.h" /* Pull in the value of _dl_progname */
4155 +/* When we enter this piece of code, the program stack looks like this:
4156 + argc argument counter (integer)
4157 + argv[0] program name (pointer)
4158 + argv[1...N] program args (pointers)
4159 + argv[argc-1] end of args (integer)
4161 + env[0...N] environment variables (pointers)
4163 + auxvt[0...N] Auxiliary Vector Table elements (mixed types)
4166 +#ifdef __SUPPORT_LD_DEBUG_EARLY__
4167 +/* Debugging is especially tricky on PowerPC, since string literals
4168 + * require relocations. Thus, you can't use _dl_dprintf() for
4169 + * anything until the bootstrap relocations are finished. */
4170 +static inline void hexprint(unsigned long x)
4175 + for (i = 0; i < 8; i++) {
4176 + c = ((x >> 28) + '0');
4178 + c += 'a' - '9' - 1;
4179 + _dl_write(1, &c, 1);
4183 + _dl_write(1, &c, 1);
4187 +LD_BOOT(unsigned long args) __attribute__ ((unused));
4189 +LD_BOOT(unsigned long args)
4191 + unsigned int argc;
4192 + char **argv, **envp;
4193 + unsigned long load_addr;
4194 + unsigned long *got;
4195 + unsigned long *aux_dat;
4197 + ElfW(Ehdr) *header;
4198 + struct elf_resolve *tpnt;
4199 + struct elf_resolve *app_tpnt;
4200 + Elf32_auxv_t auxvt[AT_EGID + 1];
4201 + unsigned char *malloc_buffer, *mmap_zero;
4203 + unsigned long *hash_addr;
4204 + struct r_debug *debug_addr = NULL;
4209 + /* WARNING! -- we cannot make _any_ funtion calls until we have
4210 + * taken care of fixing up our own relocations. Making static
4211 + * inline calls is ok, but _no_ function calls. Not yet
4214 + /* First obtain the information on the stack that tells us more about
4215 + what binary is loaded, where it is loaded, etc, etc */
4216 + GET_ARGV(aux_dat, args);
4217 +#if defined (__arm__) || defined (__mips__) || defined (__cris__)
4220 + argc = *(aux_dat - 1);
4221 + argv = (char **) aux_dat;
4222 + aux_dat += argc; /* Skip over the argv pointers */
4223 + aux_dat++; /* Skip over NULL at end of argv */
4224 + envp = (char **) aux_dat;
4226 + aux_dat++; /* Skip over the envp pointers */
4227 + aux_dat++; /* Skip over NULL at end of envp */
4229 + /* Place -1 here as a checkpoint. We later check if it was changed
4230 + * when we read in the auxvt */
4231 + auxvt[AT_UID].a_type = -1;
4233 + /* The junk on the stack immediately following the environment is
4234 + * the Auxiliary Vector Table. Read out the elements of the auxvt,
4235 + * sort and store them in auxvt for later use. */
4236 + while (*aux_dat) {
4237 + Elf32_auxv_t *auxv_entry = (Elf32_auxv_t *) aux_dat;
4239 + if (auxv_entry->a_type <= AT_EGID) {
4240 + _dl_memcpy(&(auxvt[auxv_entry->a_type]), auxv_entry, sizeof(Elf32_auxv_t));
4245 + /* locate the ELF header. We need this done as soon as possible
4246 + * (esp since SEND_STDERR() needs this on some platforms... */
4247 + load_addr = auxvt[AT_BASE].a_un.a_val;
4248 + header = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_ptr;
4250 + /* Check the ELF header to make sure everything looks ok. */
4251 + if (!header || header->e_ident[EI_CLASS] != ELFCLASS32 ||
4252 + header->e_ident[EI_VERSION] != EV_CURRENT
4253 +#if !defined(__powerpc__) && !defined(__mips__) && !defined(__sh__)
4254 + || _dl_strncmp((void *) header, ELFMAGIC, SELFMAG) != 0
4256 + || header->e_ident[EI_MAG0] != ELFMAG0
4257 + || header->e_ident[EI_MAG1] != ELFMAG1
4258 + || header->e_ident[EI_MAG2] != ELFMAG2
4259 + || header->e_ident[EI_MAG3] != ELFMAG3
4262 + SEND_STDERR("Invalid ELF header\n");
4265 +#ifdef __SUPPORT_LD_DEBUG_EARLY__
4266 + SEND_STDERR("ELF header=");
4267 + SEND_ADDRESS_STDERR(load_addr, 1);
4271 + /* Locate the global offset table. Since this code must be PIC
4272 + * we can take advantage of the magic offset register, if we
4273 + * happen to know what that is for this architecture. If not,
4274 + * we can always read stuff out of the ELF file to find it... */
4275 +#if defined(__i386__)
4276 + __asm__("\tmovl %%ebx,%0\n\t":"=a"(got));
4277 +#elif defined(__m68k__)
4278 + __asm__("movel %%a5,%0":"=g"(got))
4279 +#elif defined(__sparc__)
4280 + __asm__("\tmov %%l7,%0\n\t":"=r"(got))
4281 +#elif defined(__arm__)
4282 + __asm__("\tmov %0, r10\n\t":"=r"(got));
4283 +#elif defined(__powerpc__)
4284 + __asm__("\tbl _GLOBAL_OFFSET_TABLE_-4@local\n\t":"=l"(got));
4285 +#elif defined(__mips__)
4286 + __asm__("\tmove %0, $28\n\tsubu %0,%0,0x7ff0\n\t":"=r"(got));
4287 +#elif defined(__sh__)
4294 +"1: .long _GLOBAL_OFFSET_TABLE_\n"
4295 +"2:" : "=r" (got) : : "r0");
4296 +#elif defined(__cris__)
4297 + __asm__("\tmove.d $pc,%0\n\tsub.d .:GOTOFF,%0\n\t":"=r"(got));
4299 + /* Do things the slow way in C */
4301 + unsigned long tx_reloc;
4302 + Elf32_Dyn *dynamic = NULL;
4304 + Elf32_Phdr *pt_load;
4306 +#ifdef __SUPPORT_LD_DEBUG_EARLY__
4307 + SEND_STDERR("Finding the GOT using C code to read the ELF file\n");
4309 + /* Find where the dynamic linking information section is hiding */
4310 + shdr = (Elf32_Shdr *) (header->e_shoff + (char *) header);
4311 + for (indx = header->e_shnum; --indx >= 0; ++shdr) {
4312 + if (shdr->sh_type == SHT_DYNAMIC) {
4313 + goto found_dynamic;
4316 + SEND_STDERR("missing dynamic linking information section \n");
4320 + dynamic = (Elf32_Dyn *) (shdr->sh_offset + (char *) header);
4322 + /* Find where PT_LOAD is hiding */
4323 + pt_load = (Elf32_Phdr *) (header->e_phoff + (char *) header);
4324 + for (indx = header->e_phnum; --indx >= 0; ++pt_load) {
4325 + if (pt_load->p_type == PT_LOAD) {
4326 + goto found_pt_load;
4329 + SEND_STDERR("missing loadable program segment\n");
4333 + /* Now (finally) find where DT_PLTGOT is hiding */
4334 + tx_reloc = pt_load->p_vaddr - pt_load->p_offset;
4335 + for (; DT_NULL != dynamic->d_tag; ++dynamic) {
4336 + if (dynamic->d_tag == DT_PLTGOT) {
4340 + SEND_STDERR("missing global offset table\n");
4344 + got = (unsigned long *) (dynamic->d_un.d_val - tx_reloc +
4349 + /* Now, finally, fix up the location of the dynamic stuff */
4350 + dpnt = (Elf32_Dyn *) (*got + load_addr);
4351 +#ifdef __SUPPORT_LD_DEBUG_EARLY__
4352 + SEND_STDERR("First Dynamic section entry=");
4353 + SEND_ADDRESS_STDERR(dpnt, 1);
4357 + /* Call mmap to get a page of writable memory that can be used
4358 + * for _dl_malloc throughout the shared lib loader. */
4359 + mmap_zero = malloc_buffer = _dl_mmap((void *) 0, 4096,
4360 + PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
4361 + if (_dl_mmap_check_error(mmap_zero)) {
4362 + SEND_STDERR("dl_boot: mmap of a spare page failed!\n");
4366 + tpnt = LD_MALLOC(sizeof(struct elf_resolve));
4367 + _dl_memset(tpnt, 0, sizeof(struct elf_resolve));
4368 + app_tpnt = LD_MALLOC(sizeof(struct elf_resolve));
4369 + _dl_memset(app_tpnt, 0, sizeof(struct elf_resolve));
4372 + * This is used by gdb to locate the chain of shared libraries that are currently loaded.
4374 + debug_addr = LD_MALLOC(sizeof(struct r_debug));
4375 + _dl_memset(debug_addr, 0, sizeof(struct r_debug));
4377 + /* OK, that was easy. Next scan the DYNAMIC section of the image.
4378 + We are only doing ourself right now - we will have to do the rest later */
4379 +#ifdef __SUPPORT_LD_DEBUG_EARLY__
4380 + SEND_STDERR("scanning DYNAMIC section\n");
4382 + while (dpnt->d_tag) {
4383 +#if defined(__mips__)
4384 + if (dpnt->d_tag == DT_MIPS_GOTSYM)
4385 + tpnt->mips_gotsym = (unsigned long) dpnt->d_un.d_val;
4386 + if (dpnt->d_tag == DT_MIPS_LOCAL_GOTNO)
4387 + tpnt->mips_local_gotno = (unsigned long) dpnt->d_un.d_val;
4388 + if (dpnt->d_tag == DT_MIPS_SYMTABNO)
4389 + tpnt->mips_symtabno = (unsigned long) dpnt->d_un.d_val;
4391 + if (dpnt->d_tag < 24) {
4392 + tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
4393 + if (dpnt->d_tag == DT_TEXTREL) {
4394 + tpnt->dynamic_info[DT_TEXTREL] = 1;
4404 + ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_ptr;
4405 + for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++)
4406 + if (ppnt->p_type == PT_DYNAMIC) {
4407 + dpnt = (Elf32_Dyn *) ppnt->p_vaddr;
4408 + while (dpnt->d_tag) {
4409 +#if defined(__mips__)
4410 + if (dpnt->d_tag == DT_MIPS_GOTSYM)
4411 + app_tpnt->mips_gotsym =
4412 + (unsigned long) dpnt->d_un.d_val;
4413 + if (dpnt->d_tag == DT_MIPS_LOCAL_GOTNO)
4414 + app_tpnt->mips_local_gotno =
4415 + (unsigned long) dpnt->d_un.d_val;
4416 + if (dpnt->d_tag == DT_MIPS_SYMTABNO)
4417 + app_tpnt->mips_symtabno =
4418 + (unsigned long) dpnt->d_un.d_val;
4419 + if (dpnt->d_tag > DT_JMPREL) {
4423 + app_tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
4425 +#warning "Debugging threads on mips won't work till someone fixes this..."
4427 + if (dpnt->d_tag == DT_DEBUG) {
4428 + dpnt->d_un.d_val = (unsigned long) debug_addr;
4433 + if (dpnt->d_tag > DT_JMPREL) {
4437 + app_tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
4438 + if (dpnt->d_tag == DT_DEBUG) {
4439 + dpnt->d_un.d_val = (unsigned long) debug_addr;
4442 + if (dpnt->d_tag == DT_TEXTREL)
4443 + app_tpnt->dynamic_info[DT_TEXTREL] = 1;
4449 +#ifdef __SUPPORT_LD_DEBUG_EARLY__
4450 + SEND_STDERR("done scanning DYNAMIC section\n");
4453 + /* Get some more of the information that we will need to dynamicly link
4454 + this module to itself */
4456 + hash_addr = (unsigned long *) (tpnt->dynamic_info[DT_HASH] + load_addr);
4457 + tpnt->nbucket = *hash_addr++;
4458 + tpnt->nchain = *hash_addr++;
4459 + tpnt->elf_buckets = hash_addr;
4460 + hash_addr += tpnt->nbucket;
4462 +#ifdef __SUPPORT_LD_DEBUG_EARLY__
4463 + SEND_STDERR("done grabbing link information\n");
4466 +#ifndef FORCE_SHAREABLE_TEXT_SEGMENTS
4467 + /* Ugly, ugly. We need to call mprotect to change the protection of
4468 + the text pages so that we can do the dynamic linking. We can set the
4469 + protection back again once we are done */
4475 +#ifdef __SUPPORT_LD_DEBUG_EARLY__
4476 + SEND_STDERR("calling mprotect on the shared library/dynamic linker\n");
4479 + /* First cover the shared library/dynamic linker. */
4480 + if (tpnt->dynamic_info[DT_TEXTREL]) {
4481 + header = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_ptr;
4482 + ppnt = (ElfW(Phdr) *) ((int)auxvt[AT_BASE].a_un.a_ptr +
4484 + for (i = 0; i < header->e_phnum; i++, ppnt++) {
4485 + if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W)) {
4486 + _dl_mprotect((void *) (load_addr + (ppnt->p_vaddr & PAGE_ALIGN)),
4487 + (ppnt->p_vaddr & ADDR_ALIGN) + (unsigned long) ppnt->p_filesz,
4488 + PROT_READ | PROT_WRITE | PROT_EXEC);
4493 +#ifdef __SUPPORT_LD_DEBUG_EARLY__
4494 + SEND_STDERR("calling mprotect on the application program\n");
4496 + /* Now cover the application program. */
4497 + if (app_tpnt->dynamic_info[DT_TEXTREL]) {
4498 + ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_ptr;
4499 + for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
4500 + if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
4501 + _dl_mprotect((void *) (ppnt->p_vaddr & PAGE_ALIGN),
4502 + (ppnt->p_vaddr & ADDR_ALIGN) +
4503 + (unsigned long) ppnt->p_filesz,
4504 + PROT_READ | PROT_WRITE | PROT_EXEC);
4510 +#if defined(__mips__)
4511 +#ifdef __SUPPORT_LD_DEBUG_EARLY__
4512 + SEND_STDERR("About to do MIPS specific GOT bootstrap\n");
4514 + /* For MIPS we have to do stuff to the GOT before we do relocations. */
4515 + PERFORM_BOOTSTRAP_GOT(got);
4518 + /* OK, now do the relocations. We do not do a lazy binding here, so
4519 + that once we are done, we have considerably more flexibility. */
4520 +#ifdef __SUPPORT_LD_DEBUG_EARLY__
4521 + SEND_STDERR("About to do library loader relocations\n");
4525 + for (indx = 0; indx < 2; indx++) {
4528 + unsigned long *reloc_addr;
4529 + unsigned long symbol_addr;
4531 + unsigned long rel_addr, rel_size;
4534 +#ifdef ELF_USES_RELOCA
4535 + rel_addr = (indx ? tpnt->dynamic_info[DT_JMPREL] : tpnt->
4536 + dynamic_info[DT_RELA]);
4537 + rel_size = (indx ? tpnt->dynamic_info[DT_PLTRELSZ] : tpnt->
4538 + dynamic_info[DT_RELASZ]);
4540 + rel_addr = (indx ? tpnt->dynamic_info[DT_JMPREL] : tpnt->
4541 + dynamic_info[DT_REL]);
4542 + rel_size = (indx ? tpnt->dynamic_info[DT_PLTRELSZ] : tpnt->
4543 + dynamic_info[DT_RELSZ]);
4549 + /* Now parse the relocation information */
4550 + rpnt = (ELF_RELOC *) (rel_addr + load_addr);
4551 + for (i = 0; i < rel_size; i += sizeof(ELF_RELOC), rpnt++) {
4552 + reloc_addr = (unsigned long *) (load_addr + (unsigned long) rpnt->r_offset);
4553 + symtab_index = ELF32_R_SYM(rpnt->r_info);
4555 + if (symtab_index) {
4557 + Elf32_Sym *symtab;
4559 + symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + load_addr);
4560 + strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + load_addr);
4562 + /* We only do a partial dynamic linking right now. The user
4563 + is not supposed to redefine any symbols that start with
4564 + a '_', so we can do this with confidence. */
4565 + if (!_dl_symbol(strtab + symtab[symtab_index].st_name))
4567 + symbol_addr = load_addr + symtab[symtab_index].st_value;
4569 + if (!symbol_addr) {
4570 + /* This will segfault - you cannot call a function until
4571 + * we have finished the relocations.
4573 + SEND_STDERR("ELF dynamic loader - unable to self-bootstrap - symbol ");
4574 + SEND_STDERR(strtab + symtab[symtab_index].st_name);
4575 + SEND_STDERR(" undefined.\n");
4578 +#ifdef __SUPPORT_LD_DEBUG_EARLY__
4579 + SEND_STDERR("About to fixup symbol: ");
4580 + SEND_STDERR(strtab + symtab[symtab_index].st_name);
4581 + SEND_STDERR("\n");
4585 + * Use this machine-specific macro to perform the actual relocation.
4587 + PERFORM_BOOTSTRAP_RELOC(rpnt, reloc_addr, symbol_addr, load_addr);
4594 +#ifdef __SUPPORT_LD_DEBUG_EARLY__
4596 + _dl_dprintf(_dl_debug_file, "Done relocating library loader, so we can now\n\tuse globals and make function calls!\n");
4600 + _dl_progname = argv[0];
4603 + /* Start to build the tables of the modules that are required for
4604 + * this beast to run. We start with the basic executable, and then
4605 + * go from there. Eventually we will run across ourself, and we
4606 + * will need to properly deal with that as well. */
4608 + /* Make it so _dl_malloc can use the page of memory we have already
4609 + * allocated, so we shouldn't need to grab any more memory */
4610 + _dl_malloc_addr = malloc_buffer;
4611 + _dl_mmap_zero = mmap_zero;
4615 + /* Now we have done the mandatory linking of some things. We are now
4616 + free to start using global variables, since these things have all been
4617 + fixed up by now. Still no function calls outside of this library ,
4618 + since the dynamic resolver is not yet ready. */
4619 + _dl_get_ready_to_run(tpnt, app_tpnt, load_addr, hash_addr, auxvt, envp, debug_addr);
4622 + /* Notify the debugger that all objects are now mapped in. */
4623 + _dl_debug_addr->r_state = RT_CONSISTENT;
4624 + _dl_debug_state();
4627 + /* OK we are done here. Turn out the lights, and lock up. */
4628 + _dl_elf_main = (int (*)(int, char **, char **)) auxvt[AT_ENTRY].a_un.a_fcn;
4631 + * Transfer control to the application.
4633 + status = 0; /* Used on x86, but not on other arches */
4634 +#if defined (__SUPPORT_LD_DEBUG__)
4635 + if(_dl_debug) _dl_dprintf(_dl_debug_file,"\ntransfering control: %s\n\n", _dl_progname);
4640 +#if defined (__SUPPORT_LD_DEBUG__)
4641 +static void debug_fini (int status, void *arg)
4644 + _dl_dprintf(_dl_debug_file,"\ncalling fini: %s\n\n", (const char*)arg);
4648 +static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *app_tpnt,
4649 + unsigned long load_addr, unsigned long *hash_addr, Elf32_auxv_t auxvt[AT_EGID + 1],
4650 + char **envp, struct r_debug *debug_addr)
4654 + int i, _dl_secure, goof = 0;
4655 + struct dyn_elf *rpnt;
4656 + struct elf_resolve *tcurr;
4657 + struct elf_resolve *tpnt1;
4658 + unsigned long brk_addr, *lpnt;
4659 + int (*_dl_atexit) (void *);
4660 +#if defined (__SUPPORT_LD_DEBUG__)
4661 + int (*_dl_on_exit) (void (*FUNCTION)(int STATUS, void *ARG),void*);
4664 + /* Now we have done the mandatory linking of some things. We are now
4665 + free to start using global variables, since these things have all been
4666 + fixed up by now. Still no function calls outside of this library ,
4667 + since the dynamic resolver is not yet ready. */
4668 + lpnt = (unsigned long *) (tpnt->dynamic_info[DT_PLTGOT] + load_addr);
4670 + tpnt->chains = hash_addr;
4672 + tpnt->libname = 0;
4673 + tpnt->libtype = program_interpreter;
4674 + tpnt->loadaddr = (ElfW(Addr)) load_addr;
4676 +#ifdef ALLOW_ZERO_PLTGOT
4677 + if (tpnt->dynamic_info[DT_PLTGOT])
4680 + INIT_GOT(lpnt, tpnt);
4681 +#ifdef __SUPPORT_LD_DEBUG_EARLY__
4682 + _dl_dprintf(_dl_debug_file, "GOT found at %x\n", lpnt);
4686 + /* OK, this was a big step, now we need to scan all of the user images
4687 + and load them properly. */
4691 + ElfW(Phdr) *myppnt;
4694 + epnt = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_ptr;
4695 + tpnt->n_phent = epnt->e_phnum;
4696 + tpnt->ppnt = myppnt = (ElfW(Phdr) *) (load_addr + epnt->e_phoff);
4697 + for (j = 0; j < epnt->e_phnum; j++, myppnt++) {
4698 + if (myppnt->p_type == PT_DYNAMIC) {
4699 + tpnt->dynamic_addr = (ElfW(Dyn) *)myppnt->p_vaddr + load_addr;
4700 + tpnt->dynamic_size = myppnt->p_filesz;
4708 + /* At this point we are now free to examine the user application,
4709 + and figure out which libraries are supposed to be called. Until
4710 + we have this list, we will not be completely ready for dynamic linking */
4712 + ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_ptr;
4713 + for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
4714 + if (ppnt->p_type == PT_LOAD) {
4715 + if (ppnt->p_vaddr + ppnt->p_memsz > brk_addr)
4716 + brk_addr = ppnt->p_vaddr + ppnt->p_memsz;
4718 + if (ppnt->p_type == PT_DYNAMIC) {
4719 +#ifndef ALLOW_ZERO_PLTGOT
4720 + /* make sure it's really there. */
4721 + if (app_tpnt->dynamic_info[DT_PLTGOT] == 0)
4724 + /* OK, we have what we need - slip this one into the list. */
4725 + app_tpnt = _dl_add_elf_hash_table("", 0,
4726 + app_tpnt->dynamic_info, ppnt->p_vaddr, ppnt->p_filesz);
4727 + _dl_loaded_modules->libtype = elf_executable;
4728 + _dl_loaded_modules->ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_ptr;
4729 + _dl_loaded_modules->n_phent = auxvt[AT_PHNUM].a_un.a_val;
4730 + _dl_symbol_tables = rpnt = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
4731 + _dl_memset(rpnt, 0, sizeof(struct dyn_elf));
4732 + rpnt->dyn = _dl_loaded_modules;
4733 + app_tpnt->usage_count++;
4734 + app_tpnt->symbol_scope = _dl_symbol_tables;
4735 + lpnt = (unsigned long *) (app_tpnt->dynamic_info[DT_PLTGOT]);
4736 +#ifdef ALLOW_ZERO_PLTGOT
4739 + INIT_GOT(lpnt, _dl_loaded_modules);
4742 + /* OK, fill this in - we did not have this before */
4743 + if (ppnt->p_type == PT_INTERP) {
4745 + char *pnt, *pnt1, buf[1024];
4746 + tpnt->libname = _dl_strdup((char *) ppnt->p_offset +
4747 + (auxvt[AT_PHDR].a_un.a_val & PAGE_ALIGN));
4749 + /* Determine if the shared lib loader is a symlink */
4750 + _dl_memset(buf, 0, sizeof(buf));
4751 + readsize = _dl_readlink(tpnt->libname, buf, sizeof(buf));
4752 + if (readsize > 0 && readsize < (int)(sizeof(buf)-1)) {
4753 + pnt1 = _dl_strrchr(buf, '/');
4754 + if (pnt1 && buf != pnt1) {
4755 +#ifdef __SUPPORT_LD_DEBUG_EARLY__
4756 + _dl_dprintf(_dl_debug_file, "changing tpnt->libname from '%s' to '%s'\n", tpnt->libname, buf);
4758 + tpnt->libname = _dl_strdup(buf);
4762 + /* Store the path where the shared lib loader was found for
4764 + pnt = _dl_strdup(tpnt->libname);
4765 + pnt1 = _dl_strrchr(pnt, '/');
4766 + if (pnt != pnt1) {
4768 + _dl_ldsopath = pnt;
4770 + _dl_ldsopath = tpnt->libname;
4772 +#ifdef __SUPPORT_LD_DEBUG_EARLY__
4773 + _dl_dprintf(_dl_debug_file, "Lib Loader:\t(%x) %s\n", tpnt->loadaddr, tpnt->libname);
4779 + /* Now we need to figure out what kind of options are selected.
4780 + Note that for SUID programs we ignore the settings in LD_LIBRARY_PATH */
4782 + if (_dl_getenv("LD_BIND_NOW", envp))
4785 + if ((auxvt[AT_UID].a_un.a_val == -1 && _dl_suid_ok()) ||
4786 + (auxvt[AT_UID].a_un.a_val != -1 &&
4787 + auxvt[AT_UID].a_un.a_val == auxvt[AT_EUID].a_un.a_val
4788 + && auxvt[AT_GID].a_un.a_val== auxvt[AT_EGID].a_un.a_val)) {
4790 + _dl_preload = _dl_getenv("LD_PRELOAD", envp);
4791 + _dl_library_path = _dl_getenv("LD_LIBRARY_PATH", envp);
4794 + _dl_preload = _dl_getenv("LD_PRELOAD", envp);
4795 + _dl_unsetenv("LD_AOUT_PRELOAD", envp);
4796 + _dl_unsetenv("LD_LIBRARY_PATH", envp);
4797 + _dl_unsetenv("LD_AOUT_LIBRARY_PATH", envp);
4798 + _dl_library_path = NULL;
4802 +#ifdef __SUPPORT_LD_DEBUG__
4803 + _dl_debug = _dl_getenv("LD_DEBUG", envp);
4806 + if (_dl_strstr(_dl_debug, "all")) {
4807 + _dl_debug_detail = _dl_debug_move = _dl_debug_symbols
4808 + = _dl_debug_reloc = _dl_debug_bindings = _dl_debug_nofixups = _dl_strstr(_dl_debug, "all");
4811 + _dl_debug_detail = _dl_strstr(_dl_debug, "detail");
4812 + _dl_debug_move = _dl_strstr(_dl_debug, "move");
4813 + _dl_debug_symbols = _dl_strstr(_dl_debug, "sym");
4814 + _dl_debug_reloc = _dl_strstr(_dl_debug, "reloc");
4815 + _dl_debug_nofixups = _dl_strstr(_dl_debug, "nofix");
4816 + _dl_debug_bindings = _dl_strstr(_dl_debug, "bind");
4820 + const char *dl_debug_output;
4822 + dl_debug_output = _dl_getenv("LD_DEBUG_OUTPUT", envp);
4824 + if (dl_debug_output)
4826 + char tmp[22], *tmp1, *filename;
4829 + _dl_memset(tmp, 0, sizeof(tmp));
4830 + tmp1=_dl_simple_ltoa( tmp, (unsigned long)_dl_getpid());
4832 + len1 = _dl_strlen(dl_debug_output);
4833 + len2 = _dl_strlen(tmp1);
4835 + filename = _dl_malloc(len1+len2+2);
4839 + _dl_strcpy (filename, dl_debug_output);
4840 + filename[len1] = '.';
4841 + _dl_strcpy (&filename[len1+1], tmp1);
4843 + _dl_debug_file= _dl_open (filename, O_WRONLY|O_CREAT);
4844 + if (_dl_debug_file<0)
4846 + _dl_debug_file = 2;
4847 + _dl_dprintf (2, "can't open file: '%s'\n",filename);
4855 + _dl_trace_loaded_objects = _dl_getenv("LD_TRACE_LOADED_OBJECTS", envp);
4856 +#ifndef __LDSO_LDD_SUPPORT__
4857 + if (_dl_trace_loaded_objects) {
4858 + _dl_dprintf(_dl_debug_file, "Use the ldd provided by uClibc\n");
4864 + * OK, fix one more thing - set up debug_addr so it will point
4865 + * to our chain. Later we may need to fill in more fields, but this
4866 + * should be enough for now.
4868 + debug_addr->r_map = (struct link_map *) _dl_loaded_modules;
4869 + debug_addr->r_version = 1;
4870 + debug_addr->r_ldbase = load_addr;
4871 + debug_addr->r_brk = (unsigned long) &_dl_debug_state;
4872 + _dl_debug_addr = debug_addr;
4874 + /* Notify the debugger we are in a consistant state */
4875 + _dl_debug_addr->r_state = RT_CONSISTENT;
4876 + _dl_debug_state();
4878 + /* OK, we now have the application in the list, and we have some
4879 + basic stuff in place. Now search through the list for other shared
4880 + libraries that should be loaded, and insert them on the list in the
4888 + char c, *str, *str2;
4890 + str = _dl_preload;
4891 + while (*str == ':' || *str == ' ' || *str == '\t')
4896 + while (*str2 && *str2 != ':' && *str2 != ' ' && *str2 != '\t')
4900 + if (!_dl_secure || _dl_strchr(str, '/') == NULL)
4902 + if ((tpnt1 = _dl_check_if_named_library_is_loaded(str)))
4906 +#if defined (__SUPPORT_LD_DEBUG__)
4907 + if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tfile='%s'; needed by '%s'\n",
4908 + str, _dl_progname);
4910 + tpnt1 = _dl_load_shared_library(_dl_secure, &rpnt, NULL, str);
4912 +#ifdef __LDSO_LDD_SUPPORT__
4913 + if (_dl_trace_loaded_objects)
4914 + _dl_dprintf(1, "\t%s => not found\n", str);
4918 + _dl_dprintf(2, "%s: can't load " "library '%s'\n", _dl_progname, str);
4922 +#ifdef __SUPPORT_LD_DEBUG_EARLY__
4923 + _dl_dprintf(_dl_debug_file, "Loading:\t(%x) %s\n", tpnt1->loadaddr, tpnt1->libname);
4925 +#ifdef __LDSO_LDD_SUPPORT__
4926 + if (_dl_trace_loaded_objects && tpnt1->usage_count==1) {
4927 + /* this is a real hack to make ldd not print
4928 + * the library itself when run on a library. */
4929 + if (_dl_strcmp(_dl_progname, str) != 0)
4930 + _dl_dprintf(1, "\t%s => %s (%x)\n", str, tpnt1->libname,
4931 + (unsigned) tpnt1->loadaddr);
4938 + while (*str == ':' || *str == ' ' || *str == '\t')
4943 +#ifdef SUPPORT_LDSO_PRELOAD_FILE
4948 + if (!_dl_stat(LDSO_PRELOAD, &st) && st.st_size > 0) {
4949 + if ((fd = _dl_open(LDSO_PRELOAD, O_RDONLY)) < 0) {
4950 + _dl_dprintf(2, "%s: can't open file '%s'\n",
4951 + _dl_progname, LDSO_PRELOAD);
4953 + preload = (caddr_t) _dl_mmap(0, st.st_size + 1,
4954 + PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
4956 + if (preload == (caddr_t) - 1) {
4957 + _dl_dprintf(2, "%s: can't map file '%s'\n",
4958 + _dl_progname, LDSO_PRELOAD);
4960 + char c, *cp, *cp2;
4962 + /* convert all separators and comments to spaces */
4963 + for (cp = preload; *cp; /*nada */ ) {
4964 + if (*cp == ':' || *cp == '\t' || *cp == '\n') {
4966 + } else if (*cp == '#') {
4969 + while (*cp != '\n' && *cp != '\0');
4975 + /* find start of first library */
4976 + for (cp = preload; *cp && *cp == ' '; cp++)
4980 + /* find end of library */
4981 + for (cp2 = cp; *cp && *cp != ' '; cp++)
4986 + if ((tpnt1 = _dl_check_if_named_library_is_loaded(cp2)))
4990 +#if defined (__SUPPORT_LD_DEBUG__)
4991 + if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tfile='%s'; needed by '%s'\n",
4992 + cp2, _dl_progname);
4994 + tpnt1 = _dl_load_shared_library(0, &rpnt, NULL, cp2);
4996 +#ifdef __LDSO_LDD_SUPPORT__
4997 + if (_dl_trace_loaded_objects)
4998 + _dl_dprintf(1, "\t%s => not found\n", cp2);
5002 + _dl_dprintf(2, "%s: can't load library '%s'\n", _dl_progname, cp2);
5006 +#ifdef __SUPPORT_LD_DEBUG_EARLY__
5007 + _dl_dprintf(_dl_debug_file, "Loading:\t(%x) %s\n", tpnt1->loadaddr, tpnt1->libname);
5009 +#ifdef __LDSO_LDD_SUPPORT__
5010 + if (_dl_trace_loaded_objects && tpnt1->usage_count==1) {
5011 + _dl_dprintf(1, "\t%s => %s (%x)\n", cp2,
5012 + tpnt1->libname, (unsigned) tpnt1->loadaddr);
5017 + /* find start of next library */
5019 + for ( /*nada */ ; *cp && *cp == ' '; cp++)
5023 + _dl_munmap(preload, st.st_size + 1);
5030 + for (tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next)
5033 + for (dpnt = (Elf32_Dyn *) tcurr->dynamic_addr; dpnt->d_tag; dpnt++)
5035 + if (dpnt->d_tag == DT_NEEDED)
5038 + lpntstr = (char*) (tcurr->loadaddr + tcurr->dynamic_info[DT_STRTAB] + dpnt->d_un.d_val);
5039 + name = _dl_get_last_path_component(lpntstr);
5041 + if ((tpnt1 = _dl_check_if_named_library_is_loaded(name)))
5045 +#if defined (__SUPPORT_LD_DEBUG__)
5046 + if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tfile='%s'; needed by '%s'\n",
5047 + lpntstr, _dl_progname);
5049 + if (!(tpnt1 = _dl_load_shared_library(0, &rpnt, tcurr, lpntstr)))
5051 +#ifdef __LDSO_LDD_SUPPORT__
5052 + if (_dl_trace_loaded_objects) {
5053 + _dl_dprintf(1, "\t%s => not found\n", lpntstr);
5058 + _dl_dprintf(2, "%s: can't load library '%s'\n", _dl_progname, lpntstr);
5062 +#ifdef __SUPPORT_LD_DEBUG_EARLY__
5063 + _dl_dprintf(_dl_debug_file, "Loading:\t(%x) %s\n", tpnt1->loadaddr, tpnt1->libname);
5065 +#ifdef __LDSO_LDD_SUPPORT__
5066 + if (_dl_trace_loaded_objects && tpnt1->usage_count==1) {
5067 + _dl_dprintf(1, "\t%s => %s (%x)\n", lpntstr, tpnt1->libname,
5068 + (unsigned) tpnt1->loadaddr);
5077 + _dl_unmap_cache();
5080 + * If the program interpreter is not in the module chain, add it. This will
5081 + * be required for dlopen to be able to access the internal functions in the
5085 + tcurr = _dl_loaded_modules;
5087 + while (tcurr->next)
5088 + tcurr = tcurr->next;
5089 + tpnt->next = NULL;
5090 + tpnt->usage_count++;
5093 + tcurr->next = tpnt;
5094 + tpnt->prev = tcurr;
5096 + _dl_loaded_modules = tpnt;
5097 + tpnt->prev = NULL;
5100 + rpnt->next = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
5101 + _dl_memset(rpnt->next, 0, sizeof(struct dyn_elf));
5102 + rpnt->next->prev = rpnt;
5103 + rpnt = rpnt->next;
5105 + rpnt = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
5106 + _dl_memset(rpnt, 0, sizeof(struct dyn_elf));
5112 +#ifdef __LDSO_LDD_SUPPORT__
5113 + /* End of the line for ldd.... */
5114 + if (_dl_trace_loaded_objects) {
5115 + _dl_dprintf(1, "\t%s => %s (%x)\n", rpnt->dyn->libname + (_dl_strlen(_dl_ldsopath)) + 1,
5116 + rpnt->dyn->libname, rpnt->dyn->loadaddr);
5124 + * Relocation of the GOT entries for MIPS have to be done
5125 + * after all the libraries have been loaded.
5127 + _dl_perform_mips_global_got_relocations(_dl_loaded_modules);
5130 +#ifdef __SUPPORT_LD_DEBUG_EARLY__
5131 + _dl_dprintf(_dl_debug_file, "Beginning relocation fixups\n");
5134 + * OK, now all of the kids are tucked into bed in their proper addresses.
5135 + * Now we go through and look for REL and RELA records that indicate fixups
5136 + * to the GOT tables. We need to do this in reverse order so that COPY
5137 + * directives work correctly */
5138 + goof = _dl_loaded_modules ? _dl_fixup(_dl_loaded_modules, _dl_be_lazy) : 0;
5141 + /* Some flavors of SVr4 do not generate the R_*_COPY directive,
5142 + and we have to manually search for entries that require fixups.
5143 + Solaris gets this one right, from what I understand. */
5145 +#ifdef __SUPPORT_LD_DEBUG_EARLY__
5146 + _dl_dprintf(_dl_debug_file, "Beginning copy fixups\n");
5148 + if (_dl_symbol_tables)
5149 + goof += _dl_copy_fixups(_dl_symbol_tables);
5151 + /* OK, at this point things are pretty much ready to run. Now we
5152 + need to touch up a few items that are required, and then
5153 + we can let the user application have at it. Note that
5154 + the dynamic linker itself is not guaranteed to be fully
5155 + dynamicly linked if we are using ld.so.1, so we have to look
5156 + up each symbol individually. */
5159 + _dl_brkp = (unsigned long *) (intptr_t) _dl_find_hash("___brk_addr", NULL, NULL, symbolrel);
5162 + *_dl_brkp = brk_addr;
5164 + _dl_envp = (unsigned long *) (intptr_t) _dl_find_hash("__environ", NULL, NULL, symbolrel);
5167 + *_dl_envp = (unsigned long) envp;
5170 +#ifndef FORCE_SHAREABLE_TEXT_SEGMENTS
5173 + ElfW(Phdr) *myppnt;
5175 + /* We had to set the protections of all pages to R/W for dynamic linking.
5176 + Set text pages back to R/O */
5177 + for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
5178 + for (myppnt = tpnt->ppnt, j = 0; j < tpnt->n_phent; j++, myppnt++) {
5179 + if (myppnt->p_type == PT_LOAD && !(myppnt->p_flags & PF_W) && tpnt->dynamic_info[DT_TEXTREL]) {
5180 + _dl_mprotect((void *) (tpnt->loadaddr + (myppnt->p_vaddr & PAGE_ALIGN)),
5181 + (myppnt->p_vaddr & ADDR_ALIGN) + (unsigned long) myppnt->p_filesz, LXFLAGS(myppnt->p_flags));
5188 + _dl_atexit = (int (*)(void *)) (intptr_t) _dl_find_hash("atexit", NULL, NULL, symbolrel);
5189 +#if defined (__SUPPORT_LD_DEBUG__)
5190 + _dl_on_exit = (int (*)(void (*)(int, void *),void*))
5191 + (intptr_t) _dl_find_hash("on_exit", NULL, NULL, symbolrel);
5194 + /* Notify the debugger we have added some objects. */
5195 + _dl_debug_addr->r_state = RT_ADD;
5196 + _dl_debug_state();
5198 + for (rpnt = _dl_symbol_tables; rpnt!=NULL&& rpnt->next!=NULL; rpnt=rpnt->next)
5201 + for (;rpnt!=NULL; rpnt=rpnt->prev)
5205 + if (tpnt->libtype == program_interpreter)
5208 + /* Apparently crt0/1 for the application is responsible for handling this.
5209 + * We only need to run the init/fini for shared libraries
5211 + if (tpnt->libtype == elf_executable)
5212 + break; /* at this point all shared libs are initialized !! */
5214 + if (tpnt->init_flag & INIT_FUNCS_CALLED)
5216 + tpnt->init_flag |= INIT_FUNCS_CALLED;
5218 + if (tpnt->dynamic_info[DT_INIT]) {
5219 + void (*dl_elf_func) (void);
5220 + dl_elf_func = (void (*)(void)) (intptr_t) (tpnt->loadaddr + tpnt->dynamic_info[DT_INIT]);
5221 +#if defined (__SUPPORT_LD_DEBUG__)
5222 + if(_dl_debug) _dl_dprintf(_dl_debug_file,"\ncalling init: %s\n\n", tpnt->libname);
5224 + (*dl_elf_func) ();
5226 + if (_dl_atexit && tpnt->dynamic_info[DT_FINI]) {
5227 + void (*dl_elf_func) (void);
5228 + dl_elf_func = (void (*)(void)) (intptr_t) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI]);
5229 + (*_dl_atexit) (dl_elf_func);
5230 +#if defined (__SUPPORT_LD_DEBUG__)
5231 + if(_dl_debug && _dl_on_exit)
5233 + (*_dl_on_exit)(debug_fini, tpnt->libname);
5237 +#if defined (__SUPPORT_LD_DEBUG__)
5240 + _dl_dprintf(_dl_debug_file, "%s: The address of atexit () is 0x0.\n", tpnt->libname);
5242 + if (!tpnt->dynamic_info[DT_FINI])
5243 + _dl_dprintf(_dl_debug_file, "%s: Invalid .fini section.\n", tpnt->libname);
5251 + * This stub function is used by some debuggers. The idea is that they
5252 + * can set an internal breakpoint on it, so that we are notified when the
5253 + * address mapping is changed in some way.
5255 +void _dl_debug_state(void)
5259 +char *_dl_getenv(const char *symbol, char **envp)
5264 + while ((pnt = *envp++)) {
5266 + while (*pnt && *pnt == *pnt1)
5268 + if (!*pnt || *pnt != '=' || *pnt1)
5275 +void _dl_unsetenv(const char *symbol, char **envp)
5279 + char **newenvp = envp;
5281 + for (pnt = *envp; pnt; pnt = *++envp) {
5283 + while (*pnt && *pnt == *pnt1)
5285 + if (!*pnt || *pnt != '=' || *pnt1)
5286 + *newenvp++ = *envp;
5288 + *newenvp++ = *envp;
5293 +#include "readelflib1.c"
5294 diff -urN uClibc/ldso-0.9.24/ldso/m68k/boot1_arch.h uClibc.ldso.24/ldso-0.9.24/ldso/m68k/boot1_arch.h
5295 --- uClibc/ldso-0.9.24/ldso/m68k/boot1_arch.h 1969-12-31 18:00:00.000000000 -0600
5296 +++ uClibc.ldso.24/ldso-0.9.24/ldso/m68k/boot1_arch.h 2002-08-08 09:35:37.000000000 -0500
5298 +/* Any assmbly language/system dependent hacks needed to setup boot1.c so it
5299 + * will work as expected and cope with whatever platform specific wierdness is
5300 + * needed for this architecture. See arm/boot1_arch.h for an example of what
5304 +#define LD_BOOT(X) void _dl_boot (X)
5305 diff -urN uClibc/ldso-0.9.24/ldso/m68k/elfinterp.c uClibc.ldso.24/ldso-0.9.24/ldso/m68k/elfinterp.c
5306 --- uClibc/ldso-0.9.24/ldso/m68k/elfinterp.c 1969-12-31 18:00:00.000000000 -0600
5307 +++ uClibc.ldso.24/ldso-0.9.24/ldso/m68k/elfinterp.c 2002-11-05 12:21:04.000000000 -0600
5309 +/* vi: set sw=4 ts=4: */
5310 +/* m68k ELF shared library loader suppport
5312 + * Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald,
5313 + * David Engel, Hongjiu Lu and Mitch D'Souza
5314 + * Adapted to ELF/68k by Andreas Schwab.
5316 + * All rights reserved.
5318 + * Redistribution and use in source and binary forms, with or without
5319 + * modification, are permitted provided that the following conditions
5321 + * 1. Redistributions of source code must retain the above copyright
5322 + * notice, this list of conditions and the following disclaimer.
5323 + * 2. The name of the above contributors may not be
5324 + * used to endorse or promote products derived from this software
5325 + * without specific prior written permission.
5327 + * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
5328 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
5329 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
5330 + * ARE DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE
5331 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
5332 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
5333 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
5334 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
5335 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5336 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5340 +#if defined (__SUPPORT_LD_DEBUG__)
5341 +static const char *_dl_reltypes[] =
5344 + "R_68K_32", "R_68K_16", "R_68K_8",
5345 + "R_68K_PC32", "R_68K_PC16", "R_68K_PC8",
5346 + "R_68K_GOT32", "R_68K_GOT16", "R_68K_GOT8",
5347 + "R_68K_GOT32O", "R_68K_GOT16O", "R_68K_GOT8O",
5348 + "R_68K_PLT32", "R_68K_PLT16", "R_68K_PLT8",
5349 + "R_68K_PLT32O", "R_68K_PLT16O", "R_68K_PLT8O",
5350 + "R_68K_COPY", "R_68K_GLOB_DAT", "R_68K_JMP_SLOT", "R_68K_RELATIVE",
5355 +/* Program to load an ELF binary on a linux system, and run it.
5356 + References to symbols in sharable libraries can be resolved by either
5357 + an ELF sharable library or a linux style of shared library. */
5359 +/* Disclaimer: I have never seen any AT&T source code for SVr4, nor have
5360 + I ever taken any courses on internals. This program was developed using
5361 + information available through the book "UNIX SYSTEM V RELEASE 4,
5362 + Programmers guide: Ansi C and Programming Support Tools", which did
5363 + a more than adequate job of explaining everything required to get this
5367 +unsigned int _dl_linux_resolver (int dummy1, int dummy2,
5368 + struct elf_resolve *tpnt, int reloc_entry)
5371 + Elf32_Rela *this_reloc;
5373 + Elf32_Sym *symtab;
5378 + unsigned int instr_addr;
5380 + rel_addr = tpnt->loadaddr + tpnt->dynamic_info[DT_JMPREL];
5381 + this_reloc = (Elf32_Rela *) (rel_addr + reloc_entry);
5382 + reloc_type = ELF32_R_TYPE (this_reloc->r_info);
5383 + symtab_index = ELF32_R_SYM (this_reloc->r_info);
5385 + symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB]
5386 + + tpnt->loadaddr);
5387 + strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
5390 + if (reloc_type != R_68K_JMP_SLOT)
5392 + _dl_dprintf (2, "%s: incorrect relocation type in jump relocations\n",
5397 + /* Address of jump instruction to fix up. */
5398 + instr_addr = (int) this_reloc->r_offset + (int) tpnt->loadaddr;
5399 + got_addr = (char **) instr_addr;
5401 +#ifdef __SUPPORT_LD_DEBUG__
5402 + if (_dl_debug_symbols) {
5403 + _dl_dprintf (2, "Resolving symbol %s\n", strtab + symtab[symtab_index].st_name);
5407 + /* Get the address of the GOT entry. */
5408 + new_addr = _dl_find_hash (strtab + symtab[symtab_index].st_name,
5409 + tpnt->symbol_scope, tpnt, resolver);
5412 + _dl_dprintf (2, "%s: can't resolve symbol '%s'\n",
5413 + _dl_progname, strtab + symtab[symtab_index].st_name);
5416 +#if defined (__SUPPORT_LD_DEBUG__)
5417 + if ((unsigned long) got_addr < 0x40000000)
5419 + if (_dl_debug_bindings)
5421 + _dl_dprintf(_dl_debug_file, "\nresolve function: %s",
5422 + strtab + symtab[symtab_index].st_name);
5423 + if(_dl_debug_detail) _dl_dprintf(_dl_debug_file,
5424 + "\tpatch %x ==> %x @ %x", *got_addr, new_addr, got_addr);
5427 + if (!_dl_debug_nofixups) {
5428 + *got_addr = new_addr;
5431 + *got_addr = new_addr;
5434 + return (unsigned int) new_addr;
5438 +_dl_parse_lazy_relocation_information (struct elf_resolve *tpnt,
5439 + unsigned long rel_addr, unsigned long rel_size, int type)
5445 + Elf32_Sym *symtab;
5447 + unsigned int *reloc_addr;
5449 + /* Now parse the relocation information. */
5450 + rpnt = (Elf32_Rela *) (rel_addr + tpnt->loadaddr);
5451 + rel_size = rel_size / sizeof (Elf32_Rela);
5453 + symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB]
5454 + + tpnt->loadaddr);
5455 + strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
5457 + for (i = 0; i < rel_size; i++, rpnt++)
5459 + reloc_addr = (int *) (tpnt->loadaddr + (int) rpnt->r_offset);
5460 + reloc_type = ELF32_R_TYPE (rpnt->r_info);
5461 + symtab_index = ELF32_R_SYM (rpnt->r_info);
5463 + /* When the dynamic linker bootstrapped itself, it resolved some symbols.
5464 + Make sure we do not do them again. */
5465 + if (tpnt->libtype == program_interpreter
5467 + || _dl_symbol (strtab + symtab[symtab_index].st_name)))
5470 + switch (reloc_type)
5474 + case R_68K_JMP_SLOT:
5475 + *reloc_addr += (unsigned int) tpnt->loadaddr;
5478 + _dl_dprintf (2, "%s: (LAZY) can't handle reloc type ", _dl_progname);
5479 +#if defined (__SUPPORT_LD_DEBUG__)
5480 + _dl_dprintf (2, "%s ", _dl_reltypes[reloc_type]);
5483 + _dl_dprintf (2, "'%s'", strtab + symtab[symtab_index].st_name);
5484 + _dl_dprintf (2, "\n");
5491 +_dl_parse_relocation_information (struct elf_resolve *tpnt,
5492 + unsigned long rel_addr, unsigned long rel_size, int type)
5498 + Elf32_Sym *symtab;
5500 + unsigned int *reloc_addr;
5501 + unsigned int symbol_addr;
5503 + /* Now parse the relocation information */
5505 + rpnt = (Elf32_Rela *) (rel_addr + tpnt->loadaddr);
5506 + rel_size = rel_size / sizeof (Elf32_Rela);
5508 + symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB]
5509 + + tpnt->loadaddr);
5510 + strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
5512 + for (i = 0; i < rel_size; i++, rpnt++)
5514 + reloc_addr = (int *) (tpnt->loadaddr + (int) rpnt->r_offset);
5515 + reloc_type = ELF32_R_TYPE (rpnt->r_info);
5516 + symtab_index = ELF32_R_SYM (rpnt->r_info);
5519 + if (tpnt->libtype == program_interpreter
5521 + || _dl_symbol (strtab + symtab[symtab_index].st_name)))
5526 + symbol_addr = (unsigned int)
5527 + _dl_find_hash (strtab + symtab[symtab_index].st_name,
5528 + tpnt->symbol_scope,
5529 + reloc_type == R_68K_JMP_SLOT ? tpnt : NULL, symbolrel);
5531 + /* We want to allow undefined references to weak symbols -
5532 + this might have been intentional. We should not be
5533 + linking local symbols here, so all bases should be
5536 + && ELF32_ST_BIND (symtab[symtab_index].st_info) == STB_GLOBAL)
5538 + _dl_dprintf (2, "%s: can't resolve symbol '%s'\n",
5539 + _dl_progname, strtab + symtab[symtab_index].st_name);
5543 + switch (reloc_type)
5548 + *(char *) reloc_addr = symbol_addr + rpnt->r_addend;
5551 + *(short *) reloc_addr = symbol_addr + rpnt->r_addend;
5554 + *reloc_addr = symbol_addr + rpnt->r_addend;
5557 + *(char *) reloc_addr = (symbol_addr + rpnt->r_addend
5558 + - (unsigned int) reloc_addr);
5561 + *(short *) reloc_addr = (symbol_addr + rpnt->r_addend
5562 + - (unsigned int) reloc_addr);
5565 + *reloc_addr = (symbol_addr + rpnt->r_addend
5566 + - (unsigned int) reloc_addr);
5568 + case R_68K_GLOB_DAT:
5569 + case R_68K_JMP_SLOT:
5570 + *reloc_addr = symbol_addr;
5572 + case R_68K_RELATIVE:
5573 + *reloc_addr = ((unsigned int) tpnt->loadaddr
5574 + /* Compatibility kludge. */
5575 + + (rpnt->r_addend ? : *reloc_addr));
5578 +#if 0 /* Do this later. */
5579 + _dl_dprintf (2, "Doing copy");
5581 + _dl_dprintf (2, " for symbol %s",
5582 + strtab + symtab[symtab_index].st_name);
5583 + _dl_dprintf (2, "\n");
5584 + _dl_memcpy ((void *) symtab[symtab_index].st_value,
5585 + (void *) symbol_addr,
5586 + symtab[symtab_index].st_size);
5590 + _dl_dprintf (2, "%s: can't handle reloc type ", _dl_progname);
5591 +#if defined (__SUPPORT_LD_DEBUG__)
5592 + _dl_dprintf (2, "%s ", _dl_reltypes[reloc_type]);
5595 + _dl_dprintf (2, "'%s'", strtab + symtab[symtab_index].st_name);
5596 + _dl_dprintf (2, "\n");
5604 +/* This is done as a separate step, because there are cases where
5605 + information is first copied and later initialized. This results in
5606 + the wrong information being copied. Someone at Sun was complaining about
5607 + a bug in the handling of _COPY by SVr4, and this may in fact be what he
5608 + was talking about. Sigh. */
5610 +/* No, there are cases where the SVr4 linker fails to emit COPY relocs
5614 +_dl_parse_copy_information (struct dyn_elf *xpnt, unsigned long rel_addr,
5615 + unsigned long rel_size, int type)
5621 + Elf32_Sym *symtab;
5623 + unsigned int *reloc_addr;
5624 + unsigned int symbol_addr;
5625 + struct elf_resolve *tpnt;
5627 + /* Now parse the relocation information */
5631 + rpnt = (Elf32_Rela *) (rel_addr + tpnt->loadaddr);
5632 + rel_size = rel_size / sizeof (Elf32_Rela);
5634 + symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB]
5635 + + tpnt->loadaddr);
5636 + strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
5638 + for (i = 0; i < rel_size; i++, rpnt++)
5640 + reloc_addr = (int *) (tpnt->loadaddr + (int) rpnt->r_offset);
5641 + reloc_type = ELF32_R_TYPE (rpnt->r_info);
5642 + if (reloc_type != R_68K_COPY)
5644 + symtab_index = ELF32_R_SYM (rpnt->r_info);
5646 + if (tpnt->libtype == program_interpreter
5648 + || _dl_symbol (strtab + symtab[symtab_index].st_name)))
5652 + symbol_addr = (unsigned int)
5653 + _dl_find_hash (strtab + symtab[symtab_index].st_name,
5654 + xpnt->next, NULL, copyrel);
5657 + _dl_dprintf (2, "%s: can't resolve symbol '%s'\n",
5658 + _dl_progname, strtab + symtab[symtab_index].st_name);
5663 + _dl_memcpy ((void *) symtab[symtab_index].st_value, (void *) symbol_addr,
5664 + symtab[symtab_index].st_size);
5668 diff -urN uClibc/ldso-0.9.24/ldso/m68k/ld_syscalls.h uClibc.ldso.24/ldso-0.9.24/ldso/m68k/ld_syscalls.h
5669 --- uClibc/ldso-0.9.24/ldso/m68k/ld_syscalls.h 1969-12-31 18:00:00.000000000 -0600
5670 +++ uClibc.ldso.24/ldso-0.9.24/ldso/m68k/ld_syscalls.h 2002-03-19 04:43:32.000000000 -0600
5673 + * This file contains the system call macros and syscall
5674 + * numbers used by the shared library loader.
5677 +#define __NR_exit 1
5678 +#define __NR_read 3
5679 +#define __NR_write 4
5680 +#define __NR_open 5
5681 +#define __NR_close 6
5682 +#define __NR_getuid 24
5683 +#define __NR_geteuid 49
5684 +#define __NR_getgid 47
5685 +#define __NR_getegid 50
5686 +#define __NR_readlink 85
5687 +#define __NR_mmap 90
5688 +#define __NR_munmap 91
5689 +#define __NR_stat 106
5690 +#define __NR_mprotect 125
5693 +/* Here are the macros which define how this platform makes
5694 + * system calls. This particular variant does _not_ set
5695 + * errno (note how it is disabled in __syscall_return) since
5696 + * these will get called before the errno symbol is dynamicly
5700 +#define __syscall_return(type, res) \
5702 + if ((unsigned long)(res) >= (unsigned long)(-125)) { \
5703 + /* avoid using res which is declared to be in register d0; \
5704 + errno might expand to a function call and clobber it. */ \
5705 + /* int __err = -(res); \
5706 + errno = __err; */ \
5709 + return (type) (res); \
5712 +#define _syscall0(type, name) \
5716 + __asm__ __volatile__ ("movel %1, %%d0\n\t" \
5718 + "movel %%d0, %0" \
5720 + : "i" (__NR_##name) \
5722 + if ((unsigned long)(__res) >= (unsigned long)(-125)) { \
5723 + /* errno = -__res; */ \
5726 + return (type)__res; \
5729 +#define _syscall1(type, name, atype, a) \
5730 +type name(atype a) \
5733 + __asm__ __volatile__ ("movel %2, %%d1\n\t" \
5734 + "movel %1, %%d0\n\t" \
5736 + "movel %%d0, %0" \
5738 + : "i" (__NR_##name), \
5740 + : "cc", "%d0", "%d1"); \
5741 + if ((unsigned long)(__res) >= (unsigned long)(-125)) { \
5742 + /* errno = -__res; */ \
5745 + return (type)__res; \
5748 +#define _syscall2(type, name, atype, a, btype, b) \
5749 +type name(atype a, btype b) \
5752 + __asm__ __volatile__ ("movel %3, %%d2\n\t" \
5753 + "movel %2, %%d1\n\t" \
5754 + "movel %1, %%d0\n\t" \
5756 + "movel %%d0, %0" \
5758 + : "i" (__NR_##name), \
5761 + : "cc", "%d0", "%d1", "%d2"); \
5762 + if ((unsigned long)(__res) >= (unsigned long)(-125)) { \
5763 + /* errno = -__res; */ \
5766 + return (type)__res; \
5769 +#define _syscall3(type, name, atype, a, btype, b, ctype, c) \
5770 +type name(atype a, btype b, ctype c) \
5773 + __asm__ __volatile__ ("movel %4, %%d3\n\t" \
5774 + "movel %3, %%d2\n\t" \
5775 + "movel %2, %%d1\n\t" \
5776 + "movel %1, %%d0\n\t" \
5778 + "movel %%d0, %0" \
5780 + : "i" (__NR_##name), \
5784 + : "cc", "%d0", "%d1", "%d2", "%d3"); \
5785 + if ((unsigned long)(__res) >= (unsigned long)(-125)) { \
5786 + /* errno = -__res; */ \
5789 + return (type)__res; \
5792 +#define _syscall4(type, name, atype, a, btype, b, ctype, c, dtype, d) \
5793 +type name(atype a, btype b, ctype c, dtype d) \
5796 + __asm__ __volatile__ ("movel %5, %%d4\n\t" \
5797 + "movel %4, %%d3\n\t" \
5798 + "movel %3, %%d2\n\t" \
5799 + "movel %2, %%d1\n\t" \
5800 + "movel %1, %%d0\n\t" \
5802 + "movel %%d0, %0" \
5804 + : "i" (__NR_##name), \
5809 + : "cc", "%d0", "%d1", "%d2", "%d3", \
5811 + if ((unsigned long)(__res) >= (unsigned long)(-125)) { \
5812 + /* errno = -__res; */ \
5815 + return (type)__res; \
5818 +#define _syscall5(type, name, atype, a, btype, b, ctype, c, dtype, d, etype, e)\
5819 +type name(atype a, btype b, ctype c, dtype d, etype e) \
5822 + __asm__ __volatile__ ("movel %6, %%d5\n\t" \
5823 + "movel %5, %%d4\n\t" \
5824 + "movel %4, %%d3\n\t" \
5825 + "movel %3, %%d2\n\t" \
5826 + "movel %2, %%d1\n\t" \
5827 + "movel %1, %%d0\n\t" \
5829 + "movel %%d0, %0" \
5831 + : "i" (__NR_##name), \
5837 + : "cc", "%d0", "%d1", "%d2", "%d3", \
5839 + if ((unsigned long)(__res) >= (unsigned long)(-125)) { \
5840 + /* errno = -__res; */ \
5843 + return (type)__res; \
5846 diff -urN uClibc/ldso-0.9.24/ldso/m68k/ld_sysdep.h uClibc.ldso.24/ldso-0.9.24/ldso/m68k/ld_sysdep.h
5847 --- uClibc/ldso-0.9.24/ldso/m68k/ld_sysdep.h 1969-12-31 18:00:00.000000000 -0600
5848 +++ uClibc.ldso.24/ldso-0.9.24/ldso/m68k/ld_sysdep.h 2002-05-28 16:33:34.000000000 -0500
5851 +/* Various assmbly language/system dependent hacks that are required
5852 + so that we can minimize the amount of platform specific code. */
5854 +/* Define this if the system uses RELOCA. */
5855 +#define ELF_USES_RELOCA
5857 +/* Get a pointer to the argv array. On many platforms this can be
5858 + just the address if the first argument, on other platforms we need
5859 + to do something a little more subtle here. */
5860 +#define GET_ARGV(ARGVP, ARGS) ((ARGVP) = ((unsigned int *) &(ARGS)))
5862 +/* Initialization sequence for a GOT. */
5863 +#define INIT_GOT(GOT_BASE,MODULE) \
5865 + GOT_BASE[2] = (int) _dl_linux_resolve; \
5866 + GOT_BASE[1] = (int) (MODULE); \
5869 +/* Here is a macro to perform a relocation. This is only used when
5870 + bootstrapping the dynamic loader. RELP is the relocation that we
5871 + are performing, REL is the pointer to the address we are
5872 + relocating. SYMBOL is the symbol involved in the relocation, and
5873 + LOAD is the load address. */
5874 +#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD) \
5875 + switch (ELF32_R_TYPE ((RELP)->r_info)) \
5878 + *(char *) (REL) = (SYMBOL) + (RELP)->r_addend; \
5881 + *(short *) (REL) = (SYMBOL) + (RELP)->r_addend; \
5884 + *(REL) = (SYMBOL) + (RELP)->r_addend; \
5887 + *(char *) (REL) = ((SYMBOL) + (RELP)->r_addend \
5888 + - (unsigned int) (REL)); \
5890 + case R_68K_PC16: \
5891 + *(short *) (REL) = ((SYMBOL) + (RELP)->r_addend \
5892 + - (unsigned int) (REL)); \
5894 + case R_68K_PC32: \
5895 + *(REL) = ((SYMBOL) + (RELP)->r_addend \
5896 + - (unsigned int) (REL)); \
5898 + case R_68K_GLOB_DAT: \
5899 + case R_68K_JMP_SLOT: \
5900 + *(REL) = (SYMBOL); \
5902 + case R_68K_RELATIVE: /* Compatibility kludge */ \
5903 + *(REL) = ((unsigned int) (LOAD) + ((RELP)->r_addend ? : *(REL))); \
5910 +/* Transfer control to the user's application, once the dynamic loader
5914 + __asm__ volatile ("unlk %%a6\n\t" \
5916 + : : "a" (_dl_elf_main));
5920 +/* Here we define the magic numbers that this dynamic loader should accept */
5922 +#define MAGIC1 EM_68K
5924 +/* Used for error messages */
5925 +#define ELF_TARGET "m68k"
5927 +struct elf_resolve;
5928 +extern unsigned int _dl_linux_resolver (int, int, struct elf_resolve *, int);
5930 +/* Define this because we do not want to call .udiv in the library.
5931 + Not needed for m68k. */
5932 +#define do_rem(result, n, base) ((result) = (n) % (base))
5934 +/* 4096 bytes alignment */
5935 +#define PAGE_ALIGN 0xfffff000
5936 +#define ADDR_ALIGN 0xfff
5937 +#define OFFS_ALIGN 0x7ffff000
5938 diff -urN uClibc/ldso-0.9.24/ldso/m68k/resolve.S uClibc.ldso.24/ldso-0.9.24/ldso/m68k/resolve.S
5939 --- uClibc/ldso-0.9.24/ldso/m68k/resolve.S 1969-12-31 18:00:00.000000000 -0600
5940 +++ uClibc.ldso.24/ldso-0.9.24/ldso/m68k/resolve.S 2001-04-27 12:23:26.000000000 -0500
5943 + * These are various helper routines that are needed to run an ELF image.
5949 +.globl _dl_linux_resolve
5950 + .type _dl_linux_resolve,@function
5952 + moveml %a0/%a1,%sp@-
5954 + bsrl _dl_linux_resolver@PLTPC
5956 + jbsr _dl_linux_resolver
5958 + moveml %sp@+,%a0/%a1
5962 + .size _dl_linux_resolve,.LFE2-_dl_linux_resolve
5963 diff -urN uClibc/ldso-0.9.24/ldso/mips/README uClibc.ldso.24/ldso-0.9.24/ldso/mips/README
5964 --- uClibc/ldso-0.9.24/ldso/mips/README 1969-12-31 18:00:00.000000000 -0600
5965 +++ uClibc.ldso.24/ldso-0.9.24/ldso/mips/README 2002-07-25 16:15:59.000000000 -0500
5967 +Almost all of the code present in these source files was taken
5968 +from GLIBC. In the descriptions below, all files mentioned are
5969 +with respect to the top level GLIBC source directory accept for
5970 +code taken from the Linux kernel.
5974 +Contains code to fix up the stack pointer so that the dynamic
5975 +linker can find argc, argv and Auxillary Vector Table (AVT).
5976 +The code is taken from the function 'RTLD_START' in the file
5977 +'sysdeps/mips/dl-machine.h'.
5981 +Contains the runtime resolver code taken from the function
5982 +'__dl_runtime_resolve' in 'sysdeps/mips/dl-machine.h'. Also
5983 +contains the function to perform relocations for objects
5984 +other than the linker itself. The code was taken from the
5985 +function 'elf_machine_rel' in 'sysdeps/mips/dl-machine.h'.
5989 +Used to contain all the macro functions for the system calls
5990 +as well as the list of system calls supported. We now include
5991 +<sys/syscall.h> but with the __set_errno macro defined empty
5992 +so we can use the same file for the linker as well as userspace.
5993 +Original code was taken from the Linux kernel source 2.4.17 and
5994 +can be found in the file 'include/asm-mips/unistd.h'.
5998 +Contains bootstrap code for the dynamic linker, magic numbers
5999 +for detecting MIPS target types and some macros. The macro
6000 +function 'PERFORM_BOOTSTRAP_GOT' is used to relocate the dynamic
6001 +linker's GOT so that function calls can be made. The code is
6002 +taken from the function 'ELF_MACHINE_BEFORE_RTLD_RELOC' in the
6003 +file 'sysdeps/mips/dl-machine.h'. The other macro function
6004 +'PERFORM_BOOTSTRAP_RELOC' is used to do the relocations for
6005 +the dynamic loader. The code is taken from the function
6006 +'elf_machine_rel' in the file 'sysdeps/mips/dl-machine.h'. The
6007 +final macro function is 'INIT_GOT' which initializes the GOT
6008 +for the application being dynamically linked and loaded. The
6009 +code is taken from the functions 'elf_machine_runtime_setup'
6010 +and 'elf_machine_got_rel' in 'sysdeps/mips/dl-machine.h'.
6014 +Contains the low-level assembly code for the dynamic runtime
6015 +resolver. The code is taken from the assembly code function
6016 +'_dl_runtime_resolve' in the file 'sysdeps/mips/dl-machine.h'.
6017 +The code looks a bit different since we only need to pass the
6018 +symbol index and the old GP register.
6019 diff -urN uClibc/ldso-0.9.24/ldso/mips/boot1_arch.h uClibc.ldso.24/ldso-0.9.24/ldso/mips/boot1_arch.h
6020 --- uClibc/ldso-0.9.24/ldso/mips/boot1_arch.h 1969-12-31 18:00:00.000000000 -0600
6021 +++ uClibc.ldso.24/ldso-0.9.24/ldso/mips/boot1_arch.h 2003-06-12 16:39:10.000000000 -0500
6023 +/* Any assmbly language/system dependent hacks needed to setup boot1.c so it
6024 + * will work as expected and cope with whatever platform specific wierdness is
6025 + * needed for this architecture.
6030 +" .globl _dl_boot\n" \
6032 +" .set noreorder\n" \
6033 +" bltzal $0, 0f\n" \
6035 +"0: .cpload $31\n" \
6036 +" .set reorder\n" \
6037 +" la $4, _DYNAMIC\n" \
6038 +" sw $4, -0x7ff0($28)\n" \
6039 +" move $4, $29\n" \
6041 +" .set noreorder\n" \
6042 +" bltzal $0, coff\n" \
6044 +"coff: subu $8, $31, $8\n" \
6045 +" .set reorder\n" \
6046 +" la $25, _dl_boot2\n" \
6047 +" addu $25, $8\n" \
6049 +" lw $4, 0($29)\n" \
6050 +" la $5, 4($29)\n" \
6051 +" sll $6, $4, 2\n" \
6052 +" addu $6, $6, $5\n" \
6053 +" addu $6, $6, 4\n" \
6054 +" la $7, _dl_elf_main\n" \
6055 +" lw $25, 0($7)\n" \
6059 +#define _dl_boot _dl_boot2
6060 +#define LD_BOOT(X) static void __attribute__ ((unused)) _dl_boot (X)
6061 diff -urN uClibc/ldso-0.9.24/ldso/mips/elfinterp.c uClibc.ldso.24/ldso-0.9.24/ldso/mips/elfinterp.c
6062 --- uClibc/ldso-0.9.24/ldso/mips/elfinterp.c 1969-12-31 18:00:00.000000000 -0600
6063 +++ uClibc.ldso.24/ldso-0.9.24/ldso/mips/elfinterp.c 2003-08-22 02:04:16.000000000 -0500
6065 +/* vi: set sw=4 ts=4: */
6066 +/* mips/mipsel ELF shared library loader suppport
6068 + Copyright (C) 2002, Steven J. Hill (sjhill@realitydiluted.com)
6070 + * All rights reserved.
6072 + * Redistribution and use in source and binary forms, with or without
6073 + * modification, are permitted provided that the following conditions
6075 + * 1. Redistributions of source code must retain the above copyright
6076 + * notice, this list of conditions and the following disclaimer.
6077 + * 2. The name of the above contributors may not be
6078 + * used to endorse or promote products derived from this software
6079 + * without specific prior written permission.
6081 + * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
6082 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
6083 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
6084 + * ARE DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE
6085 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
6086 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
6087 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
6088 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
6089 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
6090 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
6094 +#if defined (__SUPPORT_LD_DEBUG__)
6095 +static const char *_dl_reltypes_tab[] =
6097 + [0] "R_MIPS_NONE", "R_MIPS_16", "R_MIPS_32",
6098 + [3] "R_MIPS_REL32", "R_MIPS_26", "R_MIPS_HI16",
6099 + [6] "R_MIPS_LO16", "R_MIPS_GPREL16", "R_MIPS_LITERAL",
6100 + [9] "R_MIPS_GOT16", "R_MIPS_PC16", "R_MIPS_CALL16",
6101 + [12] "R_MIPS_GPREL32",
6102 + [16] "R_MIPS_SHIFT5", "R_MIPS_SHIFT6", "R_MIPS_64",
6103 + [19] "R_MIPS_GOT_DISP", "R_MIPS_GOT_PAGE", "R_MIPS_GOT_OFST",
6104 + [22] "R_MIPS_GOT_HI16", "R_MIPS_GOT_LO16", "R_MIPS_SUB",
6105 + [25] "R_MIPS_INSERT_A", "R_MIPS_INSERT_B", "R_MIPS_DELETE",
6106 + [28] "R_MIPS_HIGHER", "R_MIPS_HIGHEST", "R_MIPS_CALL_HI16",
6107 + [31] "R_MIPS_CALL_LO16", "R_MIPS_SCN_DISP", "R_MIPS_REL16",
6108 + [34] "R_MIPS_ADD_IMMEDIATE", "R_MIPS_PJUMP", "R_MIPS_RELGOT",
6109 + [37] "R_MIPS_JALR",
6112 +static const char *
6113 +_dl_reltypes(int type)
6115 + static char buf[22];
6118 + if (type >= (int)(sizeof (_dl_reltypes_tab)/sizeof(_dl_reltypes_tab[0])) ||
6119 + NULL == (str = _dl_reltypes_tab[type]))
6121 + str =_dl_simple_ltoa( buf, (unsigned long)(type));
6127 +void debug_sym(Elf32_Sym *symtab,char *strtab,int symtab_index)
6129 + if(_dl_debug_symbols)
6132 + _dl_dprintf(_dl_debug_file, "\n%s\n\tvalue=%x\tsize=%x\tinfo=%x\tother=%x\tshndx=%x",
6133 + strtab + symtab[symtab_index].st_name,
6134 + symtab[symtab_index].st_value,
6135 + symtab[symtab_index].st_size,
6136 + symtab[symtab_index].st_info,
6137 + symtab[symtab_index].st_other,
6138 + symtab[symtab_index].st_shndx);
6143 +static void debug_reloc(Elf32_Sym *symtab,char *strtab, ELF_RELOC *rpnt)
6145 + if(_dl_debug_reloc)
6149 + symtab_index = ELF32_R_SYM(rpnt->r_info);
6150 + sym = symtab_index ? strtab + symtab[symtab_index].st_name : "sym=0x0";
6152 + if(_dl_debug_symbols)
6153 + _dl_dprintf(_dl_debug_file, "\n\t");
6155 + _dl_dprintf(_dl_debug_file, "\n%s\n\t", sym);
6156 +#ifdef ELF_USES_RELOCA
6157 + _dl_dprintf(_dl_debug_file, "%s\toffset=%x\taddend=%x",
6158 + _dl_reltypes(ELF32_R_TYPE(rpnt->r_info)),
6162 + _dl_dprintf(_dl_debug_file, "%s\toffset=%x\n",
6163 + _dl_reltypes(ELF32_R_TYPE(rpnt->r_info)),
6170 +extern int _dl_linux_resolve(void);
6172 +#define OFFSET_GP_GOT 0x7ff0
6174 +unsigned long _dl_linux_resolver(unsigned long sym_index,
6175 + unsigned long old_gpreg)
6177 + unsigned long *got = (unsigned long *) (old_gpreg - OFFSET_GP_GOT);
6178 + struct elf_resolve *tpnt = (struct elf_resolve *) got[1];
6181 + unsigned long local_gotno;
6182 + unsigned long gotsym;
6183 + unsigned long new_addr;
6184 + unsigned long instr_addr;
6188 + gotsym = tpnt->mips_gotsym;
6189 + local_gotno = tpnt->mips_local_gotno;
6191 + sym = ((Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr)) + sym_index;
6192 + strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
6193 + symname = strtab + sym->st_name;
6195 + new_addr = (unsigned long) _dl_find_hash(strtab + sym->st_name,
6196 + tpnt->symbol_scope, tpnt, resolver);
6198 + /* Address of jump instruction to fix up */
6199 + instr_addr = (unsigned long) (got + local_gotno + sym_index - gotsym);
6200 + got_addr = (char **) instr_addr;
6202 +#if defined (__SUPPORT_LD_DEBUG__)
6203 + if (_dl_debug_bindings)
6205 + _dl_dprintf(_dl_debug_file, "\nresolve function: %s", symname);
6206 + if(_dl_debug_detail) _dl_dprintf(_dl_debug_file,
6207 + "\n\tpatched %x ==> %x @ %x\n", *got_addr, new_addr, got_addr);
6209 + if (!_dl_debug_nofixups) {
6210 + *got_addr = (char*)new_addr;
6213 + *got_addr = (char*)new_addr;
6219 +void _dl_parse_lazy_relocation_information(struct elf_resolve *tpnt,
6220 + unsigned long rel_addr, unsigned long rel_size, int type)
6222 + /* Nothing to do */
6226 +int _dl_parse_copy_information(struct dyn_elf *xpnt, unsigned long rel_addr,
6227 + unsigned long rel_size, int type)
6229 + /* Nothing to do */
6234 +int _dl_parse_relocation_information(struct elf_resolve *tpnt,
6235 + unsigned long rel_addr, unsigned long rel_size, int type)
6237 + Elf32_Sym *symtab;
6240 + unsigned long *got;
6241 + unsigned long *reloc_addr=NULL, old_val=0;
6242 + unsigned long symbol_addr;
6243 + int i, reloc_type, symtab_index;
6245 + /* Now parse the relocation information */
6246 + rel_size = rel_size / sizeof(Elf32_Rel);
6247 + rpnt = (Elf32_Rel *) (rel_addr + tpnt->loadaddr);
6249 + symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
6250 + strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
6251 + got = (unsigned long *) (tpnt->dynamic_info[DT_PLTGOT] + tpnt->loadaddr);
6253 + for (i = 0; i < rel_size; i++, rpnt++) {
6254 + reloc_addr = (unsigned long *) (tpnt->loadaddr +
6255 + (unsigned long) rpnt->r_offset);
6256 + reloc_type = ELF32_R_TYPE(rpnt->r_info);
6257 + symtab_index = ELF32_R_SYM(rpnt->r_info);
6260 + if (!symtab_index && tpnt->libtype == program_interpreter)
6263 +#if defined (__SUPPORT_LD_DEBUG__)
6264 + debug_sym(symtab,strtab,symtab_index);
6265 + debug_reloc(symtab,strtab,rpnt);
6266 + old_val = *reloc_addr;
6269 + switch (reloc_type) {
6270 + case R_MIPS_REL32:
6271 + if (symtab_index) {
6272 + if (symtab_index < tpnt->mips_gotsym)
6274 + symtab[symtab_index].st_value +
6275 + (unsigned long) tpnt->loadaddr;
6277 + *reloc_addr += got[symtab_index + tpnt->mips_local_gotno -
6278 + tpnt->mips_gotsym];
6282 + *reloc_addr += (unsigned long) tpnt->loadaddr;
6289 + int reloc_type = ELF32_R_TYPE(rpnt->r_info);
6290 + _dl_dprintf(2, "\n%s: ",_dl_progname);
6293 + _dl_dprintf(2, "symbol '%s': ", strtab + symtab[symtab_index].st_name);
6295 +#if defined (__SUPPORT_LD_DEBUG__)
6296 + _dl_dprintf(2, "can't handle reloc type %s\n ", _dl_reltypes(reloc_type));
6298 + _dl_dprintf(2, "can't handle reloc type %x\n", reloc_type);
6305 +#if defined (__SUPPORT_LD_DEBUG__)
6306 + if(_dl_debug_reloc && _dl_debug_detail)
6307 + _dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x\n", old_val, *reloc_addr, reloc_addr);
6313 +void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt)
6318 + unsigned long *got_entry;
6320 + for (; tpnt ; tpnt = tpnt->next) {
6322 + /* We don't touch the dynamic linker */
6323 + if (tpnt->libtype == program_interpreter)
6326 + /* Setup the loop variables */
6327 + got_entry = (unsigned long *) (tpnt->loadaddr +
6328 + tpnt->dynamic_info[DT_PLTGOT]) + tpnt->mips_local_gotno;
6329 + sym = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] +
6330 + (unsigned long) tpnt->loadaddr) + tpnt->mips_gotsym;
6331 + strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] +
6332 + (unsigned long) tpnt->loadaddr);
6333 + i = tpnt->mips_symtabno - tpnt->mips_gotsym;
6335 + /* Relocate the global GOT entries for the object */
6337 + if (sym->st_shndx == SHN_UNDEF) {
6338 + if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC && sym->st_value)
6339 + *got_entry = sym->st_value + (unsigned long) tpnt->loadaddr;
6341 + *got_entry = (unsigned long) _dl_find_hash(strtab +
6342 + sym->st_name, tpnt->symbol_scope, NULL, copyrel);
6345 + else if (sym->st_shndx == SHN_COMMON) {
6346 + *got_entry = (unsigned long) _dl_find_hash(strtab +
6347 + sym->st_name, tpnt->symbol_scope, NULL, copyrel);
6349 + else if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC &&
6350 + *got_entry != sym->st_value)
6351 + *got_entry += (unsigned long) tpnt->loadaddr;
6352 + else if (ELF32_ST_TYPE(sym->st_info) == STT_SECTION) {
6353 + if (sym->st_other == 0)
6354 + *got_entry += (unsigned long) tpnt->loadaddr;
6357 + *got_entry = (unsigned long) _dl_find_hash(strtab +
6358 + sym->st_name, tpnt->symbol_scope, NULL, copyrel);
6366 diff -urN uClibc/ldso-0.9.24/ldso/mips/ld_syscalls.h uClibc.ldso.24/ldso-0.9.24/ldso/mips/ld_syscalls.h
6367 --- uClibc/ldso-0.9.24/ldso/mips/ld_syscalls.h 1969-12-31 18:00:00.000000000 -0600
6368 +++ uClibc.ldso.24/ldso-0.9.24/ldso/mips/ld_syscalls.h 2002-08-09 07:20:20.000000000 -0500
6370 +/* Define the __set_errno macro as nothing so that we don't bother
6371 + * setting errno, which is important since we make system calls
6372 + * before the errno symbol is dynamicly linked. */
6374 +#define __set_errno(X) {(void)(X);}
6375 +#include "sys/syscall.h"
6377 diff -urN uClibc/ldso-0.9.24/ldso/mips/ld_sysdep.h uClibc.ldso.24/ldso-0.9.24/ldso/mips/ld_sysdep.h
6378 --- uClibc/ldso-0.9.24/ldso/mips/ld_sysdep.h 1969-12-31 18:00:00.000000000 -0600
6379 +++ uClibc.ldso.24/ldso-0.9.24/ldso/mips/ld_sysdep.h 2002-05-28 16:33:36.000000000 -0500
6381 +/* vi: set sw=4 ts=4: */
6384 + * Various assmbly language/system dependent hacks that are required
6385 + * so that we can minimize the amount of platform specific code.
6389 + * Define this if the system uses RELOCA.
6391 +#undef ELF_USES_RELOCA
6395 + * Get a pointer to the argv array. On many platforms this can be just
6396 + * the address if the first argument, on other platforms we need to
6397 + * do something a little more subtle here.
6399 +#define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned long *) ARGS)
6403 + * Initialization sequence for the application/library GOT.
6405 +#define INIT_GOT(GOT_BASE,MODULE) \
6407 + unsigned long i; \
6409 + /* Check if this is the dynamic linker itself */ \
6410 + if (MODULE->libtype == program_interpreter) \
6413 + /* Fill in first two GOT entries according to the ABI */ \
6414 + GOT_BASE[0] = (unsigned long) _dl_linux_resolve; \
6415 + GOT_BASE[1] = (unsigned long) MODULE; \
6417 + /* Add load address displacement to all local GOT entries */ \
6419 + while (i < MODULE->mips_local_gotno) \
6420 + GOT_BASE[i++] += (unsigned long) MODULE->loadaddr; \
6426 + * Here is a macro to perform the GOT relocation. This is only
6427 + * used when bootstrapping the dynamic loader.
6429 +#define PERFORM_BOOTSTRAP_GOT(got) \
6432 + unsigned long i; \
6434 + /* Add load address displacement to all local GOT entries */ \
6436 + while (i < tpnt->mips_local_gotno) \
6437 + got[i++] += load_addr; \
6439 + /* Handle global GOT entries */ \
6440 + got += tpnt->mips_local_gotno; \
6441 + sym = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + \
6442 + load_addr) + tpnt->mips_gotsym; \
6443 + i = tpnt->mips_symtabno - tpnt->mips_gotsym; \
6446 + if (sym->st_shndx == SHN_UNDEF || \
6447 + sym->st_shndx == SHN_COMMON) \
6448 + *got = load_addr + sym->st_value; \
6449 + else if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC && \
6450 + *got != sym->st_value) \
6451 + *got += load_addr; \
6452 + else if (ELF32_ST_TYPE(sym->st_info) == STT_SECTION) { \
6453 + if (sym->st_other == 0) \
6454 + *got += load_addr; \
6457 + *got = load_addr + sym->st_value; \
6466 + * Here is a macro to perform a relocation. This is only used when
6467 + * bootstrapping the dynamic loader.
6469 +#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD) \
6470 + switch(ELF32_R_TYPE((RELP)->r_info)) { \
6471 + case R_MIPS_REL32: \
6472 + if (symtab_index) { \
6473 + if (symtab_index < tpnt->mips_gotsym) \
6480 + case R_MIPS_NONE: \
6483 + SEND_STDERR("Aiieeee!"); \
6489 + * Transfer control to the user's application, once the dynamic loader
6490 + * is done. This routine has to exit the current function, then
6491 + * call the _dl_elf_main function. For MIPS, we do it in assembly
6492 + * because the stack doesn't get properly restored otherwise. Got look
6498 +/* Here we define the magic numbers that this dynamic loader should accept */
6499 +#define MAGIC1 EM_MIPS
6500 +#define MAGIC2 EM_MIPS_RS3_LE
6503 +/* Used for error messages */
6504 +#define ELF_TARGET "MIPS"
6507 +unsigned long _dl_linux_resolver(unsigned long sym_index,
6508 + unsigned long old_gpreg);
6511 +#define do_rem(result, n, base) result = (n % base)
6513 +/* 4096 bytes alignment */
6514 +#define PAGE_ALIGN 0xfffff000
6515 +#define ADDR_ALIGN 0xfff
6516 +#define OFFS_ALIGN 0x7ffff000
6517 diff -urN uClibc/ldso-0.9.24/ldso/mips/resolve.S uClibc.ldso.24/ldso-0.9.24/ldso/mips/resolve.S
6518 --- uClibc/ldso-0.9.24/ldso/mips/resolve.S 1969-12-31 18:00:00.000000000 -0600
6519 +++ uClibc.ldso.24/ldso-0.9.24/ldso/mips/resolve.S 2003-01-30 10:40:26.000000000 -0600
6522 + * Linux dynamic resolving code for MIPS. Fixes up the GOT entry as
6523 + * indicated in register t8 and jumps to the resolved address. Shamelessly
6524 + * ripped from 'sysdeps/mips/dl-machine.h' in glibc-2.2.5.
6526 + * This file is subject to the terms and conditions of the GNU Lesser General
6527 + * Public License. See the file "COPYING.LIB" in the main directory of this
6528 + * archive for more details.
6530 + * Copyright (C) 1996-2001 Kazumoto Kojima <kkojima@info.kanagawa-u.ac.jp>
6531 + * Copyright (C) 2002 Steven J. Hill <sjhill@realitydiluted.com>
6536 +.globl _dl_linux_resolve
6537 +.type _dl_linux_resolve,@function
6538 +.ent _dl_linux_resolve
6540 + .frame $29, 40, $31
6542 + move $3, $28 # Save GP
6543 + addu $25, 8 # t9 ($25) now points at .cpload instruction
6544 + .cpload $25 # Compute GP
6555 + jal _dl_linux_resolver
6564 +.size _dl_linux_resolve,.-_dl_linux_resolve
6565 +.end _dl_linux_resolve
6566 diff -urN uClibc/ldso-0.9.24/ldso/powerpc/boot1_arch.h uClibc.ldso.24/ldso-0.9.24/ldso/powerpc/boot1_arch.h
6567 --- uClibc/ldso-0.9.24/ldso/powerpc/boot1_arch.h 1969-12-31 18:00:00.000000000 -0600
6568 +++ uClibc.ldso.24/ldso-0.9.24/ldso/powerpc/boot1_arch.h 2003-02-15 19:22:41.000000000 -0600
6570 +/* Any assmbly language/system dependent hacks needed to setup boot1.c so it
6571 + * will work as expected and cope with whatever platform specific wierdness is
6572 + * needed for this architecture. */
6574 +/* Overrive the default _dl_boot function, and replace it with a bit of asm.
6575 + * Then call the real _dl_boot function, which is now named _dl_boot2. */
6579 +" .globl _dl_boot\n" \
6582 +" addi 1,1,-16\n" \
6583 +" bl _dl_boot2\n" \
6587 +#define _dl_boot _dl_boot2
6588 +#define LD_BOOT(X) static void * __attribute__ ((unused)) _dl_boot (X)
6590 diff -urN uClibc/ldso-0.9.24/ldso/powerpc/elfinterp.c uClibc.ldso.24/ldso-0.9.24/ldso/powerpc/elfinterp.c
6591 --- uClibc/ldso-0.9.24/ldso/powerpc/elfinterp.c 1969-12-31 18:00:00.000000000 -0600
6592 +++ uClibc.ldso.24/ldso-0.9.24/ldso/powerpc/elfinterp.c 2003-12-03 17:28:33.000000000 -0600
6594 +/* vi: set sw=4 ts=4: */
6595 +/* powerpc shared library loader suppport
6597 + * Copyright (C) 2001-2002, David A. Schleef
6598 + * Copyright (C) 2003, Erik Andersen
6600 + * All rights reserved.
6602 + * Redistribution and use in source and binary forms, with or without
6603 + * modification, are permitted provided that the following conditions
6605 + * 1. Redistributions of source code must retain the above copyright
6606 + * notice, this list of conditions and the following disclaimer.
6607 + * 2. The name of the above contributors may not be
6608 + * used to endorse or promote products derived from this software
6609 + * without specific prior written permission.
6611 + * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
6612 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
6613 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
6614 + * ARE DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE
6615 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
6616 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
6617 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
6618 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
6619 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
6620 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
6624 +#if defined (__SUPPORT_LD_DEBUG__)
6625 +static const char *_dl_reltypes_tab[] =
6626 + { "R_PPC_NONE", "R_PPC_ADDR32", "R_PPC_ADDR24", "R_PPC_ADDR16",
6627 + "R_PPC_ADDR16_LO", "R_PPC_ADDR16_HI", "R_PPC_ADDR16_HA",
6628 + "R_PPC_ADDR14", "R_PPC_ADDR14_BRTAKEN", "R_PPC_ADDR14_BRNTAKEN",
6629 + "R_PPC_REL24", "R_PPC_REL14", "R_PPC_REL14_BRTAKEN",
6630 + "R_PPC_REL14_BRNTAKEN", "R_PPC_GOT16", "R_PPC_GOT16_LO",
6631 + "R_PPC_GOT16_HI", "R_PPC_GOT16_HA", "R_PPC_PLTREL24",
6632 + "R_PPC_COPY", "R_PPC_GLOB_DAT", "R_PPC_JMP_SLOT", "R_PPC_RELATIVE",
6633 + "R_PPC_LOCAL24PC", "R_PPC_UADDR32", "R_PPC_UADDR16", "R_PPC_REL32",
6634 + "R_PPC_PLT32", "R_PPC_PLTREL32", "R_PPC_PLT16_LO", "R_PPC_PLT16_HI",
6635 + "R_PPC_PLT16_HA", "R_PPC_SDAREL16", "R_PPC_SECTOFF",
6636 + "R_PPC_SECTOFF_LO", "R_PPC_SECTOFF_HI", "R_PPC_SECTOFF_HA",
6639 +static const char *
6640 +_dl_reltypes(int type)
6642 + static char buf[22];
6645 + if (type >= (int)(sizeof (_dl_reltypes_tab)/sizeof(_dl_reltypes_tab[0])) ||
6646 + NULL == (str = _dl_reltypes_tab[type]))
6648 + str =_dl_simple_ltoa( buf, (unsigned long)(type));
6654 +void debug_sym(Elf32_Sym *symtab,char *strtab,int symtab_index)
6656 + if(_dl_debug_symbols)
6659 + _dl_dprintf(_dl_debug_file, "\n%s\n\tvalue=%x\tsize=%x\tinfo=%x\tother=%x\tshndx=%x",
6660 + strtab + symtab[symtab_index].st_name,
6661 + symtab[symtab_index].st_value,
6662 + symtab[symtab_index].st_size,
6663 + symtab[symtab_index].st_info,
6664 + symtab[symtab_index].st_other,
6665 + symtab[symtab_index].st_shndx);
6671 +void debug_reloc(Elf32_Sym *symtab,char *strtab, ELF_RELOC *rpnt)
6673 + if(_dl_debug_reloc)
6677 + symtab_index = ELF32_R_SYM(rpnt->r_info);
6678 + sym = symtab_index ? strtab + symtab[symtab_index].st_name : "sym=0x0";
6680 + if(_dl_debug_symbols)
6681 + _dl_dprintf(_dl_debug_file, "\n\t");
6683 + _dl_dprintf(_dl_debug_file, "\n%s\n\t", sym);
6684 +#ifdef ELF_USES_RELOCA
6685 + _dl_dprintf(_dl_debug_file, "%s\toffset=%x\taddend=%x",
6686 + _dl_reltypes(ELF32_R_TYPE(rpnt->r_info)),
6690 + _dl_dprintf(_dl_debug_file, "%s\toffset=%x\n",
6691 + _dl_reltypes(ELF32_R_TYPE(rpnt->r_info)),
6698 +extern int _dl_linux_resolve(void);
6700 +void _dl_init_got(unsigned long *plt,struct elf_resolve *tpnt)
6702 + unsigned long target_addr = (unsigned long)_dl_linux_resolve;
6703 + unsigned int n_plt_entries;
6704 + unsigned long *tramp;
6705 + unsigned long data_words;
6706 + unsigned int rel_offset_words;
6708 + //DPRINTF("init_got plt=%x, tpnt=%x\n", (unsigned long)plt,(unsigned long)tpnt);
6710 + n_plt_entries = tpnt->dynamic_info[DT_PLTRELSZ] / sizeof(ELF_RELOC);
6711 + //DPRINTF("n_plt_entries %d\n",n_plt_entries);
6713 + rel_offset_words = PLT_DATA_START_WORDS(n_plt_entries);
6714 + //DPRINTF("rel_offset_words %x\n",rel_offset_words);
6715 + data_words = (unsigned long)(plt + rel_offset_words);
6716 + //DPRINTF("data_words %x\n",data_words);
6718 + tpnt->data_words = data_words;
6720 + plt[PLT_LONGBRANCH_ENTRY_WORDS] = OPCODE_ADDIS_HI(11, 11, data_words);
6721 + plt[PLT_LONGBRANCH_ENTRY_WORDS+1] = OPCODE_LWZ(11,data_words,11);
6723 + plt[PLT_LONGBRANCH_ENTRY_WORDS+2] = OPCODE_MTCTR(11);
6724 + plt[PLT_LONGBRANCH_ENTRY_WORDS+3] = OPCODE_BCTR();
6729 + tramp = plt + PLT_TRAMPOLINE_ENTRY_WORDS;
6730 + tramp[0] = OPCODE_ADDIS_HI(11,11,-data_words);
6731 + tramp[1] = OPCODE_ADDI(11,11,-data_words);
6732 + tramp[2] = OPCODE_SLWI(12,11,1);
6733 + tramp[3] = OPCODE_ADD(11,12,11);
6734 + tramp[4] = OPCODE_LI(12,target_addr);
6735 + tramp[5] = OPCODE_ADDIS_HI(12,12,target_addr);
6736 + tramp[6] = OPCODE_MTCTR(12);
6737 + tramp[7] = OPCODE_LI(12,(unsigned long)tpnt);
6738 + tramp[8] = OPCODE_ADDIS_HI(12,12,(unsigned long)tpnt);
6739 + tramp[9] = OPCODE_BCTR();
6744 + /* instructions were modified */
6748 + PPC_DCBST(plt+12);
6749 + PPC_DCBST(plt+16-1);
6752 + PPC_ICBI(plt+4); /* glibc thinks this is not needed */
6753 + PPC_ICBI(plt+8); /* glibc thinks this is not needed */
6754 + PPC_ICBI(plt+12); /* glibc thinks this is not needed */
6755 + PPC_ICBI(plt+16-1);
6759 +unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
6762 + ELF_RELOC *this_reloc;
6764 + Elf32_Sym *symtab;
6765 + ELF_RELOC *rel_addr;
6768 + unsigned long insn_addr;
6769 + unsigned long *insns;
6770 + unsigned long new_addr;
6771 + unsigned long delta;
6773 + rel_addr = (ELF_RELOC *) (tpnt->dynamic_info[DT_JMPREL] + tpnt->loadaddr);
6775 + this_reloc = (void *)rel_addr + reloc_entry;
6776 + reloc_type = ELF32_R_TYPE(this_reloc->r_info);
6777 + symtab_index = ELF32_R_SYM(this_reloc->r_info);
6779 + symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
6780 + strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
6781 + symname = strtab + symtab[symtab_index].st_name;
6783 +#if defined (__SUPPORT_LD_DEBUG__)
6784 + debug_sym(symtab,strtab,symtab_index);
6785 + debug_reloc(symtab,strtab,this_reloc);
6788 + if (reloc_type != R_PPC_JMP_SLOT) {
6789 + _dl_dprintf(2, "%s: Incorrect relocation type in jump relocation\n", _dl_progname);
6793 + /* Address of dump instruction to fix up */
6794 + insn_addr = (unsigned long) tpnt->loadaddr +
6795 + (unsigned long) this_reloc->r_offset;
6797 +#if defined (__SUPPORT_LD_DEBUG__)
6798 + if(_dl_debug_reloc && _dl_debug_detail)
6799 + _dl_dprintf(_dl_debug_file, "\n\tResolving symbol %s %x --> ", symname, insn_addr);
6802 + /* Get the address of the GOT entry */
6803 + new_addr = (unsigned long) _dl_find_hash(
6804 + strtab + symtab[symtab_index].st_name,
6805 + tpnt->symbol_scope, tpnt, resolver);
6807 + _dl_dprintf(2, "%s: can't resolve symbol '%s'\n",
6808 + _dl_progname, symname);
6812 +#if defined (__SUPPORT_LD_DEBUG__)
6813 + if(_dl_debug_reloc && _dl_debug_detail)
6814 + _dl_dprintf(_dl_debug_file, "%x\n", new_addr);
6817 + insns = (unsigned long *)insn_addr;
6818 + delta = new_addr - insn_addr;
6820 + if(delta<<6>>6 == delta){
6821 + insns[0] = OPCODE_B(delta);
6822 + }else if (new_addr <= 0x01fffffc || new_addr >= 0xfe000000){
6823 + insns[0] = OPCODE_BA (new_addr);
6825 + /* Warning: we don't handle double-sized PLT entries */
6826 + unsigned long plt_addr;
6827 + unsigned long *ptr;
6830 + plt_addr = (unsigned long)tpnt->dynamic_info[DT_PLTGOT] +
6831 + (unsigned long)tpnt->loadaddr;
6833 + delta = PLT_LONGBRANCH_ENTRY_WORDS*4 - (insn_addr-plt_addr+4);
6835 + index = (insn_addr - plt_addr - PLT_INITIAL_ENTRY_WORDS*4)/8;
6837 + ptr = (unsigned long *)tpnt->data_words;
6838 + //DPRINTF("plt_addr=%x delta=%x index=%x ptr=%x\n", plt_addr, delta, index, ptr);
6841 + ptr[index] = new_addr;
6843 + /* icache sync is not necessary, since this will be a data load */
6844 + //PPC_DCBST(ptr+index);
6846 + //PPC_ICBI(ptr+index);
6849 + insns[0] = OPCODE_B(delta);
6853 + /* instructions were modified */
6863 +_dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope,
6864 + unsigned long rel_addr, unsigned long rel_size,
6865 + int (*reloc_fnc) (struct elf_resolve *tpnt, struct dyn_elf *scope,
6866 + ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab))
6870 + Elf32_Sym *symtab;
6874 + /* Now parse the relocation information */
6875 + rpnt = (ELF_RELOC *)(intptr_t) (rel_addr + tpnt->loadaddr);
6876 + rel_size = rel_size / sizeof(ELF_RELOC);
6878 + symtab = (Elf32_Sym *)(intptr_t) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
6879 + strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
6881 + for (i = 0; i < rel_size; i++, rpnt++) {
6884 + symtab_index = ELF32_R_SYM(rpnt->r_info);
6886 + /* When the dynamic linker bootstrapped itself, it resolved some symbols.
6887 + Make sure we do not do them again */
6888 + if (!symtab_index && tpnt->libtype == program_interpreter)
6890 + if (symtab_index && tpnt->libtype == program_interpreter &&
6891 + _dl_symbol(strtab + symtab[symtab_index].st_name))
6894 +#if defined (__SUPPORT_LD_DEBUG__)
6895 + debug_sym(symtab,strtab,symtab_index);
6896 + debug_reloc(symtab,strtab,rpnt);
6899 + res = reloc_fnc (tpnt, scope, rpnt, symtab, strtab);
6901 + if (res==0) continue;
6903 + _dl_dprintf(2, "\n%s: ",_dl_progname);
6906 + _dl_dprintf(2, "symbol '%s': ", strtab + symtab[symtab_index].st_name);
6910 + int reloc_type = ELF32_R_TYPE(rpnt->r_info);
6911 +#if defined (__SUPPORT_LD_DEBUG__)
6912 + _dl_dprintf(2, "can't handle reloc type %s\n ", _dl_reltypes(reloc_type));
6914 + _dl_dprintf(2, "can't handle reloc type %x\n", reloc_type);
6920 + _dl_dprintf(2, "can't resolve symbol\n");
6928 +_dl_do_lazy_reloc (struct elf_resolve *tpnt, struct dyn_elf *scope,
6929 + ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)
6932 + unsigned long reloc_addr;
6933 +#if defined (__SUPPORT_LD_DEBUG__)
6934 + unsigned long old_val;
6940 + reloc_addr = (unsigned long)tpnt->loadaddr + (unsigned long) rpnt->r_offset;
6941 + reloc_type = ELF32_R_TYPE(rpnt->r_info);
6943 +#if defined (__SUPPORT_LD_DEBUG__)
6944 + old_val = reloc_addr;
6947 + switch (reloc_type) {
6951 + case R_PPC_JMP_SLOT:
6954 + unsigned long delta;
6955 + unsigned long *plt;
6956 + unsigned long *insns;
6958 + plt = (unsigned long *)(tpnt->dynamic_info[DT_PLTGOT] + tpnt->loadaddr);
6960 + delta = (unsigned long)(plt+PLT_TRAMPOLINE_ENTRY_WORDS+2) - (reloc_addr+4);
6962 + index = (reloc_addr - (unsigned long)(plt+PLT_INITIAL_ENTRY_WORDS))
6963 + /sizeof(unsigned long);
6965 + //DPRINTF(" index %x delta %x\n",index,delta);
6966 + insns = (unsigned long *)reloc_addr;
6967 + insns[0] = OPCODE_LI(11,index*4);
6968 + insns[1] = OPCODE_B(delta);
6973 + _dl_dprintf(2, "%s: (LAZY) can't handle reloc type ",
6975 +#if defined (__SUPPORT_LD_DEBUG__)
6976 + _dl_dprintf(2, "%s ", _dl_reltypes[reloc_type]);
6979 + _dl_dprintf(2, "'%s'\n", strtab + symtab[symtab_index].st_name);
6985 + /* instructions were modified */
6986 + PPC_DCBST(reloc_addr);
6987 + PPC_DCBST(reloc_addr+4);
6989 + PPC_ICBI(reloc_addr);
6990 + PPC_ICBI(reloc_addr+4);
6993 +#if defined (__SUPPORT_LD_DEBUG__)
6994 + if(_dl_debug_reloc && _dl_debug_detail)
6995 + _dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x", old_val, reloc_addr);
7002 +_dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope,
7003 + ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)
7008 + unsigned long *reloc_addr;
7009 + unsigned long symbol_addr;
7010 +#if defined (__SUPPORT_LD_DEBUG__)
7011 + unsigned long old_val;
7014 + reloc_addr = (unsigned long *)(intptr_t) (tpnt->loadaddr + (unsigned long) rpnt->r_offset);
7015 + reloc_type = ELF32_R_TYPE(rpnt->r_info);
7016 + symtab_index = ELF32_R_SYM(rpnt->r_info);
7018 + symname = strtab + symtab[symtab_index].st_name;
7020 + if (symtab_index) {
7022 + symbol_addr = (unsigned long) _dl_find_hash(symname, scope,
7023 + (reloc_type == R_PPC_JMP_SLOT ? tpnt : NULL), symbolrel);
7026 + * We want to allow undefined references to weak symbols - this might
7027 + * have been intentional. We should not be linking local symbols
7028 + * here, so all bases should be covered.
7031 + if (!symbol_addr && ELF32_ST_BIND(symtab[symtab_index].st_info) == STB_GLOBAL) {
7032 +#if defined (__SUPPORT_LD_DEBUG__)
7033 + _dl_dprintf(2, "\tglobal symbol '%s' already defined in '%s'\n",
7034 + symname, tpnt->libname);
7040 +#if defined (__SUPPORT_LD_DEBUG__)
7041 + old_val = *reloc_addr;
7043 + switch (reloc_type) {
7050 + unsigned long delta = symbol_addr - (unsigned long)reloc_addr;
7051 + if(delta<<6>>6 != delta){
7052 + _dl_dprintf(2,"R_PPC_REL24: Reloc out of range\n");
7055 + *reloc_addr &= 0xfc000003;
7056 + *reloc_addr |= delta&0x03fffffc;
7060 + _dl_dprintf(2, "%s: symbol '%s' is type R_PPC_REL24\n\tCompile shared libraries with -fPIC!\n",
7061 + _dl_progname, symname);
7064 + case R_PPC_RELATIVE:
7065 + *reloc_addr = (unsigned long)tpnt->loadaddr + (unsigned long)rpnt->r_addend;
7067 + case R_PPC_ADDR32:
7068 + *reloc_addr += symbol_addr;
7070 + case R_PPC_ADDR16_HA:
7071 + /* XXX is this correct? */
7072 + *(short *)reloc_addr += (symbol_addr+0x8000)>>16;
7074 + case R_PPC_ADDR16_HI:
7075 + *(short *)reloc_addr += symbol_addr>>16;
7077 + case R_PPC_ADDR16_LO:
7078 + *(short *)reloc_addr += symbol_addr;
7080 + case R_PPC_JMP_SLOT:
7082 + unsigned long targ_addr = (unsigned long)*reloc_addr;
7083 + unsigned long delta = targ_addr - (unsigned long)reloc_addr;
7084 + if(delta<<6>>6 == delta){
7085 + *reloc_addr = OPCODE_B(delta);
7086 + }else if (targ_addr <= 0x01fffffc || targ_addr >= 0xfe000000){
7087 + *reloc_addr = OPCODE_BA (targ_addr);
7091 + unsigned long delta2;
7092 + unsigned long *plt, *ptr;
7093 + plt = (unsigned long *)(tpnt->dynamic_info[DT_PLTGOT] + tpnt->loadaddr);
7095 + delta2 = (unsigned long)(plt+PLT_LONGBRANCH_ENTRY_WORDS)
7096 + - (unsigned long)(reloc_addr+1);
7098 + index = ((unsigned long)reloc_addr -
7099 + (unsigned long)(plt+PLT_INITIAL_ENTRY_WORDS))
7100 + /sizeof(unsigned long);
7102 + //DPRINTF(" index %x delta %x\n",index,delta2);
7103 + ptr = (unsigned long *)tpnt->data_words;
7104 + ptr[index] = targ_addr;
7105 + reloc_addr[0] = OPCODE_LI(11,index*4);
7106 + reloc_addr[1] = OPCODE_B(delta2);
7108 + /* instructions were modified */
7109 + PPC_DCBST(reloc_addr+1);
7111 + PPC_ICBI(reloc_addr+1);
7116 + case R_PPC_GLOB_DAT:
7117 + *reloc_addr += symbol_addr;
7125 + _dl_dprintf(2, "%s: can't handle reloc type ", _dl_progname);
7126 +#if defined (__SUPPORT_LD_DEBUG__)
7127 + _dl_dprintf(2, "%s ", _dl_reltypes[reloc_type]);
7130 + _dl_dprintf(2, "'%s'\n", strtab + symtab[symtab_index].st_name);
7136 + /* instructions were modified */
7137 + PPC_DCBST(reloc_addr);
7139 + PPC_ICBI(reloc_addr);
7142 +#if defined (__SUPPORT_LD_DEBUG__)
7143 + if(_dl_debug_reloc && _dl_debug_detail)
7144 + _dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x", old_val, *reloc_addr, reloc_addr);
7151 +/* This is done as a separate step, because there are cases where
7152 + information is first copied and later initialized. This results in
7153 + the wrong information being copied. Someone at Sun was complaining about
7154 + a bug in the handling of _COPY by SVr4, and this may in fact be what he
7155 + was talking about. Sigh. */
7157 +_dl_do_copy (struct elf_resolve *tpnt, struct dyn_elf *scope,
7158 + ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)
7162 + unsigned long *reloc_addr;
7163 + unsigned long symbol_addr;
7167 + reloc_addr = (unsigned long *)(intptr_t) (tpnt->loadaddr + (unsigned long) rpnt->r_offset);
7168 + reloc_type = ELF32_R_TYPE(rpnt->r_info);
7169 + if (reloc_type != R_PPC_COPY)
7171 + symtab_index = ELF32_R_SYM(rpnt->r_info);
7173 + symname = strtab + symtab[symtab_index].st_name;
7175 + if (symtab_index) {
7176 + symbol_addr = (unsigned long) _dl_find_hash(symname, scope, NULL, copyrel);
7177 + if (!symbol_addr) goof++;
7180 +#if defined (__SUPPORT_LD_DEBUG__)
7181 + if(_dl_debug_move)
7182 + _dl_dprintf(_dl_debug_file,"\n%s move %x bytes from %x to %x",
7183 + symname, symtab[symtab_index].st_size,
7184 + symbol_addr, symtab[symtab_index].st_value);
7186 + _dl_memcpy((char *) reloc_addr,
7187 + (char *) symbol_addr, symtab[symtab_index].st_size);
7193 +void _dl_parse_lazy_relocation_information(struct elf_resolve *tpnt,
7194 + unsigned long rel_addr, unsigned long rel_size, int type)
7197 + (void)_dl_parse(tpnt, NULL, rel_addr, rel_size, _dl_do_lazy_reloc);
7200 +int _dl_parse_relocation_information(struct elf_resolve *tpnt,
7201 + unsigned long rel_addr, unsigned long rel_size, int type)
7204 + return _dl_parse(tpnt, tpnt->symbol_scope, rel_addr, rel_size, _dl_do_reloc);
7207 +int _dl_parse_copy_information(struct dyn_elf *xpnt, unsigned long rel_addr,
7208 + unsigned long rel_size, int type)
7211 + return _dl_parse(xpnt->dyn, xpnt->next, rel_addr, rel_size, _dl_do_copy);
7215 diff -urN uClibc/ldso-0.9.24/ldso/powerpc/ld_syscalls.h uClibc.ldso.24/ldso-0.9.24/ldso/powerpc/ld_syscalls.h
7216 --- uClibc/ldso-0.9.24/ldso/powerpc/ld_syscalls.h 1969-12-31 18:00:00.000000000 -0600
7217 +++ uClibc.ldso.24/ldso-0.9.24/ldso/powerpc/ld_syscalls.h 2003-06-14 20:08:43.000000000 -0500
7220 + * This file contains the system call macros and syscall
7221 + * numbers used by the shared library loader.
7224 +#define __NR_exit 1
7225 +#define __NR_read 3
7226 +#define __NR_write 4
7227 +#define __NR_open 5
7228 +#define __NR_close 6
7229 +#define __NR_getpid 20
7230 +#define __NR_getuid 24
7231 +#define __NR_geteuid 49
7232 +#define __NR_getgid 47
7233 +#define __NR_getegid 50
7234 +#define __NR_readlink 85
7235 +#define __NR_mmap 90
7236 +#define __NR_munmap 91
7237 +#define __NR_stat 106
7238 +#define __NR_mprotect 125
7240 +/* Here are the macros which define how this platform makes
7241 + * system calls. This particular variant does _not_ set
7242 + * errno (note how it is disabled in __syscall_return) since
7243 + * these will get called before the errno symbol is dynamicly
7246 +#undef __syscall_return
7247 +#define __syscall_return(type) \
7248 + return (__sc_err & 0x10000000 ? /*errno = __sc_ret,*/ __sc_ret = -1 : 0), \
7251 +#undef __syscall_clobbers
7252 +#define __syscall_clobbers \
7253 + "r9", "r10", "r11", "r12"
7254 + //"r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"
7257 +#define _syscall0(type,name) \
7260 + unsigned long __sc_ret, __sc_err; \
7262 + register unsigned long __sc_0 __asm__ ("r0"); \
7263 + register unsigned long __sc_3 __asm__ ("r3"); \
7265 + __sc_0 = __NR_##name; \
7266 + __asm__ __volatile__ \
7269 + : "=&r" (__sc_3), "=&r" (__sc_0) \
7270 + : "0" (__sc_3), "1" (__sc_0) \
7271 + : "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12" ); \
7272 + __sc_ret = __sc_3; \
7273 + __sc_err = __sc_0; \
7275 + __syscall_return (type); \
7279 +#define _syscall1(type,name,type1,arg1) \
7280 +type name(type1 arg1) \
7282 + unsigned long __sc_ret, __sc_err; \
7284 + register unsigned long __sc_0 __asm__ ("r0"); \
7285 + register unsigned long __sc_3 __asm__ ("r3"); \
7287 + __sc_3 = (unsigned long) (arg1); \
7288 + __sc_0 = __NR_##name; \
7289 + __asm__ __volatile__ \
7292 + : "=&r" (__sc_3), "=&r" (__sc_0) \
7293 + : "0" (__sc_3), "1" (__sc_0) \
7294 + : "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12" ); \
7295 + __sc_ret = __sc_3; \
7296 + __sc_err = __sc_0; \
7298 + __syscall_return (type); \
7302 +#define _syscall2(type,name,type1,arg1,type2,arg2) \
7303 +type name(type1 arg1, type2 arg2) \
7305 + unsigned long __sc_ret, __sc_err; \
7307 + register unsigned long __sc_0 __asm__ ("r0"); \
7308 + register unsigned long __sc_3 __asm__ ("r3"); \
7309 + register unsigned long __sc_4 __asm__ ("r4"); \
7311 + __sc_3 = (unsigned long) (arg1); \
7312 + __sc_4 = (unsigned long) (arg2); \
7313 + __sc_0 = __NR_##name; \
7314 + __asm__ __volatile__ \
7317 + : "=&r" (__sc_3), "=&r" (__sc_0) \
7318 + : "0" (__sc_3), "1" (__sc_0), \
7320 + : "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12" ); \
7321 + __sc_ret = __sc_3; \
7322 + __sc_err = __sc_0; \
7324 + __syscall_return (type); \
7328 +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
7329 +type name(type1 arg1, type2 arg2, type3 arg3) \
7331 + unsigned long __sc_ret, __sc_err; \
7333 + register unsigned long __sc_0 __asm__ ("r0"); \
7334 + register unsigned long __sc_3 __asm__ ("r3"); \
7335 + register unsigned long __sc_4 __asm__ ("r4"); \
7336 + register unsigned long __sc_5 __asm__ ("r5"); \
7338 + __sc_3 = (unsigned long) (arg1); \
7339 + __sc_4 = (unsigned long) (arg2); \
7340 + __sc_5 = (unsigned long) (arg3); \
7341 + __sc_0 = __NR_##name; \
7342 + __asm__ __volatile__ \
7345 + : "=&r" (__sc_3), "=&r" (__sc_0) \
7346 + : "0" (__sc_3), "1" (__sc_0), \
7349 + : "r6", "r7", "r8", "r9", "r10", "r11", "r12" ); \
7350 + __sc_ret = __sc_3; \
7351 + __sc_err = __sc_0; \
7353 + __syscall_return (type); \
7357 +#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
7358 +type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
7360 + unsigned long __sc_ret, __sc_err; \
7362 + register unsigned long __sc_0 __asm__ ("r0"); \
7363 + register unsigned long __sc_3 __asm__ ("r3"); \
7364 + register unsigned long __sc_4 __asm__ ("r4"); \
7365 + register unsigned long __sc_5 __asm__ ("r5"); \
7366 + register unsigned long __sc_6 __asm__ ("r6"); \
7368 + __sc_3 = (unsigned long) (arg1); \
7369 + __sc_4 = (unsigned long) (arg2); \
7370 + __sc_5 = (unsigned long) (arg3); \
7371 + __sc_6 = (unsigned long) (arg4); \
7372 + __sc_0 = __NR_##name; \
7373 + __asm__ __volatile__ \
7376 + : "=&r" (__sc_3), "=&r" (__sc_0) \
7377 + : "0" (__sc_3), "1" (__sc_0), \
7381 + : "r7", "r8", "r9", "r10", "r11", "r12" ); \
7382 + __sc_ret = __sc_3; \
7383 + __sc_err = __sc_0; \
7385 + __syscall_return (type); \
7389 +#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
7390 +type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \
7392 + unsigned long __sc_ret, __sc_err; \
7394 + register unsigned long __sc_0 __asm__ ("r0"); \
7395 + register unsigned long __sc_3 __asm__ ("r3"); \
7396 + register unsigned long __sc_4 __asm__ ("r4"); \
7397 + register unsigned long __sc_5 __asm__ ("r5"); \
7398 + register unsigned long __sc_6 __asm__ ("r6"); \
7399 + register unsigned long __sc_7 __asm__ ("r7"); \
7401 + __sc_3 = (unsigned long) (arg1); \
7402 + __sc_4 = (unsigned long) (arg2); \
7403 + __sc_5 = (unsigned long) (arg3); \
7404 + __sc_6 = (unsigned long) (arg4); \
7405 + __sc_7 = (unsigned long) (arg5); \
7406 + __sc_0 = __NR_##name; \
7407 + __asm__ __volatile__ \
7410 + : "=&r" (__sc_3), "=&r" (__sc_0) \
7411 + : "0" (__sc_3), "1" (__sc_0), \
7416 + : "r8", "r9", "r10", "r11", "r12" ); \
7417 + __sc_ret = __sc_3; \
7418 + __sc_err = __sc_0; \
7420 + __syscall_return (type); \
7425 +#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \
7426 +type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) \
7428 + unsigned long __sc_ret, __sc_err; \
7430 + register unsigned long __sc_0 __asm__ ("r0"); \
7431 + register unsigned long __sc_3 __asm__ ("r3"); \
7432 + register unsigned long __sc_4 __asm__ ("r4"); \
7433 + register unsigned long __sc_5 __asm__ ("r5"); \
7434 + register unsigned long __sc_6 __asm__ ("r6"); \
7435 + register unsigned long __sc_7 __asm__ ("r7"); \
7436 + register unsigned long __sc_8 __asm__ ("r8"); \
7438 + __sc_3 = (unsigned long) (arg1); \
7439 + __sc_4 = (unsigned long) (arg2); \
7440 + __sc_5 = (unsigned long) (arg3); \
7441 + __sc_6 = (unsigned long) (arg4); \
7442 + __sc_7 = (unsigned long) (arg5); \
7443 + __sc_8 = (unsigned long) (arg6); \
7444 + __sc_0 = __NR_##name; \
7445 + __asm__ __volatile__ \
7448 + : "=&r" (__sc_3), "=&r" (__sc_0) \
7449 + : "0" (__sc_3), "1" (__sc_0), \
7455 + : "r9", "r10", "r11", "r12" ); \
7456 + __sc_ret = __sc_3; \
7457 + __sc_err = __sc_0; \
7459 + __syscall_return (type); \
7463 diff -urN uClibc/ldso-0.9.24/ldso/powerpc/ld_sysdep.h uClibc.ldso.24/ldso-0.9.24/ldso/powerpc/ld_sysdep.h
7464 --- uClibc/ldso-0.9.24/ldso/powerpc/ld_sysdep.h 1969-12-31 18:00:00.000000000 -0600
7465 +++ uClibc.ldso.24/ldso-0.9.24/ldso/powerpc/ld_sysdep.h 2003-12-03 17:38:43.000000000 -0600
7468 + * Various assmbly language/system dependent hacks that are required
7469 + * so that we can minimize the amount of platform specific code.
7473 + * Define this if the system uses RELOCA.
7475 +#define ELF_USES_RELOCA
7478 + * Get a pointer to the argv array. On many platforms this can be just
7479 + * the address if the first argument, on other platforms we need to
7480 + * do something a little more subtle here.
7482 +#define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long*) ARGS)+1)
7485 + * Initialization sequence for a GOT.
7487 +#define INIT_GOT(GOT_BASE,MODULE) _dl_init_got(GOT_BASE,MODULE)
7489 +/* Stuff for the PLT. */
7490 +#define PLT_INITIAL_ENTRY_WORDS 18
7491 +#define PLT_LONGBRANCH_ENTRY_WORDS 0
7492 +#define PLT_TRAMPOLINE_ENTRY_WORDS 6
7493 +#define PLT_DOUBLE_SIZE (1<<13)
7494 +#define PLT_ENTRY_START_WORDS(entry_number) \
7495 + (PLT_INITIAL_ENTRY_WORDS + (entry_number)*2 \
7496 + + ((entry_number) > PLT_DOUBLE_SIZE \
7497 + ? ((entry_number) - PLT_DOUBLE_SIZE)*2 \
7499 +#define PLT_DATA_START_WORDS(num_entries) PLT_ENTRY_START_WORDS(num_entries)
7501 +/* Macros to build PowerPC opcode words. */
7502 +#define OPCODE_ADDI(rd,ra,simm) \
7503 + (0x38000000 | (rd) << 21 | (ra) << 16 | ((simm) & 0xffff))
7504 +#define OPCODE_ADDIS(rd,ra,simm) \
7505 + (0x3c000000 | (rd) << 21 | (ra) << 16 | ((simm) & 0xffff))
7506 +#define OPCODE_ADD(rd,ra,rb) \
7507 + (0x7c000214 | (rd) << 21 | (ra) << 16 | (rb) << 11)
7508 +#define OPCODE_B(target) (0x48000000 | ((target) & 0x03fffffc))
7509 +#define OPCODE_BA(target) (0x48000002 | ((target) & 0x03fffffc))
7510 +#define OPCODE_BCTR() 0x4e800420
7511 +#define OPCODE_LWZ(rd,d,ra) \
7512 + (0x80000000 | (rd) << 21 | (ra) << 16 | ((d) & 0xffff))
7513 +#define OPCODE_LWZU(rd,d,ra) \
7514 + (0x84000000 | (rd) << 21 | (ra) << 16 | ((d) & 0xffff))
7515 +#define OPCODE_MTCTR(rd) (0x7C0903A6 | (rd) << 21)
7516 +#define OPCODE_RLWINM(ra,rs,sh,mb,me) \
7517 + (0x54000000 | (rs) << 21 | (ra) << 16 | (sh) << 11 | (mb) << 6 | (me) << 1)
7519 +#define OPCODE_LI(rd,simm) OPCODE_ADDI(rd,0,simm)
7520 +#define OPCODE_ADDIS_HI(rd,ra,value) \
7521 + OPCODE_ADDIS(rd,ra,((value) + 0x8000) >> 16)
7522 +#define OPCODE_LIS_HI(rd,value) OPCODE_ADDIS_HI(rd,0,value)
7523 +#define OPCODE_SLWI(ra,rs,sh) OPCODE_RLWINM(ra,rs,sh,0,31-sh)
7526 +#define PPC_DCBST(where) asm volatile ("dcbst 0,%0" : : "r"(where) : "memory")
7527 +#define PPC_SYNC asm volatile ("sync" : : : "memory")
7528 +#define PPC_ISYNC asm volatile ("sync; isync" : : : "memory")
7529 +#define PPC_ICBI(where) asm volatile ("icbi 0,%0" : : "r"(where) : "memory")
7530 +#define PPC_DIE asm volatile ("tweq 0,0")
7533 + * Here is a macro to perform a relocation. This is only used when
7534 + * bootstrapping the dynamic loader. RELP is the relocation that we
7535 + * are performing, REL is the pointer to the address we are relocating.
7536 + * SYMBOL is the symbol involved in the relocation, and LOAD is the
7539 +// finaladdr = LOAD ?
7540 +#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD) \
7541 + {int type=ELF32_R_TYPE((RELP)->r_info); \
7542 + if(type==R_PPC_NONE){ \
7543 + }else if(type==R_PPC_ADDR32){ \
7544 + *REL += (SYMBOL); \
7545 + }else if(type==R_PPC_RELATIVE){ \
7546 + *REL = (Elf32_Word)(LOAD) + (RELP)->r_addend; \
7547 + }else if(type==R_PPC_REL24){ \
7548 + Elf32_Sword delta = (Elf32_Word)(SYMBOL) - (Elf32_Word)(REL); \
7549 + *REL &= 0xfc000003; \
7550 + *REL |= (delta & 0x03fffffc); \
7551 + }else if(type==R_PPC_JMP_SLOT){ \
7552 + Elf32_Sword delta = (Elf32_Word)(SYMBOL) - (Elf32_Word)(REL); \
7553 + /*if (delta << 6 >> 6 != delta)_dl_exit(99);*/ \
7554 + *REL = OPCODE_B(delta); \
7556 + _dl_exit(100+ELF32_R_TYPE((RELP)->r_info)); \
7558 + if(type!=R_PPC_NONE){ \
7559 + PPC_DCBST(REL); PPC_SYNC; PPC_ICBI(REL);\
7564 + * Transfer control to the user's application, once the dynamic loader
7565 + * is done. This routine has to exit the current function, then
7566 + * call the _dl_elf_main function.
7570 + * Adding a clobber list consisting of r0 for %1. addi on PowerPC
7571 + * takes a register as the second argument, but if the register is
7572 + * r0, the value 0 is used instead. If r0 is used here, the stack
7573 + * pointer (r1) will be zeroed, and the dynamically linked
7574 + * application will seg.fault immediatly when receiving control.
7577 + __asm__ volatile ( \
7578 + "addi 1,%1,0\n\t" \
7581 + : : "r" (_dl_elf_main), "r" (args) \
7585 +/* Here we define the magic numbers that this dynamic loader should accept */
7587 +#define MAGIC1 EM_PPC
7589 +/* Used for error messages */
7590 +#define ELF_TARGET "powerpc"
7592 +struct elf_resolve;
7593 +extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
7594 +void _dl_init_got(unsigned long *lpnt,struct elf_resolve *tpnt);
7597 +#define do_rem(result, n, base) result = (n % base)
7599 +/* 4096 bytes alignment */
7600 +#define PAGE_ALIGN 0xfffff000
7601 +#define ADDR_ALIGN 0xfff
7602 +#define OFFS_ALIGN 0x7ffff000
7603 diff -urN uClibc/ldso-0.9.24/ldso/powerpc/resolve.S uClibc.ldso.24/ldso-0.9.24/ldso/powerpc/resolve.S
7604 --- uClibc/ldso-0.9.24/ldso/powerpc/resolve.S 1969-12-31 18:00:00.000000000 -0600
7605 +++ uClibc.ldso.24/ldso-0.9.24/ldso/powerpc/resolve.S 2001-07-12 05:14:09.000000000 -0500
7608 + * Stolen from glibc-2.2.2 by David Schleef <ds@schleef.org>
7614 +.globl _dl_linux_resolver
7616 +.globl _dl_linux_resolve
7617 +.type _dl_linux_resolve,@function
7620 +// We need to save the registers used to pass parameters, and register 0,
7621 +// which is used by _mcount; the registers are saved in a stack frame.
7626 +// The code that calls this has put parameters for 'fixup' in r12 and r11.
7632 +// We also need to save some of the condition register fields.
7640 + bl _dl_linux_resolver@local
7641 +// 'fixup' returns the address we want to branch to.
7643 +// Put the registers back...
7657 +// ...unwind the stack frame, and jump to the PLT entry we updated.
7662 + .size _dl_linux_resolve,.LFE2-_dl_linux_resolve
7666 + pusha /* preserve all regs */
7667 + lea 0x20(%esp),%eax /* eax = tpnt and reloc_entry params */
7668 + pushl 4(%eax) /* push copy of reloc_entry param */
7669 + pushl (%eax) /* push copy of tpnt param */
7675 + addl $_GLOBAL_OFFSET_TABLE_+[.-.L24],%ebx
7676 + movl _dl_linux_resolver@GOT(%ebx),%ebx /* eax = resolved func */
7679 + call _dl_linux_resolver
7681 + movl %eax,0x28(%esp) /* store func addr over original
7683 + addl $0x8,%esp /* remove copy parameters */
7684 + popa /* restore regs */
7685 + ret $4 /* jump to func removing original
7686 + * reloc_entry param from stack */
7689 diff -urN uClibc/ldso-0.9.24/ldso/readelflib1.c uClibc.ldso.24/ldso-0.9.24/ldso/readelflib1.c
7690 --- uClibc/ldso-0.9.24/ldso/readelflib1.c 1969-12-31 18:00:00.000000000 -0600
7691 +++ uClibc.ldso.24/ldso-0.9.24/ldso/readelflib1.c 2003-12-05 14:24:26.000000000 -0600
7693 +/* vi: set sw=4 ts=4: */
7694 +/* Program to load an ELF binary on a linux system, and run it
7695 + * after resolving ELF shared library symbols
7697 + * Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald,
7698 + * David Engel, Hongjiu Lu and Mitch D'Souza
7699 + * Copyright (C) 2001-2003, Erik Andersen
7701 + * All rights reserved.
7703 + * Redistribution and use in source and binary forms, with or without
7704 + * modification, are permitted provided that the following conditions
7706 + * 1. Redistributions of source code must retain the above copyright
7707 + * notice, this list of conditions and the following disclaimer.
7708 + * 2. The name of the above contributors may not be
7709 + * used to endorse or promote products derived from this software
7710 + * without specific prior written permission.
7712 + * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
7713 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
7714 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
7715 + * ARE DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE
7716 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
7717 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
7718 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
7719 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
7720 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
7721 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
7726 +/* This file contains the helper routines to load an ELF sharable
7727 + library into memory and add the symbol table info to the chain. */
7731 +static caddr_t _dl_cache_addr = NULL;
7732 +static size_t _dl_cache_size = 0;
7734 +int _dl_map_cache(void)
7739 + libentry_t *libent;
7740 + int i, strtabsize;
7742 + if (_dl_cache_addr == (caddr_t) - 1)
7744 + else if (_dl_cache_addr != NULL)
7747 + if (_dl_stat(LDSO_CACHE, &st)
7748 + || (fd = _dl_open(LDSO_CACHE, O_RDONLY)) < 0) {
7749 + _dl_dprintf(2, "%s: can't open cache '%s'\n", _dl_progname, LDSO_CACHE);
7750 + _dl_cache_addr = (caddr_t) - 1; /* so we won't try again */
7754 + _dl_cache_size = st.st_size;
7755 + _dl_cache_addr = (caddr_t) _dl_mmap(0, _dl_cache_size, PROT_READ, MAP_SHARED, fd, 0);
7757 + if (_dl_mmap_check_error(_dl_cache_addr)) {
7758 + _dl_dprintf(2, "%s: can't map cache '%s'\n",
7759 + _dl_progname, LDSO_CACHE);
7763 + header = (header_t *) _dl_cache_addr;
7765 + if (_dl_cache_size < sizeof(header_t) ||
7766 + _dl_memcmp(header->magic, LDSO_CACHE_MAGIC, LDSO_CACHE_MAGIC_LEN)
7767 + || _dl_memcmp(header->version, LDSO_CACHE_VER, LDSO_CACHE_VER_LEN)
7768 + || _dl_cache_size <
7769 + (sizeof(header_t) + header->nlibs * sizeof(libentry_t))
7770 + || _dl_cache_addr[_dl_cache_size - 1] != '\0')
7772 + _dl_dprintf(2, "%s: cache '%s' is corrupt\n", _dl_progname,
7777 + strtabsize = _dl_cache_size - sizeof(header_t) -
7778 + header->nlibs * sizeof(libentry_t);
7779 + libent = (libentry_t *) & header[1];
7781 + for (i = 0; i < header->nlibs; i++) {
7782 + if (libent[i].sooffset >= strtabsize ||
7783 + libent[i].liboffset >= strtabsize)
7785 + _dl_dprintf(2, "%s: cache '%s' is corrupt\n", _dl_progname, LDSO_CACHE);
7793 + _dl_munmap(_dl_cache_addr, _dl_cache_size);
7794 + _dl_cache_addr = (caddr_t) - 1;
7798 +int _dl_unmap_cache(void)
7800 + if (_dl_cache_addr == NULL || _dl_cache_addr == (caddr_t) - 1)
7804 + _dl_munmap(_dl_cache_addr, _dl_cache_size);
7805 + _dl_cache_addr = NULL;
7813 +/* This function's behavior must exactly match that
7814 + * in uClibc/ldso/util/ldd.c */
7815 +static struct elf_resolve *
7816 +search_for_named_library(const char *name, int secure, const char *path_list,
7817 + struct dyn_elf **rpnt)
7820 + char *path, *path_n;
7821 + char mylibname[2050];
7822 + struct elf_resolve *tpnt1;
7824 + if (path_list==NULL)
7827 + /* We need a writable copy of this string */
7828 + path = _dl_strdup(path_list);
7830 + _dl_dprintf(2, "Out of memory!\n");
7835 + /* Unlike ldd.c, don't bother to eliminate double //s */
7838 + /* Replace colons with zeros in path_list and count them */
7839 + for(i=_dl_strlen(path); i > 0; i--) {
7840 + if (path[i]==':') {
7847 + for (i = 0; i < count; i++) {
7848 + _dl_strcpy(mylibname, path_n);
7849 + _dl_strcat(mylibname, "/");
7850 + _dl_strcat(mylibname, name);
7851 + if ((tpnt1 = _dl_load_elf_shared_library(secure, rpnt, mylibname)) != NULL)
7855 + path_n += (_dl_strlen(path_n) + 1);
7860 +/* Check if the named library is already loaded... */
7861 +struct elf_resolve *_dl_check_if_named_library_is_loaded(const char *full_libname)
7863 + const char *pnt, *pnt1;
7864 + struct elf_resolve *tpnt1;
7865 + const char *libname, *libname2;
7866 + static const char *libc = "libc.so.";
7867 + static const char *aborted_wrong_lib = "%s: aborted attempt to load %s!\n";
7869 + pnt = libname = full_libname;
7871 +#if defined (__SUPPORT_LD_DEBUG__)
7873 + _dl_dprintf(_dl_debug_file, "Checking if '%s' is already loaded\n", full_libname);
7875 + /* quick hack to ensure mylibname buffer doesn't overflow. don't
7876 + allow full_libname or any directory to be longer than 1024. */
7877 + if (_dl_strlen(full_libname) > 1024)
7880 + /* Skip over any initial initial './' and '/' stuff to
7881 + * get the short form libname with no path garbage */
7882 + pnt1 = _dl_strrchr(pnt, '/');
7884 + libname = pnt1 + 1;
7887 + /* Make sure they are not trying to load the wrong C library!
7888 + * This sometimes happens esp with shared libraries when the
7889 + * library path is somehow wrong! */
7890 +#define isdigit(c) (c >= '0' && c <= '9')
7891 + if ((_dl_strncmp(libname, libc, 8) == 0) && _dl_strlen(libname) >=8 &&
7892 + isdigit(libname[8]))
7894 + /* Abort attempts to load glibc, libc5, etc */
7895 + if ( libname[8]!='0') {
7896 + if (!_dl_trace_loaded_objects) {
7897 + _dl_dprintf(2, aborted_wrong_lib, libname, _dl_progname);
7904 + /* Critical step! Weed out duplicates early to avoid
7905 + * function aliasing, which wastes memory, and causes
7906 + * really bad things to happen with weaks and globals. */
7907 + for (tpnt1 = _dl_loaded_modules; tpnt1; tpnt1 = tpnt1->next) {
7909 + /* Skip over any initial initial './' and '/' stuff to
7910 + * get the short form libname with no path garbage */
7911 + libname2 = tpnt1->libname;
7912 + pnt1 = _dl_strrchr(libname2, '/');
7914 + libname2 = pnt1 + 1;
7917 + if (_dl_strcmp(libname2, libname) == 0) {
7918 + /* Well, that was certainly easy */
7929 + * Used to return error codes back to dlopen et. al.
7932 +unsigned long _dl_error_number;
7933 +unsigned long _dl_internal_error_number;
7934 +extern char *_dl_ldsopath;
7936 +struct elf_resolve *_dl_load_shared_library(int secure, struct dyn_elf **rpnt,
7937 + struct elf_resolve *tpnt, char *full_libname)
7940 + struct elf_resolve *tpnt1;
7943 + _dl_internal_error_number = 0;
7944 + libname = full_libname;
7946 + /* quick hack to ensure mylibname buffer doesn't overflow. don't
7947 + allow full_libname or any directory to be longer than 1024. */
7948 + if (_dl_strlen(full_libname) > 1024)
7951 + /* Skip over any initial initial './' and '/' stuff to
7952 + * get the short form libname with no path garbage */
7953 + pnt1 = _dl_strrchr(libname, '/');
7955 + libname = pnt1 + 1;
7958 + /* Critical step! Weed out duplicates early to avoid
7959 + * function aliasing, which wastes memory, and causes
7960 + * really bad things to happen with weaks and globals. */
7961 + if ((tpnt1=_dl_check_if_named_library_is_loaded(libname))!=NULL)
7964 +#if defined (__SUPPORT_LD_DEBUG__)
7965 + if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tfind library='%s'; searching\n", libname);
7967 + /* If the filename has any '/', try it straight and leave it at that.
7968 + For IBCS2 compatibility under linux, we substitute the string
7969 + /usr/i486-sysv4/lib for /usr/lib in library names. */
7971 + if (libname != full_libname) {
7972 +#if defined (__SUPPORT_LD_DEBUG__)
7973 + if(_dl_debug) _dl_dprintf(_dl_debug_file, "\ttrying file='%s'\n", full_libname);
7975 + tpnt1 = _dl_load_elf_shared_library(secure, rpnt, full_libname);
7983 + * The ABI specifies that RPATH is searched before LD_*_PATH or
7984 + * the default path of /usr/lib. Check in rpath directories.
7986 + for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
7987 + if (tpnt->libtype == elf_executable) {
7988 + pnt = (char *) tpnt->dynamic_info[DT_RPATH];
7990 + pnt += (unsigned long) tpnt->loadaddr + tpnt->dynamic_info[DT_STRTAB];
7991 +#if defined (__SUPPORT_LD_DEBUG__)
7992 + if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tsearching RPATH='%s'\n", pnt);
7994 + if ((tpnt1 = search_for_named_library(libname, secure, pnt, rpnt)) != NULL)
8002 + /* Check in LD_{ELF_}LIBRARY_PATH, if specified and allowed */
8003 + if (_dl_library_path) {
8004 +#if defined (__SUPPORT_LD_DEBUG__)
8005 + if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tsearching LD_LIBRARY_PATH='%s'\n", _dl_library_path);
8007 + if ((tpnt1 = search_for_named_library(libname, secure, _dl_library_path, rpnt)) != NULL)
8014 + * Where should the cache be searched? There is no such concept in the
8015 + * ABI, so we have some flexibility here. For now, search it before
8016 + * the hard coded paths that follow (i.e before /lib and /usr/lib).
8019 + if (_dl_cache_addr != NULL && _dl_cache_addr != (caddr_t) - 1) {
8021 + header_t *header = (header_t *) _dl_cache_addr;
8022 + libentry_t *libent = (libentry_t *) & header[1];
8023 + char *strs = (char *) &libent[header->nlibs];
8025 +#if defined (__SUPPORT_LD_DEBUG__)
8026 + if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tsearching cache='%s'\n", LDSO_CACHE);
8028 + for (i = 0; i < header->nlibs; i++) {
8029 + if ((libent[i].flags == LIB_ELF ||
8030 + libent[i].flags == LIB_ELF_LIBC5) &&
8031 + _dl_strcmp(libname, strs + libent[i].sooffset) == 0 &&
8032 + (tpnt1 = _dl_load_elf_shared_library(secure,
8033 + rpnt, strs + libent[i].liboffset)))
8039 + /* Look for libraries wherever the shared library loader
8040 + * was installed */
8041 +#if defined (__SUPPORT_LD_DEBUG__)
8042 + if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tsearching ldso dir='%s'\n", _dl_ldsopath);
8044 + if ((tpnt1 = search_for_named_library(libname, secure, _dl_ldsopath, rpnt)) != NULL)
8050 + /* Lastly, search the standard list of paths for the library.
8051 + This list must exactly match the list in uClibc/ldso/util/ldd.c */
8052 +#if defined (__SUPPORT_LD_DEBUG__)
8053 + if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tsearching full lib path list\n");
8055 + if ((tpnt1 = search_for_named_library(libname, secure,
8056 + UCLIBC_RUNTIME_PREFIX "usr/X11R6/lib:"
8057 + UCLIBC_RUNTIME_PREFIX "usr/lib:"
8058 + UCLIBC_RUNTIME_PREFIX "lib:"
8067 + /* Well, we shot our wad on that one. All we can do now is punt */
8068 + if (_dl_internal_error_number)
8069 + _dl_error_number = _dl_internal_error_number;
8071 + _dl_error_number = LD_ERROR_NOFILE;
8072 +#if defined (__SUPPORT_LD_DEBUG__)
8073 + if(_dl_debug) _dl_dprintf(2, "Bummer: could not find '%s'!\n", libname);
8080 + * Read one ELF library into memory, mmap it into the correct locations and
8081 + * add the symbol info to the symbol chain. Perform any relocations that
8085 +struct elf_resolve *_dl_load_elf_shared_library(int secure,
8086 + struct dyn_elf **rpnt, char *libname)
8089 + unsigned long dynamic_addr = 0;
8090 + unsigned long dynamic_size = 0;
8092 + struct elf_resolve *tpnt;
8094 + char *status, *header;
8095 + unsigned long dynamic_info[24];
8096 + unsigned long *lpnt;
8097 + unsigned long libaddr;
8098 + unsigned long minvma = 0xffffffff, maxvma = 0;
8099 + int i, flags, piclib, infile;
8101 + /* If this file is already loaded, skip this step */
8102 + tpnt = _dl_check_hashed_files(libname);
8105 + (*rpnt)->next = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
8106 + _dl_memset((*rpnt)->next, 0, sizeof(struct dyn_elf));
8107 + (*rpnt)->next->prev = (*rpnt);
8108 + *rpnt = (*rpnt)->next;
8109 + (*rpnt)->dyn = tpnt;
8110 + tpnt->symbol_scope = _dl_symbol_tables;
8112 + tpnt->usage_count++;
8113 + tpnt->libtype = elf_lib;
8114 +#if defined (__SUPPORT_LD_DEBUG__)
8115 + if(_dl_debug) _dl_dprintf(2, "file='%s'; already loaded\n", libname);
8120 + /* If we are in secure mode (i.e. a setu/gid binary using LD_PRELOAD),
8121 + we don't load the library if it isn't setuid. */
8126 + if (_dl_stat(libname, &st) || !(st.st_mode & S_ISUID))
8131 + infile = _dl_open(libname, O_RDONLY);
8135 + * NO! When we open shared libraries we may search several paths.
8136 + * it is inappropriate to generate an error here.
8138 + _dl_dprintf(2, "%s: can't open '%s'\n", _dl_progname, libname);
8140 + _dl_internal_error_number = LD_ERROR_NOFILE;
8144 + header = _dl_mmap((void *) 0, 4096, PROT_READ | PROT_WRITE,
8145 + MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
8146 + if (_dl_mmap_check_error(header)) {
8147 + _dl_dprintf(2, "%s: can't map '%s'\n", _dl_progname, libname);
8148 + _dl_internal_error_number = LD_ERROR_MMAP_FAILED;
8149 + _dl_close(infile);
8153 + _dl_read(infile, header, 4096);
8154 + epnt = (ElfW(Ehdr) *) (intptr_t) header;
8155 + if (epnt->e_ident[0] != 0x7f ||
8156 + epnt->e_ident[1] != 'E' ||
8157 + epnt->e_ident[2] != 'L' ||
8158 + epnt->e_ident[3] != 'F')
8160 + _dl_dprintf(2, "%s: '%s' is not an ELF file\n", _dl_progname,
8162 + _dl_internal_error_number = LD_ERROR_NOTELF;
8163 + _dl_close(infile);
8164 + _dl_munmap(header, 4096);
8168 + if ((epnt->e_type != ET_DYN) || (epnt->e_machine != MAGIC1
8170 + && epnt->e_machine != MAGIC2
8174 + _dl_internal_error_number =
8175 + (epnt->e_type != ET_DYN ? LD_ERROR_NOTDYN : LD_ERROR_NOTMAGIC);
8176 + _dl_dprintf(2, "%s: '%s' is not an ELF executable for " ELF_TARGET
8177 + "\n", _dl_progname, libname);
8178 + _dl_close(infile);
8179 + _dl_munmap(header, 4096);
8183 + ppnt = (ElfW(Phdr) *)(intptr_t) & header[epnt->e_phoff];
8186 + for (i = 0; i < epnt->e_phnum; i++) {
8188 + if (ppnt->p_type == PT_DYNAMIC) {
8190 + _dl_dprintf(2, "%s: '%s' has more than one dynamic section\n",
8191 + _dl_progname, libname);
8192 + dynamic_addr = ppnt->p_vaddr;
8193 + dynamic_size = ppnt->p_filesz;
8196 + if (ppnt->p_type == PT_LOAD) {
8197 + /* See if this is a PIC library. */
8198 + if (i == 0 && ppnt->p_vaddr > 0x1000000) {
8200 + minvma = ppnt->p_vaddr;
8202 + if (piclib && ppnt->p_vaddr < minvma) {
8203 + minvma = ppnt->p_vaddr;
8205 + if (((unsigned long) ppnt->p_vaddr + ppnt->p_memsz) > maxvma) {
8206 + maxvma = ppnt->p_vaddr + ppnt->p_memsz;
8212 + maxvma = (maxvma + ADDR_ALIGN) & ~ADDR_ALIGN;
8213 + minvma = minvma & ~0xffffU;
8215 + flags = MAP_PRIVATE /*| MAP_DENYWRITE */ ;
8217 + flags |= MAP_FIXED;
8219 + status = (char *) _dl_mmap((char *) (piclib ? 0 : minvma),
8220 + maxvma - minvma, PROT_NONE, flags | MAP_ANONYMOUS, -1, 0);
8221 + if (_dl_mmap_check_error(status)) {
8222 + _dl_dprintf(2, "%s: can't map %s\n", _dl_progname, libname);
8223 + _dl_internal_error_number = LD_ERROR_MMAP_FAILED;
8224 + _dl_close(infile);
8225 + _dl_munmap(header, 4096);
8228 + libaddr = (unsigned long) status;
8229 + flags |= MAP_FIXED;
8231 + /* Get the memory to store the library */
8232 + ppnt = (ElfW(Phdr) *)(intptr_t) & header[epnt->e_phoff];
8234 + for (i = 0; i < epnt->e_phnum; i++) {
8235 + if (ppnt->p_type == PT_LOAD) {
8237 + /* See if this is a PIC library. */
8238 + if (i == 0 && ppnt->p_vaddr > 0x1000000) {
8240 + /* flags |= MAP_FIXED; */
8245 + if (ppnt->p_flags & PF_W) {
8246 + unsigned long map_size;
8249 + status = (char *) _dl_mmap((char *) ((piclib ? libaddr : 0) +
8250 + (ppnt->p_vaddr & PAGE_ALIGN)), (ppnt->p_vaddr & ADDR_ALIGN)
8251 + + ppnt->p_filesz, LXFLAGS(ppnt->p_flags), flags, infile,
8252 + ppnt->p_offset & OFFS_ALIGN);
8254 + if (_dl_mmap_check_error(status)) {
8255 + _dl_dprintf(2, "%s: can't map '%s'\n",
8256 + _dl_progname, libname);
8257 + _dl_internal_error_number = LD_ERROR_MMAP_FAILED;
8258 + _dl_munmap((char *) libaddr, maxvma - minvma);
8259 + _dl_close(infile);
8260 + _dl_munmap(header, 4096);
8264 + /* Pad the last page with zeroes. */
8265 + cpnt = (char *) (status + (ppnt->p_vaddr & ADDR_ALIGN) +
8267 + while (((unsigned long) cpnt) & ADDR_ALIGN)
8270 + /* I am not quite sure if this is completely
8271 + * correct to do or not, but the basic way that
8272 + * we handle bss segments is that we mmap
8273 + * /dev/zero if there are any pages left over
8274 + * that are not mapped as part of the file */
8276 + map_size = (ppnt->p_vaddr + ppnt->p_filesz + ADDR_ALIGN) & PAGE_ALIGN;
8278 + if (map_size < ppnt->p_vaddr + ppnt->p_memsz)
8279 + status = (char *) _dl_mmap((char *) map_size +
8280 + (piclib ? libaddr : 0),
8281 + ppnt->p_vaddr + ppnt->p_memsz - map_size,
8282 + LXFLAGS(ppnt->p_flags), flags | MAP_ANONYMOUS, -1, 0);
8284 + status = (char *) _dl_mmap((char *) (ppnt->p_vaddr & PAGE_ALIGN)
8285 + + (piclib ? libaddr : 0), (ppnt->p_vaddr & ADDR_ALIGN) +
8286 + ppnt->p_filesz, LXFLAGS(ppnt->p_flags), flags,
8287 + infile, ppnt->p_offset & OFFS_ALIGN);
8288 + if (_dl_mmap_check_error(status)) {
8289 + _dl_dprintf(2, "%s: can't map '%s'\n", _dl_progname, libname);
8290 + _dl_internal_error_number = LD_ERROR_MMAP_FAILED;
8291 + _dl_munmap((char *) libaddr, maxvma - minvma);
8292 + _dl_close(infile);
8293 + _dl_munmap(header, 4096);
8297 + /* if(libaddr == 0 && piclib) {
8298 + libaddr = (unsigned long) status;
8299 + flags |= MAP_FIXED;
8304 + _dl_close(infile);
8306 + /* For a non-PIC library, the addresses are all absolute */
8308 + dynamic_addr += (unsigned long) libaddr;
8312 + * OK, the ELF library is now loaded into VM in the correct locations
8313 + * The next step is to go through and do the dynamic linking (if needed).
8316 + /* Start by scanning the dynamic section to get all of the pointers */
8318 + if (!dynamic_addr) {
8319 + _dl_internal_error_number = LD_ERROR_NODYNAMIC;
8320 + _dl_dprintf(2, "%s: '%s' is missing a dynamic section\n",
8321 + _dl_progname, libname);
8322 + _dl_munmap(header, 4096);
8326 + dpnt = (Elf32_Dyn *) dynamic_addr;
8328 + dynamic_size = dynamic_size / sizeof(Elf32_Dyn);
8329 + _dl_memset(dynamic_info, 0, sizeof(dynamic_info));
8331 +#if defined(__mips__)
8335 + Elf32_Dyn *dpnt = (Elf32_Dyn *) dynamic_addr;
8337 + while(dpnt->d_tag) {
8341 + dynamic_size = indx;
8346 + unsigned long indx;
8348 + for (indx = 0; indx < dynamic_size; indx++)
8350 + if (dpnt->d_tag > DT_JMPREL) {
8354 + dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
8355 + if (dpnt->d_tag == DT_TEXTREL)
8356 + dynamic_info[DT_TEXTREL] = 1;
8361 + /* If the TEXTREL is set, this means that we need to make the pages
8362 + writable before we perform relocations. Do this now. They get set
8363 + back again later. */
8365 + if (dynamic_info[DT_TEXTREL]) {
8366 +#ifndef FORCE_SHAREABLE_TEXT_SEGMENTS
8367 + ppnt = (ElfW(Phdr) *)(intptr_t) & header[epnt->e_phoff];
8368 + for (i = 0; i < epnt->e_phnum; i++, ppnt++) {
8369 + if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
8370 + _dl_mprotect((void *) ((piclib ? libaddr : 0) +
8371 + (ppnt->p_vaddr & PAGE_ALIGN)),
8372 + (ppnt->p_vaddr & ADDR_ALIGN) + (unsigned long) ppnt->p_filesz,
8373 + PROT_READ | PROT_WRITE | PROT_EXEC);
8376 + _dl_dprintf(_dl_debug_file, "Can't modify %s's text section. Use GCC option -fPIC for shared objects, please.\n",libname);
8381 + tpnt = _dl_add_elf_hash_table(libname, (char *) libaddr, dynamic_info,
8382 + dynamic_addr, dynamic_size);
8384 + tpnt->ppnt = (ElfW(Phdr) *)(intptr_t) (tpnt->loadaddr + epnt->e_phoff);
8385 + tpnt->n_phent = epnt->e_phnum;
8388 + * Add this object into the symbol chain
8391 + (*rpnt)->next = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
8392 + _dl_memset((*rpnt)->next, 0, sizeof(struct dyn_elf));
8393 + (*rpnt)->next->prev = (*rpnt);
8394 + *rpnt = (*rpnt)->next;
8395 + (*rpnt)->dyn = tpnt;
8396 + tpnt->symbol_scope = _dl_symbol_tables;
8398 + tpnt->usage_count++;
8399 + tpnt->libtype = elf_lib;
8402 + * OK, the next thing we need to do is to insert the dynamic linker into
8403 + * the proper entry in the GOT so that the PLT symbols can be properly
8407 + lpnt = (unsigned long *) dynamic_info[DT_PLTGOT];
8410 + lpnt = (unsigned long *) (dynamic_info[DT_PLTGOT] +
8412 + INIT_GOT(lpnt, tpnt);
8415 +#if defined (__SUPPORT_LD_DEBUG__)
8417 + _dl_dprintf(2, "\n\tfile='%s'; generating link map\n", libname);
8418 + _dl_dprintf(2, "\t\tdynamic: %x base: %x size: %x\n",
8419 + dynamic_addr, libaddr, dynamic_size);
8420 + _dl_dprintf(2, "\t\t entry: %x phdr: %x phnum: %d\n\n",
8421 + epnt->e_entry + libaddr, tpnt->ppnt, tpnt->n_phent);
8425 + _dl_munmap(header, 4096);
8430 +/* Ugly, ugly. Some versions of the SVr4 linker fail to generate COPY
8431 + relocations for global variables that are present both in the image and
8432 + the shared library. Go through and do it manually. If the images
8433 + are guaranteed to be generated by a trustworthy linker, then this
8434 + step can be skipped. */
8436 +int _dl_copy_fixups(struct dyn_elf *rpnt)
8439 + struct elf_resolve *tpnt;
8442 + goof += _dl_copy_fixups(rpnt->next);
8448 + if (tpnt->init_flag & COPY_RELOCS_DONE)
8450 + tpnt->init_flag |= COPY_RELOCS_DONE;
8452 +#if defined (__SUPPORT_LD_DEBUG__)
8453 + if(_dl_debug) _dl_dprintf(_dl_debug_file,"\nrelocation copy fixups: %s", tpnt->libname);
8456 +#ifdef ELF_USES_RELOCA
8457 + goof += _dl_parse_copy_information(rpnt,
8458 + tpnt->dynamic_info[DT_RELA], tpnt->dynamic_info[DT_RELASZ], 0);
8461 + goof += _dl_parse_copy_information(rpnt, tpnt->dynamic_info[DT_REL],
8462 + tpnt->dynamic_info[DT_RELSZ], 0);
8465 +#if defined (__SUPPORT_LD_DEBUG__)
8466 + if(_dl_debug) _dl_dprintf(_dl_debug_file,"\nrelocation copy fixups: %s; finished\n\n", tpnt->libname);
8471 +/* Minimal printf which handles only %s, %d, and %x */
8472 +void _dl_dprintf(int fd, const char *fmt, ...)
8476 + char *start, *ptr, *string;
8479 + buf = _dl_mmap((void *) 0, 4096, PROT_READ | PROT_WRITE,
8480 + MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
8481 + if (_dl_mmap_check_error(buf)) {
8482 + _dl_dprintf(2, "%s: mmap of a spare page failed!\n", _dl_progname);
8486 + start = ptr = buf;
8491 + if (_dl_strlen(fmt) >= (sizeof(buf) - 1))
8492 + _dl_write(fd, "(overflow)\n", 10);
8494 + _dl_strcpy(buf, fmt);
8495 + va_start(args, fmt);
8498 + while (*ptr != '%' && *ptr) {
8502 + if (*ptr == '%') {
8504 + _dl_write(fd, start, _dl_strlen(start));
8508 + string = va_arg(args, char *);
8511 + _dl_write(fd, "(null)", 6);
8513 + _dl_write(fd, string, _dl_strlen(string));
8520 + num = va_arg(args, int);
8522 + string = _dl_simple_ltoa(tmp, num);
8523 + _dl_write(fd, string, _dl_strlen(string));
8530 + num = va_arg(args, int);
8532 + string = _dl_simple_ltoahex(tmp, num);
8533 + _dl_write(fd, string, _dl_strlen(string));
8537 + _dl_write(fd, "(null)", 6);
8543 + _dl_write(fd, start, _dl_strlen(start));
8547 + _dl_munmap(buf, 4096);
8551 +char *_dl_strdup(const char *string)
8556 + len = _dl_strlen(string);
8557 + retval = _dl_malloc(len + 1);
8558 + _dl_strcpy(retval, string);
8562 +void *(*_dl_malloc_function) (size_t size) = NULL;
8563 +void *_dl_malloc(int size)
8568 +#ifdef __SUPPORT_LD_DEBUG_EARLY__
8569 + _dl_dprintf(2, "malloc: request for %d bytes\n", size);
8573 + if (_dl_malloc_function)
8574 + return (*_dl_malloc_function) (size);
8576 + if (_dl_malloc_addr - _dl_mmap_zero + size > 4096) {
8577 +#ifdef __SUPPORT_LD_DEBUG_EARLY__
8578 + _dl_dprintf(2, "malloc: mmapping more memory\n");
8580 + _dl_mmap_zero = _dl_malloc_addr = _dl_mmap((void *) 0, size,
8581 + PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
8582 + if (_dl_mmap_check_error(_dl_mmap_zero)) {
8583 + _dl_dprintf(2, "%s: mmap of a spare page failed!\n", _dl_progname);
8587 + retval = _dl_malloc_addr;
8588 + _dl_malloc_addr += size;
8591 + * Align memory to 4 byte boundary. Some platforms require this, others
8592 + * simply get better performance.
8594 + _dl_malloc_addr = (char *) (((unsigned long) _dl_malloc_addr + 3) & ~(3));
8598 +int _dl_fixup(struct elf_resolve *tpnt, int flag)
8603 + goof += _dl_fixup(tpnt->next, flag);
8604 +#if defined (__SUPPORT_LD_DEBUG__)
8605 + if(_dl_debug) _dl_dprintf(_dl_debug_file,"\nrelocation processing: %s", tpnt->libname);
8608 + if (tpnt->dynamic_info[DT_REL]) {
8609 +#ifdef ELF_USES_RELOCA
8610 +#if defined (__SUPPORT_LD_DEBUG__)
8611 + if(_dl_debug) _dl_dprintf(2, "%s: can't handle REL relocation records\n", _dl_progname);
8616 + if (tpnt->init_flag & RELOCS_DONE)
8618 + tpnt->init_flag |= RELOCS_DONE;
8619 + goof += _dl_parse_relocation_information(tpnt,
8620 + tpnt->dynamic_info[DT_REL],
8621 + tpnt->dynamic_info[DT_RELSZ], 0);
8624 + if (tpnt->dynamic_info[DT_RELA]) {
8625 +#ifndef ELF_USES_RELOCA
8626 +#if defined (__SUPPORT_LD_DEBUG__)
8627 + if(_dl_debug) _dl_dprintf(2, "%s: can't handle RELA relocation records\n", _dl_progname);
8632 + if (tpnt->init_flag & RELOCS_DONE)
8634 + tpnt->init_flag |= RELOCS_DONE;
8635 + goof += _dl_parse_relocation_information(tpnt,
8636 + tpnt->dynamic_info[DT_RELA],
8637 + tpnt->dynamic_info[DT_RELASZ], 0);
8640 + if (tpnt->dynamic_info[DT_JMPREL]) {
8641 + if (tpnt->init_flag & JMP_RELOCS_DONE)
8643 + tpnt->init_flag |= JMP_RELOCS_DONE;
8644 + if (flag & RTLD_LAZY) {
8645 + _dl_parse_lazy_relocation_information(tpnt,
8646 + tpnt->dynamic_info[DT_JMPREL],
8647 + tpnt->dynamic_info [DT_PLTRELSZ], 0);
8649 + goof += _dl_parse_relocation_information(tpnt,
8650 + tpnt->dynamic_info[DT_JMPREL],
8651 + tpnt->dynamic_info[DT_PLTRELSZ], 0);
8654 +#if defined (__SUPPORT_LD_DEBUG__)
8656 + _dl_dprintf(_dl_debug_file,"\nrelocation processing: %s", tpnt->libname);
8657 + _dl_dprintf(_dl_debug_file,"; finished\n\n");
8664 diff -urN uClibc/ldso-0.9.24/ldso/sh/boot1_arch.h uClibc.ldso.24/ldso-0.9.24/ldso/sh/boot1_arch.h
8665 --- uClibc/ldso-0.9.24/ldso/sh/boot1_arch.h 1969-12-31 18:00:00.000000000 -0600
8666 +++ uClibc.ldso.24/ldso-0.9.24/ldso/sh/boot1_arch.h 2002-11-03 08:12:29.000000000 -0600
8668 +/* Any assmbly language/system dependent hacks needed to setup boot1.c so it
8669 + * will work as expected and cope with whatever platform specific wierdness is
8670 + * needed for this architecture. */
8674 +" .globl _dl_boot\n" \
8677 +" mov.l .L_dl_boot2, r0\n" \
8682 +" mov #0, r4 !call _start with arg == 0\n" \
8684 +" .long _dl_boot2-.jmp_loc\n" \
8688 +#define _dl_boot _dl_boot2
8689 +#define LD_BOOT(X) static void * __attribute__ ((unused)) _dl_boot (X)
8690 diff -urN uClibc/ldso-0.9.24/ldso/sh/elfinterp.c uClibc.ldso.24/ldso-0.9.24/ldso/sh/elfinterp.c
8691 --- uClibc/ldso-0.9.24/ldso/sh/elfinterp.c 1969-12-31 18:00:00.000000000 -0600
8692 +++ uClibc.ldso.24/ldso-0.9.24/ldso/sh/elfinterp.c 2003-09-11 05:26:16.000000000 -0500
8694 +/* vi: set sw=4 ts=4: */
8695 +/* SuperH ELF shared library loader suppport
8697 + * Copyright (C) 2002, Stefan Allius <allius@atecom.com> and
8698 + * Eddie C. Dost <ecd@atecom.com>
8700 + * All rights reserved.
8702 + * Redistribution and use in source and binary forms, with or without
8703 + * modification, are permitted provided that the following conditions
8705 + * 1. Redistributions of source code must retain the above copyright
8706 + * notice, this list of conditions and the following disclaimer.
8707 + * 2. The name of the above contributors may not be
8708 + * used to endorse or promote products derived from this software
8709 + * without specific prior written permission.
8711 + * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
8712 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
8713 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
8714 + * ARE DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE
8715 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
8716 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
8717 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
8718 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
8719 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
8720 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
8724 +#if defined (__SUPPORT_LD_DEBUG__)
8725 +static const char *_dl_reltypes_tab[] =
8727 + [0] "R_SH_NONE", "R_SH_DIR32", "R_SH_REL32", "R_SH_DIR8WPN",
8728 + [4] "R_SH_IND12W", "R_SH_DIR8WPL", "R_SH_DIR8WPZ", "R_SH_DIR8BP",
8729 + [8] "R_SH_DIR8W", "R_SH_DIR8L",
8730 + [25] "R_SH_SWITCH16","R_SH_SWITCH32","R_SH_USES",
8731 + [28] "R_SH_COUNT", "R_SH_ALIGN", "R_SH_CODE", "R_SH_DATA",
8732 + [32] "R_SH_LABEL", "R_SH_SWITCH8", "R_SH_GNU_VTINHERIT","R_SH_GNU_VTENTRY",
8733 +[160] "R_SH_GOT32", "R_SH_PLT32", "R_SH_COPY", "R_SH_GLOB_DAT",
8734 +[164] "R_SH_JMP_SLOT","R_SH_RELATIVE","R_SH_GOTOFF", "R_SH_GOTPC",
8737 +static const char *
8738 +_dl_reltypes(int type)
8740 + static char buf[22];
8743 + if (type >= (int)(sizeof (_dl_reltypes_tab)/sizeof(_dl_reltypes_tab[0])) ||
8744 + NULL == (str = _dl_reltypes_tab[type]))
8746 + str =_dl_simple_ltoa( buf, (unsigned long)(type));
8752 +void debug_sym(Elf32_Sym *symtab,char *strtab,int symtab_index)
8754 + if(_dl_debug_symbols)
8757 + _dl_dprintf(_dl_debug_file, "\n%s\tvalue=%x\tsize=%x\tinfo=%x\tother=%x\tshndx=%x",
8758 + strtab + symtab[symtab_index].st_name,
8759 + symtab[symtab_index].st_value,
8760 + symtab[symtab_index].st_size,
8761 + symtab[symtab_index].st_info,
8762 + symtab[symtab_index].st_other,
8763 + symtab[symtab_index].st_shndx);
8768 +static void debug_reloc(Elf32_Sym *symtab,char *strtab, ELF_RELOC *rpnt)
8770 + if(_dl_debug_reloc)
8774 + symtab_index = ELF32_R_SYM(rpnt->r_info);
8775 + sym = symtab_index ? strtab + symtab[symtab_index].st_name : "sym=0x0";
8777 + if(_dl_debug_symbols)
8778 + _dl_dprintf(_dl_debug_file, "\n\t");
8780 + _dl_dprintf(_dl_debug_file, "\n%s\n\t", sym);
8782 +#ifdef ELF_USES_RELOCA
8783 + _dl_dprintf(_dl_debug_file, "%s\toffset=%x\taddend=%x",
8784 + _dl_reltypes(ELF32_R_TYPE(rpnt->r_info)),
8788 + _dl_dprintf(_dl_debug_file, "%s\toffset=%x\n",
8789 + _dl_reltypes(ELF32_R_TYPE(rpnt->r_info)),
8796 +/* Program to load an ELF binary on a linux system, and run it.
8797 + References to symbols in sharable libraries can be resolved by either
8798 + an ELF sharable library or a linux style of shared library. */
8800 +/* Disclaimer: I have never seen any AT&T source code for SVr4, nor have
8801 + I ever taken any courses on internals. This program was developed using
8802 + information available through the book "UNIX SYSTEM V RELEASE 4,
8803 + Programmers guide: Ansi C and Programming Support Tools", which did
8804 + a more than adequate job of explaining everything required to get this
8807 +extern int _dl_linux_resolve(void);
8809 +unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
8812 + ELF_RELOC *this_reloc;
8814 + Elf32_Sym *symtab;
8819 + unsigned long instr_addr;
8822 + rel_addr = (char *) (tpnt->dynamic_info[DT_JMPREL] + tpnt->loadaddr);
8824 + this_reloc = (ELF_RELOC *)(intptr_t)(rel_addr + reloc_entry);
8825 + reloc_type = ELF32_R_TYPE(this_reloc->r_info);
8826 + symtab_index = ELF32_R_SYM(this_reloc->r_info);
8828 + symtab = (Elf32_Sym *)(intptr_t) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
8829 + strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
8830 + symname = strtab + symtab[symtab_index].st_name;
8832 + if (reloc_type != R_SH_JMP_SLOT) {
8833 + _dl_dprintf(2, "%s: Incorrect relocation type in jump relocations\n",
8838 + /* Address of jump instruction to fix up */
8839 + instr_addr = ((unsigned long) this_reloc->r_offset +
8840 + (unsigned long) tpnt->loadaddr);
8841 + got_addr = (char **) instr_addr;
8844 + /* Get the address of the GOT entry */
8845 + new_addr = _dl_find_hash(symname, tpnt->symbol_scope, tpnt, resolver);
8847 + new_addr = _dl_find_hash(symname, NULL, NULL, resolver);
8849 + return (unsigned long) new_addr;
8852 + _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname);
8856 +#if defined (__SUPPORT_LD_DEBUG__)
8857 + if ((unsigned long) got_addr < 0x20000000)
8859 + if (_dl_debug_bindings)
8861 + _dl_dprintf(_dl_debug_file, "\nresolve function: %s", symname);
8862 + if(_dl_debug_detail) _dl_dprintf(_dl_debug_file,
8863 + "\n\tpatched %x ==> %x @ %x\n", *got_addr, new_addr, got_addr);
8866 + if (!_dl_debug_nofixups) {
8867 + *got_addr = new_addr;
8870 + *got_addr = new_addr;
8873 + return (unsigned long) new_addr;
8878 +_dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope,
8879 + unsigned long rel_addr, unsigned long rel_size,
8880 + int (*reloc_fnc) (struct elf_resolve *tpnt, struct dyn_elf *scope,
8881 + ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab))
8885 + Elf32_Sym *symtab;
8888 + /* Now parse the relocation information */
8890 + rpnt = (ELF_RELOC *)(intptr_t) (rel_addr + tpnt->loadaddr);
8891 + rel_size = rel_size / sizeof(ELF_RELOC);
8893 + symtab = (Elf32_Sym *)(intptr_t) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
8894 + strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
8896 + for (i = 0; i < rel_size; i++, rpnt++) {
8899 + symtab_index = ELF32_R_SYM(rpnt->r_info);
8901 + /* When the dynamic linker bootstrapped itself, it resolved some symbols.
8902 + Make sure we do not do them again */
8903 + if (!symtab_index && tpnt->libtype == program_interpreter)
8905 + if (symtab_index && tpnt->libtype == program_interpreter &&
8906 + _dl_symbol(strtab + symtab[symtab_index].st_name))
8909 +#if defined (__SUPPORT_LD_DEBUG__)
8910 + debug_sym(symtab,strtab,symtab_index);
8911 + debug_reloc(symtab,strtab,rpnt);
8914 + res = reloc_fnc (tpnt, scope, rpnt, symtab, strtab);
8916 + if (res==0) continue;
8918 + _dl_dprintf(2, "\n%s: ",_dl_progname);
8921 + _dl_dprintf(2, "symbol '%s': ", strtab + symtab[symtab_index].st_name);
8925 + int reloc_type = ELF32_R_TYPE(rpnt->r_info);
8926 +#if defined (__SUPPORT_LD_DEBUG__)
8927 + _dl_dprintf(2, "can't handle reloc type %s\n ", _dl_reltypes(reloc_type));
8929 + _dl_dprintf(2, "can't handle reloc type %x\n", reloc_type);
8935 + _dl_dprintf(2, "can't resolve symbol\n");
8944 +_dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope,
8945 + ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)
8950 + unsigned long *reloc_addr;
8951 + unsigned long symbol_addr;
8952 +#if defined (__SUPPORT_LD_DEBUG__)
8953 + unsigned long old_val;
8956 + reloc_addr = (unsigned long *)(intptr_t) (tpnt->loadaddr + (unsigned long) rpnt->r_offset);
8957 + reloc_type = ELF32_R_TYPE(rpnt->r_info);
8958 + symtab_index = ELF32_R_SYM(rpnt->r_info);
8960 + symname = strtab + symtab[symtab_index].st_name;
8962 + if (symtab_index) {
8965 + symbol_addr = (unsigned long) _dl_find_hash(symname, scope,
8966 + (reloc_type == R_SH_JMP_SLOT ? tpnt : NULL), symbolrel);
8969 + * We want to allow undefined references to weak symbols - this might
8970 + * have been intentional. We should not be linking local symbols
8971 + * here, so all bases should be covered.
8973 + if (!symbol_addr && ELF32_ST_BIND(symtab[symtab_index].st_info) == STB_GLOBAL) {
8974 +#if defined (__SUPPORT_LD_DEBUG__)
8975 + _dl_dprintf(2, "\tglobal symbol '%s' already defined in '%s'\n",
8976 + symname, tpnt->libname);
8983 +#if defined (__SUPPORT_LD_DEBUG__)
8984 + old_val = *reloc_addr;
8986 + switch (reloc_type) {
8990 + /* handled later on */
8993 + case R_SH_GLOB_DAT:
8994 + case R_SH_JMP_SLOT:
8995 + *reloc_addr = symbol_addr + rpnt->r_addend;
8998 + *reloc_addr = symbol_addr + rpnt->r_addend -
8999 + (unsigned long) reloc_addr;
9001 + case R_SH_RELATIVE:
9002 + *reloc_addr = (unsigned long) tpnt->loadaddr + rpnt->r_addend;
9005 + return -1; /*call _dl_exit(1) */
9007 +#if defined (__SUPPORT_LD_DEBUG__)
9008 + if(_dl_debug_reloc && _dl_debug_detail)
9009 + _dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x", old_val, *reloc_addr, reloc_addr);
9017 +_dl_do_lazy_reloc (struct elf_resolve *tpnt, struct dyn_elf *scope,
9018 + ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)
9021 + unsigned long *reloc_addr;
9022 +#if defined (__SUPPORT_LD_DEBUG__)
9023 + unsigned long old_val;
9029 + reloc_addr = (unsigned long *)(intptr_t) (tpnt->loadaddr + (unsigned long) rpnt->r_offset);
9030 + reloc_type = ELF32_R_TYPE(rpnt->r_info);
9032 +#if defined (__SUPPORT_LD_DEBUG__)
9033 + old_val = *reloc_addr;
9035 + switch (reloc_type) {
9038 + case R_SH_JMP_SLOT:
9039 + *reloc_addr += (unsigned long) tpnt->loadaddr;
9042 + return -1; /*call _dl_exit(1) */
9044 +#if defined (__SUPPORT_LD_DEBUG__)
9045 + if(_dl_debug_reloc && _dl_debug_detail)
9046 + _dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x", old_val, *reloc_addr, reloc_addr);
9052 +/* This is done as a separate step, because there are cases where
9053 + information is first copied and later initialized. This results in
9054 + the wrong information being copied. Someone at Sun was complaining about
9055 + a bug in the handling of _COPY by SVr4, and this may in fact be what he
9056 + was talking about. Sigh. */
9058 +/* No, there are cases where the SVr4 linker fails to emit COPY relocs
9061 +_dl_do_copy (struct elf_resolve *tpnt, struct dyn_elf *scope,
9062 + ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)
9066 + unsigned long *reloc_addr;
9067 + unsigned long symbol_addr;
9071 + reloc_addr = (unsigned long *)(intptr_t) (tpnt->loadaddr + (unsigned long) rpnt->r_offset);
9072 + reloc_type = ELF32_R_TYPE(rpnt->r_info);
9073 + if (reloc_type != R_SH_COPY)
9075 + symtab_index = ELF32_R_SYM(rpnt->r_info);
9077 + symname = strtab + symtab[symtab_index].st_name;
9079 + if (symtab_index) {
9081 + symbol_addr = (unsigned long) _dl_find_hash(symname, scope, NULL, copyrel);
9082 + if (!symbol_addr) goof++;
9085 +#if defined (__SUPPORT_LD_DEBUG__)
9086 + if(_dl_debug_move)
9087 + _dl_dprintf(_dl_debug_file,"\n%s move %x bytes from %x to %x",
9088 + symname, symtab[symtab_index].st_size,
9089 + symbol_addr, symtab[symtab_index].st_value);
9091 + _dl_memcpy((char *) symtab[symtab_index].st_value,
9092 + (char *) symbol_addr, symtab[symtab_index].st_size);
9099 +void _dl_parse_lazy_relocation_information(struct elf_resolve *tpnt,
9100 + unsigned long rel_addr, unsigned long rel_size, int type)
9103 + (void)_dl_parse(tpnt, NULL, rel_addr, rel_size, _dl_do_lazy_reloc);
9106 +int _dl_parse_relocation_information(struct elf_resolve *tpnt,
9107 + unsigned long rel_addr, unsigned long rel_size, int type)
9110 + return _dl_parse(tpnt, tpnt->symbol_scope, rel_addr, rel_size, _dl_do_reloc);
9113 +int _dl_parse_copy_information(struct dyn_elf *xpnt, unsigned long rel_addr,
9114 + unsigned long rel_size, int type)
9117 + return _dl_parse(xpnt->dyn, xpnt->next, rel_addr, rel_size, _dl_do_copy);
9121 diff -urN uClibc/ldso-0.9.24/ldso/sh/ld_syscalls.h uClibc.ldso.24/ldso-0.9.24/ldso/sh/ld_syscalls.h
9122 --- uClibc/ldso-0.9.24/ldso/sh/ld_syscalls.h 1969-12-31 18:00:00.000000000 -0600
9123 +++ uClibc.ldso.24/ldso-0.9.24/ldso/sh/ld_syscalls.h 2002-08-09 07:20:19.000000000 -0500
9125 +/* Define the __set_errno macro as nothing so that we don't bother
9126 + * setting errno, which is important since we make system calls
9127 + * before the errno symbol is dynamicly linked. */
9129 +#define __set_errno(X) {(void)(X);}
9130 +#include "sys/syscall.h"
9132 diff -urN uClibc/ldso-0.9.24/ldso/sh/ld_sysdep.h uClibc.ldso.24/ldso-0.9.24/ldso/sh/ld_sysdep.h
9133 --- uClibc/ldso-0.9.24/ldso/sh/ld_sysdep.h 1969-12-31 18:00:00.000000000 -0600
9134 +++ uClibc.ldso.24/ldso-0.9.24/ldso/sh/ld_sysdep.h 2002-11-07 20:18:16.000000000 -0600
9137 + * Various assmbly language/system dependent hacks that are required
9138 + * so that we can minimize the amount of platform specific code.
9142 + * Define this if the system uses RELOCA.
9144 +#define ELF_USES_RELOCA
9147 + * Get a pointer to the argv array. On many platforms this can be just
9148 + * the address if the first argument, on other platforms we need to
9149 + * do something a little more subtle here.
9151 +#define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned long*) ARGS)
9154 + * Initialization sequence for a GOT.
9156 +#define INIT_GOT(GOT_BASE,MODULE) \
9158 + GOT_BASE[2] = (unsigned long) _dl_linux_resolve; \
9159 + GOT_BASE[1] = (unsigned long) (MODULE); \
9163 + * Here is a macro to perform a relocation. This is only used when
9164 + * bootstrapping the dynamic loader. RELP is the relocation that we
9165 + * are performing, REL is the pointer to the address we are relocating.
9166 + * SYMBOL is the symbol involved in the relocation, and LOAD is the
9169 +#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD) \
9170 + switch(ELF32_R_TYPE((RELP)->r_info)){ \
9171 + case R_SH_REL32: \
9172 + *(REL) = (SYMBOL) + (RELP)->r_addend \
9173 + - (unsigned long)(REL); \
9175 + case R_SH_DIR32: \
9176 + case R_SH_GLOB_DAT: \
9177 + case R_SH_JMP_SLOT: \
9178 + *(REL) = (SYMBOL) + (RELP)->r_addend; \
9180 + case R_SH_RELATIVE: \
9181 + *(REL) = (LOAD) + (RELP)->r_addend; \
9186 + SEND_STDERR("BOOTSTRAP_RELOC: unhandled reloc type "); \
9187 + SEND_NUMBER_STDERR(ELF32_R_TYPE((RELP)->r_info), 1); \
9188 + SEND_STDERR("REL, SYMBOL, LOAD: "); \
9189 + SEND_ADDRESS_STDERR(REL, 0); \
9190 + SEND_STDERR(", "); \
9191 + SEND_ADDRESS_STDERR(SYMBOL, 0); \
9192 + SEND_STDERR(", "); \
9193 + SEND_ADDRESS_STDERR(LOAD, 1); \
9199 + * Transfer control to the user's application, once the dynamic loader
9200 + * is done. This routine has to exit the current function, then
9201 + * call the _dl_elf_main function.
9204 +#define START() return _dl_elf_main;
9208 +/* Here we define the magic numbers that this dynamic loader should accept */
9210 +#define MAGIC1 EM_SH
9212 +/* Used for error messages */
9213 +#define ELF_TARGET "sh"
9215 +struct elf_resolve;
9216 +extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
9218 +static __inline__ unsigned int
9219 +_dl_urem(unsigned int n, unsigned int base)
9224 + "mov #0, r0\n\t" \
9227 + "! get one bit from the msb of the numerator into the T\n\t" \
9228 + "! bit and divide it by whats in %2. Put the answer bit\n\t" \
9229 + "! into the T bit so it can come out again at the bottom\n\t" \
9231 + "rotcl %1 ; div1 %2, r0\n\t" \
9232 + "rotcl %1 ; div1 %2, r0\n\t" \
9233 + "rotcl %1 ; div1 %2, r0\n\t" \
9234 + "rotcl %1 ; div1 %2, r0\n\t" \
9235 + "rotcl %1 ; div1 %2, r0\n\t" \
9236 + "rotcl %1 ; div1 %2, r0\n\t" \
9237 + "rotcl %1 ; div1 %2, r0\n\t" \
9238 + "rotcl %1 ; div1 %2, r0\n\t" \
9240 + "rotcl %1 ; div1 %2, r0\n\t" \
9241 + "rotcl %1 ; div1 %2, r0\n\t" \
9242 + "rotcl %1 ; div1 %2, r0\n\t" \
9243 + "rotcl %1 ; div1 %2, r0\n\t" \
9244 + "rotcl %1 ; div1 %2, r0\n\t" \
9245 + "rotcl %1 ; div1 %2, r0\n\t" \
9246 + "rotcl %1 ; div1 %2, r0\n\t" \
9247 + "rotcl %1 ; div1 %2, r0\n\t" \
9249 + "rotcl %1 ; div1 %2, r0\n\t" \
9250 + "rotcl %1 ; div1 %2, r0\n\t" \
9251 + "rotcl %1 ; div1 %2, r0\n\t" \
9252 + "rotcl %1 ; div1 %2, r0\n\t" \
9253 + "rotcl %1 ; div1 %2, r0\n\t" \
9254 + "rotcl %1 ; div1 %2, r0\n\t" \
9255 + "rotcl %1 ; div1 %2, r0\n\t" \
9256 + "rotcl %1 ; div1 %2, r0\n\t" \
9258 + "rotcl %1 ; div1 %2, r0\n\t" \
9259 + "rotcl %1 ; div1 %2, r0\n\t" \
9260 + "rotcl %1 ; div1 %2, r0\n\t" \
9261 + "rotcl %1 ; div1 %2, r0\n\t" \
9262 + "rotcl %1 ; div1 %2, r0\n\t" \
9263 + "rotcl %1 ; div1 %2, r0\n\t" \
9264 + "rotcl %1 ; div1 %2, r0\n\t" \
9265 + "rotcl %1 ; div1 %2, r0\n\t" \
9268 + : "0" (n), "r" (base)
9271 + return n - (base * res);
9274 +#define do_rem(result, n, base) ((result) = _dl_urem((n), (base)))
9276 +/* 4096 bytes alignment */
9277 +#define PAGE_ALIGN 0xfffff000
9278 +#define ADDR_ALIGN 0xfff
9279 +#define OFFS_ALIGN 0x7ffff000
9280 diff -urN uClibc/ldso-0.9.24/ldso/sh/resolve.S uClibc.ldso.24/ldso-0.9.24/ldso/sh/resolve.S
9281 --- uClibc/ldso-0.9.24/ldso/sh/resolve.S 1969-12-31 18:00:00.000000000 -0600
9282 +++ uClibc.ldso.24/ldso-0.9.24/ldso/sh/resolve.S 2002-11-07 20:18:16.000000000 -0600
9285 + * Stolen from glibc-2.2.2 by Eddie C. Dost <ecd@atecom.com>
9289 + .globl _dl_linux_resolver
9290 + .globl _dl_linux_resolve
9291 + .type _dl_linux_resolve, @function
9300 + movt r3 ! Save T flag
9304 + sts.l fpscr, @-r15
9308 + fmov.s fr11, @-r15
9309 + fmov.s fr10, @-r15
9318 +/* Note - The PLT entries have been "optimised" not to use r2. r2 is used by
9319 + GCC to return the address of large structures, so it should not be
9320 + corrupted here. This does mean however, that those PLTs does not conform
9321 + to the SH PIC ABI. That spec says that r0 contains the type of the PLT
9322 + and r2 contains the GOT id. The GNU Plt version stores the GOT id in r0 and
9323 + ignores the type. We can easily detect this difference however,
9324 + since the type will always be 0 or 8, and the GOT ids will always be
9325 + greater than or equal to 12.
9327 + Found in binutils/bfd/elf32-sh.c by Stefan Allius <allius@atecom.com>
9332 + mov r2, r0 ! link map address in r2 (SH PIC ABI)
9334 + mov r0, r4 ! link map address in r0 (GNUs PLT)
9339 + mov.l @(r0, r5),r5
9341 + mov r1, r5 ! Reloc offset
9343 + lds.l @r15+, pr ! Get register content back
9352 + fmov.s @r15+, fr10
9353 + fmov.s @r15+, fr11
9354 + lds.l @r15+, fpscr
9358 + shal r3 ! Load T flag
9364 + jmp @r0 ! Jump to function address
9370 + .long _dl_linux_resolver@GOT
9372 + .long _GLOBAL_OFFSET_TABLE_
9373 + .size _dl_linux_resolve, . - _dl_linux_resolve
9375 diff -urN uClibc/ldso-0.9.24/ldso/sparc/boot1_arch.h uClibc.ldso.24/ldso-0.9.24/ldso/sparc/boot1_arch.h
9376 --- uClibc/ldso-0.9.24/ldso/sparc/boot1_arch.h 1969-12-31 18:00:00.000000000 -0600
9377 +++ uClibc.ldso.24/ldso-0.9.24/ldso/sparc/boot1_arch.h 2002-08-08 09:35:49.000000000 -0500
9379 +/* Any assmbly language/system dependent hacks needed to setup boot1.c so it
9380 + * will work as expected and cope with whatever platform specific wierdness is
9381 + * needed for this architecture. See arm/boot1_arch.h for an example of what
9385 +#define LD_BOOT(X) void _dl_boot (X)
9386 diff -urN uClibc/ldso-0.9.24/ldso/sparc/elfinterp.c uClibc.ldso.24/ldso-0.9.24/ldso/sparc/elfinterp.c
9387 --- uClibc/ldso-0.9.24/ldso/sparc/elfinterp.c 1969-12-31 18:00:00.000000000 -0600
9388 +++ uClibc.ldso.24/ldso-0.9.24/ldso/sparc/elfinterp.c 2002-11-05 12:21:12.000000000 -0600
9390 +/* vi: set sw=4 ts=4: */
9391 +/* sparc ELF shared library loader suppport
9393 + * Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald,
9394 + * David Engel, Hongjiu Lu and Mitch D'Souza
9396 + * All rights reserved.
9398 + * Redistribution and use in source and binary forms, with or without
9399 + * modification, are permitted provided that the following conditions
9401 + * 1. Redistributions of source code must retain the above copyright
9402 + * notice, this list of conditions and the following disclaimer.
9403 + * 2. The name of the above contributors may not be
9404 + * used to endorse or promote products derived from this software
9405 + * without specific prior written permission.
9407 + * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
9408 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
9409 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
9410 + * ARE DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE
9411 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
9412 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
9413 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
9414 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
9415 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
9416 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
9420 +#if defined (__SUPPORT_LD_DEBUG__)
9421 +static const char * _dl_reltypes[] = { "R_SPARC_NONE", "R_SPARC_8",
9422 + "R_SPARC_16", "R_SPARC_32", "R_SPARC_DISP8", "R_SPARC_DISP16",
9423 + "R_SPARC_DISP32", "R_SPARC_WDISP30", "R_SPARC_WDISP22",
9424 + "R_SPARC_HI22", "R_SPARC_22", "R_SPARC_13", "R_SPARC_LO10",
9425 + "R_SPARC_GOT10", "R_SPARC_GOT13", "R_SPARC_GOT22", "R_SPARC_PC10",
9426 + "R_SPARC_PC22", "R_SPARC_WPLT30", "R_SPARC_COPY",
9427 + "R_SPARC_GLOB_DAT", "R_SPARC_JMP_SLOT", "R_SPARC_RELATIVE",
9431 +/* Program to load an ELF binary on a linux system, and run it.
9432 +References to symbols in sharable libraries can be resolved by either
9433 +an ELF sharable library or a linux style of shared library. */
9435 +/* Disclaimer: I have never seen any AT&T source code for SVr4, nor have
9436 + I ever taken any courses on internals. This program was developed using
9437 + information available through the book "UNIX SYSTEM V RELEASE 4,
9438 + Programmers guide: Ansi C and Programming Support Tools", which did
9439 + a more than adequate job of explaining everything required to get this
9442 +extern _dl_linux_resolve(void);
9444 +unsigned int _dl_linux_resolver(unsigned int reloc_entry, unsigned int * plt)
9447 + Elf32_Rela * this_reloc;
9449 + Elf32_Sym * symtab;
9450 + Elf32_Rela * rel_addr;
9451 + struct elf_resolve * tpnt;
9455 + unsigned int instr_addr;
9456 + tpnt = (struct elf_resolve *) plt[2];
9458 + rel_addr = (Elf32_Rela *) (tpnt->dynamic_info[DT_JMPREL] +
9462 + * Generate the correct relocation index into the .rela.plt section.
9464 + reloc_entry = (reloc_entry >> 12) - 0xc;
9466 + this_reloc = (Elf32_Rela *) ((char *) rel_addr + reloc_entry);
9468 + reloc_type = ELF32_R_TYPE(this_reloc->r_info);
9469 + symtab_index = ELF32_R_SYM(this_reloc->r_info);
9471 + symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
9472 + strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
9474 + _dl_dprintf(2, "tpnt = %x\n", tpnt);
9475 + _dl_dprintf(2, "reloc = %x\n", this_reloc);
9476 + _dl_dprintf(2, "symtab = %x\n", symtab);
9477 + _dl_dprintf(2, "strtab = %x\n", strtab);
9480 + if (reloc_type != R_SPARC_JMP_SLOT) {
9481 + _dl_dprintf(2, "%s: incorrect relocation type in jump relocations (%d)\n",
9482 + _dl_progname, reloc_type);
9486 + /* Address of jump instruction to fix up */
9487 + instr_addr = ((int)this_reloc->r_offset + (int)tpnt->loadaddr);
9488 + got_addr = (char **) instr_addr;
9490 + _dl_dprintf(2, "symtab_index %d\n", symtab_index);
9492 +#ifdef __SUPPORT_LD_DEBUG__
9493 + if (_dl_debug_symbols) {
9494 + _dl_dprintf(2, "Resolving symbol %s\n",
9495 + strtab + symtab[symtab_index].st_name);
9499 + /* Get the address of the GOT entry */
9500 + new_addr = _dl_find_hash(strtab + symtab[symtab_index].st_name,
9501 + tpnt->symbol_scope, tpnt, resolver);
9503 + _dl_dprintf(2, "%s: can't resolve symbol '%s'\n",
9504 + _dl_progname, strtab + symtab[symtab_index].st_name);
9508 +#if defined (__SUPPORT_LD_DEBUG__)
9509 + if ((unsigned long) got_addr < 0x40000000)
9511 + if (_dl_debug_bindings)
9513 + _dl_dprintf(_dl_debug_file, "\nresolve function: %s",
9514 + strtab + symtab[symtab_index].st_name);
9515 + if(_dl_debug_detail) _dl_dprintf(_dl_debug_file,
9516 + "\tpatch %x ==> %x @ %x", *got_addr, new_addr, got_addr);
9519 + if (!_dl_debug_nofixups) {
9520 + got_addr[1] = (char *) (0x03000000 | (((unsigned int) new_addr >> 10) & 0x3fffff));
9521 + got_addr[2] = (char *) (0x81c06000 | ((unsigned int) new_addr & 0x3ff));
9524 + got_addr[1] = (char *) (0x03000000 | (((unsigned int) new_addr >> 10) & 0x3fffff));
9525 + got_addr[2] = (char *) (0x81c06000 | ((unsigned int) new_addr & 0x3ff));
9528 + _dl_dprintf(2, "Address = %x\n",new_addr);
9531 + return (unsigned int) new_addr;
9534 +void _dl_parse_lazy_relocation_information(struct elf_resolve * tpnt, int rel_addr,
9535 + int rel_size, int type){
9540 + Elf32_Sym * symtab;
9541 + Elf32_Rela * rpnt;
9542 + unsigned int * reloc_addr;
9544 + /* Now parse the relocation information */
9545 + rpnt = (Elf32_Rela *) (rel_addr + tpnt->loadaddr);
9547 + symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
9548 + strtab = ( char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
9550 + for(i=0; i< rel_size; i += sizeof(Elf32_Rela), rpnt++){
9551 + reloc_addr = (int *) (tpnt->loadaddr + (int)rpnt->r_offset);
9552 + reloc_type = ELF32_R_TYPE(rpnt->r_info);
9553 + symtab_index = ELF32_R_SYM(rpnt->r_info);
9555 + /* When the dynamic linker bootstrapped itself, it resolved some symbols.
9556 + Make sure we do not do them again */
9557 + if(!symtab_index && tpnt->libtype == program_interpreter) continue;
9558 + if(symtab_index && tpnt->libtype == program_interpreter &&
9559 + _dl_symbol(strtab + symtab[symtab_index].st_name))
9562 + switch(reloc_type){
9563 + case R_SPARC_NONE:
9565 + case R_SPARC_JMP_SLOT:
9568 + _dl_dprintf(2, "%s: (LAZY) can't handle reloc type ", _dl_progname);
9569 +#if defined (__SUPPORT_LD_DEBUG__)
9570 + _dl_dprintf(2, "%s ", _dl_reltypes[reloc_type]);
9572 + if(symtab_index) _dl_dprintf(2, "'%s'\n",
9573 + strtab + symtab[symtab_index].st_name);
9579 +int _dl_parse_relocation_information(struct elf_resolve * tpnt, int rel_addr,
9580 + int rel_size, int type){
9585 + Elf32_Sym * symtab;
9586 + Elf32_Rela * rpnt;
9587 + unsigned int * reloc_addr;
9588 + unsigned int symbol_addr;
9590 + /* Now parse the relocation information */
9592 + rpnt = (Elf32_Rela *) (rel_addr + tpnt->loadaddr);
9594 + symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
9595 + strtab = ( char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
9597 + for(i=0; i< rel_size; i+= sizeof(Elf32_Rela), rpnt++){
9598 + reloc_addr = (int *) (tpnt->loadaddr + (int)rpnt->r_offset);
9599 + reloc_type = ELF32_R_TYPE(rpnt->r_info);
9600 + symtab_index = ELF32_R_SYM(rpnt->r_info);
9603 + if(!symtab_index && tpnt->libtype == program_interpreter) continue;
9605 + if(symtab_index) {
9607 + if(tpnt->libtype == program_interpreter &&
9608 + _dl_symbol(strtab + symtab[symtab_index].st_name))
9611 + symbol_addr = (unsigned int)
9612 + _dl_find_hash(strtab + symtab[symtab_index].st_name,
9613 + tpnt->symbol_scope,
9614 + (reloc_type == R_SPARC_JMP_SLOT ? tpnt : NULL), symbolrel);
9616 + if(!symbol_addr &&
9617 + ELF32_ST_BIND(symtab [symtab_index].st_info) == STB_GLOBAL) {
9618 + _dl_dprintf(2, "%s: can't resolve symbol '%s'\n",
9619 + _dl_progname, strtab + symtab[symtab_index].st_name);
9623 + switch(reloc_type){
9624 + case R_SPARC_NONE:
9627 + *reloc_addr = symbol_addr + rpnt->r_addend;
9629 + case R_SPARC_DISP32:
9630 + *reloc_addr = symbol_addr + rpnt->r_addend - (unsigned int) reloc_addr;
9632 + case R_SPARC_GLOB_DAT:
9633 + *reloc_addr = symbol_addr + rpnt->r_addend;
9635 + case R_SPARC_JMP_SLOT:
9636 + reloc_addr[1] = 0x03000000 | ((symbol_addr >> 10) & 0x3fffff);
9637 + reloc_addr[2] = 0x81c06000 | (symbol_addr & 0x3ff);
9639 + case R_SPARC_RELATIVE:
9640 + *reloc_addr += (unsigned int) tpnt->loadaddr + rpnt->r_addend;
9642 + case R_SPARC_HI22:
9644 + symbol_addr = tpnt->loadaddr + rpnt->r_addend;
9646 + symbol_addr += rpnt->r_addend;
9647 + *reloc_addr = (*reloc_addr & 0xffc00000)|(symbol_addr >> 10);
9649 + case R_SPARC_LO10:
9651 + symbol_addr = tpnt->loadaddr + rpnt->r_addend;
9653 + symbol_addr += rpnt->r_addend;
9654 + *reloc_addr = (*reloc_addr & ~0x3ff)|(symbol_addr & 0x3ff);
9656 + case R_SPARC_WDISP30:
9657 + *reloc_addr = (*reloc_addr & 0xc0000000)|
9658 + ((symbol_addr - (unsigned int) reloc_addr) >> 2);
9660 + case R_SPARC_COPY:
9661 +#if 0 /* This one is done later */
9662 + _dl_dprintf(2, "Doing copy for symbol ");
9663 + if(symtab_index) _dl_dprintf(2, strtab + symtab[symtab_index].st_name);
9664 + _dl_dprintf(2, "\n");
9665 + _dl_memcpy((void *) symtab[symtab_index].st_value,
9666 + (void *) symbol_addr,
9667 + symtab[symtab_index].st_size);
9671 + _dl_dprintf(2, "%s: can't handle reloc type ", _dl_progname);
9672 +#if defined (__SUPPORT_LD_DEBUG__)
9673 + _dl_dprintf(2, "%s ", _dl_reltypes[reloc_type]);
9676 + _dl_dprintf(2, "'%s'\n", strtab + symtab[symtab_index].st_name);
9685 +/* This is done as a separate step, because there are cases where
9686 + information is first copied and later initialized. This results in
9687 + the wrong information being copied. Someone at Sun was complaining about
9688 + a bug in the handling of _COPY by SVr4, and this may in fact be what he
9689 + was talking about. Sigh. */
9691 +/* No, there are cases where the SVr4 linker fails to emit COPY relocs
9694 +int _dl_parse_copy_information(struct dyn_elf * xpnt, int rel_addr,
9695 + int rel_size, int type)
9701 + Elf32_Sym * symtab;
9702 + Elf32_Rela * rpnt;
9703 + unsigned int * reloc_addr;
9704 + unsigned int symbol_addr;
9705 + struct elf_resolve *tpnt;
9707 + /* Now parse the relocation information */
9711 + rpnt = (Elf32_Rela *) (rel_addr + tpnt->loadaddr);
9713 + symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
9714 + strtab = ( char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
9716 + for(i=0; i< rel_size; i+= sizeof(Elf32_Rela), rpnt++){
9717 + reloc_addr = (int *) (tpnt->loadaddr + (int)rpnt->r_offset);
9718 + reloc_type = ELF32_R_TYPE(rpnt->r_info);
9719 + if(reloc_type != R_SPARC_COPY) continue;
9720 + symtab_index = ELF32_R_SYM(rpnt->r_info);
9722 + if(!symtab_index && tpnt->libtype == program_interpreter) continue;
9723 + if(symtab_index) {
9725 + if(tpnt->libtype == program_interpreter &&
9726 + _dl_symbol(strtab + symtab[symtab_index].st_name))
9729 + symbol_addr = (unsigned int)
9730 + _dl_find_hash(strtab + symtab[symtab_index].st_name,
9731 + xpnt->next, NULL, copyrel);
9732 + if(!symbol_addr) {
9733 + _dl_dprintf(2, "%s: can't resolve symbol '%s'\n",
9734 + _dl_progname, strtab + symtab[symtab_index].st_name);
9739 + _dl_memcpy((char *) symtab[symtab_index].st_value,
9740 + (char *) symbol_addr,
9741 + symtab[symtab_index].st_size);
9747 diff -urN uClibc/ldso-0.9.24/ldso/sparc/ld_syscalls.h uClibc.ldso.24/ldso-0.9.24/ldso/sparc/ld_syscalls.h
9748 --- uClibc/ldso-0.9.24/ldso/sparc/ld_syscalls.h 1969-12-31 18:00:00.000000000 -0600
9749 +++ uClibc.ldso.24/ldso-0.9.24/ldso/sparc/ld_syscalls.h 2002-03-19 04:43:35.000000000 -0600
9752 + * This file contains the system call macros and syscall
9753 + * numbers used by the shared library loader.
9756 +#define __NR_exit 1
9757 +#define __NR_read 3
9758 +#define __NR_write 4
9759 +#define __NR_open 5
9760 +#define __NR_close 6
9761 +#define __NR_getuid 24
9762 +#define __NR_getgid 47
9763 +#define __NR_geteuid 49
9764 +#define __NR_getegid 50
9765 +#define __NR_readlink 58
9766 +#define __NR_mmap 71
9767 +#define __NR_munmap 73
9768 +#define __NR_stat 38
9769 +#define __NR_mprotect 74
9771 +/* Here are the macros which define how this platform makes
9772 + * system calls. This particular variant does _not_ set
9773 + * errno (note how it is disabled in __syscall_return) since
9774 + * these will get called before the errno symbol is dynamicly
9777 +#define _syscall0(type,name) \
9781 +register long __g1 __asm__ ("g1") = __NR_##name; \
9782 +__asm__ __volatile__ ("t 0x10\n\t" \
9784 + "mov %%o0, %0\n\t" \
9785 + "sub %%g0, %%o0, %0\n\t" \
9790 +if (__res < -255 || __res >= 0) \
9791 + return (type) __res; \
9792 +/*errno = -__res; */\
9796 +#define _syscall1(type,name,type1,arg1) \
9797 +type name(type1 arg1) \
9800 +register long __g1 __asm__ ("g1") = __NR_##name; \
9801 +register long __o0 __asm__ ("o0") = (long)(arg1); \
9802 +__asm__ __volatile__ ("t 0x10\n\t" \
9804 + "mov %%o0, %0\n\t" \
9805 + "sub %%g0, %%o0, %0\n\t" \
9807 + : "=r" (__res), "=&r" (__o0) \
9808 + : "1" (__o0), "r" (__g1) \
9810 +if (__res < -255 || __res >= 0) \
9811 + return (type) __res; \
9812 +/*errno = -__res;*/ \
9816 +#define _syscall2(type,name,type1,arg1,type2,arg2) \
9817 +type name(type1 arg1,type2 arg2) \
9820 +register long __g1 __asm__ ("g1") = __NR_##name; \
9821 +register long __o0 __asm__ ("o0") = (long)(arg1); \
9822 +register long __o1 __asm__ ("o1") = (long)(arg2); \
9823 +__asm__ __volatile__ ("t 0x10\n\t" \
9825 + "mov %%o0, %0\n\t" \
9826 + "sub %%g0, %%o0, %0\n\t" \
9828 + : "=r" (__res), "=&r" (__o0) \
9829 + : "1" (__o0), "r" (__o1), "r" (__g1) \
9831 +if (__res < -255 || __res >= 0) \
9832 + return (type) __res; \
9833 +/*errno = -__res;*/ \
9837 +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
9838 +type name(type1 arg1,type2 arg2,type3 arg3) \
9841 +register long __g1 __asm__ ("g1") = __NR_##name; \
9842 +register long __o0 __asm__ ("o0") = (long)(arg1); \
9843 +register long __o1 __asm__ ("o1") = (long)(arg2); \
9844 +register long __o2 __asm__ ("o2") = (long)(arg3); \
9845 +__asm__ __volatile__ ("t 0x10\n\t" \
9847 + "mov %%o0, %0\n\t" \
9848 + "sub %%g0, %%o0, %0\n\t" \
9850 + : "=r" (__res), "=&r" (__o0) \
9851 + : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1) \
9853 +if (__res < -255 || __res>=0) \
9854 + return (type) __res; \
9855 +/*errno = -__res;*/ \
9859 +#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
9860 +type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
9863 +register long __g1 __asm__ ("g1") = __NR_##name; \
9864 +register long __o0 __asm__ ("o0") = (long)(arg1); \
9865 +register long __o1 __asm__ ("o1") = (long)(arg2); \
9866 +register long __o2 __asm__ ("o2") = (long)(arg3); \
9867 +register long __o3 __asm__ ("o3") = (long)(arg4); \
9868 +__asm__ __volatile__ ("t 0x10\n\t" \
9870 + "mov %%o0, %0\n\t" \
9871 + "sub %%g0, %%o0, %0\n\t" \
9873 + : "=r" (__res), "=&r" (__o0) \
9874 + : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__g1) \
9876 +if (__res < -255 || __res>=0) \
9877 + return (type) __res; \
9878 +/*errno = -__res;*/ \
9882 +#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
9884 +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
9887 +register long __g1 __asm__ ("g1") = __NR_##name; \
9888 +register long __o0 __asm__ ("o0") = (long)(arg1); \
9889 +register long __o1 __asm__ ("o1") = (long)(arg2); \
9890 +register long __o2 __asm__ ("o2") = (long)(arg3); \
9891 +register long __o3 __asm__ ("o3") = (long)(arg4); \
9892 +register long __o4 __asm__ ("o4") = (long)(arg5); \
9893 +__asm__ __volatile__ ("t 0x10\n\t" \
9895 + "mov %%o0, %0\n\t" \
9896 + "sub %%g0, %%o0, %0\n\t" \
9898 + : "=r" (__res), "=&r" (__o0) \
9899 + : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__o4), "r" (__g1) \
9901 +if (__res < -255 || __res>=0) \
9902 + return (type) __res; \
9903 +/*errno = -__res; */\
9906 diff -urN uClibc/ldso-0.9.24/ldso/sparc/ld_sysdep.h uClibc.ldso.24/ldso-0.9.24/ldso/sparc/ld_sysdep.h
9907 --- uClibc/ldso-0.9.24/ldso/sparc/ld_sysdep.h 1969-12-31 18:00:00.000000000 -0600
9908 +++ uClibc.ldso.24/ldso-0.9.24/ldso/sparc/ld_sysdep.h 2002-08-09 08:05:29.000000000 -0500
9912 + * Various assmbly language/system dependent hacks that are required
9913 + * so that we can minimize the amount of platform specific code.
9918 + * Define this if the system uses RELOCA.
9920 +#define ELF_USES_RELOCA
9923 + * Get a pointer to the argv array. On many platforms this can be just
9924 + * the address if the first argument, on other platforms we need to
9925 + * do something a little more subtle here. We assume that argc is stored
9926 + * at the word just below the argvp that we return here.
9928 +#define GET_ARGV(ARGVP, ARGS) __asm__("\tadd %%fp,68,%0\n" : "=r" (ARGVP));
9931 + * Initialization sequence for a GOT. For the Sparc, this points to the
9932 + * PLT, and we need to initialize a couple of the slots. The PLT should
9935 + * save %sp, -64, %sp
9936 + * call _dl_linux_resolve
9938 + * .word implementation_dependent
9940 +#define INIT_GOT(GOT_BASE,MODULE) \
9942 + GOT_BASE[0] = 0x9de3bfc0; /* save %sp, -64, %sp */ \
9943 + GOT_BASE[1] = 0x40000000 | (((unsigned int) _dl_linux_resolve - (unsigned int) GOT_BASE - 4) >> 2); \
9944 + GOT_BASE[2] = 0x01000000; /* nop */ \
9945 + GOT_BASE[3] = (int) MODULE; \
9949 + * Here is a macro to perform a relocation. This is only used when
9950 + * bootstrapping the dynamic loader.
9952 +#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD) \
9953 + switch(ELF32_R_TYPE((RELP)->r_info)) { \
9954 + case R_SPARC_32: \
9955 + *REL = SYMBOL + (RELP)->r_addend; \
9957 + case R_SPARC_GLOB_DAT: \
9958 + *REL = SYMBOL + (RELP)->r_addend; \
9960 + case R_SPARC_JMP_SLOT: \
9961 + REL[1] = 0x03000000 | ((SYMBOL >> 10) & 0x3fffff); \
9962 + REL[2] = 0x81c06000 | (SYMBOL & 0x3ff); \
9964 + case R_SPARC_NONE: \
9966 + case R_SPARC_WDISP30: \
9968 + case R_SPARC_RELATIVE: \
9969 + *REL += (unsigned int) LOAD + (RELP)->r_addend; \
9977 + * Transfer control to the user's application, once the dynamic loader
9978 + * is done. The crt calls atexit with $g1 if not null, so we need to
9979 + * ensure that it contains NULL.
9983 + __asm__ volatile ( \
9984 + "add %%g0,%%g0,%%g1\n\t" \
9985 + "jmpl %0, %%o7\n\t" \
9986 + "restore %%g0,%%g0,%%g0\n\t" \
9987 + : /*"=r" (status) */ : \
9988 + "r" (_dl_elf_main): "g1", "o0", "o1")
9992 +/* Here we define the magic numbers that this dynamic loader should accept */
9994 +#define MAGIC1 EM_SPARC
9996 +/* Used for error messages */
9997 +#define ELF_TARGET "Sparc"
9999 +#ifndef COMPILE_ASM
10000 +extern unsigned int _dl_linux_resolver(unsigned int reloc_entry,
10001 + unsigned int * i);
10005 + * Define this if you want a dynamic loader that works on Solaris.
10007 +#define SOLARIS_COMPATIBLE
10009 +#define do_rem(result, n, base) result = (n % base)
10012 + * dbx wants the binder to have a specific name. Mustn't disappoint it.
10014 +#ifdef SOLARIS_COMPATIBLE
10015 +#define _dl_linux_resolve _elf_rtbndr
10018 +/* 4096 bytes alignment */
10019 +#define PAGE_ALIGN 0xfffff000
10020 +#define ADDR_ALIGN 0xfff
10021 +#define OFFS_ALIGN 0x7ffff000
10022 diff -urN uClibc/ldso-0.9.24/ldso/sparc/resolve.S uClibc.ldso.24/ldso-0.9.24/ldso/sparc/resolve.S
10023 --- uClibc/ldso-0.9.24/ldso/sparc/resolve.S 1969-12-31 18:00:00.000000000 -0600
10024 +++ uClibc.ldso.24/ldso-0.9.24/ldso/sparc/resolve.S 2002-01-11 13:57:41.000000000 -0600
10027 + * These are various helper routines that are needed to run an ELF image.
10029 +#define COMPILE_ASM
10030 +#include "ld_sysdep.h"
10035 +.globl _dl_linux_resolve
10036 +_dl_linux_resolve:
10038 + * Call the resolver - pass the address of the PLT so that we can
10039 + * figure out which module we are in.
10042 + call _dl_linux_resolver
10049 + .type _dl_linux_resolve,#function
10050 + .size _dl_linux_resolve,.LFE2-_dl_linux_resolve
10051 diff -urN uClibc/ldso-0.9.24/libdl/.cvsignore uClibc.ldso.24/ldso-0.9.24/libdl/.cvsignore
10052 --- uClibc/ldso-0.9.24/libdl/.cvsignore 1969-12-31 18:00:00.000000000 -0600
10053 +++ uClibc.ldso.24/ldso-0.9.24/libdl/.cvsignore 2001-04-26 11:12:47.000000000 -0500
10057 diff -urN uClibc/ldso-0.9.24/libdl/Makefile uClibc.ldso.24/ldso-0.9.24/libdl/Makefile
10058 --- uClibc/ldso-0.9.24/libdl/Makefile 1969-12-31 18:00:00.000000000 -0600
10059 +++ uClibc.ldso.24/ldso-0.9.24/libdl/Makefile 2004-03-01 03:05:53.000000000 -0600
10061 +# Makefile for uClibc
10063 +# Copyright (C) 2000 by Lineo, inc.
10064 +# Copyright (C) 2000-2002 Erik Andersen <andersen@uclibc.org>
10066 +# This program is free software; you can redistribute it and/or modify it under
10067 +# the terms of the GNU Library General Public License as published by the Free
10068 +# Software Foundation; either version 2 of the License, or (at your option) any
10071 +# This program is distributed in the hope that it will be useful, but WITHOUT
10072 +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10073 +# FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more
10076 +# You should have received a copy of the GNU Library General Public License
10077 +# along with this program; if not, write to the Free Software Foundation, Inc.,
10078 +# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
10082 +include $(TOPDIR)Rules.mak
10084 +XXFLAGS=$(XWARNINGS) $(OPTIMIZATION) $(XARCH_CFLAGS) $(CPU_CFLAGS) \
10085 + -DUCLIBC_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" \
10086 + -fno-builtin -nostdinc -D_LIBC -I$(TOPDIR)ldso-0.9.24/include -I. -I$(TOPDIR)include
10088 +ifeq ($(DODEBUG),y)
10089 +XXFLAGS=$(XWARNINGS) -O0 -g3 $(XARCH_CFLAGS) $(CPU_CFLAGS) \
10090 + -DUCLIBC_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" \
10091 + -fno-builtin -nostdinc -D_LIBC -I$(TOPDIR)ldso-0.9.24/include -I. -I$(TOPDIR)include
10094 +XXFLAGS+=$(shell $(CC) -print-search-dirs | sed -ne "s/install: *\(.*\)/-I\1include/gp")
10095 +XXFLAGS_NOPIC:=$(XXFLAGS)
10097 + XXFLAGS += $(PICFLAG) -D__LIBDL_SHARED__
10099 +ifeq ($(strip $(SUPPORT_LD_DEBUG)),y)
10100 +XXFLAGS+=-D__SUPPORT_LD_DEBUG__
10104 +LIBDL_PIC=libdl_pic.a
10105 +LIBDL_SHARED=libdl.so
10106 +LIBDL_SHARED_FULLNAME=libdl-$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBLEVEL).so
10110 +PIC_OBJS=dlib_pic.o
10112 +all: $(OBJS) $(LIBDL) shared
10114 +$(LIBDL): ar-target
10116 +ar-target: $(OBJS) $(PIC_OBJS)
10117 + $(AR) $(ARFLAGS) $(LIBDL) ../ldso/$(TARGET_ARCH)/resolve.o $(OBJS)
10118 + $(AR) $(ARFLAGS) $(LIBDL_PIC) $(PIC_OBJS)
10119 + $(INSTALL) -d $(TOPDIR)lib
10120 + $(RM) $(TOPDIR)lib/$(LIBDL)
10121 + $(INSTALL) -m 644 $(LIBDL) $(TOPDIR)lib
10125 + $(CC) $(XXFLAGS_NOPIC) -c dlib.c -o dlib.o
10126 + $(STRIPTOOL) -x -R .note -R .comment $*.o
10128 +dlib_pic.o: dlib.c
10129 + $(CC) $(XXFLAGS) -c dlib.c -o dlib_pic.o
10130 + $(STRIPTOOL) -x -R .note -R .comment $*.o
10135 + $(LD) $(LDFLAGS) -soname=$(LIBDL_SHARED).$(MAJOR_VERSION) \
10136 + -o $(LIBDL_SHARED_FULLNAME) --whole-archive $(LIBDL_PIC) \
10137 + --no-whole-archive $(TOPDIR)/libc/misc/internals/interp.o \
10138 + -L$(TOPDIR)/lib -lc $(LDADD_LIBFLOAT) $(LIBGCC);
10139 + $(INSTALL) -d $(TOPDIR)lib
10140 + $(RM) $(TOPDIR)lib/$(LIBDL_SHARED_FULLNAME) $(TOPDIR)lib/$(LIBDL_SHARED).$(MAJOR_VERSION)
10141 + $(INSTALL) -m 644 $(LIBDL_SHARED_FULLNAME) $(TOPDIR)lib
10142 + $(LN) -sf $(LIBDL_SHARED_FULLNAME) $(TOPDIR)lib/$(LIBDL_SHARED)
10143 + $(LN) -sf $(LIBDL_SHARED_FULLNAME) $(TOPDIR)lib/$(LIBDL_SHARED).$(MAJOR_VERSION)
10146 + $(RM) .depend $(LIBDL_SHARED)* $(LIBDL_SHARED_FULLNAME) core *.o *.a *.s *.i tmp_make foo *~
10147 diff -urN uClibc/ldso-0.9.24/libdl/dlib.c uClibc.ldso.24/ldso-0.9.24/libdl/dlib.c
10148 --- uClibc/ldso-0.9.24/libdl/dlib.c 1969-12-31 18:00:00.000000000 -0600
10149 +++ uClibc.ldso.24/ldso-0.9.24/libdl/dlib.c 2004-03-01 03:04:42.000000000 -0600
10154 + * Functions required for dlopen et. al.
10160 +/* The public interfaces */
10161 +void *dlopen(const char *, int) __attribute__ ((__weak__, __alias__ ("_dlopen")));
10162 +int dlclose(void *) __attribute__ ((__weak__, __alias__ ("_dlclose")));
10163 +void *dlsym(void *, const char *) __attribute__ ((__weak__, __alias__ ("_dlsym")));
10164 +const char *dlerror(void) __attribute__ ((__weak__, __alias__ ("_dlerror")));
10165 +int dladdr(void *, Dl_info *) __attribute__ ((__weak__, __alias__ ("_dladdr")));
10166 +void _dlinfo(void);
10169 +#ifdef __LIBDL_SHARED__
10170 +/* This is a real hack. We need access to the dynamic linker, but we
10171 +also need to make it possible to link against this library without any
10172 +unresolved externals. We provide these weak symbols to make the link
10173 +possible, but at run time the normal symbols are accessed. */
10174 +static void __attribute__ ((unused)) foobar(void)
10176 + const char msg[]="libdl library not correctly linked\n";
10177 + _dl_write(2, msg, _dl_strlen(msg));
10181 +static int __attribute__ ((unused)) foobar1 = (int) foobar; /* Use as pointer */
10182 +extern void _dl_dprintf(int, const char *, ...) __attribute__ ((__weak__, __alias__ ("foobar")));
10183 +extern char *_dl_find_hash(const char *, struct dyn_elf *, struct elf_resolve *, enum caller_type)
10184 + __attribute__ ((__weak__, __alias__ ("foobar")));
10185 +extern struct elf_resolve * _dl_load_shared_library(int, struct dyn_elf **, struct elf_resolve *, char *)
10186 + __attribute__ ((__weak__, __alias__ ("foobar")));
10187 +extern struct elf_resolve * _dl_check_if_named_library_is_loaded(const char *full_libname)
10188 + __attribute__ ((__weak__, __alias__ ("foobar")));
10189 +extern int _dl_fixup(struct elf_resolve *tpnt, int lazy)
10190 + __attribute__ ((__weak__, __alias__ ("foobar")));
10191 +extern int _dl_copy_fixups(struct dyn_elf * tpnt)
10192 + __attribute__ ((__weak__, __alias__ ("foobar")));
10194 +extern void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt)
10195 + __attribute__ ((__weak__, __alias__ ("foobar")));
10198 +int _dl_map_cache(void) __attribute__ ((__weak__, __alias__ ("foobar")));
10199 +int _dl_unmap_cache(void) __attribute__ ((__weak__, __alias__ ("foobar")));
10202 +extern struct dyn_elf *_dl_symbol_tables __attribute__ ((__weak__, __alias__ ("foobar1")));
10203 +extern struct dyn_elf *_dl_handles __attribute__ ((__weak__, __alias__ ("foobar1")));
10204 +extern struct elf_resolve *_dl_loaded_modules __attribute__ ((__weak__, __alias__ ("foobar1")));
10205 +extern struct r_debug *_dl_debug_addr __attribute__ ((__weak__, __alias__ ("foobar1")));
10206 +extern unsigned long _dl_error_number __attribute__ ((__weak__, __alias__ ("foobar1")));
10207 +extern void *(*_dl_malloc_function)(size_t) __attribute__ ((__weak__, __alias__ ("foobar1")));
10208 +#ifdef __SUPPORT_LD_DEBUG__
10209 +extern char *_dl_debug __attribute__ ((__weak__, __alias__ ("foobar1")));
10210 +extern char *_dl_debug_symbols __attribute__ ((__weak__, __alias__ ("foobar1")));
10211 +extern char *_dl_debug_move __attribute__ ((__weak__, __alias__ ("foobar1")));
10212 +extern char *_dl_debug_reloc __attribute__ ((__weak__, __alias__ ("foobar1")));
10213 +extern char *_dl_debug_detail __attribute__ ((__weak__, __alias__ ("foobar1")));
10214 +extern char *_dl_debug_nofixups __attribute__ ((__weak__, __alias__ ("foobar1")));
10215 +extern char *_dl_debug_bindings __attribute__ ((__weak__, __alias__ ("foobar1")));
10216 +extern int _dl_debug_file __attribute__ ((__weak__, __alias__ ("foobar1")));
10219 +#else /* __LIBDL_SHARED__ */
10221 +#ifdef __SUPPORT_LD_DEBUG__
10222 +char *_dl_debug = 0;
10223 +char *_dl_debug_symbols = 0;
10224 +char *_dl_debug_move = 0;
10225 +char *_dl_debug_reloc = 0;
10226 +char *_dl_debug_detail = 0;
10227 +char *_dl_debug_nofixups = 0;
10228 +char *_dl_debug_bindings = 0;
10229 +int _dl_debug_file = 2;
10231 +char *_dl_library_path = 0;
10232 +char *_dl_ldsopath = 0;
10233 +struct r_debug *_dl_debug_addr = NULL;
10234 +static char *_dl_malloc_addr, *_dl_mmap_zero;
10235 +#include "../ldso/_dl_progname.h" /* Pull in the name of ld.so */
10236 +#include "../ldso/hash.c"
10237 +#define _dl_trace_loaded_objects 0
10238 +#include "../ldso/readelflib1.c"
10239 +void *(*_dl_malloc_function) (size_t size);
10240 +int _dl_fixup(struct elf_resolve *tpnt, int lazy);
10243 +static int do_dlclose(void *, int need_fini);
10246 +static const char *dl_error_names[] = {
10248 + "File not found",
10249 + "Unable to open /dev/zero",
10250 + "Not an ELF file",
10251 +#if defined (__i386__)
10252 + "Not i386 binary",
10253 +#elif defined (__sparc__)
10254 + "Not sparc binary",
10255 +#elif defined (__mc68000__)
10256 + "Not m68k binary",
10258 + "Unrecognized binary type",
10260 + "Not an ELF shared library",
10261 + "Unable to mmap file",
10262 + "No dynamic section",
10263 +#ifdef ELF_USES_RELOCA
10264 + "Unable to process REL relocs",
10266 + "Unable to process RELA relocs",
10269 + "Unable to resolve symbol"
10272 +static void __attribute__ ((destructor)) dl_cleanup(void)
10274 + struct dyn_elf *d;
10276 + for (d = _dl_handles; d; d = d->next_handle)
10277 + if (d->dyn->libtype == loaded_file && d->dyn->dynamic_info[DT_FINI]) {
10278 + (* ((int (*)(void)) (d->dyn->loadaddr + d->dyn->dynamic_info[DT_FINI]))) ();
10279 + d->dyn->dynamic_info[DT_FINI] = 0;
10283 +void *_dlopen(const char *libname, int flag)
10285 + struct elf_resolve *tpnt, *tfrom, *tcurr;
10286 + struct dyn_elf *dyn_chain, *rpnt = NULL;
10287 + struct dyn_elf *dpnt;
10288 + static int dl_init = 0;
10290 + struct elf_resolve *tpnt1;
10291 + void (*dl_brk) (void);
10293 + /* A bit of sanity checking... */
10294 + if (!(flag & (RTLD_LAZY|RTLD_NOW))) {
10295 + _dl_error_number = LD_BAD_HANDLE;
10299 + from = (ElfW(Addr)) __builtin_return_address(0);
10301 + /* Have the dynamic linker use the regular malloc function now */
10304 + _dl_malloc_function = malloc;
10307 + /* Cover the trivial case first */
10309 + return _dl_symbol_tables;
10314 + * Try and locate the module we were called from - we
10315 + * need this so that we get the correct RPATH. Note that
10316 + * this is the current behavior under Solaris, but the
10317 + * ABI+ specifies that we should only use the RPATH from
10318 + * the application. Thus this may go away at some time
10322 + for (dpnt = _dl_symbol_tables; dpnt; dpnt = dpnt->next) {
10323 + tpnt = dpnt->dyn;
10324 + if (tpnt->loadaddr < from
10325 + && (tfrom == NULL || tfrom->loadaddr < tpnt->loadaddr))
10329 + /* Try to load the specified library */
10330 +#ifdef __SUPPORT_LD_DEBUG__
10332 + _dl_dprintf(_dl_debug_file, "Trying to dlopen '%s'\n", (char*)libname);
10334 + tpnt = _dl_load_shared_library(0, &rpnt, tfrom, (char*)libname);
10335 + if (tpnt == NULL) {
10336 + _dl_unmap_cache();
10340 + dyn_chain = (struct dyn_elf *) malloc(sizeof(struct dyn_elf));
10341 + _dl_memset(dyn_chain, 0, sizeof(struct dyn_elf));
10342 + dyn_chain->dyn = tpnt;
10343 + dyn_chain->flags = flag;
10344 + if (!tpnt->symbol_scope)
10345 + tpnt->symbol_scope = dyn_chain;
10347 + dyn_chain->next_handle = _dl_handles;
10348 + _dl_handles = rpnt = dyn_chain;
10350 + if (tpnt->init_flag & INIT_FUNCS_CALLED) {
10351 + /* If the init and fini stuff has already been run, that means
10352 + * the dlopen'd library has already been loaded, and nothing
10353 + * further needs to be done. */
10354 + return (void *) dyn_chain;
10358 +#ifdef __SUPPORT_LD_DEBUG__
10360 + _dl_dprintf(_dl_debug_file, "Looking for needed libraries\n");
10363 + for (tcurr = tpnt; tcurr; tcurr = tcurr->next)
10367 + for (dpnt = (Elf32_Dyn *) tcurr->dynamic_addr; dpnt->d_tag; dpnt++) {
10368 + if (dpnt->d_tag == DT_NEEDED) {
10371 + lpntstr = (char*) (tcurr->loadaddr + tcurr->dynamic_info[DT_STRTAB] +
10372 + dpnt->d_un.d_val);
10373 + name = _dl_get_last_path_component(lpntstr);
10375 +#ifdef __SUPPORT_LD_DEBUG__
10377 + _dl_dprintf(_dl_debug_file, "Trying to load '%s', needed by '%s'\n",
10378 + lpntstr, tcurr->libname);
10381 + if (!(tpnt1 = _dl_load_shared_library(0, &rpnt, tcurr, lpntstr))) {
10386 +//FIXME: Enabling this is _so_ wrong....
10387 + /* We need global symbol resolution for everything
10388 + * in the dependent chain */
10389 + dyn_chain->flags |= RTLD_GLOBAL;
10392 + rpnt->next = (struct dyn_elf *) malloc(sizeof(struct dyn_elf));
10393 + _dl_memset (rpnt->next, 0, sizeof (struct dyn_elf));
10394 + rpnt = rpnt->next;
10395 + if (!tpnt1->symbol_scope) tpnt1->symbol_scope = rpnt;
10396 + rpnt->dyn = tpnt1;
10403 + * OK, now attach the entire chain at the end
10405 + rpnt->next = _dl_symbol_tables;
10409 + * Relocation of the GOT entries for MIPS have to be done
10410 + * after all the libraries have been loaded.
10412 + _dl_perform_mips_global_got_relocations(tpnt);
10415 +#ifdef __SUPPORT_LD_DEBUG__
10417 + _dl_dprintf(_dl_debug_file, "Beginning dlopen relocation fixups\n");
10420 + * OK, now all of the kids are tucked into bed in their proper addresses.
10421 + * Now we go through and look for REL and RELA records that indicate fixups
10422 + * to the GOT tables. We need to do this in reverse order so that COPY
10423 + * directives work correctly */
10424 + if (_dl_fixup(dyn_chain->dyn, dyn_chain->flags))
10427 +#ifdef __SUPPORT_LD_DEBUG__
10429 + _dl_dprintf(_dl_debug_file, "Beginning dlopen copy fixups\n");
10431 + if (_dl_symbol_tables) {
10432 + if (_dl_copy_fixups(dyn_chain))
10437 + /* TODO: Should we set the protections of all pages back to R/O now ? */
10440 + /* Notify the debugger we have added some objects. */
10441 + _dl_debug_addr->r_state = RT_ADD;
10442 + if (_dl_debug_addr) {
10443 + dl_brk = (void (*)(void)) _dl_debug_addr->r_brk;
10444 + if (dl_brk != NULL) {
10445 + _dl_debug_addr->r_state = RT_ADD;
10448 + _dl_debug_addr->r_state = RT_CONSISTENT;
10453 +#if 0 //def __SUPPORT_LD_DEBUG__
10458 +#ifdef __LIBDL_SHARED__
10459 + /* Find the last library so we can run things in the right order */
10460 + for (tpnt = dyn_chain->dyn; tpnt->next!=NULL; tpnt = tpnt->next)
10463 + /* Run the ctors and set up the dtors */
10464 + for (; tpnt != dyn_chain->dyn->prev; tpnt=tpnt->prev)
10466 + /* Apparently crt1 for the application is responsible for handling this.
10467 + * We only need to run the init/fini for shared libraries
10469 + if (tpnt->libtype == program_interpreter)
10471 + if (tpnt->libtype == elf_executable)
10473 + if (tpnt->init_flag & INIT_FUNCS_CALLED)
10475 + tpnt->init_flag |= INIT_FUNCS_CALLED;
10477 + if (tpnt->dynamic_info[DT_INIT]) {
10478 + void (*dl_elf_func) (void);
10479 + dl_elf_func = (void (*)(void)) (tpnt->loadaddr + tpnt->dynamic_info[DT_INIT]);
10480 + if (dl_elf_func && *dl_elf_func != NULL) {
10481 +#ifdef __SUPPORT_LD_DEBUG__
10483 + _dl_dprintf(2, "running ctors for library %s at '%x'\n", tpnt->libname, dl_elf_func);
10485 + (*dl_elf_func) ();
10488 + if (tpnt->dynamic_info[DT_FINI]) {
10489 + void (*dl_elf_func) (void);
10490 + dl_elf_func = (void (*)(void)) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI]);
10491 + if (dl_elf_func && *dl_elf_func != NULL) {
10492 +#ifdef __SUPPORT_LD_DEBUG__
10494 + _dl_dprintf(2, "setting up dtors for library %s at '%x'\n", tpnt->libname, dl_elf_func);
10496 + atexit(dl_elf_func);
10501 + return (void *) dyn_chain;
10504 + /* Something went wrong. Clean up and return NULL. */
10505 + _dl_unmap_cache();
10506 + do_dlclose(dyn_chain, 0);
10510 +void *_dlsym(void *vhandle, const char *name)
10512 + struct elf_resolve *tpnt, *tfrom;
10513 + struct dyn_elf *handle;
10515 + struct dyn_elf *rpnt;
10518 + handle = (struct dyn_elf *) vhandle;
10520 + /* First of all verify that we have a real handle
10521 + of some kind. Return NULL if not a valid handle. */
10523 + if (handle == NULL)
10524 + handle = _dl_symbol_tables;
10525 + else if (handle != RTLD_NEXT && handle != _dl_symbol_tables) {
10526 + for (rpnt = _dl_handles; rpnt; rpnt = rpnt->next_handle)
10527 + if (rpnt == handle)
10530 + _dl_error_number = LD_BAD_HANDLE;
10533 + } else if (handle == RTLD_NEXT) {
10535 + * Try and locate the module we were called from - we
10536 + * need this so that we know where to start searching
10537 + * from. We never pass RTLD_NEXT down into the actual
10538 + * dynamic loader itself, as it doesn't know
10539 + * how to properly treat it.
10541 + from = (ElfW(Addr)) __builtin_return_address(0);
10544 + for (rpnt = _dl_symbol_tables; rpnt; rpnt = rpnt->next) {
10545 + tpnt = rpnt->dyn;
10546 + if (tpnt->loadaddr < from
10547 + && (tfrom == NULL || tfrom->loadaddr < tpnt->loadaddr)) {
10549 + handle = rpnt->next;
10554 + ret = _dl_find_hash((char*)name, handle, NULL, copyrel);
10560 + _dl_error_number = LD_NO_SYMBOL;
10564 +int _dlclose(void *vhandle)
10566 + return do_dlclose(vhandle, 1);
10569 +static int do_dlclose(void *vhandle, int need_fini)
10571 + struct dyn_elf *rpnt, *rpnt1;
10572 + struct dyn_elf *spnt, *spnt1;
10573 + ElfW(Phdr) *ppnt;
10574 + struct elf_resolve *tpnt;
10575 + int (*dl_elf_fini) (void);
10576 + void (*dl_brk) (void);
10577 + struct dyn_elf *handle;
10578 + unsigned int end;
10581 + handle = (struct dyn_elf *) vhandle;
10583 + for (rpnt = _dl_handles; rpnt; rpnt = rpnt->next_handle) {
10584 + if (rpnt == handle) {
10591 + _dl_error_number = LD_BAD_HANDLE;
10595 + /* OK, this is a valid handle - now close out the file.
10596 + * We check if we need to call fini () on the handle. */
10597 + spnt = need_fini ? handle : handle->next;
10598 + for (; spnt; spnt = spnt1) {
10599 + spnt1 = spnt->next;
10601 + /* We appended the module list to the end - when we get back here,
10602 + quit. The access counts were not adjusted to account for being here. */
10603 + if (spnt == _dl_symbol_tables)
10605 + if (spnt->dyn->usage_count == 1
10606 + && spnt->dyn->libtype == loaded_file) {
10607 + tpnt = spnt->dyn;
10608 + /* Apparently crt1 for the application is responsible for handling this.
10609 + * We only need to run the init/fini for shared libraries
10612 + if (tpnt->dynamic_info[DT_FINI]) {
10613 + dl_elf_fini = (int (*)(void)) (tpnt->loadaddr +
10614 + tpnt->dynamic_info[DT_FINI]);
10615 + (*dl_elf_fini) ();
10620 + rpnt1->next_handle = rpnt->next_handle;
10622 + _dl_handles = rpnt->next_handle;
10624 + /* OK, this is a valid handle - now close out the file */
10625 + for (rpnt = handle; rpnt; rpnt = rpnt1) {
10626 + rpnt1 = rpnt->next;
10628 + /* We appended the module list to the end - when we get back here,
10629 + quit. The access counts were not adjusted to account for being here. */
10630 + if (rpnt == _dl_symbol_tables)
10633 + rpnt->dyn->usage_count--;
10634 + if (rpnt->dyn->usage_count == 0
10635 + && rpnt->dyn->libtype == loaded_file) {
10636 + tpnt = rpnt->dyn;
10637 + /* Apparently crt1 for the application is responsible for handling this.
10638 + * We only need to run the init/fini for shared libraries
10642 + /* We have to do this above, before we start closing objects.
10643 + * Otherwise when the needed symbols for _fini handling are
10644 + * resolved a coredump would occur. Rob Ryan (robr@cmu.edu)*/
10645 + if (tpnt->dynamic_info[DT_FINI]) {
10646 + dl_elf_fini = (int (*)(void)) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI]);
10647 + (*dl_elf_fini) ();
10651 + for (i = 0, ppnt = rpnt->dyn->ppnt;
10652 + i < rpnt->dyn->n_phent; ppnt++, i++) {
10653 + if (ppnt->p_type != PT_LOAD)
10655 + if (end < ppnt->p_vaddr + ppnt->p_memsz)
10656 + end = ppnt->p_vaddr + ppnt->p_memsz;
10658 + _dl_munmap((void*)rpnt->dyn->loadaddr, end);
10659 + /* Next, remove rpnt->dyn from the loaded_module list */
10660 + if (_dl_loaded_modules == rpnt->dyn) {
10661 + _dl_loaded_modules = rpnt->dyn->next;
10662 + if (_dl_loaded_modules)
10663 + _dl_loaded_modules->prev = 0;
10665 + for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next)
10666 + if (tpnt->next == rpnt->dyn) {
10667 + tpnt->next = tpnt->next->next;
10669 + tpnt->next->prev = tpnt;
10672 + free(rpnt->dyn->libname);
10679 + if (_dl_debug_addr) {
10680 + dl_brk = (void (*)(void)) _dl_debug_addr->r_brk;
10681 + if (dl_brk != NULL) {
10682 + _dl_debug_addr->r_state = RT_DELETE;
10685 + _dl_debug_addr->r_state = RT_CONSISTENT;
10693 +const char *_dlerror(void)
10695 + const char *retval;
10697 + if (!_dl_error_number)
10699 + retval = dl_error_names[_dl_error_number];
10700 + _dl_error_number = 0;
10705 + * Dump information to stderrr about the current loaded modules
10707 +static char *type[] = { "Lib", "Exe", "Int", "Mod" };
10709 +void _dlinfo(void)
10711 + struct elf_resolve *tpnt;
10712 + struct dyn_elf *rpnt, *hpnt;
10714 + _dl_dprintf(2, "List of loaded modules\n");
10715 + /* First start with a complete list of all of the loaded files. */
10716 + for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
10717 + _dl_dprintf(2, "\t%x %x %x %s %d %s\n",
10718 + (unsigned) tpnt->loadaddr, (unsigned) tpnt,
10719 + (unsigned) tpnt->symbol_scope,
10720 + type[tpnt->libtype],
10721 + tpnt->usage_count, tpnt->libname);
10724 + /* Next dump the module list for the application itself */
10725 + _dl_dprintf(2, "\nModules for application (%x):\n",
10726 + (unsigned) _dl_symbol_tables);
10727 + for (rpnt = _dl_symbol_tables; rpnt; rpnt = rpnt->next)
10728 + _dl_dprintf(2, "\t%x %s\n", (unsigned) rpnt->dyn, rpnt->dyn->libname);
10730 + for (hpnt = _dl_handles; hpnt; hpnt = hpnt->next_handle) {
10731 + _dl_dprintf(2, "Modules for handle %x\n", (unsigned) hpnt);
10732 + for (rpnt = hpnt; rpnt; rpnt = rpnt->next)
10733 + _dl_dprintf(2, "\t%x %s\n", (unsigned) rpnt->dyn,
10734 + rpnt->dyn->libname);
10738 +int _dladdr(void *__address, Dl_info * __dlip)
10740 + struct elf_resolve *pelf;
10741 + struct elf_resolve *rpnt;
10746 + * Try and locate the module address is in
10751 + _dl_dprintf(2, "dladdr( %x, %x )\n", __address, __dlip);
10754 + for (rpnt = _dl_loaded_modules; rpnt; rpnt = rpnt->next) {
10755 + struct elf_resolve *tpnt;
10759 + _dl_dprintf(2, "Module \"%s\" at %x\n",
10760 + tpnt->libname, tpnt->loadaddr);
10762 + if (tpnt->loadaddr < (ElfW(Addr)) __address
10763 + && (pelf == NULL || pelf->loadaddr < tpnt->loadaddr)) {
10773 + * Try and locate the symbol of address
10778 + Elf32_Sym *symtab;
10785 + symtab = (Elf32_Sym *) (pelf->dynamic_info[DT_SYMTAB] + pelf->loadaddr);
10786 + strtab = (char *) (pelf->dynamic_info[DT_STRTAB] + pelf->loadaddr);
10789 + for (hn = 0; hn < pelf->nbucket; hn++) {
10790 + for (si = pelf->elf_buckets[hn]; si; si = pelf->chains[si]) {
10791 + ElfW(Addr) symbol_addr;
10793 + symbol_addr = pelf->loadaddr + symtab[si].st_value;
10794 + if (symbol_addr <= (ElfW(Addr))__address && (!sf || sa < symbol_addr)) {
10795 + sa = symbol_addr;
10800 + _dl_dprintf(2, "Symbol \"%s\" at %x\n",
10801 + strtab + symtab[si].st_name, symbol_addr);
10807 + __dlip->dli_fname = pelf->libname;
10808 + __dlip->dli_fbase = (void *)pelf->loadaddr;
10809 + __dlip->dli_sname = strtab + symtab[sn].st_name;
10810 + __dlip->dli_saddr = (void *)sa;
10815 diff -urN uClibc/ldso-0.9.24/man/Makefile uClibc.ldso.24/ldso-0.9.24/man/Makefile
10816 --- uClibc/ldso-0.9.24/man/Makefile 1969-12-31 18:00:00.000000000 -0600
10817 +++ uClibc.ldso.24/ldso-0.9.24/man/Makefile 2003-10-18 05:18:37.000000000 -0500
10819 +# Makefile for uClibc
10821 +# Copyright (C) 2000,2001 Erik Andersen <andersen@uclibc.org>
10823 +# This program is free software; you can redistribute it and/or modify it under
10824 +# the terms of the GNU Library General Public License as published by the Free
10825 +# Software Foundation; either version 2 of the License, or (at your option) any
10828 +# This program is distributed in the hope that it will be useful, but WITHOUT
10829 +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10830 +# FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more
10833 +# You should have received a copy of the GNU Library General Public License
10834 +# along with this program; if not, write to the Free Software Foundation, Inc.,
10835 +# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
10837 +# Derived in part from the Linux-8086 C library, the GNU C Library, and several
10838 +# other sundry sources. Files within this library are copyright by their
10839 +# respective copyright holders.
10841 +include ../Config.mk
10847 +ld.so.info: ld.so.texi
10852 diff -urN uClibc/ldso-0.9.24/man/dlopen.3 uClibc.ldso.24/ldso-0.9.24/man/dlopen.3
10853 --- uClibc/ldso-0.9.24/man/dlopen.3 1969-12-31 18:00:00.000000000 -0600
10854 +++ uClibc.ldso.24/ldso-0.9.24/man/dlopen.3 2001-04-23 12:43:54.000000000 -0500
10857 +.\" Copyright 1995 Yggdrasil Computing, Incorporated.
10858 +.\" written by Adam J. Richter (adam@yggdrasil.com),
10859 +.\" with typesetting help from Daniel Quinlan (quinlan@yggdrasil.com).
10861 +.\" This is free documentation; you can redistribute it and/or
10862 +.\" modify it under the terms of the GNU General Public License as
10863 +.\" published by the Free Software Foundation; either version 2 of
10864 +.\" the License, or (at your option) any later version.
10866 +.\" The GNU General Public License's references to "object code"
10867 +.\" and "executables" are to be interpreted as the output of any
10868 +.\" document formatting or typesetting system, including
10869 +.\" intermediate and printed output.
10871 +.\" This manual is distributed in the hope that it will be useful,
10872 +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
10873 +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10874 +.\" GNU General Public License for more details.
10876 +.\" You should have received a copy of the GNU General Public
10877 +.\" License along with this manual; if not, write to the Free
10878 +.\" Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
10881 +.TH DLOPEN 3 "16 May 1995" "Linux" "Linux Programmer's Manual"
10883 +dlclose, dlerror, dlopen, dlsym \- Programming interface to dynamic linking loader.
10885 +.B #include <dlfcn.h>
10887 +.BI "void *dlopen (const char *" "filename" ", int " flag ");
10889 +.BI "const char *dlerror(void);"
10891 +.BI "void *dlsym(void *"handle ", char *"symbol ");"
10893 +.BI "int dladdr(void *"address ", Dl_info *"dlip ");"
10895 +.BI "int dlclose (void *"handle ");
10898 +.BR "_init" ", " "_fini" ". "
10901 +loads a dynamic library from the file named by the null terminated
10904 +and returns an opaque "handle" for the dynamic library.
10907 +is not an absolute path (i.e., it does not begin with a "/"), then the
10908 +file is searched for in the following locations:
10911 +A colon-separated list of directories in the user's
10912 +\fBLD_LIBRARY\fP path environment variable.
10914 +The list of libraries specified in \fI/etc/ld.so.cache\fP.
10916 +\fI/usr/lib\fP, followed by \fI/lib\fP.
10921 +is a NULL pointer, then the returned handle is for the main program.
10923 +External references in the library are resolved using the libraries
10924 +in that library's dependency list and any other libraries previously
10928 +If the executable was linked
10929 +with the flag "-rdynamic", then the global symbols in the executable
10930 +will also be used to resolve references in a dynamically loaded
10936 +meaning resolve undefined symbols as code from the dynamic library is
10939 +meaning resolve all undefined symbols before
10941 +returns, and fail if this cannot be done.
10946 +in which case the external symbols defined in the library will be
10947 +made available to subsequently loaded libraries.
10949 +If the library exports a routine named
10951 +then that code is executed before dlopen returns.
10952 +If the same library is loaded twice with
10954 +the same file handle is returned. The dl library maintains link
10955 +counts for dynamic file handles, so a dynamic library is not
10958 +has been called on it as many times as
10960 +has succeeded on it.
10964 +fails for any reason, it returns NULL.
10965 +A human readable string describing the most recent error that occurred
10966 +from any of the dl routines (dlopen, dlsym or dlclose) can be
10970 +returns NULL if no errors have occurred since initialization or since
10971 +it was last called. (Calling
10973 +twice consecutively, will always result in the second call returning
10977 +takes a "handle" of a dynamic library returned by dlopen and the null
10978 +terminated symbol name, returning the address where that symbol is
10979 +loaded. If the symbol is not found,
10981 +returns NULL; however, the correct way to test for an error from
10983 +is to save the result of
10985 +into a variable, and then check if saved value is not NULL.
10986 +This is because the value of the symbol could actually be NULL.
10987 +It is also necessary to save the results of
10989 +into a variable because if
10991 +is called again, it will return NULL.
10994 +returns information about the shared library containing the memory
10995 +location specified by
10998 +returns zero on success and non-zero on error.
11001 +decrements the reference count on the dynamic library handle
11003 +If the reference count drops to zero and no other loaded libraries use
11004 +symbols in it, then the dynamic library is unloaded. If the dynamic
11005 +library exports a routine named
11007 +then that routine is called just before the library is unloaded.
11009 +.B Load the math library, and print the cosine of 2.0:
11013 +#include <dlfcn.h>
11015 +int main(int argc, char **argv) {
11016 + void *handle = dlopen ("/lib/libm.so", RTLD_LAZY);
11017 + double (*cosine)(double) = dlsym(handle, "cos");
11018 + printf ("%f\\n", (*cosine)(2.0));
11024 +If this program were in a file named "foo.c", you would build the program
11025 +with the following command:
11028 +gcc -rdynamic -o foo foo.c -ldl
11032 +.B Do the same thing, but check for errors at every step:
11036 +#include <stdio.h>
11037 +#include <dlfcn.h>
11039 +int main(int argc, char **argv) {
11041 + double (*cosine)(double);
11044 + handle = dlopen ("/lib/libm.so", RTLD_LAZY);
11046 + fputs (dlerror(), stderr);
11050 + cosine = dlsym(handle, "cos");
11051 + if ((error = dlerror()) != NULL) {
11052 + fputs(error, stderr);
11056 + printf ("%f\\n", (*cosine)(2.0));
11062 +.SH ACKNOWLEDGEMENTS
11063 +The dlopen interface standard comes from Solaris.
11064 +The Linux dlopen implementation was primarily written by
11065 +Eric Youngdale with help from Mitch D'Souza, David Engel,
11066 +Hongjiu Lu, Andreas Schwab and others.
11067 +The manual page was written by Adam Richter.
11074 diff -urN uClibc/ldso-0.9.24/man/ld.so.8 uClibc.ldso.24/ldso-0.9.24/man/ld.so.8
11075 --- uClibc/ldso-0.9.24/man/ld.so.8 1969-12-31 18:00:00.000000000 -0600
11076 +++ uClibc.ldso.24/ldso-0.9.24/man/ld.so.8 2001-04-23 12:43:54.000000000 -0500
11078 +.TH ld.so 8 "14 March 1998"
11080 +ld.so/ld-linux.so \- dynamic linker/loader
11083 +loads the shared libraries needed by a program, prepares the program
11084 +to run, and then runs it.
11085 +Unless explicitly specified via the
11089 +during compilation, all Linux programs are incomplete and require
11090 +further linking at run time.
11092 +The necessary shared libraries needed by the program are searched for
11093 +in the following order
11095 +Using the environment variable
11096 +.B LD_LIBRARY_PATH
11097 +.RB ( LD_AOUT_LIBRARY_PATH
11098 +for a.out programs).
11099 +Except if the executable is a setuid/setgid binary, in which case it
11102 +From the cache file
11103 +.BR /etc/ld.so.cache
11104 +which contains a compiled list of candidate libraries previously found
11105 +in the augmented library path.
11107 +In the default path
11113 +.B LD_LIBRARY_PATH
11114 +A colon-separated list of directories in which to search for
11115 +ELF libraries at execution-time.
11118 +environment variable.
11121 +A whitespace-separated list of additional, user-specified, ELF shared
11122 +libraries to be loaded before all others.
11123 +This can be used to selectively override functions in other shared libraries.
11124 +For setuid/setgid ELF binaries, only libraries in the standard search
11125 +directories that are also setgid will be loaded.
11127 +.B LD_TRACE_LOADED_OBJECTS
11128 +If present, causes the program to list its dynamic library dependencies,
11129 +as if run by ldd, instead of running normally.
11132 +If present, causes the dynamic linker to resolve all symbols at program
11133 +startup instead of when they are first referenced.
11135 +.B LD_AOUT_LIBRARY_PATH
11136 +A colon-separated list of directories in which to search for
11137 +a.out libraries at execution-time.
11140 +environment variable.
11142 +.B LD_AOUT_PRELOAD
11143 +The name of an additional, user-specified, a.out shared library to be loaded
11145 +This can be used to selectively override functions in other shared libraries.
11148 +Suppress warnings about a.out libraries with incompatible minor
11152 +Don't ignore the directory in the names of a.out libraries to be loaded.
11153 +Use of this option is strongly discouraged.
11158 +a.out dynamic linker/loader
11160 +.B /lib/ld-linux.so.*
11161 +ELF dynamic linker/loader
11163 +.B /etc/ld.so.cache
11164 +File containing a compiled list of directories in which to search for
11165 +libraries and an ordered list of candidate libraries.
11167 +.B /etc/ld.so.preload
11168 +File containing a whitespace separated list of ELF shared libraries to
11169 +be loaded before the program.
11170 +libraries and an ordered list of candidate libraries.
11182 +has no means of unloading and searching for compatible or newer version of
11186 +functionality is only available for executables compiled using libc version
11189 +David Engel, Eric Youngdale, Peter MacDonald, Hongjiu Lu, Linus
11190 +Torvalds, Lars Wirzenius and Mitch D'Souza (not necessarily in that order).
11191 diff -urN uClibc/ldso-0.9.24/man/ld.so.texi uClibc.ldso.24/ldso-0.9.24/man/ld.so.texi
11192 --- uClibc/ldso-0.9.24/man/ld.so.texi 1969-12-31 18:00:00.000000000 -0600
11193 +++ uClibc.ldso.24/ldso-0.9.24/man/ld.so.texi 2001-04-23 12:43:54.000000000 -0500
11195 +\input texinfo @c -*-texinfo-*-
11196 +@c %**start of header
11197 +@setfilename ld.so.info
11198 +@settitle ld.so : Dynamic-Link Library support
11199 +@c %**end of header
11202 +This file documents the dynamic-link support libraries and utilities for the
11203 +Linux OS, version 1.8.1.
11205 +Copyright 1996 Michael Deutschmann
11207 +This document is subject to the GNU General Public License as published by
11208 +the Free Software foundation, version 2 or later (your choice).
11210 +Note: The software described in this document is under a different copyright
11217 +@subtitle Dynamic Link library support for the Linux OS.
11218 +@author David Engel
11219 +@author Eric Youngdale
11220 +@author Peter Macdonald
11221 +@author Hongjiu Lu
11222 +@author Mitch D'Souza
11223 +@author Michael Deutschmann (this documentation)
11226 +Copyright @copyright{} 1996 Michael Deutschmann
11228 +This document is subject to the GNU General Public License as published by
11229 +the Free Software foundation, version 2 or later (your choice).
11231 +Note: The software described in this document is under a different copyright
11239 +The @code{ld.so} module provides dynamic linked library support in Linux.
11240 +This file documents @code{ld.so} and its companion software.
11243 +* intro:: Introduction
11245 +* ld.so:: The dynamic linker core program
11246 +* ldd:: A utility to print out dependencies
11247 +* ldconfig:: A utility to maintain the cache and symlinks
11248 +* libdl:: Manual dynamic linking library
11254 +@unnumbered Introduction
11256 +The @code{ld.so} suite contains special files and utilities needed for linux
11257 +to handle @dfn{dynamic libraries}.
11259 +Ordinary static libraries (@file{lib*.a} files) are included into executables
11260 +that use their functions. A file that only uses static libraries needs less
11261 +intelligence to load, but takes up more space. If many executables use the
11262 +same library, there can be much wastage of storage space, since multiple
11263 +copies of the library functions are scattered across the executables.
11264 +However, static libraries are easier to make.
11266 +Dynamic libraries (@file{lib*.so*} files) are not copied into executables ---
11267 +the executable is written in such a way that it will automatically load the
11268 +libraries. In linux, the executable will first load the special library
11269 +@code{ld.so} or @code{ld-linux.so}, which contains the intelligence
11270 +to load further dynamic libraries. Since multiple files end up getting
11271 +executable data from the same file, dynamic libraries are also known as
11274 +Linux executables come in two flavors, @sc{elf} and a.out.
11276 +a.out is the original executable format used by Linux. It has somewhat less
11277 +overhead than @sc{elf}. However creating shared libraries for a.out is
11278 +@emph{very} involved, and each a.out shared library must be explicitly
11281 +@sc{elf} is a more recent format, which supports a much simpler method of
11282 +creating libraries. @sc{elf} libraries may also be linked manually
11285 +Since many library authors prefer @sc{elf} and no longer release shared a.out
11286 +libraries, a.out is moribund on Linux. This version of the @code{ld.so} can
11287 +be compiled to support only @sc{elf}, or to support both formats. (The last
11288 +release of ld.so to support a.out alone was 1.8.0.)
11291 +@chapter @code{ld.so}: Dynamic linker core
11293 +@code{ld.so} works behind the scenes to handle dynamic libraries in Linux.
11294 +Users will almost never have to deal with it directly, but in special cases
11295 +one can send instructions to it through environment variables. Also, if
11296 +something is wrong with your libraries (usually an incorrect version) ld.so
11297 +will give error messages.
11299 +Actually @code{ld.so} is the a.out linker. The new @sc{elf} executables are
11300 +handled by a related program @code{ld-linux.so}.
11303 +* files:: Configuration files used by the suite
11304 +* environment:: Environment settings that tweak @code{ld.so}
11305 +* errors:: Complaints @code{ld.so} might make
11309 +@section Configuration Files
11312 +@item /etc/ld.so.cache
11313 +A file created by @code{ldconfig} and used to speed linking. It's structure
11314 +is private to the suite.
11316 +@item /etc/ld.so.conf
11317 +A simple list of directories to scan for libraries, in addition to
11318 +@file{/usr/lib} and @file{/lib}, which are hardwired. It may contain
11319 +comments started with a @samp{#}.
11321 +@item /etc/ld.so.preload
11322 +A list of libraries to preload. This allows preloading libraries for
11323 +setuid/setgid executables securely. It may contain comments.
11327 +@section Environment Variables
11330 +@item LD_AOUT_LIBRARY_PATH
11331 +@itemx LD_LIBRARY_PATH
11332 +These variables supply a library path for finding dynamic libraries, in the
11333 +standard colon seperated format. These variables are ignored when executing
11334 +setuid/setgid programs, because otherwise they would be a security hazard.
11335 +@code{ld.so} will use @code{LD_AOUT_LIBRARY_PATH} and @code{ld-linux.so} will
11336 +use @code{LD_LIBRARY_PATH}.
11338 +@item LD_AOUT_PRELOAD
11340 +These variables allow an extra library not specified in the executable to be
11341 +loaded. Generally this is only useful if you want to override a function.
11342 +These are also ignored when running setuid/setgid executables. @code{ld.so}
11343 +will use @code{LD_AOUT_PRELOAD} and @code{ld-linux.so} will use
11344 +@code{LD_PRELOAD}.
11347 +If non-empty, errors about incompatible minor revisions are suppressed.
11350 +If non-empty, allow executables to specify absolute library names. This
11351 +option is deprecated.
11353 +@c The following are things I noticed in the ld-linux.so source.
11354 +@c I don't really understand 'em. Could someone help me?
11356 +@c @item LD_BIND_NOW
11357 +@c This option is used by the @code{ld-linux.so} only. I don't know
11358 +@c what it does. (I suspect, looking at the code, that it specifies
11359 +@c "RTLD_NOW" rather than "RTLD_LAZY" mode for the shared libraries.)
11361 +@c @item LD_TRACE_LOADED_OBJECTS
11363 +@c These seem to have something to do with the communication between the
11364 +@c @code{ld-linux.so} and @code{ldd}. I don't know more.
11371 +@item Can't find library @var{library}
11372 +The executable required a dynamically linked library that ld.so cannot find.
11373 +Your symbolic links may be not set right, or you may have not installed a
11374 +library needed by the program.
11376 +@item Can't load library @var{library}
11377 +The library is corrupt.
11379 +@item Incompatible library @var{library}
11380 +@itemx Require major version @var{x} and found @var{y}
11381 +Your version of the library is incompatible with the executable. Recompiling
11382 +the executable, or upgrading the library will fix the problem.
11384 +@item using incompatible library @var{library}
11385 +@itemx Desire minor version >= @var{x} and found @var{y}.
11386 +Your version of the library is older than that expected by the executable,
11387 +but not so old that the library interface has radically changed, so the
11388 +linker will attempt to run anyway. There is a chance that it will work, but
11389 +you should upgrade the library or recompile the software. The environment
11390 +variable @code{LD_NOWARN} can be used to supress this message.
11392 +@item too many directories in library path
11393 +The linker only supports up to 32 library directories. You have too many.
11395 +@item dynamic linker error in @var{blah}
11396 +The linker is having trouble handling a binary - it is probably corrupt.
11398 +@item can't map cache file @var{cache-file}
11399 +@itemx cache file @var{cache-file} @var{blah}
11400 +The linker cache file (generally @file{/etc/ld.so.cache}) is corrupt or
11401 +non-existent. These errors can be ignored, and can be prevented by
11402 +regenerating the cache file with @code{ldconfig}.
11406 +@chapter @code{ldd}: Dependency scanner
11408 +@code{ldd} is a utility that prints out the dynamic libraries that an
11409 +executable is linked to.
11411 +Actually @code{ldd} works by signalling ld.so to print the dependencies.
11412 +For a.out executables this is done by starting the executable with
11413 +@code{argc} equal to 0. The linker detects this and prints the dependencies.
11414 +(This can cause problems with @emph{very} old binaries, which would run as
11415 +normal only with an inappropriate @code{argc}.)
11417 +For @sc{elf} executables, special environment variables are used to tell the
11418 +linker to print the dependencies.
11420 +@code{ldd} has a few options:
11424 +Print the version number of @code{ldd} itself
11427 +Print the version number of the dynamic linker
11430 +Report missing functions. This is only supported for @sc{elf} executables.
11433 +Report missing objects. This is also only available for @sc{elf}
11438 +@chapter @code{ldconfig}: Setup program
11440 +This utility is used by the system administrator to automatically set up
11441 +symbolic links needed by the libraries, and also to set up the cache file.
11443 +@code{ldconfig} is run after new dynamic libraries are installed, and if the
11444 +cache file or links are damaged. It is also run when upgrading the
11445 +@code{ld.so} suite itself.
11447 +The @file{/lib} and @file{/usr/lib} directories, and any listed in the file
11448 +@file{/etc/ld.so.conf} are scanned by default unless @samp{-n} is used.
11449 +Additional directories may be specified on the command line.
11451 +It has the following options:
11455 +Enter debug mode. Implies @samp{-N} and @samp{-X}.
11458 +Verbose. Print out links created and directories scanned.
11461 +Check directories specified on the commandline @emph{only}.
11464 +Do not regenerate the cache.
11467 +Do not rebuild symbolic links.
11470 +Set up symbolic links for only libraries presented on the command line.
11473 +Print out the library pathnames in the cache file (@file{/etc/ld.so.cache})
11477 +@chapter User dynamic linking library
11479 +The @code{ld.so} package includes a small library of functions
11480 +(@code{libdl}) to allow manual dynamic linking. Normally programs are linked
11481 +so that dynamic functions and objects are automagically available. These
11482 +functions allow one to manually load and access a symbol from a library.
11483 +They are only available for @sc{elf} executables.
11486 +* using libdl:: General points
11487 +* functions:: How to use the functions
11488 +* example:: A sample program
11494 +To access this library, add the flag @samp{-ldl} to your compile command when
11495 +linking the executable. You also must include the header file
11496 +@code{dlfcn.h}. You may also need the flag @samp{-rdynamic}, which enables
11497 +resolving references in the loaded libraries against your executable.
11499 +Generally, you will first use @code{dlopen} to open a library. Then you use
11500 +@code{dlsym} one or more times to access symbols. Finally you use
11501 +@code{dlclose} to close the library.
11503 +These facilities are most useful for language interpreters that provide
11504 +access to external libraries. Without @code{libdl}, it would be neccessary
11505 +to link the interpreter executable with any and all external libraries
11506 +needed by the programs it runs. With @code{libdl}, the interpreter only
11507 +needs to be linked with the libraries it uses itself, and can dynamically
11508 +load in additional ones if programs need it.
11511 +@section Functions
11513 +@deftypefun void *dlopen ( const char @var{filename}, int @var{flags} )
11515 +This function opens the dynamic library specified by @var{filename}
11516 +and returns an abstract handle, which can be used in subsequent calls to
11517 +@code{dlsym}. The function will respect the @code{LD_ELF_LIBRARY_PATH} and
11518 +@code{LD_LIBRARY_PATH} environment variables.
11522 +The following flags can be used with @code{dlopen}:
11524 +@deftypevr Macro int RTLD_LAZY
11525 +Resolve symbols in the library as they are needed.
11528 +@deftypevr Macro int RTLD_NOW
11529 +Resolve all symbols in the library before returning, and fail if not all can
11530 +be resolved. This is mutually exclusive with @code{RTLD_LAZY}.
11533 +@deftypevr Macro int RTLD_GLOBAL
11534 +Make symbols in this library available for resolving symbols in other
11535 +libraries loaded with @code{dlopen}.
11538 +@deftypefun int dlclose ( void *@var{handle} )
11540 +This function releases a library handle.
11542 +Note that if a library opened twice, the handle will be the same. However,
11543 +a reference count is used, so you should still close the library as many
11544 +times as you open it.
11548 +@deftypefun void *dlsym (void *@var{handle},char *@var{symbol-name})
11550 +This function looks up the name @var{symbol-name} in the library and returns
11551 +it in the void pointer.
11553 +If there is an error, a null pointer will be returned. However, it is
11554 +possible for a valid name in the library to have a null value, so
11555 +@code{dlerror} should be used to check if there was an error.
11559 +@deftypefun {libdl function} {const char} *dlerror( void )
11561 +This function is used to read the error state. It returns a human-readable
11562 +string describing the last error, or null, meaning no error.
11564 +The function resets the error value each time it is called, so the result
11565 +should be copied into a variable. If the function is called more than once
11566 +after an error, the second and subsequent calls will return null.
11571 +@section Example program
11573 +Here is an example program that prints the cosine of two by manually linking
11574 +to the math library:
11577 +@c The following was snarfed verbatim from the dlopen.3 man file.
11578 +#include <stdio.h>
11579 +#include <dlfcn.h>
11581 +int main(int argc, char **argv) @{
11583 + double (*cosine)(double);
11586 + handle = dlopen ("/lib/libm.so", RTLD_LAZY);
11588 + fputs (dlerror(), stderr);
11592 + cosine = dlsym(handle, "cos");
11593 + if ((error = dlerror()) != NULL) @{
11594 + fputs(error, stderr);
11598 + printf ("%f\\n", (*cosine)(2.0));
11606 diff -urN uClibc/ldso-0.9.24/man/ldconfig.8 uClibc.ldso.24/ldso-0.9.24/man/ldconfig.8
11607 --- uClibc/ldso-0.9.24/man/ldconfig.8 1969-12-31 18:00:00.000000000 -0600
11608 +++ uClibc.ldso.24/ldso-0.9.24/man/ldconfig.8 2001-04-23 12:43:54.000000000 -0500
11610 +.TH ldconfig 8 "14 March 1998"
11612 +ldconfig \- determine run-time link bindings
11617 +.RB [ \-C\ cache ]
11619 +.IR directory \ ...
11634 +creates the necessary links and cache (for use by the run-time linker,
11636 +to the most recent shared libraries found in the directories specified
11637 +on the command line, in the file
11638 +.IR /etc/ld.so.conf ,
11639 +and in the trusted directories
11644 +checks the header and file names of the libraries it encounters when
11645 +determining which versions should have their links updated.
11647 +ignores symbolic links when scanning for libraries.
11650 +will attempt to deduce the type of ELF libs (ie. libc5 or libc6/glibc)
11651 +based on what C libs if any the library was linked against, therefore when
11652 +making dynamic libraries, it is wise to explicitly link against libc (use -lc).
11654 +Some existing libs do not contain enough information to allow the deduction of
11655 +their type, therefore the
11656 +.IR /etc/ld.so.conf
11657 +file format allows the specification of an expected type. This is
11659 +used for those ELF libs which we can not work out. The format
11660 +is like this "dirname=TYPE", where type can be libc4, libc5 or libc6.
11661 +(This syntax also works on the command line). Spaces are
11663 +allowed. Also see the
11667 +Directory names containing an
11668 +.B = are no longer legal
11669 +unless they also have an expected type specifier.
11672 +should normally be run by the super-user as it may require write
11673 +permission on some root owned directories and files.
11674 +It is normally run automatically at bootup, from /etc/rc, or manually
11675 +whenever new DLL's are installed.
11687 +Print current version number, the name of each directory as it
11688 +is scanned and any links that are created.
11689 +Overrides quiet mode.
11693 +Don't print warnings.
11696 +Only process directories specified on the command line.
11697 +Don't process the trusted directories
11701 +nor those specified in
11702 +.IR /etc/ld.so.conf .
11707 +Don't rebuild the cache.
11710 +is also specified, links are still updated.
11713 +Don't update links.
11716 +is also specified, the cache is still rebuilt.
11722 +.IR /etc/ld.so.conf .
11728 +.IR /etc/ld.so.cache .
11733 +as the root directory.
11737 +Manually link individual libraries.
11738 +Intended for use by experts only.
11741 +Print the lists of directories and candidate libraries stored in
11742 +the current cache.
11744 +In the bootup file
11752 +will set up the correct links for the shared binaries and rebuild
11755 +On the command line
11758 +# /sbin/ldconfig -n /lib
11761 +as root after the installation of a new DLL, will properly update the
11762 +shared library symbolic links in /lib.
11768 +execution time linker/loader
11770 +.B /etc/ld.so.conf
11771 +File containing a list of colon, space, tab, newline, or comma spearated
11772 +directories in which to search for libraries.
11774 +.B /etc/ld.so.cache
11775 +File containing an ordered list of libraries found in the directories
11777 +.BR /etc/ld.so.conf .
11779 +.B lib*.so.version
11788 +functionality, in conjunction with
11790 +is only available for executables compiled using libc version 4.4.3 or greater.
11793 +being a user process, must be run manually and has no means of dynamically
11794 +determining and relinking shared libraries for use by
11796 +when a new DLL is installed.
11798 +David Engel and Mitch D'Souza.
11799 diff -urN uClibc/ldso-0.9.24/man/ldd.1 uClibc.ldso.24/ldso-0.9.24/man/ldd.1
11800 --- uClibc/ldso-0.9.24/man/ldd.1 1969-12-31 18:00:00.000000000 -0600
11801 +++ uClibc.ldso.24/ldso-0.9.24/man/ldd.1 2001-04-23 12:43:54.000000000 -0500
11803 +.\" Copyright 1995-2000 David Engel (david@ods.com)
11804 +.\" Copyright 1995 Rickard E. Faith (faith@cs.unc.edu)
11805 +.\" Most of this was copied from the README file. Do not restrict distribution.
11806 +.\" May be distributed under the GNU General Public License
11807 +.TH LDD 1 "14 March 1998"
11809 +ldd \- print shared library dependencies
11813 +program|library ...
11816 +prints the shared libraries required by each program or shared library
11817 +specified on the command line.
11818 +If a shared library name does not contain a '/',
11820 +attempts to locate the library in the standard locations.
11823 +on a shared library in the current directory, a "./" must be prepended
11828 +Print the version number of
11832 +Print the version number of the dynamic linker,
11836 +Perform relocations and report any missing functions (ELF only).
11839 +Perform relocations for both data objects and functions, and
11840 +report any missing objects (ELF only).
11843 +does not work very well on libc.so.5 itself.
11846 +does not work on a.out shared libraries.
11849 +does not work with some extremely old a.out programs which were
11852 +support was added to the compiler releases.
11855 +on one of these programs, the program will attempt to run with argc = 0 and
11856 +the results will be unpredictable.