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