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