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