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;
1624 extern void DEFUN_VOID(write_object_file
)
1627 struct frchain
*frchain_ptr
;
1629 struct internal_filehdr filehdr
;
1630 struct internal_aouthdr aouthdr
;
1631 unsigned long file_cursor
;
1633 unsigned int addr
= 0;
1634 abfd
= bfd_openw(out_file_name
, TARGET_FORMAT
);
1638 as_perror ("FATAL: Can't create %s", out_file_name
);
1641 bfd_set_format(abfd
, bfd_object
);
1642 bfd_set_arch_mach(abfd
, BFD_ARCH
, machine
);
1646 string_byte_count
= 4;
1648 for (frchain_ptr
= frchain_root
;
1649 frchain_ptr
!= (struct frchain
*)NULL
;
1650 frchain_ptr
= frchain_ptr
->frch_next
) {
1651 /* Run through all the sub-segments and align them up. Also close any
1652 open frags. We tack a .fill onto the end of the frag chain so
1653 that any .align's size can be worked by looking at the next
1656 subseg_new(frchain_ptr
->frch_seg
, frchain_ptr
->frch_subseg
);
1657 #define SUB_SEGMENT_ALIGN 1
1658 frag_align(SUB_SEGMENT_ALIGN
,0);
1659 frag_wane(frag_now
);
1660 frag_now
->fr_fix
= 0;
1661 know( frag_now
->fr_next
== NULL
);
1668 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1670 relax_segment(segment_info
[i
].frchainP
->frch_root
, i
);
1677 filehdr
.f_nscns
= 0;
1679 /* Find out how big the sections are */
1680 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1683 if (segment_info
[i
].scnhdr
.s_name
[0])
1690 /* THis is a special case, we leave the size alone, which will have */
1691 /* been made up from all and any lcomms seen */
1695 addr
+= size_section(abfd
, i
);
1701 /* Turn the gas native symbol table shape into a coff symbol table */
1702 crawl_symbols(&filehdr
, abfd
);
1704 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1706 fixup_segment(segment_info
[i
].fix_root
, i
);
1710 file_cursor
= FILHSZ
+ SCNHSZ
* filehdr
.f_nscns
;
1712 bfd_seek(abfd
, file_cursor
, 0);
1715 do_relocs_for(abfd
, &file_cursor
);
1717 do_linenos_for(abfd
, &file_cursor
);
1720 /* Plant the data */
1722 fill_section(abfd
,&filehdr
, &file_cursor
);
1726 filehdr
.f_magic
= COFF_MAGIC
;
1727 filehdr
.f_timdat
= time(0);
1728 filehdr
.f_flags
= COFF_FLAGS
| coff_flags
;
1732 filehdr
.f_flags
|= F_LNNO
;
1736 filehdr
.f_flags
|= F_RELFLG
;
1747 unsigned int symtable_size
= filehdr
.f_nsyms
* SYMESZ
;
1748 char *buffer1
= malloc(symtable_size
+ string_byte_count
+ 4);
1749 char *ptr
= buffer1
;
1750 filehdr
.f_symptr
= bfd_tell(abfd
);
1751 w_symbols(abfd
, buffer1
, symbol_rootP
);
1752 w_strings(buffer1
+ symtable_size
);
1753 bfd_write(buffer1
, 1,symtable_size
+ string_byte_count
+ 4, abfd
);
1757 coff_header_append(abfd
, &filehdr
, &aouthdr
);
1759 bfd_close_all_done(abfd
);
1763 static void DEFUN(change_to_section
,(name
, len
, exp
),
1765 unsigned int len AND
1769 /* Find out if we've already got a section of this name etc */
1770 for(i
= SEG_E0
; i
< SEG_E9
&& segment_info
[i
].scnhdr
.s_name
[0] ; i
++)
1772 if (strncmp(segment_info
[i
].scnhdr
.s_name
, name
, len
) == 0)
1779 /* No section, add one */
1780 strncpy(segment_info
[i
].scnhdr
.s_name
, name
, 8);
1785 DEFUN_VOID(obj_coff_section
)
1787 /* Strip out the section name */
1788 char *section_name
;
1789 char *section_name_end
;
1795 section_name
= input_line_pointer
;
1796 c
= get_symbol_end();
1797 section_name_end
= input_line_pointer
;
1799 len
= section_name_end
- section_name
;
1800 input_line_pointer
++;
1804 exp
= get_absolute_expression();
1806 else if ( *input_line_pointer
== ',')
1809 input_line_pointer
++;
1810 exp
= get_absolute_expression();
1817 change_to_section(section_name
, len
,exp
);
1818 *section_name_end
= c
;
1823 static void obj_coff_text()
1825 change_to_section(".text",5, get_absolute_expression());
1829 static void obj_coff_data()
1831 change_to_section(".data",5, get_absolute_expression());
1834 void c_symbol_merge(debug
, normal
)
1838 S_SET_DATA_TYPE(normal
, S_GET_DATA_TYPE(debug
));
1839 S_SET_STORAGE_CLASS(normal
, S_GET_STORAGE_CLASS(debug
));
1841 if (S_GET_NUMBER_AUXILIARY(debug
) > S_GET_NUMBER_AUXILIARY(normal
)) {
1842 S_SET_NUMBER_AUXILIARY(normal
, S_GET_NUMBER_AUXILIARY(debug
));
1843 } /* take the most we have */
1845 if (S_GET_NUMBER_AUXILIARY(debug
) > 0) {
1846 memcpy((char*)&normal
->sy_symbol
.ost_auxent
[0], (char*)&debug
->sy_symbol
.ost_auxent
[0], S_GET_NUMBER_AUXILIARY(debug
) * AUXESZ
);
1847 } /* Move all the auxiliary information */
1849 /* Move the debug flags. */
1850 SF_SET_DEBUG_FIELD(normal
, SF_GET_DEBUG_FIELD(debug
));
1851 } /* c_symbol_merge() */
1854 DEFUN(c_line_new
,(symbol
, paddr
, line_number
, frag
),
1857 unsigned short line_number AND
1860 struct lineno_list
* new_line
=
1861 (struct lineno_list
*)xmalloc(sizeof(struct lineno_list
));
1863 segment_info_type
*s
= segment_info
+ now_seg
;
1864 new_line
->line
.l_lnno
= line_number
;
1868 if (line_number
== 0)
1870 last_line_symbol
= symbol
;
1871 new_line
->line
.l_addr
.l_symndx
= (long)symbol
;
1875 new_line
->line
.l_addr
.l_paddr
= paddr
;
1878 new_line
->frag
= (char*)frag
;
1879 new_line
->next
= (struct lineno_list
*)NULL
;
1882 if (s
->lineno_list_head
== (struct lineno_list
*)NULL
)
1884 s
->lineno_list_head
= new_line
;
1888 s
->lineno_list_tail
->next
= new_line
;
1890 s
->lineno_list_tail
= new_line
;
1891 return LINESZ
* s
->scnhdr
.s_nlnno
++;
1894 void c_dot_file_symbol(filename
)
1899 symbolP
= symbol_new(".file",
1902 &zero_address_frag
);
1904 S_SET_STORAGE_CLASS(symbolP
, C_FILE
);
1905 S_SET_NUMBER_AUXILIARY(symbolP
, 1);
1906 SA_SET_FILE_FNAME(symbolP
, filename
);
1912 listing_source_file(filename
);
1918 SF_SET_DEBUG(symbolP
);
1919 S_SET_VALUE(symbolP
, (long) previous_file_symbol
);
1921 previous_file_symbol
= symbolP
;
1923 /* Make sure that the symbol is first on the symbol chain */
1924 if (symbol_rootP
!= symbolP
) {
1925 if (symbolP
== symbol_lastP
) {
1926 symbol_lastP
= symbol_lastP
->sy_previous
;
1927 } /* if it was the last thing on the list */
1929 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1930 symbol_insert(symbolP
, symbol_rootP
, &symbol_rootP
, &symbol_lastP
);
1931 symbol_rootP
= symbolP
;
1932 } /* if not first on the list */
1934 } /* c_dot_file_symbol() */
1937 * Build a 'section static' symbol.
1940 symbolS
*c_section_symbol(name
,idx
)
1946 symbolP
= symbol_new(name
,idx
,
1948 &zero_address_frag
);
1950 S_SET_STORAGE_CLASS(symbolP
, C_STAT
);
1951 S_SET_NUMBER_AUXILIARY(symbolP
, 1);
1953 SF_SET_STATICS(symbolP
);
1956 } /* c_section_symbol() */
1959 DEFUN(w_symbols
,(abfd
, where
, symbol_rootP
),
1962 symbolS
*symbol_rootP
)
1967 /* First fill in those values we have only just worked out */
1968 for (i
= SEG_E0
; i
< SEG_E9
; i
++)
1970 symbolP
= segment_info
[i
].dot
;
1974 SA_SET_SCN_SCNLEN(symbolP
, segment_info
[i
].scnhdr
.s_size
);
1975 SA_SET_SCN_NRELOC(symbolP
, segment_info
[i
].scnhdr
.s_nreloc
);
1976 SA_SET_SCN_NLINNO(symbolP
, segment_info
[i
].scnhdr
.s_nlnno
);
1982 * Emit all symbols left in the symbol chain.
1984 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next(symbolP
)) {
1985 /* Used to save the offset of the name. It is used to point
1986 to the string in memory but must be a file offset. */
1987 register char * temp
;
1989 tc_coff_symbol_emit_hook(symbolP
);
1991 temp
= S_GET_NAME(symbolP
);
1992 if (SF_GET_STRING(symbolP
)) {
1993 S_SET_OFFSET(symbolP
, symbolP
->sy_name_offset
);
1994 S_SET_ZEROES(symbolP
, 0);
1996 bzero(symbolP
->sy_symbol
.ost_entry
.n_name
, SYMNMLEN
);
1997 strncpy(symbolP
->sy_symbol
.ost_entry
.n_name
, temp
, SYMNMLEN
);
1999 where
= symbol_to_chars(abfd
, where
, symbolP
);
2000 S_SET_NAME(symbolP
,temp
);
2005 static void DEFUN_VOID(obj_coff_lcomm
)
2014 name
= input_line_pointer
;
2018 c
= get_symbol_end();
2019 p
= input_line_pointer
;
2022 if (*input_line_pointer
!= ',') {
2023 as_bad("Expected comma after name");
2024 ignore_rest_of_line();
2027 if (*input_line_pointer
== '\n') {
2028 as_bad("Missing size expression");
2031 input_line_pointer
++;
2032 if ((temp
= get_absolute_expression ()) < 0) {
2033 as_warn("lcomm length (%d.) <0! Ignored.", temp
);
2034 ignore_rest_of_line();
2038 symbolP
= symbol_find_or_make(name
);
2039 vma
= segment_info
[SEG_E2
].scnhdr
.s_size
;
2040 vma
+= relax_align(vma
, MIN(8, temp
));
2041 S_SET_VALUE(symbolP
,vma
);
2042 S_SET_SEGMENT(symbolP
, SEG_E2
);
2043 segment_info
[SEG_E2
].scnhdr
.s_size
= vma
+ temp
;
2044 S_SET_STORAGE_CLASS(symbolP
, C_STAT
);
2045 demand_empty_rest_of_line();
2050 static void DEFUN(fixup_segment
,(fixP
, this_segment_type
),
2051 register fixS
* fixP AND
2052 segT this_segment_type
)
2054 register symbolS
*add_symbolP
;
2055 register symbolS
*sub_symbolP
;
2056 register long add_number
;
2058 register char *place
;
2059 register long where
;
2060 register char pcrel
;
2061 register fragS
*fragP
;
2062 register segT add_symbol_segment
= SEG_ABSOLUTE
;
2065 for ( ; fixP
; fixP
= fixP
->fx_next
)
2067 fragP
= fixP
->fx_frag
;
2069 where
= fixP
->fx_where
;
2070 place
= fragP
->fr_literal
+ where
;
2071 size
= fixP
->fx_size
;
2072 add_symbolP
= fixP
->fx_addsy
;
2074 if (fixP
->fx_callj
&& TC_S_IS_CALLNAME(add_symbolP
)) {
2075 /* Relocation should be done via the
2076 associated 'bal' entry point
2079 if (!TC_S_IS_BALNAME(tc_get_bal_of_call(add_symbolP
))) {
2080 as_bad("No 'bal' entry point for leafproc %s",
2081 S_GET_NAME(add_symbolP
));
2084 fixP
->fx_addsy
= add_symbolP
= tc_get_bal_of_call(add_symbolP
);
2085 } /* callj relocation */
2087 sub_symbolP
= fixP
->fx_subsy
;
2088 add_number
= fixP
->fx_offset
;
2089 pcrel
= fixP
->fx_pcrel
;
2092 add_symbol_segment
= S_GET_SEGMENT(add_symbolP
);
2093 } /* if there is an addend */
2098 if (S_GET_SEGMENT(sub_symbolP
) != SEG_ABSOLUTE
) {
2099 as_bad("Negative of non-absolute symbol %s", S_GET_NAME(sub_symbolP
));
2100 } /* not absolute */
2102 add_number
-= S_GET_VALUE(sub_symbolP
);
2104 /* if sub_symbol is in the same segment that add_symbol
2105 and add_symbol is either in DATA, TEXT, BSS or ABSOLUTE */
2106 } else if ((S_GET_SEGMENT(sub_symbolP
) == add_symbol_segment
)
2107 && (SEG_NORMAL(add_symbol_segment
)
2108 || (add_symbol_segment
== SEG_ABSOLUTE
))) {
2109 /* Difference of 2 symbols from same segment. */
2110 /* Can't make difference of 2 undefineds: 'value' means */
2111 /* something different for N_UNDF. */
2113 /* Makes no sense to use the difference of 2 arbitrary symbols
2114 * as the target of a call instruction.
2116 if (fixP
->fx_callj
) {
2117 as_bad("callj to difference of 2 symbols");
2119 #endif /* TC_I960 */
2120 add_number
+= S_GET_VALUE(add_symbolP
) -
2121 S_GET_VALUE(sub_symbolP
);
2124 fixP
->fx_addsy
= NULL
;
2126 /* Different segments in subtraction. */
2127 know(!(S_IS_EXTERNAL(sub_symbolP
) && (S_GET_SEGMENT(sub_symbolP
) == SEG_ABSOLUTE
)));
2129 if ((S_GET_SEGMENT(sub_symbolP
) == SEG_ABSOLUTE
)) {
2130 add_number
-= S_GET_VALUE(sub_symbolP
);
2132 as_bad("Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %d.",
2133 segment_name(S_GET_SEGMENT(sub_symbolP
)),
2134 S_GET_NAME(sub_symbolP
), fragP
->fr_address
+ where
);
2137 } /* if sub_symbolP */
2140 if (add_symbol_segment
== this_segment_type
&& pcrel
) {
2142 * This fixup was made when the symbol's segment was
2143 * SEG_UNKNOWN, but it is now in the local segment.
2144 * So we know how to do the address without relocation.
2147 /* reloc_callj() may replace a 'call' with a 'calls' or a 'bal',
2148 * in which cases it modifies *fixP as appropriate. In the case
2149 * of a 'calls', no further work is required, and *fixP has been
2150 * set up to make the rest of the code below a no-op.
2153 #endif /* TC_I960 */
2155 add_number
+= S_GET_VALUE(add_symbolP
);
2156 add_number
-= md_pcrel_from (fixP
);
2157 pcrel
= 0; /* Lie. Don't want further pcrel processing. */
2158 fixP
->fx_addsy
= NULL
; /* No relocations please. */
2161 switch (add_symbol_segment
)
2165 reloc_callj(fixP
); /* See comment about reloc_callj() above*/
2166 #endif /* TC_I960 */
2167 add_number
+= S_GET_VALUE(add_symbolP
);
2168 fixP
->fx_addsy
= NULL
;
2173 add_number
+= S_GET_VALUE(add_symbolP
) +
2174 segment_info
[S_GET_SEGMENT(add_symbolP
)].scnhdr
.s_paddr
;
2179 if ((int)fixP
->fx_bit_fixP
== 13) {
2180 /* This is a COBR instruction. They have only a
2181 * 13-bit displacement and are only to be used
2182 * for local branches: flag as error, don't generate
2185 as_bad("can't use COBR format with external label");
2186 fixP
->fx_addsy
= NULL
; /* No relocations please. */
2189 #endif /* TC_I960 */
2196 } /* switch on symbol seg */
2197 } /* if not in local seg */
2198 } /* if there was a + symbol */
2201 add_number
-= md_pcrel_from(fixP
);
2202 if (add_symbolP
== 0) {
2203 fixP
->fx_addsy
= & abs_symbol
;
2204 } /* if there's an add_symbol */
2207 if (!fixP
->fx_bit_fixP
) {
2209 (add_number
& ~0xFF) && (add_number
&~0xFF!=(-1&~0xFF))) ||
2211 (add_number
& ~0xFFFF) && (add_number
&~0xFFFF!=(-1&~0xFFFF)))) {
2212 as_bad("Value of %d too large for field of %d bytes at 0x%x",
2213 add_number
, size
, fragP
->fr_address
+ where
);
2214 } /* generic error checking */
2215 } /* not a bit fix */
2216 /* once this fix has been applied, we don't have to output anything
2217 nothing more need be done -*/
2218 md_apply_fix(fixP
, add_number
);
2220 } /* For each fixS in this segment. */
2223 } /* fixup_segment() */