1 /* coff object file format with bfd
2 Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc.
4 This file is part of GAS.
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
22 How does this releate to the rest of GAS ?
24 Well, all the other files in gas are more or less a black box. It
25 takes care of opening files, parsing command lines, stripping blanks
26 etc etc. This module gets a chance to register what it wants to do by
27 saying that it is interested in various pseduo ops. The other big
28 change is write_object_file. This runs through all the data
29 structures that gas builds, and outputs the file in the format of our
32 Hacked for BFDness by steve chamberlain
34 This object module now supports the Hitachi H8/300 and the AMD 29k
43 #include "../bfd/libbfd.h"
46 #define MIN(a,b) ((a) < (b)? (a) : (b))
47 /* This vector is used to turn an internal segment into a section #
48 suitable for insertion into a coff symbol table
51 const short seg_N_TYPE
[] = { /* in: segT out: N_TYPE bits */
63 C_UNDEF_SECTION
, /* SEG_UNKNOWN */
64 C_UNDEF_SECTION
, /* SEG_ABSENT */
65 C_UNDEF_SECTION
, /* SEG_PASS1 */
66 C_UNDEF_SECTION
, /* SEG_GOOF */
67 C_UNDEF_SECTION
, /* SEG_BIG */
68 C_UNDEF_SECTION
, /* SEG_DIFFERENCE */
69 C_DEBUG_SECTION
, /* SEG_DEBUG */
70 C_NTV_SECTION
, /* SEG_NTV */
71 C_PTV_SECTION
, /* SEG_PTV */
72 C_REGISTER_SECTION
, /* SEG_REGISTER */
76 int function_lineoff
= -1; /* Offset in line#s where the last function
77 started (the odd entry for line #0) */
83 static symbolS
*last_line_symbol
;
84 /* Add 4 to the real value to get the index and compensate the
85 negatives. This vector is used by S_GET_SEGMENT to turn a coff
86 section number into a segment number
88 static symbolS
*previous_file_symbol
= NULL
;
89 void c_symbol_merge();
92 symbolS
*c_section_symbol();
94 void EXFUN(bfd_as_write_hook
,(struct internal_filehdr
*,
97 static void EXFUN(fixup_segment
,(fixS
* fixP
,
98 segT this_segment_type
));
100 static void EXFUN(fill_section
,(bfd
*abfd
,
101 struct internal_filehdr
*f
, unsigned
105 char *EXFUN(s_get_name
,(symbolS
*s
));
106 static symbolS
*EXFUN(tag_find_or_make
,(char *name
));
107 static symbolS
* EXFUN(tag_find
,(char *name
));
114 unsigned short line_number
,
118 static void EXFUN(w_symbols
,
121 symbolS
*symbol_rootP
));
125 static void EXFUN( obj_coff_def
,(int what
));
126 static void EXFUN( obj_coff_lcomm
,(void));
127 static void EXFUN( obj_coff_dim
,(void));
128 static void EXFUN( obj_coff_text
,(void));
129 static void EXFUN( obj_coff_data
,(void));
130 static void EXFUN( obj_coff_endef
,(void));
131 static void EXFUN( obj_coff_line
,(void));
132 static void EXFUN( obj_coff_ln
,(void));
133 static void EXFUN( obj_coff_scl
,(void));
134 static void EXFUN( obj_coff_size
,(void));
135 static void EXFUN( obj_coff_tag
,(void));
136 static void EXFUN( obj_coff_type
,(void));
137 static void EXFUN( obj_coff_val
,(void));
138 static void EXFUN( obj_coff_section
,(void));
139 static void EXFUN( tag_init
,(void));
140 static void EXFUN( tag_insert
,(char *name
, symbolS
*symbolP
));
143 static struct hash_control
*tag_hash
;
144 static symbolS
*def_symbol_in_progress
= NULL
;
146 const pseudo_typeS obj_pseudo_table
[] = {
147 { "def", obj_coff_def
, 0 },
148 { "dim", obj_coff_dim
, 0 },
149 { "endef", obj_coff_endef
, 0 },
150 { "line", obj_coff_line
, 0 },
151 { "ln", obj_coff_ln
, 0 },
152 { "scl", obj_coff_scl
, 0 },
153 { "size", obj_coff_size
, 0 },
154 { "tag", obj_coff_tag
, 0 },
155 { "type", obj_coff_type
, 0 },
156 { "val", obj_coff_val
, 0 },
157 { "section", obj_coff_section
, 0 },
158 { "sect", obj_coff_section
, 0 },
159 { "text", obj_coff_text
, 0 },
160 { "data", obj_coff_data
, 0 },
161 /* we don't yet handle this. */
162 { "ident", s_ignore
, 0 },
163 { "ABORT", s_abort
, 0 },
164 { "lcomm", obj_coff_lcomm
, 0},
165 { NULL
} /* end sentinel */
166 }; /* obj_pseudo_table */
172 We allow more than just the standard 3 sections, infact, we allow
173 10 sections, (though the usual three have to be there).
175 This structure performs the mappings for us:
180 static struct internal_scnhdr bss_section_header;
181 struct internal_scnhdr data_section_header;
182 struct internal_scnhdr text_section_header;
184 const segT N_TYPE_seg [32] =
198 seg_info_type seg_info_off_by_4
[N_SEG
] =
224 {SEG_REGISTER
},0,0,0,0};
226 #define SEG_INFO_FROM_SECTION_NUMBER(x) (seg_info_off_by_4[(x)+4])
227 #define SEG_INFO_FROM_SEG_NUMBER(x) (seg_info_off_by_4[(x)])
231 DEFUN(relax_align
,(address
, alignment
),
232 register relax_addressT address AND
233 register long alignment
)
236 relax_addressT new_address
;
238 mask
= ~ ( (~0) << alignment
);
239 new_address
= (address
+ mask
) & (~ mask
);
240 return (new_address
- address
);
241 } /* relax_align() */
245 DEFUN(s_get_segment
,(x
) ,
248 return SEG_INFO_FROM_SECTION_NUMBER(x
->sy_symbol
.ost_entry
.n_scnum
).seg_t
;
253 /* calculate the size of the frag chain and fill in the section header
254 to contain all of it, also fill in the addr of the sections */
255 static unsigned int DEFUN(size_section
,(abfd
, idx
),
260 unsigned int size
= 0;
261 fragS
*frag
= segment_info
[idx
].frchainP
->frch_root
;
263 if (frag
->fr_address
!= size
) {
264 printf("Out of step\n");
265 size
= frag
->fr_address
;
267 size
+= frag
->fr_fix
;
268 switch (frag
->fr_type
) {
271 size
+= frag
->fr_offset
* frag
->fr_var
;
274 size
+= relax_align(size
, frag
->fr_offset
);
276 frag
= frag
->fr_next
;
278 segment_info
[idx
].scnhdr
.s_size
= size
;
283 static unsigned int DEFUN(count_entries_in_chain
,(idx
),
286 unsigned int nrelocs
;
289 /* Count the relocations */
290 fixup_ptr
= segment_info
[idx
].fix_root
;
292 while (fixup_ptr
!= (fixS
*)NULL
)
294 if (TC_COUNT_RELOC(fixup_ptr
))
299 if (fixup_ptr
->fx_r_type
== RELOC_CONSTH
)
308 fixup_ptr
= fixup_ptr
->fx_next
;
313 /* output all the relocations for a section */
314 void DEFUN(do_relocs_for
,(abfd
, file_cursor
),
316 unsigned long *file_cursor
)
318 unsigned int nrelocs
;
321 for (idx
= SEG_E0
; idx
< SEG_E9
; idx
++)
323 if (segment_info
[idx
].scnhdr
.s_name
[0])
326 struct external_reloc
*ext_ptr
;
327 struct external_reloc
*external_reloc_vec
;
328 unsigned int external_reloc_size
;
329 unsigned int count
= 0;
330 unsigned int base
= segment_info
[idx
].scnhdr
.s_paddr
;
331 fixS
* fix_ptr
= segment_info
[idx
].fix_root
;
332 nrelocs
= count_entries_in_chain(idx
);
337 external_reloc_size
= nrelocs
* RELSZ
;
339 (struct external_reloc
*)malloc(external_reloc_size
);
343 ext_ptr
= external_reloc_vec
;
345 /* Fill in the internal coff style reloc struct from the
350 struct internal_reloc intr
;
352 /* Only output some of the relocations */
353 if (TC_COUNT_RELOC(fix_ptr
))
355 #ifdef TC_RELOC_MANGLE
356 TC_RELOC_MANGLE(fix_ptr
, &intr
, base
);
360 symbol_ptr
= fix_ptr
->fx_addsy
;
362 intr
.r_type
= TC_COFF_FIX2RTYPE(fix_ptr
);
364 base
+ fix_ptr
->fx_frag
->fr_address
+ fix_ptr
->fx_where
;
366 intr
.r_offset
= fix_ptr
->fx_offset
;
370 /* Turn the segment of the symbol into an offset
374 dot
= segment_info
[S_GET_SEGMENT(symbol_ptr
)].dot
;
377 intr
.r_symndx
= dot
->sy_number
;
381 intr
.r_symndx
= symbol_ptr
->sy_number
;
393 (void)bfd_coff_swap_reloc_out(abfd
, &intr
, ext_ptr
);
397 /* The 29k has a special kludge for the high 16 bit reloc.
398 Two relocations are emmited, R_IHIHALF, and
399 R_IHCONST. The second one doesn't contain a symbol,
400 but uses the value for offset */
402 if (intr
.r_type
== R_IHIHALF
)
404 /* now emit the second bit */
405 intr
.r_type
= R_IHCONST
;
406 intr
.r_symndx
= fix_ptr
->fx_addnumber
;
407 (void)bfd_coff_swap_reloc_out(abfd
,&intr
,ext_ptr
);
413 fix_ptr
= fix_ptr
->fx_next
;
416 /* Write out the reloc table */
417 segment_info
[idx
].scnhdr
.s_relptr
= *file_cursor
;
418 segment_info
[idx
].scnhdr
.s_nreloc
= nrelocs
;
419 bfd_write((PTR
)external_reloc_vec
, 1, external_reloc_size
, abfd
);
420 *file_cursor
+= external_reloc_size
;
421 free( external_reloc_vec
);
427 /* run through a frag chain and write out the data to go with it, fill
428 in the scnhdrs with the info on the file postions
430 static void DEFUN(fill_section
,(abfd
, filehdr
, file_cursor
),
432 struct internal_filehdr
*filehdr AND
433 unsigned long *file_cursor
)
437 unsigned int paddr
= 0;
439 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
441 unsigned int offset
= 0;
443 struct internal_scnhdr
*s
= &( segment_info
[i
].scnhdr
);
447 fragS
*frag
= segment_info
[i
].frchainP
->frch_root
;
448 char *buffer
= malloc(s
->s_size
);
451 s
->s_scnptr
= *file_cursor
;
465 s
->s_flags
= STYP_REG
;
466 if (strcmp(s
->s_name
,".text")==0)
467 s
->s_flags
|= STYP_TEXT
;
468 else if (strcmp(s
->s_name
,".data")==0)
469 s
->s_flags
|= STYP_DATA
;
470 else if (strcmp(s
->s_name
,".bss")==0)
471 s
->s_flags
|= STYP_BSS
| STYP_NOLOAD
;
474 unsigned int fill_size
;
475 switch (frag
->fr_type
) {
482 memcpy(buffer
+ frag
->fr_address
,
485 offset
+= frag
->fr_fix
;
488 fill_size
= frag
->fr_var
;
492 unsigned int off
= frag
->fr_fix
;
493 for (count
= frag
->fr_offset
; count
; count
--)
495 memcpy(buffer
+ frag
->fr_address
+ off
,
496 frag
->fr_literal
+ frag
->fr_fix
,
508 frag
= frag
->fr_next
;
512 bfd_write(buffer
, s
->s_size
,1,abfd
);
515 *file_cursor
+= s
->s_size
;
524 /* Coff file generation & utilities */
528 DEFUN(coff_header_append
,(abfd
, filehdr
, aouthdr
),
530 struct internal_filehdr
*filehdr AND
531 struct internal_aouthdr
*aouthdr
)
537 bfd_seek(abfd
, 0, 0);
539 filehdr
.f_opthdr
= bfd_coff_swap_aouthdr_out(abfd
, aouthdr
,
542 filehdr
->f_opthdr
= 0;
544 i
= bfd_coff_swap_filehdr_out(abfd
, filehdr
, buffer
);
546 bfd_write(buffer
, i
,1, abfd
);
547 bfd_write(buffero
, filehdr
->f_opthdr
, 1, abfd
);
549 for (i
= SEG_E0
; i
< SEG_E9
; i
++)
551 if (segment_info
[i
].scnhdr
.s_name
[0])
554 bfd_coff_swap_scnhdr_out(abfd
,
555 &(segment_info
[i
].scnhdr
),
557 bfd_write(buffer
, size
, 1, abfd
);
564 DEFUN(symbol_to_chars
,(abfd
, where
, symbolP
),
569 unsigned int numaux
= symbolP
->sy_symbol
.ost_entry
.n_numaux
;
572 /* Turn any symbols with register attributes into abs symbols */
573 if (S_GET_SEGMENT(symbolP
) == SEG_REGISTER
)
575 S_SET_SEGMENT(symbolP
, SEG_ABSOLUTE
);
577 /* At the same time, relocate all symbols to their output value */
580 segment_info
[S_GET_SEGMENT(symbolP
)].scnhdr
.s_paddr
581 + S_GET_VALUE(symbolP
));
583 where
+= bfd_coff_swap_sym_out(abfd
, &symbolP
->sy_symbol
.ost_entry
,
586 for (i
= 0; i
< numaux
; i
++)
588 where
+= bfd_coff_swap_aux_out(abfd
,
589 &symbolP
->sy_symbol
.ost_auxent
[i
],
590 S_GET_DATA_TYPE(symbolP
),
591 S_GET_STORAGE_CLASS(symbolP
),
601 void obj_symbol_new_hook(symbolP
)
604 char underscore
= 0; /* Symbol has leading _ */
606 /* Effective symbol */
607 /* Store the pointer in the offset. */
608 S_SET_ZEROES(symbolP
, 0L);
609 S_SET_DATA_TYPE(symbolP
, T_NULL
);
610 S_SET_STORAGE_CLASS(symbolP
, 0);
611 S_SET_NUMBER_AUXILIARY(symbolP
, 0);
612 /* Additional information */
613 symbolP
->sy_symbol
.ost_flags
= 0;
614 /* Auxiliary entries */
615 bzero((char*)&symbolP
->sy_symbol
.ost_auxent
[0], AUXESZ
);
617 #ifdef STRIP_UNDERSCORE
618 /* Remove leading underscore at the beginning of the symbol.
619 * This is to be compatible with the standard librairies.
621 if (*S_GET_NAME(symbolP
) == '_') {
623 S_SET_NAME(symbolP
, S_GET_NAME(symbolP
) + 1);
624 } /* strip underscore */
625 #endif /* STRIP_UNDERSCORE */
627 if (S_IS_STRING(symbolP
))
628 SF_SET_STRING(symbolP
);
629 if (!underscore
&& S_IS_LOCAL(symbolP
))
630 SF_SET_LOCAL(symbolP
);
633 } /* obj_symbol_new_hook() */
636 stack
* stack_init(chunk_size
, element_size
)
637 unsigned long chunk_size
;
638 unsigned long element_size
;
642 if ((st
= (stack
*)malloc(sizeof(stack
))) == (stack
*)0)
644 if ((st
->data
= malloc(chunk_size
)) == (char*)0) {
649 st
->size
= chunk_size
;
650 st
->chunk_size
= chunk_size
;
651 st
->element_size
= element_size
;
655 void stack_delete(st
)
662 char *stack_push(st
, element
)
666 if (st
->pointer
+ st
->element_size
>= st
->size
) {
667 st
->size
+= st
->chunk_size
;
668 if ((st
->data
= xrealloc(st
->data
, st
->size
)) == (char*)0)
671 memcpy(st
->data
+ st
->pointer
, element
, st
->element_size
);
672 st
->pointer
+= st
->element_size
;
673 return st
->data
+ st
->pointer
;
679 if ((st
->pointer
-= st
->element_size
) < 0) {
684 return st
->data
+ st
->pointer
;
690 return st
->data
+ st
->pointer
- st
->element_size
;
695 * Handle .ln directives.
698 static void obj_coff_ln()
702 if (def_symbol_in_progress
!= NULL
) {
703 as_warn(".ln pseudo-op inside .def/.endef: ignored.");
704 demand_empty_rest_of_line();
706 } /* wrong context */
709 obstack_next_free(&frags
) - frag_now
->fr_literal
,
710 l
= get_absolute_expression(),
718 listing_source_line(l
+ line_base
- 1);
723 demand_empty_rest_of_line();
725 } /* obj_coff_line() */
730 * Handle .def directives.
732 * One might ask : why can't we symbol_new if the symbol does not
733 * already exist and fill it with debug information. Because of
734 * the C_EFCN special symbol. It would clobber the value of the
735 * function symbol before we have a chance to notice that it is
736 * a C_EFCN. And a second reason is that the code is more clear this
737 * way. (at least I think it is :-).
741 #define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';')
742 #define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \
743 *input_line_pointer == '\t') \
744 input_line_pointer++;
747 DEFUN(obj_coff_def
,(what
),
750 char name_end
; /* Char after the end of name */
751 char *symbol_name
; /* Name of the debug symbol */
752 char *symbol_name_copy
; /* Temporary copy of the name */
753 unsigned int symbol_name_length
;
754 /*$char* directiveP;$ */ /* Name of the pseudo opcode */
755 /*$char directive[MAX_DIRECTIVE];$ */ /* Backup of the directive */
756 /*$char end = 0;$ */ /* If 1, stop parsing */
758 if (def_symbol_in_progress
!= NULL
) {
759 as_warn(".def pseudo-op used inside of .def/.endef: ignored.");
760 demand_empty_rest_of_line();
762 } /* if not inside .def/.endef */
766 def_symbol_in_progress
= (symbolS
*) obstack_alloc(¬es
, sizeof(*def_symbol_in_progress
));
767 bzero(def_symbol_in_progress
, sizeof(*def_symbol_in_progress
));
769 symbol_name
= input_line_pointer
;
770 name_end
= get_symbol_end();
771 symbol_name_length
= strlen(symbol_name
);
772 symbol_name_copy
= xmalloc(symbol_name_length
+ 1);
773 strcpy(symbol_name_copy
, symbol_name
);
775 /* Initialize the new symbol */
776 #ifdef STRIP_UNDERSCORE
777 S_SET_NAME(def_symbol_in_progress
, (*symbol_name_copy
== '_'
778 ? symbol_name_copy
+ 1
779 : symbol_name_copy
));
780 #else /* STRIP_UNDERSCORE */
781 S_SET_NAME(def_symbol_in_progress
, symbol_name_copy
);
782 #endif /* STRIP_UNDERSCORE */
783 /* free(symbol_name_copy); */
784 def_symbol_in_progress
->sy_name_offset
= ~0;
785 def_symbol_in_progress
->sy_number
= ~0;
786 def_symbol_in_progress
->sy_frag
= &zero_address_frag
;
788 if (S_IS_STRING(def_symbol_in_progress
)) {
789 SF_SET_STRING(def_symbol_in_progress
);
792 *input_line_pointer
= name_end
;
794 demand_empty_rest_of_line();
796 } /* obj_coff_def() */
798 unsigned int dim_index
;
800 DEFUN_VOID(obj_coff_endef
)
802 symbolS
*symbolP
= 0;
803 /* DIM BUG FIX sac@cygnus.com */
805 if (def_symbol_in_progress
== NULL
) {
806 as_warn(".endef pseudo-op used outside of .def/.endef: ignored.");
807 demand_empty_rest_of_line();
809 } /* if not inside .def/.endef */
811 /* Set the section number according to storage class. */
812 switch (S_GET_STORAGE_CLASS(def_symbol_in_progress
)) {
816 SF_SET_TAG(def_symbol_in_progress
);
817 /* intentional fallthrough */
820 SF_SET_DEBUG(def_symbol_in_progress
);
821 S_SET_SEGMENT(def_symbol_in_progress
, SEG_DEBUG
);
825 SF_SET_LOCAL(def_symbol_in_progress
); /* Do not emit this symbol. */
826 /* intentional fallthrough */
828 SF_SET_PROCESS(def_symbol_in_progress
); /* Will need processing before writing */
829 /* intentional fallthrough */
831 S_SET_SEGMENT(def_symbol_in_progress
, SEG_E0
);
833 if (def_symbol_in_progress
->sy_symbol
.ost_entry
._n
._n_nptr
[1][1] == 'b'
834 && def_symbol_in_progress
->sy_symbol
.ost_entry
._n
._n_nptr
[1][2] == 'f') { /* .bf */
835 if (function_lineoff
< 0) {
836 fprintf(stderr
, "`.bf' symbol without preceding function\n");
837 } /* missing function symbol */
838 SA_GET_SYM_LNNOPTR(last_line_symbol
) = function_lineoff
;
840 SF_SET_PROCESS(last_line_symbol
);
841 function_lineoff
= -1;
847 #endif /* C_AUTOARG */
857 SF_SET_DEBUG(def_symbol_in_progress
);
858 S_SET_SEGMENT(def_symbol_in_progress
, SEG_ABSOLUTE
);
864 /* Valid but set somewhere else (s_comm, s_lcomm, colon) */
870 as_warn("unexpected storage class %d", S_GET_STORAGE_CLASS(def_symbol_in_progress
));
872 } /* switch on storage class */
874 /* Now that we have built a debug symbol, try to
875 find if we should merge with an existing symbol
876 or not. If a symbol is C_EFCN or SEG_ABSOLUTE or
877 untagged SEG_DEBUG it never merges. */
879 /* Two cases for functions. Either debug followed
880 by definition or definition followed by debug.
881 For definition first, we will merge the debug
882 symbol into the definition. For debug first, the
883 lineno entry MUST point to the definition
884 function or else it will point off into space
885 when crawl_symbols() merges the debug
886 symbol into the real symbol. Therefor, let's
887 presume the debug symbol is a real function
890 /* FIXME-SOON If for some reason the definition
891 label/symbol is never seen, this will probably
892 leave an undefined symbol at link time. */
894 if (S_GET_STORAGE_CLASS(def_symbol_in_progress
) == C_EFCN
895 || (S_GET_SEGMENT(def_symbol_in_progress
) == SEG_DEBUG
896 && !SF_GET_TAG(def_symbol_in_progress
))
897 || S_GET_SEGMENT(def_symbol_in_progress
) == SEG_ABSOLUTE
898 || (symbolP
= symbol_find_base(S_GET_NAME(def_symbol_in_progress
), DO_NOT_STRIP
)) == NULL
) {
900 symbol_append(def_symbol_in_progress
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
903 /* This symbol already exists, merge the
904 newly created symbol into the old one.
905 This is not mandatory. The linker can
906 handle duplicate symbols correctly. But I
907 guess that it save a *lot* of space if
908 the assembly file defines a lot of
911 /* The debug entry (def_symbol_in_progress)
912 is merged into the previous definition. */
914 c_symbol_merge(def_symbol_in_progress
, symbolP
);
915 /* FIXME-SOON Should *def_symbol_in_progress be free'd? xoxorich. */
916 def_symbol_in_progress
= symbolP
;
918 if (SF_GET_FUNCTION(def_symbol_in_progress
)
919 || SF_GET_TAG(def_symbol_in_progress
)) {
920 /* For functions, and tags, the symbol *must* be where the debug symbol
921 appears. Move the existing symbol to the current place. */
922 /* If it already is at the end of the symbol list, do nothing */
923 if (def_symbol_in_progress
!= symbol_lastP
) {
924 symbol_remove(def_symbol_in_progress
, &symbol_rootP
, &symbol_lastP
);
925 symbol_append(def_symbol_in_progress
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
926 } /* if not already in place */
928 } /* normal or mergable */
930 if (SF_GET_TAG(def_symbol_in_progress
)
931 && symbol_find_base(S_GET_NAME(def_symbol_in_progress
), DO_NOT_STRIP
) == NULL
) {
932 tag_insert(S_GET_NAME(def_symbol_in_progress
), def_symbol_in_progress
);
933 } /* If symbol is a {structure,union} tag, associate symbol to its name. */
935 if (SF_GET_FUNCTION(def_symbol_in_progress
)) {
936 know(sizeof(def_symbol_in_progress
) <= sizeof(long));
938 = c_line_new(def_symbol_in_progress
,0, 0, &zero_address_frag
);
942 SF_SET_PROCESS(def_symbol_in_progress
);
944 if (symbolP
== NULL
) {
945 /* That is, if this is the first
946 time we've seen the function... */
947 symbol_table_insert(def_symbol_in_progress
);
948 } /* definition follows debug */
949 } /* Create the line number entry pointing to the function being defined */
951 def_symbol_in_progress
= NULL
;
952 demand_empty_rest_of_line();
954 } /* obj_coff_endef() */
957 DEFUN_VOID(obj_coff_dim
)
959 register int dim_index
;
961 if (def_symbol_in_progress
== NULL
)
963 as_warn(".dim pseudo-op used outside of .def/.endef: ignored.");
964 demand_empty_rest_of_line();
966 } /* if not inside .def/.endef */
968 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
970 for (dim_index
= 0; dim_index
< DIMNUM
; dim_index
++)
973 SA_SET_SYM_DIMEN(def_symbol_in_progress
, dim_index
, get_absolute_expression());
975 switch (*input_line_pointer
)
979 input_line_pointer
++;
983 as_warn("badly formed .dim directive ignored");
984 /* intentional fallthrough */
989 } /* switch on following character */
990 } /* for each dimension */
992 demand_empty_rest_of_line();
994 } /* obj_coff_dim() */
996 static void obj_coff_line()
1000 if (def_symbol_in_progress
== NULL
) {
1003 } /* if it looks like a stabs style line */
1005 this_base
= get_absolute_expression();
1006 if (this_base
> line_base
)
1008 line_base
= this_base
;
1016 listing_source_line(line_base
);
1020 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1021 SA_SET_SYM_LNNO(def_symbol_in_progress
, line_base
);
1023 demand_empty_rest_of_line();
1025 } /* obj_coff_line() */
1027 static void obj_coff_size() {
1028 if (def_symbol_in_progress
== NULL
) {
1029 as_warn(".size pseudo-op used outside of .def/.endef ignored.");
1030 demand_empty_rest_of_line();
1032 } /* if not inside .def/.endef */
1034 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1035 SA_SET_SYM_SIZE(def_symbol_in_progress
, get_absolute_expression());
1036 demand_empty_rest_of_line();
1038 } /* obj_coff_size() */
1040 static void obj_coff_scl() {
1041 if (def_symbol_in_progress
== NULL
) {
1042 as_warn(".scl pseudo-op used outside of .def/.endef ignored.");
1043 demand_empty_rest_of_line();
1045 } /* if not inside .def/.endef */
1047 S_SET_STORAGE_CLASS(def_symbol_in_progress
, get_absolute_expression());
1048 demand_empty_rest_of_line();
1050 } /* obj_coff_scl() */
1052 static void obj_coff_tag() {
1056 if (def_symbol_in_progress
== NULL
) {
1057 as_warn(".tag pseudo-op used outside of .def/.endef ignored.");
1058 demand_empty_rest_of_line();
1060 } /* if not inside .def/.endef */
1062 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1063 symbol_name
= input_line_pointer
;
1064 name_end
= get_symbol_end();
1066 /* Assume that the symbol referred to by .tag is always defined. */
1067 /* This was a bad assumption. I've added find_or_make. xoxorich. */
1068 SA_SET_SYM_TAGNDX(def_symbol_in_progress
, (long) tag_find_or_make(symbol_name
));
1069 if (SA_GET_SYM_TAGNDX(def_symbol_in_progress
) == 0L) {
1070 as_warn("tag not found for .tag %s", symbol_name
);
1073 SF_SET_TAGGED(def_symbol_in_progress
);
1074 *input_line_pointer
= name_end
;
1076 demand_empty_rest_of_line();
1078 } /* obj_coff_tag() */
1080 static void obj_coff_type() {
1081 if (def_symbol_in_progress
== NULL
) {
1082 as_warn(".type pseudo-op used outside of .def/.endef ignored.");
1083 demand_empty_rest_of_line();
1085 } /* if not inside .def/.endef */
1087 S_SET_DATA_TYPE(def_symbol_in_progress
, get_absolute_expression());
1089 if (ISFCN(S_GET_DATA_TYPE(def_symbol_in_progress
)) &&
1090 S_GET_STORAGE_CLASS(def_symbol_in_progress
) != C_TPDEF
) {
1091 SF_SET_FUNCTION(def_symbol_in_progress
);
1092 } /* is a function */
1094 demand_empty_rest_of_line();
1096 } /* obj_coff_type() */
1098 static void obj_coff_val() {
1099 if (def_symbol_in_progress
== NULL
) {
1100 as_warn(".val pseudo-op used outside of .def/.endef ignored.");
1101 demand_empty_rest_of_line();
1103 } /* if not inside .def/.endef */
1105 if (is_name_beginner(*input_line_pointer
)) {
1106 char *symbol_name
= input_line_pointer
;
1107 char name_end
= get_symbol_end();
1109 if (!strcmp(symbol_name
, ".")) {
1110 def_symbol_in_progress
->sy_frag
= frag_now
;
1111 S_SET_VALUE(def_symbol_in_progress
, obstack_next_free(&frags
) - frag_now
->fr_literal
);
1112 /* If the .val is != from the .def (e.g. statics) */
1113 } else if (strcmp(S_GET_NAME(def_symbol_in_progress
), symbol_name
)) {
1114 def_symbol_in_progress
->sy_forward
= symbol_find_or_make(symbol_name
);
1116 /* If the segment is undefined when the forward
1117 reference is solved, then copy the segment id
1118 from the forward symbol. */
1119 SF_SET_GET_SEGMENT(def_symbol_in_progress
);
1121 /* Otherwise, it is the name of a non debug symbol and its value will be calculated later. */
1122 *input_line_pointer
= name_end
;
1124 S_SET_VALUE(def_symbol_in_progress
, get_absolute_expression());
1125 } /* if symbol based */
1127 demand_empty_rest_of_line();
1129 } /* obj_coff_val() */
1132 * Maintain a list of the tagnames of the structres.
1135 static void tag_init() {
1136 tag_hash
= hash_new();
1140 static void tag_insert(name
, symbolP
)
1144 register char * error_string
;
1146 if (*(error_string
= hash_jam(tag_hash
, name
, (char *)symbolP
))) {
1147 as_fatal("Inserting \"%s\" into structure table failed: %s",
1148 name
, error_string
);
1151 } /* tag_insert() */
1153 static symbolS
*tag_find_or_make(name
)
1158 if ((symbolP
= tag_find(name
)) == NULL
) {
1159 symbolP
= symbol_new(name
,
1162 &zero_address_frag
);
1164 tag_insert(S_GET_NAME(symbolP
), symbolP
);
1165 symbol_table_insert(symbolP
);
1169 } /* tag_find_or_make() */
1171 static symbolS
*tag_find(name
)
1174 #ifdef STRIP_UNDERSCORE
1175 if (*name
== '_') name
++;
1176 #endif /* STRIP_UNDERSCORE */
1177 return((symbolS
*)hash_find(tag_hash
, name
));
1180 void obj_read_begin_hook() {
1181 /* These had better be the same. Usually 18 bytes. */
1183 know(sizeof(SYMENT
) == sizeof(AUXENT
));
1184 know(SYMESZ
== AUXESZ
);
1189 } /* obj_read_begin_hook() */
1191 /* This function runs through the symbol table and puts all the
1192 externals onto another chain */
1194 /* The chain of externals */
1195 symbolS
*symbol_externP
= NULL
;
1196 symbolS
*symbol_extern_lastP
= NULL
;
1199 symbolS
*last_functionP
= NULL
;
1203 static unsigned int DEFUN_VOID(yank_symbols
)
1206 unsigned int symbol_number
=0;
1208 for (symbolP
= symbol_rootP
;
1210 symbolP
= symbolP
? symbol_next(symbolP
) : symbol_rootP
) {
1211 if (!SF_GET_DEBUG(symbolP
)) {
1212 /* Debug symbols do not need all this rubbish */
1213 symbolS
* real_symbolP
;
1215 /* L* and C_EFCN symbols never merge. */
1216 if (!SF_GET_LOCAL(symbolP
)
1217 && (real_symbolP
= symbol_find_base(S_GET_NAME(symbolP
), DO_NOT_STRIP
))
1218 && real_symbolP
!= symbolP
) {
1219 /* FIXME-SOON: where do dups come from?
1220 Maybe tag references before definitions? xoxorich. */
1221 /* Move the debug data from the debug symbol to the
1222 real symbol. Do NOT do the oposite (i.e. move from
1223 real symbol to debug symbol and remove real symbol from the
1224 list.) Because some pointers refer to the real symbol
1225 whereas no pointers refer to the debug symbol. */
1226 c_symbol_merge(symbolP
, real_symbolP
);
1227 /* Replace the current symbol by the real one */
1228 /* The symbols will never be the last or the first
1229 because : 1st symbol is .file and 3 last symbols are
1230 .text, .data, .bss */
1231 symbol_remove(real_symbolP
, &symbol_rootP
, &symbol_lastP
);
1232 symbol_insert(real_symbolP
, symbolP
, &symbol_rootP
, &symbol_lastP
);
1233 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1234 symbolP
= real_symbolP
;
1235 } /* if not local but dup'd */
1237 if (flagseen
['R'] && (S_GET_SEGMENT(symbolP
) == SEG_E1
)) {
1238 S_SET_SEGMENT(symbolP
, SEG_E0
);
1239 } /* push data into text */
1241 S_SET_VALUE(symbolP
,
1242 S_GET_VALUE(symbolP
) + symbolP
->sy_frag
->fr_address
);
1244 if (!S_IS_DEFINED(symbolP
) && !SF_GET_LOCAL(symbolP
))
1246 S_SET_EXTERNAL(symbolP
);
1248 else if (S_GET_STORAGE_CLASS(symbolP
) == C_NULL
)
1250 if (S_GET_SEGMENT(symbolP
) == SEG_E0
)
1252 S_SET_STORAGE_CLASS(symbolP
, C_LABEL
);
1256 S_SET_STORAGE_CLASS(symbolP
, C_STAT
);
1260 /* Mainly to speed up if not -g */
1261 if (SF_GET_PROCESS(symbolP
))
1263 /* Handle the nested blocks auxiliary info. */
1264 if (S_GET_STORAGE_CLASS(symbolP
) == C_BLOCK
) {
1265 if (!strcmp(S_GET_NAME(symbolP
), ".bb"))
1266 stack_push(block_stack
, (char *) &symbolP
);
1268 register symbolS
* begin_symbolP
;
1269 begin_symbolP
= *(symbolS
**)stack_pop(block_stack
);
1270 if (begin_symbolP
== (symbolS
*)0)
1271 as_warn("mismatched .eb");
1273 SA_SET_SYM_ENDNDX(begin_symbolP
, symbol_number
+2);
1276 /* If we are able to identify the type of a function, and we
1277 are out of a function (last_functionP == 0) then, the
1278 function symbol will be associated with an auxiliary
1280 if (last_functionP
== (symbolS
*)0 &&
1281 SF_GET_FUNCTION(symbolP
)) {
1282 last_functionP
= symbolP
;
1284 if (S_GET_NUMBER_AUXILIARY(symbolP
) < 1) {
1285 S_SET_NUMBER_AUXILIARY(symbolP
, 1);
1286 } /* make it at least 1 */
1288 /* Clobber possible stale .dim information. */
1290 /* Iffed out by steve - this fries the lnnoptr info too */
1291 bzero(symbolP
->sy_symbol
.ost_auxent
[0].x_sym
.x_fcnary
.x_ary
.x_dimen
,
1292 sizeof(symbolP
->sy_symbol
.ost_auxent
[0].x_sym
.x_fcnary
.x_ary
.x_dimen
));
1295 /* The C_FCN doesn't need any additional information.
1296 I don't even know if this is needed for sdb. But the
1297 standard assembler generates it, so...
1299 if (S_GET_STORAGE_CLASS(symbolP
) == C_EFCN
) {
1300 if (last_functionP
== (symbolS
*)0)
1301 as_fatal("C_EFCN symbol out of scope");
1302 SA_SET_SYM_FSIZE(last_functionP
,
1303 (long)(S_GET_VALUE(symbolP
) -
1304 S_GET_VALUE(last_functionP
)));
1305 SA_SET_SYM_ENDNDX(last_functionP
, symbol_number
);
1306 last_functionP
= (symbolS
*)0;
1309 } else if (SF_GET_TAG(symbolP
)) {
1310 /* First descriptor of a structure must point to
1311 the first slot after the structure description. */
1312 last_tagP
= symbolP
;
1314 } else if (S_GET_STORAGE_CLASS(symbolP
) == C_EOS
) {
1315 /* +2 take in account the current symbol */
1316 SA_SET_SYM_ENDNDX(last_tagP
, symbol_number
+ 2);
1317 } else if (S_GET_STORAGE_CLASS(symbolP
) == C_FILE
) {
1318 if (S_GET_VALUE(symbolP
)) {
1319 S_SET_VALUE((symbolS
*) S_GET_VALUE(symbolP
), symbol_number
);
1320 S_SET_VALUE(symbolP
, 0);
1321 } /* no one points at the first .file symbol */
1322 } /* if debug or tag or eos or file */
1324 /* We must put the external symbols apart. The loader
1325 does not bomb if we do not. But the references in
1326 the endndx field for a .bb symbol are not corrected
1327 if an external symbol is removed between .bb and .be.
1328 I.e in the following case :
1329 [20] .bb endndx = 22
1332 ld will move the symbol 21 to the end of the list but
1333 endndx will still be 22 instead of 21. */
1336 if (SF_GET_LOCAL(symbolP
)) {
1337 /* remove C_EFCN and LOCAL (L...) symbols */
1338 /* next pointer remains valid */
1339 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1342 else if (!S_IS_DEFINED(symbolP
)
1343 && !S_IS_DEBUG(symbolP
)
1344 && !SF_GET_STATICS(symbolP
) &&
1345 S_GET_STORAGE_CLASS(symbolP
) == C_EXT
)
1346 { /* C_EXT && !SF_GET_FUNCTION(symbolP)) */
1347 /* if external, Remove from the list */
1348 symbolS
*hold
= symbol_previous(symbolP
);
1350 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1351 symbol_clear_list_pointers(symbolP
);
1352 symbol_append(symbolP
, symbol_extern_lastP
, &symbol_externP
, &symbol_extern_lastP
);
1355 if (SF_GET_STRING(symbolP
)) {
1356 symbolP
->sy_name_offset
= string_byte_count
;
1357 string_byte_count
+= strlen(S_GET_NAME(symbolP
)) + 1;
1359 symbolP
->sy_name_offset
= 0;
1360 } /* fix "long" names */
1362 symbolP
->sy_number
= symbol_number
;
1363 symbol_number
+= 1 + S_GET_NUMBER_AUXILIARY(symbolP
);
1364 } /* if local symbol */
1365 } /* traverse the symbol list */
1366 return symbol_number
;
1371 static unsigned int DEFUN_VOID(glue_symbols
)
1373 unsigned int symbol_number
= 0;
1375 for (symbolP
= symbol_externP
; symbol_externP
;) {
1376 symbolS
*tmp
= symbol_externP
;
1379 symbol_remove(tmp
, &symbol_externP
, &symbol_extern_lastP
);
1380 symbol_append(tmp
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
1383 if (SF_GET_STRING(tmp
)) {
1384 tmp
->sy_name_offset
= string_byte_count
;
1385 string_byte_count
+= strlen(S_GET_NAME(tmp
)) + 1;
1387 tmp
->sy_name_offset
= 0;
1388 } /* fix "long" names */
1390 tmp
->sy_number
= symbol_number
;
1391 symbol_number
+= 1 + S_GET_NUMBER_AUXILIARY(tmp
);
1392 } /* append the entire extern chain */
1393 return symbol_number
;
1397 static unsigned int DEFUN_VOID(tie_tags
)
1399 unsigned int symbol_number
= 0;
1402 for (symbolP
= symbol_rootP
; symbolP
; symbolP
=
1403 symbol_next(symbolP
))
1405 symbolP
->sy_number
= symbol_number
;
1409 if (SF_GET_TAGGED(symbolP
))
1413 ((symbolS
*) SA_GET_SYM_TAGNDX(symbolP
))->sy_number
);
1416 symbol_number
+= 1 + S_GET_NUMBER_AUXILIARY(symbolP
);
1418 return symbol_number
;
1423 DEFUN(crawl_symbols
,(headers
, abfd
),
1424 struct internal_filehdr
*headers AND
1429 unsigned int ptr
= 0;
1434 /* Initialize the stack used to keep track of the matching .bb .be */
1436 block_stack
= stack_init(512, sizeof(symbolS
*));
1437 /* JF deal with forward references first... */
1438 for (symbolP
= symbol_rootP
;
1440 symbolP
= symbol_next(symbolP
))
1443 if (symbolP
->sy_forward
) {
1444 S_SET_VALUE(symbolP
, (S_GET_VALUE(symbolP
)
1445 + S_GET_VALUE(symbolP
->sy_forward
)
1446 + symbolP
->sy_forward
->sy_frag
->fr_address
));
1448 if (SF_GET_GET_SEGMENT(symbolP
)) {
1449 S_SET_SEGMENT(symbolP
, S_GET_SEGMENT(symbolP
->sy_forward
));
1450 } /* forward segment also */
1452 symbolP
->sy_forward
=0;
1453 } /* if it has a forward reference */
1454 } /* walk the symbol chain */
1457 /* The symbol list should be ordered according to the following sequence
1460 * . debug entries for functions
1461 * . fake symbols for the sections, including.text .data and .bss
1463 * . undefined symbols
1464 * But this is not mandatory. The only important point is to put the
1465 * undefined symbols at the end of the list.
1468 if (symbol_rootP
== NULL
1469 || S_GET_STORAGE_CLASS(symbol_rootP
) != C_FILE
) {
1470 c_dot_file_symbol("fake");
1472 /* Is there a .file symbol ? If not insert one at the beginning. */
1475 * Build up static symbols for the sections, they are filled in later
1479 for (i
= SEG_E0
; i
< SEG_E9
; i
++)
1481 if (segment_info
[i
].scnhdr
.s_name
[0])
1483 segment_info
[i
].dot
=
1484 c_section_symbol(segment_info
[i
].scnhdr
.s_name
,
1491 /* Take all the externals out and put them into another chain */
1492 headers
->f_nsyms
= yank_symbols();
1493 /* Take the externals and glue them onto the end.*/
1494 headers
->f_nsyms
+= glue_symbols();
1496 headers
->f_nsyms
= tie_tags();
1497 know(symbol_externP
== NULL
);
1498 know(symbol_extern_lastP
== NULL
);
1504 * Find strings by crawling along symbol table chain.
1507 void DEFUN(w_strings
,(where
),
1512 /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
1513 md_number_to_chars(where
, string_byte_count
, sizeof(string_byte_count
));
1514 where
+= sizeof(string_byte_count
);
1515 for (symbolP
= symbol_rootP
;
1517 symbolP
= symbol_next(symbolP
))
1521 if (SF_GET_STRING(symbolP
)) {
1522 size
= strlen(S_GET_NAME(symbolP
)) + 1;
1524 memcpy(where
, S_GET_NAME(symbolP
),size
);
1537 DEFUN(do_linenos_for
,(abfd
, file_cursor
),
1539 unsigned long *file_cursor
)
1543 for (idx
= SEG_E0
; idx
< SEG_E9
; idx
++)
1545 segment_info_type
*s
= segment_info
+ idx
;
1548 if (s
->scnhdr
.s_nlnno
!= 0)
1550 struct lineno_list
*line_ptr
;
1552 struct external_lineno
*buffer
=
1553 (struct external_lineno
*)xmalloc(s
->scnhdr
.s_nlnno
* LINESZ
);
1555 struct external_lineno
*dst
= buffer
;
1557 /* Run through the table we've built and turn it into its external
1558 form, take this chance to remove duplicates */
1560 for (line_ptr
= s
->lineno_list_head
;
1561 line_ptr
!= (struct lineno_list
*)NULL
;
1562 line_ptr
= line_ptr
->next
)
1565 if (line_ptr
->line
.l_lnno
== 0)
1567 /* Turn a pointer to a symbol into the symbols' index */
1568 line_ptr
->line
.l_addr
.l_symndx
=
1569 ( (symbolS
*)line_ptr
->line
.l_addr
.l_symndx
)->sy_number
;
1573 line_ptr
->line
.l_addr
.l_paddr
+= ((struct frag
* )(line_ptr
->frag
))->fr_address
;
1577 (void) bfd_coff_swap_lineno_out(abfd
, &(line_ptr
->line
), dst
);
1582 s
->scnhdr
.s_lnnoptr
= *file_cursor
;
1584 bfd_write(buffer
, 1, s
->scnhdr
.s_nlnno
* LINESZ
, abfd
);
1587 *file_cursor
+= s
->scnhdr
.s_nlnno
* LINESZ
;
1593 /* Now we run through the list of frag chains in a segment and
1594 make all the subsegment frags appear at the end of the
1595 list, as if the seg 0 was extra long */
1597 static void DEFUN_VOID(remove_subsegs
)
1601 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1603 frchainS
*head
= segment_info
[i
].frchainP
;
1605 fragS
* prev_frag
= &dummy
;
1607 while (head
&& head
->frch_seg
== i
)
1609 prev_frag
->fr_next
= head
->frch_root
;
1610 prev_frag
= head
->frch_last
;
1611 head
= head
->frch_next
;
1613 prev_frag
->fr_next
= 0;
1618 extern void DEFUN_VOID(write_object_file
)
1621 struct frchain
*frchain_ptr
;
1623 struct internal_filehdr filehdr
;
1624 struct internal_aouthdr aouthdr
;
1625 unsigned long file_cursor
;
1627 unsigned int addr
= 0;
1628 abfd
= bfd_openw(out_file_name
, TARGET_FORMAT
);
1632 as_perror ("FATAL: Can't create %s", out_file_name
);
1635 bfd_set_format(abfd
, bfd_object
);
1636 bfd_set_arch_mach(abfd
, BFD_ARCH
, 0);
1640 string_byte_count
= 4;
1642 for (frchain_ptr
= frchain_root
;
1643 frchain_ptr
!= (struct frchain
*)NULL
;
1644 frchain_ptr
= frchain_ptr
->frch_next
) {
1645 /* Run through all the sub-segments and align them up. Also close any
1646 open frags. We tack a .fill onto the end of the frag chain so
1647 that any .align's size can be worked by looking at the next
1650 subseg_new(frchain_ptr
->frch_seg
, frchain_ptr
->frch_subseg
);
1651 #define SUB_SEGMENT_ALIGN 1
1652 frag_align(SUB_SEGMENT_ALIGN
,0);
1653 frag_wane(frag_now
);
1654 frag_now
->fr_fix
= 0;
1655 know( frag_now
->fr_next
== NULL
);
1662 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1664 relax_segment(segment_info
[i
].frchainP
->frch_root
, i
);
1671 filehdr
.f_nscns
= 0;
1673 /* Find out how big the sections are */
1674 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1677 if (segment_info
[i
].scnhdr
.s_name
[0])
1684 /* THis is a special case, we leave the size alone, which will have */
1685 /* been made up from all and any lcomms seen */
1688 addr
+= size_section(abfd
, i
);
1694 /* Turn the gas native symbol table shape into a coff symbol table */
1695 crawl_symbols(&filehdr
, abfd
);
1697 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1699 fixup_segment(segment_info
[i
].fix_root
, i
);
1703 file_cursor
= FILHSZ
+ SCNHSZ
* filehdr
.f_nscns
;
1705 bfd_seek(abfd
, file_cursor
, 0);
1708 do_relocs_for(abfd
, &file_cursor
);
1710 do_linenos_for(abfd
, &file_cursor
);
1713 /* Plant the data */
1715 fill_section(abfd
,&filehdr
, &file_cursor
);
1717 filehdr
.f_magic
= COFF_MAGIC
;
1718 filehdr
.f_timdat
= time(0);
1719 filehdr
.f_flags
= COFF_FLAGS
;
1723 filehdr
.f_flags
|= F_LNNO
;
1727 filehdr
.f_flags
|= F_RELFLG
;
1738 unsigned int symtable_size
= filehdr
.f_nsyms
* SYMESZ
;
1739 char *buffer1
= malloc(symtable_size
+ string_byte_count
+ 4);
1740 char *ptr
= buffer1
;
1741 filehdr
.f_symptr
= bfd_tell(abfd
);
1742 w_symbols(abfd
, buffer1
, symbol_rootP
);
1743 w_strings(buffer1
+ symtable_size
);
1744 bfd_write(buffer1
, 1,symtable_size
+ string_byte_count
+ 4, abfd
);
1748 coff_header_append(abfd
, &filehdr
, &aouthdr
);
1750 bfd_close_all_done(abfd
);
1754 static void DEFUN(change_to_section
,(name
, len
, exp
),
1756 unsigned int len AND
1760 /* Find out if we've already got a section of this name etc */
1761 for(i
= SEG_E0
; i
< SEG_E9
&& segment_info
[i
].scnhdr
.s_name
[0] ; i
++)
1763 if (strncmp(segment_info
[i
].scnhdr
.s_name
, name
, len
) == 0)
1770 /* No section, add one */
1771 strncpy(segment_info
[i
].scnhdr
.s_name
, name
, 8);
1776 DEFUN_VOID(obj_coff_section
)
1778 /* Strip out the section name */
1779 char *section_name
;
1780 char *section_name_end
;
1786 section_name
= input_line_pointer
;
1787 c
= get_symbol_end();
1788 section_name_end
= input_line_pointer
;
1790 len
= section_name_end
- section_name
;
1791 input_line_pointer
++;
1795 exp
= get_absolute_expression();
1797 else if ( *input_line_pointer
== ',')
1800 input_line_pointer
++;
1801 exp
= get_absolute_expression();
1808 change_to_section(section_name
, len
,exp
);
1809 *section_name_end
= c
;
1814 static void obj_coff_text()
1816 change_to_section(".text",5, get_absolute_expression());
1820 static void obj_coff_data()
1822 change_to_section(".data",5, get_absolute_expression());
1825 void c_symbol_merge(debug
, normal
)
1829 S_SET_DATA_TYPE(normal
, S_GET_DATA_TYPE(debug
));
1830 S_SET_STORAGE_CLASS(normal
, S_GET_STORAGE_CLASS(debug
));
1832 if (S_GET_NUMBER_AUXILIARY(debug
) > S_GET_NUMBER_AUXILIARY(normal
)) {
1833 S_SET_NUMBER_AUXILIARY(normal
, S_GET_NUMBER_AUXILIARY(debug
));
1834 } /* take the most we have */
1836 if (S_GET_NUMBER_AUXILIARY(debug
) > 0) {
1837 memcpy((char*)&normal
->sy_symbol
.ost_auxent
[0], (char*)&debug
->sy_symbol
.ost_auxent
[0], S_GET_NUMBER_AUXILIARY(debug
) * AUXESZ
);
1838 } /* Move all the auxiliary information */
1840 /* Move the debug flags. */
1841 SF_SET_DEBUG_FIELD(normal
, SF_GET_DEBUG_FIELD(debug
));
1842 } /* c_symbol_merge() */
1845 DEFUN(c_line_new
,(symbol
, paddr
, line_number
, frag
),
1848 unsigned short line_number AND
1851 struct lineno_list
* new_line
=
1852 (struct lineno_list
*)xmalloc(sizeof(struct lineno_list
));
1854 segment_info_type
*s
= segment_info
+ now_seg
;
1855 new_line
->line
.l_lnno
= line_number
;
1859 if (line_number
== 0)
1861 last_line_symbol
= symbol
;
1862 new_line
->line
.l_addr
.l_symndx
= (long)symbol
;
1866 new_line
->line
.l_addr
.l_paddr
= paddr
;
1869 new_line
->frag
= (char*)frag
;
1870 new_line
->next
= (struct lineno_list
*)NULL
;
1873 if (s
->lineno_list_head
== (struct lineno_list
*)NULL
)
1875 s
->lineno_list_head
= new_line
;
1879 s
->lineno_list_tail
->next
= new_line
;
1881 s
->lineno_list_tail
= new_line
;
1882 return LINESZ
* s
->scnhdr
.s_nlnno
++;
1885 void c_dot_file_symbol(filename
)
1890 symbolP
= symbol_new(".file",
1893 &zero_address_frag
);
1895 S_SET_STORAGE_CLASS(symbolP
, C_FILE
);
1896 S_SET_NUMBER_AUXILIARY(symbolP
, 1);
1897 SA_SET_FILE_FNAME(symbolP
, filename
);
1903 listing_source_file(filename
);
1909 SF_SET_DEBUG(symbolP
);
1910 S_SET_VALUE(symbolP
, (long) previous_file_symbol
);
1912 previous_file_symbol
= symbolP
;
1914 /* Make sure that the symbol is first on the symbol chain */
1915 if (symbol_rootP
!= symbolP
) {
1916 if (symbolP
== symbol_lastP
) {
1917 symbol_lastP
= symbol_lastP
->sy_previous
;
1918 } /* if it was the last thing on the list */
1920 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1921 symbol_insert(symbolP
, symbol_rootP
, &symbol_rootP
, &symbol_lastP
);
1922 symbol_rootP
= symbolP
;
1923 } /* if not first on the list */
1925 } /* c_dot_file_symbol() */
1928 * Build a 'section static' symbol.
1931 symbolS
*c_section_symbol(name
,idx
)
1937 symbolP
= symbol_new(name
,idx
,
1939 &zero_address_frag
);
1941 S_SET_STORAGE_CLASS(symbolP
, C_STAT
);
1942 S_SET_NUMBER_AUXILIARY(symbolP
, 1);
1944 SF_SET_STATICS(symbolP
);
1947 } /* c_section_symbol() */
1950 DEFUN(w_symbols
,(abfd
, where
, symbol_rootP
),
1953 symbolS
*symbol_rootP
)
1958 /* First fill in those values we have only just worked out */
1959 for (i
= SEG_E0
; i
< SEG_E9
; i
++)
1961 symbolP
= segment_info
[i
].dot
;
1965 SA_SET_SCN_SCNLEN(symbolP
, segment_info
[i
].scnhdr
.s_size
);
1966 SA_SET_SCN_NRELOC(symbolP
, segment_info
[i
].scnhdr
.s_nreloc
);
1967 SA_SET_SCN_NLINNO(symbolP
, segment_info
[i
].scnhdr
.s_nlnno
);
1973 * Emit all symbols left in the symbol chain.
1975 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next(symbolP
)) {
1976 /* Used to save the offset of the name. It is used to point
1977 to the string in memory but must be a file offset. */
1978 register char * temp
;
1980 tc_coff_symbol_emit_hook(symbolP
);
1982 temp
= S_GET_NAME(symbolP
);
1983 if (SF_GET_STRING(symbolP
)) {
1984 S_SET_OFFSET(symbolP
, symbolP
->sy_name_offset
);
1985 S_SET_ZEROES(symbolP
, 0);
1987 bzero(symbolP
->sy_symbol
.ost_entry
.n_name
, SYMNMLEN
);
1988 strncpy(symbolP
->sy_symbol
.ost_entry
.n_name
, temp
, SYMNMLEN
);
1990 where
= symbol_to_chars(abfd
, where
, symbolP
);
1991 S_SET_NAME(symbolP
,temp
);
1996 static void DEFUN_VOID(obj_coff_lcomm
)
2005 name
= input_line_pointer
;
2009 c
= get_symbol_end();
2010 p
= input_line_pointer
;
2013 if (*input_line_pointer
!= ',') {
2014 as_bad("Expected comma after name");
2015 ignore_rest_of_line();
2018 if (*input_line_pointer
== '\n') {
2019 as_bad("Missing size expression");
2022 input_line_pointer
++;
2023 if ((temp
= get_absolute_expression ()) < 0) {
2024 as_warn("lcomm length (%d.) <0! Ignored.", temp
);
2025 ignore_rest_of_line();
2029 symbolP
= symbol_find_or_make(name
);
2030 vma
= segment_info
[SEG_E2
].scnhdr
.s_size
;
2031 vma
+= relax_align(vma
, MIN(8, temp
));
2032 S_SET_VALUE(symbolP
,vma
);
2033 S_SET_SEGMENT(symbolP
, SEG_E2
);
2034 segment_info
[SEG_E2
].scnhdr
.s_size
= vma
+ temp
;
2035 S_SET_STORAGE_CLASS(symbolP
, C_STAT
);
2036 demand_empty_rest_of_line();
2041 static void DEFUN(fixup_segment
,(fixP
, this_segment_type
),
2042 register fixS
* fixP AND
2043 segT this_segment_type
)
2045 register symbolS
*add_symbolP
;
2046 register symbolS
*sub_symbolP
;
2047 register long add_number
;
2049 register char *place
;
2050 register long where
;
2051 register char pcrel
;
2052 register fragS
*fragP
;
2053 register segT add_symbol_segment
= SEG_ABSOLUTE
;
2056 for ( ; fixP
; fixP
= fixP
->fx_next
)
2058 fragP
= fixP
->fx_frag
;
2060 where
= fixP
->fx_where
;
2061 place
= fragP
->fr_literal
+ where
;
2062 size
= fixP
->fx_size
;
2063 add_symbolP
= fixP
->fx_addsy
;
2065 if (fixP
->fx_callj
&& TC_S_IS_CALLNAME(add_symbolP
)) {
2066 /* Relocation should be done via the
2067 associated 'bal' entry point
2070 if (!TC_S_IS_BALNAME(tc_get_bal_of_call(add_symbolP
))) {
2071 as_bad("No 'bal' entry point for leafproc %s",
2072 S_GET_NAME(add_symbolP
));
2075 fixP
->fx_addsy
= add_symbolP
= tc_get_bal_of_call(add_symbolP
);
2076 } /* callj relocation */
2078 sub_symbolP
= fixP
->fx_subsy
;
2079 add_number
= fixP
->fx_offset
;
2080 pcrel
= fixP
->fx_pcrel
;
2083 add_symbol_segment
= S_GET_SEGMENT(add_symbolP
);
2084 } /* if there is an addend */
2089 if (S_GET_SEGMENT(sub_symbolP
) != SEG_ABSOLUTE
) {
2090 as_bad("Negative of non-absolute symbol %s", S_GET_NAME(sub_symbolP
));
2091 } /* not absolute */
2093 add_number
-= S_GET_VALUE(sub_symbolP
);
2095 /* if sub_symbol is in the same segment that add_symbol
2096 and add_symbol is either in DATA, TEXT, BSS or ABSOLUTE */
2097 } else if ((S_GET_SEGMENT(sub_symbolP
) == add_symbol_segment
)
2098 && (SEG_NORMAL(add_symbol_segment
)
2099 || (add_symbol_segment
== SEG_ABSOLUTE
))) {
2100 /* Difference of 2 symbols from same segment. */
2101 /* Can't make difference of 2 undefineds: 'value' means */
2102 /* something different for N_UNDF. */
2104 /* Makes no sense to use the difference of 2 arbitrary symbols
2105 * as the target of a call instruction.
2107 if (fixP
->fx_callj
) {
2108 as_bad("callj to difference of 2 symbols");
2110 #endif /* TC_I960 */
2111 add_number
+= S_GET_VALUE(add_symbolP
) -
2112 S_GET_VALUE(sub_symbolP
);
2115 fixP
->fx_addsy
= NULL
;
2117 /* Different segments in subtraction. */
2118 know(!(S_IS_EXTERNAL(sub_symbolP
) && (S_GET_SEGMENT(sub_symbolP
) == SEG_ABSOLUTE
)));
2120 if ((S_GET_SEGMENT(sub_symbolP
) == SEG_ABSOLUTE
)) {
2121 add_number
-= S_GET_VALUE(sub_symbolP
);
2123 as_bad("Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %d.",
2124 segment_name(S_GET_SEGMENT(sub_symbolP
)),
2125 S_GET_NAME(sub_symbolP
), fragP
->fr_address
+ where
);
2128 } /* if sub_symbolP */
2131 if (add_symbol_segment
== this_segment_type
&& pcrel
) {
2133 * This fixup was made when the symbol's segment was
2134 * SEG_UNKNOWN, but it is now in the local segment.
2135 * So we know how to do the address without relocation.
2138 /* reloc_callj() may replace a 'call' with a 'calls' or a 'bal',
2139 * in which cases it modifies *fixP as appropriate. In the case
2140 * of a 'calls', no further work is required, and *fixP has been
2141 * set up to make the rest of the code below a no-op.
2144 #endif /* TC_I960 */
2146 add_number
+= S_GET_VALUE(add_symbolP
);
2147 add_number
-= md_pcrel_from (fixP
);
2148 pcrel
= 0; /* Lie. Don't want further pcrel processing. */
2149 fixP
->fx_addsy
= NULL
; /* No relocations please. */
2152 switch (add_symbol_segment
)
2156 reloc_callj(fixP
); /* See comment about reloc_callj() above*/
2157 #endif /* TC_I960 */
2158 add_number
+= S_GET_VALUE(add_symbolP
);
2159 fixP
->fx_addsy
= NULL
;
2164 add_number
+= S_GET_VALUE(add_symbolP
) +
2165 segment_info
[S_GET_SEGMENT(add_symbolP
)].scnhdr
.s_paddr
;
2170 if ((int)fixP
->fx_bit_fixP
== 13) {
2171 /* This is a COBR instruction. They have only a
2172 * 13-bit displacement and are only to be used
2173 * for local branches: flag as error, don't generate
2176 as_bad("can't use COBR format with external label");
2177 fixP
->fx_addsy
= NULL
; /* No relocations please. */
2180 #endif /* TC_I960 */
2187 } /* switch on symbol seg */
2188 } /* if not in local seg */
2189 } /* if there was a + symbol */
2192 add_number
-= md_pcrel_from(fixP
);
2193 if (add_symbolP
== 0) {
2194 fixP
->fx_addsy
= & abs_symbol
;
2195 } /* if there's an add_symbol */
2198 if (!fixP
->fx_bit_fixP
) {
2200 (add_number
& ~0xFF) && (add_number
&~0xFF!=(-1&~0xFF))) ||
2202 (add_number
& ~0xFFFF) && (add_number
&~0xFFFF!=(-1&~0xFFFF)))) {
2203 as_bad("Value of %d too large for field of %d bytes at 0x%x",
2204 add_number
, size
, fragP
->fr_address
+ where
);
2205 } /* generic error checking */
2206 } /* not a bit fix */
2207 /* once this fix has been applied, we don't have to output anything
2208 nothing more need be done -*/
2209 md_apply_fix(fixP
, add_number
);
2211 } /* For each fixS in this segment. */
2214 } /* fixup_segment() */