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