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)])
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
352 TC_RELOC_MANGLE(fix_ptr
, &intr
, base
);
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));
907 = c_line_new(def_symbol_in_progress
,0, 0, &zero_address_frag
);
911 SF_SET_PROCESS(def_symbol_in_progress
);
913 if (symbolP
== NULL
) {
914 /* That is, if this is the first
915 time we've seen the function... */
916 symbol_table_insert(def_symbol_in_progress
);
917 } /* definition follows debug */
918 } /* Create the line number entry pointing to the function being defined */
920 def_symbol_in_progress
= NULL
;
921 demand_empty_rest_of_line();
923 } /* obj_coff_endef() */
926 DEFUN_VOID(obj_coff_dim
)
928 register int dim_index
;
930 if (def_symbol_in_progress
== NULL
)
932 as_warn(".dim pseudo-op used outside of .def/.endef: ignored.");
933 demand_empty_rest_of_line();
935 } /* if not inside .def/.endef */
937 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
939 for (dim_index
= 0; dim_index
< DIMNUM
; dim_index
++)
942 SA_SET_SYM_DIMEN(def_symbol_in_progress
, dim_index
, get_absolute_expression());
944 switch (*input_line_pointer
)
948 input_line_pointer
++;
952 as_warn("badly formed .dim directive ignored");
953 /* intentional fallthrough */
958 } /* switch on following character */
959 } /* for each dimension */
961 demand_empty_rest_of_line();
963 } /* obj_coff_dim() */
965 static void obj_coff_line() {
966 if (def_symbol_in_progress
== NULL
) {
969 } /* if it looks like a stabs style line */
971 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
972 SA_SET_SYM_LNNO(def_symbol_in_progress
, get_absolute_expression());
974 demand_empty_rest_of_line();
976 } /* obj_coff_line() */
978 static void obj_coff_size() {
979 if (def_symbol_in_progress
== NULL
) {
980 as_warn(".size pseudo-op used outside of .def/.endef ignored.");
981 demand_empty_rest_of_line();
983 } /* if not inside .def/.endef */
985 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
986 SA_SET_SYM_SIZE(def_symbol_in_progress
, get_absolute_expression());
987 demand_empty_rest_of_line();
989 } /* obj_coff_size() */
991 static void obj_coff_scl() {
992 if (def_symbol_in_progress
== NULL
) {
993 as_warn(".scl pseudo-op used outside of .def/.endef ignored.");
994 demand_empty_rest_of_line();
996 } /* if not inside .def/.endef */
998 S_SET_STORAGE_CLASS(def_symbol_in_progress
, get_absolute_expression());
999 demand_empty_rest_of_line();
1001 } /* obj_coff_scl() */
1003 static void obj_coff_tag() {
1007 if (def_symbol_in_progress
== NULL
) {
1008 as_warn(".tag 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);
1014 symbol_name
= input_line_pointer
;
1015 name_end
= get_symbol_end();
1017 /* Assume that the symbol referred to by .tag is always defined. */
1018 /* This was a bad assumption. I've added find_or_make. xoxorich. */
1019 SA_SET_SYM_TAGNDX(def_symbol_in_progress
, (long) tag_find_or_make(symbol_name
));
1020 if (SA_GET_SYM_TAGNDX(def_symbol_in_progress
) == 0L) {
1021 as_warn("tag not found for .tag %s", symbol_name
);
1024 SF_SET_TAGGED(def_symbol_in_progress
);
1025 *input_line_pointer
= name_end
;
1027 demand_empty_rest_of_line();
1029 } /* obj_coff_tag() */
1031 static void obj_coff_type() {
1032 if (def_symbol_in_progress
== NULL
) {
1033 as_warn(".type pseudo-op used outside of .def/.endef ignored.");
1034 demand_empty_rest_of_line();
1036 } /* if not inside .def/.endef */
1038 S_SET_DATA_TYPE(def_symbol_in_progress
, get_absolute_expression());
1040 if (ISFCN(S_GET_DATA_TYPE(def_symbol_in_progress
)) &&
1041 S_GET_STORAGE_CLASS(def_symbol_in_progress
) != C_TPDEF
) {
1042 SF_SET_FUNCTION(def_symbol_in_progress
);
1043 } /* is a function */
1045 demand_empty_rest_of_line();
1047 } /* obj_coff_type() */
1049 static void obj_coff_val() {
1050 if (def_symbol_in_progress
== NULL
) {
1051 as_warn(".val pseudo-op used outside of .def/.endef ignored.");
1052 demand_empty_rest_of_line();
1054 } /* if not inside .def/.endef */
1056 if (is_name_beginner(*input_line_pointer
)) {
1057 char *symbol_name
= input_line_pointer
;
1058 char name_end
= get_symbol_end();
1060 if (!strcmp(symbol_name
, ".")) {
1061 def_symbol_in_progress
->sy_frag
= frag_now
;
1062 S_SET_VALUE(def_symbol_in_progress
, obstack_next_free(&frags
) - frag_now
->fr_literal
);
1063 /* If the .val is != from the .def (e.g. statics) */
1064 } else if (strcmp(S_GET_NAME(def_symbol_in_progress
), symbol_name
)) {
1065 def_symbol_in_progress
->sy_forward
= symbol_find_or_make(symbol_name
);
1067 /* If the segment is undefined when the forward
1068 reference is solved, then copy the segment id
1069 from the forward symbol. */
1070 SF_SET_GET_SEGMENT(def_symbol_in_progress
);
1072 /* Otherwise, it is the name of a non debug symbol and its value will be calculated later. */
1073 *input_line_pointer
= name_end
;
1075 S_SET_VALUE(def_symbol_in_progress
, get_absolute_expression());
1076 } /* if symbol based */
1078 demand_empty_rest_of_line();
1080 } /* obj_coff_val() */
1083 * Maintain a list of the tagnames of the structres.
1086 static void tag_init() {
1087 tag_hash
= hash_new();
1091 static void tag_insert(name
, symbolP
)
1095 register char * error_string
;
1097 if (*(error_string
= hash_jam(tag_hash
, name
, (char *)symbolP
))) {
1098 as_fatal("Inserting \"%s\" into structure table failed: %s",
1099 name
, error_string
);
1102 } /* tag_insert() */
1104 static symbolS
*tag_find_or_make(name
)
1109 if ((symbolP
= tag_find(name
)) == NULL
) {
1110 symbolP
= symbol_new(name
,
1113 &zero_address_frag
);
1115 tag_insert(S_GET_NAME(symbolP
), symbolP
);
1116 symbol_table_insert(symbolP
);
1120 } /* tag_find_or_make() */
1122 static symbolS
*tag_find(name
)
1125 #ifdef STRIP_UNDERSCORE
1126 if (*name
== '_') name
++;
1127 #endif /* STRIP_UNDERSCORE */
1128 return((symbolS
*)hash_find(tag_hash
, name
));
1131 void obj_read_begin_hook() {
1132 /* These had better be the same. Usually 18 bytes. */
1134 know(sizeof(SYMENT
) == sizeof(AUXENT
));
1135 know(SYMESZ
== AUXESZ
);
1140 } /* obj_read_begin_hook() */
1142 /* This function runs through the symbol table and puts all the
1143 externals onto another chain */
1145 /* The chain of externals */
1146 symbolS
*symbol_externP
= NULL
;
1147 symbolS
*symbol_extern_lastP
= NULL
;
1150 symbolS
*last_functionP
= NULL
;
1154 static unsigned int DEFUN_VOID(yank_symbols
)
1157 unsigned int symbol_number
=0;
1159 for (symbolP
= symbol_rootP
;
1161 symbolP
= symbolP
? symbol_next(symbolP
) : symbol_rootP
) {
1162 if (!SF_GET_DEBUG(symbolP
)) {
1163 /* Debug symbols do not need all this rubbish */
1164 symbolS
* real_symbolP
;
1166 /* L* and C_EFCN symbols never merge. */
1167 if (!SF_GET_LOCAL(symbolP
)
1168 && (real_symbolP
= symbol_find_base(S_GET_NAME(symbolP
), DO_NOT_STRIP
))
1169 && real_symbolP
!= symbolP
) {
1170 /* FIXME-SOON: where do dups come from?
1171 Maybe tag references before definitions? xoxorich. */
1172 /* Move the debug data from the debug symbol to the
1173 real symbol. Do NOT do the oposite (i.e. move from
1174 real symbol to debug symbol and remove real symbol from the
1175 list.) Because some pointers refer to the real symbol
1176 whereas no pointers refer to the debug symbol. */
1177 c_symbol_merge(symbolP
, real_symbolP
);
1178 /* Replace the current symbol by the real one */
1179 /* The symbols will never be the last or the first
1180 because : 1st symbol is .file and 3 last symbols are
1181 .text, .data, .bss */
1182 symbol_remove(real_symbolP
, &symbol_rootP
, &symbol_lastP
);
1183 symbol_insert(real_symbolP
, symbolP
, &symbol_rootP
, &symbol_lastP
);
1184 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1185 symbolP
= real_symbolP
;
1186 } /* if not local but dup'd */
1188 if (flagseen
['R'] && (S_GET_SEGMENT(symbolP
) == SEG_E1
)) {
1189 S_SET_SEGMENT(symbolP
, SEG_E0
);
1190 } /* push data into text */
1192 S_SET_VALUE(symbolP
,
1193 S_GET_VALUE(symbolP
) + symbolP
->sy_frag
->fr_address
);
1195 if (!S_IS_DEFINED(symbolP
) && !SF_GET_LOCAL(symbolP
))
1197 S_SET_EXTERNAL(symbolP
);
1199 else if (S_GET_STORAGE_CLASS(symbolP
) == C_NULL
)
1201 if (S_GET_SEGMENT(symbolP
) == SEG_E0
)
1203 S_SET_STORAGE_CLASS(symbolP
, C_LABEL
);
1207 S_SET_STORAGE_CLASS(symbolP
, C_STAT
);
1211 /* Mainly to speed up if not -g */
1212 if (SF_GET_PROCESS(symbolP
))
1214 /* Handle the nested blocks auxiliary info. */
1215 if (S_GET_STORAGE_CLASS(symbolP
) == C_BLOCK
) {
1216 if (!strcmp(S_GET_NAME(symbolP
), ".bb"))
1217 stack_push(block_stack
, (char *) &symbolP
);
1219 register symbolS
* begin_symbolP
;
1220 begin_symbolP
= *(symbolS
**)stack_pop(block_stack
);
1221 if (begin_symbolP
== (symbolS
*)0)
1222 as_warn("mismatched .eb");
1224 SA_SET_SYM_ENDNDX(begin_symbolP
, symbol_number
+2);
1227 /* If we are able to identify the type of a function, and we
1228 are out of a function (last_functionP == 0) then, the
1229 function symbol will be associated with an auxiliary
1231 if (last_functionP
== (symbolS
*)0 &&
1232 SF_GET_FUNCTION(symbolP
)) {
1233 last_functionP
= symbolP
;
1235 if (S_GET_NUMBER_AUXILIARY(symbolP
) < 1) {
1236 S_SET_NUMBER_AUXILIARY(symbolP
, 1);
1237 } /* make it at least 1 */
1239 /* Clobber possible stale .dim information. */
1240 bzero(symbolP
->sy_symbol
.ost_auxent
[0].x_sym
.x_fcnary
.x_ary
.x_dimen
,
1241 sizeof(symbolP
->sy_symbol
.ost_auxent
[0].x_sym
.x_fcnary
.x_ary
.x_dimen
));
1243 /* The C_FCN doesn't need any additional information.
1244 I don't even know if this is needed for sdb. But the
1245 standard assembler generates it, so...
1247 if (S_GET_STORAGE_CLASS(symbolP
) == C_EFCN
) {
1248 if (last_functionP
== (symbolS
*)0)
1249 as_fatal("C_EFCN symbol out of scope");
1250 SA_SET_SYM_FSIZE(last_functionP
,
1251 (long)(S_GET_VALUE(symbolP
) -
1252 S_GET_VALUE(last_functionP
)));
1253 SA_SET_SYM_ENDNDX(last_functionP
, symbol_number
);
1254 last_functionP
= (symbolS
*)0;
1257 } else if (SF_GET_TAG(symbolP
)) {
1258 /* First descriptor of a structure must point to
1259 the first slot after the structure description. */
1260 last_tagP
= symbolP
;
1262 } else if (S_GET_STORAGE_CLASS(symbolP
) == C_EOS
) {
1263 /* +2 take in account the current symbol */
1264 SA_SET_SYM_ENDNDX(last_tagP
, symbol_number
+ 2);
1265 } else if (S_GET_STORAGE_CLASS(symbolP
) == C_FILE
) {
1266 if (S_GET_VALUE(symbolP
)) {
1267 S_SET_VALUE((symbolS
*) S_GET_VALUE(symbolP
), symbol_number
);
1268 S_SET_VALUE(symbolP
, 0);
1269 } /* no one points at the first .file symbol */
1270 } /* if debug or tag or eos or file */
1272 /* We must put the external symbols apart. The loader
1273 does not bomb if we do not. But the references in
1274 the endndx field for a .bb symbol are not corrected
1275 if an external symbol is removed between .bb and .be.
1276 I.e in the following case :
1277 [20] .bb endndx = 22
1280 ld will move the symbol 21 to the end of the list but
1281 endndx will still be 22 instead of 21. */
1284 if (SF_GET_LOCAL(symbolP
)) {
1285 /* remove C_EFCN and LOCAL (L...) symbols */
1286 /* next pointer remains valid */
1287 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1290 else if (!S_IS_DEFINED(symbolP
)
1291 && !S_IS_DEBUG(symbolP
)
1292 && !SF_GET_STATICS(symbolP
) &&
1293 S_GET_STORAGE_CLASS(symbolP
) == C_EXT
)
1294 { /* C_EXT && !SF_GET_FUNCTION(symbolP)) */
1295 /* if external, Remove from the list */
1296 symbolS
*hold
= symbol_previous(symbolP
);
1298 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1299 symbol_clear_list_pointers(symbolP
);
1300 symbol_append(symbolP
, symbol_extern_lastP
, &symbol_externP
, &symbol_extern_lastP
);
1303 if (SF_GET_STRING(symbolP
)) {
1304 symbolP
->sy_name_offset
= string_byte_count
;
1305 string_byte_count
+= strlen(S_GET_NAME(symbolP
)) + 1;
1307 symbolP
->sy_name_offset
= 0;
1308 } /* fix "long" names */
1310 symbolP
->sy_number
= symbol_number
;
1311 symbol_number
+= 1 + S_GET_NUMBER_AUXILIARY(symbolP
);
1312 } /* if local symbol */
1313 } /* traverse the symbol list */
1314 return symbol_number
;
1319 static unsigned int DEFUN_VOID(glue_symbols
)
1321 unsigned int symbol_number
= 0;
1323 for (symbolP
= symbol_externP
; symbol_externP
;) {
1324 symbolS
*tmp
= symbol_externP
;
1327 symbol_remove(tmp
, &symbol_externP
, &symbol_extern_lastP
);
1328 symbol_append(tmp
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
1331 if (SF_GET_STRING(tmp
)) {
1332 tmp
->sy_name_offset
= string_byte_count
;
1333 string_byte_count
+= strlen(S_GET_NAME(tmp
)) + 1;
1335 tmp
->sy_name_offset
= 0;
1336 } /* fix "long" names */
1338 tmp
->sy_number
= symbol_number
;
1339 symbol_number
+= 1 + S_GET_NUMBER_AUXILIARY(tmp
);
1340 } /* append the entire extern chain */
1341 return symbol_number
;
1345 static unsigned int DEFUN_VOID(tie_tags
)
1347 unsigned int symbol_number
= 0;
1350 for (symbolP
= symbol_rootP
; symbolP
; symbolP
=
1351 symbol_next(symbolP
))
1353 symbolP
->sy_number
= symbol_number
;
1357 if (SF_GET_TAGGED(symbolP
))
1361 ((symbolS
*) SA_GET_SYM_TAGNDX(symbolP
))->sy_number
);
1364 symbol_number
+= 1 + S_GET_NUMBER_AUXILIARY(symbolP
);
1366 return symbol_number
;
1371 DEFUN(crawl_symbols
,(headers
, abfd
),
1372 struct internal_filehdr
*headers AND
1377 unsigned int ptr
= 0;
1382 /* Initialize the stack used to keep track of the matching .bb .be */
1384 block_stack
= stack_init(512, sizeof(symbolS
*));
1385 /* JF deal with forward references first... */
1386 for (symbolP
= symbol_rootP
;
1388 symbolP
= symbol_next(symbolP
))
1391 if (symbolP
->sy_forward
) {
1392 S_SET_VALUE(symbolP
, (S_GET_VALUE(symbolP
)
1393 + S_GET_VALUE(symbolP
->sy_forward
)
1394 + symbolP
->sy_forward
->sy_frag
->fr_address
));
1396 if (SF_GET_GET_SEGMENT(symbolP
)) {
1397 S_SET_SEGMENT(symbolP
, S_GET_SEGMENT(symbolP
->sy_forward
));
1398 } /* forward segment also */
1400 symbolP
->sy_forward
=0;
1401 } /* if it has a forward reference */
1402 } /* walk the symbol chain */
1405 /* The symbol list should be ordered according to the following sequence
1408 * . debug entries for functions
1409 * . fake symbols for the sections, including.text .data and .bss
1411 * . undefined symbols
1412 * But this is not mandatory. The only important point is to put the
1413 * undefined symbols at the end of the list.
1416 if (symbol_rootP
== NULL
1417 || S_GET_STORAGE_CLASS(symbol_rootP
) != C_FILE
) {
1418 c_dot_file_symbol("fake");
1420 /* Is there a .file symbol ? If not insert one at the beginning. */
1423 * Build up static symbols for the sections, they are filled in later
1427 for (i
= SEG_E0
; i
< SEG_E9
; i
++)
1429 if (segment_info
[i
].scnhdr
.s_name
[0])
1431 segment_info
[i
].dot
=
1432 c_section_symbol(segment_info
[i
].scnhdr
.s_name
,
1439 /* Take all the externals out and put them into another chain */
1440 headers
->f_nsyms
= yank_symbols();
1441 /* Take the externals and glue them onto the end.*/
1442 headers
->f_nsyms
+= glue_symbols();
1444 headers
->f_nsyms
= tie_tags();
1445 know(symbol_externP
== NULL
);
1446 know(symbol_extern_lastP
== NULL
);
1452 * Find strings by crawling along symbol table chain.
1455 void DEFUN(w_strings
,(where
),
1460 /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
1461 md_number_to_chars(where
, string_byte_count
, sizeof(string_byte_count
));
1462 where
+= sizeof(string_byte_count
);
1463 for (symbolP
= symbol_rootP
;
1465 symbolP
= symbol_next(symbolP
))
1469 if (SF_GET_STRING(symbolP
)) {
1470 size
= strlen(S_GET_NAME(symbolP
)) + 1;
1472 memcpy(where
, S_GET_NAME(symbolP
),size
);
1485 DEFUN(do_linenos_for
,(abfd
, file_cursor
),
1487 unsigned long *file_cursor
)
1491 for (idx
= SEG_E0
; idx
< SEG_E9
; idx
++)
1493 segment_info_type
*s
= segment_info
+ idx
;
1495 if (s
->scnhdr
.s_nlnno
!= 0)
1497 struct lineno_list
*line_ptr
;
1499 struct external_lineno
*buffer
=
1500 (struct external_lineno
*)xmalloc(s
->scnhdr
.s_nlnno
* LINESZ
);
1502 struct external_lineno
*dst
= buffer
;
1504 /* Run through the table we've built and turn it into its external
1507 for (line_ptr
= s
->lineno_list_head
;
1508 line_ptr
!= (struct lineno_list
*)NULL
;
1509 line_ptr
= line_ptr
->next
)
1511 if (line_ptr
->line
.l_lnno
== 0)
1513 /* Turn a pointer to a symbol into the symbols' index */
1514 line_ptr
->line
.l_addr
.l_symndx
=
1515 ( (symbolS
*)line_ptr
->line
.l_addr
.l_symndx
)->sy_number
;
1517 (void) bfd_coff_swap_lineno_out(abfd
, &(line_ptr
->line
), dst
);
1521 s
->scnhdr
.s_lnnoptr
= *file_cursor
;
1523 bfd_write(buffer
, 1, s
->scnhdr
.s_nlnno
* LINESZ
, abfd
);
1526 *file_cursor
+= s
->scnhdr
.s_nlnno
* LINESZ
;
1532 /* Now we run through the list of frag chains in a segment and
1533 make all the subsegment frags appear at the end of the
1534 list, as if the seg 0 was extra long */
1536 static void DEFUN_VOID(remove_subsegs
)
1540 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1542 frchainS
*head
= segment_info
[i
].frchainP
;
1544 fragS
* prev_frag
= &dummy
;
1546 while (head
&& head
->frch_seg
== i
)
1548 prev_frag
->fr_next
= head
->frch_root
;
1549 prev_frag
= head
->frch_last
;
1550 head
= head
->frch_next
;
1552 prev_frag
->fr_next
= 0;
1557 extern void DEFUN_VOID(write_object_file
)
1560 struct frchain
*frchain_ptr
;
1562 struct internal_filehdr filehdr
;
1563 struct internal_aouthdr aouthdr
;
1564 unsigned long file_cursor
;
1566 unsigned int addr
= 0;
1567 abfd
= bfd_openw(out_file_name
, TARGET_FORMAT
);
1571 as_perror ("FATAL: Can't create %s", out_file_name
);
1574 bfd_set_format(abfd
, bfd_object
);
1575 bfd_set_arch_mach(abfd
, BFD_ARCH
, 0);
1579 string_byte_count
= 4;
1581 for (frchain_ptr
= frchain_root
;
1582 frchain_ptr
!= (struct frchain
*)NULL
;
1583 frchain_ptr
= frchain_ptr
->frch_next
) {
1584 /* Run through all the sub-segments and align them up. Also close any
1585 open frags. We tack a .fill onto the end of the frag chain so
1586 that any .align's size can be worked by looking at the next
1589 subseg_new(frchain_ptr
->frch_seg
, frchain_ptr
->frch_subseg
);
1590 #define SUB_SEGMENT_ALIGN 1
1591 frag_align(SUB_SEGMENT_ALIGN
,0);
1592 frag_wane(frag_now
);
1593 frag_now
->fr_fix
= 0;
1594 know( frag_now
->fr_next
== NULL
);
1601 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1603 relax_segment(segment_info
[i
].frchainP
->frch_root
, i
);
1610 filehdr
.f_nscns
= 0;
1612 /* Find out how big the sections are */
1613 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1616 if (segment_info
[i
].scnhdr
.s_name
[0])
1620 segment_info
[i
].scnhdr
.s_paddr
= addr
;
1622 /* THis is a special case, we leave the size alone, which will have */
1623 /* been made up from all and any lcomms seen */
1626 addr
+= size_section(abfd
, i
);
1632 /* Turn the gas native symbol table shape into a coff symbol table */
1633 crawl_symbols(&filehdr
, abfd
);
1635 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1637 fixup_segment(segment_info
[i
].fix_root
, i
);
1641 file_cursor
= FILHSZ
+ SCNHSZ
* filehdr
.f_nscns
;
1643 bfd_seek(abfd
, file_cursor
, 0);
1646 do_relocs_for(abfd
, &file_cursor
);
1648 do_linenos_for(abfd
, &file_cursor
);
1651 /* Plant the data */
1653 fill_section(abfd
,&filehdr
, &file_cursor
);
1655 filehdr
.f_magic
= COFF_MAGIC
;
1656 filehdr
.f_timdat
= 0;
1657 filehdr
.f_flags
= 0;
1663 unsigned int symtable_size
= filehdr
.f_nsyms
* SYMESZ
;
1664 char *buffer1
= malloc(symtable_size
+ string_byte_count
+ 4);
1665 char *ptr
= buffer1
;
1666 filehdr
.f_symptr
= bfd_tell(abfd
);
1667 w_symbols(abfd
, buffer1
, symbol_rootP
);
1668 w_strings(buffer1
+ symtable_size
);
1669 bfd_write(buffer1
, 1,symtable_size
+ string_byte_count
+ 4, abfd
);
1673 coff_header_append(abfd
, &filehdr
, &aouthdr
);
1675 bfd_close_all_done(abfd
);
1679 static void DEFUN(change_to_section
,(name
, len
, exp
),
1681 unsigned int len AND
1685 /* Find out if we've already got a section of this name etc */
1686 for(i
= SEG_E0
; i
< SEG_E9
&& segment_info
[i
].scnhdr
.s_name
[0] ; i
++)
1688 if (strncmp(segment_info
[i
].scnhdr
.s_name
, name
, len
) == 0)
1695 /* No section, add one */
1696 strncpy(segment_info
[i
].scnhdr
.s_name
, name
, 8);
1701 DEFUN_VOID(obj_coff_section
)
1703 /* Strip out the section name */
1704 char *section_name
;
1705 char *section_name_end
;
1711 section_name
= input_line_pointer
;
1712 c
= get_symbol_end();
1713 section_name_end
= input_line_pointer
;
1715 len
= section_name_end
- section_name
;
1716 input_line_pointer
++;
1720 exp
= get_absolute_expression();
1722 else if ( *input_line_pointer
== ',')
1725 input_line_pointer
++;
1726 exp
= get_absolute_expression();
1733 change_to_section(section_name
, len
,exp
);
1734 *section_name_end
= c
;
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() */