* ldmisc.c (vfinfo): Handle %D as %C, but never print the function
[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           bfd *abfd;
218           asection *section;
219           bfd_vma offset;
220           lang_input_statement_type *entry;
221           asymbol **asymbols;
222           const char *filename;
223           const char *functionname;
224           unsigned int linenumber;
225
226           abfd = va_arg (arg, bfd *);
227           section = va_arg (arg, asection *);
228           offset = va_arg (arg, bfd_vma);
229
230           entry = (lang_input_statement_type *) abfd->usrdata;
231           if (entry != (lang_input_statement_type *) NULL
232               && entry->asymbols != (asymbol **) NULL)
233             asymbols = entry->asymbols;
234           else
235             {
236               long symsize;
237               long symbol_count;
238
239               symsize = bfd_get_symtab_upper_bound (abfd);
240               if (symsize < 0)
241                 einfo ("%B%F: could not read symbols", abfd);
242               asymbols = (asymbol **) xmalloc (symsize);
243               symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
244               if (symbol_count < 0)
245                 einfo ("%B%F: could not read symbols", abfd);
246               if (entry != (lang_input_statement_type *) NULL)
247                 {
248                   entry->asymbols = asymbols;
249                   entry->symbol_count = symbol_count;
250                 }
251             }
252
253           if (bfd_find_nearest_line (abfd, section, asymbols, offset,
254                                      &filename, &functionname, &linenumber))
255             {
256               if (filename == (char *) NULL)
257                 filename = abfd->filename;
258
259               if (functionname != NULL && fmt[-1] == 'C')
260                 {
261                   fprintf (fp, "%s: In function `%s':\n", filename,
262                            demangle (functionname, 1));
263                   fprintf (fp, "%s:%u", filename, linenumber);
264                 }
265               else if (linenumber != 0) 
266                 fprintf (fp, "%s:%u", filename, linenumber);
267               else
268                 finfo (fp, "%s(%s+0x%v)", filename, section->name, offset);
269
270             }
271           else
272             finfo (fp, "%s(%s+0x%v)", abfd->filename, section->name, offset);
273         }
274         break;
275                 
276        case 's':
277         /* arbitrary string, like printf */
278         fprintf(fp,"%s", va_arg(arg, char *));
279         break;
280
281        case 'd':
282         /* integer, like printf */
283         fprintf(fp,"%d", va_arg(arg, int));
284         break;
285       }
286     }
287   }
288
289   if (fatal == true) 
290     xexit(1);
291 }
292
293 /* Format info message and print on stdout. */
294
295 /* (You would think this should be called just "info", but then you would
296    hosed by LynxOS, which defines that name in its libc.) */
297
298 void info_msg(va_alist)
299      va_dcl
300 {
301   char *fmt;
302   va_list arg;
303   va_start(arg);
304   fmt = va_arg(arg, char *);
305   vfinfo(stdout, fmt, arg);
306   va_end(arg);
307 }
308
309 /* ('e' for error.) Format info message and print on stderr. */
310
311 void einfo(va_alist)
312      va_dcl
313 {
314   char *fmt;
315   va_list arg;
316   va_start(arg);
317   fmt = va_arg(arg, char *);
318   vfinfo(stderr, fmt, arg);
319   va_end(arg);
320 }
321
322 void 
323 info_assert(file, line)
324      char *file;
325      unsigned int line;
326 {
327   einfo("%F%P: internal error %s %d\n", file,line);
328 }
329
330 char *
331 buystring (x)
332      CONST char *CONST x;
333 {
334   size_t l = strlen(x)+1;
335   char *r = xmalloc(l);
336   memcpy(r, x,l);
337   return r;
338 }
339
340
341 /* ('m' for map) Format info message and print on map. */
342
343 void minfo(va_alist)
344      va_dcl
345 {
346   char *fmt;
347   va_list arg;
348   va_start(arg);
349   fmt = va_arg(arg, char *);
350   vfinfo(config.map_file, fmt, arg);
351   va_end(arg);
352 }
353
354
355 static void
356 finfo (va_alist)
357      va_dcl
358 {
359   char *fmt;
360   FILE *file;
361   va_list arg;
362   va_start (arg);
363   file = va_arg (arg, FILE *);
364   fmt = va_arg (arg, char *);
365   vfinfo (file, fmt, arg);
366   va_end (arg);
367 }
368
369
370
371 /*----------------------------------------------------------------------
372   Functions to print the link map 
373  */
374
375 void 
376 print_space ()
377 {
378   fprintf(config.map_file, " ");
379 }
380 void 
381 print_nl ()
382 {
383   fprintf(config.map_file, "\n");
384 }
385 void 
386 print_address (value)
387      bfd_vma value;
388 {
389   fprintf_vma(config.map_file, value);
390 }