1 /* coff object file format
2 Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009
4 Free Software Foundation, Inc.
6 This file is part of GAS.
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to the Free
20 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
23 #define OBJ_HEADER "obj-coff.h"
26 #include "safe-ctype.h"
34 #define streq(a,b) (strcmp ((a), (b)) == 0)
35 #define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
37 /* I think this is probably always correct. */
38 #ifndef KEEP_RELOC_INFO
39 #define KEEP_RELOC_INFO
42 /* obj_coff_section will use this macro to set a new section's
43 attributes when a directive has no valid flags or the "w" flag is
44 used. This default should be appropriate for most. */
45 #ifndef TC_COFF_SECTION_DEFAULT_ATTRIBUTES
46 #define TC_COFF_SECTION_DEFAULT_ATTRIBUTES (SEC_LOAD | SEC_DATA)
49 /* This is used to hold the symbol built by a sequence of pseudo-ops
50 from .def and .endef. */
51 static symbolS
*def_symbol_in_progress
;
53 /* PE weak alternate symbols begin with this string. */
54 static const char weak_altprefix
[] = ".weak.";
57 #include "obj-coff-seh.c"
61 unsigned long chunk_size
;
62 unsigned long element_size
;
65 unsigned long pointer
;
73 stack_init (unsigned long chunk_size
,
74 unsigned long element_size
)
78 st
= malloc (sizeof (* st
));
81 st
->data
= malloc (chunk_size
);
88 st
->size
= chunk_size
;
89 st
->chunk_size
= chunk_size
;
90 st
->element_size
= element_size
;
95 stack_push (stack
*st
, char *element
)
97 if (st
->pointer
+ st
->element_size
>= st
->size
)
99 st
->size
+= st
->chunk_size
;
100 if ((st
->data
= xrealloc (st
->data
, st
->size
)) == NULL
)
103 memcpy (st
->data
+ st
->pointer
, element
, st
->element_size
);
104 st
->pointer
+= st
->element_size
;
105 return st
->data
+ st
->pointer
;
109 stack_pop (stack
*st
)
111 if (st
->pointer
< st
->element_size
)
116 st
->pointer
-= st
->element_size
;
117 return st
->data
+ st
->pointer
;
120 /* Maintain a list of the tagnames of the structures. */
122 static struct hash_control
*tag_hash
;
127 tag_hash
= hash_new ();
131 tag_insert (const char *name
, symbolS
*symbolP
)
133 const char *error_string
;
135 if ((error_string
= hash_jam (tag_hash
, name
, (char *) symbolP
)))
136 as_fatal (_("Inserting \"%s\" into structure table failed: %s"),
141 tag_find (char *name
)
143 return (symbolS
*) hash_find (tag_hash
, name
);
147 tag_find_or_make (char *name
)
151 if ((symbolP
= tag_find (name
)) == NULL
)
153 symbolP
= symbol_new (name
, undefined_section
,
154 0, &zero_address_frag
);
156 tag_insert (S_GET_NAME (symbolP
), symbolP
);
157 symbol_table_insert (symbolP
);
163 /* We accept the .bss directive to set the section for backward
164 compatibility with earlier versions of gas. */
167 obj_coff_bss (int ignore ATTRIBUTE_UNUSED
)
169 if (*input_line_pointer
== '\n')
170 subseg_new (".bss", get_absolute_expression ());
176 /* Called from read.c:s_comm after we've parsed .comm symbol, size.
177 Parse a possible alignment value. */
180 obj_coff_common_parse (int ignore ATTRIBUTE_UNUSED
, symbolS
*symbolP
, addressT size
)
184 if (*input_line_pointer
== ',')
186 align
= parse_align (0);
187 if (align
== (addressT
) -1)
191 S_SET_VALUE (symbolP
, size
);
192 S_SET_EXTERNAL (symbolP
);
193 S_SET_SEGMENT (symbolP
, bfd_com_section_ptr
);
195 symbol_get_bfdsym (symbolP
)->flags
|= BSF_OBJECT
;
197 /* There is no S_SET_ALIGN (symbolP, align) in COFF/PE.
198 Instead we must add a note to the .drectve section. */
201 segT current_seg
= now_seg
;
202 subsegT current_subseg
= now_subseg
;
205 size_t pfxlen
, numlen
;
209 sec
= subseg_new (".drectve", 0);
210 oldflags
= bfd_get_section_flags (stdoutput
, sec
);
211 if (oldflags
== SEC_NO_FLAGS
)
213 if (!bfd_set_section_flags (stdoutput
, sec
,
214 TC_COFF_SECTION_DEFAULT_ATTRIBUTES
))
215 as_warn (_("error setting flags for \"%s\": %s"),
216 bfd_section_name (stdoutput
, sec
),
217 bfd_errmsg (bfd_get_error ()));
220 /* Emit a string. Note no NUL-termination. */
221 pfxlen
= strlen (" -aligncomm:") + strlen (S_GET_NAME (symbolP
)) + 1;
222 numlen
= snprintf (numbuff
, sizeof (numbuff
), "%d", (int) align
);
223 frag
= frag_more (pfxlen
+ numlen
);
224 (void) sprintf (frag
, " -aligncomm:%s,", S_GET_NAME (symbolP
));
225 memcpy (frag
+ pfxlen
, numbuff
, numlen
);
226 /* Restore original subseg. */
227 subseg_set (current_seg
, current_subseg
);
234 obj_coff_comm (int ignore ATTRIBUTE_UNUSED
)
236 s_comm_internal (ignore
, obj_coff_common_parse
);
240 #define GET_FILENAME_STRING(X) \
241 ((char *) (&((X)->sy_symbol.ost_auxent->x_file.x_n.x_offset))[1])
245 fetch_coff_debug_section (void)
247 static segT debug_section
;
253 s
= bfd_make_debug_symbol (stdoutput
, NULL
, 0);
255 debug_section
= s
->section
;
257 return debug_section
;
261 SA_SET_SYM_ENDNDX (symbolS
*sym
, symbolS
*val
)
263 combined_entry_type
*entry
, *p
;
265 entry
= &coffsymbol (symbol_get_bfdsym (sym
))->native
[1];
266 p
= coffsymbol (symbol_get_bfdsym (val
))->native
;
267 entry
->u
.auxent
.x_sym
.x_fcnary
.x_fcn
.x_endndx
.p
= p
;
272 SA_SET_SYM_TAGNDX (symbolS
*sym
, symbolS
*val
)
274 combined_entry_type
*entry
, *p
;
276 entry
= &coffsymbol (symbol_get_bfdsym (sym
))->native
[1];
277 p
= coffsymbol (symbol_get_bfdsym (val
))->native
;
278 entry
->u
.auxent
.x_sym
.x_tagndx
.p
= p
;
283 S_GET_DATA_TYPE (symbolS
*sym
)
285 return coffsymbol (symbol_get_bfdsym (sym
))->native
->u
.syment
.n_type
;
289 S_SET_DATA_TYPE (symbolS
*sym
, int val
)
291 coffsymbol (symbol_get_bfdsym (sym
))->native
->u
.syment
.n_type
= val
;
296 S_GET_STORAGE_CLASS (symbolS
*sym
)
298 return coffsymbol (symbol_get_bfdsym (sym
))->native
->u
.syment
.n_sclass
;
302 S_SET_STORAGE_CLASS (symbolS
*sym
, int val
)
304 coffsymbol (symbol_get_bfdsym (sym
))->native
->u
.syment
.n_sclass
= val
;
308 /* Merge a debug symbol containing debug information into a normal symbol. */
311 c_symbol_merge (symbolS
*debug
, symbolS
*normal
)
313 S_SET_DATA_TYPE (normal
, S_GET_DATA_TYPE (debug
));
314 S_SET_STORAGE_CLASS (normal
, S_GET_STORAGE_CLASS (debug
));
316 if (S_GET_NUMBER_AUXILIARY (debug
) > S_GET_NUMBER_AUXILIARY (normal
))
317 /* Take the most we have. */
318 S_SET_NUMBER_AUXILIARY (normal
, S_GET_NUMBER_AUXILIARY (debug
));
320 if (S_GET_NUMBER_AUXILIARY (debug
) > 0)
321 /* Move all the auxiliary information. */
322 memcpy (SYM_AUXINFO (normal
), SYM_AUXINFO (debug
),
323 (S_GET_NUMBER_AUXILIARY (debug
)
324 * sizeof (*SYM_AUXINFO (debug
))));
326 /* Move the debug flags. */
327 SF_SET_DEBUG_FIELD (normal
, SF_GET_DEBUG_FIELD (debug
));
331 c_dot_file_symbol (const char *filename
, int appfile ATTRIBUTE_UNUSED
)
335 /* BFD converts filename to a .file symbol with an aux entry. It
336 also handles chaining. */
337 symbolP
= symbol_new (filename
, bfd_abs_section_ptr
, 0, &zero_address_frag
);
339 S_SET_STORAGE_CLASS (symbolP
, C_FILE
);
340 S_SET_NUMBER_AUXILIARY (symbolP
, 1);
342 symbol_get_bfdsym (symbolP
)->flags
= BSF_DEBUGGING
;
349 listing_source_file (filename
);
353 /* Make sure that the symbol is first on the symbol chain. */
354 if (symbol_rootP
!= symbolP
)
356 symbol_remove (symbolP
, &symbol_rootP
, &symbol_lastP
);
357 symbol_insert (symbolP
, symbol_rootP
, &symbol_rootP
, &symbol_lastP
);
361 /* Line number handling. */
365 struct line_no
*next
;
372 /* Symbol of last function, which we should hang line#s off of. */
373 static symbolS
*line_fsym
;
375 #define in_function() (line_fsym != 0)
376 #define clear_function() (line_fsym = 0)
377 #define set_function(F) (line_fsym = (F), coff_add_linesym (F))
381 coff_obj_symbol_new_hook (symbolS
*symbolP
)
383 long sz
= (OBJ_COFF_MAX_AUXENTRIES
+ 1) * sizeof (combined_entry_type
);
384 char * s
= xmalloc (sz
);
387 coffsymbol (symbol_get_bfdsym (symbolP
))->native
= (combined_entry_type
*) s
;
389 S_SET_DATA_TYPE (symbolP
, T_NULL
);
390 S_SET_STORAGE_CLASS (symbolP
, 0);
391 S_SET_NUMBER_AUXILIARY (symbolP
, 0);
393 if (S_IS_STRING (symbolP
))
394 SF_SET_STRING (symbolP
);
396 if (S_IS_LOCAL (symbolP
))
397 SF_SET_LOCAL (symbolP
);
401 coff_obj_symbol_clone_hook (symbolS
*newsymP
, symbolS
*orgsymP
)
403 long sz
= (OBJ_COFF_MAX_AUXENTRIES
+ 1) * sizeof (combined_entry_type
);
404 combined_entry_type
* s
= xmalloc (sz
);
406 memcpy (s
, coffsymbol (symbol_get_bfdsym (orgsymP
))->native
, sz
);
407 coffsymbol (symbol_get_bfdsym (newsymP
))->native
= s
;
409 SF_SET (newsymP
, SF_GET (orgsymP
));
413 /* Handle .ln directives. */
415 static symbolS
*current_lineno_sym
;
416 static struct line_no
*line_nos
;
417 /* FIXME: Blindly assume all .ln directives will be in the .text section. */
421 add_lineno (fragS
* frag
, addressT offset
, int num
)
423 struct line_no
* new_line
= xmalloc (sizeof (* new_line
));
425 if (!current_lineno_sym
)
429 /* The native aix assembler accepts negative line number. */
433 /* Zero is used as an end marker in the file. */
434 as_warn (_("Line numbers must be positive integers\n"));
437 #endif /* OBJ_XCOFF */
438 new_line
->next
= line_nos
;
439 new_line
->frag
= frag
;
440 new_line
->l
.line_number
= num
;
441 new_line
->l
.u
.offset
= offset
;
447 coff_add_linesym (symbolS
*sym
)
451 coffsymbol (symbol_get_bfdsym (current_lineno_sym
))->lineno
=
456 current_lineno_sym
= sym
;
460 obj_coff_ln (int appline
)
464 if (! appline
&& def_symbol_in_progress
!= NULL
)
466 as_warn (_(".ln pseudo-op inside .def/.endef: ignored."));
467 demand_empty_rest_of_line ();
471 l
= get_absolute_expression ();
473 /* If there is no lineno symbol, treat a .ln
474 directive as if it were a .appline directive. */
475 if (appline
|| current_lineno_sym
== NULL
)
476 new_logical_line ((char *) NULL
, l
- 1);
478 add_lineno (frag_now
, frag_now_fix (), l
);
487 l
+= coff_line_base
- 1;
488 listing_source_line (l
);
493 demand_empty_rest_of_line ();
496 /* .loc is essentially the same as .ln; parse it for assembler
500 obj_coff_loc (int ignore ATTRIBUTE_UNUSED
)
504 /* FIXME: Why do we need this check? We need it for ECOFF, but why
505 do we need it for COFF? */
506 if (now_seg
!= text_section
)
508 as_warn (_(".loc outside of .text"));
509 demand_empty_rest_of_line ();
513 if (def_symbol_in_progress
!= NULL
)
515 as_warn (_(".loc pseudo-op inside .def/.endef: ignored."));
516 demand_empty_rest_of_line ();
520 /* Skip the file number. */
522 get_absolute_expression ();
525 lineno
= get_absolute_expression ();
533 lineno
+= coff_line_base
- 1;
534 listing_source_line (lineno
);
539 demand_empty_rest_of_line ();
541 add_lineno (frag_now
, frag_now_fix (), lineno
);
544 /* Handle the .ident pseudo-op. */
547 obj_coff_ident (int ignore ATTRIBUTE_UNUSED
)
549 segT current_seg
= now_seg
;
550 subsegT current_subseg
= now_subseg
;
556 /* We could put it in .comment, but that creates an extra section
557 that shouldn't be loaded into memory, which requires linker
558 changes... For now, until proven otherwise, use .rdata. */
559 sec
= subseg_new (".rdata$zzz", 0);
560 bfd_set_section_flags (stdoutput
, sec
,
561 ((SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
| SEC_DATA
)
562 & bfd_applicable_section_flags (stdoutput
)));
565 subseg_new (".comment", 0);
569 subseg_set (current_seg
, current_subseg
);
572 /* Handle .def directives.
574 One might ask : why can't we symbol_new if the symbol does not
575 already exist and fill it with debug information. Because of
576 the C_EFCN special symbol. It would clobber the value of the
577 function symbol before we have a chance to notice that it is
578 a C_EFCN. And a second reason is that the code is more clear this
579 way. (at least I think it is :-). */
581 #define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';')
582 #define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \
583 *input_line_pointer == '\t') \
584 input_line_pointer++;
587 obj_coff_def (int what ATTRIBUTE_UNUSED
)
589 char name_end
; /* Char after the end of name. */
590 char *symbol_name
; /* Name of the debug symbol. */
591 char *symbol_name_copy
; /* Temporary copy of the name. */
592 unsigned int symbol_name_length
;
594 if (def_symbol_in_progress
!= NULL
)
596 as_warn (_(".def pseudo-op used inside of .def/.endef: ignored."));
597 demand_empty_rest_of_line ();
603 symbol_name
= input_line_pointer
;
604 name_end
= get_symbol_end ();
605 symbol_name_length
= strlen (symbol_name
);
606 symbol_name_copy
= xmalloc (symbol_name_length
+ 1);
607 strcpy (symbol_name_copy
, symbol_name
);
608 #ifdef tc_canonicalize_symbol_name
609 symbol_name_copy
= tc_canonicalize_symbol_name (symbol_name_copy
);
612 /* Initialize the new symbol. */
613 def_symbol_in_progress
= symbol_make (symbol_name_copy
);
614 symbol_set_frag (def_symbol_in_progress
, &zero_address_frag
);
615 S_SET_VALUE (def_symbol_in_progress
, 0);
617 if (S_IS_STRING (def_symbol_in_progress
))
618 SF_SET_STRING (def_symbol_in_progress
);
620 *input_line_pointer
= name_end
;
622 demand_empty_rest_of_line ();
626 obj_coff_endef (int ignore ATTRIBUTE_UNUSED
)
628 symbolS
*symbolP
= NULL
;
630 if (def_symbol_in_progress
== NULL
)
632 as_warn (_(".endef pseudo-op used outside of .def/.endef: ignored."));
633 demand_empty_rest_of_line ();
637 /* Set the section number according to storage class. */
638 switch (S_GET_STORAGE_CLASS (def_symbol_in_progress
))
643 SF_SET_TAG (def_symbol_in_progress
);
647 SF_SET_DEBUG (def_symbol_in_progress
);
648 S_SET_SEGMENT (def_symbol_in_progress
, fetch_coff_debug_section ());
652 SF_SET_LOCAL (def_symbol_in_progress
); /* Do not emit this symbol. */
655 SF_SET_PROCESS (def_symbol_in_progress
); /* Will need processing before writing. */
661 S_SET_SEGMENT (def_symbol_in_progress
, text_section
);
663 name
= S_GET_NAME (def_symbol_in_progress
);
664 if (name
[0] == '.' && name
[2] == 'f' && name
[3] == '\0')
670 if (! in_function ())
671 as_warn (_("`%s' symbol without preceding function"), name
);
672 /* Will need relocating. */
673 SF_SET_PROCESS (def_symbol_in_progress
);
679 /* The MS compilers output the actual endline, not the
680 function-relative one... we want to match without
681 changing the assembler input. */
682 SA_SET_SYM_LNNO (def_symbol_in_progress
,
683 (SA_GET_SYM_LNNO (def_symbol_in_progress
)
694 #endif /* C_AUTOARG */
701 /* According to the COFF documentation:
703 http://osr5doc.sco.com:1996/topics/COFF_SectNumFld.html
705 A special section number (-2) marks symbolic debugging symbols,
706 including structure/union/enumeration tag names, typedefs, and
707 the name of the file. A section number of -1 indicates that the
708 symbol has a value but is not relocatable. Examples of
709 absolute-valued symbols include automatic and register variables,
710 function arguments, and .eos symbols.
712 But from Ian Lance Taylor:
714 http://sources.redhat.com/ml/binutils/2000-08/msg00202.html
716 the actual tools all marked them as section -1. So the GNU COFF
717 assembler follows historical COFF assemblers.
719 However, it causes problems for djgpp
721 http://sources.redhat.com/ml/binutils/2000-08/msg00210.html
723 By defining STRICTCOFF, a COFF port can make the assembler to
724 follow the documented behavior. */
731 SF_SET_DEBUG (def_symbol_in_progress
);
732 S_SET_SEGMENT (def_symbol_in_progress
, absolute_section
);
740 S_SET_SEGMENT (def_symbol_in_progress
, absolute_section
);
751 /* Valid but set somewhere else (s_comm, s_lcomm, colon). */
758 as_warn (_("unexpected storage class %d"),
759 S_GET_STORAGE_CLASS (def_symbol_in_progress
));
763 /* Now that we have built a debug symbol, try to find if we should
764 merge with an existing symbol or not. If a symbol is C_EFCN or
765 absolute_section or untagged SEG_DEBUG it never merges. We also
766 don't merge labels, which are in a different namespace, nor
767 symbols which have not yet been defined since they are typically
768 unique, nor do we merge tags with non-tags. */
770 /* Two cases for functions. Either debug followed by definition or
771 definition followed by debug. For definition first, we will
772 merge the debug symbol into the definition. For debug first, the
773 lineno entry MUST point to the definition function or else it
774 will point off into space when obj_crawl_symbol_chain() merges
775 the debug symbol into the real symbol. Therefor, let's presume
776 the debug symbol is a real function reference. */
778 /* FIXME-SOON If for some reason the definition label/symbol is
779 never seen, this will probably leave an undefined symbol at link
782 if (S_GET_STORAGE_CLASS (def_symbol_in_progress
) == C_EFCN
783 || S_GET_STORAGE_CLASS (def_symbol_in_progress
) == C_LABEL
784 || (streq (bfd_get_section_name (stdoutput
,
785 S_GET_SEGMENT (def_symbol_in_progress
)),
787 && !SF_GET_TAG (def_symbol_in_progress
))
788 || S_GET_SEGMENT (def_symbol_in_progress
) == absolute_section
789 || ! symbol_constant_p (def_symbol_in_progress
)
790 || (symbolP
= symbol_find (S_GET_NAME (def_symbol_in_progress
))) == NULL
791 || SF_GET_TAG (def_symbol_in_progress
) != SF_GET_TAG (symbolP
))
793 /* If it already is at the end of the symbol list, do nothing */
794 if (def_symbol_in_progress
!= symbol_lastP
)
796 symbol_remove (def_symbol_in_progress
, &symbol_rootP
, &symbol_lastP
);
797 symbol_append (def_symbol_in_progress
, symbol_lastP
, &symbol_rootP
,
803 /* This symbol already exists, merge the newly created symbol
804 into the old one. This is not mandatory. The linker can
805 handle duplicate symbols correctly. But I guess that it save
806 a *lot* of space if the assembly file defines a lot of
809 /* The debug entry (def_symbol_in_progress) is merged into the
810 previous definition. */
812 c_symbol_merge (def_symbol_in_progress
, symbolP
);
813 symbol_remove (def_symbol_in_progress
, &symbol_rootP
, &symbol_lastP
);
815 def_symbol_in_progress
= symbolP
;
817 if (SF_GET_FUNCTION (def_symbol_in_progress
)
818 || SF_GET_TAG (def_symbol_in_progress
)
819 || S_GET_STORAGE_CLASS (def_symbol_in_progress
) == C_STAT
)
821 /* For functions, and tags, and static symbols, the symbol
822 *must* be where the debug symbol appears. Move the
823 existing symbol to the current place. */
824 /* If it already is at the end of the symbol list, do nothing. */
825 if (def_symbol_in_progress
!= symbol_lastP
)
827 symbol_remove (def_symbol_in_progress
, &symbol_rootP
, &symbol_lastP
);
828 symbol_append (def_symbol_in_progress
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
833 if (SF_GET_TAG (def_symbol_in_progress
))
837 oldtag
= symbol_find (S_GET_NAME (def_symbol_in_progress
));
838 if (oldtag
== NULL
|| ! SF_GET_TAG (oldtag
))
839 tag_insert (S_GET_NAME (def_symbol_in_progress
),
840 def_symbol_in_progress
);
843 if (SF_GET_FUNCTION (def_symbol_in_progress
))
845 set_function (def_symbol_in_progress
);
846 SF_SET_PROCESS (def_symbol_in_progress
);
849 /* That is, if this is the first time we've seen the
851 symbol_table_insert (def_symbol_in_progress
);
855 def_symbol_in_progress
= NULL
;
856 demand_empty_rest_of_line ();
860 obj_coff_dim (int ignore ATTRIBUTE_UNUSED
)
864 if (def_symbol_in_progress
== NULL
)
866 as_warn (_(".dim pseudo-op used outside of .def/.endef: ignored."));
867 demand_empty_rest_of_line ();
871 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress
, 1);
873 for (d_index
= 0; d_index
< DIMNUM
; d_index
++)
876 SA_SET_SYM_DIMEN (def_symbol_in_progress
, d_index
,
877 get_absolute_expression ());
879 switch (*input_line_pointer
)
882 input_line_pointer
++;
886 as_warn (_("badly formed .dim directive ignored"));
895 demand_empty_rest_of_line ();
899 obj_coff_line (int ignore ATTRIBUTE_UNUSED
)
903 if (def_symbol_in_progress
== NULL
)
905 /* Probably stabs-style line? */
910 this_base
= get_absolute_expression ();
911 if (streq (".bf", S_GET_NAME (def_symbol_in_progress
)))
912 coff_line_base
= this_base
;
914 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress
, 1);
915 SA_SET_SYM_LNNO (def_symbol_in_progress
, this_base
);
917 demand_empty_rest_of_line ();
920 if (streq (".bf", S_GET_NAME (def_symbol_in_progress
)))
925 listing_source_line ((unsigned int) this_base
);
931 obj_coff_size (int ignore ATTRIBUTE_UNUSED
)
933 if (def_symbol_in_progress
== NULL
)
935 as_warn (_(".size pseudo-op used outside of .def/.endef ignored."));
936 demand_empty_rest_of_line ();
940 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress
, 1);
941 SA_SET_SYM_SIZE (def_symbol_in_progress
, get_absolute_expression ());
942 demand_empty_rest_of_line ();
946 obj_coff_scl (int ignore ATTRIBUTE_UNUSED
)
948 if (def_symbol_in_progress
== NULL
)
950 as_warn (_(".scl pseudo-op used outside of .def/.endef ignored."));
951 demand_empty_rest_of_line ();
955 S_SET_STORAGE_CLASS (def_symbol_in_progress
, get_absolute_expression ());
956 demand_empty_rest_of_line ();
960 obj_coff_tag (int ignore ATTRIBUTE_UNUSED
)
965 if (def_symbol_in_progress
== NULL
)
967 as_warn (_(".tag pseudo-op used outside of .def/.endef ignored."));
968 demand_empty_rest_of_line ();
972 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress
, 1);
973 symbol_name
= input_line_pointer
;
974 name_end
= get_symbol_end ();
976 #ifdef tc_canonicalize_symbol_name
977 symbol_name
= tc_canonicalize_symbol_name (symbol_name
);
980 /* Assume that the symbol referred to by .tag is always defined.
981 This was a bad assumption. I've added find_or_make. xoxorich. */
982 SA_SET_SYM_TAGNDX (def_symbol_in_progress
,
983 tag_find_or_make (symbol_name
));
984 if (SA_GET_SYM_TAGNDX (def_symbol_in_progress
) == 0L)
985 as_warn (_("tag not found for .tag %s"), symbol_name
);
987 SF_SET_TAGGED (def_symbol_in_progress
);
988 *input_line_pointer
= name_end
;
990 demand_empty_rest_of_line ();
994 obj_coff_type (int ignore ATTRIBUTE_UNUSED
)
996 if (def_symbol_in_progress
== NULL
)
998 as_warn (_(".type pseudo-op used outside of .def/.endef ignored."));
999 demand_empty_rest_of_line ();
1003 S_SET_DATA_TYPE (def_symbol_in_progress
, get_absolute_expression ());
1005 if (ISFCN (S_GET_DATA_TYPE (def_symbol_in_progress
)) &&
1006 S_GET_STORAGE_CLASS (def_symbol_in_progress
) != C_TPDEF
)
1007 SF_SET_FUNCTION (def_symbol_in_progress
);
1009 demand_empty_rest_of_line ();
1013 obj_coff_val (int ignore ATTRIBUTE_UNUSED
)
1015 if (def_symbol_in_progress
== NULL
)
1017 as_warn (_(".val pseudo-op used outside of .def/.endef ignored."));
1018 demand_empty_rest_of_line ();
1022 if (is_name_beginner (*input_line_pointer
))
1024 char *symbol_name
= input_line_pointer
;
1025 char name_end
= get_symbol_end ();
1027 #ifdef tc_canonicalize_symbol_name
1028 symbol_name
= tc_canonicalize_symbol_name (symbol_name
);
1030 if (streq (symbol_name
, "."))
1032 /* If the .val is != from the .def (e.g. statics). */
1033 symbol_set_frag (def_symbol_in_progress
, frag_now
);
1034 S_SET_VALUE (def_symbol_in_progress
, (valueT
) frag_now_fix ());
1036 else if (! streq (S_GET_NAME (def_symbol_in_progress
), symbol_name
))
1040 exp
.X_op
= O_symbol
;
1041 exp
.X_add_symbol
= symbol_find_or_make (symbol_name
);
1042 exp
.X_op_symbol
= NULL
;
1043 exp
.X_add_number
= 0;
1044 symbol_set_value_expression (def_symbol_in_progress
, &exp
);
1046 /* If the segment is undefined when the forward reference is
1047 resolved, then copy the segment id from the forward
1049 SF_SET_GET_SEGMENT (def_symbol_in_progress
);
1051 /* FIXME: gcc can generate address expressions here in
1052 unusual cases (search for "obscure" in sdbout.c). We
1053 just ignore the offset here, thus generating incorrect
1054 debugging information. We ignore the rest of the line
1057 /* Otherwise, it is the name of a non debug symbol and its value
1058 will be calculated later. */
1059 *input_line_pointer
= name_end
;
1063 S_SET_VALUE (def_symbol_in_progress
, get_absolute_expression ());
1066 demand_empty_rest_of_line ();
1071 /* Return nonzero if name begins with weak alternate symbol prefix. */
1074 weak_is_altname (const char * name
)
1076 return strneq (name
, weak_altprefix
, sizeof (weak_altprefix
) - 1);
1079 /* Return the name of the alternate symbol
1080 name corresponding to a weak symbol's name. */
1083 weak_name2altname (const char * name
)
1087 alt_name
= xmalloc (sizeof (weak_altprefix
) + strlen (name
));
1088 strcpy (alt_name
, weak_altprefix
);
1089 return strcat (alt_name
, name
);
1092 /* Return the name of the weak symbol corresponding to an
1093 alternate symbol. */
1096 weak_altname2name (const char * name
)
1101 gas_assert (weak_is_altname (name
));
1103 weak_name
= xstrdup (name
+ 6);
1104 if ((dot
= strchr (weak_name
, '.')))
1109 /* Make a weak symbol name unique by
1110 appending the name of an external symbol. */
1113 weak_uniquify (const char * name
)
1116 const char * unique
= "";
1119 if (an_external_name
!= NULL
)
1120 unique
= an_external_name
;
1122 gas_assert (weak_is_altname (name
));
1124 if (strchr (name
+ sizeof (weak_altprefix
), '.'))
1127 ret
= xmalloc (strlen (name
) + strlen (unique
) + 2);
1130 strcat (ret
, unique
);
1135 pecoff_obj_set_weak_hook (symbolS
*symbolP
)
1137 symbolS
*alternateP
;
1139 /* See _Microsoft Portable Executable and Common Object
1140 File Format Specification_, section 5.5.3.
1141 Create a symbol representing the alternate value.
1142 coff_frob_symbol will set the value of this symbol from
1143 the value of the weak symbol itself. */
1144 S_SET_STORAGE_CLASS (symbolP
, C_NT_WEAK
);
1145 S_SET_NUMBER_AUXILIARY (symbolP
, 1);
1146 SA_SET_SYM_FSIZE (symbolP
, IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY
);
1148 alternateP
= symbol_find_or_make (weak_name2altname (S_GET_NAME (symbolP
)));
1149 S_SET_EXTERNAL (alternateP
);
1150 S_SET_STORAGE_CLASS (alternateP
, C_NT_WEAK
);
1152 SA_SET_SYM_TAGNDX (symbolP
, alternateP
);
1156 pecoff_obj_clear_weak_hook (symbolS
*symbolP
)
1158 symbolS
*alternateP
;
1160 S_SET_STORAGE_CLASS (symbolP
, 0);
1161 SA_SET_SYM_FSIZE (symbolP
, 0);
1163 alternateP
= symbol_find (weak_name2altname (S_GET_NAME (symbolP
)));
1164 S_CLEAR_EXTERNAL (alternateP
);
1169 /* Handle .weak. This is a GNU extension in formats other than PE. */
1172 obj_coff_weak (int ignore ATTRIBUTE_UNUSED
)
1180 name
= input_line_pointer
;
1181 c
= get_symbol_end ();
1184 as_warn (_("badly formed .weak directive ignored"));
1185 ignore_rest_of_line ();
1189 symbolP
= symbol_find_or_make (name
);
1190 *input_line_pointer
= c
;
1192 S_SET_WEAK (symbolP
);
1196 input_line_pointer
++;
1198 if (*input_line_pointer
== '\n')
1205 demand_empty_rest_of_line ();
1209 coff_obj_read_begin_hook (void)
1211 /* These had better be the same. Usually 18 bytes. */
1212 know (sizeof (SYMENT
) == sizeof (AUXENT
));
1213 know (SYMESZ
== AUXESZ
);
1217 symbolS
*coff_last_function
;
1219 static symbolS
*coff_last_bf
;
1223 coff_frob_symbol (symbolS
*symp
, int *punt
)
1225 static symbolS
*last_tagP
;
1226 static stack
*block_stack
;
1227 static symbolS
*set_end
;
1228 symbolS
*next_set_end
= NULL
;
1230 if (symp
== &abs_symbol
)
1236 if (current_lineno_sym
)
1237 coff_add_linesym (NULL
);
1240 block_stack
= stack_init (512, sizeof (symbolS
*));
1243 if (S_GET_STORAGE_CLASS (symp
) == C_NT_WEAK
1244 && ! S_IS_WEAK (symp
)
1245 && weak_is_altname (S_GET_NAME (symp
)))
1247 /* This is a weak alternate symbol. All processing of
1248 PECOFFweak symbols is done here, through the alternate. */
1249 symbolS
*weakp
= symbol_find_noref (weak_altname2name
1250 (S_GET_NAME (symp
)), 1);
1253 gas_assert (S_GET_NUMBER_AUXILIARY (weakp
) == 1);
1255 if (! S_IS_WEAK (weakp
))
1257 /* The symbol was turned from weak to strong. Discard altname. */
1261 else if (symbol_equated_p (weakp
))
1263 /* The weak symbol has an alternate specified; symp is unneeded. */
1264 S_SET_STORAGE_CLASS (weakp
, C_NT_WEAK
);
1265 SA_SET_SYM_TAGNDX (weakp
,
1266 symbol_get_value_expression (weakp
)->X_add_symbol
);
1268 S_CLEAR_EXTERNAL (symp
);
1274 /* The weak symbol has been assigned an alternate value.
1275 Copy this value to symp, and set symp as weakp's alternate. */
1276 if (S_GET_STORAGE_CLASS (weakp
) != C_NT_WEAK
)
1278 S_SET_STORAGE_CLASS (symp
, S_GET_STORAGE_CLASS (weakp
));
1279 S_SET_STORAGE_CLASS (weakp
, C_NT_WEAK
);
1282 if (S_IS_DEFINED (weakp
))
1284 /* This is a defined weak symbol. Copy value information
1285 from the weak symbol itself to the alternate symbol. */
1286 symbol_set_value_expression (symp
,
1287 symbol_get_value_expression (weakp
));
1288 symbol_set_frag (symp
, symbol_get_frag (weakp
));
1289 S_SET_SEGMENT (symp
, S_GET_SEGMENT (weakp
));
1293 /* This is an undefined weak symbol.
1294 Define the alternate symbol to zero. */
1295 S_SET_VALUE (symp
, 0);
1296 S_SET_SEGMENT (symp
, absolute_section
);
1299 S_SET_NAME (symp
, weak_uniquify (S_GET_NAME (symp
)));
1300 S_SET_STORAGE_CLASS (symp
, C_EXT
);
1302 S_SET_VALUE (weakp
, 0);
1303 S_SET_SEGMENT (weakp
, undefined_section
);
1307 if (S_IS_WEAK (symp
))
1308 S_SET_STORAGE_CLASS (symp
, C_WEAKEXT
);
1311 if (!S_IS_DEFINED (symp
)
1312 && !S_IS_WEAK (symp
)
1313 && S_GET_STORAGE_CLASS (symp
) != C_STAT
)
1314 S_SET_STORAGE_CLASS (symp
, C_EXT
);
1316 if (!SF_GET_DEBUG (symp
))
1320 if (!SF_GET_LOCAL (symp
)
1321 && !SF_GET_STATICS (symp
)
1322 && S_GET_STORAGE_CLASS (symp
) != C_LABEL
1323 && symbol_constant_p (symp
)
1324 && (real
= symbol_find_noref (S_GET_NAME (symp
), 1))
1325 && S_GET_STORAGE_CLASS (real
) == C_NULL
1328 c_symbol_merge (symp
, real
);
1333 if (!S_IS_DEFINED (symp
) && !SF_GET_LOCAL (symp
))
1335 gas_assert (S_GET_VALUE (symp
) == 0);
1336 if (S_IS_WEAKREFD (symp
))
1339 S_SET_EXTERNAL (symp
);
1341 else if (S_GET_STORAGE_CLASS (symp
) == C_NULL
)
1343 if (S_GET_SEGMENT (symp
) == text_section
1344 && symp
!= seg_info (text_section
)->sym
)
1345 S_SET_STORAGE_CLASS (symp
, C_LABEL
);
1347 S_SET_STORAGE_CLASS (symp
, C_STAT
);
1350 if (SF_GET_PROCESS (symp
))
1352 if (S_GET_STORAGE_CLASS (symp
) == C_BLOCK
)
1354 if (streq (S_GET_NAME (symp
), ".bb"))
1355 stack_push (block_stack
, (char *) &symp
);
1360 begin
= *(symbolS
**) stack_pop (block_stack
);
1362 as_warn (_("mismatched .eb"));
1364 next_set_end
= begin
;
1368 if (coff_last_function
== 0 && SF_GET_FUNCTION (symp
))
1370 union internal_auxent
*auxp
;
1372 coff_last_function
= symp
;
1373 if (S_GET_NUMBER_AUXILIARY (symp
) < 1)
1374 S_SET_NUMBER_AUXILIARY (symp
, 1);
1375 auxp
= SYM_AUXENT (symp
);
1376 memset (auxp
->x_sym
.x_fcnary
.x_ary
.x_dimen
, 0,
1377 sizeof (auxp
->x_sym
.x_fcnary
.x_ary
.x_dimen
));
1380 if (S_GET_STORAGE_CLASS (symp
) == C_EFCN
)
1382 if (coff_last_function
== 0)
1383 as_fatal (_("C_EFCN symbol for %s out of scope"),
1385 SA_SET_SYM_FSIZE (coff_last_function
,
1386 (long) (S_GET_VALUE (symp
)
1387 - S_GET_VALUE (coff_last_function
)));
1388 next_set_end
= coff_last_function
;
1389 coff_last_function
= 0;
1393 if (S_IS_EXTERNAL (symp
))
1394 S_SET_STORAGE_CLASS (symp
, C_EXT
);
1395 else if (SF_GET_LOCAL (symp
))
1398 if (SF_GET_FUNCTION (symp
))
1399 symbol_get_bfdsym (symp
)->flags
|= BSF_FUNCTION
;
1402 /* Double check weak symbols. */
1403 if (S_IS_WEAK (symp
) && S_IS_COMMON (symp
))
1404 as_bad (_("Symbol `%s' can not be both weak and common"),
1407 if (SF_GET_TAG (symp
))
1409 else if (S_GET_STORAGE_CLASS (symp
) == C_EOS
)
1410 next_set_end
= last_tagP
;
1413 /* This is pretty horrible, but we have to set *punt correctly in
1414 order to call SA_SET_SYM_ENDNDX correctly. */
1415 if (! symbol_used_in_reloc_p (symp
)
1416 && ((symbol_get_bfdsym (symp
)->flags
& BSF_SECTION_SYM
) != 0
1417 || (! (S_IS_EXTERNAL (symp
) || S_IS_WEAK (symp
))
1418 && ! symbol_get_tc (symp
)->output
1419 && S_GET_STORAGE_CLASS (symp
) != C_FILE
)))
1423 if (set_end
!= (symbolS
*) NULL
1425 && ((symbol_get_bfdsym (symp
)->flags
& BSF_NOT_AT_END
) != 0
1426 || (S_IS_DEFINED (symp
)
1427 && ! S_IS_COMMON (symp
)
1428 && (! S_IS_EXTERNAL (symp
) || SF_GET_FUNCTION (symp
)))))
1430 SA_SET_SYM_ENDNDX (set_end
, symp
);
1434 if (next_set_end
!= NULL
)
1436 if (set_end
!= NULL
)
1437 as_warn (_("Warning: internal error: forgetting to set endndx of %s"),
1438 S_GET_NAME (set_end
));
1439 set_end
= next_set_end
;
1444 && S_GET_STORAGE_CLASS (symp
) == C_FCN
1445 && streq (S_GET_NAME (symp
), ".bf"))
1447 if (coff_last_bf
!= NULL
)
1448 SA_SET_SYM_ENDNDX (coff_last_bf
, symp
);
1449 coff_last_bf
= symp
;
1452 if (coffsymbol (symbol_get_bfdsym (symp
))->lineno
)
1455 struct line_no
*lptr
;
1458 lptr
= (struct line_no
*) coffsymbol (symbol_get_bfdsym (symp
))->lineno
;
1459 for (i
= 0; lptr
; lptr
= lptr
->next
)
1461 lptr
= (struct line_no
*) coffsymbol (symbol_get_bfdsym (symp
))->lineno
;
1463 /* We need i entries for line numbers, plus 1 for the first
1464 entry which BFD will override, plus 1 for the last zero
1465 entry (a marker for BFD). */
1466 l
= xmalloc ((i
+ 2) * sizeof (* l
));
1467 coffsymbol (symbol_get_bfdsym (symp
))->lineno
= l
;
1468 l
[i
+ 1].line_number
= 0;
1469 l
[i
+ 1].u
.sym
= NULL
;
1473 lptr
->l
.u
.offset
+= lptr
->frag
->fr_address
/ OCTETS_PER_BYTE
;
1481 coff_adjust_section_syms (bfd
*abfd ATTRIBUTE_UNUSED
,
1483 void * x ATTRIBUTE_UNUSED
)
1486 segment_info_type
*seginfo
= seg_info (sec
);
1487 int nlnno
, nrelocs
= 0;
1489 /* RS/6000 gas creates a .debug section manually in ppc_frob_file in
1490 tc-ppc.c. Do not get confused by it. */
1491 if (seginfo
== NULL
)
1494 if (streq (sec
->name
, ".text"))
1495 nlnno
= coff_n_line_nos
;
1499 /* @@ Hope that none of the fixups expand to more than one reloc
1501 fixS
*fixp
= seginfo
->fix_root
;
1504 if (! fixp
->fx_done
)
1506 fixp
= fixp
->fx_next
;
1509 if (bfd_get_section_size (sec
) == 0
1512 && sec
!= text_section
1513 && sec
!= data_section
1514 && sec
!= bss_section
)
1517 secsym
= section_symbol (sec
);
1518 /* This is an estimate; we'll plug in the real value using
1519 SET_SECTION_RELOCS later */
1520 SA_SET_SCN_NRELOC (secsym
, nrelocs
);
1521 SA_SET_SCN_NLINNO (secsym
, nlnno
);
1525 coff_frob_file_after_relocs (void)
1527 bfd_map_over_sections (stdoutput
, coff_adjust_section_syms
, NULL
);
1530 /* Implement the .section pseudo op:
1531 .section name {, "flags"}
1533 | +--- optional flags: 'b' for bss
1535 +-- section name 'l' for lib
1539 'd' (apparently m88k for data)
1541 'r' for read-only data
1542 's' for shared data (PE)
1544 '0' - '9' for power-of-two alignment (GNU extension).
1545 But if the argument is not a quoted string, treat it as a
1548 Note the 'a' flag is silently ignored. This allows the same
1549 .section directive to be parsed in both ELF and COFF formats. */
1552 obj_coff_section (int ignore ATTRIBUTE_UNUSED
)
1554 /* Strip out the section name. */
1560 flagword flags
, oldflags
;
1571 section_name
= input_line_pointer
;
1572 c
= get_symbol_end ();
1574 name
= xmalloc (input_line_pointer
- section_name
+ 1);
1575 strcpy (name
, section_name
);
1577 *input_line_pointer
= c
;
1582 flags
= SEC_NO_FLAGS
;
1584 if (*input_line_pointer
== ',')
1586 ++input_line_pointer
;
1588 if (*input_line_pointer
!= '"')
1589 exp
= get_absolute_expression ();
1593 int readonly_removed
= 0;
1594 int load_removed
= 0;
1596 while (attr
= *++input_line_pointer
,
1598 && ! is_end_of_line
[attr
])
1602 alignment
= attr
- '0';
1608 /* Uninitialised data section. */
1614 /* Section not loaded. */
1616 flags
|= SEC_NEVER_LOAD
;
1621 /* Shared section. */
1622 flags
|= SEC_COFF_SHARED
;
1629 flags
&=~ SEC_READONLY
;
1633 /* Writable section. */
1634 flags
&=~ SEC_READONLY
;
1635 readonly_removed
= 1;
1639 /* Ignore. Here for compatibility with ELF. */
1642 case 'r': /* Read-only section. Implies a data section. */
1643 readonly_removed
= 0;
1645 case 'x': /* Executable section. */
1646 /* If we are setting the 'x' attribute or if the 'r'
1647 attribute is being used to restore the readonly status
1648 of a code section (eg "wxr") then set the SEC_CODE flag,
1649 otherwise set the SEC_DATA flag. */
1650 flags
|= (attr
== 'x' || (flags
& SEC_CODE
) ? SEC_CODE
: SEC_DATA
);
1653 /* Note - the READONLY flag is set here, even for the 'x'
1654 attribute in order to be compatible with the MSVC
1656 if (! readonly_removed
)
1657 flags
|= SEC_READONLY
;
1661 flags
|= SEC_COFF_NOREAD
| SEC_READONLY
;
1664 case 'i': /* STYP_INFO */
1665 case 'l': /* STYP_LIB */
1666 case 'o': /* STYP_OVER */
1667 as_warn (_("unsupported section attribute '%c'"), attr
);
1671 as_warn (_("unknown section attribute '%c'"), attr
);
1676 ++input_line_pointer
;
1680 sec
= subseg_new (name
, (subsegT
) exp
);
1682 sec
->alignment_power
= alignment
;
1684 oldflags
= bfd_get_section_flags (stdoutput
, sec
);
1685 if (oldflags
== SEC_NO_FLAGS
)
1687 /* Set section flags for a new section just created by subseg_new.
1688 Provide a default if no flags were parsed. */
1689 if (flags
== SEC_NO_FLAGS
)
1690 flags
= TC_COFF_SECTION_DEFAULT_ATTRIBUTES
;
1692 #ifdef COFF_LONG_SECTION_NAMES
1693 /* Add SEC_LINK_ONCE and SEC_LINK_DUPLICATES_DISCARD to .gnu.linkonce
1694 sections so adjust_reloc_syms in write.c will correctly handle
1695 relocs which refer to non-local symbols in these sections. */
1696 if (strneq (name
, ".gnu.linkonce", sizeof (".gnu.linkonce") - 1))
1697 flags
|= SEC_LINK_ONCE
| SEC_LINK_DUPLICATES_DISCARD
;
1700 if (! bfd_set_section_flags (stdoutput
, sec
, flags
))
1701 as_warn (_("error setting flags for \"%s\": %s"),
1702 bfd_section_name (stdoutput
, sec
),
1703 bfd_errmsg (bfd_get_error ()));
1705 else if (flags
!= SEC_NO_FLAGS
)
1707 /* This section's attributes have already been set. Warn if the
1708 attributes don't match. */
1709 flagword matchflags
= (SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
| SEC_CODE
1710 | SEC_DATA
| SEC_COFF_SHARED
| SEC_NEVER_LOAD
1712 if ((flags
^ oldflags
) & matchflags
)
1713 as_warn (_("Ignoring changed section attributes for %s"), name
);
1716 demand_empty_rest_of_line ();
1720 coff_adjust_symtab (void)
1722 if (symbol_rootP
== NULL
1723 || S_GET_STORAGE_CLASS (symbol_rootP
) != C_FILE
)
1724 c_dot_file_symbol ("fake", 0);
1728 coff_frob_section (segT sec
)
1733 bfd_vma size
, n_entries
, mask
;
1734 bfd_vma align_power
= (bfd_vma
)sec
->alignment_power
+ OCTETS_PER_BYTE_POWER
;
1736 /* The COFF back end in BFD requires that all section sizes be
1737 rounded up to multiples of the corresponding section alignments,
1738 supposedly because standard COFF has no other way of encoding alignment
1739 for sections. If your COFF flavor has a different way of encoding
1740 section alignment, then skip this step, as TICOFF does. */
1741 size
= bfd_get_section_size (sec
);
1742 mask
= ((bfd_vma
) 1 << align_power
) - 1;
1743 #if !defined(TICOFF)
1749 new_size
= (size
+ mask
) & ~mask
;
1750 bfd_set_section_size (stdoutput
, sec
, new_size
);
1752 /* If the size had to be rounded up, add some padding in
1753 the last non-empty frag. */
1754 fragp
= seg_info (sec
)->frchainP
->frch_root
;
1755 last
= seg_info (sec
)->frchainP
->frch_last
;
1756 while (fragp
->fr_next
!= last
)
1757 fragp
= fragp
->fr_next
;
1758 last
->fr_address
= size
;
1759 fragp
->fr_offset
+= new_size
- size
;
1763 /* If the section size is non-zero, the section symbol needs an aux
1764 entry associated with it, indicating the size. We don't know
1765 all the values yet; coff_frob_symbol will fill them in later. */
1768 || sec
== text_section
1769 || sec
== data_section
1770 || sec
== bss_section
)
1773 symbolS
*secsym
= section_symbol (sec
);
1775 S_SET_STORAGE_CLASS (secsym
, C_STAT
);
1776 S_SET_NUMBER_AUXILIARY (secsym
, 1);
1777 SF_SET_STATICS (secsym
);
1778 SA_SET_SCN_SCNLEN (secsym
, size
);
1780 /* FIXME: These should be in a "stabs.h" file, or maybe as.h. */
1781 #ifndef STAB_SECTION_NAME
1782 #define STAB_SECTION_NAME ".stab"
1784 #ifndef STAB_STRING_SECTION_NAME
1785 #define STAB_STRING_SECTION_NAME ".stabstr"
1787 if (! streq (STAB_STRING_SECTION_NAME
, sec
->name
))
1791 sec
= subseg_get (STAB_SECTION_NAME
, 0);
1792 /* size is already rounded up, since other section will be listed first */
1793 size
= bfd_get_section_size (strsec
);
1795 n_entries
= bfd_get_section_size (sec
) / 12 - 1;
1797 /* Find first non-empty frag. It should be large enough. */
1798 fragp
= seg_info (sec
)->frchainP
->frch_root
;
1799 while (fragp
&& fragp
->fr_fix
== 0)
1800 fragp
= fragp
->fr_next
;
1801 gas_assert (fragp
!= 0 && fragp
->fr_fix
>= 12);
1803 /* Store the values. */
1804 p
= fragp
->fr_literal
;
1805 bfd_h_put_16 (stdoutput
, n_entries
, (bfd_byte
*) p
+ 6);
1806 bfd_h_put_32 (stdoutput
, size
, (bfd_byte
*) p
+ 8);
1810 obj_coff_init_stab_section (segT seg
)
1815 unsigned int stroff
;
1817 /* Make space for this first symbol. */
1821 as_where (&file
, (unsigned int *) NULL
);
1822 stabstr_name
= xmalloc (strlen (seg
->name
) + 4);
1823 strcpy (stabstr_name
, seg
->name
);
1824 strcat (stabstr_name
, "str");
1825 stroff
= get_stab_string_offset (file
, stabstr_name
);
1827 md_number_to_chars (p
, stroff
, 4);
1832 s_get_name (symbolS
*s
)
1834 return ((s
== NULL
) ? "(NULL)" : S_GET_NAME (s
));
1842 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
1843 printf (_("0x%lx: \"%s\" type = %ld, class = %d, segment = %d\n"),
1844 (unsigned long) symbolP
,
1845 S_GET_NAME (symbolP
),
1846 (long) S_GET_DATA_TYPE (symbolP
),
1847 S_GET_STORAGE_CLASS (symbolP
),
1848 (int) S_GET_SEGMENT (symbolP
));
1853 const pseudo_typeS coff_pseudo_table
[] =
1855 {"ABORT", s_abort
, 0},
1856 {"appline", obj_coff_ln
, 1},
1857 /* We accept the .bss directive for backward compatibility with
1858 earlier versions of gas. */
1859 {"bss", obj_coff_bss
, 0},
1861 /* PE provides an enhanced version of .comm with alignment. */
1862 {"comm", obj_coff_comm
, 0},
1864 {"def", obj_coff_def
, 0},
1865 {"dim", obj_coff_dim
, 0},
1866 {"endef", obj_coff_endef
, 0},
1867 {"ident", obj_coff_ident
, 0},
1868 {"line", obj_coff_line
, 0},
1869 {"ln", obj_coff_ln
, 0},
1870 {"scl", obj_coff_scl
, 0},
1871 {"sect", obj_coff_section
, 0},
1872 {"sect.s", obj_coff_section
, 0},
1873 {"section", obj_coff_section
, 0},
1874 {"section.s", obj_coff_section
, 0},
1875 /* FIXME: We ignore the MRI short attribute. */
1876 {"size", obj_coff_size
, 0},
1877 {"tag", obj_coff_tag
, 0},
1878 {"type", obj_coff_type
, 0},
1879 {"val", obj_coff_val
, 0},
1880 {"version", s_ignore
, 0},
1881 {"loc", obj_coff_loc
, 0},
1882 {"optim", s_ignore
, 0}, /* For sun386i cc (?) */
1883 {"weak", obj_coff_weak
, 0},
1884 #if defined TC_TIC4X
1885 /* The tic4x uses sdef instead of def. */
1886 {"sdef", obj_coff_def
, 0},
1888 #if defined(SEH_CMDS)
1895 /* Support for a COFF emulation. */
1898 coff_pop_insert (void)
1900 pop_insert (coff_pseudo_table
);
1904 coff_separate_stab_sections (void)
1909 const struct format_ops coff_format_ops
=
1911 bfd_target_coff_flavour
,
1912 0, /* dfl_leading_underscore */
1913 1, /* emit_section_symbols */
1918 0, /* frob_file_before_adjust */
1919 0, /* frob_file_before_fix */
1920 coff_frob_file_after_relocs
,
1923 0, /* s_get_align */
1924 0, /* s_set_align */
1925 0, /* s_get_other */
1926 0, /* s_set_other */
1931 0, /* copy_symbol_attributes */
1932 0, /* generate_asm_lineno */
1933 0, /* process_stab */
1934 coff_separate_stab_sections
,
1935 obj_coff_init_stab_section
,
1936 0, /* sec_sym_ok_for_reloc */
1938 0, /* ecoff_set_ext */
1939 coff_obj_read_begin_hook
,
1940 coff_obj_symbol_new_hook
,
1941 coff_obj_symbol_clone_hook