* po/bfd.pot: Updated by the Translation project.
[binutils.git] / gas / config / obj-coff.c
blob271b01ef3dc3ff3163f4b791ee135de5a169a6f0
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 unsigned int dim_index;
626 static void
627 obj_coff_endef (int ignore ATTRIBUTE_UNUSED)
629 symbolS *symbolP = NULL;
631 dim_index = 0;
632 if (def_symbol_in_progress == NULL)
634 as_warn (_(".endef pseudo-op used outside of .def/.endef: ignored."));
635 demand_empty_rest_of_line ();
636 return;
639 /* Set the section number according to storage class. */
640 switch (S_GET_STORAGE_CLASS (def_symbol_in_progress))
642 case C_STRTAG:
643 case C_ENTAG:
644 case C_UNTAG:
645 SF_SET_TAG (def_symbol_in_progress);
646 /* Fall through. */
647 case C_FILE:
648 case C_TPDEF:
649 SF_SET_DEBUG (def_symbol_in_progress);
650 S_SET_SEGMENT (def_symbol_in_progress, fetch_coff_debug_section ());
651 break;
653 case C_EFCN:
654 SF_SET_LOCAL (def_symbol_in_progress); /* Do not emit this symbol. */
655 /* Fall through. */
656 case C_BLOCK:
657 SF_SET_PROCESS (def_symbol_in_progress); /* Will need processing before writing. */
658 /* Fall through. */
659 case C_FCN:
661 const char *name;
663 S_SET_SEGMENT (def_symbol_in_progress, text_section);
665 name = S_GET_NAME (def_symbol_in_progress);
666 if (name[0] == '.' && name[2] == 'f' && name[3] == '\0')
668 switch (name[1])
670 case 'b':
671 /* .bf */
672 if (! in_function ())
673 as_warn (_("`%s' symbol without preceding function"), name);
674 /* Will need relocating. */
675 SF_SET_PROCESS (def_symbol_in_progress);
676 clear_function ();
677 break;
678 #ifdef TE_PE
679 case 'e':
680 /* .ef */
681 /* The MS compilers output the actual endline, not the
682 function-relative one... we want to match without
683 changing the assembler input. */
684 SA_SET_SYM_LNNO (def_symbol_in_progress,
685 (SA_GET_SYM_LNNO (def_symbol_in_progress)
686 + coff_line_base));
687 break;
688 #endif
692 break;
694 #ifdef C_AUTOARG
695 case C_AUTOARG:
696 #endif /* C_AUTOARG */
697 case C_AUTO:
698 case C_REG:
699 case C_ARG:
700 case C_REGPARM:
701 case C_FIELD:
703 /* According to the COFF documentation:
705 http://osr5doc.sco.com:1996/topics/COFF_SectNumFld.html
707 A special section number (-2) marks symbolic debugging symbols,
708 including structure/union/enumeration tag names, typedefs, and
709 the name of the file. A section number of -1 indicates that the
710 symbol has a value but is not relocatable. Examples of
711 absolute-valued symbols include automatic and register variables,
712 function arguments, and .eos symbols.
714 But from Ian Lance Taylor:
716 http://sources.redhat.com/ml/binutils/2000-08/msg00202.html
718 the actual tools all marked them as section -1. So the GNU COFF
719 assembler follows historical COFF assemblers.
721 However, it causes problems for djgpp
723 http://sources.redhat.com/ml/binutils/2000-08/msg00210.html
725 By defining STRICTCOFF, a COFF port can make the assembler to
726 follow the documented behavior. */
727 #ifdef STRICTCOFF
728 case C_MOS:
729 case C_MOE:
730 case C_MOU:
731 case C_EOS:
732 #endif
733 SF_SET_DEBUG (def_symbol_in_progress);
734 S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
735 break;
737 #ifndef STRICTCOFF
738 case C_MOS:
739 case C_MOE:
740 case C_MOU:
741 case C_EOS:
742 S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
743 break;
744 #endif
746 case C_EXT:
747 case C_WEAKEXT:
748 #ifdef TE_PE
749 case C_NT_WEAK:
750 #endif
751 case C_STAT:
752 case C_LABEL:
753 /* Valid but set somewhere else (s_comm, s_lcomm, colon). */
754 break;
756 default:
757 case C_USTATIC:
758 case C_EXTDEF:
759 case C_ULABEL:
760 as_warn (_("unexpected storage class %d"),
761 S_GET_STORAGE_CLASS (def_symbol_in_progress));
762 break;
765 /* Now that we have built a debug symbol, try to find if we should
766 merge with an existing symbol or not. If a symbol is C_EFCN or
767 absolute_section or untagged SEG_DEBUG it never merges. We also
768 don't merge labels, which are in a different namespace, nor
769 symbols which have not yet been defined since they are typically
770 unique, nor do we merge tags with non-tags. */
772 /* Two cases for functions. Either debug followed by definition or
773 definition followed by debug. For definition first, we will
774 merge the debug symbol into the definition. For debug first, the
775 lineno entry MUST point to the definition function or else it
776 will point off into space when obj_crawl_symbol_chain() merges
777 the debug symbol into the real symbol. Therefor, let's presume
778 the debug symbol is a real function reference. */
780 /* FIXME-SOON If for some reason the definition label/symbol is
781 never seen, this will probably leave an undefined symbol at link
782 time. */
784 if (S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_EFCN
785 || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_LABEL
786 || (streq (bfd_get_section_name (stdoutput,
787 S_GET_SEGMENT (def_symbol_in_progress)),
788 "*DEBUG*")
789 && !SF_GET_TAG (def_symbol_in_progress))
790 || S_GET_SEGMENT (def_symbol_in_progress) == absolute_section
791 || ! symbol_constant_p (def_symbol_in_progress)
792 || (symbolP = symbol_find (S_GET_NAME (def_symbol_in_progress))) == NULL
793 || SF_GET_TAG (def_symbol_in_progress) != SF_GET_TAG (symbolP))
795 /* If it already is at the end of the symbol list, do nothing */
796 if (def_symbol_in_progress != symbol_lastP)
798 symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
799 symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP,
800 &symbol_lastP);
803 else
805 /* This symbol already exists, merge the newly created symbol
806 into the old one. This is not mandatory. The linker can
807 handle duplicate symbols correctly. But I guess that it save
808 a *lot* of space if the assembly file defines a lot of
809 symbols. [loic] */
811 /* The debug entry (def_symbol_in_progress) is merged into the
812 previous definition. */
814 c_symbol_merge (def_symbol_in_progress, symbolP);
815 symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
817 def_symbol_in_progress = symbolP;
819 if (SF_GET_FUNCTION (def_symbol_in_progress)
820 || SF_GET_TAG (def_symbol_in_progress)
821 || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_STAT)
823 /* For functions, and tags, and static symbols, the symbol
824 *must* be where the debug symbol appears. Move the
825 existing symbol to the current place. */
826 /* If it already is at the end of the symbol list, do nothing. */
827 if (def_symbol_in_progress != symbol_lastP)
829 symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
830 symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
835 if (SF_GET_TAG (def_symbol_in_progress))
837 symbolS *oldtag;
839 oldtag = symbol_find (S_GET_NAME (def_symbol_in_progress));
840 if (oldtag == NULL || ! SF_GET_TAG (oldtag))
841 tag_insert (S_GET_NAME (def_symbol_in_progress),
842 def_symbol_in_progress);
845 if (SF_GET_FUNCTION (def_symbol_in_progress))
847 set_function (def_symbol_in_progress);
848 SF_SET_PROCESS (def_symbol_in_progress);
850 if (symbolP == NULL)
851 /* That is, if this is the first time we've seen the
852 function. */
853 symbol_table_insert (def_symbol_in_progress);
857 def_symbol_in_progress = NULL;
858 demand_empty_rest_of_line ();
861 static void
862 obj_coff_dim (int ignore ATTRIBUTE_UNUSED)
864 int dim_index;
866 if (def_symbol_in_progress == NULL)
868 as_warn (_(".dim pseudo-op used outside of .def/.endef: ignored."));
869 demand_empty_rest_of_line ();
870 return;
873 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
875 for (dim_index = 0; dim_index < DIMNUM; dim_index++)
877 SKIP_WHITESPACES ();
878 SA_SET_SYM_DIMEN (def_symbol_in_progress, dim_index,
879 get_absolute_expression ());
881 switch (*input_line_pointer)
883 case ',':
884 input_line_pointer++;
885 break;
887 default:
888 as_warn (_("badly formed .dim directive ignored"));
889 /* Fall through. */
890 case '\n':
891 case ';':
892 dim_index = DIMNUM;
893 break;
897 demand_empty_rest_of_line ();
900 static void
901 obj_coff_line (int ignore ATTRIBUTE_UNUSED)
903 int this_base;
905 if (def_symbol_in_progress == NULL)
907 /* Probably stabs-style line? */
908 obj_coff_ln (0);
909 return;
912 this_base = get_absolute_expression ();
913 if (streq (".bf", S_GET_NAME (def_symbol_in_progress)))
914 coff_line_base = this_base;
916 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
917 SA_SET_SYM_LNNO (def_symbol_in_progress, this_base);
919 demand_empty_rest_of_line ();
921 #ifndef NO_LISTING
922 if (streq (".bf", S_GET_NAME (def_symbol_in_progress)))
924 extern int listing;
926 if (listing)
927 listing_source_line ((unsigned int) this_base);
929 #endif
932 static void
933 obj_coff_size (int ignore ATTRIBUTE_UNUSED)
935 if (def_symbol_in_progress == NULL)
937 as_warn (_(".size pseudo-op used outside of .def/.endef ignored."));
938 demand_empty_rest_of_line ();
939 return;
942 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
943 SA_SET_SYM_SIZE (def_symbol_in_progress, get_absolute_expression ());
944 demand_empty_rest_of_line ();
947 static void
948 obj_coff_scl (int ignore ATTRIBUTE_UNUSED)
950 if (def_symbol_in_progress == NULL)
952 as_warn (_(".scl pseudo-op used outside of .def/.endef ignored."));
953 demand_empty_rest_of_line ();
954 return;
957 S_SET_STORAGE_CLASS (def_symbol_in_progress, get_absolute_expression ());
958 demand_empty_rest_of_line ();
961 static void
962 obj_coff_tag (int ignore ATTRIBUTE_UNUSED)
964 char *symbol_name;
965 char name_end;
967 if (def_symbol_in_progress == NULL)
969 as_warn (_(".tag pseudo-op used outside of .def/.endef ignored."));
970 demand_empty_rest_of_line ();
971 return;
974 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
975 symbol_name = input_line_pointer;
976 name_end = get_symbol_end ();
978 #ifdef tc_canonicalize_symbol_name
979 symbol_name = tc_canonicalize_symbol_name (symbol_name);
980 #endif
982 /* Assume that the symbol referred to by .tag is always defined.
983 This was a bad assumption. I've added find_or_make. xoxorich. */
984 SA_SET_SYM_TAGNDX (def_symbol_in_progress,
985 tag_find_or_make (symbol_name));
986 if (SA_GET_SYM_TAGNDX (def_symbol_in_progress) == 0L)
987 as_warn (_("tag not found for .tag %s"), symbol_name);
989 SF_SET_TAGGED (def_symbol_in_progress);
990 *input_line_pointer = name_end;
992 demand_empty_rest_of_line ();
995 static void
996 obj_coff_type (int ignore ATTRIBUTE_UNUSED)
998 if (def_symbol_in_progress == NULL)
1000 as_warn (_(".type pseudo-op used outside of .def/.endef ignored."));
1001 demand_empty_rest_of_line ();
1002 return;
1005 S_SET_DATA_TYPE (def_symbol_in_progress, get_absolute_expression ());
1007 if (ISFCN (S_GET_DATA_TYPE (def_symbol_in_progress)) &&
1008 S_GET_STORAGE_CLASS (def_symbol_in_progress) != C_TPDEF)
1009 SF_SET_FUNCTION (def_symbol_in_progress);
1011 demand_empty_rest_of_line ();
1014 static void
1015 obj_coff_val (int ignore ATTRIBUTE_UNUSED)
1017 if (def_symbol_in_progress == NULL)
1019 as_warn (_(".val pseudo-op used outside of .def/.endef ignored."));
1020 demand_empty_rest_of_line ();
1021 return;
1024 if (is_name_beginner (*input_line_pointer))
1026 char *symbol_name = input_line_pointer;
1027 char name_end = get_symbol_end ();
1029 #ifdef tc_canonicalize_symbol_name
1030 symbol_name = tc_canonicalize_symbol_name (symbol_name);
1031 #endif
1032 if (streq (symbol_name, "."))
1034 /* If the .val is != from the .def (e.g. statics). */
1035 symbol_set_frag (def_symbol_in_progress, frag_now);
1036 S_SET_VALUE (def_symbol_in_progress, (valueT) frag_now_fix ());
1038 else if (! streq (S_GET_NAME (def_symbol_in_progress), symbol_name))
1040 expressionS exp;
1042 exp.X_op = O_symbol;
1043 exp.X_add_symbol = symbol_find_or_make (symbol_name);
1044 exp.X_op_symbol = NULL;
1045 exp.X_add_number = 0;
1046 symbol_set_value_expression (def_symbol_in_progress, &exp);
1048 /* If the segment is undefined when the forward reference is
1049 resolved, then copy the segment id from the forward
1050 symbol. */
1051 SF_SET_GET_SEGMENT (def_symbol_in_progress);
1053 /* FIXME: gcc can generate address expressions here in
1054 unusual cases (search for "obscure" in sdbout.c). We
1055 just ignore the offset here, thus generating incorrect
1056 debugging information. We ignore the rest of the line
1057 just below. */
1059 /* Otherwise, it is the name of a non debug symbol and its value
1060 will be calculated later. */
1061 *input_line_pointer = name_end;
1063 else
1065 S_SET_VALUE (def_symbol_in_progress, get_absolute_expression ());
1068 demand_empty_rest_of_line ();
1071 #ifdef TE_PE
1073 /* Return nonzero if name begins with weak alternate symbol prefix. */
1075 static int
1076 weak_is_altname (const char * name)
1078 return strneq (name, weak_altprefix, sizeof (weak_altprefix) - 1);
1081 /* Return the name of the alternate symbol
1082 name corresponding to a weak symbol's name. */
1084 static const char *
1085 weak_name2altname (const char * name)
1087 char *alt_name;
1089 alt_name = xmalloc (sizeof (weak_altprefix) + strlen (name));
1090 strcpy (alt_name, weak_altprefix);
1091 return strcat (alt_name, name);
1094 /* Return the name of the weak symbol corresponding to an
1095 alternate symbol. */
1097 static const char *
1098 weak_altname2name (const char * name)
1100 char * weak_name;
1101 char * dot;
1103 gas_assert (weak_is_altname (name));
1105 weak_name = xstrdup (name + 6);
1106 if ((dot = strchr (weak_name, '.')))
1107 *dot = 0;
1108 return weak_name;
1111 /* Make a weak symbol name unique by
1112 appending the name of an external symbol. */
1114 static const char *
1115 weak_uniquify (const char * name)
1117 char *ret;
1118 const char * unique = "";
1120 #ifdef TE_PE
1121 if (an_external_name != NULL)
1122 unique = an_external_name;
1123 #endif
1124 gas_assert (weak_is_altname (name));
1126 if (strchr (name + sizeof (weak_altprefix), '.'))
1127 return name;
1129 ret = xmalloc (strlen (name) + strlen (unique) + 2);
1130 strcpy (ret, name);
1131 strcat (ret, ".");
1132 strcat (ret, unique);
1133 return ret;
1136 void
1137 pecoff_obj_set_weak_hook (symbolS *symbolP)
1139 symbolS *alternateP;
1141 /* See _Microsoft Portable Executable and Common Object
1142 File Format Specification_, section 5.5.3.
1143 Create a symbol representing the alternate value.
1144 coff_frob_symbol will set the value of this symbol from
1145 the value of the weak symbol itself. */
1146 S_SET_STORAGE_CLASS (symbolP, C_NT_WEAK);
1147 S_SET_NUMBER_AUXILIARY (symbolP, 1);
1148 SA_SET_SYM_FSIZE (symbolP, IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY);
1150 alternateP = symbol_find_or_make (weak_name2altname (S_GET_NAME (symbolP)));
1151 S_SET_EXTERNAL (alternateP);
1152 S_SET_STORAGE_CLASS (alternateP, C_NT_WEAK);
1154 SA_SET_SYM_TAGNDX (symbolP, alternateP);
1157 void
1158 pecoff_obj_clear_weak_hook (symbolS *symbolP)
1160 symbolS *alternateP;
1162 S_SET_STORAGE_CLASS (symbolP, 0);
1163 SA_SET_SYM_FSIZE (symbolP, 0);
1165 alternateP = symbol_find (weak_name2altname (S_GET_NAME (symbolP)));
1166 S_CLEAR_EXTERNAL (alternateP);
1169 #endif /* TE_PE */
1171 /* Handle .weak. This is a GNU extension in formats other than PE. */
1173 static void
1174 obj_coff_weak (int ignore ATTRIBUTE_UNUSED)
1176 char *name;
1177 int c;
1178 symbolS *symbolP;
1182 name = input_line_pointer;
1183 c = get_symbol_end ();
1184 if (*name == 0)
1186 as_warn (_("badly formed .weak directive ignored"));
1187 ignore_rest_of_line ();
1188 return;
1190 c = 0;
1191 symbolP = symbol_find_or_make (name);
1192 *input_line_pointer = c;
1193 SKIP_WHITESPACE ();
1194 S_SET_WEAK (symbolP);
1196 if (c == ',')
1198 input_line_pointer++;
1199 SKIP_WHITESPACE ();
1200 if (*input_line_pointer == '\n')
1201 c = '\n';
1205 while (c == ',');
1207 demand_empty_rest_of_line ();
1210 void
1211 coff_obj_read_begin_hook (void)
1213 /* These had better be the same. Usually 18 bytes. */
1214 know (sizeof (SYMENT) == sizeof (AUXENT));
1215 know (SYMESZ == AUXESZ);
1216 tag_init ();
1219 symbolS *coff_last_function;
1220 #ifndef OBJ_XCOFF
1221 static symbolS *coff_last_bf;
1222 #endif
1224 void
1225 coff_frob_symbol (symbolS *symp, int *punt)
1227 static symbolS *last_tagP;
1228 static stack *block_stack;
1229 static symbolS *set_end;
1230 symbolS *next_set_end = NULL;
1232 if (symp == &abs_symbol)
1234 *punt = 1;
1235 return;
1238 if (current_lineno_sym)
1239 coff_add_linesym (NULL);
1241 if (!block_stack)
1242 block_stack = stack_init (512, sizeof (symbolS*));
1244 #ifdef TE_PE
1245 if (S_GET_STORAGE_CLASS (symp) == C_NT_WEAK
1246 && ! S_IS_WEAK (symp)
1247 && weak_is_altname (S_GET_NAME (symp)))
1249 /* This is a weak alternate symbol. All processing of
1250 PECOFFweak symbols is done here, through the alternate. */
1251 symbolS *weakp = symbol_find_noref (weak_altname2name
1252 (S_GET_NAME (symp)), 1);
1254 gas_assert (weakp);
1255 gas_assert (S_GET_NUMBER_AUXILIARY (weakp) == 1);
1257 if (! S_IS_WEAK (weakp))
1259 /* The symbol was turned from weak to strong. Discard altname. */
1260 *punt = 1;
1261 return;
1263 else if (symbol_equated_p (weakp))
1265 /* The weak symbol has an alternate specified; symp is unneeded. */
1266 S_SET_STORAGE_CLASS (weakp, C_NT_WEAK);
1267 SA_SET_SYM_TAGNDX (weakp,
1268 symbol_get_value_expression (weakp)->X_add_symbol);
1270 S_CLEAR_EXTERNAL (symp);
1271 *punt = 1;
1272 return;
1274 else
1276 /* The weak symbol has been assigned an alternate value.
1277 Copy this value to symp, and set symp as weakp's alternate. */
1278 if (S_GET_STORAGE_CLASS (weakp) != C_NT_WEAK)
1280 S_SET_STORAGE_CLASS (symp, S_GET_STORAGE_CLASS (weakp));
1281 S_SET_STORAGE_CLASS (weakp, C_NT_WEAK);
1284 if (S_IS_DEFINED (weakp))
1286 /* This is a defined weak symbol. Copy value information
1287 from the weak symbol itself to the alternate symbol. */
1288 symbol_set_value_expression (symp,
1289 symbol_get_value_expression (weakp));
1290 symbol_set_frag (symp, symbol_get_frag (weakp));
1291 S_SET_SEGMENT (symp, S_GET_SEGMENT (weakp));
1293 else
1295 /* This is an undefined weak symbol.
1296 Define the alternate symbol to zero. */
1297 S_SET_VALUE (symp, 0);
1298 S_SET_SEGMENT (symp, absolute_section);
1301 S_SET_NAME (symp, weak_uniquify (S_GET_NAME (symp)));
1302 S_SET_STORAGE_CLASS (symp, C_EXT);
1304 S_SET_VALUE (weakp, 0);
1305 S_SET_SEGMENT (weakp, undefined_section);
1308 #else /* TE_PE */
1309 if (S_IS_WEAK (symp))
1310 S_SET_STORAGE_CLASS (symp, C_WEAKEXT);
1311 #endif /* TE_PE */
1313 if (!S_IS_DEFINED (symp)
1314 && !S_IS_WEAK (symp)
1315 && S_GET_STORAGE_CLASS (symp) != C_STAT)
1316 S_SET_STORAGE_CLASS (symp, C_EXT);
1318 if (!SF_GET_DEBUG (symp))
1320 symbolS * real;
1322 if (!SF_GET_LOCAL (symp)
1323 && !SF_GET_STATICS (symp)
1324 && S_GET_STORAGE_CLASS (symp) != C_LABEL
1325 && symbol_constant_p (symp)
1326 && (real = symbol_find_noref (S_GET_NAME (symp), 1))
1327 && S_GET_STORAGE_CLASS (real) == C_NULL
1328 && real != symp)
1330 c_symbol_merge (symp, real);
1331 *punt = 1;
1332 return;
1335 if (!S_IS_DEFINED (symp) && !SF_GET_LOCAL (symp))
1337 gas_assert (S_GET_VALUE (symp) == 0);
1338 if (S_IS_WEAKREFD (symp))
1339 *punt = 1;
1340 else
1341 S_SET_EXTERNAL (symp);
1343 else if (S_GET_STORAGE_CLASS (symp) == C_NULL)
1345 if (S_GET_SEGMENT (symp) == text_section
1346 && symp != seg_info (text_section)->sym)
1347 S_SET_STORAGE_CLASS (symp, C_LABEL);
1348 else
1349 S_SET_STORAGE_CLASS (symp, C_STAT);
1352 if (SF_GET_PROCESS (symp))
1354 if (S_GET_STORAGE_CLASS (symp) == C_BLOCK)
1356 if (streq (S_GET_NAME (symp), ".bb"))
1357 stack_push (block_stack, (char *) &symp);
1358 else
1360 symbolS *begin;
1362 begin = *(symbolS **) stack_pop (block_stack);
1363 if (begin == 0)
1364 as_warn (_("mismatched .eb"));
1365 else
1366 next_set_end = begin;
1370 if (coff_last_function == 0 && SF_GET_FUNCTION (symp))
1372 union internal_auxent *auxp;
1374 coff_last_function = symp;
1375 if (S_GET_NUMBER_AUXILIARY (symp) < 1)
1376 S_SET_NUMBER_AUXILIARY (symp, 1);
1377 auxp = SYM_AUXENT (symp);
1378 memset (auxp->x_sym.x_fcnary.x_ary.x_dimen, 0,
1379 sizeof (auxp->x_sym.x_fcnary.x_ary.x_dimen));
1382 if (S_GET_STORAGE_CLASS (symp) == C_EFCN)
1384 if (coff_last_function == 0)
1385 as_fatal (_("C_EFCN symbol for %s out of scope"),
1386 S_GET_NAME (symp));
1387 SA_SET_SYM_FSIZE (coff_last_function,
1388 (long) (S_GET_VALUE (symp)
1389 - S_GET_VALUE (coff_last_function)));
1390 next_set_end = coff_last_function;
1391 coff_last_function = 0;
1395 if (S_IS_EXTERNAL (symp))
1396 S_SET_STORAGE_CLASS (symp, C_EXT);
1397 else if (SF_GET_LOCAL (symp))
1398 *punt = 1;
1400 if (SF_GET_FUNCTION (symp))
1401 symbol_get_bfdsym (symp)->flags |= BSF_FUNCTION;
1404 /* Double check weak symbols. */
1405 if (S_IS_WEAK (symp) && S_IS_COMMON (symp))
1406 as_bad (_("Symbol `%s' can not be both weak and common"),
1407 S_GET_NAME (symp));
1409 if (SF_GET_TAG (symp))
1410 last_tagP = symp;
1411 else if (S_GET_STORAGE_CLASS (symp) == C_EOS)
1412 next_set_end = last_tagP;
1414 #ifdef OBJ_XCOFF
1415 /* This is pretty horrible, but we have to set *punt correctly in
1416 order to call SA_SET_SYM_ENDNDX correctly. */
1417 if (! symbol_used_in_reloc_p (symp)
1418 && ((symbol_get_bfdsym (symp)->flags & BSF_SECTION_SYM) != 0
1419 || (! (S_IS_EXTERNAL (symp) || S_IS_WEAK (symp))
1420 && ! symbol_get_tc (symp)->output
1421 && S_GET_STORAGE_CLASS (symp) != C_FILE)))
1422 *punt = 1;
1423 #endif
1425 if (set_end != (symbolS *) NULL
1426 && ! *punt
1427 && ((symbol_get_bfdsym (symp)->flags & BSF_NOT_AT_END) != 0
1428 || (S_IS_DEFINED (symp)
1429 && ! S_IS_COMMON (symp)
1430 && (! S_IS_EXTERNAL (symp) || SF_GET_FUNCTION (symp)))))
1432 SA_SET_SYM_ENDNDX (set_end, symp);
1433 set_end = NULL;
1436 if (next_set_end != NULL)
1438 if (set_end != NULL)
1439 as_warn (_("Warning: internal error: forgetting to set endndx of %s"),
1440 S_GET_NAME (set_end));
1441 set_end = next_set_end;
1444 #ifndef OBJ_XCOFF
1445 if (! *punt
1446 && S_GET_STORAGE_CLASS (symp) == C_FCN
1447 && streq (S_GET_NAME (symp), ".bf"))
1449 if (coff_last_bf != NULL)
1450 SA_SET_SYM_ENDNDX (coff_last_bf, symp);
1451 coff_last_bf = symp;
1453 #endif
1454 if (coffsymbol (symbol_get_bfdsym (symp))->lineno)
1456 int i;
1457 struct line_no *lptr;
1458 alent *l;
1460 lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno;
1461 for (i = 0; lptr; lptr = lptr->next)
1462 i++;
1463 lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno;
1465 /* We need i entries for line numbers, plus 1 for the first
1466 entry which BFD will override, plus 1 for the last zero
1467 entry (a marker for BFD). */
1468 l = xmalloc ((i + 2) * sizeof (* l));
1469 coffsymbol (symbol_get_bfdsym (symp))->lineno = l;
1470 l[i + 1].line_number = 0;
1471 l[i + 1].u.sym = NULL;
1472 for (; i > 0; i--)
1474 if (lptr->frag)
1475 lptr->l.u.offset += lptr->frag->fr_address / OCTETS_PER_BYTE;
1476 l[i] = lptr->l;
1477 lptr = lptr->next;
1482 void
1483 coff_adjust_section_syms (bfd *abfd ATTRIBUTE_UNUSED,
1484 asection *sec,
1485 void * x ATTRIBUTE_UNUSED)
1487 symbolS *secsym;
1488 segment_info_type *seginfo = seg_info (sec);
1489 int nlnno, nrelocs = 0;
1491 /* RS/6000 gas creates a .debug section manually in ppc_frob_file in
1492 tc-ppc.c. Do not get confused by it. */
1493 if (seginfo == NULL)
1494 return;
1496 if (streq (sec->name, ".text"))
1497 nlnno = coff_n_line_nos;
1498 else
1499 nlnno = 0;
1501 /* @@ Hope that none of the fixups expand to more than one reloc
1502 entry... */
1503 fixS *fixp = seginfo->fix_root;
1504 while (fixp)
1506 if (! fixp->fx_done)
1507 nrelocs++;
1508 fixp = fixp->fx_next;
1511 if (bfd_get_section_size (sec) == 0
1512 && nrelocs == 0
1513 && nlnno == 0
1514 && sec != text_section
1515 && sec != data_section
1516 && sec != bss_section)
1517 return;
1519 secsym = section_symbol (sec);
1520 /* This is an estimate; we'll plug in the real value using
1521 SET_SECTION_RELOCS later */
1522 SA_SET_SCN_NRELOC (secsym, nrelocs);
1523 SA_SET_SCN_NLINNO (secsym, nlnno);
1526 void
1527 coff_frob_file_after_relocs (void)
1529 bfd_map_over_sections (stdoutput, coff_adjust_section_syms, NULL);
1532 /* Implement the .section pseudo op:
1533 .section name {, "flags"}
1535 | +--- optional flags: 'b' for bss
1536 | 'i' for info
1537 +-- section name 'l' for lib
1538 'n' for noload
1539 'o' for over
1540 'w' for data
1541 'd' (apparently m88k for data)
1542 'x' for text
1543 'r' for read-only data
1544 's' for shared data (PE)
1545 'y' for noread
1546 But if the argument is not a quoted string, treat it as a
1547 subsegment number.
1549 Note the 'a' flag is silently ignored. This allows the same
1550 .section directive to be parsed in both ELF and COFF formats. */
1552 void
1553 obj_coff_section (int ignore ATTRIBUTE_UNUSED)
1555 /* Strip out the section name. */
1556 char *section_name;
1557 char c;
1558 char *name;
1559 unsigned int exp;
1560 flagword flags, oldflags;
1561 asection *sec;
1563 if (flag_mri)
1565 char type;
1567 s_mri_sect (&type);
1568 return;
1571 section_name = input_line_pointer;
1572 c = get_symbol_end ();
1574 name = xmalloc (input_line_pointer - section_name + 1);
1575 strcpy (name, section_name);
1577 *input_line_pointer = c;
1579 SKIP_WHITESPACE ();
1581 exp = 0;
1582 flags = SEC_NO_FLAGS;
1584 if (*input_line_pointer == ',')
1586 ++input_line_pointer;
1587 SKIP_WHITESPACE ();
1588 if (*input_line_pointer != '"')
1589 exp = get_absolute_expression ();
1590 else
1592 unsigned char attr;
1593 int readonly_removed = 0;
1594 int load_removed = 0;
1596 while (attr = *++input_line_pointer,
1597 attr != '"'
1598 && ! is_end_of_line[attr])
1600 switch (attr)
1602 case 'b':
1603 /* Uninitialised data section. */
1604 flags |= SEC_ALLOC;
1605 flags &=~ SEC_LOAD;
1606 break;
1608 case 'n':
1609 /* Section not loaded. */
1610 flags &=~ SEC_LOAD;
1611 flags |= SEC_NEVER_LOAD;
1612 load_removed = 1;
1613 break;
1615 case 's':
1616 /* Shared section. */
1617 flags |= SEC_COFF_SHARED;
1618 /* Fall through. */
1619 case 'd':
1620 /* Data section. */
1621 flags |= SEC_DATA;
1622 if (! load_removed)
1623 flags |= SEC_LOAD;
1624 flags &=~ SEC_READONLY;
1625 break;
1627 case 'w':
1628 /* Writable section. */
1629 flags &=~ SEC_READONLY;
1630 readonly_removed = 1;
1631 break;
1633 case 'a':
1634 /* Ignore. Here for compatibility with ELF. */
1635 break;
1637 case 'r': /* Read-only section. Implies a data section. */
1638 readonly_removed = 0;
1639 /* Fall through. */
1640 case 'x': /* Executable section. */
1641 /* If we are setting the 'x' attribute or if the 'r'
1642 attribute is being used to restore the readonly status
1643 of a code section (eg "wxr") then set the SEC_CODE flag,
1644 otherwise set the SEC_DATA flag. */
1645 flags |= (attr == 'x' || (flags & SEC_CODE) ? SEC_CODE : SEC_DATA);
1646 if (! load_removed)
1647 flags |= SEC_LOAD;
1648 /* Note - the READONLY flag is set here, even for the 'x'
1649 attribute in order to be compatible with the MSVC
1650 linker. */
1651 if (! readonly_removed)
1652 flags |= SEC_READONLY;
1653 break;
1655 case 'y':
1656 flags |= SEC_COFF_NOREAD | SEC_READONLY;
1657 break;
1659 case 'i': /* STYP_INFO */
1660 case 'l': /* STYP_LIB */
1661 case 'o': /* STYP_OVER */
1662 as_warn (_("unsupported section attribute '%c'"), attr);
1663 break;
1665 default:
1666 as_warn (_("unknown section attribute '%c'"), attr);
1667 break;
1670 if (attr == '"')
1671 ++input_line_pointer;
1675 sec = subseg_new (name, (subsegT) exp);
1677 oldflags = bfd_get_section_flags (stdoutput, sec);
1678 if (oldflags == SEC_NO_FLAGS)
1680 /* Set section flags for a new section just created by subseg_new.
1681 Provide a default if no flags were parsed. */
1682 if (flags == SEC_NO_FLAGS)
1683 flags = TC_COFF_SECTION_DEFAULT_ATTRIBUTES;
1685 #ifdef COFF_LONG_SECTION_NAMES
1686 /* Add SEC_LINK_ONCE and SEC_LINK_DUPLICATES_DISCARD to .gnu.linkonce
1687 sections so adjust_reloc_syms in write.c will correctly handle
1688 relocs which refer to non-local symbols in these sections. */
1689 if (strneq (name, ".gnu.linkonce", sizeof (".gnu.linkonce") - 1))
1690 flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
1691 #endif
1693 if (! bfd_set_section_flags (stdoutput, sec, flags))
1694 as_warn (_("error setting flags for \"%s\": %s"),
1695 bfd_section_name (stdoutput, sec),
1696 bfd_errmsg (bfd_get_error ()));
1698 else if (flags != SEC_NO_FLAGS)
1700 /* This section's attributes have already been set. Warn if the
1701 attributes don't match. */
1702 flagword matchflags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
1703 | SEC_DATA | SEC_COFF_SHARED | SEC_NEVER_LOAD
1704 | SEC_COFF_NOREAD);
1705 if ((flags ^ oldflags) & matchflags)
1706 as_warn (_("Ignoring changed section attributes for %s"), name);
1709 demand_empty_rest_of_line ();
1712 void
1713 coff_adjust_symtab (void)
1715 if (symbol_rootP == NULL
1716 || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
1717 c_dot_file_symbol ("fake", 0);
1720 void
1721 coff_frob_section (segT sec)
1723 segT strsec;
1724 char *p;
1725 fragS *fragp;
1726 bfd_vma size, n_entries, mask;
1727 bfd_vma align_power = (bfd_vma)sec->alignment_power + OCTETS_PER_BYTE_POWER;
1729 /* The COFF back end in BFD requires that all section sizes be
1730 rounded up to multiples of the corresponding section alignments,
1731 supposedly because standard COFF has no other way of encoding alignment
1732 for sections. If your COFF flavor has a different way of encoding
1733 section alignment, then skip this step, as TICOFF does. */
1734 size = bfd_get_section_size (sec);
1735 mask = ((bfd_vma) 1 << align_power) - 1;
1736 #if !defined(TICOFF)
1737 if (size & mask)
1739 bfd_vma new_size;
1740 fragS *last;
1742 new_size = (size + mask) & ~mask;
1743 bfd_set_section_size (stdoutput, sec, new_size);
1745 /* If the size had to be rounded up, add some padding in
1746 the last non-empty frag. */
1747 fragp = seg_info (sec)->frchainP->frch_root;
1748 last = seg_info (sec)->frchainP->frch_last;
1749 while (fragp->fr_next != last)
1750 fragp = fragp->fr_next;
1751 last->fr_address = size;
1752 fragp->fr_offset += new_size - size;
1754 #endif
1756 /* If the section size is non-zero, the section symbol needs an aux
1757 entry associated with it, indicating the size. We don't know
1758 all the values yet; coff_frob_symbol will fill them in later. */
1759 #ifndef TICOFF
1760 if (size != 0
1761 || sec == text_section
1762 || sec == data_section
1763 || sec == bss_section)
1764 #endif
1766 symbolS *secsym = section_symbol (sec);
1768 S_SET_STORAGE_CLASS (secsym, C_STAT);
1769 S_SET_NUMBER_AUXILIARY (secsym, 1);
1770 SF_SET_STATICS (secsym);
1771 SA_SET_SCN_SCNLEN (secsym, size);
1773 /* FIXME: These should be in a "stabs.h" file, or maybe as.h. */
1774 #ifndef STAB_SECTION_NAME
1775 #define STAB_SECTION_NAME ".stab"
1776 #endif
1777 #ifndef STAB_STRING_SECTION_NAME
1778 #define STAB_STRING_SECTION_NAME ".stabstr"
1779 #endif
1780 if (! streq (STAB_STRING_SECTION_NAME, sec->name))
1781 return;
1783 strsec = sec;
1784 sec = subseg_get (STAB_SECTION_NAME, 0);
1785 /* size is already rounded up, since other section will be listed first */
1786 size = bfd_get_section_size (strsec);
1788 n_entries = bfd_get_section_size (sec) / 12 - 1;
1790 /* Find first non-empty frag. It should be large enough. */
1791 fragp = seg_info (sec)->frchainP->frch_root;
1792 while (fragp && fragp->fr_fix == 0)
1793 fragp = fragp->fr_next;
1794 gas_assert (fragp != 0 && fragp->fr_fix >= 12);
1796 /* Store the values. */
1797 p = fragp->fr_literal;
1798 bfd_h_put_16 (stdoutput, n_entries, (bfd_byte *) p + 6);
1799 bfd_h_put_32 (stdoutput, size, (bfd_byte *) p + 8);
1802 void
1803 obj_coff_init_stab_section (segT seg)
1805 char *file;
1806 char *p;
1807 char *stabstr_name;
1808 unsigned int stroff;
1810 /* Make space for this first symbol. */
1811 p = frag_more (12);
1812 /* Zero it out. */
1813 memset (p, 0, 12);
1814 as_where (&file, (unsigned int *) NULL);
1815 stabstr_name = xmalloc (strlen (seg->name) + 4);
1816 strcpy (stabstr_name, seg->name);
1817 strcat (stabstr_name, "str");
1818 stroff = get_stab_string_offset (file, stabstr_name);
1819 know (stroff == 1);
1820 md_number_to_chars (p, stroff, 4);
1823 #ifdef DEBUG
1824 const char *
1825 s_get_name (symbolS *s)
1827 return ((s == NULL) ? "(NULL)" : S_GET_NAME (s));
1830 void
1831 symbol_dump (void)
1833 symbolS *symbolP;
1835 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
1836 printf (_("0x%lx: \"%s\" type = %ld, class = %d, segment = %d\n"),
1837 (unsigned long) symbolP,
1838 S_GET_NAME (symbolP),
1839 (long) S_GET_DATA_TYPE (symbolP),
1840 S_GET_STORAGE_CLASS (symbolP),
1841 (int) S_GET_SEGMENT (symbolP));
1844 #endif /* DEBUG */
1846 const pseudo_typeS coff_pseudo_table[] =
1848 {"ABORT", s_abort, 0},
1849 {"appline", obj_coff_ln, 1},
1850 /* We accept the .bss directive for backward compatibility with
1851 earlier versions of gas. */
1852 {"bss", obj_coff_bss, 0},
1853 #ifdef TE_PE
1854 /* PE provides an enhanced version of .comm with alignment. */
1855 {"comm", obj_coff_comm, 0},
1856 #endif /* TE_PE */
1857 {"def", obj_coff_def, 0},
1858 {"dim", obj_coff_dim, 0},
1859 {"endef", obj_coff_endef, 0},
1860 {"ident", obj_coff_ident, 0},
1861 {"line", obj_coff_line, 0},
1862 {"ln", obj_coff_ln, 0},
1863 {"scl", obj_coff_scl, 0},
1864 {"sect", obj_coff_section, 0},
1865 {"sect.s", obj_coff_section, 0},
1866 {"section", obj_coff_section, 0},
1867 {"section.s", obj_coff_section, 0},
1868 /* FIXME: We ignore the MRI short attribute. */
1869 {"size", obj_coff_size, 0},
1870 {"tag", obj_coff_tag, 0},
1871 {"type", obj_coff_type, 0},
1872 {"val", obj_coff_val, 0},
1873 {"version", s_ignore, 0},
1874 {"loc", obj_coff_loc, 0},
1875 {"optim", s_ignore, 0}, /* For sun386i cc (?) */
1876 {"weak", obj_coff_weak, 0},
1877 #if defined TC_TIC4X
1878 /* The tic4x uses sdef instead of def. */
1879 {"sdef", obj_coff_def, 0},
1880 #endif
1881 #if defined(SEH_CMDS)
1882 SEH_CMDS
1883 #endif
1884 {NULL, NULL, 0}
1888 /* Support for a COFF emulation. */
1890 static void
1891 coff_pop_insert (void)
1893 pop_insert (coff_pseudo_table);
1896 static int
1897 coff_separate_stab_sections (void)
1899 return 1;
1902 const struct format_ops coff_format_ops =
1904 bfd_target_coff_flavour,
1905 0, /* dfl_leading_underscore */
1906 1, /* emit_section_symbols */
1907 0, /* begin */
1908 c_dot_file_symbol,
1909 coff_frob_symbol,
1910 0, /* frob_file */
1911 0, /* frob_file_before_adjust */
1912 0, /* frob_file_before_fix */
1913 coff_frob_file_after_relocs,
1914 0, /* s_get_size */
1915 0, /* s_set_size */
1916 0, /* s_get_align */
1917 0, /* s_set_align */
1918 0, /* s_get_other */
1919 0, /* s_set_other */
1920 0, /* s_get_desc */
1921 0, /* s_set_desc */
1922 0, /* s_get_type */
1923 0, /* s_set_type */
1924 0, /* copy_symbol_attributes */
1925 0, /* generate_asm_lineno */
1926 0, /* process_stab */
1927 coff_separate_stab_sections,
1928 obj_coff_init_stab_section,
1929 0, /* sec_sym_ok_for_reloc */
1930 coff_pop_insert,
1931 0, /* ecoff_set_ext */
1932 coff_obj_read_begin_hook,
1933 coff_obj_symbol_new_hook