update from main archive 960814
authordrepper <drepper>
Thu, 15 Aug 1996 01:20:13 +0000 (01:20 +0000)
committerdrepper <drepper>
Thu, 15 Aug 1996 01:20:13 +0000 (01:20 +0000)
elf/dl-load.c
elf/dl-lookup.c
elf/dl-reloc.c
elf/dl-runtime.c
elf/dl-symbol.c
elf/dlsym.c
elf/link.h
elf/rtld.c

index 8ccc838..6fd6a6c 100644 (file)
@@ -70,11 +70,25 @@ int _dl_zerofd = -1;
 size_t _dl_pagesize;
 
 
+/* Local version of `strdup' function.  */
+static inline char *
+local_strdup (const char *s)
+{
+  size_t len = strlen (s) + 1;
+  void *new = malloc (len);
+
+  if (new == NULL)
+    return NULL;
+
+  return (char *) memcpy (new, s, len);
+}
+
+
 /* Map in the shared object NAME, actually located in REALNAME, and already
    opened on FD.  */
 
 struct link_map *
-_dl_map_object_from_fd (const char *name, int fd, char *realname,
+_dl_map_object_from_fd (char *name, int fd, char *realname,
                        struct link_map *loader, int l_type)
 {
   struct link_map *l = NULL;
@@ -96,6 +110,7 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname,
            l->l_next->l_prev = l->l_prev;
          free (l);
        }
+      free (name);
       free (realname);
       _dl_signal_error (code, name, msg);
     }
@@ -142,6 +157,7 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname,
        /* The object is already loaded.
           Just bump its reference count and return it.  */
        __close (fd);
+       free (name);
        free (realname);
        ++l->l_opencount;
        return l;
@@ -524,11 +540,8 @@ _dl_map_object (struct link_map *loader, const char *name, int type)
              fd = __open (cached, O_RDONLY);
              if (fd != -1)
                {
-                 size_t cl = strlen (cached) + 1;
-                 realname = malloc (cl);
-                 if (realname)
-                   memcpy (realname, cached, cl);
-                 else
+                 realname = local_strdup (cached);
+                 if (realname == NULL)
                    {
                      __close (fd);
                      fd = -1;
@@ -548,11 +561,8 @@ _dl_map_object (struct link_map *loader, const char *name, int type)
       fd = __open (name, O_RDONLY);
       if (fd != -1)
        {
-         size_t len = strlen (name) + 1;
-         realname = malloc (len);
-         if (realname)
-           memcpy (realname, name, len);
-         else
+         realname = local_strdup (name);
+         if (realname == NULL)
            {
              __close (fd);
              fd = -1;
@@ -560,6 +570,16 @@ _dl_map_object (struct link_map *loader, const char *name, int type)
        }
     }
 
+  if (fd != -1)
+    {
+      name = local_strdup (name);
+      if (name == NULL)
+       {
+         __close (fd);
+         fd = -1;
+       }
+    }
+
   if (fd == -1)
     _dl_signal_error (errno, name, "cannot open shared object file");
 
index 44f91fc..e57887b 100644 (file)
@@ -45,16 +45,16 @@ _dl_elf_hash (const char *name)
 }
 
 /* Search loaded objects' symbol tables for a definition of the symbol
-   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.  */
+   UNDEF_NAME.  FLAGS is a set of flags.  If DL_LOOKUP_NOEXEC is set,
+   then don't search the executable for a definition; this used for
+   copy relocs.  If DL_LOOKUP_NOPLT is set, then a PLT entry cannot
+   satisfy the reference; some different binding must be found.  */
 
 ElfW(Addr)
 _dl_lookup_symbol (const char *undef_name, const ElfW(Sym) **ref,
                   struct link_map *symbol_scope[],
                   const char *reference_name,
-                  ElfW(Addr) reloc_addr,
-                  int noplt)
+                  int flags)
 {
   const unsigned long int hash = _dl_elf_hash (undef_name);
   struct
@@ -75,6 +75,10 @@ _dl_lookup_symbol (const char *undef_name, const ElfW(Sym) **ref,
 
        map = (*scope)->l_searchlist[i];
 
+       /* Don't search the executable when resolving a copy reloc.  */
+       if (flags & DL_LOOKUP_NOEXEC && map->l_type == lt_executable)
+         continue;
+
        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);
 
@@ -87,9 +91,8 @@ _dl_lookup_symbol (const char *undef_name, const ElfW(Sym) **ref,
            const ElfW(Sym) *sym = &symtab[symidx];
 
            if (sym->st_value == 0 || /* No value.  */
-               /* Cannot resolve to the location being filled in.  */
-               reloc_addr == map->l_addr + sym->st_value ||
-               (noplt && sym->st_shndx == SHN_UNDEF)) /* Reject PLT.  */
+               ((flags & DL_LOOKUP_NOPLT) != 0 /* Reject PLT entry.  */
+                && sym->st_shndx == SHN_UNDEF))
              continue;
 
            switch (ELFW(ST_TYPE) (sym->st_info))
index 5adf0f6..fa424a4 100644 (file)
@@ -57,9 +57,9 @@ _dl_relocate_object (struct link_map *l, struct link_map *scope[], int lazy)
       = ((void *) l->l_addr + 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, reloc_addr, noplt) \
+#define RESOLVE(ref, flags) \
     (_dl_lookup_symbol (strtab + (*ref)->st_name, ref, scope, \
-                       l->l_name, reloc_addr, noplt))
+                       l->l_name, flags))
 
 #include "dynamic-link.h"
     ELF_DYNAMIC_RELOCATE (l, lazy);
index 16e0379..4e7b529 100644 (file)
@@ -122,9 +122,9 @@ fixup (
 
   {
     /* This macro is used as a callback from the elf_machine_relplt code.  */
-#define RESOLVE(ref, reloc_addr, noplt) \
+#define RESOLVE(ref, flags) \
   (_dl_lookup_symbol (strtab + (*ref)->st_name, ref, scope, \
-                     l->l_name, reloc_addr, noplt))
+                     l->l_name, flags))
 #include "dynamic-link.h"
 
     /* Perform the specified relocation.  */
index 7977e69..04dd122 100644 (file)
@@ -28,6 +28,6 @@ _dl_symbol_value (struct link_map *map, const char *name)
   ElfW(Addr) loadbase;
   const ElfW(Sym) *ref = NULL;
   struct link_map *scope[2] = { map, NULL };
-  loadbase = _dl_lookup_symbol (name, &ref, scope, map->l_name, 0, 0);
+  loadbase = _dl_lookup_symbol (name, &ref, scope, map->l_name, 0);
   return loadbase + ref->st_value;
 }
index 256eba8..98e3629 100644 (file)
@@ -44,7 +44,7 @@ dlsym (void *handle, const char *name)
          scope = &(_dl_global_scope ?: _dl_default_scope)[2];
          owner = NULL;
        }
-      loadbase = _dl_lookup_symbol (name, &ref, scope, owner, 0, 0);
+      loadbase = _dl_lookup_symbol (name, &ref, scope, owner, 0);
     }
 
   return _dlerror_run (doit) ? NULL : (void *) (loadbase + ref->st_value);
index fa96613..a963700 100644 (file)
@@ -224,16 +224,18 @@ extern void _dl_close (struct link_map *map);
    null-terminated list of object scopes to search; each object's
    l_searchlist (i.e. the segment of the dependency tree starting at that
    object) is searched in turn.  REFERENCE_NAME should name the object
-   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.  */
+   containing the reference; it is used in error messages.  FLAGS is a
+   set of flags:  */
+#define DL_LOOKUP_NOEXEC 1     /* Don't search the executable for a
+                                  definition; this is used for copy
+                                  relocs. */
+#define DL_LOOKUP_NOPLT 2      /* The reference must not be resolved
+                                  to a PLT entry.  */
 extern ElfW(Addr) _dl_lookup_symbol (const char *undef,
                                     const ElfW(Sym) **sym,
                                     struct link_map *symbol_scope[],
                                     const char *reference_name,
-                                    ElfW(Addr) reloc_addr,
-                                    int noplt);
+                                    int flags);
 
 /* Look up symbol NAME in MAP's scope and return its run-time address.  */
 extern ElfW(Addr) _dl_symbol_value (struct link_map *map, const char *name);
index fe5d269..308c2f4 100644 (file)
@@ -62,7 +62,7 @@ _dl_start (void *arg)
   /* This #define produces dynamic linking inline functions for
      bootstrap relocation instead of general-purpose relocation.  */
 #define RTLD_BOOTSTRAP
-#define RESOLVE(sym, reloc_addr, noplt) bootstrap_map.l_addr
+#define RESOLVE(sym, flags) bootstrap_map.l_addr
 #include "dynamic-link.h"
 
   /* Figure out the run-time load address of the dynamic linker itself.  */
@@ -369,7 +369,7 @@ of this helper program; chances are you did not intend to run this program.\n",
            const ElfW(Sym) *ref = NULL;
            ElfW(Addr) loadbase = _dl_lookup_symbol (_dl_argv[i], &ref,
                                                     &_dl_default_scope[2],
-                                                    "argument", 0, 0);
+                                                    "argument", 0);
            char buf[20], *bp;
            buf[sizeof buf - 1] = '\0';
            bp = _itoa (ref->st_value, &buf[sizeof buf - 1], 16, 0);