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