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
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 DEFUN (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 DEFUN (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 DEFUN (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 */
181 DEFUN (do_relocs_for, (idx),
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.. */
273 DEFUN (do_symbols, (abfd),
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
336 DEFUN_VOID (bfd_as_write_hook)
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;
512 DEFUN_VOID (write_object_file)
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 */