Update.
authorUlrich Drepper <drepper@redhat.com>
Sat, 20 Feb 1999 15:02:24 +0000 (15:02 +0000)
committerUlrich Drepper <drepper@redhat.com>
Sat, 20 Feb 1999 15:02:24 +0000 (15:02 +0000)
* elf/dynamic-link.h (elf_get_dynamic_info): Take new argument with
load address.  Relocate d_ptr in DT_DTRTAB, DT_SYMTAB, DT_RELA, DT_REL,
DT_JMPREL, DT_PLTGOT, and DT_VERSYM l_info entry.
(_ELF_DYNAMIC_DO_RELOC): Take extra argument which specifies whether
rel and rela relocations can both happen and skip one test if this
is not possible.
(ELF_DYNAMIC_DO_RELA, ELF_DYNAMIC_DO_REL): Call _ELF_DYNAMIC_DO_RELOC
appropriately.
* elf/dl-addr.c (_dl_addr): DT_SYMTAB and DT_STRTAB entries are
already relocated.
* elf/dl-deps.c (_dl_map_object_deps): DT_STRTAB entry is already
relocated.
* elf/dl-load.c (_dl_init_paths): DT_STRTAB entry is already relocated.
(_dl_map_object_from_fd): Call elf_get_dynamic_info with new argument.
(_dl_map_object): DT_STRTAB entry is already relocated.
* elf/dl-lookup.c (do_lookup): DT_STRTAB and DT_SYMTAB entries are
already relocated.
* elf/dl-reloc.c (_dl_relocate_object): DT_STRTAB entry is already
relocated.
* elf/dl-runtime.c (fixup): DT_SYMTAB, DT_STRTAB, DT_JMPREL, and
DT_VERSYM entries are already relocated.
(profile_fixup): Likewise.
* elf/dl-version.c: Rename VERSTAG macro into VERSYMIDX.  Replace
all users.
(match_symbol): DT_STRTAB entry is already relocated.
(_dl_check_map_versions): Likewise.  Also fo DT_VERSYM.
* elf/do-rel.h (elf_dynamic_do_rel): reladdr is now assumed to be
relocated already.  DT_SYMTAB and DT_VERSYM entries are also relocated.
* elf/rtld.c (_dl_start): Pass extra argument to elf_get_dynamic_info.
(find_needed): DT_STRTAB entry is already relocated.
(dl_main): Pass extra argument to elf_get_dynamic_info.
DT_STRTAB entry is already relocated.
* sysdeps/alpha/dl-machine.h (elf_machine_fixup_plt): DT_JMPREL and
DT_PLTGOT entries are already relocated.
(elf_machine_rela): Likewise for DT_SYMTAB.
* sysdeps/arm/dl-machine.h (elf_machine_rel): DT_STRTAB is already
relocated.
* sysdeps/i386/dl-machine.h (elf_machine_rel): Likewise.
* sysdeps/m68k/dl-machine.h (elf_machine_rela): Likewise.
* sysdeps/sparc/sparc32/dl-machine.h (elf_machine_rela): Likewise.
* sysdeps/sparc/sparc64/dl-machine.h (elf_machine_rela): Likewise.
* sysdeps/powerpc/dl-machine.c (__process_machine_rela): Likewise.
* sysdeps/mips/dl-machine.h (elf_machine_got_rel): Likewise.
(elf_machine_got_rel): Likewise for DT_SYMTAB and DT_STRTAB.

* grp/initgroups.c (initgroups): If function in current module was
successful don't stop but continue to process to get all the groups.

20 files changed:
ChangeLog
elf/dl-addr.c
elf/dl-deps.c
elf/dl-load.c
elf/dl-lookup.c
elf/dl-reloc.c
elf/dl-runtime.c
elf/dl-version.c
elf/do-rel.h
elf/dynamic-link.h
elf/rtld.c
grp/initgroups.c
sysdeps/alpha/dl-machine.h
sysdeps/arm/dl-machine.h
sysdeps/i386/dl-machine.h
sysdeps/m68k/dl-machine.h
sysdeps/mips/dl-machine.h
sysdeps/powerpc/dl-machine.c
sysdeps/sparc/sparc32/dl-machine.h
sysdeps/sparc/sparc64/dl-machine.h

index cc94e947cf6cced4de31a3507f884880d6f98109..dfc4d0da81d8be92764e49423796ee69b0a3175c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,53 @@
 1999-02-20  Ulrich Drepper  <drepper@cygnus.com>
 
+       * elf/dynamic-link.h (elf_get_dynamic_info): Take new argument with
+       load address.  Relocate d_ptr in DT_DTRTAB, DT_SYMTAB, DT_RELA, DT_REL,
+       DT_JMPREL, DT_PLTGOT, and DT_VERSYM l_info entry.
+       (_ELF_DYNAMIC_DO_RELOC): Take extra argument which specifies whether
+       rel and rela relocations can both happen and skip one test if this
+       is not possible.
+       (ELF_DYNAMIC_DO_RELA, ELF_DYNAMIC_DO_REL): Call _ELF_DYNAMIC_DO_RELOC
+       appropriately.
+       * elf/dl-addr.c (_dl_addr): DT_SYMTAB and DT_STRTAB entries are
+       already relocated.
+       * elf/dl-deps.c (_dl_map_object_deps): DT_STRTAB entry is already
+       relocated.
+       * elf/dl-load.c (_dl_init_paths): DT_STRTAB entry is already relocated.
+       (_dl_map_object_from_fd): Call elf_get_dynamic_info with new argument.
+       (_dl_map_object): DT_STRTAB entry is already relocated.
+       * elf/dl-lookup.c (do_lookup): DT_STRTAB and DT_SYMTAB entries are
+       already relocated.
+       * elf/dl-reloc.c (_dl_relocate_object): DT_STRTAB entry is already
+       relocated.
+       * elf/dl-runtime.c (fixup): DT_SYMTAB, DT_STRTAB, DT_JMPREL, and
+       DT_VERSYM entries are already relocated.
+       (profile_fixup): Likewise.
+       * elf/dl-version.c: Rename VERSTAG macro into VERSYMIDX.  Replace
+       all users.
+       (match_symbol): DT_STRTAB entry is already relocated.
+       (_dl_check_map_versions): Likewise.  Also fo DT_VERSYM.
+       * elf/do-rel.h (elf_dynamic_do_rel): reladdr is now assumed to be
+       relocated already.  DT_SYMTAB and DT_VERSYM entries are also relocated.
+       * elf/rtld.c (_dl_start): Pass extra argument to elf_get_dynamic_info.
+       (find_needed): DT_STRTAB entry is already relocated.
+       (dl_main): Pass extra argument to elf_get_dynamic_info.
+       DT_STRTAB entry is already relocated.
+       * sysdeps/alpha/dl-machine.h (elf_machine_fixup_plt): DT_JMPREL and
+       DT_PLTGOT entries are already relocated.
+       (elf_machine_rela): Likewise for DT_SYMTAB.
+       * sysdeps/arm/dl-machine.h (elf_machine_rel): DT_STRTAB is already
+       relocated.
+       * sysdeps/i386/dl-machine.h (elf_machine_rel): Likewise.
+       * sysdeps/m68k/dl-machine.h (elf_machine_rela): Likewise.
+       * sysdeps/sparc/sparc32/dl-machine.h (elf_machine_rela): Likewise.
+       * sysdeps/sparc/sparc64/dl-machine.h (elf_machine_rela): Likewise.
+       * sysdeps/powerpc/dl-machine.c (__process_machine_rela): Likewise.
+       * sysdeps/mips/dl-machine.h (elf_machine_got_rel): Likewise.
+       (elf_machine_got_rel): Likewise for DT_SYMTAB and DT_STRTAB.
+
+       * grp/initgroups.c (initgroups): If function in current module was
+       successful don't stop but continue to process to get all the groups.
+
        * elf/dl-load.c (_dl_map_object_from_fd): Use global
        _dl_pf_to_proot array to convert p_flags value.
        * elf/dl-reloc.c (_dl_relocate_object): Likewise.
index 2c9a9dd84eb76ff27e278eb23b8b08b2369ec178..14bff06f1386af76aa85fc9a86c185af616cb9c8 100644 (file)
@@ -1,5 +1,5 @@
 /* Locate the shared object symbol nearest a given address.
-   Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 1998, 1999 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
@@ -62,8 +62,8 @@ _dl_addr (const void *address, Dl_info *info)
   info->dli_fname = match->l_name;
   info->dli_fbase = (void *) match->l_addr;
 
-  symtab = ((void *) match->l_addr + match->l_info[DT_SYMTAB]->d_un.d_ptr);
-  strtab = ((void *) match->l_addr + match->l_info[DT_STRTAB]->d_un.d_ptr);
+  symtab = (const void *) match->l_info[DT_SYMTAB]->d_un.d_ptr;
+  strtab = (const void *) match->l_info[DT_STRTAB]->d_un.d_ptr;
 
   /* We assume that the string table follows the symbol table, because
      there is no way in ELF to know the size of the dynamic symbol table!!  */
index 355618ad1c899820010509bb68d6dff39c19c958..ca0d9322bab1658c28049ec0c0ccf099b43ab550 100644 (file)
@@ -149,8 +149,7 @@ _dl_map_object_deps (struct link_map *map,
 
       if (l->l_info[DT_NEEDED] || l->l_info[AUXTAG] || l->l_info[FILTERTAG])
        {
-         const char *strtab = ((void *) l->l_addr
-                               + l->l_info[DT_STRTAB]->d_un.d_ptr);
+         const char *strtab = (const void *) l->l_info[DT_STRTAB]->d_un.d_ptr;
          struct openaux_args args;
          struct list *orig;
          const ElfW(Dyn) *d;
index 3de1dca57333eb3f85cfad62e33ddfea4ed124af..345b97f099fa1f4e8f50b72d81b86b8be3a42417 100644 (file)
@@ -531,9 +531,9 @@ _dl_init_paths (const char *llp)
        /* Allocate room for the search path and fill in information
           from RPATH.  */
        l->l_rpath_dirs =
-         decompose_rpath ((const char *)
-                          (l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr
-                           + l->l_info[DT_RPATH]->d_un.d_val), l);
+         decompose_rpath ((const void *) (l->l_info[DT_STRTAB]->d_un.d_ptr
+                                          + l->l_info[DT_RPATH]->d_un.d_val),
+                          l);
       else
        l->l_rpath_dirs = NULL;
     }
@@ -983,7 +983,7 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname,
                         "  phnum:   ", buf3, "\n\n", NULL);
     }
 
-  elf_get_dynamic_info (l->l_ld, l->l_info);
+  elf_get_dynamic_info (l->l_ld, l->l_addr, l->l_info);
   if (l->l_info[DT_HASH])
     _dl_setup_hash (l);
 
@@ -1208,8 +1208,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
          if (l->l_info[DT_SONAME] == NULL)
            continue;
 
-         soname = (const char *) (l->l_addr
-                                  + l->l_info[DT_STRTAB]->d_un.d_ptr
+         soname = (const void *) (l->l_info[DT_STRTAB]->d_un.d_ptr
                                   + l->l_info[DT_SONAME]->d_un.d_val);
          if (strcmp (name, soname) != 0)
            continue;
@@ -1248,8 +1247,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
            /* Make sure the cache information is available.  */
            if (l->l_rpath_dirs == NULL)
              {
-               size_t ptrval = (l->l_addr
-                                + l->l_info[DT_STRTAB]->d_un.d_ptr
+               size_t ptrval = (l->l_info[DT_STRTAB]->d_un.d_ptr
                                 + l->l_info[DT_RPATH]->d_un.d_val);
                l->l_rpath_dirs =
                  decompose_rpath ((const char *) ptrval, l);
index ef953c54753607c20b91d9dd6d70e7c0893d51cd..de5ecf5d621696ea48ba3e142def5300702ff11e 100644 (file)
@@ -110,8 +110,8 @@ do_lookup (const char *undef_name, unsigned long int hash,
                           map->l_name[0] ? map->l_name : _dl_argv[0],
                           "\n", NULL);
 
-      symtab = ((void *) map->l_addr + map->l_info[DT_SYMTAB]->d_un.d_ptr);
-      strtab = ((void *) map->l_addr + map->l_info[DT_STRTAB]->d_un.d_ptr);
+      symtab = (const void *) map->l_info[DT_SYMTAB]->d_un.d_ptr;
+      strtab = (const void *) map->l_info[DT_STRTAB]->d_un.d_ptr;
       verstab = map->l_versyms;
 
       /* Search the appropriate hash bucket in this object's symbol table
index be860af940320c88d3d6bd4269a37931e43e6b8f..54a2acc065788b37efe57aaf5018784c22bf1f72 100644 (file)
@@ -66,8 +66,8 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
   {
     /* Do the actual relocation of the object's GOT and other data.  */
 
-    const char *strtab         /* String table object symbols.  */
-      = ((void *) l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr);
+    /* String table object symbols.  */
+    const char *strtab = (const void *) l->l_info[DT_STRTAB]->d_un.d_ptr;
 
     /* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code.  */
 #define RESOLVE(ref, version, flags) \
index 91700c2764e48107b1a90f06d25b0dc839d8374e..a0f54bd3fccc72cf08beb2718b6e0e917ba66f6d 100644 (file)
@@ -1,5 +1,5 @@
 /* On-demand PLT fixup for shared objects.
-   Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 1997, 1998, 1999 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
@@ -48,13 +48,11 @@ fixup (
        struct link_map *l, ElfW(Word) reloc_offset)
 {
   const ElfW(Sym) *const symtab
-    = (const ElfW(Sym) *) (l->l_addr + l->l_info[DT_SYMTAB]->d_un.d_ptr);
-  const char *strtab =
-    (const char *) (l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr);
+    = (const void *) l->l_info[DT_SYMTAB]->d_un.d_ptr;
+  const char *strtab = (const void *) l->l_info[DT_STRTAB]->d_un.d_ptr;
 
   const PLTREL *const reloc
-    = (const void *) (l->l_addr + l->l_info[DT_JMPREL]->d_un.d_ptr +
-                     reloc_offset);
+    = (const void *) (l->l_info[DT_JMPREL]->d_un.d_ptr + reloc_offset);
   const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)];
   void *const rel_addr = (void *)(l->l_addr + reloc->r_offset);
   ElfW(Addr) value;
@@ -67,8 +65,8 @@ fixup (
     {
     default:
       {
-       const ElfW(Half) *vernum = (const ElfW(Half) *)
-         (l->l_addr + l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr);
+       const ElfW(Half) *vernum =
+         (const void *) l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr;
        ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)];
        const struct r_found_version *version = &l->l_versions[ndx];
 
@@ -121,13 +119,11 @@ profile_fixup (
     {
       /* This is the first time we have to relocate this object.  */
       const ElfW(Sym) *const symtab
-       = (const ElfW(Sym) *) (l->l_addr + l->l_info[DT_SYMTAB]->d_un.d_ptr);
-      const char *strtab =
-       (const char *) (l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr);
+       = (const void *) l->l_info[DT_SYMTAB]->d_un.d_ptr;
+      const char *strtab = (const void *) l->l_info[DT_STRTAB]->d_un.d_ptr;
 
       const PLTREL *const reloc
-       = (const void *) (l->l_addr + l->l_info[DT_JMPREL]->d_un.d_ptr +
-                         reloc_offset);
+       = (const void *) (l->l_info[DT_JMPREL]->d_un.d_ptr + reloc_offset);
       const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)];
 
       /* Sanity check that we're really looking at a PLT relocation.  */
@@ -138,8 +134,8 @@ profile_fixup (
        {
        default:
          {
-           const ElfW(Half) *vernum = (const ElfW(Half) *)
-             (l->l_addr + l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr);
+           const ElfW(Half) *vernum =
+             (const void *) l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr;
            ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)];
            const struct r_found_version *version = &l->l_versions[ndx];
 
index 4ba7f1ab3ad2161ed534a9db2f1ab9188cbb7827..fbc41654ef8e5b09d5bff1e978fc97c99d7da1b7 100644 (file)
@@ -1,5 +1,5 @@
 /* Handle symbol and library versioning.
-   Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -28,7 +28,9 @@
 #include <assert.h>
 
 
-#define VERSTAG(tag)   (DT_NUM + DT_PROCNUM + DT_VERSIONTAGIDX (tag))
+#ifndef VERSYMIDX
+# define VERSYMIDX(tag)        (DT_NUM + DT_PROCNUM + DT_VERSIONTAGIDX (tag))
+#endif
 
 
 #define make_string(string, rest...) \
@@ -75,8 +77,7 @@ internal_function
 match_symbol (const char *name, ElfW(Word) hash, const char *string,
              struct link_map *map, int verbose, int weak)
 {
-  const char *strtab = (const char *) (map->l_addr
-                                      + map->l_info[DT_STRTAB]->d_un.d_ptr);
+  const char *strtab = (const void *) map->l_info[DT_STRTAB]->d_un.d_ptr;
   ElfW(Addr) def_offset;
   ElfW(Verdef) *def;
 
@@ -86,7 +87,7 @@ match_symbol (const char *name, ElfW(Word) hash, const char *string,
                       map->l_name[0] ? map->l_name : _dl_argv[0],
                       " required by file ", name, "\n", NULL);
 
-  if (map->l_info[VERSTAG (DT_VERDEF)] == NULL)
+  if (map->l_info[VERSYMIDX (DT_VERDEF)] == NULL)
     {
       /* The file has no symbol versioning.  I.e., the dependent
         object was linked against another version of this file.  We
@@ -98,7 +99,7 @@ no version information available (required by ",
       return 0;
     }
 
-  def_offset = map->l_info[VERSTAG (DT_VERDEF)]->d_un.d_ptr;
+  def_offset = map->l_info[VERSYMIDX (DT_VERDEF)]->d_un.d_ptr;
   assert (def_offset != 0);
 
   def = (ElfW(Verdef) *) ((char *) map->l_addr + def_offset);
@@ -173,10 +174,10 @@ _dl_check_map_versions (struct link_map *map, int verbose)
   /* If we don't have a string table, we must be ok.  */
   if (map->l_info[DT_STRTAB] == NULL)
     return 0;
-  strtab = (const char *) (map->l_addr + map->l_info[DT_STRTAB]->d_un.d_ptr);
+  strtab = (const void *) map->l_info[DT_STRTAB]->d_un.d_ptr;
 
-  dyn = map->l_info[VERSTAG (DT_VERNEED)];
-  def = map->l_info[VERSTAG (DT_VERDEF)];
+  dyn = map->l_info[VERSYMIDX (DT_VERNEED)];
+  def = map->l_info[VERSYMIDX (DT_VERDEF)];
 
   if (dyn != NULL)
     {
@@ -282,8 +283,8 @@ _dl_check_map_versions (struct link_map *map, int verbose)
          map->l_nversions = ndx_high + 1;
 
          /* Compute the pointer to the version symbols.  */
-         map->l_versyms = ((void *) map->l_addr
-                           + map->l_info[VERSTAG (DT_VERSYM)]->d_un.d_ptr);
+         map->l_versyms =
+           (void *) map->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr;
 
          if (dyn != NULL)
            {
index c0f48241bfd933345ea33eee7bc6453e4614f5e7..803d250bba652d754d7d995414f1bf236a2ab1f6 100644 (file)
@@ -1,5 +1,5 @@
 /* Do relocations for ELF dynamic linking.
-   Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 1997, 1998, 1999 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
@@ -40,8 +40,8 @@ elf_dynamic_do_rel (struct link_map *map,
                    ElfW(Addr) reladdr, ElfW(Addr) relsize,
                    int lazy)
 {
-  const ElfW(Rel) *r = (const ElfW(Rel) *)(map->l_addr + reladdr);
-  const ElfW(Rel) *end = (const ElfW(Rel) *)(map->l_addr + reladdr + relsize);
+  const ElfW(Rel) *r = (const void *) reladdr;
+  const ElfW(Rel) *end = (const void *) (reladdr + relsize);
 
   if (lazy)
     {
@@ -53,13 +53,12 @@ elf_dynamic_do_rel (struct link_map *map,
   else
     {
       const ElfW(Sym) *const symtab =
-       (const ElfW(Sym) *) (map->l_addr + map->l_info[DT_SYMTAB]->d_un.d_ptr);
+       (const void *) map->l_info[DT_SYMTAB]->d_un.d_ptr;
 
       if (map->l_info[VERSYMIDX (DT_VERSYM)])
        {
          const ElfW(Half) *const version =
-           (const ElfW(Half) *) (map->l_addr
-                                 + map->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr);
+           (const void *) map->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr;
 
          for (; r < end; ++r)
            {
index 3d96ecc143cb2c57bf8eca2a5d9a7872df7694f0..d322c1231faa19900cf1f5e078d93d4203b8ce7a 100644 (file)
 #include <dl-machine.h>
 #include <assert.h>
 
+#ifndef VERSYMIDX
+# define VERSYMIDX(sym)        (DT_NUM + DT_PROCNUM + DT_VERSIONTAGIDX (sym))
+#endif
+
 
 /* Global read-only variable defined in rtld.c which is nonzero if we
    shall give more warning messages.  */
@@ -30,13 +34,10 @@ extern int _dl_verbose __attribute__ ((unused));
 /* Read the dynamic section at DYN and fill in INFO with indices DT_*.  */
 
 static inline void __attribute__ ((unused))
-elf_get_dynamic_info (ElfW(Dyn) *dyn,
+elf_get_dynamic_info (ElfW(Dyn) *dyn, ElfW(Addr) l_addr,
                      ElfW(Dyn) *info[DT_NUM + DT_PROCNUM + DT_VERSIONTAGNUM
                                     + DT_EXTRANUM])
 {
-  memset (info, '\0', ((DT_NUM + DT_PROCNUM + DT_VERSIONTAGNUM + DT_EXTRANUM)
-                      * sizeof (ElfW(Dyn) *)));
-
   if (! dyn)
     return;
 
@@ -48,7 +49,7 @@ elf_get_dynamic_info (ElfW(Dyn) *dyn,
               dyn->d_tag < DT_LOPROC + DT_PROCNUM)
        info[dyn->d_tag - DT_LOPROC + DT_NUM] = dyn;
       else if ((Elf32_Word) DT_VERSIONTAGIDX (dyn->d_tag) < DT_VERSIONTAGNUM)
-       info[DT_VERSIONTAGIDX (dyn->d_tag) + DT_NUM + DT_PROCNUM] = dyn;
+       info[VERSYMIDX (dyn->d_tag)] = dyn;
       else if ((Elf32_Word) DT_EXTRATAGIDX (dyn->d_tag) < DT_EXTRANUM)
        info[DT_EXTRATAGIDX (dyn->d_tag) + DT_NUM + DT_PROCNUM
             + DT_VERSIONTAGNUM] = dyn;
@@ -57,13 +58,41 @@ elf_get_dynamic_info (ElfW(Dyn) *dyn,
       ++dyn;
     }
 
-  if (info[DT_RELA])
-    assert (info[DT_RELAENT]->d_un.d_val == sizeof (ElfW(Rela)));
-  if (info[DT_REL])
-    assert (info[DT_RELENT]->d_un.d_val == sizeof (ElfW(Rel)));
-  if (info[DT_PLTREL])
-    assert (info[DT_PLTREL]->d_un.d_val == DT_REL ||
-           info[DT_PLTREL]->d_un.d_val == DT_RELA);
+  if (info[DT_PLTGOT] != NULL)
+    info[DT_PLTGOT]->d_un.d_ptr += l_addr;
+  if (info[DT_STRTAB] != NULL)
+    info[DT_STRTAB]->d_un.d_ptr += l_addr;
+  if (info[DT_SYMTAB] != NULL)
+    info[DT_SYMTAB]->d_un.d_ptr += l_addr;
+#if ! ELF_MACHINE_NO_RELA
+  if (info[DT_RELA] != NULL)
+    {
+      assert (info[DT_RELAENT]->d_un.d_val == sizeof (ElfW(Rela)));
+      info[DT_RELA]->d_un.d_ptr += l_addr;
+    }
+#endif
+#if ! ELF_MACHINE_NO_REL
+  if (info[DT_REL] != NULL)
+    {
+      assert (info[DT_RELENT]->d_un.d_val == sizeof (ElfW(Rel)));
+      info[DT_REL]->d_un.d_ptr += l_addr;
+    }
+#endif
+  if (info[DT_PLTREL] != NULL)
+    {
+#if ELF_MACHINE_NO_RELA
+      assert (info[DT_PLTREL]->d_un.d_val == DT_REL);
+#elif ELF_MACHINE_NO_REL
+      assert (info[DT_PLTREL]->d_un.d_val == DT_RELA);
+#else
+      assert (info[DT_PLTREL]->d_un.d_val == DT_REL
+             || info[DT_PLTREL]->d_un.d_val == DT_RELA);
+#endif
+    }
+  if (info[DT_JMPREL] != NULL)
+    info[DT_JMPREL]->d_un.d_ptr += l_addr;
+  if (info[VERSYMIDX (DT_VERSYM)] != NULL)
+    info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr += l_addr;
 }
 
 #ifdef RESOLVE
@@ -73,13 +102,13 @@ elf_get_dynamic_info (ElfW(Dyn) *dyn,
    duplicating their code.  It cannot be done in a more general function
    because we must be able to completely inline.  */
 
-/* On some machines, notably Sparc, DT_REL* includes DT_JMPREL in its
+/* On some machines, notably SPARC, DT_REL* includes DT_JMPREL in its
    range.  Note that according to the ELF spec, this is completely legal!
    But conditionally define things so that on machines we know this will
    not happen we do something more optimal.  */
 
-#ifdef ELF_MACHINE_PLTREL_OVERLAP
-#define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy) \
+# ifdef ELF_MACHINE_PLTREL_OVERLAP
+#  define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, test_rel) \
   do {                                                                       \
     struct { ElfW(Addr) start, size; int lazy; } ranges[3];                  \
     int ranges_index;                                                        \
@@ -96,7 +125,7 @@ elf_get_dynamic_info (ElfW(Dyn) *dyn,
                                                                              \
      if ((do_lazy)                                                           \
        && (map)->l_info[DT_PLTREL]                                           \
-       && (map)->l_info[DT_PLTREL]->d_un.d_val == DT_##RELOC)                \
+       && (!test_rel || (map)->l_info[DT_PLTREL]->d_un.d_val == DT_##RELOC)) \
       {                                                                              \
        ranges[1].start = (map)->l_info[DT_JMPREL]->d_un.d_ptr;               \
        ranges[1].size = (map)->l_info[DT_PLTRELSZ]->d_un.d_val;              \
@@ -111,8 +140,8 @@ elf_get_dynamic_info (ElfW(Dyn) *dyn,
                              ranges[ranges_index].size,                      \
                              ranges[ranges_index].lazy);                     \
   } while (0)
-#else
-#define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy) \
+# else
+#  define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, test_rel) \
   do {                                                                       \
     struct { ElfW(Addr) start, size; int lazy; } ranges[2];                  \
     int ranges_index;                                                        \
@@ -125,8 +154,8 @@ elf_get_dynamic_info (ElfW(Dyn) *dyn,
         ranges[0].start = (map)->l_info[DT_##RELOC]->d_un.d_ptr;             \
         ranges[0].size = (map)->l_info[DT_##RELOC##SZ]->d_un.d_val;          \
       }                                                                              \
-    if ((map)->l_info[DT_PLTREL] &&                                          \
-       (map)->l_info[DT_PLTREL]->d_un.d_val == DT_##RELOC)                   \
+    if ((map)->l_info[DT_PLTREL]                                             \
+       && (!test_rel || (map)->l_info[DT_PLTREL]->d_un.d_val == DT_##RELOC)) \
       {                                                                              \
        ElfW(Addr) start = (map)->l_info[DT_JMPREL]->d_un.d_ptr;              \
                                                                              \
@@ -151,28 +180,34 @@ elf_get_dynamic_info (ElfW(Dyn) *dyn,
                              ranges[ranges_index].size,                      \
                              ranges[ranges_index].lazy);                     \
   } while (0)
-#endif
-
-#if ! ELF_MACHINE_NO_REL
-#include "do-rel.h"
-#define ELF_DYNAMIC_DO_REL(map, lazy) \
-  _ELF_DYNAMIC_DO_RELOC (REL, rel, map, lazy)
-#else
-#define ELF_DYNAMIC_DO_REL(map, lazy) /* Nothing to do.  */
-#endif
-
-#if ! ELF_MACHINE_NO_RELA
-#define DO_RELA
-#include "do-rel.h"
-#define ELF_DYNAMIC_DO_RELA(map, lazy) \
-  _ELF_DYNAMIC_DO_RELOC (RELA, rela, map, lazy)
-#else
-#define ELF_DYNAMIC_DO_RELA(map, lazy) /* Nothing to do.  */
-#endif
+# endif
+
+# if ELF_MACHINE_NO_REL || ELF_MACHINE_NO_RELA
+#  define _ELF_CHECK_REL 0
+# else
+#  define _ELF_CHECK_REL 1
+# endif
+
+# if ! ELF_MACHINE_NO_REL
+#  include "do-rel.h"
+#  define ELF_DYNAMIC_DO_REL(map, lazy) \
+  _ELF_DYNAMIC_DO_RELOC (REL, rel, map, lazy, _ELF_CHECK_REL)
+# else
+#  define ELF_DYNAMIC_DO_REL(map, lazy) /* Nothing to do.  */
+# endif
+
+# if ! ELF_MACHINE_NO_RELA
+#  define DO_RELA
+#  include "do-rel.h"
+#  define ELF_DYNAMIC_DO_RELA(map, lazy) \
+  _ELF_DYNAMIC_DO_RELOC (RELA, rela, map, lazy, _ELF_CHECK_REL)
+# else
+#  define ELF_DYNAMIC_DO_RELA(map, lazy) /* Nothing to do.  */
+# endif
 
 /* This can't just be an inline function because GCC is too dumb
    to inline functions containing inlines themselves.  */
-#define ELF_DYNAMIC_RELOCATE(map, lazy, consider_profile) \
+# define ELF_DYNAMIC_RELOCATE(map, lazy, consider_profile) \
   do {                                                                       \
     int edr_lazy = elf_machine_runtime_setup ((map), (lazy),                 \
                                              (consider_profile));            \
index 6aa3a65fbbac2afc404a5a78f96d56b9b4395fe5..762cdc5ff2280a0975d759ea1d3def65c192f316 100644 (file)
@@ -1,5 +1,5 @@
 /* Run time dynamic linker.
-   Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 1997, 1998, 1999 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
@@ -156,7 +156,8 @@ _dl_start (void *arg)
 
   /* Read our own dynamic section and fill in the info array.  */
   bootstrap_map.l_ld = (void *) bootstrap_map.l_addr + elf_machine_dynamic ();
-  elf_get_dynamic_info (bootstrap_map.l_ld, bootstrap_map.l_info);
+  elf_get_dynamic_info (bootstrap_map.l_ld, bootstrap_map.l_addr,
+                       bootstrap_map.l_info);
 
 #ifdef ELF_MACHINE_BEFORE_RTLD_RELOC
   ELF_MACHINE_BEFORE_RTLD_RELOC (bootstrap_map.l_info);
@@ -290,8 +291,7 @@ find_needed (const char *name)
 static int
 match_version (const char *string, struct link_map *map)
 {
-  const char *strtab = (const char *) (map->l_addr
-                                      + map->l_info[DT_STRTAB]->d_un.d_ptr);
+  const char *strtab = (const void *) map->l_info[DT_STRTAB]->d_un.d_ptr;
   ElfW(Verdef) *def;
 
 #define VERDEFTAG (DT_NUM + DT_PROCNUM + DT_VERSIONTAGIDX (DT_VERDEF))
@@ -575,7 +575,8 @@ of this helper program; chances are you did not intend to run this program.\n\
     assert (_dl_rtld_map.l_libname); /* How else did we get here?  */
 
   /* Extract the contents of the dynamic section for easy access.  */
-  elf_get_dynamic_info (_dl_loaded->l_ld, _dl_loaded->l_info);
+  elf_get_dynamic_info (_dl_loaded->l_ld, _dl_loaded->l_addr,
+                       _dl_loaded->l_info);
   if (_dl_loaded->l_info[DT_HASH])
     /* Set up our cache of pointers into the hash table.  */
     _dl_setup_hash (_dl_loaded);
@@ -889,8 +890,7 @@ of this helper program; chances are you did not intend to run this program.\n\
                  if (dyn == NULL)
                    continue;
 
-                 strtab = (const char *)
-                   (map->l_addr + map->l_info[DT_STRTAB]->d_un.d_ptr);
+                 strtab = (const void *) map->l_info[DT_STRTAB]->d_un.d_ptr;
                  ent = (ElfW(Verneed) *) (map->l_addr + dyn->d_un.d_ptr);
 
                  if (first)
index b7708077b60deb7ab456cb1c72061163501820d9..93f78eb54767349f807657bd2b50c760352ae126 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 91, 93, 96, 97, 98 Free Software Foundation, Inc.
+/* Copyright (C) 1989, 91, 93, 96, 97, 98, 99 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
@@ -198,7 +198,8 @@ initgroups (user, group)
       if (NSS_STATUS_TRYAGAIN > status || status > NSS_STATUS_RETURN)
         __libc_fatal ("illegal status in " __FUNCTION__);
 
-      if (nss_next_action (nip, status) == NSS_ACTION_RETURN)
+      if (status != NSS_STATUS_SUCCESS
+         && nss_next_action (nip, status) == NSS_ACTION_RETURN)
         break;
 
       if (nip->next == NULL)
index d351e9dccc8a39c23a9b1fe8daba24b66cdf498e..6e113807743b2c7fec5e520d45169238208c92d3 100644 (file)
@@ -1,5 +1,5 @@
 /* Machine-dependent ELF dynamic relocation inline functions.  Alpha version.
-   Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Richard Henderson <rth@tamu.edu>.
 
@@ -350,8 +350,8 @@ elf_machine_fixup_plt(struct link_map *l, const Elf64_Rela *reloc,
 
   /* Recover the PLT entry address by calculating reloc's index into the
      .rela.plt, and finding that entry in the .plt.  */
-  rela_plt = (void *)(l->l_addr + l->l_info[DT_JMPREL]->d_un.d_ptr);
-  plte = (void *)(l->l_addr + l->l_info[DT_PLTGOT]->d_un.d_ptr + 32);
+  rela_plt = (void *) l->l_info[DT_JMPREL]->d_un.d_ptr;
+  plte = (void *) (l->l_info[DT_PLTGOT]->d_un.d_ptr + 32);
   plte += 3 * (reloc - rela_plt);
 
   /* Find the displacement from the plt entry to the function.  */
@@ -481,7 +481,7 @@ elf_machine_rela (struct link_map *map,
                 than the dynamic linker's built-in definitions used
                 while loading those libraries.  */
              const Elf64_Sym *const dlsymtab
-               = (void *)(map->l_addr + map->l_info[DT_SYMTAB]->d_un.d_ptr);
+               = (void *) map->l_info[DT_SYMTAB]->d_un.d_ptr;
              sym_value -= map->l_addr;
              sym_value -= dlsymtab[ELF64_R_SYM(reloc->r_info)].st_value;
              sym_value -= reloc->r_addend;
index b8a1e19359c75e7ee8d08e79fbcb03ad84c8fda2..e443711fbac6ac1ed45c1ab8e4211183b148f9d5 100644 (file)
@@ -1,5 +1,5 @@
 /* Machine-dependent ELF dynamic relocation inline functions.  ARM version.
-   Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 1997, 1998, 1999 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
@@ -405,8 +405,7 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
            {
              const char *strtab;
 
-             strtab = ((const char *) map->l_addr
-                       + map->l_info[DT_STRTAB]->d_un.d_ptr);
+             strtab = (const void *) map->l_info[DT_STRTAB]->d_un.d_ptr;
              _dl_sysdep_error (_dl_argv[0] ?: "<program name unknown>",
                                ": Symbol `", strtab + refsym->st_name,
                                "' has different size in shared object, "
@@ -417,9 +416,9 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
          break;
        case R_ARM_GLOB_DAT:
        case R_ARM_JUMP_SLOT:
-#ifdef RTLD_BOOTSTRAP 
+#ifdef RTLD_BOOTSTRAP
          /* Fix weak undefined references.  */
-         if (sym != NULL && sym->st_value == 0) 
+         if (sym != NULL && sym->st_value == 0)
            *reloc_addr = 0;
          else
 #endif
index 8338a93617358d8d21fe7052765947b67aafa6e5..fb7fc4095e13eb188d947662c89438fb4b059d78 100644 (file)
@@ -1,5 +1,5 @@
 /* Machine-dependent ELF dynamic relocation inline functions.  i386 version.
-   Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 1997, 1998, 1999 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
@@ -339,8 +339,7 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
            {
              const char *strtab;
 
-             strtab = ((const char *) map->l_addr
-                       + map->l_info[DT_STRTAB]->d_un.d_ptr);
+             strtab = (const char *) map->l_info[DT_STRTAB]->d_un.d_ptr;
              _dl_sysdep_error (_dl_argv[0] ?: "<program name unknown>",
                                ": Symbol `", strtab + refsym->st_name,
                                "' has different size in shared object, "
@@ -359,7 +358,7 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
           /* This is defined in rtld.c, but nowhere in the static
              libc.a; make the reference weak so static programs can
              still link.  This declaration cannot be done when
-             compiling rtld.c (i.e.  #ifdef RTLD_BOOTSTRAP) because
+             compiling rtld.c (i.e. #ifdef RTLD_BOOTSTRAP) because
              rtld.c contains the common defn for _dl_rtld_map, which
              is incompatible with a weak decl in the same file.  */
            weak_extern (_dl_rtld_map);
index f2fe553069c4d4b0ab8d5c799701d201e062d61c..8ce24a7f636977565e77bc852e6885a75b9a5c15 100644 (file)
@@ -1,5 +1,5 @@
 /* Machine-dependent ELF dynamic relocation inline functions.  m68k version.
-   Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 1998, 1999 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
@@ -277,8 +277,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
              extern char **_dl_argv;
              const char *strtab;
 
-             strtab = ((void *) map->l_addr
-                       + map->l_info[DT_STRTAB]->d_un.d_ptr);
+             strtab = (const void *) map->l_info[DT_STRTAB]->d_un.d_ptr;
              _dl_sysdep_error (_dl_argv[0] ?: "<program name unknown>",
                                ": Symbol `", strtab + refsym->st_name,
                                "' has different size in shared object, "
index 77b8c4e18f014ba3d93e4c4f9acfcd1b8e33b835..749ea00170d255c29635ad88bffa16f19799d4c8 100644 (file)
@@ -1,5 +1,5 @@
 /* Machine-dependent ELF dynamic relocation inline functions.  MIPS version.
-   Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Kazumoto Kojima <kkojima@info.kanagawa-u.ac.jp>.
 
@@ -144,8 +144,7 @@ elf_machine_got_rel (struct link_map *map, int lazy)
   ElfW(Addr) *got;
   ElfW(Sym) *sym;
   int i, n;
-  const char *strtab
-    = ((void *) map->l_addr + map->l_info[DT_STRTAB]->d_un.d_ptr);
+  const char *strtab = (const void *) map->l_info[DT_STRTAB]->d_un.d_ptr;
 
 #define RESOLVE_GOTSYM(sym) \
     ({ \
@@ -170,8 +169,7 @@ elf_machine_got_rel (struct link_map *map, int lazy)
 
   /* Handle global got entries. */
   got += n;
-  sym = (ElfW(Sym) *) ((void *) map->l_addr
-                      + map->l_info[DT_SYMTAB]->d_un.d_ptr);
+  sym = (void *) map->l_info[DT_SYMTAB]->d_un.d_ptr;
   sym += map->l_info[DT_MIPS (GOTSYM)]->d_un.d_val;
   i = (map->l_info[DT_MIPS (SYMTABNO)]->d_un.d_val
        - map->l_info[DT_MIPS (GOTSYM)]->d_un.d_val);
@@ -348,9 +346,9 @@ __dl_runtime_resolve (ElfW(Word) sym_index,                               \
 {                                                                            \
   struct link_map *l = elf_machine_runtime_link_map (old_gpreg, stub_pc);     \
   const ElfW(Sym) *const symtab                                                      \
-    = (const ElfW(Sym) *) (l->l_addr + l->l_info[DT_SYMTAB]->d_un.d_ptr);     \
+    = (const void *) l->l_info[DT_SYMTAB]->d_un.d_ptr;                       \
   const char *strtab                                                         \
-    = (void *) (l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr);               \
+    = (const void *) l->l_info[DT_STRTAB]->d_un.d_ptr;                       \
   const ElfW(Addr) *got                                                              \
     = (const ElfW(Addr) *) (l->l_addr + l->l_info[DT_PLTGOT]->d_un.d_ptr);    \
   const ElfW(Word) local_gotno                                               \
index 7d45e74d65bebc1c7314ddab373b90c8e81c71b3..35086997b56fd29ac1e6256eb2b398e443e79287 100644 (file)
@@ -1,5 +1,5 @@
 /* Machine-dependent ELF dynamic relocation functions.  PowerPC version.
-   Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 1997, 1998, 1999 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
@@ -417,8 +417,7 @@ __process_machine_rela (struct link_map *map,
        {
          const char *strtab;
 
-         strtab = ((void *) map->l_addr
-                   + map->l_info[DT_STRTAB]->d_un.d_ptr);
+         strtab = (const void *) map->l_info[DT_STRTAB]->d_un.d_ptr;
          _dl_sysdep_error (_dl_argv[0] ?: "<program name unknown>",
                            ": Symbol `", strtab + refsym->st_name,
                            "' has different size in shared object, "
index e1fb2b68ce15e84f41bb5b2414a9a9fcdb2bde77..fa8cd45f45cf9b762ad047fc96dcfac9986d27a2 100644 (file)
@@ -1,5 +1,5 @@
 /* Machine-dependent ELF dynamic relocation inline functions.  SPARC version.
-   Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 1998, 1999 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
@@ -386,8 +386,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
              extern char **_dl_argv;
              const char *strtab;
 
-             strtab = ((void *) map->l_addr
-                       + map->l_info[DT_STRTAB]->d_un.d_ptr);
+             strtab = (const void *) map->l_info[DT_STRTAB]->d_un.d_ptr;
              _dl_sysdep_error (_dl_argv[0] ?: "<program name unknown>",
                                ": Symbol `", strtab + refsym->st_name,
                                "' has different size in shared object, "
index 33def6b45506dd0fdcc32cb6d19e41be58fc8181..851801bc425fc80f5b57c22c4258962508d59791 100644 (file)
@@ -1,5 +1,5 @@
 /* Machine-dependent ELF dynamic relocation inline functions.  Sparc64 version.
-   Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1998, 1999 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
@@ -213,8 +213,7 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
              extern char **_dl_argv;
              const char *strtab;
 
-             strtab = ((void *) map->l_addr
-                       + map->l_info[DT_STRTAB]->d_un.d_ptr);
+             strtab = (const void *) map->l_info[DT_STRTAB]->d_un.d_ptr;
              _dl_sysdep_error (_dl_argv[0] ?: "<program name unknown>",
                                ": Symbol `", strtab + refsym->st_name,
                                "' has different size in shared object, "