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