1 /* obj-format for ieee-695 records.
2 Copyright (C) 1991, 92, 93, 94, 95, 1997, 1998 Free Software Foundation, Inc.
4 This file is part of GAS, the GNU Assembler.
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to the Free
18 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
25 steve chamberlain steve@cygnus.com
29 this will hopefully become the port through which bfd and gas talk,
30 for the moment, only ieee is known to work well.
36 #include "output-file.h"
41 /* How many addresses does the .align take? */
43 relax_align (address
, alignment
)
44 register relax_addressT address
; /* Address now. */
45 register long alignment
; /* Alignment (binary). */
48 relax_addressT new_address
;
50 mask
= ~((~0) << alignment
);
51 new_address
= (address
+ mask
) & (~mask
);
52 return (new_address
- address
);
55 /* calculate the size of the frag chain and create a bfd section
56 to contain all of it */
58 size_section (abfd
, idx
)
63 unsigned int size
= 0;
64 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
;
95 if (name
== (char *) NULL
)
99 segment_info
[idx
].user_stuff
= (char *) (sec
= bfd_make_section (abfd
, name
));
100 /* Make it output through itself */
101 sec
->output_section
= sec
;
102 sec
->flags
|= SEC_HAS_CONTENTS
;
103 bfd_set_section_size (abfd
, sec
, size
);
107 /* run through a frag chain and write out the data to go with it */
109 fill_section (abfd
, idx
)
113 asection
*sec
= segment_info
[idx
].user_stuff
;
116 fragS
*frag
= segment_info
[idx
].frag_root
;
117 unsigned int offset
= 0;
120 unsigned int fill_size
;
122 switch (frag
->fr_type
)
129 bfd_set_section_contents (abfd
,
135 offset
+= frag
->fr_fix
;
136 fill_size
= frag
->fr_var
;
139 unsigned int off
= frag
->fr_fix
;
140 for (count
= frag
->fr_offset
; count
; count
--)
142 bfd_set_section_contents (abfd
, sec
,
145 frag
->fr_address
+ off
,
154 frag
= frag
->fr_next
;
159 /* Count the relocations in a chain */
162 count_entries_in_chain (idx
)
165 unsigned int nrelocs
;
168 /* Count the relocations */
169 fixup_ptr
= segment_info
[idx
].fix_root
;
171 while (fixup_ptr
!= (fixS
*) NULL
)
173 fixup_ptr
= fixup_ptr
->fx_next
;
179 /* output all the relocations for a section */
184 unsigned int nrelocs
;
185 arelent
**reloc_ptr_vector
;
186 arelent
*reloc_vector
;
188 asection
*section
= (asection
*) (segment_info
[idx
].user_stuff
);
193 nrelocs
= count_entries_in_chain (idx
);
195 reloc_ptr_vector
= (arelent
**) malloc ((nrelocs
+ 1) * sizeof (arelent
*));
196 reloc_vector
= (arelent
*) malloc (nrelocs
* sizeof (arelent
));
197 ptrs
= (asymbol
**) malloc (nrelocs
* sizeof (asymbol
*));
198 from
= segment_info
[idx
].fix_root
;
199 for (i
= 0; i
< nrelocs
; i
++)
201 arelent
*to
= reloc_vector
+ i
;
203 reloc_ptr_vector
[i
] = to
;
204 to
->howto
= (reloc_howto_type
*) (from
->fx_r_type
);
206 #if 0 /* We can't represent complicated things in a reloc yet */
207 if (from
->fx_addsy
== 0 || from
->fx_subsy
!= 0) abort();
210 s
= &(from
->fx_addsy
->sy_symbol
.sy
);
211 to
->address
= ((char *) (from
->fx_frag
->fr_address
+
213 - ((char *) (&(from
->fx_frag
->fr_literal
)));
214 to
->addend
= from
->fx_offset
;
215 /* If we know the symbol which we want to relocate to, turn
216 this reloaction into a section relative.
218 If this relocation is pcrelative, and we know the
219 destination, we still want to keep the relocation - since
220 the linker might relax some of the bytes, but it stops
221 being pc relative and turns into an absolute relocation. */
224 if ((s
->flags
& BSF_UNDEFINED
) == 0)
226 to
->section
= s
->section
;
228 /* We can refer directly to the value field here,
229 rather than using S_GET_VALUE, because this is
230 only called after do_symbols, which sets up the
232 to
->addend
+= s
->value
;
235 if (to
->howto
->pcrel_offset
)
237 /* This is a pcrel relocation, the addend should be adjusted */
238 to
->addend
-= to
->address
+ 1;
244 *ptrs
= &(from
->fx_addsy
->sy_symbol
.sy
);
245 to
->sym_ptr_ptr
= ptrs
;
247 if (to
->howto
->pcrel_offset
)
249 /* This is a pcrel relocation, the addend should be adjusted */
250 to
->addend
-= to
->address
- 1;
261 from
= from
->fx_next
;
264 /* attatch to the section */
265 section
->orelocation
= reloc_ptr_vector
;
266 section
->reloc_count
= nrelocs
;
267 section
->flags
|= SEC_LOAD
;
271 /* do the symbols.. */
276 extern symbolS
*symbol_rootP
;
278 asymbol
**symbol_ptr_vec
;
280 unsigned int count
= 0;
284 for (ptr
= symbol_rootP
;
285 ptr
!= (symbolS
*) NULL
;
288 if (SEG_NORMAL (ptr
->sy_symbol
.seg
))
290 ptr
->sy_symbol
.sy
.section
=
291 (asection
*) (segment_info
[ptr
->sy_symbol
.seg
].user_stuff
);
292 S_SET_VALUE (ptr
, S_GET_VALUE (ptr
) + ptr
->sy_frag
->fr_address
);
293 if (ptr
->sy_symbol
.sy
.flags
== 0)
295 ptr
->sy_symbol
.sy
.flags
= BSF_LOCAL
;
300 switch (ptr
->sy_symbol
.seg
)
303 ptr
->sy_symbol
.sy
.flags
|= BSF_ABSOLUTE
;
304 ptr
->sy_symbol
.sy
.section
= 0;
307 ptr
->sy_symbol
.sy
.flags
= BSF_UNDEFINED
;
308 ptr
->sy_symbol
.sy
.section
= 0;
314 ptr
->sy_symbol
.sy
.value
= S_GET_VALUE (ptr
);
317 symbol_ptr_vec
= (asymbol
**) malloc ((count
+ 1) * sizeof (asymbol
*));
320 for (ptr
= symbol_rootP
;
321 ptr
!= (symbolS
*) NULL
;
324 symbol_ptr_vec
[index
] = &(ptr
->sy_symbol
.sy
);
327 symbol_ptr_vec
[index
] = 0;
328 abfd
->outsymbols
= symbol_ptr_vec
;
329 abfd
->symcount
= count
;
332 /* The generic as->bfd converter. Other backends may have special case
340 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
342 size_section (abfd
, i
);
346 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
347 fill_section (abfd
, i
);
351 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
360 x
->sy_symbol
.seg
= y
;
366 if (SEG_NORMAL (x
->sy_symbol
.seg
))
370 switch (x
->sy_symbol
.seg
)
392 return x
->sy_symbol
.seg
;
398 x
->sy_symbol
.sy
.flags
|= BSF_GLOBAL
| BSF_EXPORT
;
405 x
->sy_symbol
.sy
.name
= y
;
427 obj_read_begin_hook ()
432 obj_ieee_section (ignore
)
435 extern char *input_line_pointer
;
436 extern char is_end_of_line
[];
437 char *p
= input_line_pointer
;
440 /* Look up the name, if it doesn't exist, make it */
441 while (*p
&& *p
!= ' ' && *p
!= ',' && !is_end_of_line
[*p
])
445 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
447 if (segment_info
[i
].hadone
)
449 if (strncmp (segment_info
[i
].name
, s
, p
- s
) == 0)
458 if (i
== SEG_UNKNOWN
)
460 as_bad (_("too many sections"));
464 segment_info
[i
].hadone
= 1;
465 segment_info
[i
].name
= malloc (p
- s
+ 1);
466 memcpy (segment_info
[i
].name
, s
, p
- s
);
467 segment_info
[i
].name
[p
- s
] = 0;
470 while (!is_end_of_line
[*p
])
472 input_line_pointer
= p
;
482 const pseudo_typeS obj_pseudo_table
[] =
484 {"section", obj_ieee_section
, 0},
488 {"export", s_globl
, 0},
489 {"option", s_ignore
, 0},
490 {"end", s_ignore
, 0},
491 {"import", s_ignore
, 0},
492 {"sdata", stringer
, 0},
500 obj_symbol_new_hook (symbolP
)
503 symbolP
->sy_symbol
.sy
.the_bfd
= abfd
;
515 struct frchain
*frchain_ptr
;
516 struct frag
*frag_ptr
;
518 abfd
= bfd_openw (out_file_name
, "ieee");
522 as_perror (_("FATAL: Can't create %s"), out_file_name
);
525 bfd_set_format (abfd
, bfd_object
);
526 bfd_set_arch_mach (abfd
, bfd_arch_h8300
, 0);
530 for (frchain_ptr
= frchain_root
;
531 frchain_ptr
!= (struct frchain
*) NULL
;
532 frchain_ptr
= frchain_ptr
->frch_next
)
534 /* Run through all the sub-segments and align them up. Also close any
535 open frags. We tack a .fill onto the end of the frag chain so
536 that any .align's size can be worked by looking at the next
539 subseg_set (frchain_ptr
->frch_seg
, frchain_ptr
->frch_subseg
);
540 #ifndef SUB_SEGMENT_ALIGN
541 #define SUB_SEGMENT_ALIGN(SEG) 2
543 frag_align (SUB_SEGMENT_ALIGN (now_seg
), 0, 0);
544 frag_wane (frag_now
);
545 frag_now
->fr_fix
= 0;
546 know (frag_now
->fr_next
== NULL
);
549 /* Now build one big frag chain for each segment, linked through
551 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
554 fragS
**prev_frag_ptr_ptr
;
555 struct frchain
*next_frchain_ptr
;
557 /* struct frag **head_ptr = segment_info[i].frag_root;*/
559 segment_info
[i
].frag_root
= segment_info
[i
].frchainP
->frch_root
;
561 /* Im not sure what this is for */
562 for (frchain_ptr
= segment_info
[i
].frchainP
->frch_root
;
563 frchain_ptr
!= (struct frchain
*) NULL
;
564 frchain_ptr
= frchain_ptr
->frch_next
)
566 *head_ptr
= frchain_ptr
;
567 head_ptr
= &frchain_ptr
->next
;
574 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
576 relax_segment (segment_info
[i
].frag_root
, i
);
579 /* Now the addresses of the frags are correct within the segment */
581 bfd_as_write_hook ();
587 H_SET_TEXT_SIZE (a
, b
)
607 H_SET_RELOCATION_SIZE ()
612 H_SET_MAGIC_NUMBER ()
622 H_GET_TEXT_RELOCATION_SIZE ()
627 /* end of obj-ieee.c */