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