]>
Commit | Line | Data |
---|---|---|
c611e285 SC |
1 | /* ldmisc.c |
2 | Copyright (C) 1991 Free Software Foundation, Inc. | |
3 | ||
4 | Written by Steve Chamberlain of Cygnus Support. | |
2fa0b342 DHW |
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 | |
c611e285 | 10 | the Free Software Foundation; either version 2, or (at your option) |
2fa0b342 DHW |
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 | /* | |
c611e285 | 23 | $Id$ |
2fa0b342 | 24 | |
2fa0b342 | 25 | |
c611e285 | 26 | */ |
2fa0b342 | 27 | |
c611e285 | 28 | #include "bfd.h" |
2fa0b342 DHW |
29 | #include "sysdep.h" |
30 | #include <varargs.h> | |
2fa0b342 DHW |
31 | |
32 | #include "ld.h" | |
33 | #include "ldmisc.h" | |
34 | #include "ldlang.h" | |
1418c83b | 35 | #include "ldlex.h" |
2fa0b342 DHW |
36 | /* IMPORTS */ |
37 | ||
38 | extern char *program_name; | |
39 | ||
40 | extern FILE *ldlex_input_stack; | |
41 | extern char *ldfile_input_filename; | |
42 | extern ld_config_type config; | |
43 | ||
44 | void | |
45 | yyerror(arg) | |
46 | char *arg; | |
47 | { | |
c611e285 | 48 | einfo("%P%F: %S %s\n",arg); |
2fa0b342 DHW |
49 | } |
50 | ||
51 | extern int errno; | |
52 | extern int sys_nerr; | |
53 | extern char *sys_errlist[]; | |
54 | ||
55 | /* | |
56 | %F error is fatal | |
57 | %P print progam name | |
58 | %S print script file and linenumber | |
59 | %E current bfd error or errno | |
60 | %I filename from a lang_input_statement_type | |
61 | %B filename from a bfd | |
62 | %T symbol table entry | |
63 | %X no object output, fail return | |
64 | %V hex bfd_vma | |
65 | %C Clever filename:linenumber | |
c611e285 | 66 | %R info about a relent |
2fa0b342 DHW |
67 | % |
68 | */ | |
c611e285 SC |
69 | static void |
70 | vfinfo(fp, fmt, arg) | |
71 | FILE *fp; | |
72 | char *fmt; | |
73 | va_list arg; | |
2fa0b342 | 74 | { |
2fa0b342 | 75 | boolean fatal = false; |
2fa0b342 DHW |
76 | while (*fmt) { |
77 | while (*fmt != '%' && *fmt != '\0') { | |
c611e285 | 78 | putc(*fmt, fp); |
2fa0b342 DHW |
79 | fmt++; |
80 | } | |
81 | if (*fmt == '%') { | |
82 | fmt ++; | |
83 | switch (*fmt++) { | |
84 | case 'X': | |
85 | config.make_executable = false; | |
86 | break; | |
87 | case 'V': | |
c611e285 SC |
88 | { |
89 | bfd_vma value = va_arg(arg, bfd_vma); | |
90 | fprintf_vma(fp, value); | |
91 | } | |
2fa0b342 DHW |
92 | break; |
93 | case 'T': | |
94 | { | |
95 | asymbol *symbol = va_arg(arg, asymbol *); | |
c611e285 SC |
96 | if (symbol) |
97 | { | |
2fa0b342 | 98 | asection *section = symbol->section; |
c611e285 SC |
99 | CONST char *section_name = section->name; |
100 | fprintf(fp,"%s (%s)", symbol->name, section_name); | |
2fa0b342 | 101 | } |
c611e285 SC |
102 | else |
103 | { | |
104 | fprintf(fp,"no symbol"); | |
2fa0b342 DHW |
105 | } |
106 | } | |
107 | break; | |
108 | case 'B': | |
109 | { | |
110 | bfd *abfd = va_arg(arg, bfd *); | |
111 | if (abfd->my_archive) { | |
c611e285 | 112 | fprintf(fp,"%s(%s)", abfd->my_archive->filename, |
2fa0b342 DHW |
113 | abfd->filename); |
114 | } | |
115 | else { | |
c611e285 | 116 | fprintf(fp,"%s", abfd->filename); |
2fa0b342 DHW |
117 | |
118 | } | |
119 | } | |
120 | break; | |
121 | case 'F': | |
122 | fatal = true; | |
123 | break; | |
124 | case 'P': | |
c611e285 | 125 | fprintf(fp,"%s", program_name); |
2fa0b342 DHW |
126 | break; |
127 | case 'E': | |
128 | /* Replace with the most recent errno explanation */ | |
129 | ||
130 | ||
c611e285 | 131 | fprintf(fp, bfd_errmsg(bfd_error)); |
2fa0b342 DHW |
132 | |
133 | ||
134 | break; | |
135 | case 'I': | |
136 | { | |
137 | lang_input_statement_type *i = | |
138 | va_arg(arg,lang_input_statement_type *); | |
139 | ||
c611e285 | 140 | fprintf(fp,"%s", i->local_sym_name); |
2fa0b342 DHW |
141 | } |
142 | break; | |
143 | case 'S': | |
144 | /* Print source script file and line number */ | |
145 | ||
146 | if (ldlex_input_stack) { | |
147 | extern unsigned int lineno; | |
148 | if (ldfile_input_filename == (char *)NULL) { | |
c611e285 | 149 | fprintf(fp,"command line"); |
2fa0b342 DHW |
150 | } |
151 | else { | |
c611e285 | 152 | fprintf(fp,"%s:%u", ldfile_input_filename, lineno ); |
2fa0b342 DHW |
153 | } |
154 | } | |
155 | else { | |
7ca04d28 SC |
156 | int ch; |
157 | int n = 0; | |
c611e285 | 158 | fprintf(fp,"command (just before \""); |
7ca04d28 SC |
159 | ch = lex_input(); |
160 | while (ch != 0 && n < 10) { | |
c611e285 | 161 | fprintf(fp, "%c", ch); |
7ca04d28 SC |
162 | ch = lex_input(); |
163 | n++; | |
164 | } | |
c611e285 | 165 | fprintf(fp,"\")"); |
7ca04d28 | 166 | |
2fa0b342 DHW |
167 | } |
168 | break; | |
c611e285 SC |
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 | ||
2fa0b342 DHW |
187 | case 'C': |
188 | { | |
99fe4553 SC |
189 | CONST char *filename; |
190 | CONST char *functionname; | |
2fa0b342 DHW |
191 | unsigned int linenumber; |
192 | bfd *abfd = va_arg(arg, bfd *); | |
193 | asection *section = va_arg(arg, asection *); | |
194 | asymbol **symbols = va_arg(arg, asymbol **); | |
195 | bfd_vma offset = va_arg(arg, bfd_vma); | |
196 | ||
197 | if (bfd_find_nearest_line(abfd, | |
198 | section, | |
199 | symbols, | |
200 | offset, | |
201 | &filename, | |
202 | &functionname, | |
203 | &linenumber)) | |
204 | { | |
205 | if (filename == (char *)NULL) | |
206 | filename = abfd->filename; | |
207 | if (functionname != (char *)NULL) | |
c611e285 | 208 | fprintf(fp,"%s:%u: (%s)", filename, linenumber, functionname); |
2fa0b342 | 209 | else if (linenumber != 0) |
c611e285 | 210 | fprintf(fp,"%s:%u", filename, linenumber); |
2fa0b342 | 211 | else |
c611e285 SC |
212 | fprintf(fp,"%s(%s+%0x)", filename, |
213 | section->name, | |
214 | offset); | |
2fa0b342 DHW |
215 | |
216 | } | |
217 | else { | |
c611e285 SC |
218 | fprintf(fp,"%s(%s+%0x)", abfd->filename, |
219 | section->name, | |
220 | offset); | |
2fa0b342 DHW |
221 | } |
222 | } | |
223 | break; | |
224 | ||
225 | case 's': | |
c611e285 | 226 | fprintf(fp,"%s", va_arg(arg, char *)); |
2fa0b342 DHW |
227 | break; |
228 | case 'd': | |
c611e285 | 229 | fprintf(fp,"%d", va_arg(arg, int)); |
2fa0b342 DHW |
230 | break; |
231 | default: | |
c611e285 | 232 | fprintf(fp,"%s", va_arg(arg, char *)); |
2fa0b342 DHW |
233 | break; |
234 | } | |
235 | } | |
236 | } | |
237 | if (fatal == true) { | |
238 | extern char *output_filename; | |
239 | if (output_filename) | |
240 | unlink(output_filename); | |
241 | exit(1); | |
242 | } | |
c611e285 SC |
243 | } |
244 | ||
245 | /* Format info message and print on stdout. */ | |
246 | ||
247 | void info(va_alist) | |
248 | va_dcl | |
249 | { | |
250 | char *fmt; | |
251 | va_list arg; | |
252 | va_start(arg); | |
253 | fmt = va_arg(arg, char *); | |
254 | vfinfo(stdout, fmt, arg); | |
2fa0b342 DHW |
255 | va_end(arg); |
256 | } | |
257 | ||
c611e285 SC |
258 | /* ('e' for error.) Format info message and print on stderr. */ |
259 | ||
260 | void einfo(va_alist) | |
261 | va_dcl | |
262 | { | |
263 | char *fmt; | |
264 | va_list arg; | |
265 | va_start(arg); | |
266 | fmt = va_arg(arg, char *); | |
267 | vfinfo(stderr, fmt, arg); | |
268 | va_end(arg); | |
269 | } | |
2fa0b342 DHW |
270 | |
271 | void | |
272 | info_assert(file, line) | |
273 | char *file; | |
274 | unsigned int line; | |
275 | { | |
c611e285 | 276 | einfo("%F%P internal error %s %d\n", file,line); |
2fa0b342 DHW |
277 | } |
278 | ||
279 | /* Return a newly-allocated string | |
280 | whose contents concatenate those of S1, S2, S3. */ | |
281 | ||
282 | char * | |
99fe4553 SC |
283 | DEFUN(concat, (s1, s2, s3), |
284 | CONST char *s1 AND | |
285 | CONST char *s2 AND | |
286 | CONST char *s3) | |
2fa0b342 | 287 | { |
c611e285 SC |
288 | bfd_size_type len1 = strlen (s1); |
289 | bfd_size_type len2 = strlen (s2); | |
290 | bfd_size_type len3 = strlen (s3); | |
2fa0b342 DHW |
291 | char *result = ldmalloc (len1 + len2 + len3 + 1); |
292 | ||
293 | if (len1 != 0) | |
294 | memcpy(result, s1, len1); | |
295 | if (len2 != 0) | |
296 | memcpy(result+len1, s2, len2); | |
297 | if (len3 != 0) | |
298 | memcpy(result+len1+len2, s2, len3); | |
299 | *(result + len1 + len2 + len3) = 0; | |
300 | ||
301 | return result; | |
302 | } | |
303 | ||
304 | ||
305 | ||
c611e285 SC |
306 | PTR |
307 | DEFUN(ldmalloc, (size), | |
308 | bfd_size_type size) | |
2fa0b342 | 309 | { |
c611e285 | 310 | PTR result = malloc ((int)size); |
2fa0b342 DHW |
311 | |
312 | if (result == (char *)NULL && size != 0) | |
c611e285 | 313 | einfo("%F%P virtual memory exhausted\n"); |
2fa0b342 DHW |
314 | |
315 | return result; | |
316 | } | |
317 | ||
318 | ||
319 | ||
1418c83b SC |
320 | char *DEFUN(buystring,(x), |
321 | CONST char *CONST x) | |
2fa0b342 | 322 | { |
c611e285 | 323 | bfd_size_type l = strlen(x)+1; |
2fa0b342 DHW |
324 | char *r = ldmalloc(l); |
325 | memcpy(r, x,l); | |
326 | return r; | |
327 | } | |
c611e285 SC |
328 | |
329 | ||
330 | /*---------------------------------------------------------------------- | |
331 | Functions to print the link map | |
332 | */ | |
333 | ||
334 | void | |
335 | DEFUN_VOID(print_space) | |
336 | { | |
337 | printf(" "); | |
338 | } | |
339 | void | |
340 | DEFUN_VOID(print_nl) | |
341 | { | |
342 | printf("\n"); | |
343 | } | |
344 | void | |
345 | DEFUN(print_address,(value), | |
346 | bfd_vma value) | |
347 | { | |
348 | printf_vma(value); | |
349 | } |