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 #define MIN(a,b) ((a) < (b)? (a) : (b))
47 /* This vector is used to turn an internal segment into a section #
48 suitable for insertion into a coff symbol table
51 const short seg_N_TYPE
[] = { /* in: segT out: N_TYPE bits */
63 C_UNDEF_SECTION
, /* SEG_UNKNOWN */
64 C_UNDEF_SECTION
, /* SEG_ABSENT */
65 C_UNDEF_SECTION
, /* SEG_PASS1 */
66 C_UNDEF_SECTION
, /* SEG_GOOF */
67 C_UNDEF_SECTION
, /* SEG_BIG */
68 C_UNDEF_SECTION
, /* SEG_DIFFERENCE */
69 C_DEBUG_SECTION
, /* SEG_DEBUG */
70 C_NTV_SECTION
, /* SEG_NTV */
71 C_PTV_SECTION
, /* SEG_PTV */
72 C_REGISTER_SECTION
, /* SEG_REGISTER */
76 int function_lineoff
= -1; /* Offset in line#s where the last function
77 started (the odd entry for line #0) */
83 static symbolS
*last_line_symbol
;
84 /* Add 4 to the real value to get the index and compensate the
85 negatives. This vector is used by S_GET_SEGMENT to turn a coff
86 section number into a segment number
88 static symbolS
*previous_file_symbol
= NULL
;
89 void c_symbol_merge();
92 symbolS
*c_section_symbol();
94 void EXFUN(bfd_as_write_hook
,(struct internal_filehdr
*,
97 static void EXFUN(fixup_segment
,(fixS
* fixP
,
98 segT this_segment_type
));
101 static void EXFUN(fixup_mdeps
,(fragS
*));
104 static void EXFUN(fill_section
,(bfd
*abfd
,
105 struct internal_filehdr
*f
, unsigned
109 char *EXFUN(s_get_name
,(symbolS
*s
));
110 static symbolS
*EXFUN(tag_find_or_make
,(char *name
));
111 static symbolS
* EXFUN(tag_find
,(char *name
));
118 unsigned short line_number
,
122 static void EXFUN(w_symbols
,
125 symbolS
*symbol_rootP
));
129 static void EXFUN( obj_coff_def
,(int what
));
130 static void EXFUN( obj_coff_lcomm
,(void));
131 static void EXFUN( obj_coff_dim
,(void));
132 static void EXFUN( obj_coff_text
,(void));
133 static void EXFUN( obj_coff_data
,(void));
134 static void EXFUN( obj_coff_endef
,(void));
135 static void EXFUN( obj_coff_line
,(void));
136 static void EXFUN( obj_coff_ln
,(void));
137 static void EXFUN( obj_coff_scl
,(void));
138 static void EXFUN( obj_coff_size
,(void));
139 static void EXFUN( obj_coff_tag
,(void));
140 static void EXFUN( obj_coff_type
,(void));
141 static void EXFUN( obj_coff_val
,(void));
142 void EXFUN( obj_coff_section
,(void));
143 static void EXFUN( tag_init
,(void));
144 static void EXFUN( tag_insert
,(char *name
, symbolS
*symbolP
));
147 static struct hash_control
*tag_hash
;
148 static symbolS
*def_symbol_in_progress
= NULL
;
150 const pseudo_typeS obj_pseudo_table
[] = {
151 { "def", obj_coff_def
, 0 },
152 { "dim", obj_coff_dim
, 0 },
153 { "endef", obj_coff_endef
, 0 },
154 { "line", obj_coff_line
, 0 },
155 { "ln", obj_coff_ln
, 0 },
156 { "scl", obj_coff_scl
, 0 },
157 { "size", obj_coff_size
, 0 },
158 { "tag", obj_coff_tag
, 0 },
159 { "type", obj_coff_type
, 0 },
160 { "val", obj_coff_val
, 0 },
161 { "section", obj_coff_section
, 0 },
162 { "use", obj_coff_section
, 0 },
163 { "sect", obj_coff_section
, 0 },
164 { "text", obj_coff_text
, 0 },
165 { "data", obj_coff_data
, 0 },
166 /* we don't yet handle this. */
167 { "ident", s_ignore
, 0 },
168 { "ABORT", s_abort
, 0 },
169 { "lcomm", obj_coff_lcomm
, 0},
170 { NULL
} /* end sentinel */
171 }; /* obj_pseudo_table */
177 We allow more than just the standard 3 sections, infact, we allow
178 10 sections, (though the usual three have to be there).
180 This structure performs the mappings for us:
185 static struct internal_scnhdr bss_section_header;
186 struct internal_scnhdr data_section_header;
187 struct internal_scnhdr text_section_header;
189 const segT N_TYPE_seg [32] =
203 seg_info_type seg_info_off_by_4
[N_SEG
] =
229 {SEG_REGISTER
},0,0,0,0};
231 #define SEG_INFO_FROM_SECTION_NUMBER(x) (seg_info_off_by_4[(x)+4])
232 #define SEG_INFO_FROM_SEG_NUMBER(x) (seg_info_off_by_4[(x)])
236 DEFUN(relax_align
,(address
, alignment
),
237 register relax_addressT address AND
238 register long alignment
)
241 relax_addressT new_address
;
243 mask
= ~ ( (~0) << alignment
);
244 new_address
= (address
+ mask
) & (~ mask
);
245 return (new_address
- address
);
246 } /* relax_align() */
250 DEFUN(s_get_segment
,(x
) ,
253 return SEG_INFO_FROM_SECTION_NUMBER(x
->sy_symbol
.ost_entry
.n_scnum
).seg_t
;
258 /* calculate the size of the frag chain and fill in the section header
259 to contain all of it, also fill in the addr of the sections */
261 DEFUN(size_section
,(abfd
, idx
),
266 unsigned int size
= 0;
267 fragS
*frag
= segment_info
[idx
].frchainP
->frch_root
;
269 size
= frag
->fr_address
;
271 if (frag
->fr_address
!= size
) {
272 printf("Out of step\n");
273 size
= frag
->fr_address
;
276 switch (frag
->fr_type
) {
277 #ifdef TC_COFF_SIZEMACHDEP
278 case rs_machine_dependent
:
279 size
+= TC_COFF_SIZEMACHDEP(frag
);
284 size
+= frag
->fr_fix
;
285 size
+= frag
->fr_offset
* frag
->fr_var
;
288 size
+= frag
->fr_fix
;
289 size
+= relax_align(size
, frag
->fr_offset
);
292 frag
= frag
->fr_next
;
294 segment_info
[idx
].scnhdr
.s_size
= size
;
299 static unsigned int DEFUN(count_entries_in_chain
,(idx
),
302 unsigned int nrelocs
;
305 /* Count the relocations */
306 fixup_ptr
= segment_info
[idx
].fix_root
;
308 while (fixup_ptr
!= (fixS
*)NULL
)
310 if (TC_COUNT_RELOC(fixup_ptr
))
315 if (fixup_ptr
->fx_r_type
== RELOC_CONSTH
)
324 fixup_ptr
= fixup_ptr
->fx_next
;
329 /* output all the relocations for a section */
330 void DEFUN(do_relocs_for
,(abfd
, file_cursor
),
332 unsigned long *file_cursor
)
334 unsigned int nrelocs
;
336 unsigned int addr
= 0;
337 for (idx
= SEG_E0
; idx
< SEG_E9
; idx
++)
339 if (segment_info
[idx
].scnhdr
.s_name
[0])
342 struct external_reloc
*ext_ptr
;
343 struct external_reloc
*external_reloc_vec
;
344 unsigned int external_reloc_size
;
345 unsigned int count
= 0;
346 unsigned int base
= addr
;
347 fixS
* fix_ptr
= segment_info
[idx
].fix_root
;
348 nrelocs
= count_entries_in_chain(idx
);
353 external_reloc_size
= nrelocs
* RELSZ
;
355 (struct external_reloc
*)malloc(external_reloc_size
);
359 ext_ptr
= external_reloc_vec
;
361 /* Fill in the internal coff style reloc struct from the
366 struct internal_reloc intr
;
368 /* Only output some of the relocations */
369 if (TC_COUNT_RELOC(fix_ptr
))
371 #ifdef TC_RELOC_MANGLE
372 TC_RELOC_MANGLE(fix_ptr
, &intr
, base
);
376 symbol_ptr
= fix_ptr
->fx_addsy
;
378 intr
.r_type
= TC_COFF_FIX2RTYPE(fix_ptr
);
380 base
+ fix_ptr
->fx_frag
->fr_address
+ fix_ptr
->fx_where
;
382 intr
.r_offset
= fix_ptr
->fx_offset
;
386 /* Turn the segment of the symbol into an offset
390 dot
= segment_info
[S_GET_SEGMENT(symbol_ptr
)].dot
;
393 intr
.r_symndx
= dot
->sy_number
;
397 intr
.r_symndx
= symbol_ptr
->sy_number
;
409 (void)bfd_coff_swap_reloc_out(abfd
, &intr
, ext_ptr
);
413 /* The 29k has a special kludge for the high 16 bit reloc.
414 Two relocations are emmited, R_IHIHALF, and
415 R_IHCONST. The second one doesn't contain a symbol,
416 but uses the value for offset */
418 if (intr
.r_type
== R_IHIHALF
)
420 /* now emit the second bit */
421 intr
.r_type
= R_IHCONST
;
422 intr
.r_symndx
= fix_ptr
->fx_addnumber
;
423 (void)bfd_coff_swap_reloc_out(abfd
,&intr
,ext_ptr
);
429 fix_ptr
= fix_ptr
->fx_next
;
432 /* Write out the reloc table */
433 segment_info
[idx
].scnhdr
.s_relptr
= *file_cursor
;
434 segment_info
[idx
].scnhdr
.s_nreloc
= nrelocs
;
435 bfd_write((PTR
)external_reloc_vec
, 1, external_reloc_size
, abfd
);
436 *file_cursor
+= external_reloc_size
;
437 free( external_reloc_vec
);
439 addr
+= segment_info
[idx
].scnhdr
.s_size
;
444 /* run through a frag chain and write out the data to go with it, fill
445 in the scnhdrs with the info on the file postions
447 static void DEFUN(fill_section
,(abfd
, filehdr
, file_cursor
),
449 struct internal_filehdr
*filehdr AND
450 unsigned long *file_cursor
)
454 unsigned int paddr
= 0;
456 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
458 unsigned int offset
= 0;
460 struct internal_scnhdr
*s
= &( segment_info
[i
].scnhdr
);
464 fragS
*frag
= segment_info
[i
].frchainP
->frch_root
;
465 char *buffer
= malloc(s
->s_size
);
468 s
->s_scnptr
= *file_cursor
;
482 s
->s_flags
= STYP_REG
;
483 if (strcmp(s
->s_name
,".text")==0)
484 s
->s_flags
|= STYP_TEXT
;
485 else if (strcmp(s
->s_name
,".data")==0)
486 s
->s_flags
|= STYP_DATA
;
487 else if (strcmp(s
->s_name
,".bss")==0)
488 s
->s_flags
|= STYP_BSS
| STYP_NOLOAD
;
489 else if (strcmp(s
->s_name
,".lit")==0)
490 s
->s_flags
= STYP_LIT
| STYP_TEXT
;
494 unsigned int fill_size
;
495 switch (frag
->fr_type
) {
496 case rs_machine_dependent
:
499 memcpy(buffer
+ frag
->fr_address
,
502 offset
+= frag
->fr_fix
;
511 memcpy(buffer
+ frag
->fr_address
,
514 offset
+= frag
->fr_fix
;
517 fill_size
= frag
->fr_var
;
521 unsigned int off
= frag
->fr_fix
;
522 for (count
= frag
->fr_offset
; count
; count
--)
524 memcpy(buffer
+ frag
->fr_address
+ off
,
525 frag
->fr_literal
+ frag
->fr_fix
,
539 frag
= frag
->fr_next
;
543 bfd_write(buffer
, s
->s_size
,1,abfd
);
546 *file_cursor
+= s
->s_size
;
555 /* Coff file generation & utilities */
559 DEFUN(coff_header_append
,(abfd
, filehdr
, aouthdr
),
561 struct internal_filehdr
*filehdr AND
562 struct internal_aouthdr
*aouthdr
)
568 bfd_seek(abfd
, 0, 0);
570 filehdr
.f_opthdr
= bfd_coff_swap_aouthdr_out(abfd
, aouthdr
,
573 filehdr
->f_opthdr
= 0;
575 i
= bfd_coff_swap_filehdr_out(abfd
, filehdr
, buffer
);
577 bfd_write(buffer
, i
,1, abfd
);
578 bfd_write(buffero
, filehdr
->f_opthdr
, 1, abfd
);
580 for (i
= SEG_E0
; i
< SEG_E9
; i
++)
582 if (segment_info
[i
].scnhdr
.s_name
[0])
585 bfd_coff_swap_scnhdr_out(abfd
,
586 &(segment_info
[i
].scnhdr
),
588 bfd_write(buffer
, size
, 1, abfd
);
595 DEFUN(symbol_to_chars
,(abfd
, where
, symbolP
),
600 unsigned int numaux
= symbolP
->sy_symbol
.ost_entry
.n_numaux
;
603 /* Turn any symbols with register attributes into abs symbols */
604 if (S_GET_SEGMENT(symbolP
) == SEG_REGISTER
)
606 S_SET_SEGMENT(symbolP
, SEG_ABSOLUTE
);
608 /* At the same time, relocate all symbols to their output value */
611 segment_info
[S_GET_SEGMENT(symbolP
)].scnhdr
.s_paddr
612 + S_GET_VALUE(symbolP
));
614 where
+= bfd_coff_swap_sym_out(abfd
, &symbolP
->sy_symbol
.ost_entry
,
617 for (i
= 0; i
< numaux
; i
++)
619 where
+= bfd_coff_swap_aux_out(abfd
,
620 &symbolP
->sy_symbol
.ost_auxent
[i
],
621 S_GET_DATA_TYPE(symbolP
),
622 S_GET_STORAGE_CLASS(symbolP
),
632 void obj_symbol_new_hook(symbolP
)
635 char underscore
= 0; /* Symbol has leading _ */
637 /* Effective symbol */
638 /* Store the pointer in the offset. */
639 S_SET_ZEROES(symbolP
, 0L);
640 S_SET_DATA_TYPE(symbolP
, T_NULL
);
641 S_SET_STORAGE_CLASS(symbolP
, 0);
642 S_SET_NUMBER_AUXILIARY(symbolP
, 0);
643 /* Additional information */
644 symbolP
->sy_symbol
.ost_flags
= 0;
645 /* Auxiliary entries */
646 bzero((char*)&symbolP
->sy_symbol
.ost_auxent
[0], AUXESZ
);
648 #ifdef STRIP_UNDERSCORE
649 /* Remove leading underscore at the beginning of the symbol.
650 * This is to be compatible with the standard librairies.
652 if (*S_GET_NAME(symbolP
) == '_') {
654 S_SET_NAME(symbolP
, S_GET_NAME(symbolP
) + 1);
655 } /* strip underscore */
656 #endif /* STRIP_UNDERSCORE */
658 if (S_IS_STRING(symbolP
))
659 SF_SET_STRING(symbolP
);
660 if (!underscore
&& S_IS_LOCAL(symbolP
))
661 SF_SET_LOCAL(symbolP
);
664 } /* obj_symbol_new_hook() */
667 stack
* stack_init(chunk_size
, element_size
)
668 unsigned long chunk_size
;
669 unsigned long element_size
;
673 if ((st
= (stack
*)malloc(sizeof(stack
))) == (stack
*)0)
675 if ((st
->data
= malloc(chunk_size
)) == (char*)0) {
680 st
->size
= chunk_size
;
681 st
->chunk_size
= chunk_size
;
682 st
->element_size
= element_size
;
686 void stack_delete(st
)
693 char *stack_push(st
, element
)
697 if (st
->pointer
+ st
->element_size
>= st
->size
) {
698 st
->size
+= st
->chunk_size
;
699 if ((st
->data
= xrealloc(st
->data
, st
->size
)) == (char*)0)
702 memcpy(st
->data
+ st
->pointer
, element
, st
->element_size
);
703 st
->pointer
+= st
->element_size
;
704 return st
->data
+ st
->pointer
;
710 if ((st
->pointer
-= st
->element_size
) < 0) {
715 return st
->data
+ st
->pointer
;
721 return st
->data
+ st
->pointer
- st
->element_size
;
726 * Handle .ln directives.
729 static void obj_coff_ln()
733 if (def_symbol_in_progress
!= NULL
) {
734 as_warn(".ln pseudo-op inside .def/.endef: ignored.");
735 demand_empty_rest_of_line();
737 } /* wrong context */
740 obstack_next_free(&frags
) - frag_now
->fr_literal
,
741 l
= get_absolute_expression(),
749 listing_source_line(l
+ line_base
- 1);
754 demand_empty_rest_of_line();
756 } /* obj_coff_line() */
761 * Handle .def directives.
763 * One might ask : why can't we symbol_new if the symbol does not
764 * already exist and fill it with debug information. Because of
765 * the C_EFCN special symbol. It would clobber the value of the
766 * function symbol before we have a chance to notice that it is
767 * a C_EFCN. And a second reason is that the code is more clear this
768 * way. (at least I think it is :-).
772 #define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';')
773 #define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \
774 *input_line_pointer == '\t') \
775 input_line_pointer++;
778 DEFUN(obj_coff_def
,(what
),
781 char name_end
; /* Char after the end of name */
782 char *symbol_name
; /* Name of the debug symbol */
783 char *symbol_name_copy
; /* Temporary copy of the name */
784 unsigned int symbol_name_length
;
785 /*$char* directiveP;$ */ /* Name of the pseudo opcode */
786 /*$char directive[MAX_DIRECTIVE];$ */ /* Backup of the directive */
787 /*$char end = 0;$ */ /* If 1, stop parsing */
789 if (def_symbol_in_progress
!= NULL
) {
790 as_warn(".def pseudo-op used inside of .def/.endef: ignored.");
791 demand_empty_rest_of_line();
793 } /* if not inside .def/.endef */
797 def_symbol_in_progress
= (symbolS
*) obstack_alloc(¬es
, sizeof(*def_symbol_in_progress
));
798 bzero(def_symbol_in_progress
, sizeof(*def_symbol_in_progress
));
800 symbol_name
= input_line_pointer
;
801 name_end
= get_symbol_end();
802 symbol_name_length
= strlen(symbol_name
);
803 symbol_name_copy
= xmalloc(symbol_name_length
+ 1);
804 strcpy(symbol_name_copy
, symbol_name
);
806 /* Initialize the new symbol */
807 #ifdef STRIP_UNDERSCORE
808 S_SET_NAME(def_symbol_in_progress
, (*symbol_name_copy
== '_'
809 ? symbol_name_copy
+ 1
810 : symbol_name_copy
));
811 #else /* STRIP_UNDERSCORE */
812 S_SET_NAME(def_symbol_in_progress
, symbol_name_copy
);
813 #endif /* STRIP_UNDERSCORE */
814 /* free(symbol_name_copy); */
815 def_symbol_in_progress
->sy_name_offset
= ~0;
816 def_symbol_in_progress
->sy_number
= ~0;
817 def_symbol_in_progress
->sy_frag
= &zero_address_frag
;
819 if (S_IS_STRING(def_symbol_in_progress
)) {
820 SF_SET_STRING(def_symbol_in_progress
);
823 *input_line_pointer
= name_end
;
825 demand_empty_rest_of_line();
827 } /* obj_coff_def() */
829 unsigned int dim_index
;
831 DEFUN_VOID(obj_coff_endef
)
833 symbolS
*symbolP
= 0;
834 /* DIM BUG FIX sac@cygnus.com */
836 if (def_symbol_in_progress
== NULL
) {
837 as_warn(".endef pseudo-op used outside of .def/.endef: ignored.");
838 demand_empty_rest_of_line();
840 } /* if not inside .def/.endef */
842 /* Set the section number according to storage class. */
843 switch (S_GET_STORAGE_CLASS(def_symbol_in_progress
)) {
847 SF_SET_TAG(def_symbol_in_progress
);
848 /* intentional fallthrough */
851 SF_SET_DEBUG(def_symbol_in_progress
);
852 S_SET_SEGMENT(def_symbol_in_progress
, SEG_DEBUG
);
856 SF_SET_LOCAL(def_symbol_in_progress
); /* Do not emit this symbol. */
857 /* intentional fallthrough */
859 SF_SET_PROCESS(def_symbol_in_progress
); /* Will need processing before writing */
860 /* intentional fallthrough */
862 S_SET_SEGMENT(def_symbol_in_progress
, SEG_E0
);
864 if (def_symbol_in_progress
->sy_symbol
.ost_entry
._n
._n_nptr
[1][1] == 'b'
865 && def_symbol_in_progress
->sy_symbol
.ost_entry
._n
._n_nptr
[1][2] == 'f') { /* .bf */
866 if (function_lineoff
< 0) {
867 fprintf(stderr
, "`.bf' symbol without preceding function\n");
868 } /* missing function symbol */
869 SA_GET_SYM_LNNOPTR(last_line_symbol
) = function_lineoff
;
871 SF_SET_PROCESS(last_line_symbol
);
872 function_lineoff
= -1;
878 #endif /* C_AUTOARG */
888 SF_SET_DEBUG(def_symbol_in_progress
);
889 S_SET_SEGMENT(def_symbol_in_progress
, SEG_ABSOLUTE
);
895 /* Valid but set somewhere else (s_comm, s_lcomm, colon) */
901 as_warn("unexpected storage class %d", S_GET_STORAGE_CLASS(def_symbol_in_progress
));
903 } /* switch on storage class */
905 /* Now that we have built a debug symbol, try to
906 find if we should merge with an existing symbol
907 or not. If a symbol is C_EFCN or SEG_ABSOLUTE or
908 untagged SEG_DEBUG it never merges. */
910 /* Two cases for functions. Either debug followed
911 by definition or definition followed by debug.
912 For definition first, we will merge the debug
913 symbol into the definition. For debug first, the
914 lineno entry MUST point to the definition
915 function or else it will point off into space
916 when crawl_symbols() merges the debug
917 symbol into the real symbol. Therefor, let's
918 presume the debug symbol is a real function
921 /* FIXME-SOON If for some reason the definition
922 label/symbol is never seen, this will probably
923 leave an undefined symbol at link time. */
925 if (S_GET_STORAGE_CLASS(def_symbol_in_progress
) == C_EFCN
926 || (S_GET_SEGMENT(def_symbol_in_progress
) == SEG_DEBUG
927 && !SF_GET_TAG(def_symbol_in_progress
))
928 || S_GET_SEGMENT(def_symbol_in_progress
) == SEG_ABSOLUTE
929 || (symbolP
= symbol_find_base(S_GET_NAME(def_symbol_in_progress
), DO_NOT_STRIP
)) == NULL
) {
931 symbol_append(def_symbol_in_progress
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
934 /* This symbol already exists, merge the
935 newly created symbol into the old one.
936 This is not mandatory. The linker can
937 handle duplicate symbols correctly. But I
938 guess that it save a *lot* of space if
939 the assembly file defines a lot of
942 /* The debug entry (def_symbol_in_progress)
943 is merged into the previous definition. */
945 c_symbol_merge(def_symbol_in_progress
, symbolP
);
946 /* FIXME-SOON Should *def_symbol_in_progress be free'd? xoxorich. */
947 def_symbol_in_progress
= symbolP
;
949 if (SF_GET_FUNCTION(def_symbol_in_progress
)
950 || SF_GET_TAG(def_symbol_in_progress
)) {
951 /* For functions, and tags, the symbol *must* be where the debug symbol
952 appears. Move the existing symbol to the current place. */
953 /* If it already is at the end of the symbol list, do nothing */
954 if (def_symbol_in_progress
!= symbol_lastP
) {
955 symbol_remove(def_symbol_in_progress
, &symbol_rootP
, &symbol_lastP
);
956 symbol_append(def_symbol_in_progress
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
957 } /* if not already in place */
959 } /* normal or mergable */
961 if (SF_GET_TAG(def_symbol_in_progress
)
962 && symbol_find_base(S_GET_NAME(def_symbol_in_progress
), DO_NOT_STRIP
) == NULL
) {
963 tag_insert(S_GET_NAME(def_symbol_in_progress
), def_symbol_in_progress
);
964 } /* If symbol is a {structure,union} tag, associate symbol to its name. */
966 if (SF_GET_FUNCTION(def_symbol_in_progress
)) {
967 know(sizeof(def_symbol_in_progress
) <= sizeof(long));
969 = c_line_new(def_symbol_in_progress
,0, 0, &zero_address_frag
);
973 SF_SET_PROCESS(def_symbol_in_progress
);
975 if (symbolP
== NULL
) {
976 /* That is, if this is the first
977 time we've seen the function... */
978 symbol_table_insert(def_symbol_in_progress
);
979 } /* definition follows debug */
980 } /* Create the line number entry pointing to the function being defined */
982 def_symbol_in_progress
= NULL
;
983 demand_empty_rest_of_line();
985 } /* obj_coff_endef() */
988 DEFUN_VOID(obj_coff_dim
)
990 register int dim_index
;
992 if (def_symbol_in_progress
== NULL
)
994 as_warn(".dim pseudo-op used outside of .def/.endef: ignored.");
995 demand_empty_rest_of_line();
997 } /* if not inside .def/.endef */
999 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1001 for (dim_index
= 0; dim_index
< DIMNUM
; dim_index
++)
1004 SA_SET_SYM_DIMEN(def_symbol_in_progress
, dim_index
, get_absolute_expression());
1006 switch (*input_line_pointer
)
1010 input_line_pointer
++;
1014 as_warn("badly formed .dim directive ignored");
1015 /* intentional fallthrough */
1020 } /* switch on following character */
1021 } /* for each dimension */
1023 demand_empty_rest_of_line();
1025 } /* obj_coff_dim() */
1027 static void obj_coff_line()
1031 if (def_symbol_in_progress
== NULL
) {
1034 } /* if it looks like a stabs style line */
1036 this_base
= get_absolute_expression();
1037 if (this_base
> line_base
)
1039 line_base
= this_base
;
1047 listing_source_line(line_base
);
1051 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1052 SA_SET_SYM_LNNO(def_symbol_in_progress
, line_base
);
1054 demand_empty_rest_of_line();
1056 } /* obj_coff_line() */
1058 static void obj_coff_size() {
1059 if (def_symbol_in_progress
== NULL
) {
1060 as_warn(".size pseudo-op used outside of .def/.endef ignored.");
1061 demand_empty_rest_of_line();
1063 } /* if not inside .def/.endef */
1065 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1066 SA_SET_SYM_SIZE(def_symbol_in_progress
, get_absolute_expression());
1067 demand_empty_rest_of_line();
1069 } /* obj_coff_size() */
1071 static void obj_coff_scl() {
1072 if (def_symbol_in_progress
== NULL
) {
1073 as_warn(".scl pseudo-op used outside of .def/.endef ignored.");
1074 demand_empty_rest_of_line();
1076 } /* if not inside .def/.endef */
1078 S_SET_STORAGE_CLASS(def_symbol_in_progress
, get_absolute_expression());
1079 demand_empty_rest_of_line();
1081 } /* obj_coff_scl() */
1083 static void obj_coff_tag() {
1087 if (def_symbol_in_progress
== NULL
) {
1088 as_warn(".tag pseudo-op used outside of .def/.endef ignored.");
1089 demand_empty_rest_of_line();
1091 } /* if not inside .def/.endef */
1093 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1094 symbol_name
= input_line_pointer
;
1095 name_end
= get_symbol_end();
1097 /* Assume that the symbol referred to by .tag is always defined. */
1098 /* This was a bad assumption. I've added find_or_make. xoxorich. */
1099 SA_SET_SYM_TAGNDX(def_symbol_in_progress
, (long) tag_find_or_make(symbol_name
));
1100 if (SA_GET_SYM_TAGNDX(def_symbol_in_progress
) == 0L) {
1101 as_warn("tag not found for .tag %s", symbol_name
);
1104 SF_SET_TAGGED(def_symbol_in_progress
);
1105 *input_line_pointer
= name_end
;
1107 demand_empty_rest_of_line();
1109 } /* obj_coff_tag() */
1111 static void obj_coff_type() {
1112 if (def_symbol_in_progress
== NULL
) {
1113 as_warn(".type pseudo-op used outside of .def/.endef ignored.");
1114 demand_empty_rest_of_line();
1116 } /* if not inside .def/.endef */
1118 S_SET_DATA_TYPE(def_symbol_in_progress
, get_absolute_expression());
1120 if (ISFCN(S_GET_DATA_TYPE(def_symbol_in_progress
)) &&
1121 S_GET_STORAGE_CLASS(def_symbol_in_progress
) != C_TPDEF
) {
1122 SF_SET_FUNCTION(def_symbol_in_progress
);
1123 } /* is a function */
1125 demand_empty_rest_of_line();
1127 } /* obj_coff_type() */
1129 static void obj_coff_val() {
1130 if (def_symbol_in_progress
== NULL
) {
1131 as_warn(".val pseudo-op used outside of .def/.endef ignored.");
1132 demand_empty_rest_of_line();
1134 } /* if not inside .def/.endef */
1136 if (is_name_beginner(*input_line_pointer
)) {
1137 char *symbol_name
= input_line_pointer
;
1138 char name_end
= get_symbol_end();
1140 if (!strcmp(symbol_name
, ".")) {
1141 def_symbol_in_progress
->sy_frag
= frag_now
;
1142 S_SET_VALUE(def_symbol_in_progress
, obstack_next_free(&frags
) - frag_now
->fr_literal
);
1143 /* If the .val is != from the .def (e.g. statics) */
1144 } else if (strcmp(S_GET_NAME(def_symbol_in_progress
), symbol_name
)) {
1145 def_symbol_in_progress
->sy_forward
= symbol_find_or_make(symbol_name
);
1147 /* If the segment is undefined when the forward
1148 reference is solved, then copy the segment id
1149 from the forward symbol. */
1150 SF_SET_GET_SEGMENT(def_symbol_in_progress
);
1152 /* Otherwise, it is the name of a non debug symbol and its value will be calculated later. */
1153 *input_line_pointer
= name_end
;
1155 S_SET_VALUE(def_symbol_in_progress
, get_absolute_expression());
1156 } /* if symbol based */
1158 demand_empty_rest_of_line();
1160 } /* obj_coff_val() */
1163 * Maintain a list of the tagnames of the structres.
1166 static void tag_init() {
1167 tag_hash
= hash_new();
1171 static void tag_insert(name
, symbolP
)
1175 register char * error_string
;
1177 if (*(error_string
= hash_jam(tag_hash
, name
, (char *)symbolP
))) {
1178 as_fatal("Inserting \"%s\" into structure table failed: %s",
1179 name
, error_string
);
1182 } /* tag_insert() */
1184 static symbolS
*tag_find_or_make(name
)
1189 if ((symbolP
= tag_find(name
)) == NULL
) {
1190 symbolP
= symbol_new(name
,
1193 &zero_address_frag
);
1195 tag_insert(S_GET_NAME(symbolP
), symbolP
);
1196 symbol_table_insert(symbolP
);
1200 } /* tag_find_or_make() */
1202 static symbolS
*tag_find(name
)
1205 #ifdef STRIP_UNDERSCORE
1206 if (*name
== '_') name
++;
1207 #endif /* STRIP_UNDERSCORE */
1208 return((symbolS
*)hash_find(tag_hash
, name
));
1211 void obj_read_begin_hook() {
1212 /* These had better be the same. Usually 18 bytes. */
1214 know(sizeof(SYMENT
) == sizeof(AUXENT
));
1215 know(SYMESZ
== AUXESZ
);
1220 } /* obj_read_begin_hook() */
1222 /* This function runs through the symbol table and puts all the
1223 externals onto another chain */
1225 /* The chain of externals */
1226 symbolS
*symbol_externP
= NULL
;
1227 symbolS
*symbol_extern_lastP
= NULL
;
1230 symbolS
*last_functionP
= NULL
;
1234 static unsigned int DEFUN_VOID(yank_symbols
)
1237 unsigned int symbol_number
=0;
1239 for (symbolP
= symbol_rootP
;
1241 symbolP
= symbolP
? symbol_next(symbolP
) : symbol_rootP
) {
1242 if (!SF_GET_DEBUG(symbolP
)) {
1243 /* Debug symbols do not need all this rubbish */
1244 symbolS
* real_symbolP
;
1246 /* L* and C_EFCN symbols never merge. */
1247 if (!SF_GET_LOCAL(symbolP
)
1248 && (real_symbolP
= symbol_find_base(S_GET_NAME(symbolP
), DO_NOT_STRIP
))
1249 && real_symbolP
!= symbolP
) {
1250 /* FIXME-SOON: where do dups come from?
1251 Maybe tag references before definitions? xoxorich. */
1252 /* Move the debug data from the debug symbol to the
1253 real symbol. Do NOT do the oposite (i.e. move from
1254 real symbol to debug symbol and remove real symbol from the
1255 list.) Because some pointers refer to the real symbol
1256 whereas no pointers refer to the debug symbol. */
1257 c_symbol_merge(symbolP
, real_symbolP
);
1258 /* Replace the current symbol by the real one */
1259 /* The symbols will never be the last or the first
1260 because : 1st symbol is .file and 3 last symbols are
1261 .text, .data, .bss */
1262 symbol_remove(real_symbolP
, &symbol_rootP
, &symbol_lastP
);
1263 symbol_insert(real_symbolP
, symbolP
, &symbol_rootP
, &symbol_lastP
);
1264 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1265 symbolP
= real_symbolP
;
1266 } /* if not local but dup'd */
1268 if (flagseen
['R'] && (S_GET_SEGMENT(symbolP
) == SEG_E1
)) {
1269 S_SET_SEGMENT(symbolP
, SEG_E0
);
1270 } /* push data into text */
1272 S_SET_VALUE(symbolP
,
1273 S_GET_VALUE(symbolP
) + symbolP
->sy_frag
->fr_address
);
1275 if (!S_IS_DEFINED(symbolP
) && !SF_GET_LOCAL(symbolP
))
1277 S_SET_EXTERNAL(symbolP
);
1279 else if (S_GET_STORAGE_CLASS(symbolP
) == C_NULL
)
1281 if (S_GET_SEGMENT(symbolP
) == SEG_E0
)
1283 S_SET_STORAGE_CLASS(symbolP
, C_LABEL
);
1287 S_SET_STORAGE_CLASS(symbolP
, C_STAT
);
1291 /* Mainly to speed up if not -g */
1292 if (SF_GET_PROCESS(symbolP
))
1294 /* Handle the nested blocks auxiliary info. */
1295 if (S_GET_STORAGE_CLASS(symbolP
) == C_BLOCK
) {
1296 if (!strcmp(S_GET_NAME(symbolP
), ".bb"))
1297 stack_push(block_stack
, (char *) &symbolP
);
1299 register symbolS
* begin_symbolP
;
1300 begin_symbolP
= *(symbolS
**)stack_pop(block_stack
);
1301 if (begin_symbolP
== (symbolS
*)0)
1302 as_warn("mismatched .eb");
1304 SA_SET_SYM_ENDNDX(begin_symbolP
, symbol_number
+2);
1307 /* If we are able to identify the type of a function, and we
1308 are out of a function (last_functionP == 0) then, the
1309 function symbol will be associated with an auxiliary
1311 if (last_functionP
== (symbolS
*)0 &&
1312 SF_GET_FUNCTION(symbolP
)) {
1313 last_functionP
= symbolP
;
1315 if (S_GET_NUMBER_AUXILIARY(symbolP
) < 1) {
1316 S_SET_NUMBER_AUXILIARY(symbolP
, 1);
1317 } /* make it at least 1 */
1319 /* Clobber possible stale .dim information. */
1321 /* Iffed out by steve - this fries the lnnoptr info too */
1322 bzero(symbolP
->sy_symbol
.ost_auxent
[0].x_sym
.x_fcnary
.x_ary
.x_dimen
,
1323 sizeof(symbolP
->sy_symbol
.ost_auxent
[0].x_sym
.x_fcnary
.x_ary
.x_dimen
));
1326 /* The C_FCN doesn't need any additional information.
1327 I don't even know if this is needed for sdb. But the
1328 standard assembler generates it, so...
1330 if (S_GET_STORAGE_CLASS(symbolP
) == C_EFCN
) {
1331 if (last_functionP
== (symbolS
*)0)
1332 as_fatal("C_EFCN symbol out of scope");
1333 SA_SET_SYM_FSIZE(last_functionP
,
1334 (long)(S_GET_VALUE(symbolP
) -
1335 S_GET_VALUE(last_functionP
)));
1336 SA_SET_SYM_ENDNDX(last_functionP
, symbol_number
);
1337 last_functionP
= (symbolS
*)0;
1340 } else if (SF_GET_TAG(symbolP
)) {
1341 /* First descriptor of a structure must point to
1342 the first slot after the structure description. */
1343 last_tagP
= symbolP
;
1345 } else if (S_GET_STORAGE_CLASS(symbolP
) == C_EOS
) {
1346 /* +2 take in account the current symbol */
1347 SA_SET_SYM_ENDNDX(last_tagP
, symbol_number
+ 2);
1348 } else if (S_GET_STORAGE_CLASS(symbolP
) == C_FILE
) {
1349 if (S_GET_VALUE(symbolP
)) {
1350 S_SET_VALUE((symbolS
*) S_GET_VALUE(symbolP
), symbol_number
);
1351 S_SET_VALUE(symbolP
, 0);
1352 } /* no one points at the first .file symbol */
1353 } /* if debug or tag or eos or file */
1355 /* We must put the external symbols apart. The loader
1356 does not bomb if we do not. But the references in
1357 the endndx field for a .bb symbol are not corrected
1358 if an external symbol is removed between .bb and .be.
1359 I.e in the following case :
1360 [20] .bb endndx = 22
1363 ld will move the symbol 21 to the end of the list but
1364 endndx will still be 22 instead of 21. */
1367 if (SF_GET_LOCAL(symbolP
)) {
1368 /* remove C_EFCN and LOCAL (L...) symbols */
1369 /* next pointer remains valid */
1370 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1373 else if (!S_IS_DEFINED(symbolP
)
1374 && !S_IS_DEBUG(symbolP
)
1375 && !SF_GET_STATICS(symbolP
) &&
1376 S_GET_STORAGE_CLASS(symbolP
) == C_EXT
)
1377 { /* C_EXT && !SF_GET_FUNCTION(symbolP)) */
1378 /* if external, Remove from the list */
1379 symbolS
*hold
= symbol_previous(symbolP
);
1381 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1382 symbol_clear_list_pointers(symbolP
);
1383 symbol_append(symbolP
, symbol_extern_lastP
, &symbol_externP
, &symbol_extern_lastP
);
1386 if (SF_GET_STRING(symbolP
)) {
1387 symbolP
->sy_name_offset
= string_byte_count
;
1388 string_byte_count
+= strlen(S_GET_NAME(symbolP
)) + 1;
1390 symbolP
->sy_name_offset
= 0;
1391 } /* fix "long" names */
1393 symbolP
->sy_number
= symbol_number
;
1394 symbol_number
+= 1 + S_GET_NUMBER_AUXILIARY(symbolP
);
1395 } /* if local symbol */
1396 } /* traverse the symbol list */
1397 return symbol_number
;
1402 static unsigned int DEFUN_VOID(glue_symbols
)
1404 unsigned int symbol_number
= 0;
1406 for (symbolP
= symbol_externP
; symbol_externP
;) {
1407 symbolS
*tmp
= symbol_externP
;
1410 symbol_remove(tmp
, &symbol_externP
, &symbol_extern_lastP
);
1411 symbol_append(tmp
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
1414 if (SF_GET_STRING(tmp
)) {
1415 tmp
->sy_name_offset
= string_byte_count
;
1416 string_byte_count
+= strlen(S_GET_NAME(tmp
)) + 1;
1418 tmp
->sy_name_offset
= 0;
1419 } /* fix "long" names */
1421 tmp
->sy_number
= symbol_number
;
1422 symbol_number
+= 1 + S_GET_NUMBER_AUXILIARY(tmp
);
1423 } /* append the entire extern chain */
1424 return symbol_number
;
1428 static unsigned int DEFUN_VOID(tie_tags
)
1430 unsigned int symbol_number
= 0;
1433 for (symbolP
= symbol_rootP
; symbolP
; symbolP
=
1434 symbol_next(symbolP
))
1436 symbolP
->sy_number
= symbol_number
;
1440 if (SF_GET_TAGGED(symbolP
))
1444 ((symbolS
*) SA_GET_SYM_TAGNDX(symbolP
))->sy_number
);
1447 symbol_number
+= 1 + S_GET_NUMBER_AUXILIARY(symbolP
);
1449 return symbol_number
;
1454 DEFUN(crawl_symbols
,(headers
, abfd
),
1455 struct internal_filehdr
*headers AND
1460 unsigned int ptr
= 0;
1465 /* Initialize the stack used to keep track of the matching .bb .be */
1467 block_stack
= stack_init(512, sizeof(symbolS
*));
1468 /* JF deal with forward references first... */
1469 for (symbolP
= symbol_rootP
;
1471 symbolP
= symbol_next(symbolP
))
1474 if (symbolP
->sy_forward
) {
1475 S_SET_VALUE(symbolP
, (S_GET_VALUE(symbolP
)
1476 + S_GET_VALUE(symbolP
->sy_forward
)
1477 + symbolP
->sy_forward
->sy_frag
->fr_address
));
1479 if (SF_GET_GET_SEGMENT(symbolP
)) {
1480 S_SET_SEGMENT(symbolP
, S_GET_SEGMENT(symbolP
->sy_forward
));
1481 } /* forward segment also */
1483 symbolP
->sy_forward
=0;
1484 } /* if it has a forward reference */
1485 } /* walk the symbol chain */
1488 /* The symbol list should be ordered according to the following sequence
1491 * . debug entries for functions
1492 * . fake symbols for the sections, including.text .data and .bss
1494 * . undefined symbols
1495 * But this is not mandatory. The only important point is to put the
1496 * undefined symbols at the end of the list.
1499 if (symbol_rootP
== NULL
1500 || S_GET_STORAGE_CLASS(symbol_rootP
) != C_FILE
) {
1501 c_dot_file_symbol("fake");
1503 /* Is there a .file symbol ? If not insert one at the beginning. */
1506 * Build up static symbols for the sections, they are filled in later
1510 for (i
= SEG_E0
; i
< SEG_E9
; i
++)
1512 if (segment_info
[i
].scnhdr
.s_name
[0])
1514 segment_info
[i
].dot
=
1515 c_section_symbol(segment_info
[i
].scnhdr
.s_name
,
1522 /* Take all the externals out and put them into another chain */
1523 headers
->f_nsyms
= yank_symbols();
1524 /* Take the externals and glue them onto the end.*/
1525 headers
->f_nsyms
+= glue_symbols();
1527 headers
->f_nsyms
= tie_tags();
1528 know(symbol_externP
== NULL
);
1529 know(symbol_extern_lastP
== NULL
);
1535 * Find strings by crawling along symbol table chain.
1538 void DEFUN(w_strings
,(where
),
1543 /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
1544 md_number_to_chars(where
, string_byte_count
, sizeof(string_byte_count
));
1545 where
+= sizeof(string_byte_count
);
1546 for (symbolP
= symbol_rootP
;
1548 symbolP
= symbol_next(symbolP
))
1552 if (SF_GET_STRING(symbolP
)) {
1553 size
= strlen(S_GET_NAME(symbolP
)) + 1;
1555 memcpy(where
, S_GET_NAME(symbolP
),size
);
1568 DEFUN(do_linenos_for
,(abfd
, file_cursor
),
1570 unsigned long *file_cursor
)
1574 for (idx
= SEG_E0
; idx
< SEG_E9
; idx
++)
1576 segment_info_type
*s
= segment_info
+ idx
;
1579 if (s
->scnhdr
.s_nlnno
!= 0)
1581 struct lineno_list
*line_ptr
;
1583 struct external_lineno
*buffer
=
1584 (struct external_lineno
*)xmalloc(s
->scnhdr
.s_nlnno
* LINESZ
);
1586 struct external_lineno
*dst
= buffer
;
1588 /* Run through the table we've built and turn it into its external
1589 form, take this chance to remove duplicates */
1591 for (line_ptr
= s
->lineno_list_head
;
1592 line_ptr
!= (struct lineno_list
*)NULL
;
1593 line_ptr
= line_ptr
->next
)
1596 if (line_ptr
->line
.l_lnno
== 0)
1598 /* Turn a pointer to a symbol into the symbols' index */
1599 line_ptr
->line
.l_addr
.l_symndx
=
1600 ( (symbolS
*)line_ptr
->line
.l_addr
.l_symndx
)->sy_number
;
1604 line_ptr
->line
.l_addr
.l_paddr
+= ((struct frag
* )(line_ptr
->frag
))->fr_address
;
1608 (void) bfd_coff_swap_lineno_out(abfd
, &(line_ptr
->line
), dst
);
1613 s
->scnhdr
.s_lnnoptr
= *file_cursor
;
1615 bfd_write(buffer
, 1, s
->scnhdr
.s_nlnno
* LINESZ
, abfd
);
1618 *file_cursor
+= s
->scnhdr
.s_nlnno
* LINESZ
;
1624 /* Now we run through the list of frag chains in a segment and
1625 make all the subsegment frags appear at the end of the
1626 list, as if the seg 0 was extra long */
1628 static void DEFUN_VOID(remove_subsegs
)
1632 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1634 frchainS
*head
= segment_info
[i
].frchainP
;
1636 fragS
* prev_frag
= &dummy
;
1638 while (head
&& head
->frch_seg
== i
)
1640 prev_frag
->fr_next
= head
->frch_root
;
1641 prev_frag
= head
->frch_last
;
1642 head
= head
->frch_next
;
1644 prev_frag
->fr_next
= 0;
1650 extern void DEFUN_VOID(write_object_file
)
1653 struct frchain
*frchain_ptr
;
1655 struct internal_filehdr filehdr
;
1656 struct internal_aouthdr aouthdr
;
1657 unsigned long file_cursor
;
1659 unsigned int addr
= 0;
1660 abfd
= bfd_openw(out_file_name
, TARGET_FORMAT
);
1664 as_perror ("FATAL: Can't create %s", out_file_name
);
1667 bfd_set_format(abfd
, bfd_object
);
1668 bfd_set_arch_mach(abfd
, BFD_ARCH
, machine
);
1672 string_byte_count
= 4;
1674 for (frchain_ptr
= frchain_root
;
1675 frchain_ptr
!= (struct frchain
*)NULL
;
1676 frchain_ptr
= frchain_ptr
->frch_next
) {
1677 /* Run through all the sub-segments and align them up. Also close any
1678 open frags. We tack a .fill onto the end of the frag chain so
1679 that any .align's size can be worked by looking at the next
1682 subseg_new(frchain_ptr
->frch_seg
, frchain_ptr
->frch_subseg
);
1683 #define SUB_SEGMENT_ALIGN 1
1684 frag_align(SUB_SEGMENT_ALIGN
,0);
1685 frag_wane(frag_now
);
1686 frag_now
->fr_fix
= 0;
1687 know( frag_now
->fr_next
== NULL
);
1694 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1696 relax_segment(segment_info
[i
].frchainP
->frch_root
, i
);
1703 filehdr
.f_nscns
= 0;
1705 /* Find out how big the sections are */
1706 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1709 if (segment_info
[i
].scnhdr
.s_name
[0])
1716 /* THis is a special case, we leave the size alone, which will have */
1717 /* been made up from all and any lcomms seen */
1721 addr
+= size_section(abfd
, i
);
1727 /* Turn the gas native symbol table shape into a coff symbol table */
1728 crawl_symbols(&filehdr
, abfd
);
1730 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1732 fixup_mdeps(segment_info
[i
].frchainP
->frch_root
);
1733 fixup_segment(segment_info
[i
].fix_root
, i
);
1737 file_cursor
= FILHSZ
+ SCNHSZ
* filehdr
.f_nscns
;
1739 bfd_seek(abfd
, file_cursor
, 0);
1742 do_relocs_for(abfd
, &file_cursor
);
1744 do_linenos_for(abfd
, &file_cursor
);
1747 /* Plant the data */
1749 fill_section(abfd
,&filehdr
, &file_cursor
);
1753 filehdr
.f_magic
= COFF_MAGIC
;
1754 filehdr
.f_timdat
= time(0);
1755 filehdr
.f_flags
= COFF_FLAGS
| coff_flags
;
1759 filehdr
.f_flags
|= F_LNNO
;
1763 filehdr
.f_flags
|= F_RELFLG
;
1774 unsigned int symtable_size
= filehdr
.f_nsyms
* SYMESZ
;
1775 char *buffer1
= malloc(symtable_size
+ string_byte_count
+ 4);
1776 char *ptr
= buffer1
;
1777 filehdr
.f_symptr
= bfd_tell(abfd
);
1778 w_symbols(abfd
, buffer1
, symbol_rootP
);
1779 w_strings(buffer1
+ symtable_size
);
1780 bfd_write(buffer1
, 1,symtable_size
+ string_byte_count
+ 4, abfd
);
1784 coff_header_append(abfd
, &filehdr
, &aouthdr
);
1786 bfd_close_all_done(abfd
);
1790 static void DEFUN(change_to_section
,(name
, len
, exp
),
1792 unsigned int len AND
1796 /* Find out if we've already got a section of this name etc */
1797 for(i
= SEG_E0
; i
< SEG_E9
&& segment_info
[i
].scnhdr
.s_name
[0] ; i
++)
1799 if (strncmp(segment_info
[i
].scnhdr
.s_name
, name
, len
) == 0)
1806 /* No section, add one */
1807 strncpy(segment_info
[i
].scnhdr
.s_name
, name
, 8);
1812 DEFUN_VOID(obj_coff_section
)
1814 /* Strip out the section name */
1815 char *section_name
;
1816 char *section_name_end
;
1822 section_name
= input_line_pointer
;
1823 c
= get_symbol_end();
1824 section_name_end
= input_line_pointer
;
1826 len
= section_name_end
- section_name
;
1827 input_line_pointer
++;
1831 exp
= get_absolute_expression();
1833 else if ( *input_line_pointer
== ',')
1836 input_line_pointer
++;
1837 exp
= get_absolute_expression();
1844 change_to_section(section_name
, len
,exp
);
1845 *section_name_end
= c
;
1850 static void obj_coff_text()
1852 change_to_section(".text",5, get_absolute_expression());
1856 static void obj_coff_data()
1858 change_to_section(".data",5, get_absolute_expression());
1861 void c_symbol_merge(debug
, normal
)
1865 S_SET_DATA_TYPE(normal
, S_GET_DATA_TYPE(debug
));
1866 S_SET_STORAGE_CLASS(normal
, S_GET_STORAGE_CLASS(debug
));
1868 if (S_GET_NUMBER_AUXILIARY(debug
) > S_GET_NUMBER_AUXILIARY(normal
)) {
1869 S_SET_NUMBER_AUXILIARY(normal
, S_GET_NUMBER_AUXILIARY(debug
));
1870 } /* take the most we have */
1872 if (S_GET_NUMBER_AUXILIARY(debug
) > 0) {
1873 memcpy((char*)&normal
->sy_symbol
.ost_auxent
[0], (char*)&debug
->sy_symbol
.ost_auxent
[0], S_GET_NUMBER_AUXILIARY(debug
) * AUXESZ
);
1874 } /* Move all the auxiliary information */
1876 /* Move the debug flags. */
1877 SF_SET_DEBUG_FIELD(normal
, SF_GET_DEBUG_FIELD(debug
));
1878 } /* c_symbol_merge() */
1881 DEFUN(c_line_new
,(symbol
, paddr
, line_number
, frag
),
1884 unsigned short line_number AND
1887 struct lineno_list
* new_line
=
1888 (struct lineno_list
*)xmalloc(sizeof(struct lineno_list
));
1890 segment_info_type
*s
= segment_info
+ now_seg
;
1891 new_line
->line
.l_lnno
= line_number
;
1895 if (line_number
== 0)
1897 last_line_symbol
= symbol
;
1898 new_line
->line
.l_addr
.l_symndx
= (long)symbol
;
1902 new_line
->line
.l_addr
.l_paddr
= paddr
;
1905 new_line
->frag
= (char*)frag
;
1906 new_line
->next
= (struct lineno_list
*)NULL
;
1909 if (s
->lineno_list_head
== (struct lineno_list
*)NULL
)
1911 s
->lineno_list_head
= new_line
;
1915 s
->lineno_list_tail
->next
= new_line
;
1917 s
->lineno_list_tail
= new_line
;
1918 return LINESZ
* s
->scnhdr
.s_nlnno
++;
1921 void c_dot_file_symbol(filename
)
1926 symbolP
= symbol_new(".file",
1929 &zero_address_frag
);
1931 S_SET_STORAGE_CLASS(symbolP
, C_FILE
);
1932 S_SET_NUMBER_AUXILIARY(symbolP
, 1);
1933 SA_SET_FILE_FNAME(symbolP
, filename
);
1939 listing_source_file(filename
);
1945 SF_SET_DEBUG(symbolP
);
1946 S_SET_VALUE(symbolP
, (long) previous_file_symbol
);
1948 previous_file_symbol
= symbolP
;
1950 /* Make sure that the symbol is first on the symbol chain */
1951 if (symbol_rootP
!= symbolP
) {
1952 if (symbolP
== symbol_lastP
) {
1953 symbol_lastP
= symbol_lastP
->sy_previous
;
1954 } /* if it was the last thing on the list */
1956 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1957 symbol_insert(symbolP
, symbol_rootP
, &symbol_rootP
, &symbol_lastP
);
1958 symbol_rootP
= symbolP
;
1959 } /* if not first on the list */
1961 } /* c_dot_file_symbol() */
1964 * Build a 'section static' symbol.
1967 symbolS
*c_section_symbol(name
,idx
)
1973 symbolP
= symbol_new(name
,idx
,
1975 &zero_address_frag
);
1977 S_SET_STORAGE_CLASS(symbolP
, C_STAT
);
1978 S_SET_NUMBER_AUXILIARY(symbolP
, 1);
1980 SF_SET_STATICS(symbolP
);
1983 } /* c_section_symbol() */
1986 DEFUN(w_symbols
,(abfd
, where
, symbol_rootP
),
1989 symbolS
*symbol_rootP
)
1994 /* First fill in those values we have only just worked out */
1995 for (i
= SEG_E0
; i
< SEG_E9
; i
++)
1997 symbolP
= segment_info
[i
].dot
;
2001 SA_SET_SCN_SCNLEN(symbolP
, segment_info
[i
].scnhdr
.s_size
);
2002 SA_SET_SCN_NRELOC(symbolP
, segment_info
[i
].scnhdr
.s_nreloc
);
2003 SA_SET_SCN_NLINNO(symbolP
, segment_info
[i
].scnhdr
.s_nlnno
);
2009 * Emit all symbols left in the symbol chain.
2011 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next(symbolP
)) {
2012 /* Used to save the offset of the name. It is used to point
2013 to the string in memory but must be a file offset. */
2014 register char * temp
;
2016 tc_coff_symbol_emit_hook(symbolP
);
2018 temp
= S_GET_NAME(symbolP
);
2019 if (SF_GET_STRING(symbolP
)) {
2020 S_SET_OFFSET(symbolP
, symbolP
->sy_name_offset
);
2021 S_SET_ZEROES(symbolP
, 0);
2023 bzero(symbolP
->sy_symbol
.ost_entry
.n_name
, SYMNMLEN
);
2024 strncpy(symbolP
->sy_symbol
.ost_entry
.n_name
, temp
, SYMNMLEN
);
2026 where
= symbol_to_chars(abfd
, where
, symbolP
);
2027 S_SET_NAME(symbolP
,temp
);
2032 static void DEFUN_VOID(obj_coff_lcomm
)
2041 name
= input_line_pointer
;
2045 c
= get_symbol_end();
2046 p
= input_line_pointer
;
2049 if (*input_line_pointer
!= ',') {
2050 as_bad("Expected comma after name");
2051 ignore_rest_of_line();
2054 if (*input_line_pointer
== '\n') {
2055 as_bad("Missing size expression");
2058 input_line_pointer
++;
2059 if ((temp
= get_absolute_expression ()) < 0) {
2060 as_warn("lcomm length (%d.) <0! Ignored.", temp
);
2061 ignore_rest_of_line();
2065 symbolP
= symbol_find_or_make(name
);
2066 vma
= segment_info
[SEG_E2
].scnhdr
.s_size
;
2067 vma
+= relax_align(vma
, MIN(8, temp
));
2068 S_SET_VALUE(symbolP
,vma
);
2069 S_SET_SEGMENT(symbolP
, SEG_E2
);
2070 segment_info
[SEG_E2
].scnhdr
.s_size
= vma
+ temp
;
2071 S_SET_STORAGE_CLASS(symbolP
, C_STAT
);
2072 demand_empty_rest_of_line();
2075 static void DEFUN(fixup_mdeps
,(frags
),
2080 switch (frags
->fr_type
)
2084 frags
->fr_type
= rs_fill
;
2086 (frags
->fr_next
->fr_address
- frags
->fr_address
- frags
->fr_fix
);
2088 case rs_machine_dependent
:
2089 md_convert_frag(0, frags
);
2094 frags
= frags
->fr_next
;
2099 static void DEFUN(fixup_segment
,(fixP
, this_segment_type
),
2100 register fixS
* fixP AND
2101 segT this_segment_type
)
2103 register symbolS
*add_symbolP
;
2104 register symbolS
*sub_symbolP
;
2105 register long add_number
;
2107 register char *place
;
2108 register long where
;
2109 register char pcrel
;
2110 register fragS
*fragP
;
2111 register segT add_symbol_segment
= SEG_ABSOLUTE
;
2114 for ( ; fixP
; fixP
= fixP
->fx_next
)
2116 fragP
= fixP
->fx_frag
;
2118 where
= fixP
->fx_where
;
2119 place
= fragP
->fr_literal
+ where
;
2120 size
= fixP
->fx_size
;
2121 add_symbolP
= fixP
->fx_addsy
;
2123 if (fixP
->fx_callj
&& TC_S_IS_CALLNAME(add_symbolP
)) {
2124 /* Relocation should be done via the
2125 associated 'bal' entry point
2128 if (!TC_S_IS_BALNAME(tc_get_bal_of_call(add_symbolP
))) {
2129 as_bad("No 'bal' entry point for leafproc %s",
2130 S_GET_NAME(add_symbolP
));
2133 fixP
->fx_addsy
= add_symbolP
= tc_get_bal_of_call(add_symbolP
);
2134 } /* callj relocation */
2136 sub_symbolP
= fixP
->fx_subsy
;
2137 add_number
= fixP
->fx_offset
;
2138 pcrel
= fixP
->fx_pcrel
;
2141 add_symbol_segment
= S_GET_SEGMENT(add_symbolP
);
2142 } /* if there is an addend */
2147 if (S_GET_SEGMENT(sub_symbolP
) != SEG_ABSOLUTE
) {
2148 as_bad("Negative of non-absolute symbol %s", S_GET_NAME(sub_symbolP
));
2149 } /* not absolute */
2151 add_number
-= S_GET_VALUE(sub_symbolP
);
2154 /* if sub_symbol is in the same segment that add_symbol
2155 and add_symbol is either in DATA, TEXT, BSS or ABSOLUTE */
2156 } else if ((S_GET_SEGMENT(sub_symbolP
) == add_symbol_segment
)
2157 && (SEG_NORMAL(add_symbol_segment
)
2158 || (add_symbol_segment
== SEG_ABSOLUTE
))) {
2159 /* Difference of 2 symbols from same segment. */
2160 /* Can't make difference of 2 undefineds: 'value' means */
2161 /* something different for N_UNDF. */
2163 /* Makes no sense to use the difference of 2 arbitrary symbols
2164 * as the target of a call instruction.
2166 if (fixP
->fx_callj
) {
2167 as_bad("callj to difference of 2 symbols");
2169 #endif /* TC_I960 */
2170 add_number
+= S_GET_VALUE(add_symbolP
) -
2171 S_GET_VALUE(sub_symbolP
);
2174 fixP
->fx_addsy
= NULL
;
2176 /* Different segments in subtraction. */
2177 know(!(S_IS_EXTERNAL(sub_symbolP
) && (S_GET_SEGMENT(sub_symbolP
) == SEG_ABSOLUTE
)));
2179 if ((S_GET_SEGMENT(sub_symbolP
) == SEG_ABSOLUTE
)) {
2180 add_number
-= S_GET_VALUE(sub_symbolP
);
2182 as_bad("Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %d.",
2183 segment_name(S_GET_SEGMENT(sub_symbolP
)),
2184 S_GET_NAME(sub_symbolP
), fragP
->fr_address
+ where
);
2187 } /* if sub_symbolP */
2190 if (add_symbol_segment
== this_segment_type
&& pcrel
) {
2192 * This fixup was made when the symbol's segment was
2193 * SEG_UNKNOWN, but it is now in the local segment.
2194 * So we know how to do the address without relocation.
2197 /* reloc_callj() may replace a 'call' with a 'calls' or a 'bal',
2198 * in which cases it modifies *fixP as appropriate. In the case
2199 * of a 'calls', no further work is required, and *fixP has been
2200 * set up to make the rest of the code below a no-op.
2203 #endif /* TC_I960 */
2205 add_number
+= S_GET_VALUE(add_symbolP
);
2206 add_number
-= md_pcrel_from (fixP
);
2207 pcrel
= 0; /* Lie. Don't want further pcrel processing. */
2208 fixP
->fx_addsy
= NULL
; /* No relocations please. */
2211 switch (add_symbol_segment
)
2215 reloc_callj(fixP
); /* See comment about reloc_callj() above*/
2216 #endif /* TC_I960 */
2217 add_number
+= S_GET_VALUE(add_symbolP
);
2218 fixP
->fx_addsy
= NULL
;
2223 add_number
+= S_GET_VALUE(add_symbolP
) +
2224 segment_info
[S_GET_SEGMENT(add_symbolP
)].scnhdr
.s_paddr
;
2229 if ((int)fixP
->fx_bit_fixP
== 13) {
2230 /* This is a COBR instruction. They have only a
2231 * 13-bit displacement and are only to be used
2232 * for local branches: flag as error, don't generate
2235 as_bad("can't use COBR format with external label");
2236 fixP
->fx_addsy
= NULL
; /* No relocations please. */
2239 #endif /* TC_I960 */
2246 } /* switch on symbol seg */
2247 } /* if not in local seg */
2248 } /* if there was a + symbol */
2251 add_number
-= md_pcrel_from(fixP
);
2252 if (add_symbolP
== 0) {
2253 fixP
->fx_addsy
= & abs_symbol
;
2254 } /* if there's an add_symbol */
2257 if (!fixP
->fx_bit_fixP
) {
2259 (add_number
& ~0xFF) && ((add_number
&~0xFF)!=(-1&~0xFF))) ||
2261 (add_number
& ~0xFFFF) && ((add_number
&~0xFFFF)!=(-1&~0xFFFF)))) {
2262 as_bad("Value of %d too large for field of %d bytes at 0x%x",
2263 add_number
, size
, fragP
->fr_address
+ where
);
2264 } /* generic error checking */
2265 } /* not a bit fix */
2266 /* once this fix has been applied, we don't have to output anything
2267 nothing more need be done -*/
2268 md_apply_fix(fixP
, add_number
);
2270 } /* For each fixS in this segment. */
2273 } /* fixup_segment() */