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) */
78 int our_lineno_number
= 0; /* we use this to build pointers from .bf's
79 into the linetable. It should match
80 exactly the values that are later
81 assigned in text_lineno_number by
84 int text_lineno_number
= 0;
86 /* Add 4 to the real value to get the index and compensate the
87 negatives. This vector is used by S_GET_SEGMENT to turn a coff
88 section number into a segment number
90 static symbolS
*previous_file_symbol
= NULL
;
91 void c_symbol_merge();
94 symbolS
*c_section_symbol();
96 void EXFUN(bfd_as_write_hook
,(struct internal_filehdr
*,
99 static void EXFUN(fixup_segment
,(fixS
* fixP
,
100 segT this_segment_type
));
102 static void EXFUN(fill_section
,(bfd
*abfd
,
103 struct internal_filehdr
*f
, unsigned
107 char *EXFUN(s_get_name
,(symbolS
*s
));
108 static symbolS
*EXFUN(tag_find_or_make
,(char *name
));
109 static symbolS
* EXFUN(tag_find
,(char *name
));
116 unsigned short line_number
,
120 static void EXFUN(w_symbols
,
123 symbolS
*symbol_rootP
));
127 static void EXFUN( obj_coff_def
,(int what
));
128 static void EXFUN( obj_coff_lcomm
,(void));
129 static void EXFUN( obj_coff_dim
,(void));
130 static void EXFUN( obj_coff_text
,(void));
131 static void EXFUN( obj_coff_data
,(void));
132 static void EXFUN( obj_coff_endef
,(void));
133 static void EXFUN( obj_coff_line
,(void));
134 static void EXFUN( obj_coff_ln
,(void));
135 static void EXFUN( obj_coff_scl
,(void));
136 static void EXFUN( obj_coff_size
,(void));
137 static void EXFUN( obj_coff_tag
,(void));
138 static void EXFUN( obj_coff_type
,(void));
139 static void EXFUN( obj_coff_val
,(void));
140 static void EXFUN( obj_coff_section
,(void));
141 static void EXFUN( tag_init
,(void));
142 static void EXFUN( tag_insert
,(char *name
, symbolS
*symbolP
));
145 static struct hash_control
*tag_hash
;
146 static symbolS
*def_symbol_in_progress
= NULL
;
148 const pseudo_typeS obj_pseudo_table
[] = {
149 { "def", obj_coff_def
, 0 },
150 { "dim", obj_coff_dim
, 0 },
151 { "endef", obj_coff_endef
, 0 },
152 { "line", obj_coff_line
, 0 },
153 { "ln", obj_coff_ln
, 0 },
154 { "scl", obj_coff_scl
, 0 },
155 { "size", obj_coff_size
, 0 },
156 { "tag", obj_coff_tag
, 0 },
157 { "type", obj_coff_type
, 0 },
158 { "val", obj_coff_val
, 0 },
159 { "section", obj_coff_section
, 0 },
160 { "text", obj_coff_text
, 0 },
161 { "data", obj_coff_data
, 0 },
162 /* we don't yet handle this. */
163 { "ident", s_ignore
, 0 },
164 { "ABORT", s_abort
, 0 },
165 { "lcomm", obj_coff_lcomm
, 0},
166 { NULL
} /* end sentinel */
167 }; /* obj_pseudo_table */
173 We allow more than just the standard 3 sections, infact, we allow
174 10 sections, (though the usual three have to be there).
176 This structure performs the mappings for us:
181 static struct internal_scnhdr bss_section_header;
182 struct internal_scnhdr data_section_header;
183 struct internal_scnhdr text_section_header;
185 const segT N_TYPE_seg [32] =
199 seg_info_type seg_info_off_by_4
[N_SEG
] =
225 {SEG_REGISTER
},0,0,0,0};
227 #define SEG_INFO_FROM_SECTION_NUMBER(x) (seg_info_off_by_4[(x)+4])
228 #define SEG_INFO_FROM_SEG_NUMBER(x) (seg_info_off_by_4[(x)])
232 DEFUN(relax_align
,(address
, alignment
),
233 register relax_addressT address AND
234 register long alignment
)
237 relax_addressT new_address
;
239 mask
= ~ ( (~0) << alignment
);
240 new_address
= (address
+ mask
) & (~ mask
);
241 return (new_address
- address
);
242 } /* relax_align() */
246 DEFUN(s_get_segment
,(x
) ,
249 return SEG_INFO_FROM_SECTION_NUMBER(x
->sy_symbol
.ost_entry
.n_scnum
).seg_t
;
254 /* calculate the size of the frag chain and fill in the section header
255 to contain all of it, also fill in the addr of the sections */
256 static unsigned int DEFUN(size_section
,(abfd
, idx
),
261 unsigned int size
= 0;
262 fragS
*frag
= segment_info
[idx
].frchainP
->frch_root
;
264 if (frag
->fr_address
!= size
) {
265 printf("Out of step\n");
266 size
= frag
->fr_address
;
268 size
+= frag
->fr_fix
;
269 switch (frag
->fr_type
) {
272 size
+= frag
->fr_offset
* frag
->fr_var
;
275 size
+= relax_align(size
, frag
->fr_offset
);
277 frag
= frag
->fr_next
;
279 segment_info
[idx
].scnhdr
.s_size
= size
;
284 static unsigned int DEFUN(count_entries_in_chain
,(idx
),
287 unsigned int nrelocs
;
290 /* Count the relocations */
291 fixup_ptr
= segment_info
[idx
].fix_root
;
293 while (fixup_ptr
!= (fixS
*)NULL
)
295 if (TC_COUNT_RELOC(fixup_ptr
))
300 if (fixup_ptr
->fx_r_type
== RELOC_CONSTH
)
309 fixup_ptr
= fixup_ptr
->fx_next
;
314 /* output all the relocations for a section */
315 void DEFUN(do_relocs_for
,(abfd
, file_cursor
),
317 unsigned long *file_cursor
)
319 unsigned int nrelocs
;
322 for (idx
= SEG_E0
; idx
< SEG_E9
; idx
++)
324 if (segment_info
[idx
].scnhdr
.s_name
[0])
327 struct external_reloc
*ext_ptr
;
328 struct external_reloc
*external_reloc_vec
;
329 unsigned int external_reloc_size
;
330 unsigned int count
= 0;
331 unsigned int base
= segment_info
[idx
].scnhdr
.s_paddr
;
332 fixS
* fix_ptr
= segment_info
[idx
].fix_root
;
333 nrelocs
= count_entries_in_chain(idx
);
334 external_reloc_size
= nrelocs
* RELSZ
;
336 (struct external_reloc
*)malloc(external_reloc_size
);
340 ext_ptr
= external_reloc_vec
;
342 /* Fill in the internal coff style reloc struct from the
347 struct internal_reloc intr
;
349 /* Only output some of the relocations */
350 if (TC_COUNT_RELOC(fix_ptr
))
352 #ifdef TC_RELOC_MANGLE
353 TC_RELOC_MANGLE(fix_ptr
, &intr
, base
);
357 symbol_ptr
= fix_ptr
->fx_addsy
;
359 intr
.r_type
= TC_COFF_FIX2RTYPE(fix_ptr
);
361 base
+ fix_ptr
->fx_frag
->fr_address
+ fix_ptr
->fx_where
;
363 intr
.r_offset
= fix_ptr
->fx_offset
;
367 /* Turn the segment of the symbol into an offset
371 dot
= segment_info
[S_GET_SEGMENT(symbol_ptr
)].dot
;
374 intr
.r_symndx
= dot
->sy_number
;
378 intr
.r_symndx
= symbol_ptr
->sy_number
;
390 (void)bfd_coff_swap_reloc_out(abfd
, &intr
, ext_ptr
);
394 /* The 29k has a special kludge for the high 16 bit reloc.
395 Two relocations are emmited, R_IHIHALF, and
396 R_IHCONST. The second one doesn't contain a symbol,
397 but uses the value for offset */
399 if (intr
.r_type
== R_IHIHALF
)
401 /* now emit the second bit */
402 intr
.r_type
= R_IHCONST
;
403 intr
.r_symndx
= fix_ptr
->fx_addnumber
;
404 (void)bfd_coff_swap_reloc_out(abfd
,&intr
,ext_ptr
);
410 fix_ptr
= fix_ptr
->fx_next
;
413 /* Write out the reloc table */
414 segment_info
[idx
].scnhdr
.s_relptr
= *file_cursor
;
415 segment_info
[idx
].scnhdr
.s_nreloc
= nrelocs
;
416 bfd_write((PTR
)external_reloc_vec
, 1, external_reloc_size
, abfd
);
417 *file_cursor
+= external_reloc_size
;
418 free( external_reloc_vec
);
424 /* run through a frag chain and write out the data to go with it, fill
425 in the scnhdrs with the info on the file postions
427 static void DEFUN(fill_section
,(abfd
, filehdr
, file_cursor
),
429 struct internal_filehdr
*filehdr AND
430 unsigned long *file_cursor
)
434 unsigned int paddr
= 0;
436 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
438 unsigned int offset
= 0;
440 struct internal_scnhdr
*s
= &( segment_info
[i
].scnhdr
);
444 fragS
*frag
= segment_info
[i
].frchainP
->frch_root
;
445 char *buffer
= malloc(s
->s_size
);
446 s
->s_scnptr
= *file_cursor
;
450 s
->s_flags
= STYP_REG
;
451 if (strcmp(s
->s_name
,".text")==0)
452 s
->s_flags
|= STYP_TEXT
;
453 else if (strcmp(s
->s_name
,".data")==0)
454 s
->s_flags
|= STYP_DATA
;
455 else if (strcmp(s
->s_name
,".bss")==0)
456 s
->s_flags
|= STYP_BSS
| STYP_NOLOAD
;
459 unsigned int fill_size
;
460 switch (frag
->fr_type
) {
467 memcpy(buffer
+ frag
->fr_address
,
470 offset
+= frag
->fr_fix
;
473 fill_size
= frag
->fr_var
;
477 unsigned int off
= frag
->fr_fix
;
478 for (count
= frag
->fr_offset
; count
; count
--)
480 memcpy(buffer
+ frag
->fr_address
+ off
,
481 frag
->fr_literal
+ frag
->fr_fix
,
493 frag
= frag
->fr_next
;
497 bfd_write(buffer
, s
->s_size
,1,abfd
);
500 *file_cursor
+= s
->s_size
;
509 /* Coff file generation & utilities */
513 DEFUN(coff_header_append
,(abfd
, filehdr
, aouthdr
),
515 struct internal_filehdr
*filehdr AND
516 struct internal_aouthdr
*aouthdr
)
522 bfd_seek(abfd
, 0, 0);
524 filehdr
.f_opthdr
= bfd_coff_swap_aouthdr_out(abfd
, aouthdr
,
527 filehdr
->f_opthdr
= 0;
529 i
= bfd_coff_swap_filehdr_out(abfd
, filehdr
, buffer
);
531 bfd_write(buffer
, i
,1, abfd
);
532 bfd_write(buffero
, filehdr
->f_opthdr
, 1, abfd
);
534 for (i
= SEG_E0
; i
< SEG_E9
; i
++)
536 if (segment_info
[i
].scnhdr
.s_name
[0])
539 bfd_coff_swap_scnhdr_out(abfd
,
540 &(segment_info
[i
].scnhdr
),
542 bfd_write(buffer
, size
, 1, abfd
);
549 DEFUN(symbol_to_chars
,(abfd
, where
, symbolP
),
554 unsigned int numaux
= symbolP
->sy_symbol
.ost_entry
.n_numaux
;
557 /* Turn any symbols with register attributes into abs symbols */
558 if (S_GET_SEGMENT(symbolP
) == SEG_REGISTER
)
560 S_SET_SEGMENT(symbolP
, SEG_ABSOLUTE
);
562 /* At the same time, relocate all symbols to their output value */
565 segment_info
[S_GET_SEGMENT(symbolP
)].scnhdr
.s_paddr
566 + S_GET_VALUE(symbolP
));
568 where
+= bfd_coff_swap_sym_out(abfd
, &symbolP
->sy_symbol
.ost_entry
,
571 for (i
= 0; i
< numaux
; i
++)
573 where
+= bfd_coff_swap_aux_out(abfd
,
574 &symbolP
->sy_symbol
.ost_auxent
[i
],
575 S_GET_DATA_TYPE(symbolP
),
576 S_GET_STORAGE_CLASS(symbolP
),
586 void obj_symbol_new_hook(symbolP
)
589 char underscore
= 0; /* Symbol has leading _ */
591 /* Effective symbol */
592 /* Store the pointer in the offset. */
593 S_SET_ZEROES(symbolP
, 0L);
594 S_SET_DATA_TYPE(symbolP
, T_NULL
);
595 S_SET_STORAGE_CLASS(symbolP
, 0);
596 S_SET_NUMBER_AUXILIARY(symbolP
, 0);
597 /* Additional information */
598 symbolP
->sy_symbol
.ost_flags
= 0;
599 /* Auxiliary entries */
600 bzero((char*)&symbolP
->sy_symbol
.ost_auxent
[0], AUXESZ
);
602 #ifdef STRIP_UNDERSCORE
603 /* Remove leading underscore at the beginning of the symbol.
604 * This is to be compatible with the standard librairies.
606 if (*S_GET_NAME(symbolP
) == '_') {
608 S_SET_NAME(symbolP
, S_GET_NAME(symbolP
) + 1);
609 } /* strip underscore */
610 #endif /* STRIP_UNDERSCORE */
612 if (S_IS_STRING(symbolP
))
613 SF_SET_STRING(symbolP
);
614 if (!underscore
&& S_IS_LOCAL(symbolP
))
615 SF_SET_LOCAL(symbolP
);
618 } /* obj_symbol_new_hook() */
621 stack
* stack_init(chunk_size
, element_size
)
622 unsigned long chunk_size
;
623 unsigned long element_size
;
627 if ((st
= (stack
*)malloc(sizeof(stack
))) == (stack
*)0)
629 if ((st
->data
= malloc(chunk_size
)) == (char*)0) {
634 st
->size
= chunk_size
;
635 st
->chunk_size
= chunk_size
;
636 st
->element_size
= element_size
;
640 void stack_delete(st
)
647 char *stack_push(st
, element
)
651 if (st
->pointer
+ st
->element_size
>= st
->size
) {
652 st
->size
+= st
->chunk_size
;
653 if ((st
->data
= xrealloc(st
->data
, st
->size
)) == (char*)0)
656 memcpy(st
->data
+ st
->pointer
, element
, st
->element_size
);
657 st
->pointer
+= st
->element_size
;
658 return st
->data
+ st
->pointer
;
664 if ((st
->pointer
-= st
->element_size
) < 0) {
669 return st
->data
+ st
->pointer
;
675 return st
->data
+ st
->pointer
- st
->element_size
;
680 * Handle .ln directives.
683 static void obj_coff_ln()
687 if (def_symbol_in_progress
!= NULL
) {
688 as_warn(".ln pseudo-op inside .def/.endef: ignored.");
689 demand_empty_rest_of_line();
691 } /* wrong context */
694 obstack_next_free(&frags
) - frag_now
->fr_literal
,
695 l
= get_absolute_expression(),
703 listing_source_line(l
+ line_base
- 1);
708 demand_empty_rest_of_line();
710 } /* obj_coff_line() */
715 * Handle .def directives.
717 * One might ask : why can't we symbol_new if the symbol does not
718 * already exist and fill it with debug information. Because of
719 * the C_EFCN special symbol. It would clobber the value of the
720 * function symbol before we have a chance to notice that it is
721 * a C_EFCN. And a second reason is that the code is more clear this
722 * way. (at least I think it is :-).
726 #define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';')
727 #define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \
728 *input_line_pointer == '\t') \
729 input_line_pointer++;
732 DEFUN(obj_coff_def
,(what
),
735 char name_end
; /* Char after the end of name */
736 char *symbol_name
; /* Name of the debug symbol */
737 char *symbol_name_copy
; /* Temporary copy of the name */
738 unsigned int symbol_name_length
;
739 /*$char* directiveP;$ */ /* Name of the pseudo opcode */
740 /*$char directive[MAX_DIRECTIVE];$ */ /* Backup of the directive */
741 /*$char end = 0;$ */ /* If 1, stop parsing */
743 if (def_symbol_in_progress
!= NULL
) {
744 as_warn(".def pseudo-op used inside of .def/.endef: ignored.");
745 demand_empty_rest_of_line();
747 } /* if not inside .def/.endef */
751 def_symbol_in_progress
= (symbolS
*) obstack_alloc(¬es
, sizeof(*def_symbol_in_progress
));
752 bzero(def_symbol_in_progress
, sizeof(*def_symbol_in_progress
));
754 symbol_name
= input_line_pointer
;
755 name_end
= get_symbol_end();
756 symbol_name_length
= strlen(symbol_name
);
757 symbol_name_copy
= xmalloc(symbol_name_length
+ 1);
758 strcpy(symbol_name_copy
, symbol_name
);
760 /* Initialize the new symbol */
761 #ifdef STRIP_UNDERSCORE
762 S_SET_NAME(def_symbol_in_progress
, (*symbol_name_copy
== '_'
763 ? symbol_name_copy
+ 1
764 : symbol_name_copy
));
765 #else /* STRIP_UNDERSCORE */
766 S_SET_NAME(def_symbol_in_progress
, symbol_name_copy
);
767 #endif /* STRIP_UNDERSCORE */
768 /* free(symbol_name_copy); */
769 def_symbol_in_progress
->sy_name_offset
= ~0;
770 def_symbol_in_progress
->sy_number
= ~0;
771 def_symbol_in_progress
->sy_frag
= &zero_address_frag
;
773 if (S_IS_STRING(def_symbol_in_progress
)) {
774 SF_SET_STRING(def_symbol_in_progress
);
777 *input_line_pointer
= name_end
;
779 demand_empty_rest_of_line();
781 } /* obj_coff_def() */
783 unsigned int dim_index
;
785 DEFUN_VOID(obj_coff_endef
)
787 symbolS
*symbolP
= 0;
788 /* DIM BUG FIX sac@cygnus.com */
790 if (def_symbol_in_progress
== NULL
) {
791 as_warn(".endef pseudo-op used outside of .def/.endef: ignored.");
792 demand_empty_rest_of_line();
794 } /* if not inside .def/.endef */
796 /* Set the section number according to storage class. */
797 switch (S_GET_STORAGE_CLASS(def_symbol_in_progress
)) {
801 SF_SET_TAG(def_symbol_in_progress
);
802 /* intentional fallthrough */
805 SF_SET_DEBUG(def_symbol_in_progress
);
806 S_SET_SEGMENT(def_symbol_in_progress
, SEG_DEBUG
);
810 SF_SET_LOCAL(def_symbol_in_progress
); /* Do not emit this symbol. */
811 /* intentional fallthrough */
813 SF_SET_PROCESS(def_symbol_in_progress
); /* Will need processing before writing */
814 /* intentional fallthrough */
816 S_SET_SEGMENT(def_symbol_in_progress
, SEG_E0
);
818 if (def_symbol_in_progress
->sy_symbol
.ost_entry
.n_name
[1] == 'b') { /* .bf */
819 if (function_lineoff
< 0) {
820 fprintf(stderr
, "`.bf' symbol without preceding function\n");
821 } /* missing function symbol */
822 SA_GET_SYM_LNNOPTR(def_symbol_in_progress
) = function_lineoff
;
823 SF_SET_PROCESS(def_symbol_in_progress
); /* Will need relocating */
824 function_lineoff
= -1;
830 #endif /* C_AUTOARG */
840 SF_SET_DEBUG(def_symbol_in_progress
);
841 S_SET_SEGMENT(def_symbol_in_progress
, SEG_ABSOLUTE
);
847 /* Valid but set somewhere else (s_comm, s_lcomm, colon) */
853 as_warn("unexpected storage class %d", S_GET_STORAGE_CLASS(def_symbol_in_progress
));
855 } /* switch on storage class */
857 /* Now that we have built a debug symbol, try to
858 find if we should merge with an existing symbol
859 or not. If a symbol is C_EFCN or SEG_ABSOLUTE or
860 untagged SEG_DEBUG it never merges. */
862 /* Two cases for functions. Either debug followed
863 by definition or definition followed by debug.
864 For definition first, we will merge the debug
865 symbol into the definition. For debug first, the
866 lineno entry MUST point to the definition
867 function or else it will point off into space
868 when crawl_symbols() merges the debug
869 symbol into the real symbol. Therefor, let's
870 presume the debug symbol is a real function
873 /* FIXME-SOON If for some reason the definition
874 label/symbol is never seen, this will probably
875 leave an undefined symbol at link time. */
877 if (S_GET_STORAGE_CLASS(def_symbol_in_progress
) == C_EFCN
878 || (S_GET_SEGMENT(def_symbol_in_progress
) == SEG_DEBUG
879 && !SF_GET_TAG(def_symbol_in_progress
))
880 || S_GET_SEGMENT(def_symbol_in_progress
) == SEG_ABSOLUTE
881 || (symbolP
= symbol_find_base(S_GET_NAME(def_symbol_in_progress
), DO_NOT_STRIP
)) == NULL
) {
883 symbol_append(def_symbol_in_progress
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
886 /* This symbol already exists, merge the
887 newly created symbol into the old one.
888 This is not mandatory. The linker can
889 handle duplicate symbols correctly. But I
890 guess that it save a *lot* of space if
891 the assembly file defines a lot of
894 /* The debug entry (def_symbol_in_progress)
895 is merged into the previous definition. */
897 c_symbol_merge(def_symbol_in_progress
, symbolP
);
898 /* FIXME-SOON Should *def_symbol_in_progress be free'd? xoxorich. */
899 def_symbol_in_progress
= symbolP
;
901 if (SF_GET_FUNCTION(def_symbol_in_progress
)
902 || SF_GET_TAG(def_symbol_in_progress
)) {
903 /* For functions, and tags, the symbol *must* be where the debug symbol
904 appears. Move the existing symbol to the current place. */
905 /* If it already is at the end of the symbol list, do nothing */
906 if (def_symbol_in_progress
!= symbol_lastP
) {
907 symbol_remove(def_symbol_in_progress
, &symbol_rootP
, &symbol_lastP
);
908 symbol_append(def_symbol_in_progress
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
909 } /* if not already in place */
911 } /* normal or mergable */
913 if (SF_GET_TAG(def_symbol_in_progress
)
914 && symbol_find_base(S_GET_NAME(def_symbol_in_progress
), DO_NOT_STRIP
) == NULL
) {
915 tag_insert(S_GET_NAME(def_symbol_in_progress
), def_symbol_in_progress
);
916 } /* If symbol is a {structure,union} tag, associate symbol to its name. */
918 if (SF_GET_FUNCTION(def_symbol_in_progress
)) {
919 know(sizeof(def_symbol_in_progress
) <= sizeof(long));
921 = c_line_new(def_symbol_in_progress
,0, 0, &zero_address_frag
);
925 SF_SET_PROCESS(def_symbol_in_progress
);
927 if (symbolP
== NULL
) {
928 /* That is, if this is the first
929 time we've seen the function... */
930 symbol_table_insert(def_symbol_in_progress
);
931 } /* definition follows debug */
932 } /* Create the line number entry pointing to the function being defined */
934 def_symbol_in_progress
= NULL
;
935 demand_empty_rest_of_line();
937 } /* obj_coff_endef() */
940 DEFUN_VOID(obj_coff_dim
)
942 register int dim_index
;
944 if (def_symbol_in_progress
== NULL
)
946 as_warn(".dim pseudo-op used outside of .def/.endef: ignored.");
947 demand_empty_rest_of_line();
949 } /* if not inside .def/.endef */
951 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
953 for (dim_index
= 0; dim_index
< DIMNUM
; dim_index
++)
956 SA_SET_SYM_DIMEN(def_symbol_in_progress
, dim_index
, get_absolute_expression());
958 switch (*input_line_pointer
)
962 input_line_pointer
++;
966 as_warn("badly formed .dim directive ignored");
967 /* intentional fallthrough */
972 } /* switch on following character */
973 } /* for each dimension */
975 demand_empty_rest_of_line();
977 } /* obj_coff_dim() */
979 static void obj_coff_line()
983 if (def_symbol_in_progress
== NULL
) {
986 } /* if it looks like a stabs style line */
988 this_base
= get_absolute_expression();
989 if (this_base
> line_base
)
991 line_base
= this_base
;
999 listing_source_line(line_base
);
1003 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1004 SA_SET_SYM_LNNO(def_symbol_in_progress
, line_base
);
1006 demand_empty_rest_of_line();
1008 } /* obj_coff_line() */
1010 static void obj_coff_size() {
1011 if (def_symbol_in_progress
== NULL
) {
1012 as_warn(".size pseudo-op used outside of .def/.endef ignored.");
1013 demand_empty_rest_of_line();
1015 } /* if not inside .def/.endef */
1017 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1018 SA_SET_SYM_SIZE(def_symbol_in_progress
, get_absolute_expression());
1019 demand_empty_rest_of_line();
1021 } /* obj_coff_size() */
1023 static void obj_coff_scl() {
1024 if (def_symbol_in_progress
== NULL
) {
1025 as_warn(".scl pseudo-op used outside of .def/.endef ignored.");
1026 demand_empty_rest_of_line();
1028 } /* if not inside .def/.endef */
1030 S_SET_STORAGE_CLASS(def_symbol_in_progress
, get_absolute_expression());
1031 demand_empty_rest_of_line();
1033 } /* obj_coff_scl() */
1035 static void obj_coff_tag() {
1039 if (def_symbol_in_progress
== NULL
) {
1040 as_warn(".tag pseudo-op used outside of .def/.endef ignored.");
1041 demand_empty_rest_of_line();
1043 } /* if not inside .def/.endef */
1045 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1046 symbol_name
= input_line_pointer
;
1047 name_end
= get_symbol_end();
1049 /* Assume that the symbol referred to by .tag is always defined. */
1050 /* This was a bad assumption. I've added find_or_make. xoxorich. */
1051 SA_SET_SYM_TAGNDX(def_symbol_in_progress
, (long) tag_find_or_make(symbol_name
));
1052 if (SA_GET_SYM_TAGNDX(def_symbol_in_progress
) == 0L) {
1053 as_warn("tag not found for .tag %s", symbol_name
);
1056 SF_SET_TAGGED(def_symbol_in_progress
);
1057 *input_line_pointer
= name_end
;
1059 demand_empty_rest_of_line();
1061 } /* obj_coff_tag() */
1063 static void obj_coff_type() {
1064 if (def_symbol_in_progress
== NULL
) {
1065 as_warn(".type pseudo-op used outside of .def/.endef ignored.");
1066 demand_empty_rest_of_line();
1068 } /* if not inside .def/.endef */
1070 S_SET_DATA_TYPE(def_symbol_in_progress
, get_absolute_expression());
1072 if (ISFCN(S_GET_DATA_TYPE(def_symbol_in_progress
)) &&
1073 S_GET_STORAGE_CLASS(def_symbol_in_progress
) != C_TPDEF
) {
1074 SF_SET_FUNCTION(def_symbol_in_progress
);
1075 } /* is a function */
1077 demand_empty_rest_of_line();
1079 } /* obj_coff_type() */
1081 static void obj_coff_val() {
1082 if (def_symbol_in_progress
== NULL
) {
1083 as_warn(".val pseudo-op used outside of .def/.endef ignored.");
1084 demand_empty_rest_of_line();
1086 } /* if not inside .def/.endef */
1088 if (is_name_beginner(*input_line_pointer
)) {
1089 char *symbol_name
= input_line_pointer
;
1090 char name_end
= get_symbol_end();
1092 if (!strcmp(symbol_name
, ".")) {
1093 def_symbol_in_progress
->sy_frag
= frag_now
;
1094 S_SET_VALUE(def_symbol_in_progress
, obstack_next_free(&frags
) - frag_now
->fr_literal
);
1095 /* If the .val is != from the .def (e.g. statics) */
1096 } else if (strcmp(S_GET_NAME(def_symbol_in_progress
), symbol_name
)) {
1097 def_symbol_in_progress
->sy_forward
= symbol_find_or_make(symbol_name
);
1099 /* If the segment is undefined when the forward
1100 reference is solved, then copy the segment id
1101 from the forward symbol. */
1102 SF_SET_GET_SEGMENT(def_symbol_in_progress
);
1104 /* Otherwise, it is the name of a non debug symbol and its value will be calculated later. */
1105 *input_line_pointer
= name_end
;
1107 S_SET_VALUE(def_symbol_in_progress
, get_absolute_expression());
1108 } /* if symbol based */
1110 demand_empty_rest_of_line();
1112 } /* obj_coff_val() */
1115 * Maintain a list of the tagnames of the structres.
1118 static void tag_init() {
1119 tag_hash
= hash_new();
1123 static void tag_insert(name
, symbolP
)
1127 register char * error_string
;
1129 if (*(error_string
= hash_jam(tag_hash
, name
, (char *)symbolP
))) {
1130 as_fatal("Inserting \"%s\" into structure table failed: %s",
1131 name
, error_string
);
1134 } /* tag_insert() */
1136 static symbolS
*tag_find_or_make(name
)
1141 if ((symbolP
= tag_find(name
)) == NULL
) {
1142 symbolP
= symbol_new(name
,
1145 &zero_address_frag
);
1147 tag_insert(S_GET_NAME(symbolP
), symbolP
);
1148 symbol_table_insert(symbolP
);
1152 } /* tag_find_or_make() */
1154 static symbolS
*tag_find(name
)
1157 #ifdef STRIP_UNDERSCORE
1158 if (*name
== '_') name
++;
1159 #endif /* STRIP_UNDERSCORE */
1160 return((symbolS
*)hash_find(tag_hash
, name
));
1163 void obj_read_begin_hook() {
1164 /* These had better be the same. Usually 18 bytes. */
1166 know(sizeof(SYMENT
) == sizeof(AUXENT
));
1167 know(SYMESZ
== AUXESZ
);
1172 } /* obj_read_begin_hook() */
1174 /* This function runs through the symbol table and puts all the
1175 externals onto another chain */
1177 /* The chain of externals */
1178 symbolS
*symbol_externP
= NULL
;
1179 symbolS
*symbol_extern_lastP
= NULL
;
1182 symbolS
*last_functionP
= NULL
;
1186 static unsigned int DEFUN_VOID(yank_symbols
)
1189 unsigned int symbol_number
=0;
1191 for (symbolP
= symbol_rootP
;
1193 symbolP
= symbolP
? symbol_next(symbolP
) : symbol_rootP
) {
1194 if (!SF_GET_DEBUG(symbolP
)) {
1195 /* Debug symbols do not need all this rubbish */
1196 symbolS
* real_symbolP
;
1198 /* L* and C_EFCN symbols never merge. */
1199 if (!SF_GET_LOCAL(symbolP
)
1200 && (real_symbolP
= symbol_find_base(S_GET_NAME(symbolP
), DO_NOT_STRIP
))
1201 && real_symbolP
!= symbolP
) {
1202 /* FIXME-SOON: where do dups come from?
1203 Maybe tag references before definitions? xoxorich. */
1204 /* Move the debug data from the debug symbol to the
1205 real symbol. Do NOT do the oposite (i.e. move from
1206 real symbol to debug symbol and remove real symbol from the
1207 list.) Because some pointers refer to the real symbol
1208 whereas no pointers refer to the debug symbol. */
1209 c_symbol_merge(symbolP
, real_symbolP
);
1210 /* Replace the current symbol by the real one */
1211 /* The symbols will never be the last or the first
1212 because : 1st symbol is .file and 3 last symbols are
1213 .text, .data, .bss */
1214 symbol_remove(real_symbolP
, &symbol_rootP
, &symbol_lastP
);
1215 symbol_insert(real_symbolP
, symbolP
, &symbol_rootP
, &symbol_lastP
);
1216 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1217 symbolP
= real_symbolP
;
1218 } /* if not local but dup'd */
1220 if (flagseen
['R'] && (S_GET_SEGMENT(symbolP
) == SEG_E1
)) {
1221 S_SET_SEGMENT(symbolP
, SEG_E0
);
1222 } /* push data into text */
1224 S_SET_VALUE(symbolP
,
1225 S_GET_VALUE(symbolP
) + symbolP
->sy_frag
->fr_address
);
1227 if (!S_IS_DEFINED(symbolP
) && !SF_GET_LOCAL(symbolP
))
1229 S_SET_EXTERNAL(symbolP
);
1231 else if (S_GET_STORAGE_CLASS(symbolP
) == C_NULL
)
1233 if (S_GET_SEGMENT(symbolP
) == SEG_E0
)
1235 S_SET_STORAGE_CLASS(symbolP
, C_LABEL
);
1239 S_SET_STORAGE_CLASS(symbolP
, C_STAT
);
1243 /* Mainly to speed up if not -g */
1244 if (SF_GET_PROCESS(symbolP
))
1246 /* Handle the nested blocks auxiliary info. */
1247 if (S_GET_STORAGE_CLASS(symbolP
) == C_BLOCK
) {
1248 if (!strcmp(S_GET_NAME(symbolP
), ".bb"))
1249 stack_push(block_stack
, (char *) &symbolP
);
1251 register symbolS
* begin_symbolP
;
1252 begin_symbolP
= *(symbolS
**)stack_pop(block_stack
);
1253 if (begin_symbolP
== (symbolS
*)0)
1254 as_warn("mismatched .eb");
1256 SA_SET_SYM_ENDNDX(begin_symbolP
, symbol_number
+2);
1259 /* If we are able to identify the type of a function, and we
1260 are out of a function (last_functionP == 0) then, the
1261 function symbol will be associated with an auxiliary
1263 if (last_functionP
== (symbolS
*)0 &&
1264 SF_GET_FUNCTION(symbolP
)) {
1265 last_functionP
= symbolP
;
1267 if (S_GET_NUMBER_AUXILIARY(symbolP
) < 1) {
1268 S_SET_NUMBER_AUXILIARY(symbolP
, 1);
1269 } /* make it at least 1 */
1271 /* Clobber possible stale .dim information. */
1272 bzero(symbolP
->sy_symbol
.ost_auxent
[0].x_sym
.x_fcnary
.x_ary
.x_dimen
,
1273 sizeof(symbolP
->sy_symbol
.ost_auxent
[0].x_sym
.x_fcnary
.x_ary
.x_dimen
));
1275 /* The C_FCN doesn't need any additional information.
1276 I don't even know if this is needed for sdb. But the
1277 standard assembler generates it, so...
1279 if (S_GET_STORAGE_CLASS(symbolP
) == C_EFCN
) {
1280 if (last_functionP
== (symbolS
*)0)
1281 as_fatal("C_EFCN symbol out of scope");
1282 SA_SET_SYM_FSIZE(last_functionP
,
1283 (long)(S_GET_VALUE(symbolP
) -
1284 S_GET_VALUE(last_functionP
)));
1285 SA_SET_SYM_ENDNDX(last_functionP
, symbol_number
);
1286 last_functionP
= (symbolS
*)0;
1289 } else if (SF_GET_TAG(symbolP
)) {
1290 /* First descriptor of a structure must point to
1291 the first slot after the structure description. */
1292 last_tagP
= symbolP
;
1294 } else if (S_GET_STORAGE_CLASS(symbolP
) == C_EOS
) {
1295 /* +2 take in account the current symbol */
1296 SA_SET_SYM_ENDNDX(last_tagP
, symbol_number
+ 2);
1297 } else if (S_GET_STORAGE_CLASS(symbolP
) == C_FILE
) {
1298 if (S_GET_VALUE(symbolP
)) {
1299 S_SET_VALUE((symbolS
*) S_GET_VALUE(symbolP
), symbol_number
);
1300 S_SET_VALUE(symbolP
, 0);
1301 } /* no one points at the first .file symbol */
1302 } /* if debug or tag or eos or file */
1304 /* We must put the external symbols apart. The loader
1305 does not bomb if we do not. But the references in
1306 the endndx field for a .bb symbol are not corrected
1307 if an external symbol is removed between .bb and .be.
1308 I.e in the following case :
1309 [20] .bb endndx = 22
1312 ld will move the symbol 21 to the end of the list but
1313 endndx will still be 22 instead of 21. */
1316 if (SF_GET_LOCAL(symbolP
)) {
1317 /* remove C_EFCN and LOCAL (L...) symbols */
1318 /* next pointer remains valid */
1319 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1322 else if (!S_IS_DEFINED(symbolP
)
1323 && !S_IS_DEBUG(symbolP
)
1324 && !SF_GET_STATICS(symbolP
) &&
1325 S_GET_STORAGE_CLASS(symbolP
) == C_EXT
)
1326 { /* C_EXT && !SF_GET_FUNCTION(symbolP)) */
1327 /* if external, Remove from the list */
1328 symbolS
*hold
= symbol_previous(symbolP
);
1330 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1331 symbol_clear_list_pointers(symbolP
);
1332 symbol_append(symbolP
, symbol_extern_lastP
, &symbol_externP
, &symbol_extern_lastP
);
1335 if (SF_GET_STRING(symbolP
)) {
1336 symbolP
->sy_name_offset
= string_byte_count
;
1337 string_byte_count
+= strlen(S_GET_NAME(symbolP
)) + 1;
1339 symbolP
->sy_name_offset
= 0;
1340 } /* fix "long" names */
1342 symbolP
->sy_number
= symbol_number
;
1343 symbol_number
+= 1 + S_GET_NUMBER_AUXILIARY(symbolP
);
1344 } /* if local symbol */
1345 } /* traverse the symbol list */
1346 return symbol_number
;
1351 static unsigned int DEFUN_VOID(glue_symbols
)
1353 unsigned int symbol_number
= 0;
1355 for (symbolP
= symbol_externP
; symbol_externP
;) {
1356 symbolS
*tmp
= symbol_externP
;
1359 symbol_remove(tmp
, &symbol_externP
, &symbol_extern_lastP
);
1360 symbol_append(tmp
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
1363 if (SF_GET_STRING(tmp
)) {
1364 tmp
->sy_name_offset
= string_byte_count
;
1365 string_byte_count
+= strlen(S_GET_NAME(tmp
)) + 1;
1367 tmp
->sy_name_offset
= 0;
1368 } /* fix "long" names */
1370 tmp
->sy_number
= symbol_number
;
1371 symbol_number
+= 1 + S_GET_NUMBER_AUXILIARY(tmp
);
1372 } /* append the entire extern chain */
1373 return symbol_number
;
1377 static unsigned int DEFUN_VOID(tie_tags
)
1379 unsigned int symbol_number
= 0;
1382 for (symbolP
= symbol_rootP
; symbolP
; symbolP
=
1383 symbol_next(symbolP
))
1385 symbolP
->sy_number
= symbol_number
;
1389 if (SF_GET_TAGGED(symbolP
))
1393 ((symbolS
*) SA_GET_SYM_TAGNDX(symbolP
))->sy_number
);
1396 symbol_number
+= 1 + S_GET_NUMBER_AUXILIARY(symbolP
);
1398 return symbol_number
;
1403 DEFUN(crawl_symbols
,(headers
, abfd
),
1404 struct internal_filehdr
*headers AND
1409 unsigned int ptr
= 0;
1414 /* Initialize the stack used to keep track of the matching .bb .be */
1416 block_stack
= stack_init(512, sizeof(symbolS
*));
1417 /* JF deal with forward references first... */
1418 for (symbolP
= symbol_rootP
;
1420 symbolP
= symbol_next(symbolP
))
1423 if (symbolP
->sy_forward
) {
1424 S_SET_VALUE(symbolP
, (S_GET_VALUE(symbolP
)
1425 + S_GET_VALUE(symbolP
->sy_forward
)
1426 + symbolP
->sy_forward
->sy_frag
->fr_address
));
1428 if (SF_GET_GET_SEGMENT(symbolP
)) {
1429 S_SET_SEGMENT(symbolP
, S_GET_SEGMENT(symbolP
->sy_forward
));
1430 } /* forward segment also */
1432 symbolP
->sy_forward
=0;
1433 } /* if it has a forward reference */
1434 } /* walk the symbol chain */
1437 /* The symbol list should be ordered according to the following sequence
1440 * . debug entries for functions
1441 * . fake symbols for the sections, including.text .data and .bss
1443 * . undefined symbols
1444 * But this is not mandatory. The only important point is to put the
1445 * undefined symbols at the end of the list.
1448 if (symbol_rootP
== NULL
1449 || S_GET_STORAGE_CLASS(symbol_rootP
) != C_FILE
) {
1450 c_dot_file_symbol("fake");
1452 /* Is there a .file symbol ? If not insert one at the beginning. */
1455 * Build up static symbols for the sections, they are filled in later
1459 for (i
= SEG_E0
; i
< SEG_E9
; i
++)
1461 if (segment_info
[i
].scnhdr
.s_name
[0])
1463 segment_info
[i
].dot
=
1464 c_section_symbol(segment_info
[i
].scnhdr
.s_name
,
1471 /* Take all the externals out and put them into another chain */
1472 headers
->f_nsyms
= yank_symbols();
1473 /* Take the externals and glue them onto the end.*/
1474 headers
->f_nsyms
+= glue_symbols();
1476 headers
->f_nsyms
= tie_tags();
1477 know(symbol_externP
== NULL
);
1478 know(symbol_extern_lastP
== NULL
);
1484 * Find strings by crawling along symbol table chain.
1487 void DEFUN(w_strings
,(where
),
1492 /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
1493 md_number_to_chars(where
, string_byte_count
, sizeof(string_byte_count
));
1494 where
+= sizeof(string_byte_count
);
1495 for (symbolP
= symbol_rootP
;
1497 symbolP
= symbol_next(symbolP
))
1501 if (SF_GET_STRING(symbolP
)) {
1502 size
= strlen(S_GET_NAME(symbolP
)) + 1;
1504 memcpy(where
, S_GET_NAME(symbolP
),size
);
1517 DEFUN(do_linenos_for
,(abfd
, file_cursor
),
1519 unsigned long *file_cursor
)
1523 for (idx
= SEG_E0
; idx
< SEG_E9
; idx
++)
1525 segment_info_type
*s
= segment_info
+ idx
;
1527 if (s
->scnhdr
.s_nlnno
!= 0)
1529 struct lineno_list
*line_ptr
;
1531 struct external_lineno
*buffer
=
1532 (struct external_lineno
*)xmalloc(s
->scnhdr
.s_nlnno
* LINESZ
);
1534 struct external_lineno
*dst
= buffer
;
1536 /* Run through the table we've built and turn it into its external
1539 for (line_ptr
= s
->lineno_list_head
;
1540 line_ptr
!= (struct lineno_list
*)NULL
;
1541 line_ptr
= line_ptr
->next
)
1543 if (line_ptr
->line
.l_lnno
== 0)
1545 /* Turn a pointer to a symbol into the symbols' index */
1546 line_ptr
->line
.l_addr
.l_symndx
=
1547 ( (symbolS
*)line_ptr
->line
.l_addr
.l_symndx
)->sy_number
;
1549 (void) bfd_coff_swap_lineno_out(abfd
, &(line_ptr
->line
), dst
);
1553 s
->scnhdr
.s_lnnoptr
= *file_cursor
;
1555 bfd_write(buffer
, 1, s
->scnhdr
.s_nlnno
* LINESZ
, abfd
);
1558 *file_cursor
+= s
->scnhdr
.s_nlnno
* LINESZ
;
1564 /* Now we run through the list of frag chains in a segment and
1565 make all the subsegment frags appear at the end of the
1566 list, as if the seg 0 was extra long */
1568 static void DEFUN_VOID(remove_subsegs
)
1572 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1574 frchainS
*head
= segment_info
[i
].frchainP
;
1576 fragS
* prev_frag
= &dummy
;
1578 while (head
&& head
->frch_seg
== i
)
1580 prev_frag
->fr_next
= head
->frch_root
;
1581 prev_frag
= head
->frch_last
;
1582 head
= head
->frch_next
;
1584 prev_frag
->fr_next
= 0;
1589 extern void DEFUN_VOID(write_object_file
)
1592 struct frchain
*frchain_ptr
;
1594 struct internal_filehdr filehdr
;
1595 struct internal_aouthdr aouthdr
;
1596 unsigned long file_cursor
;
1598 unsigned int addr
= 0;
1599 abfd
= bfd_openw(out_file_name
, TARGET_FORMAT
);
1603 as_perror ("FATAL: Can't create %s", out_file_name
);
1606 bfd_set_format(abfd
, bfd_object
);
1607 bfd_set_arch_mach(abfd
, BFD_ARCH
, 0);
1611 string_byte_count
= 4;
1613 for (frchain_ptr
= frchain_root
;
1614 frchain_ptr
!= (struct frchain
*)NULL
;
1615 frchain_ptr
= frchain_ptr
->frch_next
) {
1616 /* Run through all the sub-segments and align them up. Also close any
1617 open frags. We tack a .fill onto the end of the frag chain so
1618 that any .align's size can be worked by looking at the next
1621 subseg_new(frchain_ptr
->frch_seg
, frchain_ptr
->frch_subseg
);
1622 #define SUB_SEGMENT_ALIGN 1
1623 frag_align(SUB_SEGMENT_ALIGN
,0);
1624 frag_wane(frag_now
);
1625 frag_now
->fr_fix
= 0;
1626 know( frag_now
->fr_next
== NULL
);
1633 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1635 relax_segment(segment_info
[i
].frchainP
->frch_root
, i
);
1642 filehdr
.f_nscns
= 0;
1644 /* Find out how big the sections are */
1645 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1648 if (segment_info
[i
].scnhdr
.s_name
[0])
1652 segment_info
[i
].scnhdr
.s_paddr
= addr
;
1654 /* THis is a special case, we leave the size alone, which will have */
1655 /* been made up from all and any lcomms seen */
1658 addr
+= size_section(abfd
, i
);
1664 /* Turn the gas native symbol table shape into a coff symbol table */
1665 crawl_symbols(&filehdr
, abfd
);
1667 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1669 fixup_segment(segment_info
[i
].fix_root
, i
);
1673 file_cursor
= FILHSZ
+ SCNHSZ
* filehdr
.f_nscns
;
1675 bfd_seek(abfd
, file_cursor
, 0);
1678 do_relocs_for(abfd
, &file_cursor
);
1680 do_linenos_for(abfd
, &file_cursor
);
1683 /* Plant the data */
1685 fill_section(abfd
,&filehdr
, &file_cursor
);
1687 filehdr
.f_magic
= COFF_MAGIC
;
1688 filehdr
.f_timdat
= 0;
1689 filehdr
.f_flags
= 0;
1695 unsigned int symtable_size
= filehdr
.f_nsyms
* SYMESZ
;
1696 char *buffer1
= malloc(symtable_size
+ string_byte_count
+ 4);
1697 char *ptr
= buffer1
;
1698 filehdr
.f_symptr
= bfd_tell(abfd
);
1699 w_symbols(abfd
, buffer1
, symbol_rootP
);
1700 w_strings(buffer1
+ symtable_size
);
1701 bfd_write(buffer1
, 1,symtable_size
+ string_byte_count
+ 4, abfd
);
1705 coff_header_append(abfd
, &filehdr
, &aouthdr
);
1707 bfd_close_all_done(abfd
);
1711 static void DEFUN(change_to_section
,(name
, len
, exp
),
1713 unsigned int len AND
1717 /* Find out if we've already got a section of this name etc */
1718 for(i
= SEG_E0
; i
< SEG_E9
&& segment_info
[i
].scnhdr
.s_name
[0] ; i
++)
1720 if (strncmp(segment_info
[i
].scnhdr
.s_name
, name
, len
) == 0)
1727 /* No section, add one */
1728 strncpy(segment_info
[i
].scnhdr
.s_name
, name
, 8);
1733 DEFUN_VOID(obj_coff_section
)
1735 /* Strip out the section name */
1736 char *section_name
;
1737 char *section_name_end
;
1743 section_name
= input_line_pointer
;
1744 c
= get_symbol_end();
1745 section_name_end
= input_line_pointer
;
1747 len
= section_name_end
- section_name
;
1748 input_line_pointer
++;
1752 exp
= get_absolute_expression();
1754 else if ( *input_line_pointer
== ',')
1757 input_line_pointer
++;
1758 exp
= get_absolute_expression();
1765 change_to_section(section_name
, len
,exp
);
1766 *section_name_end
= c
;
1771 static void obj_coff_text()
1773 change_to_section(".text",5, get_absolute_expression());
1777 static void obj_coff_data()
1779 change_to_section(".data",5, get_absolute_expression());
1782 void c_symbol_merge(debug
, normal
)
1786 S_SET_DATA_TYPE(normal
, S_GET_DATA_TYPE(debug
));
1787 S_SET_STORAGE_CLASS(normal
, S_GET_STORAGE_CLASS(debug
));
1789 if (S_GET_NUMBER_AUXILIARY(debug
) > S_GET_NUMBER_AUXILIARY(normal
)) {
1790 S_SET_NUMBER_AUXILIARY(normal
, S_GET_NUMBER_AUXILIARY(debug
));
1791 } /* take the most we have */
1793 if (S_GET_NUMBER_AUXILIARY(debug
) > 0) {
1794 memcpy((char*)&normal
->sy_symbol
.ost_auxent
[0], (char*)&debug
->sy_symbol
.ost_auxent
[0], S_GET_NUMBER_AUXILIARY(debug
) * AUXESZ
);
1795 } /* Move all the auxiliary information */
1797 /* Move the debug flags. */
1798 SF_SET_DEBUG_FIELD(normal
, SF_GET_DEBUG_FIELD(debug
));
1799 } /* c_symbol_merge() */
1802 DEFUN(c_line_new
,(symbol
, paddr
, line_number
, frag
),
1805 unsigned short line_number AND
1808 struct lineno_list
* new_line
=
1809 (struct lineno_list
*)xmalloc(sizeof(struct lineno_list
));
1811 segment_info_type
*s
= segment_info
+ now_seg
;
1812 new_line
->line
.l_lnno
= line_number
;
1813 if (line_number
== 0)
1815 new_line
->line
.l_addr
.l_symndx
= (long)symbol
;
1819 new_line
->line
.l_addr
.l_paddr
= paddr
;
1822 new_line
->frag
= (char*)frag
;
1823 new_line
->next
= (struct lineno_list
*)NULL
;
1826 if (s
->lineno_list_head
== (struct lineno_list
*)NULL
)
1828 s
->lineno_list_head
= new_line
;
1832 s
->lineno_list_tail
->next
= new_line
;
1834 s
->lineno_list_tail
= new_line
;
1835 return LINESZ
* s
->scnhdr
.s_nlnno
++;
1838 void c_dot_file_symbol(filename
)
1843 symbolP
= symbol_new(".file",
1846 &zero_address_frag
);
1848 S_SET_STORAGE_CLASS(symbolP
, C_FILE
);
1849 S_SET_NUMBER_AUXILIARY(symbolP
, 1);
1850 SA_SET_FILE_FNAME(symbolP
, filename
);
1856 listing_source_file(filename
);
1862 SF_SET_DEBUG(symbolP
);
1863 S_SET_VALUE(symbolP
, (long) previous_file_symbol
);
1865 previous_file_symbol
= symbolP
;
1867 /* Make sure that the symbol is first on the symbol chain */
1868 if (symbol_rootP
!= symbolP
) {
1869 if (symbolP
== symbol_lastP
) {
1870 symbol_lastP
= symbol_lastP
->sy_previous
;
1871 } /* if it was the last thing on the list */
1873 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1874 symbol_insert(symbolP
, symbol_rootP
, &symbol_rootP
, &symbol_lastP
);
1875 symbol_rootP
= symbolP
;
1876 } /* if not first on the list */
1878 } /* c_dot_file_symbol() */
1881 * Build a 'section static' symbol.
1884 symbolS
*c_section_symbol(name
,idx
)
1890 symbolP
= symbol_new(name
,idx
,
1892 &zero_address_frag
);
1894 S_SET_STORAGE_CLASS(symbolP
, C_STAT
);
1895 S_SET_NUMBER_AUXILIARY(symbolP
, 1);
1897 SF_SET_STATICS(symbolP
);
1900 } /* c_section_symbol() */
1903 DEFUN(w_symbols
,(abfd
, where
, symbol_rootP
),
1906 symbolS
*symbol_rootP
)
1911 /* First fill in those values we have only just worked out */
1912 for (i
= SEG_E0
; i
< SEG_E9
; i
++)
1914 symbolP
= segment_info
[i
].dot
;
1918 SA_SET_SCN_SCNLEN(symbolP
, segment_info
[i
].scnhdr
.s_size
);
1919 SA_SET_SCN_NRELOC(symbolP
, segment_info
[i
].scnhdr
.s_nreloc
);
1920 SA_SET_SCN_NLINNO(symbolP
, segment_info
[i
].scnhdr
.s_nlnno
);
1926 * Emit all symbols left in the symbol chain.
1928 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next(symbolP
)) {
1929 /* Used to save the offset of the name. It is used to point
1930 to the string in memory but must be a file offset. */
1931 register char * temp
;
1933 tc_coff_symbol_emit_hook(symbolP
);
1935 temp
= S_GET_NAME(symbolP
);
1936 if (SF_GET_STRING(symbolP
)) {
1937 S_SET_OFFSET(symbolP
, symbolP
->sy_name_offset
);
1938 S_SET_ZEROES(symbolP
, 0);
1940 bzero(symbolP
->sy_symbol
.ost_entry
.n_name
, SYMNMLEN
);
1941 strncpy(symbolP
->sy_symbol
.ost_entry
.n_name
, temp
, SYMNMLEN
);
1943 where
= symbol_to_chars(abfd
, where
, symbolP
);
1944 S_SET_NAME(symbolP
,temp
);
1949 static void DEFUN_VOID(obj_coff_lcomm
)
1956 name
= input_line_pointer
;
1960 c
= get_symbol_end();
1961 p
= input_line_pointer
;
1964 if (*input_line_pointer
!= ',') {
1965 as_bad("Expected comma after name");
1966 ignore_rest_of_line();
1969 if (*input_line_pointer
== '\n') {
1970 as_bad("Missing size expression");
1973 input_line_pointer
++;
1974 if ((temp
= get_absolute_expression ()) < 0) {
1975 as_warn("lcomm length (%d.) <0! Ignored.", temp
);
1976 ignore_rest_of_line();
1980 symbolP
= symbol_find_or_make(name
);
1981 S_SET_VALUE(symbolP
, segment_info
[SEG_E2
].scnhdr
.s_size
);
1982 S_SET_SEGMENT(symbolP
, SEG_E2
);
1983 segment_info
[SEG_E2
].scnhdr
.s_size
+= temp
;
1984 S_SET_STORAGE_CLASS(symbolP
, C_STAT
);
1985 demand_empty_rest_of_line();
1990 static void DEFUN(fixup_segment
,(fixP
, this_segment_type
),
1991 register fixS
* fixP AND
1992 segT this_segment_type
)
1994 register symbolS
*add_symbolP
;
1995 register symbolS
*sub_symbolP
;
1996 register long add_number
;
1998 register char *place
;
1999 register long where
;
2000 register char pcrel
;
2001 register fragS
*fragP
;
2002 register segT add_symbol_segment
= SEG_ABSOLUTE
;
2005 for ( ; fixP
; fixP
= fixP
->fx_next
)
2007 fragP
= fixP
->fx_frag
;
2009 where
= fixP
->fx_where
;
2010 place
= fragP
->fr_literal
+ where
;
2011 size
= fixP
->fx_size
;
2012 add_symbolP
= fixP
->fx_addsy
;
2014 if (fixP
->fx_callj
&& TC_S_IS_CALLNAME(add_symbolP
)) {
2015 /* Relocation should be done via the
2016 associated 'bal' entry point
2019 if (!TC_S_IS_BALNAME(tc_get_bal_of_call(add_symbolP
))) {
2020 as_bad("No 'bal' entry point for leafproc %s",
2021 S_GET_NAME(add_symbolP
));
2024 fixP
->fx_addsy
= add_symbolP
= tc_get_bal_of_call(add_symbolP
);
2025 } /* callj relocation */
2027 sub_symbolP
= fixP
->fx_subsy
;
2028 add_number
= fixP
->fx_offset
;
2029 pcrel
= fixP
->fx_pcrel
;
2032 add_symbol_segment
= S_GET_SEGMENT(add_symbolP
);
2033 } /* if there is an addend */
2038 if (S_GET_SEGMENT(sub_symbolP
) != SEG_ABSOLUTE
) {
2039 as_bad("Negative of non-absolute symbol %s", S_GET_NAME(sub_symbolP
));
2040 } /* not absolute */
2042 add_number
-= S_GET_VALUE(sub_symbolP
);
2044 /* if sub_symbol is in the same segment that add_symbol
2045 and add_symbol is either in DATA, TEXT, BSS or ABSOLUTE */
2046 } else if ((S_GET_SEGMENT(sub_symbolP
) == add_symbol_segment
)
2047 && (SEG_NORMAL(add_symbol_segment
)
2048 || (add_symbol_segment
== SEG_ABSOLUTE
))) {
2049 /* Difference of 2 symbols from same segment. */
2050 /* Can't make difference of 2 undefineds: 'value' means */
2051 /* something different for N_UNDF. */
2053 /* Makes no sense to use the difference of 2 arbitrary symbols
2054 * as the target of a call instruction.
2056 if (fixP
->fx_callj
) {
2057 as_bad("callj to difference of 2 symbols");
2059 #endif /* TC_I960 */
2060 add_number
+= S_GET_VALUE(add_symbolP
) -
2061 S_GET_VALUE(sub_symbolP
);
2064 fixP
->fx_addsy
= NULL
;
2066 /* Different segments in subtraction. */
2067 know(!(S_IS_EXTERNAL(sub_symbolP
) && (S_GET_SEGMENT(sub_symbolP
) == SEG_ABSOLUTE
)));
2069 if ((S_GET_SEGMENT(sub_symbolP
) == SEG_ABSOLUTE
)) {
2070 add_number
-= S_GET_VALUE(sub_symbolP
);
2072 as_bad("Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %d.",
2073 segment_name(S_GET_SEGMENT(sub_symbolP
)),
2074 S_GET_NAME(sub_symbolP
), fragP
->fr_address
+ where
);
2077 } /* if sub_symbolP */
2080 if (add_symbol_segment
== this_segment_type
&& pcrel
) {
2082 * This fixup was made when the symbol's segment was
2083 * SEG_UNKNOWN, but it is now in the local segment.
2084 * So we know how to do the address without relocation.
2087 /* reloc_callj() may replace a 'call' with a 'calls' or a 'bal',
2088 * in which cases it modifies *fixP as appropriate. In the case
2089 * of a 'calls', no further work is required, and *fixP has been
2090 * set up to make the rest of the code below a no-op.
2093 #endif /* TC_I960 */
2095 add_number
+= S_GET_VALUE(add_symbolP
);
2096 add_number
-= md_pcrel_from (fixP
);
2097 pcrel
= 0; /* Lie. Don't want further pcrel processing. */
2098 fixP
->fx_addsy
= NULL
; /* No relocations please. */
2101 switch (add_symbol_segment
)
2105 reloc_callj(fixP
); /* See comment about reloc_callj() above*/
2106 #endif /* TC_I960 */
2107 add_number
+= S_GET_VALUE(add_symbolP
);
2108 fixP
->fx_addsy
= NULL
;
2113 add_number
+= S_GET_VALUE(add_symbolP
) +
2114 segment_info
[S_GET_SEGMENT(add_symbolP
)].scnhdr
.s_paddr
;
2119 if ((int)fixP
->fx_bit_fixP
== 13) {
2120 /* This is a COBR instruction. They have only a
2121 * 13-bit displacement and are only to be used
2122 * for local branches: flag as error, don't generate
2125 as_bad("can't use COBR format with external label");
2126 fixP
->fx_addsy
= NULL
; /* No relocations please. */
2129 #endif /* TC_I960 */
2136 } /* switch on symbol seg */
2137 } /* if not in local seg */
2138 } /* if there was a + symbol */
2141 add_number
-= md_pcrel_from(fixP
);
2142 if (add_symbolP
== 0) {
2143 fixP
->fx_addsy
= & abs_symbol
;
2144 } /* if there's an add_symbol */
2147 if (!fixP
->fx_bit_fixP
) {
2149 (add_number
& ~0xFF) && (add_number
&~0xFF!=(-1&~0xFF))) ||
2151 (add_number
& ~0xFFFF) && (add_number
&~0xFFFF!=(-1&~0xFFFF)))) {
2152 as_bad("Value of %d too large for field of %d bytes at 0x%x",
2153 add_number
, size
, fragP
->fr_address
+ where
);
2154 } /* generic error checking */
2155 } /* not a bit fix */
2156 /* once this fix has been applied, we don't have to output anything
2157 nothing more need be done -*/
2158 md_apply_fix(fixP
, add_number
);
2160 } /* For each fixS in this segment. */
2163 } /* fixup_segment() */