1 /* coff object file format
2 Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994
3 Free Software Foundation, Inc.
5 This file is part of GAS.
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to
19 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
25 const char *s_get_name
PARAMS ((symbolS
* s
));
26 static symbolS
*tag_find_or_make
PARAMS ((char *name
));
27 static symbolS
*tag_find
PARAMS ((char *name
));
29 static void obj_coff_def
PARAMS ((int what
));
30 static void obj_coff_dim
PARAMS ((int));
31 static void obj_coff_endef
PARAMS ((int));
32 static void obj_coff_line
PARAMS ((int));
33 static void obj_coff_ln
PARAMS ((int));
34 static void obj_coff_scl
PARAMS ((int));
35 static void obj_coff_size
PARAMS ((int));
36 static void obj_coff_tag
PARAMS ((int));
37 static void obj_coff_type
PARAMS ((int));
38 static void obj_coff_val
PARAMS ((int));
39 static void tag_init
PARAMS ((void));
40 static void tag_insert
PARAMS ((const char *name
, symbolS
* symbolP
));
42 static void SA_SET_SYM_TAGNDX
PARAMS ((symbolS
*, symbolS
*));
44 static struct hash_control
*tag_hash
;
45 static symbolS
*def_symbol_in_progress
;
47 const pseudo_typeS obj_pseudo_table
[] =
50 {"def", obj_coff_def
, 0},
51 {"dim", obj_coff_dim
, 0},
52 {"endef", obj_coff_endef
, 0},
53 {"line", obj_coff_line
, 0},
54 {"ln", obj_coff_ln
, 0},
55 {"appline", obj_coff_ln
, 1},
56 {"scl", obj_coff_scl
, 0},
57 {"size", obj_coff_size
, 0},
58 {"tag", obj_coff_tag
, 0},
59 {"type", obj_coff_type
, 0},
60 {"val", obj_coff_val
, 0},
64 {"endef", s_ignore
, 0},
65 {"line", s_ignore
, 0},
68 {"size", s_ignore
, 0},
70 {"type", s_ignore
, 0},
72 #endif /* ignore debug */
74 { "section", obj_coff_section
, 0 },
76 {"ident", s_ignore
, 0}, /* we don't yet handle this. */
77 {"optim", s_ignore
, 0}, /* For sun386i cc (?) */
79 {"ABORT", s_abort
, 0},
81 {NULL
} /* end sentinel */
82 }; /* obj_pseudo_table */
90 #define GET_FILENAME_STRING(X) \
91 ((char*)(&((X)->sy_symbol.ost_auxent->x_file.x_n.x_offset))[1])
95 fetch_coff_debug_section ()
97 static segT debug_section
;
101 s
= bfd_make_debug_symbol (stdoutput
, (char *) 0, 0);
103 debug_section
= s
->section
;
105 return debug_section
;
109 SA_SET_SYM_ENDNDX (sym
, val
)
113 combined_entry_type
*entry
, *p
;
115 entry
= &coffsymbol (sym
->bsym
)->native
[1];
116 p
= coffsymbol (val
->bsym
)->native
;
117 entry
->u
.auxent
.x_sym
.x_fcnary
.x_fcn
.x_endndx
.p
= p
;
122 SA_SET_SYM_TAGNDX (sym
, val
)
126 combined_entry_type
*entry
, *p
;
128 entry
= &coffsymbol (sym
->bsym
)->native
[1];
129 p
= coffsymbol (val
->bsym
)->native
;
130 entry
->u
.auxent
.x_sym
.x_tagndx
.p
= p
;
135 S_GET_DATA_TYPE (sym
)
138 return coffsymbol (sym
->bsym
)->native
->u
.syment
.n_type
;
142 S_SET_DATA_TYPE (sym
, val
)
146 coffsymbol (sym
->bsym
)->native
->u
.syment
.n_type
= val
;
151 S_GET_STORAGE_CLASS (sym
)
154 return coffsymbol (sym
->bsym
)->native
->u
.syment
.n_sclass
;
158 S_SET_STORAGE_CLASS (sym
, val
)
162 coffsymbol (sym
->bsym
)->native
->u
.syment
.n_sclass
= val
;
166 /* Merge a debug symbol containing debug information into a normal symbol. */
169 c_symbol_merge (debug
, normal
)
173 S_SET_DATA_TYPE (normal
, S_GET_DATA_TYPE (debug
));
174 S_SET_STORAGE_CLASS (normal
, S_GET_STORAGE_CLASS (debug
));
176 if (S_GET_NUMBER_AUXILIARY (debug
) > S_GET_NUMBER_AUXILIARY (normal
))
177 /* take the most we have */
178 S_SET_NUMBER_AUXILIARY (normal
, S_GET_NUMBER_AUXILIARY (debug
));
180 if (S_GET_NUMBER_AUXILIARY (debug
) > 0)
182 /* Move all the auxiliary information. */
183 /* @@ How many fields do we want to preserve? Would it make more
184 sense to pick and choose those we want to copy? Should look
185 into this further.... [raeburn:19920512.2209EST] */
187 linenos
= coffsymbol (normal
->bsym
)->lineno
;
188 memcpy ((char *) &coffsymbol (normal
->bsym
)->native
,
189 (char *) &coffsymbol (debug
->bsym
)->native
,
190 S_GET_NUMBER_AUXILIARY(debug
) * AUXESZ
);
191 coffsymbol (normal
->bsym
)->lineno
= linenos
;
194 /* Move the debug flags. */
195 SF_SET_DEBUG_FIELD (normal
, SF_GET_DEBUG_FIELD (debug
));
198 static symbolS
*previous_file_symbol
;
200 c_dot_file_symbol (filename
)
205 symbolP
= symbol_new (filename
, &bfd_abs_section
, 0,
208 S_SET_STORAGE_CLASS (symbolP
, C_FILE
);
209 S_SET_NUMBER_AUXILIARY (symbolP
, 1);
211 symbolP
->bsym
->flags
= BSF_DEBUGGING
;
218 listing_source_file (filename
);
223 S_SET_VALUE (symbolP
, (long) previous_file_symbol
);
225 previous_file_symbol
= symbolP
;
227 /* Make sure that the symbol is first on the symbol chain */
228 if (symbol_rootP
!= symbolP
)
230 if (symbolP
== symbol_lastP
)
232 symbol_lastP
= symbol_lastP
->sy_previous
;
233 } /* if it was the last thing on the list */
235 symbol_remove (symbolP
, &symbol_rootP
, &symbol_lastP
);
236 symbol_insert (symbolP
, symbol_rootP
, &symbol_rootP
, &symbol_lastP
);
237 symbol_rootP
= symbolP
;
238 } /* if not first on the list */
242 * Build a 'section static' symbol.
246 c_section_symbol (name
, value
, length
, nreloc
, nlnno
)
250 unsigned short nreloc
;
251 unsigned short nlnno
;
255 symbolP
= symbol_new (name
,
264 S_SET_STORAGE_CLASS (symbolP
, C_STAT
);
265 S_SET_NUMBER_AUXILIARY (symbolP
, 1);
267 SA_SET_SCN_SCNLEN (symbolP
, length
);
268 SA_SET_SCN_NRELOC (symbolP
, nreloc
);
269 SA_SET_SCN_NLINNO (symbolP
, nlnno
);
271 SF_SET_STATICS (symbolP
);
273 return (char *) symbolP
;
276 /* Line number handling */
280 /* Symbol of last function, which we should hang line#s off of. */
281 static symbolS
*line_fsym
;
283 #define in_function() (line_fsym != 0)
284 #define clear_function() (line_fsym = 0)
285 #define set_function(F) (line_fsym = (F), coff_add_linesym (F))
289 obj_symbol_new_hook (symbolP
)
292 char underscore
= 0; /* Symbol has leading _ */
295 long sz
= (OBJ_COFF_MAX_AUXENTRIES
+ 1) * sizeof (combined_entry_type
);
296 char *s
= (char *) bfd_alloc_by_size_t (stdoutput
, sz
);
298 coffsymbol (symbolP
->bsym
)->native
= (combined_entry_type
*) s
;
300 S_SET_DATA_TYPE (symbolP
, T_NULL
);
301 S_SET_STORAGE_CLASS (symbolP
, 0);
302 S_SET_NUMBER_AUXILIARY (symbolP
, 0);
304 #ifdef STRIP_UNDERSCORE
305 /* Remove leading underscore at the beginning of the symbol.
306 This is to be compatible with the standard librairies. */
307 if (*S_GET_NAME (symbolP
) == '_')
310 S_SET_NAME (symbolP
, S_GET_NAME (symbolP
) + 1);
312 #endif /* STRIP_UNDERSCORE */
314 if (S_IS_STRING (symbolP
))
315 SF_SET_STRING (symbolP
);
316 if (!underscore
&& S_IS_LOCAL (symbolP
))
317 SF_SET_LOCAL (symbolP
);
323 stack_init (chunk_size
, element_size
)
324 unsigned long chunk_size
;
325 unsigned long element_size
;
329 st
= (stack
*) malloc (sizeof (stack
));
332 st
->data
= malloc (chunk_size
);
339 st
->size
= chunk_size
;
340 st
->chunk_size
= chunk_size
;
341 st
->element_size
= element_size
;
354 stack_push (st
, element
)
358 if (st
->pointer
+ st
->element_size
>= st
->size
)
360 st
->size
+= st
->chunk_size
;
361 if ((st
->data
= xrealloc (st
->data
, st
->size
)) == (char *) 0)
364 memcpy (st
->data
+ st
->pointer
, element
, st
->element_size
);
365 st
->pointer
+= st
->element_size
;
366 return st
->data
+ st
->pointer
;
373 if (st
->pointer
< st
->element_size
)
378 st
->pointer
-= st
->element_size
;
379 return st
->data
+ st
->pointer
;
386 return st
->data
+ st
->pointer
- st
->element_size
;
391 * Handle .ln directives.
394 static symbolS
*current_lineno_sym
;
395 static struct line_no
*line_nos
;
398 add_lineno (frag
, offset
, num
)
403 struct line_no
*new_line
= (struct line_no
*) bfd_alloc_by_size_t (stdoutput
,
404 sizeof (struct line_no
));
405 if (!current_lineno_sym
)
409 new_line
->next
= line_nos
;
410 new_line
->frag
= frag
;
411 new_line
->l
.line_number
= num
;
412 new_line
->l
.u
.offset
= offset
;
417 coff_add_linesym (sym
)
422 add_lineno (0, 0, 0);
423 coffsymbol (current_lineno_sym
->bsym
)->lineno
= (alent
*) line_nos
;
426 current_lineno_sym
= sym
;
430 obj_coff_ln (appline
)
435 if (! appline
&& def_symbol_in_progress
!= NULL
)
437 as_warn (".ln pseudo-op inside .def/.endef: ignored.");
438 demand_empty_rest_of_line ();
442 l
= get_absolute_expression ();
445 add_lineno (frag_now
, frag_now_fix (), l
);
455 l
+= coff_line_base
- 1;
456 listing_source_line (l
);
461 demand_empty_rest_of_line ();
467 * Handle .def directives.
469 * One might ask : why can't we symbol_new if the symbol does not
470 * already exist and fill it with debug information. Because of
471 * the C_EFCN special symbol. It would clobber the value of the
472 * function symbol before we have a chance to notice that it is
473 * a C_EFCN. And a second reason is that the code is more clear this
474 * way. (at least I think it is :-).
478 #define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';')
479 #define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \
480 *input_line_pointer == '\t') \
481 input_line_pointer++;
487 char name_end
; /* Char after the end of name */
488 char *symbol_name
; /* Name of the debug symbol */
489 char *symbol_name_copy
; /* Temporary copy of the name */
490 unsigned int symbol_name_length
;
492 if (def_symbol_in_progress
!= NULL
)
494 as_warn (".def pseudo-op used inside of .def/.endef: ignored.");
495 demand_empty_rest_of_line ();
497 } /* if not inside .def/.endef */
501 symbol_name
= input_line_pointer
;
502 #ifdef STRIP_UNDERSCORE
503 if (symbol_name
[0] == '_' && symbol_name
[1] != 0)
505 #endif /* STRIP_UNDERSCORE */
507 name_end
= get_symbol_end ();
508 symbol_name_length
= strlen (symbol_name
);
509 symbol_name_copy
= xmalloc (symbol_name_length
+ 1);
510 strcpy (symbol_name_copy
, symbol_name
);
512 /* Initialize the new symbol */
513 def_symbol_in_progress
= symbol_make (symbol_name_copy
);
514 def_symbol_in_progress
->sy_frag
= &zero_address_frag
;
515 S_SET_VALUE (def_symbol_in_progress
, 0);
517 if (S_IS_STRING (def_symbol_in_progress
))
518 SF_SET_STRING (def_symbol_in_progress
);
520 *input_line_pointer
= name_end
;
522 demand_empty_rest_of_line ();
525 unsigned int dim_index
;
528 obj_coff_endef (ignored
)
532 /* DIM BUG FIX sac@cygnus.com */
534 if (def_symbol_in_progress
== NULL
)
536 as_warn (".endef pseudo-op used outside of .def/.endef: ignored.");
537 demand_empty_rest_of_line ();
539 } /* if not inside .def/.endef */
541 /* Set the section number according to storage class. */
542 switch (S_GET_STORAGE_CLASS (def_symbol_in_progress
))
547 SF_SET_TAG (def_symbol_in_progress
);
548 /* intentional fallthrough */
551 SF_SET_DEBUG (def_symbol_in_progress
);
552 S_SET_SEGMENT (def_symbol_in_progress
, fetch_coff_debug_section ());
556 SF_SET_LOCAL (def_symbol_in_progress
); /* Do not emit this symbol. */
557 /* intentional fallthrough */
559 SF_SET_PROCESS (def_symbol_in_progress
); /* Will need processing before writing */
560 /* intentional fallthrough */
564 S_SET_SEGMENT (def_symbol_in_progress
, text_section
);
566 name
= bfd_asymbol_name (def_symbol_in_progress
->bsym
);
567 if (name
[1] == 'b' && name
[2] == 'f')
569 if (! in_function ())
570 as_warn ("`%s' symbol without preceding function", name
);
571 /* SA_SET_SYM_LNNO (def_symbol_in_progress, 12345);*/
572 /* Will need relocating */
573 SF_SET_PROCESS (def_symbol_in_progress
);
581 #endif /* C_AUTOARG */
591 SF_SET_DEBUG (def_symbol_in_progress
);
592 S_SET_SEGMENT (def_symbol_in_progress
, absolute_section
);
598 /* Valid but set somewhere else (s_comm, s_lcomm, colon) */
604 as_warn ("unexpected storage class %d",
605 S_GET_STORAGE_CLASS (def_symbol_in_progress
));
607 } /* switch on storage class */
609 /* Now that we have built a debug symbol, try to find if we should
610 merge with an existing symbol or not. If a symbol is C_EFCN or
611 SEG_ABSOLUTE or untagged SEG_DEBUG it never merges. */
613 /* Two cases for functions. Either debug followed by definition or
614 definition followed by debug. For definition first, we will
615 merge the debug symbol into the definition. For debug first, the
616 lineno entry MUST point to the definition function or else it
617 will point off into space when obj_crawl_symbol_chain() merges
618 the debug symbol into the real symbol. Therefor, let's presume
619 the debug symbol is a real function reference. */
621 /* FIXME-SOON If for some reason the definition label/symbol is
622 never seen, this will probably leave an undefined symbol at link
625 if (S_GET_STORAGE_CLASS (def_symbol_in_progress
) == C_EFCN
626 || (!strcmp (bfd_get_section_name (stdoutput
,
627 S_GET_SEGMENT (def_symbol_in_progress
)),
629 && !SF_GET_TAG (def_symbol_in_progress
))
630 || S_GET_SEGMENT (def_symbol_in_progress
) == absolute_section
631 || (symbolP
= symbol_find_base (S_GET_NAME (def_symbol_in_progress
), DO_NOT_STRIP
)) == NULL
)
633 if (def_symbol_in_progress
!= symbol_lastP
)
634 symbol_append (def_symbol_in_progress
, symbol_lastP
, &symbol_rootP
,
639 /* This symbol already exists, merge the newly created symbol
640 into the old one. This is not mandatory. The linker can
641 handle duplicate symbols correctly. But I guess that it save
642 a *lot* of space if the assembly file defines a lot of
645 /* The debug entry (def_symbol_in_progress) is merged into the
646 previous definition. */
648 c_symbol_merge (def_symbol_in_progress
, symbolP
);
649 /* FIXME-SOON Should *def_symbol_in_progress be free'd? xoxorich. */
650 def_symbol_in_progress
= symbolP
;
652 if (SF_GET_FUNCTION (def_symbol_in_progress
)
653 || SF_GET_TAG (def_symbol_in_progress
))
655 /* For functions, and tags, the symbol *must* be where the
656 debug symbol appears. Move the existing symbol to the
658 /* If it already is at the end of the symbol list, do nothing */
659 if (def_symbol_in_progress
!= symbol_lastP
)
661 symbol_remove (def_symbol_in_progress
, &symbol_rootP
, &symbol_lastP
);
662 symbol_append (def_symbol_in_progress
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
667 if (SF_GET_TAG (def_symbol_in_progress
)
668 && symbol_find_base (S_GET_NAME (def_symbol_in_progress
), DO_NOT_STRIP
) == NULL
)
670 tag_insert (S_GET_NAME (def_symbol_in_progress
), def_symbol_in_progress
);
673 if (SF_GET_FUNCTION (def_symbol_in_progress
))
675 know (sizeof (def_symbol_in_progress
) <= sizeof (long));
676 set_function (def_symbol_in_progress
);
677 SF_SET_PROCESS (def_symbol_in_progress
);
681 /* That is, if this is the first time we've seen the
683 symbol_table_insert (def_symbol_in_progress
);
684 } /* definition follows debug */
685 } /* Create the line number entry pointing to the function being defined */
687 def_symbol_in_progress
= NULL
;
688 demand_empty_rest_of_line ();
692 obj_coff_dim (ignored
)
697 if (def_symbol_in_progress
== NULL
)
699 as_warn (".dim pseudo-op used outside of .def/.endef: ignored.");
700 demand_empty_rest_of_line ();
702 } /* if not inside .def/.endef */
704 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress
, 1);
706 for (dim_index
= 0; dim_index
< DIMNUM
; dim_index
++)
709 SA_SET_SYM_DIMEN (def_symbol_in_progress
, dim_index
,
710 get_absolute_expression ());
712 switch (*input_line_pointer
)
715 input_line_pointer
++;
719 as_warn ("badly formed .dim directive ignored");
720 /* intentional fallthrough */
728 demand_empty_rest_of_line ();
732 obj_coff_line (ignored
)
737 if (def_symbol_in_progress
== NULL
)
739 /* Probably stabs-style line? */
744 this_base
= get_absolute_expression ();
745 if (this_base
> coff_line_base
)
746 coff_line_base
= this_base
;
748 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress
, 1);
749 SA_SET_SYM_LNNO (def_symbol_in_progress
, coff_line_base
);
751 demand_empty_rest_of_line ();
755 obj_coff_size (ignored
)
758 if (def_symbol_in_progress
== NULL
)
760 as_warn (".size pseudo-op used outside of .def/.endef ignored.");
761 demand_empty_rest_of_line ();
763 } /* if not inside .def/.endef */
765 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress
, 1);
766 SA_SET_SYM_SIZE (def_symbol_in_progress
, get_absolute_expression ());
767 demand_empty_rest_of_line ();
771 obj_coff_scl (ignored
)
774 if (def_symbol_in_progress
== NULL
)
776 as_warn (".scl pseudo-op used outside of .def/.endef ignored.");
777 demand_empty_rest_of_line ();
779 } /* if not inside .def/.endef */
781 S_SET_STORAGE_CLASS (def_symbol_in_progress
, get_absolute_expression ());
782 demand_empty_rest_of_line ();
786 obj_coff_tag (ignored
)
792 if (def_symbol_in_progress
== NULL
)
794 as_warn (".tag pseudo-op used outside of .def/.endef ignored.");
795 demand_empty_rest_of_line ();
799 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress
, 1);
800 symbol_name
= input_line_pointer
;
801 name_end
= get_symbol_end ();
803 /* Assume that the symbol referred to by .tag is always defined.
804 This was a bad assumption. I've added find_or_make. xoxorich. */
805 SA_SET_SYM_TAGNDX (def_symbol_in_progress
,
806 tag_find_or_make (symbol_name
));
807 if (SA_GET_SYM_TAGNDX (def_symbol_in_progress
) == 0L)
809 as_warn ("tag not found for .tag %s", symbol_name
);
812 SF_SET_TAGGED (def_symbol_in_progress
);
813 *input_line_pointer
= name_end
;
815 demand_empty_rest_of_line ();
819 obj_coff_type (ignored
)
822 if (def_symbol_in_progress
== NULL
)
824 as_warn (".type pseudo-op used outside of .def/.endef ignored.");
825 demand_empty_rest_of_line ();
827 } /* if not inside .def/.endef */
829 S_SET_DATA_TYPE (def_symbol_in_progress
, get_absolute_expression ());
831 if (ISFCN (S_GET_DATA_TYPE (def_symbol_in_progress
)) &&
832 S_GET_STORAGE_CLASS (def_symbol_in_progress
) != C_TPDEF
)
834 SF_SET_FUNCTION (def_symbol_in_progress
);
835 } /* is a function */
837 demand_empty_rest_of_line ();
841 obj_coff_val (ignored
)
844 if (def_symbol_in_progress
== NULL
)
846 as_warn (".val pseudo-op used outside of .def/.endef ignored.");
847 demand_empty_rest_of_line ();
849 } /* if not inside .def/.endef */
851 if (is_name_beginner (*input_line_pointer
))
853 char *symbol_name
= input_line_pointer
;
854 char name_end
= get_symbol_end ();
856 if (!strcmp (symbol_name
, "."))
858 def_symbol_in_progress
->sy_frag
= frag_now
;
859 S_SET_VALUE (def_symbol_in_progress
, obstack_next_free (&frags
) - frag_now
->fr_literal
);
860 /* If the .val is != from the .def (e.g. statics) */
862 else if (strcmp (S_GET_NAME (def_symbol_in_progress
), symbol_name
))
864 def_symbol_in_progress
->sy_value
.X_op
= O_symbol
;
865 def_symbol_in_progress
->sy_value
.X_add_symbol
=
866 symbol_find_or_make (symbol_name
);
867 def_symbol_in_progress
->sy_value
.X_op_symbol
= NULL
;
868 def_symbol_in_progress
->sy_value
.X_add_number
= 0;
870 /* If the segment is undefined when the forward reference is
871 resolved, then copy the segment id from the forward
873 SF_SET_GET_SEGMENT (def_symbol_in_progress
);
875 /* Otherwise, it is the name of a non debug symbol and its value will be calculated later. */
876 *input_line_pointer
= name_end
;
880 S_SET_VALUE (def_symbol_in_progress
, get_absolute_expression ());
881 } /* if symbol based */
883 demand_empty_rest_of_line ();
887 * Maintain a list of the tagnames of the structres.
893 tag_hash
= hash_new ();
897 tag_insert (name
, symbolP
)
901 const char *error_string
;
903 if ((error_string
= hash_jam (tag_hash
, name
, (char *) symbolP
)))
905 as_fatal ("Inserting \"%s\" into structure table failed: %s",
911 tag_find_or_make (name
)
916 if ((symbolP
= tag_find (name
)) == NULL
)
918 symbolP
= symbol_new (name
, undefined_section
,
919 0, &zero_address_frag
);
921 tag_insert (S_GET_NAME (symbolP
), symbolP
);
922 symbol_table_insert (symbolP
);
932 #ifdef STRIP_UNDERSCORE
935 #endif /* STRIP_UNDERSCORE */
936 return (symbolS
*) hash_find (tag_hash
, name
);
940 obj_read_begin_hook ()
942 /* These had better be the same. Usually 18 bytes. */
944 know (sizeof (SYMENT
) == sizeof (AUXENT
));
945 know (SYMESZ
== AUXESZ
);
951 symbolS
*coff_last_function
;
954 coff_frob_symbol (symp
, punt
)
958 static symbolS
*last_tagP
;
959 static stack
*block_stack
;
960 static symbolS
*set_end
;
962 if (symp
== &abs_symbol
)
968 if (current_lineno_sym
)
969 coff_add_linesym ((symbolS
*) 0);
972 block_stack
= stack_init (512, sizeof (symbolS
*));
974 if (!S_IS_DEFINED (symp
) && S_GET_STORAGE_CLASS (symp
) != C_STAT
)
975 S_SET_STORAGE_CLASS (symp
, C_EXT
);
977 if (!SF_GET_DEBUG (symp
))
980 if (!SF_GET_LOCAL (symp
)
981 && (real
= symbol_find_base (S_GET_NAME (symp
), DO_NOT_STRIP
))
984 c_symbol_merge (symp
, real
);
987 if (!S_IS_DEFINED (symp
) && !SF_GET_LOCAL (symp
))
989 assert (S_GET_VALUE (symp
) == 0);
990 S_SET_EXTERNAL (symp
);
992 else if (S_GET_STORAGE_CLASS (symp
) == C_NULL
)
994 if (S_GET_SEGMENT (symp
) == text_section
)
995 S_SET_STORAGE_CLASS (symp
, C_LABEL
);
997 S_SET_STORAGE_CLASS (symp
, C_STAT
);
999 if (SF_GET_PROCESS (symp
))
1001 if (S_GET_STORAGE_CLASS (symp
) == C_BLOCK
)
1003 if (!strcmp (S_GET_NAME (symp
), ".bb"))
1004 stack_push (block_stack
, (char *) &symp
);
1008 begin
= *(symbolS
**) stack_pop (block_stack
);
1010 as_warn ("mismatched .eb");
1015 if (coff_last_function
== 0 && SF_GET_FUNCTION (symp
))
1017 union internal_auxent
*auxp
;
1018 coff_last_function
= symp
;
1019 if (S_GET_NUMBER_AUXILIARY (symp
) < 1)
1020 S_SET_NUMBER_AUXILIARY (symp
, 1);
1021 auxp
= &coffsymbol (symp
->bsym
)->native
[1].u
.auxent
;
1022 memset (auxp
->x_sym
.x_fcnary
.x_ary
.x_dimen
, 0,
1023 sizeof (auxp
->x_sym
.x_fcnary
.x_ary
.x_dimen
));
1025 if (S_GET_STORAGE_CLASS (symp
) == C_EFCN
)
1027 if (coff_last_function
== 0)
1028 as_fatal ("C_EFCN symbol out of scope");
1029 SA_SET_SYM_FSIZE (coff_last_function
,
1030 (long) (S_GET_VALUE (symp
)
1031 - S_GET_VALUE (coff_last_function
)));
1032 set_end
= coff_last_function
;
1033 coff_last_function
= 0;
1036 else if (SF_GET_TAG (symp
))
1038 else if (S_GET_STORAGE_CLASS (symp
) == C_EOS
)
1039 set_end
= last_tagP
;
1040 else if (S_GET_STORAGE_CLASS (symp
) == C_FILE
)
1042 if (S_GET_VALUE (symp
))
1044 S_SET_VALUE ((symbolS
*) S_GET_VALUE (symp
), 0xdeadbeef);
1045 S_SET_VALUE (symp
, 0);
1048 if (S_IS_EXTERNAL (symp
))
1049 S_SET_STORAGE_CLASS (symp
, C_EXT
);
1050 else if (SF_GET_LOCAL (symp
))
1055 if (set_end
!= (symbolS
*) NULL
1058 SA_SET_SYM_ENDNDX (set_end
, symp
);
1062 if (coffsymbol (symp
->bsym
)->lineno
)
1065 struct line_no
*lptr
;
1068 lptr
= (struct line_no
*) coffsymbol (symp
->bsym
)->lineno
;
1069 for (i
= 0; lptr
; lptr
= lptr
->next
)
1072 lptr
= (struct line_no
*) coffsymbol (symp
->bsym
)->lineno
;
1073 l
= (alent
*) bfd_alloc_by_size_t (stdoutput
, n
* sizeof (alent
));
1074 coffsymbol (symp
->bsym
)->lineno
= l
;
1075 for (i
= n
- 1; i
> 0; i
--)
1078 lptr
->l
.u
.offset
+= lptr
->frag
->fr_address
;
1086 * implement the .section pseudo op:
1087 * .section name {, "flags"}
1089 * | +--- optional flags: 'b' for bss
1091 * +-- section name 'l' for lib
1095 * 'd' (apparently m88k for data)
1097 * But if the argument is not a quoted string, treat it as a
1098 * subsegment number.
1102 obj_coff_section (ignore
)
1105 /* Strip out the section name */
1113 section_name
= input_line_pointer
;
1114 c
= get_symbol_end ();
1116 name
= xmalloc (input_line_pointer
- section_name
+ 1);
1117 strcpy (name
, section_name
);
1119 *input_line_pointer
= c
;
1124 flags
= SEC_NO_FLAGS
;
1126 if (*input_line_pointer
== ',')
1128 ++input_line_pointer
;
1130 if (*input_line_pointer
!= '"')
1131 exp
= get_absolute_expression ();
1134 ++input_line_pointer
;
1135 while (*input_line_pointer
!= '"'
1136 && ! is_end_of_line
[(unsigned char) *input_line_pointer
])
1138 switch (*input_line_pointer
)
1140 case 'b': flags
|= SEC_ALLOC
; flags
&=~ SEC_LOAD
; break;
1141 case 'n': flags
&=~ SEC_LOAD
; break;
1143 case 'w': flags
&=~ SEC_READONLY
; break;
1144 case 'x': flags
|= SEC_CODE
; break;
1146 case 'i': /* STYP_INFO */
1147 case 'l': /* STYP_LIB */
1148 case 'o': /* STYP_OVER */
1149 as_warn ("unsupported section attribute '%c'",
1150 *input_line_pointer
);
1154 as_warn("unknown section attribute '%c'",
1155 *input_line_pointer
);
1158 ++input_line_pointer
;
1160 if (*input_line_pointer
== '"')
1161 ++input_line_pointer
;
1165 sec
= subseg_new (name
, (subsegT
) exp
);
1167 if (flags
!= SEC_NO_FLAGS
)
1169 if (! bfd_set_section_flags (stdoutput
, sec
, flags
))
1170 as_warn ("error setting flags for \"%s\": %s",
1171 bfd_section_name (stdoutput
, sec
),
1172 bfd_errmsg (bfd_get_error ()));
1179 if (symbol_rootP
== NULL
1180 || S_GET_STORAGE_CLASS (symbol_rootP
) != C_FILE
)
1182 assert (previous_file_symbol
== 0);
1183 c_dot_file_symbol ("fake");
1188 coff_frob_section (strsec
)
1194 bfd_vma size
, n_entries
;
1196 /* @@ these should be in a "stabs.h" file, or maybe as.h */
1197 #ifndef STAB_SECTION_NAME
1198 #define STAB_SECTION_NAME ".stab"
1200 #ifndef STAB_STRING_SECTION_NAME
1201 #define STAB_STRING_SECTION_NAME ".stabstr"
1203 if (strcmp (STAB_STRING_SECTION_NAME
, strsec
->name
))
1206 sec
= subseg_get (STAB_SECTION_NAME
, 0);
1207 /* size is already rounded up, since other section will be listed first */
1208 size
= bfd_get_section_size_before_reloc (strsec
);
1210 n_entries
= bfd_get_section_size_before_reloc (sec
) / 12 - 1;
1212 /* Find first non-empty frag. It should be large enough. */
1213 fragp
= seg_info (sec
)->frchainP
->frch_root
;
1214 while (fragp
&& fragp
->fr_fix
== 0)
1215 fragp
= fragp
->fr_next
;
1216 assert (fragp
!= 0 && fragp
->fr_fix
>= 12);
1218 /* Store the values. */
1219 p
= fragp
->fr_literal
;
1220 bfd_h_put_16 (stdoutput
, n_entries
, (bfd_byte
*) p
+ 6);
1221 bfd_h_put_32 (stdoutput
, size
, (bfd_byte
*) p
+ 8);
1225 obj_coff_init_stab_section (seg
)
1231 unsigned int stroff
;
1233 /* Make space for this first symbol. */
1237 as_where (&file
, (unsigned int *) NULL
);
1238 stabstr_name
= (char *) alloca (strlen (seg
->name
) + 4);
1239 strcpy (stabstr_name
, seg
->name
);
1240 strcat (stabstr_name
, "str");
1241 stroff
= get_stab_string_offset (file
, stabstr_name
);
1243 md_number_to_chars (p
, stroff
, 4);
1252 return ((s
== NULL
) ? "(NULL)" : S_GET_NAME (s
));
1260 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
1262 printf("0x%lx: \"%s\" type = %ld, class = %d, segment = %d\n",
1263 (unsigned long) symbolP
,
1264 S_GET_NAME(symbolP
),
1265 (long) S_GET_DATA_TYPE(symbolP
),
1266 S_GET_STORAGE_CLASS(symbolP
),
1267 (int) S_GET_SEGMENT(symbolP
));
1273 /* end of obj-coff.c */