* write.c (size_seg): Check adjustment to last frag.
[deliverable/binutils-gdb.git] / gas / config / obj-ieee.c
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 /* Attatch 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 void cons ();
471 void s_ignore ();
472
473 void s_globl ();
474 const pseudo_typeS obj_pseudo_table[] =
475 {
476 {"section", obj_ieee_section, 0},
477 {"data.b" , cons , 1},
478 {"data.w" , cons , 2},
479 {"data.l" , cons , 4},
480 {"export" , s_globl , 0},
481 {"option" , s_ignore , 0},
482 {"end" , s_ignore , 0},
483 {"import" , s_ignore , 0},
484 {"sdata" , stringer , 0},
485 0,
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 #if 1
496
497 #ifndef SUB_SEGMENT_ALIGN
498 #ifdef HANDLE_ALIGN
499 /* The last subsegment gets an aligment corresponding to the alignment
500 of the section. This allows proper nop-filling at the end of
501 code-bearing sections. */
502 #define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) \
503 (!(FRCHAIN)->frch_next || (FRCHAIN)->frch_next->frch_seg != (SEG) \
504 ? get_recorded_alignment (SEG) : 0)
505 #else
506 #define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 2
507 #endif
508 #endif
509
510 extern void
511 write_object_file ()
512 {
513 int i;
514 struct frchain *frchain_ptr;
515 struct frag *frag_ptr;
516
517 abfd = bfd_openw (out_file_name, "ieee");
518
519 if (abfd == 0)
520 {
521 as_perror (_("FATAL: Can't create %s"), out_file_name);
522 exit (EXIT_FAILURE);
523 }
524 bfd_set_format (abfd, bfd_object);
525 bfd_set_arch_mach (abfd, bfd_arch_h8300, 0);
526 subseg_set (1, 0);
527 subseg_set (2, 0);
528 subseg_set (3, 0);
529
530 /* Run through all the sub-segments and align them up. Also
531 close any open frags. We tack a .fill onto the end of the
532 frag chain so that any .align's size can be worked by looking
533 at the next frag. */
534 for (frchain_ptr = frchain_root;
535 frchain_ptr != (struct frchain *) NULL;
536 frchain_ptr = frchain_ptr->frch_next)
537 {
538 int alignment;
539
540 subseg_set (frchain_ptr->frch_seg, frchain_ptr->frch_subseg);
541
542 alignment = SUB_SEGMENT_ALIGN (now_seg, frchain_ptr)
543
544 #ifdef md_do_align
545 md_do_align (alignment, (char *) NULL, 0, 0, alignment_done);
546 #endif
547 if (subseg_text_p (now_seg))
548 frag_align_code (alignment, 0);
549 else
550 frag_align (alignment, 0, 0);
551
552 #ifdef md_do_align
553 alignment_done:
554 #endif
555
556 frag_wane (frag_now);
557 frag_now->fr_fix = 0;
558 know (frag_now->fr_next == NULL);
559 }
560
561 /* Now build one big frag chain for each segment, linked through
562 fr_next. */
563 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
564 {
565 fragS **prev_frag_ptr_ptr;
566 struct frchain *next_frchain_ptr;
567
568 #if 0
569 struct frag **head_ptr = segment_info[i].frag_root;
570 #endif
571
572 segment_info[i].frag_root = segment_info[i].frchainP->frch_root;
573 #if 0
574 /* I'm not sure what this is for. */
575 for (frchain_ptr = segment_info[i].frchainP->frch_root;
576 frchain_ptr != (struct frchain *) NULL;
577 frchain_ptr = frchain_ptr->frch_next)
578 {
579 *head_ptr = frchain_ptr;
580 head_ptr = &frchain_ptr->next;
581 }
582 #endif
583 }
584
585 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
586 relax_segment (segment_info[i].frag_root, i);
587
588 /* Relaxation has completed. Freeze all syms. */
589 finalize_syms = 1;
590
591 /* Now the addresses of the frags are correct within the segment. */
592
593 bfd_as_write_hook ();
594 bfd_close (abfd);
595 }
596
597 #endif
598
599 H_SET_TEXT_SIZE (a, b)
600 {
601 abort ();
602 }
603
604 H_GET_TEXT_SIZE ()
605 {
606 abort ();
607 }
608
609 H_SET_BSS_SIZE ()
610 {
611 abort ();
612 }
613
614 H_SET_STRING_SIZE ()
615 {
616 abort ();
617 }
618
619 H_SET_RELOCATION_SIZE ()
620 {
621 abort ();
622 }
623
624 H_SET_MAGIC_NUMBER ()
625 {
626 abort ();
627 }
628
629 H_GET_FILE_SIZE ()
630 {
631 abort ();
632 }
633
634 H_GET_TEXT_RELOCATION_SIZE ()
635 {
636 abort ();
637 }
This page took 0.058526 seconds and 4 git commands to generate.