summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Makeconfig18
-rw-r--r--Makerules52
-rwxr-xr-xconfigure34
-rw-r--r--elf/dl-error.c1
-rw-r--r--elf/dlsym.c2
-rw-r--r--elf/elf.h2
-rw-r--r--elf/rtld.c24
-rw-r--r--hurd/hurdstartup.h63
-rw-r--r--sysdeps/i386/elf/start.S10
-rw-r--r--sysdeps/mach/_strerror.c23
10 files changed, 185 insertions, 44 deletions
diff --git a/Makeconfig b/Makeconfig
index cb3c065ddc..f001982496 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -78,11 +78,21 @@ endif
 # Get the values defined by options to `configure'.
 include $(common-objpfx)config.make
 
+# Run config.status to update config.make and config.h.  We don't show the
+# dependence of config.h to Make, because it is only touched when it
+# changes and so config.status would be run every time; the dependence of
+# config.make should suffice to force regeneration and re-exec, and the new
+# image will notice if config.h changed.
+$(common-objpfx)config.make: $(common-objpfx)config.status
+	cd $(<D); $(SHELL) $(<F)
+
 # Force the user to configure before making.
-$(common-objpfx)config.make:
-	@echo The GNU C library has not been configured. >&2
-	@echo Run \`configure\' to configure it before building. >&2
-	@exit 1
+$(common-objpfx)config.status: $(..)configure
+	@cd $(@D); if test -f $(@F); then exec $(SHELL) $(@F) --recheck; else \
+	 echo The GNU C library has not been configured. >&2; \
+	 echo Run \`configure\' to configure it before building. >&2; \
+	 echo Try \`configure --help\' for more details. >&2; \
+	 exit 1; fi
 
 # Get the user's configuration parameters.
 ifneq ($(wildcard $(..)configparms),)
diff --git a/Makerules b/Makerules
index 0e67398dad..e36bf7b738 100644
--- a/Makerules
+++ b/Makerules
@@ -86,9 +86,15 @@ in-Makerules := yes
 
 ifndef avoid-generated
 include $(+sysdir_pfx)sysd-Makefile
-$(+sysdir_pfx)sysd-Makefile: $(+sysdir_pfx)config.make $(..)Makerules
+ifneq ($(sysd-Makefile-sysdirs),$(sysdirs))
+sysd-Makefile-force = FORCE
+FORCE:
+endif
+$(+sysdir_pfx)sysd-Makefile: $(+sysdir_pfx)config.make $(..)Makerules \
+			     $(sysd-Makefile-force)
 	-@rm -f $@T
-	(for dir in $(sysdirs); do		   			      \
+	(echo 'sysd-Makefile-sysdirs := $(sysdirs)';			      \
+	 for dir in $(sysdirs); do		   			      \
 	   file=sysdeps/$$dir/Makefile;					      \
 	   if [ -f $(..)$$file ]; then					      \
 	     echo include "\$$(..)$$file";				      \
@@ -192,12 +198,20 @@ endif
 # contents of sysd-rules.
 ifdef sysd-Makefile-done
 include $(+sysdir_pfx)sysd-rules
+ifneq ($(sysd-rules-sysdirs),$(sysdirs))
+# The value of $(sysdirs) the sysd-rules was computed for
+# differs from the one we are using now.  So force a rebuild of sysd-rules.
+sysd-rules-force = FORCE
+FORCE:
+endif
 endif
 $(+sysdir_pfx)sysd-rules: $(+sysdir_pfx)config.make $(..)Makerules \
 			  $(wildcard $(foreach dir,$(sysdirs),\
-					       $(sysdep_dir)/$(dir)/Makefile))
+					       $(sysdep_dir)/$(dir)/Makefile))\
+			  $(sysd-rules-force)
 	-@rm -f $@T
-	(for sysdir in $(sysdirs); do		   			      \
+	(echo 'sysd-rules-sysdirs := $(sysdirs)';			      \
+	 for sysdir in $(sysdirs); do		   			      \
 	   dir="\$$(sysdep_dir)/$$sysdir";				      \
 	   for o in $(object-suffixes); do \
 	     $(open-check-inhibit-asm) \
@@ -351,7 +365,7 @@ lib%.so: lib%_pic.a
 # since we define our own `.init' section specially.
 LDFLAGS-c.so = -nostdlib
 # Give libc.so an entry point and make it directly runnable itself.
-LDFLAGS-c.so += -Wl,-interp -Wl,/lib/ld.so -e __libc_print_version
+LDFLAGS-c.so += -Wl,-dynamic-linker -Wl,/lib/ld.so -e __libc_print_version
 endif
 
 libobjs: $(foreach o,$(object-suffixes),\
@@ -472,23 +486,33 @@ $(installed-libcs): $(libdir)/lib$(libprefix)%: libobjs subdir_install
 	$(RANLIB) $@
 endif
 
-install-lib.so := libc.so $(filter lib%.so,$(install-lib))
-install-lib := $(filter-out lib%.so,$(install-lib))
+define do-install-program
+$(make-target-directory)
+$(INSTALL_PROGRAM) $< $@.new
+mv -f $@.new $@
+endef
+
+install-lib.so := libc.so $(filter %.so,$(install-lib))
+install-lib := $(filter-out %.so,$(install-lib))
 ifeq (yes,$(build-shared))
-install: $(foreach so,$(install-lib.so), \
-		   $(libdir)/$(so:lib%=lib$(libprefix)%).$($(so)-version))
-$(libdir)/lib$(libprefix)%.so: $(common-objpfx)lib%.so; $(do-install)
+install: $(foreach so,$(install-lib.so),\
+  $(libdir)/$(patsubst $(libprefix)lib%,lib$(libprefix)%,\
+		       $(libprefix)$(so))$($(so)-version))
+$(foreach v,$(sort $(foreach so,$(install-lib.so),.so$((so)-version))),\
+	  $(libdir)/lib$(libprefix)%$v): $(common-objpfx)lib%.so
+	$(do-install-program)
+$(foreach v,$(sort $(foreach so,$(install-lib.so),.so$((so)-version))),\
+	  $(libdir)/$(libprefix)%$v): $(common-objpfx)%.so
+	$(do-install-program)
 endif
 
 ifdef install-bin
 $(addprefix $(bindir)/,$(install-bin)): $(bindir)/%: $(objpfx)%
-	$(make-target-directory)
-	$(INSTALL_PROGRAM) $< $@
+	$(do-install-program)
 endif
 ifdef install-sbin
 $(addprefix $(sbindir)/,$(install-sbin)): $(sbindir)/%: $(objpfx)%
-	$(make-target-directory)
-	$(INSTALL_PROGRAM) $< $@
+	$(do-install-program)
 endif
 ifdef install-lib
 install-lib.a := $(filter lib%.a,$(install-lib))
diff --git a/configure b/configure
index 36fcca0d5b..6f043c4106 100755
--- a/configure
+++ b/configure
@@ -660,9 +660,9 @@ mach=
 tail=$machine
 while m=`echo $tail | sed 's@^\(.*\)/\([^/]*\)$@& \1@'`; test -n "$m"; do
   set $m
-  # If using ELF, look for an `elf' subdirectory of each machine directory.
-  if test "$elf" = yes; then
-    mach="$mach /$1/elf"
+  # Prepend the machine's FPU directory unless --without-fp.
+  if test "$with_fp" = yes; then
+    mach="$mach /$1/fpu"
   fi
   mach="$mach /$1"
   tail="$2"
@@ -698,21 +698,25 @@ fi
 # We have now validated the configuration.
 
 
-# Remove the leading slashes.
-sysnames="`echo $sysnames | sed -e 's@^/@@' -e 's@ /@ @g'`"
-
-# Prepend the machine's FPU directory unless --without-fp.
-if test "$with_fp" = yes; then
-  fpu_dirs=
+# If using ELF, look for an `elf' subdirectory of each machine directory.
+# We prepend these rather than inserting them whereever the machine appears
+# because things specified by the machine's ELF ABI should override
+# OS-specific things, and should always be the same for any OS on the
+# machine (otherwise what's the point of an ABI?).
+if test "$elf" = yes; then
+  elf_dirs=
   for m in $mach; do
-    if test -d $sysdep_dir$m/fpu; then
-      fpu_dirs="$fpu_dirs $m/fpu"
+    if test -d $sysdep_dir$m/elf; then
+      elf_dirs="$elf_dirs $m/elf"
     fi
   done
-  sysnames="`echo $fpu_dirs | sed -e 's,^/,,' -e 's, /,,g'` $sysnames"
+  sysnames="`echo $elf_dirs | sed -e 's,^/,,' -e 's, /,,g'` $sysnames"
 fi
 
 
+# Remove the leading slashes.
+sysnames="`echo $sysnames | sed -e 's@^/@@' -e 's@ /@ @g'`"
+
 
 # Expand the list of system names into a full list of directories
 # from each element's parent name and Implies file (if present).
@@ -993,7 +997,7 @@ else
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat > conftest.$ac_ext <<EOF
-#line 997 "configure"
+#line 1001 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
@@ -1007,7 +1011,7 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 1011 "configure"
+#line 1015 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
@@ -1059,7 +1063,7 @@ if eval "test \"`echo '$''{'libc_cv_friendly_stddef'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&4
 else
   cat > conftest.$ac_ext <<EOF
-#line 1063 "configure"
+#line 1067 "configure"
 #include "confdefs.h"
 #define __need_size_t
 #define __need_wchar_t
diff --git a/elf/dl-error.c b/elf/dl-error.c
index 5f8e4e4088..acb21a0414 100644
--- a/elf/dl-error.c
+++ b/elf/dl-error.c
@@ -30,6 +30,7 @@ _dl_signal_error (int errcode,
 		  const char *errstring)
 {
   signalled_errstring = errstring ?: "DYNAMIC LINKER BUG!!!";
+  signalled_objname = objname;
   longjmp (catch_env, errcode ?: -1);
 }
 
diff --git a/elf/dlsym.c b/elf/dlsym.c
index 3e10812da8..dbd617ec9a 100644
--- a/elf/dlsym.c
+++ b/elf/dlsym.c
@@ -33,7 +33,7 @@ dlsym (void *handle, const char *name)
   void doit (void)
     {
       const Elf32_Sym *ref = NULL;
-      value = _dl_lookup_symbol (name, map->l_name, &ref, map);
+      value = _dl_lookup_symbol (name, &ref, map, map->l_name);
     }
 
   /* Confine the symbol scope to just this map.  */
diff --git a/elf/elf.h b/elf/elf.h
index 40c0cd8aab..433aa479e7 100644
--- a/elf/elf.h
+++ b/elf/elf.h
@@ -545,7 +545,7 @@ typedef struct
 
 /* Legal values for p_type field of Elf32_Phdr.  */
 
-#define PT_MIPS_REGINFO	0x70000000	/* Regiser usage information */
+#define PT_MIPS_REGINFO	0x70000000	/* Register usage information */
 
 /* Legal values for d_tag field of Elf32_Dyn.  */
 
diff --git a/elf/rtld.c b/elf/rtld.c
index 0605336603..85f258a948 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -261,3 +261,27 @@ void
 _dl_r_debug_state (void)
 {
 }
+
+#ifndef NDEBUG
+
+/* Define (weakly) our own assert failure function which doesn't use stdio.
+   If we are linked into the user program (-ldl), the normal __assert_fail
+   defn can override this one.  */
+
+#include "../stdio/_itoa.h"
+
+void
+__assert_fail (const char *assertion,
+	       const char *file, unsigned int line, const char *function)
+{
+  char buf[64];
+  buf[sizeof buf - 1] = '\0';
+  _dl_sysdep_fatal ("BUG IN DYNAMIC LINKER ld.so: ",
+		    file, ": ", _itoa (line, buf + sizeof buf - 1, 10, 0),
+		    ": ", function ?: "", function ? ": " : "",
+		    "Assertion `", assertion, "' failed!\n");
+
+}
+weak_symbol (__assert_fail)
+
+#endif
diff --git a/hurd/hurdstartup.h b/hurd/hurdstartup.h
new file mode 100644
index 0000000000..fd6a36605d
--- /dev/null
+++ b/hurd/hurdstartup.h
@@ -0,0 +1,63 @@
+/* Data from initial program startup for running under the GNU Hurd.
+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.  */
+
+#ifndef _HURDSTARTUP_H
+#define _HURDSTARTUP_H 1
+
+
+/* Interesting data saved from the exec_startup reply.
+   The DATA argument to *MAIN (see below) points to:
+
+    int argc;
+    char *argv[argc];
+    char *argv_terminator = NULL;
+    char *envp[?];
+    char *envp_terminator = NULL;
+    struct hurd_startup_data data;
+
+*/   
+
+struct hurd_startup_data
+  {
+    int flags;
+    mach_port_t *dtable;
+    mach_msg_type_number_t dtablesize;
+    mach_port_t *portarray;
+    mach_msg_type_number_t portarraysize;
+    int *intarray;
+    mach_msg_type_number_t intarraysize;
+    vm_address_t stack_base;
+    vm_size_t stack_size;
+    vm_address_t phdr;
+    vm_size_t phdrsz;
+    vm_address_t user_entry;
+  };
+
+
+/* Initialize Mach RPCs; do initial handshake with the exec server (or
+   extract the arguments from the stack in the case of the bootstrap task);
+   finally, call *MAIN with the information gleaned.  That function is not
+   expected to return.  ARGPTR should be the address of the first argument
+   of the entry point function that is called with the stack exactly as the
+   exec server or kernel sets it.  */
+
+extern void _hurd_startup (void **argptr, void (*main) (int *data));
+
+
+#endif	/* hurdstartup.h */
diff --git a/sysdeps/i386/elf/start.S b/sysdeps/i386/elf/start.S
index 5c29ce412a..67d7916ad6 100644
--- a/sysdeps/i386/elf/start.S
+++ b/sysdeps/i386/elf/start.S
@@ -49,8 +49,8 @@ _start:
 	   linked, this will not be set by anything to any function
 	   pointer; hopefully it will be zero so we don't try to call
 	   random pointers.  */
-	testl %edx
-	jeq nofini
+	testl %edx,%edx
+	jz nofini
 	pushl %edx
 	call atexit
 	addl $4, %esp
@@ -84,3 +84,9 @@ nofini:
 	pushl %eax
 	call exit		/* This should never return.  */
 	hlt			/* Crash if somehow it does return.  */
+
+/* Define a symbol for the first piece of initialized data.  */
+	.data
+	.globl __data_start
+__data_start:
+	.long 0
diff --git a/sysdeps/mach/_strerror.c b/sysdeps/mach/_strerror.c
index 398c77fbdf..eeebb9e360 100644
--- a/sysdeps/mach/_strerror.c
+++ b/sysdeps/mach/_strerror.c
@@ -16,15 +16,15 @@ 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.  */
 
-#include <ansidecl.h>
 #include <stdio.h>
 #include <string.h>
 #include <mach/error.h>
 #include <errorlib.h>
+#include "../stdio/_itoa.h"
 
 /* Return a string describing the errno code in ERRNUM.  */
 char *
-DEFUN(_strerror_internal, (errnum, buf), int errnum AND char buf[1024])
+_strerror_internal (int errnum, char buf[1024])
 {
   int system; 
   int sub;
@@ -40,8 +40,12 @@ DEFUN(_strerror_internal, (errnum, buf), int errnum AND char buf[1024])
 
   if (system > err_max_system || ! __mach_error_systems[system].bad_sub)
     {
-      sprintf (buf, "Unknown error system %d", system);
-      return buf;
+      static const char unk[] = "Error in unknown error system: ";
+      char *p = buf + sizeof buf;
+      *p-- = '\0';
+      p = _itoa (errnum, p, 16, 1);
+      p -= sizeof unk - 1;
+      return memcpy (p, unk, sizeof unk - 1);
     }
 
   es = &__mach_error_systems[system];
@@ -51,9 +55,14 @@ DEFUN(_strerror_internal, (errnum, buf), int errnum AND char buf[1024])
 
   if (code >= es->subsystem[sub].max_code)
     {
-      sprintf (buf, "Unknown error %d in system %d subsystem %d",
-	       code, system, sub);
-      return buf;
+      static const char unk[] = "Unknown error ";
+      char *p = buf + sizeof buf;
+      size_t len = strlen (es->subsystem[sub].subsys_name);
+      *p-- = '\0';
+      p = _itoa (errnum, p, 16, 1);
+      *p-- = ' ';
+      p = memcpy (p - len, es->subsystem[sub].subsys_name, len);
+      return memcpy (p - sizeof unk - 1, unk, sizeof unk - 1);
     }
 
   return (char *) es->subsystem[sub].codes[code];