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