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