Add -Wshadow to the gcc command line options used when compiling the binutils.
[binutils.git] / gas / config / obj-coff.c
blobaa621b96d56e45198e109cc242d5073fd91e8741
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)
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 #include "obj-coff-seh.c"
58 typedef struct
60 unsigned long chunk_size;
61 unsigned long element_size;
62 unsigned long size;
63 char *data;
64 unsigned long pointer;
66 stack;
69 /* Stack stuff. */
71 static stack *
72 stack_init (unsigned long chunk_size,
73 unsigned long element_size)
75 stack *st;
77 st = malloc (sizeof (* st));
78 if (!st)
79 return NULL;
80 st->data = malloc (chunk_size);
81 if (!st->data)
83 free (st);
84 return NULL;
86 st->pointer = 0;
87 st->size = chunk_size;
88 st->chunk_size = chunk_size;
89 st->element_size = element_size;
90 return st;
93 static char *
94 stack_push (stack *st, char *element)
96 if (st->pointer + st->element_size >= st->size)
98 st->size += st->chunk_size;
99 if ((st->data = xrealloc (st->data, st->size)) == NULL)
100 return NULL;
102 memcpy (st->data + st->pointer, element, st->element_size);
103 st->pointer += st->element_size;
104 return st->data + st->pointer;
107 static char *
108 stack_pop (stack *st)
110 if (st->pointer < st->element_size)
112 st->pointer = 0;
113 return NULL;
115 st->pointer -= st->element_size;
116 return st->data + st->pointer;
119 /* Maintain a list of the tagnames of the structures. */
121 static struct hash_control *tag_hash;
123 static void
124 tag_init (void)
126 tag_hash = hash_new ();
129 static void
130 tag_insert (const char *name, symbolS *symbolP)
132 const char *error_string;
134 if ((error_string = hash_jam (tag_hash, name, (char *) symbolP)))
135 as_fatal (_("Inserting \"%s\" into structure table failed: %s"),
136 name, error_string);
139 static symbolS *
140 tag_find (char *name)
142 return (symbolS *) hash_find (tag_hash, name);
145 static symbolS *
146 tag_find_or_make (char *name)
148 symbolS *symbolP;
150 if ((symbolP = tag_find (name)) == NULL)
152 symbolP = symbol_new (name, undefined_section,
153 0, &zero_address_frag);
155 tag_insert (S_GET_NAME (symbolP), symbolP);
156 symbol_table_insert (symbolP);
159 return symbolP;
162 /* We accept the .bss directive to set the section for backward
163 compatibility with earlier versions of gas. */
165 static void
166 obj_coff_bss (int ignore ATTRIBUTE_UNUSED)
168 if (*input_line_pointer == '\n')
169 subseg_new (".bss", get_absolute_expression ());
170 else
171 s_lcomm (0);
174 #ifdef TE_PE
175 /* Called from read.c:s_comm after we've parsed .comm symbol, size.
176 Parse a possible alignment value. */
178 static symbolS *
179 obj_coff_common_parse (int ignore ATTRIBUTE_UNUSED, symbolS *symbolP, addressT size)
181 addressT align = 0;
183 if (*input_line_pointer == ',')
185 align = parse_align (0);
186 if (align == (addressT) -1)
187 return NULL;
190 S_SET_VALUE (symbolP, size);
191 S_SET_EXTERNAL (symbolP);
192 S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
194 symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
196 /* There is no S_SET_ALIGN (symbolP, align) in COFF/PE.
197 Instead we must add a note to the .drectve section. */
198 if (align)
200 segT current_seg = now_seg;
201 subsegT current_subseg = now_subseg;
202 flagword oldflags;
203 asection *sec;
204 size_t pfxlen, numlen;
205 char *frag;
206 char numbuff[20];
208 sec = subseg_new (".drectve", 0);
209 oldflags = bfd_get_section_flags (stdoutput, sec);
210 if (oldflags == SEC_NO_FLAGS)
212 if (!bfd_set_section_flags (stdoutput, sec,
213 TC_COFF_SECTION_DEFAULT_ATTRIBUTES))
214 as_warn (_("error setting flags for \"%s\": %s"),
215 bfd_section_name (stdoutput, sec),
216 bfd_errmsg (bfd_get_error ()));
219 /* Emit a string. Note no NUL-termination. */
220 pfxlen = strlen (" -aligncomm:") + strlen (S_GET_NAME (symbolP)) + 1;
221 numlen = snprintf (numbuff, sizeof (numbuff), "%d", (int) align);
222 frag = frag_more (pfxlen + numlen);
223 (void) sprintf (frag, " -aligncomm:%s,", S_GET_NAME (symbolP));
224 memcpy (frag + pfxlen, numbuff, numlen);
225 /* Restore original subseg. */
226 subseg_set (current_seg, current_subseg);
229 return symbolP;
232 static void
233 obj_coff_comm (int ignore ATTRIBUTE_UNUSED)
235 s_comm_internal (ignore, obj_coff_common_parse);
237 #endif /* TE_PE */
239 #define GET_FILENAME_STRING(X) \
240 ((char *) (&((X)->sy_symbol.ost_auxent->x_file.x_n.x_offset))[1])
242 /* @@ Ick. */
243 static segT
244 fetch_coff_debug_section (void)
246 static segT debug_section;
248 if (!debug_section)
250 const asymbol *s;
252 s = bfd_make_debug_symbol (stdoutput, NULL, 0);
253 gas_assert (s != 0);
254 debug_section = s->section;
256 return debug_section;
259 void
260 SA_SET_SYM_ENDNDX (symbolS *sym, symbolS *val)
262 combined_entry_type *entry, *p;
264 entry = &coffsymbol (symbol_get_bfdsym (sym))->native[1];
265 p = coffsymbol (symbol_get_bfdsym (val))->native;
266 entry->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p = p;
267 entry->fix_end = 1;
270 static void
271 SA_SET_SYM_TAGNDX (symbolS *sym, symbolS *val)
273 combined_entry_type *entry, *p;
275 entry = &coffsymbol (symbol_get_bfdsym (sym))->native[1];
276 p = coffsymbol (symbol_get_bfdsym (val))->native;
277 entry->u.auxent.x_sym.x_tagndx.p = p;
278 entry->fix_tag = 1;
281 static int
282 S_GET_DATA_TYPE (symbolS *sym)
284 return coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_type;
288 S_SET_DATA_TYPE (symbolS *sym, int val)
290 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_type = val;
291 return val;
295 S_GET_STORAGE_CLASS (symbolS *sym)
297 return coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_sclass;
301 S_SET_STORAGE_CLASS (symbolS *sym, int val)
303 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_sclass = val;
304 return val;
307 /* Merge a debug symbol containing debug information into a normal symbol. */
309 static void
310 c_symbol_merge (symbolS *debug, symbolS *normal)
312 S_SET_DATA_TYPE (normal, S_GET_DATA_TYPE (debug));
313 S_SET_STORAGE_CLASS (normal, S_GET_STORAGE_CLASS (debug));
315 if (S_GET_NUMBER_AUXILIARY (debug) > S_GET_NUMBER_AUXILIARY (normal))
316 /* Take the most we have. */
317 S_SET_NUMBER_AUXILIARY (normal, S_GET_NUMBER_AUXILIARY (debug));
319 if (S_GET_NUMBER_AUXILIARY (debug) > 0)
320 /* Move all the auxiliary information. */
321 memcpy (SYM_AUXINFO (normal), SYM_AUXINFO (debug),
322 (S_GET_NUMBER_AUXILIARY (debug)
323 * sizeof (*SYM_AUXINFO (debug))));
325 /* Move the debug flags. */
326 SF_SET_DEBUG_FIELD (normal, SF_GET_DEBUG_FIELD (debug));
329 void
330 c_dot_file_symbol (const char *filename, int appfile ATTRIBUTE_UNUSED)
332 symbolS *symbolP;
334 /* BFD converts filename to a .file symbol with an aux entry. It
335 also handles chaining. */
336 symbolP = symbol_new (filename, bfd_abs_section_ptr, 0, &zero_address_frag);
338 S_SET_STORAGE_CLASS (symbolP, C_FILE);
339 S_SET_NUMBER_AUXILIARY (symbolP, 1);
341 symbol_get_bfdsym (symbolP)->flags = BSF_DEBUGGING;
343 #ifndef NO_LISTING
345 extern int listing;
347 if (listing)
348 listing_source_file (filename);
350 #endif
352 /* Make sure that the symbol is first on the symbol chain. */
353 if (symbol_rootP != symbolP)
355 symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
356 symbol_insert (symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP);
360 /* Line number handling. */
362 struct line_no
364 struct line_no *next;
365 fragS *frag;
366 alent l;
369 int coff_line_base;
371 /* Symbol of last function, which we should hang line#s off of. */
372 static symbolS *line_fsym;
374 #define in_function() (line_fsym != 0)
375 #define clear_function() (line_fsym = 0)
376 #define set_function(F) (line_fsym = (F), coff_add_linesym (F))
379 void
380 coff_obj_symbol_new_hook (symbolS *symbolP)
382 long sz = (OBJ_COFF_MAX_AUXENTRIES + 1) * sizeof (combined_entry_type);
383 char * s = xmalloc (sz);
385 memset (s, 0, sz);
386 coffsymbol (symbol_get_bfdsym (symbolP))->native = (combined_entry_type *) s;
388 S_SET_DATA_TYPE (symbolP, T_NULL);
389 S_SET_STORAGE_CLASS (symbolP, 0);
390 S_SET_NUMBER_AUXILIARY (symbolP, 0);
392 if (S_IS_STRING (symbolP))
393 SF_SET_STRING (symbolP);
395 if (S_IS_LOCAL (symbolP))
396 SF_SET_LOCAL (symbolP);
399 void
400 coff_obj_symbol_clone_hook (symbolS *newsymP, symbolS *orgsymP)
402 long sz = (OBJ_COFF_MAX_AUXENTRIES + 1) * sizeof (combined_entry_type);
403 combined_entry_type * s = xmalloc (sz);
405 memcpy (s, coffsymbol (symbol_get_bfdsym (orgsymP))->native, sz);
406 coffsymbol (symbol_get_bfdsym (newsymP))->native = s;
408 SF_SET (newsymP, SF_GET (orgsymP));
412 /* Handle .ln directives. */
414 static symbolS *current_lineno_sym;
415 static struct line_no *line_nos;
416 /* FIXME: Blindly assume all .ln directives will be in the .text section. */
417 int coff_n_line_nos;
419 static void
420 add_lineno (fragS * frag, addressT offset, int num)
422 struct line_no * new_line = xmalloc (sizeof (* new_line));
424 if (!current_lineno_sym)
425 abort ();
427 #ifndef OBJ_XCOFF
428 /* The native aix assembler accepts negative line number. */
430 if (num <= 0)
432 /* Zero is used as an end marker in the file. */
433 as_warn (_("Line numbers must be positive integers\n"));
434 num = 1;
436 #endif /* OBJ_XCOFF */
437 new_line->next = line_nos;
438 new_line->frag = frag;
439 new_line->l.line_number = num;
440 new_line->l.u.offset = offset;
441 line_nos = new_line;
442 coff_n_line_nos++;
445 void
446 coff_add_linesym (symbolS *sym)
448 if (line_nos)
450 coffsymbol (symbol_get_bfdsym (current_lineno_sym))->lineno =
451 (alent *) line_nos;
452 coff_n_line_nos++;
453 line_nos = 0;
455 current_lineno_sym = sym;
458 static void
459 obj_coff_ln (int appline)
461 int l;
463 if (! appline && def_symbol_in_progress != NULL)
465 as_warn (_(".ln pseudo-op inside .def/.endef: ignored."));
466 demand_empty_rest_of_line ();
467 return;
470 l = get_absolute_expression ();
472 /* If there is no lineno symbol, treat a .ln
473 directive as if it were a .appline directive. */
474 if (appline || current_lineno_sym == NULL)
475 new_logical_line ((char *) NULL, l - 1);
476 else
477 add_lineno (frag_now, frag_now_fix (), l);
479 #ifndef NO_LISTING
481 extern int listing;
483 if (listing)
485 if (! appline)
486 l += coff_line_base - 1;
487 listing_source_line (l);
490 #endif
492 demand_empty_rest_of_line ();
495 /* .loc is essentially the same as .ln; parse it for assembler
496 compatibility. */
498 static void
499 obj_coff_loc (int ignore ATTRIBUTE_UNUSED)
501 int lineno;
503 /* FIXME: Why do we need this check? We need it for ECOFF, but why
504 do we need it for COFF? */
505 if (now_seg != text_section)
507 as_warn (_(".loc outside of .text"));
508 demand_empty_rest_of_line ();
509 return;
512 if (def_symbol_in_progress != NULL)
514 as_warn (_(".loc pseudo-op inside .def/.endef: ignored."));
515 demand_empty_rest_of_line ();
516 return;
519 /* Skip the file number. */
520 SKIP_WHITESPACE ();
521 get_absolute_expression ();
522 SKIP_WHITESPACE ();
524 lineno = get_absolute_expression ();
526 #ifndef NO_LISTING
528 extern int listing;
530 if (listing)
532 lineno += coff_line_base - 1;
533 listing_source_line (lineno);
536 #endif
538 demand_empty_rest_of_line ();
540 add_lineno (frag_now, frag_now_fix (), lineno);
543 /* Handle the .ident pseudo-op. */
545 static void
546 obj_coff_ident (int ignore ATTRIBUTE_UNUSED)
548 segT current_seg = now_seg;
549 subsegT current_subseg = now_subseg;
551 #ifdef TE_PE
553 segT sec;
555 /* We could put it in .comment, but that creates an extra section
556 that shouldn't be loaded into memory, which requires linker
557 changes... For now, until proven otherwise, use .rdata. */
558 sec = subseg_new (".rdata$zzz", 0);
559 bfd_set_section_flags (stdoutput, sec,
560 ((SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA)
561 & bfd_applicable_section_flags (stdoutput)));
563 #else
564 subseg_new (".comment", 0);
565 #endif
567 stringer (8 + 1);
568 subseg_set (current_seg, current_subseg);
571 /* Handle .def directives.
573 One might ask : why can't we symbol_new if the symbol does not
574 already exist and fill it with debug information. Because of
575 the C_EFCN special symbol. It would clobber the value of the
576 function symbol before we have a chance to notice that it is
577 a C_EFCN. And a second reason is that the code is more clear this
578 way. (at least I think it is :-). */
580 #define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';')
581 #define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \
582 *input_line_pointer == '\t') \
583 input_line_pointer++;
585 static void
586 obj_coff_def (int what ATTRIBUTE_UNUSED)
588 char name_end; /* Char after the end of name. */
589 char *symbol_name; /* Name of the debug symbol. */
590 char *symbol_name_copy; /* Temporary copy of the name. */
591 unsigned int symbol_name_length;
593 if (def_symbol_in_progress != NULL)
595 as_warn (_(".def pseudo-op used inside of .def/.endef: ignored."));
596 demand_empty_rest_of_line ();
597 return;
600 SKIP_WHITESPACES ();
602 symbol_name = input_line_pointer;
603 name_end = get_symbol_end ();
604 symbol_name_length = strlen (symbol_name);
605 symbol_name_copy = xmalloc (symbol_name_length + 1);
606 strcpy (symbol_name_copy, symbol_name);
607 #ifdef tc_canonicalize_symbol_name
608 symbol_name_copy = tc_canonicalize_symbol_name (symbol_name_copy);
609 #endif
611 /* Initialize the new symbol. */
612 def_symbol_in_progress = symbol_make (symbol_name_copy);
613 symbol_set_frag (def_symbol_in_progress, &zero_address_frag);
614 S_SET_VALUE (def_symbol_in_progress, 0);
616 if (S_IS_STRING (def_symbol_in_progress))
617 SF_SET_STRING (def_symbol_in_progress);
619 *input_line_pointer = name_end;
621 demand_empty_rest_of_line ();
624 static void
625 obj_coff_endef (int ignore ATTRIBUTE_UNUSED)
627 symbolS *symbolP = NULL;
629 if (def_symbol_in_progress == NULL)
631 as_warn (_(".endef pseudo-op used outside of .def/.endef: ignored."));
632 demand_empty_rest_of_line ();
633 return;
636 /* Set the section number according to storage class. */
637 switch (S_GET_STORAGE_CLASS (def_symbol_in_progress))
639 case C_STRTAG:
640 case C_ENTAG:
641 case C_UNTAG:
642 SF_SET_TAG (def_symbol_in_progress);
643 /* Fall through. */
644 case C_FILE:
645 case C_TPDEF:
646 SF_SET_DEBUG (def_symbol_in_progress);
647 S_SET_SEGMENT (def_symbol_in_progress, fetch_coff_debug_section ());
648 break;
650 case C_EFCN:
651 SF_SET_LOCAL (def_symbol_in_progress); /* Do not emit this symbol. */
652 /* Fall through. */
653 case C_BLOCK:
654 SF_SET_PROCESS (def_symbol_in_progress); /* Will need processing before writing. */
655 /* Fall through. */
656 case C_FCN:
658 const char *name;
660 S_SET_SEGMENT (def_symbol_in_progress, text_section);
662 name = S_GET_NAME (def_symbol_in_progress);
663 if (name[0] == '.' && name[2] == 'f' && name[3] == '\0')
665 switch (name[1])
667 case 'b':
668 /* .bf */
669 if (! in_function ())
670 as_warn (_("`%s' symbol without preceding function"), name);
671 /* Will need relocating. */
672 SF_SET_PROCESS (def_symbol_in_progress);
673 clear_function ();
674 break;
675 #ifdef TE_PE
676 case 'e':
677 /* .ef */
678 /* The MS compilers output the actual endline, not the
679 function-relative one... we want to match without
680 changing the assembler input. */
681 SA_SET_SYM_LNNO (def_symbol_in_progress,
682 (SA_GET_SYM_LNNO (def_symbol_in_progress)
683 + coff_line_base));
684 break;
685 #endif
689 break;
691 #ifdef C_AUTOARG
692 case C_AUTOARG:
693 #endif /* C_AUTOARG */
694 case C_AUTO:
695 case C_REG:
696 case C_ARG:
697 case C_REGPARM:
698 case C_FIELD:
700 /* According to the COFF documentation:
702 http://osr5doc.sco.com:1996/topics/COFF_SectNumFld.html
704 A special section number (-2) marks symbolic debugging symbols,
705 including structure/union/enumeration tag names, typedefs, and
706 the name of the file. A section number of -1 indicates that the
707 symbol has a value but is not relocatable. Examples of
708 absolute-valued symbols include automatic and register variables,
709 function arguments, and .eos symbols.
711 But from Ian Lance Taylor:
713 http://sources.redhat.com/ml/binutils/2000-08/msg00202.html
715 the actual tools all marked them as section -1. So the GNU COFF
716 assembler follows historical COFF assemblers.
718 However, it causes problems for djgpp
720 http://sources.redhat.com/ml/binutils/2000-08/msg00210.html
722 By defining STRICTCOFF, a COFF port can make the assembler to
723 follow the documented behavior. */
724 #ifdef STRICTCOFF
725 case C_MOS:
726 case C_MOE:
727 case C_MOU:
728 case C_EOS:
729 #endif
730 SF_SET_DEBUG (def_symbol_in_progress);
731 S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
732 break;
734 #ifndef STRICTCOFF
735 case C_MOS:
736 case C_MOE:
737 case C_MOU:
738 case C_EOS:
739 S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
740 break;
741 #endif
743 case C_EXT:
744 case C_WEAKEXT:
745 #ifdef TE_PE
746 case C_NT_WEAK:
747 #endif
748 case C_STAT:
749 case C_LABEL:
750 /* Valid but set somewhere else (s_comm, s_lcomm, colon). */
751 break;
753 default:
754 case C_USTATIC:
755 case C_EXTDEF:
756 case C_ULABEL:
757 as_warn (_("unexpected storage class %d"),
758 S_GET_STORAGE_CLASS (def_symbol_in_progress));
759 break;
762 /* Now that we have built a debug symbol, try to find if we should
763 merge with an existing symbol or not. If a symbol is C_EFCN or
764 absolute_section or untagged SEG_DEBUG it never merges. We also
765 don't merge labels, which are in a different namespace, nor
766 symbols which have not yet been defined since they are typically
767 unique, nor do we merge tags with non-tags. */
769 /* Two cases for functions. Either debug followed by definition or
770 definition followed by debug. For definition first, we will
771 merge the debug symbol into the definition. For debug first, the
772 lineno entry MUST point to the definition function or else it
773 will point off into space when obj_crawl_symbol_chain() merges
774 the debug symbol into the real symbol. Therefor, let's presume
775 the debug symbol is a real function reference. */
777 /* FIXME-SOON If for some reason the definition label/symbol is
778 never seen, this will probably leave an undefined symbol at link
779 time. */
781 if (S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_EFCN
782 || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_LABEL
783 || (streq (bfd_get_section_name (stdoutput,
784 S_GET_SEGMENT (def_symbol_in_progress)),
785 "*DEBUG*")
786 && !SF_GET_TAG (def_symbol_in_progress))
787 || S_GET_SEGMENT (def_symbol_in_progress) == absolute_section
788 || ! symbol_constant_p (def_symbol_in_progress)
789 || (symbolP = symbol_find (S_GET_NAME (def_symbol_in_progress))) == NULL
790 || SF_GET_TAG (def_symbol_in_progress) != SF_GET_TAG (symbolP))
792 /* If it already is at the end of the symbol list, do nothing */
793 if (def_symbol_in_progress != symbol_lastP)
795 symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
796 symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP,
797 &symbol_lastP);
800 else
802 /* This symbol already exists, merge the newly created symbol
803 into the old one. This is not mandatory. The linker can
804 handle duplicate symbols correctly. But I guess that it save
805 a *lot* of space if the assembly file defines a lot of
806 symbols. [loic] */
808 /* The debug entry (def_symbol_in_progress) is merged into the
809 previous definition. */
811 c_symbol_merge (def_symbol_in_progress, symbolP);
812 symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
814 def_symbol_in_progress = symbolP;
816 if (SF_GET_FUNCTION (def_symbol_in_progress)
817 || SF_GET_TAG (def_symbol_in_progress)
818 || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_STAT)
820 /* For functions, and tags, and static symbols, the symbol
821 *must* be where the debug symbol appears. Move the
822 existing symbol to the current place. */
823 /* If it already is at the end of the symbol list, do nothing. */
824 if (def_symbol_in_progress != symbol_lastP)
826 symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
827 symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
832 if (SF_GET_TAG (def_symbol_in_progress))
834 symbolS *oldtag;
836 oldtag = symbol_find (S_GET_NAME (def_symbol_in_progress));
837 if (oldtag == NULL || ! SF_GET_TAG (oldtag))
838 tag_insert (S_GET_NAME (def_symbol_in_progress),
839 def_symbol_in_progress);
842 if (SF_GET_FUNCTION (def_symbol_in_progress))
844 set_function (def_symbol_in_progress);
845 SF_SET_PROCESS (def_symbol_in_progress);
847 if (symbolP == NULL)
848 /* That is, if this is the first time we've seen the
849 function. */
850 symbol_table_insert (def_symbol_in_progress);
854 def_symbol_in_progress = NULL;
855 demand_empty_rest_of_line ();
858 static void
859 obj_coff_dim (int ignore ATTRIBUTE_UNUSED)
861 int d_index;
863 if (def_symbol_in_progress == NULL)
865 as_warn (_(".dim pseudo-op used outside of .def/.endef: ignored."));
866 demand_empty_rest_of_line ();
867 return;
870 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
872 for (d_index = 0; d_index < DIMNUM; d_index++)
874 SKIP_WHITESPACES ();
875 SA_SET_SYM_DIMEN (def_symbol_in_progress, d_index,
876 get_absolute_expression ());
878 switch (*input_line_pointer)
880 case ',':
881 input_line_pointer++;
882 break;
884 default:
885 as_warn (_("badly formed .dim directive ignored"));
886 /* Fall through. */
887 case '\n':
888 case ';':
889 d_index = DIMNUM;
890 break;
894 demand_empty_rest_of_line ();
897 static void
898 obj_coff_line (int ignore ATTRIBUTE_UNUSED)
900 int this_base;
902 if (def_symbol_in_progress == NULL)
904 /* Probably stabs-style line? */
905 obj_coff_ln (0);
906 return;
909 this_base = get_absolute_expression ();
910 if (streq (".bf", S_GET_NAME (def_symbol_in_progress)))
911 coff_line_base = this_base;
913 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
914 SA_SET_SYM_LNNO (def_symbol_in_progress, this_base);
916 demand_empty_rest_of_line ();
918 #ifndef NO_LISTING
919 if (streq (".bf", S_GET_NAME (def_symbol_in_progress)))
921 extern int listing;
923 if (listing)
924 listing_source_line ((unsigned int) this_base);
926 #endif
929 static void
930 obj_coff_size (int ignore ATTRIBUTE_UNUSED)
932 if (def_symbol_in_progress == NULL)
934 as_warn (_(".size pseudo-op used outside of .def/.endef ignored."));
935 demand_empty_rest_of_line ();
936 return;
939 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
940 SA_SET_SYM_SIZE (def_symbol_in_progress, get_absolute_expression ());
941 demand_empty_rest_of_line ();
944 static void
945 obj_coff_scl (int ignore ATTRIBUTE_UNUSED)
947 if (def_symbol_in_progress == NULL)
949 as_warn (_(".scl pseudo-op used outside of .def/.endef ignored."));
950 demand_empty_rest_of_line ();
951 return;
954 S_SET_STORAGE_CLASS (def_symbol_in_progress, get_absolute_expression ());
955 demand_empty_rest_of_line ();
958 static void
959 obj_coff_tag (int ignore ATTRIBUTE_UNUSED)
961 char *symbol_name;
962 char name_end;
964 if (def_symbol_in_progress == NULL)
966 as_warn (_(".tag pseudo-op used outside of .def/.endef ignored."));
967 demand_empty_rest_of_line ();
968 return;
971 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
972 symbol_name = input_line_pointer;
973 name_end = get_symbol_end ();
975 #ifdef tc_canonicalize_symbol_name
976 symbol_name = tc_canonicalize_symbol_name (symbol_name);
977 #endif
979 /* Assume that the symbol referred to by .tag is always defined.
980 This was a bad assumption. I've added find_or_make. xoxorich. */
981 SA_SET_SYM_TAGNDX (def_symbol_in_progress,
982 tag_find_or_make (symbol_name));
983 if (SA_GET_SYM_TAGNDX (def_symbol_in_progress) == 0L)
984 as_warn (_("tag not found for .tag %s"), symbol_name);
986 SF_SET_TAGGED (def_symbol_in_progress);
987 *input_line_pointer = name_end;
989 demand_empty_rest_of_line ();
992 static void
993 obj_coff_type (int ignore ATTRIBUTE_UNUSED)
995 if (def_symbol_in_progress == NULL)
997 as_warn (_(".type pseudo-op used outside of .def/.endef ignored."));
998 demand_empty_rest_of_line ();
999 return;
1002 S_SET_DATA_TYPE (def_symbol_in_progress, get_absolute_expression ());
1004 if (ISFCN (S_GET_DATA_TYPE (def_symbol_in_progress)) &&
1005 S_GET_STORAGE_CLASS (def_symbol_in_progress) != C_TPDEF)
1006 SF_SET_FUNCTION (def_symbol_in_progress);
1008 demand_empty_rest_of_line ();
1011 static void
1012 obj_coff_val (int ignore ATTRIBUTE_UNUSED)
1014 if (def_symbol_in_progress == NULL)
1016 as_warn (_(".val pseudo-op used outside of .def/.endef ignored."));
1017 demand_empty_rest_of_line ();
1018 return;
1021 if (is_name_beginner (*input_line_pointer))
1023 char *symbol_name = input_line_pointer;
1024 char name_end = get_symbol_end ();
1026 #ifdef tc_canonicalize_symbol_name
1027 symbol_name = tc_canonicalize_symbol_name (symbol_name);
1028 #endif
1029 if (streq (symbol_name, "."))
1031 /* If the .val is != from the .def (e.g. statics). */
1032 symbol_set_frag (def_symbol_in_progress, frag_now);
1033 S_SET_VALUE (def_symbol_in_progress, (valueT) frag_now_fix ());
1035 else if (! streq (S_GET_NAME (def_symbol_in_progress), symbol_name))
1037 expressionS exp;
1039 exp.X_op = O_symbol;
1040 exp.X_add_symbol = symbol_find_or_make (symbol_name);
1041 exp.X_op_symbol = NULL;
1042 exp.X_add_number = 0;
1043 symbol_set_value_expression (def_symbol_in_progress, &exp);
1045 /* If the segment is undefined when the forward reference is
1046 resolved, then copy the segment id from the forward
1047 symbol. */
1048 SF_SET_GET_SEGMENT (def_symbol_in_progress);
1050 /* FIXME: gcc can generate address expressions here in
1051 unusual cases (search for "obscure" in sdbout.c). We
1052 just ignore the offset here, thus generating incorrect
1053 debugging information. We ignore the rest of the line
1054 just below. */
1056 /* Otherwise, it is the name of a non debug symbol and its value
1057 will be calculated later. */
1058 *input_line_pointer = name_end;
1060 else
1062 S_SET_VALUE (def_symbol_in_progress, get_absolute_expression ());
1065 demand_empty_rest_of_line ();
1068 #ifdef TE_PE
1070 /* Return nonzero if name begins with weak alternate symbol prefix. */
1072 static int
1073 weak_is_altname (const char * name)
1075 return strneq (name, weak_altprefix, sizeof (weak_altprefix) - 1);
1078 /* Return the name of the alternate symbol
1079 name corresponding to a weak symbol's name. */
1081 static const char *
1082 weak_name2altname (const char * name)
1084 char *alt_name;
1086 alt_name = xmalloc (sizeof (weak_altprefix) + strlen (name));
1087 strcpy (alt_name, weak_altprefix);
1088 return strcat (alt_name, name);
1091 /* Return the name of the weak symbol corresponding to an
1092 alternate symbol. */
1094 static const char *
1095 weak_altname2name (const char * name)
1097 char * weak_name;
1098 char * dot;
1100 gas_assert (weak_is_altname (name));
1102 weak_name = xstrdup (name + 6);
1103 if ((dot = strchr (weak_name, '.')))
1104 *dot = 0;
1105 return weak_name;
1108 /* Make a weak symbol name unique by
1109 appending the name of an external symbol. */
1111 static const char *
1112 weak_uniquify (const char * name)
1114 char *ret;
1115 const char * unique = "";
1117 #ifdef TE_PE
1118 if (an_external_name != NULL)
1119 unique = an_external_name;
1120 #endif
1121 gas_assert (weak_is_altname (name));
1123 if (strchr (name + sizeof (weak_altprefix), '.'))
1124 return name;
1126 ret = xmalloc (strlen (name) + strlen (unique) + 2);
1127 strcpy (ret, name);
1128 strcat (ret, ".");
1129 strcat (ret, unique);
1130 return ret;
1133 void
1134 pecoff_obj_set_weak_hook (symbolS *symbolP)
1136 symbolS *alternateP;
1138 /* See _Microsoft Portable Executable and Common Object
1139 File Format Specification_, section 5.5.3.
1140 Create a symbol representing the alternate value.
1141 coff_frob_symbol will set the value of this symbol from
1142 the value of the weak symbol itself. */
1143 S_SET_STORAGE_CLASS (symbolP, C_NT_WEAK);
1144 S_SET_NUMBER_AUXILIARY (symbolP, 1);
1145 SA_SET_SYM_FSIZE (symbolP, IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY);
1147 alternateP = symbol_find_or_make (weak_name2altname (S_GET_NAME (symbolP)));
1148 S_SET_EXTERNAL (alternateP);
1149 S_SET_STORAGE_CLASS (alternateP, C_NT_WEAK);
1151 SA_SET_SYM_TAGNDX (symbolP, alternateP);
1154 void
1155 pecoff_obj_clear_weak_hook (symbolS *symbolP)
1157 symbolS *alternateP;
1159 S_SET_STORAGE_CLASS (symbolP, 0);
1160 SA_SET_SYM_FSIZE (symbolP, 0);
1162 alternateP = symbol_find (weak_name2altname (S_GET_NAME (symbolP)));
1163 S_CLEAR_EXTERNAL (alternateP);
1166 #endif /* TE_PE */
1168 /* Handle .weak. This is a GNU extension in formats other than PE. */
1170 static void
1171 obj_coff_weak (int ignore ATTRIBUTE_UNUSED)
1173 char *name;
1174 int c;
1175 symbolS *symbolP;
1179 name = input_line_pointer;
1180 c = get_symbol_end ();
1181 if (*name == 0)
1183 as_warn (_("badly formed .weak directive ignored"));
1184 ignore_rest_of_line ();
1185 return;
1187 c = 0;
1188 symbolP = symbol_find_or_make (name);
1189 *input_line_pointer = c;
1190 SKIP_WHITESPACE ();
1191 S_SET_WEAK (symbolP);
1193 if (c == ',')
1195 input_line_pointer++;
1196 SKIP_WHITESPACE ();
1197 if (*input_line_pointer == '\n')
1198 c = '\n';
1202 while (c == ',');
1204 demand_empty_rest_of_line ();
1207 void
1208 coff_obj_read_begin_hook (void)
1210 /* These had better be the same. Usually 18 bytes. */
1211 know (sizeof (SYMENT) == sizeof (AUXENT));
1212 know (SYMESZ == AUXESZ);
1213 tag_init ();
1216 symbolS *coff_last_function;
1217 #ifndef OBJ_XCOFF
1218 static symbolS *coff_last_bf;
1219 #endif
1221 void
1222 coff_frob_symbol (symbolS *symp, int *punt)
1224 static symbolS *last_tagP;
1225 static stack *block_stack;
1226 static symbolS *set_end;
1227 symbolS *next_set_end = NULL;
1229 if (symp == &abs_symbol)
1231 *punt = 1;
1232 return;
1235 if (current_lineno_sym)
1236 coff_add_linesym (NULL);
1238 if (!block_stack)
1239 block_stack = stack_init (512, sizeof (symbolS*));
1241 #ifdef TE_PE
1242 if (S_GET_STORAGE_CLASS (symp) == C_NT_WEAK
1243 && ! S_IS_WEAK (symp)
1244 && weak_is_altname (S_GET_NAME (symp)))
1246 /* This is a weak alternate symbol. All processing of
1247 PECOFFweak symbols is done here, through the alternate. */
1248 symbolS *weakp = symbol_find_noref (weak_altname2name
1249 (S_GET_NAME (symp)), 1);
1251 gas_assert (weakp);
1252 gas_assert (S_GET_NUMBER_AUXILIARY (weakp) == 1);
1254 if (! S_IS_WEAK (weakp))
1256 /* The symbol was turned from weak to strong. Discard altname. */
1257 *punt = 1;
1258 return;
1260 else if (symbol_equated_p (weakp))
1262 /* The weak symbol has an alternate specified; symp is unneeded. */
1263 S_SET_STORAGE_CLASS (weakp, C_NT_WEAK);
1264 SA_SET_SYM_TAGNDX (weakp,
1265 symbol_get_value_expression (weakp)->X_add_symbol);
1267 S_CLEAR_EXTERNAL (symp);
1268 *punt = 1;
1269 return;
1271 else
1273 /* The weak symbol has been assigned an alternate value.
1274 Copy this value to symp, and set symp as weakp's alternate. */
1275 if (S_GET_STORAGE_CLASS (weakp) != C_NT_WEAK)
1277 S_SET_STORAGE_CLASS (symp, S_GET_STORAGE_CLASS (weakp));
1278 S_SET_STORAGE_CLASS (weakp, C_NT_WEAK);
1281 if (S_IS_DEFINED (weakp))
1283 /* This is a defined weak symbol. Copy value information
1284 from the weak symbol itself to the alternate symbol. */
1285 symbol_set_value_expression (symp,
1286 symbol_get_value_expression (weakp));
1287 symbol_set_frag (symp, symbol_get_frag (weakp));
1288 S_SET_SEGMENT (symp, S_GET_SEGMENT (weakp));
1290 else
1292 /* This is an undefined weak symbol.
1293 Define the alternate symbol to zero. */
1294 S_SET_VALUE (symp, 0);
1295 S_SET_SEGMENT (symp, absolute_section);
1298 S_SET_NAME (symp, weak_uniquify (S_GET_NAME (symp)));
1299 S_SET_STORAGE_CLASS (symp, C_EXT);
1301 S_SET_VALUE (weakp, 0);
1302 S_SET_SEGMENT (weakp, undefined_section);
1305 #else /* TE_PE */
1306 if (S_IS_WEAK (symp))
1307 S_SET_STORAGE_CLASS (symp, C_WEAKEXT);
1308 #endif /* TE_PE */
1310 if (!S_IS_DEFINED (symp)
1311 && !S_IS_WEAK (symp)
1312 && S_GET_STORAGE_CLASS (symp) != C_STAT)
1313 S_SET_STORAGE_CLASS (symp, C_EXT);
1315 if (!SF_GET_DEBUG (symp))
1317 symbolS * real;
1319 if (!SF_GET_LOCAL (symp)
1320 && !SF_GET_STATICS (symp)
1321 && S_GET_STORAGE_CLASS (symp) != C_LABEL
1322 && symbol_constant_p (symp)
1323 && (real = symbol_find_noref (S_GET_NAME (symp), 1))
1324 && S_GET_STORAGE_CLASS (real) == C_NULL
1325 && real != symp)
1327 c_symbol_merge (symp, real);
1328 *punt = 1;
1329 return;
1332 if (!S_IS_DEFINED (symp) && !SF_GET_LOCAL (symp))
1334 gas_assert (S_GET_VALUE (symp) == 0);
1335 if (S_IS_WEAKREFD (symp))
1336 *punt = 1;
1337 else
1338 S_SET_EXTERNAL (symp);
1340 else if (S_GET_STORAGE_CLASS (symp) == C_NULL)
1342 if (S_GET_SEGMENT (symp) == text_section
1343 && symp != seg_info (text_section)->sym)
1344 S_SET_STORAGE_CLASS (symp, C_LABEL);
1345 else
1346 S_SET_STORAGE_CLASS (symp, C_STAT);
1349 if (SF_GET_PROCESS (symp))
1351 if (S_GET_STORAGE_CLASS (symp) == C_BLOCK)
1353 if (streq (S_GET_NAME (symp), ".bb"))
1354 stack_push (block_stack, (char *) &symp);
1355 else
1357 symbolS *begin;
1359 begin = *(symbolS **) stack_pop (block_stack);
1360 if (begin == 0)
1361 as_warn (_("mismatched .eb"));
1362 else
1363 next_set_end = begin;
1367 if (coff_last_function == 0 && SF_GET_FUNCTION (symp))
1369 union internal_auxent *auxp;
1371 coff_last_function = symp;
1372 if (S_GET_NUMBER_AUXILIARY (symp) < 1)
1373 S_SET_NUMBER_AUXILIARY (symp, 1);
1374 auxp = SYM_AUXENT (symp);
1375 memset (auxp->x_sym.x_fcnary.x_ary.x_dimen, 0,
1376 sizeof (auxp->x_sym.x_fcnary.x_ary.x_dimen));
1379 if (S_GET_STORAGE_CLASS (symp) == C_EFCN)
1381 if (coff_last_function == 0)
1382 as_fatal (_("C_EFCN symbol for %s out of scope"),
1383 S_GET_NAME (symp));
1384 SA_SET_SYM_FSIZE (coff_last_function,
1385 (long) (S_GET_VALUE (symp)
1386 - S_GET_VALUE (coff_last_function)));
1387 next_set_end = coff_last_function;
1388 coff_last_function = 0;
1392 if (S_IS_EXTERNAL (symp))
1393 S_SET_STORAGE_CLASS (symp, C_EXT);
1394 else if (SF_GET_LOCAL (symp))
1395 *punt = 1;
1397 if (SF_GET_FUNCTION (symp))
1398 symbol_get_bfdsym (symp)->flags |= BSF_FUNCTION;
1401 /* Double check weak symbols. */
1402 if (S_IS_WEAK (symp) && S_IS_COMMON (symp))
1403 as_bad (_("Symbol `%s' can not be both weak and common"),
1404 S_GET_NAME (symp));
1406 if (SF_GET_TAG (symp))
1407 last_tagP = symp;
1408 else if (S_GET_STORAGE_CLASS (symp) == C_EOS)
1409 next_set_end = last_tagP;
1411 #ifdef OBJ_XCOFF
1412 /* This is pretty horrible, but we have to set *punt correctly in
1413 order to call SA_SET_SYM_ENDNDX correctly. */
1414 if (! symbol_used_in_reloc_p (symp)
1415 && ((symbol_get_bfdsym (symp)->flags & BSF_SECTION_SYM) != 0
1416 || (! (S_IS_EXTERNAL (symp) || S_IS_WEAK (symp))
1417 && ! symbol_get_tc (symp)->output
1418 && S_GET_STORAGE_CLASS (symp) != C_FILE)))
1419 *punt = 1;
1420 #endif
1422 if (set_end != (symbolS *) NULL
1423 && ! *punt
1424 && ((symbol_get_bfdsym (symp)->flags & BSF_NOT_AT_END) != 0
1425 || (S_IS_DEFINED (symp)
1426 && ! S_IS_COMMON (symp)
1427 && (! S_IS_EXTERNAL (symp) || SF_GET_FUNCTION (symp)))))
1429 SA_SET_SYM_ENDNDX (set_end, symp);
1430 set_end = NULL;
1433 if (next_set_end != NULL)
1435 if (set_end != NULL)
1436 as_warn (_("Warning: internal error: forgetting to set endndx of %s"),
1437 S_GET_NAME (set_end));
1438 set_end = next_set_end;
1441 #ifndef OBJ_XCOFF
1442 if (! *punt
1443 && S_GET_STORAGE_CLASS (symp) == C_FCN
1444 && streq (S_GET_NAME (symp), ".bf"))
1446 if (coff_last_bf != NULL)
1447 SA_SET_SYM_ENDNDX (coff_last_bf, symp);
1448 coff_last_bf = symp;
1450 #endif
1451 if (coffsymbol (symbol_get_bfdsym (symp))->lineno)
1453 int i;
1454 struct line_no *lptr;
1455 alent *l;
1457 lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno;
1458 for (i = 0; lptr; lptr = lptr->next)
1459 i++;
1460 lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno;
1462 /* We need i entries for line numbers, plus 1 for the first
1463 entry which BFD will override, plus 1 for the last zero
1464 entry (a marker for BFD). */
1465 l = xmalloc ((i + 2) * sizeof (* l));
1466 coffsymbol (symbol_get_bfdsym (symp))->lineno = l;
1467 l[i + 1].line_number = 0;
1468 l[i + 1].u.sym = NULL;
1469 for (; i > 0; i--)
1471 if (lptr->frag)
1472 lptr->l.u.offset += lptr->frag->fr_address / OCTETS_PER_BYTE;
1473 l[i] = lptr->l;
1474 lptr = lptr->next;
1479 void
1480 coff_adjust_section_syms (bfd *abfd ATTRIBUTE_UNUSED,
1481 asection *sec,
1482 void * x ATTRIBUTE_UNUSED)
1484 symbolS *secsym;
1485 segment_info_type *seginfo = seg_info (sec);
1486 int nlnno, nrelocs = 0;
1488 /* RS/6000 gas creates a .debug section manually in ppc_frob_file in
1489 tc-ppc.c. Do not get confused by it. */
1490 if (seginfo == NULL)
1491 return;
1493 if (streq (sec->name, ".text"))
1494 nlnno = coff_n_line_nos;
1495 else
1496 nlnno = 0;
1498 /* @@ Hope that none of the fixups expand to more than one reloc
1499 entry... */
1500 fixS *fixp = seginfo->fix_root;
1501 while (fixp)
1503 if (! fixp->fx_done)
1504 nrelocs++;
1505 fixp = fixp->fx_next;
1508 if (bfd_get_section_size (sec) == 0
1509 && nrelocs == 0
1510 && nlnno == 0
1511 && sec != text_section
1512 && sec != data_section
1513 && sec != bss_section)
1514 return;
1516 secsym = section_symbol (sec);
1517 /* This is an estimate; we'll plug in the real value using
1518 SET_SECTION_RELOCS later */
1519 SA_SET_SCN_NRELOC (secsym, nrelocs);
1520 SA_SET_SCN_NLINNO (secsym, nlnno);
1523 void
1524 coff_frob_file_after_relocs (void)
1526 bfd_map_over_sections (stdoutput, coff_adjust_section_syms, NULL);
1529 /* Implement the .section pseudo op:
1530 .section name {, "flags"}
1532 | +--- optional flags: 'b' for bss
1533 | 'i' for info
1534 +-- section name 'l' for lib
1535 'n' for noload
1536 'o' for over
1537 'w' for data
1538 'd' (apparently m88k for data)
1539 'x' for text
1540 'r' for read-only data
1541 's' for shared data (PE)
1542 'y' for noread
1543 But if the argument is not a quoted string, treat it as a
1544 subsegment number.
1546 Note the 'a' flag is silently ignored. This allows the same
1547 .section directive to be parsed in both ELF and COFF formats. */
1549 void
1550 obj_coff_section (int ignore ATTRIBUTE_UNUSED)
1552 /* Strip out the section name. */
1553 char *section_name;
1554 char c;
1555 char *name;
1556 unsigned int exp;
1557 flagword flags, oldflags;
1558 asection *sec;
1560 if (flag_mri)
1562 char type;
1564 s_mri_sect (&type);
1565 return;
1568 section_name = input_line_pointer;
1569 c = get_symbol_end ();
1571 name = xmalloc (input_line_pointer - section_name + 1);
1572 strcpy (name, section_name);
1574 *input_line_pointer = c;
1576 SKIP_WHITESPACE ();
1578 exp = 0;
1579 flags = SEC_NO_FLAGS;
1581 if (*input_line_pointer == ',')
1583 ++input_line_pointer;
1584 SKIP_WHITESPACE ();
1585 if (*input_line_pointer != '"')
1586 exp = get_absolute_expression ();
1587 else
1589 unsigned char attr;
1590 int readonly_removed = 0;
1591 int load_removed = 0;
1593 while (attr = *++input_line_pointer,
1594 attr != '"'
1595 && ! is_end_of_line[attr])
1597 switch (attr)
1599 case 'b':
1600 /* Uninitialised data section. */
1601 flags |= SEC_ALLOC;
1602 flags &=~ SEC_LOAD;
1603 break;
1605 case 'n':
1606 /* Section not loaded. */
1607 flags &=~ SEC_LOAD;
1608 flags |= SEC_NEVER_LOAD;
1609 load_removed = 1;
1610 break;
1612 case 's':
1613 /* Shared section. */
1614 flags |= SEC_COFF_SHARED;
1615 /* Fall through. */
1616 case 'd':
1617 /* Data section. */
1618 flags |= SEC_DATA;
1619 if (! load_removed)
1620 flags |= SEC_LOAD;
1621 flags &=~ SEC_READONLY;
1622 break;
1624 case 'w':
1625 /* Writable section. */
1626 flags &=~ SEC_READONLY;
1627 readonly_removed = 1;
1628 break;
1630 case 'a':
1631 /* Ignore. Here for compatibility with ELF. */
1632 break;
1634 case 'r': /* Read-only section. Implies a data section. */
1635 readonly_removed = 0;
1636 /* Fall through. */
1637 case 'x': /* Executable section. */
1638 /* If we are setting the 'x' attribute or if the 'r'
1639 attribute is being used to restore the readonly status
1640 of a code section (eg "wxr") then set the SEC_CODE flag,
1641 otherwise set the SEC_DATA flag. */
1642 flags |= (attr == 'x' || (flags & SEC_CODE) ? SEC_CODE : SEC_DATA);
1643 if (! load_removed)
1644 flags |= SEC_LOAD;
1645 /* Note - the READONLY flag is set here, even for the 'x'
1646 attribute in order to be compatible with the MSVC
1647 linker. */
1648 if (! readonly_removed)
1649 flags |= SEC_READONLY;
1650 break;
1652 case 'y':
1653 flags |= SEC_COFF_NOREAD | SEC_READONLY;
1654 break;
1656 case 'i': /* STYP_INFO */
1657 case 'l': /* STYP_LIB */
1658 case 'o': /* STYP_OVER */
1659 as_warn (_("unsupported section attribute '%c'"), attr);
1660 break;
1662 default:
1663 as_warn (_("unknown section attribute '%c'"), attr);
1664 break;
1667 if (attr == '"')
1668 ++input_line_pointer;
1672 sec = subseg_new (name, (subsegT) exp);
1674 oldflags = bfd_get_section_flags (stdoutput, sec);
1675 if (oldflags == SEC_NO_FLAGS)
1677 /* Set section flags for a new section just created by subseg_new.
1678 Provide a default if no flags were parsed. */
1679 if (flags == SEC_NO_FLAGS)
1680 flags = TC_COFF_SECTION_DEFAULT_ATTRIBUTES;
1682 #ifdef COFF_LONG_SECTION_NAMES
1683 /* Add SEC_LINK_ONCE and SEC_LINK_DUPLICATES_DISCARD to .gnu.linkonce
1684 sections so adjust_reloc_syms in write.c will correctly handle
1685 relocs which refer to non-local symbols in these sections. */
1686 if (strneq (name, ".gnu.linkonce", sizeof (".gnu.linkonce") - 1))
1687 flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
1688 #endif
1690 if (! bfd_set_section_flags (stdoutput, sec, flags))
1691 as_warn (_("error setting flags for \"%s\": %s"),
1692 bfd_section_name (stdoutput, sec),
1693 bfd_errmsg (bfd_get_error ()));
1695 else if (flags != SEC_NO_FLAGS)
1697 /* This section's attributes have already been set. Warn if the
1698 attributes don't match. */
1699 flagword matchflags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
1700 | SEC_DATA | SEC_COFF_SHARED | SEC_NEVER_LOAD
1701 | SEC_COFF_NOREAD);
1702 if ((flags ^ oldflags) & matchflags)
1703 as_warn (_("Ignoring changed section attributes for %s"), name);
1706 demand_empty_rest_of_line ();
1709 void
1710 coff_adjust_symtab (void)
1712 if (symbol_rootP == NULL
1713 || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
1714 c_dot_file_symbol ("fake", 0);
1717 void
1718 coff_frob_section (segT sec)
1720 segT strsec;
1721 char *p;
1722 fragS *fragp;
1723 bfd_vma size, n_entries, mask;
1724 bfd_vma align_power = (bfd_vma)sec->alignment_power + OCTETS_PER_BYTE_POWER;
1726 /* The COFF back end in BFD requires that all section sizes be
1727 rounded up to multiples of the corresponding section alignments,
1728 supposedly because standard COFF has no other way of encoding alignment
1729 for sections. If your COFF flavor has a different way of encoding
1730 section alignment, then skip this step, as TICOFF does. */
1731 size = bfd_get_section_size (sec);
1732 mask = ((bfd_vma) 1 << align_power) - 1;
1733 #if !defined(TICOFF)
1734 if (size & mask)
1736 bfd_vma new_size;
1737 fragS *last;
1739 new_size = (size + mask) & ~mask;
1740 bfd_set_section_size (stdoutput, sec, new_size);
1742 /* If the size had to be rounded up, add some padding in
1743 the last non-empty frag. */
1744 fragp = seg_info (sec)->frchainP->frch_root;
1745 last = seg_info (sec)->frchainP->frch_last;
1746 while (fragp->fr_next != last)
1747 fragp = fragp->fr_next;
1748 last->fr_address = size;
1749 fragp->fr_offset += new_size - size;
1751 #endif
1753 /* If the section size is non-zero, the section symbol needs an aux
1754 entry associated with it, indicating the size. We don't know
1755 all the values yet; coff_frob_symbol will fill them in later. */
1756 #ifndef TICOFF
1757 if (size != 0
1758 || sec == text_section
1759 || sec == data_section
1760 || sec == bss_section)
1761 #endif
1763 symbolS *secsym = section_symbol (sec);
1765 S_SET_STORAGE_CLASS (secsym, C_STAT);
1766 S_SET_NUMBER_AUXILIARY (secsym, 1);
1767 SF_SET_STATICS (secsym);
1768 SA_SET_SCN_SCNLEN (secsym, size);
1770 /* FIXME: These should be in a "stabs.h" file, or maybe as.h. */
1771 #ifndef STAB_SECTION_NAME
1772 #define STAB_SECTION_NAME ".stab"
1773 #endif
1774 #ifndef STAB_STRING_SECTION_NAME
1775 #define STAB_STRING_SECTION_NAME ".stabstr"
1776 #endif
1777 if (! streq (STAB_STRING_SECTION_NAME, sec->name))
1778 return;
1780 strsec = sec;
1781 sec = subseg_get (STAB_SECTION_NAME, 0);
1782 /* size is already rounded up, since other section will be listed first */
1783 size = bfd_get_section_size (strsec);
1785 n_entries = bfd_get_section_size (sec) / 12 - 1;
1787 /* Find first non-empty frag. It should be large enough. */
1788 fragp = seg_info (sec)->frchainP->frch_root;
1789 while (fragp && fragp->fr_fix == 0)
1790 fragp = fragp->fr_next;
1791 gas_assert (fragp != 0 && fragp->fr_fix >= 12);
1793 /* Store the values. */
1794 p = fragp->fr_literal;
1795 bfd_h_put_16 (stdoutput, n_entries, (bfd_byte *) p + 6);
1796 bfd_h_put_32 (stdoutput, size, (bfd_byte *) p + 8);
1799 void
1800 obj_coff_init_stab_section (segT seg)
1802 char *file;
1803 char *p;
1804 char *stabstr_name;
1805 unsigned int stroff;
1807 /* Make space for this first symbol. */
1808 p = frag_more (12);
1809 /* Zero it out. */
1810 memset (p, 0, 12);
1811 as_where (&file, (unsigned int *) NULL);
1812 stabstr_name = xmalloc (strlen (seg->name) + 4);
1813 strcpy (stabstr_name, seg->name);
1814 strcat (stabstr_name, "str");
1815 stroff = get_stab_string_offset (file, stabstr_name);
1816 know (stroff == 1);
1817 md_number_to_chars (p, stroff, 4);
1820 #ifdef DEBUG
1821 const char *
1822 s_get_name (symbolS *s)
1824 return ((s == NULL) ? "(NULL)" : S_GET_NAME (s));
1827 void
1828 symbol_dump (void)
1830 symbolS *symbolP;
1832 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
1833 printf (_("0x%lx: \"%s\" type = %ld, class = %d, segment = %d\n"),
1834 (unsigned long) symbolP,
1835 S_GET_NAME (symbolP),
1836 (long) S_GET_DATA_TYPE (symbolP),
1837 S_GET_STORAGE_CLASS (symbolP),
1838 (int) S_GET_SEGMENT (symbolP));
1841 #endif /* DEBUG */
1843 const pseudo_typeS coff_pseudo_table[] =
1845 {"ABORT", s_abort, 0},
1846 {"appline", obj_coff_ln, 1},
1847 /* We accept the .bss directive for backward compatibility with
1848 earlier versions of gas. */
1849 {"bss", obj_coff_bss, 0},
1850 #ifdef TE_PE
1851 /* PE provides an enhanced version of .comm with alignment. */
1852 {"comm", obj_coff_comm, 0},
1853 #endif /* TE_PE */
1854 {"def", obj_coff_def, 0},
1855 {"dim", obj_coff_dim, 0},
1856 {"endef", obj_coff_endef, 0},
1857 {"ident", obj_coff_ident, 0},
1858 {"line", obj_coff_line, 0},
1859 {"ln", obj_coff_ln, 0},
1860 {"scl", obj_coff_scl, 0},
1861 {"sect", obj_coff_section, 0},
1862 {"sect.s", obj_coff_section, 0},
1863 {"section", obj_coff_section, 0},
1864 {"section.s", obj_coff_section, 0},
1865 /* FIXME: We ignore the MRI short attribute. */
1866 {"size", obj_coff_size, 0},
1867 {"tag", obj_coff_tag, 0},
1868 {"type", obj_coff_type, 0},
1869 {"val", obj_coff_val, 0},
1870 {"version", s_ignore, 0},
1871 {"loc", obj_coff_loc, 0},
1872 {"optim", s_ignore, 0}, /* For sun386i cc (?) */
1873 {"weak", obj_coff_weak, 0},
1874 #if defined TC_TIC4X
1875 /* The tic4x uses sdef instead of def. */
1876 {"sdef", obj_coff_def, 0},
1877 #endif
1878 #if defined(SEH_CMDS)
1879 SEH_CMDS
1880 #endif
1881 {NULL, NULL, 0}
1885 /* Support for a COFF emulation. */
1887 static void
1888 coff_pop_insert (void)
1890 pop_insert (coff_pseudo_table);
1893 static int
1894 coff_separate_stab_sections (void)
1896 return 1;
1899 const struct format_ops coff_format_ops =
1901 bfd_target_coff_flavour,
1902 0, /* dfl_leading_underscore */
1903 1, /* emit_section_symbols */
1904 0, /* begin */
1905 c_dot_file_symbol,
1906 coff_frob_symbol,
1907 0, /* frob_file */
1908 0, /* frob_file_before_adjust */
1909 0, /* frob_file_before_fix */
1910 coff_frob_file_after_relocs,
1911 0, /* s_get_size */
1912 0, /* s_set_size */
1913 0, /* s_get_align */
1914 0, /* s_set_align */
1915 0, /* s_get_other */
1916 0, /* s_set_other */
1917 0, /* s_get_desc */
1918 0, /* s_set_desc */
1919 0, /* s_get_type */
1920 0, /* s_set_type */
1921 0, /* copy_symbol_attributes */
1922 0, /* generate_asm_lineno */
1923 0, /* process_stab */
1924 coff_separate_stab_sections,
1925 obj_coff_init_stab_section,
1926 0, /* sec_sym_ok_for_reloc */
1927 coff_pop_insert,
1928 0, /* ecoff_set_ext */
1929 coff_obj_read_begin_hook,
1930 coff_obj_symbol_new_hook,
1931 coff_obj_symbol_clone_hook