Tue Jan 25 19:54:19 1994 Stan Shebs (shebs@andros.cygnus.com)
[deliverable/binutils-gdb.git] / ld / ldmisc.c
... / ...
CommitLineData
1/* ldmisc.c
2 Copyright (C) 1991 Free Software Foundation, Inc.
3
4 Written by Steve Chamberlain of Cygnus Support.
5
6This file is part of GLD, the Gnu Linker.
7
8GLD is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2, or (at your option)
11any later version.
12
13GLD is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with GLD; see the file COPYING. If not, write to
20the 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*/
37static 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
57static char *
58demangle(string, remove_underscore)
59char *string;
60int 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
76static void
77vfinfo(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
294void info_msg(va_alist)
295va_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
307void einfo(va_alist)
308va_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
323void
324multiple_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
347void
348info_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
358char *
359concat (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
381PTR
382ldmalloc (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
393PTR
394xmalloc (size)
395 int size;
396{
397return ldmalloc(size);
398}
399
400
401PTR
402ldrealloc (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
414PTR
415xrealloc (ptr, size)
416 PTR ptr;
417 size_t size;
418{
419return ldrealloc(ptr, size);
420}
421
422
423char *
424buystring (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
436void minfo(va_alist)
437va_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
448static void
449finfo (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
468void
469print_space ()
470{
471 fprintf(config.map_file, " ");
472}
473void
474print_nl ()
475{
476 fprintf(config.map_file, "\n");
477}
478void
479print_address (value)
480 bfd_vma value;
481{
482 fprintf_vma(config.map_file, value);
483}
This page took 0.023794 seconds and 4 git commands to generate.