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
;
327 for (idx
= SEG_E0
; idx
< SEG_E9
; idx
++)
329 if (segment_info
[idx
].scnhdr
.s_name
[0])
332 struct external_reloc
*ext_ptr
;
333 struct external_reloc
*external_reloc_vec
;
334 unsigned int external_reloc_size
;
335 unsigned int count
= 0;
336 unsigned int base
= segment_info
[idx
].scnhdr
.s_paddr
;
337 fixS
* fix_ptr
= segment_info
[idx
].fix_root
;
338 nrelocs
= count_entries_in_chain(idx
);
339 external_reloc_size
= nrelocs
* RELSZ
;
341 (struct external_reloc
*)malloc(external_reloc_size
);
345 ext_ptr
= external_reloc_vec
;
347 /* Fill in the internal coff style reloc struct from the
352 struct internal_reloc intr
;
354 /* Only output some of the relocations */
355 if (TC_COUNT_RELOC(fix_ptr
))
358 symbol_ptr
= fix_ptr
->fx_addsy
;
360 intr
.r_type
= TC_COFF_FIX2RTYPE(fix_ptr
);
361 intr
.r_vaddr
= base
+ fix_ptr
->fx_frag
->fr_address
+ fix_ptr
->fx_where
;
364 /* Turn the segment of the symbol into an offset
367 segment_info
[S_GET_SEGMENT(symbol_ptr
)].dot
;
371 intr
.r_symndx
= dot
->sy_number
;
375 intr
.r_symndx
= symbol_ptr
->sy_number
;
379 (void)bfd_coff_swap_reloc_out(abfd
, &intr
, ext_ptr
);
383 /* The 29k has a special kludge for the high 16 bit reloc.
384 Two relocations are emmited, R_IHIHALF, and
385 R_IHCONST. The second one doesn't contain a symbol,
386 but uses the value for offset */
388 if (intr
.r_type
== R_IHIHALF
)
390 /* now emit the second bit */
391 intr
.r_type
= R_IHCONST
;
392 intr
.r_symndx
= fix_ptr
->fx_addnumber
;
393 (void)bfd_coff_swap_reloc_out(abfd
,&intr
,ext_ptr
);
399 fix_ptr
= fix_ptr
->fx_next
;
402 /* Write out the reloc table */
403 segment_info
[idx
].scnhdr
.s_relptr
= *file_cursor
;
404 segment_info
[idx
].scnhdr
.s_nreloc
= nrelocs
;
405 bfd_write((PTR
)external_reloc_vec
, 1, external_reloc_size
, abfd
);
406 *file_cursor
+= external_reloc_size
;
407 free( external_reloc_vec
);
413 /* run through a frag chain and write out the data to go with it, fill
414 in the scnhdrs with the info on the file postions
416 static void DEFUN(fill_section
,(abfd
, filehdr
, file_cursor
),
418 struct internal_filehdr
*filehdr AND
419 unsigned long *file_cursor
)
423 unsigned int paddr
= 0;
425 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
427 unsigned int offset
= 0;
429 struct internal_scnhdr
*s
= &( segment_info
[i
].scnhdr
);
433 fragS
*frag
= segment_info
[i
].frchainP
->frch_root
;
434 char *buffer
= malloc(s
->s_size
);
435 s
->s_scnptr
= *file_cursor
;
439 s
->s_flags
= STYP_REG
;
440 if (strcmp(s
->s_name
,".text")==0)
441 s
->s_flags
|= STYP_TEXT
;
442 else if (strcmp(s
->s_name
,".data")==0)
443 s
->s_flags
|= STYP_DATA
;
444 else if (strcmp(s
->s_name
,".bss")==0)
445 s
->s_flags
|= STYP_BSS
| STYP_NOLOAD
;
448 unsigned int fill_size
;
449 switch (frag
->fr_type
) {
456 memcpy(buffer
+ frag
->fr_address
,
459 offset
+= frag
->fr_fix
;
462 fill_size
= frag
->fr_var
;
466 unsigned int off
= frag
->fr_fix
;
467 for (count
= frag
->fr_offset
; count
; count
--)
469 memcpy(buffer
+ frag
->fr_address
+ off
,
470 frag
->fr_literal
+ frag
->fr_fix
,
482 frag
= frag
->fr_next
;
486 bfd_write(buffer
, s
->s_size
,1,abfd
);
489 *file_cursor
+= s
->s_size
;
498 /* Coff file generation & utilities */
502 DEFUN(coff_header_append
,(abfd
, filehdr
, aouthdr
),
504 struct internal_filehdr
*filehdr AND
505 struct internal_aouthdr
*aouthdr
)
511 bfd_seek(abfd
, 0, 0);
513 filehdr
.f_opthdr
= bfd_coff_swap_aouthdr_out(abfd
, aouthdr
,
516 filehdr
->f_opthdr
= 0;
518 i
= bfd_coff_swap_filehdr_out(abfd
, filehdr
, buffer
);
520 bfd_write(buffer
, i
,1, abfd
);
521 bfd_write(buffero
, filehdr
->f_opthdr
, 1, abfd
);
523 for (i
= SEG_E0
; i
< SEG_E9
; i
++)
525 if (segment_info
[i
].scnhdr
.s_name
[0])
528 bfd_coff_swap_scnhdr_out(abfd
,
529 &(segment_info
[i
].scnhdr
),
531 bfd_write(buffer
, size
, 1, abfd
);
538 DEFUN(symbol_to_chars
,(abfd
, where
, symbolP
),
543 unsigned int numaux
= symbolP
->sy_symbol
.ost_entry
.n_numaux
;
546 /* Turn any symbols with register attributes into abs symbols */
547 if (S_GET_SEGMENT(symbolP
) == SEG_REGISTER
)
549 S_SET_SEGMENT(symbolP
, SEG_ABSOLUTE
);
551 /* At the same time, relocate all symbols to their output value */
554 segment_info
[S_GET_SEGMENT(symbolP
)].scnhdr
.s_paddr
555 + S_GET_VALUE(symbolP
));
557 where
+= bfd_coff_swap_sym_out(abfd
, &symbolP
->sy_symbol
.ost_entry
,
560 for (i
= 0; i
< numaux
; i
++)
562 where
+= bfd_coff_swap_aux_out(abfd
,
563 &symbolP
->sy_symbol
.ost_auxent
[i
],
564 S_GET_DATA_TYPE(symbolP
),
565 S_GET_STORAGE_CLASS(symbolP
),
575 void obj_symbol_new_hook(symbolP
)
578 char underscore
= 0; /* Symbol has leading _ */
580 /* Effective symbol */
581 /* Store the pointer in the offset. */
582 S_SET_ZEROES(symbolP
, 0L);
583 S_SET_DATA_TYPE(symbolP
, T_NULL
);
584 S_SET_STORAGE_CLASS(symbolP
, 0);
585 S_SET_NUMBER_AUXILIARY(symbolP
, 0);
586 /* Additional information */
587 symbolP
->sy_symbol
.ost_flags
= 0;
588 /* Auxiliary entries */
589 bzero((char*)&symbolP
->sy_symbol
.ost_auxent
[0], AUXESZ
);
591 #ifdef STRIP_UNDERSCORE
592 /* Remove leading underscore at the beginning of the symbol.
593 * This is to be compatible with the standard librairies.
595 if (*S_GET_NAME(symbolP
) == '_') {
597 S_SET_NAME(symbolP
, S_GET_NAME(symbolP
) + 1);
598 } /* strip underscore */
599 #endif /* STRIP_UNDERSCORE */
601 if (S_IS_STRING(symbolP
))
602 SF_SET_STRING(symbolP
);
603 if (!underscore
&& S_IS_LOCAL(symbolP
))
604 SF_SET_LOCAL(symbolP
);
607 } /* obj_symbol_new_hook() */
610 stack
* stack_init(chunk_size
, element_size
)
611 unsigned long chunk_size
;
612 unsigned long element_size
;
616 if ((st
= (stack
*)malloc(sizeof(stack
))) == (stack
*)0)
618 if ((st
->data
= malloc(chunk_size
)) == (char*)0) {
623 st
->size
= chunk_size
;
624 st
->chunk_size
= chunk_size
;
625 st
->element_size
= element_size
;
629 void stack_delete(st
)
636 char *stack_push(st
, element
)
640 if (st
->pointer
+ st
->element_size
>= st
->size
) {
641 st
->size
+= st
->chunk_size
;
642 if ((st
->data
= xrealloc(st
->data
, st
->size
)) == (char*)0)
645 memcpy(st
->data
+ st
->pointer
, element
, st
->element_size
);
646 st
->pointer
+= st
->element_size
;
647 return st
->data
+ st
->pointer
;
653 if ((st
->pointer
-= st
->element_size
) < 0) {
658 return st
->data
+ st
->pointer
;
664 return st
->data
+ st
->pointer
- st
->element_size
;
669 * Handle .ln directives.
672 static void obj_coff_ln() {
673 if (def_symbol_in_progress
!= NULL
) {
674 as_warn(".ln pseudo-op inside .def/.endef: ignored.");
675 demand_empty_rest_of_line();
677 } /* wrong context */
680 obstack_next_free(&frags
) - frag_now
->fr_literal
,
681 get_absolute_expression(),
684 demand_empty_rest_of_line();
686 } /* obj_coff_line() */
691 * Handle .def directives.
693 * One might ask : why can't we symbol_new if the symbol does not
694 * already exist and fill it with debug information. Because of
695 * the C_EFCN special symbol. It would clobber the value of the
696 * function symbol before we have a chance to notice that it is
697 * a C_EFCN. And a second reason is that the code is more clear this
698 * way. (at least I think it is :-).
702 #define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';')
703 #define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \
704 *input_line_pointer == '\t') \
705 input_line_pointer++;
708 DEFUN(obj_coff_def
,(what
),
711 char name_end
; /* Char after the end of name */
712 char *symbol_name
; /* Name of the debug symbol */
713 char *symbol_name_copy
; /* Temporary copy of the name */
714 unsigned int symbol_name_length
;
715 /*$char* directiveP;$ */ /* Name of the pseudo opcode */
716 /*$char directive[MAX_DIRECTIVE];$ */ /* Backup of the directive */
717 /*$char end = 0;$ */ /* If 1, stop parsing */
719 if (def_symbol_in_progress
!= NULL
) {
720 as_warn(".def pseudo-op used inside of .def/.endef: ignored.");
721 demand_empty_rest_of_line();
723 } /* if not inside .def/.endef */
727 def_symbol_in_progress
= (symbolS
*) obstack_alloc(¬es
, sizeof(*def_symbol_in_progress
));
728 bzero(def_symbol_in_progress
, sizeof(*def_symbol_in_progress
));
730 symbol_name
= input_line_pointer
;
731 name_end
= get_symbol_end();
732 symbol_name_length
= strlen(symbol_name
);
733 symbol_name_copy
= xmalloc(symbol_name_length
+ 1);
734 strcpy(symbol_name_copy
, symbol_name
);
736 /* Initialize the new symbol */
737 #ifdef STRIP_UNDERSCORE
738 S_SET_NAME(def_symbol_in_progress
, (*symbol_name_copy
== '_'
739 ? symbol_name_copy
+ 1
740 : symbol_name_copy
));
741 #else /* STRIP_UNDERSCORE */
742 S_SET_NAME(def_symbol_in_progress
, symbol_name_copy
);
743 #endif /* STRIP_UNDERSCORE */
744 /* free(symbol_name_copy); */
745 def_symbol_in_progress
->sy_name_offset
= ~0;
746 def_symbol_in_progress
->sy_number
= ~0;
747 def_symbol_in_progress
->sy_frag
= &zero_address_frag
;
749 if (S_IS_STRING(def_symbol_in_progress
)) {
750 SF_SET_STRING(def_symbol_in_progress
);
753 *input_line_pointer
= name_end
;
755 demand_empty_rest_of_line();
757 } /* obj_coff_def() */
759 unsigned int dim_index
;
761 DEFUN_VOID(obj_coff_endef
)
763 symbolS
*symbolP
= 0;
764 /* DIM BUG FIX sac@cygnus.com */
766 if (def_symbol_in_progress
== NULL
) {
767 as_warn(".endef pseudo-op used outside of .def/.endef: ignored.");
768 demand_empty_rest_of_line();
770 } /* if not inside .def/.endef */
772 /* Set the section number according to storage class. */
773 switch (S_GET_STORAGE_CLASS(def_symbol_in_progress
)) {
777 SF_SET_TAG(def_symbol_in_progress
);
778 /* intentional fallthrough */
781 SF_SET_DEBUG(def_symbol_in_progress
);
782 S_SET_SEGMENT(def_symbol_in_progress
, SEG_DEBUG
);
786 SF_SET_LOCAL(def_symbol_in_progress
); /* Do not emit this symbol. */
787 /* intentional fallthrough */
789 SF_SET_PROCESS(def_symbol_in_progress
); /* Will need processing before writing */
790 /* intentional fallthrough */
792 S_SET_SEGMENT(def_symbol_in_progress
, SEG_E0
);
794 if (def_symbol_in_progress
->sy_symbol
.ost_entry
.n_name
[1] == 'b') { /* .bf */
795 if (function_lineoff
< 0) {
796 fprintf(stderr
, "`.bf' symbol without preceding function\n");
797 } /* missing function symbol */
798 SA_GET_SYM_LNNOPTR(def_symbol_in_progress
) = function_lineoff
;
799 SF_SET_PROCESS(def_symbol_in_progress
); /* Will need relocating */
800 function_lineoff
= -1;
806 #endif /* C_AUTOARG */
816 SF_SET_DEBUG(def_symbol_in_progress
);
817 S_SET_SEGMENT(def_symbol_in_progress
, SEG_ABSOLUTE
);
823 /* Valid but set somewhere else (s_comm, s_lcomm, colon) */
829 as_warn("unexpected storage class %d", S_GET_STORAGE_CLASS(def_symbol_in_progress
));
831 } /* switch on storage class */
833 /* Now that we have built a debug symbol, try to
834 find if we should merge with an existing symbol
835 or not. If a symbol is C_EFCN or SEG_ABSOLUTE or
836 untagged SEG_DEBUG it never merges. */
838 /* Two cases for functions. Either debug followed
839 by definition or definition followed by debug.
840 For definition first, we will merge the debug
841 symbol into the definition. For debug first, the
842 lineno entry MUST point to the definition
843 function or else it will point off into space
844 when crawl_symbols() merges the debug
845 symbol into the real symbol. Therefor, let's
846 presume the debug symbol is a real function
849 /* FIXME-SOON If for some reason the definition
850 label/symbol is never seen, this will probably
851 leave an undefined symbol at link time. */
853 if (S_GET_STORAGE_CLASS(def_symbol_in_progress
) == C_EFCN
854 || (S_GET_SEGMENT(def_symbol_in_progress
) == SEG_DEBUG
855 && !SF_GET_TAG(def_symbol_in_progress
))
856 || S_GET_SEGMENT(def_symbol_in_progress
) == SEG_ABSOLUTE
857 || (symbolP
= symbol_find_base(S_GET_NAME(def_symbol_in_progress
), DO_NOT_STRIP
)) == NULL
) {
859 symbol_append(def_symbol_in_progress
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
862 /* This symbol already exists, merge the
863 newly created symbol into the old one.
864 This is not mandatory. The linker can
865 handle duplicate symbols correctly. But I
866 guess that it save a *lot* of space if
867 the assembly file defines a lot of
870 /* The debug entry (def_symbol_in_progress)
871 is merged into the previous definition. */
873 c_symbol_merge(def_symbol_in_progress
, symbolP
);
874 /* FIXME-SOON Should *def_symbol_in_progress be free'd? xoxorich. */
875 def_symbol_in_progress
= symbolP
;
877 if (SF_GET_FUNCTION(def_symbol_in_progress
)
878 || SF_GET_TAG(def_symbol_in_progress
)) {
879 /* For functions, and tags, the symbol *must* be where the debug symbol
880 appears. Move the existing symbol to the current place. */
881 /* If it already is at the end of the symbol list, do nothing */
882 if (def_symbol_in_progress
!= symbol_lastP
) {
883 symbol_remove(def_symbol_in_progress
, &symbol_rootP
, &symbol_lastP
);
884 symbol_append(def_symbol_in_progress
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
885 } /* if not already in place */
887 } /* normal or mergable */
889 if (SF_GET_TAG(def_symbol_in_progress
)
890 && symbol_find_base(S_GET_NAME(def_symbol_in_progress
), DO_NOT_STRIP
) == NULL
) {
891 tag_insert(S_GET_NAME(def_symbol_in_progress
), def_symbol_in_progress
);
892 } /* If symbol is a {structure,union} tag, associate symbol to its name. */
894 if (SF_GET_FUNCTION(def_symbol_in_progress
)) {
895 know(sizeof(def_symbol_in_progress
) <= sizeof(long));
898 def_symbol_in_progress
,0, 0, &zero_address_frag
);
902 SF_SET_PROCESS(def_symbol_in_progress
);
904 if (symbolP
== NULL
) {
905 /* That is, if this is the first
906 time we've seen the function... */
907 symbol_table_insert(def_symbol_in_progress
);
908 } /* definition follows debug */
909 } /* Create the line number entry pointing to the function being defined */
911 def_symbol_in_progress
= NULL
;
912 demand_empty_rest_of_line();
914 } /* obj_coff_endef() */
917 DEFUN_VOID(obj_coff_dim
)
919 register int dim_index
;
921 if (def_symbol_in_progress
== NULL
)
923 as_warn(".dim pseudo-op used outside of .def/.endef: ignored.");
924 demand_empty_rest_of_line();
926 } /* if not inside .def/.endef */
928 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
930 for (dim_index
= 0; dim_index
< DIMNUM
; dim_index
++)
933 SA_SET_SYM_DIMEN(def_symbol_in_progress
, dim_index
, get_absolute_expression());
935 switch (*input_line_pointer
)
939 input_line_pointer
++;
943 as_warn("badly formed .dim directive ignored");
944 /* intentional fallthrough */
949 } /* switch on following character */
950 } /* for each dimension */
952 demand_empty_rest_of_line();
954 } /* obj_coff_dim() */
956 static void obj_coff_line() {
957 if (def_symbol_in_progress
== NULL
) {
960 } /* if it looks like a stabs style line */
962 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
963 SA_SET_SYM_LNNO(def_symbol_in_progress
, get_absolute_expression());
965 demand_empty_rest_of_line();
967 } /* obj_coff_line() */
969 static void obj_coff_size() {
970 if (def_symbol_in_progress
== NULL
) {
971 as_warn(".size pseudo-op used outside of .def/.endef ignored.");
972 demand_empty_rest_of_line();
974 } /* if not inside .def/.endef */
976 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
977 SA_SET_SYM_SIZE(def_symbol_in_progress
, get_absolute_expression());
978 demand_empty_rest_of_line();
980 } /* obj_coff_size() */
982 static void obj_coff_scl() {
983 if (def_symbol_in_progress
== NULL
) {
984 as_warn(".scl pseudo-op used outside of .def/.endef ignored.");
985 demand_empty_rest_of_line();
987 } /* if not inside .def/.endef */
989 S_SET_STORAGE_CLASS(def_symbol_in_progress
, get_absolute_expression());
990 demand_empty_rest_of_line();
992 } /* obj_coff_scl() */
994 static void obj_coff_tag() {
998 if (def_symbol_in_progress
== NULL
) {
999 as_warn(".tag pseudo-op used outside of .def/.endef ignored.");
1000 demand_empty_rest_of_line();
1002 } /* if not inside .def/.endef */
1004 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1005 symbol_name
= input_line_pointer
;
1006 name_end
= get_symbol_end();
1008 /* Assume that the symbol referred to by .tag is always defined. */
1009 /* This was a bad assumption. I've added find_or_make. xoxorich. */
1010 SA_SET_SYM_TAGNDX(def_symbol_in_progress
, (long) tag_find_or_make(symbol_name
));
1011 if (SA_GET_SYM_TAGNDX(def_symbol_in_progress
) == 0L) {
1012 as_warn("tag not found for .tag %s", symbol_name
);
1015 SF_SET_TAGGED(def_symbol_in_progress
);
1016 *input_line_pointer
= name_end
;
1018 demand_empty_rest_of_line();
1020 } /* obj_coff_tag() */
1022 static void obj_coff_type() {
1023 if (def_symbol_in_progress
== NULL
) {
1024 as_warn(".type pseudo-op used outside of .def/.endef ignored.");
1025 demand_empty_rest_of_line();
1027 } /* if not inside .def/.endef */
1029 S_SET_DATA_TYPE(def_symbol_in_progress
, get_absolute_expression());
1031 if (ISFCN(S_GET_DATA_TYPE(def_symbol_in_progress
)) &&
1032 S_GET_STORAGE_CLASS(def_symbol_in_progress
) != C_TPDEF
) {
1033 SF_SET_FUNCTION(def_symbol_in_progress
);
1034 } /* is a function */
1036 demand_empty_rest_of_line();
1038 } /* obj_coff_type() */
1040 static void obj_coff_val() {
1041 if (def_symbol_in_progress
== NULL
) {
1042 as_warn(".val pseudo-op used outside of .def/.endef ignored.");
1043 demand_empty_rest_of_line();
1045 } /* if not inside .def/.endef */
1047 if (is_name_beginner(*input_line_pointer
)) {
1048 char *symbol_name
= input_line_pointer
;
1049 char name_end
= get_symbol_end();
1051 if (!strcmp(symbol_name
, ".")) {
1052 def_symbol_in_progress
->sy_frag
= frag_now
;
1053 S_SET_VALUE(def_symbol_in_progress
, obstack_next_free(&frags
) - frag_now
->fr_literal
);
1054 /* If the .val is != from the .def (e.g. statics) */
1055 } else if (strcmp(S_GET_NAME(def_symbol_in_progress
), symbol_name
)) {
1056 def_symbol_in_progress
->sy_forward
= symbol_find_or_make(symbol_name
);
1058 /* If the segment is undefined when the forward
1059 reference is solved, then copy the segment id
1060 from the forward symbol. */
1061 SF_SET_GET_SEGMENT(def_symbol_in_progress
);
1063 /* Otherwise, it is the name of a non debug symbol and its value will be calculated later. */
1064 *input_line_pointer
= name_end
;
1066 S_SET_VALUE(def_symbol_in_progress
, get_absolute_expression());
1067 } /* if symbol based */
1069 demand_empty_rest_of_line();
1071 } /* obj_coff_val() */
1074 * Maintain a list of the tagnames of the structres.
1077 static void tag_init() {
1078 tag_hash
= hash_new();
1082 static void tag_insert(name
, symbolP
)
1086 register char * error_string
;
1088 if (*(error_string
= hash_jam(tag_hash
, name
, (char *)symbolP
))) {
1089 as_fatal("Inserting \"%s\" into structure table failed: %s",
1090 name
, error_string
);
1093 } /* tag_insert() */
1095 static symbolS
*tag_find_or_make(name
)
1100 if ((symbolP
= tag_find(name
)) == NULL
) {
1101 symbolP
= symbol_new(name
,
1104 &zero_address_frag
);
1106 tag_insert(S_GET_NAME(symbolP
), symbolP
);
1107 symbol_table_insert(symbolP
);
1111 } /* tag_find_or_make() */
1113 static symbolS
*tag_find(name
)
1116 #ifdef STRIP_UNDERSCORE
1117 if (*name
== '_') name
++;
1118 #endif /* STRIP_UNDERSCORE */
1119 return((symbolS
*)hash_find(tag_hash
, name
));
1122 void obj_read_begin_hook() {
1123 /* These had better be the same. Usually 18 bytes. */
1125 know(sizeof(SYMENT
) == sizeof(AUXENT
));
1126 know(SYMESZ
== AUXESZ
);
1131 } /* obj_read_begin_hook() */
1133 /* This function runs through the symbol table and puts all the
1134 externals onto another chain */
1136 /* The chain of externals */
1137 symbolS
*symbol_externP
= NULL
;
1138 symbolS
*symbol_extern_lastP
= NULL
;
1141 symbolS
*last_functionP
= NULL
;
1145 static unsigned int DEFUN_VOID(yank_symbols
)
1148 unsigned int symbol_number
=0;
1150 for (symbolP
= symbol_rootP
;
1152 symbolP
= symbolP
? symbol_next(symbolP
) : symbol_rootP
) {
1153 if (!SF_GET_DEBUG(symbolP
)) {
1154 /* Debug symbols do not need all this rubbish */
1155 symbolS
* real_symbolP
;
1157 /* L* and C_EFCN symbols never merge. */
1158 if (!SF_GET_LOCAL(symbolP
)
1159 && (real_symbolP
= symbol_find_base(S_GET_NAME(symbolP
), DO_NOT_STRIP
))
1160 && real_symbolP
!= symbolP
) {
1161 /* FIXME-SOON: where do dups come from?
1162 Maybe tag references before definitions? xoxorich. */
1163 /* Move the debug data from the debug symbol to the
1164 real symbol. Do NOT do the oposite (i.e. move from
1165 real symbol to debug symbol and remove real symbol from the
1166 list.) Because some pointers refer to the real symbol
1167 whereas no pointers refer to the debug symbol. */
1168 c_symbol_merge(symbolP
, real_symbolP
);
1169 /* Replace the current symbol by the real one */
1170 /* The symbols will never be the last or the first
1171 because : 1st symbol is .file and 3 last symbols are
1172 .text, .data, .bss */
1173 symbol_remove(real_symbolP
, &symbol_rootP
, &symbol_lastP
);
1174 symbol_insert(real_symbolP
, symbolP
, &symbol_rootP
, &symbol_lastP
);
1175 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1176 symbolP
= real_symbolP
;
1177 } /* if not local but dup'd */
1179 if (flagseen
['R'] && (S_GET_SEGMENT(symbolP
) == SEG_E1
)) {
1180 S_SET_SEGMENT(symbolP
, SEG_E0
);
1181 } /* push data into text */
1183 S_SET_VALUE(symbolP
,
1184 S_GET_VALUE(symbolP
) + symbolP
->sy_frag
->fr_address
);
1186 if (!S_IS_DEFINED(symbolP
) && !SF_GET_LOCAL(symbolP
))
1188 S_SET_EXTERNAL(symbolP
);
1190 else if (S_GET_STORAGE_CLASS(symbolP
) == C_NULL
)
1192 if (S_GET_SEGMENT(symbolP
) == SEG_E0
)
1194 S_SET_STORAGE_CLASS(symbolP
, C_LABEL
);
1198 S_SET_STORAGE_CLASS(symbolP
, C_STAT
);
1202 /* Mainly to speed up if not -g */
1203 if (SF_GET_PROCESS(symbolP
))
1205 /* Handle the nested blocks auxiliary info. */
1206 if (S_GET_STORAGE_CLASS(symbolP
) == C_BLOCK
) {
1207 if (!strcmp(S_GET_NAME(symbolP
), ".bb"))
1208 stack_push(block_stack
, (char *) &symbolP
);
1210 register symbolS
* begin_symbolP
;
1211 begin_symbolP
= *(symbolS
**)stack_pop(block_stack
);
1212 if (begin_symbolP
== (symbolS
*)0)
1213 as_warn("mismatched .eb");
1215 SA_SET_SYM_ENDNDX(begin_symbolP
, symbol_number
+2);
1218 /* If we are able to identify the type of a function, and we
1219 are out of a function (last_functionP == 0) then, the
1220 function symbol will be associated with an auxiliary
1222 if (last_functionP
== (symbolS
*)0 &&
1223 SF_GET_FUNCTION(symbolP
)) {
1224 last_functionP
= symbolP
;
1226 if (S_GET_NUMBER_AUXILIARY(symbolP
) < 1) {
1227 S_SET_NUMBER_AUXILIARY(symbolP
, 1);
1228 } /* make it at least 1 */
1230 /* Clobber possible stale .dim information. */
1231 bzero(symbolP
->sy_symbol
.ost_auxent
[0].x_sym
.x_fcnary
.x_ary
.x_dimen
,
1232 sizeof(symbolP
->sy_symbol
.ost_auxent
[0].x_sym
.x_fcnary
.x_ary
.x_dimen
));
1234 /* The C_FCN doesn't need any additional information.
1235 I don't even know if this is needed for sdb. But the
1236 standard assembler generates it, so...
1238 if (S_GET_STORAGE_CLASS(symbolP
) == C_EFCN
) {
1239 if (last_functionP
== (symbolS
*)0)
1240 as_fatal("C_EFCN symbol out of scope");
1241 SA_SET_SYM_FSIZE(last_functionP
,
1242 (long)(S_GET_VALUE(symbolP
) -
1243 S_GET_VALUE(last_functionP
)));
1244 SA_SET_SYM_ENDNDX(last_functionP
, symbol_number
);
1245 last_functionP
= (symbolS
*)0;
1248 } else if (SF_GET_TAG(symbolP
)) {
1249 /* First descriptor of a structure must point to
1250 the first slot after the structure description. */
1251 last_tagP
= symbolP
;
1253 } else if (S_GET_STORAGE_CLASS(symbolP
) == C_EOS
) {
1254 /* +2 take in account the current symbol */
1255 SA_SET_SYM_ENDNDX(last_tagP
, symbol_number
+ 2);
1256 } else if (S_GET_STORAGE_CLASS(symbolP
) == C_FILE
) {
1257 if (S_GET_VALUE(symbolP
)) {
1258 S_SET_VALUE((symbolS
*) S_GET_VALUE(symbolP
), symbol_number
);
1259 S_SET_VALUE(symbolP
, 0);
1260 } /* no one points at the first .file symbol */
1261 } /* if debug or tag or eos or file */
1263 /* We must put the external symbols apart. The loader
1264 does not bomb if we do not. But the references in
1265 the endndx field for a .bb symbol are not corrected
1266 if an external symbol is removed between .bb and .be.
1267 I.e in the following case :
1268 [20] .bb endndx = 22
1271 ld will move the symbol 21 to the end of the list but
1272 endndx will still be 22 instead of 21. */
1275 if (SF_GET_LOCAL(symbolP
)) {
1276 /* remove C_EFCN and LOCAL (L...) symbols */
1277 /* next pointer remains valid */
1278 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1281 else if (!S_IS_DEFINED(symbolP
)
1282 && !S_IS_DEBUG(symbolP
)
1283 && !SF_GET_STATICS(symbolP
) &&
1284 S_GET_STORAGE_CLASS(symbolP
) == C_EXT
)
1285 { /* C_EXT && !SF_GET_FUNCTION(symbolP)) */
1286 /* if external, Remove from the list */
1287 symbolS
*hold
= symbol_previous(symbolP
);
1289 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1290 symbol_clear_list_pointers(symbolP
);
1291 symbol_append(symbolP
, symbol_extern_lastP
, &symbol_externP
, &symbol_extern_lastP
);
1294 if (SF_GET_STRING(symbolP
)) {
1295 symbolP
->sy_name_offset
= string_byte_count
;
1296 string_byte_count
+= strlen(S_GET_NAME(symbolP
)) + 1;
1298 symbolP
->sy_name_offset
= 0;
1299 } /* fix "long" names */
1301 symbolP
->sy_number
= symbol_number
;
1302 symbol_number
+= 1 + S_GET_NUMBER_AUXILIARY(symbolP
);
1303 } /* if local symbol */
1304 } /* traverse the symbol list */
1305 return symbol_number
;
1310 static unsigned int DEFUN_VOID(glue_symbols
)
1312 unsigned int symbol_number
= 0;
1314 for (symbolP
= symbol_externP
; symbol_externP
;) {
1315 symbolS
*tmp
= symbol_externP
;
1318 symbol_remove(tmp
, &symbol_externP
, &symbol_extern_lastP
);
1319 symbol_append(tmp
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
1322 if (SF_GET_STRING(tmp
)) {
1323 tmp
->sy_name_offset
= string_byte_count
;
1324 string_byte_count
+= strlen(S_GET_NAME(tmp
)) + 1;
1326 tmp
->sy_name_offset
= 0;
1327 } /* fix "long" names */
1329 tmp
->sy_number
= symbol_number
;
1330 symbol_number
+= 1 + S_GET_NUMBER_AUXILIARY(tmp
);
1331 } /* append the entire extern chain */
1332 return symbol_number
;
1336 static unsigned int DEFUN_VOID(tie_tags
)
1338 unsigned int symbol_number
= 0;
1341 for (symbolP
= symbol_rootP
; symbolP
; symbolP
=
1342 symbol_next(symbolP
))
1344 symbolP
->sy_number
= symbol_number
;
1348 if (SF_GET_TAGGED(symbolP
))
1352 ((symbolS
*) SA_GET_SYM_TAGNDX(symbolP
))->sy_number
);
1355 symbol_number
+= 1 + S_GET_NUMBER_AUXILIARY(symbolP
);
1357 return symbol_number
;
1362 DEFUN(crawl_symbols
,(headers
, abfd
),
1363 struct internal_filehdr
*headers AND
1368 unsigned int ptr
= 0;
1373 /* Initialize the stack used to keep track of the matching .bb .be */
1375 block_stack
= stack_init(512, sizeof(symbolS
*));
1376 /* JF deal with forward references first... */
1377 for (symbolP
= symbol_rootP
;
1379 symbolP
= symbol_next(symbolP
))
1382 if (symbolP
->sy_forward
) {
1383 S_SET_VALUE(symbolP
, (S_GET_VALUE(symbolP
)
1384 + S_GET_VALUE(symbolP
->sy_forward
)
1385 + symbolP
->sy_forward
->sy_frag
->fr_address
));
1387 if (SF_GET_GET_SEGMENT(symbolP
)) {
1388 S_SET_SEGMENT(symbolP
, S_GET_SEGMENT(symbolP
->sy_forward
));
1389 } /* forward segment also */
1391 symbolP
->sy_forward
=0;
1392 } /* if it has a forward reference */
1393 } /* walk the symbol chain */
1396 /* The symbol list should be ordered according to the following sequence
1399 * . debug entries for functions
1400 * . fake symbols for the sections, including.text .data and .bss
1402 * . undefined symbols
1403 * But this is not mandatory. The only important point is to put the
1404 * undefined symbols at the end of the list.
1407 if (symbol_rootP
== NULL
1408 || S_GET_STORAGE_CLASS(symbol_rootP
) != C_FILE
) {
1409 c_dot_file_symbol("fake");
1411 /* Is there a .file symbol ? If not insert one at the beginning. */
1414 * Build up static symbols for the sections, they are filled in later
1418 for (i
= SEG_E0
; i
< SEG_E9
; i
++)
1420 if (segment_info
[i
].scnhdr
.s_name
[0])
1422 segment_info
[i
].dot
=
1423 c_section_symbol(segment_info
[i
].scnhdr
.s_name
,
1430 /* Take all the externals out and put them into another chain */
1431 headers
->f_nsyms
= yank_symbols();
1432 /* Take the externals and glue them onto the end.*/
1433 headers
->f_nsyms
+= glue_symbols();
1435 headers
->f_nsyms
= tie_tags();
1436 know(symbol_externP
== NULL
);
1437 know(symbol_extern_lastP
== NULL
);
1443 * Find strings by crawling along symbol table chain.
1446 void DEFUN(w_strings
,(where
),
1451 /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
1452 md_number_to_chars(where
, string_byte_count
, sizeof(string_byte_count
));
1453 where
+= sizeof(string_byte_count
);
1454 for (symbolP
= symbol_rootP
;
1456 symbolP
= symbol_next(symbolP
))
1460 if (SF_GET_STRING(symbolP
)) {
1461 size
= strlen(S_GET_NAME(symbolP
)) + 1;
1463 memcpy(where
, S_GET_NAME(symbolP
),size
);
1476 DEFUN(do_linenos_for
,(abfd
, file_cursor
),
1478 unsigned long *file_cursor
)
1482 for (idx
= SEG_E0
; idx
< SEG_E9
; idx
++)
1484 segment_info_type
*s
= segment_info
+ idx
;
1486 if (s
->scnhdr
.s_nlnno
!= 0)
1488 struct lineno_list
*line_ptr
;
1490 struct external_lineno
*buffer
=
1491 (struct external_lineno
*)xmalloc(s
->scnhdr
.s_nlnno
* LINESZ
);
1493 struct external_lineno
*dst
= buffer
;
1495 /* Run through the table we've built and turn it into its external
1498 for (line_ptr
= s
->lineno_list_head
;
1499 line_ptr
!= (struct lineno_list
*)NULL
;
1500 line_ptr
= line_ptr
->next
)
1502 if (line_ptr
->line
.l_lnno
== 0)
1504 /* Turn a pointer to a symbol into the symbols' index */
1505 line_ptr
->line
.l_addr
.l_symndx
=
1506 ( (symbolS
*)line_ptr
->line
.l_addr
.l_symndx
)->sy_number
;
1508 (void) bfd_coff_swap_lineno_out(abfd
, &(line_ptr
->line
), dst
);
1512 s
->scnhdr
.s_lnnoptr
= *file_cursor
;
1514 bfd_write(buffer
, 1, s
->scnhdr
.s_nlnno
* LINESZ
, abfd
);
1517 *file_cursor
+= s
->scnhdr
.s_nlnno
* LINESZ
;
1523 /* Now we run through the list of frag chains in a segment and
1524 make all the subsegment frags appear at the end of the
1525 list, as if the seg 0 was extra long */
1527 static void DEFUN_VOID(remove_subsegs
)
1531 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1533 frchainS
*head
= segment_info
[i
].frchainP
;
1535 fragS
* prev_frag
= &dummy
;
1537 while (head
&& head
->frch_seg
== i
)
1539 prev_frag
->fr_next
= head
->frch_root
;
1540 prev_frag
= head
->frch_last
;
1541 head
= head
->frch_next
;
1543 prev_frag
->fr_next
= 0;
1548 extern void DEFUN_VOID(write_object_file
)
1551 struct frchain
*frchain_ptr
;
1553 struct internal_filehdr filehdr
;
1554 struct internal_aouthdr aouthdr
;
1555 unsigned long file_cursor
;
1557 unsigned int addr
= 0;
1558 abfd
= bfd_openw(out_file_name
, TARGET_FORMAT
);
1562 as_perror ("FATAL: Can't create %s", out_file_name
);
1565 bfd_set_format(abfd
, bfd_object
);
1566 bfd_set_arch_mach(abfd
, BFD_ARCH
, 0);
1570 string_byte_count
= 4;
1572 for (frchain_ptr
= frchain_root
;
1573 frchain_ptr
!= (struct frchain
*)NULL
;
1574 frchain_ptr
= frchain_ptr
->frch_next
) {
1575 /* Run through all the sub-segments and align them up. Also close any
1576 open frags. We tack a .fill onto the end of the frag chain so
1577 that any .align's size can be worked by looking at the next
1580 subseg_new(frchain_ptr
->frch_seg
, frchain_ptr
->frch_subseg
);
1581 #define SUB_SEGMENT_ALIGN 1
1582 frag_align(SUB_SEGMENT_ALIGN
,0);
1583 frag_wane(frag_now
);
1584 frag_now
->fr_fix
= 0;
1585 know( frag_now
->fr_next
== NULL
);
1592 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1594 relax_segment(segment_info
[i
].frchainP
->frch_root
, i
);
1601 filehdr
.f_nscns
= 0;
1603 /* Find out how big the sections are */
1604 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1607 if (segment_info
[i
].scnhdr
.s_name
[0])
1611 segment_info
[i
].scnhdr
.s_paddr
= addr
;
1613 /* THis is a special case, we leave the size alone, which will have */
1614 /* been made up from all and any lcomms seen */
1617 addr
+= size_section(abfd
, i
);
1623 /* Turn the gas native symbol table shape into a coff symbol table */
1624 crawl_symbols(&filehdr
, abfd
);
1626 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1628 fixup_segment(segment_info
[i
].fix_root
, i
);
1631 file_cursor
= FILHSZ
+ SCNHSZ
* filehdr
.f_nscns
;
1633 bfd_seek(abfd
, file_cursor
, 0);
1636 do_relocs_for(abfd
, &file_cursor
);
1638 do_linenos_for(abfd
, &file_cursor
);
1641 /* Plant the data */
1643 fill_section(abfd
,&filehdr
, &file_cursor
);
1645 filehdr
.f_magic
= COFF_MAGIC
;
1646 filehdr
.f_timdat
= 0;
1647 filehdr
.f_flags
= 0;
1653 unsigned int symtable_size
= filehdr
.f_nsyms
* SYMESZ
;
1654 char *buffer1
= malloc(symtable_size
+ string_byte_count
+ 4);
1655 char *ptr
= buffer1
;
1656 filehdr
.f_symptr
= bfd_tell(abfd
);
1657 w_symbols(abfd
, buffer1
, symbol_rootP
);
1658 w_strings(buffer1
+ symtable_size
);
1659 bfd_write(buffer1
, 1,symtable_size
+ string_byte_count
+ 4, abfd
);
1663 coff_header_append(abfd
, &filehdr
, &aouthdr
);
1665 bfd_close_all_done(abfd
);
1669 static void DEFUN(change_to_section
,(name
, len
, exp
),
1671 unsigned int len AND
1675 /* Find out if we've already got a section of this name etc */
1676 for(i
= SEG_E0
; i
< SEG_E9
&& segment_info
[i
].scnhdr
.s_name
[0] ; i
++)
1678 if (strncmp(segment_info
[i
].scnhdr
.s_name
, name
, len
) == 0)
1685 /* No section, add one */
1686 strncpy(segment_info
[i
].scnhdr
.s_name
, name
, 8);
1691 DEFUN_VOID(obj_coff_section
)
1693 /* Strip out the section name */
1694 char *section_name
;
1695 char *section_name_end
;
1701 section_name
= input_line_pointer
;
1702 c
= get_symbol_end();
1703 section_name_end
= input_line_pointer
;
1705 len
= section_name_end
- section_name
;
1706 input_line_pointer
++;
1710 exp
= get_absolute_expression();
1712 else if ( *input_line_pointer
== ',')
1715 input_line_pointer
++;
1716 exp
= get_absolute_expression();
1723 change_to_section(section_name
, len
,exp
);
1728 static void obj_coff_text()
1730 change_to_section(".text",5, get_absolute_expression());
1734 static void obj_coff_data()
1736 change_to_section(".data",5, get_absolute_expression());
1739 void c_symbol_merge(debug
, normal
)
1743 S_SET_DATA_TYPE(normal
, S_GET_DATA_TYPE(debug
));
1744 S_SET_STORAGE_CLASS(normal
, S_GET_STORAGE_CLASS(debug
));
1746 if (S_GET_NUMBER_AUXILIARY(debug
) > S_GET_NUMBER_AUXILIARY(normal
)) {
1747 S_SET_NUMBER_AUXILIARY(normal
, S_GET_NUMBER_AUXILIARY(debug
));
1748 } /* take the most we have */
1750 if (S_GET_NUMBER_AUXILIARY(debug
) > 0) {
1751 memcpy((char*)&normal
->sy_symbol
.ost_auxent
[0], (char*)&debug
->sy_symbol
.ost_auxent
[0], S_GET_NUMBER_AUXILIARY(debug
) * AUXESZ
);
1752 } /* Move all the auxiliary information */
1754 /* Move the debug flags. */
1755 SF_SET_DEBUG_FIELD(normal
, SF_GET_DEBUG_FIELD(debug
));
1756 } /* c_symbol_merge() */
1759 DEFUN(c_line_new
,(symbol
, paddr
, line_number
, frag
),
1762 unsigned short line_number AND
1765 struct lineno_list
* new_line
=
1766 (struct lineno_list
*)xmalloc(sizeof(struct lineno_list
));
1768 segment_info_type
*s
= segment_info
+ now_seg
;
1769 new_line
->line
.l_lnno
= line_number
;
1770 if (line_number
== 0)
1772 new_line
->line
.l_addr
.l_symndx
= (long)symbol
;
1776 new_line
->line
.l_addr
.l_paddr
= paddr
;
1779 new_line
->frag
= (char*)frag
;
1780 new_line
->next
= (struct lineno_list
*)NULL
;
1783 if (s
->lineno_list_head
== (struct lineno_list
*)NULL
)
1785 s
->lineno_list_head
= new_line
;
1789 s
->lineno_list_tail
->next
= new_line
;
1791 s
->lineno_list_tail
= new_line
;
1792 return LINESZ
* s
->scnhdr
.s_nlnno
++;
1795 void c_dot_file_symbol(filename
)
1800 symbolP
= symbol_new(".file",
1803 &zero_address_frag
);
1805 S_SET_STORAGE_CLASS(symbolP
, C_FILE
);
1806 S_SET_NUMBER_AUXILIARY(symbolP
, 1);
1807 SA_SET_FILE_FNAME(symbolP
, filename
);
1808 SF_SET_DEBUG(symbolP
);
1809 S_SET_VALUE(symbolP
, (long) previous_file_symbol
);
1811 previous_file_symbol
= symbolP
;
1813 /* Make sure that the symbol is first on the symbol chain */
1814 if (symbol_rootP
!= symbolP
) {
1815 if (symbolP
== symbol_lastP
) {
1816 symbol_lastP
= symbol_lastP
->sy_previous
;
1817 } /* if it was the last thing on the list */
1819 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1820 symbol_insert(symbolP
, symbol_rootP
, &symbol_rootP
, &symbol_lastP
);
1821 symbol_rootP
= symbolP
;
1822 } /* if not first on the list */
1824 } /* c_dot_file_symbol() */
1827 * Build a 'section static' symbol.
1830 symbolS
*c_section_symbol(name
,idx
)
1836 symbolP
= symbol_new(name
,idx
,
1838 &zero_address_frag
);
1840 S_SET_STORAGE_CLASS(symbolP
, C_STAT
);
1841 S_SET_NUMBER_AUXILIARY(symbolP
, 1);
1843 SF_SET_STATICS(symbolP
);
1846 } /* c_section_symbol() */
1849 DEFUN(w_symbols
,(abfd
, where
, symbol_rootP
),
1852 symbolS
*symbol_rootP
)
1857 /* First fill in those values we have only just worked out */
1858 for (i
= SEG_E0
; i
< SEG_E9
; i
++)
1860 symbolP
= segment_info
[i
].dot
;
1864 SA_SET_SCN_SCNLEN(symbolP
, segment_info
[i
].scnhdr
.s_size
);
1865 SA_SET_SCN_NRELOC(symbolP
, segment_info
[i
].scnhdr
.s_nreloc
);
1866 SA_SET_SCN_NLINNO(symbolP
, segment_info
[i
].scnhdr
.s_nlnno
);
1872 * Emit all symbols left in the symbol chain.
1874 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next(symbolP
)) {
1875 /* Used to save the offset of the name. It is used to point
1876 to the string in memory but must be a file offset. */
1877 register char * temp
;
1879 tc_coff_symbol_emit_hook(symbolP
);
1881 temp
= S_GET_NAME(symbolP
);
1882 if (SF_GET_STRING(symbolP
)) {
1883 S_SET_OFFSET(symbolP
, symbolP
->sy_name_offset
);
1884 S_SET_ZEROES(symbolP
, 0);
1886 bzero(symbolP
->sy_symbol
.ost_entry
.n_name
, SYMNMLEN
);
1887 strncpy(symbolP
->sy_symbol
.ost_entry
.n_name
, temp
, SYMNMLEN
);
1889 where
= symbol_to_chars(abfd
, where
, symbolP
);
1890 S_SET_NAME(symbolP
,temp
);
1895 static void DEFUN_VOID(obj_coff_lcomm
)
1902 name
= input_line_pointer
;
1906 c
= get_symbol_end();
1907 p
= input_line_pointer
;
1910 if (*input_line_pointer
!= ',') {
1911 as_bad("Expected comma after name");
1912 ignore_rest_of_line();
1915 if (*input_line_pointer
== '\n') {
1916 as_bad("Missing size expression");
1919 input_line_pointer
++;
1920 if ((temp
= get_absolute_expression ()) < 0) {
1921 as_warn("lcomm length (%d.) <0! Ignored.", temp
);
1922 ignore_rest_of_line();
1926 symbolP
= symbol_find_or_make(name
);
1927 S_SET_VALUE(symbolP
, segment_info
[SEG_E2
].scnhdr
.s_size
);
1928 S_SET_SEGMENT(symbolP
, SEG_E2
);
1929 segment_info
[SEG_E2
].scnhdr
.s_size
+= temp
;
1930 S_SET_STORAGE_CLASS(symbolP
, C_STAT
);
1931 demand_empty_rest_of_line();
1936 static void DEFUN(fixup_segment
,(fixP
, this_segment_type
),
1937 register fixS
* fixP AND
1938 segT this_segment_type
)
1940 register symbolS
*add_symbolP
;
1941 register symbolS
*sub_symbolP
;
1942 register long add_number
;
1944 register char *place
;
1945 register long where
;
1946 register char pcrel
;
1947 register fragS
*fragP
;
1948 register segT add_symbol_segment
= SEG_ABSOLUTE
;
1951 for ( ; fixP
; fixP
= fixP
->fx_next
)
1953 fragP
= fixP
->fx_frag
;
1955 where
= fixP
->fx_where
;
1956 place
= fragP
->fr_literal
+ where
;
1957 size
= fixP
->fx_size
;
1958 add_symbolP
= fixP
->fx_addsy
;
1960 if (fixP
->fx_callj
&& TC_S_IS_CALLNAME(add_symbolP
)) {
1961 /* Relocation should be done via the
1962 associated 'bal' entry point
1965 if (!TC_S_IS_BALNAME(tc_get_bal_of_call(add_symbolP
))) {
1966 as_bad("No 'bal' entry point for leafproc %s",
1967 S_GET_NAME(add_symbolP
));
1970 fixP
->fx_addsy
= add_symbolP
= tc_get_bal_of_call(add_symbolP
);
1971 } /* callj relocation */
1973 sub_symbolP
= fixP
->fx_subsy
;
1974 add_number
= fixP
->fx_offset
;
1975 pcrel
= fixP
->fx_pcrel
;
1978 add_symbol_segment
= S_GET_SEGMENT(add_symbolP
);
1979 } /* if there is an addend */
1984 if (S_GET_SEGMENT(sub_symbolP
) != SEG_ABSOLUTE
) {
1985 as_bad("Negative of non-absolute symbol %s", S_GET_NAME(sub_symbolP
));
1986 } /* not absolute */
1988 add_number
-= S_GET_VALUE(sub_symbolP
);
1990 /* if sub_symbol is in the same segment that add_symbol
1991 and add_symbol is either in DATA, TEXT, BSS or ABSOLUTE */
1992 } else if ((S_GET_SEGMENT(sub_symbolP
) == add_symbol_segment
)
1993 && (SEG_NORMAL(add_symbol_segment
)
1994 || (add_symbol_segment
== SEG_ABSOLUTE
))) {
1995 /* Difference of 2 symbols from same segment. */
1996 /* Can't make difference of 2 undefineds: 'value' means */
1997 /* something different for N_UNDF. */
1999 /* Makes no sense to use the difference of 2 arbitrary symbols
2000 * as the target of a call instruction.
2002 if (fixP
->fx_callj
) {
2003 as_bad("callj to difference of 2 symbols");
2005 #endif /* TC_I960 */
2006 add_number
+= S_GET_VALUE(add_symbolP
) -
2007 S_GET_VALUE(sub_symbolP
);
2010 fixP
->fx_addsy
= NULL
;
2012 /* Different segments in subtraction. */
2013 know(!(S_IS_EXTERNAL(sub_symbolP
) && (S_GET_SEGMENT(sub_symbolP
) == SEG_ABSOLUTE
)));
2015 if ((S_GET_SEGMENT(sub_symbolP
) == SEG_ABSOLUTE
)) {
2016 add_number
-= S_GET_VALUE(sub_symbolP
);
2018 as_bad("Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %d.",
2019 segment_name(S_GET_SEGMENT(sub_symbolP
)),
2020 S_GET_NAME(sub_symbolP
), fragP
->fr_address
+ where
);
2023 } /* if sub_symbolP */
2026 if (add_symbol_segment
== this_segment_type
&& pcrel
) {
2028 * This fixup was made when the symbol's segment was
2029 * SEG_UNKNOWN, but it is now in the local segment.
2030 * So we know how to do the address without relocation.
2033 /* reloc_callj() may replace a 'call' with a 'calls' or a 'bal',
2034 * in which cases it modifies *fixP as appropriate. In the case
2035 * of a 'calls', no further work is required, and *fixP has been
2036 * set up to make the rest of the code below a no-op.
2039 #endif /* TC_I960 */
2041 add_number
+= S_GET_VALUE(add_symbolP
);
2042 add_number
-= md_pcrel_from (fixP
);
2043 pcrel
= 0; /* Lie. Don't want further pcrel processing. */
2044 fixP
->fx_addsy
= NULL
; /* No relocations please. */
2047 switch (add_symbol_segment
)
2051 reloc_callj(fixP
); /* See comment about reloc_callj() above*/
2052 #endif /* TC_I960 */
2053 add_number
+= S_GET_VALUE(add_symbolP
);
2054 fixP
->fx_addsy
= NULL
;
2059 add_number
+= S_GET_VALUE(add_symbolP
) +
2060 segment_info
[S_GET_SEGMENT(add_symbolP
)].scnhdr
.s_paddr
;
2065 if ((int)fixP
->fx_bit_fixP
== 13) {
2066 /* This is a COBR instruction. They have only a
2067 * 13-bit displacement and are only to be used
2068 * for local branches: flag as error, don't generate
2071 as_bad("can't use COBR format with external label");
2072 fixP
->fx_addsy
= NULL
; /* No relocations please. */
2075 #endif /* TC_I960 */
2082 } /* switch on symbol seg */
2083 } /* if not in local seg */
2084 } /* if there was a + symbol */
2087 add_number
-= md_pcrel_from(fixP
);
2088 if (add_symbolP
== 0) {
2089 fixP
->fx_addsy
= & abs_symbol
;
2090 } /* if there's an add_symbol */
2093 if (!fixP
->fx_bit_fixP
) {
2095 (add_number
& ~0xFF) && (add_number
&~0xFF!=(-1&~0xFF))) ||
2097 (add_number
& ~0xFFFF) && (add_number
&~0xFFFF!=(-1&~0xFFFF)))) {
2098 as_bad("Value of %d too large for field of %d bytes at 0x%x",
2099 add_number
, size
, fragP
->fr_address
+ where
);
2100 } /* generic error checking */
2101 } /* not a bit fix */
2102 /* once this fix has been applied, we don't have to output anything
2103 nothing more need be done -*/
2104 md_apply_fix(fixP
, add_number
);
2106 } /* For each fixS in this segment. */
2109 } /* fixup_segment() */