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