[PATCH 22/57][Arm][GAS] Add support for MVE instructions: vmlaldav, vmlalv, vmlsldav...
[binutils-gdb.git] / gas / config / obj-coff.c
blobc4e1d71ce4e6ccfd46cd0cec6d5c69fcd7669248
1 /* coff object file format
2 Copyright (C) 1989-2019 Free Software Foundation, Inc.
4 This file is part of GAS.
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to the Free
18 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
19 02110-1301, USA. */
21 #define OBJ_HEADER "obj-coff.h"
23 #include "as.h"
24 #include "safe-ctype.h"
25 #include "subsegs.h"
27 #ifdef TE_PE
28 #include "coff/pe.h"
29 #endif
31 #ifdef OBJ_XCOFF
32 #include "coff/xcoff.h"
33 #endif
35 #define streq(a,b) (strcmp ((a), (b)) == 0)
36 #define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
38 /* I think this is probably always correct. */
39 #ifndef KEEP_RELOC_INFO
40 #define KEEP_RELOC_INFO
41 #endif
43 /* obj_coff_section will use this macro to set a new section's
44 attributes when a directive has no valid flags or the "w" flag is
45 used. This default should be appropriate for most. */
46 #ifndef TC_COFF_SECTION_DEFAULT_ATTRIBUTES
47 #define TC_COFF_SECTION_DEFAULT_ATTRIBUTES (SEC_LOAD | SEC_DATA)
48 #endif
50 /* This is used to hold the symbol built by a sequence of pseudo-ops
51 from .def and .endef. */
52 static symbolS *def_symbol_in_progress;
53 #ifdef TE_PE
54 /* PE weak alternate symbols begin with this string. */
55 static const char weak_altprefix[] = ".weak.";
56 #endif /* TE_PE */
58 #include "obj-coff-seh.c"
60 typedef struct
62 unsigned long chunk_size;
63 unsigned long element_size;
64 unsigned long size;
65 char *data;
66 unsigned long pointer;
68 stack;
71 /* Stack stuff. */
73 static stack *
74 stack_init (unsigned long chunk_size,
75 unsigned long element_size)
77 stack *st;
79 st = XNEW (stack);
80 st->data = XNEWVEC (char, 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 st->data = XRESIZEVEC (char, st->data, st->size);
101 memcpy (st->data + st->pointer, element, st->element_size);
102 st->pointer += st->element_size;
103 return st->data + st->pointer;
106 static char *
107 stack_pop (stack *st)
109 if (st->pointer < st->element_size)
111 st->pointer = 0;
112 return NULL;
114 st->pointer -= st->element_size;
115 return st->data + st->pointer;
118 /* Maintain a list of the tagnames of the structures. */
120 static struct hash_control *tag_hash;
122 static void
123 tag_init (void)
125 tag_hash = hash_new ();
128 static void
129 tag_insert (const char *name, symbolS *symbolP)
131 const char *error_string;
133 if ((error_string = hash_jam (tag_hash, name, (char *) symbolP)))
134 as_fatal (_("Inserting \"%s\" into structure table failed: %s"),
135 name, error_string);
138 static symbolS *
139 tag_find (char *name)
141 return (symbolS *) hash_find (tag_hash, name);
144 static symbolS *
145 tag_find_or_make (char *name)
147 symbolS *symbolP;
149 if ((symbolP = tag_find (name)) == NULL)
151 symbolP = symbol_new (name, undefined_section,
152 0, &zero_address_frag);
154 tag_insert (S_GET_NAME (symbolP), symbolP);
155 symbol_table_insert (symbolP);
158 return symbolP;
161 /* We accept the .bss directive to set the section for backward
162 compatibility with earlier versions of gas. */
164 static void
165 obj_coff_bss (int ignore ATTRIBUTE_UNUSED)
167 if (*input_line_pointer == '\n')
168 subseg_new (".bss", get_absolute_expression ());
169 else
170 s_lcomm (0);
173 #ifdef TE_PE
174 /* Called from read.c:s_comm after we've parsed .comm symbol, size.
175 Parse a possible alignment value. */
177 static symbolS *
178 obj_coff_common_parse (int ignore ATTRIBUTE_UNUSED, symbolS *symbolP, addressT size)
180 addressT align = 0;
182 if (*input_line_pointer == ',')
184 align = parse_align (0);
185 if (align == (addressT) -1)
186 return NULL;
189 S_SET_VALUE (symbolP, size);
190 S_SET_EXTERNAL (symbolP);
191 S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
193 symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
195 /* There is no S_SET_ALIGN (symbolP, align) in COFF/PE.
196 Instead we must add a note to the .drectve section. */
197 if (align)
199 segT current_seg = now_seg;
200 subsegT current_subseg = now_subseg;
201 flagword oldflags;
202 asection *sec;
203 size_t pfxlen, numlen;
204 char *frag;
205 char numbuff[20];
207 sec = subseg_new (".drectve", 0);
208 oldflags = bfd_get_section_flags (stdoutput, sec);
209 if (oldflags == SEC_NO_FLAGS)
211 if (!bfd_set_section_flags (stdoutput, sec,
212 TC_COFF_SECTION_DEFAULT_ATTRIBUTES))
213 as_warn (_("error setting flags for \"%s\": %s"),
214 bfd_section_name (stdoutput, sec),
215 bfd_errmsg (bfd_get_error ()));
218 /* Emit a string. Note no NUL-termination. */
219 pfxlen = strlen (" -aligncomm:") + 2 + strlen (S_GET_NAME (symbolP)) + 1;
220 numlen = snprintf (numbuff, sizeof (numbuff), "%d", (int) align);
221 frag = frag_more (pfxlen + numlen);
222 (void) sprintf (frag, " -aligncomm:\"%s\",", S_GET_NAME (symbolP));
223 memcpy (frag + pfxlen, numbuff, numlen);
224 /* Restore original subseg. */
225 subseg_set (current_seg, current_subseg);
228 return symbolP;
231 static void
232 obj_coff_comm (int ignore ATTRIBUTE_UNUSED)
234 s_comm_internal (ignore, obj_coff_common_parse);
236 #endif /* TE_PE */
238 /* @@ Ick. */
239 static segT
240 fetch_coff_debug_section (void)
242 static segT debug_section;
244 if (!debug_section)
246 const asymbol *s;
248 s = bfd_make_debug_symbol (stdoutput, NULL, 0);
249 gas_assert (s != 0);
250 debug_section = s->section;
252 return debug_section;
255 void
256 SA_SET_SYM_ENDNDX (symbolS *sym, symbolS *val)
258 combined_entry_type *entry, *p;
260 entry = &coffsymbol (symbol_get_bfdsym (sym))->native[1];
261 p = coffsymbol (symbol_get_bfdsym (val))->native;
262 entry->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p = p;
263 entry->fix_end = 1;
266 static void
267 SA_SET_SYM_TAGNDX (symbolS *sym, symbolS *val)
269 combined_entry_type *entry, *p;
271 entry = &coffsymbol (symbol_get_bfdsym (sym))->native[1];
272 p = coffsymbol (symbol_get_bfdsym (val))->native;
273 entry->u.auxent.x_sym.x_tagndx.p = p;
274 entry->fix_tag = 1;
277 static int
278 S_GET_DATA_TYPE (symbolS *sym)
280 return coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_type;
284 S_SET_DATA_TYPE (symbolS *sym, int val)
286 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_type = val;
287 return val;
291 S_GET_STORAGE_CLASS (symbolS *sym)
293 return coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_sclass;
297 S_SET_STORAGE_CLASS (symbolS *sym, int val)
299 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_sclass = val;
300 return val;
303 /* Merge a debug symbol containing debug information into a normal symbol. */
305 static void
306 c_symbol_merge (symbolS *debug, symbolS *normal)
308 S_SET_DATA_TYPE (normal, S_GET_DATA_TYPE (debug));
309 S_SET_STORAGE_CLASS (normal, S_GET_STORAGE_CLASS (debug));
311 if (S_GET_NUMBER_AUXILIARY (debug) > S_GET_NUMBER_AUXILIARY (normal))
312 /* Take the most we have. */
313 S_SET_NUMBER_AUXILIARY (normal, S_GET_NUMBER_AUXILIARY (debug));
315 if (S_GET_NUMBER_AUXILIARY (debug) > 0)
316 /* Move all the auxiliary information. */
317 memcpy (SYM_AUXINFO (normal), SYM_AUXINFO (debug),
318 (S_GET_NUMBER_AUXILIARY (debug)
319 * sizeof (*SYM_AUXINFO (debug))));
321 /* Move the debug flags. */
322 SF_SET_DEBUG_FIELD (normal, SF_GET_DEBUG_FIELD (debug));
325 void
326 c_dot_file_symbol (const char *filename, int appfile ATTRIBUTE_UNUSED)
328 symbolS *symbolP;
330 /* BFD converts filename to a .file symbol with an aux entry. It
331 also handles chaining. */
332 symbolP = symbol_new (filename, bfd_abs_section_ptr, 0, &zero_address_frag);
334 S_SET_STORAGE_CLASS (symbolP, C_FILE);
335 S_SET_NUMBER_AUXILIARY (symbolP, 1);
337 symbol_get_bfdsym (symbolP)->flags = BSF_DEBUGGING;
339 #ifndef NO_LISTING
341 extern int listing;
343 if (listing)
344 listing_source_file (filename);
346 #endif
348 /* Make sure that the symbol is first on the symbol chain. */
349 if (symbol_rootP != symbolP)
351 symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
352 symbol_insert (symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP);
356 /* Line number handling. */
358 struct line_no
360 struct line_no *next;
361 fragS *frag;
362 alent l;
365 int coff_line_base;
367 /* Symbol of last function, which we should hang line#s off of. */
368 static symbolS *line_fsym;
370 #define in_function() (line_fsym != 0)
371 #define clear_function() (line_fsym = 0)
372 #define set_function(F) (line_fsym = (F), coff_add_linesym (F))
375 void
376 coff_obj_symbol_new_hook (symbolS *symbolP)
378 long sz = (OBJ_COFF_MAX_AUXENTRIES + 1) * sizeof (combined_entry_type);
379 char * s = XNEWVEC (char, sz);
381 memset (s, 0, sz);
382 coffsymbol (symbol_get_bfdsym (symbolP))->native = (combined_entry_type *) s;
383 coffsymbol (symbol_get_bfdsym (symbolP))->native->is_sym = TRUE;
385 S_SET_DATA_TYPE (symbolP, T_NULL);
386 S_SET_STORAGE_CLASS (symbolP, 0);
387 S_SET_NUMBER_AUXILIARY (symbolP, 0);
389 if (S_IS_STRING (symbolP))
390 SF_SET_STRING (symbolP);
392 if (S_IS_LOCAL (symbolP))
393 SF_SET_LOCAL (symbolP);
396 void
397 coff_obj_symbol_clone_hook (symbolS *newsymP, symbolS *orgsymP)
399 long elts = OBJ_COFF_MAX_AUXENTRIES + 1;
400 combined_entry_type * s = XNEWVEC (combined_entry_type, elts);
402 memcpy (s, coffsymbol (symbol_get_bfdsym (orgsymP))->native,
403 elts * sizeof (combined_entry_type));
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 = XNEW (struct line_no);
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. */
590 if (def_symbol_in_progress != NULL)
592 as_warn (_(".def pseudo-op used inside of .def/.endef: ignored."));
593 demand_empty_rest_of_line ();
594 return;
597 SKIP_WHITESPACES ();
599 name_end = get_symbol_name (&symbol_name);
600 symbol_name_copy = xstrdup (symbol_name);
601 #ifdef tc_canonicalize_symbol_name
602 symbol_name_copy = tc_canonicalize_symbol_name (symbol_name_copy);
603 #endif
605 /* Initialize the new symbol. */
606 def_symbol_in_progress = symbol_make (symbol_name_copy);
607 symbol_set_frag (def_symbol_in_progress, &zero_address_frag);
608 S_SET_VALUE (def_symbol_in_progress, 0);
610 if (S_IS_STRING (def_symbol_in_progress))
611 SF_SET_STRING (def_symbol_in_progress);
613 (void) restore_line_pointer (name_end);
615 demand_empty_rest_of_line ();
618 static void
619 obj_coff_endef (int ignore ATTRIBUTE_UNUSED)
621 symbolS *symbolP = NULL;
623 if (def_symbol_in_progress == NULL)
625 as_warn (_(".endef pseudo-op used outside of .def/.endef: ignored."));
626 demand_empty_rest_of_line ();
627 return;
630 /* Set the section number according to storage class. */
631 switch (S_GET_STORAGE_CLASS (def_symbol_in_progress))
633 case C_STRTAG:
634 case C_ENTAG:
635 case C_UNTAG:
636 SF_SET_TAG (def_symbol_in_progress);
637 /* Fall through. */
638 case C_FILE:
639 case C_TPDEF:
640 SF_SET_DEBUG (def_symbol_in_progress);
641 S_SET_SEGMENT (def_symbol_in_progress, fetch_coff_debug_section ());
642 break;
644 case C_EFCN:
645 SF_SET_LOCAL (def_symbol_in_progress); /* Do not emit this symbol. */
646 /* Fall through. */
647 case C_BLOCK:
648 SF_SET_PROCESS (def_symbol_in_progress); /* Will need processing before writing. */
649 /* Fall through. */
650 case C_FCN:
652 const char *name;
654 S_SET_SEGMENT (def_symbol_in_progress, text_section);
656 name = S_GET_NAME (def_symbol_in_progress);
657 if (name[0] == '.' && name[2] == 'f' && name[3] == '\0')
659 switch (name[1])
661 case 'b':
662 /* .bf */
663 if (! in_function ())
664 as_warn (_("`%s' symbol without preceding function"), name);
665 /* Will need relocating. */
666 SF_SET_PROCESS (def_symbol_in_progress);
667 clear_function ();
668 break;
669 #ifdef TE_PE
670 case 'e':
671 /* .ef */
672 /* The MS compilers output the actual endline, not the
673 function-relative one... we want to match without
674 changing the assembler input. */
675 SA_SET_SYM_LNNO (def_symbol_in_progress,
676 (SA_GET_SYM_LNNO (def_symbol_in_progress)
677 + coff_line_base));
678 break;
679 #endif
683 break;
685 #ifdef C_AUTOARG
686 case C_AUTOARG:
687 #endif /* C_AUTOARG */
688 case C_AUTO:
689 case C_REG:
690 case C_ARG:
691 case C_REGPARM:
692 case C_FIELD:
694 /* According to the COFF documentation:
696 http://osr5doc.sco.com:1996/topics/COFF_SectNumFld.html
698 A special section number (-2) marks symbolic debugging symbols,
699 including structure/union/enumeration tag names, typedefs, and
700 the name of the file. A section number of -1 indicates that the
701 symbol has a value but is not relocatable. Examples of
702 absolute-valued symbols include automatic and register variables,
703 function arguments, and .eos symbols.
705 But from Ian Lance Taylor:
707 http://sources.redhat.com/ml/binutils/2000-08/msg00202.html
709 the actual tools all marked them as section -1. So the GNU COFF
710 assembler follows historical COFF assemblers.
712 However, it causes problems for djgpp
714 http://sources.redhat.com/ml/binutils/2000-08/msg00210.html
716 By defining STRICTCOFF, a COFF port can make the assembler to
717 follow the documented behavior. */
718 #ifdef STRICTCOFF
719 case C_MOS:
720 case C_MOE:
721 case C_MOU:
722 case C_EOS:
723 #endif
724 SF_SET_DEBUG (def_symbol_in_progress);
725 S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
726 break;
728 #ifndef STRICTCOFF
729 case C_MOS:
730 case C_MOE:
731 case C_MOU:
732 case C_EOS:
733 S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
734 break;
735 #endif
737 case C_EXT:
738 case C_WEAKEXT:
739 #ifdef TE_PE
740 case C_NT_WEAK:
741 #endif
742 case C_STAT:
743 case C_LABEL:
744 /* Valid but set somewhere else (s_comm, s_lcomm, colon). */
745 break;
747 default:
748 case C_USTATIC:
749 case C_EXTDEF:
750 case C_ULABEL:
751 as_warn (_("unexpected storage class %d"),
752 S_GET_STORAGE_CLASS (def_symbol_in_progress));
753 break;
756 /* Now that we have built a debug symbol, try to find if we should
757 merge with an existing symbol or not. If a symbol is C_EFCN or
758 absolute_section or untagged SEG_DEBUG it never merges. We also
759 don't merge labels, which are in a different namespace, nor
760 symbols which have not yet been defined since they are typically
761 unique, nor do we merge tags with non-tags. */
763 /* Two cases for functions. Either debug followed by definition or
764 definition followed by debug. For definition first, we will
765 merge the debug symbol into the definition. For debug first, the
766 lineno entry MUST point to the definition function or else it
767 will point off into space when obj_crawl_symbol_chain() merges
768 the debug symbol into the real symbol. Therefor, let's presume
769 the debug symbol is a real function reference. */
771 /* FIXME-SOON If for some reason the definition label/symbol is
772 never seen, this will probably leave an undefined symbol at link
773 time. */
775 if (S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_EFCN
776 || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_LABEL
777 || (streq (bfd_get_section_name (stdoutput,
778 S_GET_SEGMENT (def_symbol_in_progress)),
779 "*DEBUG*")
780 && !SF_GET_TAG (def_symbol_in_progress))
781 || S_GET_SEGMENT (def_symbol_in_progress) == absolute_section
782 || ! symbol_constant_p (def_symbol_in_progress)
783 || (symbolP = symbol_find (S_GET_NAME (def_symbol_in_progress))) == NULL
784 || SF_GET_TAG (def_symbol_in_progress) != SF_GET_TAG (symbolP))
786 /* If it already is at the end of the symbol list, do nothing */
787 if (def_symbol_in_progress != symbol_lastP)
789 symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
790 symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP,
791 &symbol_lastP);
794 else
796 /* This symbol already exists, merge the newly created symbol
797 into the old one. This is not mandatory. The linker can
798 handle duplicate symbols correctly. But I guess that it save
799 a *lot* of space if the assembly file defines a lot of
800 symbols. [loic] */
802 /* The debug entry (def_symbol_in_progress) is merged into the
803 previous definition. */
805 c_symbol_merge (def_symbol_in_progress, symbolP);
806 symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
808 def_symbol_in_progress = symbolP;
810 if (SF_GET_FUNCTION (def_symbol_in_progress)
811 || SF_GET_TAG (def_symbol_in_progress)
812 || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_STAT)
814 /* For functions, and tags, and static symbols, the symbol
815 *must* be where the debug symbol appears. Move the
816 existing symbol to the current place. */
817 /* If it already is at the end of the symbol list, do nothing. */
818 if (def_symbol_in_progress != symbol_lastP)
820 symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
821 symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
826 if (SF_GET_TAG (def_symbol_in_progress))
828 symbolS *oldtag;
830 oldtag = symbol_find (S_GET_NAME (def_symbol_in_progress));
831 if (oldtag == NULL || ! SF_GET_TAG (oldtag))
832 tag_insert (S_GET_NAME (def_symbol_in_progress),
833 def_symbol_in_progress);
836 if (SF_GET_FUNCTION (def_symbol_in_progress))
838 set_function (def_symbol_in_progress);
839 SF_SET_PROCESS (def_symbol_in_progress);
841 if (symbolP == NULL)
842 /* That is, if this is the first time we've seen the
843 function. */
844 symbol_table_insert (def_symbol_in_progress);
848 def_symbol_in_progress = NULL;
849 demand_empty_rest_of_line ();
852 static void
853 obj_coff_dim (int ignore ATTRIBUTE_UNUSED)
855 int d_index;
857 if (def_symbol_in_progress == NULL)
859 as_warn (_(".dim pseudo-op used outside of .def/.endef: ignored."));
860 demand_empty_rest_of_line ();
861 return;
864 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
866 for (d_index = 0; d_index < DIMNUM; d_index++)
868 SKIP_WHITESPACES ();
869 SA_SET_SYM_DIMEN (def_symbol_in_progress, d_index,
870 get_absolute_expression ());
872 switch (*input_line_pointer)
874 case ',':
875 input_line_pointer++;
876 break;
878 default:
879 as_warn (_("badly formed .dim directive ignored"));
880 /* Fall through. */
881 case '\n':
882 case ';':
883 d_index = DIMNUM;
884 break;
888 demand_empty_rest_of_line ();
891 static void
892 obj_coff_line (int ignore ATTRIBUTE_UNUSED)
894 int this_base;
896 if (def_symbol_in_progress == NULL)
898 /* Probably stabs-style line? */
899 obj_coff_ln (0);
900 return;
903 this_base = get_absolute_expression ();
904 if (streq (".bf", S_GET_NAME (def_symbol_in_progress)))
905 coff_line_base = this_base;
907 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
908 SA_SET_SYM_LNNO (def_symbol_in_progress, this_base);
910 demand_empty_rest_of_line ();
912 #ifndef NO_LISTING
913 if (streq (".bf", S_GET_NAME (def_symbol_in_progress)))
915 extern int listing;
917 if (listing)
918 listing_source_line ((unsigned int) this_base);
920 #endif
923 static void
924 obj_coff_size (int ignore ATTRIBUTE_UNUSED)
926 if (def_symbol_in_progress == NULL)
928 as_warn (_(".size pseudo-op used outside of .def/.endef: ignored."));
929 demand_empty_rest_of_line ();
930 return;
933 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
934 SA_SET_SYM_SIZE (def_symbol_in_progress, get_absolute_expression ());
935 demand_empty_rest_of_line ();
938 static void
939 obj_coff_scl (int ignore ATTRIBUTE_UNUSED)
941 if (def_symbol_in_progress == NULL)
943 as_warn (_(".scl pseudo-op used outside of .def/.endef: ignored."));
944 demand_empty_rest_of_line ();
945 return;
948 S_SET_STORAGE_CLASS (def_symbol_in_progress, get_absolute_expression ());
949 demand_empty_rest_of_line ();
952 static void
953 obj_coff_tag (int ignore ATTRIBUTE_UNUSED)
955 char *symbol_name;
956 char name_end;
958 if (def_symbol_in_progress == NULL)
960 as_warn (_(".tag pseudo-op used outside of .def/.endef: ignored."));
961 demand_empty_rest_of_line ();
962 return;
965 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
966 name_end = get_symbol_name (&symbol_name);
968 #ifdef tc_canonicalize_symbol_name
969 symbol_name = tc_canonicalize_symbol_name (symbol_name);
970 #endif
972 /* Assume that the symbol referred to by .tag is always defined.
973 This was a bad assumption. I've added find_or_make. xoxorich. */
974 SA_SET_SYM_TAGNDX (def_symbol_in_progress,
975 tag_find_or_make (symbol_name));
976 if (SA_GET_SYM_TAGNDX (def_symbol_in_progress) == 0L)
977 as_warn (_("tag not found for .tag %s"), symbol_name);
979 SF_SET_TAGGED (def_symbol_in_progress);
981 (void) restore_line_pointer (name_end);
982 demand_empty_rest_of_line ();
985 static void
986 obj_coff_type (int ignore ATTRIBUTE_UNUSED)
988 if (def_symbol_in_progress == NULL)
990 as_warn (_(".type pseudo-op used outside of .def/.endef: ignored."));
991 demand_empty_rest_of_line ();
992 return;
995 S_SET_DATA_TYPE (def_symbol_in_progress, get_absolute_expression ());
997 if (ISFCN (S_GET_DATA_TYPE (def_symbol_in_progress)) &&
998 S_GET_STORAGE_CLASS (def_symbol_in_progress) != C_TPDEF)
999 SF_SET_FUNCTION (def_symbol_in_progress);
1001 demand_empty_rest_of_line ();
1004 static void
1005 obj_coff_val (int ignore ATTRIBUTE_UNUSED)
1007 if (def_symbol_in_progress == NULL)
1009 as_warn (_(".val pseudo-op used outside of .def/.endef: ignored."));
1010 demand_empty_rest_of_line ();
1011 return;
1014 if (is_name_beginner (*input_line_pointer))
1016 char *symbol_name;
1017 char name_end = get_symbol_name (&symbol_name);
1019 #ifdef tc_canonicalize_symbol_name
1020 symbol_name = tc_canonicalize_symbol_name (symbol_name);
1021 #endif
1022 if (streq (symbol_name, "."))
1024 /* If the .val is != from the .def (e.g. statics). */
1025 symbol_set_frag (def_symbol_in_progress, frag_now);
1026 S_SET_VALUE (def_symbol_in_progress, (valueT) frag_now_fix ());
1028 else if (! streq (S_GET_NAME (def_symbol_in_progress), symbol_name))
1030 expressionS exp;
1032 exp.X_op = O_symbol;
1033 exp.X_add_symbol = symbol_find_or_make (symbol_name);
1034 exp.X_op_symbol = NULL;
1035 exp.X_add_number = 0;
1036 symbol_set_value_expression (def_symbol_in_progress, &exp);
1038 /* If the segment is undefined when the forward reference is
1039 resolved, then copy the segment id from the forward
1040 symbol. */
1041 SF_SET_GET_SEGMENT (def_symbol_in_progress);
1043 /* FIXME: gcc can generate address expressions here in
1044 unusual cases (search for "obscure" in sdbout.c). We
1045 just ignore the offset here, thus generating incorrect
1046 debugging information. We ignore the rest of the line
1047 just below. */
1049 /* Otherwise, it is the name of a non debug symbol and its value
1050 will be calculated later. */
1051 (void) restore_line_pointer (name_end);
1053 else
1055 S_SET_VALUE (def_symbol_in_progress, get_absolute_expression ());
1058 demand_empty_rest_of_line ();
1061 #ifdef TE_PE
1063 /* Return nonzero if name begins with weak alternate symbol prefix. */
1065 static int
1066 weak_is_altname (const char * name)
1068 return strneq (name, weak_altprefix, sizeof (weak_altprefix) - 1);
1071 /* Return the name of the alternate symbol
1072 name corresponding to a weak symbol's name. */
1074 static const char *
1075 weak_name2altname (const char * name)
1077 return concat (weak_altprefix, name, (char *) NULL);
1080 /* Return the name of the weak symbol corresponding to an
1081 alternate symbol. */
1083 static const char *
1084 weak_altname2name (const char * name)
1086 gas_assert (weak_is_altname (name));
1087 return xstrdup (name + 6);
1090 /* Make a weak symbol name unique by
1091 appending the name of an external symbol. */
1093 static const char *
1094 weak_uniquify (const char * name)
1096 const char * unique = "";
1098 #ifdef TE_PE
1099 if (an_external_name != NULL)
1100 unique = an_external_name;
1101 #endif
1102 gas_assert (weak_is_altname (name));
1104 return concat (name, ".", unique, (char *) NULL);
1107 void
1108 pecoff_obj_set_weak_hook (symbolS *symbolP)
1110 symbolS *alternateP;
1112 /* See _Microsoft Portable Executable and Common Object
1113 File Format Specification_, section 5.5.3.
1114 Create a symbol representing the alternate value.
1115 coff_frob_symbol will set the value of this symbol from
1116 the value of the weak symbol itself. */
1117 S_SET_STORAGE_CLASS (symbolP, C_NT_WEAK);
1118 S_SET_NUMBER_AUXILIARY (symbolP, 1);
1119 SA_SET_SYM_FSIZE (symbolP, IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY);
1121 alternateP = symbol_find_or_make (weak_name2altname (S_GET_NAME (symbolP)));
1122 S_SET_EXTERNAL (alternateP);
1123 S_SET_STORAGE_CLASS (alternateP, C_NT_WEAK);
1125 SA_SET_SYM_TAGNDX (symbolP, alternateP);
1128 void
1129 pecoff_obj_clear_weak_hook (symbolS *symbolP)
1131 symbolS *alternateP;
1133 S_SET_STORAGE_CLASS (symbolP, 0);
1134 SA_SET_SYM_FSIZE (symbolP, 0);
1136 alternateP = symbol_find (weak_name2altname (S_GET_NAME (symbolP)));
1137 S_CLEAR_EXTERNAL (alternateP);
1140 #endif /* TE_PE */
1142 /* Handle .weak. This is a GNU extension in formats other than PE. */
1144 static void
1145 obj_coff_weak (int ignore ATTRIBUTE_UNUSED)
1147 char *name;
1148 int c;
1149 symbolS *symbolP;
1153 c = get_symbol_name (&name);
1154 if (*name == 0)
1156 as_warn (_("badly formed .weak directive ignored"));
1157 ignore_rest_of_line ();
1158 return;
1160 c = 0;
1161 symbolP = symbol_find_or_make (name);
1162 *input_line_pointer = c;
1163 SKIP_WHITESPACE_AFTER_NAME ();
1164 S_SET_WEAK (symbolP);
1166 if (c == ',')
1168 input_line_pointer++;
1169 SKIP_WHITESPACE ();
1170 if (*input_line_pointer == '\n')
1171 c = '\n';
1175 while (c == ',');
1177 demand_empty_rest_of_line ();
1180 void
1181 coff_obj_read_begin_hook (void)
1183 /* These had better be the same. Usually 18 bytes. */
1184 know (sizeof (SYMENT) == sizeof (AUXENT));
1185 know (SYMESZ == AUXESZ);
1186 tag_init ();
1189 symbolS *coff_last_function;
1190 #ifndef OBJ_XCOFF
1191 static symbolS *coff_last_bf;
1192 #endif
1194 void
1195 coff_frob_symbol (symbolS *symp, int *punt)
1197 static symbolS *last_tagP;
1198 static stack *block_stack;
1199 static symbolS *set_end;
1200 symbolS *next_set_end = NULL;
1202 if (symp == &abs_symbol)
1204 *punt = 1;
1205 return;
1208 if (current_lineno_sym)
1209 coff_add_linesym (NULL);
1211 if (!block_stack)
1212 block_stack = stack_init (512, sizeof (symbolS*));
1214 #ifdef TE_PE
1215 if (S_GET_STORAGE_CLASS (symp) == C_NT_WEAK
1216 && ! S_IS_WEAK (symp)
1217 && weak_is_altname (S_GET_NAME (symp)))
1219 /* This is a weak alternate symbol. All processing of
1220 PECOFFweak symbols is done here, through the alternate. */
1221 symbolS *weakp = symbol_find_noref (weak_altname2name
1222 (S_GET_NAME (symp)), 1);
1224 gas_assert (weakp);
1225 gas_assert (S_GET_NUMBER_AUXILIARY (weakp) == 1);
1227 if (! S_IS_WEAK (weakp))
1229 /* The symbol was turned from weak to strong. Discard altname. */
1230 *punt = 1;
1231 return;
1233 else if (symbol_equated_p (weakp))
1235 /* The weak symbol has an alternate specified; symp is unneeded. */
1236 S_SET_STORAGE_CLASS (weakp, C_NT_WEAK);
1237 SA_SET_SYM_TAGNDX (weakp,
1238 symbol_get_value_expression (weakp)->X_add_symbol);
1240 S_CLEAR_EXTERNAL (symp);
1241 *punt = 1;
1242 return;
1244 else
1246 /* The weak symbol has been assigned an alternate value.
1247 Copy this value to symp, and set symp as weakp's alternate. */
1248 if (S_GET_STORAGE_CLASS (weakp) != C_NT_WEAK)
1250 S_SET_STORAGE_CLASS (symp, S_GET_STORAGE_CLASS (weakp));
1251 S_SET_STORAGE_CLASS (weakp, C_NT_WEAK);
1254 if (S_IS_DEFINED (weakp))
1256 /* This is a defined weak symbol. Copy value information
1257 from the weak symbol itself to the alternate symbol. */
1258 symbol_set_value_expression (symp,
1259 symbol_get_value_expression (weakp));
1260 symbol_set_frag (symp, symbol_get_frag (weakp));
1261 S_SET_SEGMENT (symp, S_GET_SEGMENT (weakp));
1263 else
1265 /* This is an undefined weak symbol.
1266 Define the alternate symbol to zero. */
1267 S_SET_VALUE (symp, 0);
1268 S_SET_SEGMENT (symp, absolute_section);
1271 S_SET_NAME (symp, weak_uniquify (S_GET_NAME (symp)));
1272 S_SET_STORAGE_CLASS (symp, C_EXT);
1274 S_SET_VALUE (weakp, 0);
1275 S_SET_SEGMENT (weakp, undefined_section);
1278 #else /* TE_PE */
1279 if (S_IS_WEAK (symp))
1280 S_SET_STORAGE_CLASS (symp, C_WEAKEXT);
1281 #endif /* TE_PE */
1283 if (!S_IS_DEFINED (symp)
1284 && !S_IS_WEAK (symp)
1285 && S_GET_STORAGE_CLASS (symp) != C_STAT)
1286 S_SET_STORAGE_CLASS (symp, C_EXT);
1288 if (!SF_GET_DEBUG (symp))
1290 symbolS * real;
1292 if (!SF_GET_LOCAL (symp)
1293 && !SF_GET_STATICS (symp)
1294 && S_GET_STORAGE_CLASS (symp) != C_LABEL
1295 && symbol_constant_p (symp)
1296 && (real = symbol_find_noref (S_GET_NAME (symp), 1))
1297 && S_GET_STORAGE_CLASS (real) == C_NULL
1298 && real != symp)
1300 c_symbol_merge (symp, real);
1301 *punt = 1;
1302 return;
1305 if (!S_IS_DEFINED (symp) && !SF_GET_LOCAL (symp))
1307 gas_assert (S_GET_VALUE (symp) == 0);
1308 if (S_IS_WEAKREFD (symp))
1309 *punt = 1;
1310 else
1311 S_SET_EXTERNAL (symp);
1313 else if (S_GET_STORAGE_CLASS (symp) == C_NULL)
1315 if (S_GET_SEGMENT (symp) == text_section
1316 && symp != seg_info (text_section)->sym)
1317 S_SET_STORAGE_CLASS (symp, C_LABEL);
1318 else
1319 S_SET_STORAGE_CLASS (symp, C_STAT);
1322 if (SF_GET_PROCESS (symp))
1324 if (S_GET_STORAGE_CLASS (symp) == C_BLOCK)
1326 if (streq (S_GET_NAME (symp), ".bb"))
1327 stack_push (block_stack, (char *) &symp);
1328 else
1330 symbolS *begin;
1332 begin = *(symbolS **) stack_pop (block_stack);
1333 if (begin == 0)
1334 as_warn (_("mismatched .eb"));
1335 else
1336 next_set_end = begin;
1340 if (coff_last_function == 0 && SF_GET_FUNCTION (symp)
1341 && S_IS_DEFINED (symp))
1343 union internal_auxent *auxp;
1345 coff_last_function = symp;
1346 if (S_GET_NUMBER_AUXILIARY (symp) < 1)
1347 S_SET_NUMBER_AUXILIARY (symp, 1);
1348 auxp = SYM_AUXENT (symp);
1349 memset (auxp->x_sym.x_fcnary.x_ary.x_dimen, 0,
1350 sizeof (auxp->x_sym.x_fcnary.x_ary.x_dimen));
1353 if (S_GET_STORAGE_CLASS (symp) == C_EFCN
1354 && S_IS_DEFINED (symp))
1356 if (coff_last_function == 0)
1357 as_fatal (_("C_EFCN symbol for %s out of scope"),
1358 S_GET_NAME (symp));
1359 SA_SET_SYM_FSIZE (coff_last_function,
1360 (long) (S_GET_VALUE (symp)
1361 - S_GET_VALUE (coff_last_function)));
1362 next_set_end = coff_last_function;
1363 coff_last_function = 0;
1367 if (S_IS_EXTERNAL (symp))
1368 S_SET_STORAGE_CLASS (symp, C_EXT);
1369 else if (SF_GET_LOCAL (symp))
1370 *punt = 1;
1372 if (SF_GET_FUNCTION (symp))
1373 symbol_get_bfdsym (symp)->flags |= BSF_FUNCTION;
1376 /* Double check weak symbols. */
1377 if (S_IS_WEAK (symp) && S_IS_COMMON (symp))
1378 as_bad (_("Symbol `%s' can not be both weak and common"),
1379 S_GET_NAME (symp));
1381 if (SF_GET_TAG (symp))
1382 last_tagP = symp;
1383 else if (S_GET_STORAGE_CLASS (symp) == C_EOS)
1384 next_set_end = last_tagP;
1386 #ifdef OBJ_XCOFF
1387 /* This is pretty horrible, but we have to set *punt correctly in
1388 order to call SA_SET_SYM_ENDNDX correctly. */
1389 if (! symbol_used_in_reloc_p (symp)
1390 && ((symbol_get_bfdsym (symp)->flags & BSF_SECTION_SYM) != 0
1391 || (! (S_IS_EXTERNAL (symp) || S_IS_WEAK (symp))
1392 && ! symbol_get_tc (symp)->output
1393 && S_GET_STORAGE_CLASS (symp) != C_FILE)))
1394 *punt = 1;
1395 #endif
1397 if (set_end != (symbolS *) NULL
1398 && ! *punt
1399 && ((symbol_get_bfdsym (symp)->flags & BSF_NOT_AT_END) != 0
1400 || (S_IS_DEFINED (symp)
1401 && ! S_IS_COMMON (symp)
1402 && (! S_IS_EXTERNAL (symp) || SF_GET_FUNCTION (symp)))))
1404 SA_SET_SYM_ENDNDX (set_end, symp);
1405 set_end = NULL;
1408 if (next_set_end != NULL)
1410 if (set_end != NULL)
1411 as_warn (_("Warning: internal error: forgetting to set endndx of %s"),
1412 S_GET_NAME (set_end));
1413 set_end = next_set_end;
1416 #ifndef OBJ_XCOFF
1417 if (! *punt
1418 && S_GET_STORAGE_CLASS (symp) == C_FCN
1419 && streq (S_GET_NAME (symp), ".bf"))
1421 if (coff_last_bf != NULL)
1422 SA_SET_SYM_ENDNDX (coff_last_bf, symp);
1423 coff_last_bf = symp;
1425 #endif
1426 if (coffsymbol (symbol_get_bfdsym (symp))->lineno)
1428 int i;
1429 struct line_no *lptr;
1430 alent *l;
1432 lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno;
1433 for (i = 0; lptr; lptr = lptr->next)
1434 i++;
1435 lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno;
1437 /* We need i entries for line numbers, plus 1 for the first
1438 entry which BFD will override, plus 1 for the last zero
1439 entry (a marker for BFD). */
1440 l = XNEWVEC (alent, (i + 2));
1441 coffsymbol (symbol_get_bfdsym (symp))->lineno = l;
1442 l[i + 1].line_number = 0;
1443 l[i + 1].u.sym = NULL;
1444 for (; i > 0; i--)
1446 if (lptr->frag)
1447 lptr->l.u.offset += lptr->frag->fr_address / OCTETS_PER_BYTE;
1448 l[i] = lptr->l;
1449 lptr = lptr->next;
1454 void
1455 coff_adjust_section_syms (bfd *abfd ATTRIBUTE_UNUSED,
1456 asection *sec,
1457 void * x ATTRIBUTE_UNUSED)
1459 symbolS *secsym;
1460 segment_info_type *seginfo = seg_info (sec);
1461 int nlnno, nrelocs = 0;
1463 /* RS/6000 gas creates a .debug section manually in ppc_frob_file in
1464 tc-ppc.c. Do not get confused by it. */
1465 if (seginfo == NULL)
1466 return;
1468 if (streq (sec->name, ".text"))
1469 nlnno = coff_n_line_nos;
1470 else
1471 nlnno = 0;
1473 /* @@ Hope that none of the fixups expand to more than one reloc
1474 entry... */
1475 fixS *fixp = seginfo->fix_root;
1476 while (fixp)
1478 if (! fixp->fx_done)
1479 nrelocs++;
1480 fixp = fixp->fx_next;
1483 if (bfd_get_section_size (sec) == 0
1484 && nrelocs == 0
1485 && nlnno == 0
1486 && sec != text_section
1487 && sec != data_section
1488 && sec != bss_section)
1489 return;
1491 secsym = section_symbol (sec);
1492 /* This is an estimate; we'll plug in the real value using
1493 SET_SECTION_RELOCS later */
1494 SA_SET_SCN_NRELOC (secsym, nrelocs);
1495 SA_SET_SCN_NLINNO (secsym, nlnno);
1498 void
1499 coff_frob_file_after_relocs (void)
1501 bfd_map_over_sections (stdoutput, coff_adjust_section_syms, NULL);
1504 /* Implement the .section pseudo op:
1505 .section name {, "flags"}
1507 | +--- optional flags: 'b' for bss
1508 | 'i' for info
1509 +-- section name 'l' for lib
1510 'n' for noload
1511 'o' for over
1512 'w' for data
1513 'd' (apparently m88k for data)
1514 'e' for exclude
1515 'x' for text
1516 'r' for read-only data
1517 's' for shared data (PE)
1518 'y' for noread
1519 '0' - '9' for power-of-two alignment (GNU extension).
1520 But if the argument is not a quoted string, treat it as a
1521 subsegment number.
1523 Note the 'a' flag is silently ignored. This allows the same
1524 .section directive to be parsed in both ELF and COFF formats. */
1526 void
1527 obj_coff_section (int ignore ATTRIBUTE_UNUSED)
1529 /* Strip out the section name. */
1530 char *section_name;
1531 char c;
1532 int alignment = -1;
1533 char *name;
1534 unsigned int exp;
1535 flagword flags, oldflags;
1536 asection *sec;
1538 if (flag_mri)
1540 char type;
1542 s_mri_sect (&type);
1543 return;
1546 c = get_symbol_name (&section_name);
1547 name = xmemdup0 (section_name, input_line_pointer - section_name);
1548 *input_line_pointer = c;
1549 SKIP_WHITESPACE_AFTER_NAME ();
1551 exp = 0;
1552 flags = SEC_NO_FLAGS;
1554 if (*input_line_pointer == ',')
1556 ++input_line_pointer;
1557 SKIP_WHITESPACE ();
1558 if (*input_line_pointer != '"')
1559 exp = get_absolute_expression ();
1560 else
1562 unsigned char attr;
1563 int readonly_removed = 0;
1564 int load_removed = 0;
1566 while (attr = *++input_line_pointer,
1567 attr != '"'
1568 && ! is_end_of_line[attr])
1570 if (ISDIGIT (attr))
1572 alignment = attr - '0';
1573 continue;
1575 switch (attr)
1577 case 'e':
1578 /* Exclude section from linking. */
1579 flags |= SEC_EXCLUDE;
1580 break;
1582 case 'b':
1583 /* Uninitialised data section. */
1584 flags |= SEC_ALLOC;
1585 flags &=~ SEC_LOAD;
1586 break;
1588 case 'n':
1589 /* Section not loaded. */
1590 flags &=~ SEC_LOAD;
1591 flags |= SEC_NEVER_LOAD;
1592 load_removed = 1;
1593 break;
1595 case 's':
1596 /* Shared section. */
1597 flags |= SEC_COFF_SHARED;
1598 /* Fall through. */
1599 case 'd':
1600 /* Data section. */
1601 flags |= SEC_DATA;
1602 if (! load_removed)
1603 flags |= SEC_LOAD;
1604 flags &=~ SEC_READONLY;
1605 break;
1607 case 'w':
1608 /* Writable section. */
1609 flags &=~ SEC_READONLY;
1610 readonly_removed = 1;
1611 break;
1613 case 'a':
1614 /* Ignore. Here for compatibility with ELF. */
1615 break;
1617 case 'r': /* Read-only section. Implies a data section. */
1618 readonly_removed = 0;
1619 /* Fall through. */
1620 case 'x': /* Executable section. */
1621 /* If we are setting the 'x' attribute or if the 'r'
1622 attribute is being used to restore the readonly status
1623 of a code section (eg "wxr") then set the SEC_CODE flag,
1624 otherwise set the SEC_DATA flag. */
1625 flags |= (attr == 'x' || (flags & SEC_CODE) ? SEC_CODE : SEC_DATA);
1626 if (! load_removed)
1627 flags |= SEC_LOAD;
1628 /* Note - the READONLY flag is set here, even for the 'x'
1629 attribute in order to be compatible with the MSVC
1630 linker. */
1631 if (! readonly_removed)
1632 flags |= SEC_READONLY;
1633 break;
1635 case 'y':
1636 flags |= SEC_COFF_NOREAD | SEC_READONLY;
1637 break;
1639 case 'i': /* STYP_INFO */
1640 case 'l': /* STYP_LIB */
1641 case 'o': /* STYP_OVER */
1642 as_warn (_("unsupported section attribute '%c'"), attr);
1643 break;
1645 default:
1646 as_warn (_("unknown section attribute '%c'"), attr);
1647 break;
1650 if (attr == '"')
1651 ++input_line_pointer;
1655 sec = subseg_new (name, (subsegT) exp);
1657 if (alignment >= 0)
1658 sec->alignment_power = alignment;
1660 oldflags = bfd_get_section_flags (stdoutput, sec);
1661 if (oldflags == SEC_NO_FLAGS)
1663 /* Set section flags for a new section just created by subseg_new.
1664 Provide a default if no flags were parsed. */
1665 if (flags == SEC_NO_FLAGS)
1666 flags = TC_COFF_SECTION_DEFAULT_ATTRIBUTES;
1668 #ifdef COFF_LONG_SECTION_NAMES
1669 /* Add SEC_LINK_ONCE and SEC_LINK_DUPLICATES_DISCARD to .gnu.linkonce
1670 sections so adjust_reloc_syms in write.c will correctly handle
1671 relocs which refer to non-local symbols in these sections. */
1672 if (strneq (name, ".gnu.linkonce", sizeof (".gnu.linkonce") - 1))
1673 flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
1674 #endif
1676 if (! bfd_set_section_flags (stdoutput, sec, flags))
1677 as_warn (_("error setting flags for \"%s\": %s"),
1678 bfd_section_name (stdoutput, sec),
1679 bfd_errmsg (bfd_get_error ()));
1681 else if (flags != SEC_NO_FLAGS)
1683 /* This section's attributes have already been set. Warn if the
1684 attributes don't match. */
1685 flagword matchflags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
1686 | SEC_DATA | SEC_COFF_SHARED | SEC_NEVER_LOAD
1687 | SEC_COFF_NOREAD);
1688 if ((flags ^ oldflags) & matchflags)
1689 as_warn (_("Ignoring changed section attributes for %s"), name);
1692 demand_empty_rest_of_line ();
1695 void
1696 coff_adjust_symtab (void)
1698 if (symbol_rootP == NULL
1699 || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
1700 c_dot_file_symbol ("fake", 0);
1703 void
1704 coff_frob_section (segT sec)
1706 segT strsec;
1707 char *p;
1708 fragS *fragp;
1709 bfd_vma n_entries;
1711 /* The COFF back end in BFD requires that all section sizes be
1712 rounded up to multiples of the corresponding section alignments,
1713 supposedly because standard COFF has no other way of encoding alignment
1714 for sections. If your COFF flavor has a different way of encoding
1715 section alignment, then skip this step, as TICOFF does. */
1716 bfd_vma size = bfd_get_section_size (sec);
1717 #if !defined(TICOFF)
1718 bfd_vma align_power = (bfd_vma) sec->alignment_power + OCTETS_PER_BYTE_POWER;
1719 bfd_vma mask = ((bfd_vma) 1 << align_power) - 1;
1721 if (size & mask)
1723 bfd_vma new_size;
1724 fragS *last;
1726 new_size = (size + mask) & ~mask;
1727 bfd_set_section_size (stdoutput, sec, new_size);
1729 /* If the size had to be rounded up, add some padding in
1730 the last non-empty frag. */
1731 fragp = seg_info (sec)->frchainP->frch_root;
1732 last = seg_info (sec)->frchainP->frch_last;
1733 while (fragp->fr_next != last)
1734 fragp = fragp->fr_next;
1735 last->fr_address = size;
1736 fragp->fr_offset += new_size - size;
1738 #endif
1740 /* If the section size is non-zero, the section symbol needs an aux
1741 entry associated with it, indicating the size. We don't know
1742 all the values yet; coff_frob_symbol will fill them in later. */
1743 #ifndef TICOFF
1744 if (size != 0
1745 || sec == text_section
1746 || sec == data_section
1747 || sec == bss_section)
1748 #endif
1750 symbolS *secsym = section_symbol (sec);
1751 unsigned char sclass = C_STAT;
1753 #ifdef OBJ_XCOFF
1754 if (bfd_get_section_flags (stdoutput, sec) & SEC_DEBUGGING)
1755 sclass = C_DWARF;
1756 #endif
1757 S_SET_STORAGE_CLASS (secsym, sclass);
1758 S_SET_NUMBER_AUXILIARY (secsym, 1);
1759 SF_SET_STATICS (secsym);
1760 SA_SET_SCN_SCNLEN (secsym, size);
1762 /* FIXME: These should be in a "stabs.h" file, or maybe as.h. */
1763 #ifndef STAB_SECTION_NAME
1764 #define STAB_SECTION_NAME ".stab"
1765 #endif
1766 #ifndef STAB_STRING_SECTION_NAME
1767 #define STAB_STRING_SECTION_NAME ".stabstr"
1768 #endif
1769 if (! streq (STAB_STRING_SECTION_NAME, sec->name))
1770 return;
1772 strsec = sec;
1773 sec = subseg_get (STAB_SECTION_NAME, 0);
1774 /* size is already rounded up, since other section will be listed first */
1775 size = bfd_get_section_size (strsec);
1777 n_entries = bfd_get_section_size (sec) / 12 - 1;
1779 /* Find first non-empty frag. It should be large enough. */
1780 fragp = seg_info (sec)->frchainP->frch_root;
1781 while (fragp && fragp->fr_fix == 0)
1782 fragp = fragp->fr_next;
1783 gas_assert (fragp != 0 && fragp->fr_fix >= 12);
1785 /* Store the values. */
1786 p = fragp->fr_literal;
1787 bfd_h_put_16 (stdoutput, n_entries, (bfd_byte *) p + 6);
1788 bfd_h_put_32 (stdoutput, size, (bfd_byte *) p + 8);
1791 void
1792 obj_coff_init_stab_section (segT seg)
1794 const char *file;
1795 char *p;
1796 char *stabstr_name;
1797 unsigned int stroff;
1799 /* Make space for this first symbol. */
1800 p = frag_more (12);
1801 /* Zero it out. */
1802 memset (p, 0, 12);
1803 file = as_where ((unsigned int *) NULL);
1804 stabstr_name = concat (seg->name, "str", (char *) NULL);
1805 stroff = get_stab_string_offset (file, stabstr_name, TRUE);
1806 know (stroff == 1);
1807 md_number_to_chars (p, stroff, 4);
1810 #ifdef DEBUG
1811 const char * s_get_name (symbolS *);
1813 const char *
1814 s_get_name (symbolS *s)
1816 return ((s == NULL) ? "(NULL)" : S_GET_NAME (s));
1819 void symbol_dump (void);
1821 void
1822 symbol_dump (void)
1824 symbolS *symbolP;
1826 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
1827 printf (_("0x%lx: \"%s\" type = %ld, class = %d, segment = %d\n"),
1828 (unsigned long) symbolP,
1829 S_GET_NAME (symbolP),
1830 (long) S_GET_DATA_TYPE (symbolP),
1831 S_GET_STORAGE_CLASS (symbolP),
1832 (int) S_GET_SEGMENT (symbolP));
1835 #endif /* DEBUG */
1837 const pseudo_typeS coff_pseudo_table[] =
1839 {"ABORT", s_abort, 0},
1840 {"appline", obj_coff_ln, 1},
1841 /* We accept the .bss directive for backward compatibility with
1842 earlier versions of gas. */
1843 {"bss", obj_coff_bss, 0},
1844 #ifdef TE_PE
1845 /* PE provides an enhanced version of .comm with alignment. */
1846 {"comm", obj_coff_comm, 0},
1847 #endif /* TE_PE */
1848 {"def", obj_coff_def, 0},
1849 {"dim", obj_coff_dim, 0},
1850 {"endef", obj_coff_endef, 0},
1851 {"ident", obj_coff_ident, 0},
1852 {"line", obj_coff_line, 0},
1853 {"ln", obj_coff_ln, 0},
1854 {"scl", obj_coff_scl, 0},
1855 {"sect", obj_coff_section, 0},
1856 {"sect.s", obj_coff_section, 0},
1857 {"section", obj_coff_section, 0},
1858 {"section.s", obj_coff_section, 0},
1859 /* FIXME: We ignore the MRI short attribute. */
1860 {"size", obj_coff_size, 0},
1861 {"tag", obj_coff_tag, 0},
1862 {"type", obj_coff_type, 0},
1863 {"val", obj_coff_val, 0},
1864 {"version", s_ignore, 0},
1865 {"loc", obj_coff_loc, 0},
1866 {"optim", s_ignore, 0}, /* For sun386i cc (?) */
1867 {"weak", obj_coff_weak, 0},
1868 #if defined TC_TIC4X
1869 /* The tic4x uses sdef instead of def. */
1870 {"sdef", obj_coff_def, 0},
1871 #endif
1872 #if defined(SEH_CMDS)
1873 SEH_CMDS
1874 #endif
1875 {NULL, NULL, 0}
1879 /* Support for a COFF emulation. */
1881 static void
1882 coff_pop_insert (void)
1884 pop_insert (coff_pseudo_table);
1887 static int
1888 coff_separate_stab_sections (void)
1890 return 1;
1893 const struct format_ops coff_format_ops =
1895 bfd_target_coff_flavour,
1896 0, /* dfl_leading_underscore */
1897 1, /* emit_section_symbols */
1898 0, /* begin */
1899 c_dot_file_symbol,
1900 coff_frob_symbol,
1901 0, /* frob_file */
1902 0, /* frob_file_before_adjust */
1903 0, /* frob_file_before_fix */
1904 coff_frob_file_after_relocs,
1905 0, /* s_get_size */
1906 0, /* s_set_size */
1907 0, /* s_get_align */
1908 0, /* s_set_align */
1909 0, /* s_get_other */
1910 0, /* s_set_other */
1911 0, /* s_get_desc */
1912 0, /* s_set_desc */
1913 0, /* s_get_type */
1914 0, /* s_set_type */
1915 0, /* copy_symbol_attributes */
1916 0, /* generate_asm_lineno */
1917 0, /* process_stab */
1918 coff_separate_stab_sections,
1919 obj_coff_init_stab_section,
1920 0, /* sec_sym_ok_for_reloc */
1921 coff_pop_insert,
1922 0, /* ecoff_set_ext */
1923 coff_obj_read_begin_hook,
1924 coff_obj_symbol_new_hook,
1925 coff_obj_symbol_clone_hook,
1926 coff_adjust_symtab