1 /* coff object file format with bfd
2 Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc.
4 This file is part of GAS.
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)
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.
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. */
22 How does this releate to the rest of GAS ?
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
32 Hacked for BFDness by steve chamberlain
34 This object module now supports the Hitachi H8/300 and the AMD 29k
43 #include "../bfd/libbfd.h"
46 /* This vector is used to turn an internal segment into a section #
47 suitable for insertion into a coff symbol table
50 const short seg_N_TYPE[] = { /* in: segT out: N_TYPE bits */
62 C_UNDEF_SECTION, /* SEG_UNKNOWN */
63 C_UNDEF_SECTION, /* SEG_ABSENT */
64 C_UNDEF_SECTION, /* SEG_PASS1 */
65 C_UNDEF_SECTION, /* SEG_GOOF */
66 C_UNDEF_SECTION, /* SEG_BIG */
67 C_UNDEF_SECTION, /* SEG_DIFFERENCE */
68 C_DEBUG_SECTION, /* SEG_DEBUG */
69 C_NTV_SECTION, /* SEG_NTV */
70 C_PTV_SECTION, /* SEG_PTV */
71 C_REGISTER_SECTION, /* SEG_REGISTER */
75 int function_lineoff = -1; /* Offset in line#s where the last function
76 started (the odd entry for line #0) */
82 static symbolS*last_line_symbol;
83 /* Add 4 to the real value to get the index and compensate the
84 negatives. This vector is used by S_GET_SEGMENT to turn a coff
85 section number into a segment number
87 static symbolS *previous_file_symbol = NULL;
88 void c_symbol_merge();
91 symbolS *c_section_symbol();
93 void EXFUN(bfd_as_write_hook,(struct internal_filehdr *,
96 static void EXFUN(fixup_segment,(fixS * fixP,
97 segT this_segment_type));
99 static void EXFUN(fill_section,(bfd *abfd ,
100 struct internal_filehdr *f, unsigned
104 char *EXFUN(s_get_name,(symbolS *s));
105 static symbolS *EXFUN(tag_find_or_make,(char *name));
106 static symbolS* EXFUN(tag_find,(char *name));
113 unsigned short line_number,
117 static void EXFUN(w_symbols,
120 symbolS *symbol_rootP));
124 static void EXFUN( obj_coff_def,(int what));
125 static void EXFUN( obj_coff_lcomm,(void));
126 static void EXFUN( obj_coff_dim,(void));
127 static void EXFUN( obj_coff_text,(void));
128 static void EXFUN( obj_coff_data,(void));
129 static void EXFUN( obj_coff_endef,(void));
130 static void EXFUN( obj_coff_line,(void));
131 static void EXFUN( obj_coff_ln,(void));
132 static void EXFUN( obj_coff_scl,(void));
133 static void EXFUN( obj_coff_size,(void));
134 static void EXFUN( obj_coff_tag,(void));
135 static void EXFUN( obj_coff_type,(void));
136 static void EXFUN( obj_coff_val,(void));
137 static void EXFUN( obj_coff_section,(void));
138 static void EXFUN( tag_init,(void));
139 static void EXFUN( tag_insert,(char *name, symbolS *symbolP));
142 static struct hash_control *tag_hash;
143 static symbolS *def_symbol_in_progress = NULL;
145 const pseudo_typeS obj_pseudo_table[] = {
146 { "def", obj_coff_def, 0 },
147 { "dim", obj_coff_dim, 0 },
148 { "endef", obj_coff_endef, 0 },
149 { "line", obj_coff_line, 0 },
150 { "ln", obj_coff_ln, 0 },
151 { "scl", obj_coff_scl, 0 },
152 { "size", obj_coff_size, 0 },
153 { "tag", obj_coff_tag, 0 },
154 { "type", obj_coff_type, 0 },
155 { "val", obj_coff_val, 0 },
156 { "section", obj_coff_section, 0 },
157 { "text", obj_coff_text, 0 },
158 { "data", obj_coff_data, 0 },
159 /* we don't yet handle this. */
160 { "ident", s_ignore, 0 },
161 { "ABORT", s_abort, 0 },
162 { "lcomm", obj_coff_lcomm, 0},
163 { NULL} /* end sentinel */
164 }; /* obj_pseudo_table */
170 We allow more than just the standard 3 sections, infact, we allow
171 10 sections, (though the usual three have to be there).
173 This structure performs the mappings for us:
178 static struct internal_scnhdr bss_section_header;
179 struct internal_scnhdr data_section_header;
180 struct internal_scnhdr text_section_header;
182 const segT N_TYPE_seg [32] =
196 seg_info_type seg_info_off_by_4[N_SEG] =
222 {SEG_REGISTER},0,0,0,0};
224 #define SEG_INFO_FROM_SECTION_NUMBER(x) (seg_info_off_by_4[(x)+4])
225 #define SEG_INFO_FROM_SEG_NUMBER(x) (seg_info_off_by_4[(x)])
229 DEFUN(relax_align,(address, alignment),
230 register relax_addressT address AND
231 register long alignment )
234 relax_addressT new_address;
236 mask = ~ ( (~0) << alignment );
237 new_address = (address + mask) & (~ mask);
238 return (new_address - address);
239 } /* relax_align() */
243 DEFUN(s_get_segment,(x) ,
246 return SEG_INFO_FROM_SECTION_NUMBER(x->sy_symbol.ost_entry.n_scnum).seg_t;
251 /* calculate the size of the frag chain and fill in the section header
252 to contain all of it, also fill in the addr of the sections */
253 static unsigned int DEFUN(size_section,(abfd, idx),
258 unsigned int size = 0;
259 fragS *frag = segment_info[idx].frchainP->frch_root;
261 if (frag->fr_address != size) {
262 printf("Out of step\n");
263 size = frag->fr_address;
265 size += frag->fr_fix;
266 switch (frag->fr_type) {
269 size += frag->fr_offset * frag->fr_var;
272 size += relax_align(size, frag->fr_offset);
274 frag = frag->fr_next;
276 segment_info[idx].scnhdr.s_size = size;
281 static unsigned int DEFUN(count_entries_in_chain,(idx),
284 unsigned int nrelocs;
287 /* Count the relocations */
288 fixup_ptr = segment_info[idx].fix_root;
290 while (fixup_ptr != (fixS *)NULL)
292 if (TC_COUNT_RELOC(fixup_ptr))
297 if (fixup_ptr->fx_r_type == RELOC_CONSTH)
306 fixup_ptr = fixup_ptr->fx_next;
311 /* output all the relocations for a section */
312 void DEFUN(do_relocs_for,(abfd, file_cursor),
314 unsigned long *file_cursor)
316 unsigned int nrelocs;
319 for (idx = SEG_E0; idx < SEG_E9; idx++)
321 if (segment_info[idx].scnhdr.s_name[0])
324 struct external_reloc *ext_ptr;
325 struct external_reloc *external_reloc_vec;
326 unsigned int external_reloc_size;
327 unsigned int count = 0;
328 unsigned int base = segment_info[idx].scnhdr.s_paddr;
329 fixS * fix_ptr = segment_info[idx].fix_root;
330 nrelocs = count_entries_in_chain(idx);
335 external_reloc_size = nrelocs * RELSZ;
337 (struct external_reloc*)malloc(external_reloc_size);
341 ext_ptr = external_reloc_vec;
343 /* Fill in the internal coff style reloc struct from the
348 struct internal_reloc intr;
350 /* Only output some of the relocations */
351 if (TC_COUNT_RELOC(fix_ptr))
353 #ifdef TC_RELOC_MANGLE
354 TC_RELOC_MANGLE(fix_ptr, &intr, base);
358 symbol_ptr = fix_ptr->fx_addsy;
360 intr.r_type = TC_COFF_FIX2RTYPE(fix_ptr);
362 base + fix_ptr->fx_frag->fr_address + fix_ptr->fx_where ;
364 intr.r_offset = fix_ptr->fx_offset;
368 /* Turn the segment of the symbol into an offset
372 dot = segment_info[S_GET_SEGMENT(symbol_ptr)].dot;
375 intr.r_symndx = dot->sy_number;
379 intr.r_symndx = symbol_ptr->sy_number;
391 (void)bfd_coff_swap_reloc_out(abfd, &intr, ext_ptr);
395 /* The 29k has a special kludge for the high 16 bit reloc.
396 Two relocations are emmited, R_IHIHALF, and
397 R_IHCONST. The second one doesn't contain a symbol,
398 but uses the value for offset */
400 if (intr.r_type == R_IHIHALF)
402 /* now emit the second bit */
403 intr.r_type = R_IHCONST;
404 intr.r_symndx = fix_ptr->fx_addnumber;
405 (void)bfd_coff_swap_reloc_out(abfd,&intr,ext_ptr);
411 fix_ptr = fix_ptr->fx_next;
414 /* Write out the reloc table */
415 segment_info[idx].scnhdr.s_relptr = *file_cursor;
416 segment_info[idx].scnhdr.s_nreloc = nrelocs;
417 bfd_write((PTR)external_reloc_vec, 1, external_reloc_size, abfd);
418 *file_cursor += external_reloc_size;
419 free( external_reloc_vec);
425 /* run through a frag chain and write out the data to go with it, fill
426 in the scnhdrs with the info on the file postions
428 static void DEFUN(fill_section,(abfd, filehdr, file_cursor),
430 struct internal_filehdr *filehdr AND
431 unsigned long *file_cursor)
435 unsigned int paddr = 0;
437 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
439 unsigned int offset = 0;
441 struct internal_scnhdr *s = &( segment_info[i].scnhdr);
445 fragS *frag = segment_info[i].frchainP->frch_root;
446 char *buffer = malloc(s->s_size);
449 s->s_scnptr = *file_cursor;
463 s->s_flags = STYP_REG;
464 if (strcmp(s->s_name,".text")==0)
465 s->s_flags |= STYP_TEXT;
466 else if (strcmp(s->s_name,".data")==0)
467 s->s_flags |= STYP_DATA;
468 else if (strcmp(s->s_name,".bss")==0)
469 s->s_flags |= STYP_BSS | STYP_NOLOAD;
472 unsigned int fill_size;
473 switch (frag->fr_type) {
480 memcpy(buffer + frag->fr_address,
483 offset += frag->fr_fix;
486 fill_size = frag->fr_var;
490 unsigned int off = frag->fr_fix;
491 for (count = frag->fr_offset; count; count--)
493 memcpy(buffer + frag->fr_address + off,
494 frag->fr_literal + frag->fr_fix,
506 frag = frag->fr_next;
510 bfd_write(buffer, s->s_size,1,abfd);
513 *file_cursor += s->s_size;
522 /* Coff file generation & utilities */
526 DEFUN(coff_header_append,(abfd, filehdr, aouthdr),
528 struct internal_filehdr *filehdr AND
529 struct internal_aouthdr *aouthdr)
535 bfd_seek(abfd, 0, 0);
537 filehdr.f_opthdr = bfd_coff_swap_aouthdr_out(abfd, aouthdr,
540 filehdr->f_opthdr = 0;
542 i = bfd_coff_swap_filehdr_out(abfd, filehdr, buffer);
544 bfd_write(buffer, i ,1, abfd);
545 bfd_write(buffero, filehdr->f_opthdr, 1, abfd);
547 for (i = SEG_E0; i < SEG_E9; i++)
549 if (segment_info[i].scnhdr.s_name[0])
552 bfd_coff_swap_scnhdr_out(abfd,
553 &(segment_info[i].scnhdr),
555 bfd_write(buffer, size, 1, abfd);
562 DEFUN(symbol_to_chars,(abfd, where, symbolP),
567 unsigned int numaux = symbolP->sy_symbol.ost_entry.n_numaux;
570 /* Turn any symbols with register attributes into abs symbols */
571 if (S_GET_SEGMENT(symbolP) == SEG_REGISTER)
573 S_SET_SEGMENT(symbolP, SEG_ABSOLUTE);
575 /* At the same time, relocate all symbols to their output value */
578 segment_info[S_GET_SEGMENT(symbolP)].scnhdr.s_paddr
579 + S_GET_VALUE(symbolP));
581 where += bfd_coff_swap_sym_out(abfd, &symbolP->sy_symbol.ost_entry,
584 for (i = 0; i < numaux; i++)
586 where += bfd_coff_swap_aux_out(abfd,
587 &symbolP->sy_symbol.ost_auxent[i],
588 S_GET_DATA_TYPE(symbolP),
589 S_GET_STORAGE_CLASS(symbolP),
599 void obj_symbol_new_hook(symbolP)
602 char underscore = 0; /* Symbol has leading _ */
604 /* Effective symbol */
605 /* Store the pointer in the offset. */
606 S_SET_ZEROES(symbolP, 0L);
607 S_SET_DATA_TYPE(symbolP, T_NULL);
608 S_SET_STORAGE_CLASS(symbolP, 0);
609 S_SET_NUMBER_AUXILIARY(symbolP, 0);
610 /* Additional information */
611 symbolP->sy_symbol.ost_flags = 0;
612 /* Auxiliary entries */
613 bzero((char*)&symbolP->sy_symbol.ost_auxent[0], AUXESZ);
615 #ifdef STRIP_UNDERSCORE
616 /* Remove leading underscore at the beginning of the symbol.
617 * This is to be compatible with the standard librairies.
619 if (*S_GET_NAME(symbolP) == '_') {
621 S_SET_NAME(symbolP, S_GET_NAME(symbolP) + 1);
622 } /* strip underscore */
623 #endif /* STRIP_UNDERSCORE */
625 if (S_IS_STRING(symbolP))
626 SF_SET_STRING(symbolP);
627 if (!underscore && S_IS_LOCAL(symbolP))
628 SF_SET_LOCAL(symbolP);
631 } /* obj_symbol_new_hook() */
634 stack* stack_init(chunk_size, element_size)
635 unsigned long chunk_size;
636 unsigned long element_size;
640 if ((st = (stack*)malloc(sizeof(stack))) == (stack*)0)
642 if ((st->data = malloc(chunk_size)) == (char*)0) {
647 st->size = chunk_size;
648 st->chunk_size = chunk_size;
649 st->element_size = element_size;
653 void stack_delete(st)
660 char *stack_push(st, element)
664 if (st->pointer + st->element_size >= st->size) {
665 st->size += st->chunk_size;
666 if ((st->data = xrealloc(st->data, st->size)) == (char*)0)
669 memcpy(st->data + st->pointer, element, st->element_size);
670 st->pointer += st->element_size;
671 return st->data + st->pointer;
677 if ((st->pointer -= st->element_size) < 0) {
682 return st->data + st->pointer;
688 return st->data + st->pointer - st->element_size;
693 * Handle .ln directives.
696 static void obj_coff_ln()
700 if (def_symbol_in_progress != NULL) {
701 as_warn(".ln pseudo-op inside .def/.endef: ignored.");
702 demand_empty_rest_of_line();
704 } /* wrong context */
707 obstack_next_free(&frags) - frag_now->fr_literal,
708 l = get_absolute_expression(),
716 listing_source_line(l + line_base - 1);
721 demand_empty_rest_of_line();
723 } /* obj_coff_line() */
728 * Handle .def directives.
730 * One might ask : why can't we symbol_new if the symbol does not
731 * already exist and fill it with debug information. Because of
732 * the C_EFCN special symbol. It would clobber the value of the
733 * function symbol before we have a chance to notice that it is
734 * a C_EFCN. And a second reason is that the code is more clear this
735 * way. (at least I think it is :-).
739 #define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';')
740 #define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \
741 *input_line_pointer == '\t') \
742 input_line_pointer++;
745 DEFUN(obj_coff_def,(what),
748 char name_end; /* Char after the end of name */
749 char *symbol_name; /* Name of the debug symbol */
750 char *symbol_name_copy; /* Temporary copy of the name */
751 unsigned int symbol_name_length;
752 /*$char* directiveP;$ */ /* Name of the pseudo opcode */
753 /*$char directive[MAX_DIRECTIVE];$ */ /* Backup of the directive */
754 /*$char end = 0;$ */ /* If 1, stop parsing */
756 if (def_symbol_in_progress != NULL) {
757 as_warn(".def pseudo-op used inside of .def/.endef: ignored.");
758 demand_empty_rest_of_line();
760 } /* if not inside .def/.endef */
764 def_symbol_in_progress = (symbolS *) obstack_alloc(¬es, sizeof(*def_symbol_in_progress));
765 bzero(def_symbol_in_progress, sizeof(*def_symbol_in_progress));
767 symbol_name = input_line_pointer;
768 name_end = get_symbol_end();
769 symbol_name_length = strlen(symbol_name);
770 symbol_name_copy = xmalloc(symbol_name_length + 1);
771 strcpy(symbol_name_copy, symbol_name);
773 /* Initialize the new symbol */
774 #ifdef STRIP_UNDERSCORE
775 S_SET_NAME(def_symbol_in_progress, (*symbol_name_copy == '_'
776 ? symbol_name_copy + 1
777 : symbol_name_copy));
778 #else /* STRIP_UNDERSCORE */
779 S_SET_NAME(def_symbol_in_progress, symbol_name_copy);
780 #endif /* STRIP_UNDERSCORE */
781 /* free(symbol_name_copy); */
782 def_symbol_in_progress->sy_name_offset = ~0;
783 def_symbol_in_progress->sy_number = ~0;
784 def_symbol_in_progress->sy_frag = &zero_address_frag;
786 if (S_IS_STRING(def_symbol_in_progress)) {
787 SF_SET_STRING(def_symbol_in_progress);
790 *input_line_pointer = name_end;
792 demand_empty_rest_of_line();
794 } /* obj_coff_def() */
796 unsigned int dim_index;
798 DEFUN_VOID(obj_coff_endef)
800 symbolS *symbolP = 0;
801 /* DIM BUG FIX sac@cygnus.com */
803 if (def_symbol_in_progress == NULL) {
804 as_warn(".endef pseudo-op used outside of .def/.endef: ignored.");
805 demand_empty_rest_of_line();
807 } /* if not inside .def/.endef */
809 /* Set the section number according to storage class. */
810 switch (S_GET_STORAGE_CLASS(def_symbol_in_progress)) {
814 SF_SET_TAG(def_symbol_in_progress);
815 /* intentional fallthrough */
818 SF_SET_DEBUG(def_symbol_in_progress);
819 S_SET_SEGMENT(def_symbol_in_progress, SEG_DEBUG);
823 SF_SET_LOCAL(def_symbol_in_progress); /* Do not emit this symbol. */
824 /* intentional fallthrough */
826 SF_SET_PROCESS(def_symbol_in_progress); /* Will need processing before writing */
827 /* intentional fallthrough */
829 S_SET_SEGMENT(def_symbol_in_progress, SEG_E0);
831 if (def_symbol_in_progress->sy_symbol.ost_entry._n._n_nptr[1][1] == 'b') { /* .bf */
832 if (function_lineoff < 0) {
833 fprintf(stderr, "`.bf' symbol without preceding function\n");
834 } /* missing function symbol */
835 SA_GET_SYM_LNNOPTR(last_line_symbol) = function_lineoff;
837 SF_SET_PROCESS(last_line_symbol);
838 function_lineoff = -1;
844 #endif /* C_AUTOARG */
854 SF_SET_DEBUG(def_symbol_in_progress);
855 S_SET_SEGMENT(def_symbol_in_progress, SEG_ABSOLUTE);
861 /* Valid but set somewhere else (s_comm, s_lcomm, colon) */
867 as_warn("unexpected storage class %d", S_GET_STORAGE_CLASS(def_symbol_in_progress));
869 } /* switch on storage class */
871 /* Now that we have built a debug symbol, try to
872 find if we should merge with an existing symbol
873 or not. If a symbol is C_EFCN or SEG_ABSOLUTE or
874 untagged SEG_DEBUG it never merges. */
876 /* Two cases for functions. Either debug followed
877 by definition or definition followed by debug.
878 For definition first, we will merge the debug
879 symbol into the definition. For debug first, the
880 lineno entry MUST point to the definition
881 function or else it will point off into space
882 when crawl_symbols() merges the debug
883 symbol into the real symbol. Therefor, let's
884 presume the debug symbol is a real function
887 /* FIXME-SOON If for some reason the definition
888 label/symbol is never seen, this will probably
889 leave an undefined symbol at link time. */
891 if (S_GET_STORAGE_CLASS(def_symbol_in_progress) == C_EFCN
892 || (S_GET_SEGMENT(def_symbol_in_progress) == SEG_DEBUG
893 && !SF_GET_TAG(def_symbol_in_progress))
894 || S_GET_SEGMENT(def_symbol_in_progress) == SEG_ABSOLUTE
895 || (symbolP = symbol_find_base(S_GET_NAME(def_symbol_in_progress), DO_NOT_STRIP)) == NULL) {
897 symbol_append(def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
900 /* This symbol already exists, merge the
901 newly created symbol into the old one.
902 This is not mandatory. The linker can
903 handle duplicate symbols correctly. But I
904 guess that it save a *lot* of space if
905 the assembly file defines a lot of
908 /* The debug entry (def_symbol_in_progress)
909 is merged into the previous definition. */
911 c_symbol_merge(def_symbol_in_progress, symbolP);
912 /* FIXME-SOON Should *def_symbol_in_progress be free'd? xoxorich. */
913 def_symbol_in_progress = symbolP;
915 if (SF_GET_FUNCTION(def_symbol_in_progress)
916 || SF_GET_TAG(def_symbol_in_progress)) {
917 /* For functions, and tags, the symbol *must* be where the debug symbol
918 appears. Move the existing symbol to the current place. */
919 /* If it already is at the end of the symbol list, do nothing */
920 if (def_symbol_in_progress != symbol_lastP) {
921 symbol_remove(def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
922 symbol_append(def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
923 } /* if not already in place */
925 } /* normal or mergable */
927 if (SF_GET_TAG(def_symbol_in_progress)
928 && symbol_find_base(S_GET_NAME(def_symbol_in_progress), DO_NOT_STRIP) == NULL) {
929 tag_insert(S_GET_NAME(def_symbol_in_progress), def_symbol_in_progress);
930 } /* If symbol is a {structure,union} tag, associate symbol to its name. */
932 if (SF_GET_FUNCTION(def_symbol_in_progress)) {
933 know(sizeof(def_symbol_in_progress) <= sizeof(long));
935 = c_line_new(def_symbol_in_progress,0, 0, &zero_address_frag);
939 SF_SET_PROCESS(def_symbol_in_progress);
941 if (symbolP == NULL) {
942 /* That is, if this is the first
943 time we've seen the function... */
944 symbol_table_insert(def_symbol_in_progress);
945 } /* definition follows debug */
946 } /* Create the line number entry pointing to the function being defined */
948 def_symbol_in_progress = NULL;
949 demand_empty_rest_of_line();
951 } /* obj_coff_endef() */
954 DEFUN_VOID(obj_coff_dim)
956 register int dim_index;
958 if (def_symbol_in_progress == NULL)
960 as_warn(".dim pseudo-op used outside of .def/.endef: ignored.");
961 demand_empty_rest_of_line();
963 } /* if not inside .def/.endef */
965 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1);
967 for (dim_index = 0; dim_index < DIMNUM; dim_index++)
970 SA_SET_SYM_DIMEN(def_symbol_in_progress, dim_index, get_absolute_expression());
972 switch (*input_line_pointer)
976 input_line_pointer++;
980 as_warn("badly formed .dim directive ignored");
981 /* intentional fallthrough */
986 } /* switch on following character */
987 } /* for each dimension */
989 demand_empty_rest_of_line();
991 } /* obj_coff_dim() */
993 static void obj_coff_line()
997 if (def_symbol_in_progress == NULL) {
1000 } /* if it looks like a stabs style line */
1002 this_base = get_absolute_expression();
1003 if (this_base > line_base)
1005 line_base = this_base;
1013 listing_source_line(line_base);
1017 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1);
1018 SA_SET_SYM_LNNO(def_symbol_in_progress, line_base);
1020 demand_empty_rest_of_line();
1022 } /* obj_coff_line() */
1024 static void obj_coff_size() {
1025 if (def_symbol_in_progress == NULL) {
1026 as_warn(".size pseudo-op used outside of .def/.endef ignored.");
1027 demand_empty_rest_of_line();
1029 } /* if not inside .def/.endef */
1031 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1);
1032 SA_SET_SYM_SIZE(def_symbol_in_progress, get_absolute_expression());
1033 demand_empty_rest_of_line();
1035 } /* obj_coff_size() */
1037 static void obj_coff_scl() {
1038 if (def_symbol_in_progress == NULL) {
1039 as_warn(".scl pseudo-op used outside of .def/.endef ignored.");
1040 demand_empty_rest_of_line();
1042 } /* if not inside .def/.endef */
1044 S_SET_STORAGE_CLASS(def_symbol_in_progress, get_absolute_expression());
1045 demand_empty_rest_of_line();
1047 } /* obj_coff_scl() */
1049 static void obj_coff_tag() {
1053 if (def_symbol_in_progress == NULL) {
1054 as_warn(".tag pseudo-op used outside of .def/.endef ignored.");
1055 demand_empty_rest_of_line();
1057 } /* if not inside .def/.endef */
1059 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1);
1060 symbol_name = input_line_pointer;
1061 name_end = get_symbol_end();
1063 /* Assume that the symbol referred to by .tag is always defined. */
1064 /* This was a bad assumption. I've added find_or_make. xoxorich. */
1065 SA_SET_SYM_TAGNDX(def_symbol_in_progress, (long) tag_find_or_make(symbol_name));
1066 if (SA_GET_SYM_TAGNDX(def_symbol_in_progress) == 0L) {
1067 as_warn("tag not found for .tag %s", symbol_name);
1070 SF_SET_TAGGED(def_symbol_in_progress);
1071 *input_line_pointer = name_end;
1073 demand_empty_rest_of_line();
1075 } /* obj_coff_tag() */
1077 static void obj_coff_type() {
1078 if (def_symbol_in_progress == NULL) {
1079 as_warn(".type pseudo-op used outside of .def/.endef ignored.");
1080 demand_empty_rest_of_line();
1082 } /* if not inside .def/.endef */
1084 S_SET_DATA_TYPE(def_symbol_in_progress, get_absolute_expression());
1086 if (ISFCN(S_GET_DATA_TYPE(def_symbol_in_progress)) &&
1087 S_GET_STORAGE_CLASS(def_symbol_in_progress) != C_TPDEF) {
1088 SF_SET_FUNCTION(def_symbol_in_progress);
1089 } /* is a function */
1091 demand_empty_rest_of_line();
1093 } /* obj_coff_type() */
1095 static void obj_coff_val() {
1096 if (def_symbol_in_progress == NULL) {
1097 as_warn(".val pseudo-op used outside of .def/.endef ignored.");
1098 demand_empty_rest_of_line();
1100 } /* if not inside .def/.endef */
1102 if (is_name_beginner(*input_line_pointer)) {
1103 char *symbol_name = input_line_pointer;
1104 char name_end = get_symbol_end();
1106 if (!strcmp(symbol_name, ".")) {
1107 def_symbol_in_progress->sy_frag = frag_now;
1108 S_SET_VALUE(def_symbol_in_progress, obstack_next_free(&frags) - frag_now->fr_literal);
1109 /* If the .val is != from the .def (e.g. statics) */
1110 } else if (strcmp(S_GET_NAME(def_symbol_in_progress), symbol_name)) {
1111 def_symbol_in_progress->sy_forward = symbol_find_or_make(symbol_name);
1113 /* If the segment is undefined when the forward
1114 reference is solved, then copy the segment id
1115 from the forward symbol. */
1116 SF_SET_GET_SEGMENT(def_symbol_in_progress);
1118 /* Otherwise, it is the name of a non debug symbol and its value will be calculated later. */
1119 *input_line_pointer = name_end;
1121 S_SET_VALUE(def_symbol_in_progress, get_absolute_expression());
1122 } /* if symbol based */
1124 demand_empty_rest_of_line();
1126 } /* obj_coff_val() */
1129 * Maintain a list of the tagnames of the structres.
1132 static void tag_init() {
1133 tag_hash = hash_new();
1137 static void tag_insert(name, symbolP)
1141 register char * error_string;
1143 if (*(error_string = hash_jam(tag_hash, name, (char *)symbolP))) {
1144 as_fatal("Inserting \"%s\" into structure table failed: %s",
1145 name, error_string);
1148 } /* tag_insert() */
1150 static symbolS *tag_find_or_make(name)
1155 if ((symbolP = tag_find(name)) == NULL) {
1156 symbolP = symbol_new(name,
1159 &zero_address_frag);
1161 tag_insert(S_GET_NAME(symbolP), symbolP);
1162 symbol_table_insert(symbolP);
1166 } /* tag_find_or_make() */
1168 static symbolS *tag_find(name)
1171 #ifdef STRIP_UNDERSCORE
1172 if (*name == '_') name++;
1173 #endif /* STRIP_UNDERSCORE */
1174 return((symbolS*)hash_find(tag_hash, name));
1177 void obj_read_begin_hook() {
1178 /* These had better be the same. Usually 18 bytes. */
1180 know(sizeof(SYMENT) == sizeof(AUXENT));
1181 know(SYMESZ == AUXESZ);
1186 } /* obj_read_begin_hook() */
1188 /* This function runs through the symbol table and puts all the
1189 externals onto another chain */
1191 /* The chain of externals */
1192 symbolS *symbol_externP = NULL;
1193 symbolS *symbol_extern_lastP = NULL;
1196 symbolS *last_functionP = NULL;
1200 static unsigned int DEFUN_VOID(yank_symbols)
1203 unsigned int symbol_number =0;
1205 for (symbolP = symbol_rootP;
1207 symbolP = symbolP ? symbol_next(symbolP) : symbol_rootP) {
1208 if (!SF_GET_DEBUG(symbolP)) {
1209 /* Debug symbols do not need all this rubbish */
1210 symbolS* real_symbolP;
1212 /* L* and C_EFCN symbols never merge. */
1213 if (!SF_GET_LOCAL(symbolP)
1214 && (real_symbolP = symbol_find_base(S_GET_NAME(symbolP), DO_NOT_STRIP))
1215 && real_symbolP != symbolP) {
1216 /* FIXME-SOON: where do dups come from?
1217 Maybe tag references before definitions? xoxorich. */
1218 /* Move the debug data from the debug symbol to the
1219 real symbol. Do NOT do the oposite (i.e. move from
1220 real symbol to debug symbol and remove real symbol from the
1221 list.) Because some pointers refer to the real symbol
1222 whereas no pointers refer to the debug symbol. */
1223 c_symbol_merge(symbolP, real_symbolP);
1224 /* Replace the current symbol by the real one */
1225 /* The symbols will never be the last or the first
1226 because : 1st symbol is .file and 3 last symbols are
1227 .text, .data, .bss */
1228 symbol_remove(real_symbolP, &symbol_rootP, &symbol_lastP);
1229 symbol_insert(real_symbolP, symbolP, &symbol_rootP, &symbol_lastP);
1230 symbol_remove(symbolP, &symbol_rootP, &symbol_lastP);
1231 symbolP = real_symbolP;
1232 } /* if not local but dup'd */
1234 if (flagseen['R'] && (S_GET_SEGMENT(symbolP) == SEG_E1)) {
1235 S_SET_SEGMENT(symbolP, SEG_E0);
1236 } /* push data into text */
1238 S_SET_VALUE(symbolP,
1239 S_GET_VALUE(symbolP) + symbolP->sy_frag->fr_address);
1241 if (!S_IS_DEFINED(symbolP) && !SF_GET_LOCAL(symbolP))
1243 S_SET_EXTERNAL(symbolP);
1245 else if (S_GET_STORAGE_CLASS(symbolP) == C_NULL)
1247 if (S_GET_SEGMENT(symbolP) == SEG_E0)
1249 S_SET_STORAGE_CLASS(symbolP, C_LABEL);
1253 S_SET_STORAGE_CLASS(symbolP, C_STAT);
1257 /* Mainly to speed up if not -g */
1258 if (SF_GET_PROCESS(symbolP))
1260 /* Handle the nested blocks auxiliary info. */
1261 if (S_GET_STORAGE_CLASS(symbolP) == C_BLOCK) {
1262 if (!strcmp(S_GET_NAME(symbolP), ".bb"))
1263 stack_push(block_stack, (char *) &symbolP);
1265 register symbolS* begin_symbolP;
1266 begin_symbolP = *(symbolS**)stack_pop(block_stack);
1267 if (begin_symbolP == (symbolS*)0)
1268 as_warn("mismatched .eb");
1270 SA_SET_SYM_ENDNDX(begin_symbolP, symbol_number+2);
1273 /* If we are able to identify the type of a function, and we
1274 are out of a function (last_functionP == 0) then, the
1275 function symbol will be associated with an auxiliary
1277 if (last_functionP == (symbolS*)0 &&
1278 SF_GET_FUNCTION(symbolP)) {
1279 last_functionP = symbolP;
1281 if (S_GET_NUMBER_AUXILIARY(symbolP) < 1) {
1282 S_SET_NUMBER_AUXILIARY(symbolP, 1);
1283 } /* make it at least 1 */
1285 /* Clobber possible stale .dim information. */
1287 /* Iffed out by steve - this fries the lnnoptr info too */
1288 bzero(symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen,
1289 sizeof(symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen));
1292 /* The C_FCN doesn't need any additional information.
1293 I don't even know if this is needed for sdb. But the
1294 standard assembler generates it, so...
1296 if (S_GET_STORAGE_CLASS(symbolP) == C_EFCN) {
1297 if (last_functionP == (symbolS*)0)
1298 as_fatal("C_EFCN symbol out of scope");
1299 SA_SET_SYM_FSIZE(last_functionP,
1300 (long)(S_GET_VALUE(symbolP) -
1301 S_GET_VALUE(last_functionP)));
1302 SA_SET_SYM_ENDNDX(last_functionP, symbol_number);
1303 last_functionP = (symbolS*)0;
1306 } else if (SF_GET_TAG(symbolP)) {
1307 /* First descriptor of a structure must point to
1308 the first slot after the structure description. */
1309 last_tagP = symbolP;
1311 } else if (S_GET_STORAGE_CLASS(symbolP) == C_EOS) {
1312 /* +2 take in account the current symbol */
1313 SA_SET_SYM_ENDNDX(last_tagP, symbol_number + 2);
1314 } else if (S_GET_STORAGE_CLASS(symbolP) == C_FILE) {
1315 if (S_GET_VALUE(symbolP)) {
1316 S_SET_VALUE((symbolS *) S_GET_VALUE(symbolP), symbol_number);
1317 S_SET_VALUE(symbolP, 0);
1318 } /* no one points at the first .file symbol */
1319 } /* if debug or tag or eos or file */
1321 /* We must put the external symbols apart. The loader
1322 does not bomb if we do not. But the references in
1323 the endndx field for a .bb symbol are not corrected
1324 if an external symbol is removed between .bb and .be.
1325 I.e in the following case :
1326 [20] .bb endndx = 22
1329 ld will move the symbol 21 to the end of the list but
1330 endndx will still be 22 instead of 21. */
1333 if (SF_GET_LOCAL(symbolP)) {
1334 /* remove C_EFCN and LOCAL (L...) symbols */
1335 /* next pointer remains valid */
1336 symbol_remove(symbolP, &symbol_rootP, &symbol_lastP);
1339 else if (!S_IS_DEFINED(symbolP)
1340 && !S_IS_DEBUG(symbolP)
1341 && !SF_GET_STATICS(symbolP) &&
1342 S_GET_STORAGE_CLASS(symbolP) == C_EXT)
1343 { /* C_EXT && !SF_GET_FUNCTION(symbolP)) */
1344 /* if external, Remove from the list */
1345 symbolS *hold = symbol_previous(symbolP);
1347 symbol_remove(symbolP, &symbol_rootP, &symbol_lastP);
1348 symbol_clear_list_pointers(symbolP);
1349 symbol_append(symbolP, symbol_extern_lastP, &symbol_externP, &symbol_extern_lastP);
1352 if (SF_GET_STRING(symbolP)) {
1353 symbolP->sy_name_offset = string_byte_count;
1354 string_byte_count += strlen(S_GET_NAME(symbolP)) + 1;
1356 symbolP->sy_name_offset = 0;
1357 } /* fix "long" names */
1359 symbolP->sy_number = symbol_number;
1360 symbol_number += 1 + S_GET_NUMBER_AUXILIARY(symbolP);
1361 } /* if local symbol */
1362 } /* traverse the symbol list */
1363 return symbol_number;
1368 static unsigned int DEFUN_VOID(glue_symbols)
1370 unsigned int symbol_number = 0;
1372 for (symbolP = symbol_externP; symbol_externP;) {
1373 symbolS *tmp = symbol_externP;
1376 symbol_remove(tmp, &symbol_externP, &symbol_extern_lastP);
1377 symbol_append(tmp, symbol_lastP, &symbol_rootP, &symbol_lastP);
1380 if (SF_GET_STRING(tmp)) {
1381 tmp->sy_name_offset = string_byte_count;
1382 string_byte_count += strlen(S_GET_NAME(tmp)) + 1;
1384 tmp->sy_name_offset = 0;
1385 } /* fix "long" names */
1387 tmp->sy_number = symbol_number;
1388 symbol_number += 1 + S_GET_NUMBER_AUXILIARY(tmp);
1389 } /* append the entire extern chain */
1390 return symbol_number;
1394 static unsigned int DEFUN_VOID(tie_tags)
1396 unsigned int symbol_number = 0;
1399 for (symbolP = symbol_rootP; symbolP; symbolP =
1400 symbol_next(symbolP))
1402 symbolP->sy_number = symbol_number;
1406 if (SF_GET_TAGGED(symbolP))
1410 ((symbolS*) SA_GET_SYM_TAGNDX(symbolP))->sy_number);
1413 symbol_number += 1 + S_GET_NUMBER_AUXILIARY(symbolP);
1415 return symbol_number;
1420 DEFUN(crawl_symbols,(headers, abfd),
1421 struct internal_filehdr *headers AND
1426 unsigned int ptr = 0;
1431 /* Initialize the stack used to keep track of the matching .bb .be */
1433 block_stack = stack_init(512, sizeof(symbolS*));
1434 /* JF deal with forward references first... */
1435 for (symbolP = symbol_rootP;
1437 symbolP = symbol_next(symbolP))
1440 if (symbolP->sy_forward) {
1441 S_SET_VALUE(symbolP, (S_GET_VALUE(symbolP)
1442 + S_GET_VALUE(symbolP->sy_forward)
1443 + symbolP->sy_forward->sy_frag->fr_address));
1445 if (SF_GET_GET_SEGMENT(symbolP)) {
1446 S_SET_SEGMENT(symbolP, S_GET_SEGMENT(symbolP->sy_forward));
1447 } /* forward segment also */
1449 symbolP->sy_forward=0;
1450 } /* if it has a forward reference */
1451 } /* walk the symbol chain */
1454 /* The symbol list should be ordered according to the following sequence
1457 * . debug entries for functions
1458 * . fake symbols for the sections, including.text .data and .bss
1460 * . undefined symbols
1461 * But this is not mandatory. The only important point is to put the
1462 * undefined symbols at the end of the list.
1465 if (symbol_rootP == NULL
1466 || S_GET_STORAGE_CLASS(symbol_rootP) != C_FILE) {
1467 c_dot_file_symbol("fake");
1469 /* Is there a .file symbol ? If not insert one at the beginning. */
1472 * Build up static symbols for the sections, they are filled in later
1476 for (i = SEG_E0; i < SEG_E9; i++)
1478 if (segment_info[i].scnhdr.s_name[0])
1480 segment_info[i].dot =
1481 c_section_symbol(segment_info[i].scnhdr.s_name,
1488 /* Take all the externals out and put them into another chain */
1489 headers->f_nsyms = yank_symbols();
1490 /* Take the externals and glue them onto the end.*/
1491 headers->f_nsyms += glue_symbols();
1493 headers->f_nsyms = tie_tags();
1494 know(symbol_externP == NULL);
1495 know(symbol_extern_lastP == NULL);
1501 * Find strings by crawling along symbol table chain.
1504 void DEFUN(w_strings,(where),
1509 /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
1510 md_number_to_chars(where, string_byte_count, sizeof(string_byte_count));
1511 where += sizeof(string_byte_count);
1512 for (symbolP = symbol_rootP;
1514 symbolP = symbol_next(symbolP))
1518 if (SF_GET_STRING(symbolP)) {
1519 size = strlen(S_GET_NAME(symbolP)) + 1;
1521 memcpy(where, S_GET_NAME(symbolP),size);
1534 DEFUN(do_linenos_for,(abfd, file_cursor),
1536 unsigned long *file_cursor)
1540 for (idx = SEG_E0; idx < SEG_E9; idx++)
1542 segment_info_type *s = segment_info + idx;
1545 if (s->scnhdr.s_nlnno != 0)
1547 struct lineno_list *line_ptr ;
1549 struct external_lineno *buffer =
1550 (struct external_lineno *)xmalloc(s->scnhdr.s_nlnno * LINESZ);
1552 struct external_lineno *dst= buffer;
1554 /* Run through the table we've built and turn it into its external
1555 form, take this chance to remove duplicates */
1557 for (line_ptr = s->lineno_list_head;
1558 line_ptr != (struct lineno_list *)NULL;
1559 line_ptr = line_ptr->next)
1562 if (line_ptr->line.l_lnno == 0)
1564 /* Turn a pointer to a symbol into the symbols' index */
1565 line_ptr->line.l_addr.l_symndx =
1566 ( (symbolS *)line_ptr->line.l_addr.l_symndx)->sy_number;
1570 line_ptr->line.l_addr.l_paddr += ((struct frag * )(line_ptr->frag))->fr_address;
1574 (void) bfd_coff_swap_lineno_out(abfd, &(line_ptr->line), dst);
1579 s->scnhdr.s_lnnoptr = *file_cursor;
1581 bfd_write(buffer, 1, s->scnhdr.s_nlnno* LINESZ, abfd);
1584 *file_cursor += s->scnhdr.s_nlnno * LINESZ;
1590 /* Now we run through the list of frag chains in a segment and
1591 make all the subsegment frags appear at the end of the
1592 list, as if the seg 0 was extra long */
1594 static void DEFUN_VOID(remove_subsegs)
1598 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
1600 frchainS *head = segment_info[i].frchainP;
1602 fragS * prev_frag = &dummy;
1604 while (head && head->frch_seg == i)
1606 prev_frag->fr_next = head->frch_root;
1607 prev_frag = head->frch_last;
1608 head = head->frch_next;
1610 prev_frag->fr_next = 0;
1615 extern void DEFUN_VOID(write_object_file)
1618 struct frchain *frchain_ptr;
1620 struct internal_filehdr filehdr;
1621 struct internal_aouthdr aouthdr;
1622 unsigned long file_cursor;
1624 unsigned int addr = 0;
1625 abfd = bfd_openw(out_file_name, TARGET_FORMAT);
1629 as_perror ("FATAL: Can't create %s", out_file_name);
1632 bfd_set_format(abfd, bfd_object);
1633 bfd_set_arch_mach(abfd, BFD_ARCH, 0);
1637 string_byte_count = 4;
1639 for (frchain_ptr = frchain_root;
1640 frchain_ptr != (struct frchain *)NULL;
1641 frchain_ptr = frchain_ptr->frch_next) {
1642 /* Run through all the sub-segments and align them up. Also close any
1643 open frags. We tack a .fill onto the end of the frag chain so
1644 that any .align's size can be worked by looking at the next
1647 subseg_new(frchain_ptr->frch_seg, frchain_ptr->frch_subseg);
1648 #define SUB_SEGMENT_ALIGN 1
1649 frag_align(SUB_SEGMENT_ALIGN,0);
1650 frag_wane(frag_now);
1651 frag_now->fr_fix = 0;
1652 know( frag_now->fr_next == NULL );
1659 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
1661 relax_segment(segment_info[i].frchainP->frch_root, i);
1668 filehdr.f_nscns = 0;
1670 /* Find out how big the sections are */
1671 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
1674 if (segment_info[i].scnhdr.s_name[0])
1681 /* THis is a special case, we leave the size alone, which will have */
1682 /* been made up from all and any lcomms seen */
1685 addr += size_section(abfd, i);
1691 /* Turn the gas native symbol table shape into a coff symbol table */
1692 crawl_symbols(&filehdr, abfd);
1694 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
1696 fixup_segment(segment_info[i].fix_root, i);
1700 file_cursor = FILHSZ + SCNHSZ * filehdr.f_nscns ;
1702 bfd_seek(abfd, file_cursor, 0);
1705 do_relocs_for(abfd, &file_cursor);
1707 do_linenos_for(abfd, &file_cursor);
1710 /* Plant the data */
1712 fill_section(abfd,&filehdr, &file_cursor);
1714 filehdr.f_magic = COFF_MAGIC;
1715 filehdr.f_timdat = time(0);
1716 filehdr.f_flags = COFF_FLAGS ;
1720 filehdr.f_flags |= F_LNNO;
1724 filehdr.f_flags |= F_RELFLG;
1735 unsigned int symtable_size = filehdr.f_nsyms * SYMESZ;
1736 char *buffer1 = malloc(symtable_size + string_byte_count + 4);
1737 char *ptr = buffer1;
1738 filehdr.f_symptr = bfd_tell(abfd);
1739 w_symbols(abfd, buffer1, symbol_rootP);
1740 w_strings(buffer1 + symtable_size);
1741 bfd_write(buffer1, 1,symtable_size + string_byte_count + 4, abfd);
1745 coff_header_append(abfd, &filehdr, &aouthdr);
1747 bfd_close_all_done(abfd);
1751 static void DEFUN(change_to_section,(name, len, exp),
1753 unsigned int len AND
1757 /* Find out if we've already got a section of this name etc */
1758 for(i = SEG_E0; i < SEG_E9 && segment_info[i].scnhdr.s_name[0] ; i++)
1760 if (strncmp(segment_info[i].scnhdr.s_name, name, len) == 0)
1767 /* No section, add one */
1768 strncpy(segment_info[i].scnhdr.s_name, name, 8);
1773 DEFUN_VOID(obj_coff_section)
1775 /* Strip out the section name */
1776 char *section_name ;
1777 char *section_name_end;
1783 section_name = input_line_pointer;
1784 c = get_symbol_end();
1785 section_name_end = input_line_pointer;
1787 len = section_name_end - section_name ;
1788 input_line_pointer++;
1792 exp = get_absolute_expression();
1794 else if ( *input_line_pointer == ',')
1797 input_line_pointer++;
1798 exp = get_absolute_expression();
1805 change_to_section(section_name, len,exp);
1806 *section_name_end = c;
1811 static void obj_coff_text()
1813 change_to_section(".text",5, get_absolute_expression());
1817 static void obj_coff_data()
1819 change_to_section(".data",5, get_absolute_expression());
1822 void c_symbol_merge(debug, normal)
1826 S_SET_DATA_TYPE(normal, S_GET_DATA_TYPE(debug));
1827 S_SET_STORAGE_CLASS(normal, S_GET_STORAGE_CLASS(debug));
1829 if (S_GET_NUMBER_AUXILIARY(debug) > S_GET_NUMBER_AUXILIARY(normal)) {
1830 S_SET_NUMBER_AUXILIARY(normal, S_GET_NUMBER_AUXILIARY(debug));
1831 } /* take the most we have */
1833 if (S_GET_NUMBER_AUXILIARY(debug) > 0) {
1834 memcpy((char*)&normal->sy_symbol.ost_auxent[0], (char*)&debug->sy_symbol.ost_auxent[0], S_GET_NUMBER_AUXILIARY(debug) * AUXESZ);
1835 } /* Move all the auxiliary information */
1837 /* Move the debug flags. */
1838 SF_SET_DEBUG_FIELD(normal, SF_GET_DEBUG_FIELD(debug));
1839 } /* c_symbol_merge() */
1842 DEFUN(c_line_new,(symbol, paddr, line_number, frag),
1845 unsigned short line_number AND
1848 struct lineno_list* new_line =
1849 (struct lineno_list *)xmalloc(sizeof(struct lineno_list));
1851 segment_info_type *s = segment_info + now_seg;
1852 new_line->line.l_lnno = line_number;
1856 if (line_number == 0)
1858 last_line_symbol = symbol;
1859 new_line->line.l_addr.l_symndx = (long)symbol;
1863 new_line->line.l_addr.l_paddr = paddr;
1866 new_line->frag = (char*)frag;
1867 new_line->next = (struct lineno_list*)NULL;
1870 if (s->lineno_list_head == (struct lineno_list *)NULL)
1872 s->lineno_list_head = new_line;
1876 s->lineno_list_tail->next = new_line;
1878 s->lineno_list_tail = new_line;
1879 return LINESZ * s->scnhdr.s_nlnno ++;
1882 void c_dot_file_symbol(filename)
1887 symbolP = symbol_new(".file",
1890 &zero_address_frag);
1892 S_SET_STORAGE_CLASS(symbolP, C_FILE);
1893 S_SET_NUMBER_AUXILIARY(symbolP, 1);
1894 SA_SET_FILE_FNAME(symbolP, filename);
1900 listing_source_file(filename);
1906 SF_SET_DEBUG(symbolP);
1907 S_SET_VALUE(symbolP, (long) previous_file_symbol);
1909 previous_file_symbol = symbolP;
1911 /* Make sure that the symbol is first on the symbol chain */
1912 if (symbol_rootP != symbolP) {
1913 if (symbolP == symbol_lastP) {
1914 symbol_lastP = symbol_lastP->sy_previous;
1915 } /* if it was the last thing on the list */
1917 symbol_remove(symbolP, &symbol_rootP, &symbol_lastP);
1918 symbol_insert(symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP);
1919 symbol_rootP = symbolP;
1920 } /* if not first on the list */
1922 } /* c_dot_file_symbol() */
1925 * Build a 'section static' symbol.
1928 symbolS *c_section_symbol(name,idx)
1934 symbolP = symbol_new(name,idx,
1936 &zero_address_frag);
1938 S_SET_STORAGE_CLASS(symbolP, C_STAT);
1939 S_SET_NUMBER_AUXILIARY(symbolP, 1);
1941 SF_SET_STATICS(symbolP);
1944 } /* c_section_symbol() */
1947 DEFUN(w_symbols,(abfd, where, symbol_rootP),
1950 symbolS *symbol_rootP)
1955 /* First fill in those values we have only just worked out */
1956 for (i = SEG_E0; i < SEG_E9; i++)
1958 symbolP = segment_info[i].dot;
1962 SA_SET_SCN_SCNLEN(symbolP, segment_info[i].scnhdr.s_size);
1963 SA_SET_SCN_NRELOC(symbolP, segment_info[i].scnhdr.s_nreloc);
1964 SA_SET_SCN_NLINNO(symbolP, segment_info[i].scnhdr.s_nlnno);
1970 * Emit all symbols left in the symbol chain.
1972 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) {
1973 /* Used to save the offset of the name. It is used to point
1974 to the string in memory but must be a file offset. */
1975 register char * temp;
1977 tc_coff_symbol_emit_hook(symbolP);
1979 temp = S_GET_NAME(symbolP);
1980 if (SF_GET_STRING(symbolP)) {
1981 S_SET_OFFSET(symbolP, symbolP->sy_name_offset);
1982 S_SET_ZEROES(symbolP, 0);
1984 bzero(symbolP->sy_symbol.ost_entry.n_name, SYMNMLEN);
1985 strncpy(symbolP->sy_symbol.ost_entry.n_name, temp, SYMNMLEN);
1987 where = symbol_to_chars(abfd, where, symbolP);
1988 S_SET_NAME(symbolP,temp);
1993 static void DEFUN_VOID(obj_coff_lcomm)
2000 name = input_line_pointer;
2004 c = get_symbol_end();
2005 p = input_line_pointer;
2008 if (*input_line_pointer != ',') {
2009 as_bad("Expected comma after name");
2010 ignore_rest_of_line();
2013 if (*input_line_pointer == '\n') {
2014 as_bad("Missing size expression");
2017 input_line_pointer++;
2018 if ((temp = get_absolute_expression ()) < 0) {
2019 as_warn("lcomm length (%d.) <0! Ignored.", temp);
2020 ignore_rest_of_line();
2024 symbolP = symbol_find_or_make(name);
2025 S_SET_VALUE(symbolP, segment_info[SEG_E2].scnhdr.s_size);
2026 S_SET_SEGMENT(symbolP, SEG_E2);
2027 segment_info[SEG_E2].scnhdr.s_size += temp;
2028 S_SET_STORAGE_CLASS(symbolP, C_STAT);
2029 demand_empty_rest_of_line();
2034 static void DEFUN(fixup_segment,(fixP, this_segment_type),
2035 register fixS * fixP AND
2036 segT this_segment_type)
2038 register symbolS *add_symbolP;
2039 register symbolS *sub_symbolP;
2040 register long add_number;
2042 register char *place;
2043 register long where;
2044 register char pcrel;
2045 register fragS *fragP;
2046 register segT add_symbol_segment = SEG_ABSOLUTE;
2049 for ( ; fixP; fixP = fixP->fx_next)
2051 fragP = fixP->fx_frag;
2053 where = fixP->fx_where;
2054 place = fragP->fr_literal + where;
2055 size = fixP->fx_size;
2056 add_symbolP = fixP->fx_addsy;
2058 if (fixP->fx_callj && TC_S_IS_CALLNAME(add_symbolP)) {
2059 /* Relocation should be done via the
2060 associated 'bal' entry point
2063 if (!TC_S_IS_BALNAME(tc_get_bal_of_call(add_symbolP))) {
2064 as_bad("No 'bal' entry point for leafproc %s",
2065 S_GET_NAME(add_symbolP));
2068 fixP->fx_addsy = add_symbolP = tc_get_bal_of_call(add_symbolP);
2069 } /* callj relocation */
2071 sub_symbolP = fixP->fx_subsy;
2072 add_number = fixP->fx_offset;
2073 pcrel = fixP->fx_pcrel;
2076 add_symbol_segment = S_GET_SEGMENT(add_symbolP);
2077 } /* if there is an addend */
2082 if (S_GET_SEGMENT(sub_symbolP) != SEG_ABSOLUTE) {
2083 as_bad("Negative of non-absolute symbol %s", S_GET_NAME(sub_symbolP));
2084 } /* not absolute */
2086 add_number -= S_GET_VALUE(sub_symbolP);
2088 /* if sub_symbol is in the same segment that add_symbol
2089 and add_symbol is either in DATA, TEXT, BSS or ABSOLUTE */
2090 } else if ((S_GET_SEGMENT(sub_symbolP) == add_symbol_segment)
2091 && (SEG_NORMAL(add_symbol_segment)
2092 || (add_symbol_segment == SEG_ABSOLUTE))) {
2093 /* Difference of 2 symbols from same segment. */
2094 /* Can't make difference of 2 undefineds: 'value' means */
2095 /* something different for N_UNDF. */
2097 /* Makes no sense to use the difference of 2 arbitrary symbols
2098 * as the target of a call instruction.
2100 if (fixP->fx_callj) {
2101 as_bad("callj to difference of 2 symbols");
2103 #endif /* TC_I960 */
2104 add_number += S_GET_VALUE(add_symbolP) -
2105 S_GET_VALUE(sub_symbolP);
2108 fixP->fx_addsy = NULL;
2110 /* Different segments in subtraction. */
2111 know(!(S_IS_EXTERNAL(sub_symbolP) && (S_GET_SEGMENT(sub_symbolP) == SEG_ABSOLUTE)));
2113 if ((S_GET_SEGMENT(sub_symbolP) == SEG_ABSOLUTE)) {
2114 add_number -= S_GET_VALUE(sub_symbolP);
2116 as_bad("Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %d.",
2117 segment_name(S_GET_SEGMENT(sub_symbolP)),
2118 S_GET_NAME(sub_symbolP), fragP->fr_address + where);
2121 } /* if sub_symbolP */
2124 if (add_symbol_segment == this_segment_type && pcrel) {
2126 * This fixup was made when the symbol's segment was
2127 * SEG_UNKNOWN, but it is now in the local segment.
2128 * So we know how to do the address without relocation.
2131 /* reloc_callj() may replace a 'call' with a 'calls' or a 'bal',
2132 * in which cases it modifies *fixP as appropriate. In the case
2133 * of a 'calls', no further work is required, and *fixP has been
2134 * set up to make the rest of the code below a no-op.
2137 #endif /* TC_I960 */
2139 add_number += S_GET_VALUE(add_symbolP);
2140 add_number -= md_pcrel_from (fixP);
2141 pcrel = 0; /* Lie. Don't want further pcrel processing. */
2142 fixP->fx_addsy = NULL; /* No relocations please. */
2145 switch (add_symbol_segment)
2149 reloc_callj(fixP); /* See comment about reloc_callj() above*/
2150 #endif /* TC_I960 */
2151 add_number += S_GET_VALUE(add_symbolP);
2152 fixP->fx_addsy = NULL;
2157 add_number += S_GET_VALUE(add_symbolP) +
2158 segment_info[S_GET_SEGMENT(add_symbolP)].scnhdr.s_paddr ;
2163 if ((int)fixP->fx_bit_fixP == 13) {
2164 /* This is a COBR instruction. They have only a
2165 * 13-bit displacement and are only to be used
2166 * for local branches: flag as error, don't generate
2169 as_bad("can't use COBR format with external label");
2170 fixP->fx_addsy = NULL; /* No relocations please. */
2173 #endif /* TC_I960 */
2180 } /* switch on symbol seg */
2181 } /* if not in local seg */
2182 } /* if there was a + symbol */
2185 add_number -= md_pcrel_from(fixP);
2186 if (add_symbolP == 0) {
2187 fixP->fx_addsy = & abs_symbol;
2188 } /* if there's an add_symbol */
2191 if (!fixP->fx_bit_fixP) {
2193 (add_number& ~0xFF) && (add_number&~0xFF!=(-1&~0xFF))) ||
2195 (add_number& ~0xFFFF) && (add_number&~0xFFFF!=(-1&~0xFFFF)))) {
2196 as_bad("Value of %d too large for field of %d bytes at 0x%x",
2197 add_number, size, fragP->fr_address + where);
2198 } /* generic error checking */
2199 } /* not a bit fix */
2200 /* once this fix has been applied, we don't have to output anything
2201 nothing more need be done -*/
2202 md_apply_fix(fixP, add_number);
2204 } /* For each fixS in this segment. */
2207 } /* fixup_segment() */