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
));
101 static void EXFUN(fixup_mdeps
,(fragS
*));
104 static void EXFUN(fill_section
,(bfd
*abfd
,
105 struct internal_filehdr
*f
, unsigned
109 char *EXFUN(s_get_name
,(symbolS
*s
));
110 static symbolS
*EXFUN(tag_find_or_make
,(char *name
));
111 static symbolS
* EXFUN(tag_find
,(char *name
));
118 unsigned short line_number
,
122 static void EXFUN(w_symbols
,
125 symbolS
*symbol_rootP
));
129 static void EXFUN( obj_coff_def
,(int what
));
130 static void EXFUN( obj_coff_lcomm
,(void));
131 static void EXFUN( obj_coff_dim
,(void));
132 static void EXFUN( obj_coff_text
,(void));
133 static void EXFUN( obj_coff_data
,(void));
134 static void EXFUN( obj_coff_endef
,(void));
135 static void EXFUN( obj_coff_line
,(void));
136 static void EXFUN( obj_coff_ln
,(void));
137 static void EXFUN( obj_coff_scl
,(void));
138 static void EXFUN( obj_coff_size
,(void));
139 static void EXFUN( obj_coff_tag
,(void));
140 static void EXFUN( obj_coff_type
,(void));
141 static void EXFUN( obj_coff_val
,(void));
142 void EXFUN( obj_coff_section
,(void));
143 static void EXFUN( tag_init
,(void));
144 static void EXFUN( tag_insert
,(char *name
, symbolS
*symbolP
));
147 static struct hash_control
*tag_hash
;
148 static symbolS
*def_symbol_in_progress
= NULL
;
150 const pseudo_typeS obj_pseudo_table
[] = {
151 { "def", obj_coff_def
, 0 },
152 { "dim", obj_coff_dim
, 0 },
153 { "endef", obj_coff_endef
, 0 },
154 { "line", obj_coff_line
, 0 },
155 { "ln", obj_coff_ln
, 0 },
156 { "scl", obj_coff_scl
, 0 },
157 { "size", obj_coff_size
, 0 },
158 { "tag", obj_coff_tag
, 0 },
159 { "type", obj_coff_type
, 0 },
160 { "val", obj_coff_val
, 0 },
161 { "section", obj_coff_section
, 0 },
162 { "use", obj_coff_section
, 0 },
163 { "sect", obj_coff_section
, 0 },
164 { "text", obj_coff_text
, 0 },
165 { "data", obj_coff_data
, 0 },
166 /* we don't yet handle this. */
167 { "ident", s_ignore
, 0 },
168 { "ABORT", s_abort
, 0 },
169 { "lcomm", obj_coff_lcomm
, 0},
170 { NULL
} /* end sentinel */
171 }; /* obj_pseudo_table */
177 We allow more than just the standard 3 sections, infact, we allow
178 10 sections, (though the usual three have to be there).
180 This structure performs the mappings for us:
185 static struct internal_scnhdr bss_section_header;
186 struct internal_scnhdr data_section_header;
187 struct internal_scnhdr text_section_header;
189 const segT N_TYPE_seg [32] =
203 seg_info_type seg_info_off_by_4
[N_SEG
] =
229 {SEG_REGISTER
},0,0,0,0};
231 #define SEG_INFO_FROM_SECTION_NUMBER(x) (seg_info_off_by_4[(x)+4])
232 #define SEG_INFO_FROM_SEG_NUMBER(x) (seg_info_off_by_4[(x)])
236 DEFUN(relax_align
,(address
, alignment
),
237 register relax_addressT address AND
238 register long alignment
)
241 relax_addressT new_address
;
243 mask
= ~ ( (~0) << alignment
);
244 new_address
= (address
+ mask
) & (~ mask
);
245 return (new_address
- address
);
246 } /* relax_align() */
250 DEFUN(s_get_segment
,(x
) ,
253 return SEG_INFO_FROM_SECTION_NUMBER(x
->sy_symbol
.ost_entry
.n_scnum
).seg_t
;
258 /* calculate the size of the frag chain and fill in the section header
259 to contain all of it, also fill in the addr of the sections */
261 DEFUN(size_section
,(abfd
, idx
),
266 unsigned int size
= 0;
267 fragS
*frag
= segment_info
[idx
].frchainP
->frch_root
;
269 size
= frag
->fr_address
;
271 if (frag
->fr_address
!= size
) {
272 printf("Out of step\n");
273 size
= frag
->fr_address
;
276 switch (frag
->fr_type
) {
277 #ifdef TC_COFF_SIZEMACHDEP
278 case rs_machine_dependent
:
279 size
+= TC_COFF_SIZEMACHDEP(frag
);
284 size
+= frag
->fr_fix
;
285 size
+= frag
->fr_offset
* frag
->fr_var
;
288 size
+= frag
->fr_fix
;
289 size
+= relax_align(size
, frag
->fr_offset
);
292 frag
= frag
->fr_next
;
294 segment_info
[idx
].scnhdr
.s_size
= size
;
299 static unsigned int DEFUN(count_entries_in_chain
,(idx
),
302 unsigned int nrelocs
;
305 /* Count the relocations */
306 fixup_ptr
= segment_info
[idx
].fix_root
;
308 while (fixup_ptr
!= (fixS
*)NULL
)
310 if (TC_COUNT_RELOC(fixup_ptr
))
315 if (fixup_ptr
->fx_r_type
== RELOC_CONSTH
)
324 fixup_ptr
= fixup_ptr
->fx_next
;
329 /* output all the relocations for a section */
330 void DEFUN(do_relocs_for
,(abfd
, file_cursor
),
332 unsigned long *file_cursor
)
334 unsigned int nrelocs
;
336 unsigned int addr
= 0;
337 for (idx
= SEG_E0
; idx
< SEG_E9
; idx
++)
339 if (segment_info
[idx
].scnhdr
.s_name
[0])
342 struct external_reloc
*ext_ptr
;
343 struct external_reloc
*external_reloc_vec
;
344 unsigned int external_reloc_size
;
345 unsigned int count
= 0;
346 unsigned int base
= addr
;
347 fixS
* fix_ptr
= segment_info
[idx
].fix_root
;
348 nrelocs
= count_entries_in_chain(idx
);
353 external_reloc_size
= nrelocs
* RELSZ
;
355 (struct external_reloc
*)malloc(external_reloc_size
);
359 ext_ptr
= external_reloc_vec
;
361 /* Fill in the internal coff style reloc struct from the
366 struct internal_reloc intr
;
368 /* Only output some of the relocations */
369 if (TC_COUNT_RELOC(fix_ptr
))
371 #ifdef TC_RELOC_MANGLE
372 TC_RELOC_MANGLE(fix_ptr
, &intr
, base
);
376 symbol_ptr
= fix_ptr
->fx_addsy
;
378 intr
.r_type
= TC_COFF_FIX2RTYPE(fix_ptr
);
380 base
+ fix_ptr
->fx_frag
->fr_address
+ fix_ptr
->fx_where
;
382 intr
.r_offset
= fix_ptr
->fx_offset
;
386 /* Turn the segment of the symbol into an offset
390 dot
= segment_info
[S_GET_SEGMENT(symbol_ptr
)].dot
;
393 intr
.r_symndx
= dot
->sy_number
;
397 intr
.r_symndx
= symbol_ptr
->sy_number
;
409 (void)bfd_coff_swap_reloc_out(abfd
, &intr
, ext_ptr
);
413 /* The 29k has a special kludge for the high 16 bit reloc.
414 Two relocations are emmited, R_IHIHALF, and
415 R_IHCONST. The second one doesn't contain a symbol,
416 but uses the value for offset */
418 if (intr
.r_type
== R_IHIHALF
)
420 /* now emit the second bit */
421 intr
.r_type
= R_IHCONST
;
422 intr
.r_symndx
= fix_ptr
->fx_addnumber
;
423 (void)bfd_coff_swap_reloc_out(abfd
,&intr
,ext_ptr
);
429 fix_ptr
= fix_ptr
->fx_next
;
432 /* Write out the reloc table */
433 segment_info
[idx
].scnhdr
.s_relptr
= *file_cursor
;
434 segment_info
[idx
].scnhdr
.s_nreloc
= nrelocs
;
435 bfd_write((PTR
)external_reloc_vec
, 1, external_reloc_size
, abfd
);
436 *file_cursor
+= external_reloc_size
;
437 free( external_reloc_vec
);
439 #ifndef ZERO_BASED_SEGMENTS
440 /* Supposedly setting segment addresses non-zero causes problems
441 for some platforms, although it shouldn't. If you define
442 ZERO_BASED_SEGMENTS, all the segments will be based at 0.
443 Please don't make this the default, since some systems (e.g.,
444 SVR3.2) require the segments to be non-zero based. Ian Taylor
446 addr
+= segment_info
[idx
].scnhdr
.s_size
;
452 /* run through a frag chain and write out the data to go with it, fill
453 in the scnhdrs with the info on the file postions
455 static void DEFUN(fill_section
,(abfd
, filehdr
, file_cursor
),
457 struct internal_filehdr
*filehdr AND
458 unsigned long *file_cursor
)
463 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
465 unsigned int offset
= 0;
467 struct internal_scnhdr
*s
= &( segment_info
[i
].scnhdr
);
471 fragS
*frag
= segment_info
[i
].frchainP
->frch_root
;
472 char *buffer
= malloc(s
->s_size
);
474 s
->s_scnptr
= *file_cursor
;
478 s
->s_flags
= STYP_REG
;
479 if (strcmp(s
->s_name
,".text")==0)
480 s
->s_flags
|= STYP_TEXT
;
481 else if (strcmp(s
->s_name
,".data")==0)
482 s
->s_flags
|= STYP_DATA
;
483 else if (strcmp(s
->s_name
,".bss")==0)
484 s
->s_flags
|= STYP_BSS
| STYP_NOLOAD
;
485 else if (strcmp(s
->s_name
,".lit")==0)
486 s
->s_flags
= STYP_LIT
| STYP_TEXT
;
490 unsigned int fill_size
;
491 switch (frag
->fr_type
) {
492 case rs_machine_dependent
:
495 memcpy(buffer
+ frag
->fr_address
,
498 offset
+= frag
->fr_fix
;
507 memcpy(buffer
+ frag
->fr_address
,
510 offset
+= frag
->fr_fix
;
513 fill_size
= frag
->fr_var
;
517 unsigned int off
= frag
->fr_fix
;
518 for (count
= frag
->fr_offset
; count
; count
--)
520 memcpy(buffer
+ frag
->fr_address
+ off
,
521 frag
->fr_literal
+ frag
->fr_fix
,
535 frag
= frag
->fr_next
;
539 bfd_write(buffer
, s
->s_size
,1,abfd
);
542 *file_cursor
+= s
->s_size
;
551 /* Coff file generation & utilities */
555 DEFUN(coff_header_append
,(abfd
, filehdr
, aouthdr
),
557 struct internal_filehdr
*filehdr AND
558 struct internal_aouthdr
*aouthdr
)
564 bfd_seek(abfd
, 0, 0);
566 filehdr
.f_opthdr
= bfd_coff_swap_aouthdr_out(abfd
, aouthdr
,
569 filehdr
->f_opthdr
= 0;
571 i
= bfd_coff_swap_filehdr_out(abfd
, filehdr
, buffer
);
573 bfd_write(buffer
, i
,1, abfd
);
574 bfd_write(buffero
, filehdr
->f_opthdr
, 1, abfd
);
576 for (i
= SEG_E0
; i
< SEG_E9
; i
++)
578 if (segment_info
[i
].scnhdr
.s_name
[0])
581 bfd_coff_swap_scnhdr_out(abfd
,
582 &(segment_info
[i
].scnhdr
),
584 bfd_write(buffer
, size
, 1, abfd
);
591 DEFUN(symbol_to_chars
,(abfd
, where
, symbolP
),
596 unsigned int numaux
= symbolP
->sy_symbol
.ost_entry
.n_numaux
;
599 /* Turn any symbols with register attributes into abs symbols */
600 if (S_GET_SEGMENT(symbolP
) == SEG_REGISTER
)
602 S_SET_SEGMENT(symbolP
, SEG_ABSOLUTE
);
604 /* At the same time, relocate all symbols to their output value */
607 segment_info
[S_GET_SEGMENT(symbolP
)].scnhdr
.s_paddr
608 + S_GET_VALUE(symbolP
));
610 where
+= bfd_coff_swap_sym_out(abfd
, &symbolP
->sy_symbol
.ost_entry
,
613 for (i
= 0; i
< numaux
; i
++)
615 where
+= bfd_coff_swap_aux_out(abfd
,
616 &symbolP
->sy_symbol
.ost_auxent
[i
],
617 S_GET_DATA_TYPE(symbolP
),
618 S_GET_STORAGE_CLASS(symbolP
),
628 void obj_symbol_new_hook(symbolP
)
631 char underscore
= 0; /* Symbol has leading _ */
633 /* Effective symbol */
634 /* Store the pointer in the offset. */
635 S_SET_ZEROES(symbolP
, 0L);
636 S_SET_DATA_TYPE(symbolP
, T_NULL
);
637 S_SET_STORAGE_CLASS(symbolP
, 0);
638 S_SET_NUMBER_AUXILIARY(symbolP
, 0);
639 /* Additional information */
640 symbolP
->sy_symbol
.ost_flags
= 0;
641 /* Auxiliary entries */
642 bzero((char*)&symbolP
->sy_symbol
.ost_auxent
[0], AUXESZ
);
644 #ifdef STRIP_UNDERSCORE
645 /* Remove leading underscore at the beginning of the symbol.
646 * This is to be compatible with the standard librairies.
648 if (*S_GET_NAME(symbolP
) == '_') {
650 S_SET_NAME(symbolP
, S_GET_NAME(symbolP
) + 1);
651 } /* strip underscore */
652 #endif /* STRIP_UNDERSCORE */
654 if (S_IS_STRING(symbolP
))
655 SF_SET_STRING(symbolP
);
656 if (!underscore
&& S_IS_LOCAL(symbolP
))
657 SF_SET_LOCAL(symbolP
);
660 } /* obj_symbol_new_hook() */
663 stack
* stack_init(chunk_size
, element_size
)
664 unsigned long chunk_size
;
665 unsigned long element_size
;
669 if ((st
= (stack
*)malloc(sizeof(stack
))) == (stack
*)0)
671 if ((st
->data
= malloc(chunk_size
)) == (char*)0) {
676 st
->size
= chunk_size
;
677 st
->chunk_size
= chunk_size
;
678 st
->element_size
= element_size
;
682 void stack_delete(st
)
689 char *stack_push(st
, element
)
693 if (st
->pointer
+ st
->element_size
>= st
->size
) {
694 st
->size
+= st
->chunk_size
;
695 if ((st
->data
= xrealloc(st
->data
, st
->size
)) == (char*)0)
698 memcpy(st
->data
+ st
->pointer
, element
, st
->element_size
);
699 st
->pointer
+= st
->element_size
;
700 return st
->data
+ st
->pointer
;
706 if ((st
->pointer
-= st
->element_size
) < 0) {
711 return st
->data
+ st
->pointer
;
717 return st
->data
+ st
->pointer
- st
->element_size
;
722 * Handle .ln directives.
725 static void obj_coff_ln()
729 if (def_symbol_in_progress
!= NULL
) {
730 as_warn(".ln pseudo-op inside .def/.endef: ignored.");
731 demand_empty_rest_of_line();
733 } /* wrong context */
736 obstack_next_free(&frags
) - frag_now
->fr_literal
,
737 l
= get_absolute_expression(),
745 listing_source_line(l
+ line_base
- 1);
750 demand_empty_rest_of_line();
752 } /* obj_coff_line() */
757 * Handle .def directives.
759 * One might ask : why can't we symbol_new if the symbol does not
760 * already exist and fill it with debug information. Because of
761 * the C_EFCN special symbol. It would clobber the value of the
762 * function symbol before we have a chance to notice that it is
763 * a C_EFCN. And a second reason is that the code is more clear this
764 * way. (at least I think it is :-).
768 #define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';')
769 #define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \
770 *input_line_pointer == '\t') \
771 input_line_pointer++;
774 DEFUN(obj_coff_def
,(what
),
777 char name_end
; /* Char after the end of name */
778 char *symbol_name
; /* Name of the debug symbol */
779 char *symbol_name_copy
; /* Temporary copy of the name */
780 unsigned int symbol_name_length
;
781 /*$char* directiveP;$ */ /* Name of the pseudo opcode */
782 /*$char directive[MAX_DIRECTIVE];$ */ /* Backup of the directive */
783 /*$char end = 0;$ */ /* If 1, stop parsing */
785 if (def_symbol_in_progress
!= NULL
) {
786 as_warn(".def pseudo-op used inside of .def/.endef: ignored.");
787 demand_empty_rest_of_line();
789 } /* if not inside .def/.endef */
793 def_symbol_in_progress
= (symbolS
*) obstack_alloc(¬es
, sizeof(*def_symbol_in_progress
));
794 bzero(def_symbol_in_progress
, sizeof(*def_symbol_in_progress
));
796 symbol_name
= input_line_pointer
;
797 name_end
= get_symbol_end();
798 symbol_name_length
= strlen(symbol_name
);
799 symbol_name_copy
= xmalloc(symbol_name_length
+ 1);
800 strcpy(symbol_name_copy
, symbol_name
);
802 /* Initialize the new symbol */
803 #ifdef STRIP_UNDERSCORE
804 S_SET_NAME(def_symbol_in_progress
, (*symbol_name_copy
== '_'
805 ? symbol_name_copy
+ 1
806 : symbol_name_copy
));
807 #else /* STRIP_UNDERSCORE */
808 S_SET_NAME(def_symbol_in_progress
, symbol_name_copy
);
809 #endif /* STRIP_UNDERSCORE */
810 /* free(symbol_name_copy); */
811 def_symbol_in_progress
->sy_name_offset
= ~0;
812 def_symbol_in_progress
->sy_number
= ~0;
813 def_symbol_in_progress
->sy_frag
= &zero_address_frag
;
815 if (S_IS_STRING(def_symbol_in_progress
)) {
816 SF_SET_STRING(def_symbol_in_progress
);
819 *input_line_pointer
= name_end
;
821 demand_empty_rest_of_line();
823 } /* obj_coff_def() */
825 unsigned int dim_index
;
827 DEFUN_VOID(obj_coff_endef
)
829 symbolS
*symbolP
= 0;
830 /* DIM BUG FIX sac@cygnus.com */
832 if (def_symbol_in_progress
== NULL
) {
833 as_warn(".endef pseudo-op used outside of .def/.endef: ignored.");
834 demand_empty_rest_of_line();
836 } /* if not inside .def/.endef */
838 /* Set the section number according to storage class. */
839 switch (S_GET_STORAGE_CLASS(def_symbol_in_progress
)) {
843 SF_SET_TAG(def_symbol_in_progress
);
844 /* intentional fallthrough */
847 SF_SET_DEBUG(def_symbol_in_progress
);
848 S_SET_SEGMENT(def_symbol_in_progress
, SEG_DEBUG
);
852 SF_SET_LOCAL(def_symbol_in_progress
); /* Do not emit this symbol. */
853 /* intentional fallthrough */
855 SF_SET_PROCESS(def_symbol_in_progress
); /* Will need processing before writing */
856 /* intentional fallthrough */
858 S_SET_SEGMENT(def_symbol_in_progress
, SEG_E0
);
860 if (def_symbol_in_progress
->sy_symbol
.ost_entry
._n
._n_nptr
[1][1] == 'b'
861 && def_symbol_in_progress
->sy_symbol
.ost_entry
._n
._n_nptr
[1][2] == 'f') { /* .bf */
862 if (function_lineoff
< 0) {
863 fprintf(stderr
, "`.bf' symbol without preceding function\n");
864 } /* missing function symbol */
865 SA_GET_SYM_LNNOPTR(last_line_symbol
) = function_lineoff
;
867 SF_SET_PROCESS(last_line_symbol
);
868 function_lineoff
= -1;
874 #endif /* C_AUTOARG */
884 SF_SET_DEBUG(def_symbol_in_progress
);
885 S_SET_SEGMENT(def_symbol_in_progress
, SEG_ABSOLUTE
);
891 /* Valid but set somewhere else (s_comm, s_lcomm, colon) */
897 as_warn("unexpected storage class %d", S_GET_STORAGE_CLASS(def_symbol_in_progress
));
899 } /* switch on storage class */
901 /* Now that we have built a debug symbol, try to
902 find if we should merge with an existing symbol
903 or not. If a symbol is C_EFCN or SEG_ABSOLUTE or
904 untagged SEG_DEBUG it never merges. */
906 /* Two cases for functions. Either debug followed
907 by definition or definition followed by debug.
908 For definition first, we will merge the debug
909 symbol into the definition. For debug first, the
910 lineno entry MUST point to the definition
911 function or else it will point off into space
912 when crawl_symbols() merges the debug
913 symbol into the real symbol. Therefor, let's
914 presume the debug symbol is a real function
917 /* FIXME-SOON If for some reason the definition
918 label/symbol is never seen, this will probably
919 leave an undefined symbol at link time. */
921 if (S_GET_STORAGE_CLASS(def_symbol_in_progress
) == C_EFCN
922 || (S_GET_SEGMENT(def_symbol_in_progress
) == SEG_DEBUG
923 && !SF_GET_TAG(def_symbol_in_progress
))
924 || S_GET_SEGMENT(def_symbol_in_progress
) == SEG_ABSOLUTE
925 || (symbolP
= symbol_find_base(S_GET_NAME(def_symbol_in_progress
), DO_NOT_STRIP
)) == NULL
) {
927 symbol_append(def_symbol_in_progress
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
930 /* This symbol already exists, merge the
931 newly created symbol into the old one.
932 This is not mandatory. The linker can
933 handle duplicate symbols correctly. But I
934 guess that it save a *lot* of space if
935 the assembly file defines a lot of
938 /* The debug entry (def_symbol_in_progress)
939 is merged into the previous definition. */
941 c_symbol_merge(def_symbol_in_progress
, symbolP
);
942 /* FIXME-SOON Should *def_symbol_in_progress be free'd? xoxorich. */
943 def_symbol_in_progress
= symbolP
;
945 if (SF_GET_FUNCTION(def_symbol_in_progress
)
946 || SF_GET_TAG(def_symbol_in_progress
)) {
947 /* For functions, and tags, the symbol *must* be where the debug symbol
948 appears. Move the existing symbol to the current place. */
949 /* If it already is at the end of the symbol list, do nothing */
950 if (def_symbol_in_progress
!= symbol_lastP
) {
951 symbol_remove(def_symbol_in_progress
, &symbol_rootP
, &symbol_lastP
);
952 symbol_append(def_symbol_in_progress
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
953 } /* if not already in place */
955 } /* normal or mergable */
957 if (SF_GET_TAG(def_symbol_in_progress
)
958 && symbol_find_base(S_GET_NAME(def_symbol_in_progress
), DO_NOT_STRIP
) == NULL
) {
959 tag_insert(S_GET_NAME(def_symbol_in_progress
), def_symbol_in_progress
);
960 } /* If symbol is a {structure,union} tag, associate symbol to its name. */
962 if (SF_GET_FUNCTION(def_symbol_in_progress
)) {
963 know(sizeof(def_symbol_in_progress
) <= sizeof(long));
965 = c_line_new(def_symbol_in_progress
,0, 0, &zero_address_frag
);
969 SF_SET_PROCESS(def_symbol_in_progress
);
971 if (symbolP
== NULL
) {
972 /* That is, if this is the first
973 time we've seen the function... */
974 symbol_table_insert(def_symbol_in_progress
);
975 } /* definition follows debug */
976 } /* Create the line number entry pointing to the function being defined */
978 def_symbol_in_progress
= NULL
;
979 demand_empty_rest_of_line();
981 } /* obj_coff_endef() */
984 DEFUN_VOID(obj_coff_dim
)
986 register int dim_index
;
988 if (def_symbol_in_progress
== NULL
)
990 as_warn(".dim pseudo-op used outside of .def/.endef: ignored.");
991 demand_empty_rest_of_line();
993 } /* if not inside .def/.endef */
995 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
997 for (dim_index
= 0; dim_index
< DIMNUM
; dim_index
++)
1000 SA_SET_SYM_DIMEN(def_symbol_in_progress
, dim_index
, get_absolute_expression());
1002 switch (*input_line_pointer
)
1006 input_line_pointer
++;
1010 as_warn("badly formed .dim directive ignored");
1011 /* intentional fallthrough */
1016 } /* switch on following character */
1017 } /* for each dimension */
1019 demand_empty_rest_of_line();
1021 } /* obj_coff_dim() */
1023 static void obj_coff_line()
1027 if (def_symbol_in_progress
== NULL
) {
1030 } /* if it looks like a stabs style line */
1032 this_base
= get_absolute_expression();
1033 if (this_base
> line_base
)
1035 line_base
= this_base
;
1043 listing_source_line(line_base
);
1047 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1048 SA_SET_SYM_LNNO(def_symbol_in_progress
, line_base
);
1050 demand_empty_rest_of_line();
1052 } /* obj_coff_line() */
1054 static void obj_coff_size() {
1055 if (def_symbol_in_progress
== NULL
) {
1056 as_warn(".size pseudo-op used outside of .def/.endef ignored.");
1057 demand_empty_rest_of_line();
1059 } /* if not inside .def/.endef */
1061 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1062 SA_SET_SYM_SIZE(def_symbol_in_progress
, get_absolute_expression());
1063 demand_empty_rest_of_line();
1065 } /* obj_coff_size() */
1067 static void obj_coff_scl() {
1068 if (def_symbol_in_progress
== NULL
) {
1069 as_warn(".scl pseudo-op used outside of .def/.endef ignored.");
1070 demand_empty_rest_of_line();
1072 } /* if not inside .def/.endef */
1074 S_SET_STORAGE_CLASS(def_symbol_in_progress
, get_absolute_expression());
1075 demand_empty_rest_of_line();
1077 } /* obj_coff_scl() */
1079 static void obj_coff_tag() {
1083 if (def_symbol_in_progress
== NULL
) {
1084 as_warn(".tag pseudo-op used outside of .def/.endef ignored.");
1085 demand_empty_rest_of_line();
1087 } /* if not inside .def/.endef */
1089 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1090 symbol_name
= input_line_pointer
;
1091 name_end
= get_symbol_end();
1093 /* Assume that the symbol referred to by .tag is always defined. */
1094 /* This was a bad assumption. I've added find_or_make. xoxorich. */
1095 SA_SET_SYM_TAGNDX(def_symbol_in_progress
, (long) tag_find_or_make(symbol_name
));
1096 if (SA_GET_SYM_TAGNDX(def_symbol_in_progress
) == 0L) {
1097 as_warn("tag not found for .tag %s", symbol_name
);
1100 SF_SET_TAGGED(def_symbol_in_progress
);
1101 *input_line_pointer
= name_end
;
1103 demand_empty_rest_of_line();
1105 } /* obj_coff_tag() */
1107 static void obj_coff_type() {
1108 if (def_symbol_in_progress
== NULL
) {
1109 as_warn(".type pseudo-op used outside of .def/.endef ignored.");
1110 demand_empty_rest_of_line();
1112 } /* if not inside .def/.endef */
1114 S_SET_DATA_TYPE(def_symbol_in_progress
, get_absolute_expression());
1116 if (ISFCN(S_GET_DATA_TYPE(def_symbol_in_progress
)) &&
1117 S_GET_STORAGE_CLASS(def_symbol_in_progress
) != C_TPDEF
) {
1118 SF_SET_FUNCTION(def_symbol_in_progress
);
1119 } /* is a function */
1121 demand_empty_rest_of_line();
1123 } /* obj_coff_type() */
1125 static void obj_coff_val() {
1126 if (def_symbol_in_progress
== NULL
) {
1127 as_warn(".val pseudo-op used outside of .def/.endef ignored.");
1128 demand_empty_rest_of_line();
1130 } /* if not inside .def/.endef */
1132 if (is_name_beginner(*input_line_pointer
)) {
1133 char *symbol_name
= input_line_pointer
;
1134 char name_end
= get_symbol_end();
1136 if (!strcmp(symbol_name
, ".")) {
1137 def_symbol_in_progress
->sy_frag
= frag_now
;
1138 S_SET_VALUE(def_symbol_in_progress
, obstack_next_free(&frags
) - frag_now
->fr_literal
);
1139 /* If the .val is != from the .def (e.g. statics) */
1140 } else if (strcmp(S_GET_NAME(def_symbol_in_progress
), symbol_name
)) {
1141 def_symbol_in_progress
->sy_forward
= symbol_find_or_make(symbol_name
);
1143 /* If the segment is undefined when the forward
1144 reference is solved, then copy the segment id
1145 from the forward symbol. */
1146 SF_SET_GET_SEGMENT(def_symbol_in_progress
);
1148 /* Otherwise, it is the name of a non debug symbol and its value will be calculated later. */
1149 *input_line_pointer
= name_end
;
1151 S_SET_VALUE(def_symbol_in_progress
, get_absolute_expression());
1152 } /* if symbol based */
1154 demand_empty_rest_of_line();
1156 } /* obj_coff_val() */
1159 * Maintain a list of the tagnames of the structres.
1162 static void tag_init() {
1163 tag_hash
= hash_new();
1167 static void tag_insert(name
, symbolP
)
1171 register char * error_string
;
1173 if (*(error_string
= hash_jam(tag_hash
, name
, (char *)symbolP
))) {
1174 as_fatal("Inserting \"%s\" into structure table failed: %s",
1175 name
, error_string
);
1178 } /* tag_insert() */
1180 static symbolS
*tag_find_or_make(name
)
1185 if ((symbolP
= tag_find(name
)) == NULL
) {
1186 symbolP
= symbol_new(name
,
1189 &zero_address_frag
);
1191 tag_insert(S_GET_NAME(symbolP
), symbolP
);
1192 symbol_table_insert(symbolP
);
1196 } /* tag_find_or_make() */
1198 static symbolS
*tag_find(name
)
1201 #ifdef STRIP_UNDERSCORE
1202 if (*name
== '_') name
++;
1203 #endif /* STRIP_UNDERSCORE */
1204 return((symbolS
*)hash_find(tag_hash
, name
));
1207 void obj_read_begin_hook() {
1208 /* These had better be the same. Usually 18 bytes. */
1210 know(sizeof(SYMENT
) == sizeof(AUXENT
));
1211 know(SYMESZ
== AUXESZ
);
1216 } /* obj_read_begin_hook() */
1218 /* This function runs through the symbol table and puts all the
1219 externals onto another chain */
1221 /* The chain of externals */
1222 symbolS
*symbol_externP
= NULL
;
1223 symbolS
*symbol_extern_lastP
= NULL
;
1226 symbolS
*last_functionP
= NULL
;
1230 static unsigned int DEFUN_VOID(yank_symbols
)
1233 unsigned int symbol_number
=0;
1235 for (symbolP
= symbol_rootP
;
1237 symbolP
= symbolP
? symbol_next(symbolP
) : symbol_rootP
) {
1238 if (!SF_GET_DEBUG(symbolP
)) {
1239 /* Debug symbols do not need all this rubbish */
1240 symbolS
* real_symbolP
;
1242 /* L* and C_EFCN symbols never merge. */
1243 if (!SF_GET_LOCAL(symbolP
)
1244 && (real_symbolP
= symbol_find_base(S_GET_NAME(symbolP
), DO_NOT_STRIP
))
1245 && real_symbolP
!= symbolP
) {
1246 /* FIXME-SOON: where do dups come from?
1247 Maybe tag references before definitions? xoxorich. */
1248 /* Move the debug data from the debug symbol to the
1249 real symbol. Do NOT do the oposite (i.e. move from
1250 real symbol to debug symbol and remove real symbol from the
1251 list.) Because some pointers refer to the real symbol
1252 whereas no pointers refer to the debug symbol. */
1253 c_symbol_merge(symbolP
, real_symbolP
);
1254 /* Replace the current symbol by the real one */
1255 /* The symbols will never be the last or the first
1256 because : 1st symbol is .file and 3 last symbols are
1257 .text, .data, .bss */
1258 symbol_remove(real_symbolP
, &symbol_rootP
, &symbol_lastP
);
1259 symbol_insert(real_symbolP
, symbolP
, &symbol_rootP
, &symbol_lastP
);
1260 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1261 symbolP
= real_symbolP
;
1262 } /* if not local but dup'd */
1264 if (flagseen
['R'] && (S_GET_SEGMENT(symbolP
) == SEG_E1
)) {
1265 S_SET_SEGMENT(symbolP
, SEG_E0
);
1266 } /* push data into text */
1268 S_SET_VALUE(symbolP
,
1269 S_GET_VALUE(symbolP
) + symbolP
->sy_frag
->fr_address
);
1271 if (!S_IS_DEFINED(symbolP
) && !SF_GET_LOCAL(symbolP
))
1273 S_SET_EXTERNAL(symbolP
);
1275 else if (S_GET_STORAGE_CLASS(symbolP
) == C_NULL
)
1277 if (S_GET_SEGMENT(symbolP
) == SEG_E0
)
1279 S_SET_STORAGE_CLASS(symbolP
, C_LABEL
);
1283 S_SET_STORAGE_CLASS(symbolP
, C_STAT
);
1287 /* Mainly to speed up if not -g */
1288 if (SF_GET_PROCESS(symbolP
))
1290 /* Handle the nested blocks auxiliary info. */
1291 if (S_GET_STORAGE_CLASS(symbolP
) == C_BLOCK
) {
1292 if (!strcmp(S_GET_NAME(symbolP
), ".bb"))
1293 stack_push(block_stack
, (char *) &symbolP
);
1295 register symbolS
* begin_symbolP
;
1296 begin_symbolP
= *(symbolS
**)stack_pop(block_stack
);
1297 if (begin_symbolP
== (symbolS
*)0)
1298 as_warn("mismatched .eb");
1300 SA_SET_SYM_ENDNDX(begin_symbolP
, symbol_number
+2);
1303 /* If we are able to identify the type of a function, and we
1304 are out of a function (last_functionP == 0) then, the
1305 function symbol will be associated with an auxiliary
1307 if (last_functionP
== (symbolS
*)0 &&
1308 SF_GET_FUNCTION(symbolP
)) {
1309 last_functionP
= symbolP
;
1311 if (S_GET_NUMBER_AUXILIARY(symbolP
) < 1) {
1312 S_SET_NUMBER_AUXILIARY(symbolP
, 1);
1313 } /* make it at least 1 */
1315 /* Clobber possible stale .dim information. */
1317 /* Iffed out by steve - this fries the lnnoptr info too */
1318 bzero(symbolP
->sy_symbol
.ost_auxent
[0].x_sym
.x_fcnary
.x_ary
.x_dimen
,
1319 sizeof(symbolP
->sy_symbol
.ost_auxent
[0].x_sym
.x_fcnary
.x_ary
.x_dimen
));
1322 /* The C_FCN doesn't need any additional information.
1323 I don't even know if this is needed for sdb. But the
1324 standard assembler generates it, so...
1326 if (S_GET_STORAGE_CLASS(symbolP
) == C_EFCN
) {
1327 if (last_functionP
== (symbolS
*)0)
1328 as_fatal("C_EFCN symbol out of scope");
1329 SA_SET_SYM_FSIZE(last_functionP
,
1330 (long)(S_GET_VALUE(symbolP
) -
1331 S_GET_VALUE(last_functionP
)));
1332 SA_SET_SYM_ENDNDX(last_functionP
, symbol_number
);
1333 last_functionP
= (symbolS
*)0;
1336 } else if (SF_GET_TAG(symbolP
)) {
1337 /* First descriptor of a structure must point to
1338 the first slot after the structure description. */
1339 last_tagP
= symbolP
;
1341 } else if (S_GET_STORAGE_CLASS(symbolP
) == C_EOS
) {
1342 /* +2 take in account the current symbol */
1343 SA_SET_SYM_ENDNDX(last_tagP
, symbol_number
+ 2);
1344 } else if (S_GET_STORAGE_CLASS(symbolP
) == C_FILE
) {
1345 if (S_GET_VALUE(symbolP
)) {
1346 S_SET_VALUE((symbolS
*) S_GET_VALUE(symbolP
), symbol_number
);
1347 S_SET_VALUE(symbolP
, 0);
1348 } /* no one points at the first .file symbol */
1349 } /* if debug or tag or eos or file */
1351 /* We must put the external symbols apart. The loader
1352 does not bomb if we do not. But the references in
1353 the endndx field for a .bb symbol are not corrected
1354 if an external symbol is removed between .bb and .be.
1355 I.e in the following case :
1356 [20] .bb endndx = 22
1359 ld will move the symbol 21 to the end of the list but
1360 endndx will still be 22 instead of 21. */
1363 if (SF_GET_LOCAL(symbolP
)) {
1364 /* remove C_EFCN and LOCAL (L...) symbols */
1365 /* next pointer remains valid */
1366 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1369 else if (!S_IS_DEFINED(symbolP
)
1370 && !S_IS_DEBUG(symbolP
)
1371 && !SF_GET_STATICS(symbolP
) &&
1372 S_GET_STORAGE_CLASS(symbolP
) == C_EXT
)
1373 { /* C_EXT && !SF_GET_FUNCTION(symbolP)) */
1374 /* if external, Remove from the list */
1375 symbolS
*hold
= symbol_previous(symbolP
);
1377 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1378 symbol_clear_list_pointers(symbolP
);
1379 symbol_append(symbolP
, symbol_extern_lastP
, &symbol_externP
, &symbol_extern_lastP
);
1382 if (SF_GET_STRING(symbolP
)) {
1383 symbolP
->sy_name_offset
= string_byte_count
;
1384 string_byte_count
+= strlen(S_GET_NAME(symbolP
)) + 1;
1386 symbolP
->sy_name_offset
= 0;
1387 } /* fix "long" names */
1389 symbolP
->sy_number
= symbol_number
;
1390 symbol_number
+= 1 + S_GET_NUMBER_AUXILIARY(symbolP
);
1391 } /* if local symbol */
1392 } /* traverse the symbol list */
1393 return symbol_number
;
1398 static unsigned int DEFUN_VOID(glue_symbols
)
1400 unsigned int symbol_number
= 0;
1402 for (symbolP
= symbol_externP
; symbol_externP
;) {
1403 symbolS
*tmp
= symbol_externP
;
1406 symbol_remove(tmp
, &symbol_externP
, &symbol_extern_lastP
);
1407 symbol_append(tmp
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
1410 if (SF_GET_STRING(tmp
)) {
1411 tmp
->sy_name_offset
= string_byte_count
;
1412 string_byte_count
+= strlen(S_GET_NAME(tmp
)) + 1;
1414 tmp
->sy_name_offset
= 0;
1415 } /* fix "long" names */
1417 tmp
->sy_number
= symbol_number
;
1418 symbol_number
+= 1 + S_GET_NUMBER_AUXILIARY(tmp
);
1419 } /* append the entire extern chain */
1420 return symbol_number
;
1424 static unsigned int DEFUN_VOID(tie_tags
)
1426 unsigned int symbol_number
= 0;
1429 for (symbolP
= symbol_rootP
; symbolP
; symbolP
=
1430 symbol_next(symbolP
))
1432 symbolP
->sy_number
= symbol_number
;
1436 if (SF_GET_TAGGED(symbolP
))
1440 ((symbolS
*) SA_GET_SYM_TAGNDX(symbolP
))->sy_number
);
1443 symbol_number
+= 1 + S_GET_NUMBER_AUXILIARY(symbolP
);
1445 return symbol_number
;
1450 DEFUN(crawl_symbols
,(headers
, abfd
),
1451 struct internal_filehdr
*headers AND
1456 unsigned int ptr
= 0;
1461 /* Initialize the stack used to keep track of the matching .bb .be */
1463 block_stack
= stack_init(512, sizeof(symbolS
*));
1464 /* JF deal with forward references first... */
1465 for (symbolP
= symbol_rootP
;
1467 symbolP
= symbol_next(symbolP
))
1470 if (symbolP
->sy_forward
) {
1471 S_SET_VALUE(symbolP
, (S_GET_VALUE(symbolP
)
1472 + S_GET_VALUE(symbolP
->sy_forward
)
1473 + symbolP
->sy_forward
->sy_frag
->fr_address
));
1475 if (SF_GET_GET_SEGMENT(symbolP
)) {
1476 S_SET_SEGMENT(symbolP
, S_GET_SEGMENT(symbolP
->sy_forward
));
1477 } /* forward segment also */
1479 symbolP
->sy_forward
=0;
1480 } /* if it has a forward reference */
1481 } /* walk the symbol chain */
1484 /* The symbol list should be ordered according to the following sequence
1487 * . debug entries for functions
1488 * . fake symbols for the sections, including.text .data and .bss
1490 * . undefined symbols
1491 * But this is not mandatory. The only important point is to put the
1492 * undefined symbols at the end of the list.
1495 if (symbol_rootP
== NULL
1496 || S_GET_STORAGE_CLASS(symbol_rootP
) != C_FILE
) {
1497 c_dot_file_symbol("fake");
1499 /* Is there a .file symbol ? If not insert one at the beginning. */
1502 * Build up static symbols for the sections, they are filled in later
1506 for (i
= SEG_E0
; i
< SEG_E9
; i
++)
1508 if (segment_info
[i
].scnhdr
.s_name
[0])
1510 segment_info
[i
].dot
=
1511 c_section_symbol(segment_info
[i
].scnhdr
.s_name
,
1518 /* Take all the externals out and put them into another chain */
1519 headers
->f_nsyms
= yank_symbols();
1520 /* Take the externals and glue them onto the end.*/
1521 headers
->f_nsyms
+= glue_symbols();
1523 headers
->f_nsyms
= tie_tags();
1524 know(symbol_externP
== NULL
);
1525 know(symbol_extern_lastP
== NULL
);
1531 * Find strings by crawling along symbol table chain.
1534 void DEFUN(w_strings
,(where
),
1539 /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
1540 md_number_to_chars(where
, string_byte_count
, sizeof(string_byte_count
));
1541 where
+= sizeof(string_byte_count
);
1542 for (symbolP
= symbol_rootP
;
1544 symbolP
= symbol_next(symbolP
))
1548 if (SF_GET_STRING(symbolP
)) {
1549 size
= strlen(S_GET_NAME(symbolP
)) + 1;
1551 memcpy(where
, S_GET_NAME(symbolP
),size
);
1564 DEFUN(do_linenos_for
,(abfd
, file_cursor
),
1566 unsigned long *file_cursor
)
1570 for (idx
= SEG_E0
; idx
< SEG_E9
; idx
++)
1572 segment_info_type
*s
= segment_info
+ idx
;
1575 if (s
->scnhdr
.s_nlnno
!= 0)
1577 struct lineno_list
*line_ptr
;
1579 struct external_lineno
*buffer
=
1580 (struct external_lineno
*)xmalloc(s
->scnhdr
.s_nlnno
* LINESZ
);
1582 struct external_lineno
*dst
= buffer
;
1584 /* Run through the table we've built and turn it into its external
1585 form, take this chance to remove duplicates */
1587 for (line_ptr
= s
->lineno_list_head
;
1588 line_ptr
!= (struct lineno_list
*)NULL
;
1589 line_ptr
= line_ptr
->next
)
1592 if (line_ptr
->line
.l_lnno
== 0)
1594 /* Turn a pointer to a symbol into the symbols' index */
1595 line_ptr
->line
.l_addr
.l_symndx
=
1596 ( (symbolS
*)line_ptr
->line
.l_addr
.l_symndx
)->sy_number
;
1600 line_ptr
->line
.l_addr
.l_paddr
+= ((struct frag
* )(line_ptr
->frag
))->fr_address
;
1604 (void) bfd_coff_swap_lineno_out(abfd
, &(line_ptr
->line
), dst
);
1609 s
->scnhdr
.s_lnnoptr
= *file_cursor
;
1611 bfd_write(buffer
, 1, s
->scnhdr
.s_nlnno
* LINESZ
, abfd
);
1614 *file_cursor
+= s
->scnhdr
.s_nlnno
* LINESZ
;
1620 /* Now we run through the list of frag chains in a segment and
1621 make all the subsegment frags appear at the end of the
1622 list, as if the seg 0 was extra long */
1624 static void DEFUN_VOID(remove_subsegs
)
1628 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1630 frchainS
*head
= segment_info
[i
].frchainP
;
1632 fragS
* prev_frag
= &dummy
;
1634 while (head
&& head
->frch_seg
== i
)
1636 prev_frag
->fr_next
= head
->frch_root
;
1637 prev_frag
= head
->frch_last
;
1638 head
= head
->frch_next
;
1640 prev_frag
->fr_next
= 0;
1646 extern void DEFUN_VOID(write_object_file
)
1649 struct frchain
*frchain_ptr
;
1651 struct internal_filehdr filehdr
;
1652 struct internal_aouthdr aouthdr
;
1653 unsigned long file_cursor
;
1656 abfd
= bfd_openw(out_file_name
, TARGET_FORMAT
);
1660 as_perror ("FATAL: Can't create %s", out_file_name
);
1663 bfd_set_format(abfd
, bfd_object
);
1664 bfd_set_arch_mach(abfd
, BFD_ARCH
, machine
);
1668 string_byte_count
= 4;
1670 for (frchain_ptr
= frchain_root
;
1671 frchain_ptr
!= (struct frchain
*)NULL
;
1672 frchain_ptr
= frchain_ptr
->frch_next
) {
1673 /* Run through all the sub-segments and align them up. Also close any
1674 open frags. We tack a .fill onto the end of the frag chain so
1675 that any .align's size can be worked by looking at the next
1678 subseg_new(frchain_ptr
->frch_seg
, frchain_ptr
->frch_subseg
);
1679 #define SUB_SEGMENT_ALIGN 1
1680 frag_align(SUB_SEGMENT_ALIGN
,0);
1681 frag_wane(frag_now
);
1682 frag_now
->fr_fix
= 0;
1683 know( frag_now
->fr_next
== NULL
);
1690 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1692 relax_segment(segment_info
[i
].frchainP
->frch_root
, i
);
1695 filehdr
.f_nscns
= 0;
1697 /* Find out how big the sections are, and set the addresses. */
1699 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1701 segment_info
[i
].scnhdr
.s_paddr
= addr
;
1702 segment_info
[i
].scnhdr
.s_vaddr
= addr
;
1704 if (segment_info
[i
].scnhdr
.s_name
[0])
1709 #ifndef ZERO_BASED_SEGMENTS
1710 /* See the comment at the previous ZERO_BASED_SEGMENTS check. */
1713 /* This is a special case, we leave the size alone, which
1714 will have been made up from all and any lcomms seen. */
1715 addr
+= segment_info
[i
].scnhdr
.s_size
;
1719 addr
+= size_section(abfd
, i
);
1726 /* Turn the gas native symbol table shape into a coff symbol table */
1727 crawl_symbols(&filehdr
, abfd
);
1728 #if !defined(TC_H8300) && !defined(TC_Z8K)
1729 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1731 fixup_mdeps(segment_info
[i
].frchainP
->frch_root
);
1732 fixup_segment(segment_info
[i
].fix_root
, i
);
1736 file_cursor
= FILHSZ
+ SCNHSZ
* filehdr
.f_nscns
;
1738 bfd_seek(abfd
, file_cursor
, 0);
1741 do_relocs_for(abfd
, &file_cursor
);
1743 do_linenos_for(abfd
, &file_cursor
);
1746 /* Plant the data */
1748 fill_section(abfd
,&filehdr
, &file_cursor
);
1752 filehdr
.f_magic
= COFF_MAGIC
;
1753 filehdr
.f_timdat
= time(0);
1754 filehdr
.f_flags
= COFF_FLAGS
| coff_flags
;
1758 filehdr
.f_flags
|= F_LNNO
;
1762 filehdr
.f_flags
|= F_RELFLG
;
1773 unsigned int symtable_size
= filehdr
.f_nsyms
* SYMESZ
;
1774 char *buffer1
= malloc(symtable_size
+ string_byte_count
+ 4);
1775 char *ptr
= buffer1
;
1776 filehdr
.f_symptr
= bfd_tell(abfd
);
1777 w_symbols(abfd
, buffer1
, symbol_rootP
);
1778 w_strings(buffer1
+ symtable_size
);
1779 bfd_write(buffer1
, 1,symtable_size
+ string_byte_count
+ 4, abfd
);
1783 coff_header_append(abfd
, &filehdr
, &aouthdr
);
1785 if (bfd_close_all_done(abfd
) == false)
1786 as_fatal ("Can't close %s: %s", out_file_name
,
1787 bfd_errmsg (bfd_error
));
1791 static void DEFUN(change_to_section
,(name
, len
, exp
),
1793 unsigned int len AND
1797 /* Find out if we've already got a section of this name etc */
1798 for(i
= SEG_E0
; i
< SEG_E9
&& segment_info
[i
].scnhdr
.s_name
[0] ; i
++)
1800 if (strncmp(segment_info
[i
].scnhdr
.s_name
, name
, len
) == 0)
1807 /* No section, add one */
1808 strncpy(segment_info
[i
].scnhdr
.s_name
, name
, 8);
1813 DEFUN_VOID(obj_coff_section
)
1815 /* Strip out the section name */
1816 char *section_name
;
1817 char *section_name_end
;
1823 section_name
= input_line_pointer
;
1824 c
= get_symbol_end();
1825 section_name_end
= input_line_pointer
;
1827 len
= section_name_end
- section_name
;
1828 input_line_pointer
++;
1832 exp
= get_absolute_expression();
1834 else if ( *input_line_pointer
== ',')
1837 input_line_pointer
++;
1838 exp
= get_absolute_expression();
1845 change_to_section(section_name
, len
,exp
);
1846 *section_name_end
= c
;
1851 static void obj_coff_text()
1853 change_to_section(".text",5, get_absolute_expression());
1857 static void obj_coff_data()
1859 change_to_section(".data",5, get_absolute_expression());
1862 void c_symbol_merge(debug
, normal
)
1866 S_SET_DATA_TYPE(normal
, S_GET_DATA_TYPE(debug
));
1867 S_SET_STORAGE_CLASS(normal
, S_GET_STORAGE_CLASS(debug
));
1869 if (S_GET_NUMBER_AUXILIARY(debug
) > S_GET_NUMBER_AUXILIARY(normal
)) {
1870 S_SET_NUMBER_AUXILIARY(normal
, S_GET_NUMBER_AUXILIARY(debug
));
1871 } /* take the most we have */
1873 if (S_GET_NUMBER_AUXILIARY(debug
) > 0) {
1874 memcpy((char*)&normal
->sy_symbol
.ost_auxent
[0], (char*)&debug
->sy_symbol
.ost_auxent
[0], S_GET_NUMBER_AUXILIARY(debug
) * AUXESZ
);
1875 } /* Move all the auxiliary information */
1877 /* Move the debug flags. */
1878 SF_SET_DEBUG_FIELD(normal
, SF_GET_DEBUG_FIELD(debug
));
1879 } /* c_symbol_merge() */
1882 DEFUN(c_line_new
,(symbol
, paddr
, line_number
, frag
),
1885 unsigned short line_number AND
1888 struct lineno_list
* new_line
=
1889 (struct lineno_list
*)xmalloc(sizeof(struct lineno_list
));
1891 segment_info_type
*s
= segment_info
+ now_seg
;
1892 new_line
->line
.l_lnno
= line_number
;
1896 if (line_number
== 0)
1898 last_line_symbol
= symbol
;
1899 new_line
->line
.l_addr
.l_symndx
= (long)symbol
;
1903 new_line
->line
.l_addr
.l_paddr
= paddr
;
1906 new_line
->frag
= (char*)frag
;
1907 new_line
->next
= (struct lineno_list
*)NULL
;
1910 if (s
->lineno_list_head
== (struct lineno_list
*)NULL
)
1912 s
->lineno_list_head
= new_line
;
1916 s
->lineno_list_tail
->next
= new_line
;
1918 s
->lineno_list_tail
= new_line
;
1919 return LINESZ
* s
->scnhdr
.s_nlnno
++;
1922 void c_dot_file_symbol(filename
)
1927 symbolP
= symbol_new(".file",
1930 &zero_address_frag
);
1932 S_SET_STORAGE_CLASS(symbolP
, C_FILE
);
1933 S_SET_NUMBER_AUXILIARY(symbolP
, 1);
1934 SA_SET_FILE_FNAME(symbolP
, filename
);
1940 listing_source_file(filename
);
1946 SF_SET_DEBUG(symbolP
);
1947 S_SET_VALUE(symbolP
, (long) previous_file_symbol
);
1949 previous_file_symbol
= symbolP
;
1951 /* Make sure that the symbol is first on the symbol chain */
1952 if (symbol_rootP
!= symbolP
) {
1953 if (symbolP
== symbol_lastP
) {
1954 symbol_lastP
= symbol_lastP
->sy_previous
;
1955 } /* if it was the last thing on the list */
1957 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1958 symbol_insert(symbolP
, symbol_rootP
, &symbol_rootP
, &symbol_lastP
);
1959 symbol_rootP
= symbolP
;
1960 } /* if not first on the list */
1962 } /* c_dot_file_symbol() */
1965 * Build a 'section static' symbol.
1968 symbolS
*c_section_symbol(name
,idx
)
1974 symbolP
= symbol_new(name
,idx
,
1976 &zero_address_frag
);
1978 S_SET_STORAGE_CLASS(symbolP
, C_STAT
);
1979 S_SET_NUMBER_AUXILIARY(symbolP
, 1);
1981 SF_SET_STATICS(symbolP
);
1984 } /* c_section_symbol() */
1987 DEFUN(w_symbols
,(abfd
, where
, symbol_rootP
),
1990 symbolS
*symbol_rootP
)
1995 /* First fill in those values we have only just worked out */
1996 for (i
= SEG_E0
; i
< SEG_E9
; i
++)
1998 symbolP
= segment_info
[i
].dot
;
2002 SA_SET_SCN_SCNLEN(symbolP
, segment_info
[i
].scnhdr
.s_size
);
2003 SA_SET_SCN_NRELOC(symbolP
, segment_info
[i
].scnhdr
.s_nreloc
);
2004 SA_SET_SCN_NLINNO(symbolP
, segment_info
[i
].scnhdr
.s_nlnno
);
2010 * Emit all symbols left in the symbol chain.
2012 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next(symbolP
)) {
2013 /* Used to save the offset of the name. It is used to point
2014 to the string in memory but must be a file offset. */
2015 register char * temp
;
2017 tc_coff_symbol_emit_hook(symbolP
);
2019 temp
= S_GET_NAME(symbolP
);
2020 if (SF_GET_STRING(symbolP
)) {
2021 S_SET_OFFSET(symbolP
, symbolP
->sy_name_offset
);
2022 S_SET_ZEROES(symbolP
, 0);
2024 bzero(symbolP
->sy_symbol
.ost_entry
.n_name
, SYMNMLEN
);
2025 strncpy(symbolP
->sy_symbol
.ost_entry
.n_name
, temp
, SYMNMLEN
);
2027 where
= symbol_to_chars(abfd
, where
, symbolP
);
2028 S_SET_NAME(symbolP
,temp
);
2033 static void DEFUN_VOID(obj_coff_lcomm
)
2042 name
= input_line_pointer
;
2045 c
= get_symbol_end();
2046 p
= input_line_pointer
;
2049 if (*input_line_pointer
!= ',') {
2050 as_bad("Expected comma after name");
2051 ignore_rest_of_line();
2054 if (*input_line_pointer
== '\n') {
2055 as_bad("Missing size expression");
2058 input_line_pointer
++;
2059 if ((temp
= get_absolute_expression ()) < 0) {
2060 as_warn("lcomm length (%d.) <0! Ignored.", temp
);
2061 ignore_rest_of_line();
2067 /* Allocate zero static local data in the .data section now
2068 instead of the bss section as a symbol with a value */
2070 segT oldseg
= now_seg
;
2071 int oldsubseg
= now_subseg
;
2073 subseg_new(SEG_DATA
, 10);
2076 record_alignment(SEG_DATA
, 4);
2077 x
= frag_var (rs_fill
, 1, 1, (relax_substateT
)0, (symbolS
*)0,
2081 subseg_new(oldseg
, oldsubseg
);
2083 demand_empty_rest_of_line();
2086 static void DEFUN(fixup_mdeps
,(frags
),
2091 switch (frags
->fr_type
)
2095 frags
->fr_type
= rs_fill
;
2097 (frags
->fr_next
->fr_address
- frags
->fr_address
- frags
->fr_fix
);
2099 case rs_machine_dependent
:
2100 md_convert_frag(0, frags
);
2105 frags
= frags
->fr_next
;
2110 static void DEFUN(fixup_segment
,(fixP
, this_segment_type
),
2111 register fixS
* fixP AND
2112 segT this_segment_type
)
2114 register symbolS
*add_symbolP
;
2115 register symbolS
*sub_symbolP
;
2116 register long add_number
;
2118 register char *place
;
2119 register long where
;
2120 register char pcrel
;
2121 register fragS
*fragP
;
2122 register segT add_symbol_segment
= SEG_ABSOLUTE
;
2125 for ( ; fixP
; fixP
= fixP
->fx_next
)
2127 fragP
= fixP
->fx_frag
;
2129 where
= fixP
->fx_where
;
2130 place
= fragP
->fr_literal
+ where
;
2131 size
= fixP
->fx_size
;
2132 add_symbolP
= fixP
->fx_addsy
;
2134 if (fixP
->fx_callj
&& TC_S_IS_CALLNAME(add_symbolP
)) {
2135 /* Relocation should be done via the
2136 associated 'bal' entry point
2139 if (!TC_S_IS_BALNAME(tc_get_bal_of_call(add_symbolP
))) {
2140 as_bad("No 'bal' entry point for leafproc %s",
2141 S_GET_NAME(add_symbolP
));
2144 fixP
->fx_addsy
= add_symbolP
= tc_get_bal_of_call(add_symbolP
);
2145 } /* callj relocation */
2147 sub_symbolP
= fixP
->fx_subsy
;
2148 add_number
= fixP
->fx_offset
;
2149 pcrel
= fixP
->fx_pcrel
;
2152 add_symbol_segment
= S_GET_SEGMENT(add_symbolP
);
2153 } /* if there is an addend */
2158 if (S_GET_SEGMENT(sub_symbolP
) != SEG_ABSOLUTE
) {
2159 as_bad("Negative of non-absolute symbol %s", S_GET_NAME(sub_symbolP
));
2160 } /* not absolute */
2162 add_number
-= S_GET_VALUE(sub_symbolP
);
2165 /* if sub_symbol is in the same segment that add_symbol
2166 and add_symbol is either in DATA, TEXT, BSS or ABSOLUTE */
2167 } else if ((S_GET_SEGMENT(sub_symbolP
) == add_symbol_segment
)
2168 && (SEG_NORMAL(add_symbol_segment
)
2169 || (add_symbol_segment
== SEG_ABSOLUTE
))) {
2170 /* Difference of 2 symbols from same segment. */
2171 /* Can't make difference of 2 undefineds: 'value' means */
2172 /* something different for N_UNDF. */
2174 /* Makes no sense to use the difference of 2 arbitrary symbols
2175 * as the target of a call instruction.
2177 if (fixP
->fx_callj
) {
2178 as_bad("callj to difference of 2 symbols");
2180 #endif /* TC_I960 */
2181 add_number
+= S_GET_VALUE(add_symbolP
) -
2182 S_GET_VALUE(sub_symbolP
);
2185 fixP
->fx_addsy
= NULL
;
2187 /* Different segments in subtraction. */
2188 know(!(S_IS_EXTERNAL(sub_symbolP
) && (S_GET_SEGMENT(sub_symbolP
) == SEG_ABSOLUTE
)));
2190 if ((S_GET_SEGMENT(sub_symbolP
) == SEG_ABSOLUTE
)) {
2191 add_number
-= S_GET_VALUE(sub_symbolP
);
2193 as_bad("Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %d.",
2194 segment_name(S_GET_SEGMENT(sub_symbolP
)),
2195 S_GET_NAME(sub_symbolP
), fragP
->fr_address
+ where
);
2198 } /* if sub_symbolP */
2201 if (add_symbol_segment
== this_segment_type
&& pcrel
) {
2203 * This fixup was made when the symbol's segment was
2204 * SEG_UNKNOWN, but it is now in the local segment.
2205 * So we know how to do the address without relocation.
2208 /* reloc_callj() may replace a 'call' with a 'calls' or a 'bal',
2209 * in which cases it modifies *fixP as appropriate. In the case
2210 * of a 'calls', no further work is required, and *fixP has been
2211 * set up to make the rest of the code below a no-op.
2214 #endif /* TC_I960 */
2216 add_number
+= S_GET_VALUE(add_symbolP
);
2217 add_number
-= md_pcrel_from (fixP
);
2218 pcrel
= 0; /* Lie. Don't want further pcrel processing. */
2219 fixP
->fx_addsy
= NULL
; /* No relocations please. */
2222 switch (add_symbol_segment
)
2226 reloc_callj(fixP
); /* See comment about reloc_callj() above*/
2227 #endif /* TC_I960 */
2228 add_number
+= S_GET_VALUE(add_symbolP
);
2229 fixP
->fx_addsy
= NULL
;
2234 add_number
+= S_GET_VALUE(add_symbolP
) +
2235 segment_info
[S_GET_SEGMENT(add_symbolP
)].scnhdr
.s_paddr
;
2240 if ((int)fixP
->fx_bit_fixP
== 13) {
2241 /* This is a COBR instruction. They have only a
2242 * 13-bit displacement and are only to be used
2243 * for local branches: flag as error, don't generate
2246 as_bad("can't use COBR format with external label");
2247 fixP
->fx_addsy
= NULL
; /* No relocations please. */
2250 #endif /* TC_I960 */
2252 /* 386 COFF uses a peculiar format in
2253 which the value of a common symbol is
2254 stored in the .text segment (I've
2255 checked this on SVR3.2 and SCO 3.2.2)
2256 Ian Taylor <ian@cygnus.com>. */
2257 add_number
+= S_GET_VALUE(add_symbolP
);
2262 } /* switch on symbol seg */
2263 } /* if not in local seg */
2264 } /* if there was a + symbol */
2267 add_number
-= md_pcrel_from(fixP
);
2268 if (add_symbolP
== 0) {
2269 fixP
->fx_addsy
= & abs_symbol
;
2270 } /* if there's an add_symbol */
2273 if (!fixP
->fx_bit_fixP
) {
2275 (add_number
& ~0xFF) && ((add_number
&~0xFF)!=(-1&~0xFF))) ||
2277 (add_number
& ~0xFFFF) && ((add_number
&~0xFFFF)!=(-1&~0xFFFF)))) {
2278 as_bad("Value of %d too large for field of %d bytes at 0x%x",
2279 add_number
, size
, fragP
->fr_address
+ where
);
2280 } /* generic error checking */
2281 #ifdef WARN_SIGNED_OVERFLOW_WORD
2282 /* Warn if a .word value is too large when treated as
2283 a signed number. We already know it is not too
2284 negative. This is to catch over-large switches
2285 generated by gcc on the 68k. */
2288 && add_number
> 0x7fff)
2289 as_bad ("Signed .word overflow; switch may be too large; %d at 0x%x",
2290 add_number
, fragP
->fr_address
+ where
);
2292 } /* not a bit fix */
2293 /* once this fix has been applied, we don't have to output anything
2294 nothing more need be done -*/
2295 md_apply_fix(fixP
, add_number
);
2297 } /* For each fixS in this segment. */
2300 } /* fixup_segment() */