]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Mon Jun 3 00:30:35 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu> cvs/libc-960603
authorRoland McGrath <roland@gnu.org>
Mon, 3 Jun 1996 04:46:40 +0000 (04:46 +0000)
committerRoland McGrath <roland@gnu.org>
Mon, 3 Jun 1996 04:46:40 +0000 (04:46 +0000)
* 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.

16 files changed:
ChangeLog
csu/initfini.c
elf/dl-lookup.c
elf/dl-reloc.c
elf/dl-runtime.c
elf/dlfcn.h
elf/dlopen.c
elf/do-rel.h
elf/link.h
elf/rtld.c
math/math.h
posix/regex.c
shlib-versions
sysdeps/i386/dl-machine.h
sysdeps/m68k/dl-machine.h
sysdeps/stub/dl-machine.h

index a50a266bd85d8ae27c84c5a16819951b2e6fb258..7b8b44f2b7387f06788a78049010782e0977c88e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,34 @@
+Mon Jun  3 00:30:35 1996  Roland McGrath  <roland@delasyd.gnu.ai.mit.edu>
+
+       * 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  <roland@delasyd.gnu.ai.mit.edu>
 
+       * 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.
index 2727596a4ce8e6474be28b6e9706b1261479905c..8fe2368e360e3853b956e46baed0bf84bbc9b5e4 100644 (file)
@@ -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\
index 90c9b6a18df1617e634fe4119a4af1005e0bcc07..b72a6a27d55c259840df7cda671b89f0e459bda5 100644 (file)
@@ -23,13 +23,15 @@ Cambridge, MA 02139, USA.  */
 #include <assert.h>
 
 /* 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;
 
index 46fc4c4def3c4422ac892af32ddc54a7fa2670eb..424d303800098396e8006b77024775627b2b4335 100644 (file)
@@ -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;
index 941a306df91c730578624b4b66244fcb0d6d9c62..0beba769fa5b49d45f4b8ab32534fdc246b2220f 100644 (file)
@@ -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);
 }
index e5d68f82bee7acade0ffd6b907b92c23c3eaa243..a405baa4735c1815ce6531ae9a0c6e7d225bef72 100644 (file)
@@ -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'.  */
index de65a20d97169202a5468e09ddd2f9586564b2cb..26ed35ace6273039be305bcf93c4292db00a7c25 100644 (file)
@@ -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 <dlfcn.h>
 
 void *
-dlopen (const char *file, dl_open_mode mode)
+dlopen (const char *file, int mode)
 {
   struct link_map *new, *l;
 
index a265550caef54cba430f944a6a48a4bf2c4fa38b..438613a32d71f49dc7b56bb14169d3aeee04df88 100644 (file)
@@ -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
index cd75263e0a32f5977bf9ce1a89b519f28b86a781..a19a2ce0b38b79c49219688fce53bc856ac02236 100644 (file)
@@ -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);
 
 
index 157cde51d91bdc538dc4ab1ea5c35a47ca7bf5eb..511d19cb15ab201f2242d14311a6c8e72bd4c357 100644 (file)
@@ -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);
index 7a6134a6f0cb709a78e2c04a202d10a3f7c1e020..fbec2e89aef94c806c5fe8da3f56d6f863857c88 100644 (file)
@@ -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
 
 
index 8b66cd6c5a82a419f706138e351693042ea29be9..85c297b295e53afc957ebd0de2b739f43a88d81e 100644 (file)
@@ -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
index 77d7f74b33c96c1213761d8dfaf31a9f35417302..656fb2e51c991a10ea136ef18163b36984f02986 100644 (file)
@@ -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
 # -------------                ------- --------
index 4e0806fd48b5498d58829c79851d11a5c5b2e7df..e53c779ec381668f855ea74c0a04e1b7c494c2db 100644 (file)
@@ -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;
index aa1f19eacb751dda0a8a36a411232c0a7103d795..760bf9662dfc5b22a5ac607bdfc83a0466ca2cd8 100644 (file)
@@ -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;
index 73943f1558c7065947c35f704d5a01c8295e6b90..1fdb461da7efd59642307be50e1b8bebbd28040b 100644 (file)
@@ -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);