Ran "indent", for GNU coding style; some code & comments still need fixup.
[binutils-gdb.git] / gas / config / obj-coffbfd.c
1 /* coff object file format with bfd
2 Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc.
3
4 This file is part of GAS.
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 How does this releate to the rest of GAS ?
23
24 Well, all the other files in gas are more or less a black box. It
25 takes care of opening files, parsing command lines, stripping blanks
26 etc etc. This module gets a chance to register what it wants to do by
27 saying that it is interested in various pseduo ops. The other big
28 change is write_object_file. This runs through all the data
29 structures that gas builds, and outputs the file in the format of our
30 choice.
31
32 Hacked for BFDness by steve chamberlain
33
34 This object module now supports the Hitachi H8/300 and the AMD 29k
35
36 sac@cygnus.com
37 */
38
39 #include "as.h"
40 #include "obstack.h"
41 #include "subsegs.h"
42 #include "frags.h"
43 #include "../bfd/libbfd.h"
44
45
46 #define MIN(a,b) ((a) < (b)? (a) : (b))
47 /* This vector is used to turn an internal segment into a section #
48 suitable for insertion into a coff symbol table
49 */
50
51 const short seg_N_TYPE[] =
52 { /* in: segT out: N_TYPE bits */
53 C_ABS_SECTION,
54 1,
55 2,
56 3,
57 4,
58 5,
59 6,
60 7,
61 8,
62 9,
63 10,
64 C_UNDEF_SECTION, /* SEG_UNKNOWN */
65 C_UNDEF_SECTION, /* SEG_ABSENT */
66 C_UNDEF_SECTION, /* SEG_PASS1 */
67 C_UNDEF_SECTION, /* SEG_GOOF */
68 C_UNDEF_SECTION, /* SEG_BIG */
69 C_UNDEF_SECTION, /* SEG_DIFFERENCE */
70 C_DEBUG_SECTION, /* SEG_DEBUG */
71 C_NTV_SECTION, /* SEG_NTV */
72 C_PTV_SECTION, /* SEG_PTV */
73 C_REGISTER_SECTION, /* SEG_REGISTER */
74 };
75
76
77 int function_lineoff = -1; /* Offset in line#s where the last function
78 started (the odd entry for line #0) */
79
80
81 int had_lineno = 0;
82 int had_reloc = 0;
83
84 static symbolS *last_line_symbol;
85 /* Add 4 to the real value to get the index and compensate the
86 negatives. This vector is used by S_GET_SEGMENT to turn a coff
87 section number into a segment number
88 */
89 static symbolS *previous_file_symbol = NULL;
90 void c_symbol_merge ();
91 static int line_base;
92
93 symbolS *c_section_symbol ();
94 bfd *abfd;
95 void EXFUN (bfd_as_write_hook, (struct internal_filehdr *,
96 bfd * abfd));
97
98 static void EXFUN (fixup_segment, (fixS * fixP,
99 segT this_segment_type));
100
101
102 static void EXFUN (fixup_mdeps, (fragS *));
103
104
105 static void EXFUN (fill_section, (bfd * abfd,
106 struct internal_filehdr * f, unsigned
107 long *));
108
109
110 char *EXFUN (s_get_name, (symbolS * s));
111 static symbolS *EXFUN (tag_find_or_make, (char *name));
112 static symbolS *EXFUN (tag_find, (char *name));
113
114
115 static int
116 EXFUN (c_line_new, (
117 symbolS * symbol,
118 long paddr,
119 unsigned short line_number,
120 fragS * frag));
121
122
123 static void EXFUN (w_symbols,
124 (bfd * abfd,
125 char *where,
126 symbolS * symbol_rootP));
127
128
129
130 static void EXFUN (obj_coff_def, (int what));
131 static void EXFUN (obj_coff_lcomm, (void));
132 static void EXFUN (obj_coff_dim, (void));
133 static void EXFUN (obj_coff_text, (void));
134 static void EXFUN (obj_coff_data, (void));
135 static void EXFUN (obj_coff_endef, (void));
136 static void EXFUN (obj_coff_line, (void));
137 static void EXFUN (obj_coff_ln, (void));
138 static void EXFUN (obj_coff_scl, (void));
139 static void EXFUN (obj_coff_size, (void));
140 static void EXFUN (obj_coff_tag, (void));
141 static void EXFUN (obj_coff_type, (void));
142 static void EXFUN (obj_coff_val, (void));
143 void EXFUN (obj_coff_section, (void));
144 static void EXFUN (tag_init, (void));
145 static void EXFUN (tag_insert, (char *name, symbolS * symbolP));
146
147
148 static struct hash_control *tag_hash;
149 static symbolS *def_symbol_in_progress = NULL;
150
151 const pseudo_typeS obj_pseudo_table[] =
152 {
153 {"def", obj_coff_def, 0},
154 {"dim", obj_coff_dim, 0},
155 {"endef", obj_coff_endef, 0},
156 {"line", obj_coff_line, 0},
157 {"ln", obj_coff_ln, 0},
158 {"scl", obj_coff_scl, 0},
159 {"size", obj_coff_size, 0},
160 {"tag", obj_coff_tag, 0},
161 {"type", obj_coff_type, 0},
162 {"val", obj_coff_val, 0},
163 {"section", obj_coff_section, 0},
164 {"use", obj_coff_section, 0},
165 {"sect", obj_coff_section, 0},
166 {"text", obj_coff_text, 0},
167 {"data", obj_coff_data, 0},
168 /* we don't yet handle this. */
169 {"ident", s_ignore, 0},
170 {"ABORT", s_abort, 0},
171 {"lcomm", obj_coff_lcomm, 0},
172 {NULL} /* end sentinel */
173 }; /* obj_pseudo_table */
174
175
176
177 /* Section stuff
178
179 We allow more than just the standard 3 sections, infact, we allow
180 10 sections, (though the usual three have to be there).
181
182 This structure performs the mappings for us:
183
184 */
185
186 /* OBS stuff
187 static struct internal_scnhdr bss_section_header;
188 struct internal_scnhdr data_section_header;
189 struct internal_scnhdr text_section_header;
190
191 const segT N_TYPE_seg [32] =
192 {
193
194 };
195
196 */
197
198 #define N_SEG 32
199 typedef struct
200 {
201 segT seg_t;
202 int i;
203 }
204
205 seg_info_type;
206
207 seg_info_type seg_info_off_by_4[N_SEG] =
208 {
209 {SEG_PTV,},
210 {SEG_NTV,},
211 {SEG_DEBUG,},
212 {SEG_ABSOLUTE,},
213 {SEG_UNKNOWN,},
214 {SEG_E0},
215 {SEG_E1},
216 {SEG_E2},
217 {SEG_E3},
218 {SEG_E4},
219 {SEG_E5},
220 {SEG_E6},
221 {SEG_E7},
222 {SEG_E8},
223 {SEG_E9},
224 {15},
225 {16},
226 {17},
227 {18},
228 {19},
229 {20},
230 {0},
231 {0},
232 {0},
233 {SEG_REGISTER}, 0, 0, 0, 0};
234
235 #define SEG_INFO_FROM_SECTION_NUMBER(x) (seg_info_off_by_4[(x)+4])
236 #define SEG_INFO_FROM_SEG_NUMBER(x) (seg_info_off_by_4[(x)])
237
238
239 relax_addressT
240 DEFUN (relax_align, (address, alignment),
241 register relax_addressT address AND
242 register long alignment)
243 {
244 relax_addressT mask;
245 relax_addressT new_address;
246
247 mask = ~((~0) << alignment);
248 new_address = (address + mask) & (~mask);
249 return (new_address - address);
250 } /* relax_align() */
251
252
253 segT
254 DEFUN (s_get_segment, (x),
255 symbolS * x)
256 {
257 return SEG_INFO_FROM_SECTION_NUMBER (x->sy_symbol.ost_entry.n_scnum).seg_t;
258 }
259
260
261
262 /* calculate the size of the frag chain and fill in the section header
263 to contain all of it, also fill in the addr of the sections */
264 static unsigned int
265 DEFUN (size_section, (abfd, idx),
266 bfd * abfd AND
267 unsigned int idx)
268 {
269
270 unsigned int size = 0;
271 fragS *frag = segment_info[idx].frchainP->frch_root;
272 while (frag)
273 {
274 size = frag->fr_address;
275 #if 0
276 if (frag->fr_address != size)
277 {
278 printf ("Out of step\n");
279 size = frag->fr_address;
280 }
281
282 switch (frag->fr_type)
283 {
284 #ifdef TC_COFF_SIZEMACHDEP
285 case rs_machine_dependent:
286 size += TC_COFF_SIZEMACHDEP (frag);
287 break;
288 #endif
289 case rs_fill:
290 case rs_org:
291 size += frag->fr_fix;
292 size += frag->fr_offset * frag->fr_var;
293 break;
294 case rs_align:
295 size += frag->fr_fix;
296 size += relax_align (size, frag->fr_offset);
297 }
298 #endif
299 frag = frag->fr_next;
300 }
301 segment_info[idx].scnhdr.s_size = size;
302 return size;
303 }
304
305
306 static unsigned int
307 DEFUN (count_entries_in_chain, (idx),
308 unsigned int idx)
309 {
310 unsigned int nrelocs;
311 fixS *fixup_ptr;
312
313 /* Count the relocations */
314 fixup_ptr = segment_info[idx].fix_root;
315 nrelocs = 0;
316 while (fixup_ptr != (fixS *) NULL)
317 {
318 if (TC_COUNT_RELOC (fixup_ptr))
319 {
320
321 #ifdef TC_A29K
322
323 if (fixup_ptr->fx_r_type == RELOC_CONSTH)
324 nrelocs += 2;
325 else
326 nrelocs++;
327 #else
328 nrelocs++;
329 #endif
330 }
331
332 fixup_ptr = fixup_ptr->fx_next;
333 }
334 return nrelocs;
335 }
336
337 /* output all the relocations for a section */
338 void
339 DEFUN (do_relocs_for, (abfd, file_cursor),
340 bfd * abfd AND
341 unsigned long *file_cursor)
342 {
343 unsigned int nrelocs;
344 unsigned int idx;
345 unsigned int addr = 0;
346 for (idx = SEG_E0; idx < SEG_E9; idx++)
347 {
348 if (segment_info[idx].scnhdr.s_name[0])
349 {
350
351 struct external_reloc *ext_ptr;
352 struct external_reloc *external_reloc_vec;
353 unsigned int external_reloc_size;
354 unsigned int count = 0;
355 unsigned int base = addr;
356 fixS *fix_ptr = segment_info[idx].fix_root;
357 nrelocs = count_entries_in_chain (idx);
358
359 if (nrelocs)
360 had_reloc = 1;
361
362 external_reloc_size = nrelocs * RELSZ;
363 external_reloc_vec =
364 (struct external_reloc *) malloc (external_reloc_size);
365
366
367
368 ext_ptr = external_reloc_vec;
369
370 /* Fill in the internal coff style reloc struct from the
371 internal fix list */
372 while (fix_ptr)
373 {
374 symbolS *symbol_ptr;
375 struct internal_reloc intr;
376
377 /* Only output some of the relocations */
378 if (TC_COUNT_RELOC (fix_ptr))
379 {
380 #ifdef TC_RELOC_MANGLE
381 TC_RELOC_MANGLE (fix_ptr, &intr, base);
382
383 #else
384 symbolS *dot;
385 symbol_ptr = fix_ptr->fx_addsy;
386
387 intr.r_type = TC_COFF_FIX2RTYPE (fix_ptr);
388 intr.r_vaddr =
389 base + fix_ptr->fx_frag->fr_address + fix_ptr->fx_where;
390
391 intr.r_offset = fix_ptr->fx_offset;
392
393 intr.r_offset = 0;
394
395 /* Turn the segment of the symbol into an offset
396 */
397 if (symbol_ptr)
398 {
399 dot = segment_info[S_GET_SEGMENT (symbol_ptr)].dot;
400 if (dot)
401 {
402 intr.r_symndx = dot->sy_number;
403 }
404 else
405 {
406 intr.r_symndx = symbol_ptr->sy_number;
407 }
408
409 }
410 else
411 {
412 intr.r_symndx = -1;
413
414
415 }
416 #endif
417
418 (void) bfd_coff_swap_reloc_out (abfd, &intr, ext_ptr);
419 ext_ptr++;
420
421 #if defined(TC_A29K)
422 /* The 29k has a special kludge for the high 16 bit reloc.
423 Two relocations are emmited, R_IHIHALF, and
424 R_IHCONST. The second one doesn't contain a symbol,
425 but uses the value for offset */
426
427 if (intr.r_type == R_IHIHALF)
428 {
429 /* now emit the second bit */
430 intr.r_type = R_IHCONST;
431 intr.r_symndx = fix_ptr->fx_addnumber;
432 (void) bfd_coff_swap_reloc_out (abfd, &intr, ext_ptr);
433 ext_ptr++;
434 }
435 #endif
436 }
437
438 fix_ptr = fix_ptr->fx_next;
439 }
440
441 /* Write out the reloc table */
442 segment_info[idx].scnhdr.s_relptr = *file_cursor;
443 segment_info[idx].scnhdr.s_nreloc = nrelocs;
444 bfd_write ((PTR) external_reloc_vec, 1, external_reloc_size, abfd);
445 *file_cursor += external_reloc_size;
446 free (external_reloc_vec);
447 }
448 #ifndef ZERO_BASED_SEGMENTS
449 /* Supposedly setting segment addresses non-zero causes problems
450 for some platforms, although it shouldn't. If you define
451 ZERO_BASED_SEGMENTS, all the segments will be based at 0.
452 Please don't make this the default, since some systems (e.g.,
453 SVR3.2) require the segments to be non-zero based. Ian Taylor
454 <ian@cygnus.com>. */
455 addr += segment_info[idx].scnhdr.s_size;
456 #endif
457 }
458 }
459
460
461 /* run through a frag chain and write out the data to go with it, fill
462 in the scnhdrs with the info on the file postions
463 */
464 static void
465 DEFUN (fill_section, (abfd, filehdr, file_cursor),
466 bfd * abfd AND
467 struct internal_filehdr *filehdr AND
468 unsigned long *file_cursor)
469 {
470
471 unsigned int i;
472
473 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
474 {
475 unsigned int offset = 0;
476
477 struct internal_scnhdr *s = &(segment_info[i].scnhdr);
478
479 if (s->s_name[0])
480 {
481 fragS *frag = segment_info[i].frchainP->frch_root;
482 char *buffer = malloc (s->s_size);
483 if (s->s_size != 0)
484 s->s_scnptr = *file_cursor;
485 else
486 s->s_scnptr = 0;
487
488 s->s_flags = STYP_REG;
489 if (strcmp (s->s_name, ".text") == 0)
490 s->s_flags |= STYP_TEXT;
491 else if (strcmp (s->s_name, ".data") == 0)
492 s->s_flags |= STYP_DATA;
493 else if (strcmp (s->s_name, ".bss") == 0)
494 s->s_flags |= STYP_BSS | STYP_NOLOAD;
495 else if (strcmp (s->s_name, ".lit") == 0)
496 s->s_flags = STYP_LIT | STYP_TEXT;
497
498
499 while (frag)
500 {
501 unsigned int fill_size;
502 switch (frag->fr_type)
503 {
504 case rs_machine_dependent:
505 if (frag->fr_fix)
506 {
507 memcpy (buffer + frag->fr_address,
508 frag->fr_literal,
509 frag->fr_fix);
510 offset += frag->fr_fix;
511 }
512
513 break;
514 case rs_fill:
515 case rs_align:
516 case rs_org:
517 if (frag->fr_fix)
518 {
519 memcpy (buffer + frag->fr_address,
520 frag->fr_literal,
521 frag->fr_fix);
522 offset += frag->fr_fix;
523 }
524
525 fill_size = frag->fr_var;
526 if (fill_size)
527 {
528 unsigned int count;
529 unsigned int off = frag->fr_fix;
530 for (count = frag->fr_offset; count; count--)
531 {
532 memcpy (buffer + frag->fr_address + off,
533 frag->fr_literal + frag->fr_fix,
534 fill_size);
535 off += fill_size;
536 offset += fill_size;
537
538 }
539
540 }
541 break;
542 case rs_broken_word:
543 break;
544 default:
545 abort ();
546 }
547 frag = frag->fr_next;
548 }
549
550
551 bfd_write (buffer, s->s_size, 1, abfd);
552 free (buffer);
553
554 *file_cursor += s->s_size;
555
556 }
557 }
558
559 }
560
561
562
563 /* Coff file generation & utilities */
564
565
566 static void
567 DEFUN (coff_header_append, (abfd, filehdr, aouthdr),
568 bfd * abfd AND
569 struct internal_filehdr *filehdr AND
570 struct internal_aouthdr *aouthdr)
571 {
572 unsigned int i;
573 char buffer[1000];
574 char buffero[1000];
575
576 bfd_seek (abfd, 0, 0);
577 #if 0
578 filehdr.f_opthdr = bfd_coff_swap_aouthdr_out (abfd, aouthdr,
579 buffero);
580 #else
581 filehdr->f_opthdr = 0;
582 #endif
583 i = bfd_coff_swap_filehdr_out (abfd, filehdr, buffer);
584
585 bfd_write (buffer, i, 1, abfd);
586 bfd_write (buffero, filehdr->f_opthdr, 1, abfd);
587
588 for (i = SEG_E0; i < SEG_E9; i++)
589 {
590 if (segment_info[i].scnhdr.s_name[0])
591 {
592 unsigned int size =
593 bfd_coff_swap_scnhdr_out (abfd,
594 &(segment_info[i].scnhdr),
595 buffer);
596 bfd_write (buffer, size, 1, abfd);
597 }
598 }
599 }
600
601
602 char *
603 DEFUN (symbol_to_chars, (abfd, where, symbolP),
604 bfd * abfd AND
605 char *where AND
606 symbolS * symbolP)
607 {
608 unsigned int numaux = symbolP->sy_symbol.ost_entry.n_numaux;
609 unsigned int i;
610
611 /* Turn any symbols with register attributes into abs symbols */
612 if (S_GET_SEGMENT (symbolP) == SEG_REGISTER)
613 {
614 S_SET_SEGMENT (symbolP, SEG_ABSOLUTE);
615 }
616 /* At the same time, relocate all symbols to their output value */
617
618 S_SET_VALUE (symbolP,
619 segment_info[S_GET_SEGMENT (symbolP)].scnhdr.s_paddr
620 + S_GET_VALUE (symbolP));
621
622 where += bfd_coff_swap_sym_out (abfd, &symbolP->sy_symbol.ost_entry,
623 where);
624
625 for (i = 0; i < numaux; i++)
626 {
627 where += bfd_coff_swap_aux_out (abfd,
628 &symbolP->sy_symbol.ost_auxent[i],
629 S_GET_DATA_TYPE (symbolP),
630 S_GET_STORAGE_CLASS (symbolP),
631 where);
632 }
633 return where;
634
635 }
636
637
638
639
640 void
641 obj_symbol_new_hook (symbolP)
642 symbolS *symbolP;
643 {
644 char underscore = 0; /* Symbol has leading _ */
645
646 /* Effective symbol */
647 /* Store the pointer in the offset. */
648 S_SET_ZEROES (symbolP, 0L);
649 S_SET_DATA_TYPE (symbolP, T_NULL);
650 S_SET_STORAGE_CLASS (symbolP, 0);
651 S_SET_NUMBER_AUXILIARY (symbolP, 0);
652 /* Additional information */
653 symbolP->sy_symbol.ost_flags = 0;
654 /* Auxiliary entries */
655 bzero ((char *) &symbolP->sy_symbol.ost_auxent[0], AUXESZ);
656
657 #ifdef STRIP_UNDERSCORE
658 /* Remove leading underscore at the beginning of the symbol.
659 * This is to be compatible with the standard librairies.
660 */
661 if (*S_GET_NAME (symbolP) == '_')
662 {
663 underscore = 1;
664 S_SET_NAME (symbolP, S_GET_NAME (symbolP) + 1);
665 } /* strip underscore */
666 #endif /* STRIP_UNDERSCORE */
667
668 if (S_IS_STRING (symbolP))
669 SF_SET_STRING (symbolP);
670 if (!underscore && S_IS_LOCAL (symbolP))
671 SF_SET_LOCAL (symbolP);
672
673 return;
674 } /* obj_symbol_new_hook() */
675
676 /* stack stuff */
677 stack *
678 stack_init (chunk_size, element_size)
679 unsigned long chunk_size;
680 unsigned long element_size;
681 {
682 stack *st;
683
684 if ((st = (stack *) malloc (sizeof (stack))) == (stack *) 0)
685 return (stack *) 0;
686 if ((st->data = malloc (chunk_size)) == (char *) 0)
687 {
688 free (st);
689 return (stack *) 0;
690 }
691 st->pointer = 0;
692 st->size = chunk_size;
693 st->chunk_size = chunk_size;
694 st->element_size = element_size;
695 return st;
696 } /* stack_init() */
697
698 void
699 stack_delete (st)
700 stack *st;
701 {
702 free (st->data);
703 free (st);
704 }
705
706 char *
707 stack_push (st, element)
708 stack *st;
709 char *element;
710 {
711 if (st->pointer + st->element_size >= st->size)
712 {
713 st->size += st->chunk_size;
714 if ((st->data = xrealloc (st->data, st->size)) == (char *) 0)
715 return (char *) 0;
716 }
717 memcpy (st->data + st->pointer, element, st->element_size);
718 st->pointer += st->element_size;
719 return st->data + st->pointer;
720 } /* stack_push() */
721
722 char *
723 stack_pop (st)
724 stack *st;
725 {
726 if ((st->pointer -= st->element_size) < 0)
727 {
728 st->pointer = 0;
729 return (char *) 0;
730 }
731
732 return st->data + st->pointer;
733 }
734
735 char *
736 stack_top (st)
737 stack *st;
738 {
739 return st->data + st->pointer - st->element_size;
740 }
741
742
743 /*
744 * Handle .ln directives.
745 */
746
747 static void
748 obj_coff_ln ()
749 {
750 int l;
751
752 if (def_symbol_in_progress != NULL)
753 {
754 as_warn (".ln pseudo-op inside .def/.endef: ignored.");
755 demand_empty_rest_of_line ();
756 return;
757 } /* wrong context */
758
759 c_line_new (0,
760 obstack_next_free (&frags) - frag_now->fr_literal,
761 l = get_absolute_expression (),
762 frag_now);
763 #ifndef NO_LISTING
764 {
765 extern int listing;
766
767 if (listing)
768 {
769 listing_source_line (l + line_base - 1);
770 }
771
772 }
773 #endif
774 demand_empty_rest_of_line ();
775 return;
776 } /* obj_coff_line() */
777
778 /*
779 * def()
780 *
781 * Handle .def directives.
782 *
783 * One might ask : why can't we symbol_new if the symbol does not
784 * already exist and fill it with debug information. Because of
785 * the C_EFCN special symbol. It would clobber the value of the
786 * function symbol before we have a chance to notice that it is
787 * a C_EFCN. And a second reason is that the code is more clear this
788 * way. (at least I think it is :-).
789 *
790 */
791
792 #define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';')
793 #define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \
794 *input_line_pointer == '\t') \
795 input_line_pointer++;
796
797 static void
798 DEFUN (obj_coff_def, (what),
799 int what)
800 {
801 char name_end; /* Char after the end of name */
802 char *symbol_name; /* Name of the debug symbol */
803 char *symbol_name_copy; /* Temporary copy of the name */
804 unsigned int symbol_name_length;
805 /*$char* directiveP;$ *//* Name of the pseudo opcode */
806 /*$char directive[MAX_DIRECTIVE];$ *//* Backup of the directive */
807 /*$char end = 0;$ *//* If 1, stop parsing */
808
809 if (def_symbol_in_progress != NULL)
810 {
811 as_warn (".def pseudo-op used inside of .def/.endef: ignored.");
812 demand_empty_rest_of_line ();
813 return;
814 } /* if not inside .def/.endef */
815
816 SKIP_WHITESPACES ();
817
818 def_symbol_in_progress = (symbolS *) obstack_alloc (&notes, sizeof (*def_symbol_in_progress));
819 bzero (def_symbol_in_progress, sizeof (*def_symbol_in_progress));
820
821 symbol_name = input_line_pointer;
822 name_end = get_symbol_end ();
823 symbol_name_length = strlen (symbol_name);
824 symbol_name_copy = xmalloc (symbol_name_length + 1);
825 strcpy (symbol_name_copy, symbol_name);
826
827 /* Initialize the new symbol */
828 #ifdef STRIP_UNDERSCORE
829 S_SET_NAME (def_symbol_in_progress, (*symbol_name_copy == '_'
830 ? symbol_name_copy + 1
831 : symbol_name_copy));
832 #else /* STRIP_UNDERSCORE */
833 S_SET_NAME (def_symbol_in_progress, symbol_name_copy);
834 #endif /* STRIP_UNDERSCORE */
835 /* free(symbol_name_copy); */
836 def_symbol_in_progress->sy_name_offset = ~0;
837 def_symbol_in_progress->sy_number = ~0;
838 def_symbol_in_progress->sy_frag = &zero_address_frag;
839
840 if (S_IS_STRING (def_symbol_in_progress))
841 {
842 SF_SET_STRING (def_symbol_in_progress);
843 } /* "long" name */
844
845 *input_line_pointer = name_end;
846
847 demand_empty_rest_of_line ();
848 return;
849 } /* obj_coff_def() */
850
851 unsigned int dim_index;
852 static void
853 DEFUN_VOID (obj_coff_endef)
854 {
855 symbolS *symbolP = 0;
856 /* DIM BUG FIX sac@cygnus.com */
857 dim_index = 0;
858 if (def_symbol_in_progress == NULL)
859 {
860 as_warn (".endef pseudo-op used outside of .def/.endef: ignored.");
861 demand_empty_rest_of_line ();
862 return;
863 } /* if not inside .def/.endef */
864
865 /* Set the section number according to storage class. */
866 switch (S_GET_STORAGE_CLASS (def_symbol_in_progress))
867 {
868 case C_STRTAG:
869 case C_ENTAG:
870 case C_UNTAG:
871 SF_SET_TAG (def_symbol_in_progress);
872 /* intentional fallthrough */
873 case C_FILE:
874 case C_TPDEF:
875 SF_SET_DEBUG (def_symbol_in_progress);
876 S_SET_SEGMENT (def_symbol_in_progress, SEG_DEBUG);
877 break;
878
879 case C_EFCN:
880 SF_SET_LOCAL (def_symbol_in_progress); /* Do not emit this symbol. */
881 /* intentional fallthrough */
882 case C_BLOCK:
883 SF_SET_PROCESS (def_symbol_in_progress); /* Will need processing before writing */
884 /* intentional fallthrough */
885 case C_FCN:
886 S_SET_SEGMENT (def_symbol_in_progress, SEG_E0);
887
888 if (def_symbol_in_progress->sy_symbol.ost_entry._n._n_nptr[1][1] == 'b'
889 && def_symbol_in_progress->sy_symbol.ost_entry._n._n_nptr[1][2] == 'f')
890 { /* .bf */
891 if (function_lineoff < 0)
892 {
893 fprintf (stderr, "`.bf' symbol without preceding function\n");
894 } /* missing function symbol */
895 SA_GET_SYM_LNNOPTR (last_line_symbol) = function_lineoff;
896
897 SF_SET_PROCESS (last_line_symbol);
898 function_lineoff = -1;
899 }
900 break;
901
902 #ifdef C_AUTOARG
903 case C_AUTOARG:
904 #endif /* C_AUTOARG */
905 case C_AUTO:
906 case C_REG:
907 case C_MOS:
908 case C_MOE:
909 case C_MOU:
910 case C_ARG:
911 case C_REGPARM:
912 case C_FIELD:
913 case C_EOS:
914 SF_SET_DEBUG (def_symbol_in_progress);
915 S_SET_SEGMENT (def_symbol_in_progress, SEG_ABSOLUTE);
916 break;
917
918 case C_EXT:
919 case C_STAT:
920 case C_LABEL:
921 /* Valid but set somewhere else (s_comm, s_lcomm, colon) */
922 break;
923
924 case C_USTATIC:
925 case C_EXTDEF:
926 case C_ULABEL:
927 as_warn ("unexpected storage class %d", S_GET_STORAGE_CLASS (def_symbol_in_progress));
928 break;
929 } /* switch on storage class */
930
931 /* Now that we have built a debug symbol, try to
932 find if we should merge with an existing symbol
933 or not. If a symbol is C_EFCN or SEG_ABSOLUTE or
934 untagged SEG_DEBUG it never merges. */
935
936 /* Two cases for functions. Either debug followed
937 by definition or definition followed by debug.
938 For definition first, we will merge the debug
939 symbol into the definition. For debug first, the
940 lineno entry MUST point to the definition
941 function or else it will point off into space
942 when crawl_symbols() merges the debug
943 symbol into the real symbol. Therefor, let's
944 presume the debug symbol is a real function
945 reference. */
946
947 /* FIXME-SOON If for some reason the definition
948 label/symbol is never seen, this will probably
949 leave an undefined symbol at link time. */
950
951 if (S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_EFCN
952 || (S_GET_SEGMENT (def_symbol_in_progress) == SEG_DEBUG
953 && !SF_GET_TAG (def_symbol_in_progress))
954 || S_GET_SEGMENT (def_symbol_in_progress) == SEG_ABSOLUTE
955 || (symbolP = symbol_find_base (S_GET_NAME (def_symbol_in_progress), DO_NOT_STRIP)) == NULL)
956 {
957
958 symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
959
960 }
961 else
962 {
963 /* This symbol already exists, merge the
964 newly created symbol into the old one.
965 This is not mandatory. The linker can
966 handle duplicate symbols correctly. But I
967 guess that it save a *lot* of space if
968 the assembly file defines a lot of
969 symbols. [loic] */
970
971 /* The debug entry (def_symbol_in_progress)
972 is merged into the previous definition. */
973
974 c_symbol_merge (def_symbol_in_progress, symbolP);
975 /* FIXME-SOON Should *def_symbol_in_progress be free'd? xoxorich. */
976 def_symbol_in_progress = symbolP;
977
978 if (SF_GET_FUNCTION (def_symbol_in_progress)
979 || SF_GET_TAG (def_symbol_in_progress))
980 {
981 /* For functions, and tags, the symbol *must* be where the debug symbol
982 appears. Move the existing symbol to the current place. */
983 /* If it already is at the end of the symbol list, do nothing */
984 if (def_symbol_in_progress != symbol_lastP)
985 {
986 symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
987 symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
988 } /* if not already in place */
989 } /* if function */
990 } /* normal or mergable */
991
992 if (SF_GET_TAG (def_symbol_in_progress)
993 && symbol_find_base (S_GET_NAME (def_symbol_in_progress), DO_NOT_STRIP) == NULL)
994 {
995 tag_insert (S_GET_NAME (def_symbol_in_progress), def_symbol_in_progress);
996 } /* If symbol is a {structure,union} tag, associate symbol to its name. */
997
998 if (SF_GET_FUNCTION (def_symbol_in_progress))
999 {
1000 know (sizeof (def_symbol_in_progress) <= sizeof (long));
1001 function_lineoff
1002 = c_line_new (def_symbol_in_progress, 0, 0, &zero_address_frag);
1003
1004
1005
1006 SF_SET_PROCESS (def_symbol_in_progress);
1007
1008 if (symbolP == NULL)
1009 {
1010 /* That is, if this is the first
1011 time we've seen the function... */
1012 symbol_table_insert (def_symbol_in_progress);
1013 } /* definition follows debug */
1014 } /* Create the line number entry pointing to the function being defined */
1015
1016 def_symbol_in_progress = NULL;
1017 demand_empty_rest_of_line ();
1018 return;
1019 } /* obj_coff_endef() */
1020
1021 static void
1022 DEFUN_VOID (obj_coff_dim)
1023 {
1024 register int dim_index;
1025
1026 if (def_symbol_in_progress == NULL)
1027 {
1028 as_warn (".dim pseudo-op used outside of .def/.endef: ignored.");
1029 demand_empty_rest_of_line ();
1030 return;
1031 } /* if not inside .def/.endef */
1032
1033 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
1034
1035 for (dim_index = 0; dim_index < DIMNUM; dim_index++)
1036 {
1037 SKIP_WHITESPACES ();
1038 SA_SET_SYM_DIMEN (def_symbol_in_progress, dim_index, get_absolute_expression ());
1039
1040 switch (*input_line_pointer)
1041 {
1042
1043 case ',':
1044 input_line_pointer++;
1045 break;
1046
1047 default:
1048 as_warn ("badly formed .dim directive ignored");
1049 /* intentional fallthrough */
1050 case '\n':
1051 case ';':
1052 dim_index = DIMNUM;
1053 break;
1054 } /* switch on following character */
1055 } /* for each dimension */
1056
1057 demand_empty_rest_of_line ();
1058 return;
1059 } /* obj_coff_dim() */
1060
1061 static void
1062 obj_coff_line ()
1063 {
1064 int this_base;
1065
1066 if (def_symbol_in_progress == NULL)
1067 {
1068 obj_coff_ln ();
1069 return;
1070 } /* if it looks like a stabs style line */
1071
1072 this_base = get_absolute_expression ();
1073 if (this_base > line_base)
1074 {
1075 line_base = this_base;
1076 }
1077
1078
1079 #ifndef NO_LISTING
1080 {
1081 extern int listing;
1082 if (listing && 0)
1083 {
1084 listing_source_line (line_base);
1085 }
1086 }
1087 #endif
1088 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
1089 SA_SET_SYM_LNNO (def_symbol_in_progress, line_base);
1090
1091 demand_empty_rest_of_line ();
1092 return;
1093 } /* obj_coff_line() */
1094
1095 static void
1096 obj_coff_size ()
1097 {
1098 if (def_symbol_in_progress == NULL)
1099 {
1100 as_warn (".size pseudo-op used outside of .def/.endef ignored.");
1101 demand_empty_rest_of_line ();
1102 return;
1103 } /* if not inside .def/.endef */
1104
1105 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
1106 SA_SET_SYM_SIZE (def_symbol_in_progress, get_absolute_expression ());
1107 demand_empty_rest_of_line ();
1108 return;
1109 } /* obj_coff_size() */
1110
1111 static void
1112 obj_coff_scl ()
1113 {
1114 if (def_symbol_in_progress == NULL)
1115 {
1116 as_warn (".scl pseudo-op used outside of .def/.endef ignored.");
1117 demand_empty_rest_of_line ();
1118 return;
1119 } /* if not inside .def/.endef */
1120
1121 S_SET_STORAGE_CLASS (def_symbol_in_progress, get_absolute_expression ());
1122 demand_empty_rest_of_line ();
1123 return;
1124 } /* obj_coff_scl() */
1125
1126 static void
1127 obj_coff_tag ()
1128 {
1129 char *symbol_name;
1130 char name_end;
1131
1132 if (def_symbol_in_progress == NULL)
1133 {
1134 as_warn (".tag pseudo-op used outside of .def/.endef ignored.");
1135 demand_empty_rest_of_line ();
1136 return;
1137 } /* if not inside .def/.endef */
1138
1139 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
1140 symbol_name = input_line_pointer;
1141 name_end = get_symbol_end ();
1142
1143 /* Assume that the symbol referred to by .tag is always defined. */
1144 /* This was a bad assumption. I've added find_or_make. xoxorich. */
1145 SA_SET_SYM_TAGNDX (def_symbol_in_progress, (long) tag_find_or_make (symbol_name));
1146 if (SA_GET_SYM_TAGNDX (def_symbol_in_progress) == 0L)
1147 {
1148 as_warn ("tag not found for .tag %s", symbol_name);
1149 } /* not defined */
1150
1151 SF_SET_TAGGED (def_symbol_in_progress);
1152 *input_line_pointer = name_end;
1153
1154 demand_empty_rest_of_line ();
1155 return;
1156 } /* obj_coff_tag() */
1157
1158 static void
1159 obj_coff_type ()
1160 {
1161 if (def_symbol_in_progress == NULL)
1162 {
1163 as_warn (".type pseudo-op used outside of .def/.endef ignored.");
1164 demand_empty_rest_of_line ();
1165 return;
1166 } /* if not inside .def/.endef */
1167
1168 S_SET_DATA_TYPE (def_symbol_in_progress, get_absolute_expression ());
1169
1170 if (ISFCN (S_GET_DATA_TYPE (def_symbol_in_progress)) &&
1171 S_GET_STORAGE_CLASS (def_symbol_in_progress) != C_TPDEF)
1172 {
1173 SF_SET_FUNCTION (def_symbol_in_progress);
1174 } /* is a function */
1175
1176 demand_empty_rest_of_line ();
1177 return;
1178 } /* obj_coff_type() */
1179
1180 static void
1181 obj_coff_val ()
1182 {
1183 if (def_symbol_in_progress == NULL)
1184 {
1185 as_warn (".val pseudo-op used outside of .def/.endef ignored.");
1186 demand_empty_rest_of_line ();
1187 return;
1188 } /* if not inside .def/.endef */
1189
1190 if (is_name_beginner (*input_line_pointer))
1191 {
1192 char *symbol_name = input_line_pointer;
1193 char name_end = get_symbol_end ();
1194
1195 if (!strcmp (symbol_name, "."))
1196 {
1197 def_symbol_in_progress->sy_frag = frag_now;
1198 S_SET_VALUE (def_symbol_in_progress, obstack_next_free (&frags) - frag_now->fr_literal);
1199 /* If the .val is != from the .def (e.g. statics) */
1200 }
1201 else if (strcmp (S_GET_NAME (def_symbol_in_progress), symbol_name))
1202 {
1203 def_symbol_in_progress->sy_forward = symbol_find_or_make (symbol_name);
1204
1205 /* If the segment is undefined when the forward
1206 reference is solved, then copy the segment id
1207 from the forward symbol. */
1208 SF_SET_GET_SEGMENT (def_symbol_in_progress);
1209 }
1210 /* Otherwise, it is the name of a non debug symbol and its value will be calculated later. */
1211 *input_line_pointer = name_end;
1212 }
1213 else
1214 {
1215 S_SET_VALUE (def_symbol_in_progress, get_absolute_expression ());
1216 } /* if symbol based */
1217
1218 demand_empty_rest_of_line ();
1219 return;
1220 } /* obj_coff_val() */
1221
1222 /*
1223 * Maintain a list of the tagnames of the structres.
1224 */
1225
1226 static void
1227 tag_init ()
1228 {
1229 tag_hash = hash_new ();
1230 return;
1231 } /* tag_init() */
1232
1233 static void
1234 tag_insert (name, symbolP)
1235 char *name;
1236 symbolS *symbolP;
1237 {
1238 register char *error_string;
1239
1240 if (*(error_string = hash_jam (tag_hash, name, (char *) symbolP)))
1241 {
1242 as_fatal ("Inserting \"%s\" into structure table failed: %s",
1243 name, error_string);
1244 }
1245 return;
1246 } /* tag_insert() */
1247
1248 static symbolS *
1249 tag_find_or_make (name)
1250 char *name;
1251 {
1252 symbolS *symbolP;
1253
1254 if ((symbolP = tag_find (name)) == NULL)
1255 {
1256 symbolP = symbol_new (name,
1257 SEG_UNKNOWN,
1258 0,
1259 &zero_address_frag);
1260
1261 tag_insert (S_GET_NAME (symbolP), symbolP);
1262 symbol_table_insert (symbolP);
1263 } /* not found */
1264
1265 return (symbolP);
1266 } /* tag_find_or_make() */
1267
1268 static symbolS *
1269 tag_find (name)
1270 char *name;
1271 {
1272 #ifdef STRIP_UNDERSCORE
1273 if (*name == '_')
1274 name++;
1275 #endif /* STRIP_UNDERSCORE */
1276 return ((symbolS *) hash_find (tag_hash, name));
1277 } /* tag_find() */
1278
1279 void
1280 obj_read_begin_hook ()
1281 {
1282 /* These had better be the same. Usually 18 bytes. */
1283 #ifndef BFD_HEADERS
1284 know (sizeof (SYMENT) == sizeof (AUXENT));
1285 know (SYMESZ == AUXESZ);
1286 #endif
1287 tag_init ();
1288
1289 return;
1290 } /* obj_read_begin_hook() */
1291
1292 /* This function runs through the symbol table and puts all the
1293 externals onto another chain */
1294
1295 /* The chain of externals */
1296 symbolS *symbol_externP = NULL;
1297 symbolS *symbol_extern_lastP = NULL;
1298
1299 stack *block_stack;
1300 symbolS *last_functionP = NULL;
1301 symbolS *last_tagP;
1302
1303
1304 static unsigned int
1305 DEFUN_VOID (yank_symbols)
1306 {
1307 symbolS *symbolP;
1308 unsigned int symbol_number = 0;
1309
1310 for (symbolP = symbol_rootP;
1311 symbolP;
1312 symbolP = symbolP ? symbol_next (symbolP) : symbol_rootP)
1313 {
1314 if (!SF_GET_DEBUG (symbolP))
1315 {
1316 /* Debug symbols do not need all this rubbish */
1317 symbolS *real_symbolP;
1318
1319 /* L* and C_EFCN symbols never merge. */
1320 if (!SF_GET_LOCAL (symbolP)
1321 && (real_symbolP = symbol_find_base (S_GET_NAME (symbolP), DO_NOT_STRIP))
1322 && real_symbolP != symbolP)
1323 {
1324 /* FIXME-SOON: where do dups come from?
1325 Maybe tag references before definitions? xoxorich. */
1326 /* Move the debug data from the debug symbol to the
1327 real symbol. Do NOT do the oposite (i.e. move from
1328 real symbol to debug symbol and remove real symbol from the
1329 list.) Because some pointers refer to the real symbol
1330 whereas no pointers refer to the debug symbol. */
1331 c_symbol_merge (symbolP, real_symbolP);
1332 /* Replace the current symbol by the real one */
1333 /* The symbols will never be the last or the first
1334 because : 1st symbol is .file and 3 last symbols are
1335 .text, .data, .bss */
1336 symbol_remove (real_symbolP, &symbol_rootP, &symbol_lastP);
1337 symbol_insert (real_symbolP, symbolP, &symbol_rootP, &symbol_lastP);
1338 symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
1339 symbolP = real_symbolP;
1340 } /* if not local but dup'd */
1341
1342 if (flagseen['R'] && (S_GET_SEGMENT (symbolP) == SEG_E1))
1343 {
1344 S_SET_SEGMENT (symbolP, SEG_E0);
1345 } /* push data into text */
1346
1347 S_SET_VALUE (symbolP,
1348 S_GET_VALUE (symbolP) + symbolP->sy_frag->fr_address);
1349
1350 if (!S_IS_DEFINED (symbolP) && !SF_GET_LOCAL (symbolP))
1351 {
1352 S_SET_EXTERNAL (symbolP);
1353 }
1354 else if (S_GET_STORAGE_CLASS (symbolP) == C_NULL)
1355 {
1356 if (S_GET_SEGMENT (symbolP) == SEG_E0)
1357 {
1358 S_SET_STORAGE_CLASS (symbolP, C_LABEL);
1359 }
1360 else
1361 {
1362 S_SET_STORAGE_CLASS (symbolP, C_STAT);
1363 }
1364 }
1365
1366 /* Mainly to speed up if not -g */
1367 if (SF_GET_PROCESS (symbolP))
1368 {
1369 /* Handle the nested blocks auxiliary info. */
1370 if (S_GET_STORAGE_CLASS (symbolP) == C_BLOCK)
1371 {
1372 if (!strcmp (S_GET_NAME (symbolP), ".bb"))
1373 stack_push (block_stack, (char *) &symbolP);
1374 else
1375 { /* .eb */
1376 register symbolS *begin_symbolP;
1377 begin_symbolP = *(symbolS **) stack_pop (block_stack);
1378 if (begin_symbolP == (symbolS *) 0)
1379 as_warn ("mismatched .eb");
1380 else
1381 SA_SET_SYM_ENDNDX (begin_symbolP, symbol_number + 2);
1382 }
1383 }
1384 /* If we are able to identify the type of a function, and we
1385 are out of a function (last_functionP == 0) then, the
1386 function symbol will be associated with an auxiliary
1387 entry. */
1388 if (last_functionP == (symbolS *) 0 &&
1389 SF_GET_FUNCTION (symbolP))
1390 {
1391 last_functionP = symbolP;
1392
1393 if (S_GET_NUMBER_AUXILIARY (symbolP) < 1)
1394 {
1395 S_SET_NUMBER_AUXILIARY (symbolP, 1);
1396 } /* make it at least 1 */
1397
1398 /* Clobber possible stale .dim information. */
1399 #if 0
1400 /* Iffed out by steve - this fries the lnnoptr info too */
1401 bzero (symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen,
1402 sizeof (symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen));
1403 #endif
1404 }
1405 /* The C_FCN doesn't need any additional information.
1406 I don't even know if this is needed for sdb. But the
1407 standard assembler generates it, so...
1408 */
1409 if (S_GET_STORAGE_CLASS (symbolP) == C_EFCN)
1410 {
1411 if (last_functionP == (symbolS *) 0)
1412 as_fatal ("C_EFCN symbol out of scope");
1413 SA_SET_SYM_FSIZE (last_functionP,
1414 (long) (S_GET_VALUE (symbolP) -
1415 S_GET_VALUE (last_functionP)));
1416 SA_SET_SYM_ENDNDX (last_functionP, symbol_number);
1417 last_functionP = (symbolS *) 0;
1418 }
1419 }
1420 }
1421 else if (SF_GET_TAG (symbolP))
1422 {
1423 /* First descriptor of a structure must point to
1424 the first slot after the structure description. */
1425 last_tagP = symbolP;
1426
1427 }
1428 else if (S_GET_STORAGE_CLASS (symbolP) == C_EOS)
1429 {
1430 /* +2 take in account the current symbol */
1431 SA_SET_SYM_ENDNDX (last_tagP, symbol_number + 2);
1432 }
1433 else if (S_GET_STORAGE_CLASS (symbolP) == C_FILE)
1434 {
1435 if (S_GET_VALUE (symbolP))
1436 {
1437 S_SET_VALUE ((symbolS *) S_GET_VALUE (symbolP), symbol_number);
1438 S_SET_VALUE (symbolP, 0);
1439 } /* no one points at the first .file symbol */
1440 } /* if debug or tag or eos or file */
1441
1442 /* We must put the external symbols apart. The loader
1443 does not bomb if we do not. But the references in
1444 the endndx field for a .bb symbol are not corrected
1445 if an external symbol is removed between .bb and .be.
1446 I.e in the following case :
1447 [20] .bb endndx = 22
1448 [21] foo external
1449 [22] .be
1450 ld will move the symbol 21 to the end of the list but
1451 endndx will still be 22 instead of 21. */
1452
1453
1454 if (SF_GET_LOCAL (symbolP))
1455 {
1456 /* remove C_EFCN and LOCAL (L...) symbols */
1457 /* next pointer remains valid */
1458 symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
1459
1460 }
1461 else if (!S_IS_DEFINED (symbolP)
1462 && !S_IS_DEBUG (symbolP)
1463 && !SF_GET_STATICS (symbolP) &&
1464 S_GET_STORAGE_CLASS (symbolP) == C_EXT)
1465 { /* C_EXT && !SF_GET_FUNCTION(symbolP)) */
1466 /* if external, Remove from the list */
1467 symbolS *hold = symbol_previous (symbolP);
1468
1469 symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
1470 symbol_clear_list_pointers (symbolP);
1471 symbol_append (symbolP, symbol_extern_lastP, &symbol_externP, &symbol_extern_lastP);
1472 symbolP = hold;
1473 }
1474 else
1475 {
1476 if (SF_GET_STRING (symbolP))
1477 {
1478 symbolP->sy_name_offset = string_byte_count;
1479 string_byte_count += strlen (S_GET_NAME (symbolP)) + 1;
1480 }
1481 else
1482 {
1483 symbolP->sy_name_offset = 0;
1484 } /* fix "long" names */
1485
1486 symbolP->sy_number = symbol_number;
1487 symbol_number += 1 + S_GET_NUMBER_AUXILIARY (symbolP);
1488 } /* if local symbol */
1489 } /* traverse the symbol list */
1490 return symbol_number;
1491
1492 }
1493
1494
1495 static unsigned int
1496 DEFUN_VOID (glue_symbols)
1497 {
1498 unsigned int symbol_number = 0;
1499 symbolS *symbolP;
1500 for (symbolP = symbol_externP; symbol_externP;)
1501 {
1502 symbolS *tmp = symbol_externP;
1503
1504 /* append */
1505 symbol_remove (tmp, &symbol_externP, &symbol_extern_lastP);
1506 symbol_append (tmp, symbol_lastP, &symbol_rootP, &symbol_lastP);
1507
1508 /* and process */
1509 if (SF_GET_STRING (tmp))
1510 {
1511 tmp->sy_name_offset = string_byte_count;
1512 string_byte_count += strlen (S_GET_NAME (tmp)) + 1;
1513 }
1514 else
1515 {
1516 tmp->sy_name_offset = 0;
1517 } /* fix "long" names */
1518
1519 tmp->sy_number = symbol_number;
1520 symbol_number += 1 + S_GET_NUMBER_AUXILIARY (tmp);
1521 } /* append the entire extern chain */
1522 return symbol_number;
1523
1524 }
1525
1526 static unsigned int
1527 DEFUN_VOID (tie_tags)
1528 {
1529 unsigned int symbol_number = 0;
1530
1531 symbolS *symbolP;
1532 for (symbolP = symbol_rootP; symbolP; symbolP =
1533 symbol_next (symbolP))
1534 {
1535 symbolP->sy_number = symbol_number;
1536
1537
1538
1539 if (SF_GET_TAGGED (symbolP))
1540 {
1541 SA_SET_SYM_TAGNDX
1542 (symbolP,
1543 ((symbolS *) SA_GET_SYM_TAGNDX (symbolP))->sy_number);
1544 }
1545
1546 symbol_number += 1 + S_GET_NUMBER_AUXILIARY (symbolP);
1547 }
1548 return symbol_number;
1549
1550 }
1551
1552 static void
1553 DEFUN (crawl_symbols, (headers, abfd),
1554 struct internal_filehdr *headers AND
1555 bfd * abfd)
1556 {
1557
1558 unsigned int i;
1559 unsigned int ptr = 0;
1560
1561
1562 symbolS *symbolP;
1563
1564 /* Initialize the stack used to keep track of the matching .bb .be */
1565
1566 block_stack = stack_init (512, sizeof (symbolS *));
1567 /* JF deal with forward references first... */
1568 for (symbolP = symbol_rootP;
1569 symbolP;
1570 symbolP = symbol_next (symbolP))
1571 {
1572
1573 if (symbolP->sy_forward)
1574 {
1575 S_SET_VALUE (symbolP, (S_GET_VALUE (symbolP)
1576 + S_GET_VALUE (symbolP->sy_forward)
1577 + symbolP->sy_forward->sy_frag->fr_address));
1578
1579 if (SF_GET_GET_SEGMENT (symbolP))
1580 {
1581 S_SET_SEGMENT (symbolP, S_GET_SEGMENT (symbolP->sy_forward));
1582 } /* forward segment also */
1583
1584 symbolP->sy_forward = 0;
1585 } /* if it has a forward reference */
1586 } /* walk the symbol chain */
1587
1588
1589 /* The symbol list should be ordered according to the following sequence
1590 * order :
1591 * . .file symbol
1592 * . debug entries for functions
1593 * . fake symbols for the sections, including.text .data and .bss
1594 * . defined symbols
1595 * . undefined symbols
1596 * But this is not mandatory. The only important point is to put the
1597 * undefined symbols at the end of the list.
1598 */
1599
1600 if (symbol_rootP == NULL
1601 || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
1602 {
1603 c_dot_file_symbol ("fake");
1604 }
1605 /* Is there a .file symbol ? If not insert one at the beginning. */
1606
1607 /*
1608 * Build up static symbols for the sections, they are filled in later
1609 */
1610
1611
1612 for (i = SEG_E0; i < SEG_E9; i++)
1613 {
1614 if (segment_info[i].scnhdr.s_name[0])
1615 {
1616 segment_info[i].dot =
1617 c_section_symbol (segment_info[i].scnhdr.s_name,
1618 i - SEG_E0 + 1);
1619
1620 }
1621 }
1622
1623
1624 /* Take all the externals out and put them into another chain */
1625 headers->f_nsyms = yank_symbols ();
1626 /* Take the externals and glue them onto the end.*/
1627 headers->f_nsyms += glue_symbols ();
1628
1629 headers->f_nsyms = tie_tags ();
1630 know (symbol_externP == NULL);
1631 know (symbol_extern_lastP == NULL);
1632
1633 return;
1634 }
1635
1636 /*
1637 * Find strings by crawling along symbol table chain.
1638 */
1639
1640 void
1641 DEFUN (w_strings, (where),
1642 char *where)
1643 {
1644 symbolS *symbolP;
1645
1646 /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
1647 md_number_to_chars (where, string_byte_count, sizeof (string_byte_count));
1648 where += sizeof (string_byte_count);
1649 for (symbolP = symbol_rootP;
1650 symbolP;
1651 symbolP = symbol_next (symbolP))
1652 {
1653 unsigned int size;
1654
1655 if (SF_GET_STRING (symbolP))
1656 {
1657 size = strlen (S_GET_NAME (symbolP)) + 1;
1658
1659 memcpy (where, S_GET_NAME (symbolP), size);
1660 where += size;
1661
1662 }
1663 }
1664
1665 }
1666
1667
1668
1669
1670
1671 static void
1672 DEFUN (do_linenos_for, (abfd, file_cursor),
1673 bfd * abfd AND
1674 unsigned long *file_cursor)
1675 {
1676 unsigned int idx;
1677
1678 for (idx = SEG_E0; idx < SEG_E9; idx++)
1679 {
1680 segment_info_type *s = segment_info + idx;
1681
1682
1683 if (s->scnhdr.s_nlnno != 0)
1684 {
1685 struct lineno_list *line_ptr;
1686
1687 struct external_lineno *buffer =
1688 (struct external_lineno *) xmalloc (s->scnhdr.s_nlnno * LINESZ);
1689
1690 struct external_lineno *dst = buffer;
1691
1692 /* Run through the table we've built and turn it into its external
1693 form, take this chance to remove duplicates */
1694
1695 for (line_ptr = s->lineno_list_head;
1696 line_ptr != (struct lineno_list *) NULL;
1697 line_ptr = line_ptr->next)
1698 {
1699
1700 if (line_ptr->line.l_lnno == 0)
1701 {
1702 /* Turn a pointer to a symbol into the symbols' index */
1703 line_ptr->line.l_addr.l_symndx =
1704 ((symbolS *) line_ptr->line.l_addr.l_symndx)->sy_number;
1705 }
1706 else
1707 {
1708 line_ptr->line.l_addr.l_paddr += ((struct frag *) (line_ptr->frag))->fr_address;
1709 }
1710
1711
1712 (void) bfd_coff_swap_lineno_out (abfd, &(line_ptr->line), dst);
1713 dst++;
1714
1715 }
1716
1717 s->scnhdr.s_lnnoptr = *file_cursor;
1718
1719 bfd_write (buffer, 1, s->scnhdr.s_nlnno * LINESZ, abfd);
1720 free (buffer);
1721
1722 *file_cursor += s->scnhdr.s_nlnno * LINESZ;
1723 }
1724 }
1725 }
1726
1727
1728 /* Now we run through the list of frag chains in a segment and
1729 make all the subsegment frags appear at the end of the
1730 list, as if the seg 0 was extra long */
1731
1732 static void
1733 DEFUN_VOID (remove_subsegs)
1734 {
1735 unsigned int i;
1736
1737 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
1738 {
1739 frchainS *head = segment_info[i].frchainP;
1740 fragS dummy;
1741 fragS *prev_frag = &dummy;
1742
1743 while (head && head->frch_seg == i)
1744 {
1745 prev_frag->fr_next = head->frch_root;
1746 prev_frag = head->frch_last;
1747 head = head->frch_next;
1748 }
1749 prev_frag->fr_next = 0;
1750 }
1751 }
1752
1753 int machine;
1754 int coff_flags;
1755 extern void
1756 DEFUN_VOID (write_object_file)
1757 {
1758 int i;
1759 struct frchain *frchain_ptr;
1760
1761 struct internal_filehdr filehdr;
1762 struct internal_aouthdr aouthdr;
1763 unsigned long file_cursor;
1764 bfd *abfd;
1765 unsigned int addr;
1766 abfd = bfd_openw (out_file_name, TARGET_FORMAT);
1767
1768
1769 if (abfd == 0)
1770 {
1771 as_perror ("FATAL: Can't create %s", out_file_name);
1772 exit (42);
1773 }
1774 bfd_set_format (abfd, bfd_object);
1775 bfd_set_arch_mach (abfd, BFD_ARCH, machine);
1776
1777
1778
1779 string_byte_count = 4;
1780
1781 for (frchain_ptr = frchain_root;
1782 frchain_ptr != (struct frchain *) NULL;
1783 frchain_ptr = frchain_ptr->frch_next)
1784 {
1785 /* Run through all the sub-segments and align them up. Also close any
1786 open frags. We tack a .fill onto the end of the frag chain so
1787 that any .align's size can be worked by looking at the next
1788 frag */
1789
1790 subseg_new (frchain_ptr->frch_seg, frchain_ptr->frch_subseg);
1791 #define SUB_SEGMENT_ALIGN 1
1792 frag_align (SUB_SEGMENT_ALIGN, 0);
1793 frag_wane (frag_now);
1794 frag_now->fr_fix = 0;
1795 know (frag_now->fr_next == NULL);
1796 }
1797
1798
1799 remove_subsegs ();
1800
1801
1802 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
1803 {
1804 relax_segment (segment_info[i].frchainP->frch_root, i);
1805 }
1806
1807 filehdr.f_nscns = 0;
1808
1809 /* Find out how big the sections are, and set the addresses. */
1810 addr = 0;
1811 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
1812 {
1813 segment_info[i].scnhdr.s_paddr = addr;
1814 segment_info[i].scnhdr.s_vaddr = addr;
1815
1816 if (segment_info[i].scnhdr.s_name[0])
1817 {
1818 filehdr.f_nscns++;
1819 }
1820
1821 #ifndef ZERO_BASED_SEGMENTS
1822 /* See the comment at the previous ZERO_BASED_SEGMENTS check. */
1823 if (i == SEG_E2)
1824 {
1825 /* This is a special case, we leave the size alone, which
1826 will have been made up from all and any lcomms seen. */
1827 addr += segment_info[i].scnhdr.s_size;
1828 }
1829 else
1830 {
1831 addr += size_section (abfd, i);
1832 }
1833 #endif
1834 }
1835
1836
1837
1838 /* Turn the gas native symbol table shape into a coff symbol table */
1839 crawl_symbols (&filehdr, abfd);
1840 #if !defined(TC_H8300) && !defined(TC_Z8K)
1841 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
1842 {
1843 fixup_mdeps (segment_info[i].frchainP->frch_root);
1844 fixup_segment (segment_info[i].fix_root, i);
1845 }
1846 #endif
1847
1848 file_cursor = FILHSZ + SCNHSZ * filehdr.f_nscns;
1849
1850 bfd_seek (abfd, file_cursor, 0);
1851
1852
1853 do_relocs_for (abfd, &file_cursor);
1854
1855 do_linenos_for (abfd, &file_cursor);
1856
1857
1858 /* Plant the data */
1859
1860 fill_section (abfd, &filehdr, &file_cursor);
1861
1862
1863
1864 filehdr.f_magic = COFF_MAGIC;
1865 filehdr.f_timdat = time (0);
1866 filehdr.f_flags = COFF_FLAGS | coff_flags;
1867
1868 if (!had_lineno)
1869 {
1870 filehdr.f_flags |= F_LNNO;
1871 }
1872 if (!had_reloc)
1873 {
1874 filehdr.f_flags |= F_RELFLG;
1875 }
1876
1877
1878
1879
1880
1881
1882
1883 {
1884
1885 unsigned int symtable_size = filehdr.f_nsyms * SYMESZ;
1886 char *buffer1 = malloc (symtable_size + string_byte_count + 4);
1887 char *ptr = buffer1;
1888 filehdr.f_symptr = bfd_tell (abfd);
1889 w_symbols (abfd, buffer1, symbol_rootP);
1890 w_strings (buffer1 + symtable_size);
1891 bfd_write (buffer1, 1, symtable_size + string_byte_count + 4, abfd);
1892 free (buffer1);
1893
1894 }
1895 coff_header_append (abfd, &filehdr, &aouthdr);
1896
1897 if (bfd_close_all_done (abfd) == false)
1898 as_fatal ("Can't close %s: %s", out_file_name,
1899 bfd_errmsg (bfd_error));
1900 }
1901
1902
1903 static void
1904 DEFUN (change_to_section, (name, len, exp),
1905 char *name AND
1906 unsigned int len AND
1907 unsigned int exp)
1908 {
1909 unsigned int i;
1910 /* Find out if we've already got a section of this name etc */
1911 for (i = SEG_E0; i < SEG_E9 && segment_info[i].scnhdr.s_name[0]; i++)
1912 {
1913 if (strncmp (segment_info[i].scnhdr.s_name, name, len) == 0)
1914 {
1915 subseg_new (i, exp);
1916 return;
1917
1918 }
1919 }
1920 /* No section, add one */
1921 strncpy (segment_info[i].scnhdr.s_name, name, 8);
1922 subseg_new (i, exp);
1923 }
1924
1925 void
1926 DEFUN_VOID (obj_coff_section)
1927 {
1928 /* Strip out the section name */
1929 char *section_name;
1930 char *section_name_end;
1931 char c;
1932
1933 unsigned int len;
1934 unsigned int exp;
1935
1936 section_name = input_line_pointer;
1937 c = get_symbol_end ();
1938 section_name_end = input_line_pointer;
1939
1940 len = section_name_end - section_name;
1941 input_line_pointer++;
1942 SKIP_WHITESPACE ();
1943 if (c == ',')
1944 {
1945 exp = get_absolute_expression ();
1946 }
1947 else if (*input_line_pointer == ',')
1948 {
1949
1950 input_line_pointer++;
1951 exp = get_absolute_expression ();
1952 }
1953 else
1954 {
1955 exp = 0;
1956 }
1957
1958 change_to_section (section_name, len, exp);
1959 *section_name_end = c;
1960
1961 }
1962
1963
1964 static void
1965 obj_coff_text ()
1966 {
1967 change_to_section (".text", 5, get_absolute_expression ());
1968 }
1969
1970
1971 static void
1972 obj_coff_data ()
1973 {
1974 change_to_section (".data", 5, get_absolute_expression ());
1975 }
1976
1977 void
1978 c_symbol_merge (debug, normal)
1979 symbolS *debug;
1980 symbolS *normal;
1981 {
1982 S_SET_DATA_TYPE (normal, S_GET_DATA_TYPE (debug));
1983 S_SET_STORAGE_CLASS (normal, S_GET_STORAGE_CLASS (debug));
1984
1985 if (S_GET_NUMBER_AUXILIARY (debug) > S_GET_NUMBER_AUXILIARY (normal))
1986 {
1987 S_SET_NUMBER_AUXILIARY (normal, S_GET_NUMBER_AUXILIARY (debug));
1988 } /* take the most we have */
1989
1990 if (S_GET_NUMBER_AUXILIARY (debug) > 0)
1991 {
1992 memcpy ((char *) &normal->sy_symbol.ost_auxent[0], (char *) &debug->sy_symbol.ost_auxent[0], S_GET_NUMBER_AUXILIARY (debug) * AUXESZ);
1993 } /* Move all the auxiliary information */
1994
1995 /* Move the debug flags. */
1996 SF_SET_DEBUG_FIELD (normal, SF_GET_DEBUG_FIELD (debug));
1997 } /* c_symbol_merge() */
1998
1999 static int
2000 DEFUN (c_line_new, (symbol, paddr, line_number, frag),
2001 symbolS * symbol AND
2002 long paddr AND
2003 unsigned short line_number AND
2004 fragS * frag)
2005 {
2006 struct lineno_list *new_line =
2007 (struct lineno_list *) xmalloc (sizeof (struct lineno_list));
2008
2009 segment_info_type *s = segment_info + now_seg;
2010 new_line->line.l_lnno = line_number;
2011
2012 had_lineno = 1;
2013
2014 if (line_number == 0)
2015 {
2016 last_line_symbol = symbol;
2017 new_line->line.l_addr.l_symndx = (long) symbol;
2018 }
2019 else
2020 {
2021 new_line->line.l_addr.l_paddr = paddr;
2022 }
2023
2024 new_line->frag = (char *) frag;
2025 new_line->next = (struct lineno_list *) NULL;
2026
2027
2028 if (s->lineno_list_head == (struct lineno_list *) NULL)
2029 {
2030 s->lineno_list_head = new_line;
2031 }
2032 else
2033 {
2034 s->lineno_list_tail->next = new_line;
2035 }
2036 s->lineno_list_tail = new_line;
2037 return LINESZ * s->scnhdr.s_nlnno++;
2038 }
2039
2040 void
2041 c_dot_file_symbol (filename)
2042 char *filename;
2043 {
2044 symbolS *symbolP;
2045
2046 symbolP = symbol_new (".file",
2047 SEG_DEBUG,
2048 0,
2049 &zero_address_frag);
2050
2051 S_SET_STORAGE_CLASS (symbolP, C_FILE);
2052 S_SET_NUMBER_AUXILIARY (symbolP, 1);
2053 SA_SET_FILE_FNAME (symbolP, filename);
2054 #ifndef NO_LISTING
2055 {
2056 extern int listing;
2057 if (listing)
2058 {
2059 listing_source_file (filename);
2060 }
2061
2062 }
2063
2064 #endif
2065 SF_SET_DEBUG (symbolP);
2066 S_SET_VALUE (symbolP, (long) previous_file_symbol);
2067
2068 previous_file_symbol = symbolP;
2069
2070 /* Make sure that the symbol is first on the symbol chain */
2071 if (symbol_rootP != symbolP)
2072 {
2073 if (symbolP == symbol_lastP)
2074 {
2075 symbol_lastP = symbol_lastP->sy_previous;
2076 } /* if it was the last thing on the list */
2077
2078 symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
2079 symbol_insert (symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP);
2080 symbol_rootP = symbolP;
2081 } /* if not first on the list */
2082
2083 } /* c_dot_file_symbol() */
2084
2085 /*
2086 * Build a 'section static' symbol.
2087 */
2088
2089 symbolS *
2090 c_section_symbol (name, idx)
2091 char *name;
2092 int idx;
2093 {
2094 symbolS *symbolP;
2095
2096 symbolP = symbol_new (name, idx,
2097 0,
2098 &zero_address_frag);
2099
2100 S_SET_STORAGE_CLASS (symbolP, C_STAT);
2101 S_SET_NUMBER_AUXILIARY (symbolP, 1);
2102
2103 SF_SET_STATICS (symbolP);
2104
2105 return symbolP;
2106 } /* c_section_symbol() */
2107
2108 static void
2109 DEFUN (w_symbols, (abfd, where, symbol_rootP),
2110 bfd * abfd AND
2111 char *where AND
2112 symbolS * symbol_rootP)
2113 {
2114 symbolS *symbolP;
2115 unsigned int i;
2116
2117 /* First fill in those values we have only just worked out */
2118 for (i = SEG_E0; i < SEG_E9; i++)
2119 {
2120 symbolP = segment_info[i].dot;
2121 if (symbolP)
2122 {
2123
2124 SA_SET_SCN_SCNLEN (symbolP, segment_info[i].scnhdr.s_size);
2125 SA_SET_SCN_NRELOC (symbolP, segment_info[i].scnhdr.s_nreloc);
2126 SA_SET_SCN_NLINNO (symbolP, segment_info[i].scnhdr.s_nlnno);
2127
2128 }
2129 }
2130
2131 /*
2132 * Emit all symbols left in the symbol chain.
2133 */
2134 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
2135 {
2136 /* Used to save the offset of the name. It is used to point
2137 to the string in memory but must be a file offset. */
2138 register char *temp;
2139
2140 tc_coff_symbol_emit_hook (symbolP);
2141
2142 temp = S_GET_NAME (symbolP);
2143 if (SF_GET_STRING (symbolP))
2144 {
2145 S_SET_OFFSET (symbolP, symbolP->sy_name_offset);
2146 S_SET_ZEROES (symbolP, 0);
2147 }
2148 else
2149 {
2150 bzero (symbolP->sy_symbol.ost_entry.n_name, SYMNMLEN);
2151 strncpy (symbolP->sy_symbol.ost_entry.n_name, temp, SYMNMLEN);
2152 }
2153 where = symbol_to_chars (abfd, where, symbolP);
2154 S_SET_NAME (symbolP, temp);
2155 }
2156
2157 } /* w_symbols() */
2158
2159 static void
2160 DEFUN_VOID (obj_coff_lcomm)
2161 {
2162 char *name;
2163 char c;
2164 int temp;
2165 char *p;
2166 unsigned long vma;
2167
2168 symbolS *symbolP;
2169 name = input_line_pointer;
2170
2171
2172 c = get_symbol_end ();
2173 p = input_line_pointer;
2174 *p = c;
2175 SKIP_WHITESPACE ();
2176 if (*input_line_pointer != ',')
2177 {
2178 as_bad ("Expected comma after name");
2179 ignore_rest_of_line ();
2180 return;
2181 }
2182 if (*input_line_pointer == '\n')
2183 {
2184 as_bad ("Missing size expression");
2185 return;
2186 }
2187 input_line_pointer++;
2188 if ((temp = get_absolute_expression ()) < 0)
2189 {
2190 as_warn ("lcomm length (%d.) <0! Ignored.", temp);
2191 ignore_rest_of_line ();
2192 return;
2193 }
2194 *p = 0;
2195
2196 {
2197 /* Allocate zero static local data in the .data section now
2198 instead of the bss section as a symbol with a value */
2199 char *x;
2200 segT oldseg = now_seg;
2201 int oldsubseg = now_subseg;
2202
2203 subseg_new (SEG_DATA, 10);
2204 colon (name);
2205 frag_align (2, 0);
2206 record_alignment (SEG_DATA, 4);
2207 x = frag_var (rs_fill, 1, 1, (relax_substateT) 0, (symbolS *) 0,
2208 temp, (char *) 0);
2209 *x = 0;
2210
2211 subseg_new (oldseg, oldsubseg);
2212 }
2213 demand_empty_rest_of_line ();
2214 }
2215
2216 static void
2217 DEFUN (fixup_mdeps, (frags),
2218 fragS * frags)
2219 {
2220 while (frags)
2221 {
2222 switch (frags->fr_type)
2223 {
2224 case rs_align:
2225 case rs_org:
2226 frags->fr_type = rs_fill;
2227 frags->fr_offset =
2228 (frags->fr_next->fr_address - frags->fr_address - frags->fr_fix);
2229 break;
2230 case rs_machine_dependent:
2231 md_convert_frag (0, frags);
2232 break;
2233 default:
2234 ;
2235 }
2236 frags = frags->fr_next;
2237 }
2238
2239 }
2240
2241 #if 1
2242 static void
2243 DEFUN (fixup_segment, (fixP, this_segment_type),
2244 register fixS * fixP AND
2245 segT this_segment_type)
2246 {
2247 register symbolS *add_symbolP;
2248 register symbolS *sub_symbolP;
2249 register long add_number;
2250 register int size;
2251 register char *place;
2252 register long where;
2253 register char pcrel;
2254 register fragS *fragP;
2255 register segT add_symbol_segment = SEG_ABSOLUTE;
2256
2257
2258 for (; fixP; fixP = fixP->fx_next)
2259 {
2260 fragP = fixP->fx_frag;
2261 know (fragP);
2262 where = fixP->fx_where;
2263 place = fragP->fr_literal + where;
2264 size = fixP->fx_size;
2265 add_symbolP = fixP->fx_addsy;
2266 #ifdef TC_I960
2267 if (fixP->fx_callj && TC_S_IS_CALLNAME (add_symbolP))
2268 {
2269 /* Relocation should be done via the
2270 associated 'bal' entry point
2271 symbol. */
2272
2273 if (!TC_S_IS_BALNAME (tc_get_bal_of_call (add_symbolP)))
2274 {
2275 as_bad ("No 'bal' entry point for leafproc %s",
2276 S_GET_NAME (add_symbolP));
2277 continue;
2278 }
2279 fixP->fx_addsy = add_symbolP = tc_get_bal_of_call (add_symbolP);
2280 } /* callj relocation */
2281 #endif
2282 sub_symbolP = fixP->fx_subsy;
2283 add_number = fixP->fx_offset;
2284 pcrel = fixP->fx_pcrel;
2285
2286 if (add_symbolP)
2287 {
2288 add_symbol_segment = S_GET_SEGMENT (add_symbolP);
2289 } /* if there is an addend */
2290
2291 if (sub_symbolP)
2292 {
2293 if (!add_symbolP)
2294 {
2295 /* Its just -sym */
2296 if (S_GET_SEGMENT (sub_symbolP) != SEG_ABSOLUTE)
2297 {
2298 as_bad ("Negative of non-absolute symbol %s", S_GET_NAME (sub_symbolP));
2299 } /* not absolute */
2300
2301 add_number -= S_GET_VALUE (sub_symbolP);
2302 fixP->fx_subsy = 0;
2303
2304 /* if sub_symbol is in the same segment that add_symbol
2305 and add_symbol is either in DATA, TEXT, BSS or ABSOLUTE */
2306 }
2307 else if ((S_GET_SEGMENT (sub_symbolP) == add_symbol_segment)
2308 && (SEG_NORMAL (add_symbol_segment)
2309 || (add_symbol_segment == SEG_ABSOLUTE)))
2310 {
2311 /* Difference of 2 symbols from same segment. */
2312 /* Can't make difference of 2 undefineds: 'value' means */
2313 /* something different for N_UNDF. */
2314 #ifdef TC_I960
2315 /* Makes no sense to use the difference of 2 arbitrary symbols
2316 * as the target of a call instruction.
2317 */
2318 if (fixP->fx_callj)
2319 {
2320 as_bad ("callj to difference of 2 symbols");
2321 }
2322 #endif /* TC_I960 */
2323 add_number += S_GET_VALUE (add_symbolP) -
2324 S_GET_VALUE (sub_symbolP);
2325
2326 add_symbolP = NULL;
2327 fixP->fx_addsy = NULL;
2328 }
2329 else
2330 {
2331 /* Different segments in subtraction. */
2332 know (!(S_IS_EXTERNAL (sub_symbolP) && (S_GET_SEGMENT (sub_symbolP) == SEG_ABSOLUTE)));
2333
2334 if ((S_GET_SEGMENT (sub_symbolP) == SEG_ABSOLUTE))
2335 {
2336 add_number -= S_GET_VALUE (sub_symbolP);
2337 }
2338 else
2339 {
2340 as_bad ("Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %d.",
2341 segment_name (S_GET_SEGMENT (sub_symbolP)),
2342 S_GET_NAME (sub_symbolP), fragP->fr_address + where);
2343 } /* if absolute */
2344 }
2345 } /* if sub_symbolP */
2346
2347 if (add_symbolP)
2348 {
2349 if (add_symbol_segment == this_segment_type && pcrel)
2350 {
2351 /*
2352 * This fixup was made when the symbol's segment was
2353 * SEG_UNKNOWN, but it is now in the local segment.
2354 * So we know how to do the address without relocation.
2355 */
2356 #ifdef TC_I960
2357 /* reloc_callj() may replace a 'call' with a 'calls' or a 'bal',
2358 * in which cases it modifies *fixP as appropriate. In the case
2359 * of a 'calls', no further work is required, and *fixP has been
2360 * set up to make the rest of the code below a no-op.
2361 */
2362 reloc_callj (fixP);
2363 #endif /* TC_I960 */
2364
2365 add_number += S_GET_VALUE (add_symbolP);
2366 add_number -= md_pcrel_from (fixP);
2367 pcrel = 0; /* Lie. Don't want further pcrel processing. */
2368 fixP->fx_addsy = NULL; /* No relocations please. */
2369 }
2370 else
2371 {
2372 switch (add_symbol_segment)
2373 {
2374 case SEG_ABSOLUTE:
2375 #ifdef TC_I960
2376 reloc_callj (fixP); /* See comment about reloc_callj() above*/
2377 #endif /* TC_I960 */
2378 add_number += S_GET_VALUE (add_symbolP);
2379 fixP->fx_addsy = NULL;
2380 add_symbolP = NULL;
2381 break;
2382 default:
2383
2384 add_number += S_GET_VALUE (add_symbolP) +
2385 segment_info[S_GET_SEGMENT (add_symbolP)].scnhdr.s_paddr;
2386 break;
2387
2388 case SEG_UNKNOWN:
2389 #ifdef TC_I960
2390 if ((int) fixP->fx_bit_fixP == 13)
2391 {
2392 /* This is a COBR instruction. They have only a
2393 * 13-bit displacement and are only to be used
2394 * for local branches: flag as error, don't generate
2395 * relocation.
2396 */
2397 as_bad ("can't use COBR format with external label");
2398 fixP->fx_addsy = NULL; /* No relocations please. */
2399 continue;
2400 } /* COBR */
2401 #endif /* TC_I960 */
2402 #ifdef TC_I386
2403 /* 386 COFF uses a peculiar format in
2404 which the value of a common symbol is
2405 stored in the .text segment (I've
2406 checked this on SVR3.2 and SCO 3.2.2)
2407 Ian Taylor <ian@cygnus.com>. */
2408 add_number += S_GET_VALUE (add_symbolP);
2409 #endif
2410 break;
2411
2412
2413 } /* switch on symbol seg */
2414 } /* if not in local seg */
2415 } /* if there was a + symbol */
2416
2417 if (pcrel)
2418 {
2419 add_number -= md_pcrel_from (fixP);
2420 if (add_symbolP == 0)
2421 {
2422 fixP->fx_addsy = &abs_symbol;
2423 } /* if there's an add_symbol */
2424 } /* if pcrel */
2425
2426 if (!fixP->fx_bit_fixP)
2427 {
2428 if ((size == 1 &&
2429 (add_number & ~0xFF) && ((add_number & ~0xFF) != (-1 & ~0xFF))) ||
2430 (size == 2 &&
2431 (add_number & ~0xFFFF) && ((add_number & ~0xFFFF) != (-1 & ~0xFFFF))))
2432 {
2433 as_bad ("Value of %d too large for field of %d bytes at 0x%x",
2434 add_number, size, fragP->fr_address + where);
2435 } /* generic error checking */
2436 #ifdef WARN_SIGNED_OVERFLOW_WORD
2437 /* Warn if a .word value is too large when treated as
2438 a signed number. We already know it is not too
2439 negative. This is to catch over-large switches
2440 generated by gcc on the 68k. */
2441 if (!flagseen['J']
2442 && size == 2
2443 && add_number > 0x7fff)
2444 as_bad ("Signed .word overflow; switch may be too large; %d at 0x%x",
2445 add_number, fragP->fr_address + where);
2446 #endif
2447 } /* not a bit fix */
2448 /* once this fix has been applied, we don't have to output anything
2449 nothing more need be done -*/
2450 md_apply_fix (fixP, add_number);
2451
2452 } /* For each fixS in this segment. */
2453
2454
2455 } /* fixup_segment() */
2456
2457 #endif