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