1 /* coff object file format
2 Copyright (C) 1989-2020 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 3, 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 the Free
18 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
21 #define OBJ_HEADER "obj-coff.h"
24 #include "safe-ctype.h"
32 #include "coff/xcoff.h"
35 #define streq(a,b) (strcmp ((a), (b)) == 0)
36 #define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
38 /* I think this is probably always correct. */
39 #ifndef KEEP_RELOC_INFO
40 #define KEEP_RELOC_INFO
43 /* obj_coff_section will use this macro to set a new section's
44 attributes when a directive has no valid flags or the "w" flag is
45 used. This default should be appropriate for most. */
46 #ifndef TC_COFF_SECTION_DEFAULT_ATTRIBUTES
47 #define TC_COFF_SECTION_DEFAULT_ATTRIBUTES (SEC_LOAD | SEC_DATA)
50 /* This is used to hold the symbol built by a sequence of pseudo-ops
51 from .def and .endef. */
52 static symbolS
*def_symbol_in_progress
;
54 /* PE weak alternate symbols begin with this string. */
55 static const char weak_altprefix
[] = ".weak.";
58 #include "obj-coff-seh.c"
62 unsigned long chunk_size
;
63 unsigned long element_size
;
66 unsigned long pointer
;
74 stack_init (unsigned long chunk_size
,
75 unsigned long element_size
)
80 st
->data
= XNEWVEC (char, chunk_size
);
87 st
->size
= chunk_size
;
88 st
->chunk_size
= chunk_size
;
89 st
->element_size
= element_size
;
94 stack_push (stack
*st
, char *element
)
96 if (st
->pointer
+ st
->element_size
>= st
->size
)
98 st
->size
+= st
->chunk_size
;
99 st
->data
= XRESIZEVEC (char, st
->data
, st
->size
);
101 memcpy (st
->data
+ st
->pointer
, element
, st
->element_size
);
102 st
->pointer
+= st
->element_size
;
103 return st
->data
+ st
->pointer
;
107 stack_pop (stack
*st
)
109 if (st
->pointer
< st
->element_size
)
114 st
->pointer
-= st
->element_size
;
115 return st
->data
+ st
->pointer
;
118 /* Maintain a list of the tagnames of the structures. */
120 static struct hash_control
*tag_hash
;
125 tag_hash
= hash_new ();
129 tag_insert (const char *name
, symbolS
*symbolP
)
131 const char *error_string
;
133 if ((error_string
= hash_jam (tag_hash
, name
, (char *) symbolP
)))
134 as_fatal (_("Inserting \"%s\" into structure table failed: %s"),
139 tag_find (char *name
)
141 return (symbolS
*) hash_find (tag_hash
, name
);
145 tag_find_or_make (char *name
)
149 if ((symbolP
= tag_find (name
)) == NULL
)
151 symbolP
= symbol_new (name
, undefined_section
,
152 0, &zero_address_frag
);
154 tag_insert (S_GET_NAME (symbolP
), symbolP
);
155 symbol_table_insert (symbolP
);
161 /* We accept the .bss directive to set the section for backward
162 compatibility with earlier versions of gas. */
165 obj_coff_bss (int ignore ATTRIBUTE_UNUSED
)
167 if (*input_line_pointer
== '\n')
168 subseg_new (".bss", get_absolute_expression ());
174 /* Called from read.c:s_comm after we've parsed .comm symbol, size.
175 Parse a possible alignment value. */
178 obj_coff_common_parse (int ignore ATTRIBUTE_UNUSED
, symbolS
*symbolP
, addressT size
)
182 if (*input_line_pointer
== ',')
184 align
= parse_align (0);
185 if (align
== (addressT
) -1)
189 S_SET_VALUE (symbolP
, size
);
190 S_SET_EXTERNAL (symbolP
);
191 S_SET_SEGMENT (symbolP
, bfd_com_section_ptr
);
193 symbol_get_bfdsym (symbolP
)->flags
|= BSF_OBJECT
;
195 /* There is no S_SET_ALIGN (symbolP, align) in COFF/PE.
196 Instead we must add a note to the .drectve section. */
199 segT current_seg
= now_seg
;
200 subsegT current_subseg
= now_subseg
;
203 size_t pfxlen
, numlen
;
207 sec
= subseg_new (".drectve", 0);
208 oldflags
= bfd_section_flags (sec
);
209 if (oldflags
== SEC_NO_FLAGS
)
211 if (!bfd_set_section_flags (sec
, TC_COFF_SECTION_DEFAULT_ATTRIBUTES
))
212 as_warn (_("error setting flags for \"%s\": %s"),
213 bfd_section_name (sec
),
214 bfd_errmsg (bfd_get_error ()));
217 /* Emit a string. Note no NUL-termination. */
218 pfxlen
= strlen (" -aligncomm:") + 2 + strlen (S_GET_NAME (symbolP
)) + 1;
219 numlen
= snprintf (numbuff
, sizeof (numbuff
), "%d", (int) align
);
220 frag
= frag_more (pfxlen
+ numlen
);
221 (void) sprintf (frag
, " -aligncomm:\"%s\",", S_GET_NAME (symbolP
));
222 memcpy (frag
+ pfxlen
, numbuff
, numlen
);
223 /* Restore original subseg. */
224 subseg_set (current_seg
, current_subseg
);
231 obj_coff_comm (int ignore ATTRIBUTE_UNUSED
)
233 s_comm_internal (ignore
, obj_coff_common_parse
);
239 fetch_coff_debug_section (void)
241 static segT debug_section
;
247 s
= bfd_make_debug_symbol (stdoutput
, NULL
, 0);
249 debug_section
= s
->section
;
251 return debug_section
;
255 SA_SET_SYM_ENDNDX (symbolS
*sym
, symbolS
*val
)
257 combined_entry_type
*entry
, *p
;
259 entry
= &coffsymbol (symbol_get_bfdsym (sym
))->native
[1];
260 p
= coffsymbol (symbol_get_bfdsym (val
))->native
;
261 entry
->u
.auxent
.x_sym
.x_fcnary
.x_fcn
.x_endndx
.p
= p
;
266 SA_SET_SYM_TAGNDX (symbolS
*sym
, symbolS
*val
)
268 combined_entry_type
*entry
, *p
;
270 entry
= &coffsymbol (symbol_get_bfdsym (sym
))->native
[1];
271 p
= coffsymbol (symbol_get_bfdsym (val
))->native
;
272 entry
->u
.auxent
.x_sym
.x_tagndx
.p
= p
;
277 S_GET_DATA_TYPE (symbolS
*sym
)
279 return coffsymbol (symbol_get_bfdsym (sym
))->native
->u
.syment
.n_type
;
283 S_SET_DATA_TYPE (symbolS
*sym
, int val
)
285 coffsymbol (symbol_get_bfdsym (sym
))->native
->u
.syment
.n_type
= val
;
290 S_GET_STORAGE_CLASS (symbolS
*sym
)
292 return coffsymbol (symbol_get_bfdsym (sym
))->native
->u
.syment
.n_sclass
;
296 S_SET_STORAGE_CLASS (symbolS
*sym
, int val
)
298 coffsymbol (symbol_get_bfdsym (sym
))->native
->u
.syment
.n_sclass
= val
;
302 /* Merge a debug symbol containing debug information into a normal symbol. */
305 c_symbol_merge (symbolS
*debug
, symbolS
*normal
)
307 S_SET_DATA_TYPE (normal
, S_GET_DATA_TYPE (debug
));
308 S_SET_STORAGE_CLASS (normal
, S_GET_STORAGE_CLASS (debug
));
310 if (S_GET_NUMBER_AUXILIARY (debug
) > S_GET_NUMBER_AUXILIARY (normal
))
311 /* Take the most we have. */
312 S_SET_NUMBER_AUXILIARY (normal
, S_GET_NUMBER_AUXILIARY (debug
));
314 if (S_GET_NUMBER_AUXILIARY (debug
) > 0)
315 /* Move all the auxiliary information. */
316 memcpy (SYM_AUXINFO (normal
), SYM_AUXINFO (debug
),
317 (S_GET_NUMBER_AUXILIARY (debug
)
318 * sizeof (*SYM_AUXINFO (debug
))));
320 /* Move the debug flags. */
321 SF_SET_DEBUG_FIELD (normal
, SF_GET_DEBUG_FIELD (debug
));
325 c_dot_file_symbol (const char *filename
, int appfile ATTRIBUTE_UNUSED
)
329 /* BFD converts filename to a .file symbol with an aux entry. It
330 also handles chaining. */
331 symbolP
= symbol_new (filename
, bfd_abs_section_ptr
, 0, &zero_address_frag
);
333 S_SET_STORAGE_CLASS (symbolP
, C_FILE
);
334 S_SET_NUMBER_AUXILIARY (symbolP
, 1);
336 symbol_get_bfdsym (symbolP
)->flags
= BSF_DEBUGGING
;
343 listing_source_file (filename
);
347 /* Make sure that the symbol is first on the symbol chain. */
348 if (symbol_rootP
!= symbolP
)
350 symbol_remove (symbolP
, &symbol_rootP
, &symbol_lastP
);
351 symbol_insert (symbolP
, symbol_rootP
, &symbol_rootP
, &symbol_lastP
);
355 /* Line number handling. */
359 struct line_no
*next
;
366 /* Symbol of last function, which we should hang line#s off of. */
367 static symbolS
*line_fsym
;
369 #define in_function() (line_fsym != 0)
370 #define clear_function() (line_fsym = 0)
371 #define set_function(F) (line_fsym = (F), coff_add_linesym (F))
375 coff_obj_symbol_new_hook (symbolS
*symbolP
)
377 long sz
= (OBJ_COFF_MAX_AUXENTRIES
+ 1) * sizeof (combined_entry_type
);
378 char * s
= XNEWVEC (char, sz
);
381 coffsymbol (symbol_get_bfdsym (symbolP
))->native
= (combined_entry_type
*) s
;
382 coffsymbol (symbol_get_bfdsym (symbolP
))->native
->is_sym
= TRUE
;
384 S_SET_DATA_TYPE (symbolP
, T_NULL
);
385 S_SET_STORAGE_CLASS (symbolP
, 0);
386 S_SET_NUMBER_AUXILIARY (symbolP
, 0);
388 if (S_IS_STRING (symbolP
))
389 SF_SET_STRING (symbolP
);
391 if (S_IS_LOCAL (symbolP
))
392 SF_SET_LOCAL (symbolP
);
396 coff_obj_symbol_clone_hook (symbolS
*newsymP
, symbolS
*orgsymP
)
398 long elts
= OBJ_COFF_MAX_AUXENTRIES
+ 1;
399 combined_entry_type
* s
= XNEWVEC (combined_entry_type
, elts
);
401 memcpy (s
, coffsymbol (symbol_get_bfdsym (orgsymP
))->native
,
402 elts
* sizeof (combined_entry_type
));
403 coffsymbol (symbol_get_bfdsym (newsymP
))->native
= s
;
405 SF_SET (newsymP
, SF_GET (orgsymP
));
409 /* Handle .ln directives. */
411 static symbolS
*current_lineno_sym
;
412 static struct line_no
*line_nos
;
413 /* FIXME: Blindly assume all .ln directives will be in the .text section. */
417 add_lineno (fragS
* frag
, addressT offset
, int num
)
419 struct line_no
* new_line
= XNEW (struct line_no
);
421 if (!current_lineno_sym
)
425 /* The native aix assembler accepts negative line number. */
429 /* Zero is used as an end marker in the file. */
430 as_warn (_("Line numbers must be positive integers\n"));
433 #endif /* OBJ_XCOFF */
434 new_line
->next
= line_nos
;
435 new_line
->frag
= frag
;
436 new_line
->l
.line_number
= num
;
437 new_line
->l
.u
.offset
= offset
;
443 coff_add_linesym (symbolS
*sym
)
447 coffsymbol (symbol_get_bfdsym (current_lineno_sym
))->lineno
=
452 current_lineno_sym
= sym
;
456 obj_coff_ln (int appline
)
460 if (! appline
&& def_symbol_in_progress
!= NULL
)
462 as_warn (_(".ln pseudo-op inside .def/.endef: ignored."));
463 demand_empty_rest_of_line ();
467 l
= get_absolute_expression ();
469 /* If there is no lineno symbol, treat a .ln
470 directive as if it were a .appline directive. */
471 if (appline
|| current_lineno_sym
== NULL
)
472 new_logical_line ((char *) NULL
, l
- 1);
474 add_lineno (frag_now
, frag_now_fix (), l
);
483 l
+= coff_line_base
- 1;
484 listing_source_line (l
);
489 demand_empty_rest_of_line ();
492 /* .loc is essentially the same as .ln; parse it for assembler
496 obj_coff_loc (int ignore ATTRIBUTE_UNUSED
)
500 /* FIXME: Why do we need this check? We need it for ECOFF, but why
501 do we need it for COFF? */
502 if (now_seg
!= text_section
)
504 as_warn (_(".loc outside of .text"));
505 demand_empty_rest_of_line ();
509 if (def_symbol_in_progress
!= NULL
)
511 as_warn (_(".loc pseudo-op inside .def/.endef: ignored."));
512 demand_empty_rest_of_line ();
516 /* Skip the file number. */
518 get_absolute_expression ();
521 lineno
= get_absolute_expression ();
529 lineno
+= coff_line_base
- 1;
530 listing_source_line (lineno
);
535 demand_empty_rest_of_line ();
537 add_lineno (frag_now
, frag_now_fix (), lineno
);
540 /* Handle the .ident pseudo-op. */
543 obj_coff_ident (int ignore ATTRIBUTE_UNUSED
)
545 segT current_seg
= now_seg
;
546 subsegT current_subseg
= now_subseg
;
552 /* We could put it in .comment, but that creates an extra section
553 that shouldn't be loaded into memory, which requires linker
554 changes... For now, until proven otherwise, use .rdata. */
555 sec
= subseg_new (".rdata$zzz", 0);
556 bfd_set_section_flags (sec
,
557 ((SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
| SEC_DATA
)
558 & bfd_applicable_section_flags (stdoutput
)));
561 subseg_new (".comment", 0);
565 subseg_set (current_seg
, current_subseg
);
568 /* Handle .def directives.
570 One might ask : why can't we symbol_new if the symbol does not
571 already exist and fill it with debug information. Because of
572 the C_EFCN special symbol. It would clobber the value of the
573 function symbol before we have a chance to notice that it is
574 a C_EFCN. And a second reason is that the code is more clear this
575 way. (at least I think it is :-). */
577 #define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';')
578 #define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \
579 *input_line_pointer == '\t') \
580 input_line_pointer++;
583 obj_coff_def (int what ATTRIBUTE_UNUSED
)
585 char name_end
; /* Char after the end of name. */
586 char *symbol_name
; /* Name of the debug symbol. */
587 char *symbol_name_copy
; /* Temporary copy of the name. */
589 if (def_symbol_in_progress
!= NULL
)
591 as_warn (_(".def pseudo-op used inside of .def/.endef: ignored."));
592 demand_empty_rest_of_line ();
598 name_end
= get_symbol_name (&symbol_name
);
599 symbol_name_copy
= xstrdup (symbol_name
);
600 #ifdef tc_canonicalize_symbol_name
601 symbol_name_copy
= tc_canonicalize_symbol_name (symbol_name_copy
);
604 /* Initialize the new symbol. */
605 def_symbol_in_progress
= symbol_make (symbol_name_copy
);
606 symbol_set_frag (def_symbol_in_progress
, &zero_address_frag
);
607 S_SET_VALUE (def_symbol_in_progress
, 0);
609 if (S_IS_STRING (def_symbol_in_progress
))
610 SF_SET_STRING (def_symbol_in_progress
);
612 (void) restore_line_pointer (name_end
);
614 demand_empty_rest_of_line ();
618 obj_coff_endef (int ignore ATTRIBUTE_UNUSED
)
620 symbolS
*symbolP
= NULL
;
622 if (def_symbol_in_progress
== NULL
)
624 as_warn (_(".endef pseudo-op used outside of .def/.endef: ignored."));
625 demand_empty_rest_of_line ();
629 /* Set the section number according to storage class. */
630 switch (S_GET_STORAGE_CLASS (def_symbol_in_progress
))
635 SF_SET_TAG (def_symbol_in_progress
);
639 SF_SET_DEBUG (def_symbol_in_progress
);
640 S_SET_SEGMENT (def_symbol_in_progress
, fetch_coff_debug_section ());
644 SF_SET_LOCAL (def_symbol_in_progress
); /* Do not emit this symbol. */
647 SF_SET_PROCESS (def_symbol_in_progress
); /* Will need processing before writing. */
653 S_SET_SEGMENT (def_symbol_in_progress
, text_section
);
655 name
= S_GET_NAME (def_symbol_in_progress
);
656 if (name
[0] == '.' && name
[2] == 'f' && name
[3] == '\0')
662 if (! in_function ())
663 as_warn (_("`%s' symbol without preceding function"), name
);
664 /* Will need relocating. */
665 SF_SET_PROCESS (def_symbol_in_progress
);
671 /* The MS compilers output the actual endline, not the
672 function-relative one... we want to match without
673 changing the assembler input. */
674 SA_SET_SYM_LNNO (def_symbol_in_progress
,
675 (SA_GET_SYM_LNNO (def_symbol_in_progress
)
686 #endif /* C_AUTOARG */
693 /* According to the COFF documentation:
695 http://osr5doc.sco.com:1996/topics/COFF_SectNumFld.html
697 A special section number (-2) marks symbolic debugging symbols,
698 including structure/union/enumeration tag names, typedefs, and
699 the name of the file. A section number of -1 indicates that the
700 symbol has a value but is not relocatable. Examples of
701 absolute-valued symbols include automatic and register variables,
702 function arguments, and .eos symbols.
704 But from Ian Lance Taylor:
706 http://sources.redhat.com/ml/binutils/2000-08/msg00202.html
708 the actual tools all marked them as section -1. So the GNU COFF
709 assembler follows historical COFF assemblers.
711 However, it causes problems for djgpp
713 http://sources.redhat.com/ml/binutils/2000-08/msg00210.html
715 By defining STRICTCOFF, a COFF port can make the assembler to
716 follow the documented behavior. */
723 SF_SET_DEBUG (def_symbol_in_progress
);
724 S_SET_SEGMENT (def_symbol_in_progress
, absolute_section
);
732 S_SET_SEGMENT (def_symbol_in_progress
, absolute_section
);
743 /* Valid but set somewhere else (s_comm, s_lcomm, colon). */
750 as_warn (_("unexpected storage class %d"),
751 S_GET_STORAGE_CLASS (def_symbol_in_progress
));
755 /* Now that we have built a debug symbol, try to find if we should
756 merge with an existing symbol or not. If a symbol is C_EFCN or
757 absolute_section or untagged SEG_DEBUG it never merges. We also
758 don't merge labels, which are in a different namespace, nor
759 symbols which have not yet been defined since they are typically
760 unique, nor do we merge tags with non-tags. */
762 /* Two cases for functions. Either debug followed by definition or
763 definition followed by debug. For definition first, we will
764 merge the debug symbol into the definition. For debug first, the
765 lineno entry MUST point to the definition function or else it
766 will point off into space when obj_crawl_symbol_chain() merges
767 the debug symbol into the real symbol. Therefor, let's presume
768 the debug symbol is a real function reference. */
770 /* FIXME-SOON If for some reason the definition label/symbol is
771 never seen, this will probably leave an undefined symbol at link
774 if (S_GET_STORAGE_CLASS (def_symbol_in_progress
) == C_EFCN
775 || S_GET_STORAGE_CLASS (def_symbol_in_progress
) == C_LABEL
776 || (streq (bfd_section_name (S_GET_SEGMENT (def_symbol_in_progress
)),
778 && !SF_GET_TAG (def_symbol_in_progress
))
779 || S_GET_SEGMENT (def_symbol_in_progress
) == absolute_section
780 || ! symbol_constant_p (def_symbol_in_progress
)
781 || (symbolP
= symbol_find (S_GET_NAME (def_symbol_in_progress
))) == NULL
782 || SF_GET_TAG (def_symbol_in_progress
) != SF_GET_TAG (symbolP
))
784 /* If it already is at the end of the symbol list, do nothing */
785 if (def_symbol_in_progress
!= symbol_lastP
)
787 symbol_remove (def_symbol_in_progress
, &symbol_rootP
, &symbol_lastP
);
788 symbol_append (def_symbol_in_progress
, symbol_lastP
, &symbol_rootP
,
794 /* This symbol already exists, merge the newly created symbol
795 into the old one. This is not mandatory. The linker can
796 handle duplicate symbols correctly. But I guess that it save
797 a *lot* of space if the assembly file defines a lot of
800 /* The debug entry (def_symbol_in_progress) is merged into the
801 previous definition. */
803 c_symbol_merge (def_symbol_in_progress
, symbolP
);
804 symbol_remove (def_symbol_in_progress
, &symbol_rootP
, &symbol_lastP
);
806 def_symbol_in_progress
= symbolP
;
808 if (SF_GET_FUNCTION (def_symbol_in_progress
)
809 || SF_GET_TAG (def_symbol_in_progress
)
810 || S_GET_STORAGE_CLASS (def_symbol_in_progress
) == C_STAT
)
812 /* For functions, and tags, and static symbols, the symbol
813 *must* be where the debug symbol appears. Move the
814 existing symbol to the current place. */
815 /* If it already is at the end of the symbol list, do nothing. */
816 if (def_symbol_in_progress
!= symbol_lastP
)
818 symbol_remove (def_symbol_in_progress
, &symbol_rootP
, &symbol_lastP
);
819 symbol_append (def_symbol_in_progress
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
824 if (SF_GET_TAG (def_symbol_in_progress
))
828 oldtag
= symbol_find (S_GET_NAME (def_symbol_in_progress
));
829 if (oldtag
== NULL
|| ! SF_GET_TAG (oldtag
))
830 tag_insert (S_GET_NAME (def_symbol_in_progress
),
831 def_symbol_in_progress
);
834 if (SF_GET_FUNCTION (def_symbol_in_progress
))
836 set_function (def_symbol_in_progress
);
837 SF_SET_PROCESS (def_symbol_in_progress
);
840 /* That is, if this is the first time we've seen the
842 symbol_table_insert (def_symbol_in_progress
);
846 def_symbol_in_progress
= NULL
;
847 demand_empty_rest_of_line ();
851 obj_coff_dim (int ignore ATTRIBUTE_UNUSED
)
855 if (def_symbol_in_progress
== NULL
)
857 as_warn (_(".dim pseudo-op used outside of .def/.endef: ignored."));
858 demand_empty_rest_of_line ();
862 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress
, 1);
864 for (d_index
= 0; d_index
< DIMNUM
; d_index
++)
867 SA_SET_SYM_DIMEN (def_symbol_in_progress
, d_index
,
868 get_absolute_expression ());
870 switch (*input_line_pointer
)
873 input_line_pointer
++;
877 as_warn (_("badly formed .dim directive ignored"));
886 demand_empty_rest_of_line ();
890 obj_coff_line (int ignore ATTRIBUTE_UNUSED
)
894 if (def_symbol_in_progress
== NULL
)
896 /* Probably stabs-style line? */
901 this_base
= get_absolute_expression ();
902 if (streq (".bf", S_GET_NAME (def_symbol_in_progress
)))
903 coff_line_base
= this_base
;
905 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress
, 1);
906 SA_SET_SYM_LNNO (def_symbol_in_progress
, this_base
);
908 demand_empty_rest_of_line ();
911 if (streq (".bf", S_GET_NAME (def_symbol_in_progress
)))
916 listing_source_line ((unsigned int) this_base
);
922 obj_coff_size (int ignore ATTRIBUTE_UNUSED
)
924 if (def_symbol_in_progress
== NULL
)
926 as_warn (_(".size pseudo-op used outside of .def/.endef: ignored."));
927 demand_empty_rest_of_line ();
931 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress
, 1);
932 SA_SET_SYM_SIZE (def_symbol_in_progress
, get_absolute_expression ());
933 demand_empty_rest_of_line ();
937 obj_coff_scl (int ignore ATTRIBUTE_UNUSED
)
939 if (def_symbol_in_progress
== NULL
)
941 as_warn (_(".scl pseudo-op used outside of .def/.endef: ignored."));
942 demand_empty_rest_of_line ();
946 S_SET_STORAGE_CLASS (def_symbol_in_progress
, get_absolute_expression ());
947 demand_empty_rest_of_line ();
951 obj_coff_tag (int ignore ATTRIBUTE_UNUSED
)
956 if (def_symbol_in_progress
== NULL
)
958 as_warn (_(".tag pseudo-op used outside of .def/.endef: ignored."));
959 demand_empty_rest_of_line ();
963 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress
, 1);
964 name_end
= get_symbol_name (&symbol_name
);
966 #ifdef tc_canonicalize_symbol_name
967 symbol_name
= tc_canonicalize_symbol_name (symbol_name
);
970 /* Assume that the symbol referred to by .tag is always defined.
971 This was a bad assumption. I've added find_or_make. xoxorich. */
972 SA_SET_SYM_TAGNDX (def_symbol_in_progress
,
973 tag_find_or_make (symbol_name
));
974 if (SA_GET_SYM_TAGNDX (def_symbol_in_progress
) == 0L)
975 as_warn (_("tag not found for .tag %s"), symbol_name
);
977 SF_SET_TAGGED (def_symbol_in_progress
);
979 (void) restore_line_pointer (name_end
);
980 demand_empty_rest_of_line ();
984 obj_coff_type (int ignore ATTRIBUTE_UNUSED
)
986 if (def_symbol_in_progress
== NULL
)
988 as_warn (_(".type pseudo-op used outside of .def/.endef: ignored."));
989 demand_empty_rest_of_line ();
993 S_SET_DATA_TYPE (def_symbol_in_progress
, get_absolute_expression ());
995 if (ISFCN (S_GET_DATA_TYPE (def_symbol_in_progress
)) &&
996 S_GET_STORAGE_CLASS (def_symbol_in_progress
) != C_TPDEF
)
997 SF_SET_FUNCTION (def_symbol_in_progress
);
999 demand_empty_rest_of_line ();
1003 obj_coff_val (int ignore ATTRIBUTE_UNUSED
)
1005 if (def_symbol_in_progress
== NULL
)
1007 as_warn (_(".val pseudo-op used outside of .def/.endef: ignored."));
1008 demand_empty_rest_of_line ();
1012 if (is_name_beginner (*input_line_pointer
))
1015 char name_end
= get_symbol_name (&symbol_name
);
1017 #ifdef tc_canonicalize_symbol_name
1018 symbol_name
= tc_canonicalize_symbol_name (symbol_name
);
1020 if (streq (symbol_name
, "."))
1022 /* If the .val is != from the .def (e.g. statics). */
1023 symbol_set_frag (def_symbol_in_progress
, frag_now
);
1024 S_SET_VALUE (def_symbol_in_progress
, (valueT
) frag_now_fix ());
1026 else if (! streq (S_GET_NAME (def_symbol_in_progress
), symbol_name
))
1030 exp
.X_op
= O_symbol
;
1031 exp
.X_add_symbol
= symbol_find_or_make (symbol_name
);
1032 exp
.X_op_symbol
= NULL
;
1033 exp
.X_add_number
= 0;
1034 symbol_set_value_expression (def_symbol_in_progress
, &exp
);
1036 /* If the segment is undefined when the forward reference is
1037 resolved, then copy the segment id from the forward
1039 SF_SET_GET_SEGMENT (def_symbol_in_progress
);
1041 /* FIXME: gcc can generate address expressions here in
1042 unusual cases (search for "obscure" in sdbout.c). We
1043 just ignore the offset here, thus generating incorrect
1044 debugging information. We ignore the rest of the line
1047 /* Otherwise, it is the name of a non debug symbol and its value
1048 will be calculated later. */
1049 (void) restore_line_pointer (name_end
);
1053 S_SET_VALUE (def_symbol_in_progress
, get_absolute_expression ());
1056 demand_empty_rest_of_line ();
1061 /* Return nonzero if name begins with weak alternate symbol prefix. */
1064 weak_is_altname (const char * name
)
1066 return strneq (name
, weak_altprefix
, sizeof (weak_altprefix
) - 1);
1069 /* Return the name of the alternate symbol
1070 name corresponding to a weak symbol's name. */
1073 weak_name2altname (const char * name
)
1075 return concat (weak_altprefix
, name
, (char *) NULL
);
1078 /* Return the name of the weak symbol corresponding to an
1079 alternate symbol. */
1082 weak_altname2name (const char * name
)
1084 gas_assert (weak_is_altname (name
));
1085 return xstrdup (name
+ 6);
1088 /* Make a weak symbol name unique by
1089 appending the name of an external symbol. */
1092 weak_uniquify (const char * name
)
1094 const char * unique
= "";
1097 if (an_external_name
!= NULL
)
1098 unique
= an_external_name
;
1100 gas_assert (weak_is_altname (name
));
1102 return concat (name
, ".", unique
, (char *) NULL
);
1106 pecoff_obj_set_weak_hook (symbolS
*symbolP
)
1108 symbolS
*alternateP
;
1110 /* See _Microsoft Portable Executable and Common Object
1111 File Format Specification_, section 5.5.3.
1112 Create a symbol representing the alternate value.
1113 coff_frob_symbol will set the value of this symbol from
1114 the value of the weak symbol itself. */
1115 S_SET_STORAGE_CLASS (symbolP
, C_NT_WEAK
);
1116 S_SET_NUMBER_AUXILIARY (symbolP
, 1);
1117 SA_SET_SYM_FSIZE (symbolP
, IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY
);
1119 alternateP
= symbol_find_or_make (weak_name2altname (S_GET_NAME (symbolP
)));
1120 S_SET_EXTERNAL (alternateP
);
1121 S_SET_STORAGE_CLASS (alternateP
, C_NT_WEAK
);
1123 SA_SET_SYM_TAGNDX (symbolP
, alternateP
);
1127 pecoff_obj_clear_weak_hook (symbolS
*symbolP
)
1129 symbolS
*alternateP
;
1131 S_SET_STORAGE_CLASS (symbolP
, 0);
1132 SA_SET_SYM_FSIZE (symbolP
, 0);
1134 alternateP
= symbol_find (weak_name2altname (S_GET_NAME (symbolP
)));
1135 S_CLEAR_EXTERNAL (alternateP
);
1140 /* Handle .weak. This is a GNU extension in formats other than PE. */
1143 obj_coff_weak (int ignore ATTRIBUTE_UNUSED
)
1151 c
= get_symbol_name (&name
);
1154 as_warn (_("badly formed .weak directive ignored"));
1155 ignore_rest_of_line ();
1159 symbolP
= symbol_find_or_make (name
);
1160 *input_line_pointer
= c
;
1161 SKIP_WHITESPACE_AFTER_NAME ();
1162 S_SET_WEAK (symbolP
);
1166 input_line_pointer
++;
1168 if (*input_line_pointer
== '\n')
1175 demand_empty_rest_of_line ();
1179 coff_obj_read_begin_hook (void)
1181 /* These had better be the same. Usually 18 bytes. */
1182 know (sizeof (SYMENT
) == sizeof (AUXENT
));
1183 know (SYMESZ
== AUXESZ
);
1187 symbolS
*coff_last_function
;
1189 static symbolS
*coff_last_bf
;
1193 coff_frob_symbol (symbolS
*symp
, int *punt
)
1195 static symbolS
*last_tagP
;
1196 static stack
*block_stack
;
1197 static symbolS
*set_end
;
1198 symbolS
*next_set_end
= NULL
;
1200 if (symp
== &abs_symbol
)
1206 if (current_lineno_sym
)
1207 coff_add_linesym (NULL
);
1210 block_stack
= stack_init (512, sizeof (symbolS
*));
1213 if (S_GET_STORAGE_CLASS (symp
) == C_NT_WEAK
1214 && ! S_IS_WEAK (symp
)
1215 && weak_is_altname (S_GET_NAME (symp
)))
1217 /* This is a weak alternate symbol. All processing of
1218 PECOFFweak symbols is done here, through the alternate. */
1219 symbolS
*weakp
= symbol_find_noref (weak_altname2name
1220 (S_GET_NAME (symp
)), 1);
1223 gas_assert (S_GET_NUMBER_AUXILIARY (weakp
) == 1);
1225 if (! S_IS_WEAK (weakp
))
1227 /* The symbol was turned from weak to strong. Discard altname. */
1231 else if (symbol_equated_p (weakp
))
1233 /* The weak symbol has an alternate specified; symp is unneeded. */
1234 S_SET_STORAGE_CLASS (weakp
, C_NT_WEAK
);
1235 SA_SET_SYM_TAGNDX (weakp
,
1236 symbol_get_value_expression (weakp
)->X_add_symbol
);
1238 S_CLEAR_EXTERNAL (symp
);
1244 /* The weak symbol has been assigned an alternate value.
1245 Copy this value to symp, and set symp as weakp's alternate. */
1246 if (S_GET_STORAGE_CLASS (weakp
) != C_NT_WEAK
)
1248 S_SET_STORAGE_CLASS (symp
, S_GET_STORAGE_CLASS (weakp
));
1249 S_SET_STORAGE_CLASS (weakp
, C_NT_WEAK
);
1252 if (S_IS_DEFINED (weakp
))
1254 /* This is a defined weak symbol. Copy value information
1255 from the weak symbol itself to the alternate symbol. */
1256 symbol_set_value_expression (symp
,
1257 symbol_get_value_expression (weakp
));
1258 symbol_set_frag (symp
, symbol_get_frag (weakp
));
1259 S_SET_SEGMENT (symp
, S_GET_SEGMENT (weakp
));
1263 /* This is an undefined weak symbol.
1264 Define the alternate symbol to zero. */
1265 S_SET_VALUE (symp
, 0);
1266 S_SET_SEGMENT (symp
, absolute_section
);
1269 S_SET_NAME (symp
, weak_uniquify (S_GET_NAME (symp
)));
1270 S_SET_STORAGE_CLASS (symp
, C_EXT
);
1272 S_SET_VALUE (weakp
, 0);
1273 S_SET_SEGMENT (weakp
, undefined_section
);
1277 if (S_IS_WEAK (symp
))
1278 S_SET_STORAGE_CLASS (symp
, C_WEAKEXT
);
1281 if (!S_IS_DEFINED (symp
)
1282 && !S_IS_WEAK (symp
)
1283 && S_GET_STORAGE_CLASS (symp
) != C_STAT
)
1284 S_SET_STORAGE_CLASS (symp
, C_EXT
);
1286 if (!SF_GET_DEBUG (symp
))
1290 if (!SF_GET_LOCAL (symp
)
1291 && !SF_GET_STATICS (symp
)
1292 && S_GET_STORAGE_CLASS (symp
) != C_LABEL
1293 && symbol_constant_p (symp
)
1294 && (real
= symbol_find_noref (S_GET_NAME (symp
), 1))
1295 && S_GET_STORAGE_CLASS (real
) == C_NULL
1298 c_symbol_merge (symp
, real
);
1303 if (!S_IS_DEFINED (symp
) && !SF_GET_LOCAL (symp
))
1305 gas_assert (S_GET_VALUE (symp
) == 0);
1306 if (S_IS_WEAKREFD (symp
))
1309 S_SET_EXTERNAL (symp
);
1311 else if (S_GET_STORAGE_CLASS (symp
) == C_NULL
)
1313 if (S_GET_SEGMENT (symp
) == text_section
1314 && symp
!= seg_info (text_section
)->sym
)
1315 S_SET_STORAGE_CLASS (symp
, C_LABEL
);
1317 S_SET_STORAGE_CLASS (symp
, C_STAT
);
1320 if (SF_GET_PROCESS (symp
))
1322 if (S_GET_STORAGE_CLASS (symp
) == C_BLOCK
)
1324 if (streq (S_GET_NAME (symp
), ".bb"))
1325 stack_push (block_stack
, (char *) &symp
);
1330 begin
= *(symbolS
**) stack_pop (block_stack
);
1332 as_warn (_("mismatched .eb"));
1334 next_set_end
= begin
;
1338 if (coff_last_function
== 0 && SF_GET_FUNCTION (symp
)
1339 && S_IS_DEFINED (symp
))
1341 union internal_auxent
*auxp
;
1343 coff_last_function
= symp
;
1344 if (S_GET_NUMBER_AUXILIARY (symp
) < 1)
1345 S_SET_NUMBER_AUXILIARY (symp
, 1);
1346 auxp
= SYM_AUXENT (symp
);
1347 memset (auxp
->x_sym
.x_fcnary
.x_ary
.x_dimen
, 0,
1348 sizeof (auxp
->x_sym
.x_fcnary
.x_ary
.x_dimen
));
1351 if (S_GET_STORAGE_CLASS (symp
) == C_EFCN
1352 && S_IS_DEFINED (symp
))
1354 if (coff_last_function
== 0)
1355 as_fatal (_("C_EFCN symbol for %s out of scope"),
1357 SA_SET_SYM_FSIZE (coff_last_function
,
1358 (long) (S_GET_VALUE (symp
)
1359 - S_GET_VALUE (coff_last_function
)));
1360 next_set_end
= coff_last_function
;
1361 coff_last_function
= 0;
1365 if (S_IS_EXTERNAL (symp
))
1366 S_SET_STORAGE_CLASS (symp
, C_EXT
);
1367 else if (SF_GET_LOCAL (symp
))
1370 if (SF_GET_FUNCTION (symp
))
1371 symbol_get_bfdsym (symp
)->flags
|= BSF_FUNCTION
;
1374 /* Double check weak symbols. */
1375 if (S_IS_WEAK (symp
) && S_IS_COMMON (symp
))
1376 as_bad (_("Symbol `%s' can not be both weak and common"),
1379 if (SF_GET_TAG (symp
))
1381 else if (S_GET_STORAGE_CLASS (symp
) == C_EOS
)
1382 next_set_end
= last_tagP
;
1385 /* This is pretty horrible, but we have to set *punt correctly in
1386 order to call SA_SET_SYM_ENDNDX correctly. */
1387 if (! symbol_used_in_reloc_p (symp
)
1388 && ((symbol_get_bfdsym (symp
)->flags
& BSF_SECTION_SYM
) != 0
1389 || (! (S_IS_EXTERNAL (symp
) || S_IS_WEAK (symp
))
1390 && ! symbol_get_tc (symp
)->output
1391 && S_GET_STORAGE_CLASS (symp
) != C_FILE
)))
1395 if (set_end
!= (symbolS
*) NULL
1397 && ((symbol_get_bfdsym (symp
)->flags
& BSF_NOT_AT_END
) != 0
1398 || (S_IS_DEFINED (symp
)
1399 && ! S_IS_COMMON (symp
)
1400 && (! S_IS_EXTERNAL (symp
) || SF_GET_FUNCTION (symp
)))))
1402 SA_SET_SYM_ENDNDX (set_end
, symp
);
1406 if (next_set_end
!= NULL
)
1408 if (set_end
!= NULL
)
1409 as_warn (_("Warning: internal error: forgetting to set endndx of %s"),
1410 S_GET_NAME (set_end
));
1411 set_end
= next_set_end
;
1416 && S_GET_STORAGE_CLASS (symp
) == C_FCN
1417 && streq (S_GET_NAME (symp
), ".bf"))
1419 if (coff_last_bf
!= NULL
)
1420 SA_SET_SYM_ENDNDX (coff_last_bf
, symp
);
1421 coff_last_bf
= symp
;
1424 if (coffsymbol (symbol_get_bfdsym (symp
))->lineno
)
1427 struct line_no
*lptr
;
1430 lptr
= (struct line_no
*) coffsymbol (symbol_get_bfdsym (symp
))->lineno
;
1431 for (i
= 0; lptr
; lptr
= lptr
->next
)
1433 lptr
= (struct line_no
*) coffsymbol (symbol_get_bfdsym (symp
))->lineno
;
1435 /* We need i entries for line numbers, plus 1 for the first
1436 entry which BFD will override, plus 1 for the last zero
1437 entry (a marker for BFD). */
1438 l
= XNEWVEC (alent
, (i
+ 2));
1439 coffsymbol (symbol_get_bfdsym (symp
))->lineno
= l
;
1440 l
[i
+ 1].line_number
= 0;
1441 l
[i
+ 1].u
.sym
= NULL
;
1445 lptr
->l
.u
.offset
+= lptr
->frag
->fr_address
/ OCTETS_PER_BYTE
;
1453 coff_adjust_section_syms (bfd
*abfd ATTRIBUTE_UNUSED
,
1455 void * x ATTRIBUTE_UNUSED
)
1458 segment_info_type
*seginfo
= seg_info (sec
);
1459 int nlnno
, nrelocs
= 0;
1461 /* RS/6000 gas creates a .debug section manually in ppc_frob_file in
1462 tc-ppc.c. Do not get confused by it. */
1463 if (seginfo
== NULL
)
1466 if (streq (sec
->name
, ".text"))
1467 nlnno
= coff_n_line_nos
;
1471 /* @@ Hope that none of the fixups expand to more than one reloc
1473 fixS
*fixp
= seginfo
->fix_root
;
1476 if (! fixp
->fx_done
)
1478 fixp
= fixp
->fx_next
;
1481 if (bfd_section_size (sec
) == 0
1484 && sec
!= text_section
1485 && sec
!= data_section
1486 && sec
!= bss_section
)
1489 secsym
= section_symbol (sec
);
1490 /* This is an estimate; we'll plug in the real value using
1491 SET_SECTION_RELOCS later */
1492 SA_SET_SCN_NRELOC (secsym
, nrelocs
);
1493 SA_SET_SCN_NLINNO (secsym
, nlnno
);
1497 coff_frob_file_after_relocs (void)
1499 bfd_map_over_sections (stdoutput
, coff_adjust_section_syms
, NULL
);
1502 /* Implement the .section pseudo op:
1503 .section name {, "flags"}
1505 | +--- optional flags: 'b' for bss
1507 +-- section name 'l' for lib
1511 'd' (apparently m88k for data)
1514 'r' for read-only data
1515 's' for shared data (PE)
1517 '0' - '9' for power-of-two alignment (GNU extension).
1518 But if the argument is not a quoted string, treat it as a
1521 Note the 'a' flag is silently ignored. This allows the same
1522 .section directive to be parsed in both ELF and COFF formats. */
1525 obj_coff_section (int ignore ATTRIBUTE_UNUSED
)
1527 /* Strip out the section name. */
1533 flagword flags
, oldflags
;
1535 bfd_boolean is_bss
= FALSE
;
1545 c
= get_symbol_name (§ion_name
);
1546 name
= xmemdup0 (section_name
, input_line_pointer
- section_name
);
1547 *input_line_pointer
= c
;
1548 SKIP_WHITESPACE_AFTER_NAME ();
1551 flags
= SEC_NO_FLAGS
;
1553 if (*input_line_pointer
== ',')
1555 ++input_line_pointer
;
1557 if (*input_line_pointer
!= '"')
1558 exp
= get_absolute_expression ();
1562 int readonly_removed
= 0;
1563 int load_removed
= 0;
1565 while (attr
= *++input_line_pointer
,
1567 && ! is_end_of_line
[attr
])
1571 alignment
= attr
- '0';
1577 /* Exclude section from linking. */
1578 flags
|= SEC_EXCLUDE
;
1582 /* Uninitialised data section. */
1589 /* Section not loaded. */
1591 flags
|= SEC_NEVER_LOAD
;
1596 /* Shared section. */
1597 flags
|= SEC_COFF_SHARED
;
1604 flags
&=~ SEC_READONLY
;
1608 /* Writable section. */
1609 flags
&=~ SEC_READONLY
;
1610 readonly_removed
= 1;
1614 /* Ignore. Here for compatibility with ELF. */
1617 case 'r': /* Read-only section. Implies a data section. */
1618 readonly_removed
= 0;
1620 case 'x': /* Executable section. */
1621 /* If we are setting the 'x' attribute or if the 'r'
1622 attribute is being used to restore the readonly status
1623 of a code section (eg "wxr") then set the SEC_CODE flag,
1624 otherwise set the SEC_DATA flag. */
1625 flags
|= (attr
== 'x' || (flags
& SEC_CODE
) ? SEC_CODE
: SEC_DATA
);
1628 /* Note - the READONLY flag is set here, even for the 'x'
1629 attribute in order to be compatible with the MSVC
1631 if (! readonly_removed
)
1632 flags
|= SEC_READONLY
;
1636 flags
|= SEC_COFF_NOREAD
| SEC_READONLY
;
1639 case 'i': /* STYP_INFO */
1640 case 'l': /* STYP_LIB */
1641 case 'o': /* STYP_OVER */
1642 as_warn (_("unsupported section attribute '%c'"), attr
);
1646 as_warn (_("unknown section attribute '%c'"), attr
);
1651 ++input_line_pointer
;
1655 sec
= subseg_new (name
, (subsegT
) exp
);
1658 seg_info (sec
)->bss
= 1;
1661 sec
->alignment_power
= alignment
;
1663 oldflags
= bfd_section_flags (sec
);
1664 if (oldflags
== SEC_NO_FLAGS
)
1666 /* Set section flags for a new section just created by subseg_new.
1667 Provide a default if no flags were parsed. */
1668 if (flags
== SEC_NO_FLAGS
)
1669 flags
= TC_COFF_SECTION_DEFAULT_ATTRIBUTES
;
1671 #ifdef COFF_LONG_SECTION_NAMES
1672 /* Add SEC_LINK_ONCE and SEC_LINK_DUPLICATES_DISCARD to .gnu.linkonce
1673 sections so adjust_reloc_syms in write.c will correctly handle
1674 relocs which refer to non-local symbols in these sections. */
1675 if (strneq (name
, ".gnu.linkonce", sizeof (".gnu.linkonce") - 1))
1676 flags
|= SEC_LINK_ONCE
| SEC_LINK_DUPLICATES_DISCARD
;
1679 if (!bfd_set_section_flags (sec
, flags
))
1680 as_warn (_("error setting flags for \"%s\": %s"),
1681 bfd_section_name (sec
),
1682 bfd_errmsg (bfd_get_error ()));
1684 else if (flags
!= SEC_NO_FLAGS
)
1686 /* This section's attributes have already been set. Warn if the
1687 attributes don't match. */
1688 flagword matchflags
= (SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
| SEC_CODE
1689 | SEC_DATA
| SEC_COFF_SHARED
| SEC_NEVER_LOAD
1691 if ((flags
^ oldflags
) & matchflags
)
1692 as_warn (_("Ignoring changed section attributes for %s"), name
);
1695 demand_empty_rest_of_line ();
1699 coff_adjust_symtab (void)
1701 if (symbol_rootP
== NULL
1702 || S_GET_STORAGE_CLASS (symbol_rootP
) != C_FILE
)
1703 c_dot_file_symbol ("fake", 0);
1707 coff_frob_section (segT sec
)
1714 /* The COFF back end in BFD requires that all section sizes be
1715 rounded up to multiples of the corresponding section alignments,
1716 supposedly because standard COFF has no other way of encoding alignment
1717 for sections. If your COFF flavor has a different way of encoding
1718 section alignment, then skip this step, as TICOFF does. */
1719 bfd_vma size
= bfd_section_size (sec
);
1720 #if !defined(TICOFF)
1721 bfd_vma align_power
= (bfd_vma
) sec
->alignment_power
+ OCTETS_PER_BYTE_POWER
;
1722 bfd_vma mask
= ((bfd_vma
) 1 << align_power
) - 1;
1729 new_size
= (size
+ mask
) & ~mask
;
1730 bfd_set_section_size (sec
, new_size
);
1732 /* If the size had to be rounded up, add some padding in
1733 the last non-empty frag. */
1734 fragp
= seg_info (sec
)->frchainP
->frch_root
;
1735 last
= seg_info (sec
)->frchainP
->frch_last
;
1736 while (fragp
->fr_next
!= last
)
1737 fragp
= fragp
->fr_next
;
1738 last
->fr_address
= size
;
1739 fragp
->fr_offset
+= new_size
- size
;
1743 /* If the section size is non-zero, the section symbol needs an aux
1744 entry associated with it, indicating the size. We don't know
1745 all the values yet; coff_frob_symbol will fill them in later. */
1748 || sec
== text_section
1749 || sec
== data_section
1750 || sec
== bss_section
)
1753 symbolS
*secsym
= section_symbol (sec
);
1754 unsigned char sclass
= C_STAT
;
1757 if (bfd_section_flags (sec
) & SEC_DEBUGGING
)
1760 S_SET_STORAGE_CLASS (secsym
, sclass
);
1761 S_SET_NUMBER_AUXILIARY (secsym
, 1);
1762 SF_SET_STATICS (secsym
);
1763 SA_SET_SCN_SCNLEN (secsym
, size
);
1765 /* FIXME: These should be in a "stabs.h" file, or maybe as.h. */
1766 #ifndef STAB_SECTION_NAME
1767 #define STAB_SECTION_NAME ".stab"
1769 #ifndef STAB_STRING_SECTION_NAME
1770 #define STAB_STRING_SECTION_NAME ".stabstr"
1772 if (! streq (STAB_STRING_SECTION_NAME
, sec
->name
))
1776 sec
= subseg_get (STAB_SECTION_NAME
, 0);
1777 /* size is already rounded up, since other section will be listed first */
1778 size
= bfd_section_size (strsec
);
1780 n_entries
= bfd_section_size (sec
) / 12 - 1;
1782 /* Find first non-empty frag. It should be large enough. */
1783 fragp
= seg_info (sec
)->frchainP
->frch_root
;
1784 while (fragp
&& fragp
->fr_fix
== 0)
1785 fragp
= fragp
->fr_next
;
1786 gas_assert (fragp
!= 0 && fragp
->fr_fix
>= 12);
1788 /* Store the values. */
1789 p
= fragp
->fr_literal
;
1790 bfd_h_put_16 (stdoutput
, n_entries
, (bfd_byte
*) p
+ 6);
1791 bfd_h_put_32 (stdoutput
, size
, (bfd_byte
*) p
+ 8);
1795 obj_coff_init_stab_section (segT seg
)
1800 unsigned int stroff
;
1802 /* Make space for this first symbol. */
1806 file
= as_where ((unsigned int *) NULL
);
1807 stabstr_name
= concat (seg
->name
, "str", (char *) NULL
);
1808 stroff
= get_stab_string_offset (file
, stabstr_name
, TRUE
);
1810 md_number_to_chars (p
, stroff
, 4);
1814 const char * s_get_name (symbolS
*);
1817 s_get_name (symbolS
*s
)
1819 return ((s
== NULL
) ? "(NULL)" : S_GET_NAME (s
));
1822 void symbol_dump (void);
1829 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
1830 printf (_("0x%lx: \"%s\" type = %ld, class = %d, segment = %d\n"),
1831 (unsigned long) symbolP
,
1832 S_GET_NAME (symbolP
),
1833 (long) S_GET_DATA_TYPE (symbolP
),
1834 S_GET_STORAGE_CLASS (symbolP
),
1835 (int) S_GET_SEGMENT (symbolP
));
1840 const pseudo_typeS coff_pseudo_table
[] =
1842 {"ABORT", s_abort
, 0},
1843 {"appline", obj_coff_ln
, 1},
1844 /* We accept the .bss directive for backward compatibility with
1845 earlier versions of gas. */
1846 {"bss", obj_coff_bss
, 0},
1848 /* PE provides an enhanced version of .comm with alignment. */
1849 {"comm", obj_coff_comm
, 0},
1851 {"def", obj_coff_def
, 0},
1852 {"dim", obj_coff_dim
, 0},
1853 {"endef", obj_coff_endef
, 0},
1854 {"ident", obj_coff_ident
, 0},
1855 {"line", obj_coff_line
, 0},
1856 {"ln", obj_coff_ln
, 0},
1857 {"scl", obj_coff_scl
, 0},
1858 {"sect", obj_coff_section
, 0},
1859 {"sect.s", obj_coff_section
, 0},
1860 {"section", obj_coff_section
, 0},
1861 {"section.s", obj_coff_section
, 0},
1862 /* FIXME: We ignore the MRI short attribute. */
1863 {"size", obj_coff_size
, 0},
1864 {"tag", obj_coff_tag
, 0},
1865 {"type", obj_coff_type
, 0},
1866 {"val", obj_coff_val
, 0},
1867 {"version", s_ignore
, 0},
1868 {"loc", obj_coff_loc
, 0},
1869 {"optim", s_ignore
, 0}, /* For sun386i cc (?) */
1870 {"weak", obj_coff_weak
, 0},
1871 #if defined TC_TIC4X
1872 /* The tic4x uses sdef instead of def. */
1873 {"sdef", obj_coff_def
, 0},
1875 #if defined(SEH_CMDS)
1882 /* Support for a COFF emulation. */
1885 coff_pop_insert (void)
1887 pop_insert (coff_pseudo_table
);
1891 coff_separate_stab_sections (void)
1896 const struct format_ops coff_format_ops
=
1898 bfd_target_coff_flavour
,
1899 0, /* dfl_leading_underscore */
1900 1, /* emit_section_symbols */
1905 0, /* frob_file_before_adjust */
1906 0, /* frob_file_before_fix */
1907 coff_frob_file_after_relocs
,
1910 0, /* s_get_align */
1911 0, /* s_set_align */
1912 0, /* s_get_other */
1913 0, /* s_set_other */
1918 0, /* copy_symbol_attributes */
1919 0, /* generate_asm_lineno */
1920 0, /* process_stab */
1921 coff_separate_stab_sections
,
1922 obj_coff_init_stab_section
,
1923 0, /* sec_sym_ok_for_reloc */
1925 0, /* ecoff_set_ext */
1926 coff_obj_read_begin_hook
,
1927 coff_obj_symbol_new_hook
,
1928 coff_obj_symbol_clone_hook
,