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