bump version
[buildroot.git] / toolchain / uClibc / uClibc-0.9.28-ldso.patch
blob4081fc7d1b8406c8ed9d653d4970431a42cdda92
1 diff -urN uClibc-0.9.28.orig/include/elf.h uClibc-0.9.28/include/elf.h
2 --- uClibc-0.9.28.orig/include/elf.h 2006-05-02 10:47:27.000000000 -0600
3 +++ uClibc-0.9.28/include/elf.h 2006-04-28 00:14:35.000000000 -0600
4 @@ -142,6 +142,7 @@
5 #define ELFOSABI_HPUX 1 /* HP-UX */
6 #define ELFOSABI_NETBSD 2 /* NetBSD. */
7 #define ELFOSABI_LINUX 3 /* Linux. */
8 +#define ELFOSABI_HURD 4 /* GNU/Hurd */
9 #define ELFOSABI_SOLARIS 6 /* Sun Solaris. */
10 #define ELFOSABI_AIX 7 /* IBM AIX. */
11 #define ELFOSABI_IRIX 8 /* SGI Irix. */
12 @@ -149,6 +150,9 @@
13 #define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX. */
14 #define ELFOSABI_MODESTO 11 /* Novell Modesto. */
15 #define ELFOSABI_OPENBSD 12 /* OpenBSD. */
16 +#define ELFOSABI_OPENVMS 13 /* OpenVMS */
17 +#define ELFOSABI_NSK 14 /* Hewlett-Packard Non-Stop Kernel */
18 +#define ELFOSABI_AROS 15 /* Amiga Research OS */
19 #define ELFOSABI_ARM 97 /* ARM */
20 #define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */
22 @@ -177,6 +181,7 @@
23 #define EM_386 3 /* Intel 80386 */
24 #define EM_68K 4 /* Motorola m68k family */
25 #define EM_88K 5 /* Motorola m88k family */
26 +#define EM_486 6 /* Intel 80486 *//* Reserved for future use */
27 #define EM_860 7 /* Intel 80860 */
28 #define EM_MIPS 8 /* MIPS R3000 big-endian */
29 #define EM_S370 9 /* IBM System/370 */
30 @@ -193,7 +198,8 @@
31 #define EM_V800 36 /* NEC V800 series */
32 #define EM_FR20 37 /* Fujitsu FR20 */
33 #define EM_RH32 38 /* TRW RH-32 */
34 -#define EM_RCE 39 /* Motorola RCE */
35 +#define EM_MCORE 39 /* Motorola M*Core */ /* May also be taken by Fujitsu MMA */
36 +#define EM_RCE 39 /* Old name for MCore */
37 #define EM_ARM 40 /* ARM */
38 #define EM_FAKE_ALPHA 41 /* Digital Alpha */
39 #define EM_SH 42 /* Renesas SH */
40 @@ -248,18 +254,105 @@
41 #define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */
42 #define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */
43 #define EM_XTENSA 94 /* Tensilica Xtensa Architecture */
44 +#define EM_IP2K 101 /* Ubicom IP2022 micro controller */
45 +#define EM_CR 103 /* National Semiconductor CompactRISC */
46 +#define EM_MSP430 105 /* TI msp430 micro controller */
47 +#define EM_BLACKFIN 106 /* Analog Devices Blackfin */
48 +#define EM_ALTERA_NIOS2 113 /* Altera Nios II soft-core processor */
49 +#define EM_CRX 114 /* National Semiconductor CRX */
50 #define EM_NUM 95
52 -/* If it is necessary to assign new unofficial EM_* values, please
53 - pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the
54 - chances of collision with official or non-GNU unofficial values. */
55 +/* If it is necessary to assign new unofficial EM_* values, please pick large
56 + random numbers (0x8523, 0xa7f2, etc.) to minimize the chances of collision
57 + with official or non-GNU unofficial values.
59 -/* Fujitsu FR-V. */
60 + NOTE: Do not just increment the most recent number by one.
61 + Somebody else somewhere will do exactly the same thing, and you
62 + will have a collision. Instead, pick a random number.
64 + Normally, each entity or maintainer responsible for a machine with an
65 + unofficial e_machine number should eventually ask registry@caldera.com for
66 + an officially blessed number to be added to the list above. */
68 +/* picoJava */
69 +#define EM_PJ_OLD 99
71 +/* Cygnus PowerPC ELF backend. Written in the absence of an ABI. */
72 +#define EM_CYGNUS_POWERPC 0x9025
74 +/* Old version of Sparc v9, from before the ABI; this should be
75 + removed shortly. */
76 +#define EM_OLD_SPARCV9 11
78 +/* Old version of PowerPC, this should be removed shortly. */
79 +#define EM_PPC_OLD 17
81 +/* (Deprecated) Temporary number for the OpenRISC processor. */
82 +#define EM_OR32 0x8472
84 +/* Renesas M32C and M16C. */
85 +#define EM_M32C 0xFEB0
87 +/* Cygnus M32R ELF backend. Written in the absence of an ABI. */
88 +#define EM_CYGNUS_M32R 0x9041
90 +/* old S/390 backend magic number. Written in the absence of an ABI. */
91 +#define EM_S390_OLD 0xa390
93 +/* D10V backend magic number. Written in the absence of an ABI. */
94 +#define EM_CYGNUS_D10V 0x7650
96 +/* D30V backend magic number. Written in the absence of an ABI. */
97 +#define EM_CYGNUS_D30V 0x7676
99 +/* V850 backend magic number. Written in the absense of an ABI. */
100 +#define EM_CYGNUS_V850 0x9080
102 +/* mn10200 and mn10300 backend magic numbers.
103 + Written in the absense of an ABI. */
104 +#define EM_CYGNUS_MN10200 0xdead
105 +#define EM_CYGNUS_MN10300 0xbeef
107 +/* FR30 magic number - no EABI available. */
108 +#define EM_CYGNUS_FR30 0x3330
110 +/* AVR magic number
111 + Written in the absense of an ABI. */
112 +#define EM_AVR_OLD 0x1057
114 +/* OpenRISC magic number
115 + Written in the absense of an ABI. */
116 +#define EM_OPENRISC_OLD 0x3426
118 +/* DLX magic number
119 + Written in the absense of an ABI. */
120 +#define EM_DLX 0x5aa5
122 +#define EM_XSTORMY16 0xad45
124 +/* FRV magic number - no EABI available??. */
125 #define EM_CYGNUS_FRV 0x5441
127 +/* Ubicom IP2xxx; no ABI */
128 +#define EM_IP2K_OLD 0x8217
130 +#define EM_MT 0x2530 /* Morpho MT; no ABI */
132 +/* MSP430 magic number
133 + Written in the absense everything. */
134 +#define EM_MSP430_OLD 0x1059
136 +/* Vitesse IQ2000. */
137 +#define EM_IQ2000 0xFEBA
139 +/* Old, unofficial value for Xtensa. */
140 +#define EM_XTENSA_OLD 0xabc7
142 +/* Alpha backend magic number. Written in the absence of an ABI. */
143 #define EM_ALPHA 0x9026
144 -#define EM_NIOS32 0xfebb /* Altera Nios 32 */
145 -#define EM_ALTERA_NIOS2 0x9ee5 /* Altera Nios II */
147 +/* NIOS magic number - no EABI available. */
148 +#define EM_NIOS32 0xFEBB
150 /* V850 backend magic number. Written in the absense of an ABI. */
151 #define EM_CYGNUS_V850 0x9080
152 @@ -2498,6 +2591,12 @@
153 #define R_390_NUM 61
156 +/* CRIS flags. */
157 +#define EF_CRIS_VARIANT_MASK 0x0000000e
158 +#define EF_CRIS_VARIANT_ANY_V0_V10 0x00000000
159 +#define EF_CRIS_VARIANT_V32 0x00000002
160 +#define EF_CRIS_VARIANT_COMMON_V10_V32 0x00000004
162 /* CRIS relocations. */
163 #define R_CRIS_NONE 0
164 #define R_CRIS_8 1
165 @@ -2688,6 +2787,7 @@
166 #define R_V850_NUM 25
169 +/* Renesas H8/300 Relocations */
170 #define R_H8_NONE 0
171 #define R_H8_DIR32 1
172 #define R_H8_DIR32_28 2
173 @@ -2731,8 +2831,7 @@
174 #define R_H8_DIR32A16 63
175 #define R_H8_ABS32 65
176 #define R_H8_ABS32A16 127
178 -/* Altera NIOS specific definitions. */
179 +#define R_H8_NUM 128
181 /* NIOS relocations. */
182 #define R_NIOS_NONE 0
183 diff -urN uClibc-0.9.28.orig/include/errno.h uClibc-0.9.28/include/errno.h
184 --- uClibc-0.9.28.orig/include/errno.h 2006-05-02 10:47:27.000000000 -0600
185 +++ uClibc-0.9.28/include/errno.h 2006-04-28 00:14:35.000000000 -0600
186 @@ -43,9 +43,11 @@
187 variable. This redeclaration using the macro still works, but it
188 will be a function declaration without a prototype and may trigger
189 a -Wstrict-prototypes warning. */
190 +#ifndef __ASSEMBLER__
191 #ifndef errno
192 extern int errno;
193 #endif
194 +#endif
196 #if 0 /*def __USE_GNU uClibc note: not supported */
198 diff -urN uClibc-0.9.28.orig/ldso/Makefile uClibc-0.9.28/ldso/Makefile
199 --- uClibc-0.9.28.orig/ldso/Makefile 2006-05-02 10:47:27.000000000 -0600
200 +++ uClibc-0.9.28/ldso/Makefile 2006-04-28 00:14:35.000000000 -0600
201 @@ -37,15 +37,12 @@
203 LN_HEADERS := $(patsubst %, include/%, elf.h)
204 LN_ARCH_HEADERS := $(patsubst %, include/%, dl-startup.h dl-syscalls.h dl-sysdep.h dl-debug.h)
205 -HEADERS := $(LN_HEADERS) $(LN_ARCH_HEADERS) include/dl-progname.h
206 +HEADERS := $(LN_HEADERS) $(LN_ARCH_HEADERS)
207 headers: $(HEADERS)
208 $(LN_HEADERS):
209 $(LN) -fs $(TOPDIR)../$@ $@
210 $(LN_ARCH_HEADERS):
211 $(LN) -fs ../ldso/$(TARGET_ARCH)/$(patsubst include/%,%,$@) $@
212 -include/dl-progname.h:
213 - echo '#include "$(TARGET_ARCH)/elfinterp.c"' \
214 - > include/dl-progname.h
216 clean:
217 set -e ; for d in $(DIRS) ; do $(MAKE) -C $$d $@ ; done
218 diff -urN uClibc-0.9.28.orig/ldso/include/dl-defs.h uClibc-0.9.28/ldso/include/dl-defs.h
219 --- uClibc-0.9.28.orig/ldso/include/dl-defs.h 2006-05-02 10:47:27.000000000 -0600
220 +++ uClibc-0.9.28/ldso/include/dl-defs.h 2006-04-28 00:14:35.000000000 -0600
221 @@ -1,6 +1,29 @@
222 +/* vi: set sw=4 ts=4: */
224 + * Copyright (C) 2000-2005 by Erik Andersen <andersen@codepoet.org>
226 + * GNU Lesser General Public License version 2.1 or later.
227 + */
229 #ifndef _LD_DEFS_H
230 #define _LD_DEFS_H
232 +#define FLAG_ANY -1
233 +#define FLAG_TYPE_MASK 0x00ff
234 +#define FLAG_LIBC4 0x0000
235 +#define FLAG_ELF 0x0001
236 +#define FLAG_ELF_LIBC5 0x0002
237 +#define FLAG_ELF_LIBC6 0x0003
238 +#define FLAG_ELF_UCLIBC 0x0004
239 +#define FLAG_REQUIRED_MASK 0xff00
240 +#define FLAG_SPARC_LIB64 0x0100
241 +#define FLAG_IA64_LIB64 0x0200
242 +#define FLAG_X8664_LIB64 0x0300
243 +#define FLAG_S390_LIB64 0x0400
244 +#define FLAG_POWERPC_LIB64 0x0500
245 +#define FLAG_MIPS64_LIBN32 0x0600
246 +#define FLAG_MIPS64_LIBN64 0x0700
248 #define LIB_ANY -1
249 #define LIB_DLL 0
250 #define LIB_ELF 1
251 diff -urN uClibc-0.9.28.orig/ldso/include/dl-elf.h uClibc-0.9.28/ldso/include/dl-elf.h
252 --- uClibc-0.9.28.orig/ldso/include/dl-elf.h 2006-05-02 10:47:27.000000000 -0600
253 +++ uClibc-0.9.28/ldso/include/dl-elf.h 2006-04-28 00:14:35.000000000 -0600
254 @@ -1,3 +1,10 @@
255 +/* vi: set sw=4 ts=4: */
257 + * Copyright (C) 2000-2005 by Erik Andersen <andersen@codepoet.org>
259 + * GNU Lesser General Public License version 2.1 or later.
260 + */
262 #ifndef LINUXELF_H
263 #define LINUXELF_H
265 diff -urN uClibc-0.9.28.orig/ldso/include/dl-hash.h uClibc-0.9.28/ldso/include/dl-hash.h
266 --- uClibc-0.9.28.orig/ldso/include/dl-hash.h 2006-05-02 10:47:27.000000000 -0600
267 +++ uClibc-0.9.28/ldso/include/dl-hash.h 2006-04-28 00:14:35.000000000 -0600
268 @@ -1,3 +1,10 @@
269 +/* vi: set sw=4 ts=4: */
271 + * Copyright (C) 2000-2005 by Erik Andersen <andersen@codepoet.org>
273 + * GNU Lesser General Public License version 2.1 or later.
274 + */
276 #ifndef _LD_HASH_H_
277 #define _LD_HASH_H_
279 @@ -32,15 +39,15 @@
280 unsigned short usage_count;
281 unsigned short int init_flag;
282 unsigned long rtld_flags; /* RTLD_GLOBAL, RTLD_NOW etc. */
283 - Elf32_Word nbucket;
284 - Elf32_Word *elf_buckets;
285 + Elf_Symndx nbucket;
286 + Elf_Symndx *elf_buckets;
287 struct init_fini_list *init_fini;
288 struct init_fini_list *rtld_local; /* keep tack of RTLD_LOCAL libs in same group */
290 * These are only used with ELF style shared libraries
292 - Elf32_Word nchain;
293 - Elf32_Word *chains;
294 + Elf_Symndx nchain;
295 + Elf_Symndx *chains;
296 unsigned long dynamic_info[DYNAMIC_SIZE];
298 unsigned long n_phent;
299 @@ -49,6 +56,9 @@
300 ElfW(Addr) relro_addr;
301 size_t relro_size;
303 + dev_t st_dev; /* device */
304 + ino_t st_ino; /* inode */
306 #ifdef __powerpc__
307 /* this is used to store the address of relocation data words, so
308 * we don't have to calculate it every time, which requires a divide */
309 @@ -66,7 +76,6 @@
310 extern struct elf_resolve * _dl_loaded_modules;
311 extern struct dyn_elf * _dl_handles;
313 -extern struct elf_resolve * _dl_check_hashed_files(const char * libname);
314 extern struct elf_resolve * _dl_add_elf_hash_table(const char * libname,
315 char * loadaddr, unsigned long * dynamic_info,
316 unsigned long dynamic_addr, unsigned long dynamic_size);
317 diff -urN uClibc-0.9.28.orig/ldso/include/dl-string.h uClibc-0.9.28/ldso/include/dl-string.h
318 --- uClibc-0.9.28.orig/ldso/include/dl-string.h 2006-05-02 10:47:27.000000000 -0600
319 +++ uClibc-0.9.28/ldso/include/dl-string.h 2006-04-28 00:14:35.000000000 -0600
320 @@ -1,9 +1,24 @@
321 +/* vi: set sw=4 ts=4: */
323 + * Copyright (C) 2000-2005 by Erik Andersen <andersen@codepoet.org>
325 + * GNU Lesser General Public License version 2.1 or later.
326 + */
328 #ifndef _LINUX_STRING_H_
329 #define _LINUX_STRING_H_
331 -#include <dl-sysdep.h> // for do_rem
332 +#include <dl-sysdep.h> /* for do_rem */
333 #include <features.h>
335 +/* provide some sane defaults */
336 +#ifndef do_rem
337 +# define do_rem(result, n, base) ((result) = (n) % (base))
338 +#endif
339 +#ifndef do_div_10
340 +# define do_div_10(result, remain) ((result) /= 10)
341 +#endif
343 static size_t _dl_strlen(const char * str);
344 static char *_dl_strcat(char *dst, const char *src);
345 static char * _dl_strcpy(char * dst,const char *src);
346 @@ -26,8 +41,8 @@
347 static __always_inline size_t _dl_strlen(const char * str)
349 register const char *ptr = (char *) str-1;
351 - while (*++ptr);
352 + while (*++ptr)
353 + ;/* empty */
354 return (ptr - str);
357 @@ -49,7 +64,8 @@
358 register char *ptr = dst;
360 dst--;src--;
361 - while ((*++dst = *++src) != 0);
362 + while ((*++dst = *++src) != 0)
363 + ;/* empty */
365 return ptr;
367 @@ -63,8 +79,7 @@
368 c2 = (unsigned char) *++s2;
369 if (c1 == '\0')
370 return c1 - c2;
372 - while (c1 == c2);
373 + } while (c1 == c2);
375 return c1 - c2;
377 @@ -98,43 +113,41 @@
378 return 0;
381 -static inline char * _dl_strrchr(const char *str, int c)
382 +static __always_inline char * _dl_strrchr(const char *str, int c)
384 - register char *prev = 0;
385 - register char *ptr = (char *) str-1;
386 + register char *prev = 0;
387 + register char *ptr = (char *) str-1;
389 - while (*++ptr != '\0') {
390 - if (*ptr == c)
391 - prev = ptr;
393 - if (c == '\0')
394 - return(ptr);
395 - return(prev);
396 + while (*++ptr != '\0') {
397 + if (*ptr == c)
398 + prev = ptr;
400 + if (c == '\0')
401 + return(ptr);
402 + return(prev);
405 -static inline char * _dl_strstr(const char *s1, const char *s2)
406 +static __always_inline char * _dl_strstr(const char *s1, const char *s2)
408 - register const char *s = s1;
409 - register const char *p = s2;
410 + register const char *s = s1;
411 + register const char *p = s2;
413 - do {
414 - if (!*p) {
415 - return (char *) s1;;
417 - if (*p == *s) {
418 - ++p;
419 - ++s;
420 - } else {
421 - p = s2;
422 - if (!*s) {
423 - return NULL;
425 - s = ++s1;
427 - } while (1);
428 + do {
429 + if (!*p)
430 + return (char *) s1;;
431 + if (*p == *s) {
432 + ++p;
433 + ++s;
434 + } else {
435 + p = s2;
436 + if (!*s)
437 + return NULL;
438 + s = ++s1;
440 + } while (1);
443 -static inline void * _dl_memcpy(void * dst, const void * src, size_t len)
444 +static __always_inline void * _dl_memcpy(void * dst, const void * src, size_t len)
446 register char *a = dst-1;
447 register const char *b = src-1;
448 @@ -163,27 +176,28 @@
449 /* Will generate smaller and faster code due to loop unrolling.*/
450 static __always_inline void * _dl_memset(void *to, int c, size_t n)
452 - unsigned long chunks;
453 - unsigned long *tmp_to;
454 + unsigned long chunks;
455 + unsigned long *tmp_to;
456 unsigned char *tmp_char;
458 - chunks = n / 4;
459 - tmp_to = to + n;
460 - c = c << 8 | c;
461 - c = c << 16 | c;
462 - if (!chunks)
463 - goto lessthan4;
464 - do {
465 - *--tmp_to = c;
466 - } while (--chunks);
467 - lessthan4:
468 - n = n % 4;
469 - if (!n ) return to;
470 - tmp_char = (unsigned char *)tmp_to;
471 - do {
472 - *--tmp_char = c;
473 - } while (--n);
474 - return to;
475 + chunks = n / 4;
476 + tmp_to = to + n;
477 + c = c << 8 | c;
478 + c = c << 16 | c;
479 + if (!chunks)
480 + goto lessthan4;
481 + do {
482 + *--tmp_to = c;
483 + } while (--chunks);
484 +lessthan4:
485 + n = n % 4;
486 + if (!n)
487 + return to;
488 + tmp_char = (unsigned char *)tmp_to;
489 + do {
490 + *--tmp_char = c;
491 + } while (--n);
492 + return to;
494 #else
495 static __always_inline void * _dl_memset(void * str,int c,size_t len)
496 @@ -225,10 +239,10 @@
497 char *p = &local[22];
498 *--p = '\0';
499 do {
500 - char temp;
501 - do_rem(temp, i, 10);
502 - *--p = '0' + temp;
503 - i /= 10;
504 + char temp;
505 + do_rem(temp, i, 10);
506 + *--p = '0' + temp;
507 + do_div_10(i, temp);
508 } while (i > 0);
509 return p;
511 @@ -242,9 +256,9 @@
512 do {
513 char temp = i & 0xf;
514 if (temp <= 0x09)
515 - *--p = '0' + temp;
516 + *--p = '0' + temp;
517 else
518 - *--p = 'a' - 0x0a + temp;
519 + *--p = 'a' - 0x0a + temp;
520 i >>= 4;
521 } while (i > 0);
522 *--p = 'x';
523 @@ -270,8 +284,8 @@
525 /* On some arches constant strings are referenced through the GOT.
526 * This requires that load_addr must already be defined... */
527 -#if defined(mc68000) || defined(__arm__) || defined(__mips__) \
528 - || defined(__sh__) || defined(__powerpc__)
529 +#if defined(mc68000) || defined(__arm__) || defined(__thumb__) || \
530 + defined(__mips__) || defined(__sh__) || defined(__powerpc__)
531 # define CONSTANT_STRING_GOT_FIXUP(X) \
532 if ((X) < (const char *) load_addr) (X) += load_addr
533 # define NO_EARLY_SEND_STDERR
534 @@ -318,7 +332,7 @@
535 do { \
536 do_rem(v, (X), 10); \
537 *--tmp2 = '0' + v; \
538 - (X) /= 10; \
539 + do_div_10((X), v); \
540 } while ((X) > 0); \
541 _dl_write(2, tmp2, tmp1 - tmp2 + sizeof(tmp) - 1); \
543 diff -urN uClibc-0.9.28.orig/ldso/include/dl-syscall.h uClibc-0.9.28/ldso/include/dl-syscall.h
544 --- uClibc-0.9.28.orig/ldso/include/dl-syscall.h 2006-05-02 10:47:27.000000000 -0600
545 +++ uClibc-0.9.28/ldso/include/dl-syscall.h 2006-04-28 00:14:35.000000000 -0600
546 @@ -1,3 +1,10 @@
547 +/* vi: set sw=4 ts=4: */
549 + * Copyright (C) 2000-2005 by Erik Andersen <andersen@codepoet.org>
551 + * GNU Lesser General Public License version 2.1 or later.
552 + */
554 #ifndef _LD_SYSCALL_H_
555 #define _LD_SYSCALL_H_
557 @@ -12,9 +19,8 @@
558 #include <bits/kernel_stat.h>
559 #include <bits/kernel_types.h>
562 /* _dl_open() parameters */
563 -#define O_RDONLY 0x0000
564 +#define O_RDONLY 00
565 #define O_WRONLY 01
566 #define O_RDWR 02
567 #define O_CREAT 0100
568 @@ -39,18 +45,6 @@
569 #define S_IWRITE 0200 /* Write by owner. */
570 #define S_IEXEC 0100 /* Execute by owner. */
572 -/* Stuff for _dl_mmap */
573 -#if 0
574 -#define MAP_FAILED ((void *) -1)
575 -#define _dl_mmap_check_error(X) (((void *)X) == MAP_FAILED)
576 -#else
577 -#ifndef _dl_MAX_ERRNO
578 -#define _dl_MAX_ERRNO 4096
579 -#endif
580 -#define _dl_mmap_check_error(__res) \
581 - (((long)__res) < 0 && ((long)__res) >= -_dl_MAX_ERRNO)
582 -#endif
586 /* Here are the definitions for some syscalls that are used
587 @@ -66,54 +60,125 @@
588 static inline _syscall1(int, _dl_close, int, fd);
590 #define __NR__dl_open __NR_open
591 -static inline _syscall3(int, _dl_open, const char *, fn, int, flags, __kernel_mode_t, mode);
592 +static inline _syscall3(int, _dl_open, const char *, fn, int, flags,
593 + __kernel_mode_t, mode);
595 #define __NR__dl_write __NR_write
596 static inline _syscall3(unsigned long, _dl_write, int, fd,
597 - const void *, buf, unsigned long, count);
598 + const void *, buf, unsigned long, count);
600 #define __NR__dl_read __NR_read
601 static inline _syscall3(unsigned long, _dl_read, int, fd,
602 - const void *, buf, unsigned long, count);
603 + const void *, buf, unsigned long, count);
605 #define __NR__dl_mprotect __NR_mprotect
606 -static inline _syscall3(int, _dl_mprotect, const void *, addr, unsigned long, len, int, prot);
607 +static inline _syscall3(int, _dl_mprotect, const void *, addr,
608 + unsigned long, len, int, prot);
610 #define __NR__dl_stat __NR_stat
611 -static inline _syscall2(int, _dl_stat, const char *, file_name, struct stat *, buf);
612 +static inline _syscall2(int, _dl_stat, const char *, file_name,
613 + struct stat *, buf);
615 +#define __NR__dl_fstat __NR_fstat
616 +static inline _syscall2(int, _dl_fstat, int, fd, struct stat *, buf);
618 #define __NR__dl_munmap __NR_munmap
619 static inline _syscall2(int, _dl_munmap, void *, start, unsigned long, length);
621 +#ifdef __NR_getxuid
622 +# define __NR_getuid __NR_getxuid
623 +#endif
624 #define __NR__dl_getuid __NR_getuid
625 static inline _syscall0(uid_t, _dl_getuid);
627 +#ifndef __NR_geteuid
628 +# define __NR_geteuid __NR_getuid
629 +#endif
630 #define __NR__dl_geteuid __NR_geteuid
631 static inline _syscall0(uid_t, _dl_geteuid);
633 +#ifdef __NR_getxgid
634 +# define __NR_getgid __NR_getxgid
635 +#endif
636 #define __NR__dl_getgid __NR_getgid
637 static inline _syscall0(gid_t, _dl_getgid);
639 +#ifndef __NR_getegid
640 +# define __NR_getegid __NR_getgid
641 +#endif
642 #define __NR__dl_getegid __NR_getegid
643 static inline _syscall0(gid_t, _dl_getegid);
645 +#ifdef __NR_getxpid
646 +# define __NR_getpid __NR_getxpid
647 +#endif
648 #define __NR__dl_getpid __NR_getpid
649 static inline _syscall0(gid_t, _dl_getpid);
651 #define __NR__dl_readlink __NR_readlink
652 -static inline _syscall3(int, _dl_readlink, const char *, path, char *, buf, size_t, bufsiz);
653 +static inline _syscall3(int, _dl_readlink, const char *, path, char *, buf,
654 + size_t, bufsiz);
656 -#ifdef __NR_mmap
657 -#ifdef MMAP_HAS_6_ARGS
658 -#define __NR__dl_mmap __NR_mmap
659 -static inline _syscall6(void *, _dl_mmap, void *, start, size_t, length,
660 - int, prot, int, flags, int, fd, off_t, offset);
661 +#ifdef __UCLIBC_HAS_SSP__
662 +# include <sys/time.h>
663 +# define __NR__dl_gettimeofday __NR_gettimeofday
664 +static inline _syscall2(int, _dl_gettimeofday, struct timeval *, tv,
665 +# ifdef __USE_BSD
666 + struct timezone *, tz);
667 +# else
668 + void *, tz);
669 +# endif
670 +#endif
673 +/* handle all the fun mmap intricacies */
674 +#if (defined(__UCLIBC_MMAP_HAS_6_ARGS__) && defined(__NR_mmap)) || !defined(__NR_mmap2)
675 +# define _dl_MAX_ERRNO 4096
676 +# define _dl_mmap_check_error(__res) \
677 + (((long)__res) < 0 && ((long)__res) >= -_dl_MAX_ERRNO)
678 #else
679 -#define __NR__dl_mmap_real __NR_mmap
680 -static inline _syscall1(void *, _dl_mmap_real, unsigned long *, buffer);
681 +# define MAP_FAILED ((void *) -1)
682 +# define _dl_mmap_check_error(X) (((void *)X) == MAP_FAILED)
683 +#endif
685 +/* first try mmap(), syscall6() style */
686 +#if defined(__UCLIBC_MMAP_HAS_6_ARGS__) && defined(__NR_mmap)
688 +# define __NR__dl_mmap __NR_mmap
689 +static inline _syscall6(void *, _dl_mmap, void *, start, size_t, length,
690 + int, prot, int, flags, int, fd, off_t, offset);
692 +/* then try mmap2() */
693 +#elif defined(__NR_mmap2)
695 +# define __NR___syscall_mmap2 __NR_mmap2
696 +static inline _syscall6(__ptr_t, __syscall_mmap2, __ptr_t, addr, size_t, len,
697 + int, prot, int, flags, int, fd, off_t, offset);
699 +/* Some architectures always use 12 as page shift for mmap2() eventhough the
700 + * real PAGE_SHIFT != 12. Other architectures use the same value as
701 + * PAGE_SHIFT...
702 + */
703 +#ifndef MMAP2_PAGE_SHIFT
704 +# define MMAP2_PAGE_SHIFT 12
705 +#endif
707 static inline void * _dl_mmap(void * addr, unsigned long size, int prot,
708 - int flags, int fd, unsigned long offset)
709 + int flags, int fd, unsigned long offset)
711 + if (offset & ((1 << MMAP2_PAGE_SHIFT) - 1))
712 + return MAP_FAILED;
713 + return __syscall_mmap2(addr, size, prot, flags,
714 + fd, (off_t) (offset >> MMAP2_PAGE_SHIFT));
717 +/* finally, fall back to mmap(), syscall1() style */
718 +#elif defined(__NR_mmap)
720 +# define __NR__dl_mmap_real __NR_mmap
721 +static inline _syscall1(void *, _dl_mmap_real, unsigned long *, buffer);
722 +static inline void * _dl_mmap(void * addr, unsigned long size, int prot,
723 + int flags, int fd, unsigned long offset)
725 unsigned long buffer[6];
727 @@ -125,24 +190,9 @@
728 buffer[5] = (unsigned long) offset;
729 return (void *) _dl_mmap_real(buffer);
731 -#endif
732 -#elif defined __NR_mmap2
733 -#define __NR___syscall_mmap2 __NR_mmap2
734 -static inline _syscall6(__ptr_t, __syscall_mmap2, __ptr_t, addr,
735 - size_t, len, int, prot, int, flags, int, fd, off_t, offset);
736 -/*always 12, even on architectures where PAGE_SHIFT != 12 */
737 -#define MMAP2_PAGE_SHIFT 12
738 -static inline void * _dl_mmap(void * addr, unsigned long size, int prot,
739 - int flags, int fd, unsigned long offset)
741 - if (offset & ((1 << MMAP2_PAGE_SHIFT) - 1))
742 - return MAP_FAILED;
743 - return(__syscall_mmap2(addr, size, prot, flags,
744 - fd, (off_t) (offset >> MMAP2_PAGE_SHIFT)));
747 #else
748 -#error "Your architecture doesn't seem to provide mmap() !?"
749 +# error "Your architecture doesn't seem to provide mmap() !?"
750 #endif
752 #endif /* _LD_SYSCALL_H_ */
754 diff -urN uClibc-0.9.28.orig/ldso/include/dlfcn.h uClibc-0.9.28/ldso/include/dlfcn.h
755 --- uClibc-0.9.28.orig/ldso/include/dlfcn.h 2006-05-02 10:47:27.000000000 -0600
756 +++ uClibc-0.9.28/ldso/include/dlfcn.h 2006-04-28 00:14:35.000000000 -0600
757 @@ -1,3 +1,10 @@
758 +/* vi: set sw=4 ts=4: */
760 + * Copyright (C) 2000-2005 by Erik Andersen <andersen@codepoet.org>
762 + * GNU Lesser General Public License version 2.1 or later.
763 + */
765 /* User functions for run-time dynamic loading. libdl version */
766 #ifndef _DLFCN_H
767 #define _DLFCN_H 1
768 diff -urN uClibc-0.9.28.orig/ldso/include/ldso.h uClibc-0.9.28/ldso/include/ldso.h
769 --- uClibc-0.9.28.orig/ldso/include/ldso.h 2006-05-02 10:47:27.000000000 -0600
770 +++ uClibc-0.9.28/ldso/include/ldso.h 2006-04-28 00:14:35.000000000 -0600
771 @@ -1,3 +1,10 @@
772 +/* vi: set sw=4 ts=4: */
774 + * Copyright (C) 2000-2005 by Erik Andersen <andersen@codepoet.org>
776 + * GNU Lesser General Public License version 2.1 or later.
777 + */
779 #ifndef _LDSO_H_
780 #define _LDSO_H_
782 @@ -20,13 +27,15 @@
783 /* Pull in compiler and arch stuff */
784 #include <stdlib.h>
785 #include <stdarg.h>
786 +#include <bits/wordsize.h>
787 /* Pull in the arch specific type information */
788 #include <sys/types.h>
789 +/* Pull in the arch specific page size */
790 +#include <bits/uClibc_page.h>
791 +#define attribute_unused __attribute__ ((unused))
792 /* Pull in the ldso syscalls and string functions */
793 #include <dl-syscall.h>
794 #include <dl-string.h>
795 -/* Pull in the arch specific page size */
796 -#include <bits/uClibc_page.h>
797 /* Now the ldso specific headers */
798 #include <dl-elf.h>
799 #include <dl-hash.h>
800 diff -urN uClibc-0.9.28.orig/ldso/include/unsecvars.h uClibc-0.9.28/ldso/include/unsecvars.h
801 --- uClibc-0.9.28.orig/ldso/include/unsecvars.h 2006-05-02 10:47:27.000000000 -0600
802 +++ uClibc-0.9.28/ldso/include/unsecvars.h 2006-04-28 00:14:35.000000000 -0600
803 @@ -1,3 +1,10 @@
804 +/* vi: set sw=4 ts=4: */
806 + * Copyright (C) 2000-2005 by Erik Andersen <andersen@codepoet.org>
808 + * GNU Lesser General Public License version 2.1 or later.
809 + */
812 * Environment variable to be removed for SUID programs. The names are all
813 * stuffed in a single string which means they have to be terminated with a
814 @@ -5,22 +12,21 @@
817 #define UNSECURE_ENVVARS \
818 - "LD_AOUT_PRELOAD\0" \
819 - "LD_AOUT_LIBRARY_PATH\0" \
820 "LD_PRELOAD\0" \
821 "LD_LIBRARY_PATH\0" \
822 "LD_DEBUG\0" \
823 "LD_DEBUG_OUTPUT\0" \
824 "LD_TRACE_LOADED_OBJECTS\0" \
825 - "HOSTALIASES\0" \
826 - "LOCALDOMAIN\0" \
827 - "RES_OPTIONS\0" \
828 "TMPDIR\0"
831 + * LD_TRACE_LOADED_OBJECTS is not in glibc-2.3.5's unsecvars.h
832 + * though used by ldd
834 * These environment variables are defined by glibc but ignored in
835 * uClibc, but may very well have an equivalent in uClibc.
837 - * MALLOC_TRACE, RESOLV_HOST_CONF, TZDIR, GCONV_PATH, LD_USE_LOAD_BIAS,
838 - * LD_PROFILE, LD_ORIGIN_PATH, LOCPATH, NLSPATH
839 + * LD_ORIGIN_PATH, LD_PROFILE, LD_USE_LOAD_BIAS, LD_DYNAMIC_WEAK, LD_SHOW_AUXV,
840 + * GCONV_PATH, GETCONF_DIR, HOSTALIASES, LOCALDOMAIN, LOCPATH, MALLOC_TRACE,
841 + * NLSPATH, RESOLV_HOST_CONF, RES_OPTIONS, TZDIR
843 diff -urN uClibc-0.9.28.orig/ldso/ldso/Makefile uClibc-0.9.28/ldso/ldso/Makefile
844 --- uClibc-0.9.28.orig/ldso/ldso/Makefile 2006-05-02 10:47:27.000000000 -0600
845 +++ uClibc-0.9.28/ldso/ldso/Makefile 2006-04-28 00:14:35.000000000 -0600
846 @@ -42,7 +42,9 @@
847 endif
848 XXFLAGS+= -DUCLIBC_LDSO=\"$(UCLIBC_LDSO)\" $(XARCH_CFLAGS) $(CPU_CFLAGS) $(PICFLAG) \
849 -DUCLIBC_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" \
850 - -fno-builtin -nostdinc -D_LIBC -I$(TOPDIR)ldso/include -I. -I$(TOPDIR)include
851 + -fno-builtin -nostdinc -D_LIBC \
852 + -DLDSO_ELFINTERP=\"$(TARGET_ARCH)/elfinterp.c\" \
853 + -I$(TOPDIR)ldso/ldso/$(TARGET_ARCH) -I$(TOPDIR)ldso/include -I$(TOPDIR)ldso/ldso -I$(TOPDIR)include
855 # BEWARE!!! At least mips* will die if -O0 is used!!!
856 XXFLAGS:=$(XXFLAGS:-O0=-O1)
857 diff -urN uClibc-0.9.28.orig/ldso/ldso/arm/dl-startup.h uClibc-0.9.28/ldso/ldso/arm/dl-startup.h
858 --- uClibc-0.9.28.orig/ldso/ldso/arm/dl-startup.h 2006-05-02 10:47:27.000000000 -0600
859 +++ uClibc-0.9.28/ldso/ldso/arm/dl-startup.h 2006-04-28 00:14:35.000000000 -0600
860 @@ -1,10 +1,15 @@
861 /* vi: set sw=4 ts=4: */
863 * Architecture specific code used by dl-startup.c
864 - * Copyright (C) 2000-2004 by Erik Andersen <andersen@codepoet.org>
865 + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
867 + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
870 -asm(
871 +#include <features.h>
873 +#if !defined(__thumb__)
874 +__asm__(
875 " .text\n"
876 " .globl _start\n"
877 " .type _start,%function\n"
878 @@ -40,7 +45,78 @@
879 " ldr r0, .L_FINI_PROC\n"
880 " ldr r0, [sl, r0]\n"
881 " @ jump to the user_s entry point\n"
882 +#if defined(__USE_BX__)
883 + " bx r6\n"
884 +#else
885 + " mov pc, r6\n"
886 +#endif
887 + ".L_GET_GOT:\n"
888 + " .word _GLOBAL_OFFSET_TABLE_ - .L_GOT_GOT - 4\n"
889 + ".L_SKIP_ARGS:\n"
890 + " .word _dl_skip_args(GOTOFF)\n"
891 + ".L_FINI_PROC:\n"
892 + " .word _dl_fini(GOT)\n"
893 + "\n\n"
894 + " .size _start,.-_start\n"
895 + ".previous\n"
897 +#else
898 +__asm__(
899 + " .text\n"
900 + " .arm\n"
901 + " .globl _start\n"
902 + " .type _start,%function\n"
903 + "_start:\n"
904 + " @ dumb: can't persuade the linker to make the start address\n"
905 + " @ odd, so use an arm function and change to thumb (_dl_start\n"
906 + " @ is thumb)\n"
907 + " adr r0, __dl_thumb_start+1\n"
908 + " bx r0\n"
909 + "\n\n"
910 + " .thumb\n"
911 + " .globl __dl_thumb_start\n"
912 + " .thumb_func\n"
913 + " .type __dl_thumb_start,%function\n"
914 + "__dl_thumb_start:\n"
915 + " @ at start time, all the args are on the stack\n"
916 + " mov r0, sp\n"
917 + " bl _dl_start\n"
918 + " @ returns user entry point in r0\n"
919 + " mov r6, r0\n"
920 + " @ we are PIC code, so get global offset table\n"
921 + " ldr r7, .L_GET_GOT\n"
922 + ".L_GOT_GOT:\n"
923 + " add r7, pc\n"
924 + " @ See if we were run as a command with the executable file\n"
925 + " @ name as an extra leading argument.\n"
926 + " ldr r4, .L_SKIP_ARGS\n"
927 + " ldr r4, [r7, r4]\n"
928 + " @ get the original arg count\n"
929 + " ldr r1, [sp]\n"
930 + " @ subtract _dl_skip_args from it\n"
931 + " sub r1, r1, r4\n"
932 + " @ adjust the stack pointer to skip them\n"
933 + " lsl r4, r4, #2\n"
934 + " add sp, r4\n"
935 + " @ get the argv address\n"
936 + " add r2, sp, #4\n"
937 + " @ store the new argc in the new stack location\n"
938 + " str r1, [sp]\n"
939 + " @ compute envp\n"
940 + " lsl r3, r1, #2\n"
941 + " add r3, r3, r2\n"
942 + " add r3, #4\n"
943 + "\n\n"
944 + " @ load the finalizer function\n"
945 + " ldr r0, .L_FINI_PROC\n"
946 + " ldr r0, [r7, r0]\n"
947 + " @ jump to the user_s entry point\n"
948 +#if defined(__USE_BX__)
949 + " bx r6\n"
950 +#else
951 " mov pc, r6\n"
952 +#endif
953 + "\n\n"
954 ".L_GET_GOT:\n"
955 " .word _GLOBAL_OFFSET_TABLE_ - .L_GOT_GOT - 4\n"
956 ".L_SKIP_ARGS:\n"
957 @@ -51,6 +127,7 @@
958 " .size _start,.-_start\n"
959 ".previous\n"
961 +#endif
964 /* Get a pointer to the argv array. On many platforms this can be just
965 @@ -115,9 +192,3 @@
966 _dl_exit(1);
971 -/* Transfer control to the user's application, once the dynamic loader is
972 - * done. This routine has to exit the current function, then call the
973 - * _dl_elf_main function. */
974 -#define START() return _dl_elf_main;
975 diff -urN uClibc-0.9.28.orig/ldso/ldso/arm/dl-syscalls.h uClibc-0.9.28/ldso/ldso/arm/dl-syscalls.h
976 --- uClibc-0.9.28.orig/ldso/ldso/arm/dl-syscalls.h 2006-05-02 10:47:27.000000000 -0600
977 +++ uClibc-0.9.28/ldso/ldso/arm/dl-syscalls.h 2006-04-28 00:14:35.000000000 -0600
978 @@ -1,6 +1,7 @@
979 /* We can't use the real errno in ldso, since it has not yet
980 * been dynamicly linked in yet. */
981 +#include "sys/syscall.h"
982 extern int _dl_errno;
983 +#undef __set_errno
984 #define __set_errno(X) {(_dl_errno) = (X);}
985 -#include "sys/syscall.h"
987 diff -urN uClibc-0.9.28.orig/ldso/ldso/arm/dl-sysdep.h uClibc-0.9.28/ldso/ldso/arm/dl-sysdep.h
988 --- uClibc-0.9.28.orig/ldso/ldso/arm/dl-sysdep.h 2006-05-02 10:47:27.000000000 -0600
989 +++ uClibc-0.9.28/ldso/ldso/arm/dl-sysdep.h 2006-04-28 00:14:35.000000000 -0600
990 @@ -43,6 +43,7 @@
991 return m;
993 #define do_rem(result, n, base) ((result) = arm_modulus(n, base))
994 +#define do_div_10(result, remain) ((result) = (((result) - (remain)) / 2) * -(-1ul / 5ul))
996 /* Here we define the magic numbers that this dynamic loader should accept */
997 #define MAGIC1 EM_ARM
998 @@ -85,7 +86,25 @@
999 extern void __dl_start asm ("_dl_start");
1000 Elf32_Addr got_addr = (Elf32_Addr) &__dl_start;
1001 Elf32_Addr pcrel_addr;
1002 +#if !defined __thumb__
1003 asm ("adr %0, _dl_start" : "=r" (pcrel_addr));
1004 +#else
1005 + int tmp;
1006 + /* The above adr will not work on thumb because it
1007 + * is negative. The only safe way is to temporarily
1008 + * swap to arm.
1009 + */
1010 + asm( ".align 2\n"
1011 + " bx pc\n"
1012 + " nop \n"
1013 + " .arm \n"
1014 + " adr %0, _dl_start\n"
1015 + " .align 2\n"
1016 + " orr %1, pc, #1\n"
1017 + " bx %1\n"
1018 + " .force_thumb\n"
1019 + : "=r" (pcrel_addr), "=&r" (tmp));
1020 +#endif
1021 return pcrel_addr - got_addr;
1024 diff -urN uClibc-0.9.28.orig/ldso/ldso/arm/elfinterp.c uClibc-0.9.28/ldso/ldso/arm/elfinterp.c
1025 --- uClibc-0.9.28.orig/ldso/ldso/arm/elfinterp.c 2006-05-02 10:47:27.000000000 -0600
1026 +++ uClibc-0.9.28/ldso/ldso/arm/elfinterp.c 2006-04-28 00:14:35.000000000 -0600
1027 @@ -38,6 +38,8 @@
1028 a more than adequate job of explaining everything required to get this
1029 working. */
1031 +#include "ldso.h"
1033 extern int _dl_linux_resolve(void);
1035 unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
1036 @@ -63,7 +65,6 @@
1037 strtab = (char *) tpnt->dynamic_info[DT_STRTAB];
1038 symname = strtab + symtab[symtab_index].st_name;
1041 if (unlikely(reloc_type != R_ARM_JUMP_SLOT)) {
1042 _dl_dprintf(2, "%s: Incorrect relocation type in jump relocations\n",
1043 _dl_progname);
1044 diff -urN uClibc-0.9.28.orig/ldso/ldso/cris/dl-startup.h uClibc-0.9.28/ldso/ldso/cris/dl-startup.h
1045 --- uClibc-0.9.28.orig/ldso/ldso/cris/dl-startup.h 2006-05-02 10:47:27.000000000 -0600
1046 +++ uClibc-0.9.28/ldso/ldso/cris/dl-startup.h 2006-04-28 00:14:35.000000000 -0600
1047 @@ -4,22 +4,43 @@
1049 /* This code fixes the stack pointer so that the dynamic linker
1050 * can find argc, argv and auxvt (Auxillary Vector Table). */
1051 +#ifdef __arch_v32
1053 +asm("" \
1054 +" .text\n" \
1055 +" .globl _start\n" \
1056 +" .type _start,@function\n" \
1057 +"_start:\n" \
1058 +" move.d $sp,$r10\n" \
1059 +" lapc _dl_start,$r9\n" \
1060 +" jsr $r9\n" \
1061 +" nop\n" \
1062 +" moveq 0,$r8\n" \
1063 +" jump $r10\n" \
1064 +" move $r8,$srp\n" \
1065 +" .size _start,.-_start\n" \
1066 +" .previous\n" \
1069 +#else
1071 asm("" \
1072 " .text\n" \
1073 " .globl _start\n" \
1074 " .type _start,@function\n" \
1075 "_start:\n" \
1076 -" move.d $sp,$r10\n" \
1077 -" move.d $pc,$r9\n" \
1078 -" add.d _dl_start - ., $r9\n" \
1079 -" jsr $r9\n" \
1080 -" moveq 0,$r8\n" \
1081 -" move $r8,$srp\n" \
1082 -" jump $r10\n" \
1083 +" move.d $sp,$r10\n" \
1084 +" move.d $pc,$r9\n" \
1085 +" add.d _dl_start - ., $r9\n" \
1086 +" jsr $r9\n" \
1087 +" moveq 0,$r8\n" \
1088 +" move $r8,$srp\n" \
1089 +" jump $r10\n" \
1090 " .size _start,.-_start\n" \
1091 " .previous\n" \
1094 +#endif /* __arch_v32 */
1096 /* Get a pointer to the argv array. On many platforms this can be just
1097 * the address if the first argument, on other platforms we need to
1098 @@ -58,8 +79,3 @@
1099 break;
1103 -/* Transfer control to the user's application, once the dynamic loader is
1104 - * done. This routine has to exit the current function, then call the
1105 - * _dl_elf_main function. */
1106 -#define START() return _dl_elf_main
1107 diff -urN uClibc-0.9.28.orig/ldso/ldso/cris/dl-syscalls.h uClibc-0.9.28/ldso/ldso/cris/dl-syscalls.h
1108 --- uClibc-0.9.28.orig/ldso/ldso/cris/dl-syscalls.h 2006-05-02 10:47:27.000000000 -0600
1109 +++ uClibc-0.9.28/ldso/ldso/cris/dl-syscalls.h 2006-04-28 00:14:35.000000000 -0600
1110 @@ -1,5 +1,6 @@
1111 /* We can't use the real errno in ldso, since it has not yet
1112 * been dynamicly linked in yet. */
1113 +#include "sys/syscall.h"
1114 extern int _dl_errno;
1115 +#undef __set_errno
1116 #define __set_errno(X) {(_dl_errno) = (X);}
1117 -#include "sys/syscall.h"
1118 diff -urN uClibc-0.9.28.orig/ldso/ldso/cris/dl-sysdep.h uClibc-0.9.28/ldso/ldso/cris/dl-sysdep.h
1119 --- uClibc-0.9.28.orig/ldso/ldso/cris/dl-sysdep.h 2006-05-02 10:47:27.000000000 -0600
1120 +++ uClibc-0.9.28/ldso/ldso/cris/dl-sysdep.h 2006-04-28 00:14:35.000000000 -0600
1121 @@ -18,8 +18,6 @@
1122 struct elf_resolve;
1123 extern unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry);
1125 -#define do_rem(result, n, base) ((result) = (n) % (base))
1127 /* 8192 bytes alignment */
1128 #define PAGE_ALIGN 0xffffe000
1129 #define ADDR_ALIGN 0x1fff
1130 @@ -68,8 +66,32 @@
1132 Elf32_Addr gotaddr_diff;
1134 +#ifdef __arch_v32
1135 + extern char ___CRISv32_dummy[] __asm__ ("_dl_start");
1137 + __asm__ ("addo.w _dl_start:GOT16,$r0,$acr\n\t"
1138 + "lapc _dl_start,%0\n\t"
1139 + "sub.d [$acr],%0"
1140 + /* For v32, we need to force GCC to have R0 loaded with
1141 + _GLOBAL_OFFSET_TABLE_ at this point, which might not
1142 + otherwise have happened in the caller. (For v10, it's
1143 + loaded for non-global variables too, so we don't need
1144 + anything special there.) We accomplish this by faking the
1145 + address of a global variable (as seen by GCC) as input to
1146 + the asm; that address calculation goes through the GOT.
1147 + Use of this function happens before we've filled in the
1148 + GOT, so the address itself will not be correctly
1149 + calculated, therefore we don't use any symbol whose
1150 + address may be re-used later on. Let's just reuse the
1151 + _dl_start symbol, faking it as a global by renaming it as
1152 + another variable through an asm. */
1153 + : "=r" (gotaddr_diff)
1154 + : "g" (___CRISv32_dummy)
1155 + : "acr");
1156 +#else
1157 __asm__ ("sub.d [$r0+_dl_start:GOT16],$r0,%0\n\t"
1158 "add.d _dl_start:GOTOFF,%0" : "=r" (gotaddr_diff));
1159 +#endif
1160 return gotaddr_diff;
1163 diff -urN uClibc-0.9.28.orig/ldso/ldso/cris/resolve.S uClibc-0.9.28/ldso/ldso/cris/resolve.S
1164 --- uClibc-0.9.28.orig/ldso/ldso/cris/resolve.S 2006-05-02 10:47:27.000000000 -0600
1165 +++ uClibc-0.9.28/ldso/ldso/cris/resolve.S 2006-04-28 00:14:35.000000000 -0600
1166 @@ -17,33 +17,73 @@
1167 .globl _dl_linux_resolve
1168 .type _dl_linux_resolve,@function
1170 +#ifdef __arch_v32
1172 +_dl_linux_resolve:
1173 + subq 4,$sp
1174 + move.d $r0,[$sp]
1175 + subq 4,$sp
1176 + move.d $r13,[$sp]
1177 + subq 4,$sp
1178 + move.d $r12,[$sp]
1179 + subq 4,$sp
1180 + move.d $r11,[$sp]
1181 + subq 4,$sp
1182 + addoq 5*4,$sp,$acr
1183 + move.d $r10,[$sp]
1184 + subq 4,$sp
1185 + move $mof,$r10
1186 + move.d $r9,[$sp]
1187 + subq 4,$sp
1188 + move.d [$acr],$r11
1189 + move $srp,[$sp]
1190 + lapc _GLOBAL_OFFSET_TABLE_,$r0
1191 + move.d _dl_linux_resolver:PLTG,$r9
1192 + add.d $r0,$r9
1193 + jsr $r9
1194 + nop
1195 + move.d $r10,$acr
1196 + move [$sp+],$srp
1197 + move.d [$sp+],$r9
1198 + move.d [$sp+],$r10
1199 + move.d [$sp+],$r11
1200 + move.d [$sp+],$r12
1201 + move.d [$sp+],$r13
1202 + move.d [$sp+],$r0
1203 + jump $acr
1204 + addq 4,$sp
1206 +#else
1208 _dl_linux_resolve:
1209 - push $r13
1210 - push $r12
1211 - push $r11
1212 - push $r10
1213 - push $r9
1214 - push $r0
1215 - push $srp
1216 - move.d [$sp+7*4],$r11
1217 - move $mof,$r10
1218 + push $r13
1219 + push $r12
1220 + push $r11
1221 + push $r10
1222 + push $r9
1223 + push $r0
1224 + push $srp
1225 + move.d [$sp+7*4],$r11
1226 + move $mof,$r10
1227 #ifdef __PIC__
1228 - move.d $pc,$r0
1229 - sub.d .:GOTOFF,$r0
1230 - move.d _dl_linux_resolver:PLTG,$r9
1231 - add.d $r0,$r9
1232 - jsr $r9
1233 + move.d $pc,$r0
1234 + sub.d .:GOTOFF,$r0
1235 + move.d _dl_linux_resolver:PLTG,$r9
1236 + add.d $r0,$r9
1237 + jsr $r9
1238 #else
1239 - jsr _dl_linux_resolver
1240 + jsr _dl_linux_resolver
1241 #endif
1242 - move.d $r10,[$sp+7*4]
1243 - pop $srp
1244 - pop $r0
1245 - pop $r9
1246 - pop $r10
1247 - pop $r11
1248 - pop $r12
1249 - pop $r13
1250 - jump [$sp+]
1251 + move.d $r10,[$sp+7*4]
1252 + pop $srp
1253 + pop $r0
1254 + pop $r9
1255 + pop $r10
1256 + pop $r11
1257 + pop $r12
1258 + pop $r13
1259 + jump [$sp+]
1261 +#endif /* __arch_v32 */
1263 .size _dl_linux_resolve, . - _dl_linux_resolve
1264 diff -urN uClibc-0.9.28.orig/ldso/ldso/dl-elf.c uClibc-0.9.28/ldso/ldso/dl-elf.c
1265 --- uClibc-0.9.28.orig/ldso/ldso/dl-elf.c 2006-05-02 10:47:27.000000000 -0600
1266 +++ uClibc-0.9.28/ldso/ldso/dl-elf.c 2006-05-02 13:50:58.000000000 -0600
1267 @@ -3,7 +3,7 @@
1268 * This file contains the helper routines to load an ELF shared
1269 * library into memory and add the symbol table info to the chain.
1271 - * Copyright (C) 2000-2004 by Erik Andersen <andersen@codepoet.org>
1272 + * Copyright (C) 2000-2006 by Erik Andersen <andersen@codepoet.org>
1273 * Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald,
1274 * David Engel, Hongjiu Lu and Mitch D'Souza
1276 @@ -60,8 +60,8 @@
1277 _dl_cache_addr = (caddr_t) _dl_mmap(0, _dl_cache_size, PROT_READ, MAP_SHARED, fd, 0);
1278 _dl_close(fd);
1279 if (_dl_mmap_check_error(_dl_cache_addr)) {
1280 - _dl_dprintf(2, "%s: can't map cache '%s'\n",
1281 - _dl_progname, LDSO_CACHE);
1282 + _dl_dprintf(2, "%s:%i: can't map '%s'\n",
1283 + _dl_progname, __LINE__, LDSO_CACHE);
1284 return -1;
1287 @@ -115,7 +115,7 @@
1288 #endif
1291 -void
1292 +void
1293 _dl_protect_relro (struct elf_resolve *l)
1295 ElfW(Addr) start = ((l->loadaddr + l->relro_addr)
1296 @@ -136,27 +136,41 @@
1297 search_for_named_library(const char *name, int secure, const char *path_list,
1298 struct dyn_elf **rpnt)
1300 - char *path, *path_n;
1301 - char mylibname[2050];
1302 + char *path, *path_n, *mylibname;
1303 struct elf_resolve *tpnt;
1304 - int done = 0;
1305 + int done;
1307 if (path_list==NULL)
1308 return NULL;
1310 - /* We need a writable copy of this string */
1311 - path = _dl_strdup(path_list);
1312 - if (!path) {
1313 + /* We need a writable copy of this string, but we don't
1314 + * need this allocated permanently since we don't want
1315 + * to leak memory, so use alloca to put path on the stack */
1316 + done = _dl_strlen(path_list);
1317 + path = alloca(done + 1);
1319 + /* another bit of local storage */
1320 + mylibname = alloca(2050);
1322 + /* gcc inlines alloca using a single instruction adjusting
1323 + * the stack pointer and no stack overflow check and thus
1324 + * no NULL error return. No point leaving in dead code... */
1325 +#if 0
1326 + if (!path || !mylibname) {
1327 _dl_dprintf(2, "Out of memory!\n");
1328 _dl_exit(0);
1330 +#endif
1332 + _dl_memcpy(path, path_list, done+1);
1334 /* Unlike ldd.c, don't bother to eliminate double //s */
1336 /* Replace colons with zeros in path_list */
1337 /* : at the beginning or end of path maps to CWD */
1338 /* :: anywhere maps CWD */
1339 - /* "" maps to CWD */
1340 + /* "" maps to CWD */
1341 + done = 0;
1342 path_n = path;
1343 do {
1344 if (*path == 0) {
1345 @@ -180,71 +194,6 @@
1346 return NULL;
1349 -/* Check if the named library is already loaded... */
1350 -struct elf_resolve *_dl_check_if_named_library_is_loaded(const char *full_libname,
1351 - int trace_loaded_objects)
1353 - const char *pnt, *pnt1;
1354 - struct elf_resolve *tpnt1;
1355 - const char *libname, *libname2;
1356 - static const char libc[] = "libc.so.";
1357 - static const char aborted_wrong_lib[] = "%s: aborted attempt to load %s!\n";
1359 - pnt = libname = full_libname;
1361 - _dl_if_debug_dprint("Checking if '%s' is already loaded\n", full_libname);
1362 - /* quick hack to ensure mylibname buffer doesn't overflow. don't
1363 - allow full_libname or any directory to be longer than 1024. */
1364 - if (_dl_strlen(full_libname) > 1024)
1365 - return NULL;
1367 - /* Skip over any initial initial './' and '/' stuff to
1368 - * get the short form libname with no path garbage */
1369 - pnt1 = _dl_strrchr(pnt, '/');
1370 - if (pnt1) {
1371 - libname = pnt1 + 1;
1374 - /* Make sure they are not trying to load the wrong C library!
1375 - * This sometimes happens esp with shared libraries when the
1376 - * library path is somehow wrong! */
1377 -#define isdigit(c) (c >= '0' && c <= '9')
1378 - if ((_dl_strncmp(libname, libc, 8) == 0) && _dl_strlen(libname) >=8 &&
1379 - isdigit(libname[8]))
1381 - /* Abort attempts to load glibc, libc5, etc */
1382 - if ( libname[8]!='0') {
1383 - if (!trace_loaded_objects) {
1384 - _dl_dprintf(2, aborted_wrong_lib, libname, _dl_progname);
1385 - _dl_exit(1);
1387 - return NULL;
1391 - /* Critical step! Weed out duplicates early to avoid
1392 - * function aliasing, which wastes memory, and causes
1393 - * really bad things to happen with weaks and globals. */
1394 - for (tpnt1 = _dl_loaded_modules; tpnt1; tpnt1 = tpnt1->next) {
1396 - /* Skip over any initial initial './' and '/' stuff to
1397 - * get the short form libname with no path garbage */
1398 - libname2 = tpnt1->libname;
1399 - pnt1 = _dl_strrchr(libname2, '/');
1400 - if (pnt1) {
1401 - libname2 = pnt1 + 1;
1404 - if (_dl_strcmp(libname2, libname) == 0) {
1405 - /* Well, that was certainly easy */
1406 - return tpnt1;
1410 - return NULL;
1414 /* Used to return error codes back to dlopen et. al. */
1415 unsigned long _dl_error_number;
1416 unsigned long _dl_internal_error_number;
1417 @@ -271,14 +220,6 @@
1418 libname = pnt + 1;
1421 - /* Critical step! Weed out duplicates early to avoid
1422 - * function aliasing, which wastes memory, and causes
1423 - * really bad things to happen with weaks and globals. */
1424 - if ((tpnt1=_dl_check_if_named_library_is_loaded(libname, trace_loaded_objects))!=NULL) {
1425 - tpnt1->usage_count++;
1426 - return tpnt1;
1429 _dl_if_debug_dprint("\tfind library='%s'; searching\n", libname);
1430 /* If the filename has any '/', try it straight and leave it at that.
1431 For IBCS2 compatibility under linux, we substitute the string
1432 @@ -290,7 +231,6 @@
1433 if (tpnt1) {
1434 return tpnt1;
1436 - //goto goof;
1440 @@ -411,56 +351,45 @@
1441 int i, flags, piclib, infile;
1442 ElfW(Addr) relro_addr = 0;
1443 size_t relro_size = 0;
1445 - /* If this file is already loaded, skip this step */
1446 - tpnt = _dl_check_hashed_files(libname);
1447 - if (tpnt) {
1448 - if (*rpnt) {
1449 - (*rpnt)->next = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
1450 - _dl_memset((*rpnt)->next, 0, sizeof(struct dyn_elf));
1451 - (*rpnt)->next->prev = (*rpnt);
1452 - *rpnt = (*rpnt)->next;
1453 - (*rpnt)->dyn = tpnt;
1454 - tpnt->symbol_scope = _dl_symbol_tables;
1456 - tpnt->usage_count++;
1457 - tpnt->libtype = elf_lib;
1458 - _dl_if_debug_dprint("file='%s'; already loaded\n", libname);
1459 - return tpnt;
1462 - /* If we are in secure mode (i.e. a setu/gid binary using LD_PRELOAD),
1463 - we don't load the library if it isn't setuid. */
1465 - if (secure) {
1466 - struct stat st;
1468 - if (_dl_stat(libname, &st) || !(st.st_mode & S_ISUID))
1469 - return NULL;
1471 + struct stat st;
1473 libaddr = 0;
1474 infile = _dl_open(libname, O_RDONLY, 0);
1475 if (infile < 0) {
1476 -#if 0
1477 - /*
1478 - * NO! When we open shared libraries we may search several paths.
1479 - * it is inappropriate to generate an error here.
1480 - */
1481 - _dl_dprintf(2, "%s: can't open '%s'\n", _dl_progname, libname);
1482 -#endif
1483 _dl_internal_error_number = LD_ERROR_NOFILE;
1484 return NULL;
1487 + if (_dl_fstat(infile, &st) < 0) {
1488 + _dl_internal_error_number = LD_ERROR_NOFILE;
1489 + _dl_close(infile);
1490 + return NULL;
1492 + /* If we are in secure mode (i.e. a setu/gid binary using LD_PRELOAD),
1493 + we don't load the library if it isn't setuid. */
1494 + if (secure)
1495 + if (!(st.st_mode & S_ISUID)) {
1496 + _dl_close(infile);
1497 + return NULL;
1500 + /* Check if file is already loaded */
1501 + for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
1502 + if(tpnt->st_dev == st.st_dev && tpnt->st_ino == st.st_ino) {
1503 + /* Already loaded */
1504 + tpnt->usage_count++;
1505 + _dl_close(infile);
1506 + return tpnt;
1509 header = _dl_mmap((void *) 0, _dl_pagesize, PROT_READ | PROT_WRITE,
1510 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
1511 if (_dl_mmap_check_error(header)) {
1512 - _dl_dprintf(2, "%s: can't map '%s'\n", _dl_progname, libname);
1513 + _dl_dprintf(2, "%s:%i: can't map '%s'\n", _dl_progname, __LINE__, libname);
1514 _dl_internal_error_number = LD_ERROR_MMAP_FAILED;
1515 _dl_close(infile);
1516 return NULL;
1517 - };
1520 _dl_read(infile, header, _dl_pagesize);
1521 epnt = (ElfW(Ehdr) *) (intptr_t) header;
1522 @@ -475,7 +404,7 @@
1523 _dl_close(infile);
1524 _dl_munmap(header, _dl_pagesize);
1525 return NULL;
1526 - };
1529 if ((epnt->e_type != ET_DYN) || (epnt->e_machine != MAGIC1
1530 #ifdef MAGIC2
1531 @@ -490,7 +419,7 @@
1532 _dl_close(infile);
1533 _dl_munmap(header, _dl_pagesize);
1534 return NULL;
1535 - };
1538 ppnt = (ElfW(Phdr) *)(intptr_t) & header[epnt->e_phoff];
1540 @@ -502,7 +431,7 @@
1541 _dl_dprintf(2, "%s: '%s' has more than one dynamic section\n",
1542 _dl_progname, libname);
1543 dynamic_addr = ppnt->p_vaddr;
1544 - };
1547 if (ppnt->p_type == PT_LOAD) {
1548 /* See if this is a PIC library. */
1549 @@ -518,7 +447,7 @@
1552 ppnt++;
1553 - };
1556 maxvma = (maxvma + ADDR_ALIGN) & ~ADDR_ALIGN;
1557 minvma = minvma & ~0xffffU;
1558 @@ -530,12 +459,12 @@
1559 status = (char *) _dl_mmap((char *) (piclib ? 0 : minvma),
1560 maxvma - minvma, PROT_NONE, flags | MAP_ANONYMOUS, -1, 0);
1561 if (_dl_mmap_check_error(status)) {
1562 - _dl_dprintf(2, "%s: can't map %s\n", _dl_progname, libname);
1563 + _dl_dprintf(2, "%s:%i: can't map '%s'\n", _dl_progname, __LINE__, libname);
1564 _dl_internal_error_number = LD_ERROR_MMAP_FAILED;
1565 _dl_close(infile);
1566 _dl_munmap(header, _dl_pagesize);
1567 return NULL;
1568 - };
1570 libaddr = (unsigned long) status;
1571 flags |= MAP_FIXED;
1573 @@ -567,14 +496,14 @@
1574 ppnt->p_offset & OFFS_ALIGN);
1576 if (_dl_mmap_check_error(status)) {
1577 - _dl_dprintf(2, "%s: can't map '%s'\n",
1578 - _dl_progname, libname);
1579 + _dl_dprintf(2, "%s:%i: can't map '%s'\n",
1580 + _dl_progname, __LINE__, libname);
1581 _dl_internal_error_number = LD_ERROR_MMAP_FAILED;
1582 _dl_munmap((char *) libaddr, maxvma - minvma);
1583 _dl_close(infile);
1584 _dl_munmap(header, _dl_pagesize);
1585 return NULL;
1586 - };
1589 /* Pad the last page with zeroes. */
1590 cpnt = (char *) (status + (ppnt->p_vaddr & ADDR_ALIGN) +
1591 @@ -601,21 +530,21 @@
1592 ppnt->p_filesz, LXFLAGS(ppnt->p_flags), flags,
1593 infile, ppnt->p_offset & OFFS_ALIGN);
1594 if (_dl_mmap_check_error(status)) {
1595 - _dl_dprintf(2, "%s: can't map '%s'\n", _dl_progname, libname);
1596 + _dl_dprintf(2, "%s:%i: can't map '%s'\n", _dl_progname, __LINE__, libname);
1597 _dl_internal_error_number = LD_ERROR_MMAP_FAILED;
1598 _dl_munmap((char *) libaddr, maxvma - minvma);
1599 _dl_close(infile);
1600 _dl_munmap(header, _dl_pagesize);
1601 return NULL;
1602 - };
1605 /* if(libaddr == 0 && piclib) {
1606 libaddr = (unsigned long) status;
1607 flags |= MAP_FIXED;
1608 - }; */
1609 - };
1610 + } */
1612 ppnt++;
1613 - };
1615 _dl_close(infile);
1617 /* For a non-PIC library, the addresses are all absolute */
1618 @@ -665,6 +594,8 @@
1619 dynamic_addr, 0);
1620 tpnt->relro_addr = relro_addr;
1621 tpnt->relro_size = relro_size;
1622 + tpnt->st_dev = st.st_dev;
1623 + tpnt->st_ino = st.st_ino;
1624 tpnt->ppnt = (ElfW(Phdr) *)(intptr_t) (tpnt->loadaddr + epnt->e_phoff);
1625 tpnt->n_phent = epnt->e_phnum;
1627 @@ -693,7 +624,7 @@
1628 if (lpnt) {
1629 lpnt = (unsigned long *) (dynamic_info[DT_PLTGOT]);
1630 INIT_GOT(lpnt, tpnt);
1631 - };
1634 _dl_if_debug_dprint("\n\tfile='%s'; generating link map\n", libname);
1635 _dl_if_debug_dprint("\t\tdynamic: %x base: %x\n", dynamic_addr, libaddr);
1636 @@ -714,10 +645,12 @@
1637 ElfW(Addr) reloc_addr;
1639 if (rpnt->next)
1640 - goof += _dl_fixup(rpnt->next, now_flag);
1641 + goof = _dl_fixup(rpnt->next, now_flag);
1642 + if (goof)
1643 + return goof;
1644 tpnt = rpnt->dyn;
1646 - if(!(tpnt->init_flag & RELOCS_DONE))
1647 + if(!(tpnt->init_flag & RELOCS_DONE))
1648 _dl_if_debug_dprint("relocation processing: %s\n", tpnt->libname);
1650 if (unlikely(tpnt->dynamic_info[UNSUPPORTED_RELOC_TYPE])) {
1651 @@ -735,7 +668,6 @@
1652 #endif
1653 if (tpnt->dynamic_info[DT_RELOC_TABLE_ADDR] &&
1654 !(tpnt->init_flag & RELOCS_DONE)) {
1655 - tpnt->init_flag |= RELOCS_DONE;
1656 reloc_addr = tpnt->dynamic_info[DT_RELOC_TABLE_ADDR];
1657 relative_count = tpnt->dynamic_info[DT_RELCONT_IDX];
1658 if (relative_count) { /* Optimize the XX_RELATIVE relocations if possible */
1659 @@ -746,14 +678,14 @@
1660 goof += _dl_parse_relocation_information(rpnt,
1661 reloc_addr,
1662 reloc_size);
1663 + tpnt->init_flag |= RELOCS_DONE;
1665 if (tpnt->dynamic_info[DT_BIND_NOW])
1666 now_flag = RTLD_NOW;
1667 if (tpnt->dynamic_info[DT_JMPREL] &&
1668 (!(tpnt->init_flag & JMP_RELOCS_DONE) ||
1669 (now_flag && !(tpnt->rtld_flags & now_flag)))) {
1670 - tpnt->rtld_flags |= now_flag;
1671 - tpnt->init_flag |= JMP_RELOCS_DONE;
1672 + tpnt->rtld_flags |= now_flag;
1673 if (!(tpnt->rtld_flags & RTLD_NOW)) {
1674 _dl_parse_lazy_relocation_information(rpnt,
1675 tpnt->dynamic_info[DT_JMPREL],
1676 @@ -763,6 +695,7 @@
1677 tpnt->dynamic_info[DT_JMPREL],
1678 tpnt->dynamic_info[DT_PLTRELSZ]);
1680 + tpnt->init_flag |= JMP_RELOCS_DONE;
1682 return goof;
1684 @@ -770,11 +703,18 @@
1685 /* Minimal printf which handles only %s, %d, and %x */
1686 void _dl_dprintf(int fd, const char *fmt, ...)
1688 - long num;
1689 +#if __WORDSIZE > 32
1690 + long int num;
1691 +#else
1692 + int num;
1693 +#endif
1694 va_list args;
1695 char *start, *ptr, *string;
1696 static char *buf;
1698 + if (!fmt)
1699 + return;
1701 buf = _dl_mmap((void *) 0, _dl_pagesize, PROT_READ | PROT_WRITE,
1702 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
1703 if (_dl_mmap_check_error(buf)) {
1704 @@ -784,9 +724,6 @@
1706 start = ptr = buf;
1708 - if (!fmt)
1709 - return;
1711 if (_dl_strlen(fmt) >= (_dl_pagesize - 1)) {
1712 _dl_write(fd, "overflow\n", 11);
1713 _dl_exit(20);
1714 @@ -818,8 +755,11 @@
1715 case 'd':
1717 char tmp[22];
1718 - num = va_arg(args, long);
1720 +#if __WORDSIZE > 32
1721 + num = va_arg(args, long int);
1722 +#else
1723 + num = va_arg(args, int);
1724 +#endif
1725 string = _dl_simple_ltoa(tmp, num);
1726 _dl_write(fd, string, _dl_strlen(string));
1727 break;
1728 @@ -828,8 +768,11 @@
1729 case 'X':
1731 char tmp[22];
1732 - num = va_arg(args, long);
1734 +#if __WORDSIZE > 32
1735 + num = va_arg(args, long int);
1736 +#else
1737 + num = va_arg(args, int);
1738 +#endif
1739 string = _dl_simple_ltoahex(tmp, num);
1740 _dl_write(fd, string, _dl_strlen(string));
1741 break;
1742 @@ -864,8 +807,10 @@
1744 __dl_parse_dynamic_info(dpnt, dynamic_info, debug_addr, load_off);
1747 +/* we want this in ldso.so and libdl.a but nowhere else */
1748 #ifdef __USE_GNU
1749 -#if ! defined LIBDL || (! defined PIC && ! defined __PIC__)
1750 +#if ! defined SHARED || (! defined PIC && ! defined __PIC__)
1752 __dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info, size_t size, void *data), void *data)
1754 @@ -884,6 +829,6 @@
1756 return ret;
1758 -strong_alias(__dl_iterate_phdr, dl_iterate_phdr);
1759 +strong_alias(__dl_iterate_phdr, dl_iterate_phdr)
1760 #endif
1761 #endif
1762 diff -urN uClibc-0.9.28.orig/ldso/ldso/dl-hash.c uClibc-0.9.28/ldso/ldso/dl-hash.c
1763 --- uClibc-0.9.28.orig/ldso/ldso/dl-hash.c 2006-05-02 10:47:27.000000000 -0600
1764 +++ uClibc-0.9.28/ldso/ldso/dl-hash.c 2006-04-28 00:14:35.000000000 -0600
1765 @@ -57,7 +57,7 @@
1766 /* This is the hash function that is used by the ELF linker to generate the
1767 * hash table that each executable and library is required to have. We need
1768 * it to decode the hash table. */
1769 -static inline Elf32_Word _dl_elf_hash(const char *name)
1770 +static inline Elf_Symndx _dl_elf_hash(const char *name)
1772 unsigned long hash=0;
1773 unsigned long tmp;
1774 @@ -77,21 +77,6 @@
1775 return hash;
1778 -/* Check to see if a library has already been added to the hash chain. */
1779 -struct elf_resolve *_dl_check_hashed_files(const char *libname)
1781 - struct elf_resolve *tpnt;
1782 - int len = _dl_strlen(libname);
1784 - for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
1785 - if (_dl_strncmp(tpnt->libname, libname, len) == 0 &&
1786 - (tpnt->libname[len] == '\0' || tpnt->libname[len] == '.'))
1787 - return tpnt;
1790 - return NULL;
1794 * We call this function when we have just read an ELF library or executable.
1795 * We add the relevant info to the symbol chain, so that we can resolve all
1796 @@ -99,9 +84,10 @@
1798 struct elf_resolve *_dl_add_elf_hash_table(const char *libname,
1799 char *loadaddr, unsigned long *dynamic_info, unsigned long dynamic_addr,
1800 + //attribute_unused
1801 unsigned long dynamic_size)
1803 - Elf32_Word *hash_addr;
1804 + Elf_Symndx *hash_addr;
1805 struct elf_resolve *tpnt;
1806 int i;
1808 @@ -125,7 +111,7 @@
1809 tpnt->libtype = loaded_file;
1811 if (dynamic_info[DT_HASH] != 0) {
1812 - hash_addr = (Elf32_Word*)dynamic_info[DT_HASH];
1813 + hash_addr = (Elf_Symndx*)dynamic_info[DT_HASH];
1814 tpnt->nbucket = *hash_addr++;
1815 tpnt->nchain = *hash_addr++;
1816 tpnt->elf_buckets = hash_addr;
1817 diff -urN uClibc-0.9.28.orig/ldso/ldso/dl-startup.c uClibc-0.9.28/ldso/ldso/dl-startup.c
1818 --- uClibc-0.9.28.orig/ldso/ldso/dl-startup.c 2006-05-02 10:47:27.000000000 -0600
1819 +++ uClibc-0.9.28/ldso/ldso/dl-startup.c 2006-04-28 00:14:35.000000000 -0600
1820 @@ -98,7 +98,7 @@
1821 int (*_dl_elf_main) (int, char **, char **);
1823 static void* __rtld_stack_end; /* Points to argc on stack, e.g *((long *)__rtld_stackend) == argc */
1824 -strong_alias(__rtld_stack_end, __libc_stack_end); /* Exported version of __rtld_stack_end */
1825 +strong_alias(__rtld_stack_end, __libc_stack_end) /* Exported version of __rtld_stack_end */
1827 /* When we enter this piece of code, the program stack looks like this:
1828 argc argument counter (integer)
1829 @@ -307,5 +307,11 @@
1830 SEND_STDERR_DEBUG("transfering control to application @ ");
1831 _dl_elf_main = (int (*)(int, char **, char **)) auxvt[AT_ENTRY].a_un.a_val;
1832 SEND_ADDRESS_STDERR_DEBUG(_dl_elf_main, 1);
1834 +#ifndef START
1835 + return _dl_elf_main;
1836 +#else
1837 +#warning You need to update your arch ldso code
1838 START();
1839 +#endif
1841 diff -urN uClibc-0.9.28.orig/ldso/ldso/frv/dl-syscalls.h uClibc-0.9.28/ldso/ldso/frv/dl-syscalls.h
1842 --- uClibc-0.9.28.orig/ldso/ldso/frv/dl-syscalls.h 2006-05-02 10:47:27.000000000 -0600
1843 +++ uClibc-0.9.28/ldso/ldso/frv/dl-syscalls.h 2006-04-28 00:14:35.000000000 -0600
1844 @@ -20,9 +20,10 @@
1846 /* We can't use the real errno in ldso, since it has not yet
1847 * been dynamicly linked in yet. */
1848 +#include "sys/syscall.h"
1849 extern int _dl_errno;
1850 +#undef __set_errno
1851 #define __set_errno(X) {(_dl_errno) = (X);}
1852 -#include "sys/syscall.h"
1853 #include <sys/mman.h>
1855 /* The code below is extracted from libc/sysdeps/linux/frv/_mmap.c */
1856 diff -urN uClibc-0.9.28.orig/ldso/ldso/frv/dl-sysdep.h uClibc-0.9.28/ldso/ldso/frv/dl-sysdep.h
1857 --- uClibc-0.9.28.orig/ldso/ldso/frv/dl-sysdep.h 2006-05-02 10:47:27.000000000 -0600
1858 +++ uClibc-0.9.28/ldso/ldso/frv/dl-sysdep.h 2006-04-28 00:14:35.000000000 -0600
1859 @@ -65,8 +65,6 @@
1861 extern int _dl_linux_resolve(void) __attribute__((__visibility__("hidden")));
1863 -#define do_rem(result, n, base) ((result) = (n) % (base))
1865 /* 16KiB page alignment. Should perhaps be made dynamic using
1866 getpagesize(), based on AT_PAGESZ from auxvt? */
1867 #define PAGE_ALIGN 0xffffc000
1868 diff -urN uClibc-0.9.28.orig/ldso/ldso/frv/elfinterp.c uClibc-0.9.28/ldso/ldso/frv/elfinterp.c
1869 --- uClibc-0.9.28.orig/ldso/ldso/frv/elfinterp.c 2006-05-02 10:47:27.000000000 -0600
1870 +++ uClibc-0.9.28/ldso/ldso/frv/elfinterp.c 2006-04-28 00:14:35.000000000 -0600
1871 @@ -24,7 +24,7 @@
1872 the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
1873 USA. */
1875 -#include <sys/cdefs.h> /* __attribute_used__ */
1876 +#include <features.h>
1878 /* Program to load an ELF binary on a linux system, and run it.
1879 References to symbols in sharable libraries can be resolved by either
1880 @@ -37,7 +37,7 @@
1881 a more than adequate job of explaining everything required to get this
1882 working. */
1884 -struct funcdesc_value volatile *__attribute__((__visibility__("hidden")))
1885 +struct funcdesc_value volatile attribute_hidden *
1886 _dl_linux_resolver (struct elf_resolve *tpnt, int reloc_entry)
1888 int reloc_type;
1889 diff -urN uClibc-0.9.28.orig/ldso/ldso/i386/dl-startup.h uClibc-0.9.28/ldso/ldso/i386/dl-startup.h
1890 --- uClibc-0.9.28.orig/ldso/ldso/i386/dl-startup.h 2006-05-02 10:47:27.000000000 -0600
1891 +++ uClibc-0.9.28/ldso/ldso/i386/dl-startup.h 2006-04-28 00:14:35.000000000 -0600
1892 @@ -3,7 +3,7 @@
1893 * Architecture specific code used by dl-startup.c
1894 * Copyright (C) 2000-2004 by Erik Andersen <andersen@codepoet.org>
1896 -asm(
1897 +__asm__ (
1898 " .text\n"
1899 " .align 16\n"
1900 " .globl _start\n"
1901 @@ -41,9 +41,9 @@
1902 #define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long*) & ARGS)+1)
1904 /* Handle relocation of the symbols in the dynamic loader. */
1905 -static inline
1906 +static __always_inline
1907 void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, unsigned long *reloc_addr,
1908 - unsigned long symbol_addr, unsigned long load_addr, Elf32_Sym *symtab)
1909 + unsigned long symbol_addr, unsigned long load_addr, attribute_unused Elf32_Sym *symtab)
1911 switch (ELF32_R_TYPE(rpnt->r_info))
1913 @@ -64,8 +64,3 @@
1914 _dl_exit(1);
1918 -/* Transfer control to the user's application, once the dynamic loader is
1919 - * done. This routine has to exit the current function, then call the
1920 - * _dl_elf_main function. */
1921 -#define START() return _dl_elf_main
1922 diff -urN uClibc-0.9.28.orig/ldso/ldso/i386/dl-syscalls.h uClibc-0.9.28/ldso/ldso/i386/dl-syscalls.h
1923 --- uClibc-0.9.28.orig/ldso/ldso/i386/dl-syscalls.h 2006-05-02 10:47:27.000000000 -0600
1924 +++ uClibc-0.9.28/ldso/ldso/i386/dl-syscalls.h 2006-04-28 00:14:35.000000000 -0600
1925 @@ -1,5 +1,6 @@
1926 /* We can't use the real errno in ldso, since it has not yet
1927 * been dynamicly linked in yet. */
1928 +#include "sys/syscall.h"
1929 extern int _dl_errno;
1930 +#undef __set_errno
1931 #define __set_errno(X) {(_dl_errno) = (X);}
1932 -#include "sys/syscall.h"
1933 diff -urN uClibc-0.9.28.orig/ldso/ldso/i386/dl-sysdep.h uClibc-0.9.28/ldso/ldso/i386/dl-sysdep.h
1934 --- uClibc-0.9.28.orig/ldso/ldso/i386/dl-sysdep.h 2006-05-02 10:47:27.000000000 -0600
1935 +++ uClibc-0.9.28/ldso/ldso/i386/dl-sysdep.h 2006-04-28 00:14:35.000000000 -0600
1936 @@ -25,8 +25,6 @@
1937 struct elf_resolve;
1938 extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
1940 -#define do_rem(result, n, base) ((result) = (n) % (base))
1942 /* 4096 bytes alignment */
1943 #define PAGE_ALIGN 0xfffff000
1944 #define ADDR_ALIGN 0xfff
1945 @@ -44,16 +42,18 @@
1946 /* Return the link-time address of _DYNAMIC. Conveniently, this is the
1947 first element of the GOT. This must be inlined in a function which
1948 uses global data. */
1949 -static inline Elf32_Addr __attribute__ ((unused))
1950 +static inline Elf32_Addr elf_machine_dynamic (void) attribute_unused;
1951 +static inline Elf32_Addr
1952 elf_machine_dynamic (void)
1954 - register Elf32_Addr *got asm ("%ebx");
1955 + register Elf32_Addr *got __asm__ ("%ebx");
1956 return *got;
1960 /* Return the run-time load address of the shared object. */
1961 -static inline Elf32_Addr __attribute__ ((unused))
1962 +static inline Elf32_Addr elf_machine_load_address (void) attribute_unused;
1963 +static inline Elf32_Addr
1964 elf_machine_load_address (void)
1966 /* It doesn't matter what variable this is, the reference never makes
1967 @@ -61,7 +61,7 @@
1968 via the GOT to make sure the compiler initialized %ebx in time. */
1969 extern int _dl_errno;
1970 Elf32_Addr addr;
1971 - asm ("leal _dl_start@GOTOFF(%%ebx), %0\n"
1972 + __asm__ ("leal _dl_start@GOTOFF(%%ebx), %0\n"
1973 "subl _dl_start@GOT(%%ebx), %0"
1974 : "=r" (addr) : "m" (_dl_errno) : "cc");
1975 return addr;
1976 diff -urN uClibc-0.9.28.orig/ldso/ldso/i386/elfinterp.c uClibc-0.9.28/ldso/ldso/i386/elfinterp.c
1977 --- uClibc-0.9.28.orig/ldso/ldso/i386/elfinterp.c 2006-05-02 10:47:27.000000000 -0600
1978 +++ uClibc-0.9.28/ldso/ldso/i386/elfinterp.c 2006-04-28 00:14:35.000000000 -0600
1979 @@ -67,12 +67,6 @@
1980 strtab = (char *)tpnt->dynamic_info[DT_STRTAB];
1981 symname = strtab + symtab[symtab_index].st_name;
1983 - if (unlikely(reloc_type != R_386_JMP_SLOT)) {
1984 - _dl_dprintf(2, "%s: Incorrect relocation type in jump relocations\n",
1985 - _dl_progname);
1986 - _dl_exit(1);
1989 /* Address of the jump instruction to fix up. */
1990 instr_addr = ((unsigned long)this_reloc->r_offset +
1991 (unsigned long)tpnt->loadaddr);
1992 @@ -81,7 +75,7 @@
1993 /* Get the address of the GOT entry. */
1994 new_addr = _dl_find_hash(symname, tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT);
1995 if (unlikely(!new_addr)) {
1996 - _dl_dprintf(2, "%s: Can't resolve symbol '%s'\n", _dl_progname, symname);
1997 + _dl_dprintf(2, "%s: can't resolve symbol '%s' in lib '%s'.\n", _dl_progname, symname, tpnt->libname);
1998 _dl_exit(1);
2001 @@ -147,15 +141,15 @@
2002 int reloc_type = ELF32_R_TYPE(rpnt->r_info);
2004 #if defined (__SUPPORT_LD_DEBUG__)
2005 - _dl_dprintf(2, "can't handle reloc type %s\n",
2006 - _dl_reltypes(reloc_type));
2007 + _dl_dprintf(2, "can't handle reloc type '%s' in lib '%s'\n",
2008 + _dl_reltypes(reloc_type), tpnt->libname);
2009 #else
2010 - _dl_dprintf(2, "can't handle reloc type %x\n",
2011 - reloc_type);
2012 + _dl_dprintf(2, "can't handle reloc type %x in lib '%s'\n",
2013 + reloc_type, tpnt->libname);
2014 #endif
2015 - _dl_exit(-res);
2016 + return res;
2017 } else if (unlikely(res > 0)) {
2018 - _dl_dprintf(2, "can't resolve symbol\n");
2019 + _dl_dprintf(2, "can't resolve symbol in lib '%s'.\n", tpnt->libname);
2020 return res;
2023 @@ -191,10 +185,8 @@
2024 * might have been intentional. We should not be linking local
2025 * symbols here, so all bases should be covered.
2027 - if (unlikely(!symbol_addr && ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK)) {
2028 - _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname);
2029 - _dl_exit(1);
2030 - };
2031 + if (unlikely(!symbol_addr && ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK))
2032 + return 1;
2035 #if defined (__SUPPORT_LD_DEBUG__)
2036 @@ -233,7 +225,7 @@
2038 break;
2039 default:
2040 - return -1; /* Calls _dl_exit(1). */
2041 + return -1;
2044 #if defined (__SUPPORT_LD_DEBUG__)
2045 @@ -273,7 +265,7 @@
2046 *reloc_addr += (unsigned long)tpnt->loadaddr;
2047 break;
2048 default:
2049 - return -1; /* Calls _dl_exit(1). */
2050 + return -1;
2053 #if defined (__SUPPORT_LD_DEBUG__)
2054 diff -urN uClibc-0.9.28.orig/ldso/ldso/ldso.c uClibc-0.9.28/ldso/ldso/ldso.c
2055 --- uClibc-0.9.28.orig/ldso/ldso/ldso.c 2006-05-02 10:47:27.000000000 -0600
2056 +++ uClibc-0.9.28/ldso/ldso/ldso.c 2006-05-02 13:55:54.000000000 -0600
2057 @@ -39,7 +39,7 @@
2058 #define ALLOW_ZERO_PLTGOT
2060 /* Pull in the value of _dl_progname */
2061 -#include "dl-progname.h"
2062 +#include LDSO_ELFINTERP
2064 /* Global variables used within the shared library loader */
2065 char *_dl_library_path = 0; /* Where we look for libraries */
2066 @@ -74,7 +74,8 @@
2067 * can set an internal breakpoint on it, so that we are notified when the
2068 * address mapping is changed in some way.
2070 -void _dl_debug_state(void)
2071 +void _dl_debug_state(void);
2072 +void _dl_debug_state()
2076 @@ -82,9 +83,78 @@
2077 static unsigned char *_dl_mmap_zero = 0; /* Also used by _dl_malloc */
2079 static struct elf_resolve **init_fini_list;
2080 -static int nlist; /* # items in init_fini_list */
2081 +static unsigned int nlist; /* # items in init_fini_list */
2082 extern void _start(void);
2084 +#ifdef __UCLIBC_HAS_SSP__
2085 +#ifndef __UCLIBC_HAS_SSP_COMPAT__
2086 +#define __UCLIBC_HAS_SSP_COMPAT__ 1
2087 +#endif
2088 +# include <dl-osinfo.h>
2089 +uintptr_t stack_chk_guard;
2090 +# ifndef THREAD_SET_STACK_GUARD
2091 +/* Only exported for architectures that don't store the stack guard canary
2092 + * in local thread area. */
2093 +uintptr_t __stack_chk_guard attribute_relro;
2094 +# ifdef __UCLIBC_HAS_SSP_COMPAT__
2095 +strong_alias(__stack_chk_guard,__guard)
2096 +# endif
2097 +# elif __UCLIBC_HAS_SSP_COMPAT__
2098 +uintptr_t __guard attribute_relro;
2099 +# endif
2100 +#endif
2102 +static void _dl_run_array_forward(unsigned long array, unsigned long size,
2103 + ElfW(Addr) loadaddr)
2105 + if (array != 0) {
2106 + unsigned int j;
2107 + unsigned int jm;
2108 + ElfW(Addr) *addrs;
2109 + jm = size / sizeof (ElfW(Addr));
2110 + addrs = (ElfW(Addr) *) (array + loadaddr);
2111 + for (j = 0; j < jm; ++j) {
2112 + void (*dl_elf_func) (void);
2113 + dl_elf_func = (void (*)(void)) (intptr_t) addrs[j];
2114 + (*dl_elf_func) ();
2119 +void _dl_run_init_array(struct elf_resolve *tpnt);
2120 +void _dl_run_init_array(struct elf_resolve *tpnt)
2122 + _dl_run_array_forward(tpnt->dynamic_info[DT_INIT_ARRAY],
2123 + tpnt->dynamic_info[DT_INIT_ARRAYSZ],
2124 + tpnt->loadaddr);
2127 +void _dl_app_init_array(void);
2128 +void _dl_app_init_array(void)
2130 + _dl_run_init_array(_dl_loaded_modules);
2133 +void _dl_run_fini_array(struct elf_resolve *tpnt);
2134 +void _dl_run_fini_array(struct elf_resolve *tpnt)
2136 + if (tpnt->dynamic_info[DT_FINI_ARRAY]) {
2137 + ElfW(Addr) *array = (ElfW(Addr) *) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI_ARRAY]);
2138 + unsigned int i = (tpnt->dynamic_info[DT_FINI_ARRAYSZ] / sizeof(ElfW(Addr)));
2139 + while (i-- > 0) {
2140 + void (*dl_elf_func) (void);
2141 + dl_elf_func = (void (*)(void)) (intptr_t) array[i];
2142 + (*dl_elf_func) ();
2147 +void _dl_app_fini_array(void);
2148 +void _dl_app_fini_array(void)
2150 + _dl_run_fini_array(_dl_loaded_modules);
2153 static void __attribute__ ((destructor)) __attribute_used__ _dl_fini(void)
2155 int i;
2156 @@ -95,6 +165,7 @@
2157 if (tpnt->init_flag & FINI_FUNCS_CALLED)
2158 continue;
2159 tpnt->init_flag |= FINI_FUNCS_CALLED;
2160 + _dl_run_fini_array(tpnt);
2161 if (tpnt->dynamic_info[DT_FINI]) {
2162 void (*dl_elf_func) (void);
2164 @@ -112,7 +183,8 @@
2165 ElfW(Phdr) *ppnt;
2166 ElfW(Dyn) *dpnt;
2167 char *lpntstr;
2168 - int i, goof = 0, unlazy = 0, trace_loaded_objects = 0;
2169 + unsigned int i;
2170 + int unlazy = 0, trace_loaded_objects = 0;
2171 struct dyn_elf *rpnt;
2172 struct elf_resolve *tcurr;
2173 struct elf_resolve *tpnt1;
2174 @@ -128,6 +200,7 @@
2175 * setup so we can use _dl_dprintf() to print debug noise
2176 * instead of the SEND_STDERR macros used in dl-startup.c */
2178 + _dl_memset(app_tpnt, 0x00, sizeof(*app_tpnt));
2180 /* Store the page size for later use */
2181 _dl_pagesize = (auxvt[AT_PAGESZ].a_un.a_val) ? (size_t) auxvt[AT_PAGESZ].a_un.a_val : PAGE_SIZE;
2182 @@ -168,8 +241,8 @@
2183 * Note that for SUID programs we ignore the settings in
2184 * LD_LIBRARY_PATH.
2186 - if ((auxvt[AT_UID].a_un.a_val == -1 && _dl_suid_ok()) ||
2187 - (auxvt[AT_UID].a_un.a_val != -1 &&
2188 + if ((auxvt[AT_UID].a_un.a_val == (size_t)-1 && _dl_suid_ok()) ||
2189 + (auxvt[AT_UID].a_un.a_val != (size_t)-1 &&
2190 auxvt[AT_UID].a_un.a_val == auxvt[AT_EUID].a_un.a_val &&
2191 auxvt[AT_GID].a_un.a_val == auxvt[AT_EGID].a_un.a_val)) {
2192 _dl_secure = 0;
2193 @@ -196,6 +269,20 @@
2194 unlazy = RTLD_NOW;
2197 + /* sjhill: your TLS init should go before this */
2198 +#ifdef __UCLIBC_HAS_SSP__
2199 + /* Set up the stack checker's canary. */
2200 + stack_chk_guard = _dl_setup_stack_chk_guard ();
2201 +# ifdef THREAD_SET_STACK_GUARD
2202 + THREAD_SET_STACK_GUARD (stack_chk_guard);
2203 +# ifdef __UCLIBC_HAS_SSP_COMPAT__
2204 + __guard = stack_chk_guard;
2205 +# endif
2206 +# else
2207 + __stack_chk_guard = stack_chk_guard;
2208 +# endif
2209 +#endif
2211 /* At this point we are now free to examine the user application,
2212 * and figure out which libraries are supposed to be called. Until
2213 * we have this list, we will not be completely ready for dynamic
2214 @@ -206,12 +293,12 @@
2215 * different from what the ELF header says for ET_DYN/PIE executables.
2218 - int i;
2219 - ElfW(Phdr) *ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
2220 + unsigned int idx;
2221 + ElfW(Phdr) *phdr = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
2223 - for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++)
2224 - if (ppnt->p_type == PT_PHDR) {
2225 - app_tpnt->loadaddr = (ElfW(Addr)) (auxvt[AT_PHDR].a_un.a_val - ppnt->p_vaddr);
2226 + for (idx = 0; idx < auxvt[AT_PHNUM].a_un.a_val; idx++, phdr++)
2227 + if (phdr->p_type == PT_PHDR) {
2228 + app_tpnt->loadaddr = (ElfW(Addr)) (auxvt[AT_PHDR].a_un.a_val - phdr->p_vaddr);
2229 break;
2232 @@ -459,8 +546,8 @@
2233 PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
2234 _dl_close(fd);
2235 if (preload == (caddr_t) -1) {
2236 - _dl_dprintf(_dl_debug_file, "%s: can't map file '%s'\n",
2237 - _dl_progname, LDSO_PRELOAD);
2238 + _dl_dprintf(_dl_debug_file, "%s:%i: can't map '%s'\n",
2239 + _dl_progname, __LINE__, LDSO_PRELOAD);
2240 break;
2243 @@ -528,15 +615,15 @@
2245 nlist = 0;
2246 for (tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next) {
2247 - ElfW(Dyn) *dpnt;
2248 + ElfW(Dyn) *this_dpnt;
2250 nlist++;
2251 - for (dpnt = (ElfW(Dyn) *) tcurr->dynamic_addr; dpnt->d_tag; dpnt++) {
2252 - if (dpnt->d_tag == DT_NEEDED) {
2253 + for (this_dpnt = (ElfW(Dyn) *) tcurr->dynamic_addr; this_dpnt->d_tag; this_dpnt++) {
2254 + if (this_dpnt->d_tag == DT_NEEDED) {
2255 char *name;
2256 struct init_fini_list *tmp;
2258 - lpntstr = (char*) (tcurr->dynamic_info[DT_STRTAB] + dpnt->d_un.d_val);
2259 + lpntstr = (char*) (tcurr->dynamic_info[DT_STRTAB] + this_dpnt->d_un.d_val);
2260 name = _dl_get_last_path_component(lpntstr);
2261 if (_dl_strcmp(name, UCLIBC_LDSO) == 0)
2262 continue;
2263 @@ -633,7 +720,7 @@
2264 ElfW(Ehdr) *epnt = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_val;
2265 ElfW(Phdr) *myppnt = (ElfW(Phdr) *) (load_addr + epnt->e_phoff);
2266 int j;
2269 tpnt = _dl_add_elf_hash_table(tpnt->libname, (char *)load_addr,
2270 tpnt->dynamic_info,
2271 (unsigned long)tpnt->dynamic_addr,
2272 @@ -703,16 +790,14 @@
2273 * order so that COPY directives work correctly.
2275 if (_dl_symbol_tables)
2276 - goof += _dl_fixup(_dl_symbol_tables, unlazy);
2277 + if (_dl_fixup(_dl_symbol_tables, unlazy))
2278 + _dl_exit(-1);
2280 for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
2281 if (tpnt->relro_size)
2282 _dl_protect_relro (tpnt);
2288 /* OK, at this point things are pretty much ready to run. Now we need
2289 * to touch up a few items that are required, and then we can let the
2290 * user application have at it. Note that the dynamic linker itself
2291 @@ -746,6 +831,14 @@
2292 /* Notify the debugger we have added some objects. */
2293 _dl_debug_addr->r_state = RT_ADD;
2294 _dl_debug_state();
2296 + /* Run pre-initialization functions for the executable. */
2297 + _dl_run_array_forward(_dl_loaded_modules->dynamic_info[DT_PREINIT_ARRAY],
2298 + _dl_loaded_modules->dynamic_info[DT_PREINIT_ARRAYSZ],
2299 + _dl_loaded_modules->loadaddr);
2301 + /* Run initialization functions for loaded objects. For the
2302 + main executable, they will be run from __uClibc_main. */
2303 for (i = nlist; i; --i) {
2304 tpnt = init_fini_list[i-1];
2305 tpnt->init_fini = NULL; /* Clear, since alloca was used */
2306 @@ -762,17 +855,9 @@
2308 (*dl_elf_func) ();
2311 -#ifdef _DL_FINI_CRT_COMPAT
2312 - /* arches that have moved their ldso FINI handling should skip this part */
2314 - int (*_dl_atexit) (void *) = (int (*)(void *)) (intptr_t) _dl_find_hash("atexit",
2315 - _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT);
2317 - if (_dl_atexit)
2318 - (*_dl_atexit) (_dl_fini);
2319 + _dl_run_init_array(tpnt);
2321 -#endif
2323 /* Find the real malloc function and make ldso functions use that from now on */
2324 _dl_malloc_function = (void* (*)(size_t)) (intptr_t) _dl_find_hash("malloc",
2325 diff -urN uClibc-0.9.28.orig/ldso/ldso/m68k/dl-startup.h uClibc-0.9.28/ldso/ldso/m68k/dl-startup.h
2326 --- uClibc-0.9.28.orig/ldso/ldso/m68k/dl-startup.h 2006-05-02 10:47:27.000000000 -0600
2327 +++ uClibc-0.9.28/ldso/ldso/m68k/dl-startup.h 2006-04-28 00:14:35.000000000 -0600
2328 @@ -4,23 +4,48 @@
2329 * Copyright (C) 2005 by Erik Andersen <andersen@codepoet.org>
2332 -asm(
2333 - " .text\n"
2334 - " .globl _start\n"
2335 - " .type _start,@function\n"
2336 - "_start:\n"
2337 - " .set _start,_dl_start\n"
2338 - " .size _start,.-_start\n"
2339 - " .previous\n"
2341 +asm ("\
2342 + .text\n\
2343 + .globl _start\n\
2344 + .type _start,@function\n\
2345 +_start:\n\
2346 + move.l %sp, -(%sp)\n\
2347 + jbsr _dl_start\n\
2348 + addq.l #4, %sp\n\
2349 + /* FALLTHRU */\n\
2350 +\n\
2351 + .globl _dl_start_user\n\
2352 +.type _dl_start_user,@function\n\
2353 +_dl_start_user:\n\
2354 + # Save the user entry point address in %a4.\n\
2355 + move.l %d0, %a4\n\
2356 + # See if we were run as a command with the executable file\n\
2357 + # name as an extra leading argument.\n\
2358 + move.l _dl_skip_args(%pc), %d0\n\
2359 + # Pop the original argument count\n\
2360 + move.l (%sp)+, %d1\n\
2361 + # Subtract _dl_skip_args from it.\n\
2362 + sub.l %d0, %d1\n\
2363 + # Adjust the stack pointer to skip _dl_skip_args words.\n\
2364 + lea (%sp, %d0*4), %sp\n\
2365 + # Push back the modified argument count.\n\
2366 + move.l %d1, -(%sp)\n\
2367 + # Pass our finalizer function to the user in %a1.\n\
2368 + lea _dl_fini(%pc), %a1\n\
2369 + # Initialize %fp with the stack pointer.\n\
2370 + move.l %sp, %fp\n\
2371 + # Jump to the user's entry point.\n\
2372 + jmp (%a4)\n\
2373 + .size _dl_start_user, . - _dl_start_user\n\
2374 + .previous");
2376 /* Get a pointer to the argv array. On many platforms this can be just
2377 * the address if the first argument, on other platforms we need to
2378 * do something a little more subtle here. */
2379 -#define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned int *) & ARGS)
2380 +#define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long *) ARGS) + 1)
2382 /* Handle relocation of the symbols in the dynamic loader. */
2383 -static inline
2384 +static __always_inline
2385 void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, unsigned long *reloc_addr,
2386 unsigned long symbol_addr, unsigned long load_addr, Elf32_Sym *symtab)
2388 @@ -59,12 +84,3 @@
2389 _dl_exit (1);
2393 -/* Transfer control to the user's application, once the dynamic loader is
2394 - * done. This routine has to exit the current function, then call the
2395 - * _dl_elf_main function. */
2396 -#define START() \
2397 - __asm__ volatile ( \
2398 - "unlk %%a6\n\t" \
2399 - "jmp %0@" \
2400 - : : "a" (_dl_elf_main));
2401 diff -urN uClibc-0.9.28.orig/ldso/ldso/m68k/dl-syscalls.h uClibc-0.9.28/ldso/ldso/m68k/dl-syscalls.h
2402 --- uClibc-0.9.28.orig/ldso/ldso/m68k/dl-syscalls.h 2006-05-02 10:47:27.000000000 -0600
2403 +++ uClibc-0.9.28/ldso/ldso/m68k/dl-syscalls.h 2006-04-28 00:14:35.000000000 -0600
2404 @@ -1,5 +1,6 @@
2405 /* We can't use the real errno in ldso, since it has not yet
2406 * been dynamicly linked in yet. */
2407 +#include "sys/syscall.h"
2408 extern int _dl_errno;
2409 +#undef __set_errno
2410 #define __set_errno(X) {(_dl_errno) = (X);}
2411 -#include "sys/syscall.h"
2412 diff -urN uClibc-0.9.28.orig/ldso/ldso/m68k/dl-sysdep.h uClibc-0.9.28/ldso/ldso/m68k/dl-sysdep.h
2413 --- uClibc-0.9.28.orig/ldso/ldso/m68k/dl-sysdep.h 2006-05-02 10:47:27.000000000 -0600
2414 +++ uClibc-0.9.28/ldso/ldso/m68k/dl-sysdep.h 2006-04-28 00:14:35.000000000 -0600
2415 @@ -25,10 +25,6 @@
2416 struct elf_resolve;
2417 extern unsigned int _dl_linux_resolver (struct elf_resolve *, int);
2419 -/* Define this because we do not want to call .udiv in the library.
2420 - Not needed for m68k. */
2421 -#define do_rem(result, n, base) ((result) = (n) % (base))
2423 /* 4096 bytes alignment */
2424 #define PAGE_ALIGN 0xfffff000
2425 #define ADDR_ALIGN 0xfff
2426 diff -urN uClibc-0.9.28.orig/ldso/ldso/m68k/elfinterp.c uClibc-0.9.28/ldso/ldso/m68k/elfinterp.c
2427 --- uClibc-0.9.28.orig/ldso/ldso/m68k/elfinterp.c 2006-05-02 10:47:27.000000000 -0600
2428 +++ uClibc-0.9.28/ldso/ldso/m68k/elfinterp.c 2006-04-28 00:14:35.000000000 -0600
2429 @@ -40,6 +40,8 @@
2430 a more than adequate job of explaining everything required to get this
2431 working. */
2433 +#include "ldso.h"
2435 extern int _dl_linux_resolve(void);
2437 unsigned int
2438 @@ -48,20 +50,20 @@
2439 int reloc_type;
2440 ELF_RELOC *this_reloc;
2441 char *strtab;
2442 - Elf32_Sym *symtab;
2443 + ElfW(Sym) *symtab;
2444 int symtab_index;
2445 - ELF_RELOC *rel_addr;
2446 + char *rel_addr;
2447 char *new_addr;
2448 char **got_addr;
2449 - unsigned int instr_addr;
2450 + ElfW(Addr) instr_addr;
2451 char *symname;
2453 - rel_addr = (ELF_RELOC *)tpnt->dynamic_info[DT_JMPREL];
2454 - this_reloc = (ELF_RELOC *)(intptr_t)(rel_addr + reloc_entry);
2455 - reloc_type = ELF32_R_TYPE(this_reloc->r_info);
2456 - symtab_index = ELF32_R_SYM(this_reloc->r_info);
2457 + rel_addr = (char *)tpnt->dynamic_info[DT_JMPREL];
2458 + this_reloc = (ELF_RELOC *)(rel_addr + reloc_entry);
2459 + reloc_type = ELF_R_TYPE(this_reloc->r_info);
2460 + symtab_index = ELF_R_SYM(this_reloc->r_info);
2462 - symtab = (Elf32_Sym *)(intptr_t)tpnt->dynamic_info[DT_SYMTAB];
2463 + symtab = (ElfW(Sym) *)tpnt->dynamic_info[DT_SYMTAB];
2464 strtab = (char *)tpnt->dynamic_info[DT_STRTAB];
2465 symname = strtab + symtab[symtab_index].st_name;
2467 @@ -72,7 +74,7 @@
2470 /* Address of the jump instruction to fix up. */
2471 - instr_addr = ((int)this_reloc->r_offset + (int)tpnt->loadaddr);
2472 + instr_addr = (this_reloc->r_offset + tpnt->loadaddr);
2473 got_addr = (char **)instr_addr;
2475 /* Get the address of the GOT entry. */
2476 @@ -88,159 +90,237 @@
2477 _dl_dprintf(_dl_debug_file, "\nresolve function: %s", symname);
2478 if (_dl_debug_detail)
2479 _dl_dprintf(_dl_debug_file,
2480 - "\n\tpatched: %x ==> %x @ %x",
2481 + "\tpatched: %x ==> %x @ %x\n",
2482 *got_addr, new_addr, got_addr);
2485 - if (!_dl_debug_nofixups) {
2486 - *got_addr = new_addr;
2488 -#else
2489 - *got_addr = new_addr;
2490 + if (!_dl_debug_nofixups)
2491 #endif
2492 + *got_addr = new_addr;
2494 - return (unsigned int)new_addr;
2495 + return (unsigned int)new_addr;
2498 -void
2499 -_dl_parse_lazy_relocation_information(struct dyn_elf *arg_rpnt,
2500 - unsigned long rel_addr, unsigned long rel_size)
2501 +static int
2502 +_dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope,
2503 + unsigned long rel_addr, unsigned long rel_size,
2504 + int (*reloc_fnc)(struct elf_resolve *tpnt, struct dyn_elf *scope,
2505 + ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab))
2507 - int i;
2508 + unsigned int i;
2509 char *strtab;
2510 - int reloc_type;
2511 + ElfW(Sym) *symtab;
2512 + ELF_RELOC *rpnt;
2513 int symtab_index;
2514 - Elf32_Sym *symtab;
2515 - Elf32_Rela *rpnt;
2516 - unsigned int *reloc_addr;
2517 - struct elf_resolve *tpnt = arg_rpnt->dyn;
2519 - /* Now parse the relocation information. */
2520 - rpnt = (Elf32_Rela *)rel_addr;
2521 - rel_size = rel_size / sizeof (Elf32_Rela);
2523 - symtab = (Elf32_Sym *)tpnt->dynamic_info[DT_SYMTAB];
2524 + /* Parse the relocation information. */
2525 + rpnt = (ELF_RELOC *)rel_addr;
2526 + rel_size /= sizeof(ELF_RELOC);
2528 + symtab = (ElfW(Sym) *)tpnt->dynamic_info[DT_SYMTAB];
2529 strtab = (char *)tpnt->dynamic_info[DT_STRTAB];
2531 for (i = 0; i < rel_size; i++, rpnt++) {
2532 - reloc_addr = (int *) (tpnt->loadaddr + (int) rpnt->r_offset);
2533 - reloc_type = ELF32_R_TYPE (rpnt->r_info);
2534 - symtab_index = ELF32_R_SYM (rpnt->r_info);
2535 + int res;
2537 - switch (reloc_type)
2539 - case R_68K_NONE:
2540 - break;
2541 - case R_68K_JMP_SLOT:
2542 - *reloc_addr += (unsigned int) tpnt->loadaddr;
2543 - break;
2544 - default:
2545 - _dl_dprintf (2, "%s: (LAZY) can't handle reloc type ", _dl_progname);
2546 + symtab_index = ELF_R_SYM(rpnt->r_info);
2548 + debug_sym(symtab, strtab, symtab_index);
2549 + debug_reloc(symtab, strtab, rpnt);
2551 + res = reloc_fnc(tpnt, scope, rpnt, symtab, strtab);
2553 + if (res == 0)
2554 + continue;
2556 + _dl_dprintf(2, "\n%s: ", _dl_progname);
2558 + if (symtab_index)
2559 + _dl_dprintf(2, "symbol '%s': ",
2560 + strtab + symtab[symtab_index].st_name);
2562 + if (unlikely(res < 0)) {
2563 + int reloc_type = ELF_R_TYPE(rpnt->r_info);
2565 + _dl_dprintf(2, "can't handle reloc type "
2566 #if defined (__SUPPORT_LD_DEBUG__)
2567 - _dl_dprintf (2, "%s ", _dl_reltypes_tab[reloc_type]);
2568 + "%s\n", _dl_reltypes(reloc_type));
2569 +#else
2570 + "%x\n", reloc_type);
2571 #endif
2572 - if (symtab_index)
2573 - _dl_dprintf (2, "'%s'", strtab + symtab[symtab_index].st_name);
2574 - _dl_dprintf (2, "\n");
2575 - _dl_exit (1);
2576 + _dl_exit(-res);
2577 + } else if (unlikely(res > 0)) {
2578 + _dl_dprintf(2, "can't resolve symbol\n");
2579 + return res;
2583 + return 0;
2586 -int
2587 -_dl_parse_relocation_information(struct dyn_elf *arg_rpnt,
2588 - unsigned long rel_addr, unsigned long rel_size)
2589 +static int
2590 +_dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
2591 + ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab)
2593 - int i;
2594 - char *strtab;
2595 int reloc_type;
2596 - int goof = 0;
2597 - Elf32_Sym *symtab;
2598 - Elf32_Rela *rpnt;
2599 - unsigned int *reloc_addr;
2600 - unsigned int symbol_addr;
2601 int symtab_index;
2602 - struct elf_resolve *tpnt = arg_rpnt->dyn;
2603 - /* Now parse the relocation information */
2604 + char *symname;
2605 + ElfW(Sym) *sym;
2606 + ElfW(Addr) *reloc_addr;
2607 + ElfW(Addr) symbol_addr;
2608 +#if defined (__SUPPORT_LD_DEBUG__)
2609 + ElfW(Addr) old_val;
2610 +#endif
2612 - rpnt = (Elf32_Rela *)rel_addr;
2613 - rel_size = rel_size / sizeof (Elf32_Rela);
2614 + reloc_addr = (ElfW(Addr)*)(tpnt->loadaddr + (unsigned long)rpnt->r_offset);
2615 + reloc_type = ELF_R_TYPE(rpnt->r_info);
2616 + symtab_index = ELF_R_SYM(rpnt->r_info);
2617 + sym = &symtab[symtab_index];
2618 + symbol_addr = 0;
2619 + symname = strtab + sym->st_name;
2621 + if (symtab_index) {
2622 + symbol_addr = (ElfW(Addr))_dl_find_hash(symname, scope, tpnt,
2623 + elf_machine_type_class(reloc_type));
2624 + /*
2625 + * We want to allow undefined references to weak symbols - this
2626 + * might have been intentional. We should not be linking local
2627 + * symbols here, so all bases should be covered.
2628 + */
2629 + if (unlikely(!symbol_addr && ELF_ST_BIND(sym->st_info) != STB_WEAK)) {
2630 + _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname);
2631 + _dl_exit(1);
2632 + };
2635 - symtab = (Elf32_Sym *)tpnt->dynamic_info[DT_SYMTAB];
2636 - strtab = (char *)tpnt->dynamic_info[DT_STRTAB];
2637 +#if defined (__SUPPORT_LD_DEBUG__)
2638 + old_val = *reloc_addr;
2639 +#endif
2641 - for (i = 0; i < rel_size; i++, rpnt++) {
2642 - reloc_addr = (int *) (tpnt->loadaddr + (int) rpnt->r_offset);
2643 - reloc_type = ELF32_R_TYPE (rpnt->r_info);
2644 - symtab_index = ELF32_R_SYM (rpnt->r_info);
2645 - symbol_addr = 0;
2646 - if (symtab_index) {
2647 - symbol_addr = (unsigned int)
2648 - _dl_find_hash (strtab + symtab[symtab_index].st_name,
2649 - tpnt->symbol_scope, tpnt,
2650 - elf_machine_type_class(reloc_type));
2652 - /* We want to allow undefined references to weak symbols -
2653 - this might have been intentional. We should not be
2654 - linking local symbols here, so all bases should be
2655 - covered. */
2656 - if (!symbol_addr
2657 - && ELF32_ST_BIND (symtab[symtab_index].st_info) != STB_WEAK)
2659 - _dl_dprintf (2, "%s: can't resolve symbol '%s'\n",
2660 - _dl_progname, strtab + symtab[symtab_index].st_name);
2661 - _dl_exit (1);
2664 - switch (reloc_type)
2666 - case R_68K_NONE:
2667 - break;
2668 - case R_68K_8:
2669 - *(char *) reloc_addr = symbol_addr + rpnt->r_addend;
2670 - break;
2671 - case R_68K_16:
2672 - *(short *) reloc_addr = symbol_addr + rpnt->r_addend;
2673 - break;
2674 - case R_68K_32:
2675 - *reloc_addr = symbol_addr + rpnt->r_addend;
2676 - break;
2677 - case R_68K_PC8:
2678 - *(char *) reloc_addr = (symbol_addr + rpnt->r_addend
2679 - - (unsigned int) reloc_addr);
2680 - break;
2681 - case R_68K_PC16:
2682 - *(short *) reloc_addr = (symbol_addr + rpnt->r_addend
2683 - - (unsigned int) reloc_addr);
2684 - break;
2685 - case R_68K_PC32:
2686 - *reloc_addr = (symbol_addr + rpnt->r_addend
2687 - - (unsigned int) reloc_addr);
2688 - break;
2689 - case R_68K_GLOB_DAT:
2690 - case R_68K_JMP_SLOT:
2691 - *reloc_addr = symbol_addr;
2692 - break;
2693 - case R_68K_RELATIVE:
2694 - *reloc_addr = ((unsigned int) tpnt->loadaddr
2695 - /* Compatibility kludge. */
2696 - + (rpnt->r_addend ? : *reloc_addr));
2697 - break;
2698 - case R_68K_COPY:
2699 + switch (reloc_type) {
2700 + case R_68K_NONE:
2701 + break;
2702 + case R_68K_8:
2703 + *(char *) reloc_addr = symbol_addr + rpnt->r_addend;
2704 + break;
2705 + case R_68K_16:
2706 + *(short *) reloc_addr = symbol_addr + rpnt->r_addend;
2707 + break;
2708 + case R_68K_32:
2709 + *reloc_addr = symbol_addr + rpnt->r_addend;
2710 + break;
2711 + case R_68K_PC8:
2712 + *(char *) reloc_addr = (symbol_addr + rpnt->r_addend
2713 + - (unsigned int) reloc_addr);
2714 + break;
2715 + case R_68K_PC16:
2716 + *(short *) reloc_addr = (symbol_addr + rpnt->r_addend
2717 + - (unsigned int) reloc_addr);
2718 + break;
2719 + case R_68K_PC32:
2720 + *reloc_addr = (symbol_addr + rpnt->r_addend
2721 + - (unsigned int) reloc_addr);
2722 + break;
2723 + case R_68K_GLOB_DAT:
2724 + case R_68K_JMP_SLOT:
2725 + *reloc_addr = symbol_addr + rpnt->r_addend;
2726 + break;
2727 + /* handled by elf_machine_relative()
2728 + case R_68K_RELATIVE:
2729 + *reloc_addr = ((unsigned int) tpnt->loadaddr
2730 + / * Compatibility kludge. * /
2731 + + (rpnt->r_addend ? : *reloc_addr));
2732 + */
2733 + break;
2734 + case R_68K_COPY:
2735 + if (symbol_addr) {
2736 +#if defined (__SUPPORT_LD_DEBUG__)
2737 + if (_dl_debug_move)
2738 + _dl_dprintf(_dl_debug_file,
2739 + "\t%s move %d bytes from %x to %x\n",
2740 + symname, sym->st_size,
2741 + symbol_addr, reloc_addr);
2742 +#endif
2743 _dl_memcpy ((void *) reloc_addr,
2744 (void *) symbol_addr,
2745 - symtab[symtab_index].st_size);
2746 - break;
2747 - default:
2748 - _dl_dprintf (2, "%s: can't handle reloc type ", _dl_progname);
2749 -#if defined (__SUPPORT_LD_DEBUG__)
2750 - _dl_dprintf (2, "%s ", _dl_reltypes_tab[reloc_type]);
2751 -#endif
2752 - if (symtab_index)
2753 - _dl_dprintf (2, "'%s'", strtab + symtab[symtab_index].st_name);
2754 - _dl_dprintf (2, "\n");
2755 - _dl_exit (1);
2757 + sym->st_size);
2758 + } else
2759 + _dl_dprintf(_dl_debug_file, "no symbol_addr to copy !?\n");
2760 + break;
2762 + default:
2763 + return -1; /* Calls _dl_exit(1). */
2766 +#if defined (__SUPPORT_LD_DEBUG__)
2767 + if (_dl_debug_reloc && _dl_debug_detail)
2768 + _dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x\n",
2769 + old_val, *reloc_addr, reloc_addr);
2770 +#endif
2772 + return 0;
2775 +#undef LAZY_RELOC_WORKS
2776 +#ifdef LAZY_RELOC_WORKS
2777 +static int
2778 +_dl_do_lazy_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
2779 + ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab)
2781 + int reloc_type;
2782 + int symtab_index;
2783 + ElfW(Addr) *reloc_addr;
2784 +#if defined (__SUPPORT_LD_DEBUG__)
2785 + ElfW(Addr) old_val;
2786 +#endif
2788 + (void)scope;
2789 + symtab_index = ELF_R_SYM(rpnt->r_info);
2790 + (void)strtab;
2792 + reloc_addr = (ElfW(Addr)*)(tpnt->loadaddr + rpnt->r_offset);
2793 + reloc_type = ELF_R_TYPE(rpnt->r_info);
2795 +#if defined (__SUPPORT_LD_DEBUG__)
2796 + old_val = *reloc_addr;
2797 +#endif
2799 + switch (reloc_type) {
2800 + case R_68K_NONE:
2801 + break;
2802 + case R_68K_JMP_SLOT:
2803 + *reloc_addr += (unsigned int) tpnt->loadaddr;
2804 + break;
2805 + default:
2806 + _dl_exit(1);
2808 - return goof;
2810 +#if defined (__SUPPORT_LD_DEBUG__)
2811 + if (_dl_debug_reloc && _dl_debug_detail)
2812 + _dl_dprintf(_dl_debug_file, "\tpatched_lazy: %x ==> %x @ %x\n",
2813 + old_val, *reloc_addr, reloc_addr);
2814 +#endif
2816 + return 0;
2818 +#endif
2820 +void
2821 +_dl_parse_lazy_relocation_information(struct dyn_elf *rpnt,
2822 + unsigned long rel_addr,
2823 + unsigned long rel_size)
2825 +#ifdef LAZY_RELOC_WORKS
2826 + (void)_dl_parse(rpnt->dyn, NULL, rel_addr, rel_size, _dl_do_lazy_reloc);
2827 +#else
2828 + _dl_parse_relocation_information(rpnt, rel_addr, rel_size);
2829 +#endif
2832 +int
2833 +_dl_parse_relocation_information(struct dyn_elf *rpnt,
2834 + unsigned long rel_addr,
2835 + unsigned long rel_size)
2837 + return _dl_parse(rpnt->dyn, rpnt->dyn->symbol_scope, rel_addr, rel_size, _dl_do_reloc);
2839 diff -urN uClibc-0.9.28.orig/ldso/ldso/m68k/resolve.S uClibc-0.9.28/ldso/ldso/m68k/resolve.S
2840 --- uClibc-0.9.28.orig/ldso/ldso/m68k/resolve.S 2006-05-02 10:47:27.000000000 -0600
2841 +++ uClibc-0.9.28/ldso/ldso/m68k/resolve.S 2006-04-28 00:14:35.000000000 -0600
2842 @@ -8,14 +8,16 @@
2843 .globl _dl_linux_resolve
2844 .type _dl_linux_resolve,@function
2845 _dl_linux_resolve:
2846 - moveml %a0/%a1,%sp@-
2847 -#ifdef __PIC__
2848 - bsrl _dl_linux_resolver@PLTPC
2849 -#else
2850 - jbsr _dl_linux_resolver
2851 -#endif
2852 - moveml %sp@+,%a0/%a1
2853 - addql #8,%sp
2854 - jmp @(%d0)
2855 -.LFE2:
2856 - .size _dl_linux_resolve,.LFE2-_dl_linux_resolve
2857 + # Save %a0 (struct return address) and %a1.
2858 + move.l %a0, -(%sp)
2859 + move.l %a1, -(%sp)
2860 + # Call the real address resolver.
2861 + jbsr _dl_linux_resolver
2862 + # Restore register %a0 and %a1.
2863 + move.l (%sp)+, %a1
2864 + move.l (%sp)+, %a0
2865 + # Pop parameters
2866 + addq.l #8, %sp
2867 + # Call real function.
2868 + jmp (%d0)
2869 +.size _dl_linux_resolve,.-_dl_linux_resolve
2870 diff -urN uClibc-0.9.28.orig/ldso/ldso/mips/dl-startup.h uClibc-0.9.28/ldso/ldso/mips/dl-startup.h
2871 --- uClibc-0.9.28.orig/ldso/ldso/mips/dl-startup.h 2006-05-02 10:47:27.000000000 -0600
2872 +++ uClibc-0.9.28/ldso/ldso/mips/dl-startup.h 2006-04-28 00:14:35.000000000 -0600
2873 @@ -136,13 +136,3 @@
2874 SEND_STDERR("Aiieeee!"); \
2875 _dl_exit(1); \
2880 - * Transfer control to the user's application, once the dynamic loader
2881 - * is done. This routine has to exit the current function, then
2882 - * call the _dl_elf_main function. For MIPS, we do it in assembly
2883 - * because the stack doesn't get properly restored otherwise. Got look
2884 - * at boot1_arch.h
2885 - */
2886 -#define START() return _dl_elf_main
2887 diff -urN uClibc-0.9.28.orig/ldso/ldso/mips/dl-syscalls.h uClibc-0.9.28/ldso/ldso/mips/dl-syscalls.h
2888 --- uClibc-0.9.28.orig/ldso/ldso/mips/dl-syscalls.h 2006-05-02 10:47:27.000000000 -0600
2889 +++ uClibc-0.9.28/ldso/ldso/mips/dl-syscalls.h 2006-05-02 13:39:25.000000000 -0600
2890 @@ -1,7 +1,8 @@
2891 /* We can't use the real errno in ldso, since it has not yet
2892 * been dynamicly linked in yet. */
2893 +#define __UCLIBC_MMAP_HAS_6_ARGS__
2895 +#include "sys/syscall.h"
2896 extern int _dl_errno;
2897 +#undef __set_errno
2898 #define __set_errno(X) {(_dl_errno) = (X);}
2899 -#include "sys/syscall.h"
2901 -#define MMAP_HAS_6_ARGS
2902 diff -urN uClibc-0.9.28.orig/ldso/ldso/mips/dl-sysdep.h uClibc-0.9.28/ldso/ldso/mips/dl-sysdep.h
2903 --- uClibc-0.9.28.orig/ldso/ldso/mips/dl-sysdep.h 2006-05-02 10:47:27.000000000 -0600
2904 +++ uClibc-0.9.28/ldso/ldso/mips/dl-sysdep.h 2006-04-28 00:14:35.000000000 -0600
2905 @@ -30,7 +30,7 @@
2906 /* Initialization sequence for the application/library GOT. */
2907 #define INIT_GOT(GOT_BASE,MODULE) \
2908 do { \
2909 - unsigned long i; \
2910 + unsigned long idx; \
2912 /* Check if this is the dynamic linker itself */ \
2913 if (MODULE->libtype == program_interpreter) \
2914 @@ -41,9 +41,9 @@
2915 GOT_BASE[1] = (unsigned long) MODULE; \
2917 /* Add load address displacement to all local GOT entries */ \
2918 - i = 2; \
2919 - while (i < MODULE->dynamic_info[DT_MIPS_LOCAL_GOTNO_IDX]) \
2920 - GOT_BASE[i++] += (unsigned long) MODULE->loadaddr; \
2921 + idx = 2; \
2922 + while (idx < MODULE->dynamic_info[DT_MIPS_LOCAL_GOTNO_IDX]) \
2923 + GOT_BASE[idx++] += (unsigned long) MODULE->loadaddr; \
2925 } while (0)
2927 @@ -63,8 +63,6 @@
2928 struct elf_resolve;
2929 void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt, int lazy);
2931 -#define do_rem(result, n, base) ((result) = (n) % (base))
2933 /* 4096 bytes alignment */
2934 #define PAGE_ALIGN 0xfffff000
2935 #define ADDR_ALIGN 0xfff
2936 diff -urN uClibc-0.9.28.orig/ldso/ldso/mips/elfinterp.c uClibc-0.9.28/ldso/ldso/mips/elfinterp.c
2937 --- uClibc-0.9.28.orig/ldso/ldso/mips/elfinterp.c 2006-05-02 10:47:27.000000000 -0600
2938 +++ uClibc-0.9.28/ldso/ldso/mips/elfinterp.c 2006-04-28 00:14:35.000000000 -0600
2939 @@ -27,6 +27,8 @@
2940 * SUCH DAMAGE.
2943 +#include "ldso.h"
2945 extern int _dl_runtime_resolve(void);
2947 #define OFFSET_GP_GOT 0x7ff0
2948 @@ -146,7 +148,6 @@
2949 break;
2950 default:
2952 - int reloc_type = ELF32_R_TYPE(rpnt->r_info);
2953 _dl_dprintf(2, "\n%s: ",_dl_progname);
2955 if (symtab_index)
2956 diff -urN uClibc-0.9.28.orig/ldso/ldso/powerpc/dl-startup.h uClibc-0.9.28/ldso/ldso/powerpc/dl-startup.h
2957 --- uClibc-0.9.28.orig/ldso/ldso/powerpc/dl-startup.h 2006-05-02 10:47:27.000000000 -0600
2958 +++ uClibc-0.9.28/ldso/ldso/powerpc/dl-startup.h 2006-04-28 00:14:35.000000000 -0600
2959 @@ -42,8 +42,10 @@
2960 " bne 2b\n"
2961 " addi 6,6,4\n"
2962 #endif
2963 - /* Pass a termination function pointer (in this case _dl_fini) in r7. */
2964 - " lwz 7,_dl_fini@got(31)\n"
2965 + /* Pass a termination function pointer (in this case _dl_fini) in r3. */
2966 + /* Paulus promized he would keep r3 zero in the exec ABI. */
2967 + " lwz 3,_dl_fini@got(31)\n"
2968 + " mr 7,3\n" /* Pass _dl_fini in r7 to maintain compat */
2969 " bctr\n" /* Jump to entry point */
2970 " .size _start,.-_start\n"
2971 " .previous\n"
2972 @@ -78,9 +80,3 @@
2973 _dl_exit(100+ELF32_R_TYPE((RELP)->r_info));\
2977 - * Transfer control to the user's application, once the dynamic loader
2978 - * is done. This routine has to exit the current function, then
2979 - * call the _dl_elf_main function.
2980 - */
2981 -#define START() return _dl_elf_main
2982 diff -urN uClibc-0.9.28.orig/ldso/ldso/powerpc/dl-syscalls.h uClibc-0.9.28/ldso/ldso/powerpc/dl-syscalls.h
2983 --- uClibc-0.9.28.orig/ldso/ldso/powerpc/dl-syscalls.h 2006-05-02 10:47:27.000000000 -0600
2984 +++ uClibc-0.9.28/ldso/ldso/powerpc/dl-syscalls.h 2006-05-02 13:39:14.000000000 -0600
2985 @@ -1,251 +1,8 @@
2987 - * This file contains the system call macros and syscall
2988 - * numbers used by the shared library loader.
2989 - */
2991 -#define MMAP_HAS_6_ARGS
2993 -#define __NR_exit 1
2994 -#define __NR_read 3
2995 -#define __NR_write 4
2996 -#define __NR_open 5
2997 -#define __NR_close 6
2998 -#define __NR_getpid 20
2999 -#define __NR_getuid 24
3000 -#define __NR_geteuid 49
3001 -#define __NR_getgid 47
3002 -#define __NR_getegid 50
3003 -#define __NR_readlink 85
3004 -#define __NR_mmap 90
3005 -#define __NR_munmap 91
3006 -#define __NR_stat 106
3007 -#define __NR_mprotect 125
3010 /* We can't use the real errno in ldso, since it has not yet
3011 * been dynamicly linked in yet. */
3012 -extern int _dl_errno;
3014 -/* Here are the macros which define how this platform makes
3015 - * system calls. This particular variant does _not_ set
3016 - * errno (note how it is disabled in __syscall_return) since
3017 - * these will get called before the errno symbol is dynamicly
3018 - * linked. */
3020 -#undef __syscall_return
3021 -#define __syscall_return(type) \
3022 - return (__sc_err & 0x10000000 ? _dl_errno = __sc_ret, __sc_ret = -1 : 0), \
3023 - (type) __sc_ret
3025 -#undef __syscall_clobbers
3026 -#define __syscall_clobbers \
3027 - "r9", "r10", "r11", "r12"
3028 - //"r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"
3030 -#undef _syscall0
3031 -#define _syscall0(type,name) \
3032 -type name(void) \
3033 -{ \
3034 - unsigned long __sc_ret, __sc_err; \
3035 - { \
3036 - register unsigned long __sc_0 __asm__ ("r0"); \
3037 - register unsigned long __sc_3 __asm__ ("r3"); \
3039 - __sc_0 = __NR_##name; \
3040 - __asm__ __volatile__ \
3041 - ("sc \n\t" \
3042 - "mfcr %1 " \
3043 - : "=&r" (__sc_3), "=&r" (__sc_0) \
3044 - : "0" (__sc_3), "1" (__sc_0) \
3045 - : "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12" ); \
3046 - __sc_ret = __sc_3; \
3047 - __sc_err = __sc_0; \
3048 - } \
3049 - __syscall_return (type); \
3052 -#undef _syscall1
3053 -#define _syscall1(type,name,type1,arg1) \
3054 -type name(type1 arg1) \
3055 -{ \
3056 - unsigned long __sc_ret, __sc_err; \
3057 - { \
3058 - register unsigned long __sc_0 __asm__ ("r0"); \
3059 - register unsigned long __sc_3 __asm__ ("r3"); \
3061 - __sc_3 = (unsigned long) (arg1); \
3062 - __sc_0 = __NR_##name; \
3063 - __asm__ __volatile__ \
3064 - ("sc \n\t" \
3065 - "mfcr %1 " \
3066 - : "=&r" (__sc_3), "=&r" (__sc_0) \
3067 - : "0" (__sc_3), "1" (__sc_0) \
3068 - : "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12" ); \
3069 - __sc_ret = __sc_3; \
3070 - __sc_err = __sc_0; \
3071 - } \
3072 - __syscall_return (type); \
3075 -#undef _syscall2
3076 -#define _syscall2(type,name,type1,arg1,type2,arg2) \
3077 -type name(type1 arg1, type2 arg2) \
3078 -{ \
3079 - unsigned long __sc_ret, __sc_err; \
3080 - { \
3081 - register unsigned long __sc_0 __asm__ ("r0"); \
3082 - register unsigned long __sc_3 __asm__ ("r3"); \
3083 - register unsigned long __sc_4 __asm__ ("r4"); \
3085 - __sc_3 = (unsigned long) (arg1); \
3086 - __sc_4 = (unsigned long) (arg2); \
3087 - __sc_0 = __NR_##name; \
3088 - __asm__ __volatile__ \
3089 - ("sc \n\t" \
3090 - "mfcr %1 " \
3091 - : "=&r" (__sc_3), "=&r" (__sc_0) \
3092 - : "0" (__sc_3), "1" (__sc_0), \
3093 - "r" (__sc_4) \
3094 - : "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12" ); \
3095 - __sc_ret = __sc_3; \
3096 - __sc_err = __sc_0; \
3097 - } \
3098 - __syscall_return (type); \
3101 -#undef _syscall3
3102 -#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
3103 -type name(type1 arg1, type2 arg2, type3 arg3) \
3104 -{ \
3105 - unsigned long __sc_ret, __sc_err; \
3106 - { \
3107 - register unsigned long __sc_0 __asm__ ("r0"); \
3108 - register unsigned long __sc_3 __asm__ ("r3"); \
3109 - register unsigned long __sc_4 __asm__ ("r4"); \
3110 - register unsigned long __sc_5 __asm__ ("r5"); \
3112 - __sc_3 = (unsigned long) (arg1); \
3113 - __sc_4 = (unsigned long) (arg2); \
3114 - __sc_5 = (unsigned long) (arg3); \
3115 - __sc_0 = __NR_##name; \
3116 - __asm__ __volatile__ \
3117 - ("sc \n\t" \
3118 - "mfcr %1 " \
3119 - : "=&r" (__sc_3), "=&r" (__sc_0) \
3120 - : "0" (__sc_3), "1" (__sc_0), \
3121 - "r" (__sc_4), \
3122 - "r" (__sc_5) \
3123 - : "r6", "r7", "r8", "r9", "r10", "r11", "r12" ); \
3124 - __sc_ret = __sc_3; \
3125 - __sc_err = __sc_0; \
3126 - } \
3127 - __syscall_return (type); \
3130 -#undef _syscall4
3131 -#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
3132 -type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
3133 -{ \
3134 - unsigned long __sc_ret, __sc_err; \
3135 - { \
3136 - register unsigned long __sc_0 __asm__ ("r0"); \
3137 - register unsigned long __sc_3 __asm__ ("r3"); \
3138 - register unsigned long __sc_4 __asm__ ("r4"); \
3139 - register unsigned long __sc_5 __asm__ ("r5"); \
3140 - register unsigned long __sc_6 __asm__ ("r6"); \
3142 - __sc_3 = (unsigned long) (arg1); \
3143 - __sc_4 = (unsigned long) (arg2); \
3144 - __sc_5 = (unsigned long) (arg3); \
3145 - __sc_6 = (unsigned long) (arg4); \
3146 - __sc_0 = __NR_##name; \
3147 - __asm__ __volatile__ \
3148 - ("sc \n\t" \
3149 - "mfcr %1 " \
3150 - : "=&r" (__sc_3), "=&r" (__sc_0) \
3151 - : "0" (__sc_3), "1" (__sc_0), \
3152 - "r" (__sc_4), \
3153 - "r" (__sc_5), \
3154 - "r" (__sc_6) \
3155 - : "r7", "r8", "r9", "r10", "r11", "r12" ); \
3156 - __sc_ret = __sc_3; \
3157 - __sc_err = __sc_0; \
3158 - } \
3159 - __syscall_return (type); \
3162 -#undef _syscall5
3163 -#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
3164 -type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \
3165 -{ \
3166 - unsigned long __sc_ret, __sc_err; \
3167 - { \
3168 - register unsigned long __sc_0 __asm__ ("r0"); \
3169 - register unsigned long __sc_3 __asm__ ("r3"); \
3170 - register unsigned long __sc_4 __asm__ ("r4"); \
3171 - register unsigned long __sc_5 __asm__ ("r5"); \
3172 - register unsigned long __sc_6 __asm__ ("r6"); \
3173 - register unsigned long __sc_7 __asm__ ("r7"); \
3175 - __sc_3 = (unsigned long) (arg1); \
3176 - __sc_4 = (unsigned long) (arg2); \
3177 - __sc_5 = (unsigned long) (arg3); \
3178 - __sc_6 = (unsigned long) (arg4); \
3179 - __sc_7 = (unsigned long) (arg5); \
3180 - __sc_0 = __NR_##name; \
3181 - __asm__ __volatile__ \
3182 - ("sc \n\t" \
3183 - "mfcr %1 " \
3184 - : "=&r" (__sc_3), "=&r" (__sc_0) \
3185 - : "0" (__sc_3), "1" (__sc_0), \
3186 - "r" (__sc_4), \
3187 - "r" (__sc_5), \
3188 - "r" (__sc_6), \
3189 - "r" (__sc_7) \
3190 - : "r8", "r9", "r10", "r11", "r12" ); \
3191 - __sc_ret = __sc_3; \
3192 - __sc_err = __sc_0; \
3193 - } \
3194 - __syscall_return (type); \
3198 -#undef _syscall6
3199 -#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \
3200 -type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) \
3201 -{ \
3202 - unsigned long __sc_ret, __sc_err; \
3203 - { \
3204 - register unsigned long __sc_0 __asm__ ("r0"); \
3205 - register unsigned long __sc_3 __asm__ ("r3"); \
3206 - register unsigned long __sc_4 __asm__ ("r4"); \
3207 - register unsigned long __sc_5 __asm__ ("r5"); \
3208 - register unsigned long __sc_6 __asm__ ("r6"); \
3209 - register unsigned long __sc_7 __asm__ ("r7"); \
3210 - register unsigned long __sc_8 __asm__ ("r8"); \
3212 - __sc_3 = (unsigned long) (arg1); \
3213 - __sc_4 = (unsigned long) (arg2); \
3214 - __sc_5 = (unsigned long) (arg3); \
3215 - __sc_6 = (unsigned long) (arg4); \
3216 - __sc_7 = (unsigned long) (arg5); \
3217 - __sc_8 = (unsigned long) (arg6); \
3218 - __sc_0 = __NR_##name; \
3219 - __asm__ __volatile__ \
3220 - ("sc \n\t" \
3221 - "mfcr %1 " \
3222 - : "=&r" (__sc_3), "=&r" (__sc_0) \
3223 - : "0" (__sc_3), "1" (__sc_0), \
3224 - "r" (__sc_4), \
3225 - "r" (__sc_5), \
3226 - "r" (__sc_6), \
3227 - "r" (__sc_7), \
3228 - "r" (__sc_8) \
3229 - : "r9", "r10", "r11", "r12" ); \
3230 - __sc_ret = __sc_3; \
3231 - __sc_err = __sc_0; \
3232 - } \
3233 - __syscall_return (type); \
3236 +#define __UCLIBC_MMAP_HAS_6_ARGS__
3238 +#include "sys/syscall.h"
3239 +extern int _dl_errno;
3240 +#undef __set_errno
3241 +#define __set_errno(X) {(_dl_errno) = (X);}
3242 diff -urN uClibc-0.9.28.orig/ldso/ldso/powerpc/dl-sysdep.h uClibc-0.9.28/ldso/ldso/powerpc/dl-sysdep.h
3243 --- uClibc-0.9.28.orig/ldso/ldso/powerpc/dl-sysdep.h 2006-05-02 10:47:27.000000000 -0600
3244 +++ uClibc-0.9.28/ldso/ldso/powerpc/dl-sysdep.h 2006-04-28 00:14:35.000000000 -0600
3245 @@ -67,9 +67,6 @@
3246 extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
3247 void _dl_init_got(unsigned long *lpnt,struct elf_resolve *tpnt);
3250 -#define do_rem(result, n, base) ((result) = (n) % (base))
3252 /* 4096 bytes alignment */
3253 #define PAGE_ALIGN 0xfffff000
3254 #define ADDR_ALIGN 0xfff
3255 diff -urN uClibc-0.9.28.orig/ldso/ldso/powerpc/elfinterp.c uClibc-0.9.28/ldso/ldso/powerpc/elfinterp.c
3256 --- uClibc-0.9.28.orig/ldso/ldso/powerpc/elfinterp.c 2006-05-02 10:47:27.000000000 -0600
3257 +++ uClibc-0.9.28/ldso/ldso/powerpc/elfinterp.c 2006-04-28 00:14:35.000000000 -0600
3258 @@ -29,6 +29,8 @@
3259 * SUCH DAMAGE.
3262 +#include "ldso.h"
3264 extern int _dl_linux_resolve(void);
3266 void _dl_init_got(unsigned long *plt,struct elf_resolve *tpnt)
3267 @@ -138,7 +140,7 @@
3268 finaladdr = (Elf32_Addr) _dl_find_hash(symname,
3269 tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT);
3270 if (unlikely(!finaladdr)) {
3271 - _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname);
3272 + _dl_dprintf(2, "%s: can't resolve symbol '%s' in lib '%s'.\n", _dl_progname, symname, tpnt->libname);
3273 _dl_exit(1);
3275 finaladdr += this_reloc->r_addend;
3276 @@ -379,15 +381,15 @@
3278 int reloc_type = ELF32_R_TYPE(rpnt->r_info);
3279 #if defined (__SUPPORT_LD_DEBUG__)
3280 - _dl_dprintf(2, "can't handle reloc type %s\n ", _dl_reltypes(reloc_type));
3281 + _dl_dprintf(2, "can't handle reloc type '%s' in lib '%s'\n", _dl_reltypes(reloc_type), tpnt->libname);
3282 #else
3283 - _dl_dprintf(2, "can't handle reloc type %x\n", reloc_type);
3284 + _dl_dprintf(2, "can't handle reloc type %x in lib '%s'\n", reloc_type, tpnt->libname);
3285 #endif
3286 - _dl_exit(-res);
3287 + return res;
3289 if (unlikely(res >0))
3291 - _dl_dprintf(2, "can't resolve symbol\n");
3292 + _dl_dprintf(2, "can't resolve symbol in lib '%s'.\n", tpnt->libname);
3293 return res;
3296 diff -urN uClibc-0.9.28.orig/ldso/ldso/sh/dl-startup.h uClibc-0.9.28/ldso/ldso/sh/dl-startup.h
3297 --- uClibc-0.9.28.orig/ldso/ldso/sh/dl-startup.h 2006-05-02 10:47:27.000000000 -0600
3298 +++ uClibc-0.9.28/ldso/ldso/sh/dl-startup.h 2006-04-28 00:14:35.000000000 -0600
3299 @@ -55,11 +55,3 @@
3300 default: \
3301 _dl_exit(1); \
3306 - * Transfer control to the user's application, once the dynamic loader
3307 - * is done. This routine has to exit the current function, then
3308 - * call the _dl_elf_main function.
3309 - */
3310 -#define START() return _dl_elf_main;
3311 diff -urN uClibc-0.9.28.orig/ldso/ldso/sh/dl-syscalls.h uClibc-0.9.28/ldso/ldso/sh/dl-syscalls.h
3312 --- uClibc-0.9.28.orig/ldso/ldso/sh/dl-syscalls.h 2006-05-02 10:47:27.000000000 -0600
3313 +++ uClibc-0.9.28/ldso/ldso/sh/dl-syscalls.h 2006-05-02 13:39:28.000000000 -0600
3314 @@ -1,7 +1,8 @@
3315 /* We can't use the real errno in ldso, since it has not yet
3316 * been dynamicly linked in yet. */
3317 +#define __UCLIBC_MMAP_HAS_6_ARGS__
3319 +#include "sys/syscall.h"
3320 extern int _dl_errno;
3321 +#undef __set_errno
3322 #define __set_errno(X) {(_dl_errno) = (X);}
3323 -#include "sys/syscall.h"
3325 -#define MMAP_HAS_6_ARGS
3326 diff -urN uClibc-0.9.28.orig/ldso/ldso/sh/dl-sysdep.h uClibc-0.9.28/ldso/ldso/sh/dl-sysdep.h
3327 --- uClibc-0.9.28.orig/ldso/ldso/sh/dl-sysdep.h 2006-05-02 10:47:27.000000000 -0600
3328 +++ uClibc-0.9.28/ldso/ldso/sh/dl-sysdep.h 2006-04-28 00:14:35.000000000 -0600
3329 @@ -25,7 +25,7 @@
3330 struct elf_resolve;
3331 extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
3333 -static __inline__ unsigned int
3334 +static inline unsigned int
3335 _dl_urem(unsigned int n, unsigned int base)
3337 int res;
3338 @@ -104,7 +104,7 @@
3339 elf_machine_dynamic (void)
3341 register Elf32_Addr *got;
3342 - asm ("mov r12,%0" :"=r" (got));
3343 + __asm__ ("mov r12,%0" :"=r" (got));
3344 return *got;
3347 @@ -113,7 +113,7 @@
3348 elf_machine_load_address (void)
3350 Elf32_Addr addr;
3351 - asm ("mov.l 1f,r0\n\
3352 + __asm__ ("mov.l 1f,r0\n\
3353 mov.l 3f,r2\n\
3354 add r12,r2\n\
3355 mov.l @(r0,r12),r0\n\
3356 diff -urN uClibc-0.9.28.orig/ldso/ldso/sh/elfinterp.c uClibc-0.9.28/ldso/ldso/sh/elfinterp.c
3357 --- uClibc-0.9.28.orig/ldso/ldso/sh/elfinterp.c 2006-05-02 10:47:27.000000000 -0600
3358 +++ uClibc-0.9.28/ldso/ldso/sh/elfinterp.c 2006-04-28 00:14:35.000000000 -0600
3359 @@ -39,6 +39,8 @@
3360 a more than adequate job of explaining everything required to get this
3361 working. */
3363 +#include "ldso.h"
3365 extern int _dl_linux_resolve(void);
3367 unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
3368 diff -urN uClibc-0.9.28.orig/ldso/ldso/sh64/dl-startup.h uClibc-0.9.28/ldso/ldso/sh64/dl-startup.h
3369 --- uClibc-0.9.28.orig/ldso/ldso/sh64/dl-startup.h 2006-05-02 10:47:27.000000000 -0600
3370 +++ uClibc-0.9.28/ldso/ldso/sh64/dl-startup.h 2006-04-28 00:14:35.000000000 -0600
3371 @@ -115,12 +115,3 @@
3372 default: \
3373 _dl_exit(1); \
3377 - * Transfer control to the user's application, once the dynamic loader
3378 - * is done. This routine has to exit the current function, then
3379 - * call the _dl_elf_main function.
3380 - */
3382 -#define START() return _dl_elf_main;
3384 diff -urN uClibc-0.9.28.orig/ldso/ldso/sh64/dl-syscalls.h uClibc-0.9.28/ldso/ldso/sh64/dl-syscalls.h
3385 --- uClibc-0.9.28.orig/ldso/ldso/sh64/dl-syscalls.h 2006-05-02 10:47:27.000000000 -0600
3386 +++ uClibc-0.9.28/ldso/ldso/sh64/dl-syscalls.h 2006-04-28 00:14:35.000000000 -0600
3387 @@ -1,8 +1,9 @@
3388 /* We can't use the real errno in ldso, since it has not yet
3389 * been dynamicly linked in yet. */
3390 +#include "sys/syscall.h"
3391 extern int _dl_errno;
3392 +#undef __set_errno
3393 #define __set_errno(X) {(_dl_errno) = (X);}
3394 -#include "sys/syscall.h"
3396 #undef __syscall_return
3397 #define __syscall_return(type, res) \
3398 diff -urN uClibc-0.9.28.orig/ldso/ldso/sh64/dl-sysdep.h uClibc-0.9.28/ldso/ldso/sh64/dl-sysdep.h
3399 --- uClibc-0.9.28.orig/ldso/ldso/sh64/dl-sysdep.h 2006-05-02 10:47:27.000000000 -0600
3400 +++ uClibc-0.9.28/ldso/ldso/sh64/dl-sysdep.h 2006-04-28 00:14:35.000000000 -0600
3401 @@ -25,8 +25,6 @@
3402 struct elf_resolve;
3403 extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
3405 -#define do_rem(result, n, base) ((result) = (n) % (base))
3407 /* 4096 bytes alignment */
3408 #define PAGE_ALIGN 0xfffff000
3409 #define ADDR_ALIGN 0xfff
3410 diff -urN uClibc-0.9.28.orig/ldso/ldso/sh64/elfinterp.c uClibc-0.9.28/ldso/ldso/sh64/elfinterp.c
3411 --- uClibc-0.9.28.orig/ldso/ldso/sh64/elfinterp.c 2006-05-02 10:47:27.000000000 -0600
3412 +++ uClibc-0.9.28/ldso/ldso/sh64/elfinterp.c 2006-04-28 00:14:35.000000000 -0600
3413 @@ -41,6 +41,8 @@
3414 a more than adequate job of explaining everything required to get this
3415 working. */
3417 +#include "ldso.h"
3419 extern int _dl_linux_resolve(void);
3421 unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
3422 diff -urN uClibc-0.9.28.orig/ldso/ldso/sparc/dl-startup.h uClibc-0.9.28/ldso/ldso/sparc/dl-startup.h
3423 --- uClibc-0.9.28.orig/ldso/ldso/sparc/dl-startup.h 2006-05-02 10:47:27.000000000 -0600
3424 +++ uClibc-0.9.28/ldso/ldso/sparc/dl-startup.h 2006-04-28 00:14:35.000000000 -0600
3425 @@ -3,15 +3,46 @@
3426 * needed for this architecture. See arm/boot1_arch.h for an example of what
3427 * can be done.
3429 -asm(
3430 - " .text\n"
3431 - " .global _start\n"
3432 - " .type _start,%function\n"
3433 - "_start:\n"
3434 - " .set _start,_dl_start\n"
3435 - " .size _start,.-_start\n"
3436 - " .previous\n"
3439 +asm ("\
3440 + .text\n\
3441 + .global _start\n\
3442 + .type _start,%function\n\
3443 + .align 32\n\
3444 +_start:\n\
3445 + /* Allocate space for functions to drop their arguments. */\n\
3446 + sub %sp, 6*4, %sp\n\
3447 + /* Pass pointer to argument block to _dl_start. */\n\
3448 + call _dl_start\n\
3449 + add %sp, 22*4, %o0\n\
3450 + /* FALTHRU */\n\
3451 + .globl _dl_start_user\n\
3452 + .type _dl_start_user, @function\n\
3453 +_dl_start_user:\n\
3454 + /* Load the PIC register. */\n\
3455 +1: call 2f\n\
3456 + sethi %hi(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7\n\
3457 +2: or %l7, %lo(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7\n\
3458 + add %l7, %o7, %l7\n\
3459 + /* Save the user entry point address in %l0 */\n\
3460 + mov %o0, %l0\n\
3461 + /* See if we were run as a command with the executable file name as an\n\
3462 + extra leading argument. If so, adjust the contents of the stack. */\n\
3463 + sethi %hi(_dl_skip_args), %g2\n\
3464 + or %g2, %lo(_dl_skip_args), %g2\n\
3465 + ld [%l7+%g2], %i0\n\
3466 + ld [%i0], %i0\n\
3467 + tst %i0\n\
3468 + /* Pass our finalizer function to the user in %g1. */\n\
3469 + sethi %hi(_dl_fini), %g1\n\
3470 + or %g1, %lo(_dl_fini), %g1\n\
3471 + ld [%l7+%g1], %g1\n\
3472 + /* Jump to the user's entry point and deallocate the extra stack we got. */\n\
3473 + jmp %l0\n\
3474 + add %sp, 6*4, %sp\n\
3475 + .size _dl_start_user, . - _dl_start_user\n\
3476 + .previous\n\
3477 +");
3480 * Get a pointer to the argv array. On many platforms this can be just
3481 @@ -19,17 +50,15 @@
3482 * do something a little more subtle here. We assume that argc is stored
3483 * at the word just below the argvp that we return here.
3485 -#define GET_ARGV(ARGVP, ARGS) __asm__("\tadd %%fp,68,%0\n" : "=r" (ARGVP));
3486 +#define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long *) ARGS) + 1)
3489 * Here is a macro to perform a relocation. This is only used when
3490 * bootstrapping the dynamic loader.
3492 #define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD,SYMTAB) \
3493 - switch(ELF32_R_TYPE((RELP)->r_info)) { \
3494 +switch(ELF_R_TYPE((RELP)->r_info)) { \
3495 case R_SPARC_32: \
3496 - *REL = SYMBOL + (RELP)->r_addend; \
3497 - break; \
3498 case R_SPARC_GLOB_DAT: \
3499 *REL = SYMBOL + (RELP)->r_addend; \
3500 break; \
3501 @@ -38,7 +67,6 @@
3502 REL[2] = 0x81c06000 | (SYMBOL & 0x3ff); \
3503 break; \
3504 case R_SPARC_NONE: \
3505 - break; \
3506 case R_SPARC_WDISP30: \
3507 break; \
3508 case R_SPARC_RELATIVE: \
3509 @@ -46,18 +74,4 @@
3510 break; \
3511 default: \
3512 _dl_exit(1); \
3516 - * Transfer control to the user's application, once the dynamic loader
3517 - * is done. The crt calls atexit with $g1 if not null, so we need to
3518 - * ensure that it contains NULL.
3519 - */
3521 -#define START() \
3522 - __asm__ volatile ( \
3523 - "add %%g0,%%g0,%%g1\n\t" \
3524 - "jmpl %0, %%o7\n\t" \
3525 - "restore %%g0,%%g0,%%g0\n\t" \
3526 - : /*"=r" (status) */ : \
3527 - "r" (_dl_elf_main): "g1", "o0", "o1")
3529 diff -urN uClibc-0.9.28.orig/ldso/ldso/sparc/dl-syscalls.h uClibc-0.9.28/ldso/ldso/sparc/dl-syscalls.h
3530 --- uClibc-0.9.28.orig/ldso/ldso/sparc/dl-syscalls.h 2006-05-02 10:47:27.000000000 -0600
3531 +++ uClibc-0.9.28/ldso/ldso/sparc/dl-syscalls.h 2006-05-02 13:39:21.000000000 -0600
3532 @@ -1,187 +1,8 @@
3534 - * This file contains the system call macros and syscall
3535 - * numbers used by the shared library loader.
3537 - * NOTE: This should be integrated/moved to
3538 - * sysdeps/linux/sparc/bits/syscalls.h at some point ...
3539 - */
3541 -#define MMAP_HAS_6_ARGS
3543 -#define __NR_exit 1
3544 -#define __NR_read 3
3545 -#define __NR_write 4
3546 -#define __NR_open 5
3547 -#define __NR_close 6
3548 -#define __NR_getpid 20
3549 -#define __NR_getuid 24
3550 -#define __NR_getgid 47
3551 -#define __NR_geteuid 49
3552 -#define __NR_getegid 50
3553 -#define __NR_readlink 58
3554 -#define __NR_mmap 71
3555 -#define __NR_munmap 73
3556 -#define __NR_stat 38
3557 -#define __NR_mprotect 74
3559 /* We can't use the real errno in ldso, since it has not yet
3560 * been dynamicly linked in yet. */
3561 +#define __UCLIBC_MMAP_HAS_6_ARGS__
3563 +#include "sys/syscall.h"
3564 extern int _dl_errno;
3565 +#undef __set_errno
3566 #define __set_errno(X) {(_dl_errno) = (X);}
3568 -/* Here are the macros which define how this platform makes
3569 - * system calls. This particular variant does _not_ set
3570 - * errno (note how _dl_errno is used in __syscall_return) since
3571 - * these will get called before the errno symbol is dynamicly
3572 - * linked. */
3574 -#define __syscall_return(type, res) \
3575 -do { \
3576 - if (res < -255 || res >= 0) \
3577 - return (type) res; \
3578 - __set_errno(-res); \
3579 - res = -1; \
3580 - return (type) res; \
3581 -} while (0)
3583 -#define _syscall0(type,name) \
3584 -type name(void) \
3585 -{ \
3586 - long __res; \
3587 - register long __g1 __asm__ ("g1") = __NR_##name; \
3588 - __asm__ __volatile__ ( \
3589 - "t 0x10\n\t" \
3590 - "bcc 1f\n\t" \
3591 - "mov %%o0, %0\n\t" \
3592 - "sub %%g0, %%o0, %0\n\t" \
3593 - "1:\n\t" \
3594 - : "=r" (__res)\
3595 - : "r" (__g1) \
3596 - : "o0", "cc"); \
3597 - __syscall_return(type, __res); \
3600 -#define _syscall1(type,name,type1,arg1) \
3601 -type name(type1 arg1) \
3602 -{ \
3603 - long __res; \
3604 - register long __g1 __asm__ ("g1") = __NR_##name; \
3605 - register long __o0 __asm__ ("o0") = (long)(arg1); \
3606 - __asm__ __volatile__ ( \
3607 - "t 0x10\n\t" \
3608 - "bcc 1f\n\t" \
3609 - "mov %%o0, %0\n\t" \
3610 - "sub %%g0, %%o0, %0\n\t" \
3611 - "1:\n\t" \
3612 - : "=r" (__res), "=&r" (__o0) \
3613 - : "1" (__o0), "r" (__g1) \
3614 - : "cc"); \
3615 - __syscall_return(type, __res); \
3618 -#define _syscall2(type,name,type1,arg1,type2,arg2) \
3619 -type name(type1 arg1,type2 arg2) \
3620 -{ \
3621 - long __res; \
3622 - register long __g1 __asm__ ("g1") = __NR_##name; \
3623 - register long __o0 __asm__ ("o0") = (long)(arg1); \
3624 - register long __o1 __asm__ ("o1") = (long)(arg2); \
3625 - __asm__ __volatile__ ( \
3626 - "t 0x10\n\t" \
3627 - "bcc 1f\n\t" \
3628 - "mov %%o0, %0\n\t" \
3629 - "sub %%g0, %%o0, %0\n\t" \
3630 - "1:\n\t" \
3631 - : "=r" (__res), "=&r" (__o0) \
3632 - : "1" (__o0), "r" (__o1), "r" (__g1) \
3633 - : "cc"); \
3634 - __syscall_return(type, __res); \
3637 -#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
3638 -type name(type1 arg1,type2 arg2,type3 arg3) \
3639 -{ \
3640 - long __res; \
3641 - register long __g1 __asm__ ("g1") = __NR_##name; \
3642 - register long __o0 __asm__ ("o0") = (long)(arg1); \
3643 - register long __o1 __asm__ ("o1") = (long)(arg2); \
3644 - register long __o2 __asm__ ("o2") = (long)(arg3); \
3645 - __asm__ __volatile__ ( \
3646 - "t 0x10\n\t" \
3647 - "bcc 1f\n\t" \
3648 - "mov %%o0, %0\n\t" \
3649 - "sub %%g0, %%o0, %0\n\t" \
3650 - "1:\n\t" \
3651 - : "=r" (__res), "=&r" (__o0) \
3652 - : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1) \
3653 - : "cc"); \
3654 - __syscall_return(type, __res); \
3657 -#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
3658 -type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
3659 -{ \
3660 - long __res; \
3661 - register long __g1 __asm__ ("g1") = __NR_##name; \
3662 - register long __o0 __asm__ ("o0") = (long)(arg1); \
3663 - register long __o1 __asm__ ("o1") = (long)(arg2); \
3664 - register long __o2 __asm__ ("o2") = (long)(arg3); \
3665 - register long __o3 __asm__ ("o3") = (long)(arg4); \
3666 - __asm__ __volatile__ ( \
3667 - "t 0x10\n\t" \
3668 - "bcc 1f\n\t" \
3669 - "mov %%o0, %0\n\t" \
3670 - "sub %%g0, %%o0, %0\n\t" \
3671 - "1:\n\t" \
3672 - : "=r" (__res), "=&r" (__o0) \
3673 - : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__g1) \
3674 - : "cc"); \
3675 - __syscall_return(type, __res); \
3678 -#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
3679 - type5,arg5) \
3680 -type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
3681 -{ \
3682 - long __res; \
3683 - register long __g1 __asm__ ("g1") = __NR_##name; \
3684 - register long __o0 __asm__ ("o0") = (long)(arg1); \
3685 - register long __o1 __asm__ ("o1") = (long)(arg2); \
3686 - register long __o2 __asm__ ("o2") = (long)(arg3); \
3687 - register long __o3 __asm__ ("o3") = (long)(arg4); \
3688 - register long __o4 __asm__ ("o4") = (long)(arg5); \
3689 - __asm__ __volatile__ ( \
3690 - "t 0x10\n\t" \
3691 - "bcc 1f\n\t" \
3692 - "mov %%o0, %0\n\t" \
3693 - "sub %%g0, %%o0, %0\n\t" \
3694 - "1:\n\t" \
3695 - : "=r" (__res), "=&r" (__o0) \
3696 - : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__o4), "r" (__g1) \
3697 - : "cc"); \
3698 - __syscall_return(type, __res); \
3701 -#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
3702 - type5,arg5,type6,arg6) \
3703 -type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \
3704 -{ \
3705 - long __res; \
3706 - register long __g1 __asm__ ("g1") = __NR_##name; \
3707 - register long __o0 __asm__ ("o0") = (long)(arg1); \
3708 - register long __o1 __asm__ ("o1") = (long)(arg2); \
3709 - register long __o2 __asm__ ("o2") = (long)(arg3); \
3710 - register long __o3 __asm__ ("o3") = (long)(arg4); \
3711 - register long __o4 __asm__ ("o4") = (long)(arg5); \
3712 - register long __o5 __asm__ ("o5") = (long)(arg6); \
3713 - __asm__ __volatile__ ( \
3714 - "t 0x10\n\t" \
3715 - "bcc 1f\n\t" \
3716 - "mov %%o0, %0\n\t" \
3717 - "sub %%g0, %%o0, %0\n\t" \
3718 - "1:\n\t" \
3719 - : "=r" (__res), "=&r" (__o0) \
3720 - : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__o4), "r" (__o5), "r" (__g1) \
3721 - : "cc"); \
3722 - __syscall_return(type, __res); \
3724 diff -urN uClibc-0.9.28.orig/ldso/ldso/sparc/dl-sysdep.h uClibc-0.9.28/ldso/ldso/sparc/dl-sysdep.h
3725 --- uClibc-0.9.28.orig/ldso/ldso/sparc/dl-sysdep.h 2006-05-02 10:47:27.000000000 -0600
3726 +++ uClibc-0.9.28/ldso/ldso/sparc/dl-sysdep.h 2006-04-28 00:14:35.000000000 -0600
3727 @@ -1,9 +1,9 @@
3729 +/* vi: set sw=4 ts=4: */
3731 * Various assmbly language/system dependent hacks that are required
3732 * so that we can minimize the amount of platform specific code.
3733 + * Copyright (C) 2000-2004 by Erik Andersen <andersen@codepoet.org>
3735 -#define LINUXBIN
3737 /* Define this if the system uses RELOCA. */
3738 #define ELF_USES_RELOCA
3739 @@ -31,19 +31,14 @@
3740 #undef MAGIC2
3742 /* Used for error messages */
3743 -#define ELF_TARGET "Sparc"
3744 +#define ELF_TARGET "sparc"
3746 -#ifndef COMPILE_ASM
3747 -extern unsigned int _dl_linux_resolver(unsigned int reloc_entry,
3748 - unsigned int * i);
3749 -#endif
3750 +struct elf_resolve;
3751 +unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
3754 * Define this if you want a dynamic loader that works on Solaris.
3756 -#ifndef __linux__
3757 -#define SOLARIS_COMPATIBLE
3758 -#endif
3760 #ifndef COMPILE_ASM
3761 /* Cheap modulo implementation, taken from arm/ld_sysdep.h. */
3762 @@ -87,13 +82,6 @@
3763 #define do_rem(result, n, base) ((result) = sparc_mod(n, base))
3764 #endif
3767 - * dbx wants the binder to have a specific name. Mustn't disappoint it.
3768 - */
3769 -#ifdef SOLARIS_COMPATIBLE
3770 -#define _dl_linux_resolve _elf_rtbndr
3771 -#endif
3773 /* 4096 bytes alignment */
3774 /* ...but 8192 is required for mmap() on sparc64 kernel */
3775 #define PAGE_ALIGN 0xffffe000
3776 @@ -160,7 +148,7 @@
3777 elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr,
3778 Elf32_Word relative_count)
3780 - Elf32_Rela * rpnt = (void *)rel_addr;
3781 + Elf32_Rela * rpnt = (void *)rel_addr;
3782 --rpnt;
3783 do {
3784 Elf32_Addr *const reloc_addr = (void *) (load_off + (++rpnt)->r_offset);
3785 diff -urN uClibc-0.9.28.orig/ldso/ldso/sparc/elfinterp.c uClibc-0.9.28/ldso/ldso/sparc/elfinterp.c
3786 --- uClibc-0.9.28.orig/ldso/ldso/sparc/elfinterp.c 2006-05-02 10:47:27.000000000 -0600
3787 +++ uClibc-0.9.28/ldso/ldso/sparc/elfinterp.c 2006-04-28 00:14:35.000000000 -0600
3788 @@ -33,236 +33,340 @@
3789 an ELF sharable library or a linux style of shared library. */
3791 /* Disclaimer: I have never seen any AT&T source code for SVr4, nor have
3792 - I ever taken any courses on internals. This program was developed using
3793 - information available through the book "UNIX SYSTEM V RELEASE 4,
3794 - Programmers guide: Ansi C and Programming Support Tools", which did
3795 - a more than adequate job of explaining everything required to get this
3796 - working. */
3797 + I ever taken any courses on internals. This program was developed using
3798 + information available through the book "UNIX SYSTEM V RELEASE 4,
3799 + Programmers guide: Ansi C and Programming Support Tools", which did
3800 + a more than adequate job of explaining everything required to get this
3801 + working. */
3803 +/* Some SPARC opcodes we need to use for self-modifying code. */
3804 +#define OPCODE_NOP 0x01000000 /* nop */
3805 +#define OPCODE_CALL 0x40000000 /* call ?; add PC-rel word address */
3806 +#define OPCODE_SETHI_G1 0x03000000 /* sethi ?, %g1; add value>>10 */
3807 +#define OPCODE_JMP_G1 0x81c06000 /* jmp %g1+?; add lo 10 bits of value */
3808 +#define OPCODE_SAVE_SP 0x9de3bfa8 /* save %sp, -(16+6)*4, %sp */
3809 +#define OPCODE_BA 0x30800000 /* b,a ?; add PC-rel word address */
3811 extern int _dl_linux_resolve(void);
3813 -unsigned int _dl_linux_resolver(unsigned int reloc_entry, unsigned int * plt)
3814 +unsigned long
3815 +_dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
3817 - int reloc_type;
3818 - Elf32_Rela * this_reloc;
3819 - char * strtab;
3820 - Elf32_Sym * symtab;
3821 - Elf32_Rela * rel_addr;
3822 - struct elf_resolve * tpnt;
3823 - int symtab_index;
3824 - char * new_addr;
3825 - char ** got_addr;
3826 - unsigned int instr_addr;
3827 - tpnt = (struct elf_resolve *) plt[2];
3829 - rel_addr = (Elf32_Rela *)tpnt->dynamic_info[DT_JMPREL];
3831 - /*
3832 - * Generate the correct relocation index into the .rela.plt section.
3833 - */
3834 - reloc_entry = (reloc_entry >> 10) - 0xc;
3836 - this_reloc = (Elf32_Rela *) ((char *) rel_addr + reloc_entry);
3838 - reloc_type = ELF32_R_TYPE(this_reloc->r_info);
3839 - symtab_index = ELF32_R_SYM(this_reloc->r_info);
3841 - symtab = (Elf32_Sym *)tpnt->dynamic_info[DT_SYMTAB];
3842 - strtab = (char *)tpnt->dynamic_info[DT_STRTAB];
3844 -#ifdef __SUPPORT_LD_DEBUG__
3845 - if (_dl_debug_symbols) {
3846 - _dl_dprintf(2, "tpnt = %x\n", tpnt);
3847 - _dl_dprintf(2, "reloc = %x\n", this_reloc);
3848 - _dl_dprintf(2, "symtab = %x\n", symtab);
3849 - _dl_dprintf(2, "strtab = %x\n", strtab);
3851 -#endif
3854 - if (unlikely(reloc_type != R_SPARC_JMP_SLOT)) {
3855 - _dl_dprintf(2, "%s: incorrect relocation type in jump relocations (%d)\n",
3856 - _dl_progname, reloc_type);
3857 - _dl_exit(30);
3858 - };
3860 - /* Address of jump instruction to fix up */
3861 - instr_addr = ((int)this_reloc->r_offset + (int)tpnt->loadaddr);
3862 - got_addr = (char **) instr_addr;
3864 -#ifdef __SUPPORT_LD_DEBUG__
3865 - if (_dl_debug_symbols) {
3866 - _dl_dprintf(2, "symtab_index %x\n", symtab_index);
3868 - _dl_dprintf(2, "Resolving symbol %s\n",
3869 - strtab + symtab[symtab_index].st_name);
3871 -#endif
3873 - /* Get the address of the GOT entry */
3874 - new_addr = _dl_find_hash(strtab + symtab[symtab_index].st_name,
3875 - tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT);
3876 - if(unlikely(!new_addr)) {
3877 - _dl_dprintf(2, "%s: can't resolve symbol '%s'\n",
3878 - _dl_progname, strtab + symtab[symtab_index].st_name);
3879 - _dl_exit(31);
3880 - };
3881 + int reloc_type;
3882 + ELF_RELOC *this_reloc;
3883 + char *strtab;
3884 + ElfW(Sym) *symtab;
3885 + int symtab_index;
3886 + char *rel_addr;
3887 + char *new_addr;
3888 + char **got_addr;
3889 + ElfW(Addr) instr_addr;
3890 + char *symname;
3892 + rel_addr = (char *)tpnt->dynamic_info[DT_JMPREL];
3893 + /*
3894 + * Generate the correct relocation index into the .rela.plt section.
3895 + */
3896 + reloc_entry = (reloc_entry >> 10) - 0xc;
3898 + this_reloc = (ELF_RELOC *)(rel_addr + reloc_entry);
3899 + reloc_type = ELF_R_TYPE(this_reloc->r_info);
3900 + symtab_index = ELF_R_SYM(this_reloc->r_info);
3902 + symtab = (ElfW(Sym) *)tpnt->dynamic_info[DT_SYMTAB];
3903 + strtab = (char *)tpnt->dynamic_info[DT_STRTAB];
3904 + symname = strtab + symtab[symtab_index].st_name;
3906 + if (unlikely(reloc_type != R_SPARC_JMP_SLOT)) {
3907 + _dl_dprintf(2, "%s: Incorrect relocation type in jump relocations\n",
3908 + _dl_progname);
3909 + _dl_exit(1);
3912 + /* Address of the jump instruction to fix up. */
3913 + instr_addr = (this_reloc->r_offset + tpnt->loadaddr);
3914 + got_addr = (char **)instr_addr;
3916 + /* Get the address of the GOT entry */
3917 + new_addr = _dl_find_hash(symname, tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT);
3918 + if (unlikely(!new_addr)) {
3919 + _dl_dprintf(2, "%s: Can't resolve symbol '%s'\n", _dl_progname, symname);
3920 + _dl_exit(1);
3923 #if defined (__SUPPORT_LD_DEBUG__)
3924 - if ((unsigned long) got_addr < 0x40000000)
3926 - if (_dl_debug_bindings)
3928 - _dl_dprintf(_dl_debug_file, "\nresolve function: %s",
3929 - strtab + symtab[symtab_index].st_name);
3930 - if(_dl_debug_detail) _dl_dprintf(_dl_debug_file,
3931 - "\tpatch %x ==> %x @ %x", *got_addr, new_addr, got_addr);
3932 + if ((unsigned long)got_addr < 0x40000000) {
3933 + if (_dl_debug_bindings) {
3934 + _dl_dprintf(_dl_debug_file, "\nresolve function: %s", symname);
3935 + if (_dl_debug_detail)
3936 + _dl_dprintf(_dl_debug_file,
3937 + "\tpatched: %x ==> %x @ %x\n",
3938 + *got_addr, new_addr, got_addr);
3941 - if (!_dl_debug_nofixups) {
3942 + if (!_dl_debug_nofixups)
3943 +#endif
3945 got_addr[1] = (char *) (0x03000000 | (((unsigned int) new_addr >> 10) & 0x3fffff));
3946 got_addr[2] = (char *) (0x81c06000 | ((unsigned int) new_addr & 0x3ff));
3949 + return (unsigned long)new_addr;
3952 +static int
3953 +_dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope,
3954 + unsigned long rel_addr, unsigned long rel_size,
3955 + int (*reloc_fnc)(struct elf_resolve *tpnt, struct dyn_elf *scope,
3956 + ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab))
3958 + unsigned int i;
3959 + char *strtab;
3960 + ElfW(Sym) *symtab;
3961 + ELF_RELOC *rpnt;
3962 + int symtab_index;
3964 + /* Parse the relocation information. */
3965 + rpnt = (ELF_RELOC *)rel_addr;
3966 + rel_size /= sizeof(ELF_RELOC);
3968 + symtab = (ElfW(Sym) *)tpnt->dynamic_info[DT_SYMTAB];
3969 + strtab = (char *)tpnt->dynamic_info[DT_STRTAB];
3971 + for (i = 0; i < rel_size; i++, rpnt++) {
3972 + int res;
3974 + symtab_index = ELF_R_SYM(rpnt->r_info);
3976 + debug_sym(symtab, strtab, symtab_index);
3977 + debug_reloc(symtab, strtab, rpnt);
3979 + res = reloc_fnc(tpnt, scope, rpnt, symtab, strtab);
3981 + if (res == 0)
3982 + continue;
3984 + _dl_dprintf(2, "\n%s: ", _dl_progname);
3986 + if (symtab_index)
3987 + _dl_dprintf(2, "symbol '%s': ",
3988 + strtab + symtab[symtab_index].st_name);
3990 + if (unlikely(res < 0)) {
3991 + int reloc_type = ELF_R_TYPE(rpnt->r_info);
3993 + _dl_dprintf(2, "can't handle reloc type "
3994 +#if defined (__SUPPORT_LD_DEBUG__)
3995 + "%s\n", _dl_reltypes(reloc_type));
3996 #else
3997 - got_addr[1] = (char *) (0x03000000 | (((unsigned int) new_addr >> 10) & 0x3fffff));
3998 - got_addr[2] = (char *) (0x81c06000 | ((unsigned int) new_addr & 0x3ff));
3999 + "%x\n", reloc_type);
4000 #endif
4001 + _dl_exit(-res);
4002 + } else if (unlikely(res > 0)) {
4003 + _dl_dprintf(2, "can't resolve symbol\n");
4004 + return res;
4008 + return 0;
4011 - _dl_dprintf(2, "Address = %x\n",new_addr);
4012 - _dl_exit(32);
4013 +static int
4014 +_dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
4015 + ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab)
4017 + int reloc_type;
4018 + int symtab_index;
4019 + char *symname;
4020 + ElfW(Sym) *sym;
4021 + ElfW(Addr) *reloc_addr;
4022 + ElfW(Addr) symbol_addr;
4023 +#if defined (__SUPPORT_LD_DEBUG__)
4024 + ElfW(Addr) old_val;
4025 +#endif
4027 + reloc_addr = (ElfW(Addr)*)(tpnt->loadaddr + (unsigned long)rpnt->r_offset);
4028 + reloc_type = ELF_R_TYPE(rpnt->r_info);
4029 + symtab_index = ELF_R_SYM(rpnt->r_info);
4030 + sym = &symtab[symtab_index];
4031 + symbol_addr = 0;
4032 + symname = strtab + sym->st_name;
4034 + if (symtab_index) {
4035 + symbol_addr = (ElfW(Addr))_dl_find_hash(symname, scope, tpnt,
4036 + elf_machine_type_class(reloc_type));
4037 + /*
4038 + * We want to allow undefined references to weak symbols - this
4039 + * might have been intentional. We should not be linking local
4040 + * symbols here, so all bases should be covered.
4041 + */
4042 + if (unlikely(!symbol_addr && ELF_ST_BIND(sym->st_info) != STB_WEAK)) {
4043 + _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname);
4044 + _dl_exit(1);
4048 +#if defined (__SUPPORT_LD_DEBUG__)
4049 + old_val = *reloc_addr;
4050 +#endif
4052 - return (unsigned int) new_addr;
4053 + symbol_addr += rpnt->r_addend; /* Assume copy relocs have zero addend. */
4055 + switch (reloc_type) {
4056 + case R_SPARC_NONE:
4057 + break;
4059 +#if 0 /* these dont really seem to be useful */
4060 + case R_SPARC_8:
4061 + *(char *) reloc_addr = symbol_addr;
4062 + break;
4063 + case R_SPARC_16:
4064 + *(short *) reloc_addr = symbol_addr;
4065 + break;
4066 + case R_SPARC_DISP8:
4067 + *(char *) reloc_addr = (symbol_addr) - (Elf32_Addr) reloc_addr;
4068 + break;
4069 + case R_SPARC_DISP16:
4070 + *(short *) reloc_addr = (symbol_addr) - (Elf32_Addr) reloc_addr;
4071 + break;
4072 +#endif
4074 + case R_SPARC_DISP32:
4075 + *reloc_addr = symbol_addr - (unsigned int) reloc_addr;
4076 + break;
4078 + case R_SPARC_LO10:
4079 + if (!symbol_addr)
4080 + symbol_addr = tpnt->loadaddr + rpnt->r_addend;
4081 + else
4082 + symbol_addr += rpnt->r_addend;
4083 + *reloc_addr = (*reloc_addr & ~0x3ff)|(symbol_addr & 0x3ff);
4084 + break;
4086 + case R_SPARC_GLOB_DAT:
4087 + case R_SPARC_32:
4088 + *reloc_addr = symbol_addr;
4089 + break;
4091 + case R_SPARC_JMP_SLOT:
4093 +value = symbol_addr;
4094 +value += reloc->r_addend;
4095 +disp = value - reloc_addr;
4096 +reloc_addr[1] = OPCODE_JMP_G1 | (value & 0x3ff);
4097 +reloc_addr[0] = OPCODE_SETHI_G1 | (value >> 10);
4098 + reloc_addr[1] = OPCODE_JMP_G1 | ((symbol_addr-(Elf32_Addr)reloc_addr) & 0x3ff);
4099 + reloc_addr[0] = OPCODE_SETHI_G1 | ((symbol_addr-(Elf32_Addr)reloc_addr) >> 10);
4101 + reloc_addr[1] = 0x03000000 | ((symbol_addr >> 10) & 0x3fffff);
4102 + reloc_addr[2] = 0x81c06000 | (symbol_addr & 0x3ff);
4103 + break;
4105 + case R_SPARC_RELATIVE:
4106 + *reloc_addr += tpnt->loadaddr + rpnt->r_addend;
4107 + break;
4109 + case R_SPARC_WDISP30:
4110 + *reloc_addr = (*reloc_addr & 0xc0000000)|
4111 + ((symbol_addr - (unsigned int) reloc_addr) >> 2);
4112 + break;
4114 + case R_SPARC_HI22:
4115 + if (!symbol_addr)
4116 + symbol_addr = tpnt->loadaddr + rpnt->r_addend;
4117 + else
4118 + symbol_addr += rpnt->r_addend;
4119 + *reloc_addr = (*reloc_addr & 0xffc00000) | (symbol_addr >> 10);
4120 + break;
4122 + case R_SPARC_COPY:
4123 + if (symbol_addr) {
4124 +#if defined (__SUPPORT_LD_DEBUG__)
4125 + if (_dl_debug_move)
4126 + _dl_dprintf(_dl_debug_file,
4127 + "\t%s move %d bytes from %x to %x\n",
4128 + symname, sym->st_size,
4129 + symbol_addr, reloc_addr);
4130 +#endif
4132 + _dl_memcpy((char *)reloc_addr,
4133 + (char *)symbol_addr,
4134 + sym->st_size);
4135 + } else
4136 + _dl_dprintf(_dl_debug_file, "no symbol_addr to copy !?\n");
4137 + break;
4138 + default:
4139 + return -1; /* Calls _dl_exit(1). */
4142 +#if defined (__SUPPORT_LD_DEBUG__)
4143 + if (_dl_debug_reloc && _dl_debug_detail)
4144 + _dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x\n",
4145 + old_val, *reloc_addr, reloc_addr);
4146 +#endif
4148 + return 0;
4151 +#undef __SPARC_LAZY_RELOC_WORKS
4152 +#ifdef __SPARC_LAZY_RELOC_WORKS
4153 +static int
4154 +_dl_do_lazy_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
4155 + ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab)
4157 + int reloc_type;
4158 + int symtab_index;
4159 + ElfW(Addr) *reloc_addr;
4160 +#if defined (__SUPPORT_LD_DEBUG__)
4161 + ElfW(Addr) old_val;
4162 +#endif
4164 + (void)scope;
4165 + symtab_index = ELF_R_SYM(rpnt->r_info);
4166 + (void)strtab;
4168 + reloc_addr = (ElfW(Addr)*)(tpnt->loadaddr + rpnt->r_offset);
4169 + reloc_type = ELF_R_TYPE(rpnt->r_info);
4171 +#if defined (__SUPPORT_LD_DEBUG__)
4172 + old_val = *reloc_addr;
4173 +#endif
4175 + switch (reloc_type) {
4176 + case R_SPARC_NONE:
4177 + break;
4178 + case R_SPARC_JMP_SLOT:
4179 + break;
4180 + default:
4181 + _dl_exit(1);
4184 +#if defined (__SUPPORT_LD_DEBUG__)
4185 + if (_dl_debug_reloc && _dl_debug_detail)
4186 + _dl_dprintf(_dl_debug_file, "\tpatched_lazy: %x ==> %x @ %x\n",
4187 + old_val, *reloc_addr, reloc_addr);
4188 +#endif
4190 + return 0;
4192 +#endif
4194 -void _dl_parse_lazy_relocation_information(struct dyn_elf *arg_rpnt,
4195 - unsigned long rel_addr, unsigned long rel_size)
4197 - int i;
4198 - char * strtab;
4199 - int reloc_type;
4200 - int symtab_index;
4201 - Elf32_Sym * symtab;
4202 - Elf32_Rela * rpnt;
4203 - unsigned int * reloc_addr;
4204 - struct elf_resolve * tpnt = arg_rpnt->dyn;
4206 - /* Now parse the relocation information */
4207 - rpnt = (Elf32_Rela *)rel_addr;
4209 - symtab = (Elf32_Sym *)tpnt->dynamic_info[DT_SYMTAB];
4210 - strtab = ( char *)tpnt->dynamic_info[DT_STRTAB];
4212 - for(i=0; i< rel_size; i += sizeof(Elf32_Rela), rpnt++){
4213 - reloc_addr = (int *) (tpnt->loadaddr + (int)rpnt->r_offset);
4214 - reloc_type = ELF32_R_TYPE(rpnt->r_info);
4215 - symtab_index = ELF32_R_SYM(rpnt->r_info);
4217 - switch(reloc_type){
4218 - case R_SPARC_NONE:
4219 - break;
4220 - case R_SPARC_JMP_SLOT:
4221 - break;
4222 - default:
4223 - _dl_dprintf(2, "%s: (LAZY) can't handle reloc type ", _dl_progname);
4224 -#if defined (__SUPPORT_LD_DEBUG__)
4225 - _dl_dprintf(2, "%s ", _dl_reltypes_tab[reloc_type]);
4226 -#endif
4227 - if(symtab_index) _dl_dprintf(2, "'%s'\n",
4228 - strtab + symtab[symtab_index].st_name);
4229 - _dl_exit(33);
4230 - };
4231 - };
4234 -int _dl_parse_relocation_information(struct dyn_elf *arg_rpnt,
4235 - unsigned long rel_addr, unsigned long rel_size)
4237 - int i;
4238 - char * strtab;
4239 - int reloc_type;
4240 - int goof = 0;
4241 - Elf32_Sym * symtab;
4242 - Elf32_Rela * rpnt;
4243 - unsigned int * reloc_addr;
4244 - unsigned int symbol_addr;
4245 - int symtab_index;
4246 - struct elf_resolve * tpnt = arg_rpnt->dyn;
4247 - /* Now parse the relocation information */
4249 - rpnt = (Elf32_Rela *)rel_addr;
4251 - symtab = (Elf32_Sym *)tpnt->dynamic_info[DT_SYMTAB];
4252 - strtab = ( char *)tpnt->dynamic_info[DT_STRTAB];
4254 - for(i=0; i< rel_size; i+= sizeof(Elf32_Rela), rpnt++){
4255 - reloc_addr = (int *) (tpnt->loadaddr + (int)rpnt->r_offset);
4256 - reloc_type = ELF32_R_TYPE(rpnt->r_info);
4257 - symtab_index = ELF32_R_SYM(rpnt->r_info);
4258 - symbol_addr = 0;
4260 - if(symtab_index) {
4262 - symbol_addr = (unsigned int)
4263 - _dl_find_hash(strtab + symtab[symtab_index].st_name,
4264 - tpnt->symbol_scope, tpnt, elf_machine_type_class(reloc_type));
4266 - if(!symbol_addr &&
4267 - ELF32_ST_BIND(symtab [symtab_index].st_info) != STB_WEAK) {
4268 - _dl_dprintf (2, "%s: can't resolve symbol '%s'\n",
4269 - _dl_progname, strtab + symtab[symtab_index].st_name);
4270 - _dl_exit (1);
4271 - };
4272 - };
4273 - switch(reloc_type){
4274 - case R_SPARC_NONE:
4275 - break;
4276 - case R_SPARC_32:
4277 - *reloc_addr = symbol_addr + rpnt->r_addend;
4278 - break;
4279 - case R_SPARC_DISP32:
4280 - *reloc_addr = symbol_addr + rpnt->r_addend - (unsigned int) reloc_addr;
4281 - break;
4282 - case R_SPARC_GLOB_DAT:
4283 - *reloc_addr = symbol_addr + rpnt->r_addend;
4284 - break;
4285 - case R_SPARC_JMP_SLOT:
4286 - reloc_addr[1] = 0x03000000 | ((symbol_addr >> 10) & 0x3fffff);
4287 - reloc_addr[2] = 0x81c06000 | (symbol_addr & 0x3ff);
4288 - break;
4289 - case R_SPARC_RELATIVE:
4290 - *reloc_addr += (unsigned int) tpnt->loadaddr + rpnt->r_addend;
4291 - break;
4292 - case R_SPARC_HI22:
4293 - if (!symbol_addr)
4294 - symbol_addr = tpnt->loadaddr + rpnt->r_addend;
4295 - else
4296 - symbol_addr += rpnt->r_addend;
4297 - *reloc_addr = (*reloc_addr & 0xffc00000)|(symbol_addr >> 10);
4298 - break;
4299 - case R_SPARC_LO10:
4300 - if (!symbol_addr)
4301 - symbol_addr = tpnt->loadaddr + rpnt->r_addend;
4302 - else
4303 - symbol_addr += rpnt->r_addend;
4304 - *reloc_addr = (*reloc_addr & ~0x3ff)|(symbol_addr & 0x3ff);
4305 - break;
4306 - case R_SPARC_WDISP30:
4307 - *reloc_addr = (*reloc_addr & 0xc0000000)|
4308 - ((symbol_addr - (unsigned int) reloc_addr) >> 2);
4309 - break;
4310 - case R_SPARC_COPY:
4311 - _dl_memcpy((void *) reloc_addr, (void *) symbol_addr, symtab[symtab_index].st_size);
4312 - break;
4313 - default:
4314 - _dl_dprintf(2, "%s: can't handle reloc type ", _dl_progname);
4315 -#if defined (__SUPPORT_LD_DEBUG__)
4316 - _dl_dprintf(2, "%s ", _dl_reltypes_tab[reloc_type]);
4317 -#endif
4318 - if (symtab_index)
4319 - _dl_dprintf(2, "'%s'\n", strtab + symtab[symtab_index].st_name);
4320 - _dl_exit(34);
4321 - };
4322 +void
4323 +_dl_parse_lazy_relocation_information(struct dyn_elf *rpnt,
4324 + unsigned long rel_addr,
4325 + unsigned long rel_size)
4327 +#ifdef __SPARC_LAZY_RELOC_WORKS
4328 + (void)_dl_parse(rpnt->dyn, NULL, rel_addr, rel_size, _dl_do_lazy_reloc);
4329 +#else
4330 + _dl_parse_relocation_information(rpnt, rel_addr, rel_size);
4331 +#endif
4334 - };
4335 - return goof;
4336 +int
4337 +_dl_parse_relocation_information(struct dyn_elf *rpnt,
4338 + unsigned long rel_addr,
4339 + unsigned long rel_size)
4341 + return _dl_parse(rpnt->dyn, rpnt->dyn->symbol_scope, rel_addr, rel_size, _dl_do_reloc);
4343 diff -urN uClibc-0.9.28.orig/ldso/ldso/x86_64/dl-debug.h uClibc-0.9.28/ldso/ldso/x86_64/dl-debug.h
4344 --- uClibc-0.9.28.orig/ldso/ldso/x86_64/dl-debug.h 2006-05-02 10:47:27.000000000 -0600
4345 +++ uClibc-0.9.28/ldso/ldso/x86_64/dl-debug.h 2006-04-28 00:14:35.000000000 -0600
4346 @@ -30,7 +30,10 @@
4349 static const char *_dl_reltypes_tab[] = {
4350 - [0] "R_X86_64_NONE", "R_X86_64_64", "R_X86_64_PC32", "R_X86_64_GOT32",
4351 - [4] "R_X86_64_PLT32", "R_X86_64_COPY", "R_X86_64_GLOB_DAT", "R_X86_64_JUMP_SLOT",
4352 - [8] "R_X86_64_RELATIVE", "R_X86_64_GOTPCREL", "R_X86_64_32"
4353 + [ 0] "R_X86_64_NONE", "R_X86_64_64", "R_X86_64_PC32", "R_X86_64_GOT32",
4354 + [ 4] "R_X86_64_PLT32", "R_X86_64_COPY", "R_X86_64_GLOB_DAT", "R_X86_64_JUMP_SLOT",
4355 + [ 8] "R_X86_64_RELATIVE", "R_X86_64_GOTPCREL", "R_X86_64_32", "R_X86_64_32S",
4356 + [12] "R_X86_64_16", "R_X86_64_PC16", "R_X86_64_8", "R_X86_64_PC8",
4357 + [16] "R_X86_64_DTPMOD64", "R_X86_64_DTPOFF64", "R_X86_64_TPOFF64", "R_X86_64_TLSGD",
4358 + [20] "R_X86_64_TLSLD", "R_X86_64_DTPOFF32", "R_X86_64_GOTTPOFF", "R_X86_64_TPOFF32"
4360 diff -urN uClibc-0.9.28.orig/ldso/ldso/x86_64/dl-startup.h uClibc-0.9.28/ldso/ldso/x86_64/dl-startup.h
4361 --- uClibc-0.9.28.orig/ldso/ldso/x86_64/dl-startup.h 2006-05-02 10:47:27.000000000 -0600
4362 +++ uClibc-0.9.28/ldso/ldso/x86_64/dl-startup.h 2006-04-28 00:14:35.000000000 -0600
4363 @@ -6,7 +6,7 @@
4365 * Parts taken from glibc/sysdeps/x86_64/dl-machine.h
4367 -asm(
4368 +__asm__ (
4369 " .text\n"
4370 " .align 16\n"
4371 " .global _start\n"
4372 @@ -42,10 +42,10 @@
4374 /* Handle relocation of the symbols in the dynamic loader. */
4375 static __always_inline
4376 -void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, unsigned long *reloc_addr,
4377 - unsigned long symbol_addr, unsigned long load_addr, Elf64_Sym *sym)
4378 +void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, ElfW(Addr) *reloc_addr,
4379 + ElfW(Addr) symbol_addr, ElfW(Addr) load_addr, ElfW(Sym) *sym)
4381 - switch (ELF64_R_TYPE(rpnt->r_info)) {
4382 + switch (ELF_R_TYPE(rpnt->r_info)) {
4383 case R_X86_64_GLOB_DAT:
4384 case R_X86_64_JUMP_SLOT:
4385 *reloc_addr = symbol_addr + rpnt->r_addend;
4386 @@ -63,8 +63,3 @@
4387 _dl_exit(1);
4391 -/* Transfer control to the user's application, once the dynamic loader is
4392 - * done. This routine has to exit the current function, then call the
4393 - * _dl_elf_main function. */
4394 -#define START() return _dl_elf_main
4395 diff -urN uClibc-0.9.28.orig/ldso/ldso/x86_64/dl-syscalls.h uClibc-0.9.28/ldso/ldso/x86_64/dl-syscalls.h
4396 --- uClibc-0.9.28.orig/ldso/ldso/x86_64/dl-syscalls.h 2006-05-02 10:47:27.000000000 -0600
4397 +++ uClibc-0.9.28/ldso/ldso/x86_64/dl-syscalls.h 2006-05-02 13:39:17.000000000 -0600
4398 @@ -1,7 +1,8 @@
4399 /* We can't use the real errno in ldso, since it has not yet
4400 * been dynamicly linked in yet. */
4401 +#define __UCLIBC_MMAP_HAS_6_ARGS__
4403 +#include "sys/syscall.h"
4404 extern int _dl_errno;
4405 +#undef __set_errno
4406 #define __set_errno(X) {(_dl_errno) = (X);}
4407 -#include "sys/syscall.h"
4409 -#define MMAP_HAS_6_ARGS
4410 diff -urN uClibc-0.9.28.orig/ldso/ldso/x86_64/dl-sysdep.h uClibc-0.9.28/ldso/ldso/x86_64/dl-sysdep.h
4411 --- uClibc-0.9.28.orig/ldso/ldso/x86_64/dl-sysdep.h 2006-05-02 10:47:27.000000000 -0600
4412 +++ uClibc-0.9.28/ldso/ldso/x86_64/dl-sysdep.h 2006-04-28 00:14:35.000000000 -0600
4413 @@ -41,8 +41,6 @@
4414 struct elf_resolve;
4415 extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
4417 -#define do_rem(result, n, base) ((result) = (n) % (base))
4419 /* 4096 bytes alignment */
4420 #define PAGE_ALIGN 0xfffff000
4421 #define ADDR_ALIGN 0xfff
4422 @@ -90,7 +88,7 @@
4423 and compare it with the current value that we can get via
4424 an RIP relative addressing mode. */
4426 - asm ("movq 1f(%%rip), %1\n"
4427 + __asm__ ("movq 1f(%%rip), %1\n"
4428 "0:\tleaq _dl_start(%%rip), %0\n\t"
4429 "subq %1, %0\n\t"
4430 ".section\t.data\n"
4431 diff -urN uClibc-0.9.28.orig/ldso/ldso/x86_64/elfinterp.c uClibc-0.9.28/ldso/ldso/x86_64/elfinterp.c
4432 --- uClibc-0.9.28.orig/ldso/ldso/x86_64/elfinterp.c 2006-05-02 10:47:27.000000000 -0600
4433 +++ uClibc-0.9.28/ldso/ldso/x86_64/elfinterp.c 2006-04-28 00:14:35.000000000 -0600
4434 @@ -165,6 +165,7 @@
4435 int reloc_type;
4436 int symtab_index;
4437 char *symname;
4438 + ElfW(Sym) *sym;
4439 ElfW(Addr) *reloc_addr;
4440 ElfW(Addr) symbol_addr;
4441 #if defined (__SUPPORT_LD_DEBUG__)
4442 @@ -174,8 +175,9 @@
4443 reloc_addr = (ElfW(Addr)*)(tpnt->loadaddr + (unsigned long)rpnt->r_offset);
4444 reloc_type = ELF_R_TYPE(rpnt->r_info);
4445 symtab_index = ELF_R_SYM(rpnt->r_info);
4446 + sym = &symtab[symtab_index];
4447 symbol_addr = 0;
4448 - symname = strtab + symtab[symtab_index].st_name;
4449 + symname = strtab + sym->st_name;
4451 if (symtab_index) {
4452 symbol_addr = (ElfW(Addr))_dl_find_hash(symname, scope, tpnt,
4453 @@ -185,7 +187,7 @@
4454 * might have been intentional. We should not be linking local
4455 * symbols here, so all bases should be covered.
4457 - if (unlikely(!symbol_addr && ELF_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK)) {
4458 + if (unlikely(!symbol_addr && ELF_ST_BIND(sym->st_info) != STB_WEAK)) {
4459 _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname);
4460 _dl_exit(1);
4462 @@ -209,7 +211,7 @@
4464 case R_X86_64_GLOB_DAT:
4465 case R_X86_64_JUMP_SLOT:
4466 - *reloc_addr = symbol_addr;
4467 + *reloc_addr = symbol_addr + rpnt->r_addend;
4468 break;
4470 /* handled by elf_machine_relative()
4471 @@ -217,33 +219,33 @@
4472 *reloc_addr = map->l_addr + rpnt->r_addend;
4473 break;
4475 -#if 0
4476 case R_X86_64_DTPMOD64:
4477 + *reloc_addr = 1;
4478 break;
4479 case R_X86_64_DTPOFF64:
4480 - *reloc_addr = symbol_addr + rpnt->r_addend;
4481 + *reloc_addr = sym->st_value + rpnt->r_addend;
4482 break;
4483 case R_X86_64_TPOFF64:
4484 - *reloc_addr = symbol_addr + rpnt->r_addend;
4485 + *reloc_addr = sym->st_value + rpnt->r_addend - symbol_addr;
4486 break;
4487 case R_X86_64_32:
4488 - *reloc_addr = symbol_addr + rpnt->r_addend;
4489 + *(unsigned int *) reloc_addr = symbol_addr + rpnt->r_addend;
4490 + /* XXX: should check for overflow eh ? */
4491 break;
4493 -#endif
4494 case R_X86_64_COPY:
4495 if (symbol_addr) {
4496 #if defined (__SUPPORT_LD_DEBUG__)
4497 if (_dl_debug_move)
4498 _dl_dprintf(_dl_debug_file,
4499 "\t%s move %d bytes from %x to %x\n",
4500 - symname, symtab[symtab_index].st_size,
4501 + symname, sym->st_size,
4502 symbol_addr, reloc_addr);
4503 #endif
4505 _dl_memcpy((char *)reloc_addr,
4506 (char *)symbol_addr,
4507 - symtab[symtab_index].st_size);
4508 + sym->st_size);
4509 } else
4510 _dl_dprintf(_dl_debug_file, "no symbol_addr to copy !?\n");
4511 break;
4512 @@ -261,7 +263,6 @@
4513 return 0;
4516 -#if 0
4517 static int
4518 _dl_do_lazy_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
4519 ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab)
4520 @@ -288,7 +289,7 @@
4521 case R_X86_64_NONE:
4522 break;
4523 case R_X86_64_JUMP_SLOT:
4524 - *reloc_addr = tpnt->loadaddr + symtab[symtab_index].st_value;
4525 + *reloc_addr += (unsigned long)tpnt->loadaddr;
4526 break;
4527 default:
4528 _dl_exit(1);
4529 @@ -302,17 +303,13 @@
4531 return 0;
4533 -#endif
4535 void
4536 _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt,
4537 unsigned long rel_addr,
4538 unsigned long rel_size)
4540 - _dl_parse_relocation_information(rpnt, rel_addr, rel_size);
4541 -/* jump slot isnt working
4542 (void)_dl_parse(rpnt->dyn, NULL, rel_addr, rel_size, _dl_do_lazy_reloc);
4547 diff -urN uClibc-0.9.28.orig/ldso/ldso/x86_64/resolve.S uClibc-0.9.28/ldso/ldso/x86_64/resolve.S
4548 --- uClibc-0.9.28.orig/ldso/ldso/x86_64/resolve.S 1969-12-31 17:00:00.000000000 -0700
4549 +++ uClibc-0.9.28/ldso/ldso/x86_64/resolve.S 2006-04-28 00:14:35.000000000 -0600
4550 @@ -0,0 +1,63 @@
4552 + * This function is _not_ called directly. It is jumped to (so no return
4553 + * address is on the stack) when attempting to use a symbol that has not yet
4554 + * been resolved. The first time a jump symbol (such as a function call inside
4555 + * a shared library) is used (before it gets resolved) it will jump here to
4556 + * _dl_linux_resolve. When we get called the stack looks like this:
4557 + * reloc_entry
4558 + * tpnt
4560 + * This function saves all the registers, puts a copy of reloc_entry and tpnt
4561 + * on the stack (as function arguments) then make the function call
4562 + * _dl_linux_resolver(tpnt, reloc_entry). _dl_linux_resolver() figures out
4563 + * where the jump symbol is _really_ supposed to have jumped to and returns
4564 + * that to us. Once we have that, we overwrite tpnt with this fixed up
4565 + * address. We then clean up after ourselves, put all the registers back how we
4566 + * found them, then we jump to where the fixed up address, which is where the
4567 + * jump symbol that got us here really wanted to jump to in the first place.
4568 + * found them, then we jump to the fixed up address, which is where the jump
4569 + * symbol that got us here really wanted to jump to in the first place.
4570 + * -Erik Andersen
4571 + */
4573 +/* more info taken from glibc/sysdeps/x86_64/dl-trampoline.S */
4575 +.text
4577 +.global _dl_linux_resolve
4578 +.type _dl_linux_resolve,%function
4579 +.align 16
4581 +_dl_linux_resolve:
4582 + subq $56,%rsp
4583 + /* Preserve registers otherwise clobbered. */
4584 + movq %rax, (%rsp)
4585 + movq %rcx, 8(%rsp)
4586 + movq %rdx, 16(%rsp)
4587 + movq %rsi, 24(%rsp)
4588 + movq %rdi, 32(%rsp)
4589 + movq %r8, 40(%rsp)
4590 + movq %r9, 48(%rsp)
4592 + movq 64(%rsp), %rsi /* Copy args pushed by PLT in register. */
4593 + movq %rsi, %r11 /* Multiply by 24 */
4594 + addq %r11, %rsi
4595 + addq %r11, %rsi
4596 + shlq $3, %rsi
4597 + movq 56(%rsp), %rdi /* %rdi: link_map, %rsi: reloc_offset */
4598 + call _dl_linux_resolver /* Call resolver. */
4599 + movq %rax, %r11 /* Save return value */
4601 + /* Get register content back. */
4602 + movq 48(%rsp), %r9
4603 + movq 40(%rsp), %r8
4604 + movq 32(%rsp), %rdi
4605 + movq 24(%rsp), %rsi
4606 + movq 16(%rsp), %rdx
4607 + movq 8(%rsp), %rcx
4608 + movq (%rsp), %rax
4610 + addq $72, %rsp /* Adjust stack(PLT did 2 pushes) */
4611 + jmp *%r11 /* Jump to function address. */
4613 +.size _dl_linux_resolve,.-_dl_linux_resolve
4614 diff -urN uClibc-0.9.28.orig/ldso/libdl/Makefile uClibc-0.9.28/ldso/libdl/Makefile
4615 --- uClibc-0.9.28.orig/ldso/libdl/Makefile 2006-05-02 10:47:27.000000000 -0600
4616 +++ uClibc-0.9.28/ldso/libdl/Makefile 2006-04-28 00:14:35.000000000 -0600
4617 @@ -29,12 +29,14 @@
4618 endif
4619 XXFLAGS+= $(XARCH_CFLAGS) $(CPU_CFLAGS) \
4620 -DUCLIBC_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" \
4621 - -fno-builtin -nostdinc -D_LIBC -I$(TOPDIR)ldso/include -I$(TOPDIR)ldso/ldso -I. -I$(TOPDIR)include
4622 + -fno-builtin -nostdinc -D_LIBC \
4623 + -DLDSO_ELFINTERP=\"$(TARGET_ARCH)/elfinterp.c\" \
4624 + -I$(TOPDIR)ldso/ldso/$(TARGET_ARCH) -I$(TOPDIR)ldso/include -I$(TOPDIR)ldso/ldso -I$(TOPDIR)include
4626 XXFLAGS+=-isystem $(shell $(CC) -print-file-name=include)
4627 XXFLAGS_NOPIC:=$(XXFLAGS)
4628 ifeq ($(DOPIC),y)
4629 - XXFLAGS += $(PICFLAG) -D__LIBDL_SHARED__
4630 + XXFLAGS += $(PICFLAG) -DSHARED
4631 endif
4632 ifeq ($(strip $(SUPPORT_LD_DEBUG)),y)
4633 XXFLAGS+=-D__SUPPORT_LD_DEBUG__
4634 diff -urN uClibc-0.9.28.orig/ldso/libdl/libdl.c uClibc-0.9.28/ldso/libdl/libdl.c
4635 --- uClibc-0.9.28.orig/ldso/libdl/libdl.c 2006-05-02 10:47:27.000000000 -0600
4636 +++ uClibc-0.9.28/ldso/libdl/libdl.c 2006-04-28 00:14:35.000000000 -0600
4637 @@ -3,7 +3,7 @@
4638 * Program to load an ELF binary on a linux system, and run it
4639 * after resolving ELF shared library symbols
4641 - * Copyright (C) 2000-2004 by Erik Andersen <andersen@codepoet.org>
4642 + * Copyright (C) 2000-2006 by Erik Andersen <andersen@uclibc.org>
4643 * Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald,
4644 * David Engel, Hongjiu Lu and Mitch D'Souza
4646 @@ -30,12 +30,12 @@
4650 -#define _GNU_SOURCE
4651 +#define _GNU_SOURCE
4652 #include <ldso.h>
4653 #include <stdio.h>
4656 -#if defined (__LIBDL_SHARED__)
4657 +#ifdef SHARED
4659 /* When libdl is loaded as a shared library, we need to load in
4660 * and use a pile of symbols from ldso... */
4661 @@ -52,6 +51,8 @@
4662 extern struct r_debug *_dl_debug_addr;
4663 extern unsigned long _dl_error_number;
4664 extern void *(*_dl_malloc_function)(size_t);
4665 +extern void _dl_run_init_array(struct elf_resolve *);
4666 +extern void _dl_run_fini_array(struct elf_resolve *);
4667 #ifdef __LDSO_CACHE_SUPPORT__
4668 int _dl_map_cache(void);
4669 int _dl_unmap_cache(void);
4670 @@ -64,7 +65,7 @@
4671 #endif
4674 -#else /* __LIBDL_SHARED__ */
4675 +#else /* SHARED */
4677 /* When libdl is linked as a static library, we need to replace all
4678 * the symbols that otherwise would have been loaded in from ldso... */
4679 @@ -81,11 +82,11 @@
4680 struct r_debug *_dl_debug_addr = NULL;
4681 #define _dl_malloc malloc
4682 #include "../ldso/dl-debug.c"
4683 -#include "dl-progname.h"
4684 +#include LDSO_ELFINTERP
4685 #include "../ldso/dl-hash.c"
4686 #define _dl_trace_loaded_objects 0
4687 #include "../ldso/dl-elf.c"
4688 -#endif /* __LIBDL_SHARED__ */
4689 +#endif /* SHARED */
4691 #ifdef __SUPPORT_LD_DEBUG__
4692 # define _dl_if_debug_print(fmt, args...) \
4693 @@ -126,7 +127,8 @@
4694 "Unable to resolve symbol"
4697 -void __attribute__ ((destructor)) dl_cleanup(void)
4698 +void dl_cleanup(void) __attribute__ ((destructor));
4699 +void dl_cleanup(void)
4701 struct dyn_elf *d;
4702 for (d = _dl_handles; d; d = d->next_handle) {
4703 @@ -138,13 +140,12 @@
4705 struct elf_resolve *tpnt, *tfrom;
4706 struct dyn_elf *dyn_chain, *rpnt = NULL, *dyn_ptr, *relro_ptr, *handle;
4707 - struct dyn_elf *dpnt;
4708 ElfW(Addr) from;
4709 struct elf_resolve *tpnt1;
4710 void (*dl_brk) (void);
4711 int now_flag;
4712 struct init_fini_list *tmp, *runp, *runp2, *dep_list;
4713 - int nlist, i;
4714 + unsigned int nlist, i;
4715 struct elf_resolve **init_fini_list;
4717 /* A bit of sanity checking... */
4718 @@ -169,12 +170,15 @@
4719 * the application. Thus this may go away at some time
4720 * in the future.
4722 - tfrom = NULL;
4723 - for (dpnt = _dl_symbol_tables; dpnt; dpnt = dpnt->next) {
4724 - tpnt = dpnt->dyn;
4725 - if (tpnt->loadaddr < from
4726 - && (tfrom == NULL || tfrom->loadaddr < tpnt->loadaddr))
4727 - tfrom = tpnt;
4729 + struct dyn_elf *dpnt;
4730 + tfrom = NULL;
4731 + for (dpnt = _dl_symbol_tables; dpnt; dpnt = dpnt->next) {
4732 + tpnt = dpnt->dyn;
4733 + if (tpnt->loadaddr < from
4734 + && (tfrom == NULL || tfrom->loadaddr < tpnt->loadaddr))
4735 + tfrom = tpnt;
4738 for(rpnt = _dl_symbol_tables; rpnt && rpnt->next; rpnt=rpnt->next);
4740 @@ -233,11 +237,8 @@
4741 runp->tpnt->init_fini = NULL; /* clear any previous dependcies */
4742 for (dpnt = (ElfW(Dyn) *) runp->tpnt->dynamic_addr; dpnt->d_tag; dpnt++) {
4743 if (dpnt->d_tag == DT_NEEDED) {
4744 - char *name;
4746 lpntstr = (char*) (runp->tpnt->dynamic_info[DT_STRTAB] +
4747 dpnt->d_un.d_val);
4748 - name = _dl_get_last_path_component(lpntstr);
4749 _dl_if_debug_print("Trying to load '%s', needed by '%s'\n",
4750 lpntstr, runp->tpnt->libname);
4751 tpnt1 = _dl_load_shared_library(0, &rpnt, runp->tpnt, lpntstr, 0);
4752 @@ -297,14 +298,14 @@
4754 /* Sort the INIT/FINI list in dependency order. */
4755 for (runp2 = dep_list; runp2; runp2 = runp2->next) {
4756 - int j, k;
4757 + unsigned int j, k;
4758 for (j = 0; init_fini_list[j] != runp2->tpnt; ++j)
4759 /* Empty */;
4760 for (k = j + 1; k < nlist; ++k) {
4761 - struct init_fini_list *runp = init_fini_list[k]->init_fini;
4762 + struct init_fini_list *ele = init_fini_list[k]->init_fini;
4764 - for (; runp; runp = runp->next) {
4765 - if (runp->tpnt == runp2->tpnt) {
4766 + for (; ele; ele = ele->next) {
4767 + if (ele->tpnt == runp2->tpnt) {
4768 struct elf_resolve *here = init_fini_list[k];
4769 _dl_if_debug_print("Move %s from pos %d to %d in INIT/FINI list.\n", here->libname, k, j);
4770 for (i = (k - j); i; --i)
4771 @@ -367,7 +368,7 @@
4775 -#if defined (__LIBDL_SHARED__)
4776 +#ifdef SHARED
4777 /* Run the ctors and setup the dtors */
4778 for (i = nlist; i; --i) {
4779 tpnt = init_fini_list[i-1];
4780 @@ -384,8 +385,11 @@
4781 (*dl_elf_func) ();
4785 + _dl_run_init_array(tpnt);
4787 -#endif
4788 +#endif /* SHARED */
4790 _dl_unmap_cache();
4791 return (void *) dyn_chain;
4793 @@ -450,9 +454,16 @@
4794 return ret;
4797 +#if 0
4798 +void *dlvsym(void *vhandle, const char *name, const char *version)
4800 + return dlsym(vhandle, name);
4802 +#endif
4804 static int do_dlclose(void *vhandle, int need_fini)
4806 - struct dyn_elf *rpnt, *rpnt1;
4807 + struct dyn_elf *rpnt, *rpnt1, *rpnt1_tmp;
4808 struct init_fini_list *runp, *tmp;
4809 ElfW(Phdr) *ppnt;
4810 struct elf_resolve *tpnt, *run_tpnt;
4811 @@ -460,7 +471,7 @@
4812 void (*dl_brk) (void);
4813 struct dyn_elf *handle;
4814 unsigned int end;
4815 - int i = 0, j;
4816 + unsigned int i, j;
4818 handle = (struct dyn_elf *) vhandle;
4819 if (handle == _dl_symbol_tables)
4820 @@ -491,13 +502,21 @@
4821 for (j = 0; j < handle->init_fini.nlist; ++j) {
4822 tpnt = handle->init_fini.init_fini[j];
4823 if (--tpnt->usage_count == 0) {
4824 - if (tpnt->dynamic_info[DT_FINI] && need_fini &&
4825 + if ((tpnt->dynamic_info[DT_FINI]
4826 + || tpnt->dynamic_info[DT_FINI_ARRAY])
4827 + && need_fini &&
4828 !(tpnt->init_flag & FINI_FUNCS_CALLED)) {
4829 tpnt->init_flag |= FINI_FUNCS_CALLED;
4830 - dl_elf_fini = (int (*)(void)) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI]);
4831 - _dl_if_debug_print("running dtors for library %s at '%p'\n",
4832 - tpnt->libname, dl_elf_fini);
4833 - (*dl_elf_fini) ();
4834 +#ifdef SHARED
4835 + _dl_run_fini_array(tpnt);
4836 +#endif
4838 + if (tpnt->dynamic_info[DT_FINI]) {
4839 + dl_elf_fini = (int (*)(void)) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI]);
4840 + _dl_if_debug_print("running dtors for library %s at '%p'\n",
4841 + tpnt->libname, dl_elf_fini);
4842 + (*dl_elf_fini) ();
4846 _dl_if_debug_print("unmapping: %s\n", tpnt->libname);
4847 @@ -541,8 +560,9 @@
4848 for (rpnt1 = _dl_symbol_tables; rpnt1->next; rpnt1 = rpnt1->next) {
4849 if (rpnt1->next->dyn == tpnt) {
4850 _dl_if_debug_print("removing symbol_tables: %s\n", tpnt->libname);
4851 + rpnt1_tmp = rpnt1->next->next;
4852 free(rpnt1->next);
4853 - rpnt1->next = rpnt1->next->next;
4854 + rpnt1->next = rpnt1_tmp;
4855 if (rpnt1->next)
4856 rpnt1->next->prev = rpnt1;
4857 break;
4858 @@ -588,8 +608,9 @@
4862 - * Dump information to stderrr about the current loaded modules
4863 + * Dump information to stderr about the current loaded modules
4865 +#if 1
4866 static char *type[] = { "Lib", "Exe", "Int", "Mod" };
4868 int dlinfo(void)
4869 @@ -660,16 +681,14 @@
4871 char *strtab;
4872 ElfW(Sym) *symtab;
4873 - int hn, si;
4874 - int sf;
4875 - int sn = 0;
4876 + unsigned int hn, si, sn, sf;
4877 ElfW(Addr) sa;
4879 sa = 0;
4880 symtab = (ElfW(Sym) *) (pelf->dynamic_info[DT_SYMTAB]);
4881 strtab = (char *) (pelf->dynamic_info[DT_STRTAB]);
4883 - sf = 0;
4884 + sf = sn = 0;
4885 for (hn = 0; hn < pelf->nbucket; hn++) {
4886 for (si = pelf->elf_buckets[hn]; si; si = pelf->chains[si]) {
4887 ElfW(Addr) symbol_addr;
4888 @@ -696,3 +715,4 @@
4889 return 1;
4892 +#endif
4893 diff -urN uClibc-0.9.28.orig/libc/sysdeps/linux/i386/bits/syscalls.h uClibc-0.9.28/libc/sysdeps/linux/i386/bits/syscalls.h
4894 --- uClibc-0.9.28.orig/libc/sysdeps/linux/i386/bits/syscalls.h 2006-05-02 10:47:27.000000000 -0600
4895 +++ uClibc-0.9.28/libc/sysdeps/linux/i386/bits/syscalls.h 2006-04-28 00:14:35.000000000 -0600
4896 @@ -4,17 +4,15 @@
4897 # error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead."
4898 #endif
4900 +#include <errno.h>
4902 /* This includes the `__NR_<name>' syscall numbers taken from the Linux kernel
4903 * header files. It also defines the traditional `SYS_<name>' macros for older
4904 * programs. */
4905 #include <bits/sysnum.h>
4907 -#ifndef __set_errno
4908 -# define __set_errno(val) (*__errno_location ()) = (val)
4909 -#endif
4912 - Some of the sneaky macros in the code were taken from
4913 + Some of the sneaky macros in the code were taken from
4914 glibc-2.2.5/sysdeps/unix/sysv/linux/i386/sysdep.h
4917 @@ -22,7 +20,8 @@
4919 /* We need some help from the assembler to generate optimal code. We
4920 define some macros here which later will be used. */
4921 -asm (".L__X'%ebx = 1\n\t"
4923 +__asm__ (".L__X'%ebx = 1\n\t"
4924 ".L__X'%ecx = 2\n\t"
4925 ".L__X'%edx = 2\n\t"
4926 ".L__X'%eax = 3\n\t"
4927 @@ -56,7 +55,6 @@
4928 ".endif\n\t"
4929 ".endm\n\t");
4932 #undef _syscall0
4933 #define _syscall0(type,name) \
4934 type name(void) \
4935 @@ -90,7 +88,7 @@
4936 type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
4938 return (type) (INLINE_SYSCALL(name, 4, arg1, arg2, arg3, arg4)); \
4942 #undef _syscall5
4943 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
4944 @@ -100,10 +98,18 @@
4945 return (type) (INLINE_SYSCALL(name, 5, arg1, arg2, arg3, arg4, arg5)); \
4948 +#undef _syscall6
4949 +#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
4950 + type5,arg5,type6,arg6) \
4951 +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, type6 arg6) \
4952 +{ \
4953 +return (type) (INLINE_SYSCALL(name, 6, arg1, arg2, arg3, arg4, arg5, arg6)); \
4956 #define INLINE_SYSCALL(name, nr, args...) \
4957 ({ \
4958 unsigned int resultvar; \
4959 - asm volatile ( \
4960 + __asm__ __volatile__ ( \
4961 LOADARGS_##nr \
4962 "movl %1, %%eax\n\t" \
4963 "int $0x80\n\t" \
4964 @@ -125,6 +131,7 @@
4965 #define LOADARGS_3 LOADARGS_1
4966 #define LOADARGS_4 LOADARGS_1
4967 #define LOADARGS_5 LOADARGS_1
4968 +#define LOADARGS_6 LOADARGS_1 "push %%ebp ; movl %7, %%ebp\n\t"
4970 #define RESTOREARGS_0
4971 #define RESTOREARGS_1 \
4972 @@ -133,6 +140,7 @@
4973 #define RESTOREARGS_3 RESTOREARGS_1
4974 #define RESTOREARGS_4 RESTOREARGS_1
4975 #define RESTOREARGS_5 RESTOREARGS_1
4976 +#define RESTOREARGS_6 "pop %%ebp\n\t" RESTOREARGS_1
4978 #define ASMFMT_0()
4979 #define ASMFMT_1(arg1) \
4980 @@ -145,7 +153,8 @@
4981 , "aD" (arg1), "c" (arg2), "d" (arg3), "S" (arg4)
4982 #define ASMFMT_5(arg1, arg2, arg3, arg4, arg5) \
4983 , "a" (arg1), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5)
4985 +#define ASMFMT_6(arg1, arg2, arg3, arg4, arg5, arg6) \
4986 + , "a" (arg1), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5), "m" (arg6)
4988 #endif /* __ASSEMBLER__ */
4989 #endif /* _BITS_SYSCALLS_H */
4990 diff -urN uClibc-0.9.28.orig/libc/sysdeps/linux/powerpc/bits/syscalls.h uClibc-0.9.28/libc/sysdeps/linux/powerpc/bits/syscalls.h
4991 --- uClibc-0.9.28.orig/libc/sysdeps/linux/powerpc/bits/syscalls.h 2006-05-02 10:47:27.000000000 -0600
4992 +++ uClibc-0.9.28/libc/sysdeps/linux/powerpc/bits/syscalls.h 2006-04-28 00:14:35.000000000 -0600
4993 @@ -5,67 +5,164 @@
4994 # error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead."
4995 #endif
4997 +#include <errno.h>
4999 /* This includes the `__NR_<name>' syscall numbers taken from the Linux kernel
5000 * header files. It also defines the traditional `SYS_<name>' macros for older
5001 * programs. */
5002 #include <bits/sysnum.h>
5005 -#define __STRINGIFY(s) __STRINGIFY2 (s)
5006 -#define __STRINGIFY2(s) #s
5008 -#undef JUMPTARGET
5009 -#ifdef __PIC__
5010 -#define __MAKE_SYSCALL __STRINGIFY(__uClibc_syscall@plt)
5011 +/* Define a macro which expands inline into the wrapper code for a system
5012 + call. This use is for internal calls that do not need to handle errors
5013 + normally. It will never touch errno.
5014 + On powerpc a system call basically clobbers the same registers like a
5015 + function call, with the exception of LR (which is needed for the
5016 + "sc; bnslr+" sequence) and CR (where only CR0.SO is clobbered to signal
5017 + an error return status). */
5019 +# undef INLINE_SYSCALL
5020 +#if 1
5021 +# define INLINE_SYSCALL(name, nr, args...) \
5022 + ({ \
5023 + INTERNAL_SYSCALL_DECL (sc_err); \
5024 + long int sc_ret = INTERNAL_SYSCALL (name, sc_err, nr, args); \
5025 + if (INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err)) \
5026 + { \
5027 + __set_errno (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err)); \
5028 + sc_ret = -1L; \
5029 + } \
5030 + sc_ret; \
5031 + })
5032 #else
5033 -#define __MAKE_SYSCALL __STRINGIFY(__uClibc_syscall)
5034 +# define INLINE_SYSCALL(name, nr, args...) \
5035 + ({ \
5036 + INTERNAL_SYSCALL_DECL (sc_err); \
5037 + long int sc_ret = INTERNAL_SYSCALL (name, sc_err, nr, args); \
5038 + if (INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err)) \
5039 + { \
5040 + sc_ret = __syscall_error(INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err));\
5041 + } \
5042 + sc_ret; \
5043 + })
5044 #endif
5046 -#define unified_syscall_body(name) \
5047 - __asm__ ( \
5048 - ".section \".text\"\n\t" \
5049 - ".align 2\n\t" \
5050 - ".globl " __STRINGIFY(name) "\n\t" \
5051 - ".type " __STRINGIFY(name) ",@function\n\t" \
5052 - #name":\tli 0," __STRINGIFY(__NR_##name) "\n\t" \
5053 - "b " __MAKE_SYSCALL "\n\t" \
5054 - ".size\t" __STRINGIFY(name) ",.""-" __STRINGIFY(name) "\n" \
5056 +/* Define a macro which expands inline into the wrapper code for a system
5057 + call. This use is for internal calls that do not need to handle errors
5058 + normally. It will never touch errno.
5059 + On powerpc a system call basically clobbers the same registers like a
5060 + function call, with the exception of LR (which is needed for the
5061 + "sc; bnslr+" sequence) and CR (where only CR0.SO is clobbered to signal
5062 + an error return status). */
5064 +# undef INTERNAL_SYSCALL_DECL
5065 +# define INTERNAL_SYSCALL_DECL(err) long int err
5067 +# undef INTERNAL_SYSCALL
5068 +# define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
5069 + ({ \
5070 + register long int r0 __asm__ ("r0"); \
5071 + register long int r3 __asm__ ("r3"); \
5072 + register long int r4 __asm__ ("r4"); \
5073 + register long int r5 __asm__ ("r5"); \
5074 + register long int r6 __asm__ ("r6"); \
5075 + register long int r7 __asm__ ("r7"); \
5076 + register long int r8 __asm__ ("r8"); \
5077 + register long int r9 __asm__ ("r9"); \
5078 + register long int r10 __asm__ ("r10"); \
5079 + register long int r11 __asm__ ("r11"); \
5080 + register long int r12 __asm__ ("r12"); \
5081 + LOADARGS_##nr(name, args); \
5082 + __asm__ __volatile__ \
5083 + ("sc \n\t" \
5084 + "mfcr %0" \
5085 + : "=&r" (r0), \
5086 + "=&r" (r3), "=&r" (r4), "=&r" (r5), "=&r" (r6), "=&r" (r7), \
5087 + "=&r" (r8), "=&r" (r9), "=&r" (r10), "=&r" (r11), "=&r" (r12) \
5088 + : ASM_INPUT_##nr \
5089 + : "cr0", "ctr", "memory"); \
5090 + err = r0; \
5091 + (int) r3; \
5092 + })
5093 +# define INTERNAL_SYSCALL(name, err, nr, args...) \
5094 + INTERNAL_SYSCALL_NCS (__NR_##name, err, nr, ##args)
5096 +# undef INTERNAL_SYSCALL_ERROR_P
5097 +# define INTERNAL_SYSCALL_ERROR_P(val, err) \
5098 + ((void) (val), __builtin_expect ((err) & (1 << 28), 0))
5100 +# undef INTERNAL_SYSCALL_ERRNO
5101 +# define INTERNAL_SYSCALL_ERRNO(val, err) (val)
5103 +# define LOADARGS_0(name, dummy) \
5104 + r0 = (long int)name
5105 +# define LOADARGS_1(name, __arg1) \
5106 + LOADARGS_0(name, 0); \
5107 + r3 = (long int)__arg1
5108 +# define LOADARGS_2(name, __arg1, __arg2) \
5109 + LOADARGS_1(name, __arg1); \
5110 + r4 = (long int)__arg2
5111 +# define LOADARGS_3(name, __arg1, __arg2, __arg3) \
5112 + LOADARGS_2(name, __arg1, __arg2); \
5113 + r5 = (long int)__arg3
5114 +# define LOADARGS_4(name, __arg1, __arg2, __arg3, __arg4) \
5115 + LOADARGS_3(name, __arg1, __arg2, __arg3); \
5116 + r6 = (long int)__arg4
5117 +# define LOADARGS_5(name, __arg1, __arg2, __arg3, __arg4, __arg5) \
5118 + LOADARGS_4(name, __arg1, __arg2, __arg3, __arg4); \
5119 + r7 = (long int)__arg5
5120 +# define LOADARGS_6(name, __arg1, __arg2, __arg3, __arg4, __arg5, __arg6) \
5121 + LOADARGS_5(name, __arg1, __arg2, __arg3, __arg4, __arg5); \
5122 + r8 = (long int)__arg6
5124 +# define ASM_INPUT_0 "0" (r0)
5125 +# define ASM_INPUT_1 ASM_INPUT_0, "1" (r3)
5126 +# define ASM_INPUT_2 ASM_INPUT_1, "2" (r4)
5127 +# define ASM_INPUT_3 ASM_INPUT_2, "3" (r5)
5128 +# define ASM_INPUT_4 ASM_INPUT_3, "4" (r6)
5129 +# define ASM_INPUT_5 ASM_INPUT_4, "5" (r7)
5130 +# define ASM_INPUT_6 ASM_INPUT_5, "6" (r8)
5132 #undef _syscall0
5133 -#define _syscall0(type,name) \
5134 -type name(void); \
5135 -unified_syscall_body(name)
5136 +#define _syscall0(type,name) \
5137 +type name(void){ \
5138 + return (type) INLINE_SYSCALL(name, 0); \
5141 #undef _syscall1
5142 #define _syscall1(type,name,type1,arg1) \
5143 -type name(type1 arg1); \
5144 -unified_syscall_body(name)
5145 +type name(type1 arg1){ \
5146 + return (type) INLINE_SYSCALL(name, 1, arg1); \
5149 #undef _syscall2
5150 #define _syscall2(type,name,type1,arg1,type2,arg2) \
5151 -type name(type1 arg1, type2 arg2); \
5152 -unified_syscall_body(name)
5153 +type name(type1 arg1, type2 arg2){ \
5154 + return (type) INLINE_SYSCALL(name, 2, arg1, arg2); \
5157 #undef _syscall3
5158 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
5159 -type name(type1 arg1, type2 arg2, type3 arg3); \
5160 -unified_syscall_body(name)
5161 +type name(type1 arg1, type2 arg2, type3 arg3){ \
5162 + return (type) INLINE_SYSCALL(name, 3, arg1, arg2, arg3); \
5165 #undef _syscall4
5166 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
5167 -type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4); \
5168 -unified_syscall_body(name)
5169 +type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4){ \
5170 + return (type) INLINE_SYSCALL(name, 4, arg1, arg2, arg3, arg4); \
5173 #undef _syscall5
5174 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
5175 -type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5); \
5176 -unified_syscall_body(name)
5177 +type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5){ \
5178 + return (type) INLINE_SYSCALL(name, 5, arg1, arg2, arg3, arg4, arg5); \
5181 #undef _syscall6
5182 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \
5183 -type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6); \
5184 -unified_syscall_body(name)
5185 +type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6){ \
5186 + return (type) INLINE_SYSCALL(name, 6, arg1, arg2, arg3, arg4, arg5, arg6); \
5189 #endif /* _BITS_SYSCALLS_H */