diff options
| author | pk <pk@NetBSD.org> | 1994-01-28 20:56:09 +0000 |
|---|---|---|
| committer | pk <pk@NetBSD.org> | 1994-01-28 20:56:09 +0000 |
| commit | 90cfba21cbdf9695f8edcf1db5affea1d7b5d5e3 (patch) | |
| tree | cd7fba84949d25348d2ae81ededa0c6426fa6db1 /gnu/usr.bin | |
| parent | 64075b6a06a77715d7a55b25d58a2e4d547c832b (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')
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; } } |
