1 /* obj-format for ieee-695 records.
2 Copyright (C) 1991, 1992 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
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
24 steve chamberlain steve@cygnus.com
28 this will hopefully become the port through which bfd and gas talk,
29 for the moment, only ieee is known to work well.
35 #include "output-file.h"
40 /* How many addresses does the .align take? */
42 relax_align (address
, alignment
)
43 register relax_addressT address
; /* Address now. */
44 register long alignment
; /* Alignment (binary). */
47 relax_addressT new_address
;
49 mask
= ~((~0) << alignment
);
50 new_address
= (address
+ mask
) & (~mask
);
51 return (new_address
- address
);
54 /* calculate the size of the frag chain and create a bfd section
55 to contain all of it */
57 DEFUN (size_section
, (abfd
, idx
),
62 unsigned int size
= 0;
63 fragS
*frag
= segment_info
[idx
].frag_root
;
66 if (frag
->fr_address
!= size
)
68 printf ("Out of step\n");
69 size
= frag
->fr_address
;
72 switch (frag
->fr_type
)
76 size
+= frag
->fr_offset
* frag
->fr_var
;
79 size
+= relax_align (size
, frag
->fr_offset
);
85 char *name
= segment_info
[idx
].name
;
86 if (name
== (char *) NULL
)
90 segment_info
[idx
].user_stuff
= (char *) (sec
= bfd_make_section (abfd
, name
));
91 /* Make it output through itself */
92 sec
->output_section
= sec
;
93 sec
->flags
|= SEC_HAS_CONTENTS
;
94 bfd_set_section_size (abfd
, sec
, size
);
98 /* run through a frag chain and write out the data to go with it */
100 DEFUN (fill_section
, (abfd
, idx
),
104 asection
*sec
= segment_info
[idx
].user_stuff
;
107 fragS
*frag
= segment_info
[idx
].frag_root
;
108 unsigned int offset
= 0;
111 unsigned int fill_size
;
113 switch (frag
->fr_type
)
120 bfd_set_section_contents (abfd
,
126 offset
+= frag
->fr_fix
;
127 fill_size
= frag
->fr_var
;
130 unsigned int off
= frag
->fr_fix
;
131 for (count
= frag
->fr_offset
; count
; count
--)
133 bfd_set_section_contents (abfd
, sec
,
136 frag
->fr_address
+ off
,
145 frag
= frag
->fr_next
;
150 /* Count the relocations in a chain */
153 DEFUN (count_entries_in_chain
, (idx
),
156 unsigned int nrelocs
;
159 /* Count the relocations */
160 fixup_ptr
= segment_info
[idx
].fix_root
;
162 while (fixup_ptr
!= (fixS
*) NULL
)
164 fixup_ptr
= fixup_ptr
->fx_next
;
170 /* output all the relocations for a section */
172 DEFUN (do_relocs_for
, (idx
),
175 unsigned int nrelocs
;
176 arelent
**reloc_ptr_vector
;
177 arelent
*reloc_vector
;
179 asection
*section
= (asection
*) (segment_info
[idx
].user_stuff
);
184 nrelocs
= count_entries_in_chain (idx
);
186 reloc_ptr_vector
= (arelent
**) malloc ((nrelocs
+ 1) * sizeof (arelent
*));
187 reloc_vector
= (arelent
*) malloc (nrelocs
* sizeof (arelent
));
188 ptrs
= (asymbol
**) malloc (nrelocs
* sizeof (asymbol
*));
189 from
= segment_info
[idx
].fix_root
;
190 for (i
= 0; i
< nrelocs
; i
++)
192 arelent
*to
= reloc_vector
+ i
;
194 reloc_ptr_vector
[i
] = to
;
195 to
->howto
= (reloc_howto_type
*) (from
->fx_r_type
);
197 /* We can't represent complicated things in a reloc yet */
198 /* if (from->fx_addsy == 0 ||
199 from->fx_subsy != 0) abort();
201 s
= &(from
->fx_addsy
->sy_symbol
.sy
);
202 to
->address
= ((char *) (from
->fx_frag
->fr_address
+
204 - ((char *) (&(from
->fx_frag
->fr_literal
)));
205 to
->addend
= from
->fx_offset
;
206 /* If we know the symbol which we want to relocate to, turn this
207 reloaction into a section relative.
209 If this relocation is pcrelative, and we know the
210 destination, we still want to keep the relocation - since
211 the linker might relax some of the bytes, but it stops
212 being pc relative and turns into an absolute relocation.
217 if ((s
->flags
& BSF_UNDEFINED
) == 0)
219 to
->section
= s
->section
;
220 to
->addend
+= s
->value
;
222 if (to
->howto
->pcrel_offset
)
224 /* This is a pcrel relocation, the addend should be adjusted */
225 to
->addend
-= to
->address
+ 1;
231 *ptrs
= &(from
->fx_addsy
->sy_symbol
.sy
);
232 to
->sym_ptr_ptr
= ptrs
;
234 if (to
->howto
->pcrel_offset
)
236 /* This is a pcrel relocation, the addend should be adjusted */
237 to
->addend
-= to
->address
- 1;
248 from
= from
->fx_next
;
251 /* attatch to the section */
252 section
->orelocation
= reloc_ptr_vector
;
253 section
->reloc_count
= nrelocs
;
254 section
->flags
|= SEC_LOAD
;
258 /* do the symbols.. */
260 DEFUN (do_symbols
, (abfd
),
263 extern symbolS
*symbol_rootP
;
265 asymbol
**symbol_ptr_vec
;
267 unsigned int count
= 0;
271 for (ptr
= symbol_rootP
;
272 ptr
!= (symbolS
*) NULL
;
275 if (SEG_NORMAL (ptr
->sy_symbol
.seg
))
277 ptr
->sy_symbol
.sy
.section
=
278 (asection
*) (segment_info
[ptr
->sy_symbol
.seg
].user_stuff
);
279 ptr
->sy_symbol
.sy
.value
+= ptr
->sy_frag
->fr_address
;
280 if (ptr
->sy_symbol
.sy
.flags
== 0)
282 ptr
->sy_symbol
.sy
.flags
= BSF_LOCAL
;
287 switch (ptr
->sy_symbol
.seg
)
290 ptr
->sy_symbol
.sy
.flags
|= BSF_ABSOLUTE
;
291 ptr
->sy_symbol
.sy
.section
= 0;
294 ptr
->sy_symbol
.sy
.flags
= BSF_UNDEFINED
;
295 ptr
->sy_symbol
.sy
.section
= 0;
303 symbol_ptr_vec
= (asymbol
**) malloc ((count
+ 1) * sizeof (asymbol
*));
306 for (ptr
= symbol_rootP
;
307 ptr
!= (symbolS
*) NULL
;
310 symbol_ptr_vec
[index
] = &(ptr
->sy_symbol
.sy
);
313 symbol_ptr_vec
[index
] = 0;
314 abfd
->outsymbols
= symbol_ptr_vec
;
315 abfd
->symcount
= count
;
318 /* The generic as->bfd converter. Other backends may have special case
322 DEFUN_VOID (bfd_as_write_hook
)
326 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
328 size_section (abfd
, i
);
332 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
333 fill_section (abfd
, i
);
337 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
347 return x
->sy_symbol
.sy
.value
;
354 x
->sy_symbol
.seg
= y
;
360 if (SEG_NORMAL (x
->sy_symbol
.seg
))
364 switch (x
->sy_symbol
.seg
)
386 return x
->sy_symbol
.seg
;
392 x
->sy_symbol
.sy
.flags
|= BSF_GLOBAL
| BSF_EXPORT
;
399 x
->sy_symbol
.sy
.name
= y
;
406 s
->sy_symbol
.sy
.value
= v
;
426 obj_read_begin_hook ()
431 obj_ieee_section (ignore
)
434 extern char *input_line_pointer
;
435 extern char is_end_of_line
[];
436 char *p
= input_line_pointer
;
439 /* Look up the name, if it doesn't exist, make it */
440 while (*p
&& *p
!= ' ' && *p
!= ',' && !is_end_of_line
[*p
])
444 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
446 if (segment_info
[i
].hadone
)
448 if (strncmp (segment_info
[i
].name
, s
, p
- s
) == 0)
457 if (i
== SEG_UNKNOWN
)
459 as_bad ("too many sections");
463 segment_info
[i
].hadone
= 1;
464 segment_info
[i
].name
= malloc (p
- s
+ 1);
465 memcpy (segment_info
[i
].name
, s
, p
- s
);
466 segment_info
[i
].name
[p
- s
] = 0;
469 while (!is_end_of_line
[*p
])
471 input_line_pointer
= p
;
483 * We read 0 or more ',' seperated, double-quoted strings.
485 * Caller should have checked need_pass_2 is FALSE because we don't check it.
490 const pseudo_typeS obj_pseudo_table
[] =
492 {"section", obj_ieee_section
, 0},
496 {"export", s_globl
, 0},
497 {"option", s_ignore
, 0},
498 {"end", s_ignore
, 0},
499 {"import", s_ignore
, 0},
500 {"sdata", stringer
, 0},
508 obj_symbol_new_hook (symbolP
)
511 symbolP
->sy_symbol
.sy
.the_bfd
= abfd
;
520 DEFUN_VOID (write_object_file
)
523 struct frchain
*frchain_ptr
;
524 struct frag
*frag_ptr
;
526 abfd
= bfd_openw (out_file_name
, "ieee");
530 as_perror ("FATAL: Can't create %s", out_file_name
);
533 bfd_set_format (abfd
, bfd_object
);
534 bfd_set_arch_mach (abfd
, bfd_arch_h8300
, 0);
538 for (frchain_ptr
= frchain_root
;
539 frchain_ptr
!= (struct frchain
*) NULL
;
540 frchain_ptr
= frchain_ptr
->frch_next
)
542 /* Run through all the sub-segments and align them up. Also close any
543 open frags. We tack a .fill onto the end of the frag chain so
544 that any .align's size can be worked by looking at the next
547 subseg_new (frchain_ptr
->frch_seg
, frchain_ptr
->frch_subseg
);
548 #ifndef SUB_SEGMENT_ALIGN
549 #define SUB_SEGMENT_ALIGN(SEG) 2
551 frag_align (SUB_SEGMENT_ALIGN (now_seg
), 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
++)
562 fragS
**prev_frag_ptr_ptr
;
563 struct frchain
*next_frchain_ptr
;
565 /* struct frag **head_ptr = segment_info[i].frag_root;*/
567 segment_info
[i
].frag_root
= segment_info
[i
].frchainP
->frch_root
;
569 /* Im not sure what this is for */
570 for (frchain_ptr
= segment_info
[i
].frchainP
->frch_root
;
571 frchain_ptr
!= (struct frchain
*) NULL
;
572 frchain_ptr
= frchain_ptr
->frch_next
)
574 *head_ptr
= frchain_ptr
;
575 head_ptr
= &frchain_ptr
->next
;
582 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
584 relax_segment (segment_info
[i
].frag_root
, i
);
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 ()
635 /* end of obj-ieee.c */