1 /* coff object file format with bfd
2 Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc.
4 This file is part of GAS.
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
22 How does this releate to the rest of GAS ?
24 Well, all the other files in gas are more or less a black box. It
25 takes care of opening files, parsing command lines, stripping blanks
26 etc etc. This module gets a chance to register what it wants to do by
27 saying that it is interested in various pseduo ops. The other big
28 change is write_object_file. This runs through all the data
29 structures that gas builds, and outputs the file in the format of our
32 Hacked for BFDness by steve chamberlain
34 This object module now supports the Hitachi H8/300 and the AMD 29k
43 #include "../bfd/libbfd.h"
46 /* This vector is used to turn an internal segment into a section #
47 suitable for insertion into a coff symbol table
50 const short seg_N_TYPE
[] = { /* in: segT out: N_TYPE bits */
62 C_UNDEF_SECTION
, /* SEG_UNKNOWN */
63 C_UNDEF_SECTION
, /* SEG_ABSENT */
64 C_UNDEF_SECTION
, /* SEG_PASS1 */
65 C_UNDEF_SECTION
, /* SEG_GOOF */
66 C_UNDEF_SECTION
, /* SEG_BIG */
67 C_UNDEF_SECTION
, /* SEG_DIFFERENCE */
68 C_DEBUG_SECTION
, /* SEG_DEBUG */
69 C_NTV_SECTION
, /* SEG_NTV */
70 C_PTV_SECTION
, /* SEG_PTV */
71 C_REGISTER_SECTION
, /* SEG_REGISTER */
75 int function_lineoff
= -1; /* Offset in line#s where the last function
76 started (the odd entry for line #0) */
78 int our_lineno_number
= 0; /* we use this to build pointers from .bf's
79 into the linetable. It should match
80 exactly the values that are later
81 assigned in text_lineno_number by
84 int text_lineno_number
= 0;
86 /* Add 4 to the real value to get the index and compensate the
87 negatives. This vector is used by S_GET_SEGMENT to turn a coff
88 section number into a segment number
90 static symbolS
*previous_file_symbol
= NULL
;
91 void c_symbol_merge();
93 symbolS
*c_section_symbol();
95 void EXFUN(bfd_as_write_hook
,(struct internal_filehdr
*,
98 static void EXFUN(fixup_segment
,(fixS
* fixP
,
99 segT this_segment_type
));
101 static void EXFUN(fill_section
,(bfd
*abfd
,
102 struct internal_filehdr
*f
, unsigned
106 char *EXFUN(s_get_name
,(symbolS
*s
));
107 static symbolS
*EXFUN(tag_find_or_make
,(char *name
));
108 static symbolS
* EXFUN(tag_find
,(char *name
));
115 unsigned short line_number
,
119 static void EXFUN(w_symbols
,
122 symbolS
*symbol_rootP
));
126 static void EXFUN( obj_coff_def
,(int what
));
127 static void EXFUN( obj_coff_lcomm
,(void));
128 static void EXFUN( obj_coff_dim
,(void));
129 static void EXFUN( obj_coff_text
,(void));
130 static void EXFUN( obj_coff_data
,(void));
131 static void EXFUN( obj_coff_endef
,(void));
132 static void EXFUN( obj_coff_line
,(void));
133 static void EXFUN( obj_coff_ln
,(void));
134 static void EXFUN( obj_coff_scl
,(void));
135 static void EXFUN( obj_coff_size
,(void));
136 static void EXFUN( obj_coff_tag
,(void));
137 static void EXFUN( obj_coff_type
,(void));
138 static void EXFUN( obj_coff_val
,(void));
139 static void EXFUN( obj_coff_section
,(void));
140 static void EXFUN( tag_init
,(void));
141 static void EXFUN( tag_insert
,(char *name
, symbolS
*symbolP
));
144 static struct hash_control
*tag_hash
;
145 static symbolS
*def_symbol_in_progress
= NULL
;
147 const pseudo_typeS obj_pseudo_table
[] = {
148 { "def", obj_coff_def
, 0 },
149 { "dim", obj_coff_dim
, 0 },
150 { "endef", obj_coff_endef
, 0 },
151 { "line", obj_coff_line
, 0 },
152 { "ln", obj_coff_ln
, 0 },
153 { "scl", obj_coff_scl
, 0 },
154 { "size", obj_coff_size
, 0 },
155 { "tag", obj_coff_tag
, 0 },
156 { "type", obj_coff_type
, 0 },
157 { "val", obj_coff_val
, 0 },
158 { "section", obj_coff_section
, 0 },
159 { "text", obj_coff_text
, 0 },
160 { "data", obj_coff_data
, 0 },
161 /* we don't yet handle this. */
162 { "ident", s_ignore
, 0 },
163 { "ABORT", s_abort
, 0 },
164 { "lcomm", obj_coff_lcomm
, 0},
165 { NULL
} /* end sentinel */
166 }; /* obj_pseudo_table */
172 We allow more than just the standard 3 sections, infact, we allow
173 10 sections, (though the usual three have to be there).
175 This structure performs the mappings for us:
180 static struct internal_scnhdr bss_section_header;
181 struct internal_scnhdr data_section_header;
182 struct internal_scnhdr text_section_header;
184 const segT N_TYPE_seg [32] =
198 seg_info_type seg_info_off_by_4
[N_SEG
] =
224 {SEG_REGISTER
},0,0,0,0};
226 #define SEG_INFO_FROM_SECTION_NUMBER(x) (seg_info_off_by_4[(x)+4])
227 #define SEG_INFO_FROM_SEG_NUMBER(x) (seg_info_off_by_4[(x)])
230 static relax_addressT
231 DEFUN(relax_align
,(address
, alignment
),
232 register relax_addressT address AND
233 register long alignment
)
236 relax_addressT new_address
;
238 mask
= ~ ( (~0) << alignment
);
239 new_address
= (address
+ mask
) & (~ mask
);
240 return (new_address
- address
);
241 } /* relax_align() */
245 DEFUN(s_get_segment
,(x
) ,
248 return SEG_INFO_FROM_SECTION_NUMBER(x
->sy_symbol
.ost_entry
.n_scnum
).seg_t
;
253 /* calculate the size of the frag chain and fill in the section header
254 to contain all of it, also fill in the addr of the sections */
255 static unsigned int DEFUN(size_section
,(abfd
, idx
),
260 unsigned int size
= 0;
261 fragS
*frag
= segment_info
[idx
].frchainP
->frch_root
;
263 if (frag
->fr_address
!= size
) {
264 printf("Out of step\n");
265 size
= frag
->fr_address
;
267 size
+= frag
->fr_fix
;
268 switch (frag
->fr_type
) {
271 size
+= frag
->fr_offset
* frag
->fr_var
;
274 size
+= relax_align(size
, frag
->fr_offset
);
276 frag
= frag
->fr_next
;
278 segment_info
[idx
].scnhdr
.s_size
= size
;
283 static unsigned int DEFUN(count_entries_in_chain
,(idx
),
286 unsigned int nrelocs
;
289 /* Count the relocations */
290 fixup_ptr
= segment_info
[idx
].fix_root
;
292 while (fixup_ptr
!= (fixS
*)NULL
)
294 if (TC_COUNT_RELOC(fixup_ptr
))
299 if (fixup_ptr
->fx_r_type
== RELOC_CONSTH
)
308 fixup_ptr
= fixup_ptr
->fx_next
;
313 /* output all the relocations for a section */
314 void DEFUN(do_relocs_for
,(abfd
, file_cursor
),
316 unsigned long *file_cursor
)
318 unsigned int nrelocs
;
321 for (idx
= SEG_E0
; idx
< SEG_E9
; idx
++)
323 if (segment_info
[idx
].scnhdr
.s_name
[0])
326 struct external_reloc
*ext_ptr
;
327 struct external_reloc
*external_reloc_vec
;
328 unsigned int external_reloc_size
;
329 unsigned int count
= 0;
330 unsigned int base
= segment_info
[idx
].scnhdr
.s_paddr
;
331 fixS
* fix_ptr
= segment_info
[idx
].fix_root
;
332 nrelocs
= count_entries_in_chain(idx
);
333 external_reloc_size
= nrelocs
* RELSZ
;
335 (struct external_reloc
*)malloc(external_reloc_size
);
339 ext_ptr
= external_reloc_vec
;
341 /* Fill in the internal coff style reloc struct from the
346 struct internal_reloc intr
;
348 /* Only output some of the relocations */
349 if (TC_COUNT_RELOC(fix_ptr
))
351 #ifdef TC_RELOC_MANGLE(fix_ptr, &intr)
352 TC_RELOC_MANGLE(fix_ptr
, &intr
);
356 symbol_ptr
= fix_ptr
->fx_addsy
;
358 intr
.r_type
= TC_COFF_FIX2RTYPE(fix_ptr
);
360 base
+ fix_ptr
->fx_frag
->fr_address
+ fix_ptr
->fx_where
;
362 intr
.r_offset
= fix_ptr
->fx_offset
;
366 /* Turn the segment of the symbol into an offset
370 dot
= segment_info
[S_GET_SEGMENT(symbol_ptr
)].dot
;
373 intr
.r_symndx
= dot
->sy_number
;
377 intr
.r_symndx
= symbol_ptr
->sy_number
;
389 (void)bfd_coff_swap_reloc_out(abfd
, &intr
, ext_ptr
);
393 /* The 29k has a special kludge for the high 16 bit reloc.
394 Two relocations are emmited, R_IHIHALF, and
395 R_IHCONST. The second one doesn't contain a symbol,
396 but uses the value for offset */
398 if (intr
.r_type
== R_IHIHALF
)
400 /* now emit the second bit */
401 intr
.r_type
= R_IHCONST
;
402 intr
.r_symndx
= fix_ptr
->fx_addnumber
;
403 (void)bfd_coff_swap_reloc_out(abfd
,&intr
,ext_ptr
);
409 fix_ptr
= fix_ptr
->fx_next
;
412 /* Write out the reloc table */
413 segment_info
[idx
].scnhdr
.s_relptr
= *file_cursor
;
414 segment_info
[idx
].scnhdr
.s_nreloc
= nrelocs
;
415 bfd_write((PTR
)external_reloc_vec
, 1, external_reloc_size
, abfd
);
416 *file_cursor
+= external_reloc_size
;
417 free( external_reloc_vec
);
423 /* run through a frag chain and write out the data to go with it, fill
424 in the scnhdrs with the info on the file postions
426 static void DEFUN(fill_section
,(abfd
, filehdr
, file_cursor
),
428 struct internal_filehdr
*filehdr AND
429 unsigned long *file_cursor
)
433 unsigned int paddr
= 0;
435 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
437 unsigned int offset
= 0;
439 struct internal_scnhdr
*s
= &( segment_info
[i
].scnhdr
);
443 fragS
*frag
= segment_info
[i
].frchainP
->frch_root
;
444 char *buffer
= malloc(s
->s_size
);
445 s
->s_scnptr
= *file_cursor
;
449 s
->s_flags
= STYP_REG
;
450 if (strcmp(s
->s_name
,".text")==0)
451 s
->s_flags
|= STYP_TEXT
;
452 else if (strcmp(s
->s_name
,".data")==0)
453 s
->s_flags
|= STYP_DATA
;
454 else if (strcmp(s
->s_name
,".bss")==0)
455 s
->s_flags
|= STYP_BSS
| STYP_NOLOAD
;
458 unsigned int fill_size
;
459 switch (frag
->fr_type
) {
466 memcpy(buffer
+ frag
->fr_address
,
469 offset
+= frag
->fr_fix
;
472 fill_size
= frag
->fr_var
;
476 unsigned int off
= frag
->fr_fix
;
477 for (count
= frag
->fr_offset
; count
; count
--)
479 memcpy(buffer
+ frag
->fr_address
+ off
,
480 frag
->fr_literal
+ frag
->fr_fix
,
492 frag
= frag
->fr_next
;
496 bfd_write(buffer
, s
->s_size
,1,abfd
);
499 *file_cursor
+= s
->s_size
;
508 /* Coff file generation & utilities */
512 DEFUN(coff_header_append
,(abfd
, filehdr
, aouthdr
),
514 struct internal_filehdr
*filehdr AND
515 struct internal_aouthdr
*aouthdr
)
521 bfd_seek(abfd
, 0, 0);
523 filehdr
.f_opthdr
= bfd_coff_swap_aouthdr_out(abfd
, aouthdr
,
526 filehdr
->f_opthdr
= 0;
528 i
= bfd_coff_swap_filehdr_out(abfd
, filehdr
, buffer
);
530 bfd_write(buffer
, i
,1, abfd
);
531 bfd_write(buffero
, filehdr
->f_opthdr
, 1, abfd
);
533 for (i
= SEG_E0
; i
< SEG_E9
; i
++)
535 if (segment_info
[i
].scnhdr
.s_name
[0])
538 bfd_coff_swap_scnhdr_out(abfd
,
539 &(segment_info
[i
].scnhdr
),
541 bfd_write(buffer
, size
, 1, abfd
);
548 DEFUN(symbol_to_chars
,(abfd
, where
, symbolP
),
553 unsigned int numaux
= symbolP
->sy_symbol
.ost_entry
.n_numaux
;
556 /* Turn any symbols with register attributes into abs symbols */
557 if (S_GET_SEGMENT(symbolP
) == SEG_REGISTER
)
559 S_SET_SEGMENT(symbolP
, SEG_ABSOLUTE
);
561 /* At the same time, relocate all symbols to their output value */
564 segment_info
[S_GET_SEGMENT(symbolP
)].scnhdr
.s_paddr
565 + S_GET_VALUE(symbolP
));
567 where
+= bfd_coff_swap_sym_out(abfd
, &symbolP
->sy_symbol
.ost_entry
,
570 for (i
= 0; i
< numaux
; i
++)
572 where
+= bfd_coff_swap_aux_out(abfd
,
573 &symbolP
->sy_symbol
.ost_auxent
[i
],
574 S_GET_DATA_TYPE(symbolP
),
575 S_GET_STORAGE_CLASS(symbolP
),
585 void obj_symbol_new_hook(symbolP
)
588 char underscore
= 0; /* Symbol has leading _ */
590 /* Effective symbol */
591 /* Store the pointer in the offset. */
592 S_SET_ZEROES(symbolP
, 0L);
593 S_SET_DATA_TYPE(symbolP
, T_NULL
);
594 S_SET_STORAGE_CLASS(symbolP
, 0);
595 S_SET_NUMBER_AUXILIARY(symbolP
, 0);
596 /* Additional information */
597 symbolP
->sy_symbol
.ost_flags
= 0;
598 /* Auxiliary entries */
599 bzero((char*)&symbolP
->sy_symbol
.ost_auxent
[0], AUXESZ
);
601 #ifdef STRIP_UNDERSCORE
602 /* Remove leading underscore at the beginning of the symbol.
603 * This is to be compatible with the standard librairies.
605 if (*S_GET_NAME(symbolP
) == '_') {
607 S_SET_NAME(symbolP
, S_GET_NAME(symbolP
) + 1);
608 } /* strip underscore */
609 #endif /* STRIP_UNDERSCORE */
611 if (S_IS_STRING(symbolP
))
612 SF_SET_STRING(symbolP
);
613 if (!underscore
&& S_IS_LOCAL(symbolP
))
614 SF_SET_LOCAL(symbolP
);
617 } /* obj_symbol_new_hook() */
620 stack
* stack_init(chunk_size
, element_size
)
621 unsigned long chunk_size
;
622 unsigned long element_size
;
626 if ((st
= (stack
*)malloc(sizeof(stack
))) == (stack
*)0)
628 if ((st
->data
= malloc(chunk_size
)) == (char*)0) {
633 st
->size
= chunk_size
;
634 st
->chunk_size
= chunk_size
;
635 st
->element_size
= element_size
;
639 void stack_delete(st
)
646 char *stack_push(st
, element
)
650 if (st
->pointer
+ st
->element_size
>= st
->size
) {
651 st
->size
+= st
->chunk_size
;
652 if ((st
->data
= xrealloc(st
->data
, st
->size
)) == (char*)0)
655 memcpy(st
->data
+ st
->pointer
, element
, st
->element_size
);
656 st
->pointer
+= st
->element_size
;
657 return st
->data
+ st
->pointer
;
663 if ((st
->pointer
-= st
->element_size
) < 0) {
668 return st
->data
+ st
->pointer
;
674 return st
->data
+ st
->pointer
- st
->element_size
;
679 * Handle .ln directives.
682 static void obj_coff_ln() {
683 if (def_symbol_in_progress
!= NULL
) {
684 as_warn(".ln pseudo-op inside .def/.endef: ignored.");
685 demand_empty_rest_of_line();
687 } /* wrong context */
690 obstack_next_free(&frags
) - frag_now
->fr_literal
,
691 get_absolute_expression(),
694 demand_empty_rest_of_line();
696 } /* obj_coff_line() */
701 * Handle .def directives.
703 * One might ask : why can't we symbol_new if the symbol does not
704 * already exist and fill it with debug information. Because of
705 * the C_EFCN special symbol. It would clobber the value of the
706 * function symbol before we have a chance to notice that it is
707 * a C_EFCN. And a second reason is that the code is more clear this
708 * way. (at least I think it is :-).
712 #define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';')
713 #define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \
714 *input_line_pointer == '\t') \
715 input_line_pointer++;
718 DEFUN(obj_coff_def
,(what
),
721 char name_end
; /* Char after the end of name */
722 char *symbol_name
; /* Name of the debug symbol */
723 char *symbol_name_copy
; /* Temporary copy of the name */
724 unsigned int symbol_name_length
;
725 /*$char* directiveP;$ */ /* Name of the pseudo opcode */
726 /*$char directive[MAX_DIRECTIVE];$ */ /* Backup of the directive */
727 /*$char end = 0;$ */ /* If 1, stop parsing */
729 if (def_symbol_in_progress
!= NULL
) {
730 as_warn(".def pseudo-op used inside of .def/.endef: ignored.");
731 demand_empty_rest_of_line();
733 } /* if not inside .def/.endef */
737 def_symbol_in_progress
= (symbolS
*) obstack_alloc(¬es
, sizeof(*def_symbol_in_progress
));
738 bzero(def_symbol_in_progress
, sizeof(*def_symbol_in_progress
));
740 symbol_name
= input_line_pointer
;
741 name_end
= get_symbol_end();
742 symbol_name_length
= strlen(symbol_name
);
743 symbol_name_copy
= xmalloc(symbol_name_length
+ 1);
744 strcpy(symbol_name_copy
, symbol_name
);
746 /* Initialize the new symbol */
747 #ifdef STRIP_UNDERSCORE
748 S_SET_NAME(def_symbol_in_progress
, (*symbol_name_copy
== '_'
749 ? symbol_name_copy
+ 1
750 : symbol_name_copy
));
751 #else /* STRIP_UNDERSCORE */
752 S_SET_NAME(def_symbol_in_progress
, symbol_name_copy
);
753 #endif /* STRIP_UNDERSCORE */
754 /* free(symbol_name_copy); */
755 def_symbol_in_progress
->sy_name_offset
= ~0;
756 def_symbol_in_progress
->sy_number
= ~0;
757 def_symbol_in_progress
->sy_frag
= &zero_address_frag
;
759 if (S_IS_STRING(def_symbol_in_progress
)) {
760 SF_SET_STRING(def_symbol_in_progress
);
763 *input_line_pointer
= name_end
;
765 demand_empty_rest_of_line();
767 } /* obj_coff_def() */
769 unsigned int dim_index
;
771 DEFUN_VOID(obj_coff_endef
)
773 symbolS
*symbolP
= 0;
774 /* DIM BUG FIX sac@cygnus.com */
776 if (def_symbol_in_progress
== NULL
) {
777 as_warn(".endef pseudo-op used outside of .def/.endef: ignored.");
778 demand_empty_rest_of_line();
780 } /* if not inside .def/.endef */
782 /* Set the section number according to storage class. */
783 switch (S_GET_STORAGE_CLASS(def_symbol_in_progress
)) {
787 SF_SET_TAG(def_symbol_in_progress
);
788 /* intentional fallthrough */
791 SF_SET_DEBUG(def_symbol_in_progress
);
792 S_SET_SEGMENT(def_symbol_in_progress
, SEG_DEBUG
);
796 SF_SET_LOCAL(def_symbol_in_progress
); /* Do not emit this symbol. */
797 /* intentional fallthrough */
799 SF_SET_PROCESS(def_symbol_in_progress
); /* Will need processing before writing */
800 /* intentional fallthrough */
802 S_SET_SEGMENT(def_symbol_in_progress
, SEG_E0
);
804 if (def_symbol_in_progress
->sy_symbol
.ost_entry
.n_name
[1] == 'b') { /* .bf */
805 if (function_lineoff
< 0) {
806 fprintf(stderr
, "`.bf' symbol without preceding function\n");
807 } /* missing function symbol */
808 SA_GET_SYM_LNNOPTR(def_symbol_in_progress
) = function_lineoff
;
809 SF_SET_PROCESS(def_symbol_in_progress
); /* Will need relocating */
810 function_lineoff
= -1;
816 #endif /* C_AUTOARG */
826 SF_SET_DEBUG(def_symbol_in_progress
);
827 S_SET_SEGMENT(def_symbol_in_progress
, SEG_ABSOLUTE
);
833 /* Valid but set somewhere else (s_comm, s_lcomm, colon) */
839 as_warn("unexpected storage class %d", S_GET_STORAGE_CLASS(def_symbol_in_progress
));
841 } /* switch on storage class */
843 /* Now that we have built a debug symbol, try to
844 find if we should merge with an existing symbol
845 or not. If a symbol is C_EFCN or SEG_ABSOLUTE or
846 untagged SEG_DEBUG it never merges. */
848 /* Two cases for functions. Either debug followed
849 by definition or definition followed by debug.
850 For definition first, we will merge the debug
851 symbol into the definition. For debug first, the
852 lineno entry MUST point to the definition
853 function or else it will point off into space
854 when crawl_symbols() merges the debug
855 symbol into the real symbol. Therefor, let's
856 presume the debug symbol is a real function
859 /* FIXME-SOON If for some reason the definition
860 label/symbol is never seen, this will probably
861 leave an undefined symbol at link time. */
863 if (S_GET_STORAGE_CLASS(def_symbol_in_progress
) == C_EFCN
864 || (S_GET_SEGMENT(def_symbol_in_progress
) == SEG_DEBUG
865 && !SF_GET_TAG(def_symbol_in_progress
))
866 || S_GET_SEGMENT(def_symbol_in_progress
) == SEG_ABSOLUTE
867 || (symbolP
= symbol_find_base(S_GET_NAME(def_symbol_in_progress
), DO_NOT_STRIP
)) == NULL
) {
869 symbol_append(def_symbol_in_progress
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
872 /* This symbol already exists, merge the
873 newly created symbol into the old one.
874 This is not mandatory. The linker can
875 handle duplicate symbols correctly. But I
876 guess that it save a *lot* of space if
877 the assembly file defines a lot of
880 /* The debug entry (def_symbol_in_progress)
881 is merged into the previous definition. */
883 c_symbol_merge(def_symbol_in_progress
, symbolP
);
884 /* FIXME-SOON Should *def_symbol_in_progress be free'd? xoxorich. */
885 def_symbol_in_progress
= symbolP
;
887 if (SF_GET_FUNCTION(def_symbol_in_progress
)
888 || SF_GET_TAG(def_symbol_in_progress
)) {
889 /* For functions, and tags, the symbol *must* be where the debug symbol
890 appears. Move the existing symbol to the current place. */
891 /* If it already is at the end of the symbol list, do nothing */
892 if (def_symbol_in_progress
!= symbol_lastP
) {
893 symbol_remove(def_symbol_in_progress
, &symbol_rootP
, &symbol_lastP
);
894 symbol_append(def_symbol_in_progress
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
895 } /* if not already in place */
897 } /* normal or mergable */
899 if (SF_GET_TAG(def_symbol_in_progress
)
900 && symbol_find_base(S_GET_NAME(def_symbol_in_progress
), DO_NOT_STRIP
) == NULL
) {
901 tag_insert(S_GET_NAME(def_symbol_in_progress
), def_symbol_in_progress
);
902 } /* If symbol is a {structure,union} tag, associate symbol to its name. */
904 if (SF_GET_FUNCTION(def_symbol_in_progress
)) {
905 know(sizeof(def_symbol_in_progress
) <= sizeof(long));
908 def_symbol_in_progress
,0, 0, &zero_address_frag
);
912 SF_SET_PROCESS(def_symbol_in_progress
);
914 if (symbolP
== NULL
) {
915 /* That is, if this is the first
916 time we've seen the function... */
917 symbol_table_insert(def_symbol_in_progress
);
918 } /* definition follows debug */
919 } /* Create the line number entry pointing to the function being defined */
921 def_symbol_in_progress
= NULL
;
922 demand_empty_rest_of_line();
924 } /* obj_coff_endef() */
927 DEFUN_VOID(obj_coff_dim
)
929 register int dim_index
;
931 if (def_symbol_in_progress
== NULL
)
933 as_warn(".dim pseudo-op used outside of .def/.endef: ignored.");
934 demand_empty_rest_of_line();
936 } /* if not inside .def/.endef */
938 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
940 for (dim_index
= 0; dim_index
< DIMNUM
; dim_index
++)
943 SA_SET_SYM_DIMEN(def_symbol_in_progress
, dim_index
, get_absolute_expression());
945 switch (*input_line_pointer
)
949 input_line_pointer
++;
953 as_warn("badly formed .dim directive ignored");
954 /* intentional fallthrough */
959 } /* switch on following character */
960 } /* for each dimension */
962 demand_empty_rest_of_line();
964 } /* obj_coff_dim() */
966 static void obj_coff_line() {
967 if (def_symbol_in_progress
== NULL
) {
970 } /* if it looks like a stabs style line */
972 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
973 SA_SET_SYM_LNNO(def_symbol_in_progress
, get_absolute_expression());
975 demand_empty_rest_of_line();
977 } /* obj_coff_line() */
979 static void obj_coff_size() {
980 if (def_symbol_in_progress
== NULL
) {
981 as_warn(".size pseudo-op used outside of .def/.endef ignored.");
982 demand_empty_rest_of_line();
984 } /* if not inside .def/.endef */
986 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
987 SA_SET_SYM_SIZE(def_symbol_in_progress
, get_absolute_expression());
988 demand_empty_rest_of_line();
990 } /* obj_coff_size() */
992 static void obj_coff_scl() {
993 if (def_symbol_in_progress
== NULL
) {
994 as_warn(".scl pseudo-op used outside of .def/.endef ignored.");
995 demand_empty_rest_of_line();
997 } /* if not inside .def/.endef */
999 S_SET_STORAGE_CLASS(def_symbol_in_progress
, get_absolute_expression());
1000 demand_empty_rest_of_line();
1002 } /* obj_coff_scl() */
1004 static void obj_coff_tag() {
1008 if (def_symbol_in_progress
== NULL
) {
1009 as_warn(".tag pseudo-op used outside of .def/.endef ignored.");
1010 demand_empty_rest_of_line();
1012 } /* if not inside .def/.endef */
1014 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1015 symbol_name
= input_line_pointer
;
1016 name_end
= get_symbol_end();
1018 /* Assume that the symbol referred to by .tag is always defined. */
1019 /* This was a bad assumption. I've added find_or_make. xoxorich. */
1020 SA_SET_SYM_TAGNDX(def_symbol_in_progress
, (long) tag_find_or_make(symbol_name
));
1021 if (SA_GET_SYM_TAGNDX(def_symbol_in_progress
) == 0L) {
1022 as_warn("tag not found for .tag %s", symbol_name
);
1025 SF_SET_TAGGED(def_symbol_in_progress
);
1026 *input_line_pointer
= name_end
;
1028 demand_empty_rest_of_line();
1030 } /* obj_coff_tag() */
1032 static void obj_coff_type() {
1033 if (def_symbol_in_progress
== NULL
) {
1034 as_warn(".type pseudo-op used outside of .def/.endef ignored.");
1035 demand_empty_rest_of_line();
1037 } /* if not inside .def/.endef */
1039 S_SET_DATA_TYPE(def_symbol_in_progress
, get_absolute_expression());
1041 if (ISFCN(S_GET_DATA_TYPE(def_symbol_in_progress
)) &&
1042 S_GET_STORAGE_CLASS(def_symbol_in_progress
) != C_TPDEF
) {
1043 SF_SET_FUNCTION(def_symbol_in_progress
);
1044 } /* is a function */
1046 demand_empty_rest_of_line();
1048 } /* obj_coff_type() */
1050 static void obj_coff_val() {
1051 if (def_symbol_in_progress
== NULL
) {
1052 as_warn(".val pseudo-op used outside of .def/.endef ignored.");
1053 demand_empty_rest_of_line();
1055 } /* if not inside .def/.endef */
1057 if (is_name_beginner(*input_line_pointer
)) {
1058 char *symbol_name
= input_line_pointer
;
1059 char name_end
= get_symbol_end();
1061 if (!strcmp(symbol_name
, ".")) {
1062 def_symbol_in_progress
->sy_frag
= frag_now
;
1063 S_SET_VALUE(def_symbol_in_progress
, obstack_next_free(&frags
) - frag_now
->fr_literal
);
1064 /* If the .val is != from the .def (e.g. statics) */
1065 } else if (strcmp(S_GET_NAME(def_symbol_in_progress
), symbol_name
)) {
1066 def_symbol_in_progress
->sy_forward
= symbol_find_or_make(symbol_name
);
1068 /* If the segment is undefined when the forward
1069 reference is solved, then copy the segment id
1070 from the forward symbol. */
1071 SF_SET_GET_SEGMENT(def_symbol_in_progress
);
1073 /* Otherwise, it is the name of a non debug symbol and its value will be calculated later. */
1074 *input_line_pointer
= name_end
;
1076 S_SET_VALUE(def_symbol_in_progress
, get_absolute_expression());
1077 } /* if symbol based */
1079 demand_empty_rest_of_line();
1081 } /* obj_coff_val() */
1084 * Maintain a list of the tagnames of the structres.
1087 static void tag_init() {
1088 tag_hash
= hash_new();
1092 static void tag_insert(name
, symbolP
)
1096 register char * error_string
;
1098 if (*(error_string
= hash_jam(tag_hash
, name
, (char *)symbolP
))) {
1099 as_fatal("Inserting \"%s\" into structure table failed: %s",
1100 name
, error_string
);
1103 } /* tag_insert() */
1105 static symbolS
*tag_find_or_make(name
)
1110 if ((symbolP
= tag_find(name
)) == NULL
) {
1111 symbolP
= symbol_new(name
,
1114 &zero_address_frag
);
1116 tag_insert(S_GET_NAME(symbolP
), symbolP
);
1117 symbol_table_insert(symbolP
);
1121 } /* tag_find_or_make() */
1123 static symbolS
*tag_find(name
)
1126 #ifdef STRIP_UNDERSCORE
1127 if (*name
== '_') name
++;
1128 #endif /* STRIP_UNDERSCORE */
1129 return((symbolS
*)hash_find(tag_hash
, name
));
1132 void obj_read_begin_hook() {
1133 /* These had better be the same. Usually 18 bytes. */
1135 know(sizeof(SYMENT
) == sizeof(AUXENT
));
1136 know(SYMESZ
== AUXESZ
);
1141 } /* obj_read_begin_hook() */
1143 /* This function runs through the symbol table and puts all the
1144 externals onto another chain */
1146 /* The chain of externals */
1147 symbolS
*symbol_externP
= NULL
;
1148 symbolS
*symbol_extern_lastP
= NULL
;
1151 symbolS
*last_functionP
= NULL
;
1155 static unsigned int DEFUN_VOID(yank_symbols
)
1158 unsigned int symbol_number
=0;
1160 for (symbolP
= symbol_rootP
;
1162 symbolP
= symbolP
? symbol_next(symbolP
) : symbol_rootP
) {
1163 if (!SF_GET_DEBUG(symbolP
)) {
1164 /* Debug symbols do not need all this rubbish */
1165 symbolS
* real_symbolP
;
1167 /* L* and C_EFCN symbols never merge. */
1168 if (!SF_GET_LOCAL(symbolP
)
1169 && (real_symbolP
= symbol_find_base(S_GET_NAME(symbolP
), DO_NOT_STRIP
))
1170 && real_symbolP
!= symbolP
) {
1171 /* FIXME-SOON: where do dups come from?
1172 Maybe tag references before definitions? xoxorich. */
1173 /* Move the debug data from the debug symbol to the
1174 real symbol. Do NOT do the oposite (i.e. move from
1175 real symbol to debug symbol and remove real symbol from the
1176 list.) Because some pointers refer to the real symbol
1177 whereas no pointers refer to the debug symbol. */
1178 c_symbol_merge(symbolP
, real_symbolP
);
1179 /* Replace the current symbol by the real one */
1180 /* The symbols will never be the last or the first
1181 because : 1st symbol is .file and 3 last symbols are
1182 .text, .data, .bss */
1183 symbol_remove(real_symbolP
, &symbol_rootP
, &symbol_lastP
);
1184 symbol_insert(real_symbolP
, symbolP
, &symbol_rootP
, &symbol_lastP
);
1185 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1186 symbolP
= real_symbolP
;
1187 } /* if not local but dup'd */
1189 if (flagseen
['R'] && (S_GET_SEGMENT(symbolP
) == SEG_E1
)) {
1190 S_SET_SEGMENT(symbolP
, SEG_E0
);
1191 } /* push data into text */
1193 S_SET_VALUE(symbolP
,
1194 S_GET_VALUE(symbolP
) + symbolP
->sy_frag
->fr_address
);
1196 if (!S_IS_DEFINED(symbolP
) && !SF_GET_LOCAL(symbolP
))
1198 S_SET_EXTERNAL(symbolP
);
1200 else if (S_GET_STORAGE_CLASS(symbolP
) == C_NULL
)
1202 if (S_GET_SEGMENT(symbolP
) == SEG_E0
)
1204 S_SET_STORAGE_CLASS(symbolP
, C_LABEL
);
1208 S_SET_STORAGE_CLASS(symbolP
, C_STAT
);
1212 /* Mainly to speed up if not -g */
1213 if (SF_GET_PROCESS(symbolP
))
1215 /* Handle the nested blocks auxiliary info. */
1216 if (S_GET_STORAGE_CLASS(symbolP
) == C_BLOCK
) {
1217 if (!strcmp(S_GET_NAME(symbolP
), ".bb"))
1218 stack_push(block_stack
, (char *) &symbolP
);
1220 register symbolS
* begin_symbolP
;
1221 begin_symbolP
= *(symbolS
**)stack_pop(block_stack
);
1222 if (begin_symbolP
== (symbolS
*)0)
1223 as_warn("mismatched .eb");
1225 SA_SET_SYM_ENDNDX(begin_symbolP
, symbol_number
+2);
1228 /* If we are able to identify the type of a function, and we
1229 are out of a function (last_functionP == 0) then, the
1230 function symbol will be associated with an auxiliary
1232 if (last_functionP
== (symbolS
*)0 &&
1233 SF_GET_FUNCTION(symbolP
)) {
1234 last_functionP
= symbolP
;
1236 if (S_GET_NUMBER_AUXILIARY(symbolP
) < 1) {
1237 S_SET_NUMBER_AUXILIARY(symbolP
, 1);
1238 } /* make it at least 1 */
1240 /* Clobber possible stale .dim information. */
1241 bzero(symbolP
->sy_symbol
.ost_auxent
[0].x_sym
.x_fcnary
.x_ary
.x_dimen
,
1242 sizeof(symbolP
->sy_symbol
.ost_auxent
[0].x_sym
.x_fcnary
.x_ary
.x_dimen
));
1244 /* The C_FCN doesn't need any additional information.
1245 I don't even know if this is needed for sdb. But the
1246 standard assembler generates it, so...
1248 if (S_GET_STORAGE_CLASS(symbolP
) == C_EFCN
) {
1249 if (last_functionP
== (symbolS
*)0)
1250 as_fatal("C_EFCN symbol out of scope");
1251 SA_SET_SYM_FSIZE(last_functionP
,
1252 (long)(S_GET_VALUE(symbolP
) -
1253 S_GET_VALUE(last_functionP
)));
1254 SA_SET_SYM_ENDNDX(last_functionP
, symbol_number
);
1255 last_functionP
= (symbolS
*)0;
1258 } else if (SF_GET_TAG(symbolP
)) {
1259 /* First descriptor of a structure must point to
1260 the first slot after the structure description. */
1261 last_tagP
= symbolP
;
1263 } else if (S_GET_STORAGE_CLASS(symbolP
) == C_EOS
) {
1264 /* +2 take in account the current symbol */
1265 SA_SET_SYM_ENDNDX(last_tagP
, symbol_number
+ 2);
1266 } else if (S_GET_STORAGE_CLASS(symbolP
) == C_FILE
) {
1267 if (S_GET_VALUE(symbolP
)) {
1268 S_SET_VALUE((symbolS
*) S_GET_VALUE(symbolP
), symbol_number
);
1269 S_SET_VALUE(symbolP
, 0);
1270 } /* no one points at the first .file symbol */
1271 } /* if debug or tag or eos or file */
1273 /* We must put the external symbols apart. The loader
1274 does not bomb if we do not. But the references in
1275 the endndx field for a .bb symbol are not corrected
1276 if an external symbol is removed between .bb and .be.
1277 I.e in the following case :
1278 [20] .bb endndx = 22
1281 ld will move the symbol 21 to the end of the list but
1282 endndx will still be 22 instead of 21. */
1285 if (SF_GET_LOCAL(symbolP
)) {
1286 /* remove C_EFCN and LOCAL (L...) symbols */
1287 /* next pointer remains valid */
1288 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1291 else if (!S_IS_DEFINED(symbolP
)
1292 && !S_IS_DEBUG(symbolP
)
1293 && !SF_GET_STATICS(symbolP
) &&
1294 S_GET_STORAGE_CLASS(symbolP
) == C_EXT
)
1295 { /* C_EXT && !SF_GET_FUNCTION(symbolP)) */
1296 /* if external, Remove from the list */
1297 symbolS
*hold
= symbol_previous(symbolP
);
1299 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1300 symbol_clear_list_pointers(symbolP
);
1301 symbol_append(symbolP
, symbol_extern_lastP
, &symbol_externP
, &symbol_extern_lastP
);
1304 if (SF_GET_STRING(symbolP
)) {
1305 symbolP
->sy_name_offset
= string_byte_count
;
1306 string_byte_count
+= strlen(S_GET_NAME(symbolP
)) + 1;
1308 symbolP
->sy_name_offset
= 0;
1309 } /* fix "long" names */
1311 symbolP
->sy_number
= symbol_number
;
1312 symbol_number
+= 1 + S_GET_NUMBER_AUXILIARY(symbolP
);
1313 } /* if local symbol */
1314 } /* traverse the symbol list */
1315 return symbol_number
;
1320 static unsigned int DEFUN_VOID(glue_symbols
)
1322 unsigned int symbol_number
= 0;
1324 for (symbolP
= symbol_externP
; symbol_externP
;) {
1325 symbolS
*tmp
= symbol_externP
;
1328 symbol_remove(tmp
, &symbol_externP
, &symbol_extern_lastP
);
1329 symbol_append(tmp
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
1332 if (SF_GET_STRING(tmp
)) {
1333 tmp
->sy_name_offset
= string_byte_count
;
1334 string_byte_count
+= strlen(S_GET_NAME(tmp
)) + 1;
1336 tmp
->sy_name_offset
= 0;
1337 } /* fix "long" names */
1339 tmp
->sy_number
= symbol_number
;
1340 symbol_number
+= 1 + S_GET_NUMBER_AUXILIARY(tmp
);
1341 } /* append the entire extern chain */
1342 return symbol_number
;
1346 static unsigned int DEFUN_VOID(tie_tags
)
1348 unsigned int symbol_number
= 0;
1351 for (symbolP
= symbol_rootP
; symbolP
; symbolP
=
1352 symbol_next(symbolP
))
1354 symbolP
->sy_number
= symbol_number
;
1358 if (SF_GET_TAGGED(symbolP
))
1362 ((symbolS
*) SA_GET_SYM_TAGNDX(symbolP
))->sy_number
);
1365 symbol_number
+= 1 + S_GET_NUMBER_AUXILIARY(symbolP
);
1367 return symbol_number
;
1372 DEFUN(crawl_symbols
,(headers
, abfd
),
1373 struct internal_filehdr
*headers AND
1378 unsigned int ptr
= 0;
1383 /* Initialize the stack used to keep track of the matching .bb .be */
1385 block_stack
= stack_init(512, sizeof(symbolS
*));
1386 /* JF deal with forward references first... */
1387 for (symbolP
= symbol_rootP
;
1389 symbolP
= symbol_next(symbolP
))
1392 if (symbolP
->sy_forward
) {
1393 S_SET_VALUE(symbolP
, (S_GET_VALUE(symbolP
)
1394 + S_GET_VALUE(symbolP
->sy_forward
)
1395 + symbolP
->sy_forward
->sy_frag
->fr_address
));
1397 if (SF_GET_GET_SEGMENT(symbolP
)) {
1398 S_SET_SEGMENT(symbolP
, S_GET_SEGMENT(symbolP
->sy_forward
));
1399 } /* forward segment also */
1401 symbolP
->sy_forward
=0;
1402 } /* if it has a forward reference */
1403 } /* walk the symbol chain */
1406 /* The symbol list should be ordered according to the following sequence
1409 * . debug entries for functions
1410 * . fake symbols for the sections, including.text .data and .bss
1412 * . undefined symbols
1413 * But this is not mandatory. The only important point is to put the
1414 * undefined symbols at the end of the list.
1417 if (symbol_rootP
== NULL
1418 || S_GET_STORAGE_CLASS(symbol_rootP
) != C_FILE
) {
1419 c_dot_file_symbol("fake");
1421 /* Is there a .file symbol ? If not insert one at the beginning. */
1424 * Build up static symbols for the sections, they are filled in later
1428 for (i
= SEG_E0
; i
< SEG_E9
; i
++)
1430 if (segment_info
[i
].scnhdr
.s_name
[0])
1432 segment_info
[i
].dot
=
1433 c_section_symbol(segment_info
[i
].scnhdr
.s_name
,
1440 /* Take all the externals out and put them into another chain */
1441 headers
->f_nsyms
= yank_symbols();
1442 /* Take the externals and glue them onto the end.*/
1443 headers
->f_nsyms
+= glue_symbols();
1445 headers
->f_nsyms
= tie_tags();
1446 know(symbol_externP
== NULL
);
1447 know(symbol_extern_lastP
== NULL
);
1453 * Find strings by crawling along symbol table chain.
1456 void DEFUN(w_strings
,(where
),
1461 /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
1462 md_number_to_chars(where
, string_byte_count
, sizeof(string_byte_count
));
1463 where
+= sizeof(string_byte_count
);
1464 for (symbolP
= symbol_rootP
;
1466 symbolP
= symbol_next(symbolP
))
1470 if (SF_GET_STRING(symbolP
)) {
1471 size
= strlen(S_GET_NAME(symbolP
)) + 1;
1473 memcpy(where
, S_GET_NAME(symbolP
),size
);
1486 DEFUN(do_linenos_for
,(abfd
, file_cursor
),
1488 unsigned long *file_cursor
)
1492 for (idx
= SEG_E0
; idx
< SEG_E9
; idx
++)
1494 segment_info_type
*s
= segment_info
+ idx
;
1496 if (s
->scnhdr
.s_nlnno
!= 0)
1498 struct lineno_list
*line_ptr
;
1500 struct external_lineno
*buffer
=
1501 (struct external_lineno
*)xmalloc(s
->scnhdr
.s_nlnno
* LINESZ
);
1503 struct external_lineno
*dst
= buffer
;
1505 /* Run through the table we've built and turn it into its external
1508 for (line_ptr
= s
->lineno_list_head
;
1509 line_ptr
!= (struct lineno_list
*)NULL
;
1510 line_ptr
= line_ptr
->next
)
1512 if (line_ptr
->line
.l_lnno
== 0)
1514 /* Turn a pointer to a symbol into the symbols' index */
1515 line_ptr
->line
.l_addr
.l_symndx
=
1516 ( (symbolS
*)line_ptr
->line
.l_addr
.l_symndx
)->sy_number
;
1518 (void) bfd_coff_swap_lineno_out(abfd
, &(line_ptr
->line
), dst
);
1522 s
->scnhdr
.s_lnnoptr
= *file_cursor
;
1524 bfd_write(buffer
, 1, s
->scnhdr
.s_nlnno
* LINESZ
, abfd
);
1527 *file_cursor
+= s
->scnhdr
.s_nlnno
* LINESZ
;
1533 /* Now we run through the list of frag chains in a segment and
1534 make all the subsegment frags appear at the end of the
1535 list, as if the seg 0 was extra long */
1537 static void DEFUN_VOID(remove_subsegs
)
1541 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1543 frchainS
*head
= segment_info
[i
].frchainP
;
1545 fragS
* prev_frag
= &dummy
;
1547 while (head
&& head
->frch_seg
== i
)
1549 prev_frag
->fr_next
= head
->frch_root
;
1550 prev_frag
= head
->frch_last
;
1551 head
= head
->frch_next
;
1553 prev_frag
->fr_next
= 0;
1558 extern void DEFUN_VOID(write_object_file
)
1561 struct frchain
*frchain_ptr
;
1563 struct internal_filehdr filehdr
;
1564 struct internal_aouthdr aouthdr
;
1565 unsigned long file_cursor
;
1567 unsigned int addr
= 0;
1568 abfd
= bfd_openw(out_file_name
, TARGET_FORMAT
);
1572 as_perror ("FATAL: Can't create %s", out_file_name
);
1575 bfd_set_format(abfd
, bfd_object
);
1576 bfd_set_arch_mach(abfd
, BFD_ARCH
, 0);
1580 string_byte_count
= 4;
1582 for (frchain_ptr
= frchain_root
;
1583 frchain_ptr
!= (struct frchain
*)NULL
;
1584 frchain_ptr
= frchain_ptr
->frch_next
) {
1585 /* Run through all the sub-segments and align them up. Also close any
1586 open frags. We tack a .fill onto the end of the frag chain so
1587 that any .align's size can be worked by looking at the next
1590 subseg_new(frchain_ptr
->frch_seg
, frchain_ptr
->frch_subseg
);
1591 #define SUB_SEGMENT_ALIGN 1
1592 frag_align(SUB_SEGMENT_ALIGN
,0);
1593 frag_wane(frag_now
);
1594 frag_now
->fr_fix
= 0;
1595 know( frag_now
->fr_next
== NULL
);
1602 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1604 relax_segment(segment_info
[i
].frchainP
->frch_root
, i
);
1611 filehdr
.f_nscns
= 0;
1613 /* Find out how big the sections are */
1614 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1617 if (segment_info
[i
].scnhdr
.s_name
[0])
1621 segment_info
[i
].scnhdr
.s_paddr
= addr
;
1623 /* THis is a special case, we leave the size alone, which will have */
1624 /* been made up from all and any lcomms seen */
1627 addr
+= size_section(abfd
, i
);
1633 /* Turn the gas native symbol table shape into a coff symbol table */
1634 crawl_symbols(&filehdr
, abfd
);
1636 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1638 fixup_segment(segment_info
[i
].fix_root
, i
);
1642 file_cursor
= FILHSZ
+ SCNHSZ
* filehdr
.f_nscns
;
1644 bfd_seek(abfd
, file_cursor
, 0);
1647 do_relocs_for(abfd
, &file_cursor
);
1649 do_linenos_for(abfd
, &file_cursor
);
1652 /* Plant the data */
1654 fill_section(abfd
,&filehdr
, &file_cursor
);
1656 filehdr
.f_magic
= COFF_MAGIC
;
1657 filehdr
.f_timdat
= 0;
1658 filehdr
.f_flags
= 0;
1664 unsigned int symtable_size
= filehdr
.f_nsyms
* SYMESZ
;
1665 char *buffer1
= malloc(symtable_size
+ string_byte_count
+ 4);
1666 char *ptr
= buffer1
;
1667 filehdr
.f_symptr
= bfd_tell(abfd
);
1668 w_symbols(abfd
, buffer1
, symbol_rootP
);
1669 w_strings(buffer1
+ symtable_size
);
1670 bfd_write(buffer1
, 1,symtable_size
+ string_byte_count
+ 4, abfd
);
1674 coff_header_append(abfd
, &filehdr
, &aouthdr
);
1676 bfd_close_all_done(abfd
);
1680 static void DEFUN(change_to_section
,(name
, len
, exp
),
1682 unsigned int len AND
1686 /* Find out if we've already got a section of this name etc */
1687 for(i
= SEG_E0
; i
< SEG_E9
&& segment_info
[i
].scnhdr
.s_name
[0] ; i
++)
1689 if (strncmp(segment_info
[i
].scnhdr
.s_name
, name
, len
) == 0)
1696 /* No section, add one */
1697 strncpy(segment_info
[i
].scnhdr
.s_name
, name
, 8);
1702 DEFUN_VOID(obj_coff_section
)
1704 /* Strip out the section name */
1705 char *section_name
;
1706 char *section_name_end
;
1712 section_name
= input_line_pointer
;
1713 c
= get_symbol_end();
1714 section_name_end
= input_line_pointer
;
1716 len
= section_name_end
- section_name
;
1717 input_line_pointer
++;
1721 exp
= get_absolute_expression();
1723 else if ( *input_line_pointer
== ',')
1726 input_line_pointer
++;
1727 exp
= get_absolute_expression();
1734 change_to_section(section_name
, len
,exp
);
1739 static void obj_coff_text()
1741 change_to_section(".text",5, get_absolute_expression());
1745 static void obj_coff_data()
1747 change_to_section(".data",5, get_absolute_expression());
1750 void c_symbol_merge(debug
, normal
)
1754 S_SET_DATA_TYPE(normal
, S_GET_DATA_TYPE(debug
));
1755 S_SET_STORAGE_CLASS(normal
, S_GET_STORAGE_CLASS(debug
));
1757 if (S_GET_NUMBER_AUXILIARY(debug
) > S_GET_NUMBER_AUXILIARY(normal
)) {
1758 S_SET_NUMBER_AUXILIARY(normal
, S_GET_NUMBER_AUXILIARY(debug
));
1759 } /* take the most we have */
1761 if (S_GET_NUMBER_AUXILIARY(debug
) > 0) {
1762 memcpy((char*)&normal
->sy_symbol
.ost_auxent
[0], (char*)&debug
->sy_symbol
.ost_auxent
[0], S_GET_NUMBER_AUXILIARY(debug
) * AUXESZ
);
1763 } /* Move all the auxiliary information */
1765 /* Move the debug flags. */
1766 SF_SET_DEBUG_FIELD(normal
, SF_GET_DEBUG_FIELD(debug
));
1767 } /* c_symbol_merge() */
1770 DEFUN(c_line_new
,(symbol
, paddr
, line_number
, frag
),
1773 unsigned short line_number AND
1776 struct lineno_list
* new_line
=
1777 (struct lineno_list
*)xmalloc(sizeof(struct lineno_list
));
1779 segment_info_type
*s
= segment_info
+ now_seg
;
1780 new_line
->line
.l_lnno
= line_number
;
1781 if (line_number
== 0)
1783 new_line
->line
.l_addr
.l_symndx
= (long)symbol
;
1787 new_line
->line
.l_addr
.l_paddr
= paddr
;
1790 new_line
->frag
= (char*)frag
;
1791 new_line
->next
= (struct lineno_list
*)NULL
;
1794 if (s
->lineno_list_head
== (struct lineno_list
*)NULL
)
1796 s
->lineno_list_head
= new_line
;
1800 s
->lineno_list_tail
->next
= new_line
;
1802 s
->lineno_list_tail
= new_line
;
1803 return LINESZ
* s
->scnhdr
.s_nlnno
++;
1806 void c_dot_file_symbol(filename
)
1811 symbolP
= symbol_new(".file",
1814 &zero_address_frag
);
1816 S_SET_STORAGE_CLASS(symbolP
, C_FILE
);
1817 S_SET_NUMBER_AUXILIARY(symbolP
, 1);
1818 SA_SET_FILE_FNAME(symbolP
, filename
);
1819 SF_SET_DEBUG(symbolP
);
1820 S_SET_VALUE(symbolP
, (long) previous_file_symbol
);
1822 previous_file_symbol
= symbolP
;
1824 /* Make sure that the symbol is first on the symbol chain */
1825 if (symbol_rootP
!= symbolP
) {
1826 if (symbolP
== symbol_lastP
) {
1827 symbol_lastP
= symbol_lastP
->sy_previous
;
1828 } /* if it was the last thing on the list */
1830 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1831 symbol_insert(symbolP
, symbol_rootP
, &symbol_rootP
, &symbol_lastP
);
1832 symbol_rootP
= symbolP
;
1833 } /* if not first on the list */
1835 } /* c_dot_file_symbol() */
1838 * Build a 'section static' symbol.
1841 symbolS
*c_section_symbol(name
,idx
)
1847 symbolP
= symbol_new(name
,idx
,
1849 &zero_address_frag
);
1851 S_SET_STORAGE_CLASS(symbolP
, C_STAT
);
1852 S_SET_NUMBER_AUXILIARY(symbolP
, 1);
1854 SF_SET_STATICS(symbolP
);
1857 } /* c_section_symbol() */
1860 DEFUN(w_symbols
,(abfd
, where
, symbol_rootP
),
1863 symbolS
*symbol_rootP
)
1868 /* First fill in those values we have only just worked out */
1869 for (i
= SEG_E0
; i
< SEG_E9
; i
++)
1871 symbolP
= segment_info
[i
].dot
;
1875 SA_SET_SCN_SCNLEN(symbolP
, segment_info
[i
].scnhdr
.s_size
);
1876 SA_SET_SCN_NRELOC(symbolP
, segment_info
[i
].scnhdr
.s_nreloc
);
1877 SA_SET_SCN_NLINNO(symbolP
, segment_info
[i
].scnhdr
.s_nlnno
);
1883 * Emit all symbols left in the symbol chain.
1885 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next(symbolP
)) {
1886 /* Used to save the offset of the name. It is used to point
1887 to the string in memory but must be a file offset. */
1888 register char * temp
;
1890 tc_coff_symbol_emit_hook(symbolP
);
1892 temp
= S_GET_NAME(symbolP
);
1893 if (SF_GET_STRING(symbolP
)) {
1894 S_SET_OFFSET(symbolP
, symbolP
->sy_name_offset
);
1895 S_SET_ZEROES(symbolP
, 0);
1897 bzero(symbolP
->sy_symbol
.ost_entry
.n_name
, SYMNMLEN
);
1898 strncpy(symbolP
->sy_symbol
.ost_entry
.n_name
, temp
, SYMNMLEN
);
1900 where
= symbol_to_chars(abfd
, where
, symbolP
);
1901 S_SET_NAME(symbolP
,temp
);
1906 static void DEFUN_VOID(obj_coff_lcomm
)
1913 name
= input_line_pointer
;
1917 c
= get_symbol_end();
1918 p
= input_line_pointer
;
1921 if (*input_line_pointer
!= ',') {
1922 as_bad("Expected comma after name");
1923 ignore_rest_of_line();
1926 if (*input_line_pointer
== '\n') {
1927 as_bad("Missing size expression");
1930 input_line_pointer
++;
1931 if ((temp
= get_absolute_expression ()) < 0) {
1932 as_warn("lcomm length (%d.) <0! Ignored.", temp
);
1933 ignore_rest_of_line();
1937 symbolP
= symbol_find_or_make(name
);
1938 S_SET_VALUE(symbolP
, segment_info
[SEG_E2
].scnhdr
.s_size
);
1939 S_SET_SEGMENT(symbolP
, SEG_E2
);
1940 segment_info
[SEG_E2
].scnhdr
.s_size
+= temp
;
1941 S_SET_STORAGE_CLASS(symbolP
, C_STAT
);
1942 demand_empty_rest_of_line();
1947 static void DEFUN(fixup_segment
,(fixP
, this_segment_type
),
1948 register fixS
* fixP AND
1949 segT this_segment_type
)
1951 register symbolS
*add_symbolP
;
1952 register symbolS
*sub_symbolP
;
1953 register long add_number
;
1955 register char *place
;
1956 register long where
;
1957 register char pcrel
;
1958 register fragS
*fragP
;
1959 register segT add_symbol_segment
= SEG_ABSOLUTE
;
1962 for ( ; fixP
; fixP
= fixP
->fx_next
)
1964 fragP
= fixP
->fx_frag
;
1966 where
= fixP
->fx_where
;
1967 place
= fragP
->fr_literal
+ where
;
1968 size
= fixP
->fx_size
;
1969 add_symbolP
= fixP
->fx_addsy
;
1971 if (fixP
->fx_callj
&& TC_S_IS_CALLNAME(add_symbolP
)) {
1972 /* Relocation should be done via the
1973 associated 'bal' entry point
1976 if (!TC_S_IS_BALNAME(tc_get_bal_of_call(add_symbolP
))) {
1977 as_bad("No 'bal' entry point for leafproc %s",
1978 S_GET_NAME(add_symbolP
));
1981 fixP
->fx_addsy
= add_symbolP
= tc_get_bal_of_call(add_symbolP
);
1982 } /* callj relocation */
1984 sub_symbolP
= fixP
->fx_subsy
;
1985 add_number
= fixP
->fx_offset
;
1986 pcrel
= fixP
->fx_pcrel
;
1989 add_symbol_segment
= S_GET_SEGMENT(add_symbolP
);
1990 } /* if there is an addend */
1995 if (S_GET_SEGMENT(sub_symbolP
) != SEG_ABSOLUTE
) {
1996 as_bad("Negative of non-absolute symbol %s", S_GET_NAME(sub_symbolP
));
1997 } /* not absolute */
1999 add_number
-= S_GET_VALUE(sub_symbolP
);
2001 /* if sub_symbol is in the same segment that add_symbol
2002 and add_symbol is either in DATA, TEXT, BSS or ABSOLUTE */
2003 } else if ((S_GET_SEGMENT(sub_symbolP
) == add_symbol_segment
)
2004 && (SEG_NORMAL(add_symbol_segment
)
2005 || (add_symbol_segment
== SEG_ABSOLUTE
))) {
2006 /* Difference of 2 symbols from same segment. */
2007 /* Can't make difference of 2 undefineds: 'value' means */
2008 /* something different for N_UNDF. */
2010 /* Makes no sense to use the difference of 2 arbitrary symbols
2011 * as the target of a call instruction.
2013 if (fixP
->fx_callj
) {
2014 as_bad("callj to difference of 2 symbols");
2016 #endif /* TC_I960 */
2017 add_number
+= S_GET_VALUE(add_symbolP
) -
2018 S_GET_VALUE(sub_symbolP
);
2021 fixP
->fx_addsy
= NULL
;
2023 /* Different segments in subtraction. */
2024 know(!(S_IS_EXTERNAL(sub_symbolP
) && (S_GET_SEGMENT(sub_symbolP
) == SEG_ABSOLUTE
)));
2026 if ((S_GET_SEGMENT(sub_symbolP
) == SEG_ABSOLUTE
)) {
2027 add_number
-= S_GET_VALUE(sub_symbolP
);
2029 as_bad("Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %d.",
2030 segment_name(S_GET_SEGMENT(sub_symbolP
)),
2031 S_GET_NAME(sub_symbolP
), fragP
->fr_address
+ where
);
2034 } /* if sub_symbolP */
2037 if (add_symbol_segment
== this_segment_type
&& pcrel
) {
2039 * This fixup was made when the symbol's segment was
2040 * SEG_UNKNOWN, but it is now in the local segment.
2041 * So we know how to do the address without relocation.
2044 /* reloc_callj() may replace a 'call' with a 'calls' or a 'bal',
2045 * in which cases it modifies *fixP as appropriate. In the case
2046 * of a 'calls', no further work is required, and *fixP has been
2047 * set up to make the rest of the code below a no-op.
2050 #endif /* TC_I960 */
2052 add_number
+= S_GET_VALUE(add_symbolP
);
2053 add_number
-= md_pcrel_from (fixP
);
2054 pcrel
= 0; /* Lie. Don't want further pcrel processing. */
2055 fixP
->fx_addsy
= NULL
; /* No relocations please. */
2058 switch (add_symbol_segment
)
2062 reloc_callj(fixP
); /* See comment about reloc_callj() above*/
2063 #endif /* TC_I960 */
2064 add_number
+= S_GET_VALUE(add_symbolP
);
2065 fixP
->fx_addsy
= NULL
;
2070 add_number
+= S_GET_VALUE(add_symbolP
) +
2071 segment_info
[S_GET_SEGMENT(add_symbolP
)].scnhdr
.s_paddr
;
2076 if ((int)fixP
->fx_bit_fixP
== 13) {
2077 /* This is a COBR instruction. They have only a
2078 * 13-bit displacement and are only to be used
2079 * for local branches: flag as error, don't generate
2082 as_bad("can't use COBR format with external label");
2083 fixP
->fx_addsy
= NULL
; /* No relocations please. */
2086 #endif /* TC_I960 */
2093 } /* switch on symbol seg */
2094 } /* if not in local seg */
2095 } /* if there was a + symbol */
2098 add_number
-= md_pcrel_from(fixP
);
2099 if (add_symbolP
== 0) {
2100 fixP
->fx_addsy
= & abs_symbol
;
2101 } /* if there's an add_symbol */
2104 if (!fixP
->fx_bit_fixP
) {
2106 (add_number
& ~0xFF) && (add_number
&~0xFF!=(-1&~0xFF))) ||
2108 (add_number
& ~0xFFFF) && (add_number
&~0xFFFF!=(-1&~0xFFFF)))) {
2109 as_bad("Value of %d too large for field of %d bytes at 0x%x",
2110 add_number
, size
, fragP
->fr_address
+ where
);
2111 } /* generic error checking */
2112 } /* not a bit fix */
2113 /* once this fix has been applied, we don't have to output anything
2114 nothing more need be done -*/
2115 md_apply_fix(fixP
, add_number
);
2117 } /* For each fixS in this segment. */
2120 } /* fixup_segment() */