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