* config/obj-coffbfd.c: lint
[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 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
352 TC_RELOC_MANGLE(fix_ptr, &intr, base);
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(def_symbol_in_progress,0, 0, &zero_address_frag);
908
909
910
911 SF_SET_PROCESS(def_symbol_in_progress);
912
913 if (symbolP == NULL) {
914 /* That is, if this is the first
915 time we've seen the function... */
916 symbol_table_insert(def_symbol_in_progress);
917 } /* definition follows debug */
918 } /* Create the line number entry pointing to the function being defined */
919
920 def_symbol_in_progress = NULL;
921 demand_empty_rest_of_line();
922 return;
923 } /* obj_coff_endef() */
924
925 static void
926 DEFUN_VOID(obj_coff_dim)
927 {
928 register int dim_index;
929
930 if (def_symbol_in_progress == NULL)
931 {
932 as_warn(".dim pseudo-op used outside of .def/.endef: ignored.");
933 demand_empty_rest_of_line();
934 return;
935 } /* if not inside .def/.endef */
936
937 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1);
938
939 for (dim_index = 0; dim_index < DIMNUM; dim_index++)
940 {
941 SKIP_WHITESPACES();
942 SA_SET_SYM_DIMEN(def_symbol_in_progress, dim_index, get_absolute_expression());
943
944 switch (*input_line_pointer)
945 {
946
947 case ',':
948 input_line_pointer++;
949 break;
950
951 default:
952 as_warn("badly formed .dim directive ignored");
953 /* intentional fallthrough */
954 case '\n':
955 case ';':
956 dim_index = DIMNUM;
957 break;
958 } /* switch on following character */
959 } /* for each dimension */
960
961 demand_empty_rest_of_line();
962 return;
963 } /* obj_coff_dim() */
964
965 static void obj_coff_line() {
966 if (def_symbol_in_progress == NULL) {
967 obj_coff_ln();
968 return;
969 } /* if it looks like a stabs style line */
970
971 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1);
972 SA_SET_SYM_LNNO(def_symbol_in_progress, get_absolute_expression());
973
974 demand_empty_rest_of_line();
975 return;
976 } /* obj_coff_line() */
977
978 static void obj_coff_size() {
979 if (def_symbol_in_progress == NULL) {
980 as_warn(".size pseudo-op used outside of .def/.endef ignored.");
981 demand_empty_rest_of_line();
982 return;
983 } /* if not inside .def/.endef */
984
985 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1);
986 SA_SET_SYM_SIZE(def_symbol_in_progress, get_absolute_expression());
987 demand_empty_rest_of_line();
988 return;
989 } /* obj_coff_size() */
990
991 static void obj_coff_scl() {
992 if (def_symbol_in_progress == NULL) {
993 as_warn(".scl pseudo-op used outside of .def/.endef ignored.");
994 demand_empty_rest_of_line();
995 return;
996 } /* if not inside .def/.endef */
997
998 S_SET_STORAGE_CLASS(def_symbol_in_progress, get_absolute_expression());
999 demand_empty_rest_of_line();
1000 return;
1001 } /* obj_coff_scl() */
1002
1003 static void obj_coff_tag() {
1004 char *symbol_name;
1005 char name_end;
1006
1007 if (def_symbol_in_progress == NULL) {
1008 as_warn(".tag pseudo-op used outside of .def/.endef ignored.");
1009 demand_empty_rest_of_line();
1010 return;
1011 } /* if not inside .def/.endef */
1012
1013 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1);
1014 symbol_name = input_line_pointer;
1015 name_end = get_symbol_end();
1016
1017 /* Assume that the symbol referred to by .tag is always defined. */
1018 /* This was a bad assumption. I've added find_or_make. xoxorich. */
1019 SA_SET_SYM_TAGNDX(def_symbol_in_progress, (long) tag_find_or_make(symbol_name));
1020 if (SA_GET_SYM_TAGNDX(def_symbol_in_progress) == 0L) {
1021 as_warn("tag not found for .tag %s", symbol_name);
1022 } /* not defined */
1023
1024 SF_SET_TAGGED(def_symbol_in_progress);
1025 *input_line_pointer = name_end;
1026
1027 demand_empty_rest_of_line();
1028 return;
1029 } /* obj_coff_tag() */
1030
1031 static void obj_coff_type() {
1032 if (def_symbol_in_progress == NULL) {
1033 as_warn(".type pseudo-op used outside of .def/.endef ignored.");
1034 demand_empty_rest_of_line();
1035 return;
1036 } /* if not inside .def/.endef */
1037
1038 S_SET_DATA_TYPE(def_symbol_in_progress, get_absolute_expression());
1039
1040 if (ISFCN(S_GET_DATA_TYPE(def_symbol_in_progress)) &&
1041 S_GET_STORAGE_CLASS(def_symbol_in_progress) != C_TPDEF) {
1042 SF_SET_FUNCTION(def_symbol_in_progress);
1043 } /* is a function */
1044
1045 demand_empty_rest_of_line();
1046 return;
1047 } /* obj_coff_type() */
1048
1049 static void obj_coff_val() {
1050 if (def_symbol_in_progress == NULL) {
1051 as_warn(".val pseudo-op used outside of .def/.endef ignored.");
1052 demand_empty_rest_of_line();
1053 return;
1054 } /* if not inside .def/.endef */
1055
1056 if (is_name_beginner(*input_line_pointer)) {
1057 char *symbol_name = input_line_pointer;
1058 char name_end = get_symbol_end();
1059
1060 if (!strcmp(symbol_name, ".")) {
1061 def_symbol_in_progress->sy_frag = frag_now;
1062 S_SET_VALUE(def_symbol_in_progress, obstack_next_free(&frags) - frag_now->fr_literal);
1063 /* If the .val is != from the .def (e.g. statics) */
1064 } else if (strcmp(S_GET_NAME(def_symbol_in_progress), symbol_name)) {
1065 def_symbol_in_progress->sy_forward = symbol_find_or_make(symbol_name);
1066
1067 /* If the segment is undefined when the forward
1068 reference is solved, then copy the segment id
1069 from the forward symbol. */
1070 SF_SET_GET_SEGMENT(def_symbol_in_progress);
1071 }
1072 /* Otherwise, it is the name of a non debug symbol and its value will be calculated later. */
1073 *input_line_pointer = name_end;
1074 } else {
1075 S_SET_VALUE(def_symbol_in_progress, get_absolute_expression());
1076 } /* if symbol based */
1077
1078 demand_empty_rest_of_line();
1079 return;
1080 } /* obj_coff_val() */
1081
1082 /*
1083 * Maintain a list of the tagnames of the structres.
1084 */
1085
1086 static void tag_init() {
1087 tag_hash = hash_new();
1088 return ;
1089 } /* tag_init() */
1090
1091 static void tag_insert(name, symbolP)
1092 char *name;
1093 symbolS *symbolP;
1094 {
1095 register char * error_string;
1096
1097 if (*(error_string = hash_jam(tag_hash, name, (char *)symbolP))) {
1098 as_fatal("Inserting \"%s\" into structure table failed: %s",
1099 name, error_string);
1100 }
1101 return ;
1102 } /* tag_insert() */
1103
1104 static symbolS *tag_find_or_make(name)
1105 char *name;
1106 {
1107 symbolS *symbolP;
1108
1109 if ((symbolP = tag_find(name)) == NULL) {
1110 symbolP = symbol_new(name,
1111 SEG_UNKNOWN,
1112 0,
1113 &zero_address_frag);
1114
1115 tag_insert(S_GET_NAME(symbolP), symbolP);
1116 symbol_table_insert(symbolP);
1117 } /* not found */
1118
1119 return(symbolP);
1120 } /* tag_find_or_make() */
1121
1122 static symbolS *tag_find(name)
1123 char *name;
1124 {
1125 #ifdef STRIP_UNDERSCORE
1126 if (*name == '_') name++;
1127 #endif /* STRIP_UNDERSCORE */
1128 return((symbolS*)hash_find(tag_hash, name));
1129 } /* tag_find() */
1130
1131 void obj_read_begin_hook() {
1132 /* These had better be the same. Usually 18 bytes. */
1133 #ifndef BFD_HEADERS
1134 know(sizeof(SYMENT) == sizeof(AUXENT));
1135 know(SYMESZ == AUXESZ);
1136 #endif
1137 tag_init();
1138
1139 return;
1140 } /* obj_read_begin_hook() */
1141
1142 /* This function runs through the symbol table and puts all the
1143 externals onto another chain */
1144
1145 /* The chain of externals */
1146 symbolS *symbol_externP = NULL;
1147 symbolS *symbol_extern_lastP = NULL;
1148
1149 stack*block_stack;
1150 symbolS *last_functionP = NULL;
1151 symbolS *last_tagP;
1152
1153
1154 static unsigned int DEFUN_VOID(yank_symbols)
1155 {
1156 symbolS *symbolP;
1157 unsigned int symbol_number =0;
1158
1159 for (symbolP = symbol_rootP;
1160 symbolP;
1161 symbolP = symbolP ? symbol_next(symbolP) : symbol_rootP) {
1162 if (!SF_GET_DEBUG(symbolP)) {
1163 /* Debug symbols do not need all this rubbish */
1164 symbolS* real_symbolP;
1165
1166 /* L* and C_EFCN symbols never merge. */
1167 if (!SF_GET_LOCAL(symbolP)
1168 && (real_symbolP = symbol_find_base(S_GET_NAME(symbolP), DO_NOT_STRIP))
1169 && real_symbolP != symbolP) {
1170 /* FIXME-SOON: where do dups come from?
1171 Maybe tag references before definitions? xoxorich. */
1172 /* Move the debug data from the debug symbol to the
1173 real symbol. Do NOT do the oposite (i.e. move from
1174 real symbol to debug symbol and remove real symbol from the
1175 list.) Because some pointers refer to the real symbol
1176 whereas no pointers refer to the debug symbol. */
1177 c_symbol_merge(symbolP, real_symbolP);
1178 /* Replace the current symbol by the real one */
1179 /* The symbols will never be the last or the first
1180 because : 1st symbol is .file and 3 last symbols are
1181 .text, .data, .bss */
1182 symbol_remove(real_symbolP, &symbol_rootP, &symbol_lastP);
1183 symbol_insert(real_symbolP, symbolP, &symbol_rootP, &symbol_lastP);
1184 symbol_remove(symbolP, &symbol_rootP, &symbol_lastP);
1185 symbolP = real_symbolP;
1186 } /* if not local but dup'd */
1187
1188 if (flagseen['R'] && (S_GET_SEGMENT(symbolP) == SEG_E1)) {
1189 S_SET_SEGMENT(symbolP, SEG_E0);
1190 } /* push data into text */
1191
1192 S_SET_VALUE(symbolP,
1193 S_GET_VALUE(symbolP) + symbolP->sy_frag->fr_address);
1194
1195 if (!S_IS_DEFINED(symbolP) && !SF_GET_LOCAL(symbolP))
1196 {
1197 S_SET_EXTERNAL(symbolP);
1198 }
1199 else if (S_GET_STORAGE_CLASS(symbolP) == C_NULL)
1200 {
1201 if (S_GET_SEGMENT(symbolP) == SEG_E0)
1202 {
1203 S_SET_STORAGE_CLASS(symbolP, C_LABEL);
1204 }
1205 else
1206 {
1207 S_SET_STORAGE_CLASS(symbolP, C_STAT);
1208 }
1209 }
1210
1211 /* Mainly to speed up if not -g */
1212 if (SF_GET_PROCESS(symbolP))
1213 {
1214 /* Handle the nested blocks auxiliary info. */
1215 if (S_GET_STORAGE_CLASS(symbolP) == C_BLOCK) {
1216 if (!strcmp(S_GET_NAME(symbolP), ".bb"))
1217 stack_push(block_stack, (char *) &symbolP);
1218 else { /* .eb */
1219 register symbolS* begin_symbolP;
1220 begin_symbolP = *(symbolS**)stack_pop(block_stack);
1221 if (begin_symbolP == (symbolS*)0)
1222 as_warn("mismatched .eb");
1223 else
1224 SA_SET_SYM_ENDNDX(begin_symbolP, symbol_number+2);
1225 }
1226 }
1227 /* If we are able to identify the type of a function, and we
1228 are out of a function (last_functionP == 0) then, the
1229 function symbol will be associated with an auxiliary
1230 entry. */
1231 if (last_functionP == (symbolS*)0 &&
1232 SF_GET_FUNCTION(symbolP)) {
1233 last_functionP = symbolP;
1234
1235 if (S_GET_NUMBER_AUXILIARY(symbolP) < 1) {
1236 S_SET_NUMBER_AUXILIARY(symbolP, 1);
1237 } /* make it at least 1 */
1238
1239 /* Clobber possible stale .dim information. */
1240 bzero(symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen,
1241 sizeof(symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen));
1242 }
1243 /* The C_FCN doesn't need any additional information.
1244 I don't even know if this is needed for sdb. But the
1245 standard assembler generates it, so...
1246 */
1247 if (S_GET_STORAGE_CLASS(symbolP) == C_EFCN) {
1248 if (last_functionP == (symbolS*)0)
1249 as_fatal("C_EFCN symbol out of scope");
1250 SA_SET_SYM_FSIZE(last_functionP,
1251 (long)(S_GET_VALUE(symbolP) -
1252 S_GET_VALUE(last_functionP)));
1253 SA_SET_SYM_ENDNDX(last_functionP, symbol_number);
1254 last_functionP = (symbolS*)0;
1255 }
1256 }
1257 } else if (SF_GET_TAG(symbolP)) {
1258 /* First descriptor of a structure must point to
1259 the first slot after the structure description. */
1260 last_tagP = symbolP;
1261
1262 } else if (S_GET_STORAGE_CLASS(symbolP) == C_EOS) {
1263 /* +2 take in account the current symbol */
1264 SA_SET_SYM_ENDNDX(last_tagP, symbol_number + 2);
1265 } else if (S_GET_STORAGE_CLASS(symbolP) == C_FILE) {
1266 if (S_GET_VALUE(symbolP)) {
1267 S_SET_VALUE((symbolS *) S_GET_VALUE(symbolP), symbol_number);
1268 S_SET_VALUE(symbolP, 0);
1269 } /* no one points at the first .file symbol */
1270 } /* if debug or tag or eos or file */
1271
1272 /* We must put the external symbols apart. The loader
1273 does not bomb if we do not. But the references in
1274 the endndx field for a .bb symbol are not corrected
1275 if an external symbol is removed between .bb and .be.
1276 I.e in the following case :
1277 [20] .bb endndx = 22
1278 [21] foo external
1279 [22] .be
1280 ld will move the symbol 21 to the end of the list but
1281 endndx will still be 22 instead of 21. */
1282
1283
1284 if (SF_GET_LOCAL(symbolP)) {
1285 /* remove C_EFCN and LOCAL (L...) symbols */
1286 /* next pointer remains valid */
1287 symbol_remove(symbolP, &symbol_rootP, &symbol_lastP);
1288
1289 }
1290 else if (!S_IS_DEFINED(symbolP)
1291 && !S_IS_DEBUG(symbolP)
1292 && !SF_GET_STATICS(symbolP) &&
1293 S_GET_STORAGE_CLASS(symbolP) == C_EXT)
1294 { /* C_EXT && !SF_GET_FUNCTION(symbolP)) */
1295 /* if external, Remove from the list */
1296 symbolS *hold = symbol_previous(symbolP);
1297
1298 symbol_remove(symbolP, &symbol_rootP, &symbol_lastP);
1299 symbol_clear_list_pointers(symbolP);
1300 symbol_append(symbolP, symbol_extern_lastP, &symbol_externP, &symbol_extern_lastP);
1301 symbolP = hold;
1302 } else {
1303 if (SF_GET_STRING(symbolP)) {
1304 symbolP->sy_name_offset = string_byte_count;
1305 string_byte_count += strlen(S_GET_NAME(symbolP)) + 1;
1306 } else {
1307 symbolP->sy_name_offset = 0;
1308 } /* fix "long" names */
1309
1310 symbolP->sy_number = symbol_number;
1311 symbol_number += 1 + S_GET_NUMBER_AUXILIARY(symbolP);
1312 } /* if local symbol */
1313 } /* traverse the symbol list */
1314 return symbol_number;
1315
1316 }
1317
1318
1319 static unsigned int DEFUN_VOID(glue_symbols)
1320 {
1321 unsigned int symbol_number = 0;
1322 symbolS *symbolP;
1323 for (symbolP = symbol_externP; symbol_externP;) {
1324 symbolS *tmp = symbol_externP;
1325
1326 /* append */
1327 symbol_remove(tmp, &symbol_externP, &symbol_extern_lastP);
1328 symbol_append(tmp, symbol_lastP, &symbol_rootP, &symbol_lastP);
1329
1330 /* and process */
1331 if (SF_GET_STRING(tmp)) {
1332 tmp->sy_name_offset = string_byte_count;
1333 string_byte_count += strlen(S_GET_NAME(tmp)) + 1;
1334 } else {
1335 tmp->sy_name_offset = 0;
1336 } /* fix "long" names */
1337
1338 tmp->sy_number = symbol_number;
1339 symbol_number += 1 + S_GET_NUMBER_AUXILIARY(tmp);
1340 } /* append the entire extern chain */
1341 return symbol_number;
1342
1343 }
1344
1345 static unsigned int DEFUN_VOID(tie_tags)
1346 {
1347 unsigned int symbol_number = 0;
1348
1349 symbolS*symbolP;
1350 for (symbolP = symbol_rootP; symbolP; symbolP =
1351 symbol_next(symbolP))
1352 {
1353 symbolP->sy_number = symbol_number;
1354
1355
1356
1357 if (SF_GET_TAGGED(symbolP))
1358 {
1359 SA_SET_SYM_TAGNDX
1360 (symbolP,
1361 ((symbolS*) SA_GET_SYM_TAGNDX(symbolP))->sy_number);
1362 }
1363
1364 symbol_number += 1 + S_GET_NUMBER_AUXILIARY(symbolP);
1365 }
1366 return symbol_number;
1367
1368 }
1369
1370 static void
1371 DEFUN(crawl_symbols,(headers, abfd),
1372 struct internal_filehdr *headers AND
1373 bfd *abfd)
1374 {
1375
1376 unsigned int i;
1377 unsigned int ptr = 0;
1378
1379
1380 symbolS *symbolP;
1381
1382 /* Initialize the stack used to keep track of the matching .bb .be */
1383
1384 block_stack = stack_init(512, sizeof(symbolS*));
1385 /* JF deal with forward references first... */
1386 for (symbolP = symbol_rootP;
1387 symbolP;
1388 symbolP = symbol_next(symbolP))
1389 {
1390
1391 if (symbolP->sy_forward) {
1392 S_SET_VALUE(symbolP, (S_GET_VALUE(symbolP)
1393 + S_GET_VALUE(symbolP->sy_forward)
1394 + symbolP->sy_forward->sy_frag->fr_address));
1395
1396 if (SF_GET_GET_SEGMENT(symbolP)) {
1397 S_SET_SEGMENT(symbolP, S_GET_SEGMENT(symbolP->sy_forward));
1398 } /* forward segment also */
1399
1400 symbolP->sy_forward=0;
1401 } /* if it has a forward reference */
1402 } /* walk the symbol chain */
1403
1404
1405 /* The symbol list should be ordered according to the following sequence
1406 * order :
1407 * . .file symbol
1408 * . debug entries for functions
1409 * . fake symbols for the sections, including.text .data and .bss
1410 * . defined symbols
1411 * . undefined symbols
1412 * But this is not mandatory. The only important point is to put the
1413 * undefined symbols at the end of the list.
1414 */
1415
1416 if (symbol_rootP == NULL
1417 || S_GET_STORAGE_CLASS(symbol_rootP) != C_FILE) {
1418 c_dot_file_symbol("fake");
1419 }
1420 /* Is there a .file symbol ? If not insert one at the beginning. */
1421
1422 /*
1423 * Build up static symbols for the sections, they are filled in later
1424 */
1425
1426
1427 for (i = SEG_E0; i < SEG_E9; i++)
1428 {
1429 if (segment_info[i].scnhdr.s_name[0])
1430 {
1431 segment_info[i].dot =
1432 c_section_symbol(segment_info[i].scnhdr.s_name,
1433 i-SEG_E0+1);
1434
1435 }
1436 }
1437
1438
1439 /* Take all the externals out and put them into another chain */
1440 headers->f_nsyms = yank_symbols();
1441 /* Take the externals and glue them onto the end.*/
1442 headers->f_nsyms += glue_symbols();
1443
1444 headers->f_nsyms = tie_tags();
1445 know(symbol_externP == NULL);
1446 know(symbol_extern_lastP == NULL);
1447
1448 return;
1449 }
1450
1451 /*
1452 * Find strings by crawling along symbol table chain.
1453 */
1454
1455 void DEFUN(w_strings,(where),
1456 char *where)
1457 {
1458 symbolS *symbolP;
1459
1460 /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
1461 md_number_to_chars(where, string_byte_count, sizeof(string_byte_count));
1462 where += sizeof(string_byte_count);
1463 for (symbolP = symbol_rootP;
1464 symbolP;
1465 symbolP = symbol_next(symbolP))
1466 {
1467 unsigned int size;
1468
1469 if (SF_GET_STRING(symbolP)) {
1470 size = strlen(S_GET_NAME(symbolP)) + 1;
1471
1472 memcpy(where, S_GET_NAME(symbolP),size);
1473 where += size;
1474
1475 }
1476 }
1477
1478 }
1479
1480
1481
1482
1483
1484 static void
1485 DEFUN(do_linenos_for,(abfd, file_cursor),
1486 bfd *abfd AND
1487 unsigned long *file_cursor)
1488 {
1489 unsigned int idx;
1490
1491 for (idx = SEG_E0; idx < SEG_E9; idx++)
1492 {
1493 segment_info_type *s = segment_info + idx;
1494
1495 if (s->scnhdr.s_nlnno != 0)
1496 {
1497 struct lineno_list *line_ptr ;
1498
1499 struct external_lineno *buffer =
1500 (struct external_lineno *)xmalloc(s->scnhdr.s_nlnno * LINESZ);
1501
1502 struct external_lineno *dst= buffer;
1503
1504 /* Run through the table we've built and turn it into its external
1505 form */
1506
1507 for (line_ptr = s->lineno_list_head;
1508 line_ptr != (struct lineno_list *)NULL;
1509 line_ptr = line_ptr->next)
1510 {
1511 if (line_ptr->line.l_lnno == 0)
1512 {
1513 /* Turn a pointer to a symbol into the symbols' index */
1514 line_ptr->line.l_addr.l_symndx =
1515 ( (symbolS *)line_ptr->line.l_addr.l_symndx)->sy_number;
1516 }
1517 (void) bfd_coff_swap_lineno_out(abfd, &(line_ptr->line), dst);
1518 dst++;
1519 }
1520
1521 s->scnhdr.s_lnnoptr = *file_cursor;
1522
1523 bfd_write(buffer, 1, s->scnhdr.s_nlnno* LINESZ, abfd);
1524 free(buffer);
1525
1526 *file_cursor += s->scnhdr.s_nlnno * LINESZ;
1527 }
1528 }
1529 }
1530
1531
1532 /* Now we run through the list of frag chains in a segment and
1533 make all the subsegment frags appear at the end of the
1534 list, as if the seg 0 was extra long */
1535
1536 static void DEFUN_VOID(remove_subsegs)
1537 {
1538 unsigned int i;
1539
1540 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
1541 {
1542 frchainS *head = segment_info[i].frchainP;
1543 fragS dummy;
1544 fragS * prev_frag = &dummy;
1545
1546 while (head && head->frch_seg == i)
1547 {
1548 prev_frag->fr_next = head->frch_root;
1549 prev_frag = head->frch_last;
1550 head = head->frch_next;
1551 }
1552 prev_frag->fr_next = 0;
1553 }
1554 }
1555
1556
1557 extern void DEFUN_VOID(write_object_file)
1558 {
1559 int i;
1560 struct frchain *frchain_ptr;
1561
1562 struct internal_filehdr filehdr;
1563 struct internal_aouthdr aouthdr;
1564 unsigned long file_cursor;
1565 bfd *abfd;
1566 unsigned int addr = 0;
1567 abfd = bfd_openw(out_file_name, TARGET_FORMAT);
1568
1569
1570 if (abfd == 0) {
1571 as_perror ("FATAL: Can't create %s", out_file_name);
1572 exit(42);
1573 }
1574 bfd_set_format(abfd, bfd_object);
1575 bfd_set_arch_mach(abfd, BFD_ARCH, 0);
1576
1577
1578
1579 string_byte_count = 4;
1580
1581 for (frchain_ptr = frchain_root;
1582 frchain_ptr != (struct frchain *)NULL;
1583 frchain_ptr = frchain_ptr->frch_next) {
1584 /* Run through all the sub-segments and align them up. Also close any
1585 open frags. We tack a .fill onto the end of the frag chain so
1586 that any .align's size can be worked by looking at the next
1587 frag */
1588
1589 subseg_new(frchain_ptr->frch_seg, frchain_ptr->frch_subseg);
1590 #define SUB_SEGMENT_ALIGN 1
1591 frag_align(SUB_SEGMENT_ALIGN,0);
1592 frag_wane(frag_now);
1593 frag_now->fr_fix = 0;
1594 know( frag_now->fr_next == NULL );
1595 }
1596
1597
1598 remove_subsegs();
1599
1600
1601 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
1602 {
1603 relax_segment(segment_info[i].frchainP->frch_root, i);
1604 }
1605
1606
1607
1608
1609
1610 filehdr.f_nscns = 0;
1611
1612 /* Find out how big the sections are */
1613 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
1614 {
1615
1616 if (segment_info[i].scnhdr.s_name[0])
1617 {
1618 filehdr.f_nscns++;
1619 }
1620 segment_info[i].scnhdr.s_paddr = addr;
1621 if (i == SEG_E2) {
1622 /* THis is a special case, we leave the size alone, which will have */
1623 /* been made up from all and any lcomms seen */
1624 }
1625 else {
1626 addr += size_section(abfd, i);
1627 }
1628 }
1629
1630
1631
1632 /* Turn the gas native symbol table shape into a coff symbol table */
1633 crawl_symbols(&filehdr, abfd);
1634 #ifndef TC_H8300
1635 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
1636 {
1637 fixup_segment(segment_info[i].fix_root, i);
1638 }
1639 #endif
1640
1641 file_cursor = FILHSZ + SCNHSZ * filehdr.f_nscns ;
1642
1643 bfd_seek(abfd, file_cursor, 0);
1644
1645
1646 do_relocs_for(abfd, &file_cursor);
1647
1648 do_linenos_for(abfd, &file_cursor);
1649
1650
1651 /* Plant the data */
1652
1653 fill_section(abfd,&filehdr, &file_cursor);
1654
1655 filehdr.f_magic = COFF_MAGIC;
1656 filehdr.f_timdat = 0;
1657 filehdr.f_flags = 0;
1658
1659
1660
1661 {
1662
1663 unsigned int symtable_size = filehdr.f_nsyms * SYMESZ;
1664 char *buffer1 = malloc(symtable_size + string_byte_count + 4);
1665 char *ptr = buffer1;
1666 filehdr.f_symptr = bfd_tell(abfd);
1667 w_symbols(abfd, buffer1, symbol_rootP);
1668 w_strings(buffer1 + symtable_size);
1669 bfd_write(buffer1, 1,symtable_size + string_byte_count + 4, abfd);
1670 free(buffer1);
1671
1672 }
1673 coff_header_append(abfd, &filehdr, &aouthdr);
1674
1675 bfd_close_all_done(abfd);
1676 }
1677
1678
1679 static void DEFUN(change_to_section,(name, len, exp),
1680 char *name AND
1681 unsigned int len AND
1682 unsigned int exp)
1683 {
1684 unsigned int i;
1685 /* Find out if we've already got a section of this name etc */
1686 for(i = SEG_E0; i < SEG_E9 && segment_info[i].scnhdr.s_name[0] ; i++)
1687 {
1688 if (strncmp(segment_info[i].scnhdr.s_name, name, len) == 0)
1689 {
1690 subseg_new(i, exp);
1691 return;
1692
1693 }
1694 }
1695 /* No section, add one */
1696 strncpy(segment_info[i].scnhdr.s_name, name, 8);
1697 subseg_new(i, exp);
1698 }
1699
1700 static void
1701 DEFUN_VOID(obj_coff_section)
1702 {
1703 /* Strip out the section name */
1704 char *section_name ;
1705 char *section_name_end;
1706 char c;
1707
1708 unsigned int len;
1709 unsigned int exp;
1710
1711 section_name = input_line_pointer;
1712 c = get_symbol_end();
1713 section_name_end = input_line_pointer;
1714
1715 len = section_name_end - section_name ;
1716 input_line_pointer++;
1717 SKIP_WHITESPACE();
1718 if (c == ',')
1719 {
1720 exp = get_absolute_expression();
1721 }
1722 else if ( *input_line_pointer == ',')
1723 {
1724
1725 input_line_pointer++;
1726 exp = get_absolute_expression();
1727 }
1728 else
1729 {
1730 exp = 0;
1731 }
1732
1733 change_to_section(section_name, len,exp);
1734 *section_name_end = c;
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