]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - ld/ldwrite.c
Initial revision
[thirdparty/binutils-gdb.git] / ld / ldwrite.c
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$
23 * Revision 1.1 1991/03/21 21:29:04 gumby
24 * Initial revision
25 *
26 * Revision 1.2 1991/03/15 18:45:55 rich
27 * foo
28 *
29 * Revision 1.1 1991/03/13 00:48:37 chrisb
30 * Initial revision
31 *
32 * Revision 1.7 1991/03/10 19:15:03 sac
33 * Took out the abort() which had been put in the wrong place
34 * Updated the version #.
35 *
36 * Revision 1.6 1991/03/10 09:31:41 rich
37 * Modified Files:
38 * Makefile config.h ld-emul.c ld-emul.h ld-gld.c ld-gld960.c
39 * ld-lnk960.c ld.h lddigest.c ldexp.c ldexp.h ldfile.c ldfile.h
40 * ldgram.y ldinfo.h ldlang.c ldlang.h ldlex.h ldlex.l ldmain.c
41 * ldmain.h ldmisc.c ldmisc.h ldsym.c ldsym.h ldversion.c
42 * ldversion.h ldwarn.h ldwrite.c ldwrite.h y.tab.h
43 *
44 * As of this round of changes, ld now builds on all hosts of (Intel960)
45 * interest and copy passes my copy test on big endian hosts again.
46 *
47 * Revision 1.5 1991/03/09 03:25:08 sac
48 * Added support for LONG, SHORT and BYTE keywords in scripts
49 *
50 * Revision 1.4 1991/03/06 21:59:34 sac
51 * Completed G++ support
52 *
53 * Revision 1.3 1991/03/06 02:29:52 sac
54 * Added support for partial linking.
55 *
56 * Revision 1.2 1991/02/22 17:15:11 sac
57 * Added RCS keywords and copyrights
58 *
59 */
60
61 /*
62 This module writes out the final image by reading sections from the
63 input files, relocating them and writing them out
64
65 There are two main paths through this module, one for normal
66 operation and one for partial linking.
67
68 During normal operation, raw section data is read along with the
69 associated relocation information, the relocation info applied and
70 the section data written out on a section by section basis.
71
72 When partially linking, all the relocation records are read to work
73 out how big the output relocation vector will be. Then raw data is
74 read, relocated and written section by section.
75
76 Written by Steve Chamberlain steve@cygnus.com
77
78 */
79
80
81 #include "sysdep.h"
82 #include "bfd.h"
83
84 #include "ldlang.h"
85 #include "ld.h"
86 #include "ldwrite.h"
87 #include "ldmisc.h"
88 #include "ldsym.h"
89 #include "ldgram.tab.h"
90
91
92
93 char *ldmalloc();
94 /* Static vars for do_warnings and subroutines of it */
95 int list_unresolved_refs; /* List unresolved refs */
96 int list_warning_symbols; /* List warning syms */
97 int list_multiple_defs; /* List multiple definitions */
98 extern int errno;
99 extern char *sys_errlist[];
100
101 extern unsigned int undefined_global_sym_count;
102
103 extern bfd *output_bfd;
104
105 extern struct lang_output_section_statement_struct * create_object_symbols;
106
107 extern char lprefix;
108
109 #ifdef __STDC__
110 void lang_for_each_statement(void (*func)());
111 #else /* __STDC__ */
112 void lang_for_each_statement();
113 #endif /* __STDC__ */
114
115 extern size_t largest_section;
116 ld_config_type config;
117
118 extern unsigned int global_symbol_count;
119
120 boolean trace_files;
121
122 static void perform_relocation(input_bfd,
123 input_section,
124 data,
125 symbols)
126 bfd *input_bfd;
127 asection *input_section;
128 void *data;
129 asymbol **symbols;
130 {
131 static asymbol *error_symbol = (asymbol *)NULL;
132 static unsigned int error_count = 0;
133 #define MAX_ERRORS_IN_A_ROW 5
134 size_t reloc_size = get_reloc_upper_bound(input_bfd, input_section);
135
136 arelent **reloc_vector = (arelent **)ldmalloc(reloc_size);
137 arelent **parent;
138 bfd *ob = output_bfd;
139 asection *os = input_section->output_section;
140 if (config.relocateable_output == false) ob = (bfd *)NULL;
141
142 if (bfd_canonicalize_reloc(input_bfd,
143 input_section,
144 reloc_vector,
145 symbols) )
146 {
147 for (parent = reloc_vector; *parent; parent++)
148 {
149
150 bfd_reloc_status_enum_type r=
151 bfd_perform_relocation(input_bfd,
152 *parent,
153 data,
154 input_section,
155 ob);
156
157 if (r == bfd_reloc_ok) {
158 if (ob != (bfd *)NULL) {
159 /* A parital link, so keep the relocs */
160 os->orelocation[os->reloc_count] = *parent;
161 os->reloc_count++;
162 }
163 }
164 else
165 {
166 asymbol *s;
167 arelent *p = *parent;
168
169 if (ob != (bfd *)NULL) {
170 /* A parital link, so keep the relocs */
171 os->orelocation[os->reloc_count] = *parent;
172 os->reloc_count++;
173 }
174
175 if (p->sym_ptr_ptr != (asymbol **)NULL) {
176 s = *(p->sym_ptr_ptr);
177 }
178 else {
179 s = (asymbol *)NULL;
180 }
181 switch (r)
182 {
183 case bfd_reloc_undefined:
184 /* We remember the symbol, and never print more than
185 a reasonable number of them in a row */
186 if (s == error_symbol) {
187 error_count++;
188 }
189 else {
190 error_count = 0;
191 error_symbol = s;
192 }
193 if (error_count < MAX_ERRORS_IN_A_ROW) {
194 info("%C: undefined reference to `%T'\n",
195 input_bfd,
196 input_section,
197 symbols,
198 (*parent)->address,
199 s);
200 config.make_executable = false;
201 }
202 else if (error_count == MAX_ERRORS_IN_A_ROW) {
203 info("%C: more undefined references to `%T' follow\n",
204 input_bfd,
205 input_section,
206 symbols,
207 (*parent)->address,
208 s);
209 }
210 else {
211 /* Don't print any more */
212 }
213 break;
214 case bfd_reloc_dangerous:
215 info("%B: relocation may be wrong `%T'\n",
216 input_bfd,
217 s);
218 break;
219 case bfd_reloc_outofrange:
220 info("%B:%s relocation address out of range %T (%x)\n",
221 input_bfd,
222 input_section->name,
223 s,
224 p->address);
225 break;
226 case bfd_reloc_overflow:
227 info("%B:%s relocation overflow in %T reloc type %d\n",
228 input_bfd,
229 input_section->name,
230 s,
231 p->howto->type);
232 break;
233 default:
234 info("%F%B: relocation error, symbol `%T'\n",
235 input_bfd,
236 s);
237 break;
238 }
239 }
240 }
241 }
242 free((char *)reloc_vector);
243 }
244
245
246
247
248
249
250 void *data_area;
251
252 static void
253 copy_and_relocate(statement)
254 lang_statement_union_type *statement;
255 {
256 switch (statement->header.type) {
257 case lang_fill_statement_enum:
258 {
259 #if 0
260 bfd_byte play_area[SHORT_SIZE];
261 unsigned int i;
262 bfd_putshort(output_bfd, statement->fill_statement.fill, play_area);
263 /* Write out all entire shorts */
264 for (i = 0;
265 i < statement->fill_statement.size - SHORT_SIZE + 1;
266 i+= SHORT_SIZE)
267 {
268 bfd_set_section_contents(output_bfd,
269 statement->fill_statement.output_section,
270 play_area,
271 statement->data_statement.output_offset +i,
272 SHORT_SIZE);
273
274 }
275
276 /* Now write any remaining byte */
277 if (i < statement->fill_statement.size)
278 {
279 bfd_set_section_contents(output_bfd,
280 statement->fill_statement.output_section,
281 play_area,
282 statement->data_statement.output_offset +i,
283 1);
284
285 }
286 #endif
287 }
288 break;
289 case lang_data_statement_enum:
290 {
291 bfd_vma value = statement->data_statement.value;
292 bfd_byte play_area[LONG_SIZE];
293 unsigned int size;
294 switch (statement->data_statement.type) {
295 case LONG:
296 bfd_putlong(output_bfd, value, play_area);
297 size = LONG_SIZE;
298 break;
299 case SHORT:
300 bfd_putshort(output_bfd, value, play_area);
301 size = SHORT_SIZE;
302 break;
303 case BYTE:
304 bfd_putchar(output_bfd, value, play_area);
305 size = BYTE_SIZE;
306 break;
307 }
308
309 bfd_set_section_contents(output_bfd,
310 statement->data_statement.output_section,
311 play_area,
312 statement->data_statement.output_vma,
313 size);
314
315
316
317
318 }
319 break;
320 case lang_input_section_enum:
321 {
322
323 asection *i = statement->input_section.section;
324 asection *output_section = i->output_section;
325 lang_input_statement_type *ifile = statement->input_section.ifile;
326 bfd *inbfd = ifile->the_bfd;
327 if (output_section->flags & SEC_LOAD && i->size != 0)
328 {
329 if(bfd_get_section_contents(inbfd,
330 i,
331 data_area,
332 0L,
333 i->size) == false)
334 {
335 info("%F%B error reading section contents %E\n",
336 inbfd);
337 }
338 perform_relocation (inbfd, i, data_area, ifile->asymbols);
339
340
341 if(bfd_set_section_contents(output_bfd,
342 output_section,
343 data_area,
344 (file_ptr)i->output_offset,
345 i->size) == false)
346 {
347 info("%F%B error writing section contents of %E\n",
348 output_bfd);
349 }
350
351 }
352 }
353 break;
354
355 default:
356 /* All the other ones fall through */
357 ;
358
359 }
360 }
361
362 void
363 write_norel()
364 {
365 /* Output the text and data segments, relocating as we go. */
366 lang_for_each_statement(copy_and_relocate);
367 }
368
369
370 static void read_relocs(abfd, section, symbols)
371 bfd *abfd;
372 asection *section;
373 asymbol **symbols;
374 {
375 /* Work out the output section ascociated with this input section */
376 asection *output_section = section->output_section;
377
378 size_t reloc_size = get_reloc_upper_bound(abfd, section);
379 arelent **reloc_vector = (arelent **)ldmalloc(reloc_size);
380
381 if (bfd_canonicalize_reloc(abfd,
382 section,
383 reloc_vector,
384 symbols)) {
385 output_section->reloc_count += section->reloc_count;
386 }
387 }
388
389
390 static void
391 write_rel()
392 {
393 /*
394 Run through each section of each file and work work out the total
395 number of relocation records which will finally be in each output
396 section
397 */
398
399 LANG_FOR_EACH_INPUT_SECTION
400 (statement, abfd, section,
401 (read_relocs(abfd, section, statement->asymbols)));
402
403
404
405 /*
406 Now run though all the output sections and allocate the space for
407 all the relocations
408 */
409 LANG_FOR_EACH_OUTPUT_SECTION
410 (section,
411 (section->orelocation =
412 (arelent **)ldmalloc((size_t)(sizeof(arelent **)*
413 section->reloc_count)),
414 section->reloc_count = 0,
415 section->flags |= SEC_HAS_CONTENTS));
416
417
418 /*
419 Copy the data, relocating as we go
420 */
421 lang_for_each_statement(copy_and_relocate);
422 }
423
424 void
425 ldwrite ()
426 {
427 data_area = (void*) ldmalloc(largest_section);
428 if (config.relocateable_output == true)
429 {
430 write_rel();
431 }
432 else
433 {
434 write_norel();
435 }
436 free(data_area);
437 /* Output the symbol table (both globals and locals). */
438 ldsym_write ();
439
440 }
441