Update the address and phone number of the FSF
[deliverable/binutils-gdb.git] / gas / config / obj-ieee.c
CommitLineData
252b5132 1/* obj-format for ieee-695 records.
aef6203b 2 Copyright 1991, 1992, 1993, 1994, 1997, 2000, 2001, 2002, 2003, 2005
28e4f854 3 Free Software Foundation, Inc.
252b5132
RH
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
4b4da160
NC
19 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
20 02110-1301, USA. */
252b5132 21
28e4f854 22/* Created by Steve Chamberlain <steve@cygnus.com>. */
252b5132 23
28e4f854
KH
24/* This will hopefully become the port through which bfd and gas talk,
25 for the moment, only ieee is known to work well. */
252b5132
RH
26
27#include "bfd.h"
28#include "as.h"
29#include "subsegs.h"
30#include "output-file.h"
31#include "frags.h"
32
33bfd *abfd;
34
28e4f854
KH
35/* How many addresses does the .align take? */
36
252b5132
RH
37static relax_addressT
38relax_align (address, alignment)
28e4f854
KH
39 /* Address now. */
40 register relax_addressT address;
41
42 /* Alignment (binary). */
43 register long alignment;
252b5132
RH
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);
28e4f854
KH
51}
52
53/* Calculate the size of the frag chain
54 and create a bfd section to contain all of it. */
252b5132 55
252b5132 56static void
1994a7c7 57size_section (abfd, idx)
28e4f854 58 bfd *abfd;
1994a7c7 59 unsigned int idx;
252b5132
RH
60{
61 asection *sec;
62 unsigned int size = 0;
63 fragS *frag = segment_info[idx].frag_root;
28e4f854 64
252b5132
RH
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;
28e4f854 95
252b5132 96 if (name == (char *) NULL)
28e4f854
KH
97 name = ".data";
98
99 segment_info[idx].user_stuff =
100 (char *) (sec = bfd_make_section (abfd, name));
101 /* Make it output through itself. */
252b5132
RH
102 sec->output_section = sec;
103 sec->flags |= SEC_HAS_CONTENTS;
104 bfd_set_section_size (abfd, sec, size);
105 }
106}
107
28e4f854
KH
108/* Run through a frag chain and write out the data to go with it. */
109
252b5132 110static void
1994a7c7 111fill_section (abfd, idx)
28e4f854 112 bfd *abfd;
1994a7c7 113 unsigned int idx;
252b5132
RH
114{
115 asection *sec = segment_info[idx].user_stuff;
28e4f854 116
252b5132
RH
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
28e4f854 162/* Count the relocations in a chain. */
252b5132
RH
163
164static unsigned int
1994a7c7
NC
165count_entries_in_chain (idx)
166 unsigned int idx;
252b5132
RH
167{
168 unsigned int nrelocs;
169 fixS *fixup_ptr;
170
28e4f854 171 /* Count the relocations. */
252b5132
RH
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
28e4f854
KH
182/* Output all the relocations for a section. */
183
252b5132 184void
1994a7c7
NC
185do_relocs_for (idx)
186 unsigned int idx;
252b5132
RH
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;
28e4f854 195
252b5132
RH
196 if (section)
197 {
198 nrelocs = count_entries_in_chain (idx);
199
28e4f854
KH
200 reloc_ptr_vector =
201 (arelent **) malloc ((nrelocs + 1) * sizeof (arelent *));
252b5132
RH
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
252b5132
RH
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
28e4f854 223 being pc relative and turns into an absolute relocation. */
252b5132
RH
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)
28e4f854
KH
238 /* This is a pcrel relocation, the addend should
239 be adjusted. */
240 to->addend -= to->address + 1;
252b5132
RH
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)
28e4f854
KH
249 /* This is a pcrel relocation, the addend should
250 be adjusted. */
251 to->addend -= to->address - 1;
252b5132 252 }
252b5132
RH
253 }
254 else
28e4f854 255 to->section = 0;
252b5132
RH
256
257 ptrs++;
258 from = from->fx_next;
259 }
260
aaa2624b 261 /* Attach to the section. */
252b5132
RH
262 section->orelocation = reloc_ptr_vector;
263 section->reloc_count = nrelocs;
264 section->flags |= SEC_LOAD;
265 }
266}
267
28e4f854
KH
268/* Do the symbols. */
269
252b5132 270static void
1994a7c7 271do_symbols (abfd)
28e4f854 272 bfd *abfd;
252b5132
RH
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
252b5132
RH
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);
ac62c346 289 S_SET_VALUE (ptr, S_GET_VALUE (ptr));
252b5132 290 if (ptr->sy_symbol.sy.flags == 0)
28e4f854 291 ptr->sy_symbol.sy.flags = BSF_LOCAL;
252b5132
RH
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
28e4f854 328 code. */
252b5132
RH
329
330void
1994a7c7 331bfd_as_write_hook ()
252b5132
RH
332{
333 int i;
334
335 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
28e4f854 336 size_section (abfd, i);
252b5132
RH
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);
252b5132
RH
345}
346
347S_SET_SEGMENT (x, y)
348 symbolS *x;
349 int y;
350{
351 x->sy_symbol.seg = y;
352}
353
354S_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
370S_IS_EXTERNAL (x)
371{
372 abort ();
373}
374
375S_GET_DESC (x)
376{
377 abort ();
378}
379
380S_GET_SEGMENT (x)
381 symbolS *x;
382{
383 return x->sy_symbol.seg;
384}
385
386S_SET_EXTERNAL (x)
387 symbolS *x;
388{
389 x->sy_symbol.sy.flags |= BSF_GLOBAL | BSF_EXPORT;
390}
391
392S_SET_NAME (x, y)
393 symbolS *x;
394 char *y;
395{
396 x->sy_symbol.sy.name = y;
397}
398
399S_GET_OTHER (x)
400{
401 abort ();
402}
403
404S_IS_DEBUG (x)
405{
406 abort ();
407}
408
409#ifndef segment_name
410char *
411segment_name ()
412{
413 abort ();
414}
415#endif
416
417void
418obj_read_begin_hook ()
419{
420}
421
422static void
423obj_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;
28e4f854
KH
431
432 /* Look up the name, if it doesn't exist, make it. */
252b5132
RH
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)
28e4f854 442 goto ok;
252b5132
RH
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;
457ok:
458 subseg_set (i, 0);
459 while (!is_end_of_line[*p])
460 p++;
461 input_line_pointer = p;
252b5132
RH
462}
463
252b5132
RH
464const pseudo_typeS obj_pseudo_table[] =
465{
466 {"section", obj_ieee_section, 0},
28e4f854
KH
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},
252b5132 475 0,
252b5132
RH
476};
477
252b5132
RH
478void
479obj_symbol_new_hook (symbolP)
480 symbolS *symbolP;
481{
482 symbolP->sy_symbol.sy.the_bfd = abfd;
483}
484
252b5132 485#if 1
18e1d487
AM
486
487#ifndef SUB_SEGMENT_ALIGN
488#ifdef HANDLE_ALIGN
aaa2624b 489/* The last subsegment gets an alignment corresponding to the alignment
18e1d487
AM
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
252b5132 500extern void
1994a7c7 501write_object_file ()
252b5132
RH
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);
18e1d487
AM
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. */
252b5132
RH
524 for (frchain_ptr = frchain_root;
525 frchain_ptr != (struct frchain *) NULL;
526 frchain_ptr = frchain_ptr->frch_next)
527 {
18e1d487 528 int alignment;
252b5132
RH
529
530 subseg_set (frchain_ptr->frch_seg, frchain_ptr->frch_subseg);
18e1d487
AM
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:
252b5132 544#endif
18e1d487 545
252b5132
RH
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
28e4f854 552 fr_next. */
252b5132
RH
553 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
554 {
252b5132
RH
555 fragS **prev_frag_ptr_ptr;
556 struct frchain *next_frchain_ptr;
557
252b5132 558 segment_info[i].frag_root = segment_info[i].frchainP->frch_root;
252b5132
RH
559 }
560
561 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
28e4f854 562 relax_segment (segment_info[i].frag_root, i);
252b5132 563
1cd55018
AM
564 /* Relaxation has completed. Freeze all syms. */
565 finalize_syms = 1;
566
28e4f854 567 /* Now the addresses of the frags are correct within the segment. */
252b5132
RH
568
569 bfd_as_write_hook ();
570 bfd_close (abfd);
571}
572
573#endif
574
575H_SET_TEXT_SIZE (a, b)
576{
577 abort ();
578}
579
580H_GET_TEXT_SIZE ()
581{
582 abort ();
583}
584
585H_SET_BSS_SIZE ()
586{
587 abort ();
588}
589
590H_SET_STRING_SIZE ()
591{
592 abort ();
593}
594
595H_SET_RELOCATION_SIZE ()
596{
597 abort ();
598}
599
600H_SET_MAGIC_NUMBER ()
601{
602 abort ();
603}
604
605H_GET_FILE_SIZE ()
606{
607 abort ();
608}
609
610H_GET_TEXT_RELOCATION_SIZE ()
611{
612 abort ();
613}
This page took 0.276986 seconds and 4 git commands to generate.