2009-07-02 Tristan Gingold <gingold@adacore.com>
[binutils.git] / gas / config / obj-coff.c
blobc184cbbaa13c7a1b11b331e08d01e91e33cfeb07
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, 2007
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)
11 any later version.
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
21 02110-1301, USA. */
23 #define OBJ_HEADER "obj-coff.h"
25 #include "as.h"
26 #include "obstack.h"
27 #include "subsegs.h"
29 #ifdef TE_PE
30 #include "coff/pe.h"
31 #endif
33 #define streq(a,b) (strcmp ((a), (b)) == 0)
34 #define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
36 /* I think this is probably always correct. */
37 #ifndef KEEP_RELOC_INFO
38 #define KEEP_RELOC_INFO
39 #endif
41 /* obj_coff_section will use this macro to set a new section's
42 attributes when a directive has no valid flags or the "w" flag is
43 used. This default should be appropriate for most. */
44 #ifndef TC_COFF_SECTION_DEFAULT_ATTRIBUTES
45 #define TC_COFF_SECTION_DEFAULT_ATTRIBUTES (SEC_LOAD | SEC_DATA)
46 #endif
48 /* This is used to hold the symbol built by a sequence of pseudo-ops
49 from .def and .endef. */
50 static symbolS *def_symbol_in_progress;
51 #ifdef TE_PE
52 /* PE weak alternate symbols begin with this string. */
53 static const char weak_altprefix[] = ".weak.";
54 #endif /* TE_PE */
56 typedef struct
58 unsigned long chunk_size;
59 unsigned long element_size;
60 unsigned long size;
61 char *data;
62 unsigned long pointer;
64 stack;
67 /* Stack stuff. */
69 static stack *
70 stack_init (unsigned long chunk_size,
71 unsigned long element_size)
73 stack *st;
75 st = malloc (sizeof (* st));
76 if (!st)
77 return NULL;
78 st->data = malloc (chunk_size);
79 if (!st->data)
81 free (st);
82 return NULL;
84 st->pointer = 0;
85 st->size = chunk_size;
86 st->chunk_size = chunk_size;
87 st->element_size = element_size;
88 return st;
91 static char *
92 stack_push (stack *st, char *element)
94 if (st->pointer + st->element_size >= st->size)
96 st->size += st->chunk_size;
97 if ((st->data = xrealloc (st->data, st->size)) == NULL)
98 return NULL;
100 memcpy (st->data + st->pointer, element, st->element_size);
101 st->pointer += st->element_size;
102 return st->data + st->pointer;
105 static char *
106 stack_pop (stack *st)
108 if (st->pointer < st->element_size)
110 st->pointer = 0;
111 return NULL;
113 st->pointer -= st->element_size;
114 return st->data + st->pointer;
117 /* Maintain a list of the tagnames of the structures. */
119 static struct hash_control *tag_hash;
121 static void
122 tag_init (void)
124 tag_hash = hash_new ();
127 static void
128 tag_insert (const char *name, symbolS *symbolP)
130 const char *error_string;
132 if ((error_string = hash_jam (tag_hash, name, (char *) symbolP)))
133 as_fatal (_("Inserting \"%s\" into structure table failed: %s"),
134 name, error_string);
137 static symbolS *
138 tag_find (char *name)
140 return (symbolS *) hash_find (tag_hash, name);
143 static symbolS *
144 tag_find_or_make (char *name)
146 symbolS *symbolP;
148 if ((symbolP = tag_find (name)) == NULL)
150 symbolP = symbol_new (name, undefined_section,
151 0, &zero_address_frag);
153 tag_insert (S_GET_NAME (symbolP), symbolP);
154 symbol_table_insert (symbolP);
157 return symbolP;
160 /* We accept the .bss directive to set the section for backward
161 compatibility with earlier versions of gas. */
163 static void
164 obj_coff_bss (int ignore ATTRIBUTE_UNUSED)
166 if (*input_line_pointer == '\n')
167 subseg_new (".bss", get_absolute_expression ());
168 else
169 s_lcomm (0);
172 #ifdef TE_PE
173 /* Called from read.c:s_comm after we've parsed .comm symbol, size.
174 Parse a possible alignment value. */
176 static symbolS *
177 obj_coff_common_parse (int ignore ATTRIBUTE_UNUSED, symbolS *symbolP, addressT size)
179 addressT align = 0;
181 if (*input_line_pointer == ',')
183 align = parse_align (0);
184 if (align == (addressT) -1)
185 return NULL;
188 S_SET_VALUE (symbolP, size);
189 S_SET_EXTERNAL (symbolP);
190 S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
192 symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
194 /* There is no S_SET_ALIGN (symbolP, align) in COFF/PE.
195 Instead we must add a note to the .drectve section. */
196 if (align)
198 segT current_seg = now_seg;
199 subsegT current_subseg = now_subseg;
200 flagword oldflags;
201 asection *sec;
202 size_t pfxlen, numlen;
203 char *frag;
204 char numbuff[20];
206 sec = subseg_new (".drectve", 0);
207 oldflags = bfd_get_section_flags (stdoutput, sec);
208 if (oldflags == SEC_NO_FLAGS)
210 if (!bfd_set_section_flags (stdoutput, sec,
211 TC_COFF_SECTION_DEFAULT_ATTRIBUTES))
212 as_warn (_("error setting flags for \"%s\": %s"),
213 bfd_section_name (stdoutput, sec),
214 bfd_errmsg (bfd_get_error ()));
217 /* Emit a string. Note no NUL-termination. */
218 pfxlen = strlen (" -aligncomm:") + 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);
227 return symbolP;
230 static void
231 obj_coff_comm (int ignore ATTRIBUTE_UNUSED)
233 s_comm_internal (ignore, obj_coff_common_parse);
235 #endif /* TE_PE */
237 #define GET_FILENAME_STRING(X) \
238 ((char *) (&((X)->sy_symbol.ost_auxent->x_file.x_n.x_offset))[1])
240 /* @@ Ick. */
241 static segT
242 fetch_coff_debug_section (void)
244 static segT debug_section;
246 if (!debug_section)
248 const asymbol *s;
250 s = bfd_make_debug_symbol (stdoutput, NULL, 0);
251 gas_assert (s != 0);
252 debug_section = s->section;
254 return debug_section;
257 void
258 SA_SET_SYM_ENDNDX (symbolS *sym, symbolS *val)
260 combined_entry_type *entry, *p;
262 entry = &coffsymbol (symbol_get_bfdsym (sym))->native[1];
263 p = coffsymbol (symbol_get_bfdsym (val))->native;
264 entry->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p = p;
265 entry->fix_end = 1;
268 static void
269 SA_SET_SYM_TAGNDX (symbolS *sym, symbolS *val)
271 combined_entry_type *entry, *p;
273 entry = &coffsymbol (symbol_get_bfdsym (sym))->native[1];
274 p = coffsymbol (symbol_get_bfdsym (val))->native;
275 entry->u.auxent.x_sym.x_tagndx.p = p;
276 entry->fix_tag = 1;
279 static int
280 S_GET_DATA_TYPE (symbolS *sym)
282 return coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_type;
286 S_SET_DATA_TYPE (symbolS *sym, int val)
288 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_type = val;
289 return val;
293 S_GET_STORAGE_CLASS (symbolS *sym)
295 return coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_sclass;
299 S_SET_STORAGE_CLASS (symbolS *sym, int val)
301 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_sclass = val;
302 return val;
305 /* Merge a debug symbol containing debug information into a normal symbol. */
307 static void
308 c_symbol_merge (symbolS *debug, symbolS *normal)
310 S_SET_DATA_TYPE (normal, S_GET_DATA_TYPE (debug));
311 S_SET_STORAGE_CLASS (normal, S_GET_STORAGE_CLASS (debug));
313 if (S_GET_NUMBER_AUXILIARY (debug) > S_GET_NUMBER_AUXILIARY (normal))
314 /* Take the most we have. */
315 S_SET_NUMBER_AUXILIARY (normal, S_GET_NUMBER_AUXILIARY (debug));
317 if (S_GET_NUMBER_AUXILIARY (debug) > 0)
318 /* Move all the auxiliary information. */
319 memcpy (SYM_AUXINFO (normal), SYM_AUXINFO (debug),
320 (S_GET_NUMBER_AUXILIARY (debug)
321 * sizeof (*SYM_AUXINFO (debug))));
323 /* Move the debug flags. */
324 SF_SET_DEBUG_FIELD (normal, SF_GET_DEBUG_FIELD (debug));
327 void
328 c_dot_file_symbol (const char *filename, int appfile ATTRIBUTE_UNUSED)
330 symbolS *symbolP;
332 /* BFD converts filename to a .file symbol with an aux entry. It
333 also handles chaining. */
334 symbolP = symbol_new (filename, bfd_abs_section_ptr, 0, &zero_address_frag);
336 S_SET_STORAGE_CLASS (symbolP, C_FILE);
337 S_SET_NUMBER_AUXILIARY (symbolP, 1);
339 symbol_get_bfdsym (symbolP)->flags = BSF_DEBUGGING;
341 #ifndef NO_LISTING
343 extern int listing;
345 if (listing)
346 listing_source_file (filename);
348 #endif
350 /* Make sure that the symbol is first on the symbol chain. */
351 if (symbol_rootP != symbolP)
353 symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
354 symbol_insert (symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP);
358 /* Line number handling. */
360 struct line_no
362 struct line_no *next;
363 fragS *frag;
364 alent l;
367 int coff_line_base;
369 /* Symbol of last function, which we should hang line#s off of. */
370 static symbolS *line_fsym;
372 #define in_function() (line_fsym != 0)
373 #define clear_function() (line_fsym = 0)
374 #define set_function(F) (line_fsym = (F), coff_add_linesym (F))
377 void
378 coff_obj_symbol_new_hook (symbolS *symbolP)
380 long sz = (OBJ_COFF_MAX_AUXENTRIES + 1) * sizeof (combined_entry_type);
381 char * s = xmalloc (sz);
383 memset (s, 0, sz);
384 coffsymbol (symbol_get_bfdsym (symbolP))->native = (combined_entry_type *) s;
386 S_SET_DATA_TYPE (symbolP, T_NULL);
387 S_SET_STORAGE_CLASS (symbolP, 0);
388 S_SET_NUMBER_AUXILIARY (symbolP, 0);
390 if (S_IS_STRING (symbolP))
391 SF_SET_STRING (symbolP);
393 if (S_IS_LOCAL (symbolP))
394 SF_SET_LOCAL (symbolP);
397 void
398 coff_obj_symbol_clone_hook (symbolS *newsymP, symbolS *orgsymP)
400 long sz = (OBJ_COFF_MAX_AUXENTRIES + 1) * sizeof (combined_entry_type);
401 combined_entry_type * s = xmalloc (sz);
403 memcpy (s, coffsymbol (symbol_get_bfdsym (orgsymP))->native, sz);
404 coffsymbol (symbol_get_bfdsym (newsymP))->native = s;
406 SF_SET (newsymP, SF_GET (orgsymP));
410 /* Handle .ln directives. */
412 static symbolS *current_lineno_sym;
413 static struct line_no *line_nos;
414 /* FIXME: Blindly assume all .ln directives will be in the .text section. */
415 int coff_n_line_nos;
417 static void
418 add_lineno (fragS * frag, addressT offset, int num)
420 struct line_no * new_line = xmalloc (sizeof (* new_line));
422 if (!current_lineno_sym)
423 abort ();
425 #ifndef OBJ_XCOFF
426 /* The native aix assembler accepts negative line number. */
428 if (num <= 0)
430 /* Zero is used as an end marker in the file. */
431 as_warn (_("Line numbers must be positive integers\n"));
432 num = 1;
434 #endif /* OBJ_XCOFF */
435 new_line->next = line_nos;
436 new_line->frag = frag;
437 new_line->l.line_number = num;
438 new_line->l.u.offset = offset;
439 line_nos = new_line;
440 coff_n_line_nos++;
443 void
444 coff_add_linesym (symbolS *sym)
446 if (line_nos)
448 coffsymbol (symbol_get_bfdsym (current_lineno_sym))->lineno =
449 (alent *) line_nos;
450 coff_n_line_nos++;
451 line_nos = 0;
453 current_lineno_sym = sym;
456 static void
457 obj_coff_ln (int appline)
459 int l;
461 if (! appline && def_symbol_in_progress != NULL)
463 as_warn (_(".ln pseudo-op inside .def/.endef: ignored."));
464 demand_empty_rest_of_line ();
465 return;
468 l = get_absolute_expression ();
470 /* If there is no lineno symbol, treat a .ln
471 directive as if it were a .appline directive. */
472 if (appline || current_lineno_sym == NULL)
473 new_logical_line ((char *) NULL, l - 1);
474 else
475 add_lineno (frag_now, frag_now_fix (), l);
477 #ifndef NO_LISTING
479 extern int listing;
481 if (listing)
483 if (! appline)
484 l += coff_line_base - 1;
485 listing_source_line (l);
488 #endif
490 demand_empty_rest_of_line ();
493 /* .loc is essentially the same as .ln; parse it for assembler
494 compatibility. */
496 static void
497 obj_coff_loc (int ignore ATTRIBUTE_UNUSED)
499 int lineno;
501 /* FIXME: Why do we need this check? We need it for ECOFF, but why
502 do we need it for COFF? */
503 if (now_seg != text_section)
505 as_warn (_(".loc outside of .text"));
506 demand_empty_rest_of_line ();
507 return;
510 if (def_symbol_in_progress != NULL)
512 as_warn (_(".loc pseudo-op inside .def/.endef: ignored."));
513 demand_empty_rest_of_line ();
514 return;
517 /* Skip the file number. */
518 SKIP_WHITESPACE ();
519 get_absolute_expression ();
520 SKIP_WHITESPACE ();
522 lineno = get_absolute_expression ();
524 #ifndef NO_LISTING
526 extern int listing;
528 if (listing)
530 lineno += coff_line_base - 1;
531 listing_source_line (lineno);
534 #endif
536 demand_empty_rest_of_line ();
538 add_lineno (frag_now, frag_now_fix (), lineno);
541 /* Handle the .ident pseudo-op. */
543 static void
544 obj_coff_ident (int ignore ATTRIBUTE_UNUSED)
546 segT current_seg = now_seg;
547 subsegT current_subseg = now_subseg;
549 #ifdef TE_PE
551 segT sec;
553 /* We could put it in .comment, but that creates an extra section
554 that shouldn't be loaded into memory, which requires linker
555 changes... For now, until proven otherwise, use .rdata. */
556 sec = subseg_new (".rdata$zzz", 0);
557 bfd_set_section_flags (stdoutput, sec,
558 ((SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA)
559 & bfd_applicable_section_flags (stdoutput)));
561 #else
562 subseg_new (".comment", 0);
563 #endif
565 stringer (8 + 1);
566 subseg_set (current_seg, current_subseg);
569 /* Handle .def directives.
571 One might ask : why can't we symbol_new if the symbol does not
572 already exist and fill it with debug information. Because of
573 the C_EFCN special symbol. It would clobber the value of the
574 function symbol before we have a chance to notice that it is
575 a C_EFCN. And a second reason is that the code is more clear this
576 way. (at least I think it is :-). */
578 #define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';')
579 #define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \
580 *input_line_pointer == '\t') \
581 input_line_pointer++;
583 static void
584 obj_coff_def (int what ATTRIBUTE_UNUSED)
586 char name_end; /* Char after the end of name. */
587 char *symbol_name; /* Name of the debug symbol. */
588 char *symbol_name_copy; /* Temporary copy of the name. */
589 unsigned int symbol_name_length;
591 if (def_symbol_in_progress != NULL)
593 as_warn (_(".def pseudo-op used inside of .def/.endef: ignored."));
594 demand_empty_rest_of_line ();
595 return;
598 SKIP_WHITESPACES ();
600 symbol_name = input_line_pointer;
601 name_end = get_symbol_end ();
602 symbol_name_length = strlen (symbol_name);
603 symbol_name_copy = xmalloc (symbol_name_length + 1);
604 strcpy (symbol_name_copy, symbol_name);
605 #ifdef tc_canonicalize_symbol_name
606 symbol_name_copy = tc_canonicalize_symbol_name (symbol_name_copy);
607 #endif
609 /* Initialize the new symbol. */
610 def_symbol_in_progress = symbol_make (symbol_name_copy);
611 symbol_set_frag (def_symbol_in_progress, &zero_address_frag);
612 S_SET_VALUE (def_symbol_in_progress, 0);
614 if (S_IS_STRING (def_symbol_in_progress))
615 SF_SET_STRING (def_symbol_in_progress);
617 *input_line_pointer = name_end;
619 demand_empty_rest_of_line ();
622 unsigned int dim_index;
624 static void
625 obj_coff_endef (int ignore ATTRIBUTE_UNUSED)
627 symbolS *symbolP = NULL;
629 dim_index = 0;
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 ();
634 return;
637 /* Set the section number according to storage class. */
638 switch (S_GET_STORAGE_CLASS (def_symbol_in_progress))
640 case C_STRTAG:
641 case C_ENTAG:
642 case C_UNTAG:
643 SF_SET_TAG (def_symbol_in_progress);
644 /* Fall through. */
645 case C_FILE:
646 case C_TPDEF:
647 SF_SET_DEBUG (def_symbol_in_progress);
648 S_SET_SEGMENT (def_symbol_in_progress, fetch_coff_debug_section ());
649 break;
651 case C_EFCN:
652 SF_SET_LOCAL (def_symbol_in_progress); /* Do not emit this symbol. */
653 /* Fall through. */
654 case C_BLOCK:
655 SF_SET_PROCESS (def_symbol_in_progress); /* Will need processing before writing. */
656 /* Fall through. */
657 case C_FCN:
659 const char *name;
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')
666 switch (name[1])
668 case 'b':
669 /* .bf */
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);
674 clear_function ();
675 break;
676 #ifdef TE_PE
677 case 'e':
678 /* .ef */
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)
684 + coff_line_base));
685 break;
686 #endif
690 break;
692 #ifdef C_AUTOARG
693 case C_AUTOARG:
694 #endif /* C_AUTOARG */
695 case C_AUTO:
696 case C_REG:
697 case C_ARG:
698 case C_REGPARM:
699 case C_FIELD:
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. */
725 #ifdef STRICTCOFF
726 case C_MOS:
727 case C_MOE:
728 case C_MOU:
729 case C_EOS:
730 #endif
731 SF_SET_DEBUG (def_symbol_in_progress);
732 S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
733 break;
735 #ifndef STRICTCOFF
736 case C_MOS:
737 case C_MOE:
738 case C_MOU:
739 case C_EOS:
740 S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
741 break;
742 #endif
744 case C_EXT:
745 case C_WEAKEXT:
746 #ifdef TE_PE
747 case C_NT_WEAK:
748 #endif
749 case C_STAT:
750 case C_LABEL:
751 /* Valid but set somewhere else (s_comm, s_lcomm, colon). */
752 break;
754 default:
755 case C_USTATIC:
756 case C_EXTDEF:
757 case C_ULABEL:
758 as_warn (_("unexpected storage class %d"),
759 S_GET_STORAGE_CLASS (def_symbol_in_progress));
760 break;
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
780 time. */
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)),
786 "*DEBUG*")
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,
798 &symbol_lastP);
801 else
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
807 symbols. [loic] */
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))
835 symbolS *oldtag;
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);
848 if (symbolP == NULL)
849 /* That is, if this is the first time we've seen the
850 function. */
851 symbol_table_insert (def_symbol_in_progress);
855 def_symbol_in_progress = NULL;
856 demand_empty_rest_of_line ();
859 static void
860 obj_coff_dim (int ignore ATTRIBUTE_UNUSED)
862 int dim_index;
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 ();
868 return;
871 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
873 for (dim_index = 0; dim_index < DIMNUM; dim_index++)
875 SKIP_WHITESPACES ();
876 SA_SET_SYM_DIMEN (def_symbol_in_progress, dim_index,
877 get_absolute_expression ());
879 switch (*input_line_pointer)
881 case ',':
882 input_line_pointer++;
883 break;
885 default:
886 as_warn (_("badly formed .dim directive ignored"));
887 /* Fall through. */
888 case '\n':
889 case ';':
890 dim_index = DIMNUM;
891 break;
895 demand_empty_rest_of_line ();
898 static void
899 obj_coff_line (int ignore ATTRIBUTE_UNUSED)
901 int this_base;
903 if (def_symbol_in_progress == NULL)
905 /* Probably stabs-style line? */
906 obj_coff_ln (0);
907 return;
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 ();
919 #ifndef NO_LISTING
920 if (streq (".bf", S_GET_NAME (def_symbol_in_progress)))
922 extern int listing;
924 if (listing)
925 listing_source_line ((unsigned int) this_base);
927 #endif
930 static void
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 ();
937 return;
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 ();
945 static void
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 ();
952 return;
955 S_SET_STORAGE_CLASS (def_symbol_in_progress, get_absolute_expression ());
956 demand_empty_rest_of_line ();
959 static void
960 obj_coff_tag (int ignore ATTRIBUTE_UNUSED)
962 char *symbol_name;
963 char name_end;
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 ();
969 return;
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);
978 #endif
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 ();
993 static void
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 ();
1000 return;
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 ();
1012 static void
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 ();
1019 return;
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);
1029 #endif
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))
1038 expressionS exp;
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
1048 symbol. */
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
1055 just below. */
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;
1061 else
1063 S_SET_VALUE (def_symbol_in_progress, get_absolute_expression ());
1066 demand_empty_rest_of_line ();
1069 #ifdef TE_PE
1071 /* Return nonzero if name begins with weak alternate symbol prefix. */
1073 static int
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. */
1082 static const char *
1083 weak_name2altname (const char * name)
1085 char *alt_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. */
1095 static const char *
1096 weak_altname2name (const char * name)
1098 char * weak_name;
1099 char * dot;
1101 gas_assert (weak_is_altname (name));
1103 weak_name = xstrdup (name + 6);
1104 if ((dot = strchr (weak_name, '.')))
1105 *dot = 0;
1106 return weak_name;
1109 /* Make a weak symbol name unique by
1110 appending the name of an external symbol. */
1112 static const char *
1113 weak_uniquify (const char * name)
1115 char *ret;
1116 const char * unique = "";
1118 #ifdef USE_UNIQUE
1119 if (an_external_name != NULL)
1120 unique = an_external_name;
1121 #endif
1122 gas_assert (weak_is_altname (name));
1124 if (strchr (name + sizeof (weak_altprefix), '.'))
1125 return name;
1127 ret = xmalloc (strlen (name) + strlen (unique) + 2);
1128 strcpy (ret, name);
1129 strcat (ret, ".");
1130 strcat (ret, unique);
1131 return ret;
1134 void
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);
1155 void
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);
1167 #endif /* TE_PE */
1169 /* Handle .weak. This is a GNU extension in formats other than PE. */
1171 static void
1172 obj_coff_weak (int ignore ATTRIBUTE_UNUSED)
1174 char *name;
1175 int c;
1176 symbolS *symbolP;
1180 name = input_line_pointer;
1181 c = get_symbol_end ();
1182 if (*name == 0)
1184 as_warn (_("badly formed .weak directive ignored"));
1185 ignore_rest_of_line ();
1186 return;
1188 c = 0;
1189 symbolP = symbol_find_or_make (name);
1190 *input_line_pointer = c;
1191 SKIP_WHITESPACE ();
1192 S_SET_WEAK (symbolP);
1194 if (c == ',')
1196 input_line_pointer++;
1197 SKIP_WHITESPACE ();
1198 if (*input_line_pointer == '\n')
1199 c = '\n';
1203 while (c == ',');
1205 demand_empty_rest_of_line ();
1208 void
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);
1214 tag_init ();
1217 symbolS *coff_last_function;
1218 #ifndef OBJ_XCOFF
1219 static symbolS *coff_last_bf;
1220 #endif
1222 void
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)
1232 *punt = 1;
1233 return;
1236 if (current_lineno_sym)
1237 coff_add_linesym (NULL);
1239 if (!block_stack)
1240 block_stack = stack_init (512, sizeof (symbolS*));
1242 #ifdef TE_PE
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);
1252 gas_assert (weakp);
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. */
1258 *punt = 1;
1259 return;
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);
1269 *punt = 1;
1270 return;
1272 else
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));
1291 else
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);
1306 #else /* TE_PE */
1307 if (S_IS_WEAK (symp))
1308 S_SET_STORAGE_CLASS (symp, C_WEAKEXT);
1309 #endif /* TE_PE */
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))
1318 symbolS * real;
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
1326 && real != symp)
1328 c_symbol_merge (symp, real);
1329 *punt = 1;
1330 return;
1333 if (!S_IS_DEFINED (symp) && !SF_GET_LOCAL (symp))
1335 gas_assert (S_GET_VALUE (symp) == 0);
1336 if (S_IS_WEAKREFD (symp))
1337 *punt = 1;
1338 else
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);
1346 else
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);
1356 else
1358 symbolS *begin;
1360 begin = *(symbolS **) stack_pop (block_stack);
1361 if (begin == 0)
1362 as_warn (_("mismatched .eb"));
1363 else
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"),
1384 S_GET_NAME (symp));
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))
1396 *punt = 1;
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"),
1405 S_GET_NAME (symp));
1407 if (SF_GET_TAG (symp))
1408 last_tagP = symp;
1409 else if (S_GET_STORAGE_CLASS (symp) == C_EOS)
1410 next_set_end = last_tagP;
1412 #ifdef OBJ_XCOFF
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)))
1420 *punt = 1;
1421 #endif
1423 if (set_end != (symbolS *) NULL
1424 && ! *punt
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);
1431 set_end = NULL;
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;
1442 #ifndef OBJ_XCOFF
1443 if (! *punt
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;
1451 #endif
1452 if (coffsymbol (symbol_get_bfdsym (symp))->lineno)
1454 int i;
1455 struct line_no *lptr;
1456 alent *l;
1458 lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno;
1459 for (i = 0; lptr; lptr = lptr->next)
1460 i++;
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;
1470 for (; i > 0; i--)
1472 if (lptr->frag)
1473 lptr->l.u.offset += lptr->frag->fr_address / OCTETS_PER_BYTE;
1474 l[i] = lptr->l;
1475 lptr = lptr->next;
1480 void
1481 coff_adjust_section_syms (bfd *abfd ATTRIBUTE_UNUSED,
1482 asection *sec,
1483 void * x ATTRIBUTE_UNUSED)
1485 symbolS *secsym;
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)
1492 return;
1494 if (streq (sec->name, ".text"))
1495 nlnno = coff_n_line_nos;
1496 else
1497 nlnno = 0;
1499 /* @@ Hope that none of the fixups expand to more than one reloc
1500 entry... */
1501 fixS *fixp = seginfo->fix_root;
1502 while (fixp)
1504 if (! fixp->fx_done)
1505 nrelocs++;
1506 fixp = fixp->fx_next;
1509 if (bfd_get_section_size (sec) == 0
1510 && nrelocs == 0
1511 && nlnno == 0
1512 && sec != text_section
1513 && sec != data_section
1514 && sec != bss_section)
1515 return;
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);
1524 void
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
1534 | 'i' for info
1535 +-- section name 'l' for lib
1536 'n' for noload
1537 'o' for over
1538 'w' for data
1539 'd' (apparently m88k for data)
1540 'x' for text
1541 'r' for read-only data
1542 's' for shared data (PE)
1543 'y' for noread
1544 But if the argument is not a quoted string, treat it as a
1545 subsegment number.
1547 Note the 'a' flag is silently ignored. This allows the same
1548 .section directive to be parsed in both ELF and COFF formats. */
1550 void
1551 obj_coff_section (int ignore ATTRIBUTE_UNUSED)
1553 /* Strip out the section name. */
1554 char *section_name;
1555 char c;
1556 char *name;
1557 unsigned int exp;
1558 flagword flags, oldflags;
1559 asection *sec;
1561 if (flag_mri)
1563 char type;
1565 s_mri_sect (&type);
1566 return;
1569 section_name = input_line_pointer;
1570 c = get_symbol_end ();
1572 name = xmalloc (input_line_pointer - section_name + 1);
1573 strcpy (name, section_name);
1575 *input_line_pointer = c;
1577 SKIP_WHITESPACE ();
1579 exp = 0;
1580 flags = SEC_NO_FLAGS;
1582 if (*input_line_pointer == ',')
1584 ++input_line_pointer;
1585 SKIP_WHITESPACE ();
1586 if (*input_line_pointer != '"')
1587 exp = get_absolute_expression ();
1588 else
1590 unsigned char attr;
1591 int readonly_removed = 0;
1592 int load_removed = 0;
1594 while (attr = *++input_line_pointer,
1595 attr != '"'
1596 && ! is_end_of_line[attr])
1598 switch (attr)
1600 case 'b':
1601 /* Uninitialised data section. */
1602 flags |= SEC_ALLOC;
1603 flags &=~ SEC_LOAD;
1604 break;
1606 case 'n':
1607 /* Section not loaded. */
1608 flags &=~ SEC_LOAD;
1609 flags |= SEC_NEVER_LOAD;
1610 load_removed = 1;
1611 break;
1613 case 's':
1614 /* Shared section. */
1615 flags |= SEC_COFF_SHARED;
1616 /* Fall through. */
1617 case 'd':
1618 /* Data section. */
1619 flags |= SEC_DATA;
1620 if (! load_removed)
1621 flags |= SEC_LOAD;
1622 flags &=~ SEC_READONLY;
1623 break;
1625 case 'w':
1626 /* Writable section. */
1627 flags &=~ SEC_READONLY;
1628 readonly_removed = 1;
1629 break;
1631 case 'a':
1632 /* Ignore. Here for compatibility with ELF. */
1633 break;
1635 case 'r': /* Read-only section. Implies a data section. */
1636 readonly_removed = 0;
1637 /* Fall through. */
1638 case 'x': /* Executable section. */
1639 /* If we are setting the 'x' attribute or if the 'r'
1640 attribute is being used to restore the readonly status
1641 of a code section (eg "wxr") then set the SEC_CODE flag,
1642 otherwise set the SEC_DATA flag. */
1643 flags |= (attr == 'x' || (flags & SEC_CODE) ? SEC_CODE : SEC_DATA);
1644 if (! load_removed)
1645 flags |= SEC_LOAD;
1646 /* Note - the READONLY flag is set here, even for the 'x'
1647 attribute in order to be compatible with the MSVC
1648 linker. */
1649 if (! readonly_removed)
1650 flags |= SEC_READONLY;
1651 break;
1653 case 'y':
1654 flags |= SEC_COFF_NOREAD | SEC_READONLY;
1655 break;
1657 case 'i': /* STYP_INFO */
1658 case 'l': /* STYP_LIB */
1659 case 'o': /* STYP_OVER */
1660 as_warn (_("unsupported section attribute '%c'"), attr);
1661 break;
1663 default:
1664 as_warn (_("unknown section attribute '%c'"), attr);
1665 break;
1668 if (attr == '"')
1669 ++input_line_pointer;
1673 sec = subseg_new (name, (subsegT) exp);
1675 oldflags = bfd_get_section_flags (stdoutput, sec);
1676 if (oldflags == SEC_NO_FLAGS)
1678 /* Set section flags for a new section just created by subseg_new.
1679 Provide a default if no flags were parsed. */
1680 if (flags == SEC_NO_FLAGS)
1681 flags = TC_COFF_SECTION_DEFAULT_ATTRIBUTES;
1683 #ifdef COFF_LONG_SECTION_NAMES
1684 /* Add SEC_LINK_ONCE and SEC_LINK_DUPLICATES_DISCARD to .gnu.linkonce
1685 sections so adjust_reloc_syms in write.c will correctly handle
1686 relocs which refer to non-local symbols in these sections. */
1687 if (strneq (name, ".gnu.linkonce", sizeof (".gnu.linkonce") - 1))
1688 flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
1689 #endif
1691 if (! bfd_set_section_flags (stdoutput, sec, flags))
1692 as_warn (_("error setting flags for \"%s\": %s"),
1693 bfd_section_name (stdoutput, sec),
1694 bfd_errmsg (bfd_get_error ()));
1696 else if (flags != SEC_NO_FLAGS)
1698 /* This section's attributes have already been set. Warn if the
1699 attributes don't match. */
1700 flagword matchflags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
1701 | SEC_DATA | SEC_COFF_SHARED | SEC_NEVER_LOAD
1702 | SEC_COFF_NOREAD);
1703 if ((flags ^ oldflags) & matchflags)
1704 as_warn (_("Ignoring changed section attributes for %s"), name);
1707 demand_empty_rest_of_line ();
1710 void
1711 coff_adjust_symtab (void)
1713 if (symbol_rootP == NULL
1714 || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
1715 c_dot_file_symbol ("fake", 0);
1718 void
1719 coff_frob_section (segT sec)
1721 segT strsec;
1722 char *p;
1723 fragS *fragp;
1724 bfd_vma size, n_entries, mask;
1725 bfd_vma align_power = (bfd_vma)sec->alignment_power + OCTETS_PER_BYTE_POWER;
1727 /* The COFF back end in BFD requires that all section sizes be
1728 rounded up to multiples of the corresponding section alignments,
1729 supposedly because standard COFF has no other way of encoding alignment
1730 for sections. If your COFF flavor has a different way of encoding
1731 section alignment, then skip this step, as TICOFF does. */
1732 size = bfd_get_section_size (sec);
1733 mask = ((bfd_vma) 1 << align_power) - 1;
1734 #if !defined(TICOFF)
1735 if (size & mask)
1737 bfd_vma new_size;
1738 fragS *last;
1740 new_size = (size + mask) & ~mask;
1741 bfd_set_section_size (stdoutput, sec, new_size);
1743 /* If the size had to be rounded up, add some padding in
1744 the last non-empty frag. */
1745 fragp = seg_info (sec)->frchainP->frch_root;
1746 last = seg_info (sec)->frchainP->frch_last;
1747 while (fragp->fr_next != last)
1748 fragp = fragp->fr_next;
1749 last->fr_address = size;
1750 fragp->fr_offset += new_size - size;
1752 #endif
1754 /* If the section size is non-zero, the section symbol needs an aux
1755 entry associated with it, indicating the size. We don't know
1756 all the values yet; coff_frob_symbol will fill them in later. */
1757 #ifndef TICOFF
1758 if (size != 0
1759 || sec == text_section
1760 || sec == data_section
1761 || sec == bss_section)
1762 #endif
1764 symbolS *secsym = section_symbol (sec);
1766 S_SET_STORAGE_CLASS (secsym, C_STAT);
1767 S_SET_NUMBER_AUXILIARY (secsym, 1);
1768 SF_SET_STATICS (secsym);
1769 SA_SET_SCN_SCNLEN (secsym, size);
1772 /* FIXME: These should be in a "stabs.h" file, or maybe as.h. */
1773 #ifndef STAB_SECTION_NAME
1774 #define STAB_SECTION_NAME ".stab"
1775 #endif
1776 #ifndef STAB_STRING_SECTION_NAME
1777 #define STAB_STRING_SECTION_NAME ".stabstr"
1778 #endif
1779 if (! streq (STAB_STRING_SECTION_NAME, sec->name))
1780 return;
1782 strsec = sec;
1783 sec = subseg_get (STAB_SECTION_NAME, 0);
1784 /* size is already rounded up, since other section will be listed first */
1785 size = bfd_get_section_size (strsec);
1787 n_entries = bfd_get_section_size (sec) / 12 - 1;
1789 /* Find first non-empty frag. It should be large enough. */
1790 fragp = seg_info (sec)->frchainP->frch_root;
1791 while (fragp && fragp->fr_fix == 0)
1792 fragp = fragp->fr_next;
1793 gas_assert (fragp != 0 && fragp->fr_fix >= 12);
1795 /* Store the values. */
1796 p = fragp->fr_literal;
1797 bfd_h_put_16 (stdoutput, n_entries, (bfd_byte *) p + 6);
1798 bfd_h_put_32 (stdoutput, size, (bfd_byte *) p + 8);
1801 void
1802 obj_coff_init_stab_section (segT seg)
1804 char *file;
1805 char *p;
1806 char *stabstr_name;
1807 unsigned int stroff;
1809 /* Make space for this first symbol. */
1810 p = frag_more (12);
1811 /* Zero it out. */
1812 memset (p, 0, 12);
1813 as_where (&file, (unsigned int *) NULL);
1814 stabstr_name = xmalloc (strlen (seg->name) + 4);
1815 strcpy (stabstr_name, seg->name);
1816 strcat (stabstr_name, "str");
1817 stroff = get_stab_string_offset (file, stabstr_name);
1818 know (stroff == 1);
1819 md_number_to_chars (p, stroff, 4);
1822 #ifdef DEBUG
1823 const char *
1824 s_get_name (symbolS *s)
1826 return ((s == NULL) ? "(NULL)" : S_GET_NAME (s));
1829 void
1830 symbol_dump (void)
1832 symbolS *symbolP;
1834 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
1835 printf (_("0x%lx: \"%s\" type = %ld, class = %d, segment = %d\n"),
1836 (unsigned long) symbolP,
1837 S_GET_NAME (symbolP),
1838 (long) S_GET_DATA_TYPE (symbolP),
1839 S_GET_STORAGE_CLASS (symbolP),
1840 (int) S_GET_SEGMENT (symbolP));
1843 #endif /* DEBUG */
1845 const pseudo_typeS coff_pseudo_table[] =
1847 {"ABORT", s_abort, 0},
1848 {"appline", obj_coff_ln, 1},
1849 /* We accept the .bss directive for backward compatibility with
1850 earlier versions of gas. */
1851 {"bss", obj_coff_bss, 0},
1852 #ifdef TE_PE
1853 /* PE provides an enhanced version of .comm with alignment. */
1854 {"comm", obj_coff_comm, 0},
1855 #endif /* TE_PE */
1856 {"def", obj_coff_def, 0},
1857 {"dim", obj_coff_dim, 0},
1858 {"endef", obj_coff_endef, 0},
1859 {"ident", obj_coff_ident, 0},
1860 {"line", obj_coff_line, 0},
1861 {"ln", obj_coff_ln, 0},
1862 {"scl", obj_coff_scl, 0},
1863 {"sect", obj_coff_section, 0},
1864 {"sect.s", obj_coff_section, 0},
1865 {"section", obj_coff_section, 0},
1866 {"section.s", obj_coff_section, 0},
1867 /* FIXME: We ignore the MRI short attribute. */
1868 {"size", obj_coff_size, 0},
1869 {"tag", obj_coff_tag, 0},
1870 {"type", obj_coff_type, 0},
1871 {"val", obj_coff_val, 0},
1872 {"version", s_ignore, 0},
1873 {"loc", obj_coff_loc, 0},
1874 {"optim", s_ignore, 0}, /* For sun386i cc (?) */
1875 {"weak", obj_coff_weak, 0},
1876 #if defined TC_TIC4X
1877 /* The tic4x uses sdef instead of def. */
1878 {"sdef", obj_coff_def, 0},
1879 #endif
1880 {NULL, NULL, 0}
1884 /* Support for a COFF emulation. */
1886 static void
1887 coff_pop_insert (void)
1889 pop_insert (coff_pseudo_table);
1892 static int
1893 coff_separate_stab_sections (void)
1895 return 1;
1898 const struct format_ops coff_format_ops =
1900 bfd_target_coff_flavour,
1901 0, /* dfl_leading_underscore */
1902 1, /* emit_section_symbols */
1903 0, /* begin */
1904 c_dot_file_symbol,
1905 coff_frob_symbol,
1906 0, /* frob_file */
1907 0, /* frob_file_before_adjust */
1908 0, /* frob_file_before_fix */
1909 coff_frob_file_after_relocs,
1910 0, /* s_get_size */
1911 0, /* s_set_size */
1912 0, /* s_get_align */
1913 0, /* s_set_align */
1914 0, /* s_get_other */
1915 0, /* s_set_other */
1916 0, /* s_get_desc */
1917 0, /* s_set_desc */
1918 0, /* s_get_type */
1919 0, /* s_set_type */
1920 0, /* copy_symbol_attributes */
1921 0, /* generate_asm_lineno */
1922 0, /* process_stab */
1923 coff_separate_stab_sections,
1924 obj_coff_init_stab_section,
1925 0, /* sec_sym_ok_for_reloc */
1926 coff_pop_insert,
1927 0, /* ecoff_set_ext */
1928 coff_obj_read_begin_hook,
1929 coff_obj_symbol_new_hook