1 /* coff object file format
2 Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007
4 Free Software Foundation, Inc.
6 This file is part of GAS.
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to the Free
20 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
23 #define OBJ_HEADER "obj-coff.h"
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
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)
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;
52 /* PE weak alternate symbols begin with this string. */
53 static const char weak_altprefix[] = ".weak.";
58 unsigned long chunk_size;
59 unsigned long element_size;
62 unsigned long pointer;
70 stack_init (unsigned long chunk_size,
71 unsigned long element_size)
75 st = malloc (sizeof (* st));
78 st->data = malloc (chunk_size);
85 st->size = chunk_size;
86 st->chunk_size = chunk_size;
87 st->element_size = element_size;
92 stack_push (stack *st, char *element)
94 if (st->pointer + st->element_size >= st->size)
96 st->size += st->chunk_size;
97 if ((st->data = xrealloc (st->data, st->size)) == NULL)
100 memcpy (st->data + st->pointer, element, st->element_size);
101 st->pointer += st->element_size;
102 return st->data + st->pointer;
106 stack_pop (stack *st)
108 if (st->pointer < st->element_size)
113 st->pointer -= st->element_size;
114 return st->data + st->pointer;
117 /* Maintain a list of the tagnames of the structures. */
119 static struct hash_control *tag_hash;
124 tag_hash = hash_new ();
128 tag_insert (const char *name, symbolS *symbolP)
130 const char *error_string;
132 if ((error_string = hash_jam (tag_hash, name, (char *) symbolP)))
133 as_fatal (_("Inserting \"%s\" into structure table failed: %s"),
138 tag_find (char *name)
140 return (symbolS *) hash_find (tag_hash, name);
144 tag_find_or_make (char *name)
148 if ((symbolP = tag_find (name)) == NULL)
150 symbolP = symbol_new (name, undefined_section,
151 0, &zero_address_frag);
153 tag_insert (S_GET_NAME (symbolP), symbolP);
154 symbol_table_insert (symbolP);
160 /* We accept the .bss directive to set the section for backward
161 compatibility with earlier versions of gas. */
164 obj_coff_bss (int ignore ATTRIBUTE_UNUSED)
166 if (*input_line_pointer == '\n')
167 subseg_new (".bss", get_absolute_expression ());
172 #define GET_FILENAME_STRING(X) \
173 ((char *) (&((X)->sy_symbol.ost_auxent->x_file.x_n.x_offset))[1])
177 fetch_coff_debug_section (void)
179 static segT debug_section;
185 s = bfd_make_debug_symbol (stdoutput, NULL, 0);
187 debug_section = s->section;
189 return debug_section;
193 SA_SET_SYM_ENDNDX (symbolS *sym, symbolS *val)
195 combined_entry_type *entry, *p;
197 entry = &coffsymbol (symbol_get_bfdsym (sym))->native[1];
198 p = coffsymbol (symbol_get_bfdsym (val))->native;
199 entry->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p = p;
204 SA_SET_SYM_TAGNDX (symbolS *sym, symbolS *val)
206 combined_entry_type *entry, *p;
208 entry = &coffsymbol (symbol_get_bfdsym (sym))->native[1];
209 p = coffsymbol (symbol_get_bfdsym (val))->native;
210 entry->u.auxent.x_sym.x_tagndx.p = p;
215 S_GET_DATA_TYPE (symbolS *sym)
217 return coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_type;
221 S_SET_DATA_TYPE (symbolS *sym, int val)
223 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_type = val;
228 S_GET_STORAGE_CLASS (symbolS *sym)
230 return coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_sclass;
234 S_SET_STORAGE_CLASS (symbolS *sym, int val)
236 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_sclass = val;
240 /* Merge a debug symbol containing debug information into a normal symbol. */
243 c_symbol_merge (symbolS *debug, symbolS *normal)
245 S_SET_DATA_TYPE (normal, S_GET_DATA_TYPE (debug));
246 S_SET_STORAGE_CLASS (normal, S_GET_STORAGE_CLASS (debug));
248 if (S_GET_NUMBER_AUXILIARY (debug) > S_GET_NUMBER_AUXILIARY (normal))
249 /* Take the most we have. */
250 S_SET_NUMBER_AUXILIARY (normal, S_GET_NUMBER_AUXILIARY (debug));
252 if (S_GET_NUMBER_AUXILIARY (debug) > 0)
253 /* Move all the auxiliary information. */
254 memcpy (SYM_AUXINFO (normal), SYM_AUXINFO (debug),
255 (S_GET_NUMBER_AUXILIARY (debug)
256 * sizeof (*SYM_AUXINFO (debug))));
258 /* Move the debug flags. */
259 SF_SET_DEBUG_FIELD (normal, SF_GET_DEBUG_FIELD (debug));
263 c_dot_file_symbol (const char *filename, int appfile ATTRIBUTE_UNUSED)
267 /* BFD converts filename to a .file symbol with an aux entry. It
268 also handles chaining. */
269 symbolP = symbol_new (filename, bfd_abs_section_ptr, 0, &zero_address_frag);
271 S_SET_STORAGE_CLASS (symbolP, C_FILE);
272 S_SET_NUMBER_AUXILIARY (symbolP, 1);
274 symbol_get_bfdsym (symbolP)->flags = BSF_DEBUGGING;
281 listing_source_file (filename);
285 /* Make sure that the symbol is first on the symbol chain. */
286 if (symbol_rootP != symbolP)
288 symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
289 symbol_insert (symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP);
293 /* Line number handling. */
297 struct line_no *next;
304 /* Symbol of last function, which we should hang line#s off of. */
305 static symbolS *line_fsym;
307 #define in_function() (line_fsym != 0)
308 #define clear_function() (line_fsym = 0)
309 #define set_function(F) (line_fsym = (F), coff_add_linesym (F))
313 coff_obj_symbol_new_hook (symbolS *symbolP)
315 long sz = (OBJ_COFF_MAX_AUXENTRIES + 1) * sizeof (combined_entry_type);
316 char * s = xmalloc (sz);
319 coffsymbol (symbol_get_bfdsym (symbolP))->native = (combined_entry_type *) s;
321 S_SET_DATA_TYPE (symbolP, T_NULL);
322 S_SET_STORAGE_CLASS (symbolP, 0);
323 S_SET_NUMBER_AUXILIARY (symbolP, 0);
325 if (S_IS_STRING (symbolP))
326 SF_SET_STRING (symbolP);
328 if (S_IS_LOCAL (symbolP))
329 SF_SET_LOCAL (symbolP);
333 coff_obj_symbol_clone_hook (symbolS *newsymP, symbolS *orgsymP)
335 long sz = (OBJ_COFF_MAX_AUXENTRIES + 1) * sizeof (combined_entry_type);
336 combined_entry_type * s = xmalloc (sz);
338 memcpy (s, coffsymbol (symbol_get_bfdsym (orgsymP))->native, sz);
339 coffsymbol (symbol_get_bfdsym (newsymP))->native = s;
341 SF_SET (newsymP, SF_GET (orgsymP));
345 /* Handle .ln directives. */
347 static symbolS *current_lineno_sym;
348 static struct line_no *line_nos;
349 /* FIXME: Blindly assume all .ln directives will be in the .text section. */
353 add_lineno (fragS * frag, addressT offset, int num)
355 struct line_no * new_line = xmalloc (sizeof (* new_line));
357 if (!current_lineno_sym)
361 /* The native aix assembler accepts negative line number. */
365 /* Zero is used as an end marker in the file. */
366 as_warn (_("Line numbers must be positive integers\n"));
369 #endif /* OBJ_XCOFF */
370 new_line->next = line_nos;
371 new_line->frag = frag;
372 new_line->l.line_number = num;
373 new_line->l.u.offset = offset;
379 coff_add_linesym (symbolS *sym)
383 coffsymbol (symbol_get_bfdsym (current_lineno_sym))->lineno =
388 current_lineno_sym = sym;
392 obj_coff_ln (int appline)
396 if (! appline && def_symbol_in_progress != NULL)
398 as_warn (_(".ln pseudo-op inside .def/.endef: ignored."));
399 demand_empty_rest_of_line ();
403 l = get_absolute_expression ();
405 /* If there is no lineno symbol, treat a .ln
406 directive as if it were a .appline directive. */
407 if (appline || current_lineno_sym == NULL)
408 new_logical_line ((char *) NULL, l - 1);
410 add_lineno (frag_now, frag_now_fix (), l);
419 l += coff_line_base - 1;
420 listing_source_line (l);
425 demand_empty_rest_of_line ();
428 /* .loc is essentially the same as .ln; parse it for assembler
432 obj_coff_loc (int ignore ATTRIBUTE_UNUSED)
436 /* FIXME: Why do we need this check? We need it for ECOFF, but why
437 do we need it for COFF? */
438 if (now_seg != text_section)
440 as_warn (_(".loc outside of .text"));
441 demand_empty_rest_of_line ();
445 if (def_symbol_in_progress != NULL)
447 as_warn (_(".loc pseudo-op inside .def/.endef: ignored."));
448 demand_empty_rest_of_line ();
452 /* Skip the file number. */
454 get_absolute_expression ();
457 lineno = get_absolute_expression ();
465 lineno += coff_line_base - 1;
466 listing_source_line (lineno);
471 demand_empty_rest_of_line ();
473 add_lineno (frag_now, frag_now_fix (), lineno);
476 /* Handle the .ident pseudo-op. */
479 obj_coff_ident (int ignore ATTRIBUTE_UNUSED)
481 segT current_seg = now_seg;
482 subsegT current_subseg = now_subseg;
488 /* We could put it in .comment, but that creates an extra section
489 that shouldn't be loaded into memory, which requires linker
490 changes... For now, until proven otherwise, use .rdata. */
491 sec = subseg_new (".rdata$zzz", 0);
492 bfd_set_section_flags (stdoutput, sec,
493 ((SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA)
494 & bfd_applicable_section_flags (stdoutput)));
497 subseg_new (".comment", 0);
501 subseg_set (current_seg, current_subseg);
504 /* Handle .def directives.
506 One might ask : why can't we symbol_new if the symbol does not
507 already exist and fill it with debug information. Because of
508 the C_EFCN special symbol. It would clobber the value of the
509 function symbol before we have a chance to notice that it is
510 a C_EFCN. And a second reason is that the code is more clear this
511 way. (at least I think it is :-). */
513 #define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';')
514 #define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \
515 *input_line_pointer == '\t') \
516 input_line_pointer++;
519 obj_coff_def (int what ATTRIBUTE_UNUSED)
521 char name_end; /* Char after the end of name. */
522 char *symbol_name; /* Name of the debug symbol. */
523 char *symbol_name_copy; /* Temporary copy of the name. */
524 unsigned int symbol_name_length;
526 if (def_symbol_in_progress != NULL)
528 as_warn (_(".def pseudo-op used inside of .def/.endef: ignored."));
529 demand_empty_rest_of_line ();
535 symbol_name = input_line_pointer;
536 name_end = get_symbol_end ();
537 symbol_name_length = strlen (symbol_name);
538 symbol_name_copy = xmalloc (symbol_name_length + 1);
539 strcpy (symbol_name_copy, symbol_name);
540 #ifdef tc_canonicalize_symbol_name
541 symbol_name_copy = tc_canonicalize_symbol_name (symbol_name_copy);
544 /* Initialize the new symbol. */
545 def_symbol_in_progress = symbol_make (symbol_name_copy);
546 symbol_set_frag (def_symbol_in_progress, &zero_address_frag);
547 S_SET_VALUE (def_symbol_in_progress, 0);
549 if (S_IS_STRING (def_symbol_in_progress))
550 SF_SET_STRING (def_symbol_in_progress);
552 *input_line_pointer = name_end;
554 demand_empty_rest_of_line ();
557 unsigned int dim_index;
560 obj_coff_endef (int ignore ATTRIBUTE_UNUSED)
562 symbolS *symbolP = NULL;
565 if (def_symbol_in_progress == NULL)
567 as_warn (_(".endef pseudo-op used outside of .def/.endef: ignored."));
568 demand_empty_rest_of_line ();
572 /* Set the section number according to storage class. */
573 switch (S_GET_STORAGE_CLASS (def_symbol_in_progress))
578 SF_SET_TAG (def_symbol_in_progress);
582 SF_SET_DEBUG (def_symbol_in_progress);
583 S_SET_SEGMENT (def_symbol_in_progress, fetch_coff_debug_section ());
587 SF_SET_LOCAL (def_symbol_in_progress); /* Do not emit this symbol. */
590 SF_SET_PROCESS (def_symbol_in_progress); /* Will need processing before writing. */
596 S_SET_SEGMENT (def_symbol_in_progress, text_section);
598 name = S_GET_NAME (def_symbol_in_progress);
599 if (name[0] == '.' && name[2] == 'f' && name[3] == '\0')
605 if (! in_function ())
606 as_warn (_("`%s' symbol without preceding function"), name);
607 /* Will need relocating. */
608 SF_SET_PROCESS (def_symbol_in_progress);
614 /* The MS compilers output the actual endline, not the
615 function-relative one... we want to match without
616 changing the assembler input. */
617 SA_SET_SYM_LNNO (def_symbol_in_progress,
618 (SA_GET_SYM_LNNO (def_symbol_in_progress)
629 #endif /* C_AUTOARG */
636 /* According to the COFF documentation:
638 http://osr5doc.sco.com:1996/topics/COFF_SectNumFld.html
640 A special section number (-2) marks symbolic debugging symbols,
641 including structure/union/enumeration tag names, typedefs, and
642 the name of the file. A section number of -1 indicates that the
643 symbol has a value but is not relocatable. Examples of
644 absolute-valued symbols include automatic and register variables,
645 function arguments, and .eos symbols.
647 But from Ian Lance Taylor:
649 http://sources.redhat.com/ml/binutils/2000-08/msg00202.html
651 the actual tools all marked them as section -1. So the GNU COFF
652 assembler follows historical COFF assemblers.
654 However, it causes problems for djgpp
656 http://sources.redhat.com/ml/binutils/2000-08/msg00210.html
658 By defining STRICTCOFF, a COFF port can make the assembler to
659 follow the documented behavior. */
666 SF_SET_DEBUG (def_symbol_in_progress);
667 S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
675 S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
686 /* Valid but set somewhere else (s_comm, s_lcomm, colon). */
693 as_warn (_("unexpected storage class %d"),
694 S_GET_STORAGE_CLASS (def_symbol_in_progress));
698 /* Now that we have built a debug symbol, try to find if we should
699 merge with an existing symbol or not. If a symbol is C_EFCN or
700 absolute_section or untagged SEG_DEBUG it never merges. We also
701 don't merge labels, which are in a different namespace, nor
702 symbols which have not yet been defined since they are typically
703 unique, nor do we merge tags with non-tags. */
705 /* Two cases for functions. Either debug followed by definition or
706 definition followed by debug. For definition first, we will
707 merge the debug symbol into the definition. For debug first, the
708 lineno entry MUST point to the definition function or else it
709 will point off into space when obj_crawl_symbol_chain() merges
710 the debug symbol into the real symbol. Therefor, let's presume
711 the debug symbol is a real function reference. */
713 /* FIXME-SOON If for some reason the definition label/symbol is
714 never seen, this will probably leave an undefined symbol at link
717 if (S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_EFCN
718 || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_LABEL
719 || (streq (bfd_get_section_name (stdoutput,
720 S_GET_SEGMENT (def_symbol_in_progress)),
722 && !SF_GET_TAG (def_symbol_in_progress))
723 || S_GET_SEGMENT (def_symbol_in_progress) == absolute_section
724 || ! symbol_constant_p (def_symbol_in_progress)
725 || (symbolP = symbol_find (S_GET_NAME (def_symbol_in_progress))) == NULL
726 || SF_GET_TAG (def_symbol_in_progress) != SF_GET_TAG (symbolP))
728 /* If it already is at the end of the symbol list, do nothing */
729 if (def_symbol_in_progress != symbol_lastP)
731 symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
732 symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP,
738 /* This symbol already exists, merge the newly created symbol
739 into the old one. This is not mandatory. The linker can
740 handle duplicate symbols correctly. But I guess that it save
741 a *lot* of space if the assembly file defines a lot of
744 /* The debug entry (def_symbol_in_progress) is merged into the
745 previous definition. */
747 c_symbol_merge (def_symbol_in_progress, symbolP);
748 symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
750 def_symbol_in_progress = symbolP;
752 if (SF_GET_FUNCTION (def_symbol_in_progress)
753 || SF_GET_TAG (def_symbol_in_progress)
754 || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_STAT)
756 /* For functions, and tags, and static symbols, the symbol
757 *must* be where the debug symbol appears. Move the
758 existing symbol to the current place. */
759 /* If it already is at the end of the symbol list, do nothing. */
760 if (def_symbol_in_progress != symbol_lastP)
762 symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
763 symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
768 if (SF_GET_TAG (def_symbol_in_progress))
772 oldtag = symbol_find (S_GET_NAME (def_symbol_in_progress));
773 if (oldtag == NULL || ! SF_GET_TAG (oldtag))
774 tag_insert (S_GET_NAME (def_symbol_in_progress),
775 def_symbol_in_progress);
778 if (SF_GET_FUNCTION (def_symbol_in_progress))
780 set_function (def_symbol_in_progress);
781 SF_SET_PROCESS (def_symbol_in_progress);
784 /* That is, if this is the first time we've seen the
786 symbol_table_insert (def_symbol_in_progress);
790 def_symbol_in_progress = NULL;
791 demand_empty_rest_of_line ();
795 obj_coff_dim (int ignore ATTRIBUTE_UNUSED)
799 if (def_symbol_in_progress == NULL)
801 as_warn (_(".dim pseudo-op used outside of .def/.endef: ignored."));
802 demand_empty_rest_of_line ();
806 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
808 for (dim_index = 0; dim_index < DIMNUM; dim_index++)
811 SA_SET_SYM_DIMEN (def_symbol_in_progress, dim_index,
812 get_absolute_expression ());
814 switch (*input_line_pointer)
817 input_line_pointer++;
821 as_warn (_("badly formed .dim directive ignored"));
830 demand_empty_rest_of_line ();
834 obj_coff_line (int ignore ATTRIBUTE_UNUSED)
838 if (def_symbol_in_progress == NULL)
840 /* Probably stabs-style line? */
845 this_base = get_absolute_expression ();
846 if (streq (".bf", S_GET_NAME (def_symbol_in_progress)))
847 coff_line_base = this_base;
849 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
850 SA_SET_SYM_LNNO (def_symbol_in_progress, this_base);
852 demand_empty_rest_of_line ();
855 if (streq (".bf", S_GET_NAME (def_symbol_in_progress)))
860 listing_source_line ((unsigned int) this_base);
866 obj_coff_size (int ignore ATTRIBUTE_UNUSED)
868 if (def_symbol_in_progress == NULL)
870 as_warn (_(".size pseudo-op used outside of .def/.endef ignored."));
871 demand_empty_rest_of_line ();
875 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
876 SA_SET_SYM_SIZE (def_symbol_in_progress, get_absolute_expression ());
877 demand_empty_rest_of_line ();
881 obj_coff_scl (int ignore ATTRIBUTE_UNUSED)
883 if (def_symbol_in_progress == NULL)
885 as_warn (_(".scl pseudo-op used outside of .def/.endef ignored."));
886 demand_empty_rest_of_line ();
890 S_SET_STORAGE_CLASS (def_symbol_in_progress, get_absolute_expression ());
891 demand_empty_rest_of_line ();
895 obj_coff_tag (int ignore ATTRIBUTE_UNUSED)
900 if (def_symbol_in_progress == NULL)
902 as_warn (_(".tag pseudo-op used outside of .def/.endef ignored."));
903 demand_empty_rest_of_line ();
907 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
908 symbol_name = input_line_pointer;
909 name_end = get_symbol_end ();
911 #ifdef tc_canonicalize_symbol_name
912 symbol_name = tc_canonicalize_symbol_name (symbol_name);
915 /* Assume that the symbol referred to by .tag is always defined.
916 This was a bad assumption. I've added find_or_make. xoxorich. */
917 SA_SET_SYM_TAGNDX (def_symbol_in_progress,
918 tag_find_or_make (symbol_name));
919 if (SA_GET_SYM_TAGNDX (def_symbol_in_progress) == 0L)
920 as_warn (_("tag not found for .tag %s"), symbol_name);
922 SF_SET_TAGGED (def_symbol_in_progress);
923 *input_line_pointer = name_end;
925 demand_empty_rest_of_line ();
929 obj_coff_type (int ignore ATTRIBUTE_UNUSED)
931 if (def_symbol_in_progress == NULL)
933 as_warn (_(".type pseudo-op used outside of .def/.endef ignored."));
934 demand_empty_rest_of_line ();
938 S_SET_DATA_TYPE (def_symbol_in_progress, get_absolute_expression ());
940 if (ISFCN (S_GET_DATA_TYPE (def_symbol_in_progress)) &&
941 S_GET_STORAGE_CLASS (def_symbol_in_progress) != C_TPDEF)
942 SF_SET_FUNCTION (def_symbol_in_progress);
944 demand_empty_rest_of_line ();
948 obj_coff_val (int ignore ATTRIBUTE_UNUSED)
950 if (def_symbol_in_progress == NULL)
952 as_warn (_(".val pseudo-op used outside of .def/.endef ignored."));
953 demand_empty_rest_of_line ();
957 if (is_name_beginner (*input_line_pointer))
959 char *symbol_name = input_line_pointer;
960 char name_end = get_symbol_end ();
962 #ifdef tc_canonicalize_symbol_name
963 symbol_name = tc_canonicalize_symbol_name (symbol_name);
965 if (streq (symbol_name, "."))
967 /* If the .val is != from the .def (e.g. statics). */
968 symbol_set_frag (def_symbol_in_progress, frag_now);
969 S_SET_VALUE (def_symbol_in_progress, (valueT) frag_now_fix ());
971 else if (! streq (S_GET_NAME (def_symbol_in_progress), symbol_name))
976 exp.X_add_symbol = symbol_find_or_make (symbol_name);
977 exp.X_op_symbol = NULL;
978 exp.X_add_number = 0;
979 symbol_set_value_expression (def_symbol_in_progress, &exp);
981 /* If the segment is undefined when the forward reference is
982 resolved, then copy the segment id from the forward
984 SF_SET_GET_SEGMENT (def_symbol_in_progress);
986 /* FIXME: gcc can generate address expressions here in
987 unusual cases (search for "obscure" in sdbout.c). We
988 just ignore the offset here, thus generating incorrect
989 debugging information. We ignore the rest of the line
992 /* Otherwise, it is the name of a non debug symbol and its value
993 will be calculated later. */
994 *input_line_pointer = name_end;
998 S_SET_VALUE (def_symbol_in_progress, get_absolute_expression ());
1001 demand_empty_rest_of_line ();
1006 /* Return nonzero if name begins with weak alternate symbol prefix. */
1009 weak_is_altname (const char * name)
1011 return strneq (name, weak_altprefix, sizeof (weak_altprefix) - 1);
1014 /* Return the name of the alternate symbol
1015 name corresponding to a weak symbol's name. */
1018 weak_name2altname (const char * name)
1022 alt_name = xmalloc (sizeof (weak_altprefix) + strlen (name));
1023 strcpy (alt_name, weak_altprefix);
1024 return strcat (alt_name, name);
1027 /* Return the name of the weak symbol corresponding to an
1028 alternate symbol. */
1031 weak_altname2name (const char * name)
1036 assert (weak_is_altname (name));
1038 weak_name = xstrdup (name + 6);
1039 if ((dot = strchr (weak_name, '.')))
1044 /* Make a weak symbol name unique by
1045 appending the name of an external symbol. */
1048 weak_uniquify (const char * name)
1051 const char * unique = "";
1054 if (an_external_name != NULL)
1055 unique = an_external_name;
1057 assert (weak_is_altname (name));
1059 if (strchr (name + sizeof (weak_altprefix), '.'))
1062 ret = xmalloc (strlen (name) + strlen (unique) + 2);
1065 strcat (ret, unique);
1070 pecoff_obj_set_weak_hook (symbolS *symbolP)
1072 symbolS *alternateP;
1074 /* See _Microsoft Portable Executable and Common Object
1075 File Format Specification_, section 5.5.3.
1076 Create a symbol representing the alternate value.
1077 coff_frob_symbol will set the value of this symbol from
1078 the value of the weak symbol itself. */
1079 S_SET_STORAGE_CLASS (symbolP, C_NT_WEAK);
1080 S_SET_NUMBER_AUXILIARY (symbolP, 1);
1081 SA_SET_SYM_FSIZE (symbolP, IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY);
1083 alternateP = symbol_find_or_make (weak_name2altname (S_GET_NAME (symbolP)));
1084 S_SET_EXTERNAL (alternateP);
1085 S_SET_STORAGE_CLASS (alternateP, C_NT_WEAK);
1087 SA_SET_SYM_TAGNDX (symbolP, alternateP);
1091 pecoff_obj_clear_weak_hook (symbolS *symbolP)
1093 symbolS *alternateP;
1095 S_SET_STORAGE_CLASS (symbolP, 0);
1096 SA_SET_SYM_FSIZE (symbolP, 0);
1098 alternateP = symbol_find (weak_name2altname (S_GET_NAME (symbolP)));
1099 S_CLEAR_EXTERNAL (alternateP);
1104 /* Handle .weak. This is a GNU extension in formats other than PE. */
1107 obj_coff_weak (int ignore ATTRIBUTE_UNUSED)
1115 name = input_line_pointer;
1116 c = get_symbol_end ();
1119 as_warn (_("badly formed .weak directive ignored"));
1120 ignore_rest_of_line ();
1124 symbolP = symbol_find_or_make (name);
1125 *input_line_pointer = c;
1127 S_SET_WEAK (symbolP);
1131 input_line_pointer++;
1133 if (*input_line_pointer == '\n')
1140 demand_empty_rest_of_line ();
1144 coff_obj_read_begin_hook (void)
1146 /* These had better be the same. Usually 18 bytes. */
1147 know (sizeof (SYMENT) == sizeof (AUXENT));
1148 know (SYMESZ == AUXESZ);
1152 symbolS *coff_last_function;
1154 static symbolS *coff_last_bf;
1158 coff_frob_symbol (symbolS *symp, int *punt)
1160 static symbolS *last_tagP;
1161 static stack *block_stack;
1162 static symbolS *set_end;
1163 symbolS *next_set_end = NULL;
1165 if (symp == &abs_symbol)
1171 if (current_lineno_sym)
1172 coff_add_linesym (NULL);
1175 block_stack = stack_init (512, sizeof (symbolS*));
1178 if (S_GET_STORAGE_CLASS (symp) == C_NT_WEAK
1179 && ! S_IS_WEAK (symp)
1180 && weak_is_altname (S_GET_NAME (symp)))
1182 /* This is a weak alternate symbol. All processing of
1183 PECOFFweak symbols is done here, through the alternate. */
1184 symbolS *weakp = symbol_find_noref (weak_altname2name
1185 (S_GET_NAME (symp)), 1);
1188 assert (S_GET_NUMBER_AUXILIARY (weakp) == 1);
1190 if (! S_IS_WEAK (weakp))
1192 /* The symbol was turned from weak to strong. Discard altname. */
1196 else if (symbol_equated_p (weakp))
1198 /* The weak symbol has an alternate specified; symp is unneeded. */
1199 S_SET_STORAGE_CLASS (weakp, C_NT_WEAK);
1200 SA_SET_SYM_TAGNDX (weakp,
1201 symbol_get_value_expression (weakp)->X_add_symbol);
1203 S_CLEAR_EXTERNAL (symp);
1209 /* The weak symbol has been assigned an alternate value.
1210 Copy this value to symp, and set symp as weakp's alternate. */
1211 if (S_GET_STORAGE_CLASS (weakp) != C_NT_WEAK)
1213 S_SET_STORAGE_CLASS (symp, S_GET_STORAGE_CLASS (weakp));
1214 S_SET_STORAGE_CLASS (weakp, C_NT_WEAK);
1217 if (S_IS_DEFINED (weakp))
1219 /* This is a defined weak symbol. Copy value information
1220 from the weak symbol itself to the alternate symbol. */
1221 symbol_set_value_expression (symp,
1222 symbol_get_value_expression (weakp));
1223 symbol_set_frag (symp, symbol_get_frag (weakp));
1224 S_SET_SEGMENT (symp, S_GET_SEGMENT (weakp));
1228 /* This is an undefined weak symbol.
1229 Define the alternate symbol to zero. */
1230 S_SET_VALUE (symp, 0);
1231 S_SET_SEGMENT (symp, absolute_section);
1234 S_SET_NAME (symp, weak_uniquify (S_GET_NAME (symp)));
1235 S_SET_STORAGE_CLASS (symp, C_EXT);
1237 S_SET_VALUE (weakp, 0);
1238 S_SET_SEGMENT (weakp, undefined_section);
1242 if (S_IS_WEAK (symp))
1243 S_SET_STORAGE_CLASS (symp, C_WEAKEXT);
1246 if (!S_IS_DEFINED (symp)
1247 && !S_IS_WEAK (symp)
1248 && S_GET_STORAGE_CLASS (symp) != C_STAT)
1249 S_SET_STORAGE_CLASS (symp, C_EXT);
1251 if (!SF_GET_DEBUG (symp))
1255 if (!SF_GET_LOCAL (symp)
1256 && !SF_GET_STATICS (symp)
1257 && S_GET_STORAGE_CLASS (symp) != C_LABEL
1258 && symbol_constant_p (symp)
1259 && (real = symbol_find_noref (S_GET_NAME (symp), 1))
1260 && S_GET_STORAGE_CLASS (real) == C_NULL
1263 c_symbol_merge (symp, real);
1268 if (!S_IS_DEFINED (symp) && !SF_GET_LOCAL (symp))
1270 assert (S_GET_VALUE (symp) == 0);
1271 if (S_IS_WEAKREFD (symp))
1274 S_SET_EXTERNAL (symp);
1276 else if (S_GET_STORAGE_CLASS (symp) == C_NULL)
1278 if (S_GET_SEGMENT (symp) == text_section
1279 && symp != seg_info (text_section)->sym)
1280 S_SET_STORAGE_CLASS (symp, C_LABEL);
1282 S_SET_STORAGE_CLASS (symp, C_STAT);
1285 if (SF_GET_PROCESS (symp))
1287 if (S_GET_STORAGE_CLASS (symp) == C_BLOCK)
1289 if (streq (S_GET_NAME (symp), ".bb"))
1290 stack_push (block_stack, (char *) &symp);
1295 begin = *(symbolS **) stack_pop (block_stack);
1297 as_warn (_("mismatched .eb"));
1299 next_set_end = begin;
1303 if (coff_last_function == 0 && SF_GET_FUNCTION (symp))
1305 union internal_auxent *auxp;
1307 coff_last_function = symp;
1308 if (S_GET_NUMBER_AUXILIARY (symp) < 1)
1309 S_SET_NUMBER_AUXILIARY (symp, 1);
1310 auxp = SYM_AUXENT (symp);
1311 memset (auxp->x_sym.x_fcnary.x_ary.x_dimen, 0,
1312 sizeof (auxp->x_sym.x_fcnary.x_ary.x_dimen));
1315 if (S_GET_STORAGE_CLASS (symp) == C_EFCN)
1317 if (coff_last_function == 0)
1318 as_fatal (_("C_EFCN symbol for %s out of scope"),
1320 SA_SET_SYM_FSIZE (coff_last_function,
1321 (long) (S_GET_VALUE (symp)
1322 - S_GET_VALUE (coff_last_function)));
1323 next_set_end = coff_last_function;
1324 coff_last_function = 0;
1328 if (S_IS_EXTERNAL (symp))
1329 S_SET_STORAGE_CLASS (symp, C_EXT);
1330 else if (SF_GET_LOCAL (symp))
1333 if (SF_GET_FUNCTION (symp))
1334 symbol_get_bfdsym (symp)->flags |= BSF_FUNCTION;
1337 /* Double check weak symbols. */
1338 if (S_IS_WEAK (symp) && S_IS_COMMON (symp))
1339 as_bad (_("Symbol `%s' can not be both weak and common"),
1342 if (SF_GET_TAG (symp))
1344 else if (S_GET_STORAGE_CLASS (symp) == C_EOS)
1345 next_set_end = last_tagP;
1348 /* This is pretty horrible, but we have to set *punt correctly in
1349 order to call SA_SET_SYM_ENDNDX correctly. */
1350 if (! symbol_used_in_reloc_p (symp)
1351 && ((symbol_get_bfdsym (symp)->flags & BSF_SECTION_SYM) != 0
1352 || (! (S_IS_EXTERNAL (symp) || S_IS_WEAK (symp))
1353 && ! symbol_get_tc (symp)->output
1354 && S_GET_STORAGE_CLASS (symp) != C_FILE)))
1358 if (set_end != (symbolS *) NULL
1360 && ((symbol_get_bfdsym (symp)->flags & BSF_NOT_AT_END) != 0
1361 || (S_IS_DEFINED (symp)
1362 && ! S_IS_COMMON (symp)
1363 && (! S_IS_EXTERNAL (symp) || SF_GET_FUNCTION (symp)))))
1365 SA_SET_SYM_ENDNDX (set_end, symp);
1369 if (next_set_end != NULL)
1371 if (set_end != NULL)
1372 as_warn ("Warning: internal error: forgetting to set endndx of %s",
1373 S_GET_NAME (set_end));
1374 set_end = next_set_end;
1379 && S_GET_STORAGE_CLASS (symp) == C_FCN
1380 && streq (S_GET_NAME (symp), ".bf"))
1382 if (coff_last_bf != NULL)
1383 SA_SET_SYM_ENDNDX (coff_last_bf, symp);
1384 coff_last_bf = symp;
1387 if (coffsymbol (symbol_get_bfdsym (symp))->lineno)
1390 struct line_no *lptr;
1393 lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno;
1394 for (i = 0; lptr; lptr = lptr->next)
1396 lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno;
1398 /* We need i entries for line numbers, plus 1 for the first
1399 entry which BFD will override, plus 1 for the last zero
1400 entry (a marker for BFD). */
1401 l = xmalloc ((i + 2) * sizeof (* l));
1402 coffsymbol (symbol_get_bfdsym (symp))->lineno = l;
1403 l[i + 1].line_number = 0;
1404 l[i + 1].u.sym = NULL;
1408 lptr->l.u.offset += lptr->frag->fr_address / OCTETS_PER_BYTE;
1416 coff_adjust_section_syms (bfd *abfd ATTRIBUTE_UNUSED,
1418 void * x ATTRIBUTE_UNUSED)
1421 segment_info_type *seginfo = seg_info (sec);
1422 int nlnno, nrelocs = 0;
1424 /* RS/6000 gas creates a .debug section manually in ppc_frob_file in
1425 tc-ppc.c. Do not get confused by it. */
1426 if (seginfo == NULL)
1429 if (streq (sec->name, ".text"))
1430 nlnno = coff_n_line_nos;
1434 /* @@ Hope that none of the fixups expand to more than one reloc
1436 fixS *fixp = seginfo->fix_root;
1439 if (! fixp->fx_done)
1441 fixp = fixp->fx_next;
1444 if (bfd_get_section_size (sec) == 0
1447 && sec != text_section
1448 && sec != data_section
1449 && sec != bss_section)
1452 secsym = section_symbol (sec);
1453 /* This is an estimate; we'll plug in the real value using
1454 SET_SECTION_RELOCS later */
1455 SA_SET_SCN_NRELOC (secsym, nrelocs);
1456 SA_SET_SCN_NLINNO (secsym, nlnno);
1460 coff_frob_file_after_relocs (void)
1462 bfd_map_over_sections (stdoutput, coff_adjust_section_syms, NULL);
1465 /* Implement the .section pseudo op:
1466 .section name {, "flags"}
1468 | +--- optional flags: 'b' for bss
1470 +-- section name 'l' for lib
1474 'd' (apparently m88k for data)
1476 'r' for read-only data
1477 's' for shared data (PE)
1478 But if the argument is not a quoted string, treat it as a
1481 Note the 'a' flag is silently ignored. This allows the same
1482 .section directive to be parsed in both ELF and COFF formats. */
1485 obj_coff_section (int ignore ATTRIBUTE_UNUSED)
1487 /* Strip out the section name. */
1492 flagword flags, oldflags;
1503 section_name = input_line_pointer;
1504 c = get_symbol_end ();
1506 name = xmalloc (input_line_pointer - section_name + 1);
1507 strcpy (name, section_name);
1509 *input_line_pointer = c;
1514 flags = SEC_NO_FLAGS;
1516 if (*input_line_pointer == ',')
1518 ++input_line_pointer;
1520 if (*input_line_pointer != '"')
1521 exp = get_absolute_expression ();
1525 int readonly_removed = 0;
1526 int load_removed = 0;
1528 while (attr = *++input_line_pointer,
1530 && ! is_end_of_line[attr])
1535 /* Uninitialised data section. */
1541 /* Section not loaded. */
1543 flags |= SEC_NEVER_LOAD;
1548 /* Shared section. */
1549 flags |= SEC_COFF_SHARED;
1556 flags &=~ SEC_READONLY;
1560 /* Writable section. */
1561 flags &=~ SEC_READONLY;
1562 readonly_removed = 1;
1566 /* Ignore. Here for compatibility with ELF. */
1569 case 'r': /* Read-only section. Implies a data section. */
1570 readonly_removed = 0;
1572 case 'x': /* Executable section. */
1573 /* If we are setting the 'x' attribute or if the 'r'
1574 attribute is being used to restore the readonly status
1575 of a code section (eg "wxr") then set the SEC_CODE flag,
1576 otherwise set the SEC_DATA flag. */
1577 flags |= (attr == 'x' || (flags & SEC_CODE) ? SEC_CODE : SEC_DATA);
1580 /* Note - the READONLY flag is set here, even for the 'x'
1581 attribute in order to be compatible with the MSVC
1583 if (! readonly_removed)
1584 flags |= SEC_READONLY;
1587 case 'i': /* STYP_INFO */
1588 case 'l': /* STYP_LIB */
1589 case 'o': /* STYP_OVER */
1590 as_warn (_("unsupported section attribute '%c'"), attr);
1594 as_warn (_("unknown section attribute '%c'"), attr);
1599 ++input_line_pointer;
1603 sec = subseg_new (name, (subsegT) exp);
1605 oldflags = bfd_get_section_flags (stdoutput, sec);
1606 if (oldflags == SEC_NO_FLAGS)
1608 /* Set section flags for a new section just created by subseg_new.
1609 Provide a default if no flags were parsed. */
1610 if (flags == SEC_NO_FLAGS)
1611 flags = TC_COFF_SECTION_DEFAULT_ATTRIBUTES;
1613 #ifdef COFF_LONG_SECTION_NAMES
1614 /* Add SEC_LINK_ONCE and SEC_LINK_DUPLICATES_DISCARD to .gnu.linkonce
1615 sections so adjust_reloc_syms in write.c will correctly handle
1616 relocs which refer to non-local symbols in these sections. */
1617 if (strneq (name, ".gnu.linkonce", sizeof (".gnu.linkonce") - 1))
1618 flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
1621 if (! bfd_set_section_flags (stdoutput, sec, flags))
1622 as_warn (_("error setting flags for \"%s\": %s"),
1623 bfd_section_name (stdoutput, sec),
1624 bfd_errmsg (bfd_get_error ()));
1626 else if (flags != SEC_NO_FLAGS)
1628 /* This section's attributes have already been set. Warn if the
1629 attributes don't match. */
1630 flagword matchflags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
1631 | SEC_DATA | SEC_COFF_SHARED | SEC_NEVER_LOAD);
1632 if ((flags ^ oldflags) & matchflags)
1633 as_warn (_("Ignoring changed section attributes for %s"), name);
1636 demand_empty_rest_of_line ();
1640 coff_adjust_symtab (void)
1642 if (symbol_rootP == NULL
1643 || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
1644 c_dot_file_symbol ("fake", 0);
1648 coff_frob_section (segT sec)
1653 bfd_vma size, n_entries, mask;
1654 bfd_vma align_power = (bfd_vma)sec->alignment_power + OCTETS_PER_BYTE_POWER;
1656 /* The COFF back end in BFD requires that all section sizes be
1657 rounded up to multiples of the corresponding section alignments,
1658 supposedly because standard COFF has no other way of encoding alignment
1659 for sections. If your COFF flavor has a different way of encoding
1660 section alignment, then skip this step, as TICOFF does. */
1661 size = bfd_get_section_size (sec);
1662 mask = ((bfd_vma) 1 << align_power) - 1;
1663 #if !defined(TICOFF)
1669 new_size = (size + mask) & ~mask;
1670 bfd_set_section_size (stdoutput, sec, new_size);
1672 /* If the size had to be rounded up, add some padding in
1673 the last non-empty frag. */
1674 fragp = seg_info (sec)->frchainP->frch_root;
1675 last = seg_info (sec)->frchainP->frch_last;
1676 while (fragp->fr_next != last)
1677 fragp = fragp->fr_next;
1678 last->fr_address = size;
1679 fragp->fr_offset += new_size - size;
1683 /* If the section size is non-zero, the section symbol needs an aux
1684 entry associated with it, indicating the size. We don't know
1685 all the values yet; coff_frob_symbol will fill them in later. */
1688 || sec == text_section
1689 || sec == data_section
1690 || sec == bss_section)
1693 symbolS *secsym = section_symbol (sec);
1695 S_SET_STORAGE_CLASS (secsym, C_STAT);
1696 S_SET_NUMBER_AUXILIARY (secsym, 1);
1697 SF_SET_STATICS (secsym);
1698 SA_SET_SCN_SCNLEN (secsym, size);
1701 /* FIXME: These should be in a "stabs.h" file, or maybe as.h. */
1702 #ifndef STAB_SECTION_NAME
1703 #define STAB_SECTION_NAME ".stab"
1705 #ifndef STAB_STRING_SECTION_NAME
1706 #define STAB_STRING_SECTION_NAME ".stabstr"
1708 if (! streq (STAB_STRING_SECTION_NAME, sec->name))
1712 sec = subseg_get (STAB_SECTION_NAME, 0);
1713 /* size is already rounded up, since other section will be listed first */
1714 size = bfd_get_section_size (strsec);
1716 n_entries = bfd_get_section_size (sec) / 12 - 1;
1718 /* Find first non-empty frag. It should be large enough. */
1719 fragp = seg_info (sec)->frchainP->frch_root;
1720 while (fragp && fragp->fr_fix == 0)
1721 fragp = fragp->fr_next;
1722 assert (fragp != 0 && fragp->fr_fix >= 12);
1724 /* Store the values. */
1725 p = fragp->fr_literal;
1726 bfd_h_put_16 (stdoutput, n_entries, (bfd_byte *) p + 6);
1727 bfd_h_put_32 (stdoutput, size, (bfd_byte *) p + 8);
1731 obj_coff_init_stab_section (segT seg)
1736 unsigned int stroff;
1738 /* Make space for this first symbol. */
1742 as_where (&file, (unsigned int *) NULL);
1743 stabstr_name = xmalloc (strlen (seg->name) + 4);
1744 strcpy (stabstr_name, seg->name);
1745 strcat (stabstr_name, "str");
1746 stroff = get_stab_string_offset (file, stabstr_name);
1748 md_number_to_chars (p, stroff, 4);
1753 s_get_name (symbolS *s)
1755 return ((s == NULL) ? "(NULL)" : S_GET_NAME (s));
1763 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
1764 printf (_("0x%lx: \"%s\" type = %ld, class = %d, segment = %d\n"),
1765 (unsigned long) symbolP,
1766 S_GET_NAME (symbolP),
1767 (long) S_GET_DATA_TYPE (symbolP),
1768 S_GET_STORAGE_CLASS (symbolP),
1769 (int) S_GET_SEGMENT (symbolP));
1774 const pseudo_typeS coff_pseudo_table[] =
1776 {"ABORT", s_abort, 0},
1777 {"appline", obj_coff_ln, 1},
1778 /* We accept the .bss directive for backward compatibility with
1779 earlier versions of gas. */
1780 {"bss", obj_coff_bss, 0},
1781 {"def", obj_coff_def, 0},
1782 {"dim", obj_coff_dim, 0},
1783 {"endef", obj_coff_endef, 0},
1784 {"ident", obj_coff_ident, 0},
1785 {"line", obj_coff_line, 0},
1786 {"ln", obj_coff_ln, 0},
1787 {"scl", obj_coff_scl, 0},
1788 {"sect", obj_coff_section, 0},
1789 {"sect.s", obj_coff_section, 0},
1790 {"section", obj_coff_section, 0},
1791 {"section.s", obj_coff_section, 0},
1792 /* FIXME: We ignore the MRI short attribute. */
1793 {"size", obj_coff_size, 0},
1794 {"tag", obj_coff_tag, 0},
1795 {"type", obj_coff_type, 0},
1796 {"val", obj_coff_val, 0},
1797 {"version", s_ignore, 0},
1798 {"loc", obj_coff_loc, 0},
1799 {"optim", s_ignore, 0}, /* For sun386i cc (?) */
1800 {"weak", obj_coff_weak, 0},
1801 #if defined TC_TIC4X
1802 /* The tic4x uses sdef instead of def. */
1803 {"sdef", obj_coff_def, 0},
1809 /* Support for a COFF emulation. */
1812 coff_pop_insert (void)
1814 pop_insert (coff_pseudo_table);
1818 coff_separate_stab_sections (void)
1823 const struct format_ops coff_format_ops =
1825 bfd_target_coff_flavour,
1826 0, /* dfl_leading_underscore */
1827 1, /* emit_section_symbols */
1832 0, /* frob_file_before_adjust */
1833 0, /* frob_file_before_fix */
1834 coff_frob_file_after_relocs,
1837 0, /* s_get_align */
1838 0, /* s_set_align */
1839 0, /* s_get_other */
1840 0, /* s_set_other */
1845 0, /* copy_symbol_attributes */
1846 0, /* generate_asm_lineno */
1847 0, /* process_stab */
1848 coff_separate_stab_sections,
1849 obj_coff_init_stab_section,
1850 0, /* sec_sym_ok_for_reloc */
1852 0, /* ecoff_set_ext */
1853 coff_obj_read_begin_hook,
1854 coff_obj_symbol_new_hook