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"
44 #include "../bfd/libcoff.h"
47 #define MIN(a,b) ((a) < (b)? (a) : (b))
48 /* This vector is used to turn an internal segment into a section #
49 suitable for insertion into a coff symbol table
52 const short seg_N_TYPE
[] =
53 { /* in: segT out: N_TYPE bits */
65 C_UNDEF_SECTION
, /* SEG_UNKNOWN */
66 C_UNDEF_SECTION
, /* SEG_ABSENT */
67 C_UNDEF_SECTION
, /* SEG_PASS1 */
68 C_UNDEF_SECTION
, /* SEG_GOOF */
69 C_UNDEF_SECTION
, /* SEG_BIG */
70 C_UNDEF_SECTION
, /* SEG_DIFFERENCE */
71 C_DEBUG_SECTION
, /* SEG_DEBUG */
72 C_NTV_SECTION
, /* SEG_NTV */
73 C_PTV_SECTION
, /* SEG_PTV */
74 C_REGISTER_SECTION
, /* SEG_REGISTER */
78 int function_lineoff
= -1; /* Offset in line#s where the last function
79 started (the odd entry for line #0) */
85 static symbolS
*last_line_symbol
;
86 /* Add 4 to the real value to get the index and compensate the
87 negatives. This vector is used by S_GET_SEGMENT to turn a coff
88 section number into a segment number
90 static symbolS
*previous_file_symbol
= NULL
;
91 void c_symbol_merge ();
94 symbolS
*c_section_symbol ();
96 void EXFUN (bfd_as_write_hook
, (struct internal_filehdr
*,
99 static void EXFUN (fixup_segment
, (fixS
* fixP
,
100 segT this_segment_type
));
103 static void EXFUN (fixup_mdeps
, (fragS
*));
106 static void EXFUN (fill_section
, (bfd
* abfd
,
107 struct internal_filehdr
* f
, unsigned
111 char *EXFUN (s_get_name
, (symbolS
* s
));
112 static symbolS
*EXFUN (tag_find_or_make
, (char *name
));
113 static symbolS
*EXFUN (tag_find
, (char *name
));
120 unsigned short line_number
,
124 static void EXFUN (w_symbols
,
127 symbolS
* symbol_rootP
));
131 static void EXFUN (obj_coff_def
, (int what
));
132 static void EXFUN (obj_coff_lcomm
, (void));
133 static void EXFUN (obj_coff_dim
, (void));
134 static void EXFUN (obj_coff_text
, (void));
135 static void EXFUN (obj_coff_data
, (void));
136 static void EXFUN (obj_coff_endef
, (void));
137 static void EXFUN (obj_coff_line
, (void));
138 static void EXFUN (obj_coff_ln
, (void));
139 static void EXFUN (obj_coff_scl
, (void));
140 static void EXFUN (obj_coff_size
, (void));
141 static void EXFUN (obj_coff_tag
, (void));
142 static void EXFUN (obj_coff_type
, (void));
143 static void EXFUN (obj_coff_val
, (void));
144 void EXFUN (obj_coff_section
, (void));
145 static void EXFUN (tag_init
, (void));
146 static void EXFUN (tag_insert
, (char *name
, symbolS
* symbolP
));
149 static struct hash_control
*tag_hash
;
150 static symbolS
*def_symbol_in_progress
= NULL
;
152 const pseudo_typeS obj_pseudo_table
[] =
154 {"def", obj_coff_def
, 0},
155 {"dim", obj_coff_dim
, 0},
156 {"endef", obj_coff_endef
, 0},
157 {"line", obj_coff_line
, 0},
158 {"ln", obj_coff_ln
, 0},
159 {"scl", obj_coff_scl
, 0},
160 {"size", obj_coff_size
, 0},
161 {"tag", obj_coff_tag
, 0},
162 {"type", obj_coff_type
, 0},
163 {"val", obj_coff_val
, 0},
164 {"section", obj_coff_section
, 0},
165 {"use", obj_coff_section
, 0},
166 {"sect", obj_coff_section
, 0},
167 {"text", obj_coff_text
, 0},
168 {"data", obj_coff_data
, 0},
169 /* we don't yet handle this. */
170 {"ident", s_ignore
, 0},
171 {"ABORT", s_abort
, 0},
172 {"lcomm", obj_coff_lcomm
, 0},
173 {NULL
} /* end sentinel */
174 }; /* obj_pseudo_table */
180 We allow more than just the standard 3 sections, infact, we allow
181 10 sections, (though the usual three have to be there).
183 This structure performs the mappings for us:
188 static struct internal_scnhdr bss_section_header;
189 struct internal_scnhdr data_section_header;
190 struct internal_scnhdr text_section_header;
192 const segT N_TYPE_seg [32] =
208 seg_info_type seg_info_off_by_4
[N_SEG
] =
234 {SEG_REGISTER
}, 0, 0, 0, 0};
236 #define SEG_INFO_FROM_SECTION_NUMBER(x) (seg_info_off_by_4[(x)+4])
237 #define SEG_INFO_FROM_SEG_NUMBER(x) (seg_info_off_by_4[(x)])
241 DEFUN (relax_align
, (address
, alignment
),
242 register relax_addressT address AND
243 register long alignment
)
246 relax_addressT new_address
;
248 mask
= ~((~0) << alignment
);
249 new_address
= (address
+ mask
) & (~mask
);
250 return (new_address
- address
);
251 } /* relax_align() */
255 DEFUN (s_get_segment
, (x
),
258 return SEG_INFO_FROM_SECTION_NUMBER (x
->sy_symbol
.ost_entry
.n_scnum
).seg_t
;
263 /* calculate the size of the frag chain and fill in the section header
264 to contain all of it, also fill in the addr of the sections */
266 DEFUN (size_section
, (abfd
, idx
),
271 unsigned int size
= 0;
272 fragS
*frag
= segment_info
[idx
].frchainP
->frch_root
;
275 size
= frag
->fr_address
;
277 if (frag
->fr_address
!= size
)
279 printf ("Out of step\n");
280 size
= frag
->fr_address
;
283 switch (frag
->fr_type
)
285 #ifdef TC_COFF_SIZEMACHDEP
286 case rs_machine_dependent
:
287 size
+= TC_COFF_SIZEMACHDEP (frag
);
292 size
+= frag
->fr_fix
;
293 size
+= frag
->fr_offset
* frag
->fr_var
;
296 size
+= frag
->fr_fix
;
297 size
+= relax_align (size
, frag
->fr_offset
);
300 frag
= frag
->fr_next
;
302 segment_info
[idx
].scnhdr
.s_size
= size
;
308 DEFUN (count_entries_in_chain
, (idx
),
311 unsigned int nrelocs
;
314 /* Count the relocations */
315 fixup_ptr
= segment_info
[idx
].fix_root
;
317 while (fixup_ptr
!= (fixS
*) NULL
)
319 if (TC_COUNT_RELOC (fixup_ptr
))
324 if (fixup_ptr
->fx_r_type
== RELOC_CONSTH
)
333 fixup_ptr
= fixup_ptr
->fx_next
;
338 /* output all the relocations for a section */
340 DEFUN (do_relocs_for
, (abfd
, file_cursor
),
342 unsigned long *file_cursor
)
344 unsigned int nrelocs
;
346 unsigned int addr
= 0;
347 for (idx
= SEG_E0
; idx
< SEG_E9
; idx
++)
349 if (segment_info
[idx
].scnhdr
.s_name
[0])
352 struct external_reloc
*ext_ptr
;
353 struct external_reloc
*external_reloc_vec
;
354 unsigned int external_reloc_size
;
355 unsigned int count
= 0;
356 unsigned int base
= addr
;
357 fixS
*fix_ptr
= segment_info
[idx
].fix_root
;
358 nrelocs
= count_entries_in_chain (idx
);
363 external_reloc_size
= nrelocs
* RELSZ
;
365 (struct external_reloc
*) malloc (external_reloc_size
);
369 ext_ptr
= external_reloc_vec
;
371 /* Fill in the internal coff style reloc struct from the
376 struct internal_reloc intr
;
378 /* Only output some of the relocations */
379 if (TC_COUNT_RELOC (fix_ptr
))
381 #ifdef TC_RELOC_MANGLE
382 TC_RELOC_MANGLE (fix_ptr
, &intr
, base
);
386 symbol_ptr
= fix_ptr
->fx_addsy
;
388 intr
.r_type
= TC_COFF_FIX2RTYPE (fix_ptr
);
390 base
+ fix_ptr
->fx_frag
->fr_address
+ fix_ptr
->fx_where
;
392 intr
.r_offset
= fix_ptr
->fx_offset
;
396 /* Turn the segment of the symbol into an offset
400 dot
= segment_info
[S_GET_SEGMENT (symbol_ptr
)].dot
;
403 intr
.r_symndx
= dot
->sy_number
;
407 intr
.r_symndx
= symbol_ptr
->sy_number
;
419 (void) bfd_coff_swap_reloc_out (abfd
, &intr
, ext_ptr
);
423 /* The 29k has a special kludge for the high 16 bit reloc.
424 Two relocations are emmited, R_IHIHALF, and
425 R_IHCONST. The second one doesn't contain a symbol,
426 but uses the value for offset */
428 if (intr
.r_type
== R_IHIHALF
)
430 /* now emit the second bit */
431 intr
.r_type
= R_IHCONST
;
432 intr
.r_symndx
= fix_ptr
->fx_addnumber
;
433 (void) bfd_coff_swap_reloc_out (abfd
, &intr
, ext_ptr
);
439 fix_ptr
= fix_ptr
->fx_next
;
442 /* Write out the reloc table */
443 segment_info
[idx
].scnhdr
.s_relptr
= *file_cursor
;
444 segment_info
[idx
].scnhdr
.s_nreloc
= nrelocs
;
445 bfd_write ((PTR
) external_reloc_vec
, 1, external_reloc_size
, abfd
);
446 *file_cursor
+= external_reloc_size
;
447 free (external_reloc_vec
);
449 #ifndef ZERO_BASED_SEGMENTS
450 /* Supposedly setting segment addresses non-zero causes problems
451 for some platforms, although it shouldn't. If you define
452 ZERO_BASED_SEGMENTS, all the segments will be based at 0.
453 Please don't make this the default, since some systems (e.g.,
454 SVR3.2) require the segments to be non-zero based. Ian Taylor
456 addr
+= segment_info
[idx
].scnhdr
.s_size
;
462 /* run through a frag chain and write out the data to go with it, fill
463 in the scnhdrs with the info on the file postions
466 DEFUN (fill_section
, (abfd
, filehdr
, file_cursor
),
468 struct internal_filehdr
*filehdr AND
469 unsigned long *file_cursor
)
474 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
476 unsigned int offset
= 0;
478 struct internal_scnhdr
*s
= &(segment_info
[i
].scnhdr
);
482 fragS
*frag
= segment_info
[i
].frchainP
->frch_root
;
483 char *buffer
= malloc (s
->s_size
);
485 s
->s_scnptr
= *file_cursor
;
489 s
->s_flags
= STYP_REG
;
490 if (strcmp (s
->s_name
, ".text") == 0)
491 s
->s_flags
|= STYP_TEXT
;
492 else if (strcmp (s
->s_name
, ".data") == 0)
493 s
->s_flags
|= STYP_DATA
;
494 else if (strcmp (s
->s_name
, ".bss") == 0)
495 s
->s_flags
|= STYP_BSS
| STYP_NOLOAD
;
496 else if (strcmp (s
->s_name
, ".lit") == 0)
497 s
->s_flags
= STYP_LIT
| STYP_TEXT
;
502 unsigned int fill_size
;
503 switch (frag
->fr_type
)
505 case rs_machine_dependent
:
508 memcpy (buffer
+ frag
->fr_address
,
511 offset
+= frag
->fr_fix
;
520 memcpy (buffer
+ frag
->fr_address
,
523 offset
+= frag
->fr_fix
;
526 fill_size
= frag
->fr_var
;
530 unsigned int off
= frag
->fr_fix
;
531 for (count
= frag
->fr_offset
; count
; count
--)
533 memcpy (buffer
+ frag
->fr_address
+ off
,
534 frag
->fr_literal
+ frag
->fr_fix
,
548 frag
= frag
->fr_next
;
552 bfd_write (buffer
, s
->s_size
, 1, abfd
);
555 *file_cursor
+= s
->s_size
;
564 /* Coff file generation & utilities */
568 DEFUN (coff_header_append
, (abfd
, filehdr
, aouthdr
),
570 struct internal_filehdr
*filehdr AND
571 struct internal_aouthdr
*aouthdr
)
577 bfd_seek (abfd
, 0, 0);
579 filehdr
.f_opthdr
= bfd_coff_swap_aouthdr_out (abfd
, aouthdr
,
582 filehdr
->f_opthdr
= 0;
584 i
= bfd_coff_swap_filehdr_out (abfd
, filehdr
, buffer
);
586 bfd_write (buffer
, i
, 1, abfd
);
587 bfd_write (buffero
, filehdr
->f_opthdr
, 1, abfd
);
589 for (i
= SEG_E0
; i
< SEG_E9
; i
++)
591 if (segment_info
[i
].scnhdr
.s_name
[0])
594 bfd_coff_swap_scnhdr_out (abfd
,
595 &(segment_info
[i
].scnhdr
),
597 bfd_write (buffer
, size
, 1, abfd
);
604 DEFUN (symbol_to_chars
, (abfd
, where
, symbolP
),
609 unsigned int numaux
= symbolP
->sy_symbol
.ost_entry
.n_numaux
;
612 /* Turn any symbols with register attributes into abs symbols */
613 if (S_GET_SEGMENT (symbolP
) == SEG_REGISTER
)
615 S_SET_SEGMENT (symbolP
, SEG_ABSOLUTE
);
617 /* At the same time, relocate all symbols to their output value */
619 S_SET_VALUE (symbolP
,
620 segment_info
[S_GET_SEGMENT (symbolP
)].scnhdr
.s_paddr
621 + S_GET_VALUE (symbolP
));
623 where
+= bfd_coff_swap_sym_out (abfd
, &symbolP
->sy_symbol
.ost_entry
,
626 for (i
= 0; i
< numaux
; i
++)
628 where
+= bfd_coff_swap_aux_out (abfd
,
629 &symbolP
->sy_symbol
.ost_auxent
[i
],
630 S_GET_DATA_TYPE (symbolP
),
631 S_GET_STORAGE_CLASS (symbolP
),
642 obj_symbol_new_hook (symbolP
)
645 char underscore
= 0; /* Symbol has leading _ */
647 /* Effective symbol */
648 /* Store the pointer in the offset. */
649 S_SET_ZEROES (symbolP
, 0L);
650 S_SET_DATA_TYPE (symbolP
, T_NULL
);
651 S_SET_STORAGE_CLASS (symbolP
, 0);
652 S_SET_NUMBER_AUXILIARY (symbolP
, 0);
653 /* Additional information */
654 symbolP
->sy_symbol
.ost_flags
= 0;
655 /* Auxiliary entries */
656 bzero ((char *) &symbolP
->sy_symbol
.ost_auxent
[0], AUXESZ
);
658 #ifdef STRIP_UNDERSCORE
659 /* Remove leading underscore at the beginning of the symbol.
660 * This is to be compatible with the standard librairies.
662 if (*S_GET_NAME (symbolP
) == '_')
665 S_SET_NAME (symbolP
, S_GET_NAME (symbolP
) + 1);
666 } /* strip underscore */
667 #endif /* STRIP_UNDERSCORE */
669 if (S_IS_STRING (symbolP
))
670 SF_SET_STRING (symbolP
);
671 if (!underscore
&& S_IS_LOCAL (symbolP
))
672 SF_SET_LOCAL (symbolP
);
675 } /* obj_symbol_new_hook() */
679 stack_init (chunk_size
, element_size
)
680 unsigned long chunk_size
;
681 unsigned long element_size
;
685 if ((st
= (stack
*) malloc (sizeof (stack
))) == (stack
*) 0)
687 if ((st
->data
= malloc (chunk_size
)) == (char *) 0)
693 st
->size
= chunk_size
;
694 st
->chunk_size
= chunk_size
;
695 st
->element_size
= element_size
;
708 stack_push (st
, element
)
712 if (st
->pointer
+ st
->element_size
>= st
->size
)
714 st
->size
+= st
->chunk_size
;
715 if ((st
->data
= xrealloc (st
->data
, st
->size
)) == (char *) 0)
718 memcpy (st
->data
+ st
->pointer
, element
, st
->element_size
);
719 st
->pointer
+= st
->element_size
;
720 return st
->data
+ st
->pointer
;
727 if ((st
->pointer
-= st
->element_size
) < 0)
733 return st
->data
+ st
->pointer
;
740 return st
->data
+ st
->pointer
- st
->element_size
;
745 * Handle .ln directives.
753 if (def_symbol_in_progress
!= NULL
)
755 as_warn (".ln pseudo-op inside .def/.endef: ignored.");
756 demand_empty_rest_of_line ();
758 } /* wrong context */
761 obstack_next_free (&frags
) - frag_now
->fr_literal
,
762 l
= get_absolute_expression (),
770 listing_source_line (l
+ line_base
- 1);
775 demand_empty_rest_of_line ();
777 } /* obj_coff_line() */
782 * Handle .def directives.
784 * One might ask : why can't we symbol_new if the symbol does not
785 * already exist and fill it with debug information. Because of
786 * the C_EFCN special symbol. It would clobber the value of the
787 * function symbol before we have a chance to notice that it is
788 * a C_EFCN. And a second reason is that the code is more clear this
789 * way. (at least I think it is :-).
793 #define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';')
794 #define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \
795 *input_line_pointer == '\t') \
796 input_line_pointer++;
799 DEFUN (obj_coff_def
, (what
),
802 char name_end
; /* Char after the end of name */
803 char *symbol_name
; /* Name of the debug symbol */
804 char *symbol_name_copy
; /* Temporary copy of the name */
805 unsigned int symbol_name_length
;
806 /*$char* directiveP;$ *//* Name of the pseudo opcode */
807 /*$char directive[MAX_DIRECTIVE];$ *//* Backup of the directive */
808 /*$char end = 0;$ *//* If 1, stop parsing */
810 if (def_symbol_in_progress
!= NULL
)
812 as_warn (".def pseudo-op used inside of .def/.endef: ignored.");
813 demand_empty_rest_of_line ();
815 } /* if not inside .def/.endef */
819 def_symbol_in_progress
= (symbolS
*) obstack_alloc (¬es
, sizeof (*def_symbol_in_progress
));
820 bzero (def_symbol_in_progress
, sizeof (*def_symbol_in_progress
));
822 symbol_name
= input_line_pointer
;
823 name_end
= get_symbol_end ();
824 symbol_name_length
= strlen (symbol_name
);
825 symbol_name_copy
= xmalloc (symbol_name_length
+ 1);
826 strcpy (symbol_name_copy
, symbol_name
);
828 /* Initialize the new symbol */
829 #ifdef STRIP_UNDERSCORE
830 S_SET_NAME (def_symbol_in_progress
, (*symbol_name_copy
== '_'
831 ? symbol_name_copy
+ 1
832 : symbol_name_copy
));
833 #else /* STRIP_UNDERSCORE */
834 S_SET_NAME (def_symbol_in_progress
, symbol_name_copy
);
835 #endif /* STRIP_UNDERSCORE */
836 /* free(symbol_name_copy); */
837 def_symbol_in_progress
->sy_name_offset
= ~0;
838 def_symbol_in_progress
->sy_number
= ~0;
839 def_symbol_in_progress
->sy_frag
= &zero_address_frag
;
841 if (S_IS_STRING (def_symbol_in_progress
))
843 SF_SET_STRING (def_symbol_in_progress
);
846 *input_line_pointer
= name_end
;
848 demand_empty_rest_of_line ();
850 } /* obj_coff_def() */
852 unsigned int dim_index
;
854 DEFUN_VOID (obj_coff_endef
)
856 symbolS
*symbolP
= 0;
857 /* DIM BUG FIX sac@cygnus.com */
859 if (def_symbol_in_progress
== NULL
)
861 as_warn (".endef pseudo-op used outside of .def/.endef: ignored.");
862 demand_empty_rest_of_line ();
864 } /* if not inside .def/.endef */
866 /* Set the section number according to storage class. */
867 switch (S_GET_STORAGE_CLASS (def_symbol_in_progress
))
872 SF_SET_TAG (def_symbol_in_progress
);
873 /* intentional fallthrough */
876 SF_SET_DEBUG (def_symbol_in_progress
);
877 S_SET_SEGMENT (def_symbol_in_progress
, SEG_DEBUG
);
881 SF_SET_LOCAL (def_symbol_in_progress
); /* Do not emit this symbol. */
882 /* intentional fallthrough */
884 SF_SET_PROCESS (def_symbol_in_progress
); /* Will need processing before writing */
885 /* intentional fallthrough */
887 S_SET_SEGMENT (def_symbol_in_progress
, SEG_E0
);
889 if (def_symbol_in_progress
->sy_symbol
.ost_entry
._n
._n_nptr
[1][1] == 'b'
890 && def_symbol_in_progress
->sy_symbol
.ost_entry
._n
._n_nptr
[1][2] == 'f')
892 if (function_lineoff
< 0)
894 fprintf (stderr
, "`.bf' symbol without preceding function\n");
895 } /* missing function symbol */
896 SA_GET_SYM_LNNOPTR (last_line_symbol
) = function_lineoff
;
898 SF_SET_PROCESS (last_line_symbol
);
899 function_lineoff
= -1;
905 #endif /* C_AUTOARG */
915 SF_SET_DEBUG (def_symbol_in_progress
);
916 S_SET_SEGMENT (def_symbol_in_progress
, SEG_ABSOLUTE
);
922 /* Valid but set somewhere else (s_comm, s_lcomm, colon) */
928 as_warn ("unexpected storage class %d", S_GET_STORAGE_CLASS (def_symbol_in_progress
));
930 } /* switch on storage class */
932 /* Now that we have built a debug symbol, try to
933 find if we should merge with an existing symbol
934 or not. If a symbol is C_EFCN or SEG_ABSOLUTE or
935 untagged SEG_DEBUG it never merges. */
937 /* Two cases for functions. Either debug followed
938 by definition or definition followed by debug.
939 For definition first, we will merge the debug
940 symbol into the definition. For debug first, the
941 lineno entry MUST point to the definition
942 function or else it will point off into space
943 when crawl_symbols() merges the debug
944 symbol into the real symbol. Therefor, let's
945 presume the debug symbol is a real function
948 /* FIXME-SOON If for some reason the definition
949 label/symbol is never seen, this will probably
950 leave an undefined symbol at link time. */
952 if (S_GET_STORAGE_CLASS (def_symbol_in_progress
) == C_EFCN
953 || (S_GET_SEGMENT (def_symbol_in_progress
) == SEG_DEBUG
954 && !SF_GET_TAG (def_symbol_in_progress
))
955 || S_GET_SEGMENT (def_symbol_in_progress
) == SEG_ABSOLUTE
956 || (symbolP
= symbol_find_base (S_GET_NAME (def_symbol_in_progress
), DO_NOT_STRIP
)) == NULL
)
959 symbol_append (def_symbol_in_progress
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
964 /* This symbol already exists, merge the
965 newly created symbol into the old one.
966 This is not mandatory. The linker can
967 handle duplicate symbols correctly. But I
968 guess that it save a *lot* of space if
969 the assembly file defines a lot of
972 /* The debug entry (def_symbol_in_progress)
973 is merged into the previous definition. */
975 c_symbol_merge (def_symbol_in_progress
, symbolP
);
976 /* FIXME-SOON Should *def_symbol_in_progress be free'd? xoxorich. */
977 def_symbol_in_progress
= symbolP
;
979 if (SF_GET_FUNCTION (def_symbol_in_progress
)
980 || SF_GET_TAG (def_symbol_in_progress
))
982 /* For functions, and tags, the symbol *must* be where the debug symbol
983 appears. Move the existing symbol to the current place. */
984 /* If it already is at the end of the symbol list, do nothing */
985 if (def_symbol_in_progress
!= symbol_lastP
)
987 symbol_remove (def_symbol_in_progress
, &symbol_rootP
, &symbol_lastP
);
988 symbol_append (def_symbol_in_progress
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
989 } /* if not already in place */
991 } /* normal or mergable */
993 if (SF_GET_TAG (def_symbol_in_progress
)
994 && symbol_find_base (S_GET_NAME (def_symbol_in_progress
), DO_NOT_STRIP
) == NULL
)
996 tag_insert (S_GET_NAME (def_symbol_in_progress
), def_symbol_in_progress
);
997 } /* If symbol is a {structure,union} tag, associate symbol to its name. */
999 if (SF_GET_FUNCTION (def_symbol_in_progress
))
1001 know (sizeof (def_symbol_in_progress
) <= sizeof (long));
1003 = c_line_new (def_symbol_in_progress
, 0, 0, &zero_address_frag
);
1007 SF_SET_PROCESS (def_symbol_in_progress
);
1009 if (symbolP
== NULL
)
1011 /* That is, if this is the first
1012 time we've seen the function... */
1013 symbol_table_insert (def_symbol_in_progress
);
1014 } /* definition follows debug */
1015 } /* Create the line number entry pointing to the function being defined */
1017 def_symbol_in_progress
= NULL
;
1018 demand_empty_rest_of_line ();
1020 } /* obj_coff_endef() */
1023 DEFUN_VOID (obj_coff_dim
)
1025 register int dim_index
;
1027 if (def_symbol_in_progress
== NULL
)
1029 as_warn (".dim 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);
1036 for (dim_index
= 0; dim_index
< DIMNUM
; dim_index
++)
1038 SKIP_WHITESPACES ();
1039 SA_SET_SYM_DIMEN (def_symbol_in_progress
, dim_index
, get_absolute_expression ());
1041 switch (*input_line_pointer
)
1045 input_line_pointer
++;
1049 as_warn ("badly formed .dim directive ignored");
1050 /* intentional fallthrough */
1055 } /* switch on following character */
1056 } /* for each dimension */
1058 demand_empty_rest_of_line ();
1060 } /* obj_coff_dim() */
1067 if (def_symbol_in_progress
== NULL
)
1071 } /* if it looks like a stabs style line */
1073 this_base
= get_absolute_expression ();
1074 if (this_base
> line_base
)
1076 line_base
= this_base
;
1085 listing_source_line (line_base
);
1089 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress
, 1);
1090 SA_SET_SYM_LNNO (def_symbol_in_progress
, line_base
);
1092 demand_empty_rest_of_line ();
1094 } /* obj_coff_line() */
1099 if (def_symbol_in_progress
== NULL
)
1101 as_warn (".size pseudo-op used outside of .def/.endef ignored.");
1102 demand_empty_rest_of_line ();
1104 } /* if not inside .def/.endef */
1106 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress
, 1);
1107 SA_SET_SYM_SIZE (def_symbol_in_progress
, get_absolute_expression ());
1108 demand_empty_rest_of_line ();
1110 } /* obj_coff_size() */
1115 if (def_symbol_in_progress
== NULL
)
1117 as_warn (".scl pseudo-op used outside of .def/.endef ignored.");
1118 demand_empty_rest_of_line ();
1120 } /* if not inside .def/.endef */
1122 S_SET_STORAGE_CLASS (def_symbol_in_progress
, get_absolute_expression ());
1123 demand_empty_rest_of_line ();
1125 } /* obj_coff_scl() */
1133 if (def_symbol_in_progress
== NULL
)
1135 as_warn (".tag pseudo-op used outside of .def/.endef ignored.");
1136 demand_empty_rest_of_line ();
1138 } /* if not inside .def/.endef */
1140 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress
, 1);
1141 symbol_name
= input_line_pointer
;
1142 name_end
= get_symbol_end ();
1144 /* Assume that the symbol referred to by .tag is always defined. */
1145 /* This was a bad assumption. I've added find_or_make. xoxorich. */
1146 SA_SET_SYM_TAGNDX (def_symbol_in_progress
, (long) tag_find_or_make (symbol_name
));
1147 if (SA_GET_SYM_TAGNDX (def_symbol_in_progress
) == 0L)
1149 as_warn ("tag not found for .tag %s", symbol_name
);
1152 SF_SET_TAGGED (def_symbol_in_progress
);
1153 *input_line_pointer
= name_end
;
1155 demand_empty_rest_of_line ();
1157 } /* obj_coff_tag() */
1162 if (def_symbol_in_progress
== NULL
)
1164 as_warn (".type pseudo-op used outside of .def/.endef ignored.");
1165 demand_empty_rest_of_line ();
1167 } /* if not inside .def/.endef */
1169 S_SET_DATA_TYPE (def_symbol_in_progress
, get_absolute_expression ());
1171 if (ISFCN (S_GET_DATA_TYPE (def_symbol_in_progress
)) &&
1172 S_GET_STORAGE_CLASS (def_symbol_in_progress
) != C_TPDEF
)
1174 SF_SET_FUNCTION (def_symbol_in_progress
);
1175 } /* is a function */
1177 demand_empty_rest_of_line ();
1179 } /* obj_coff_type() */
1184 if (def_symbol_in_progress
== NULL
)
1186 as_warn (".val pseudo-op used outside of .def/.endef ignored.");
1187 demand_empty_rest_of_line ();
1189 } /* if not inside .def/.endef */
1191 if (is_name_beginner (*input_line_pointer
))
1193 char *symbol_name
= input_line_pointer
;
1194 char name_end
= get_symbol_end ();
1196 if (!strcmp (symbol_name
, "."))
1198 def_symbol_in_progress
->sy_frag
= frag_now
;
1199 S_SET_VALUE (def_symbol_in_progress
, obstack_next_free (&frags
) - frag_now
->fr_literal
);
1200 /* If the .val is != from the .def (e.g. statics) */
1202 else if (strcmp (S_GET_NAME (def_symbol_in_progress
), symbol_name
))
1204 def_symbol_in_progress
->sy_forward
= symbol_find_or_make (symbol_name
);
1206 /* If the segment is undefined when the forward
1207 reference is solved, then copy the segment id
1208 from the forward symbol. */
1209 SF_SET_GET_SEGMENT (def_symbol_in_progress
);
1211 /* Otherwise, it is the name of a non debug symbol and its value will be calculated later. */
1212 *input_line_pointer
= name_end
;
1216 S_SET_VALUE (def_symbol_in_progress
, get_absolute_expression ());
1217 } /* if symbol based */
1219 demand_empty_rest_of_line ();
1221 } /* obj_coff_val() */
1224 * Maintain a list of the tagnames of the structres.
1230 tag_hash
= hash_new ();
1235 tag_insert (name
, symbolP
)
1239 register char *error_string
;
1241 if (*(error_string
= hash_jam (tag_hash
, name
, (char *) symbolP
)))
1243 as_fatal ("Inserting \"%s\" into structure table failed: %s",
1244 name
, error_string
);
1247 } /* tag_insert() */
1250 tag_find_or_make (name
)
1255 if ((symbolP
= tag_find (name
)) == NULL
)
1257 symbolP
= symbol_new (name
,
1260 &zero_address_frag
);
1262 tag_insert (S_GET_NAME (symbolP
), symbolP
);
1263 symbol_table_insert (symbolP
);
1267 } /* tag_find_or_make() */
1273 #ifdef STRIP_UNDERSCORE
1276 #endif /* STRIP_UNDERSCORE */
1277 return ((symbolS
*) hash_find (tag_hash
, name
));
1281 obj_read_begin_hook ()
1283 /* These had better be the same. Usually 18 bytes. */
1285 know (sizeof (SYMENT
) == sizeof (AUXENT
));
1286 know (SYMESZ
== AUXESZ
);
1291 } /* obj_read_begin_hook() */
1293 /* This function runs through the symbol table and puts all the
1294 externals onto another chain */
1296 /* The chain of externals */
1297 symbolS
*symbol_externP
= NULL
;
1298 symbolS
*symbol_extern_lastP
= NULL
;
1301 symbolS
*last_functionP
= NULL
;
1306 DEFUN_VOID (yank_symbols
)
1309 unsigned int symbol_number
= 0;
1311 for (symbolP
= symbol_rootP
;
1313 symbolP
= symbolP
? symbol_next (symbolP
) : symbol_rootP
)
1315 if (!SF_GET_DEBUG (symbolP
))
1317 /* Debug symbols do not need all this rubbish */
1318 symbolS
*real_symbolP
;
1320 /* L* and C_EFCN symbols never merge. */
1321 if (!SF_GET_LOCAL (symbolP
)
1322 && (real_symbolP
= symbol_find_base (S_GET_NAME (symbolP
), DO_NOT_STRIP
))
1323 && real_symbolP
!= symbolP
)
1325 /* FIXME-SOON: where do dups come from?
1326 Maybe tag references before definitions? xoxorich. */
1327 /* Move the debug data from the debug symbol to the
1328 real symbol. Do NOT do the oposite (i.e. move from
1329 real symbol to debug symbol and remove real symbol from the
1330 list.) Because some pointers refer to the real symbol
1331 whereas no pointers refer to the debug symbol. */
1332 c_symbol_merge (symbolP
, real_symbolP
);
1333 /* Replace the current symbol by the real one */
1334 /* The symbols will never be the last or the first
1335 because : 1st symbol is .file and 3 last symbols are
1336 .text, .data, .bss */
1337 symbol_remove (real_symbolP
, &symbol_rootP
, &symbol_lastP
);
1338 symbol_insert (real_symbolP
, symbolP
, &symbol_rootP
, &symbol_lastP
);
1339 symbol_remove (symbolP
, &symbol_rootP
, &symbol_lastP
);
1340 symbolP
= real_symbolP
;
1341 } /* if not local but dup'd */
1343 if (flagseen
['R'] && (S_GET_SEGMENT (symbolP
) == SEG_E1
))
1345 S_SET_SEGMENT (symbolP
, SEG_E0
);
1346 } /* push data into text */
1348 S_SET_VALUE (symbolP
,
1349 S_GET_VALUE (symbolP
) + symbolP
->sy_frag
->fr_address
);
1351 if (!S_IS_DEFINED (symbolP
) && !SF_GET_LOCAL (symbolP
))
1353 S_SET_EXTERNAL (symbolP
);
1355 else if (S_GET_STORAGE_CLASS (symbolP
) == C_NULL
)
1357 if (S_GET_SEGMENT (symbolP
) == SEG_E0
)
1359 S_SET_STORAGE_CLASS (symbolP
, C_LABEL
);
1363 S_SET_STORAGE_CLASS (symbolP
, C_STAT
);
1367 /* Mainly to speed up if not -g */
1368 if (SF_GET_PROCESS (symbolP
))
1370 /* Handle the nested blocks auxiliary info. */
1371 if (S_GET_STORAGE_CLASS (symbolP
) == C_BLOCK
)
1373 if (!strcmp (S_GET_NAME (symbolP
), ".bb"))
1374 stack_push (block_stack
, (char *) &symbolP
);
1377 register symbolS
*begin_symbolP
;
1378 begin_symbolP
= *(symbolS
**) stack_pop (block_stack
);
1379 if (begin_symbolP
== (symbolS
*) 0)
1380 as_warn ("mismatched .eb");
1382 SA_SET_SYM_ENDNDX (begin_symbolP
, symbol_number
+ 2);
1385 /* If we are able to identify the type of a function, and we
1386 are out of a function (last_functionP == 0) then, the
1387 function symbol will be associated with an auxiliary
1389 if (last_functionP
== (symbolS
*) 0 &&
1390 SF_GET_FUNCTION (symbolP
))
1392 last_functionP
= symbolP
;
1394 if (S_GET_NUMBER_AUXILIARY (symbolP
) < 1)
1396 S_SET_NUMBER_AUXILIARY (symbolP
, 1);
1397 } /* make it at least 1 */
1399 /* Clobber possible stale .dim information. */
1401 /* Iffed out by steve - this fries the lnnoptr info too */
1402 bzero (symbolP
->sy_symbol
.ost_auxent
[0].x_sym
.x_fcnary
.x_ary
.x_dimen
,
1403 sizeof (symbolP
->sy_symbol
.ost_auxent
[0].x_sym
.x_fcnary
.x_ary
.x_dimen
));
1406 /* The C_FCN doesn't need any additional information.
1407 I don't even know if this is needed for sdb. But the
1408 standard assembler generates it, so...
1410 if (S_GET_STORAGE_CLASS (symbolP
) == C_EFCN
)
1412 if (last_functionP
== (symbolS
*) 0)
1413 as_fatal ("C_EFCN symbol out of scope");
1414 SA_SET_SYM_FSIZE (last_functionP
,
1415 (long) (S_GET_VALUE (symbolP
) -
1416 S_GET_VALUE (last_functionP
)));
1417 SA_SET_SYM_ENDNDX (last_functionP
, symbol_number
);
1418 last_functionP
= (symbolS
*) 0;
1422 else if (SF_GET_TAG (symbolP
))
1424 /* First descriptor of a structure must point to
1425 the first slot after the structure description. */
1426 last_tagP
= symbolP
;
1429 else if (S_GET_STORAGE_CLASS (symbolP
) == C_EOS
)
1431 /* +2 take in account the current symbol */
1432 SA_SET_SYM_ENDNDX (last_tagP
, symbol_number
+ 2);
1434 else if (S_GET_STORAGE_CLASS (symbolP
) == C_FILE
)
1436 if (S_GET_VALUE (symbolP
))
1438 S_SET_VALUE ((symbolS
*) S_GET_VALUE (symbolP
), symbol_number
);
1439 S_SET_VALUE (symbolP
, 0);
1440 } /* no one points at the first .file symbol */
1441 } /* if debug or tag or eos or file */
1443 /* We must put the external symbols apart. The loader
1444 does not bomb if we do not. But the references in
1445 the endndx field for a .bb symbol are not corrected
1446 if an external symbol is removed between .bb and .be.
1447 I.e in the following case :
1448 [20] .bb endndx = 22
1451 ld will move the symbol 21 to the end of the list but
1452 endndx will still be 22 instead of 21. */
1455 if (SF_GET_LOCAL (symbolP
))
1457 /* remove C_EFCN and LOCAL (L...) symbols */
1458 /* next pointer remains valid */
1459 symbol_remove (symbolP
, &symbol_rootP
, &symbol_lastP
);
1462 else if (!S_IS_DEFINED (symbolP
)
1463 && !S_IS_DEBUG (symbolP
)
1464 && !SF_GET_STATICS (symbolP
) &&
1465 S_GET_STORAGE_CLASS (symbolP
) == C_EXT
)
1466 { /* C_EXT && !SF_GET_FUNCTION(symbolP)) */
1467 /* if external, Remove from the list */
1468 symbolS
*hold
= symbol_previous (symbolP
);
1470 symbol_remove (symbolP
, &symbol_rootP
, &symbol_lastP
);
1471 symbol_clear_list_pointers (symbolP
);
1472 symbol_append (symbolP
, symbol_extern_lastP
, &symbol_externP
, &symbol_extern_lastP
);
1477 if (SF_GET_STRING (symbolP
))
1479 symbolP
->sy_name_offset
= string_byte_count
;
1480 string_byte_count
+= strlen (S_GET_NAME (symbolP
)) + 1;
1484 symbolP
->sy_name_offset
= 0;
1485 } /* fix "long" names */
1487 symbolP
->sy_number
= symbol_number
;
1488 symbol_number
+= 1 + S_GET_NUMBER_AUXILIARY (symbolP
);
1489 } /* if local symbol */
1490 } /* traverse the symbol list */
1491 return symbol_number
;
1497 DEFUN_VOID (glue_symbols
)
1499 unsigned int symbol_number
= 0;
1501 for (symbolP
= symbol_externP
; symbol_externP
;)
1503 symbolS
*tmp
= symbol_externP
;
1506 symbol_remove (tmp
, &symbol_externP
, &symbol_extern_lastP
);
1507 symbol_append (tmp
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
1510 if (SF_GET_STRING (tmp
))
1512 tmp
->sy_name_offset
= string_byte_count
;
1513 string_byte_count
+= strlen (S_GET_NAME (tmp
)) + 1;
1517 tmp
->sy_name_offset
= 0;
1518 } /* fix "long" names */
1520 tmp
->sy_number
= symbol_number
;
1521 symbol_number
+= 1 + S_GET_NUMBER_AUXILIARY (tmp
);
1522 } /* append the entire extern chain */
1523 return symbol_number
;
1528 DEFUN_VOID (tie_tags
)
1530 unsigned int symbol_number
= 0;
1533 for (symbolP
= symbol_rootP
; symbolP
; symbolP
=
1534 symbol_next (symbolP
))
1536 symbolP
->sy_number
= symbol_number
;
1540 if (SF_GET_TAGGED (symbolP
))
1544 ((symbolS
*) SA_GET_SYM_TAGNDX (symbolP
))->sy_number
);
1547 symbol_number
+= 1 + S_GET_NUMBER_AUXILIARY (symbolP
);
1549 return symbol_number
;
1554 DEFUN (crawl_symbols
, (headers
, abfd
),
1555 struct internal_filehdr
*headers AND
1560 unsigned int ptr
= 0;
1565 /* Initialize the stack used to keep track of the matching .bb .be */
1567 block_stack
= stack_init (512, sizeof (symbolS
*));
1568 /* JF deal with forward references first... */
1569 for (symbolP
= symbol_rootP
;
1571 symbolP
= symbol_next (symbolP
))
1574 if (symbolP
->sy_forward
)
1576 S_SET_VALUE (symbolP
, (S_GET_VALUE (symbolP
)
1577 + S_GET_VALUE (symbolP
->sy_forward
)
1578 + symbolP
->sy_forward
->sy_frag
->fr_address
));
1580 if (SF_GET_GET_SEGMENT (symbolP
))
1582 S_SET_SEGMENT (symbolP
, S_GET_SEGMENT (symbolP
->sy_forward
));
1583 } /* forward segment also */
1585 symbolP
->sy_forward
= 0;
1586 } /* if it has a forward reference */
1587 } /* walk the symbol chain */
1590 /* The symbol list should be ordered according to the following sequence
1593 * . debug entries for functions
1594 * . fake symbols for the sections, including.text .data and .bss
1596 * . undefined symbols
1597 * But this is not mandatory. The only important point is to put the
1598 * undefined symbols at the end of the list.
1601 if (symbol_rootP
== NULL
1602 || S_GET_STORAGE_CLASS (symbol_rootP
) != C_FILE
)
1604 c_dot_file_symbol ("fake");
1606 /* Is there a .file symbol ? If not insert one at the beginning. */
1609 * Build up static symbols for the sections, they are filled in later
1613 for (i
= SEG_E0
; i
< SEG_E9
; i
++)
1615 if (segment_info
[i
].scnhdr
.s_name
[0])
1617 segment_info
[i
].dot
=
1618 c_section_symbol (segment_info
[i
].scnhdr
.s_name
,
1625 /* Take all the externals out and put them into another chain */
1626 headers
->f_nsyms
= yank_symbols ();
1627 /* Take the externals and glue them onto the end.*/
1628 headers
->f_nsyms
+= glue_symbols ();
1630 headers
->f_nsyms
= tie_tags ();
1631 know (symbol_externP
== NULL
);
1632 know (symbol_extern_lastP
== NULL
);
1638 * Find strings by crawling along symbol table chain.
1642 DEFUN (w_strings
, (where
),
1647 /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
1648 md_number_to_chars (where
, string_byte_count
, sizeof (string_byte_count
));
1649 where
+= sizeof (string_byte_count
);
1650 for (symbolP
= symbol_rootP
;
1652 symbolP
= symbol_next (symbolP
))
1656 if (SF_GET_STRING (symbolP
))
1658 size
= strlen (S_GET_NAME (symbolP
)) + 1;
1660 memcpy (where
, S_GET_NAME (symbolP
), size
);
1673 DEFUN (do_linenos_for
, (abfd
, file_cursor
),
1675 unsigned long *file_cursor
)
1679 for (idx
= SEG_E0
; idx
< SEG_E9
; idx
++)
1681 segment_info_type
*s
= segment_info
+ idx
;
1684 if (s
->scnhdr
.s_nlnno
!= 0)
1686 struct lineno_list
*line_ptr
;
1688 struct external_lineno
*buffer
=
1689 (struct external_lineno
*) xmalloc (s
->scnhdr
.s_nlnno
* LINESZ
);
1691 struct external_lineno
*dst
= buffer
;
1693 /* Run through the table we've built and turn it into its external
1694 form, take this chance to remove duplicates */
1696 for (line_ptr
= s
->lineno_list_head
;
1697 line_ptr
!= (struct lineno_list
*) NULL
;
1698 line_ptr
= line_ptr
->next
)
1701 if (line_ptr
->line
.l_lnno
== 0)
1703 /* Turn a pointer to a symbol into the symbols' index */
1704 line_ptr
->line
.l_addr
.l_symndx
=
1705 ((symbolS
*) line_ptr
->line
.l_addr
.l_symndx
)->sy_number
;
1709 line_ptr
->line
.l_addr
.l_paddr
+= ((struct frag
*) (line_ptr
->frag
))->fr_address
;
1713 (void) bfd_coff_swap_lineno_out (abfd
, &(line_ptr
->line
), dst
);
1718 s
->scnhdr
.s_lnnoptr
= *file_cursor
;
1720 bfd_write (buffer
, 1, s
->scnhdr
.s_nlnno
* LINESZ
, abfd
);
1723 *file_cursor
+= s
->scnhdr
.s_nlnno
* LINESZ
;
1729 /* Now we run through the list of frag chains in a segment and
1730 make all the subsegment frags appear at the end of the
1731 list, as if the seg 0 was extra long */
1734 DEFUN_VOID (remove_subsegs
)
1738 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1740 frchainS
*head
= segment_info
[i
].frchainP
;
1742 fragS
*prev_frag
= &dummy
;
1744 while (head
&& head
->frch_seg
== i
)
1746 prev_frag
->fr_next
= head
->frch_root
;
1747 prev_frag
= head
->frch_last
;
1748 head
= head
->frch_next
;
1750 prev_frag
->fr_next
= 0;
1757 DEFUN_VOID (write_object_file
)
1760 struct frchain
*frchain_ptr
;
1762 struct internal_filehdr filehdr
;
1763 struct internal_aouthdr aouthdr
;
1764 unsigned long file_cursor
;
1767 abfd
= bfd_openw (out_file_name
, TARGET_FORMAT
);
1772 as_perror ("FATAL: Can't create %s", out_file_name
);
1775 bfd_set_format (abfd
, bfd_object
);
1776 bfd_set_arch_mach (abfd
, BFD_ARCH
, machine
);
1780 string_byte_count
= 4;
1782 for (frchain_ptr
= frchain_root
;
1783 frchain_ptr
!= (struct frchain
*) NULL
;
1784 frchain_ptr
= frchain_ptr
->frch_next
)
1786 /* Run through all the sub-segments and align them up. Also close any
1787 open frags. We tack a .fill onto the end of the frag chain so
1788 that any .align's size can be worked by looking at the next
1791 subseg_new (frchain_ptr
->frch_seg
, frchain_ptr
->frch_subseg
);
1792 #define SUB_SEGMENT_ALIGN 1
1793 frag_align (SUB_SEGMENT_ALIGN
, 0);
1794 frag_wane (frag_now
);
1795 frag_now
->fr_fix
= 0;
1796 know (frag_now
->fr_next
== NULL
);
1803 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1805 relax_segment (segment_info
[i
].frchainP
->frch_root
, i
);
1808 filehdr
.f_nscns
= 0;
1810 /* Find out how big the sections are, and set the addresses. */
1812 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1814 segment_info
[i
].scnhdr
.s_paddr
= addr
;
1815 segment_info
[i
].scnhdr
.s_vaddr
= addr
;
1817 if (segment_info
[i
].scnhdr
.s_name
[0])
1822 #ifndef ZERO_BASED_SEGMENTS
1823 /* See the comment at the previous ZERO_BASED_SEGMENTS check. */
1826 /* This is a special case, we leave the size alone, which
1827 will have been made up from all and any lcomms seen. */
1828 addr
+= segment_info
[i
].scnhdr
.s_size
;
1832 addr
+= size_section (abfd
, i
);
1839 /* Turn the gas native symbol table shape into a coff symbol table */
1840 crawl_symbols (&filehdr
, abfd
);
1841 #if !defined(TC_H8300) && !defined(TC_Z8K)
1842 for (i
= SEG_E0
; i
< SEG_UNKNOWN
; i
++)
1844 fixup_mdeps (segment_info
[i
].frchainP
->frch_root
);
1845 fixup_segment (segment_info
[i
].fix_root
, i
);
1849 file_cursor
= FILHSZ
+ SCNHSZ
* filehdr
.f_nscns
;
1851 bfd_seek (abfd
, file_cursor
, 0);
1854 do_relocs_for (abfd
, &file_cursor
);
1856 do_linenos_for (abfd
, &file_cursor
);
1859 /* Plant the data */
1861 fill_section (abfd
, &filehdr
, &file_cursor
);
1865 filehdr
.f_magic
= COFF_MAGIC
;
1866 filehdr
.f_timdat
= time (0);
1867 filehdr
.f_flags
= COFF_FLAGS
| coff_flags
;
1871 filehdr
.f_flags
|= F_LNNO
;
1875 filehdr
.f_flags
|= F_RELFLG
;
1886 unsigned int symtable_size
= filehdr
.f_nsyms
* SYMESZ
;
1887 char *buffer1
= malloc (symtable_size
+ string_byte_count
+ 4);
1888 char *ptr
= buffer1
;
1889 filehdr
.f_symptr
= bfd_tell (abfd
);
1890 w_symbols (abfd
, buffer1
, symbol_rootP
);
1891 w_strings (buffer1
+ symtable_size
);
1892 bfd_write (buffer1
, 1, symtable_size
+ string_byte_count
+ 4, abfd
);
1896 coff_header_append (abfd
, &filehdr
, &aouthdr
);
1898 if (bfd_close_all_done (abfd
) == false)
1899 as_fatal ("Can't close %s: %s", out_file_name
,
1900 bfd_errmsg (bfd_error
));
1905 DEFUN (change_to_section
, (name
, len
, exp
),
1907 unsigned int len AND
1911 /* Find out if we've already got a section of this name etc */
1912 for (i
= SEG_E0
; i
< SEG_E9
&& segment_info
[i
].scnhdr
.s_name
[0]; i
++)
1914 if (strncmp (segment_info
[i
].scnhdr
.s_name
, name
, len
) == 0)
1916 subseg_new (i
, exp
);
1921 /* No section, add one */
1922 strncpy (segment_info
[i
].scnhdr
.s_name
, name
, 8);
1923 subseg_new (i
, exp
);
1927 DEFUN_VOID (obj_coff_section
)
1929 /* Strip out the section name */
1931 char *section_name_end
;
1937 section_name
= input_line_pointer
;
1938 c
= get_symbol_end ();
1939 section_name_end
= input_line_pointer
;
1941 len
= section_name_end
- section_name
;
1942 input_line_pointer
++;
1946 exp
= get_absolute_expression ();
1948 else if (*input_line_pointer
== ',')
1951 input_line_pointer
++;
1952 exp
= get_absolute_expression ();
1959 change_to_section (section_name
, len
, exp
);
1960 *section_name_end
= c
;
1968 change_to_section (".text", 5, get_absolute_expression ());
1975 change_to_section (".data", 5, get_absolute_expression ());
1979 c_symbol_merge (debug
, normal
)
1983 S_SET_DATA_TYPE (normal
, S_GET_DATA_TYPE (debug
));
1984 S_SET_STORAGE_CLASS (normal
, S_GET_STORAGE_CLASS (debug
));
1986 if (S_GET_NUMBER_AUXILIARY (debug
) > S_GET_NUMBER_AUXILIARY (normal
))
1988 S_SET_NUMBER_AUXILIARY (normal
, S_GET_NUMBER_AUXILIARY (debug
));
1989 } /* take the most we have */
1991 if (S_GET_NUMBER_AUXILIARY (debug
) > 0)
1993 memcpy ((char *) &normal
->sy_symbol
.ost_auxent
[0], (char *) &debug
->sy_symbol
.ost_auxent
[0], S_GET_NUMBER_AUXILIARY (debug
) * AUXESZ
);
1994 } /* Move all the auxiliary information */
1996 /* Move the debug flags. */
1997 SF_SET_DEBUG_FIELD (normal
, SF_GET_DEBUG_FIELD (debug
));
1998 } /* c_symbol_merge() */
2001 DEFUN (c_line_new
, (symbol
, paddr
, line_number
, frag
),
2002 symbolS
* symbol AND
2004 unsigned short line_number AND
2007 struct lineno_list
*new_line
=
2008 (struct lineno_list
*) xmalloc (sizeof (struct lineno_list
));
2010 segment_info_type
*s
= segment_info
+ now_seg
;
2011 new_line
->line
.l_lnno
= line_number
;
2015 if (line_number
== 0)
2017 last_line_symbol
= symbol
;
2018 new_line
->line
.l_addr
.l_symndx
= (long) symbol
;
2022 new_line
->line
.l_addr
.l_paddr
= paddr
;
2025 new_line
->frag
= (char *) frag
;
2026 new_line
->next
= (struct lineno_list
*) NULL
;
2029 if (s
->lineno_list_head
== (struct lineno_list
*) NULL
)
2031 s
->lineno_list_head
= new_line
;
2035 s
->lineno_list_tail
->next
= new_line
;
2037 s
->lineno_list_tail
= new_line
;
2038 return LINESZ
* s
->scnhdr
.s_nlnno
++;
2042 c_dot_file_symbol (filename
)
2047 symbolP
= symbol_new (".file",
2050 &zero_address_frag
);
2052 S_SET_STORAGE_CLASS (symbolP
, C_FILE
);
2053 S_SET_NUMBER_AUXILIARY (symbolP
, 1);
2054 SA_SET_FILE_FNAME (symbolP
, filename
);
2060 listing_source_file (filename
);
2066 SF_SET_DEBUG (symbolP
);
2067 S_SET_VALUE (symbolP
, (long) previous_file_symbol
);
2069 previous_file_symbol
= symbolP
;
2071 /* Make sure that the symbol is first on the symbol chain */
2072 if (symbol_rootP
!= symbolP
)
2074 if (symbolP
== symbol_lastP
)
2076 symbol_lastP
= symbol_lastP
->sy_previous
;
2077 } /* if it was the last thing on the list */
2079 symbol_remove (symbolP
, &symbol_rootP
, &symbol_lastP
);
2080 symbol_insert (symbolP
, symbol_rootP
, &symbol_rootP
, &symbol_lastP
);
2081 symbol_rootP
= symbolP
;
2082 } /* if not first on the list */
2084 } /* c_dot_file_symbol() */
2087 * Build a 'section static' symbol.
2091 c_section_symbol (name
, idx
)
2097 symbolP
= symbol_new (name
, idx
,
2099 &zero_address_frag
);
2101 S_SET_STORAGE_CLASS (symbolP
, C_STAT
);
2102 S_SET_NUMBER_AUXILIARY (symbolP
, 1);
2104 SF_SET_STATICS (symbolP
);
2107 } /* c_section_symbol() */
2110 DEFUN (w_symbols
, (abfd
, where
, symbol_rootP
),
2113 symbolS
* symbol_rootP
)
2118 /* First fill in those values we have only just worked out */
2119 for (i
= SEG_E0
; i
< SEG_E9
; i
++)
2121 symbolP
= segment_info
[i
].dot
;
2125 SA_SET_SCN_SCNLEN (symbolP
, segment_info
[i
].scnhdr
.s_size
);
2126 SA_SET_SCN_NRELOC (symbolP
, segment_info
[i
].scnhdr
.s_nreloc
);
2127 SA_SET_SCN_NLINNO (symbolP
, segment_info
[i
].scnhdr
.s_nlnno
);
2133 * Emit all symbols left in the symbol chain.
2135 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
2137 /* Used to save the offset of the name. It is used to point
2138 to the string in memory but must be a file offset. */
2139 register char *temp
;
2141 tc_coff_symbol_emit_hook (symbolP
);
2143 temp
= S_GET_NAME (symbolP
);
2144 if (SF_GET_STRING (symbolP
))
2146 S_SET_OFFSET (symbolP
, symbolP
->sy_name_offset
);
2147 S_SET_ZEROES (symbolP
, 0);
2151 bzero (symbolP
->sy_symbol
.ost_entry
.n_name
, SYMNMLEN
);
2152 strncpy (symbolP
->sy_symbol
.ost_entry
.n_name
, temp
, SYMNMLEN
);
2154 where
= symbol_to_chars (abfd
, where
, symbolP
);
2155 S_SET_NAME (symbolP
, temp
);
2161 DEFUN_VOID (obj_coff_lcomm
)
2170 name
= input_line_pointer
;
2173 c
= get_symbol_end ();
2174 p
= input_line_pointer
;
2177 if (*input_line_pointer
!= ',')
2179 as_bad ("Expected comma after name");
2180 ignore_rest_of_line ();
2183 if (*input_line_pointer
== '\n')
2185 as_bad ("Missing size expression");
2188 input_line_pointer
++;
2189 if ((temp
= get_absolute_expression ()) < 0)
2191 as_warn ("lcomm length (%d.) <0! Ignored.", temp
);
2192 ignore_rest_of_line ();
2198 /* Allocate zero static local data in the .data section now
2199 instead of the bss section as a symbol with a value */
2201 segT oldseg
= now_seg
;
2202 int oldsubseg
= now_subseg
;
2204 subseg_new (SEG_DATA
, 10);
2207 record_alignment (SEG_DATA
, 4);
2208 x
= frag_var (rs_fill
, 1, 1, (relax_substateT
) 0, (symbolS
*) 0,
2212 subseg_new (oldseg
, oldsubseg
);
2214 demand_empty_rest_of_line ();
2218 DEFUN (fixup_mdeps
, (frags
),
2223 switch (frags
->fr_type
)
2227 frags
->fr_type
= rs_fill
;
2229 (frags
->fr_next
->fr_address
- frags
->fr_address
- frags
->fr_fix
);
2231 case rs_machine_dependent
:
2232 md_convert_frag (0, frags
);
2237 frags
= frags
->fr_next
;
2244 DEFUN (fixup_segment
, (fixP
, this_segment_type
),
2245 register fixS
* fixP AND
2246 segT this_segment_type
)
2248 register symbolS
*add_symbolP
;
2249 register symbolS
*sub_symbolP
;
2250 register long add_number
;
2252 register char *place
;
2253 register long where
;
2254 register char pcrel
;
2255 register fragS
*fragP
;
2256 register segT add_symbol_segment
= SEG_ABSOLUTE
;
2259 for (; fixP
; fixP
= fixP
->fx_next
)
2261 fragP
= fixP
->fx_frag
;
2263 where
= fixP
->fx_where
;
2264 place
= fragP
->fr_literal
+ where
;
2265 size
= fixP
->fx_size
;
2266 add_symbolP
= fixP
->fx_addsy
;
2268 if (fixP
->fx_callj
&& TC_S_IS_CALLNAME (add_symbolP
))
2270 /* Relocation should be done via the
2271 associated 'bal' entry point
2274 if (!TC_S_IS_BALNAME (tc_get_bal_of_call (add_symbolP
)))
2276 as_bad ("No 'bal' entry point for leafproc %s",
2277 S_GET_NAME (add_symbolP
));
2280 fixP
->fx_addsy
= add_symbolP
= tc_get_bal_of_call (add_symbolP
);
2281 } /* callj relocation */
2283 sub_symbolP
= fixP
->fx_subsy
;
2284 add_number
= fixP
->fx_offset
;
2285 pcrel
= fixP
->fx_pcrel
;
2289 add_symbol_segment
= S_GET_SEGMENT (add_symbolP
);
2290 } /* if there is an addend */
2297 if (S_GET_SEGMENT (sub_symbolP
) != SEG_ABSOLUTE
)
2299 as_bad ("Negative of non-absolute symbol %s", S_GET_NAME (sub_symbolP
));
2300 } /* not absolute */
2302 add_number
-= S_GET_VALUE (sub_symbolP
);
2305 /* if sub_symbol is in the same segment that add_symbol
2306 and add_symbol is either in DATA, TEXT, BSS or ABSOLUTE */
2308 else if ((S_GET_SEGMENT (sub_symbolP
) == add_symbol_segment
)
2309 && (SEG_NORMAL (add_symbol_segment
)
2310 || (add_symbol_segment
== SEG_ABSOLUTE
)))
2312 /* Difference of 2 symbols from same segment. */
2313 /* Can't make difference of 2 undefineds: 'value' means */
2314 /* something different for N_UNDF. */
2316 /* Makes no sense to use the difference of 2 arbitrary symbols
2317 * as the target of a call instruction.
2321 as_bad ("callj to difference of 2 symbols");
2323 #endif /* TC_I960 */
2324 add_number
+= S_GET_VALUE (add_symbolP
) -
2325 S_GET_VALUE (sub_symbolP
);
2328 fixP
->fx_addsy
= NULL
;
2332 /* Different segments in subtraction. */
2333 know (!(S_IS_EXTERNAL (sub_symbolP
) && (S_GET_SEGMENT (sub_symbolP
) == SEG_ABSOLUTE
)));
2335 if ((S_GET_SEGMENT (sub_symbolP
) == SEG_ABSOLUTE
))
2337 add_number
-= S_GET_VALUE (sub_symbolP
);
2341 as_bad ("Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %d.",
2342 segment_name (S_GET_SEGMENT (sub_symbolP
)),
2343 S_GET_NAME (sub_symbolP
), fragP
->fr_address
+ where
);
2346 } /* if sub_symbolP */
2350 if (add_symbol_segment
== this_segment_type
&& pcrel
)
2353 * This fixup was made when the symbol's segment was
2354 * SEG_UNKNOWN, but it is now in the local segment.
2355 * So we know how to do the address without relocation.
2358 /* reloc_callj() may replace a 'call' with a 'calls' or a 'bal',
2359 * in which cases it modifies *fixP as appropriate. In the case
2360 * of a 'calls', no further work is required, and *fixP has been
2361 * set up to make the rest of the code below a no-op.
2364 #endif /* TC_I960 */
2366 add_number
+= S_GET_VALUE (add_symbolP
);
2367 add_number
-= md_pcrel_from (fixP
);
2368 pcrel
= 0; /* Lie. Don't want further pcrel processing. */
2369 fixP
->fx_addsy
= NULL
; /* No relocations please. */
2373 switch (add_symbol_segment
)
2377 reloc_callj (fixP
); /* See comment about reloc_callj() above*/
2378 #endif /* TC_I960 */
2379 add_number
+= S_GET_VALUE (add_symbolP
);
2380 fixP
->fx_addsy
= NULL
;
2385 add_number
+= S_GET_VALUE (add_symbolP
) +
2386 segment_info
[S_GET_SEGMENT (add_symbolP
)].scnhdr
.s_paddr
;
2391 if ((int) fixP
->fx_bit_fixP
== 13)
2393 /* This is a COBR instruction. They have only a
2394 * 13-bit displacement and are only to be used
2395 * for local branches: flag as error, don't generate
2398 as_bad ("can't use COBR format with external label");
2399 fixP
->fx_addsy
= NULL
; /* No relocations please. */
2402 #endif /* TC_I960 */
2404 /* 386 COFF uses a peculiar format in
2405 which the value of a common symbol is
2406 stored in the .text segment (I've
2407 checked this on SVR3.2 and SCO 3.2.2)
2408 Ian Taylor <ian@cygnus.com>. */
2409 add_number
+= S_GET_VALUE (add_symbolP
);
2414 } /* switch on symbol seg */
2415 } /* if not in local seg */
2416 } /* if there was a + symbol */
2420 add_number
-= md_pcrel_from (fixP
);
2421 if (add_symbolP
== 0)
2423 fixP
->fx_addsy
= &abs_symbol
;
2424 } /* if there's an add_symbol */
2427 if (!fixP
->fx_bit_fixP
)
2430 (add_number
& ~0xFF) && ((add_number
& ~0xFF) != (-1 & ~0xFF))) ||
2432 (add_number
& ~0xFFFF) && ((add_number
& ~0xFFFF) != (-1 & ~0xFFFF))))
2434 as_bad ("Value of %d too large for field of %d bytes at 0x%x",
2435 add_number
, size
, fragP
->fr_address
+ where
);
2436 } /* generic error checking */
2437 #ifdef WARN_SIGNED_OVERFLOW_WORD
2438 /* Warn if a .word value is too large when treated as
2439 a signed number. We already know it is not too
2440 negative. This is to catch over-large switches
2441 generated by gcc on the 68k. */
2444 && add_number
> 0x7fff)
2445 as_bad ("Signed .word overflow; switch may be too large; %d at 0x%x",
2446 add_number
, fragP
->fr_address
+ where
);
2448 } /* not a bit fix */
2449 /* once this fix has been applied, we don't have to output anything
2450 nothing more need be done -*/
2451 md_apply_fix (fixP
, add_number
);
2453 } /* For each fixS in this segment. */
2456 } /* fixup_segment() */