SUB_SEGMENT_ALIGN now takes an argument.
[binutils-gdb.git] / gas / config / obj-ieee.c
1 /* obj-format for ieee-695 records.
2 Copyright (C) 1991, 1992 Free Software Foundation, Inc.
3
4 This file is part of GAS, the GNU Assembler.
5
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)
9 any later version.
10
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.
15
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. */
19
20
21 /*
22 created by
23
24 steve chamberlain steve@cygnus.com
25 */
26
27 /*
28 this will hopefully become the port through which bfd and gas talk,
29 for the moment, only ieee is known to work well.
30 */
31
32 #include "bfd.h"
33 #include "as.h"
34 #include "subsegs.h"
35 #include "output-file.h"
36 #include "frags.h"
37
38 bfd *abfd;
39
40 /* How many addresses does the .align take? */
41 static relax_addressT
42 relax_align (address, alignment)
43 register relax_addressT address; /* Address now. */
44 register long alignment; /* Alignment (binary). */
45 {
46 relax_addressT mask;
47 relax_addressT new_address;
48
49 mask = ~((~0) << alignment);
50 new_address = (address + mask) & (~mask);
51 return (new_address - address);
52 } /* relax_align() */
53
54 /* calculate the size of the frag chain and create a bfd section
55 to contain all of it */
56 static void
57 DEFUN (size_section, (abfd, idx),
58 bfd * abfd AND
59 unsigned int idx)
60 {
61 asection *sec;
62 unsigned int size = 0;
63 fragS *frag = segment_info[idx].frag_root;
64 while (frag)
65 {
66 if (frag->fr_address != size)
67 {
68 printf ("Out of step\n");
69 size = frag->fr_address;
70 }
71 size += frag->fr_fix;
72 switch (frag->fr_type)
73 {
74 case rs_fill:
75 case rs_org:
76 size += frag->fr_offset * frag->fr_var;
77 break;
78 case rs_align:
79 size += relax_align (size, frag->fr_offset);
80 }
81 frag = frag->fr_next;
82 }
83 if (size)
84 {
85 char *name = segment_info[idx].name;
86 if (name == (char *) NULL)
87 {
88 name = ".data";
89 }
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);
95 }
96 }
97
98 /* run through a frag chain and write out the data to go with it */
99 static void
100 DEFUN (fill_section, (abfd, idx),
101 bfd * abfd AND
102 unsigned int idx)
103 {
104 asection *sec = segment_info[idx].user_stuff;
105 if (sec)
106 {
107 fragS *frag = segment_info[idx].frag_root;
108 unsigned int offset = 0;
109 while (frag)
110 {
111 unsigned int fill_size;
112 unsigned int count;
113 switch (frag->fr_type)
114 {
115 case rs_fill:
116 case rs_align:
117 case rs_org:
118 if (frag->fr_fix)
119 {
120 bfd_set_section_contents (abfd,
121 sec,
122 frag->fr_literal,
123 frag->fr_address,
124 frag->fr_fix);
125 }
126 offset += frag->fr_fix;
127 fill_size = frag->fr_var;
128 if (fill_size)
129 {
130 unsigned int off = frag->fr_fix;
131 for (count = frag->fr_offset; count; count--)
132 {
133 bfd_set_section_contents (abfd, sec,
134 frag->fr_literal +
135 frag->fr_fix,
136 frag->fr_address + off,
137 fill_size);
138 off += fill_size;
139 }
140 }
141 break;
142 default:
143 abort ();
144 }
145 frag = frag->fr_next;
146 }
147 }
148 }
149
150 /* Count the relocations in a chain */
151
152 static unsigned int
153 DEFUN (count_entries_in_chain, (idx),
154 unsigned int idx)
155 {
156 unsigned int nrelocs;
157 fixS *fixup_ptr;
158
159 /* Count the relocations */
160 fixup_ptr = segment_info[idx].fix_root;
161 nrelocs = 0;
162 while (fixup_ptr != (fixS *) NULL)
163 {
164 fixup_ptr = fixup_ptr->fx_next;
165 nrelocs++;
166 }
167 return nrelocs;
168 }
169
170 /* output all the relocations for a section */
171 void
172 DEFUN (do_relocs_for, (idx),
173 unsigned int idx)
174 {
175 unsigned int nrelocs;
176 arelent **reloc_ptr_vector;
177 arelent *reloc_vector;
178 asymbol **ptrs;
179 asection *section = (asection *) (segment_info[idx].user_stuff);
180 unsigned int i;
181 fixS *from;
182 if (section)
183 {
184 nrelocs = count_entries_in_chain (idx);
185
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++)
191 {
192 arelent *to = reloc_vector + i;
193 asymbol *s;
194 reloc_ptr_vector[i] = to;
195 to->howto = (reloc_howto_type *) (from->fx_r_type);
196
197 /* We can't represent complicated things in a reloc yet */
198 /* if (from->fx_addsy == 0 ||
199 from->fx_subsy != 0) abort();
200 */
201 s = &(from->fx_addsy->sy_symbol.sy);
202 to->address = ((char *) (from->fx_frag->fr_address +
203 from->fx_where))
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.
208
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.
213
214 */
215 if (s)
216 {
217 if ((s->flags & BSF_UNDEFINED) == 0)
218 {
219 to->section = s->section;
220 to->addend += s->value;
221 to->sym_ptr_ptr = 0;
222 if (to->howto->pcrel_offset)
223 {
224 /* This is a pcrel relocation, the addend should be adjusted */
225 to->addend -= to->address + 1;
226 }
227 }
228 else
229 {
230 to->section = 0;
231 *ptrs = &(from->fx_addsy->sy_symbol.sy);
232 to->sym_ptr_ptr = ptrs;
233
234 if (to->howto->pcrel_offset)
235 {
236 /* This is a pcrel relocation, the addend should be adjusted */
237 to->addend -= to->address - 1;
238 }
239 }
240
241 }
242 else
243 {
244 to->section = 0;
245 }
246
247 ptrs++;
248 from = from->fx_next;
249 }
250
251 /* attatch to the section */
252 section->orelocation = reloc_ptr_vector;
253 section->reloc_count = nrelocs;
254 section->flags |= SEC_LOAD;
255 }
256 }
257
258 /* do the symbols.. */
259 static void
260 DEFUN (do_symbols, (abfd),
261 bfd * abfd)
262 {
263 extern symbolS *symbol_rootP;
264 symbolS *ptr;
265 asymbol **symbol_ptr_vec;
266 asymbol *symbol_vec;
267 unsigned int count = 0;
268 unsigned int index;
269
270
271 for (ptr = symbol_rootP;
272 ptr != (symbolS *) NULL;
273 ptr = ptr->sy_next)
274 {
275 if (SEG_NORMAL (ptr->sy_symbol.seg))
276 {
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)
281 {
282 ptr->sy_symbol.sy.flags = BSF_LOCAL;
283 }
284 }
285 else
286 {
287 switch (ptr->sy_symbol.seg)
288 {
289 case SEG_ABSOLUTE:
290 ptr->sy_symbol.sy.flags |= BSF_ABSOLUTE;
291 ptr->sy_symbol.sy.section = 0;
292 break;
293 case SEG_UNKNOWN:
294 ptr->sy_symbol.sy.flags = BSF_UNDEFINED;
295 ptr->sy_symbol.sy.section = 0;
296 break;
297 default:
298 abort ();
299 }
300 }
301 count++;
302 }
303 symbol_ptr_vec = (asymbol **) malloc ((count + 1) * sizeof (asymbol *));
304
305 index = 0;
306 for (ptr = symbol_rootP;
307 ptr != (symbolS *) NULL;
308 ptr = ptr->sy_next)
309 {
310 symbol_ptr_vec[index] = &(ptr->sy_symbol.sy);
311 index++;
312 }
313 symbol_ptr_vec[index] = 0;
314 abfd->outsymbols = symbol_ptr_vec;
315 abfd->symcount = count;
316 }
317
318 /* The generic as->bfd converter. Other backends may have special case
319 code */
320
321 void
322 DEFUN_VOID (bfd_as_write_hook)
323 {
324 int i;
325
326 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
327 {
328 size_section (abfd, i);
329 }
330
331
332 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
333 fill_section (abfd, i);
334
335 do_symbols (abfd);
336
337 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
338 do_relocs_for (i);
339
340 }
341
342
343
344 S_GET_VALUE (x)
345 symbolS *x;
346 {
347 return x->sy_symbol.sy.value;
348 }
349
350 S_SET_SEGMENT (x, y)
351 symbolS *x;
352 int y;
353 {
354 x->sy_symbol.seg = y;
355 }
356
357 S_IS_DEFINED (x)
358 symbolS *x;
359 {
360 if (SEG_NORMAL (x->sy_symbol.seg))
361 {
362 return 1;
363 }
364 switch (x->sy_symbol.seg)
365 {
366 case SEG_UNKNOWN:
367 return 0;
368 default:
369 abort ();
370 }
371 }
372
373 S_IS_EXTERNAL (x)
374 {
375 abort ();
376 }
377
378 S_GET_DESC (x)
379 {
380 abort ();
381 }
382
383 S_GET_SEGMENT (x)
384 symbolS *x;
385 {
386 return x->sy_symbol.seg;
387 }
388
389 S_SET_EXTERNAL (x)
390 symbolS *x;
391 {
392 x->sy_symbol.sy.flags |= BSF_GLOBAL | BSF_EXPORT;
393 }
394
395 S_SET_NAME (x, y)
396 symbolS *x;
397 char *y;
398 {
399 x->sy_symbol.sy.name = y;
400 }
401
402 S_SET_VALUE (s, v)
403 symbolS *s;
404 long v;
405 {
406 s->sy_symbol.sy.value = v;
407 }
408
409 S_GET_OTHER (x)
410 {
411 abort ();
412 }
413
414 S_IS_DEBUG (x)
415 {
416 abort ();
417 }
418
419 char *
420 segment_name ()
421 {
422 abort ();
423 }
424
425 void
426 obj_read_begin_hook ()
427 {
428 }
429
430 static void
431 obj_ieee_section (ignore)
432 int ignore;
433 {
434 extern char *input_line_pointer;
435 extern char is_end_of_line[];
436 char *p = input_line_pointer;
437 char *s = p;
438 int i;
439 /* Look up the name, if it doesn't exist, make it */
440 while (*p && *p != ' ' && *p != ',' && !is_end_of_line[*p])
441 {
442 p++;
443 }
444 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
445 {
446 if (segment_info[i].hadone)
447 {
448 if (strncmp (segment_info[i].name, s, p - s) == 0)
449 {
450 goto ok;
451
452 }
453 }
454 else
455 break;
456 }
457 if (i == SEG_UNKNOWN)
458 {
459 as_bad ("too many sections");
460 return;
461 }
462
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;
467 ok:
468 subseg_new (i, 0);
469 while (!is_end_of_line[*p])
470 p++;
471 input_line_pointer = p;
472
473 }
474
475
476 void cons ();
477 void s_ignore ();
478
479
480 /*
481 * stringer()
482 *
483 * We read 0 or more ',' seperated, double-quoted strings.
484 *
485 * Caller should have checked need_pass_2 is FALSE because we don't check it.
486 */
487
488 void stringer ();
489 void s_globl ();
490 const pseudo_typeS obj_pseudo_table[] =
491 {
492 {"section", obj_ieee_section, 0},
493 {"data.b", cons, 1},
494 {"data.w", cons, 2},
495 {"data.l", cons, 4},
496 {"export", s_globl, 0},
497 {"option", s_ignore, 0},
498 {"end", s_ignore, 0},
499 {"import", s_ignore, 0},
500 {"sdata", stringer, 0},
501 0,
502
503 };
504
505
506
507 void
508 obj_symbol_new_hook (symbolP)
509 symbolS *symbolP;
510 {
511 symbolP->sy_symbol.sy.the_bfd = abfd;
512 }
513
514
515
516
517
518 #if 1
519 extern void
520 DEFUN_VOID (write_object_file)
521 {
522 int i;
523 struct frchain *frchain_ptr;
524 struct frag *frag_ptr;
525
526 abfd = bfd_openw (out_file_name, "ieee");
527
528 if (abfd == 0)
529 {
530 as_perror ("FATAL: Can't create %s", out_file_name);
531 exit (42);
532 }
533 bfd_set_format (abfd, bfd_object);
534 bfd_set_arch_mach (abfd, bfd_arch_h8300, 0);
535 subseg_new (1, 0);
536 subseg_new (2, 0);
537 subseg_new (3, 0);
538 for (frchain_ptr = frchain_root;
539 frchain_ptr != (struct frchain *) NULL;
540 frchain_ptr = frchain_ptr->frch_next)
541 {
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
545 frag. */
546
547 subseg_new (frchain_ptr->frch_seg, frchain_ptr->frch_subseg);
548 #ifndef SUB_SEGMENT_ALIGN
549 #define SUB_SEGMENT_ALIGN(SEG) 2
550 #endif
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);
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
562 fragS **prev_frag_ptr_ptr;
563 struct frchain *next_frchain_ptr;
564
565 /* struct frag **head_ptr = segment_info[i].frag_root;*/
566
567 segment_info[i].frag_root = segment_info[i].frchainP->frch_root;
568 #if 0
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)
573 {
574 *head_ptr = frchain_ptr;
575 head_ptr = &frchain_ptr->next;
576 }
577
578
579 #endif
580 }
581
582 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
583 {
584 relax_segment (segment_info[i].frag_root, i);
585 }
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
635 /* end of obj-ieee.c */