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