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 $(&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 < Syntax Error @@ -1007,7 +1011,7 @@ else rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < 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 <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 #include #include #include #include +#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];