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