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