* config/tc-sh.h (struct sh_segment_info_type): Define.
[deliverable/binutils-gdb.git] / gas / config / obj-ieee.c
CommitLineData
cd8761e1 1/* obj-format for ieee-695 records.
01170860 2 Copyright (C) 1991, 1992 Free Software Foundation, Inc.
355afbcd 3
a39116f1 4 This file is part of GAS, the GNU Assembler.
355afbcd 5
a39116f1
RP
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.
355afbcd 10
a39116f1
RP
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.
355afbcd 15
a39116f1
RP
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
a2a5a4fa 18 the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
cd8761e1
SC
19
20
355afbcd 21/*
cd8761e1 22 created by
355afbcd 23
cd8761e1 24 steve chamberlain steve@cygnus.com
a39116f1 25 */
cd8761e1
SC
26
27/*
a39116f1
RP
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 */
cd8761e1
SC
31
32#include "bfd.h"
33#include "as.h"
34#include "subsegs.h"
35#include "output-file.h"
36#include "frags.h"
37
38bfd *abfd;
39
40/* How many addresses does the .align take? */
355afbcd
KR
41static relax_addressT
42relax_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() */
cd8761e1
SC
53
54/* calculate the size of the frag chain and create a bfd section
55 to contain all of it */
355afbcd
KR
56static void
57DEFUN (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;
a39116f1 70 }
355afbcd
KR
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);
a39116f1 80 }
355afbcd
KR
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 }
cd8761e1
SC
96}
97
98/* run through a frag chain and write out the data to go with it */
355afbcd
KR
99static void
100DEFUN (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);
a39116f1 125 }
355afbcd
KR
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;
a39116f1 146 }
355afbcd 147 }
cd8761e1
SC
148}
149
150/* Count the relocations in a chain */
151
355afbcd
KR
152static unsigned int
153DEFUN (count_entries_in_chain, (idx),
154 unsigned int idx)
cd8761e1 155{
355afbcd
KR
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;
cd8761e1
SC
168}
169
170/* output all the relocations for a section */
355afbcd
KR
171void
172DEFUN (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
c1b625be
KR
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
355afbcd
KR
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;
c1b625be
KR
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. */
355afbcd
KR
213 if (s)
214 {
215 if ((s->flags & BSF_UNDEFINED) == 0)
216 {
217 to->section = s->section;
85051959
ILT
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. */
355afbcd 223 to->addend += s->value;
85051959 224
355afbcd
KR
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;
a39116f1 230 }
355afbcd
KR
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 }
cd8761e1
SC
260}
261
262/* do the symbols.. */
355afbcd
KR
263static void
264DEFUN (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);
85051959 283 S_SET_VALUE (ptr, S_GET_VALUE (ptr) + ptr->sy_frag->fr_address);
355afbcd 284 if (ptr->sy_symbol.sy.flags == 0)
cd8761e1 285 {
355afbcd 286 ptr->sy_symbol.sy.flags = BSF_LOCAL;
cd8761e1 287 }
355afbcd
KR
288 }
289 else
290 {
291 switch (ptr->sy_symbol.seg)
a39116f1 292 {
355afbcd
KR
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 ();
a39116f1 303 }
355afbcd 304 }
85051959 305 ptr->sy_symbol.sy.value = S_GET_VALUE (ptr);
355afbcd
KR
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;
cd8761e1
SC
321}
322
323/* The generic as->bfd converter. Other backends may have special case
324 code */
325
355afbcd
KR
326void
327DEFUN_VOID (bfd_as_write_hook)
cd8761e1 328{
355afbcd
KR
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
cd8761e1
SC
345}
346
355afbcd
KR
347S_SET_SEGMENT (x, y)
348 symbolS *x;
349 int y;
350{
351 x->sy_symbol.seg = y;
cd8761e1
SC
352}
353
355afbcd
KR
354S_IS_DEFINED (x)
355 symbolS *x;
cd8761e1 356{
355afbcd
KR
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 ();
cd8761e1
SC
373}
374
355afbcd
KR
375S_GET_DESC (x)
376{
377 abort ();
378}
379
380S_GET_SEGMENT (x)
381 symbolS *x;
382{
383 return x->sy_symbol.seg;
384}
cd8761e1 385
355afbcd
KR
386S_SET_EXTERNAL (x)
387 symbolS *x;
388{
389 x->sy_symbol.sy.flags |= BSF_GLOBAL | BSF_EXPORT;
390}
cd8761e1 391
355afbcd
KR
392S_SET_NAME (x, y)
393 symbolS *x;
394 char *y;
cd8761e1 395{
355afbcd 396 x->sy_symbol.sy.name = y;
cd8761e1
SC
397}
398
355afbcd
KR
399S_GET_OTHER (x)
400{
401 abort ();
cd8761e1
SC
402}
403
355afbcd
KR
404S_IS_DEBUG (x)
405{
406 abort ();
407}
cd8761e1 408
355afbcd
KR
409char *
410segment_name ()
411{
412 abort ();
413}
cd8761e1 414
355afbcd
KR
415void
416obj_read_begin_hook ()
417{
418}
cd8761e1 419
355afbcd
KR
420static void
421obj_ieee_section (ignore)
422 int ignore;
cd8761e1 423{
355afbcd
KR
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 }
a39116f1 443 }
355afbcd
KR
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:
604633ae 458 subseg_set (i, 0);
355afbcd
KR
459 while (!is_end_of_line[*p])
460 p++;
461 input_line_pointer = p;
462
cd8761e1
SC
463}
464
465
355afbcd
KR
466void cons ();
467void s_ignore ();
cd8761e1
SC
468
469
355afbcd
KR
470void s_globl ();
471const 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
cd8761e1
SC
484};
485
486
487
355afbcd
KR
488void
489obj_symbol_new_hook (symbolP)
490 symbolS *symbolP;
cd8761e1 491{
355afbcd 492 symbolP->sy_symbol.sy.the_bfd = abfd;
cd8761e1
SC
493}
494
495
496
497
498
499#if 1
355afbcd
KR
500extern void
501DEFUN_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);
460531da 512 exit (EXIT_FAILURE);
355afbcd
KR
513 }
514 bfd_set_format (abfd, bfd_object);
515 bfd_set_arch_mach (abfd, bfd_arch_h8300, 0);
604633ae
ILT
516 subseg_set (1, 0);
517 subseg_set (2, 0);
518 subseg_set (3, 0);
355afbcd
KR
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
2492e118
KR
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. */
355afbcd 527
604633ae 528 subseg_set (frchain_ptr->frch_seg, frchain_ptr->frch_subseg);
3eb802b5 529#ifndef SUB_SEGMENT_ALIGN
2492e118 530#define SUB_SEGMENT_ALIGN(SEG) 2
3eb802b5 531#endif
2492e118 532 frag_align (SUB_SEGMENT_ALIGN (now_seg), 0);
355afbcd
KR
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
a39116f1 539 fr_next. */
355afbcd
KR
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;
cd8761e1 549#if 0
355afbcd
KR
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;
a39116f1 557 }
355afbcd
KR
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);
cd8761e1
SC
572}
573
574#endif
575
355afbcd
KR
576H_SET_TEXT_SIZE (a, b)
577{
578 abort ();
579}
580
581H_GET_TEXT_SIZE ()
582{
583 abort ();
584}
585
586H_SET_BSS_SIZE ()
587{
588 abort ();
589}
590
591H_SET_STRING_SIZE ()
592{
593 abort ();
594}
595
596H_SET_RELOCATION_SIZE ()
597{
598 abort ();
599}
600
601H_SET_MAGIC_NUMBER ()
602{
603 abort ();
604}
605
606H_GET_FILE_SIZE ()
607{
608 abort ();
609}
610
611H_GET_TEXT_RELOCATION_SIZE ()
612{
613 abort ();
614}
a39116f1
RP
615
616/* end of obj-ieee.c */
This page took 0.178805 seconds and 4 git commands to generate.