1 /* coff object file format
2 Copyright (C) 1989-2016 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"
26 #include "struc-symbol.h"
33 #include "coff/xcoff.h"
36 #define streq(a,b) (strcmp ((a), (b)) == 0)
37 #define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
39 /* I think this is probably always correct. */
40 #ifndef KEEP_RELOC_INFO
41 #define KEEP_RELOC_INFO
44 /* obj_coff_section will use this macro to set a new section's
45 attributes when a directive has no valid flags or the "w" flag is
46 used. This default should be appropriate for most. */
47 #ifndef TC_COFF_SECTION_DEFAULT_ATTRIBUTES
48 #define TC_COFF_SECTION_DEFAULT_ATTRIBUTES (SEC_LOAD | SEC_DATA)
51 /* This is used to hold the symbol built by a sequence of pseudo-ops
52 from .def and .endef. */
53 static symbolS
*def_symbol_in_progress
;
55 /* PE weak alternate symbols begin with this string. */
56 static const char weak_altprefix
[] = ".weak.";
59 #include "obj-coff-seh.c"
63 unsigned long chunk_size
;
64 unsigned long element_size
;
67 unsigned long pointer
;
75 stack_init (unsigned long chunk_size
,
76 unsigned long element_size
)
80 st
= malloc (sizeof (* st
));
83 st
->data
= malloc (chunk_size
);
90 st
->size
= chunk_size
;
91 st
->chunk_size
= chunk_size
;
92 st
->element_size
= element_size
;
97 stack_push (stack
*st
, char *element
)
99 if (st
->pointer
+ st
->element_size
>= st
->size
)
101 st
->size
+= st
->chunk_size
;
102 if ((st
->data
= xrealloc (st
->data
, st
->size
)) == NULL
)
105 memcpy (st
->data
+ st
->pointer
, element
, st
->element_size
);
106 st
->pointer
+= st
->element_size
;
107 return st
->data
+ st
->pointer
;
111 stack_pop (stack
*st
)
113 if (st
->pointer
< st
->element_size
)
118 st
->pointer
-= st
->element_size
;
119 return st
->data
+ st
->pointer
;
122 /* Maintain a list of the tagnames of the structures. */
124 static struct hash_control
*tag_hash
;
129 tag_hash
= hash_new ();
133 tag_insert (const char *name
, symbolS
*symbolP
)
135 const char *error_string
;
137 if ((error_string
= hash_jam (tag_hash
, name
, (char *) symbolP
)))
138 as_fatal (_("Inserting \"%s\" into structure table failed: %s"),
143 tag_find (char *name
)
145 return (symbolS
*) hash_find (tag_hash
, name
);
149 tag_find_or_make (char *name
)
153 if ((symbolP
= tag_find (name
)) == NULL
)
155 symbolP
= symbol_new (name
, undefined_section
,
156 0, &zero_address_frag
);
158 tag_insert (S_GET_NAME (symbolP
), symbolP
);
159 symbol_table_insert (symbolP
);
165 /* We accept the .bss directive to set the section for backward
166 compatibility with earlier versions of gas. */
169 obj_coff_bss (int ignore ATTRIBUTE_UNUSED
)
171 if (*input_line_pointer
== '\n')
172 subseg_new (".bss", get_absolute_expression ());
178 /* Called from read.c:s_comm after we've parsed .comm symbol, size.
179 Parse a possible alignment value. */
182 obj_coff_common_parse (int ignore ATTRIBUTE_UNUSED
, symbolS
*symbolP
, addressT size
)
186 if (*input_line_pointer
== ',')
188 align
= parse_align (0);
189 if (align
== (addressT
) -1)
193 S_SET_VALUE (symbolP
, size
);
194 S_SET_EXTERNAL (symbolP
);
195 S_SET_SEGMENT (symbolP
, bfd_com_section_ptr
);
197 symbol_get_bfdsym (symbolP
)->flags
|= BSF_OBJECT
;
199 /* There is no S_SET_ALIGN (symbolP, align) in COFF/PE.
200 Instead we must add a note to the .drectve section. */
203 segT current_seg
= now_seg
;
204 subsegT current_subseg
= now_subseg
;
207 size_t pfxlen
, numlen
;
211 sec
= subseg_new (".drectve", 0);
212 oldflags
= bfd_get_section_flags (stdoutput
, sec
);
213 if (oldflags
== SEC_NO_FLAGS
)
215 if (!bfd_set_section_flags (stdoutput
, sec
,
216 TC_COFF_SECTION_DEFAULT_ATTRIBUTES
))
217 as_warn (_("error setting flags for \"%s\": %s"),
218 bfd_section_name (stdoutput
, sec
),
219 bfd_errmsg (bfd_get_error ()));
222 /* Emit a string. Note no NUL-termination. */
223 pfxlen
= strlen (" -aligncomm:") + 2 + strlen (S_GET_NAME (symbolP
)) + 1;
224 numlen
= snprintf (numbuff
, sizeof (numbuff
), "%d", (int) align
);
225 frag
= frag_more (pfxlen
+ numlen
);
226 (void) sprintf (frag
, " -aligncomm:\"%s\",", S_GET_NAME (symbolP
));
227 memcpy (frag
+ pfxlen
, numbuff
, numlen
);
228 /* Restore original subseg. */
229 subseg_set (current_seg
, current_subseg
);
236 obj_coff_comm (int ignore ATTRIBUTE_UNUSED
)
238 s_comm_internal (ignore
, obj_coff_common_parse
);
242 #define GET_FILENAME_STRING(X) \
243 ((char *) (&((X)->sy_symbol.ost_auxent->x_file.x_n.x_offset))[1])
247 fetch_coff_debug_section (void)
249 static segT debug_section
;
255 s
= bfd_make_debug_symbol (stdoutput
, NULL
, 0);
257 debug_section
= s
->section
;
259 return debug_section
;
263 SA_SET_SYM_ENDNDX (symbolS
*sym
, symbolS
*val
)
265 combined_entry_type
*entry
, *p
;
267 entry
= &coffsymbol (symbol_get_bfdsym (sym
))->native
[1];
268 p
= coffsymbol (symbol_get_bfdsym (val
))->native
;
269 entry
->u
.auxent
.x_sym
.x_fcnary
.x_fcn
.x_endndx
.p
= p
;
274 SA_SET_SYM_TAGNDX (symbolS
*sym
, symbolS
*val
)
276 combined_entry_type
*entry
, *p
;
278 entry
= &coffsymbol (symbol_get_bfdsym (sym
))->native
[1];
279 p
= coffsymbol (symbol_get_bfdsym (val
))->native
;
280 entry
->u
.auxent
.x_sym
.x_tagndx
.p
= p
;
285 S_GET_DATA_TYPE (symbolS
*sym
)
287 return coffsymbol (symbol_get_bfdsym (sym
))->native
->u
.syment
.n_type
;
291 S_SET_DATA_TYPE (symbolS
*sym
, int val
)
293 coffsymbol (symbol_get_bfdsym (sym
))->native
->u
.syment
.n_type
= val
;
298 S_GET_STORAGE_CLASS (symbolS
*sym
)
300 return coffsymbol (symbol_get_bfdsym (sym
))->native
->u
.syment
.n_sclass
;
304 S_SET_STORAGE_CLASS (symbolS
*sym
, int val
)
306 coffsymbol (symbol_get_bfdsym (sym
))->native
->u
.syment
.n_sclass
= val
;
310 /* Merge a debug symbol containing debug information into a normal symbol. */
313 c_symbol_merge (symbolS
*debug
, symbolS
*normal
)
315 S_SET_DATA_TYPE (normal
, S_GET_DATA_TYPE (debug
));
316 S_SET_STORAGE_CLASS (normal
, S_GET_STORAGE_CLASS (debug
));
318 if (S_GET_NUMBER_AUXILIARY (debug
) > S_GET_NUMBER_AUXILIARY (normal
))
319 /* Take the most we have. */
320 S_SET_NUMBER_AUXILIARY (normal
, S_GET_NUMBER_AUXILIARY (debug
));
322 if (S_GET_NUMBER_AUXILIARY (debug
) > 0)
323 /* Move all the auxiliary information. */
324 memcpy (SYM_AUXINFO (normal
), SYM_AUXINFO (debug
),
325 (S_GET_NUMBER_AUXILIARY (debug
)
326 * sizeof (*SYM_AUXINFO (debug
))));
328 /* Move the debug flags. */
329 SF_SET_DEBUG_FIELD (normal
, SF_GET_DEBUG_FIELD (debug
));
333 c_dot_file_symbol (const char *filename
, int appfile ATTRIBUTE_UNUSED
)
337 /* BFD converts filename to a .file symbol with an aux entry. It
338 also handles chaining. */
339 symbolP
= symbol_new (filename
, bfd_abs_section_ptr
, 0, &zero_address_frag
);
341 S_SET_STORAGE_CLASS (symbolP
, C_FILE
);
342 S_SET_NUMBER_AUXILIARY (symbolP
, 1);
344 symbol_get_bfdsym (symbolP
)->flags
= BSF_DEBUGGING
;
351 listing_source_file (filename
);
355 /* Make sure that the symbol is first on the symbol chain. */
356 if (symbol_rootP
!= symbolP
)
358 symbol_remove (symbolP
, &symbol_rootP
, &symbol_lastP
);
359 symbol_insert (symbolP
, symbol_rootP
, &symbol_rootP
, &symbol_lastP
);
363 /* Line number handling. */
367 struct line_no
*next
;
374 /* Symbol of last function, which we should hang line#s off of. */
375 static symbolS
*line_fsym
;
377 #define in_function() (line_fsym != 0)
378 #define clear_function() (line_fsym = 0)
379 #define set_function(F) (line_fsym = (F), coff_add_linesym (F))
383 coff_obj_symbol_new_hook (symbolS
*symbolP
)
385 long sz
= (OBJ_COFF_MAX_AUXENTRIES
+ 1) * sizeof (combined_entry_type
);
386 char * s
= xmalloc (sz
);
389 coffsymbol (symbol_get_bfdsym (symbolP
))->native
= (combined_entry_type
*) s
;
390 coffsymbol (symbol_get_bfdsym (symbolP
))->native
->is_sym
= TRUE
;
392 S_SET_DATA_TYPE (symbolP
, T_NULL
);
393 S_SET_STORAGE_CLASS (symbolP
, 0);
394 S_SET_NUMBER_AUXILIARY (symbolP
, 0);
396 if (S_IS_STRING (symbolP
))
397 SF_SET_STRING (symbolP
);
399 if (S_IS_LOCAL (symbolP
))
400 SF_SET_LOCAL (symbolP
);
404 coff_obj_symbol_clone_hook (symbolS
*newsymP
, symbolS
*orgsymP
)
406 long sz
= (OBJ_COFF_MAX_AUXENTRIES
+ 1) * sizeof (combined_entry_type
);
407 combined_entry_type
* s
= xmalloc (sz
);
409 memcpy (s
, coffsymbol (symbol_get_bfdsym (orgsymP
))->native
, sz
);
410 coffsymbol (symbol_get_bfdsym (newsymP
))->native
= s
;
412 SF_SET (newsymP
, SF_GET (orgsymP
));
416 /* Handle .ln directives. */
418 static symbolS
*current_lineno_sym
;
419 static struct line_no
*line_nos
;
420 /* FIXME: Blindly assume all .ln directives will be in the .text section. */
424 add_lineno (fragS
* frag
, addressT offset
, int num
)
426 struct line_no
* new_line
= xmalloc (sizeof (* new_line
));
428 if (!current_lineno_sym
)
432 /* The native aix assembler accepts negative line number. */
436 /* Zero is used as an end marker in the file. */
437 as_warn (_("Line numbers must be positive integers\n"));
440 #endif /* OBJ_XCOFF */
441 new_line
->next
= line_nos
;
442 new_line
->frag
= frag
;
443 new_line
->l
.line_number
= num
;
444 new_line
->l
.u
.offset
= offset
;
450 coff_add_linesym (symbolS
*sym
)
454 coffsymbol (symbol_get_bfdsym (current_lineno_sym
))->lineno
=
459 current_lineno_sym
= sym
;
463 obj_coff_ln (int appline
)
467 if (! appline
&& def_symbol_in_progress
!= NULL
)
469 as_warn (_(".ln pseudo-op inside .def/.endef: ignored."));
470 demand_empty_rest_of_line ();
474 l
= get_absolute_expression ();
476 /* If there is no lineno symbol, treat a .ln
477 directive as if it were a .appline directive. */
478 if (appline
|| current_lineno_sym
== NULL
)
479 new_logical_line ((char *) NULL
, l
- 1);
481 add_lineno (frag_now
, frag_now_fix (), l
);
490 l
+= coff_line_base
- 1;
491 listing_source_line (l
);
496 demand_empty_rest_of_line ();
499 /* .loc is essentially the same as .ln; parse it for assembler
503 obj_coff_loc (int ignore ATTRIBUTE_UNUSED
)
507 /* FIXME: Why do we need this check? We need it for ECOFF, but why
508 do we need it for COFF? */
509 if (now_seg
!= text_section
)
511 as_warn (_(".loc outside of .text"));
512 demand_empty_rest_of_line ();
516 if (def_symbol_in_progress
!= NULL
)
518 as_warn (_(".loc pseudo-op inside .def/.endef: ignored."));
519 demand_empty_rest_of_line ();
523 /* Skip the file number. */
525 get_absolute_expression ();
528 lineno
= get_absolute_expression ();
536 lineno
+= coff_line_base
- 1;
537 listing_source_line (lineno
);
542 demand_empty_rest_of_line ();
544 add_lineno (frag_now
, frag_now_fix (), lineno
);
547 /* Handle the .ident pseudo-op. */
550 obj_coff_ident (int ignore ATTRIBUTE_UNUSED
)
552 segT current_seg
= now_seg
;
553 subsegT current_subseg
= now_subseg
;
559 /* We could put it in .comment, but that creates an extra section
560 that shouldn't be loaded into memory, which requires linker
561 changes... For now, until proven otherwise, use .rdata. */
562 sec
= subseg_new (".rdata$zzz", 0);
563 bfd_set_section_flags (stdoutput
, sec
,
564 ((SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
| SEC_DATA
)
565 & bfd_applicable_section_flags (stdoutput
)));
568 subseg_new (".comment", 0);
572 subseg_set (current_seg
, current_subseg
);
575 /* Handle .def directives.
577 One might ask : why can't we symbol_new if the symbol does not
578 already exist and fill it with debug information. Because of
579 the C_EFCN special symbol. It would clobber the value of the
580 function symbol before we have a chance to notice that it is
581 a C_EFCN. And a second reason is that the code is more clear this
582 way. (at least I think it is :-). */
584 #define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';')
585 #define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \
586 *input_line_pointer == '\t') \
587 input_line_pointer++;
590 obj_coff_def (int what ATTRIBUTE_UNUSED
)
592 char name_end
; /* Char after the end of name. */
593 char *symbol_name
; /* Name of the debug symbol. */
594 char *symbol_name_copy
; /* Temporary copy of the name. */
596 if (def_symbol_in_progress
!= NULL
)
598 as_warn (_(".def pseudo-op used inside of .def/.endef: ignored."));
599 demand_empty_rest_of_line ();
605 name_end
= get_symbol_name (&symbol_name
);
606 symbol_name_copy
= xstrdup (symbol_name
);
607 #ifdef tc_canonicalize_symbol_name
608 symbol_name_copy
= tc_canonicalize_symbol_name (symbol_name_copy
);
611 /* Initialize the new symbol. */
612 def_symbol_in_progress
= symbol_make (symbol_name_copy
);
613 symbol_set_frag (def_symbol_in_progress
, &zero_address_frag
);
614 S_SET_VALUE (def_symbol_in_progress
, 0);
616 if (S_IS_STRING (def_symbol_in_progress
))
617 SF_SET_STRING (def_symbol_in_progress
);
619 (void) restore_line_pointer (name_end
);
621 demand_empty_rest_of_line ();
625 obj_coff_endef (int ignore ATTRIBUTE_UNUSED
)
627 symbolS
*symbolP
= NULL
;
629 if (def_symbol_in_progress
== NULL
)
631 as_warn (_(".endef pseudo-op used outside of .def/.endef: ignored."));
632 demand_empty_rest_of_line ();
636 /* Set the section number according to storage class. */
637 switch (S_GET_STORAGE_CLASS (def_symbol_in_progress
))
642 SF_SET_TAG (def_symbol_in_progress
);
646 SF_SET_DEBUG (def_symbol_in_progress
);
647 S_SET_SEGMENT (def_symbol_in_progress
, fetch_coff_debug_section ());
651 SF_SET_LOCAL (def_symbol_in_progress
); /* Do not emit this symbol. */
654 SF_SET_PROCESS (def_symbol_in_progress
); /* Will need processing before writing. */
660 S_SET_SEGMENT (def_symbol_in_progress
, text_section
);
662 name
= S_GET_NAME (def_symbol_in_progress
);
663 if (name
[0] == '.' && name
[2] == 'f' && name
[3] == '\0')
669 if (! in_function ())
670 as_warn (_("`%s' symbol without preceding function"), name
);
671 /* Will need relocating. */
672 SF_SET_PROCESS (def_symbol_in_progress
);
678 /* The MS compilers output the actual endline, not the
679 function-relative one... we want to match without
680 changing the assembler input. */
681 SA_SET_SYM_LNNO (def_symbol_in_progress
,
682 (SA_GET_SYM_LNNO (def_symbol_in_progress
)
693 #endif /* C_AUTOARG */
700 /* According to the COFF documentation:
702 http://osr5doc.sco.com:1996/topics/COFF_SectNumFld.html
704 A special section number (-2) marks symbolic debugging symbols,
705 including structure/union/enumeration tag names, typedefs, and
706 the name of the file. A section number of -1 indicates that the
707 symbol has a value but is not relocatable. Examples of
708 absolute-valued symbols include automatic and register variables,
709 function arguments, and .eos symbols.
711 But from Ian Lance Taylor:
713 http://sources.redhat.com/ml/binutils/2000-08/msg00202.html
715 the actual tools all marked them as section -1. So the GNU COFF
716 assembler follows historical COFF assemblers.
718 However, it causes problems for djgpp
720 http://sources.redhat.com/ml/binutils/2000-08/msg00210.html
722 By defining STRICTCOFF, a COFF port can make the assembler to
723 follow the documented behavior. */
730 SF_SET_DEBUG (def_symbol_in_progress
);
731 S_SET_SEGMENT (def_symbol_in_progress
, absolute_section
);
739 S_SET_SEGMENT (def_symbol_in_progress
, absolute_section
);
750 /* Valid but set somewhere else (s_comm, s_lcomm, colon). */
757 as_warn (_("unexpected storage class %d"),
758 S_GET_STORAGE_CLASS (def_symbol_in_progress
));
762 /* Now that we have built a debug symbol, try to find if we should
763 merge with an existing symbol or not. If a symbol is C_EFCN or
764 absolute_section or untagged SEG_DEBUG it never merges. We also
765 don't merge labels, which are in a different namespace, nor
766 symbols which have not yet been defined since they are typically
767 unique, nor do we merge tags with non-tags. */
769 /* Two cases for functions. Either debug followed by definition or
770 definition followed by debug. For definition first, we will
771 merge the debug symbol into the definition. For debug first, the
772 lineno entry MUST point to the definition function or else it
773 will point off into space when obj_crawl_symbol_chain() merges
774 the debug symbol into the real symbol. Therefor, let's presume
775 the debug symbol is a real function reference. */
777 /* FIXME-SOON If for some reason the definition label/symbol is
778 never seen, this will probably leave an undefined symbol at link
781 if (S_GET_STORAGE_CLASS (def_symbol_in_progress
) == C_EFCN
782 || S_GET_STORAGE_CLASS (def_symbol_in_progress
) == C_LABEL
783 || (streq (bfd_get_section_name (stdoutput
,
784 S_GET_SEGMENT (def_symbol_in_progress
)),
786 && !SF_GET_TAG (def_symbol_in_progress
))
787 || S_GET_SEGMENT (def_symbol_in_progress
) == absolute_section
788 || ! symbol_constant_p (def_symbol_in_progress
)
789 || (symbolP
= symbol_find (S_GET_NAME (def_symbol_in_progress
))) == NULL
790 || SF_GET_TAG (def_symbol_in_progress
) != SF_GET_TAG (symbolP
))
792 /* If it already is at the end of the symbol list, do nothing */
793 if (def_symbol_in_progress
!= symbol_lastP
)
795 symbol_remove (def_symbol_in_progress
, &symbol_rootP
, &symbol_lastP
);
796 symbol_append (def_symbol_in_progress
, symbol_lastP
, &symbol_rootP
,
802 /* This symbol already exists, merge the newly created symbol
803 into the old one. This is not mandatory. The linker can
804 handle duplicate symbols correctly. But I guess that it save
805 a *lot* of space if the assembly file defines a lot of
808 /* The debug entry (def_symbol_in_progress) is merged into the
809 previous definition. */
811 c_symbol_merge (def_symbol_in_progress
, symbolP
);
812 symbol_remove (def_symbol_in_progress
, &symbol_rootP
, &symbol_lastP
);
814 def_symbol_in_progress
= symbolP
;
816 if (SF_GET_FUNCTION (def_symbol_in_progress
)
817 || SF_GET_TAG (def_symbol_in_progress
)
818 || S_GET_STORAGE_CLASS (def_symbol_in_progress
) == C_STAT
)
820 /* For functions, and tags, and static symbols, the symbol
821 *must* be where the debug symbol appears. Move the
822 existing symbol to the current place. */
823 /* If it already is at the end of the symbol list, do nothing. */
824 if (def_symbol_in_progress
!= symbol_lastP
)
826 symbol_remove (def_symbol_in_progress
, &symbol_rootP
, &symbol_lastP
);
827 symbol_append (def_symbol_in_progress
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
832 if (SF_GET_TAG (def_symbol_in_progress
))
836 oldtag
= symbol_find (S_GET_NAME (def_symbol_in_progress
));
837 if (oldtag
== NULL
|| ! SF_GET_TAG (oldtag
))
838 tag_insert (S_GET_NAME (def_symbol_in_progress
),
839 def_symbol_in_progress
);
842 if (SF_GET_FUNCTION (def_symbol_in_progress
))
844 set_function (def_symbol_in_progress
);
845 SF_SET_PROCESS (def_symbol_in_progress
);
848 /* That is, if this is the first time we've seen the
850 symbol_table_insert (def_symbol_in_progress
);
854 def_symbol_in_progress
= NULL
;
855 demand_empty_rest_of_line ();
859 obj_coff_dim (int ignore ATTRIBUTE_UNUSED
)
863 if (def_symbol_in_progress
== NULL
)
865 as_warn (_(".dim pseudo-op used outside of .def/.endef: ignored."));
866 demand_empty_rest_of_line ();
870 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress
, 1);
872 for (d_index
= 0; d_index
< DIMNUM
; d_index
++)
875 SA_SET_SYM_DIMEN (def_symbol_in_progress
, d_index
,
876 get_absolute_expression ());
878 switch (*input_line_pointer
)
881 input_line_pointer
++;
885 as_warn (_("badly formed .dim directive ignored"));
894 demand_empty_rest_of_line ();
898 obj_coff_line (int ignore ATTRIBUTE_UNUSED
)
902 if (def_symbol_in_progress
== NULL
)
904 /* Probably stabs-style line? */
909 this_base
= get_absolute_expression ();
910 if (streq (".bf", S_GET_NAME (def_symbol_in_progress
)))
911 coff_line_base
= this_base
;
913 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress
, 1);
914 SA_SET_SYM_LNNO (def_symbol_in_progress
, this_base
);
916 demand_empty_rest_of_line ();
919 if (streq (".bf", S_GET_NAME (def_symbol_in_progress
)))
924 listing_source_line ((unsigned int) this_base
);
930 obj_coff_size (int ignore ATTRIBUTE_UNUSED
)
932 if (def_symbol_in_progress
== NULL
)
934 as_warn (_(".size pseudo-op used outside of .def/.endef ignored."));
935 demand_empty_rest_of_line ();
939 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress
, 1);
940 SA_SET_SYM_SIZE (def_symbol_in_progress
, get_absolute_expression ());
941 demand_empty_rest_of_line ();
945 obj_coff_scl (int ignore ATTRIBUTE_UNUSED
)
947 if (def_symbol_in_progress
== NULL
)
949 as_warn (_(".scl pseudo-op used outside of .def/.endef ignored."));
950 demand_empty_rest_of_line ();
954 S_SET_STORAGE_CLASS (def_symbol_in_progress
, get_absolute_expression ());
955 demand_empty_rest_of_line ();
959 obj_coff_tag (int ignore ATTRIBUTE_UNUSED
)
964 if (def_symbol_in_progress
== NULL
)
966 as_warn (_(".tag pseudo-op used outside of .def/.endef ignored."));
967 demand_empty_rest_of_line ();
971 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress
, 1);
972 name_end
= get_symbol_name (&symbol_name
);
974 #ifdef tc_canonicalize_symbol_name
975 symbol_name
= tc_canonicalize_symbol_name (symbol_name
);
978 /* Assume that the symbol referred to by .tag is always defined.
979 This was a bad assumption. I've added find_or_make. xoxorich. */
980 SA_SET_SYM_TAGNDX (def_symbol_in_progress
,
981 tag_find_or_make (symbol_name
));
982 if (SA_GET_SYM_TAGNDX (def_symbol_in_progress
) == 0L)
983 as_warn (_("tag not found for .tag %s"), symbol_name
);
985 SF_SET_TAGGED (def_symbol_in_progress
);
987 (void) restore_line_pointer (name_end
);
988 demand_empty_rest_of_line ();
992 obj_coff_type (int ignore ATTRIBUTE_UNUSED
)
994 if (def_symbol_in_progress
== NULL
)
996 as_warn (_(".type pseudo-op used outside of .def/.endef ignored."));
997 demand_empty_rest_of_line ();
1001 S_SET_DATA_TYPE (def_symbol_in_progress
, get_absolute_expression ());
1003 if (ISFCN (S_GET_DATA_TYPE (def_symbol_in_progress
)) &&
1004 S_GET_STORAGE_CLASS (def_symbol_in_progress
) != C_TPDEF
)
1005 SF_SET_FUNCTION (def_symbol_in_progress
);
1007 demand_empty_rest_of_line ();
1011 obj_coff_val (int ignore ATTRIBUTE_UNUSED
)
1013 if (def_symbol_in_progress
== NULL
)
1015 as_warn (_(".val pseudo-op used outside of .def/.endef ignored."));
1016 demand_empty_rest_of_line ();
1020 if (is_name_beginner (*input_line_pointer
))
1023 char name_end
= get_symbol_name (&symbol_name
);
1025 #ifdef tc_canonicalize_symbol_name
1026 symbol_name
= tc_canonicalize_symbol_name (symbol_name
);
1028 if (streq (symbol_name
, "."))
1030 /* If the .val is != from the .def (e.g. statics). */
1031 symbol_set_frag (def_symbol_in_progress
, frag_now
);
1032 S_SET_VALUE (def_symbol_in_progress
, (valueT
) frag_now_fix ());
1034 else if (! streq (S_GET_NAME (def_symbol_in_progress
), symbol_name
))
1038 exp
.X_op
= O_symbol
;
1039 exp
.X_add_symbol
= symbol_find_or_make (symbol_name
);
1040 exp
.X_op_symbol
= NULL
;
1041 exp
.X_add_number
= 0;
1042 symbol_set_value_expression (def_symbol_in_progress
, &exp
);
1044 /* If the segment is undefined when the forward reference is
1045 resolved, then copy the segment id from the forward
1047 SF_SET_GET_SEGMENT (def_symbol_in_progress
);
1049 /* FIXME: gcc can generate address expressions here in
1050 unusual cases (search for "obscure" in sdbout.c). We
1051 just ignore the offset here, thus generating incorrect
1052 debugging information. We ignore the rest of the line
1055 /* Otherwise, it is the name of a non debug symbol and its value
1056 will be calculated later. */
1057 (void) restore_line_pointer (name_end
);
1061 S_SET_VALUE (def_symbol_in_progress
, get_absolute_expression ());
1064 demand_empty_rest_of_line ();
1069 /* Return nonzero if name begins with weak alternate symbol prefix. */
1072 weak_is_altname (const char * name
)
1074 return strneq (name
, weak_altprefix
, sizeof (weak_altprefix
) - 1);
1077 /* Return the name of the alternate symbol
1078 name corresponding to a weak symbol's name. */
1081 weak_name2altname (const char * name
)
1083 return concat (weak_altprefix
, name
, (char *) NULL
);
1086 /* Return the name of the weak symbol corresponding to an
1087 alternate symbol. */
1090 weak_altname2name (const char * name
)
1092 gas_assert (weak_is_altname (name
));
1093 return xstrdup (name
+ 6);
1096 /* Make a weak symbol name unique by
1097 appending the name of an external symbol. */
1100 weak_uniquify (const char * name
)
1103 const char * unique
= "";
1106 if (an_external_name
!= NULL
)
1107 unique
= an_external_name
;
1109 gas_assert (weak_is_altname (name
));
1111 return concat (name
, ".", unique
, (char *) NULL
);
1115 pecoff_obj_set_weak_hook (symbolS
*symbolP
)
1117 symbolS
*alternateP
;
1119 /* See _Microsoft Portable Executable and Common Object
1120 File Format Specification_, section 5.5.3.
1121 Create a symbol representing the alternate value.
1122 coff_frob_symbol will set the value of this symbol from
1123 the value of the weak symbol itself. */
1124 S_SET_STORAGE_CLASS (symbolP
, C_NT_WEAK
);
1125 S_SET_NUMBER_AUXILIARY (symbolP
, 1);
1126 SA_SET_SYM_FSIZE (symbolP
, IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY
);
1128 alternateP
= symbol_find_or_make (weak_name2altname (S_GET_NAME (symbolP
)));
1129 S_SET_EXTERNAL (alternateP
);
1130 S_SET_STORAGE_CLASS (alternateP
, C_NT_WEAK
);
1132 SA_SET_SYM_TAGNDX (symbolP
, alternateP
);
1136 pecoff_obj_clear_weak_hook (symbolS
*symbolP
)
1138 symbolS
*alternateP
;
1140 S_SET_STORAGE_CLASS (symbolP
, 0);
1141 SA_SET_SYM_FSIZE (symbolP
, 0);
1143 alternateP
= symbol_find (weak_name2altname (S_GET_NAME (symbolP
)));
1144 S_CLEAR_EXTERNAL (alternateP
);
1149 /* Handle .weak. This is a GNU extension in formats other than PE. */
1152 obj_coff_weak (int ignore ATTRIBUTE_UNUSED
)
1160 c
= get_symbol_name (&name
);
1163 as_warn (_("badly formed .weak directive ignored"));
1164 ignore_rest_of_line ();
1168 symbolP
= symbol_find_or_make (name
);
1169 *input_line_pointer
= c
;
1170 SKIP_WHITESPACE_AFTER_NAME ();
1171 S_SET_WEAK (symbolP
);
1175 input_line_pointer
++;
1177 if (*input_line_pointer
== '\n')
1184 demand_empty_rest_of_line ();
1188 coff_obj_read_begin_hook (void)
1190 /* These had better be the same. Usually 18 bytes. */
1191 know (sizeof (SYMENT
) == sizeof (AUXENT
));
1192 know (SYMESZ
== AUXESZ
);
1196 symbolS
*coff_last_function
;
1198 static symbolS
*coff_last_bf
;
1202 coff_frob_symbol (symbolS
*symp
, int *punt
)
1204 static symbolS
*last_tagP
;
1205 static stack
*block_stack
;
1206 static symbolS
*set_end
;
1207 symbolS
*next_set_end
= NULL
;
1209 if (symp
== &abs_symbol
)
1215 if (current_lineno_sym
)
1216 coff_add_linesym (NULL
);
1219 block_stack
= stack_init (512, sizeof (symbolS
*));
1222 if (S_GET_STORAGE_CLASS (symp
) == C_NT_WEAK
1223 && ! S_IS_WEAK (symp
)
1224 && weak_is_altname (S_GET_NAME (symp
)))
1226 /* This is a weak alternate symbol. All processing of
1227 PECOFFweak symbols is done here, through the alternate. */
1228 symbolS
*weakp
= symbol_find_noref (weak_altname2name
1229 (S_GET_NAME (symp
)), 1);
1232 gas_assert (S_GET_NUMBER_AUXILIARY (weakp
) == 1);
1234 if (! S_IS_WEAK (weakp
))
1236 /* The symbol was turned from weak to strong. Discard altname. */
1240 else if (symbol_equated_p (weakp
))
1242 /* The weak symbol has an alternate specified; symp is unneeded. */
1243 S_SET_STORAGE_CLASS (weakp
, C_NT_WEAK
);
1244 SA_SET_SYM_TAGNDX (weakp
,
1245 symbol_get_value_expression (weakp
)->X_add_symbol
);
1247 S_CLEAR_EXTERNAL (symp
);
1253 /* The weak symbol has been assigned an alternate value.
1254 Copy this value to symp, and set symp as weakp's alternate. */
1255 if (S_GET_STORAGE_CLASS (weakp
) != C_NT_WEAK
)
1257 S_SET_STORAGE_CLASS (symp
, S_GET_STORAGE_CLASS (weakp
));
1258 S_SET_STORAGE_CLASS (weakp
, C_NT_WEAK
);
1261 if (S_IS_DEFINED (weakp
))
1263 /* This is a defined weak symbol. Copy value information
1264 from the weak symbol itself to the alternate symbol. */
1265 symbol_set_value_expression (symp
,
1266 symbol_get_value_expression (weakp
));
1267 symbol_set_frag (symp
, symbol_get_frag (weakp
));
1268 S_SET_SEGMENT (symp
, S_GET_SEGMENT (weakp
));
1272 /* This is an undefined weak symbol.
1273 Define the alternate symbol to zero. */
1274 S_SET_VALUE (symp
, 0);
1275 S_SET_SEGMENT (symp
, absolute_section
);
1278 S_SET_NAME (symp
, weak_uniquify (S_GET_NAME (symp
)));
1279 S_SET_STORAGE_CLASS (symp
, C_EXT
);
1281 S_SET_VALUE (weakp
, 0);
1282 S_SET_SEGMENT (weakp
, undefined_section
);
1286 if (S_IS_WEAK (symp
))
1287 S_SET_STORAGE_CLASS (symp
, C_WEAKEXT
);
1290 if (!S_IS_DEFINED (symp
)
1291 && !S_IS_WEAK (symp
)
1292 && S_GET_STORAGE_CLASS (symp
) != C_STAT
)
1293 S_SET_STORAGE_CLASS (symp
, C_EXT
);
1295 if (!SF_GET_DEBUG (symp
))
1299 if (!SF_GET_LOCAL (symp
)
1300 && !SF_GET_STATICS (symp
)
1301 && S_GET_STORAGE_CLASS (symp
) != C_LABEL
1302 && symbol_constant_p (symp
)
1303 && (real
= symbol_find_noref (S_GET_NAME (symp
), 1))
1304 && S_GET_STORAGE_CLASS (real
) == C_NULL
1307 c_symbol_merge (symp
, real
);
1312 if (!S_IS_DEFINED (symp
) && !SF_GET_LOCAL (symp
))
1314 gas_assert (S_GET_VALUE (symp
) == 0);
1315 if (S_IS_WEAKREFD (symp
))
1318 S_SET_EXTERNAL (symp
);
1320 else if (S_GET_STORAGE_CLASS (symp
) == C_NULL
)
1322 if (S_GET_SEGMENT (symp
) == text_section
1323 && symp
!= seg_info (text_section
)->sym
)
1324 S_SET_STORAGE_CLASS (symp
, C_LABEL
);
1326 S_SET_STORAGE_CLASS (symp
, C_STAT
);
1329 if (SF_GET_PROCESS (symp
))
1331 if (S_GET_STORAGE_CLASS (symp
) == C_BLOCK
)
1333 if (streq (S_GET_NAME (symp
), ".bb"))
1334 stack_push (block_stack
, (char *) &symp
);
1339 begin
= *(symbolS
**) stack_pop (block_stack
);
1341 as_warn (_("mismatched .eb"));
1343 next_set_end
= begin
;
1347 if (coff_last_function
== 0 && SF_GET_FUNCTION (symp
)
1348 && S_IS_DEFINED (symp
))
1350 union internal_auxent
*auxp
;
1352 coff_last_function
= symp
;
1353 if (S_GET_NUMBER_AUXILIARY (symp
) < 1)
1354 S_SET_NUMBER_AUXILIARY (symp
, 1);
1355 auxp
= SYM_AUXENT (symp
);
1356 memset (auxp
->x_sym
.x_fcnary
.x_ary
.x_dimen
, 0,
1357 sizeof (auxp
->x_sym
.x_fcnary
.x_ary
.x_dimen
));
1360 if (S_GET_STORAGE_CLASS (symp
) == C_EFCN
1361 && S_IS_DEFINED (symp
))
1363 if (coff_last_function
== 0)
1364 as_fatal (_("C_EFCN symbol for %s out of scope"),
1366 SA_SET_SYM_FSIZE (coff_last_function
,
1367 (long) (S_GET_VALUE (symp
)
1368 - S_GET_VALUE (coff_last_function
)));
1369 next_set_end
= coff_last_function
;
1370 coff_last_function
= 0;
1374 if (S_IS_EXTERNAL (symp
))
1375 S_SET_STORAGE_CLASS (symp
, C_EXT
);
1376 else if (SF_GET_LOCAL (symp
))
1379 if (SF_GET_FUNCTION (symp
))
1380 symbol_get_bfdsym (symp
)->flags
|= BSF_FUNCTION
;
1383 /* Double check weak symbols. */
1384 if (S_IS_WEAK (symp
) && S_IS_COMMON (symp
))
1385 as_bad (_("Symbol `%s' can not be both weak and common"),
1388 if (SF_GET_TAG (symp
))
1390 else if (S_GET_STORAGE_CLASS (symp
) == C_EOS
)
1391 next_set_end
= last_tagP
;
1394 /* This is pretty horrible, but we have to set *punt correctly in
1395 order to call SA_SET_SYM_ENDNDX correctly. */
1396 if (! symbol_used_in_reloc_p (symp
)
1397 && ((symbol_get_bfdsym (symp
)->flags
& BSF_SECTION_SYM
) != 0
1398 || (! (S_IS_EXTERNAL (symp
) || S_IS_WEAK (symp
))
1399 && ! symbol_get_tc (symp
)->output
1400 && S_GET_STORAGE_CLASS (symp
) != C_FILE
)))
1404 if (set_end
!= (symbolS
*) NULL
1406 && ((symbol_get_bfdsym (symp
)->flags
& BSF_NOT_AT_END
) != 0
1407 || (S_IS_DEFINED (symp
)
1408 && ! S_IS_COMMON (symp
)
1409 && (! S_IS_EXTERNAL (symp
) || SF_GET_FUNCTION (symp
)))))
1411 SA_SET_SYM_ENDNDX (set_end
, symp
);
1415 if (next_set_end
!= NULL
)
1417 if (set_end
!= NULL
)
1418 as_warn (_("Warning: internal error: forgetting to set endndx of %s"),
1419 S_GET_NAME (set_end
));
1420 set_end
= next_set_end
;
1425 && S_GET_STORAGE_CLASS (symp
) == C_FCN
1426 && streq (S_GET_NAME (symp
), ".bf"))
1428 if (coff_last_bf
!= NULL
)
1429 SA_SET_SYM_ENDNDX (coff_last_bf
, symp
);
1430 coff_last_bf
= symp
;
1433 if (coffsymbol (symbol_get_bfdsym (symp
))->lineno
)
1436 struct line_no
*lptr
;
1439 lptr
= (struct line_no
*) coffsymbol (symbol_get_bfdsym (symp
))->lineno
;
1440 for (i
= 0; lptr
; lptr
= lptr
->next
)
1442 lptr
= (struct line_no
*) coffsymbol (symbol_get_bfdsym (symp
))->lineno
;
1444 /* We need i entries for line numbers, plus 1 for the first
1445 entry which BFD will override, plus 1 for the last zero
1446 entry (a marker for BFD). */
1447 l
= xmalloc ((i
+ 2) * sizeof (* l
));
1448 coffsymbol (symbol_get_bfdsym (symp
))->lineno
= l
;
1449 l
[i
+ 1].line_number
= 0;
1450 l
[i
+ 1].u
.sym
= NULL
;
1454 lptr
->l
.u
.offset
+= lptr
->frag
->fr_address
/ OCTETS_PER_BYTE
;
1462 coff_adjust_section_syms (bfd
*abfd ATTRIBUTE_UNUSED
,
1464 void * x ATTRIBUTE_UNUSED
)
1467 segment_info_type
*seginfo
= seg_info (sec
);
1468 int nlnno
, nrelocs
= 0;
1470 /* RS/6000 gas creates a .debug section manually in ppc_frob_file in
1471 tc-ppc.c. Do not get confused by it. */
1472 if (seginfo
== NULL
)
1475 if (streq (sec
->name
, ".text"))
1476 nlnno
= coff_n_line_nos
;
1480 /* @@ Hope that none of the fixups expand to more than one reloc
1482 fixS
*fixp
= seginfo
->fix_root
;
1485 if (! fixp
->fx_done
)
1487 fixp
= fixp
->fx_next
;
1490 if (bfd_get_section_size (sec
) == 0
1493 && sec
!= text_section
1494 && sec
!= data_section
1495 && sec
!= bss_section
)
1498 secsym
= section_symbol (sec
);
1499 /* This is an estimate; we'll plug in the real value using
1500 SET_SECTION_RELOCS later */
1501 SA_SET_SCN_NRELOC (secsym
, nrelocs
);
1502 SA_SET_SCN_NLINNO (secsym
, nlnno
);
1506 coff_frob_file_after_relocs (void)
1508 bfd_map_over_sections (stdoutput
, coff_adjust_section_syms
, NULL
);
1511 /* Implement the .section pseudo op:
1512 .section name {, "flags"}
1514 | +--- optional flags: 'b' for bss
1516 +-- section name 'l' for lib
1520 'd' (apparently m88k for data)
1523 'r' for read-only data
1524 's' for shared data (PE)
1526 '0' - '9' for power-of-two alignment (GNU extension).
1527 But if the argument is not a quoted string, treat it as a
1530 Note the 'a' flag is silently ignored. This allows the same
1531 .section directive to be parsed in both ELF and COFF formats. */
1534 obj_coff_section (int ignore ATTRIBUTE_UNUSED
)
1536 /* Strip out the section name. */
1542 flagword flags
, oldflags
;
1553 c
= get_symbol_name (§ion_name
);
1554 name
= xmemdup0 (section_name
, input_line_pointer
- section_name
);
1555 *input_line_pointer
= c
;
1556 SKIP_WHITESPACE_AFTER_NAME ();
1559 flags
= SEC_NO_FLAGS
;
1561 if (*input_line_pointer
== ',')
1563 ++input_line_pointer
;
1565 if (*input_line_pointer
!= '"')
1566 exp
= get_absolute_expression ();
1570 int readonly_removed
= 0;
1571 int load_removed
= 0;
1573 while (attr
= *++input_line_pointer
,
1575 && ! is_end_of_line
[attr
])
1579 alignment
= attr
- '0';
1585 /* Exclude section from linking. */
1586 flags
|= SEC_EXCLUDE
;
1590 /* Uninitialised data section. */
1596 /* Section not loaded. */
1598 flags
|= SEC_NEVER_LOAD
;
1603 /* Shared section. */
1604 flags
|= SEC_COFF_SHARED
;
1611 flags
&=~ SEC_READONLY
;
1615 /* Writable section. */
1616 flags
&=~ SEC_READONLY
;
1617 readonly_removed
= 1;
1621 /* Ignore. Here for compatibility with ELF. */
1624 case 'r': /* Read-only section. Implies a data section. */
1625 readonly_removed
= 0;
1627 case 'x': /* Executable section. */
1628 /* If we are setting the 'x' attribute or if the 'r'
1629 attribute is being used to restore the readonly status
1630 of a code section (eg "wxr") then set the SEC_CODE flag,
1631 otherwise set the SEC_DATA flag. */
1632 flags
|= (attr
== 'x' || (flags
& SEC_CODE
) ? SEC_CODE
: SEC_DATA
);
1635 /* Note - the READONLY flag is set here, even for the 'x'
1636 attribute in order to be compatible with the MSVC
1638 if (! readonly_removed
)
1639 flags
|= SEC_READONLY
;
1643 flags
|= SEC_COFF_NOREAD
| SEC_READONLY
;
1646 case 'i': /* STYP_INFO */
1647 case 'l': /* STYP_LIB */
1648 case 'o': /* STYP_OVER */
1649 as_warn (_("unsupported section attribute '%c'"), attr
);
1653 as_warn (_("unknown section attribute '%c'"), attr
);
1658 ++input_line_pointer
;
1662 sec
= subseg_new (name
, (subsegT
) exp
);
1665 sec
->alignment_power
= alignment
;
1667 oldflags
= bfd_get_section_flags (stdoutput
, sec
);
1668 if (oldflags
== SEC_NO_FLAGS
)
1670 /* Set section flags for a new section just created by subseg_new.
1671 Provide a default if no flags were parsed. */
1672 if (flags
== SEC_NO_FLAGS
)
1673 flags
= TC_COFF_SECTION_DEFAULT_ATTRIBUTES
;
1675 #ifdef COFF_LONG_SECTION_NAMES
1676 /* Add SEC_LINK_ONCE and SEC_LINK_DUPLICATES_DISCARD to .gnu.linkonce
1677 sections so adjust_reloc_syms in write.c will correctly handle
1678 relocs which refer to non-local symbols in these sections. */
1679 if (strneq (name
, ".gnu.linkonce", sizeof (".gnu.linkonce") - 1))
1680 flags
|= SEC_LINK_ONCE
| SEC_LINK_DUPLICATES_DISCARD
;
1683 if (! bfd_set_section_flags (stdoutput
, sec
, flags
))
1684 as_warn (_("error setting flags for \"%s\": %s"),
1685 bfd_section_name (stdoutput
, sec
),
1686 bfd_errmsg (bfd_get_error ()));
1688 else if (flags
!= SEC_NO_FLAGS
)
1690 /* This section's attributes have already been set. Warn if the
1691 attributes don't match. */
1692 flagword matchflags
= (SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
| SEC_CODE
1693 | SEC_DATA
| SEC_COFF_SHARED
| SEC_NEVER_LOAD
1695 if ((flags
^ oldflags
) & matchflags
)
1696 as_warn (_("Ignoring changed section attributes for %s"), name
);
1699 demand_empty_rest_of_line ();
1703 coff_adjust_symtab (void)
1705 if (symbol_rootP
== NULL
1706 || S_GET_STORAGE_CLASS (symbol_rootP
) != C_FILE
)
1707 c_dot_file_symbol ("fake", 0);
1711 coff_frob_section (segT sec
)
1718 /* The COFF back end in BFD requires that all section sizes be
1719 rounded up to multiples of the corresponding section alignments,
1720 supposedly because standard COFF has no other way of encoding alignment
1721 for sections. If your COFF flavor has a different way of encoding
1722 section alignment, then skip this step, as TICOFF does. */
1723 bfd_vma size
= bfd_get_section_size (sec
);
1724 #if !defined(TICOFF)
1725 bfd_vma align_power
= (bfd_vma
) sec
->alignment_power
+ OCTETS_PER_BYTE_POWER
;
1726 bfd_vma mask
= ((bfd_vma
) 1 << align_power
) - 1;
1733 new_size
= (size
+ mask
) & ~mask
;
1734 bfd_set_section_size (stdoutput
, sec
, new_size
);
1736 /* If the size had to be rounded up, add some padding in
1737 the last non-empty frag. */
1738 fragp
= seg_info (sec
)->frchainP
->frch_root
;
1739 last
= seg_info (sec
)->frchainP
->frch_last
;
1740 while (fragp
->fr_next
!= last
)
1741 fragp
= fragp
->fr_next
;
1742 last
->fr_address
= size
;
1743 fragp
->fr_offset
+= new_size
- size
;
1747 /* If the section size is non-zero, the section symbol needs an aux
1748 entry associated with it, indicating the size. We don't know
1749 all the values yet; coff_frob_symbol will fill them in later. */
1752 || sec
== text_section
1753 || sec
== data_section
1754 || sec
== bss_section
)
1757 symbolS
*secsym
= section_symbol (sec
);
1758 unsigned char sclass
= C_STAT
;
1761 if (bfd_get_section_flags (stdoutput
, sec
) & SEC_DEBUGGING
)
1764 S_SET_STORAGE_CLASS (secsym
, sclass
);
1765 S_SET_NUMBER_AUXILIARY (secsym
, 1);
1766 SF_SET_STATICS (secsym
);
1767 SA_SET_SCN_SCNLEN (secsym
, size
);
1769 /* FIXME: These should be in a "stabs.h" file, or maybe as.h. */
1770 #ifndef STAB_SECTION_NAME
1771 #define STAB_SECTION_NAME ".stab"
1773 #ifndef STAB_STRING_SECTION_NAME
1774 #define STAB_STRING_SECTION_NAME ".stabstr"
1776 if (! streq (STAB_STRING_SECTION_NAME
, sec
->name
))
1780 sec
= subseg_get (STAB_SECTION_NAME
, 0);
1781 /* size is already rounded up, since other section will be listed first */
1782 size
= bfd_get_section_size (strsec
);
1784 n_entries
= bfd_get_section_size (sec
) / 12 - 1;
1786 /* Find first non-empty frag. It should be large enough. */
1787 fragp
= seg_info (sec
)->frchainP
->frch_root
;
1788 while (fragp
&& fragp
->fr_fix
== 0)
1789 fragp
= fragp
->fr_next
;
1790 gas_assert (fragp
!= 0 && fragp
->fr_fix
>= 12);
1792 /* Store the values. */
1793 p
= fragp
->fr_literal
;
1794 bfd_h_put_16 (stdoutput
, n_entries
, (bfd_byte
*) p
+ 6);
1795 bfd_h_put_32 (stdoutput
, size
, (bfd_byte
*) p
+ 8);
1799 obj_coff_init_stab_section (segT seg
)
1804 unsigned int stroff
;
1806 /* Make space for this first symbol. */
1810 file
= as_where ((unsigned int *) NULL
);
1811 stabstr_name
= concat (seg
->name
, "str", (char *) NULL
);
1812 stroff
= get_stab_string_offset (file
, stabstr_name
);
1814 md_number_to_chars (p
, stroff
, 4);
1818 const char * s_get_name (symbolS
*);
1821 s_get_name (symbolS
*s
)
1823 return ((s
== NULL
) ? "(NULL)" : S_GET_NAME (s
));
1826 void symbol_dump (void);
1833 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
1834 printf (_("0x%lx: \"%s\" type = %ld, class = %d, segment = %d\n"),
1835 (unsigned long) symbolP
,
1836 S_GET_NAME (symbolP
),
1837 (long) S_GET_DATA_TYPE (symbolP
),
1838 S_GET_STORAGE_CLASS (symbolP
),
1839 (int) S_GET_SEGMENT (symbolP
));
1844 const pseudo_typeS coff_pseudo_table
[] =
1846 {"ABORT", s_abort
, 0},
1847 {"appline", obj_coff_ln
, 1},
1848 /* We accept the .bss directive for backward compatibility with
1849 earlier versions of gas. */
1850 {"bss", obj_coff_bss
, 0},
1852 /* PE provides an enhanced version of .comm with alignment. */
1853 {"comm", obj_coff_comm
, 0},
1855 {"def", obj_coff_def
, 0},
1856 {"dim", obj_coff_dim
, 0},
1857 {"endef", obj_coff_endef
, 0},
1858 {"ident", obj_coff_ident
, 0},
1859 {"line", obj_coff_line
, 0},
1860 {"ln", obj_coff_ln
, 0},
1861 {"scl", obj_coff_scl
, 0},
1862 {"sect", obj_coff_section
, 0},
1863 {"sect.s", obj_coff_section
, 0},
1864 {"section", obj_coff_section
, 0},
1865 {"section.s", obj_coff_section
, 0},
1866 /* FIXME: We ignore the MRI short attribute. */
1867 {"size", obj_coff_size
, 0},
1868 {"tag", obj_coff_tag
, 0},
1869 {"type", obj_coff_type
, 0},
1870 {"val", obj_coff_val
, 0},
1871 {"version", s_ignore
, 0},
1872 {"loc", obj_coff_loc
, 0},
1873 {"optim", s_ignore
, 0}, /* For sun386i cc (?) */
1874 {"weak", obj_coff_weak
, 0},
1875 #if defined TC_TIC4X
1876 /* The tic4x uses sdef instead of def. */
1877 {"sdef", obj_coff_def
, 0},
1879 #if defined(SEH_CMDS)
1886 /* Support for a COFF emulation. */
1889 coff_pop_insert (void)
1891 pop_insert (coff_pseudo_table
);
1895 coff_separate_stab_sections (void)
1900 const struct format_ops coff_format_ops
=
1902 bfd_target_coff_flavour
,
1903 0, /* dfl_leading_underscore */
1904 1, /* emit_section_symbols */
1909 0, /* frob_file_before_adjust */
1910 0, /* frob_file_before_fix */
1911 coff_frob_file_after_relocs
,
1914 0, /* s_get_align */
1915 0, /* s_set_align */
1916 0, /* s_get_other */
1917 0, /* s_set_other */
1922 0, /* copy_symbol_attributes */
1923 0, /* generate_asm_lineno */
1924 0, /* process_stab */
1925 coff_separate_stab_sections
,
1926 obj_coff_init_stab_section
,
1927 0, /* sec_sym_ok_for_reloc */
1929 0, /* ecoff_set_ext */
1930 coff_obj_read_begin_hook
,
1931 coff_obj_symbol_new_hook
,
1932 coff_obj_symbol_clone_hook
,