9a70af92e003eaacb818c333ba467e37c92fe20a
[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
26 #include "ld.h"
27 #include "ldmisc.h"
28 #include "ldlang.h"
29 #include "ldlex.h"
30 /* IMPORTS */
31
32 extern char *program_name;
33
34 extern FILE *ldlex_input_stack;
35 extern char *ldfile_input_filename;
36 extern ld_config_type config;
37
38
39 extern int errno;
40 extern int sys_nerr;
41 extern char *sys_errlist[];
42
43 /*
44 %F error is fatal
45 %P print progam name
46 %S print script file and linenumber
47 %E current bfd error or errno
48 %I filename from a lang_input_statement_type
49 %B filename from a bfd
50 %T symbol table entry
51 %X no object output, fail return
52 %V hex bfd_vma
53 %C Clever filename:linenumber
54 %R info about a relent
55 %
56 */
57 static void
58 vfinfo(fp, fmt, arg)
59 FILE *fp;
60 char *fmt;
61 va_list arg;
62 {
63 extern char *cplus_demangle();
64 boolean fatal = false;
65 while (*fmt)
66 {
67 while (*fmt != '%' && *fmt != '\0')
68 {
69 putc(*fmt, fp);
70 fmt++;
71 }
72 if (*fmt == '%')
73 {
74 fmt ++;
75 switch (*fmt++)
76 {
77 case 'X':
78 config.make_executable = false;
79 break;
80 case 'V':
81 {
82 bfd_vma value = va_arg(arg, bfd_vma);
83 fprintf_vma(fp, value);
84 }
85 break;
86 case 'T':
87 {
88 asymbol *symbol = va_arg(arg, asymbol *);
89 if (symbol)
90 {
91
92
93 asection *section = symbol->section;
94 char *cplusname = cplus_demangle(symbol->name, 1);
95 CONST char *section_name = section->name;
96 if (section != &bfd_und_section)
97 {
98 fprintf(fp,"%s (%s)", cplusname ? cplusname :
99 symbol->name, section_name);
100 }
101 else
102 {
103 fprintf(fp,"%s", cplusname ? cplusname : symbol->name);
104 }
105
106 if (cplusname)
107 {
108 free(cplusname);
109 }
110
111 }
112 else
113 {
114 fprintf(fp,"no symbol");
115 }
116 }
117 break;
118 case 'B':
119 {
120 bfd *abfd = va_arg(arg, bfd *);
121 if (abfd->my_archive) {
122 fprintf(fp,"%s(%s)", abfd->my_archive->filename,
123 abfd->filename);
124 }
125 else {
126 fprintf(fp,"%s", abfd->filename);
127
128 }
129 }
130 break;
131 case 'F':
132 fatal = true;
133 break;
134 case 'P':
135 fprintf(fp,"%s", program_name);
136 break;
137 case 'E':
138 /* Replace with the most recent errno explanation */
139
140
141 fprintf(fp, bfd_errmsg(bfd_error));
142
143
144 break;
145 case 'I':
146 {
147 lang_input_statement_type *i =
148 va_arg(arg,lang_input_statement_type *);
149
150 fprintf(fp,"%s", i->local_sym_name);
151 }
152 break;
153 case 'S':
154 /* Print source script file and line number */
155
156 {
157
158
159 extern unsigned int lineno;
160 if (ldfile_input_filename == (char *)NULL) {
161 fprintf(fp,"command line");
162 }
163 else {
164 fprintf(fp,"%s:%u", ldfile_input_filename, lineno );
165 }
166 }
167
168 break;
169
170 case 'R':
171 /* Print all that's interesting about a relent */
172 {
173 arelent *relent = va_arg(arg, arelent *);
174
175 fprintf(fp,"%s+0x%x (type %s)",
176 (*(relent->sym_ptr_ptr))->name,
177 relent->addend,
178 relent->howto->name);
179
180
181 }
182 break;
183
184
185
186
187 case 'C':
188 {
189 CONST char *filename;
190 CONST char *functionname;
191 char *cplus_name;
192
193 unsigned int linenumber;
194 bfd *abfd = va_arg(arg, bfd *);
195 asection *section = va_arg(arg, asection *);
196 asymbol **symbols = va_arg(arg, asymbol **);
197 bfd_vma offset = va_arg(arg, bfd_vma);
198
199 if (bfd_find_nearest_line(abfd,
200 section,
201 symbols,
202 offset,
203 &filename,
204 &functionname,
205 &linenumber))
206 {
207 if (filename == (char *)NULL)
208 filename = abfd->filename;
209 if (functionname != (char *)NULL)
210 {
211 cplus_name = cplus_demangle(functionname, 1);
212 fprintf(fp,"%s:%u: (%s)", filename, linenumber,
213 cplus_name? cplus_name: functionname);
214 if (cplus_name)
215 free(cplus_name);
216
217
218 }
219
220 else if (linenumber != 0)
221 fprintf(fp,"%s:%u", filename, linenumber);
222 else
223 fprintf(fp,"%s(%s+%0x)", filename,
224 section->name,
225 offset);
226
227 }
228 else {
229 fprintf(fp,"%s(%s+%0x)", abfd->filename,
230 section->name,
231 offset);
232 }
233 }
234 break;
235
236 case 's':
237 fprintf(fp,"%s", va_arg(arg, char *));
238 break;
239 case 'd':
240 fprintf(fp,"%d", va_arg(arg, int));
241 break;
242 default:
243 fprintf(fp,"%s", va_arg(arg, char *));
244 break;
245 }
246 }
247 }
248 if (fatal == true)
249 {
250 extern char *output_filename;
251 if (output_filename)
252 {
253 char *new = malloc(strlen(output_filename)+2);
254 extern bfd *output_bfd;
255
256 strcpy(new, output_filename);
257 if (output_bfd && output_bfd->iostream)
258 fclose((FILE *)(output_bfd->iostream));
259 unlink(new);
260 }
261 exit(1);
262 }
263 }
264
265 /* Format info message and print on stdout. */
266
267 void info(va_alist)
268 va_dcl
269 {
270 char *fmt;
271 va_list arg;
272 va_start(arg);
273 fmt = va_arg(arg, char *);
274 vfinfo(stdout, fmt, arg);
275 va_end(arg);
276 }
277
278 /* ('e' for error.) Format info message and print on stderr. */
279
280 void einfo(va_alist)
281 va_dcl
282 {
283 char *fmt;
284 va_list arg;
285 va_start(arg);
286 fmt = va_arg(arg, char *);
287 vfinfo(stderr, fmt, arg);
288 va_end(arg);
289 }
290
291 void
292 info_assert(file, line)
293 char *file;
294 unsigned int line;
295 {
296 einfo("%F%P internal error %s %d\n", file,line);
297 }
298
299 /* Return a newly-allocated string
300 whose contents concatenate those of S1, S2, S3. */
301
302 char *
303 DEFUN(concat, (s1, s2, s3),
304 CONST char *s1 AND
305 CONST char *s2 AND
306 CONST char *s3)
307 {
308 bfd_size_type len1 = strlen (s1);
309 bfd_size_type len2 = strlen (s2);
310 bfd_size_type len3 = strlen (s3);
311 char *result = ldmalloc (len1 + len2 + len3 + 1);
312
313 if (len1 != 0)
314 memcpy(result, s1, len1);
315 if (len2 != 0)
316 memcpy(result+len1, s2, len2);
317 if (len3 != 0)
318 memcpy(result+len1+len2, s2, len3);
319 *(result + len1 + len2 + len3) = 0;
320
321 return result;
322 }
323
324
325 PTR
326 DEFUN(ldmalloc, (size),
327 bfd_size_type size)
328 {
329 PTR result = malloc ((int)size);
330
331 if (result == (char *)NULL && size != 0)
332 einfo("%F%P virtual memory exhausted\n");
333
334 return result;
335 }
336
337 PTR
338 DEFUN(xmalloc,(size),
339 int size)
340 {
341 return ldmalloc(size);
342 }
343
344
345 PTR
346 DEFUN(ldrealloc, (ptr, size),
347 PTR ptr AND
348 bfd_size_type size)
349 {
350 PTR result = realloc (ptr, (int)size);
351
352 if (result == (char *)NULL && size != 0)
353 einfo("%F%P virtual memory exhausted\n");
354
355 return result;
356 }
357
358
359
360 char *DEFUN(buystring,(x),
361 CONST char *CONST x)
362 {
363 bfd_size_type l = strlen(x)+1;
364 char *r = ldmalloc(l);
365 memcpy(r, x,l);
366 return r;
367 }
368
369
370 /* ('m' for map) Format info message and print on map. */
371
372 void minfo(va_alist)
373 va_dcl
374 {
375 char *fmt;
376 va_list arg;
377 va_start(arg);
378 fmt = va_arg(arg, char *);
379 vfinfo(config.map_file, fmt, arg);
380 va_end(arg);
381 }
382
383
384
385
386
387
388 /*----------------------------------------------------------------------
389 Functions to print the link map
390 */
391
392 void
393 DEFUN_VOID(print_space)
394 {
395 fprintf(config.map_file, " ");
396 }
397 void
398 DEFUN_VOID(print_nl)
399 {
400 fprintf(config.map_file, "\n");
401 }
402 void
403 DEFUN(print_address,(value),
404 bfd_vma value)
405 {
406 fprintf_vma(config.map_file, value);
407 }
This page took 0.037099 seconds and 4 git commands to generate.