1 /* obj-format for ieee-695 records.
2 Copyright 1991, 1992, 1993, 1994, 1997, 2000
3 Free Software Foundation, Inc.
5 This file is part of GAS, the GNU Assembler.
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
22 /* Created by Steve Chamberlain <steve@cygnus.com>. */
24 /* This will hopefully become the port through which bfd and gas talk,
25 for the moment, only ieee is known to work well. */
30 #include "output-file.h"
35 /* How many addresses does the .align take? */
38 relax_align (address
, alignment
)
40 register relax_addressT address
;
42 /* Alignment (binary). */
43 register long alignment
;
46 relax_addressT new_address
;
48 mask
= ~((~0) << alignment
);
49 new_address
= (address
+ mask
) & (~mask
);
50 return (new_address
- address
);
53 /* Calculate the size of the frag chain
54 and create a bfd section to contain all of it. */
57 size_section (abfd
, idx
)
62 unsigned int size
= 0;
63 fragS
*frag
= segment_info
[idx
].frag_root
;
67 if (frag
->fr_address
!= size
)
69 printf (_("Out of step\n"));
70 size
= frag
->fr_address
;
73 switch (frag
->fr_type
)
77 size
+= frag
->fr_offset
* frag
->fr_var
;
84 off
= relax_align (size
, frag
->fr_offset
);
85 if (frag
->fr_subtype
!= 0 && off
> frag
->fr_subtype
)
94 char *name
= segment_info
[idx
].name
;
96 if (name
== (char *) NULL
)
99 segment_info
[idx
].user_stuff
=
100 (char *) (sec
= bfd_make_section (abfd
, name
));
101 /* Make it output through itself. */
102 sec
->output_section
= sec
;
103 sec
->flags
|= SEC_HAS_CONTENTS
;
104 bfd_set_section_size (abfd
, sec
, size
);
108 /* Run through a frag chain and write out the data to go with it. */
111 fill_section (abfd
, idx
)
115 asection
*sec
= segment_info
[idx
].user_stuff
;
119 fragS
*frag
= segment_info
[idx
].frag_root
;
120 unsigned int offset
= 0;
123 unsigned int fill_size
;
125 switch (frag
->fr_type
)
132 bfd_set_section_contents (abfd
,
138 offset
+= frag
->fr_fix
;
139 fill_size
= frag
->fr_var
;
142 unsigned int off
= frag
->fr_fix
;
143 for (count
= frag
->fr_offset
; count
; count
--)
145 bfd_set_section_contents (abfd
, sec
,
148 frag
->fr_address
+ off
,
157 frag
= frag
->fr_next
;
162 /* Count the relocations in a chain. */
165 count_entries_in_chain (idx
)
168 unsigned int nrelocs
;
171 /* Count the relocations. */
172 fixup_ptr
= segment_info
[idx
].fix_root
;
174 while (fixup_ptr
!= (fixS
*) NULL
)
176 fixup_ptr
= fixup_ptr
->fx_next
;
182 /* Output all the relocations for a section. */
188 unsigned int nrelocs
;
189 arelent
**reloc_ptr_vector
;
190 arelent
*reloc_vector
;
192 asection
*section
= (asection
*) (segment_info
[idx
].user_stuff
);
198 nrelocs
= count_entries_in_chain (idx
);
201 (arelent
**) malloc ((nrelocs
+ 1) * sizeof (arelent
*));
202 reloc_vector
= (arelent
*) malloc (nrelocs
* sizeof (arelent
));
203 ptrs
= (asymbol
**) malloc (nrelocs
* sizeof (asymbol
*));
204 from
= segment_info
[idx
].fix_root
;
205 for (i
= 0; i
< nrelocs
; i
++)
207 arelent
*to
= reloc_vector
+ i
;
209 reloc_ptr_vector
[i
] = to
;
210 to
->howto
= (reloc_howto_type
*) (from
->fx_r_type
);
213 /* We can't represent complicated things in a reloc yet. */
214 if (from
->fx_addsy
== 0 || from
->fx_subsy
!= 0)
218 s
= &(from
->fx_addsy
->sy_symbol
.sy
);
219 to
->address
= ((char *) (from
->fx_frag
->fr_address
+
221 - ((char *) (&(from
->fx_frag
->fr_literal
)));
222 to
->addend
= from
->fx_offset
;
223 /* If we know the symbol which we want to relocate to, turn
224 this reloaction into a section relative.
226 If this relocation is pcrelative, and we know the
227 destination, we still want to keep the relocation - since
228 the linker might relax some of the bytes, but it stops
229 being pc relative and turns into an absolute relocation. */
232 if ((s
->flags
& BSF_UNDEFINED
) == 0)
234 to
->section
= s
->section
;
236 /* We can refer directly to the value field here,
237 rather than using S_GET_VALUE, because this is
238 only called after do_symbols, which sets up the
240 to
->addend
+= s
->value
;
243 if (to
->howto
->pcrel_offset
)
244 /* This is a pcrel relocation, the addend should
246 to
->addend
-= to
->address
+ 1;
251 *ptrs
= &(from
->fx_addsy
->sy_symbol
.sy
);
252 to
->sym_ptr_ptr
= ptrs
;
254 if (to
->howto
->pcrel_offset
)
255 /* This is a pcrel relocation, the addend should
257 to
->addend
-= to
->address
- 1;
264 from
= from
->fx_next
;
267 /* Attach to the section. */
268 section
->orelocation
= reloc_ptr_vector
;
269 section
->reloc_count
= nrelocs
;
270 section
->flags
|= SEC_LOAD
;
274 /* Do the symbols. */
280 extern symbolS
*symbol_rootP
;
282 asymbol
**symbol_ptr_vec
;
284 unsigned int count
= 0;
287 for (ptr
= symbol_rootP
;
288 ptr
!= (symbolS
*) NULL
;
291 if (SEG_NORMAL (ptr
->sy_symbol
.seg
))
293 ptr
->sy_symbol
.sy
.section
=
294 (asection
*) (segment_info
[ptr
->sy_symbol
.seg
].user_stuff
);
295 S_SET_VALUE (ptr
, S_GET_VALUE (ptr
));
296 if (ptr
->sy_symbol
.sy
.flags
== 0)
297 ptr
->sy_symbol
.sy
.flags
= BSF_LOCAL
;
301 switch (ptr
->sy_symbol
.seg
)
304 ptr
->sy_symbol
.sy
.flags
|= BSF_ABSOLUTE
;
305 ptr
->sy_symbol
.sy
.section
= 0;
308 ptr
->sy_symbol
.sy
.flags
= BSF_UNDEFINED
;
309 ptr
->sy_symbol
.sy
.section
= 0;
315 ptr
->sy_symbol
.sy
.value
= S_GET_VALUE (ptr
);
318 symbol_ptr_vec
= (asymbol
**) malloc ((count
+ 1) * sizeof (asymbol
*));
321 for (ptr
= symbol_rootP
;
322 ptr
!= (symbolS
*) NULL
;
325 symbol_ptr_vec
[index
] = &(ptr
->sy_symbol
.sy
);
328 symbol_ptr_vec
[index
] = 0;
329 abfd
->outsymbols
= symbol_ptr_vec
;
330 abfd
->symcount
= count
;
333 /* The generic as->bfd converter. Other backends may have special case
341 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
342 size_section (abfd
, i
);
344 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
345 fill_section (abfd
, i
);
349 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
357 x
->sy_symbol
.seg
= y
;
363 if (SEG_NORMAL (x
->sy_symbol
.seg
))
367 switch (x
->sy_symbol
.seg
)
389 return x
->sy_symbol
.seg
;
395 x
->sy_symbol
.sy
.flags
|= BSF_GLOBAL
| BSF_EXPORT
;
402 x
->sy_symbol
.sy
.name
= y
;
424 obj_read_begin_hook ()
429 obj_ieee_section (ignore
)
432 extern char *input_line_pointer
;
433 extern char is_end_of_line
[];
434 char *p
= input_line_pointer
;
438 /* Look up the name, if it doesn't exist, make it. */
439 while (*p
&& *p
!= ' ' && *p
!= ',' && !is_end_of_line
[*p
])
443 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
445 if (segment_info
[i
].hadone
)
447 if (strncmp (segment_info
[i
].name
, s
, p
- s
) == 0)
453 if (i
== SEG_UNKNOWN
)
455 as_bad (_("too many sections"));
459 segment_info
[i
].hadone
= 1;
460 segment_info
[i
].name
= malloc (p
- s
+ 1);
461 memcpy (segment_info
[i
].name
, s
, p
- s
);
462 segment_info
[i
].name
[p
- s
] = 0;
465 while (!is_end_of_line
[*p
])
467 input_line_pointer
= p
;
470 const pseudo_typeS obj_pseudo_table
[] =
472 {"section", obj_ieee_section
, 0},
473 {"data.b" , cons
, 1},
474 {"data.w" , cons
, 2},
475 {"data.l" , cons
, 4},
476 {"export" , s_globl
, 0},
477 {"option" , s_ignore
, 0},
478 {"end" , s_ignore
, 0},
479 {"import" , s_ignore
, 0},
480 {"sdata" , stringer
, 0},
485 obj_symbol_new_hook (symbolP
)
488 symbolP
->sy_symbol
.sy
.the_bfd
= abfd
;
493 #ifndef SUB_SEGMENT_ALIGN
495 /* The last subsegment gets an alignment corresponding to the alignment
496 of the section. This allows proper nop-filling at the end of
497 code-bearing sections. */
498 #define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) \
499 (!(FRCHAIN)->frch_next || (FRCHAIN)->frch_next->frch_seg != (SEG) \
500 ? get_recorded_alignment (SEG) : 0)
502 #define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 2
510 struct frchain
*frchain_ptr
;
511 struct frag
*frag_ptr
;
513 abfd
= bfd_openw (out_file_name
, "ieee");
517 as_perror (_("FATAL: Can't create %s"), out_file_name
);
520 bfd_set_format (abfd
, bfd_object
);
521 bfd_set_arch_mach (abfd
, bfd_arch_h8300
, 0);
526 /* Run through all the sub-segments and align them up. Also
527 close any open frags. We tack a .fill onto the end of the
528 frag chain so that any .align's size can be worked by looking
530 for (frchain_ptr
= frchain_root
;
531 frchain_ptr
!= (struct frchain
*) NULL
;
532 frchain_ptr
= frchain_ptr
->frch_next
)
536 subseg_set (frchain_ptr
->frch_seg
, frchain_ptr
->frch_subseg
);
538 alignment
= SUB_SEGMENT_ALIGN (now_seg
, frchain_ptr
)
541 md_do_align (alignment
, (char *) NULL
, 0, 0, alignment_done
);
543 if (subseg_text_p (now_seg
))
544 frag_align_code (alignment
, 0);
546 frag_align (alignment
, 0, 0);
552 frag_wane (frag_now
);
553 frag_now
->fr_fix
= 0;
554 know (frag_now
->fr_next
== NULL
);
557 /* Now build one big frag chain for each segment, linked through
559 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
561 fragS
**prev_frag_ptr_ptr
;
562 struct frchain
*next_frchain_ptr
;
565 struct frag
**head_ptr
= segment_info
[i
].frag_root
;
568 segment_info
[i
].frag_root
= segment_info
[i
].frchainP
->frch_root
;
570 /* I'm not sure what this is for. */
571 for (frchain_ptr
= segment_info
[i
].frchainP
->frch_root
;
572 frchain_ptr
!= (struct frchain
*) NULL
;
573 frchain_ptr
= frchain_ptr
->frch_next
)
575 *head_ptr
= frchain_ptr
;
576 head_ptr
= &frchain_ptr
->next
;
581 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
582 relax_segment (segment_info
[i
].frag_root
, i
);
584 /* Relaxation has completed. Freeze all syms. */
587 /* Now the addresses of the frags are correct within the segment. */
589 bfd_as_write_hook ();
595 H_SET_TEXT_SIZE (a
, b
)
615 H_SET_RELOCATION_SIZE ()
620 H_SET_MAGIC_NUMBER ()
630 H_GET_TEXT_RELOCATION_SIZE ()