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