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