52dee619a3c4b4b598a6bb1db16c93d30c9b9561
[deliverable/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
54 %R info about a relent
55 %s arbitrary string, like printf
56 %d integer, like printf
57 */
58
59 static const char *
60 demangle (string, remove_underscore)
61 const char *string;
62 int remove_underscore;
63 {
64 const char *res;
65 if (remove_underscore && output_bfd)
66 {
67 if (bfd_get_symbol_leading_char (output_bfd) == string[0])
68 string++;
69 }
70 /* Note that there's a memory leak here, we keep buying memory
71 for demangled names, and never free. But if you have so many
72 errors that you run out of VM with the error messages, then
73 there's something up */
74 res = cplus_demangle (string, DMGL_ANSI|DMGL_PARAMS);
75 return res ? res : string;
76 }
77
78 static void
79 vfinfo(fp, fmt, arg)
80 FILE *fp;
81 char *fmt;
82 va_list arg;
83 {
84 boolean fatal = false;
85
86 while (*fmt)
87 {
88 while (*fmt != '%' && *fmt != '\0')
89 {
90 putc(*fmt, fp);
91 fmt++;
92 }
93
94 if (*fmt == '%')
95 {
96 fmt ++;
97 switch (*fmt++)
98 {
99 default:
100 fprintf(fp,"%%%c", fmt[-1]);
101 break;
102
103 case '%':
104 /* literal % */
105 putc('%', fp);
106 break;
107
108 case 'X':
109 /* no object output, fail return */
110 config.make_executable = false;
111 break;
112
113 case 'V':
114 /* hex bfd_vma */
115 {
116 bfd_vma value = va_arg(arg, bfd_vma);
117 fprintf_vma(fp, value);
118 }
119 break;
120
121 case 'v':
122 /* hex bfd_vma, no leading zeros */
123 {
124 char buf[100];
125 char *p = buf;
126 bfd_vma value = va_arg (arg, bfd_vma);
127 sprintf_vma (p, value);
128 while (*p == '0')
129 p++;
130 if (!*p)
131 p--;
132 fputs (p, fp);
133 }
134 break;
135
136 case 'T':
137 /* Symbol name. */
138 {
139 const char *name = va_arg (arg, const char *);
140
141 if (name != (const char *) NULL)
142 fprintf (fp, "%s", demangle (name, 1));
143 else
144 fprintf (fp, "no symbol");
145 }
146 break;
147
148 case 'B':
149 /* filename from a bfd */
150 {
151 bfd *abfd = va_arg(arg, bfd *);
152 if (abfd->my_archive) {
153 fprintf(fp,"%s(%s)", abfd->my_archive->filename,
154 abfd->filename);
155 }
156 else {
157 fprintf(fp,"%s", abfd->filename);
158 }
159 }
160 break;
161
162 case 'F':
163 /* error is fatal */
164 fatal = true;
165 break;
166
167 case 'P':
168 /* print program name */
169 fprintf(fp,"%s", program_name);
170 break;
171
172 case 'E':
173 /* current bfd error or errno */
174 fprintf(fp, bfd_errmsg(bfd_get_error ()));
175 break;
176
177 case 'I':
178 /* filename from a lang_input_statement_type */
179 {
180 lang_input_statement_type *i =
181 va_arg(arg,lang_input_statement_type *);
182
183 if (i->the_bfd->my_archive)
184 fprintf(fp, "(%s)", i->the_bfd->my_archive->filename);
185 fprintf(fp,"%s", i->local_sym_name);
186 }
187 break;
188
189 case 'S':
190 /* print script file and linenumber */
191 {
192 if (ldfile_input_filename) {
193 fprintf(fp,"%s:%u", ldfile_input_filename, lineno );
194 }
195 }
196 break;
197
198 case 'R':
199 /* Print all that's interesting about a relent */
200 {
201 arelent *relent = va_arg(arg, arelent *);
202
203 finfo (fp, "%s+0x%v (type %s)",
204 (*(relent->sym_ptr_ptr))->name,
205 relent->addend,
206 relent->howto->name);
207 }
208 break;
209
210 case 'C':
211 /* Clever filename:linenumber with function name if possible,
212 or section name as a last resort. The arguments are a BFD,
213 a section, and an offset. */
214 {
215 bfd *abfd;
216 asection *section;
217 bfd_vma offset;
218 lang_input_statement_type *entry;
219 asymbol **asymbols;
220 const char *filename;
221 const char *functionname;
222 unsigned int linenumber;
223
224 abfd = va_arg (arg, bfd *);
225 section = va_arg (arg, asection *);
226 offset = va_arg (arg, bfd_vma);
227
228 entry = (lang_input_statement_type *) abfd->usrdata;
229 if (entry != (lang_input_statement_type *) NULL
230 && entry->asymbols != (asymbol **) NULL)
231 asymbols = entry->asymbols;
232 else
233 {
234 long symsize;
235 long symbol_count;
236
237 symsize = bfd_get_symtab_upper_bound (abfd);
238 if (symsize < 0)
239 einfo ("%B%F: could not read symbols", abfd);
240 asymbols = (asymbol **) xmalloc (symsize);
241 symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
242 if (symbol_count < 0)
243 einfo ("%B%F: could not read symbols", abfd);
244 if (entry != (lang_input_statement_type *) NULL)
245 {
246 entry->asymbols = asymbols;
247 entry->symbol_count = symbol_count;
248 }
249 }
250
251 if (bfd_find_nearest_line (abfd, section, asymbols, offset,
252 &filename, &functionname, &linenumber))
253 {
254 if (filename == (char *) NULL)
255 filename = abfd->filename;
256
257 if (functionname != (char *)NULL)
258 fprintf (fp, "%s:%u: %s", filename, linenumber,
259 demangle (functionname, 1));
260 else if (linenumber != 0)
261 fprintf (fp, "%s:%u", filename, linenumber);
262 else
263 finfo (fp, "%s(%s+0x%v)", filename, section->name, offset);
264
265 }
266 else
267 finfo (fp, "%s(%s+0x%v)", abfd->filename, section->name, offset);
268 }
269 break;
270
271 case 's':
272 /* arbitrary string, like printf */
273 fprintf(fp,"%s", va_arg(arg, char *));
274 break;
275
276 case 'd':
277 /* integer, like printf */
278 fprintf(fp,"%d", va_arg(arg, int));
279 break;
280 }
281 }
282 }
283
284 if (fatal == true)
285 xexit(1);
286 }
287
288 /* Format info message and print on stdout. */
289
290 /* (You would think this should be called just "info", but then you would
291 hosed by LynxOS, which defines that name in its libc.) */
292
293 void info_msg(va_alist)
294 va_dcl
295 {
296 char *fmt;
297 va_list arg;
298 va_start(arg);
299 fmt = va_arg(arg, char *);
300 vfinfo(stdout, fmt, arg);
301 va_end(arg);
302 }
303
304 /* ('e' for error.) Format info message and print on stderr. */
305
306 void einfo(va_alist)
307 va_dcl
308 {
309 char *fmt;
310 va_list arg;
311 va_start(arg);
312 fmt = va_arg(arg, char *);
313 vfinfo(stderr, fmt, arg);
314 va_end(arg);
315 }
316
317 void
318 info_assert(file, line)
319 char *file;
320 unsigned int line;
321 {
322 einfo("%F%P: internal error %s %d\n", file,line);
323 }
324
325 char *
326 buystring (x)
327 CONST char *CONST x;
328 {
329 size_t l = strlen(x)+1;
330 char *r = xmalloc(l);
331 memcpy(r, x,l);
332 return r;
333 }
334
335
336 /* ('m' for map) Format info message and print on map. */
337
338 void minfo(va_alist)
339 va_dcl
340 {
341 char *fmt;
342 va_list arg;
343 va_start(arg);
344 fmt = va_arg(arg, char *);
345 vfinfo(config.map_file, fmt, arg);
346 va_end(arg);
347 }
348
349
350 static void
351 finfo (va_alist)
352 va_dcl
353 {
354 char *fmt;
355 FILE *file;
356 va_list arg;
357 va_start (arg);
358 file = va_arg (arg, FILE *);
359 fmt = va_arg (arg, char *);
360 vfinfo (file, fmt, arg);
361 va_end (arg);
362 }
363
364
365
366 /*----------------------------------------------------------------------
367 Functions to print the link map
368 */
369
370 void
371 print_space ()
372 {
373 fprintf(config.map_file, " ");
374 }
375 void
376 print_nl ()
377 {
378 fprintf(config.map_file, "\n");
379 }
380 void
381 print_address (value)
382 bfd_vma value;
383 {
384 fprintf_vma(config.map_file, value);
385 }
This page took 0.038512 seconds and 4 git commands to generate.