]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gas/config/obj-coff.c
* config/obj-coff.h (USE_UNIQUE): Don't define.
[thirdparty/binutils-gdb.git] / gas / config / obj-coff.c
CommitLineData
252b5132 1/* coff object file format
f7e42eb4 2 Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
aa820537 3 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009
252b5132
RH
4 Free Software Foundation, Inc.
5
6 This file is part of GAS.
7
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
ec2655a6 10 the Free Software Foundation; either version 3, or (at your option)
252b5132
RH
11 any later version.
12
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.
17
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
4b4da160
NC
20 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
21 02110-1301, USA. */
252b5132
RH
22
23#define OBJ_HEADER "obj-coff.h"
24
25#include "as.h"
26#include "obstack.h"
27#include "subsegs.h"
28
977cdf5a
NC
29#ifdef TE_PE
30#include "coff/pe.h"
31#endif
32
a5324a3e
NC
33#define streq(a,b) (strcmp ((a), (b)) == 0)
34#define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
35
252b5132
RH
36/* I think this is probably always correct. */
37#ifndef KEEP_RELOC_INFO
38#define KEEP_RELOC_INFO
39#endif
40
7be1c489
AM
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. */
b8a9dcab
NC
44#ifndef TC_COFF_SECTION_DEFAULT_ATTRIBUTES
45#define TC_COFF_SECTION_DEFAULT_ATTRIBUTES (SEC_LOAD | SEC_DATA)
46#endif
47
8d28c9d7
AM
48/* This is used to hold the symbol built by a sequence of pseudo-ops
49 from .def and .endef. */
50static symbolS *def_symbol_in_progress;
977cdf5a
NC
51#ifdef TE_PE
52/* PE weak alternate symbols begin with this string. */
53static const char weak_altprefix[] = ".weak.";
54#endif /* TE_PE */
8d28c9d7 55
f3d2b04b
KT
56#include "obj-coff-seh.c"
57
8d28c9d7
AM
58typedef struct
59 {
60 unsigned long chunk_size;
61 unsigned long element_size;
62 unsigned long size;
63 char *data;
64 unsigned long pointer;
65 }
66stack;
67
252b5132 68\f
a5324a3e 69/* Stack stuff. */
252b5132
RH
70
71static stack *
a5324a3e
NC
72stack_init (unsigned long chunk_size,
73 unsigned long element_size)
252b5132
RH
74{
75 stack *st;
76
a5324a3e 77 st = malloc (sizeof (* st));
252b5132 78 if (!st)
a5324a3e 79 return NULL;
252b5132
RH
80 st->data = malloc (chunk_size);
81 if (!st->data)
82 {
83 free (st);
a5324a3e 84 return NULL;
252b5132
RH
85 }
86 st->pointer = 0;
87 st->size = chunk_size;
88 st->chunk_size = chunk_size;
89 st->element_size = element_size;
90 return st;
91}
92
252b5132 93static char *
a5324a3e 94stack_push (stack *st, char *element)
252b5132
RH
95{
96 if (st->pointer + st->element_size >= st->size)
97 {
98 st->size += st->chunk_size;
a5324a3e
NC
99 if ((st->data = xrealloc (st->data, st->size)) == NULL)
100 return NULL;
252b5132
RH
101 }
102 memcpy (st->data + st->pointer, element, st->element_size);
103 st->pointer += st->element_size;
104 return st->data + st->pointer;
105}
106
107static char *
a5324a3e 108stack_pop (stack *st)
252b5132
RH
109{
110 if (st->pointer < st->element_size)
111 {
112 st->pointer = 0;
a5324a3e 113 return NULL;
252b5132
RH
114 }
115 st->pointer -= st->element_size;
116 return st->data + st->pointer;
117}
118\f
a5324a3e 119/* Maintain a list of the tagnames of the structures. */
252b5132
RH
120
121static struct hash_control *tag_hash;
122
123static void
a5324a3e 124tag_init (void)
252b5132
RH
125{
126 tag_hash = hash_new ();
127}
128
129static void
a5324a3e 130tag_insert (const char *name, symbolS *symbolP)
252b5132
RH
131{
132 const char *error_string;
133
134 if ((error_string = hash_jam (tag_hash, name, (char *) symbolP)))
a5324a3e
NC
135 as_fatal (_("Inserting \"%s\" into structure table failed: %s"),
136 name, error_string);
252b5132
RH
137}
138
139static symbolS *
a5324a3e 140tag_find (char *name)
252b5132 141{
252b5132
RH
142 return (symbolS *) hash_find (tag_hash, name);
143}
144
145static symbolS *
a5324a3e 146tag_find_or_make (char *name)
252b5132
RH
147{
148 symbolS *symbolP;
149
150 if ((symbolP = tag_find (name)) == NULL)
151 {
152 symbolP = symbol_new (name, undefined_section,
153 0, &zero_address_frag);
154
155 tag_insert (S_GET_NAME (symbolP), symbolP);
252b5132 156 symbol_table_insert (symbolP);
a5324a3e 157 }
252b5132
RH
158
159 return symbolP;
160}
161
162/* We accept the .bss directive to set the section for backward
163 compatibility with earlier versions of gas. */
164
165static void
a5324a3e 166obj_coff_bss (int ignore ATTRIBUTE_UNUSED)
252b5132
RH
167{
168 if (*input_line_pointer == '\n')
169 subseg_new (".bss", get_absolute_expression ());
170 else
171 s_lcomm (0);
172}
173
c1711530
DK
174#ifdef TE_PE
175/* Called from read.c:s_comm after we've parsed .comm symbol, size.
176 Parse a possible alignment value. */
177
178static symbolS *
179obj_coff_common_parse (int ignore ATTRIBUTE_UNUSED, symbolS *symbolP, addressT size)
180{
181 addressT align = 0;
182
183 if (*input_line_pointer == ',')
184 {
185 align = parse_align (0);
186 if (align == (addressT) -1)
187 return NULL;
188 }
189
190 S_SET_VALUE (symbolP, size);
191 S_SET_EXTERNAL (symbolP);
192 S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
193
194 symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
195
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)
199 {
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];
207
208 sec = subseg_new (".drectve", 0);
209 oldflags = bfd_get_section_flags (stdoutput, sec);
210 if (oldflags == SEC_NO_FLAGS)
211 {
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 ()));
217 }
218
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);
227 }
228
229 return symbolP;
230}
231
232static void
233obj_coff_comm (int ignore ATTRIBUTE_UNUSED)
234{
235 s_comm_internal (ignore, obj_coff_common_parse);
236}
237#endif /* TE_PE */
238
252b5132 239#define GET_FILENAME_STRING(X) \
a5324a3e 240 ((char *) (&((X)->sy_symbol.ost_auxent->x_file.x_n.x_offset))[1])
252b5132
RH
241
242/* @@ Ick. */
243static segT
a5324a3e 244fetch_coff_debug_section (void)
252b5132
RH
245{
246 static segT debug_section;
a5324a3e 247
252b5132
RH
248 if (!debug_section)
249 {
5a38dc70 250 const asymbol *s;
a5324a3e
NC
251
252 s = bfd_make_debug_symbol (stdoutput, NULL, 0);
9c2799c2 253 gas_assert (s != 0);
252b5132
RH
254 debug_section = s->section;
255 }
256 return debug_section;
257}
258
259void
a5324a3e 260SA_SET_SYM_ENDNDX (symbolS *sym, symbolS *val)
252b5132
RH
261{
262 combined_entry_type *entry, *p;
263
49309057
ILT
264 entry = &coffsymbol (symbol_get_bfdsym (sym))->native[1];
265 p = coffsymbol (symbol_get_bfdsym (val))->native;
252b5132
RH
266 entry->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p = p;
267 entry->fix_end = 1;
268}
269
270static void
a5324a3e 271SA_SET_SYM_TAGNDX (symbolS *sym, symbolS *val)
252b5132
RH
272{
273 combined_entry_type *entry, *p;
274
49309057
ILT
275 entry = &coffsymbol (symbol_get_bfdsym (sym))->native[1];
276 p = coffsymbol (symbol_get_bfdsym (val))->native;
252b5132
RH
277 entry->u.auxent.x_sym.x_tagndx.p = p;
278 entry->fix_tag = 1;
279}
280
281static int
a5324a3e 282S_GET_DATA_TYPE (symbolS *sym)
252b5132 283{
49309057 284 return coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_type;
252b5132
RH
285}
286
287int
a5324a3e 288S_SET_DATA_TYPE (symbolS *sym, int val)
252b5132 289{
49309057 290 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_type = val;
252b5132
RH
291 return val;
292}
293
294int
a5324a3e 295S_GET_STORAGE_CLASS (symbolS *sym)
252b5132 296{
49309057 297 return coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_sclass;
252b5132
RH
298}
299
300int
a5324a3e 301S_SET_STORAGE_CLASS (symbolS *sym, int val)
252b5132 302{
49309057 303 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_sclass = val;
252b5132
RH
304 return val;
305}
306
dcd619be 307/* Merge a debug symbol containing debug information into a normal symbol. */
252b5132 308
a5324a3e
NC
309static void
310c_symbol_merge (symbolS *debug, symbolS *normal)
252b5132
RH
311{
312 S_SET_DATA_TYPE (normal, S_GET_DATA_TYPE (debug));
313 S_SET_STORAGE_CLASS (normal, S_GET_STORAGE_CLASS (debug));
314
315 if (S_GET_NUMBER_AUXILIARY (debug) > S_GET_NUMBER_AUXILIARY (normal))
a5324a3e
NC
316 /* Take the most we have. */
317 S_SET_NUMBER_AUXILIARY (normal, S_GET_NUMBER_AUXILIARY (debug));
252b5132
RH
318
319 if (S_GET_NUMBER_AUXILIARY (debug) > 0)
a5324a3e
NC
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))));
252b5132 324
dcd619be 325 /* Move the debug flags. */
252b5132
RH
326 SF_SET_DEBUG_FIELD (normal, SF_GET_DEBUG_FIELD (debug));
327}
328
329void
a4528eeb 330c_dot_file_symbol (const char *filename, int appfile ATTRIBUTE_UNUSED)
252b5132
RH
331{
332 symbolS *symbolP;
333
0561a208
ILT
334 /* BFD converts filename to a .file symbol with an aux entry. It
335 also handles chaining. */
252b5132
RH
336 symbolP = symbol_new (filename, bfd_abs_section_ptr, 0, &zero_address_frag);
337
338 S_SET_STORAGE_CLASS (symbolP, C_FILE);
339 S_SET_NUMBER_AUXILIARY (symbolP, 1);
340
49309057 341 symbol_get_bfdsym (symbolP)->flags = BSF_DEBUGGING;
252b5132
RH
342
343#ifndef NO_LISTING
344 {
345 extern int listing;
a5324a3e 346
252b5132 347 if (listing)
a5324a3e 348 listing_source_file (filename);
252b5132
RH
349 }
350#endif
351
a5324a3e 352 /* Make sure that the symbol is first on the symbol chain. */
252b5132
RH
353 if (symbol_rootP != symbolP)
354 {
355 symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
356 symbol_insert (symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP);
a5324a3e 357 }
252b5132
RH
358}
359
a5324a3e 360/* Line number handling. */
252b5132 361
a5324a3e
NC
362struct line_no
363{
252b5132
RH
364 struct line_no *next;
365 fragS *frag;
366 alent l;
367};
368
369int coff_line_base;
370
371/* Symbol of last function, which we should hang line#s off of. */
372static symbolS *line_fsym;
373
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))
377
378\f
379void
a5324a3e 380coff_obj_symbol_new_hook (symbolS *symbolP)
252b5132
RH
381{
382 long sz = (OBJ_COFF_MAX_AUXENTRIES + 1) * sizeof (combined_entry_type);
a5324a3e 383 char * s = xmalloc (sz);
dcd619be 384
252b5132 385 memset (s, 0, sz);
49309057 386 coffsymbol (symbol_get_bfdsym (symbolP))->native = (combined_entry_type *) s;
252b5132
RH
387
388 S_SET_DATA_TYPE (symbolP, T_NULL);
389 S_SET_STORAGE_CLASS (symbolP, 0);
390 S_SET_NUMBER_AUXILIARY (symbolP, 0);
391
392 if (S_IS_STRING (symbolP))
393 SF_SET_STRING (symbolP);
dcd619be 394
252b5132
RH
395 if (S_IS_LOCAL (symbolP))
396 SF_SET_LOCAL (symbolP);
397}
398
6a2b6326
JB
399void
400coff_obj_symbol_clone_hook (symbolS *newsymP, symbolS *orgsymP)
401{
402 long sz = (OBJ_COFF_MAX_AUXENTRIES + 1) * sizeof (combined_entry_type);
403 combined_entry_type * s = xmalloc (sz);
404
405 memcpy (s, coffsymbol (symbol_get_bfdsym (orgsymP))->native, sz);
406 coffsymbol (symbol_get_bfdsym (newsymP))->native = s;
407
408 SF_SET (newsymP, SF_GET (orgsymP));
409}
410
252b5132 411\f
a5324a3e 412/* Handle .ln directives. */
252b5132
RH
413
414static symbolS *current_lineno_sym;
415static struct line_no *line_nos;
a5324a3e 416/* FIXME: Blindly assume all .ln directives will be in the .text section. */
252b5132
RH
417int coff_n_line_nos;
418
419static void
a5324a3e 420add_lineno (fragS * frag, addressT offset, int num)
252b5132 421{
a5324a3e
NC
422 struct line_no * new_line = xmalloc (sizeof (* new_line));
423
252b5132 424 if (!current_lineno_sym)
a5324a3e 425 abort ();
6877bb43
TR
426
427#ifndef OBJ_XCOFF
a5324a3e 428 /* The native aix assembler accepts negative line number. */
6877bb43 429
dcd619be 430 if (num <= 0)
e8a3ab75
ILT
431 {
432 /* Zero is used as an end marker in the file. */
b985eaa8
ILT
433 as_warn (_("Line numbers must be positive integers\n"));
434 num = 1;
e8a3ab75 435 }
6877bb43 436#endif /* OBJ_XCOFF */
252b5132
RH
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++;
443}
444
445void
a5324a3e 446coff_add_linesym (symbolS *sym)
252b5132
RH
447{
448 if (line_nos)
449 {
49309057
ILT
450 coffsymbol (symbol_get_bfdsym (current_lineno_sym))->lineno =
451 (alent *) line_nos;
252b5132
RH
452 coff_n_line_nos++;
453 line_nos = 0;
454 }
455 current_lineno_sym = sym;
456}
457
458static void
a5324a3e 459obj_coff_ln (int appline)
252b5132
RH
460{
461 int l;
462
463 if (! appline && def_symbol_in_progress != NULL)
464 {
465 as_warn (_(".ln pseudo-op inside .def/.endef: ignored."));
466 demand_empty_rest_of_line ();
467 return;
468 }
469
470 l = get_absolute_expression ();
252b5132 471
e237d851
NC
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)
252b5132 475 new_logical_line ((char *) NULL, l - 1);
e237d851
NC
476 else
477 add_lineno (frag_now, frag_now_fix (), l);
252b5132
RH
478
479#ifndef NO_LISTING
480 {
481 extern int listing;
482
483 if (listing)
484 {
485 if (! appline)
486 l += coff_line_base - 1;
487 listing_source_line (l);
488 }
489 }
490#endif
491
492 demand_empty_rest_of_line ();
493}
494
28428223
ILT
495/* .loc is essentially the same as .ln; parse it for assembler
496 compatibility. */
497
498static void
a5324a3e 499obj_coff_loc (int ignore ATTRIBUTE_UNUSED)
28428223
ILT
500{
501 int lineno;
502
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)
506 {
507 as_warn (_(".loc outside of .text"));
508 demand_empty_rest_of_line ();
509 return;
510 }
511
512 if (def_symbol_in_progress != NULL)
513 {
514 as_warn (_(".loc pseudo-op inside .def/.endef: ignored."));
515 demand_empty_rest_of_line ();
516 return;
517 }
518
519 /* Skip the file number. */
520 SKIP_WHITESPACE ();
521 get_absolute_expression ();
522 SKIP_WHITESPACE ();
523
524 lineno = get_absolute_expression ();
525
526#ifndef NO_LISTING
527 {
528 extern int listing;
529
530 if (listing)
531 {
cc8a6dd0 532 lineno += coff_line_base - 1;
28428223
ILT
533 listing_source_line (lineno);
534 }
535 }
536#endif
537
538 demand_empty_rest_of_line ();
539
540 add_lineno (frag_now, frag_now_fix (), lineno);
541}
542
7a6284c4
ILT
543/* Handle the .ident pseudo-op. */
544
545static void
a5324a3e 546obj_coff_ident (int ignore ATTRIBUTE_UNUSED)
7a6284c4
ILT
547{
548 segT current_seg = now_seg;
549 subsegT current_subseg = now_subseg;
550
551#ifdef TE_PE
552 {
553 segT sec;
554
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)));
562 }
563#else
564 subseg_new (".comment", 0);
565#endif
566
38a57ae7 567 stringer (8 + 1);
7a6284c4
ILT
568 subseg_set (current_seg, current_subseg);
569}
570
a5324a3e
NC
571/* Handle .def directives.
572
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 :-). */
252b5132
RH
579
580#define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';')
581#define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \
a5324a3e
NC
582 *input_line_pointer == '\t') \
583 input_line_pointer++;
252b5132
RH
584
585static void
a5324a3e 586obj_coff_def (int what ATTRIBUTE_UNUSED)
252b5132 587{
a5324a3e
NC
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. */
252b5132
RH
591 unsigned int symbol_name_length;
592
593 if (def_symbol_in_progress != NULL)
594 {
595 as_warn (_(".def pseudo-op used inside of .def/.endef: ignored."));
596 demand_empty_rest_of_line ();
597 return;
a5324a3e 598 }
252b5132
RH
599
600 SKIP_WHITESPACES ();
601
602 symbol_name = input_line_pointer;
252b5132
RH
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
610
a5324a3e 611 /* Initialize the new symbol. */
252b5132 612 def_symbol_in_progress = symbol_make (symbol_name_copy);
49309057 613 symbol_set_frag (def_symbol_in_progress, &zero_address_frag);
252b5132
RH
614 S_SET_VALUE (def_symbol_in_progress, 0);
615
616 if (S_IS_STRING (def_symbol_in_progress))
617 SF_SET_STRING (def_symbol_in_progress);
618
619 *input_line_pointer = name_end;
620
621 demand_empty_rest_of_line ();
622}
623
624unsigned int dim_index;
625
626static void
a5324a3e 627obj_coff_endef (int ignore ATTRIBUTE_UNUSED)
252b5132 628{
c9900432 629 symbolS *symbolP = NULL;
252b5132 630
252b5132
RH
631 dim_index = 0;
632 if (def_symbol_in_progress == NULL)
633 {
634 as_warn (_(".endef pseudo-op used outside of .def/.endef: ignored."));
635 demand_empty_rest_of_line ();
636 return;
a5324a3e 637 }
252b5132 638
dcd619be 639 /* Set the section number according to storage class. */
252b5132
RH
640 switch (S_GET_STORAGE_CLASS (def_symbol_in_progress))
641 {
642 case C_STRTAG:
643 case C_ENTAG:
644 case C_UNTAG:
645 SF_SET_TAG (def_symbol_in_progress);
a5324a3e 646 /* Fall through. */
252b5132
RH
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;
652
653 case C_EFCN:
dcd619be 654 SF_SET_LOCAL (def_symbol_in_progress); /* Do not emit this symbol. */
a5324a3e 655 /* Fall through. */
252b5132 656 case C_BLOCK:
a5324a3e
NC
657 SF_SET_PROCESS (def_symbol_in_progress); /* Will need processing before writing. */
658 /* Fall through. */
252b5132
RH
659 case C_FCN:
660 {
5a38dc70 661 const char *name;
a5324a3e 662
252b5132
RH
663 S_SET_SEGMENT (def_symbol_in_progress, text_section);
664
49309057 665 name = S_GET_NAME (def_symbol_in_progress);
23dab925 666 if (name[0] == '.' && name[2] == 'f' && name[3] == '\0')
cc8a6dd0 667 {
23dab925
ILT
668 switch (name[1])
669 {
dcd619be 670 case 'b':
23dab925
ILT
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
dcd619be 679 case 'e':
23dab925
ILT
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. */
dcd619be 684 SA_SET_SYM_LNNO (def_symbol_in_progress,
23dab925
ILT
685 (SA_GET_SYM_LNNO (def_symbol_in_progress)
686 + coff_line_base));
687 break;
688#endif
689 }
252b5132
RH
690 }
691 }
692 break;
693
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:
56385375
L
702
703 /* According to the COFF documentation:
704
705 http://osr5doc.sco.com:1996/topics/COFF_SectNumFld.html
706
707 A special section number (-2) marks symbolic debugging symbols,
708 including structure/union/enumeration tag names, typedefs, and
dcd619be 709 the name of the file. A section number of -1 indicates that the
56385375 710 symbol has a value but is not relocatable. Examples of
dcd619be
KH
711 absolute-valued symbols include automatic and register variables,
712 function arguments, and .eos symbols.
56385375
L
713
714 But from Ian Lance Taylor:
715
716 http://sources.redhat.com/ml/binutils/2000-08/msg00202.html
717
718 the actual tools all marked them as section -1. So the GNU COFF
719 assembler follows historical COFF assemblers.
720
721 However, it causes problems for djgpp
722
723 http://sources.redhat.com/ml/binutils/2000-08/msg00210.html
724
725 By defining STRICTCOFF, a COFF port can make the assembler to
dcd619be 726 follow the documented behavior. */
56385375 727#ifdef STRICTCOFF
252b5132
RH
728 case C_MOS:
729 case C_MOE:
730 case C_MOU:
731 case C_EOS:
56385375 732#endif
d1d8ba22 733 SF_SET_DEBUG (def_symbol_in_progress);
252b5132
RH
734 S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
735 break;
736
56385375
L
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
745
252b5132
RH
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:
a5324a3e 753 /* Valid but set somewhere else (s_comm, s_lcomm, colon). */
252b5132
RH
754 break;
755
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;
a5324a3e 763 }
252b5132
RH
764
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
9690c54d
ILT
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. */
252b5132
RH
771
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
dcd619be 778 the debug symbol is a real function reference. */
252b5132
RH
779
780 /* FIXME-SOON If for some reason the definition label/symbol is
781 never seen, this will probably leave an undefined symbol at link
dcd619be 782 time. */
252b5132
RH
783
784 if (S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_EFCN
9690c54d 785 || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_LABEL
a5324a3e
NC
786 || (streq (bfd_get_section_name (stdoutput,
787 S_GET_SEGMENT (def_symbol_in_progress)),
788 "*DEBUG*")
252b5132
RH
789 && !SF_GET_TAG (def_symbol_in_progress))
790 || S_GET_SEGMENT (def_symbol_in_progress) == absolute_section
9690c54d 791 || ! symbol_constant_p (def_symbol_in_progress)
91c4c449 792 || (symbolP = symbol_find (S_GET_NAME (def_symbol_in_progress))) == NULL
9690c54d 793 || SF_GET_TAG (def_symbol_in_progress) != SF_GET_TAG (symbolP))
252b5132 794 {
9690c54d 795 /* If it already is at the end of the symbol list, do nothing */
252b5132 796 if (def_symbol_in_progress != symbol_lastP)
cc8a6dd0 797 {
9690c54d
ILT
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);
cc8a6dd0 801 }
252b5132
RH
802 }
803 else
804 {
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
a5324a3e 809 symbols. [loic] */
252b5132
RH
810
811 /* The debug entry (def_symbol_in_progress) is merged into the
dcd619be 812 previous definition. */
252b5132
RH
813
814 c_symbol_merge (def_symbol_in_progress, symbolP);
815 symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
816
817 def_symbol_in_progress = symbolP;
818
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)
822 {
823 /* For functions, and tags, and static symbols, the symbol
824 *must* be where the debug symbol appears. Move the
dcd619be 825 existing symbol to the current place. */
a5324a3e 826 /* If it already is at the end of the symbol list, do nothing. */
252b5132
RH
827 if (def_symbol_in_progress != symbol_lastP)
828 {
829 symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
830 symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
831 }
832 }
833 }
834
835 if (SF_GET_TAG (def_symbol_in_progress))
836 {
837 symbolS *oldtag;
838
91c4c449 839 oldtag = symbol_find (S_GET_NAME (def_symbol_in_progress));
252b5132
RH
840 if (oldtag == NULL || ! SF_GET_TAG (oldtag))
841 tag_insert (S_GET_NAME (def_symbol_in_progress),
842 def_symbol_in_progress);
843 }
844
845 if (SF_GET_FUNCTION (def_symbol_in_progress))
846 {
252b5132
RH
847 set_function (def_symbol_in_progress);
848 SF_SET_PROCESS (def_symbol_in_progress);
849
850 if (symbolP == NULL)
a5324a3e
NC
851 /* That is, if this is the first time we've seen the
852 function. */
853 symbol_table_insert (def_symbol_in_progress);
854
855 }
252b5132
RH
856
857 def_symbol_in_progress = NULL;
858 demand_empty_rest_of_line ();
859}
860
861static void
a5324a3e 862obj_coff_dim (int ignore ATTRIBUTE_UNUSED)
252b5132
RH
863{
864 int dim_index;
865
866 if (def_symbol_in_progress == NULL)
867 {
868 as_warn (_(".dim pseudo-op used outside of .def/.endef: ignored."));
869 demand_empty_rest_of_line ();
870 return;
a5324a3e 871 }
252b5132
RH
872
873 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
874
875 for (dim_index = 0; dim_index < DIMNUM; dim_index++)
876 {
877 SKIP_WHITESPACES ();
878 SA_SET_SYM_DIMEN (def_symbol_in_progress, dim_index,
879 get_absolute_expression ());
880
881 switch (*input_line_pointer)
882 {
883 case ',':
884 input_line_pointer++;
885 break;
886
887 default:
888 as_warn (_("badly formed .dim directive ignored"));
a5324a3e 889 /* Fall through. */
252b5132
RH
890 case '\n':
891 case ';':
892 dim_index = DIMNUM;
893 break;
894 }
895 }
896
897 demand_empty_rest_of_line ();
898}
899
900static void
a5324a3e 901obj_coff_line (int ignore ATTRIBUTE_UNUSED)
252b5132
RH
902{
903 int this_base;
904
905 if (def_symbol_in_progress == NULL)
906 {
907 /* Probably stabs-style line? */
908 obj_coff_ln (0);
909 return;
910 }
911
912 this_base = get_absolute_expression ();
a5324a3e 913 if (streq (".bf", S_GET_NAME (def_symbol_in_progress)))
252b5132
RH
914 coff_line_base = this_base;
915
916 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
23dab925 917 SA_SET_SYM_LNNO (def_symbol_in_progress, this_base);
252b5132
RH
918
919 demand_empty_rest_of_line ();
920
921#ifndef NO_LISTING
a5324a3e 922 if (streq (".bf", S_GET_NAME (def_symbol_in_progress)))
252b5132
RH
923 {
924 extern int listing;
925
926 if (listing)
23dab925 927 listing_source_line ((unsigned int) this_base);
252b5132
RH
928 }
929#endif
930}
931
932static void
a5324a3e 933obj_coff_size (int ignore ATTRIBUTE_UNUSED)
252b5132
RH
934{
935 if (def_symbol_in_progress == NULL)
936 {
937 as_warn (_(".size pseudo-op used outside of .def/.endef ignored."));
938 demand_empty_rest_of_line ();
939 return;
a5324a3e 940 }
252b5132
RH
941
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 ();
945}
946
947static void
a5324a3e 948obj_coff_scl (int ignore ATTRIBUTE_UNUSED)
252b5132
RH
949{
950 if (def_symbol_in_progress == NULL)
951 {
952 as_warn (_(".scl pseudo-op used outside of .def/.endef ignored."));
953 demand_empty_rest_of_line ();
954 return;
a5324a3e 955 }
252b5132
RH
956
957 S_SET_STORAGE_CLASS (def_symbol_in_progress, get_absolute_expression ());
958 demand_empty_rest_of_line ();
959}
960
961static void
a5324a3e 962obj_coff_tag (int ignore ATTRIBUTE_UNUSED)
252b5132
RH
963{
964 char *symbol_name;
965 char name_end;
966
967 if (def_symbol_in_progress == NULL)
968 {
969 as_warn (_(".tag pseudo-op used outside of .def/.endef ignored."));
970 demand_empty_rest_of_line ();
971 return;
972 }
973
974 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
975 symbol_name = input_line_pointer;
976 name_end = get_symbol_end ();
977
978#ifdef tc_canonicalize_symbol_name
979 symbol_name = tc_canonicalize_symbol_name (symbol_name);
980#endif
981
982 /* Assume that the symbol referred to by .tag is always defined.
dcd619be 983 This was a bad assumption. I've added find_or_make. xoxorich. */
252b5132
RH
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)
a5324a3e 987 as_warn (_("tag not found for .tag %s"), symbol_name);
252b5132
RH
988
989 SF_SET_TAGGED (def_symbol_in_progress);
990 *input_line_pointer = name_end;
991
992 demand_empty_rest_of_line ();
993}
994
995static void
a5324a3e 996obj_coff_type (int ignore ATTRIBUTE_UNUSED)
252b5132
RH
997{
998 if (def_symbol_in_progress == NULL)
999 {
1000 as_warn (_(".type pseudo-op used outside of .def/.endef ignored."));
1001 demand_empty_rest_of_line ();
1002 return;
a5324a3e 1003 }
252b5132
RH
1004
1005 S_SET_DATA_TYPE (def_symbol_in_progress, get_absolute_expression ());
1006
1007 if (ISFCN (S_GET_DATA_TYPE (def_symbol_in_progress)) &&
1008 S_GET_STORAGE_CLASS (def_symbol_in_progress) != C_TPDEF)
a5324a3e 1009 SF_SET_FUNCTION (def_symbol_in_progress);
252b5132
RH
1010
1011 demand_empty_rest_of_line ();
1012}
1013
1014static void
a5324a3e 1015obj_coff_val (int ignore ATTRIBUTE_UNUSED)
252b5132
RH
1016{
1017 if (def_symbol_in_progress == NULL)
1018 {
1019 as_warn (_(".val pseudo-op used outside of .def/.endef ignored."));
1020 demand_empty_rest_of_line ();
1021 return;
a5324a3e 1022 }
252b5132
RH
1023
1024 if (is_name_beginner (*input_line_pointer))
1025 {
1026 char *symbol_name = input_line_pointer;
1027 char name_end = get_symbol_end ();
1028
1029#ifdef tc_canonicalize_symbol_name
1030 symbol_name = tc_canonicalize_symbol_name (symbol_name);
1031#endif
a5324a3e 1032 if (streq (symbol_name, "."))
252b5132 1033 {
a5324a3e 1034 /* If the .val is != from the .def (e.g. statics). */
49309057 1035 symbol_set_frag (def_symbol_in_progress, frag_now);
252b5132 1036 S_SET_VALUE (def_symbol_in_progress, (valueT) frag_now_fix ());
252b5132 1037 }
a5324a3e 1038 else if (! streq (S_GET_NAME (def_symbol_in_progress), symbol_name))
252b5132 1039 {
49309057
ILT
1040 expressionS exp;
1041
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);
252b5132
RH
1047
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);
0561a208
ILT
1052
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. */
252b5132 1058 }
0561a208 1059 /* Otherwise, it is the name of a non debug symbol and its value
dcd619be 1060 will be calculated later. */
252b5132
RH
1061 *input_line_pointer = name_end;
1062 }
1063 else
1064 {
1065 S_SET_VALUE (def_symbol_in_progress, get_absolute_expression ());
a5324a3e 1066 }
252b5132
RH
1067
1068 demand_empty_rest_of_line ();
1069}
1070
977cdf5a
NC
1071#ifdef TE_PE
1072
1073/* Return nonzero if name begins with weak alternate symbol prefix. */
1074
1075static int
1076weak_is_altname (const char * name)
1077{
a5324a3e 1078 return strneq (name, weak_altprefix, sizeof (weak_altprefix) - 1);
977cdf5a
NC
1079}
1080
1081/* Return the name of the alternate symbol
1082 name corresponding to a weak symbol's name. */
1083
1084static const char *
1085weak_name2altname (const char * name)
1086{
1087 char *alt_name;
1088
1089 alt_name = xmalloc (sizeof (weak_altprefix) + strlen (name));
1090 strcpy (alt_name, weak_altprefix);
1091 return strcat (alt_name, name);
1092}
1093
a5324a3e 1094/* Return the name of the weak symbol corresponding to an
708587a4 1095 alternate symbol. */
977cdf5a
NC
1096
1097static const char *
1098weak_altname2name (const char * name)
1099{
1100 char * weak_name;
1101 char * dot;
1102
9c2799c2 1103 gas_assert (weak_is_altname (name));
977cdf5a
NC
1104
1105 weak_name = xstrdup (name + 6);
1106 if ((dot = strchr (weak_name, '.')))
1107 *dot = 0;
1108 return weak_name;
1109}
1110
1111/* Make a weak symbol name unique by
1112 appending the name of an external symbol. */
1113
1114static const char *
1115weak_uniquify (const char * name)
1116{
1117 char *ret;
1118 const char * unique = "";
1119
22ba0981 1120#ifdef TE_PE
977cdf5a
NC
1121 if (an_external_name != NULL)
1122 unique = an_external_name;
1123#endif
9c2799c2 1124 gas_assert (weak_is_altname (name));
977cdf5a
NC
1125
1126 if (strchr (name + sizeof (weak_altprefix), '.'))
1127 return name;
1128
1129 ret = xmalloc (strlen (name) + strlen (unique) + 2);
1130 strcpy (ret, name);
1131 strcat (ret, ".");
1132 strcat (ret, unique);
1133 return ret;
1134}
1135
06e77878
AO
1136void
1137pecoff_obj_set_weak_hook (symbolS *symbolP)
1138{
1139 symbolS *alternateP;
1140
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);
1149
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);
1153
1154 SA_SET_SYM_TAGNDX (symbolP, alternateP);
1155}
1156
1157void
1158pecoff_obj_clear_weak_hook (symbolS *symbolP)
1159{
1160 symbolS *alternateP;
1161
1162 S_SET_STORAGE_CLASS (symbolP, 0);
1163 SA_SET_SYM_FSIZE (symbolP, 0);
1164
1165 alternateP = symbol_find (weak_name2altname (S_GET_NAME (symbolP)));
1166 S_CLEAR_EXTERNAL (alternateP);
1167}
1168
977cdf5a
NC
1169#endif /* TE_PE */
1170
c87db184 1171/* Handle .weak. This is a GNU extension in formats other than PE. */
977cdf5a 1172
c87db184 1173static void
977cdf5a 1174obj_coff_weak (int ignore ATTRIBUTE_UNUSED)
c87db184
CF
1175{
1176 char *name;
1177 int c;
1178 symbolS *symbolP;
1179
1180 do
1181 {
1182 name = input_line_pointer;
1183 c = get_symbol_end ();
1184 if (*name == 0)
1185 {
1186 as_warn (_("badly formed .weak directive ignored"));
1187 ignore_rest_of_line ();
1188 return;
1189 }
977cdf5a 1190 c = 0;
c87db184
CF
1191 symbolP = symbol_find_or_make (name);
1192 *input_line_pointer = c;
1193 SKIP_WHITESPACE ();
c87db184 1194 S_SET_WEAK (symbolP);
c87db184 1195
c87db184
CF
1196 if (c == ',')
1197 {
1198 input_line_pointer++;
1199 SKIP_WHITESPACE ();
1200 if (*input_line_pointer == '\n')
1201 c = '\n';
1202 }
1203
1204 }
1205 while (c == ',');
1206
1207 demand_empty_rest_of_line ();
1208}
1209
252b5132 1210void
a5324a3e 1211coff_obj_read_begin_hook (void)
252b5132 1212{
dcd619be 1213 /* These had better be the same. Usually 18 bytes. */
252b5132
RH
1214 know (sizeof (SYMENT) == sizeof (AUXENT));
1215 know (SYMESZ == AUXESZ);
252b5132
RH
1216 tag_init ();
1217}
1218
252b5132 1219symbolS *coff_last_function;
17fc154e 1220#ifndef OBJ_XCOFF
252b5132 1221static symbolS *coff_last_bf;
17fc154e 1222#endif
252b5132
RH
1223
1224void
a5324a3e 1225coff_frob_symbol (symbolS *symp, int *punt)
252b5132
RH
1226{
1227 static symbolS *last_tagP;
1228 static stack *block_stack;
1229 static symbolS *set_end;
1230 symbolS *next_set_end = NULL;
1231
1232 if (symp == &abs_symbol)
1233 {
1234 *punt = 1;
1235 return;
1236 }
1237
1238 if (current_lineno_sym)
a5324a3e 1239 coff_add_linesym (NULL);
252b5132
RH
1240
1241 if (!block_stack)
1242 block_stack = stack_init (512, sizeof (symbolS*));
1243
252b5132 1244#ifdef TE_PE
977cdf5a
NC
1245 if (S_GET_STORAGE_CLASS (symp) == C_NT_WEAK
1246 && ! S_IS_WEAK (symp)
1247 && weak_is_altname (S_GET_NAME (symp)))
1248 {
1249 /* This is a weak alternate symbol. All processing of
1250 PECOFFweak symbols is done here, through the alternate. */
06e77878
AO
1251 symbolS *weakp = symbol_find_noref (weak_altname2name
1252 (S_GET_NAME (symp)), 1);
977cdf5a 1253
9c2799c2
NC
1254 gas_assert (weakp);
1255 gas_assert (S_GET_NUMBER_AUXILIARY (weakp) == 1);
977cdf5a 1256
06e77878
AO
1257 if (! S_IS_WEAK (weakp))
1258 {
1259 /* The symbol was turned from weak to strong. Discard altname. */
1260 *punt = 1;
1261 return;
1262 }
1263 else if (symbol_equated_p (weakp))
977cdf5a
NC
1264 {
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);
1269
1270 S_CLEAR_EXTERNAL (symp);
1271 *punt = 1;
1272 return;
1273 }
1274 else
1275 {
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)
1279 {
1280 S_SET_STORAGE_CLASS (symp, S_GET_STORAGE_CLASS (weakp));
1281 S_SET_STORAGE_CLASS (weakp, C_NT_WEAK);
1282 }
1283
1284 if (S_IS_DEFINED (weakp))
1285 {
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));
1292 }
1293 else
1294 {
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);
1299 }
1300
1301 S_SET_NAME (symp, weak_uniquify (S_GET_NAME (symp)));
1302 S_SET_STORAGE_CLASS (symp, C_EXT);
1303
1304 S_SET_VALUE (weakp, 0);
1305 S_SET_SEGMENT (weakp, undefined_section);
1306 }
252b5132 1307 }
977cdf5a
NC
1308#else /* TE_PE */
1309 if (S_IS_WEAK (symp))
1310 S_SET_STORAGE_CLASS (symp, C_WEAKEXT);
1311#endif /* TE_PE */
252b5132
RH
1312
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);
1317
1318 if (!SF_GET_DEBUG (symp))
1319 {
bdbe95c8
NC
1320 symbolS * real;
1321
252b5132
RH
1322 if (!SF_GET_LOCAL (symp)
1323 && !SF_GET_STATICS (symp)
39da8128 1324 && S_GET_STORAGE_CLASS (symp) != C_LABEL
a5324a3e 1325 && symbol_constant_p (symp)
06e77878 1326 && (real = symbol_find_noref (S_GET_NAME (symp), 1))
bdbe95c8 1327 && S_GET_STORAGE_CLASS (real) == C_NULL
252b5132
RH
1328 && real != symp)
1329 {
1330 c_symbol_merge (symp, real);
1331 *punt = 1;
39da8128 1332 return;
252b5132 1333 }
bdbe95c8 1334
5e0d736c 1335 if (!S_IS_DEFINED (symp) && !SF_GET_LOCAL (symp))
252b5132 1336 {
9c2799c2 1337 gas_assert (S_GET_VALUE (symp) == 0);
06e77878
AO
1338 if (S_IS_WEAKREFD (symp))
1339 *punt = 1;
1340 else
1341 S_SET_EXTERNAL (symp);
5e0d736c
DD
1342 }
1343 else if (S_GET_STORAGE_CLASS (symp) == C_NULL)
1344 {
1345 if (S_GET_SEGMENT (symp) == text_section
1346 && symp != seg_info (text_section)->sym)
1347 S_SET_STORAGE_CLASS (symp, C_LABEL);
252b5132 1348 else
5e0d736c 1349 S_SET_STORAGE_CLASS (symp, C_STAT);
252b5132 1350 }
bdbe95c8 1351
252b5132
RH
1352 if (SF_GET_PROCESS (symp))
1353 {
1354 if (S_GET_STORAGE_CLASS (symp) == C_BLOCK)
1355 {
a5324a3e 1356 if (streq (S_GET_NAME (symp), ".bb"))
252b5132
RH
1357 stack_push (block_stack, (char *) &symp);
1358 else
1359 {
1360 symbolS *begin;
bdbe95c8 1361
252b5132
RH
1362 begin = *(symbolS **) stack_pop (block_stack);
1363 if (begin == 0)
1364 as_warn (_("mismatched .eb"));
1365 else
1366 next_set_end = begin;
1367 }
1368 }
bdbe95c8 1369
252b5132
RH
1370 if (coff_last_function == 0 && SF_GET_FUNCTION (symp))
1371 {
1372 union internal_auxent *auxp;
bdbe95c8 1373
252b5132
RH
1374 coff_last_function = symp;
1375 if (S_GET_NUMBER_AUXILIARY (symp) < 1)
1376 S_SET_NUMBER_AUXILIARY (symp, 1);
0561a208 1377 auxp = SYM_AUXENT (symp);
252b5132
RH
1378 memset (auxp->x_sym.x_fcnary.x_ary.x_dimen, 0,
1379 sizeof (auxp->x_sym.x_fcnary.x_ary.x_dimen));
1380 }
bdbe95c8 1381
252b5132
RH
1382 if (S_GET_STORAGE_CLASS (symp) == C_EFCN)
1383 {
1384 if (coff_last_function == 0)
161840f9
ILT
1385 as_fatal (_("C_EFCN symbol for %s out of scope"),
1386 S_GET_NAME (symp));
252b5132
RH
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;
1392 }
1393 }
bdbe95c8 1394
252b5132
RH
1395 if (S_IS_EXTERNAL (symp))
1396 S_SET_STORAGE_CLASS (symp, C_EXT);
1397 else if (SF_GET_LOCAL (symp))
1398 *punt = 1;
1399
1400 if (SF_GET_FUNCTION (symp))
49309057 1401 symbol_get_bfdsym (symp)->flags |= BSF_FUNCTION;
252b5132
RH
1402 }
1403
8828d862
ILT
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));
1408
252b5132
RH
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;
1413
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. */
809ffe0d 1417 if (! symbol_used_in_reloc_p (symp)
49309057 1418 && ((symbol_get_bfdsym (symp)->flags & BSF_SECTION_SYM) != 0
670ec21d 1419 || (! (S_IS_EXTERNAL (symp) || S_IS_WEAK (symp))
809ffe0d 1420 && ! symbol_get_tc (symp)->output
252b5132
RH
1421 && S_GET_STORAGE_CLASS (symp) != C_FILE)))
1422 *punt = 1;
1423#endif
1424
1425 if (set_end != (symbolS *) NULL
1426 && ! *punt
49309057 1427 && ((symbol_get_bfdsym (symp)->flags & BSF_NOT_AT_END) != 0
252b5132
RH
1428 || (S_IS_DEFINED (symp)
1429 && ! S_IS_COMMON (symp)
1430 && (! S_IS_EXTERNAL (symp) || SF_GET_FUNCTION (symp)))))
1431 {
1432 SA_SET_SYM_ENDNDX (set_end, symp);
1433 set_end = NULL;
1434 }
1435
a04b544b
ILT
1436 if (next_set_end != NULL)
1437 {
1438 if (set_end != NULL)
20203fb9 1439 as_warn (_("Warning: internal error: forgetting to set endndx of %s"),
a04b544b
ILT
1440 S_GET_NAME (set_end));
1441 set_end = next_set_end;
1442 }
252b5132 1443
8642cce8 1444#ifndef OBJ_XCOFF
252b5132
RH
1445 if (! *punt
1446 && S_GET_STORAGE_CLASS (symp) == C_FCN
a5324a3e 1447 && streq (S_GET_NAME (symp), ".bf"))
252b5132
RH
1448 {
1449 if (coff_last_bf != NULL)
1450 SA_SET_SYM_ENDNDX (coff_last_bf, symp);
1451 coff_last_bf = symp;
1452 }
8642cce8 1453#endif
49309057 1454 if (coffsymbol (symbol_get_bfdsym (symp))->lineno)
252b5132
RH
1455 {
1456 int i;
1457 struct line_no *lptr;
1458 alent *l;
1459
49309057 1460 lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno;
252b5132
RH
1461 for (i = 0; lptr; lptr = lptr->next)
1462 i++;
49309057 1463 lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno;
252b5132
RH
1464
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). */
a5324a3e 1468 l = xmalloc ((i + 2) * sizeof (* l));
49309057 1469 coffsymbol (symbol_get_bfdsym (symp))->lineno = l;
252b5132
RH
1470 l[i + 1].line_number = 0;
1471 l[i + 1].u.sym = NULL;
1472 for (; i > 0; i--)
1473 {
1474 if (lptr->frag)
bea9907b 1475 lptr->l.u.offset += lptr->frag->fr_address / OCTETS_PER_BYTE;
252b5132
RH
1476 l[i] = lptr->l;
1477 lptr = lptr->next;
1478 }
1479 }
1480}
1481
1482void
a5324a3e
NC
1483coff_adjust_section_syms (bfd *abfd ATTRIBUTE_UNUSED,
1484 asection *sec,
1485 void * x ATTRIBUTE_UNUSED)
252b5132
RH
1486{
1487 symbolS *secsym;
1488 segment_info_type *seginfo = seg_info (sec);
1489 int nlnno, nrelocs = 0;
1490
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;
1495
a5324a3e 1496 if (streq (sec->name, ".text"))
252b5132
RH
1497 nlnno = coff_n_line_nos;
1498 else
1499 nlnno = 0;
1500 {
1501 /* @@ Hope that none of the fixups expand to more than one reloc
1502 entry... */
1503 fixS *fixp = seginfo->fix_root;
1504 while (fixp)
1505 {
1506 if (! fixp->fx_done)
1507 nrelocs++;
1508 fixp = fixp->fx_next;
1509 }
1510 }
587aac4e 1511 if (bfd_get_section_size (sec) == 0
252b5132
RH
1512 && nrelocs == 0
1513 && nlnno == 0
1514 && sec != text_section
1515 && sec != data_section
1516 && sec != bss_section)
1517 return;
a5324a3e 1518
252b5132 1519 secsym = section_symbol (sec);
945a1a6b
ILT
1520 /* This is an estimate; we'll plug in the real value using
1521 SET_SECTION_RELOCS later */
252b5132
RH
1522 SA_SET_SCN_NRELOC (secsym, nrelocs);
1523 SA_SET_SCN_NLINNO (secsym, nlnno);
1524}
1525
1526void
a5324a3e 1527coff_frob_file_after_relocs (void)
252b5132 1528{
a5324a3e 1529 bfd_map_over_sections (stdoutput, coff_adjust_section_syms, NULL);
252b5132
RH
1530}
1531
6ff96af6
NC
1532/* Implement the .section pseudo op:
1533 .section name {, "flags"}
1534 ^ ^
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)
63ad59ae 1545 'y' for noread
6ff96af6
NC
1546 But if the argument is not a quoted string, treat it as a
1547 subsegment number.
1548
1549 Note the 'a' flag is silently ignored. This allows the same
1550 .section directive to be parsed in both ELF and COFF formats. */
252b5132
RH
1551
1552void
a5324a3e 1553obj_coff_section (int ignore ATTRIBUTE_UNUSED)
252b5132 1554{
a5324a3e 1555 /* Strip out the section name. */
252b5132
RH
1556 char *section_name;
1557 char c;
1558 char *name;
1559 unsigned int exp;
c9900432 1560 flagword flags, oldflags;
252b5132
RH
1561 asection *sec;
1562
1563 if (flag_mri)
1564 {
1565 char type;
1566
1567 s_mri_sect (&type);
1568 return;
1569 }
1570
1571 section_name = input_line_pointer;
1572 c = get_symbol_end ();
1573
1574 name = xmalloc (input_line_pointer - section_name + 1);
1575 strcpy (name, section_name);
1576
1577 *input_line_pointer = c;
1578
1579 SKIP_WHITESPACE ();
1580
1581 exp = 0;
c9900432 1582 flags = SEC_NO_FLAGS;
252b5132
RH
1583
1584 if (*input_line_pointer == ',')
1585 {
1586 ++input_line_pointer;
1587 SKIP_WHITESPACE ();
1588 if (*input_line_pointer != '"')
1589 exp = get_absolute_expression ();
1590 else
1591 {
422fee64
NC
1592 unsigned char attr;
1593 int readonly_removed = 0;
1594 int load_removed = 0;
1595
1596 while (attr = *++input_line_pointer,
1597 attr != '"'
1598 && ! is_end_of_line[attr])
252b5132 1599 {
422fee64 1600 switch (attr)
252b5132 1601 {
422fee64
NC
1602 case 'b':
1603 /* Uninitialised data section. */
1604 flags |= SEC_ALLOC;
1605 flags &=~ SEC_LOAD;
1606 break;
1607
1608 case 'n':
1609 /* Section not loaded. */
1610 flags &=~ SEC_LOAD;
1611 flags |= SEC_NEVER_LOAD;
1612 load_removed = 1;
1613 break;
1614
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;
e96c5464 1626
422fee64
NC
1627 case 'w':
1628 /* Writable section. */
1629 flags &=~ SEC_READONLY;
1630 readonly_removed = 1;
1631 break;
e96c5464 1632
422fee64
NC
1633 case 'a':
1634 /* Ignore. Here for compatibility with ELF. */
1635 break;
1636
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'
708587a4 1649 attribute in order to be compatible with the MSVC
422fee64
NC
1650 linker. */
1651 if (! readonly_removed)
1652 flags |= SEC_READONLY;
1653 break;
252b5132 1654
63ad59ae
KT
1655 case 'y':
1656 flags |= SEC_COFF_NOREAD | SEC_READONLY;
1657 break;
1658
252b5132
RH
1659 case 'i': /* STYP_INFO */
1660 case 'l': /* STYP_LIB */
1661 case 'o': /* STYP_OVER */
422fee64 1662 as_warn (_("unsupported section attribute '%c'"), attr);
252b5132
RH
1663 break;
1664
1665 default:
422fee64 1666 as_warn (_("unknown section attribute '%c'"), attr);
252b5132
RH
1667 break;
1668 }
252b5132 1669 }
422fee64 1670 if (attr == '"')
252b5132
RH
1671 ++input_line_pointer;
1672 }
1673 }
1674
1675 sec = subseg_new (name, (subsegT) exp);
1676
c9900432
NC
1677 oldflags = bfd_get_section_flags (stdoutput, sec);
1678 if (oldflags == SEC_NO_FLAGS)
252b5132 1679 {
c9900432
NC
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)
1ad5eac0 1683 flags = TC_COFF_SECTION_DEFAULT_ATTRIBUTES;
dcd619be 1684
c9900432
NC
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. */
a5324a3e 1689 if (strneq (name, ".gnu.linkonce", sizeof (".gnu.linkonce") - 1))
cc8a6dd0 1690 flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
c9900432 1691#endif
252b5132
RH
1692
1693 if (! bfd_set_section_flags (stdoutput, sec, flags))
cc8a6dd0
KH
1694 as_warn (_("error setting flags for \"%s\": %s"),
1695 bfd_section_name (stdoutput, sec),
1696 bfd_errmsg (bfd_get_error ()));
c9900432
NC
1697 }
1698 else if (flags != SEC_NO_FLAGS)
1699 {
a5324a3e 1700 /* This section's attributes have already been set. Warn if the
c9900432 1701 attributes don't match. */
5dd0794d 1702 flagword matchflags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
63ad59ae
KT
1703 | SEC_DATA | SEC_COFF_SHARED | SEC_NEVER_LOAD
1704 | SEC_COFF_NOREAD);
c9900432
NC
1705 if ((flags ^ oldflags) & matchflags)
1706 as_warn (_("Ignoring changed section attributes for %s"), name);
252b5132
RH
1707 }
1708
1709 demand_empty_rest_of_line ();
1710}
1711
1712void
a5324a3e 1713coff_adjust_symtab (void)
252b5132
RH
1714{
1715 if (symbol_rootP == NULL
1716 || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
a4528eeb 1717 c_dot_file_symbol ("fake", 0);
252b5132
RH
1718}
1719
1720void
a5324a3e 1721coff_frob_section (segT sec)
252b5132
RH
1722{
1723 segT strsec;
1724 char *p;
1725 fragS *fragp;
1726 bfd_vma size, n_entries, mask;
bea9907b 1727 bfd_vma align_power = (bfd_vma)sec->alignment_power + OCTETS_PER_BYTE_POWER;
252b5132
RH
1728
1729 /* The COFF back end in BFD requires that all section sizes be
bea9907b
TW
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
dcd619be 1733 section alignment, then skip this step, as TICOFF does. */
587aac4e 1734 size = bfd_get_section_size (sec);
bea9907b
TW
1735 mask = ((bfd_vma) 1 << align_power) - 1;
1736#if !defined(TICOFF)
252b5132
RH
1737 if (size & mask)
1738 {
7f788821
NC
1739 bfd_vma new_size;
1740 fragS *last;
dcd619be 1741
7f788821
NC
1742 new_size = (size + mask) & ~mask;
1743 bfd_set_section_size (stdoutput, sec, new_size);
1744
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)
cc8a6dd0 1750 fragp = fragp->fr_next;
7f788821
NC
1751 last->fr_address = size;
1752 fragp->fr_offset += new_size - size;
252b5132 1753 }
bea9907b 1754#endif
252b5132
RH
1755
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. */
bea9907b 1759#ifndef TICOFF
252b5132
RH
1760 if (size != 0
1761 || sec == text_section
1762 || sec == data_section
1763 || sec == bss_section)
bea9907b 1764#endif
252b5132
RH
1765 {
1766 symbolS *secsym = section_symbol (sec);
1767
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);
1772 }
a5324a3e 1773 /* FIXME: These should be in a "stabs.h" file, or maybe as.h. */
252b5132
RH
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
a5324a3e 1780 if (! streq (STAB_STRING_SECTION_NAME, sec->name))
252b5132
RH
1781 return;
1782
1783 strsec = sec;
1784 sec = subseg_get (STAB_SECTION_NAME, 0);
1785 /* size is already rounded up, since other section will be listed first */
587aac4e 1786 size = bfd_get_section_size (strsec);
252b5132 1787
587aac4e 1788 n_entries = bfd_get_section_size (sec) / 12 - 1;
252b5132
RH
1789
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;
9c2799c2 1794 gas_assert (fragp != 0 && fragp->fr_fix >= 12);
252b5132
RH
1795
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);
1800}
1801
1802void
a5324a3e 1803obj_coff_init_stab_section (segT seg)
252b5132
RH
1804{
1805 char *file;
1806 char *p;
1807 char *stabstr_name;
1808 unsigned int stroff;
1809
dcd619be 1810 /* Make space for this first symbol. */
252b5132 1811 p = frag_more (12);
dcd619be 1812 /* Zero it out. */
252b5132
RH
1813 memset (p, 0, 12);
1814 as_where (&file, (unsigned int *) NULL);
a5324a3e 1815 stabstr_name = xmalloc (strlen (seg->name) + 4);
252b5132
RH
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);
1821}
1822
1823#ifdef DEBUG
252b5132 1824const char *
a5324a3e 1825s_get_name (symbolS *s)
252b5132
RH
1826{
1827 return ((s == NULL) ? "(NULL)" : S_GET_NAME (s));
1828}
1829
1830void
a5324a3e 1831symbol_dump (void)
252b5132
RH
1832{
1833 symbolS *symbolP;
1834
1835 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
a5324a3e
NC
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));
252b5132
RH
1842}
1843
1844#endif /* DEBUG */
1845
7be1c489 1846const pseudo_typeS coff_pseudo_table[] =
252b5132 1847{
7be1c489
AM
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},
c1711530
DK
1853#ifdef TE_PE
1854 /* PE provides an enhanced version of .comm with alignment. */
1855 {"comm", obj_coff_comm, 0},
1856#endif /* TE_PE */
7be1c489
AM
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},
f3d2b04b
KT
1880#endif
1881#if defined(SEH_CMDS)
1882 SEH_CMDS
252b5132 1883#endif
7be1c489
AM
1884 {NULL, NULL, 0}
1885};
1886\f
252b5132 1887
7be1c489 1888/* Support for a COFF emulation. */
252b5132
RH
1889
1890static void
7be1c489 1891coff_pop_insert (void)
252b5132 1892{
7be1c489 1893 pop_insert (coff_pseudo_table);
252b5132
RH
1894}
1895
a5324a3e 1896static int
7be1c489 1897coff_separate_stab_sections (void)
a5324a3e 1898{
7be1c489 1899 return 1;
a5324a3e
NC
1900}
1901
7be1c489 1902const struct format_ops coff_format_ops =
252b5132
RH
1903{
1904 bfd_target_coff_flavour,
4c63da97
AM
1905 0, /* dfl_leading_underscore */
1906 1, /* emit_section_symbols */
5110c57e
HPN
1907 0, /* begin */
1908 c_dot_file_symbol,
252b5132 1909 coff_frob_symbol,
4c63da97 1910 0, /* frob_file */
339681c0 1911 0, /* frob_file_before_adjust */
a161fe53 1912 0, /* frob_file_before_fix */
252b5132 1913 coff_frob_file_after_relocs,
4c63da97
AM
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 */
5110c57e 1919 0, /* s_set_other */
4c63da97 1920 0, /* s_get_desc */
5110c57e
HPN
1921 0, /* s_set_desc */
1922 0, /* s_get_type */
1923 0, /* s_set_type */
4c63da97
AM
1924 0, /* copy_symbol_attributes */
1925 0, /* generate_asm_lineno */
1926 0, /* process_stab */
5110c57e
HPN
1927 coff_separate_stab_sections,
1928 obj_coff_init_stab_section,
4c63da97 1929 0, /* sec_sym_ok_for_reloc */
252b5132 1930 coff_pop_insert,
4c63da97 1931 0, /* ecoff_set_ext */
252b5132 1932 coff_obj_read_begin_hook,
4c63da97 1933 coff_obj_symbol_new_hook
252b5132 1934};