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