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