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