Initial import from FreeBSD RELENG_4:
[dragonfly.git] / gnu / usr.bin / ld / warnings.c
1 /*-
2  * This code is derived from software copyrighted by the Free Software
3  * Foundation.
4  *
5  * Modified 1991 by Donn Seeley at UUNET Technologies, Inc.
6  *
7  * Modified 1993 by Paul Kranenburg, Erasmus University
8  */
9
10 /* Derived from ld.c: "@(#)ld.c 6.10 (Berkeley) 5/22/91"; */
11
12 /* Linker `ld' for GNU
13    Copyright (C) 1988 Free Software Foundation, Inc.
14
15    This program is free software; you can redistribute it and/or modify
16    it under the terms of the GNU General Public License as published by
17    the Free Software Foundation; either version 1, or (at your option)
18    any later version.
19
20    This program is distributed in the hope that it will be useful,
21    but WITHOUT ANY WARRANTY; without even the implied warranty of
22    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23    GNU General Public License for more details.
24
25    You should have received a copy of the GNU General Public License
26    along with this program; if not, write to the Free Software
27    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
28
29 /* Written by Richard Stallman with some help from Eric Albert.
30    Set, indirect, and warning symbol features added by Randy Smith. */
31
32 /*
33  * $FreeBSD: src/gnu/usr.bin/ld/warnings.c,v 1.18 1999/08/27 23:36:02 peter Exp $
34  */
35
36 #include <sys/param.h>
37 #include <sys/types.h>
38 #include <sys/stat.h>
39 #include <sys/file.h>
40 #include <sys/time.h>
41 #include <sys/errno.h>
42 #include <err.h>
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <fcntl.h>
46 #include <ar.h>
47 #include <ranlib.h>
48 #include <a.out.h>
49 #include <stab.h>
50 #include <string.h>
51 #if __STDC__
52 #include <stdarg.h>
53 #else
54 #include <varargs.h>
55 #endif
56
57 #include "ld.h"
58 #include "dynamic.h"
59
60 static int reported_undefineds;
61
62 #ifdef DEMANGLE_CPLUSPLUS
63 #include "demangle.h"
64
65 char *demangle(name)
66      char *name;
67 {
68   static char* saved_result = NULL;
69
70   if (saved_result)
71     free (saved_result);
72
73   saved_result = cplus_demangle (name[0] == '_' ? name + 1 : name, DMGL_PARAMS | DMGL_ANSI);
74
75   if (saved_result)
76     return saved_result;
77   else
78     return name;
79 }
80 #endif
81
82 /*
83  * Print the filename of ENTRY on OUTFILE (a stdio stream),
84  * and then a newline.
85  */
86
87 void
88 prline_file_name (entry, outfile)
89      struct file_entry *entry;
90      FILE *outfile;
91 {
92         print_file_name (entry, outfile);
93         fprintf (outfile, "\n");
94 }
95
96 /*
97  * Print the filename of ENTRY on OUTFILE (a stdio stream).
98  */
99
100 void
101 print_file_name (entry, outfile)
102      struct file_entry *entry;
103      FILE *outfile;
104 {
105         if (entry == NULL) {
106                 fprintf (outfile, "NULL");
107         }
108
109         if (entry->superfile) {
110                 print_file_name (entry->superfile, outfile);
111                 fprintf (outfile, "(%s)", entry->filename);
112         } else
113                 fprintf (outfile, "%s", entry->filename);
114 }
115
116 /*
117  * Return the filename of entry as a string (malloc'd for the purpose)
118  */
119
120 char *
121 get_file_name (entry)
122      struct file_entry *entry;
123 {
124         char *result, *supfile;
125
126         if (entry == NULL) {
127                 return (char *)strdup("NULL");
128         }
129
130         if (entry->superfile) {
131                 supfile = get_file_name(entry->superfile);
132                 result = (char *)
133                         xmalloc(strlen(supfile) + strlen(entry->filename) + 3);
134                 (void)sprintf(result, "%s(%s)", supfile, entry->filename);
135                 free(supfile);
136
137         } else {
138                 result = (char *)xmalloc(strlen(entry->filename) + 1);
139                 strcpy(result, entry->filename);
140         }
141         return result;
142 }
143
144 /* Print a complete or partial map of the output file. */
145
146 static void     describe_file_sections __P((struct file_entry *, FILE *));
147 static void     list_file_locals __P((struct file_entry *, FILE *));
148
149 void
150 print_symbols(outfile)
151         FILE           *outfile;
152 {
153         fprintf(outfile, "\nFiles:\n\n");
154         each_file(describe_file_sections, (void *)outfile);
155
156         fprintf(outfile, "\nGlobal symbols:\n\n");
157         FOR_EACH_SYMBOL(i, sp) {
158                 fprintf(outfile, "  %s: ", demangle(sp->name));
159                 if (!(sp->flags & GS_REFERENCED))
160                         fprintf(outfile, "unreferenced");
161                 else if (sp->so_defined)
162                         fprintf(outfile, "sodefined");
163                 else if (!sp->defined)
164                         fprintf(outfile, "undefined");
165                 else if (sp->defined == (N_UNDF|N_EXT))
166                         fprintf(outfile, "common: size %#x", sp->common_size);
167                 else
168                         fprintf(outfile, "type %d, value %#lx, size %#x",
169                                 sp->defined, sp->value, sp->size);
170                 if (sp->alias)
171                         fprintf(outfile, ", aliased to %s", demangle(sp->alias->name));
172                 fprintf(outfile, "\n");
173         } END_EACH_SYMBOL;
174
175         each_file(list_file_locals, (void *)outfile);
176 }
177
178 static void
179 describe_file_sections(entry, outfile)
180         struct file_entry *entry;
181         FILE           *outfile;
182 {
183         fprintf(outfile, "  ");
184         print_file_name(entry, outfile);
185         if (entry->flags & (E_JUST_SYMS | E_DYNAMIC))
186                 fprintf(outfile, " symbols only\n");
187         else
188                 fprintf(outfile,
189                         " text %x(%lx), data %x(%lx), bss %x(%lx) hex\n",
190                         entry->text_start_address,
191                         (unsigned long)entry->header.a_text,
192                         entry->data_start_address,
193                         (unsigned long)entry->header.a_data,
194                         entry->bss_start_address,
195                         (unsigned long)entry->header.a_bss);
196 }
197
198 static void
199 list_file_locals (entry, outfile)
200      struct file_entry *entry;
201      FILE *outfile;
202 {
203         struct localsymbol      *lsp, *lspend;
204
205         entry->strings = (char *)alloca(entry->string_size);
206         read_entry_strings (file_open(entry), entry);
207
208         fprintf (outfile, "\nLocal symbols of ");
209         print_file_name (entry, outfile);
210         fprintf (outfile, ":\n\n");
211
212         lspend = entry->symbols + entry->nsymbols;
213         for (lsp = entry->symbols; lsp < lspend; lsp++) {
214                 register struct nlist *p = &lsp->nzlist.nlist;
215                 /*
216                  * If this is a definition,
217                  * update it if necessary by this file's start address.
218                  */
219                 if (!(p->n_type & (N_STAB | N_EXT)))
220                         fprintf(outfile, "  %s: 0x%lx\n",
221                                 entry->strings + p->n_un.n_strx, p->n_value);
222         }
223
224         entry->strings = 0;             /* All done with them.  */
225 }
226
227
228 /* Static vars for do_warnings and subroutines of it */
229 static int list_unresolved_refs;        /* List unresolved refs */
230 static int list_multiple_defs;          /* List multiple definitions */
231
232 static struct line_debug_entry *init_debug_scan __P((int, struct file_entry *));
233 static int      next_debug_entry __P((int, struct line_debug_entry *));
234 static int      address_to_line __P((unsigned long, struct line_debug_entry *));
235
236 /*
237  * Structure for communication between do_file_warnings and it's
238  * helper routines.  Will in practice be an array of three of these:
239  * 0) Current line, 1) Next line, 2) Source file info.
240  */
241 struct line_debug_entry
242 {
243         int                     line;
244         char                    *filename;
245         struct localsymbol      *sym;
246 };
247
248 /*
249  * Helper routines for do_file_warnings.
250  */
251
252 /*
253  * Return an integer less than, equal to, or greater than 0 as per the
254  * relation between the two relocation entries.  Used by qsort.
255  */
256
257 static int
258 reloc_cmp(rel1, rel2)
259         struct relocation_info *rel1, *rel2;
260 {
261         return RELOC_ADDRESS(rel1) - RELOC_ADDRESS(rel2);
262 }
263
264 /*
265  * Moves to the next debugging symbol in the file.  USE_DATA_SYMBOLS
266  * determines the type of the debugging symbol to look for (DSLINE or
267  * SLINE).  STATE_POINTER keeps track of the old and new locatiosn in
268  * the file.  It assumes that state_pointer[1] is valid; ie
269  * that it.sym points into some entry in the symbol table.  If
270  * state_pointer[1].sym == 0, this routine should not be called.
271  */
272
273 static int
274 next_debug_entry(use_data_symbols, state_pointer)
275         register int use_data_symbols;
276         /* Next must be passed by reference! */
277         struct line_debug_entry state_pointer[3];
278 {
279         register struct line_debug_entry
280                                 *current = state_pointer,
281                                 *next = state_pointer + 1,
282                                 /* Used to store source file */
283                                 *source = state_pointer + 2;
284
285         struct file_entry       *entry = (struct file_entry *)source->sym;
286         struct localsymbol      *lspend = entry->symbols + entry->nsymbols;
287
288
289         current->sym = next->sym;
290         current->line = next->line;
291         current->filename = next->filename;
292
293         while (++(next->sym) < lspend) {
294
295                 struct nlist    *np = &next->sym->nzlist.nlist;
296
297                 /*
298                  * n_type is a char, and N_SOL, N_EINCL and N_BINCL are > 0x80,
299                  * so may look negative...therefore, must mask to low bits
300                  */
301                 switch (np->n_type & 0xff) {
302                 case N_SLINE:
303                         if (use_data_symbols)
304                                 continue;
305                         next->line = np->n_desc;
306                         return 1;
307                 case N_DSLINE:
308                         if (!use_data_symbols)
309                                 continue;
310                         next->line = np->n_desc;
311                         return 1;
312 #ifdef HAVE_SUN_STABS
313                 case N_EINCL:
314                         next->filename = source->filename;
315                         continue;
316 #endif
317                 case N_SO:
318                         source->filename = np->n_un.n_strx + entry->strings;
319                         source->line++;
320 #ifdef HAVE_SUN_STABS
321                 case N_BINCL:
322 #endif
323                 case N_SOL:
324                         next->filename = np->n_un.n_strx + entry->strings;
325                 default:
326                         continue;
327                 }
328         }
329         next->sym = (struct localsymbol *)0;
330         return 0;
331 }
332
333 /*
334  * Create a structure to save the state of a scan through the debug symbols.
335  * USE_DATA_SYMBOLS is set if we should be scanning for DSLINE's instead of
336  * SLINE's. ENTRY is the file entry which points at the symbols to use.
337  */
338
339 static struct line_debug_entry *
340 init_debug_scan(use_data_symbols, entry)
341         int                     use_data_symbols;
342         struct file_entry       *entry;
343 {
344         register struct localsymbol     *lsp, *lspend;
345         struct line_debug_entry *state_pointer, *current, *next, *source;
346
347         state_pointer = (struct line_debug_entry *)
348                 xmalloc(3 * sizeof(*state_pointer));
349
350         current = state_pointer,
351         next = state_pointer + 1,
352         source = state_pointer + 2;     /* Used to store source file */
353
354         lspend = entry->symbols+entry->nsymbols;
355
356         for (lsp = entry->symbols; lsp < lspend; lsp++)
357                 if (lsp->nzlist.nlist.n_type == N_SO)
358                         break;
359
360         if (lsp >= lspend) {
361                 /* I believe this translates to "We lose" */
362                 current->filename = next->filename = entry->filename;
363                 current->line = next->line = -1;
364                 current->sym = next->sym = (struct localsymbol *)0;
365                 return state_pointer;
366         }
367         next->line = source->line = 0;
368         next->filename = source->filename
369                         = (lsp->nzlist.nlist.n_un.n_strx + entry->strings);
370         source->sym = (struct localsymbol *)entry;
371         next->sym = lsp;
372
373         /* To setup next */
374         next_debug_entry(use_data_symbols, state_pointer);
375
376         if (!next->sym) {       /* No line numbers for this section; */
377                 /* setup output results as appropriate */
378                 if (source->line) {
379                         current->filename = source->filename = entry->filename;
380                         current->line = -1;     /* Don't print lineno */
381                 } else {
382                         current->filename = source->filename;
383                         current->line = 0;
384                 }
385                 return state_pointer;
386         }
387         /* To setup current */
388         next_debug_entry(use_data_symbols, state_pointer);
389
390         return state_pointer;
391 }
392
393 /*
394  * Takes an ADDRESS (in either text or data space) and a STATE_POINTER which
395  * describes the current location in the implied scan through the debug
396  * symbols within the file which ADDRESS is within, and returns the source
397  * line number which corresponds to ADDRESS.
398  */
399
400 static int
401 address_to_line(address, state_pointer)
402         unsigned long   address;
403 /* Next must be passed by reference! */
404         struct line_debug_entry state_pointer[3];
405 {
406         struct line_debug_entry *current, *next, *tmp_pointer;
407         int                     use_data_symbols;
408
409         current = state_pointer;
410         next = state_pointer + 1;
411
412         if (next->sym)
413                 use_data_symbols =
414                         (next->sym->nzlist.nlist.n_type & N_TYPE) == N_DATA;
415         else
416                 return current->line;
417
418         /* Go back to the beginning if we've already passed it. */
419         if (current->sym->nzlist.nlist.n_value > address) {
420                 tmp_pointer = init_debug_scan(use_data_symbols,
421                                               (struct file_entry *)
422                                               ((state_pointer + 2)->sym));
423                 state_pointer[0] = tmp_pointer[0];
424                 state_pointer[1] = tmp_pointer[1];
425                 state_pointer[2] = tmp_pointer[2];
426                 free(tmp_pointer);
427         }
428
429         /* If we're still in a bad way, return -1, meaning invalid line. */
430         if (current->sym->nzlist.nlist.n_value > address)
431                 return -1;
432
433         while (next->sym
434                && next->sym->nzlist.nlist.n_value <= address
435                && next_debug_entry(use_data_symbols, state_pointer));
436
437         return current->line;
438 }
439
440
441 /* Macros for manipulating bitvectors.  */
442 #define BIT_SET_P(bv, index)    ((bv)[(index) >> 3] & 1 << ((index) & 0x7))
443 #define SET_BIT(bv, index)      ((bv)[(index) >> 3] |= 1 << ((index) & 0x7))
444
445 /*
446  * This routine will scan through the relocation data of file ENTRY, printing
447  * out references to undefined symbols and references to symbols defined in
448  * files with N_WARNING symbols.  If DATA_SEGMENT is non-zero, it will scan
449  * the data relocation segment (and use N_DSLINE symbols to track line
450  * number); otherwise it will scan the text relocation segment.  Warnings
451  * will be printed on the output stream OUTFILE.  Eventually, every nlist
452  * symbol mapped through will be marked in the NLIST_BITVECTOR, so we don't
453  * repeat ourselves when we scan the nlists themselves.
454  */
455
456 static void
457 do_relocation_warnings(entry, data_segment, outfile, nlist_bitvector)
458         struct file_entry *entry;
459         int             data_segment;
460         FILE           *outfile;
461         unsigned char  *nlist_bitvector;
462 {
463         struct relocation_info  *rp, *erp;
464         int                     start_of_segment;
465         struct localsymbol      *start_of_syms;
466         struct line_debug_entry *state_pointer, *current;
467         /* Assigned to generally static values; should not be written into.  */
468         char *errfmt;
469         /*
470          * Assigned to alloca'd values cand copied into; should be freed when
471          * done.
472          */
473         char *errmsg;
474         int  invalidate_line_number;
475
476         rp = data_segment ? entry->datarel : entry->textrel;
477         erp = data_segment ? (rp + entry->ndatarel) : (rp + entry->ntextrel);
478         start_of_syms = entry->symbols;
479         start_of_segment = (data_segment ?
480                 entry->data_start_address :
481                 entry->text_start_address);
482         state_pointer = init_debug_scan(data_segment != 0, entry);
483         current = state_pointer;
484
485         /*
486          * We need to sort the relocation info here.  Sheesh, so much effort
487          * for one lousy error optimization.
488          */
489         qsort(rp, erp - rp, sizeof(rp[0]), reloc_cmp);
490
491         for (; rp < erp; rp++) {
492                 register struct localsymbol *lsp;
493                 register symbol *g;
494
495                 /*
496                  * If the relocation isn't resolved through a symbol, continue.
497                  */
498                 if (!RELOC_EXTERN_P(rp))
499                         continue;
500
501                 lsp = &entry->symbols[RELOC_SYMBOL(rp)];
502
503                 /*
504                  * Local symbols shouldn't ever be used by relocation info,
505                  * so the next should be safe. This is, of course, wrong.
506                  * References to local BSS symbols can be the targets of
507                  * relocation info, and they can (must) be resolved through
508                  * symbols.  However, these must be defined properly, (the
509                  * assembler would have caught it otherwise), so we can
510                  * ignore these cases.
511                  */
512
513                 if ((g = lsp->symbol) == NULL)
514                         continue;
515
516                 if (!(lsp->nzlist.nz_type & N_EXT) &&
517                     !SET_ELEMENT_P(lsp->nzlist.nz_type)) {
518                         warnx("internal error: `%s' N_EXT not set", demangle(g->name));
519                         continue;
520                 }
521
522                 errmsg = 0;
523
524                 if (!g->defined && !g->so_defined && list_unresolved_refs) {
525                         /* Mark as being noted by relocation warning pass. */
526                         SET_BIT(nlist_bitvector, lsp - start_of_syms);
527
528                         if (g->undef_refs == 0)
529                                 reported_undefineds++;
530                         if (g->undef_refs >= MAX_UREFS_PRINTED)
531                                 /* Listed too many */
532                                 continue;
533                         /* Undefined symbol which we should mention */
534
535                         if (++(g->undef_refs) == MAX_UREFS_PRINTED) {
536                                 errfmt = "More undefined symbol %s refs follow";
537                                 invalidate_line_number = 1;
538                         } else {
539                                 errfmt =
540                         "Undefined symbol `%s' referenced from %s segment";
541                                 invalidate_line_number = 0;
542                         }
543                 } else {        /* Defined */
544                         /* Potential symbol warning here */
545                         if (!g->warning)
546                                 continue;
547
548                         if (BIT_SET_P(nlist_bitvector, lsp - start_of_syms))
549                                 continue;
550
551                         /* Mark as being noted by relocation warning pass.  */
552                         SET_BIT(nlist_bitvector, lsp - start_of_syms);
553
554                         errfmt = 0;
555                         errmsg = g->warning;
556                         invalidate_line_number = 0;
557                 }
558
559
560                 /* If errfmt == 0, errmsg has already been defined.  */
561                 if (errfmt != 0) {
562                         char *nm = demangle(g->name);
563                         errmsg = (char *)
564                                 xmalloc(strlen(errfmt) + strlen(nm) + 1);
565                         sprintf(errmsg, errfmt, nm, data_segment?"data":"text");
566                 }
567                 address_to_line(RELOC_ADDRESS(rp) + start_of_segment,
568                                 state_pointer);
569
570                 if (current->line >= 0)
571                         fprintf(outfile, "%s:%d: %s\n",
572                                 current->filename,
573                                 invalidate_line_number ? 0 : current->line,
574                                 errmsg);
575                 else
576                         fprintf(outfile, "%s: %s\n", current->filename, errmsg);
577
578                 if (errfmt != 0)
579                         free(errmsg);
580         }
581
582         free(state_pointer);
583 }
584
585 /*
586  * Print on OUTFILE a list of all warnings generated by references and/or
587  * definitions in the file ENTRY.  List source file and line number if
588  * possible, just the .o file if not.
589  */
590
591 void
592 do_file_warnings (entry, outfile)
593         struct file_entry       *entry;
594         FILE                    *outfile;
595 {
596         int     nsym;
597         int     i;
598         char    *errfmt, *file_name;
599         int     line_number;
600         int     dont_allow_symbol_name;
601         u_char  *nlist_bitvector;
602         struct line_debug_entry *text_scan, *data_scan;
603
604         nsym = entry->nsymbols;
605         nlist_bitvector = (u_char *)alloca((nsym >> 3) + 1);
606         bzero(nlist_bitvector, (nsym >> 3) + 1);
607
608         /* Read in the strings */
609         entry->strings = (char *)alloca(entry->string_size);
610         read_entry_strings(file_open(entry), entry);
611
612         if (!(entry->flags & E_DYNAMIC)) {
613                 /* Do text warnings based on a scan through the reloc info. */
614                 do_relocation_warnings(entry, 0, outfile, nlist_bitvector);
615
616                 /* Do data warnings based on a scan through the reloc info. */
617                 do_relocation_warnings(entry, 1, outfile, nlist_bitvector);
618         }
619
620         /*
621          * Scan through all of the nlist entries in this file and pick up
622          * anything that the scan through the relocation stuff didn't.
623          */
624         text_scan = init_debug_scan(0, entry);
625         data_scan = init_debug_scan(1, entry);
626
627         for (i = 0; i < nsym; i++) {
628                 struct nlist *np;
629                 symbol *g;
630
631                 g = entry->symbols[i].symbol;
632                 np = &entry->symbols[i].nzlist.nlist;
633
634                 if (g == NULL)
635                         continue;
636
637                 if (!(np->n_type & N_EXT) && !SET_ELEMENT_P(np->n_type)) {
638                         warnx("internal error: `%s' N_EXT not set", demangle(g->name));
639                         continue;
640                 }
641
642                 if (!(g->flags & GS_REFERENCED)) {
643 #if 0
644                         /* Check for undefined shobj symbols */
645                         struct localsymbol      *lsp;
646                         register int            type;
647
648                         for (lsp = g->sorefs; lsp; lsp = lsp->next) {
649                                 type = lsp->nzlist.nz_type;
650                                 if ((type & N_EXT) &&
651                                                 type != (N_UNDF | N_EXT)) {
652                                         break;
653                                 }
654                         }
655                         if (type == (N_UNDF | N_EXT)) {
656                                 fprintf(stderr,
657                                         "Undefined symbol %s referenced from %s\n",
658                                         demangle(g->name),
659                                         get_file_name(entry));
660                         }
661 #endif
662                         continue;
663                 }
664
665                 dont_allow_symbol_name = 0;
666
667                 if (list_multiple_defs && g->mult_defs) {
668
669                         errfmt = "Definition of symbol `%s' (multiply defined)";
670                         switch (np->n_type) {
671                         case N_TEXT | N_EXT:
672                                 line_number =
673                                         address_to_line(np->n_value, text_scan);
674                                 file_name = text_scan[0].filename;
675                                 break;
676
677                         case N_DATA | N_EXT:
678                                 line_number =
679                                         address_to_line(np->n_value, data_scan);
680                                 file_name = data_scan[0].filename;
681                                 break;
682
683                         case N_SETA | N_EXT:
684                         case N_SETT | N_EXT:
685                         case N_SETD | N_EXT:
686                         case N_SETB | N_EXT:
687                                 if (g->mult_defs == 2)
688                                         continue;
689                                 errfmt =
690         "First set element definition of symbol `%s' (multiply defined)";
691                                 line_number = -1;
692                                 break;
693
694                         case N_SIZE | N_EXT:
695                                 errfmt =
696         "Size element definition of symbol `%s' (multiply defined)";
697                                 line_number = -1;
698                                 break;
699
700                         case N_INDR | N_EXT:
701                                 errfmt =
702         "Alias definition of symbol `%s' (multiply defined)";
703                                 line_number = -1;
704                                 break;
705
706                         case N_UNDF | N_EXT:
707                                 /* Don't print out multiple defs at references.*/
708                                 continue;
709
710                         default:
711                                 warnx("%s: unexpected multiple definitions "
712                                       "of symbol `%s', type %#x",
713                                       get_file_name(entry),
714                                       demangle(g->name), np->n_type);
715                                 break;
716                         }
717
718                 } else if (BIT_SET_P(nlist_bitvector, i)) {
719                         continue;
720                 } else if (list_unresolved_refs &&
721                            !g->defined && !g->so_defined) {
722
723                         if (g->undef_refs == 0)
724                                 reported_undefineds++;
725                         if (g->undef_refs >= MAX_UREFS_PRINTED)
726                                 continue;
727                         if (++(g->undef_refs) == MAX_UREFS_PRINTED)
728                                 errfmt = "More undefined `%s' refs follow";
729                         else
730                                 errfmt = "Undefined symbol `%s' referenced";
731                         line_number = -1;
732                 } else if (g->def_lsp && g->def_lsp->entry != entry &&
733                            !(entry->flags & E_DYNAMIC) &&
734                            g->def_lsp->entry->flags & E_SECONDCLASS) {
735                         fprintf(outfile,
736                         "%s: Undefined symbol `%s' referenced (use %s ?)\n",
737                                 get_file_name(entry),
738                                 demangle(g->name),
739                                 g->def_lsp->entry->local_sym_name);
740                         continue;
741                 } else if (g->warning) {
742                         /*
743                          * There are two cases in which we don't want to do
744                          * this. The first is if this is a definition instead
745                          * of a reference. The second is if it's the reference
746                          * used by the warning stabs itself.
747                          */
748                         if (np->n_type != (N_EXT | N_UNDF) ||
749                             (entry->symbols[i].flags & LS_WARNING))
750                                 continue;
751
752                         errfmt = g->warning;
753                         line_number = -1;
754                         dont_allow_symbol_name = 1;
755                 } else
756                         continue;
757
758                 if (line_number == -1)
759                         fprintf(outfile, "%s: ", get_file_name(entry));
760                 else
761                         fprintf(outfile, "%s:%d: ", file_name, line_number);
762
763                 if (dont_allow_symbol_name)
764                         fprintf(outfile, "%s", errfmt);
765                 else
766                         fprintf(outfile, errfmt, demangle(g->name));
767
768                 fputc('\n', outfile);
769         }
770         free(text_scan);
771         free(data_scan);
772         entry->strings = 0;     /* Since it will disappear anyway. */
773 }
774
775 int
776 do_warnings(outfile)
777         FILE    *outfile;
778 {
779
780         list_unresolved_refs = !relocatable_output &&
781                 ( (undefined_global_sym_count - undefined_weak_sym_count) > 0
782                    || undefined_shobj_sym_count
783                 );
784         list_multiple_defs = multiple_def_count != 0;
785
786         if (!(list_unresolved_refs ||
787               list_warning_symbols ||
788               list_multiple_defs))
789                 /* No need to run this routine */
790                 return 1;
791
792         if (entry_symbol && !entry_symbol->defined)
793                 fprintf(outfile, "Undefined entry symbol `%s'\n",
794                         demangle(entry_symbol->name));
795
796         each_file(do_file_warnings, (void *)outfile);
797
798         if (list_unresolved_refs &&
799             reported_undefineds !=
800             (undefined_global_sym_count - undefined_weak_sym_count))
801                 warnx("Spurious undefined symbols: "
802                       "# undefined symbols %d, reported %d",
803                       (undefined_global_sym_count - undefined_weak_sym_count),
804                       reported_undefineds);
805
806         if (list_unresolved_refs || list_multiple_defs)
807                 return 0;
808
809         return 1;
810 }