]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Sat May 6 11:06:47 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
authorRoland McGrath <roland@gnu.org>
Mon, 8 May 1995 09:11:25 +0000 (09:11 +0000)
committerRoland McGrath <roland@gnu.org>
Mon, 8 May 1995 09:11:25 +0000 (09:11 +0000)
* Makeconfig (+gccwarn): Add -Winline.

* hurd/hurdsig.c (_hurd_internal_post_signal): If SS->context is
  set, avoid abort_rpcs, and use reply and intr ports saved in
  SS->context.
* sysdeps/mach/hurd/i386/trampoline.c: Don't set SS->intr_port
  from SS->context.  Don't clear SS->context.
* sysdeps/mach/hurd/i386/sigreturn.c: Don't set SS->intr_port when
  setting SS->context.  If msg_sig_post returns, re-lock and clear
  SS->context.

Fri May  5 10:37:09 1995  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>

* mach/Makefile (errsystems.c): Comment out generation rule.

* sysdeps/mach/_strerror.c: Consider a system unknown if its
  bad_sub member is null.

* mach/mig-alloc.c: Add weak alias to non-__ name.

22 files changed:
ChangeLog
Makeconfig
elf/dl-error.c
elf/dl-load.c
elf/dl-lookup.c
elf/dl-object.c
elf/dl-reloc.c
elf/dlclose.c
elf/dlerror.c
elf/dlsym.c
elf/do-rel.h [new file with mode: 0644]
elf/dynamic-link.h
elf/link.h
elf/rtld.c
hurd/hurdsig.c
mach/Makefile
sysdeps/i386/dl-machine.h
sysdeps/i386/dl-runtime.c
sysdeps/mach/_strerror.c
sysdeps/mach/hurd/getdtsz.c
sysdeps/mach/hurd/i386/sigreturn.c
sysdeps/mach/hurd/i386/trampoline.c

index 2bf9c5aa2dded5e57f7a455e879ea5440f105e02..609e65c4b62edf7b9c4564d199bff3482d253225 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+Sat May  6 11:06:47 1995  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>
+
+       * Makeconfig (+gccwarn): Add -Winline.
+
+       * hurd/hurdsig.c (_hurd_internal_post_signal): If SS->context is
+       set, avoid abort_rpcs, and use reply and intr ports saved in
+       SS->context.
+       * sysdeps/mach/hurd/i386/trampoline.c: Don't set SS->intr_port
+       from SS->context.  Don't clear SS->context.
+       * sysdeps/mach/hurd/i386/sigreturn.c: Don't set SS->intr_port when
+       setting SS->context.  If msg_sig_post returns, re-lock and clear
+       SS->context.
+
+Fri May  5 10:37:09 1995  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>
+
+       * mach/Makefile (errsystems.c): Comment out generation rule.
+
+       * sysdeps/mach/_strerror.c: Consider a system unknown if its
+       bad_sub member is null.
+
+       * mach/mig-alloc.c: Add weak alias to non-__ name.
+
 Wed May  3 11:56:35 1995  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>
 
        * sysdeps/mach/hurd/dup2.c: Fixed broken test in last change.
index 823b7f44f1b57762db2d2b07c3a312a6862da582..cb3c065ddc928075c7c14695720e0571f94a678b 100644 (file)
@@ -272,7 +272,7 @@ RANLIB = ranlib
 endif
 
 # Extra flags to pass to GCC.
-+gccwarn := -Wall -Wwrite-strings -Wno-parentheses
++gccwarn := -Wall -Wwrite-strings -Wno-parentheses -Winline
 
 # This is the program that generates makefile
 # dependencies from C source files.
index b9ee3516b52ecc7c6ad3d500dfd07ffd53e46d73..5f8e4e40880245d1771603810af355fc9b8f83f8 100644 (file)
@@ -22,23 +22,28 @@ Cambridge, MA 02139, USA.  */
 #include <setjmp.h>
 
 static jmp_buf catch_env;
-static const char *signalled_errstring;
+static const char *signalled_errstring, *signalled_objname;
 
 void
-_dl_signal_error (int errcode, const char *errstring)
+_dl_signal_error (int errcode,
+                 const char *objname,
+                 const char *errstring)
 {
   signalled_errstring = errstring ?: "DYNAMIC LINKER BUG!!!";
   longjmp (catch_env, errcode ?: -1);
 }
 
 int
-_dl_catch_error (const char **errstring, void (*operate) (void))
+_dl_catch_error (const char **errstring,
+                const char **objname,
+                void (*operate) (void))
 {
   int errcode;
 
-  signalled_errstring = NULL;
+  signalled_errstring = signalled_objname = NULL;
   errcode = setjmp (catch_env);
   (*operate) ();
   *errstring = signalled_errstring;
+  *objname = signalled_objname;
   return *errstring ? errcode : 0;
 }
index 0de7404a80f8ff883d0c08b78d8c47eceed9a7c7..f8b37ba34672e92ac73c097a6e095d171cd5e0b5 100644 (file)
@@ -107,10 +107,20 @@ _dl_map_object (struct link_map *loader, const char *name,
                Elf32_Addr *entry_point)
 {
   int fd;
+  struct link_map *l = NULL;
   char *realname;
   const size_t pagesize = getpagesize ();
   void *file_mapping = NULL;
   size_t mapping_size = 0;
+
+  void lose (int code, const char *msg)
+    {
+      (void) close (fd);
+      if (file_mapping)
+       munmap (file_mapping, mapping_size);
+      _dl_signal_error (code, l ? l->l_name : name, msg);
+    }
+
   /* Make sure LOCATION is mapped in.  */
   void *map (off_t location, size_t size)
     {
@@ -124,14 +134,13 @@ _dl_map_object (struct link_map *loader, const char *name,
          result = mmap (file_mapping, mapping_size, PROT_READ,
                         MAP_COPY|MAP_FILE, fd, 0);
          if (result == (void *) -1)
-           return NULL;
+           lose (errno, "cannot map file data");
          file_mapping = result;
        }
       return file_mapping + location;
     }
 
   const Elf32_Ehdr *header;
-  struct link_map *l;
 
   /* Look for this name among those already loaded.  */
   for (l = _dl_loaded; l; l = l->l_next)
@@ -170,7 +179,7 @@ _dl_map_object (struct link_map *loader, const char *name,
     }
 
   if (fd == -1)
-    return NULL;
+    lose (errno, "cannot open shared object file");
 
   /* Look again to see if the real name matched another already loaded.  */
   for (l = _dl_loaded; l; l = l->l_next)
@@ -186,17 +195,9 @@ _dl_map_object (struct link_map *loader, const char *name,
 
   /* Map in the first page to read the header.  */
   header = map (0, sizeof *header);
-  if (! header)
-    {
-    lose:
-      (void) close (fd);
-      if (file_mapping)
-       munmap (file_mapping, mapping_size);
-      return NULL;
-    }
 
 #undef LOSE
-#define LOSE(s) _dl_signal_error (0, s)
+#define LOSE(s) lose (0, (s))
   /* Check the header for basic validity.  */
   if (*(Elf32_Word *) &header->e_ident != ((ELFMAG0 << (EI_MAG0 * 8)) |
                                           (ELFMAG1 << (EI_MAG1 * 8)) |
@@ -224,7 +225,7 @@ _dl_map_object (struct link_map *loader, const char *name,
     {
       _dl_zerofd = _dl_sysdep_open_zero_fill ();
       if (_dl_zerofd == -1)
-       _dl_signal_error (errno, "cannot open zero fill device");
+       _dl_signal_error (errno, NULL, "cannot open zero fill device");
     }
 
   {
@@ -235,8 +236,6 @@ _dl_map_object (struct link_map *loader, const char *name,
     int anywhere;
 
     ph = map (header->e_phoff, header->e_phnum * sizeof (Elf32_Phdr));
-    if (! ph)
-      goto lose;
     memcpy (phdr, ph, sizeof phdr);
     l->l_phnum = header->e_phnum;
 
@@ -288,7 +287,8 @@ _dl_map_object (struct link_map *loader, const char *name,
              {
                /* XXX this loses if the first segment mmap call puts
                   it someplace where the later segments cannot fit.  */
-               mapat = mmap ((caddr_t) l->l_addr + mapstart, mapend - mapstart,
+               mapat = mmap ((caddr_t) (l->l_addr + mapstart),
+                             mapend - mapstart,
                              prot, MAP_COPY|MAP_FILE|MAP_INHERIT |
                              /* Let the system choose any convenient
                                 location if this is the first segment.
@@ -312,8 +312,7 @@ _dl_map_object (struct link_map *loader, const char *name,
                l->l_addr = 0;
              }
            if (mapat == (caddr_t) -1)
-             _dl_signal_error (errno,
-                               "failed to map region from shared object");
+             lose (errno, "failed to map segment from shared object");
 
            if (ph->p_memsz > ph->p_filesz)
              {
@@ -341,8 +340,7 @@ _dl_map_object (struct link_map *loader, const char *name,
                                                 & ~(pagesize - 1)),
                                      pagesize,
                                      prot|PROT_WRITE) < 0)
-                         _dl_signal_error (errno,
-                                           "cannot change protections");
+                         lose (errno, "cannot change memory protections");
                      }
                    memset (zero, 0, zeroend - zero);
                    if ((prot & PROT_WRITE) == 0)
index b4600b19709a78557d71302ca5eeb5287206e1b1..a7afcc79bbe098fb4d58e600a516c5697dc0173a 100644 (file)
@@ -27,7 +27,8 @@ Cambridge, MA 02139, USA.  */
 
 Elf32_Addr
 _dl_lookup_symbol (const char *undef_name, const Elf32_Sym **ref,
-                  struct link_map *symbol_scope)
+                  struct link_map *symbol_scope,
+                  const char *reference_name)
 {
   unsigned long int hash = elf_hash (undef_name);
   struct link_map *map;
@@ -106,7 +107,7 @@ _dl_lookup_symbol (const char *undef_name, const Elf32_Sym **ref,
       char buf[sizeof msg + strlen (undef_name)];
       memcpy (buf, msg, sizeof msg - 1);
       memcpy (&buf[sizeof msg - 1], undef_name, sizeof buf - sizeof msg);
-      _dl_signal_error (0, msg);
+      _dl_signal_error (0, reference_name, msg);
     }
 
   *ref = weak_value.s;
index e7b1ce3f45cc2b066bba9420a5bff2a535fbe1ba..ca4e785be308a8e0043c6a7187381808e5390df2 100644 (file)
@@ -37,7 +37,8 @@ _dl_new_object (char *realname, const char *libname, int type)
 {
   struct link_map *new = malloc (sizeof *new);
   if (! new)
-    _dl_signal_error (ENOMEM, "can't open new object");
+    _dl_signal_error (ENOMEM, libname,
+                     "cannot allocate shared object descriptor");
 
   memset (new, 0, sizeof *new);
   new->l_name = realname;
index 8efb3f04a608a22d4a0388687bf557912506c373..94ffb7175978e11b1527a02bca969f432528de99 100644 (file)
@@ -48,7 +48,7 @@ _dl_relocate_object (struct link_map *l, int lazy)
                               & ~(pagesize - 1)));
            if (mprotect (mapstart, mapend - mapstart,
                          PROT_READ|PROT_WRITE) < 0)
-             _dl_signal_error (errno,
+             _dl_signal_error (errno, l->l_name,
                                "cannot make segment writable for relocation");
          }
     }
@@ -62,7 +62,8 @@ _dl_relocate_object (struct link_map *l, int lazy)
 
     Elf32_Addr resolve (const Elf32_Sym **ref)
       {
-       return _dl_lookup_symbol (strtab + (*ref)->st_name, ref, scope);
+       return _dl_lookup_symbol (strtab + (*ref)->st_name, ref, scope,
+                                 l->l_name);
       }
 
     real_next = l->l_next;
@@ -75,7 +76,7 @@ _dl_relocate_object (struct link_map *l, int lazy)
     else
       scope = _dl_loaded;
 
-    elf_dynamic_relocate (l->l_info, l->l_addr, lazy, resolve);
+    ELF_DYNAMIC_RELOCATE (l, lazy, resolve);
 
     /* Restore list frobnication done above for DT_SYMBOLIC.  */
     l->l_next = real_next;
@@ -107,7 +108,7 @@ _dl_relocate_object (struct link_map *l, int lazy)
            if (ph->p_flags & PF_X)
              prot |= PROT_EXEC;
            if (mprotect (mapstart, mapend - mapstart, prot) < 0)
-             _dl_signal_error (errno,
+             _dl_signal_error (errno, l->l_name,
                                "can't restore segment prot after reloc");
          }
     }
index 4aa4085f664157c2ed1f274e7c777a660295cf13..06b2d1bdcdc828cb3d4cbc2a1cd37fe024085248 100644 (file)
@@ -24,7 +24,7 @@ Cambridge, MA 02139, USA.  */
 #include <sys/mman.h>
 
 
-#define LOSE(s) _dl_signal_error (0, s)
+#define LOSE(s) _dl_signal_error (0, map->l_name, s)
 
 int
 dlclose (void *handle)
index 0eed60a45d2ad4bba8b87a3d59aff6a5b6c99e77..4ec5037de487c95fa28d0fd5c23fa31b21aade38 100644 (file)
@@ -23,42 +23,49 @@ Cambridge, MA 02139, USA.  */
 #include <string.h>
 #include <stdlib.h>
 
-static int _dl_last_errcode;
-static const char *_dl_last_errstring;
+static int last_errcode;
+static const char *last_errstring;
+static const char *last_object_name;
 
 char *
 dlerror (void)
 {
- char *ret;
+  static char *buf;
+  char *ret;
 
-  if (! _dl_last_errstring)
-    return NULL;
-
-  if (_dl_last_errcode)
+  if (buf)
     {
-      static char *buf;
-      if (buf)
-       {
-         free (buf);
-         buf = NULL;
-       }
-      if (asprintf (&buf, "%s: %s",
-                   _dl_last_errstring, strerror (_dl_last_errcode)) == -1)
-       return NULL;
-      else
-       ret = buf;
+      free (buf);
+      buf = NULL;
     }
- else
-   ret = (char *) _dl_last_errstring;
 
- /* Reset the error indicator.  */
- _dl_last_errstring = NULL;
- return ret;
+  if (! last_errstring)
+    return NULL;
+
+  if (last_errcode == 0 && ! last_object_name)
+    ret = (char *) last_errstring;
+  else if (last_errcode == 0)
+    ret = (asprintf (&buf, "%s: %s", last_object_name, last_errstring) == -1
+          ? NULL : buf);
+  else if (! last_object_name)
+    ret = (asprintf (&buf, "%s: %s",
+                    last_errstring, strerror (last_errcode)) == -1
+          ? NULL : buf);
+  else
+    ret = (asprintf (&buf, "%s: %s: %s",
+                    last_object_name, last_errstring,
+                    strerror (last_errcode)) == -1
+          ? NULL : buf);
+
+  /* Reset the error indicator.  */
+  last_errstring = NULL;
+  return ret;
 }
 
 int
 _dlerror_run (void (*operate) (void))
 {
-  _dl_last_errcode = _dl_catch_error (&_dl_last_errstring, operate);
-  return _dl_last_errstring != NULL;
+  last_errcode = _dl_catch_error (&last_errstring, &last_object_name,
+                                 operate);
+  return last_errstring != NULL;
 }
index 6d8781053b995ccc77201b680c63a05d27b70750..3e10812da8454bd84571b4e064d3bcbe332f28a4 100644 (file)
@@ -33,7 +33,7 @@ dlsym (void *handle, const char *name)
   void doit (void)
     {
       const Elf32_Sym *ref = NULL;
-      value = _dl_lookup_symbol (name, &ref, map);
+      value = _dl_lookup_symbol (name, map->l_name, &ref, map);
     }
 
   /* Confine the symbol scope to just this map.  */
diff --git a/elf/do-rel.h b/elf/do-rel.h
new file mode 100644 (file)
index 0000000..04643e8
--- /dev/null
@@ -0,0 +1,68 @@
+/* Do relocations for ELF dynamic linking.
+Copyright (C) 1995 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
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+/* This file may be included twice, to define both
+   `elf_dynamic_do_rel' and `elf_dynamic_do_rela'.  */
+
+#ifdef DO_RELA
+#define elf_dynamic_do_rel     elf_dynamic_do_rela
+#define        Elf32_Rel               Elf32_Rela
+#define elf_machine_rel                elf_machine_rela
+#endif
+
+
+/* Perform the relocations in MAP on the running program image as specified
+   by RELTAG, SZTAG.  *RESOLVE is called to resolve symbol values; it
+   modifies its argument pointer to point to the defining symbol, and
+   returns the base load address of the defining object.  */
+
+static inline void
+elf_dynamic_do_rel (struct link_map *map,
+                   int reltag, int sztag, 
+                   Elf32_Addr (*resolve) (const Elf32_Sym **))
+{
+  const Elf32_Sym *const symtab
+    = (const Elf32_Sym *) map->l_info[DT_SYMTAB]->d_un.d_ptr;
+  const Elf32_Rel *r = (const Elf32_Rel *) map->l_info[reltag]->d_un.d_ptr;
+  const Elf32_Rel *end = &r[map->l_info[sztag]->d_un.d_val / sizeof *r];
+
+  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 (resolve)
+           loadbase = (*resolve) (&definer);
+         else
+           {
+             assert (definer->st_shndx != SHN_UNDEF);
+             loadbase = map->l_addr;
+           }
+       }
+      elf_machine_rel (map, r, loadbase, definer);
+    }
+}
+
+#undef elf_dynamic_do_rel
+#undef Elf32_Rel
+#undef elf_machine_rel
index 1c3af29d6a09527acca308592c512f5628492273..fc5c585356d776d5e57e0a047c11b5a0e63ed20e 100644 (file)
@@ -18,23 +18,10 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
 #include <elf.h>
-
-/* This machine-dependent file defines these inline functions.  */
-
-static void elf_machine_rel (Elf32_Addr loadaddr, Elf32_Dyn *info[DT_NUM],
-                            const Elf32_Rel *reloc, 
-                            Elf32_Addr sym_loadaddr, const Elf32_Sym *sym);
-static void elf_machine_rela (Elf32_Addr loadaddr, Elf32_Dyn *info[DT_NUM],
-                             const Elf32_Rela *reloc, 
-                             Elf32_Addr sym_loadaddr, const Elf32_Sym *sym);
-static Elf32_Addr *elf_machine_got (void);
-static Elf32_Addr elf_machine_load_address (void);
-
 #include <dl-machine.h>
-
-
 #include <assert.h>
 
+
 /* Read the dynamic section at DYN and fill in INFO with indices DT_*.  */
 
 static inline void
@@ -60,60 +47,36 @@ elf_get_dynamic_info (Elf32_Dyn *dyn, Elf32_Dyn *info[DT_NUM])
            info[DT_PLTREL]->d_un.d_val == DT_RELA);
 }
 
-/* Perform the relocations specified by DYNAMIC on the running program
-   image.  If LAZY is nonzero, don't relocate PLT entries.  *RESOLVE is
-   called to resolve symbol values; it modifies its argument pointer to
-   point to the defining symbol, and returns the base load address of the
-   defining object.  */
-
-static inline void
-elf_dynamic_relocate (Elf32_Dyn *dynamic[DT_NUM], Elf32_Addr loadaddr,
-                     int lazy, Elf32_Addr (*resolve) (const Elf32_Sym **))
-{
-  const Elf32_Sym *const symtab
-    = (const Elf32_Sym *) dynamic[DT_SYMTAB]->d_un.d_ptr;
-
-  inline Elf32_Addr symvalue (Elf32_Word info, const Elf32_Sym **definer)
-    {
-      if (ELF32_R_SYM (info) == STN_UNDEF)
-       return 0;               /* This value will not be consulted.  */
-      *definer = &symtab[ELF32_R_SYM (info)];
-      return (*resolve) (definer);
-    }
-
-  /* Perform Elf32_Rel relocations in the section found by RELTAG, SZTAG.  */
-  inline void do_rel (Elf32_Word reltag, Elf32_Word sztag)
-    {
-      const Elf32_Rel *r = (const Elf32_Rel *) dynamic[reltag]->d_un.d_ptr;
-      const Elf32_Rel *end = &r[dynamic[sztag]->d_un.d_val / sizeof *r];
-      while (r < end)
-       {
-         const Elf32_Sym *definer;
-         Elf32_Addr loadbase = symvalue (r->r_info, &definer);
-         elf_machine_rel (loadaddr, dynamic, r, loadbase, definer);
-         ++r;
-       }
-    }
-  /* Perform Elf32_Rela relocations in the section found by RELTAG, SZTAG.  */
-  inline void do_rela (Elf32_Word reltag, Elf32_Word sztag)
-    {
-      const Elf32_Rela *r = (const Elf32_Rela *) dynamic[reltag]->d_un.d_ptr;
-      const Elf32_Rela *end = &r[dynamic[sztag]->d_un.d_val / sizeof *r];
-      while (r < end)
-       {
-         const Elf32_Sym *definer;
-         Elf32_Addr loadbase = symvalue (r->r_info, &definer);
-         elf_machine_rela (loadaddr, dynamic, r, loadbase, definer);
-         ++r;
-       }
-    }
-
-  if (dynamic[DT_RELA])
-    do_rela (DT_RELA, DT_RELASZ);
-  if (dynamic[DT_REL])
-    do_rel (DT_REL, DT_RELSZ);
-  if (dynamic[DT_JMPREL] && ! lazy)
-    /* Relocate the PLT right now.  */
-    (dynamic[DT_PLTREL]->d_un.d_val == DT_REL ? do_rel : do_rela)
-      (DT_JMPREL, DT_PLTRELSZ);
-}
+/* Get the definitions of `elf_dynamic_do_rel' and `elf_dynamic_do_rela'.
+   These functions are almost identical, so we use cpp magic to avoid
+   duplicating their code.  It cannot be done in a more general function
+   because we must be able to completely inline.  */
+
+#if ! ELF_MACHINE_NO_REL
+#include "do-rel.h"
+#define ELF_DYNAMIC_DO_REL(map, lazy, resolve)                               \
+  if ((map)->l_info[DT_REL])                                                 \
+    elf_dynamic_do_rel ((map), DT_REL, DT_RELSZ, (resolve));                 \
+  if (!(lazy) && (map)->l_info[DT_PLTREL]->d_un.d_val == DT_REL)             \
+    elf_dynamic_do_rel ((map), DT_JMPREL, DT_PLTRELSZ, (resolve));
+#else
+#define ELF_DYNAMIC_DO_RELA(map, lazy, resolve) /* Nothing to do.  */
+#endif
+
+#if ! ELF_MACHINE_NO_RELA
+#define DO_RELA
+#include "do-rel.h"
+#define ELF_DYNAMIC_DO_RELA(map, lazy, resolve)                                      \
+  if ((map)->l_info[DT_RELA])                                                \
+    elf_dynamic_do_rela ((map), DT_RELA, DT_RELASZ, (resolve));                      \
+  if (!(lazy) && (map)->l_info[DT_PLTREL]->d_un.d_val == DT_RELA)            \
+    elf_dynamic_do_rela ((map), DT_JMPREL, DT_PLTRELSZ, (resolve);
+#else
+#define ELF_DYNAMIC_DO_RELA(map, lazy, resolve) /* 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, resolve) \
+  do { ELF_DYNAMIC_DO_REL ((map), (lazy), (resolve)); \
+       ELF_DYNAMIC_DO_RELA ((map), (lazy), (resolve)); } while (0)
index 7b999dc532d200575cbd73d31fef7e19281f13e0..66de6d97d7b8c998a4dc69b980c17d99afb03c0c 100644 (file)
@@ -131,17 +131,23 @@ extern void _dl_sysdep_fatal (const char *string, ...)
 extern int _dl_secure;
 
 /* This function is called by all the internal dynamic linker functions
-   when they encounter an error.  ERRCODE is either an `errno' code
-   or zero; ERRSTRING is a string describing the specific problem.  */
+   when they encounter an error.  ERRCODE is either an `errno' code or
+   zero; OBJECT is the name of the problematical shared object, or null if
+   it is a general problem; ERRSTRING is a string describing the specific
+   problem.  */
    
-extern void _dl_signal_error (int errcode, const char *errstring)
+extern void _dl_signal_error (int errcode,
+                             const char *object,
+                             const char *errstring)
      __attribute__ ((__noreturn__));
 
 /* Call OPERATE, catching errors from `dl_signal_error'.  If there is no
-   error, *ERRSTRING is set to null.  If there is an error, *ERRSTRING is
-   set to the string passed to _dl_signal_error, and the error code passed
-   is the return value.  */
-extern int _dl_catch_error (const char **errstring, void (*operate) (void));
+   error, *ERRSTRING is set to null.  If there is an error, *ERRSTRING and
+   *OBJECT are set to the strings passed to _dl_signal_error, and the error
+   code passed is the return value.  */
+extern int _dl_catch_error (const char **errstring,
+                           const char **object,
+                           void (*operate) (void));
 
 
 /* Helper function for <dlfcn.h> functions.  Runs the OPERATE function via
@@ -166,10 +172,12 @@ extern void _dl_setup_hash (struct link_map *map);
    referred to by UNDEF.  *SYM is the symbol table entry containing the
    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.  */
+   the chain used for searching.  REFERENCE_NAME should name the object
+   containing the reference; it is used in error messages.  */
 extern Elf32_Addr _dl_lookup_symbol (const char *undef,
                                     const Elf32_Sym **sym,
-                                    struct link_map *symbol_scope);
+                                    struct link_map *symbol_scope,
+                                    const char *reference_name);
 
 
 /* List of objects currently loaded.  */
index fd75779a010c50a37f62747aae9d18e3a41356d8..0605336603616b7c449fb2a7e5416c9576a12524 100644 (file)
@@ -52,40 +52,33 @@ static void dl_main (const Elf32_Phdr *phdr,
 Elf32_Addr
 _dl_start (void *arg)
 {
-  Elf32_Addr rtld_loadaddr;
-  Elf32_Dyn *dynamic_section;
-  Elf32_Dyn *dynamic_info[DT_NUM];
+  struct link_map rtld_map;
 
   /* Figure out the run-time load address of the dynamic linker itself.  */
-  rtld_loadaddr = elf_machine_load_address ();
+  rtld_map.l_addr = elf_machine_load_address ();
 
   /* Read our own dynamic section and fill in the info array.
      Conveniently, the first element of the GOT contains the
      offset of _DYNAMIC relative to the run-time load address.  */
-  dynamic_section = (void *) rtld_loadaddr + *elf_machine_got ();
-  elf_get_dynamic_info (dynamic_section, dynamic_info);
+  rtld_map.l_ld = (void *) rtld_map.l_addr + *elf_machine_got ();
+  elf_get_dynamic_info (rtld_map.l_ld, rtld_map.l_info);
 
 #ifdef ELF_MACHINE_BEFORE_RTLD_RELOC
-  ELF_MACHINE_BEFORE_RTLD_RELOC (dynamic_info);
+  ELF_MACHINE_BEFORE_RTLD_RELOC (rtld_map.l_info);
 #endif
 
   /* Relocate ourselves so we can do normal function calls and
      data access using the global offset table.  */
-  {
-    Elf32_Addr resolve (const Elf32_Sym **ref)
-      {
-       assert ((*ref)->st_shndx != SHN_UNDEF);
-       return rtld_loadaddr;
-      }
-    elf_dynamic_relocate (dynamic_info, rtld_loadaddr, 0, resolve);
-  }
+
+  ELF_DYNAMIC_RELOCATE (&rtld_map, 0, NULL);
+
 
   /* Now life is sane; we can call functions and access global data.
      Set up to use the operating system facilities, and find out from
      the operating system's program loader where to find the program
      header table in core.  */
 
-  dl_r_debug.r_ldbase = rtld_loadaddr; /* Record our load address.  */
+  dl_r_debug.r_ldbase = rtld_map.l_addr; /* Record our load address.  */
 
   /* Call the OS-dependent function to set up life so we can do things like
      file access.  It will call `dl_main' (below) to do all the real work
@@ -107,29 +100,30 @@ dl_main (const Elf32_Phdr *phdr,
 {
   void doit (void)
     {
-  const Elf32_Phdr *ph;
-  struct link_map *l;
-  const char *interpreter_name;
-  int lazy;
+      const Elf32_Phdr *ph;
+      struct link_map *l;
+      const char *interpreter_name;
+      int lazy;
 
-  if (*user_entry == (Elf32_Addr) &_start)
-    {
-      /* Ho ho.  We are not the program interpreter!  We are the program
-        itself!  This means someone ran ld.so as a command.  Well, that
-        might be convenient to do sometimes.  We support it by
-        interpreting the args like this:
-
-        ld.so PROGRAM ARGS...
-        
-        The first argument is the name of a file containing an ELF
-        executable we will load and run with the following arguments.  To
-        simplify life here, PROGRAM is searched for using the normal rules
-        for shared objects, rather than $PATH or anything like that.  We
-        just load it and use its entry point; we don't pay attention to
-        its PT_INTERP command (we are the interpreter ourselves).  This is
-        an easy way to test a new ld.so before installing it.  */
-      if (_dl_argc < 2)
-       _dl_sysdep_fatal ("\
+      if (*user_entry == (Elf32_Addr) &_start)
+       {
+         /* Ho ho.  We are not the program interpreter!  We are the program
+            itself!  This means someone ran ld.so as a command.  Well, that
+            might be convenient to do sometimes.  We support it by
+            interpreting the args like this:
+            
+            ld.so PROGRAM ARGS...
+            
+            The first argument is the name of a file containing an ELF
+            executable we will load and run with the following arguments.
+            To simplify life here, PROGRAM is searched for using the
+            normal rules for shared objects, rather than $PATH or anything
+            like that.  We just load it and use its entry point; we don't
+            pay attention to its PT_INTERP command (we are the interpreter
+            ourselves).  This is an easy way to test a new ld.so before
+            installing it.  */
+         if (_dl_argc < 2)
+           _dl_sysdep_fatal ("\
 Usage: ld.so EXECUTABLE-FILE [ARGS-FOR-PROGRAM...]\n\
 You have invoked `ld.so', the helper program for shared library executables.\n\
 This program usually lives in the file `/lib/ld.so', and special directives\n\
@@ -142,116 +136,118 @@ that file itself, but always uses this helper program from the file you\n\
 specified, instead of the helper program file specified in the executable\n\
 file you run.  This is mostly of use for maintainers to test new versions\n\
 of this helper program; chances are you did not intend to run this program.\n"
-                         );
-
-      interpreter_name = _dl_argv[0];
-      --_dl_argc;
-      ++_dl_argv;
-      l = _dl_map_object (NULL, _dl_argv[0], user_entry);
-      phdr = l->l_phdr;
-      phent = l->l_phnum;
-      l->l_type = lt_executable;
-      l->l_libname = (char *) "";
-    }
-  else
-    {
-      /* Create a link_map for the executable itself.
-        This will be what dlopen on "" returns.  */
-      l = _dl_new_object ((char *) "", "", lt_executable);
-      l->l_phdr = phdr;
-      l->l_phnum = phent;
-      interpreter_name = 0;
-    }
+                             );
+
+         interpreter_name = _dl_argv[0];
+         --_dl_argc;
+         ++_dl_argv;
+         l = _dl_map_object (NULL, _dl_argv[0], user_entry);
+         phdr = l->l_phdr;
+         phent = l->l_phnum;
+         l->l_type = lt_executable;
+         l->l_libname = (char *) "";
+       }
+      else
+       {
+         /* Create a link_map for the executable itself.
+            This will be what dlopen on "" returns.  */
+         l = _dl_new_object ((char *) "", "", lt_executable);
+         l->l_phdr = phdr;
+         l->l_phnum = phent;
+         interpreter_name = 0;
+       }
 
-  /* Scan the program header table for the dynamic section.  */
-  for (ph = phdr; ph < &phdr[phent]; ++ph)
-    switch (ph->p_type)
-      {
-      case PT_DYNAMIC:
-       /* This tells us where to find the dynamic section,
-          which tells us everything we need to do.  */
-       l->l_ld = (void *) ph->p_vaddr;
-       break;
-      case PT_INTERP:
-       /* This "interpreter segment" was used by the program loader to
-          find the program interpreter, which is this program itself, the
-          dynamic linker.  We note what name finds us, so that a future
-          dlopen call or DT_NEEDED entry, for something that wants to link
-          against the dynamic linker as a shared library, will know that
-          the shared object is already loaded.  */
-       interpreter_name = (void *) ph->p_vaddr;
-       break;
-      }
-  assert (interpreter_name);   /* How else did we get here?  */
-
-  /* Extract the contents of the dynamic section for easy access.  */
-  elf_get_dynamic_info (l->l_ld, l->l_info);
-  /* Set up our cache of pointers into the hash table.  */
-  _dl_setup_hash (l);
-
-  if (l->l_info[DT_DEBUG])
-    /* There is a DT_DEBUG entry in the dynamic section.  Fill it in
-       with the run-time address of the r_debug structure, which we
-       will set up later to communicate with the debugger.  */
-    l->l_info[DT_DEBUG]->d_un.d_ptr = (Elf32_Addr) &dl_r_debug;
-
-  l = _dl_new_object ((char *) interpreter_name, interpreter_name,
-                     lt_interpreter);
-
-  /* Now process all the DT_NEEDED entries and map in the objects.
-     Each new link_map will go on the end of the chain, so we will
-     come across it later in the loop to map in its dependencies.  */
-  for (l = _dl_loaded; l; l = l->l_next)
-    {
-      if (l->l_info[DT_NEEDED])
+      /* Scan the program header table for the dynamic section.  */
+      for (ph = phdr; ph < &phdr[phent]; ++ph)
+       switch (ph->p_type)
+         {
+         case PT_DYNAMIC:
+           /* This tells us where to find the dynamic section,
+              which tells us everything we need to do.  */
+           l->l_ld = (void *) ph->p_vaddr;
+           break;
+         case PT_INTERP:
+           /* This "interpreter segment" was used by the program loader to
+              find the program interpreter, which is this program itself, the
+              dynamic linker.  We note what name finds us, so that a future
+              dlopen call or DT_NEEDED entry, for something that wants to link
+              against the dynamic linker as a shared library, will know that
+              the shared object is already loaded.  */
+           interpreter_name = (void *) ph->p_vaddr;
+           break;
+         }
+      assert (interpreter_name); /* How else did we get here?  */
+
+      /* Extract the contents of the dynamic section for easy access.  */
+      elf_get_dynamic_info (l->l_ld, l->l_info);
+      /* Set up our cache of pointers into the hash table.  */
+      _dl_setup_hash (l);
+
+      if (l->l_info[DT_DEBUG])
+       /* There is a DT_DEBUG entry in the dynamic section.  Fill it in
+          with the run-time address of the r_debug structure, which we
+          will set up later to communicate with the debugger.  */
+       l->l_info[DT_DEBUG]->d_un.d_ptr = (Elf32_Addr) &dl_r_debug;
+
+      l = _dl_new_object ((char *) interpreter_name, interpreter_name,
+                         lt_interpreter);
+
+      /* Now process all the DT_NEEDED entries and map in the objects.
+        Each new link_map will go on the end of the chain, so we will
+        come across it later in the loop to map in its dependencies.  */
+      for (l = _dl_loaded; l; l = l->l_next)
        {
-         const char *strtab
-           = (void *) l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr;
-         const Elf32_Dyn *d;
-         for (d = l->l_ld; d->d_tag != DT_NULL; ++d)
-           if (d->d_tag == DT_NEEDED)
-             _dl_map_object (l, strtab + d->d_un.d_val, NULL);
+         if (l->l_info[DT_NEEDED])
+           {
+             const char *strtab
+               = (void *) l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr;
+             const Elf32_Dyn *d;
+             for (d = l->l_ld; d->d_tag != DT_NULL; ++d)
+               if (d->d_tag == DT_NEEDED)
+                 _dl_map_object (l, strtab + d->d_un.d_val, NULL);
+           }
+         l->l_deps_loaded = 1;
        }
-      l->l_deps_loaded = 1;
-    }
 
-  l = _dl_loaded->l_next;
-  assert (l->l_type == lt_interpreter);
-  if (l->l_opencount == 0)
-    {
-      /* No DT_NEEDED entry referred to the interpreter object itself.
-        Remove it from the maps we will use for symbol resolution.  */
-      l->l_prev->l_next = l->l_next;
-      if (l->l_next)
-       l->l_next->l_prev = l->l_prev;
-    }
+      l = _dl_loaded->l_next;
+      assert (l->l_type == lt_interpreter);
+      if (l->l_opencount == 0)
+       {
+         /* No DT_NEEDED entry referred to the interpreter object itself.
+            Remove it from the maps we will use for symbol resolution.  */
+         l->l_prev->l_next = l->l_next;
+         if (l->l_next)
+           l->l_next->l_prev = l->l_prev;
+       }
 
-  lazy = _dl_secure || *(getenv ("LD_BIND_NOW") ?: "");
+      lazy = _dl_secure || *(getenv ("LD_BIND_NOW") ?: "");
 
-  /* Now we have all the objects loaded.  Relocate them all.
-     We do this in reverse order so that copy relocs of earlier
-     objects overwrite the data written by later objects.  */
-  l = _dl_loaded;
-  while (l->l_next)
-    l = l->l_next;
-  do
-    {
-      _dl_relocate_object (l, lazy);
-      l = l->l_prev;
-    } while (l);
-
-  /* Tell the debugger where to find the map of loaded objects.  */
-  dl_r_debug.r_version = 1 /* R_DEBUG_VERSION XXX */;
-  dl_r_debug.r_map = _dl_loaded;
-  dl_r_debug.r_brk = (Elf32_Addr) &_dl_r_debug_state;
-}
+      /* Now we have all the objects loaded.  Relocate them all.
+        We do this in reverse order so that copy relocs of earlier
+        objects overwrite the data written by later objects.  */
+      l = _dl_loaded;
+      while (l->l_next)
+       l = l->l_next;
+      do
+       {
+         _dl_relocate_object (l, lazy);
+         l = l->l_prev;
+       } while (l);
+
+      /* Tell the debugger where to find the map of loaded objects.  */
+      dl_r_debug.r_version = 1 /* R_DEBUG_VERSION XXX */;
+      dl_r_debug.r_map = _dl_loaded;
+      dl_r_debug.r_brk = (Elf32_Addr) &_dl_r_debug_state;
+    }
   const char *errstring;
+  const char *errobj;
   int err;
 
-  err = _dl_catch_error (&errstring, &doit);
+  err = _dl_catch_error (&errstring, &errobj, &doit);
   if (errstring)
     _dl_sysdep_fatal (_dl_argv[0] ?: "<program name unknown>",
                      ": error in loading shared libraries\n",
+                     errobj ?: "", errobj ? ": " : "",
                      errstring, err ? ": " : NULL,
                      err ? strerror (err) : NULL, NULL);
 
index 9620a00ca43087cb013bc471e3f35d83d7eca1de..c5ce050c7a7c0ec14c9866c3e7b2c4af2b97b3f7 100644 (file)
@@ -667,9 +667,16 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
       /* Nobody cares about this signal.  */
       break;
 
+    sigbomb:
+      /* We got a fault setting up the stack frame for the handler.
+        Nothing to do but die; BSD gets SIGILL in this case.  */
+      sigcode = signo; /* XXX ? */
+      signo = SIGILL;
+      act = core;
+      /* FALLTHROUGH */
+
     case term:                 /* Time to die.  */
     case core:                 /* And leave a rotting corpse.  */
-    nirvana:
       /* Have the proc server stop all other threads in our task.  */
       err = __USEPORT (PROC, __proc_dostop (port, _hurd_msgport_thread));
       assert_perror (err);
@@ -693,7 +700,7 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
     case handle:
       /* Call a handler for this signal.  */
       {
-       struct sigcontext *scp;
+       struct sigcontext *scp, ocontext;
        int wait_for_reply, state_changed;
 
        /* Stop the thread and abort its pending RPC operations.  */
@@ -710,19 +717,64 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
           thread_get_state is never kosher before thread_abort.  */
        abort_thread (ss, &thread_state, NULL, 0, 0);
 
-       wait_for_reply = (abort_rpcs (ss, signo, &thread_state, &state_changed,
-                                     &reply_port, reply_port_type, untraced)
-                         != MACH_PORT_NULL);
+       if (ss->context)
+         {
+           /* We have a previous sigcontext that sigreturn was about
+              to restore when another signal arrived.  */
+
+           mach_port_t *loc;
 
-       if (ss->critical_section)
+           if (_hurdsig_catch_fault (SIGSEGV))
+             {
+               assert (_hurdsig_fault_sigcode >= (long int) ss->context &&
+                       _hurdsig_fault_sigcode < (long int) (ss->context + 1));
+               /* We faulted reading the thread's stack.  Forget that
+                  context and pretend it wasn't there.  It almost
+                  certainly crash if this handler returns, but that's it's
+                  problem.  */
+               ss->context = NULL;
+             }
+           else
+             {
+               /* Copy the context from the thread's stack before
+                  we start diddling the stack to set up the handler.  */
+               ocontext = *ss->context;
+               ss->context = &ocontext;
+             }
+           _hurdsig_end_catch_fault ();
+           
+           if (! machine_get_basic_state (ss->thread, &thread_state))
+             goto sigbomb;
+           loc = interrupted_reply_port_location (&thread_state);
+           if (loc && *loc != MACH_PORT_NULL)
+             /* This is the reply port for the context which called
+                sigreturn.  Since we are abandoning that context entirely
+                and restoring SS->context instead, destroy this port.  */
+             __mach_port_destroy (__mach_task_self (), *loc);
+
+           /* The thread was in sigreturn, not in any interruptible RPC.  */
+           wait_for_reply = 0;
+
+           assert (! ss->critical_section);
+         }
+       else
          {
-           /* The thread is in a critical section.  Mark the signal as
-              pending.  When it finishes the critical section, it will
-              check for pending signals.  */
-           mark_pending ();
-           assert (! state_changed);
-           __thread_resume (ss->thread);
-           break;
+           wait_for_reply = (abort_rpcs (ss, signo,
+                                         &thread_state, &state_changed,
+                                         &reply_port, reply_port_type,
+                                         untraced)
+                             != MACH_PORT_NULL);
+
+           if (ss->critical_section)
+             {
+               /* The thread is in a critical section.  Mark the signal as
+                  pending.  When it finishes the critical section, it will
+                  check for pending signals.  */
+               mark_pending ();
+               assert (! state_changed);
+               __thread_resume (ss->thread);
+               break;
+             }
          }
 
        /* Call the machine-dependent function to set the thread up
@@ -731,18 +783,10 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
                                      signo, sigcode,
                                      wait_for_reply, &thread_state);
        if (scp == NULL)
-         {
-           /* We got a fault setting up the stack frame for the handler.
-              Nothing to do but die; BSD gets SIGILL in this case.  */
-           sigcode = signo;    /* XXX ? */
-           signo = SIGILL;
-           act = core;
-           goto nirvana;
-         }
+         goto sigbomb;
 
        /* Set the machine-independent parts of the signal context.  */
 
-       scp->sc_error = sigerror;
        {
          /* Fetch the thread variable for the MiG reply port,
             and set it to MACH_PORT_NULL.  */
@@ -754,17 +798,32 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
            }
          else
            scp->sc_reply_port = MACH_PORT_NULL;
+
+         /* Save the intr_port in use by the interrupted code,
+            and clear the cell before running the trampoline.  */
+         scp->sc_intr_port = ss->intr_port;
+         ss->intr_port = MACH_PORT_NULL;
+
+         if (ss->context)
+           {
+             /* After the handler runs we will restore to the state in
+                SS->context, not the state of the thread now.  So restore
+                that context's reply port and intr port.  */
+
+             scp->sc_reply_port = ss->context->sc_reply_port;
+             scp->sc_intr_port = ss->context->sc_intr_port;
+
+             ss->context = NULL;
+           }
        }
 
+       /* Backdoor extra argument to signal handler.  */
+       scp->sc_error = sigerror;
+
        /* Block SIGNO and requested signals while running the handler.  */
        scp->sc_mask = ss->blocked;
        ss->blocked |= __sigmask (signo) | ss->actions[signo].sa_mask;
 
-       /* Save the intr_port in use by the interrupted code,
-          and clear the cell before running the trampoline.  */
-       scp->sc_intr_port = ss->intr_port;
-       ss->intr_port = MACH_PORT_NULL;
-
        /* Start the thread running the handler (or possibly waiting for an
           RPC reply before running the handler).  */
        err = __thread_set_state (ss->thread, MACHINE_THREAD_STATE_FLAVOR,
index 509785cb600b6303f6e3be2adc9a3d4d5d3075c5..dbb5da5b9086cc6efc98541755f8e6ecfb606c03 100644 (file)
@@ -183,8 +183,12 @@ endif
 # Be sure not to make these with implicit rules from foo.defs.
 mach.h mach/memory_object.h: ;
 
+ifneq (,)
+# A gcc bug prevents the generated file from working properly,
+# so we have one in the distribution for the time being.
 generated += errsystems.c
 $(objpfx)errsystems.c: errsystems.awk err_*.sub \
                       $(wildcard $(addsuffix /err_*.sub,$(+sysdep_dirs)))
        gawk -v subsys='$(filter-out $<,$^)' -f $^ > $@.n
        mv $@.n $@
+endif
index 5e1ee2a4133acf15eba3245688fb112f725ea355..1797ae5b87df048e999b85205a4bcd6104c99b79 100644 (file)
@@ -68,11 +68,10 @@ elf_machine_load_address (void)
   ++(const Elf32_Rel *) (dynamic_info)[DT_REL]->d_un.d_ptr;
 
 /* Perform the relocation specified by RELOC and SYM (which is fully resolved).
-   LOADADDR is the load address of the object; INFO is an array indexed
-   by DT_* of the .dynamic section info.  */
+   MAP is the object containing the reloc.  */
 
 static inline void
-elf_machine_rel (Elf32_Addr loadaddr, Elf32_Dyn *info[DT_NUM],
+elf_machine_rel (struct link_map *map,
                 const Elf32_Rel *reloc,
                 Elf32_Addr sym_loadaddr, const Elf32_Sym *sym)
 {
@@ -92,7 +91,7 @@ elf_machine_rel (Elf32_Addr loadaddr, Elf32_Dyn *info[DT_NUM],
       *reloc_addr += sym_value;
       break;
     case R_386_RELATIVE:
-      *reloc_addr += loadaddr;
+      *reloc_addr += map->l_addr;
       break;
     case R_386_PC32:
       *reloc_addr = sym_value - (Elf32_Addr) reloc_addr;
@@ -105,13 +104,7 @@ elf_machine_rel (Elf32_Addr loadaddr, Elf32_Dyn *info[DT_NUM],
 
 
 /* The i386 never uses Elf32_Rela relocations.  */
-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)
-{
-  _dl_signal_error (0, "Elf32_Rela relocation requested -- unused on i386");
-}
+#define ELF_MACHINE_NO_RELA 1
 
 
 /* Set up the loaded object described by L so its unrelocated PLT
@@ -140,9 +133,16 @@ elf_machine_runtime_setup (struct link_map *l)
 #define RTLD_START asm ("\
 .text\n\
 .globl _start\n\
-_start:        call _dl_start\n\
-       # Save the user entry point address in %ebx.\n\
-       movl %eax, %ebx\n\
+.globl _dl_start_user\n\
+_start:\n\
+       call _dl_start\n\
+_dl_start_user:\n\
+       # Save the user entry point address in %edi.\n\
+       movl %eax, %edi\n\
+       # Point %ebx at the GOT.
+1:     call 2f\n\
+2:     popl %ebx\n\
+       addl $_GLOBAL_OFFSET_TABLE_+[.-2b], %ebx\n\
        # Call _dl_init_next to return the address of an initializer\n\
        # function to run.\n\
 0:     call _dl_init_next@PLT\n\
@@ -160,10 +160,7 @@ _start:    call _dl_start\n\
        # Loop to call _dl_init_next for the next initializer.\n\
        jmp 0b\n\
        # Pass our finalizer function to the user in %edx, as per ELF ABI.\n\
-1:     call 2f\n\
-2:     popl %eax\n\
-       addl $_GLOBAL_OFFSET_TABLE_+[.-2b], %eax\n\
-       leal _dl_fini@GOT(%eax), %edx\n\
-       # Jump to the user entry point.\n\
-       jmp *%ebx\n\
+       leal _dl_fini@GOT(%ebx), %edx\n\
+       # Jump to the user's entry point.\n\
+       jmp *%edi\n\
 ");
index 897524fdd36ec444cf89ae246f77cb1727459d06..1bc569760c4118e8a322ef768582c8d3e85fc0ad 100644 (file)
@@ -17,8 +17,6 @@ License along with the GNU C Library; see the file COPYING.LIB.  If
 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
-register void *sp asm ("%esp");
-
 #include <link.h>
 #include "dynamic-link.h"
 
@@ -30,7 +28,7 @@ register void *sp asm ("%esp");
    0(%esp)     identifier for this shared object (struct link_map *)
 
    The user expects the real function the PLT refers to to be entered
-   8(%esp) as the top of stack.  */
+   with 8(%esp) as the top of stack.  */
 
 void
 _dl_runtime_resolve (Elf32_Word reloc_offset)
@@ -63,14 +61,15 @@ _dl_runtime_resolve (Elf32_Word reloc_offset)
     scope = _dl_loaded;
   
   definer = &symtab[ELF32_R_SYM (reloc->r_info)];
-  loadbase = _dl_lookup_symbol (strtab + definer->st_name, &definer, scope);
+  loadbase = _dl_lookup_symbol (strtab + definer->st_name, &definer,
+                               scope, l->l_name);
   
   /* Restore list frobnication done above for DT_SYMBOLIC.  */
   l->l_next = real_next;
   l->l_prev->l_next = l;
 
   /* Apply the relocation with that value.  */
-  elf_machine_rel (l->l_addr, l->l_info, reloc, loadbase, definer);
+  elf_machine_rel (l, reloc, loadbase, definer);
 
   /* The top of the stack is the word we set L from; but this location
      holds the address we will return to.  Store there the address of a
index 4740902a10c5b3e11e108645a6bfd901f2526a9b..398c77fbdf789c4e1dcf05748daeb27205fb8141 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995 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
@@ -20,7 +20,7 @@ Cambridge, MA 02139, USA.  */
 #include <stdio.h>
 #include <string.h>
 #include <mach/error.h>
-#include <mach/errorlib.h>
+#include <errorlib.h>
 
 /* Return a string describing the errno code in ERRNUM.  */
 char *
@@ -38,7 +38,7 @@ DEFUN(_strerror_internal, (errnum, buf), int errnum AND char buf[1024])
   sub = err_get_sub (errnum);
   code = err_get_code (errnum);
 
-  if (system > err_max_system)
+  if (system > err_max_system || ! __mach_error_systems[system].bad_sub)
     {
       sprintf (buf, "Unknown error system %d", system);
       return buf;
index 3e6385f64e64cd1fb3c1a2b6c3b3dd44cbd5592d..1befd48a70c29544b369359cc5a316afbd6300c8 100644 (file)
@@ -21,6 +21,7 @@ Cambridge, MA 02139, USA.  */
 #include <unistd.h>
 #include <hurd.h>
 #include <hurd/fd.h>
+#include <hurd/resource.h>
 
 /* Return the maximum number of file descriptors the current process
    could possibly have (until it raises the resource limit).  */
@@ -29,9 +30,9 @@ DEFUN_VOID(__getdtablesize)
 {
   int size;
   HURD_CRITICAL_BEGIN;
-  __mutex_lock (&_hurd_rlimits_lock);
-  size = _hurd_rlimits[RLIM_NOFILE].rlim_cur; /* XXX RLIM_INFINITY?? */
-  __mutex_unlock (&_hurd_rlimits_lock);
+  __mutex_lock (&_hurd_rlimit_lock);
+  size = _hurd_rlimits[RLIMIT_NOFILE].rlim_cur;
+  __mutex_unlock (&_hurd_rlimit_lock);
   HURD_CRITICAL_END;
   return size;
 }
index d00fa7755fab8341e94a7827a194a542f00fb166..0e5ccfc9f51c4c9d037f24e8d83e135b25abc4e0 100644 (file)
@@ -57,15 +57,13 @@ __sigreturn (struct sigcontext *scp)
         the signal thread will notice it if it runs another handler, and
         arrange to have us called over again in the new reality.  */
       ss->context = scp;
-      /* Clear the intr_port slot, since we are not in fact doing
-        an interruptible RPC right now.  If SS->intr_port is not null,
-        the SCP context is doing an interruptible RPC, but the signal
-        thread will examine us while we are blocked in the sig_post RPC.  */
-      ss->intr_port = MACH_PORT_NULL;
       __spin_unlock (&ss->lock);
       __msg_sig_post (_hurd_msgport, 0, __mach_task_self ());
-      /* If a pending signal was handled, sig_post never returned.  */
+      /* If a pending signal was handled, sig_post never returned.
+        If it did return, the pending signal didn't run a handler;
+        proceed as usual.  */
       __spin_lock (&ss->lock);
+      ss->context = NULL;
     }
 
   if (scp->sc_onstack)
index 3402181481eca28dbf7983c841de04e318270c45..2a31588e21836b75e5ee301d5b388ad10208501d 100644 (file)
@@ -73,23 +73,11 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
                  sizeof (state->basic));
          memcpy (&state->fpu, &ss->context->sc_i386_float_state,
                  sizeof (state->fpu));
-         state->set = (1 << i386_THREAD_STATE) | (1 << i386_FLOAT_STATE);
-         assert (! rpc_wait);
-         /* The intr_port slot was cleared before sigreturn sent us the
-            sig_post that made us notice this pending signal, so
-            _hurd_internal_post_signal wouldn't do interrupt_operation.
-            After we return, our caller will set SCP->sc_intr_port (in the
-            new context) from SS->intr_port and clear SS->intr_port.  Now
-            that we are restoring this old context recorded by sigreturn,
-            we want to restore its intr_port too; so store it in
-            SS->intr_port now, so it will end up in SCP->sc_intr_port
-            later.  */
-         ss->intr_port = ss->context->sc_intr_port;
+         state->set |= (1 << i386_THREAD_STATE) | (1 << i386_FLOAT_STATE);
        }
-      /* If the sigreturn context was bogus, just ignore it.  */
-      ss->context = NULL;
     }
-  else if (! machine_get_basic_state (ss->thread, state))
+
+  if (! machine_get_basic_state (ss->thread, state))
     return NULL;
 
   if ((ss->actions[signo].sa_flags & SA_ONSTACK) &&