summaryrefslogtreecommitdiffstats
path: root/gnu/usr.bin/ld/warnings.c
diff options
context:
space:
mode:
authornate <nate@FreeBSD.org>1994-12-23 22:31:35 +0000
committernate <nate@FreeBSD.org>1994-12-23 22:31:35 +0000
commit7f56eb7b93f7774321c3f5924447d96ffcb858b9 (patch)
tree44d4ecee16a0e6d497426a41a2bdd4542c4c3342 /gnu/usr.bin/ld/warnings.c
parent92495f8331471c4b72fe0037463cdac16b87b02e (diff)
downloadFreeBSD-src-7f56eb7b93f7774321c3f5924447d96ffcb858b9.zip
FreeBSD-src-7f56eb7b93f7774321c3f5924447d96ffcb858b9.tar.gz
Updated to recent version of Paul K.'s shlib code. This code has better
warning handling and allows for link-time warnings with a modified version of gas. Note: Not all of the newer bits were updated such as some of the non-x86 machine-dependant code is relevant to FreeBSD right now. Obtained from: NetBSD
Diffstat (limited to 'gnu/usr.bin/ld/warnings.c')
-rw-r--r--gnu/usr.bin/ld/warnings.c229
1 files changed, 116 insertions, 113 deletions
diff --git a/gnu/usr.bin/ld/warnings.c b/gnu/usr.bin/ld/warnings.c
index 6ae1be9..0479344 100644
--- a/gnu/usr.bin/ld/warnings.c
+++ b/gnu/usr.bin/ld/warnings.c
@@ -1,5 +1,5 @@
/*
- * $Id: warnings.c,v 1.7 1994/06/14 12:45:41 csgr Exp $
+ * $Id: warnings.c,v 1.8 1994/06/15 22:40:00 rich Exp $
*/
#include <sys/param.h>
@@ -141,8 +141,8 @@ list_file_locals (entry, outfile)
{
struct localsymbol *lsp, *lspend;
- entry->strings = (char *) alloca (entry->string_size);
- read_entry_strings (file_open (entry), entry);
+ entry->strings = (char *)alloca(entry->string_size);
+ read_entry_strings (file_open(entry), entry);
fprintf (outfile, "\nLocal symbols of ");
print_file_name (entry, outfile);
@@ -163,14 +163,13 @@ list_file_locals (entry, outfile)
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_warning_symbols; /* List warning syms */
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 *));
+static int next_debug_entry __P((int, struct line_debug_entry *));
/*
* Structure for communication between do_file_warnings and it's
@@ -188,28 +187,32 @@ struct line_debug_entry
* 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. */
+/*
+ * 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
-relocation_entries_relation(rel1, rel2)
- struct relocation_info *rel1, *rel2;
+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. */
+/*
+ * 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 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,
@@ -217,15 +220,15 @@ next_debug_entry(use_data_symbols, state_pointer)
/* Used to store source file */
*source = state_pointer + 2;
- struct file_entry *entry = (struct file_entry *) source->sym;
- struct localsymbol *endp = entry->symbols + entry->nsymbols;
+ 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) < endp) {
+ while (++(next->sym) < lspend) {
struct nlist *np = &next->sym->nzlist.nlist;
@@ -235,11 +238,13 @@ next_debug_entry(use_data_symbols, state_pointer)
*/
switch (np->n_type & 0xff) {
case N_SLINE:
- if (use_data_symbols) continue;
+ if (use_data_symbols)
+ continue;
next->line = np->n_desc;
return 1;
case N_DSLINE:
- if (!use_data_symbols) continue;
+ if (!use_data_symbols)
+ continue;
next->line = np->n_desc;
return 1;
#ifdef HAVE_SUN_STABS
@@ -266,39 +271,41 @@ next_debug_entry(use_data_symbols, state_pointer)
/*
* 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.
+ * 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;
+ int use_data_symbols;
+ struct file_entry *entry;
{
- struct localsymbol *lsp;
- struct line_debug_entry *state_pointer = (struct line_debug_entry *)
- xmalloc(3 * sizeof(struct line_debug_entry));
+ register struct localsymbol *lsp, *lspend;
+ struct line_debug_entry *state_pointer, *current, *next, *source;
- register struct line_debug_entry
- *current = state_pointer,
- *next = state_pointer + 1,
- *source = state_pointer + 2; /* Used to store source file */
+ 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 < entry->symbols+entry->nsymbols; lsp++)
+ for (lsp = entry->symbols; lsp < lspend; lsp++)
if (lsp->nzlist.nlist.n_type == N_SO)
break;
- if (lsp >= entry->symbols + entry->nsymbols) {
+ 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;
+ 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;
+ source->sym = (struct localsymbol *)entry;
next->sym = lsp;
/* To setup next */
@@ -335,7 +342,7 @@ address_to_line(address, state_pointer)
struct line_debug_entry state_pointer[3];
{
struct line_debug_entry *current, *next, *tmp_pointer;
- int use_data_symbols;
+ int use_data_symbols;
current = state_pointer;
next = state_pointer + 1;
@@ -346,7 +353,7 @@ address_to_line(address, state_pointer)
else
return current->line;
- /* Go back to the beginning if we've already passed it. */
+ /* 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 *)
@@ -357,7 +364,7 @@ address_to_line(address, state_pointer)
free(tmp_pointer);
}
- /* If we're still in a bad way, return -1, meaning invalid line. */
+ /* If we're still in a bad way, return -1, meaning invalid line. */
if (current->sym->nzlist.nlist.n_value > address)
return -1;
@@ -391,22 +398,12 @@ do_relocation_warnings(entry, data_segment, outfile, nlist_bitvector)
FILE *outfile;
unsigned char *nlist_bitvector;
{
- 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;
-
+ 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.
@@ -414,28 +411,32 @@ do_relocation_warnings(entry, data_segment, outfile, nlist_bitvector)
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);
- qsort(reloc_start, reloc_size, sizeof(struct relocation_info),
- relocation_entries_relation);
-
- for (reloc = reloc_start;
- reloc < (reloc_start + reloc_size);
- reloc++) {
+ for (; rp < erp; rp++) {
register struct localsymbol *lsp;
register symbol *g;
/*
- * If the relocation isn't resolved through a symbol,
- * continue
+ * If the relocation isn't resolved through a symbol, continue.
*/
- if (!RELOC_EXTERN_P(reloc))
+ if (!RELOC_EXTERN_P(rp))
continue;
- lsp = &entry->symbols[RELOC_SYMBOL(reloc)];
+ lsp = &entry->symbols[RELOC_SYMBOL(rp)];
/*
* Local symbols shouldn't ever be used by relocation info,
@@ -459,7 +460,7 @@ do_relocation_warnings(entry, data_segment, outfile, nlist_bitvector)
errmsg = 0;
if (!g->defined && !g->so_defined && list_unresolved_refs) {
- /* Mark as being noted by relocation warning pass. */
+ /* Mark as being noted by relocation warning pass. */
SET_BIT(nlist_bitvector, lsp - start_of_syms);
if (g->undef_refs >= MAX_UREFS_PRINTED)
@@ -481,6 +482,9 @@ do_relocation_warnings(entry, data_segment, outfile, nlist_bitvector)
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);
@@ -501,12 +505,14 @@ do_relocation_warnings(entry, data_segment, outfile, nlist_bitvector)
if (nm != g->name)
free(nm);
}
- address_to_line(RELOC_ADDRESS(reloc) + start_of_segment,
+ 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);
+ fprintf(outfile, "%s:%d: %s\n",
+ current->filename,
+ invalidate_line_number ? 0 : current->line,
+ errmsg);
else
fprintf(outfile, "%s: %s\n", current->filename, errmsg);
@@ -525,28 +531,24 @@ do_relocation_warnings(entry, data_segment, outfile, nlist_bitvector)
void
do_file_warnings (entry, outfile)
- struct file_entry *entry;
- FILE *outfile;
+ struct file_entry *entry;
+ FILE *outfile;
{
- 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;
+ 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;
- bzero (nlist_bitvector, (number_of_syms >> 3) + 1);
+ nsym = entry->nsymbols;
+ nlist_bitvector = (u_char *)alloca((nsym >> 3) + 1);
+ bzero(nlist_bitvector, (nsym >> 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);
- }
+ /* 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. */
@@ -563,26 +565,17 @@ do_file_warnings (entry, outfile)
text_scan = init_debug_scan(0, entry);
data_scan = init_debug_scan(1, entry);
- for (i = 0; i < number_of_syms; i++) {
- struct nlist *s;
+ for (i = 0; i < nsym; i++) {
+ struct nlist *np;
symbol *g;
g = entry->symbols[i].symbol;
- s = &entry->symbols[i].nzlist.nlist;
-
- /*
- * XXX This is a temporary fence to correct an
- * incorrect assumption made in the case of symbols
- * which do not have entries in the (global)
- * symbol table.
- */
- if(g == NULL)
- continue;
+ np = &entry->symbols[i].nzlist.nlist;
if (g == NULL)
continue;
- if (!(s->n_type & N_EXT) && !SET_ELEMENT_P(s->n_type)) {
+ if (!(np->n_type & N_EXT) && !SET_ELEMENT_P(np->n_type)) {
warnx("internal error: `%s' N_EXT not set", g->name);
continue;
}
@@ -613,18 +606,18 @@ do_file_warnings (entry, outfile)
dont_allow_symbol_name = 0;
if (list_multiple_defs && g->mult_defs) {
- errfmt = "Definition of symbol `%s' (multiply defined)";
- switch (s->n_type) {
+ errfmt = "Definition of symbol `%s' (multiply defined)";
+ switch (np->n_type) {
case N_TEXT | N_EXT:
line_number =
- address_to_line(s->n_value, text_scan);
+ 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(s->n_value, data_scan);
+ address_to_line(np->n_value, data_scan);
file_name = data_scan[0].filename;
break;
@@ -635,12 +628,12 @@ do_file_warnings (entry, outfile)
if (g->mult_defs == 2)
continue;
errfmt =
- "First set element definition of symbol %s (multiply defined)";
+ "First set element definition of symbol `%s' (multiply defined)";
line_number = -1;
break;
default:
-printf("multiply defined: %s, type %#x\n", g->name, s->n_type);
+warnx("Unexpected multiple definitions of symbol `%s', type %#x\n", g->name, np->n_type);
/* Don't print out multiple defs at references.*/
continue;
}
@@ -654,19 +647,28 @@ printf("multiply defined: %s, type %#x\n", g->name, s->n_type);
continue;
if (++(g->undef_refs) == MAX_UREFS_PRINTED)
- errfmt = "More undefined \"%s\" refs follow";
+ errfmt = "More undefined `%s' refs follow";
else
- errfmt = "Undefined symbol \"%s\" referenced";
+ 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",
+ entry->filename,
+ 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
- * do a reference. The second is if it's the reference
+ * of a reference. The second is if it's the reference
* used by the warning stabs itself.
*/
- if (s->n_type != (N_EXT | N_UNDF) ||
- (i && (s-1)->n_type == N_WARNING))
+ if (np->n_type != (N_EXT | N_UNDF) ||
+ (entry->symbols[i].flags & LS_WARNING))
continue;
errfmt = g->warning;
@@ -689,7 +691,7 @@ printf("multiply defined: %s, type %#x\n", g->name, s->n_type);
}
free(text_scan);
free(data_scan);
- entry->strings = 0; /* Since it will dissapear anyway. */
+ entry->strings = 0; /* Since it will disappear anyway. */
}
int
@@ -698,17 +700,18 @@ do_warnings(outfile)
{
list_unresolved_refs = !relocatable_output &&
(undefined_global_sym_count || undefined_shobj_sym_count);
- list_warning_symbols = warning_count;
list_multiple_defs = multiple_def_count != 0;
if (!(list_unresolved_refs ||
- list_warning_symbols || list_multiple_defs))
+ 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);
+ fprintf(outfile, "Undefined entry symbol `%s'\n",
+ entry_symbol->name);
+
each_file(do_file_warnings, (void *)outfile);
if (list_unresolved_refs || list_multiple_defs)
OpenPOWER on IntegriCloud