1 /* obj-format for ieee-695 records.
2    Copyright 1991, 1992, 1993, 1994, 1997, 2000, 2001, 2002, 2003, 2005
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, 51 Franklin Street - Fifth Floor, Boston, MA
20    02110-1301, 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 	  s = &(from->fx_addsy->sy_symbol.sy);
213 	  to->address = ((char *) (from->fx_frag->fr_address +
214 				   from->fx_where))
215 	    - ((char *) (&(from->fx_frag->fr_literal)));
216 	  to->addend = from->fx_offset;
217 	  /* If we know the symbol which we want to relocate to, turn
218 	     this reloaction into a section relative.
219 
220 	     If this relocation is pcrelative, and we know the
221 	     destination, we still want to keep the relocation - since
222 	     the linker might relax some of the bytes, but it stops
223 	     being pc relative and turns into an absolute relocation.  */
224 	  if (s)
225 	    {
226 	      if ((s->flags & BSF_UNDEFINED) == 0)
227 		{
228 		  to->section = s->section;
229 
230 		  /* We can refer directly to the value field here,
231 		     rather than using S_GET_VALUE, because this is
232 		     only called after do_symbols, which sets up the
233 		     value field.  */
234 		  to->addend += s->value;
235 
236 		  to->sym_ptr_ptr = 0;
237 		  if (to->howto->pcrel_offset)
238 		    /* This is a pcrel relocation, the addend should
239 		       be adjusted.  */
240 		    to->addend -= to->address + 1;
241 		}
242 	      else
243 		{
244 		  to->section = 0;
245 		  *ptrs = &(from->fx_addsy->sy_symbol.sy);
246 		  to->sym_ptr_ptr = ptrs;
247 
248 		  if (to->howto->pcrel_offset)
249 		    /* This is a pcrel relocation, the addend should
250 		       be adjusted.  */
251 		    to->addend -= to->address - 1;
252 		}
253 	    }
254 	  else
255 	    to->section = 0;
256 
257 	  ptrs++;
258 	  from = from->fx_next;
259 	}
260 
261       /* Attach to the section.  */
262       section->orelocation = reloc_ptr_vector;
263       section->reloc_count = nrelocs;
264       section->flags |= SEC_LOAD;
265     }
266 }
267 
268 /* Do the symbols.  */
269 
270 static void
271 do_symbols (abfd)
272      bfd *abfd;
273 {
274   extern symbolS *symbol_rootP;
275   symbolS *ptr;
276   asymbol **symbol_ptr_vec;
277   asymbol *symbol_vec;
278   unsigned int count = 0;
279   unsigned int index;
280 
281   for (ptr = symbol_rootP;
282        ptr != (symbolS *) NULL;
283        ptr = ptr->sy_next)
284     {
285       if (SEG_NORMAL (ptr->sy_symbol.seg))
286 	{
287 	  ptr->sy_symbol.sy.section =
288 	    (asection *) (segment_info[ptr->sy_symbol.seg].user_stuff);
289 	  S_SET_VALUE (ptr, S_GET_VALUE (ptr));
290 	  if (ptr->sy_symbol.sy.flags == 0)
291 	    ptr->sy_symbol.sy.flags = BSF_LOCAL;
292 	}
293       else
294 	{
295 	  switch (ptr->sy_symbol.seg)
296 	    {
297 	    case SEG_ABSOLUTE:
298 	      ptr->sy_symbol.sy.flags |= BSF_ABSOLUTE;
299 	      ptr->sy_symbol.sy.section = 0;
300 	      break;
301 	    case SEG_UNKNOWN:
302 	      ptr->sy_symbol.sy.flags = BSF_UNDEFINED;
303 	      ptr->sy_symbol.sy.section = 0;
304 	      break;
305 	    default:
306 	      abort ();
307 	    }
308 	}
309       ptr->sy_symbol.sy.value = S_GET_VALUE (ptr);
310       count++;
311     }
312   symbol_ptr_vec = (asymbol **) malloc ((count + 1) * sizeof (asymbol *));
313 
314   index = 0;
315   for (ptr = symbol_rootP;
316        ptr != (symbolS *) NULL;
317        ptr = ptr->sy_next)
318     {
319       symbol_ptr_vec[index] = &(ptr->sy_symbol.sy);
320       index++;
321     }
322   symbol_ptr_vec[index] = 0;
323   abfd->outsymbols = symbol_ptr_vec;
324   abfd->symcount = count;
325 }
326 
327 /* The generic as->bfd converter. Other backends may have special case
328    code.  */
329 
330 void
331 bfd_as_write_hook ()
332 {
333   int i;
334 
335   for (i = SEG_E0; i < SEG_UNKNOWN; i++)
336     size_section (abfd, i);
337 
338   for (i = SEG_E0; i < SEG_UNKNOWN; i++)
339     fill_section (abfd, i);
340 
341   do_symbols (abfd);
342 
343   for (i = SEG_E0; i < SEG_UNKNOWN; i++)
344     do_relocs_for (i);
345 }
346 
347 S_SET_SEGMENT (x, y)
348      symbolS *x;
349      int y;
350 {
351   x->sy_symbol.seg = y;
352 }
353 
354 S_IS_DEFINED (x)
355      symbolS *x;
356 {
357   if (SEG_NORMAL (x->sy_symbol.seg))
358     {
359       return 1;
360     }
361   switch (x->sy_symbol.seg)
362     {
363     case SEG_UNKNOWN:
364       return 0;
365     default:
366       abort ();
367     }
368 }
369 
370 S_IS_EXTERNAL (x)
371 {
372   abort ();
373 }
374 
375 S_GET_DESC (x)
376 {
377   abort ();
378 }
379 
380 S_GET_SEGMENT (x)
381      symbolS *x;
382 {
383   return x->sy_symbol.seg;
384 }
385 
386 S_SET_EXTERNAL (x)
387      symbolS *x;
388 {
389   x->sy_symbol.sy.flags |= BSF_GLOBAL | BSF_EXPORT;
390 }
391 
392 S_SET_NAME (x, y)
393      symbolS *x;
394      char *y;
395 {
396   x->sy_symbol.sy.name = y;
397 }
398 
399 S_GET_OTHER (x)
400 {
401   abort ();
402 }
403 
404 S_IS_DEBUG (x)
405 {
406   abort ();
407 }
408 
409 #ifndef segment_name
410 char *
411 segment_name ()
412 {
413   abort ();
414 }
415 #endif
416 
417 void
418 obj_read_begin_hook ()
419 {
420 }
421 
422 static void
423 obj_ieee_section (ignore)
424      int ignore;
425 {
426   extern char *input_line_pointer;
427   extern char is_end_of_line[];
428   char *p = input_line_pointer;
429   char *s = p;
430   int i;
431 
432   /* Look up the name, if it doesn't exist, make it.  */
433   while (*p && *p != ' ' && *p != ',' && !is_end_of_line[*p])
434     {
435       p++;
436     }
437   for (i = SEG_E0; i < SEG_UNKNOWN; i++)
438     {
439       if (segment_info[i].hadone)
440 	{
441 	  if (strncmp (segment_info[i].name, s, p - s) == 0)
442 	    goto ok;
443 	}
444       else
445 	break;
446     }
447   if (i == SEG_UNKNOWN)
448     {
449       as_bad (_("too many sections"));
450       return;
451     }
452 
453   segment_info[i].hadone = 1;
454   segment_info[i].name = malloc (p - s + 1);
455   memcpy (segment_info[i].name, s, p - s);
456   segment_info[i].name[p - s] = 0;
457 ok:
458   subseg_set (i, 0);
459   while (!is_end_of_line[*p])
460     p++;
461   input_line_pointer = p;
462 }
463 
464 const pseudo_typeS obj_pseudo_table[] =
465 {
466   {"section", obj_ieee_section, 0},
467   {"data.b" , cons            , 1},
468   {"data.w" , cons            , 2},
469   {"data.l" , cons            , 4},
470   {"export" , s_globl         , 0},
471   {"option" , s_ignore        , 0},
472   {"end"    , s_ignore        , 0},
473   {"import" , s_ignore        , 0},
474   {"sdata"  , stringer        , 0},
475   0,
476 };
477 
478 void
479 obj_symbol_new_hook (symbolP)
480      symbolS *symbolP;
481 {
482   symbolP->sy_symbol.sy.the_bfd = abfd;
483 }
484 
485 #if 1
486 
487 #ifndef SUB_SEGMENT_ALIGN
488 #ifdef HANDLE_ALIGN
489 /* The last subsegment gets an alignment corresponding to the alignment
490    of the section.  This allows proper nop-filling at the end of
491    code-bearing sections.  */
492 #define SUB_SEGMENT_ALIGN(SEG, FRCHAIN)					\
493   (!(FRCHAIN)->frch_next || (FRCHAIN)->frch_next->frch_seg != (SEG)	\
494    ? get_recorded_alignment (SEG) : 0)
495 #else
496 #define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 2
497 #endif
498 #endif
499 
500 extern void
501 write_object_file ()
502 {
503   int i;
504   struct frchain *frchain_ptr;
505   struct frag *frag_ptr;
506 
507   abfd = bfd_openw (out_file_name, "ieee");
508 
509   if (abfd == 0)
510     {
511       as_perror (_("FATAL: Can't create %s"), out_file_name);
512       exit (EXIT_FAILURE);
513     }
514   bfd_set_format (abfd, bfd_object);
515   bfd_set_arch_mach (abfd, bfd_arch_h8300, 0);
516   subseg_set (1, 0);
517   subseg_set (2, 0);
518   subseg_set (3, 0);
519 
520   /* Run through all the sub-segments and align them up.  Also
521      close any open frags.  We tack a .fill onto the end of the
522      frag chain so that any .align's size can be worked by looking
523      at the next frag.  */
524   for (frchain_ptr = frchain_root;
525        frchain_ptr != (struct frchain *) NULL;
526        frchain_ptr = frchain_ptr->frch_next)
527     {
528       int alignment;
529 
530       subseg_set (frchain_ptr->frch_seg, frchain_ptr->frch_subseg);
531 
532       alignment = SUB_SEGMENT_ALIGN (now_seg, frchain_ptr)
533 
534 #ifdef md_do_align
535       md_do_align (alignment, (char *) NULL, 0, 0, alignment_done);
536 #endif
537       if (subseg_text_p (now_seg))
538 	frag_align_code (alignment, 0);
539       else
540 	frag_align (alignment, 0, 0);
541 
542 #ifdef md_do_align
543     alignment_done:
544 #endif
545 
546       frag_wane (frag_now);
547       frag_now->fr_fix = 0;
548       know (frag_now->fr_next == NULL);
549     }
550 
551   /* Now build one big frag chain for each segment, linked through
552      fr_next.  */
553   for (i = SEG_E0; i < SEG_UNKNOWN; i++)
554     {
555       fragS **prev_frag_ptr_ptr;
556       struct frchain *next_frchain_ptr;
557 
558       segment_info[i].frag_root = segment_info[i].frchainP->frch_root;
559     }
560 
561   for (i = SEG_E0; i < SEG_UNKNOWN; i++)
562     relax_segment (segment_info[i].frag_root, i);
563 
564   /* Relaxation has completed.  Freeze all syms.  */
565   finalize_syms = 1;
566 
567   /* Now the addresses of the frags are correct within the segment.  */
568 
569   bfd_as_write_hook ();
570   bfd_close (abfd);
571 }
572 
573 #endif
574 
575 H_SET_TEXT_SIZE (a, b)
576 {
577   abort ();
578 }
579 
580 H_GET_TEXT_SIZE ()
581 {
582   abort ();
583 }
584 
585 H_SET_BSS_SIZE ()
586 {
587   abort ();
588 }
589 
590 H_SET_STRING_SIZE ()
591 {
592   abort ();
593 }
594 
595 H_SET_RELOCATION_SIZE ()
596 {
597   abort ();
598 }
599 
600 H_SET_MAGIC_NUMBER ()
601 {
602   abort ();
603 }
604 
605 H_GET_FILE_SIZE ()
606 {
607   abort ();
608 }
609 
610 H_GET_TEXT_RELOCATION_SIZE ()
611 {
612   abort ();
613 }
614