Tweak the new handling of function names.
[binutils-gdb.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 }