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., 675 Mass Ave, Cambridge, MA 02139, 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
:
47 /* FIXME: This should probably build a link_order, but instead
48 it just does the output directly. */
50 bfd_vma value
= statement
->data_statement
.value
;
51 bfd_byte play_area
[LONG_SIZE
];
52 unsigned int size
= 0;
53 asection
*output_section
= statement
->data_statement
.output_section
;
55 ASSERT (output_section
->owner
== output_bfd
);
56 switch (statement
->data_statement
.type
)
59 bfd_put_32 (output_bfd
, value
, play_area
);
63 bfd_put_16 (output_bfd
, value
, play_area
);
67 bfd_put_8 (output_bfd
, value
, play_area
);
74 if (! bfd_set_section_contents (output_bfd
, output_section
,
76 statement
->data_statement
.output_vma
,
78 einfo ("%P%X: writing data failed: %E\n");
82 case lang_input_section_enum
:
83 /* Create a new link_order in the output section with this
85 if (statement
->input_section
.ifile
->just_syms_flag
== false)
87 asection
*i
= statement
->input_section
.section
;
88 asection
*output_section
= i
->output_section
;
90 ASSERT (output_section
->owner
== output_bfd
);
92 if ((output_section
->flags
& SEC_HAS_CONTENTS
) != 0)
94 struct bfd_link_order
*link_order
;
96 link_order
= bfd_new_link_order (output_bfd
, output_section
);
98 if (i
->flags
& SEC_NEVER_LOAD
)
100 /* We've got a never load section inside one which
101 is going to be output, we'll change it into a
103 link_order
->type
= bfd_fill_link_order
;
104 link_order
->u
.fill
.value
= 0;
108 link_order
->type
= bfd_indirect_link_order
;
109 link_order
->u
.indirect
.section
= i
;
110 ASSERT (i
->output_section
== output_section
);
112 link_order
->size
= bfd_section_size (i
->owner
, i
);
113 link_order
->offset
= i
->output_offset
;
118 case lang_padding_statement_enum
:
119 /* Make a new link_order with the right filler */
121 asection
*output_section
;
122 struct bfd_link_order
*link_order
;
124 output_section
= statement
->padding_statement
.output_section
;
125 ASSERT (statement
->padding_statement
.output_section
->owner
127 if ((output_section
->flags
& SEC_HAS_CONTENTS
) != 0)
129 link_order
= bfd_new_link_order (output_bfd
, output_section
);
130 link_order
->type
= bfd_fill_link_order
;
131 link_order
->size
= statement
->padding_statement
.size
;
132 link_order
->offset
= statement
->padding_statement
.output_offset
;
133 link_order
->u
.fill
.value
= statement
->padding_statement
.fill
;
139 /* All the other ones fall through */
144 /* Call BFD to write out the linked file. */
149 lang_for_each_statement (build_link_order
);
151 if (! bfd_final_link (output_bfd
, &link_info
))
152 einfo ("%F%P: %B: %E\n", output_bfd
);
156 print_symbol_table ();
161 /* Print the symbol table. */
164 print_symbol_table ()
166 fprintf (config
.map_file
, "**FILES**\n\n");
167 lang_for_each_file (print_file_stuff
);
169 fprintf (config
.map_file
, "**GLOBAL SYMBOLS**\n\n");
170 fprintf (config
.map_file
, "offset section offset symbol\n");
171 bfd_link_hash_traverse (link_info
.hash
, print_symbol
, (PTR
) NULL
);
174 /* Print information about a file. */
178 lang_input_statement_type
* f
;
180 fprintf (config
.map_file
, " %s\n", f
->filename
);
181 if (f
->just_syms_flag
)
183 fprintf (config
.map_file
, " symbols only\n");
190 for (s
= f
->the_bfd
->sections
;
191 s
!= (asection
*) NULL
;
194 print_address (s
->output_offset
);
197 fprintf (config
.map_file
, " %08x 2**%2ud %s\n",
198 (unsigned) bfd_get_section_size_after_reloc (s
),
199 s
->alignment_power
, s
->name
);
204 fprintf (config
.map_file
, " %08x 2**%2ud %s\n",
205 (unsigned) bfd_get_section_size_before_reloc (s
),
206 s
->alignment_power
, s
->name
);
212 for (s
= f
->the_bfd
->sections
;
213 s
!= (asection
*) NULL
;
216 fprintf (config
.map_file
, "%s ", s
->name
);
217 print_address (s
->output_offset
);
218 fprintf (config
.map_file
, "(%x)",
219 (unsigned) bfd_get_section_size_after_reloc (s
));
221 fprintf (config
.map_file
, "hex \n");
227 /* Print a symbol. */
230 print_symbol (p
, ignore
)
231 struct bfd_link_hash_entry
*p
;
234 while (p
->type
== bfd_link_hash_indirect
235 || p
->type
== bfd_link_hash_warning
)
240 case bfd_link_hash_new
:
243 case bfd_link_hash_undefined
:
244 fprintf (config
.map_file
, "undefined ");
245 fprintf (config
.map_file
, "%s ", p
->root
.string
);
249 case bfd_link_hash_weak
:
250 fprintf (config
.map_file
, "weak ");
251 fprintf (config
.map_file
, "%s ", p
->root
.string
);
255 case bfd_link_hash_defined
:
257 asection
*defsec
= p
->u
.def
.section
;
259 print_address (p
->u
.def
.value
);
262 fprintf (config
.map_file
, " %-10s",
263 bfd_section_name (output_bfd
, defsec
));
265 print_address (p
->u
.def
.value
+ defsec
->vma
);
269 fprintf (config
.map_file
, " .......");
271 fprintf (config
.map_file
, " %s ", p
->root
.string
);
276 case bfd_link_hash_common
:
277 fprintf (config
.map_file
, "common ");
278 print_address (p
->u
.c
.size
);
279 fprintf (config
.map_file
, " %s ", p
->root
.string
);