head	1.19;
access;
symbols
	perseant-exfatfs-base-20250801:1.19
	perseant-exfatfs-base-20240630:1.19
	cjep_sun2x:1.19.0.44
	cjep_sun2x-base:1.19
	cjep_staticlib_x-base1:1.19
	cjep_staticlib_x:1.19.0.42
	cjep_staticlib_x-base:1.19
	phil-wifi-20200421:1.19
	phil-wifi-20200411:1.19
	phil-wifi-20200406:1.19
	pgoyette-compat-merge-20190127:1.19
	pgoyette-compat-20190127:1.19
	pgoyette-compat-20190118:1.19
	pgoyette-compat-1226:1.19
	pgoyette-compat-1126:1.19
	pgoyette-compat-1020:1.19
	pgoyette-compat-0930:1.19
	pgoyette-compat-0906:1.19
	pgoyette-compat-0728:1.19
	pgoyette-compat-0625:1.19
	pgoyette-compat-0521:1.19
	pgoyette-compat-0502:1.19
	pgoyette-compat-0422:1.19
	pgoyette-compat-0415:1.19
	pgoyette-compat-0407:1.19
	pgoyette-compat-0330:1.19
	pgoyette-compat-0322:1.19
	pgoyette-compat-0315:1.19
	pgoyette-compat:1.19.0.40
	pgoyette-compat-base:1.19
	perseant-stdc-iso10646:1.19.0.38
	perseant-stdc-iso10646-base:1.19
	prg-localcount2-base3:1.19
	prg-localcount2-base2:1.19
	prg-localcount2-base1:1.19
	prg-localcount2:1.19.0.36
	prg-localcount2-base:1.19
	pgoyette-localcount-20170426:1.19
	bouyer-socketcan-base1:1.19
	pgoyette-localcount-20170320:1.19
	bouyer-socketcan:1.19.0.34
	bouyer-socketcan-base:1.19
	pgoyette-localcount-20170107:1.19
	pgoyette-localcount-20161104:1.19
	localcount-20160914:1.19
	pgoyette-localcount-20160806:1.19
	pgoyette-localcount-20160726:1.19
	pgoyette-localcount:1.19.0.32
	pgoyette-localcount-base:1.19
	netbsd-5-2-3-RELEASE:1.19
	netbsd-5-1-5-RELEASE:1.19
	yamt-pagecache-base9:1.19
	yamt-pagecache-tag8:1.19
	tls-earlyentropy:1.19.0.28
	tls-earlyentropy-base:1.19
	riastradh-xf86-video-intel-2-7-1-pre-2-21-15:1.19
	riastradh-drm2-base3:1.19
	netbsd-5-2-2-RELEASE:1.19
	netbsd-5-1-4-RELEASE:1.19
	netbsd-5-2-1-RELEASE:1.19
	netbsd-5-1-3-RELEASE:1.19
	agc-symver:1.19.0.30
	agc-symver-base:1.19
	tls-maxphys-base:1.19
	yamt-pagecache-base8:1.19
	netbsd-5-2:1.19.0.26
	yamt-pagecache-base7:1.19
	netbsd-5-2-RELEASE:1.19
	netbsd-5-2-RC1:1.19
	yamt-pagecache-base6:1.19
	yamt-pagecache-base5:1.19
	yamt-pagecache-base4:1.19
	netbsd-5-1-2-RELEASE:1.19
	netbsd-5-1-1-RELEASE:1.19
	yamt-pagecache-base3:1.19
	yamt-pagecache-base2:1.19
	yamt-pagecache:1.19.0.24
	yamt-pagecache-base:1.19
	bouyer-quota2-nbase:1.19
	bouyer-quota2:1.19.0.22
	bouyer-quota2-base:1.19
	matt-nb5-pq3:1.19.0.20
	matt-nb5-pq3-base:1.19
	netbsd-5-1:1.19.0.18
	netbsd-5-1-RELEASE:1.19
	netbsd-5-1-RC4:1.19
	netbsd-5-1-RC3:1.19
	netbsd-5-1-RC2:1.19
	netbsd-5-1-RC1:1.19
	netbsd-5-0-2-RELEASE:1.19
	netbsd-5-0-1-RELEASE:1.19
	jym-xensuspend-nbase:1.19
	netbsd-5-0:1.19.0.16
	netbsd-5-0-RELEASE:1.19
	netbsd-5-0-RC4:1.19
	netbsd-5-0-RC3:1.19
	netbsd-5-0-RC2:1.19
	jym-xensuspend:1.19.0.14
	jym-xensuspend-base:1.19
	netbsd-5-0-RC1:1.19
	netbsd-5:1.19.0.12
	netbsd-5-base:1.19
	mjf-devfs2:1.19.0.10
	mjf-devfs2-base:1.19
	yamt-pf42-base4:1.19
	yamt-pf42-base3:1.19
	hpcarm-cleanup-nbase:1.19
	yamt-pf42-base2:1.19
	yamt-pf42:1.19.0.8
	yamt-pf42-base:1.19
	keiichi-mipv6:1.19.0.6
	keiichi-mipv6-base:1.19
	cube-autoconf:1.19.0.4
	cube-autoconf-base:1.19
	hpcarm-cleanup:1.19.0.2
	hpcarm-cleanup-base:1.19
	netbsd-1-2-PATCH001:1.18
	netbsd-1-2-RELEASE:1.18
	netbsd-1-2-BETA:1.18
	netbsd-1-2-base:1.18
	netbsd-1-2:1.18.0.6
	netbsd-1-1-PATCH001:1.18
	netbsd-1-1-RELEASE:1.18
	netbsd-1-1:1.18.0.2
	netbsd-1-1-base:1.18
	netbsd-1-0-PATCH06:1.13.2.2
	netbsd-1-0-PATCH05:1.13.2.2
	netbsd-1-0-PATCH04:1.13.2.2
	netbsd-1-0-PATCH03:1.13.2.2
	netbsd-1-0-PATCH02:1.13.2.2
	netbsd-1-0-PATCH1:1.13.2.2
	netbsd-1-0-PATCH0:1.13.2.2
	netbsd-1-0-RELEASE:1.13.2.2
	netbsd-1-0:1.13.0.2
	netbsd-1-0-base:1.13;
locks; strict;
comment	@ * @;


1.19
date	97.04.16.16.49.39;	author christos;	state dead;
branches;
next	1.18;

1.18
date	94.12.28.10.37.38;	author pk;	state Exp;
branches;
next	1.17;

1.17
date	94.12.23.20.33.01;	author pk;	state Exp;
branches;
next	1.16;

1.16
date	94.10.19.20.16.38;	author pk;	state Exp;
branches;
next	1.15;

1.15
date	94.07.23.08.40.57;	author pk;	state Exp;
branches;
next	1.14;

1.14
date	94.07.21.14.59.11;	author pk;	state Exp;
branches;
next	1.13;

1.13
date	94.06.29.11.18.56;	author pk;	state Exp;
branches
	1.13.2.1;
next	1.12;

1.12
date	94.06.24.13.33.50;	author pk;	state Exp;
branches;
next	1.11;

1.11
date	94.06.16.13.42.05;	author pk;	state Exp;
branches;
next	1.10;

1.10
date	94.06.10.15.16.17;	author pk;	state Exp;
branches;
next	1.9;

1.9
date	94.01.28.20.56.42;	author pk;	state Exp;
branches;
next	1.8;

1.8
date	93.12.23.09.37.43;	author pk;	state Exp;
branches;
next	1.7;

1.7
date	93.12.20.22.44.44;	author pk;	state Exp;
branches;
next	1.6;

1.6
date	93.12.08.10.14.09;	author pk;	state Exp;
branches;
next	1.5;

1.5
date	93.12.07.01.44.26;	author mycroft;	state Exp;
branches;
next	1.4;

1.4
date	93.11.05.12.45.25;	author pk;	state Exp;
branches;
next	1.3;

1.3
date	93.11.01.16.26.20;	author pk;	state Exp;
branches;
next	1.2;

1.2
date	93.10.21.00.53.01;	author pk;	state Exp;
branches;
next	1.1;

1.1
date	93.10.16.21.52.36;	author pk;	state Exp;
branches;
next	;

1.13.2.1
date	94.07.22.03.38.16;	author cgd;	state Exp;
branches;
next	1.13.2.2;

1.13.2.2
date	94.07.24.01.39.30;	author cgd;	state Exp;
branches;
next	;


desc
@@


1.19
log
@Ld directory reorganization:
	- separate out the common files used by rtld ldd ld
	- move machine dependent files into arch
	- move ld in its own directory
	- factor out .PATH and CFLAGS common to all Makefiles
@
text
@/*
 * $Id: warnings.c,v 1.18 1994/12/28 10:37:38 pk Exp $
 */

#include <sys/param.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <sys/time.h>
#include <sys/errno.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <ar.h>
#include <ranlib.h>
#include <a.out.h>
#include <stab.h>
#include <string.h>
#if __STDC__
#include <stdarg.h>
#else
#include <varargs.h>
#endif

#include "ld.h"

static int reported_undefineds;

/*
 * Print the filename of ENTRY on OUTFILE (a stdio stream),
 * and then a newline.
 */

void
prline_file_name (entry, outfile)
     struct file_entry *entry;
     FILE *outfile;
{
	print_file_name (entry, outfile);
	fprintf (outfile, "\n");
}

/*
 * Print the filename of ENTRY on OUTFILE (a stdio stream).
 */

void
print_file_name (entry, outfile)
     struct file_entry *entry;
     FILE *outfile;
{
	if (entry == NULL) {
		fprintf (outfile, "NULL");
	}

	if (entry->superfile) {
		print_file_name (entry->superfile, outfile);
		fprintf (outfile, "(%s)", entry->filename);
	} else
		fprintf (outfile, "%s", entry->filename);
}

/*
 * Return the filename of entry as a string (malloc'd for the purpose)
 */

char *
get_file_name (entry)
     struct file_entry *entry;
{
	char *result, *supfile;

	if (entry == NULL) {
		return (char *)strdup("NULL");
	}

	if (entry->superfile) {
		supfile = get_file_name(entry->superfile);
		result = (char *)
			xmalloc(strlen(supfile) + strlen(entry->filename) + 3);
		(void)sprintf(result, "%s(%s)", supfile, entry->filename);
		free(supfile);

	} else {
		result = (char *)xmalloc(strlen(entry->filename) + 1);
		strcpy(result, entry->filename);
	}
	return result;
}

/* Print a complete or partial map of the output file. */

static void	describe_file_sections __P((struct file_entry *, FILE *));
static void	list_file_locals __P((struct file_entry *, FILE *));

void
print_symbols(outfile)
	FILE           *outfile;
{
	fprintf(outfile, "\nFiles:\n\n");
	each_file(describe_file_sections, (void *)outfile);

	fprintf(outfile, "\nGlobal symbols:\n\n");
	FOR_EACH_SYMBOL(i, sp) {
		fprintf(outfile, "  %s: ", sp->name);
		if (!(sp->flags & GS_REFERENCED))
			fprintf(outfile, "unreferenced");
		else if (sp->so_defined)
			fprintf(outfile, "sodefined");
		else if (!sp->defined)
			fprintf(outfile, "undefined");
		else if (sp->defined == (N_UNDF|N_EXT))
			fprintf(outfile, "common: size %#x", sp->common_size);
		else
			fprintf(outfile, "type %d, value %#x, size %#x",
				sp->defined, sp->value, sp->size);
		if (sp->alias)
			fprintf(outfile, ", aliased to %s", sp->alias->name);
		fprintf(outfile, "\n");
	} END_EACH_SYMBOL;

	each_file(list_file_locals, (void *)outfile);
}

static void
describe_file_sections(entry, outfile)
	struct file_entry *entry;
	FILE           *outfile;
{
	fprintf(outfile, "  ");
	print_file_name(entry, outfile);
	if (entry->flags & (E_JUST_SYMS | E_DYNAMIC))
		fprintf(outfile, " symbols only\n");
	else
		fprintf(outfile, " text %x(%x), data %x(%x), bss %x(%x) hex\n",
			entry->text_start_address, entry->header.a_text,
			entry->data_start_address, entry->header.a_data,
			entry->bss_start_address, entry->header.a_bss);
}

static void
list_file_locals (entry, outfile)
     struct file_entry *entry;
     FILE *outfile;
{
	struct localsymbol	*lsp, *lspend;

	entry->strings = (char *)alloca(entry->string_size);
	read_entry_strings (file_open(entry), entry);

	fprintf (outfile, "\nLocal symbols of ");
	print_file_name (entry, outfile);
	fprintf (outfile, ":\n\n");

	lspend = entry->symbols + entry->nsymbols;
	for (lsp = entry->symbols; lsp < lspend; lsp++) {
		register struct nlist *p = &lsp->nzlist.nlist;
		/*
		 * If this is a definition,
		 * update it if necessary by this file's start address.
		 */
		if (!(p->n_type & (N_STAB | N_EXT)))
			fprintf(outfile, "  %s: 0x%x\n",
				entry->strings + p->n_un.n_strx, p->n_value);
	}

	entry->strings = 0;		/* All done with them.  */
}


/* Static vars for do_warnings and subroutines of it */
static int list_unresolved_refs;	/* List unresolved refs */
static int list_multiple_defs;		/* List multiple definitions */

static struct line_debug_entry *init_debug_scan __P((int, struct file_entry *));
static int	next_debug_entry __P((int, struct line_debug_entry *));

/*
 * Structure for communication between do_file_warnings and it's
 * helper routines.  Will in practice be an array of three of these:
 * 0) Current line, 1) Next line, 2) Source file info.
 */
struct line_debug_entry
{
	int			line;
	char			*filename;
	struct localsymbol	*sym;
};

/*
 * Helper routines for do_file_warnings.
 */

/*
 * Return an integer less than, equal to, or greater than 0 as per the
 * relation between the two relocation entries.  Used by qsort.
 */

static int
reloc_cmp(rel1, rel2)
	struct relocation_info *rel1, *rel2;
{
	return RELOC_ADDRESS(rel1) - RELOC_ADDRESS(rel2);
}

/*
 * Moves to the next debugging symbol in the file.  USE_DATA_SYMBOLS
 * determines the type of the debugging symbol to look for (DSLINE or
 * SLINE).  STATE_POINTER keeps track of the old and new locatiosn in
 * the file.  It assumes that state_pointer[1] is valid; ie
 * that it.sym points into some entry in the symbol table.  If
 * state_pointer[1].sym == 0, this routine should not be called.
 */

static int
next_debug_entry(use_data_symbols, state_pointer)
	register int use_data_symbols;
	/* Next must be passed by reference! */
	struct line_debug_entry state_pointer[3];
{
	register struct line_debug_entry
				*current = state_pointer,
				*next = state_pointer + 1,
				/* Used to store source file */
				*source = state_pointer + 2;

	struct file_entry	*entry = (struct file_entry *)source->sym;
	struct localsymbol	*lspend = entry->symbols + entry->nsymbols;


	current->sym = next->sym;
	current->line = next->line;
	current->filename = next->filename;

	while (++(next->sym) < lspend) {

		struct nlist	*np = &next->sym->nzlist.nlist;

		/*
		 * n_type is a char, and N_SOL, N_EINCL and N_BINCL are > 0x80,
		 * so may look negative...therefore, must mask to low bits
		 */
		switch (np->n_type & 0xff) {
		case N_SLINE:
			if (use_data_symbols)
				continue;
			next->line = np->n_desc;
			return 1;
		case N_DSLINE:
			if (!use_data_symbols)
				continue;
			next->line = np->n_desc;
			return 1;
#ifdef HAVE_SUN_STABS
		case N_EINCL:
			next->filename = source->filename;
			continue;
#endif
		case N_SO:
			source->filename = np->n_un.n_strx + entry->strings;
			source->line++;
#ifdef HAVE_SUN_STABS
		case N_BINCL:
#endif
		case N_SOL:
			next->filename = np->n_un.n_strx + entry->strings;
		default:
			continue;
		}
	}
	next->sym = (struct localsymbol *)0;
	return 0;
}

/*
 * Create a structure to save the state of a scan through the debug symbols.
 * USE_DATA_SYMBOLS is set if we should be scanning for DSLINE's instead of
 * SLINE's. ENTRY is the file entry which points at the symbols to use.
 */

static struct line_debug_entry *
init_debug_scan(use_data_symbols, entry)
	int			use_data_symbols;
	struct file_entry	*entry;
{
	register struct localsymbol	*lsp, *lspend;
	struct line_debug_entry *state_pointer, *current, *next, *source;

	state_pointer = (struct line_debug_entry *)
		xmalloc(3 * sizeof(*state_pointer));

	current = state_pointer,
	next = state_pointer + 1,
	source = state_pointer + 2;	/* Used to store source file */

	lspend = entry->symbols+entry->nsymbols;

	for (lsp = entry->symbols; lsp < lspend; lsp++)
		if (lsp->nzlist.nlist.n_type == N_SO)
			break;

	if (lsp >= lspend) {
		/* I believe this translates to "We lose" */
		current->filename = next->filename = entry->filename;
		current->line = next->line = -1;
		current->sym = next->sym = (struct localsymbol *)0;
		return state_pointer;
	}
	next->line = source->line = 0;
	next->filename = source->filename
			= (lsp->nzlist.nlist.n_un.n_strx + entry->strings);
	source->sym = (struct localsymbol *)entry;
	next->sym = lsp;

	/* To setup next */
	next_debug_entry(use_data_symbols, state_pointer);

	if (!next->sym) {	/* No line numbers for this section; */
		/* setup output results as appropriate */
		if (source->line) {
			current->filename = source->filename = entry->filename;
			current->line = -1;	/* Don't print lineno */
		} else {
			current->filename = source->filename;
			current->line = 0;
		}
		return state_pointer;
	}
	/* To setup current */
	next_debug_entry(use_data_symbols, state_pointer);

	return state_pointer;
}

/*
 * Takes an ADDRESS (in either text or data space) and a STATE_POINTER which
 * describes the current location in the implied scan through the debug
 * symbols within the file which ADDRESS is within, and returns the source
 * line number which corresponds to ADDRESS.
 */

static int
address_to_line(address, state_pointer)
	unsigned long   address;
/* Next must be passed by reference! */
	struct line_debug_entry state_pointer[3];
{
	struct line_debug_entry	*current, *next, *tmp_pointer;
	int			use_data_symbols;

	current = state_pointer;
	next = state_pointer + 1;

	if (next->sym)
		use_data_symbols =
			(next->sym->nzlist.nlist.n_type & N_TYPE) == N_DATA;
	else
		return current->line;

	/* Go back to the beginning if we've already passed it. */
	if (current->sym->nzlist.nlist.n_value > address) {
		tmp_pointer = init_debug_scan(use_data_symbols,
					      (struct file_entry *)
					      ((state_pointer + 2)->sym));
		state_pointer[0] = tmp_pointer[0];
		state_pointer[1] = tmp_pointer[1];
		state_pointer[2] = tmp_pointer[2];
		free(tmp_pointer);
	}

	/* If we're still in a bad way, return -1, meaning invalid line. */
	if (current->sym->nzlist.nlist.n_value > address)
		return -1;

	while (next->sym
	       && next->sym->nzlist.nlist.n_value <= address
	       && next_debug_entry(use_data_symbols, state_pointer));

	return current->line;
}


/* Macros for manipulating bitvectors.  */
#define	BIT_SET_P(bv, index)	((bv)[(index) >> 3] & 1 << ((index) & 0x7))
#define	SET_BIT(bv, index)	((bv)[(index) >> 3] |= 1 << ((index) & 0x7))

/*
 * This routine will scan through the relocation data of file ENTRY, printing
 * out references to undefined symbols and references to symbols defined in
 * files with N_WARNING symbols.  If DATA_SEGMENT is non-zero, it will scan
 * the data relocation segment (and use N_DSLINE symbols to track line
 * number); otherwise it will scan the text relocation segment.  Warnings
 * will be printed on the output stream OUTFILE.  Eventually, every nlist
 * symbol mapped through will be marked in the NLIST_BITVECTOR, so we don't
 * repeat ourselves when we scan the nlists themselves.
 */

static void
do_relocation_warnings(entry, data_segment, outfile, nlist_bitvector)
	struct file_entry *entry;
	int             data_segment;
	FILE           *outfile;
	unsigned char  *nlist_bitvector;
{
	struct relocation_info	*rp, *erp;
	int			start_of_segment;
	struct localsymbol	*start_of_syms;
	struct line_debug_entry	*state_pointer, *current;
	/* Assigned to generally static values; should not be written into.  */
	char *errfmt;
	/*
	 * Assigned to alloca'd values cand copied into; should be freed when
	 * done.
	 */
	char *errmsg;
	int  invalidate_line_number;

	rp = data_segment ? entry->datarel : entry->textrel;
	erp = data_segment ? (rp + entry->ndatarel) : (rp + entry->ntextrel);
	start_of_syms = entry->symbols;
	start_of_segment = (data_segment ?
		entry->data_start_address :
		entry->text_start_address);
	state_pointer = init_debug_scan(data_segment != 0, entry);
	current = state_pointer;

	/*
	 * We need to sort the relocation info here.  Sheesh, so much effort
	 * for one lousy error optimization.
	 */
	qsort(rp, erp - rp, sizeof(rp[0]), reloc_cmp);

	for (; rp < erp; rp++) {
		register struct localsymbol *lsp;
		register symbol *g;

		/*
		 * If the relocation isn't resolved through a symbol, continue.
		 */
		if (!RELOC_EXTERN_P(rp))
			continue;

		lsp = &entry->symbols[RELOC_SYMBOL(rp)];

		/*
		 * Local symbols shouldn't ever be used by relocation info,
		 * so the next should be safe. This is, of course, wrong.
		 * References to local BSS symbols can be the targets of
		 * relocation info, and they can (must) be resolved through
		 * symbols.  However, these must be defined properly, (the
		 * assembler would have caught it otherwise), so we can
		 * ignore these cases.
		 */

		if ((g = lsp->symbol) == NULL)
			continue;

		if (!(lsp->nzlist.nz_type & N_EXT) &&
		    !SET_ELEMENT_P(lsp->nzlist.nz_type)) {
			warnx("internal error: `%s' N_EXT not set", g->name);
			continue;
		}

		errmsg = 0;

		if (!g->defined && !g->so_defined && list_unresolved_refs) {
			/* Mark as being noted by relocation warning pass. */
			SET_BIT(nlist_bitvector, lsp - start_of_syms);

			if (g->undef_refs == 0)
				reported_undefineds++;
			if (g->undef_refs >= MAX_UREFS_PRINTED)
				/* Listed too many */
				continue;
			/* Undefined symbol which we should mention */

			if (++(g->undef_refs) == MAX_UREFS_PRINTED) {
				errfmt = "More undefined symbol %s refs follow";
				invalidate_line_number = 1;
			} else {
				errfmt =
			"Undefined symbol `%s' referenced from %s segment";
				invalidate_line_number = 0;
			}
		} else {	/* Defined */
			/* Potential symbol warning here */
			if (!g->warning)
				continue;

			if (BIT_SET_P(nlist_bitvector, lsp - start_of_syms))
				continue;

			/* Mark as being noted by relocation warning pass.  */
			SET_BIT(nlist_bitvector, lsp - start_of_syms);

			errfmt = 0;
			errmsg = g->warning;
			invalidate_line_number = 0;
		}


		/* If errfmt == 0, errmsg has already been defined.  */
		if (errfmt != 0) {
			char           *nm;

			nm = g->name;
			errmsg = (char *)
				xmalloc(strlen(errfmt) + strlen(nm) + 1);
			sprintf(errmsg, errfmt, nm, data_segment?"data":"text");
			if (nm != g->name)
				free(nm);
		}
		address_to_line(RELOC_ADDRESS(rp) + start_of_segment,
				state_pointer);

		if (current->line >= 0)
			fprintf(outfile, "%s:%d: %s\n",
				current->filename,
				invalidate_line_number ? 0 : current->line,
				errmsg);
		else
			fprintf(outfile, "%s: %s\n", current->filename, errmsg);

		if (errfmt != 0)
			free(errmsg);
	}

	free(state_pointer);
}

/*
 * Print on OUTFILE a list of all warnings generated by references and/or
 * definitions in the file ENTRY.  List source file and line number if
 * possible, just the .o file if not.
 */

void
do_file_warnings (entry, outfile)
	struct file_entry	*entry;
	FILE			*outfile;
{
	int	nsym;
	int	i;
	char	*errfmt, *file_name;
	int	line_number;
	int	dont_allow_symbol_name;
	u_char	*nlist_bitvector;
	struct line_debug_entry	*text_scan, *data_scan;

	nsym = entry->nsymbols;
	nlist_bitvector = (u_char *)alloca((nsym >> 3) + 1);
	bzero(nlist_bitvector, (nsym >> 3) + 1);

	/* Read in the strings */
	entry->strings = (char *)alloca(entry->string_size);
	read_entry_strings(file_open(entry), entry);

	if (!(entry->flags & E_DYNAMIC)) {
		/* Do text warnings based on a scan through the reloc info. */
		do_relocation_warnings(entry, 0, outfile, nlist_bitvector);

		/* Do data warnings based on a scan through the reloc info. */
		do_relocation_warnings(entry, 1, outfile, nlist_bitvector);
	}

	/*
	 * Scan through all of the nlist entries in this file and pick up
	 * anything that the scan through the relocation stuff didn't.
	 */
	text_scan = init_debug_scan(0, entry);
	data_scan = init_debug_scan(1, entry);

	for (i = 0; i < nsym; i++) {
		struct nlist *np;
		symbol *g;

	        g = entry->symbols[i].symbol;
		np = &entry->symbols[i].nzlist.nlist;

		if (g == NULL)
			continue;

		if (!(np->n_type & N_EXT) && !SET_ELEMENT_P(np->n_type)) {
			warnx("internal error: `%s' N_EXT not set", g->name);
			continue;
		}

		if (!(g->flags & GS_REFERENCED)) {
#if 0
			/* Check for undefined shobj symbols */
			struct localsymbol	*lsp;
			register int		type;

			for (lsp = g->sorefs; lsp; lsp = lsp->next) {
				type = lsp->nzlist.nz_type;
				if ((type & N_EXT) &&
						type != (N_UNDF | N_EXT)) {
					break;
				}
			}
			if (type == (N_UNDF | N_EXT)) {
				fprintf(stderr,
					"Undefined symbol %s referenced from %s\n",
					g->name,
					get_file_name(entry));
			}
#endif
			continue;
		}

		dont_allow_symbol_name = 0;

		if (list_multiple_defs && g->mult_defs) {

			errfmt = "Definition of symbol `%s' (multiply defined)";
			switch (np->n_type) {
			case N_TEXT | N_EXT:
				line_number =
					address_to_line(np->n_value, text_scan);
				file_name = text_scan[0].filename;
				break;

			case N_DATA | N_EXT:
				line_number =
					address_to_line(np->n_value, data_scan);
				file_name = data_scan[0].filename;
				break;

			case N_SETA | N_EXT:
			case N_SETT | N_EXT:
			case N_SETD | N_EXT:
			case N_SETB | N_EXT:
				if (g->mult_defs == 2)
					continue;
				errfmt =
	"First set element definition of symbol `%s' (multiply defined)";
				line_number = -1;
				break;

			case N_SIZE | N_EXT:
				errfmt =
	"Size element definition of symbol `%s' (multiply defined)";
				line_number = -1;
				break;

			case N_INDR | N_EXT:
				errfmt =
	"Alias definition of symbol `%s' (multiply defined)";
				line_number = -1;
				break;

			case N_UNDF | N_EXT:
				/* Don't print out multiple defs at references.*/
				continue;

			default:
				warnx("%s: unexpected multiple definitions "
				      "of symbol `%s', type %#x",
				      get_file_name(entry),
				      g->name, np->n_type);
				break;
			}

		} else if (BIT_SET_P(nlist_bitvector, i)) {
			continue;
		} else if (list_unresolved_refs &&
			   !g->defined && !g->so_defined) {

			if (g->undef_refs == 0)
				reported_undefineds++;
			if (g->undef_refs >= MAX_UREFS_PRINTED)
				continue;
			if (++(g->undef_refs) == MAX_UREFS_PRINTED)
				errfmt = "More undefined `%s' refs follow";
			else
				errfmt = "Undefined symbol `%s' referenced";
			line_number = -1;
		} else if (g->def_lsp && g->def_lsp->entry != entry &&
			   !(entry->flags & E_DYNAMIC) &&
			   g->def_lsp->entry->flags & E_SECONDCLASS) {
			fprintf(outfile,
			"%s: Undefined symbol `%s' referenced (use %s ?)\n",
				get_file_name(entry),
				g->name,
				g->def_lsp->entry->local_sym_name);
			continue;
		} else if (g->warning) {
			/*
			 * There are two cases in which we don't want to do
			 * this. The first is if this is a definition instead
			 * of a reference. The second is if it's the reference
			 * used by the warning stabs itself.
			 */
			if (np->n_type != (N_EXT | N_UNDF) ||
			    (entry->symbols[i].flags & LS_WARNING))
				continue;

			errfmt = g->warning;
			line_number = -1;
			dont_allow_symbol_name = 1;
		} else
			continue;

		if (line_number == -1)
			fprintf(outfile, "%s: ", get_file_name(entry));
		else
			fprintf(outfile, "%s:%d: ", file_name, line_number);

		if (dont_allow_symbol_name)
			fprintf(outfile, "%s", errfmt);
		else
			fprintf(outfile, errfmt, g->name);

		fputc('\n', outfile);
	}
	free(text_scan);
	free(data_scan);
	entry->strings = 0;	/* Since it will disappear anyway. */
}

int
do_warnings(outfile)
	FILE	*outfile;
{

	list_unresolved_refs = !relocatable_output &&
		( (undefined_global_sym_count - undefined_weak_sym_count) > 0
		   || undefined_shobj_sym_count
		);
	list_multiple_defs = multiple_def_count != 0;

	if (!(list_unresolved_refs ||
	      list_warning_symbols ||
	      list_multiple_defs))
		/* No need to run this routine */
		return 1;

	if (entry_symbol && !entry_symbol->defined)
		fprintf(outfile, "Undefined entry symbol `%s'\n",
			entry_symbol->name);

	each_file(do_file_warnings, (void *)outfile);

	if (list_unresolved_refs &&
	    reported_undefineds !=
	    (undefined_global_sym_count - undefined_weak_sym_count))
		warnx("Spurious undefined symbols: "
		      "# undefined symbols %d, reported %d",
		      (undefined_global_sym_count - undefined_weak_sym_count),
		      reported_undefineds);

	if (list_unresolved_refs || list_multiple_defs)
		return 0;

	return 1;
}

@


1.18
log
@Don't whine about undefined symbols.
@
text
@d2 1
a2 1
 * $Id: warnings.c,v 1.17 1994/12/23 20:33:01 pk Exp $
@


1.17
log
@"weak symbol" support (fudged into `a.out' by means of the n_other field).
Weak symbols are to replace indirect (type N_INDR) symbols and will help
to clean up name spaces in libraries.

Also, some misc. bug fixes, including PR 586, and use stdio for the output
file entirely.
@
text
@d2 1
a2 1
 * $Id: warnings.c,v 1.16 1994/10/19 20:16:38 pk Exp $
d726 1
d745 2
a746 1
	if (reported_undefineds !=
d749 1
a749 1
		      "# undefined symbols %d, reported %d\n",
@


1.16
log
@Recognise more symbol types when complaining.
@
text
@d2 1
a2 1
 * $Id: warnings.c,v 1.15 1994/07/23 08:40:57 pk Exp $
d28 2
d471 2
a475 1

d653 1
a653 2
			default:
warnx("Unexpected multiple definitions of symbol `%s', type %#x\n", g->name, np->n_type);
d656 7
d670 2
a673 1

d684 1
a684 1
				entry->filename,
d706 1
a706 1
			fprintf(outfile, "%s: ", entry->filename);
d727 3
a729 1
		(undefined_global_sym_count || undefined_shobj_sym_count);
d743 7
@


1.15
log
@Propagate warning symbols into shared libraries too.
Fix RRS relocation counters.
@
text
@d2 1
a2 1
 * $Id: warnings.c,v 1.14 1994/07/21 14:59:11 pk Exp $
d104 1
a104 3
		if (sp->defined == (N_UNDF|N_EXT))
			fprintf(outfile, "  %s: common, length %#x\n",
						sp->name, sp->common_size);
d106 1
a106 1
			fprintf(outfile, "  %s: unreferenced\n", sp->name);
d108 1
a108 1
			fprintf(outfile, "  %s: sodefined\n", sp->name);
d110 3
a112 1
			fprintf(outfile, "  %s: undefined\n", sp->name);
d114 5
a118 2
			fprintf(outfile, "  %s: %#x, size %#x\n",
						sp->name, sp->value, sp->size);
d635 12
@


1.14
log
@Propagate N_WARNING symbols to `-r' output.
@
text
@d2 1
a2 1
 * $Id: warnings.c,v 1.13 1994/06/29 11:18:56 pk Exp $
d671 1
a671 1
			    (i && entry->symbols[i-1].nzlist.nz_type == N_WARNING))
@


1.13
log
@Some refinement in resolving symbols from shared objects.
@
text
@d2 1
a2 1
 * $Id: warnings.c,v 1.12 1994/06/24 13:33:50 pk Exp $
a168 1
static int list_warning_symbols;	/* List warning syms */
a702 1
	list_warning_symbols = warning_count;
@


1.13.2.1
log
@from trunk
@
text
@d2 1
a2 1
 * $Id: warnings.c,v 1.14 1994/07/21 14:59:11 pk Exp $
d169 1
d704 1
@


1.13.2.2
log
@from trunk.
@
text
@d2 1
a2 1
 * $Id: warnings.c,v 1.15 1994/07/23 08:40:57 pk Exp $
d671 1
a671 1
			    (entry->symbols[i].flags & LS_WARNING))
@


1.12
log
@N_WARNING symbols handling.
@
text
@d2 1
a2 1
 * $Id: warnings.c,v 1.11 1994/06/16 13:42:05 pk Exp $
d486 3
d655 9
@


1.11
log
@Fix false assumption about external (N_EXT) symbols always being
in the global symbol table (reported by Geoff Rehmet).
Some misc. reformatting.
@
text
@d2 1
a2 1
 * $Id: warnings.c,v 1.10 1994/06/10 15:16:17 pk Exp $
d660 1
a660 1
			    (i && (np-1)->n_type == N_WARNING))
@


1.10
log
@Conversion to err()/warn() for error reports.
Minor bug fixes:
	a case of free()ing in the wrong order. (from Rick Murphey).
	processing alias symbol twice (sometimes).
Some miscellaneous cleanup.
@
text
@d2 1
a2 1
 * $Id: warnings.c,v 1.9 1994/01/28 20:56:42 pk Exp $
d77 5
a81 5
		supfile = get_file_name (entry->superfile);
		result = (char *) xmalloc (strlen(supfile)
					+ strlen(entry->filename) + 3);
		sprintf (result, "%s(%s)", supfile, entry->filename);
		free (supfile);
d84 2
a85 2
		result = (char *) xmalloc (strlen (entry->filename) + 1);
		strcpy (result, entry->filename);
d144 2
a145 2
	entry->strings = (char *) alloca (entry->string_size);
	read_entry_strings (file_open (entry), entry);
d173 1
a173 1
static int		next_debug_entry __P((int, struct line_debug_entry *));
d191 4
a194 2
/* Return an integer less than, equal to, or greater than 0 as per the
   relation between the two relocation entries.  Used by qsort.  */
d197 2
a198 2
relocation_entries_relation (rel1, rel2)
     struct relocation_info *rel1, *rel2;
d203 8
a210 6
/* Moves to the next debugging symbol in the file.  USE_DATA_SYMBOLS
   determines the type of the debugging symbol to look for (DSLINE or
   SLINE).  STATE_POINTER keeps track of the old and new locatiosn in
   the file.  It assumes that state_pointer[1] is valid; ie
   that it.sym points into some entry in the symbol table.  If
   state_pointer[1].sym == 0, this routine should not be called.  */
d213 4
a216 4
next_debug_entry (use_data_symbols, state_pointer)
     register int use_data_symbols;
     /* Next must be passed by reference! */
     struct line_debug_entry state_pointer[3];
d224 2
a225 2
	struct file_entry	*entry = (struct file_entry *) source->sym;
	struct localsymbol	*endp = entry->symbols + entry->nsymbols;
d232 1
a232 1
	while (++(next->sym) < endp) {
d242 2
a243 1
			if (use_data_symbols) continue;
d247 2
a248 1
			if (!use_data_symbols) continue;
d275 1
a275 1
 * SLINE's.  entry is the file entry which points at the symbols to use.
d280 2
a281 2
	int             use_data_symbols;
	struct file_entry *entry;
d283 5
a287 3
	struct localsymbol	*lsp;
	struct line_debug_entry *state_pointer = (struct line_debug_entry *)
				xmalloc(3 * sizeof(struct line_debug_entry));
d289 3
a291 4
	register struct line_debug_entry
		*current = state_pointer,
		*next = state_pointer + 1,
		*source = state_pointer + 2;	/* Used to store source file */
d293 1
d295 1
a295 1
	for (lsp = entry->symbols; lsp < entry->symbols+entry->nsymbols; lsp++)
d299 1
a299 1
	if (lsp >= entry->symbols + entry->nsymbols) {
d303 1
a303 1
		current->sym = next->sym = (struct localsymbol *) 0;
d309 1
a309 1
	source->sym = (struct localsymbol *) entry;
d402 4
a405 13
	struct relocation_info *reloc, *reloc_start =
			data_segment ? entry->datarel : entry->textrel;

	int	reloc_size = (data_segment ? entry->ndatarel : entry->ntextrel);
	int	start_of_segment = (data_segment ?
					entry->data_start_address :
					entry->text_start_address);
	struct localsymbol	*start_of_syms = entry->symbols;
	struct line_debug_entry	*state_pointer =
				init_debug_scan(data_segment != 0, entry);

	register struct line_debug_entry	*current = state_pointer;

a407 1

d415 9
d428 1
d430 2
a431 7
	qsort(reloc_start, reloc_size, sizeof(struct relocation_info),
	      relocation_entries_relation);

	for (reloc = reloc_start;
	     reloc < (reloc_start + reloc_size);
	     reloc++) {
		register struct localsymbol *s;
d435 1
a435 2
		 * If the relocation isn't resolved through a symbol,
		 * continue
d437 1
a437 1
		if (!RELOC_EXTERN_P(reloc))
d440 1
a440 1
		s = &entry->symbols[RELOC_SYMBOL(reloc)];
d451 2
a452 1
		if (!(s->nzlist.nz_type & N_EXT))
d455 6
a460 1
		g = s->symbol;
d463 3
a465 3
		if (!g->defined && !g->so_defined && list_unresolved_refs) {	/* Reference */
			/* Mark as being noted by relocation warning pass.  */
			SET_BIT(nlist_bitvector, s - start_of_syms);
d467 2
a468 1
			if (g->undef_refs >= MAX_UREFS_PRINTED)	/* Listed too many */
d477 2
a478 1
				errfmt = "Undefined symbol %s referenced from %s segment";
d487 1
a487 1
			SET_BIT(nlist_bitvector, s - start_of_syms);
d506 1
a506 1
		address_to_line(RELOC_ADDRESS(reloc) + start_of_segment,
d510 4
a513 2
			fprintf(outfile, "%s:%d: %s\n", current->filename,
			invalidate_line_number ? 0 : current->line, errmsg);
d535 1
a535 4
	int number_of_syms = entry->nsymbols;
	unsigned char *nlist_bitvector = (unsigned char *)
					alloca ((number_of_syms >> 3) + 1);
	struct line_debug_entry *text_scan, *data_scan;
d540 2
d543 7
a549 10
	bzero (nlist_bitvector, (number_of_syms >> 3) + 1);

	/* Read in the files strings if they aren't available */
	if (!entry->strings) {
		int desc;

		entry->strings = (char *)alloca(entry->string_size);
		desc = file_open(entry);
		read_entry_strings(desc, entry);
	}
d559 4
a562 3
	/* Scan through all of the nlist entries in this file and pick up
	anything that the scan through the relocation stuff didn't. */

d566 2
a567 2
	for (i = 0; i < number_of_syms; i++) {
		struct nlist *s;
d571 1
a571 1
		s = &entry->symbols[i].nzlist.nlist;
d573 1
a573 1
		if (!(s->n_type & N_EXT))
d576 5
a606 2
			errfmt = "Definition of symbol %s (multiply defined)";
			switch (s->n_type) {
d608 2
d612 1
a612 1
					address_to_line(s->n_value, text_scan);
d618 1
a618 1
					address_to_line(s->n_value, data_scan);
d629 1
a629 1
		"First set element definition of symbol %s (multiply defined)";
d634 1
a634 1
printf("multiply defined: %s, type %#x\n", g->name, s->n_type);
d648 1
a648 1
				errfmt = "More undefined \"%s\" refs follow";
d650 1
a650 1
				errfmt = "Undefined symbol \"%s\" referenced";
d656 1
a656 1
			 * do a reference. The second is if it's the reference
d659 2
a660 2
			if (s->n_type != (N_EXT | N_UNDF) ||
			    (i && (s-1)->n_type == N_WARNING))
d683 1
a683 1
	entry->strings = 0;	/* Since it will dissapear anyway. */
d696 2
a697 1
	    list_warning_symbols || list_multiple_defs))
d702 1
a702 1
		fprintf(outfile, "Undefined entry symbol %s\n",
d704 1
@


1.9
log
@Use `.type' directives generated by gcc.
Numerous internal changes & bug fixes.
NOTE: must re-compile & re-link shared libraries before used to link programs.
@
text
@d2 1
a2 1
 * $Id: warnings.c,v 1.8 1993/12/23 09:37:43 pk Exp $
a5 2
#include <stdio.h>
#include <stdlib.h>
d11 3
a89 64
/*
 * Report a fatal error.  The error message is STRING followed by the
 * filename of ENTRY.
 */
void
#if __STDC__
fatal_with_file (char *fmt, struct file_entry *entry, ...)
#else
fatal_with_file (fmt, entry, va_alist)
	char			*fmt;
	struct file_entry	*entry;
	va_dcl
#endif
{
	va_list	ap;
#if __STDC__
	va_start(ap, fmt);
#else
	va_start(ap);
#endif
	(void)fprintf(stderr, "%s: ", progname);
	(void)vfprintf(stderr, fmt, ap);
	print_file_name (entry, stderr);
	(void)fprintf(stderr, "\n");

	va_end(ap);
	exit (1);
}

/*
 * Report a fatal error using the message for the last failed system call,
 * followed by the string NAME.
 */
void
perror_name (name)
	char *name;
{
	char *s;

	if (errno < sys_nerr)
		s = concat ("", sys_errlist[errno], " for %s");
	else
		s = "cannot open %s";
	fatal (s, name);
}

/*
 * Report a fatal error using the message for the last failed system call,
 * followed by the name of file ENTRY.
 */
void
perror_file (entry)
     struct file_entry *entry;
{
	char *s;

	if (errno < sys_nerr)
		s = concat ("", sys_errlist[errno], " for ");
	else
		s = "cannot open ";
	fatal_with_file (s, entry);
}


d100 1
a100 1
	each_file(describe_file_sections, outfile);
d118 1
a118 1
	each_file(list_file_locals, outfile);
d129 1
a129 1
		fprintf(outfile, " symbols only\n", 0);
d166 1
a166 1

d337 2
a338 3
	struct line_debug_entry
	               *current = state_pointer, *next = state_pointer + 1;
	struct line_debug_entry *tmp_pointer;
d340 2
a341 1
	int             use_data_symbols;
d349 1
a349 1
	/* Go back to the beginning if we've already passed it.  */
d359 2
a360 1
	/* If we're still in a bad way, return -1, meaning invalid line.  */
d367 1
d490 3
a492 2
			errmsg = (char *) xmalloc(strlen(errfmt) + strlen(nm) + 1);
			sprintf(errmsg, errfmt, nm, data_segment ? "data" : "text");
d520 2
a521 2
     struct file_entry *entry;
     FILE *outfile;
d538 3
a540 3
		entry->strings = (char *) alloca (entry->string_size);
		desc = file_open (entry);
		read_entry_strings (desc, entry);
d544 2
a545 2
		/* Do text warnings based on a scan through the relocation info. */
		do_relocation_warnings (entry, 0, outfile, nlist_bitvector);
d547 2
a548 2
		/* Do data warnings based on a scan through the relocation info. */
		do_relocation_warnings (entry, 1, outfile, nlist_bitvector);
d554 2
a555 2
	text_scan = init_debug_scan (0, entry);
	data_scan = init_debug_scan (1, entry);
d597 2
a598 1
				line_number = address_to_line (s->n_value, text_scan);
d603 2
a604 1
				line_number = address_to_line (s->n_value, data_scan);
d614 3
a616 1
				errfmt = "First set element definition of symbol %s (multiply defined)";
d625 1
a625 1
		} else if (BIT_SET_P (nlist_bitvector, i)) {
d627 3
a629 1
		} else if (list_unresolved_refs && !g->defined && !g->so_defined) {
d645 2
a646 2
			if (s->n_type != (N_EXT | N_UNDF)
					|| (i && (s-1)->n_type == N_WARNING))
d656 1
a656 1
			fprintf (outfile, "%s: ", entry->filename);
d658 1
a658 1
			fprintf (outfile, "%s:%d: ", file_name, line_number);
d661 1
a661 1
			fprintf (outfile, "%s", errfmt);
d663 1
a663 1
			fprintf (outfile, errfmt, g->name);
d665 1
a665 1
		fputc ('\n', outfile);
d667 2
a668 2
	free (text_scan);
	free (data_scan);
d682 1
a682 1
			list_warning_symbols || list_multiple_defs))
d687 3
a689 3
		fprintf (outfile, "Undefined entry symbol %s\n",
						entry_symbol->name);
	each_file (do_file_warnings, outfile);
@


1.8
log
@Remove some debris, causing "multiple defined" messages to be missed.
@
text
@d2 1
a2 1
 * $Id: warnings.c,v 1.7 1993/12/20 22:44:44 pk Exp $
a161 2
	register int    i;

a162 1

d166 12
a177 14

	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",
d179 1
a179 2
		}
	}
d191 1
a191 1
	if (entry->just_syms_flag || entry->is_dynamic)
d603 1
a603 1
	if (! entry->is_dynamic) {
d619 1
a619 1
		struct glosym *g;
d627 1
a627 1
		if (!g->referenced) {
d633 2
a634 2
			for (lsp = g->dynrefs; lsp; lsp = lsp->next) {
				type = lsp->nlist.n_type;
d652 1
a652 1
		if (list_multiple_defs && g->multiply_defined) {
d670 1
a670 1
				if (g->multiply_defined == 2)
@


1.7
log
@Hooks for for shared C++ objects with static contructors/destructors.
@
text
@d2 1
a2 1
 * $Id: warnings.c,v 1.6 1993/12/08 10:14:09 pk Exp $
a654 4

		if (undefined_global_sym_count == 0)
			/* No undefined symbols in rel files */
			continue;
@


1.6
log
@Many internal changes, most notably in the symbol counting stuff.
`ld -r -x'  now supported on all object files.
Support for long archive member names (AR_EFMT1 format),
	thanks to Bill Sommerfeld/Mark Eichin
Do the right(?) thing with symbol aliases (N_INDR) for POSIX lover, especially
when equiping shared libraries with these (this was *not* fun).
Handle silly archives (.sa) for people who needs them; turn on by `-Bsilly'.
@
text
@d2 1
a2 1
 * $Id$
d50 4
d71 4
d686 1
d691 1
a691 1
		} else if (BIT_SET_P (nlist_bitvector, i))
d693 1
a693 1
		else if (list_unresolved_refs && !g->defined && !g->so_defined) {
@


1.5
log
@Prototype concat() more strongly, and remove bogus definitions of variables
in system .h files.
@
text
@d2 1
a2 1
 * $Id: warnings.c,v 1.4 1993/11/05 12:45:25 pk Exp $
d165 1
a165 1
			if (sp->defined == 1)
d168 7
a174 3
			if ( sp->referenced) {
				if (sp->defined)
					fprintf(outfile, "  %s: %#x %#x\n",
a175 6
				else
					fprintf(outfile, "  %s: undefined\n",
						sp->name);
			} else
				fprintf(outfile, "  %s: unreferenced\n",
						sp->name);
d189 1
a189 1
	if (entry->just_syms_flag)
d657 1
d662 1
d667 1
a667 1
#if 0
d676 1
a676 1
#endif
d678 1
a678 2
				/* Don't print out multiple defs
					at references.*/
@


1.4
log
@Less spurious "undefined symbol" msgs for shared library defined symbols.
@
text
@d2 1
a2 1
 * $Id: warnings.c,v 1.3 1993/11/01 16:26:20 pk Exp $
d12 1
d116 1
a116 1
     char *name;
a117 2
	extern int errno, sys_nerr;
	extern char *sys_errlist[];
a134 2
	extern int errno, sys_nerr;
	extern char *sys_errlist[];
@


1.3
log
@The N_SET* symbols are back in. C++ object files can now be linked again.
(not yet fit for *shared* C++ libraries).
@
text
@d2 1
a2 1
 * $Id: warnings.c,v 1.2 1993/10/21 00:53:01 pk Exp $
d688 1
a688 1
		else if (list_unresolved_refs && !g->defined) {
@


1.2
log
@No rounding of bss size to page boundary in ZMAGIC a.out's, the kernel
chokes on it.
Some other minor changes.
@
text
@d2 1
a2 1
 * $Id: warnings.c,v 1.1 1993/10/16 21:52:36 pk Exp $
d519 1
a519 1
		if (!g->defined && list_unresolved_refs) {	/* Reference */
@


1.1
log
@A linker supporting shared libraries.
@
text
@d2 1
a2 1
 * $Id$
d169 1
a169 1
				fprintf(outfile, "  %s: common, length 0x%x\n",
d173 2
a174 2
					fprintf(outfile, "  %s: 0x%x\n",
						sp->name, sp->value);
@
