8 Tie together all the interseting blocks
14 #include "../bfd/seclet.h"
15 #include "coff/internal.h"
26 DEFUN(build_it
,(statement
),
27 lang_statement_union_type
*statement
)
29 switch (statement
->header
.type
) {
30 case lang_fill_statement_enum
:
33 bfd_byte play_area
[SHORT_SIZE
];
35 bfd_putshort(output_bfd
, statement
->fill_statement
.fill
, play_area
);
36 /* Write out all entire shorts */
38 i
< statement
->fill_statement
.size
- SHORT_SIZE
+ 1;
41 bfd_set_section_contents(output_bfd
,
42 statement
->fill_statement
.output_section
,
44 statement
->data_statement
.output_offset
+i
,
49 /* Now write any remaining byte */
50 if (i
< statement
->fill_statement
.size
)
52 bfd_set_section_contents(output_bfd
,
53 statement
->fill_statement
.output_section
,
55 statement
->data_statement
.output_offset
+i
,
62 case lang_data_statement_enum
:
67 bfd_vma value
= statement
->data_statement
.value
;
68 bfd_byte play_area
[LONG_SIZE
];
69 unsigned int size
= 0;
70 switch (statement
->data_statement
.type
) {
72 bfd_put_32(output_bfd
, value
, play_area
);
76 bfd_put_16(output_bfd
, value
, play_area
);
80 bfd_put_8(output_bfd
, value
, play_area
);
85 bfd_set_section_contents(output_bfd
,
86 statement
->data_statement
.output_section
,
88 statement
->data_statement
.output_vma
,
96 case lang_input_section_enum
:
98 /* Create a new seclet in the output section with this
101 asection
*i
= statement
->input_section
.section
;
103 asection
*output_section
= i
->output_section
;
105 bfd_seclet_type
*seclet
= bfd_new_seclet(output_section
->owner
,output_section
);
107 seclet
->type
= bfd_indirect_seclet
;
108 seclet
->u
.indirect
.section
= i
;
109 seclet
->u
.indirect
.symbols
= statement
->input_section
.ifile
->asymbols
;
110 seclet
->size
= bfd_get_section_size_before_reloc(i
);
111 seclet
->offset
= i
->output_offset
;
118 /* All the other ones fall through */
129 DEFUN(write_relaxnorel
,(output_bfd
),
132 /* Tie up all the statements to generate an output bfd structure which
136 lang_for_each_statement(build_it
);
138 seclet_dump(output_bfd
);
145 DEFUN(perform_slip
,(s
, slip
, input_section
, value
),
147 unsigned int slip AND
148 asection
*input_section AND
152 /* Find all symbols past this point, and make them know
157 if (p
->section
== input_section
)
159 /* This was pointing into this section, so mangle it */
160 if (p
->value
> value
)
170 DEFUN(movb1
,(input_section
, symbols
, r
, shrink
),
171 asection
*input_section AND
172 asymbol
**symbols AND
178 bfd_vma value
= get_value(r
, input_section
);
183 /* Change the reloc type from 16bit, possible 8 to 8bit
185 r
->howto
= r
->howto
+ 1;
186 /* The place to relc moves back by one */
189 /* This will be two bytes smaller in the long run */
191 perform_slip(symbols
, 2, input_section
, r
->address
- shrink
+1);
199 DEFUN(jmp1
,(input_section
, symbols
, r
, shrink
),
200 asection
*input_section AND
201 asymbol
**symbols AND
207 bfd_vma value
= get_value(r
, 0);
209 bfd_vma dot
= input_section
->output_section
->vma
+
210 input_section
->output_offset
+ r
->address
;
213 /* See if the address we're looking at within 127 bytes of where
214 we are, if so then we can use a small branch rather than the
215 jump we were going to */
217 gap
= value
- (dot
- shrink
);
220 if (-120 < (long)gap
&& (long)gap
< 120 )
223 /* Change the reloc type from 16bit, possible 8 to 8bit
225 r
->howto
= r
->howto
+ 1;
226 /* The place to relc moves back by one */
229 /* This will be two bytes smaller in the long run */
231 perform_slip(symbols
, 2, input_section
, r
->address
-shrink
+1);
239 /* See if we can change the size of this section by shrinking the
240 relocations in it. If this happens, then we'll have to renumber the
241 symbols in it, and shift around the data too.
244 DEFUN(relax_section
,(this_ptr
),
245 lang_statement_union_type
**this_ptr
)
248 lang_input_section_type
*is
= &((*this_ptr
)->input_section
);
249 asection
*i
= is
->section
;
252 /* Get enough memory to hold the stuff */
253 bfd
*input_bfd
= i
->owner
;
254 asection
*input_section
= i
;
258 bfd_size_type reloc_size
= bfd_get_reloc_upper_bound(input_bfd
,
260 arelent
**reloc_vector
= (arelent
**)ldmalloc(reloc_size
);
262 /* Get the relocs and think about them */
263 if (bfd_canonicalize_reloc(input_bfd
,
266 is
->ifile
->asymbols
) )
269 asymbol
**symbols
= is
->ifile
->asymbols
;
270 for (parent
= reloc_vector
; *parent
; parent
++)
272 arelent
*r
= *parent
;
273 switch (r
->howto
->type
) {
281 shrink
= movb1(input_section
, symbols
, r
, shrink
);
286 shrink
= jmp1(input_section
, symbols
, r
, shrink
);
294 input_section
->_cooked_size
-= shrink
;
295 free((char *)reloc_vector
);