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