Changes from Paul Kranenburg which bring us into sync with his sources:
authorPaul Richards <paul@isl.cf.ac.uk>
Wed, 15 Jun 1994 22:41:19 +0000 (22:41 +0000)
committerPaul Richards <paul@isl.cf.ac.uk>
Wed, 15 Jun 1994 22:41:19 +0000 (22:41 +0000)
 handling of errors through the standard err() and warn()
 more fixes for Geoff Rehmet's NULL pointer bug.
 fixes NULL pointer bugs when linking mono and nested X servers.
 supports a `-nostdlib' option.
 accept object files without a symbol table
 don't attempt dynamic linking when `-A' is given

a few variable names have chaged (desc -> fd), and the formatting has
changed which should make it much easier to track his sources.

I tested 'make world' for /usr/src and X twice with these changes.

18 files changed:
gnu/usr.bin/ld/etc.c
gnu/usr.bin/ld/i386/md.c
gnu/usr.bin/ld/i386/md.h
gnu/usr.bin/ld/i386/mdprologue.S
gnu/usr.bin/ld/ld.1
gnu/usr.bin/ld/ld.c
gnu/usr.bin/ld/ld.h
gnu/usr.bin/ld/ldconfig/ldconfig.8
gnu/usr.bin/ld/ldconfig/ldconfig.c
gnu/usr.bin/ld/ldd/ldd.c
gnu/usr.bin/ld/lib.c
gnu/usr.bin/ld/rrs.c
gnu/usr.bin/ld/rtld/malloc.c
gnu/usr.bin/ld/rtld/rtld.c
gnu/usr.bin/ld/shlib.c
gnu/usr.bin/ld/sparc/md.c
gnu/usr.bin/ld/symbol.c
gnu/usr.bin/ld/warnings.c

index 2ddd50a..59e0a18 100644 (file)
 /*
 /*
- * $Id: etc.c,v 1.6 1993/12/11 11:58:22 jkh Exp $
+ * $Id: etc.c,v 1.7 1994/02/13 20:41:05 jkh Exp $
  */
 
  */
 
-#include <sys/param.h>
-#include <stdio.h>
+#include <err.h>
 #include <stdlib.h>
 #include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/file.h>
-#include <sys/time.h>
-#include <fcntl.h>
-#include <ar.h>
-#include <ranlib.h>
-#include <a.out.h>
-#include <stab.h>
 #include <string.h>
 #include <string.h>
-#if __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-
-#include "ld.h"
 
 /*
 
 /*
- * Report a nonfatal error.
+ * Like malloc but get fatal error if memory is exhausted.
  */
  */
-
-void
-#if __STDC__
-error(char *fmt, ...)
-#else
-error(fmt, va_alist)
-       char    *fmt;
-       va_dcl
-#endif
+void *
+xmalloc(size)
+       size_t size;
 {
 {
-       va_list ap;
-#if __STDC__
-       va_start(ap, fmt);
-#else
-       va_start(ap);
-#endif
-       (void)fprintf(stderr, "%s: ", progname);
-       (void)vfprintf(stderr, fmt, ap);
-       (void)fprintf(stderr, "\n");
-       va_end(ap);
+       register void   *result = (void *)malloc(size);
+
+       if (!result)
+               errx(1, "virtual memory exhausted");
+
+       return result;
 }
 
 }
 
-void   (*fatal_cleanup_hook)__P((void));
 /*
 /*
- * Report a fatal error.
+ * Like realloc but get fatal error if memory is exhausted.
  */
  */
-
-void
-#if __STDC__
-fatal(char *fmt, ...)
-#else
-fatal(fmt, va_alist)
-       char    *fmt;
-       va_dcl
-#endif
+void *
+xrealloc(ptr, size)
+       void *ptr;
+       size_t size;
 {
 {
-       va_list ap;
-#if __STDC__
-       va_start(ap, fmt);
-#else
-       va_start(ap);
-#endif
-       (void)fprintf(stderr, "%s: ", progname);
-       (void)vfprintf(stderr, fmt, ap);
-       (void)fprintf(stderr, "\n");
-       va_end(ap);
+       register void   *result;
 
 
-       if (fatal_cleanup_hook)
-               (*fatal_cleanup_hook)();
-       exit(1);
-}
+       if (ptr == NULL)
+               result = (void *)malloc(size);
+       else
+               result = (void *)realloc(ptr, size);
 
 
+       if (!result)
+               errx(1, "virtual memory exhausted");
+
+       return result;
+}
 
 /*
  * Return a newly-allocated string whose contents concatenate
  * the strings S1, S2, S3.
  */
 
 /*
  * Return a newly-allocated string whose contents concatenate
  * the strings S1, S2, S3.
  */
-
 char *
 concat(s1, s2, s3)
        const char *s1, *s2, *s3;
 {
 char *
 concat(s1, s2, s3)
        const char *s1, *s2, *s3;
 {
-       register int    len1 = strlen (s1),
-                       len2 = strlen (s2),
-                       len3 = strlen (s3);
+       register int    len1 = strlen(s1),
+                       len2 = strlen(s2),
+                       len3 = strlen(s3);
 
 
-       register char *result = (char *) xmalloc (len1 + len2 + len3 + 1);
+       register char *result = (char *)xmalloc(len1 + len2 + len3 + 1);
 
 
-       strcpy (result, s1);
-       strcpy (result + len1, s2);
-       strcpy (result + len1 + len2, s3);
+       strcpy(result, s1);
+       strcpy(result + len1, s2);
+       strcpy(result + len1 + len2, s3);
        result[len1 + len2 + len3] = 0;
 
        return result;
 }
 
        result[len1 + len2 + len3] = 0;
 
        return result;
 }
 
-/* Parse the string ARG using scanf format FORMAT, and return the result.
-   If it does not parse, report fatal error
-   generating the error message using format string ERROR and ARG as arg.  */
-
-int
-parse(arg, format, error)
-       char *arg, *format, *error;
-{
-       int x;
-       if (1 != sscanf (arg, format, &x))
-               fatal (error, arg);
-       return x;
-}
-
-/* Like malloc but get fatal error if memory is exhausted.  */
-
-void *
-xmalloc(size)
-       int size;
-{
-       register void   *result = (void *)malloc (size);
-
-       if (!result)
-               fatal ("virtual memory exhausted", 0);
-
-       return result;
-}
-
-/* Like realloc but get fatal error if memory is exhausted.  */
-
-void *
-xrealloc(ptr, size)
-       void *ptr;
-       int size;
-{
-       register void   *result;
-
-       if (ptr == NULL)
-               result = (void *)malloc (size);
-       else
-               result = (void *)realloc (ptr, size);
-
-       if (!result)
-               fatal ("virtual memory exhausted", 0);
-
-       return result;
-}
index 311a5f6..ce61355 100644 (file)
@@ -14,7 +14,7 @@
  *    must display the following acknowledgement:
  *      This product includes software developed by Paul Kranenburg.
  * 4. The name of the author may not be used to endorse or promote products
  *    must display the following acknowledgement:
  *      This product includes software developed by Paul Kranenburg.
  * 4. The name of the author may not be used to endorse or promote products
- *    derived from this software withough specific prior written permission
+ *    derived from this software without specific prior written permission
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- *     $Id: md.c,v 1.8 1994/01/19 15:00:37 davidg Exp $
+ *     $Id: md.c,v 1.9 1994/02/13 20:42:09 jkh Exp $
  */
 
 #include <sys/param.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/types.h>
  */
 
 #include <sys/param.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/types.h>
+#include <err.h>
 #include <fcntl.h>
 #include <a.out.h>
 #include <stab.h>
 #include <fcntl.h>
 #include <a.out.h>
 #include <stab.h>
@@ -53,14 +54,13 @@ unsigned char               *addr;
        switch (RELOC_TARGET_SIZE(rp)) {
        case 0:
                return get_byte(addr);
        switch (RELOC_TARGET_SIZE(rp)) {
        case 0:
                return get_byte(addr);
-               break;
        case 1:
                return get_short(addr);
        case 1:
                return get_short(addr);
-               break;
        case 2:
                return get_long(addr);
        case 2:
                return get_long(addr);
-               break;
        }
        }
+       errx(1, "Unsupported relocation size: %x", RELOC_TARGET_SIZE(rp));
+       return 0;
 }
 
 /*
 }
 
 /*
@@ -71,20 +71,20 @@ md_relocate(rp, relocation, addr, relocatable_output)
 struct relocation_info *rp;
 long                   relocation;
 unsigned char          *addr;
 struct relocation_info *rp;
 long                   relocation;
 unsigned char          *addr;
+int                    relocatable_output;
 {
        switch (RELOC_TARGET_SIZE(rp)) {
        case 0:
                put_byte(addr, relocation);
 {
        switch (RELOC_TARGET_SIZE(rp)) {
        case 0:
                put_byte(addr, relocation);
-               break;
+               return;
        case 1:
                put_short(addr, relocation);
        case 1:
                put_short(addr, relocation);
-               break;
+               return;
        case 2:
                put_long(addr, relocation);
        case 2:
                put_long(addr, relocation);
-               break;
-       default:
-               fatal("Unsupported relocation size: %x", RELOC_TARGET_SIZE(rp));
+               return;
        }
        }
+       errx(1, "Unsupported relocation size: %x", RELOC_TARGET_SIZE(rp));
 }
 
 /*
 }
 
 /*
index bbb28f2..1209aee 100644 (file)
@@ -14,7 +14,7 @@
  *    must display the following acknowledgement:
  *      This product includes software developed by Paul Kranenburg.
  * 4. The name of the author may not be used to endorse or promote products
  *    must display the following acknowledgement:
  *      This product includes software developed by Paul Kranenburg.
  * 4. The name of the author may not be used to endorse or promote products
- *    derived from this software withough specific prior written permission
+ *    derived from this software without specific prior written permission
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -27,7 +27,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- *     $Id: md.h,v 1.8 1994/01/19 15:00:37 davidg Exp $
+ *     $Id: md.h,v 1.9 1994/02/13 20:42:11 jkh Exp $
  */
 
 
  */
 
 
index 23bcb03..6a582be 100644 (file)
@@ -14,7 +14,7 @@
  *    must display the following acknowledgement:
  *      This product includes software developed by Paul Kranenburg.
  * 4. The name of the author may not be used to endorse or promote products
  *    must display the following acknowledgement:
  *      This product includes software developed by Paul Kranenburg.
  * 4. The name of the author may not be used to endorse or promote products
- *    derived from this software withough specific prior written permission
+ *    derived from this software without specific prior written permission
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -27,7 +27,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- *     $Id: mdprologue.S,v 1.2 1993/11/09 04:19:18 paul Exp $
+ *     $Id: mdprologue.S,v 1.3 1993/12/10 10:16:00 jkh Exp $
  */
 
 /*
  */
 
 /*
index 56fa4ba..efbe7ee 100644 (file)
@@ -27,7 +27,7 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.\"    $Id: ld.1,v 1.5 1994/02/13 20:41:22 jkh Exp $
+.\"    $Id: ld.1,v 1.6 1994/03/09 14:28:02 davidg Exp $
 .\"
 .Dd October 14, 1993
 .Dt LD 8
 .\"
 .Dd October 14, 1993
 .Dt LD 8
@@ -103,6 +103,11 @@ Force all members of archives to be loaded, whether or not such members
 contribute a definition to any plain object files. Useful for making a
 shared library from an archive of PIC objects without having to unpack
 the archive.
 contribute a definition to any plain object files. Useful for making a
 shared library from an archive of PIC objects without having to unpack
 the archive.
+.It Fl B Ar silly
+Search for
+.Em \.sa
+silly archive companions of shared objects. Useful for compatibility with
+version 3 shared objects.
 .It Fl D Ar data-size
 Set the size of the data segment. For sanity's sake, this should be larger
 than the cumulative data sizes of the input files.
 .It Fl D Ar data-size
 Set the size of the data segment. For sanity's sake, this should be larger
 than the cumulative data sizes of the input files.
index d3ef9f5..3cb49d2 100644 (file)
@@ -32,26 +32,27 @@ static char sccsid[] = "@(#)ld.c    6.10 (Berkeley) 5/22/91";
    Set, indirect, and warning symbol features added by Randy Smith. */
 
 /*
    Set, indirect, and warning symbol features added by Randy Smith. */
 
 /*
- *     $Id: ld.c,v 1.20 1994/02/13 20:41:28 jkh Exp $
+ *     $Id: ld.c,v 1.21 1994/02/17 03:57:00 davidg Exp $
  */
    
 /* Define how to initialize system-dependent header fields.  */
 
 #include <sys/param.h>
  */
    
 /* Define how to initialize system-dependent header fields.  */
 
 #include <sys/param.h>
-#include <stdio.h>
-#include <stdlib.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/file.h>
 #include <sys/time.h>
 #include <sys/resource.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/file.h>
 #include <sys/time.h>
 #include <sys/resource.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <err.h>
 #include <fcntl.h>
 #include <ar.h>
 #include <ranlib.h>
 #include <a.out.h>
 #include <stab.h>
 #include <string.h>
 #include <fcntl.h>
 #include <ar.h>
 #include <ranlib.h>
 #include <a.out.h>
 #include <stab.h>
 #include <string.h>
-#include <strings.h>
 
 #include "ld.h"
 
 
 #include "ld.h"
 
@@ -88,6 +89,9 @@ int   page_align_segments;
 /* 1 => data segment must be page aligned, even if `-n' or `-N' */
 int    page_align_data;
 
 /* 1 => data segment must be page aligned, even if `-n' or `-N' */
 int    page_align_data;
 
+/* 1 => do not use standard library search path */
+int    nostdlib;
+
 /* Version number to put in __DYNAMIC (set by -V) */
 int    soversion;
 
 /* Version number to put in __DYNAMIC (set by -V) */
 int    soversion;
 
@@ -137,15 +141,17 @@ int               magic;                  /* Output file magic. */
 int            oldmagic;
 int            relocatable_output;     /* `-r'-ed output */
 
 int            oldmagic;
 int            relocatable_output;     /* `-r'-ed output */
 
-symbol         *entry_symbol;
-int            entry_offset;
+symbol         *entry_symbol;          /* specified by `-e' */
+int            entry_offset;           /* program entry if no `-e' given */
 
 int            page_size;              /* Size of a page (machine dependent) */
 
 
 int            page_size;              /* Size of a page (machine dependent) */
 
-/* Keep a list of any symbols referenced from the command line (so
-   that error messages for these guys can be generated). This list is
-   zero terminated. */
-struct glosym  **cmdline_references;
+/*
+ * Keep a list of any symbols referenced from the command line (so
+ * that error messages for these guys can be generated). This list is
+ * zero terminated.
+ */
+symbol         **cmdline_references;
 int            cl_refs_allocated;
 
 /*
 int            cl_refs_allocated;
 
 /*
@@ -246,20 +252,16 @@ static void       write_data __P((void));
 static void    write_rel __P((void));
 static void    write_syms __P((void));
 static void    assign_symbolnums __P((struct file_entry *, int *));
 static void    write_rel __P((void));
 static void    write_syms __P((void));
 static void    assign_symbolnums __P((struct file_entry *, int *));
-static void    myfatal __P((void));
+static void    cleanup __P((void));
+static int     parse __P((char *, char *, char *));
 
 
 int
 main(argc, argv)
 
 
 int
 main(argc, argv)
-       char          **argv;
        int             argc;
        int             argc;
+       char    *argv[];
 {
 
 {
 
-       if ((progname = strrchr(argv[0], '/')) == NULL)
-               progname = argv[0];
-       else
-               progname++;
-
        /* Added this to stop ld core-dumping on very large .o files.    */
 #ifdef RLIMIT_STACK
        /* Get rid of any avoidable limit on stack size.  */
        /* Added this to stop ld core-dumping on very large .o files.    */
 #ifdef RLIMIT_STACK
        /* Get rid of any avoidable limit on stack size.  */
@@ -267,9 +269,13 @@ main(argc, argv)
                struct rlimit   rlim;
 
                /* Set the stack limit huge so that alloca does not fail. */
                struct rlimit   rlim;
 
                /* Set the stack limit huge so that alloca does not fail. */
-               getrlimit(RLIMIT_STACK, &rlim);
+               if (getrlimit(RLIMIT_STACK, &rlim) != 0)
+                       warn("getrlimit");
+               else {
                rlim.rlim_cur = rlim.rlim_max;
                rlim.rlim_cur = rlim.rlim_max;
-               setrlimit(RLIMIT_STACK, &rlim);
+                       if (setrlimit(RLIMIT_STACK, &rlim) != 0)
+                               warn("setrlimit");
+               }
        }
 #endif /* RLIMIT_STACK */
 
        }
 #endif /* RLIMIT_STACK */
 
@@ -321,9 +327,8 @@ main(argc, argv)
 
        /* Keep a list of symbols referenced from the command line */
        cl_refs_allocated = 10;
 
        /* Keep a list of symbols referenced from the command line */
        cl_refs_allocated = 10;
-       cmdline_references
-               = (struct glosym **) xmalloc(cl_refs_allocated
-                                            * sizeof(struct glosym *));
+       cmdline_references = (symbol **)
+               xmalloc(cl_refs_allocated * sizeof(symbol *));
        *cmdline_references = 0;
 
        /* Completely decode ARGV.  */
        *cmdline_references = 0;
 
        /* Completely decode ARGV.  */
@@ -333,7 +338,7 @@ main(argc, argv)
                (!relocatable_output && (link_mode & SHAREABLE));
 
        if (building_shared_object && entry_symbol) {
                (!relocatable_output && (link_mode & SHAREABLE));
 
        if (building_shared_object && entry_symbol) {
-               fatal("`-Bshareable' and `-e' options are mutually exclusive");
+               errx(1,"`-Bshareable' and `-e' options are mutually exclusive");
        }
 
        /* Create the symbols `etext', `edata' and `end'.  */
        }
 
        /* Create the symbols `etext', `edata' and `end'.  */
@@ -347,6 +352,7 @@ main(argc, argv)
         * and initialize the text size accordingly. This depends on the kind
         * of system and on the output format selected.
         */
         * and initialize the text size accordingly. This depends on the kind
         * of system and on the output format selected.
         */
+
        if (magic == ZMAGIC || magic == QMAGIC)
                page_align_segments = 1;
 
        if (magic == ZMAGIC || magic == QMAGIC)
                page_align_segments = 1;
 
@@ -454,7 +460,6 @@ decode_command(argc, argv)
 {
        register int    i;
        register struct file_entry *p;
 {
        register int    i;
        register struct file_entry *p;
-       char           *cp;
 
        number_of_files = 0;
        output_filename = "a.out";
 
        number_of_files = 0;
        output_filename = "a.out";
@@ -469,7 +474,7 @@ decode_command(argc, argv)
                register int    code = classify_arg(argv[i]);
                if (code) {
                        if (i + code > argc)
                register int    code = classify_arg(argv[i]);
                if (code) {
                        if (i + code > argc)
-                               fatal("no argument following %s\n", argv[i]);
+                               errx(1, "no argument following %s", argv[i]);
 
                        decode_option(argv[i], argv[i + 1]);
 
 
                        decode_option(argv[i], argv[i + 1]);
 
@@ -482,7 +487,7 @@ decode_command(argc, argv)
        }
 
        if (!number_of_files)
        }
 
        if (!number_of_files)
-               fatal("no input files");
+               errx(1, "no input files");
 
        p = file_table = (struct file_entry *)
                        xmalloc(number_of_files * sizeof(struct file_entry));
 
        p = file_table = (struct file_entry *)
                        xmalloc(number_of_files * sizeof(struct file_entry));
@@ -526,10 +531,11 @@ decode_command(argc, argv)
                }
                if (argv[i][1] == 'A') {
                        if (p != file_table)
                }
                if (argv[i][1] == 'A') {
                        if (p != file_table)
-                               fatal("-A specified before an input file other than the first");
+                               errx(1, "-A specified before an input file other than the first");
                        p->filename = string;
                        p->local_sym_name = string;
                        p->flags |= E_JUST_SYMS;
                        p->filename = string;
                        p->local_sym_name = string;
                        p->flags |= E_JUST_SYMS;
+                       link_mode &= ~DYNAMIC;
                        p++;
                }
                if (argv[i][1] == 'l') {
                        p++;
                }
                if (argv[i][1] == 'l') {
@@ -545,12 +551,14 @@ decode_command(argc, argv)
 
        /* Now check some option settings for consistency.  */
 
 
        /* Now check some option settings for consistency.  */
 
-       if (page_align_segments
-               && (text_start - text_start_alignment) & (page_size - 1))
-               fatal("-T argument not multiple of page size, with sharable output");
+       if (page_align_segments &&
+           (text_start - text_start_alignment) & (page_size - 1))
+               errx(1, "-T argument not multiple of page size, with sharable output");
 
        /* Append the standard search directories to the user-specified ones. */
 
        /* Append the standard search directories to the user-specified ones. */
-       std_search_dirs(getenv("LD_LIBRARY_PATH"));
+       add_search_path(getenv("LD_LIBRARY_PATH"));
+       if (!nostdlib && getenv("LD_NOSTD_PATH") == NULL)
+               std_search_path();
 }
 
 void
 }
 
 void
@@ -567,13 +575,13 @@ add_cmdline_ref(sp)
                int diff = ptr - cmdline_references;
 
                cl_refs_allocated *= 2;
                int diff = ptr - cmdline_references;
 
                cl_refs_allocated *= 2;
-               cmdline_references = (struct glosym **)
+               cmdline_references = (symbol **)
                        xrealloc(cmdline_references,
                        xrealloc(cmdline_references,
-                              cl_refs_allocated * sizeof(struct glosym *));
+                              cl_refs_allocated * sizeof(symbol *));
                ptr = cmdline_references + diff;
        }
        *ptr++ = sp;
                ptr = cmdline_references + diff;
        }
        *ptr++ = sp;
-       *ptr = (symbol *) 0;
+       *ptr = (symbol *)0;
 }
 
 int
 }
 
 int
@@ -634,6 +642,10 @@ decode_option(swt, arg)
                force_executable = 1;
                return;
        }
                force_executable = 1;
                return;
        }
+       if (!strcmp(swt + 1, "nostdlib")) {
+               nostdlib = 1;
+               return;
+       }
        if (swt[2] != 0)
                arg = &swt[2];
 
        if (swt[2] != 0)
                arg = &swt[2];
 
@@ -646,12 +658,12 @@ decode_option(swt, arg)
                return;
 
        case 'd':
                return;
 
        case 'd':
-               if (*arg == 'c')
+               if (swt[2] == 0 || *arg == 'c')
                        force_common_definition = 1;
                else if (*arg == 'p')
                        force_alias_definition = 1;
                else
                        force_common_definition = 1;
                else if (*arg == 'p')
                        force_alias_definition = 1;
                else
-                       fatal("-d option takes 'c' or 'p' argument");
+                       errx(1, "-d option takes 'c' or 'p' argument");
                return;
 
        case 'e':
                return;
 
        case 'e':
@@ -767,7 +779,7 @@ decode_option(swt, arg)
                return;
 
        default:
                return;
 
        default:
-               fatal("invalid command option `%s'", swt);
+               errx(1, "invalid command option `%s'", swt);
        }
 }
 \f
        }
 }
 \f
@@ -783,8 +795,8 @@ decode_option(swt, arg)
 
 void
 each_file(function, arg)
 
 void
 each_file(function, arg)
-       register void   (*function) ();
-       register int    arg;
+       register void   (*function)();
+       register void   *arg;
 {
        register int    i;
 
 {
        register int    i;
 
@@ -796,29 +808,29 @@ each_file(function, arg)
                        continue;
 
                if (!(entry->flags & E_IS_LIBRARY))
                        continue;
 
                if (!(entry->flags & E_IS_LIBRARY))
-                       (*function) (entry, arg);
+                       (*function)(entry, arg);
 
                subentry = entry->subfiles;
                for (; subentry; subentry = subentry->chain) {
                        if (subentry->flags & E_SCRAPPED)
                                continue;
 
                subentry = entry->subfiles;
                for (; subentry; subentry = subentry->chain) {
                        if (subentry->flags & E_SCRAPPED)
                                continue;
-                       (*function) (subentry, arg);
+                       (*function)(subentry, arg);
                }
 
 #ifdef SUN_COMPAT
                if (entry->silly_archive) {
 
                        if (!(entry->flags & E_DYNAMIC))
                }
 
 #ifdef SUN_COMPAT
                if (entry->silly_archive) {
 
                        if (!(entry->flags & E_DYNAMIC))
-                               error("Silly");
+                               warnx("Silly");
 
                        if (!(entry->silly_archive->flags & E_IS_LIBRARY))
 
                        if (!(entry->silly_archive->flags & E_IS_LIBRARY))
-                               error("Sillier");
+                               warnx("Sillier");
 
                        subentry = entry->silly_archive->subfiles;
                        for (; subentry; subentry = subentry->chain) {
                                if (subentry->flags & E_SCRAPPED)
                                        continue;
 
                        subentry = entry->silly_archive->subfiles;
                        for (; subentry; subentry = subentry->chain) {
                                if (subentry->flags & E_SCRAPPED)
                                        continue;
-                               (*function) (subentry, arg);
+                               (*function)(subentry, arg);
                        }
                }
 #endif
                        }
                }
 #endif
@@ -836,8 +848,8 @@ each_file(function, arg)
 
 unsigned long
 check_each_file(function, arg)
 
 unsigned long
 check_each_file(function, arg)
-       register unsigned long (*function) ();
-       register int    arg;
+       register unsigned long  (*function)();
+       register void           *arg;
 {
        register int    i;
        register unsigned long return_val;
 {
        register int    i;
        register unsigned long return_val;
@@ -851,10 +863,10 @@ check_each_file(function, arg)
                        for (; subentry; subentry = subentry->chain) {
                                if (subentry->flags & E_SCRAPPED)
                                        continue;
                        for (; subentry; subentry = subentry->chain) {
                                if (subentry->flags & E_SCRAPPED)
                                        continue;
-                               if (return_val = (*function) (subentry, arg))
+                               if (return_val = (*function)(subentry, arg))
                                        return return_val;
                        }
                                        return return_val;
                        }
-               } else if (return_val = (*function) (entry, arg))
+               } else if (return_val = (*function)(entry, arg))
                        return return_val;
        }
        return 0;
                        return return_val;
        }
        return 0;
@@ -864,8 +876,8 @@ check_each_file(function, arg)
 
 void
 each_full_file(function, arg)
 
 void
 each_full_file(function, arg)
-       register void   (*function) ();
-       register int    arg;
+       register void   (*function)();
+       register void   *arg;
 {
        register int    i;
 
 {
        register int    i;
 
@@ -880,16 +892,16 @@ each_full_file(function, arg)
                if (entry->silly_archive) {
 
                        if (!(entry->flags & E_DYNAMIC))
                if (entry->silly_archive) {
 
                        if (!(entry->flags & E_DYNAMIC))
-                               error("Silly");
+                               warnx("Silly");
 
                        if (!(entry->silly_archive->flags & E_IS_LIBRARY))
 
                        if (!(entry->silly_archive->flags & E_IS_LIBRARY))
-                               error("Sillier");
+                               warnx("Sillier");
 
                        subentry = entry->silly_archive->subfiles;
                        for (; subentry; subentry = subentry->chain) {
                                if (subentry->flags & E_SCRAPPED)
                                        continue;
 
                        subentry = entry->silly_archive->subfiles;
                        for (; subentry; subentry = subentry->chain) {
                                if (subentry->flags & E_SCRAPPED)
                                        continue;
-                               (*function) (subentry, arg);
+                               (*function)(subentry, arg);
                        }
                }
 #endif
                        }
                }
 #endif
@@ -897,13 +909,13 @@ each_full_file(function, arg)
                        continue;
 
                if (!(entry->flags & E_IS_LIBRARY))
                        continue;
 
                if (!(entry->flags & E_IS_LIBRARY))
-                       (*function) (entry, arg);
+                       (*function)(entry, arg);
 
                subentry = entry->subfiles;
                for (; subentry; subentry = subentry->chain) {
                        if (subentry->flags & E_SCRAPPED)
                                continue;
 
                subentry = entry->subfiles;
                for (; subentry; subentry = subentry->chain) {
                        if (subentry->flags & E_SCRAPPED)
                                continue;
-                       (*function) (subentry, arg);
+                       (*function)(subentry, arg);
                }
 
        }
                }
 
        }
@@ -925,36 +937,40 @@ file_close()
  * open is not actually done.
  */
 int
  * open is not actually done.
  */
 int
-file_open (entry)
+file_open(entry)
      register struct file_entry *entry;
 {
      register struct file_entry *entry;
 {
-       register int desc;
+       register int    fd;
 
        if (entry->superfile && (entry->superfile->flags & E_IS_LIBRARY))
 
        if (entry->superfile && (entry->superfile->flags & E_IS_LIBRARY))
-               return file_open (entry->superfile);
+               return file_open(entry->superfile);
 
        if (entry == input_file)
                return input_desc;
 
 
        if (entry == input_file)
                return input_desc;
 
-       if (input_file) file_close ();
+       if (input_file)
+               file_close();
 
        if (entry->flags & E_SEARCH_DIRS) {
 
        if (entry->flags & E_SEARCH_DIRS) {
-               desc = findlib(entry);
+               fd = findlib(entry);
        } else
        } else
-               desc = open (entry->filename, O_RDONLY, 0);
+               fd = open(entry->filename, O_RDONLY, 0);
 
 
-       if (desc > 0) {
+       if (fd > 0) {
                input_file = entry;
                input_file = entry;
-               input_desc = desc;
-               return desc;
+               input_desc = fd;
+               return fd;
        }
 
        }
 
-       perror_file (entry);
-       /* NOTREACHED */
+       if (entry->flags & E_SEARCH_DIRS)
+               errx(1, "%s: no match", entry->local_sym_name);
+       else
+               err(1, "%s", entry->filename);
+       return fd;
 }
 
 int
 }
 
 int
-text_offset (entry)
+text_offset(entry)
      struct file_entry *entry;
 {
        return entry->starting_offset + N_TXTOFF (entry->header);
      struct file_entry *entry;
 {
        return entry->starting_offset + N_TXTOFF (entry->header);
@@ -963,64 +979,68 @@ text_offset (entry)
 /*---------------------------------------------------------------------------*/
 
 /*
 /*---------------------------------------------------------------------------*/
 
 /*
- * Read a file's header into the proper place in the file_entry. DESC is the
+ * Read a file's header into the proper place in the file_entry. FD is the
  * descriptor on which the file is open. ENTRY is the file's entry.
  */
 void
  * descriptor on which the file is open. ENTRY is the file's entry.
  */
 void
-read_header (desc, entry)
-     int desc;
-     register struct file_entry *entry;
+read_header(fd, entry)
+       int     fd;
+       struct file_entry *entry;
 {
 {
-       register int len, mid;
+       register int len;
 
 
-       if (lseek (desc, entry->starting_offset, L_SET) !=
+       if (lseek(fd, entry->starting_offset, L_SET) !=
                                                entry->starting_offset)
                                                entry->starting_offset)
-               fatal_with_file("read_header: lseek failure ", entry);
+               err(1, "%s: read_header: lseek", get_file_name(entry));
 
 
-       len = read (desc, &entry->header, sizeof (struct exec));
+       len = read(fd, &entry->header, sizeof(struct exec));
        if (len != sizeof (struct exec))
        if (len != sizeof (struct exec))
-               fatal_with_file ("failure reading header of ", entry);
+               err(1, "%s: read_header: read", get_file_name(entry));
 
        md_swapin_exec_hdr(&entry->header);
 
        if (N_BADMAG (entry->header))
 
        md_swapin_exec_hdr(&entry->header);
 
        if (N_BADMAG (entry->header))
-               fatal_with_file ("bad magic number in ", entry);
+               errx(1, "%s: bad magic number", get_file_name(entry));
 
        if (N_BADMID(entry->header))
 
        if (N_BADMID(entry->header))
-               fatal_with_file ("non-native input file ", entry);
+               errx(1, "%s: non-native input file", get_file_name(entry));
 
        entry->flags |= E_HEADER_VALID;
 }
 
 /*
  * Read the symbols of file ENTRY into core. Assume it is already open, on
 
        entry->flags |= E_HEADER_VALID;
 }
 
 /*
  * Read the symbols of file ENTRY into core. Assume it is already open, on
- * descriptor DESC. Also read the length of the string table, which follows
+ * descriptor FD. Also read the length of the string table, which follows
  * the symbol table, but don't read the contents of the string table.
  */
 
 void
  * the symbol table, but don't read the contents of the string table.
  */
 
 void
-read_entry_symbols (desc, entry)
+read_entry_symbols(fd, entry)
      struct file_entry *entry;
      struct file_entry *entry;
-     int desc;
+       int fd;
 {
        int             str_size;
        struct nlist    *np;
        int             i;
 
        if (!(entry->flags & E_HEADER_VALID))
 {
        int             str_size;
        struct nlist    *np;
        int             i;
 
        if (!(entry->flags & E_HEADER_VALID))
-               read_header (desc, entry);
+               read_header(fd, entry);
 
 
-       np = (struct nlist *) alloca (entry->header.a_syms);
+       np = (struct nlist *)alloca(entry->header.a_syms);
        entry->nsymbols = entry->header.a_syms / sizeof(struct nlist);
        entry->nsymbols = entry->header.a_syms / sizeof(struct nlist);
+       if (entry->nsymbols == 0)
+               return;
+
        entry->symbols = (struct localsymbol *)
                xmalloc(entry->nsymbols * sizeof(struct localsymbol));
 
        entry->symbols = (struct localsymbol *)
                xmalloc(entry->nsymbols * sizeof(struct localsymbol));
 
-       if (lseek(desc, N_SYMOFF(entry->header) + entry->starting_offset, L_SET)
+       if (lseek(fd, N_SYMOFF(entry->header) + entry->starting_offset, L_SET)
                        != N_SYMOFF(entry->header) + entry->starting_offset)
                        != N_SYMOFF(entry->header) + entry->starting_offset)
-               fatal_with_file ("read_symbols(h): lseek failure ", entry);
+               err(1, "%s: read_symbols: lseek(syms) failed", get_file_name(entry));
 
 
-       if (entry->header.a_syms != read (desc, np, entry->header.a_syms))
-               fatal_with_file ("premature end of file in symbols of ", entry);
+       if (entry->header.a_syms != read(fd, np, entry->header.a_syms))
+               errx(1, "%s: read_symbols: premature end of file in symbols",
+                       get_file_name(entry));
 
        md_swapin_symbols(np, entry->header.a_syms / sizeof(struct nlist));
 
 
        md_swapin_symbols(np, entry->header.a_syms / sizeof(struct nlist));
 
@@ -1036,35 +1056,41 @@ read_entry_symbols (desc, entry)
 
        entry->strings_offset = N_STROFF(entry->header) +
                                        entry->starting_offset;
 
        entry->strings_offset = N_STROFF(entry->header) +
                                        entry->starting_offset;
-       if (lseek(desc, entry->strings_offset, 0) == (off_t)-1)
-               fatal_with_file ("read_symbols(s): lseek failure ", entry);
-       if (sizeof str_size != read (desc, &str_size, sizeof str_size))
-               fatal_with_file ("bad string table size in ", entry);
+       if (lseek(fd, entry->strings_offset, 0) == (off_t)-1)
+               err(1, "%s: read_symbols: lseek(strings) failed",
+                       get_file_name(entry));
+       if (sizeof str_size != read(fd, &str_size, sizeof str_size))
+               errx(1, "%s: read_symbols: cannot read string table size",
+                       get_file_name(entry));
 
        entry->string_size = md_swap_long(str_size);
 }
 
 /*
 
        entry->string_size = md_swap_long(str_size);
 }
 
 /*
- * Read the string table of file ENTRY into core. Assume it is already open,
- * on descriptor DESC.
+ * Read the string table of file ENTRY open on descriptor FD, into core.
  */
 void
  */
 void
-read_entry_strings (desc, entry)
+read_entry_strings(fd, entry)
      struct file_entry *entry;
      struct file_entry *entry;
-     int desc;
+       int fd;
 {
 {
-       int buffer;
+
+       if (entry->string_size == 0)
+               return;
 
        if (!(entry->flags & E_HEADER_VALID) || !entry->strings_offset)
 
        if (!(entry->flags & E_HEADER_VALID) || !entry->strings_offset)
-               fatal_with_file("internal error: cannot read string table for ",
-                                       entry);
+               errx(1, "%s: read_strings: string table unavailable",
+                       get_file_name(entry));
 
 
-       if (lseek (desc, entry->strings_offset, L_SET) != entry->strings_offset)
-               fatal_with_file ("read_strings: lseek failure ", entry);
+       if (lseek(fd, entry->strings_offset, L_SET) !=
+           entry->strings_offset)
+               err(1, "%s: read_strings: lseek",
+                       get_file_name(entry));
 
 
-       if (entry->string_size !=
-                       read (desc, entry->strings, entry->string_size))
-               fatal_with_file ("premature end of file in strings of ", entry);
+       if (read(fd, entry->strings, entry->string_size) !=
+           entry->string_size)
+               errx(1, "%s: read_strings: premature end of file in strings",
+                       get_file_name(entry));
 
        return;
 }
 
        return;
 }
@@ -1072,8 +1098,8 @@ read_entry_strings (desc, entry)
 /* Read in the relocation sections of ENTRY if necessary */
 
 void
 /* Read in the relocation sections of ENTRY if necessary */
 
 void
-read_entry_relocation (desc, entry)
-       int                     desc;
+read_entry_relocation(fd, entry)
+       int                     fd;
        struct file_entry       *entry;
 {
        register struct relocation_info *reloc;
        struct file_entry       *entry;
 {
        register struct relocation_info *reloc;
@@ -1087,14 +1113,15 @@ read_entry_relocation (desc, entry)
                pos = text_offset(entry) +
                                entry->header.a_text + entry->header.a_data;
 
                pos = text_offset(entry) +
                                entry->header.a_text + entry->header.a_data;
 
-               if (lseek(desc, pos, L_SET) != pos)
-                       fatal_with_file("read_reloc(t): lseek failure ", entry);
+               if (lseek(fd, pos, L_SET) != pos)
+                       err(1, "%s: read_reloc(text): lseek failed",
+                               get_file_name(entry));
+
+               if (read(fd, reloc, entry->header.a_trsize) !=
+                   entry->header.a_trsize)
+                       errx(1, "%s: read_reloc(text): premature EOF",
+                            get_file_name(entry));
 
 
-               if (entry->header.a_trsize !=
-                               read(desc, reloc, entry->header.a_trsize)) {
-                       fatal_with_file (
-                               "premature eof in text relocation of ", entry);
-               }
                md_swapin_reloc(reloc, entry->header.a_trsize / sizeof(*reloc));
                entry->textrel = reloc;
                entry->ntextrel = entry->header.a_trsize / sizeof(*reloc);
                md_swapin_reloc(reloc, entry->header.a_trsize / sizeof(*reloc));
                entry->textrel = reloc;
                entry->ntextrel = entry->header.a_trsize / sizeof(*reloc);
@@ -1109,14 +1136,15 @@ read_entry_relocation (desc, entry)
                pos = text_offset(entry) + entry->header.a_text +
                        entry->header.a_data + entry->header.a_trsize;
 
                pos = text_offset(entry) + entry->header.a_text +
                        entry->header.a_data + entry->header.a_trsize;
 
-               if (lseek(desc, pos, L_SET) != pos)
-                       fatal_with_file("read_reloc(d): lseek failure ", entry);
+               if (lseek(fd, pos, L_SET) != pos)
+                       err(1, "%s: read_reloc(data): lseek failed",
+                               get_file_name(entry));
+
+               if (read(fd, reloc, entry->header.a_drsize) !=
+                   entry->header.a_drsize)
+                       errx(1, "%s: read_reloc(data): premature EOF",
+                            get_file_name(entry));
 
 
-               if (entry->header.a_drsize !=
-                               read (desc, reloc, entry->header.a_drsize)) {
-                       fatal_with_file (
-                               "premature eof in data relocation of ", entry);
-               }
                md_swapin_reloc(reloc, entry->header.a_drsize / sizeof(*reloc));
                entry->datarel = reloc;
                entry->ndatarel = entry->header.a_drsize / sizeof(*reloc);
                md_swapin_reloc(reloc, entry->header.a_drsize / sizeof(*reloc));
                entry->datarel = reloc;
                entry->ndatarel = entry->header.a_drsize / sizeof(*reloc);
@@ -1130,7 +1158,7 @@ read_entry_relocation (desc, entry)
  * Read in the symbols of all input files.
  */
 static void
  * Read in the symbols of all input files.
  */
 static void
-load_symbols ()
+load_symbols()
 {
        register int i;
 
 {
        register int i;
 
@@ -1141,7 +1169,7 @@ load_symbols ()
                read_file_symbols(&file_table[i]);
 
        if (trace_files)
                read_file_symbols(&file_table[i]);
 
        if (trace_files)
-               fprintf (stderr, "\n");
+               fprintf(stderr, "\n");
 }
 
 /*
 }
 
 /*
@@ -1151,55 +1179,57 @@ load_symbols ()
  */
 
 void
  */
 
 void
-read_file_symbols (entry)
+read_file_symbols(entry)
      register struct file_entry *entry;
 {
      register struct file_entry *entry;
 {
-       register int desc;
+       register int    fd;
        register int len;
        struct exec hdr;
 
        register int len;
        struct exec hdr;
 
-       desc = file_open (entry);
+       fd = file_open(entry);
 
 
-       len = read (desc, &hdr, sizeof hdr);
+       len = read(fd, &hdr, sizeof hdr);
        if (len != sizeof hdr)
        if (len != sizeof hdr)
-               fatal_with_file ("failure reading header of ", entry);
+               errx(1, "%s: read_file_symbols(header): premature EOF",
+                       get_file_name(entry));
 
        md_swapin_exec_hdr(&hdr);
 
        if (!N_BADMAG (hdr)) {
                if (N_IS_DYNAMIC(hdr) && !(entry->flags & E_JUST_SYMS)) {
                        if (relocatable_output) {
 
        md_swapin_exec_hdr(&hdr);
 
        if (!N_BADMAG (hdr)) {
                if (N_IS_DYNAMIC(hdr) && !(entry->flags & E_JUST_SYMS)) {
                        if (relocatable_output) {
-                               fatal_with_file(
-                       "-r and shared objects currently not supported ",
-                                       entry);
+                               errx(1,
+                       "%s: -r and shared objects currently not supported ",
+                                       get_file_name(entry));
                                return;
                        }
                        entry->flags |= E_DYNAMIC;
                        if (entry->superfile || rrs_add_shobj(entry))
                                return;
                        }
                        entry->flags |= E_DYNAMIC;
                        if (entry->superfile || rrs_add_shobj(entry))
-                               read_shared_object(desc, entry);
+                               read_shared_object(fd, entry);
                        else
                                entry->flags |= E_SCRAPPED;
                } else {
                        else
                                entry->flags |= E_SCRAPPED;
                } else {
-                       read_entry_symbols (desc, entry);
-                       entry->strings = (char *) alloca (entry->string_size);
-                       read_entry_strings (desc, entry);
-                       read_entry_relocation(desc, entry);
-                       enter_file_symbols (entry);
+                       read_entry_symbols(fd, entry);
+                       entry->strings = (char *)alloca (entry->string_size);
+                       read_entry_strings(fd, entry);
+                       read_entry_relocation(fd, entry);
+                       enter_file_symbols(entry);
                        entry->strings = 0;
                }
        } else {
                char armag[SARMAG];
 
                        entry->strings = 0;
                }
        } else {
                char armag[SARMAG];
 
-               lseek (desc, 0, 0);
-               if (SARMAG != read (desc, armag, SARMAG) ||
+               lseek (fd, 0, 0);
+               if (SARMAG != read(fd, armag, SARMAG) ||
                                        strncmp (armag, ARMAG, SARMAG))
                                        strncmp (armag, ARMAG, SARMAG))
-                       fatal_with_file(
-                       "malformed input file (not rel or archive) ", entry);
+                       errx(1,
+                            "%s: malformed input file (not rel or archive)",   
+                            get_file_name(entry));
                entry->flags |= E_IS_LIBRARY;
                entry->flags |= E_IS_LIBRARY;
-               search_library (desc, entry);
+               search_library(fd, entry);
        }
 
        }
 
-       file_close ();
+       file_close();
 }
 
 
 }
 
 
@@ -1208,12 +1238,13 @@ read_file_symbols (entry)
  */
 
 void
  */
 
 void
-enter_file_symbols (entry)
+enter_file_symbols(entry)
      struct file_entry *entry;
 {
        struct localsymbol      *lsp, *lspend;
 
      struct file_entry *entry;
 {
        struct localsymbol      *lsp, *lspend;
 
-       if (trace_files) prline_file_name (entry, stderr);
+       if (trace_files)
+               prline_file_name(entry, stderr);
 
        lspend = entry->symbols + entry->nsymbols;
 
 
        lspend = entry->symbols + entry->nsymbols;
 
@@ -1242,7 +1273,8 @@ enter_file_symbols (entry)
                        /* Grab the next entry.  */
                        p++;
                        if (p->n_type != (N_UNDF | N_EXT)) {
                        /* Grab the next entry.  */
                        p++;
                        if (p->n_type != (N_UNDF | N_EXT)) {
-                               error("Warning symbol found in %s without external reference following.",
+                               warnx(
+               "%s: Warning symbol without external reference following.",
                                        get_file_name(entry));
                                make_executable = 0;
                                p--;            /* Process normally.  */
                                        get_file_name(entry));
                                make_executable = 0;
                                p--;            /* Process normally.  */
@@ -1284,13 +1316,13 @@ enter_file_symbols (entry)
  */
 
 static void
  */
 
 static void
-enter_global_ref (lsp, name, entry)
+enter_global_ref(lsp, name, entry)
      struct localsymbol *lsp;
      char *name;
      struct file_entry *entry;
 {
        register struct nzlist *nzp = &lsp->nzlist;
      struct localsymbol *lsp;
      char *name;
      struct file_entry *entry;
 {
        register struct nzlist *nzp = &lsp->nzlist;
-       register symbol *sp = getsym (name);
+       register symbol *sp = getsym(name);
        register int type = nzp->nz_type;
        int oldref = (sp->flags & GS_REFERENCED);
        int olddef = sp->defined;
        register int type = nzp->nz_type;
        int oldref = (sp->flags & GS_REFERENCED);
        int olddef = sp->defined;
@@ -1299,7 +1331,7 @@ enter_global_ref (lsp, name, entry)
        if (type == (N_INDR | N_EXT)) {
                sp->alias = getsym(entry->strings + (lsp + 1)->nzlist.nz_strx);
                if (sp == sp->alias) {
        if (type == (N_INDR | N_EXT)) {
                sp->alias = getsym(entry->strings + (lsp + 1)->nzlist.nz_strx);
                if (sp == sp->alias) {
-                       error("%s: %s is alias for itself",
+                       warnx("%s: %s is alias for itself",
                                        get_file_name(entry), name);
                        /* Rewrite symbol as global text symbol with value 0 */
                        lsp->nzlist.nz_type = N_TEXT|N_EXT;
                                        get_file_name(entry), name);
                        /* Rewrite symbol as global text symbol with value 0 */
                        lsp->nzlist.nz_type = N_TEXT|N_EXT;
@@ -1356,7 +1388,7 @@ enter_global_ref (lsp, name, entry)
 
        if (sp == dynamic_symbol || sp == got_symbol) {
                if (type != (N_UNDF | N_EXT) && !(entry->flags & E_JUST_SYMS))
 
        if (sp == dynamic_symbol || sp == got_symbol) {
                if (type != (N_UNDF | N_EXT) && !(entry->flags & E_JUST_SYMS))
-                       fatal("Linker reserved symbol %s defined as type %x ",  
+                       errx(1,"Linker reserved symbol %s defined as type %x ", 
                                                name, type);
                return;
        }
                                                name, type);
                return;
        }
@@ -1383,6 +1415,10 @@ enter_global_ref (lsp, name, entry)
                         * It used to be undefined and we're defining it.
                         */
                        undefined_global_sym_count--;
                         * It used to be undefined and we're defining it.
                         */
                        undefined_global_sym_count--;
+                       if (undefined_global_sym_count < 0)
+                               errx(1,
+       "internal error: enter_glob_ref: undefined_global_sym_count = %d",
+                                       undefined_global_sym_count);
 
                if (!olddef && type == (N_UNDF | N_EXT) && nzp->nz_value) {
                        /*
 
                if (!olddef && type == (N_UNDF | N_EXT) && nzp->nz_value) {
                        /*
@@ -1449,9 +1485,9 @@ enter_global_ref (lsp, name, entry)
                        break;
                }
 
                        break;
                }
 
-               fprintf (stderr, "symbol %s %s in ", sp->name, reftype);
+               fprintf(stderr, "symbol %s %s in ", sp->name, reftype);
                print_file_name (entry, stderr);
                print_file_name (entry, stderr);
-               fprintf (stderr, "\n");
+               fprintf(stderr, "\n");
        }
 }
 
        }
 }
 
@@ -1462,7 +1498,7 @@ enter_global_ref (lsp, name, entry)
  */
 
 unsigned long
  */
 
 unsigned long
-contains_symbol (entry, np)
+contains_symbol(entry, np)
      struct file_entry *entry;
      register struct nlist *np;
 {
      struct file_entry *entry;
      register struct nlist *np;
 {
@@ -1505,7 +1541,7 @@ contains_symbol (entry, np)
  */
 
 static void
  */
 
 static void
-digest_symbols ()
+digest_symbols()
 {
 
        if (trace_files)
 {
 
        if (trace_files)
@@ -1528,10 +1564,10 @@ digest_symbols ()
        defined_global_sym_count = 0;
        digest_pass1();
 
        defined_global_sym_count = 0;
        digest_pass1();
 
-       each_full_file(consider_relocation, 0); /* Text */
-       each_full_file(consider_relocation, 1); /* Data */
+       each_full_file(consider_relocation, (void *)0); /* Text */
+       each_full_file(consider_relocation, (void *)1); /* Data */
 
 
-       each_file(consider_local_symbols, 0);
+       each_file(consider_local_symbols, (void *)0);
 
        /*
         * Compute total size of sections.
 
        /*
         * Compute total size of sections.
@@ -1570,7 +1606,7 @@ digest_symbols ()
        data_start = rrs_data_start + rrs_data_size;
        if (!relocatable_output) {
                set_sect_start = rrs_data_start + data_size;
        data_start = rrs_data_start + rrs_data_size;
        if (!relocatable_output) {
                set_sect_start = rrs_data_start + data_size;
-               data_size += set_sect_size;
+               data_size += MALIGN(set_sect_size);
        }
        bss_start = rrs_data_start + data_size;
 
        }
        bss_start = rrs_data_start + data_size;
 
@@ -1581,6 +1617,8 @@ printf("datastart = %#x, datasize = %#x, rrs_data_start %#x, rrs_data_size %#x\n
        data_start, data_size, rrs_data_start, rrs_data_size);
 printf("bssstart = %#x, bsssize = %#x\n",
        bss_start, bss_size);
        data_start, data_size, rrs_data_start, rrs_data_size);
 printf("bssstart = %#x, bsssize = %#x\n",
        bss_start, bss_size);
+printf("set_sect_start = %#x, set_sect_size = %#x\n",
+       set_sect_start, set_sect_size);
 #endif
 
        /* Compute start addresses of each file's sections and symbols.  */
 #endif
 
        /* Compute start addresses of each file's sections and symbols.  */
@@ -1679,6 +1717,9 @@ digest_pass1()
                        /* Superfluous symbol from shared object */
                        continue;
                }
                        /* Superfluous symbol from shared object */
                        continue;
                }
+               if (sp->so_defined)
+                       /* Already examined; must have been an alias */
+                       continue;
 
                if (sp == got_symbol || sp == dynamic_symbol)
                        continue;
 
                if (sp == got_symbol || sp == dynamic_symbol)
                        continue;
@@ -1689,7 +1730,7 @@ digest_pass1()
 
                        if (SET_ELEMENT_P(type)) {
                                if (relocatable_output)
 
                        if (SET_ELEMENT_P(type)) {
                                if (relocatable_output)
-                                       fatal(
+                                       errx(1,
                                "internal error: global ref to set el %s with -r",
                                                sp->name);
                                if (!defs++) {
                                "internal error: global ref to set el %s with -r",
                                                sp->name);
                                if (!defs++) {
@@ -1758,6 +1799,10 @@ digest_pass1()
                if (building_shared_object) {
                        /* Just punt for now */
                        undefined_global_sym_count--;
                if (building_shared_object) {
                        /* Just punt for now */
                        undefined_global_sym_count--;
+                       if (undefined_global_sym_count < 0)
+                               errx(1,
+       "internal error: digest_pass1,1: %s: undefined_global_sym_count = %d",
+                                       sp->name, undefined_global_sym_count);
                        continue;
                }
 
                        continue;
                }
 
@@ -1766,8 +1811,8 @@ digest_pass1()
                        register struct nlist *p = &lsp->nzlist.nlist;
                        register int    type = p->n_type;
 
                        register struct nlist *p = &lsp->nzlist.nlist;
                        register int    type = p->n_type;
 
-                       if ((type & N_EXT) && type != (N_UNDF | N_EXT)
-                                               && (type & N_TYPE) != N_FN) {
+                       if ((type & N_EXT) && type != (N_UNDF | N_EXT) &&
+                           (type & N_TYPE) != N_FN) {
                                /* non-common definition */
                                sp->def_nlist = p;
                                lsp->entry->flags |= E_SYMBOLS_USED;
                                /* non-common definition */
                                sp->def_nlist = p;
                                lsp->entry->flags |= E_SYMBOLS_USED;
@@ -1780,6 +1825,10 @@ digest_pass1()
 #ifdef DEBUG
 printf("shr: %s gets defined to %x with value %x\n", sp->name, type, sp->value);
 #endif
 #ifdef DEBUG
 printf("shr: %s gets defined to %x with value %x\n", sp->name, type, sp->value);
 #endif
+                               if (undefined_global_sym_count < 0)
+                                       errx(1,
+               "internal error: digest_pass1,2: %s: undefined_global_sym_count = %d",
+                                       sp->name, undefined_global_sym_count);
                                if (sp->alias && !(sp->alias->flags & GS_REFERENCED)) {
                                        sp = sp->alias;
                                        goto again;
                                if (sp->alias && !(sp->alias->flags & GS_REFERENCED)) {
                                        sp = sp->alias;
                                        goto again;
@@ -1790,7 +1839,7 @@ printf("shr: %s gets defined to %x with value %x\n", sp->name, type, sp->value);
        } END_EACH_SYMBOL;
 
        if (setv_fill_count != set_sect_size/sizeof(long))
        } END_EACH_SYMBOL;
 
        if (setv_fill_count != set_sect_size/sizeof(long))
-               fatal("internal error: allocated set symbol space (%d) \
+               errx(1, "internal error: allocated set symbol space (%d) \
 doesn't match actual (%d)",
                        set_sect_size/sizeof(long), setv_fill_count);
 }
 doesn't match actual (%d)",
                        set_sect_size/sizeof(long), setv_fill_count);
 }
@@ -1801,7 +1850,7 @@ doesn't match actual (%d)",
  * of the output file.
  */
 static void
  * of the output file.
  */
 static void
-consider_relocation (entry, dataseg)
+consider_relocation(entry, dataseg)
        struct file_entry       *entry;
        int                     dataseg;
 {
        struct file_entry       *entry;
        int                     dataseg;
 {
@@ -1863,6 +1912,10 @@ consider_relocation (entry, dataseg)
                        sp = lsp->symbol;
                        if (sp->alias)
                                sp = sp->alias;
                        sp = lsp->symbol;
                        if (sp->alias)
                                sp = sp->alias;
+                       if (sp->flags & GS_TRACE) {
+                               fprintf(stderr, "symbol %s has jmpslot in %s\n",
+                                               sp->name, get_file_name(entry));
+                       }
                        alloc_rrs_jmpslot(entry, sp);
 
                } else if (RELOC_BASEREL_P(reloc)) {
                        alloc_rrs_jmpslot(entry, sp);
 
                } else if (RELOC_BASEREL_P(reloc)) {
@@ -1892,8 +1945,8 @@ consider_relocation (entry, dataseg)
                        lsp = &entry->symbols[reloc->r_symbolnum];
                        sp = lsp->symbol;
                        if (sp == NULL)
                        lsp = &entry->symbols[reloc->r_symbolnum];
                        sp = lsp->symbol;
                        if (sp == NULL)
-                               fatal_with_file(
-                                       "internal error, sp==NULL", entry);
+                               errx(1, "%s: internal error, sp==NULL",
+                                       get_file_name(entry));
 
                        if (sp->alias)
                                sp = sp->alias;
 
                        if (sp->alias)
                                sp = sp->alias;
@@ -1903,8 +1956,9 @@ consider_relocation (entry, dataseg)
                         */
                        if (sp == got_symbol) {
                                if (!CHECK_GOT_RELOC(reloc))
                         */
                        if (sp == got_symbol) {
                                if (!CHECK_GOT_RELOC(reloc))
-                                       fatal_with_file(
-                                       "Unexpected relocation type ", entry);
+                                       errx(1,
+                               "%s: Unexpected relocation type for GOT symbol",
+                                       get_file_name(entry));
                                continue;
                        }
 
                                continue;
                        }
 
@@ -1913,6 +1967,11 @@ consider_relocation (entry, dataseg)
                         */
 
                        if (building_shared_object) {
                         */
 
                        if (building_shared_object) {
+                               if (sp->flags & GS_TRACE) {
+                                       fprintf(stderr,
+                                           "symbol %s RRS entry in %s\n",
+                                           sp->name, get_file_name(entry));
+                               }
                                alloc_rrs_reloc(entry, sp);
                                continue;
                        }
                                alloc_rrs_reloc(entry, sp);
                                continue;
                        }
@@ -1939,7 +1998,7 @@ consider_relocation (entry, dataseg)
                         * Prepare an RRS relocation as these are load
                         * address dependent.
                         */
                         * Prepare an RRS relocation as these are load
                         * address dependent.
                         */
-                       if (building_shared_object) {
+                       if (building_shared_object && !RELOC_PCREL_P(reloc)) {
                                alloc_rrs_segment_reloc(entry, reloc);
                        }
                }
                                alloc_rrs_segment_reloc(entry, reloc);
                        }
                }
@@ -2021,7 +2080,7 @@ consider_local_symbols(entry)
  * the output file.
  */
 static void
  * the output file.
  */
 static void
-consider_file_section_lengths (entry)
+consider_file_section_lengths(entry)
      register struct file_entry *entry;
 {
 
      register struct file_entry *entry;
 {
 
@@ -2043,7 +2102,7 @@ consider_file_section_lengths (entry)
  * Also relocate the addresses of the file's local and debugger symbols.
  */
 static void
  * Also relocate the addresses of the file's local and debugger symbols.
  */
 static void
-relocate_file_addresses (entry)
+relocate_file_addresses(entry)
      register struct file_entry *entry;
 {
        register struct localsymbol     *lsp, *lspend;
      register struct file_entry *entry;
 {
        register struct localsymbol     *lsp, *lspend;
@@ -2092,8 +2151,9 @@ printf("%s: datastart: %#x, bss %#x\n", get_file_name(entry),
                case N_BSS:
                case N_SETB:
                        /* likewise for symbols with value in BSS.  */
                case N_BSS:
                case N_SETB:
                        /* likewise for symbols with value in BSS.  */
-                       p->n_value += entry->bss_start_address
-                               - entry->header.a_text - entry->header.a_data;
+                       p->n_value += entry->bss_start_address -
+                                     (entry->header.a_text +
+                                     entry->header.a_data);
                break;
                }
 
                break;
                }
 
@@ -2194,14 +2254,14 @@ digest_pass2()
                         * It's a common.
                         */
                        if (sp->defined != (N_UNDF + N_EXT))
                         * It's a common.
                         */
                        if (sp->defined != (N_UNDF + N_EXT))
-                               fatal("%s: common isn't", sp->name);
+                               errx(1, "%s: common isn't", sp->name);
 
                } else if ((size = sp->size) != 0 && sp->defined == N_SIZE) {
                        /*
                         * It's data from shared object with size info.
                         */
                        if (!sp->so_defined)
 
                } else if ((size = sp->size) != 0 && sp->defined == N_SIZE) {
                        /*
                         * It's data from shared object with size info.
                         */
                        if (!sp->so_defined)
-                               fatal("%s: Bogus N_SIZE item", sp->name);
+                               errx(1, "%s: Bogus N_SIZE item", sp->name);
 
                } else
                        /*
 
                } else
                        /*
@@ -2257,62 +2317,64 @@ digest_pass2()
 
 /* Write the output file */
 void
 
 /* Write the output file */
 void
-write_output ()
+write_output()
 {
        struct stat     statbuf;
        int             filemode;
 
 {
        struct stat     statbuf;
        int             filemode;
 
-       if (lstat(output_filename, &statbuf) != -1) {
-               if (!S_ISDIR(statbuf.st_mode))
+       if (lstat(output_filename, &statbuf) == 0) {
+               if (S_ISREG(statbuf.st_mode))
                        (void)unlink(output_filename);
        }
 
                        (void)unlink(output_filename);
        }
 
-       outdesc = open (output_filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
+       outdesc = open(output_filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
        if (outdesc < 0)
        if (outdesc < 0)
-               perror_name (output_filename);
+               err(1, "open: %s", output_filename);
 
 
-       fatal_cleanup_hook = myfatal;
+       if (atexit(cleanup))
+               err(1, "atexit");
 
        if (fstat (outdesc, &statbuf) < 0)
 
        if (fstat (outdesc, &statbuf) < 0)
-               perror_name (output_filename);
+               err(1, "fstat: %s", output_filename);
 
        filemode = statbuf.st_mode;
 
        chmod (output_filename, filemode & ~0111);
 
        /* Output the a.out header.  */
 
        filemode = statbuf.st_mode;
 
        chmod (output_filename, filemode & ~0111);
 
        /* Output the a.out header.  */
-       write_header ();
+       write_header();
 
        /* Output the text and data segments, relocating as we go.  */
 
        /* Output the text and data segments, relocating as we go.  */
-       write_text ();
-       write_data ();
+       write_text();
+       write_data();
 
        /* Output the merged relocation info, if requested with `-r'.  */
        if (relocatable_output)
 
        /* Output the merged relocation info, if requested with `-r'.  */
        if (relocatable_output)
-               write_rel ();
+               write_rel();
 
        /* Output the symbol table (both globals and locals).  */
 
        /* Output the symbol table (both globals and locals).  */
-       write_syms ();
+       write_syms();
 
        /* Output the RSS section */
 
        /* Output the RSS section */
-       write_rrs ();
-
-       close (outdesc);
+       write_rrs();
 
        if (chmod (output_filename, filemode | 0111) == -1)
 
        if (chmod (output_filename, filemode | 0111) == -1)
-               perror_name (output_filename);
+               err(1, "chmod: %s", output_filename);
+
+       close(outdesc);
+       outdesc = 0;
 }
 
 /* Total number of symbols to be written in the output file. */
 static int     nsyms;
 
 void
 }
 
 /* Total number of symbols to be written in the output file. */
 static int     nsyms;
 
 void
-write_header ()
+write_header()
 {
        int flags = (rrs_section_type == RRS_FULL) ? EX_DYNAMIC : 0;
 
        if (oldmagic && (flags & EX_DYNAMIC))
 {
        int flags = (rrs_section_type == RRS_FULL) ? EX_DYNAMIC : 0;
 
        if (oldmagic && (flags & EX_DYNAMIC))
-               error("Cannot set flag in old magic headers\n");
+               warnx("Cannot set flag in old magic headers\n");
 
        N_SET_FLAG (outheader, flags);
 
 
        N_SET_FLAG (outheader, flags);
 
@@ -2341,7 +2403,7 @@ write_header ()
        }
 
        md_swapout_exec_hdr(&outheader);
        }
 
        md_swapout_exec_hdr(&outheader);
-       mywrite (&outheader, sizeof (struct exec), 1, outdesc);
+       mywrite(&outheader, sizeof (struct exec), 1, outdesc);
        md_swapin_exec_hdr(&outheader);
 
        /*
        md_swapin_exec_hdr(&outheader);
 
        /*
@@ -2350,27 +2412,28 @@ write_header ()
         */
 
 #ifndef COFF_ENCAPSULATE
         */
 
 #ifndef COFF_ENCAPSULATE
-       padfile (N_TXTOFF(outheader) - sizeof outheader, outdesc);
+       padfile(N_TXTOFF(outheader) - sizeof outheader, outdesc);
 #endif
 }
 \f
 #endif
 }
 \f
-/* Relocate the text segment of each input file
-   and write to the output file.  */
-
+/*
+ * Relocate the text segment of each input file
+ * and write to the output file.
+ */
 void
 void
-write_text ()
+write_text()
 {
 
        if (trace_files)
 {
 
        if (trace_files)
-               fprintf (stderr, "Copying and relocating text:\n\n");
+               fprintf(stderr, "Copying and relocating text:\n\n");
 
 
-       each_full_file (copy_text, 0);
-       file_close ();
+       each_full_file(copy_text, 0);
+       file_close();
 
        if (trace_files)
 
        if (trace_files)
-               fprintf (stderr, "\n");
+               fprintf(stderr, "\n");
 
 
-       padfile (text_pad, outdesc);
+       padfile(text_pad, outdesc);
 }
 
 /*
 }
 
 /*
@@ -2379,55 +2442,57 @@ write_text ()
  * reuse.
  */
 void
  * reuse.
  */
 void
-copy_text (entry)
+copy_text(entry)
      struct file_entry *entry;
 {
        register char *bytes;
      struct file_entry *entry;
 {
        register char *bytes;
-       register int desc;
+       register int    fd;
 
        if (trace_files)
 
        if (trace_files)
-               prline_file_name (entry, stderr);
+               prline_file_name(entry, stderr);
 
 
-       desc = file_open (entry);
+       fd = file_open(entry);
 
        /* Allocate space for the file's text section */
 
        /* Allocate space for the file's text section */
-       bytes = (char *) alloca (entry->header.a_text);
+       bytes = (char *)alloca(entry->header.a_text);
 
        /* Deal with relocation information however is appropriate */
        if (entry->textrel == NULL)
 
        /* Deal with relocation information however is appropriate */
        if (entry->textrel == NULL)
-               fatal_with_file("no text relocation of ", entry);
+               errx(1, "%s: no text relocation", get_file_name(entry));
 
        /* Read the text section into core.  */
 
        /* Read the text section into core.  */
-       lseek (desc, text_offset (entry), 0);
-       if (entry->header.a_text != read (desc, bytes, entry->header.a_text))
-               fatal_with_file ("premature eof in text section of ", entry);
-
+       if (lseek(fd, text_offset(entry), L_SET) == (off_t)-1)
+               err(1, "%s: copy_text: lseek", get_file_name(entry));
+       if (entry->header.a_text != read(fd, bytes, entry->header.a_text))
+               errx(1, "%s: copy_text: premature EOF in text section", get_file_name(entry));
 
        /* Relocate the text according to the text relocation.  */
        perform_relocation (bytes, entry->header.a_text,
                        entry->textrel, entry->ntextrel, entry, 0);
 
        /* Write the relocated text to the output file.  */
 
        /* Relocate the text according to the text relocation.  */
        perform_relocation (bytes, entry->header.a_text,
                        entry->textrel, entry->ntextrel, entry, 0);
 
        /* Write the relocated text to the output file.  */
-       mywrite (bytes, 1, entry->header.a_text, outdesc);
+       mywrite(bytes, 1, entry->header.a_text, outdesc);
 }
 \f
 }
 \f
-/* Relocate the data segment of each input file
-   and write to the output file.  */
+/*
+ * Relocate the data segment of each input file
+ * and write to the output file.
+ */
 
 void
 
 void
-write_data ()
+write_data()
 {
 {
-       long    pos;
+       off_t   pos;
 
        if (trace_files)
 
        if (trace_files)
-               fprintf (stderr, "Copying and relocating data:\n\n");
+               fprintf(stderr, "Copying and relocating data:\n\n");
 
        pos = N_DATOFF(outheader) + data_start - rrs_data_start;
        if (lseek(outdesc, pos, L_SET) != pos)
 
        pos = N_DATOFF(outheader) + data_start - rrs_data_start;
        if (lseek(outdesc, pos, L_SET) != pos)
-               fatal("write_data: lseek: cant position data offset");
+               errx(1, "write_data: failed to lseek to data offset");
 
 
-       each_full_file (copy_data, 0);
-       file_close ();
+       each_full_file(copy_data, 0);
+       file_close();
 
        /*
         * Write out the set element vectors.  See digest symbols for
 
        /*
         * Write out the set element vectors.  See digest symbols for
@@ -2436,14 +2501,14 @@ write_data ()
 
        if (set_vector_count) {
                swap_longs(set_vectors, set_symbol_count + 2*set_vector_count);
 
        if (set_vector_count) {
                swap_longs(set_vectors, set_symbol_count + 2*set_vector_count);
-               mywrite (set_vectors, set_symbol_count + 2*set_vector_count,
+               mywrite(set_vectors, set_symbol_count + 2*set_vector_count,
                                sizeof (unsigned long), outdesc);
        }
 
        if (trace_files)
                                sizeof (unsigned long), outdesc);
        }
 
        if (trace_files)
-               fprintf (stderr, "\n");
+               fprintf(stderr, "\n");
 
 
-       padfile (data_pad, outdesc);
+       padfile(data_pad, outdesc);
 }
 
 /*
 }
 
 /*
@@ -2452,30 +2517,32 @@ write_data ()
  * reuse. See comments in `copy_text'.
  */
 void
  * reuse. See comments in `copy_text'.
  */
 void
-copy_data (entry)
+copy_data(entry)
      struct file_entry *entry;
 {
        register char *bytes;
      struct file_entry *entry;
 {
        register char *bytes;
-       register int desc;
+       register int    fd;
 
        if (trace_files)
                prline_file_name (entry, stderr);
 
 
        if (trace_files)
                prline_file_name (entry, stderr);
 
-       desc = file_open (entry);
+       fd = file_open(entry);
 
        bytes = (char *)alloca(entry->header.a_data);
 
        if (entry->datarel == NULL)
 
        bytes = (char *)alloca(entry->header.a_data);
 
        if (entry->datarel == NULL)
-               fatal_with_file("no data relocation of ", entry);
+               errx(1, "%s: no data relocation", get_file_name(entry));
 
 
-       lseek (desc, text_offset (entry) + entry->header.a_text, 0);
-       if (entry->header.a_data != read(desc, bytes, entry->header.a_data))
-               fatal_with_file ("premature eof in data section of ", entry);
+       if (lseek(fd, text_offset(entry) + entry->header.a_text, L_SET) ==
+           (off_t)-1)
+               err(1, "%s: copy_data: lseek", get_file_name(entry));
+       if (entry->header.a_data != read(fd, bytes, entry->header.a_data))
+               errx(1, "%s: copy_data: premature EOF in data section", get_file_name(entry));
 
 
-       perform_relocation (bytes, entry->header.a_data,
+       perform_relocation(bytes, entry->header.a_data,
                        entry->datarel, entry->ndatarel, entry, 1);
 
                        entry->datarel, entry->ndatarel, entry, 1);
 
-       mywrite (bytes, 1, entry->header.a_data, outdesc);
+       mywrite(bytes, 1, entry->header.a_data, outdesc);
 }
 
 /*
 }
 
 /*
@@ -2522,8 +2589,8 @@ perform_relocation(data, data_size, reloc, nreloc, entry, dataseg)
                 */
 
                if (addr >= data_size)
                 */
 
                if (addr >= data_size)
-                       fatal_with_file(
-                               "relocation address out of range in ", entry);
+                       errx(1, "%s: relocation address out of range",
+                               get_file_name(entry));
 
                if (RELOC_JMPTAB_P(r)) {
 
 
                if (RELOC_JMPTAB_P(r)) {
 
@@ -2532,8 +2599,8 @@ perform_relocation(data, data_size, reloc, nreloc, entry, dataseg)
                        symbol             *sp;
 
                        if (symindex >= entry->nsymbols)
                        symbol             *sp;
 
                        if (symindex >= entry->nsymbols)
-                               fatal_with_file(
-                               "relocation symbolnum out of range in ", entry);
+                               errx(1, "%s: relocation symbolnum out of range",
+                                       get_file_name(entry));
 
                        sp = lsp->symbol;
                        if (sp->alias)
 
                        sp = lsp->symbol;
                        if (sp->alias)
@@ -2554,17 +2621,17 @@ perform_relocation(data, data_size, reloc, nreloc, entry, dataseg)
                        struct localsymbol *lsp = &entry->symbols[symindex];
 
                        if (symindex >= entry->nsymbols)
                        struct localsymbol *lsp = &entry->symbols[symindex];
 
                        if (symindex >= entry->nsymbols)
-                               fatal_with_file(
-                               "relocation symbolnum out of range in ", entry);
+                               errx(1, "%s: relocation symbolnum out of range",
+                                       get_file_name(entry));
 
                        if (relocatable_output)
                                relocation = addend;
                        else if (!RELOC_EXTERN_P(r))
 
                        if (relocatable_output)
                                relocation = addend;
                        else if (!RELOC_EXTERN_P(r))
-                               relocation = claim_rrs_internal_gotslot(entry,
-                                                               r, lsp, addend);
+                               relocation = claim_rrs_internal_gotslot(
+                                               entry, r, lsp, addend);
                        else
                        else
-                               relocation = claim_rrs_gotslot(entry,
-                                                               r, lsp, addend);
+                               relocation = claim_rrs_gotslot(
+                                               entry, r, lsp, addend);
 
                } else if (RELOC_EXTERN_P(r)) {
 
 
                } else if (RELOC_EXTERN_P(r)) {
 
@@ -2572,8 +2639,8 @@ perform_relocation(data, data_size, reloc, nreloc, entry, dataseg)
                        symbol  *sp;
 
                        if (symindex >= entry->nsymbols)
                        symbol  *sp;
 
                        if (symindex >= entry->nsymbols)
-                               fatal_with_file(
-                               "relocation symbolnum out of range in ", entry);
+                               errx(1, "%s: relocation symbolnum out of range",
+                                       get_file_name(entry));
 
                        sp = entry->symbols[symindex].symbol;
                        if (sp->alias)
 
                        sp = entry->symbols[symindex].symbol;
                        if (sp->alias)
@@ -2588,6 +2655,12 @@ perform_relocation(data, data_size, reloc, nreloc, entry, dataseg)
                                if (!pic_code_seen)
                                        relocation += sp->value;
                        } else if (sp->defined) {
                                if (!pic_code_seen)
                                        relocation += sp->value;
                        } else if (sp->defined) {
+                               if (sp->flags & GS_TRACE) {
+                                       fprintf(stderr,
+                                           "symbol %s defined as %x in %s\n",
+                                           sp->name, sp->defined,
+                                           get_file_name(entry) );
+                               }
                                if (sp == got_symbol) {
                                        /* Handle _GOT_ refs */
                                        relocation = addend + sp->value
                                if (sp == got_symbol) {
                                        /* Handle _GOT_ refs */
                                        relocation = addend + sp->value
@@ -2602,8 +2675,8 @@ perform_relocation(data, data_size, reloc, nreloc, entry, dataseg)
                                                entry->data_start_address:
                                                entry->text_start_address;
                                        relocation = addend;
                                                entry->data_start_address:
                                                entry->text_start_address;
                                        relocation = addend;
-                                       if (claim_rrs_reloc(entry, r,
-                                                       sp, &relocation))
+                                       if (claim_rrs_reloc(
+                                               entry, r, sp, &relocation))
                                                continue;
                                } else if (sp->defined == N_SIZE) {
                                        /*
                                                continue;
                                } else if (sp->defined == N_SIZE) {
                                        /*
@@ -2611,7 +2684,7 @@ perform_relocation(data, data_size, reloc, nreloc, entry, dataseg)
                                         * run-time copy.
                                         */
                                        if (!sp->size)
                                         * run-time copy.
                                         */
                                        if (!sp->size)
-                                               fatal("Copy item isn't: %s",
+                                               errx(1, "Copy item isn't: %s",
                                                        sp->name);
 
                                        relocation = addend + sp->value;
                                                        sp->name);
 
                                        relocation = addend + sp->value;
@@ -2628,48 +2701,35 @@ perform_relocation(data, data_size, reloc, nreloc, entry, dataseg)
                                 * run-time. The r_address field is updated
                                 * to reflect the changed position in the
                                 * output file.
                                 * run-time. The r_address field is updated
                                 * to reflect the changed position in the
                                 * output file.
-                                *
-                                * In case the symbol is defined in a shared
-                                * object as N_TEXT or N_DATA, an appropriate
-                                * jmpslot or copy relocation is generated.
                                 */
                                 */
-                               switch (sp->so_defined) {
-
-                               case N_TEXT+N_EXT:
+                               if (sp->flags & GS_TRACE) {
+                                       fprintf(stderr,
+                                           "symbol %s claims RRS in %s%s\n",
+                                           sp->name, get_file_name(entry),
+                                           (sp->so_defined == (N_TEXT+N_EXT) &&
+                                           sp->jmpslot_offset != -1)?
+                                               " (JMPSLOT)":"");
+                               }
+                               if (sp->so_defined == (N_TEXT+N_EXT) &&
+                                   sp->jmpslot_offset != -1) {
                                        /*
                                        /*
-                                        * Claim a jmpslot if one was
-                                        * allocated (dependent on
-                                        * `force_alias_flag').
+                                        * Claim a jmpslot if one was allocated.
+                                        *
+                                        * At this point, a jmpslot can only
+                                        * result from a shared object reference
+                                        * while `force_alias' is in effect.
                                         */
                                         */
-
-                                       if (sp->jmpslot_offset == -1)
-                                               goto undefined;
-
                                        relocation = addend +
                                        relocation = addend +
-                                               claim_rrs_jmpslot(entry, r,
-                                                               sp, addend);
-                                       break;
-
-                               case N_DATA+N_EXT:
-                                       /*FALLTHROUGH*/
-                               case 0:
-                               undefined:
+                                                    claim_rrs_jmpslot(
+                                                       entry, r, sp, addend);
+                               } else {
                                        r->r_address += dataseg?
                                                entry->data_start_address:
                                                entry->text_start_address;
                                        relocation = addend;
                                        r->r_address += dataseg?
                                                entry->data_start_address:
                                                entry->text_start_address;
                                        relocation = addend;
-                                       if (claim_rrs_reloc(entry, r,
-                                                       sp, &relocation))
+                                       if (claim_rrs_reloc(
+                                               entry, r, sp, &relocation))
                                                continue;
                                                continue;
-                                       break;
-
-                               case N_BSS+N_EXT:
-printf("%s: BSS found in so_defined\n", sp->name);
-                                       /*break;*/
-
-                               default:
-                                       fatal("%s: shobj symbol with unknown type %#x", sp->name, sp->so_defined);
-                                       break;
                                }
                        }
 
                                }
                        }
 
@@ -2712,8 +2772,8 @@ printf("%s: BSS found in so_defined\n", sp->name);
                                break;
 
                        default:
                                break;
 
                        default:
-                               fatal_with_file(
-                               "nonexternal relocation code invalid in ", entry);
+                               errx(1, "%s: nonexternal relocation invalid",
+                                       get_file_name(entry));
                        }
 
                        /*
                        }
 
                        /*
@@ -2721,7 +2781,7 @@ printf("%s: BSS found in so_defined\n", sp->name);
                         * relocations need a "load address relative"
                         * RRS fixup.
                         */
                         * relocations need a "load address relative"
                         * RRS fixup.
                         */
-                       if (building_shared_object) {
+                       if (building_shared_object && !RELOC_PCREL_P(r)) {
                                r->r_address += dataseg?
                                        entry->data_start_address:
                                        entry->text_start_address;
                                r->r_address += dataseg?
                                        entry->data_start_address:
                                        entry->text_start_address;
@@ -2743,19 +2803,19 @@ printf("%s: BSS found in so_defined\n", sp->name);
  */
 
 void
  */
 
 void
-write_rel ()
+write_rel()
 {
        int count = 0;
 
        if (trace_files)
 {
        int count = 0;
 
        if (trace_files)
-               fprintf (stderr, "Writing text relocation:\n\n");
+               fprintf(stderr, "Writing text relocation:\n\n");
 
        /*
         * Assign each global symbol a sequence number, giving the order
         * in which `write_syms' will write it.
         * This is so we can store the proper symbolnum fields
         * in relocation entries we write.
 
        /*
         * Assign each global symbol a sequence number, giving the order
         * in which `write_syms' will write it.
         * This is so we can store the proper symbolnum fields
         * in relocation entries we write.
-        *
+        */
 
        /* BLECH - Assign number 0 to __DYNAMIC (!! Sun compatibility) */
 
 
        /* BLECH - Assign number 0 to __DYNAMIC (!! Sun compatibility) */
 
@@ -2772,20 +2832,20 @@ write_rel ()
        } END_EACH_SYMBOL;
 
        if (count != global_sym_count)
        } END_EACH_SYMBOL;
 
        if (count != global_sym_count)
-               fatal ("internal error: write_rel: count = %d", count);
+               errx(1, "internal error: write_rel: count = %d", count);
 
 
-       each_full_file (assign_symbolnums, &count);
+       each_full_file(assign_symbolnums, &count);
 
        /* Write out the relocations of all files, remembered from copy_text. */
 
        /* Write out the relocations of all files, remembered from copy_text. */
-       each_full_file (coptxtrel, 0);
+       each_full_file(coptxtrel, 0);
 
        if (trace_files)
 
        if (trace_files)
-               fprintf (stderr, "\nWriting data relocation:\n\n");
+               fprintf(stderr, "\nWriting data relocation:\n\n");
 
 
-       each_full_file (copdatrel, 0);
+       each_full_file(copdatrel, 0);
 
        if (trace_files)
 
        if (trace_files)
-               fprintf (stderr, "\n");
+               fprintf(stderr, "\n");
 }
 
 
 }
 
 
@@ -2842,8 +2902,8 @@ coptxtrel(entry)
                }
 
                if (symindex >= entry->nsymbols)
                }
 
                if (symindex >= entry->nsymbols)
-                       fatal_with_file(
-                       "relocation symbolnum out of range in ", entry);
+                       errx(1, "%s: relocation symbolnum out of range",
+                               get_file_name(entry));
 
                sp = lsp->symbol;
 
 
                sp = lsp->symbol;
 
@@ -2851,7 +2911,7 @@ coptxtrel(entry)
                /* Resolve indirection.  */
                if ((sp->defined & ~N_EXT) == N_INDR) {
                        if (sp->alias == NULL)
                /* Resolve indirection.  */
                if ((sp->defined & ~N_EXT) == N_INDR) {
                        if (sp->alias == NULL)
-                               fatal("internal error: alias in hyperspace");
+                               errx(1, "internal error: alias in hyperspace");
                        sp = sp->alias;
                }
 #endif
                        sp = sp->alias;
                }
 #endif
@@ -2914,9 +2974,8 @@ copdatrel(entry)
 
                if (!RELOC_EXTERN_P(r)) {
                        if (RELOC_BASEREL_P(r))
 
                if (!RELOC_EXTERN_P(r)) {
                        if (RELOC_BASEREL_P(r))
-                               fatal_with_file(
-                                   "Unsupported relocation type in ",
-                                       entry);
+                               errx(1, "%s: Unsupported relocation type",
+                                       get_file_name(entry));
                        continue;
                }
 
                        continue;
                }
 
@@ -2924,14 +2983,14 @@ copdatrel(entry)
                sp = entry->symbols[symindex].symbol;
 
                if (symindex >= entry->header.a_syms)
                sp = entry->symbols[symindex].symbol;
 
                if (symindex >= entry->header.a_syms)
-                       fatal_with_file(
-                       "relocation symbolnum out of range in ", entry);
+                       errx(1, "%s: relocation symbolnum out of range",
+                               get_file_name(entry));
 
 #ifdef N_INDR
                /* Resolve indirection.  */
                if ((sp->defined & ~N_EXT) == N_INDR) {
                        if (sp->alias == NULL)
 
 #ifdef N_INDR
                /* Resolve indirection.  */
                if ((sp->defined & ~N_EXT) == N_INDR) {
                        if (sp->alias == NULL)
-                               fatal("internal error: alias in hyperspace");
+                               errx(1, "internal error: alias in hyperspace");
                        sp = sp->alias;
                }
 #endif
                        sp = sp->alias;
                }
 #endif
@@ -3004,7 +3063,7 @@ assign_string_table_index(name)
        return index;
 }
 
        return index;
 }
 
-FILE           *outstream = (FILE *) 0;
+FILE           *outstream = (FILE *)0;
 
 /*
  * Write the contents of `strtab_vector' into the string table. This is done
 
 /*
  * Write the contents of `strtab_vector' into the string table. This is done
@@ -3012,25 +3071,27 @@ FILE           *outstream = (FILE *) 0;
  * symbols.
  */
 void
  * symbols.
  */
 void
-write_string_table ()
+write_string_table()
 {
        register int i;
 
 {
        register int i;
 
-       lseek (outdesc, string_table_offset + string_table_len, 0);
+       if (lseek(outdesc, string_table_offset + string_table_len, 0) ==
+           (off_t)-1)
+               err(1, "write_string_table: %s: lseek", output_filename);
 
        if (!outstream)
 
        if (!outstream)
-               outstream = fdopen (outdesc, "w");
+               outstream = fdopen(outdesc, "w");
 
        for (i = 0; i < strtab_index; i++) {
                fwrite (strtab_vector[i], 1, strtab_lens[i], outstream);
                string_table_len += strtab_lens[i];
        }
 
 
        for (i = 0; i < strtab_index; i++) {
                fwrite (strtab_vector[i], 1, strtab_lens[i], outstream);
                string_table_len += strtab_lens[i];
        }
 
-       fflush (outstream);
+       fflush(outstream);
 
        /* Report I/O error such as disk full.  */
 
        /* Report I/O error such as disk full.  */
-       if (ferror (outstream))
-               perror_name (output_filename);
+       if (ferror(outstream))
+               err(1, "write_string_table: %s", output_filename);
 }
 \f
 /* Write the symbol table and string table of the output file.  */
 }
 \f
 /* Write the symbol table and string table of the output file.  */
@@ -3070,8 +3131,8 @@ write_syms()
         * extra space for the references following indirect outputs.
         */
 
         * extra space for the references following indirect outputs.
         */
 
-       strtab_vector = (char **) alloca((global_sym_count) * sizeof(char *));
-       strtab_lens = (int *) alloca((global_sym_count) * sizeof(int));
+       strtab_vector = (char **)alloca((global_sym_count) * sizeof(char *));
+       strtab_lens = (int *)alloca((global_sym_count) * sizeof(int));
        strtab_index = 0;
 
        /*
        strtab_index = 0;
 
        /*
@@ -3124,12 +3185,12 @@ write_syms()
                         * (they are in the RRS symbol table).
                         */
                        if (!building_shared_object)
                         * (they are in the RRS symbol table).
                         */
                        if (!building_shared_object)
-                               error("symbol %s remains undefined", sp->name);
+                               warnx("symbol %s remains undefined", sp->name);
                        continue;
                }
 
                if (syms_written >= global_sym_count)
                        continue;
                }
 
                if (syms_written >= global_sym_count)
-                       fatal(
+                       errx(1,
                        "internal error: number of symbols exceeds alloc'd %d",
                                global_sym_count);
 
                        "internal error: number of symbols exceeds alloc'd %d",
                                global_sym_count);
 
@@ -3161,7 +3222,7 @@ write_syms()
                                        nl.n_type = sp->defined;
                                if (nl.n_type == (N_INDR|N_EXT) &&
                                                        sp->value != 0)
                                        nl.n_type = sp->defined;
                                if (nl.n_type == (N_INDR|N_EXT) &&
                                                        sp->value != 0)
-                                       fatal("%s: N_INDR has value %#x",
+                                       errx(1, "%s: N_INDR has value %#x",
                                                        sp->name, sp->value);
                                nl.n_value = sp->value;
                                nl.n_other = N_OTHER(0, sp->aux);
                                                        sp->name, sp->value);
                                nl.n_value = sp->value;
                                nl.n_other = N_OTHER(0, sp->aux);
@@ -3184,7 +3245,7 @@ write_syms()
                        nl.n_type = N_UNDF | N_EXT;
                        nl.n_value = 0;
                } else
                        nl.n_type = N_UNDF | N_EXT;
                        nl.n_value = 0;
                } else
-                       fatal(
+                       errx(1,
                              "internal error: %s defined in mysterious way",
                              sp->name);
 
                              "internal error: %s defined in mysterious way",
                              sp->name);
 
@@ -3204,7 +3265,7 @@ write_syms()
                 */
                if (nl.n_type == N_INDR + N_EXT) {
                        if (sp->alias == NULL)
                 */
                if (nl.n_type == N_INDR + N_EXT) {
                        if (sp->alias == NULL)
-                               fatal("internal error: alias in hyperspace");
+                               errx(1, "internal error: alias in hyperspace");
                        nl.n_type = N_UNDF + N_EXT;
                        nl.n_un.n_strx =
                                assign_string_table_index(sp->alias->name);
                        nl.n_type = N_UNDF + N_EXT;
                        nl.n_un.n_strx =
                                assign_string_table_index(sp->alias->name);
@@ -3234,13 +3295,15 @@ printf("writesym(#%d): %s, type %x\n", syms_written, sp->name, sp->defined);
        } END_EACH_SYMBOL;
 
        if (syms_written != strtab_index || strtab_index != global_sym_count)
        } END_EACH_SYMBOL;
 
        if (syms_written != strtab_index || strtab_index != global_sym_count)
-               fatal("internal error:\
+               errx(1, "internal error:\
 wrong number (%d) of global symbols written into output file, should be %d",
                                syms_written, global_sym_count);
 
        /* Output the buffer full of `struct nlist's.  */
 
 wrong number (%d) of global symbols written into output file, should be %d",
                                syms_written, global_sym_count);
 
        /* Output the buffer full of `struct nlist's.  */
 
-       lseek(outdesc, symbol_table_offset + symbol_table_len, 0);
+       if (lseek(outdesc, symbol_table_offset + symbol_table_len, 0) ==
+           (off_t)-1)
+               err(1, "write_syms: lseek");
        md_swapout_symbols(buf, bufp - buf);
        mywrite(buf, bufp - buf, sizeof(struct nlist), outdesc);
        symbol_table_len += sizeof(struct nlist) * (bufp - buf);
        md_swapout_symbols(buf, bufp - buf);
        mywrite(buf, bufp - buf, sizeof(struct nlist), outdesc);
        symbol_table_len += sizeof(struct nlist) * (bufp - buf);
@@ -3249,16 +3312,16 @@ wrong number (%d) of global symbols written into output file, should be %d",
        write_string_table();
 
        /* Write the local symbols defined by the various files.  */
        write_string_table();
 
        /* Write the local symbols defined by the various files.  */
-       each_file(write_file_syms, &syms_written);
+       each_file(write_file_syms, (void *)&syms_written);
        file_close();
 
        if (syms_written != nsyms)
        file_close();
 
        if (syms_written != nsyms)
-               fatal("internal error:\
+               errx(1, "internal error:\
 wrong number of symbols (%d) written into output file, should be %d",
                                syms_written, nsyms);
 
        if (symbol_table_offset + symbol_table_len != string_table_offset)
 wrong number of symbols (%d) written into output file, should be %d",
                                syms_written, nsyms);
 
        if (symbol_table_offset + symbol_table_len != string_table_offset)
-               fatal(
+               errx(1,
                "internal error: inconsistent symbol table length: %d vs %s",
                symbol_table_offset + symbol_table_len, string_table_offset);
 
                "internal error: inconsistent symbol table length: %d vs %s",
                symbol_table_offset + symbol_table_len, string_table_offset);
 
@@ -3304,8 +3367,8 @@ write_file_syms(entry, syms_written_addr)
         * length. The elements are filled in by `assign_string_table_index'.
         */
 
         * length. The elements are filled in by `assign_string_table_index'.
         */
 
-       strtab_vector = (char **) alloca(max_syms * sizeof(char *));
-       strtab_lens = (int *) alloca(max_syms * sizeof(int));
+       strtab_vector = (char **)alloca(max_syms * sizeof(char *));
+       strtab_lens = (int *)alloca(max_syms * sizeof(int));
        strtab_index = 0;
 
        /* Generate a local symbol for the start of this file's text.  */
        strtab_index = 0;
 
        /* Generate a local symbol for the start of this file's text.  */
@@ -3314,7 +3377,8 @@ write_file_syms(entry, syms_written_addr)
                struct nlist    nl;
 
                nl.n_type = N_FN | N_EXT;
                struct nlist    nl;
 
                nl.n_type = N_FN | N_EXT;
-               nl.n_un.n_strx = assign_string_table_index(entry->local_sym_name);
+               nl.n_un.n_strx =
+                       assign_string_table_index(entry->local_sym_name);
                nl.n_value = entry->text_start_address;
                nl.n_desc = 0;
                nl.n_other = 0;
                nl.n_value = entry->text_start_address;
                nl.n_desc = 0;
                nl.n_other = 0;
@@ -3323,15 +3387,13 @@ write_file_syms(entry, syms_written_addr)
        }
        /* Read the file's string table.  */
 
        }
        /* Read the file's string table.  */
 
-       entry->strings = (char *) alloca(entry->string_size);
+       entry->strings = (char *)alloca(entry->string_size);
        read_entry_strings(file_open(entry), entry);
 
        lspend = entry->symbols + entry->nsymbols;
 
        for (lsp = entry->symbols; lsp < lspend; lsp++) {
                register struct nlist *p = &lsp->nzlist.nlist;
        read_entry_strings(file_open(entry), entry);
 
        lspend = entry->symbols + entry->nsymbols;
 
        for (lsp = entry->symbols; lsp < lspend; lsp++) {
                register struct nlist *p = &lsp->nzlist.nlist;
-               register int    type = p->n_type;
-               register int    write = 0;
                char            *name;
 
                if (!(lsp->flags & LS_WRITE))
                char            *name;
 
                if (!(lsp->flags & LS_WRITE))
@@ -3380,48 +3442,72 @@ write_file_syms(entry, syms_written_addr)
 }
 
 /*
 }
 
 /*
- * Output COUNT*ELTSIZE bytes of data at BUF to the descriptor DESC.
+ * Parse the string ARG using scanf format FORMAT, and return the result.
+ * If it does not parse, report fatal error
+ * generating the error message using format string ERROR and ARG as arg.
+ */
+
+static int
+parse(arg, format, error)
+       char *arg, *format, *error;
+{
+       int x;
+
+       if (1 != sscanf(arg, format, &x))
+               errx(1, error, arg);
+       return x;
+}
+
+/*
+ * Output COUNT*ELTSIZE bytes of data at BUF to the descriptor FD.
  */
 void
  */
 void
-mywrite (buf, count, eltsize, desc)
+mywrite(buf, count, eltsize, fd)
      void *buf;
      int count;
      int eltsize;
      void *buf;
      int count;
      int eltsize;
-     int desc;
+       int fd;
 {
        register int val;
        register int bytes = count * eltsize;
 
        while (bytes > 0) {
 {
        register int val;
        register int bytes = count * eltsize;
 
        while (bytes > 0) {
-               val = write (desc, buf, bytes);
+               val = write(fd, buf, bytes);
                if (val <= 0)
                if (val <= 0)
-                       perror(output_filename);
+                       err(1, "write: %s", output_filename);
                buf += val;
                bytes -= val;
        }
 }
 
 static void
                buf += val;
                bytes -= val;
        }
 }
 
 static void
-myfatal()
+cleanup()
 {
 {
-       if (outdesc > 0)
-               unlink(output_filename);
+       struct stat     statbuf;
+
+       if (outdesc <= 0)
+               return;
+
+       if (fstat(outdesc, &statbuf) == 0) {
+               if (S_ISREG(statbuf.st_mode))
+                       (void)unlink(output_filename);
+       }
 }
 
 /*
 }
 
 /*
- * Output PADDING zero-bytes to descriptor OUTDESC.
+ * Output PADDING zero-bytes to descriptor FD.
  * PADDING may be negative; in that case, do nothing.
  */
 void
  * PADDING may be negative; in that case, do nothing.
  */
 void
-padfile (padding, outdesc)
+padfile(padding, fd)
      int padding;
      int padding;
-     int outdesc;
+       int fd;
 {
        register char *buf;
        if (padding <= 0)
                return;
 
 {
        register char *buf;
        if (padding <= 0)
                return;
 
-       buf = (char *) alloca (padding);
-       bzero (buf, padding);
-       mywrite (buf, padding, 1, outdesc);
+       buf = (char *)alloca(padding);
+       bzero(buf, padding);
+       mywrite(buf, padding, 1, fd);
 }
 }
index a43eac8..3c1b195 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- *     $Id: ld.h,v 1.8 1994/01/28 20:56:24 pk Exp $
+ *     $Id: ld.h,v 1.10 1994/02/13 20:41:34 jkh Exp $
  */
 /*-
  * This code is derived from software copyrighted by the Free Software
  */
 /*-
  * This code is derived from software copyrighted by the Free Software
 /* Align to machine dependent boundary */
 #define MALIGN(x)      PALIGN(x,MAX_ALIGNMENT)
 
 /* Align to machine dependent boundary */
 #define MALIGN(x)      PALIGN(x,MAX_ALIGNMENT)
 
-/* Name this program was invoked by.  */
-char   *progname;
-
-/* System dependencies */
-
 /* Define this to specify the default executable format.  */
 /* Define this to specify the default executable format.  */
-
 #ifndef DEFAULT_MAGIC
 #ifdef FreeBSD
 #define DEFAULT_MAGIC QMAGIC
 #ifndef DEFAULT_MAGIC
 #ifdef FreeBSD
 #define DEFAULT_MAGIC QMAGIC
@@ -596,20 +590,24 @@ extern int        n_search_dirs;  /* Length of above. */
 
 extern int     write_map;      /* write a load map (`-M') */
 
 
 extern int     write_map;      /* write a load map (`-M') */
 
-extern void    (*fatal_cleanup_hook)__P((void));
-
 void   read_header __P((int, struct file_entry *));
 void   read_entry_symbols __P((int, struct file_entry *));
 void   read_entry_strings __P((int, struct file_entry *));
 void   read_entry_relocation __P((int, struct file_entry *));
 void   enter_file_symbols __P((struct file_entry *));
 void   read_file_symbols __P((struct file_entry *));
 void   read_header __P((int, struct file_entry *));
 void   read_entry_symbols __P((int, struct file_entry *));
 void   read_entry_strings __P((int, struct file_entry *));
 void   read_entry_relocation __P((int, struct file_entry *));
 void   enter_file_symbols __P((struct file_entry *));
 void   read_file_symbols __P((struct file_entry *));
+int    set_element_prefixed_p __P((char *));
+int    text_offset __P((struct file_entry *));
+int    file_open __P((struct file_entry *));
+void   each_file __P((void (*)(), void *));
+void   each_full_file __P((void (*)(), void *));
+unsigned long  check_each_file __P((unsigned long (*)(), void *));
 void   mywrite __P((void *, int, int, int));
 void   mywrite __P((void *, int, int, int));
+void   padfile __P((int,int));
 
 /* In warnings.c: */
 void   perror_name __P((char *));
 void   perror_file __P((struct file_entry *));
 
 /* In warnings.c: */
 void   perror_name __P((char *));
 void   perror_file __P((struct file_entry *));
-void   fatal_with_file __P((char *, struct file_entry *, ...));
 void   print_symbols __P((FILE *));
 char   *get_file_name __P((struct file_entry *));
 void   print_file_name __P((struct file_entry *, FILE *));
 void   print_symbols __P((FILE *));
 char   *get_file_name __P((struct file_entry *));
 void   print_file_name __P((struct file_entry *, FILE *));
@@ -617,13 +615,9 @@ void       prline_file_name __P((struct file_entry *, FILE *));
 int    do_warnings __P((FILE *));
 
 /* In etc.c: */
 int    do_warnings __P((FILE *));
 
 /* In etc.c: */
-void   *xmalloc __P((int));
-void   *xrealloc __P((void *, int));
-void   fatal __P((char *, ...));
-void   error __P((char *, ...));
-void   padfile __P((int,int));
+void   *xmalloc __P((size_t));
+void   *xrealloc __P((void *, size_t));
 char   *concat __P((const char *, const char *, const char *));
 char   *concat __P((const char *, const char *, const char *));
-int    parse __P((char *, char *, char *));
 
 /* In symbol.c: */
 void   symtab_init __P((int));
 
 /* In symbol.c: */
 void   symtab_init __P((int));
@@ -637,7 +631,10 @@ int        findlib __P((struct file_entry *));
 /* In shlib.c: */
 char   *findshlib __P((char *, int *, int *, int));
 void   add_search_dir __P((char *));
 /* In shlib.c: */
 char   *findshlib __P((char *, int *, int *, int));
 void   add_search_dir __P((char *));
-void   std_search_dirs __P((char *));
+void   add_search_path __P((char *));
+void   std_search_path __P((void));
+int    getdewey __P((int[], char *));
+int    cmpndewey __P((int[], int, int[], int));
 
 /* In rrs.c: */
 void   init_rrs __P((void));
 
 /* In rrs.c: */
 void   init_rrs __P((void));
@@ -654,6 +651,9 @@ long        claim_rrs_gotslot __P((struct file_entry *, struct relocation_info *, struc
 long   claim_rrs_internal_gotslot __P((struct file_entry *, struct relocation_info *, struct localsymbol *, long));
 void   claim_rrs_cpy_reloc __P((struct file_entry *, struct relocation_info *, symbol *));
 void   claim_rrs_segment_reloc __P((struct file_entry *, struct relocation_info *));
 long   claim_rrs_internal_gotslot __P((struct file_entry *, struct relocation_info *, struct localsymbol *, long));
 void   claim_rrs_cpy_reloc __P((struct file_entry *, struct relocation_info *, symbol *));
 void   claim_rrs_segment_reloc __P((struct file_entry *, struct relocation_info *));
+void   consider_rrs_section_lengths __P((void));
+void   relocate_rrs_addresses __P((void));
+void   write_rrs __P((void));
 
 /* In <md>.c */
 void   md_init_header __P((struct exec *, int, int));
 
 /* In <md>.c */
 void   md_init_header __P((struct exec *, int, int));
@@ -665,6 +665,7 @@ int md_make_reloc __P((struct relocation_info *, struct relocation_info *, int))
 void   md_make_jmpreloc __P((struct relocation_info *, struct relocation_info *, int));
 void   md_make_gotreloc __P((struct relocation_info *, struct relocation_info *, int));
 void   md_make_copyreloc __P((struct relocation_info *, struct relocation_info *));
 void   md_make_jmpreloc __P((struct relocation_info *, struct relocation_info *, int));
 void   md_make_gotreloc __P((struct relocation_info *, struct relocation_info *, int));
 void   md_make_copyreloc __P((struct relocation_info *, struct relocation_info *));
+void   md_set_breakpoint __P((long, long *));
 
 #ifdef NEED_SWAP
 void   md_swapin_exec_hdr __P((struct exec *));
 
 #ifdef NEED_SWAP
 void   md_swapin_exec_hdr __P((struct exec *));
index 32c35af..1ca25a4 100644 (file)
@@ -62,6 +62,8 @@ Do not scan
 .Sq /usr/lib
 ,
 .Sq /usr/X386/lib
 .Sq /usr/lib
 ,
 .Sq /usr/X386/lib
+,
+.Sq /usr/X11R6/lib
 and
 .Sq /usr/local/lib
 for shared libraries.
 and
 .Sq /usr/local/lib
 for shared libraries.
index ec92b9c..b31271f 100644 (file)
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- *     $Id: ldconfig.c,v 1.5 1994/02/13 20:42:30 jkh Exp $
+ *     $Id: ldconfig.c,v 1.6 1994/06/05 19:04:11 ats Exp $
  */
 
 #include <sys/param.h>
  */
 
 #include <sys/param.h>
-#include <stdio.h>
-#include <stdlib.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/file.h>
 #include <sys/time.h>
 #include <sys/mman.h>
 #include <sys/resource.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/file.h>
 #include <sys/time.h>
 #include <sys/mman.h>
 #include <sys/resource.h>
-#include <fcntl.h>
+#include <dirent.h>
 #include <errno.h>
 #include <errno.h>
+#include <fcntl.h>
 #include <ar.h>
 #include <ranlib.h>
 #include <a.out.h>
 #include <stab.h>
 #include <ar.h>
 #include <ranlib.h>
 #include <a.out.h>
 #include <stab.h>
+#include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <string.h>
-#include <dirent.h>
+#include <unistd.h>
 
 #include "ld.h"
 
 
 #include "ld.h"
 
@@ -74,6 +75,7 @@ static struct shlib_list      *shlib_head = NULL, **shlib_tail = &shlib_head;
 static void    enter __P((char *, char *, char *, int *, int));
 static int     dodir __P((char *, int));
 static int     build_hints __P((void));
 static void    enter __P((char *, char *, char *, int *, int));
 static int     dodir __P((char *, int));
 static int     build_hints __P((void));
+static int     listhints __P((void));
 
 int
 main(argc, argv)
 
 int
 main(argc, argv)
@@ -111,7 +113,7 @@ char        *argv[];
                return listhints();
 
        if (!nostd)
                return listhints();
 
        if (!nostd)
-               std_search_dirs(NULL);
+               std_search_path();
 
        for (i = 0; i < n_search_dirs; i++)
                rval |= dodir(search_dirs[i], 1);
 
        for (i = 0; i < n_search_dirs; i++)
                rval |= dodir(search_dirs[i], 1);
@@ -349,7 +351,7 @@ build_hints()
        return 0;
 }
 
        return 0;
 }
 
-int
+static int
 listhints()
 {
        int                     fd;
 listhints()
 {
        int                     fd;
@@ -375,7 +377,8 @@ listhints()
 
        hdr = (struct hints_header *)addr;
        if (HH_BADMAG(*hdr)) {
 
        hdr = (struct hints_header *)addr;
        if (HH_BADMAG(*hdr)) {
-               fprintf(stderr, "%s: Bad magic: %d\n");
+               fprintf(stderr, "%s: Bad magic: %o\n",
+                       _PATH_LD_HINTS, hdr->hh_magic);
                return -1;
        }
 
                return -1;
        }
 
index 7fba989..1072d80 100644 (file)
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- *     $Id: ldd.c,v 1.2 1993/11/09 04:19:27 paul Exp $
+ *     $Id: ldd.c,v 1.3 1994/02/13 20:42:43 jkh Exp $
  */
 
  */
 
-#include <sys/param.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/file.h>
 #include <sys/time.h>
 #include <sys/resource.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/file.h>
 #include <sys/time.h>
 #include <sys/resource.h>
-#include <fcntl.h>
 #include <sys/wait.h>
 #include <a.out.h>
 #include <sys/wait.h>
 #include <a.out.h>
-
-static char    *progname;
+#include <err.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
 
 void
 usage()
 {
 
 void
 usage()
 {
-       fprintf(stderr, "Usage: %s <filename> ...\n", progname);
+       extern char *__progname;
+
+       fprintf(stderr, "Usage: %s <filename> ...\n", __progname);
+       exit(1);
 }
 
 int
 }
 
 int
@@ -57,20 +58,14 @@ main(argc, argv)
 int    argc;
 char   *argv[];
 {
 int    argc;
 char   *argv[];
 {
-       int             rval = 0;
+       int             rval;
        int             c;
        int             c;
-       extern int      optind;
-
-       if ((progname = strrchr(argv[0], '/')) == NULL)
-               progname = argv[0];
-       else
-               progname++;
 
        while ((c = getopt(argc, argv, "")) != EOF) {
                switch (c) {
                default:
                        usage();
 
        while ((c = getopt(argc, argv, "")) != EOF) {
                switch (c) {
                default:
                        usage();
-                       exit(1);
+                       /*NOTREACHED*/
                }
        }
        argc -= optind;
                }
        }
        argc -= optind;
@@ -78,27 +73,29 @@ char        *argv[];
 
        if (argc <= 0) {
                usage();
 
        if (argc <= 0) {
                usage();
-               exit(1);
+               /*NOTREACHED*/
        }
 
        /* ld.so magic */
        setenv("LD_TRACE_LOADED_OBJECTS", "", 1);
 
        }
 
        /* ld.so magic */
        setenv("LD_TRACE_LOADED_OBJECTS", "", 1);
 
+       rval = 0;
        while (argc--) {
                int     fd;
                struct exec hdr;
                int     status;
 
                if ((fd = open(*argv, O_RDONLY, 0)) < 0) {
        while (argc--) {
                int     fd;
                struct exec hdr;
                int     status;
 
                if ((fd = open(*argv, O_RDONLY, 0)) < 0) {
-                       perror(*argv);
+                       warn("%s", *argv);
                        rval |= 1;
                        argv++;
                        continue;
                }
                if (read(fd, &hdr, sizeof hdr) != sizeof hdr ||
                        rval |= 1;
                        argv++;
                        continue;
                }
                if (read(fd, &hdr, sizeof hdr) != sizeof hdr ||
-                                       !(N_GETFLAG(hdr) & EX_DYNAMIC)) {
-                       fprintf(stderr, "%s: not a dynamic executable\n",
-                                               *argv);
+                   !(N_GETFLAG(hdr) & EX_DYNAMIC) ||
+                   hdr.a_entry < __LDPGSZ) {
+
+                       warnx("%s: not a dynamic executable", *argv);
                        (void)close(fd);
                        rval |= 1;
                        argv++;
                        (void)close(fd);
                        rval |= 1;
                        argv++;
@@ -111,14 +108,13 @@ char      *argv[];
 
                switch (fork()) {
                case -1:
 
                switch (fork()) {
                case -1:
-                       perror("fork");
-                       exit(1);
+                       err(1, "fork");
                        break;
                default:
                        break;
                default:
-                       if (wait(&status) <= 0)
-                               perror("wait");
-
-                       if (WIFSIGNALED(status)) {
+                       if (wait(&status) <= 0) {
+                               warn("wait");
+                               rval |= 1;
+                       } else if (WIFSIGNALED(status)) {
                                fprintf(stderr, "%s: signal %d\n",
                                                *argv, WTERMSIG(status));
                                rval |= 1;
                                fprintf(stderr, "%s: signal %d\n",
                                                *argv, WTERMSIG(status));
                                rval |= 1;
@@ -129,7 +125,7 @@ char        *argv[];
                        }
                        break;
                case 0:
                        }
                        break;
                case 0:
-                       rval != execl(*argv, *argv, NULL) != 0;
+                       rval |= execl(*argv, *argv, NULL) != 0;
                        perror(*argv);
                        _exit(1);
                }
                        perror(*argv);
                        _exit(1);
                }
index 78d337e..7eaaa98 100644 (file)
@@ -1,14 +1,16 @@
 /*
 /*
- * $Id: lib.c,v 1.8 1993/12/22 23:28:11 jkh Exp $      - library routines
+ * $Id: lib.c,v 1.9 1994/02/13 20:41:37 jkh Exp $      - library routines
  */
 
 #include <sys/param.h>
 #include <stdio.h>
 #include <stdlib.h>
  */
 
 #include <sys/param.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <unistd.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/file.h>
 #include <sys/time.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/file.h>
 #include <sys/time.h>
+#include <err.h>
 #include <fcntl.h>
 #include <ar.h>
 #include <ranlib.h>
 #include <fcntl.h>
 #include <ar.h>
 #include <ranlib.h>
@@ -16,6 +18,7 @@
 #include <stab.h>
 #include <string.h>
 #include <dirent.h>
 #include <stab.h>
 #include <string.h>
 #include <dirent.h>
+#include <ctype.h>
 
 #include "ld.h"
 
 
 #include "ld.h"
 
@@ -26,15 +29,15 @@ static struct file_entry    *decode_library_subfile __P((int,
                                                        int, int *));
 
 /*
                                                        int, int *));
 
 /*
- * Search the library ENTRY, already open on descriptor DESC. This means
+ * Search the library ENTRY, already open on descriptor FD. This means
  * deciding which library members to load, making a chain of `struct
  * file_entry' for those members, and entering their global symbols in the
  * hash table.
  */
 
 void
  * deciding which library members to load, making a chain of `struct
  * file_entry' for those members, and entering their global symbols in the
  * hash table.
  */
 
 void
-search_library(desc, entry)
-       int             desc;
+search_library(fd, entry)
+       int             fd;
        struct file_entry *entry;
 {
        int             member_length;
        struct file_entry *entry;
 {
        int             member_length;
@@ -45,7 +48,7 @@ search_library(desc, entry)
                return;
 
        /* Examine its first member, which starts SARMAG bytes in.  */
                return;
 
        /* Examine its first member, which starts SARMAG bytes in.  */
-       subentry = decode_library_subfile(desc, entry, SARMAG, &member_length);
+       subentry = decode_library_subfile(fd, entry, SARMAG, &member_length);
        if (!subentry)
                return;
 
        if (!subentry)
                return;
 
@@ -55,21 +58,21 @@ search_library(desc, entry)
        /* Search via __.SYMDEF if that exists, else linearly.  */
 
        if (!strcmp(name, "__.SYMDEF"))
        /* Search via __.SYMDEF if that exists, else linearly.  */
 
        if (!strcmp(name, "__.SYMDEF"))
-               symdef_library(desc, entry, member_length);
+               symdef_library(fd, entry, member_length);
        else
        else
-               linear_library(desc, entry);
+               linear_library(fd, entry);
 }
 
 /*
  * Construct and return a file_entry for a library member. The library's
 }
 
 /*
  * Construct and return a file_entry for a library member. The library's
- * file_entry is library_entry, and the library is open on DESC.
+ * file_entry is library_entry, and the library is open on FD.
  * SUBFILE_OFFSET is the byte index in the library of this member's header.
  * We store the length of the member into *LENGTH_LOC.
  */
 
 static struct file_entry *
  * SUBFILE_OFFSET is the byte index in the library of this member's header.
  * We store the length of the member into *LENGTH_LOC.
  */
 
 static struct file_entry *
-decode_library_subfile(desc, library_entry, subfile_offset, length_loc)
-       int             desc;
+decode_library_subfile(fd, library_entry, subfile_offset, length_loc)
+       int             fd;
        struct file_entry *library_entry;
        int             subfile_offset;
        int            *length_loc;
        struct file_entry *library_entry;
        int             subfile_offset;
        int            *length_loc;
@@ -82,17 +85,20 @@ decode_library_subfile(desc, library_entry, subfile_offset, length_loc)
        struct ar_hdr   hdr1;
        register struct file_entry *subentry;
 
        struct ar_hdr   hdr1;
        register struct file_entry *subentry;
 
-       lseek(desc, subfile_offset, 0);
+       lseek(fd, subfile_offset, 0);
 
 
-       bytes_read = read(desc, &hdr1, sizeof hdr1);
+       bytes_read = read(fd, &hdr1, sizeof hdr1);
        if (!bytes_read)
                return 0;       /* end of archive */
 
        if (sizeof hdr1 != bytes_read)
        if (!bytes_read)
                return 0;       /* end of archive */
 
        if (sizeof hdr1 != bytes_read)
-               fatal_with_file("malformed library archive ", library_entry);
+               errx(1, "%s: malformed library archive",
+                       get_file_name(library_entry));
 
        if (sscanf(hdr1.ar_size, "%d", &member_length) != 1)
 
        if (sscanf(hdr1.ar_size, "%d", &member_length) != 1)
-               fatal_with_file("malformatted header of archive member in ", library_entry);
+               errx(1, "%s: malformatted header of archive member: %.*s",
+                       get_file_name(library_entry),
+                       sizeof(hdr1.ar_name), hdr1.ar_name);
 
        subentry = (struct file_entry *) xmalloc(sizeof(struct file_entry));
        bzero(subentry, sizeof(struct file_entry));
 
        subentry = (struct file_entry *) xmalloc(sizeof(struct file_entry));
        bzero(subentry, sizeof(struct file_entry));
@@ -116,10 +122,10 @@ decode_library_subfile(desc, library_entry, subfile_offset, length_loc)
 
                namelen = atoi(&hdr1.ar_name[sizeof(AR_EFMT1) - 1]);
                name = (char *)xmalloc(namelen + 1);
 
                namelen = atoi(&hdr1.ar_name[sizeof(AR_EFMT1) - 1]);
                name = (char *)xmalloc(namelen + 1);
-               if (read(desc, name, namelen) != namelen)
-                       fatal_with_file(
-                       "malformatted header of archive member in ",
-                               library_entry);
+               if (read(fd, name, namelen) != namelen)
+                       errx(1, "%s: malformatted archive member: %.*s",
+                               get_file_name(library_entry),
+                               sizeof(hdr1.ar_name), hdr1.ar_name);
                name[namelen] = 0;
                content_length -= namelen;
                starting_offset += namelen;
                name[namelen] = 0;
                content_length -= namelen;
                starting_offset += namelen;
@@ -134,14 +140,16 @@ decode_library_subfile(desc, library_entry, subfile_offset, length_loc)
 
        subentry->filename = name;
        subentry->local_sym_name = name;
 
        subentry->filename = name;
        subentry->local_sym_name = name;
+       subentry->starting_offset = starting_offset;
+       subentry->superfile = library_entry;
+       subentry->total_size = content_length;
+#if 0
        subentry->symbols = 0;
        subentry->strings = 0;
        subentry->subfiles = 0;
        subentry->symbols = 0;
        subentry->strings = 0;
        subentry->subfiles = 0;
-       subentry->starting_offset = starting_offset;
-       subentry->superfile = library_entry;
        subentry->chain = 0;
        subentry->flags = 0;
        subentry->chain = 0;
        subentry->flags = 0;
-       subentry->total_size = content_length;
+#endif
 
        (*length_loc) = member_length;
 
 
        (*length_loc) = member_length;
 
@@ -151,15 +159,15 @@ decode_library_subfile(desc, library_entry, subfile_offset, length_loc)
 static int     subfile_wanted_p __P((struct file_entry *));
 
 /*
 static int     subfile_wanted_p __P((struct file_entry *));
 
 /*
- * Search a library that has a __.SYMDEF member. DESC is a descriptor on
+ * Search a library that has a __.SYMDEF member. FD is a descriptor on
  * which the library is open. The file pointer is assumed to point at the
  * __.SYMDEF data. ENTRY is the library's file_entry. MEMBER_LENGTH is the
  * length of the __.SYMDEF data.
  */
 
 static void
  * which the library is open. The file pointer is assumed to point at the
  * __.SYMDEF data. ENTRY is the library's file_entry. MEMBER_LENGTH is the
  * length of the __.SYMDEF data.
  */
 
 static void
-symdef_library(desc, entry, member_length)
-       int             desc;
+symdef_library(fd, entry, member_length)
+       int             fd;
        struct file_entry *entry;
        int             member_length;
 {
        struct file_entry *entry;
        int             member_length;
 {
@@ -174,14 +182,16 @@ symdef_library(desc, entry, member_length)
        struct file_entry *prev = 0;
        int             prev_offset = 0;
 
        struct file_entry *prev = 0;
        int             prev_offset = 0;
 
-       bytes_read = read(desc, symdef_data, member_length);
+       bytes_read = read(fd, symdef_data, member_length);
        if (bytes_read != member_length)
        if (bytes_read != member_length)
-               fatal_with_file("malformatted __.SYMDEF in ", entry);
+               errx(1, "%s: malformatted __.SYMDEF",
+                       get_file_name(entry));
 
        nsymdefs = md_swap_long(*symdef_data) / sizeof(struct ranlib);
        if (nsymdefs < 0 ||
            nsymdefs * sizeof(struct ranlib) + 2 * sizeof(int) > member_length)
 
        nsymdefs = md_swap_long(*symdef_data) / sizeof(struct ranlib);
        if (nsymdefs < 0 ||
            nsymdefs * sizeof(struct ranlib) + 2 * sizeof(int) > member_length)
-               fatal_with_file("malformatted __.SYMDEF in ", entry);
+               errx(1, "%s: malformatted __.SYMDEF",
+                       get_file_name(entry));
 
        symdef_base = (struct ranlib *) (symdef_data + 1);
        length_of_strings = md_swap_long(*(int *) (symdef_base + nsymdefs));
 
        symdef_base = (struct ranlib *) (symdef_data + 1);
        length_of_strings = md_swap_long(*(int *) (symdef_base + nsymdefs));
@@ -189,7 +199,8 @@ symdef_library(desc, entry, member_length)
        if (length_of_strings < 0
            || nsymdefs * sizeof(struct ranlib) + length_of_strings
            + 2 * sizeof(int) > member_length)
        if (length_of_strings < 0
            || nsymdefs * sizeof(struct ranlib) + length_of_strings
            + 2 * sizeof(int) > member_length)
-               fatal_with_file("malformatted __.SYMDEF in ", entry);
+               errx(1, "%s: malformatted __.SYMDEF",
+                       get_file_name(entry));
 
        sym_name_base = sizeof(int) + (char *) (symdef_base + nsymdefs);
 
 
        sym_name_base = sizeof(int) + (char *) (symdef_base + nsymdefs);
 
@@ -199,7 +210,8 @@ symdef_library(desc, entry, member_length)
                register int    index = symdef_base[i].ran_un.ran_strx;
                if (index < 0 || index >= length_of_strings
                    || (index && *(sym_name_base + index - 1)))
                register int    index = symdef_base[i].ran_un.ran_strx;
                if (index < 0 || index >= length_of_strings
                    || (index && *(sym_name_base + index - 1)))
-                       fatal_with_file("malformatted __.SYMDEF in ", entry);
+                       errx(1, "%s: malformatted __.SYMDEF",
+                               get_file_name(entry));
        }
 
        /*
        }
 
        /*
@@ -268,19 +280,19 @@ symdef_library(desc, entry, member_length)
                         * Read the symbol table of the archive member.
                         */
 
                         * Read the symbol table of the archive member.
                         */
 
-                       subentry = decode_library_subfile(desc,
+                       subentry = decode_library_subfile(fd,
                                                      entry, offset, &junk);
                        if (subentry == 0)
                                                      entry, offset, &junk);
                        if (subentry == 0)
-                               fatal(
+                               errx(1,
                                "invalid offset for %s in symbol table of %s",
                                      sym_name_base
                                              + symdef_base[i].ran_un.ran_strx,
                                      entry->filename);
 
                                "invalid offset for %s in symbol table of %s",
                                      sym_name_base
                                              + symdef_base[i].ran_un.ran_strx,
                                      entry->filename);
 
-                       read_entry_symbols(desc, subentry);
+                       read_entry_symbols(fd, subentry);
                        subentry->strings = (char *)
                        subentry->strings = (char *)
-                               malloc(subentry->string_size);
-                       read_entry_strings(desc, subentry);
+                               alloca(subentry->string_size);
+                       read_entry_strings(fd, subentry);
 
                        /*
                         * Now scan the symbol table and decide whether to
 
                        /*
                         * Now scan the symbol table and decide whether to
@@ -289,6 +301,7 @@ symdef_library(desc, entry, member_length)
 
                        if (!(link_mode & FORCEARCHIVE) &&
                                        !subfile_wanted_p(subentry)) {
 
                        if (!(link_mode & FORCEARCHIVE) &&
                                        !subfile_wanted_p(subentry)) {
+                               if (subentry->symbols)
                                free(subentry->symbols);
                                free(subentry);
                        } else {
                                free(subentry->symbols);
                                free(subentry);
                        } else {
@@ -301,7 +314,7 @@ symdef_library(desc, entry, member_length)
 
                                not_finished = 1;
 
 
                                not_finished = 1;
 
-                               read_entry_relocation(desc, subentry);
+                               read_entry_relocation(fd, subentry);
                                enter_file_symbols(subentry);
 
                                if (prev)
                                enter_file_symbols(subentry);
 
                                if (prev)
@@ -320,28 +333,27 @@ symdef_library(desc, entry, member_length)
                                        if (symdef_base[j].ran_off == offset)
                                                symdef_base[j].ran_un.ran_strx = -1;
                                }
                                        if (symdef_base[j].ran_off == offset)
                                                symdef_base[j].ran_un.ran_strx = -1;
                                }
-                       }
 
                        /*
 
                        /*
-                        * We'll read the strings again if we need them
-                        * again.
+                                * We'll read the strings again
+                                * if we need them.
                         */
                         */
-                       free(subentry->strings);
                        subentry->strings = 0;
                }
        }
                        subentry->strings = 0;
                }
        }
+       }
 
        free(symdef_data);
 }
 
 /*
  * Search a library that has no __.SYMDEF. ENTRY is the library's file_entry.
 
        free(symdef_data);
 }
 
 /*
  * Search a library that has no __.SYMDEF. ENTRY is the library's file_entry.
- * DESC is the descriptor it is open on.
+ * FD is the descriptor it is open on.
  */
 
 static void
  */
 
 static void
-linear_library(desc, entry)
-       int             desc;
+linear_library(fd, entry)
+       int             fd;
        struct file_entry *entry;
 {
        register struct file_entry *prev = 0;
        struct file_entry *entry;
 {
        register struct file_entry *prev = 0;
@@ -353,22 +365,23 @@ linear_library(desc, entry)
                int                             member_length;
                register struct file_entry      *subentry;
 
                int                             member_length;
                register struct file_entry      *subentry;
 
-               subentry = decode_library_subfile(desc, entry,
+               subentry = decode_library_subfile(fd, entry,
                                        this_subfile_offset, &member_length);
 
                if (!subentry)
                        return;
 
                                        this_subfile_offset, &member_length);
 
                if (!subentry)
                        return;
 
-               read_entry_symbols(desc, subentry);
-               subentry->strings = (char *) alloca(subentry->string_size);
-               read_entry_strings(desc, subentry);
+               read_entry_symbols(fd, subentry);
+               subentry->strings = (char *)alloca(subentry->string_size);
+               read_entry_strings(fd, subentry);
 
                if (!(link_mode & FORCEARCHIVE) &&
                                        !subfile_wanted_p(subentry)) {
 
                if (!(link_mode & FORCEARCHIVE) &&
                                        !subfile_wanted_p(subentry)) {
+                       if (subentry->symbols)
                        free(subentry->symbols);
                        free(subentry);
                } else {
                        free(subentry->symbols);
                        free(subentry);
                } else {
-                       read_entry_relocation(desc, subentry);
+                       read_entry_relocation(fd, subentry);
                        enter_file_symbols(subentry);
 
                        if (prev)
                        enter_file_symbols(subentry);
 
                        if (prev)
@@ -527,6 +540,7 @@ subfile_wanted_p(entry)
                                        /*
                                         * But this member wants it to be
                                         * a common; ignore it.
                                        /*
                                         * But this member wants it to be
                                         * a common; ignore it.
+                                        */
                                        continue;
                        }
 
                                        continue;
                        }
 
@@ -550,7 +564,9 @@ subfile_wanted_p(entry)
 
                        if (write_map) {
                                print_file_name(entry, stdout);
 
                        if (write_map) {
                                print_file_name(entry, stdout);
-                               fprintf(stdout, " needed due to shared lib ref %s\n", sp->name);
+                               fprintf(stdout,
+                                       " needed due to shared lib ref %s\n",
+                                       sp->name);
                        }
                        return 1;
                }
                        }
                        return 1;
                }
@@ -561,12 +577,12 @@ subfile_wanted_p(entry)
 
 /*
  * Read the symbols of dynamic entity ENTRY into core. Assume it is already
 
 /*
  * Read the symbols of dynamic entity ENTRY into core. Assume it is already
- * open, on descriptor DESC.
+ * open, on descriptor FD.
  */
 void
  */
 void
-read_shared_object (desc, entry)
+read_shared_object(fd, entry)
      struct file_entry *entry;
      struct file_entry *entry;
-     int desc;
+       int fd;
 {
        struct _dynamic                 dyn;
        struct section_dispatch_table   sdt;
 {
        struct _dynamic                 dyn;
        struct section_dispatch_table   sdt;
@@ -575,22 +591,23 @@ read_shared_object (desc, entry)
        int                             n, i, has_nz = 0;
 
        if (!(entry->flags & E_HEADER_VALID))
        int                             n, i, has_nz = 0;
 
        if (!(entry->flags & E_HEADER_VALID))
-               read_header (desc, entry);
+               read_header(fd, entry);
 
        /* Read DYNAMIC structure (first in data segment) */
 
        /* Read DYNAMIC structure (first in data segment) */
-       lseek (desc,
-               text_offset (entry) + entry->header.a_text,
-               L_SET);
-       if (read(desc, &dyn, sizeof dyn) != sizeof dyn) {
-               fatal_with_file (
-                       "premature eof in data segment of ", entry);
+       if (lseek(fd, text_offset(entry) + entry->header.a_text, L_SET) ==
+           (off_t)-1)
+               err(1, "%s: lseek", get_file_name(entry));
+       if (read(fd, &dyn, sizeof dyn) != sizeof dyn) {
+               errx(1, "%s: premature EOF reading _dynamic",
+                       get_file_name(entry));
        }
        md_swapin__dynamic(&dyn);
 
        /* Check version */
        switch (dyn.d_version) {
        default:
        }
        md_swapin__dynamic(&dyn);
 
        /* Check version */
        switch (dyn.d_version) {
        default:
-               fatal_with_file( "unsupported _DYNAMIC version ", entry);
+               errx(1, "%s: unsupported _DYNAMIC version: %d",
+                       get_file_name(entry), dyn.d_version);
                break;
        case LD_VERSION_SUN:
                break;
                break;
        case LD_VERSION_SUN:
                break;
@@ -600,29 +617,33 @@ read_shared_object (desc, entry)
        }
 
        /* Read Section Dispatch Table (from data segment) */
        }
 
        /* Read Section Dispatch Table (from data segment) */
-       lseek (desc,
+       if (lseek(fd,
                text_offset(entry) + (long)dyn.d_un.d_sdt -
                        (DATA_START(entry->header) - N_DATOFF(entry->header)),
                text_offset(entry) + (long)dyn.d_un.d_sdt -
                        (DATA_START(entry->header) - N_DATOFF(entry->header)),
-               L_SET);
-       if (read(desc, &sdt, sizeof sdt) != sizeof sdt) {
-               fatal_with_file( "premature eof in data segment of ", entry);
-       }
+           L_SET) == (off_t)-1)
+               err(1, "%s: lseek", get_file_name(entry));
+       if (read(fd, &sdt, sizeof sdt) != sizeof sdt)
+               errx(1, "%s: premature EOF reading sdt",
+                       get_file_name(entry));
        md_swapin_section_dispatch_table(&sdt);
 
        /* Read symbols (text segment) */
        n = sdt.sdt_strings - sdt.sdt_nzlist;
        entry->nsymbols = n /
                (has_nz ? sizeof(struct nzlist) : sizeof(struct nlist));
        md_swapin_section_dispatch_table(&sdt);
 
        /* Read symbols (text segment) */
        n = sdt.sdt_strings - sdt.sdt_nzlist;
        entry->nsymbols = n /
                (has_nz ? sizeof(struct nzlist) : sizeof(struct nlist));
-       nzp = (struct nzlist *)(np = (struct nlist *) alloca (n));
+       nzp = (struct nzlist *)(np = (struct nlist *)alloca (n));
        entry->symbols = (struct localsymbol *)
                        xmalloc(entry->nsymbols * sizeof(struct localsymbol));
        entry->symbols = (struct localsymbol *)
                        xmalloc(entry->nsymbols * sizeof(struct localsymbol));
-       lseek(desc, text_offset(entry) + (long)sdt.sdt_nzlist -
+
+       if (lseek(fd,
+           text_offset(entry) + (long)sdt.sdt_nzlist -
                        (TEXT_START(entry->header) - N_TXTOFF(entry->header)),
                        (TEXT_START(entry->header) - N_TXTOFF(entry->header)),
-               L_SET);
-       if (read(desc, (char *)nzp, n) != n) {
-               fatal_with_file(
-                       "premature eof while reading object symbols ", entry);
-       }
+           L_SET) == (off_t)-1)
+               err(1, "%s: lseek", get_file_name(entry));
+       if (read(fd, (char *)nzp, n) != n)
+               errx(1, "%s: premature EOF reading symbols ",
+                       get_file_name(entry));
+
        if (has_nz)
                md_swapin_zsymbols(nzp, entry->nsymbols);
        else
        if (has_nz)
                md_swapin_zsymbols(nzp, entry->nsymbols);
        else
@@ -645,15 +666,16 @@ read_shared_object (desc, entry)
 
        /* Read strings (text segment) */
        n = entry->string_size = sdt.sdt_str_sz;
 
        /* Read strings (text segment) */
        n = entry->string_size = sdt.sdt_str_sz;
-       entry->strings = (char *) alloca(n);
+       entry->strings = (char *)alloca(n);
        entry->strings_offset = text_offset(entry) + sdt.sdt_strings;
        entry->strings_offset = text_offset(entry) + sdt.sdt_strings;
-       lseek(desc, entry->strings_offset -
+       if (lseek(fd,
+           entry->strings_offset -
                        (TEXT_START(entry->header) - N_TXTOFF(entry->header)),
                        (TEXT_START(entry->header) - N_TXTOFF(entry->header)),
-               L_SET);
-       if (read(desc, entry->strings, n) != n) {
-               fatal_with_file(
-                       "premature eof while reading object strings ", entry);
-       }
+           L_SET) == (off_t)-1)
+               err(1, "%s: lseek", get_file_name(entry));
+       if (read(fd, entry->strings, n) != n)
+               errx(1, "%s: premature EOF reading strings",
+                       get_file_name(entry));
        enter_file_symbols (entry);
        entry->strings = 0;
 
        enter_file_symbols (entry);
        entry->strings = 0;
 
@@ -675,19 +697,21 @@ read_shared_object (desc, entry)
                        bzero(subentry, sizeof(struct file_entry));
                        subentry->superfile = entry;
 
                        bzero(subentry, sizeof(struct file_entry));
                        subentry->superfile = entry;
 
-                       lseek(desc, offset -
-                          (TEXT_START(entry->header) - N_TXTOFF(entry->header)),
-                               L_SET);
-                       if (read(desc, &sod, sizeof(sod)) != sizeof(sod)) {
-                               fatal_with_file(
-                               "premature eof while reading sod ",
-                                               entry);
-                       }
+                       if (lseek(fd,
+                           offset - (TEXT_START(entry->header) -
+                                     N_TXTOFF(entry->header)),
+                           L_SET) == (off_t)-1)
+                               err(1, "%s: lseek", get_file_name(entry));
+                       if (read(fd, &sod, sizeof(sod)) != sizeof(sod))
+                               errx(1, "%s: premature EOF reding sod",
+                                       get_file_name(entry));
                        md_swapin_sod(&sod, 1);
                        md_swapin_sod(&sod, 1);
-                       (void)lseek(desc, (off_t)sod.sod_name -
-                          (TEXT_START(entry->header) - N_TXTOFF(entry->header)),
-                          L_SET);
-                       (void)read(desc, name, sizeof(name)); /*XXX*/
+                       if (lseek(fd,
+                           (off_t)sod.sod_name - (TEXT_START(entry->header) -
+                                                  N_TXTOFF(entry->header)),
+                           L_SET) == (off_t)-1)
+                               err(1, "%s: lseek", get_file_name(entry));
+                       (void)read(fd, name, sizeof(name)); /*XXX*/
                        if (sod.sod_library) {
                                int sod_major = sod.sod_major;
                                int sod_minor = sod.sod_minor;
                        if (sod.sod_library) {
                                int sod_major = sod.sod_major;
                                int sod_minor = sod.sod_minor;
@@ -695,7 +719,7 @@ read_shared_object (desc, entry)
                                libname = findshlib(name,
                                                &sod_major, &sod_minor, 0);
                                if (libname == NULL)
                                libname = findshlib(name,
                                                &sod_major, &sod_minor, 0);
                                if (libname == NULL)
-                                       fatal("no shared -l%s.%d.%d available",
+                                       errx(1,"no shared -l%s.%d.%d available",
                                        name, sod.sod_major, sod.sod_minor);
                                subentry->filename = libname;
                                subentry->local_sym_name = concat("-l", name, "");
                                        name, sod.sod_major, sod.sod_minor);
                                subentry->filename = libname;
                                subentry->local_sym_name = concat("-l", name, "");
@@ -710,7 +734,7 @@ read_shared_object (desc, entry)
                        else
                                entry->subfiles = subentry;
                        prev = subentry;
                        else
                                entry->subfiles = subentry;
                        prev = subentry;
-                       desc = file_open(entry);
+                       fd = file_open(entry);
                        if ((offset = (off_t)sod.sod_next) == 0)
                                break;
                }
                        if ((offset = (off_t)sod.sod_next) == 0)
                                break;
                }
@@ -746,7 +770,7 @@ read_shared_object (desc, entry)
                (void)read(fd, armag, SARMAG);
                (void)close(fd);
                if (strncmp(armag, ARMAG, SARMAG) != 0) {
                (void)read(fd, armag, SARMAG);
                (void)close(fd);
                if (strncmp(armag, ARMAG, SARMAG) != 0) {
-                       error("%s: malformed silly archive",
+                       warnx("%s: malformed silly archive",
                                        get_file_name(entry));
                        goto out;
                }
                                        get_file_name(entry));
                        goto out;
                }
@@ -774,9 +798,8 @@ int
 findlib(p)
 struct file_entry      *p;
 {
 findlib(p)
 struct file_entry      *p;
 {
-       int             desc;
        int             i;
        int             i;
-       int             len;
+       int             fd = -1;
        int             major = -1, minor = -1;
        char            *cp, *fname = NULL;
 
        int             major = -1, minor = -1;
        char            *cp, *fname = NULL;
 
@@ -785,14 +808,14 @@ struct file_entry *p;
 
        fname = findshlib(p->filename, &major, &minor, 1);
 
 
        fname = findshlib(p->filename, &major, &minor, 1);
 
-       if (fname && (desc = open (fname, O_RDONLY, 0)) > 0) {
+       if (fname && (fd = open(fname, O_RDONLY, 0)) > 0) {
                p->filename = fname;
                p->lib_major = major;
                p->lib_minor = minor;
                p->flags &= ~E_SEARCH_DIRS;
                p->filename = fname;
                p->lib_major = major;
                p->lib_minor = minor;
                p->flags &= ~E_SEARCH_DIRS;
-               return desc;
+               return fd;
        }
        }
-       free (fname);
+       (void)free(fname);
 
 dot_a:
        p->flags &= ~E_SEARCH_DYNAMIC;
 
 dot_a:
        p->flags &= ~E_SEARCH_DYNAMIC;
@@ -804,16 +827,17 @@ dot_a:
                fname = concat("lib", p->filename, ".a");
 
        for (i = 0; i < n_search_dirs; i++) {
                fname = concat("lib", p->filename, ".a");
 
        for (i = 0; i < n_search_dirs; i++) {
-               register char *string
-                       = concat (search_dirs[i], "/", fname);
-               desc = open (string, O_RDONLY, 0);
-               if (desc > 0) {
-                       p->filename = string;
+               register char *path
+                       = concat(search_dirs[i], "/", fname);
+               fd = open(path, O_RDONLY, 0);
+               if (fd > 0) {
+                       p->filename = path;
                        p->flags &= ~E_SEARCH_DIRS;
                        break;
                }
                        p->flags &= ~E_SEARCH_DIRS;
                        break;
                }
-               free (string);
+               (void)free(path);
        }
        }
-       return desc;
+       (void)free(fname);
+       return fd;
 }
 
 }
 
index 6c042d9..a0627e7 100644 (file)
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- *     $Id: rrs.c,v 1.10 1993/12/11 11:58:28 jkh Exp $
+ *     $Id: rrs.c,v 1.11 1994/02/13 20:41:40 jkh Exp $
  */
 
 #include <sys/param.h>
  */
 
 #include <sys/param.h>
-#include <stdio.h>
-#include <stdlib.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/file.h>
 #include <sys/time.h>
 #include <sys/resource.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/file.h>
 #include <sys/time.h>
 #include <sys/resource.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <err.h>
 #include <fcntl.h>
 #include <ar.h>
 #include <ranlib.h>
 #include <a.out.h>
 #include <stab.h>
 #include <string.h>
 #include <fcntl.h>
 #include <ar.h>
 #include <ranlib.h>
 #include <a.out.h>
 #include <stab.h>
 #include <string.h>
-#include <strings.h>
 
 #include "ld.h"
 
 
 #include "ld.h"
 
@@ -228,7 +229,7 @@ struct localsymbol  *lsp;
        if (!RELOC_EXTERN_P(r)) {
 
                if (sp != NULL) {
        if (!RELOC_EXTERN_P(r)) {
 
                if (sp != NULL) {
-                       error("%s: relocation for internal symbol expected at %#x",
+                       warnx("%s: relocation for internal symbol expected at %#x",
                                get_file_name(entry), RELOC_ADDRESS(r));
                        return;
                }
                                get_file_name(entry), RELOC_ADDRESS(r));
                        return;
                }
@@ -253,7 +254,7 @@ struct localsymbol  *lsp;
        } else {
 
                if (sp == NULL) {
        } else {
 
                if (sp == NULL) {
-                       error("%s: relocation must refer to global symbol at %#x",
+                       warnx("%s: relocation must refer to global symbol at %#x",
                                get_file_name(entry), RELOC_ADDRESS(r));
                        return;
                }
                                get_file_name(entry), RELOC_ADDRESS(r));
                        return;
                }
@@ -296,7 +297,7 @@ rrs_next_reloc()
 
        r = rrs_reloc + claimed_rrs_relocs++;
        if (claimed_rrs_relocs > reserved_rrs_relocs)
 
        r = rrs_reloc + claimed_rrs_relocs++;
        if (claimed_rrs_relocs > reserved_rrs_relocs)
-               fatal("internal error: RRS relocs exceed allocation %d",
+               errx(1, "internal error: RRS relocs exceed allocation %d",
                        reserved_rrs_relocs);
        return r;
 }
                        reserved_rrs_relocs);
        return r;
 }
@@ -319,7 +320,7 @@ long        *relocation;
        struct relocation_info  *r = rrs_next_reloc();
 
        if (rp->r_address < text_start + text_size)
        struct relocation_info  *r = rrs_next_reloc();
 
        if (rp->r_address < text_start + text_size)
-               error("%s: RRS text relocation at %#x for \"%s\"",
+               warnx("%s: RRS text relocation at %#x for \"%s\"",
                        get_file_name(entry), rp->r_address, sp->name);
 
 #ifdef DEBUG
                        get_file_name(entry), rp->r_address, sp->name);
 
 #ifdef DEBUG
@@ -330,7 +331,7 @@ printf("claim_rrs_reloc: %s in %s\n", sp->name, get_file_name(entry));
 
        if (link_mode & SYMBOLIC) {
                if (!sp->defined)
 
        if (link_mode & SYMBOLIC) {
                if (!sp->defined)
-                       error("Cannot reduce symbol \"%s\" in %s",
+                       warnx("Cannot reduce symbol \"%s\" in %s",
                                        sp->name, get_file_name(entry));
                RELOC_EXTERN_P(r) = 0;
                *relocation += sp->value;
                                        sp->name, get_file_name(entry));
                RELOC_EXTERN_P(r) = 0;
                *relocation += sp->value;
@@ -358,20 +359,20 @@ long                      addend;
                return rrs_sdt.sdt_plt + sp->jmpslot_offset;
 
 #ifdef DEBUG
                return rrs_sdt.sdt_plt + sp->jmpslot_offset;
 
 #ifdef DEBUG
-printf("claim_rrs_jmpslot: %s: %s(%d) -> offset %x (textreloc %#x)\n",
+printf("claim_rrs_jmpslot: %s: %s(%d) -> offset %x\n",
        get_file_name(entry),
        get_file_name(entry),
-       sp->name, sp->rrs_symbolnum, sp->jmpslot_offset, text_relocation);
+       sp->name, sp->rrs_symbolnum, sp->jmpslot_offset);
 #endif
 
        if (sp->jmpslot_offset == -1)
 #endif
 
        if (sp->jmpslot_offset == -1)
-               fatal(
+               errx(1,
                "internal error: %s: claim_rrs_jmpslot: %s: jmpslot_offset == -1\n",
                get_file_name(entry),
                sp->name);
 
        if ((link_mode & SYMBOLIC) || rrs_section_type == RRS_PARTIAL) {
                if (!sp->defined)
                "internal error: %s: claim_rrs_jmpslot: %s: jmpslot_offset == -1\n",
                get_file_name(entry),
                sp->name);
 
        if ((link_mode & SYMBOLIC) || rrs_section_type == RRS_PARTIAL) {
                if (!sp->defined)
-                       error("Cannot reduce symbol \"%s\" in %s",
+                       warnx("Cannot reduce symbol \"%s\" in %s",
                                sp->name, get_file_name(entry));
 
                md_fix_jmpslot( rrs_plt + sp->jmpslot_offset/sizeof(jmpslot_t),
                                sp->name, get_file_name(entry));
 
                md_fix_jmpslot( rrs_plt + sp->jmpslot_offset/sizeof(jmpslot_t),
@@ -439,7 +440,7 @@ printf("claim_rrs_gotslot: %s(%d) slot offset %#x, addend %#x\n",
         sp->name, sp->rrs_symbolnum, sp->gotslot_offset, addend);
 #endif
        if (sp->gotslot_offset == -1)
         sp->name, sp->rrs_symbolnum, sp->gotslot_offset, addend);
 #endif
        if (sp->gotslot_offset == -1)
-               fatal(
+               errx(1,
                "internal error: %s: claim_rrs_gotslot: %s: gotslot_offset == -1\n",
                        get_file_name(entry), sp->name);
 
                "internal error: %s: claim_rrs_gotslot: %s: gotslot_offset == -1\n",
                        get_file_name(entry), sp->name);
 
@@ -464,7 +465,7 @@ printf("claim_rrs_gotslot: %s(%d) slot offset %#x, addend %#x\n",
                 * RRS_PARTIAL: we don't link against shared objects,
                 * so again all symbols must be known.
                 */
                 * RRS_PARTIAL: we don't link against shared objects,
                 * so again all symbols must be known.
                 */
-               error("Cannot reduce symbol \"%s\" in %s",
+               warnx("Cannot reduce symbol \"%s\" in %s",
                                sp->name, get_file_name(entry));
 
        } else {
                                sp->name, get_file_name(entry));
 
        } else {
@@ -483,7 +484,7 @@ printf("claim_rrs_gotslot: %s(%d) slot offset %#x, addend %#x\n",
                 * NOTE: RRS_PARTIAL implies !SHAREABLE.
                 */
                if (!sp->defined)
                 * NOTE: RRS_PARTIAL implies !SHAREABLE.
                 */
                if (!sp->defined)
-                       error("Cannot reduce symbol \"%s\" in %s",
+                       warnx("Cannot reduce symbol \"%s\" in %s",
                                        sp->name, get_file_name(entry));
                return sp->gotslot_offset;
        }
                                        sp->name, get_file_name(entry));
                return sp->gotslot_offset;
        }
@@ -532,7 +533,7 @@ printf("claim_rrs_internal_gotslot: %s: slot offset %#x, addend = %#x\n",
 #endif
 
        if (lsp->gotslot_offset == -1)
 #endif
 
        if (lsp->gotslot_offset == -1)
-               fatal(
+               errx(1,
                "internal error: %s: claim_rrs_internal_gotslot at %#x: slot_offset == -1\n",
                        get_file_name(entry), RELOC_ADDRESS(rp));
 
                "internal error: %s: claim_rrs_internal_gotslot at %#x: slot_offset == -1\n",
                        get_file_name(entry), RELOC_ADDRESS(rp));
 
@@ -568,7 +569,8 @@ symbol *sp;
                return;
 
        if (!(sp->flags & GS_CPYRELOCRESERVED))
                return;
 
        if (!(sp->flags & GS_CPYRELOCRESERVED))
-               fatal("internal error: %s: claim_cpy_reloc: %s: no reservation\n",
+               errx(1,
+               "internal error: %s: claim_cpy_reloc: %s: no reservation\n",
                        get_file_name(entry), sp->name);
 
 #ifdef DEBUG
                        get_file_name(entry), sp->name);
 
 #ifdef DEBUG
@@ -652,7 +654,6 @@ consider_rrs_section_lengths()
 {
        int             n;
        struct shobj    *shp, **shpp;
 {
        int             n;
        struct shobj    *shp, **shpp;
-       int             symbolsize;
 
 #ifdef notyet
 /* We run into trouble with this as long as shared object symbols
 
 #ifdef notyet
 /* We run into trouble with this as long as shared object symbols
@@ -663,7 +664,7 @@ consider_rrs_section_lengths()
        for (shpp = &rrs_shobjs; *shpp; shpp = &(*shpp)->next) {
                while (*shpp && !((*shpp)->entry->flags & E_SYMBOLS_USED)) {
                        if (--number_of_shobjs < 0)
        for (shpp = &rrs_shobjs; *shpp; shpp = &(*shpp)->next) {
                while (*shpp && !((*shpp)->entry->flags & E_SYMBOLS_USED)) {
                        if (--number_of_shobjs < 0)
-                               fatal("internal error: number_of_shobjs < 0");
+                               errx(1, "internal error: number_of_shobjs < 0");
                        *shpp = (*shpp)->next;
                }
                if (*shpp == NULL)
                        *shpp = (*shpp)->next;
                }
                if (*shpp == NULL)
@@ -703,7 +704,7 @@ consider_rrs_section_lengths()
         */
        if (!(link_mode & SHAREABLE) &&
                        !(dynamic_symbol->flags & GS_REFERENCED))
         */
        if (!(link_mode & SHAREABLE) &&
                        !(dynamic_symbol->flags & GS_REFERENCED))
-               fatal("No reference to __DYNAMIC");
+               errx(1, "No reference to __DYNAMIC");
 
        dynamic_symbol->flags |= GS_REFERENCED;
 
 
        dynamic_symbol->flags |= GS_REFERENCED;
 
@@ -891,21 +892,21 @@ write_rrs_data()
 
        pos = rrs_data_start + (N_DATOFF(outheader) - DATA_START(outheader));
        if (lseek(outdesc, pos, L_SET) != pos)
 
        pos = rrs_data_start + (N_DATOFF(outheader) - DATA_START(outheader));
        if (lseek(outdesc, pos, L_SET) != pos)
-               fatal("write_rrs_data: cant position in output file");
+               err(1, "write_rrs_data: lseek");
 
        if (rrs_section_type == RRS_PARTIAL) {
                /*
                 * Only a GOT and PLT are needed.
                 */
                if (number_of_gotslots <= 1)
 
        if (rrs_section_type == RRS_PARTIAL) {
                /*
                 * Only a GOT and PLT are needed.
                 */
                if (number_of_gotslots <= 1)
-                       fatal("write_rrs_data: # gotslots <= 1");
+                       errx(1, "write_rrs_data: # gotslots <= 1");
 
                md_swapout_got(rrs_got, number_of_gotslots);
                mywrite(rrs_got, number_of_gotslots,
                                        sizeof(got_t), outdesc);
 
                if (number_of_jmpslots <= 1)
 
                md_swapout_got(rrs_got, number_of_gotslots);
                mywrite(rrs_got, number_of_gotslots,
                                        sizeof(got_t), outdesc);
 
                if (number_of_jmpslots <= 1)
-                       fatal("write_rrs_data: # jmpslots <= 1");
+                       errx(1, "write_rrs_data: # jmpslots <= 1");
 
                md_swapout_jmpslot(rrs_plt, number_of_jmpslots);
                mywrite(rrs_plt, number_of_jmpslots,
 
                md_swapout_jmpslot(rrs_plt, number_of_jmpslots);
                mywrite(rrs_plt, number_of_jmpslots,
@@ -945,7 +946,7 @@ write_rrs_text()
 
        pos = rrs_text_start + (N_TXTOFF(outheader) - TEXT_START(outheader));
        if (lseek(outdesc, pos, L_SET) != pos)
 
        pos = rrs_text_start + (N_TXTOFF(outheader) - TEXT_START(outheader));
        if (lseek(outdesc, pos, L_SET) != pos)
-               fatal("write_rrs_text: cant position in output file");
+               err(1, "write_rrs_text: lseek");
 
        /* Write relocation records */
        md_swapout_reloc(rrs_reloc, reserved_rrs_relocs);
 
        /* Write relocation records */
        md_swapout_reloc(rrs_reloc, reserved_rrs_relocs);
@@ -989,7 +990,7 @@ write_rrs_text()
 
                if ((long)nlp - (long)rrs_symbols >=
                                        number_of_rrs_symbols * rrs_symbol_size)
 
                if ((long)nlp - (long)rrs_symbols >=
                                        number_of_rrs_symbols * rrs_symbol_size)
-                       fatal(
+                       errx(1,
                            "internal error: rrs symbols exceed allocation %d ",
                                number_of_rrs_symbols);
 
                            "internal error: rrs symbols exceed allocation %d ",
                                number_of_rrs_symbols);
 
@@ -1040,14 +1041,14 @@ write_rrs_text()
                                 * Define a "weak" function symbol.
                                 */
                                if (sp->aux != AUX_FUNC)
                                 * Define a "weak" function symbol.
                                 */
                                if (sp->aux != AUX_FUNC)
-                                       fatal("%s: non-function jmpslot",
+                                       errx(1, "%s: non-function jmpslot",
                                                                sp->name);
                                nlp->nz_other = N_OTHER(0, sp->aux);
                                nlp->nz_value =
                                        rrs_sdt.sdt_plt + sp->jmpslot_offset;
                        }
                } else
                                                                sp->name);
                                nlp->nz_other = N_OTHER(0, sp->aux);
                                nlp->nz_value =
                                        rrs_sdt.sdt_plt + sp->jmpslot_offset;
                        }
                } else
-                       fatal(
+                       errx(1,
                              "internal error: %s defined in mysterious way",
                              sp->name);
 
                              "internal error: %s defined in mysterious way",
                              sp->name);
 
@@ -1079,7 +1080,7 @@ write_rrs_text()
        } END_EACH_SYMBOL;
 
        if (MALIGN(offset) != rrs_strtab_size)
        } END_EACH_SYMBOL;
 
        if (MALIGN(offset) != rrs_strtab_size)
-               fatal(
+               errx(1,
                "internal error: inconsistent RRS string table length: %d, expected %d",
                        offset, rrs_strtab_size);
 
                "internal error: inconsistent RRS string table length: %d, expected %d",
                        offset, rrs_strtab_size);
 
@@ -1103,7 +1104,7 @@ write_rrs_text()
                char    *name = shp->entry->local_sym_name;
 
                if (i >= number_of_shobjs)
                char    *name = shp->entry->local_sym_name;
 
                if (i >= number_of_shobjs)
-                       fatal("internal error: # of link objects exceeds %d",
+                       errx(1, "internal error: # of link objects exceeds %d",
                                number_of_shobjs);
 
                sodp[i].sod_name = pos;
                                number_of_shobjs);
 
                sodp[i].sod_name = pos;
@@ -1122,7 +1123,8 @@ write_rrs_text()
        }
 
        if (i < number_of_shobjs)
        }
 
        if (i < number_of_shobjs)
-               fatal("internal error: # of link objects less then expected %d",
+               errx(1,
+               "internal error: # of link objects less then expected %d",
                                number_of_shobjs);
 
        md_swapout_sod(sodp, number_of_shobjs);
                                number_of_shobjs);
 
        md_swapout_sod(sodp, number_of_shobjs);
@@ -1148,7 +1150,7 @@ write_rrs()
         */
        if (rrs_section_type == RRS_NONE) {
                if (reserved_rrs_relocs > 1)
         */
        if (rrs_section_type == RRS_NONE) {
                if (reserved_rrs_relocs > 1)
-                       fatal(
+                       errx(1,
                        "internal error: RRS relocs in static program: %d",
                                reserved_rrs_relocs-1);
                return;
                        "internal error: RRS relocs in static program: %d",
                                reserved_rrs_relocs-1);
                return;
@@ -1159,14 +1161,17 @@ printf("rrs_relocs %d, gotslots %d, jmpslots %d\n",
        reserved_rrs_relocs, number_of_gotslots-1, number_of_jmpslots-1);
 #endif
 
        reserved_rrs_relocs, number_of_gotslots-1, number_of_jmpslots-1);
 #endif
 
+#if 0
+       /* Must fix this check: misses out when linking PIC code but no
+          shared object involved: reserved relocs are never claimed!
+       */
        if (claimed_rrs_relocs != reserved_rrs_relocs) {
        if (claimed_rrs_relocs != reserved_rrs_relocs) {
-/*
-               fatal("internal error: reserved relocs(%d) != claimed(%d)",
+               errx(1, "internal error: reserved relocs(%d) != claimed(%d)",
                        reserved_rrs_relocs, claimed_rrs_relocs);
                        reserved_rrs_relocs, claimed_rrs_relocs);
-*/
                printf("FIX:internal error: reserved relocs(%d) != claimed(%d)\n",
                        reserved_rrs_relocs, claimed_rrs_relocs);
        }
                printf("FIX:internal error: reserved relocs(%d) != claimed(%d)\n",
                        reserved_rrs_relocs, claimed_rrs_relocs);
        }
+#endif
 
        /* Write the RRS segments. */
        write_rrs_text ();
 
        /* Write the RRS segments. */
        write_rrs_text ();
index 04f6b9f..b5c54f8 100644 (file)
@@ -33,7 +33,7 @@
 
 #if defined(LIBC_SCCS) && !defined(lint)
 /*static char *sccsid = "from: @(#)malloc.c    5.11 (Berkeley) 2/23/91";*/
 
 #if defined(LIBC_SCCS) && !defined(lint)
 /*static char *sccsid = "from: @(#)malloc.c    5.11 (Berkeley) 2/23/91";*/
-static char *rcsid = "$Id: malloc.c,v 1.1 1994/01/28 21:01:22 pk Exp $";
+static char *rcsid = "$Id: malloc.c,v 1.1 1994/02/13 20:44:09 jkh Exp $";
 #endif /* LIBC_SCCS and not lint */
 
 /*
 #endif /* LIBC_SCCS and not lint */
 
 /*
@@ -48,6 +48,7 @@ static char *rcsid = "$Id: malloc.c,v 1.1 1994/01/28 21:01:22 pk Exp $";
  */
 
 #include <sys/types.h>
  */
 
 #include <sys/types.h>
+#include <err.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
@@ -460,7 +461,7 @@ int n;
                caddr_t addr = (caddr_t)
                        (((int)pagepool_start + pagesz - 1) & ~(pagesz - 1));
                if (munmap(addr, pagepool_end - addr) != 0)
                caddr_t addr = (caddr_t)
                        (((int)pagepool_start + pagesz - 1) & ~(pagesz - 1));
                if (munmap(addr, pagepool_end - addr) != 0)
-                       perror("munmap");
+                       warn("morepages: munmap %p", addr);
        }
 
        offset = (int)pagepool_start - ((int)pagepool_start & ~(pagesz - 1));
        }
 
        offset = (int)pagepool_start - ((int)pagepool_start & ~(pagesz - 1));
index de86819..96dd0fe 100644 (file)
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- *     $Id: rtld.c,v 1.15 1994/02/13 20:42:53 jkh Exp $
+ *     $Id: rtld.c,v 1.16 1994/04/13 20:52:40 ats Exp $
  */
 
  */
 
-#include <machine/vmparam.h>
 #include <sys/param.h>
 #include <sys/param.h>
-#include <stdio.h>
-#include <stdlib.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/file.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/file.h>
 #include <sys/mman.h>
 #ifndef BSD
 #define MAP_COPY       MAP_PRIVATE
 #include <sys/mman.h>
 #ifndef BSD
 #define MAP_COPY       MAP_PRIVATE
-#define MAP_FILE       0
 #define MAP_ANON       0
 #endif
 #define MAP_ANON       0
 #endif
+#include <err.h>
 #include <fcntl.h>
 #include <a.out.h>
 #include <stab.h>
 #include <fcntl.h>
 #include <a.out.h>
 #include <stab.h>
+#include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <string.h>
+#include <unistd.h>
 #if __STDC__
 #include <stdarg.h>
 #else
 #if __STDC__
 #include <stdarg.h>
 #else
@@ -123,34 +123,37 @@ struct somap_private {
 #define LM_PARENT(smp) (LM_PRIVATE(smp)->spd_parent)
 
 char                   **environ;
 #define LM_PARENT(smp) (LM_PRIVATE(smp)->spd_parent)
 
 char                   **environ;
+char                   *__progname;
 int                    errno;
 int                    errno;
+
 static uid_t           uid, euid;
 static gid_t           gid, egid;
 static int             careful;
 static uid_t           uid, euid;
 static gid_t           gid, egid;
 static int             careful;
-static char            *main_progname = "main";
+static char            __main_progname[] = "main";
+static char            *main_progname = __main_progname;
+static char            us[] = "/usr/libexec/ld.so";
 
 struct so_map          *link_map_head, *main_map;
 struct so_map          **link_map_tail = &link_map_head;
 struct rt_symbol       *rt_symbol_head;
 
 
 struct so_map          *link_map_head, *main_map;
 struct so_map          **link_map_tail = &link_map_head;
 struct rt_symbol       *rt_symbol_head;
 
-void           *dlopen __P((char *, int));
-int            dlclose __P((void *));
-void           *dlsym __P((void *, char *));
-int            dlctl __P((void *, int, void *));
+static void            *__dlopen __P((char *, int));
+static int             __dlclose __P((void *));
+static void            *__dlsym __P((void *, char *));
+static int             __dlctl __P((void *, int, void *));
 
 
-struct ld_entry        ld_entry = {
-       dlopen, dlclose, dlsym, dlctl
+static struct ld_entry ld_entry = {
+       __dlopen, __dlclose, __dlsym, __dlctl
 };
 
        void            xprintf __P((char *, ...));
 };
 
        void            xprintf __P((char *, ...));
-static void            init_brk __P((void));
 static void            load_objects __P((      struct crt_ldso *,
                                                struct _dynamic *));
 static struct so_map   *map_object __P((struct sod *, struct so_map *));
 static struct so_map   *alloc_link_map __P((   char *, struct sod *,
                                                struct so_map *, caddr_t,
                                                struct _dynamic *));
 static void            load_objects __P((      struct crt_ldso *,
                                                struct _dynamic *));
 static struct so_map   *map_object __P((struct sod *, struct so_map *));
 static struct so_map   *alloc_link_map __P((   char *, struct sod *,
                                                struct so_map *, caddr_t,
                                                struct _dynamic *));
-static void inline     check_text_reloc __P((  struct relocation_info *,
+static inline void     check_text_reloc __P((  struct relocation_info *,
                                                struct so_map *,
                                                caddr_t));
 static void            reloc_map __P((struct so_map *));
                                                struct so_map *,
                                                caddr_t));
 static void            reloc_map __P((struct so_map *));
@@ -188,7 +191,6 @@ struct _dynamic             *dp;
        int                     n;
        int                     nreloc;         /* # of ld.so relocations */
        struct relocation_info  *reloc;
        int                     n;
        int                     nreloc;         /* # of ld.so relocations */
        struct relocation_info  *reloc;
-       char                    **envp;
        struct so_debug         *ddp;
        struct so_map           *smp;
 
        struct so_debug         *ddp;
        struct so_map           *smp;
 
@@ -217,7 +219,7 @@ struct _dynamic             *dp;
                md_relocate_simple(reloc, crtp->crt_ba, addr);
        }
 
                md_relocate_simple(reloc, crtp->crt_ba, addr);
        }
 
-       progname = "ld.so";
+       __progname = "ld.so";
        if (version >= CRT_VERSION_BSD_3)
                main_progname = crtp->crt_prog;
 
        if (version >= CRT_VERSION_BSD_3)
                main_progname = crtp->crt_prog;
 
@@ -237,7 +239,10 @@ struct _dynamic            *dp;
        }
 
        /* Setup directory search */
        }
 
        /* Setup directory search */
-       std_search_dirs(getenv("LD_LIBRARY_PATH"));
+       add_search_path(getenv("LD_RUN_PATH"));
+       add_search_path(getenv("LD_LIBRARY_PATH"));
+       if (getenv("LD_NOSTD_PATH") == NULL)
+               std_search_path();
 
        /* Load required objects into the process address space */
        load_objects(crtp, dp);
 
        /* Load required objects into the process address space */
        load_objects(crtp, dp);
@@ -275,12 +280,12 @@ struct _dynamic           *dp;
                /* Set breakpoint for the benefit of debuggers */
                if (mprotect(addr, PAGSIZ,
                                PROT_READ|PROT_WRITE|PROT_EXEC) == -1) {
                /* Set breakpoint for the benefit of debuggers */
                if (mprotect(addr, PAGSIZ,
                                PROT_READ|PROT_WRITE|PROT_EXEC) == -1) {
-                       perror("mprotect"),
-                       fatal("Cannot set breakpoint (%s)\n", main_progname);
+                       err(1, "Cannot set breakpoint (%s)", main_progname);
                }
                }
-               md_set_breakpoint(crtp->crt_bp, &ddp->dd_bpt_shadow);
+               md_set_breakpoint((long)crtp->crt_bp, (long *)&ddp->dd_bpt_shadow);
                if (mprotect(addr, PAGSIZ, PROT_READ|PROT_EXEC) == -1) {
                if (mprotect(addr, PAGSIZ, PROT_READ|PROT_EXEC) == -1) {
-                       perror("mprotect");
+                       err(1, "Cannot re-protect breakpoint (%s)",
+                               main_progname);
                }
 
                ddp->dd_bpt_addr = crtp->crt_bp;
                }
 
                ddp->dd_bpt_addr = crtp->crt_bp;
@@ -311,7 +316,7 @@ struct _dynamic     *dp;
        LM_PRIVATE(smp)->spd_flags |= RTLD_MAIN;
 
        /* Make an entry for ourselves */
        LM_PRIVATE(smp)->spd_flags |= RTLD_MAIN;
 
        /* Make an entry for ourselves */
-       smp = alloc_link_map("/usr/libexec/ld.so", (struct sod *)0, (struct so_map *)0,
+       smp = alloc_link_map(us, (struct sod *)0, (struct so_map *)0,
                                        (caddr_t)crtp->crt_ba, dp);
        LM_PRIVATE(smp)->spd_refcount++;
        LM_PRIVATE(smp)->spd_flags |= RTLD_RTLD;
                                        (caddr_t)crtp->crt_ba, dp);
        LM_PRIVATE(smp)->spd_refcount++;
        LM_PRIVATE(smp)->spd_flags |= RTLD_RTLD;
@@ -335,12 +340,11 @@ struct _dynamic   *dp;
                                        char *name = (char *)
                                            (sodp->sod_name + LM_LDBASE(smp));
                                        char *fmt = sodp->sod_library ?
                                        char *name = (char *)
                                            (sodp->sod_name + LM_LDBASE(smp));
                                        char *fmt = sodp->sod_library ?
-                                               "%s: lib%s.so.%d.%d: %s\n" :
-                                               "%s: %s: %s\n";
-                                       fatal(fmt, main_progname, name,
+                                               "%s: lib%s.so.%d.%d" :
+                                               "%s: %s";
+                                       err(1, fmt, main_progname, name,
                                                sodp->sod_major,
                                                sodp->sod_major,
-                                               sodp->sod_minor,
-                                               strerror(errno));
+                                               sodp->sod_minor);
                                }
                                newmap = alloc_link_map(NULL, sodp, smp, 0, 0);
                        }
                                }
                                newmap = alloc_link_map(NULL, sodp, smp, 0, 0);
                        }
@@ -364,17 +368,17 @@ struct _dynamic   *dp;
                        path = "not found";
 
                if (sodp->sod_library)
                        path = "not found";
 
                if (sodp->sod_library)
-                       printf("\t-l%s.%d => %s (%#x)\n", name,
+                       printf("\t-l%s.%d => %s (%p)\n", name,
                                        sodp->sod_major, path, smp->som_addr);
                else
                                        sodp->sod_major, path, smp->som_addr);
                else
-                       printf("\t%s => %s (%#x)\n", name, path, smp->som_addr);
+                       printf("\t%s => %s (%p)\n", name, path, smp->som_addr);
        }
 
        exit(0);
 }
 
 /*
        }
 
        exit(0);
 }
 
 /*
- * Allocate a new link map for an shared object NAME loaded at ADDR as a
+ * Allocate a new link map for shared object NAME loaded at ADDR as a
  * result of the presence of link object LOP in the link map PARENT.
  */
        static struct so_map *
  * result of the presence of link object LOP in the link map PARENT.
  */
        static struct so_map *
@@ -395,7 +399,7 @@ alloc_link_map(path, sodp, parent, addr, dp)
        link_map_tail = &smp->som_next;
 
        smp->som_addr = addr;
        link_map_tail = &smp->som_next;
 
        smp->som_addr = addr;
-       smp->som_path = path;
+       smp->som_path = strdup(path);
        smp->som_sod = sodp;
        smp->som_dynamic = dp;
        smp->som_spd = (caddr_t)smpp;
        smp->som_sod = sodp;
        smp->som_dynamic = dp;
        smp->som_spd = (caddr_t)smpp;
@@ -482,6 +486,7 @@ again:
                return NULL;
        }
 
                return NULL;
        }
 
+#if 0
        if (mmap(addr + hdr.a_text, hdr.a_data,
                                PROT_READ|PROT_WRITE|PROT_EXEC,
                                MAP_FILE|MAP_FIXED|MAP_COPY,
        if (mmap(addr + hdr.a_text, hdr.a_data,
                                PROT_READ|PROT_WRITE|PROT_EXEC,
                                MAP_FILE|MAP_FIXED|MAP_COPY,
@@ -489,13 +494,19 @@ again:
                (void)close(fd);
                return NULL;
        }
                (void)close(fd);
                return NULL;
        }
+#endif
+       if (mprotect(addr + hdr.a_text, hdr.a_data,
+           PROT_READ|PROT_WRITE|PROT_EXEC) != 0) {
+               (void)close(fd);
+               return NULL;
+       }
 
        (void)close(fd);
 
        fd = -1;
 #ifdef NEED_DEV_ZERO
        if ((fd = open("/dev/zero", O_RDWR, 0)) == -1)
 
        (void)close(fd);
 
        fd = -1;
 #ifdef NEED_DEV_ZERO
        if ((fd = open("/dev/zero", O_RDWR, 0)) == -1)
-               perror("/dev/zero");
+               warn("open: %s", "/dev/zero");
 #endif
        if (hdr.a_bss && mmap(addr + hdr.a_text + hdr.a_data, hdr.a_bss,
                                PROT_READ|PROT_WRITE|PROT_EXEC,
 #endif
        if (hdr.a_bss && mmap(addr + hdr.a_text + hdr.a_data, hdr.a_bss,
                                PROT_READ|PROT_WRITE|PROT_EXEC,
@@ -516,7 +527,7 @@ again:
        return alloc_link_map(path, sodp, smp, addr, dp);
 }
 
        return alloc_link_map(path, sodp, smp, addr, dp);
 }
 
-static void inline
+static inline void
 check_text_reloc(r, smp, addr)
 struct relocation_info *r;
 struct so_map          *smp;
 check_text_reloc(r, smp, addr)
 struct relocation_info *r;
 struct so_map          *smp;
@@ -543,8 +554,7 @@ caddr_t                     addr;
                                LD_TEXTSZ(smp->som_dynamic),
                                PROT_READ|PROT_WRITE|PROT_EXEC) == -1) {
 
                                LD_TEXTSZ(smp->som_dynamic),
                                PROT_READ|PROT_WRITE|PROT_EXEC) == -1) {
 
-               perror("mprotect"),
-               fatal("Cannot enable writes to %s:%s\n",
+               err(1, "Cannot enable writes to %s:%s",
                                        main_progname, smp->som_path);
        }
 
                                        main_progname, smp->som_path);
        }
 
@@ -592,7 +602,7 @@ reloc_map(smp)
 
                        np = lookup(sym, &src_map, 0/*XXX-jumpslots!*/);
                        if (np == NULL)
 
                        np = lookup(sym, &src_map, 0/*XXX-jumpslots!*/);
                        if (np == NULL)
-                               fatal("Undefined symbol \"%s\" in %s:%s\n",
+                               errx(1, "Undefined symbol \"%s\" in %s:%s\n",
                                        sym, main_progname, smp->som_path);
 
                        /*
                                        sym, main_progname, smp->som_path);
 
                        /*
@@ -636,8 +646,7 @@ reloc_map(smp)
                                LD_TEXTSZ(smp->som_dynamic),
                                PROT_READ|PROT_EXEC) == -1) {
 
                                LD_TEXTSZ(smp->som_dynamic),
                                PROT_READ|PROT_EXEC) == -1) {
 
-                       perror("mprotect"),
-                       fatal("Cannot disable writes to %s:%s\n",
+                       err(1, "Cannot disable writes to %s:%s\n",
                                                main_progname, smp->som_path);
                }
                smp->som_write = 0;
                                                main_progname, smp->som_path);
                }
                smp->som_write = 0;
@@ -681,7 +690,7 @@ static struct rt_symbol     *rt_symtab[RTC_TABSIZE];
 /*
  * Compute hash value for run-time symbol table
  */
 /*
  * Compute hash value for run-time symbol table
  */
-       static int inline
+       static inline int
 hash_string(key)
        char *key;
 {
 hash_string(key)
        char *key;
 {
@@ -784,7 +793,7 @@ lookup(name, src_map, strong)
         */
        for (smp = link_map_head; smp; smp = smp->som_next) {
                int             buckets = LD_BUCKETS(smp->som_dynamic);
         */
        for (smp = link_map_head; smp; smp = smp->som_next) {
                int             buckets = LD_BUCKETS(smp->som_dynamic);
-               long            hashval = 0;
+               long            hashval;
                struct rrs_hash *hp;
                char            *cp;
                struct  nzlist  *np;
                struct rrs_hash *hp;
                char            *cp;
                struct  nzlist  *np;
@@ -801,10 +810,11 @@ lookup(name, src_map, strong)
                if (*src_map && smp != *src_map)
                        continue;
 
                if (*src_map && smp != *src_map)
                        continue;
 
+restart:
                /*
                 * Compute bucket in which the symbol might be found.
                 */
                /*
                 * Compute bucket in which the symbol might be found.
                 */
-               for (cp = name; *cp; cp++)
+               for (hashval = 0, cp = name; *cp; cp++)
                        hashval = (hashval << 1) + *cp;
 
                hashval = (hashval & 0x7fffffff) % buckets;
                        hashval = (hashval << 1) + *cp;
 
                hashval = (hashval & 0x7fffffff) % buckets;
@@ -838,6 +848,15 @@ lookup(name, src_map, strong)
                /*
                 * We have a symbol with the name we're looking for.
                 */
                /*
                 * We have a symbol with the name we're looking for.
                 */
+               if (np->nz_type == N_INDR+N_EXT) {
+                       /*
+                        * Next symbol gives the aliased name. Restart
+                        * search with new name and confine to this map.
+                        */
+                       name = stringbase + (++np)->nz_strx;
+                       *src_map = smp;
+                       goto restart;
+               }
 
                if (np->nz_value == 0)
                        /* It's not a definition */
 
                if (np->nz_value == 0)
                        /* It's not a definition */
@@ -902,7 +921,7 @@ binder(jsp)
        }
 
        if (smp == NULL)
        }
 
        if (smp == NULL)
-               fatal("Call to binder from unknown location: %#x\n", jsp);
+               errx(1, "Call to binder from unknown location: %#x\n", jsp);
 
        index = jsp->reloc_index & JMPSLOT_RELOC_MASK;
 
 
        index = jsp->reloc_index & JMPSLOT_RELOC_MASK;
 
@@ -912,7 +931,7 @@ binder(jsp)
 
        np = lookup(sym, &src_map, 1);
        if (np == NULL)
 
        np = lookup(sym, &src_map, 1);
        if (np == NULL)
-               fatal("Undefined symbol \"%s\" called from %s:%s at %#x",
+               errx(1, "Undefined symbol \"%s\" called from %s:%s at %#x",
                                sym, main_progname, smp->som_path, jsp);
 
        /* Fixup jmpslot so future calls transfer directly to target */
                                sym, main_progname, smp->som_path, jsp);
 
        /* Fixup jmpslot so future calls transfer directly to target */
@@ -1074,13 +1093,17 @@ rtfindlib(name, major, minor, usehints)
                        if (hint)
                                return hint;
                }
                        if (hint)
                                return hint;
                }
-       } else {
-               /* No LD_LIBRARY_PATH, check default */
-               hint = findhint(name, major, minor, NULL);
+               /* Not found in hints, try directory search */
+               hint = (char *)findshlib(name, &major, &minor, 0);
                if (hint)
                        return hint;
        }
 
                if (hint)
                        return hint;
        }
 
+       /* No LD_LIBRARY_PATH or lib not found in there; check default */
+       hint = findhint(name, major, minor, NULL);
+       if (hint)
+               return hint;
+
        /* No hints available for name */
        *usehints = 0;
        return (char *)findshlib(name, &major, &minor, 0);
        /* No hints available for name */
        *usehints = 0;
        return (char *)findshlib(name, &major, &minor, 0);
@@ -1107,8 +1130,8 @@ static struct so_map dlmap = {
 };
 static int dlerrno;
 
 };
 static int dlerrno;
 
-       void *
-dlopen(name, mode)
+       static void *
+__dlopen(name, mode)
        char    *name;
        int     mode;
 {
        char    *name;
        int     mode;
 {
@@ -1126,7 +1149,7 @@ dlopen(name, mode)
                return NULL;
        }
 
                return NULL;
        }
 
-       sodp->sod_name = (long)name;
+       sodp->sod_name = (long)strdup(name);
        sodp->sod_library = 0;
        sodp->sod_major = sodp->sod_minor = 0;
 
        sodp->sod_library = 0;
        sodp->sod_major = sodp->sod_minor = 0;
 
@@ -1148,8 +1171,8 @@ xprintf("%s: %s\n", name, strerror(errno));
        return smp;
 }
 
        return smp;
 }
 
-       int
-dlclose(fd)
+       static int
+__dlclose(fd)
        void    *fd;
 {
        struct so_map   *smp = (struct so_map *)fd;
        void    *fd;
 {
        struct so_map   *smp = (struct so_map *)fd;
@@ -1164,6 +1187,7 @@ xprintf("dlclose(%s): refcount = %d\n", smp->som_path, LM_PRIVATE(smp)->spd_refc
        init_map(smp, "_fini");
 #if 0
        unmap_object(smp);
        init_map(smp, "_fini");
 #if 0
        unmap_object(smp);
+       free(smp->som_sod->sod_name);
        free(smp->som_sod);
        free(smp);
 #endif
        free(smp->som_sod);
        free(smp);
 #endif
@@ -1171,8 +1195,8 @@ xprintf("dlclose(%s): refcount = %d\n", smp->som_path, LM_PRIVATE(smp)->spd_refc
        return 0;
 }
 
        return 0;
 }
 
-       void *
-dlsym(fd, sym)
+       static void *
+__dlsym(fd, sym)
        void    *fd;
        char    *sym;
 {
        void    *fd;
        char    *sym;
 {
@@ -1198,8 +1222,8 @@ dlsym(fd, sym)
        return (void *)addr;
 }
 
        return (void *)addr;
 }
 
-       int
-dlctl(fd, cmd, arg)
+       static int
+__dlctl(fd, cmd, arg)
        void    *fd, *arg;
        int     cmd;
 {
        void    *fd, *arg;
        int     cmd;
 {
index 38ec051..2e8dfe9 100644 (file)
@@ -27,7 +27,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- *     $Id: shlib.c,v 1.9 1994/01/29 02:03:15 jtc Exp $
+ *     $Id: shlib.c,v 1.8 1994/02/13 20:41:43 jkh Exp $
  */
 
 #include <sys/param.h>
  */
 
 #include <sys/param.h>
@@ -37,6 +37,7 @@
 #include <sys/stat.h>
 #include <sys/file.h>
 #include <sys/time.h>
 #include <sys/stat.h>
 #include <sys/file.h>
 #include <sys/time.h>
+#include <err.h>
 #include <fcntl.h>
 #include <string.h>
 #include <ctype.h>
 #include <fcntl.h>
 #include <string.h>
 #include <ctype.h>
@@ -53,7 +54,7 @@ char  *strsep();
  * Standard directories to search for files specified by -l.
  */
 #ifndef STANDARD_SEARCH_DIRS
  * Standard directories to search for files specified by -l.
  */
 #ifndef STANDARD_SEARCH_DIRS
-#define        STANDARD_SEARCH_DIRS    "/usr/lib", "/usr/X386/lib", "/usr/local/lib"
+#define        STANDARD_SEARCH_DIRS    "/usr/lib", "/usr/X11R6/lib", "/usr/X386/lib", "/usr/local/lib"
 #endif
 
 /*
 #endif
 
 /*
@@ -73,25 +74,32 @@ add_search_dir(name)
        char    *name;
 {
        n_search_dirs++;
        char    *name;
 {
        n_search_dirs++;
-       search_dirs = (char **)xrealloc(search_dirs,
-                               n_search_dirs * sizeof(char *));
+       search_dirs = (char **)
+               xrealloc(search_dirs, n_search_dirs * sizeof(char *));
        search_dirs[n_search_dirs - 1] = strdup(name);
 }
 
 void
        search_dirs[n_search_dirs - 1] = strdup(name);
 }
 
 void
-std_search_dirs(paths)
-char   *paths;
+add_search_path(path)
+char   *path;
 {
 {
-       char    *cp;
-       int     i, n;
+       register char   *cp;
+
+       if (path == NULL)
+               return;
 
 
-       if (paths != NULL)
                /* Add search directories from `paths' */
                /* Add search directories from `paths' */
-               while ((cp = strsep(&paths, ":")) != NULL) {
+       while ((cp = strsep(&path, ":")) != NULL) {
                        add_search_dir(cp);
                        add_search_dir(cp);
-                       if (paths)
-                               *(paths-1) = ':';
+               if (path)
+                       *(path-1) = ':';
                }
                }
+}
+
+void
+std_search_path()
+{
+       int     i, n;
 
        /* Append standard search directories */
        n = sizeof standard_search_dirs / sizeof standard_search_dirs[0];
 
        /* Append standard search directories */
        n = sizeof standard_search_dirs / sizeof standard_search_dirs[0];
@@ -137,7 +145,7 @@ cmpndewey(d1, n1, d2, n2)
 int    d1[], d2[];
 int    n1, n2;
 {
 int    d1[], d2[];
 int    n1, n2;
 {
-       int     i;
+       register int    i;
 
        for (i = 0; i < n1 && i < n2; i++) {
                if (d1[i] < d2[i])
 
        for (i = 0; i < n1 && i < n2; i++) {
                if (d1[i] < d2[i])
@@ -154,6 +162,9 @@ int n1, n2;
 
        if (i == n2)
                return 1;
 
        if (i == n2)
                return 1;
+
+       errx(1, "cmpndewey: cant happen");
+       return 0;
 }
 
 /*
 }
 
 /*
@@ -200,7 +211,7 @@ int do_dot_a;
                        continue;
 
                while ((dp = readdir(dd)) != NULL) {
                        continue;
 
                while ((dp = readdir(dd)) != NULL) {
-                       int     n, j, might_take_it = 0;
+                       int     n, might_take_it = 0;
 
                        if (do_dot_a && path == NULL &&
                                        dp->d_namlen == len + 2 &&
 
                        if (do_dot_a && path == NULL &&
                                        dp->d_namlen == len + 2 &&
index 15281cc..508d37d 100644 (file)
@@ -14,7 +14,7 @@
  *    must display the following acknowledgement:
  *      This product includes software developed by Paul Kranenburg.
  * 4. The name of the author may not be used to endorse or promote products
  *    must display the following acknowledgement:
  *      This product includes software developed by Paul Kranenburg.
  * 4. The name of the author may not be used to endorse or promote products
- *    derived from this software withough specific prior written permission
+ *    derived from this software without specific prior written permission
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- *     $Id: md.c,v 1.6 1993/12/11 12:02:10 jkh Exp $
+ *     $Id: md.c,v 1.7 1994/02/13 20:43:03 jkh Exp $
  */
 
 #include <sys/param.h>
  */
 
 #include <sys/param.h>
+#include <sys/types.h>
+#include <a.out.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <sys/types.h>
+#include <err.h>
 #include <fcntl.h>
 #include <fcntl.h>
-#include <a.out.h>
 #include <stab.h>
 #include <string.h>
 
 #include <stab.h>
 #include <string.h>
 
@@ -165,7 +166,8 @@ int                 relocatable_output;
                *(u_long *) (addr) |= relocation;
                break;
        default:
                *(u_long *) (addr) |= relocation;
                break;
        default:
-               fatal( "Unimplemented relocation field length in");
+               errx(1, "Unimplemented relocation field length: %d",
+                       RELOC_TARGET_SIZE(r));
        }
 }
 
        }
 }
 
index af182a9..f355b3e 100644 (file)
@@ -1,16 +1,16 @@
 /*
 /*
- * $Id: symbol.c,v 1.3 1993/11/22 19:04:45 jkh Exp $           - symbol table routines
+ * $Id: symbol.c,v 1.4 1994/02/13 20:41:46 jkh Exp $           - symbol table routines
  */
 
 /* Create the symbol table entries for `etext', `edata' and `end'.  */
 
 #include <sys/param.h>
  */
 
 /* Create the symbol table entries for `etext', `edata' and `end'.  */
 
 #include <sys/param.h>
-#include <stdio.h>
-#include <stdlib.h>
 #include <sys/types.h>
 #include <fcntl.h>
 #include <a.out.h>
 #include <stab.h>
 #include <sys/types.h>
 #include <fcntl.h>
 #include <a.out.h>
 #include <stab.h>
+#include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 
 #include "ld.h"
 #include <string.h>
 
 #include "ld.h"
@@ -25,8 +25,8 @@ symbol        *got_symbol;            /* the symbol __GLOBAL_OFFSET_TABLE_ */
 symbol *dynamic_symbol;        /* the symbol __DYNAMIC */
 
 void
 symbol *dynamic_symbol;        /* the symbol __DYNAMIC */
 
 void
-symtab_init (relocatable_output)
-int    relocatable_output;
+symtab_init(relocatable_output)
+       int     relocatable_output;
 {
        /*
         * Put linker reserved symbols into symbol table.
 {
        /*
         * Put linker reserved symbols into symbol table.
@@ -45,18 +45,18 @@ int relocatable_output;
 #define GOT_SYM                "_GLOBAL_OFFSET_TABLE_"
 #endif
 
 #define GOT_SYM                "_GLOBAL_OFFSET_TABLE_"
 #endif
 
-       dynamic_symbol = getsym (DYN_SYM);
+       dynamic_symbol = getsym(DYN_SYM);
        dynamic_symbol->defined = relocatable_output?N_UNDF:(N_DATA | N_EXT);
 
        dynamic_symbol->defined = relocatable_output?N_UNDF:(N_DATA | N_EXT);
 
-       got_symbol = getsym (GOT_SYM);
+       got_symbol = getsym(GOT_SYM);
        got_symbol->defined = N_DATA | N_EXT;
 
        if (relocatable_output)
                return;
 
        got_symbol->defined = N_DATA | N_EXT;
 
        if (relocatable_output)
                return;
 
-       etext_symbol = getsym (ETEXT_SYM);
-       edata_symbol = getsym (EDATA_SYM);
-       end_symbol = getsym (END_SYM);
+       etext_symbol = getsym(ETEXT_SYM);
+       edata_symbol = getsym(EDATA_SYM);
+       end_symbol = getsym(END_SYM);
 
        etext_symbol->defined = N_TEXT | N_EXT;
        edata_symbol->defined = N_DATA | N_EXT;
 
        etext_symbol->defined = N_TEXT | N_EXT;
        edata_symbol->defined = N_DATA | N_EXT;
@@ -67,7 +67,9 @@ int   relocatable_output;
        end_symbol->flags |= GS_REFERENCED;
 }
 
        end_symbol->flags |= GS_REFERENCED;
 }
 
-/* Compute the hash code for symbol name KEY.  */
+/*
+ * Compute the hash code for symbol name KEY.
+ */
 
 int
 hash_string (key)
 
 int
 hash_string (key)
@@ -84,8 +86,10 @@ hash_string (key)
        return k;
 }
 
        return k;
 }
 
-/* Get the symbol table entry for the global symbol named KEY.
-   Create one if there is none.  */
+/*
+ * Get the symbol table entry for the global symbol named KEY.
+ * Create one if there is none.
+ */
 
 symbol *
 getsym(key)
 
 symbol *
 getsym(key)
@@ -95,16 +99,16 @@ getsym(key)
        register symbol *bp;
 
        /* Determine the proper bucket.  */
        register symbol *bp;
 
        /* Determine the proper bucket.  */
-       hashval = hash_string (key) % SYMTABSIZE;
+       hashval = hash_string(key) % SYMTABSIZE;
 
        /* Search the bucket.  */
        for (bp = symtab[hashval]; bp; bp = bp->link)
 
        /* Search the bucket.  */
        for (bp = symtab[hashval]; bp; bp = bp->link)
-               if (! strcmp (key, bp->name))
+               if (strcmp(key, bp->name) == 0)
                        return bp;
 
        /* Nothing was found; create a new symbol table entry.  */
                        return bp;
 
        /* Nothing was found; create a new symbol table entry.  */
-       bp = (symbol *) xmalloc (sizeof (symbol));
-       bp->name = (char *) xmalloc (strlen (key) + 1);
+       bp = (symbol *)xmalloc(sizeof(symbol));
+       bp->name = (char *)xmalloc(strlen(key) + 1);
        strcpy (bp->name, key);
        bp->refs = 0;
        bp->defined = 0;
        strcpy (bp->name, key);
        bp->refs = 0;
        bp->defined = 0;
@@ -146,13 +150,11 @@ getsym_soft (key)
        register symbol *bp;
 
        /* Determine which bucket.  */
        register symbol *bp;
 
        /* Determine which bucket.  */
-
-       hashval = hash_string (key) % SYMTABSIZE;
+       hashval = hash_string(key) % SYMTABSIZE;
 
        /* Search the bucket.  */
 
        /* Search the bucket.  */
-
        for (bp = symtab[hashval]; bp; bp = bp->link)
        for (bp = symtab[hashval]; bp; bp = bp->link)
-               if (! strcmp (key, bp->name))
+               if (strcmp(key, bp->name) == 0)
                        return bp;
 
        return 0;
                        return bp;
 
        return 0;
index aec2236..6ae1be9 100644 (file)
@@ -1,15 +1,16 @@
 /*
 /*
- * $Id: warnings.c,v 1.6 1994/02/13 20:41:48 jkh Exp $
+ * $Id: warnings.c,v 1.7 1994/06/14 12:45:41 csgr Exp $
  */
 
 #include <sys/param.h>
  */
 
 #include <sys/param.h>
-#include <stdio.h>
-#include <stdlib.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/file.h>
 #include <sys/time.h>
 #include <sys/errno.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/file.h>
 #include <sys/time.h>
 #include <sys/errno.h>
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
 #include <fcntl.h>
 #include <ar.h>
 #include <ranlib.h>
 #include <fcntl.h>
 #include <ar.h>
 #include <ranlib.h>
@@ -73,83 +74,19 @@ get_file_name (entry)
        }
 
        if (entry->superfile) {
        }
 
        if (entry->superfile) {
-               supfile = get_file_name (entry->superfile);
-               result = (char *) xmalloc (strlen(supfile)
-                                       + strlen(entry->filename) + 3);
-               sprintf (result, "%s(%s)", supfile, entry->filename);
-               free (supfile);
+               supfile = get_file_name(entry->superfile);
+               result = (char *)
+                       xmalloc(strlen(supfile) + strlen(entry->filename) + 3);
+               (void)sprintf(result, "%s(%s)", supfile, entry->filename);
+               free(supfile);
 
        } else {
 
        } else {
-               result = (char *) xmalloc (strlen (entry->filename) + 1);
-               strcpy (result, entry->filename);
+               result = (char *)xmalloc(strlen(entry->filename) + 1);
+               strcpy(result, entry->filename);
        }
        return result;
 }
 
        }
        return result;
 }
 
-/*
- * Report a fatal error.  The error message is STRING followed by the
- * filename of ENTRY.
- */
-void
-#if __STDC__
-fatal_with_file (char *fmt, struct file_entry *entry, ...)
-#else
-fatal_with_file (fmt, entry, va_alist)
-       char                    *fmt;
-       struct file_entry       *entry;
-       va_dcl
-#endif
-{
-       va_list ap;
-#if __STDC__
-       va_start(ap, fmt);
-#else
-       va_start(ap);
-#endif
-       (void)fprintf(stderr, "%s: ", progname);
-       (void)vfprintf(stderr, fmt, ap);
-       print_file_name (entry, stderr);
-       (void)fprintf(stderr, "\n");
-
-       va_end(ap);
-       exit (1);
-}
-
-/*
- * Report a fatal error using the message for the last failed system call,
- * followed by the string NAME.
- */
-void
-perror_name (name)
-       char *name;
-{
-       char *s;
-
-       if (errno < sys_nerr)
-               s = concat ("", sys_errlist[errno], " for %s");
-       else
-               s = "cannot open %s";
-       fatal (s, name);
-}
-
-/*
- * Report a fatal error using the message for the last failed system call,
- * followed by the name of file ENTRY.
- */
-void
-perror_file (entry)
-     struct file_entry *entry;
-{
-       char *s;
-
-       if (errno < sys_nerr)
-               s = concat ("", sys_errlist[errno], " for ");
-       else
-               s = "cannot open ";
-       fatal_with_file (s, entry);
-}
-
-
 /* Print a complete or partial map of the output file. */
 
 static void    describe_file_sections __P((struct file_entry *, FILE *));
 /* Print a complete or partial map of the output file. */
 
 static void    describe_file_sections __P((struct file_entry *, FILE *));
@@ -160,7 +97,7 @@ print_symbols(outfile)
        FILE           *outfile;
 {
        fprintf(outfile, "\nFiles:\n\n");
        FILE           *outfile;
 {
        fprintf(outfile, "\nFiles:\n\n");
-       each_file(describe_file_sections, outfile);
+       each_file(describe_file_sections, (void *)outfile);
 
        fprintf(outfile, "\nGlobal symbols:\n\n");
        FOR_EACH_SYMBOL(i, sp) {
 
        fprintf(outfile, "\nGlobal symbols:\n\n");
        FOR_EACH_SYMBOL(i, sp) {
@@ -178,7 +115,7 @@ print_symbols(outfile)
                                                sp->name, sp->value, sp->size);
        } END_EACH_SYMBOL;
 
                                                sp->name, sp->value, sp->size);
        } END_EACH_SYMBOL;
 
-       each_file(list_file_locals, outfile);
+       each_file(list_file_locals, (void *)outfile);
 }
 
 static void
 }
 
 static void
@@ -189,7 +126,7 @@ describe_file_sections(entry, outfile)
        fprintf(outfile, "  ");
        print_file_name(entry, outfile);
        if (entry->flags & (E_JUST_SYMS | E_DYNAMIC))
        fprintf(outfile, "  ");
        print_file_name(entry, outfile);
        if (entry->flags & (E_JUST_SYMS | E_DYNAMIC))
-               fprintf(outfile, " symbols only\n", 0);
+               fprintf(outfile, " symbols only\n");
        else
                fprintf(outfile, " text %x(%x), data %x(%x), bss %x(%x) hex\n",
                        entry->text_start_address, entry->header.a_text,
        else
                fprintf(outfile, " text %x(%x), data %x(%x), bss %x(%x) hex\n",
                        entry->text_start_address, entry->header.a_text,
@@ -255,7 +192,7 @@ struct line_debug_entry
    relation between the two relocation entries.  Used by qsort.  */
 
 static int
    relation between the two relocation entries.  Used by qsort.  */
 
 static int
-relocation_entries_relation (rel1, rel2)
+relocation_entries_relation(rel1, rel2)
      struct relocation_info *rel1, *rel2;
 {
        return RELOC_ADDRESS(rel1) - RELOC_ADDRESS(rel2);
      struct relocation_info *rel1, *rel2;
 {
        return RELOC_ADDRESS(rel1) - RELOC_ADDRESS(rel2);
@@ -269,7 +206,7 @@ relocation_entries_relation (rel1, rel2)
    state_pointer[1].sym == 0, this routine should not be called.  */
 
 static int
    state_pointer[1].sym == 0, this routine should not be called.  */
 
 static int
-next_debug_entry (use_data_symbols, state_pointer)
+next_debug_entry(use_data_symbols, state_pointer)
      register int use_data_symbols;
      /* Next must be passed by reference! */
      struct line_debug_entry state_pointer[3];
      register int use_data_symbols;
      /* Next must be passed by reference! */
      struct line_debug_entry state_pointer[3];
@@ -397,12 +334,12 @@ address_to_line(address, state_pointer)
 /* Next must be passed by reference! */
        struct line_debug_entry state_pointer[3];
 {
 /* Next must be passed by reference! */
        struct line_debug_entry state_pointer[3];
 {
-       struct line_debug_entry
-                      *current = state_pointer, *next = state_pointer + 1;
-       struct line_debug_entry *tmp_pointer;
-
+       struct line_debug_entry *current, *next, *tmp_pointer;
        int             use_data_symbols;
 
        int             use_data_symbols;
 
+       current = state_pointer;
+       next = state_pointer + 1;
+
        if (next->sym)
                use_data_symbols =
                        (next->sym->nzlist.nlist.n_type & N_TYPE) == N_DATA;
        if (next->sym)
                use_data_symbols =
                        (next->sym->nzlist.nlist.n_type & N_TYPE) == N_DATA;
@@ -419,6 +356,7 @@ address_to_line(address, state_pointer)
                state_pointer[2] = tmp_pointer[2];
                free(tmp_pointer);
        }
                state_pointer[2] = tmp_pointer[2];
                free(tmp_pointer);
        }
+
        /* If we're still in a bad way, return -1, meaning invalid line.  */
        if (current->sym->nzlist.nlist.n_value > address)
                return -1;
        /* If we're still in a bad way, return -1, meaning invalid line.  */
        if (current->sym->nzlist.nlist.n_value > address)
                return -1;
@@ -426,6 +364,7 @@ address_to_line(address, state_pointer)
        while (next->sym
               && next->sym->nzlist.nlist.n_value <= address
               && next_debug_entry(use_data_symbols, state_pointer));
        while (next->sym
               && next->sym->nzlist.nlist.n_value <= address
               && next_debug_entry(use_data_symbols, state_pointer));
+
        return current->line;
 }
 
        return current->line;
 }
 
@@ -486,7 +425,7 @@ do_relocation_warnings(entry, data_segment, outfile, nlist_bitvector)
        for (reloc = reloc_start;
             reloc < (reloc_start + reloc_size);
             reloc++) {
        for (reloc = reloc_start;
             reloc < (reloc_start + reloc_size);
             reloc++) {
-               register struct localsymbol *s;
+               register struct localsymbol *lsp;
                register symbol *g;
 
                /*
                register symbol *g;
 
                /*
@@ -496,7 +435,7 @@ do_relocation_warnings(entry, data_segment, outfile, nlist_bitvector)
                if (!RELOC_EXTERN_P(reloc))
                        continue;
 
                if (!RELOC_EXTERN_P(reloc))
                        continue;
 
-               s = &entry->symbols[RELOC_SYMBOL(reloc)];
+               lsp = &entry->symbols[RELOC_SYMBOL(reloc)];
 
                /*
                 * Local symbols shouldn't ever be used by relocation info,
 
                /*
                 * Local symbols shouldn't ever be used by relocation info,
@@ -507,17 +446,24 @@ do_relocation_warnings(entry, data_segment, outfile, nlist_bitvector)
                 * assembler would have caught it otherwise), so we can
                 * ignore these cases.
                 */
                 * assembler would have caught it otherwise), so we can
                 * ignore these cases.
                 */
-               if (!(s->nzlist.nz_type & N_EXT))
+
+               if ((g = lsp->symbol) == NULL)
+                       continue;
+
+               if (!(lsp->nzlist.nz_type & N_EXT) &&
+                   !SET_ELEMENT_P(lsp->nzlist.nz_type)) {
+                       warnx("internal error: `%s' N_EXT not set", g->name);
                        continue;
                        continue;
+               }
 
 
-               g = s->symbol;
                errmsg = 0;
 
                errmsg = 0;
 
-               if (!g->defined && !g->so_defined && list_unresolved_refs) {    /* Reference */
+               if (!g->defined && !g->so_defined && list_unresolved_refs) {
                        /* Mark as being noted by relocation warning pass.  */
                        /* Mark as being noted by relocation warning pass.  */
-                       SET_BIT(nlist_bitvector, s - start_of_syms);
+                       SET_BIT(nlist_bitvector, lsp - start_of_syms);
 
 
-                       if (g->undef_refs >= MAX_UREFS_PRINTED) /* Listed too many */
+                       if (g->undef_refs >= MAX_UREFS_PRINTED)
+                               /* Listed too many */
                                continue;
 
                        /* Undefined symbol which we should mention */
                                continue;
 
                        /* Undefined symbol which we should mention */
@@ -526,7 +472,8 @@ do_relocation_warnings(entry, data_segment, outfile, nlist_bitvector)
                                errfmt = "More undefined symbol %s refs follow";
                                invalidate_line_number = 1;
                        } else {
                                errfmt = "More undefined symbol %s refs follow";
                                invalidate_line_number = 1;
                        } else {
-                               errfmt = "Undefined symbol %s referenced from %s segment";
+                               errfmt =
+                       "Undefined symbol `%s' referenced from %s segment";
                                invalidate_line_number = 0;
                        }
                } else {        /* Defined */
                                invalidate_line_number = 0;
                        }
                } else {        /* Defined */
@@ -535,7 +482,7 @@ do_relocation_warnings(entry, data_segment, outfile, nlist_bitvector)
                                continue;
 
                        /* Mark as being noted by relocation warning pass.  */
                                continue;
 
                        /* Mark as being noted by relocation warning pass.  */
-                       SET_BIT(nlist_bitvector, s - start_of_syms);
+                       SET_BIT(nlist_bitvector, lsp - start_of_syms);
 
                        errfmt = 0;
                        errmsg = g->warning;
 
                        errfmt = 0;
                        errmsg = g->warning;
@@ -548,8 +495,9 @@ do_relocation_warnings(entry, data_segment, outfile, nlist_bitvector)
                        char           *nm;
 
                        nm = g->name;
                        char           *nm;
 
                        nm = g->name;
-                       errmsg = (char *) xmalloc(strlen(errfmt) + strlen(nm) + 1);
-                       sprintf(errmsg, errfmt, nm, data_segment ? "data" : "text");
+                       errmsg = (char *)
+                               xmalloc(strlen(errfmt) + strlen(nm) + 1);
+                       sprintf(errmsg, errfmt, nm, data_segment?"data":"text");
                        if (nm != g->name)
                                free(nm);
                }
                        if (nm != g->name)
                                free(nm);
                }
@@ -595,24 +543,25 @@ do_file_warnings (entry, outfile)
        if (!entry->strings) {
                int desc;
 
        if (!entry->strings) {
                int desc;
 
-               entry->strings = (char *) alloca (entry->string_size);
-               desc = file_open (entry);
-               read_entry_strings (desc, entry);
+               entry->strings = (char *)alloca(entry->string_size);
+               desc = file_open(entry);
+               read_entry_strings(desc, entry);
        }
 
        if (!(entry->flags & E_DYNAMIC)) {
        }
 
        if (!(entry->flags & E_DYNAMIC)) {
-               /* Do text warnings based on a scan through the relocation info. */
-               do_relocation_warnings (entry, 0, outfile, nlist_bitvector);
+               /* Do text warnings based on a scan through the reloc info. */
+               do_relocation_warnings(entry, 0, outfile, nlist_bitvector);
 
 
-               /* Do data warnings based on a scan through the relocation info. */
-               do_relocation_warnings (entry, 1, outfile, nlist_bitvector);
+               /* Do data warnings based on a scan through the reloc info. */
+               do_relocation_warnings(entry, 1, outfile, nlist_bitvector);
        }
 
        }
 
-       /* Scan through all of the nlist entries in this file and pick up
-       anything that the scan through the relocation stuff didn't. */
-
-       text_scan = init_debug_scan (0, entry);
-       data_scan = init_debug_scan (1, entry);
+       /*
+        * Scan through all of the nlist entries in this file and pick up
+        * anything that the scan through the relocation stuff didn't.
+        */
+       text_scan = init_debug_scan(0, entry);
+       data_scan = init_debug_scan(1, entry);
 
        for (i = 0; i < number_of_syms; i++) {
                struct nlist *s;
 
        for (i = 0; i < number_of_syms; i++) {
                struct nlist *s;
@@ -630,8 +579,13 @@ do_file_warnings (entry, outfile)
                if(g == NULL)
                        continue;
 
                if(g == NULL)
                        continue;
 
-               if (!(s->n_type & N_EXT))
+               if (g == NULL)
+                       continue;
+
+               if (!(s->n_type & N_EXT) && !SET_ELEMENT_P(s->n_type)) {
+                       warnx("internal error: `%s' N_EXT not set", g->name);
                        continue;
                        continue;
+               }
 
                if (!(g->flags & GS_REFERENCED)) {
 #if 0
 
                if (!(g->flags & GS_REFERENCED)) {
 #if 0
@@ -659,16 +613,18 @@ do_file_warnings (entry, outfile)
                dont_allow_symbol_name = 0;
 
                if (list_multiple_defs && g->mult_defs) {
                dont_allow_symbol_name = 0;
 
                if (list_multiple_defs && g->mult_defs) {
-                       errfmt = "Definition of symbol %s (multiply defined)";
+                       errfmt = "Definition of symbol `%s' (multiply defined)";
                        switch (s->n_type) {
 
                        case N_TEXT | N_EXT:
                        switch (s->n_type) {
 
                        case N_TEXT | N_EXT:
-                               line_number = address_to_line (s->n_value, text_scan);
+                               line_number =
+                                       address_to_line(s->n_value, text_scan);
                                file_name = text_scan[0].filename;
                                break;
 
                        case N_DATA | N_EXT:
                                file_name = text_scan[0].filename;
                                break;
 
                        case N_DATA | N_EXT:
-                               line_number = address_to_line (s->n_value, data_scan);
+                               line_number =
+                                       address_to_line(s->n_value, data_scan);
                                file_name = data_scan[0].filename;
                                break;
 
                                file_name = data_scan[0].filename;
                                break;
 
@@ -678,7 +634,9 @@ do_file_warnings (entry, outfile)
                        case N_SETB | N_EXT:
                                if (g->mult_defs == 2)
                                        continue;
                        case N_SETB | N_EXT:
                                if (g->mult_defs == 2)
                                        continue;
-                               errfmt = "First set element definition of symbol %s (multiply defined)";
+                               errfmt =
+               "First set element definition of symbol %s (multiply defined)";
+                               line_number = -1;
                                break;
 
                        default:
                                break;
 
                        default:
@@ -687,9 +645,11 @@ printf("multiply defined: %s, type %#x\n", g->name, s->n_type);
                                continue;
                        }
 
                                continue;
                        }
 
-               } else if (BIT_SET_P (nlist_bitvector, i)) {
+               } else if (BIT_SET_P(nlist_bitvector, i)) {
                        continue;
                        continue;
-               } else if (list_unresolved_refs && !g->defined && !g->so_defined) {
+               } else if (list_unresolved_refs &&
+                          !g->defined && !g->so_defined) {
+
                        if (g->undef_refs >= MAX_UREFS_PRINTED)
                                continue;
 
                        if (g->undef_refs >= MAX_UREFS_PRINTED)
                                continue;
 
@@ -705,8 +665,8 @@ printf("multiply defined: %s, type %#x\n", g->name, s->n_type);
                         * do a reference. The second is if it's the reference
                         * used by the warning stabs itself.
                         */
                         * do a reference. The second is if it's the reference
                         * used by the warning stabs itself.
                         */
-                       if (s->n_type != (N_EXT | N_UNDF)
-                                       || (i && (s-1)->n_type == N_WARNING))
+                       if (s->n_type != (N_EXT | N_UNDF) ||
+                           (i && (s-1)->n_type == N_WARNING))
                                continue;
 
                        errfmt = g->warning;
                                continue;
 
                        errfmt = g->warning;
@@ -716,19 +676,19 @@ printf("multiply defined: %s, type %#x\n", g->name, s->n_type);
                        continue;
 
                if (line_number == -1)
                        continue;
 
                if (line_number == -1)
-                       fprintf (outfile, "%s: ", entry->filename);
+                       fprintf(outfile, "%s: ", entry->filename);
                else
                else
-                       fprintf (outfile, "%s:%d: ", file_name, line_number);
+                       fprintf(outfile, "%s:%d: ", file_name, line_number);
 
                if (dont_allow_symbol_name)
 
                if (dont_allow_symbol_name)
-                       fprintf (outfile, "%s", errfmt);
+                       fprintf(outfile, "%s", errfmt);
                else
                else
-                       fprintf (outfile, errfmt, g->name);
+                       fprintf(outfile, errfmt, g->name);
 
 
-               fputc ('\n', outfile);
+               fputc('\n', outfile);
        }
        }
-       free (text_scan);
-       free (data_scan);
+       free(text_scan);
+       free(data_scan);
        entry->strings = 0;     /* Since it will dissapear anyway. */
 }
 
        entry->strings = 0;     /* Since it will dissapear anyway. */
 }
 
@@ -747,9 +707,9 @@ do_warnings(outfile)
                return 1;
 
        if (entry_symbol && !entry_symbol->defined)
                return 1;
 
        if (entry_symbol && !entry_symbol->defined)
-               fprintf (outfile, "Undefined entry symbol %s\n",
+               fprintf(outfile, "Undefined entry symbol %s\n",
                                                entry_symbol->name);
                                                entry_symbol->name);
-       each_file (do_file_warnings, outfile);
+       each_file(do_file_warnings, (void *)outfile);
 
        if (list_unresolved_refs || list_multiple_defs)
                return 0;
 
        if (list_unresolved_refs || list_multiple_defs)
                return 0;