fix svn patch breakage in glib
[openwrt.git] / obsolete-buildroot / sources / uClibc-ldso-0.9.24.patch
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
4 @@ -0,0 +1,49 @@
5 +/*
6 + * Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald, David Engel,
7 + * Hongjiu Lu and Mitch D'Souza
8 + *
9 + * All rights reserved.
10 + *
11 + * Redistribution and use in source and binary forms, with or without
12 + * modification, are permitted provided that the following conditions
13 + * are met:
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.
19 + *
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
30 + * SUCH DAMAGE.
31 + */
32 +
33 +/* Notice of general intent:
34 + *
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.
44 + *
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.
53 + */
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
57 @@ -0,0 +1,52 @@
58 +# Makefile for uClibc
59 +#
60 +# Copyright (C) 2000,2001 Erik Andersen <andersen@uclibc.org>
61 +#
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
65 +# later version.
66 +#
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
70 +# details.
71 +#
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
75 +#
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.
79 +
80 +TOPDIR=../
81 +include $(TOPDIR)Rules.mak
82 +
83 +ALL_SUBDIRS = ldso libdl
84 +
85 +
86 +all: headers
87 +ifeq ($(strip $(BUILD_UCLIBC_LDSO)),y)
88 +       $(MAKE) -C ldso;
89 +else
90 +       echo "Not building ld-uClibc"
91 +endif
92 +
93 +shared:
94 +ifeq ($(strip $(BUILD_UCLIBC_LDSO)),y)
95 +       $(MAKE) -C libdl;
96 +else
97 +       echo "Not building libdl"
98 +endif
99 +
100 +headers:
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/
105 +
106 +clean:
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
113 @@ -0,0 +1,841 @@
114 +
115 +Apr 20, 2001 -- Manuel Novoa III
116 +
117 +Inital port for uClibc from debian ld.so_1.9.11-9.tar.gz.
118 +
119 +Removed a.out support.
120 +
121 +****************** original ld.so.lsm file **************************
122 +Begin3
123 +Title:          Linux shared, dynamic linker and utilities.
124 +Version:        1.9.11
125 +Entered-date:   01MAY99
126 +Description:    This package contains ld.so, ld-linux.so, ldconfig,
127 +               ldd and libdl.
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.
138 +End
139 +*********************************************************************
140 +                   Original README starts here
141 +*********************************************************************
142 +
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.
145 +
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.
148 +
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.
155 +
156 +Please see the included manual pages for further details.
157 +
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.
163 +
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.
168 +
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
172 +order).
173 +
174 +###################### IMPORTANT NOTICES #############################
175 +
176 +A.OUT SUPPORT:
177 +
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.
182 +
183 +GLIBC (AKA LIBC6) SUPPORT:
184 +
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.
188 +
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.
197 +
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.
202 +
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.
209 +
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.
215 +
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.
221 +
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.
230 +
231 +######################################################################
232 +
233 +Changes in version 1.9.11:
234 +
235 +       Fixed a bug in ld-linux.so where a reference to an
236 +       undefined symbol could cause a segfault.
237 +
238 +       Added a clarification for LD_PRELOAD to the ld.so manual 
239 +       page and added a symlink for ld-linux.so (Bug#33123).
240 +
241 +       Don't install ldd for Debian except for the m68k arch
242 +       because glibc 2.1 now includes it (Bug#35458).
243 +
244 +Changes in version 1.9.10:
245 +
246 +       Changed ldconfig to issue a warning and not overwrite a
247 +       regular file with a symlink (Bug#30859).
248 +
249 +       Changed Debian packaging to conflict with and replace the
250 +       ldconfig package (Bug#29398).
251 +
252 +Changes in version 1.9.9:
253 +
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.
257 +
258 +       Fixed problems in ld-linux.so on the sparc architecture
259 +       (Juan Cespedes).
260 +
261 +Changes in version 1.9.8:
262 +
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.
266 +
267 +       Changed ldconfig to use the same type names used in the
268 +       change above when the -p option is used.
269 +
270 +Changes in version 1.9.7:
271 +
272 +       Changed ldd for m68k to use /lib/ld.so.1 instead of 
273 +       /lib/ld-linux.so.2.
274 +
275 +       Added support for dladdr to libdl.so (Eduard Gode).
276 +
277 +       Fixed a small memory leak in libdl.so (Richard Garnish).
278 +
279 +       Fixed a bug in ldconfig when the -l option was used on a
280 +       filename without a '/' in it.
281 +
282 +       Updated the man pages (Bug#6404, Bug#9721, Bug#10652, 
283 +       Bug#13494 and Bug#14127).  They could still use some work.
284 +
285 +       No longer install the info page since it's way out of date.
286 +
287 +       Fixed minor Debian packaging problems (Bug#13160, 
288 +       Bug#15577 and Bug#19345).
289 +
290 +Changes in version 1.9.6:
291 +
292 +       Changed ldd to not use the glibc dynamic linker when run
293 +       on a libc5-based shared library.
294 +
295 +       Added a -q option to ldconfig which causes warnings not
296 +       to be printed (Bob Tinsley).
297 +
298 +       Dropped support for the Debian libdl1-dev package.
299 +
300 +       Changed ld-linux.so to be compilable with gcc 2.8.0 (Sven 
301 +       Verdoolaege)
302 +
303 +Changes in version 1.9.5:
304 +
305 +       Fixed a bug in ldd where ld-linux.so.2 was not called
306 +       correctly when run on shared libraries.
307 +
308 +       Fixed a problem in the previous version where some
309 +       Makefiles were not architecture independent.
310 +
311 +Changes in version 1.9.4:
312 +
313 +       Fixed a bug in ld.so introduced in the previous version
314 +       which broke preloads.
315 +
316 +       Turned a.out support back on by default, at least for the
317 +       time being.  There are no promises to keep it.
318 +
319 +Changes in version 1.9.3:
320 +
321 +       Fixed buffer overflow bugs in ld-linux.so and ld.so.
322 +
323 +       Changed the README file a little to clarify a couple of
324 +       things.
325 +
326 +       Changed ldconfig to chroot to the specified directory when
327 +       the new -r option is used (Bob Tinsley).
328 +
329 +Changes in version 1.9.2:
330 +
331 +       Removed /usr/local/lib from the default /etc/ld.so.conf
332 +       for Debian (Bug#8181).
333 +
334 +       Changed ldconfig to be 64-bit clean (H.J. Lu).
335 +
336 +Changes in version 1.9.1:
337 +
338 +       Changed ldconfig to try to determine which libc a
339 +       library is for even if it doesn't have an soname.
340 +
341 +       Fixed a bug in ldconfig where an older library using
342 +       the glibc naming convention would be used instead of
343 +       a newer library.
344 +
345 +       Changed to ld-linux.so and libdl.so to not require the 
346 +       libc5 headers in order to compile.
347 +
348 +       Changed ldconfig and ldd to be compilable with either
349 +       libc5 or libc6.
350 +
351 +Changes in version 1.9.0:
352 +
353 +       Changed to not build the old, a.out dynamic loader by
354 +       default.
355 +
356 +       Changed instldso.sh to require the --force option to
357 +       make sure users read the README file.
358 +
359 +       Changed instldso.sh to not install the libdl.so
360 +       development files unless the --devfiles option is used.
361 +
362 +       Changed instldso.sh to not strip binaries and libraries
363 +       if the --no-strip option is used.
364 +
365 +       Changed the Debian packaging to put the development files 
366 +       which conflict with glibc in a new libdl1-dev package.
367 +
368 +       Changed ldd to use the glibc dynamic linker, if it is
369 +       available, when run on a shared library.
370 +
371 +       Changed ld-linux.so to print the load addresses of
372 +       libraries, ala glibc, when run by ldd.
373 +
374 +       Changed ld-linux.so to allow the libraries listed in 
375 +       LD_PRELOAD to be separated by white space in addition to 
376 +       colons.
377 +
378 +       Changed ld-linux.so to load the libraries listed in 
379 +       LD_PRELOAD for setu/gid programs as long as they can be 
380 +       loaded securely.
381 +
382 +       Changed ldconfig to update the symlinks for the dynamic
383 +       linkers.
384 +
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.
389 +
390 +       Changed ldconfig to print the type of ELF library when
391 +       printing the cache.
392 +
393 +       Changed ld-linux.so to only load ELF shared libraries for
394 +       use with libc5 or an unknown libc.
395 +
396 +Changes in version 1.8.10:
397 +
398 +       Fixed a bug in ldconfig where a symlink could be used
399 +       instead of a regular file.
400 +
401 +       Fixed a Debian packaging problem for the sparc 
402 +       architecture.
403 +
404 +Changes in version 1.8.9:
405 +
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.
409 +
410 +       Changed ldconfig to cache the symlinks that it finds but
411 +       use the name of the symlink as the soname instead of the 
412 +       actual soname.
413 +
414 +Changes in version 1.8.8:
415 +
416 +       Minor documentation updates to reflect recent changes.
417 +
418 +       Changed ld.so and ld-linux.so to perform more complete
419 +       validation on ld.so.cache before using it.
420 +
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.
424 +
425 +       Changed the install script to not strip _dl_debug_state
426 +       from ld-linux.so since gdb needs it.
427 +
428 +       More sparc fixes (Derrick Brashear).
429 +
430 +       Changed ldconfig to not issue a warning when a linker
431 +       script disguised as a shared library is found.
432 +
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).
436 +
437 +       Fixed a bug in ld-linux.so where global variables were 
438 +       not always mapped correctly across dynamically loaded 
439 +       libraries (Mikihiko Nakao).
440 +
441 +       Converted to new Debian source packaging format (Shaya
442 +       Potter).
443 +
444 +Changes in version 1.8.6/7:
445 +
446 +       Never released as some unofficial patches used these
447 +       version numbers.
448 +
449 +Changes in version 1.8.5:
450 +
451 +       Fixed a bug in ld.so introduced in the previous changes.
452 +
453 +Changes in version 1.8.4:
454 +
455 +       Changed ldconfig to completely ignore symbolic links.
456 +
457 +       Changed ldconfig to issue the warning concerning an
458 +       inconsistent soname in non-verbose mode.
459 +
460 +       Changed ld-linux.so back to not keep ld.so.cache mapped
461 +       at all times.
462 +
463 +       Changed Debian packaging to compress man pages, strip all
464 +       binaries (Bug#5125) and include a shlibs file.
465 +
466 +Changes in version 1.8.3:
467 +
468 +       Changed ld-linux.so to process LD_PRELOAD before
469 +       /etc/ld.so.preload.
470 +
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).
474 +
475 +       Changed ldd to always exit with status 1 if any errors
476 +       occur (Debian Bug#4188).
477 +
478 +       Fixed some minor problems in instldso.sh (Mike Castle and
479 +       Wolfgang Franke).
480 +
481 +       Changed ldconfig to issue a warning in verbose mode when 
482 +       skipping a library because the soname doesn't match.
483 +
484 +       More sparc fixes (Miguel de Icaza).
485 +
486 +       Don't link with -N when building ld.so (Alan Modra).
487 +
488 +       Changed ld-linux.so to better support position-dependant
489 +       libraries (NIIBE Yutaka).
490 +
491 +Changes in version 1.8.2:
492 +
493 +       Added a texinfo file for ld.so and libdl (Michael 
494 +       Deutschmann).
495 +
496 +       Minor sparc and installation changes (Elliot Lee).
497 +
498 +       Added multiple architecture support for Debian (Leland
499 +       Lucius).
500 +
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.
504 +
505 +       Removed some libc dependencies from libdl.  Still need
506 +       to remove malloc and free.
507 +
508 +Changes in version 1.8.1:
509 +
510 +       Changed ld.so to be compiled as ELF.  This also means
511 +       that ELF support is now required.  A.out support is 
512 +       still optional.
513 +
514 +       Changed ld-linux.so and libdl.so to use the rpath in the 
515 +       executable instead of in the invoking shared library.
516 +
517 +       More m68k fixes (Andreas Schwab).
518 +
519 +       Various sparc fixes (Miguel de Icaza).
520 +
521 +       Changed ldcnnfig to ignore libraries ending in '~'.
522 +
523 +       Changed ldconfig to allow alternative conf and cache 
524 +       files to be specified on the command-line.
525 +
526 +       Changed libdl.so to work when dlsym is passed a NULL
527 +       handle pointer.
528 +
529 +Changes in version 1.8.0:
530 +
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
534 +       the -rpath option.
535 +
536 +       Various m68k fixes (Andreas Schwab).
537 +
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.
542 +
543 +       Changed ld-linux.so to allow debugging of shared and
544 +       dynamically loaded libraries (H.J. Lu, Andreas Schwab).
545 +
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.
549 +
550 +       Changed ld-linux.so to keep ld.so.cache mapped at all
551 +       times.
552 +
553 +       Changed ldconfig to allow #-style comments in ld.so.conf.
554 +
555 +       Removed various compiler warnings (Richard Sladkey and
556 +       David Engel).
557 +
558 +       Changed ldd to work on ELF shared libraries.  This may
559 +       need a little more work.
560 +
561 +Changes in version 1.7.14:
562 +
563 +       Changed ldconfig to recognize ELF shared libraries
564 +       generated by post-2.6 versions of ld (Andreas Schwab).
565 +
566 +       Changed ldconfig to not remove stale links that do not
567 +       have a version number since they may be needed by ld.
568 +
569 +Changes in version 1.7.13:
570 +
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).
574 +
575 +Changes in version 1.7.12:
576 +
577 +       Fixed a problem in libdl.so where the wrong library
578 +       could be marked as global when RTLD_GLOBAL was used
579 +       (Lars Heete).
580 +
581 +       Installed dlfcn.h with libdl.so instead of requiring
582 +       it to be supplied with libc.
583 +
584 +       Removed support for libldso.a since it was nearly
585 +       impossible to use anyway.
586 +
587 +       Changed ldd to detect when the program being checked
588 +       exited abnormally.
589 +
590 +Changes in version 1.7.11:
591 +
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
595 +       compromised.
596 +
597 +       Fixed a problem in libdl.so where dlsym would not accept
598 +       the handle returned from dlopen(0, *).
599 +
600 +Changes in version 1.7.10:
601 +
602 +       Changed ld-linux.so and libdl.so to support RTLD_GLOBAL
603 +       (Eric Youngdale).
604 +
605 +Changes in version 1.7.9:
606 +
607 +       Fixed a problem in ld-linux.so in detecting when the 
608 +       new user/group information is provided by the kernel.
609 +
610 +       Fixed a problem in ld-linux.so where a buffer could be
611 +       overflowed if a large number of libraries were loaded
612 +       (Thomas Moore).
613 +
614 +Changes in version 1.7.8:
615 +
616 +       Changed the Makefiles and install scripts to support 
617 +       a.out- and ELF-only configurations.
618 +
619 +       Changed ld-linux.so to use the user/group information
620 +       provided by linux 1.3.23+ instead of making syscalls
621 +       to get it.
622 +
623 +       Changed libdl.so to support RTLD_NEXT (Glenn Fowler).
624 +
625 +       Changed libdl.so to only execute the fini sections
626 +       instead of completely closing libraries at exit (Glenn
627 +       Fowler).
628 +
629 +       Changed ld.so and ld-linux.so to print the required
630 +       cache version when a mismatch is detected.
631 +
632 +       Changed ld-linux.so to not require on /dev/zero (Ralph
633 +       Loader).
634 +
635 +       Minor m68k cleanups (Andreas Schwab).
636 +
637 +Changes in version 1.7.7:
638 +
639 +       Fixed problems compiling with recent 1.3.x kernels.
640 +
641 +       Changed ld-linux.so to not use MAP_DENYWRITE until the
642 +       permission issue regarding it is resolved.
643 +
644 +Changes in version 1.7.6:
645 +
646 +       Fixed a bug in ld-linux.so dealing with a zero-length
647 +       LD_{ELF_}PRELOAD.
648 +
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.
651 +
652 +Changes in version 1.7.5:
653 +
654 +       Changed ldconfig to recognize libraries without any
655 +       version number (eg. libXYZ.so).
656 +
657 +       Changed ldconfig to not generate a corrupt cache when
658 +       the disk is full or other write errors occur.
659 +
660 +       Changed ld-linux.so to map files with MAP_DENYWRITE to
661 +       keep them from being changed while the file is in use
662 +       (Rick Sladkey).
663 +
664 +       Changed libdl to not overwrite the scope pointer of a 
665 +       library if it was already loaded (H.J. Lu).
666 +
667 +       Changed ld-linux.so so gdb can be used on constructors
668 +       (Eric Youngdale).
669 +
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).
673 +
674 +Changes in version 1.7.4:
675 +
676 +       Changed ld-linux.so and libdl to use the appropriate
677 +       rpaths when searching for shared libraries (Eric
678 +       Youngdale).
679 +
680 +       Changed ld-linux.so to search rpath before using the
681 +       cache.  This more closely conforms to the IBCS standard.
682 +
683 +Changes in version 1.7.3:
684 +
685 +       Changed ld-linux.so to only print a library name the
686 +       first time it is loaded when run from ldd.
687 +
688 +       Fixed a bug in ldconfig where an invalid cache could be
689 +       generated if a directory was specified multiple times in
690 +       ld.so.conf.
691 +
692 +       Changed ld-linux.so so it will return the address of a
693 +       weak symbol when called from dlsym in libdl (Eric 
694 +       Youngdale.
695 +
696 +Changes in version 1.7.2:
697 +
698 +       Changed libdl.so again to fix the undefined foobar
699 +       problem.
700 +
701 +Changes in version 1.7.1:
702 +
703 +       Changed libdl so it will compile at optimization level
704 +       O3 or higher.
705 +
706 +       Changed ldconfig to always create the cache file with 
707 +       mode 644.
708 +
709 +       Changed ldconfig to not ingore valid symlinks.
710 +
711 +       Changed ldconfig to use the library name as the soname 
712 +       for ELF libraries that do not have an soname entry.
713 +
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.
717 +
718 +Changes in version 1.7.0:
719 +
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.
724 +
725 +       Changed ldconfig to no longer support the undocumented
726 +       sort options.
727 +
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
731 +       operated this way.
732 +
733 +       Fixed a bug in libldso.a where the arguments to
734 +       shared_loader were not parsed correctly (Wolfram Gloger).
735 +
736 +       Added support for RELA-style relocations under Linux/68k
737 +       (Andreas Schwab).
738 +
739 +       Changed ld-linux.so to only map the cache once for all
740 +       libraries instead of individually for each library.
741 +
742 +       Changed ld-linux.so continue searching the cache instead of
743 +       giving up when failing to load the first entry found.
744 +
745 +       Changed ld-linux.so to produce output similar to ld.so when
746 +       run from ldd or when errors occur.
747 +
748 +Changes in version 1.6.7:
749 +
750 +       Changed the install scripts to make sure that ld.so and
751 +       ld-linux.so are always usable.
752 +
753 +       Added support for Linux/Sparc (Eric Youngdale).
754 +
755 +       Added support for Linux/68k (Andreas Schwab).
756 +
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 
760 +       Andreas Schwab).
761 +
762 +       Replaced the manual page for libdl with a freely
763 +       distributable one (Adam Richter).
764 +
765 +       Fixed a bug in ld-linux.so where LD_LIBRARY_PATH and
766 +       LD_PRELOAD were not cleared for setuid/setgid programs.
767 +
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).
771 +
772 +       Changed ld-linux.so to use the following order to search 
773 +       for libraries:  LD_{ELF_}LIBRARY_PATH, ld.so.cache, rpath, 
774 +       /usr/lib and /lib.
775 +
776 +       Changed ld-linux.so to not needlessly allocate memory when
777 +       using ld.so.cache.
778 +
779 +Changes in version 1.6.6:
780 +
781 +       Changed ldconfig to not warn about removing stale links
782 +       unless the -v option is specified.
783 +
784 +       Added manual pages for libdl (from FreeBSD/Sun)
785 +
786 +       Fixed a bug in ld.so dealing with preloading of objects
787 +       generated by recent versions of ld (Mitch D'Souza).
788 +
789 +       Fixed bugs in ldd where some errors were either not
790 +       detected or not printed.
791 +
792 +       Fixed a bug in ld-linux.so where the trailing nul in a
793 +       library name was not being copied (Owen Taylor).
794 +
795 +Changes in version 1.6.5:
796 +
797 +       Changed ldconfig to remove stale symbolic links.
798 +
799 +       Added debug hooks in ld-linux.so and libdl.so to be used 
800 +       by a future version of gdb (Eric Youngdale).
801 +
802 +Changes in version 1.6.4:
803 +
804 +       Change ld-linux.so to print on stdout instead of stderr
805 +       when run from ldd.
806 +
807 +       Added support for Debian GNU/Linux packaging.
808 +
809 +Changes in version 1.6.3:
810 +
811 +       Fixed a bug in libdl when closing a library (H.J. Lu).
812 +
813 +Changes in version 1.6.2:
814 +
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.
817 +
818 +       Changed ldconfig to no longer cache and set up links for
819 +       ld-linux.so.
820 +
821 +       Changed ld-linux.so and libdl to not conflict with upcoming
822 +       changes in kernel header files.
823 +
824 +       Changed ld-linux.so to not print preloaded libraries.
825 +
826 +Changes in version 1.6.1:
827 +
828 +       Updated the installation script.
829 +
830 +       Changed ld.so and ld-linux.so to look for LD_AOUT_PRELOAD
831 +       and LD_ELF_PRELOAD, respectively, before LD_PRELOAD.
832 +
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.
836 +
837 +Changes in version 1.6.0:
838 +
839 +       Changed ldconfig to process libraries which do not have
840 +       a minor version or patch level number.
841 +
842 +       Incorporated ld-linux.so and libdl.so.
843 +
844 +       Changed ld.so and ld-linux.so to not miss entries in the
845 +       cache when the fully qualified library is requested.
846 +
847 +       Changed ldconfig to use stdout instead of stderr when
848 +       printing the cache.
849 +
850 +Changes in version 1.5.3:
851 +
852 +       LD_PRELOAD enhancements (Tristan Gigold).
853 +
854 +       LD_PRELOAD patch for linux-68k (Andreas Schwab).
855 +
856 +Changes in version 1.5.2:
857 +
858 +       More ELF changes (Mitch D'Souza).
859 +
860 +       Changed ldconfig to also update the link for ld-linux.so.
861 +
862 +Changes in version 1.5.1:
863 +
864 +       More ELF and LD_PRELOAD changes (Mitch D'Souza).
865 +
866 +Changes in version 1.5.0:
867 +
868 +       Chnaged all executables to QMAGIC (Mitch D'Souza and Rick
869 +       Sladkey).
870 +
871 +       Added preliminary support for ELF to ldd and ldconfig (Eric 
872 +       Youndale and H.J. Lu).
873 +
874 +       Added support for LD_PRELOAD to ld.so (Mitch D'Souza).
875 +
876 +       Removed the "advertising" clause from the copyright notices
877 +       in all source files.
878 +
879 +Changes in version 1.4.4:
880 +
881 +       Changed ldconfig to support QMAGIC libraries.
882 +
883 +       Fixed a bug in ld.so where some of the error messages had
884 +       transposed arguments.
885 +
886 +Changes in version 1.4.3:
887 +
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.
890 +
891 +Changes in version 1.4.2:
892 +
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.
897 +
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.
902 +
903 +Changes in version 1.4.1:
904 +
905 +       Fixed minor Makefile problems.
906 +
907 +       Added support for linux-68k.
908 +
909 +       Fixed a bug in ld.so where libraries with absolute paths
910 +       were not handled correctly.
911 +
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.
916 +
917 +       Added a minimal usage message to ldconfig.
918 +
919 +Changes in version 1.4:
920 +
921 +       Fixed bug in ld.so where minor version numbers were not
922 +       reported correctly when a minor version incompatibility
923 +       was found.
924 +
925 +       Fixed bug in ldconfig where libraries with subversion
926 +       numbers greater than 9 were not compared correctly.
927 +
928 +       Added Mitch D'Souza's support for suppressing warning
929 +       messages from ld.so about minor version incompatibilities.
930 +
931 +       Added Mitch D'Souza's support for using a cache to speed
932 +       up searching for libraries in the standard directories.
933 +
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.
937 +
938 +Changes in version 1.3:
939 +
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.
943 +
944 +       Fixed a bug handling old libraries using a pathname beginning
945 +       with '/' or '/lib/'.
946 +
947 +Changes in version 1.2a:
948 +
949 +       Fixed a minor bug in ldd which caused all files, specifically
950 +       scripts, to be recognized as binaries.  Thanks to Olaf Flebbe
951 +       for reporting it.
952 +
953 +David Engel
954 +david@sw.ods.com
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
958 @@ -0,0 +1,4 @@
959 +elf.h
960 +ld_syscalls.h
961 +ld_sysdep.h
962 +boot1_arch.h
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
966 @@ -0,0 +1,22 @@
967 +/* User functions for run-time dynamic loading.  libdl version */
968 +#ifndef        _DLFCN_H
969 +#define        _DLFCN_H 1
970 +
971 +#include <features.h>
972 +#include <bits/dlfcn.h>
973 +
974 +#define RTLD_NEXT      ((void *) -1l)
975 +#define RTLD_DEFAULT   ((void *) 0)
976 +
977 +/* Structure containing information about object searched using
978 +   `dladdr'.  */
979 +typedef struct
980 +{
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.  */
985 +} Dl_info;
986 +
987 +
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
992 @@ -0,0 +1,93 @@
993 +#ifndef LINUXELF_H
994 +#define LINUXELF_H
995 +
996 +#include <ld_sysdep.h> /* before elf.h to get ELF_USES_RELOCA right */
997 +#include <elf.h>
998 +#include <link.h>
999 +
1000 +#ifdef DEBUG
1001 +#  define LDSO_CONF  "../util/ld.so.conf"
1002 +#  define LDSO_CACHE "../util/ld.so.cache"
1003 +#  define LDSO_PRELOAD "../util/ld.so.preload"
1004 +#else
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"
1008 +#endif
1009 +
1010 +
1011 +#define LIB_ANY             -1
1012 +#define LIB_DLL       0
1013 +#define LIB_ELF       1
1014 +#define LIB_ELF64     0x80
1015 +#define LIB_ELF_LIBC5 2
1016 +#define LIB_ELF_LIBC6 3
1017 +#define LIB_ELF_LIBC0 4
1018 +
1019 +/* Forward declarations for stuff defined in ld_hash.h */
1020 +struct dyn_elf;
1021 +struct elf_resolve;
1022 +
1023 +
1024 +/* Definitions and prototypes for cache stuff */
1025 +#ifdef USE_CACHE
1026 +extern int _dl_map_cache(void);
1027 +extern int _dl_unmap_cache(void);
1028 +
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)
1033 +
1034 +typedef struct {
1035 +       char magic   [LDSO_CACHE_MAGIC_LEN];
1036 +       char version [LDSO_CACHE_VER_LEN];
1037 +       int nlibs;
1038 +} header_t;
1039 +
1040 +typedef struct {
1041 +       int flags;
1042 +       int sooffset;
1043 +       int liboffset;
1044 +} libentry_t;
1045 +
1046 +#else
1047 +static inline void _dl_map_cache(void) { }
1048 +static inline void _dl_unmap_cache(void) { }
1049 +#endif 
1050 +
1051 +
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);
1066 +
1067 +
1068 +/*
1069 + * Datatype of a relocation on this platform
1070 + */
1071 +#ifdef ELF_USES_RELOCA
1072 +# define ELF_RELOC     ElfW(Rela)
1073 +#else
1074 +# define ELF_RELOC     ElfW(Rel)
1075 +#endif
1076 +
1077 +
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))
1083 +
1084 +
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
1089 @@ -0,0 +1,103 @@
1090 +#ifndef _LD_HASH_H_
1091 +#define _LD_HASH_H_
1092 +
1093 +#ifndef RTLD_NEXT
1094 +#define RTLD_NEXT      ((void*)-1)
1095 +#endif
1096 +
1097 +struct dyn_elf{
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;
1103 +};
1104 +
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;
1120 +  /*
1121 +   * These are only used with ELF style shared libraries
1122 +   */
1123 +  unsigned long nchain;
1124 +  unsigned long * chains;
1125 +  unsigned long dynamic_info[24];
1126 +
1127 +  unsigned long dynamic_size;
1128 +  unsigned long n_phent;
1129 +  Elf32_Phdr * ppnt;
1130 +
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;
1136 +#endif
1137 +
1138 +#ifdef __powerpc__
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;
1142 +#endif
1143 +};
1144 +
1145 +#define COPY_RELOCS_DONE    1
1146 +#define RELOCS_DONE         2
1147 +#define JMP_RELOCS_DONE     4
1148 +#define INIT_FUNCS_CALLED   8
1149 +
1150 +extern struct dyn_elf     * _dl_symbol_tables;
1151 +extern struct elf_resolve * _dl_loaded_modules;
1152 +extern struct dyn_elf    * _dl_handles;
1153 +
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);
1158 +
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);
1162 +
1163 +extern int _dl_linux_dynamic_link(void);
1164 +
1165 +extern char * _dl_library_path;
1166 +extern char * _dl_not_lazy;
1167 +extern unsigned long _dl_elf_hash(const char * name);
1168 +
1169 +static inline int _dl_symbol(char * name)
1170 +{
1171 +  if(name[0] != '_' || name[1] != 'd' || name[2] != 'l' || name[3] != '_')
1172 +    return 0;
1173 +  return 1;
1174 +}
1175 +
1176 +
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
1187 +
1188 +
1189 +
1190 +#endif /* _LD_HASH_H_ */
1191 +
1192 +
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
1196 @@ -0,0 +1,281 @@
1197 +#ifndef _LINUX_STRING_H_
1198 +#define _LINUX_STRING_H_
1199 +
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 *, ...);
1205 +
1206 +
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);
1221 +
1222 +#ifndef NULL
1223 +#define NULL ((void *) 0)
1224 +#endif
1225 +
1226 +static inline size_t _dl_strlen(const char * str)
1227 +{
1228 +       register char *ptr = (char *) str;
1229 +
1230 +       while (*ptr)
1231 +               ptr++;
1232 +       return (ptr - str);
1233 +}
1234 +
1235 +static inline char *_dl_strcat(char *dst, const char *src)
1236 +{
1237 +       register char *ptr = dst;
1238 +
1239 +       while (*ptr)
1240 +               ptr++;
1241 +
1242 +       while (*src)
1243 +               *ptr++ = *src++;
1244 +       *ptr = '\0';
1245 +
1246 +       return dst;
1247 +}
1248 +
1249 +static inline char * _dl_strcpy(char * dst,const char *src)
1250 +{
1251 +       register char *ptr = dst;
1252 +
1253 +       while (*src)
1254 +               *dst++ = *src++;
1255 +       *dst = '\0';
1256 +
1257 +       return ptr;
1258 +}
1259
1260 +static inline int _dl_strcmp(const char * s1,const char * s2)
1261 +{
1262 +       register unsigned char c1, c2;
1263 +
1264 +       do {
1265 +               c1 = (unsigned char) *s1++;
1266 +               c2 = (unsigned char) *s2++;
1267 +               if (c1 == '\0')
1268 +                       return c1 - c2;
1269 +       }
1270 +       while (c1 == c2);
1271 +
1272 +       return c1 - c2;
1273 +}
1274 +
1275 +static inline int _dl_strncmp(const char * s1,const char * s2,size_t len)
1276 +{
1277 +       register unsigned char c1 = '\0';
1278 +       register unsigned char c2 = '\0';
1279 +
1280 +       while (len > 0) {
1281 +               c1 = (unsigned char) *s1++;
1282 +               c2 = (unsigned char) *s2++;
1283 +               if (c1 == '\0' || c1 != c2)
1284 +                       return c1 - c2;
1285 +               len--;
1286 +       }
1287 +
1288 +       return c1 - c2;
1289 +}
1290 +
1291 +static inline char * _dl_strchr(const char * str,int c)
1292 +{
1293 +       register char ch;
1294 +
1295 +       do {
1296 +               if ((ch = *str) == c)
1297 +                       return (char *) str;
1298 +               str++;
1299 +       }
1300 +       while (ch);
1301 +
1302 +       return 0;
1303 +}
1304 +
1305 +static inline char *_dl_strrchr(const char *str, int c)
1306 +{
1307 +    register char *prev = 0;
1308 +    register char *ptr = (char *) str;
1309 +
1310 +    while (*ptr != '\0') {
1311 +       if (*ptr == c)
1312 +           prev = ptr;
1313 +       ptr++;  
1314 +    }   
1315 +    if (c == '\0')
1316 +       return(ptr);
1317 +    return(prev);
1318 +}
1319 +
1320 +
1321 +static inline char *_dl_strstr(const char *s1, const char *s2)
1322 +{
1323 +    register const char *s = s1;
1324 +    register const char *p = s2;
1325 +    
1326 +    do {
1327 +        if (!*p) {
1328 +           return (char *) s1;;
1329 +       }
1330 +       if (*p == *s) {
1331 +           ++p;
1332 +           ++s;
1333 +       } else {
1334 +           p = s2;
1335 +           if (!*s) {
1336 +             return NULL;
1337 +           }
1338 +           s = ++s1;
1339 +       }
1340 +    } while (1);
1341 +}
1342 +
1343 +static inline void * _dl_memcpy(void * dst, const void * src, size_t len)
1344 +{
1345 +       register char *a = dst;
1346 +       register const char *b = src;
1347 +
1348 +       while (len--)
1349 +               *a++ = *b++;
1350 +
1351 +       return dst;
1352 +}
1353 +
1354 +
1355 +static inline int _dl_memcmp(const void * s1,const void * s2,size_t len)
1356 +{
1357 +       unsigned char *c1 = (unsigned char *)s1;
1358 +       unsigned char *c2 = (unsigned char *)s2;
1359 +
1360 +       while (len--) {
1361 +               if (*c1 != *c2) 
1362 +                       return *c1 - *c2;
1363 +               c1++;
1364 +               c2++;
1365 +       }
1366 +       return 0;
1367 +}
1368 +
1369 +static inline void * _dl_memset(void * str,int c,size_t len)
1370 +{
1371 +       register char *a = str;
1372 +
1373 +       while (len--)
1374 +               *a++ = c;
1375 +
1376 +       return str;
1377 +}
1378 +
1379 +static inline char *_dl_get_last_path_component(char *path)
1380 +{
1381 +       char *s;
1382 +       register char *ptr = path;
1383 +       register char *prev = 0;
1384 +
1385 +       while (*ptr)
1386 +               ptr++;
1387 +       s = ptr - 1;
1388 +
1389 +       /* strip trailing slashes */
1390 +       while (s != path && *s == '/') {
1391 +               *s-- = '\0';
1392 +       }
1393 +
1394 +       /* find last component */
1395 +       ptr = path;
1396 +       while (*ptr != '\0') {
1397 +           if (*ptr == '/')
1398 +               prev = ptr;
1399 +           ptr++;  
1400 +       }   
1401 +       s = prev;
1402 +
1403 +       if (s == NULL || s[1] == '\0')
1404 +               return path;
1405 +       else
1406 +               return s+1;
1407 +}
1408 +
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)
1412 +{
1413 +       /* 21 digits plus null terminator, good for 64-bit or smaller ints */
1414 +       char *p = &local[22];
1415 +       *p-- = '\0';
1416 +       do {
1417 +               *p-- = '0' + i % 10;
1418 +               i /= 10;
1419 +       } while (i > 0);
1420 +       return p + 1;
1421 +}
1422 +
1423 +static inline char *_dl_simple_ltoahex(char * local, unsigned long i)
1424 +{
1425 +       /* 21 digits plus null terminator, good for 64-bit or smaller ints */
1426 +       char *p = &local[22];
1427 +       *p-- = '\0';
1428 +       do {
1429 +               char temp = i % 0x10;
1430 +               if (temp <= 0x09)
1431 +                   *p-- = '0' + temp;
1432 +               else
1433 +                   *p-- = 'a' - 0x0a + temp;
1434 +               i /= 0x10;
1435 +       } while (i > 0);
1436 +       *p-- = 'x';
1437 +       *p-- = '0';
1438 +       return p + 1;
1439 +}
1440 +
1441 +
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));      \
1449 +  }
1450 +#else
1451 +#define SEND_STDERR(X) _dl_write(2, X, _dl_strlen(X));
1452 +#endif
1453 +
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) { \
1460 +       tmp[0]='\n'; \
1461 +       _dl_write(2, tmp, 1); \
1462 +    } \
1463 +};
1464 +
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) { \
1471 +       tmp[0]='\n'; \
1472 +       _dl_write(2, tmp, 1); \
1473 +    } \
1474 +};
1475 +
1476 +
1477 +#endif
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
1481 @@ -0,0 +1,157 @@
1482 +#ifndef _LD_SYSCALL_H_
1483 +#define _LD_SYSCALL_H_
1484 +
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>
1494 +
1495 +
1496 +/* Encoding of the file mode.  */
1497 +#define        S_IFMT          0170000 /* These bits determine file type.  */
1498 +
1499 +/* File types.  */
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.  */
1507 +
1508 +/* Protection bits.  */
1509 +
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.  */
1516 +
1517 +
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. */
1524 +
1525 +
1526 +#define __NR__dl_exit __NR_exit
1527 +static inline _syscall1(void, _dl_exit, int, status);
1528 +
1529 +
1530 +#define __NR__dl_close __NR_close
1531 +static inline _syscall1(int, _dl_close, int, fd);
1532 +
1533 +
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);
1539 +#else
1540 +#define __NR__dl_mmap_real __NR_mmap
1541 +static inline _syscall1(void *, _dl_mmap_real, unsigned long *, buffer);
1542 +
1543 +static inline void * _dl_mmap(void * addr, unsigned long size, int prot,
1544 +               int flags, int fd, unsigned long offset)
1545 +{
1546 +       unsigned long buffer[6];
1547 +
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);
1555 +}
1556 +#endif
1557 +
1558 +#ifndef _dl_MAX_ERRNO
1559 +#define _dl_MAX_ERRNO 4096
1560 +#endif
1561 +#define _dl_mmap_check_error(__res)    \
1562 +       (((int)__res) < 0 && ((int)__res) >= -_dl_MAX_ERRNO)
1563 +#ifndef MAP_ANONYMOUS
1564 +#ifdef __sparc__
1565 +#define MAP_ANONYMOUS 0x20
1566 +#else
1567 +#error MAP_ANONYMOUS not defined and suplementary value not known
1568 +#endif
1569 +#endif
1570 +
1571 +
1572 +#define __NR__dl_open __NR_open
1573 +#define O_RDONLY        0x0000
1574 +#define O_WRONLY            01
1575 +#define O_RDWR              02
1576 +#define O_CREAT                   0100 /* not fcntl */
1577 +static inline _syscall2(int, _dl_open, const char *, fn, int, flags);
1578 +
1579 +#define __NR__dl_write __NR_write
1580 +static inline _syscall3(unsigned long, _dl_write, int, fd, 
1581 +           const void *, buf, unsigned long, count);
1582 +
1583 +
1584 +#define __NR__dl_read __NR_read
1585 +static inline _syscall3(unsigned long, _dl_read, int, fd, 
1586 +           const void *, buf, unsigned long, count);
1587 +
1588 +#define __NR__dl_mprotect __NR_mprotect
1589 +static inline _syscall3(int, _dl_mprotect, const void *, addr, unsigned long, len, int, prot);
1590 +
1591 +
1592 +
1593 +#define __NR__dl_stat __NR_stat
1594 +static inline _syscall2(int, _dl_stat, const char *, file_name, struct stat *, buf);
1595 +
1596 +
1597 +#define __NR__dl_munmap __NR_munmap
1598 +static inline _syscall2(int, _dl_munmap, void *, start, unsigned long, length);
1599 +
1600 +#define __NR__dl_getuid __NR_getuid
1601 +static inline _syscall0(uid_t, _dl_getuid);
1602 +
1603 +#define __NR__dl_geteuid __NR_geteuid
1604 +static inline _syscall0(uid_t, _dl_geteuid);
1605 +
1606 +#define __NR__dl_getgid __NR_getgid
1607 +static inline _syscall0(gid_t, _dl_getgid);
1608 +
1609 +#define __NR__dl_getegid __NR_getegid
1610 +static inline _syscall0(gid_t, _dl_getegid);
1611 +
1612 +#define __NR__dl_getpid __NR_getpid
1613 +static inline _syscall0(gid_t, _dl_getpid);
1614 +
1615 +/*
1616 + * Not an actual syscall, but we need something in assembly to say whether
1617 + * this is OK or not.
1618 + */
1619 +static inline int _dl_suid_ok(void)
1620 +{
1621 +    uid_t uid, euid, gid, egid;
1622 +
1623 +    uid = _dl_getuid();
1624 +    euid = _dl_geteuid();
1625 +    gid = _dl_getgid();
1626 +    egid = _dl_getegid();
1627 +
1628 +    if(uid == euid && gid == egid)
1629 +       return 1;
1630 +    else
1631 +       return 0;
1632 +}
1633 +
1634 +#define __NR__dl_readlink __NR_readlink
1635 +static inline _syscall3(int, _dl_readlink, const char *, path, char *, buf, size_t, bufsiz);
1636 +
1637 +#endif /* _LD_SYSCALL_H_ */
1638 +
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
1642 @@ -0,0 +1,11 @@
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
1657 @@ -0,0 +1,2 @@
1658 +ld-uclibc.so*
1659 +_dl_progname.h
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
1663 @@ -0,0 +1,101 @@
1664 +# Makefile for uClibc
1665 +#
1666 +# Copyright (C) 2000 by Lineo, inc.
1667 +# Copyright (C) 2000-2002 Erik Andersen <andersen@uclibc.org>
1668 +#
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
1672 +# later version.
1673 +#
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
1677 +# details.
1678 +#
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
1682 +#
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.
1686 +
1687 +
1688 +TOPDIR=../../
1689 +include $(TOPDIR)Rules.mak
1690 +LDSO_FULLNAME=ld-uClibc-$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBLEVEL).so
1691 +
1692 +
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
1696 +
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
1703 +# debug things....
1704 +XXFLAGS+=-Os #-g3
1705 +endif
1706 +
1707 +# BEWARE!!! At least mips* will die if -O0 is used!!!
1708 +XXFLAGS :=$(XXFLAGS:-O0=-O1)
1709 +
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
1713 +
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)
1719 +
1720 +ifneq ($(strip $(SUPPORT_LD_DEBUG)),y)
1721 +LDFLAGS+=-s
1722 +endif
1723 +
1724 +ifeq ($(strip $(SUPPORT_LD_DEBUG)),y)
1725 +XXFLAGS+=-D__SUPPORT_LD_DEBUG__
1726 +endif
1727 +
1728 +ifeq ($(strip $(SUPPORT_LD_DEBUG_EARLY)),y)
1729 +XXFLAGS+=-D__SUPPORT_LD_DEBUG_EARLY__
1730 +endif
1731 +
1732 +ifeq ($(strip $(FORCE_SHAREABLE_TEXT_SEGMENTS)),y)
1733 +XXFLAGS+=-DFORCE_SHAREABLE_TEXT_SEGMENTS
1734 +endif
1735 +
1736 +#This stuff will not work with -fomit-frame-pointer
1737 +XXFLAGS := $(XXFLAGS:-fomit-frame-pointer=)
1738 +
1739 +all: lib
1740 +
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)
1747 +
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
1751 +
1752 +
1753 +$(COBJS): %.o : %.c
1754 +       $(CC) $(XXFLAGS) -I../libdl -c $< -o $@
1755 +       $(STRIPTOOL) -x -R .note -R .comment $*.o
1756 +
1757 +$(AOBJS): %.o : %.S
1758 +       $(CC) $(XXFLAGS) -I../libdl -c $< -o $@
1759 +       $(STRIPTOOL) -x -R .note -R .comment $*.o
1760 +
1761 +ldso.o: ldso.c hash.c readelflib1.c $(TARGET_ARCH)/elfinterp.c _dl_progname.h
1762 +
1763 +clean:
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
1768 @@ -0,0 +1,30 @@
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.  */
1772 +
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. */
1775 +
1776 +asm("" \
1777 +"      .text\n"                        \
1778 +"      .globl  _dl_boot\n"             \
1779 +"_dl_boot:\n"                          \
1780 +"      mov     r7, sp\n"               \
1781 +"      @ldr    r0, [sp], #4\n"         \
1782 +"      mov     r0, sp\n"               \
1783 +"      bl      _dl_boot2\n"            \
1784 +"      mov     r6, r0\n"               \
1785 +"      mov     r0, r7\n"               \
1786 +"      mov     pc, r6\n"               \
1787 +);
1788 +
1789 +#define _dl_boot _dl_boot2
1790 +#define LD_BOOT(X)   static void *  __attribute__ ((unused)) _dl_boot (X)
1791 +
1792 +
1793 + /* It seems ARM needs an offset here */
1794 +#undef ELFMAGIC
1795 +#define            ELFMAGIC    ELFMAG+load_addr 
1796 +
1797 +
1798 +
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
1802 @@ -0,0 +1,462 @@
1803 +/* vi: set sw=4 ts=4: */
1804 +/* ARM ELF shared library loader suppport
1805 + *
1806 + * Copyright (C) 2001-2002, Erik Andersen
1807 + *
1808 + * All rights reserved.
1809 + *
1810 + * Redistribution and use in source and binary forms, with or without
1811 + * modification, are permitted provided that the following conditions
1812 + * are met:
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.
1818 + *
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
1829 + * SUCH DAMAGE.
1830 + */
1831 +
1832 +#if defined (__SUPPORT_LD_DEBUG__)
1833 +static const char *_dl_reltypes_tab[] =
1834 +{
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",
1847 +};
1848 +
1849 +static const char *
1850 +_dl_reltypes(int type)
1851 +{
1852 +  static char buf[22];  
1853 +  const char *str;
1854 +  
1855 +  if (type >= (sizeof (_dl_reltypes_tab)/sizeof(_dl_reltypes_tab[0])) ||
1856 +      NULL == (str = _dl_reltypes_tab[type]))
1857 +  {
1858 +    str =_dl_simple_ltoa( buf, (unsigned long)(type));
1859 +  }
1860 +  return str;
1861 +}
1862 +
1863 +static 
1864 +void debug_sym(Elf32_Sym *symtab,char *strtab,int symtab_index)
1865 +{
1866 +  if(_dl_debug_symbols)
1867 +  {
1868 +    if(symtab_index){
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);
1876 +    }
1877 +  }
1878 +}
1879 +
1880 +static void debug_reloc(Elf32_Sym *symtab,char *strtab, ELF_RELOC *rpnt)
1881 +{
1882 +  if(_dl_debug_reloc)
1883 +  {
1884 +    int symtab_index;
1885 +    const char *sym;
1886 +    symtab_index = ELF32_R_SYM(rpnt->r_info);
1887 +    sym = symtab_index ? strtab + symtab[symtab_index].st_name : "sym=0x0";
1888 +    
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)),
1892 +               rpnt->r_offset,
1893 +               rpnt->r_addend,
1894 +               sym);
1895 +#else
1896 +    _dl_dprintf(_dl_debug_file, "\n%s\toffset=%x %s",
1897 +               _dl_reltypes(ELF32_R_TYPE(rpnt->r_info)),
1898 +               rpnt->r_offset,
1899 +               sym);
1900 +#endif
1901 +  }
1902 +}
1903 +#endif
1904 +
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. */
1908 +
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
1914 +   working. */
1915 +
1916 +extern int _dl_linux_resolve(void);
1917 +
1918 +unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
1919 +{
1920 +       int reloc_type;
1921 +       ELF_RELOC *this_reloc;
1922 +       char *strtab;
1923 +       Elf32_Sym *symtab;
1924 +       ELF_RELOC *rel_addr;
1925 +       int symtab_index;
1926 +       char *new_addr;
1927 +       char **got_addr;
1928 +       unsigned long instr_addr;
1929 +
1930 +       rel_addr = (ELF_RELOC *) (tpnt->dynamic_info[DT_JMPREL] + tpnt->loadaddr);
1931 +
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);
1935 +
1936 +       symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
1937 +       strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
1938 +
1939 +
1940 +       if (reloc_type != R_ARM_JUMP_SLOT) {
1941 +               _dl_dprintf(2, "%s: Incorrect relocation type in jump relocations\n", 
1942 +                       _dl_progname);
1943 +               _dl_exit(1);
1944 +       };
1945 +
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;
1950 +
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);
1954 +       if (!new_addr) {
1955 +               _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", 
1956 +                       _dl_progname, strtab + symtab[symtab_index].st_name);
1957 +               _dl_exit(1);
1958 +       };
1959 +#if defined (__SUPPORT_LD_DEBUG__)
1960 +       if ((unsigned long) got_addr < 0x40000000)
1961 +       {
1962 +               if (_dl_debug_bindings)
1963 +               {
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);
1968 +               }
1969 +       }
1970 +       if (!_dl_debug_nofixups) {
1971 +               *got_addr = new_addr;
1972 +       }
1973 +#else
1974 +       *got_addr = new_addr;
1975 +#endif
1976 +
1977 +       return (unsigned long) new_addr;
1978 +}
1979 +
1980 +static int
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))
1985 +{
1986 +       int i;
1987 +       char *strtab;
1988 +       int goof = 0;
1989 +       Elf32_Sym *symtab;
1990 +       ELF_RELOC *rpnt;
1991 +       int symtab_index;
1992 +       /* Now parse the relocation information */
1993 +
1994 +       rpnt = (ELF_RELOC *) (rel_addr + tpnt->loadaddr);
1995 +       rel_size = rel_size / sizeof(ELF_RELOC);
1996 +
1997 +       symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
1998 +       strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
1999 +
2000 +         for (i = 0; i < rel_size; i++, rpnt++) {
2001 +               int res;
2002 +           
2003 +               symtab_index = ELF32_R_SYM(rpnt->r_info);
2004 +               
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)
2008 +                       continue;
2009 +               if (symtab_index && tpnt->libtype == program_interpreter &&
2010 +                   _dl_symbol(strtab + symtab[symtab_index].st_name))
2011 +                       continue;
2012 +
2013 +#if defined (__SUPPORT_LD_DEBUG__)
2014 +               debug_sym(symtab,strtab,symtab_index);
2015 +               debug_reloc(symtab,strtab,rpnt);
2016 +#endif
2017 +
2018 +               res = reloc_fnc (tpnt, scope, rpnt, symtab, strtab);
2019 +
2020 +               if (res==0) continue;
2021 +
2022 +               _dl_dprintf(2, "\n%s: ",_dl_progname);
2023 +               
2024 +               if (symtab_index)
2025 +                 _dl_dprintf(2, "symbol '%s': ", strtab + symtab[symtab_index].st_name);
2026 +                 
2027 +               if (res <0)
2028 +               {
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));
2032 +#else
2033 +                       _dl_dprintf(2, "can't handle reloc type %x\n", reloc_type);
2034 +#endif                 
2035 +                       _dl_exit(-res);
2036 +               }
2037 +               else if (res >0)
2038 +               {
2039 +                       _dl_dprintf(2, "can't resolve symbol\n");
2040 +                       goof += res;
2041 +               }
2042 +         }
2043 +         return goof;
2044 +}
2045 +
2046 +static unsigned long
2047 +fix_bad_pc24 (unsigned long *const reloc_addr, unsigned long value)
2048 +{
2049 +  static void *fix_page;
2050 +  static unsigned int fix_offset;
2051 +  unsigned int *fix_address;
2052 +  if (! fix_page)
2053 +    {
2054 +      fix_page = _dl_mmap (NULL,  4096   , PROT_READ | PROT_WRITE | PROT_EXEC,
2055 +                       MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
2056 +      fix_offset = 0;
2057 +    }
2058 +
2059 +  fix_address = (unsigned int *)(fix_page + fix_offset);
2060 +  fix_address[0] = 0xe51ff004;  /* ldr pc, [pc, #-4] */
2061 +  fix_address[1] = value;
2062 +
2063 +  fix_offset += 8;
2064 +  if (fix_offset >= 4096)
2065 +    fix_page = NULL;
2066 +
2067 +  return (unsigned long)fix_address;
2068 +}
2069 +
2070 +static int
2071 +_dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope,
2072 +             ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)
2073 +{
2074 +       int reloc_type;
2075 +       int symtab_index;
2076 +       unsigned long *reloc_addr;
2077 +       unsigned long symbol_addr;
2078 +       int goof = 0;
2079 +
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);
2083 +       symbol_addr = 0;
2084 +
2085 +       if (symtab_index) {
2086 +
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);
2089 +
2090 +               /*
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.
2094 +                */
2095 +               if (!symbol_addr && ELF32_ST_BIND(symtab[symtab_index].st_info) == STB_GLOBAL) {
2096 +                       goof++;
2097 +               }
2098 +       }
2099 +
2100 +#if defined (__SUPPORT_LD_DEBUG__)
2101 +       {
2102 +               unsigned long old_val = *reloc_addr;
2103 +#endif
2104 +               switch (reloc_type) {
2105 +                       case R_ARM_NONE:
2106 +                               break;
2107 +                       case R_ARM_ABS32:
2108 +                               *reloc_addr += symbol_addr;
2109 +                               break;
2110 +                       case R_ARM_PC24:
2111 +                               {
2112 +                                       unsigned long addend;
2113 +                                       long newvalue, topbits;
2114 +
2115 +                                       addend = *reloc_addr & 0x00ffffff;
2116 +                                       if (addend & 0x00800000) addend |= 0xff000000;
2117 +
2118 +                                       newvalue = symbol_addr - (unsigned long)reloc_addr + (addend << 2);
2119 +                                       topbits = newvalue & 0xfe000000;
2120 +                                       if (topbits != 0xfe000000 && topbits != 0x00000000)
2121 +                                       {
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)
2126 +                                               {
2127 +                                                       _dl_dprintf(2,"symbol '%s': R_ARM_PC24 relocation out of range.", 
2128 +                                                               symtab[symtab_index].st_name);
2129 +                                                       _dl_exit(1);
2130 +                                               }
2131 +                                       }
2132 +                                       newvalue >>= 2;
2133 +                                       symbol_addr = (*reloc_addr & 0xff000000) | (newvalue & 0x00ffffff);
2134 +                                       *reloc_addr = symbol_addr;
2135 +                                       break;
2136 +                               }
2137 +                       case R_ARM_GLOB_DAT:
2138 +                       case R_ARM_JUMP_SLOT:
2139 +                               *reloc_addr = symbol_addr;
2140 +                               break;
2141 +                       case R_ARM_RELATIVE:
2142 +                               *reloc_addr += (unsigned long) tpnt->loadaddr;
2143 +                               break;
2144 +                       case R_ARM_COPY:                                                
2145 +#if 0                                                  
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);
2152 +#endif
2153 +                               break;
2154 +                       default:
2155 +                               return -1; /*call _dl_exit(1) */
2156 +               }
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);
2160 +       }
2161 +
2162 +#endif
2163 +
2164 +       return goof;
2165 +}
2166 +
2167 +static int
2168 +_dl_do_lazy_reloc (struct elf_resolve *tpnt, struct dyn_elf *scope,
2169 +                  ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)
2170 +{
2171 +       int reloc_type;
2172 +       unsigned long *reloc_addr;
2173 +
2174 +       reloc_addr = (unsigned long *) (tpnt->loadaddr + (unsigned long) rpnt->r_offset);
2175 +       reloc_type = ELF32_R_TYPE(rpnt->r_info);
2176 +
2177 +#if defined (__SUPPORT_LD_DEBUG__)
2178 +       {
2179 +               unsigned long old_val = *reloc_addr;
2180 +#endif
2181 +               switch (reloc_type) {
2182 +                       case R_ARM_NONE:
2183 +                               break;
2184 +                       case R_ARM_JUMP_SLOT:
2185 +                               *reloc_addr += (unsigned long) tpnt->loadaddr;
2186 +                               break;
2187 +                       default:
2188 +                               return -1; /*call _dl_exit(1) */
2189 +               }
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);
2193 +       }
2194 +
2195 +#endif
2196 +       return 0;
2197 +
2198 +}
2199 +
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. */
2205 +
2206 +/* No, there are cases where the SVr4 linker fails to emit COPY relocs
2207 +   at all */
2208 +static int
2209 +_dl_do_copy (struct elf_resolve *tpnt, struct dyn_elf *scope,
2210 +            ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)
2211 +{
2212 +        int reloc_type;
2213 +       int symtab_index;
2214 +       unsigned long *reloc_addr;
2215 +       unsigned long symbol_addr;
2216 +       int goof = 0;
2217 +         
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) 
2221 +               return 0;
2222 +       symtab_index = ELF32_R_SYM(rpnt->r_info);
2223 +       symbol_addr = 0;
2224 +               
2225 +       if (symtab_index) {
2226 +
2227 +               symbol_addr = (unsigned long) _dl_find_hash(strtab + 
2228 +                       symtab[symtab_index].st_name, scope, 
2229 +                       NULL, copyrel);
2230 +               if (!symbol_addr) goof++;
2231 +       }
2232 +       if (!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);
2239 +#endif
2240 +               _dl_memcpy((char *) symtab[symtab_index].st_value, 
2241 +                       (char *) symbol_addr, symtab[symtab_index].st_size);
2242 +       }
2243 +
2244 +       return goof;
2245 +}
2246 +
2247 +void _dl_parse_lazy_relocation_information(struct elf_resolve *tpnt, 
2248 +       unsigned long rel_addr, unsigned long rel_size, int type)
2249 +{
2250 +  (void)_dl_parse(tpnt, NULL, rel_addr, rel_size, _dl_do_lazy_reloc);
2251 +}
2252 +
2253 +int _dl_parse_relocation_information(struct elf_resolve *tpnt, 
2254 +       unsigned long rel_addr, unsigned long rel_size, int type)
2255 +{
2256 +  return _dl_parse(tpnt, tpnt->symbol_scope, rel_addr, rel_size, _dl_do_reloc);
2257 +}
2258 +
2259 +int _dl_parse_copy_information(struct dyn_elf *xpnt, unsigned long rel_addr, 
2260 +       unsigned long rel_size, int type)
2261 +{
2262 +  return _dl_parse(xpnt->dyn, xpnt->next, rel_addr, rel_size, _dl_do_copy);
2263 +}
2264 +
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
2268 @@ -0,0 +1,19 @@
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. */
2272 +
2273 +#define __set_errno(X) {(void)(X);}
2274 +
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)
2278 +#endif
2279 +#ifndef likely
2280 +# define likely(x)     __builtin_expect((!!(x)),1)
2281 +#endif
2282 +#ifndef unlikely
2283 +# define unlikely(x)   __builtin_expect((!!(x)),0)
2284 +#endif
2285 +
2286 +#include "sys/syscall.h"
2287 +
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
2291 @@ -0,0 +1,124 @@
2292 +/*
2293 + * Various assmbly language/system dependent  hacks that are required
2294 + * so that we can minimize the amount of platform specific code.
2295 + */
2296 +
2297 +/* 
2298 + * Define this if the system uses RELOCA.
2299 + */
2300 +#undef ELF_USES_RELOCA
2301 +
2302 +/*
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.
2306 + */
2307 +#define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned long*)   ARGS)
2308 +
2309 +/*
2310 + * Initialization sequence for a GOT.
2311 + */
2312 +#define INIT_GOT(GOT_BASE,MODULE) \
2313 +{                              \
2314 +  GOT_BASE[2] = (unsigned long) _dl_linux_resolve; \
2315 +  GOT_BASE[1] = (unsigned long) MODULE; \
2316 +}
2317 +
2318 +/*
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
2323 + * load address.
2324 + */
2325 +#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD)          \
2326 +       switch(ELF32_R_TYPE((RELP)->r_info)){                   \
2327 +       case R_ARM_ABS32:                                       \
2328 +         *REL += SYMBOL;                                       \
2329 +         break;                                                \
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); } }                                    \
2343 +           newvalue>>=2;                                       \
2344 +           SYMBOL=(*REL&0xff000000)|(newvalue & 0x00ffffff);   \
2345 +           *REL=SYMBOL;                                        \
2346 +           }                                                   \
2347 +         break;                                                \
2348 +       case R_ARM_GLOB_DAT:                                    \
2349 +       case R_ARM_JUMP_SLOT:                                   \
2350 +         *REL = SYMBOL;                                        \
2351 +         break;                                                \
2352 +        case R_ARM_RELATIVE:                                   \
2353 +         *REL += (unsigned long) LOAD;                         \
2354 +         break;                                                \
2355 +        case R_ARM_NONE:                                       \
2356 +         break;                                                \
2357 +       default:                                                \
2358 +         SEND_STDERR("Aiieeee!");                              \
2359 +         _dl_exit(1);                                          \
2360 +       }
2361 +
2362 +
2363 +/*
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.
2367 + */
2368 +
2369 +#define START()   return _dl_elf_main;      
2370 +
2371 +
2372 +
2373 +/* Here we define the magic numbers that this dynamic loader should accept */
2374 +
2375 +#define MAGIC1 EM_ARM
2376 +#undef  MAGIC2
2377 +/* Used for error messages */
2378 +#define ELF_TARGET "ARM"
2379 +
2380 +struct elf_resolve;
2381 +unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
2382 +
2383 +static inline unsigned long arm_modulus(unsigned long m, unsigned long p) {
2384 +       unsigned long i,t,inc;
2385 +        i=p; t=0;
2386 +        while(!(i&(1<<31))) {
2387 +                i<<=1;
2388 +                t++;
2389 +        }
2390 +        t--;
2391 +        for(inc=t;inc>2;inc--) {
2392 +                i=p<<inc;
2393 +                if(i&(1<<31))
2394 +                        break;
2395 +                while(m>=i) {
2396 +                        m-=i;
2397 +                        i<<=1;
2398 +                        if(i&(1<<31))
2399 +                                break;
2400 +                        if(i<p)
2401 +                                break;
2402 +                }
2403 +        }
2404 +        while(m>=p) {
2405 +                m-=p;
2406 +        }
2407 +        return m;
2408 +}
2409 +
2410 +#define do_rem(result, n, base)  result=arm_modulus(n,base);
2411 +
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
2419 @@ -0,0 +1,43 @@
2420 +/*
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:
2426 + *     reloc_entry
2427 + *     tpnt
2428 + *
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.  
2437 + *  -Erik Andersen
2438 + */
2439 +
2440 +#define sl r10
2441 +#define fp r11
2442 +#define ip r12
2443 +
2444 +.text
2445 +.globl _dl_linux_resolve
2446 +.type _dl_linux_resolve,%function
2447 +.align 4;
2448 +
2449 +_dl_linux_resolve:
2450 +       stmdb sp!, {r0, r1, r2, r3, sl, fp}
2451 +       sub r1, ip, lr
2452 +       sub r1, r1, #4
2453 +       add r1, r1, r1
2454 +       ldr r0, [lr, #-4]
2455 +       mov r3,r0
2456 +
2457 +       bl _dl_linux_resolver
2458 +
2459 +       mov ip, r0
2460 +       ldmia sp!, {r0, r1, r2, r3, sl, fp, lr}
2461 +       mov pc,ip
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
2466 @@ -0,0 +1,17 @@
2467 +/*
2468 + * This code fix the stack pointer so that the dynamic linker
2469 + * can find argc, argv and auxvt (Auxillary Vector Table).
2470 + */
2471 +asm(""                                 \
2472 +"      .text\n"                        \
2473 +"      .globl _dl_boot\n"              \
2474 +"      .type _dl_boot,@function\n"     \
2475 +"_dl_boot:\n"                          \
2476 +"      move.d $sp,$r10\n"              \
2477 +"      move.d $pc,$r9\n"               \
2478 +"      add.d _dl_boot2 - ., $r9\n"     \
2479 +"      jsr $r9\n"                      \
2480 +);
2481 +
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
2487 @@ -0,0 +1,414 @@
2488 +/*
2489 + * CRIS ELF shared library loader support.
2490 + *
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
2494 + * library.
2495 + *
2496 + * Copyright (C) 2002, Axis Communications AB
2497 + * All rights reserved
2498 + *
2499 + * Author: Tobias Anderberg, <tobiasa@axis.com>
2500 + *
2501 + * Redistribution and use in source and binary forms, with or without
2502 + * modification, are permitted provided that the following conditions
2503 + * are met:
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.
2509 + *
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
2520 + * SUCH DAMAGE.
2521 + */
2522 +
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",
2531 +
2532 +};
2533 +
2534 +
2535 +static const char *
2536 +_dl_reltypes(int type)
2537 +{
2538 +       const char *str;
2539 +       static char buf[22];
2540 +
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));
2544 +       
2545 +       return str;
2546 +}
2547 +
2548 +static void 
2549 +debug_sym(Elf32_Sym *symtab, char *strtab, int symtab_index)
2550 +{ 
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);
2561 +               }
2562 +       }
2563 +}
2564 +
2565 +static void
2566 +debug_reloc(Elf32_Sym *symtab, char *strtab, ELF_RELOC *rpnt)
2567 +{
2568 +       if (_dl_debug_reloc) {
2569 +               int symtab_index;
2570 +               const char *sym;
2571 +
2572 +               symtab_index = ELF32_R_SYM(rpnt->r_info);
2573 +               sym = symtab_index ? strtab + symtab[symtab_index].st_name : "sym=0x0";
2574 +
2575 +               if (_dl_debug_symbols)
2576 +                       _dl_dprintf(_dl_debug_file, "\n\t");
2577 +               else
2578 +                       _dl_dprintf(_dl_debug_file, "\n%s\n\t", sym);
2579 +
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)),
2583 +                       rpnt->r_offset,
2584 +                       rpnt->r_addend);
2585 +#else
2586 +               _dl_dprintf(_dl_debug_file, "%s\toffset%x\n",
2587 +                       _dl_reltypes(ELF32_R_TYPE(rpnt->r_info)),
2588 +                       rpnt->r_offset);
2589 +#endif
2590 +       }
2591 +}
2592 +#endif /* __SUPPORT_LD_DEBUG__ */
2593 +
2594 +/* Defined in resolve.S. */
2595 +extern int _dl_linux_resolv(void);
2596 +
2597 +unsigned long
2598 +_dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
2599 +{
2600 +       int reloc_type;
2601 +       int symtab_index;
2602 +       char *strtab;
2603 +       char *symname;
2604 +       char *new_addr;
2605 +       char *rel_addr;
2606 +       char **got_addr;
2607 +       Elf32_Sym *symtab;
2608 +       ELF_RELOC *this_reloc;
2609 +       unsigned long instr_addr;
2610 +
2611 +       rel_addr = (char *) (tpnt->dynamic_info[DT_JMPREL] + tpnt->loadaddr);
2612 +
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);
2616 +
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;
2620 +
2621 +       if (reloc_type != R_CRIS_JUMP_SLOT) {
2622 +               _dl_dprintf(2, "%s: Incorrect relocation type for jump relocations.\n",
2623 +                       _dl_progname);
2624 +               _dl_exit(1);
2625 +       }
2626 +
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;
2630 +
2631 +       /* Fetch the address of the GOT entry. */
2632 +       new_addr = _dl_find_hash(symname, tpnt->symbol_scope, tpnt, resolver);
2633 +
2634 +       if (!new_addr) {
2635 +               new_addr = _dl_find_hash(symname, NULL, NULL, resolver);
2636 +
2637 +               if (new_addr)
2638 +                       return (unsigned long) new_addr;
2639 +
2640 +               _dl_dprintf(2, "%s: Can't resolv symbol '%s'\n", _dl_progname, symname);
2641 +               _dl_exit(1);
2642 +       }
2643 +
2644 +#if defined (__SUPPORT_LD_DEBUG__)
2645 +       if (_dl_debug_bindings) {
2646 +               _dl_dprintf(_dl_debug_file, "\nresolve function: %s", symname);
2647 +               
2648 +               if (_dl_debug_detail)
2649 +                       _dl_dprintf(_dl_debug_file, "\tpatch %x ==> %x @ %x", *got_addr, new_addr, got_addr);
2650 +       }
2651 +#endif
2652 +
2653 +       *got_addr = new_addr;
2654 +       return (unsigned long) new_addr;
2655 +}
2656 +
2657 +static int
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))
2661 +{
2662 +       int symtab_index;
2663 +       int res;
2664 +       unsigned int i;
2665 +       char *strtab;
2666 +       Elf32_Sym *symtab;
2667 +       ELF_RELOC *rpnt;
2668 +
2669 +       /* Parse the relocation information. */
2670 +       rpnt = (ELF_RELOC *) (intptr_t) (rel_addr + tpnt->loadaddr);
2671 +       rel_size /= sizeof(ELF_RELOC);
2672 +
2673 +       symtab = (Elf32_Sym *) (intptr_t) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
2674 +       strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
2675 +
2676 +       for (i = 0; i < rel_size; i++, rpnt++) {
2677 +               symtab_index = ELF32_R_SYM(rpnt->r_info);
2678 +
2679 +               /* 
2680 +                * Make sure the same symbols that the linker resolved when it
2681 +                * bootstapped itself isn't resolved again.
2682 +                */
2683 +               if (!symtab_index && tpnt->libtype == program_interpreter)
2684 +                       continue;
2685 +
2686 +               if (symtab_index && tpnt->libtype == program_interpreter &&
2687 +                       _dl_symbol(strtab + symtab[symtab_index].st_name))
2688 +                       continue;
2689 +
2690 +#if defined (__SUPPORT_LD_DEBUG__)
2691 +               debug_sym(symtab, strtab, symtab_index);
2692 +               debug_reloc(symtab, strtab, rpnt);
2693 +#endif
2694 +
2695 +               /* Pass over to actual relocation function. */
2696 +               res = reloc_fnc(tpnt, scope, rpnt, symtab, strtab);
2697 +
2698 +               if (res == 0)
2699 +                       continue;
2700 +
2701 +               _dl_dprintf(2, "\n%s: ", _dl_progname);
2702 +
2703 +               if (symtab_index)
2704 +                       _dl_dprintf(2, "symbol '%s': ", strtab + symtab[symtab_index].st_name);
2705 +
2706 +               if (res < 0) {
2707 +                       int reloc_type = ELF32_R_TYPE(rpnt->r_info);
2708 +
2709 +#if defined (__SUPPORT_LD_DEBUG__)
2710 +                       _dl_dprintf(2, "can't handle relocation type '%s'\n", _dl_reltypes(reloc_type));
2711 +#else
2712 +                       _dl_dprintf(2, "can't handle relocation type %x\n", reloc_type);
2713 +#endif
2714 +                       _dl_exit(-res);
2715 +               }
2716 +               else if (res > 0) {
2717 +                       _dl_dprintf(2, "can't resolv symbol\n");
2718 +                       return res;
2719 +               }
2720 +       }
2721 +
2722 +       return 0;
2723 +}
2724 +
2725 +static int
2726 +_dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, ELF_RELOC *rpnt,
2727 +       Elf32_Sym *symtab, char *strtab)
2728 +{
2729 +       int reloc_type;
2730 +       int symtab_index;
2731 +       char *symname;
2732 +       unsigned long *reloc_addr;
2733 +       unsigned symbol_addr;
2734 +#if defined (__SUPPORT_LD_DEBUG__)
2735 +       unsigned long old_val;
2736 +#endif
2737 +
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);
2741 +       symbol_addr = 0;
2742 +       symname = strtab + symtab[symtab_index].st_name;
2743 +
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;
2748 +               }
2749 +               else {
2750 +                       symbol_addr = (unsigned long) _dl_find_hash(symname, scope,
2751 +                               (reloc_type == R_CRIS_JUMP_SLOT ? tpnt : NULL), symbolrel);
2752 +               }
2753 +
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);
2758 +#endif
2759 +                       return 0;
2760 +               }
2761 +
2762 +               symbol_addr += rpnt->r_addend;
2763 +       }
2764 +
2765 +#if defined (__SUPPORT_LD_DEBUG__)
2766 +       old_val = *reloc_addr;
2767 +#endif
2768 +
2769 +       switch (reloc_type) {
2770 +               case R_CRIS_NONE:
2771 +                       break;
2772 +               case R_CRIS_GLOB_DAT:
2773 +               case R_CRIS_JUMP_SLOT:
2774 +               case R_CRIS_32:
2775 +               case R_CRIS_COPY:
2776 +                       *reloc_addr = symbol_addr;
2777 +                       break;
2778 +               case R_CRIS_RELATIVE:
2779 +                       *reloc_addr = (unsigned long) tpnt->loadaddr + rpnt->r_addend;
2780 +                       break;
2781 +               default:
2782 +                       return -1;      /* Call _dl_exit(1). */
2783 +       }
2784 +
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);
2788 +#endif
2789 +
2790 +       return 0;
2791 +}
2792 +
2793 +static int
2794 +_dl_do_lazy_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, ELF_RELOC *rpnt,
2795 +       Elf32_Sym *symtab, char *strtab)
2796 +{
2797 +       int reloc_type;
2798 +       unsigned long *reloc_addr;
2799 +#if defined (__SUPPORT_LD_DEBUG__)
2800 +       unsigned long old_val;
2801 +#endif
2802 +
2803 +       /* Don't care about these, just keep the compiler happy. */
2804 +       (void) scope;
2805 +       (void) symtab;
2806 +       (void) strtab;
2807 +
2808 +       reloc_addr = (unsigned long *)(intptr_t)(tpnt->loadaddr + (unsigned long) rpnt->r_offset);
2809 +       reloc_type = ELF32_R_TYPE(rpnt->r_info);
2810 +
2811 +#if defined (__SUPPORT_LD_DEBUG__)
2812 +       old_val = *reloc_addr;
2813 +#endif
2814 +
2815 +       switch (reloc_type) {
2816 +               case R_CRIS_NONE:
2817 +                       break;
2818 +               case R_CRIS_JUMP_SLOT:
2819 +                       *reloc_addr += (unsigned long) tpnt->loadaddr;
2820 +                       break;
2821 +               default:
2822 +                       return -1;      /* Calls _dl_exit(1). */
2823 +       }
2824 +
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);
2828 +#endif
2829 +
2830 +       return 0;
2831 +}
2832 +
2833 +static int
2834 +_dl_do_copy_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, ELF_RELOC *rpnt,
2835 +       Elf32_Sym *symtab, char *strtab)
2836 +{
2837 +       int goof;
2838 +       int reloc_type;
2839 +       int symtab_index;
2840 +       char *symname;
2841 +       unsigned long *reloc_addr;
2842 +       unsigned long symbol_addr;
2843 +
2844 +       reloc_addr = (unsigned long *)(intptr_t) (tpnt->loadaddr + (unsigned long) rpnt->r_offset);
2845 +       reloc_type = ELF32_R_TYPE(rpnt->r_info);
2846 +
2847 +       if (reloc_type != R_CRIS_COPY)
2848 +               return 0;
2849 +       
2850 +       symtab_index = ELF32_R_SYM(rpnt->r_info);
2851 +       symbol_addr = 0;
2852 +       symname = strtab + symtab[symtab_index].st_name;
2853 +       goof = 0;
2854 +
2855 +       if (symtab_index) {
2856 +               symbol_addr = (unsigned long) _dl_find_hash(symname, scope, NULL, copyrel);
2857 +
2858 +               if (!symbol_addr)
2859 +                       goof++;
2860 +       }
2861 +
2862 +       if (!goof) {
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);
2867 +#endif
2868 +                       _dl_memcpy((char *) symtab[symtab_index].st_value,
2869 +                               (char *) symbol_addr, symtab[symtab_index].st_size);
2870 +       }
2871 +
2872 +       return goof;
2873 +}
2874 +
2875 +/* External interface to the generic part of the dynamic linker. */
2876 +
2877 +int
2878 +_dl_parse_relocation_information(struct elf_resolve *tpnt, unsigned long rel_addr,
2879 +       unsigned long rel_size, int type)
2880 +{
2881 +       /* Keep the compiler happy. */
2882 +       (void) type;
2883 +       return _dl_parse(tpnt, tpnt->symbol_scope, rel_addr, rel_size, _dl_do_reloc);
2884 +}
2885 +void
2886 +_dl_parse_lazy_relocation_information(struct elf_resolve *tpnt, unsigned long rel_addr,
2887 +       unsigned long rel_size, int type)
2888 +{
2889 +       /* Keep the compiler happy. */
2890 +       (void) type;
2891 +       _dl_parse(tpnt, NULL, rel_addr, rel_size, _dl_do_lazy_reloc);
2892 +}
2893 +
2894 +int
2895 +_dl_parse_copy_information(struct dyn_elf *xpnt, unsigned long rel_addr,
2896 +       unsigned long rel_size, int type)
2897 +{
2898 +       /* Keep the compiler happy. */
2899 +       (void) type;
2900 +       return _dl_parse(xpnt->dyn, xpnt->next, rel_addr, rel_size, _dl_do_copy_reloc);
2901 +}
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
2905 @@ -0,0 +1,7 @@
2906 +/* 
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. 
2910 + */
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
2916 @@ -0,0 +1,112 @@
2917 +/* CRIS can never use Elf32_Rel relocations. */
2918 +#define ELF_USES_RELOCA
2919 +
2920 +/*
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.
2924 + */
2925 +#define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned long *) ARGS)
2926 +
2927 +/*
2928 + * Initialization sequence for a GOT.
2929 + */
2930 +#define INIT_GOT(GOT_BASE,MODULE)                              \
2931 +{                                                              \
2932 +       GOT_BASE[1] = (unsigned long) MODULE;                   \
2933 +       GOT_BASE[2] = (unsigned long) _dl_linux_resolve;        \
2934 +}
2935 +
2936 +/*
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
2941 + * load address.
2942 + */
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:                                  \
2947 +               case R_CRIS_32:                                         \
2948 +                       *REL = SYMBOL;                                  \
2949 +                       break;                                          \
2950 +               case R_CRIS_16_PCREL:                                   \
2951 +                       *(short *) *REL = SYMBOL + (RELP)->r_addend - *REL - 2; \
2952 +                       break;                                          \
2953 +               case R_CRIS_32_PCREL:                                   \
2954 +                       *REL = SYMBOL + (RELP)->r_addend - *REL - 4;    \
2955 +                       break;                                          \
2956 +               case R_CRIS_NONE:                                       \
2957 +                       break;                                          \
2958 +               case R_CRIS_RELATIVE:                                   \
2959 +                       *REL = (unsigned long) LOAD + (RELP)->r_addend; \
2960 +                       break;                                          \
2961 +               default:                                                \
2962 +                       _dl_exit(1);                                    \
2963 +                       break;                                          \
2964 +       }
2965 +
2966 +/*
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
2969 + * _dl_elf_main.
2970 + */
2971 +#define START() __asm__ volatile ("moveq 0,$r8\n\t" \
2972 +                                 "move $r8,$srp\n\t" \
2973 +                                 "move.d %1,$sp\n\t" \
2974 +                                 "jump %0\n\t" \
2975 +                                 : : "r" (_dl_elf_main), "r" (args))
2976 +
2977 +/* Defined some magic numbers that this ld.so should accept. */
2978 +#define MAGIC1 EM_CRIS
2979 +#undef MAGIC2
2980 +#define ELF_TARGET "CRIS"
2981 +
2982 +struct elf_resolve;
2983 +extern unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry);
2984 +
2985 +/* Cheap modulo implementation, taken from arm/ld_sysdep.h. */
2986 +static inline unsigned long
2987 +cris_mod(unsigned long m, unsigned long p)
2988 +{
2989 +       unsigned long i, t, inc;
2990 +
2991 +       i = p;
2992 +       t = 0;
2993 +
2994 +       while (!(i & (1 << 31))) {
2995 +               i <<= 1;
2996 +               t++;
2997 +       }
2998 +
2999 +       t--;
3000 +
3001 +       for (inc = t; inc > 2; inc--) {
3002 +               i = p << inc;
3003 +
3004 +               if (i & (1 << 31))
3005 +                       break;
3006 +
3007 +               while (m >= i) {
3008 +                       m -= i;
3009 +                       i <<= 1;
3010 +                       if (i & (1 << 31))
3011 +                               break;
3012 +                       if (i < p)
3013 +                               break;
3014 +               }
3015 +       }
3016 +
3017 +       while (m >= p)
3018 +               m -= p;
3019 +
3020 +       return m;
3021 +}
3022 +
3023 +#define do_rem(result, n, base) result = cris_mod(n, base);
3024 +
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
3032 @@ -0,0 +1,48 @@
3033 +/*
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.
3039 + *
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 
3047 + * first place.
3048 + */              
3049 +
3050 +.globl _dl_linux_resolve
3051 +.type _dl_linux_resolve,@function
3052 +
3053 +_dl_linux_resolve:
3054 +       push $r13
3055 +       push $r12
3056 +       push $r11
3057 +       push $r10
3058 +       push $r9
3059 +       push $srp
3060 +       move.d [$sp+6*4],$r11
3061 +       move $mof,$r10
3062 +#ifdef __PIC__
3063 +       move.d $pc,$r0
3064 +       sub.d .:GOTOFF,$r0
3065 +       move.d _dl_linux_resolver:PLTG,$r9
3066 +       add.d $r0,$r9
3067 +       jsr $r9
3068 +#else
3069 +       jsr _dl_linux_resolver
3070 +#endif
3071 +       move.d $r10,[$sp+6*4]
3072 +       pop $srp
3073 +       pop $r9
3074 +       pop $r10
3075 +       pop $r11
3076 +       pop $r12
3077 +       pop $r13
3078 +       jump [$sp+]
3079 +
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
3084 @@ -0,0 +1,327 @@
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
3088 + *
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
3092 + *
3093 + * All rights reserved.
3094 + *
3095 + * Redistribution and use in source and binary forms, with or without
3096 + * modification, are permitted provided that the following conditions
3097 + * are met:
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.
3103 + *
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
3114 + * SUCH DAMAGE.
3115 + */
3116 +
3117 +
3118 +/* Various symbol table handling functions, including symbol lookup */
3119 +
3120 +/*
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.
3124 + */
3125 +
3126 +struct elf_resolve *_dl_loaded_modules = NULL;
3127 +
3128 +/*
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
3131 + * chains.
3132 + */
3133 +struct dyn_elf *_dl_symbol_tables = NULL;
3134 +
3135 +/*
3136 + * This is the list of modules that are loaded via dlopen.  We may need
3137 + * to search these for RTLD_GLOBAL files.
3138 + */
3139 +struct dyn_elf *_dl_handles = NULL;
3140 +
3141 +
3142 +/*
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.
3146 + */
3147 +
3148 +unsigned long _dl_elf_hash(const char *name)
3149 +{
3150 +       unsigned long hash = 0;
3151 +       unsigned long tmp;
3152 +
3153 +       while (*name) {
3154 +               hash = (hash << 4) + *name++;
3155 +               if ((tmp = hash & 0xf0000000))
3156 +                       hash ^= tmp >> 24;
3157 +               hash &= ~tmp;
3158 +       };
3159 +       return hash;
3160 +}
3161 +
3162 +/*
3163 + * Check to see if a library has already been added to the hash chain.
3164 + */
3165 +struct elf_resolve *_dl_check_hashed_files(const char *libname)
3166 +{
3167 +       struct elf_resolve *tpnt;
3168 +       int len = _dl_strlen(libname);
3169 +
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] == '.'))
3173 +                       return tpnt;
3174 +       }
3175 +
3176 +       return NULL;
3177 +}
3178 +
3179 +/*
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.
3183 + */
3184 +
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)
3188 +{
3189 +       unsigned long *hash_addr;
3190 +       struct elf_resolve *tpnt;
3191 +       int i;
3192 +
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));
3197 +       } else {
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;
3205 +       };
3206 +
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;
3213 +
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;
3221 +       }
3222 +       tpnt->loadaddr = (ElfW(Addr))loadaddr;
3223 +       for (i = 0; i < 24; i++)
3224 +               tpnt->dynamic_info[i] = dynamic_info[i];
3225 +#ifdef __mips__
3226 +       {
3227 +               Elf32_Dyn *dpnt = (Elf32_Dyn *) dynamic_addr;
3228 +
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;
3236 +                       dpnt++;
3237 +               }
3238 +       }
3239 +#endif
3240 +       return tpnt;
3241 +}
3242 +
3243 +
3244 +/*
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.
3247 + */
3248 +
3249 +char *_dl_find_hash(const char *name, struct dyn_elf *rpnt1, 
3250 +       struct elf_resolve *f_tpnt, enum caller_type caller_type)
3251 +{
3252 +       struct elf_resolve *tpnt;
3253 +       int si;
3254 +       char *pnt;
3255 +       int pass;
3256 +       char *strtab;
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 */
3263 +
3264 +       weak_result = 0;
3265 +       elf_hash_number = _dl_elf_hash(name);
3266 +
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;
3275 +               rpnt1 = (&first);
3276 +       }
3277 +
3278 +       /*
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.
3284 +        */
3285 +       for (pass = 0; (1 == 1); pass++) {
3286 +
3287 +               /*
3288 +                * If we are just starting to search for RTLD_GLOBAL, setup
3289 +                * the pointer for the start of the search.
3290 +                */
3291 +               if (pass == 1) {
3292 +                       rpnt1 = _dl_handles;
3293 +               }
3294 +
3295 +               /*
3296 +                * Anything after this, we need to skip to the next module.
3297 +                */
3298 +               else if (pass >= 2) {
3299 +                       rpnt1 = rpnt1->next_handle;
3300 +               }
3301 +
3302 +               /*
3303 +                * Make sure we still have a module, and make sure that this
3304 +                * module was loaded with RTLD_GLOBAL.
3305 +                */
3306 +               if (pass != 0) {
3307 +                       if (rpnt1 == NULL)
3308 +                               break;
3309 +                       if ((rpnt1->flags & RTLD_GLOBAL) == 0)
3310 +                               continue;
3311 +               }
3312 +
3313 +               for (rpnt = (rpnt1 ? rpnt1 : _dl_symbol_tables); rpnt; rpnt = rpnt->next) {
3314 +                       tpnt = rpnt->dyn;
3315 +
3316 +                       /*
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.  
3323 +                        */
3324 +                       if (tpnt->libtype == elf_executable && weak_result != 0) {
3325 +                               break;
3326 +                       }
3327 +
3328 +                       /*
3329 +                        * Avoid calling .urem here.
3330 +                        */
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);
3334 +                       /*
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, 
3339 +                        */
3340 +
3341 +                       first_def = NULL;
3342 +
3343 +                       for (si = tpnt->elf_buckets[hn]; si; si = tpnt->chains[si]) {
3344 +                               pnt = strtab + symtab[si].st_name;
3345 +
3346 +                               if (_dl_strcmp(pnt, name) == 0 &&
3347 +                                   symtab[si].st_value != 0)
3348 +                               {
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) {
3353 +
3354 +                                       /* Here we make sure that we find a module where the symbol is
3355 +                                        * actually defined.
3356 +                                        */
3357 +
3358 +                                       if (f_tpnt) {
3359 +                                               if (!first_def)
3360 +                                                       first_def = tpnt;
3361 +                                               if (first_def == f_tpnt
3362 +                                                       && symtab[si].st_shndx == 0)
3363 +                                                       continue;
3364 +                                       }
3365 +
3366 +                                       switch (ELF32_ST_BIND(symtab[si].st_info)) {
3367 +                                       case STB_GLOBAL:
3368 +                                               if (tpnt->libtype != elf_executable && 
3369 +                                                       ELF32_ST_TYPE(symtab[si].st_info) 
3370 +                                                       == STT_NOTYPE) 
3371 +                                               {       /* nakao */
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;
3377 +                                       case STB_WEAK:
3378 +                                               if (!weak_result)
3379 +                                                       weak_result = (char *)tpnt->loadaddr + symtab[si].st_value;
3380 +                                               break;
3381 +                                       default:        /* Do local symbols need to be examined? */
3382 +                                               break;
3383 +                                       }
3384 +                                 }
3385 +#ifndef __mips__
3386 +                                 /*
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
3393 +                                  * Adresses) 
3394 +                                  */                            
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)
3400 +                                 {
3401 +                                     return (char*)symtab[si].st_value;
3402 +                                 }
3403 +#endif
3404 +                               }
3405 +                       }
3406 +               }
3407 +       }
3408 +       if (data_result)
3409 +               return data_result;             /* nakao */
3410 +       return weak_result;
3411 +}
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
3415 @@ -0,0 +1,7 @@
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
3419 + * can be done.
3420 + */
3421 +
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
3426 @@ -0,0 +1,415 @@
3427 +/* vi: set sw=4 ts=4: */
3428 +/* i386 ELF shared library loader suppport
3429 + *
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
3433 + *
3434 + * All rights reserved.
3435 + *
3436 + * Redistribution and use in source and binary forms, with or without
3437 + * modification, are permitted provided that the following conditions
3438 + * are met:
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.
3444 + *
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
3455 + * SUCH DAMAGE.
3456 + */
3457 +
3458 +#if defined (__SUPPORT_LD_DEBUG__)
3459 +static const char *_dl_reltypes_tab[] =
3460 +{
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",
3464 +};
3465 +
3466 +static const char *
3467 +_dl_reltypes(int type)
3468 +{
3469 +  static char buf[22];  
3470 +  const char *str;
3471 +  
3472 +  if (type >= (int)(sizeof (_dl_reltypes_tab)/sizeof(_dl_reltypes_tab[0])) ||
3473 +      NULL == (str = _dl_reltypes_tab[type]))
3474 +  {
3475 +    str =_dl_simple_ltoa( buf, (unsigned long)(type));
3476 +  }
3477 +  return str;
3478 +}
3479 +
3480 +static 
3481 +void debug_sym(Elf32_Sym *symtab,char *strtab,int symtab_index)
3482 +{
3483 +  if(_dl_debug_symbols)
3484 +  {
3485 +    if(symtab_index){
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);
3493 +    }
3494 +  }
3495 +}
3496 +
3497 +static void debug_reloc(Elf32_Sym *symtab,char *strtab, ELF_RELOC *rpnt)
3498 +{
3499 +  if(_dl_debug_reloc)
3500 +  {
3501 +    int symtab_index;
3502 +    const char *sym;
3503 +    symtab_index = ELF32_R_SYM(rpnt->r_info);
3504 +    sym = symtab_index ? strtab + symtab[symtab_index].st_name : "sym=0x0";
3505 +    
3506 +  if(_dl_debug_symbols)
3507 +         _dl_dprintf(_dl_debug_file, "\n\t");
3508 +  else
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)),
3513 +               rpnt->r_offset,
3514 +               rpnt->r_addend);
3515 +#else
3516 +    _dl_dprintf(_dl_debug_file, "%s\toffset=%x\n",
3517 +               _dl_reltypes(ELF32_R_TYPE(rpnt->r_info)),
3518 +               rpnt->r_offset);
3519 +#endif
3520 +  }
3521 +}
3522 +#endif
3523 +
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. */
3527 +
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
3533 +   working. */
3534 +
3535 +extern int _dl_linux_resolve(void);
3536 +
3537 +unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
3538 +{
3539 +       int reloc_type;
3540 +       ELF_RELOC *this_reloc;
3541 +       char *strtab;
3542 +       Elf32_Sym *symtab;
3543 +       int symtab_index;
3544 +       char *rel_addr;
3545 +       char *new_addr;
3546 +       char **got_addr;
3547 +       unsigned long instr_addr;
3548 +       char *symname;
3549 +
3550 +       rel_addr = (char *) (tpnt->dynamic_info[DT_JMPREL] + tpnt->loadaddr);
3551 +
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);
3555 +
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;
3559 +
3560 +       if (reloc_type != R_386_JMP_SLOT) {
3561 +               _dl_dprintf(2, "%s: Incorrect relocation type in jump relocations\n", 
3562 +                               _dl_progname);
3563 +               _dl_exit(1);
3564 +       }
3565 +
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;
3570 +
3571 +       /* Get the address of the GOT entry */
3572 +       new_addr = _dl_find_hash(symname, tpnt->symbol_scope, tpnt, resolver);
3573 +       if (!new_addr) {
3574 +               new_addr = _dl_find_hash(symname, NULL, NULL, resolver);
3575 +               if (new_addr) {
3576 +                       return (unsigned long) new_addr;
3577 +               }
3578 +               _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname);
3579 +               _dl_exit(1);
3580 +       }
3581 +
3582 +#if defined (__SUPPORT_LD_DEBUG__)
3583 +       if ((unsigned long) got_addr < 0x40000000)
3584 +       {
3585 +               if (_dl_debug_bindings)
3586 +               {
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);
3590 +               }
3591 +       }
3592 +       if (!_dl_debug_nofixups) {
3593 +               *got_addr = new_addr;
3594 +       }
3595 +#else
3596 +       *got_addr = new_addr;
3597 +#endif
3598 +
3599 +       return (unsigned long) new_addr;
3600 +}
3601 +
3602 +static int
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))
3607 +{
3608 +       unsigned int i;
3609 +       char *strtab;
3610 +       Elf32_Sym *symtab;
3611 +       ELF_RELOC *rpnt;
3612 +       int symtab_index;
3613 +
3614 +       /* Now parse the relocation information */
3615 +       rpnt = (ELF_RELOC *)(intptr_t) (rel_addr + tpnt->loadaddr);
3616 +       rel_size = rel_size / sizeof(ELF_RELOC);
3617 +
3618 +       symtab = (Elf32_Sym *)(intptr_t) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
3619 +       strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
3620 +
3621 +         for (i = 0; i < rel_size; i++, rpnt++) {
3622 +               int res;
3623 +           
3624 +               symtab_index = ELF32_R_SYM(rpnt->r_info);
3625 +               
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)
3629 +                       continue;
3630 +               if (symtab_index && tpnt->libtype == program_interpreter &&
3631 +                   _dl_symbol(strtab + symtab[symtab_index].st_name))
3632 +                       continue;
3633 +
3634 +#if defined (__SUPPORT_LD_DEBUG__)
3635 +               debug_sym(symtab,strtab,symtab_index);
3636 +               debug_reloc(symtab,strtab,rpnt);
3637 +#endif
3638 +
3639 +               res = reloc_fnc (tpnt, scope, rpnt, symtab, strtab);
3640 +
3641 +               if (res==0) continue;
3642 +
3643 +               _dl_dprintf(2, "\n%s: ",_dl_progname);
3644 +               
3645 +               if (symtab_index)
3646 +                 _dl_dprintf(2, "symbol '%s': ", strtab + symtab[symtab_index].st_name);
3647 +                 
3648 +               if (res <0)
3649 +               {
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));
3653 +#else
3654 +                       _dl_dprintf(2, "can't handle reloc type %x\n", reloc_type);
3655 +#endif                 
3656 +                       _dl_exit(-res);
3657 +               }
3658 +               else if (res >0)
3659 +               {
3660 +                       _dl_dprintf(2, "can't resolve symbol\n");
3661 +                       return res;
3662 +               }
3663 +         }
3664 +         return 0;
3665 +}
3666 +
3667 +
3668 +static int
3669 +_dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope,
3670 +             ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)
3671 +{
3672 +       int reloc_type;
3673 +       int symtab_index;
3674 +       char *symname;
3675 +       unsigned long *reloc_addr;
3676 +       unsigned long symbol_addr;
3677 +#if defined (__SUPPORT_LD_DEBUG__)
3678 +       unsigned long old_val;
3679 +#endif
3680 +
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);
3684 +       symbol_addr  = 0;
3685 +       symname      = strtab + symtab[symtab_index].st_name;
3686 +
3687 +       if (symtab_index) {
3688 +
3689 +               symbol_addr = (unsigned long) _dl_find_hash(symname, scope, 
3690 +                               (reloc_type == R_386_JMP_SLOT ? tpnt : NULL), symbolrel);
3691 +
3692 +               /*
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.
3696 +                */
3697 +
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);
3702 +#endif
3703 +                       return 0;
3704 +               }
3705 +       }
3706 +
3707 +#if defined (__SUPPORT_LD_DEBUG__)
3708 +       old_val = *reloc_addr;
3709 +#endif
3710 +               switch (reloc_type) {
3711 +                       case R_386_NONE:
3712 +                               break;
3713 +                       case R_386_32:
3714 +                               *reloc_addr += symbol_addr;
3715 +                               break;
3716 +                       case R_386_PC32:
3717 +                               *reloc_addr += symbol_addr - (unsigned long) reloc_addr;
3718 +                               break;
3719 +                       case R_386_GLOB_DAT:
3720 +                       case R_386_JMP_SLOT:
3721 +                               *reloc_addr = symbol_addr;
3722 +                               break;
3723 +                       case R_386_RELATIVE:
3724 +                               *reloc_addr += (unsigned long) tpnt->loadaddr;
3725 +                               break;
3726 +                       case R_386_COPY:
3727 +                               /* handled later on */
3728 +                               break;
3729 +                       default:
3730 +                               return -1; /*call _dl_exit(1) */
3731 +               }
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);
3735 +#endif
3736 +
3737 +       return 0;
3738 +}
3739 +
3740 +static int
3741 +_dl_do_lazy_reloc (struct elf_resolve *tpnt, struct dyn_elf *scope,
3742 +                  ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)
3743 +{
3744 +       int reloc_type;
3745 +       unsigned long *reloc_addr;
3746 +#if defined (__SUPPORT_LD_DEBUG__)
3747 +       unsigned long old_val;
3748 +#endif
3749 +       (void)scope;
3750 +       (void)symtab;
3751 +       (void)strtab;
3752 +
3753 +       reloc_addr = (unsigned long *)(intptr_t) (tpnt->loadaddr + (unsigned long) rpnt->r_offset);
3754 +       reloc_type = ELF32_R_TYPE(rpnt->r_info);
3755 +
3756 +#if defined (__SUPPORT_LD_DEBUG__)
3757 +       old_val = *reloc_addr;
3758 +#endif
3759 +               switch (reloc_type) {
3760 +                       case R_386_NONE:
3761 +                               break;
3762 +                       case R_386_JMP_SLOT:
3763 +                               *reloc_addr += (unsigned long) tpnt->loadaddr;
3764 +                               break;
3765 +                       default:
3766 +                               return -1; /*call _dl_exit(1) */
3767 +               }
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);
3771 +#endif
3772 +       return 0;
3773 +
3774 +}
3775 +
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. */
3781 +
3782 +/* No, there are cases where the SVr4 linker fails to emit COPY relocs
3783 +   at all */
3784 +static int
3785 +_dl_do_copy (struct elf_resolve *tpnt, struct dyn_elf *scope,
3786 +            ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)
3787 +{
3788 +       int reloc_type;
3789 +       int symtab_index;
3790 +       unsigned long *reloc_addr;
3791 +       unsigned long symbol_addr;
3792 +       int goof = 0;
3793 +       char *symname;
3794 +         
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) 
3798 +               return 0;
3799 +       symtab_index = ELF32_R_SYM(rpnt->r_info);
3800 +       symbol_addr = 0;
3801 +       symname      = strtab + symtab[symtab_index].st_name;
3802 +               
3803 +       if (symtab_index) {
3804 +               symbol_addr = (unsigned long) _dl_find_hash(symname, scope, NULL, copyrel);
3805 +               if (!symbol_addr) goof++;
3806 +       }
3807 +       if (!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);
3813 +#endif
3814 +               _dl_memcpy((char *) symtab[symtab_index].st_value, 
3815 +                       (char *) symbol_addr, symtab[symtab_index].st_size);
3816 +       }
3817 +
3818 +       return goof;
3819 +}
3820 +
3821 +void _dl_parse_lazy_relocation_information(struct elf_resolve *tpnt, 
3822 +       unsigned long rel_addr, unsigned long rel_size, int type)
3823 +{
3824 +       (void) type;
3825 +       (void)_dl_parse(tpnt, NULL, rel_addr, rel_size, _dl_do_lazy_reloc);
3826 +}
3827 +
3828 +int _dl_parse_relocation_information(struct elf_resolve *tpnt, 
3829 +       unsigned long rel_addr, unsigned long rel_size, int type)
3830 +{
3831 +       (void) type;
3832 +       return _dl_parse(tpnt, tpnt->symbol_scope, rel_addr, rel_size, _dl_do_reloc);
3833 +}
3834 +
3835 +int _dl_parse_copy_information(struct dyn_elf *xpnt, unsigned long rel_addr, 
3836 +       unsigned long rel_size, int type)
3837 +{
3838 +       (void) type;
3839 +       return _dl_parse(xpnt->dyn, xpnt->next, rel_addr, rel_size, _dl_do_copy);
3840 +}
3841 +
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
3845 @@ -0,0 +1,7 @@
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. */
3849 +
3850 +#define __set_errno(X) {(void)(X);}
3851 +#include "sys/syscall.h"
3852 +
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
3856 @@ -0,0 +1,81 @@
3857 +/*
3858 + * Various assmbly language/system dependent  hacks that are required
3859 + * so that we can minimize the amount of platform specific code.
3860 + */
3861 +
3862 +/*
3863 + * Define this if the system uses RELOCA.
3864 + */
3865 +#undef ELF_USES_RELOCA
3866 +
3867 +/*
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.
3871 + */
3872 +#define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned long*) & ARGS)
3873 +
3874 +/*
3875 + * Initialization sequence for a GOT.
3876 + */
3877 +#define INIT_GOT(GOT_BASE,MODULE) \
3878 +{                              \
3879 +  GOT_BASE[2] = (unsigned long) _dl_linux_resolve; \
3880 +  GOT_BASE[1] = (unsigned long) MODULE; \
3881 +}
3882 +
3883 +/*
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
3888 + * load address.
3889 + */
3890 +#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD) \
3891 +       switch(ELF32_R_TYPE((RELP)->r_info)){           \
3892 +       case R_386_32:          \
3893 +         *REL += SYMBOL;               \
3894 +         break;                \
3895 +       case R_386_PC32:                \
3896 +         *REL += SYMBOL - (unsigned long) REL;         \
3897 +         break;                \
3898 +       case R_386_GLOB_DAT:            \
3899 +       case R_386_JMP_SLOT:            \
3900 +         *REL = SYMBOL;                \
3901 +         break;                \
3902 +       case R_386_RELATIVE:            \
3903 +         *REL += (unsigned long) LOAD;         \
3904 +         break;                \
3905 +       default:                \
3906 +         _dl_exit(1);          \
3907 +       }
3908 +
3909 +
3910 +/*
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.
3914 + */
3915 +#define START()                \
3916 +       __asm__ volatile ("leave\n\t" \
3917 +                   "jmp *%%eax\n\t"    \
3918 +                   : "=a" (status) :   "a" (_dl_elf_main))
3919 +
3920 +
3921 +
3922 +/* Here we define the magic numbers that this dynamic loader should accept */
3923 +
3924 +#define MAGIC1 EM_386
3925 +#undef  MAGIC2
3926 +/* Used for error messages */
3927 +#define ELF_TARGET "386"
3928 +
3929 +struct elf_resolve;
3930 +extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
3931 +
3932 +#define do_rem(result, n, base)  result = (n % base)
3933 +
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
3941 @@ -0,0 +1,52 @@
3942 +/*
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:
3948 + *     reloc_entry
3949 + *     tpnt
3950 + *
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.  
3961 + *  -Erik Andersen
3962 + */
3963 +
3964 +.text
3965 +.align 4
3966 +
3967 +.globl _dl_linux_resolve
3968 +.type  _dl_linux_resolve,@function
3969 +
3970 +_dl_linux_resolve:
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 */
3975 +                                        
3976 +#ifdef __PIC__
3977 +       call    .L24
3978 +.L24:
3979 +       popl    %ebx
3980 +       addl    $_GLOBAL_OFFSET_TABLE_+[.-.L24],%ebx
3981 +       movl _dl_linux_resolver@GOT(%ebx),%ebx  /* eax = resolved func */
3982 +       call *%ebx
3983 +#else
3984 +       call _dl_linux_resolver
3985 +#endif
3986 +       movl    %eax,0x28(%esp)         /* store func addr over original
3987 +                                        * tpnt param */
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 */
3992 +.LFE2:
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
3997 @@ -0,0 +1,1296 @@
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
4001 + *
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
4005 + *
4006 + * All rights reserved.
4007 + *
4008 + * Redistribution and use in source and binary forms, with or without
4009 + * modification, are permitted provided that the following conditions
4010 + * are met:
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.
4016 + *
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
4027 + * SUCH DAMAGE.
4028 + */
4029 +
4030 +// Support a list of library preloads in /etc/ld.so.preload
4031 +//#define SUPPORT_LDSO_PRELOAD_FILE
4032 +
4033 +
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
4039 +   working. */
4040 +
4041 +/*
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.
4048 + *
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.
4057 + *
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.
4064 + *
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....
4074 + *
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. 
4078 + *
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.
4086 + *
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.
4093 + *
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
4102 + * application.
4103 + */
4104 +
4105 +#include "ldso.h"
4106 +
4107 +
4108 +#define ALLOW_ZERO_PLTGOT
4109 +
4110 +/*  Some arches may need to override this in boot1_arch.h */
4111 +#define            ELFMAGIC    ELFMAG
4112 +
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();
4115 +/*
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.
4119 + */
4120 +#define REALIGN() malloc_buffer = (char *) (((unsigned long) malloc_buffer + 3) & ~(3))
4121 +
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;
4135 +#else
4136 +#define _dl_debug_file 2
4137 +#endif
4138 +static char *_dl_malloc_addr, *_dl_mmap_zero;
4139 +
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);
4151 +
4152 +#include "boot1_arch.h"
4153 +#include "_dl_progname.h"                              /* Pull in the value of _dl_progname */
4154 +
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)
4160 +               NULL
4161 +        env[0...N]      environment variables (pointers)
4162 +        NULL
4163 +               auxvt[0...N]   Auxiliary Vector Table elements (mixed types)
4164 +*/
4165 +
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)
4171 +{
4172 +       int i;
4173 +       char c;
4174 +
4175 +       for (i = 0; i < 8; i++) {
4176 +               c = ((x >> 28) + '0');
4177 +               if (c > '9')
4178 +                       c += 'a' - '9' - 1;
4179 +               _dl_write(1, &c, 1);
4180 +               x <<= 4;
4181 +       }
4182 +       c = '\n';
4183 +       _dl_write(1, &c, 1);
4184 +}
4185 +#endif
4186 +
4187 +LD_BOOT(unsigned long args) __attribute__ ((unused));
4188 +
4189 +LD_BOOT(unsigned long args)
4190 +{
4191 +       unsigned int argc;
4192 +       char **argv, **envp;
4193 +       unsigned long load_addr;
4194 +       unsigned long *got;
4195 +       unsigned long *aux_dat;
4196 +       int goof = 0;
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;
4202 +       Elf32_Dyn *dpnt;
4203 +       unsigned long *hash_addr;
4204 +       struct r_debug *debug_addr = NULL;
4205 +       int indx;
4206 +       int status;
4207 +
4208 +
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
4212 +        * anyways. */
4213 +
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__)
4218 +       aux_dat += 1;
4219 +#endif
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;
4225 +       while (*aux_dat)
4226 +               aux_dat++;                              /* Skip over the envp pointers */
4227 +       aux_dat++;                                      /* Skip over NULL at end of envp */
4228 +
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;
4232 +
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;
4238 +
4239 +               if (auxv_entry->a_type <= AT_EGID) {
4240 +                       _dl_memcpy(&(auxvt[auxv_entry->a_type]), auxv_entry, sizeof(Elf32_auxv_t));
4241 +               }
4242 +               aux_dat += 2;
4243 +       }
4244 +
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;
4249 +
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
4255 +#else
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
4260 +#endif
4261 +               ) {
4262 +               SEND_STDERR("Invalid ELF header\n");
4263 +               _dl_exit(0);
4264 +       }
4265 +#ifdef __SUPPORT_LD_DEBUG_EARLY__
4266 +       SEND_STDERR("ELF header=");
4267 +       SEND_ADDRESS_STDERR(load_addr, 1);
4268 +#endif
4269 +
4270 +
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__)
4288 +  __asm__(
4289 +"       mov.l    1f, %0\n"
4290 +"       mova     1f, r0\n"
4291 +"       bra      2f\n"
4292 +"       add r0,  %0\n"
4293 +"       .balign  4\n"
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));
4298 +#else
4299 +       /* Do things the slow way in C */
4300 +       {
4301 +               unsigned long tx_reloc;
4302 +               Elf32_Dyn *dynamic = NULL;
4303 +               Elf32_Shdr *shdr;
4304 +               Elf32_Phdr *pt_load;
4305 +
4306 +#ifdef __SUPPORT_LD_DEBUG_EARLY__
4307 +               SEND_STDERR("Finding the GOT using C code to read the ELF file\n");
4308 +#endif
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;
4314 +                       }
4315 +               }
4316 +               SEND_STDERR("missing dynamic linking information section \n");
4317 +               _dl_exit(0);
4318 +
4319 +         found_dynamic:
4320 +               dynamic = (Elf32_Dyn *) (shdr->sh_offset + (char *) header);
4321 +
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;
4327 +                       }
4328 +               }
4329 +               SEND_STDERR("missing loadable program segment\n");
4330 +               _dl_exit(0);
4331 +
4332 +         found_pt_load:
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) {
4337 +                               goto found_got;
4338 +                       }
4339 +               }
4340 +               SEND_STDERR("missing global offset table\n");
4341 +               _dl_exit(0);
4342 +
4343 +         found_got:
4344 +               got = (unsigned long *) (dynamic->d_un.d_val - tx_reloc +
4345 +                               (char *) header);
4346 +       }
4347 +#endif
4348 +
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);
4354 +#endif
4355 +
4356 +
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");
4363 +               _dl_exit(13);
4364 +       }
4365 +
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));
4370 +
4371 +       /*
4372 +        * This is used by gdb to locate the chain of shared libraries that are currently loaded.
4373 +        */
4374 +       debug_addr = LD_MALLOC(sizeof(struct r_debug));
4375 +       _dl_memset(debug_addr, 0, sizeof(struct r_debug));
4376 +
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");
4381 +#endif
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;
4390 +#endif
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;
4395 +                       }
4396 +               }
4397 +               dpnt++;
4398 +       }
4399 +
4400 +       {
4401 +               ElfW(Phdr) *ppnt;
4402 +               int i;
4403 +
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) {
4420 +                                               dpnt++;
4421 +                                               continue;
4422 +                                       }
4423 +                                       app_tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
4424 +
4425 +#warning "Debugging threads on mips won't work till someone fixes this..."
4426 +#if 0
4427 +                                       if (dpnt->d_tag == DT_DEBUG) {
4428 +                                               dpnt->d_un.d_val = (unsigned long) debug_addr;
4429 +                                       }
4430 +#endif
4431 +
4432 +#else
4433 +                                       if (dpnt->d_tag > DT_JMPREL) {
4434 +                                               dpnt++;
4435 +                                               continue;
4436 +                                       }
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;
4440 +                                       }
4441 +#endif
4442 +                                       if (dpnt->d_tag == DT_TEXTREL)
4443 +                                               app_tpnt->dynamic_info[DT_TEXTREL] = 1;
4444 +                                       dpnt++;
4445 +                               }
4446 +                       }
4447 +       }
4448 +
4449 +#ifdef __SUPPORT_LD_DEBUG_EARLY__
4450 +       SEND_STDERR("done scanning DYNAMIC section\n");
4451 +#endif
4452 +
4453 +       /* Get some more of the information that we will need to dynamicly link
4454 +          this module to itself */
4455 +
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;
4461 +
4462 +#ifdef __SUPPORT_LD_DEBUG_EARLY__
4463 +       SEND_STDERR("done grabbing link information\n");
4464 +#endif
4465 +
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 */
4470 +
4471 +       {
4472 +               ElfW(Phdr) *ppnt;
4473 +               int i;
4474 +
4475 +#ifdef __SUPPORT_LD_DEBUG_EARLY__
4476 +               SEND_STDERR("calling mprotect on the shared library/dynamic linker\n");
4477 +#endif
4478 +
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 + 
4483 +                                       header->e_phoff);
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);
4489 +                               }
4490 +                       }
4491 +               }
4492 +
4493 +#ifdef __SUPPORT_LD_DEBUG_EARLY__
4494 +               SEND_STDERR("calling mprotect on the application program\n");
4495 +#endif
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);
4505 +                       }
4506 +               }
4507 +       }
4508 +#endif
4509 +       
4510 +#if defined(__mips__)
4511 +#ifdef __SUPPORT_LD_DEBUG_EARLY__
4512 +       SEND_STDERR("About to do MIPS specific GOT bootstrap\n");
4513 +#endif
4514 +       /* For MIPS we have to do stuff to the GOT before we do relocations.  */
4515 +       PERFORM_BOOTSTRAP_GOT(got);
4516 +#endif
4517 +
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");
4522 +#endif
4523 +
4524 +       goof = 0;
4525 +       for (indx = 0; indx < 2; indx++) {
4526 +               unsigned int i;
4527 +               ELF_RELOC *rpnt;
4528 +               unsigned long *reloc_addr;
4529 +               unsigned long symbol_addr;
4530 +               int symtab_index;
4531 +               unsigned long rel_addr, rel_size;
4532 +
4533 +
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]);
4539 +#else
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]);
4544 +#endif
4545 +
4546 +               if (!rel_addr)
4547 +                       continue;
4548 +
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);
4554 +                       symbol_addr = 0;
4555 +                       if (symtab_index) {
4556 +                               char *strtab;
4557 +                               Elf32_Sym *symtab;
4558 +
4559 +                               symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + load_addr);
4560 +                               strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + load_addr);
4561 +
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))
4566 +                                       continue;
4567 +                               symbol_addr = load_addr + symtab[symtab_index].st_value;
4568 +
4569 +                               if (!symbol_addr) {
4570 +                                       /* This will segfault - you cannot call a function until
4571 +                                        * we have finished the relocations.
4572 +                                        */
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");
4576 +                                       goof++;
4577 +                               }
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");
4582 +#endif  
4583 +                       }
4584 +                       /*
4585 +                        * Use this machine-specific macro to perform the actual relocation.
4586 +                        */
4587 +                       PERFORM_BOOTSTRAP_RELOC(rpnt, reloc_addr, symbol_addr, load_addr);
4588 +               }
4589 +       }
4590 +
4591 +       if (goof) {
4592 +               _dl_exit(14);
4593 +       }
4594 +#ifdef __SUPPORT_LD_DEBUG_EARLY__
4595 +       /* Wahoo!!! */
4596 +       _dl_dprintf(_dl_debug_file, "Done relocating library loader, so we can now\n\tuse globals and make function calls!\n");
4597 +#endif
4598 +
4599 +       if (argv[0]) {
4600 +               _dl_progname = argv[0];
4601 +       }
4602 +
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. */
4607 +
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;
4612 +
4613 +
4614 +
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);
4620 +
4621 +
4622 +       /* Notify the debugger that all objects are now mapped in.  */
4623 +       _dl_debug_addr->r_state = RT_CONSISTENT;
4624 +       _dl_debug_state();
4625 +
4626 +
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;
4629 +
4630 +       /*
4631 +        * Transfer control to the application.
4632 +        */
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);        
4636 +#endif    
4637 +       START();
4638 +}
4639 +
4640 +#if defined (__SUPPORT_LD_DEBUG__)
4641 +static void debug_fini (int status, void *arg)
4642 +{
4643 +       (void)status;
4644 +       _dl_dprintf(_dl_debug_file,"\ncalling fini: %s\n\n", (const char*)arg);
4645 +}
4646 +#endif    
4647 +
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)
4651 +{
4652 +       ElfW(Phdr) *ppnt;
4653 +       char *lpntstr;
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*);
4662 +#endif
4663 +
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);
4669 +
4670 +       tpnt->chains = hash_addr;
4671 +       tpnt->next = 0;
4672 +       tpnt->libname = 0;
4673 +       tpnt->libtype = program_interpreter;
4674 +       tpnt->loadaddr = (ElfW(Addr)) load_addr;
4675 +
4676 +#ifdef ALLOW_ZERO_PLTGOT
4677 +       if (tpnt->dynamic_info[DT_PLTGOT])
4678 +#endif
4679 +       {
4680 +               INIT_GOT(lpnt, tpnt);
4681 +#ifdef __SUPPORT_LD_DEBUG_EARLY__
4682 +               _dl_dprintf(_dl_debug_file, "GOT found at %x\n", lpnt);
4683 +#endif
4684 +       }
4685 +
4686 +       /* OK, this was a big step, now we need to scan all of the user images
4687 +          and load them properly. */
4688 +
4689 +       {
4690 +               ElfW(Ehdr) *epnt;
4691 +               ElfW(Phdr) *myppnt;
4692 +               int j;
4693 +
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;
4701 +                       }
4702 +               }
4703 +       }
4704 +
4705 +       brk_addr = 0;
4706 +       rpnt = NULL;
4707 +
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 */
4711 +
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;
4717 +               }
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)
4722 +                               continue;
4723 +#endif
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
4737 +                       if (lpnt)
4738 +#endif
4739 +                               INIT_GOT(lpnt, _dl_loaded_modules);
4740 +               }
4741 +
4742 +               /* OK, fill this in - we did not have this before */
4743 +               if (ppnt->p_type == PT_INTERP) {        
4744 +                       int readsize = 0;
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));
4748 +                       
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);
4757 +#endif
4758 +                                       tpnt->libname = _dl_strdup(buf);
4759 +                               }
4760 +                       }
4761 +
4762 +                       /* Store the path where the shared lib loader was found for 
4763 +                        * later use */
4764 +                       pnt = _dl_strdup(tpnt->libname);
4765 +                       pnt1 = _dl_strrchr(pnt, '/');
4766 +                       if (pnt != pnt1) {
4767 +                               *pnt1 = '\0';
4768 +                               _dl_ldsopath = pnt;
4769 +                       } else {
4770 +                               _dl_ldsopath = tpnt->libname;
4771 +                       }
4772 +#ifdef __SUPPORT_LD_DEBUG_EARLY__
4773 +                       _dl_dprintf(_dl_debug_file, "Lib Loader:\t(%x) %s\n", tpnt->loadaddr, tpnt->libname);
4774 +#endif
4775 +               }
4776 +       }
4777 +
4778 +
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 */
4781 +       {
4782 +               if (_dl_getenv("LD_BIND_NOW", envp))
4783 +                       _dl_be_lazy = 0;
4784 +
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)) {
4789 +                       _dl_secure = 0;
4790 +                       _dl_preload = _dl_getenv("LD_PRELOAD", envp);
4791 +                       _dl_library_path = _dl_getenv("LD_LIBRARY_PATH", envp);
4792 +               } else {
4793 +                       _dl_secure = 1;
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;
4799 +               }
4800 +       }
4801 +
4802 +#ifdef __SUPPORT_LD_DEBUG__
4803 +       _dl_debug    = _dl_getenv("LD_DEBUG", envp);
4804 +       if (_dl_debug)
4805 +       {
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");
4809 +         }
4810 +         else {
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");
4817 +         }
4818 +       }
4819 +       {
4820 +         const char *dl_debug_output;
4821 +         
4822 +         dl_debug_output = _dl_getenv("LD_DEBUG_OUTPUT", envp);
4823 +
4824 +         if (dl_debug_output)
4825 +         {
4826 +           char tmp[22], *tmp1, *filename;
4827 +           int len1, len2;
4828 +           
4829 +           _dl_memset(tmp, 0, sizeof(tmp));
4830 +           tmp1=_dl_simple_ltoa( tmp, (unsigned long)_dl_getpid());
4831 +
4832 +           len1 = _dl_strlen(dl_debug_output);
4833 +           len2 = _dl_strlen(tmp1);
4834 +
4835 +           filename = _dl_malloc(len1+len2+2);
4836 +
4837 +           if (filename)
4838 +           {
4839 +             _dl_strcpy (filename, dl_debug_output);
4840 +             filename[len1] = '.';
4841 +             _dl_strcpy (&filename[len1+1], tmp1);
4842 +
4843 +             _dl_debug_file= _dl_open (filename, O_WRONLY|O_CREAT);
4844 +             if (_dl_debug_file<0)
4845 +             {
4846 +               _dl_debug_file = 2;
4847 +               _dl_dprintf (2, "can't open file: '%s'\n",filename);
4848 +             }
4849 +           }
4850 +         }
4851 +       }
4852 +       
4853 +       
4854 +#endif 
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");
4859 +               _dl_exit(1);
4860 +       }
4861 +#endif
4862 +
4863 +       /*
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.
4867 +        */
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;
4873 +
4874 +       /* Notify the debugger we are in a consistant state */
4875 +       _dl_debug_addr->r_state = RT_CONSISTENT;
4876 +       _dl_debug_state();
4877 +
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
4881 +          correct order. */
4882 +
4883 +       _dl_map_cache();
4884 +
4885 +
4886 +       if (_dl_preload) 
4887 +       {
4888 +               char c, *str, *str2;
4889 +
4890 +               str = _dl_preload;
4891 +               while (*str == ':' || *str == ' ' || *str == '\t')
4892 +                       str++;
4893 +               while (*str) 
4894 +               {
4895 +                       str2 = str;
4896 +                       while (*str2 && *str2 != ':' && *str2 != ' ' && *str2 != '\t')
4897 +                               str2++;
4898 +                       c = *str2;
4899 +                       *str2 = '\0';
4900 +                       if (!_dl_secure || _dl_strchr(str, '/') == NULL) 
4901 +                       {
4902 +                               if ((tpnt1 = _dl_check_if_named_library_is_loaded(str))) 
4903 +                               {
4904 +                                       continue;
4905 +                               }
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);
4909 +#endif
4910 +                               tpnt1 = _dl_load_shared_library(_dl_secure, &rpnt, NULL, str);
4911 +                               if (!tpnt1) {
4912 +#ifdef __LDSO_LDD_SUPPORT__
4913 +                                       if (_dl_trace_loaded_objects)
4914 +                                               _dl_dprintf(1, "\t%s => not found\n", str);
4915 +                                       else 
4916 +#endif
4917 +                                       {
4918 +                                               _dl_dprintf(2, "%s: can't load " "library '%s'\n", _dl_progname, str);
4919 +                                               _dl_exit(15);
4920 +                                       }
4921 +                               } else {
4922 +#ifdef __SUPPORT_LD_DEBUG_EARLY__
4923 +                                       _dl_dprintf(_dl_debug_file, "Loading:\t(%x) %s\n", tpnt1->loadaddr, tpnt1->libname);
4924 +#endif
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);
4932 +                                       }
4933 +#endif
4934 +                               }
4935 +                       }
4936 +                       *str2 = c;
4937 +                       str = str2;
4938 +                       while (*str == ':' || *str == ' ' || *str == '\t')
4939 +                               str++;
4940 +               }
4941 +       }
4942 +
4943 +#ifdef SUPPORT_LDSO_PRELOAD_FILE
4944 +       {
4945 +               int fd;
4946 +               struct stat st;
4947 +               char *preload;
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);
4952 +                       } else {
4953 +                               preload = (caddr_t) _dl_mmap(0, st.st_size + 1, 
4954 +                                               PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
4955 +                               _dl_close(fd);
4956 +                               if (preload == (caddr_t) - 1) {
4957 +                                       _dl_dprintf(2, "%s: can't map file '%s'\n", 
4958 +                                                       _dl_progname, LDSO_PRELOAD);
4959 +                               } else {
4960 +                                       char c, *cp, *cp2;
4961 +
4962 +                                       /* convert all separators and comments to spaces */
4963 +                                       for (cp = preload; *cp; /*nada */ ) {
4964 +                                               if (*cp == ':' || *cp == '\t' || *cp == '\n') {
4965 +                                                       *cp++ = ' ';
4966 +                                               } else if (*cp == '#') {
4967 +                                                       do
4968 +                                                               *cp++ = ' ';
4969 +                                                       while (*cp != '\n' && *cp != '\0');
4970 +                                               } else {
4971 +                                                       cp++;
4972 +                                               }
4973 +                                       }
4974 +
4975 +                                       /* find start of first library */
4976 +                                       for (cp = preload; *cp && *cp == ' '; cp++)
4977 +                                               /*nada */ ;
4978 +
4979 +                                       while (*cp) {
4980 +                                               /* find end of library */
4981 +                                               for (cp2 = cp; *cp && *cp != ' '; cp++)
4982 +                                                       /*nada */ ;
4983 +                                               c = *cp;
4984 +                                               *cp = '\0';
4985 +
4986 +                                               if ((tpnt1 = _dl_check_if_named_library_is_loaded(cp2))) 
4987 +                                               {
4988 +                                                       continue;
4989 +                                               }
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);
4993 +#endif
4994 +                                               tpnt1 = _dl_load_shared_library(0, &rpnt, NULL, cp2);
4995 +                                               if (!tpnt1) {
4996 +#ifdef __LDSO_LDD_SUPPORT__
4997 +                                                       if (_dl_trace_loaded_objects)
4998 +                                                               _dl_dprintf(1, "\t%s => not found\n", cp2);
4999 +                                                       else 
5000 +#endif
5001 +                                                       {
5002 +                                                               _dl_dprintf(2, "%s: can't load library '%s'\n", _dl_progname, cp2);
5003 +                                                               _dl_exit(15);
5004 +                                                       }
5005 +                                               } else {
5006 +#ifdef __SUPPORT_LD_DEBUG_EARLY__
5007 +                                                       _dl_dprintf(_dl_debug_file, "Loading:\t(%x) %s\n", tpnt1->loadaddr, tpnt1->libname);
5008 +#endif
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);
5013 +                                                       }
5014 +#endif
5015 +                                               }
5016 +
5017 +                                               /* find start of next library */
5018 +                                               *cp = c;
5019 +                                               for ( /*nada */ ; *cp && *cp == ' '; cp++)
5020 +                                                       /*nada */ ;
5021 +                                       }
5022 +
5023 +                                       _dl_munmap(preload, st.st_size + 1);
5024 +                               }
5025 +                       }
5026 +               }
5027 +       }
5028 +#endif
5029 +
5030 +       for (tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next) 
5031 +       {
5032 +               Elf32_Dyn *dpnt;
5033 +               for (dpnt = (Elf32_Dyn *) tcurr->dynamic_addr; dpnt->d_tag; dpnt++) 
5034 +               {
5035 +                       if (dpnt->d_tag == DT_NEEDED) 
5036 +                       {
5037 +                               char *name;
5038 +                               lpntstr = (char*) (tcurr->loadaddr + tcurr->dynamic_info[DT_STRTAB] + dpnt->d_un.d_val);
5039 +                               name = _dl_get_last_path_component(lpntstr);
5040 +
5041 +                               if ((tpnt1 = _dl_check_if_named_library_is_loaded(name))) 
5042 +                               {
5043 +                                       continue;
5044 +                               }
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);
5048 +#endif
5049 +                               if (!(tpnt1 = _dl_load_shared_library(0, &rpnt, tcurr, lpntstr)))
5050 +                               {
5051 +#ifdef __LDSO_LDD_SUPPORT__
5052 +                                       if (_dl_trace_loaded_objects) {
5053 +                                               _dl_dprintf(1, "\t%s => not found\n", lpntstr);
5054 +                                               continue;
5055 +                                       } else 
5056 +#endif
5057 +                                       {
5058 +                                               _dl_dprintf(2, "%s: can't load library '%s'\n", _dl_progname, lpntstr);
5059 +                                               _dl_exit(16);
5060 +                                       }
5061 +                               } else {
5062 +#ifdef __SUPPORT_LD_DEBUG_EARLY__
5063 +                                       _dl_dprintf(_dl_debug_file, "Loading:\t(%x) %s\n", tpnt1->loadaddr, tpnt1->libname);
5064 +#endif
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);
5069 +                                       }
5070 +#endif
5071 +                               }
5072 +                       }
5073 +               }
5074 +       }
5075 +
5076 +
5077 +       _dl_unmap_cache();
5078 +
5079 +       /*
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 
5082 +        * dynamic linker.
5083 +        */
5084 +       if (tpnt) {
5085 +               tcurr = _dl_loaded_modules;
5086 +               if (tcurr)
5087 +                       while (tcurr->next)
5088 +                               tcurr = tcurr->next;
5089 +               tpnt->next = NULL;
5090 +               tpnt->usage_count++;
5091 +
5092 +               if (tcurr) {
5093 +                       tcurr->next = tpnt;
5094 +                       tpnt->prev = tcurr;
5095 +               } else {
5096 +                       _dl_loaded_modules = tpnt;
5097 +                       tpnt->prev = NULL;
5098 +               }
5099 +               if (rpnt) {
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;
5104 +               } else {
5105 +                       rpnt = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
5106 +                       _dl_memset(rpnt, 0, sizeof(struct dyn_elf));
5107 +               }
5108 +               rpnt->dyn = tpnt;
5109 +               tpnt = NULL;
5110 +       }
5111 +
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);  
5117 +               _dl_exit(0);
5118 +       }
5119 +#endif
5120 +
5121 +
5122 +#ifdef __mips__
5123 +       /*
5124 +        * Relocation of the GOT entries for MIPS have to be done
5125 +        * after all the libraries have been loaded.
5126 +        */
5127 +       _dl_perform_mips_global_got_relocations(_dl_loaded_modules);
5128 +#endif
5129 +
5130 +#ifdef __SUPPORT_LD_DEBUG_EARLY__
5131 +       _dl_dprintf(_dl_debug_file, "Beginning relocation fixups\n");
5132 +#endif
5133 +       /*
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;
5139 +
5140 +
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.  */
5144 +
5145 +#ifdef __SUPPORT_LD_DEBUG_EARLY__
5146 +       _dl_dprintf(_dl_debug_file, "Beginning copy fixups\n");
5147 +#endif
5148 +       if (_dl_symbol_tables)
5149 +               goof += _dl_copy_fixups(_dl_symbol_tables);
5150 +
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. */
5157 +
5158 +
5159 +       _dl_brkp = (unsigned long *) (intptr_t) _dl_find_hash("___brk_addr", NULL, NULL, symbolrel);
5160 +       
5161 +       if (_dl_brkp) {
5162 +               *_dl_brkp = brk_addr;
5163 +       }
5164 +       _dl_envp = (unsigned long *) (intptr_t) _dl_find_hash("__environ", NULL, NULL, symbolrel);
5165 +
5166 +       if (_dl_envp) {
5167 +               *_dl_envp = (unsigned long) envp;
5168 +       }
5169 +
5170 +#ifndef FORCE_SHAREABLE_TEXT_SEGMENTS
5171 +       {
5172 +               unsigned int j;
5173 +               ElfW(Phdr) *myppnt;
5174 +
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));
5182 +                               }
5183 +                       }
5184 +               }
5185 +
5186 +       }
5187 +#endif
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);
5192 +#endif
5193 +
5194 +       /* Notify the debugger we have added some objects. */
5195 +       _dl_debug_addr->r_state = RT_ADD;
5196 +       _dl_debug_state();
5197 +
5198 +       for (rpnt = _dl_symbol_tables; rpnt!=NULL&& rpnt->next!=NULL; rpnt=rpnt->next)
5199 +         ;
5200 +         
5201 +       for (;rpnt!=NULL; rpnt=rpnt->prev)
5202 +       {
5203 +               tpnt = rpnt->dyn;
5204 +
5205 +               if (tpnt->libtype == program_interpreter)
5206 +                       continue;
5207 +
5208 +               /* Apparently crt0/1 for the application is responsible for handling this.
5209 +                * We only need to run the init/fini for shared libraries
5210 +                */
5211 +               if (tpnt->libtype == elf_executable)
5212 +                       break;      /* at this point all shared libs are initialized !! */
5213 +
5214 +               if (tpnt->init_flag & INIT_FUNCS_CALLED)
5215 +                       continue;
5216 +               tpnt->init_flag |= INIT_FUNCS_CALLED;
5217 +
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);      
5223 +#endif    
5224 +                       (*dl_elf_func) ();
5225 +               }
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)
5232 +                       {
5233 +                               (*_dl_on_exit)(debug_fini, tpnt->libname);
5234 +                       }
5235 +#endif
5236 +               }
5237 +#if defined (__SUPPORT_LD_DEBUG__)
5238 +               else {
5239 +                       if (!_dl_atexit)
5240 +                               _dl_dprintf(_dl_debug_file, "%s: The address of atexit () is 0x0.\n", tpnt->libname);
5241 +#if 0
5242 +                       if (!tpnt->dynamic_info[DT_FINI])
5243 +                               _dl_dprintf(_dl_debug_file, "%s: Invalid .fini section.\n", tpnt->libname);
5244 +#endif
5245 +               }
5246 +#endif
5247 +       }
5248 +}
5249 +
5250 +/*
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.
5254 + */
5255 +void _dl_debug_state(void)
5256 +{
5257 +}
5258 +
5259 +char *_dl_getenv(const char *symbol, char **envp)
5260 +{
5261 +       char *pnt;
5262 +       const char *pnt1;
5263 +
5264 +       while ((pnt = *envp++)) {
5265 +               pnt1 = symbol;
5266 +               while (*pnt && *pnt == *pnt1)
5267 +                       pnt1++, pnt++;
5268 +               if (!*pnt || *pnt != '=' || *pnt1)
5269 +                       continue;
5270 +               return pnt + 1;
5271 +       }
5272 +       return 0;
5273 +}
5274 +
5275 +void _dl_unsetenv(const char *symbol, char **envp)
5276 +{
5277 +       char *pnt;
5278 +       const char *pnt1;
5279 +       char **newenvp = envp;
5280 +
5281 +       for (pnt = *envp; pnt; pnt = *++envp) {
5282 +               pnt1 = symbol;
5283 +               while (*pnt && *pnt == *pnt1)
5284 +                       pnt1++, pnt++;
5285 +               if (!*pnt || *pnt != '=' || *pnt1)
5286 +                       *newenvp++ = *envp;
5287 +       }
5288 +       *newenvp++ = *envp;
5289 +       return;
5290 +}
5291 +
5292 +#include "hash.c"
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
5297 @@ -0,0 +1,7 @@
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
5301 + * can be done.
5302 + */
5303 +
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
5308 @@ -0,0 +1,359 @@
5309 +/* vi: set sw=4 ts=4: */
5310 +/* m68k ELF shared library loader suppport
5311 + *
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.
5315 + *
5316 + * All rights reserved.
5317 + *
5318 + * Redistribution and use in source and binary forms, with or without
5319 + * modification, are permitted provided that the following conditions
5320 + * are met:
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.
5326 + *
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
5337 + * SUCH DAMAGE.
5338 + */
5339 +
5340 +#if defined (__SUPPORT_LD_DEBUG__)
5341 +static const char *_dl_reltypes[] =
5342 +{
5343 +  "R_68K_NONE",
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",
5351 +  "R_68K_NUM"
5352 +};
5353 +#endif
5354 +
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. */
5358 +
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
5364 +   working. */
5365 +
5366 +
5367 +unsigned int _dl_linux_resolver (int dummy1, int dummy2, 
5368 +       struct elf_resolve *tpnt, int reloc_entry)
5369 +{
5370 +  int reloc_type;
5371 +  Elf32_Rela *this_reloc;
5372 +  char *strtab;
5373 +  Elf32_Sym *symtab;
5374 +  char *rel_addr;
5375 +  int symtab_index;
5376 +  char *new_addr;
5377 +  char **got_addr;
5378 +  unsigned int instr_addr;
5379 +
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);
5384 +
5385 +  symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB]
5386 +                                + tpnt->loadaddr);
5387 +  strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
5388 +
5389 +
5390 +  if (reloc_type != R_68K_JMP_SLOT)
5391 +    {
5392 +      _dl_dprintf (2, "%s: incorrect relocation type in jump relocations\n",
5393 +                   _dl_progname);
5394 +      _dl_exit (1);
5395 +    }
5396 +
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;
5400 +
5401 +#ifdef __SUPPORT_LD_DEBUG__
5402 +  if (_dl_debug_symbols) {
5403 +         _dl_dprintf (2, "Resolving symbol %s\n", strtab + symtab[symtab_index].st_name);
5404 +  }
5405 +#endif
5406 +
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);
5410 +  if (!new_addr)
5411 +    {
5412 +      _dl_dprintf (2, "%s: can't resolve symbol '%s'\n",
5413 +                   _dl_progname, strtab + symtab[symtab_index].st_name);
5414 +      _dl_exit (1);
5415 +    }
5416 +#if defined (__SUPPORT_LD_DEBUG__)
5417 +       if ((unsigned long) got_addr < 0x40000000)
5418 +       {
5419 +               if (_dl_debug_bindings)
5420 +               {
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);
5425 +               }
5426 +       }
5427 +       if (!_dl_debug_nofixups) {
5428 +               *got_addr = new_addr;
5429 +       }
5430 +#else
5431 +       *got_addr = new_addr;
5432 +#endif
5433 +
5434 +  return (unsigned int) new_addr;
5435 +}
5436 +
5437 +void
5438 +_dl_parse_lazy_relocation_information (struct elf_resolve *tpnt,
5439 +                       unsigned long rel_addr, unsigned long rel_size, int type)
5440 +{
5441 +  int i;
5442 +  char *strtab;
5443 +  int reloc_type;
5444 +  int symtab_index;
5445 +  Elf32_Sym *symtab;
5446 +  Elf32_Rela *rpnt;
5447 +  unsigned int *reloc_addr;
5448 +
5449 +  /* Now parse the relocation information.  */
5450 +  rpnt = (Elf32_Rela *) (rel_addr + tpnt->loadaddr);
5451 +  rel_size = rel_size / sizeof (Elf32_Rela);
5452 +
5453 +  symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB]
5454 +                                + tpnt->loadaddr);
5455 +  strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
5456 +
5457 +  for (i = 0; i < rel_size; i++, rpnt++)
5458 +    {
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);
5462 +
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
5466 +         && (!symtab_index
5467 +             || _dl_symbol (strtab + symtab[symtab_index].st_name)))
5468 +       continue;
5469 +
5470 +      switch (reloc_type)
5471 +       {
5472 +       case R_68K_NONE:
5473 +         break;
5474 +       case R_68K_JMP_SLOT:
5475 +         *reloc_addr += (unsigned int) tpnt->loadaddr;
5476 +         break;
5477 +       default:
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]);
5481 +#endif
5482 +         if (symtab_index)
5483 +           _dl_dprintf (2, "'%s'", strtab + symtab[symtab_index].st_name);
5484 +         _dl_dprintf (2, "\n");
5485 +         _dl_exit (1);
5486 +       }
5487 +    }
5488 +}
5489 +
5490 +int 
5491 +_dl_parse_relocation_information (struct elf_resolve *tpnt,
5492 +                  unsigned long rel_addr, unsigned long rel_size, int type)
5493 +{
5494 +  int i;
5495 +  char *strtab;
5496 +  int reloc_type;
5497 +  int goof = 0;
5498 +  Elf32_Sym *symtab;
5499 +  Elf32_Rela *rpnt;
5500 +  unsigned int *reloc_addr;
5501 +  unsigned int symbol_addr;
5502 +  int symtab_index;
5503 +  /* Now parse the relocation information */
5504 +
5505 +  rpnt = (Elf32_Rela *) (rel_addr + tpnt->loadaddr);
5506 +  rel_size = rel_size / sizeof (Elf32_Rela);
5507 +
5508 +  symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB]
5509 +                                + tpnt->loadaddr);
5510 +  strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
5511 +
5512 +  for (i = 0; i < rel_size; i++, rpnt++)
5513 +    {
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);
5517 +      symbol_addr = 0;
5518 +
5519 +      if (tpnt->libtype == program_interpreter
5520 +         && (!symtab_index
5521 +             || _dl_symbol (strtab + symtab[symtab_index].st_name)))
5522 +       continue;
5523 +
5524 +      if (symtab_index)
5525 +       {
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);
5530 +
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
5534 +            covered.  */
5535 +         if (!symbol_addr
5536 +             && ELF32_ST_BIND (symtab[symtab_index].st_info) == STB_GLOBAL)
5537 +           {
5538 +             _dl_dprintf (2, "%s: can't resolve symbol '%s'\n",
5539 +                           _dl_progname, strtab + symtab[symtab_index].st_name);
5540 +             goof++;
5541 +           }
5542 +       }
5543 +      switch (reloc_type)
5544 +       {
5545 +       case R_68K_NONE:
5546 +         break;
5547 +       case R_68K_8:
5548 +         *(char *) reloc_addr = symbol_addr + rpnt->r_addend;
5549 +         break;
5550 +       case R_68K_16:
5551 +         *(short *) reloc_addr = symbol_addr + rpnt->r_addend;
5552 +         break;
5553 +       case R_68K_32:
5554 +         *reloc_addr = symbol_addr + rpnt->r_addend;
5555 +         break;
5556 +       case R_68K_PC8:
5557 +         *(char *) reloc_addr = (symbol_addr + rpnt->r_addend
5558 +                                 - (unsigned int) reloc_addr);
5559 +         break;
5560 +       case R_68K_PC16:
5561 +         *(short *) reloc_addr = (symbol_addr + rpnt->r_addend
5562 +                                  - (unsigned int) reloc_addr);
5563 +         break;
5564 +       case R_68K_PC32:
5565 +         *reloc_addr = (symbol_addr + rpnt->r_addend
5566 +                        - (unsigned int) reloc_addr);
5567 +         break;
5568 +       case R_68K_GLOB_DAT:
5569 +       case R_68K_JMP_SLOT:
5570 +         *reloc_addr = symbol_addr;
5571 +         break;
5572 +       case R_68K_RELATIVE:
5573 +         *reloc_addr = ((unsigned int) tpnt->loadaddr
5574 +                        /* Compatibility kludge.  */
5575 +                        + (rpnt->r_addend ? : *reloc_addr));
5576 +         break;
5577 +       case R_68K_COPY:
5578 +#if 0 /* Do this later.  */
5579 +         _dl_dprintf (2, "Doing copy");
5580 +         if (symtab_index)
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);
5587 +#endif
5588 +         break;
5589 +       default:
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]);
5593 +#endif
5594 +         if (symtab_index)
5595 +           _dl_dprintf (2, "'%s'", strtab + symtab[symtab_index].st_name);
5596 +         _dl_dprintf (2, "\n");
5597 +         _dl_exit (1);
5598 +       }
5599 +
5600 +    }
5601 +  return goof;
5602 +}
5603 +
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.  */
5609 +
5610 +/* No, there are cases where the SVr4 linker fails to emit COPY relocs
5611 +   at all.  */
5612 +
5613 +int 
5614 +_dl_parse_copy_information (struct dyn_elf *xpnt, unsigned long rel_addr,
5615 +                           unsigned long rel_size, int type)
5616 +{
5617 +  int i;
5618 +  char *strtab;
5619 +  int reloc_type;
5620 +  int goof = 0;
5621 +  Elf32_Sym *symtab;
5622 +  Elf32_Rela *rpnt;
5623 +  unsigned int *reloc_addr;
5624 +  unsigned int symbol_addr;
5625 +  struct elf_resolve *tpnt;
5626 +  int symtab_index;
5627 +  /* Now parse the relocation information */
5628 +
5629 +  tpnt = xpnt->dyn;
5630 +
5631 +  rpnt = (Elf32_Rela *) (rel_addr + tpnt->loadaddr);
5632 +  rel_size = rel_size / sizeof (Elf32_Rela);
5633 +
5634 +  symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB]
5635 +                                + tpnt->loadaddr);
5636 +  strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
5637 +
5638 +  for (i = 0; i < rel_size; i++, rpnt++)
5639 +    {
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)
5643 +       continue;
5644 +      symtab_index = ELF32_R_SYM (rpnt->r_info);
5645 +      symbol_addr = 0;
5646 +      if (tpnt->libtype == program_interpreter
5647 +         && (!symtab_index
5648 +             || _dl_symbol (strtab + symtab[symtab_index].st_name)))
5649 +       continue;
5650 +      if (symtab_index)
5651 +       {
5652 +         symbol_addr = (unsigned int)
5653 +           _dl_find_hash (strtab + symtab[symtab_index].st_name,
5654 +                          xpnt->next, NULL, copyrel);
5655 +         if (!symbol_addr)
5656 +           {
5657 +             _dl_dprintf (2, "%s: can't resolve symbol '%s'\n",
5658 +                           _dl_progname, strtab + symtab[symtab_index].st_name);
5659 +             goof++;
5660 +           }
5661 +       }
5662 +      if (!goof)
5663 +      _dl_memcpy ((void *) symtab[symtab_index].st_value, (void *) symbol_addr,
5664 +                 symtab[symtab_index].st_size);
5665 +    }
5666 +  return goof;
5667 +}
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
5671 @@ -0,0 +1,174 @@
5672 +/*
5673 + * This file contains the system call macros and syscall 
5674 + * numbers used by the shared library loader.
5675 + */
5676 +
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
5691 +
5692 +
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 
5697 + * linked. */
5698 +
5699 +
5700 +#define __syscall_return(type, res) \
5701 +do { \
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; */ \
5707 +               res = -1; \
5708 +       } \
5709 +       return (type) (res); \
5710 +} while (0)
5711 +
5712 +#define _syscall0(type, name)                                          \
5713 +type name(void)                                                                \
5714 +{                                                                      \
5715 +  long __res;                                                          \
5716 +  __asm__ __volatile__ ("movel %1, %%d0\n\t"                           \
5717 +                       "trap   #0\n\t"                                 \
5718 +                       "movel  %%d0, %0"                               \
5719 +                       : "=g" (__res)                                  \
5720 +                       : "i" (__NR_##name)                             \
5721 +                       : "cc", "%d0");                                 \
5722 +  if ((unsigned long)(__res) >= (unsigned long)(-125)) {                       \
5723 +    /* errno = -__res; */                                                      \
5724 +    __res = -1;                                                                \
5725 +  }                                                                    \
5726 +  return (type)__res;                                                  \
5727 +}
5728 +
5729 +#define _syscall1(type, name, atype, a)                                        \
5730 +type name(atype a)                                                     \
5731 +{                                                                      \
5732 +  long __res;                                                          \
5733 +  __asm__ __volatile__ ("movel %2, %%d1\n\t"                           \
5734 +                       "movel  %1, %%d0\n\t"                           \
5735 +                       "trap   #0\n\t"                                 \
5736 +                       "movel  %%d0, %0"                               \
5737 +                       : "=g" (__res)                                  \
5738 +                       : "i" (__NR_##name),                            \
5739 +                         "g" ((long)a)                                 \
5740 +                       : "cc", "%d0", "%d1");                          \
5741 +  if ((unsigned long)(__res) >= (unsigned long)(-125)) {                       \
5742 +    /* errno = -__res; */                                                      \
5743 +    __res = -1;                                                                \
5744 +  }                                                                    \
5745 +  return (type)__res;                                                  \
5746 +}
5747 +
5748 +#define _syscall2(type, name, atype, a, btype, b)                      \
5749 +type name(atype a, btype b)                                            \
5750 +{                                                                      \
5751 +  long __res;                                                          \
5752 +  __asm__ __volatile__ ("movel %3, %%d2\n\t"                           \
5753 +                       "movel  %2, %%d1\n\t"                           \
5754 +                       "movel  %1, %%d0\n\t"                           \
5755 +                       "trap   #0\n\t"                                 \
5756 +                       "movel  %%d0, %0"                               \
5757 +                       : "=g" (__res)                                  \
5758 +                       : "i" (__NR_##name),                            \
5759 +                         "a" ((long)a),                                \
5760 +                         "g" ((long)b)                                 \
5761 +                       : "cc", "%d0", "%d1", "%d2");                   \
5762 +  if ((unsigned long)(__res) >= (unsigned long)(-125)) {                       \
5763 +    /* errno = -__res; */                                                      \
5764 +    __res = -1;                                                                \
5765 +  }                                                                    \
5766 +  return (type)__res;                                                  \
5767 +}
5768 +
5769 +#define _syscall3(type, name, atype, a, btype, b, ctype, c)            \
5770 +type name(atype a, btype b, ctype c)                                   \
5771 +{                                                                      \
5772 +  long __res;                                                          \
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"                           \
5777 +                       "trap   #0\n\t"                                 \
5778 +                       "movel  %%d0, %0"                               \
5779 +                       : "=g" (__res)                                  \
5780 +                       : "i" (__NR_##name),                            \
5781 +                         "a" ((long)a),                                \
5782 +                         "a" ((long)b),                                \
5783 +                         "g" ((long)c)                                 \
5784 +                       : "cc", "%d0", "%d1", "%d2", "%d3");            \
5785 +  if ((unsigned long)(__res) >= (unsigned long)(-125)) {                       \
5786 +    /* errno = -__res; */                                                      \
5787 +    __res = -1;                                                                \
5788 +  }                                                                    \
5789 +  return (type)__res;                                                  \
5790 +}
5791 +
5792 +#define _syscall4(type, name, atype, a, btype, b, ctype, c, dtype, d)  \
5793 +type name(atype a, btype b, ctype c, dtype d)                          \
5794 +{                                                                      \
5795 +  long __res;                                                          \
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"                           \
5801 +                       "trap   #0\n\t"                                 \
5802 +                       "movel  %%d0, %0"                               \
5803 +                       : "=g" (__res)                                  \
5804 +                       : "i" (__NR_##name),                            \
5805 +                         "a" ((long)a),                                \
5806 +                         "a" ((long)b),                                \
5807 +                         "a" ((long)c),                                \
5808 +                         "g" ((long)d)                                 \
5809 +                       : "cc", "%d0", "%d1", "%d2", "%d3",             \
5810 +                         "%d4");                                       \
5811 +  if ((unsigned long)(__res) >= (unsigned long)(-125)) {                       \
5812 +    /* errno = -__res; */                                                      \
5813 +    __res = -1;                                                                \
5814 +  }                                                                    \
5815 +  return (type)__res;                                                  \
5816 +}
5817 +
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)                 \
5820 +{                                                                      \
5821 +  long __res;                                                          \
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"                           \
5828 +                       "trap   #0\n\t"                                 \
5829 +                       "movel  %%d0, %0"                               \
5830 +                       : "=g" (__res)                                  \
5831 +                       : "i" (__NR_##name),                            \
5832 +                         "a" ((long)a),                                \
5833 +                         "a" ((long)b),                                \
5834 +                         "a" ((long)c),                                \
5835 +                         "a" ((long)d),                                \
5836 +                         "g" ((long)e)                                 \
5837 +                       : "cc", "%d0", "%d1", "%d2", "%d3",             \
5838 +                         "%d4", "%d5");                                \
5839 +  if ((unsigned long)(__res) >= (unsigned long)(-125)) {                       \
5840 +    /* errno = -__res; */                                                      \
5841 +    __res = -1;                                                                \
5842 +  }                                                                    \
5843 +  return (type)__res;                                                  \
5844 +}
5845 +
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
5849 @@ -0,0 +1,88 @@
5850 +
5851 +/* Various assmbly language/system dependent hacks that are required
5852 +   so that we can minimize the amount of platform specific code. */
5853 +
5854 +/* Define this if the system uses RELOCA.  */
5855 +#define ELF_USES_RELOCA
5856 +
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)))
5861 +
5862 +/* Initialization sequence for a GOT.  */
5863 +#define INIT_GOT(GOT_BASE,MODULE)              \
5864 +{                                              \
5865 +  GOT_BASE[2] = (int) _dl_linux_resolve;       \
5866 +  GOT_BASE[1] = (int) (MODULE);                        \
5867 +}
5868 +
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))                       \
5876 +    {                                                          \
5877 +    case R_68K_8:                                              \
5878 +      *(char *) (REL) = (SYMBOL) + (RELP)->r_addend;           \
5879 +      break;                                                   \
5880 +    case R_68K_16:                                             \
5881 +      *(short *) (REL) = (SYMBOL) + (RELP)->r_addend;          \
5882 +      break;                                                   \
5883 +    case R_68K_32:                                             \
5884 +      *(REL) = (SYMBOL) + (RELP)->r_addend;                    \
5885 +      break;                                                   \
5886 +    case R_68K_PC8:                                            \
5887 +      *(char *) (REL) = ((SYMBOL) + (RELP)->r_addend           \
5888 +                        - (unsigned int) (REL));               \
5889 +      break;                                                   \
5890 +    case R_68K_PC16:                                           \
5891 +      *(short *) (REL) = ((SYMBOL) + (RELP)->r_addend          \
5892 +                         - (unsigned int) (REL));              \
5893 +      break;                                                   \
5894 +    case R_68K_PC32:                                           \
5895 +      *(REL) = ((SYMBOL) + (RELP)->r_addend                    \
5896 +               - (unsigned int) (REL));                        \
5897 +      break;                                                   \
5898 +    case R_68K_GLOB_DAT:                                       \
5899 +    case R_68K_JMP_SLOT:                                       \
5900 +      *(REL) = (SYMBOL);                                       \
5901 +      break;                                                   \
5902 +    case R_68K_RELATIVE:               /* Compatibility kludge */ \
5903 +      *(REL) = ((unsigned int) (LOAD) + ((RELP)->r_addend ? : *(REL))); \
5904 +      break;                                                   \
5905 +    default:                                                   \
5906 +      _dl_exit (1);                                            \
5907 +    }
5908 +
5909 +
5910 +/* Transfer control to the user's application, once the dynamic loader
5911 +   is done.  */
5912 +
5913 +#define START()                                        \
5914 +  __asm__ volatile ("unlk %%a6\n\t"            \
5915 +                   "jmp %0@"                   \
5916 +                   : : "a" (_dl_elf_main));
5917 +
5918 +
5919 +
5920 +/* Here we define the magic numbers that this dynamic loader should accept */
5921 +
5922 +#define MAGIC1 EM_68K
5923 +#undef MAGIC2
5924 +/* Used for error messages */
5925 +#define ELF_TARGET "m68k"
5926 +
5927 +struct elf_resolve;
5928 +extern unsigned int _dl_linux_resolver (int, int, struct elf_resolve *, int);
5929 +
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))
5933 +
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
5941 @@ -0,0 +1,21 @@
5942 +/*
5943 + * These are various helper routines that are needed to run an ELF image.
5944 + */
5945 +
5946 +.text
5947 +.even
5948 +
5949 +.globl _dl_linux_resolve
5950 +       .type   _dl_linux_resolve,@function
5951 +_dl_linux_resolve:
5952 +       moveml  %a0/%a1,%sp@-
5953 +#ifdef __PIC__
5954 +       bsrl    _dl_linux_resolver@PLTPC
5955 +#else
5956 +       jbsr    _dl_linux_resolver
5957 +#endif
5958 +       moveml  %sp@+,%a0/%a1
5959 +       addql   #8,%sp
5960 +       jmp     @(%d0)
5961 +.LFE2:
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
5966 @@ -0,0 +1,52 @@
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.
5971 +
5972 +boot1_arch.h
5973 +------------
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'.
5978 +
5979 +elfinterp.c
5980 +-----------
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'.
5986 +
5987 +ld_syscalls.h
5988 +-------------
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'.
5995 +
5996 +ld_sysdep.h
5997 +-----------
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'.
6011 +
6012 +resolve.S
6013 +---------
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
6022 @@ -0,0 +1,38 @@
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.
6026 + */
6027 +
6028 +asm("" \
6029 +"      .text\n"                        \
6030 +"      .globl  _dl_boot\n"             \
6031 +"_dl_boot:\n"                          \
6032 +"      .set noreorder\n"               \
6033 +"      bltzal $0, 0f\n"                \
6034 +"      nop\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"                 \
6040 +"      la $8, coff\n"                  \
6041 +"      .set noreorder\n"               \
6042 +"      bltzal $0, coff\n"              \
6043 +"      nop\n"                          \
6044 +"coff: subu $8, $31, $8\n"             \
6045 +"      .set reorder\n"                 \
6046 +"      la $25, _dl_boot2\n"            \
6047 +"      addu $25, $8\n"                 \
6048 +"      jalr $25\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"                \
6056 +"      jr $25\n"                       \
6057 +);
6058 +
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
6064 @@ -0,0 +1,301 @@
6065 +/* vi: set sw=4 ts=4: */
6066 +/* mips/mipsel ELF shared library loader suppport
6067 + *
6068 +   Copyright (C) 2002, Steven J. Hill (sjhill@realitydiluted.com)
6069 + *
6070 + * All rights reserved.
6071 + *
6072 + * Redistribution and use in source and binary forms, with or without
6073 + * modification, are permitted provided that the following conditions
6074 + * are met:
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.
6080 + *
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
6091 + * SUCH DAMAGE.
6092 + */
6093 +
6094 +#if defined (__SUPPORT_LD_DEBUG__)
6095 +static const char *_dl_reltypes_tab[] =
6096 +{
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",
6110 +};
6111 +
6112 +static const char *
6113 +_dl_reltypes(int type)
6114 +{
6115 +  static char buf[22];  
6116 +  const char *str;
6117 +  
6118 +  if (type >= (int)(sizeof (_dl_reltypes_tab)/sizeof(_dl_reltypes_tab[0])) ||
6119 +      NULL == (str = _dl_reltypes_tab[type]))
6120 +  {
6121 +    str =_dl_simple_ltoa( buf, (unsigned long)(type));
6122 +  }
6123 +  return str;
6124 +}
6125 +
6126 +static 
6127 +void debug_sym(Elf32_Sym *symtab,char *strtab,int symtab_index)
6128 +{
6129 +  if(_dl_debug_symbols)
6130 +  {
6131 +    if(symtab_index){
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);
6139 +    }
6140 +  }
6141 +}
6142 +
6143 +static void debug_reloc(Elf32_Sym *symtab,char *strtab, ELF_RELOC *rpnt)
6144 +{
6145 +  if(_dl_debug_reloc)
6146 +  {
6147 +    int symtab_index;
6148 +    const char *sym;
6149 +    symtab_index = ELF32_R_SYM(rpnt->r_info);
6150 +    sym = symtab_index ? strtab + symtab[symtab_index].st_name : "sym=0x0";
6151 +    
6152 +  if(_dl_debug_symbols)
6153 +         _dl_dprintf(_dl_debug_file, "\n\t");
6154 +  else
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)),
6159 +               rpnt->r_offset,
6160 +               rpnt->r_addend);
6161 +#else
6162 +    _dl_dprintf(_dl_debug_file, "%s\toffset=%x\n",
6163 +               _dl_reltypes(ELF32_R_TYPE(rpnt->r_info)),
6164 +               rpnt->r_offset);
6165 +#endif
6166 +  }
6167 +}
6168 +#endif
6169 +
6170 +extern int _dl_linux_resolve(void);
6171 +
6172 +#define OFFSET_GP_GOT 0x7ff0
6173 +
6174 +unsigned long _dl_linux_resolver(unsigned long sym_index,
6175 +       unsigned long old_gpreg)
6176 +{
6177 +       unsigned long *got = (unsigned long *) (old_gpreg - OFFSET_GP_GOT);
6178 +       struct elf_resolve *tpnt = (struct elf_resolve *) got[1];
6179 +       Elf32_Sym *sym;
6180 +       char *strtab;
6181 +       unsigned long local_gotno;
6182 +       unsigned long gotsym;
6183 +       unsigned long new_addr;
6184 +       unsigned long instr_addr;
6185 +       char **got_addr;
6186 +       char *symname;
6187 +
6188 +       gotsym = tpnt->mips_gotsym;
6189 +       local_gotno = tpnt->mips_local_gotno;
6190 +
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;
6194 +
6195 +       new_addr = (unsigned long) _dl_find_hash(strtab + sym->st_name,
6196 +                tpnt->symbol_scope, tpnt, resolver);
6197 +        
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;
6201 +        
6202 +#if defined (__SUPPORT_LD_DEBUG__)
6203 +       if (_dl_debug_bindings)
6204 +       {
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);
6208 +       }
6209 +       if (!_dl_debug_nofixups) {
6210 +               *got_addr = (char*)new_addr;
6211 +       }
6212 +#else
6213 +       *got_addr = (char*)new_addr;
6214 +#endif
6215 +
6216 +       return new_addr;
6217 +}
6218 +
6219 +void _dl_parse_lazy_relocation_information(struct elf_resolve *tpnt, 
6220 +       unsigned long rel_addr, unsigned long rel_size, int type)
6221 +{
6222 +       /* Nothing to do */
6223 +       return;
6224 +}
6225 +
6226 +int _dl_parse_copy_information(struct dyn_elf *xpnt, unsigned long rel_addr, 
6227 +       unsigned long rel_size, int type)
6228 +{
6229 +       /* Nothing to do */
6230 +       return 0;
6231 +}
6232 +
6233 +
6234 +int _dl_parse_relocation_information(struct elf_resolve *tpnt, 
6235 +       unsigned long rel_addr, unsigned long rel_size, int type)
6236 +{
6237 +       Elf32_Sym *symtab;
6238 +       Elf32_Rel *rpnt;
6239 +       char *strtab;
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;
6244 +
6245 +       /* Now parse the relocation information */
6246 +       rel_size = rel_size / sizeof(Elf32_Rel);
6247 +       rpnt = (Elf32_Rel *) (rel_addr + tpnt->loadaddr);
6248 +
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);
6252 +
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);
6258 +               symbol_addr = 0;
6259 +
6260 +               if (!symtab_index && tpnt->libtype == program_interpreter)
6261 +                       continue;
6262 +
6263 +#if defined (__SUPPORT_LD_DEBUG__)
6264 +               debug_sym(symtab,strtab,symtab_index);
6265 +               debug_reloc(symtab,strtab,rpnt);
6266 +               old_val = *reloc_addr;
6267 +#endif
6268 +
6269 +               switch (reloc_type) {
6270 +               case R_MIPS_REL32:
6271 +                       if (symtab_index) {
6272 +                               if (symtab_index < tpnt->mips_gotsym)
6273 +                                       *reloc_addr +=
6274 +                                               symtab[symtab_index].st_value +
6275 +                                               (unsigned long) tpnt->loadaddr;
6276 +                               else {
6277 +                                       *reloc_addr += got[symtab_index + tpnt->mips_local_gotno -
6278 +                                               tpnt->mips_gotsym];
6279 +                               }
6280 +                       }
6281 +                       else {
6282 +                               *reloc_addr += (unsigned long) tpnt->loadaddr;
6283 +                       }
6284 +                       break;
6285 +               case R_MIPS_NONE:
6286 +                       break;
6287 +               default:
6288 +                       {
6289 +                               int reloc_type = ELF32_R_TYPE(rpnt->r_info);
6290 +                               _dl_dprintf(2, "\n%s: ",_dl_progname);
6291 +
6292 +                               if (symtab_index)
6293 +                                       _dl_dprintf(2, "symbol '%s': ", strtab + symtab[symtab_index].st_name);
6294 +
6295 +#if defined (__SUPPORT_LD_DEBUG__)
6296 +                               _dl_dprintf(2, "can't handle reloc type %s\n ", _dl_reltypes(reloc_type));
6297 +#else
6298 +                               _dl_dprintf(2, "can't handle reloc type %x\n", reloc_type);
6299 +#endif                 
6300 +                               _dl_exit(1);
6301 +                       }
6302 +               };
6303 +
6304 +       };
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);
6308 +#endif
6309 +
6310 +       return 0;
6311 +}
6312 +
6313 +void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt)
6314 +{
6315 +       Elf32_Sym *sym;
6316 +       char *strtab;
6317 +       unsigned long i;
6318 +       unsigned long *got_entry;
6319 +
6320 +       for (; tpnt ; tpnt = tpnt->next) {
6321 +
6322 +               /* We don't touch the dynamic linker */
6323 +               if (tpnt->libtype == program_interpreter)
6324 +                       continue;
6325 +
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;
6334 +
6335 +               /* Relocate the global GOT entries for the object */
6336 +               while(i--) {
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;
6340 +                               else {
6341 +                                       *got_entry = (unsigned long) _dl_find_hash(strtab +
6342 +                                               sym->st_name, tpnt->symbol_scope, NULL, copyrel);
6343 +                               }
6344 +                       }
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);
6348 +                       }
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;
6355 +                       }
6356 +                       else {
6357 +                               *got_entry = (unsigned long) _dl_find_hash(strtab +
6358 +                                       sym->st_name, tpnt->symbol_scope, NULL, copyrel);
6359 +                       }
6360 +
6361 +                       got_entry++;
6362 +                       sym++;
6363 +               }
6364 +       }
6365 +}
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
6369 @@ -0,0 +1,7 @@
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. */
6373 +
6374 +#define __set_errno(X) {(void)(X);}
6375 +#include "sys/syscall.h"
6376 +
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
6380 @@ -0,0 +1,136 @@
6381 +/* vi: set sw=4 ts=4: */
6382 +
6383 +/*
6384 + * Various assmbly language/system dependent hacks that are required
6385 + * so that we can minimize the amount of platform specific code.
6386 + */
6387 +
6388 +/* 
6389 + * Define this if the system uses RELOCA.
6390 + */
6391 +#undef ELF_USES_RELOCA
6392 +
6393 +
6394 +/*
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.
6398 + */
6399 +#define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned long *) ARGS)
6400 +
6401 +
6402 +/*
6403 + * Initialization sequence for the application/library GOT.
6404 + */
6405 +#define INIT_GOT(GOT_BASE,MODULE)                                                                              \
6406 +do {                                                                                                                                   \
6407 +       unsigned long i;                                                                                                        \
6408 +                                                                                                                                               \
6409 +       /* Check if this is the dynamic linker itself */                                        \
6410 +       if (MODULE->libtype == program_interpreter)                                                     \
6411 +               continue;                                                                                                               \
6412 +                                                                                                                                               \
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;                                                           \
6416 +                                                                                                                                               \
6417 +       /* Add load address displacement to all local GOT entries */            \
6418 +       i = 2;                                                                                                                          \
6419 +       while (i < MODULE->mips_local_gotno)                                                            \
6420 +               GOT_BASE[i++] += (unsigned long) MODULE->loadaddr;                              \
6421 +                                                                                                                                               \
6422 +} while (0)
6423 +
6424 +
6425 +/*
6426 + * Here is a macro to perform the GOT relocation. This is only
6427 + * used when bootstrapping the dynamic loader.
6428 + */
6429 +#define PERFORM_BOOTSTRAP_GOT(got)                                                                             \
6430 +do {                                                                                                                                   \
6431 +       Elf32_Sym *sym;                                                                                                         \
6432 +       unsigned long i;                                                                                                        \
6433 +                                                                                                                                               \
6434 +       /* Add load address displacement to all local GOT entries */            \
6435 +       i = 2;                                                                                                                          \
6436 +       while (i < tpnt->mips_local_gotno)                                                                      \
6437 +               got[i++] += load_addr;                                                                                  \
6438 +                                                                                                                                               \
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;                                            \
6444 +                                                                                                                                               \
6445 +       while (i--) {                                                                                                           \
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;                                                                              \
6455 +               }                                                                                                                               \
6456 +               else                                                                                                                    \
6457 +                       *got = load_addr + sym->st_value;                                                       \
6458 +                                                                                                                                               \
6459 +               got++;                                                                                                                  \
6460 +               sym++;                                                                                                                  \
6461 +       }                                                                                                                                       \
6462 +} while (0)
6463 +
6464 +
6465 +/*
6466 + * Here is a macro to perform a relocation.  This is only used when
6467 + * bootstrapping the dynamic loader.
6468 + */
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)                                           \
6474 +                               *REL += SYMBOL;                                                                                 \
6475 +               }                                                                                                                               \
6476 +               else {                                                                                                                  \
6477 +                       *REL += LOAD;                                                                                           \
6478 +               }                                                                                                                               \
6479 +               break;                                                                                                                  \
6480 +       case R_MIPS_NONE:                                                                                                       \
6481 +               break;                                                                                                                  \
6482 +       default:                                                                                                                        \
6483 +               SEND_STDERR("Aiieeee!");                                                                                \
6484 +               _dl_exit(1);                                                                                                    \
6485 +       }
6486 +
6487 +
6488 +/*
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
6493 + * at boot1_arch.h
6494 + */
6495 +#define START()
6496 +
6497 +
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
6501 +
6502 +
6503 +/* Used for error messages */
6504 +#define ELF_TARGET "MIPS"
6505 +
6506 +
6507 +unsigned long _dl_linux_resolver(unsigned long sym_index,
6508 +       unsigned long old_gpreg);
6509 +
6510 +
6511 +#define do_rem(result, n, base)  result = (n % base)
6512 +
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
6520 @@ -0,0 +1,45 @@
6521 +       /*
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.
6525 + *
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.
6529 + *
6530 + * Copyright (C) 1996-2001 Kazumoto Kojima <kkojima@info.kanagawa-u.ac.jp>
6531 + * Copyright (C) 2002 Steven J. Hill <sjhill@realitydiluted.com>
6532 + *
6533 + */
6534 +.text
6535 +.align 2
6536 +.globl _dl_linux_resolve
6537 +.type  _dl_linux_resolve,@function
6538 +.ent   _dl_linux_resolve
6539 +_dl_linux_resolve:
6540 +       .frame  $29, 40, $31
6541 +       .set noreorder
6542 +       move    $3, $28         # Save GP
6543 +       addu    $25, 8          # t9 ($25) now points at .cpload instruction
6544 +       .cpload $25             # Compute GP
6545 +       .set reorder
6546 +       subu    $29, 40
6547 +       .cprestore 32
6548 +       sw      $15, 36($29)
6549 +       sw      $4, 16($29)
6550 +       sw      $5, 20($29)
6551 +       sw      $6, 24($29)
6552 +       sw      $7, 28($29)
6553 +       move    $4, $24
6554 +       move    $5, $3
6555 +       jal     _dl_linux_resolver
6556 +       lw      $31, 36($29)
6557 +       lw      $4, 16($29)
6558 +       lw      $5, 20($29)
6559 +       lw      $6, 24($29)
6560 +       lw      $7, 28($29)
6561 +       addu    $29, 40
6562 +       move    $25, $2
6563 +       jr      $25
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
6569 @@ -0,0 +1,20 @@
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.  */
6573 +
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. */
6576 +
6577 +asm("" \
6578 +"      .text\n"                        \
6579 +"      .globl  _dl_boot\n"             \
6580 +"_dl_boot:\n"                          \
6581 +"      mr      3,1\n"                  \
6582 +"      addi    1,1,-16\n"              \
6583 +"      bl      _dl_boot2\n"            \
6584 +".previous\n"                          \
6585 +);
6586 +
6587 +#define _dl_boot _dl_boot2
6588 +#define LD_BOOT(X)   static void *  __attribute__ ((unused)) _dl_boot (X)
6589 +
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
6593 @@ -0,0 +1,621 @@
6594 +/* vi: set sw=4 ts=4: */
6595 +/* powerpc shared library loader suppport
6596 + *
6597 + * Copyright (C) 2001-2002,  David A. Schleef
6598 + * Copyright (C) 2003, Erik Andersen
6599 + *
6600 + * All rights reserved.
6601 + *
6602 + * Redistribution and use in source and binary forms, with or without
6603 + * modification, are permitted provided that the following conditions
6604 + * are met:
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.
6610 + *
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
6621 + * SUCH DAMAGE.
6622 + */
6623 +
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",
6637 +};
6638 +
6639 +static const char *
6640 +_dl_reltypes(int type)
6641 +{
6642 +  static char buf[22];  
6643 +  const char *str;
6644 +  
6645 +  if (type >= (int)(sizeof (_dl_reltypes_tab)/sizeof(_dl_reltypes_tab[0])) ||
6646 +      NULL == (str = _dl_reltypes_tab[type]))
6647 +  {
6648 +    str =_dl_simple_ltoa( buf, (unsigned long)(type));
6649 +  }
6650 +  return str;
6651 +}
6652 +
6653 +static 
6654 +void debug_sym(Elf32_Sym *symtab,char *strtab,int symtab_index)
6655 +{
6656 +  if(_dl_debug_symbols)
6657 +  {
6658 +    if(symtab_index){
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);
6666 +    }
6667 +  }
6668 +}
6669 +
6670 +static 
6671 +void debug_reloc(Elf32_Sym *symtab,char *strtab, ELF_RELOC *rpnt)
6672 +{
6673 +  if(_dl_debug_reloc)
6674 +  {
6675 +    int symtab_index;
6676 +    const char *sym;
6677 +    symtab_index = ELF32_R_SYM(rpnt->r_info);
6678 +    sym = symtab_index ? strtab + symtab[symtab_index].st_name : "sym=0x0";
6679 +    
6680 +  if(_dl_debug_symbols)
6681 +         _dl_dprintf(_dl_debug_file, "\n\t");
6682 +  else
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)),
6687 +               rpnt->r_offset,
6688 +               rpnt->r_addend);
6689 +#else
6690 +    _dl_dprintf(_dl_debug_file, "%s\toffset=%x\n",
6691 +               _dl_reltypes(ELF32_R_TYPE(rpnt->r_info)),
6692 +               rpnt->r_offset);
6693 +#endif
6694 +  }
6695 +}
6696 +#endif
6697 +
6698 +extern int _dl_linux_resolve(void);
6699 +
6700 +void _dl_init_got(unsigned long *plt,struct elf_resolve *tpnt)
6701 +{
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;
6707 +
6708 +       //DPRINTF("init_got plt=%x, tpnt=%x\n", (unsigned long)plt,(unsigned long)tpnt);
6709 +
6710 +       n_plt_entries = tpnt->dynamic_info[DT_PLTRELSZ] / sizeof(ELF_RELOC);
6711 +       //DPRINTF("n_plt_entries %d\n",n_plt_entries);
6712 +
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);
6717 +
6718 +       tpnt->data_words = data_words;
6719 +
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);
6722 +
6723 +       plt[PLT_LONGBRANCH_ENTRY_WORDS+2] = OPCODE_MTCTR(11);
6724 +       plt[PLT_LONGBRANCH_ENTRY_WORDS+3] = OPCODE_BCTR();
6725 +
6726 +       /* [4] */
6727 +       /* [5] */
6728 +
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();
6740 +
6741 +       /* [16] unused */
6742 +       /* [17] unused */
6743 +
6744 +       /* instructions were modified */
6745 +       PPC_DCBST(plt);
6746 +       PPC_DCBST(plt+4);
6747 +       PPC_DCBST(plt+8);
6748 +       PPC_DCBST(plt+12);
6749 +       PPC_DCBST(plt+16-1);
6750 +       PPC_SYNC;
6751 +       PPC_ICBI(plt);
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);
6756 +       PPC_ISYNC;
6757 +}
6758 +
6759 +unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
6760 +{
6761 +       int reloc_type;
6762 +       ELF_RELOC *this_reloc;
6763 +       char *strtab;
6764 +       Elf32_Sym *symtab;
6765 +       ELF_RELOC *rel_addr;
6766 +       int symtab_index;
6767 +       char *symname;
6768 +       unsigned long insn_addr;
6769 +       unsigned long *insns;
6770 +       unsigned long new_addr;
6771 +       unsigned long delta;
6772 +
6773 +       rel_addr = (ELF_RELOC *) (tpnt->dynamic_info[DT_JMPREL] + tpnt->loadaddr);
6774 +
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);
6778 +
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;
6782 +
6783 +#if defined (__SUPPORT_LD_DEBUG__)
6784 +       debug_sym(symtab,strtab,symtab_index);
6785 +       debug_reloc(symtab,strtab,this_reloc);
6786 +#endif
6787 +
6788 +       if (reloc_type != R_PPC_JMP_SLOT) {
6789 +               _dl_dprintf(2, "%s: Incorrect relocation type in jump relocation\n", _dl_progname);
6790 +               _dl_exit(1);
6791 +       };
6792 +
6793 +       /* Address of dump instruction to fix up */
6794 +       insn_addr = (unsigned long) tpnt->loadaddr +
6795 +               (unsigned long) this_reloc->r_offset;
6796 +
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);
6800 +#endif
6801 +
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);
6806 +       if (!new_addr) {
6807 +               _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", 
6808 +                       _dl_progname, symname);
6809 +               _dl_exit(1);
6810 +       };
6811 +
6812 +#if defined (__SUPPORT_LD_DEBUG__)
6813 +       if(_dl_debug_reloc && _dl_debug_detail)
6814 +               _dl_dprintf(_dl_debug_file, "%x\n", new_addr);
6815 +#endif
6816 +
6817 +       insns = (unsigned long *)insn_addr;
6818 +       delta = new_addr - insn_addr;
6819 +
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);
6824 +       }else{
6825 +               /* Warning: we don't handle double-sized PLT entries */
6826 +               unsigned long plt_addr;
6827 +               unsigned long *ptr;
6828 +               int index;
6829 +
6830 +               plt_addr = (unsigned long)tpnt->dynamic_info[DT_PLTGOT] + 
6831 +                       (unsigned long)tpnt->loadaddr;
6832 +
6833 +               delta = PLT_LONGBRANCH_ENTRY_WORDS*4 - (insn_addr-plt_addr+4);
6834 +
6835 +               index = (insn_addr - plt_addr - PLT_INITIAL_ENTRY_WORDS*4)/8;
6836 +
6837 +               ptr = (unsigned long *)tpnt->data_words;
6838 +               //DPRINTF("plt_addr=%x delta=%x index=%x ptr=%x\n", plt_addr, delta, index, ptr);
6839 +               insns += 1;
6840 +
6841 +               ptr[index] = new_addr;
6842 +               PPC_SYNC;
6843 +               /* icache sync is not necessary, since this will be a data load */
6844 +               //PPC_DCBST(ptr+index);
6845 +               //PPC_SYNC;
6846 +               //PPC_ICBI(ptr+index);
6847 +               //PPC_ISYNC;
6848 +
6849 +               insns[0] = OPCODE_B(delta);
6850 +
6851 +       }
6852 +
6853 +       /* instructions were modified */
6854 +       PPC_DCBST(insns);
6855 +       PPC_SYNC;
6856 +       PPC_ICBI(insns);
6857 +       PPC_ISYNC;
6858 +
6859 +       return new_addr;
6860 +}
6861 +
6862 +static int
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))
6867 +{
6868 +       unsigned int i;
6869 +       char *strtab;
6870 +       Elf32_Sym *symtab;
6871 +       ELF_RELOC *rpnt;
6872 +       int symtab_index;
6873 +
6874 +       /* Now parse the relocation information */
6875 +       rpnt = (ELF_RELOC *)(intptr_t) (rel_addr + tpnt->loadaddr);
6876 +       rel_size = rel_size / sizeof(ELF_RELOC);
6877 +
6878 +       symtab = (Elf32_Sym *)(intptr_t) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
6879 +       strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
6880 +
6881 +         for (i = 0; i < rel_size; i++, rpnt++) {
6882 +               int res;
6883 +           
6884 +               symtab_index = ELF32_R_SYM(rpnt->r_info);
6885 +               
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)
6889 +                       continue;
6890 +               if (symtab_index && tpnt->libtype == program_interpreter &&
6891 +                   _dl_symbol(strtab + symtab[symtab_index].st_name))
6892 +                       continue;
6893 +
6894 +#if defined (__SUPPORT_LD_DEBUG__)
6895 +               debug_sym(symtab,strtab,symtab_index);
6896 +               debug_reloc(symtab,strtab,rpnt);
6897 +#endif
6898 +
6899 +               res = reloc_fnc (tpnt, scope, rpnt, symtab, strtab);
6900 +
6901 +               if (res==0) continue;
6902 +
6903 +               _dl_dprintf(2, "\n%s: ",_dl_progname);
6904 +               
6905 +               if (symtab_index)
6906 +                 _dl_dprintf(2, "symbol '%s': ", strtab + symtab[symtab_index].st_name);
6907 +                 
6908 +               if (res <0)
6909 +               {
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));
6913 +#else
6914 +                       _dl_dprintf(2, "can't handle reloc type %x\n", reloc_type);
6915 +#endif                 
6916 +                       _dl_exit(-res);
6917 +               }
6918 +               else if (res >0)
6919 +               {
6920 +                       _dl_dprintf(2, "can't resolve symbol\n");
6921 +                       return res;
6922 +               }
6923 +         }
6924 +         return 0;
6925 +}
6926 +
6927 +static int
6928 +_dl_do_lazy_reloc (struct elf_resolve *tpnt, struct dyn_elf *scope,
6929 +                  ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)
6930 +{
6931 +       int reloc_type;
6932 +       unsigned long reloc_addr;
6933 +#if defined (__SUPPORT_LD_DEBUG__)
6934 +       unsigned long old_val;
6935 +#endif
6936 +       (void)scope;
6937 +       (void)symtab;
6938 +       (void)strtab;
6939 +
6940 +       reloc_addr = (unsigned long)tpnt->loadaddr + (unsigned long) rpnt->r_offset;
6941 +       reloc_type = ELF32_R_TYPE(rpnt->r_info);
6942 +
6943 +#if defined (__SUPPORT_LD_DEBUG__)
6944 +       old_val = reloc_addr;
6945 +#endif
6946 +
6947 +       switch (reloc_type) {
6948 +               case R_PPC_NONE:
6949 +                       return 0;
6950 +                       break;
6951 +               case R_PPC_JMP_SLOT:
6952 +                       {
6953 +                               int index;
6954 +                               unsigned long delta;
6955 +                               unsigned long *plt;
6956 +                               unsigned long *insns;
6957 +
6958 +                               plt = (unsigned long *)(tpnt->dynamic_info[DT_PLTGOT] + tpnt->loadaddr);
6959 +
6960 +                               delta = (unsigned long)(plt+PLT_TRAMPOLINE_ENTRY_WORDS+2) - (reloc_addr+4);
6961 +
6962 +                               index = (reloc_addr - (unsigned long)(plt+PLT_INITIAL_ENTRY_WORDS)) 
6963 +                                               /sizeof(unsigned long);
6964 +                               index /= 2;
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);
6969 +                               break;
6970 +                       }
6971 +               default:
6972 +#if 0
6973 +                       _dl_dprintf(2, "%s: (LAZY) can't handle reloc type ", 
6974 +                                       _dl_progname);
6975 +#if defined (__SUPPORT_LD_DEBUG__)
6976 +                       _dl_dprintf(2, "%s ", _dl_reltypes[reloc_type]);
6977 +#endif
6978 +                       if (symtab_index)
6979 +                               _dl_dprintf(2, "'%s'\n", strtab + symtab[symtab_index].st_name);
6980 +#endif
6981 +                       //_dl_exit(1);
6982 +                       return -1;
6983 +       };
6984 +
6985 +       /* instructions were modified */
6986 +       PPC_DCBST(reloc_addr);
6987 +       PPC_DCBST(reloc_addr+4);
6988 +       PPC_SYNC;
6989 +       PPC_ICBI(reloc_addr);
6990 +       PPC_ICBI(reloc_addr+4);
6991 +       PPC_ISYNC;
6992 +
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);
6996 +#endif
6997 +       return 0;
6998 +
6999 +}
7000 +
7001 +static int
7002 +_dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope,
7003 +             ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)
7004 +{
7005 +       int reloc_type;
7006 +       int symtab_index;
7007 +       char *symname;
7008 +       unsigned long *reloc_addr;
7009 +       unsigned long symbol_addr;
7010 +#if defined (__SUPPORT_LD_DEBUG__)
7011 +       unsigned long old_val;
7012 +#endif
7013 +
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);
7017 +       symbol_addr  = 0;
7018 +       symname      = strtab + symtab[symtab_index].st_name;
7019 +
7020 +       if (symtab_index) {
7021 +
7022 +               symbol_addr = (unsigned long) _dl_find_hash(symname, scope, 
7023 +                               (reloc_type == R_PPC_JMP_SLOT ? tpnt : NULL), symbolrel);
7024 +
7025 +               /*
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.
7029 +                */
7030 +
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);
7035 +#endif
7036 +                       return 0;
7037 +               }
7038 +       }
7039 +
7040 +#if defined (__SUPPORT_LD_DEBUG__)
7041 +       old_val = *reloc_addr;
7042 +#endif
7043 +               switch (reloc_type) {
7044 +                       case R_PPC_NONE:
7045 +                               return 0;
7046 +                               break;
7047 +                       case R_PPC_REL24:
7048 +#if 0
7049 +                               {
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");
7053 +                                               _dl_exit(1);
7054 +                                       }
7055 +                                       *reloc_addr &= 0xfc000003;
7056 +                                       *reloc_addr |= delta&0x03fffffc;
7057 +                               }
7058 +                               break;
7059 +#else
7060 +                               _dl_dprintf(2, "%s: symbol '%s' is type R_PPC_REL24\n\tCompile shared libraries with -fPIC!\n",
7061 +                                               _dl_progname, symname);
7062 +                               _dl_exit(1);
7063 +#endif
7064 +                       case R_PPC_RELATIVE:
7065 +                               *reloc_addr = (unsigned long)tpnt->loadaddr + (unsigned long)rpnt->r_addend;
7066 +                               break;
7067 +                       case R_PPC_ADDR32:
7068 +                               *reloc_addr += symbol_addr;
7069 +                               break;
7070 +                       case R_PPC_ADDR16_HA:
7071 +                               /* XXX is this correct? */
7072 +                               *(short *)reloc_addr += (symbol_addr+0x8000)>>16;
7073 +                               break;
7074 +                       case R_PPC_ADDR16_HI:
7075 +                               *(short *)reloc_addr += symbol_addr>>16;
7076 +                               break;
7077 +                       case R_PPC_ADDR16_LO:
7078 +                               *(short *)reloc_addr += symbol_addr;
7079 +                               break;
7080 +                       case R_PPC_JMP_SLOT:
7081 +                               {
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);
7088 +                                       }else{
7089 +                                               {
7090 +                                                       int index;
7091 +                                                       unsigned long delta2;
7092 +                                                       unsigned long *plt, *ptr;
7093 +                                                       plt = (unsigned long *)(tpnt->dynamic_info[DT_PLTGOT] + tpnt->loadaddr);
7094 +
7095 +                                                       delta2 = (unsigned long)(plt+PLT_LONGBRANCH_ENTRY_WORDS)
7096 +                                                               - (unsigned long)(reloc_addr+1);
7097 +
7098 +                                                       index = ((unsigned long)reloc_addr -
7099 +                                                                       (unsigned long)(plt+PLT_INITIAL_ENTRY_WORDS))
7100 +                                                               /sizeof(unsigned long);
7101 +                                                       index /= 2;
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);
7107 +
7108 +                                                       /* instructions were modified */
7109 +                                                       PPC_DCBST(reloc_addr+1);
7110 +                                                       PPC_SYNC;
7111 +                                                       PPC_ICBI(reloc_addr+1);
7112 +                                               }
7113 +                                       }
7114 +                                       break;
7115 +                               }
7116 +                       case R_PPC_GLOB_DAT:
7117 +                               *reloc_addr += symbol_addr;
7118 +                               break;
7119 +                       case R_PPC_COPY:
7120 +                               // handled later
7121 +                               return 0;
7122 +                               break;
7123 +                       default:
7124 +#if 0
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]);
7128 +#endif
7129 +                               if (symtab_index)
7130 +                                       _dl_dprintf(2, "'%s'\n", strtab + symtab[symtab_index].st_name);
7131 +#endif
7132 +                               //_dl_exit(1);
7133 +                               return -1;
7134 +               };
7135 +
7136 +               /* instructions were modified */
7137 +               PPC_DCBST(reloc_addr);
7138 +               PPC_SYNC;
7139 +               PPC_ICBI(reloc_addr);
7140 +               PPC_ISYNC;
7141 +
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);
7145 +#endif
7146 +
7147 +       return 0;
7148 +}
7149 +
7150 +
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. */
7156 +static int
7157 +_dl_do_copy (struct elf_resolve *tpnt, struct dyn_elf *scope,
7158 +            ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)
7159 +{
7160 +       int reloc_type;
7161 +       int symtab_index;
7162 +       unsigned long *reloc_addr;
7163 +       unsigned long symbol_addr;
7164 +       int goof = 0;
7165 +       char *symname;
7166 +         
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) 
7170 +               return 0;
7171 +       symtab_index = ELF32_R_SYM(rpnt->r_info);
7172 +       symbol_addr = 0;
7173 +       symname      = strtab + symtab[symtab_index].st_name;
7174 +               
7175 +       if (symtab_index) {
7176 +               symbol_addr = (unsigned long) _dl_find_hash(symname, scope, NULL, copyrel);
7177 +               if (!symbol_addr) goof++;
7178 +       }
7179 +       if (!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);
7185 +#endif
7186 +                       _dl_memcpy((char *) reloc_addr,
7187 +                                       (char *) symbol_addr, symtab[symtab_index].st_size);
7188 +       }
7189 +
7190 +       return goof;
7191 +}
7192 +
7193 +void _dl_parse_lazy_relocation_information(struct elf_resolve *tpnt, 
7194 +       unsigned long rel_addr, unsigned long rel_size, int type)
7195 +{
7196 +       (void) type;
7197 +       (void)_dl_parse(tpnt, NULL, rel_addr, rel_size, _dl_do_lazy_reloc);
7198 +}
7199 +
7200 +int _dl_parse_relocation_information(struct elf_resolve *tpnt, 
7201 +       unsigned long rel_addr, unsigned long rel_size, int type)
7202 +{
7203 +       (void) type;
7204 +       return _dl_parse(tpnt, tpnt->symbol_scope, rel_addr, rel_size, _dl_do_reloc);
7205 +}
7206 +
7207 +int _dl_parse_copy_information(struct dyn_elf *xpnt, unsigned long rel_addr, 
7208 +       unsigned long rel_size, int type)
7209 +{
7210 +       (void) type;
7211 +       return _dl_parse(xpnt->dyn, xpnt->next, rel_addr, rel_size, _dl_do_copy);
7212 +}
7213 +
7214 +
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
7218 @@ -0,0 +1,244 @@
7219 +/*
7220 + * This file contains the system call macros and syscall 
7221 + * numbers used by the shared library loader.
7222 + */
7223 +
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
7239 +
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 
7244 + * linked. */
7245 +
7246 +#undef __syscall_return
7247 +#define __syscall_return(type) \
7248 +       return (__sc_err & 0x10000000 ? /*errno = __sc_ret,*/ __sc_ret = -1 : 0), \
7249 +              (type) __sc_ret
7250 +
7251 +#undef __syscall_clobbers
7252 +#define __syscall_clobbers \
7253 +       "r9", "r10", "r11", "r12"
7254 +       //"r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"
7255 +
7256 +#undef _syscall0
7257 +#define _syscall0(type,name)                                           \
7258 +type name(void)                                                                \
7259 +{                                                                      \
7260 +       unsigned long __sc_ret, __sc_err;                               \
7261 +       {                                                               \
7262 +               register unsigned long __sc_0 __asm__ ("r0");           \
7263 +               register unsigned long __sc_3 __asm__ ("r3");           \
7264 +                                                                       \
7265 +               __sc_0 = __NR_##name;                                   \
7266 +               __asm__ __volatile__                                    \
7267 +                       ("sc           \n\t"                            \
7268 +                        "mfcr %1      "                                \
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;                                      \
7274 +       }                                                               \
7275 +       __syscall_return (type);                                        \
7276 +}
7277 +
7278 +#undef _syscall1
7279 +#define _syscall1(type,name,type1,arg1)                                        \
7280 +type name(type1 arg1)                                                  \
7281 +{                                                                      \
7282 +       unsigned long __sc_ret, __sc_err;                               \
7283 +       {                                                               \
7284 +               register unsigned long __sc_0 __asm__ ("r0");           \
7285 +               register unsigned long __sc_3 __asm__ ("r3");           \
7286 +                                                                       \
7287 +               __sc_3 = (unsigned long) (arg1);                        \
7288 +               __sc_0 = __NR_##name;                                   \
7289 +               __asm__ __volatile__                                    \
7290 +                       ("sc           \n\t"                            \
7291 +                        "mfcr %1      "                                \
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;                                      \
7297 +       }                                                               \
7298 +       __syscall_return (type);                                        \
7299 +}
7300 +
7301 +#undef _syscall2
7302 +#define _syscall2(type,name,type1,arg1,type2,arg2)                     \
7303 +type name(type1 arg1, type2 arg2)                                      \
7304 +{                                                                      \
7305 +       unsigned long __sc_ret, __sc_err;                               \
7306 +       {                                                               \
7307 +               register unsigned long __sc_0 __asm__ ("r0");           \
7308 +               register unsigned long __sc_3 __asm__ ("r3");           \
7309 +               register unsigned long __sc_4 __asm__ ("r4");           \
7310 +                                                                       \
7311 +               __sc_3 = (unsigned long) (arg1);                        \
7312 +               __sc_4 = (unsigned long) (arg2);                        \
7313 +               __sc_0 = __NR_##name;                                   \
7314 +               __asm__ __volatile__                                    \
7315 +                       ("sc           \n\t"                            \
7316 +                        "mfcr %1      "                                \
7317 +                       : "=&r" (__sc_3), "=&r" (__sc_0)                \
7318 +                       : "0"   (__sc_3), "1"   (__sc_0),               \
7319 +                         "r"   (__sc_4)                                \
7320 +                       : "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12" ); \
7321 +               __sc_ret = __sc_3;                                      \
7322 +               __sc_err = __sc_0;                                      \
7323 +       }                                                               \
7324 +       __syscall_return (type);                                        \
7325 +}
7326 +
7327 +#undef _syscall3
7328 +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)          \
7329 +type name(type1 arg1, type2 arg2, type3 arg3)                          \
7330 +{                                                                      \
7331 +       unsigned long __sc_ret, __sc_err;                               \
7332 +       {                                                               \
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");           \
7337 +                                                                       \
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__                                    \
7343 +                       ("sc           \n\t"                            \
7344 +                        "mfcr %1      "                                \
7345 +                       : "=&r" (__sc_3), "=&r" (__sc_0)                \
7346 +                       : "0"   (__sc_3), "1"   (__sc_0),               \
7347 +                         "r"   (__sc_4),                               \
7348 +                         "r"   (__sc_5)                                \
7349 +                       : "r6", "r7", "r8", "r9", "r10", "r11", "r12" ); \
7350 +               __sc_ret = __sc_3;                                      \
7351 +               __sc_err = __sc_0;                                      \
7352 +       }                                                               \
7353 +       __syscall_return (type);                                        \
7354 +}
7355 +
7356 +#undef _syscall4
7357 +#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
7358 +type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4)              \
7359 +{                                                                      \
7360 +       unsigned long __sc_ret, __sc_err;                               \
7361 +       {                                                               \
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");           \
7367 +                                                                       \
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__                                    \
7374 +                       ("sc           \n\t"                            \
7375 +                        "mfcr %1      "                                \
7376 +                       : "=&r" (__sc_3), "=&r" (__sc_0)                \
7377 +                       : "0"   (__sc_3), "1"   (__sc_0),               \
7378 +                         "r"   (__sc_4),                               \
7379 +                         "r"   (__sc_5),                               \
7380 +                         "r"   (__sc_6)                                \
7381 +                       : "r7", "r8", "r9", "r10", "r11", "r12" );      \
7382 +               __sc_ret = __sc_3;                                      \
7383 +               __sc_err = __sc_0;                                      \
7384 +       }                                                               \
7385 +       __syscall_return (type);                                        \
7386 +}
7387 +
7388 +#undef _syscall5
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)  \
7391 +{                                                                      \
7392 +       unsigned long __sc_ret, __sc_err;                               \
7393 +       {                                                               \
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");           \
7400 +                                                                       \
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__                                    \
7408 +                       ("sc           \n\t"                            \
7409 +                        "mfcr %1      "                                \
7410 +                       : "=&r" (__sc_3), "=&r" (__sc_0)                \
7411 +                       : "0"   (__sc_3), "1"   (__sc_0),               \
7412 +                         "r"   (__sc_4),                               \
7413 +                         "r"   (__sc_5),                               \
7414 +                         "r"   (__sc_6),                               \
7415 +                         "r"   (__sc_7)                                \
7416 +                       : "r8", "r9", "r10", "r11", "r12" );            \
7417 +               __sc_ret = __sc_3;                                      \
7418 +               __sc_err = __sc_0;                                      \
7419 +       }                                                               \
7420 +       __syscall_return (type);                                        \
7421 +}
7422 +
7423 +
7424 +#undef _syscall6
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)      \
7427 +{                                                                      \
7428 +       unsigned long __sc_ret, __sc_err;                               \
7429 +       {                                                               \
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");           \
7437 +                                                                       \
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__                                    \
7446 +                       ("sc           \n\t"                            \
7447 +                        "mfcr %1      "                                \
7448 +                       : "=&r" (__sc_3), "=&r" (__sc_0)                \
7449 +                       : "0"   (__sc_3), "1"   (__sc_0),               \
7450 +                         "r"   (__sc_4),                               \
7451 +                         "r"   (__sc_5),                               \
7452 +                         "r"   (__sc_6),                               \
7453 +                         "r"   (__sc_7),                               \
7454 +                         "r"   (__sc_8)                                \
7455 +                       : "r9", "r10", "r11", "r12" );                  \
7456 +               __sc_ret = __sc_3;                                      \
7457 +               __sc_err = __sc_0;                                      \
7458 +       }                                                               \
7459 +       __syscall_return (type);                                        \
7460 +}
7461 +
7462 +
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
7466 @@ -0,0 +1,136 @@
7467 +/*
7468 + * Various assmbly language/system dependent  hacks that are required
7469 + * so that we can minimize the amount of platform specific code.
7470 + */
7471 +
7472 +/*
7473 + * Define this if the system uses RELOCA.
7474 + */
7475 +#define ELF_USES_RELOCA
7476 +
7477 +/*
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.
7481 + */
7482 +#define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long*) ARGS)+1)
7483 +
7484 +/*
7485 + * Initialization sequence for a GOT.
7486 + */
7487 +#define INIT_GOT(GOT_BASE,MODULE)  _dl_init_got(GOT_BASE,MODULE)
7488 +
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                           \
7498 +      : 0))
7499 +#define PLT_DATA_START_WORDS(num_entries) PLT_ENTRY_START_WORDS(num_entries)
7500 +
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)
7518 +
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)
7524 +
7525 +
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")
7531 +
7532 +/*
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
7537 + * load address.
7538 + */
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);                 \
7555 +       }else{                                          \
7556 +         _dl_exit(100+ELF32_R_TYPE((RELP)->r_info));   \
7557 +       }                                               \
7558 +       if(type!=R_PPC_NONE){                           \
7559 +               PPC_DCBST(REL); PPC_SYNC; PPC_ICBI(REL);\
7560 +       }                                               \
7561 +       }
7562 +
7563 +/*
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.
7567 + */
7568 +
7569 +/* hgb@ifi.uio.no:
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.
7575 + */
7576 +#define START()                \
7577 +       __asm__ volatile ( \
7578 +                   "addi 1,%1,0\n\t" \
7579 +                   "mtlr %0\n\t" \
7580 +                   "blrl\n\t"  \
7581 +                   : : "r" (_dl_elf_main), "r" (args) \
7582 +                   : "r0")
7583 +
7584 +
7585 +/* Here we define the magic numbers that this dynamic loader should accept */
7586 +
7587 +#define MAGIC1 EM_PPC
7588 +#undef  MAGIC2
7589 +/* Used for error messages */
7590 +#define ELF_TARGET "powerpc"
7591 +
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);
7595 +
7596 +
7597 +#define do_rem(result, n, base)  result = (n % base)
7598 +
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
7606 @@ -0,0 +1,82 @@
7607 +/*
7608 + * Stolen from glibc-2.2.2 by David Schleef <ds@schleef.org>
7609 + */
7610 +
7611 +.text
7612 +.align 4
7613 +
7614 +.globl _dl_linux_resolver
7615 +
7616 +.globl _dl_linux_resolve
7617 +.type  _dl_linux_resolve,@function
7618 +
7619 +_dl_linux_resolve:
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.
7622 +       stwu 1,-64(1)
7623 +       stw 0,12(1)
7624 +       stw 3,16(1)
7625 +       stw 4,20(1)
7626 +// The code that calls this has put parameters for 'fixup' in r12 and r11.
7627 +       mr 3,12
7628 +       stw 5,24(1)
7629 +       mr 4,11
7630 +       stw 6,28(1)
7631 +       mflr 0
7632 +// We also need to save some of the condition register fields.
7633 +       stw 7,32(1)
7634 +       stw 0,48(1)
7635 +       stw 8,36(1)
7636 +       mfcr 0
7637 +       stw 9,40(1)
7638 +       stw 10,44(1)
7639 +       stw 0,8(1)
7640 +       bl _dl_linux_resolver@local
7641 +// 'fixup' returns the address we want to branch to.
7642 +       mtctr 3
7643 +// Put the registers back...
7644 +       lwz 0,48(1)
7645 +       lwz 10,44(1)
7646 +       lwz 9,40(1)
7647 +       mtlr 0
7648 +       lwz 8,36(1)
7649 +       lwz 0,8(1)
7650 +       lwz 7,32(1)
7651 +       lwz 6,28(1)
7652 +       mtcrf 0xFF,0
7653 +       lwz 5,24(1)
7654 +       lwz 4,20(1)
7655 +       lwz 3,16(1)
7656 +       lwz 0,12(1)
7657 +// ...unwind the stack frame, and jump to the PLT entry we updated.
7658 +       addi 1,1,64
7659 +       bctr
7660 +
7661 +.LFE2:
7662 +       .size _dl_linux_resolve,.LFE2-_dl_linux_resolve
7663 +
7664 +#if 0
7665 +
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 */
7670 +                                        
7671 +#ifdef __PIC__
7672 +       call    .L24
7673 +.L24:
7674 +       popl    %ebx
7675 +       addl    $_GLOBAL_OFFSET_TABLE_+[.-.L24],%ebx
7676 +       movl _dl_linux_resolver@GOT(%ebx),%ebx  /* eax = resolved func */
7677 +       call *%ebx
7678 +#else
7679 +       call _dl_linux_resolver
7680 +#endif
7681 +       movl    %eax,0x28(%esp)         /* store func addr over original
7682 +                                        * tpnt param */
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 */
7687 +#endif
7688 +
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
7692 @@ -0,0 +1,971 @@
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
7696 + *
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
7700 + *
7701 + * All rights reserved.
7702 + *
7703 + * Redistribution and use in source and binary forms, with or without
7704 + * modification, are permitted provided that the following conditions
7705 + * are met:
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.
7711 + *
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
7722 + * SUCH DAMAGE.
7723 + */
7724 +
7725 +
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. */
7728 +
7729 +#ifdef USE_CACHE
7730 +
7731 +static caddr_t _dl_cache_addr = NULL;
7732 +static size_t _dl_cache_size = 0;
7733 +
7734 +int _dl_map_cache(void)
7735 +{
7736 +       int fd;
7737 +       struct stat st;
7738 +       header_t *header;
7739 +       libentry_t *libent;
7740 +       int i, strtabsize;
7741 +
7742 +       if (_dl_cache_addr == (caddr_t) - 1)
7743 +               return -1;
7744 +       else if (_dl_cache_addr != NULL)
7745 +               return 0;
7746 +
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 */
7751 +               return -1;
7752 +       }
7753 +
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);
7756 +       _dl_close(fd);
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);
7760 +               return -1;
7761 +       }
7762 +
7763 +       header = (header_t *) _dl_cache_addr;
7764 +
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') 
7771 +       {
7772 +               _dl_dprintf(2, "%s: cache '%s' is corrupt\n", _dl_progname, 
7773 +                       LDSO_CACHE);
7774 +               goto fail;
7775 +       }
7776 +
7777 +       strtabsize = _dl_cache_size - sizeof(header_t) -
7778 +               header->nlibs * sizeof(libentry_t);
7779 +       libent = (libentry_t *) & header[1];
7780 +
7781 +       for (i = 0; i < header->nlibs; i++) {
7782 +               if (libent[i].sooffset >= strtabsize || 
7783 +                       libent[i].liboffset >= strtabsize) 
7784 +               {
7785 +                       _dl_dprintf(2, "%s: cache '%s' is corrupt\n", _dl_progname, LDSO_CACHE);
7786 +                       goto fail;
7787 +               }
7788 +       }
7789 +
7790 +       return 0;
7791 +
7792 +  fail:
7793 +       _dl_munmap(_dl_cache_addr, _dl_cache_size);
7794 +       _dl_cache_addr = (caddr_t) - 1;
7795 +       return -1;
7796 +}
7797 +
7798 +int _dl_unmap_cache(void)
7799 +{
7800 +       if (_dl_cache_addr == NULL || _dl_cache_addr == (caddr_t) - 1)
7801 +               return -1;
7802 +
7803 +#if 1
7804 +       _dl_munmap(_dl_cache_addr, _dl_cache_size);
7805 +       _dl_cache_addr = NULL;
7806 +#endif
7807 +
7808 +       return 0;
7809 +}
7810 +
7811 +#endif
7812 +
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)
7818 +{
7819 +       int i, count = 1;
7820 +       char *path, *path_n;
7821 +       char mylibname[2050];
7822 +       struct elf_resolve *tpnt1;
7823 +       
7824 +       if (path_list==NULL)
7825 +               return NULL;
7826 +
7827 +       /* We need a writable copy of this string */
7828 +       path = _dl_strdup(path_list);
7829 +       if (!path) {
7830 +               _dl_dprintf(2, "Out of memory!\n");
7831 +               _dl_exit(0);
7832 +       }
7833 +       
7834 +
7835 +       /* Unlike ldd.c, don't bother to eliminate double //s */
7836 +
7837 +
7838 +       /* Replace colons with zeros in path_list and count them */
7839 +       for(i=_dl_strlen(path); i > 0; i--) {
7840 +               if (path[i]==':') {
7841 +                       path[i]=0;
7842 +                       count++;
7843 +               }
7844 +       }
7845 +
7846 +       path_n = path;
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)
7852 +               {
7853 +                       return tpnt1;
7854 +               }
7855 +               path_n += (_dl_strlen(path_n) + 1);
7856 +       }
7857 +       return NULL;
7858 +}
7859 +
7860 +/* Check if the named library is already loaded... */
7861 +struct elf_resolve *_dl_check_if_named_library_is_loaded(const char *full_libname)
7862 +{
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";
7868 +
7869 +       pnt = libname = full_libname;
7870 +
7871 +#if defined (__SUPPORT_LD_DEBUG__)
7872 +       if(_dl_debug) 
7873 +               _dl_dprintf(_dl_debug_file, "Checking if '%s' is already loaded\n", full_libname);
7874 +#endif
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)
7878 +               return NULL;
7879 +
7880 +       /* Skip over any initial initial './' and '/' stuff to 
7881 +        * get the short form libname with no path garbage */ 
7882 +       pnt1 = _dl_strrchr(pnt, '/');
7883 +       if (pnt1) {
7884 +               libname = pnt1 + 1;
7885 +       }
7886 +
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]))
7893 +       {
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);
7898 +                               _dl_exit(1);
7899 +                       }
7900 +                       return NULL;
7901 +               }
7902 +       }
7903 +
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) {
7908 +
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, '/');
7913 +               if (pnt1) {
7914 +                       libname2 = pnt1 + 1;
7915 +               }
7916 +
7917 +               if (_dl_strcmp(libname2, libname) == 0) {
7918 +                       /* Well, that was certainly easy */
7919 +                       return tpnt1;
7920 +               }
7921 +       }
7922 +
7923 +       return NULL;
7924 +}
7925 +       
7926 +
7927 +
7928 +/*
7929 + * Used to return error codes back to dlopen et. al.
7930 + */
7931 +
7932 +unsigned long _dl_error_number;
7933 +unsigned long _dl_internal_error_number;
7934 +extern char *_dl_ldsopath;
7935 +
7936 +struct elf_resolve *_dl_load_shared_library(int secure, struct dyn_elf **rpnt,
7937 +       struct elf_resolve *tpnt, char *full_libname)
7938 +{
7939 +       char *pnt, *pnt1;
7940 +       struct elf_resolve *tpnt1;
7941 +       char *libname;
7942 +
7943 +       _dl_internal_error_number = 0;
7944 +       libname = full_libname;
7945 +
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)
7949 +               goto goof;
7950 +
7951 +       /* Skip over any initial initial './' and '/' stuff to 
7952 +        * get the short form libname with no path garbage */ 
7953 +       pnt1 = _dl_strrchr(libname, '/');
7954 +       if (pnt1) {
7955 +               libname = pnt1 + 1;
7956 +       }
7957 +
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)
7962 +               return tpnt1;
7963 +
7964 +#if defined (__SUPPORT_LD_DEBUG__)
7965 +       if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tfind library='%s'; searching\n", libname);
7966 +#endif
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. */
7970 +
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);
7974 +#endif
7975 +               tpnt1 = _dl_load_elf_shared_library(secure, rpnt, full_libname);
7976 +               if (tpnt1) {
7977 +                       return tpnt1;
7978 +               }
7979 +               //goto goof;
7980 +       }
7981 +
7982 +       /*
7983 +        * The ABI specifies that RPATH is searched before LD_*_PATH or
7984 +        * the default path of /usr/lib.  Check in rpath directories.
7985 +        */
7986 +       for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
7987 +               if (tpnt->libtype == elf_executable) {
7988 +                       pnt = (char *) tpnt->dynamic_info[DT_RPATH];
7989 +                       if (pnt) {
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);
7993 +#endif
7994 +                               if ((tpnt1 = search_for_named_library(libname, secure, pnt, rpnt)) != NULL) 
7995 +                               {
7996 +                                   return tpnt1;
7997 +                               }
7998 +                       }
7999 +               }
8000 +       }
8001 +
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);
8006 +#endif
8007 +           if ((tpnt1 = search_for_named_library(libname, secure, _dl_library_path, rpnt)) != NULL) 
8008 +           {
8009 +               return tpnt1;
8010 +           }
8011 +       }
8012 +
8013 +       /*
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).
8017 +        */
8018 +#ifdef USE_CACHE
8019 +       if (_dl_cache_addr != NULL && _dl_cache_addr != (caddr_t) - 1) {
8020 +               int i;
8021 +               header_t *header = (header_t *) _dl_cache_addr;
8022 +               libentry_t *libent = (libentry_t *) & header[1];
8023 +               char *strs = (char *) &libent[header->nlibs];
8024 +
8025 +#if defined (__SUPPORT_LD_DEBUG__)
8026 +               if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tsearching cache='%s'\n", LDSO_CACHE);
8027 +#endif
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)))
8034 +                               return tpnt1;
8035 +               }
8036 +       }
8037 +#endif
8038 +
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);
8043 +#endif
8044 +       if ((tpnt1 = search_for_named_library(libname, secure, _dl_ldsopath, rpnt)) != NULL) 
8045 +       {
8046 +           return tpnt1;
8047 +       }
8048 +
8049 +
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");
8054 +#endif
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:"
8059 +                       "/usr/lib:"
8060 +                       "/lib", rpnt)
8061 +                   ) != NULL) 
8062 +       {
8063 +           return tpnt1;
8064 +       }
8065 +
8066 +goof:
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;
8070 +       else
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);
8074 +#endif
8075 +       return NULL;
8076 +}
8077 +
8078 +
8079 +/*
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
8082 + * are required.
8083 + */
8084 +
8085 +struct elf_resolve *_dl_load_elf_shared_library(int secure,
8086 +       struct dyn_elf **rpnt, char *libname)
8087 +{
8088 +       ElfW(Ehdr) *epnt;
8089 +       unsigned long dynamic_addr = 0;
8090 +       unsigned long dynamic_size = 0;
8091 +       Elf32_Dyn *dpnt;
8092 +       struct elf_resolve *tpnt;
8093 +       ElfW(Phdr) *ppnt;
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;
8100 +
8101 +       /* If this file is already loaded, skip this step */
8102 +       tpnt = _dl_check_hashed_files(libname);
8103 +       if (tpnt) {
8104 +               if (*rpnt) {
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;
8111 +               }
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);
8116 +#endif
8117 +               return tpnt;
8118 +       }
8119 +
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. */
8122 +
8123 +       if (secure) {
8124 +               struct stat st;
8125 +
8126 +               if (_dl_stat(libname, &st) || !(st.st_mode & S_ISUID))
8127 +                       return NULL;
8128 +       }
8129 +
8130 +       libaddr = 0;
8131 +       infile = _dl_open(libname, O_RDONLY);
8132 +       if (infile < 0) {
8133 +#if 0
8134 +               /*
8135 +                * NO!  When we open shared libraries we may search several paths.
8136 +                * it is inappropriate to generate an error here.
8137 +                */
8138 +               _dl_dprintf(2, "%s: can't open '%s'\n", _dl_progname, libname);
8139 +#endif
8140 +               _dl_internal_error_number = LD_ERROR_NOFILE;
8141 +               return NULL;
8142 +       }
8143 +
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);
8150 +               return NULL;
8151 +       };
8152 +        
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') 
8159 +       {
8160 +               _dl_dprintf(2, "%s: '%s' is not an ELF file\n", _dl_progname,
8161 +                                        libname);
8162 +               _dl_internal_error_number = LD_ERROR_NOTELF;
8163 +               _dl_close(infile);
8164 +               _dl_munmap(header, 4096);
8165 +               return NULL;
8166 +       };
8167 +
8168 +       if ((epnt->e_type != ET_DYN) || (epnt->e_machine != MAGIC1 
8169 +#ifdef MAGIC2
8170 +                   && epnt->e_machine != MAGIC2
8171 +#endif
8172 +               )) 
8173 +       {
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);
8180 +               return NULL;
8181 +       };
8182 +
8183 +       ppnt = (ElfW(Phdr) *)(intptr_t) & header[epnt->e_phoff];
8184 +
8185 +       piclib = 1;
8186 +       for (i = 0; i < epnt->e_phnum; i++) {
8187 +
8188 +               if (ppnt->p_type == PT_DYNAMIC) {
8189 +                       if (dynamic_addr)
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;
8194 +               };
8195 +
8196 +               if (ppnt->p_type == PT_LOAD) {
8197 +                       /* See if this is a PIC library. */
8198 +                       if (i == 0 && ppnt->p_vaddr > 0x1000000) {
8199 +                               piclib = 0;
8200 +                               minvma = ppnt->p_vaddr;
8201 +                       }
8202 +                       if (piclib && ppnt->p_vaddr < minvma) {
8203 +                               minvma = ppnt->p_vaddr;
8204 +                       }
8205 +                       if (((unsigned long) ppnt->p_vaddr + ppnt->p_memsz) > maxvma) {
8206 +                               maxvma = ppnt->p_vaddr + ppnt->p_memsz;
8207 +                       }
8208 +               }
8209 +               ppnt++;
8210 +       };
8211 +
8212 +       maxvma = (maxvma + ADDR_ALIGN) & ~ADDR_ALIGN;
8213 +       minvma = minvma & ~0xffffU;
8214 +
8215 +       flags = MAP_PRIVATE /*| MAP_DENYWRITE */ ;
8216 +       if (!piclib)
8217 +               flags |= MAP_FIXED;
8218 +
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);
8226 +               return NULL;
8227 +       };
8228 +       libaddr = (unsigned long) status;
8229 +       flags |= MAP_FIXED;
8230 +
8231 +       /* Get the memory to store the library */
8232 +       ppnt = (ElfW(Phdr) *)(intptr_t) & header[epnt->e_phoff];
8233 +
8234 +       for (i = 0; i < epnt->e_phnum; i++) {
8235 +               if (ppnt->p_type == PT_LOAD) {
8236 +
8237 +                       /* See if this is a PIC library. */
8238 +                       if (i == 0 && ppnt->p_vaddr > 0x1000000) {
8239 +                               piclib = 0;
8240 +                               /* flags |= MAP_FIXED; */
8241 +                       }
8242 +
8243 +
8244 +
8245 +                       if (ppnt->p_flags & PF_W) {
8246 +                               unsigned long map_size;
8247 +                               char *cpnt;
8248 +
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);
8253 +
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);
8261 +                                       return NULL;
8262 +                               };
8263 +
8264 +                               /* Pad the last page with zeroes. */
8265 +                               cpnt = (char *) (status + (ppnt->p_vaddr & ADDR_ALIGN) +
8266 +                                                         ppnt->p_filesz);
8267 +                               while (((unsigned long) cpnt) & ADDR_ALIGN)
8268 +                                       *cpnt++ = 0;
8269 +
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 */
8275 +
8276 +                               map_size = (ppnt->p_vaddr + ppnt->p_filesz + ADDR_ALIGN) & PAGE_ALIGN;
8277 +
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);
8283 +                       } else
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);
8294 +                               return NULL;
8295 +                       };
8296 +
8297 +                       /* if(libaddr == 0 && piclib) {
8298 +                          libaddr = (unsigned long) status;
8299 +                          flags |= MAP_FIXED;
8300 +                          }; */
8301 +               };
8302 +               ppnt++;
8303 +       };
8304 +       _dl_close(infile);
8305 +
8306 +       /* For a non-PIC library, the addresses are all absolute */
8307 +       if (piclib) {
8308 +               dynamic_addr += (unsigned long) libaddr;
8309 +       }
8310 +
8311 +       /* 
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).
8314 +        */
8315 +
8316 +       /* Start by scanning the dynamic section to get all of the pointers */
8317 +
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);
8323 +               return NULL;
8324 +       }
8325 +
8326 +       dpnt = (Elf32_Dyn *) dynamic_addr;
8327 +
8328 +       dynamic_size = dynamic_size / sizeof(Elf32_Dyn);
8329 +       _dl_memset(dynamic_info, 0, sizeof(dynamic_info));
8330 +
8331 +#if defined(__mips__)
8332 +       {
8333 +               
8334 +               int indx = 1;
8335 +               Elf32_Dyn *dpnt = (Elf32_Dyn *) dynamic_addr;
8336 +
8337 +               while(dpnt->d_tag) {
8338 +                       dpnt++;
8339 +                       indx++;
8340 +               }
8341 +               dynamic_size = indx;
8342 +       }
8343 +#endif
8344 +
8345 +       {
8346 +               unsigned long indx;
8347 +
8348 +               for (indx = 0; indx < dynamic_size; indx++) 
8349 +               {
8350 +                       if (dpnt->d_tag > DT_JMPREL) {
8351 +                               dpnt++;
8352 +                               continue;
8353 +                       }
8354 +                       dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
8355 +                       if (dpnt->d_tag == DT_TEXTREL)
8356 +                               dynamic_info[DT_TEXTREL] = 1;
8357 +                       dpnt++;
8358 +               };
8359 +       }
8360 +
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. */
8364 +
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);
8374 +               }
8375 +#else
8376 +               _dl_dprintf(_dl_debug_file, "Can't modify %s's text section. Use GCC option -fPIC for shared objects, please.\n",libname);
8377 +               _dl_exit(1);
8378 +#endif         
8379 +       }
8380 +
8381 +       tpnt = _dl_add_elf_hash_table(libname, (char *) libaddr, dynamic_info, 
8382 +               dynamic_addr, dynamic_size);
8383 +
8384 +       tpnt->ppnt = (ElfW(Phdr) *)(intptr_t) (tpnt->loadaddr + epnt->e_phoff);
8385 +       tpnt->n_phent = epnt->e_phnum;
8386 +
8387 +       /*
8388 +        * Add this object into the symbol chain
8389 +        */
8390 +       if (*rpnt) {
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;
8397 +       }
8398 +       tpnt->usage_count++;
8399 +       tpnt->libtype = elf_lib;
8400 +
8401 +       /*
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
8404 +        * resolved. 
8405 +        */
8406 +
8407 +       lpnt = (unsigned long *) dynamic_info[DT_PLTGOT];
8408 +
8409 +       if (lpnt) {
8410 +               lpnt = (unsigned long *) (dynamic_info[DT_PLTGOT] +
8411 +                       ((int) libaddr));
8412 +               INIT_GOT(lpnt, tpnt);
8413 +       };
8414 +
8415 +#if defined (__SUPPORT_LD_DEBUG__)
8416 +       if(_dl_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);
8422 +
8423 +       }
8424 +#endif
8425 +       _dl_munmap(header, 4096);
8426 +
8427 +       return tpnt;
8428 +}
8429 +
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. */
8435 +
8436 +int _dl_copy_fixups(struct dyn_elf *rpnt)
8437 +{
8438 +       int goof = 0;
8439 +       struct elf_resolve *tpnt;
8440 +
8441 +       if (rpnt->next)
8442 +               goof += _dl_copy_fixups(rpnt->next);
8443 +       else
8444 +               return 0;
8445 +
8446 +       tpnt = rpnt->dyn;
8447 +
8448 +       if (tpnt->init_flag & COPY_RELOCS_DONE)
8449 +               return goof;
8450 +       tpnt->init_flag |= COPY_RELOCS_DONE;
8451 +
8452 +#if defined (__SUPPORT_LD_DEBUG__)
8453 +       if(_dl_debug) _dl_dprintf(_dl_debug_file,"\nrelocation copy fixups: %s", tpnt->libname);        
8454 +#endif    
8455 +
8456 +#ifdef ELF_USES_RELOCA
8457 +       goof += _dl_parse_copy_information(rpnt, 
8458 +               tpnt->dynamic_info[DT_RELA], tpnt->dynamic_info[DT_RELASZ], 0);
8459 +
8460 +#else
8461 +       goof += _dl_parse_copy_information(rpnt, tpnt->dynamic_info[DT_REL], 
8462 +               tpnt->dynamic_info[DT_RELSZ], 0);
8463 +
8464 +#endif
8465 +#if defined (__SUPPORT_LD_DEBUG__)
8466 +       if(_dl_debug) _dl_dprintf(_dl_debug_file,"\nrelocation copy fixups: %s; finished\n\n", tpnt->libname);  
8467 +#endif    
8468 +       return goof;
8469 +}
8470 +
8471 +/* Minimal printf which handles only %s, %d, and %x */
8472 +void _dl_dprintf(int fd, const char *fmt, ...)
8473 +{
8474 +       int num;
8475 +       va_list args;
8476 +       char *start, *ptr, *string;
8477 +       static char *buf;
8478 +
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);
8483 +                       _dl_exit(20);
8484 +       }
8485 +
8486 +       start = ptr = buf;
8487 +
8488 +       if (!fmt)
8489 +               return;
8490 +
8491 +       if (_dl_strlen(fmt) >= (sizeof(buf) - 1))
8492 +               _dl_write(fd, "(overflow)\n", 10);
8493 +
8494 +       _dl_strcpy(buf, fmt);
8495 +       va_start(args, fmt);
8496 +
8497 +       while (start) {
8498 +               while (*ptr != '%' && *ptr) {
8499 +                       ptr++;
8500 +               }
8501 +
8502 +               if (*ptr == '%') {
8503 +                       *ptr++ = '\0';
8504 +                       _dl_write(fd, start, _dl_strlen(start));
8505 +
8506 +                       switch (*ptr++) {
8507 +                       case 's':
8508 +                               string = va_arg(args, char *);
8509 +
8510 +                               if (!string)
8511 +                                       _dl_write(fd, "(null)", 6);
8512 +                               else
8513 +                                       _dl_write(fd, string, _dl_strlen(string));
8514 +                               break;
8515 +
8516 +                       case 'i':
8517 +                       case 'd':
8518 +                       {
8519 +                               char tmp[22];
8520 +                               num = va_arg(args, int);
8521 +
8522 +                               string = _dl_simple_ltoa(tmp, num);
8523 +                               _dl_write(fd, string, _dl_strlen(string));
8524 +                               break;
8525 +                       }
8526 +                       case 'x':
8527 +                       case 'X':
8528 +                       {
8529 +                               char tmp[22];
8530 +                               num = va_arg(args, int);
8531 +
8532 +                               string = _dl_simple_ltoahex(tmp, num);
8533 +                               _dl_write(fd, string, _dl_strlen(string));
8534 +                               break;
8535 +                       }
8536 +                       default:
8537 +                               _dl_write(fd, "(null)", 6);
8538 +                               break;
8539 +                       }
8540 +
8541 +                       start = ptr;
8542 +               } else {
8543 +                       _dl_write(fd, start, _dl_strlen(start));
8544 +                       start = NULL;
8545 +               }
8546 +       }
8547 +       _dl_munmap(buf, 4096);
8548 +       return;
8549 +}
8550 +
8551 +char *_dl_strdup(const char *string)
8552 +{
8553 +       char *retval;
8554 +       int len;
8555 +
8556 +       len = _dl_strlen(string);
8557 +       retval = _dl_malloc(len + 1);
8558 +       _dl_strcpy(retval, string);
8559 +       return retval;
8560 +}
8561 +
8562 +void *(*_dl_malloc_function) (size_t size) = NULL;
8563 +void *_dl_malloc(int size)
8564 +{
8565 +       void *retval;
8566 +
8567 +#if 0
8568 +#ifdef __SUPPORT_LD_DEBUG_EARLY__
8569 +       _dl_dprintf(2, "malloc: request for %d bytes\n", size);
8570 +#endif
8571 +#endif
8572 +
8573 +       if (_dl_malloc_function)
8574 +               return (*_dl_malloc_function) (size);
8575 +
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");
8579 +#endif
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);
8584 +                       _dl_exit(20);
8585 +               }
8586 +       }
8587 +       retval = _dl_malloc_addr;
8588 +       _dl_malloc_addr += size;
8589 +
8590 +       /*
8591 +        * Align memory to 4 byte boundary.  Some platforms require this, others
8592 +        * simply get better performance.
8593 +        */
8594 +       _dl_malloc_addr = (char *) (((unsigned long) _dl_malloc_addr + 3) & ~(3));
8595 +       return retval;
8596 +}
8597 +
8598 +int _dl_fixup(struct elf_resolve *tpnt, int flag)
8599 +{
8600 +       int goof = 0;
8601 +
8602 +       if (tpnt->next)
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); 
8606 +#endif    
8607 +       
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);
8612 +#endif    
8613 +               goof++;
8614 +               return goof;
8615 +#else
8616 +               if (tpnt->init_flag & RELOCS_DONE)
8617 +                       return goof;
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);
8622 +#endif
8623 +       }
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);
8628 +#endif    
8629 +               goof++;
8630 +               return goof;
8631 +#else
8632 +               if (tpnt->init_flag & RELOCS_DONE)
8633 +                       return goof;
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);
8638 +#endif
8639 +       }
8640 +       if (tpnt->dynamic_info[DT_JMPREL]) {
8641 +               if (tpnt->init_flag & JMP_RELOCS_DONE)
8642 +                       return goof;
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);
8648 +               } else {
8649 +                       goof += _dl_parse_relocation_information(tpnt, 
8650 +                                       tpnt->dynamic_info[DT_JMPREL], 
8651 +                                       tpnt->dynamic_info[DT_PLTRELSZ], 0);
8652 +               }
8653 +       }
8654 +#if defined (__SUPPORT_LD_DEBUG__)
8655 +       if(_dl_debug) {
8656 +               _dl_dprintf(_dl_debug_file,"\nrelocation processing: %s", tpnt->libname);     
8657 +               _dl_dprintf(_dl_debug_file,"; finished\n\n");
8658 +       }
8659 +#endif    
8660 +       return goof;
8661 +}
8662 +
8663 +
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
8667 @@ -0,0 +1,22 @@
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.  */
8671 +
8672 +asm("" \
8673 +"      .text\n"                        \
8674 +"      .globl  _dl_boot\n"             \
8675 +"_dl_boot:\n"                          \
8676 +"      mov     r15, r4\n"              \
8677 +"      mov.l   .L_dl_boot2, r0\n"      \
8678 +"      bsrf    r0\n"                   \
8679 +"      add     #4, r4\n"               \
8680 +".jmp_loc:\n"                          \
8681 +"      jmp     @r0\n"                  \
8682 +"       mov    #0, r4  !call _start with arg == 0\n" \
8683 +".L_dl_boot2:\n"                       \
8684 +"      .long   _dl_boot2-.jmp_loc\n"   \
8685 +"      .previous\n"                    \
8686 +);
8687 +
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
8693 @@ -0,0 +1,427 @@
8694 +/* vi: set sw=4 ts=4: */
8695 +/* SuperH ELF shared library loader suppport
8696 + *
8697 + * Copyright (C) 2002, Stefan Allius <allius@atecom.com> and 
8698 + *                     Eddie C. Dost <ecd@atecom.com>
8699 + *
8700 + * All rights reserved.
8701 + *
8702 + * Redistribution and use in source and binary forms, with or without
8703 + * modification, are permitted provided that the following conditions
8704 + * are met:
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.
8710 + *
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
8721 + * SUCH DAMAGE.
8722 + */
8723 +
8724 +#if defined (__SUPPORT_LD_DEBUG__)
8725 +static const char *_dl_reltypes_tab[] =
8726 +{
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",
8735 +};
8736 +
8737 +static const char *
8738 +_dl_reltypes(int type)
8739 +{
8740 +  static char buf[22];  
8741 +  const char *str;
8742 +  
8743 +  if (type >= (int)(sizeof (_dl_reltypes_tab)/sizeof(_dl_reltypes_tab[0])) ||
8744 +      NULL == (str = _dl_reltypes_tab[type]))
8745 +  {
8746 +    str =_dl_simple_ltoa( buf, (unsigned long)(type));
8747 +  }
8748 +  return str;
8749 +}
8750 +
8751 +static 
8752 +void debug_sym(Elf32_Sym *symtab,char *strtab,int symtab_index)
8753 +{
8754 +  if(_dl_debug_symbols)
8755 +  {
8756 +    if(symtab_index){
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);
8764 +    }
8765 +  }
8766 +}
8767 +
8768 +static void debug_reloc(Elf32_Sym *symtab,char *strtab, ELF_RELOC *rpnt)
8769 +{
8770 +  if(_dl_debug_reloc)
8771 +  {
8772 +    int symtab_index;
8773 +    const char *sym;
8774 +    symtab_index = ELF32_R_SYM(rpnt->r_info);
8775 +    sym = symtab_index ? strtab + symtab[symtab_index].st_name : "sym=0x0";
8776 +    
8777 +  if(_dl_debug_symbols)
8778 +         _dl_dprintf(_dl_debug_file, "\n\t");
8779 +  else
8780 +         _dl_dprintf(_dl_debug_file, "\n%s\n\t", sym);
8781 +    
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)),
8785 +               rpnt->r_offset,
8786 +               rpnt->r_addend);
8787 +#else
8788 +    _dl_dprintf(_dl_debug_file, "%s\toffset=%x\n",
8789 +               _dl_reltypes(ELF32_R_TYPE(rpnt->r_info)),
8790 +               rpnt->r_offset);
8791 +#endif
8792 +  }
8793 +}
8794 +#endif
8795 +
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. */
8799 +
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
8805 +   working. */
8806 +
8807 +extern int _dl_linux_resolve(void);
8808 +
8809 +unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
8810 +{
8811 +       int reloc_type;
8812 +       ELF_RELOC *this_reloc;
8813 +       char *strtab;
8814 +       Elf32_Sym *symtab;
8815 +       int symtab_index;
8816 +       char *rel_addr;
8817 +       char *new_addr;
8818 +       char **got_addr;
8819 +       unsigned long instr_addr;
8820 +       char *symname;
8821 +
8822 +       rel_addr = (char *) (tpnt->dynamic_info[DT_JMPREL] + tpnt->loadaddr);
8823 +
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);
8827 +
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;
8831 +
8832 +       if (reloc_type != R_SH_JMP_SLOT) {
8833 +         _dl_dprintf(2, "%s: Incorrect relocation type in jump relocations\n", 
8834 +                      _dl_progname);
8835 +         _dl_exit(1);
8836 +       }
8837 +       
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;
8842 +
8843 +
8844 +       /* Get the address of the GOT entry */
8845 +       new_addr = _dl_find_hash(symname, tpnt->symbol_scope, tpnt, resolver);
8846 +       if (!new_addr) {
8847 +               new_addr = _dl_find_hash(symname, NULL, NULL, resolver);
8848 +               if (new_addr) {
8849 +                       return (unsigned long) new_addr;
8850 +               }
8851 +               
8852 +               _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname);
8853 +               _dl_exit(1);
8854 +       }
8855 +
8856 +#if defined (__SUPPORT_LD_DEBUG__)
8857 +       if ((unsigned long) got_addr < 0x20000000)
8858 +       {
8859 +               if (_dl_debug_bindings)
8860 +               {
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);
8864 +               }
8865 +       }
8866 +       if (!_dl_debug_nofixups) {
8867 +               *got_addr = new_addr;
8868 +       }
8869 +#else
8870 +       *got_addr = new_addr;
8871 +#endif
8872 +
8873 +       return (unsigned long) new_addr;
8874 +}
8875 +
8876 +
8877 +static int
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))
8882 +{
8883 +       unsigned int i;
8884 +       char *strtab;
8885 +       Elf32_Sym *symtab;
8886 +       ELF_RELOC *rpnt;
8887 +       int symtab_index;
8888 +       /* Now parse the relocation information */
8889 +
8890 +       rpnt = (ELF_RELOC *)(intptr_t) (rel_addr + tpnt->loadaddr);
8891 +       rel_size = rel_size / sizeof(ELF_RELOC);
8892 +
8893 +       symtab = (Elf32_Sym *)(intptr_t) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
8894 +       strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
8895 +
8896 +         for (i = 0; i < rel_size; i++, rpnt++) {
8897 +               int res;
8898 +           
8899 +               symtab_index = ELF32_R_SYM(rpnt->r_info);
8900 +               
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)
8904 +                       continue;
8905 +               if (symtab_index && tpnt->libtype == program_interpreter &&
8906 +                   _dl_symbol(strtab + symtab[symtab_index].st_name))
8907 +                       continue;
8908 +
8909 +#if defined (__SUPPORT_LD_DEBUG__)
8910 +               debug_sym(symtab,strtab,symtab_index);
8911 +               debug_reloc(symtab,strtab,rpnt);
8912 +#endif
8913 +
8914 +               res = reloc_fnc (tpnt, scope, rpnt, symtab, strtab);
8915 +
8916 +               if (res==0) continue;
8917 +
8918 +               _dl_dprintf(2, "\n%s: ",_dl_progname);
8919 +               
8920 +               if (symtab_index)
8921 +                 _dl_dprintf(2, "symbol '%s': ", strtab + symtab[symtab_index].st_name);
8922 +                 
8923 +               if (res <0)
8924 +               {
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));
8928 +#else
8929 +                       _dl_dprintf(2, "can't handle reloc type %x\n", reloc_type);
8930 +#endif                 
8931 +                       _dl_exit(-res);
8932 +               }
8933 +               else if (res >0)
8934 +               {
8935 +                       _dl_dprintf(2, "can't resolve symbol\n");
8936 +                       return res;
8937 +               }
8938 +         }
8939 +         return 0;
8940 +}
8941 +
8942 +
8943 +static int
8944 +_dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope,
8945 +             ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)
8946 +{
8947 +        int reloc_type;
8948 +       int symtab_index;
8949 +       char *symname;
8950 +       unsigned long *reloc_addr;
8951 +       unsigned long symbol_addr;
8952 +#if defined (__SUPPORT_LD_DEBUG__)
8953 +       unsigned long old_val;
8954 +#endif
8955 +  
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);
8959 +       symbol_addr = 0;
8960 +       symname      = strtab + symtab[symtab_index].st_name;
8961 +
8962 +       if (symtab_index) {
8963 +
8964 +
8965 +               symbol_addr = (unsigned long) _dl_find_hash(symname, scope, 
8966 +                               (reloc_type == R_SH_JMP_SLOT ? tpnt : NULL), symbolrel);
8967 +
8968 +               /*
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.
8972 +                */
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);
8977 +#endif
8978 +                       return 0;
8979 +               }
8980 +       }
8981 +
8982 +
8983 +#if defined (__SUPPORT_LD_DEBUG__)
8984 +       old_val = *reloc_addr;
8985 +#endif
8986 +           switch (reloc_type) {
8987 +               case R_SH_NONE:
8988 +                       break;
8989 +               case R_SH_COPY:
8990 +                       /* handled later on */
8991 +                       break;
8992 +               case R_SH_DIR32:
8993 +               case R_SH_GLOB_DAT:
8994 +               case R_SH_JMP_SLOT:
8995 +                       *reloc_addr = symbol_addr + rpnt->r_addend;
8996 +                       break;
8997 +               case R_SH_REL32:
8998 +                       *reloc_addr = symbol_addr + rpnt->r_addend -
8999 +                                       (unsigned long) reloc_addr;
9000 +                       break;
9001 +               case R_SH_RELATIVE:
9002 +                       *reloc_addr = (unsigned long) tpnt->loadaddr + rpnt->r_addend;
9003 +                       break;
9004 +               default:
9005 +                       return -1; /*call _dl_exit(1) */
9006 +           }
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);
9010 +#endif
9011 +
9012 +       return 0;
9013 +}
9014
9015 +         
9016 +static int
9017 +_dl_do_lazy_reloc (struct elf_resolve *tpnt, struct dyn_elf *scope,
9018 +                  ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)
9019 +{
9020 +       int reloc_type;
9021 +       unsigned long *reloc_addr;
9022 +#if defined (__SUPPORT_LD_DEBUG__)
9023 +       unsigned long old_val;
9024 +#endif
9025 +       (void)scope;
9026 +       (void)symtab;
9027 +       (void)strtab;
9028 +
9029 +       reloc_addr = (unsigned long *)(intptr_t) (tpnt->loadaddr + (unsigned long) rpnt->r_offset);
9030 +       reloc_type = ELF32_R_TYPE(rpnt->r_info);
9031 +  
9032 +#if defined (__SUPPORT_LD_DEBUG__)
9033 +       old_val = *reloc_addr;
9034 +#endif
9035 +           switch (reloc_type) {
9036 +             case R_SH_NONE:
9037 +               break;
9038 +             case R_SH_JMP_SLOT:
9039 +               *reloc_addr += (unsigned long) tpnt->loadaddr;
9040 +               break;
9041 +             default:
9042 +               return -1; /*call _dl_exit(1) */
9043 +           }
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);
9047 +#endif
9048 +       return 0;
9049 +       
9050 +}
9051 +
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. */
9057 +
9058 +/* No, there are cases where the SVr4 linker fails to emit COPY relocs
9059 +   at all */
9060 +static int
9061 +_dl_do_copy (struct elf_resolve *tpnt, struct dyn_elf *scope,
9062 +            ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)
9063 +{
9064 +        int reloc_type;
9065 +       int symtab_index;
9066 +       unsigned long *reloc_addr;
9067 +       unsigned long symbol_addr;
9068 +       int goof = 0;
9069 +       char*symname;
9070 +         
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) 
9074 +           return 0;
9075 +       symtab_index = ELF32_R_SYM(rpnt->r_info);
9076 +       symbol_addr = 0;
9077 +       symname      = strtab + symtab[symtab_index].st_name;
9078 +               
9079 +       if (symtab_index) {
9080 +
9081 +               symbol_addr = (unsigned long) _dl_find_hash(symname, scope, NULL, copyrel);
9082 +               if (!symbol_addr) goof++;
9083 +       }
9084 +       if (!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);
9090 +#endif
9091 +               _dl_memcpy((char *) symtab[symtab_index].st_value, 
9092 +                       (char *) symbol_addr, symtab[symtab_index].st_size);
9093 +       }
9094 +
9095 +       return goof;
9096 +}
9097 +
9098 +
9099 +void _dl_parse_lazy_relocation_information(struct elf_resolve *tpnt, 
9100 +       unsigned long rel_addr, unsigned long rel_size, int type)
9101 +{
9102 +       (void) type;
9103 +       (void)_dl_parse(tpnt, NULL, rel_addr, rel_size, _dl_do_lazy_reloc);
9104 +}
9105 +
9106 +int _dl_parse_relocation_information(struct elf_resolve *tpnt, 
9107 +       unsigned long rel_addr, unsigned long rel_size, int type)
9108 +{
9109 +       (void) type;
9110 +       return _dl_parse(tpnt, tpnt->symbol_scope, rel_addr, rel_size, _dl_do_reloc);
9111 +}
9112 +
9113 +int _dl_parse_copy_information(struct dyn_elf *xpnt, unsigned long rel_addr, 
9114 +       unsigned long rel_size, int type)
9115 +{
9116 +       (void) type;
9117 +       return _dl_parse(xpnt->dyn, xpnt->next, rel_addr, rel_size, _dl_do_copy);
9118 +}
9119 +
9120 +
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
9124 @@ -0,0 +1,7 @@
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. */
9128 +
9129 +#define __set_errno(X) {(void)(X);}
9130 +#include "sys/syscall.h"
9131 +
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
9135 @@ -0,0 +1,144 @@
9136 +/*
9137 + * Various assmbly language/system dependent  hacks that are required
9138 + * so that we can minimize the amount of platform specific code.
9139 + */
9140 +
9141 +/* 
9142 + * Define this if the system uses RELOCA.
9143 + */
9144 +#define ELF_USES_RELOCA
9145 +
9146 +/*
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.
9150 + */
9151 +#define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned long*)   ARGS)
9152 +
9153 +/*
9154 + * Initialization sequence for a GOT.
9155 + */
9156 +#define INIT_GOT(GOT_BASE,MODULE) \
9157 +{                              \
9158 +  GOT_BASE[2] = (unsigned long) _dl_linux_resolve; \
9159 +  GOT_BASE[1] = (unsigned long) (MODULE); \
9160 +}
9161 +
9162 +/*
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
9167 + * load address.
9168 + */
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);             \
9174 +               break;                                          \
9175 +       case R_SH_DIR32:                                        \
9176 +       case R_SH_GLOB_DAT:                                     \
9177 +       case R_SH_JMP_SLOT:                                     \
9178 +               *(REL)  = (SYMBOL) + (RELP)->r_addend;          \
9179 +               break;                                          \
9180 +       case R_SH_RELATIVE:                                     \
9181 +               *(REL)  = (LOAD) + (RELP)->r_addend;            \
9182 +               break;                                          \
9183 +       case R_SH_NONE:                                         \
9184 +               break;                                          \
9185 +       default:                                                \
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);                   \
9194 +               _dl_exit(1);                                    \
9195 +       }
9196 +
9197 +
9198 +/*
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.
9202 + */
9203 +
9204 +#define START()   return _dl_elf_main;
9205 +
9206 +
9207 +
9208 +/* Here we define the magic numbers that this dynamic loader should accept */
9209 +
9210 +#define MAGIC1 EM_SH
9211 +#undef  MAGIC2
9212 +/* Used for error messages */
9213 +#define ELF_TARGET "sh"
9214 +
9215 +struct elf_resolve;
9216 +extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
9217 +
9218 +static __inline__ unsigned int
9219 +_dl_urem(unsigned int n, unsigned int base)
9220 +{
9221 +  int res;
9222 +  
9223 +       __asm__ (""\
9224 +               "mov    #0, r0\n\t" \
9225 +               "div0u\n\t" \
9226 +               "" \
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" \
9230 +               ""                              \
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"   \
9239 +               ""                              \
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"   \
9248 +               ""                              \
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"   \
9257 +               ""                              \
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"   \
9266 +               "rotcl  %1\n\t"
9267 +               : "=r" (res)
9268 +               : "0" (n), "r" (base)
9269 +               : "r0","cc");
9270 +
9271 +       return n - (base * res);
9272 +}
9273 +
9274 +#define do_rem(result, n, base)     ((result) = _dl_urem((n), (base)))
9275 +
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
9283 @@ -0,0 +1,91 @@
9284 +/*
9285 + * Stolen from glibc-2.2.2 by Eddie C. Dost <ecd@atecom.com>
9286 + */
9287 +
9288 +       .text
9289 +       .globl  _dl_linux_resolver
9290 +       .globl  _dl_linux_resolve
9291 +       .type   _dl_linux_resolve, @function
9292 +       .balign 16
9293 +_dl_linux_resolve:
9294 +       mov.l   r3, @-r15
9295 +       mov.l   r4, @-r15
9296 +       mov.l   r5, @-r15
9297 +       mov.l   r6, @-r15
9298 +       mov.l   r7, @-r15
9299 +       mov.l   r12, @-r15
9300 +       movt    r3              ! Save T flag
9301 +       mov.l   r3, @-r15
9302 +
9303 +#ifdef HAVE_FPU
9304 +       sts.l   fpscr, @-r15
9305 +       mov     #8,r3
9306 +       swap.w  r3, r3
9307 +       lds     r3, fpscr
9308 +       fmov.s  fr11, @-r15
9309 +       fmov.s  fr10, @-r15
9310 +       fmov.s  fr9, @-r15
9311 +       fmov.s  fr8, @-r15
9312 +       fmov.s  fr7, @-r15
9313 +       fmov.s  fr6, @-r15
9314 +       fmov.s  fr5, @-r15
9315 +       fmov.s  fr4, @-r15
9316 +#endif
9317 +       sts.l   pr, @-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.
9326 +
9327 +   Found in binutils/bfd/elf32-sh.c by Stefan Allius <allius@atecom.com>
9328 + */
9329 +       mov     #8 ,r5
9330 +       cmp/gt  r5, r0
9331 +       bt      1f
9332 +       mov     r2, r0          ! link map address in r2 (SH PIC ABI)
9333 +1:
9334 +       mov     r0, r4          ! link map address in r0 (GNUs PLT)
9335 +       mova    .LG, r0
9336 +       mov.l   .LG, r5
9337 +       add     r5, r0
9338 +       mov.l   3f, r5
9339 +       mov.l   @(r0, r5),r5
9340 +       jsr     @r5
9341 +        mov    r1, r5          ! Reloc offset
9342 +
9343 +       lds.l   @r15+, pr       ! Get register content back
9344 +
9345 +#ifdef HAVE_FPU
9346 +       fmov.s  @r15+, fr4
9347 +       fmov.s  @r15+, fr5
9348 +       fmov.s  @r15+, fr6
9349 +       fmov.s  @r15+, fr7
9350 +       fmov.s  @r15+, fr8
9351 +       fmov.s  @r15+, fr9
9352 +       fmov.s  @r15+, fr10
9353 +       fmov.s  @r15+, fr11
9354 +       lds.l   @r15+, fpscr
9355 +#endif
9356 +
9357 +       mov.l   @r15+, r3
9358 +       shal    r3              ! Load T flag
9359 +       mov.l   @r15+, r12
9360 +       mov.l   @r15+, r7
9361 +       mov.l   @r15+, r6
9362 +       mov.l   @r15+, r5
9363 +       mov.l   @r15+, r4
9364 +       jmp     @r0             ! Jump to function address
9365 +        mov.l  @r15+, r3
9366 +
9367 +       .balign 4
9368 +
9369 +3:
9370 +       .long   _dl_linux_resolver@GOT
9371 +.LG:
9372 +       .long   _GLOBAL_OFFSET_TABLE_
9373 +       .size   _dl_linux_resolve, . - _dl_linux_resolve
9374 +
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
9378 @@ -0,0 +1,7 @@
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
9382 + * can be done.
9383 + */
9384 +
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
9389 @@ -0,0 +1,357 @@
9390 +/* vi: set sw=4 ts=4: */
9391 +/* sparc ELF shared library loader suppport
9392 + *
9393 + * Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald, 
9394 + *                             David Engel, Hongjiu Lu and Mitch D'Souza
9395 + *
9396 + * All rights reserved.
9397 + *
9398 + * Redistribution and use in source and binary forms, with or without
9399 + * modification, are permitted provided that the following conditions
9400 + * are met:
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.
9406 + *
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
9417 + * SUCH DAMAGE.
9418 + */
9419 +
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",
9428 +  "R_SPARC_UA32"};
9429 +#endif
9430 +
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. */
9434 +
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
9440 +   working. */
9441 +
9442 +extern _dl_linux_resolve(void);
9443 +
9444 +unsigned int _dl_linux_resolver(unsigned int reloc_entry, unsigned int * plt)
9445 +{
9446 +  int reloc_type;
9447 +  Elf32_Rela * this_reloc;
9448 +  char * strtab;
9449 +  Elf32_Sym * symtab; 
9450 +  Elf32_Rela * rel_addr;
9451 +  struct elf_resolve * tpnt;
9452 +  int symtab_index;
9453 +  char * new_addr;
9454 +  char ** got_addr;
9455 +  unsigned int instr_addr;
9456 +  tpnt = (struct elf_resolve *) plt[2];
9457 +
9458 +  rel_addr = (Elf32_Rela *) (tpnt->dynamic_info[DT_JMPREL] + 
9459 +                                  tpnt->loadaddr);
9460 +
9461 +  /*
9462 +   * Generate the correct relocation index into the .rela.plt section.
9463 +   */
9464 +  reloc_entry = (reloc_entry >> 12) - 0xc;
9465 +
9466 +  this_reloc = (Elf32_Rela *) ((char *) rel_addr + reloc_entry);
9467 +
9468 +  reloc_type = ELF32_R_TYPE(this_reloc->r_info);
9469 +  symtab_index = ELF32_R_SYM(this_reloc->r_info);
9470 +
9471 +  symtab =  (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
9472 +  strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
9473 +
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);
9478 +
9479 +
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);
9483 +    _dl_exit(30);
9484 +  };
9485 +
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;
9489 +
9490 +  _dl_dprintf(2, "symtab_index %d\n", symtab_index);
9491 +
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);
9496 +  }
9497 +#endif
9498 +
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);
9502 +  if(!new_addr) {
9503 +    _dl_dprintf(2, "%s: can't resolve symbol '%s'\n",
9504 +              _dl_progname, strtab + symtab[symtab_index].st_name);
9505 +    _dl_exit(31);
9506 +  };
9507 +
9508 +#if defined (__SUPPORT_LD_DEBUG__)
9509 +       if ((unsigned long) got_addr < 0x40000000)
9510 +       {
9511 +               if (_dl_debug_bindings)
9512 +               {
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);
9517 +               }
9518 +       }
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));
9522 +       }
9523 +#else
9524 +       got_addr[1] = (char *) (0x03000000 | (((unsigned int) new_addr >> 10) & 0x3fffff));
9525 +       got_addr[2] = (char *) (0x81c06000 | ((unsigned int) new_addr & 0x3ff));
9526 +#endif
9527 +
9528 +       _dl_dprintf(2, "Address = %x\n",new_addr);
9529 +       _dl_exit(32);
9530 +
9531 +  return (unsigned int) new_addr;
9532 +}
9533 +
9534 +void _dl_parse_lazy_relocation_information(struct elf_resolve * tpnt, int rel_addr,
9535 +       int rel_size, int type){
9536 +  int i;
9537 +  char * strtab;
9538 +  int reloc_type;
9539 +  int symtab_index;
9540 +  Elf32_Sym * symtab; 
9541 +  Elf32_Rela * rpnt;
9542 +  unsigned int * reloc_addr;
9543 +
9544 +  /* Now parse the relocation information */
9545 +  rpnt = (Elf32_Rela *) (rel_addr + tpnt->loadaddr);
9546 +
9547 +  symtab =  (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
9548 +  strtab = ( char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
9549 +
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);
9554 +
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))
9560 +      continue;
9561 +
9562 +    switch(reloc_type){
9563 +    case R_SPARC_NONE:
9564 +      break;
9565 +    case R_SPARC_JMP_SLOT:
9566 +      break;
9567 +    default:
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]);
9571 +#endif
9572 +      if(symtab_index) _dl_dprintf(2, "'%s'\n",
9573 +                                 strtab + symtab[symtab_index].st_name);
9574 +      _dl_exit(33);
9575 +    };
9576 +  };
9577 +}
9578 +
9579 +int _dl_parse_relocation_information(struct elf_resolve * tpnt, int rel_addr,
9580 +       int rel_size, int type){
9581 +  int i;
9582 +  char * strtab;
9583 +  int reloc_type;
9584 +  int goof = 0;
9585 +  Elf32_Sym * symtab; 
9586 +  Elf32_Rela * rpnt;
9587 +  unsigned int * reloc_addr;
9588 +  unsigned int symbol_addr;
9589 +  int symtab_index;
9590 +  /* Now parse the relocation information */
9591 +
9592 +  rpnt = (Elf32_Rela *) (rel_addr + tpnt->loadaddr);
9593 +
9594 +  symtab =  (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
9595 +  strtab = ( char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
9596 +
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);
9601 +    symbol_addr = 0;
9602 +
9603 +    if(!symtab_index && tpnt->libtype == program_interpreter) continue;
9604 +
9605 +    if(symtab_index) {
9606 +
9607 +      if(tpnt->libtype == program_interpreter && 
9608 +        _dl_symbol(strtab + symtab[symtab_index].st_name))
9609 +       continue;
9610 +
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);
9615 +
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);
9620 +       goof++;
9621 +      };
9622 +    };
9623 +    switch(reloc_type){
9624 +    case R_SPARC_NONE:
9625 +       break;
9626 +    case R_SPARC_32:
9627 +      *reloc_addr = symbol_addr + rpnt->r_addend;
9628 +      break;
9629 +    case R_SPARC_DISP32:
9630 +      *reloc_addr = symbol_addr + rpnt->r_addend - (unsigned int) reloc_addr;
9631 +      break;
9632 +    case R_SPARC_GLOB_DAT:
9633 +      *reloc_addr = symbol_addr + rpnt->r_addend;
9634 +      break;
9635 +    case R_SPARC_JMP_SLOT:
9636 +      reloc_addr[1] = 0x03000000 | ((symbol_addr >> 10) & 0x3fffff);
9637 +      reloc_addr[2] = 0x81c06000 | (symbol_addr & 0x3ff);
9638 +      break;
9639 +    case R_SPARC_RELATIVE:
9640 +      *reloc_addr += (unsigned int) tpnt->loadaddr + rpnt->r_addend;
9641 +      break;
9642 +    case R_SPARC_HI22:
9643 +      if (!symbol_addr)
9644 +        symbol_addr = tpnt->loadaddr + rpnt->r_addend;
9645 +      else
9646 +       symbol_addr += rpnt->r_addend;
9647 +      *reloc_addr = (*reloc_addr & 0xffc00000)|(symbol_addr >> 10);
9648 +      break;
9649 +    case R_SPARC_LO10:
9650 +      if (!symbol_addr)
9651 +        symbol_addr = tpnt->loadaddr + rpnt->r_addend;
9652 +      else
9653 +       symbol_addr += rpnt->r_addend;
9654 +      *reloc_addr = (*reloc_addr & ~0x3ff)|(symbol_addr & 0x3ff);
9655 +      break;
9656 +    case R_SPARC_WDISP30:
9657 +      *reloc_addr = (*reloc_addr & 0xc0000000)|
9658 +       ((symbol_addr - (unsigned int) reloc_addr) >> 2);
9659 +      break;
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);
9668 +#endif
9669 +      break;
9670 +    default:
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]);
9674 +#endif
9675 +      if (symtab_index)
9676 +       _dl_dprintf(2, "'%s'\n", strtab + symtab[symtab_index].st_name);
9677 +      _dl_exit(34);
9678 +    };
9679 +
9680 +  };
9681 +  return goof;
9682 +}
9683 +
9684 +
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. */
9690 +
9691 +/* No, there are cases where the SVr4 linker fails to emit COPY relocs
9692 +   at all */
9693 +
9694 +int _dl_parse_copy_information(struct dyn_elf * xpnt, int rel_addr,
9695 +       int rel_size, int type)
9696 +{
9697 +  int i;
9698 +  char * strtab;
9699 +  int reloc_type;
9700 +  int goof = 0;
9701 +  Elf32_Sym * symtab; 
9702 +  Elf32_Rela * rpnt;
9703 +  unsigned int * reloc_addr;
9704 +  unsigned int symbol_addr;
9705 +  struct elf_resolve *tpnt;
9706 +  int symtab_index;
9707 +  /* Now parse the relocation information */
9708 +
9709 +  tpnt = xpnt->dyn;
9710 +  
9711 +  rpnt = (Elf32_Rela *) (rel_addr + tpnt->loadaddr);
9712 +
9713 +  symtab =  (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
9714 +  strtab = ( char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
9715 +
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);
9721 +    symbol_addr = 0;
9722 +    if(!symtab_index && tpnt->libtype == program_interpreter) continue;
9723 +    if(symtab_index) {
9724 +
9725 +      if(tpnt->libtype == program_interpreter && 
9726 +        _dl_symbol(strtab + symtab[symtab_index].st_name))
9727 +       continue;
9728 +
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);
9735 +       goof++;
9736 +      };
9737 +    };
9738 +    if (!goof)
9739 +      _dl_memcpy((char *) symtab[symtab_index].st_value, 
9740 +                 (char *) symbol_addr, 
9741 +                 symtab[symtab_index].st_size);
9742 +  };
9743 +  return goof;
9744 +}
9745 +
9746 +
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
9750 @@ -0,0 +1,155 @@
9751 +/*
9752 + * This file contains the system call macros and syscall 
9753 + * numbers used by the shared library loader.
9754 + */
9755 +
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
9770 +
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 
9775 + * linked. */
9776 +
9777 +#define _syscall0(type,name) \
9778 +type name(void) \
9779 +{ \
9780 +long __res; \
9781 +register long __g1 __asm__ ("g1") = __NR_##name; \
9782 +__asm__ __volatile__ ("t 0x10\n\t" \
9783 +                     "bcc 1f\n\t" \
9784 +                     "mov %%o0, %0\n\t" \
9785 +                     "sub %%g0, %%o0, %0\n\t" \
9786 +                     "1:\n\t" \
9787 +                     : "=r" (__res)\
9788 +                     : "r" (__g1) \
9789 +                     : "o0", "cc"); \
9790 +if (__res < -255 || __res >= 0) \
9791 +    return (type) __res; \
9792 +/*errno = -__res; */\
9793 +return -1; \
9794 +}
9795 +
9796 +#define _syscall1(type,name,type1,arg1) \
9797 +type name(type1 arg1) \
9798 +{ \
9799 +long __res; \
9800 +register long __g1 __asm__ ("g1") = __NR_##name; \
9801 +register long __o0 __asm__ ("o0") = (long)(arg1); \
9802 +__asm__ __volatile__ ("t 0x10\n\t" \
9803 +                     "bcc 1f\n\t" \
9804 +                     "mov %%o0, %0\n\t" \
9805 +                     "sub %%g0, %%o0, %0\n\t" \
9806 +                     "1:\n\t" \
9807 +                     : "=r" (__res), "=&r" (__o0) \
9808 +                     : "1" (__o0), "r" (__g1) \
9809 +                     : "cc"); \
9810 +if (__res < -255 || __res >= 0) \
9811 +       return (type) __res; \
9812 +/*errno = -__res;*/ \
9813 +return -1; \
9814 +}
9815 +
9816 +#define _syscall2(type,name,type1,arg1,type2,arg2) \
9817 +type name(type1 arg1,type2 arg2) \
9818 +{ \
9819 +long __res; \
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" \
9824 +                     "bcc 1f\n\t" \
9825 +                     "mov %%o0, %0\n\t" \
9826 +                     "sub %%g0, %%o0, %0\n\t" \
9827 +                     "1:\n\t" \
9828 +                     : "=r" (__res), "=&r" (__o0) \
9829 +                     : "1" (__o0), "r" (__o1), "r" (__g1) \
9830 +                     : "cc"); \
9831 +if (__res < -255 || __res >= 0) \
9832 +       return (type) __res; \
9833 +/*errno = -__res;*/ \
9834 +return -1; \
9835 +}
9836 +
9837 +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
9838 +type name(type1 arg1,type2 arg2,type3 arg3) \
9839 +{ \
9840 +long __res; \
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" \
9846 +                     "bcc 1f\n\t" \
9847 +                     "mov %%o0, %0\n\t" \
9848 +                     "sub %%g0, %%o0, %0\n\t" \
9849 +                     "1:\n\t" \
9850 +                     : "=r" (__res), "=&r" (__o0) \
9851 +                     : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1) \
9852 +                     : "cc"); \
9853 +if (__res < -255 || __res>=0) \
9854 +       return (type) __res; \
9855 +/*errno = -__res;*/ \
9856 +return -1; \
9857 +}
9858 +
9859 +#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
9860 +type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
9861 +{ \
9862 +long __res; \
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" \
9869 +                     "bcc 1f\n\t" \
9870 +                     "mov %%o0, %0\n\t" \
9871 +                     "sub %%g0, %%o0, %0\n\t" \
9872 +                     "1:\n\t" \
9873 +                     : "=r" (__res), "=&r" (__o0) \
9874 +                     : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__g1) \
9875 +                     : "cc"); \
9876 +if (__res < -255 || __res>=0) \
9877 +       return (type) __res; \
9878 +/*errno = -__res;*/ \
9879 +return -1; \
9880 +} 
9881 +
9882 +#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
9883 +         type5,arg5) \
9884 +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
9885 +{ \
9886 +long __res; \
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" \
9894 +                     "bcc 1f\n\t" \
9895 +                     "mov %%o0, %0\n\t" \
9896 +                     "sub %%g0, %%o0, %0\n\t" \
9897 +                     "1:\n\t" \
9898 +                     : "=r" (__res), "=&r" (__o0) \
9899 +                     : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__o4), "r" (__g1) \
9900 +                     : "cc"); \
9901 +if (__res < -255 || __res>=0) \
9902 +       return (type) __res; \
9903 +/*errno = -__res; */\
9904 +return -1; \
9905 +}
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
9909 @@ -0,0 +1,112 @@
9910 +
9911 +/*
9912 + * Various assmbly language/system dependent  hacks that are required
9913 + * so that we can minimize the amount of platform specific code.
9914 + */
9915 +#define LINUXBIN
9916 +
9917 +/*
9918 + * Define this if the system uses RELOCA.
9919 + */
9920 +#define ELF_USES_RELOCA
9921 +
9922 +/*
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.
9927 + */
9928 +#define GET_ARGV(ARGVP, ARGS) __asm__("\tadd %%fp,68,%0\n" : "=r" (ARGVP));
9929 +
9930 +/*
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
9933 + * look like:
9934 + *
9935 + *             save %sp, -64, %sp
9936 + *             call _dl_linux_resolve
9937 + *             nop
9938 + *             .word implementation_dependent
9939 + */
9940 +#define INIT_GOT(GOT_BASE,MODULE) \
9941 +{                              \
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;                                 \
9946 +}
9947 +
9948 +/*
9949 + * Here is a macro to perform a relocation.  This is only used when
9950 + * bootstrapping the dynamic loader.
9951 + */
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;             \
9956 +         break;                                        \
9957 +       case R_SPARC_GLOB_DAT:                          \
9958 +         *REL = SYMBOL + (RELP)->r_addend;             \
9959 +         break;                                        \
9960 +       case R_SPARC_JMP_SLOT:                          \
9961 +         REL[1] = 0x03000000 | ((SYMBOL >> 10) & 0x3fffff);    \
9962 +         REL[2] = 0x81c06000 | (SYMBOL & 0x3ff);       \
9963 +         break;                                        \
9964 +       case R_SPARC_NONE:                              \
9965 +         break;                                        \
9966 +        case R_SPARC_WDISP30:                          \
9967 +          break;                                        \
9968 +       case R_SPARC_RELATIVE:                          \
9969 +         *REL += (unsigned int) LOAD + (RELP)->r_addend; \
9970 +         break;                                        \
9971 +       default:                                        \
9972 +         _dl_exit(1);                                  \
9973 +       }
9974 +
9975 +
9976 +/*
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.
9980 + */
9981 +
9982 +#define START()                \
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")
9989 +
9990 +
9991 +
9992 +/* Here we define the magic numbers that this dynamic loader should accept */
9993 +
9994 +#define MAGIC1 EM_SPARC
9995 +#undef  MAGIC2
9996 +/* Used for error messages */
9997 +#define ELF_TARGET "Sparc"
9998 +
9999 +#ifndef COMPILE_ASM
10000 +extern unsigned int _dl_linux_resolver(unsigned int reloc_entry,
10001 +                                       unsigned int * i);
10002 +#endif
10003 +
10004 +/*
10005 + * Define this if you want a dynamic loader that works on Solaris.
10006 + */
10007 +#define SOLARIS_COMPATIBLE
10008 +
10009 +#define do_rem(result, n, base)            result = (n % base)
10010 +
10011 +/*
10012 + * dbx wants the binder to have a specific name.  Mustn't disappoint it.
10013 + */
10014 +#ifdef SOLARIS_COMPATIBLE
10015 +#define _dl_linux_resolve _elf_rtbndr
10016 +#endif
10017 +
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
10025 @@ -0,0 +1,25 @@
10026 +/*
10027 + * These are various helper routines that are needed to run an ELF image.
10028 + */
10029 +#define COMPILE_ASM
10030 +#include "ld_sysdep.h"
10031 +
10032 +.text
10033 +       .align 16
10034 +
10035 +.globl _dl_linux_resolve
10036 +_dl_linux_resolve:
10037 +       /*
10038 +        * Call the resolver - pass the address of the PLT so that we can
10039 +        * figure out which module we are in.
10040 +        */
10041 +       mov %o7,%o1
10042 +       call  _dl_linux_resolver
10043 +       mov %g1,%o0
10044 +
10045 +       jmpl %o0,%o7
10046 +       restore
10047 +.LFE2:
10048 +
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
10054 @@ -0,0 +1,2 @@
10055 +libdl.so*
10056 +
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
10060 @@ -0,0 +1,86 @@
10061 +# Makefile for uClibc
10062 +#
10063 +# Copyright (C) 2000 by Lineo, inc.
10064 +# Copyright (C) 2000-2002 Erik Andersen <andersen@uclibc.org>
10065 +#
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
10069 +# later version.
10070 +#
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
10074 +# details.
10075 +#
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
10079 +
10080 +
10081 +TOPDIR=../../
10082 +include $(TOPDIR)Rules.mak
10083 +
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
10087 +
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
10092 +endif
10093 +
10094 +XXFLAGS+=$(shell $(CC) -print-search-dirs | sed -ne "s/install: *\(.*\)/-I\1include/gp")
10095 +XXFLAGS_NOPIC:=$(XXFLAGS)
10096 +ifeq ($(DOPIC),y)
10097 +    XXFLAGS += $(PICFLAG) -D__LIBDL_SHARED__
10098 +endif
10099 +ifeq ($(strip $(SUPPORT_LD_DEBUG)),y)
10100 +XXFLAGS+=-D__SUPPORT_LD_DEBUG__
10101 +endif
10102 +
10103 +LIBDL=libdl.a
10104 +LIBDL_PIC=libdl_pic.a
10105 +LIBDL_SHARED=libdl.so
10106 +LIBDL_SHARED_FULLNAME=libdl-$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBLEVEL).so
10107 +
10108 +CSRC=dlib.c
10109 +OBJS=dlib.o
10110 +PIC_OBJS=dlib_pic.o
10111 +
10112 +all: $(OBJS) $(LIBDL) shared
10113 +
10114 +$(LIBDL): ar-target
10115 +
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
10122 +
10123 +
10124 +dlib.o: dlib.c
10125 +       $(CC) $(XXFLAGS_NOPIC) -c dlib.c -o dlib.o
10126 +       $(STRIPTOOL) -x -R .note -R .comment $*.o
10127 +
10128 +dlib_pic.o: dlib.c
10129 +       $(CC) $(XXFLAGS) -c dlib.c -o dlib_pic.o
10130 +       $(STRIPTOOL) -x -R .note -R .comment $*.o
10131 +
10132 +$(OBJ): Makefile
10133 +
10134 +shared:
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)
10144 +
10145 +clean:
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
10150 @@ -0,0 +1,664 @@
10151 +/*
10152 + * libdl.c
10153 + * 
10154 + * Functions required for dlopen et. al.
10155 + */
10156 +
10157 +#include <ldso.h>
10158 +
10159 +
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);
10167 +
10168 +
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)
10175 +{
10176 +       const char msg[]="libdl library not correctly linked\n";
10177 +       _dl_write(2, msg, _dl_strlen(msg));
10178 +       _dl_exit(1);
10179 +}
10180 +
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")));
10193 +#ifdef __mips__
10194 +extern void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt)
10195 +       __attribute__ ((__weak__, __alias__ ("foobar")));
10196 +#endif
10197 +#ifdef USE_CACHE
10198 +int _dl_map_cache(void) __attribute__ ((__weak__, __alias__ ("foobar")));
10199 +int _dl_unmap_cache(void) __attribute__ ((__weak__, __alias__ ("foobar")));
10200 +#endif 
10201 +
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")));
10217 +#endif
10218 +
10219 +#else  /* __LIBDL_SHARED__ */
10220 +
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;
10230 +#endif
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);
10241 +#endif
10242 +
10243 +static int do_dlclose(void *, int need_fini);
10244 +
10245 +
10246 +static const char *dl_error_names[] = {
10247 +       "",
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",
10257 +#else
10258 +       "Unrecognized binary type",
10259 +#endif
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",
10265 +#else
10266 +       "Unable to process RELA relocs",
10267 +#endif
10268 +       "Bad handle",
10269 +       "Unable to resolve symbol"
10270 +};
10271 +
10272 +static void __attribute__ ((destructor)) dl_cleanup(void)
10273 +{
10274 +       struct dyn_elf *d;
10275 +
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;
10280 +               }
10281 +}
10282 +
10283 +void *_dlopen(const char *libname, int flag)
10284 +{
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;
10289 +       ElfW(Addr) from;
10290 +       struct elf_resolve *tpnt1;
10291 +       void (*dl_brk) (void);
10292 +
10293 +       /* A bit of sanity checking... */
10294 +       if (!(flag & (RTLD_LAZY|RTLD_NOW))) {
10295 +               _dl_error_number = LD_BAD_HANDLE;
10296 +               return NULL;
10297 +       }
10298 +
10299 +       from = (ElfW(Addr)) __builtin_return_address(0);
10300 +
10301 +       /* Have the dynamic linker use the regular malloc function now */
10302 +       if (!dl_init) {
10303 +               dl_init++;
10304 +               _dl_malloc_function = malloc;
10305 +       }
10306 +
10307 +       /* Cover the trivial case first */
10308 +       if (!libname)
10309 +               return _dl_symbol_tables;
10310 +
10311 +       _dl_map_cache();
10312 +
10313 +       /*
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
10319 +        * in the future.
10320 +        */
10321 +       tfrom = NULL;
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))
10326 +                       tfrom = tpnt;
10327 +       }
10328 +
10329 +       /* Try to load the specified library */
10330 +#ifdef __SUPPORT_LD_DEBUG__
10331 +       if(_dl_debug) 
10332 +       _dl_dprintf(_dl_debug_file, "Trying to dlopen '%s'\n", (char*)libname);
10333 +#endif
10334 +       tpnt = _dl_load_shared_library(0, &rpnt, tfrom, (char*)libname);
10335 +       if (tpnt == NULL) {
10336 +               _dl_unmap_cache();
10337 +               return NULL;
10338 +       }
10339 +
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;
10346 +
10347 +       dyn_chain->next_handle = _dl_handles;
10348 +       _dl_handles = rpnt = dyn_chain;
10349 +
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;
10355 +       }
10356 +
10357 +
10358 +#ifdef __SUPPORT_LD_DEBUG__
10359 +       if(_dl_debug) 
10360 +       _dl_dprintf(_dl_debug_file, "Looking for needed libraries\n");
10361 +#endif
10362 +
10363 +       for (tcurr = tpnt; tcurr; tcurr = tcurr->next)
10364 +       {
10365 +               Elf32_Dyn *dpnt;
10366 +               char *lpntstr;
10367 +               for (dpnt = (Elf32_Dyn *) tcurr->dynamic_addr; dpnt->d_tag; dpnt++) {
10368 +                       if (dpnt->d_tag == DT_NEEDED) {
10369 +
10370 +                               char *name;
10371 +                               lpntstr = (char*) (tcurr->loadaddr + tcurr->dynamic_info[DT_STRTAB] + 
10372 +                                       dpnt->d_un.d_val);
10373 +                               name = _dl_get_last_path_component(lpntstr);
10374 +
10375 +#ifdef __SUPPORT_LD_DEBUG__
10376 +                               if(_dl_debug) 
10377 +                               _dl_dprintf(_dl_debug_file, "Trying to load '%s', needed by '%s'\n", 
10378 +                                               lpntstr, tcurr->libname);
10379 +#endif
10380 +
10381 +                               if (!(tpnt1 = _dl_load_shared_library(0, &rpnt, tcurr, lpntstr))) {
10382 +                                       goto oops;
10383 +                               }
10384 +
10385 +#if 1
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;
10390 +#endif
10391 +
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;
10397 +
10398 +                       }
10399 +               }
10400 +       }
10401 +
10402 +       /*
10403 +        * OK, now attach the entire chain at the end
10404 +        */
10405 +       rpnt->next = _dl_symbol_tables;
10406 +
10407 +#ifdef __mips__
10408 +       /*
10409 +        * Relocation of the GOT entries for MIPS have to be done
10410 +        * after all the libraries have been loaded.
10411 +        */
10412 +       _dl_perform_mips_global_got_relocations(tpnt);
10413 +#endif
10414 +
10415 +#ifdef __SUPPORT_LD_DEBUG__
10416 +       if(_dl_debug) 
10417 +       _dl_dprintf(_dl_debug_file, "Beginning dlopen relocation fixups\n");
10418 +#endif
10419 +       /*
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))
10425 +               goto oops;
10426 +
10427 +#ifdef __SUPPORT_LD_DEBUG__
10428 +       if(_dl_debug) 
10429 +       _dl_dprintf(_dl_debug_file, "Beginning dlopen copy fixups\n");
10430 +#endif
10431 +       if (_dl_symbol_tables) {
10432 +               if (_dl_copy_fixups(dyn_chain))
10433 +                       goto oops;
10434 +       }
10435 +
10436 +
10437 +       /* TODO:  Should we set the protections of all pages back to R/O now ? */
10438 +       
10439 +
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;
10446 +                       (*dl_brk) ();
10447 +
10448 +                       _dl_debug_addr->r_state = RT_CONSISTENT;
10449 +                       (*dl_brk) ();
10450 +               }
10451 +       }
10452 +
10453 +#if 0 //def __SUPPORT_LD_DEBUG__
10454 +       if(_dl_debug) 
10455 +       _dlinfo();
10456 +#endif
10457 +
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)
10461 +           ;
10462 +
10463 +       /* Run the ctors and set up the dtors */
10464 +       for (; tpnt != dyn_chain->dyn->prev; tpnt=tpnt->prev)
10465 +       {
10466 +               /* Apparently crt1 for the application is responsible for handling this.
10467 +                * We only need to run the init/fini for shared libraries
10468 +                */
10469 +               if (tpnt->libtype == program_interpreter)
10470 +                       continue;
10471 +               if (tpnt->libtype == elf_executable)
10472 +                       continue;
10473 +               if (tpnt->init_flag & INIT_FUNCS_CALLED)
10474 +                       continue;
10475 +               tpnt->init_flag |= INIT_FUNCS_CALLED;
10476 +
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__
10482 +                       if(_dl_debug) 
10483 +                       _dl_dprintf(2, "running ctors for library %s at '%x'\n", tpnt->libname, dl_elf_func);
10484 +#endif
10485 +                       (*dl_elf_func) ();
10486 +                   }
10487 +               }
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__
10493 +                       if(_dl_debug) 
10494 +                       _dl_dprintf(2, "setting up dtors for library %s at '%x'\n", tpnt->libname, dl_elf_func);
10495 +#endif
10496 +                       atexit(dl_elf_func);
10497 +                   }
10498 +               }
10499 +       }
10500 +#endif
10501 +       return (void *) dyn_chain;
10502 +
10503 +oops:
10504 +       /* Something went wrong.  Clean up and return NULL. */
10505 +       _dl_unmap_cache();
10506 +       do_dlclose(dyn_chain, 0);
10507 +       return NULL;
10508 +}
10509 +
10510 +void *_dlsym(void *vhandle, const char *name)
10511 +{
10512 +       struct elf_resolve *tpnt, *tfrom;
10513 +       struct dyn_elf *handle;
10514 +       ElfW(Addr) from;
10515 +       struct dyn_elf *rpnt;
10516 +       void *ret;
10517 +
10518 +       handle = (struct dyn_elf *) vhandle;
10519 +
10520 +       /* First of all verify that we have a real handle
10521 +          of some kind.  Return NULL if not a valid handle. */
10522 +
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)
10528 +                               break;
10529 +               if (!rpnt) {
10530 +                       _dl_error_number = LD_BAD_HANDLE;
10531 +                       return NULL;
10532 +               }
10533 +       } else if (handle == RTLD_NEXT) {
10534 +               /*
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.
10540 +                */
10541 +               from = (ElfW(Addr)) __builtin_return_address(0);
10542 +
10543 +               tfrom = NULL;
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)) {
10548 +                               tfrom = tpnt;
10549 +                               handle = rpnt->next;
10550 +                       }
10551 +               }
10552 +       }
10553 +
10554 +       ret = _dl_find_hash((char*)name, handle, NULL, copyrel);
10555 +
10556 +       /*
10557 +        * Nothing found.
10558 +        */
10559 +       if (!ret)
10560 +               _dl_error_number = LD_NO_SYMBOL;
10561 +       return ret;
10562 +}
10563 +
10564 +int _dlclose(void *vhandle)
10565 +{
10566 +       return do_dlclose(vhandle, 1);
10567 +}
10568 +
10569 +static int do_dlclose(void *vhandle, int need_fini)
10570 +{
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;
10579 +       int i = 0;
10580 +
10581 +       handle = (struct dyn_elf *) vhandle;
10582 +       rpnt1 = NULL;
10583 +       for (rpnt = _dl_handles; rpnt; rpnt = rpnt->next_handle) {
10584 +               if (rpnt == handle) {
10585 +                       break;
10586 +               }
10587 +               rpnt1 = rpnt;
10588 +       }
10589 +
10590 +       if (!rpnt) {
10591 +               _dl_error_number = LD_BAD_HANDLE;
10592 +               return 1;
10593 +       }
10594 +
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;
10600 +
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)
10604 +                       break;
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
10610 +                        */
10611 +
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) ();
10616 +                       }
10617 +               }
10618 +       }
10619 +       if (rpnt1)
10620 +               rpnt1->next_handle = rpnt->next_handle;
10621 +       else
10622 +               _dl_handles = rpnt->next_handle;
10623 +
10624 +       /* OK, this is a valid handle - now close out the file */
10625 +       for (rpnt = handle; rpnt; rpnt = rpnt1) {
10626 +               rpnt1 = rpnt->next;
10627 +
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)
10631 +                       break;
10632 +
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
10639 +                        */
10640 +#if 0
10641 +
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) ();
10648 +                       }
10649 +#endif
10650 +                       end = 0;
10651 +                       for (i = 0, ppnt = rpnt->dyn->ppnt;
10652 +                                i < rpnt->dyn->n_phent; ppnt++, i++) {
10653 +                               if (ppnt->p_type != PT_LOAD)
10654 +                                       continue;
10655 +                               if (end < ppnt->p_vaddr + ppnt->p_memsz)
10656 +                                       end = ppnt->p_vaddr + ppnt->p_memsz;
10657 +                       }
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;
10664 +                       } else
10665 +                               for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next)
10666 +                                       if (tpnt->next == rpnt->dyn) {
10667 +                                               tpnt->next = tpnt->next->next;
10668 +                                               if (tpnt->next)
10669 +                                                       tpnt->next->prev = tpnt;
10670 +                                               break;
10671 +                                       }
10672 +                       free(rpnt->dyn->libname);
10673 +                       free(rpnt->dyn);
10674 +               }
10675 +               free(rpnt);
10676 +       }
10677 +
10678 +
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;
10683 +               (*dl_brk) ();
10684 +
10685 +               _dl_debug_addr->r_state = RT_CONSISTENT;
10686 +               (*dl_brk) ();
10687 +           }
10688 +       }
10689 +
10690 +       return 0;
10691 +}
10692 +
10693 +const char *_dlerror(void)
10694 +{
10695 +       const char *retval;
10696 +
10697 +       if (!_dl_error_number)
10698 +               return NULL;
10699 +       retval = dl_error_names[_dl_error_number];
10700 +       _dl_error_number = 0;
10701 +       return retval;
10702 +}
10703 +
10704 +/*
10705 + * Dump information to stderrr about the current loaded modules
10706 + */
10707 +static char *type[] = { "Lib", "Exe", "Int", "Mod" };
10708 +
10709 +void _dlinfo(void)
10710 +{
10711 +       struct elf_resolve *tpnt;
10712 +       struct dyn_elf *rpnt, *hpnt;
10713 +
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);
10722 +       }
10723 +
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);
10729 +
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);
10735 +       }
10736 +}
10737 +
10738 +int _dladdr(void *__address, Dl_info * __dlip)
10739 +{
10740 +       struct elf_resolve *pelf;
10741 +       struct elf_resolve *rpnt;
10742 +
10743 +       _dl_map_cache();
10744 +
10745 +       /*
10746 +        * Try and locate the module address is in
10747 +        */
10748 +       pelf = NULL;
10749 +
10750 +#if 0
10751 +       _dl_dprintf(2, "dladdr( %x, %x )\n", __address, __dlip);
10752 +#endif
10753 +
10754 +       for (rpnt = _dl_loaded_modules; rpnt; rpnt = rpnt->next) {
10755 +               struct elf_resolve *tpnt;
10756 +
10757 +               tpnt = rpnt;
10758 +#if 0
10759 +               _dl_dprintf(2, "Module \"%s\" at %x\n", 
10760 +                       tpnt->libname, tpnt->loadaddr);
10761 +#endif
10762 +               if (tpnt->loadaddr < (ElfW(Addr)) __address
10763 +                       && (pelf == NULL || pelf->loadaddr < tpnt->loadaddr)) {
10764 +                   pelf = tpnt;
10765 +               }
10766 +       }
10767 +
10768 +       if (!pelf) {
10769 +               return 0;
10770 +       }
10771 +
10772 +       /*
10773 +        * Try and locate the symbol of address
10774 +        */
10775 +
10776 +       {
10777 +               char *strtab;
10778 +               Elf32_Sym *symtab;
10779 +               int hn, si;
10780 +               int sf;
10781 +               int sn = 0;
10782 +               ElfW(Addr) sa;
10783 +
10784 +               sa = 0;
10785 +               symtab = (Elf32_Sym *) (pelf->dynamic_info[DT_SYMTAB] + pelf->loadaddr);
10786 +               strtab = (char *) (pelf->dynamic_info[DT_STRTAB] + pelf->loadaddr);
10787 +
10788 +               sf = 0;
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;
10792 +
10793 +                               symbol_addr = pelf->loadaddr + symtab[si].st_value;
10794 +                               if (symbol_addr <= (ElfW(Addr))__address && (!sf || sa < symbol_addr)) {
10795 +                                       sa = symbol_addr;
10796 +                                       sn = si;
10797 +                                       sf = 1;
10798 +                               }
10799 +#if 0
10800 +                               _dl_dprintf(2, "Symbol \"%s\" at %x\n", 
10801 +                                       strtab + symtab[si].st_name, symbol_addr);
10802 +#endif
10803 +                       }
10804 +               }
10805 +
10806 +               if (sf) {
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;
10811 +               }
10812 +               return 1;
10813 +       }
10814 +}
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
10818 @@ -0,0 +1,33 @@
10819 +# Makefile for uClibc
10820 +#
10821 +# Copyright (C) 2000,2001 Erik Andersen <andersen@uclibc.org>
10822 +#
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
10826 +# later version.
10827 +#
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
10831 +# details.
10832 +#
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
10836 +#
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.
10840 +
10841 +include ../Config.mk
10842 +
10843 +ALL = #ld.so.info
10844 +
10845 +all:   $(ALL)
10846 +
10847 +ld.so.info: ld.so.texi
10848 +       makeinfo $<
10849 +
10850 +clean:
10851 +       $(RM) $(ALL) *~
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
10855 @@ -0,0 +1,218 @@
10856 +.\" -*- nroff -*-
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).
10860 +.\"
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.
10865 +.\"
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.
10870 +.\"
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.
10875 +.\"
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,
10879 +.\" USA.
10880 +.\"
10881 +.TH DLOPEN 3 "16 May 1995" "Linux" "Linux Programmer's Manual"
10882 +.SH NAME
10883 +dlclose, dlerror, dlopen, dlsym \- Programming interface to dynamic linking loader.
10884 +.SH SYNOPSIS
10885 +.B #include <dlfcn.h>
10886 +.sp
10887 +.BI "void *dlopen (const char *" "filename" ", int " flag ");
10888 +.br
10889 +.BI "const char *dlerror(void);"
10890 +.br
10891 +.BI "void *dlsym(void *"handle ", char *"symbol ");"
10892 +.br
10893 +.BI "int dladdr(void *"address ", Dl_info *"dlip ");"
10894 +.br
10895 +.BI "int dlclose (void *"handle ");
10896 +.sp
10897 +Special symbols:
10898 +.BR "_init" ", " "_fini" ". "
10899 +.SH DESCRIPTION
10900 +.B dlopen
10901 +loads a dynamic library from the file named by the null terminated
10902 +string
10903 +.I filename
10904 +and returns an opaque "handle" for the dynamic library.
10905 +If
10906 +.I filename
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:
10909 +.RS
10910 +.PP
10911 +A colon-separated list of directories in the user's
10912 +\fBLD_LIBRARY\fP path environment variable.
10913 +.PP
10914 +The list of libraries specified in \fI/etc/ld.so.cache\fP.
10915 +.PP
10916 +\fI/usr/lib\fP, followed by \fI/lib\fP.
10917 +.RE
10918 +.PP
10919 +If
10920 +.I filename
10921 +is a NULL pointer, then the returned handle is for the main program.
10922 +.PP
10923 +External references in the library are resolved using the libraries
10924 +in that library's dependency list and any other libraries previously
10925 +opened with the 
10926 +.B RTLD_GLOBAL
10927 +flag.
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
10931 +library.
10932 +.PP
10933 +.I flag
10934 +must be either
10935 +.BR RTLD_LAZY ,
10936 +meaning resolve undefined symbols as code from the dynamic library is
10937 +executed, or
10938 +.BR RTLD_NOW ,
10939 +meaning resolve all undefined symbols before
10940 +.B dlopen
10941 +returns, and fail if this cannot be done.
10942 +Optionally,
10943 +.B RTLD_GLOBAL
10944 +may be or'ed with
10945 +.IR flag,
10946 +in which case the external symbols defined in the library will be
10947 +made available to subsequently loaded libraries.
10948 +.PP
10949 +If the library exports a routine named
10950 +.BR _init ,
10951 +then that code is executed before dlopen returns.
10952 +If the same library is loaded twice with
10953 +.BR dlopen() ,
10954 +the same file handle is returned.  The dl library maintains link
10955 +counts for dynamic file handles, so a dynamic library is not
10956 +deallocated until
10957 +.B dlclose
10958 +has been called on it as many times as
10959 +.B dlopen
10960 +has succeeded on it.
10961 +.PP
10962 +If
10963 +.B dlopen
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
10967 +extracted with
10968 +.BR dlerror() .
10969 +.B dlerror
10970 +returns NULL if no errors have occurred since initialization or since
10971 +it was last called.  (Calling
10972 +.B dlerror()
10973 +twice consecutively, will always result in the second call returning
10974 +NULL.)
10975 +
10976 +.B dlsym
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,
10980 +.B dlsym
10981 +returns NULL; however, the correct way to test for an error from
10982 +.B dlsym
10983 +is to save the result of
10984 +.B dlerror
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
10988 +.B dlerror
10989 +into a variable because if
10990 +.B dlerror
10991 +is called again, it will return NULL.
10992 +.PP
10993 +.B dladdr
10994 +returns information about the shared library containing the memory 
10995 +location specified by
10996 +.IR address .
10997 +.B dladdr
10998 +returns zero on success and non-zero on error.
10999 +.PP
11000 +.B dlclose
11001 +decrements the reference count on the dynamic library handle
11002 +.IR 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
11006 +.BR _fini ,
11007 +then that routine is called just before the library is unloaded.
11008 +.SH EXAMPLES
11009 +.B Load the math library, and print the cosine of 2.0:
11010 +.RS
11011 +.nf
11012 +.if t .ft CW
11013 +#include <dlfcn.h>
11014 +
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));
11019 +    dlclose(handle);
11020 +}
11021 +.if t .ft P
11022 +.fi
11023 +.PP
11024 +If this program were in a file named "foo.c", you would build the program
11025 +with the following command:
11026 +.RS
11027 +.LP
11028 +gcc -rdynamic -o foo foo.c -ldl
11029 +.RE
11030 +.RE
11031 +.LP
11032 +.B Do the same thing, but check for errors at every step:
11033 +.RS
11034 +.nf
11035 +.if t .ft CW
11036 +#include <stdio.h>
11037 +#include <dlfcn.h>
11038 +
11039 +int main(int argc, char **argv) {
11040 +    void *handle;
11041 +    double (*cosine)(double);
11042 +    char *error;
11043 +
11044 +    handle = dlopen ("/lib/libm.so", RTLD_LAZY);
11045 +    if (!handle) {
11046 +        fputs (dlerror(), stderr);
11047 +        exit(1);
11048 +    }
11049 +
11050 +    cosine = dlsym(handle, "cos");
11051 +    if ((error = dlerror()) != NULL)  {
11052 +        fputs(error, stderr);
11053 +        exit(1);
11054 +    }
11055 +
11056 +    printf ("%f\\n", (*cosine)(2.0));
11057 +    dlclose(handle);
11058 +}
11059 +.if t .ft P
11060 +.fi
11061 +.RE
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.
11068 +.SH SEE ALSO
11069 +.BR ld(1) ,
11070 +.BR ld.so(8) ,
11071 +.BR ldconfig(8) ,
11072 +.BR ldd(1) ,
11073 +.BR ld.so.info .
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
11077 @@ -0,0 +1,113 @@
11078 +.TH ld.so 8 "14 March 1998"
11079 +.SH NAME
11080 +ld.so/ld-linux.so \- dynamic linker/loader
11081 +.SH DESCRIPTION
11082 +.B ld.so
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
11086 +.B \-static
11087 +option to
11088 +.B ld
11089 +during compilation, all Linux programs are incomplete and require 
11090 +further linking at run time.
11091 +.PP
11092 +The necessary shared libraries needed by the program are searched for 
11093 +in the following order
11094 +.IP o
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
11100 +is ignored.
11101 +.IP o
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.
11106 +.IP o
11107 +In the default path
11108 +.BR /usr/lib ,
11109 +and then
11110 +.BR /lib .
11111 +.SH ENVIRONMENT
11112 +.TP
11113 +.B LD_LIBRARY_PATH
11114 +A colon-separated list of directories in which to search for
11115 +ELF libraries at execution-time.
11116 +Similar to the 
11117 +.B PATH
11118 +environment variable.
11119 +.TP
11120 +.B LD_PRELOAD
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.
11126 +.TP
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.
11130 +.TP
11131 +.B LD_BIND_NOW
11132 +If present, causes the dynamic linker to resolve all symbols at program
11133 +startup instead of when they are first referenced.
11134 +.TP
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.
11138 +Similar to the 
11139 +.B PATH
11140 +environment variable.
11141 +.TP
11142 +.B LD_AOUT_PRELOAD
11143 +The name of an additional, user-specified, a.out shared library to be loaded 
11144 +after all others.
11145 +This can be used to selectively override functions in other shared libraries.
11146 +.TP
11147 +.B LD_NOWARN
11148 +Suppress warnings about a.out libraries with incompatible minor 
11149 +version numbers.
11150 +.TP
11151 +.B LD_KEEPDIR
11152 +Don't ignore the directory in the names of a.out libraries to be loaded.
11153 +Use of this option is strongly discouraged.
11154 +.SH FILES
11155 +.PD 0
11156 +.TP 20
11157 +.B /lib/ld.so
11158 +a.out dynamic linker/loader
11159 +.TP 20
11160 +.B /lib/ld-linux.so.*
11161 +ELF dynamic linker/loader
11162 +.TP
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.
11166 +.TP
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.
11171 +.TP
11172 +.B lib*.so*
11173 +shared libraries
11174 +.PD
11175 +.SH SEE ALSO
11176 +.BR ldd (1),
11177 +.BR ldconfig (8).
11178 +.SH BUGS
11179 +.LP
11180 +Currently
11181 +.B ld.so
11182 +has no means of unloading and searching for compatible or newer version of
11183 +libraries.
11184 +.PP
11185 +.B ld.so
11186 +functionality is only available for executables compiled using libc version
11187 +4.4.3 or greater.
11188 +.SH AUTHORS
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
11194 @@ -0,0 +1,411 @@
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
11200 +
11201 +@ifinfo
11202 +This file documents the dynamic-link support libraries and utilities for the
11203 +Linux OS, version 1.8.1.
11204 +
11205 +Copyright 1996 Michael Deutschmann
11206 +
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).
11209 +
11210 +Note: The software described in this document is under a different copyright
11211 +and license.
11212 +
11213 +@end ifinfo
11214 +
11215 +@titlepage 
11216 +@title ld.so
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)
11224 +
11225 +@page
11226 +Copyright @copyright{} 1996 Michael Deutschmann
11227 +
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).
11230 +
11231 +Note: The software described in this document is under a different copyright
11232 +and license.
11233 +@end titlepage
11234 +
11235 +@ifinfo
11236 +@node Top
11237 +@top
11238 +
11239 +The @code{ld.so} module provides dynamic linked library support in Linux.
11240 +This file documents @code{ld.so} and its companion software.
11241 +
11242 +@menu
11243 +* intro::      Introduction
11244 +
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
11249 +@end menu
11250 +
11251 +@end ifinfo
11252 +
11253 +@node intro
11254 +@unnumbered Introduction
11255 +
11256 +The @code{ld.so} suite contains special files and utilities needed for linux
11257 +to handle @dfn{dynamic libraries}.
11258 +
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.
11265 +
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
11272 +shared libraries.
11273 +
11274 +Linux executables come in two flavors, @sc{elf} and a.out.
11275 +
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 
11279 +registered.
11280
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
11283 +(@pxref{libdl}).
11284 +
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.)
11289 +
11290 +@node ld.so
11291 +@chapter @code{ld.so}: Dynamic linker core
11292 +
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.
11298 +
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}.
11301 +
11302 +@menu
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
11306 +@end menu
11307 +
11308 +@node files
11309 +@section Configuration Files
11310 +
11311 +@table @file
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.
11315 +
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{#}.
11320 +
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. 
11324 +@end table
11325 +
11326 +@node environment
11327 +@section Environment Variables
11328 +
11329 +@table @code
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}.
11337 +
11338 +@item LD_AOUT_PRELOAD
11339 +@itemx LD_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}.
11345 +
11346 +@item LD_NOWARN
11347 +If non-empty, errors about incompatible minor revisions are suppressed.
11348 +
11349 +@item LD_KEEPDIR
11350 +If non-empty, allow executables to specify absolute library names. This
11351 +option is deprecated.
11352 +@c FIXME:
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?
11355 +@c
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.)
11360 +@c 
11361 +@c @item LD_TRACE_LOADED_OBJECTS
11362 +@c @itemx LD_WARN
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.
11365 +@end table
11366 +
11367 +@node errors
11368 +@section Errors
11369 +
11370 +@table @samp
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.
11375 +
11376 +@item Can't load library @var{library}
11377 +The library is corrupt. 
11378 +
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.
11383 +
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.
11391 +
11392 +@item too many directories in library path
11393 +The linker only supports up to 32 library directories. You have too many.
11394 +
11395 +@item dynamic linker error in @var{blah}
11396 +The linker is having trouble handling a binary - it is probably corrupt.
11397 +
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}.
11403 +@end table
11404 +
11405 +@node ldd
11406 +@chapter @code{ldd}: Dependency scanner
11407 +
11408 +@code{ldd} is a utility that prints out the dynamic libraries that an
11409 +executable is linked to. 
11410 +
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}.)
11416 +
11417 +For @sc{elf} executables, special environment variables are used to tell the
11418 +linker to print the dependencies.
11419 +
11420 +@code{ldd} has a few options:
11421 +
11422 +@table @samp
11423 +@item -v
11424 +Print the version number of @code{ldd} itself
11425 +
11426 +@item -V
11427 +Print the version number of the dynamic linker
11428 +
11429 +@item -d
11430 +Report missing functions. This is only supported for @sc{elf} executables.
11431 +
11432 +@item -r
11433 +Report missing objects. This is also only available for @sc{elf}
11434 +executables.
11435 +@end table
11436 +
11437 +@node ldconfig
11438 +@chapter @code{ldconfig}: Setup program 
11439 +
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.
11442 +
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.
11446 +
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.
11450 +
11451 +It has the following options:
11452 +
11453 +@table @samp
11454 +@item -D
11455 +Enter debug mode. Implies @samp{-N} and @samp{-X}.
11456 +
11457 +@item -v
11458 +Verbose. Print out links created and directories scanned.
11459 +
11460 +@item -n 
11461 +Check directories specified on the commandline @emph{only}.
11462 +
11463 +@item -N
11464 +Do not regenerate the cache.
11465 +
11466 +@item -X
11467 +Do not rebuild symbolic links.
11468 +
11469 +@item -l
11470 +Set up symbolic links for only libraries presented on the command line.
11471 +
11472 +@item -p
11473 +Print out the library pathnames in the cache file (@file{/etc/ld.so.cache})
11474 +@end table
11475 +
11476 +@node libdl
11477 +@chapter User dynamic linking library
11478 +
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.
11484 +
11485 +@menu
11486 +* using libdl::        General points
11487 +* functions::  How to use the functions
11488 +* example::    A sample program
11489 +@end menu
11490 +
11491 +@node using libdl
11492 +@section Overview
11493 +
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.
11498 +
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.
11502 +
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.
11509 +
11510 +@node functions
11511 +@section Functions
11512 +
11513 +@deftypefun void *dlopen ( const char @var{filename}, int @var{flags} )
11514 +
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.
11519 +
11520 +@end deftypefun
11521 +
11522 +The following flags can be used with @code{dlopen}:
11523 +
11524 +@deftypevr Macro int RTLD_LAZY
11525 +Resolve symbols in the library as they are needed.
11526 +@end deftypevr
11527 +
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}.
11531 +@end deftypevr
11532 +
11533 +@deftypevr Macro int RTLD_GLOBAL
11534 +Make symbols in this library available for resolving symbols in other
11535 +libraries loaded with @code{dlopen}.
11536 +@end deftypevr
11537 +
11538 +@deftypefun int dlclose ( void *@var{handle} )
11539 +
11540 +This function releases a library handle.
11541 +
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.
11545 +
11546 +@end deftypefun
11547 +
11548 +@deftypefun void *dlsym (void *@var{handle},char *@var{symbol-name})
11549 +
11550 +This function looks up the name @var{symbol-name} in the library and returns
11551 +it in the void pointer.
11552 +
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.
11556 +
11557 +@end deftypefun
11558 +
11559 +@deftypefun {libdl function} {const char} *dlerror( void )
11560 +
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.
11563 +
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.
11567 +
11568 +@end deftypefun
11569 +
11570 +@node example
11571 +@section Example program
11572 +
11573 +Here is an example program that prints the cosine of two by manually linking
11574 +to the math library:
11575
11576 +@example
11577 +@c The following was snarfed verbatim from the dlopen.3 man file.
11578 +#include <stdio.h>
11579 +#include <dlfcn.h>
11580 +
11581 +int main(int argc, char **argv) @{
11582 +    void *handle;
11583 +    double (*cosine)(double);
11584 +    char *error;
11585 +
11586 +    handle = dlopen ("/lib/libm.so", RTLD_LAZY);
11587 +    if (!handle) @{
11588 +        fputs (dlerror(), stderr);
11589 +        exit(1);
11590 +    @}
11591 +
11592 +    cosine = dlsym(handle, "cos");
11593 +    if ((error = dlerror()) != NULL)  @{
11594 +        fputs(error, stderr);
11595 +        exit(1);
11596 +    @}
11597 +
11598 +    printf ("%f\\n", (*cosine)(2.0));
11599 +    dlclose(handle);
11600 +@}
11601 +@end example
11602 +
11603 +@contents
11604 +
11605 +@bye
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
11609 @@ -0,0 +1,189 @@
11610 +.TH ldconfig 8 "14 March 1998"
11611 +.SH NAME
11612 +ldconfig \- determine run-time link bindings
11613 +.SH SYNOPSIS
11614 +ldconfig
11615 +.RB [ \-DvqnNX ]
11616 +.RB [ \-f\ conf ]
11617 +.RB [ \-C\ cache ]
11618 +.RB [ \-r\ root ]
11619 +.IR directory \ ...
11620 +.PD 0
11621 +.PP
11622 +.PD
11623 +ldconfig
11624 +.B \-l
11625 +.RB [ \-Dvq ]
11626 +.IR library \ ...
11627 +.PD 0
11628 +.PP
11629 +.PD
11630 +ldconfig
11631 +.B \-p
11632 +.SH DESCRIPTION
11633 +.B ldconfig
11634 +creates the necessary links and cache (for use by the run-time linker,
11635 +.IR ld.so )
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
11640 +.RI ( /usr/lib
11641 +and
11642 +.IR /lib ).
11643 +.B ldconfig
11644 +checks the header and file names of the libraries it encounters when
11645 +determining which versions should have their links updated.
11646 +.B ldconfig
11647 +ignores symbolic links when scanning for libraries. 
11648 +.PP
11649 +.B ldconfig
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).
11653 +.PP
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 
11658 +.B only
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 
11662 +.B not 
11663 +allowed.  Also see the 
11664 +.B -p 
11665 +option.
11666 +.PP 
11667 +Directory names containing an
11668 +.B = are no longer legal
11669 +unless they also have an expected type specifier.
11670 +.PP
11671 +.B ldconfig
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.
11676 +.SH OPTIONS
11677 +.TP
11678 +.B \-D
11679 +Debug mode.
11680 +Implies
11681 +.B \-N
11682 +and
11683 +.BR \-X .
11684 +.TP
11685 +.B \-v
11686 +Verbose mode.
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.
11690 +.TP
11691 +.B \-q
11692 +Quiet mode.
11693 +Don't print warnings.
11694 +.TP
11695 +.B \-n
11696 +Only process directories specified on the command line.
11697 +Don't process the trusted directories
11698 +.RI ( /usr/lib
11699 +and
11700 +.IR /lib )
11701 +nor those specified in
11702 +.IR /etc/ld.so.conf .
11703 +Implies
11704 +.BR \-N .
11705 +.TP
11706 +.B \-N
11707 +Don't rebuild the cache.
11708 +Unless
11709 +.B \-X
11710 +is also specified, links are still updated.
11711 +.TP
11712 +.B \-X
11713 +Don't update links.
11714 +Unless
11715 +.B \-N
11716 +is also specified, the cache is still rebuilt.
11717 +.TP
11718 +.B \-f conf
11719 +Use
11720 +.B conf
11721 +instead of
11722 +.IR /etc/ld.so.conf .
11723 +.TP
11724 +.B \-C cache
11725 +Use
11726 +.B cache
11727 +instead of
11728 +.IR /etc/ld.so.cache .
11729 +.TP
11730 +.B \-r root
11731 +Change to and use
11732 +.B root
11733 +as the root directory.
11734 +.TP
11735 +.B \-l
11736 +Library mode.
11737 +Manually link individual libraries.
11738 +Intended for use by experts only.
11739 +.TP
11740 +.B \-p
11741 +Print the lists of directories and candidate libraries stored in
11742 +the current cache.
11743 +.SH EXAMPLES
11744 +In the bootup file
11745 +.I /etc/rc
11746 +having the line
11747 +.RS
11748 +
11749 +/sbin/ldconfig -v
11750 +
11751 +.RE
11752 +will set up the correct links for the shared binaries and rebuild
11753 +the cache.
11754 +.TP
11755 +On the command line
11756 +.RS
11757 +
11758 +# /sbin/ldconfig -n /lib
11759 +
11760 +.RE
11761 +as root after the installation of a new DLL, will properly update the
11762 +shared library symbolic links in /lib.
11763 +
11764 +.SH FILES
11765 +.PD 0
11766 +.TP 20
11767 +.B /lib/ld.so
11768 +execution time linker/loader
11769 +.TP 20
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.
11773 +.TP 20
11774 +.B /etc/ld.so.cache
11775 +File containing an ordered list of libraries found in the directories
11776 +specified in
11777 +.BR /etc/ld.so.conf .
11778 +.TP
11779 +.B lib*.so.version
11780 +shared libraries
11781 +.PD
11782 +.SH SEE ALSO
11783 +.BR ldd (1),
11784 +.BR ld.so (8).
11785 +.SH BUGS
11786 +.LP
11787 +.BR ldconfig 's
11788 +functionality, in conjunction with
11789 +.BR ld.so ,
11790 +is only available for executables compiled using libc version 4.4.3 or greater.
11791 +.PP
11792 +.BR ldconfig ,
11793 +being a user process, must be run manually and has no means of dynamically
11794 +determining and relinking shared libraries for use by
11795 +.BR ld.so
11796 +when a new DLL is installed.
11797 +.SH AUTHORS
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
11802 @@ -0,0 +1,59 @@
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"
11808 +.SH NAME
11809 +ldd \- print shared library dependencies
11810 +.SH SYNOPSIS
11811 +.B ldd
11812 +.RB [ \-vVdr ]
11813 +program|library ...
11814 +.SH DESCRIPTION
11815 +.B ldd
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 '/',
11819 +.B ldd
11820 +attempts to locate the library in the standard locations.
11821 +To run
11822 +.B ldd
11823 +on a shared library in the current directory, a "./" must be prepended
11824 +to its name.
11825 +.SH OPTIONS
11826 +.TP
11827 +.B \-v
11828 +Print the version number of
11829 +.BR ldd .
11830 +.TP
11831 +.B \-V
11832 +Print the version number of the dynamic linker,
11833 +.BR ld.so .
11834 +.TP
11835 +.B \-d
11836 +Perform relocations and report any missing functions (ELF only).
11837 +.TP
11838 +.B \-r
11839 +Perform relocations for both data objects and functions, and
11840 +report any missing objects (ELF only).
11841 +.SH BUGS
11842 +.B ldd
11843 +does not work very well on libc.so.5 itself.
11844 +.PP
11845 +.B ldd
11846 +does not work on a.out shared libraries.
11847 +.PP
11848 +.B ldd
11849 +does not work with some extremely old a.out programs which were 
11850 +built before
11851 +.B ldd
11852 +support was added to the compiler releases.
11853 +If you use
11854 +.B ldd
11855 +on one of these programs, the program will attempt to run with argc = 0 and
11856 +the results will be unpredictable.
11857 +.SH AUTHOR
11858 +David Engel.
11859 +.SH SEE ALSO
11860 +.BR ldconfig (8),
11861 +.BR ld.so (8).