This is Paul K's latest set of ld changes. A commit was necessary at this
authorJordan K. Hubbard <jkh@FreeBSD.org>
Sun, 13 Feb 1994 20:43:13 +0000 (20:43 +0000)
committerJordan K. Hubbard <jkh@FreeBSD.org>
Sun, 13 Feb 1994 20:43:13 +0000 (20:43 +0000)
late stage due to the fact that link.h was copyright Sun Microsystems.

This version of ld sync's us up with NetBSD's ld and supports compatablily
with NetBSD's -[zZ] flags (which we had reversed).  Compiling with this
new ld will give you RRS warnings for libraries which do not contain .type
infomation - these wsarnings are harmless and will go away as soon as you
recompile your libraries (cd /usr/src; make libraries).

23 files changed:
gnu/usr.bin/ld/etc.c
gnu/usr.bin/ld/i386/md-static-funcs.c
gnu/usr.bin/ld/i386/md.c
gnu/usr.bin/ld/i386/md.h
gnu/usr.bin/ld/ld.1
gnu/usr.bin/ld/ld.c
gnu/usr.bin/ld/ld.h
gnu/usr.bin/ld/ldconfig/Makefile
gnu/usr.bin/ld/ldconfig/ldconfig.8
gnu/usr.bin/ld/ldconfig/ldconfig.c
gnu/usr.bin/ld/ldd/ldd.1
gnu/usr.bin/ld/ldd/ldd.c
gnu/usr.bin/ld/lib.c
gnu/usr.bin/ld/rrs.c
gnu/usr.bin/ld/rtld/Makefile
gnu/usr.bin/ld/rtld/rtld.c
gnu/usr.bin/ld/shlib.c
gnu/usr.bin/ld/sparc/md.c
gnu/usr.bin/ld/sparc/md.h
gnu/usr.bin/ld/sparc/mdprologue.S
gnu/usr.bin/ld/symbol.c
gnu/usr.bin/ld/warnings.c
gnu/usr.bin/ld/xbits.c

index 22fdfd8..2ddd50a 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: etc.c,v 1.5 1993/12/04 00:52:55 jkh Exp $
+ * $Id: etc.c,v 1.6 1993/12/11 11:58:22 jkh Exp $
  */
 
 #include <sys/param.h>
  */
 
 #include <sys/param.h>
@@ -48,6 +48,7 @@ error(fmt, va_alist)
        va_end(ap);
 }
 
        va_end(ap);
 }
 
+void   (*fatal_cleanup_hook)__P((void));
 /*
  * Report a fatal error.
  */
 /*
  * Report a fatal error.
  */
@@ -72,8 +73,8 @@ fatal(fmt, va_alist)
        (void)fprintf(stderr, "\n");
        va_end(ap);
 
        (void)fprintf(stderr, "\n");
        va_end(ap);
 
-       if (outdesc >= 0)
-               unlink(output_filename);
+       if (fatal_cleanup_hook)
+               (*fatal_cleanup_hook)();
        exit(1);
 }
 
        exit(1);
 }
 
@@ -148,50 +149,3 @@ xrealloc(ptr, size)
 
        return result;
 }
 
        return result;
 }
-\f
-
-
-/* These must move */
-
-#ifndef RTLD
-/*
- * Output COUNT*ELTSIZE bytes of data at BUF to the descriptor DESC.
- */
-void
-mywrite (buf, count, eltsize, desc)
-     char *buf;
-     int count;
-     int eltsize;
-     int desc;
-{
-       register int val;
-       register int bytes = count * eltsize;
-
-       while (bytes > 0) {
-               val = write (desc, buf, bytes);
-               if (val <= 0)
-                       perror(output_filename);
-               buf += val;
-               bytes -= val;
-       }
-}
-
-/*
- * Output PADDING zero-bytes to descriptor OUTDESC.
- * PADDING may be negative; in that case, do nothing.
- */
-
-void
-padfile (padding, outdesc)
-     int padding;
-     int outdesc;
-{
-       register char *buf;
-       if (padding <= 0)
-               return;
-
-       buf = (char *) alloca (padding);
-       bzero (buf, padding);
-       mywrite (buf, padding, 1, outdesc);
-}
-#endif
index 2cd0768..4741685 100644 (file)
@@ -1,8 +1,10 @@
-
 /*
 /*
+ *     $Id: md-static-funcs.c,v 1.2 1993/12/08 10:14:44 pk Exp $
+ *
  * Called by ld.so when onanating.
  * This *must* be a static function, so it is not called through a jmpslot.
  */
  * Called by ld.so when onanating.
  * This *must* be a static function, so it is not called through a jmpslot.
  */
+
 static void
 md_relocate_simple(r, relocation, addr)
 struct relocation_info *r;
 static void
 md_relocate_simple(r, relocation, addr)
 struct relocation_info *r;
index f78c6cc..311a5f6 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: md.c,v 1.7 1994/01/03 18:35:35 davidg Exp $
+ *     $Id: md.c,v 1.8 1994/01/19 15:00:37 davidg Exp $
  */
 
 #include <sys/param.h>
  */
 
 #include <sys/param.h>
@@ -41,8 +41,6 @@
 
 #include "ld.h"
 
 
 #include "ld.h"
 
-int netzmagic = 0;
-
 /*
  * Get relocation addend corresponding to relocation record RP
  * from address ADDR
 /*
  * Get relocation addend corresponding to relocation record RP
  * from address ADDR
@@ -89,29 +87,6 @@ unsigned char                *addr;
        }
 }
 
        }
 }
 
-/*
- * Initialize (output) exec header such that useful values are
- * obtained from subsequent N_*() macro evaluations.
- */
-void
-md_init_header(hp, magic, flags)
-struct exec    *hp;
-int            magic, flags;
-{
-       if (!netzmagic && (magic == ZMAGIC)) {
-               hp->a_midmag = magic;
-       } else {
-               if (netzmagic)
-                       N_SETMAGIC_NET((*hp), magic, MID_I386, flags);
-               else
-                       N_SETMAGIC((*hp), magic, MID_I386, flags);
-       }
-
-       /* TEXT_START depends on the value of outheader.a_entry.  */
-       if (!(link_mode & SHAREABLE)) /*WAS: if (entry_symbol) */
-               hp->a_entry = PAGSIZ;
-}
-
 /*
  * Machine dependent part of claim_rrs_reloc().
  * Set RRS relocation type.
 /*
  * Machine dependent part of claim_rrs_reloc().
  * Set RRS relocation type.
@@ -251,8 +226,44 @@ long       *savep;
        *(char *)where = TRAP;
 }
 
        *(char *)where = TRAP;
 }
 
-#ifdef NEED_SWAP
+#ifndef RTLD
+
+#ifdef FreeBSD
+int    netzmagic;
+#endif
 
 
+/*
+ * Initialize (output) exec header such that useful values are
+ * obtained from subsequent N_*() macro evaluations.
+ */
+void
+md_init_header(hp, magic, flags)
+struct exec    *hp;
+int            magic, flags;
+{
+#ifdef NetBSD
+       if (oldmagic || magic == QMAGIC)
+               hp->a_midmag = magic;
+       else
+               N_SETMAGIC((*hp), magic, MID_I386, flags);
+#endif
+#ifdef FreeBSD
+       if (oldmagic)
+               hp->a_midmag = magic;
+       else if (netzmagic)
+               N_SETMAGIC_NET((*hp), magic, MID_I386, flags);
+       else
+               N_SETMAGIC((*hp), magic, MID_I386, flags);
+#endif
+
+       /* TEXT_START depends on the value of outheader.a_entry.  */
+       if (!(link_mode & SHAREABLE)) /*WAS: if (entry_symbol) */
+               hp->a_entry = PAGSIZ;
+}
+#endif /* RTLD */
+
+
+#ifdef NEED_SWAP
 /*
  * Byte swap routines for cross-linking.
  */
 /*
  * Byte swap routines for cross-linking.
  */
index 7286a74..bbb28f2 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: md.h,v 1.7 1994/01/03 18:35:36 davidg Exp $
+ *     $Id: md.h,v 1.8 1994/01/19 15:00:37 davidg Exp $
  */
 
 
  */
 
 
 #define PAGSIZ                 4096
 #endif
 
 #define PAGSIZ                 4096
 #endif
 
-#define N_SET_FLAG(ex,f)       (netzmagic ? \
-                               N_SETMAGIC_NET(ex,N_GETMAGIC_NET(ex), MID_MACHINE, \
-                                       N_GETFLAG_NET(ex)|(f)) : \
-                               N_GETMAGIC(ex) == ZMAGIC ? \
-                               N_SETMAGIC(ex,ZMAGIC,0,N_GETFLAG(ex)|(f)) : \
-                               N_SETMAGIC(ex,N_GETMAGIC(ex), MID_MACHINE, \
-                                       N_GETFLAG(ex)|(f)))
-  
-#define N_IS_DYNAMIC(ex)       ((N_GETMAGIC_NET(ex) == ZMAGIC) ? \
-                               ((N_GETFLAG_NET(ex) & EX_DYNAMIC)) : \
-                               ((N_GETFLAG(ex) & EX_DYNAMIC)))
+#if defined(NetBSD) || defined(CROSS_LINKER)
+
+#define N_SET_FLAG(ex,f)       (oldmagic || N_GETMAGIC(ex)==QMAGIC ? (0) : \
+                                       N_SETMAGIC(ex,                  \
+                                                  N_GETMAGIC(ex),      \
+                                                  MID_MACHINE,         \
+                                                  N_GETFLAG(ex)|(f)))
+
+#define N_IS_DYNAMIC(ex)       ((N_GETFLAG(ex) & EX_DYNAMIC))
+
+#define N_BADMID(ex) \
+       (N_GETMID(ex) != 0 && N_GETMID(ex) != MID_MACHINE)
+
+#endif
+
+/*
+ * FreeBSD does it differently
+ */
+#ifdef FreeBSD
+#define N_SET_FLAG(ex,f)       (oldmagic ? (0) :                       \
+                                 (netzmagic == 0 ?                     \
+                                       N_SETMAGIC(ex,                  \
+                                                  N_GETMAGIC(ex),      \
+                                                  MID_MACHINE,         \
+                                                  N_GETFLAG(ex)|(f)) : \
+                                       N_SETMAGIC_NET(ex,              \
+                                                  N_GETMAGIC_NET(ex),  \
+                                                  MID_MACHINE,         \
+                                                  N_GETFLAG_NET(ex)|(f)) ))
+
+#define N_IS_DYNAMIC(ex)       ((N_GETMAGIC_NET(ex) == ZMAGIC) ?       \
+                               ((N_GETFLAG_NET(ex) & EX_DYNAMIC)) :    \
+                               ((N_GETFLAG(ex) & EX_DYNAMIC) ))
+#define N_BADMID(ex) 0
+#endif
 
 /*
  * Should be handled by a.out.h ?
 
 /*
  * Should be handled by a.out.h ?
@@ -101,16 +125,16 @@ typedef struct jmpslot {
 #define md_swapout_zsymbols(s,n)
 #define md_swapin_reloc(r,n)
 #define md_swapout_reloc(r,n)
 #define md_swapout_zsymbols(s,n)
 #define md_swapin_reloc(r,n)
 #define md_swapout_reloc(r,n)
-#define md_swapin_link_dynamic(l)
-#define md_swapout_link_dynamic(l)
-#define md_swapin_link_dynamic_2(l)
-#define md_swapout_link_dynamic_2(l)
-#define md_swapin_ld_debug(d)
-#define md_swapout_ld_debug(d)
+#define md_swapin__dynamic(l)
+#define md_swapout__dynamic(l)
+#define md_swapin_section_dispatch_table(l)
+#define md_swapout_section_dispatch_table(l)
+#define md_swapin_so_debug(d)
+#define md_swapout_so_debug(d)
 #define md_swapin_rrs_hash(f,n)
 #define md_swapout_rrs_hash(f,n)
 #define md_swapin_rrs_hash(f,n)
 #define md_swapout_rrs_hash(f,n)
-#define md_swapin_link_object(l,n)
-#define md_swapout_link_object(l,n)
+#define md_swapin_sod(l,n)
+#define md_swapout_sod(l,n)
 #define md_swapout_jmpslot(j,n)
 #define md_swapout_got(g,n)
 #define md_swapin_ranlib_hdr(h,n)
 #define md_swapout_jmpslot(j,n)
 #define md_swapout_got(g,n)
 #define md_swapin_ranlib_hdr(h,n)
@@ -130,23 +154,23 @@ void      md_swapin_reloc __P((struct relocation_info *, int));
 void   md_swapout_reloc __P((struct relocation_info *, int));
 void   md_swapout_jmpslot __P((jmpslot_t *, int));
 
 void   md_swapout_reloc __P((struct relocation_info *, int));
 void   md_swapout_jmpslot __P((jmpslot_t *, int));
 
-#define md_swapin_symbols(s,n)         swap_symbols(s,n)
-#define md_swapout_symbols(s,n)                swap_symbols(s,n)
-#define md_swapin_zsymbols(s,n)                swap_zsymbols(s,n)
-#define md_swapout_zsymbols(s,n)       swap_zsymbols(s,n)
-#define md_swapin_link_dynamic(l)      swap_link_dynamic(l)
-#define md_swapout_link_dynamic(l)     swap_link_dynamic(l)
-#define md_swapin_link_dynamic_2(l)    swap_link_dynamic_2(l)
-#define md_swapout_link_dynamic_2(l)   swap_link_dynamic_2(l)
-#define md_swapin_ld_debug(d)          swap_ld_debug(d)
-#define md_swapout_ld_debug(d)         swap_ld_debug(d)
-#define md_swapin_rrs_hash(f,n)                swap_rrs_hash(f,n)
-#define md_swapout_rrs_hash(f,n)       swap_rrs_hash(f,n)
-#define md_swapin_link_object(l,n)     swapin_link_object(l,n)
-#define md_swapout_link_object(l,n)    swapout_link_object(l,n)
-#define md_swapout_got(g,n)            swap_longs((long*)(g),n)
-#define md_swapin_ranlib_hdr(h,n)      swap_ranlib_hdr(h,n)
-#define md_swapout_ranlib_hdr(h,n)     swap_ranlib_hdr(h,n)
+#define md_swapin_symbols(s,n)                 swap_symbols(s,n)
+#define md_swapout_symbols(s,n)                        swap_symbols(s,n)
+#define md_swapin_zsymbols(s,n)                        swap_zsymbols(s,n)
+#define md_swapout_zsymbols(s,n)               swap_zsymbols(s,n)
+#define md_swapin__dynamic(l)                  swap__dynamic(l)
+#define md_swapout__dynamic(l)                 swap__dynamic(l)
+#define md_swapin_section_dispatch_table(l)    swap_section_dispatch_table(l)
+#define md_swapout_section_dispatch_table(l)   swap_section_dispatch_table(l)
+#define md_swapin_so_debug(d)                  swap_so_debug(d)
+#define md_swapout_so_debug(d)                 swap_so_debug(d)
+#define md_swapin_rrs_hash(f,n)                        swap_rrs_hash(f,n)
+#define md_swapout_rrs_hash(f,n)               swap_rrs_hash(f,n)
+#define md_swapin_sod(l,n)                     swapin_sod(l,n)
+#define md_swapout_sod(l,n)                    swapout_sod(l,n)
+#define md_swapout_got(g,n)                    swap_longs((long*)(g),n)
+#define md_swapin_ranlib_hdr(h,n)              swap_ranlib_hdr(h,n)
+#define md_swapout_ranlib_hdr(h,n)             swap_ranlib_hdr(h,n)
 
 #define md_swap_short(x) ( (((x) >> 8) & 0xff) | (((x) & 0xff) << 8) )
 
 
 #define md_swap_short(x) ( (((x) >> 8) & 0xff) | (((x) & 0xff) << 8) )
 
index 06855d8..3295282 100644 (file)
@@ -14,7 +14,7 @@
 .\"    must display the following acknowledgement:
 .\"      This product includes software developed by Paul Kranenburg.
 .\" 3. 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.
 .\" 3. 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: ld.1,v 1.3 1994/01/03 23:52:35 jkh Exp $
+.\"    $Id: ld.1,v 1.5 1994/01/29 02:03:04 jtc Exp $
 .\"
 .Dd October 14, 1993
 .Dt LD 8
 .\"
 .Dd October 14, 1993
 .Dt LD 8
-.Os FreeBSD
+.Os FreeBSD 1.1
 .Sh NAME
 .Nm ld
 .Nd link editor
 .Sh NAME
 .Nm ld
 .Nd link editor
@@ -69,7 +69,7 @@ The options are as follows:
 .It Fl A Ar symbol-file
 The the symbol-file is taken as a base for link-editing the object files
 on the command line.
 .It Fl A Ar symbol-file
 The the symbol-file is taken as a base for link-editing the object files
 on the command line.
-.It \-assert Ar keyword
+.It Fl a\&ssert Ar keyword
 This option has currently no effect. It is here for compatibility with
 SunOS ld. All conditions which would cause a Sun assertion to fail will
 currently always cause error or warning messages from
 This option has currently no effect. It is here for compatibility with
 SunOS ld. All conditions which would cause a Sun assertion to fail will
 currently always cause error or warning messages from
@@ -85,7 +85,7 @@ found a traditional archive is looked for.
 This options can appear anywhere on the command line and is complementary
 to -Bstatic.
 .It Fl B Ar static
 This options can appear anywhere on the command line and is complementary
 to -Bstatic.
 .It Fl B Ar static
-The counterpart of -Bdynamic. This options turns off dynamic linking for
+The counterpart of -Bdynamic. This option turns off dynamic linking for
 all library specifiers until a -Bdynamic is once again given. Any explicitly
 mentioned shared object encountered on the command line while this option is
 in effect is flagged as an error.
 all library specifiers until a -Bdynamic is once again given. Any explicitly
 mentioned shared object encountered on the command line while this option is
 in effect is flagged as an error.
@@ -170,27 +170,30 @@ Discard local symbols in the input files that start with the letter
 .Dq L
 .It Fl x
 Discard all local symbols in the input files.
 .Dq L
 .It Fl x
 Discard all local symbols in the input files.
-.It Fl y symbol
+.It Fl y Ar symbol
 Trace the manipulations inflicted on
 .Ar symbol
 Trace the manipulations inflicted on
 .Ar symbol
-.It Fl Z
-Make a NetBSD 0.9 ZMAGIC output file.
 .It Fl z
 .It Fl z
-Make a ZMAGIC output file. This is the older 386BSD / FreeBSD 1.0 format.
+Make a NetBSD 0.9 ZMAGIC output file.
 .Sh FILES
 .Sh FILES
-
 .Sh SEE ALSO
 .Xr ldconfig 1 ,
 .Xr link 5
 .Sh SEE ALSO
 .Xr ldconfig 1 ,
 .Xr link 5
-.Sh BUGS
-Spurious
-.Dq undefined symbols errors
-may be reported for symbols originating in shared libraries. This occurs
-when there is also at least one genuine undefined symbol to report.
 .Sh CAVEATS
 An entry point must now explicitly be given if the output is intended to be
 a normal executable program. This was not the case for the previous version of
 .Nm ld\&.
 .Sh CAVEATS
 An entry point must now explicitly be given if the output is intended to be
 a normal executable program. This was not the case for the previous version of
 .Nm ld\&.
+.Sh BUGS
+Shared objects are not properly checked for undefined symbols.
+.Pp
+Cascading of shared object defeats the
+.Dq -Bstatic
+option.
+.Pp
+All shared objects presented to
+.Nm ld
+are marked for run-time loading in the output file, even if no symbols
+are needed from them.
 .Sh HISTORY
 The shared library model employed by
 .Nm ld
 .Sh HISTORY
 The shared library model employed by
 .Nm ld
index ad6f9a6..1d63c82 100644 (file)
@@ -32,7 +32,7 @@ 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.18 1994/01/03 18:35:14 davidg Exp $
+ *     $Id: ld.c,v 1.19 1994/01/19 15:00:27 davidg Exp $
  */
    
 /* Define how to initialize system-dependent header fields.  */
  */
    
 /* Define how to initialize system-dependent header fields.  */
@@ -55,17 +55,18 @@ static char sccsid[] = "@(#)ld.c    6.10 (Berkeley) 5/22/91";
 
 #include "ld.h"
 
 
 #include "ld.h"
 
-#ifndef DEFAULT_SOVERSION
-#define DEFAULT_SOVERSION      LD_VERSION_BSD
-#endif
-
-int    building_shared_object;
+/* Vector of entries for input files specified by arguments.
+   These are all the input files except for members of specified libraries. */
+struct file_entry      *file_table;
+int                    number_of_files;
 
 
-/* 1 => write relocation into output file so can re-input it later.  */
+/* 1 => write relocation into output file so can re-input it later. */
 int    relocatable_output;
 
 int    relocatable_output;
 
-/* Non zero means to create the output executable. */
-/* Cleared by nonfatal errors.  */
+/* 1 => building a shared object, set by `-Bshareable'. */
+int    building_shared_object;
+
+/* 1 => create the output executable. */
 int    make_executable;
 
 /* Force the executable to be output, even if there are non-fatal errors */
 int    make_executable;
 
 /* Force the executable to be output, even if there are non-fatal errors */
@@ -81,9 +82,72 @@ int  force_alias_definition;
        if `relocatable_output'. */
 int    pic_code_seen;
 
        if `relocatable_output'. */
 int    pic_code_seen;
 
+/* 1 => segments must be page aligned (ZMAGIC, QMAGIC) */
+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;
 
+/* Version number to put in __DYNAMIC (set by -V) */
+int    soversion;
+
+int    text_size;              /* total size of text. */
+int    text_start;             /* start of text */
+int    text_pad;               /* clear space between text and data */
+int    data_size;              /* total size of data. */
+int    data_start;             /* start of data */
+int    data_pad;               /* part of bss segment as part of data */
+
+int    bss_size;               /* total size of bss. */
+int    bss_start;              /* start of bss */
+
+int    text_reloc_size;        /* total size of text relocation. */
+int    data_reloc_size;        /* total size of data relocation. */
+
+int    rrs_section_type;       /* What's in the RRS section */
+int    rrs_text_size;          /* Size of RRS text additions */
+int    rrs_text_start;         /* Location of above */
+int    rrs_data_size;          /* Size of RRS data additions */
+int    rrs_data_start;         /* Location of above */
+
+/* Specifications of start and length of the area reserved at the end
+   of the data segment for the set vectors.  Computed in 'digest_symbols' */
+int    set_sect_start;         /* start of set element vectors */
+int    set_sect_size;          /* size of above */
+
+int    link_mode;      /* Current link mode */
+
+/*
+ * When loading the text and data, we can avoid doing a close
+ * and another open between members of the same library.
+ *
+ * These two variables remember the file that is currently open.
+ * Both are zero if no file is open.
+ *
+ * See `each_file' and `file_close'.
+ */
+struct file_entry      *input_file;
+int                    input_desc;
+
+/* The name of the file to write; "a.out" by default. */
+char           *output_filename;       /* Output file name. */
+int            outdesc;                /* Output file descriptor. */
+struct exec    outheader;              /* Output file header. */
+int            magic;                  /* Output file magic. */
+int            oldmagic;
+int            relocatable_output;     /* `-r'-ed output */
+
+symbol         *entry_symbol;
+int            entry_offset;
+
+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;
+int            cl_refs_allocated;
+
 /*
  * Which symbols should be stripped (omitted from the output): none, all, or
  * debugger symbols.
 /*
  * Which symbols should be stripped (omitted from the output): none, all, or
  * debugger symbols.
@@ -100,11 +164,33 @@ enum {
        DISCARD_NONE, DISCARD_ALL, DISCARD_L
 } discard_locals;
 
        DISCARD_NONE, DISCARD_ALL, DISCARD_L
 } discard_locals;
 
-/* Nonzero means print names of input files as processed.  */
-int    trace_files;
+int    global_sym_count;       /* # of nlist entries for global symbols */
+int    size_sym_count;         /* # of N_SIZE nlist entries for output
+                                 (relocatable_output only) */
+int    local_sym_count;        /* # of nlist entries for local symbols. */
+int    non_L_local_sym_count;  /* # of nlist entries for non-L symbols */
+int    debugger_sym_count;     /* # of nlist entries for debugger info. */
+int    undefined_global_sym_count;     /* # of global symbols referenced and
+                                          not defined. */
+int    undefined_shobj_sym_count;      /* # of undefined symbols referenced
+                                          by shared objects */
+int    multiple_def_count;             /* # of multiply defined symbols. */
+int    defined_global_sym_count;       /* # of defined global symbols. */
+int    common_defined_global_count;    /* # of common symbols. */
+
+int    special_sym_count;      /* # of linker defined symbols. */
+       /* XXX - Currently, only __DYNAMIC and _G_O_T_ go here if required,
+        *  perhaps _etext, _edata and _end should go here too.
+        */
+int    global_alias_count;     /* # of aliased symbols */
+int    set_symbol_count;       /* # of N_SET* symbols. */
+int    set_vector_count;       /* # of set vectors in output. */
+int    warning_count;          /* # of warning symbols encountered. */
 
 
-/* Magic number to use for the output file, set by switch.  */
-int    magic;
+struct string_list_element     *set_element_prefixes;
+
+int    trace_files;    /* print names of input files as processed (`-t'). */
+int    write_map;      /* write a load map (`-M') */
 
 /*
  * `text-start' address is normally this much plus a page boundary.
 
 /*
  * `text-start' address is normally this much plus a page boundary.
@@ -137,6 +223,7 @@ int setv_fill_count;
 static void    decode_option __P((char *, char *));
 static void    decode_command __P((int, char **));
 static int     classify_arg __P((char *));
 static void    decode_option __P((char *, char *));
 static void    decode_command __P((int, char **));
 static int     classify_arg __P((char *));
+static void    load_symbols __P((void));
 static void    enter_global_ref __P((struct localsymbol *,
                                                char *, struct file_entry *));
 static void    digest_symbols __P((void));
 static void    enter_global_ref __P((struct localsymbol *,
                                                char *, struct file_entry *));
 static void    digest_symbols __P((void));
@@ -144,6 +231,7 @@ static void digest_pass1 __P((void)), digest_pass2 __P((void));
 static void    consider_file_section_lengths __P((struct file_entry *));
 static void    relocate_file_addresses __P((struct file_entry *));
 static void    consider_relocation __P((struct file_entry *, int));
 static void    consider_file_section_lengths __P((struct file_entry *));
 static void    relocate_file_addresses __P((struct file_entry *));
 static void    consider_relocation __P((struct file_entry *, int));
+static void    consider_local_symbols __P((struct file_entry *));
 static void    perform_relocation __P((char *, int,
                                                struct relocation_info *, int,
                                                struct file_entry *, int));
 static void    perform_relocation __P((char *, int,
                                                struct relocation_info *, int,
                                                struct file_entry *, int));
@@ -151,7 +239,15 @@ static void        copy_text __P((struct file_entry *));
 static void    copy_data __P((struct file_entry *));
 static void    coptxtrel __P((struct file_entry *));
 static void    copdatrel __P((struct file_entry *));
 static void    copy_data __P((struct file_entry *));
 static void    coptxtrel __P((struct file_entry *));
 static void    copdatrel __P((struct file_entry *));
+static void    write_output __P((void));
+static void    write_header __P((void));
+static void    write_text __P((void));
+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    assign_symbolnums __P((struct file_entry *, int *));
+static void    myfatal __P((void));
+
 
 int
 main(argc, argv)
 
 int
 main(argc, argv)
@@ -189,6 +285,7 @@ main(argc, argv)
 
        data_pad = 0;
        text_pad = 0;
 
        data_pad = 0;
        text_pad = 0;
+       page_align_segments = 0;
        page_align_data = 0;
 
        /* Initialize the data about options.  */
        page_align_data = 0;
 
        /* Initialize the data about options.  */
@@ -251,6 +348,9 @@ main(argc, argv)
         * of system and on the output format selected.
         */
 
         * of system and on the output format selected.
         */
 
+       if (magic == ZMAGIC || magic == QMAGIC)
+               page_align_segments = 1;
+
        md_init_header(&outheader, magic, 0);
 
        text_size = sizeof(struct exec);
        md_init_header(&outheader, magic, 0);
 
        text_size = sizeof(struct exec);
@@ -430,15 +530,15 @@ decode_command(argc, argv)
                                fatal("-A specified before an input file other than the first");
                        p->filename = string;
                        p->local_sym_name = string;
                                fatal("-A specified before an input file other than the first");
                        p->filename = string;
                        p->local_sym_name = string;
-                       p->just_syms_flag = 1;
+                       p->flags |= E_JUST_SYMS;
                        p++;
                }
                if (argv[i][1] == 'l') {
                        p->filename = string;
                        p->local_sym_name = concat("-l", string, "");
                        p++;
                }
                if (argv[i][1] == 'l') {
                        p->filename = string;
                        p->local_sym_name = concat("-l", string, "");
-                       p->search_dirs_flag = 1;
+                       p->flags |= E_SEARCH_DIRS;
                        if (link_mode & DYNAMIC && !relocatable_output)
                        if (link_mode & DYNAMIC && !relocatable_output)
-                               p->search_dynamic_flag = 1;
+                               p->flags |= E_SEARCH_DYNAMIC;
                        p++;
                }
                i += code - 1;
                        p++;
                }
                i += code - 1;
@@ -446,8 +546,8 @@ decode_command(argc, argv)
 
        /* Now check some option settings for consistency.  */
 
 
        /* Now check some option settings for consistency.  */
 
-       if ((magic != OMAGIC)
-           && (text_start - text_start_alignment) & (page_size - 1))
+       if (page_align_segments
+               && (text_start - text_start_alignment) & (page_size - 1))
                fatal("-T argument not multiple of page size, with sharable output");
 
        /* Append the standard search directories to the user-specified ones. */
                fatal("-T argument not multiple of page size, with sharable output");
 
        /* Append the standard search directories to the user-specified ones. */
@@ -456,9 +556,9 @@ decode_command(argc, argv)
 
 void
 add_cmdline_ref(sp)
 
 void
 add_cmdline_ref(sp)
-       struct glosym  *sp;
+       symbol *sp;
 {
 {
-       struct glosym **ptr;
+       symbol **ptr;
 
        for (ptr = cmdline_references;
             ptr < cmdline_references + cl_refs_allocated && *ptr;
 
        for (ptr = cmdline_references;
             ptr < cmdline_references + cl_refs_allocated && *ptr;
@@ -474,7 +574,7 @@ add_cmdline_ref(sp)
                ptr = cmdline_references + diff;
        }
        *ptr++ = sp;
                ptr = cmdline_references + diff;
        }
        *ptr++ = sp;
-       *ptr = (struct glosym *) 0;
+       *ptr = (symbol *) 0;
 }
 
 int
 }
 
 int
@@ -505,7 +605,6 @@ static void
 decode_option(swt, arg)
        register char  *swt, *arg;
 {
 decode_option(swt, arg)
        register char  *swt, *arg;
 {
-       /* We get Bstatic from gcc on suns.  */
        if (!strcmp(swt + 1, "Bstatic"))
                return;
        if (!strcmp(swt + 1, "Bdynamic"))
        if (!strcmp(swt + 1, "Bstatic"))
                return;
        if (!strcmp(swt + 1, "Bdynamic"))
@@ -558,9 +657,10 @@ decode_option(swt, arg)
 
        case 'e':
                entry_symbol = getsym(arg);
 
        case 'e':
                entry_symbol = getsym(arg);
-               if (!entry_symbol->defined && !entry_symbol->referenced)
+               if (!entry_symbol->defined &&
+                               !(entry_symbol->flags & GS_REFERENCED))
                        undefined_global_sym_count++;
                        undefined_global_sym_count++;
-               entry_symbol->referenced = 1;
+               entry_symbol->flags |= GS_REFERENCED;
                add_cmdline_ref(entry_symbol);
                return;
 
                add_cmdline_ref(entry_symbol);
                return;
 
@@ -579,19 +679,9 @@ decode_option(swt, arg)
                magic = OMAGIC;
                return;
 
                magic = OMAGIC;
                return;
 
-#ifdef NMAGIC
        case 'n':
                magic = NMAGIC;
                return;
        case 'n':
                magic = NMAGIC;
                return;
-#endif
-
-       case 'Q':
-               magic = QMAGIC;
-               return;
-       case 'Z':
-               magic = ZMAGIC;
-               netzmagic = 1;
-               return;
 
        case 'o':
                output_filename = arg;
 
        case 'o':
                output_filename = arg;
@@ -601,6 +691,12 @@ decode_option(swt, arg)
                page_align_data = 1;
                return;
 
                page_align_data = 1;
                return;
 
+#ifdef QMAGIC
+       case 'Q':
+               magic = QMAGIC;
+               return;
+#endif
+
        case 'r':
                relocatable_output = 1;
                magic = OMAGIC;
        case 'r':
                relocatable_output = 1;
                magic = OMAGIC;
@@ -628,9 +724,9 @@ decode_option(swt, arg)
                {
                        register symbol *sp = getsym(arg);
 
                {
                        register symbol *sp = getsym(arg);
 
-                       if (!sp->defined && !sp->referenced)
+                       if (!sp->defined && !(sp->flags & GS_REFERENCED))
                                undefined_global_sym_count++;
                                undefined_global_sym_count++;
-                       sp->referenced = 1;
+                       sp->flags |= GS_REFERENCED;
                        add_cmdline_ref(sp);
                }
                return;
                        add_cmdline_ref(sp);
                }
                return;
@@ -652,12 +748,17 @@ decode_option(swt, arg)
        case 'y':
                {
                        register symbol *sp = getsym(&swt[2]);
        case 'y':
                {
                        register symbol *sp = getsym(&swt[2]);
-                       sp->trace = 1;
+                       sp->flags |= GS_TRACE;
                }
                return;
 
        case 'z':
                magic = ZMAGIC;
                }
                return;
 
        case 'z':
                magic = ZMAGIC;
+               oldmagic = 0;
+               return;
+
+       case 'Z':
+               magic = oldmagic = ZMAGIC;
                return;
 
        default:
                return;
 
        default:
@@ -686,15 +787,15 @@ each_file(function, arg)
                register struct file_entry *entry = &file_table[i];
                register struct file_entry *subentry;
 
                register struct file_entry *entry = &file_table[i];
                register struct file_entry *subentry;
 
-               if (entry->scrapped)
+               if (entry->flags & E_SCRAPPED)
                        continue;
 
                        continue;
 
-               if (!entry->library_flag)
+               if (!(entry->flags & E_IS_LIBRARY))
                        (*function) (entry, arg);
 
                subentry = entry->subfiles;
                for (; subentry; subentry = subentry->chain) {
                        (*function) (entry, arg);
 
                subentry = entry->subfiles;
                for (; subentry; subentry = subentry->chain) {
-                       if (subentry->scrapped)
+                       if (subentry->flags & E_SCRAPPED)
                                continue;
                        (*function) (subentry, arg);
                }
                                continue;
                        (*function) (subentry, arg);
                }
@@ -702,15 +803,15 @@ each_file(function, arg)
 #ifdef SUN_COMPAT
                if (entry->silly_archive) {
 
 #ifdef SUN_COMPAT
                if (entry->silly_archive) {
 
-                       if (!entry->is_dynamic)
+                       if (!(entry->flags & E_DYNAMIC))
                                error("Silly");
 
                                error("Silly");
 
-                       if (!entry->silly_archive->library_flag)
+                       if (!(entry->silly_archive->flags & E_IS_LIBRARY))
                                error("Sillier");
 
                        subentry = entry->silly_archive->subfiles;
                        for (; subentry; subentry = subentry->chain) {
                                error("Sillier");
 
                        subentry = entry->silly_archive->subfiles;
                        for (; subentry; subentry = subentry->chain) {
-                               if (subentry->scrapped)
+                               if (subentry->flags & E_SCRAPPED)
                                        continue;
                                (*function) (subentry, arg);
                        }
                                        continue;
                                (*function) (subentry, arg);
                        }
@@ -738,12 +839,12 @@ check_each_file(function, arg)
 
        for (i = 0; i < number_of_files; i++) {
                register struct file_entry *entry = &file_table[i];
 
        for (i = 0; i < number_of_files; i++) {
                register struct file_entry *entry = &file_table[i];
-               if (entry->scrapped)
+               if (entry->flags & E_SCRAPPED)
                        continue;
                        continue;
-               if (entry->library_flag) {
+               if (entry->flags & E_IS_LIBRARY) {
                        register struct file_entry *subentry = entry->subfiles;
                        for (; subentry; subentry = subentry->chain) {
                        register struct file_entry *subentry = entry->subfiles;
                        for (; subentry; subentry = subentry->chain) {
-                               if (subentry->scrapped)
+                               if (subentry->flags & E_SCRAPPED)
                                        continue;
                                if (return_val = (*function) (subentry, arg))
                                        return return_val;
                                        continue;
                                if (return_val = (*function) (subentry, arg))
                                        return return_val;
@@ -767,35 +868,35 @@ each_full_file(function, arg)
                register struct file_entry *entry = &file_table[i];
                register struct file_entry *subentry;
 
                register struct file_entry *entry = &file_table[i];
                register struct file_entry *subentry;
 
-               if (entry->scrapped || entry->just_syms_flag)
+               if (entry->flags & (E_SCRAPPED | E_JUST_SYMS))
                        continue;
 
 #ifdef SUN_COMPAT
                if (entry->silly_archive) {
 
                        continue;
 
 #ifdef SUN_COMPAT
                if (entry->silly_archive) {
 
-                       if (!entry->is_dynamic)
+                       if (!(entry->flags & E_DYNAMIC))
                                error("Silly");
 
                                error("Silly");
 
-                       if (!entry->silly_archive->library_flag)
+                       if (!(entry->silly_archive->flags & E_IS_LIBRARY))
                                error("Sillier");
 
                        subentry = entry->silly_archive->subfiles;
                        for (; subentry; subentry = subentry->chain) {
                                error("Sillier");
 
                        subentry = entry->silly_archive->subfiles;
                        for (; subentry; subentry = subentry->chain) {
-                               if (subentry->scrapped)
+                               if (subentry->flags & E_SCRAPPED)
                                        continue;
                                (*function) (subentry, arg);
                        }
                }
 #endif
                                        continue;
                                (*function) (subentry, arg);
                        }
                }
 #endif
-               if (entry->is_dynamic)
+               if (entry->flags & E_DYNAMIC)
                        continue;
 
                        continue;
 
-               if (!entry->library_flag)
+               if (!(entry->flags & E_IS_LIBRARY))
                        (*function) (entry, arg);
 
                subentry = entry->subfiles;
                for (; subentry; subentry = subentry->chain) {
                        (*function) (entry, arg);
 
                subentry = entry->subfiles;
                for (; subentry; subentry = subentry->chain) {
-                       if (subentry->scrapped)
+                       if (subentry->flags & E_SCRAPPED)
                                continue;
                        (*function) (subentry, arg);
                }
                                continue;
                        (*function) (subentry, arg);
                }
@@ -824,7 +925,7 @@ file_open (entry)
 {
        register int desc;
 
 {
        register int desc;
 
-       if (entry->superfile && entry->superfile->library_flag)
+       if (entry->superfile && (entry->superfile->flags & E_IS_LIBRARY))
                return file_open (entry->superfile);
 
        if (entry == input_file)
                return file_open (entry->superfile);
 
        if (entry == input_file)
@@ -832,7 +933,7 @@ file_open (entry)
 
        if (input_file) file_close ();
 
 
        if (input_file) file_close ();
 
-       if (entry->search_dirs_flag) {
+       if (entry->flags & E_SEARCH_DIRS) {
                desc = findlib(entry);
        } else
                desc = open (entry->filename, O_RDONLY, 0);
                desc = findlib(entry);
        } else
                desc = open (entry->filename, O_RDONLY, 0);
@@ -853,8 +954,8 @@ text_offset (entry)
 {
        return entry->starting_offset + N_TXTOFF (entry->header);
 }
 {
        return entry->starting_offset + N_TXTOFF (entry->header);
 }
-\f
-/* Medium-level input routines for rel files.  */
+
+/*---------------------------------------------------------------------------*/
 
 /*
  * 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. DESC is the
@@ -865,8 +966,7 @@ read_header (desc, entry)
      int desc;
      register struct file_entry *entry;
 {
      int desc;
      register struct file_entry *entry;
 {
-       register int len;
-       struct exec *loc = (struct exec *) &entry->header;
+       register int len, mid;
 
        if (lseek (desc, entry->starting_offset, L_SET) !=
                                                entry->starting_offset)
 
        if (lseek (desc, entry->starting_offset, L_SET) !=
                                                entry->starting_offset)
@@ -878,10 +978,13 @@ read_header (desc, entry)
 
        md_swapin_exec_hdr(&entry->header);
 
 
        md_swapin_exec_hdr(&entry->header);
 
-       if (N_BADMAG (*loc))
+       if (N_BADMAG (entry->header))
                fatal_with_file ("bad magic number in ", entry);
 
                fatal_with_file ("bad magic number in ", entry);
 
-       entry->header_read_flag = 1;
+       if (N_BADMID(entry->header))
+               fatal_with_file ("non-native input file ", entry);
+
+       entry->flags |= E_HEADER_VALID;
 }
 
 /*
 }
 
 /*
@@ -899,7 +1002,7 @@ read_entry_symbols (desc, entry)
        struct nlist    *np;
        int             i;
 
        struct nlist    *np;
        int             i;
 
-       if (!entry->header_read_flag)
+       if (!(entry->flags & E_HEADER_VALID))
                read_header (desc, entry);
 
        np = (struct nlist *) alloca (entry->header.a_syms);
                read_header (desc, entry);
 
        np = (struct nlist *) alloca (entry->header.a_syms);
@@ -921,11 +1024,9 @@ read_entry_symbols (desc, entry)
                entry->symbols[i].nzlist.nz_size = 0;
                entry->symbols[i].symbol = NULL;
                entry->symbols[i].next = NULL;
                entry->symbols[i].nzlist.nz_size = 0;
                entry->symbols[i].symbol = NULL;
                entry->symbols[i].next = NULL;
+               entry->symbols[i].entry = entry;
                entry->symbols[i].gotslot_offset = -1;
                entry->symbols[i].gotslot_offset = -1;
-               entry->symbols[i].gotslot_claimed = 0;
-               entry->symbols[i].write = 0;
-               entry->symbols[i].is_L_symbol = 0;
-               entry->symbols[i].rename = 0;
+               entry->symbols[i].flags = 0;
        }
 
        entry->strings_offset = N_STROFF(entry->header) +
        }
 
        entry->strings_offset = N_STROFF(entry->header) +
@@ -949,7 +1050,7 @@ read_entry_strings (desc, entry)
 {
        int buffer;
 
 {
        int buffer;
 
-       if (!entry->header_read_flag || !entry->strings_offset)
+       if (!(entry->flags & E_HEADER_VALID) || !entry->strings_offset)
                fatal_with_file("internal error: cannot read string table for ",
                                        entry);
 
                fatal_with_file("internal error: cannot read string table for ",
                                        entry);
 
@@ -963,14 +1064,6 @@ read_entry_strings (desc, entry)
        return;
 }
 
        return;
 }
 
-/* DEAD - Read in all of the relocation information */
-
-void
-read_relocation ()
-{
-       each_full_file (read_entry_relocation, 0);
-}
-
 /* Read in the relocation sections of ENTRY if necessary */
 
 void
 /* Read in the relocation sections of ENTRY if necessary */
 
 void
@@ -1026,23 +1119,24 @@ read_entry_relocation (desc, entry)
        }
 }
 
        }
 }
 
-\f
-/* Read in the symbols of all input files.  */
-
+/*---------------------------------------------------------------------------*/
 
 
-void
+/*
+ * Read in the symbols of all input files.
+ */
+static void
 load_symbols ()
 {
        register int i;
 
 load_symbols ()
 {
        register int i;
 
-       if (trace_files) fprintf (stderr, "Loading symbols:\n\n");
+       if (trace_files)
+               fprintf(stderr, "Loading symbols:\n\n");
 
 
-       for (i = 0; i < number_of_files; i++) {
-               register struct file_entry *entry = &file_table[i];
-               read_file_symbols (entry);
-       }
+       for (i = 0; i < number_of_files; i++)
+               read_file_symbols(&file_table[i]);
 
 
-       if (trace_files) fprintf (stderr, "\n");
+       if (trace_files)
+               fprintf (stderr, "\n");
 }
 
 /*
 }
 
 /*
@@ -1068,18 +1162,18 @@ read_file_symbols (entry)
        md_swapin_exec_hdr(&hdr);
 
        if (!N_BADMAG (hdr)) {
        md_swapin_exec_hdr(&hdr);
 
        if (!N_BADMAG (hdr)) {
-               if (N_IS_DYNAMIC(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);
                                return;
                        }
                        if (relocatable_output) {
                                fatal_with_file(
                        "-r and shared objects currently not supported ",
                                        entry);
                                return;
                        }
-                       entry->is_dynamic = 1;
+                       entry->flags |= E_DYNAMIC;
                        if (entry->superfile || rrs_add_shobj(entry))
                                read_shared_object(desc, entry);
                        else
                        if (entry->superfile || rrs_add_shobj(entry))
                                read_shared_object(desc, entry);
                        else
-                               entry->scrapped = 1;
+                               entry->flags |= E_SCRAPPED;
                } else {
                        read_entry_symbols (desc, entry);
                        entry->strings = (char *) alloca (entry->string_size);
                } else {
                        read_entry_symbols (desc, entry);
                        entry->strings = (char *) alloca (entry->string_size);
@@ -1096,14 +1190,17 @@ read_file_symbols (entry)
                                        strncmp (armag, ARMAG, SARMAG))
                        fatal_with_file(
                        "malformed input file (not rel or archive) ", entry);
                                        strncmp (armag, ARMAG, SARMAG))
                        fatal_with_file(
                        "malformed input file (not rel or archive) ", entry);
-               entry->library_flag = 1;
+               entry->flags |= E_IS_LIBRARY;
                search_library (desc, entry);
        }
 
        file_close ();
 }
                search_library (desc, entry);
        }
 
        file_close ();
 }
-\f
-/* Enter the external symbol defs and refs of ENTRY in the hash table.  */
+
+
+/*
+ * Enter the external symbol defs and refs of ENTRY in the hash table.
+ */
 
 void
 enter_file_symbols (entry)
 
 void
 enter_file_symbols (entry)
@@ -1160,7 +1257,7 @@ enter_file_symbols (entry)
                                p->n_un.n_strx + entry->strings, entry);
                } else if (p->n_un.n_strx &&
                                (p->n_un.n_strx + entry->strings)[0] == LPREFIX)
                                p->n_un.n_strx + entry->strings, entry);
                } else if (p->n_un.n_strx &&
                                (p->n_un.n_strx + entry->strings)[0] == LPREFIX)
-                       lsp->is_L_symbol = 1;
+                       lsp->flags |= LS_L_SYMBOL;
        }
 
 }
        }
 
 }
@@ -1190,9 +1287,9 @@ enter_global_ref (lsp, name, entry)
        register struct nzlist *nzp = &lsp->nzlist;
        register symbol *sp = getsym (name);
        register int type = nzp->nz_type;
        register struct nzlist *nzp = &lsp->nzlist;
        register symbol *sp = getsym (name);
        register int type = nzp->nz_type;
-       int oldref = sp->referenced;
+       int oldref = (sp->flags & GS_REFERENCED);
        int olddef = sp->defined;
        int olddef = sp->defined;
-       int com = sp->defined && sp->max_common_size;
+       int com = sp->defined && sp->common_size;
 
        if (type == (N_INDR | N_EXT)) {
                sp->alias = getsym(entry->strings + (lsp + 1)->nzlist.nz_strx);
 
        if (type == (N_INDR | N_EXT)) {
                sp->alias = getsym(entry->strings + (lsp + 1)->nzlist.nz_strx);
@@ -1208,7 +1305,7 @@ enter_global_ref (lsp, name, entry)
                }
        }
 
                }
        }
 
-       if (entry->is_dynamic) {
+       if (entry->flags & E_DYNAMIC) {
                lsp->next = sp->sorefs;
                sp->sorefs = lsp;
 
                lsp->next = sp->sorefs;
                sp->sorefs = lsp;
 
@@ -1223,11 +1320,17 @@ enter_global_ref (lsp, name, entry)
                                if (oldref)
                                        undefined_global_sym_count--;
                                common_defined_global_count++;
                                if (oldref)
                                        undefined_global_sym_count--;
                                common_defined_global_count++;
-                               sp->max_common_size = nzp->nz_value;
+                               sp->common_size = nzp->nz_value;
                                sp->defined = N_UNDF | N_EXT;
                                sp->defined = N_UNDF | N_EXT;
-                       } else if (com && sp->max_common_size < nzp->nz_value) {
-                               sp->max_common_size = nzp->nz_value;
+                       } else if (com && sp->common_size < nzp->nz_value) {
+                               sp->common_size = nzp->nz_value;
                        }
                        }
+               } else if (type != (N_UNDF | N_EXT) && !oldref) {
+                       /*
+                        * This is an ex common...
+                        */
+                       sp->common_size = 0;
+                       sp->defined = 0;
                }
 
                /*
                }
 
                /*
@@ -1244,10 +1347,10 @@ enter_global_ref (lsp, name, entry)
        sp->refs = lsp;
        lsp->symbol = sp;
 
        sp->refs = lsp;
        lsp->symbol = sp;
 
-       sp->referenced = 1;
+       sp->flags |= GS_REFERENCED;
 
        if (sp == dynamic_symbol || sp == got_symbol) {
 
        if (sp == dynamic_symbol || sp == got_symbol) {
-               if (type != (N_UNDF | N_EXT) && !entry->just_syms_flag)
+               if (type != (N_UNDF | N_EXT) && !(entry->flags & E_JUST_SYMS))
                        fatal("Linker reserved symbol %s defined as type %x ",  
                                                name, type);
                return;
                        fatal("Linker reserved symbol %s defined as type %x ",  
                                                name, type);
                return;
@@ -1281,33 +1384,38 @@ enter_global_ref (lsp, name, entry)
                         * First definition and it's common.
                         */
                        common_defined_global_count++;
                         * First definition and it's common.
                         */
                        common_defined_global_count++;
-                       sp->max_common_size = nzp->nz_value;
+                       sp->common_size = nzp->nz_value;
                } else if (com && type != (N_UNDF | N_EXT)) {
                        /*
                         * It used to be common and we're defining
                         * it as something else.
                         */
                        common_defined_global_count--;
                } else if (com && type != (N_UNDF | N_EXT)) {
                        /*
                         * It used to be common and we're defining
                         * it as something else.
                         */
                        common_defined_global_count--;
-                       sp->max_common_size = 0;
+                       sp->common_size = 0;
                } else if (com && type == (N_UNDF | N_EXT)
                } else if (com && type == (N_UNDF | N_EXT)
-                                 && sp->max_common_size < nzp->nz_value)
+                                 && sp->common_size < nzp->nz_value)
                        /*
                         * It used to be common and this is a new common entry
                         * to which we need to pay attention.
                         */
                        /*
                         * It used to be common and this is a new common entry
                         * to which we need to pay attention.
                         */
-                       sp->max_common_size = nzp->nz_value;
+                       sp->common_size = nzp->nz_value;
 
                if (SET_ELEMENT_P(type) && (!olddef || com))
                        set_vector_count++;
 
 
                if (SET_ELEMENT_P(type) && (!olddef || com))
                        set_vector_count++;
 
-       } else if (!oldref)
+       } else if (!oldref && !com)
+               /*
+                * An unreferenced symbol can already be defined
+                * as common by shared objects.
+                */
                undefined_global_sym_count++;
 
 
                undefined_global_sym_count++;
 
 
-       if (sp == end_symbol && entry->just_syms_flag && !T_flag_specified)
+       if (sp == end_symbol && (entry->flags & E_JUST_SYMS) &&
+                                                       !T_flag_specified)
                text_start = nzp->nz_value;
 
                text_start = nzp->nz_value;
 
-       if (sp->trace) {
+       if (sp->flags & GS_TRACE) {
                register char *reftype;
                switch (type & N_TYPE) {
                case N_UNDF:
                register char *reftype;
                switch (type & N_TYPE) {
                case N_UNDF:
@@ -1343,7 +1451,7 @@ enter_global_ref (lsp, name, entry)
 }
 
 /*
 }
 
 /*
- * This return 0 if the given file entry's symbol table does *not* contain
+ * This returns 0 if the given file entry's symbol table does *not* contain
  * the nlist point entry, and it returns the files entry pointer (cast to
  * unsigned long) if it does.
  */
  * the nlist point entry, and it returns the files entry pointer (cast to
  * unsigned long) if it does.
  */
@@ -1391,7 +1499,6 @@ contains_symbol (entry, np)
  *
  */
 
  *
  */
 
-
 static void
 digest_symbols ()
 {
 static void
 digest_symbols ()
 {
@@ -1419,6 +1526,8 @@ digest_symbols ()
        each_full_file(consider_relocation, 0); /* Text */
        each_full_file(consider_relocation, 1); /* Data */
 
        each_full_file(consider_relocation, 0); /* Text */
        each_full_file(consider_relocation, 1); /* Data */
 
+       each_file(consider_local_symbols, 0);
+
        /*
         * Compute total size of sections.
         * RRS data is the first output data section, RRS text is the last
        /*
         * Compute total size of sections.
         * RRS data is the first output data section, RRS text is the last
@@ -1437,7 +1546,7 @@ digest_symbols ()
         * the padding in the text segment size.
         */
 
         * the padding in the text segment size.
         */
 
-       if (magic == ZMAGIC || magic == QMAGIC || page_align_data) {
+       if (page_align_segments || page_align_data) {
                int  text_end = text_size + N_TXTOFF(outheader);
                text_pad = PALIGN(text_end, page_size) - text_end;
                text_size += text_pad;
                int  text_end = text_size + N_TXTOFF(outheader);
                text_pad = PALIGN(text_end, page_size) - text_end;
                text_size += text_pad;
@@ -1490,7 +1599,7 @@ printf("bssstart = %#x, bsssize = %#x\n",
        if (specified_data_size && specified_data_size > data_size)
                data_pad = specified_data_size - data_size;
 
        if (specified_data_size && specified_data_size > data_size)
                data_pad = specified_data_size - data_size;
 
-       if (magic == ZMAGIC || magic == QMAGIC)
+       if (page_align_segments)
                data_pad = PALIGN(data_pad + data_size, page_size) - data_size;
 
        bss_size -= data_pad;
                data_pad = PALIGN(data_pad + data_size, page_size) - data_size;
 
        bss_size -= data_pad;
@@ -1506,10 +1615,10 @@ printf("bssstart = %#x, bsssize = %#x\n",
        global_sym_count = defined_global_sym_count +
                                        undefined_global_sym_count;
 
        global_sym_count = defined_global_sym_count +
                                        undefined_global_sym_count;
 
-       if (dynamic_symbol->referenced)
+       if (dynamic_symbol->flags & GS_REFERENCED)
                global_sym_count++;
 
                global_sym_count++;
 
-       if (got_symbol->referenced)
+       if (got_symbol->flags & GS_REFERENCED)
                global_sym_count++;
 
        if (relocatable_output || building_shared_object)
                global_sym_count++;
 
        if (relocatable_output || building_shared_object)
@@ -1529,12 +1638,15 @@ debug symbols: %d, set_symbols %d\n",
 #endif
 }
 
 #endif
 }
 
+/*
+ * Determine the definition of each global symbol.
+ */
 static void
 digest_pass1()
 {
 
        /*
 static void
 digest_pass1()
 {
 
        /*
-        * Now, for each symbol, verify that it is defined globally at most
+        * For each symbol, verify that it is defined globally at most
         * once within relocatable files (except when building a shared lib).
         * and set the `defined' field if there is a definition.
         *
         * once within relocatable files (except when building a shared lib).
         * and set the `defined' field if there is a definition.
         *
@@ -1546,7 +1658,7 @@ digest_pass1()
                struct localsymbol *lsp;
                int             defs = 0;
 
                struct localsymbol *lsp;
                int             defs = 0;
 
-               if (!sp->referenced) {
+               if (!(sp->flags & GS_REFERENCED)) {
 #if 0
                        /* Check for undefined symbols in shared objects */
                        int type;
 #if 0
                        /* Check for undefined symbols in shared objects */
                        int type;
@@ -1580,7 +1692,7 @@ digest_pass1()
                                        sp->value =
                                                setv_fill_count++ * sizeof(long);
                                } else if ((sp->defined & N_TYPE) != N_SETV) {
                                        sp->value =
                                                setv_fill_count++ * sizeof(long);
                                } else if ((sp->defined & N_TYPE) != N_SETV) {
-                                       sp->multiply_defined = 1;
+                                       sp->mult_defs = 1;
                                        multiple_def_count++;
                                }
                                /* Keep count and remember symbol */
                                        multiple_def_count++;
                                }
                                /* Keep count and remember symbol */
@@ -1588,6 +1700,12 @@ digest_pass1()
                                set_vectors[setv_fill_count++] = (long)p;
                                if (building_shared_object) {
                                        struct relocation_info reloc;
                                set_vectors[setv_fill_count++] = (long)p;
                                if (building_shared_object) {
                                        struct relocation_info reloc;
+
+                                       /*
+                                        * Make sure to relocate the contents
+                                        * of this set vector.
+                                        */
+                                       bzero(&reloc, sizeof(reloc));
                                        RELOC_ADDRESS(&reloc) =
                                                setv_fill_count * sizeof(long);
                                        alloc_rrs_segment_reloc(NULL, &reloc);
                                        RELOC_ADDRESS(&reloc) =
                                                setv_fill_count * sizeof(long);
                                        alloc_rrs_segment_reloc(NULL, &reloc);
@@ -1598,12 +1716,14 @@ digest_pass1()
                                                && (type & N_TYPE) != N_SIZE) {
                                /* non-common definition */
                                if (defs++ && sp->value != p->n_value
                                                && (type & N_TYPE) != N_SIZE) {
                                /* non-common definition */
                                if (defs++ && sp->value != p->n_value
-                                   && entry_symbol) {
-                                       sp->multiply_defined = 1;
+                                   && entry_symbol/*XXX*/) {
+                                       sp->mult_defs = 1;
                                        multiple_def_count++;
                                }
                                sp->def_nlist = p;
                                        multiple_def_count++;
                                }
                                sp->def_nlist = p;
+                               lsp->entry->flags |= E_SYMBOLS_USED;
                                sp->defined = type;
                                sp->defined = type;
+                               sp->aux = N_AUX(p);
                        }
                }
 
                        }
                }
 
@@ -1645,15 +1765,17 @@ digest_pass1()
                                                && (type & N_TYPE) != N_FN) {
                                /* non-common definition */
                                sp->def_nlist = p;
                                                && (type & N_TYPE) != N_FN) {
                                /* non-common definition */
                                sp->def_nlist = p;
+                               lsp->entry->flags |= E_SYMBOLS_USED;
                                sp->so_defined = type;
                                sp->so_defined = type;
-                               if (sp->referenced)
+                               sp->aux = N_AUX(p);
+                               if (sp->flags & GS_REFERENCED)
                                        undefined_global_sym_count--;
                                else
                                        undefined_global_sym_count--;
                                else
-                                       sp->referenced = 1;
+                                       sp->flags |= GS_REFERENCED;
 #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 (sp->alias && !sp->alias->referenced) {
+                               if (sp->alias && !(sp->alias->flags & GS_REFERENCED)) {
                                        sp = sp->alias;
                                        goto again;
                                }
                                        sp = sp->alias;
                                        goto again;
                                }
@@ -1668,159 +1790,10 @@ doesn't match actual (%d)",
                        set_sect_size/sizeof(long), setv_fill_count);
 }
 
                        set_sect_size/sizeof(long), setv_fill_count);
 }
 
-static void
-digest_pass2()
-{
-       /*
-        * Assign each symbol its final value.
-        * If not -r'ing, allocate common symbols in the BSS section.
-        */
-
-       FOR_EACH_SYMBOL(i, sp) {
-               int             size;
-               int             align = sizeof(int);
-
-               if (!sp->referenced)
-                       continue;
-
-               if (sp->alias &&
-                       (relocatable_output || building_shared_object ||
-                               (sp->alias->defined && !sp->alias->so_defined)))
-                       /*
-                        * The alias points at a defined symbol, so it
-                        * must itself be counted as one too, in order to
-                        * compute the correct number of symbol table entries.
-                        */
-                       defined_global_sym_count++;
-
-               if ((sp->defined & N_TYPE) == N_SETV) {
-                       /*
-                        * Set length word at front of vector and zero byte
-                        * at end. Reverse the vector itself to put it in
-                        * file order.
-                        */
-                       unsigned long   i, tmp;
-                       unsigned long   length_word_index =
-                                               sp->value / sizeof(long);
-
-                       /* Relocate symbol value */
-                       sp->value += set_sect_start;
-
-                       set_vectors[length_word_index] = sp->setv_count;
-
-                       /*
-                        * Relocate vector to final address.
-                        */
-                       for (i = 0; i < sp->setv_count; i++) {
-                               struct nlist    *p = (struct nlist *)
-                                       set_vectors[1+i+length_word_index];
-
-                               set_vectors[1+i+length_word_index] = p->n_value;
-                               if (building_shared_object) {
-                                       struct relocation_info reloc;
-                                       RELOC_ADDRESS(&reloc) =
-                                               (1 + i + length_word_index) *
-                                                               sizeof(long)
-                                               + set_sect_start;
-                                       RELOC_TYPE(&reloc) =
-                                               (sp->defined & N_TYPE);
-                                       claim_rrs_segment_reloc(NULL, &reloc);
-                               }
-                       }
-
-                       /*
-                        * Reverse the vector.
-                        */
-                       for (i = 1; i < (sp->setv_count - 1)/2 + 1; i++) {
-
-                               tmp = set_vectors[length_word_index + i];
-                               set_vectors[length_word_index + i] =
-                                       set_vectors[length_word_index + sp->setv_count + 1 - i];
-                               set_vectors[length_word_index + sp->setv_count + 1 - i] = tmp;
-                       }
-
-                       /* Clear terminating entry */
-                       set_vectors[length_word_index + sp->setv_count + 1] = 0;
-                       continue;
-               }
-
-
-               if (sp->defined && sp->def_nlist &&
-                               ((sp->defined & ~N_EXT) != N_SETV))
-                       sp->value = sp->def_nlist->n_value;
-
-               if (building_shared_object && !(link_mode & SYMBOLIC))
-                       /* No common allocation in shared objects */
-                       continue;
-
-               if ((size = sp->max_common_size) != 0) {
-                       /*
-                        * It's a common.
-                        */
-                       if (sp->defined != (N_UNDF + N_EXT))
-                               fatal("%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)
-                               fatal("%s: Bogus N_SIZE item", sp->name);
-
-               } else
-                       /*
-                        * It's neither
-                        */
-                       continue;
-
-
-               if (relocatable_output && !force_common_definition) {
-                       sp->defined = 0;
-                       undefined_global_sym_count++;
-                       defined_global_sym_count--;
-                       continue;
-               }
-
-               /*
-                * Round up to nearest sizeof (int). I don't know whether
-                * this is necessary or not (given that alignment is taken
-                * care of later), but it's traditional, so I'll leave it in.
-                * Note that if this size alignment is ever removed, ALIGN
-                * above will have to be initialized to 1 instead of sizeof
-                * (int).
-                */
-
-               size = PALIGN(size, sizeof(int));
-
-               while (!(size & align))
-                       align <<= 1;
-
-               align = align > MAX_ALIGNMENT ?
-                       MAX_ALIGNMENT : align;
-
-               bss_size = PALIGN(bss_size + data_size + rrs_data_start, align)
-                               - (data_size + rrs_data_start);
-
-               sp->value = rrs_data_start + data_size + bss_size;
-               if (sp->defined == (N_UNDF | N_EXT))
-                       sp->defined = N_BSS | N_EXT;
-               else {
-                       sp->so_defined = 0;
-                       defined_global_sym_count++;
-               }
-               bss_size += size;
-               if (write_map)
-                       printf("Allocating %s %s: %x at %x\n",
-                               sp->defined==(N_BSS|N_EXT)?"common":"data",
-                               sp->name, size, sp->value);
-
-       } END_EACH_SYMBOL;
-}
-
 
 /*
 
 /*
- * Scan relocation info in ENTRY for contributions to the dynamic section of
- * the output file.
+ * Scan relocation info in ENTRY for contributions to the RRS section
+ * of the output file.
  */
 static void
 consider_relocation (entry, dataseg)
  */
 static void
 consider_relocation (entry, dataseg)
@@ -1848,7 +1821,7 @@ consider_relocation (entry, dataseg)
                        if (RELOC_BASEREL_P(reloc)) {
                                pic_code_seen = 1;
                                if (!RELOC_EXTERN_P(reloc))
                        if (RELOC_BASEREL_P(reloc)) {
                                pic_code_seen = 1;
                                if (!RELOC_EXTERN_P(reloc))
-                                       lsp->rename = 1;
+                                       lsp->flags |= LS_RENAME;
                        }
                        continue;
                }
                        }
                        continue;
                }
@@ -1939,39 +1912,20 @@ consider_relocation (entry, dataseg)
                                continue;
                        }
 
                                continue;
                        }
 
-                       /*
-                        * Only allocate an alias for function calls. Use
-                        * sp->size here as a heuristic to discriminate
-                        * between function definitions and data residing
-                        * in the text segment.
-                        * NOTE THAT THE COMPILER MUST NOT GENERATE ".size"
-                        * DIRECTIVES FOR FUNCTIONS.
-                        * In the future we might go for ".type" directives.
-                        */
-                       if (force_alias_definition && sp->size == 0 &&
-                                       sp->so_defined == N_TEXT + N_EXT) {
+                       if (force_alias_definition && sp->so_defined &&
+                                       sp->aux == AUX_FUNC) {
 
                                /* Call to shared library procedure */
                                alloc_rrs_jmpslot(entry, sp);
 
                                /* Call to shared library procedure */
                                alloc_rrs_jmpslot(entry, sp);
-#define EXPERIMENTAL
-#ifdef EXPERIMENTAL
-                               if (!RELOC_PCREL_P(reloc)) {
-#ifdef DEBUG
-printf("%s: FUNC flag set\n", sp->name);
-#endif
-                                       sp->aux = RRS_FUNC;
-                               }
-#endif
 
 
-                       } else if (sp->size &&
-                                       (sp->so_defined == N_DATA + N_EXT ||
-                                       sp->so_defined == N_TEXT + N_EXT)) {
+                       } else if (sp->size && sp->so_defined &&
+                                       sp->aux == AUX_OBJECT) {
 
                                /* Reference to shared library data */
                                alloc_rrs_cpy_reloc(entry, sp);
                                sp->defined = N_SIZE;
 
 
                                /* Reference to shared library data */
                                alloc_rrs_cpy_reloc(entry, sp);
                                sp->defined = N_SIZE;
 
-                       } else if (!sp->defined && sp->max_common_size == 0)
+                       } else if (!sp->defined && sp->common_size == 0)
                                alloc_rrs_reloc(entry, sp);
 
                } else {
                                alloc_rrs_reloc(entry, sp);
 
                } else {
@@ -1987,6 +1941,76 @@ printf("%s: FUNC flag set\n", sp->name);
        }
 }
 
        }
 }
 
+/*
+ * Determine the disposition of each local symbol.
+ */
+static void
+consider_local_symbols(entry)
+     register struct file_entry *entry;
+{
+       register struct localsymbol     *lsp, *lspend;
+
+       if (entry->flags & E_DYNAMIC)
+               return;
+
+       lspend = entry->symbols + entry->nsymbols;
+
+       /*
+        * For each symbol determine whether it should go
+        * in the output symbol table.
+        */
+
+       for (lsp = entry->symbols; lsp < lspend; lsp++) {
+               register struct nlist *p = &lsp->nzlist.nlist;
+               register int type = p->n_type;
+
+               if (type == N_WARNING)
+                       continue;
+
+               if (SET_ELEMENT_P (type)) {
+                       /*
+                        * This occurs even if global. These types of
+                        * symbols are never written globally, though
+                        * they are stored globally.
+                        */
+                       if (relocatable_output)
+                               lsp->flags |= LS_WRITE;
+
+               } else if (!(type & (N_STAB | N_EXT))) {
+
+                       /*
+                        * Ordinary local symbol
+                        */
+                       if ((lsp->flags & LS_RENAME) || (
+                               discard_locals != DISCARD_ALL &&
+                                       !(discard_locals == DISCARD_L &&
+                                       (lsp->flags & LS_L_SYMBOL))) ) {
+
+                               lsp->flags |= LS_WRITE;
+                               local_sym_count++;
+                       }
+
+               } else if (!(type & N_EXT)) {
+
+                       /*
+                        * Debugger symbol
+                        */
+                       if (strip_symbols == STRIP_NONE) {
+                               lsp->flags |= LS_WRITE;
+                               debugger_sym_count++;
+                       }
+               }
+       }
+
+       /*
+        * Count one for the local symbol that we generate,
+        * whose name is the file's name (usually) and whose address
+        * is the start of the file's text.
+        */
+       if (discard_locals != DISCARD_ALL)
+               local_sym_count++;
+}
+
 /*
  * Accumulate the section sizes of input file ENTRY into the section sizes of
  * the output file.
 /*
  * Accumulate the section sizes of input file ENTRY into the section sizes of
  * the output file.
@@ -1995,8 +2019,6 @@ static void
 consider_file_section_lengths (entry)
      register struct file_entry *entry;
 {
 consider_file_section_lengths (entry)
      register struct file_entry *entry;
 {
-       if (entry->just_syms_flag)
-               return;
 
        entry->text_start_address = text_size;
        /* If there were any vectors, we need to chop them off */
 
        entry->text_start_address = text_size;
        /* If there were any vectors, we need to chop them off */
@@ -2013,9 +2035,7 @@ consider_file_section_lengths (entry)
 /*
  * Determine where the sections of ENTRY go into the output file,
  * whose total section sizes are already known.
 /*
  * Determine where the sections of ENTRY go into the output file,
  * whose total section sizes are already known.
- * Also relocate the addresses of the file's local and debugger symbols
- * and determine which of the local symbols will make it into the
- * output symbol table.
+ * Also relocate the addresses of the file's local and debugger symbols.
  */
 static void
 relocate_file_addresses (entry)
  */
 static void
 relocate_file_addresses (entry)
@@ -2072,57 +2092,165 @@ printf("%s: datastart: %#x, bss %#x\n", get_file_name(entry),
                break;
                }
 
                break;
                }
 
-               /*
-                * See if this symbol should be in the output symbol table.
-                */
+       }
 
 
-               if (type == N_WARNING)
+}
+
+/*
+ * Assign a value to each global symbol.
+ */
+static void
+digest_pass2()
+{
+       FOR_EACH_SYMBOL(i, sp) {
+               int             size;
+               int             align = sizeof(int);
+
+               if (!(sp->flags & GS_REFERENCED))
                        continue;
 
                        continue;
 
-               if (SET_ELEMENT_P (type)) {
+               if (sp->alias &&
+                       (relocatable_output || building_shared_object ||
+                               (sp->alias->defined && !sp->alias->so_defined)))
                        /*
                        /*
-                        * This occurs even if global. These types of
-                        * symbols are never written globally, though
-                        * they are stored globally.
+                        * The alias points at a defined symbol, so it
+                        * must itself be counted as one too, in order to
+                        * compute the correct number of symbol table entries.
                         */
                         */
-                       lsp->write = relocatable_output;
+                       defined_global_sym_count++;
 
 
-               } else if (!(type & (N_STAB | N_EXT))) {
+               if ((sp->defined & N_TYPE) == N_SETV) {
+                       /*
+                        * Set length word at front of vector and zero byte
+                        * at end. Reverse the vector itself to put it in
+                        * file order.
+                        */
+                       unsigned long   i, *p, *q;
+                       unsigned long   length_word_index =
+                                               sp->value / sizeof(long);
+
+                       /* Relocate symbol value */
+                       sp->value += set_sect_start;
+
+                       set_vectors[length_word_index] = sp->setv_count;
 
                        /*
 
                        /*
-                        * Ordinary local symbol
+                        * Relocate vector to final address.
                         */
                         */
-                       lsp->write = (lsp->rename || (
-                                       discard_locals != DISCARD_ALL &&
-                                       !(discard_locals == DISCARD_L &&
-                                                   lsp->is_L_symbol)));
-                       if (lsp->write)
-                               local_sym_count++;
+                       for (i = 0; i < sp->setv_count; i++) {
+                               struct nlist    *p = (struct nlist *)
+                                       set_vectors[1+i+length_word_index];
 
 
-               } else if (!(type & N_EXT)) {
+                               set_vectors[1+i+length_word_index] = p->n_value;
+                               if (building_shared_object) {
+                                       struct relocation_info reloc;
+
+                                       bzero(&reloc, sizeof(reloc));
+                                       RELOC_ADDRESS(&reloc) =
+                                               (1 + i + length_word_index) *
+                                                               sizeof(long)
+                                               + set_sect_start;
+                                       RELOC_TYPE(&reloc) =
+                                       (p->n_type - (N_SETA - N_ABS)) & N_TYPE;
+                                       claim_rrs_segment_reloc(NULL, &reloc);
+                               }
+                       }
 
                        /*
 
                        /*
-                        * Debugger symbol
+                        * Reverse the vector.
                         */
                         */
-                       lsp->write = (strip_symbols == STRIP_NONE);
-                       if (lsp->write)
-                               debugger_sym_count++;
+                       p = &set_vectors[length_word_index + 1];
+                       q = &set_vectors[length_word_index + sp->setv_count];
+                       while (p < q) {
+                               unsigned long tmp = *p;
+                               *p++ = *q;
+                               *q-- = tmp;
+                       }
 
 
+                       /* Clear terminating entry */
+                       set_vectors[length_word_index + sp->setv_count + 1] = 0;
+                       continue;
                }
                }
-       }
 
 
-       /*
-        * Count one for the local symbol that we generate,
-        * whose name is the file's name (usually) and whose address
-        * is the start of the file's text.
-        */
-       if (discard_locals != DISCARD_ALL)
-               local_sym_count++;
 
 
+               if (sp->defined && sp->def_nlist &&
+                               ((sp->defined & ~N_EXT) != N_SETV))
+                       sp->value = sp->def_nlist->n_value;
+
+               /*
+                * If not -r'ing, allocate common symbols in the BSS section.
+                */
+               if (building_shared_object && !(link_mode & SYMBOLIC))
+                       /* No common allocation in shared objects */
+                       continue;
+
+               if ((size = sp->common_size) != 0) {
+                       /*
+                        * It's a common.
+                        */
+                       if (sp->defined != (N_UNDF + N_EXT))
+                               fatal("%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)
+                               fatal("%s: Bogus N_SIZE item", sp->name);
+
+               } else
+                       /*
+                        * It's neither
+                        */
+                       continue;
+
+
+               if (relocatable_output && !force_common_definition) {
+                       sp->defined = 0;
+                       undefined_global_sym_count++;
+                       defined_global_sym_count--;
+                       continue;
+               }
+
+               /*
+                * Round up to nearest sizeof (int). I don't know whether
+                * this is necessary or not (given that alignment is taken
+                * care of later), but it's traditional, so I'll leave it in.
+                * Note that if this size alignment is ever removed, ALIGN
+                * above will have to be initialized to 1 instead of sizeof
+                * (int).
+                */
+
+               size = PALIGN(size, sizeof(int));
+
+               while (!(size & align))
+                       align <<= 1;
+
+               align = align > MAX_ALIGNMENT ? MAX_ALIGNMENT : align;
+
+               bss_size = PALIGN(bss_size + data_size + rrs_data_start, align)
+                               - (data_size + rrs_data_start);
+
+               sp->value = rrs_data_start + data_size + bss_size;
+               if (sp->defined == (N_UNDF | N_EXT))
+                       sp->defined = N_BSS | N_EXT;
+               else {
+                       sp->so_defined = 0;
+                       defined_global_sym_count++;
+               }
+               bss_size += size;
+               if (write_map)
+                       printf("Allocating %s %s: %x at %x\n",
+                               sp->defined==(N_BSS|N_EXT)?"common":"data",
+                               sp->name, size, sp->value);
+
+       } END_EACH_SYMBOL;
 }
 }
-\f
-/* Write the output file */
 
 
+
+/* -------------------------------------------------------------------*/
+
+/* Write the output file */
 void
 write_output ()
 {
 void
 write_output ()
 {
@@ -2138,6 +2266,8 @@ write_output ()
        if (outdesc < 0)
                perror_name (output_filename);
 
        if (outdesc < 0)
                perror_name (output_filename);
 
+       fatal_cleanup_hook = myfatal;
+
        if (fstat (outdesc, &statbuf) < 0)
                perror_name (output_filename);
 
        if (fstat (outdesc, &statbuf) < 0)
                perror_name (output_filename);
 
@@ -2176,6 +2306,9 @@ write_header ()
 {
        int flags = (rrs_section_type == RRS_FULL) ? EX_DYNAMIC : 0;
 
 {
        int flags = (rrs_section_type == RRS_FULL) ? EX_DYNAMIC : 0;
 
+       if (oldmagic && (flags & EX_DYNAMIC))
+               error("Cannot set flag in old magic headers\n");
+
        N_SET_FLAG (outheader, flags);
 
        outheader.a_text = text_size;
        N_SET_FLAG (outheader, flags);
 
        outheader.a_text = text_size;
@@ -2339,7 +2472,7 @@ copy_data (entry)
 
        mywrite (bytes, 1, entry->header.a_data, outdesc);
 }
 
        mywrite (bytes, 1, entry->header.a_data, outdesc);
 }
-\f
+
 /*
  * Relocate ENTRY's text or data section contents. DATA is the address of the
  * contents, in core. DATA_SIZE is the length of the contents. PC_RELOCATION
 /*
  * Relocate ENTRY's text or data section contents. DATA is the address of the
  * contents, in core. DATA_SIZE is the length of the contents. PC_RELOCATION
@@ -2347,6 +2480,10 @@ copy_data (entry)
  * and its address in the input file. RELOC is the address of the
  * relocation info, in core. NRELOC says how many there are.
  */
  * and its address in the input file. RELOC is the address of the
  * relocation info, in core. NRELOC says how many there are.
  */
+
+/* HACK: md.c may need access to this */
+int    pc_relocation;
+
 void
 perform_relocation(data, data_size, reloc, nreloc, entry, dataseg)
        char                    *data;
 void
 perform_relocation(data, data_size, reloc, nreloc, entry, dataseg)
        char                    *data;
@@ -2356,12 +2493,13 @@ perform_relocation(data, data_size, reloc, nreloc, entry, dataseg)
        struct file_entry       *entry;
        int                     dataseg;
 {
        struct file_entry       *entry;
        int                     dataseg;
 {
-       register struct relocation_info *r = reloc;
-       struct relocation_info *end = reloc + nreloc;
 
 
-       text_relocation = entry->text_start_address;
-       data_relocation = entry->data_start_address - entry->header.a_text;
-       bss_relocation = entry->bss_start_address -
+       register struct relocation_info *r = reloc;
+       struct relocation_info          *end = reloc + nreloc;
+
+       int text_relocation = entry->text_start_address;
+       int data_relocation = entry->data_start_address - entry->header.a_text;
+       int bss_relocation = entry->bss_start_address -
                                entry->header.a_text - entry->header.a_data;
        pc_relocation = dataseg?
                        entry->data_start_address - entry->header.a_text:
                                entry->header.a_text - entry->header.a_data;
        pc_relocation = dataseg?
                        entry->data_start_address - entry->header.a_text:
@@ -2616,10 +2754,10 @@ write_rel ()
 
        /* BLECH - Assign number 0 to __DYNAMIC (!! Sun compatibility) */
 
 
        /* BLECH - Assign number 0 to __DYNAMIC (!! Sun compatibility) */
 
-       if (dynamic_symbol->referenced)
+       if (dynamic_symbol->flags & GS_REFERENCED)
                dynamic_symbol->symbolnum = count++;
        FOR_EACH_SYMBOL(i, sp) {
                dynamic_symbol->symbolnum = count++;
        FOR_EACH_SYMBOL(i, sp) {
-               if (sp != dynamic_symbol && sp->referenced) {
+               if (sp != dynamic_symbol && (sp->flags & GS_REFERENCED)) {
                        sp->symbolnum = count++;
                        if (sp->size)
                                count++;
                        sp->symbolnum = count++;
                        if (sp->size)
                                count++;
@@ -2664,7 +2802,7 @@ assign_symbolnums(entry, countp)
                n++;
 
        for (lsp = entry->symbols; lsp < lspend; lsp++) {
                n++;
 
        for (lsp = entry->symbols; lsp < lspend; lsp++) {
-               if (lsp->write)
+               if (lsp->flags & LS_WRITE)
                        lsp->symbolnum = n++;
        }
        *countp = n;
                        lsp->symbolnum = n++;
        }
        *countp = n;
@@ -2729,10 +2867,11 @@ coptxtrel(entry)
                         * If we aren't going to be adding in the
                         * value in memory on the next pass of the
                         * loader, then we need to add it in from the
                         * If we aren't going to be adding in the
                         * value in memory on the next pass of the
                         * loader, then we need to add it in from the
-                        * relocation entry.  Otherwise the work we
+                        * relocation entry, unless the symbol remains
+                        * external in our output. Otherwise the work we
                         * did in this pass is lost.
                         */
                         * did in this pass is lost.
                         */
-                       if (!RELOC_MEMORY_ADD_P(r))
+                       if (!RELOC_MEMORY_ADD_P(r) && !RELOC_EXTERN_P(r))
                                RELOC_ADD_EXTRA(r) += sp->value;
 #endif
                } else
                                RELOC_ADD_EXTRA(r) += sp->value;
 #endif
                } else
@@ -2794,7 +2933,7 @@ copdatrel(entry)
 
                symtype = sp->defined & N_TYPE;
 
 
                symtype = sp->defined & N_TYPE;
 
-               if (!pic_code_seen && (force_common_definition ||
+               if (!pic_code_seen && ( symtype == N_BSS ||
                                        symtype == N_DATA ||
                                        symtype == N_TEXT ||
                                        symtype == N_ABS)) {
                                        symtype == N_DATA ||
                                        symtype == N_TEXT ||
                                        symtype == N_ABS)) {
@@ -2939,7 +3078,7 @@ write_syms()
         * If defined (ie. not relocatable_output), make it look
         * like an internal symbol.
         */
         * If defined (ie. not relocatable_output), make it look
         * like an internal symbol.
         */
-       if (dynamic_symbol->referenced) {
+       if (dynamic_symbol->flags & GS_REFERENCED) {
                nl.n_other = 0;
                nl.n_desc = 0;
                nl.n_type = dynamic_symbol->defined;
                nl.n_other = 0;
                nl.n_desc = 0;
                nl.n_type = dynamic_symbol->defined;
@@ -2961,7 +3100,7 @@ write_syms()
                        /* Already dealt with above */
                        continue;
 
                        /* Already dealt with above */
                        continue;
 
-               if (!sp->referenced)
+               if (!(sp->flags & GS_REFERENCED))
                        /* Came from shared object but was not used */
                        continue;
 
                        /* Came from shared object but was not used */
                        continue;
 
@@ -3009,6 +3148,7 @@ write_syms()
                                 */
                                nl.n_type = sp->alias->defined;
                                nl.n_value = sp->alias->value;
                                 */
                                nl.n_type = sp->alias->defined;
                                nl.n_value = sp->alias->value;
+                               nl.n_other = N_OTHER(0, sp->alias->aux);
                        } else {
                                if (sp->defined == N_SIZE)
                                        nl.n_type = N_DATA | N_EXT;
                        } else {
                                if (sp->defined == N_SIZE)
                                        nl.n_type = N_DATA | N_EXT;
@@ -3019,9 +3159,10 @@ write_syms()
                                        fatal("%s: N_INDR has value %#x",
                                                        sp->name, sp->value);
                                nl.n_value = sp->value;
                                        fatal("%s: N_INDR has value %#x",
                                                        sp->name, sp->value);
                                nl.n_value = sp->value;
+                               nl.n_other = N_OTHER(0, sp->aux);
                        }
 
                        }
 
-               } else if (sp->max_common_size) {
+               } else if (sp->common_size) {
                        /*
                         * defined as common but not allocated,
                         * happens only with -r and not -d, write out
                        /*
                         * defined as common but not allocated,
                         * happens only with -r and not -d, write out
@@ -3032,7 +3173,7 @@ write_syms()
                         * undefined in digest_symbols.
                         */
                        nl.n_type = N_UNDF | N_EXT;
                         * undefined in digest_symbols.
                         */
                        nl.n_type = N_UNDF | N_EXT;
-                       nl.n_value = sp->max_common_size;
+                       nl.n_value = sp->common_size;
                } else if (!sp->defined) {
                        /* undefined -- legit only if -r */
                        nl.n_type = N_UNDF | N_EXT;
                } else if (!sp->defined) {
                        /* undefined -- legit only if -r */
                        nl.n_type = N_UNDF | N_EXT;
@@ -3053,6 +3194,9 @@ write_syms()
                *bufp++ = nl;
                syms_written++;
 
                *bufp++ = nl;
                syms_written++;
 
+               /*
+                * Write second symbol of an alias pair.
+                */
                if (nl.n_type == N_INDR + N_EXT) {
                        if (sp->alias == NULL)
                                fatal("internal error: alias in hyperspace");
                if (nl.n_type == N_INDR + N_EXT) {
                        if (sp->alias == NULL)
                                fatal("internal error: alias in hyperspace");
@@ -3066,6 +3210,9 @@ write_syms()
                        syms_written++;
                }
 
                        syms_written++;
                }
 
+               /*
+                * Write N_SIZE symbol for a symbol with a known size.
+                */
                if (relocatable_output && sp->size) {
                        nl.n_type = N_SIZE + N_EXT;
                        nl.n_un.n_strx = assign_string_table_index(sp->name);
                if (relocatable_output && sp->size) {
                        nl.n_type = N_SIZE + N_EXT;
                        nl.n_un.n_strx = assign_string_table_index(sp->name);
@@ -3144,7 +3291,7 @@ write_file_syms(entry, syms_written_addr)
 
        register struct nlist *bufp = buf;
 
 
        register struct nlist *bufp = buf;
 
-       if (entry->is_dynamic)
+       if (entry->flags & E_DYNAMIC)
                return;
 
        /*
                return;
 
        /*
@@ -3168,9 +3315,6 @@ write_file_syms(entry, syms_written_addr)
                nl.n_other = 0;
                *bufp++ = nl;
                (*syms_written_addr)++;
                nl.n_other = 0;
                *bufp++ = nl;
                (*syms_written_addr)++;
-#if 0
-               entry->local_syms_offset = *syms_written_addr * sizeof(struct nlist);
-#endif
        }
        /* Read the file's string table.  */
 
        }
        /* Read the file's string table.  */
 
@@ -3185,12 +3329,12 @@ write_file_syms(entry, syms_written_addr)
                register int    write = 0;
                char            *name;
 
                register int    write = 0;
                char            *name;
 
-               if (! lsp->write)
+               if (!(lsp->flags & LS_WRITE))
                        continue;
 
                if (p->n_un.n_strx == 0)
                        name = NULL;
                        continue;
 
                if (p->n_un.n_strx == 0)
                        name = NULL;
-               else if (lsp->rename == 0)
+               else if (!(lsp->flags & LS_RENAME))
                        name = p->n_un.n_strx + entry->strings;
                else {
                        char *cp = p->n_un.n_strx + entry->strings;
                        name = p->n_un.n_strx + entry->strings;
                else {
                        char *cp = p->n_un.n_strx + entry->strings;
@@ -3229,3 +3373,50 @@ write_file_syms(entry, syms_written_addr)
        write_string_table();
        entry->strings = 0;     /* Since it will disappear anyway.  */
 }
        write_string_table();
        entry->strings = 0;     /* Since it will disappear anyway.  */
 }
+
+/*
+ * Output COUNT*ELTSIZE bytes of data at BUF to the descriptor DESC.
+ */
+void
+mywrite (buf, count, eltsize, desc)
+     void *buf;
+     int count;
+     int eltsize;
+     int desc;
+{
+       register int val;
+       register int bytes = count * eltsize;
+
+       while (bytes > 0) {
+               val = write (desc, buf, bytes);
+               if (val <= 0)
+                       perror(output_filename);
+               buf += val;
+               bytes -= val;
+       }
+}
+
+static void
+myfatal()
+{
+       if (outdesc > 0)
+               unlink(output_filename);
+}
+
+/*
+ * Output PADDING zero-bytes to descriptor OUTDESC.
+ * PADDING may be negative; in that case, do nothing.
+ */
+void
+padfile (padding, outdesc)
+     int padding;
+     int outdesc;
+{
+       register char *buf;
+       if (padding <= 0)
+               return;
+
+       buf = (char *) alloca (padding);
+       bzero (buf, padding);
+       mywrite (buf, padding, 1, outdesc);
+}
index 1cee37a..a43eac8 100644 (file)
@@ -1,4 +1,6 @@
-/*     $Id: ld.h,v 1.8 1993/12/11 11:58:26 jkh Exp $   */
+/*
+ *     $Id: ld.h,v 1.8 1994/01/28 20:56:24 pk Exp $
+ */
 /*-
  * This code is derived from software copyrighted by the Free Software
  * Foundation.
 /*-
  * This code is derived from software copyrighted by the Free Software
  * Foundation.
 #define alloca __builtin_alloca
 #endif
 
 #define alloca __builtin_alloca
 #endif
 
+#ifdef __FreeBSD__
+#define FreeBSD
+#endif
+
 #include "md.h"
 #include "link.h"
 
 #include "md.h"
 #include "link.h"
 
 /* Align to machine dependent boundary */
 #define MALIGN(x)      PALIGN(x,MAX_ALIGNMENT)
 
 /* Align to machine dependent boundary */
 #define MALIGN(x)      PALIGN(x,MAX_ALIGNMENT)
 
-/* Size of a page; obtained from the operating system.  */
-
-int page_size;
-
 /* Name this program was invoked by.  */
 /* Name this program was invoked by.  */
+char   *progname;
 
 
-char *progname;
-\f
 /* System dependencies */
 
 /* Define this to specify the default executable format.  */
 
 #ifndef DEFAULT_MAGIC
 /* System dependencies */
 
 /* Define this to specify the default executable format.  */
 
 #ifndef DEFAULT_MAGIC
+#ifdef FreeBSD
 #define DEFAULT_MAGIC QMAGIC
 #define DEFAULT_MAGIC QMAGIC
+extern int     netzmagic;
+#else
+#define DEFAULT_MAGIC ZMAGIC
+#endif
 #endif
 #endif
-
-extern netzmagic;
 
 
 /*
 
 
 /*
@@ -181,7 +185,7 @@ extern netzmagic;
 #ifndef DATA_START
 #define DATA_START(x)          N_DATADDR(x)
 #endif
 #ifndef DATA_START
 #define DATA_START(x)          N_DATADDR(x)
 #endif
-\f
+
 /* If a this type of symbol is encountered, its name is a warning
    message to print each time the symbol referenced by the next symbol
    table entry is referenced.
 /* If a this type of symbol is encountered, its name is a warning
    message to print each time the symbol referenced by the next symbol
    table entry is referenced.
@@ -330,6 +334,22 @@ extern netzmagic;
 
 #endif /* not __GNU_STAB__ */
 \f
 
 #endif /* not __GNU_STAB__ */
 \f
+
+typedef struct localsymbol {
+       struct nzlist           nzlist;         /* n[z]list from file */
+       struct glosym           *symbol;        /* Corresponding global symbol,
+                                                  if any */
+       struct localsymbol      *next;          /* List of definitions */
+       struct file_entry       *entry;         /* Backpointer to file */
+       long                    gotslot_offset; /* Position in GOT, if any */
+       int                     symbolnum;      /* Position in output nlist */
+       int                     flags;
+#define LS_L_SYMBOL            1       /* Local symbol starts with an `L' */
+#define LS_WRITE               2       /* Symbol goes in output symtable */
+#define LS_RENAME              4       /* xlat name to `<file>.<name>' */
+#define LS_GOTSLOTCLAIMED      8       /* This symbol has a GOT entry */
+} localsymbol_t;
+
 /* Symbol table */
 
 /*
 /* Symbol table */
 
 /*
@@ -340,225 +360,102 @@ extern netzmagic;
  */
 
 typedef struct glosym {
  */
 
 typedef struct glosym {
-       /* Pointer to next symbol in this symbol's hash bucket.  */
-       struct glosym   *link;
-       /* Name of this symbol.  */
-       char            *name;
-       /* Value of this symbol as a global symbol.  */
-       long            value;
-       /*
-        * Chain of external 'nlist's in files for this symbol, both defs and
-        * refs.
-        */
-       struct localsymbol      *refs;
-       /*
-        * Any warning message that might be associated with this symbol from
-        * an N_WARNING symbol encountered.
-        */
-       char            *warning;
-       /*
-        * Nonzero means definitions of this symbol as common have been seen,
-        * and the value here is the largest size specified by any of them.
-        */
-       int             max_common_size;
-       /*
-        * For relocatable_output, records the index of this global sym in
-        * the symbol table to be written, with the first global sym given
-        * index 0.
-        */
-       int             symbolnum;
-       /*
-        * For dynamically linked output, records the index in the RRS
-        * symbol table.
-        */
-       int             rrs_symbolnum;
-       /*
-        * Nonzero means a definition of this global symbol is known to
-        * exist. Library members should not be loaded on its account.
-        */
-       char            defined;
-       /*
-        * Nonzero means a reference to this global symbol has been seen in a
-        * file that is surely being loaded. A value higher than 1 is the
-        * n_type code for the symbol's definition.
-        */
-       char            referenced;
-       /*
-        * A count of the number of undefined references printed for a
-        * specific symbol.  If a symbol is unresolved at the end of
-        * digest_symbols (and the loading run is supposed to produce
-        * relocatable output) do_file_warnings keeps track of how many
-        * unresolved reference error messages have been printed for each
-        * symbol here.  When the number hits MAX_UREFS_PRINTED, messages
-        * stop.
-        */
-       unsigned char   undef_refs;
-       /*
-        * 1 means that this symbol has multiple definitions.  2 means that
-        * it has multiple definitions, and some of them are set elements,
-        * one of which has been printed out already.
-        */
-       unsigned char   multiply_defined;
-       /* Nonzero means print a message at all refs or defs of this symbol */
-       char            trace;
-
-       /*
-        * For symbols of type N_INDR, this points at the real symbol.
-        */
-       struct glosym   *alias;
-
-       /*
-        * Count number of elements in set vector if symbol is of type N_SETV
-        */
-       int             setv_count;
-
-       /* Dynamic lib support */
-
-       /*
-        * Nonzero means a definition of this global symbol has been found
-        * in a shared object. These symbols do not go into the symbol
-        * section of the resulting a.out file. They *do* go into the
-        * dynamic link information segment.
-        */
-       char            so_defined;
-
-       /* Size of symbol as determined by N_SIZE symbols in object files */
-       int             size;
-
-       /* Auxialiary info to put in the `nz_other' field of the
-        * RRS symbol table. Used by the run-time linker to resolve
-        * references to function addresses from within shared objects.
-        */
-       int             aux;
-#define RRS_FUNC       2
-
-       /*
-        * Chain of external 'nlist's in shared objects for this symbol, both
-        * defs and refs.
-        */
-       struct localsymbol      *sorefs;
+       struct glosym   *link;  /* Next symbol hash bucket. */
+       char            *name;  /* Name of this symbol.  */
+       long            value;  /* Value of this symbol */
+       localsymbol_t   *refs;  /* Chain of local symbols from object
+                                  files pertaining to this global
+                                  symbol */
+       localsymbol_t   *sorefs;/* Same for local symbols from shared
+                                  object files. */
+
+       char    *warning;       /* message, from N_WARNING nlists */
+       int     common_size;    /* Common size */
+       int     symbolnum;      /* Symbol index in output symbol table */
+       int     rrs_symbolnum;  /* Symbol index in RRS symbol table */
+
+       struct nlist    *def_nlist;     /* The local symbol that gave this
+                                          global symbol its definition */
+
+       char    defined;        /* Definition of this symbol */
+       char    so_defined;     /* Definition of this symbol in a shared
+                                  object. These go into the RRS symbol table */
+       u_char  undef_refs;     /* Count of number of "undefined"
+                                  messages printed for this symbol */
+       u_char  mult_defs;      /* Same for "multiply defined" symbols */
+       struct glosym   *alias; /* For symbols of type N_INDR, this
+                                  points at the real symbol. */
+       int     setv_count;     /* Number of elements in N_SETV symbols */
+       int     size;           /* Size of this symbol (either from N_SIZE
+                                  symbols or a from shared object's RRS */
+       int     aux;            /* Auxiliary type information conveyed in
+                                  the `n_other' field of nlists */
 
        /* The offset into one of the RRS tables, -1 if not used */
 
        /* The offset into one of the RRS tables, -1 if not used */
-       long                    jmpslot_offset;
-       char                    jmpslot_claimed;
+       long    jmpslot_offset;
+       long    gotslot_offset;
 
 
-       long                    gotslot_offset;
-       char                    gotslot_claimed;
+       long                    flags;
 
 
-       char                    cpyreloc_reserved;
-       char                    cpyreloc_claimed;
+#define GS_DEFINED             1       /* Symbol has definition (notyetused)*/
+#define GS_REFERENCED          2       /* Symbol is referred to by something
+                                          interesting */
+#define GS_TRACE               4       /* Symbol will be traced */
+#define GS_JMPSLOTCLAIMED      8       /*                               */
+#define GS_GOTSLOTCLAIMED      0x10    /* Some state bits concerning    */
+#define GS_CPYRELOCRESERVED    0x20    /* entries in GOT and PLT tables */
+#define GS_CPYRELOCCLAIMED     0x40    /*                               */
 
 
-       /* The local symbol that gave this global symbol its definition */
-       struct nlist            *def_nlist;
 } symbol;
 
 /* Number of buckets in symbol hash table */
 } symbol;
 
 /* Number of buckets in symbol hash table */
-#define        TABSIZE 1009
+#define        SYMTABSIZE      1009
 
 
-/* The symbol hash table: a vector of TABSIZE pointers to struct glosym. */
-symbol *symtab[TABSIZE];
+/* The symbol hash table: a vector of SYMTABSIZE pointers to struct glosym. */
+extern symbol *symtab[];
 #define FOR_EACH_SYMBOL(i,sp) {                                        \
        int i;                                                  \
 #define FOR_EACH_SYMBOL(i,sp) {                                        \
        int i;                                                  \
-       for (i = 0; i < TABSIZE; i++) {                         \
+       for (i = 0; i < SYMTABSIZE; i++) {                              \
                register symbol *sp;                            \
                for (sp = symtab[i]; sp; sp = sp->link)
 
 #define END_EACH_SYMBOL        }}
 
                register symbol *sp;                            \
                for (sp = symtab[i]; sp; sp = sp->link)
 
 #define END_EACH_SYMBOL        }}
 
-/* Number of symbols in symbol hash table. */
-int num_hash_tab_syms;
-
-/* Count number of nlist entries for global symbols */
-int global_sym_count;
-
-/* Count number of N_SIZE nlist entries for output (relocatable_output only) */
-int size_sym_count;
-
-/* Count the number of nlist entries that are for local symbols.
-   This count and the three following counts
-   are incremented as as symbols are entered in the symbol table.  */
-int local_sym_count;
-
-/* Count number of nlist entries that are for local symbols
-   whose names don't start with L. */
-int non_L_local_sym_count;
-
-/* Count the number of nlist entries for debugger info.  */
-int debugger_sym_count;
-
-/* Count the number of global symbols referenced and not defined.  */
-int undefined_global_sym_count;
-
-/* Count the number of symbols referenced from shared objects and not defined */
-int undefined_shobj_sym_count;
-
-/* Count the number of global symbols multiply defined.  */
-int multiple_def_count;
-
-/* Count the number of defined global symbols.
-   Each symbol is counted only once
-   regardless of how many different nlist entries refer to it,
-   since the output file will need only one nlist entry for it.
-   This count is computed by `digest_symbols';
-   it is undefined while symbols are being loaded. */
-int defined_global_sym_count;
-
-/* Count the number of symbols defined through common declarations.
-   This count is kept in symdef_library, linear_library, and
-   enter_global_ref.  It is incremented when the defined flag is set
-   in a symbol because of a common definition, and decremented when
-   the symbol is defined "for real" (ie. by something besides a common
-   definition).  */
-int common_defined_global_count;
-
-/* Count the number of linker defined symbols.
-   XXX - Currently, only __DYNAMIC and _G_O_T_ go here if required,
-   perhaps _etext, _edata and _end should go here too */
-int    special_sym_count;
-
-/* Count number of aliased symbols */
-int    global_alias_count;
-
-/* Count number of set element type symbols and the number of separate
-   vectors which these symbols will fit into */
-int    set_symbol_count;
-int    set_vector_count;
-
-/* Define a linked list of strings which define symbols which should
-   be treated as set elements even though they aren't.  Any symbol
-   with a prefix matching one of these should be treated as a set
-   element.
-
-   This is to make up for deficiencies in many assemblers which aren't
-   willing to pass any stabs through to the loader which they don't
-   understand.  */
-struct string_list_element {
-  char *str;
-  struct string_list_element *next;
-};
+/* # of global symbols referenced and not defined.  */
+extern int     undefined_global_sym_count;
 
 
-struct string_list_element *set_element_prefixes;
+/* # of undefined symbols referenced by shared objects */
+extern int     undefined_shobj_sym_count;
 
 
-/* Count the number of warning symbols encountered. */
-int warning_count;
+/* # of multiply defined symbols. */
+extern int     multiple_def_count;
 
 
-/* 1 => write load map.  */
-int write_map;
+/* # of common symbols. */
+extern int     common_defined_global_count;
 
 
-/* 1 => write relocation into output file so can re-input it later.  */
-int    relocatable_output;
+/* # of warning symbols encountered. */
+extern int     warning_count;
 
 
-/* Nonzero means ptr to symbol entry for symbol to use as start addr.
-   -e sets this.  */
-symbol *entry_symbol;
+/*
+ * Define a linked list of strings which define symbols which should be
+ * treated as set elements even though they aren't.  Any symbol with a prefix
+ * matching one of these should be treated as a set element.
+ * 
+ * This is to make up for deficiencies in many assemblers which aren't willing
+ * to pass any stabs through to the loader which they don't understand.
+ */
+struct string_list_element {
+       char *str;
+       struct string_list_element *next;
+};
 
 
-symbol *edata_symbol;          /* the symbol _edata */
-symbol *etext_symbol;          /* the symbol _etext */
-symbol *end_symbol;            /* the symbol _end */
-symbol *got_symbol;            /* the symbol __GLOBAL_OFFSET_TABLE_ */
-symbol *dynamic_symbol;        /* the symbol __DYNAMIC */
+extern symbol  *entry_symbol;          /* the entry symbol, if any */
+extern symbol  *edata_symbol;          /* the symbol _edata */
+extern symbol  *etext_symbol;          /* the symbol _etext */
+extern symbol  *end_symbol;            /* the symbol _end */
+extern symbol  *got_symbol;            /* the symbol __GLOBAL_OFFSET_TABLE_ */
+extern symbol  *dynamic_symbol;        /* the symbol __DYNAMIC */
 
 
-\f
 /*
  * Each input file, and each library member ("subfile") being loaded, has a
  * `file_entry' structure for it.
 /*
  * Each input file, and each library member ("subfile") being loaded, has a
  * `file_entry' structure for it.
@@ -573,160 +470,82 @@ symbol   *dynamic_symbol;        /* the symbol __DYNAMIC */
  */
 
 struct file_entry {
  */
 
 struct file_entry {
-       /* Name of this file.  */
-       char           *filename;
-
+       char    *filename;      /* Name of this file.  */
        /*
         * Name to use for the symbol giving address of text start Usually
         * the same as filename, but for a file spec'd with -l this is the -l
         * switch itself rather than the filename.
         */
        /*
         * Name to use for the symbol giving address of text start Usually
         * the same as filename, but for a file spec'd with -l this is the -l
         * switch itself rather than the filename.
         */
-       char           *local_sym_name;
-
-       /* Describe the layout of the contents of the file */
-
-       /* The file's a.out header.  */
-       struct exec     header;
-#if 0
-       /* Offset in file of GDB symbol segment, or 0 if there is none.  */
-       int             symseg_offset;
-#endif
-
-       /* Describe data from the file loaded into core */
-
+       char            *local_sym_name;
+       struct exec     header; /* The file's a.out header.  */
+       localsymbol_t   *symbols;       /* Symbol table of the file. */
+       int             nsymbols;       /* Number of symbols in above array. */
+       int             string_size;    /* Size in bytes of string table. */
+       char            *strings;       /* Pointer to the string table when
+                                          in core, NULL otherwise */
+       int             strings_offset; /* Offset of string table,
+                                          (normally N_STROFF() + 4) */
        /*
        /*
-        * Symbol table of the file.
-        * We need access to the global symbol early, ie. before
-        * symbols are asssigned there final values. gotslot_offset is
-        * here because GOT entries may be generated for local symbols.
+        * Next two used only if `relocatable_output' or if needed for
+        * output of undefined reference line numbers.
         */
         */
-       struct localsymbol {
-               struct nzlist           nzlist;
-               struct glosym           *symbol;
-               struct localsymbol      *next;
-               long                    gotslot_offset;
-               char                    gotslot_claimed;
-               char                    write;
-               char                    is_L_symbol;
-               char                    rename;
-               int                     symbolnum;
-       } *symbols;
-
-       /* Number of symbols in above array. */
-       int             nsymbols;
-
-       /* Size in bytes of string table.  */
-       int             string_size;
+       struct relocation_info  *textrel;       /* Text relocations */
+       int                     ntextrel;       /* # of text relocations */
+       struct relocation_info  *datarel;       /* Data relocations */
+       int                     ndatarel;       /* # of data relocations */
 
        /*
 
        /*
-        * Pointer to the string table. The string table is not kept in core
-        * all the time, but when it is in core, its address is here.
+        * Relation of this file's segments to the output file.
         */
         */
-       char           *strings;
-
-       /* Offset of string table (normally N_STROFF() + 4) */
-       int             strings_offset;
-
-       /* Next two used only if `relocatable_output' or if needed for */
-       /* output of undefined reference line numbers. */
-
-       /* Text reloc info saved by `write_text' for `coptxtrel'.  */
-       struct relocation_info *textrel;
-       int             ntextrel;
-
-       /* Data reloc info saved by `write_data' for `copdatrel'.  */
-       struct relocation_info *datarel;
-       int             ndatarel;
-
-       /* Relation of this file's segments to the output file */
-
-       /* Start of this file's text seg in the output file core image.  */
-       int             text_start_address;
-
-       /* Start of this file's data seg in the output file core image.  */
-       int             data_start_address;
-
-       /* Start of this file's bss seg in the output file core image.  */
-       int             bss_start_address;
-#if 0
-       /*
-        * Offset in bytes in the output file symbol table of the first local
-        * symbol for this file. Set by `write_file_symbols'.
-        */
-       int             local_syms_offset;
-#endif
-
-       /* For library members only */
-
-       /* For a library, points to chain of entries for the library members. */
-       struct file_entry *subfiles;
-
-       /*
-        * For a library member, offset of the member within the archive.
-        * Zero for files that are not library members.
-        */
-       int             starting_offset;
-
-       /* Size of contents of this file, if library member.  */
-       int             total_size;
-
-       /* For library member, points to the library's own entry.  */
-       struct file_entry *superfile;
-
-       /* For library member, points to next entry for next member.  */
-       struct file_entry *chain;
-
+       int     text_start_address;     /* Start of this file's text segment
+                                          in the output file core image. */
+       int     data_start_address;     /* Start of this file's data segment
+                                          in the output file core image. */
+       int     bss_start_address;      /* Start of this file's bss segment
+                                          in the output file core image. */
+       struct file_entry *subfiles;    /* For a library, points to chain of
+                                          entries for the library members. */
+       struct file_entry *superfile;   /* For library member, points to the
+                                          library's own entry.  */
+       struct file_entry *chain;       /* For library member, points to next
+                                          entry for next member.  */
+       int     starting_offset;        /* For a library member, offset of the
+                                          member within the archive. Zero for
+                                          files that are not library members.*/
+       int     total_size;             /* Size of contents of this file,
+                                          if library member. */
 #ifdef SUN_COMPAT
 #ifdef SUN_COMPAT
-       /* For shared libraries which have a .sa companion */
-       struct file_entry *silly_archive;
+       struct file_entry *silly_archive;/* For shared libraries which have
+                                           a .sa companion */
 #endif
 #endif
-
-       /* 1 if file is a library. */
-       char            library_flag;
-
-       /* 1 if file's header has been read into this structure.  */
-       char            header_read_flag;
-
-       /* 1 means search a set of directories for this file.  */
-       char            search_dirs_flag;
-
-       /*
-        * 1 means this is base file of incremental load. Do not load this
-        * file's text or data. Also default text_start to after this file's
-        * bss.
-        */
-       char            just_syms_flag;
-
-       /* 1 means search for dynamic libraries (dependent on -B switch) */
-       char            search_dynamic_flag;
-
-       /* version numbers of selected shared library */
-       int             lib_major, lib_minor;
-
-       /* This entry is a shared object */
-       char            is_dynamic;
-
-       /* 1 if this entry is not a major player anymore */
-       char            scrapped;
+       int     lib_major, lib_minor;   /* Version numbers of a shared object */
+
+       int     flags;
+#define E_IS_LIBRARY           1       /* File is a an archive */
+#define E_HEADER_VALID         2       /* File's header has been read */
+#define E_SEARCH_DIRS          4       /* Search directories for file */
+#define E_SEARCH_DYNAMIC       8       /* Search for shared libs allowed */
+#define E_JUST_SYMS            0x10    /* File is used for incremental load */
+#define E_DYNAMIC              0x20    /* File is a shared object */
+#define E_SCRAPPED             0x40    /* Ignore this file */
+#define E_SYMBOLS_USED         0x80    /* Symbols from this entry were used */
 };
 
 };
 
-typedef struct localsymbol localsymbol_t;
+/*
+ * Section start addresses.
+ */
+extern int     text_size;              /* total size of text. */
+extern int     text_start;             /* start of text */
+extern int     text_pad;               /* clear space between text and data */
+extern int     data_size;              /* total size of data. */
+extern int     data_start;             /* start of data */
+extern int     data_pad;               /* part of bss segment within data */
 
 
-/* Vector of entries for input files specified by arguments.
-   These are all the input files except for members of specified libraries.  */
-struct file_entry *file_table;
+extern int     bss_size;               /* total size of bss. */
+extern int     bss_start;              /* start of bss */
 
 
-/* Length of that vector.  */
-int number_of_files;
-
-/* Current link mode */
-#define DYNAMIC                1               /* Consider shared libraries */
-#define SYMBOLIC       2               /* Force symbolic resolution */
-#define FORCEARCHIVE   4               /* Force inclusion of all members
-                                          of archives */
-#define SHAREABLE      8               /* Build a shared object */
-#define SILLYARCHIVE   16              /* Process .sa companions, if any */
-int    link_mode;
+extern int     text_reloc_size;        /* total size of text relocation. */
+extern int     data_reloc_size;        /* total size of data relocation. */
 
 /*
  * Runtime Relocation Section (RRS).
 
 /*
  * Runtime Relocation Section (RRS).
@@ -735,115 +554,57 @@ int      link_mode;
  * static linking), or can just exist of GOT and PLT entries (in case of
  * statically linked PIC code).
  */
  * static linking), or can just exist of GOT and PLT entries (in case of
  * statically linked PIC code).
  */
-
-int    rrs_section_type;
+extern int             rrs_section_type;       /* What's in the RRS section */
 #define RRS_NONE       0
 #define RRS_PARTIAL    1
 #define RRS_FULL       2
 #define RRS_NONE       0
 #define RRS_PARTIAL    1
 #define RRS_FULL       2
-
-int    rrs_text_size;
-int    rrs_data_size;
-int    rrs_text_start;
-int    rrs_data_start;
+extern int             rrs_text_size;          /* Size of RRS text additions */
+extern int             rrs_text_start;         /* Location of above */
+extern int             rrs_data_size;          /* Size of RRS data additions */
+extern int             rrs_data_start;         /* Location of above */
 
 /* Version number to put in __DYNAMIC (set by -V) */
 
 /* Version number to put in __DYNAMIC (set by -V) */
-int    soversion;
-
-/* When loading the text and data, we can avoid doing a close
-   and another open between members of the same library.
-
-   These two variables remember the file that is currently open.
-   Both are zero if no file is open.
-
-   See `each_file' and `file_close'.  */
-
-struct file_entry *input_file;
-int input_desc;
-
-/* The name of the file to write; "a.out" by default.  */
-
-char *output_filename;
-
-/* Descriptor for writing that file with `mywrite'.  */
-
-int outdesc;
-
-/* Header for that file (filled in by `write_header').  */
-
-struct exec outheader;
-
-/* The following are computed by `digest_symbols'.  */
-
-int text_size;         /* total size of text of all input files. */
-int data_size;         /* total size of data of all input files. */
-int bss_size;          /* total size of bss of all input files. */
-int text_reloc_size;   /* total size of text relocation of all input files. */
-int data_reloc_size;   /* total size of data relocation of all input files. */
-
-/* Relocation offsets set by perform_relocation(). Defined globaly here
-   because some of the RRS routines need access to them */
-int    text_relocation;
-int    data_relocation;
-int    bss_relocation;
-int    pc_relocation;
-
-/* Specifications of start and length of the area reserved at the end
-   of the data segment for the set vectors.  Computed in 'digest_symbols' */
-int set_sect_start;
-int set_sect_size;
-
-/* Amount of cleared space to leave between the text and data segments.  */
-int text_pad;
-
-/* Amount of bss segment to include as part of the data segment.  */
-int data_pad;
+extern int     soversion;
+#ifndef DEFAULT_SOVERSION
+#define DEFAULT_SOVERSION      LD_VERSION_BSD
+#endif
 
 
+extern int             pc_relocation;          /* Current PC reloc value */
 
 
-/* Record most of the command options.  */
+extern int             number_of_shobjs;       /* # of shared objects linked in */
 
 
-/* Address we assume the text section will be loaded at.
-   We relocate symbols and text and data for this, but we do not
-   write any padding in the output file for it.  */
-int text_start;
+/* Current link mode */
+extern int             link_mode;
+#define DYNAMIC                1               /* Consider shared libraries */
+#define SYMBOLIC       2               /* Force symbolic resolution */
+#define FORCEARCHIVE   4               /* Force inclusion of all members
+                                          of archives */
+#define SHAREABLE      8               /* Build a shared object */
+#define SILLYARCHIVE   16              /* Process .sa companions, if any */
 
 
-/* Offset of default entry-pc within the text section.  */
-int entry_offset;
+extern int             outdesc;        /* Output file descriptor. */
+extern struct exec     outheader;      /* Output file header. */
+extern int             magic;          /* Output file magic. */
+extern int             oldmagic;
+extern int             relocatable_output;
 
 
-/* Address we decide the data section will be loaded at.  */
-int data_start;
-int bss_start;
+/* Size of a page. */
+extern int     page_size;
 
 
-/* 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;
-int cl_refs_allocated;
+extern char    **search_dirs;  /* Directories to search for libraries. */
+extern int     n_search_dirs;  /* Length of above. */
 
 
-/*
- * Actual vector of directories to search; this contains those specified with
- * -L plus the standard ones.
- */
-char   **search_dirs;
+extern int     write_map;      /* write a load map (`-M') */
 
 
-/* Length of the vector `search_dirs'.  */
-int    n_search_dirs;
+extern void    (*fatal_cleanup_hook)__P((void));
 
 
-void   load_symbols __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 *));
-
-void   write_output __P((void));
-void   write_header __P((void));
-void   write_text __P((void));
-void   write_data __P((void));
-void   write_rel __P((void));
-void   write_syms __P((void));
-void   write_symsegs __P((void));
-void   mywrite ();
+void   mywrite __P((void *, int, int, int));
 
 /* In warnings.c: */
 void   perror_name __P((char *));
 
 /* In warnings.c: */
 void   perror_name __P((char *));
@@ -917,10 +678,10 @@ void      swap_longs __P((long *, int));
 void   swap_symbols __P((struct nlist *, int));
 void   swap_zsymbols __P((struct nzlist *, int));
 void   swap_ranlib_hdr __P((struct ranlib *, int));
 void   swap_symbols __P((struct nlist *, int));
 void   swap_zsymbols __P((struct nzlist *, int));
 void   swap_ranlib_hdr __P((struct ranlib *, int));
-void   swap_link_dynamic __P((struct link_dynamic *));
-void   swap_link_dynamic_2 __P((struct link_dynamic_2 *));
-void   swap_ld_debug __P((struct ld_debug *));
-void   swapin_link_object __P((struct link_object *, int));
-void   swapout_link_object __P((struct link_object *, int));
+void   swap__dynamic __P((struct link_dynamic *));
+void   swap_section_dispatch_table __P((struct section_dispatch_table *));
+void   swap_so_debug __P((struct so_debug *));
+void   swapin_sod __P((struct sod *, int));
+void   swapout_sod __P((struct sod *, int));
 void   swapout_fshash __P((struct fshash *, int));
 #endif
 void   swapout_fshash __P((struct fshash *, int));
 #endif
index d27f9b7..f565cf1 100644 (file)
@@ -1,12 +1,12 @@
-#      $Id: Makefile,v 1.4 1993/11/09 20:39:46 paul Exp $
+#      $Id: Makefile,v 1.7 1993/12/10 05:10:22 mycroft Exp $
 
 PROG=  ldconfig
 SRCS=  ldconfig.c shlib.c etc.c
 LDDIR?= $(.CURDIR)/..
 
 PROG=  ldconfig
 SRCS=  ldconfig.c shlib.c etc.c
 LDDIR?= $(.CURDIR)/..
-LDFLAGS += -static
-CFLAGS += -I$(LDDIR) -I$(.CURDIR) -I$(LDDIR)/$(MACHINE) -O
-BINDIR= /sbin
-MAN8 = ldconfig.8
+CFLAGS+=-I$(LDDIR) -I$(.CURDIR) -I$(LDDIR)/$(MACHINE)
+LDSTATIC=-static
+BINDIR=        /sbin
+MAN8 ldconfig.8
 
 .PATH: $(LDDIR) $(LDDIR)/$(MACHINE)
 
 
 .PATH: $(LDDIR) $(LDDIR)/$(MACHINE)
 
index 78439e5..170b618 100644 (file)
@@ -1,6 +1,6 @@
 .Dd October 3, 1993
 .Dt LDCONFIG 8
 .Dd October 3, 1993
 .Dt LDCONFIG 8
-.Os FreeBSD
+.Os FreeBSD 1.1
 .Sh NAME
 .Nm ldconfig
 .Nd configure the shared library cache
 .Sh NAME
 .Nm ldconfig
 .Nd configure the shared library cache
index 899539d..fafe176 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: ldconfig.c,v 1.2 1993/11/09 04:19:22 paul Exp $
+ *     $Id: ldconfig.c,v 1.4 1993/12/02 01:03:16 jkh Exp $
  */
 
 #include <sys/param.h>
  */
 
 #include <sys/param.h>
@@ -72,7 +72,7 @@ struct shlib_list {
 static struct shlib_list       *shlib_head = NULL, **shlib_tail = &shlib_head;
 
 static void    enter __P((char *, char *, char *, int *, int));
 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 *));
+static int     dodir __P((char *, int));
 static int     build_hints __P((void));
 
 int
 static int     build_hints __P((void));
 
 int
@@ -114,10 +114,10 @@ char      *argv[];
                std_search_dirs(NULL);
 
        for (i = 0; i < n_search_dirs; i++)
                std_search_dirs(NULL);
 
        for (i = 0; i < n_search_dirs; i++)
-               rval |= dodir(search_dirs[i]);
+               rval |= dodir(search_dirs[i], 1);
 
        for (i = optind; i < argc; i++)
 
        for (i = optind; i < argc; i++)
-               rval |= dodir(argv[i]);
+               rval |= dodir(argv[i], 0);
 
        rval |= build_hints();
 
 
        rval |= build_hints();
 
@@ -125,8 +125,9 @@ char        *argv[];
 }
 
 int
 }
 
 int
-dodir(dir)
+dodir(dir, silent)
 char   *dir;
 char   *dir;
+int    silent;
 {
        DIR             *dd;
        struct dirent   *dp;
 {
        DIR             *dd;
        struct dirent   *dp;
@@ -134,7 +135,8 @@ char        *dir;
        int             dewey[MAXDEWEY], ndewey;
 
        if ((dd = opendir(dir)) == NULL) {
        int             dewey[MAXDEWEY], ndewey;
 
        if ((dd = opendir(dir)) == NULL) {
-               perror(dir);
+               if (!silent || errno != ENOENT)
+                       perror(dir);
                return -1;
        }
 
                return -1;
        }
 
@@ -314,16 +316,26 @@ build_hints()
                return -1;
        }
 
                return -1;
        }
 
-       mywrite(&hdr, 1, sizeof(struct hints_header), fd);
-       mywrite(blist, hdr.hh_nbucket, sizeof(struct hints_bucket), fd);
-       mywrite(strtab, strtab_sz, 1, fd);
-
+       if (write(fd, &hdr, sizeof(struct hints_header)) !=
+                                               sizeof(struct hints_header)) {
+               perror(_PATH_LD_HINTS);
+               return -1;
+       }
+       if (write(fd, blist, hdr.hh_nbucket * sizeof(struct hints_bucket)) !=
+                               hdr.hh_nbucket * sizeof(struct hints_bucket)) {
+               perror(_PATH_LD_HINTS);
+               return -1;
+       }
+       if (write(fd, strtab, strtab_sz) != strtab_sz) {
+               perror(_PATH_LD_HINTS);
+               return -1;
+       }
        if (close(fd) != 0) {
                perror(_PATH_LD_HINTS);
                return -1;
        }
 
        if (close(fd) != 0) {
                perror(_PATH_LD_HINTS);
                return -1;
        }
 
-       /* Now, install real file */
+       /* Install it */
        if (unlink(_PATH_LD_HINTS) != 0 && errno != ENOENT) {
                perror(_PATH_LD_HINTS);
                return -1;
        if (unlink(_PATH_LD_HINTS) != 0 && errno != ENOENT) {
                perror(_PATH_LD_HINTS);
                return -1;
index 0c3b5e4..f5a6aba 100644 (file)
@@ -1,6 +1,6 @@
 .Dd October 22, 1993
 .Dt LDD 1
 .Dd October 22, 1993
 .Dt LDD 1
-.Os FreeBSD
+.Os FreeBSD 1.1
 .Sh NAME
 .Nm ldd
 .Nd list dynamic object dependencies
 .Sh NAME
 .Nm ldd
 .Nd list dynamic object dependencies
index 65b0bc1..7fba989 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: ldd.c,v 1.3 1993/10/31 14:54:29 pk Exp $
+ *     $Id: ldd.c,v 1.2 1993/11/09 04:19:27 paul Exp $
  */
 
 #include <sys/param.h>
  */
 
 #include <sys/param.h>
@@ -107,6 +107,7 @@ char        *argv[];
                (void)close(fd);
 
                printf("%s:\n", *argv);
                (void)close(fd);
 
                printf("%s:\n", *argv);
+               fflush(stdout);
 
                switch (fork()) {
                case -1:
 
                switch (fork()) {
                case -1:
index eaa0f55..78d337e 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: lib.c,v 1.7 1993/12/11 11:58:27 jkh Exp $      - library routines
+ * $Id: lib.c,v 1.8 1993/12/22 23:28:11 jkh Exp $      - library routines
  */
 
 #include <sys/param.h>
  */
 
 #include <sys/param.h>
 
 #include "ld.h"
 
 
 #include "ld.h"
 
-char          **search_dirs;
-
-/* Length of the vector `search_dirs'.  */
-int             n_search_dirs;
-
-struct file_entry      *decode_library_subfile();
-void                   linear_library(), symdef_library();
+static void            linear_library __P((int, struct file_entry *));
+static void            symdef_library __P((int, struct file_entry *, int));
+static struct file_entry       *decode_library_subfile __P((int,
+                                                       struct file_entry *,
+                                                       int, int *));
 
 /*
  * Search the library ENTRY, already open on descriptor DESC. This means
 
 /*
  * Search the library ENTRY, already open on descriptor DESC. This means
@@ -69,7 +67,7 @@ search_library(desc, entry)
  * We store the length of the member into *LENGTH_LOC.
  */
 
  * We store the length of the member into *LENGTH_LOC.
  */
 
-struct file_entry *
+static struct file_entry *
 decode_library_subfile(desc, library_entry, subfile_offset, length_loc)
        int             desc;
        struct file_entry *library_entry;
 decode_library_subfile(desc, library_entry, subfile_offset, length_loc)
        int             desc;
        struct file_entry *library_entry;
@@ -113,12 +111,10 @@ decode_library_subfile(desc, library_entry, subfile_offset, length_loc)
         * BSD 4.4 extended AR format: #1/<namelen>, with name as the
         * first <namelen> bytes of the file
         */
         * BSD 4.4 extended AR format: #1/<namelen>, with name as the
         * first <namelen> bytes of the file
         */
-       if (            (hdr1.ar_name[0] == '#') &&
-                       (hdr1.ar_name[1] == '1') &&
-                       (hdr1.ar_name[2] == '/') && 
-                       (isdigit(hdr1.ar_name[3]))) {
+       if (strncmp(hdr1.ar_name, AR_EFMT1, sizeof(AR_EFMT1) - 1) == 0 &&
+                       isdigit(hdr1.ar_name[sizeof(AR_EFMT1) - 1])) {
 
 
-               namelen = atoi(&hdr1.ar_name[3]);
+               namelen = atoi(&hdr1.ar_name[sizeof(AR_EFMT1) - 1]);
                name = (char *)xmalloc(namelen + 1);
                if (read(desc, name, namelen) != namelen)
                        fatal_with_file(
                name = (char *)xmalloc(namelen + 1);
                if (read(desc, name, namelen) != namelen)
                        fatal_with_file(
@@ -143,10 +139,8 @@ decode_library_subfile(desc, library_entry, subfile_offset, length_loc)
        subentry->subfiles = 0;
        subentry->starting_offset = starting_offset;
        subentry->superfile = library_entry;
        subentry->subfiles = 0;
        subentry->starting_offset = starting_offset;
        subentry->superfile = library_entry;
-       subentry->library_flag = 0;
-       subentry->header_read_flag = 0;
-       subentry->just_syms_flag = 0;
        subentry->chain = 0;
        subentry->chain = 0;
+       subentry->flags = 0;
        subentry->total_size = content_length;
 
        (*length_loc) = member_length;
        subentry->total_size = content_length;
 
        (*length_loc) = member_length;
@@ -154,7 +148,7 @@ decode_library_subfile(desc, library_entry, subfile_offset, length_loc)
        return subentry;
 }
 
        return subentry;
 }
 
-int             subfile_wanted_p();
+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. DESC is a descriptor on
@@ -163,7 +157,7 @@ int             subfile_wanted_p();
  * length of the __.SYMDEF data.
  */
 
  * length of the __.SYMDEF data.
  */
 
-void
+static void
 symdef_library(desc, entry, member_length)
        int             desc;
        struct file_entry *entry;
 symdef_library(desc, entry, member_length)
        int             desc;
        struct file_entry *entry;
@@ -172,7 +166,7 @@ symdef_library(desc, entry, member_length)
        int            *symdef_data = (int *) xmalloc(member_length);
        register struct ranlib *symdef_base;
        char           *sym_name_base;
        int            *symdef_data = (int *) xmalloc(member_length);
        register struct ranlib *symdef_base;
        char           *sym_name_base;
-       int             number_of_symdefs;
+       int             nsymdefs;
        int             length_of_strings;
        int             not_finished;
        int             bytes_read;
        int             length_of_strings;
        int             not_finished;
        int             bytes_read;
@@ -184,24 +178,24 @@ symdef_library(desc, entry, member_length)
        if (bytes_read != member_length)
                fatal_with_file("malformatted __.SYMDEF in ", entry);
 
        if (bytes_read != member_length)
                fatal_with_file("malformatted __.SYMDEF in ", entry);
 
-       number_of_symdefs = md_swap_long(*symdef_data) / sizeof(struct ranlib);
-       if (number_of_symdefs < 0 ||
-           number_of_symdefs * 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);
 
        symdef_base = (struct ranlib *) (symdef_data + 1);
                fatal_with_file("malformatted __.SYMDEF in ", entry);
 
        symdef_base = (struct ranlib *) (symdef_data + 1);
-       length_of_strings = md_swap_long(*(int *) (symdef_base + number_of_symdefs));
+       length_of_strings = md_swap_long(*(int *) (symdef_base + nsymdefs));
 
        if (length_of_strings < 0
 
        if (length_of_strings < 0
-           || number_of_symdefs * sizeof(struct ranlib) + length_of_strings
+           || nsymdefs * sizeof(struct ranlib) + length_of_strings
            + 2 * sizeof(int) > member_length)
                fatal_with_file("malformatted __.SYMDEF in ", entry);
 
            + 2 * sizeof(int) > member_length)
                fatal_with_file("malformatted __.SYMDEF in ", entry);
 
-       sym_name_base = sizeof(int) + (char *) (symdef_base + number_of_symdefs);
+       sym_name_base = sizeof(int) + (char *) (symdef_base + nsymdefs);
 
        /* Check all the string indexes for validity.  */
 
        /* Check all the string indexes for validity.  */
-       md_swapin_ranlib_hdr(symdef_base, number_of_symdefs);
-       for (i = 0; i < number_of_symdefs; i++) {
+       md_swapin_ranlib_hdr(symdef_base, nsymdefs);
+       for (i = 0; i < nsymdefs; i++) {
                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)))
@@ -224,7 +218,7 @@ symdef_library(desc, entry, member_length)
                 * symbols.
                 */
 
                 * symbols.
                 */
 
-               for (i = 0; (i < number_of_symdefs &&
+               for (i = 0; (i < nsymdefs &&
                                        ((link_mode & FORCEARCHIVE) ||
                                        undefined_global_sym_count ||
                                        common_defined_global_count)); i++) {
                                        ((link_mode & FORCEARCHIVE) ||
                                        undefined_global_sym_count ||
                                        common_defined_global_count)); i++) {
@@ -256,8 +250,9 @@ symdef_library(desc, entry, member_length)
                         * global common 'utime' linked to a function).
                         */
                        if (!(link_mode & FORCEARCHIVE) &&
                         * global common 'utime' linked to a function).
                         */
                        if (!(link_mode & FORCEARCHIVE) &&
-                                       (!sp || sp->defined ||
-                                       (!sp->referenced && !sp->sorefs)) )
+                               (!sp || sp->defined ||
+                                       (!(sp->flags & GS_REFERENCED) &&
+                                               !sp->sorefs)))
                                continue;
 
                        /*
                                continue;
 
                        /*
@@ -277,10 +272,11 @@ symdef_library(desc, entry, member_length)
                                                      entry, offset, &junk);
                        if (subentry == 0)
                                fatal(
                                                      entry, offset, &junk);
                        if (subentry == 0)
                                fatal(
-                                     "invalid offset for %s in symbol table of %s",
+                               "invalid offset for %s in symbol table of %s",
                                      sym_name_base
                                              + symdef_base[i].ran_un.ran_strx,
                                      entry->filename);
                                      sym_name_base
                                              + symdef_base[i].ran_un.ran_strx,
                                      entry->filename);
+
                        read_entry_symbols(desc, subentry);
                        subentry->strings = (char *)
                                malloc(subentry->string_size);
                        read_entry_symbols(desc, subentry);
                        subentry->strings = (char *)
                                malloc(subentry->string_size);
@@ -320,7 +316,7 @@ symdef_library(desc, entry, member_length)
                                 * waste time on them.
                                 */
 
                                 * waste time on them.
                                 */
 
-                               for (j = 0; j < number_of_symdefs; j++) {
+                               for (j = 0; j < nsymdefs; j++) {
                                        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;
                                }
@@ -343,7 +339,7 @@ symdef_library(desc, entry, member_length)
  * DESC is the descriptor it is open on.
  */
 
  * DESC is the descriptor it is open on.
  */
 
-void
+static void
 linear_library(desc, entry)
        int             desc;
        struct file_entry *entry;
 linear_library(desc, entry)
        int             desc;
        struct file_entry *entry;
@@ -354,11 +350,11 @@ linear_library(desc, entry)
        while ((link_mode & FORCEARCHIVE) ||
                undefined_global_sym_count || common_defined_global_count) {
 
        while ((link_mode & FORCEARCHIVE) ||
                undefined_global_sym_count || common_defined_global_count) {
 
-               int             member_length;
-               register struct file_entry *subentry;
+               int                             member_length;
+               register struct file_entry      *subentry;
 
 
-               subentry = decode_library_subfile(desc, entry, this_subfile_offset,
-                                                 &member_length);
+               subentry = decode_library_subfile(desc, entry,
+                                       this_subfile_offset, &member_length);
 
                if (!subentry)
                        return;
 
                if (!subentry)
                        return;
@@ -395,7 +391,7 @@ linear_library(desc, entry)
  * core, but not entered. Return nonzero if we ought to load this member.
  */
 
  * core, but not entered. Return nonzero if we ought to load this member.
  */
 
-int
+static int
 subfile_wanted_p(entry)
        struct file_entry *entry;
 {
 subfile_wanted_p(entry)
        struct file_entry *entry;
 {
@@ -408,9 +404,9 @@ subfile_wanted_p(entry)
 
        for (lsp = entry->symbols; lsp < lspend; lsp++) {
                register struct nlist *p = &lsp->nzlist.nlist;
 
        for (lsp = entry->symbols; lsp < lspend; lsp++) {
                register struct nlist *p = &lsp->nzlist.nlist;
-               register int    type = p->n_type;
-               register char  *name = p->n_un.n_strx + entry->strings;
-               register symbol *sp = getsym_soft(name);
+               register int    type = p->n_type;
+               register char   *name = p->n_un.n_strx + entry->strings;
+               register symbol *sp = getsym_soft(name);
 
                /*
                 * If the symbol has an interesting definition, we could
 
                /*
                 * If the symbol has an interesting definition, we could
@@ -437,7 +433,7 @@ subfile_wanted_p(entry)
                        dollar_cond = 1;
                        if (!sp)
                                continue;
                        dollar_cond = 1;
                        if (!sp)
                                continue;
-                       if (sp->referenced) {
+                       if (sp->flags & SP_REFERENCED) {
                                if (write_map) {
                                        print_file_name(entry, stdout);
                                        fprintf(stdout, " needed due to $-conditional %s\n", name);
                                if (write_map) {
                                        print_file_name(entry, stdout);
                                        fprintf(stdout, " needed due to $-conditional %s\n", name);
@@ -461,7 +457,7 @@ subfile_wanted_p(entry)
                 * common reference (see explanation above in
                 * symdef_library()).
                 */
                 * common reference (see explanation above in
                 * symdef_library()).
                 */
-               if (sp->referenced && !sp->defined) {
+               if ((sp->flags & GS_REFERENCED) && !sp->defined) {
                        /*
                         * This is a symbol we are looking for.  It
                         * is either not yet defined or defined as a
                        /*
                         * This is a symbol we are looking for.  It
                         * is either not yet defined or defined as a
@@ -482,11 +478,11 @@ subfile_wanted_p(entry)
                                 * If it didn't used to be common, up
                                 * the count of common symbols.
                                 */
                                 * If it didn't used to be common, up
                                 * the count of common symbols.
                                 */
-                               if (!sp->max_common_size)
+                               if (!sp->common_size)
                                        common_defined_global_count++;
 
                                        common_defined_global_count++;
 
-                               if (sp->max_common_size < p->n_value)
-                                       sp->max_common_size = p->n_value;
+                               if (sp->common_size < p->n_value)
+                                       sp->common_size = p->n_value;
                                if (!sp->defined)
                                        undefined_global_sym_count--;
                                sp->defined = type;
                                if (!sp->defined)
                                        undefined_global_sym_count--;
                                sp->defined = type;
@@ -498,22 +494,59 @@ subfile_wanted_p(entry)
                        }
                        return 1;
                } else {
                        }
                        return 1;
                } else {
+                       /*
+                        * Check for undefined symbols or commons
+                        * in shared objects.
+                        */
                        struct localsymbol *lsp;
                        struct localsymbol *lsp;
-                       int             defs = 0;
+                       int wascommon = sp->defined && sp->common_size;
+                       int iscommon = type == (N_UNDF|N_EXT) && p->n_value;
+
+                       if (wascommon) {
+                               /*
+                                * sp was defined as common by shared object.
+                                */
+                               if (iscommon && p->n_value < sp->common_size)
+                                       sp->common_size = p->n_value;
+                               continue;
+                       }
 
 
-                       /* Check for undefined symbols in shared objects */
                        if (sp->sorefs == NULL)
                                continue;
 
                        for (lsp = sp->sorefs; lsp; lsp = lsp->next) {
                        if (sp->sorefs == NULL)
                                continue;
 
                        for (lsp = sp->sorefs; lsp; lsp = lsp->next) {
-                               type = lsp->nzlist.nlist.n_type;
+                               int type = lsp->nzlist.nlist.n_type;
                                if (    (type & N_EXT) &&
                                        (type & N_STAB) == 0 &&
                                        type != (N_UNDF | N_EXT))
                                if (    (type & N_EXT) &&
                                        (type & N_STAB) == 0 &&
                                        type != (N_UNDF | N_EXT))
-                                       break; /* We need it */
+                                       break; /* We don't need it */
+                       }
+                       if (lsp != NULL) {
+                               /* There's a real definition */
+                               if (iscommon)
+                                       /*
+                                        * But this member wants it to be
+                                        * a common; ignore it.
+                                       continue;
+                       }
+
+                       if (iscommon) {
+                               /*
+                                * New symbol is common, just takes its
+                                * size, but don't load.
+                                */
+                               sp->common_size = p->n_value;
+                               sp->defined = type;
+                               continue;
                        }
                        }
-                       if (lsp != NULL)
-                               continue; /* We don't need it */
+
+                       /*
+                        * THIS STILL MISSES the case where one shared
+                        * object defines a common and the next defines
+                        * more strongly; fix this someday by making
+                        * `struct glosym' and enter_global_ref() more
+                        * symmetric.
+                        */
 
                        if (write_map) {
                                print_file_name(entry, stdout);
 
                        if (write_map) {
                                print_file_name(entry, stdout);
@@ -535,13 +568,13 @@ read_shared_object (desc, entry)
      struct file_entry *entry;
      int desc;
 {
      struct file_entry *entry;
      int desc;
 {
-       struct link_dynamic     dyn;
-       struct link_dynamic_2   dyn2;
-       struct nlist            *np;
-       struct nzlist           *nzp;
-       int                     n, i, has_nz = 0;
+       struct _dynamic                 dyn;
+       struct section_dispatch_table   sdt;
+       struct nlist                    *np;
+       struct nzlist                   *nzp;
+       int                             n, i, has_nz = 0;
 
 
-       if (!entry->header_read_flag)
+       if (!(entry->flags & E_HEADER_VALID))
                read_header (desc, entry);
 
        /* Read DYNAMIC structure (first in data segment) */
                read_header (desc, entry);
 
        /* Read DYNAMIC structure (first in data segment) */
@@ -552,10 +585,10 @@ read_shared_object (desc, entry)
                fatal_with_file (
                        "premature eof in data segment of ", entry);
        }
                fatal_with_file (
                        "premature eof in data segment of ", entry);
        }
-       md_swapin_link_dynamic(&dyn);
+       md_swapin__dynamic(&dyn);
 
        /* Check version */
 
        /* Check version */
-       switch (dyn.ld_version) {
+       switch (dyn.d_version) {
        default:
                fatal_with_file( "unsupported _DYNAMIC version ", entry);
                break;
        default:
                fatal_with_file( "unsupported _DYNAMIC version ", entry);
                break;
@@ -566,26 +599,29 @@ read_shared_object (desc, entry)
                break;
        }
 
                break;
        }
 
-       /* Read link_dynamic_2 struct (from data segment) */
+       /* Read Section Dispatch Table (from data segment) */
        lseek (desc,
        lseek (desc,
-               text_offset(entry) + dyn.ld_un.ld_2,
+               text_offset(entry) + (long)dyn.d_un.d_sdt -
+                       (DATA_START(entry->header) - N_DATOFF(entry->header)),
                L_SET);
                L_SET);
-       if (read(desc, &dyn2, sizeof dyn2) != sizeof dyn2) {
+       if (read(desc, &sdt, sizeof sdt) != sizeof sdt) {
                fatal_with_file( "premature eof in data segment of ", entry);
        }
                fatal_with_file( "premature eof in data segment of ", entry);
        }
-       md_swapin_link_dynamic_2(&dyn2);
+       md_swapin_section_dispatch_table(&sdt);
 
        /* Read symbols (text segment) */
 
        /* Read symbols (text segment) */
-       n = dyn2.ld_strings - dyn2.ld_symbols;
+       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));
        entry->symbols = (struct localsymbol *)
                        xmalloc(entry->nsymbols * sizeof(struct localsymbol));
        entry->nsymbols = n /
                (has_nz ? sizeof(struct nzlist) : sizeof(struct nlist));
        nzp = (struct nzlist *)(np = (struct nlist *) alloca (n));
        entry->symbols = (struct localsymbol *)
                        xmalloc(entry->nsymbols * sizeof(struct localsymbol));
-       lseek(desc, text_offset (entry) + dyn2.ld_symbols, L_SET);
+       lseek(desc, text_offset(entry) + (long)sdt.sdt_nzlist -
+                       (TEXT_START(entry->header) - N_TXTOFF(entry->header)),
+               L_SET);
        if (read(desc, (char *)nzp, n) != n) {
                fatal_with_file(
        if (read(desc, (char *)nzp, n) != n) {
                fatal_with_file(
-                       "premature eof while reading dyn syms ", entry);
+                       "premature eof while reading object symbols ", entry);
        }
        if (has_nz)
                md_swapin_zsymbols(nzp, entry->nsymbols);
        }
        if (has_nz)
                md_swapin_zsymbols(nzp, entry->nsymbols);
@@ -602,21 +638,21 @@ read_shared_object (desc, entry)
                }
                entry->symbols[i].symbol = NULL;
                entry->symbols[i].next = NULL;
                }
                entry->symbols[i].symbol = NULL;
                entry->symbols[i].next = NULL;
+               entry->symbols[i].entry = entry;
                entry->symbols[i].gotslot_offset = -1;
                entry->symbols[i].gotslot_offset = -1;
-               entry->symbols[i].gotslot_claimed = 0;
-               entry->symbols[i].write = 0;
-               entry->symbols[i].is_L_symbol = 0;
-               entry->symbols[i].rename = 0;
+               entry->symbols[i].flags = 0;
        }
 
        /* Read strings (text segment) */
        }
 
        /* Read strings (text segment) */
-       n = entry->string_size = dyn2.ld_str_sz;
+       n = entry->string_size = sdt.sdt_str_sz;
        entry->strings = (char *) alloca(n);
        entry->strings = (char *) alloca(n);
-       entry->strings_offset = text_offset (entry) + dyn2.ld_strings;
-       lseek(desc, entry->strings_offset, L_SET);
+       entry->strings_offset = text_offset(entry) + sdt.sdt_strings;
+       lseek(desc, entry->strings_offset -
+                       (TEXT_START(entry->header) - N_TXTOFF(entry->header)),
+               L_SET);
        if (read(desc, entry->strings, n) != n) {
                fatal_with_file(
        if (read(desc, entry->strings, n) != n) {
                fatal_with_file(
-                       "premature eof while reading dyn strings ", entry);
+                       "premature eof while reading object strings ", entry);
        }
        enter_file_symbols (entry);
        entry->strings = 0;
        }
        enter_file_symbols (entry);
        entry->strings = 0;
@@ -624,39 +660,43 @@ read_shared_object (desc, entry)
        /*
         * Load any subsidiary shared objects.
         */
        /*
         * Load any subsidiary shared objects.
         */
-       if (dyn2.ld_need) {
-               struct link_object      lobj;
+       if (sdt.sdt_sods) {
+               struct sod              sod;
                off_t                   offset;
                off_t                   offset;
-               struct file_entry       *subentry, *prev = NULL;
+               struct file_entry       *prev = NULL;
 
 
-               subentry = (struct file_entry *)
-                               xmalloc(sizeof(struct file_entry));
-               bzero(subentry, sizeof(struct file_entry));
-
-               subentry->superfile = entry;
-
-               offset = (off_t)dyn2.ld_need;
+               offset = (off_t)sdt.sdt_sods;
                while (1) {
                while (1) {
+                       struct file_entry *subentry;
                        char *libname, name[MAXPATHLEN]; /*XXX*/
 
                        char *libname, name[MAXPATHLEN]; /*XXX*/
 
-                       lseek(desc, offset, L_SET);
-                       if (read(desc, &lobj, sizeof(lobj)) != sizeof(lobj)) {
+                       subentry = (struct file_entry *)
+                               xmalloc(sizeof(struct file_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(
                                fatal_with_file(
-                               "premature eof while reading link objects ",
+                               "premature eof while reading sod ",
                                                entry);
                        }
                                                entry);
                        }
-                       md_swapin_link_object(&lobj, 1);
-                       (void)lseek(desc, (off_t)lobj.lo_name, L_SET);
+                       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*/
                        (void)read(desc, name, sizeof(name)); /*XXX*/
-                       if (lobj.lo_library) {
-                               int lo_major = lobj.lo_major;
-                               int lo_minor = lobj.lo_minor;
+                       if (sod.sod_library) {
+                               int sod_major = sod.sod_major;
+                               int sod_minor = sod.sod_minor;
 
                                libname = findshlib(name,
 
                                libname = findshlib(name,
-                                               &lo_major, &lo_minor, 0);
+                                               &sod_major, &sod_minor, 0);
                                if (libname == NULL)
                                        fatal("no shared -l%s.%d.%d available",
                                if (libname == NULL)
                                        fatal("no shared -l%s.%d.%d available",
-                                       name, lobj.lo_major, lobj.lo_minor);
+                                       name, sod.sod_major, sod.sod_minor);
                                subentry->filename = libname;
                                subentry->local_sym_name = concat("-l", name, "");
                        } else {
                                subentry->filename = libname;
                                subentry->local_sym_name = concat("-l", name, "");
                        } else {
@@ -671,7 +711,7 @@ read_shared_object (desc, entry)
                                entry->subfiles = subentry;
                        prev = subentry;
                        desc = file_open(entry);
                                entry->subfiles = subentry;
                        prev = subentry;
                        desc = file_open(entry);
-                       if ((offset = (off_t)lobj.lo_next) == 0)
+                       if ((offset = (off_t)sod.sod_next) == 0)
                                break;
                }
        }
                                break;
                }
        }
@@ -719,7 +759,7 @@ read_shared_object (desc, entry)
                subentry->superfile = entry;
                subentry->filename = sa_name;
                subentry->local_sym_name = sa_name;
                subentry->superfile = entry;
                subentry->filename = sa_name;
                subentry->local_sym_name = sa_name;
-               subentry->library_flag = 1;
+               subentry->flags |= E_IS_LIBRARY;
                search_library(file_open(subentry), subentry);
 out:
                ;
                search_library(file_open(subentry), subentry);
 out:
                ;
@@ -740,7 +780,7 @@ struct file_entry   *p;
        int             major = -1, minor = -1;
        char            *cp, *fname = NULL;
 
        int             major = -1, minor = -1;
        char            *cp, *fname = NULL;
 
-       if (p->search_dynamic_flag == 0)
+       if (!(p->flags & E_SEARCH_DYNAMIC))
                goto dot_a;
 
        fname = findshlib(p->filename, &major, &minor, 1);
                goto dot_a;
 
        fname = findshlib(p->filename, &major, &minor, 1);
@@ -749,13 +789,13 @@ struct file_entry *p;
                p->filename = fname;
                p->lib_major = major;
                p->lib_minor = minor;
                p->filename = fname;
                p->lib_major = major;
                p->lib_minor = minor;
-               p->search_dirs_flag = 0;
+               p->flags &= ~E_SEARCH_DIRS;
                return desc;
        }
        free (fname);
 
 dot_a:
                return desc;
        }
        free (fname);
 
 dot_a:
-       p->search_dynamic_flag = 0;
+       p->flags &= ~E_SEARCH_DYNAMIC;
        if (cp = strrchr(p->filename, '/')) {
                *cp++ = '\0';
                fname = concat(concat(p->filename, "/lib", cp), ".a", "");
        if (cp = strrchr(p->filename, '/')) {
                *cp++ = '\0';
                fname = concat(concat(p->filename, "/lib", cp), ".a", "");
@@ -769,7 +809,7 @@ dot_a:
                desc = open (string, O_RDONLY, 0);
                if (desc > 0) {
                        p->filename = string;
                desc = open (string, O_RDONLY, 0);
                if (desc > 0) {
                        p->filename = string;
-                       p->search_dirs_flag = 0;
+                       p->flags &= ~E_SEARCH_DIRS;
                        break;
                }
                free (string);
                        break;
                }
                free (string);
index 6de17b9..6c042d9 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: rrs.c,v 1.9 1993/12/04 00:53:00 jkh Exp $
+ *     $Id: rrs.c,v 1.10 1993/12/11 11:58:28 jkh Exp $
  */
 
 #include <sys/param.h>
  */
 
 #include <sys/param.h>
@@ -48,9 +48,9 @@
 
 #include "ld.h"
 
 
 #include "ld.h"
 
-static struct link_dynamic     rrs_dyn;                /* defined in link.h */
-static struct ld_debug         rrs_ld_debug;           /* defined in link.h */
-static struct link_dynamic_2   rrs_dyn2;               /* defined in link.h */
+static struct _dynamic         rrs_dyn;                /* defined in link.h */
+static struct so_debug         rrs_so_debug;           /* defined in link.h */
+static struct section_dispatch_table   rrs_sdt;        /* defined in link.h */
 static got_t                   *rrs_got;
 static jmpslot_t               *rrs_plt;               /* defined in md.h */
 static struct relocation_info  *rrs_reloc;
 static got_t                   *rrs_got;
 static jmpslot_t               *rrs_plt;               /* defined in md.h */
 static struct relocation_info  *rrs_reloc;
@@ -73,7 +73,7 @@ static int    current_jmpslot_offset;
 static int     current_got_offset;
 static int     current_reloc_offset;
 static int     current_hash_index;
 static int     current_got_offset;
 static int     current_reloc_offset;
 static int     current_hash_index;
-static int     number_of_shobjs;
+int            number_of_shobjs;
 
 struct shobj {
        struct shobj            *next;
 
 struct shobj {
        struct shobj            *next;
@@ -82,29 +82,29 @@ struct shobj {
 
 /*
 RRS text segment:
 
 /*
 RRS text segment:
-               +-------------------+  <-- ld_rel (rrs_text_start)
+               +-------------------+  <-- sdt_rel (rrs_text_start)
                |                   |
                |    relocation     |
                |                   |
                |                   |
                |    relocation     |
                |                   |
-               +-------------------+  <-- <link_dynamic_2>.ld_hash
+               +-------------------+  <-- <sdt>.sdt_hash
                |                   |
                |    hash buckets   |
                |                   |
                |                   |
                |    hash buckets   |
                |                   |
-               +-------------------+  <-- <link_dynamic_2>.ld_stab
+               +-------------------+  <-- <sdt>.sdt_nzlist
                |                   |
                |     symbols       |
                |                   |
                |                   |
                |     symbols       |
                |                   |
-               +-------------------+  <-- <link_dynamic_2>.ld_strings
+               +-------------------+  <-- <sdt>.sdt_strings
                |                   |
                |     strings       |
                |                   |
                |                   |
                |     strings       |
                |                   |
-               +-------------------+  <-- <link_dynamic_2>.ld_need
+               +-------------------+  <-- <sdt>.sdt_sods
                |                   |
                |     shobjs        |
                |                   |
                +-------------------+
                |                   |
                |                   |
                |     shobjs        |
                |                   |
                +-------------------+
                |                   |
-               |  shobjs strings   |  <-- <shobj>.lo_name
+               |  shobjs strings   |  <-- <shobj>.sod_name
                |                   |
                +-------------------+
 
                |                   |
                +-------------------+
 
@@ -113,21 +113,21 @@ RRS data segment:
 
                +-------------------+  <-- __DYNAMIC (rrs_data_start)
                |                   |
 
                +-------------------+  <-- __DYNAMIC (rrs_data_start)
                |                   |
-               |   link_dymamic    |
+               |     _dymamic      |
                |                   |
                |                   |
-               +-------------------+  <-- __DYNAMIC.ldd
+               +-------------------+  <-- __DYNAMIC.d_debug
                |                   |
                |                   |
-               |   ld_debug        |
+               |    so_debug       |
                |                   |
                |                   |
-               +-------------------+  <-- __DYNAMIC.ld_un.ld_2
+               +-------------------+  <-- __DYNAMIC.d_un.d_sdt
                |                   |
                |                   |
-               |   link_dymamic_2  |
+               |       sdt         |
                |                   |
                |                   |
-               +-------------------+  <-- _GLOBAL_OFFSET_TABLE_ (ld_got)
+               +-------------------+  <-- _GLOBAL_OFFSET_TABLE_ (sdt_got)
                |                   |
                |      _GOT_        |
                |                   |
                |                   |
                |      _GOT_        |
                |                   |
-               +-------------------+  <-- ld_plt
+               +-------------------+  <-- sdt_plt
                |                   |
                |       PLT         |
                |                   |
                |                   |
                |       PLT         |
                |                   |
@@ -280,12 +280,12 @@ alloc_rrs_cpy_reloc(entry, sp)
 struct file_entry      *entry;
 symbol *sp;
 {
 struct file_entry      *entry;
 symbol *sp;
 {
-       if (sp->cpyreloc_reserved)
+       if (sp->flags & GS_CPYRELOCRESERVED)
                return;
 #ifdef DEBUG
 printf("alloc_rrs_copy: %s in %s\n", sp->name, get_file_name(entry));
 #endif
                return;
 #ifdef DEBUG
 printf("alloc_rrs_copy: %s in %s\n", sp->name, get_file_name(entry));
 #endif
-       sp->cpyreloc_reserved = 1;
+       sp->flags |= GS_CPYRELOCRESERVED;
        reserved_rrs_relocs++;
 }
 
        reserved_rrs_relocs++;
 }
 
@@ -318,11 +318,11 @@ long      *relocation;
 {
        struct relocation_info  *r = rrs_next_reloc();
 
 {
        struct relocation_info  *r = rrs_next_reloc();
 
-#ifdef DEBUG
        if (rp->r_address < text_start + text_size)
                error("%s: RRS text relocation at %#x for \"%s\"",
                        get_file_name(entry), rp->r_address, sp->name);
 
        if (rp->r_address < text_start + text_size)
                error("%s: RRS text relocation at %#x for \"%s\"",
                        get_file_name(entry), rp->r_address, sp->name);
 
+#ifdef DEBUG
 printf("claim_rrs_reloc: %s in %s\n", sp->name, get_file_name(entry));
 #endif
        r->r_address = rp->r_address;
 printf("claim_rrs_reloc: %s in %s\n", sp->name, get_file_name(entry));
 #endif
        r->r_address = rp->r_address;
@@ -354,8 +354,8 @@ long                        addend;
 {
        struct relocation_info *r;
 
 {
        struct relocation_info *r;
 
-       if (sp->jmpslot_claimed)
-               return rrs_dyn2.ld_plt + sp->jmpslot_offset;
+       if (sp->flags & GS_JMPSLOTCLAIMED)
+               return rrs_sdt.sdt_plt + sp->jmpslot_offset;
 
 #ifdef DEBUG
 printf("claim_rrs_jmpslot: %s: %s(%d) -> offset %x (textreloc %#x)\n",
 
 #ifdef DEBUG
 printf("claim_rrs_jmpslot: %s: %s(%d) -> offset %x (textreloc %#x)\n",
@@ -375,30 +375,30 @@ printf("claim_rrs_jmpslot: %s: %s(%d) -> offset %x (textreloc %#x)\n",
                                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),
-                               rrs_dyn2.ld_plt + sp->jmpslot_offset,
+                               rrs_sdt.sdt_plt + sp->jmpslot_offset,
                                sp->value);
                if (!JMPSLOT_NEEDS_RELOC) {
                                sp->value);
                if (!JMPSLOT_NEEDS_RELOC) {
-                       return rrs_dyn2.ld_plt + sp->jmpslot_offset;
+                       return rrs_sdt.sdt_plt + sp->jmpslot_offset;
                }
        } else {
                }
        } else {
-               md_make_jmpslot( rrs_plt + sp->jmpslot_offset/sizeof(jmpslot_t),
+               md_make_jmpslot(rrs_plt + sp->jmpslot_offset/sizeof(jmpslot_t),
                                sp->jmpslot_offset,
                                claimed_rrs_relocs);
        }
 
        if (rrs_section_type == RRS_PARTIAL)
                /* PLT is self-contained */
                                sp->jmpslot_offset,
                                claimed_rrs_relocs);
        }
 
        if (rrs_section_type == RRS_PARTIAL)
                /* PLT is self-contained */
-               return rrs_dyn2.ld_plt + sp->jmpslot_offset;
+               return rrs_sdt.sdt_plt + sp->jmpslot_offset;
 
        /*
         * Install a run-time relocation for this PLT entry.
         */
        r = rrs_next_reloc();
 
        /*
         * Install a run-time relocation for this PLT entry.
         */
        r = rrs_next_reloc();
-       sp->jmpslot_claimed = 1;
+       sp->flags |= GS_JMPSLOTCLAIMED;
 
        RELOC_SYMBOL(r) = sp->rrs_symbolnum;
 
 
        RELOC_SYMBOL(r) = sp->rrs_symbolnum;
 
-       r->r_address = (long)rrs_dyn2.ld_plt + sp->jmpslot_offset;
+       r->r_address = (long)rrs_sdt.sdt_plt + sp->jmpslot_offset;
 
        if (link_mode & SYMBOLIC) {
                RELOC_EXTERN_P(r) = 0;
 
        if (link_mode & SYMBOLIC) {
                RELOC_EXTERN_P(r) = 0;
@@ -408,7 +408,7 @@ printf("claim_rrs_jmpslot: %s: %s(%d) -> offset %x (textreloc %#x)\n",
                md_make_jmpreloc(rp, r, 0);
        }
 
                md_make_jmpreloc(rp, r, 0);
        }
 
-       return rrs_dyn2.ld_plt + sp->jmpslot_offset;
+       return rrs_sdt.sdt_plt + sp->jmpslot_offset;
 }
 
 /*
 }
 
 /*
@@ -443,7 +443,7 @@ printf("claim_rrs_gotslot: %s(%d) slot offset %#x, addend %#x\n",
                "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);
 
-       if (sp->gotslot_claimed)
+       if (sp->flags & GS_GOTSLOTCLAIMED)
                /* This symbol already passed here before. */
                return sp->gotslot_offset;
 
                /* This symbol already passed here before. */
                return sp->gotslot_offset;
 
@@ -497,8 +497,8 @@ printf("claim_rrs_gotslot: %s(%d) slot offset %#x, addend %#x\n",
         * as no symbol need be looked up at run-time.
         */
        r = rrs_next_reloc();
         * as no symbol need be looked up at run-time.
         */
        r = rrs_next_reloc();
-       sp->gotslot_claimed = 1;
-       r->r_address = rrs_dyn2.ld_got + sp->gotslot_offset;
+       sp->flags |= GS_GOTSLOTCLAIMED;
+       r->r_address = rrs_sdt.sdt_got + sp->gotslot_offset;
        RELOC_SYMBOL(r) = sp->rrs_symbolnum;
        RELOC_EXTERN_P(r) = !(reloc_type == RELTYPE_RELATIVE);
        md_make_gotreloc(rp, r, reloc_type);
        RELOC_SYMBOL(r) = sp->rrs_symbolnum;
        RELOC_EXTERN_P(r) = !(reloc_type == RELTYPE_RELATIVE);
        md_make_gotreloc(rp, r, reloc_type);
@@ -524,7 +524,7 @@ long                        addend;
        addend += lsp->nzlist.nz_value;
 
        if (!RELOC_STATICS_THROUGH_GOT_P(r))
        addend += lsp->nzlist.nz_value;
 
        if (!RELOC_STATICS_THROUGH_GOT_P(r))
-               return addend - rrs_dyn2.ld_got;
+               return addend - rrs_sdt.sdt_got;
 
 #ifdef DEBUG
 printf("claim_rrs_internal_gotslot: %s: slot offset %#x, addend = %#x\n",
 
 #ifdef DEBUG
 printf("claim_rrs_internal_gotslot: %s: slot offset %#x, addend = %#x\n",
@@ -536,7 +536,7 @@ printf("claim_rrs_internal_gotslot: %s: slot offset %#x, addend = %#x\n",
                "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));
 
-       if (lsp->gotslot_claimed)
+       if (lsp->flags & LS_GOTSLOTCLAIMED)
                /* Already done */
                return lsp->gotslot_offset;
 
                /* Already done */
                return lsp->gotslot_offset;
 
@@ -549,8 +549,8 @@ printf("claim_rrs_internal_gotslot: %s: slot offset %#x, addend = %#x\n",
         * Relocation entry needed for this static GOT entry.
         */
        r = rrs_next_reloc();
         * Relocation entry needed for this static GOT entry.
         */
        r = rrs_next_reloc();
-       lsp->gotslot_claimed = 1;
-       r->r_address = rrs_dyn2.ld_got + lsp->gotslot_offset;
+       lsp->flags |= LS_GOTSLOTCLAIMED;
+       r->r_address = rrs_sdt.sdt_got + lsp->gotslot_offset;
        RELOC_EXTERN_P(r) = 0;
        md_make_gotreloc(rp, r, RELTYPE_RELATIVE);
        return lsp->gotslot_offset;
        RELOC_EXTERN_P(r) = 0;
        md_make_gotreloc(rp, r, RELTYPE_RELATIVE);
        return lsp->gotslot_offset;
@@ -564,10 +564,10 @@ symbol *sp;
 {
        struct relocation_info  *r;
 
 {
        struct relocation_info  *r;
 
-       if (sp->cpyreloc_claimed)
+       if (sp->flags & GS_CPYRELOCCLAIMED)
                return;
 
                return;
 
-       if (!sp->cpyreloc_reserved)
+       if (!(sp->flags & GS_CPYRELOCRESERVED))
                fatal("internal error: %s: claim_cpy_reloc: %s: no reservation\n",
                        get_file_name(entry), sp->name);
 
                fatal("internal error: %s: claim_cpy_reloc: %s: no reservation\n",
                        get_file_name(entry), sp->name);
 
@@ -577,7 +577,7 @@ printf("claim_rrs_copy: %s: %s -> %x\n",
 #endif
 
        r = rrs_next_reloc();
 #endif
 
        r = rrs_next_reloc();
-       sp->cpyreloc_claimed = 1;
+       sp->flags |= GS_CPYRELOCCLAIMED;
        r->r_address = rp->r_address;
        RELOC_SYMBOL(r) = sp->rrs_symbolnum;
        RELOC_EXTERN_P(r) = RELOC_EXTERN_P(rp);
        r->r_address = rp->r_address;
        RELOC_SYMBOL(r) = sp->rrs_symbolnum;
        RELOC_EXTERN_P(r) = RELOC_EXTERN_P(rp);
@@ -617,7 +617,7 @@ int index;
        for (; *cp; cp++)
                hashval = (hashval << 1) + *cp;
 
        for (; *cp; cp++)
                hashval = (hashval << 1) + *cp;
 
-       hashval = (hashval & 0x7fffffff) % rrs_dyn2.ld_buckets;
+       hashval = (hashval & 0x7fffffff) % rrs_sdt.sdt_buckets;
 
        /* Get to the bucket */
        hp = rrs_hashtab + hashval;
 
        /* Get to the bucket */
        hp = rrs_hashtab + hashval;
@@ -651,11 +651,27 @@ void
 consider_rrs_section_lengths()
 {
        int             n;
 consider_rrs_section_lengths()
 {
        int             n;
-       struct shobj    *shp;
+       struct shobj    *shp, **shpp;
        int             symbolsize;
 
        int             symbolsize;
 
-       /* First, determine what of the RRS we want */
+#ifdef notyet
+/* We run into trouble with this as long as shared object symbols
+   are not checked for definitions */
+       /*
+        * First, determine the real number of shared objects we need.
+        */
+       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");
+                       *shpp = (*shpp)->next;
+               }
+               if (*shpp == NULL)
+                       break;
+       }
+#endif
 
 
+       /* First, determine what of the RRS we want */
        if (relocatable_output)
                rrs_section_type = RRS_NONE;
        else if (link_mode & SHAREABLE)
        if (relocatable_output)
                rrs_section_type = RRS_NONE;
        else if (link_mode & SHAREABLE)
@@ -685,13 +701,14 @@ consider_rrs_section_lengths()
         * from crt0), as this is the method used to determine whether the
         * run-time linker must be called.
         */
         * from crt0), as this is the method used to determine whether the
         * run-time linker must be called.
         */
-       if (!(link_mode & SHAREABLE) && !dynamic_symbol->referenced)
+       if (!(link_mode & SHAREABLE) &&
+                       !(dynamic_symbol->flags & GS_REFERENCED))
                fatal("No reference to __DYNAMIC");
 
                fatal("No reference to __DYNAMIC");
 
-       dynamic_symbol->referenced = 1;
+       dynamic_symbol->flags |= GS_REFERENCED;
 
        if (number_of_gotslots > 1)
 
        if (number_of_gotslots > 1)
-               got_symbol->referenced = 1;
+               got_symbol->flags |= GS_REFERENCED;
 
 
        /* Next, allocate relocs, got and plt */
 
 
        /* Next, allocate relocs, got and plt */
@@ -722,7 +739,7 @@ consider_rrs_section_lengths()
         */
        dynamic_symbol->rrs_symbolnum = number_of_rrs_symbols++;
        FOR_EACH_SYMBOL(i ,sp) {
         */
        dynamic_symbol->rrs_symbolnum = number_of_rrs_symbols++;
        FOR_EACH_SYMBOL(i ,sp) {
-               if (sp->referenced) {
+               if (sp->flags & GS_REFERENCED) {
                        rrs_strtab_size += 1 + strlen(sp->name);
                        if (sp != dynamic_symbol)
                                sp->rrs_symbolnum = number_of_rrs_symbols++;
                        rrs_strtab_size += 1 + strlen(sp->name);
                        if (sp != dynamic_symbol)
                                sp->rrs_symbolnum = number_of_rrs_symbols++;
@@ -743,16 +760,16 @@ consider_rrs_section_lengths()
         * Now that we know how many RRS symbols there are going to be,
         * allocate and initialize the RRS symbol hash table.
         */
         * Now that we know how many RRS symbols there are going to be,
         * allocate and initialize the RRS symbol hash table.
         */
-       rrs_dyn2.ld_buckets = number_of_rrs_symbols/4;
-       if (rrs_dyn2.ld_buckets < 4)
-               rrs_dyn2.ld_buckets = 4;
+       rrs_sdt.sdt_buckets = number_of_rrs_symbols/4;
+       if (rrs_sdt.sdt_buckets < 4)
+               rrs_sdt.sdt_buckets = 4;
 
 
-       number_of_rrs_hash_entries = rrs_dyn2.ld_buckets + number_of_rrs_symbols;
+       number_of_rrs_hash_entries = rrs_sdt.sdt_buckets + number_of_rrs_symbols;
        rrs_hashtab = (struct rrs_hash *)xmalloc(
                        number_of_rrs_hash_entries * sizeof(struct rrs_hash));
        rrs_hashtab = (struct rrs_hash *)xmalloc(
                        number_of_rrs_hash_entries * sizeof(struct rrs_hash));
-       for (n = 0; n < rrs_dyn2.ld_buckets; n++)
+       for (n = 0; n < rrs_sdt.sdt_buckets; n++)
                rrs_hashtab[n].rh_symbolnum = -1;
                rrs_hashtab[n].rh_symbolnum = -1;
-       current_hash_index = rrs_dyn2.ld_buckets;
+       current_hash_index = rrs_sdt.sdt_buckets;
 
        /*
         * Get symbols into hash table now, so we can fine tune the size
 
        /*
         * Get symbols into hash table now, so we can fine tune the size
@@ -760,7 +777,7 @@ consider_rrs_section_lengths()
         * to the number of hash link slots actually used.
         */
        FOR_EACH_SYMBOL(i ,sp) {
         * to the number of hash link slots actually used.
         */
        FOR_EACH_SYMBOL(i ,sp) {
-               if (sp->referenced)
+               if (sp->flags & GS_REFERENCED)
                        rrs_insert_hash(sp->name, sp->rrs_symbolnum);
        } END_EACH_SYMBOL;
        number_of_rrs_hash_entries = current_hash_index;
                        rrs_insert_hash(sp->name, sp->rrs_symbolnum);
        } END_EACH_SYMBOL;
        number_of_rrs_hash_entries = current_hash_index;
@@ -768,9 +785,9 @@ consider_rrs_section_lengths()
        /*
         * Calculate RRS section sizes.
         */
        /*
         * Calculate RRS section sizes.
         */
-       rrs_data_size = sizeof(struct link_dynamic);
-       rrs_data_size += sizeof(struct ld_debug);
-       rrs_data_size += sizeof(struct link_dynamic_2);
+       rrs_data_size = sizeof(struct _dynamic);
+       rrs_data_size += sizeof(struct so_debug);
+       rrs_data_size += sizeof(struct section_dispatch_table);
        rrs_data_size += number_of_gotslots * sizeof(got_t);
        rrs_data_size += number_of_jmpslots * sizeof(jmpslot_t);
        rrs_data_size = MALIGN(rrs_data_size);
        rrs_data_size += number_of_gotslots * sizeof(got_t);
        rrs_data_size += number_of_jmpslots * sizeof(jmpslot_t);
        rrs_data_size = MALIGN(rrs_data_size);
@@ -790,7 +807,7 @@ consider_rrs_section_lengths()
                if (*name == '-' && *(name+1) == 'l')
                        name += 2;
 
                if (*name == '-' && *(name+1) == 'l')
                        name += 2;
 
-               rrs_text_size += sizeof(struct link_object);
+               rrs_text_size += sizeof(struct sod);
                rrs_text_size += 1 + strlen(name);
        }
 
                rrs_text_size += 1 + strlen(name);
        }
 
@@ -808,8 +825,8 @@ relocate_rrs_addresses()
                return;
 
        if (rrs_section_type == RRS_PARTIAL) {
                return;
 
        if (rrs_section_type == RRS_PARTIAL) {
-               got_symbol->value = rrs_dyn2.ld_got = rrs_data_start;
-               rrs_dyn2.ld_plt = rrs_dyn2.ld_got +
+               got_symbol->value = rrs_sdt.sdt_got = rrs_data_start;
+               rrs_sdt.sdt_plt = rrs_sdt.sdt_got +
                                        number_of_gotslots * sizeof(got_t);
                return;
        }
                                        number_of_gotslots * sizeof(got_t);
                return;
        }
@@ -817,48 +834,48 @@ relocate_rrs_addresses()
        /*
         * RRS data relocations.
         */
        /*
         * RRS data relocations.
         */
-       rrs_dyn.ld_version = soversion;
-       rrs_dyn.ldd = (struct ld_debug *)
-                       (rrs_data_start + sizeof(struct link_dynamic));
-       rrs_dyn.ld_un.ld_2 = (struct link_dynamic_2 *)
-                               ((long)rrs_dyn.ldd + sizeof(struct ld_debug));
+       rrs_dyn.d_version = soversion;
+       rrs_dyn.d_debug = (struct so_debug *)
+                       (rrs_data_start + sizeof(struct _dynamic));
+       rrs_dyn.d_un.d_sdt = (struct section_dispatch_table *)
+                           ((long)rrs_dyn.d_debug + sizeof(struct so_debug));
 
 
-       rrs_dyn2.ld_got = (long)rrs_dyn.ld_un.ld_2 +
-                                       sizeof(struct link_dynamic_2);
-       rrs_dyn2.ld_plt = rrs_dyn2.ld_got + number_of_gotslots*sizeof(got_t);
+       rrs_sdt.sdt_got = (long)rrs_dyn.d_un.d_sdt +
+                                       sizeof(struct section_dispatch_table);
+       rrs_sdt.sdt_plt = rrs_sdt.sdt_got + number_of_gotslots*sizeof(got_t);
 
        /*
         * RRS text relocations.
         */
 
        /*
         * RRS text relocations.
         */
-       rrs_dyn2.ld_rel = rrs_text_start;
+       rrs_sdt.sdt_rel = rrs_text_start;
        /*
         * Sun BUG compatibility alert.
         * Main program's RRS text values are relative to TXTADDR? WHY??
         */
 #ifdef SUN_COMPAT
        if (soversion == LD_VERSION_SUN && !(link_mode & SHAREABLE))
        /*
         * Sun BUG compatibility alert.
         * Main program's RRS text values are relative to TXTADDR? WHY??
         */
 #ifdef SUN_COMPAT
        if (soversion == LD_VERSION_SUN && !(link_mode & SHAREABLE))
-               rrs_dyn2.ld_rel -= N_TXTADDR(outheader);
+               rrs_sdt.sdt_rel -= N_TXTADDR(outheader);
 #endif
 
 #endif
 
-       rrs_dyn2.ld_hash = rrs_dyn2.ld_rel +
+       rrs_sdt.sdt_hash = rrs_sdt.sdt_rel +
                        reserved_rrs_relocs * sizeof(struct relocation_info);
                        reserved_rrs_relocs * sizeof(struct relocation_info);
-       rrs_dyn2.ld_symbols = rrs_dyn2.ld_hash +
+       rrs_sdt.sdt_nzlist = rrs_sdt.sdt_hash +
                        number_of_rrs_hash_entries * sizeof(struct rrs_hash);
                        number_of_rrs_hash_entries * sizeof(struct rrs_hash);
-       rrs_dyn2.ld_strings = rrs_dyn2.ld_symbols +
+       rrs_sdt.sdt_strings = rrs_sdt.sdt_nzlist +
                        number_of_rrs_symbols * rrs_symbol_size;
                        number_of_rrs_symbols * rrs_symbol_size;
-       rrs_dyn2.ld_str_sz = rrs_strtab_size;
-       rrs_dyn2.ld_text_sz = text_size;
-       rrs_dyn2.ld_plt_sz = number_of_jmpslots * sizeof(jmpslot_t);
+       rrs_sdt.sdt_str_sz = rrs_strtab_size;
+       rrs_sdt.sdt_text_sz = text_size;
+       rrs_sdt.sdt_plt_sz = number_of_jmpslots * sizeof(jmpslot_t);
 
 
-       rrs_dyn2.ld_need = rrs_shobjs ? rrs_dyn2.ld_strings+rrs_strtab_size : 0;
-       rrs_dyn2.ld_stab_hash = 0;
-       rrs_dyn2.ld_rules = 0;
+       rrs_sdt.sdt_sods = rrs_shobjs ? rrs_sdt.sdt_strings+rrs_strtab_size : 0;
+       rrs_sdt.sdt_filler1 = 0;
+       rrs_sdt.sdt_filler2 = 0;
 
        /*
         * Assign addresses to _GLOBAL_OFFSET_TABLE_ and __DYNAMIC
         * &__DYNAMIC is also in the first GOT entry.
         */
 
        /*
         * Assign addresses to _GLOBAL_OFFSET_TABLE_ and __DYNAMIC
         * &__DYNAMIC is also in the first GOT entry.
         */
-       got_symbol->value = rrs_dyn2.ld_got;
+       got_symbol->value = rrs_sdt.sdt_got;
 
        *rrs_got = dynamic_symbol->value = rrs_data_start;
 
 
        *rrs_got = dynamic_symbol->value = rrs_data_start;
 
@@ -896,14 +913,14 @@ write_rrs_data()
                return;
        }
 
                return;
        }
 
-       md_swapout_link_dynamic(&rrs_dyn);
-       mywrite(&rrs_dyn, 1, sizeof(struct link_dynamic), outdesc);
+       md_swapout__dynamic(&rrs_dyn);
+       mywrite(&rrs_dyn, 1, sizeof(struct _dynamic), outdesc);
 
 
-       md_swapout_ld_debug(&rrs_ld_debug);
-       mywrite(&rrs_ld_debug, 1, sizeof(struct ld_debug), outdesc);
+       md_swapout_so_debug(&rrs_so_debug);
+       mywrite(&rrs_so_debug, 1, sizeof(struct so_debug), outdesc);
 
 
-       md_swapout_link_dynamic_2(&rrs_dyn2);
-       mywrite(&rrs_dyn2, 1, sizeof(struct link_dynamic_2), outdesc);
+       md_swapout_section_dispatch_table(&rrs_sdt);
+       mywrite(&rrs_sdt, 1, sizeof(struct section_dispatch_table), outdesc);
 
        md_swapout_got(rrs_got, number_of_gotslots);
        mywrite(rrs_got, number_of_gotslots, sizeof(got_t), outdesc);
 
        md_swapout_got(rrs_got, number_of_gotslots);
        mywrite(rrs_got, number_of_gotslots, sizeof(got_t), outdesc);
@@ -921,7 +938,7 @@ write_rrs_text()
        struct nzlist           *nlp;
        int                     offset = 0;
        struct shobj            *shp;
        struct nzlist           *nlp;
        int                     offset = 0;
        struct shobj            *shp;
-       struct link_object      *lo;
+       struct sod              *sodp;
 
        if (rrs_section_type == RRS_PARTIAL)
                return;
 
        if (rrs_section_type == RRS_PARTIAL)
                return;
@@ -967,7 +984,7 @@ write_rrs_text()
         */
        FOR_EACH_SYMBOL(i, sp) {
 
         */
        FOR_EACH_SYMBOL(i, sp) {
 
-               if (!sp->referenced || sp == dynamic_symbol)
+               if (!(sp->flags & GS_REFERENCED) || sp == dynamic_symbol)
                        continue;
 
                if ((long)nlp - (long)rrs_symbols >=
                        continue;
 
                if ((long)nlp - (long)rrs_symbols >=
@@ -993,6 +1010,7 @@ write_rrs_text()
                                 */
                                nlp->nz_type = sp->alias->defined;
                                nlp->nz_value = sp->alias->value;
                                 */
                                nlp->nz_type = sp->alias->defined;
                                nlp->nz_value = sp->alias->value;
+                               nlp->nz_other = N_OTHER(0, sp->alias->aux);
                        } else if (sp->defined == N_SIZE) {
                                /*
                                 * Make sure this symbol isn't going
                        } else if (sp->defined == N_SIZE) {
                                /*
                                 * Make sure this symbol isn't going
@@ -1003,47 +1021,36 @@ write_rrs_text()
                        } else {
                                nlp->nz_type = sp->defined;
                                nlp->nz_value = sp->value;
                        } else {
                                nlp->nz_type = sp->defined;
                                nlp->nz_value = sp->value;
+                               nlp->nz_other = N_OTHER(0, sp->aux);
                        }
                        if (LD_VERSION_NZLIST_P(soversion))
                                nlp->nz_size = sp->size;
                        }
                        if (LD_VERSION_NZLIST_P(soversion))
                                nlp->nz_size = sp->size;
-               } else if (sp->max_common_size) {
+               } else if (sp->common_size) {
                        /*
                         * a common definition
                         */
                        nlp->nz_type = N_UNDF | N_EXT;
                        /*
                         * a common definition
                         */
                        nlp->nz_type = N_UNDF | N_EXT;
-                       nlp->nz_value = sp->max_common_size;
+                       nlp->nz_value = sp->common_size;
                } else if (!sp->defined) {
                        /* undefined */
                        nlp->nz_type = N_UNDF | N_EXT;
                        nlp->nz_value = 0;
                } else if (!sp->defined) {
                        /* undefined */
                        nlp->nz_type = N_UNDF | N_EXT;
                        nlp->nz_value = 0;
+                       if (sp->so_defined && sp->jmpslot_offset != -1) {
+                               /*
+                                * Define a "weak" function symbol.
+                                */
+                               if (sp->aux != AUX_FUNC)
+                                       fatal("%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
                        fatal(
                              "internal error: %s defined in mysterious way",
                              sp->name);
 
                } else
                        fatal(
                              "internal error: %s defined in mysterious way",
                              sp->name);
 
-               /* Handle auxialiary type qualifiers */
-               switch (sp->aux) {
-               case 0:
-                       break;
-               case RRS_FUNC:
-                       if (sp->so_defined != (N_TEXT+N_EXT))
-                               fatal("internal error: %s: other but not text",
-                                                             sp->name);
-                       if (sp->jmpslot_offset == -1)
-                               fatal(
-                                 "internal error: %s has no jmpslot but other",
-                                     sp->name);
-                       nlp->nz_other = sp->aux;
-                       nlp->nz_value =
-                               rrs_dyn2.ld_plt + sp->jmpslot_offset;
-                       break;
-               default:
-                       fatal(
-                           "internal error: %s: unsupported other value: %x",
-                                     sp->name, sp->aux);
-                       break;
-               }
-
                /* Set symbol's name */
                nlp->nz_strx = offset;
                strcpy(rrs_strtab + offset, sp->name);
                /* Set symbol's name */
                nlp->nz_strx = offset;
                strcpy(rrs_strtab + offset, sp->name);
@@ -1089,9 +1096,8 @@ write_rrs_text()
        /*
         * Write the names of the shared objects needed at run-time
         */
        /*
         * Write the names of the shared objects needed at run-time
         */
-       pos = rrs_dyn2.ld_need + number_of_shobjs * sizeof(struct link_object);
-       lo = (struct link_object *)alloca(
-                               number_of_shobjs * sizeof(struct link_object));
+       pos = rrs_sdt.sdt_sods + number_of_shobjs * sizeof(struct sod);
+       sodp = (struct sod *)alloca( number_of_shobjs * sizeof(struct sod));
 
        for (i = 0, shp = rrs_shobjs; shp; i++, shp = shp->next) {
                char    *name = shp->entry->local_sym_name;
 
        for (i = 0, shp = rrs_shobjs; shp; i++, shp = shp->next) {
                char    *name = shp->entry->local_sym_name;
@@ -1100,27 +1106,27 @@ write_rrs_text()
                        fatal("internal error: # of link objects exceeds %d",
                                number_of_shobjs);
 
                        fatal("internal error: # of link objects exceeds %d",
                                number_of_shobjs);
 
-               lo[i].lo_name = pos;
-               lo[i].lo_major = shp->entry->lib_major;
-               lo[i].lo_minor = shp->entry->lib_minor;
+               sodp[i].sod_name = pos;
+               sodp[i].sod_major = shp->entry->lib_major;
+               sodp[i].sod_minor = shp->entry->lib_minor;
 
                if (*name == '-' && *(name+1) == 'l') {
                        name += 2;
 
                if (*name == '-' && *(name+1) == 'l') {
                        name += 2;
-                       lo[i].lo_library = 1;
+                       sodp[i].sod_library = 1;
                } else
                } else
-                       lo[i].lo_library = 0;
+                       sodp[i].sod_library = 0;
 
                pos += 1 + strlen(name);
 
                pos += 1 + strlen(name);
-               lo[i].lo_next = (i == number_of_shobjs - 1) ? 0 :
-                       (rrs_dyn2.ld_need + (i+1)*sizeof(struct link_object));
+               sodp[i].sod_next = (i == number_of_shobjs - 1) ? 0 :
+                       (rrs_sdt.sdt_sods + (i+1)*sizeof(struct sod));
        }
 
        if (i < number_of_shobjs)
                fatal("internal error: # of link objects less then expected %d",
                                number_of_shobjs);
 
        }
 
        if (i < number_of_shobjs)
                fatal("internal error: # of link objects less then expected %d",
                                number_of_shobjs);
 
-       md_swapout_link_object(lo, number_of_shobjs);
-       mywrite(lo, number_of_shobjs, sizeof(struct link_object), outdesc);
+       md_swapout_sod(sodp, number_of_shobjs);
+       mywrite(sodp, number_of_shobjs, sizeof(struct sod), outdesc);
 
        for (i = 0, shp = rrs_shobjs; shp; i++, shp = shp->next) {
                char    *name = shp->entry->local_sym_name;
 
        for (i = 0, shp = rrs_shobjs; shp; i++, shp = shp->next) {
                char    *name = shp->entry->local_sym_name;
index 1a76c51..0fbf2b2 100644 (file)
@@ -1,25 +1,25 @@
-#      $Id: Makefile,v 1.7 1993/12/11 21:05:59 jkh Exp $
+#      $Id: Makefile,v 1.8 1994/01/28 21:01:20 pk Exp $
 
 PROG=  ld.so
 
 PROG=  ld.so
-SRCS=  mdprologue.S sbrk.c rtld.c shlib.c etc.c md.c
+SRCS=  mdprologue.S rtld.c malloc.c shlib.c etc.c md.c
 NOMAN= noman
 LDDIR?= $(.CURDIR)/..
 #PICFLAG=-pic
 PICFLAG=-fpic
 NOMAN= noman
 LDDIR?= $(.CURDIR)/..
 #PICFLAG=-pic
 PICFLAG=-fpic
-CFLAGS += -I$(LDDIR) -I$(.CURDIR) -I$(LDDIR)/$(MACHINE) -O $(PICFLAG) -DRTLD
-LDFLAGS = -Bshareable -Bsymbolic -assert nosymbolic -Z
-LIBS =  -lc_pic -lgcc_pic
+CFLAGS+=-I$(LDDIR) -I$(.CURDIR) -I$(LDDIR)/$(MACHINE) $(PICFLAG) -DRTLD
+LDFLAGS+=-Bshareable -Bsymbolic -assert nosymbolic
+ASFLAGS+=-k
+LDADD+=        -lc_pic
 BINDIR= /usr/libexec
 BINDIR= /usr/libexec
-ASFLAGS = -k
-
-.PATH: $(LDDIR) $(LDDIR)/$(MACHINE)
 
 .SUFFIXES: .S
 
 
 .SUFFIXES: .S
 
+.PATH: $(LDDIR) $(LDDIR)/$(MACHINE)
+
 $(PROG):
 $(PROG):
-       $(LD) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIBS) $(LDADD)
+       $(LD) -o $(PROG) $(LDFLAGS) $(OBJS) $(LDADD)
 
 .S.o:
 
 .S.o:
-       $(CPP) $(.IMPSRC) | $(AS) $(ASFLAGS) -o $(.TARGET) -
+       ${CPP} ${.IMPSRC} | ${AS} ${ASFLAGS} -o ${.TARGET} -
 
 .include <bsd.prog.mk>
 
 .include <bsd.prog.mk>
index e02fef6..72ab49e 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: rtld.c,v 1.13 1994/01/12 23:16:19 jkh Exp $
+ *     $Id: rtld.c,v 1.14 1994/01/14 11:47:00 jkh Exp $
  */
 
 #include <machine/vmparam.h>
  */
 
 #include <machine/vmparam.h>
@@ -39,6 +39,7 @@
 #include <sys/file.h>
 #include <sys/time.h>
 #include <sys/resource.h>
 #include <sys/file.h>
 #include <sys/time.h>
 #include <sys/resource.h>
+#include <sys/errno.h>
 #include <sys/mman.h>
 #ifndef BSD
 #define MAP_COPY       MAP_PRIVATE
 #include <sys/mman.h>
 #ifndef BSD
 #define MAP_COPY       MAP_PRIVATE
 #endif
 
 /*
 #endif
 
 /*
- * Loader private data, hung off link_map->lm_lpd
+ * Loader private data, hung off <so_map>->som_spd
  */
  */
-struct lm_private {
-       int             lpd_version;
-       struct link_map *lpd_parent;
+struct somap_private {
+       int             spd_version;
+       struct so_map   *spd_parent;
+       int             spd_refcount;
+       int             spd_flags;
+#define RTLD_MAIN      1
+#define RTLD_RTLD      2
+#define RTLD_DL                4
+
 #ifdef SUN_COMPAT
 #ifdef SUN_COMPAT
-       long            lpd_offset;     /* Correction for Sun main programs */
+       long            spd_offset;     /* Correction for Sun main programs */
 #endif
 };
 
 #endif
 };
 
+#define LM_PRIVATE(smp)        ((struct somap_private *)(smp)->som_spd)
+
 #ifdef SUN_COMPAT
 #ifdef SUN_COMPAT
-#define LM_OFFSET(lmp) (((struct lm_private *)((lmp)->lm_lpd))->lpd_offset)
+#define LM_OFFSET(smp) (LM_PRIVATE(smp)->spd_offset)
 #else
 #else
-#define LM_OFFSET(lmp) (0)
+#define LM_OFFSET(smp) (0)
 #endif
 
 #endif
 
-/* Base address for link_dynamic_2 entries */
-#define LM_LDBASE(lmp) (lmp->lm_addr + LM_OFFSET(lmp))
+/* Base address for section_dispatch_table entries */
+#define LM_LDBASE(smp) (smp->som_addr + LM_OFFSET(smp))
 
 /* Start of text segment */
 
 /* Start of text segment */
-#define LM_TXTADDR(lmp)        (lmp->lm_addr == (caddr_t)0 ? PAGSIZ : 0)
+#define LM_TXTADDR(smp)        (smp->som_addr == (caddr_t)0 ? PAGSIZ : 0)
 
 /* Start of run-time relocation_info */
 
 /* Start of run-time relocation_info */
-#define LM_REL(lmp)    ((struct relocation_info *) \
-                       (lmp->lm_addr + LM_OFFSET(lmp) + LD_REL((lmp)->lm_ld)))
+#define LM_REL(smp)    ((struct relocation_info *) \
+       (smp->som_addr + LM_OFFSET(smp) + LD_REL((smp)->som_dynamic)))
 
 /* Start of symbols */
 
 /* Start of symbols */
-#define LM_SYMBOL(lmp, i)      ((struct nzlist *) \
-               (lmp->lm_addr + LM_OFFSET(lmp) + LD_SYMBOL((lmp)->lm_ld) + \
-                       i * (LD_VERSION_NZLIST_P(lmp->lm_ld->ld_version) ? \
-                               sizeof(struct nzlist) : sizeof(struct nlist))))
+#define LM_SYMBOL(smp, i)      ((struct nzlist *) \
+       (smp->som_addr + LM_OFFSET(smp) + LD_SYMBOL((smp)->som_dynamic) + \
+               i * (LD_VERSION_NZLIST_P(smp->som_dynamic->d_version) ? \
+                       sizeof(struct nzlist) : sizeof(struct nlist))))
 
 /* Start of hash table */
 
 /* Start of hash table */
-#define LM_HASH(lmp)   ((struct rrs_hash *) \
-               (lmp->lm_addr + LM_OFFSET(lmp) + LD_HASH((lmp)->lm_ld)))
+#define LM_HASH(smp)   ((struct rrs_hash *) \
+       ((smp)->som_addr + LM_OFFSET(smp) + LD_HASH((smp)->som_dynamic)))
 
 /* Start of strings */
 
 /* Start of strings */
-#define LM_STRINGS(lmp)        ((char *) \
-               (lmp->lm_addr + LM_OFFSET(lmp) + LD_STRINGS((lmp)->lm_ld)))
+#define LM_STRINGS(smp)        ((char *) \
+       ((smp)->som_addr + LM_OFFSET(smp) + LD_STRINGS((smp)->som_dynamic)))
 
 /* End of text */
 
 /* End of text */
-#define LM_ETEXT(lmp)  ((char *) \
-               (lmp->lm_addr + LM_TXTADDR(lmp) + LD_TEXTSZ((lmp)->lm_ld)))
+#define LM_ETEXT(smp)  ((char *) \
+       ((smp)->som_addr + LM_TXTADDR(smp) + LD_TEXTSZ((smp)->som_dynamic)))
 
 /* PLT is in data segment, so don't use LM_OFFSET here */
 
 /* PLT is in data segment, so don't use LM_OFFSET here */
-#define LM_PLT(lmp)    ((jmpslot_t *) \
-               (lmp->lm_addr + LD_PLT((lmp)->lm_ld)))
+#define LM_PLT(smp)    ((jmpslot_t *) \
+       ((smp)->som_addr + LD_PLT((smp)->som_dynamic)))
 
 /* Parent of link map */
 
 /* Parent of link map */
-#define LM_PARENT(lmp) (((struct lm_private *)((lmp)->lm_lpd))->lpd_parent)
+#define LM_PARENT(smp) (LM_PRIVATE(smp)->spd_parent)
 
 char                   **environ;
 int                    errno;
 
 char                   **environ;
 int                    errno;
-uid_t                  uid, euid;
-gid_t                  gid, egid;
-int                    careful;
+static uid_t           uid, euid;
+static gid_t           gid, egid;
+static int             careful;
+static char            *main_progname = "main";
 
 
-struct link_map                *link_map_head, *main_map;
-struct link_map                **link_map_tail = &link_map_head;
+struct so_map          *link_map_head, *main_map;
+struct so_map          **link_map_tail = &link_map_head;
 struct rt_symbol       *rt_symbol_head;
 
 struct rt_symbol       *rt_symbol_head;
 
-static int             dlopen(), dlclose(), dlsym();
+static void            *dlopen __P((char *, int));
+static int             dlclose __P((void *));
+static void            *dlsym __P((void *, char *));
+static int             dlctl __P((void *, int, void *));
 
 static struct ld_entry ld_entry = {
 
 static struct ld_entry ld_entry = {
-       dlopen, dlclose, dlsym
+       dlopen, dlclose, dlsym, dlctl
 };
 
 };
 
-void                   xprintf __P((char *, ...));
+       void            xprintf __P((char *, ...));
 static void            init_brk __P((void));
 static void            init_brk __P((void));
-static void            load_maps __P((struct crt_ldso *));
-static void            map_object __P((struct link_object *, struct link_map *));
-static void            alloc_link_map __P((    char *, struct link_object *,
-                                               struct link_map *, caddr_t,
-                                               struct link_dynamic *));
-static void            check_text_reloc __P((  struct relocation_info *,
-                                               struct link_map *,
+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 *,
+                                               struct so_map *,
                                                caddr_t));
                                                caddr_t));
-static void            reloc_maps __P((void));
-static void            reloc_copy __P((void));
-static void            init_maps __P((void));
+static void            reloc_map __P((struct so_map *));
+static void            reloc_copy __P((struct so_map *));
+static void            init_map __P((struct so_map *, char *));
 static char            *rtfindlib __P((char *, int, int, int *));
 void                   binder_entry __P((void));
 long                   binder __P((jmpslot_t *));
 static char            *rtfindlib __P((char *, int, int, int *));
 void                   binder_entry __P((void));
 long                   binder __P((jmpslot_t *));
-static struct nzlist   *lookup __P((char *, struct link_map **, int));
-static struct rt_symbol        *lookup_rts __P((char *));
-static struct rt_symbol        *enter_rts __P((char *, long, int, caddr_t, long));
+static struct nzlist   *lookup __P((char *, struct so_map **, int));
+static inline struct rt_symbol *lookup_rts __P((char *));
+static struct rt_symbol        *enter_rts __P((char *, long, int, caddr_t,
+                                               long, struct so_map *));
+
+static inline int
+strcmp (register const char *s1, register const char *s2)
+{
+       while (*s1 == *s2++)
+               if (*s1++ == 0)
+                       return (0);
+       return (*(unsigned char *)s1 - *(unsigned char *)--s2);
+}
 
 #include "md-static-funcs.c"
 
 
 #include "md-static-funcs.c"
 
@@ -155,34 +179,36 @@ static struct rt_symbol   *enter_rts __P((char *, long, int, caddr_t, long));
  * Called from assembler stub that has set up crtp (passed from crt0)
  * and dp (our __DYNAMIC).
  */
  * Called from assembler stub that has set up crtp (passed from crt0)
  * and dp (our __DYNAMIC).
  */
-void
+int
 rtld(version, crtp, dp)
 int                    version;
 struct crt_ldso                *crtp;
 rtld(version, crtp, dp)
 int                    version;
 struct crt_ldso                *crtp;
-struct link_dynamic    *dp;
+struct _dynamic                *dp;
 {
        int                     n;
        int                     nreloc;         /* # of ld.so relocations */
        struct relocation_info  *reloc;
        char                    **envp;
 {
        int                     n;
        int                     nreloc;         /* # of ld.so relocations */
        struct relocation_info  *reloc;
        char                    **envp;
-       struct ld_debug         *ldp;
+       struct so_debug         *ddp;
+       struct so_map           *smp;
 
        /* Check version */
 
        /* Check version */
-       if (version != CRT_VERSION_BSD && version != CRT_VERSION_SUN)
-               return;
+       if (            version != CRT_VERSION_BSD_2 &&
+                       version != CRT_VERSION_BSD_3 &&
+                       version != CRT_VERSION_SUN)
+               return -1;
 
        /* Fixup __DYNAMIC structure */
 
        /* Fixup __DYNAMIC structure */
-       (long)dp->ld_un.ld_2 += crtp->crt_ba;
+       (long)dp->d_un.d_sdt += crtp->crt_ba;
 
 
-       /* Be careful not to use .div routine from library */
+       /* Divide by hand to avoid possible use of library division routine */
        for (   nreloc = 0, n = LD_RELSZ(dp);
                n > 0;
                n -= sizeof(struct relocation_info) ) nreloc++;
 
        
        /* Relocate ourselves */
        for (   nreloc = 0, n = LD_RELSZ(dp);
                n > 0;
                n -= sizeof(struct relocation_info) ) nreloc++;
 
        
        /* Relocate ourselves */
-       for (   reloc = (struct relocation_info *)
-                               (dp->ld_un.ld_2->ld_rel + crtp->crt_ba);
+       for (   reloc = (struct relocation_info *)(LD_REL(dp) + crtp->crt_ba);
                nreloc;
                nreloc--, reloc++) {
 
                nreloc;
                nreloc--, reloc++) {
 
@@ -192,6 +218,8 @@ struct link_dynamic *dp;
        }
 
        progname = "ld.so";
        }
 
        progname = "ld.so";
+       if (version >= CRT_VERSION_BSD_3)
+               main_progname = crtp->crt_prog;
 
        /* Setup out (private) environ variable */
        environ = crtp->crt_ep;
 
        /* Setup out (private) environ variable */
        environ = crtp->crt_ep;
@@ -212,89 +240,134 @@ struct link_dynamic      *dp;
        std_search_dirs(getenv("LD_LIBRARY_PATH"));
 
        /* Load required objects into the process address space */
        std_search_dirs(getenv("LD_LIBRARY_PATH"));
 
        /* Load required objects into the process address space */
-       load_maps(crtp);
+       load_objects(crtp, dp);
 
        /* Relocate all loaded objects according to their RRS segments */
 
        /* Relocate all loaded objects according to their RRS segments */
-       reloc_maps();
-       reloc_copy();
-       init_maps();
+       for (smp = link_map_head; smp; smp = smp->som_next) {
+               if (LM_PRIVATE(smp)->spd_flags & RTLD_RTLD)
+                       continue;
+               reloc_map(smp);
+       }
+
+       /* Copy any relocated initialized data. */
+       for (smp = link_map_head; smp; smp = smp->som_next) {
+               if (LM_PRIVATE(smp)->spd_flags & RTLD_RTLD)
+                       continue;
+               reloc_copy(smp);
+       }
+
+       /* Call any object initialization routines. */
+       for (smp = link_map_head; smp; smp = smp->som_next) {
+               if (LM_PRIVATE(smp)->spd_flags & RTLD_RTLD)
+                       continue;
+               init_map(smp, ".init");
+       }
 
        /* Fill in some field in main's __DYNAMIC structure */
 
        /* Fill in some field in main's __DYNAMIC structure */
-       crtp->crt_dp->ld_entry = &ld_entry;
+       crtp->crt_dp->d_entry = &ld_entry;
+       crtp->crt_dp->d_un.d_sdt->sdt_loaded = link_map_head->som_next;
 
 
-       ldp = crtp->crt_dp->ldd;
-       ldp->ldd_cp = rt_symbol_head;
-       if (ldp->ldd_in_debugger) {
+       ddp = crtp->crt_dp->d_debug;
+       ddp->dd_cc = rt_symbol_head;
+       if (ddp->dd_in_debugger) {
                caddr_t addr = (caddr_t)((long)crtp->crt_bp & (~(PAGSIZ - 1)));
 
                /* Set breakpoint for the benefit of debuggers */
                if (mprotect(addr, PAGSIZ,
                                PROT_READ|PROT_WRITE|PROT_EXEC) == -1) {
                        perror("mprotect"),
                caddr_t addr = (caddr_t)((long)crtp->crt_bp & (~(PAGSIZ - 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\n");
+                       fatal("Cannot set breakpoint (%s)\n", main_progname);
                }
                }
-               md_set_breakpoint(crtp->crt_bp, &ldp->ldd_bp_inst);
+               md_set_breakpoint(crtp->crt_bp, &ddp->dd_bpt_shadow);
                if (mprotect(addr, PAGSIZ, PROT_READ|PROT_EXEC) == -1) {
                        perror("mprotect");
                }
 
                if (mprotect(addr, PAGSIZ, PROT_READ|PROT_EXEC) == -1) {
                        perror("mprotect");
                }
 
-               ldp->ldd_bp_addr = crtp->crt_bp;
+               ddp->dd_bpt_addr = crtp->crt_bp;
                if (link_map_head)
                if (link_map_head)
-                       ldp->ldd_sym_loaded = 1;
+                       ddp->dd_sym_loaded = 1;
        }
        }
-       crtp->crt_dp->ld_un.ld_2->ld_loaded = link_map_head->lm_next;
+
        /* Close our file descriptor */
        (void)close(crtp->crt_ldfd);
        /* Close our file descriptor */
        (void)close(crtp->crt_ldfd);
+       return 0;
 }
 
 
 static void
 }
 
 
 static void
-load_maps(crtp)
+load_objects(crtp, dp)
 struct crt_ldso        *crtp;
 struct crt_ldso        *crtp;
+struct _dynamic        *dp;
 {
 {
-       struct link_map         *lmp;
-       int                     tracing = (int)getenv("LD_TRACE_LOADED_OBJECTS");
+       struct so_map   *smp;
+       int             tracing = (int)getenv("LD_TRACE_LOADED_OBJECTS");
 
        /* Handle LD_PRELOAD's here */
 
        /* Make an entry for the main program */
 
        /* Handle LD_PRELOAD's here */
 
        /* Make an entry for the main program */
-       alloc_link_map("main", (struct link_object *)0, (struct link_map *)0,
+       smp = alloc_link_map(main_progname, (struct sod *)0, (struct so_map *)0,
                                        (caddr_t)0, crtp->crt_dp);
                                        (caddr_t)0, crtp->crt_dp);
+       LM_PRIVATE(smp)->spd_refcount++;
+       LM_PRIVATE(smp)->spd_flags |= RTLD_MAIN;
 
 
-       for (lmp = link_map_head; lmp; lmp = lmp->lm_next) {
-               struct link_object      *lop;
-               long                    next = 0;
+       /* Make an entry for ourselves */
+       smp = alloc_link_map("/usr/libexec/ld.so", (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;
 
 
-               if (lmp->lm_ld)
-                       next = LD_NEED(lmp->lm_ld);
+       for (smp = link_map_head; smp; smp = smp->som_next) {
+               struct sod      *sodp;
+               long            next = 0;
+
+               if (LM_PRIVATE(smp)->spd_flags & RTLD_RTLD)
+                       continue;
+
+               if (smp->som_dynamic)
+                       next = LD_NEED(smp->som_dynamic);
 
                while (next) {
 
                while (next) {
-                       lop = (struct link_object *) (LM_LDBASE(lmp) + next);
-                       map_object(lop, lmp);
-                       next = lop->lo_next;
+                       struct so_map   *newmap;
+
+                       sodp = (struct sod *)(LM_LDBASE(smp) + next);
+                       if ((newmap = map_object(sodp, smp)) == NULL) {
+                               if (!tracing) {
+                                       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,
+                                               sodp->sod_major,
+                                               sodp->sod_minor,
+                                               strerror(errno));
+                               }
+                               newmap = alloc_link_map(NULL, sodp, smp, 0, 0);
+                       }
+                       LM_PRIVATE(newmap)->spd_refcount++;
+                       next = sodp->sod_next;
                }
        }
 
        if (! tracing)
                return;
 
                }
        }
 
        if (! tracing)
                return;
 
-       for (lmp = link_map_head; lmp; lmp = lmp->lm_next) {
-               struct link_object      *lop;
-               char                    *name, *path;
+       for (smp = link_map_head; smp; smp = smp->som_next) {
+               struct sod      *sodp;
+               char            *name, *path;
 
 
-               if ((lop = lmp->lm_lop) == NULL)
+               if ((sodp = smp->som_sod) == NULL)
                        continue;
                        continue;
+               name = sodp->sod_name + LM_LDBASE(LM_PARENT(smp));
 
 
-               name = lop->lo_name + LM_LDBASE(LM_PARENT(lmp));
-
-               if ((path = lmp->lm_name) == NULL)
+               if ((path = smp->som_path) == NULL)
                        path = "not found";
 
                        path = "not found";
 
-               if (lop->lo_library)
+               if (sodp->sod_library)
                        printf("\t-l%s.%d => %s (%#x)\n", name,
                        printf("\t-l%s.%d => %s (%#x)\n", name,
-                                       lop->lo_major, path, lmp->lm_addr);
+                                       sodp->sod_major, path, smp->som_addr);
                else
                else
-                       printf("\t%s => %s (%#x)\n", name, path, lmp->lm_addr);
+                       printf("\t%s => %s (%#x)\n", name, path, smp->som_addr);
        }
 
        exit(0);
        }
 
        exit(0);
@@ -304,94 +377,120 @@ struct crt_ldso  *crtp;
  * Allocate a new link map for an shared object NAME loaded at ADDR as a
  * result of the presence of link object LOP in the link map PARENT.
  */
  * Allocate a new link map for an shared object NAME loaded at ADDR as a
  * result of the presence of link object LOP in the link map PARENT.
  */
-static void
-alloc_link_map(name, lop, parent, addr, dp)
-char                   *name;
-struct link_map                *parent;
-struct link_object     *lop;
-caddr_t                        addr;
-struct link_dynamic    *dp;
+       static struct so_map *
+alloc_link_map(path, sodp, parent, addr, dp)
+       char            *path;
+       struct sod      *sodp;
+       struct so_map   *parent;
+       caddr_t         addr;
+       struct _dynamic *dp;
 {
 {
-       struct link_map         *lmp;
-       struct lm_private       *lmpp;
+       struct so_map           *smp;
+       struct somap_private    *smpp;
 
 
-       lmpp = (struct lm_private *)xmalloc(sizeof(struct lm_private));
-       lmp = (struct link_map *)xmalloc(sizeof(struct link_map));
-       lmp->lm_next = NULL;
-       *link_map_tail = lmp;
-       link_map_tail = &lmp->lm_next;
+       smpp = (struct somap_private *)xmalloc(sizeof(struct somap_private));
+       smp = (struct so_map *)xmalloc(sizeof(struct so_map));
+       smp->som_next = NULL;
+       *link_map_tail = smp;
+       link_map_tail = &smp->som_next;
 
 
-       lmp->lm_addr = addr;
-       lmp->lm_name = name;
-       lmp->lm_lop = lop;
-       lmp->lm_ld = dp;
-       lmp->lm_lpd = (caddr_t)lmpp;
+       smp->som_addr = addr;
+       smp->som_path = path;
+       smp->som_sod = sodp;
+       smp->som_dynamic = dp;
+       smp->som_spd = (caddr_t)smpp;
 
 
-/*XXX*/        if (addr == 0) main_map = lmp;
+/*XXX*/        if (addr == 0) main_map = smp;
 
 
-       lmpp->lpd_parent = parent;
+       smpp->spd_refcount = 0;
+       smpp->spd_flags = 0;
+       smpp->spd_parent = parent;
 
 #ifdef SUN_COMPAT
 
 #ifdef SUN_COMPAT
-       lmpp->lpd_offset =
-               (addr == 0 && dp->ld_version == LD_VERSION_SUN) ? PAGSIZ : 0;
+       smpp->spd_offset =
+               (addr==0 && dp && dp->d_version==LD_VERSION_SUN) ? PAGSIZ : 0;
 #endif
 #endif
+       return smp;
 }
 
 /*
  * Map object identified by link object LOP which was found
  * in link map LMP.
  */
 }
 
 /*
  * Map object identified by link object LOP which was found
  * in link map LMP.
  */
-static void
-map_object(lop, lmp)
-struct link_object     *lop;
-struct link_map                *lmp;
+       static struct so_map *
+map_object(sodp, smp)
+       struct sod      *sodp;
+       struct so_map   *smp;
 {
 {
-       struct link_dynamic     *dp;
-       char            *path, *name = (char *)(lop->lo_name + LM_LDBASE(lmp));
+       struct _dynamic *dp;
+       char            *path, *name = (char *)(sodp->sod_name + LM_LDBASE(smp));
        int             fd;
        caddr_t         addr;
        struct exec     hdr;
        int             usehints = 0;
        int             fd;
        caddr_t         addr;
        struct exec     hdr;
        int             usehints = 0;
+       struct so_map   *p;
 
 
-       if (lop->lo_library) {
+       if (sodp->sod_library) {
                usehints = 1;
 again:
                usehints = 1;
 again:
-               path = rtfindlib(name, lop->lo_major, lop->lo_minor, &usehints);
-               if (path == NULL)
-                       fatal("Cannot find lib%s.so.%d.%d\n",
-                                       name, lop->lo_major, lop->lo_minor);
+               path = rtfindlib(name, sodp->sod_major,
+                                               sodp->sod_minor, &usehints);
+               if (path == NULL) {
+                       errno = ENOENT;
+                       return NULL;
+               }
        } else {
        } else {
+               if (careful && *name != '/') {
+                       errno = EACCES;
+                       return NULL;
+               }
                path = name;
        }
 
                path = name;
        }
 
-       fd = open(path, O_RDONLY, 0);
-       if (fd == -1) {
+       /* Check if already loaded */
+       for (p = link_map_head; p; p = p->som_next)
+               if (p->som_path && strcmp(p->som_path, path) == 0)
+                       break;
+
+       if (p != NULL)
+               return p;
+
+       if ((fd = open(path, O_RDONLY, 0)) == -1) {
                if (usehints) {
                        usehints = 0;
                        goto again;
                }
                if (usehints) {
                        usehints = 0;
                        goto again;
                }
-               fatal("%s not found", path);
+               return NULL;
        }
 
        if (read(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) {
        }
 
        if (read(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) {
-               fatal("%s: Cannot read exec header", path);
+               (void)close(fd);
+               /*errno = x;*/
+               return NULL;
        }
 
        }
 
-       if (N_BADMAG(hdr))
-               fatal("%s: Incorrect format", path);
+       if (N_BADMAG(hdr)) {
+               (void)close(fd);
+               errno = EFTYPE;
+               return NULL;
+       }
 
        if ((addr = mmap(0, hdr.a_text + hdr.a_data,
                                PROT_READ|PROT_EXEC,
 
        if ((addr = mmap(0, hdr.a_text + hdr.a_data,
                                PROT_READ|PROT_EXEC,
-                               MAP_FILE|MAP_COPY, fd, 0)) == (caddr_t)-1)
-               fatal("Cannot map %s text\n", path);
+                               MAP_FILE|MAP_COPY, fd, 0)) == (caddr_t)-1) {
+               (void)close(fd);
+               return NULL;
+       }
 
        if (mmap(addr + hdr.a_text, hdr.a_data,
 
        if (mmap(addr + hdr.a_text, hdr.a_data,
-                               PROT_READ|PROT_WRITE,
+                               PROT_READ|PROT_WRITE|PROT_EXEC,
                                MAP_FILE|MAP_FIXED|MAP_COPY,
                                MAP_FILE|MAP_FIXED|MAP_COPY,
-                               fd, hdr.a_text) == (caddr_t)-1)
-               fatal("Cannot map %s data", path);
+                               fd, hdr.a_text) == (caddr_t)-1) {
+               (void)close(fd);
+               return NULL;
+       }
 
 
-       close(fd);
+       (void)close(fd);
 
        fd = -1;
 #ifdef NEED_DEV_ZERO
 
        fd = -1;
 #ifdef NEED_DEV_ZERO
@@ -399,213 +498,282 @@ again:
                perror("/dev/zero");
 #endif
        if (hdr.a_bss && mmap(addr + hdr.a_text + hdr.a_data, hdr.a_bss,
                perror("/dev/zero");
 #endif
        if (hdr.a_bss && mmap(addr + hdr.a_text + hdr.a_data, hdr.a_bss,
-                               PROT_READ|PROT_WRITE,
+                               PROT_READ|PROT_WRITE|PROT_EXEC,
                                MAP_ANON|MAP_FIXED|MAP_COPY,
                                fd, hdr.a_text + hdr.a_data) == (caddr_t)-1)
                                MAP_ANON|MAP_FIXED|MAP_COPY,
                                fd, hdr.a_text + hdr.a_data) == (caddr_t)-1)
-               fatal("Cannot map %s bss", path);
+               return NULL;
 
 #ifdef NEED_DEV_ZERO
        close(fd);
 #endif
 
        /* Assume _DYNAMIC is the first data item */
 
 #ifdef NEED_DEV_ZERO
        close(fd);
 #endif
 
        /* Assume _DYNAMIC is the first data item */
-       dp = (struct link_dynamic *)(addr+hdr.a_text);
+       dp = (struct _dynamic *)(addr+hdr.a_text);
 
        /* Fixup __DYNAMIC structure */
 
        /* Fixup __DYNAMIC structure */
-       (long)dp->ld_un.ld_2 += (long)addr;
-
-       alloc_link_map(path, lop, lmp, addr, dp);
+       (long)dp->d_un.d_sdt += (long)addr;
 
 
+       return alloc_link_map(path, sodp, smp, addr, dp);
 }
 
 }
 
-static void
-reloc_maps()
+static void inline
+check_text_reloc(r, smp, addr)
+struct relocation_info *r;
+struct so_map          *smp;
+caddr_t                        addr;
 {
 {
-       struct link_map         *lmp;
-
-       for (lmp = link_map_head; lmp; lmp = lmp->lm_next) {
-
-               struct link_dynamic     *dp = lmp->lm_ld;
-               struct relocation_info  *r = LM_REL(lmp);
-               struct relocation_info  *rend = r + LD_RELSZ(dp)/sizeof(*r);
-
-               if (LD_PLTSZ(dp))
-                       md_fix_jmpslot(LM_PLT(lmp),
-                                       (long)LM_PLT(lmp), (long)binder_entry);
-
-               for (; r < rend; r++) {
-                       char    *sym;
-                       caddr_t addr = lmp->lm_addr + r->r_address;
-
-                       check_text_reloc(r, lmp, addr);
+       char    *sym;
 
 
-                       if (RELOC_EXTERN_P(r)) {
-                               struct link_map *src_map = NULL;
-                               struct nzlist   *p, *np;
-                               long    relocation = md_get_addend(r, addr);
+       if (addr >= LM_ETEXT(smp))
+               return;
 
 
-                               if (RELOC_LAZY_P(r))
-                                       continue;
+       if (RELOC_EXTERN_P(r))
+               sym = LM_STRINGS(smp) +
+                               LM_SYMBOL(smp, RELOC_SYMBOL(r))->nz_strx;
+       else
+               sym = "";
 
 
-                               p = LM_SYMBOL(lmp,RELOC_SYMBOL(r));
-                               if (p->nz_type == (N_SETV + N_EXT))
-                                       src_map = lmp;
+       if (getenv("LD_WARN_NON_PURE_CODE") != NULL)
+               fprintf(stderr,
+                       "ld.so: warning: non pure code in %s at %x (%s)\n",
+                               smp->som_path, r->r_address, sym);
 
 
-                               sym = LM_STRINGS(lmp) + p->nz_strx;
+       if (smp->som_write == 0 &&
+               mprotect(smp->som_addr + LM_TXTADDR(smp),
+                               LD_TEXTSZ(smp->som_dynamic),
+                               PROT_READ|PROT_WRITE|PROT_EXEC) == -1) {
 
 
-                               np = lookup(sym, &src_map, 0/*XXX-jumpslots!*/);
-                               if (np == NULL)
-                                       fatal("Undefined symbol \"%s\" in %s\n",
-                                                       sym, lmp->lm_name);
+               perror("mprotect"),
+               fatal("Cannot enable writes to %s:%s\n",
+                                       main_progname, smp->som_path);
+       }
 
 
-                               /*
-                                * Found symbol definition.
-                                * If it's in a link map, adjust value
-                                * according to the load address of that map.
-                                * Otherwise it's a run-time allocated common
-                                * whose value is already up-to-date.
-                                */
-                               relocation += np->nz_value;
-                               if (src_map)
-                                       relocation += (long)src_map->lm_addr;
+       smp->som_write = 1;
+}
 
 
-                               if (RELOC_PCREL_P(r))
-                                       relocation -= (long)lmp->lm_addr;
+static void
+reloc_map(smp)
+       struct so_map           *smp;
+{
+       struct _dynamic         *dp = smp->som_dynamic;
+       struct relocation_info  *r = LM_REL(smp);
+       struct relocation_info  *rend = r + LD_RELSZ(dp)/sizeof(*r);
+       long                    symbolbase = (long)LM_SYMBOL(smp, 0);
+       char                    *stringbase = LM_STRINGS(smp);
+       int symsize             = LD_VERSION_NZLIST_P(dp->d_version) ?
+                                       sizeof(struct nzlist) :
+                                       sizeof(struct nlist);
+
+       if (LD_PLTSZ(dp))
+               md_fix_jmpslot(LM_PLT(smp),
+                               (long)LM_PLT(smp), (long)binder_entry);
+
+       for (; r < rend; r++) {
+               char    *sym;
+               caddr_t addr = smp->som_addr + r->r_address;
+
+               check_text_reloc(r, smp, addr);
+
+               if (RELOC_EXTERN_P(r)) {
+                       struct so_map   *src_map = NULL;
+                       struct nzlist   *p, *np;
+                       long    relocation = md_get_addend(r, addr);
+
+                       if (RELOC_LAZY_P(r))
+                               continue;
 
 
-                               if (RELOC_COPY_P(r) && src_map) {
-#if DEBUG
-xprintf("RELOCATE(%s) copy: from %s at %#x(%#x+%#x) to %s at %#x, reloc = %#x, size %d\n",
-lmp->lm_name, src_map->lm_name, src_map->lm_addr + np->nz_value,
-src_map->lm_addr, np->nz_value, sym, addr, relocation, np->nz_size);
-#endif
-                                       (void)enter_rts(sym,
-                                               (long)addr,
-                                               N_DATA + N_EXT,
-                                               src_map->lm_addr + np->nz_value,
-                                               np->nz_size);
-                                       continue;
-                               }
-#if DEBUG
-if (sym[2]=='_'&&(sym[3]=='C'||sym[3]=='D')&&sym[4]=='T')
-xprintf("RELOCATE(%s) external: %s at %#x, reloc = %#x in %s\n",
-lmp->lm_name, sym, addr, relocation, src_map?src_map->lm_name:"(NUL)");
-#endif
-                               md_relocate(r, relocation, addr, 0);
+                       p = (struct nzlist *)
+                               (symbolbase + symsize * RELOC_SYMBOL(r));
+
+                       if (p->nz_type == (N_SETV + N_EXT))
+                               src_map = smp;
+
+                       sym = stringbase + p->nz_strx;
+
+                       np = lookup(sym, &src_map, 0/*XXX-jumpslots!*/);
+                       if (np == NULL)
+                               fatal("Undefined symbol \"%s\" in %s:%s\n",
+                                       sym, main_progname, smp->som_path);
+
+                       /*
+                        * Found symbol definition.
+                        * If it's in a link map, adjust value
+                        * according to the load address of that map.
+                        * Otherwise it's a run-time allocated common
+                        * whose value is already up-to-date.
+                        */
+                       relocation += np->nz_value;
+                       if (src_map)
+                               relocation += (long)src_map->som_addr;
+
+                       if (RELOC_PCREL_P(r))
+                               relocation -= (long)smp->som_addr;
+
+                       if (RELOC_COPY_P(r) && src_map) {
+                               (void)enter_rts(sym,
+                                       (long)addr,
+                                       N_DATA + N_EXT,
+                                       src_map->som_addr + np->nz_value,
+                                       np->nz_size, src_map);
+                               continue;
+                       }
+                       md_relocate(r, relocation, addr, 0);
 
 
-                       } else {
-#if DEBUG
-xprintf("RELOCATE(%s) internal at %#x, reloc = %#x\n", lmp->lm_name, addr, md_get_rt_segment_addend(r,addr));
-#endif
-                               md_relocate(r,
+               } else {
+                       md_relocate(r,
 #ifdef SUN_COMPAT
 #ifdef SUN_COMPAT
-                                       md_get_rt_segment_addend(r, addr)
+                               md_get_rt_segment_addend(r, addr)
 #else
 #else
-                                       md_get_addend(r, addr)
+                               md_get_addend(r, addr)
 #endif
 #endif
-                                               + (long)lmp->lm_addr, addr, 0);
-                       }
-
+                                       + (long)smp->som_addr, addr, 0);
                }
 
                }
 
-               if (lmp->lm_rwt) {
-                       if (mprotect(lmp->lm_addr + LM_TXTADDR(lmp),
-                               LD_TEXTSZ(lmp->lm_ld),
+       }
+
+       if (smp->som_write) {
+               if (mprotect(smp->som_addr + LM_TXTADDR(smp),
+                               LD_TEXTSZ(smp->som_dynamic),
                                PROT_READ|PROT_EXEC) == -1) {
 
                                PROT_READ|PROT_EXEC) == -1) {
 
-                               perror("mprotect"),
-                               fatal("Cannot disable writes to %s\n", lmp->lm_name);
-                       }
-                       lmp->lm_rwt = 0;
+                       perror("mprotect"),
+                       fatal("Cannot disable writes to %s:%s\n",
+                                               main_progname, smp->som_path);
                }
                }
-
+               smp->som_write = 0;
        }
 }
 
 static void
        }
 }
 
 static void
-reloc_copy()
+reloc_copy(smp)
+       struct so_map           *smp;
 {
        struct rt_symbol        *rtsp;
 
        for (rtsp = rt_symbol_head; rtsp; rtsp = rtsp->rt_next)
 {
        struct rt_symbol        *rtsp;
 
        for (rtsp = rt_symbol_head; rtsp; rtsp = rtsp->rt_next)
-               if (rtsp->rt_sp->nz_type == N_DATA + N_EXT) {
-#ifdef DEBUG
-xprintf("reloc_copy: from %#x to %#x, size %d\n",
-rtsp->rt_srcaddr, rtsp->rt_sp->nz_value, rtsp->rt_sp->nz_size);
-#endif
+               if ((rtsp->rt_smp == NULL || rtsp->rt_smp == smp) &&
+                               rtsp->rt_sp->nz_type == N_DATA + N_EXT) {
                        bcopy(rtsp->rt_srcaddr, (caddr_t)rtsp->rt_sp->nz_value,
                                                        rtsp->rt_sp->nz_size);
                }
 }
 
 static void
                        bcopy(rtsp->rt_srcaddr, (caddr_t)rtsp->rt_sp->nz_value,
                                                        rtsp->rt_sp->nz_size);
                }
 }
 
 static void
-check_text_reloc(r, lmp, addr)
-struct relocation_info *r;
-struct link_map                *lmp;
-caddr_t                        addr;
+init_map(smp, sym)
+       struct so_map           *smp;
+       char                    *sym;
 {
 {
-       char    *sym;
+       struct so_map           *src_map = smp;
+       struct nzlist           *np;
 
 
-       if (addr >= LM_ETEXT(lmp))
-               return;
+       np = lookup(sym, &src_map, 1);
+       if (np)
+               (*(void (*)())(src_map->som_addr + np->nz_value))();
+}
 
 
-       if (RELOC_EXTERN_P(r))
-               sym = LM_STRINGS(lmp) +
-                               LM_SYMBOL(lmp, RELOC_SYMBOL(r))->nz_strx;
-       else
-               sym = "";
+/*
+ * Run-time common symbol table.
+ */
 
 
-#ifdef DEBUG
-       fprintf(stderr, "ld.so: warning: non pure code in %s at %x (%s)\n",
-                               lmp->lm_name, r->r_address, sym);
-#endif
+#define RTC_TABSIZE            57
+static struct rt_symbol        *rt_symtab[RTC_TABSIZE];
 
 
-       if (lmp->lm_rwt == 0 &&
-               mprotect(lmp->lm_addr + LM_TXTADDR(lmp),
-                               LD_TEXTSZ(lmp->lm_ld),
-                               PROT_READ|PROT_WRITE|PROT_EXEC) == -1) {
+/*
+ * Compute hash value for run-time symbol table
+ */
+       static int inline
+hash_string(key)
+       char *key;
+{
+       register char *cp;
+       register int k;
 
 
-               perror("mprotect"),
-               fatal("Cannot enable writes to %s\n", lmp->lm_name);
-       }
+       cp = key;
+       k = 0;
+       while (*cp)
+               k = (((k << 1) + (k >> 14)) ^ (*cp++)) & 0x3fff;
 
 
-       lmp->lm_rwt = 1;
+       return k;
 }
 
 }
 
-static void
-init_maps()
+/*
+ * Lookup KEY in the run-time common symbol table.
+ */
+
+       static inline struct rt_symbol *
+lookup_rts(key)
+       char *key;
 {
 {
-       struct link_map         *lmp, *src_map;
-       struct nzlist           *np;
-       void                    (*func)();
+       register int                    hashval;
+       register struct rt_symbol       *rtsp;
 
 
-       for (lmp = link_map_head; lmp; lmp = lmp->lm_next) {
-               src_map = lmp;
-               np = lookup("___init", &src_map, 1);
-#if DEBUG
-if (np)
-xprintf("Calling __init in %s at %#x\n", src_map->lm_name, np->nz_value+src_map->lm_addr);
-#endif
-               if (np) {
-                       func = (void (*)())(src_map->lm_addr + np->nz_value);
-                       (*func)();
-               }
-       }
+       /* Determine which bucket.  */
+
+       hashval = hash_string(key) % RTC_TABSIZE;
+
+       /* Search the bucket.  */
+
+       for (rtsp = rt_symtab[hashval]; rtsp; rtsp = rtsp->rt_link)
+               if (strcmp(key, rtsp->rt_sp->nz_name) == 0)
+                       return rtsp;
+
+       return NULL;
 }
 
 }
 
+       static struct rt_symbol *
+enter_rts(name, value, type, srcaddr, size, smp)
+       char            *name;
+       long            value;
+       int             type;
+       caddr_t         srcaddr;
+       long            size;
+       struct so_map   *smp;
+{
+       register int                    hashval;
+       register struct rt_symbol       *rtsp, **rpp;
+
+       /* Determine which bucket */
+       hashval = hash_string(name) % RTC_TABSIZE;
+
+       /* Find end of bucket */
+       for (rpp = &rt_symtab[hashval]; *rpp; rpp = &(*rpp)->rt_link)
+               ;
+
+       /* Allocate new common symbol */
+       rtsp = (struct rt_symbol *)malloc(sizeof(struct rt_symbol));
+       rtsp->rt_sp = (struct nzlist *)malloc(sizeof(struct nzlist));
+       rtsp->rt_sp->nz_name = strdup(name);
+       rtsp->rt_sp->nz_value = value;
+       rtsp->rt_sp->nz_type = type;
+       rtsp->rt_sp->nz_size = size;
+       rtsp->rt_srcaddr = srcaddr;
+       rtsp->rt_smp = smp;
+       rtsp->rt_link = NULL;
+
+       /* Link onto linear list as well */
+       rtsp->rt_next = rt_symbol_head;
+       rt_symbol_head = rtsp;
+
+       *rpp = rtsp;
+
+       return rtsp;
+}
+
+
 /*
  * Lookup NAME in the link maps. The link map producing a definition
  * is returned in SRC_MAP. If SRC_MAP is not NULL on entry the search is
  * confined to that map. If STRONG is set, the symbol returned must
  * have a proper type (used by binder()).
  */
 /*
  * Lookup NAME in the link maps. The link map producing a definition
  * is returned in SRC_MAP. If SRC_MAP is not NULL on entry the search is
  * confined to that map. If STRONG is set, the symbol returned must
  * have a proper type (used by binder()).
  */
-static struct nzlist *
+       static struct nzlist *
 lookup(name, src_map, strong)
 lookup(name, src_map, strong)
-char           *name;
-struct link_map        **src_map;      /* IN/OUT */
-int            strong;
+       char            *name;
+       struct so_map   **src_map;      /* IN/OUT */
+       int             strong;
 {
        long                    common_size = 0;
 {
        long                    common_size = 0;
-       struct link_map         *lmp;
+       struct so_map           *smp;
        struct rt_symbol        *rtsp;
 
        if ((rtsp = lookup_rts(name)) != NULL)
        struct rt_symbol        *rtsp;
 
        if ((rtsp = lookup_rts(name)) != NULL)
@@ -614,14 +782,23 @@ int               strong;
        /*
         * Search all maps for a definition of NAME
         */
        /*
         * Search all maps for a definition of NAME
         */
-       for (lmp = link_map_head; lmp; lmp = lmp->lm_next) {
-               int             buckets = LD_BUCKETS(lmp->lm_ld);
+       for (smp = link_map_head; smp; smp = smp->som_next) {
+               int             buckets = LD_BUCKETS(smp->som_dynamic);
                long            hashval = 0;
                struct rrs_hash *hp;
                char            *cp;
                struct  nzlist  *np;
 
                long            hashval = 0;
                struct rrs_hash *hp;
                char            *cp;
                struct  nzlist  *np;
 
-               if (*src_map && lmp != *src_map)
+               /* Some local caching */
+               long            symbolbase;
+               struct rrs_hash *hashbase;
+               char            *stringbase;
+               int             symsize;
+
+               if (LM_PRIVATE(smp)->spd_flags & RTLD_RTLD)
+                       continue;
+
+               if (*src_map && smp != *src_map)
                        continue;
 
                /*
                        continue;
 
                /*
@@ -632,20 +809,27 @@ int               strong;
 
                hashval = (hashval & 0x7fffffff) % buckets;
 
 
                hashval = (hashval & 0x7fffffff) % buckets;
 
-               hp = LM_HASH(lmp) + hashval;
+               hashbase = LM_HASH(smp);
+               hp = hashbase + hashval;
                if (hp->rh_symbolnum == -1)
                        /* Nothing in this bucket */
                        continue;
 
                if (hp->rh_symbolnum == -1)
                        /* Nothing in this bucket */
                        continue;
 
+               symbolbase = (long)LM_SYMBOL(smp, 0);
+               stringbase = LM_STRINGS(smp);
+               symsize = LD_VERSION_NZLIST_P(smp->som_dynamic->d_version)?
+                               sizeof(struct nzlist) :
+                               sizeof(struct nlist);
                while (hp) {
                while (hp) {
-                       np = LM_SYMBOL(lmp, hp->rh_symbolnum);
-                       cp = LM_STRINGS(lmp) + np->nz_strx;
+                       np = (struct nzlist *)
+                               (symbolbase + hp->rh_symbolnum * symsize);
+                       cp = stringbase + np->nz_strx;
                        if (strcmp(cp, name) == 0)
                                break;
                        if (hp->rh_next == 0)
                                hp = NULL;
                        else
                        if (strcmp(cp, name) == 0)
                                break;
                        if (hp->rh_next == 0)
                                hp = NULL;
                        else
-                               hp = LM_HASH(lmp) + hp->rh_next;
+                               hp = hashbase + hp->rh_next;
                }
                if (hp == NULL)
                        /* Nothing in this bucket */
                }
                if (hp == NULL)
                        /* Nothing in this bucket */
@@ -660,7 +844,7 @@ int         strong;
                        continue;
 
                if (np->nz_type == N_UNDF+N_EXT && np->nz_value != 0) {
                        continue;
 
                if (np->nz_type == N_UNDF+N_EXT && np->nz_value != 0) {
-                       if (np->nz_other == RRS_FUNC) {
+                       if (np->nz_other == AUX_FUNC) {
                                /* It's a weak function definition */
                                if (strong)
                                        continue;
                                /* It's a weak function definition */
                                if (strong)
                                        continue;
@@ -672,7 +856,7 @@ int         strong;
                        }
                }
 
                        }
                }
 
-               *src_map = lmp;
+               *src_map = smp;
                return np;
        }
 
                return np;
        }
 
@@ -684,7 +868,7 @@ int         strong;
         * It's a common, enter into run-time common symbol table.
         */
        rtsp = enter_rts(name, (long)calloc(1, common_size),
         * It's a common, enter into run-time common symbol table.
         */
        rtsp = enter_rts(name, (long)calloc(1, common_size),
-                                       N_UNDF + N_EXT, 0, common_size);
+                                       N_UNDF + N_EXT, 0, common_size, NULL);
 
 #if DEBUG
 xprintf("Allocating common: %s size %d at %#x\n", name, common_size, rtsp->rt_sp->nz_value);
 
 #if DEBUG
 xprintf("Allocating common: %s size %d at %#x\n", name, common_size, rtsp->rt_sp->nz_value);
@@ -698,11 +882,11 @@ xprintf("Allocating common: %s size %d at %#x\n", name, common_size, rtsp->rt_sp
  * This routine is called from the jumptable to resolve
  * procedure calls to shared objects.
  */
  * This routine is called from the jumptable to resolve
  * procedure calls to shared objects.
  */
-long
+       long
 binder(jsp)
 binder(jsp)
-jmpslot_t      *jsp;
+       jmpslot_t       *jsp;
 {
 {
-       struct link_map *lmp, *src_map = NULL;
+       struct so_map   *smp, *src_map = NULL;
        long            addr;
        char            *sym;
        struct nzlist   *np;
        long            addr;
        char            *sym;
        struct nzlist   *np;
@@ -711,133 +895,47 @@ jmpslot_t        *jsp;
        /*
         * Find the PLT map that contains JSP.
         */
        /*
         * Find the PLT map that contains JSP.
         */
-       for (lmp = link_map_head; lmp; lmp = lmp->lm_next) {
-               if (LM_PLT(lmp) < jsp &&
-                       jsp < LM_PLT(lmp) + LD_PLTSZ(lmp->lm_ld)/sizeof(*jsp))
+       for (smp = link_map_head; smp; smp = smp->som_next) {
+               if (LM_PLT(smp) < jsp &&
+                       jsp < LM_PLT(smp) + LD_PLTSZ(smp->som_dynamic)/sizeof(*jsp))
                        break;
        }
 
                        break;
        }
 
-       if (lmp == NULL)
+       if (smp == NULL)
                fatal("Call to binder from unknown location: %#x\n", jsp);
 
        index = jsp->reloc_index & JMPSLOT_RELOC_MASK;
 
        /* Get the local symbol this jmpslot refers to */
                fatal("Call to binder from unknown location: %#x\n", jsp);
 
        index = jsp->reloc_index & JMPSLOT_RELOC_MASK;
 
        /* Get the local symbol this jmpslot refers to */
-       sym = LM_STRINGS(lmp) +
-               LM_SYMBOL(lmp,RELOC_SYMBOL(&LM_REL(lmp)[index]))->nz_strx;
+       sym = LM_STRINGS(smp) +
+               LM_SYMBOL(smp,RELOC_SYMBOL(&LM_REL(smp)[index]))->nz_strx;
 
        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 at %#x", sym,
-                                                       lmp->lm_name, jsp);
+               fatal("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 */
        addr = np->nz_value;
        if (src_map)
 
        /* Fixup jmpslot so future calls transfer directly to target */
        addr = np->nz_value;
        if (src_map)
-               addr += (long)src_map->lm_addr;
+               addr += (long)src_map->som_addr;
 
        md_fix_jmpslot(jsp, (long)jsp, addr);
 
 #if DEBUG
 
        md_fix_jmpslot(jsp, (long)jsp, addr);
 
 #if DEBUG
-xprintf(" BINDER: %s located at = %#x in %s\n", sym, addr, src_map->lm_name);
+xprintf(" BINDER: %s located at = %#x in %s\n", sym, addr, src_map->som_path);
 #endif
        return addr;
 }
 
 
 #endif
        return addr;
 }
 
 
-/*
- * Run-time common symbol table.
- */
-
-#define RTC_TABSIZE            57
-static struct rt_symbol        *rt_symtab[RTC_TABSIZE];
-
-/*
- * Compute hash value for run-time symbol table
- */
-static int
-hash_string(key)
-       char *key;
-{
-       register char *cp;
-       register int k;
-
-       cp = key;
-       k = 0;
-       while (*cp)
-               k = (((k << 1) + (k >> 14)) ^ (*cp++)) & 0x3fff;
-
-       return k;
-}
-
-/*
- * Lookup KEY in the run-time common symbol table.
- */
-
-static struct rt_symbol *
-lookup_rts(key)
-       char *key;
-{
-       register int                    hashval;
-       register struct rt_symbol       *rtsp;
-
-       /* Determine which bucket.  */
-
-       hashval = hash_string(key) % RTC_TABSIZE;
-
-       /* Search the bucket.  */
-
-       for (rtsp = rt_symtab[hashval]; rtsp; rtsp = rtsp->rt_link)
-               if (strcmp(key, rtsp->rt_sp->nz_name) == 0)
-                       return rtsp;
-
-       return NULL;
-}
-
-static struct rt_symbol *
-enter_rts(name, value, type, srcaddr, size)
-       char    *name;
-       long    value;
-       int     type;
-       caddr_t srcaddr;
-       long    size;
-{
-       register int                    hashval;
-       register struct rt_symbol       *rtsp, **rpp;
-
-       /* Determine which bucket */
-       hashval = hash_string(name) % RTC_TABSIZE;
-
-       /* Find end of bucket */
-       for (rpp = &rt_symtab[hashval]; *rpp; rpp = &(*rpp)->rt_link)
-               ;
-
-       /* Allocate new common symbol */
-       rtsp = (struct rt_symbol *)malloc(sizeof(struct rt_symbol));
-       rtsp->rt_sp = (struct nzlist *)malloc(sizeof(struct nzlist));
-       rtsp->rt_sp->nz_name = strdup(name);
-       rtsp->rt_sp->nz_value = value;
-       rtsp->rt_sp->nz_type = type;
-       rtsp->rt_sp->nz_size = size;
-       rtsp->rt_srcaddr = srcaddr;
-       rtsp->rt_link = NULL;
-
-       /* Link onto linear list as well */
-       rtsp->rt_next = rt_symbol_head;
-       rt_symbol_head = rtsp;
-
-       *rpp = rtsp;
-
-       return rtsp;
-}
-
 static struct hints_header     *hheader;
 static struct hints_bucket     *hbuckets;
 static char                    *hstrtab;
 
 #define HINTS_VALID (hheader != NULL && hheader != (struct hints_header *)-1)
 
 static struct hints_header     *hheader;
 static struct hints_bucket     *hbuckets;
 static char                    *hstrtab;
 
 #define HINTS_VALID (hheader != NULL && hheader != (struct hints_header *)-1)
 
-static void
+       static void
 maphints()
 {
        caddr_t         addr;
 maphints()
 {
        caddr_t         addr;
@@ -886,10 +984,10 @@ maphints()
        hstrtab = (char *)(addr + hheader->hh_strtab);
 }
 
        hstrtab = (char *)(addr + hheader->hh_strtab);
 }
 
-int
+       int
 hinthash(cp, vmajor, vminor)
 hinthash(cp, vmajor, vminor)
-char   *cp;
-int    vmajor, vminor;
+       char    *cp;
+       int     vmajor, vminor;
 {
        int     k = 0;
 
 {
        int     k = 0;
 
@@ -905,11 +1003,11 @@ int      vmajor, vminor;
 #undef major
 #undef minor
 
 #undef major
 #undef minor
 
-static char *
+       static char *
 findhint(name, major, minor, preferred_path)
 findhint(name, major, minor, preferred_path)
-char   *name;
-int    major, minor;
-char   *preferred_path;
+       char    *name;
+       int     major, minor;
+       char    *preferred_path;
 {
        struct hints_bucket     *bp;
 
 {
        struct hints_bucket     *bp;
 
@@ -949,11 +1047,11 @@ char     *preferred_path;
        return NULL;
 }
 
        return NULL;
 }
 
-static char *
+       static char *
 rtfindlib(name, major, minor, usehints)
 rtfindlib(name, major, minor, usehints)
-char   *name;
-int    major, minor;
-int    *usehints;
+       char    *name;
+       int     major, minor;
+       int     *usehints;
 {
        char    *hint;
        char    *cp, *ld_path = getenv("LD_LIBRARY_PATH");
 {
        char    *hint;
        char    *cp, *ld_path = getenv("LD_LIBRARY_PATH");
@@ -988,29 +1086,131 @@ int     *usehints;
        return (char *)findshlib(name, &major, &minor, 0);
 }
 
        return (char *)findshlib(name, &major, &minor, 0);
 }
 
-static int
+static struct somap_private dlmap_private = {
+               0,
+               (struct so_map *)0,
+               0,
+#ifdef SUN_COMPAT
+               0,
+#endif
+};
+
+static struct so_map dlmap = {
+       (caddr_t)0,
+       "internal",
+       (struct so_map *)0,
+       (struct sod *)0,
+       (caddr_t)0,
+       (u_int)0,
+       (struct _dynamic *)0,
+       (caddr_t)&dlmap_private
+};
+static int dlerrno;
+
+       static void *
 dlopen(name, mode)
 dlopen(name, mode)
-char   *name;
-int    mode;
+       char    *name;
+       int     mode;
 {
 {
-       xprintf("dlopen(%s, %x)\n", name, mode);
-       return -1;
+       struct sod      *sodp;
+       struct so_map   *smp;
+
+       /*
+        * A NULL argument returns the current set of mapped objects.
+        */
+       if (name == NULL)
+               return link_map_head;
+
+       if ((sodp = (struct sod *)malloc(sizeof(struct sod))) == NULL) {
+               dlerrno = ENOMEM;
+               return NULL;
+       }
+
+       sodp->sod_name = (long)name;
+       sodp->sod_library = 0;
+       sodp->sod_major = sodp->sod_minor = 0;
+
+       if ((smp = map_object(sodp, &dlmap)) == NULL) {
+#ifdef DEBUG
+xprintf("%s: %s\n", name, strerror(errno));
+#endif
+               dlerrno = errno;
+               return NULL;
+       }
+       if (LM_PRIVATE(smp)->spd_refcount++ == 0) {
+               LM_PRIVATE(smp)->spd_flags |= RTLD_DL;
+               reloc_map(smp);
+               reloc_copy(smp);
+               init_map(smp, ".init");
+               init_map(smp, "_init");
+       }
+
+       return smp;
 }
 
 }
 
-static int
+       static int
 dlclose(fd)
 dlclose(fd)
-int    fd;
+       void    *fd;
 {
 {
-       xprintf("dlclose(%d)\n", fd);
-       return -1;
+       struct so_map   *smp = (struct so_map *)fd;
+
+#ifdef DEBUG
+xprintf("dlclose(%s): refcount = %d\n", smp->som_path, LM_PRIVATE(smp)->spd_refcount);
+#endif
+       if (--LM_PRIVATE(smp)->spd_refcount != 0)
+               return 0;
+
+       /* Dismantle shared object map and descriptor */
+       init_map(smp, "_fini");
+#if 0
+       unmap_object(smp);
+       free(smp->som_sod);
+       free(smp);
+#endif
+
+       return 0;
 }
 
 }
 
-static int
+       static void *
 dlsym(fd, sym)
 dlsym(fd, sym)
-int    fd;
-char   *sym;
+       void    *fd;
+       char    *sym;
 {
 {
-       xprintf("dlsym(%d, %s)\n", fd, sym);
+       struct so_map   *smp = (struct so_map *)fd, *src_map = NULL;
+       struct nzlist   *np;
+       long            addr;
+
+       /*
+        * Restrict search to passed map if dlopen()ed.
+        */
+       if (LM_PRIVATE(smp)->spd_flags & RTLD_DL)
+               src_map = smp;
+
+       np = lookup(sym, &src_map, 1);
+       if (np == NULL)
+               return NULL;
+
+       /* Fixup jmpslot so future calls transfer directly to target */
+       addr = np->nz_value;
+       if (src_map)
+               addr += (long)src_map->som_addr;
+
+       return (void *)addr;
+}
+
+       static int
+dlctl(fd, cmd, arg)
+       void    *fd, *arg;
+       int     cmd;
+{
+       switch (cmd) {
+       case DL_GETERRNO:
+               *(int *)arg = dlerrno;
+               return 0;
+       default:
+               dlerrno = EOPNOTSUPP;
+               return -1;
+       }
        return 0;
 }
 
        return 0;
 }
 
index 0bfc373..38ec051 100644 (file)
@@ -1,5 +1,33 @@
 /*
 /*
- * $Id: shlib.c,v 1.6 1993/12/11 11:58:29 jkh Exp $
+ * Copyright (c) 1993 Paul Kranenburg
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    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 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
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 $
  */
 
 #include <sys/param.h>
  */
 
 #include <sys/param.h>
@@ -25,14 +53,20 @@ 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"
+#define        STANDARD_SEARCH_DIRS    "/usr/lib", "/usr/X386/lib", "/usr/local/lib"
 #endif
 
 #endif
 
+/*
+ * Actual vector of library search directories,
+ * including `-L'ed and LD_LIBARAY_PATH spec'd ones.
+ */
+char    **search_dirs;
+int    n_search_dirs;
+
 char *standard_search_dirs[] = {
        STANDARD_SEARCH_DIRS
 };
 
 char *standard_search_dirs[] = {
        STANDARD_SEARCH_DIRS
 };
 
-int n_search_dirs;
 
 void
 add_search_dir(name)
 
 void
 add_search_dir(name)
index 3ae54e3..15281cc 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: md.c,v 1.6 1993/12/08 10:29:02 pk Exp $
+ *     $Id: md.c,v 1.6 1993/12/11 12:02:10 jkh Exp $
  */
 
 #include <sys/param.h>
  */
 
 #include <sys/param.h>
@@ -109,6 +109,7 @@ int                 relocatable_output;
 {
        register unsigned long  mask;
 
 {
        register unsigned long  mask;
 
+#ifndef RTLD
        if (relocatable_output) {
                /*
                 * Non-PC relative relocations which are absolute or
        if (relocatable_output) {
                /*
                 * Non-PC relative relocations which are absolute or
@@ -129,6 +130,7 @@ int                 relocatable_output;
                        RELOC_ADD_EXTRA(r) -= pc_relocation;
                return;
        }
                        RELOC_ADD_EXTRA(r) -= pc_relocation;
                return;
        }
+#endif
 
        relocation >>= RELOC_VALUE_RIGHTSHIFT(r);
 
 
        relocation >>= RELOC_VALUE_RIGHTSHIFT(r);
 
@@ -167,33 +169,7 @@ int                        relocatable_output;
        }
 }
 
        }
 }
 
-/*
- * Initialize (output) exec header such that useful values are
- * obtained from subsequent N_*() macro evaluations.
- */
-void
-md_init_header(hp, magic, flags)
-struct exec    *hp;
-int            magic, flags;
-{
-#ifdef NetBSD
-       N_SETMAGIC((*hp), magic, MID_MACHINE, flags);
-
-       /* TEXT_START depends on the value of outheader.a_entry.  */
-       if (!(link_mode & SHAREABLE)) /*WAS: if (entry_symbol) */
-               hp->a_entry = PAGSIZ;
-#else
-       hp->a_magic = magic;
-       hp->a_machtype = M_SPARC;
-       hp->a_toolversion = 1;
-       hp->a_dynamic = ((flags) & EX_DYNAMIC);
-
-       /* SunOS 4.1 N_TXTADDR depends on the value of outheader.a_entry.  */
-       if (!(link_mode & SHAREABLE)) /*WAS: if (entry_symbol) */
-               hp->a_entry = N_PAGSIZ(*hp);
-#endif
-}
-
+#ifndef RTLD
 /*
  * Machine dependent part of claim_rrs_reloc().
  * On the Sparc the relocation offsets are stored in the r_addend member.
 /*
  * Machine dependent part of claim_rrs_reloc().
  * On the Sparc the relocation offsets are stored in the r_addend member.
@@ -224,6 +200,7 @@ int                 type;
 
        return 1;
 }
 
        return 1;
 }
+#endif
 
 /*
  * Set up a transfer from jmpslot at OFFSET (relative to the PLT table)
 
 /*
  * Set up a transfer from jmpslot at OFFSET (relative to the PLT table)
@@ -327,3 +304,46 @@ long       *savep;
        *(long *)where = TRAP;
 }
 
        *(long *)where = TRAP;
 }
 
+#ifndef RTLD
+/*
+ * Initialize (output) exec header such that useful values are
+ * obtained from subsequent N_*() macro evaluations.
+ */
+void
+md_init_header(hp, magic, flags)
+struct exec    *hp;
+int            magic, flags;
+{
+#ifdef NetBSD
+       N_SETMAGIC((*hp), magic, MID_MACHINE, flags);
+
+       /* TEXT_START depends on the value of outheader.a_entry.  */
+       if (!(link_mode & SHAREABLE)) /*WAS: if (entry_symbol) */
+               hp->a_entry = PAGSIZ;
+#else
+       hp->a_magic = magic;
+       hp->a_machtype = M_SPARC;
+       hp->a_toolversion = 1;
+       hp->a_dynamic = ((flags) & EX_DYNAMIC);
+
+       /* SunOS 4.1 N_TXTADDR depends on the value of outheader.a_entry.  */
+       if (!(link_mode & SHAREABLE)) /*WAS: if (entry_symbol) */
+               hp->a_entry = N_PAGSIZ(*hp);
+#endif
+}
+
+/*
+ * Check for acceptable foreign machine Ids
+ */
+int
+md_midcompat(hp)
+struct exec *hp;
+{
+#ifdef NetBSD
+#define SUN_M_SPARC    3
+       return (((md_swap_long(hp->a_midmag)&0x00ff0000) >> 16) == SUN_M_SPARC);
+#else
+       return hp->a_machtype == M_SPARC;
+#endif
+}
+#endif /* RTLD */
index c3e9064..3545d97 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.3 1993/11/22 19:05:31 jkh Exp $
+ *     $Id: md.h,v 1.5 1993/12/02 01:03:47 jkh Exp $
  */
 
 /*
  */
 
 /*
                                        MID_MACHINE, N_GETFLAG(ex)|(f))
 #define N_IS_DYNAMIC(ex)       ((N_GETFLAG(ex) & EX_DYNAMIC))
 
                                        MID_MACHINE, N_GETFLAG(ex)|(f))
 #define N_IS_DYNAMIC(ex)       ((N_GETFLAG(ex) & EX_DYNAMIC))
 
+/*
+ * Should be handled by a.out.h ?
+ */
+#define N_ADJUST(ex)           (((ex).a_entry < PAGSIZ) ? -PAGSIZ : 0)
+#define TEXT_START(ex)         (N_TXTADDR(ex) + N_ADJUST(ex))
+#define DATA_START(ex)         (N_DATADDR(ex) + N_ADJUST(ex))
+
 #else
 
 /* Get the SunOS a.out and relocation nomenclature */
 #else
 
 /* Get the SunOS a.out and relocation nomenclature */
 #define r_symbolnum                    r_index
 #endif /* NetBSD */
 
 #define r_symbolnum                    r_index
 #endif /* NetBSD */
 
+#define N_BADMID(ex) \
+       (N_GETMID(ex) != 0 && N_GETMID(ex) != MID_MACHINE && \
+                                               !md_midcompat(&(ex)))
+
 /* Sparc (Sun 4) macros */
 #define RELOC_ADDRESS(r)               ((r)->r_address)
 #define RELOC_EXTERN_P(r)              ((r)->r_extern)
 /* Sparc (Sun 4) macros */
 #define RELOC_ADDRESS(r)               ((r)->r_address)
 #define RELOC_EXTERN_P(r)              ((r)->r_extern)
@@ -139,16 +150,16 @@ typedef struct jmpslot {
 #define md_swapout_zsymbols(s,n)
 #define md_swapin_reloc(r,n)
 #define md_swapout_reloc(r,n)
 #define md_swapout_zsymbols(s,n)
 #define md_swapin_reloc(r,n)
 #define md_swapout_reloc(r,n)
-#define md_swapin_link_dynamic(l)
-#define md_swapout_link_dynamic(l)
-#define md_swapin_link_dynamic_2(l)
-#define md_swapout_link_dynamic_2(l)
-#define md_swapin_ld_debug(d)
-#define md_swapout_ld_debug(d)
+#define md_swapin__dynamic(l)
+#define md_swapout__dynamic(l)
+#define md_swapin_section_dispatch_table(l)
+#define md_swapout_section_dispatch_table(l)
+#define md_swapin_so_debug(d)
+#define md_swapout_so_debug(d)
 #define md_swapin_rrs_hash(f,n)
 #define md_swapout_rrs_hash(f,n)
 #define md_swapin_rrs_hash(f,n)
 #define md_swapout_rrs_hash(f,n)
-#define md_swapin_link_object(l,n)
-#define md_swapout_link_object(l,n)
+#define md_swapin_sod(l,n)
+#define md_swapout_sod(l,n)
 #define md_swapout_jmpslot(j,n)
 #define md_swapout_got(g,n)
 #define md_swapin_ranlib_hdr(h,n)
 #define md_swapout_jmpslot(j,n)
 #define md_swapout_got(g,n)
 #define md_swapin_ranlib_hdr(h,n)
@@ -168,23 +179,23 @@ void      md_swapin_reloc __P((struct relocation_info *, int));
 void   md_swapout_reloc __P((struct relocation_info *, int));
 void   md_swapout_jmpslot __P((jmpslot_t *, int));
 
 void   md_swapout_reloc __P((struct relocation_info *, int));
 void   md_swapout_jmpslot __P((jmpslot_t *, int));
 
-#define md_swapin_symbols(s,n)         swap_symbols(s,n)
-#define md_swapout_symbols(s,n)                swap_symbols(s,n)
-#define md_swapin_zsymbols(s,n)                swap_zsymbols(s,n)
-#define md_swapout_zsymbols(s,n)       swap_zsymbols(s,n)
-#define md_swapin_link_dynamic(l)      swap_link_dynamic(l)
-#define md_swapout_link_dynamic(l)     swap_link_dynamic(l)
-#define md_swapin_link_dynamic_2(l)    swap_link_dynamic_2(l)
-#define md_swapout_link_dynamic_2(l)   swap_link_dynamic_2(l)
-#define md_swapin_ld_debug(d)          swap_ld_debug(d)
-#define md_swapout_ld_debug(d)         swap_ld_debug(d)
-#define md_swapin_rrs_hash(f,n)                swap_rrs_hash(f,n)
-#define md_swapout_rrs_hash(f,n)       swap_rrs_hash(f,n)
-#define md_swapin_link_object(l,n)     swapin_link_object(l,n)
-#define md_swapout_link_object(l,n)    swapout_link_object(l,n)
-#define md_swapout_got(g,n)            swap_longs((long*)(g),n)
-#define md_swapin_ranlib_hdr(h,n)      swap_ranlib_hdr(h,n)
-#define md_swapout_ranlib_hdr(h,n)     swap_ranlib_hdr(h,n)
+#define md_swapin_symbols(s,n)                 swap_symbols(s,n)
+#define md_swapout_symbols(s,n)                        swap_symbols(s,n)
+#define md_swapin_zsymbols(s,n)                        swap_zsymbols(s,n)
+#define md_swapout_zsymbols(s,n)               swap_zsymbols(s,n)
+#define md_swapin__dynamic(l)                  swap__dynamic(l)
+#define md_swapout__dynamic(l)                 swap__dynamic(l)
+#define md_swapin_section_dispatch_table(l)    swap_section_dispatch_table(l)
+#define md_swapout_section_dispatch_table(l)   swap_section_dispatch_table(l)
+#define md_swapin_so_debug(d)                  swap_so_debug(d)
+#define md_swapout_so_debug(d)                 swap_so_debug(d)
+#define md_swapin_rrs_hash(f,n)                        swap_rrs_hash(f,n)
+#define md_swapout_rrs_hash(f,n)               swap_rrs_hash(f,n)
+#define md_swapin_sod(l,n)                     swapin_sod(l,n)
+#define md_swapout_sod(l,n)                    swapout_sod(l,n)
+#define md_swapout_got(g,n)                    swap_longs((long*)(g),n)
+#define md_swapin_ranlib_hdr(h,n)              swap_ranlib_hdr(h,n)
+#define md_swapout_ranlib_hdr(h,n)             swap_ranlib_hdr(h,n)
 
 #define md_swap_short(x) ( (((x) >> 8) & 0xff) | (((x) & 0xff) << 8) )
 
 
 #define md_swap_short(x) ( (((x) >> 8) & 0xff) | (((x) & 0xff) << 8) )
 
index 8ad60b0..0d006d0 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.1 1993/10/16 21:54:36 pk Exp $
+ *     $Id: mdprologue.S,v 1.2 1993/11/09 04:19:36 paul Exp $
  */
 
 /*
  */
 
 /*
index d789a3a..af182a9 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: symbol.c,v 1.2 1993/11/09 04:19:04 paul Exp $          - symbol table routines
+ * $Id: symbol.c,v 1.3 1993/11/22 19:04:45 jkh Exp $           - symbol table routines
  */
 
 /* Create the symbol table entries for `etext', `edata' and `end'.  */
  */
 
 /* Create the symbol table entries for `etext', `edata' and `end'.  */
 
 #include "ld.h"
 
 
 #include "ld.h"
 
+symbol *symtab[SYMTABSIZE];    /* The symbol table. */
+int    num_hash_tab_syms;      /* Number of symbols in symbol hash table. */
+
+symbol *edata_symbol;          /* the symbol _edata */
+symbol *etext_symbol;          /* the symbol _etext */
+symbol *end_symbol;            /* the symbol _end */
+symbol *got_symbol;            /* the symbol __GLOBAL_OFFSET_TABLE_ */
+symbol *dynamic_symbol;        /* the symbol __DYNAMIC */
+
 void
 symtab_init (relocatable_output)
 int    relocatable_output;
 void
 symtab_init (relocatable_output)
 int    relocatable_output;
@@ -22,36 +31,40 @@ int relocatable_output;
        /*
         * Put linker reserved symbols into symbol table.
         */
        /*
         * Put linker reserved symbols into symbol table.
         */
+#ifndef nounderscore
+#define ETEXT_SYM      "_etext"
+#define EDATA_SYM      "_edata"
+#define END_SYM                "_end"
+#define DYN_SYM                "__DYNAMIC"
+#define GOT_SYM                "__GLOBAL_OFFSET_TABLE_"
+#else
+#define ETEXT_SYM      "etext"
+#define EDATA_SYM      "edata"
+#define END_SYM                "end"
+#define DYN_SYM                "_DYNAMIC"
+#define GOT_SYM                "_GLOBAL_OFFSET_TABLE_"
+#endif
 
 
-       dynamic_symbol = getsym ("__DYNAMIC");
+       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);
-       dynamic_symbol->referenced = 0;
-       dynamic_symbol->value = 0;
 
 
-       got_symbol = getsym ("__GLOBAL_OFFSET_TABLE_");
+       got_symbol = getsym (GOT_SYM);
        got_symbol->defined = N_DATA | N_EXT;
        got_symbol->defined = N_DATA | N_EXT;
-       got_symbol->referenced = 0;
-       got_symbol->value = 0;
 
        if (relocatable_output)
                return;
 
 
        if (relocatable_output)
                return;
 
-#ifndef nounderscore
-       edata_symbol = getsym ("_edata");
-       etext_symbol = getsym ("_etext");
-       end_symbol = getsym ("_end");
-#else
-       edata_symbol = getsym ("edata");
-       etext_symbol = getsym ("etext");
-       end_symbol = getsym ("end");
-#endif
-       edata_symbol->defined = N_DATA | N_EXT;
+       etext_symbol = getsym (ETEXT_SYM);
+       edata_symbol = getsym (EDATA_SYM);
+       end_symbol = getsym (END_SYM);
+
        etext_symbol->defined = N_TEXT | N_EXT;
        etext_symbol->defined = N_TEXT | N_EXT;
+       edata_symbol->defined = N_DATA | N_EXT;
        end_symbol->defined = N_BSS | N_EXT;
 
        end_symbol->defined = N_BSS | N_EXT;
 
-       edata_symbol->referenced = 1;
-       etext_symbol->referenced = 1;
-       end_symbol->referenced = 1;
+       etext_symbol->flags |= GS_REFERENCED;
+       edata_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.  */
@@ -82,7 +95,7 @@ getsym(key)
        register symbol *bp;
 
        /* Determine the proper bucket.  */
        register symbol *bp;
 
        /* Determine the proper bucket.  */
-       hashval = hash_string (key) % TABSIZE;
+       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)
@@ -91,17 +104,15 @@ getsym(key)
 
        /* Nothing was found; create a new symbol table entry.  */
        bp = (symbol *) xmalloc (sizeof (symbol));
 
        /* Nothing was found; create a new symbol table entry.  */
        bp = (symbol *) xmalloc (sizeof (symbol));
-       bp->refs = 0;
        bp->name = (char *) xmalloc (strlen (key) + 1);
        strcpy (bp->name, key);
        bp->name = (char *) xmalloc (strlen (key) + 1);
        strcpy (bp->name, key);
+       bp->refs = 0;
        bp->defined = 0;
        bp->defined = 0;
-       bp->referenced = 0;
-       bp->trace = 0;
        bp->value = 0;
        bp->value = 0;
-       bp->max_common_size = 0;
+       bp->common_size = 0;
        bp->warning = 0;
        bp->undef_refs = 0;
        bp->warning = 0;
        bp->undef_refs = 0;
-       bp->multiply_defined = 0;
+       bp->mult_defs = 0;
        bp->alias = 0;
        bp->setv_count = 0;
        bp->symbolnum = 0;
        bp->alias = 0;
        bp->setv_count = 0;
        bp->symbolnum = 0;
@@ -114,10 +125,7 @@ getsym(key)
        bp->def_nlist = 0;
        bp->jmpslot_offset = -1;
        bp->gotslot_offset = -1;
        bp->def_nlist = 0;
        bp->jmpslot_offset = -1;
        bp->gotslot_offset = -1;
-       bp->jmpslot_claimed = 0;
-       bp->gotslot_claimed = 0;
-       bp->cpyreloc_reserved = 0;
-       bp->cpyreloc_claimed = 0;
+       bp->flags = 0;
 
        /* Add the entry to the bucket.  */
        bp->link = symtab[hashval];
 
        /* Add the entry to the bucket.  */
        bp->link = symtab[hashval];
@@ -139,7 +147,7 @@ getsym_soft (key)
 
        /* Determine which bucket.  */
 
 
        /* Determine which bucket.  */
 
-       hashval = hash_string (key) % TABSIZE;
+       hashval = hash_string (key) % SYMTABSIZE;
 
        /* Search the bucket.  */
 
 
        /* Search the bucket.  */
 
index 210be24..d98516a 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: warnings.c,v 1.4 1993/12/22 23:28:12 jkh Exp $
+ * $Id: warnings.c,v 1.5 1994/01/12 23:14:07 jkh Exp $
  */
 
 #include <sys/param.h>
  */
 
 #include <sys/param.h>
@@ -47,6 +47,10 @@ print_file_name (entry, outfile)
      struct file_entry *entry;
      FILE *outfile;
 {
      struct file_entry *entry;
      FILE *outfile;
 {
+       if (entry == NULL) {
+               fprintf (outfile, "NULL");
+       }
+
        if (entry->superfile) {
                print_file_name (entry->superfile, outfile);
                fprintf (outfile, "(%s)", entry->filename);
        if (entry->superfile) {
                print_file_name (entry->superfile, outfile);
                fprintf (outfile, "(%s)", entry->filename);
@@ -65,7 +69,7 @@ get_file_name (entry)
        char *result, *supfile;
 
        if (entry == NULL) {
        char *result, *supfile;
 
        if (entry == NULL) {
-               return (xmalloc("NULL"));
+               return (char *)strdup("NULL");
        }
 
        if (entry->superfile) {
        }
 
        if (entry->superfile) {
@@ -155,30 +159,24 @@ void
 print_symbols(outfile)
        FILE           *outfile;
 {
 print_symbols(outfile)
        FILE           *outfile;
 {
-       register int    i;
-
        fprintf(outfile, "\nFiles:\n\n");
        fprintf(outfile, "\nFiles:\n\n");
-
        each_file(describe_file_sections, outfile);
 
        fprintf(outfile, "\nGlobal symbols:\n\n");
        each_file(describe_file_sections, outfile);
 
        fprintf(outfile, "\nGlobal symbols:\n\n");
-
-       for (i = 0; i < TABSIZE; i++) {
-               register symbol *sp;
-               for (sp = symtab[i]; sp; sp = sp->link) {
-                       if (sp->defined == (N_UNDF|N_EXT))
-                               fprintf(outfile, "  %s: common, length %#x\n",
-                                               sp->name, sp->max_common_size);
-                       if (!sp->referenced)
-                               fprintf(outfile, "  %s: unreferenced\n",
-                                                               sp->name);
-                       else if (!sp->defined)
-                               fprintf(outfile, "  %s: undefined\n", sp->name);
-                       else
-                               fprintf(outfile, "  %s: %#x, size %#x\n",
+       FOR_EACH_SYMBOL(i, sp) {
+               if (sp->defined == (N_UNDF|N_EXT))
+                       fprintf(outfile, "  %s: common, length %#x\n",
+                                               sp->name, sp->common_size);
+               if (!(sp->flags & GS_REFERENCED))
+                       fprintf(outfile, "  %s: unreferenced\n", sp->name);
+               else if (sp->so_defined)
+                       fprintf(outfile, "  %s: sodefined\n", sp->name);
+               else if (!sp->defined)
+                       fprintf(outfile, "  %s: undefined\n", sp->name);
+               else
+                       fprintf(outfile, "  %s: %#x, size %#x\n",
                                                sp->name, sp->value, sp->size);
                                                sp->name, sp->value, sp->size);
-               }
-       }
+       } END_EACH_SYMBOL;
 
        each_file(list_file_locals, outfile);
 }
 
        each_file(list_file_locals, outfile);
 }
@@ -190,7 +188,7 @@ describe_file_sections(entry, outfile)
 {
        fprintf(outfile, "  ");
        print_file_name(entry, outfile);
 {
        fprintf(outfile, "  ");
        print_file_name(entry, outfile);
-       if (entry->just_syms_flag || entry->is_dynamic)
+       if (entry->flags & (E_JUST_SYMS | E_DYNAMIC))
                fprintf(outfile, " symbols only\n", 0);
        else
                fprintf(outfile, " text %x(%x), data %x(%x), bss %x(%x) hex\n",
                fprintf(outfile, " symbols only\n", 0);
        else
                fprintf(outfile, " text %x(%x), data %x(%x), bss %x(%x) hex\n",
@@ -602,7 +600,7 @@ do_file_warnings (entry, outfile)
                read_entry_strings (desc, entry);
        }
 
                read_entry_strings (desc, entry);
        }
 
-       if (! entry->is_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 relocation info. */
                do_relocation_warnings (entry, 0, outfile, nlist_bitvector);
 
@@ -618,7 +616,7 @@ do_file_warnings (entry, outfile)
 
        for (i = 0; i < number_of_syms; i++) {
                struct nlist *s;
 
        for (i = 0; i < number_of_syms; i++) {
                struct nlist *s;
-               struct glosym *g;
+               symbol *g;
 
                g = entry->symbols[i].symbol;
                s = &entry->symbols[i].nzlist.nlist;
 
                g = entry->symbols[i].symbol;
                s = &entry->symbols[i].nzlist.nlist;
@@ -626,14 +624,14 @@ do_file_warnings (entry, outfile)
                if (!(s->n_type & N_EXT))
                        continue;
 
                if (!(s->n_type & N_EXT))
                        continue;
 
-               if (!g->referenced) {
+               if (!(g->flags & GS_REFERENCED)) {
 #if 0
                        /* Check for undefined shobj symbols */
                        struct localsymbol      *lsp;
                        register int            type;
 
 #if 0
                        /* Check for undefined shobj symbols */
                        struct localsymbol      *lsp;
                        register int            type;
 
-                       for (lsp = g->dynrefs; lsp; lsp = lsp->next) {
-                               type = lsp->nlist.n_type;
+                       for (lsp = g->sorefs; lsp; lsp = lsp->next) {
+                               type = lsp->nzlist.nz_type;
                                if ((type & N_EXT) &&
                                                type != (N_UNDF | N_EXT)) {
                                        break;
                                if ((type & N_EXT) &&
                                                type != (N_UNDF | N_EXT)) {
                                        break;
@@ -651,7 +649,7 @@ do_file_warnings (entry, outfile)
 
                dont_allow_symbol_name = 0;
 
 
                dont_allow_symbol_name = 0;
 
-               if (list_multiple_defs && g->multiply_defined) {
+               if (list_multiple_defs && g->mult_defs) {
                        errfmt = "Definition of symbol %s (multiply defined)";
                        switch (s->n_type) {
 
                        errfmt = "Definition of symbol %s (multiply defined)";
                        switch (s->n_type) {
 
@@ -669,13 +667,13 @@ do_file_warnings (entry, outfile)
                        case N_SETT | N_EXT:
                        case N_SETD | N_EXT:
                        case N_SETB | N_EXT:
                        case N_SETT | N_EXT:
                        case N_SETD | N_EXT:
                        case N_SETB | N_EXT:
-                               if (g->multiply_defined == 2)
+                               if (g->mult_defs == 2)
                                        continue;
                                errfmt = "First set element definition of symbol %s (multiply defined)";
                                break;
 
                        default:
                                        continue;
                                errfmt = "First set element definition of symbol %s (multiply defined)";
                                break;
 
                        default:
-printf("Multiple def: %s, type %#x\n", g->name, s->n_type);
+printf("multiply defined: %s, type %#x\n", g->name, s->n_type);
                                /* Don't print out multiple defs at references.*/
                                continue;
                        }
                                /* Don't print out multiple defs at references.*/
                                continue;
                        }
index 4f85db1..6374beb 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: xbits.c,v 1.1 1993/10/16 21:52:37 pk Exp $
+ *     $Id: xbits.c,v 1.2 1993/11/09 04:19:08 paul Exp $
  */
 
 /*
  */
 
 /*
@@ -96,60 +96,61 @@ int n;
 }
 
 void
 }
 
 void
-swap_link_dynamic(dp)
-struct link_dynamic *dp;
+swap__dynamic(dp)
+struct _dynamic *dp;
 {
 {
-       dp->ld_version = md_swap_long(dp->ld_version);
-       dp->ldd = (struct ld_debug *)md_swap_long((long)dp->ldd);
-       dp->ld_un.ld_2 = (struct link_dynamic_2 *)md_swap_long((long)dp->ld_un.ld_2);
-       dp->ld_entry = (struct ld_entry *)md_swap_long((long)dp->ld_entry);
+       dp->d_version = md_swap_long(dp->d_version);
+       dp->d_debug = (struct so_debug *)md_swap_long((long)dp->d_debug);
+       dp->d_un.d_sdt = (struct section_dispatch_table *)
+                               md_swap_long((long)dp->d_un.d_sdt);
+       dp->d_entry = (struct ld_entry *)md_swap_long((long)dp->d_entry);
 }
 
 void
 }
 
 void
-swap_link_dynamic_2(ldp)
-struct link_dynamic_2 *ldp;
+swap_section_dispatch_table(sdp)
+struct section_dispatch_table *sdp;
 {
 {
-       swap_longs((long *)ldp, sizeof(*ldp)/sizeof(long));
+       swap_longs((long *)sdp, sizeof(*sdp)/sizeof(long));
 }
 
 void
 }
 
 void
-swap_ld_debug(lddp)
-struct ld_debug        *lddp;
+swap_so_debug(ddp)
+struct so_debug        *ddp;
 {
 {
-       swap_longs((long *)lddp, sizeof(*lddp)/sizeof(long));
+       swap_longs((long *)ddp, sizeof(*ddp)/sizeof(long));
 }
 
 void
 }
 
 void
-swapin_link_object(lop, n)
-struct link_object *lop;
+swapin_sod(sodp, n)
+struct sod *sodp;
 int n;
 {
        unsigned long   bits;
 
 int n;
 {
        unsigned long   bits;
 
-       for (; n; n--, lop++) {
-               lop->lo_name = md_swap_long(lop->lo_name);
-               lop->lo_major = md_swap_short(lop->lo_major);
-               lop->lo_minor = md_swap_short(lop->lo_minor);
-               lop->lo_next = md_swap_long(lop->lo_next);
-               bits = ((unsigned long *)lop)[1];
-               lop->lo_library = ((bits >> 24) & 1);
+       for (; n; n--, sodp++) {
+               sodp->sod_name = md_swap_long(sodp->sod_name);
+               sodp->sod_major = md_swap_short(sodp->sod_major);
+               sodp->sod_minor = md_swap_short(sodp->sod_minor);
+               sodp->sod_next = md_swap_long(sodp->sod_next);
+               bits = ((unsigned long *)sodp)[1];
+               sodp->sod_library = ((bits >> 24) & 1);
        }
 }
 
 void
        }
 }
 
 void
-swapout_link_object(lop, n)
-struct link_object *lop;
+swapout_sod(sodp, n)
+struct sod *sodp;
 int n;
 {
        unsigned long   bits;
 
 int n;
 {
        unsigned long   bits;
 
-       for (; n; n--, lop++) {
-               lop->lo_name = md_swap_long(lop->lo_name);
-               lop->lo_major = md_swap_short(lop->lo_major);
-               lop->lo_minor = md_swap_short(lop->lo_minor);
-               lop->lo_next = md_swap_long(lop->lo_next);
-               bits = (unsigned long)(lop->lo_library) << 24;
-               ((unsigned long *)lop)[1] = bits;
+       for (; n; n--, sodp++) {
+               sodp->sod_name = md_swap_long(sodp->sod_name);
+               sodp->sod_major = md_swap_short(sodp->sod_major);
+               sodp->sod_minor = md_swap_short(sodp->sod_minor);
+               sodp->sod_next = md_swap_long(sodp->sod_next);
+               bits = (unsigned long)(sodp->sod_library) << 24;
+               ((unsigned long *)sodp)[1] = bits;
        }
 }
 
        }
 }