* ldmisc.c: Include <stdarg.h> rather than <varargs.h> if
[platform/upstream/binutils.git] / ld / ldmisc.c
1 /* ldmisc.c
2    Copyright (C) 1991, 92, 93, 94 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
21
22 #include "bfd.h"
23 #include "sysdep.h"
24 #include <demangle.h>
25
26 #ifdef ANSI_PROTOTYPES
27 #include <stdarg.h>
28 #define USE_STDARG 1
29 #else
30 #include <varargs.h>
31 #define USE_STDARG 0
32 #endif
33
34 #include "ld.h"
35 #include "ldmisc.h"
36 #include "ldexp.h"
37 #include "ldlang.h"
38 #include "ldgram.h"
39 #include "ldlex.h"
40 #include "ldmain.h"
41 #include "ldfile.h"
42
43
44 #if USE_STDARG
45 static void finfo PARAMS ((FILE *, const char *, ...));
46 #else
47 /* VARARGS*/
48 static void finfo ();
49 #endif
50 static const char *demangle PARAMS ((const char *string,
51                                      int remove_underscore));
52
53 /*
54  %% literal %
55  %F error is fatal
56  %P print program name
57  %S print script file and linenumber
58  %E current bfd error or errno
59  %I filename from a lang_input_statement_type
60  %B filename from a bfd
61  %T symbol name
62  %X no object output, fail return
63  %V hex bfd_vma
64  %v hex bfd_vma, no leading zeros
65  %C clever filename:linenumber with function
66  %D like %C, but no function name
67  %R info about a relent
68  %s arbitrary string, like printf
69  %d integer, like printf
70  %u integer, like printf
71 */
72
73 static const char *
74 demangle (string, remove_underscore)
75      const char *string;
76      int remove_underscore;
77 {
78   const char *res;
79
80   if (remove_underscore
81       && output_bfd != NULL
82       && bfd_get_symbol_leading_char (output_bfd) == string[0])
83     ++string;
84
85   /* This is a hack for better error reporting on XCOFF.  */
86   if (remove_underscore && string[0] == '.')
87     ++string;
88
89   /* Note that there's a memory leak here, we keep buying memory for
90      demangled names, and never free.  But if you have so many errors
91      that you run out of VM with the error messages, then there's
92      something up.  */
93   res = cplus_demangle (string, DMGL_ANSI | DMGL_PARAMS);
94   return res ? res : string;
95 }
96
97 static void
98 vfinfo (fp, fmt, arg)
99      FILE *fp;
100      const char *fmt;
101      va_list arg;
102 {
103   boolean fatal = false;
104
105   while (*fmt) 
106   {
107     while (*fmt != '%' && *fmt != '\0') 
108     {
109       putc(*fmt, fp);
110       fmt++;
111     }
112
113     if (*fmt == '%') 
114     {
115       fmt ++;
116       switch (*fmt++) 
117       {
118       default:
119         fprintf(fp,"%%%c", fmt[-1]);
120         break;
121
122       case '%':
123         /* literal % */
124         putc('%', fp);
125         break;
126
127        case 'X':
128         /* no object output, fail return */
129         config.make_executable = false;
130         break;
131
132        case 'V':
133         /* hex bfd_vma */
134         {
135           bfd_vma value = va_arg(arg, bfd_vma);
136           fprintf_vma(fp, value);
137         }
138         break;
139
140       case 'v':
141         /* hex bfd_vma, no leading zeros */
142         {
143           char buf[100];
144           char *p = buf;
145           bfd_vma value = va_arg (arg, bfd_vma);
146           sprintf_vma (p, value);
147           while (*p == '0')
148             p++;
149           if (!*p)
150             p--;
151           fputs (p, fp);
152         }
153         break;
154
155        case 'T':
156         /* Symbol name.  */
157         {
158           const char *name = va_arg (arg, const char *);
159
160           if (name != (const char *) NULL)
161             fprintf (fp, "%s", demangle (name, 1));
162           else
163             fprintf (fp, "no symbol");
164         }
165         break;
166
167        case 'B':
168         /* filename from a bfd */
169        { 
170          bfd *abfd = va_arg(arg, bfd *);
171          if (abfd->my_archive) {
172            fprintf(fp,"%s(%s)", abfd->my_archive->filename,
173                    abfd->filename);
174          }
175          else {
176            fprintf(fp,"%s", abfd->filename);
177          }
178        }
179         break;
180
181        case 'F':
182         /* error is fatal */
183         fatal = true;
184         break;
185
186        case 'P':
187         /* print program name */
188         fprintf(fp,"%s", program_name);
189         break;
190
191        case 'E':
192         /* current bfd error or errno */
193         fprintf(fp, bfd_errmsg(bfd_get_error ()));
194         break;
195
196        case 'I':
197         /* filename from a lang_input_statement_type */
198        {
199          lang_input_statement_type *i =
200           va_arg(arg,lang_input_statement_type *);
201
202          if (i->the_bfd->my_archive)
203            fprintf(fp, "(%s)", i->the_bfd->my_archive->filename);
204          fprintf(fp,"%s", i->local_sym_name);
205        }
206         break;
207
208        case 'S':
209         /* print script file and linenumber */
210         if (parsing_defsym)
211           fprintf (fp, "--defsym %s", lex_string);
212         else if (ldfile_input_filename != NULL)
213           fprintf (fp, "%s:%u", ldfile_input_filename, lineno);
214         else
215           fprintf (fp, "built in linker script:%u", lineno);
216         break;
217
218        case 'R':
219         /* Print all that's interesting about a relent */
220        {
221          arelent *relent = va_arg(arg, arelent *);
222         
223          finfo (fp, "%s+0x%v (type %s)",
224                 (*(relent->sym_ptr_ptr))->name,
225                 relent->addend,
226                 relent->howto->name);
227        }
228         break;
229         
230        case 'C':
231        case 'D':
232         /* Clever filename:linenumber with function name if possible,
233            or section name as a last resort.  The arguments are a BFD,
234            a section, and an offset.  */
235         {
236           static bfd *last_bfd;
237           static char *last_file = NULL;
238           static char *last_function = NULL;
239           bfd *abfd;
240           asection *section;
241           bfd_vma offset;
242           lang_input_statement_type *entry;
243           asymbol **asymbols;
244           const char *filename;
245           const char *functionname;
246           unsigned int linenumber;
247           boolean discard_last;
248
249           abfd = va_arg (arg, bfd *);
250           section = va_arg (arg, asection *);
251           offset = va_arg (arg, bfd_vma);
252
253           entry = (lang_input_statement_type *) abfd->usrdata;
254           if (entry != (lang_input_statement_type *) NULL
255               && entry->asymbols != (asymbol **) NULL)
256             asymbols = entry->asymbols;
257           else
258             {
259               long symsize;
260               long symbol_count;
261
262               symsize = bfd_get_symtab_upper_bound (abfd);
263               if (symsize < 0)
264                 einfo ("%B%F: could not read symbols\n", abfd);
265               asymbols = (asymbol **) xmalloc (symsize);
266               symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
267               if (symbol_count < 0)
268                 einfo ("%B%F: could not read symbols\n", abfd);
269               if (entry != (lang_input_statement_type *) NULL)
270                 {
271                   entry->asymbols = asymbols;
272                   entry->symbol_count = symbol_count;
273                 }
274             }
275
276           discard_last = true;
277           if (bfd_find_nearest_line (abfd, section, asymbols, offset,
278                                      &filename, &functionname, &linenumber))
279             {
280               if (functionname != NULL && fmt[-1] == 'C')
281                 {
282                   if (filename == (char *) NULL)
283                     filename = abfd->filename;
284
285                   if (last_bfd == NULL
286                       || last_file == NULL
287                       || last_function == NULL
288                       || last_bfd != abfd
289                       || strcmp (last_file, filename) != 0
290                       || strcmp (last_function, functionname) != 0)
291                     {
292                       /* We use abfd->filename in this initial line,
293                          in case filename is a .h file or something
294                          similarly unhelpful.  */
295                       finfo (fp, "%B: In function `%s':\n",
296                              abfd, demangle (functionname, 1));
297
298                       last_bfd = abfd;
299                       if (last_file != NULL)
300                         free (last_file);
301                       last_file = buystring (filename);
302                       if (last_function != NULL)
303                         free (last_function);
304                       last_function = buystring (functionname);
305                     }
306                   discard_last = false;
307                   if (linenumber != 0)
308                     fprintf (fp, "%s:%u", filename, linenumber);
309                   else
310                     finfo (fp, "%s(%s+0x%v)", filename, section->name, offset);
311                 }
312               else if (filename == NULL
313                        || strcmp (filename, abfd->filename) == 0)
314                 {
315                   finfo (fp, "%B(%s+0x%v)", abfd, section->name, offset);
316                   if (linenumber != 0)
317                     finfo (fp, "%u", linenumber);
318                 }
319               else if (linenumber != 0) 
320                 finfo (fp, "%B:%s:%u", abfd, filename, linenumber);
321               else
322                 finfo (fp, "%B(%s+0x%v):%s", abfd, section->name, offset,
323                        filename);
324             }
325           else
326             finfo (fp, "%B(%s+0x%v)", abfd, section->name, offset);
327
328           if (discard_last)
329             {
330               last_bfd = NULL;
331               if (last_file != NULL)
332                 {
333                   free (last_file);
334                   last_file = NULL;
335                 }
336               if (last_function != NULL)
337                 {
338                   free (last_function);
339                   last_function = NULL;
340                 }
341             }
342         }
343         break;
344                 
345        case 's':
346         /* arbitrary string, like printf */
347         fprintf(fp,"%s", va_arg(arg, char *));
348         break;
349
350        case 'd':
351         /* integer, like printf */
352         fprintf(fp,"%d", va_arg(arg, int));
353         break;
354
355        case 'u':
356         /* unsigned integer, like printf */
357         fprintf(fp,"%u", va_arg(arg, unsigned int));
358         break;
359       }
360     }
361   }
362
363   if (fatal == true) 
364     xexit(1);
365 }
366
367 /* Format info message and print on stdout. */
368
369 /* (You would think this should be called just "info", but then you
370    would hosed by LynxOS, which defines that name in its libc.)  */
371
372 void
373 #if USE_STDARG
374 info_msg (const char *fmt, ...)
375 #else
376 info_msg (va_alist)
377      va_dcl
378 #endif
379 {
380   va_list arg;
381
382 #if ! USE_STDARG
383   const char *fmt;
384
385   va_start (arg);
386   fmt = va_arg (arg, const char *);
387 #else
388   va_start (arg, fmt);
389 #endif
390
391   vfinfo (stdout, fmt, arg);
392   va_end (arg);
393 }
394
395 /* ('e' for error.) Format info message and print on stderr. */
396
397 void
398 #if USE_STDARG
399 einfo (const char *fmt, ...)
400 #else
401 einfo (va_alist)
402      va_dcl
403 #endif
404 {
405   va_list arg;
406
407 #if ! USE_STDARG
408   const char *fmt;
409
410   va_start (arg);
411   fmt = va_arg (arg, const char *);
412 #else
413   va_start (arg, fmt);
414 #endif
415
416   vfinfo (stderr, fmt, arg);
417   va_end (arg);
418 }
419
420 void 
421 info_assert (file, line)
422      const char *file;
423      unsigned int line;
424 {
425   einfo ("%F%P: internal error %s %d\n", file, line);
426 }
427
428 char *
429 buystring (x)
430      CONST char *CONST x;
431 {
432   size_t l = strlen(x)+1;
433   char *r = xmalloc(l);
434   memcpy(r, x,l);
435   return r;
436 }
437
438 /* ('m' for map) Format info message and print on map. */
439
440 void
441 #if USE_STDARG
442 minfo (const char *fmt, ...)
443 #else
444 minfo (va_alist)
445      va_dcl
446 #endif
447 {
448   va_list arg;
449
450 #if ! USE_STDARG
451   const char *fmt;
452   va_start (arg);
453   fmt = va_arg (arg, const char *);
454 #else
455   va_start (arg, fmt);
456 #endif
457
458   vfinfo (config.map_file, fmt, arg);
459   va_end (arg);
460 }
461
462 static void
463 #if USE_STDARG
464 finfo (FILE *file, const char *fmt, ...)
465 #else
466 finfo (va_alist)
467      va_dcl
468 #endif
469 {
470   va_list arg;
471
472 #if ! USE_STDARG
473   FILE *file;
474   const char *fmt;
475
476   va_start (arg);
477   file = va_arg (arg, FILE *);
478   fmt = va_arg (arg, const char *);
479 #else
480   va_start (arg, fmt);
481 #endif
482
483   vfinfo (file, fmt, arg);
484   va_end (arg);
485 }
486 \f
487 /* Functions to print the link map.  */
488
489 void 
490 print_space ()
491 {
492   fprintf (config.map_file, " ");
493 }
494
495 void 
496 print_nl ()
497 {
498   fprintf (config.map_file, "\n");
499 }
500
501 void 
502 print_address (value)
503      bfd_vma value;
504 {
505   fprintf_vma (config.map_file, value);
506 }