add -warn-common option
[external/binutils.git] / ld / ldmisc.c
1 /* ldmisc.c
2    Copyright (C) 1991 Free Software Foundation, Inc.
3
4    Written by Steve Chamberlain of Cygnus Support.
5
6 This file is part of GLD, the Gnu Linker.
7
8 GLD is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 GLD is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GLD; see the file COPYING.  If not, write to
20 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
21
22 #include "bfd.h"
23 #include "sysdep.h"
24 #include <varargs.h>
25 #include <demangle.h>
26
27 #include "ld.h"
28 #include "ldmisc.h"
29 #include "ldlang.h"
30 #include "ldlex.h"
31 /* IMPORTS */
32
33 extern char *program_name;
34
35 extern FILE *ldlex_input_stack;
36 extern char *ldfile_input_filename;
37 extern ld_config_type config;
38
39
40 extern int errno;
41 extern   int  sys_nerr;
42 extern char *sys_errlist[];
43
44 /* VARARGS*/
45 static void finfo ();
46
47 /*
48  %F error is fatal
49  %P print progam name
50  %S print script file and linenumber
51  %E current bfd error or errno
52  %I filename from a lang_input_statement_type
53  %B filename from a bfd
54  %T symbol table entry
55  %X no object output, fail return
56  %V hex bfd_vma
57  %v hex bfd_vma, no leading zeros
58  %C Clever filename:linenumber 
59  %R info about a relent
60  %
61 */
62 extern bfd *output_bfd;
63
64 static char *
65 demangle(string, remove_underscore)
66 char *string;
67 int remove_underscore;
68 {
69   char *res;
70   if (remove_underscore && output_bfd) 
71   {
72     if (bfd_get_symbol_leading_char(output_bfd) == string[0])
73      string++;
74   }
75   /* Note that there's a memory leak here, we keep buying memory
76      for demangled names, and never free.  But if you have so many
77      errors that you run out of VM with the error messages, then
78      there's something up */
79   res = cplus_demangle(string, DMGL_ANSI|DMGL_PARAMS);
80   return res ? res : string;
81 }
82
83 static void
84 vfinfo(fp, fmt, arg)
85      FILE *fp;
86      char *fmt;
87      va_list arg;
88 {
89   boolean fatal = false;
90
91   while (*fmt) 
92   {
93     while (*fmt != '%' && *fmt != '\0') 
94     {
95       putc(*fmt, fp);
96       fmt++;
97     }
98
99     if (*fmt == '%') 
100     {
101       fmt ++;
102       switch (*fmt++) 
103       {
104        case 'X':
105         config.make_executable = false;
106         break;
107
108        case 'V':
109         {
110           bfd_vma value = va_arg(arg, bfd_vma);
111           fprintf_vma(fp, value);
112         }
113         break;
114
115       case 'v':
116         {
117           char buf[100];
118           char *p = buf;
119           bfd_vma value = va_arg (arg, bfd_vma);
120           sprintf_vma (p, value);
121           while (*p == '0')
122             p++;
123           if (!*p)
124             p--;
125           fputs (p, fp);
126         }
127         break;
128
129        case 'T':
130        {
131          asymbol *symbol = va_arg(arg, asymbol *);
132          if (symbol) 
133          {
134            asection *section = symbol->section;
135            char *cplusname =   demangle(symbol->name, 1);
136            CONST char *section_name =  section->name;
137            if (section != &bfd_und_section) 
138            {
139              fprintf(fp,"%s (%s)", cplusname, section_name);
140            }
141            else 
142            {
143              fprintf(fp,"%s", cplusname);
144            }
145          }
146          else 
147          {
148            fprintf(fp,"no symbol");
149          }
150        }
151         break;
152
153        case 'B':
154        { 
155          bfd *abfd = va_arg(arg, bfd *);
156          if (abfd->my_archive) {
157            fprintf(fp,"%s(%s)", abfd->my_archive->filename,
158                    abfd->filename);
159          }
160          else {
161            fprintf(fp,"%s", abfd->filename);
162          }
163        }
164         break;
165
166        case 'F':
167         fatal = true;
168         break;
169
170        case 'P':
171         fprintf(fp,"%s", program_name);
172         break;
173
174        case 'E':
175         /* Replace with the most recent errno explanation */
176         fprintf(fp, bfd_errmsg(bfd_error));
177         break;
178
179        case 'I':
180        {
181          lang_input_statement_type *i =
182           va_arg(arg,lang_input_statement_type *);
183         
184          fprintf(fp,"%s", i->local_sym_name);
185        }
186         break;
187
188        case 'S':
189         /* Print source script file and line number */
190        {
191          extern unsigned int lineno;
192          if (ldfile_input_filename == (char *)NULL) {
193            fprintf(fp,"command line");
194          }
195          else {
196            fprintf(fp,"%s:%u", ldfile_input_filename, lineno );
197          }
198        }
199         break;
200
201        case 'R':
202         /* Print all that's interesting about a relent */
203        {
204          arelent *relent = va_arg(arg, arelent *);
205         
206          finfo (fp, "%s+0x%v (type %s)",
207                 (*(relent->sym_ptr_ptr))->name,
208                 relent->addend,
209                 relent->howto->name);
210        }
211         break;
212         
213        case 'C':
214        {
215          CONST char *filename;
216          CONST char *functionname;
217          char *cplus_name;
218          
219          unsigned int linenumber;
220          bfd *abfd = va_arg(arg, bfd *);
221          asection *section = va_arg(arg, asection *);
222          asymbol **symbols = va_arg(arg, asymbol **);
223          bfd_vma offset = va_arg(arg, bfd_vma);
224          
225          if (bfd_find_nearest_line(abfd,
226                                    section,
227                                    symbols,
228                                    offset,
229                                    &filename,
230                                    &functionname,
231                                    &linenumber))
232          {
233            if (filename == (char *)NULL)        
234             filename = abfd->filename;
235            if (functionname != (char *)NULL) 
236            {
237              cplus_name = demangle(functionname, 1);
238              fprintf(fp,"%s:%u: (%s)", filename, linenumber, cplus_name);
239            }
240                 
241            else if (linenumber != 0) 
242             fprintf(fp,"%s:%u", filename, linenumber);
243            else
244              finfo (fp, "%s(%s+0x%v)", filename, section->name, offset);
245
246          }
247          else
248            finfo (fp, "%s(%s+0x%v)", abfd->filename, section->name, offset);
249        }
250         break;
251                 
252        case 's':
253         fprintf(fp,"%s", va_arg(arg, char *));
254         break;
255
256        case 'd':
257         fprintf(fp,"%d", va_arg(arg, int));
258         break;
259
260        default:
261         fprintf(fp,"%s", va_arg(arg, char *));
262         break;
263       }
264     }
265   }
266
267   if (fatal == true) 
268   {
269     extern char *output_filename;
270     if (output_filename) 
271     {
272       char *new = malloc(strlen(output_filename)+2);
273       extern bfd *output_bfd;
274       
275       strcpy(new, output_filename);
276       if (output_bfd && output_bfd->iostream)
277        fclose((FILE *)(output_bfd->iostream));
278       unlink(new);
279     }
280     exit(1);
281   }
282 }
283
284 /* Format info message and print on stdout. */
285
286 void info(va_alist)
287 va_dcl
288 {
289   char *fmt;
290   va_list arg;
291   va_start(arg);
292   fmt = va_arg(arg, char *);
293   vfinfo(stdout, fmt, arg);
294   va_end(arg);
295 }
296
297 /* ('e' for error.) Format info message and print on stderr. */
298
299 void einfo(va_alist)
300 va_dcl
301 {
302   char *fmt;
303   va_list arg;
304   va_start(arg);
305   fmt = va_arg(arg, char *);
306   vfinfo(stderr, fmt, arg);
307   va_end(arg);
308 }
309
310 /* Warn about a symbol NEWSYM being multiply defined with another symbol OLDSYM.
311    MESSAGE1 and MESSAGE2 should look something like:
312    "%C: warning: multiple commons of `%s'\n"
313    "%C: warning: previous common here\n"  */
314
315 void
316 multiple_warn (message1, newsym, message2, oldsym)
317      char *message1;
318      asymbol *newsym;
319      char *message2;
320      asymbol *oldsym;
321 {
322   lang_input_statement_type *stat;
323   asymbol **stat_symbols;
324
325   stat = (lang_input_statement_type *) bfd_asymbol_bfd (newsym)->usrdata;
326   stat_symbols = stat ? stat->asymbols : 0;
327
328   einfo (message1,
329          bfd_asymbol_bfd (newsym), newsym->section, stat_symbols, newsym->value,
330          demangle (newsym->name, 1));
331
332   stat = (lang_input_statement_type *) bfd_asymbol_bfd (oldsym)->usrdata;
333   stat_symbols = stat ? stat->asymbols : 0;
334
335   einfo (message2,
336          bfd_asymbol_bfd (oldsym), oldsym->section, stat_symbols, oldsym->value);
337 }
338
339 void 
340 info_assert(file, line)
341      char *file;
342      unsigned int line;
343 {
344   einfo("%F%P internal error %s %d\n", file,line);
345 }
346
347 /* Return a newly-allocated string
348    whose contents concatenate those of S1, S2, S3.  */
349
350 char *
351 concat (s1, s2, s3)
352      CONST char *s1;
353      CONST char *s2;
354      CONST char *s3;
355 {
356   size_t len1 = strlen (s1);
357   size_t len2 = strlen (s2);
358   size_t len3 = strlen (s3);
359   char *result = ldmalloc (len1 + len2 + len3 + 1);
360
361   if (len1 != 0)
362     memcpy(result, s1, len1);
363   if (len2 != 0)
364     memcpy(result+len1, s2, len2);
365   if (len3 != 0)
366     memcpy(result+len1+len2, s2, len3);
367   *(result + len1 + len2 + len3) = 0;
368
369   return result;
370 }
371
372
373 PTR
374 ldmalloc (size)
375      size_t size;
376 {
377   PTR result =  malloc ((int)size);
378
379   if (result == (char *)NULL && size != 0)
380     einfo("%F%P virtual memory exhausted\n");
381
382   return result;
383
384
385 PTR
386 xmalloc (size)
387      int size;
388 {
389 return ldmalloc(size);
390 }
391
392
393 PTR
394 ldrealloc (ptr, size)
395      PTR ptr;
396      size_t size;
397 {
398   PTR result =  realloc (ptr, (int)size);
399
400   if (result == (char *)NULL && size != 0)
401     einfo("%F%P virtual memory exhausted\n");
402
403   return result;
404
405
406 PTR
407 xrealloc (ptr, size)
408      PTR ptr;
409      size_t size;
410 {
411 return ldrealloc(ptr, size);
412 }
413
414
415 char *
416 buystring (x)
417      CONST char *CONST x;
418 {
419   size_t l = strlen(x)+1;
420   char *r = ldmalloc(l);
421   memcpy(r, x,l);
422   return r;
423 }
424
425
426 /* ('m' for map) Format info message and print on map. */
427
428 void minfo(va_alist)
429 va_dcl
430 {
431   char *fmt;
432   va_list arg;
433   va_start(arg);
434   fmt = va_arg(arg, char *);
435   vfinfo(config.map_file, fmt, arg);
436   va_end(arg);
437 }
438
439
440 static void
441 finfo (va_alist)
442      va_dcl
443 {
444   char *fmt;
445   FILE *file;
446   va_list arg;
447   va_start (arg);
448   file = va_arg (arg, FILE *);
449   fmt = va_arg (arg, char *);
450   vfinfo (file, fmt, arg);
451   va_end (arg);
452 }
453
454
455
456 /*----------------------------------------------------------------------
457   Functions to print the link map 
458  */
459
460 void 
461 print_space ()
462 {
463   fprintf(config.map_file, " ");
464 }
465 void 
466 print_nl ()
467 {
468   fprintf(config.map_file, "\n");
469 }
470 void 
471 print_address (value)
472      bfd_vma value;
473 {
474   fprintf_vma(config.map_file, value);
475 }