Fri Jan 7 14:34:31 1994 Stan Shebs (shebs@andros.cygnus.com)
[binutils-gdb.git] / ld / ldmisc.c
1 /* ldmisc.c
2 Copyright (C) 1991 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 "ldlex.h"
32 #include "ldsym.h"
33 #include "ldmain.h"
34 #include "ldfile.h"
35
36 /* VARARGS*/
37 static void finfo ();
38
39 /*
40 %% literal %
41 %F error is fatal
42 %P print program name
43 %S print script file and linenumber
44 %E current bfd error or errno
45 %I filename from a lang_input_statement_type
46 %B filename from a bfd
47 %T symbol table entry
48 %X no object output, fail return
49 %V hex bfd_vma
50 %v hex bfd_vma, no leading zeros
51 %C Clever filename:linenumber
52 %R info about a relent
53 %s arbitrary string, like printf
54 %d integer, like printf
55 */
56
57 static char *
58 demangle(string, remove_underscore)
59 char *string;
60 int remove_underscore;
61 {
62 char *res;
63 if (remove_underscore && output_bfd)
64 {
65 if (bfd_get_symbol_leading_char(output_bfd) == string[0])
66 string++;
67 }
68 /* Note that there's a memory leak here, we keep buying memory
69 for demangled names, and never free. But if you have so many
70 errors that you run out of VM with the error messages, then
71 there's something up */
72 res = cplus_demangle(string, DMGL_ANSI|DMGL_PARAMS);
73 return res ? res : string;
74 }
75
76 static void
77 vfinfo(fp, fmt, arg)
78 FILE *fp;
79 char *fmt;
80 va_list arg;
81 {
82 boolean fatal = false;
83
84 while (*fmt)
85 {
86 while (*fmt != '%' && *fmt != '\0')
87 {
88 putc(*fmt, fp);
89 fmt++;
90 }
91
92 if (*fmt == '%')
93 {
94 fmt ++;
95 switch (*fmt++)
96 {
97 default:
98 fprintf(fp,"%%%c", fmt[-1]);
99 break;
100
101 case '%':
102 /* literal % */
103 putc('%', fp);
104 break;
105
106 case 'X':
107 /* no object output, fail return */
108 config.make_executable = false;
109 break;
110
111 case 'V':
112 /* hex bfd_vma */
113 {
114 bfd_vma value = va_arg(arg, bfd_vma);
115 fprintf_vma(fp, value);
116 }
117 break;
118
119 case 'v':
120 /* hex bfd_vma, no leading zeros */
121 {
122 char buf[100];
123 char *p = buf;
124 bfd_vma value = va_arg (arg, bfd_vma);
125 sprintf_vma (p, value);
126 while (*p == '0')
127 p++;
128 if (!*p)
129 p--;
130 fputs (p, fp);
131 }
132 break;
133
134 case 'T':
135 /* symbol table entry */
136 {
137 asymbol *symbol = va_arg(arg, asymbol *);
138 if (symbol)
139 {
140 asection *section = symbol->section;
141 char *cplusname = demangle(symbol->name, 1);
142 CONST char *section_name = section->name;
143 if (section != &bfd_und_section)
144 {
145 fprintf(fp,"%s (%s)", cplusname, section_name);
146 }
147 else
148 {
149 fprintf(fp,"%s", cplusname);
150 }
151 }
152 else
153 {
154 fprintf(fp,"no symbol");
155 }
156 }
157 break;
158
159 case 'B':
160 /* filename from a bfd */
161 {
162 bfd *abfd = va_arg(arg, bfd *);
163 if (abfd->my_archive) {
164 fprintf(fp,"%s(%s)", abfd->my_archive->filename,
165 abfd->filename);
166 }
167 else {
168 fprintf(fp,"%s", abfd->filename);
169 }
170 }
171 break;
172
173 case 'F':
174 /* error is fatal */
175 fatal = true;
176 break;
177
178 case 'P':
179 /* print program name */
180 fprintf(fp,"%s", program_name);
181 break;
182
183 case 'E':
184 /* current bfd error or errno */
185 fprintf(fp, bfd_errmsg(bfd_error));
186 break;
187
188 case 'I':
189 /* filename from a lang_input_statement_type */
190 {
191 lang_input_statement_type *i =
192 va_arg(arg,lang_input_statement_type *);
193
194 fprintf(fp,"%s", i->local_sym_name);
195 }
196 break;
197
198 case 'S':
199 /* print script file and linenumber */
200 {
201 if (ldfile_input_filename == (char *)NULL) {
202 fprintf(fp,"command line");
203 }
204 else {
205 fprintf(fp,"%s:%u", ldfile_input_filename, lineno );
206 }
207 }
208 break;
209
210 case 'R':
211 /* Print all that's interesting about a relent */
212 {
213 arelent *relent = va_arg(arg, arelent *);
214
215 finfo (fp, "%s+0x%v (type %s)",
216 (*(relent->sym_ptr_ptr))->name,
217 relent->addend,
218 relent->howto->name);
219 }
220 break;
221
222 case 'C':
223 /* Clever filename:linenumber with function name if possible,
224 or section name as a last resort */
225 {
226 CONST char *filename;
227 CONST char *functionname;
228 char *cplus_name;
229
230 unsigned int linenumber;
231 bfd *abfd = va_arg(arg, bfd *);
232 asection *section = va_arg(arg, asection *);
233 asymbol **symbols = va_arg(arg, asymbol **);
234 bfd_vma offset = va_arg(arg, bfd_vma);
235
236 if (bfd_find_nearest_line(abfd,
237 section,
238 symbols,
239 offset,
240 &filename,
241 &functionname,
242 &linenumber))
243 {
244 if (filename == (char *)NULL)
245 filename = abfd->filename;
246 if (functionname != (char *)NULL)
247 {
248 cplus_name = demangle(functionname, 1);
249 fprintf(fp,"%s:%u: %s", filename, linenumber, cplus_name);
250 }
251
252 else if (linenumber != 0)
253 fprintf(fp,"%s:%u", filename, linenumber);
254 else
255 finfo (fp, "%s(%s+0x%v)", filename, section->name, offset);
256
257 }
258 else
259 finfo (fp, "%s(%s+0x%v)", abfd->filename, section->name, offset);
260 }
261 break;
262
263 case 's':
264 /* arbitrary string, like printf */
265 fprintf(fp,"%s", va_arg(arg, char *));
266 break;
267
268 case 'd':
269 /* integer, like printf */
270 fprintf(fp,"%d", va_arg(arg, int));
271 break;
272 }
273 }
274 }
275
276 if (fatal == true)
277 {
278 if (output_filename)
279 {
280 if (output_bfd && output_bfd->iostream)
281 fclose((FILE *)(output_bfd->iostream));
282 if (delete_output_file_on_failure)
283 unlink (output_filename);
284 }
285 exit(1);
286 }
287 }
288
289 /* Format info message and print on stdout. */
290
291 /* (You would think this should be called just "info", but then you would
292 hosed by LynxOS, which defines that name in its libc.) */
293
294 void info_msg(va_alist)
295 va_dcl
296 {
297 char *fmt;
298 va_list arg;
299 va_start(arg);
300 fmt = va_arg(arg, char *);
301 vfinfo(stdout, fmt, arg);
302 va_end(arg);
303 }
304
305 /* ('e' for error.) Format info message and print on stderr. */
306
307 void einfo(va_alist)
308 va_dcl
309 {
310 char *fmt;
311 va_list arg;
312 va_start(arg);
313 fmt = va_arg(arg, char *);
314 vfinfo(stderr, fmt, arg);
315 va_end(arg);
316 }
317
318 /* Warn about a symbol NEWSYM being multiply defined with another symbol OLDSYM.
319 MESSAGE1 and MESSAGE2 should look something like:
320 "%C: warning: multiple commons of `%s'\n"
321 "%C: warning: previous common here\n" */
322
323 void
324 multiple_warn (message1, newsym, message2, oldsym)
325 char *message1;
326 asymbol *newsym;
327 char *message2;
328 asymbol *oldsym;
329 {
330 lang_input_statement_type *stat;
331 asymbol **stat_symbols;
332
333 stat = (lang_input_statement_type *) bfd_asymbol_bfd (newsym)->usrdata;
334 stat_symbols = stat ? stat->asymbols : 0;
335
336 einfo (message1,
337 bfd_asymbol_bfd (newsym), newsym->section, stat_symbols, newsym->value,
338 demangle (newsym->name, 1));
339
340 stat = (lang_input_statement_type *) bfd_asymbol_bfd (oldsym)->usrdata;
341 stat_symbols = stat ? stat->asymbols : 0;
342
343 einfo (message2,
344 bfd_asymbol_bfd (oldsym), oldsym->section, stat_symbols, oldsym->value);
345 }
346
347 void
348 info_assert(file, line)
349 char *file;
350 unsigned int line;
351 {
352 einfo("%F%P: internal error %s %d\n", file,line);
353 }
354
355 /* Return a newly-allocated string
356 whose contents concatenate those of S1, S2, S3. */
357
358 char *
359 concat (s1, s2, s3)
360 CONST char *s1;
361 CONST char *s2;
362 CONST char *s3;
363 {
364 size_t len1 = strlen (s1);
365 size_t len2 = strlen (s2);
366 size_t len3 = strlen (s3);
367 char *result = ldmalloc (len1 + len2 + len3 + 1);
368
369 if (len1 != 0)
370 memcpy(result, s1, len1);
371 if (len2 != 0)
372 memcpy(result+len1, s2, len2);
373 if (len3 != 0)
374 memcpy(result+len1+len2, s2, len3);
375 *(result + len1 + len2 + len3) = 0;
376
377 return result;
378 }
379
380
381 PTR
382 ldmalloc (size)
383 size_t size;
384 {
385 PTR result = malloc ((int)size);
386
387 if (result == (char *)NULL && size != 0)
388 einfo("%F%P: virtual memory exhausted\n");
389
390 return result;
391 }
392
393 PTR
394 xmalloc (size)
395 int size;
396 {
397 return ldmalloc(size);
398 }
399
400
401 PTR
402 ldrealloc (ptr, size)
403 PTR ptr;
404 size_t size;
405 {
406 PTR result = realloc (ptr, (int)size);
407
408 if (result == (char *)NULL && size != 0)
409 einfo("%F%P: virtual memory exhausted\n");
410
411 return result;
412 }
413
414 PTR
415 xrealloc (ptr, size)
416 PTR ptr;
417 size_t size;
418 {
419 return ldrealloc(ptr, size);
420 }
421
422
423 char *
424 buystring (x)
425 CONST char *CONST x;
426 {
427 size_t l = strlen(x)+1;
428 char *r = ldmalloc(l);
429 memcpy(r, x,l);
430 return r;
431 }
432
433
434 /* ('m' for map) Format info message and print on map. */
435
436 void minfo(va_alist)
437 va_dcl
438 {
439 char *fmt;
440 va_list arg;
441 va_start(arg);
442 fmt = va_arg(arg, char *);
443 vfinfo(config.map_file, fmt, arg);
444 va_end(arg);
445 }
446
447
448 static void
449 finfo (va_alist)
450 va_dcl
451 {
452 char *fmt;
453 FILE *file;
454 va_list arg;
455 va_start (arg);
456 file = va_arg (arg, FILE *);
457 fmt = va_arg (arg, char *);
458 vfinfo (file, fmt, arg);
459 va_end (arg);
460 }
461
462
463
464 /*----------------------------------------------------------------------
465 Functions to print the link map
466 */
467
468 void
469 print_space ()
470 {
471 fprintf(config.map_file, " ");
472 }
473 void
474 print_nl ()
475 {
476 fprintf(config.map_file, "\n");
477 }
478 void
479 print_address (value)
480 bfd_vma value;
481 {
482 fprintf_vma(config.map_file, value);
483 }