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
);
440 This should work
, but causes problems with addends in relocs
.
441 Disable it
for the moment
442 addr
+= segment_info
[idx
].scnhdr
.s_size
;
450 /* run through a frag chain and write out the data to go with it, fill
451 in the scnhdrs with the info on the file postions
453 static void DEFUN(fill_section
,(abfd
, filehdr
, file_cursor
),
455 struct internal_filehdr
*filehdr AND
456 unsigned long *file_cursor
)
460 unsigned int paddr
= 0;
462 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
464 unsigned int offset
= 0;
466 struct internal_scnhdr
*s
= &( segment_info
[i
].scnhdr
);
470 fragS
*frag
= segment_info
[i
].frchainP
->frch_root
;
471 char *buffer
= malloc(s
->s_size
);
474 s
->s_scnptr
= *file_cursor
;
488 s
->s_flags
= STYP_REG
;
489 if (strcmp(s
->s_name
,".text")==0)
490 s
->s_flags
|= STYP_TEXT
;
491 else if (strcmp(s
->s_name
,".data")==0)
492 s
->s_flags
|= STYP_DATA
;
493 else if (strcmp(s
->s_name
,".bss")==0)
494 s
->s_flags
|= STYP_BSS
| STYP_NOLOAD
;
495 else if (strcmp(s
->s_name
,".lit")==0)
496 s
->s_flags
= STYP_LIT
| STYP_TEXT
;
500 unsigned int fill_size
;
501 switch (frag
->fr_type
) {
502 case rs_machine_dependent
:
505 memcpy(buffer
+ frag
->fr_address
,
508 offset
+= frag
->fr_fix
;
517 memcpy(buffer
+ frag
->fr_address
,
520 offset
+= frag
->fr_fix
;
523 fill_size
= frag
->fr_var
;
527 unsigned int off
= frag
->fr_fix
;
528 for (count
= frag
->fr_offset
; count
; count
--)
530 memcpy(buffer
+ frag
->fr_address
+ off
,
531 frag
->fr_literal
+ frag
->fr_fix
,
545 frag
= frag
->fr_next
;
549 bfd_write(buffer
, s
->s_size
,1,abfd
);
552 *file_cursor
+= s
->s_size
;
555 This should work
, but causes problems with addends in relocs
.
556 Disable it
for the moment
569 /* Coff file generation & utilities */
573 DEFUN(coff_header_append
,(abfd
, filehdr
, aouthdr
),
575 struct internal_filehdr
*filehdr AND
576 struct internal_aouthdr
*aouthdr
)
582 bfd_seek(abfd
, 0, 0);
584 filehdr
.f_opthdr
= bfd_coff_swap_aouthdr_out(abfd
, aouthdr
,
587 filehdr
->f_opthdr
= 0;
589 i
= bfd_coff_swap_filehdr_out(abfd
, filehdr
, buffer
);
591 bfd_write(buffer
, i
,1, abfd
);
592 bfd_write(buffero
, filehdr
->f_opthdr
, 1, abfd
);
594 for (i
= SEG_E0
; i
< SEG_E9
; i
++)
596 if (segment_info
[i
].scnhdr
.s_name
[0])
599 bfd_coff_swap_scnhdr_out(abfd
,
600 &(segment_info
[i
].scnhdr
),
602 bfd_write(buffer
, size
, 1, abfd
);
609 DEFUN(symbol_to_chars
,(abfd
, where
, symbolP
),
614 unsigned int numaux
= symbolP
->sy_symbol
.ost_entry
.n_numaux
;
617 /* Turn any symbols with register attributes into abs symbols */
618 if (S_GET_SEGMENT(symbolP
) == SEG_REGISTER
)
620 S_SET_SEGMENT(symbolP
, SEG_ABSOLUTE
);
622 /* At the same time, relocate all symbols to their output value */
625 segment_info
[S_GET_SEGMENT(symbolP
)].scnhdr
.s_paddr
626 + S_GET_VALUE(symbolP
));
628 where
+= bfd_coff_swap_sym_out(abfd
, &symbolP
->sy_symbol
.ost_entry
,
631 for (i
= 0; i
< numaux
; i
++)
633 where
+= bfd_coff_swap_aux_out(abfd
,
634 &symbolP
->sy_symbol
.ost_auxent
[i
],
635 S_GET_DATA_TYPE(symbolP
),
636 S_GET_STORAGE_CLASS(symbolP
),
646 void obj_symbol_new_hook(symbolP
)
649 char underscore
= 0; /* Symbol has leading _ */
651 /* Effective symbol */
652 /* Store the pointer in the offset. */
653 S_SET_ZEROES(symbolP
, 0L);
654 S_SET_DATA_TYPE(symbolP
, T_NULL
);
655 S_SET_STORAGE_CLASS(symbolP
, 0);
656 S_SET_NUMBER_AUXILIARY(symbolP
, 0);
657 /* Additional information */
658 symbolP
->sy_symbol
.ost_flags
= 0;
659 /* Auxiliary entries */
660 bzero((char*)&symbolP
->sy_symbol
.ost_auxent
[0], AUXESZ
);
662 #ifdef STRIP_UNDERSCORE
663 /* Remove leading underscore at the beginning of the symbol.
664 * This is to be compatible with the standard librairies.
666 if (*S_GET_NAME(symbolP
) == '_') {
668 S_SET_NAME(symbolP
, S_GET_NAME(symbolP
) + 1);
669 } /* strip underscore */
670 #endif /* STRIP_UNDERSCORE */
672 if (S_IS_STRING(symbolP
))
673 SF_SET_STRING(symbolP
);
674 if (!underscore
&& S_IS_LOCAL(symbolP
))
675 SF_SET_LOCAL(symbolP
);
678 } /* obj_symbol_new_hook() */
681 stack
* stack_init(chunk_size
, element_size
)
682 unsigned long chunk_size
;
683 unsigned long element_size
;
687 if ((st
= (stack
*)malloc(sizeof(stack
))) == (stack
*)0)
689 if ((st
->data
= malloc(chunk_size
)) == (char*)0) {
694 st
->size
= chunk_size
;
695 st
->chunk_size
= chunk_size
;
696 st
->element_size
= element_size
;
700 void stack_delete(st
)
707 char *stack_push(st
, element
)
711 if (st
->pointer
+ st
->element_size
>= st
->size
) {
712 st
->size
+= st
->chunk_size
;
713 if ((st
->data
= xrealloc(st
->data
, st
->size
)) == (char*)0)
716 memcpy(st
->data
+ st
->pointer
, element
, st
->element_size
);
717 st
->pointer
+= st
->element_size
;
718 return st
->data
+ st
->pointer
;
724 if ((st
->pointer
-= st
->element_size
) < 0) {
729 return st
->data
+ st
->pointer
;
735 return st
->data
+ st
->pointer
- st
->element_size
;
740 * Handle .ln directives.
743 static void obj_coff_ln()
747 if (def_symbol_in_progress
!= NULL
) {
748 as_warn(".ln pseudo-op inside .def/.endef: ignored.");
749 demand_empty_rest_of_line();
751 } /* wrong context */
754 obstack_next_free(&frags
) - frag_now
->fr_literal
,
755 l
= get_absolute_expression(),
763 listing_source_line(l
+ line_base
- 1);
768 demand_empty_rest_of_line();
770 } /* obj_coff_line() */
775 * Handle .def directives.
777 * One might ask : why can't we symbol_new if the symbol does not
778 * already exist and fill it with debug information. Because of
779 * the C_EFCN special symbol. It would clobber the value of the
780 * function symbol before we have a chance to notice that it is
781 * a C_EFCN. And a second reason is that the code is more clear this
782 * way. (at least I think it is :-).
786 #define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';')
787 #define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \
788 *input_line_pointer == '\t') \
789 input_line_pointer++;
792 DEFUN(obj_coff_def
,(what
),
795 char name_end
; /* Char after the end of name */
796 char *symbol_name
; /* Name of the debug symbol */
797 char *symbol_name_copy
; /* Temporary copy of the name */
798 unsigned int symbol_name_length
;
799 /*$char* directiveP;$ */ /* Name of the pseudo opcode */
800 /*$char directive[MAX_DIRECTIVE];$ */ /* Backup of the directive */
801 /*$char end = 0;$ */ /* If 1, stop parsing */
803 if (def_symbol_in_progress
!= NULL
) {
804 as_warn(".def pseudo-op used inside of .def/.endef: ignored.");
805 demand_empty_rest_of_line();
807 } /* if not inside .def/.endef */
811 def_symbol_in_progress
= (symbolS
*) obstack_alloc(¬es
, sizeof(*def_symbol_in_progress
));
812 bzero(def_symbol_in_progress
, sizeof(*def_symbol_in_progress
));
814 symbol_name
= input_line_pointer
;
815 name_end
= get_symbol_end();
816 symbol_name_length
= strlen(symbol_name
);
817 symbol_name_copy
= xmalloc(symbol_name_length
+ 1);
818 strcpy(symbol_name_copy
, symbol_name
);
820 /* Initialize the new symbol */
821 #ifdef STRIP_UNDERSCORE
822 S_SET_NAME(def_symbol_in_progress
, (*symbol_name_copy
== '_'
823 ? symbol_name_copy
+ 1
824 : symbol_name_copy
));
825 #else /* STRIP_UNDERSCORE */
826 S_SET_NAME(def_symbol_in_progress
, symbol_name_copy
);
827 #endif /* STRIP_UNDERSCORE */
828 /* free(symbol_name_copy); */
829 def_symbol_in_progress
->sy_name_offset
= ~0;
830 def_symbol_in_progress
->sy_number
= ~0;
831 def_symbol_in_progress
->sy_frag
= &zero_address_frag
;
833 if (S_IS_STRING(def_symbol_in_progress
)) {
834 SF_SET_STRING(def_symbol_in_progress
);
837 *input_line_pointer
= name_end
;
839 demand_empty_rest_of_line();
841 } /* obj_coff_def() */
843 unsigned int dim_index
;
845 DEFUN_VOID(obj_coff_endef
)
847 symbolS
*symbolP
= 0;
848 /* DIM BUG FIX sac@cygnus.com */
850 if (def_symbol_in_progress
== NULL
) {
851 as_warn(".endef pseudo-op used outside of .def/.endef: ignored.");
852 demand_empty_rest_of_line();
854 } /* if not inside .def/.endef */
856 /* Set the section number according to storage class. */
857 switch (S_GET_STORAGE_CLASS(def_symbol_in_progress
)) {
861 SF_SET_TAG(def_symbol_in_progress
);
862 /* intentional fallthrough */
865 SF_SET_DEBUG(def_symbol_in_progress
);
866 S_SET_SEGMENT(def_symbol_in_progress
, SEG_DEBUG
);
870 SF_SET_LOCAL(def_symbol_in_progress
); /* Do not emit this symbol. */
871 /* intentional fallthrough */
873 SF_SET_PROCESS(def_symbol_in_progress
); /* Will need processing before writing */
874 /* intentional fallthrough */
876 S_SET_SEGMENT(def_symbol_in_progress
, SEG_E0
);
878 if (def_symbol_in_progress
->sy_symbol
.ost_entry
._n
._n_nptr
[1][1] == 'b'
879 && def_symbol_in_progress
->sy_symbol
.ost_entry
._n
._n_nptr
[1][2] == 'f') { /* .bf */
880 if (function_lineoff
< 0) {
881 fprintf(stderr
, "`.bf' symbol without preceding function\n");
882 } /* missing function symbol */
883 SA_GET_SYM_LNNOPTR(last_line_symbol
) = function_lineoff
;
885 SF_SET_PROCESS(last_line_symbol
);
886 function_lineoff
= -1;
892 #endif /* C_AUTOARG */
902 SF_SET_DEBUG(def_symbol_in_progress
);
903 S_SET_SEGMENT(def_symbol_in_progress
, SEG_ABSOLUTE
);
909 /* Valid but set somewhere else (s_comm, s_lcomm, colon) */
915 as_warn("unexpected storage class %d", S_GET_STORAGE_CLASS(def_symbol_in_progress
));
917 } /* switch on storage class */
919 /* Now that we have built a debug symbol, try to
920 find if we should merge with an existing symbol
921 or not. If a symbol is C_EFCN or SEG_ABSOLUTE or
922 untagged SEG_DEBUG it never merges. */
924 /* Two cases for functions. Either debug followed
925 by definition or definition followed by debug.
926 For definition first, we will merge the debug
927 symbol into the definition. For debug first, the
928 lineno entry MUST point to the definition
929 function or else it will point off into space
930 when crawl_symbols() merges the debug
931 symbol into the real symbol. Therefor, let's
932 presume the debug symbol is a real function
935 /* FIXME-SOON If for some reason the definition
936 label/symbol is never seen, this will probably
937 leave an undefined symbol at link time. */
939 if (S_GET_STORAGE_CLASS(def_symbol_in_progress
) == C_EFCN
940 || (S_GET_SEGMENT(def_symbol_in_progress
) == SEG_DEBUG
941 && !SF_GET_TAG(def_symbol_in_progress
))
942 || S_GET_SEGMENT(def_symbol_in_progress
) == SEG_ABSOLUTE
943 || (symbolP
= symbol_find_base(S_GET_NAME(def_symbol_in_progress
), DO_NOT_STRIP
)) == NULL
) {
945 symbol_append(def_symbol_in_progress
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
948 /* This symbol already exists, merge the
949 newly created symbol into the old one.
950 This is not mandatory. The linker can
951 handle duplicate symbols correctly. But I
952 guess that it save a *lot* of space if
953 the assembly file defines a lot of
956 /* The debug entry (def_symbol_in_progress)
957 is merged into the previous definition. */
959 c_symbol_merge(def_symbol_in_progress
, symbolP
);
960 /* FIXME-SOON Should *def_symbol_in_progress be free'd? xoxorich. */
961 def_symbol_in_progress
= symbolP
;
963 if (SF_GET_FUNCTION(def_symbol_in_progress
)
964 || SF_GET_TAG(def_symbol_in_progress
)) {
965 /* For functions, and tags, the symbol *must* be where the debug symbol
966 appears. Move the existing symbol to the current place. */
967 /* If it already is at the end of the symbol list, do nothing */
968 if (def_symbol_in_progress
!= symbol_lastP
) {
969 symbol_remove(def_symbol_in_progress
, &symbol_rootP
, &symbol_lastP
);
970 symbol_append(def_symbol_in_progress
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
971 } /* if not already in place */
973 } /* normal or mergable */
975 if (SF_GET_TAG(def_symbol_in_progress
)
976 && symbol_find_base(S_GET_NAME(def_symbol_in_progress
), DO_NOT_STRIP
) == NULL
) {
977 tag_insert(S_GET_NAME(def_symbol_in_progress
), def_symbol_in_progress
);
978 } /* If symbol is a {structure,union} tag, associate symbol to its name. */
980 if (SF_GET_FUNCTION(def_symbol_in_progress
)) {
981 know(sizeof(def_symbol_in_progress
) <= sizeof(long));
983 = c_line_new(def_symbol_in_progress
,0, 0, &zero_address_frag
);
987 SF_SET_PROCESS(def_symbol_in_progress
);
989 if (symbolP
== NULL
) {
990 /* That is, if this is the first
991 time we've seen the function... */
992 symbol_table_insert(def_symbol_in_progress
);
993 } /* definition follows debug */
994 } /* Create the line number entry pointing to the function being defined */
996 def_symbol_in_progress
= NULL
;
997 demand_empty_rest_of_line();
999 } /* obj_coff_endef() */
1002 DEFUN_VOID(obj_coff_dim
)
1004 register int dim_index
;
1006 if (def_symbol_in_progress
== NULL
)
1008 as_warn(".dim pseudo-op used outside of .def/.endef: ignored.");
1009 demand_empty_rest_of_line();
1011 } /* if not inside .def/.endef */
1013 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1015 for (dim_index
= 0; dim_index
< DIMNUM
; dim_index
++)
1018 SA_SET_SYM_DIMEN(def_symbol_in_progress
, dim_index
, get_absolute_expression());
1020 switch (*input_line_pointer
)
1024 input_line_pointer
++;
1028 as_warn("badly formed .dim directive ignored");
1029 /* intentional fallthrough */
1034 } /* switch on following character */
1035 } /* for each dimension */
1037 demand_empty_rest_of_line();
1039 } /* obj_coff_dim() */
1041 static void obj_coff_line()
1045 if (def_symbol_in_progress
== NULL
) {
1048 } /* if it looks like a stabs style line */
1050 this_base
= get_absolute_expression();
1051 if (this_base
> line_base
)
1053 line_base
= this_base
;
1061 listing_source_line(line_base
);
1065 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1066 SA_SET_SYM_LNNO(def_symbol_in_progress
, line_base
);
1068 demand_empty_rest_of_line();
1070 } /* obj_coff_line() */
1072 static void obj_coff_size() {
1073 if (def_symbol_in_progress
== NULL
) {
1074 as_warn(".size pseudo-op used outside of .def/.endef ignored.");
1075 demand_empty_rest_of_line();
1077 } /* if not inside .def/.endef */
1079 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1080 SA_SET_SYM_SIZE(def_symbol_in_progress
, get_absolute_expression());
1081 demand_empty_rest_of_line();
1083 } /* obj_coff_size() */
1085 static void obj_coff_scl() {
1086 if (def_symbol_in_progress
== NULL
) {
1087 as_warn(".scl pseudo-op used outside of .def/.endef ignored.");
1088 demand_empty_rest_of_line();
1090 } /* if not inside .def/.endef */
1092 S_SET_STORAGE_CLASS(def_symbol_in_progress
, get_absolute_expression());
1093 demand_empty_rest_of_line();
1095 } /* obj_coff_scl() */
1097 static void obj_coff_tag() {
1101 if (def_symbol_in_progress
== NULL
) {
1102 as_warn(".tag pseudo-op used outside of .def/.endef ignored.");
1103 demand_empty_rest_of_line();
1105 } /* if not inside .def/.endef */
1107 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1108 symbol_name
= input_line_pointer
;
1109 name_end
= get_symbol_end();
1111 /* Assume that the symbol referred to by .tag is always defined. */
1112 /* This was a bad assumption. I've added find_or_make. xoxorich. */
1113 SA_SET_SYM_TAGNDX(def_symbol_in_progress
, (long) tag_find_or_make(symbol_name
));
1114 if (SA_GET_SYM_TAGNDX(def_symbol_in_progress
) == 0L) {
1115 as_warn("tag not found for .tag %s", symbol_name
);
1118 SF_SET_TAGGED(def_symbol_in_progress
);
1119 *input_line_pointer
= name_end
;
1121 demand_empty_rest_of_line();
1123 } /* obj_coff_tag() */
1125 static void obj_coff_type() {
1126 if (def_symbol_in_progress
== NULL
) {
1127 as_warn(".type pseudo-op used outside of .def/.endef ignored.");
1128 demand_empty_rest_of_line();
1130 } /* if not inside .def/.endef */
1132 S_SET_DATA_TYPE(def_symbol_in_progress
, get_absolute_expression());
1134 if (ISFCN(S_GET_DATA_TYPE(def_symbol_in_progress
)) &&
1135 S_GET_STORAGE_CLASS(def_symbol_in_progress
) != C_TPDEF
) {
1136 SF_SET_FUNCTION(def_symbol_in_progress
);
1137 } /* is a function */
1139 demand_empty_rest_of_line();
1141 } /* obj_coff_type() */
1143 static void obj_coff_val() {
1144 if (def_symbol_in_progress
== NULL
) {
1145 as_warn(".val pseudo-op used outside of .def/.endef ignored.");
1146 demand_empty_rest_of_line();
1148 } /* if not inside .def/.endef */
1150 if (is_name_beginner(*input_line_pointer
)) {
1151 char *symbol_name
= input_line_pointer
;
1152 char name_end
= get_symbol_end();
1154 if (!strcmp(symbol_name
, ".")) {
1155 def_symbol_in_progress
->sy_frag
= frag_now
;
1156 S_SET_VALUE(def_symbol_in_progress
, obstack_next_free(&frags
) - frag_now
->fr_literal
);
1157 /* If the .val is != from the .def (e.g. statics) */
1158 } else if (strcmp(S_GET_NAME(def_symbol_in_progress
), symbol_name
)) {
1159 def_symbol_in_progress
->sy_forward
= symbol_find_or_make(symbol_name
);
1161 /* If the segment is undefined when the forward
1162 reference is solved, then copy the segment id
1163 from the forward symbol. */
1164 SF_SET_GET_SEGMENT(def_symbol_in_progress
);
1166 /* Otherwise, it is the name of a non debug symbol and its value will be calculated later. */
1167 *input_line_pointer
= name_end
;
1169 S_SET_VALUE(def_symbol_in_progress
, get_absolute_expression());
1170 } /* if symbol based */
1172 demand_empty_rest_of_line();
1174 } /* obj_coff_val() */
1177 * Maintain a list of the tagnames of the structres.
1180 static void tag_init() {
1181 tag_hash
= hash_new();
1185 static void tag_insert(name
, symbolP
)
1189 register char * error_string
;
1191 if (*(error_string
= hash_jam(tag_hash
, name
, (char *)symbolP
))) {
1192 as_fatal("Inserting \"%s\" into structure table failed: %s",
1193 name
, error_string
);
1196 } /* tag_insert() */
1198 static symbolS
*tag_find_or_make(name
)
1203 if ((symbolP
= tag_find(name
)) == NULL
) {
1204 symbolP
= symbol_new(name
,
1207 &zero_address_frag
);
1209 tag_insert(S_GET_NAME(symbolP
), symbolP
);
1210 symbol_table_insert(symbolP
);
1214 } /* tag_find_or_make() */
1216 static symbolS
*tag_find(name
)
1219 #ifdef STRIP_UNDERSCORE
1220 if (*name
== '_') name
++;
1221 #endif /* STRIP_UNDERSCORE */
1222 return((symbolS
*)hash_find(tag_hash
, name
));
1225 void obj_read_begin_hook() {
1226 /* These had better be the same. Usually 18 bytes. */
1228 know(sizeof(SYMENT
) == sizeof(AUXENT
));
1229 know(SYMESZ
== AUXESZ
);
1234 } /* obj_read_begin_hook() */
1236 /* This function runs through the symbol table and puts all the
1237 externals onto another chain */
1239 /* The chain of externals */
1240 symbolS
*symbol_externP
= NULL
;
1241 symbolS
*symbol_extern_lastP
= NULL
;
1244 symbolS
*last_functionP
= NULL
;
1248 static unsigned int DEFUN_VOID(yank_symbols
)
1251 unsigned int symbol_number
=0;
1253 for (symbolP
= symbol_rootP
;
1255 symbolP
= symbolP
? symbol_next(symbolP
) : symbol_rootP
) {
1256 if (!SF_GET_DEBUG(symbolP
)) {
1257 /* Debug symbols do not need all this rubbish */
1258 symbolS
* real_symbolP
;
1260 /* L* and C_EFCN symbols never merge. */
1261 if (!SF_GET_LOCAL(symbolP
)
1262 && (real_symbolP
= symbol_find_base(S_GET_NAME(symbolP
), DO_NOT_STRIP
))
1263 && real_symbolP
!= symbolP
) {
1264 /* FIXME-SOON: where do dups come from?
1265 Maybe tag references before definitions? xoxorich. */
1266 /* Move the debug data from the debug symbol to the
1267 real symbol. Do NOT do the oposite (i.e. move from
1268 real symbol to debug symbol and remove real symbol from the
1269 list.) Because some pointers refer to the real symbol
1270 whereas no pointers refer to the debug symbol. */
1271 c_symbol_merge(symbolP
, real_symbolP
);
1272 /* Replace the current symbol by the real one */
1273 /* The symbols will never be the last or the first
1274 because : 1st symbol is .file and 3 last symbols are
1275 .text, .data, .bss */
1276 symbol_remove(real_symbolP
, &symbol_rootP
, &symbol_lastP
);
1277 symbol_insert(real_symbolP
, symbolP
, &symbol_rootP
, &symbol_lastP
);
1278 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1279 symbolP
= real_symbolP
;
1280 } /* if not local but dup'd */
1282 if (flagseen
['R'] && (S_GET_SEGMENT(symbolP
) == SEG_E1
)) {
1283 S_SET_SEGMENT(symbolP
, SEG_E0
);
1284 } /* push data into text */
1286 S_SET_VALUE(symbolP
,
1287 S_GET_VALUE(symbolP
) + symbolP
->sy_frag
->fr_address
);
1289 if (!S_IS_DEFINED(symbolP
) && !SF_GET_LOCAL(symbolP
))
1291 S_SET_EXTERNAL(symbolP
);
1293 else if (S_GET_STORAGE_CLASS(symbolP
) == C_NULL
)
1295 if (S_GET_SEGMENT(symbolP
) == SEG_E0
)
1297 S_SET_STORAGE_CLASS(symbolP
, C_LABEL
);
1301 S_SET_STORAGE_CLASS(symbolP
, C_STAT
);
1305 /* Mainly to speed up if not -g */
1306 if (SF_GET_PROCESS(symbolP
))
1308 /* Handle the nested blocks auxiliary info. */
1309 if (S_GET_STORAGE_CLASS(symbolP
) == C_BLOCK
) {
1310 if (!strcmp(S_GET_NAME(symbolP
), ".bb"))
1311 stack_push(block_stack
, (char *) &symbolP
);
1313 register symbolS
* begin_symbolP
;
1314 begin_symbolP
= *(symbolS
**)stack_pop(block_stack
);
1315 if (begin_symbolP
== (symbolS
*)0)
1316 as_warn("mismatched .eb");
1318 SA_SET_SYM_ENDNDX(begin_symbolP
, symbol_number
+2);
1321 /* If we are able to identify the type of a function, and we
1322 are out of a function (last_functionP == 0) then, the
1323 function symbol will be associated with an auxiliary
1325 if (last_functionP
== (symbolS
*)0 &&
1326 SF_GET_FUNCTION(symbolP
)) {
1327 last_functionP
= symbolP
;
1329 if (S_GET_NUMBER_AUXILIARY(symbolP
) < 1) {
1330 S_SET_NUMBER_AUXILIARY(symbolP
, 1);
1331 } /* make it at least 1 */
1333 /* Clobber possible stale .dim information. */
1335 /* Iffed out by steve - this fries the lnnoptr info too */
1336 bzero(symbolP
->sy_symbol
.ost_auxent
[0].x_sym
.x_fcnary
.x_ary
.x_dimen
,
1337 sizeof(symbolP
->sy_symbol
.ost_auxent
[0].x_sym
.x_fcnary
.x_ary
.x_dimen
));
1340 /* The C_FCN doesn't need any additional information.
1341 I don't even know if this is needed for sdb. But the
1342 standard assembler generates it, so...
1344 if (S_GET_STORAGE_CLASS(symbolP
) == C_EFCN
) {
1345 if (last_functionP
== (symbolS
*)0)
1346 as_fatal("C_EFCN symbol out of scope");
1347 SA_SET_SYM_FSIZE(last_functionP
,
1348 (long)(S_GET_VALUE(symbolP
) -
1349 S_GET_VALUE(last_functionP
)));
1350 SA_SET_SYM_ENDNDX(last_functionP
, symbol_number
);
1351 last_functionP
= (symbolS
*)0;
1354 } else if (SF_GET_TAG(symbolP
)) {
1355 /* First descriptor of a structure must point to
1356 the first slot after the structure description. */
1357 last_tagP
= symbolP
;
1359 } else if (S_GET_STORAGE_CLASS(symbolP
) == C_EOS
) {
1360 /* +2 take in account the current symbol */
1361 SA_SET_SYM_ENDNDX(last_tagP
, symbol_number
+ 2);
1362 } else if (S_GET_STORAGE_CLASS(symbolP
) == C_FILE
) {
1363 if (S_GET_VALUE(symbolP
)) {
1364 S_SET_VALUE((symbolS
*) S_GET_VALUE(symbolP
), symbol_number
);
1365 S_SET_VALUE(symbolP
, 0);
1366 } /* no one points at the first .file symbol */
1367 } /* if debug or tag or eos or file */
1369 /* We must put the external symbols apart. The loader
1370 does not bomb if we do not. But the references in
1371 the endndx field for a .bb symbol are not corrected
1372 if an external symbol is removed between .bb and .be.
1373 I.e in the following case :
1374 [20] .bb endndx = 22
1377 ld will move the symbol 21 to the end of the list but
1378 endndx will still be 22 instead of 21. */
1381 if (SF_GET_LOCAL(symbolP
)) {
1382 /* remove C_EFCN and LOCAL (L...) symbols */
1383 /* next pointer remains valid */
1384 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1387 else if (!S_IS_DEFINED(symbolP
)
1388 && !S_IS_DEBUG(symbolP
)
1389 && !SF_GET_STATICS(symbolP
) &&
1390 S_GET_STORAGE_CLASS(symbolP
) == C_EXT
)
1391 { /* C_EXT && !SF_GET_FUNCTION(symbolP)) */
1392 /* if external, Remove from the list */
1393 symbolS
*hold
= symbol_previous(symbolP
);
1395 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1396 symbol_clear_list_pointers(symbolP
);
1397 symbol_append(symbolP
, symbol_extern_lastP
, &symbol_externP
, &symbol_extern_lastP
);
1400 if (SF_GET_STRING(symbolP
)) {
1401 symbolP
->sy_name_offset
= string_byte_count
;
1402 string_byte_count
+= strlen(S_GET_NAME(symbolP
)) + 1;
1404 symbolP
->sy_name_offset
= 0;
1405 } /* fix "long" names */
1407 symbolP
->sy_number
= symbol_number
;
1408 symbol_number
+= 1 + S_GET_NUMBER_AUXILIARY(symbolP
);
1409 } /* if local symbol */
1410 } /* traverse the symbol list */
1411 return symbol_number
;
1416 static unsigned int DEFUN_VOID(glue_symbols
)
1418 unsigned int symbol_number
= 0;
1420 for (symbolP
= symbol_externP
; symbol_externP
;) {
1421 symbolS
*tmp
= symbol_externP
;
1424 symbol_remove(tmp
, &symbol_externP
, &symbol_extern_lastP
);
1425 symbol_append(tmp
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
1428 if (SF_GET_STRING(tmp
)) {
1429 tmp
->sy_name_offset
= string_byte_count
;
1430 string_byte_count
+= strlen(S_GET_NAME(tmp
)) + 1;
1432 tmp
->sy_name_offset
= 0;
1433 } /* fix "long" names */
1435 tmp
->sy_number
= symbol_number
;
1436 symbol_number
+= 1 + S_GET_NUMBER_AUXILIARY(tmp
);
1437 } /* append the entire extern chain */
1438 return symbol_number
;
1442 static unsigned int DEFUN_VOID(tie_tags
)
1444 unsigned int symbol_number
= 0;
1447 for (symbolP
= symbol_rootP
; symbolP
; symbolP
=
1448 symbol_next(symbolP
))
1450 symbolP
->sy_number
= symbol_number
;
1454 if (SF_GET_TAGGED(symbolP
))
1458 ((symbolS
*) SA_GET_SYM_TAGNDX(symbolP
))->sy_number
);
1461 symbol_number
+= 1 + S_GET_NUMBER_AUXILIARY(symbolP
);
1463 return symbol_number
;
1468 DEFUN(crawl_symbols
,(headers
, abfd
),
1469 struct internal_filehdr
*headers AND
1474 unsigned int ptr
= 0;
1479 /* Initialize the stack used to keep track of the matching .bb .be */
1481 block_stack
= stack_init(512, sizeof(symbolS
*));
1482 /* JF deal with forward references first... */
1483 for (symbolP
= symbol_rootP
;
1485 symbolP
= symbol_next(symbolP
))
1488 if (symbolP
->sy_forward
) {
1489 S_SET_VALUE(symbolP
, (S_GET_VALUE(symbolP
)
1490 + S_GET_VALUE(symbolP
->sy_forward
)
1491 + symbolP
->sy_forward
->sy_frag
->fr_address
));
1493 if (SF_GET_GET_SEGMENT(symbolP
)) {
1494 S_SET_SEGMENT(symbolP
, S_GET_SEGMENT(symbolP
->sy_forward
));
1495 } /* forward segment also */
1497 symbolP
->sy_forward
=0;
1498 } /* if it has a forward reference */
1499 } /* walk the symbol chain */
1502 /* The symbol list should be ordered according to the following sequence
1505 * . debug entries for functions
1506 * . fake symbols for the sections, including.text .data and .bss
1508 * . undefined symbols
1509 * But this is not mandatory. The only important point is to put the
1510 * undefined symbols at the end of the list.
1513 if (symbol_rootP
== NULL
1514 || S_GET_STORAGE_CLASS(symbol_rootP
) != C_FILE
) {
1515 c_dot_file_symbol("fake");
1517 /* Is there a .file symbol ? If not insert one at the beginning. */
1520 * Build up static symbols for the sections, they are filled in later
1524 for (i
= SEG_E0
; i
< SEG_E9
; i
++)
1526 if (segment_info
[i
].scnhdr
.s_name
[0])
1528 segment_info
[i
].dot
=
1529 c_section_symbol(segment_info
[i
].scnhdr
.s_name
,
1536 /* Take all the externals out and put them into another chain */
1537 headers
->f_nsyms
= yank_symbols();
1538 /* Take the externals and glue them onto the end.*/
1539 headers
->f_nsyms
+= glue_symbols();
1541 headers
->f_nsyms
= tie_tags();
1542 know(symbol_externP
== NULL
);
1543 know(symbol_extern_lastP
== NULL
);
1549 * Find strings by crawling along symbol table chain.
1552 void DEFUN(w_strings
,(where
),
1557 /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
1558 md_number_to_chars(where
, string_byte_count
, sizeof(string_byte_count
));
1559 where
+= sizeof(string_byte_count
);
1560 for (symbolP
= symbol_rootP
;
1562 symbolP
= symbol_next(symbolP
))
1566 if (SF_GET_STRING(symbolP
)) {
1567 size
= strlen(S_GET_NAME(symbolP
)) + 1;
1569 memcpy(where
, S_GET_NAME(symbolP
),size
);
1582 DEFUN(do_linenos_for
,(abfd
, file_cursor
),
1584 unsigned long *file_cursor
)
1588 for (idx
= SEG_E0
; idx
< SEG_E9
; idx
++)
1590 segment_info_type
*s
= segment_info
+ idx
;
1593 if (s
->scnhdr
.s_nlnno
!= 0)
1595 struct lineno_list
*line_ptr
;
1597 struct external_lineno
*buffer
=
1598 (struct external_lineno
*)xmalloc(s
->scnhdr
.s_nlnno
* LINESZ
);
1600 struct external_lineno
*dst
= buffer
;
1602 /* Run through the table we've built and turn it into its external
1603 form, take this chance to remove duplicates */
1605 for (line_ptr
= s
->lineno_list_head
;
1606 line_ptr
!= (struct lineno_list
*)NULL
;
1607 line_ptr
= line_ptr
->next
)
1610 if (line_ptr
->line
.l_lnno
== 0)
1612 /* Turn a pointer to a symbol into the symbols' index */
1613 line_ptr
->line
.l_addr
.l_symndx
=
1614 ( (symbolS
*)line_ptr
->line
.l_addr
.l_symndx
)->sy_number
;
1618 line_ptr
->line
.l_addr
.l_paddr
+= ((struct frag
* )(line_ptr
->frag
))->fr_address
;
1622 (void) bfd_coff_swap_lineno_out(abfd
, &(line_ptr
->line
), dst
);
1627 s
->scnhdr
.s_lnnoptr
= *file_cursor
;
1629 bfd_write(buffer
, 1, s
->scnhdr
.s_nlnno
* LINESZ
, abfd
);
1632 *file_cursor
+= s
->scnhdr
.s_nlnno
* LINESZ
;
1638 /* Now we run through the list of frag chains in a segment and
1639 make all the subsegment frags appear at the end of the
1640 list, as if the seg 0 was extra long */
1642 static void DEFUN_VOID(remove_subsegs
)
1646 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1648 frchainS
*head
= segment_info
[i
].frchainP
;
1650 fragS
* prev_frag
= &dummy
;
1652 while (head
&& head
->frch_seg
== i
)
1654 prev_frag
->fr_next
= head
->frch_root
;
1655 prev_frag
= head
->frch_last
;
1656 head
= head
->frch_next
;
1658 prev_frag
->fr_next
= 0;
1664 extern void DEFUN_VOID(write_object_file
)
1667 struct frchain
*frchain_ptr
;
1669 struct internal_filehdr filehdr
;
1670 struct internal_aouthdr aouthdr
;
1671 unsigned long file_cursor
;
1673 unsigned int addr
= 0;
1674 abfd
= bfd_openw(out_file_name
, TARGET_FORMAT
);
1678 as_perror ("FATAL: Can't create %s", out_file_name
);
1681 bfd_set_format(abfd
, bfd_object
);
1682 bfd_set_arch_mach(abfd
, BFD_ARCH
, machine
);
1686 string_byte_count
= 4;
1688 for (frchain_ptr
= frchain_root
;
1689 frchain_ptr
!= (struct frchain
*)NULL
;
1690 frchain_ptr
= frchain_ptr
->frch_next
) {
1691 /* Run through all the sub-segments and align them up. Also close any
1692 open frags. We tack a .fill onto the end of the frag chain so
1693 that any .align's size can be worked by looking at the next
1696 subseg_new(frchain_ptr
->frch_seg
, frchain_ptr
->frch_subseg
);
1697 #define SUB_SEGMENT_ALIGN 1
1698 frag_align(SUB_SEGMENT_ALIGN
,0);
1699 frag_wane(frag_now
);
1700 frag_now
->fr_fix
= 0;
1701 know( frag_now
->fr_next
== NULL
);
1708 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1710 relax_segment(segment_info
[i
].frchainP
->frch_root
, i
);
1717 filehdr
.f_nscns
= 0;
1719 /* Find out how big the sections are */
1720 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1723 if (segment_info
[i
].scnhdr
.s_name
[0])
1730 /* THis is a special case, we leave the size alone, which will have */
1731 /* been made up from all and any lcomms seen */
1735 addr
+= size_section(abfd
, i
);
1741 /* Turn the gas native symbol table shape into a coff symbol table */
1742 crawl_symbols(&filehdr
, abfd
);
1743 #if !defined(TC_H8300) && !defined(TC_Z8K)
1744 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1746 fixup_mdeps(segment_info
[i
].frchainP
->frch_root
);
1747 fixup_segment(segment_info
[i
].fix_root
, i
);
1751 file_cursor
= FILHSZ
+ SCNHSZ
* filehdr
.f_nscns
;
1753 bfd_seek(abfd
, file_cursor
, 0);
1756 do_relocs_for(abfd
, &file_cursor
);
1758 do_linenos_for(abfd
, &file_cursor
);
1761 /* Plant the data */
1763 fill_section(abfd
,&filehdr
, &file_cursor
);
1767 filehdr
.f_magic
= COFF_MAGIC
;
1768 filehdr
.f_timdat
= time(0);
1769 filehdr
.f_flags
= COFF_FLAGS
| coff_flags
;
1773 filehdr
.f_flags
|= F_LNNO
;
1777 filehdr
.f_flags
|= F_RELFLG
;
1788 unsigned int symtable_size
= filehdr
.f_nsyms
* SYMESZ
;
1789 char *buffer1
= malloc(symtable_size
+ string_byte_count
+ 4);
1790 char *ptr
= buffer1
;
1791 filehdr
.f_symptr
= bfd_tell(abfd
);
1792 w_symbols(abfd
, buffer1
, symbol_rootP
);
1793 w_strings(buffer1
+ symtable_size
);
1794 bfd_write(buffer1
, 1,symtable_size
+ string_byte_count
+ 4, abfd
);
1798 coff_header_append(abfd
, &filehdr
, &aouthdr
);
1800 bfd_close_all_done(abfd
);
1804 static void DEFUN(change_to_section
,(name
, len
, exp
),
1806 unsigned int len AND
1810 /* Find out if we've already got a section of this name etc */
1811 for(i
= SEG_E0
; i
< SEG_E9
&& segment_info
[i
].scnhdr
.s_name
[0] ; i
++)
1813 if (strncmp(segment_info
[i
].scnhdr
.s_name
, name
, len
) == 0)
1820 /* No section, add one */
1821 strncpy(segment_info
[i
].scnhdr
.s_name
, name
, 8);
1826 DEFUN_VOID(obj_coff_section
)
1828 /* Strip out the section name */
1829 char *section_name
;
1830 char *section_name_end
;
1836 section_name
= input_line_pointer
;
1837 c
= get_symbol_end();
1838 section_name_end
= input_line_pointer
;
1840 len
= section_name_end
- section_name
;
1841 input_line_pointer
++;
1845 exp
= get_absolute_expression();
1847 else if ( *input_line_pointer
== ',')
1850 input_line_pointer
++;
1851 exp
= get_absolute_expression();
1858 change_to_section(section_name
, len
,exp
);
1859 *section_name_end
= c
;
1864 static void obj_coff_text()
1866 change_to_section(".text",5, get_absolute_expression());
1870 static void obj_coff_data()
1872 change_to_section(".data",5, get_absolute_expression());
1875 void c_symbol_merge(debug
, normal
)
1879 S_SET_DATA_TYPE(normal
, S_GET_DATA_TYPE(debug
));
1880 S_SET_STORAGE_CLASS(normal
, S_GET_STORAGE_CLASS(debug
));
1882 if (S_GET_NUMBER_AUXILIARY(debug
) > S_GET_NUMBER_AUXILIARY(normal
)) {
1883 S_SET_NUMBER_AUXILIARY(normal
, S_GET_NUMBER_AUXILIARY(debug
));
1884 } /* take the most we have */
1886 if (S_GET_NUMBER_AUXILIARY(debug
) > 0) {
1887 memcpy((char*)&normal
->sy_symbol
.ost_auxent
[0], (char*)&debug
->sy_symbol
.ost_auxent
[0], S_GET_NUMBER_AUXILIARY(debug
) * AUXESZ
);
1888 } /* Move all the auxiliary information */
1890 /* Move the debug flags. */
1891 SF_SET_DEBUG_FIELD(normal
, SF_GET_DEBUG_FIELD(debug
));
1892 } /* c_symbol_merge() */
1895 DEFUN(c_line_new
,(symbol
, paddr
, line_number
, frag
),
1898 unsigned short line_number AND
1901 struct lineno_list
* new_line
=
1902 (struct lineno_list
*)xmalloc(sizeof(struct lineno_list
));
1904 segment_info_type
*s
= segment_info
+ now_seg
;
1905 new_line
->line
.l_lnno
= line_number
;
1909 if (line_number
== 0)
1911 last_line_symbol
= symbol
;
1912 new_line
->line
.l_addr
.l_symndx
= (long)symbol
;
1916 new_line
->line
.l_addr
.l_paddr
= paddr
;
1919 new_line
->frag
= (char*)frag
;
1920 new_line
->next
= (struct lineno_list
*)NULL
;
1923 if (s
->lineno_list_head
== (struct lineno_list
*)NULL
)
1925 s
->lineno_list_head
= new_line
;
1929 s
->lineno_list_tail
->next
= new_line
;
1931 s
->lineno_list_tail
= new_line
;
1932 return LINESZ
* s
->scnhdr
.s_nlnno
++;
1935 void c_dot_file_symbol(filename
)
1940 symbolP
= symbol_new(".file",
1943 &zero_address_frag
);
1945 S_SET_STORAGE_CLASS(symbolP
, C_FILE
);
1946 S_SET_NUMBER_AUXILIARY(symbolP
, 1);
1947 SA_SET_FILE_FNAME(symbolP
, filename
);
1953 listing_source_file(filename
);
1959 SF_SET_DEBUG(symbolP
);
1960 S_SET_VALUE(symbolP
, (long) previous_file_symbol
);
1962 previous_file_symbol
= symbolP
;
1964 /* Make sure that the symbol is first on the symbol chain */
1965 if (symbol_rootP
!= symbolP
) {
1966 if (symbolP
== symbol_lastP
) {
1967 symbol_lastP
= symbol_lastP
->sy_previous
;
1968 } /* if it was the last thing on the list */
1970 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1971 symbol_insert(symbolP
, symbol_rootP
, &symbol_rootP
, &symbol_lastP
);
1972 symbol_rootP
= symbolP
;
1973 } /* if not first on the list */
1975 } /* c_dot_file_symbol() */
1978 * Build a 'section static' symbol.
1981 symbolS
*c_section_symbol(name
,idx
)
1987 symbolP
= symbol_new(name
,idx
,
1989 &zero_address_frag
);
1991 S_SET_STORAGE_CLASS(symbolP
, C_STAT
);
1992 S_SET_NUMBER_AUXILIARY(symbolP
, 1);
1994 SF_SET_STATICS(symbolP
);
1997 } /* c_section_symbol() */
2000 DEFUN(w_symbols
,(abfd
, where
, symbol_rootP
),
2003 symbolS
*symbol_rootP
)
2008 /* First fill in those values we have only just worked out */
2009 for (i
= SEG_E0
; i
< SEG_E9
; i
++)
2011 symbolP
= segment_info
[i
].dot
;
2015 SA_SET_SCN_SCNLEN(symbolP
, segment_info
[i
].scnhdr
.s_size
);
2016 SA_SET_SCN_NRELOC(symbolP
, segment_info
[i
].scnhdr
.s_nreloc
);
2017 SA_SET_SCN_NLINNO(symbolP
, segment_info
[i
].scnhdr
.s_nlnno
);
2023 * Emit all symbols left in the symbol chain.
2025 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next(symbolP
)) {
2026 /* Used to save the offset of the name. It is used to point
2027 to the string in memory but must be a file offset. */
2028 register char * temp
;
2030 tc_coff_symbol_emit_hook(symbolP
);
2032 temp
= S_GET_NAME(symbolP
);
2033 if (SF_GET_STRING(symbolP
)) {
2034 S_SET_OFFSET(symbolP
, symbolP
->sy_name_offset
);
2035 S_SET_ZEROES(symbolP
, 0);
2037 bzero(symbolP
->sy_symbol
.ost_entry
.n_name
, SYMNMLEN
);
2038 strncpy(symbolP
->sy_symbol
.ost_entry
.n_name
, temp
, SYMNMLEN
);
2040 where
= symbol_to_chars(abfd
, where
, symbolP
);
2041 S_SET_NAME(symbolP
,temp
);
2046 static void DEFUN_VOID(obj_coff_lcomm
)
2055 name
= input_line_pointer
;
2058 c
= get_symbol_end();
2059 p
= input_line_pointer
;
2062 if (*input_line_pointer
!= ',') {
2063 as_bad("Expected comma after name");
2064 ignore_rest_of_line();
2067 if (*input_line_pointer
== '\n') {
2068 as_bad("Missing size expression");
2071 input_line_pointer
++;
2072 if ((temp
= get_absolute_expression ()) < 0) {
2073 as_warn("lcomm length (%d.) <0! Ignored.", temp
);
2074 ignore_rest_of_line();
2080 /* Allocate zero static local data in the .data section now
2081 instead of the bss section as a symbol with a value */
2083 segT oldseg
= now_seg
;
2084 int oldsubseg
= now_subseg
;
2086 subseg_new(SEG_DATA
, 10);
2089 record_alignment(SEG_DATA
, 4);
2090 x
= frag_var (rs_fill
, 1, 1, (relax_substateT
)0, (symbolS
*)0,
2094 subseg_new(oldseg
, oldsubseg
);
2096 demand_empty_rest_of_line();
2099 static void DEFUN(fixup_mdeps
,(frags
),
2104 switch (frags
->fr_type
)
2108 frags
->fr_type
= rs_fill
;
2110 (frags
->fr_next
->fr_address
- frags
->fr_address
- frags
->fr_fix
);
2112 case rs_machine_dependent
:
2113 md_convert_frag(0, frags
);
2118 frags
= frags
->fr_next
;
2123 static void DEFUN(fixup_segment
,(fixP
, this_segment_type
),
2124 register fixS
* fixP AND
2125 segT this_segment_type
)
2127 register symbolS
*add_symbolP
;
2128 register symbolS
*sub_symbolP
;
2129 register long add_number
;
2131 register char *place
;
2132 register long where
;
2133 register char pcrel
;
2134 register fragS
*fragP
;
2135 register segT add_symbol_segment
= SEG_ABSOLUTE
;
2138 for ( ; fixP
; fixP
= fixP
->fx_next
)
2140 fragP
= fixP
->fx_frag
;
2142 where
= fixP
->fx_where
;
2143 place
= fragP
->fr_literal
+ where
;
2144 size
= fixP
->fx_size
;
2145 add_symbolP
= fixP
->fx_addsy
;
2147 if (fixP
->fx_callj
&& TC_S_IS_CALLNAME(add_symbolP
)) {
2148 /* Relocation should be done via the
2149 associated 'bal' entry point
2152 if (!TC_S_IS_BALNAME(tc_get_bal_of_call(add_symbolP
))) {
2153 as_bad("No 'bal' entry point for leafproc %s",
2154 S_GET_NAME(add_symbolP
));
2157 fixP
->fx_addsy
= add_symbolP
= tc_get_bal_of_call(add_symbolP
);
2158 } /* callj relocation */
2160 sub_symbolP
= fixP
->fx_subsy
;
2161 add_number
= fixP
->fx_offset
;
2162 pcrel
= fixP
->fx_pcrel
;
2165 add_symbol_segment
= S_GET_SEGMENT(add_symbolP
);
2166 } /* if there is an addend */
2171 if (S_GET_SEGMENT(sub_symbolP
) != SEG_ABSOLUTE
) {
2172 as_bad("Negative of non-absolute symbol %s", S_GET_NAME(sub_symbolP
));
2173 } /* not absolute */
2175 add_number
-= S_GET_VALUE(sub_symbolP
);
2178 /* if sub_symbol is in the same segment that add_symbol
2179 and add_symbol is either in DATA, TEXT, BSS or ABSOLUTE */
2180 } else if ((S_GET_SEGMENT(sub_symbolP
) == add_symbol_segment
)
2181 && (SEG_NORMAL(add_symbol_segment
)
2182 || (add_symbol_segment
== SEG_ABSOLUTE
))) {
2183 /* Difference of 2 symbols from same segment. */
2184 /* Can't make difference of 2 undefineds: 'value' means */
2185 /* something different for N_UNDF. */
2187 /* Makes no sense to use the difference of 2 arbitrary symbols
2188 * as the target of a call instruction.
2190 if (fixP
->fx_callj
) {
2191 as_bad("callj to difference of 2 symbols");
2193 #endif /* TC_I960 */
2194 add_number
+= S_GET_VALUE(add_symbolP
) -
2195 S_GET_VALUE(sub_symbolP
);
2198 fixP
->fx_addsy
= NULL
;
2200 /* Different segments in subtraction. */
2201 know(!(S_IS_EXTERNAL(sub_symbolP
) && (S_GET_SEGMENT(sub_symbolP
) == SEG_ABSOLUTE
)));
2203 if ((S_GET_SEGMENT(sub_symbolP
) == SEG_ABSOLUTE
)) {
2204 add_number
-= S_GET_VALUE(sub_symbolP
);
2206 as_bad("Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %d.",
2207 segment_name(S_GET_SEGMENT(sub_symbolP
)),
2208 S_GET_NAME(sub_symbolP
), fragP
->fr_address
+ where
);
2211 } /* if sub_symbolP */
2214 if (add_symbol_segment
== this_segment_type
&& pcrel
) {
2216 * This fixup was made when the symbol's segment was
2217 * SEG_UNKNOWN, but it is now in the local segment.
2218 * So we know how to do the address without relocation.
2221 /* reloc_callj() may replace a 'call' with a 'calls' or a 'bal',
2222 * in which cases it modifies *fixP as appropriate. In the case
2223 * of a 'calls', no further work is required, and *fixP has been
2224 * set up to make the rest of the code below a no-op.
2227 #endif /* TC_I960 */
2229 add_number
+= S_GET_VALUE(add_symbolP
);
2230 add_number
-= md_pcrel_from (fixP
);
2231 pcrel
= 0; /* Lie. Don't want further pcrel processing. */
2232 fixP
->fx_addsy
= NULL
; /* No relocations please. */
2235 switch (add_symbol_segment
)
2239 reloc_callj(fixP
); /* See comment about reloc_callj() above*/
2240 #endif /* TC_I960 */
2241 add_number
+= S_GET_VALUE(add_symbolP
);
2242 fixP
->fx_addsy
= NULL
;
2247 add_number
+= S_GET_VALUE(add_symbolP
) +
2248 segment_info
[S_GET_SEGMENT(add_symbolP
)].scnhdr
.s_paddr
;
2253 if ((int)fixP
->fx_bit_fixP
== 13) {
2254 /* This is a COBR instruction. They have only a
2255 * 13-bit displacement and are only to be used
2256 * for local branches: flag as error, don't generate
2259 as_bad("can't use COBR format with external label");
2260 fixP
->fx_addsy
= NULL
; /* No relocations please. */
2263 #endif /* TC_I960 */
2270 } /* switch on symbol seg */
2271 } /* if not in local seg */
2272 } /* if there was a + symbol */
2275 add_number
-= md_pcrel_from(fixP
);
2276 if (add_symbolP
== 0) {
2277 fixP
->fx_addsy
= & abs_symbol
;
2278 } /* if there's an add_symbol */
2281 if (!fixP
->fx_bit_fixP
) {
2283 (add_number
& ~0xFF) && ((add_number
&~0xFF)!=(-1&~0xFF))) ||
2285 (add_number
& ~0xFFFF) && ((add_number
&~0xFFFF)!=(-1&~0xFFFF)))) {
2286 as_bad("Value of %d too large for field of %d bytes at 0x%x",
2287 add_number
, size
, fragP
->fr_address
+ where
);
2288 } /* generic error checking */
2289 #ifdef WARN_SIGNED_OVERFLOW_WORD
2290 /* Warn if a .word value is too large when treated as
2291 a signed number. We already know it is not too
2292 negative. This is to catch over-large switches
2293 generated by gcc on the 68k. */
2296 && add_number
> 0x7fff)
2297 as_bad ("Signed .word overflow; switch may be too large; %d at 0x%x",
2298 add_number
, fragP
->fr_address
+ where
);
2300 } /* not a bit fix */
2301 /* once this fix has been applied, we don't have to output anything
2302 nothing more need be done -*/
2303 md_apply_fix(fixP
, add_number
);
2305 } /* For each fixS in this segment. */
2308 } /* fixup_segment() */