Commit | Line | Data |
---|---|---|
2fa0b342 DHW |
1 | /* Copyright (C) 1991 Free Software Foundation, Inc. |
2 | ||
3 | This file is part of GLD, the Gnu Linker. | |
4 | ||
5 | GLD is free software; you can redistribute it and/or modify | |
6 | it under the terms of the GNU General Public License as published by | |
7 | the Free Software Foundation; either version 1, or (at your option) | |
8 | any later version. | |
9 | ||
10 | GLD is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | GNU General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU General Public License | |
16 | along with GLD; see the file COPYING. If not, write to | |
17 | the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
18 | ||
19 | /* | |
20 | * $Id$ | |
21 | * | |
22 | * $Log$ | |
8cb5eb31 SC |
23 | * Revision 1.2 1991/03/22 23:02:37 steve |
24 | * Brought up to sync with Intel again. | |
2fa0b342 DHW |
25 | * |
26 | * Revision 1.2 1991/03/15 18:45:55 rich | |
27 | * foo | |
28 | * | |
29 | * Revision 1.1 1991/03/13 00:48:30 chrisb | |
30 | * Initial revision | |
31 | * | |
32 | * Revision 1.7 1991/03/10 09:31:34 rich | |
33 | * Modified Files: | |
34 | * Makefile config.h ld-emul.c ld-emul.h ld-gld.c ld-gld960.c | |
35 | * ld-lnk960.c ld.h lddigest.c ldexp.c ldexp.h ldfile.c ldfile.h | |
36 | * ldgram.y ldinfo.h ldlang.c ldlang.h ldlex.h ldlex.l ldmain.c | |
37 | * ldmain.h ldmisc.c ldmisc.h ldsym.c ldsym.h ldversion.c | |
38 | * ldversion.h ldwarn.h ldwrite.c ldwrite.h y.tab.h | |
39 | * | |
40 | * As of this round of changes, ld now builds on all hosts of (Intel960) | |
41 | * interest and copy passes my copy test on big endian hosts again. | |
42 | * | |
43 | * Revision 1.6 1991/03/09 03:31:01 sac | |
44 | * After a fatal info message, the output file is deleted. | |
45 | * | |
46 | * Revision 1.5 1991/03/06 21:59:54 sac | |
47 | * Made %C print function name if available | |
48 | * | |
49 | * Revision 1.4 1991/03/06 02:27:45 sac | |
50 | * Added support for linenumber printing via %C | |
51 | * | |
52 | * Revision 1.3 1991/02/22 17:15:03 sac | |
53 | * Added RCS keywords and copyrights | |
54 | * | |
55 | */ | |
56 | ||
57 | /* | |
58 | ldmisc.c | |
59 | ||
60 | */ | |
61 | ||
62 | #include "sysdep.h" | |
63 | #include <varargs.h> | |
64 | #include "bfd.h" | |
65 | ||
66 | #include "ld.h" | |
67 | #include "ldmisc.h" | |
68 | #include "ldlang.h" | |
69 | ||
70 | /* IMPORTS */ | |
71 | ||
72 | extern char *program_name; | |
73 | ||
74 | extern FILE *ldlex_input_stack; | |
75 | extern char *ldfile_input_filename; | |
76 | extern ld_config_type config; | |
77 | ||
78 | void | |
79 | yyerror(arg) | |
80 | char *arg; | |
81 | { | |
82 | info("%P%F: %S %s\n",arg); | |
83 | } | |
84 | ||
85 | extern int errno; | |
86 | extern int sys_nerr; | |
87 | extern char *sys_errlist[]; | |
88 | ||
89 | /* | |
90 | %F error is fatal | |
91 | %P print progam name | |
92 | %S print script file and linenumber | |
93 | %E current bfd error or errno | |
94 | %I filename from a lang_input_statement_type | |
95 | %B filename from a bfd | |
96 | %T symbol table entry | |
97 | %X no object output, fail return | |
98 | %V hex bfd_vma | |
99 | %C Clever filename:linenumber | |
100 | % | |
101 | */ | |
102 | void info(va_alist) | |
103 | va_dcl | |
104 | { | |
105 | char *fmt; | |
106 | boolean fatal = false; | |
107 | va_list arg; | |
108 | va_start(arg); | |
109 | fmt = va_arg(arg, char *); | |
110 | while (*fmt) { | |
111 | while (*fmt != '%' && *fmt != '\0') { | |
112 | fputc(*fmt, stderr); | |
113 | fmt++; | |
114 | } | |
115 | if (*fmt == '%') { | |
116 | fmt ++; | |
117 | switch (*fmt++) { | |
118 | case 'X': | |
119 | config.make_executable = false; | |
120 | break; | |
121 | case 'V': | |
122 | fprintf(stderr,"%08lx", va_arg(arg, bfd_vma)); | |
123 | break; | |
124 | case 'T': | |
125 | { | |
126 | asymbol *symbol = va_arg(arg, asymbol *); | |
127 | if (symbol) { | |
128 | asection *section = symbol->section; | |
129 | if ((symbol->flags & BSF_UNDEFINED) == 0) { | |
130 | char *section_name = section == (asection *)NULL ? | |
131 | "absolute" : section->name; | |
132 | fprintf(stderr,"%s (%s)", symbol->name, section_name); | |
133 | } | |
134 | else { | |
135 | fprintf(stderr,"%s", symbol->name); | |
136 | } | |
137 | } | |
138 | else { | |
139 | fprintf(stderr,"no symbol"); | |
140 | } | |
141 | } | |
142 | break; | |
143 | case 'B': | |
144 | { | |
145 | bfd *abfd = va_arg(arg, bfd *); | |
146 | if (abfd->my_archive) { | |
147 | fprintf(stderr,"%s(%s)", abfd->my_archive->filename, | |
148 | abfd->filename); | |
149 | } | |
150 | else { | |
151 | fprintf(stderr,"%s", abfd->filename); | |
152 | ||
153 | } | |
154 | } | |
155 | break; | |
156 | case 'F': | |
157 | fatal = true; | |
158 | break; | |
159 | case 'P': | |
160 | fprintf(stderr,"%s", program_name); | |
161 | break; | |
162 | case 'E': | |
163 | /* Replace with the most recent errno explanation */ | |
164 | ||
165 | ||
166 | fprintf(stderr, bfd_errmsg(bfd_error)); | |
167 | ||
168 | ||
169 | break; | |
170 | case 'I': | |
171 | { | |
172 | lang_input_statement_type *i = | |
173 | va_arg(arg,lang_input_statement_type *); | |
174 | ||
175 | fprintf(stderr,"%s", i->local_sym_name); | |
176 | } | |
177 | break; | |
178 | case 'S': | |
179 | /* Print source script file and line number */ | |
180 | ||
181 | if (ldlex_input_stack) { | |
182 | extern unsigned int lineno; | |
183 | if (ldfile_input_filename == (char *)NULL) { | |
184 | fprintf(stderr,"command line"); | |
185 | } | |
186 | else { | |
187 | fprintf(stderr,"%s:%u", ldfile_input_filename, lineno + 1); | |
188 | } | |
189 | } | |
190 | else { | |
191 | fprintf(stderr,"command line "); | |
192 | } | |
193 | break; | |
194 | case 'C': | |
195 | { | |
196 | char *filename; | |
197 | char *functionname; | |
198 | unsigned int linenumber; | |
199 | bfd *abfd = va_arg(arg, bfd *); | |
200 | asection *section = va_arg(arg, asection *); | |
201 | asymbol **symbols = va_arg(arg, asymbol **); | |
202 | bfd_vma offset = va_arg(arg, bfd_vma); | |
203 | ||
204 | if (bfd_find_nearest_line(abfd, | |
205 | section, | |
206 | symbols, | |
207 | offset, | |
208 | &filename, | |
209 | &functionname, | |
210 | &linenumber)) | |
211 | { | |
212 | if (filename == (char *)NULL) | |
213 | filename = abfd->filename; | |
214 | if (functionname != (char *)NULL) | |
215 | fprintf(stderr,"%s:%u: (%s)", filename, linenumber, functionname); | |
216 | else if (linenumber != 0) | |
217 | fprintf(stderr,"%s:%u", filename, linenumber); | |
218 | else | |
219 | fprintf(stderr,"%s", filename); | |
220 | ||
221 | } | |
222 | else { | |
223 | fprintf(stderr,"%s", abfd->filename); | |
224 | } | |
225 | } | |
226 | break; | |
227 | ||
228 | case 's': | |
229 | fprintf(stderr,"%s", va_arg(arg, char *)); | |
230 | break; | |
231 | case 'd': | |
232 | fprintf(stderr,"%d", va_arg(arg, int)); | |
233 | break; | |
234 | default: | |
235 | fprintf(stderr,"%s", va_arg(arg, char *)); | |
236 | break; | |
237 | } | |
238 | } | |
239 | } | |
240 | if (fatal == true) { | |
241 | extern char *output_filename; | |
242 | if (output_filename) | |
243 | unlink(output_filename); | |
244 | exit(1); | |
245 | } | |
246 | va_end(arg); | |
247 | } | |
248 | ||
249 | ||
250 | void | |
251 | info_assert(file, line) | |
252 | char *file; | |
253 | unsigned int line; | |
254 | { | |
255 | info("%F%P internal error %s %d\n", file,line); | |
256 | } | |
257 | ||
258 | /* Return a newly-allocated string | |
259 | whose contents concatenate those of S1, S2, S3. */ | |
260 | ||
261 | char * | |
262 | concat (s1, s2, s3) | |
263 | char *s1, *s2, *s3; | |
264 | { | |
265 | size_t len1 = strlen (s1); | |
266 | size_t len2 = strlen (s2); | |
267 | size_t len3 = strlen (s3); | |
268 | char *result = ldmalloc (len1 + len2 + len3 + 1); | |
269 | ||
270 | if (len1 != 0) | |
271 | memcpy(result, s1, len1); | |
272 | if (len2 != 0) | |
273 | memcpy(result+len1, s2, len2); | |
274 | if (len3 != 0) | |
275 | memcpy(result+len1+len2, s2, len3); | |
276 | *(result + len1 + len2 + len3) = 0; | |
277 | ||
278 | return result; | |
279 | } | |
280 | ||
281 | ||
282 | ||
283 | char *ldmalloc (size) | |
284 | size_t size; | |
285 | { | |
286 | char * result = malloc (size); | |
287 | ||
288 | if (result == (char *)NULL && size != 0) | |
289 | info("%F%P virtual memory exhausted\n"); | |
290 | ||
291 | return result; | |
292 | } | |
293 | ||
294 | ||
295 | ||
296 | char *buystring(x) | |
297 | char *x; | |
298 | { | |
299 | size_t l = strlen(x)+1; | |
300 | char *r = ldmalloc(l); | |
301 | memcpy(r, x,l); | |
302 | return r; | |
303 | } |