Commit | Line | Data |
---|---|---|
ac496d4f | 1 | /* Copyright (C) 1992, 1993 Free Software Foundation, Inc. |
2e2bf962 | 2 | |
ac496d4f ILT |
3 | This file is part of GLD, the Gnu Linker. |
4 | ||
5 | This program 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 2 of the License, or | |
8 | (at your option) any later version. | |
9 | ||
10 | This program 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 this program; if not, write to the Free Software | |
17 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
2e2bf962 | 18 | |
29f33467 SC |
19 | /* |
20 | ||
2e2bf962 SC |
21 | new age linking |
22 | ||
23 | ||
29f33467 | 24 | Tie together all the interseting blocks |
2e2bf962 SC |
25 | |
26 | */ | |
27 | ||
28 | ||
29 | #include "bfd.h" | |
30 | #include "../bfd/seclet.h" | |
31 | #include "coff/internal.h" | |
32 | #include "sysdep.h" | |
33 | ||
2e2bf962 | 34 | #include "ld.h" |
fcf276c4 ILT |
35 | #include "ldexp.h" |
36 | #include "ldlang.h" | |
2e2bf962 SC |
37 | #include "ldwrite.h" |
38 | #include "ldmisc.h" | |
39 | #include "ldsym.h" | |
40 | #include "ldgram.h" | |
9aa97a39 | 41 | #include "relax.h" |
2e2bf962 | 42 | static void |
8ddef552 DM |
43 | build_it (statement) |
44 | lang_statement_union_type * statement; | |
2e2bf962 | 45 | { |
29f33467 SC |
46 | switch (statement->header.type) |
47 | { | |
2e2bf962 | 48 | #if 0 |
29f33467 SC |
49 | { |
50 | ||
51 | bfd_byte play_area[SHORT_SIZE]; | |
52 | unsigned int i; | |
53 | bfd_putshort (output_bfd, statement->fill_statement.fill, play_area); | |
54 | /* Write out all entire shorts */ | |
55 | for (i = 0; | |
56 | i < statement->fill_statement.size - SHORT_SIZE + 1; | |
57 | i += SHORT_SIZE) | |
58 | { | |
59 | bfd_set_section_contents (output_bfd, | |
60 | statement->fill_statement.output_section, | |
61 | play_area, | |
62 | statement->data_statement.output_offset + i, | |
63 | SHORT_SIZE); | |
64 | ||
65 | } | |
66 | ||
67 | /* Now write any remaining byte */ | |
68 | if (i < statement->fill_statement.size) | |
69 | { | |
70 | bfd_set_section_contents (output_bfd, | |
71 | statement->fill_statement.output_section, | |
72 | play_area, | |
73 | statement->data_statement.output_offset + i, | |
74 | 1); | |
75 | ||
76 | } | |
77 | ||
78 | abort (); | |
79 | } | |
80 | break; | |
cd1d8c6d | 81 | #endif |
29f33467 SC |
82 | case lang_data_statement_enum: |
83 | ||
84 | { | |
85 | ||
86 | bfd_vma value = statement->data_statement.value; | |
87 | bfd_byte play_area[LONG_SIZE]; | |
88 | unsigned int size = 0; | |
89 | asection *output_section = statement->data_statement.output_section; | |
90 | switch (statement->data_statement.type) | |
91 | { | |
92 | case LONG: | |
93 | bfd_put_32 (output_section->owner, value, play_area); | |
94 | size = LONG_SIZE; | |
95 | break; | |
96 | case SHORT: | |
97 | bfd_put_16 (output_section->owner, value, play_area); | |
98 | size = SHORT_SIZE; | |
99 | break; | |
100 | case BYTE: | |
101 | bfd_put_8 (output_section->owner, value, play_area); | |
102 | size = BYTE_SIZE; | |
103 | break; | |
104 | } | |
105 | ||
106 | bfd_set_section_contents (output_section->owner, | |
107 | statement->data_statement.output_section, | |
108 | play_area, | |
109 | statement->data_statement.output_vma, | |
110 | size); | |
111 | ||
112 | ||
113 | ||
114 | } | |
115 | ||
116 | break; | |
117 | case lang_input_section_enum: | |
118 | { | |
119 | /* Create a new seclet in the output section with this | |
85c838d6 | 120 | attached */ |
29f33467 SC |
121 | if (statement->input_section.ifile->just_syms_flag == false) |
122 | { | |
123 | asection *i = statement->input_section.section; | |
124 | ||
125 | asection *output_section = i->output_section; | |
126 | ||
127 | bfd_seclet_type *seclet = bfd_new_seclet (output_section->owner, output_section); | |
128 | ||
129 | if (i->flags & SEC_NEVER_LOAD) | |
130 | { | |
131 | /* We've got a never load section inside one which is going | |
132 | to be output, we'll change it into a fill seclet */ | |
133 | seclet->type = bfd_fill_seclet; | |
134 | seclet->u.fill.value = 0; | |
135 | } | |
136 | else | |
137 | { | |
138 | seclet->type = bfd_indirect_seclet; | |
139 | seclet->u.indirect.section = i; | |
140 | seclet->u.indirect.symbols | |
141 | = statement->input_section.ifile->asymbols; | |
142 | } | |
143 | seclet->size = i->_cooked_size; | |
144 | seclet->offset = i->output_offset; | |
145 | seclet->next = 0; | |
146 | } | |
147 | ||
148 | } | |
149 | break; | |
150 | case lang_padding_statement_enum: | |
151 | /* Make a new seclet with the right filler */ | |
152 | { | |
153 | /* Create a new seclet in the output section with this | |
85c838d6 | 154 | attached */ |
2e2bf962 | 155 | |
29f33467 SC |
156 | bfd_seclet_type *seclet = |
157 | bfd_new_seclet (statement->padding_statement.output_section->owner, | |
158 | statement->padding_statement.output_section); | |
159 | ||
160 | seclet->type = bfd_fill_seclet; | |
161 | seclet->size = statement->padding_statement.size; | |
162 | seclet->offset = statement->padding_statement.output_offset; | |
163 | seclet->u.fill.value = statement->padding_statement.fill; | |
164 | seclet->next = 0; | |
165 | } | |
166 | break; | |
0d3e45ea SC |
167 | |
168 | ||
169 | ||
29f33467 SC |
170 | break; |
171 | default: | |
172 | /* All the other ones fall through */ | |
173 | ; | |
2e2bf962 | 174 | |
29f33467 | 175 | } |
2e2bf962 SC |
176 | |
177 | ||
178 | ||
179 | } | |
180 | ||
181 | ||
29f33467 | 182 | void |
8ddef552 DM |
183 | write_relax (output_bfd, data, relocateable) |
184 | bfd * output_bfd; | |
185 | PTR data; | |
186 | boolean relocateable; | |
2e2bf962 | 187 | { |
29f33467 | 188 | /* Tie up all the statements to generate an output bfd structure which |
db4b5ad0 | 189 | bfd can mull over */ |
29f33467 | 190 | lang_for_each_statement (build_it); |
2e2bf962 | 191 | |
db4b5ad0 ILT |
192 | if (bfd_seclet_link (output_bfd, data, relocateable) == false) |
193 | einfo ("%F%P: %B: %E\n", output_bfd); | |
2e2bf962 SC |
194 | } |
195 | ||
2e2bf962 SC |
196 | /* See if we can change the size of this section by shrinking the |
197 | relocations in it. If this happens, then we'll have to renumber the | |
198 | symbols in it, and shift around the data too. | |
199 | */ | |
200 | boolean | |
8ddef552 DM |
201 | relax_section (this_ptr) |
202 | lang_statement_union_type ** this_ptr; | |
2e2bf962 | 203 | { |
2e2bf962 SC |
204 | lang_input_section_type *is = &((*this_ptr)->input_section); |
205 | asection *i = is->section; | |
29f33467 SC |
206 | if (!(i->owner->flags & BFD_IS_RELAXABLE)) |
207 | { | |
208 | if (i->owner != script_file->the_bfd) | |
209 | einfo ("%B: not assembled with -linkrelax\n", i->owner); | |
210 | } | |
211 | ||
212 | return bfd_relax_section (i->owner, i, is->ifile->asymbols); | |
2e2bf962 | 213 | |
29f33467 | 214 | } |