Use EXIT_SUCCESS and EXIT_FAILURE in all exit calls.
[deliverable/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 #if 0 /* We can't represent complicated things in a reloc yet */
198 if (from->fx_addsy == 0 || from->fx_subsy != 0) abort();
199 #endif
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
207 this 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 if (s)
214 {
215 if ((s->flags & BSF_UNDEFINED) == 0)
216 {
217 to->section = s->section;
218
219 /* We can refer directly to the value field here,
220 rather than using S_GET_VALUE, because this is
221 only called after do_symbols, which sets up the
222 value field. */
223 to->addend += s->value;
224
225 to->sym_ptr_ptr = 0;
226 if (to->howto->pcrel_offset)
227 {
228 /* This is a pcrel relocation, the addend should be adjusted */
229 to->addend -= to->address + 1;
230 }
231 }
232 else
233 {
234 to->section = 0;
235 *ptrs = &(from->fx_addsy->sy_symbol.sy);
236 to->sym_ptr_ptr = ptrs;
237
238 if (to->howto->pcrel_offset)
239 {
240 /* This is a pcrel relocation, the addend should be adjusted */
241 to->addend -= to->address - 1;
242 }
243 }
244
245 }
246 else
247 {
248 to->section = 0;
249 }
250
251 ptrs++;
252 from = from->fx_next;
253 }
254
255 /* attatch to the section */
256 section->orelocation = reloc_ptr_vector;
257 section->reloc_count = nrelocs;
258 section->flags |= SEC_LOAD;
259 }
260 }
261
262 /* do the symbols.. */
263 static void
264 DEFUN (do_symbols, (abfd),
265 bfd * abfd)
266 {
267 extern symbolS *symbol_rootP;
268 symbolS *ptr;
269 asymbol **symbol_ptr_vec;
270 asymbol *symbol_vec;
271 unsigned int count = 0;
272 unsigned int index;
273
274
275 for (ptr = symbol_rootP;
276 ptr != (symbolS *) NULL;
277 ptr = ptr->sy_next)
278 {
279 if (SEG_NORMAL (ptr->sy_symbol.seg))
280 {
281 ptr->sy_symbol.sy.section =
282 (asection *) (segment_info[ptr->sy_symbol.seg].user_stuff);
283 S_SET_VALUE (ptr, S_GET_VALUE (ptr) + ptr->sy_frag->fr_address);
284 if (ptr->sy_symbol.sy.flags == 0)
285 {
286 ptr->sy_symbol.sy.flags = BSF_LOCAL;
287 }
288 }
289 else
290 {
291 switch (ptr->sy_symbol.seg)
292 {
293 case SEG_ABSOLUTE:
294 ptr->sy_symbol.sy.flags |= BSF_ABSOLUTE;
295 ptr->sy_symbol.sy.section = 0;
296 break;
297 case SEG_UNKNOWN:
298 ptr->sy_symbol.sy.flags = BSF_UNDEFINED;
299 ptr->sy_symbol.sy.section = 0;
300 break;
301 default:
302 abort ();
303 }
304 }
305 ptr->sy_symbol.sy.value = S_GET_VALUE (ptr);
306 count++;
307 }
308 symbol_ptr_vec = (asymbol **) malloc ((count + 1) * sizeof (asymbol *));
309
310 index = 0;
311 for (ptr = symbol_rootP;
312 ptr != (symbolS *) NULL;
313 ptr = ptr->sy_next)
314 {
315 symbol_ptr_vec[index] = &(ptr->sy_symbol.sy);
316 index++;
317 }
318 symbol_ptr_vec[index] = 0;
319 abfd->outsymbols = symbol_ptr_vec;
320 abfd->symcount = count;
321 }
322
323 /* The generic as->bfd converter. Other backends may have special case
324 code */
325
326 void
327 DEFUN_VOID (bfd_as_write_hook)
328 {
329 int i;
330
331 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
332 {
333 size_section (abfd, i);
334 }
335
336
337 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
338 fill_section (abfd, i);
339
340 do_symbols (abfd);
341
342 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
343 do_relocs_for (i);
344
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 char *
410 segment_name ()
411 {
412 abort ();
413 }
414
415 void
416 obj_read_begin_hook ()
417 {
418 }
419
420 static void
421 obj_ieee_section (ignore)
422 int ignore;
423 {
424 extern char *input_line_pointer;
425 extern char is_end_of_line[];
426 char *p = input_line_pointer;
427 char *s = p;
428 int i;
429 /* Look up the name, if it doesn't exist, make it */
430 while (*p && *p != ' ' && *p != ',' && !is_end_of_line[*p])
431 {
432 p++;
433 }
434 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
435 {
436 if (segment_info[i].hadone)
437 {
438 if (strncmp (segment_info[i].name, s, p - s) == 0)
439 {
440 goto ok;
441
442 }
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
465
466 void cons ();
467 void s_ignore ();
468
469
470 void s_globl ();
471 const pseudo_typeS obj_pseudo_table[] =
472 {
473 {"section", obj_ieee_section, 0},
474 {"data.b", cons, 1},
475 {"data.w", cons, 2},
476 {"data.l", cons, 4},
477 {"export", s_globl, 0},
478 {"option", s_ignore, 0},
479 {"end", s_ignore, 0},
480 {"import", s_ignore, 0},
481 {"sdata", stringer, 0},
482 0,
483
484 };
485
486
487
488 void
489 obj_symbol_new_hook (symbolP)
490 symbolS *symbolP;
491 {
492 symbolP->sy_symbol.sy.the_bfd = abfd;
493 }
494
495
496
497
498
499 #if 1
500 extern void
501 DEFUN_VOID (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 for (frchain_ptr = frchain_root;
520 frchain_ptr != (struct frchain *) NULL;
521 frchain_ptr = frchain_ptr->frch_next)
522 {
523 /* Run through all the sub-segments and align them up. Also close any
524 open frags. We tack a .fill onto the end of the frag chain so
525 that any .align's size can be worked by looking at the next
526 frag. */
527
528 subseg_set (frchain_ptr->frch_seg, frchain_ptr->frch_subseg);
529 #ifndef SUB_SEGMENT_ALIGN
530 #define SUB_SEGMENT_ALIGN(SEG) 2
531 #endif
532 frag_align (SUB_SEGMENT_ALIGN (now_seg), 0);
533 frag_wane (frag_now);
534 frag_now->fr_fix = 0;
535 know (frag_now->fr_next == NULL);
536 }
537
538 /* Now build one big frag chain for each segment, linked through
539 fr_next. */
540 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
541 {
542
543 fragS **prev_frag_ptr_ptr;
544 struct frchain *next_frchain_ptr;
545
546 /* struct frag **head_ptr = segment_info[i].frag_root;*/
547
548 segment_info[i].frag_root = segment_info[i].frchainP->frch_root;
549 #if 0
550 /* Im not sure what this is for */
551 for (frchain_ptr = segment_info[i].frchainP->frch_root;
552 frchain_ptr != (struct frchain *) NULL;
553 frchain_ptr = frchain_ptr->frch_next)
554 {
555 *head_ptr = frchain_ptr;
556 head_ptr = &frchain_ptr->next;
557 }
558
559
560 #endif
561 }
562
563 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
564 {
565 relax_segment (segment_info[i].frag_root, i);
566 }
567
568 /* Now the addresses of the frags are correct within the segment */
569
570 bfd_as_write_hook ();
571 bfd_close (abfd);
572 }
573
574 #endif
575
576 H_SET_TEXT_SIZE (a, b)
577 {
578 abort ();
579 }
580
581 H_GET_TEXT_SIZE ()
582 {
583 abort ();
584 }
585
586 H_SET_BSS_SIZE ()
587 {
588 abort ();
589 }
590
591 H_SET_STRING_SIZE ()
592 {
593 abort ();
594 }
595
596 H_SET_RELOCATION_SIZE ()
597 {
598 abort ();
599 }
600
601 H_SET_MAGIC_NUMBER ()
602 {
603 abort ();
604 }
605
606 H_GET_FILE_SIZE ()
607 {
608 abort ();
609 }
610
611 H_GET_TEXT_RELOCATION_SIZE ()
612 {
613 abort ();
614 }
615
616 /* end of obj-ieee.c */
This page took 0.06054 seconds and 5 git commands to generate.