1 /* obj-format for ieee-695 records.
2    Copyright 1991, 1992, 1993, 1994, 1997, 2000
3    Free Software Foundation, Inc.
4 
5    This file is part of GAS, the GNU Assembler.
6 
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)
10    any later version.
11 
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.
16 
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
20    02111-1307, USA.  */
21 
22 /* Created by Steve Chamberlain <steve@cygnus.com>.  */
23 
24 /* This will hopefully become the port through which bfd and gas talk,
25    for the moment, only ieee is known to work well.  */
26 
27 #include "bfd.h"
28 #include "as.h"
29 #include "subsegs.h"
30 #include "output-file.h"
31 #include "frags.h"
32 
33 bfd *abfd;
34 
35 /* How many addresses does the .align take?  */
36 
37 static relax_addressT
38 relax_align (address, alignment)
39      /* Address now.  */
40      register relax_addressT address;
41 
42      /* Alignment (binary).  */
43      register long alignment;
44 {
45   relax_addressT mask;
46   relax_addressT new_address;
47 
48   mask = ~((~0) << alignment);
49   new_address = (address + mask) & (~mask);
50   return (new_address - address);
51 }
52 
53 /* Calculate the size of the frag chain
54    and create a bfd section to contain all of it.  */
55 
56 static void
57 size_section (abfd, idx)
58      bfd *abfd;
59      unsigned int idx;
60 {
61   asection *sec;
62   unsigned int size = 0;
63   fragS *frag = segment_info[idx].frag_root;
64 
65   while (frag)
66     {
67       if (frag->fr_address != size)
68 	{
69 	  printf (_("Out of step\n"));
70 	  size = frag->fr_address;
71 	}
72       size += frag->fr_fix;
73       switch (frag->fr_type)
74 	{
75 	case rs_fill:
76 	case rs_org:
77 	  size += frag->fr_offset * frag->fr_var;
78 	  break;
79 	case rs_align:
80 	case rs_align_code:
81 	  {
82 	    addressT off;
83 
84 	    off = relax_align (size, frag->fr_offset);
85 	    if (frag->fr_subtype != 0 && off > frag->fr_subtype)
86 	      off = 0;
87 	    size += off;
88 	  }
89 	}
90       frag = frag->fr_next;
91     }
92   if (size)
93     {
94       char *name = segment_info[idx].name;
95 
96       if (name == (char *) NULL)
97 	name = ".data";
98 
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);
105     }
106 }
107 
108 /* Run through a frag chain and write out the data to go with it.  */
109 
110 static void
111 fill_section (abfd, idx)
112      bfd *abfd;
113      unsigned int idx;
114 {
115   asection *sec = segment_info[idx].user_stuff;
116 
117   if (sec)
118     {
119       fragS *frag = segment_info[idx].frag_root;
120       unsigned int offset = 0;
121       while (frag)
122 	{
123 	  unsigned int fill_size;
124 	  unsigned int count;
125 	  switch (frag->fr_type)
126 	    {
127 	    case rs_fill:
128 	    case rs_align:
129 	    case rs_org:
130 	      if (frag->fr_fix)
131 		{
132 		  bfd_set_section_contents (abfd,
133 					    sec,
134 					    frag->fr_literal,
135 					    frag->fr_address,
136 					    frag->fr_fix);
137 		}
138 	      offset += frag->fr_fix;
139 	      fill_size = frag->fr_var;
140 	      if (fill_size)
141 		{
142 		  unsigned int off = frag->fr_fix;
143 		  for (count = frag->fr_offset; count; count--)
144 		    {
145 		      bfd_set_section_contents (abfd, sec,
146 						frag->fr_literal +
147 						frag->fr_fix,
148 						frag->fr_address + off,
149 						fill_size);
150 		      off += fill_size;
151 		    }
152 		}
153 	      break;
154 	    default:
155 	      abort ();
156 	    }
157 	  frag = frag->fr_next;
158 	}
159     }
160 }
161 
162 /* Count the relocations in a chain.  */
163 
164 static unsigned int
165 count_entries_in_chain (idx)
166      unsigned int idx;
167 {
168   unsigned int nrelocs;
169   fixS *fixup_ptr;
170 
171   /* Count the relocations.  */
172   fixup_ptr = segment_info[idx].fix_root;
173   nrelocs = 0;
174   while (fixup_ptr != (fixS *) NULL)
175     {
176       fixup_ptr = fixup_ptr->fx_next;
177       nrelocs++;
178     }
179   return nrelocs;
180 }
181 
182 /* Output all the relocations for a section.  */
183 
184 void
185 do_relocs_for (idx)
186      unsigned int idx;
187 {
188   unsigned int nrelocs;
189   arelent **reloc_ptr_vector;
190   arelent *reloc_vector;
191   asymbol **ptrs;
192   asection *section = (asection *) (segment_info[idx].user_stuff);
193   unsigned int i;
194   fixS *from;
195 
196   if (section)
197     {
198       nrelocs = count_entries_in_chain (idx);
199 
200       reloc_ptr_vector =
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++)
206 	{
207 	  arelent *to = reloc_vector + i;
208 	  asymbol *s;
209 	  reloc_ptr_vector[i] = to;
210 	  to->howto = (reloc_howto_type *) (from->fx_r_type);
211 
212 #if 0
213 	  /* We can't represent complicated things in a reloc yet.  */
214 	  if (from->fx_addsy == 0 || from->fx_subsy != 0)
215 	    abort ();
216 #endif
217 
218 	  s = &(from->fx_addsy->sy_symbol.sy);
219 	  to->address = ((char *) (from->fx_frag->fr_address +
220 				   from->fx_where))
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.
225 
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.  */
230 	  if (s)
231 	    {
232 	      if ((s->flags & BSF_UNDEFINED) == 0)
233 		{
234 		  to->section = s->section;
235 
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
239 		     value field.  */
240 		  to->addend += s->value;
241 
242 		  to->sym_ptr_ptr = 0;
243 		  if (to->howto->pcrel_offset)
244 		    /* This is a pcrel relocation, the addend should
245 		       be adjusted.  */
246 		    to->addend -= to->address + 1;
247 		}
248 	      else
249 		{
250 		  to->section = 0;
251 		  *ptrs = &(from->fx_addsy->sy_symbol.sy);
252 		  to->sym_ptr_ptr = ptrs;
253 
254 		  if (to->howto->pcrel_offset)
255 		    /* This is a pcrel relocation, the addend should
256 		       be adjusted.  */
257 		    to->addend -= to->address - 1;
258 		}
259 	    }
260 	  else
261 	    to->section = 0;
262 
263 	  ptrs++;
264 	  from = from->fx_next;
265 	}
266 
267       /* Attach to the section.  */
268       section->orelocation = reloc_ptr_vector;
269       section->reloc_count = nrelocs;
270       section->flags |= SEC_LOAD;
271     }
272 }
273 
274 /* Do the symbols.  */
275 
276 static void
277 do_symbols (abfd)
278      bfd *abfd;
279 {
280   extern symbolS *symbol_rootP;
281   symbolS *ptr;
282   asymbol **symbol_ptr_vec;
283   asymbol *symbol_vec;
284   unsigned int count = 0;
285   unsigned int index;
286 
287   for (ptr = symbol_rootP;
288        ptr != (symbolS *) NULL;
289        ptr = ptr->sy_next)
290     {
291       if (SEG_NORMAL (ptr->sy_symbol.seg))
292 	{
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;
298 	}
299       else
300 	{
301 	  switch (ptr->sy_symbol.seg)
302 	    {
303 	    case SEG_ABSOLUTE:
304 	      ptr->sy_symbol.sy.flags |= BSF_ABSOLUTE;
305 	      ptr->sy_symbol.sy.section = 0;
306 	      break;
307 	    case SEG_UNKNOWN:
308 	      ptr->sy_symbol.sy.flags = BSF_UNDEFINED;
309 	      ptr->sy_symbol.sy.section = 0;
310 	      break;
311 	    default:
312 	      abort ();
313 	    }
314 	}
315       ptr->sy_symbol.sy.value = S_GET_VALUE (ptr);
316       count++;
317     }
318   symbol_ptr_vec = (asymbol **) malloc ((count + 1) * sizeof (asymbol *));
319 
320   index = 0;
321   for (ptr = symbol_rootP;
322        ptr != (symbolS *) NULL;
323        ptr = ptr->sy_next)
324     {
325       symbol_ptr_vec[index] = &(ptr->sy_symbol.sy);
326       index++;
327     }
328   symbol_ptr_vec[index] = 0;
329   abfd->outsymbols = symbol_ptr_vec;
330   abfd->symcount = count;
331 }
332 
333 /* The generic as->bfd converter. Other backends may have special case
334    code.  */
335 
336 void
337 bfd_as_write_hook ()
338 {
339   int i;
340 
341   for (i = SEG_E0; i < SEG_UNKNOWN; i++)
342     size_section (abfd, i);
343 
344   for (i = SEG_E0; i < SEG_UNKNOWN; i++)
345     fill_section (abfd, i);
346 
347   do_symbols (abfd);
348 
349   for (i = SEG_E0; i < SEG_UNKNOWN; i++)
350     do_relocs_for (i);
351 }
352 
353 S_SET_SEGMENT (x, y)
354      symbolS *x;
355      int y;
356 {
357   x->sy_symbol.seg = y;
358 }
359 
360 S_IS_DEFINED (x)
361      symbolS *x;
362 {
363   if (SEG_NORMAL (x->sy_symbol.seg))
364     {
365       return 1;
366     }
367   switch (x->sy_symbol.seg)
368     {
369     case SEG_UNKNOWN:
370       return 0;
371     default:
372       abort ();
373     }
374 }
375 
376 S_IS_EXTERNAL (x)
377 {
378   abort ();
379 }
380 
381 S_GET_DESC (x)
382 {
383   abort ();
384 }
385 
386 S_GET_SEGMENT (x)
387      symbolS *x;
388 {
389   return x->sy_symbol.seg;
390 }
391 
392 S_SET_EXTERNAL (x)
393      symbolS *x;
394 {
395   x->sy_symbol.sy.flags |= BSF_GLOBAL | BSF_EXPORT;
396 }
397 
398 S_SET_NAME (x, y)
399      symbolS *x;
400      char *y;
401 {
402   x->sy_symbol.sy.name = y;
403 }
404 
405 S_GET_OTHER (x)
406 {
407   abort ();
408 }
409 
410 S_IS_DEBUG (x)
411 {
412   abort ();
413 }
414 
415 #ifndef segment_name
416 char *
417 segment_name ()
418 {
419   abort ();
420 }
421 #endif
422 
423 void
424 obj_read_begin_hook ()
425 {
426 }
427 
428 static void
429 obj_ieee_section (ignore)
430      int ignore;
431 {
432   extern char *input_line_pointer;
433   extern char is_end_of_line[];
434   char *p = input_line_pointer;
435   char *s = p;
436   int i;
437 
438   /* Look up the name, if it doesn't exist, make it.  */
439   while (*p && *p != ' ' && *p != ',' && !is_end_of_line[*p])
440     {
441       p++;
442     }
443   for (i = SEG_E0; i < SEG_UNKNOWN; i++)
444     {
445       if (segment_info[i].hadone)
446 	{
447 	  if (strncmp (segment_info[i].name, s, p - s) == 0)
448 	    goto ok;
449 	}
450       else
451 	break;
452     }
453   if (i == SEG_UNKNOWN)
454     {
455       as_bad (_("too many sections"));
456       return;
457     }
458 
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;
463 ok:
464   subseg_set (i, 0);
465   while (!is_end_of_line[*p])
466     p++;
467   input_line_pointer = p;
468 }
469 
470 const pseudo_typeS obj_pseudo_table[] =
471 {
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},
481   0,
482 };
483 
484 void
485 obj_symbol_new_hook (symbolP)
486      symbolS *symbolP;
487 {
488   symbolP->sy_symbol.sy.the_bfd = abfd;
489 }
490 
491 #if 1
492 
493 #ifndef SUB_SEGMENT_ALIGN
494 #ifdef HANDLE_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)
501 #else
502 #define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 2
503 #endif
504 #endif
505 
506 extern void
507 write_object_file ()
508 {
509   int i;
510   struct frchain *frchain_ptr;
511   struct frag *frag_ptr;
512 
513   abfd = bfd_openw (out_file_name, "ieee");
514 
515   if (abfd == 0)
516     {
517       as_perror (_("FATAL: Can't create %s"), out_file_name);
518       exit (EXIT_FAILURE);
519     }
520   bfd_set_format (abfd, bfd_object);
521   bfd_set_arch_mach (abfd, bfd_arch_h8300, 0);
522   subseg_set (1, 0);
523   subseg_set (2, 0);
524   subseg_set (3, 0);
525 
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
529      at the next frag.  */
530   for (frchain_ptr = frchain_root;
531        frchain_ptr != (struct frchain *) NULL;
532        frchain_ptr = frchain_ptr->frch_next)
533     {
534       int alignment;
535 
536       subseg_set (frchain_ptr->frch_seg, frchain_ptr->frch_subseg);
537 
538       alignment = SUB_SEGMENT_ALIGN (now_seg, frchain_ptr)
539 
540 #ifdef md_do_align
541       md_do_align (alignment, (char *) NULL, 0, 0, alignment_done);
542 #endif
543       if (subseg_text_p (now_seg))
544 	frag_align_code (alignment, 0);
545       else
546 	frag_align (alignment, 0, 0);
547 
548 #ifdef md_do_align
549     alignment_done:
550 #endif
551 
552       frag_wane (frag_now);
553       frag_now->fr_fix = 0;
554       know (frag_now->fr_next == NULL);
555     }
556 
557   /* Now build one big frag chain for each segment, linked through
558      fr_next.  */
559   for (i = SEG_E0; i < SEG_UNKNOWN; i++)
560     {
561       fragS **prev_frag_ptr_ptr;
562       struct frchain *next_frchain_ptr;
563 
564 #if 0
565       struct frag **head_ptr = segment_info[i].frag_root;
566 #endif
567 
568       segment_info[i].frag_root = segment_info[i].frchainP->frch_root;
569 #if 0
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)
574 	{
575 	  *head_ptr = frchain_ptr;
576 	  head_ptr = &frchain_ptr->next;
577 	}
578 #endif
579     }
580 
581   for (i = SEG_E0; i < SEG_UNKNOWN; i++)
582     relax_segment (segment_info[i].frag_root, i);
583 
584   /* Relaxation has completed.  Freeze all syms.  */
585   finalize_syms = 1;
586 
587   /* Now the addresses of the frags are correct within the segment.  */
588 
589   bfd_as_write_hook ();
590   bfd_close (abfd);
591 }
592 
593 #endif
594 
595 H_SET_TEXT_SIZE (a, b)
596 {
597   abort ();
598 }
599 
600 H_GET_TEXT_SIZE ()
601 {
602   abort ();
603 }
604 
605 H_SET_BSS_SIZE ()
606 {
607   abort ();
608 }
609 
610 H_SET_STRING_SIZE ()
611 {
612   abort ();
613 }
614 
615 H_SET_RELOCATION_SIZE ()
616 {
617   abort ();
618 }
619 
620 H_SET_MAGIC_NUMBER ()
621 {
622   abort ();
623 }
624 
625 H_GET_FILE_SIZE ()
626 {
627   abort ();
628 }
629 
630 H_GET_TEXT_RELOCATION_SIZE ()
631 {
632   abort ();
633 }
634