1 /* coff object file format with bfd
2 Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc.
4 This file is part of GAS.
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
22 How does this releate to the rest of GAS ?
24 Well, all the other files in gas are more or less a black box. It
25 takes care of opening files, parsing command lines, stripping blanks
26 etc etc. This module gets a chance to register what it wants to do by
27 saying that it is interested in various pseduo ops. The other big
28 change is write_object_file. This runs through all the data
29 structures that gas builds, and outputs the file in the format of our
32 Hacked for BFDness by steve chamberlain
34 This object module now supports the Hitachi H8/300 and the AMD 29k
43 #include "../bfd/libbfd.h"
46 #define MIN(a,b) ((a) < (b)? (a) : (b))
47 /* This vector is used to turn an internal segment into a section #
48 suitable for insertion into a coff symbol table
51 const short seg_N_TYPE
[] = { /* in: segT out: N_TYPE bits */
63 C_UNDEF_SECTION
, /* SEG_UNKNOWN */
64 C_UNDEF_SECTION
, /* SEG_ABSENT */
65 C_UNDEF_SECTION
, /* SEG_PASS1 */
66 C_UNDEF_SECTION
, /* SEG_GOOF */
67 C_UNDEF_SECTION
, /* SEG_BIG */
68 C_UNDEF_SECTION
, /* SEG_DIFFERENCE */
69 C_DEBUG_SECTION
, /* SEG_DEBUG */
70 C_NTV_SECTION
, /* SEG_NTV */
71 C_PTV_SECTION
, /* SEG_PTV */
72 C_REGISTER_SECTION
, /* SEG_REGISTER */
76 int function_lineoff
= -1; /* Offset in line#s where the last function
77 started (the odd entry for line #0) */
83 static symbolS
*last_line_symbol
;
84 /* Add 4 to the real value to get the index and compensate the
85 negatives. This vector is used by S_GET_SEGMENT to turn a coff
86 section number into a segment number
88 static symbolS
*previous_file_symbol
= NULL
;
89 void c_symbol_merge();
92 symbolS
*c_section_symbol();
94 void EXFUN(bfd_as_write_hook
,(struct internal_filehdr
*,
97 static void EXFUN(fixup_segment
,(fixS
* fixP
,
98 segT this_segment_type
));
100 static void EXFUN(fill_section
,(bfd
*abfd
,
101 struct internal_filehdr
*f
, unsigned
105 char *EXFUN(s_get_name
,(symbolS
*s
));
106 static symbolS
*EXFUN(tag_find_or_make
,(char *name
));
107 static symbolS
* EXFUN(tag_find
,(char *name
));
114 unsigned short line_number
,
118 static void EXFUN(w_symbols
,
121 symbolS
*symbol_rootP
));
125 static void EXFUN( obj_coff_def
,(int what
));
126 static void EXFUN( obj_coff_lcomm
,(void));
127 static void EXFUN( obj_coff_dim
,(void));
128 static void EXFUN( obj_coff_text
,(void));
129 static void EXFUN( obj_coff_data
,(void));
130 static void EXFUN( obj_coff_endef
,(void));
131 static void EXFUN( obj_coff_line
,(void));
132 static void EXFUN( obj_coff_ln
,(void));
133 static void EXFUN( obj_coff_scl
,(void));
134 static void EXFUN( obj_coff_size
,(void));
135 static void EXFUN( obj_coff_tag
,(void));
136 static void EXFUN( obj_coff_type
,(void));
137 static void EXFUN( obj_coff_val
,(void));
138 static void EXFUN( obj_coff_section
,(void));
139 static void EXFUN( tag_init
,(void));
140 static void EXFUN( tag_insert
,(char *name
, symbolS
*symbolP
));
143 static struct hash_control
*tag_hash
;
144 static symbolS
*def_symbol_in_progress
= NULL
;
146 const pseudo_typeS obj_pseudo_table
[] = {
147 { "def", obj_coff_def
, 0 },
148 { "dim", obj_coff_dim
, 0 },
149 { "endef", obj_coff_endef
, 0 },
150 { "line", obj_coff_line
, 0 },
151 { "ln", obj_coff_ln
, 0 },
152 { "scl", obj_coff_scl
, 0 },
153 { "size", obj_coff_size
, 0 },
154 { "tag", obj_coff_tag
, 0 },
155 { "type", obj_coff_type
, 0 },
156 { "val", obj_coff_val
, 0 },
157 { "section", obj_coff_section
, 0 },
158 { "use", obj_coff_section
, 0 },
159 { "sect", obj_coff_section
, 0 },
160 { "text", obj_coff_text
, 0 },
161 { "data", obj_coff_data
, 0 },
162 /* we don't yet handle this. */
163 { "ident", s_ignore
, 0 },
164 { "ABORT", s_abort
, 0 },
165 { "lcomm", obj_coff_lcomm
, 0},
166 { NULL
} /* end sentinel */
167 }; /* obj_pseudo_table */
173 We allow more than just the standard 3 sections, infact, we allow
174 10 sections, (though the usual three have to be there).
176 This structure performs the mappings for us:
181 static struct internal_scnhdr bss_section_header;
182 struct internal_scnhdr data_section_header;
183 struct internal_scnhdr text_section_header;
185 const segT N_TYPE_seg [32] =
199 seg_info_type seg_info_off_by_4
[N_SEG
] =
225 {SEG_REGISTER
},0,0,0,0};
227 #define SEG_INFO_FROM_SECTION_NUMBER(x) (seg_info_off_by_4[(x)+4])
228 #define SEG_INFO_FROM_SEG_NUMBER(x) (seg_info_off_by_4[(x)])
232 DEFUN(relax_align
,(address
, alignment
),
233 register relax_addressT address AND
234 register long alignment
)
237 relax_addressT new_address
;
239 mask
= ~ ( (~0) << alignment
);
240 new_address
= (address
+ mask
) & (~ mask
);
241 return (new_address
- address
);
242 } /* relax_align() */
246 DEFUN(s_get_segment
,(x
) ,
249 return SEG_INFO_FROM_SECTION_NUMBER(x
->sy_symbol
.ost_entry
.n_scnum
).seg_t
;
254 /* calculate the size of the frag chain and fill in the section header
255 to contain all of it, also fill in the addr of the sections */
256 static unsigned int DEFUN(size_section
,(abfd
, idx
),
261 unsigned int size
= 0;
262 fragS
*frag
= segment_info
[idx
].frchainP
->frch_root
;
264 if (frag
->fr_address
!= size
) {
265 printf("Out of step\n");
266 size
= frag
->fr_address
;
268 size
+= frag
->fr_fix
;
269 switch (frag
->fr_type
) {
272 size
+= frag
->fr_offset
* frag
->fr_var
;
275 size
+= relax_align(size
, frag
->fr_offset
);
277 frag
= frag
->fr_next
;
279 segment_info
[idx
].scnhdr
.s_size
= size
;
284 static unsigned int DEFUN(count_entries_in_chain
,(idx
),
287 unsigned int nrelocs
;
290 /* Count the relocations */
291 fixup_ptr
= segment_info
[idx
].fix_root
;
293 while (fixup_ptr
!= (fixS
*)NULL
)
295 if (TC_COUNT_RELOC(fixup_ptr
))
300 if (fixup_ptr
->fx_r_type
== RELOC_CONSTH
)
309 fixup_ptr
= fixup_ptr
->fx_next
;
314 /* output all the relocations for a section */
315 void DEFUN(do_relocs_for
,(abfd
, file_cursor
),
317 unsigned long *file_cursor
)
319 unsigned int nrelocs
;
321 unsigned int addr
= 0;
322 for (idx
= SEG_E0
; idx
< SEG_E9
; idx
++)
324 if (segment_info
[idx
].scnhdr
.s_name
[0])
327 struct external_reloc
*ext_ptr
;
328 struct external_reloc
*external_reloc_vec
;
329 unsigned int external_reloc_size
;
330 unsigned int count
= 0;
331 unsigned int base
= addr
;
332 fixS
* fix_ptr
= segment_info
[idx
].fix_root
;
333 nrelocs
= count_entries_in_chain(idx
);
338 external_reloc_size
= nrelocs
* RELSZ
;
340 (struct external_reloc
*)malloc(external_reloc_size
);
344 ext_ptr
= external_reloc_vec
;
346 /* Fill in the internal coff style reloc struct from the
351 struct internal_reloc intr
;
353 /* Only output some of the relocations */
354 if (TC_COUNT_RELOC(fix_ptr
))
356 #ifdef TC_RELOC_MANGLE
357 TC_RELOC_MANGLE(fix_ptr
, &intr
, base
);
361 symbol_ptr
= fix_ptr
->fx_addsy
;
363 intr
.r_type
= TC_COFF_FIX2RTYPE(fix_ptr
);
365 base
+ fix_ptr
->fx_frag
->fr_address
+ fix_ptr
->fx_where
;
367 intr
.r_offset
= fix_ptr
->fx_offset
;
371 /* Turn the segment of the symbol into an offset
375 dot
= segment_info
[S_GET_SEGMENT(symbol_ptr
)].dot
;
378 intr
.r_symndx
= dot
->sy_number
;
382 intr
.r_symndx
= symbol_ptr
->sy_number
;
394 (void)bfd_coff_swap_reloc_out(abfd
, &intr
, ext_ptr
);
398 /* The 29k has a special kludge for the high 16 bit reloc.
399 Two relocations are emmited, R_IHIHALF, and
400 R_IHCONST. The second one doesn't contain a symbol,
401 but uses the value for offset */
403 if (intr
.r_type
== R_IHIHALF
)
405 /* now emit the second bit */
406 intr
.r_type
= R_IHCONST
;
407 intr
.r_symndx
= fix_ptr
->fx_addnumber
;
408 (void)bfd_coff_swap_reloc_out(abfd
,&intr
,ext_ptr
);
414 fix_ptr
= fix_ptr
->fx_next
;
417 /* Write out the reloc table */
418 segment_info
[idx
].scnhdr
.s_relptr
= *file_cursor
;
419 segment_info
[idx
].scnhdr
.s_nreloc
= nrelocs
;
420 bfd_write((PTR
)external_reloc_vec
, 1, external_reloc_size
, abfd
);
421 *file_cursor
+= external_reloc_size
;
422 free( external_reloc_vec
);
424 addr
+= segment_info
[idx
].scnhdr
.s_size
;
429 /* run through a frag chain and write out the data to go with it, fill
430 in the scnhdrs with the info on the file postions
432 static void DEFUN(fill_section
,(abfd
, filehdr
, file_cursor
),
434 struct internal_filehdr
*filehdr AND
435 unsigned long *file_cursor
)
439 unsigned int paddr
= 0;
441 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
443 unsigned int offset
= 0;
445 struct internal_scnhdr
*s
= &( segment_info
[i
].scnhdr
);
449 fragS
*frag
= segment_info
[i
].frchainP
->frch_root
;
450 char *buffer
= malloc(s
->s_size
);
453 s
->s_scnptr
= *file_cursor
;
467 s
->s_flags
= STYP_REG
;
468 if (strcmp(s
->s_name
,".text")==0)
469 s
->s_flags
|= STYP_TEXT
;
470 else if (strcmp(s
->s_name
,".data")==0)
471 s
->s_flags
|= STYP_DATA
;
472 else if (strcmp(s
->s_name
,".bss")==0)
473 s
->s_flags
|= STYP_BSS
| STYP_NOLOAD
;
474 else if (strcmp(s
->s_name
,".lit")==0)
475 s
->s_flags
= STYP_LIT
| STYP_TEXT
;
479 unsigned int fill_size
;
480 switch (frag
->fr_type
) {
487 memcpy(buffer
+ frag
->fr_address
,
490 offset
+= frag
->fr_fix
;
493 fill_size
= frag
->fr_var
;
497 unsigned int off
= frag
->fr_fix
;
498 for (count
= frag
->fr_offset
; count
; count
--)
500 memcpy(buffer
+ frag
->fr_address
+ off
,
501 frag
->fr_literal
+ frag
->fr_fix
,
513 frag
= frag
->fr_next
;
517 bfd_write(buffer
, s
->s_size
,1,abfd
);
520 *file_cursor
+= s
->s_size
;
529 /* Coff file generation & utilities */
533 DEFUN(coff_header_append
,(abfd
, filehdr
, aouthdr
),
535 struct internal_filehdr
*filehdr AND
536 struct internal_aouthdr
*aouthdr
)
542 bfd_seek(abfd
, 0, 0);
544 filehdr
.f_opthdr
= bfd_coff_swap_aouthdr_out(abfd
, aouthdr
,
547 filehdr
->f_opthdr
= 0;
549 i
= bfd_coff_swap_filehdr_out(abfd
, filehdr
, buffer
);
551 bfd_write(buffer
, i
,1, abfd
);
552 bfd_write(buffero
, filehdr
->f_opthdr
, 1, abfd
);
554 for (i
= SEG_E0
; i
< SEG_E9
; i
++)
556 if (segment_info
[i
].scnhdr
.s_name
[0])
559 bfd_coff_swap_scnhdr_out(abfd
,
560 &(segment_info
[i
].scnhdr
),
562 bfd_write(buffer
, size
, 1, abfd
);
569 DEFUN(symbol_to_chars
,(abfd
, where
, symbolP
),
574 unsigned int numaux
= symbolP
->sy_symbol
.ost_entry
.n_numaux
;
577 /* Turn any symbols with register attributes into abs symbols */
578 if (S_GET_SEGMENT(symbolP
) == SEG_REGISTER
)
580 S_SET_SEGMENT(symbolP
, SEG_ABSOLUTE
);
582 /* At the same time, relocate all symbols to their output value */
585 segment_info
[S_GET_SEGMENT(symbolP
)].scnhdr
.s_paddr
586 + S_GET_VALUE(symbolP
));
588 where
+= bfd_coff_swap_sym_out(abfd
, &symbolP
->sy_symbol
.ost_entry
,
591 for (i
= 0; i
< numaux
; i
++)
593 where
+= bfd_coff_swap_aux_out(abfd
,
594 &symbolP
->sy_symbol
.ost_auxent
[i
],
595 S_GET_DATA_TYPE(symbolP
),
596 S_GET_STORAGE_CLASS(symbolP
),
606 void obj_symbol_new_hook(symbolP
)
609 char underscore
= 0; /* Symbol has leading _ */
611 /* Effective symbol */
612 /* Store the pointer in the offset. */
613 S_SET_ZEROES(symbolP
, 0L);
614 S_SET_DATA_TYPE(symbolP
, T_NULL
);
615 S_SET_STORAGE_CLASS(symbolP
, 0);
616 S_SET_NUMBER_AUXILIARY(symbolP
, 0);
617 /* Additional information */
618 symbolP
->sy_symbol
.ost_flags
= 0;
619 /* Auxiliary entries */
620 bzero((char*)&symbolP
->sy_symbol
.ost_auxent
[0], AUXESZ
);
622 #ifdef STRIP_UNDERSCORE
623 /* Remove leading underscore at the beginning of the symbol.
624 * This is to be compatible with the standard librairies.
626 if (*S_GET_NAME(symbolP
) == '_') {
628 S_SET_NAME(symbolP
, S_GET_NAME(symbolP
) + 1);
629 } /* strip underscore */
630 #endif /* STRIP_UNDERSCORE */
632 if (S_IS_STRING(symbolP
))
633 SF_SET_STRING(symbolP
);
634 if (!underscore
&& S_IS_LOCAL(symbolP
))
635 SF_SET_LOCAL(symbolP
);
638 } /* obj_symbol_new_hook() */
641 stack
* stack_init(chunk_size
, element_size
)
642 unsigned long chunk_size
;
643 unsigned long element_size
;
647 if ((st
= (stack
*)malloc(sizeof(stack
))) == (stack
*)0)
649 if ((st
->data
= malloc(chunk_size
)) == (char*)0) {
654 st
->size
= chunk_size
;
655 st
->chunk_size
= chunk_size
;
656 st
->element_size
= element_size
;
660 void stack_delete(st
)
667 char *stack_push(st
, element
)
671 if (st
->pointer
+ st
->element_size
>= st
->size
) {
672 st
->size
+= st
->chunk_size
;
673 if ((st
->data
= xrealloc(st
->data
, st
->size
)) == (char*)0)
676 memcpy(st
->data
+ st
->pointer
, element
, st
->element_size
);
677 st
->pointer
+= st
->element_size
;
678 return st
->data
+ st
->pointer
;
684 if ((st
->pointer
-= st
->element_size
) < 0) {
689 return st
->data
+ st
->pointer
;
695 return st
->data
+ st
->pointer
- st
->element_size
;
700 * Handle .ln directives.
703 static void obj_coff_ln()
707 if (def_symbol_in_progress
!= NULL
) {
708 as_warn(".ln pseudo-op inside .def/.endef: ignored.");
709 demand_empty_rest_of_line();
711 } /* wrong context */
714 obstack_next_free(&frags
) - frag_now
->fr_literal
,
715 l
= get_absolute_expression(),
723 listing_source_line(l
+ line_base
- 1);
728 demand_empty_rest_of_line();
730 } /* obj_coff_line() */
735 * Handle .def directives.
737 * One might ask : why can't we symbol_new if the symbol does not
738 * already exist and fill it with debug information. Because of
739 * the C_EFCN special symbol. It would clobber the value of the
740 * function symbol before we have a chance to notice that it is
741 * a C_EFCN. And a second reason is that the code is more clear this
742 * way. (at least I think it is :-).
746 #define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';')
747 #define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \
748 *input_line_pointer == '\t') \
749 input_line_pointer++;
752 DEFUN(obj_coff_def
,(what
),
755 char name_end
; /* Char after the end of name */
756 char *symbol_name
; /* Name of the debug symbol */
757 char *symbol_name_copy
; /* Temporary copy of the name */
758 unsigned int symbol_name_length
;
759 /*$char* directiveP;$ */ /* Name of the pseudo opcode */
760 /*$char directive[MAX_DIRECTIVE];$ */ /* Backup of the directive */
761 /*$char end = 0;$ */ /* If 1, stop parsing */
763 if (def_symbol_in_progress
!= NULL
) {
764 as_warn(".def pseudo-op used inside of .def/.endef: ignored.");
765 demand_empty_rest_of_line();
767 } /* if not inside .def/.endef */
771 def_symbol_in_progress
= (symbolS
*) obstack_alloc(¬es
, sizeof(*def_symbol_in_progress
));
772 bzero(def_symbol_in_progress
, sizeof(*def_symbol_in_progress
));
774 symbol_name
= input_line_pointer
;
775 name_end
= get_symbol_end();
776 symbol_name_length
= strlen(symbol_name
);
777 symbol_name_copy
= xmalloc(symbol_name_length
+ 1);
778 strcpy(symbol_name_copy
, symbol_name
);
780 /* Initialize the new symbol */
781 #ifdef STRIP_UNDERSCORE
782 S_SET_NAME(def_symbol_in_progress
, (*symbol_name_copy
== '_'
783 ? symbol_name_copy
+ 1
784 : symbol_name_copy
));
785 #else /* STRIP_UNDERSCORE */
786 S_SET_NAME(def_symbol_in_progress
, symbol_name_copy
);
787 #endif /* STRIP_UNDERSCORE */
788 /* free(symbol_name_copy); */
789 def_symbol_in_progress
->sy_name_offset
= ~0;
790 def_symbol_in_progress
->sy_number
= ~0;
791 def_symbol_in_progress
->sy_frag
= &zero_address_frag
;
793 if (S_IS_STRING(def_symbol_in_progress
)) {
794 SF_SET_STRING(def_symbol_in_progress
);
797 *input_line_pointer
= name_end
;
799 demand_empty_rest_of_line();
801 } /* obj_coff_def() */
803 unsigned int dim_index
;
805 DEFUN_VOID(obj_coff_endef
)
807 symbolS
*symbolP
= 0;
808 /* DIM BUG FIX sac@cygnus.com */
810 if (def_symbol_in_progress
== NULL
) {
811 as_warn(".endef pseudo-op used outside of .def/.endef: ignored.");
812 demand_empty_rest_of_line();
814 } /* if not inside .def/.endef */
816 /* Set the section number according to storage class. */
817 switch (S_GET_STORAGE_CLASS(def_symbol_in_progress
)) {
821 SF_SET_TAG(def_symbol_in_progress
);
822 /* intentional fallthrough */
825 SF_SET_DEBUG(def_symbol_in_progress
);
826 S_SET_SEGMENT(def_symbol_in_progress
, SEG_DEBUG
);
830 SF_SET_LOCAL(def_symbol_in_progress
); /* Do not emit this symbol. */
831 /* intentional fallthrough */
833 SF_SET_PROCESS(def_symbol_in_progress
); /* Will need processing before writing */
834 /* intentional fallthrough */
836 S_SET_SEGMENT(def_symbol_in_progress
, SEG_E0
);
838 if (def_symbol_in_progress
->sy_symbol
.ost_entry
._n
._n_nptr
[1][1] == 'b'
839 && def_symbol_in_progress
->sy_symbol
.ost_entry
._n
._n_nptr
[1][2] == 'f') { /* .bf */
840 if (function_lineoff
< 0) {
841 fprintf(stderr
, "`.bf' symbol without preceding function\n");
842 } /* missing function symbol */
843 SA_GET_SYM_LNNOPTR(last_line_symbol
) = function_lineoff
;
845 SF_SET_PROCESS(last_line_symbol
);
846 function_lineoff
= -1;
852 #endif /* C_AUTOARG */
862 SF_SET_DEBUG(def_symbol_in_progress
);
863 S_SET_SEGMENT(def_symbol_in_progress
, SEG_ABSOLUTE
);
869 /* Valid but set somewhere else (s_comm, s_lcomm, colon) */
875 as_warn("unexpected storage class %d", S_GET_STORAGE_CLASS(def_symbol_in_progress
));
877 } /* switch on storage class */
879 /* Now that we have built a debug symbol, try to
880 find if we should merge with an existing symbol
881 or not. If a symbol is C_EFCN or SEG_ABSOLUTE or
882 untagged SEG_DEBUG it never merges. */
884 /* Two cases for functions. Either debug followed
885 by definition or definition followed by debug.
886 For definition first, we will merge the debug
887 symbol into the definition. For debug first, the
888 lineno entry MUST point to the definition
889 function or else it will point off into space
890 when crawl_symbols() merges the debug
891 symbol into the real symbol. Therefor, let's
892 presume the debug symbol is a real function
895 /* FIXME-SOON If for some reason the definition
896 label/symbol is never seen, this will probably
897 leave an undefined symbol at link time. */
899 if (S_GET_STORAGE_CLASS(def_symbol_in_progress
) == C_EFCN
900 || (S_GET_SEGMENT(def_symbol_in_progress
) == SEG_DEBUG
901 && !SF_GET_TAG(def_symbol_in_progress
))
902 || S_GET_SEGMENT(def_symbol_in_progress
) == SEG_ABSOLUTE
903 || (symbolP
= symbol_find_base(S_GET_NAME(def_symbol_in_progress
), DO_NOT_STRIP
)) == NULL
) {
905 symbol_append(def_symbol_in_progress
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
908 /* This symbol already exists, merge the
909 newly created symbol into the old one.
910 This is not mandatory. The linker can
911 handle duplicate symbols correctly. But I
912 guess that it save a *lot* of space if
913 the assembly file defines a lot of
916 /* The debug entry (def_symbol_in_progress)
917 is merged into the previous definition. */
919 c_symbol_merge(def_symbol_in_progress
, symbolP
);
920 /* FIXME-SOON Should *def_symbol_in_progress be free'd? xoxorich. */
921 def_symbol_in_progress
= symbolP
;
923 if (SF_GET_FUNCTION(def_symbol_in_progress
)
924 || SF_GET_TAG(def_symbol_in_progress
)) {
925 /* For functions, and tags, the symbol *must* be where the debug symbol
926 appears. Move the existing symbol to the current place. */
927 /* If it already is at the end of the symbol list, do nothing */
928 if (def_symbol_in_progress
!= symbol_lastP
) {
929 symbol_remove(def_symbol_in_progress
, &symbol_rootP
, &symbol_lastP
);
930 symbol_append(def_symbol_in_progress
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
931 } /* if not already in place */
933 } /* normal or mergable */
935 if (SF_GET_TAG(def_symbol_in_progress
)
936 && symbol_find_base(S_GET_NAME(def_symbol_in_progress
), DO_NOT_STRIP
) == NULL
) {
937 tag_insert(S_GET_NAME(def_symbol_in_progress
), def_symbol_in_progress
);
938 } /* If symbol is a {structure,union} tag, associate symbol to its name. */
940 if (SF_GET_FUNCTION(def_symbol_in_progress
)) {
941 know(sizeof(def_symbol_in_progress
) <= sizeof(long));
943 = c_line_new(def_symbol_in_progress
,0, 0, &zero_address_frag
);
947 SF_SET_PROCESS(def_symbol_in_progress
);
949 if (symbolP
== NULL
) {
950 /* That is, if this is the first
951 time we've seen the function... */
952 symbol_table_insert(def_symbol_in_progress
);
953 } /* definition follows debug */
954 } /* Create the line number entry pointing to the function being defined */
956 def_symbol_in_progress
= NULL
;
957 demand_empty_rest_of_line();
959 } /* obj_coff_endef() */
962 DEFUN_VOID(obj_coff_dim
)
964 register int dim_index
;
966 if (def_symbol_in_progress
== NULL
)
968 as_warn(".dim pseudo-op used outside of .def/.endef: ignored.");
969 demand_empty_rest_of_line();
971 } /* if not inside .def/.endef */
973 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
975 for (dim_index
= 0; dim_index
< DIMNUM
; dim_index
++)
978 SA_SET_SYM_DIMEN(def_symbol_in_progress
, dim_index
, get_absolute_expression());
980 switch (*input_line_pointer
)
984 input_line_pointer
++;
988 as_warn("badly formed .dim directive ignored");
989 /* intentional fallthrough */
994 } /* switch on following character */
995 } /* for each dimension */
997 demand_empty_rest_of_line();
999 } /* obj_coff_dim() */
1001 static void obj_coff_line()
1005 if (def_symbol_in_progress
== NULL
) {
1008 } /* if it looks like a stabs style line */
1010 this_base
= get_absolute_expression();
1011 if (this_base
> line_base
)
1013 line_base
= this_base
;
1021 listing_source_line(line_base
);
1025 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1026 SA_SET_SYM_LNNO(def_symbol_in_progress
, line_base
);
1028 demand_empty_rest_of_line();
1030 } /* obj_coff_line() */
1032 static void obj_coff_size() {
1033 if (def_symbol_in_progress
== NULL
) {
1034 as_warn(".size pseudo-op used outside of .def/.endef ignored.");
1035 demand_empty_rest_of_line();
1037 } /* if not inside .def/.endef */
1039 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1040 SA_SET_SYM_SIZE(def_symbol_in_progress
, get_absolute_expression());
1041 demand_empty_rest_of_line();
1043 } /* obj_coff_size() */
1045 static void obj_coff_scl() {
1046 if (def_symbol_in_progress
== NULL
) {
1047 as_warn(".scl pseudo-op used outside of .def/.endef ignored.");
1048 demand_empty_rest_of_line();
1050 } /* if not inside .def/.endef */
1052 S_SET_STORAGE_CLASS(def_symbol_in_progress
, get_absolute_expression());
1053 demand_empty_rest_of_line();
1055 } /* obj_coff_scl() */
1057 static void obj_coff_tag() {
1061 if (def_symbol_in_progress
== NULL
) {
1062 as_warn(".tag pseudo-op used outside of .def/.endef ignored.");
1063 demand_empty_rest_of_line();
1065 } /* if not inside .def/.endef */
1067 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1068 symbol_name
= input_line_pointer
;
1069 name_end
= get_symbol_end();
1071 /* Assume that the symbol referred to by .tag is always defined. */
1072 /* This was a bad assumption. I've added find_or_make. xoxorich. */
1073 SA_SET_SYM_TAGNDX(def_symbol_in_progress
, (long) tag_find_or_make(symbol_name
));
1074 if (SA_GET_SYM_TAGNDX(def_symbol_in_progress
) == 0L) {
1075 as_warn("tag not found for .tag %s", symbol_name
);
1078 SF_SET_TAGGED(def_symbol_in_progress
);
1079 *input_line_pointer
= name_end
;
1081 demand_empty_rest_of_line();
1083 } /* obj_coff_tag() */
1085 static void obj_coff_type() {
1086 if (def_symbol_in_progress
== NULL
) {
1087 as_warn(".type pseudo-op used outside of .def/.endef ignored.");
1088 demand_empty_rest_of_line();
1090 } /* if not inside .def/.endef */
1092 S_SET_DATA_TYPE(def_symbol_in_progress
, get_absolute_expression());
1094 if (ISFCN(S_GET_DATA_TYPE(def_symbol_in_progress
)) &&
1095 S_GET_STORAGE_CLASS(def_symbol_in_progress
) != C_TPDEF
) {
1096 SF_SET_FUNCTION(def_symbol_in_progress
);
1097 } /* is a function */
1099 demand_empty_rest_of_line();
1101 } /* obj_coff_type() */
1103 static void obj_coff_val() {
1104 if (def_symbol_in_progress
== NULL
) {
1105 as_warn(".val pseudo-op used outside of .def/.endef ignored.");
1106 demand_empty_rest_of_line();
1108 } /* if not inside .def/.endef */
1110 if (is_name_beginner(*input_line_pointer
)) {
1111 char *symbol_name
= input_line_pointer
;
1112 char name_end
= get_symbol_end();
1114 if (!strcmp(symbol_name
, ".")) {
1115 def_symbol_in_progress
->sy_frag
= frag_now
;
1116 S_SET_VALUE(def_symbol_in_progress
, obstack_next_free(&frags
) - frag_now
->fr_literal
);
1117 /* If the .val is != from the .def (e.g. statics) */
1118 } else if (strcmp(S_GET_NAME(def_symbol_in_progress
), symbol_name
)) {
1119 def_symbol_in_progress
->sy_forward
= symbol_find_or_make(symbol_name
);
1121 /* If the segment is undefined when the forward
1122 reference is solved, then copy the segment id
1123 from the forward symbol. */
1124 SF_SET_GET_SEGMENT(def_symbol_in_progress
);
1126 /* Otherwise, it is the name of a non debug symbol and its value will be calculated later. */
1127 *input_line_pointer
= name_end
;
1129 S_SET_VALUE(def_symbol_in_progress
, get_absolute_expression());
1130 } /* if symbol based */
1132 demand_empty_rest_of_line();
1134 } /* obj_coff_val() */
1137 * Maintain a list of the tagnames of the structres.
1140 static void tag_init() {
1141 tag_hash
= hash_new();
1145 static void tag_insert(name
, symbolP
)
1149 register char * error_string
;
1151 if (*(error_string
= hash_jam(tag_hash
, name
, (char *)symbolP
))) {
1152 as_fatal("Inserting \"%s\" into structure table failed: %s",
1153 name
, error_string
);
1156 } /* tag_insert() */
1158 static symbolS
*tag_find_or_make(name
)
1163 if ((symbolP
= tag_find(name
)) == NULL
) {
1164 symbolP
= symbol_new(name
,
1167 &zero_address_frag
);
1169 tag_insert(S_GET_NAME(symbolP
), symbolP
);
1170 symbol_table_insert(symbolP
);
1174 } /* tag_find_or_make() */
1176 static symbolS
*tag_find(name
)
1179 #ifdef STRIP_UNDERSCORE
1180 if (*name
== '_') name
++;
1181 #endif /* STRIP_UNDERSCORE */
1182 return((symbolS
*)hash_find(tag_hash
, name
));
1185 void obj_read_begin_hook() {
1186 /* These had better be the same. Usually 18 bytes. */
1188 know(sizeof(SYMENT
) == sizeof(AUXENT
));
1189 know(SYMESZ
== AUXESZ
);
1194 } /* obj_read_begin_hook() */
1196 /* This function runs through the symbol table and puts all the
1197 externals onto another chain */
1199 /* The chain of externals */
1200 symbolS
*symbol_externP
= NULL
;
1201 symbolS
*symbol_extern_lastP
= NULL
;
1204 symbolS
*last_functionP
= NULL
;
1208 static unsigned int DEFUN_VOID(yank_symbols
)
1211 unsigned int symbol_number
=0;
1213 for (symbolP
= symbol_rootP
;
1215 symbolP
= symbolP
? symbol_next(symbolP
) : symbol_rootP
) {
1216 if (!SF_GET_DEBUG(symbolP
)) {
1217 /* Debug symbols do not need all this rubbish */
1218 symbolS
* real_symbolP
;
1220 /* L* and C_EFCN symbols never merge. */
1221 if (!SF_GET_LOCAL(symbolP
)
1222 && (real_symbolP
= symbol_find_base(S_GET_NAME(symbolP
), DO_NOT_STRIP
))
1223 && real_symbolP
!= symbolP
) {
1224 /* FIXME-SOON: where do dups come from?
1225 Maybe tag references before definitions? xoxorich. */
1226 /* Move the debug data from the debug symbol to the
1227 real symbol. Do NOT do the oposite (i.e. move from
1228 real symbol to debug symbol and remove real symbol from the
1229 list.) Because some pointers refer to the real symbol
1230 whereas no pointers refer to the debug symbol. */
1231 c_symbol_merge(symbolP
, real_symbolP
);
1232 /* Replace the current symbol by the real one */
1233 /* The symbols will never be the last or the first
1234 because : 1st symbol is .file and 3 last symbols are
1235 .text, .data, .bss */
1236 symbol_remove(real_symbolP
, &symbol_rootP
, &symbol_lastP
);
1237 symbol_insert(real_symbolP
, symbolP
, &symbol_rootP
, &symbol_lastP
);
1238 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1239 symbolP
= real_symbolP
;
1240 } /* if not local but dup'd */
1242 if (flagseen
['R'] && (S_GET_SEGMENT(symbolP
) == SEG_E1
)) {
1243 S_SET_SEGMENT(symbolP
, SEG_E0
);
1244 } /* push data into text */
1246 S_SET_VALUE(symbolP
,
1247 S_GET_VALUE(symbolP
) + symbolP
->sy_frag
->fr_address
);
1249 if (!S_IS_DEFINED(symbolP
) && !SF_GET_LOCAL(symbolP
))
1251 S_SET_EXTERNAL(symbolP
);
1253 else if (S_GET_STORAGE_CLASS(symbolP
) == C_NULL
)
1255 if (S_GET_SEGMENT(symbolP
) == SEG_E0
)
1257 S_SET_STORAGE_CLASS(symbolP
, C_LABEL
);
1261 S_SET_STORAGE_CLASS(symbolP
, C_STAT
);
1265 /* Mainly to speed up if not -g */
1266 if (SF_GET_PROCESS(symbolP
))
1268 /* Handle the nested blocks auxiliary info. */
1269 if (S_GET_STORAGE_CLASS(symbolP
) == C_BLOCK
) {
1270 if (!strcmp(S_GET_NAME(symbolP
), ".bb"))
1271 stack_push(block_stack
, (char *) &symbolP
);
1273 register symbolS
* begin_symbolP
;
1274 begin_symbolP
= *(symbolS
**)stack_pop(block_stack
);
1275 if (begin_symbolP
== (symbolS
*)0)
1276 as_warn("mismatched .eb");
1278 SA_SET_SYM_ENDNDX(begin_symbolP
, symbol_number
+2);
1281 /* If we are able to identify the type of a function, and we
1282 are out of a function (last_functionP == 0) then, the
1283 function symbol will be associated with an auxiliary
1285 if (last_functionP
== (symbolS
*)0 &&
1286 SF_GET_FUNCTION(symbolP
)) {
1287 last_functionP
= symbolP
;
1289 if (S_GET_NUMBER_AUXILIARY(symbolP
) < 1) {
1290 S_SET_NUMBER_AUXILIARY(symbolP
, 1);
1291 } /* make it at least 1 */
1293 /* Clobber possible stale .dim information. */
1295 /* Iffed out by steve - this fries the lnnoptr info too */
1296 bzero(symbolP
->sy_symbol
.ost_auxent
[0].x_sym
.x_fcnary
.x_ary
.x_dimen
,
1297 sizeof(symbolP
->sy_symbol
.ost_auxent
[0].x_sym
.x_fcnary
.x_ary
.x_dimen
));
1300 /* The C_FCN doesn't need any additional information.
1301 I don't even know if this is needed for sdb. But the
1302 standard assembler generates it, so...
1304 if (S_GET_STORAGE_CLASS(symbolP
) == C_EFCN
) {
1305 if (last_functionP
== (symbolS
*)0)
1306 as_fatal("C_EFCN symbol out of scope");
1307 SA_SET_SYM_FSIZE(last_functionP
,
1308 (long)(S_GET_VALUE(symbolP
) -
1309 S_GET_VALUE(last_functionP
)));
1310 SA_SET_SYM_ENDNDX(last_functionP
, symbol_number
);
1311 last_functionP
= (symbolS
*)0;
1314 } else if (SF_GET_TAG(symbolP
)) {
1315 /* First descriptor of a structure must point to
1316 the first slot after the structure description. */
1317 last_tagP
= symbolP
;
1319 } else if (S_GET_STORAGE_CLASS(symbolP
) == C_EOS
) {
1320 /* +2 take in account the current symbol */
1321 SA_SET_SYM_ENDNDX(last_tagP
, symbol_number
+ 2);
1322 } else if (S_GET_STORAGE_CLASS(symbolP
) == C_FILE
) {
1323 if (S_GET_VALUE(symbolP
)) {
1324 S_SET_VALUE((symbolS
*) S_GET_VALUE(symbolP
), symbol_number
);
1325 S_SET_VALUE(symbolP
, 0);
1326 } /* no one points at the first .file symbol */
1327 } /* if debug or tag or eos or file */
1329 /* We must put the external symbols apart. The loader
1330 does not bomb if we do not. But the references in
1331 the endndx field for a .bb symbol are not corrected
1332 if an external symbol is removed between .bb and .be.
1333 I.e in the following case :
1334 [20] .bb endndx = 22
1337 ld will move the symbol 21 to the end of the list but
1338 endndx will still be 22 instead of 21. */
1341 if (SF_GET_LOCAL(symbolP
)) {
1342 /* remove C_EFCN and LOCAL (L...) symbols */
1343 /* next pointer remains valid */
1344 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1347 else if (!S_IS_DEFINED(symbolP
)
1348 && !S_IS_DEBUG(symbolP
)
1349 && !SF_GET_STATICS(symbolP
) &&
1350 S_GET_STORAGE_CLASS(symbolP
) == C_EXT
)
1351 { /* C_EXT && !SF_GET_FUNCTION(symbolP)) */
1352 /* if external, Remove from the list */
1353 symbolS
*hold
= symbol_previous(symbolP
);
1355 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1356 symbol_clear_list_pointers(symbolP
);
1357 symbol_append(symbolP
, symbol_extern_lastP
, &symbol_externP
, &symbol_extern_lastP
);
1360 if (SF_GET_STRING(symbolP
)) {
1361 symbolP
->sy_name_offset
= string_byte_count
;
1362 string_byte_count
+= strlen(S_GET_NAME(symbolP
)) + 1;
1364 symbolP
->sy_name_offset
= 0;
1365 } /* fix "long" names */
1367 symbolP
->sy_number
= symbol_number
;
1368 symbol_number
+= 1 + S_GET_NUMBER_AUXILIARY(symbolP
);
1369 } /* if local symbol */
1370 } /* traverse the symbol list */
1371 return symbol_number
;
1376 static unsigned int DEFUN_VOID(glue_symbols
)
1378 unsigned int symbol_number
= 0;
1380 for (symbolP
= symbol_externP
; symbol_externP
;) {
1381 symbolS
*tmp
= symbol_externP
;
1384 symbol_remove(tmp
, &symbol_externP
, &symbol_extern_lastP
);
1385 symbol_append(tmp
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
1388 if (SF_GET_STRING(tmp
)) {
1389 tmp
->sy_name_offset
= string_byte_count
;
1390 string_byte_count
+= strlen(S_GET_NAME(tmp
)) + 1;
1392 tmp
->sy_name_offset
= 0;
1393 } /* fix "long" names */
1395 tmp
->sy_number
= symbol_number
;
1396 symbol_number
+= 1 + S_GET_NUMBER_AUXILIARY(tmp
);
1397 } /* append the entire extern chain */
1398 return symbol_number
;
1402 static unsigned int DEFUN_VOID(tie_tags
)
1404 unsigned int symbol_number
= 0;
1407 for (symbolP
= symbol_rootP
; symbolP
; symbolP
=
1408 symbol_next(symbolP
))
1410 symbolP
->sy_number
= symbol_number
;
1414 if (SF_GET_TAGGED(symbolP
))
1418 ((symbolS
*) SA_GET_SYM_TAGNDX(symbolP
))->sy_number
);
1421 symbol_number
+= 1 + S_GET_NUMBER_AUXILIARY(symbolP
);
1423 return symbol_number
;
1428 DEFUN(crawl_symbols
,(headers
, abfd
),
1429 struct internal_filehdr
*headers AND
1434 unsigned int ptr
= 0;
1439 /* Initialize the stack used to keep track of the matching .bb .be */
1441 block_stack
= stack_init(512, sizeof(symbolS
*));
1442 /* JF deal with forward references first... */
1443 for (symbolP
= symbol_rootP
;
1445 symbolP
= symbol_next(symbolP
))
1448 if (symbolP
->sy_forward
) {
1449 S_SET_VALUE(symbolP
, (S_GET_VALUE(symbolP
)
1450 + S_GET_VALUE(symbolP
->sy_forward
)
1451 + symbolP
->sy_forward
->sy_frag
->fr_address
));
1453 if (SF_GET_GET_SEGMENT(symbolP
)) {
1454 S_SET_SEGMENT(symbolP
, S_GET_SEGMENT(symbolP
->sy_forward
));
1455 } /* forward segment also */
1457 symbolP
->sy_forward
=0;
1458 } /* if it has a forward reference */
1459 } /* walk the symbol chain */
1462 /* The symbol list should be ordered according to the following sequence
1465 * . debug entries for functions
1466 * . fake symbols for the sections, including.text .data and .bss
1468 * . undefined symbols
1469 * But this is not mandatory. The only important point is to put the
1470 * undefined symbols at the end of the list.
1473 if (symbol_rootP
== NULL
1474 || S_GET_STORAGE_CLASS(symbol_rootP
) != C_FILE
) {
1475 c_dot_file_symbol("fake");
1477 /* Is there a .file symbol ? If not insert one at the beginning. */
1480 * Build up static symbols for the sections, they are filled in later
1484 for (i
= SEG_E0
; i
< SEG_E9
; i
++)
1486 if (segment_info
[i
].scnhdr
.s_name
[0])
1488 segment_info
[i
].dot
=
1489 c_section_symbol(segment_info
[i
].scnhdr
.s_name
,
1496 /* Take all the externals out and put them into another chain */
1497 headers
->f_nsyms
= yank_symbols();
1498 /* Take the externals and glue them onto the end.*/
1499 headers
->f_nsyms
+= glue_symbols();
1501 headers
->f_nsyms
= tie_tags();
1502 know(symbol_externP
== NULL
);
1503 know(symbol_extern_lastP
== NULL
);
1509 * Find strings by crawling along symbol table chain.
1512 void DEFUN(w_strings
,(where
),
1517 /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
1518 md_number_to_chars(where
, string_byte_count
, sizeof(string_byte_count
));
1519 where
+= sizeof(string_byte_count
);
1520 for (symbolP
= symbol_rootP
;
1522 symbolP
= symbol_next(symbolP
))
1526 if (SF_GET_STRING(symbolP
)) {
1527 size
= strlen(S_GET_NAME(symbolP
)) + 1;
1529 memcpy(where
, S_GET_NAME(symbolP
),size
);
1542 DEFUN(do_linenos_for
,(abfd
, file_cursor
),
1544 unsigned long *file_cursor
)
1548 for (idx
= SEG_E0
; idx
< SEG_E9
; idx
++)
1550 segment_info_type
*s
= segment_info
+ idx
;
1553 if (s
->scnhdr
.s_nlnno
!= 0)
1555 struct lineno_list
*line_ptr
;
1557 struct external_lineno
*buffer
=
1558 (struct external_lineno
*)xmalloc(s
->scnhdr
.s_nlnno
* LINESZ
);
1560 struct external_lineno
*dst
= buffer
;
1562 /* Run through the table we've built and turn it into its external
1563 form, take this chance to remove duplicates */
1565 for (line_ptr
= s
->lineno_list_head
;
1566 line_ptr
!= (struct lineno_list
*)NULL
;
1567 line_ptr
= line_ptr
->next
)
1570 if (line_ptr
->line
.l_lnno
== 0)
1572 /* Turn a pointer to a symbol into the symbols' index */
1573 line_ptr
->line
.l_addr
.l_symndx
=
1574 ( (symbolS
*)line_ptr
->line
.l_addr
.l_symndx
)->sy_number
;
1578 line_ptr
->line
.l_addr
.l_paddr
+= ((struct frag
* )(line_ptr
->frag
))->fr_address
;
1582 (void) bfd_coff_swap_lineno_out(abfd
, &(line_ptr
->line
), dst
);
1587 s
->scnhdr
.s_lnnoptr
= *file_cursor
;
1589 bfd_write(buffer
, 1, s
->scnhdr
.s_nlnno
* LINESZ
, abfd
);
1592 *file_cursor
+= s
->scnhdr
.s_nlnno
* LINESZ
;
1598 /* Now we run through the list of frag chains in a segment and
1599 make all the subsegment frags appear at the end of the
1600 list, as if the seg 0 was extra long */
1602 static void DEFUN_VOID(remove_subsegs
)
1606 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1608 frchainS
*head
= segment_info
[i
].frchainP
;
1610 fragS
* prev_frag
= &dummy
;
1612 while (head
&& head
->frch_seg
== i
)
1614 prev_frag
->fr_next
= head
->frch_root
;
1615 prev_frag
= head
->frch_last
;
1616 head
= head
->frch_next
;
1618 prev_frag
->fr_next
= 0;
1623 extern void DEFUN_VOID(write_object_file
)
1626 struct frchain
*frchain_ptr
;
1628 struct internal_filehdr filehdr
;
1629 struct internal_aouthdr aouthdr
;
1630 unsigned long file_cursor
;
1632 unsigned int addr
= 0;
1633 abfd
= bfd_openw(out_file_name
, TARGET_FORMAT
);
1637 as_perror ("FATAL: Can't create %s", out_file_name
);
1640 bfd_set_format(abfd
, bfd_object
);
1641 bfd_set_arch_mach(abfd
, BFD_ARCH
, 0);
1645 string_byte_count
= 4;
1647 for (frchain_ptr
= frchain_root
;
1648 frchain_ptr
!= (struct frchain
*)NULL
;
1649 frchain_ptr
= frchain_ptr
->frch_next
) {
1650 /* Run through all the sub-segments and align them up. Also close any
1651 open frags. We tack a .fill onto the end of the frag chain so
1652 that any .align's size can be worked by looking at the next
1655 subseg_new(frchain_ptr
->frch_seg
, frchain_ptr
->frch_subseg
);
1656 #define SUB_SEGMENT_ALIGN 1
1657 frag_align(SUB_SEGMENT_ALIGN
,0);
1658 frag_wane(frag_now
);
1659 frag_now
->fr_fix
= 0;
1660 know( frag_now
->fr_next
== NULL
);
1667 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1669 relax_segment(segment_info
[i
].frchainP
->frch_root
, i
);
1676 filehdr
.f_nscns
= 0;
1678 /* Find out how big the sections are */
1679 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1682 if (segment_info
[i
].scnhdr
.s_name
[0])
1689 /* THis is a special case, we leave the size alone, which will have */
1690 /* been made up from all and any lcomms seen */
1694 addr
+= size_section(abfd
, i
);
1700 /* Turn the gas native symbol table shape into a coff symbol table */
1701 crawl_symbols(&filehdr
, abfd
);
1703 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1705 fixup_segment(segment_info
[i
].fix_root
, i
);
1709 file_cursor
= FILHSZ
+ SCNHSZ
* filehdr
.f_nscns
;
1711 bfd_seek(abfd
, file_cursor
, 0);
1714 do_relocs_for(abfd
, &file_cursor
);
1716 do_linenos_for(abfd
, &file_cursor
);
1719 /* Plant the data */
1721 fill_section(abfd
,&filehdr
, &file_cursor
);
1725 filehdr
.f_magic
= COFF_MAGIC
;
1726 filehdr
.f_timdat
= time(0);
1727 filehdr
.f_flags
= COFF_FLAGS
;
1731 filehdr
.f_flags
|= F_LNNO
;
1735 filehdr
.f_flags
|= F_RELFLG
;
1746 unsigned int symtable_size
= filehdr
.f_nsyms
* SYMESZ
;
1747 char *buffer1
= malloc(symtable_size
+ string_byte_count
+ 4);
1748 char *ptr
= buffer1
;
1749 filehdr
.f_symptr
= bfd_tell(abfd
);
1750 w_symbols(abfd
, buffer1
, symbol_rootP
);
1751 w_strings(buffer1
+ symtable_size
);
1752 bfd_write(buffer1
, 1,symtable_size
+ string_byte_count
+ 4, abfd
);
1756 coff_header_append(abfd
, &filehdr
, &aouthdr
);
1758 bfd_close_all_done(abfd
);
1762 static void DEFUN(change_to_section
,(name
, len
, exp
),
1764 unsigned int len AND
1768 /* Find out if we've already got a section of this name etc */
1769 for(i
= SEG_E0
; i
< SEG_E9
&& segment_info
[i
].scnhdr
.s_name
[0] ; i
++)
1771 if (strncmp(segment_info
[i
].scnhdr
.s_name
, name
, len
) == 0)
1778 /* No section, add one */
1779 strncpy(segment_info
[i
].scnhdr
.s_name
, name
, 8);
1784 DEFUN_VOID(obj_coff_section
)
1786 /* Strip out the section name */
1787 char *section_name
;
1788 char *section_name_end
;
1794 section_name
= input_line_pointer
;
1795 c
= get_symbol_end();
1796 section_name_end
= input_line_pointer
;
1798 len
= section_name_end
- section_name
;
1799 input_line_pointer
++;
1803 exp
= get_absolute_expression();
1805 else if ( *input_line_pointer
== ',')
1808 input_line_pointer
++;
1809 exp
= get_absolute_expression();
1816 change_to_section(section_name
, len
,exp
);
1817 *section_name_end
= c
;
1822 static void obj_coff_text()
1824 change_to_section(".text",5, get_absolute_expression());
1828 static void obj_coff_data()
1830 change_to_section(".data",5, get_absolute_expression());
1833 void c_symbol_merge(debug
, normal
)
1837 S_SET_DATA_TYPE(normal
, S_GET_DATA_TYPE(debug
));
1838 S_SET_STORAGE_CLASS(normal
, S_GET_STORAGE_CLASS(debug
));
1840 if (S_GET_NUMBER_AUXILIARY(debug
) > S_GET_NUMBER_AUXILIARY(normal
)) {
1841 S_SET_NUMBER_AUXILIARY(normal
, S_GET_NUMBER_AUXILIARY(debug
));
1842 } /* take the most we have */
1844 if (S_GET_NUMBER_AUXILIARY(debug
) > 0) {
1845 memcpy((char*)&normal
->sy_symbol
.ost_auxent
[0], (char*)&debug
->sy_symbol
.ost_auxent
[0], S_GET_NUMBER_AUXILIARY(debug
) * AUXESZ
);
1846 } /* Move all the auxiliary information */
1848 /* Move the debug flags. */
1849 SF_SET_DEBUG_FIELD(normal
, SF_GET_DEBUG_FIELD(debug
));
1850 } /* c_symbol_merge() */
1853 DEFUN(c_line_new
,(symbol
, paddr
, line_number
, frag
),
1856 unsigned short line_number AND
1859 struct lineno_list
* new_line
=
1860 (struct lineno_list
*)xmalloc(sizeof(struct lineno_list
));
1862 segment_info_type
*s
= segment_info
+ now_seg
;
1863 new_line
->line
.l_lnno
= line_number
;
1867 if (line_number
== 0)
1869 last_line_symbol
= symbol
;
1870 new_line
->line
.l_addr
.l_symndx
= (long)symbol
;
1874 new_line
->line
.l_addr
.l_paddr
= paddr
;
1877 new_line
->frag
= (char*)frag
;
1878 new_line
->next
= (struct lineno_list
*)NULL
;
1881 if (s
->lineno_list_head
== (struct lineno_list
*)NULL
)
1883 s
->lineno_list_head
= new_line
;
1887 s
->lineno_list_tail
->next
= new_line
;
1889 s
->lineno_list_tail
= new_line
;
1890 return LINESZ
* s
->scnhdr
.s_nlnno
++;
1893 void c_dot_file_symbol(filename
)
1898 symbolP
= symbol_new(".file",
1901 &zero_address_frag
);
1903 S_SET_STORAGE_CLASS(symbolP
, C_FILE
);
1904 S_SET_NUMBER_AUXILIARY(symbolP
, 1);
1905 SA_SET_FILE_FNAME(symbolP
, filename
);
1911 listing_source_file(filename
);
1917 SF_SET_DEBUG(symbolP
);
1918 S_SET_VALUE(symbolP
, (long) previous_file_symbol
);
1920 previous_file_symbol
= symbolP
;
1922 /* Make sure that the symbol is first on the symbol chain */
1923 if (symbol_rootP
!= symbolP
) {
1924 if (symbolP
== symbol_lastP
) {
1925 symbol_lastP
= symbol_lastP
->sy_previous
;
1926 } /* if it was the last thing on the list */
1928 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1929 symbol_insert(symbolP
, symbol_rootP
, &symbol_rootP
, &symbol_lastP
);
1930 symbol_rootP
= symbolP
;
1931 } /* if not first on the list */
1933 } /* c_dot_file_symbol() */
1936 * Build a 'section static' symbol.
1939 symbolS
*c_section_symbol(name
,idx
)
1945 symbolP
= symbol_new(name
,idx
,
1947 &zero_address_frag
);
1949 S_SET_STORAGE_CLASS(symbolP
, C_STAT
);
1950 S_SET_NUMBER_AUXILIARY(symbolP
, 1);
1952 SF_SET_STATICS(symbolP
);
1955 } /* c_section_symbol() */
1958 DEFUN(w_symbols
,(abfd
, where
, symbol_rootP
),
1961 symbolS
*symbol_rootP
)
1966 /* First fill in those values we have only just worked out */
1967 for (i
= SEG_E0
; i
< SEG_E9
; i
++)
1969 symbolP
= segment_info
[i
].dot
;
1973 SA_SET_SCN_SCNLEN(symbolP
, segment_info
[i
].scnhdr
.s_size
);
1974 SA_SET_SCN_NRELOC(symbolP
, segment_info
[i
].scnhdr
.s_nreloc
);
1975 SA_SET_SCN_NLINNO(symbolP
, segment_info
[i
].scnhdr
.s_nlnno
);
1981 * Emit all symbols left in the symbol chain.
1983 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next(symbolP
)) {
1984 /* Used to save the offset of the name. It is used to point
1985 to the string in memory but must be a file offset. */
1986 register char * temp
;
1988 tc_coff_symbol_emit_hook(symbolP
);
1990 temp
= S_GET_NAME(symbolP
);
1991 if (SF_GET_STRING(symbolP
)) {
1992 S_SET_OFFSET(symbolP
, symbolP
->sy_name_offset
);
1993 S_SET_ZEROES(symbolP
, 0);
1995 bzero(symbolP
->sy_symbol
.ost_entry
.n_name
, SYMNMLEN
);
1996 strncpy(symbolP
->sy_symbol
.ost_entry
.n_name
, temp
, SYMNMLEN
);
1998 where
= symbol_to_chars(abfd
, where
, symbolP
);
1999 S_SET_NAME(symbolP
,temp
);
2004 static void DEFUN_VOID(obj_coff_lcomm
)
2013 name
= input_line_pointer
;
2017 c
= get_symbol_end();
2018 p
= input_line_pointer
;
2021 if (*input_line_pointer
!= ',') {
2022 as_bad("Expected comma after name");
2023 ignore_rest_of_line();
2026 if (*input_line_pointer
== '\n') {
2027 as_bad("Missing size expression");
2030 input_line_pointer
++;
2031 if ((temp
= get_absolute_expression ()) < 0) {
2032 as_warn("lcomm length (%d.) <0! Ignored.", temp
);
2033 ignore_rest_of_line();
2037 symbolP
= symbol_find_or_make(name
);
2038 vma
= segment_info
[SEG_E2
].scnhdr
.s_size
;
2039 vma
+= relax_align(vma
, MIN(8, temp
));
2040 S_SET_VALUE(symbolP
,vma
);
2041 S_SET_SEGMENT(symbolP
, SEG_E2
);
2042 segment_info
[SEG_E2
].scnhdr
.s_size
= vma
+ temp
;
2043 S_SET_STORAGE_CLASS(symbolP
, C_STAT
);
2044 demand_empty_rest_of_line();
2049 static void DEFUN(fixup_segment
,(fixP
, this_segment_type
),
2050 register fixS
* fixP AND
2051 segT this_segment_type
)
2053 register symbolS
*add_symbolP
;
2054 register symbolS
*sub_symbolP
;
2055 register long add_number
;
2057 register char *place
;
2058 register long where
;
2059 register char pcrel
;
2060 register fragS
*fragP
;
2061 register segT add_symbol_segment
= SEG_ABSOLUTE
;
2064 for ( ; fixP
; fixP
= fixP
->fx_next
)
2066 fragP
= fixP
->fx_frag
;
2068 where
= fixP
->fx_where
;
2069 place
= fragP
->fr_literal
+ where
;
2070 size
= fixP
->fx_size
;
2071 add_symbolP
= fixP
->fx_addsy
;
2073 if (fixP
->fx_callj
&& TC_S_IS_CALLNAME(add_symbolP
)) {
2074 /* Relocation should be done via the
2075 associated 'bal' entry point
2078 if (!TC_S_IS_BALNAME(tc_get_bal_of_call(add_symbolP
))) {
2079 as_bad("No 'bal' entry point for leafproc %s",
2080 S_GET_NAME(add_symbolP
));
2083 fixP
->fx_addsy
= add_symbolP
= tc_get_bal_of_call(add_symbolP
);
2084 } /* callj relocation */
2086 sub_symbolP
= fixP
->fx_subsy
;
2087 add_number
= fixP
->fx_offset
;
2088 pcrel
= fixP
->fx_pcrel
;
2091 add_symbol_segment
= S_GET_SEGMENT(add_symbolP
);
2092 } /* if there is an addend */
2097 if (S_GET_SEGMENT(sub_symbolP
) != SEG_ABSOLUTE
) {
2098 as_bad("Negative of non-absolute symbol %s", S_GET_NAME(sub_symbolP
));
2099 } /* not absolute */
2101 add_number
-= S_GET_VALUE(sub_symbolP
);
2103 /* if sub_symbol is in the same segment that add_symbol
2104 and add_symbol is either in DATA, TEXT, BSS or ABSOLUTE */
2105 } else if ((S_GET_SEGMENT(sub_symbolP
) == add_symbol_segment
)
2106 && (SEG_NORMAL(add_symbol_segment
)
2107 || (add_symbol_segment
== SEG_ABSOLUTE
))) {
2108 /* Difference of 2 symbols from same segment. */
2109 /* Can't make difference of 2 undefineds: 'value' means */
2110 /* something different for N_UNDF. */
2112 /* Makes no sense to use the difference of 2 arbitrary symbols
2113 * as the target of a call instruction.
2115 if (fixP
->fx_callj
) {
2116 as_bad("callj to difference of 2 symbols");
2118 #endif /* TC_I960 */
2119 add_number
+= S_GET_VALUE(add_symbolP
) -
2120 S_GET_VALUE(sub_symbolP
);
2123 fixP
->fx_addsy
= NULL
;
2125 /* Different segments in subtraction. */
2126 know(!(S_IS_EXTERNAL(sub_symbolP
) && (S_GET_SEGMENT(sub_symbolP
) == SEG_ABSOLUTE
)));
2128 if ((S_GET_SEGMENT(sub_symbolP
) == SEG_ABSOLUTE
)) {
2129 add_number
-= S_GET_VALUE(sub_symbolP
);
2131 as_bad("Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %d.",
2132 segment_name(S_GET_SEGMENT(sub_symbolP
)),
2133 S_GET_NAME(sub_symbolP
), fragP
->fr_address
+ where
);
2136 } /* if sub_symbolP */
2139 if (add_symbol_segment
== this_segment_type
&& pcrel
) {
2141 * This fixup was made when the symbol's segment was
2142 * SEG_UNKNOWN, but it is now in the local segment.
2143 * So we know how to do the address without relocation.
2146 /* reloc_callj() may replace a 'call' with a 'calls' or a 'bal',
2147 * in which cases it modifies *fixP as appropriate. In the case
2148 * of a 'calls', no further work is required, and *fixP has been
2149 * set up to make the rest of the code below a no-op.
2152 #endif /* TC_I960 */
2154 add_number
+= S_GET_VALUE(add_symbolP
);
2155 add_number
-= md_pcrel_from (fixP
);
2156 pcrel
= 0; /* Lie. Don't want further pcrel processing. */
2157 fixP
->fx_addsy
= NULL
; /* No relocations please. */
2160 switch (add_symbol_segment
)
2164 reloc_callj(fixP
); /* See comment about reloc_callj() above*/
2165 #endif /* TC_I960 */
2166 add_number
+= S_GET_VALUE(add_symbolP
);
2167 fixP
->fx_addsy
= NULL
;
2172 add_number
+= S_GET_VALUE(add_symbolP
) +
2173 segment_info
[S_GET_SEGMENT(add_symbolP
)].scnhdr
.s_paddr
;
2178 if ((int)fixP
->fx_bit_fixP
== 13) {
2179 /* This is a COBR instruction. They have only a
2180 * 13-bit displacement and are only to be used
2181 * for local branches: flag as error, don't generate
2184 as_bad("can't use COBR format with external label");
2185 fixP
->fx_addsy
= NULL
; /* No relocations please. */
2188 #endif /* TC_I960 */
2195 } /* switch on symbol seg */
2196 } /* if not in local seg */
2197 } /* if there was a + symbol */
2200 add_number
-= md_pcrel_from(fixP
);
2201 if (add_symbolP
== 0) {
2202 fixP
->fx_addsy
= & abs_symbol
;
2203 } /* if there's an add_symbol */
2206 if (!fixP
->fx_bit_fixP
) {
2208 (add_number
& ~0xFF) && (add_number
&~0xFF!=(-1&~0xFF))) ||
2210 (add_number
& ~0xFFFF) && (add_number
&~0xFFFF!=(-1&~0xFFFF)))) {
2211 as_bad("Value of %d too large for field of %d bytes at 0x%x",
2212 add_number
, size
, fragP
->fr_address
+ where
);
2213 } /* generic error checking */
2214 } /* not a bit fix */
2215 /* once this fix has been applied, we don't have to output anything
2216 nothing more need be done -*/
2217 md_apply_fix(fixP
, add_number
);
2219 } /* For each fixS in this segment. */
2222 } /* fixup_segment() */