From: Roland McGrath Date: Mon, 3 Jun 1996 04:46:40 +0000 (+0000) Subject: Mon Jun 3 00:30:35 1996 Roland McGrath X-Git-Tag: upstream/2.30~29440 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=710f7bab59b9bb02f1cd46fa2db14e2b4b0a806a;p=external%2Fglibc.git Mon Jun 3 00:30:35 1996 Roland McGrath * elf/dl-lookup.c (_dl_lookup_symbol): Take new arg RELOC_ADDR and don't allow a defn resolving to that address. * elf/link.h: Update prototype and comment. * elf/dl-runtime.c (fixup): Define local `resolve' function and pass it to elf_machine_relplt. * elf/dl-reloc.c (_dl_relocate_object: resolve): Take new arg RELOC_ADDR and pass it through to _dl_lookup_symbol. * elf/do-rel.h (elf_dynamic_do_rel): Pass RESOLVE to elf_machine_rel instead of calling it ourselves and passing its results. (elf_dynamic_do_rel): RESOLVE fn takes new arg RELOC_ADDR. * elf/rtld.c (dl_main): Pass 0 for RELOC_ADDR to _dl_lookup_symbol. * sysdeps/i386/dl-machine.h (elf_machine_rel): Remove SYM_LOADADDR arg. Add RESOLVE function ptr arg. Call *RESOLVE as necessary. * sysdeps/m68k/dl-machine.h (elf_machine_rela): Likewise. * sysdeps/stub/dl-machine.h: Likewise. * csu/initfini.c (_fini): Add extern decl for i_am_not_a_leaf. * elf/dlfcn.h (dl_open_mode): Enumerated type removed. (RTLD_LAZY, RTLD_NOW): Define these as macros instead. (RTLD_GLOBAL): New macro. (dlopen): Take arg of type int instead of dl_open_mode. * elf/dlopen.c: Likewise. * math/math.h (_Mldbl): New macro, either produces L suffix or not. (M_*): Use it for these constants. --- diff --git a/ChangeLog b/ChangeLog index a50a266..7b8b44f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,34 @@ +Mon Jun 3 00:30:35 1996 Roland McGrath + + * elf/dl-lookup.c (_dl_lookup_symbol): Take new arg RELOC_ADDR and + don't allow a defn resolving to that address. + * elf/link.h: Update prototype and comment. + * elf/dl-runtime.c (fixup): Define local `resolve' function and pass + it to elf_machine_relplt. + * elf/dl-reloc.c (_dl_relocate_object: resolve): Take new arg + RELOC_ADDR and pass it through to _dl_lookup_symbol. + * elf/do-rel.h (elf_dynamic_do_rel): Pass RESOLVE to elf_machine_rel + instead of calling it ourselves and passing its results. + (elf_dynamic_do_rel): RESOLVE fn takes new arg RELOC_ADDR. + * elf/rtld.c (dl_main): Pass 0 for RELOC_ADDR to _dl_lookup_symbol. + * sysdeps/i386/dl-machine.h (elf_machine_rel): Remove SYM_LOADADDR + arg. Add RESOLVE function ptr arg. Call *RESOLVE as necessary. + * sysdeps/m68k/dl-machine.h (elf_machine_rela): Likewise. + * sysdeps/stub/dl-machine.h: Likewise. + Sun Jun 2 14:56:49 1996 Roland McGrath + * csu/initfini.c (_fini): Add extern decl for i_am_not_a_leaf. + + * elf/dlfcn.h (dl_open_mode): Enumerated type removed. + (RTLD_LAZY, RTLD_NOW): Define these as macros instead. + (RTLD_GLOBAL): New macro. + (dlopen): Take arg of type int instead of dl_open_mode. + * elf/dlopen.c: Likewise. + + * math/math.h (_Mldbl): New macro, either produces L suffix or not. + (M_*): Use it for these constants. + * elf/dl-lookup.c (_dl_lookup_symbol): Arg NOSELF renamed to NOPLT. Reject SHN_UNDEF defns iff NOPLT is nonzero. * elf/link.h (_dl_lookup_symbol): Update prototype and comment. diff --git a/csu/initfini.c b/csu/initfini.c index 2727596..8fe2368 100644 --- a/csu/initfini.c +++ b/csu/initfini.c @@ -1,5 +1,5 @@ /* Special .init and .fini section support. -Copyright (C) 1995 Free Software Foundation, Inc. +Copyright (C) 1995, 1996 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -101,10 +101,13 @@ _fini (void) \n\ cat > /dev/null <<\\EOF.fini.skip"); - /* Let GCC know that _fini is not a leaf function by having a dummy - function call here. We arrange for this call to be omitted from - either crt file. */ - i_am_not_a_leaf(); + { + /* Let GCC know that _fini is not a leaf function by having a dummy + function call here. We arrange for this call to be omitted from + either crt file. */ + extern void i_am_not_a_leaf (void); + i_am_not_a_leaf (); + } asm ("\nEOF.fini.skip\ \n\ diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c index 90c9b6a..b72a6a2 100644 --- a/elf/dl-lookup.c +++ b/elf/dl-lookup.c @@ -23,13 +23,15 @@ Cambridge, MA 02139, USA. */ #include /* Search loaded objects' symbol tables for a definition of the symbol - UNDEF_NAME. If NOPLT is nonzero, then a PLT entry cannot satisfy the - reference; some different binding must be found. */ + UNDEF_NAME. The chosen value can't be RELOC_ADDR. If NOPLT is nonzero, + then a PLT entry cannot satisfy the reference; some different binding + must be found. */ Elf32_Addr _dl_lookup_symbol (const char *undef_name, const Elf32_Sym **ref, struct link_map *symbol_scope, const char *reference_name, + Elf32_Addr reloc_addr, int noplt) { unsigned long int hash = elf_hash (undef_name); @@ -59,6 +61,7 @@ _dl_lookup_symbol (const char *undef_name, const Elf32_Sym **ref, const Elf32_Sym *sym = &symtab[symidx]; if (sym->st_value == 0 || /* No value. */ + reloc_addr == map->l_addr + sym->st_value || /* Self ref. */ (noplt && sym->st_shndx == SHN_UNDEF)) /* Unwanted PLT entry. */ continue; diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c index 46fc4c4..424d303 100644 --- a/elf/dl-reloc.c +++ b/elf/dl-reloc.c @@ -60,10 +60,11 @@ _dl_relocate_object (struct link_map *l, int lazy) = ((void *) l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr); - Elf32_Addr resolve (const Elf32_Sym **ref, int noplt) + Elf32_Addr resolve (const Elf32_Sym **ref, + Elf32_Addr reloc_addr, int noplt) { return _dl_lookup_symbol (strtab + (*ref)->st_name, ref, scope, - l->l_name, noplt); + l->l_name, reloc_addr, noplt); } real_next = l->l_next; diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c index 941a306..0beba76 100644 --- a/elf/dl-runtime.c +++ b/elf/dl-runtime.c @@ -67,34 +67,15 @@ fixup ( = (const void *) (l->l_addr + l->l_info[DT_JMPREL]->d_un.d_ptr + reloc_offset); - const Elf32_Sym *definer; - Elf32_Addr loadbase; - struct link_map *scope, *real_next; - - /* Look up the symbol's run-time value. */ - - real_next = l->l_next; - if (l->l_info[DT_SYMBOLIC]) + Elf32_Addr resolve (const Elf32_Sym **ref, + Elf32_Addr reloc_addr, int noplt) { - l->l_next = _dl_loaded; - if (l->l_prev) - l->l_prev->l_next = real_next; - scope = l; + return _dl_lookup_symbol (strtab + (*ref)->st_name, ref, _dl_loaded, + l->l_name, reloc_addr, noplt); } - else - scope = _dl_loaded; - - definer = &symtab[ELF32_R_SYM (reloc->r_info)]; - loadbase = _dl_lookup_symbol (strtab + definer->st_name, &definer, - scope, l->l_name, 1); - - /* Restore list frobnication done above for DT_SYMBOLIC. */ - l->l_next = real_next; - if (l->l_prev) - l->l_prev->l_next = l; - /* Apply the relocation with that value. */ - elf_machine_relplt (l, reloc, loadbase, definer); + /* Perform the specified relocation. */ + elf_machine_relplt (l, reloc, &symtab[ELF32_R_SYM (reloc->r_info)], resolve); return *(Elf32_Addr *) (l->l_addr + reloc->r_offset); } diff --git a/elf/dlfcn.h b/elf/dlfcn.h index e5d68f8..a405baa 100644 --- a/elf/dlfcn.h +++ b/elf/dlfcn.h @@ -1,5 +1,5 @@ /* dlfcn.h -- User functions for run-time dynamic loading. -Copyright (C) 1995 Free Software Foundation, Inc. +Copyright (C) 1995, 1996 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -21,16 +21,18 @@ Cambridge, MA 02139, USA. */ #define _DLFCN_H 1 -/* Type of the second argument to `dlopen'. */ -typedef enum - { - RTLD_LAZY = 1, /* Lazy function call binding. */ - RTLD_NOW = 2 /* Immediate function call binding. */ - } dl_open_mode; +/* The MODE argument to `dlopen' contains one of the following: */ +#define RTLD_LAZY 0x001 /* Lazy function call binding. */ +#define RTLD_NOW 0x002 /* Immediate function call binding. */ + +/* If the following bit is set in the MODE argument to `dlopen', + the symbols of the loaded object and its dependencies are made + visible as if the object were linked directly into the program. */ +#define RTLD_GLOBAL 0x100 /* Open the shared object FILE and map it in; return a handle that can be passed to `dlsym' to get symbol values from it. */ -extern void *dlopen (const char *__file, dl_open_mode); +extern void *dlopen (const char *__file, int __mode); /* Unmap and close a shared object opened by `dlopen'. The handle cannot be used again after calling `dlclose'. */ diff --git a/elf/dlopen.c b/elf/dlopen.c index de65a20..26ed35a 100644 --- a/elf/dlopen.c +++ b/elf/dlopen.c @@ -1,5 +1,5 @@ /* dlopen -- Load a shared object at run time. -Copyright (C) 1995 Free Software Foundation, Inc. +Copyright (C) 1995, 1996 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -22,7 +22,7 @@ Cambridge, MA 02139, USA. */ #include void * -dlopen (const char *file, dl_open_mode mode) +dlopen (const char *file, int mode) { struct link_map *new, *l; diff --git a/elf/do-rel.h b/elf/do-rel.h index a265550..438613a 100644 --- a/elf/do-rel.h +++ b/elf/do-rel.h @@ -38,7 +38,7 @@ static inline void elf_dynamic_do_rel (struct link_map *map, int reltag, int sztag, Elf32_Addr (*resolve) (const Elf32_Sym **symbol, - int noplt), + Elf32_Addr reloc_addr, int noplt), int lazy) { const Elf32_Sym *const symtab @@ -53,28 +53,7 @@ elf_dynamic_do_rel (struct link_map *map, elf_machine_lazy_rel (map, r); else for (; r < end; ++r) - { - const Elf32_Sym *definer = &symtab[ELF32_R_SYM (r->r_info)]; - Elf32_Addr loadbase; - - if (ELF32_R_SYM (r->r_info) == STN_UNDEF) - loadbase = 0; /* This value will not be consulted. */ - else if (ELF32_ST_BIND (definer->st_info) == STB_LOCAL) - /* Local symbols always refer to the containing object. */ - loadbase = map->l_addr; - else - { - if (resolve) - loadbase = (*resolve) - (&definer, elf_machine_pltrel_p (ELF32_R_TYPE (r->r_info))); - else - { - assert (definer->st_shndx != SHN_UNDEF); - loadbase = map->l_addr; - } - } - elf_machine_rel (map, r, loadbase, definer); - } + elf_machine_rel (map, r, &symtab[ELF32_R_SYM (r->r_info)], resolve); } #undef elf_dynamic_do_rel diff --git a/elf/link.h b/elf/link.h index cd75263..a19a2ce 100644 --- a/elf/link.h +++ b/elf/link.h @@ -185,12 +185,15 @@ extern void _dl_setup_hash (struct link_map *map); reference; it is replaced with the defining symbol, and the base load address of the defining object is returned. SYMBOL_SCOPE is the head of the chain used for searching. REFERENCE_NAME should name the object - containing the reference; it is used in error messages. If NOPLT is - nonzero, then the reference must not be resolved to a PLT entry. */ + containing the reference; it is used in error messages. RELOC_ADDR is + the address being fixed up and the chosen symbol cannot be one with this + value. If NOPLT is nonzero, then the reference must not be resolved to + a PLT entry. */ extern Elf32_Addr _dl_lookup_symbol (const char *undef, const Elf32_Sym **sym, struct link_map *symbol_scope, const char *reference_name, + Elf32_Addr reloc_addr, int noplt); diff --git a/elf/rtld.c b/elf/rtld.c index 157cde5..511d19c 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -318,7 +318,7 @@ of this helper program; chances are you did not intend to run this program.\n", const Elf32_Sym *ref = NULL; Elf32_Addr loadbase = _dl_lookup_symbol (_dl_argv[i], &ref, _dl_loaded, "argument", - 0); + 0, 0); char buf[20], *bp; buf[sizeof buf - 1] = '\0'; bp = _itoa (ref->st_value, &buf[sizeof buf - 1], 16, 0); diff --git a/math/math.h b/math/math.h index 7a6134a..fbec2e8 100644 --- a/math/math.h +++ b/math/math.h @@ -127,20 +127,31 @@ extern int matherr __P ((struct exception *)); #ifdef __USE_BSD + /* Some useful constants. */ -#define M_E 2.7182818284590452354 /* e */ -#define M_LOG2E 1.4426950408889634074 /* log 2e */ -#define M_LOG10E 0.43429448190325182765 /* log 10e */ -#define M_LN2 0.69314718055994530942 /* log e2 */ -#define M_LN10 2.30258509299404568402 /* log e10 */ -#define M_PI 3.14159265358979323846 /* pi */ -#define M_PI_2 1.57079632679489661923 /* pi/2 */ -#define M_PI_4 0.78539816339744830962 /* pi/4 */ -#define M_1_PI 0.31830988618379067154 /* 1/pi */ -#define M_2_PI 0.63661977236758134308 /* 2/pi */ -#define M_2_SQRTPI 1.12837916709551257390 /* 2/sqrt(pi) */ -#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */ -#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */ +#define M_E _Mldbl(2.7182818284590452354) /* e */ +#define M_LOG2E _Mldbl(1.4426950408889634074) /* log 2e */ +#define M_LOG10E _Mldbl(0.43429448190325182765) /* log 10e */ +#define M_LN2 _Mldbl(0.69314718055994530942) /* log e2 */ +#define M_LN10 _Mldbl(2.30258509299404568402) /* log e10 */ +#define M_PI _Mldbl(3.14159265358979323846) /* pi */ +#define M_PI_2 _Mldbl(1.57079632679489661923) /* pi/2 */ +#define M_PI_4 _Mldbl(0.78539816339744830962) /* pi/4 */ +#define M_1_PI _Mldbl(0.31830988618379067154) /* 1/pi */ +#define M_2_PI _Mldbl(0.63661977236758134308) /* 2/pi */ +#define M_2_SQRTPI _Mldbl(1.12837916709551257390) /* 2/sqrt(pi) */ +#define M_SQRT2 _Mldbl(1.41421356237309504880) /* sqrt(2) */ +#define M_SQRT1_2 _Mldbl(0.70710678118654752440) /* 1/sqrt(2) */ + +/* Our constants might specify more precision than `double' can represent. + Use `long double' constants in standard and GNU C, where they are + supported and the cast to `double'. */ +#if __STDC__ - 0 || __GNUC__ - 0 +#define _Mldbl(x) x##L +#else /* Traditional C. */ +#define _Mldbl(x) x +#endif /* Standard or GNU C. */ + #endif diff --git a/posix/regex.c b/posix/regex.c index 8b66cd6..85c297b 100644 --- a/posix/regex.c +++ b/posix/regex.c @@ -1011,7 +1011,9 @@ static const char *re_error_msgid[] = This is a variable only so users of regex can assign to it; we never change it ourselves. */ #if defined (MATCH_MAY_ALLOCATE) -int re_max_failures = 20000; +/* 8600 was enough to cause a crash on Ultrix, + whose default stack limit is 2mb. */ +int re_max_failures = 8000; #else int re_max_failures = 2000; #endif diff --git a/shlib-versions b/shlib-versions index 77d7f74..656fb2e 100644 --- a/shlib-versions +++ b/shlib-versions @@ -2,8 +2,8 @@ # The following lines list filename patterns matching canonical configurations, # and the associated versions to use for various libraries. The entire -# list processed, with earlier entries taking precedence over later entries. -# So loose patterns at the end of the list can give defaults. +# list is processed, with earlier entries taking precedence over later +# entries. So loose patterns at the end of the list can give defaults. # Configuration Library versions # ------------- ------- -------- diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h index 4e0806f..e53c779 100644 --- a/sysdeps/i386/dl-machine.h +++ b/sysdeps/i386/dl-machine.h @@ -73,20 +73,31 @@ elf_machine_load_address (void) static inline void elf_machine_rel (struct link_map *map, - const Elf32_Rel *reloc, - Elf32_Addr sym_loadaddr, const Elf32_Sym *sym) + const Elf32_Rel *reloc, const Elf32_Sym *sym, + Elf32_Addr (*resolve) (const Elf32_Sym **ref, + Elf32_Addr reloc_addr, + int noplt)) { Elf32_Addr *const reloc_addr = (void *) (map->l_addr + reloc->r_offset); - const Elf32_Addr sym_value = sym ? sym_loadaddr + sym->st_value : 0; + Elf32_Addr loadbase; switch (ELF32_R_TYPE (reloc->r_info)) { case R_386_COPY: - memcpy (reloc_addr, (void *) sym_value, sym->st_size); + loadbase = (*resolve) (&sym, (Elf32_Addr) reloc_addr, 0); + memcpy (reloc_addr, (void *) (loadbase + sym->st_value), sym->st_size); break; case R_386_GLOB_DAT: + loadbase = (resolve ? (*resolve) (&sym, (Elf32_Addr) reloc_addr, 0) : + /* RESOLVE is null during bootstrap relocation. */ + map->l_addr); + *reloc_addr = sym ? (loadbase + sym->st_value) : 0; + break; case R_386_JMP_SLOT: - *reloc_addr = sym_value; + loadbase = (resolve ? (*resolve) (&sym, (Elf32_Addr) reloc_addr, 1) : + /* RESOLVE is null during bootstrap relocation. */ + map->l_addr); + *reloc_addr = sym ? (loadbase + sym->st_value) : 0; break; case R_386_32: if (map->l_type == lt_interpreter) @@ -100,14 +111,17 @@ elf_machine_rel (struct link_map *map, *reloc_addr -= (map->l_addr + dlsymtab[ELF32_R_SYM (reloc->r_info)].st_value); } - *reloc_addr += sym_value; + loadbase = (*resolve) (&sym, (Elf32_Addr) reloc_addr, 0); + *reloc_addr += sym ? (loadbase + sym->st_value) : 0; break; case R_386_RELATIVE: if (map->l_type != lt_interpreter) /* Already done in dynamic linker. */ *reloc_addr += map->l_addr; break; case R_386_PC32: - *reloc_addr += sym_value - (Elf32_Addr) reloc_addr; + loadbase = (*resolve) (&sym, (Elf32_Addr) reloc_addr, 0); + *reloc_addr += ((sym ? (loadbase + sym->st_value) : 0) - + (Elf32_Addr) reloc_addr); break; case R_386_NONE: /* Alright, Wilbur. */ break; diff --git a/sysdeps/m68k/dl-machine.h b/sysdeps/m68k/dl-machine.h index aa1f19e..760bf96 100644 --- a/sysdeps/m68k/dl-machine.h +++ b/sysdeps/m68k/dl-machine.h @@ -73,43 +73,67 @@ elf_machine_load_address (void) static inline void elf_machine_rela (struct link_map *map, - const Elf32_Rela *reloc, - Elf32_Addr sym_loadaddr, const Elf32_Sym *sym) + const Elf32_Rel *reloc, const Elf32_Sym *sym, + Elf32_Addr (*resolve) (const Elf32_Sym **ref, + Elf32_Addr reloc_addr, + int noplt)) { Elf32_Addr *const reloc_addr = (void *) (map->l_addr + reloc->r_offset); - const Elf32_Addr sym_value = sym ? sym_loadaddr + sym->st_value : 0; + Elf32_Addr loadbase; switch (ELF32_R_TYPE (reloc->r_info)) { case R_68K_COPY: - memcpy (reloc_addr, (void *) sym_value, sym->st_size); + loadbase = (*resolve) (&sym, (Elf32_Addr) reloc_addr, 0); + memcpy (reloc_addr, (void *) (loadbase + sym->st_value), sym->st_size); break; case R_68K_GLOB_DAT: + loadbase = (resolve ? (*resolve) (&sym, (Elf32_Addr) reloc_addr, 0) : + /* RESOLVE is null during bootstrap relocation. */ + map->l_addr); + *reloc_addr = sym ? (loadbase + sym->st_value) : 0; + break; case R_68K_JMP_SLOT: - *reloc_addr = sym_value; + loadbase = (resolve ? (*resolve) (&sym, (Elf32_Addr) reloc_addr, 1) : + /* RESOLVE is null during bootstrap relocation. */ + map->l_addr); + *reloc_addr = sym ? (loadbase + sym->st_value) : 0; break; case R_68K_8: - *(char *) reloc_addr = sym_value + reloc->r_addend; + loadbase = (*resolve) (&sym, (Elf32_Addr) reloc_addr, 0); + *(char *) reloc_addr = ((sym ? (loadbase + sym->st_value) : 0) + + reloc->r_addend); break; case R_68K_16: - *(short *) reloc_addr = sym_value + reloc->r_addend; + loadbase = (*resolve) (&sym, (Elf32_Addr) reloc_addr, 0); + *(short *) reloc_addr = ((sym ? (loadbase + sym->st_value) : 0) + + reloc->r_addend); break; case R_68K_32: - *reloc_addr = sym_value + reloc->r_addend; + loadbase = (*resolve) (&sym, (Elf32_Addr) reloc_addr, 0); + *reloc_addr = ((sym ? (loadbase + sym->st_value) : 0) + + reloc->r_addend); break; case R_68K_RELATIVE: *reloc_addr = map->l_addr + reloc->r_addend; break; case R_68K_PC8: - *(char *) reloc_addr = (sym_value + reloc->r_addend + loadbase = (*resolve) (&sym, (Elf32_Addr) reloc_addr, 0); + *(char *) reloc_addr = ((sym ? (loadbase + sym->st_value) : 0) + + reloc->r_addend - (Elf32_Addr) reloc_addr); break; case R_68K_PC16: - *(short *) reloc_addr = (sym_value + reloc->r_addend + loadbase = (*resolve) (&sym, (Elf32_Addr) reloc_addr, 0); + *(short *) reloc_addr = ((sym ? (loadbase + sym->st_value) : 0) + + reloc->r_addend - (Elf32_Addr) reloc_addr); break; case R_68K_PC32: - *reloc_addr = sym_value + reloc->r_addend - (Elf32_Addr) reloc_addr; + loadbase = (*resolve) (&sym, (Elf32_Addr) reloc_addr, 0); + *reloc_addr = ((sym ? (loadbase + sym->st_value) : 0) + + reloc->r_addend + - (Elf32_Addr) reloc_addr); break; case R_68K_NONE: /* Alright, Wilbur. */ break; diff --git a/sysdeps/stub/dl-machine.h b/sysdeps/stub/dl-machine.h index 73943f1..1fdb461 100644 --- a/sysdeps/stub/dl-machine.h +++ b/sysdeps/stub/dl-machine.h @@ -61,16 +61,19 @@ elf_machine_load_address (void) static inline void elf_machine_rel (Elf32_Addr loadaddr, Elf32_Dyn *info[DT_NUM], - const Elf32_Rel *reloc, - Elf32_Addr sym_loadaddr, const Elf32_Sym *sym) + const Elf32_Rel *reloc, const Elf32_Sym *sym, + Elf32_Addr (*resolve) (const Elf32_Sym **ref, + Elf32_Addr reloc_addr, + int noplt)) { Elf32_Addr *const reloc_addr = (Elf32_Addr *) reloc->r_offset; - const Elf32_Addr sym_value = sym_loadaddr + sym->st_value; + Elf32_Addr loadbase; switch (ELF32_R_TYPE (reloc->r_info)) { case R_MACHINE_COPY: - memcpy (reloc_addr, (void *) sym_value, sym->st_size); + loadbase = (*resolve) (&sym, (Elf32_Addr) reloc_addr, 0); + memcpy (reloc_addr, (void *) (loadbase + sym->st_value), sym->st_size); break; default: assert (! "unexpected dynamic reloc type"); @@ -81,8 +84,10 @@ elf_machine_rel (Elf32_Addr loadaddr, Elf32_Dyn *info[DT_NUM], static inline void elf_machine_rela (Elf32_Addr loadaddr, Elf32_Dyn *info[DT_NUM], - const Elf32_Rela *reloc, - Elf32_Addr sym_loadaddr, const Elf32_Sym *sym) + const Elf32_Rel *reloc, const Elf32_Sym *sym, + Elf32_Addr (*resolve) (const Elf32_Sym **ref, + Elf32_Addr reloc_addr, + int noplt)) { _dl_signal_error (0, "Elf32_Rela relocation requested -- unused on " ELF_MACHINE_NAME);