* ldmain.c (main): Initialize new field link_info.static_link.
[deliverable/binutils-gdb.git] / ld / ldwrite.c
1 /* ldwrite.c -- write out the linked file
2 Copyright (C) 1993 Free Software Foundation, Inc.
3 Written by Steve Chamberlain sac@cygnus.com
4
5 This file is part of GLD, the Gnu Linker.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20
21 #include "bfd.h"
22 #include "sysdep.h"
23 #include "bfdlink.h"
24
25 #include "ld.h"
26 #include "ldexp.h"
27 #include "ldlang.h"
28 #include "ldwrite.h"
29 #include "ldmisc.h"
30 #include "ldgram.h"
31 #include "ldmain.h"
32
33 static void build_link_order PARAMS ((lang_statement_union_type *));
34 static void print_symbol_table PARAMS ((void));
35 static void print_file_stuff PARAMS ((lang_input_statement_type *));
36 static boolean print_symbol PARAMS ((struct bfd_link_hash_entry *, PTR));
37
38 extern char *strdup();
39
40 /* Build link_order structures for the BFD linker. */
41
42 static void
43 build_link_order (statement)
44 lang_statement_union_type *statement;
45 {
46 switch (statement->header.type)
47 {
48 case lang_data_statement_enum:
49 {
50 asection *output_section;
51 struct bfd_link_order *link_order;
52 bfd_vma value;
53
54 output_section = statement->data_statement.output_section;
55 ASSERT (output_section->owner == output_bfd);
56
57 link_order = bfd_new_link_order (output_bfd, output_section);
58 if (link_order == NULL)
59 einfo ("%P%F: bfd_new_link_order failed\n");
60
61 link_order->type = bfd_data_link_order;
62 link_order->offset = statement->data_statement.output_vma;
63 link_order->u.data.contents = (bfd_byte *) xmalloc (QUAD_SIZE);
64
65 value = statement->data_statement.value;
66
67 ASSERT (output_section->owner == output_bfd);
68 switch (statement->data_statement.type)
69 {
70 case QUAD:
71 bfd_put_64 (output_bfd, value, link_order->u.data.contents);
72 link_order->size = QUAD_SIZE;
73 break;
74 case LONG:
75 bfd_put_32 (output_bfd, value, link_order->u.data.contents);
76 link_order->size = LONG_SIZE;
77 break;
78 case SHORT:
79 bfd_put_16 (output_bfd, value, link_order->u.data.contents);
80 link_order->size = SHORT_SIZE;
81 break;
82 case BYTE:
83 bfd_put_8 (output_bfd, value, link_order->u.data.contents);
84 link_order->size = BYTE_SIZE;
85 break;
86 default:
87 abort ();
88 }
89 }
90 break;
91
92 case lang_reloc_statement_enum:
93 {
94 lang_reloc_statement_type *rs;
95 asection *output_section;
96 struct bfd_link_order *link_order;
97
98 rs = &statement->reloc_statement;
99
100 output_section = rs->output_section;
101 ASSERT (output_section->owner == output_bfd);
102
103 link_order = bfd_new_link_order (output_bfd, output_section);
104 if (link_order == NULL)
105 einfo ("%P%F: bfd_new_link_order failed\n");
106
107 link_order->offset = rs->output_vma;
108 link_order->size = bfd_get_reloc_size (rs->howto);
109
110 link_order->u.reloc.p =
111 ((struct bfd_link_order_reloc *)
112 xmalloc (sizeof (struct bfd_link_order_reloc)));
113
114 link_order->u.reloc.p->reloc = rs->reloc;
115 link_order->u.reloc.p->addend = rs->addend_value;
116
117 if (rs->section != (asection *) NULL)
118 {
119 ASSERT (rs->name == (const char *) NULL);
120 link_order->type = bfd_section_reloc_link_order;
121 if (rs->section->owner == output_bfd)
122 link_order->u.reloc.p->u.section = rs->section;
123 else
124 {
125 link_order->u.reloc.p->u.section = rs->section->output_section;
126 link_order->u.reloc.p->addend += rs->section->output_offset;
127 }
128 }
129 else
130 {
131 ASSERT (rs->name != (const char *) NULL);
132 link_order->type = bfd_symbol_reloc_link_order;
133 link_order->u.reloc.p->u.name = rs->name;
134 }
135 }
136 break;
137
138 case lang_input_section_enum:
139 /* Create a new link_order in the output section with this
140 attached */
141 if (statement->input_section.ifile->just_syms_flag == false)
142 {
143 asection *i = statement->input_section.section;
144 asection *output_section = i->output_section;
145
146 ASSERT (output_section->owner == output_bfd);
147
148 if ((output_section->flags & SEC_HAS_CONTENTS) != 0)
149 {
150 struct bfd_link_order *link_order;
151
152 link_order = bfd_new_link_order (output_bfd, output_section);
153
154 if (i->flags & SEC_NEVER_LOAD)
155 {
156 /* We've got a never load section inside one which
157 is going to be output, we'll change it into a
158 fill link_order */
159 link_order->type = bfd_fill_link_order;
160 link_order->u.fill.value = 0;
161 }
162 else
163 {
164 link_order->type = bfd_indirect_link_order;
165 link_order->u.indirect.section = i;
166 ASSERT (i->output_section == output_section);
167 }
168 if (i->_cooked_size)
169 link_order->size = i->_cooked_size;
170 else
171 link_order->size = bfd_get_section_size_before_reloc (i);
172 link_order->offset = i->output_offset;
173 }
174 }
175 break;
176
177 case lang_padding_statement_enum:
178 /* Make a new link_order with the right filler */
179 {
180 asection *output_section;
181 struct bfd_link_order *link_order;
182
183 output_section = statement->padding_statement.output_section;
184 ASSERT (statement->padding_statement.output_section->owner
185 == output_bfd);
186 if ((output_section->flags & SEC_HAS_CONTENTS) != 0)
187 {
188 link_order = bfd_new_link_order (output_bfd, output_section);
189 link_order->type = bfd_fill_link_order;
190 link_order->size = statement->padding_statement.size;
191 link_order->offset = statement->padding_statement.output_offset;
192 link_order->u.fill.value = statement->padding_statement.fill;
193 }
194 }
195 break;
196
197 default:
198 /* All the other ones fall through */
199 break;
200 }
201 }
202
203 /* Call BFD to write out the linked file. */
204
205
206 /**********************************************************************/
207
208
209 /* Wander around the input sections, make sure that
210 we'll never try and create an output section with more relocs
211 than will fit.. Do this by always assuming the worst case, and
212 creating new output sections with all the right bits */
213 #define TESTIT 1
214 static asection *
215 clone_section (abfd, s, count)
216 bfd *abfd;
217 asection *s;
218 int *count;
219 {
220 #define SSIZE 8
221 char sname[SSIZE]; /* ?? find the name for this size */
222 asection *n;
223 struct bfd_link_hash_entry *h;
224 /* Invent a section name - use first five
225 chars of base section name and a digit suffix */
226 do
227 {
228 unsigned int i;
229 char b[6];
230 for (i = 0; i < sizeof (b) - 1 && s->name[i]; i++)
231 b[i] = s->name[i];
232 b[i] = 0;
233 sprintf (sname, "%s%d", b, (*count)++);
234 }
235 while (bfd_get_section_by_name (abfd, sname));
236
237 n = bfd_make_section_anyway (abfd, strdup (sname));
238
239 /* Create a symbol of the same name */
240
241 h = bfd_link_hash_lookup (link_info.hash,
242 sname, true, true, false);
243 h->type = bfd_link_hash_defined;
244 h->u.def.value = 0;
245 h->u.def.section = n ;
246
247
248 n->flags = s->flags;
249 n->vma = s->vma;
250 n->user_set_vma = s->user_set_vma;
251 n->lma = s->lma;
252 n->_cooked_size = 0;
253 n->_raw_size = 0;
254 n->output_offset = s->output_offset;
255 n->output_section = n;
256 n->orelocation = 0;
257 n->reloc_count = 0;
258 n->alignment_power = s->alignment_power;
259 return n;
260 }
261
262 #if TESTING
263 static void
264 ds (s)
265 asection *s;
266 {
267 struct bfd_link_order *l = s->link_order_head;
268 printf ("vma %x size %x\n", s->vma, s->_raw_size);
269 while (l)
270 {
271 if (l->type == bfd_indirect_link_order)
272 {
273 printf ("%8x %s\n", l->offset, l->u.indirect.section->owner->filename);
274 }
275 else
276 {
277 printf ("%8x something else\n", l->offset);
278 }
279 l = l->next;
280 }
281 printf ("\n");
282 }
283 dump (s, a1, a2)
284 char *s;
285 asection *a1;
286 asection *a2;
287 {
288 printf ("%s\n", s);
289 ds (a1);
290 ds (a2);
291 }
292
293 static void
294 sanity_check (abfd)
295 bfd *abfd;
296 {
297 asection *s;
298 for (s = abfd->sections; s; s = s->next)
299 {
300 struct bfd_link_order *p;
301 bfd_vma prev = 0;
302 for (p = s->link_order_head; p; p = p->next)
303 {
304 if (p->offset > 100000)
305 abort ();
306 if (p->offset < prev)
307 abort ();
308 prev = p->offset;
309 }
310 }
311 }
312 #else
313 #define sanity_check(a)
314 #define dump(a, b, c)
315 #endif
316
317
318 void
319 split_sections (abfd, info)
320 bfd *abfd;
321 struct bfd_link_info *info;
322 {
323 asection *original_sec;
324 int nsecs = abfd->section_count;
325 sanity_check (abfd);
326 /* look through all the original sections */
327 for (original_sec = abfd->sections;
328 original_sec && nsecs;
329 original_sec = original_sec->next, nsecs--)
330 {
331 boolean first = true;
332 int count = 0;
333 int lines = 0;
334 int relocs = 0;
335 struct bfd_link_order **pp;
336 bfd_vma vma = original_sec->vma;
337 bfd_vma shift_offset = 0;
338 asection *cursor = original_sec;
339
340 /* count up the relocations and line entries to see if
341 anything would be too big to fit */
342 for (pp = &(cursor->link_order_head); *pp; pp = &((*pp)->next))
343 {
344 struct bfd_link_order *p = *pp;
345 int thislines = 0;
346 int thisrelocs = 0;
347 if (p->type == bfd_indirect_link_order)
348 {
349 asection *sec;
350
351 sec = p->u.indirect.section;
352
353 if (info->strip == strip_none
354 || info->strip == strip_some)
355 thislines = sec->lineno_count;
356
357 if (info->relocateable)
358 thisrelocs = sec->reloc_count;
359
360 }
361 else if (info->relocateable
362 && (p->type == bfd_section_reloc_link_order
363 || p->type == bfd_symbol_reloc_link_order))
364 thisrelocs++;
365
366 if (! first
367 && (thisrelocs + relocs > config.split_by_reloc
368 || thislines + lines > config.split_by_reloc
369 || config.split_by_file))
370 {
371 /* create a new section and put this link order and the
372 following link orders into it */
373 struct bfd_link_order *l = p;
374 asection *n = clone_section (abfd, cursor, &count);
375 *pp = NULL; /* Snip off link orders from old section */
376 n->link_order_head = l; /* attach to new section */
377 pp = &n->link_order_head;
378
379 /* change the size of the original section and
380 update the vma of the new one */
381
382 dump ("before snip", cursor, n);
383
384 n->_raw_size = cursor->_raw_size - l->offset;
385 cursor->_raw_size = l->offset;
386
387 vma += cursor->_raw_size;
388 n->lma = n->vma = vma;
389
390 shift_offset = l->offset;
391
392 /* run down the chain and change the output section to
393 the right one, update the offsets too */
394
395 while (l)
396 {
397 l->offset -= shift_offset;
398 if (l->type == bfd_indirect_link_order)
399 {
400 l->u.indirect.section->output_section = n;
401 l->u.indirect.section->output_offset = l->offset;
402 }
403 l = l->next;
404 }
405 dump ("after snip", cursor, n);
406 cursor = n;
407 relocs = thisrelocs;
408 lines = thislines;
409 }
410 else
411 {
412 relocs += thisrelocs;
413 lines += thislines;
414 }
415
416 first = false;
417 }
418 }
419 sanity_check (abfd);
420 }
421 /**********************************************************************/
422 void
423 ldwrite ()
424 {
425 /* Reset error indicator, which can typically something like invalid
426 format from openning up the .o files */
427 bfd_set_error (bfd_error_no_error);
428 lang_for_each_statement (build_link_order);
429
430 if (config.split_by_reloc || config.split_by_file)
431 split_sections (output_bfd, &link_info);
432 if (!bfd_final_link (output_bfd, &link_info))
433 {
434 /* If there was an error recorded, print it out. Otherwise assume
435 an appropriate error message like unknown symbol was printed
436 out. */
437
438 if (bfd_get_error () != bfd_error_no_error)
439 einfo ("%F%P: final link failed: %E\n", output_bfd);
440 else
441 xexit(1);
442 }
443
444 if (config.map_file)
445 {
446 print_symbol_table ();
447 lang_map ();
448 }
449 }
450
451 /* Print the symbol table. */
452
453 static void
454 print_symbol_table ()
455 {
456 fprintf (config.map_file, "**FILES**\n\n");
457 lang_for_each_file (print_file_stuff);
458
459 fprintf (config.map_file, "**GLOBAL SYMBOLS**\n\n");
460 fprintf (config.map_file, "offset section offset symbol\n");
461 bfd_link_hash_traverse (link_info.hash, print_symbol, (PTR) NULL);
462 }
463
464 /* Print information about a file. */
465
466 static void
467 print_file_stuff (f)
468 lang_input_statement_type *f;
469 {
470 fprintf (config.map_file, " %s\n", f->filename);
471 if (f->just_syms_flag)
472 {
473 fprintf (config.map_file, " symbols only\n");
474 }
475 else
476 {
477 asection *s;
478 if (true)
479 {
480 for (s = f->the_bfd->sections;
481 s != (asection *) NULL;
482 s = s->next)
483 {
484 #ifdef WINDOWS_NT
485 /* Don't include any information that goes into the '.junk'
486 section. This includes the code view .debug$ data and
487 stuff from .drectve sections */
488 if (strcmp (s->name, ".drectve") == 0 ||
489 strncmp (s->name, ".debug$", 7) == 0)
490 continue;
491 #endif
492 print_address (s->output_offset);
493 if (s->reloc_done)
494 {
495 fprintf (config.map_file, " %08x 2**%2ud %s\n",
496 (unsigned) bfd_get_section_size_after_reloc (s),
497 s->alignment_power, s->name);
498 }
499
500 else
501 {
502 fprintf (config.map_file, " %08x 2**%2ud %s\n",
503 (unsigned) bfd_get_section_size_before_reloc (s),
504 s->alignment_power, s->name);
505 }
506 }
507 }
508 else
509 {
510 for (s = f->the_bfd->sections;
511 s != (asection *) NULL;
512 s = s->next)
513 {
514 fprintf (config.map_file, "%s ", s->name);
515 print_address (s->output_offset);
516 fprintf (config.map_file, "(%x)",
517 (unsigned) bfd_get_section_size_after_reloc (s));
518 }
519 fprintf (config.map_file, "hex \n");
520 }
521 }
522 print_nl ();
523 }
524
525 /* Print a symbol. */
526
527 /*ARGSUSED*/
528 static boolean
529 print_symbol (p, ignore)
530 struct bfd_link_hash_entry *p;
531 PTR ignore;
532 {
533 while (p->type == bfd_link_hash_indirect
534 || p->type == bfd_link_hash_warning)
535 p = p->u.i.link;
536
537 switch (p->type)
538 {
539 case bfd_link_hash_new:
540 abort ();
541
542 case bfd_link_hash_undefined:
543 fprintf (config.map_file, "undefined ");
544 fprintf (config.map_file, "%s ", p->root.string);
545 print_nl ();
546 break;
547
548 case bfd_link_hash_undefweak:
549 fprintf (config.map_file, "weak ");
550 fprintf (config.map_file, "%s ", p->root.string);
551 print_nl ();
552 break;
553
554 case bfd_link_hash_defined:
555 case bfd_link_hash_defweak:
556 {
557 asection *defsec = p->u.def.section;
558
559 print_address (p->u.def.value);
560 if (defsec)
561 {
562 fprintf (config.map_file, " %-10s",
563 bfd_section_name (output_bfd, defsec));
564 print_space ();
565 print_address (p->u.def.value + defsec->vma);
566 }
567 else
568 {
569 fprintf (config.map_file, " .......");
570 }
571 fprintf (config.map_file, " %s", p->root.string);
572 if (p->type == bfd_link_hash_defweak)
573 fprintf (config.map_file, " [weak]");
574 }
575 print_nl ();
576 break;
577
578 case bfd_link_hash_common:
579 fprintf (config.map_file, "common ");
580 print_address (p->u.c.size);
581 fprintf (config.map_file, " %s ", p->root.string);
582 print_nl ();
583 break;
584
585 default:
586 abort ();
587 }
588
589 return true;
590 }
This page took 0.041867 seconds and 5 git commands to generate.