summaryrefslogtreecommitdiff
path: root/gnu/usr.bin
diff options
context:
space:
mode:
authorpk <pk@NetBSD.org>1994-01-28 20:56:09 +0000
committerpk <pk@NetBSD.org>1994-01-28 20:56:09 +0000
commit90cfba21cbdf9695f8edcf1db5affea1d7b5d5e3 (patch)
treecd7fba84949d25348d2ae81ededa0c6426fa6db1 /gnu/usr.bin
parent64075b6a06a77715d7a55b25d58a2e4d547c832b (diff)
Use `.type' directives generated by gcc.
Numerous internal changes & bug fixes. NOTE: must re-compile & re-link shared libraries before used to link programs.
Diffstat (limited to 'gnu/usr.bin')
-rw-r--r--gnu/usr.bin/ld/arch/i386/md.c54
-rw-r--r--gnu/usr.bin/ld/arch/i386/md.h84
-rw-r--r--gnu/usr.bin/ld/arch/m68k/md.c44
-rw-r--r--gnu/usr.bin/ld/arch/m68k/md.h55
-rw-r--r--gnu/usr.bin/ld/common/etc.c54
-rw-r--r--gnu/usr.bin/ld/common/ld.h630
-rw-r--r--gnu/usr.bin/ld/common/shlib.c38
-rw-r--r--gnu/usr.bin/ld/etc.c54
-rw-r--r--gnu/usr.bin/ld/i386/md.c54
-rw-r--r--gnu/usr.bin/ld/i386/md.h84
-rw-r--r--gnu/usr.bin/ld/ld.131
-rw-r--r--gnu/usr.bin/ld/ld.c888
-rw-r--r--gnu/usr.bin/ld/ld.h630
-rw-r--r--gnu/usr.bin/ld/ld/ld.131
-rw-r--r--gnu/usr.bin/ld/ld/ld.c888
-rw-r--r--gnu/usr.bin/ld/ld/lib.c229
-rw-r--r--gnu/usr.bin/ld/ld/rrs.c254
-rw-r--r--gnu/usr.bin/ld/ld/symbol.c70
-rw-r--r--gnu/usr.bin/ld/ld/warnings.c50
-rw-r--r--gnu/usr.bin/ld/ld/xbits.c63
-rw-r--r--gnu/usr.bin/ld/lib.c229
-rw-r--r--gnu/usr.bin/ld/m68k/md.c44
-rw-r--r--gnu/usr.bin/ld/m68k/md.h55
-rw-r--r--gnu/usr.bin/ld/rrs.c254
-rw-r--r--gnu/usr.bin/ld/shlib.c38
-rw-r--r--gnu/usr.bin/ld/symbol.c70
-rw-r--r--gnu/usr.bin/ld/warnings.c50
-rw-r--r--gnu/usr.bin/ld/xbits.c63
28 files changed, 2550 insertions, 2538 deletions
diff --git a/gnu/usr.bin/ld/arch/i386/md.c b/gnu/usr.bin/ld/arch/i386/md.c
index 1b561a48919..17d6add2f99 100644
--- a/gnu/usr.bin/ld/arch/i386/md.c
+++ b/gnu/usr.bin/ld/arch/i386/md.c
@@ -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.
*
- * $Id: md.c,v 1.6 1993/12/08 10:14:46 pk Exp $
+ * $Id: md.c,v 1.7 1994/01/28 20:57:08 pk Exp $
*/
#include <sys/param.h>
@@ -88,25 +88,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 (oldmagic)
- hp->a_midmag = oldmagic;
- 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.
*/
@@ -245,8 +226,39 @@ long *savep;
*(char *)where = TRAP;
}
-#ifdef NEED_SWAP
+#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
+ if (oldmagic || magic == QMAGIC)
+ hp->a_midmag = magic;
+ else
+ N_SETMAGIC((*hp), magic, MID_I386, flags);
+#endif
+#ifdef FreeBSD
+ if (oldmagic && number_of_shobjs != 0)
+ hp->a_midmag = magic;
+ else if (magic == ZMAGIC)
+ 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.
*/
diff --git a/gnu/usr.bin/ld/arch/i386/md.h b/gnu/usr.bin/ld/arch/i386/md.h
index 285b0e6a82b..182c86fcefb 100644
--- a/gnu/usr.bin/ld/arch/i386/md.h
+++ b/gnu/usr.bin/ld/arch/i386/md.h
@@ -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.
*
- * $Id: md.h,v 1.5 1993/12/08 10:14:48 pk Exp $
+ * $Id: md.h,v 1.6 1994/01/28 20:57:10 pk Exp $
*/
@@ -45,11 +45,39 @@
#define PAGSIZ 4096
#endif
-#define N_SET_FLAG(ex,f) N_SETMAGIC(ex,N_GETMAGIC(ex), MID_MACHINE, \
- N_GETFLAG(ex)|(f))
+#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))
+#endif
+
+#ifdef FreeBSD
+
+#define N_SET_FLAG(ex,f) (oldmagic ? (0) : \
+ (N_GETMAGIC(ex)==QMAGIC ? \
+ 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) ))
+#endif
+
+#define N_BADMID(ex) \
+ (N_GETMID(ex) != 0 && N_GETMID(ex) != MID_MACHINE)
+
/*
* Should be handled by a.out.h ?
*/
@@ -94,16 +122,16 @@ typedef struct jmpslot {
#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_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)
@@ -123,23 +151,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));
-#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) )
diff --git a/gnu/usr.bin/ld/arch/m68k/md.c b/gnu/usr.bin/ld/arch/m68k/md.c
index c8210369345..c2b8921c09f 100644
--- a/gnu/usr.bin/ld/arch/m68k/md.c
+++ b/gnu/usr.bin/ld/arch/m68k/md.c
@@ -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.
*
- * $Id: md.c,v 1.1 1993/11/25 00:57:37 paulus Exp $
+ * $Id: md.c,v 1.2 1994/01/28 20:57:31 pk Exp $
*/
#include <sys/param.h>
@@ -88,25 +88,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 (oldmagic)
- hp->a_midmag = oldmagic;
- else
- 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;
-}
-
-/*
* Machine dependent part of claim_rrs_reloc().
* Set RRS relocation type.
*/
@@ -237,8 +218,29 @@ long *savep;
*(short *)where = BPT;
}
-#ifdef NEED_SWAP
+#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;
+{
+ if (oldmagic)
+ hp->a_midmag = oldmagic;
+ else
+ N_SETMAGIC((*hp), magic, MID_MACHINE, flags);
+ /* TEXT_START depends on the value of outheader.a_entry. */
+ if (!(link_mode & SHAREABLE))
+ hp->a_entry = PAGSIZ;
+}
+#endif /* RTLD */
+
+
+#ifdef NEED_SWAP
/*
* Byte swap routines for cross-linking.
*/
diff --git a/gnu/usr.bin/ld/arch/m68k/md.h b/gnu/usr.bin/ld/arch/m68k/md.h
index d9f7b7e6777..63d9f03b11a 100644
--- a/gnu/usr.bin/ld/arch/m68k/md.h
+++ b/gnu/usr.bin/ld/arch/m68k/md.h
@@ -1,5 +1,5 @@
/*
- * $Id: md.h,v 1.1 1993/11/25 00:57:38 paulus Exp $
+ * $Id: md.h,v 1.2 1994/01/28 20:57:34 pk Exp $
* - m68k dependent definitions
*/
@@ -16,6 +16,9 @@
#define N_IS_DYNAMIC(ex) ((N_GETFLAG(ex) & EX_DYNAMIC))
+#define N_BADMID(ex) \
+ (N_GETMID(ex) != 0 && N_GETMID(ex) != MID_MACHINE)
+
/*
* Should be handled by a.out.h ?
*/
@@ -60,16 +63,16 @@ typedef struct jmpslot {
#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_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)
@@ -116,23 +119,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));
-#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_link_object(l,n)
+#define md_swapout_sod(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_swap_short(x) ( (((x) >> 8) & 0xff) | (((x) & 0xff) << 8) )
diff --git a/gnu/usr.bin/ld/common/etc.c b/gnu/usr.bin/ld/common/etc.c
index 6062dcbed22..22e8adf6b5d 100644
--- a/gnu/usr.bin/ld/common/etc.c
+++ b/gnu/usr.bin/ld/common/etc.c
@@ -1,5 +1,5 @@
/*
- * $Id: etc.c,v 1.4 1993/12/08 10:13:50 pk Exp $
+ * $Id: etc.c,v 1.5 1994/01/28 20:56:09 pk Exp $
*/
#include <sys/param.h>
@@ -48,6 +48,7 @@ error(fmt, va_alist)
va_end(ap);
}
+void (*fatal_cleanup_hook)__P((void));
/*
* Report a fatal error.
*/
@@ -72,8 +73,8 @@ fatal(fmt, va_alist)
(void)fprintf(stderr, "\n");
va_end(ap);
- if (outdesc > 0)
- unlink(output_filename);
+ if (fatal_cleanup_hook)
+ (*fatal_cleanup_hook)();
exit(1);
}
@@ -148,50 +149,3 @@ xrealloc(ptr, size)
return result;
}
-
-
-
-/* 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
diff --git a/gnu/usr.bin/ld/common/ld.h b/gnu/usr.bin/ld/common/ld.h
index 803fd3116c1..eda50b3371f 100644
--- a/gnu/usr.bin/ld/common/ld.h
+++ b/gnu/usr.bin/ld/common/ld.h
@@ -1,5 +1,5 @@
/*
- * $Id: ld.h,v 1.7 1993/12/08 10:13:59 pk 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
@@ -43,24 +43,19 @@
/* 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. */
+char *progname;
-char *progname;
-
/* System dependencies */
/* Define this to specify the default executable format. */
#ifndef DEFAULT_MAGIC
+#ifdef FreeBSD
+#define DEFAULT_MAGIC QMAGIC
+#else
#define DEFAULT_MAGIC ZMAGIC
#endif
-
-#ifdef QMAGIC
-int oldmagic;
#endif
@@ -185,7 +180,7 @@ int oldmagic;
#ifndef DATA_START
#define DATA_START(x) N_DATADDR(x)
#endif
-
+
/* 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.
@@ -334,6 +329,22 @@ int oldmagic;
#endif /* not __GNU_STAB__ */
+
+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 */
/*
@@ -344,225 +355,102 @@ int oldmagic;
*/
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 */
- 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 */
-#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; \
- 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 }}
-/* 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 */
-
/*
* Each input file, and each library member ("subfile") being loaded, has a
* `file_entry' structure for it.
@@ -577,160 +465,82 @@ symbol *dynamic_symbol; /* the symbol __DYNAMIC */
*/
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.
*/
- 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 */
-
- /*
- * 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.
- */
- 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;
-
- /*
- * 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.
- */
- 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
+ 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) */
/*
- * Offset in bytes in the output file symbol table of the first local
- * symbol for this file. Set by `write_file_symbols'.
+ * Next two used only if `relocatable_output' or if needed for
+ * output of undefined reference line numbers.
*/
- 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;
+ struct relocation_info *textrel; /* Text relocations */
+ int ntextrel; /* # of text relocations */
+ struct relocation_info *datarel; /* Data relocations */
+ int ndatarel; /* # of data relocations */
/*
- * For a library member, offset of the member within the archive.
- * Zero for files that are not library members.
+ * Relation of this file's segments to the output file.
*/
- 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
- /* 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
-
- /* 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).
@@ -739,115 +549,57 @@ int link_mode;
* 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
-
-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) */
-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 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 *));
@@ -921,10 +673,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_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
diff --git a/gnu/usr.bin/ld/common/shlib.c b/gnu/usr.bin/ld/common/shlib.c
index fc34000ac42..4f6a207a603 100644
--- a/gnu/usr.bin/ld/common/shlib.c
+++ b/gnu/usr.bin/ld/common/shlib.c
@@ -1,5 +1,33 @@
/*
- * $Id: shlib.c,v 1.7 1993/12/08 10:14:04 pk 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 withough 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.8 1994/01/28 20:56:36 pk Exp $
*/
#include <sys/param.h>
@@ -28,11 +56,17 @@ char *strsep();
#define STANDARD_SEARCH_DIRS "/usr/lib", "/usr/X386/lib", "/usr/local/lib"
#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
};
-int n_search_dirs;
void
add_search_dir(name)
diff --git a/gnu/usr.bin/ld/etc.c b/gnu/usr.bin/ld/etc.c
index 6062dcbed22..22e8adf6b5d 100644
--- a/gnu/usr.bin/ld/etc.c
+++ b/gnu/usr.bin/ld/etc.c
@@ -1,5 +1,5 @@
/*
- * $Id: etc.c,v 1.4 1993/12/08 10:13:50 pk Exp $
+ * $Id: etc.c,v 1.5 1994/01/28 20:56:09 pk Exp $
*/
#include <sys/param.h>
@@ -48,6 +48,7 @@ error(fmt, va_alist)
va_end(ap);
}
+void (*fatal_cleanup_hook)__P((void));
/*
* Report a fatal error.
*/
@@ -72,8 +73,8 @@ fatal(fmt, va_alist)
(void)fprintf(stderr, "\n");
va_end(ap);
- if (outdesc > 0)
- unlink(output_filename);
+ if (fatal_cleanup_hook)
+ (*fatal_cleanup_hook)();
exit(1);
}
@@ -148,50 +149,3 @@ xrealloc(ptr, size)
return result;
}
-
-
-
-/* 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
diff --git a/gnu/usr.bin/ld/i386/md.c b/gnu/usr.bin/ld/i386/md.c
index 1b561a48919..17d6add2f99 100644
--- a/gnu/usr.bin/ld/i386/md.c
+++ b/gnu/usr.bin/ld/i386/md.c
@@ -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.
*
- * $Id: md.c,v 1.6 1993/12/08 10:14:46 pk Exp $
+ * $Id: md.c,v 1.7 1994/01/28 20:57:08 pk Exp $
*/
#include <sys/param.h>
@@ -88,25 +88,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 (oldmagic)
- hp->a_midmag = oldmagic;
- 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.
*/
@@ -245,8 +226,39 @@ long *savep;
*(char *)where = TRAP;
}
-#ifdef NEED_SWAP
+#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
+ if (oldmagic || magic == QMAGIC)
+ hp->a_midmag = magic;
+ else
+ N_SETMAGIC((*hp), magic, MID_I386, flags);
+#endif
+#ifdef FreeBSD
+ if (oldmagic && number_of_shobjs != 0)
+ hp->a_midmag = magic;
+ else if (magic == ZMAGIC)
+ 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.
*/
diff --git a/gnu/usr.bin/ld/i386/md.h b/gnu/usr.bin/ld/i386/md.h
index 285b0e6a82b..182c86fcefb 100644
--- a/gnu/usr.bin/ld/i386/md.h
+++ b/gnu/usr.bin/ld/i386/md.h
@@ -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.
*
- * $Id: md.h,v 1.5 1993/12/08 10:14:48 pk Exp $
+ * $Id: md.h,v 1.6 1994/01/28 20:57:10 pk Exp $
*/
@@ -45,11 +45,39 @@
#define PAGSIZ 4096
#endif
-#define N_SET_FLAG(ex,f) N_SETMAGIC(ex,N_GETMAGIC(ex), MID_MACHINE, \
- N_GETFLAG(ex)|(f))
+#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))
+#endif
+
+#ifdef FreeBSD
+
+#define N_SET_FLAG(ex,f) (oldmagic ? (0) : \
+ (N_GETMAGIC(ex)==QMAGIC ? \
+ 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) ))
+#endif
+
+#define N_BADMID(ex) \
+ (N_GETMID(ex) != 0 && N_GETMID(ex) != MID_MACHINE)
+
/*
* Should be handled by a.out.h ?
*/
@@ -94,16 +122,16 @@ typedef struct jmpslot {
#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_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)
@@ -123,23 +151,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));
-#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) )
diff --git a/gnu/usr.bin/ld/ld.1 b/gnu/usr.bin/ld/ld.1
index a41714ebb7d..24d9774e34c 100644
--- a/gnu/usr.bin/ld/ld.1
+++ b/gnu/usr.bin/ld/ld.1
@@ -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.
.\"
-.\" $Id: ld.1,v 1.3 1993/11/02 22:56:51 pk Exp $
+.\" $Id: ld.1,v 1.4 1994/01/28 20:56:11 pk Exp $
.\"
.Dd October 14, 1993
.Dt LD 8
@@ -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 \-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
@@ -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
-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.
@@ -103,6 +103,11 @@ Force all members of archives to be loaded, whether or not such members
contribute a definition to any plain object files. Useful for making a
shared library from an archive of PIC objects without having to unpack
the archive.
+.It Fl B Ar silly
+Search for
+.Em \.sa
+silly archive companions of shared objects. Useful for compatibility with
+version 3 shared objects.
.It Fl D Ar data-size
Set the size of the data segment. For sanity's sake, this should be larger
than the cumulative data sizes of the input files.
@@ -142,6 +147,8 @@ Produce a NMAGIC output file.
.It Fl o Ar filename
Specifies the name of the output file. Defaults to
.Dq a.out.
+.It Fl Q
+Produce a QMAGIC output file.
.It Fl r
Produce relocatable object file, suitable for another pass through
.Nm ld.
@@ -168,7 +175,7 @@ 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.
-.It Fl y symbol
+.It Fl y Ar symbol
Trace the manipulations inflicted on
.Ar symbol
.It Fl z
@@ -177,15 +184,21 @@ Make a ZMAGIC output file. This is the default.
.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 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
diff --git a/gnu/usr.bin/ld/ld.c b/gnu/usr.bin/ld/ld.c
index 71037941b01..e607ab81b8b 100644
--- a/gnu/usr.bin/ld/ld.c
+++ b/gnu/usr.bin/ld/ld.c
@@ -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. */
/*
- * $Id: ld.c,v 1.18 1994/01/06 00:20:47 pk Exp $
+ * $Id: ld.c,v 1.19 1994/01/28 20:56:17 pk Exp $
*/
/* 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"
-#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;
-/* 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 */
@@ -81,9 +82,72 @@ int force_alias_definition;
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;
+/* 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.
@@ -100,11 +164,33 @@ enum {
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. */
+
+struct string_list_element *set_element_prefixes;
-/* Magic number to use for the output file, set by switch. */
-int magic;
+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.
@@ -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 load_symbols __P((void));
static void enter_global_ref __P((struct localsymbol *,
char *, struct file_entry *));
static void digest_symbols __P((void));
@@ -152,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 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 myfatal __P((void));
+
int
main(argc, argv)
@@ -190,6 +285,7 @@ main(argc, argv)
data_pad = 0;
text_pad = 0;
+ page_align_segments = 0;
page_align_data = 0;
/* Initialize the data about options. */
@@ -252,6 +348,9 @@ main(argc, argv)
* 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);
@@ -431,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;
- 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->search_dirs_flag = 1;
+ p->flags |= E_SEARCH_DIRS;
if (link_mode & DYNAMIC && !relocatable_output)
- p->search_dynamic_flag = 1;
+ p->flags |= E_SEARCH_DYNAMIC;
p++;
}
i += code - 1;
@@ -447,8 +546,8 @@ decode_command(argc, argv)
/* 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. */
@@ -457,9 +556,9 @@ decode_command(argc, argv)
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;
@@ -475,7 +574,7 @@ add_cmdline_ref(sp)
ptr = cmdline_references + diff;
}
*ptr++ = sp;
- *ptr = (struct glosym *) 0;
+ *ptr = (symbol *) 0;
}
int
@@ -506,7 +605,6 @@ static void
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"))
@@ -559,9 +657,10 @@ decode_option(swt, 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++;
- entry_symbol->referenced = 1;
+ entry_symbol->flags |= GS_REFERENCED;
add_cmdline_ref(entry_symbol);
return;
@@ -580,20 +679,9 @@ decode_option(swt, arg)
magic = OMAGIC;
return;
-#ifdef NMAGIC
case 'n':
magic = NMAGIC;
return;
-#endif
-
-#ifdef QMAGIC
- case 'Q':
- magic = oldmagic = QMAGIC;
- return;
- case 'Z':
- magic = oldmagic = ZMAGIC;
- return;
-#endif
case 'o':
output_filename = arg;
@@ -603,6 +691,12 @@ decode_option(swt, arg)
page_align_data = 1;
return;
+#ifdef QMAGIC
+ case 'Q':
+ magic = QMAGIC;
+ return;
+#endif
+
case 'r':
relocatable_output = 1;
magic = OMAGIC;
@@ -630,9 +724,9 @@ decode_option(swt, arg)
{
register symbol *sp = getsym(arg);
- if (!sp->defined && !sp->referenced)
+ if (!sp->defined && !(sp->flags & GS_REFERENCED))
undefined_global_sym_count++;
- sp->referenced = 1;
+ sp->flags |= GS_REFERENCED;
add_cmdline_ref(sp);
}
return;
@@ -654,12 +748,17 @@ decode_option(swt, arg)
case 'y':
{
register symbol *sp = getsym(&swt[2]);
- sp->trace = 1;
+ sp->flags |= GS_TRACE;
}
return;
case 'z':
magic = ZMAGIC;
+ oldmagic = 0;
+ return;
+
+ case 'Z':
+ magic = oldmagic = ZMAGIC;
return;
default:
@@ -688,15 +787,15 @@ each_file(function, arg)
register struct file_entry *entry = &file_table[i];
register struct file_entry *subentry;
- if (entry->scrapped)
+ if (entry->flags & E_SCRAPPED)
continue;
- if (!entry->library_flag)
+ if (!(entry->flags & E_IS_LIBRARY))
(*function) (entry, arg);
subentry = entry->subfiles;
for (; subentry; subentry = subentry->chain) {
- if (subentry->scrapped)
+ if (subentry->flags & E_SCRAPPED)
continue;
(*function) (subentry, arg);
}
@@ -704,15 +803,15 @@ each_file(function, arg)
#ifdef SUN_COMPAT
if (entry->silly_archive) {
- if (!entry->is_dynamic)
+ if (!(entry->flags & E_DYNAMIC))
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) {
- if (subentry->scrapped)
+ if (subentry->flags & E_SCRAPPED)
continue;
(*function) (subentry, arg);
}
@@ -740,12 +839,12 @@ check_each_file(function, arg)
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;
- if (entry->library_flag) {
+ if (entry->flags & E_IS_LIBRARY) {
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;
@@ -769,35 +868,35 @@ each_full_file(function, arg)
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) {
- if (!entry->is_dynamic)
+ if (!(entry->flags & E_DYNAMIC))
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) {
- if (subentry->scrapped)
+ if (subentry->flags & E_SCRAPPED)
continue;
(*function) (subentry, arg);
}
}
#endif
- if (entry->is_dynamic)
+ if (entry->flags & E_DYNAMIC)
continue;
- if (!entry->library_flag)
+ if (!(entry->flags & E_IS_LIBRARY))
(*function) (entry, arg);
subentry = entry->subfiles;
for (; subentry; subentry = subentry->chain) {
- if (subentry->scrapped)
+ if (subentry->flags & E_SCRAPPED)
continue;
(*function) (subentry, arg);
}
@@ -826,7 +925,7 @@ file_open (entry)
{
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)
@@ -834,7 +933,7 @@ file_open (entry)
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);
@@ -855,8 +954,8 @@ text_offset (entry)
{
return entry->starting_offset + N_TXTOFF (entry->header);
}
-
-/* Medium-level input routines for rel files. */
+
+/*---------------------------------------------------------------------------*/
/*
* Read a file's header into the proper place in the file_entry. DESC is the
@@ -867,8 +966,7 @@ read_header (desc, 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)
@@ -880,10 +978,13 @@ read_header (desc, entry)
md_swapin_exec_hdr(&entry->header);
- if (N_BADMAG (*loc))
+ if (N_BADMAG (entry->header))
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;
}
/*
@@ -901,7 +1002,7 @@ read_entry_symbols (desc, entry)
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);
@@ -923,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].entry = entry;
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) +
@@ -951,7 +1050,7 @@ read_entry_strings (desc, entry)
{
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);
@@ -965,14 +1064,6 @@ read_entry_strings (desc, entry)
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
@@ -1028,23 +1119,24 @@ read_entry_relocation (desc, entry)
}
}
-
-/* Read in the symbols of all input files. */
+/*---------------------------------------------------------------------------*/
-
-void
+/*
+ * Read in the symbols of all input files.
+ */
+static void
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");
}
/*
@@ -1070,18 +1162,18 @@ read_file_symbols (entry)
md_swapin_exec_hdr(&hdr);
if (!N_BADMAG (hdr)) {
- if (N_IS_DYNAMIC(hdr) && !entry->just_syms_flag) {
+ 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;
}
- entry->is_dynamic = 1;
+ entry->flags |= E_DYNAMIC;
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);
@@ -1098,14 +1190,17 @@ read_file_symbols (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 ();
}
-
-/* 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)
@@ -1162,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)
- lsp->is_L_symbol = 1;
+ lsp->flags |= LS_L_SYMBOL;
}
}
@@ -1192,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;
- int oldref = sp->referenced;
+ int oldref = (sp->flags & GS_REFERENCED);
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);
@@ -1210,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;
@@ -1225,11 +1320,17 @@ enter_global_ref (lsp, name, entry)
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;
- } 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;
}
/*
@@ -1246,10 +1347,10 @@ enter_global_ref (lsp, name, entry)
sp->refs = lsp;
lsp->symbol = sp;
- sp->referenced = 1;
+ sp->flags |= GS_REFERENCED;
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;
@@ -1283,33 +1384,38 @@ enter_global_ref (lsp, name, entry)
* 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--;
- sp->max_common_size = 0;
+ sp->common_size = 0;
} 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.
*/
- sp->max_common_size = nzp->nz_value;
+ sp->common_size = nzp->nz_value;
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++;
- 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;
- if (sp->trace) {
+ if (sp->flags & GS_TRACE) {
register char *reftype;
switch (type & N_TYPE) {
case N_UNDF:
@@ -1345,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.
*/
@@ -1393,7 +1499,6 @@ contains_symbol (entry, np)
*
*/
-
static void
digest_symbols ()
{
@@ -1441,7 +1546,7 @@ digest_symbols ()
* the padding in the text segment size.
*/
- if (magic == ZMAGIC || 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;
@@ -1494,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 (magic == ZMAGIC)
+ if (page_align_segments)
data_pad = PALIGN(data_pad + data_size, page_size) - data_size;
bss_size -= data_pad;
@@ -1510,10 +1615,10 @@ printf("bssstart = %#x, bsssize = %#x\n",
global_sym_count = defined_global_sym_count +
undefined_global_sym_count;
- if (dynamic_symbol->referenced)
+ if (dynamic_symbol->flags & GS_REFERENCED)
global_sym_count++;
- if (got_symbol->referenced)
+ if (got_symbol->flags & GS_REFERENCED)
global_sym_count++;
if (relocatable_output || building_shared_object)
@@ -1533,12 +1638,15 @@ debug symbols: %d, set_symbols %d\n",
#endif
}
+/*
+ * Determine the definition of each global symbol.
+ */
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.
*
@@ -1550,7 +1658,7 @@ digest_pass1()
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;
@@ -1584,7 +1692,7 @@ digest_pass1()
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 */
@@ -1608,12 +1716,14 @@ digest_pass1()
&& (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;
+ lsp->entry->flags |= E_SYMBOLS_USED;
sp->defined = type;
+ sp->aux = N_AUX(p);
}
}
@@ -1655,15 +1765,17 @@ digest_pass1()
&& (type & N_TYPE) != N_FN) {
/* non-common definition */
sp->def_nlist = p;
+ lsp->entry->flags |= E_SYMBOLS_USED;
sp->so_defined = type;
- if (sp->referenced)
+ sp->aux = N_AUX(p);
+ if (sp->flags & GS_REFERENCED)
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
- if (sp->alias && !sp->alias->referenced) {
+ if (sp->alias && !(sp->alias->flags & GS_REFERENCED)) {
sp = sp->alias;
goto again;
}
@@ -1678,161 +1790,10 @@ doesn't match actual (%d)",
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, *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;
-
- /*
- * 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;
-
- 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);
- }
- }
-
- /*
- * Reverse the vector.
- */
- 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;
- }
-
-
- 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)
@@ -1860,7 +1821,7 @@ consider_relocation (entry, dataseg)
if (RELOC_BASEREL_P(reloc)) {
pic_code_seen = 1;
if (!RELOC_EXTERN_P(reloc))
- lsp->rename = 1;
+ lsp->flags |= LS_RENAME;
}
continue;
}
@@ -1951,39 +1912,20 @@ consider_relocation (entry, dataseg)
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);
-#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;
- } else if (!sp->defined && sp->max_common_size == 0)
+ } else if (!sp->defined && sp->common_size == 0)
alloc_rrs_reloc(entry, sp);
} else {
@@ -2000,6 +1942,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.
*/
@@ -2084,68 +2096,155 @@ printf("%s: datastart: %#x, bss %#x\n", get_file_name(entry),
}
+/*
+ * Assign a value to each global symbol.
+ */
static void
-consider_local_symbols(entry)
- register struct file_entry *entry;
+digest_pass2()
{
- register struct localsymbol *lsp, *lspend;
+ FOR_EACH_SYMBOL(i, sp) {
+ int size;
+ int align = sizeof(int);
- if (entry->is_dynamic)
- return;
+ if (!(sp->flags & GS_REFERENCED))
+ continue;
- lspend = entry->symbols + entry->nsymbols;
+ 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++;
- /*
- * For each symbol determine whether it should go
- * in the output symbol table.
- */
+ 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);
- for (lsp = entry->symbols; lsp < lspend; lsp++) {
- register struct nlist *p = &lsp->nzlist.nlist;
- register int type = p->n_type;
+ /* Relocate symbol value */
+ sp->value += set_sect_start;
- if (type == N_WARNING)
- continue;
+ set_vectors[length_word_index] = sp->setv_count;
- if (SET_ELEMENT_P (type)) {
/*
- * This occurs even if global. These types of
- * symbols are never written globally, though
- * they are stored globally.
+ * Relocate vector to final address.
*/
- lsp->write = relocatable_output;
+ for (i = 0; i < sp->setv_count; i++) {
+ struct nlist *p = (struct nlist *)
+ set_vectors[1+i+length_word_index];
- } else if (!(type & (N_STAB | 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);
+ }
+ }
/*
- * Ordinary local symbol
+ * Reverse the vector.
*/
- lsp->write = (lsp->rename || (
- discard_locals != DISCARD_ALL &&
- !(discard_locals == DISCARD_L &&
- lsp->is_L_symbol)));
- if (lsp->write)
- local_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;
+ }
- } else if (!(type & N_EXT)) {
+ /* 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 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) {
/*
- * Debugger symbol
+ * It's a common.
*/
- lsp->write = (strip_symbols == STRIP_NONE);
- if (lsp->write)
- debugger_sym_count++;
+ 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;
}
- }
- /*
- * 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++;
+ /*
+ * 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;
}
@@ -2167,6 +2266,8 @@ write_output ()
if (outdesc < 0)
perror_name (output_filename);
+ fatal_cleanup_hook = myfatal;
+
if (fstat (outdesc, &statbuf) < 0)
perror_name (output_filename);
@@ -2205,10 +2306,10 @@ write_header ()
{
int flags = (rrs_section_type == RRS_FULL) ? EX_DYNAMIC : 0;
-#ifdef QMAGIC
- if (!oldmagic)
-#endif
- N_SET_FLAG (outheader, flags);
+ if (oldmagic && (flags & EX_DYNAMIC))
+ error("Cannot set flag in old magic headers\n");
+
+ N_SET_FLAG (outheader, flags);
outheader.a_text = text_size;
outheader.a_data = data_size;
@@ -2371,7 +2472,7 @@ copy_data (entry)
mywrite (bytes, 1, entry->header.a_data, outdesc);
}
-
+
/*
* 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
@@ -2379,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.
*/
+
+/* HACK: md.c may need access to this */
+int pc_relocation;
+
void
perform_relocation(data, data_size, reloc, nreloc, entry, dataseg)
char *data;
@@ -2388,12 +2493,13 @@ perform_relocation(data, data_size, reloc, nreloc, entry, 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:
@@ -2648,10 +2754,10 @@ write_rel ()
/* 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) {
- if (sp != dynamic_symbol && sp->referenced) {
+ if (sp != dynamic_symbol && (sp->flags & GS_REFERENCED)) {
sp->symbolnum = count++;
if (sp->size)
count++;
@@ -2696,7 +2802,7 @@ assign_symbolnums(entry, countp)
n++;
for (lsp = entry->symbols; lsp < lspend; lsp++) {
- if (lsp->write)
+ if (lsp->flags & LS_WRITE)
lsp->symbolnum = n++;
}
*countp = n;
@@ -2826,7 +2932,7 @@ copdatrel(entry)
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)) {
@@ -2971,7 +3077,7 @@ write_syms()
* 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;
@@ -2993,7 +3099,7 @@ write_syms()
/* Already dealt with above */
continue;
- if (!sp->referenced)
+ if (!(sp->flags & GS_REFERENCED))
/* Came from shared object but was not used */
continue;
@@ -3041,6 +3147,7 @@ write_syms()
*/
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;
@@ -3051,9 +3158,10 @@ write_syms()
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
@@ -3064,7 +3172,7 @@ write_syms()
* 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;
@@ -3085,6 +3193,9 @@ write_syms()
*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");
@@ -3098,6 +3209,9 @@ write_syms()
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);
@@ -3176,7 +3290,7 @@ write_file_syms(entry, syms_written_addr)
register struct nlist *bufp = buf;
- if (entry->is_dynamic)
+ if (entry->flags & E_DYNAMIC)
return;
/*
@@ -3200,9 +3314,6 @@ write_file_syms(entry, 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. */
@@ -3217,12 +3328,12 @@ write_file_syms(entry, syms_written_addr)
register int write = 0;
char *name;
- if (! lsp->write)
+ if (!(lsp->flags & LS_WRITE))
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;
@@ -3261,3 +3372,50 @@ write_file_syms(entry, syms_written_addr)
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);
+}
diff --git a/gnu/usr.bin/ld/ld.h b/gnu/usr.bin/ld/ld.h
index 803fd3116c1..eda50b3371f 100644
--- a/gnu/usr.bin/ld/ld.h
+++ b/gnu/usr.bin/ld/ld.h
@@ -1,5 +1,5 @@
/*
- * $Id: ld.h,v 1.7 1993/12/08 10:13:59 pk 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
@@ -43,24 +43,19 @@
/* 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. */
+char *progname;
-char *progname;
-
/* System dependencies */
/* Define this to specify the default executable format. */
#ifndef DEFAULT_MAGIC
+#ifdef FreeBSD
+#define DEFAULT_MAGIC QMAGIC
+#else
#define DEFAULT_MAGIC ZMAGIC
#endif
-
-#ifdef QMAGIC
-int oldmagic;
#endif
@@ -185,7 +180,7 @@ int oldmagic;
#ifndef DATA_START
#define DATA_START(x) N_DATADDR(x)
#endif
-
+
/* 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.
@@ -334,6 +329,22 @@ int oldmagic;
#endif /* not __GNU_STAB__ */
+
+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 */
/*
@@ -344,225 +355,102 @@ int oldmagic;
*/
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 */
- 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 */
-#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; \
- 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 }}
-/* 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 */
-
/*
* Each input file, and each library member ("subfile") being loaded, has a
* `file_entry' structure for it.
@@ -577,160 +465,82 @@ symbol *dynamic_symbol; /* the symbol __DYNAMIC */
*/
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.
*/
- 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 */
-
- /*
- * 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.
- */
- 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;
-
- /*
- * 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.
- */
- 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
+ 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) */
/*
- * Offset in bytes in the output file symbol table of the first local
- * symbol for this file. Set by `write_file_symbols'.
+ * Next two used only if `relocatable_output' or if needed for
+ * output of undefined reference line numbers.
*/
- 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;
+ struct relocation_info *textrel; /* Text relocations */
+ int ntextrel; /* # of text relocations */
+ struct relocation_info *datarel; /* Data relocations */
+ int ndatarel; /* # of data relocations */
/*
- * For a library member, offset of the member within the archive.
- * Zero for files that are not library members.
+ * Relation of this file's segments to the output file.
*/
- 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
- /* 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
-
- /* 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).
@@ -739,115 +549,57 @@ int link_mode;
* 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
-
-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) */
-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 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 *));
@@ -921,10 +673,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_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
diff --git a/gnu/usr.bin/ld/ld/ld.1 b/gnu/usr.bin/ld/ld/ld.1
index a41714ebb7d..24d9774e34c 100644
--- a/gnu/usr.bin/ld/ld/ld.1
+++ b/gnu/usr.bin/ld/ld/ld.1
@@ -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.
.\"
-.\" $Id: ld.1,v 1.3 1993/11/02 22:56:51 pk Exp $
+.\" $Id: ld.1,v 1.4 1994/01/28 20:56:11 pk Exp $
.\"
.Dd October 14, 1993
.Dt LD 8
@@ -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 \-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
@@ -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
-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.
@@ -103,6 +103,11 @@ Force all members of archives to be loaded, whether or not such members
contribute a definition to any plain object files. Useful for making a
shared library from an archive of PIC objects without having to unpack
the archive.
+.It Fl B Ar silly
+Search for
+.Em \.sa
+silly archive companions of shared objects. Useful for compatibility with
+version 3 shared objects.
.It Fl D Ar data-size
Set the size of the data segment. For sanity's sake, this should be larger
than the cumulative data sizes of the input files.
@@ -142,6 +147,8 @@ Produce a NMAGIC output file.
.It Fl o Ar filename
Specifies the name of the output file. Defaults to
.Dq a.out.
+.It Fl Q
+Produce a QMAGIC output file.
.It Fl r
Produce relocatable object file, suitable for another pass through
.Nm ld.
@@ -168,7 +175,7 @@ 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.
-.It Fl y symbol
+.It Fl y Ar symbol
Trace the manipulations inflicted on
.Ar symbol
.It Fl z
@@ -177,15 +184,21 @@ Make a ZMAGIC output file. This is the default.
.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 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
diff --git a/gnu/usr.bin/ld/ld/ld.c b/gnu/usr.bin/ld/ld/ld.c
index 71037941b01..e607ab81b8b 100644
--- a/gnu/usr.bin/ld/ld/ld.c
+++ b/gnu/usr.bin/ld/ld/ld.c
@@ -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. */
/*
- * $Id: ld.c,v 1.18 1994/01/06 00:20:47 pk Exp $
+ * $Id: ld.c,v 1.19 1994/01/28 20:56:17 pk Exp $
*/
/* 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"
-#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;
-/* 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 */
@@ -81,9 +82,72 @@ int force_alias_definition;
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;
+/* 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.
@@ -100,11 +164,33 @@ enum {
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. */
+
+struct string_list_element *set_element_prefixes;
-/* Magic number to use for the output file, set by switch. */
-int magic;
+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.
@@ -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 load_symbols __P((void));
static void enter_global_ref __P((struct localsymbol *,
char *, struct file_entry *));
static void digest_symbols __P((void));
@@ -152,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 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 myfatal __P((void));
+
int
main(argc, argv)
@@ -190,6 +285,7 @@ main(argc, argv)
data_pad = 0;
text_pad = 0;
+ page_align_segments = 0;
page_align_data = 0;
/* Initialize the data about options. */
@@ -252,6 +348,9 @@ main(argc, argv)
* 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);
@@ -431,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;
- 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->search_dirs_flag = 1;
+ p->flags |= E_SEARCH_DIRS;
if (link_mode & DYNAMIC && !relocatable_output)
- p->search_dynamic_flag = 1;
+ p->flags |= E_SEARCH_DYNAMIC;
p++;
}
i += code - 1;
@@ -447,8 +546,8 @@ decode_command(argc, argv)
/* 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. */
@@ -457,9 +556,9 @@ decode_command(argc, argv)
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;
@@ -475,7 +574,7 @@ add_cmdline_ref(sp)
ptr = cmdline_references + diff;
}
*ptr++ = sp;
- *ptr = (struct glosym *) 0;
+ *ptr = (symbol *) 0;
}
int
@@ -506,7 +605,6 @@ static void
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"))
@@ -559,9 +657,10 @@ decode_option(swt, 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++;
- entry_symbol->referenced = 1;
+ entry_symbol->flags |= GS_REFERENCED;
add_cmdline_ref(entry_symbol);
return;
@@ -580,20 +679,9 @@ decode_option(swt, arg)
magic = OMAGIC;
return;
-#ifdef NMAGIC
case 'n':
magic = NMAGIC;
return;
-#endif
-
-#ifdef QMAGIC
- case 'Q':
- magic = oldmagic = QMAGIC;
- return;
- case 'Z':
- magic = oldmagic = ZMAGIC;
- return;
-#endif
case 'o':
output_filename = arg;
@@ -603,6 +691,12 @@ decode_option(swt, arg)
page_align_data = 1;
return;
+#ifdef QMAGIC
+ case 'Q':
+ magic = QMAGIC;
+ return;
+#endif
+
case 'r':
relocatable_output = 1;
magic = OMAGIC;
@@ -630,9 +724,9 @@ decode_option(swt, arg)
{
register symbol *sp = getsym(arg);
- if (!sp->defined && !sp->referenced)
+ if (!sp->defined && !(sp->flags & GS_REFERENCED))
undefined_global_sym_count++;
- sp->referenced = 1;
+ sp->flags |= GS_REFERENCED;
add_cmdline_ref(sp);
}
return;
@@ -654,12 +748,17 @@ decode_option(swt, arg)
case 'y':
{
register symbol *sp = getsym(&swt[2]);
- sp->trace = 1;
+ sp->flags |= GS_TRACE;
}
return;
case 'z':
magic = ZMAGIC;
+ oldmagic = 0;
+ return;
+
+ case 'Z':
+ magic = oldmagic = ZMAGIC;
return;
default:
@@ -688,15 +787,15 @@ each_file(function, arg)
register struct file_entry *entry = &file_table[i];
register struct file_entry *subentry;
- if (entry->scrapped)
+ if (entry->flags & E_SCRAPPED)
continue;
- if (!entry->library_flag)
+ if (!(entry->flags & E_IS_LIBRARY))
(*function) (entry, arg);
subentry = entry->subfiles;
for (; subentry; subentry = subentry->chain) {
- if (subentry->scrapped)
+ if (subentry->flags & E_SCRAPPED)
continue;
(*function) (subentry, arg);
}
@@ -704,15 +803,15 @@ each_file(function, arg)
#ifdef SUN_COMPAT
if (entry->silly_archive) {
- if (!entry->is_dynamic)
+ if (!(entry->flags & E_DYNAMIC))
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) {
- if (subentry->scrapped)
+ if (subentry->flags & E_SCRAPPED)
continue;
(*function) (subentry, arg);
}
@@ -740,12 +839,12 @@ check_each_file(function, arg)
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;
- if (entry->library_flag) {
+ if (entry->flags & E_IS_LIBRARY) {
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;
@@ -769,35 +868,35 @@ each_full_file(function, arg)
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) {
- if (!entry->is_dynamic)
+ if (!(entry->flags & E_DYNAMIC))
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) {
- if (subentry->scrapped)
+ if (subentry->flags & E_SCRAPPED)
continue;
(*function) (subentry, arg);
}
}
#endif
- if (entry->is_dynamic)
+ if (entry->flags & E_DYNAMIC)
continue;
- if (!entry->library_flag)
+ if (!(entry->flags & E_IS_LIBRARY))
(*function) (entry, arg);
subentry = entry->subfiles;
for (; subentry; subentry = subentry->chain) {
- if (subentry->scrapped)
+ if (subentry->flags & E_SCRAPPED)
continue;
(*function) (subentry, arg);
}
@@ -826,7 +925,7 @@ file_open (entry)
{
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)
@@ -834,7 +933,7 @@ file_open (entry)
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);
@@ -855,8 +954,8 @@ text_offset (entry)
{
return entry->starting_offset + N_TXTOFF (entry->header);
}
-
-/* Medium-level input routines for rel files. */
+
+/*---------------------------------------------------------------------------*/
/*
* Read a file's header into the proper place in the file_entry. DESC is the
@@ -867,8 +966,7 @@ read_header (desc, 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)
@@ -880,10 +978,13 @@ read_header (desc, entry)
md_swapin_exec_hdr(&entry->header);
- if (N_BADMAG (*loc))
+ if (N_BADMAG (entry->header))
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;
}
/*
@@ -901,7 +1002,7 @@ read_entry_symbols (desc, entry)
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);
@@ -923,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].entry = entry;
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) +
@@ -951,7 +1050,7 @@ read_entry_strings (desc, entry)
{
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);
@@ -965,14 +1064,6 @@ read_entry_strings (desc, entry)
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
@@ -1028,23 +1119,24 @@ read_entry_relocation (desc, entry)
}
}
-
-/* Read in the symbols of all input files. */
+/*---------------------------------------------------------------------------*/
-
-void
+/*
+ * Read in the symbols of all input files.
+ */
+static void
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");
}
/*
@@ -1070,18 +1162,18 @@ read_file_symbols (entry)
md_swapin_exec_hdr(&hdr);
if (!N_BADMAG (hdr)) {
- if (N_IS_DYNAMIC(hdr) && !entry->just_syms_flag) {
+ 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;
}
- entry->is_dynamic = 1;
+ entry->flags |= E_DYNAMIC;
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);
@@ -1098,14 +1190,17 @@ read_file_symbols (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 ();
}
-
-/* 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)
@@ -1162,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)
- lsp->is_L_symbol = 1;
+ lsp->flags |= LS_L_SYMBOL;
}
}
@@ -1192,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;
- int oldref = sp->referenced;
+ int oldref = (sp->flags & GS_REFERENCED);
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);
@@ -1210,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;
@@ -1225,11 +1320,17 @@ enter_global_ref (lsp, name, entry)
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;
- } 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;
}
/*
@@ -1246,10 +1347,10 @@ enter_global_ref (lsp, name, entry)
sp->refs = lsp;
lsp->symbol = sp;
- sp->referenced = 1;
+ sp->flags |= GS_REFERENCED;
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;
@@ -1283,33 +1384,38 @@ enter_global_ref (lsp, name, entry)
* 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--;
- sp->max_common_size = 0;
+ sp->common_size = 0;
} 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.
*/
- sp->max_common_size = nzp->nz_value;
+ sp->common_size = nzp->nz_value;
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++;
- 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;
- if (sp->trace) {
+ if (sp->flags & GS_TRACE) {
register char *reftype;
switch (type & N_TYPE) {
case N_UNDF:
@@ -1345,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.
*/
@@ -1393,7 +1499,6 @@ contains_symbol (entry, np)
*
*/
-
static void
digest_symbols ()
{
@@ -1441,7 +1546,7 @@ digest_symbols ()
* the padding in the text segment size.
*/
- if (magic == ZMAGIC || 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;
@@ -1494,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 (magic == ZMAGIC)
+ if (page_align_segments)
data_pad = PALIGN(data_pad + data_size, page_size) - data_size;
bss_size -= data_pad;
@@ -1510,10 +1615,10 @@ printf("bssstart = %#x, bsssize = %#x\n",
global_sym_count = defined_global_sym_count +
undefined_global_sym_count;
- if (dynamic_symbol->referenced)
+ if (dynamic_symbol->flags & GS_REFERENCED)
global_sym_count++;
- if (got_symbol->referenced)
+ if (got_symbol->flags & GS_REFERENCED)
global_sym_count++;
if (relocatable_output || building_shared_object)
@@ -1533,12 +1638,15 @@ debug symbols: %d, set_symbols %d\n",
#endif
}
+/*
+ * Determine the definition of each global symbol.
+ */
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.
*
@@ -1550,7 +1658,7 @@ digest_pass1()
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;
@@ -1584,7 +1692,7 @@ digest_pass1()
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 */
@@ -1608,12 +1716,14 @@ digest_pass1()
&& (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;
+ lsp->entry->flags |= E_SYMBOLS_USED;
sp->defined = type;
+ sp->aux = N_AUX(p);
}
}
@@ -1655,15 +1765,17 @@ digest_pass1()
&& (type & N_TYPE) != N_FN) {
/* non-common definition */
sp->def_nlist = p;
+ lsp->entry->flags |= E_SYMBOLS_USED;
sp->so_defined = type;
- if (sp->referenced)
+ sp->aux = N_AUX(p);
+ if (sp->flags & GS_REFERENCED)
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
- if (sp->alias && !sp->alias->referenced) {
+ if (sp->alias && !(sp->alias->flags & GS_REFERENCED)) {
sp = sp->alias;
goto again;
}
@@ -1678,161 +1790,10 @@ doesn't match actual (%d)",
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, *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;
-
- /*
- * 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;
-
- 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);
- }
- }
-
- /*
- * Reverse the vector.
- */
- 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;
- }
-
-
- 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)
@@ -1860,7 +1821,7 @@ consider_relocation (entry, dataseg)
if (RELOC_BASEREL_P(reloc)) {
pic_code_seen = 1;
if (!RELOC_EXTERN_P(reloc))
- lsp->rename = 1;
+ lsp->flags |= LS_RENAME;
}
continue;
}
@@ -1951,39 +1912,20 @@ consider_relocation (entry, dataseg)
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);
-#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;
- } else if (!sp->defined && sp->max_common_size == 0)
+ } else if (!sp->defined && sp->common_size == 0)
alloc_rrs_reloc(entry, sp);
} else {
@@ -2000,6 +1942,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.
*/
@@ -2084,68 +2096,155 @@ printf("%s: datastart: %#x, bss %#x\n", get_file_name(entry),
}
+/*
+ * Assign a value to each global symbol.
+ */
static void
-consider_local_symbols(entry)
- register struct file_entry *entry;
+digest_pass2()
{
- register struct localsymbol *lsp, *lspend;
+ FOR_EACH_SYMBOL(i, sp) {
+ int size;
+ int align = sizeof(int);
- if (entry->is_dynamic)
- return;
+ if (!(sp->flags & GS_REFERENCED))
+ continue;
- lspend = entry->symbols + entry->nsymbols;
+ 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++;
- /*
- * For each symbol determine whether it should go
- * in the output symbol table.
- */
+ 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);
- for (lsp = entry->symbols; lsp < lspend; lsp++) {
- register struct nlist *p = &lsp->nzlist.nlist;
- register int type = p->n_type;
+ /* Relocate symbol value */
+ sp->value += set_sect_start;
- if (type == N_WARNING)
- continue;
+ set_vectors[length_word_index] = sp->setv_count;
- if (SET_ELEMENT_P (type)) {
/*
- * This occurs even if global. These types of
- * symbols are never written globally, though
- * they are stored globally.
+ * Relocate vector to final address.
*/
- lsp->write = relocatable_output;
+ for (i = 0; i < sp->setv_count; i++) {
+ struct nlist *p = (struct nlist *)
+ set_vectors[1+i+length_word_index];
- } else if (!(type & (N_STAB | 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);
+ }
+ }
/*
- * Ordinary local symbol
+ * Reverse the vector.
*/
- lsp->write = (lsp->rename || (
- discard_locals != DISCARD_ALL &&
- !(discard_locals == DISCARD_L &&
- lsp->is_L_symbol)));
- if (lsp->write)
- local_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;
+ }
- } else if (!(type & N_EXT)) {
+ /* 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 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) {
/*
- * Debugger symbol
+ * It's a common.
*/
- lsp->write = (strip_symbols == STRIP_NONE);
- if (lsp->write)
- debugger_sym_count++;
+ 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;
}
- }
- /*
- * 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++;
+ /*
+ * 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;
}
@@ -2167,6 +2266,8 @@ write_output ()
if (outdesc < 0)
perror_name (output_filename);
+ fatal_cleanup_hook = myfatal;
+
if (fstat (outdesc, &statbuf) < 0)
perror_name (output_filename);
@@ -2205,10 +2306,10 @@ write_header ()
{
int flags = (rrs_section_type == RRS_FULL) ? EX_DYNAMIC : 0;
-#ifdef QMAGIC
- if (!oldmagic)
-#endif
- N_SET_FLAG (outheader, flags);
+ if (oldmagic && (flags & EX_DYNAMIC))
+ error("Cannot set flag in old magic headers\n");
+
+ N_SET_FLAG (outheader, flags);
outheader.a_text = text_size;
outheader.a_data = data_size;
@@ -2371,7 +2472,7 @@ copy_data (entry)
mywrite (bytes, 1, entry->header.a_data, outdesc);
}
-
+
/*
* 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
@@ -2379,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.
*/
+
+/* HACK: md.c may need access to this */
+int pc_relocation;
+
void
perform_relocation(data, data_size, reloc, nreloc, entry, dataseg)
char *data;
@@ -2388,12 +2493,13 @@ perform_relocation(data, data_size, reloc, nreloc, entry, 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:
@@ -2648,10 +2754,10 @@ write_rel ()
/* 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) {
- if (sp != dynamic_symbol && sp->referenced) {
+ if (sp != dynamic_symbol && (sp->flags & GS_REFERENCED)) {
sp->symbolnum = count++;
if (sp->size)
count++;
@@ -2696,7 +2802,7 @@ assign_symbolnums(entry, countp)
n++;
for (lsp = entry->symbols; lsp < lspend; lsp++) {
- if (lsp->write)
+ if (lsp->flags & LS_WRITE)
lsp->symbolnum = n++;
}
*countp = n;
@@ -2826,7 +2932,7 @@ copdatrel(entry)
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)) {
@@ -2971,7 +3077,7 @@ write_syms()
* 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;
@@ -2993,7 +3099,7 @@ write_syms()
/* Already dealt with above */
continue;
- if (!sp->referenced)
+ if (!(sp->flags & GS_REFERENCED))
/* Came from shared object but was not used */
continue;
@@ -3041,6 +3147,7 @@ write_syms()
*/
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;
@@ -3051,9 +3158,10 @@ write_syms()
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
@@ -3064,7 +3172,7 @@ write_syms()
* 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;
@@ -3085,6 +3193,9 @@ write_syms()
*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");
@@ -3098,6 +3209,9 @@ write_syms()
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);
@@ -3176,7 +3290,7 @@ write_file_syms(entry, syms_written_addr)
register struct nlist *bufp = buf;
- if (entry->is_dynamic)
+ if (entry->flags & E_DYNAMIC)
return;
/*
@@ -3200,9 +3314,6 @@ write_file_syms(entry, 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. */
@@ -3217,12 +3328,12 @@ write_file_syms(entry, syms_written_addr)
register int write = 0;
char *name;
- if (! lsp->write)
+ if (!(lsp->flags & LS_WRITE))
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;
@@ -3261,3 +3372,50 @@ write_file_syms(entry, syms_written_addr)
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);
+}
diff --git a/gnu/usr.bin/ld/ld/lib.c b/gnu/usr.bin/ld/ld/lib.c
index e79121a88dd..d54ec2342aa 100644
--- a/gnu/usr.bin/ld/ld/lib.c
+++ b/gnu/usr.bin/ld/ld/lib.c
@@ -1,5 +1,5 @@
/*
- * $Id: lib.c,v 1.8 1993/12/15 13:26:46 pk Exp $ - library routines
+ * $Id: lib.c,v 1.9 1994/01/28 20:56:28 pk Exp $ - library routines
*/
#include <sys/param.h>
@@ -19,13 +19,11 @@
#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
@@ -69,7 +67,7 @@ search_library(desc, entry)
* 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;
@@ -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
*/
- 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(
@@ -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->library_flag = 0;
- subentry->header_read_flag = 0;
- subentry->just_syms_flag = 0;
subentry->chain = 0;
+ subentry->flags = 0;
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;
}
-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
@@ -163,7 +157,7 @@ int subfile_wanted_p();
* length of the __.SYMDEF data.
*/
-void
+static void
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 number_of_symdefs;
+ int nsymdefs;
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);
- 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);
- 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
- || 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);
- 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. */
- 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)))
@@ -224,7 +218,7 @@ symdef_library(desc, entry, member_length)
* 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++) {
@@ -256,8 +250,9 @@ symdef_library(desc, entry, member_length)
* 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;
/*
@@ -277,10 +272,11 @@ symdef_library(desc, entry, member_length)
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);
+
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.
*/
- 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;
}
@@ -343,7 +339,7 @@ symdef_library(desc, entry, member_length)
* DESC is the descriptor it is open on.
*/
-void
+static void
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) {
- 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;
@@ -395,7 +391,7 @@ linear_library(desc, entry)
* core, but not entered. Return nonzero if we ought to load this member.
*/
-int
+static int
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;
- 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
@@ -437,7 +433,7 @@ subfile_wanted_p(entry)
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);
@@ -461,7 +457,7 @@ subfile_wanted_p(entry)
* 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
@@ -482,11 +478,11 @@ subfile_wanted_p(entry)
* 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++;
- 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;
@@ -498,21 +494,59 @@ subfile_wanted_p(entry)
}
return 1;
} else {
+ /*
+ * Check for undefined symbols or commons
+ * in shared objects.
+ */
struct localsymbol *lsp;
+ 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;
+ }
if (sp->sorefs == NULL)
continue;
- /* Check for undefined symbols in shared objects */
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))
- break; /* We need it */
+ break; /* We don't need it */
}
- if (lsp != NULL)
- continue; /* 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;
+ }
+
+ /*
+ * 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);
@@ -534,13 +568,13 @@ read_shared_object (desc, entry)
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) */
@@ -551,10 +585,10 @@ read_shared_object (desc, entry)
fatal_with_file (
"premature eof in data segment of ", entry);
}
- md_swapin_link_dynamic(&dyn);
+ md_swapin__dynamic(&dyn);
/* Check version */
- switch (dyn.ld_version) {
+ switch (dyn.d_version) {
default:
fatal_with_file( "unsupported _DYNAMIC version ", entry);
break;
@@ -565,26 +599,29 @@ read_shared_object (desc, entry)
break;
}
- /* Read link_dynamic_2 struct (from data segment) */
+ /* Read Section Dispatch Table (from data segment) */
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);
- 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);
}
- md_swapin_link_dynamic_2(&dyn2);
+ md_swapin_section_dispatch_table(&sdt);
/* 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));
- 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(
- "premature eof while reading dyn syms ", entry);
+ "premature eof while reading object symbols ", entry);
}
if (has_nz)
md_swapin_zsymbols(nzp, entry->nsymbols);
@@ -601,21 +638,21 @@ read_shared_object (desc, entry)
}
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_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) */
- n = entry->string_size = dyn2.ld_str_sz;
+ n = entry->string_size = sdt.sdt_str_sz;
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(
- "premature eof while reading dyn strings ", entry);
+ "premature eof while reading object strings ", entry);
}
enter_file_symbols (entry);
entry->strings = 0;
@@ -623,12 +660,12 @@ read_shared_object (desc, entry)
/*
* Load any subsidiary shared objects.
*/
- if (dyn2.ld_need) {
- struct link_object lobj;
+ if (sdt.sdt_sods) {
+ struct sod sod;
off_t offset;
struct file_entry *prev = NULL;
- offset = (off_t)dyn2.ld_need;
+ offset = (off_t)sdt.sdt_sods;
while (1) {
struct file_entry *subentry;
char *libname, name[MAXPATHLEN]; /*XXX*/
@@ -638,24 +675,28 @@ read_shared_object (desc, entry)
bzero(subentry, sizeof(struct file_entry));
subentry->superfile = entry;
- lseek(desc, offset, L_SET);
- if (read(desc, &lobj, sizeof(lobj)) != sizeof(lobj)) {
+ lseek(desc, offset -
+ (TEXT_START(entry->header) - N_TXTOFF(entry->header)),
+ L_SET);
+ if (read(desc, &sod, sizeof(sod)) != sizeof(sod)) {
fatal_with_file(
- "premature eof while reading link objects ",
+ "premature eof while reading sod ",
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*/
- 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,
- &lo_major, &lo_minor, 0);
+ &sod_major, &sod_minor, 0);
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 {
@@ -670,7 +711,7 @@ read_shared_object (desc, 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;
}
}
@@ -718,7 +759,7 @@ read_shared_object (desc, entry)
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:
;
@@ -739,7 +780,7 @@ struct file_entry *p;
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);
@@ -748,13 +789,13 @@ struct file_entry *p;
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:
- 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", "");
@@ -768,7 +809,7 @@ dot_a:
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);
diff --git a/gnu/usr.bin/ld/ld/rrs.c b/gnu/usr.bin/ld/ld/rrs.c
index af2144eef14..432da6ebfd5 100644
--- a/gnu/usr.bin/ld/ld/rrs.c
+++ b/gnu/usr.bin/ld/ld/rrs.c
@@ -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.
*
- * $Id: rrs.c,v 1.7 1993/12/08 10:14:03 pk Exp $
+ * $Id: rrs.c,v 1.8 1994/01/28 20:56:32 pk Exp $
*/
#include <sys/param.h>
@@ -48,9 +48,9 @@
#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;
@@ -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 number_of_shobjs;
+int number_of_shobjs;
struct shobj {
struct shobj *next;
@@ -82,29 +82,29 @@ struct shobj {
/*
RRS text segment:
- +-------------------+ <-- ld_rel (rrs_text_start)
+ +-------------------+ <-- sdt_rel (rrs_text_start)
| |
| relocation |
| |
- +-------------------+ <-- <link_dynamic_2>.ld_hash
+ +-------------------+ <-- <sdt>.sdt_hash
| |
| hash buckets |
| |
- +-------------------+ <-- <link_dynamic_2>.ld_stab
+ +-------------------+ <-- <sdt>.sdt_nzlist
| |
| symbols |
| |
- +-------------------+ <-- <link_dynamic_2>.ld_strings
+ +-------------------+ <-- <sdt>.sdt_strings
| |
| strings |
| |
- +-------------------+ <-- <link_dynamic_2>.ld_need
+ +-------------------+ <-- <sdt>.sdt_sods
| |
| shobjs |
| |
+-------------------+
| |
- | shobjs strings | <-- <shobj>.lo_name
+ | shobjs strings | <-- <shobj>.sod_name
| |
+-------------------+
@@ -113,21 +113,21 @@ RRS data segment:
+-------------------+ <-- __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_ |
| |
- +-------------------+ <-- ld_plt
+ +-------------------+ <-- sdt_plt
| |
| PLT |
| |
@@ -280,12 +280,12 @@ alloc_rrs_cpy_reloc(entry, 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
- sp->cpyreloc_reserved = 1;
+ sp->flags |= GS_CPYRELOCRESERVED;
reserved_rrs_relocs++;
}
@@ -354,8 +354,8 @@ long addend;
{
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",
@@ -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),
- rrs_dyn2.ld_plt + sp->jmpslot_offset,
+ rrs_sdt.sdt_plt + sp->jmpslot_offset,
sp->value);
if (!JMPSLOT_NEEDS_RELOC) {
- return rrs_dyn2.ld_plt + sp->jmpslot_offset;
+ return rrs_sdt.sdt_plt + sp->jmpslot_offset;
}
} 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 */
- 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();
- sp->jmpslot_claimed = 1;
+ sp->flags |= GS_JMPSLOTCLAIMED;
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;
@@ -408,7 +408,7 @@ printf("claim_rrs_jmpslot: %s: %s(%d) -> offset %x (textreloc %#x)\n",
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);
- if (sp->gotslot_claimed)
+ if (sp->flags & GS_GOTSLOTCLAIMED)
/* 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();
- 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);
@@ -524,7 +524,7 @@ long addend;
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",
@@ -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));
- if (lsp->gotslot_claimed)
+ if (lsp->flags & LS_GOTSLOTCLAIMED)
/* 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();
- 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;
@@ -564,10 +564,10 @@ symbol *sp;
{
struct relocation_info *r;
- if (sp->cpyreloc_claimed)
+ if (sp->flags & GS_CPYRELOCCLAIMED)
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);
@@ -577,7 +577,7 @@ printf("claim_rrs_copy: %s: %s -> %x\n",
#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);
@@ -617,7 +617,7 @@ int index;
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;
@@ -651,11 +651,27 @@ void
consider_rrs_section_lengths()
{
int n;
- struct shobj *shp;
+ struct shobj *shp, **shpp;
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)
@@ -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.
*/
- if (!(link_mode & SHAREABLE) && !dynamic_symbol->referenced)
+ if (!(link_mode & SHAREABLE) &&
+ !(dynamic_symbol->flags & GS_REFERENCED))
fatal("No reference to __DYNAMIC");
- dynamic_symbol->referenced = 1;
+ dynamic_symbol->flags |= GS_REFERENCED;
if (number_of_gotslots > 1)
- got_symbol->referenced = 1;
+ got_symbol->flags |= GS_REFERENCED;
/* 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) {
- 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++;
@@ -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.
*/
- 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));
- for (n = 0; n < rrs_dyn2.ld_buckets; n++)
+ for (n = 0; n < rrs_sdt.sdt_buckets; n++)
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
@@ -760,7 +777,7 @@ consider_rrs_section_lengths()
* 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;
@@ -768,9 +785,9 @@ consider_rrs_section_lengths()
/*
* 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);
@@ -790,7 +807,7 @@ consider_rrs_section_lengths()
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);
}
@@ -808,8 +825,8 @@ relocate_rrs_addresses()
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;
}
@@ -817,48 +834,48 @@ relocate_rrs_addresses()
/*
* 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_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))
- rrs_dyn2.ld_rel -= N_TXTADDR(outheader);
+ rrs_sdt.sdt_rel -= N_TXTADDR(outheader);
#endif
- rrs_dyn2.ld_hash = rrs_dyn2.ld_rel +
+ rrs_sdt.sdt_hash = rrs_sdt.sdt_rel +
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);
- rrs_dyn2.ld_strings = rrs_dyn2.ld_symbols +
+ rrs_sdt.sdt_strings = rrs_sdt.sdt_nzlist +
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.
*/
- got_symbol->value = rrs_dyn2.ld_got;
+ got_symbol->value = rrs_sdt.sdt_got;
*rrs_got = dynamic_symbol->value = rrs_data_start;
@@ -896,14 +913,14 @@ write_rrs_data()
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);
@@ -921,7 +938,7 @@ write_rrs_text()
struct nzlist *nlp;
int offset = 0;
struct shobj *shp;
- struct link_object *lo;
+ struct sod *sodp;
if (rrs_section_type == RRS_PARTIAL)
return;
@@ -967,7 +984,7 @@ write_rrs_text()
*/
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 >=
@@ -993,6 +1010,7 @@ write_rrs_text()
*/
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
@@ -1003,47 +1021,36 @@ write_rrs_text()
} 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;
- } else if (sp->max_common_size) {
+ } else if (sp->common_size) {
/*
* 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;
+ 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);
- /* 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);
@@ -1089,9 +1096,8 @@ write_rrs_text()
/*
* 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;
@@ -1100,27 +1106,27 @@ write_rrs_text()
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;
- lo[i].lo_library = 1;
+ sodp[i].sod_library = 1;
} else
- lo[i].lo_library = 0;
+ sodp[i].sod_library = 0;
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);
- 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;
diff --git a/gnu/usr.bin/ld/ld/symbol.c b/gnu/usr.bin/ld/ld/symbol.c
index 01a9e9aa25b..a2d1ab3fc74 100644
--- a/gnu/usr.bin/ld/ld/symbol.c
+++ b/gnu/usr.bin/ld/ld/symbol.c
@@ -1,5 +1,5 @@
/*
- * $Id: symbol.c,v 1.5 1993/12/08 10:14:06 pk Exp $ - symbol table routines
+ * $Id: symbol.c,v 1.6 1994/01/28 20:56:40 pk Exp $ - symbol table routines
*/
/* Create the symbol table entries for `etext', `edata' and `end'. */
@@ -15,6 +15,15 @@
#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;
@@ -22,36 +31,40 @@ int relocatable_output;
/*
* 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->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->referenced = 0;
- got_symbol->value = 0;
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;
+ edata_symbol->defined = N_DATA | 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. */
@@ -82,7 +95,7 @@ getsym(key)
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)
@@ -91,17 +104,15 @@ getsym(key)
/* 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->refs = 0;
bp->defined = 0;
- bp->referenced = 0;
- bp->trace = 0;
bp->value = 0;
- bp->max_common_size = 0;
+ bp->common_size = 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;
@@ -114,10 +125,7 @@ getsym(key)
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];
@@ -139,7 +147,7 @@ getsym_soft (key)
/* Determine which bucket. */
- hashval = hash_string (key) % TABSIZE;
+ hashval = hash_string (key) % SYMTABSIZE;
/* Search the bucket. */
diff --git a/gnu/usr.bin/ld/ld/warnings.c b/gnu/usr.bin/ld/ld/warnings.c
index dffe45f8a7e..429830f6083 100644
--- a/gnu/usr.bin/ld/ld/warnings.c
+++ b/gnu/usr.bin/ld/ld/warnings.c
@@ -1,5 +1,5 @@
/*
- * $Id: warnings.c,v 1.8 1993/12/23 09:37:43 pk Exp $
+ * $Id: warnings.c,v 1.9 1994/01/28 20:56:42 pk Exp $
*/
#include <sys/param.h>
@@ -159,30 +159,24 @@ void
print_symbols(outfile)
FILE *outfile;
{
- register int i;
-
fprintf(outfile, "\nFiles:\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);
- }
- }
+ } END_EACH_SYMBOL;
each_file(list_file_locals, outfile);
}
@@ -194,7 +188,7 @@ describe_file_sections(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",
@@ -606,7 +600,7 @@ do_file_warnings (entry, outfile)
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);
@@ -622,7 +616,7 @@ do_file_warnings (entry, outfile)
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;
@@ -630,14 +624,14 @@ do_file_warnings (entry, outfile)
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;
- 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;
@@ -655,7 +649,7 @@ do_file_warnings (entry, outfile)
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) {
@@ -673,7 +667,7 @@ do_file_warnings (entry, outfile)
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;
diff --git a/gnu/usr.bin/ld/ld/xbits.c b/gnu/usr.bin/ld/ld/xbits.c
index 40c3e2b543f..cc207e14227 100644
--- a/gnu/usr.bin/ld/ld/xbits.c
+++ b/gnu/usr.bin/ld/ld/xbits.c
@@ -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.
*
- * $Id: xbits.c,v 1.2 1993/12/08 10:14:10 pk Exp $
+ * $Id: xbits.c,v 1.3 1994/01/28 20:56:45 pk Exp $
*/
/*
@@ -96,60 +96,61 @@ int n;
}
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
-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
-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
-swapin_link_object(lop, n)
-struct link_object *lop;
+swapin_sod(sodp, n)
+struct sod *sodp;
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
-swapout_link_object(lop, n)
-struct link_object *lop;
+swapout_sod(sodp, n)
+struct sod *sodp;
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;
}
}
diff --git a/gnu/usr.bin/ld/lib.c b/gnu/usr.bin/ld/lib.c
index e79121a88dd..d54ec2342aa 100644
--- a/gnu/usr.bin/ld/lib.c
+++ b/gnu/usr.bin/ld/lib.c
@@ -1,5 +1,5 @@
/*
- * $Id: lib.c,v 1.8 1993/12/15 13:26:46 pk Exp $ - library routines
+ * $Id: lib.c,v 1.9 1994/01/28 20:56:28 pk Exp $ - library routines
*/
#include <sys/param.h>
@@ -19,13 +19,11 @@
#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
@@ -69,7 +67,7 @@ search_library(desc, entry)
* 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;
@@ -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
*/
- 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(
@@ -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->library_flag = 0;
- subentry->header_read_flag = 0;
- subentry->just_syms_flag = 0;
subentry->chain = 0;
+ subentry->flags = 0;
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;
}
-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
@@ -163,7 +157,7 @@ int subfile_wanted_p();
* length of the __.SYMDEF data.
*/
-void
+static void
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 number_of_symdefs;
+ int nsymdefs;
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);
- 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);
- 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
- || 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);
- 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. */
- 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)))
@@ -224,7 +218,7 @@ symdef_library(desc, entry, member_length)
* 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++) {
@@ -256,8 +250,9 @@ symdef_library(desc, entry, member_length)
* 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;
/*
@@ -277,10 +272,11 @@ symdef_library(desc, entry, member_length)
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);
+
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.
*/
- 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;
}
@@ -343,7 +339,7 @@ symdef_library(desc, entry, member_length)
* DESC is the descriptor it is open on.
*/
-void
+static void
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) {
- 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;
@@ -395,7 +391,7 @@ linear_library(desc, entry)
* core, but not entered. Return nonzero if we ought to load this member.
*/
-int
+static int
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;
- 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
@@ -437,7 +433,7 @@ subfile_wanted_p(entry)
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);
@@ -461,7 +457,7 @@ subfile_wanted_p(entry)
* 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
@@ -482,11 +478,11 @@ subfile_wanted_p(entry)
* 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++;
- 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;
@@ -498,21 +494,59 @@ subfile_wanted_p(entry)
}
return 1;
} else {
+ /*
+ * Check for undefined symbols or commons
+ * in shared objects.
+ */
struct localsymbol *lsp;
+ 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;
+ }
if (sp->sorefs == NULL)
continue;
- /* Check for undefined symbols in shared objects */
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))
- break; /* We need it */
+ break; /* We don't need it */
}
- if (lsp != NULL)
- continue; /* 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;
+ }
+
+ /*
+ * 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);
@@ -534,13 +568,13 @@ read_shared_object (desc, entry)
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) */
@@ -551,10 +585,10 @@ read_shared_object (desc, entry)
fatal_with_file (
"premature eof in data segment of ", entry);
}
- md_swapin_link_dynamic(&dyn);
+ md_swapin__dynamic(&dyn);
/* Check version */
- switch (dyn.ld_version) {
+ switch (dyn.d_version) {
default:
fatal_with_file( "unsupported _DYNAMIC version ", entry);
break;
@@ -565,26 +599,29 @@ read_shared_object (desc, entry)
break;
}
- /* Read link_dynamic_2 struct (from data segment) */
+ /* Read Section Dispatch Table (from data segment) */
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);
- 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);
}
- md_swapin_link_dynamic_2(&dyn2);
+ md_swapin_section_dispatch_table(&sdt);
/* 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));
- 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(
- "premature eof while reading dyn syms ", entry);
+ "premature eof while reading object symbols ", entry);
}
if (has_nz)
md_swapin_zsymbols(nzp, entry->nsymbols);
@@ -601,21 +638,21 @@ read_shared_object (desc, entry)
}
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_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) */
- n = entry->string_size = dyn2.ld_str_sz;
+ n = entry->string_size = sdt.sdt_str_sz;
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(
- "premature eof while reading dyn strings ", entry);
+ "premature eof while reading object strings ", entry);
}
enter_file_symbols (entry);
entry->strings = 0;
@@ -623,12 +660,12 @@ read_shared_object (desc, entry)
/*
* Load any subsidiary shared objects.
*/
- if (dyn2.ld_need) {
- struct link_object lobj;
+ if (sdt.sdt_sods) {
+ struct sod sod;
off_t offset;
struct file_entry *prev = NULL;
- offset = (off_t)dyn2.ld_need;
+ offset = (off_t)sdt.sdt_sods;
while (1) {
struct file_entry *subentry;
char *libname, name[MAXPATHLEN]; /*XXX*/
@@ -638,24 +675,28 @@ read_shared_object (desc, entry)
bzero(subentry, sizeof(struct file_entry));
subentry->superfile = entry;
- lseek(desc, offset, L_SET);
- if (read(desc, &lobj, sizeof(lobj)) != sizeof(lobj)) {
+ lseek(desc, offset -
+ (TEXT_START(entry->header) - N_TXTOFF(entry->header)),
+ L_SET);
+ if (read(desc, &sod, sizeof(sod)) != sizeof(sod)) {
fatal_with_file(
- "premature eof while reading link objects ",
+ "premature eof while reading sod ",
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*/
- 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,
- &lo_major, &lo_minor, 0);
+ &sod_major, &sod_minor, 0);
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 {
@@ -670,7 +711,7 @@ read_shared_object (desc, 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;
}
}
@@ -718,7 +759,7 @@ read_shared_object (desc, entry)
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:
;
@@ -739,7 +780,7 @@ struct file_entry *p;
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);
@@ -748,13 +789,13 @@ struct file_entry *p;
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:
- 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", "");
@@ -768,7 +809,7 @@ dot_a:
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);
diff --git a/gnu/usr.bin/ld/m68k/md.c b/gnu/usr.bin/ld/m68k/md.c
index c8210369345..c2b8921c09f 100644
--- a/gnu/usr.bin/ld/m68k/md.c
+++ b/gnu/usr.bin/ld/m68k/md.c
@@ -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.
*
- * $Id: md.c,v 1.1 1993/11/25 00:57:37 paulus Exp $
+ * $Id: md.c,v 1.2 1994/01/28 20:57:31 pk Exp $
*/
#include <sys/param.h>
@@ -88,25 +88,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 (oldmagic)
- hp->a_midmag = oldmagic;
- else
- 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;
-}
-
-/*
* Machine dependent part of claim_rrs_reloc().
* Set RRS relocation type.
*/
@@ -237,8 +218,29 @@ long *savep;
*(short *)where = BPT;
}
-#ifdef NEED_SWAP
+#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;
+{
+ if (oldmagic)
+ hp->a_midmag = oldmagic;
+ else
+ N_SETMAGIC((*hp), magic, MID_MACHINE, flags);
+ /* TEXT_START depends on the value of outheader.a_entry. */
+ if (!(link_mode & SHAREABLE))
+ hp->a_entry = PAGSIZ;
+}
+#endif /* RTLD */
+
+
+#ifdef NEED_SWAP
/*
* Byte swap routines for cross-linking.
*/
diff --git a/gnu/usr.bin/ld/m68k/md.h b/gnu/usr.bin/ld/m68k/md.h
index d9f7b7e6777..63d9f03b11a 100644
--- a/gnu/usr.bin/ld/m68k/md.h
+++ b/gnu/usr.bin/ld/m68k/md.h
@@ -1,5 +1,5 @@
/*
- * $Id: md.h,v 1.1 1993/11/25 00:57:38 paulus Exp $
+ * $Id: md.h,v 1.2 1994/01/28 20:57:34 pk Exp $
* - m68k dependent definitions
*/
@@ -16,6 +16,9 @@
#define N_IS_DYNAMIC(ex) ((N_GETFLAG(ex) & EX_DYNAMIC))
+#define N_BADMID(ex) \
+ (N_GETMID(ex) != 0 && N_GETMID(ex) != MID_MACHINE)
+
/*
* Should be handled by a.out.h ?
*/
@@ -60,16 +63,16 @@ typedef struct jmpslot {
#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_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)
@@ -116,23 +119,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));
-#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_link_object(l,n)
+#define md_swapout_sod(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_swap_short(x) ( (((x) >> 8) & 0xff) | (((x) & 0xff) << 8) )
diff --git a/gnu/usr.bin/ld/rrs.c b/gnu/usr.bin/ld/rrs.c
index af2144eef14..432da6ebfd5 100644
--- a/gnu/usr.bin/ld/rrs.c
+++ b/gnu/usr.bin/ld/rrs.c
@@ -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.
*
- * $Id: rrs.c,v 1.7 1993/12/08 10:14:03 pk Exp $
+ * $Id: rrs.c,v 1.8 1994/01/28 20:56:32 pk Exp $
*/
#include <sys/param.h>
@@ -48,9 +48,9 @@
#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;
@@ -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 number_of_shobjs;
+int number_of_shobjs;
struct shobj {
struct shobj *next;
@@ -82,29 +82,29 @@ struct shobj {
/*
RRS text segment:
- +-------------------+ <-- ld_rel (rrs_text_start)
+ +-------------------+ <-- sdt_rel (rrs_text_start)
| |
| relocation |
| |
- +-------------------+ <-- <link_dynamic_2>.ld_hash
+ +-------------------+ <-- <sdt>.sdt_hash
| |
| hash buckets |
| |
- +-------------------+ <-- <link_dynamic_2>.ld_stab
+ +-------------------+ <-- <sdt>.sdt_nzlist
| |
| symbols |
| |
- +-------------------+ <-- <link_dynamic_2>.ld_strings
+ +-------------------+ <-- <sdt>.sdt_strings
| |
| strings |
| |
- +-------------------+ <-- <link_dynamic_2>.ld_need
+ +-------------------+ <-- <sdt>.sdt_sods
| |
| shobjs |
| |
+-------------------+
| |
- | shobjs strings | <-- <shobj>.lo_name
+ | shobjs strings | <-- <shobj>.sod_name
| |
+-------------------+
@@ -113,21 +113,21 @@ RRS data segment:
+-------------------+ <-- __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_ |
| |
- +-------------------+ <-- ld_plt
+ +-------------------+ <-- sdt_plt
| |
| PLT |
| |
@@ -280,12 +280,12 @@ alloc_rrs_cpy_reloc(entry, 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
- sp->cpyreloc_reserved = 1;
+ sp->flags |= GS_CPYRELOCRESERVED;
reserved_rrs_relocs++;
}
@@ -354,8 +354,8 @@ long addend;
{
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",
@@ -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),
- rrs_dyn2.ld_plt + sp->jmpslot_offset,
+ rrs_sdt.sdt_plt + sp->jmpslot_offset,
sp->value);
if (!JMPSLOT_NEEDS_RELOC) {
- return rrs_dyn2.ld_plt + sp->jmpslot_offset;
+ return rrs_sdt.sdt_plt + sp->jmpslot_offset;
}
} 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 */
- 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();
- sp->jmpslot_claimed = 1;
+ sp->flags |= GS_JMPSLOTCLAIMED;
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;
@@ -408,7 +408,7 @@ printf("claim_rrs_jmpslot: %s: %s(%d) -> offset %x (textreloc %#x)\n",
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);
- if (sp->gotslot_claimed)
+ if (sp->flags & GS_GOTSLOTCLAIMED)
/* 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();
- 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);
@@ -524,7 +524,7 @@ long addend;
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",
@@ -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));
- if (lsp->gotslot_claimed)
+ if (lsp->flags & LS_GOTSLOTCLAIMED)
/* 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();
- 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;
@@ -564,10 +564,10 @@ symbol *sp;
{
struct relocation_info *r;
- if (sp->cpyreloc_claimed)
+ if (sp->flags & GS_CPYRELOCCLAIMED)
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);
@@ -577,7 +577,7 @@ printf("claim_rrs_copy: %s: %s -> %x\n",
#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);
@@ -617,7 +617,7 @@ int index;
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;
@@ -651,11 +651,27 @@ void
consider_rrs_section_lengths()
{
int n;
- struct shobj *shp;
+ struct shobj *shp, **shpp;
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)
@@ -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.
*/
- if (!(link_mode & SHAREABLE) && !dynamic_symbol->referenced)
+ if (!(link_mode & SHAREABLE) &&
+ !(dynamic_symbol->flags & GS_REFERENCED))
fatal("No reference to __DYNAMIC");
- dynamic_symbol->referenced = 1;
+ dynamic_symbol->flags |= GS_REFERENCED;
if (number_of_gotslots > 1)
- got_symbol->referenced = 1;
+ got_symbol->flags |= GS_REFERENCED;
/* 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) {
- 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++;
@@ -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.
*/
- 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));
- for (n = 0; n < rrs_dyn2.ld_buckets; n++)
+ for (n = 0; n < rrs_sdt.sdt_buckets; n++)
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
@@ -760,7 +777,7 @@ consider_rrs_section_lengths()
* 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;
@@ -768,9 +785,9 @@ consider_rrs_section_lengths()
/*
* 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);
@@ -790,7 +807,7 @@ consider_rrs_section_lengths()
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);
}
@@ -808,8 +825,8 @@ relocate_rrs_addresses()
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;
}
@@ -817,48 +834,48 @@ relocate_rrs_addresses()
/*
* 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_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))
- rrs_dyn2.ld_rel -= N_TXTADDR(outheader);
+ rrs_sdt.sdt_rel -= N_TXTADDR(outheader);
#endif
- rrs_dyn2.ld_hash = rrs_dyn2.ld_rel +
+ rrs_sdt.sdt_hash = rrs_sdt.sdt_rel +
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);
- rrs_dyn2.ld_strings = rrs_dyn2.ld_symbols +
+ rrs_sdt.sdt_strings = rrs_sdt.sdt_nzlist +
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.
*/
- got_symbol->value = rrs_dyn2.ld_got;
+ got_symbol->value = rrs_sdt.sdt_got;
*rrs_got = dynamic_symbol->value = rrs_data_start;
@@ -896,14 +913,14 @@ write_rrs_data()
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);
@@ -921,7 +938,7 @@ write_rrs_text()
struct nzlist *nlp;
int offset = 0;
struct shobj *shp;
- struct link_object *lo;
+ struct sod *sodp;
if (rrs_section_type == RRS_PARTIAL)
return;
@@ -967,7 +984,7 @@ write_rrs_text()
*/
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 >=
@@ -993,6 +1010,7 @@ write_rrs_text()
*/
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
@@ -1003,47 +1021,36 @@ write_rrs_text()
} 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;
- } else if (sp->max_common_size) {
+ } else if (sp->common_size) {
/*
* 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;
+ 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);
- /* 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);
@@ -1089,9 +1096,8 @@ write_rrs_text()
/*
* 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;
@@ -1100,27 +1106,27 @@ write_rrs_text()
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;
- lo[i].lo_library = 1;
+ sodp[i].sod_library = 1;
} else
- lo[i].lo_library = 0;
+ sodp[i].sod_library = 0;
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);
- 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;
diff --git a/gnu/usr.bin/ld/shlib.c b/gnu/usr.bin/ld/shlib.c
index fc34000ac42..4f6a207a603 100644
--- a/gnu/usr.bin/ld/shlib.c
+++ b/gnu/usr.bin/ld/shlib.c
@@ -1,5 +1,33 @@
/*
- * $Id: shlib.c,v 1.7 1993/12/08 10:14:04 pk 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 withough 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.8 1994/01/28 20:56:36 pk Exp $
*/
#include <sys/param.h>
@@ -28,11 +56,17 @@ char *strsep();
#define STANDARD_SEARCH_DIRS "/usr/lib", "/usr/X386/lib", "/usr/local/lib"
#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
};
-int n_search_dirs;
void
add_search_dir(name)
diff --git a/gnu/usr.bin/ld/symbol.c b/gnu/usr.bin/ld/symbol.c
index 01a9e9aa25b..a2d1ab3fc74 100644
--- a/gnu/usr.bin/ld/symbol.c
+++ b/gnu/usr.bin/ld/symbol.c
@@ -1,5 +1,5 @@
/*
- * $Id: symbol.c,v 1.5 1993/12/08 10:14:06 pk Exp $ - symbol table routines
+ * $Id: symbol.c,v 1.6 1994/01/28 20:56:40 pk Exp $ - symbol table routines
*/
/* Create the symbol table entries for `etext', `edata' and `end'. */
@@ -15,6 +15,15 @@
#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;
@@ -22,36 +31,40 @@ int relocatable_output;
/*
* 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->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->referenced = 0;
- got_symbol->value = 0;
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;
+ edata_symbol->defined = N_DATA | 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. */
@@ -82,7 +95,7 @@ getsym(key)
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)
@@ -91,17 +104,15 @@ getsym(key)
/* 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->refs = 0;
bp->defined = 0;
- bp->referenced = 0;
- bp->trace = 0;
bp->value = 0;
- bp->max_common_size = 0;
+ bp->common_size = 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;
@@ -114,10 +125,7 @@ getsym(key)
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];
@@ -139,7 +147,7 @@ getsym_soft (key)
/* Determine which bucket. */
- hashval = hash_string (key) % TABSIZE;
+ hashval = hash_string (key) % SYMTABSIZE;
/* Search the bucket. */
diff --git a/gnu/usr.bin/ld/warnings.c b/gnu/usr.bin/ld/warnings.c
index dffe45f8a7e..429830f6083 100644
--- a/gnu/usr.bin/ld/warnings.c
+++ b/gnu/usr.bin/ld/warnings.c
@@ -1,5 +1,5 @@
/*
- * $Id: warnings.c,v 1.8 1993/12/23 09:37:43 pk Exp $
+ * $Id: warnings.c,v 1.9 1994/01/28 20:56:42 pk Exp $
*/
#include <sys/param.h>
@@ -159,30 +159,24 @@ void
print_symbols(outfile)
FILE *outfile;
{
- register int i;
-
fprintf(outfile, "\nFiles:\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);
- }
- }
+ } END_EACH_SYMBOL;
each_file(list_file_locals, outfile);
}
@@ -194,7 +188,7 @@ describe_file_sections(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",
@@ -606,7 +600,7 @@ do_file_warnings (entry, outfile)
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);
@@ -622,7 +616,7 @@ do_file_warnings (entry, outfile)
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;
@@ -630,14 +624,14 @@ do_file_warnings (entry, outfile)
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;
- 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;
@@ -655,7 +649,7 @@ do_file_warnings (entry, outfile)
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) {
@@ -673,7 +667,7 @@ do_file_warnings (entry, outfile)
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;
diff --git a/gnu/usr.bin/ld/xbits.c b/gnu/usr.bin/ld/xbits.c
index 40c3e2b543f..cc207e14227 100644
--- a/gnu/usr.bin/ld/xbits.c
+++ b/gnu/usr.bin/ld/xbits.c
@@ -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.
*
- * $Id: xbits.c,v 1.2 1993/12/08 10:14:10 pk Exp $
+ * $Id: xbits.c,v 1.3 1994/01/28 20:56:45 pk Exp $
*/
/*
@@ -96,60 +96,61 @@ int n;
}
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
-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
-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
-swapin_link_object(lop, n)
-struct link_object *lop;
+swapin_sod(sodp, n)
+struct sod *sodp;
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
-swapout_link_object(lop, n)
-struct link_object *lop;
+swapout_sod(sodp, n)
+struct sod *sodp;
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;
}
}