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