1 /* ldwrite.c -- write out the linked file
2 Copyright (C) 1993 Free Software Foundation, Inc.
3 Written by Steve Chamberlain sac@cygnus.com
5 This file is part of GLD, the Gnu Linker.
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.
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.
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. */
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
));
38 /* Build link_order structures for the BFD linker. */
41 build_link_order (statement
)
42 lang_statement_union_type
*statement
;
44 switch (statement
->header
.type
)
46 case lang_data_statement_enum
:
48 asection
*output_section
;
49 struct bfd_link_order
*link_order
;
52 output_section
= statement
->data_statement
.output_section
;
53 ASSERT (output_section
->owner
== output_bfd
);
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");
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
);
63 value
= statement
->data_statement
.value
;
65 ASSERT (output_section
->owner
== output_bfd
);
66 switch (statement
->data_statement
.type
)
69 bfd_put_64 (output_bfd
, value
, link_order
->u
.data
.contents
);
70 link_order
->size
= QUAD_SIZE
;
73 bfd_put_32 (output_bfd
, value
, link_order
->u
.data
.contents
);
74 link_order
->size
= LONG_SIZE
;
77 bfd_put_16 (output_bfd
, value
, link_order
->u
.data
.contents
);
78 link_order
->size
= SHORT_SIZE
;
81 bfd_put_8 (output_bfd
, value
, link_order
->u
.data
.contents
);
82 link_order
->size
= BYTE_SIZE
;
90 case lang_reloc_statement_enum
:
92 lang_reloc_statement_type
*rs
;
93 asection
*output_section
;
94 struct bfd_link_order
*link_order
;
96 rs
= &statement
->reloc_statement
;
98 output_section
= rs
->output_section
;
99 ASSERT (output_section
->owner
== output_bfd
);
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");
105 link_order
->offset
= rs
->output_vma
;
106 link_order
->size
= bfd_get_reloc_size (rs
->howto
);
108 link_order
->u
.reloc
.p
=
109 ((struct bfd_link_order_reloc
*)
110 xmalloc (sizeof (struct bfd_link_order_reloc
)));
112 link_order
->u
.reloc
.p
->reloc
= rs
->reloc
;
113 link_order
->u
.reloc
.p
->addend
= rs
->addend_value
;
115 if (rs
->section
!= (asection
*) NULL
)
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
;
123 link_order
->u
.reloc
.p
->u
.section
= rs
->section
->output_section
;
124 link_order
->u
.reloc
.p
->addend
+= rs
->section
->output_offset
;
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
;
136 case lang_input_section_enum
:
137 /* Create a new link_order in the output section with this
139 if (statement
->input_section
.ifile
->just_syms_flag
== false)
141 asection
*i
= statement
->input_section
.section
;
142 asection
*output_section
= i
->output_section
;
144 ASSERT (output_section
->owner
== output_bfd
);
146 if ((output_section
->flags
& SEC_HAS_CONTENTS
) != 0)
148 struct bfd_link_order
*link_order
;
150 link_order
= bfd_new_link_order (output_bfd
, output_section
);
152 if (i
->flags
& SEC_NEVER_LOAD
)
154 /* We've got a never load section inside one which
155 is going to be output, we'll change it into a
157 link_order
->type
= bfd_fill_link_order
;
158 link_order
->u
.fill
.value
= 0;
162 link_order
->type
= bfd_indirect_link_order
;
163 link_order
->u
.indirect
.section
= i
;
164 ASSERT (i
->output_section
== output_section
);
167 link_order
->size
= i
->_cooked_size
;
169 link_order
->size
= bfd_get_section_size_before_reloc (i
);
170 link_order
->offset
= i
->output_offset
;
175 case lang_padding_statement_enum
:
176 /* Make a new link_order with the right filler */
178 asection
*output_section
;
179 struct bfd_link_order
*link_order
;
181 output_section
= statement
->padding_statement
.output_section
;
182 ASSERT (statement
->padding_statement
.output_section
->owner
184 if ((output_section
->flags
& SEC_HAS_CONTENTS
) != 0)
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
;
196 /* All the other ones fall through */
201 /* Call BFD to write out the linked file. */
204 /**********************************************************************/
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 */
213 clone_section (abfd
, s
, count
)
219 char sname
[SSIZE
]; /* ?? find the name for this size */
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 */
228 for (i
= 0; i
< sizeof (b
) - 1 && s
->name
[i
]; i
++)
231 sprintf (sname
, "%s%d", b
, (*count
)++);
233 while (bfd_get_section_by_name (abfd
, sname
));
235 n
= bfd_make_section_anyway (abfd
, strdup (sname
));
237 /* Create a symbol of the same name */
239 h
= bfd_link_hash_lookup (link_info
.hash
,
240 sname
, true, true, false);
241 h
->type
= bfd_link_hash_defined
;
243 h
->u
.def
.section
= n
;
248 n
->user_set_vma
= s
->user_set_vma
;
252 n
->output_offset
= s
->output_offset
;
253 n
->output_section
= n
;
256 n
->alignment_power
= 1;
265 struct bfd_link_order
*l
= s
->link_order_head
;
266 printf ("vma %x size %x\n", s
->vma
, s
->_raw_size
);
269 if (l
->type
== bfd_indirect_link_order
)
271 printf ("%8x %s\n", l
->offset
, l
->u
.indirect
.section
->owner
->filename
);
275 printf ("%8x something else\n", l
->offset
);
296 for (s
= abfd
->sections
; s
; s
= s
->next
)
298 struct bfd_link_order
*p
;
300 for (p
= s
->link_order_head
; p
; p
= p
->next
)
302 if (p
->offset
> 100000)
304 if (p
->offset
< prev
)
311 #define sanity_check(a)
312 #define dump(a, b, c)
317 split_sections (abfd
, info
)
319 struct bfd_link_info
*info
;
321 asection
*original_sec
;
322 int nsecs
= abfd
->section_count
;
324 /* look through all the original sections */
325 for (original_sec
= abfd
->sections
;
326 original_sec
&& nsecs
;
327 original_sec
= original_sec
->next
, nsecs
--)
329 boolean first
= true;
333 struct bfd_link_order
**pp
;
334 bfd_vma vma
= original_sec
->vma
;
335 bfd_vma shift_offset
= 0;
336 asection
*cursor
= original_sec
;
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
))
342 struct bfd_link_order
*p
= *pp
;
345 if (p
->type
== bfd_indirect_link_order
)
349 sec
= p
->u
.indirect
.section
;
351 if (info
->strip
== strip_none
352 || info
->strip
== strip_some
)
353 thislines
= sec
->lineno_count
;
355 if (info
->relocateable
)
356 thisrelocs
= sec
->reloc_count
;
359 else if (info
->relocateable
360 && (p
->type
== bfd_section_reloc_link_order
361 || p
->type
== bfd_symbol_reloc_link_order
))
365 && (thisrelocs
+ relocs
> config
.split_by_reloc
366 || thislines
+ lines
> config
.split_by_reloc
367 || config
.split_by_file
))
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
;
377 /* change the size of the original section and
378 update the vma of the new one */
380 dump ("before snip", cursor
, n
);
382 n
->_raw_size
= cursor
->_raw_size
- l
->offset
;
383 cursor
->_raw_size
= l
->offset
;
385 vma
+= cursor
->_raw_size
;
386 n
->lma
= n
->vma
= vma
;
388 shift_offset
= l
->offset
;
390 /* run down the chain and change the output section to
391 the right one, update the offsets too */
395 l
->offset
-= shift_offset
;
396 if (l
->type
== bfd_indirect_link_order
)
398 l
->u
.indirect
.section
->output_section
= n
;
399 l
->u
.indirect
.section
->output_offset
= l
->offset
;
403 dump ("after snip", cursor
, n
);
410 relocs
+= thisrelocs
;
419 /**********************************************************************/
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
);
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
))
432 /* If there was an error recorded, print it out. Otherwise assume
433 an appropriate error message like unknown symbol was printed
436 if (bfd_get_error () != bfd_error_no_error
)
437 einfo ("%F%P: final link failed: %E\n", output_bfd
);
444 print_symbol_table ();
449 /* Print the symbol table. */
452 print_symbol_table ()
454 fprintf (config
.map_file
, "**FILES**\n\n");
455 lang_for_each_file (print_file_stuff
);
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
);
462 /* Print information about a file. */
466 lang_input_statement_type
*f
;
468 fprintf (config
.map_file
, " %s\n", f
->filename
);
469 if (f
->just_syms_flag
)
471 fprintf (config
.map_file
, " symbols only\n");
478 for (s
= f
->the_bfd
->sections
;
479 s
!= (asection
*) NULL
;
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)
490 print_address (s
->output_offset
);
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
);
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
);
508 for (s
= f
->the_bfd
->sections
;
509 s
!= (asection
*) NULL
;
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
));
517 fprintf (config
.map_file
, "hex \n");
523 /* Print a symbol. */
527 print_symbol (p
, ignore
)
528 struct bfd_link_hash_entry
*p
;
531 while (p
->type
== bfd_link_hash_indirect
532 || p
->type
== bfd_link_hash_warning
)
537 case bfd_link_hash_new
:
540 case bfd_link_hash_undefined
:
541 fprintf (config
.map_file
, "undefined ");
542 fprintf (config
.map_file
, "%s ", p
->root
.string
);
546 case bfd_link_hash_undefweak
:
547 fprintf (config
.map_file
, "weak ");
548 fprintf (config
.map_file
, "%s ", p
->root
.string
);
552 case bfd_link_hash_defined
:
553 case bfd_link_hash_defweak
:
555 asection
*defsec
= p
->u
.def
.section
;
557 print_address (p
->u
.def
.value
);
560 fprintf (config
.map_file
, " %-10s",
561 bfd_section_name (output_bfd
, defsec
));
563 print_address (p
->u
.def
.value
+ defsec
->vma
);
567 fprintf (config
.map_file
, " .......");
569 fprintf (config
.map_file
, " %s", p
->root
.string
);
570 if (p
->type
== bfd_link_hash_defweak
)
571 fprintf (config
.map_file
, " [weak]");
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
);