1 /* coff object file format with bfd
2 Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc.
4 This file is part of GAS.
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
22 How does this releate to the rest of GAS ?
24 Well, all the other files in gas are more or less a black box. It
25 takes care of opening files, parsing command lines, stripping blanks
26 etc etc. This module gets a chance to register what it wants to do by
27 saying that it is interested in various pseduo ops. The other big
28 change is write_object_file. This runs through all the data
29 structures that gas builds, and outputs the file in the format of our
32 Hacked for BFDness by steve chamberlain
34 This object module now supports the Hitachi H8/300 and the AMD 29k
43 #include "../bfd/libbfd.h"
46 /* This vector is used to turn an internal segment into a section #
47 suitable for insertion into a coff symbol table
50 const short seg_N_TYPE
[] = { /* in: segT out: N_TYPE bits */
62 C_UNDEF_SECTION
, /* SEG_UNKNOWN */
63 C_UNDEF_SECTION
, /* SEG_ABSENT */
64 C_UNDEF_SECTION
, /* SEG_PASS1 */
65 C_UNDEF_SECTION
, /* SEG_GOOF */
66 C_UNDEF_SECTION
, /* SEG_BIG */
67 C_UNDEF_SECTION
, /* SEG_DIFFERENCE */
68 C_DEBUG_SECTION
, /* SEG_DEBUG */
69 C_NTV_SECTION
, /* SEG_NTV */
70 C_PTV_SECTION
, /* SEG_PTV */
71 C_REGISTER_SECTION
, /* SEG_REGISTER */
75 int function_lineoff
= -1; /* Offset in line#s where the last function
76 started (the odd entry for line #0) */
82 static symbolS
*last_line_symbol
;
83 /* Add 4 to the real value to get the index and compensate the
84 negatives. This vector is used by S_GET_SEGMENT to turn a coff
85 section number into a segment number
87 static symbolS
*previous_file_symbol
= NULL
;
88 void c_symbol_merge();
91 symbolS
*c_section_symbol();
93 void EXFUN(bfd_as_write_hook
,(struct internal_filehdr
*,
96 static void EXFUN(fixup_segment
,(fixS
* fixP
,
97 segT this_segment_type
));
99 static void EXFUN(fill_section
,(bfd
*abfd
,
100 struct internal_filehdr
*f
, unsigned
104 char *EXFUN(s_get_name
,(symbolS
*s
));
105 static symbolS
*EXFUN(tag_find_or_make
,(char *name
));
106 static symbolS
* EXFUN(tag_find
,(char *name
));
113 unsigned short line_number
,
117 static void EXFUN(w_symbols
,
120 symbolS
*symbol_rootP
));
124 static void EXFUN( obj_coff_def
,(int what
));
125 static void EXFUN( obj_coff_lcomm
,(void));
126 static void EXFUN( obj_coff_dim
,(void));
127 static void EXFUN( obj_coff_text
,(void));
128 static void EXFUN( obj_coff_data
,(void));
129 static void EXFUN( obj_coff_endef
,(void));
130 static void EXFUN( obj_coff_line
,(void));
131 static void EXFUN( obj_coff_ln
,(void));
132 static void EXFUN( obj_coff_scl
,(void));
133 static void EXFUN( obj_coff_size
,(void));
134 static void EXFUN( obj_coff_tag
,(void));
135 static void EXFUN( obj_coff_type
,(void));
136 static void EXFUN( obj_coff_val
,(void));
137 static void EXFUN( obj_coff_section
,(void));
138 static void EXFUN( tag_init
,(void));
139 static void EXFUN( tag_insert
,(char *name
, symbolS
*symbolP
));
142 static struct hash_control
*tag_hash
;
143 static symbolS
*def_symbol_in_progress
= NULL
;
145 const pseudo_typeS obj_pseudo_table
[] = {
146 { "def", obj_coff_def
, 0 },
147 { "dim", obj_coff_dim
, 0 },
148 { "endef", obj_coff_endef
, 0 },
149 { "line", obj_coff_line
, 0 },
150 { "ln", obj_coff_ln
, 0 },
151 { "scl", obj_coff_scl
, 0 },
152 { "size", obj_coff_size
, 0 },
153 { "tag", obj_coff_tag
, 0 },
154 { "type", obj_coff_type
, 0 },
155 { "val", obj_coff_val
, 0 },
156 { "section", obj_coff_section
, 0 },
157 { "text", obj_coff_text
, 0 },
158 { "data", obj_coff_data
, 0 },
159 /* we don't yet handle this. */
160 { "ident", s_ignore
, 0 },
161 { "ABORT", s_abort
, 0 },
162 { "lcomm", obj_coff_lcomm
, 0},
163 { NULL
} /* end sentinel */
164 }; /* obj_pseudo_table */
170 We allow more than just the standard 3 sections, infact, we allow
171 10 sections, (though the usual three have to be there).
173 This structure performs the mappings for us:
178 static struct internal_scnhdr bss_section_header;
179 struct internal_scnhdr data_section_header;
180 struct internal_scnhdr text_section_header;
182 const segT N_TYPE_seg [32] =
196 seg_info_type seg_info_off_by_4
[N_SEG
] =
222 {SEG_REGISTER
},0,0,0,0};
224 #define SEG_INFO_FROM_SECTION_NUMBER(x) (seg_info_off_by_4[(x)+4])
225 #define SEG_INFO_FROM_SEG_NUMBER(x) (seg_info_off_by_4[(x)])
229 DEFUN(relax_align
,(address
, alignment
),
230 register relax_addressT address AND
231 register long alignment
)
234 relax_addressT new_address
;
236 mask
= ~ ( (~0) << alignment
);
237 new_address
= (address
+ mask
) & (~ mask
);
238 return (new_address
- address
);
239 } /* relax_align() */
243 DEFUN(s_get_segment
,(x
) ,
246 return SEG_INFO_FROM_SECTION_NUMBER(x
->sy_symbol
.ost_entry
.n_scnum
).seg_t
;
251 /* calculate the size of the frag chain and fill in the section header
252 to contain all of it, also fill in the addr of the sections */
253 static unsigned int DEFUN(size_section
,(abfd
, idx
),
258 unsigned int size
= 0;
259 fragS
*frag
= segment_info
[idx
].frchainP
->frch_root
;
261 if (frag
->fr_address
!= size
) {
262 printf("Out of step\n");
263 size
= frag
->fr_address
;
265 size
+= frag
->fr_fix
;
266 switch (frag
->fr_type
) {
269 size
+= frag
->fr_offset
* frag
->fr_var
;
272 size
+= relax_align(size
, frag
->fr_offset
);
274 frag
= frag
->fr_next
;
276 segment_info
[idx
].scnhdr
.s_size
= size
;
281 static unsigned int DEFUN(count_entries_in_chain
,(idx
),
284 unsigned int nrelocs
;
287 /* Count the relocations */
288 fixup_ptr
= segment_info
[idx
].fix_root
;
290 while (fixup_ptr
!= (fixS
*)NULL
)
292 if (TC_COUNT_RELOC(fixup_ptr
))
297 if (fixup_ptr
->fx_r_type
== RELOC_CONSTH
)
306 fixup_ptr
= fixup_ptr
->fx_next
;
311 /* output all the relocations for a section */
312 void DEFUN(do_relocs_for
,(abfd
, file_cursor
),
314 unsigned long *file_cursor
)
316 unsigned int nrelocs
;
319 for (idx
= SEG_E0
; idx
< SEG_E9
; idx
++)
321 if (segment_info
[idx
].scnhdr
.s_name
[0])
324 struct external_reloc
*ext_ptr
;
325 struct external_reloc
*external_reloc_vec
;
326 unsigned int external_reloc_size
;
327 unsigned int count
= 0;
328 unsigned int base
= segment_info
[idx
].scnhdr
.s_paddr
;
329 fixS
* fix_ptr
= segment_info
[idx
].fix_root
;
330 nrelocs
= count_entries_in_chain(idx
);
335 external_reloc_size
= nrelocs
* RELSZ
;
337 (struct external_reloc
*)malloc(external_reloc_size
);
341 ext_ptr
= external_reloc_vec
;
343 /* Fill in the internal coff style reloc struct from the
348 struct internal_reloc intr
;
350 /* Only output some of the relocations */
351 if (TC_COUNT_RELOC(fix_ptr
))
353 #ifdef TC_RELOC_MANGLE
354 TC_RELOC_MANGLE(fix_ptr
, &intr
, base
);
358 symbol_ptr
= fix_ptr
->fx_addsy
;
360 intr
.r_type
= TC_COFF_FIX2RTYPE(fix_ptr
);
362 base
+ fix_ptr
->fx_frag
->fr_address
+ fix_ptr
->fx_where
;
364 intr
.r_offset
= fix_ptr
->fx_offset
;
368 /* Turn the segment of the symbol into an offset
372 dot
= segment_info
[S_GET_SEGMENT(symbol_ptr
)].dot
;
375 intr
.r_symndx
= dot
->sy_number
;
379 intr
.r_symndx
= symbol_ptr
->sy_number
;
391 (void)bfd_coff_swap_reloc_out(abfd
, &intr
, ext_ptr
);
395 /* The 29k has a special kludge for the high 16 bit reloc.
396 Two relocations are emmited, R_IHIHALF, and
397 R_IHCONST. The second one doesn't contain a symbol,
398 but uses the value for offset */
400 if (intr
.r_type
== R_IHIHALF
)
402 /* now emit the second bit */
403 intr
.r_type
= R_IHCONST
;
404 intr
.r_symndx
= fix_ptr
->fx_addnumber
;
405 (void)bfd_coff_swap_reloc_out(abfd
,&intr
,ext_ptr
);
411 fix_ptr
= fix_ptr
->fx_next
;
414 /* Write out the reloc table */
415 segment_info
[idx
].scnhdr
.s_relptr
= *file_cursor
;
416 segment_info
[idx
].scnhdr
.s_nreloc
= nrelocs
;
417 bfd_write((PTR
)external_reloc_vec
, 1, external_reloc_size
, abfd
);
418 *file_cursor
+= external_reloc_size
;
419 free( external_reloc_vec
);
425 /* run through a frag chain and write out the data to go with it, fill
426 in the scnhdrs with the info on the file postions
428 static void DEFUN(fill_section
,(abfd
, filehdr
, file_cursor
),
430 struct internal_filehdr
*filehdr AND
431 unsigned long *file_cursor
)
435 unsigned int paddr
= 0;
437 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
439 unsigned int offset
= 0;
441 struct internal_scnhdr
*s
= &( segment_info
[i
].scnhdr
);
445 fragS
*frag
= segment_info
[i
].frchainP
->frch_root
;
446 char *buffer
= malloc(s
->s_size
);
449 s
->s_scnptr
= *file_cursor
;
463 s
->s_flags
= STYP_REG
;
464 if (strcmp(s
->s_name
,".text")==0)
465 s
->s_flags
|= STYP_TEXT
;
466 else if (strcmp(s
->s_name
,".data")==0)
467 s
->s_flags
|= STYP_DATA
;
468 else if (strcmp(s
->s_name
,".bss")==0)
469 s
->s_flags
|= STYP_BSS
| STYP_NOLOAD
;
472 unsigned int fill_size
;
473 switch (frag
->fr_type
) {
480 memcpy(buffer
+ frag
->fr_address
,
483 offset
+= frag
->fr_fix
;
486 fill_size
= frag
->fr_var
;
490 unsigned int off
= frag
->fr_fix
;
491 for (count
= frag
->fr_offset
; count
; count
--)
493 memcpy(buffer
+ frag
->fr_address
+ off
,
494 frag
->fr_literal
+ frag
->fr_fix
,
506 frag
= frag
->fr_next
;
510 bfd_write(buffer
, s
->s_size
,1,abfd
);
513 *file_cursor
+= s
->s_size
;
522 /* Coff file generation & utilities */
526 DEFUN(coff_header_append
,(abfd
, filehdr
, aouthdr
),
528 struct internal_filehdr
*filehdr AND
529 struct internal_aouthdr
*aouthdr
)
535 bfd_seek(abfd
, 0, 0);
537 filehdr
.f_opthdr
= bfd_coff_swap_aouthdr_out(abfd
, aouthdr
,
540 filehdr
->f_opthdr
= 0;
542 i
= bfd_coff_swap_filehdr_out(abfd
, filehdr
, buffer
);
544 bfd_write(buffer
, i
,1, abfd
);
545 bfd_write(buffero
, filehdr
->f_opthdr
, 1, abfd
);
547 for (i
= SEG_E0
; i
< SEG_E9
; i
++)
549 if (segment_info
[i
].scnhdr
.s_name
[0])
552 bfd_coff_swap_scnhdr_out(abfd
,
553 &(segment_info
[i
].scnhdr
),
555 bfd_write(buffer
, size
, 1, abfd
);
562 DEFUN(symbol_to_chars
,(abfd
, where
, symbolP
),
567 unsigned int numaux
= symbolP
->sy_symbol
.ost_entry
.n_numaux
;
570 /* Turn any symbols with register attributes into abs symbols */
571 if (S_GET_SEGMENT(symbolP
) == SEG_REGISTER
)
573 S_SET_SEGMENT(symbolP
, SEG_ABSOLUTE
);
575 /* At the same time, relocate all symbols to their output value */
578 segment_info
[S_GET_SEGMENT(symbolP
)].scnhdr
.s_paddr
579 + S_GET_VALUE(symbolP
));
581 where
+= bfd_coff_swap_sym_out(abfd
, &symbolP
->sy_symbol
.ost_entry
,
584 for (i
= 0; i
< numaux
; i
++)
586 where
+= bfd_coff_swap_aux_out(abfd
,
587 &symbolP
->sy_symbol
.ost_auxent
[i
],
588 S_GET_DATA_TYPE(symbolP
),
589 S_GET_STORAGE_CLASS(symbolP
),
599 void obj_symbol_new_hook(symbolP
)
602 char underscore
= 0; /* Symbol has leading _ */
604 /* Effective symbol */
605 /* Store the pointer in the offset. */
606 S_SET_ZEROES(symbolP
, 0L);
607 S_SET_DATA_TYPE(symbolP
, T_NULL
);
608 S_SET_STORAGE_CLASS(symbolP
, 0);
609 S_SET_NUMBER_AUXILIARY(symbolP
, 0);
610 /* Additional information */
611 symbolP
->sy_symbol
.ost_flags
= 0;
612 /* Auxiliary entries */
613 bzero((char*)&symbolP
->sy_symbol
.ost_auxent
[0], AUXESZ
);
615 #ifdef STRIP_UNDERSCORE
616 /* Remove leading underscore at the beginning of the symbol.
617 * This is to be compatible with the standard librairies.
619 if (*S_GET_NAME(symbolP
) == '_') {
621 S_SET_NAME(symbolP
, S_GET_NAME(symbolP
) + 1);
622 } /* strip underscore */
623 #endif /* STRIP_UNDERSCORE */
625 if (S_IS_STRING(symbolP
))
626 SF_SET_STRING(symbolP
);
627 if (!underscore
&& S_IS_LOCAL(symbolP
))
628 SF_SET_LOCAL(symbolP
);
631 } /* obj_symbol_new_hook() */
634 stack
* stack_init(chunk_size
, element_size
)
635 unsigned long chunk_size
;
636 unsigned long element_size
;
640 if ((st
= (stack
*)malloc(sizeof(stack
))) == (stack
*)0)
642 if ((st
->data
= malloc(chunk_size
)) == (char*)0) {
647 st
->size
= chunk_size
;
648 st
->chunk_size
= chunk_size
;
649 st
->element_size
= element_size
;
653 void stack_delete(st
)
660 char *stack_push(st
, element
)
664 if (st
->pointer
+ st
->element_size
>= st
->size
) {
665 st
->size
+= st
->chunk_size
;
666 if ((st
->data
= xrealloc(st
->data
, st
->size
)) == (char*)0)
669 memcpy(st
->data
+ st
->pointer
, element
, st
->element_size
);
670 st
->pointer
+= st
->element_size
;
671 return st
->data
+ st
->pointer
;
677 if ((st
->pointer
-= st
->element_size
) < 0) {
682 return st
->data
+ st
->pointer
;
688 return st
->data
+ st
->pointer
- st
->element_size
;
693 * Handle .ln directives.
696 static void obj_coff_ln()
700 if (def_symbol_in_progress
!= NULL
) {
701 as_warn(".ln pseudo-op inside .def/.endef: ignored.");
702 demand_empty_rest_of_line();
704 } /* wrong context */
707 obstack_next_free(&frags
) - frag_now
->fr_literal
,
708 l
= get_absolute_expression(),
716 listing_source_line(l
+ line_base
- 1);
721 demand_empty_rest_of_line();
723 } /* obj_coff_line() */
728 * Handle .def directives.
730 * One might ask : why can't we symbol_new if the symbol does not
731 * already exist and fill it with debug information. Because of
732 * the C_EFCN special symbol. It would clobber the value of the
733 * function symbol before we have a chance to notice that it is
734 * a C_EFCN. And a second reason is that the code is more clear this
735 * way. (at least I think it is :-).
739 #define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';')
740 #define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \
741 *input_line_pointer == '\t') \
742 input_line_pointer++;
745 DEFUN(obj_coff_def
,(what
),
748 char name_end
; /* Char after the end of name */
749 char *symbol_name
; /* Name of the debug symbol */
750 char *symbol_name_copy
; /* Temporary copy of the name */
751 unsigned int symbol_name_length
;
752 /*$char* directiveP;$ */ /* Name of the pseudo opcode */
753 /*$char directive[MAX_DIRECTIVE];$ */ /* Backup of the directive */
754 /*$char end = 0;$ */ /* If 1, stop parsing */
756 if (def_symbol_in_progress
!= NULL
) {
757 as_warn(".def pseudo-op used inside of .def/.endef: ignored.");
758 demand_empty_rest_of_line();
760 } /* if not inside .def/.endef */
764 def_symbol_in_progress
= (symbolS
*) obstack_alloc(¬es
, sizeof(*def_symbol_in_progress
));
765 bzero(def_symbol_in_progress
, sizeof(*def_symbol_in_progress
));
767 symbol_name
= input_line_pointer
;
768 name_end
= get_symbol_end();
769 symbol_name_length
= strlen(symbol_name
);
770 symbol_name_copy
= xmalloc(symbol_name_length
+ 1);
771 strcpy(symbol_name_copy
, symbol_name
);
773 /* Initialize the new symbol */
774 #ifdef STRIP_UNDERSCORE
775 S_SET_NAME(def_symbol_in_progress
, (*symbol_name_copy
== '_'
776 ? symbol_name_copy
+ 1
777 : symbol_name_copy
));
778 #else /* STRIP_UNDERSCORE */
779 S_SET_NAME(def_symbol_in_progress
, symbol_name_copy
);
780 #endif /* STRIP_UNDERSCORE */
781 /* free(symbol_name_copy); */
782 def_symbol_in_progress
->sy_name_offset
= ~0;
783 def_symbol_in_progress
->sy_number
= ~0;
784 def_symbol_in_progress
->sy_frag
= &zero_address_frag
;
786 if (S_IS_STRING(def_symbol_in_progress
)) {
787 SF_SET_STRING(def_symbol_in_progress
);
790 *input_line_pointer
= name_end
;
792 demand_empty_rest_of_line();
794 } /* obj_coff_def() */
796 unsigned int dim_index
;
798 DEFUN_VOID(obj_coff_endef
)
800 symbolS
*symbolP
= 0;
801 /* DIM BUG FIX sac@cygnus.com */
803 if (def_symbol_in_progress
== NULL
) {
804 as_warn(".endef pseudo-op used outside of .def/.endef: ignored.");
805 demand_empty_rest_of_line();
807 } /* if not inside .def/.endef */
809 /* Set the section number according to storage class. */
810 switch (S_GET_STORAGE_CLASS(def_symbol_in_progress
)) {
814 SF_SET_TAG(def_symbol_in_progress
);
815 /* intentional fallthrough */
818 SF_SET_DEBUG(def_symbol_in_progress
);
819 S_SET_SEGMENT(def_symbol_in_progress
, SEG_DEBUG
);
823 SF_SET_LOCAL(def_symbol_in_progress
); /* Do not emit this symbol. */
824 /* intentional fallthrough */
826 SF_SET_PROCESS(def_symbol_in_progress
); /* Will need processing before writing */
827 /* intentional fallthrough */
829 S_SET_SEGMENT(def_symbol_in_progress
, SEG_E0
);
831 if (def_symbol_in_progress
->sy_symbol
.ost_entry
._n
._n_nptr
[1][1] == 'b'
832 && def_symbol_in_progress
->sy_symbol
.ost_entry
._n
._n_nptr
[1][2] == 'f') { /* .bf */
833 if (function_lineoff
< 0) {
834 fprintf(stderr
, "`.bf' symbol without preceding function\n");
835 } /* missing function symbol */
836 SA_GET_SYM_LNNOPTR(last_line_symbol
) = function_lineoff
;
838 SF_SET_PROCESS(last_line_symbol
);
839 function_lineoff
= -1;
845 #endif /* C_AUTOARG */
855 SF_SET_DEBUG(def_symbol_in_progress
);
856 S_SET_SEGMENT(def_symbol_in_progress
, SEG_ABSOLUTE
);
862 /* Valid but set somewhere else (s_comm, s_lcomm, colon) */
868 as_warn("unexpected storage class %d", S_GET_STORAGE_CLASS(def_symbol_in_progress
));
870 } /* switch on storage class */
872 /* Now that we have built a debug symbol, try to
873 find if we should merge with an existing symbol
874 or not. If a symbol is C_EFCN or SEG_ABSOLUTE or
875 untagged SEG_DEBUG it never merges. */
877 /* Two cases for functions. Either debug followed
878 by definition or definition followed by debug.
879 For definition first, we will merge the debug
880 symbol into the definition. For debug first, the
881 lineno entry MUST point to the definition
882 function or else it will point off into space
883 when crawl_symbols() merges the debug
884 symbol into the real symbol. Therefor, let's
885 presume the debug symbol is a real function
888 /* FIXME-SOON If for some reason the definition
889 label/symbol is never seen, this will probably
890 leave an undefined symbol at link time. */
892 if (S_GET_STORAGE_CLASS(def_symbol_in_progress
) == C_EFCN
893 || (S_GET_SEGMENT(def_symbol_in_progress
) == SEG_DEBUG
894 && !SF_GET_TAG(def_symbol_in_progress
))
895 || S_GET_SEGMENT(def_symbol_in_progress
) == SEG_ABSOLUTE
896 || (symbolP
= symbol_find_base(S_GET_NAME(def_symbol_in_progress
), DO_NOT_STRIP
)) == NULL
) {
898 symbol_append(def_symbol_in_progress
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
901 /* This symbol already exists, merge the
902 newly created symbol into the old one.
903 This is not mandatory. The linker can
904 handle duplicate symbols correctly. But I
905 guess that it save a *lot* of space if
906 the assembly file defines a lot of
909 /* The debug entry (def_symbol_in_progress)
910 is merged into the previous definition. */
912 c_symbol_merge(def_symbol_in_progress
, symbolP
);
913 /* FIXME-SOON Should *def_symbol_in_progress be free'd? xoxorich. */
914 def_symbol_in_progress
= symbolP
;
916 if (SF_GET_FUNCTION(def_symbol_in_progress
)
917 || SF_GET_TAG(def_symbol_in_progress
)) {
918 /* For functions, and tags, the symbol *must* be where the debug symbol
919 appears. Move the existing symbol to the current place. */
920 /* If it already is at the end of the symbol list, do nothing */
921 if (def_symbol_in_progress
!= symbol_lastP
) {
922 symbol_remove(def_symbol_in_progress
, &symbol_rootP
, &symbol_lastP
);
923 symbol_append(def_symbol_in_progress
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
924 } /* if not already in place */
926 } /* normal or mergable */
928 if (SF_GET_TAG(def_symbol_in_progress
)
929 && symbol_find_base(S_GET_NAME(def_symbol_in_progress
), DO_NOT_STRIP
) == NULL
) {
930 tag_insert(S_GET_NAME(def_symbol_in_progress
), def_symbol_in_progress
);
931 } /* If symbol is a {structure,union} tag, associate symbol to its name. */
933 if (SF_GET_FUNCTION(def_symbol_in_progress
)) {
934 know(sizeof(def_symbol_in_progress
) <= sizeof(long));
936 = c_line_new(def_symbol_in_progress
,0, 0, &zero_address_frag
);
940 SF_SET_PROCESS(def_symbol_in_progress
);
942 if (symbolP
== NULL
) {
943 /* That is, if this is the first
944 time we've seen the function... */
945 symbol_table_insert(def_symbol_in_progress
);
946 } /* definition follows debug */
947 } /* Create the line number entry pointing to the function being defined */
949 def_symbol_in_progress
= NULL
;
950 demand_empty_rest_of_line();
952 } /* obj_coff_endef() */
955 DEFUN_VOID(obj_coff_dim
)
957 register int dim_index
;
959 if (def_symbol_in_progress
== NULL
)
961 as_warn(".dim pseudo-op used outside of .def/.endef: ignored.");
962 demand_empty_rest_of_line();
964 } /* if not inside .def/.endef */
966 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
968 for (dim_index
= 0; dim_index
< DIMNUM
; dim_index
++)
971 SA_SET_SYM_DIMEN(def_symbol_in_progress
, dim_index
, get_absolute_expression());
973 switch (*input_line_pointer
)
977 input_line_pointer
++;
981 as_warn("badly formed .dim directive ignored");
982 /* intentional fallthrough */
987 } /* switch on following character */
988 } /* for each dimension */
990 demand_empty_rest_of_line();
992 } /* obj_coff_dim() */
994 static void obj_coff_line()
998 if (def_symbol_in_progress
== NULL
) {
1001 } /* if it looks like a stabs style line */
1003 this_base
= get_absolute_expression();
1004 if (this_base
> line_base
)
1006 line_base
= this_base
;
1014 listing_source_line(line_base
);
1018 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1019 SA_SET_SYM_LNNO(def_symbol_in_progress
, line_base
);
1021 demand_empty_rest_of_line();
1023 } /* obj_coff_line() */
1025 static void obj_coff_size() {
1026 if (def_symbol_in_progress
== NULL
) {
1027 as_warn(".size pseudo-op used outside of .def/.endef ignored.");
1028 demand_empty_rest_of_line();
1030 } /* if not inside .def/.endef */
1032 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1033 SA_SET_SYM_SIZE(def_symbol_in_progress
, get_absolute_expression());
1034 demand_empty_rest_of_line();
1036 } /* obj_coff_size() */
1038 static void obj_coff_scl() {
1039 if (def_symbol_in_progress
== NULL
) {
1040 as_warn(".scl pseudo-op used outside of .def/.endef ignored.");
1041 demand_empty_rest_of_line();
1043 } /* if not inside .def/.endef */
1045 S_SET_STORAGE_CLASS(def_symbol_in_progress
, get_absolute_expression());
1046 demand_empty_rest_of_line();
1048 } /* obj_coff_scl() */
1050 static void obj_coff_tag() {
1054 if (def_symbol_in_progress
== NULL
) {
1055 as_warn(".tag pseudo-op used outside of .def/.endef ignored.");
1056 demand_empty_rest_of_line();
1058 } /* if not inside .def/.endef */
1060 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1061 symbol_name
= input_line_pointer
;
1062 name_end
= get_symbol_end();
1064 /* Assume that the symbol referred to by .tag is always defined. */
1065 /* This was a bad assumption. I've added find_or_make. xoxorich. */
1066 SA_SET_SYM_TAGNDX(def_symbol_in_progress
, (long) tag_find_or_make(symbol_name
));
1067 if (SA_GET_SYM_TAGNDX(def_symbol_in_progress
) == 0L) {
1068 as_warn("tag not found for .tag %s", symbol_name
);
1071 SF_SET_TAGGED(def_symbol_in_progress
);
1072 *input_line_pointer
= name_end
;
1074 demand_empty_rest_of_line();
1076 } /* obj_coff_tag() */
1078 static void obj_coff_type() {
1079 if (def_symbol_in_progress
== NULL
) {
1080 as_warn(".type pseudo-op used outside of .def/.endef ignored.");
1081 demand_empty_rest_of_line();
1083 } /* if not inside .def/.endef */
1085 S_SET_DATA_TYPE(def_symbol_in_progress
, get_absolute_expression());
1087 if (ISFCN(S_GET_DATA_TYPE(def_symbol_in_progress
)) &&
1088 S_GET_STORAGE_CLASS(def_symbol_in_progress
) != C_TPDEF
) {
1089 SF_SET_FUNCTION(def_symbol_in_progress
);
1090 } /* is a function */
1092 demand_empty_rest_of_line();
1094 } /* obj_coff_type() */
1096 static void obj_coff_val() {
1097 if (def_symbol_in_progress
== NULL
) {
1098 as_warn(".val pseudo-op used outside of .def/.endef ignored.");
1099 demand_empty_rest_of_line();
1101 } /* if not inside .def/.endef */
1103 if (is_name_beginner(*input_line_pointer
)) {
1104 char *symbol_name
= input_line_pointer
;
1105 char name_end
= get_symbol_end();
1107 if (!strcmp(symbol_name
, ".")) {
1108 def_symbol_in_progress
->sy_frag
= frag_now
;
1109 S_SET_VALUE(def_symbol_in_progress
, obstack_next_free(&frags
) - frag_now
->fr_literal
);
1110 /* If the .val is != from the .def (e.g. statics) */
1111 } else if (strcmp(S_GET_NAME(def_symbol_in_progress
), symbol_name
)) {
1112 def_symbol_in_progress
->sy_forward
= symbol_find_or_make(symbol_name
);
1114 /* If the segment is undefined when the forward
1115 reference is solved, then copy the segment id
1116 from the forward symbol. */
1117 SF_SET_GET_SEGMENT(def_symbol_in_progress
);
1119 /* Otherwise, it is the name of a non debug symbol and its value will be calculated later. */
1120 *input_line_pointer
= name_end
;
1122 S_SET_VALUE(def_symbol_in_progress
, get_absolute_expression());
1123 } /* if symbol based */
1125 demand_empty_rest_of_line();
1127 } /* obj_coff_val() */
1130 * Maintain a list of the tagnames of the structres.
1133 static void tag_init() {
1134 tag_hash
= hash_new();
1138 static void tag_insert(name
, symbolP
)
1142 register char * error_string
;
1144 if (*(error_string
= hash_jam(tag_hash
, name
, (char *)symbolP
))) {
1145 as_fatal("Inserting \"%s\" into structure table failed: %s",
1146 name
, error_string
);
1149 } /* tag_insert() */
1151 static symbolS
*tag_find_or_make(name
)
1156 if ((symbolP
= tag_find(name
)) == NULL
) {
1157 symbolP
= symbol_new(name
,
1160 &zero_address_frag
);
1162 tag_insert(S_GET_NAME(symbolP
), symbolP
);
1163 symbol_table_insert(symbolP
);
1167 } /* tag_find_or_make() */
1169 static symbolS
*tag_find(name
)
1172 #ifdef STRIP_UNDERSCORE
1173 if (*name
== '_') name
++;
1174 #endif /* STRIP_UNDERSCORE */
1175 return((symbolS
*)hash_find(tag_hash
, name
));
1178 void obj_read_begin_hook() {
1179 /* These had better be the same. Usually 18 bytes. */
1181 know(sizeof(SYMENT
) == sizeof(AUXENT
));
1182 know(SYMESZ
== AUXESZ
);
1187 } /* obj_read_begin_hook() */
1189 /* This function runs through the symbol table and puts all the
1190 externals onto another chain */
1192 /* The chain of externals */
1193 symbolS
*symbol_externP
= NULL
;
1194 symbolS
*symbol_extern_lastP
= NULL
;
1197 symbolS
*last_functionP
= NULL
;
1201 static unsigned int DEFUN_VOID(yank_symbols
)
1204 unsigned int symbol_number
=0;
1206 for (symbolP
= symbol_rootP
;
1208 symbolP
= symbolP
? symbol_next(symbolP
) : symbol_rootP
) {
1209 if (!SF_GET_DEBUG(symbolP
)) {
1210 /* Debug symbols do not need all this rubbish */
1211 symbolS
* real_symbolP
;
1213 /* L* and C_EFCN symbols never merge. */
1214 if (!SF_GET_LOCAL(symbolP
)
1215 && (real_symbolP
= symbol_find_base(S_GET_NAME(symbolP
), DO_NOT_STRIP
))
1216 && real_symbolP
!= symbolP
) {
1217 /* FIXME-SOON: where do dups come from?
1218 Maybe tag references before definitions? xoxorich. */
1219 /* Move the debug data from the debug symbol to the
1220 real symbol. Do NOT do the oposite (i.e. move from
1221 real symbol to debug symbol and remove real symbol from the
1222 list.) Because some pointers refer to the real symbol
1223 whereas no pointers refer to the debug symbol. */
1224 c_symbol_merge(symbolP
, real_symbolP
);
1225 /* Replace the current symbol by the real one */
1226 /* The symbols will never be the last or the first
1227 because : 1st symbol is .file and 3 last symbols are
1228 .text, .data, .bss */
1229 symbol_remove(real_symbolP
, &symbol_rootP
, &symbol_lastP
);
1230 symbol_insert(real_symbolP
, symbolP
, &symbol_rootP
, &symbol_lastP
);
1231 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1232 symbolP
= real_symbolP
;
1233 } /* if not local but dup'd */
1235 if (flagseen
['R'] && (S_GET_SEGMENT(symbolP
) == SEG_E1
)) {
1236 S_SET_SEGMENT(symbolP
, SEG_E0
);
1237 } /* push data into text */
1239 S_SET_VALUE(symbolP
,
1240 S_GET_VALUE(symbolP
) + symbolP
->sy_frag
->fr_address
);
1242 if (!S_IS_DEFINED(symbolP
) && !SF_GET_LOCAL(symbolP
))
1244 S_SET_EXTERNAL(symbolP
);
1246 else if (S_GET_STORAGE_CLASS(symbolP
) == C_NULL
)
1248 if (S_GET_SEGMENT(symbolP
) == SEG_E0
)
1250 S_SET_STORAGE_CLASS(symbolP
, C_LABEL
);
1254 S_SET_STORAGE_CLASS(symbolP
, C_STAT
);
1258 /* Mainly to speed up if not -g */
1259 if (SF_GET_PROCESS(symbolP
))
1261 /* Handle the nested blocks auxiliary info. */
1262 if (S_GET_STORAGE_CLASS(symbolP
) == C_BLOCK
) {
1263 if (!strcmp(S_GET_NAME(symbolP
), ".bb"))
1264 stack_push(block_stack
, (char *) &symbolP
);
1266 register symbolS
* begin_symbolP
;
1267 begin_symbolP
= *(symbolS
**)stack_pop(block_stack
);
1268 if (begin_symbolP
== (symbolS
*)0)
1269 as_warn("mismatched .eb");
1271 SA_SET_SYM_ENDNDX(begin_symbolP
, symbol_number
+2);
1274 /* If we are able to identify the type of a function, and we
1275 are out of a function (last_functionP == 0) then, the
1276 function symbol will be associated with an auxiliary
1278 if (last_functionP
== (symbolS
*)0 &&
1279 SF_GET_FUNCTION(symbolP
)) {
1280 last_functionP
= symbolP
;
1282 if (S_GET_NUMBER_AUXILIARY(symbolP
) < 1) {
1283 S_SET_NUMBER_AUXILIARY(symbolP
, 1);
1284 } /* make it at least 1 */
1286 /* Clobber possible stale .dim information. */
1288 /* Iffed out by steve - this fries the lnnoptr info too */
1289 bzero(symbolP
->sy_symbol
.ost_auxent
[0].x_sym
.x_fcnary
.x_ary
.x_dimen
,
1290 sizeof(symbolP
->sy_symbol
.ost_auxent
[0].x_sym
.x_fcnary
.x_ary
.x_dimen
));
1293 /* The C_FCN doesn't need any additional information.
1294 I don't even know if this is needed for sdb. But the
1295 standard assembler generates it, so...
1297 if (S_GET_STORAGE_CLASS(symbolP
) == C_EFCN
) {
1298 if (last_functionP
== (symbolS
*)0)
1299 as_fatal("C_EFCN symbol out of scope");
1300 SA_SET_SYM_FSIZE(last_functionP
,
1301 (long)(S_GET_VALUE(symbolP
) -
1302 S_GET_VALUE(last_functionP
)));
1303 SA_SET_SYM_ENDNDX(last_functionP
, symbol_number
);
1304 last_functionP
= (symbolS
*)0;
1307 } else if (SF_GET_TAG(symbolP
)) {
1308 /* First descriptor of a structure must point to
1309 the first slot after the structure description. */
1310 last_tagP
= symbolP
;
1312 } else if (S_GET_STORAGE_CLASS(symbolP
) == C_EOS
) {
1313 /* +2 take in account the current symbol */
1314 SA_SET_SYM_ENDNDX(last_tagP
, symbol_number
+ 2);
1315 } else if (S_GET_STORAGE_CLASS(symbolP
) == C_FILE
) {
1316 if (S_GET_VALUE(symbolP
)) {
1317 S_SET_VALUE((symbolS
*) S_GET_VALUE(symbolP
), symbol_number
);
1318 S_SET_VALUE(symbolP
, 0);
1319 } /* no one points at the first .file symbol */
1320 } /* if debug or tag or eos or file */
1322 /* We must put the external symbols apart. The loader
1323 does not bomb if we do not. But the references in
1324 the endndx field for a .bb symbol are not corrected
1325 if an external symbol is removed between .bb and .be.
1326 I.e in the following case :
1327 [20] .bb endndx = 22
1330 ld will move the symbol 21 to the end of the list but
1331 endndx will still be 22 instead of 21. */
1334 if (SF_GET_LOCAL(symbolP
)) {
1335 /* remove C_EFCN and LOCAL (L...) symbols */
1336 /* next pointer remains valid */
1337 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1340 else if (!S_IS_DEFINED(symbolP
)
1341 && !S_IS_DEBUG(symbolP
)
1342 && !SF_GET_STATICS(symbolP
) &&
1343 S_GET_STORAGE_CLASS(symbolP
) == C_EXT
)
1344 { /* C_EXT && !SF_GET_FUNCTION(symbolP)) */
1345 /* if external, Remove from the list */
1346 symbolS
*hold
= symbol_previous(symbolP
);
1348 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1349 symbol_clear_list_pointers(symbolP
);
1350 symbol_append(symbolP
, symbol_extern_lastP
, &symbol_externP
, &symbol_extern_lastP
);
1353 if (SF_GET_STRING(symbolP
)) {
1354 symbolP
->sy_name_offset
= string_byte_count
;
1355 string_byte_count
+= strlen(S_GET_NAME(symbolP
)) + 1;
1357 symbolP
->sy_name_offset
= 0;
1358 } /* fix "long" names */
1360 symbolP
->sy_number
= symbol_number
;
1361 symbol_number
+= 1 + S_GET_NUMBER_AUXILIARY(symbolP
);
1362 } /* if local symbol */
1363 } /* traverse the symbol list */
1364 return symbol_number
;
1369 static unsigned int DEFUN_VOID(glue_symbols
)
1371 unsigned int symbol_number
= 0;
1373 for (symbolP
= symbol_externP
; symbol_externP
;) {
1374 symbolS
*tmp
= symbol_externP
;
1377 symbol_remove(tmp
, &symbol_externP
, &symbol_extern_lastP
);
1378 symbol_append(tmp
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
1381 if (SF_GET_STRING(tmp
)) {
1382 tmp
->sy_name_offset
= string_byte_count
;
1383 string_byte_count
+= strlen(S_GET_NAME(tmp
)) + 1;
1385 tmp
->sy_name_offset
= 0;
1386 } /* fix "long" names */
1388 tmp
->sy_number
= symbol_number
;
1389 symbol_number
+= 1 + S_GET_NUMBER_AUXILIARY(tmp
);
1390 } /* append the entire extern chain */
1391 return symbol_number
;
1395 static unsigned int DEFUN_VOID(tie_tags
)
1397 unsigned int symbol_number
= 0;
1400 for (symbolP
= symbol_rootP
; symbolP
; symbolP
=
1401 symbol_next(symbolP
))
1403 symbolP
->sy_number
= symbol_number
;
1407 if (SF_GET_TAGGED(symbolP
))
1411 ((symbolS
*) SA_GET_SYM_TAGNDX(symbolP
))->sy_number
);
1414 symbol_number
+= 1 + S_GET_NUMBER_AUXILIARY(symbolP
);
1416 return symbol_number
;
1421 DEFUN(crawl_symbols
,(headers
, abfd
),
1422 struct internal_filehdr
*headers AND
1427 unsigned int ptr
= 0;
1432 /* Initialize the stack used to keep track of the matching .bb .be */
1434 block_stack
= stack_init(512, sizeof(symbolS
*));
1435 /* JF deal with forward references first... */
1436 for (symbolP
= symbol_rootP
;
1438 symbolP
= symbol_next(symbolP
))
1441 if (symbolP
->sy_forward
) {
1442 S_SET_VALUE(symbolP
, (S_GET_VALUE(symbolP
)
1443 + S_GET_VALUE(symbolP
->sy_forward
)
1444 + symbolP
->sy_forward
->sy_frag
->fr_address
));
1446 if (SF_GET_GET_SEGMENT(symbolP
)) {
1447 S_SET_SEGMENT(symbolP
, S_GET_SEGMENT(symbolP
->sy_forward
));
1448 } /* forward segment also */
1450 symbolP
->sy_forward
=0;
1451 } /* if it has a forward reference */
1452 } /* walk the symbol chain */
1455 /* The symbol list should be ordered according to the following sequence
1458 * . debug entries for functions
1459 * . fake symbols for the sections, including.text .data and .bss
1461 * . undefined symbols
1462 * But this is not mandatory. The only important point is to put the
1463 * undefined symbols at the end of the list.
1466 if (symbol_rootP
== NULL
1467 || S_GET_STORAGE_CLASS(symbol_rootP
) != C_FILE
) {
1468 c_dot_file_symbol("fake");
1470 /* Is there a .file symbol ? If not insert one at the beginning. */
1473 * Build up static symbols for the sections, they are filled in later
1477 for (i
= SEG_E0
; i
< SEG_E9
; i
++)
1479 if (segment_info
[i
].scnhdr
.s_name
[0])
1481 segment_info
[i
].dot
=
1482 c_section_symbol(segment_info
[i
].scnhdr
.s_name
,
1489 /* Take all the externals out and put them into another chain */
1490 headers
->f_nsyms
= yank_symbols();
1491 /* Take the externals and glue them onto the end.*/
1492 headers
->f_nsyms
+= glue_symbols();
1494 headers
->f_nsyms
= tie_tags();
1495 know(symbol_externP
== NULL
);
1496 know(symbol_extern_lastP
== NULL
);
1502 * Find strings by crawling along symbol table chain.
1505 void DEFUN(w_strings
,(where
),
1510 /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
1511 md_number_to_chars(where
, string_byte_count
, sizeof(string_byte_count
));
1512 where
+= sizeof(string_byte_count
);
1513 for (symbolP
= symbol_rootP
;
1515 symbolP
= symbol_next(symbolP
))
1519 if (SF_GET_STRING(symbolP
)) {
1520 size
= strlen(S_GET_NAME(symbolP
)) + 1;
1522 memcpy(where
, S_GET_NAME(symbolP
),size
);
1535 DEFUN(do_linenos_for
,(abfd
, file_cursor
),
1537 unsigned long *file_cursor
)
1541 for (idx
= SEG_E0
; idx
< SEG_E9
; idx
++)
1543 segment_info_type
*s
= segment_info
+ idx
;
1546 if (s
->scnhdr
.s_nlnno
!= 0)
1548 struct lineno_list
*line_ptr
;
1550 struct external_lineno
*buffer
=
1551 (struct external_lineno
*)xmalloc(s
->scnhdr
.s_nlnno
* LINESZ
);
1553 struct external_lineno
*dst
= buffer
;
1555 /* Run through the table we've built and turn it into its external
1556 form, take this chance to remove duplicates */
1558 for (line_ptr
= s
->lineno_list_head
;
1559 line_ptr
!= (struct lineno_list
*)NULL
;
1560 line_ptr
= line_ptr
->next
)
1563 if (line_ptr
->line
.l_lnno
== 0)
1565 /* Turn a pointer to a symbol into the symbols' index */
1566 line_ptr
->line
.l_addr
.l_symndx
=
1567 ( (symbolS
*)line_ptr
->line
.l_addr
.l_symndx
)->sy_number
;
1571 line_ptr
->line
.l_addr
.l_paddr
+= ((struct frag
* )(line_ptr
->frag
))->fr_address
;
1575 (void) bfd_coff_swap_lineno_out(abfd
, &(line_ptr
->line
), dst
);
1580 s
->scnhdr
.s_lnnoptr
= *file_cursor
;
1582 bfd_write(buffer
, 1, s
->scnhdr
.s_nlnno
* LINESZ
, abfd
);
1585 *file_cursor
+= s
->scnhdr
.s_nlnno
* LINESZ
;
1591 /* Now we run through the list of frag chains in a segment and
1592 make all the subsegment frags appear at the end of the
1593 list, as if the seg 0 was extra long */
1595 static void DEFUN_VOID(remove_subsegs
)
1599 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1601 frchainS
*head
= segment_info
[i
].frchainP
;
1603 fragS
* prev_frag
= &dummy
;
1605 while (head
&& head
->frch_seg
== i
)
1607 prev_frag
->fr_next
= head
->frch_root
;
1608 prev_frag
= head
->frch_last
;
1609 head
= head
->frch_next
;
1611 prev_frag
->fr_next
= 0;
1616 extern void DEFUN_VOID(write_object_file
)
1619 struct frchain
*frchain_ptr
;
1621 struct internal_filehdr filehdr
;
1622 struct internal_aouthdr aouthdr
;
1623 unsigned long file_cursor
;
1625 unsigned int addr
= 0;
1626 abfd
= bfd_openw(out_file_name
, TARGET_FORMAT
);
1630 as_perror ("FATAL: Can't create %s", out_file_name
);
1633 bfd_set_format(abfd
, bfd_object
);
1634 bfd_set_arch_mach(abfd
, BFD_ARCH
, 0);
1638 string_byte_count
= 4;
1640 for (frchain_ptr
= frchain_root
;
1641 frchain_ptr
!= (struct frchain
*)NULL
;
1642 frchain_ptr
= frchain_ptr
->frch_next
) {
1643 /* Run through all the sub-segments and align them up. Also close any
1644 open frags. We tack a .fill onto the end of the frag chain so
1645 that any .align's size can be worked by looking at the next
1648 subseg_new(frchain_ptr
->frch_seg
, frchain_ptr
->frch_subseg
);
1649 #define SUB_SEGMENT_ALIGN 1
1650 frag_align(SUB_SEGMENT_ALIGN
,0);
1651 frag_wane(frag_now
);
1652 frag_now
->fr_fix
= 0;
1653 know( frag_now
->fr_next
== NULL
);
1660 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1662 relax_segment(segment_info
[i
].frchainP
->frch_root
, i
);
1669 filehdr
.f_nscns
= 0;
1671 /* Find out how big the sections are */
1672 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1675 if (segment_info
[i
].scnhdr
.s_name
[0])
1682 /* THis is a special case, we leave the size alone, which will have */
1683 /* been made up from all and any lcomms seen */
1686 addr
+= size_section(abfd
, i
);
1692 /* Turn the gas native symbol table shape into a coff symbol table */
1693 crawl_symbols(&filehdr
, abfd
);
1695 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1697 fixup_segment(segment_info
[i
].fix_root
, i
);
1701 file_cursor
= FILHSZ
+ SCNHSZ
* filehdr
.f_nscns
;
1703 bfd_seek(abfd
, file_cursor
, 0);
1706 do_relocs_for(abfd
, &file_cursor
);
1708 do_linenos_for(abfd
, &file_cursor
);
1711 /* Plant the data */
1713 fill_section(abfd
,&filehdr
, &file_cursor
);
1715 filehdr
.f_magic
= COFF_MAGIC
;
1716 filehdr
.f_timdat
= time(0);
1717 filehdr
.f_flags
= COFF_FLAGS
;
1721 filehdr
.f_flags
|= F_LNNO
;
1725 filehdr
.f_flags
|= F_RELFLG
;
1736 unsigned int symtable_size
= filehdr
.f_nsyms
* SYMESZ
;
1737 char *buffer1
= malloc(symtable_size
+ string_byte_count
+ 4);
1738 char *ptr
= buffer1
;
1739 filehdr
.f_symptr
= bfd_tell(abfd
);
1740 w_symbols(abfd
, buffer1
, symbol_rootP
);
1741 w_strings(buffer1
+ symtable_size
);
1742 bfd_write(buffer1
, 1,symtable_size
+ string_byte_count
+ 4, abfd
);
1746 coff_header_append(abfd
, &filehdr
, &aouthdr
);
1748 bfd_close_all_done(abfd
);
1752 static void DEFUN(change_to_section
,(name
, len
, exp
),
1754 unsigned int len AND
1758 /* Find out if we've already got a section of this name etc */
1759 for(i
= SEG_E0
; i
< SEG_E9
&& segment_info
[i
].scnhdr
.s_name
[0] ; i
++)
1761 if (strncmp(segment_info
[i
].scnhdr
.s_name
, name
, len
) == 0)
1768 /* No section, add one */
1769 strncpy(segment_info
[i
].scnhdr
.s_name
, name
, 8);
1774 DEFUN_VOID(obj_coff_section
)
1776 /* Strip out the section name */
1777 char *section_name
;
1778 char *section_name_end
;
1784 section_name
= input_line_pointer
;
1785 c
= get_symbol_end();
1786 section_name_end
= input_line_pointer
;
1788 len
= section_name_end
- section_name
;
1789 input_line_pointer
++;
1793 exp
= get_absolute_expression();
1795 else if ( *input_line_pointer
== ',')
1798 input_line_pointer
++;
1799 exp
= get_absolute_expression();
1806 change_to_section(section_name
, len
,exp
);
1807 *section_name_end
= c
;
1812 static void obj_coff_text()
1814 change_to_section(".text",5, get_absolute_expression());
1818 static void obj_coff_data()
1820 change_to_section(".data",5, get_absolute_expression());
1823 void c_symbol_merge(debug
, normal
)
1827 S_SET_DATA_TYPE(normal
, S_GET_DATA_TYPE(debug
));
1828 S_SET_STORAGE_CLASS(normal
, S_GET_STORAGE_CLASS(debug
));
1830 if (S_GET_NUMBER_AUXILIARY(debug
) > S_GET_NUMBER_AUXILIARY(normal
)) {
1831 S_SET_NUMBER_AUXILIARY(normal
, S_GET_NUMBER_AUXILIARY(debug
));
1832 } /* take the most we have */
1834 if (S_GET_NUMBER_AUXILIARY(debug
) > 0) {
1835 memcpy((char*)&normal
->sy_symbol
.ost_auxent
[0], (char*)&debug
->sy_symbol
.ost_auxent
[0], S_GET_NUMBER_AUXILIARY(debug
) * AUXESZ
);
1836 } /* Move all the auxiliary information */
1838 /* Move the debug flags. */
1839 SF_SET_DEBUG_FIELD(normal
, SF_GET_DEBUG_FIELD(debug
));
1840 } /* c_symbol_merge() */
1843 DEFUN(c_line_new
,(symbol
, paddr
, line_number
, frag
),
1846 unsigned short line_number AND
1849 struct lineno_list
* new_line
=
1850 (struct lineno_list
*)xmalloc(sizeof(struct lineno_list
));
1852 segment_info_type
*s
= segment_info
+ now_seg
;
1853 new_line
->line
.l_lnno
= line_number
;
1857 if (line_number
== 0)
1859 last_line_symbol
= symbol
;
1860 new_line
->line
.l_addr
.l_symndx
= (long)symbol
;
1864 new_line
->line
.l_addr
.l_paddr
= paddr
;
1867 new_line
->frag
= (char*)frag
;
1868 new_line
->next
= (struct lineno_list
*)NULL
;
1871 if (s
->lineno_list_head
== (struct lineno_list
*)NULL
)
1873 s
->lineno_list_head
= new_line
;
1877 s
->lineno_list_tail
->next
= new_line
;
1879 s
->lineno_list_tail
= new_line
;
1880 return LINESZ
* s
->scnhdr
.s_nlnno
++;
1883 void c_dot_file_symbol(filename
)
1888 symbolP
= symbol_new(".file",
1891 &zero_address_frag
);
1893 S_SET_STORAGE_CLASS(symbolP
, C_FILE
);
1894 S_SET_NUMBER_AUXILIARY(symbolP
, 1);
1895 SA_SET_FILE_FNAME(symbolP
, filename
);
1901 listing_source_file(filename
);
1907 SF_SET_DEBUG(symbolP
);
1908 S_SET_VALUE(symbolP
, (long) previous_file_symbol
);
1910 previous_file_symbol
= symbolP
;
1912 /* Make sure that the symbol is first on the symbol chain */
1913 if (symbol_rootP
!= symbolP
) {
1914 if (symbolP
== symbol_lastP
) {
1915 symbol_lastP
= symbol_lastP
->sy_previous
;
1916 } /* if it was the last thing on the list */
1918 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1919 symbol_insert(symbolP
, symbol_rootP
, &symbol_rootP
, &symbol_lastP
);
1920 symbol_rootP
= symbolP
;
1921 } /* if not first on the list */
1923 } /* c_dot_file_symbol() */
1926 * Build a 'section static' symbol.
1929 symbolS
*c_section_symbol(name
,idx
)
1935 symbolP
= symbol_new(name
,idx
,
1937 &zero_address_frag
);
1939 S_SET_STORAGE_CLASS(symbolP
, C_STAT
);
1940 S_SET_NUMBER_AUXILIARY(symbolP
, 1);
1942 SF_SET_STATICS(symbolP
);
1945 } /* c_section_symbol() */
1948 DEFUN(w_symbols
,(abfd
, where
, symbol_rootP
),
1951 symbolS
*symbol_rootP
)
1956 /* First fill in those values we have only just worked out */
1957 for (i
= SEG_E0
; i
< SEG_E9
; i
++)
1959 symbolP
= segment_info
[i
].dot
;
1963 SA_SET_SCN_SCNLEN(symbolP
, segment_info
[i
].scnhdr
.s_size
);
1964 SA_SET_SCN_NRELOC(symbolP
, segment_info
[i
].scnhdr
.s_nreloc
);
1965 SA_SET_SCN_NLINNO(symbolP
, segment_info
[i
].scnhdr
.s_nlnno
);
1971 * Emit all symbols left in the symbol chain.
1973 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next(symbolP
)) {
1974 /* Used to save the offset of the name. It is used to point
1975 to the string in memory but must be a file offset. */
1976 register char * temp
;
1978 tc_coff_symbol_emit_hook(symbolP
);
1980 temp
= S_GET_NAME(symbolP
);
1981 if (SF_GET_STRING(symbolP
)) {
1982 S_SET_OFFSET(symbolP
, symbolP
->sy_name_offset
);
1983 S_SET_ZEROES(symbolP
, 0);
1985 bzero(symbolP
->sy_symbol
.ost_entry
.n_name
, SYMNMLEN
);
1986 strncpy(symbolP
->sy_symbol
.ost_entry
.n_name
, temp
, SYMNMLEN
);
1988 where
= symbol_to_chars(abfd
, where
, symbolP
);
1989 S_SET_NAME(symbolP
,temp
);
1994 static void DEFUN_VOID(obj_coff_lcomm
)
2001 name
= input_line_pointer
;
2005 c
= get_symbol_end();
2006 p
= input_line_pointer
;
2009 if (*input_line_pointer
!= ',') {
2010 as_bad("Expected comma after name");
2011 ignore_rest_of_line();
2014 if (*input_line_pointer
== '\n') {
2015 as_bad("Missing size expression");
2018 input_line_pointer
++;
2019 if ((temp
= get_absolute_expression ()) < 0) {
2020 as_warn("lcomm length (%d.) <0! Ignored.", temp
);
2021 ignore_rest_of_line();
2025 symbolP
= symbol_find_or_make(name
);
2026 S_SET_VALUE(symbolP
, segment_info
[SEG_E2
].scnhdr
.s_size
);
2027 S_SET_SEGMENT(symbolP
, SEG_E2
);
2028 segment_info
[SEG_E2
].scnhdr
.s_size
+= temp
;
2029 S_SET_STORAGE_CLASS(symbolP
, C_STAT
);
2030 demand_empty_rest_of_line();
2035 static void DEFUN(fixup_segment
,(fixP
, this_segment_type
),
2036 register fixS
* fixP AND
2037 segT this_segment_type
)
2039 register symbolS
*add_symbolP
;
2040 register symbolS
*sub_symbolP
;
2041 register long add_number
;
2043 register char *place
;
2044 register long where
;
2045 register char pcrel
;
2046 register fragS
*fragP
;
2047 register segT add_symbol_segment
= SEG_ABSOLUTE
;
2050 for ( ; fixP
; fixP
= fixP
->fx_next
)
2052 fragP
= fixP
->fx_frag
;
2054 where
= fixP
->fx_where
;
2055 place
= fragP
->fr_literal
+ where
;
2056 size
= fixP
->fx_size
;
2057 add_symbolP
= fixP
->fx_addsy
;
2059 if (fixP
->fx_callj
&& TC_S_IS_CALLNAME(add_symbolP
)) {
2060 /* Relocation should be done via the
2061 associated 'bal' entry point
2064 if (!TC_S_IS_BALNAME(tc_get_bal_of_call(add_symbolP
))) {
2065 as_bad("No 'bal' entry point for leafproc %s",
2066 S_GET_NAME(add_symbolP
));
2069 fixP
->fx_addsy
= add_symbolP
= tc_get_bal_of_call(add_symbolP
);
2070 } /* callj relocation */
2072 sub_symbolP
= fixP
->fx_subsy
;
2073 add_number
= fixP
->fx_offset
;
2074 pcrel
= fixP
->fx_pcrel
;
2077 add_symbol_segment
= S_GET_SEGMENT(add_symbolP
);
2078 } /* if there is an addend */
2083 if (S_GET_SEGMENT(sub_symbolP
) != SEG_ABSOLUTE
) {
2084 as_bad("Negative of non-absolute symbol %s", S_GET_NAME(sub_symbolP
));
2085 } /* not absolute */
2087 add_number
-= S_GET_VALUE(sub_symbolP
);
2089 /* if sub_symbol is in the same segment that add_symbol
2090 and add_symbol is either in DATA, TEXT, BSS or ABSOLUTE */
2091 } else if ((S_GET_SEGMENT(sub_symbolP
) == add_symbol_segment
)
2092 && (SEG_NORMAL(add_symbol_segment
)
2093 || (add_symbol_segment
== SEG_ABSOLUTE
))) {
2094 /* Difference of 2 symbols from same segment. */
2095 /* Can't make difference of 2 undefineds: 'value' means */
2096 /* something different for N_UNDF. */
2098 /* Makes no sense to use the difference of 2 arbitrary symbols
2099 * as the target of a call instruction.
2101 if (fixP
->fx_callj
) {
2102 as_bad("callj to difference of 2 symbols");
2104 #endif /* TC_I960 */
2105 add_number
+= S_GET_VALUE(add_symbolP
) -
2106 S_GET_VALUE(sub_symbolP
);
2109 fixP
->fx_addsy
= NULL
;
2111 /* Different segments in subtraction. */
2112 know(!(S_IS_EXTERNAL(sub_symbolP
) && (S_GET_SEGMENT(sub_symbolP
) == SEG_ABSOLUTE
)));
2114 if ((S_GET_SEGMENT(sub_symbolP
) == SEG_ABSOLUTE
)) {
2115 add_number
-= S_GET_VALUE(sub_symbolP
);
2117 as_bad("Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %d.",
2118 segment_name(S_GET_SEGMENT(sub_symbolP
)),
2119 S_GET_NAME(sub_symbolP
), fragP
->fr_address
+ where
);
2122 } /* if sub_symbolP */
2125 if (add_symbol_segment
== this_segment_type
&& pcrel
) {
2127 * This fixup was made when the symbol's segment was
2128 * SEG_UNKNOWN, but it is now in the local segment.
2129 * So we know how to do the address without relocation.
2132 /* reloc_callj() may replace a 'call' with a 'calls' or a 'bal',
2133 * in which cases it modifies *fixP as appropriate. In the case
2134 * of a 'calls', no further work is required, and *fixP has been
2135 * set up to make the rest of the code below a no-op.
2138 #endif /* TC_I960 */
2140 add_number
+= S_GET_VALUE(add_symbolP
);
2141 add_number
-= md_pcrel_from (fixP
);
2142 pcrel
= 0; /* Lie. Don't want further pcrel processing. */
2143 fixP
->fx_addsy
= NULL
; /* No relocations please. */
2146 switch (add_symbol_segment
)
2150 reloc_callj(fixP
); /* See comment about reloc_callj() above*/
2151 #endif /* TC_I960 */
2152 add_number
+= S_GET_VALUE(add_symbolP
);
2153 fixP
->fx_addsy
= NULL
;
2158 add_number
+= S_GET_VALUE(add_symbolP
) +
2159 segment_info
[S_GET_SEGMENT(add_symbolP
)].scnhdr
.s_paddr
;
2164 if ((int)fixP
->fx_bit_fixP
== 13) {
2165 /* This is a COBR instruction. They have only a
2166 * 13-bit displacement and are only to be used
2167 * for local branches: flag as error, don't generate
2170 as_bad("can't use COBR format with external label");
2171 fixP
->fx_addsy
= NULL
; /* No relocations please. */
2174 #endif /* TC_I960 */
2181 } /* switch on symbol seg */
2182 } /* if not in local seg */
2183 } /* if there was a + symbol */
2186 add_number
-= md_pcrel_from(fixP
);
2187 if (add_symbolP
== 0) {
2188 fixP
->fx_addsy
= & abs_symbol
;
2189 } /* if there's an add_symbol */
2192 if (!fixP
->fx_bit_fixP
) {
2194 (add_number
& ~0xFF) && (add_number
&~0xFF!=(-1&~0xFF))) ||
2196 (add_number
& ~0xFFFF) && (add_number
&~0xFFFF!=(-1&~0xFFFF)))) {
2197 as_bad("Value of %d too large for field of %d bytes at 0x%x",
2198 add_number
, size
, fragP
->fr_address
+ where
);
2199 } /* generic error checking */
2200 } /* not a bit fix */
2201 /* once this fix has been applied, we don't have to output anything
2202 nothing more need be done -*/
2203 md_apply_fix(fixP
, add_number
);
2205 } /* For each fixS in this segment. */
2208 } /* fixup_segment() */