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