Mon Oct 9 02:54:14 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
authorRoland McGrath <roland@gnu.org>
Mon, 9 Oct 1995 07:06:29 +0000 (07:06 +0000)
committerRoland McGrath <roland@gnu.org>
Mon, 9 Oct 1995 07:06:29 +0000 (07:06 +0000)
* Makeconfig (config-LDFLAGS): Define to
-Wl-dynamic-linker=$(libdir)$(rtld-installed-name).
(rtld-installed-name): New variable.
* elf/Makefile (install-lib): Variable removed.
(install-others): Define this instead, to
$(libdir)(rtld-installed-name).
($(libdir)(rtld-installed-name)): New target; install from ld.so.

* elf/ldd.sh.in: New file.
* elf/Makefile (distribute): Add ldd.sh.in.
(install-bin): Add ldd.
($(objpfx)ldd: ldd.sh.in): New rule.

* sysdeps/mach/hurd/dl-sysdep.c: Use __hurd_fail throughout.
* hurd/hurd.h (__hurd_fail): Replace macro with inline function.
Translate some Mach errors to Hurd errors.

* elf/rtld.c (dl_main): Under --list, print msg if executable is
statically linked.

* elf/dl-load.c (_dl_map_object_from_fd): Rewrote program header
table processing.

Sat Oct  7 01:25:48 1995  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>

* sysdeps/stub/machine-gmon.h: Add #error.

Fri Oct  6 01:49:48 1995  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>

* elf/dynamic-link.h (elf_get_dynamic_info): If DYN is null, don't
examine it.

ChangeLog
Makeconfig
elf/Makefile
elf/dl-load.c
elf/dynamic-link.h
elf/ldd.sh.in [new file with mode: 0644]
elf/rtld.c
hurd/hurd.h
sysdeps/mach/hurd/dl-sysdep.c
sysdeps/stub/machine-gmon.h
sysdeps/unix/configure

index d600df2..b6935c1 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,37 @@
+Mon Oct  9 02:54:14 1995  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>
+
+       * Makeconfig (config-LDFLAGS): Define to
+       -Wl-dynamic-linker=$(libdir)$(rtld-installed-name).
+       (rtld-installed-name): New variable.
+       * elf/Makefile (install-lib): Variable removed.
+       (install-others): Define this instead, to
+       $(libdir)(rtld-installed-name). 
+       ($(libdir)(rtld-installed-name)): New target; install from ld.so.
+
+       * elf/ldd.sh.in: New file.
+       * elf/Makefile (distribute): Add ldd.sh.in.
+       (install-bin): Add ldd.
+       ($(objpfx)ldd: ldd.sh.in): New rule.
+
+       * sysdeps/mach/hurd/dl-sysdep.c: Use __hurd_fail throughout.
+       * hurd/hurd.h (__hurd_fail): Replace macro with inline function.
+       Translate some Mach errors to Hurd errors.
+
+       * elf/rtld.c (dl_main): Under --list, print msg if executable is
+       statically linked.
+
+       * elf/dl-load.c (_dl_map_object_from_fd): Rewrote program header
+       table processing.
+
+Sat Oct  7 01:25:48 1995  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>
+
+       * sysdeps/stub/machine-gmon.h: Add #error.
+
+Fri Oct  6 01:49:48 1995  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>
+
+       * elf/dynamic-link.h (elf_get_dynamic_info): If DYN is null, don't
+       examine it.
+
 Fri Sep 29 03:43:51 1995  Paul Eggert  <eggert@twinsun.com>
 
        Rewrite mktime from scratch for performance, and for correctness
index 5dd6d54..e0ec754 100644 (file)
@@ -272,6 +272,11 @@ ifndef +link
        $(^:$(common-objpfx)libc.a=$(link-libc)) \
        $(addprefix $(csu-objpfx),$(+postinit))
 endif
+ifndef config-LDFLAGS
+ifeq (yes,$(build-shared))
+config-LDFLAGS = -Wl,-dynamic-linker=$(libdir)$(rtld-installed-name)
+endif
+endif
 ifndef link-libc
 ifeq (yes,$(build-shared))
 link-libc = -L$(common-objdir) -lc $(gnulib)
@@ -292,6 +297,12 @@ else
 csu-objpfx = $(..)csu/
 endif
 
+ifeq (yes,$(build-shared))
+ifndef rtld-installed-name
+rtld-installed-name = ld.so
+endif
+endif
+
 ifndef LD
 LD := ld -X
 endif
index 0065d2b..203406d 100644 (file)
@@ -27,18 +27,18 @@ extra-libs  = libelf libdl
 libelf-routines        := elf_hash
 libdl-routines := dlopen dlclose dlsym dlerror
 libdl-inhibit-o        = $(filter-out .so,$(object-suffixes)) # Build only shared.
-LDFLAGS-dl.so  := -e 0 # work around ld bug
 
 rtld-routines  := rtld $(addprefix dl-,load lookup object reloc        \
                                        runtime sysdep error init fini)
 distribute     = $(rtld-routines:=.c) dynamic-link.h do-rel.h \
-                 soinit.c sofini.c
+                 soinit.c sofini.c ldd.sh.in
 
 include ../Makeconfig
 
 ifeq (yes,$(build-shared))
 extra-objs     = $(rtld-routines:=.so) soinit.so sofini.so
-install-lib    = ld.so
+install-others = $(libdir)(rtld-installed-name)
+install-bin    = ldd
 endif
 
 include ../Rules
@@ -54,3 +54,9 @@ $(objpfx)libdl.so: $(objpfx)libdl_pic.a $(common-objpfx)libc.so $(objpfx)ld.so
        $(LINK.o) -shared -o $(@:$(objpfx)%=%) \
                  $(LDFLAGS.so) $(LDFLAGS-dl.so) \
                  -Wl,--whole-archive $(^:$(objpfx)%=%)
+
+$(libdir)$(rtld-installed-name): $(objpfx)ld.so; $(do-install-program)
+
+$(objpfx)ldd: ldd.sh.in
+       sed 's%@RTLD@%$(libdir)/$(rtld-installed-name)%g' < $< > $@.new
+       mv -f $@.new $@
index 12b945a..b70ba55 100644 (file)
@@ -166,6 +166,7 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname)
   void *file_mapping = NULL;
   size_t mapping_size = 0;
 
+#define LOSE(s) lose (0, (s))
   void lose (int code, const char *msg)
     {
       (void) close (fd);
@@ -174,6 +175,17 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname)
       _dl_signal_error (code, l ? l->l_name : name, msg);
     }
 
+  inline caddr_t map_segment (Elf32_Addr mapstart, size_t len,
+                             int prot, int fixed, off_t offset)
+    {
+      caddr_t mapat = mmap ((caddr_t) mapstart, len, prot,
+                           fixed|MAP_COPY|MAP_FILE|MAP_INHERIT,
+                           fd, offset);
+      if (mapat == (caddr_t) -1)
+       lose (errno, "failed to map segment from shared object");
+      return mapat;
+    }
+
   /* Make sure LOCATION is mapped in.  */
   void *map (off_t location, size_t size)
     {
@@ -194,6 +206,9 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname)
     }
 
   const Elf32_Ehdr *header;
+  const Elf32_Phdr *phdr;
+  const Elf32_Phdr *ph;
+  int type;
 
   /* Look again to see if the real name matched another already loaded.  */
   for (l = _dl_loaded; l; l = l->l_next)
@@ -210,8 +225,6 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname)
   /* Map in the first page to read the header.  */
   header = map (0, sizeof *header);
 
-#undef LOSE
-#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)) |
@@ -242,27 +255,26 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname)
        _dl_signal_error (errno, NULL, "cannot open zero fill device");
     }
 
-  {
-    /* Copy the program header table into stack space so we can then unmap
-       the headers.  */
-    Elf32_Phdr phdr[header->e_phnum];
-    const Elf32_Phdr *ph;
-    int anywhere, type;
+  /* Extract the remaining details we need from the ELF header
+     and then map in the program header table.  */
+  l->l_entry = header->e_entry;
+  type = header->e_type;
+  l->l_phnum = header->e_phnum;
+  phdr = map (header->e_phoff, l->l_phnum * sizeof (Elf32_Phdr));
 
-    type = header->e_type;
-    anywhere = type == ET_DYN || type == ET_REL;
-    l->l_entry = header->e_entry;
-
-    ph = map (header->e_phoff, header->e_phnum * sizeof (Elf32_Phdr));
-    memcpy (phdr, ph, sizeof phdr);
-    l->l_phnum = header->e_phnum;
-
-    /* We are done reading the file's headers now.  Unmap them.  */
-    munmap (file_mapping, mapping_size);
+  {
+    /* Scan the program header table, collecting its load commands.  */
+    struct loadcmd
+      {
+       Elf32_Addr mapstart, mapend, dataend, allocend;
+       off_t mapoff;
+       int prot;
+      } loadcmds[l->l_phnum], *c;
+    size_t nloadcmds = 0;
 
-    /* Scan the program header table, processing its load commands.  */
-    l->l_addr = 0;
     l->l_ld = 0;
+    l->l_phdr = 0;
+    l->l_addr = 0;
     for (ph = phdr; ph < &phdr[l->l_phnum]; ++ph)
       switch (ph->p_type)
        {
@@ -277,114 +289,126 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname)
          break;
 
        case PT_LOAD:
-         /* A load command tells us to map in part of the file.  */
+         /* A load command tells us to map in part of the file.
+            We record the load commands and process them all later.  */
          if (ph->p_align % pagesize != 0)
            LOSE ("ELF load command alignment not page-aligned");
          if ((ph->p_vaddr - ph->p_offset) % ph->p_align)
            LOSE ("ELF load command address/offset not properly aligned");
          {
-           Elf32_Addr mapstart = ph->p_vaddr & ~(ph->p_align - 1);
-           Elf32_Addr mapend = ((ph->p_vaddr + ph->p_filesz + ph->p_align - 1)
-                                & ~(ph->p_align - 1));
-           off_t mapoff = ph->p_offset & ~(ph->p_align - 1);
-           caddr_t mapat;
-           int prot = 0;
+           struct loadcmd *c = &loadcmds[nloadcmds++];
+           c->mapstart = ph->p_vaddr & ~(ph->p_align - 1);
+           c->mapend = ((ph->p_vaddr + ph->p_filesz + ph->p_align - 1)
+                        & ~(ph->p_align - 1));
+           c->dataend = ph->p_vaddr + ph->p_filesz;
+           c->allocend = ph->p_vaddr + ph->p_memsz;
+           c->mapoff = ph->p_offset & ~(ph->p_align - 1);
+           c->prot = 0;
            if (ph->p_flags & PF_R)
-             prot |= PROT_READ;
+             c->prot |= PROT_READ;
            if (ph->p_flags & PF_W)
-             prot |= PROT_WRITE;
+             c->prot |= PROT_WRITE;
            if (ph->p_flags & PF_X)
-             prot |= PROT_EXEC;
+             c->prot |= PROT_EXEC;
+           break;
+         }
+       }
 
-           if (anywhere)
-             {
-               /* 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,
-                             prot, MAP_COPY|MAP_FILE|MAP_INHERIT |
-                             /* Let the system choose any convenient
-                                location if this is the first segment.
-                                Following segments must be contiguous in
-                                virtual space with the first.  */
-                             (l->l_addr == 0 ? 0 : MAP_FIXED),
-                             fd, mapoff);
-               if (l->l_addr == 0)
-                 /* This was the first segment mapped, so MAPAT is
-                    the address the system chose for us.  Record it.  */
-                 l->l_addr = (Elf32_Addr) mapat - mapstart;
-             }
-           else
-             {
-               mapat = mmap ((caddr_t) mapstart, mapend - mapstart,
-                             prot, MAP_COPY|MAP_FILE|MAP_INHERIT|MAP_FIXED,
-                             fd, mapoff);
-               /* This file refers to absolute addresses.  So consider its
-                  "load base" to be zero, since that is what we add to the
-                  file's addresses to find them in our memory.  */
-               l->l_addr = 0;
-             }
-           if (mapat == (caddr_t) -1)
-             lose (errno, "failed to map segment from shared object");
+    /* We are done reading the file's headers now.  Unmap them.  */
+    munmap (file_mapping, mapping_size);
+
+    /* Now process the load commands and map segments into memory.  */
+    c = loadcmds;
+
+    if (type == ET_DYN || type == ET_REL)
+      {
+       /* This is a position-independent shared object.  We can let the
+          kernel map it anywhere it likes, but we must have space for all
+          the segments in their specified positions relative to the first.
+          So we map the first segment without MAP_FIXED, but with its
+          extent increased to cover all the segments.  Then we unmap the
+          excess portion, and there is known sufficient space there to map
+          the later segments.  */
+       caddr_t mapat;
+       mapat = map_segment (c->mapstart,
+                            loadcmds[nloadcmds - 1].allocend - c->mapstart,
+                            c->prot, 0, c->mapoff);
+       l->l_addr = (Elf32_Addr) mapat - c->mapstart;
+
+       /* Unmap the excess portion, and then jump into the normal
+          segment-mapping loop to handle the portion of the segment past
+          the end of the file mapping.  */
+       munmap (mapat + c->mapend,
+               loadcmds[nloadcmds - 1].allocend - c->mapend);
+       goto postmap;
+      }
+
+    while (c < &loadcmds[nloadcmds])
+      {
+       if (c->mapend > c->mapstart)
+         /* Map the segment contents from the file.  */
+         map_segment (l->l_addr + c->mapstart, c->mapend - c->mapstart,
+                      c->prot, MAP_FIXED, c->mapoff);
+
+      postmap:
+       if (c->allocend > c->dataend)
+         {
+           /* Extra zero pages should appear at the end of this segment,
+              after the data mapped from the file.   */
+           Elf32_Addr zero, zeroend, zeropage;
+
+           zero = l->l_addr + c->dataend;
+           zeroend = l->l_addr + c->allocend;
+           zeropage = (zero + pagesize - 1) & ~(pagesize - 1);
 
-           if (ph->p_memsz > ph->p_filesz)
+           if (zeroend < zeropage)
+             /* All the extra data is in the last page of the segment.
+                We can just zero it.  */
+             zeropage = zeroend;
+
+           if (zeropage > zero)
              {
-               /* Extra zero pages should appear at the end of this segment,
-                  after the data mapped from the file.   */
-               caddr_t zero, zeroend, zeropage;
-
-               mapat += ph->p_vaddr - mapstart;
-               zero = mapat + ph->p_filesz;
-               zeroend = mapat + ph->p_memsz;
-               zeropage = (caddr_t) ((Elf32_Addr) (zero + pagesize - 1)
-                                     & ~(pagesize - 1));
-
-               if (zeroend < zeropage)
-                 /* All the extra data is in the last page of the segment.
-                    We can just zero it.  */
-                 zeropage = zeroend;
-               if (zeropage > zero)
+               /* Zero the final part of the last page of the segment.  */
+               if ((c->prot & PROT_WRITE) == 0)
                  {
-                   /* Zero the final part of the last page of the segment.  */
-                   if ((prot & PROT_WRITE) == 0)
-                     {
-                       /* Dag nab it.  */
-                       if (mprotect ((caddr_t) ((Elf32_Addr) zero
-                                                & ~(pagesize - 1)),
-                                     pagesize,
-                                     prot|PROT_WRITE) < 0)
-                         lose (errno, "cannot change memory protections");
-                     }
-                   memset (zero, 0, zeropage - zero);
-                   if ((prot & PROT_WRITE) == 0)
-                     mprotect ((caddr_t) ((Elf32_Addr) zero
-                                          & ~(pagesize - 1)),
-                               pagesize, prot);
+                   /* Dag nab it.  */
+                   if (mprotect ((caddr_t) (zero & ~(pagesize - 1)),
+                                 pagesize, c->prot|PROT_WRITE) < 0)
+                     lose (errno, "cannot change memory protections");
                  }
+               memset ((void *) zero, 0, zeropage - zero);
+               if ((c->prot & PROT_WRITE) == 0)
+                 mprotect ((caddr_t) (zero & ~(pagesize - 1)),
+                           pagesize, c->prot);
+             }
 
-               if (zeroend > zeropage)
-                 /* Map the remaining zero pages in from the zero fill FD.  */
-                 mapat = mmap (zeropage, zeroend - zeropage, prot,
-                               MAP_ANON|MAP_PRIVATE|MAP_FIXED|MAP_INHERIT,
-                               _dl_zerofd, 0);
+           if (zeroend > zeropage)
+             {
+               /* Map the remaining zero pages in from the zero fill FD.  */
+               caddr_t mapat;
+               mapat = mmap ((caddr_t) zeropage, zeroend - zeropage, c->prot,
+                             MAP_ANON|MAP_PRIVATE|MAP_FIXED|MAP_INHERIT,
+                             _dl_zerofd, 0);
+               if (mapat == (caddr_t) -1)
+                 lose (errno, "cannot map zero pages");
              }
          }
-       }
 
-    if (l->l_ld == 0)
-      {
-       if (type == ET_DYN)
-         LOSE ("object file has no dynamic section");
+       ++c;
       }
-    else
-      (Elf32_Addr) l->l_ld += l->l_addr;
+  }
 
-    if (l->l_phdr == 0)
-      l->l_phdr = (void *) ((const Elf32_Ehdr *) l->l_addr)->e_phoff;
-    (Elf32_Addr) l->l_phdr += l->l_addr;
+  if (l->l_ld == 0)
+    {
+      if (type == ET_DYN)
+       LOSE ("object file has no dynamic section");
+    }
+  else
+    (Elf32_Addr) l->l_ld += l->l_addr;
 
-    l->l_entry += l->l_addr;
-  }
+  if (l->l_phdr == 0)
+    l->l_phdr = (void *) ((const Elf32_Ehdr *) l->l_addr)->e_phoff;
+  (Elf32_Addr) l->l_phdr += l->l_addr;
 
   elf_get_dynamic_info (l->l_ld, l->l_info);
   if (l->l_info[DT_HASH])
index a7316ee..84d440e 100644 (file)
@@ -32,6 +32,9 @@ elf_get_dynamic_info (Elf32_Dyn *dyn, Elf32_Dyn *info[DT_NUM])
   for (i = 0; i < DT_NUM; ++i)
     info[i] = NULL;
 
+  if (! dyn)
+    return;
+
   while (dyn->d_tag != DT_NULL)
     {
       assert (dyn->d_tag < DT_NUM);
diff --git a/elf/ldd.sh.in b/elf/ldd.sh.in
new file mode 100644 (file)
index 0000000..58ae501
--- /dev/null
@@ -0,0 +1,26 @@
+#! /bin/sh
+
+# This is the `ldd' command, which lists what shared libraries are
+# used by given dynamically-linked executables.  It works by invoking the
+# run-time dynamic linker as a command and giving it the special `--list'
+# switch.
+
+RTLD=@RTLD@
+
+case $# in
+0)
+  echo >&2 "Usage: $0 FILE..."
+  exit 1 ;;
+1)
+  # We don't list the file name when there is only one.
+  exec ${RTLD} --list "$1" && exit 1
+  exit ;;
+*)
+  set -e       # Bail out immediately if ${RTLD} loses on any argument.
+  for file; do
+    echo "${file}:"
+    ${RTLD} --list "$file"
+  done
+esac
+
+exit 0
index 6be05eb..d780fcb 100644 (file)
@@ -281,6 +281,13 @@ of this helper program; chances are you did not intend to run this program.\n",
 
       if (list_only)
        {
+         if (! _dl_loaded->l_info[DT_NEEDED])
+           {
+             _dl_sysdep_message (_dl_loaded->l_name, ": statically linked\n",
+                                 NULL);
+             _exit (1);
+           }
+
          for (l = _dl_loaded->l_next; l; l = l->l_next)
            {
              char buf[20], *bp;
index 1b4db17..acad15b 100644 (file)
@@ -42,7 +42,33 @@ Cambridge, MA 02139, USA.  */
 #include <hurd/port.h>
 
 #include <errno.h>
-#define        __hurd_fail(err)        (errno = (err), -1)
+
+_EXTERN_INLINE int
+__hurd_fail (error_t err)
+{
+  switch (err)
+    {
+    case EMACH_SEND_INVALID_DEST:
+    case EMIG_SERVER_DIED:
+      /* The server has disappeared!  */
+      err = EIEIO;
+      break;
+
+    case KERN_NO_SPACE:
+      err = ENOMEM;
+      break;
+    case KERN_INVALID_ARGUMENT:
+      err = EINVAL;
+      break;
+
+    case 0:
+      return 0;
+    default:
+    }
+
+  errno = err;
+  return -1;
+}
 \f
 /* Basic ports and info, initialized by startup.  */
 
index 8e1ef17..1038075 100644 (file)
@@ -262,41 +262,38 @@ open (const char *file_name, int mode, ...)
   file_t startdir, newpt, fileport;
   int dealloc_dir;
   int nloops;
-
+  error_t err;
 
   assert (mode == O_RDONLY);
 
-
   startdir = _dl_hurd_data->portarray[file_name[0] == '/' ?
                                      INIT_PORT_CRDIR : INIT_PORT_CWDIR];
 
   while (file_name[0] == '/')
     file_name++;
 
-  if (errno = __dir_lookup (startdir, file_name, mode, 0,
-                                         &doretry, retryname, &fileport))
-    return -1;
+  if (err = __dir_lookup (startdir, file_name, mode, 0,
+                         &doretry, retryname, &fileport))
+    return __hurd_fail (err);
 
   dealloc_dir = 0;
   nloops = 0;
-  errno = 0;
   
   while (1)
     {
       if (dealloc_dir)
        __mach_port_deallocate (__mach_task_self (), startdir);
-      if (errno)
-       return -1;
+      if (err)
+       return __hurd_fail (err);
 
       switch (doretry)
        {
        case FS_RETRY_REAUTH:
          {
            mach_port_t ref = __mach_reply_port ();
-           errno = __io_reauthenticate
-             (fileport, ref, MACH_MSG_TYPE_MAKE_SEND);
-           if (! errno)
-             errno = __auth_user_authenticate
+           err = __io_reauthenticate (fileport, ref, MACH_MSG_TYPE_MAKE_SEND);
+           if (! err)
+             err = __auth_user_authenticate
                (_dl_hurd_data->portarray[INIT_PORT_AUTH],
                 fileport,
                 ref, MACH_MSG_TYPE_MAKE_SEND,
@@ -304,18 +301,15 @@ open (const char *file_name, int mode, ...)
            __mach_port_destroy (__mach_task_self (), ref);
          }
          __mach_port_deallocate (__mach_task_self (), fileport);
-         if (errno)
-           return -1;
+         if (err)
+           return __hurd_fail (err);
          fileport = newpt;
          /* Fall through.  */
 
        case FS_RETRY_NORMAL:
 #ifdef SYMLOOP_MAX
          if (nloops++ >= SYMLOOP_MAX)
-           {
-             errno = ELOOP;
-             return -1;
-           }
+           return __hurd_fail (ELOOP);
 #endif
 
          /* An empty RETRYNAME indicates we have the final port.  */
@@ -327,11 +321,11 @@ open (const char *file_name, int mode, ...)
 
            opened:
              /* We have the file open.  Now map it.  */
-             errno = __io_map (fileport, &memobj_rd, &memobj_wr);
+             err = __io_map (fileport, &memobj_rd, &memobj_wr);
              if (dealloc_dir)
                __mach_port_deallocate (__mach_task_self (), fileport);
-             if (errno)
-               return -1;
+             if (err)
+               return __hurd_fail (err);
              if (memobj_wr != MACH_PORT_NULL)
                __mach_port_deallocate (__mach_task_self (), memobj_wr);
 
@@ -359,26 +353,20 @@ open (const char *file_name, int mode, ...)
                {
                  int fd;
                  char *end;
-                 errno = 0;
+                 err = 0;
                  fd = (int) strtol (retryname, &end, 10);
-                 if (end == NULL || errno || /* Malformed number.  */
+                 if (end == NULL || err || /* Malformed number.  */
                      /* Check for excess text after the number.  A slash
                         is valid; it ends the component.  Anything else
                         does not name a numeric file descriptor.  */
                      (*end != '/' && *end != '\0'))
-                   {
-                     errno = ENOENT;
-                     return -1;
-                   }
+                   return __hurd_fail (ENOENT);
                  if (fd < 0 || fd >= _dl_hurd_data->dtablesize ||
                      _dl_hurd_data->dtable[fd] == MACH_PORT_NULL)
-                   {
-                     /* If the name was a proper number, but the file
-                        descriptor does not exist, we return EBADF instead
-                        of ENOENT.  */
-                     errno = EBADF;
-                     return -1;
-                   }
+                   /* If the name was a proper number, but the file
+                      descriptor does not exist, we return EBADF instead
+                      of ENOENT.  */
+                   return __hurd_fail (EBADF);
                  fileport = _dl_hurd_data->dtable[fd];
                  if (*end == '\0')
                    {
@@ -459,13 +447,13 @@ open (const char *file_name, int mode, ...)
                      }
 
                  case '\0':
-                   if (errno = opentty (&fileport))
-                     return -1;
+                   if (err = opentty (&fileport))
+                     return __hurd_fail (err);
                    dealloc_dir = 1;
                    goto opened;
                  case '/':
-                   if (errno = opentty (&startdir))
-                     return -1;
+                   if (err = opentty (&startdir))
+                     return __hurd_fail (err);
                    dealloc_dir = 1;
                    strcpy (retryname, &retryname[4]);
                    break;
@@ -478,18 +466,16 @@ open (const char *file_name, int mode, ...)
 
            default:
            bad_magic:
-             errno = EGRATUITOUS;
-             return -1;
+             return __hurd_fail (EGRATUITOUS);
            }
          break;                
 
        default:
-         errno = EGRATUITOUS;
-         return -1;
+         return __hurd_fail (EGRATUITOUS);
        }
 
-      errno = __dir_lookup (startdir, file_name, mode, 0,
-                           &doretry, retryname, &fileport);
+      err = __dir_lookup (startdir, file_name, mode, 0,
+                         &doretry, retryname, &fileport);
     }
 }
 
@@ -504,6 +490,7 @@ close (int fd)
 caddr_t
 mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t offset)
 {
+  error_t err;
   vm_prot_t vmprot;
   vm_address_t mapaddr;
 
@@ -516,14 +503,14 @@ mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t offset)
     vmprot |= VM_PROT_EXECUTE;
 
   mapaddr = (vm_address_t) addr;
-  errno = __vm_map (__mach_task_self (),
-                   &mapaddr, (vm_size_t) len, 0 /*ELF_MACHINE_USER_ADDRESS_MASK*/,
-                   !(flags & MAP_FIXED),
-                   (mach_port_t) fd, (vm_offset_t) offset,
-                   flags & (MAP_COPY|MAP_PRIVATE),
-                   vmprot, VM_PROT_ALL,
-                   (flags & MAP_INHERIT) ? VM_INHERIT_COPY : VM_INHERIT_NONE);
-  return errno ? (caddr_t) -1 : (caddr_t) mapaddr;
+  err = __vm_map (__mach_task_self (),
+                 &mapaddr, (vm_size_t) len, 0 /*ELF_MACHINE_USER_ADDRESS_MASK*/,
+                 !(flags & MAP_FIXED),
+                 (mach_port_t) fd, (vm_offset_t) offset,
+                 flags & (MAP_COPY|MAP_PRIVATE),
+                 vmprot, VM_PROT_ALL,
+                 (flags & MAP_INHERIT) ? VM_INHERIT_COPY : VM_INHERIT_NONE);
+  return err ? (caddr_t) __hurd_fail (err) : (caddr_t) mapaddr;
 }
 
 void
index a6edbc0..166faed 100644 (file)
@@ -26,3 +26,5 @@ void mcount (u_long arg)                                                    \
 {                                                                            \
   _mcount (caller return PC, my return PC);                                  \
 }
+
+#error "sysdeps/MACHINE/machine-gmon.h missing"
index 4fb599a..dfc1c22 100755 (executable)
@@ -65,7 +65,7 @@ for unix_function in \
   getitimer setitimer \
   getdomainname/getdomain=bsd/bsd4.4 \
   setdomainname/setdomain=bsd/bsd4.4 \
-  profil=bsd \
+  profil=bsd readv=bsd writev=bsd \
   getpriority setpriority \
   getrlimit setrlimit
 do
@@ -78,7 +78,7 @@ do
   eval "unix_syscall=`echo $unix_function | \
                       sed -e 's@=\(.*\)$@ unix_srcdir=\1@' \
                           -e 's@/\(.*\)$@ unix_srcname=\1@'`"
-  test -z "$unix_srcname" && unix_srcname=$unix_function
+  test -z "$unix_srcname" && unix_srcname=$unix_syscall
 
   unix_implementor=none
   for unix_dir in $sysnames; do
@@ -90,11 +90,13 @@ do
     fi
   done
 
-  # mkdir and rmdir have implementations in unix/sysv, but
-  # the simple syscall versions are preferable if available.
-  test $unix_syscall = mkdir -o $unix_syscall = rmdir && \
-  test $unix_implementor = unix/sysv && \
-    unix_implementor=generic
+  case $unix_syscall in
+  mkdir|rmdir) 
+    # mkdir and rmdir have implementations in unix/sysv, but
+    # the simple syscall versions are preferable if available.
+    test $unix_implementor = unix/sysv && unix_implementor=generic
+    ;;
+  esac
 
   case $unix_implementor in
   none|stub|generic|posix)