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