* ldmisc.c (vfinfo): Handle %D as %C, but never print the function
[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 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 }