]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gas/config/obj-coff.c
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.git] / gas / config / obj-coff.c
CommitLineData
252b5132 1/* coff object file format
82704155 2 Copyright (C) 1989-2019 Free Software Foundation, Inc.
252b5132
RH
3
4 This file is part of GAS.
5
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
ec2655a6 8 the Free Software Foundation; either version 3, or (at your option)
252b5132
RH
9 any later version.
10
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to the Free
4b4da160
NC
18 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
19 02110-1301, USA. */
252b5132
RH
20
21#define OBJ_HEADER "obj-coff.h"
22
23#include "as.h"
31907d5e 24#include "safe-ctype.h"
252b5132
RH
25#include "subsegs.h"
26
977cdf5a
NC
27#ifdef TE_PE
28#include "coff/pe.h"
29#endif
30
85645aed
TG
31#ifdef OBJ_XCOFF
32#include "coff/xcoff.h"
33#endif
34
a5324a3e
NC
35#define streq(a,b) (strcmp ((a), (b)) == 0)
36#define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
37
252b5132
RH
38/* I think this is probably always correct. */
39#ifndef KEEP_RELOC_INFO
40#define KEEP_RELOC_INFO
41#endif
42
7be1c489
AM
43/* obj_coff_section will use this macro to set a new section's
44 attributes when a directive has no valid flags or the "w" flag is
45 used. This default should be appropriate for most. */
b8a9dcab
NC
46#ifndef TC_COFF_SECTION_DEFAULT_ATTRIBUTES
47#define TC_COFF_SECTION_DEFAULT_ATTRIBUTES (SEC_LOAD | SEC_DATA)
48#endif
49
8d28c9d7
AM
50/* This is used to hold the symbol built by a sequence of pseudo-ops
51 from .def and .endef. */
52static symbolS *def_symbol_in_progress;
977cdf5a
NC
53#ifdef TE_PE
54/* PE weak alternate symbols begin with this string. */
55static const char weak_altprefix[] = ".weak.";
56#endif /* TE_PE */
8d28c9d7 57
f3d2b04b
KT
58#include "obj-coff-seh.c"
59
8d28c9d7
AM
60typedef struct
61 {
62 unsigned long chunk_size;
63 unsigned long element_size;
64 unsigned long size;
65 char *data;
66 unsigned long pointer;
67 }
68stack;
69
252b5132 70\f
a5324a3e 71/* Stack stuff. */
252b5132
RH
72
73static stack *
a5324a3e
NC
74stack_init (unsigned long chunk_size,
75 unsigned long element_size)
252b5132
RH
76{
77 stack *st;
78
add39d23
TS
79 st = XNEW (stack);
80 st->data = XNEWVEC (char, chunk_size);
252b5132
RH
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;
add39d23 99 st->data = XRESIZEVEC (char, st->data, st->size);
252b5132
RH
100 }
101 memcpy (st->data + st->pointer, element, st->element_size);
102 st->pointer += st->element_size;
103 return st->data + st->pointer;
104}
105
106static char *
a5324a3e 107stack_pop (stack *st)
252b5132
RH
108{
109 if (st->pointer < st->element_size)
110 {
111 st->pointer = 0;
a5324a3e 112 return NULL;
252b5132
RH
113 }
114 st->pointer -= st->element_size;
115 return st->data + st->pointer;
116}
117\f
a5324a3e 118/* Maintain a list of the tagnames of the structures. */
252b5132
RH
119
120static struct hash_control *tag_hash;
121
122static void
a5324a3e 123tag_init (void)
252b5132
RH
124{
125 tag_hash = hash_new ();
126}
127
128static void
a5324a3e 129tag_insert (const char *name, symbolS *symbolP)
252b5132
RH
130{
131 const char *error_string;
132
133 if ((error_string = hash_jam (tag_hash, name, (char *) symbolP)))
a5324a3e
NC
134 as_fatal (_("Inserting \"%s\" into structure table failed: %s"),
135 name, error_string);
252b5132
RH
136}
137
138static symbolS *
a5324a3e 139tag_find (char *name)
252b5132 140{
252b5132
RH
141 return (symbolS *) hash_find (tag_hash, name);
142}
143
144static symbolS *
a5324a3e 145tag_find_or_make (char *name)
252b5132
RH
146{
147 symbolS *symbolP;
148
149 if ((symbolP = tag_find (name)) == NULL)
150 {
151 symbolP = symbol_new (name, undefined_section,
152 0, &zero_address_frag);
153
154 tag_insert (S_GET_NAME (symbolP), symbolP);
252b5132 155 symbol_table_insert (symbolP);
a5324a3e 156 }
252b5132
RH
157
158 return symbolP;
159}
160
161/* We accept the .bss directive to set the section for backward
162 compatibility with earlier versions of gas. */
163
164static void
a5324a3e 165obj_coff_bss (int ignore ATTRIBUTE_UNUSED)
252b5132
RH
166{
167 if (*input_line_pointer == '\n')
168 subseg_new (".bss", get_absolute_expression ());
169 else
170 s_lcomm (0);
171}
172
c1711530
DK
173#ifdef TE_PE
174/* Called from read.c:s_comm after we've parsed .comm symbol, size.
175 Parse a possible alignment value. */
176
177static symbolS *
178obj_coff_common_parse (int ignore ATTRIBUTE_UNUSED, symbolS *symbolP, addressT size)
179{
180 addressT align = 0;
181
182 if (*input_line_pointer == ',')
183 {
184 align = parse_align (0);
185 if (align == (addressT) -1)
186 return NULL;
187 }
188
189 S_SET_VALUE (symbolP, size);
190 S_SET_EXTERNAL (symbolP);
191 S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
192
193 symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
194
195 /* There is no S_SET_ALIGN (symbolP, align) in COFF/PE.
196 Instead we must add a note to the .drectve section. */
197 if (align)
198 {
199 segT current_seg = now_seg;
200 subsegT current_subseg = now_subseg;
201 flagword oldflags;
202 asection *sec;
203 size_t pfxlen, numlen;
204 char *frag;
205 char numbuff[20];
206
207 sec = subseg_new (".drectve", 0);
208 oldflags = bfd_get_section_flags (stdoutput, sec);
209 if (oldflags == SEC_NO_FLAGS)
210 {
211 if (!bfd_set_section_flags (stdoutput, sec,
212 TC_COFF_SECTION_DEFAULT_ATTRIBUTES))
213 as_warn (_("error setting flags for \"%s\": %s"),
214 bfd_section_name (stdoutput, sec),
215 bfd_errmsg (bfd_get_error ()));
216 }
217
218 /* Emit a string. Note no NUL-termination. */
a7879ef1 219 pfxlen = strlen (" -aligncomm:") + 2 + strlen (S_GET_NAME (symbolP)) + 1;
c1711530
DK
220 numlen = snprintf (numbuff, sizeof (numbuff), "%d", (int) align);
221 frag = frag_more (pfxlen + numlen);
a7879ef1 222 (void) sprintf (frag, " -aligncomm:\"%s\",", S_GET_NAME (symbolP));
c1711530
DK
223 memcpy (frag + pfxlen, numbuff, numlen);
224 /* Restore original subseg. */
225 subseg_set (current_seg, current_subseg);
226 }
227
228 return symbolP;
229}
230
231static void
232obj_coff_comm (int ignore ATTRIBUTE_UNUSED)
233{
234 s_comm_internal (ignore, obj_coff_common_parse);
235}
236#endif /* TE_PE */
237
252b5132
RH
238/* @@ Ick. */
239static segT
a5324a3e 240fetch_coff_debug_section (void)
252b5132
RH
241{
242 static segT debug_section;
a5324a3e 243
252b5132
RH
244 if (!debug_section)
245 {
5a38dc70 246 const asymbol *s;
a5324a3e
NC
247
248 s = bfd_make_debug_symbol (stdoutput, NULL, 0);
9c2799c2 249 gas_assert (s != 0);
252b5132
RH
250 debug_section = s->section;
251 }
252 return debug_section;
253}
254
255void
a5324a3e 256SA_SET_SYM_ENDNDX (symbolS *sym, symbolS *val)
252b5132
RH
257{
258 combined_entry_type *entry, *p;
259
49309057
ILT
260 entry = &coffsymbol (symbol_get_bfdsym (sym))->native[1];
261 p = coffsymbol (symbol_get_bfdsym (val))->native;
252b5132
RH
262 entry->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p = p;
263 entry->fix_end = 1;
264}
265
266static void
a5324a3e 267SA_SET_SYM_TAGNDX (symbolS *sym, symbolS *val)
252b5132
RH
268{
269 combined_entry_type *entry, *p;
270
49309057
ILT
271 entry = &coffsymbol (symbol_get_bfdsym (sym))->native[1];
272 p = coffsymbol (symbol_get_bfdsym (val))->native;
252b5132
RH
273 entry->u.auxent.x_sym.x_tagndx.p = p;
274 entry->fix_tag = 1;
275}
276
277static int
a5324a3e 278S_GET_DATA_TYPE (symbolS *sym)
252b5132 279{
49309057 280 return coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_type;
252b5132
RH
281}
282
283int
a5324a3e 284S_SET_DATA_TYPE (symbolS *sym, int val)
252b5132 285{
49309057 286 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_type = val;
252b5132
RH
287 return val;
288}
289
290int
a5324a3e 291S_GET_STORAGE_CLASS (symbolS *sym)
252b5132 292{
49309057 293 return coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_sclass;
252b5132
RH
294}
295
296int
a5324a3e 297S_SET_STORAGE_CLASS (symbolS *sym, int val)
252b5132 298{
49309057 299 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_sclass = val;
252b5132
RH
300 return val;
301}
302
dcd619be 303/* Merge a debug symbol containing debug information into a normal symbol. */
252b5132 304
a5324a3e
NC
305static void
306c_symbol_merge (symbolS *debug, symbolS *normal)
252b5132
RH
307{
308 S_SET_DATA_TYPE (normal, S_GET_DATA_TYPE (debug));
309 S_SET_STORAGE_CLASS (normal, S_GET_STORAGE_CLASS (debug));
310
311 if (S_GET_NUMBER_AUXILIARY (debug) > S_GET_NUMBER_AUXILIARY (normal))
a5324a3e
NC
312 /* Take the most we have. */
313 S_SET_NUMBER_AUXILIARY (normal, S_GET_NUMBER_AUXILIARY (debug));
252b5132
RH
314
315 if (S_GET_NUMBER_AUXILIARY (debug) > 0)
a5324a3e
NC
316 /* Move all the auxiliary information. */
317 memcpy (SYM_AUXINFO (normal), SYM_AUXINFO (debug),
318 (S_GET_NUMBER_AUXILIARY (debug)
319 * sizeof (*SYM_AUXINFO (debug))));
252b5132 320
dcd619be 321 /* Move the debug flags. */
252b5132
RH
322 SF_SET_DEBUG_FIELD (normal, SF_GET_DEBUG_FIELD (debug));
323}
324
325void
a4528eeb 326c_dot_file_symbol (const char *filename, int appfile ATTRIBUTE_UNUSED)
252b5132
RH
327{
328 symbolS *symbolP;
329
0561a208
ILT
330 /* BFD converts filename to a .file symbol with an aux entry. It
331 also handles chaining. */
252b5132
RH
332 symbolP = symbol_new (filename, bfd_abs_section_ptr, 0, &zero_address_frag);
333
334 S_SET_STORAGE_CLASS (symbolP, C_FILE);
335 S_SET_NUMBER_AUXILIARY (symbolP, 1);
336
49309057 337 symbol_get_bfdsym (symbolP)->flags = BSF_DEBUGGING;
252b5132
RH
338
339#ifndef NO_LISTING
340 {
341 extern int listing;
a5324a3e 342
252b5132 343 if (listing)
a5324a3e 344 listing_source_file (filename);
252b5132
RH
345 }
346#endif
347
a5324a3e 348 /* Make sure that the symbol is first on the symbol chain. */
252b5132
RH
349 if (symbol_rootP != symbolP)
350 {
351 symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
352 symbol_insert (symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP);
a5324a3e 353 }
252b5132
RH
354}
355
a5324a3e 356/* Line number handling. */
252b5132 357
a5324a3e
NC
358struct line_no
359{
252b5132
RH
360 struct line_no *next;
361 fragS *frag;
362 alent l;
363};
364
365int coff_line_base;
366
367/* Symbol of last function, which we should hang line#s off of. */
368static symbolS *line_fsym;
369
370#define in_function() (line_fsym != 0)
371#define clear_function() (line_fsym = 0)
372#define set_function(F) (line_fsym = (F), coff_add_linesym (F))
373
374\f
375void
a5324a3e 376coff_obj_symbol_new_hook (symbolS *symbolP)
252b5132
RH
377{
378 long sz = (OBJ_COFF_MAX_AUXENTRIES + 1) * sizeof (combined_entry_type);
add39d23 379 char * s = XNEWVEC (char, sz);
dcd619be 380
252b5132 381 memset (s, 0, sz);
49309057 382 coffsymbol (symbol_get_bfdsym (symbolP))->native = (combined_entry_type *) s;
a5c71af8 383 coffsymbol (symbol_get_bfdsym (symbolP))->native->is_sym = TRUE;
252b5132
RH
384
385 S_SET_DATA_TYPE (symbolP, T_NULL);
386 S_SET_STORAGE_CLASS (symbolP, 0);
387 S_SET_NUMBER_AUXILIARY (symbolP, 0);
388
389 if (S_IS_STRING (symbolP))
390 SF_SET_STRING (symbolP);
dcd619be 391
252b5132
RH
392 if (S_IS_LOCAL (symbolP))
393 SF_SET_LOCAL (symbolP);
394}
395
6a2b6326
JB
396void
397coff_obj_symbol_clone_hook (symbolS *newsymP, symbolS *orgsymP)
398{
add39d23
TS
399 long elts = OBJ_COFF_MAX_AUXENTRIES + 1;
400 combined_entry_type * s = XNEWVEC (combined_entry_type, elts);
6a2b6326 401
add39d23
TS
402 memcpy (s, coffsymbol (symbol_get_bfdsym (orgsymP))->native,
403 elts * sizeof (combined_entry_type));
6a2b6326
JB
404 coffsymbol (symbol_get_bfdsym (newsymP))->native = s;
405
406 SF_SET (newsymP, SF_GET (orgsymP));
407}
408
252b5132 409\f
a5324a3e 410/* Handle .ln directives. */
252b5132
RH
411
412static symbolS *current_lineno_sym;
413static struct line_no *line_nos;
a5324a3e 414/* FIXME: Blindly assume all .ln directives will be in the .text section. */
252b5132
RH
415int coff_n_line_nos;
416
417static void
a5324a3e 418add_lineno (fragS * frag, addressT offset, int num)
252b5132 419{
add39d23 420 struct line_no * new_line = XNEW (struct line_no);
a5324a3e 421
252b5132 422 if (!current_lineno_sym)
a5324a3e 423 abort ();
6877bb43
TR
424
425#ifndef OBJ_XCOFF
a5324a3e 426 /* The native aix assembler accepts negative line number. */
6877bb43 427
dcd619be 428 if (num <= 0)
e8a3ab75
ILT
429 {
430 /* Zero is used as an end marker in the file. */
b985eaa8
ILT
431 as_warn (_("Line numbers must be positive integers\n"));
432 num = 1;
e8a3ab75 433 }
6877bb43 434#endif /* OBJ_XCOFF */
252b5132
RH
435 new_line->next = line_nos;
436 new_line->frag = frag;
437 new_line->l.line_number = num;
438 new_line->l.u.offset = offset;
439 line_nos = new_line;
440 coff_n_line_nos++;
441}
442
443void
a5324a3e 444coff_add_linesym (symbolS *sym)
252b5132
RH
445{
446 if (line_nos)
447 {
49309057
ILT
448 coffsymbol (symbol_get_bfdsym (current_lineno_sym))->lineno =
449 (alent *) line_nos;
252b5132
RH
450 coff_n_line_nos++;
451 line_nos = 0;
452 }
453 current_lineno_sym = sym;
454}
455
456static void
a5324a3e 457obj_coff_ln (int appline)
252b5132
RH
458{
459 int l;
460
461 if (! appline && def_symbol_in_progress != NULL)
462 {
463 as_warn (_(".ln pseudo-op inside .def/.endef: ignored."));
464 demand_empty_rest_of_line ();
465 return;
466 }
467
468 l = get_absolute_expression ();
252b5132 469
e237d851
NC
470 /* If there is no lineno symbol, treat a .ln
471 directive as if it were a .appline directive. */
472 if (appline || current_lineno_sym == NULL)
252b5132 473 new_logical_line ((char *) NULL, l - 1);
e237d851
NC
474 else
475 add_lineno (frag_now, frag_now_fix (), l);
252b5132
RH
476
477#ifndef NO_LISTING
478 {
479 extern int listing;
480
481 if (listing)
482 {
483 if (! appline)
484 l += coff_line_base - 1;
485 listing_source_line (l);
486 }
487 }
488#endif
489
490 demand_empty_rest_of_line ();
491}
492
28428223
ILT
493/* .loc is essentially the same as .ln; parse it for assembler
494 compatibility. */
495
496static void
a5324a3e 497obj_coff_loc (int ignore ATTRIBUTE_UNUSED)
28428223
ILT
498{
499 int lineno;
500
501 /* FIXME: Why do we need this check? We need it for ECOFF, but why
502 do we need it for COFF? */
503 if (now_seg != text_section)
504 {
505 as_warn (_(".loc outside of .text"));
506 demand_empty_rest_of_line ();
507 return;
508 }
509
510 if (def_symbol_in_progress != NULL)
511 {
512 as_warn (_(".loc pseudo-op inside .def/.endef: ignored."));
513 demand_empty_rest_of_line ();
514 return;
515 }
516
517 /* Skip the file number. */
518 SKIP_WHITESPACE ();
519 get_absolute_expression ();
520 SKIP_WHITESPACE ();
521
522 lineno = get_absolute_expression ();
523
524#ifndef NO_LISTING
525 {
526 extern int listing;
527
528 if (listing)
529 {
cc8a6dd0 530 lineno += coff_line_base - 1;
28428223
ILT
531 listing_source_line (lineno);
532 }
533 }
534#endif
535
536 demand_empty_rest_of_line ();
537
538 add_lineno (frag_now, frag_now_fix (), lineno);
539}
540
7a6284c4
ILT
541/* Handle the .ident pseudo-op. */
542
543static void
a5324a3e 544obj_coff_ident (int ignore ATTRIBUTE_UNUSED)
7a6284c4
ILT
545{
546 segT current_seg = now_seg;
547 subsegT current_subseg = now_subseg;
548
549#ifdef TE_PE
550 {
551 segT sec;
552
553 /* We could put it in .comment, but that creates an extra section
554 that shouldn't be loaded into memory, which requires linker
555 changes... For now, until proven otherwise, use .rdata. */
556 sec = subseg_new (".rdata$zzz", 0);
557 bfd_set_section_flags (stdoutput, sec,
558 ((SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA)
559 & bfd_applicable_section_flags (stdoutput)));
560 }
561#else
562 subseg_new (".comment", 0);
563#endif
564
38a57ae7 565 stringer (8 + 1);
7a6284c4
ILT
566 subseg_set (current_seg, current_subseg);
567}
568
a5324a3e
NC
569/* Handle .def directives.
570
571 One might ask : why can't we symbol_new if the symbol does not
572 already exist and fill it with debug information. Because of
573 the C_EFCN special symbol. It would clobber the value of the
574 function symbol before we have a chance to notice that it is
575 a C_EFCN. And a second reason is that the code is more clear this
576 way. (at least I think it is :-). */
252b5132
RH
577
578#define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';')
579#define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \
a5324a3e
NC
580 *input_line_pointer == '\t') \
581 input_line_pointer++;
252b5132
RH
582
583static void
a5324a3e 584obj_coff_def (int what ATTRIBUTE_UNUSED)
252b5132 585{
a5324a3e
NC
586 char name_end; /* Char after the end of name. */
587 char *symbol_name; /* Name of the debug symbol. */
588 char *symbol_name_copy; /* Temporary copy of the name. */
252b5132
RH
589
590 if (def_symbol_in_progress != NULL)
591 {
592 as_warn (_(".def pseudo-op used inside of .def/.endef: ignored."));
593 demand_empty_rest_of_line ();
594 return;
a5324a3e 595 }
252b5132
RH
596
597 SKIP_WHITESPACES ();
598
d02603dc 599 name_end = get_symbol_name (&symbol_name);
29a2809e 600 symbol_name_copy = xstrdup (symbol_name);
252b5132
RH
601#ifdef tc_canonicalize_symbol_name
602 symbol_name_copy = tc_canonicalize_symbol_name (symbol_name_copy);
603#endif
604
a5324a3e 605 /* Initialize the new symbol. */
252b5132 606 def_symbol_in_progress = symbol_make (symbol_name_copy);
49309057 607 symbol_set_frag (def_symbol_in_progress, &zero_address_frag);
252b5132
RH
608 S_SET_VALUE (def_symbol_in_progress, 0);
609
610 if (S_IS_STRING (def_symbol_in_progress))
611 SF_SET_STRING (def_symbol_in_progress);
612
d02603dc 613 (void) restore_line_pointer (name_end);
252b5132
RH
614
615 demand_empty_rest_of_line ();
616}
617
252b5132 618static void
a5324a3e 619obj_coff_endef (int ignore ATTRIBUTE_UNUSED)
252b5132 620{
c9900432 621 symbolS *symbolP = NULL;
252b5132 622
252b5132
RH
623 if (def_symbol_in_progress == NULL)
624 {
625 as_warn (_(".endef pseudo-op used outside of .def/.endef: ignored."));
626 demand_empty_rest_of_line ();
627 return;
a5324a3e 628 }
252b5132 629
dcd619be 630 /* Set the section number according to storage class. */
252b5132
RH
631 switch (S_GET_STORAGE_CLASS (def_symbol_in_progress))
632 {
633 case C_STRTAG:
634 case C_ENTAG:
635 case C_UNTAG:
636 SF_SET_TAG (def_symbol_in_progress);
a5324a3e 637 /* Fall through. */
252b5132
RH
638 case C_FILE:
639 case C_TPDEF:
640 SF_SET_DEBUG (def_symbol_in_progress);
641 S_SET_SEGMENT (def_symbol_in_progress, fetch_coff_debug_section ());
642 break;
643
644 case C_EFCN:
dcd619be 645 SF_SET_LOCAL (def_symbol_in_progress); /* Do not emit this symbol. */
a5324a3e 646 /* Fall through. */
252b5132 647 case C_BLOCK:
a5324a3e
NC
648 SF_SET_PROCESS (def_symbol_in_progress); /* Will need processing before writing. */
649 /* Fall through. */
252b5132
RH
650 case C_FCN:
651 {
5a38dc70 652 const char *name;
a5324a3e 653
252b5132
RH
654 S_SET_SEGMENT (def_symbol_in_progress, text_section);
655
49309057 656 name = S_GET_NAME (def_symbol_in_progress);
23dab925 657 if (name[0] == '.' && name[2] == 'f' && name[3] == '\0')
cc8a6dd0 658 {
23dab925
ILT
659 switch (name[1])
660 {
dcd619be 661 case 'b':
23dab925
ILT
662 /* .bf */
663 if (! in_function ())
664 as_warn (_("`%s' symbol without preceding function"), name);
665 /* Will need relocating. */
666 SF_SET_PROCESS (def_symbol_in_progress);
667 clear_function ();
668 break;
669#ifdef TE_PE
dcd619be 670 case 'e':
23dab925
ILT
671 /* .ef */
672 /* The MS compilers output the actual endline, not the
673 function-relative one... we want to match without
674 changing the assembler input. */
dcd619be 675 SA_SET_SYM_LNNO (def_symbol_in_progress,
23dab925
ILT
676 (SA_GET_SYM_LNNO (def_symbol_in_progress)
677 + coff_line_base));
678 break;
679#endif
680 }
252b5132
RH
681 }
682 }
683 break;
684
685#ifdef C_AUTOARG
686 case C_AUTOARG:
687#endif /* C_AUTOARG */
688 case C_AUTO:
689 case C_REG:
690 case C_ARG:
691 case C_REGPARM:
692 case C_FIELD:
56385375
L
693
694 /* According to the COFF documentation:
695
696 http://osr5doc.sco.com:1996/topics/COFF_SectNumFld.html
697
698 A special section number (-2) marks symbolic debugging symbols,
699 including structure/union/enumeration tag names, typedefs, and
dcd619be 700 the name of the file. A section number of -1 indicates that the
56385375 701 symbol has a value but is not relocatable. Examples of
dcd619be
KH
702 absolute-valued symbols include automatic and register variables,
703 function arguments, and .eos symbols.
56385375
L
704
705 But from Ian Lance Taylor:
706
707 http://sources.redhat.com/ml/binutils/2000-08/msg00202.html
708
709 the actual tools all marked them as section -1. So the GNU COFF
710 assembler follows historical COFF assemblers.
711
712 However, it causes problems for djgpp
713
714 http://sources.redhat.com/ml/binutils/2000-08/msg00210.html
715
716 By defining STRICTCOFF, a COFF port can make the assembler to
dcd619be 717 follow the documented behavior. */
56385375 718#ifdef STRICTCOFF
252b5132
RH
719 case C_MOS:
720 case C_MOE:
721 case C_MOU:
722 case C_EOS:
56385375 723#endif
d1d8ba22 724 SF_SET_DEBUG (def_symbol_in_progress);
252b5132
RH
725 S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
726 break;
727
56385375
L
728#ifndef STRICTCOFF
729 case C_MOS:
730 case C_MOE:
731 case C_MOU:
732 case C_EOS:
733 S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
734 break;
735#endif
736
252b5132
RH
737 case C_EXT:
738 case C_WEAKEXT:
739#ifdef TE_PE
740 case C_NT_WEAK:
741#endif
742 case C_STAT:
743 case C_LABEL:
a5324a3e 744 /* Valid but set somewhere else (s_comm, s_lcomm, colon). */
252b5132
RH
745 break;
746
747 default:
748 case C_USTATIC:
749 case C_EXTDEF:
750 case C_ULABEL:
751 as_warn (_("unexpected storage class %d"),
752 S_GET_STORAGE_CLASS (def_symbol_in_progress));
753 break;
a5324a3e 754 }
252b5132
RH
755
756 /* Now that we have built a debug symbol, try to find if we should
757 merge with an existing symbol or not. If a symbol is C_EFCN or
9690c54d
ILT
758 absolute_section or untagged SEG_DEBUG it never merges. We also
759 don't merge labels, which are in a different namespace, nor
760 symbols which have not yet been defined since they are typically
761 unique, nor do we merge tags with non-tags. */
252b5132
RH
762
763 /* Two cases for functions. Either debug followed by definition or
764 definition followed by debug. For definition first, we will
765 merge the debug symbol into the definition. For debug first, the
766 lineno entry MUST point to the definition function or else it
767 will point off into space when obj_crawl_symbol_chain() merges
768 the debug symbol into the real symbol. Therefor, let's presume
dcd619be 769 the debug symbol is a real function reference. */
252b5132
RH
770
771 /* FIXME-SOON If for some reason the definition label/symbol is
772 never seen, this will probably leave an undefined symbol at link
dcd619be 773 time. */
252b5132
RH
774
775 if (S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_EFCN
9690c54d 776 || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_LABEL
a5324a3e
NC
777 || (streq (bfd_get_section_name (stdoutput,
778 S_GET_SEGMENT (def_symbol_in_progress)),
779 "*DEBUG*")
252b5132
RH
780 && !SF_GET_TAG (def_symbol_in_progress))
781 || S_GET_SEGMENT (def_symbol_in_progress) == absolute_section
9690c54d 782 || ! symbol_constant_p (def_symbol_in_progress)
91c4c449 783 || (symbolP = symbol_find (S_GET_NAME (def_symbol_in_progress))) == NULL
9690c54d 784 || SF_GET_TAG (def_symbol_in_progress) != SF_GET_TAG (symbolP))
252b5132 785 {
9690c54d 786 /* If it already is at the end of the symbol list, do nothing */
252b5132 787 if (def_symbol_in_progress != symbol_lastP)
cc8a6dd0 788 {
9690c54d
ILT
789 symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
790 symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP,
791 &symbol_lastP);
cc8a6dd0 792 }
252b5132
RH
793 }
794 else
795 {
796 /* This symbol already exists, merge the newly created symbol
797 into the old one. This is not mandatory. The linker can
798 handle duplicate symbols correctly. But I guess that it save
799 a *lot* of space if the assembly file defines a lot of
a5324a3e 800 symbols. [loic] */
252b5132
RH
801
802 /* The debug entry (def_symbol_in_progress) is merged into the
dcd619be 803 previous definition. */
252b5132
RH
804
805 c_symbol_merge (def_symbol_in_progress, symbolP);
806 symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
807
808 def_symbol_in_progress = symbolP;
809
810 if (SF_GET_FUNCTION (def_symbol_in_progress)
811 || SF_GET_TAG (def_symbol_in_progress)
812 || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_STAT)
813 {
814 /* For functions, and tags, and static symbols, the symbol
815 *must* be where the debug symbol appears. Move the
dcd619be 816 existing symbol to the current place. */
a5324a3e 817 /* If it already is at the end of the symbol list, do nothing. */
252b5132
RH
818 if (def_symbol_in_progress != symbol_lastP)
819 {
820 symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
821 symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
822 }
823 }
824 }
825
826 if (SF_GET_TAG (def_symbol_in_progress))
827 {
828 symbolS *oldtag;
829
91c4c449 830 oldtag = symbol_find (S_GET_NAME (def_symbol_in_progress));
252b5132
RH
831 if (oldtag == NULL || ! SF_GET_TAG (oldtag))
832 tag_insert (S_GET_NAME (def_symbol_in_progress),
833 def_symbol_in_progress);
834 }
835
836 if (SF_GET_FUNCTION (def_symbol_in_progress))
837 {
252b5132
RH
838 set_function (def_symbol_in_progress);
839 SF_SET_PROCESS (def_symbol_in_progress);
840
841 if (symbolP == NULL)
a5324a3e
NC
842 /* That is, if this is the first time we've seen the
843 function. */
844 symbol_table_insert (def_symbol_in_progress);
845
846 }
252b5132
RH
847
848 def_symbol_in_progress = NULL;
849 demand_empty_rest_of_line ();
850}
851
852static void
a5324a3e 853obj_coff_dim (int ignore ATTRIBUTE_UNUSED)
252b5132 854{
91d6fa6a 855 int d_index;
252b5132
RH
856
857 if (def_symbol_in_progress == NULL)
858 {
859 as_warn (_(".dim pseudo-op used outside of .def/.endef: ignored."));
860 demand_empty_rest_of_line ();
861 return;
a5324a3e 862 }
252b5132
RH
863
864 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
865
91d6fa6a 866 for (d_index = 0; d_index < DIMNUM; d_index++)
252b5132
RH
867 {
868 SKIP_WHITESPACES ();
91d6fa6a 869 SA_SET_SYM_DIMEN (def_symbol_in_progress, d_index,
252b5132
RH
870 get_absolute_expression ());
871
872 switch (*input_line_pointer)
873 {
874 case ',':
875 input_line_pointer++;
876 break;
877
878 default:
879 as_warn (_("badly formed .dim directive ignored"));
a5324a3e 880 /* Fall through. */
252b5132
RH
881 case '\n':
882 case ';':
91d6fa6a 883 d_index = DIMNUM;
252b5132
RH
884 break;
885 }
886 }
887
888 demand_empty_rest_of_line ();
889}
890
891static void
a5324a3e 892obj_coff_line (int ignore ATTRIBUTE_UNUSED)
252b5132
RH
893{
894 int this_base;
895
896 if (def_symbol_in_progress == NULL)
897 {
898 /* Probably stabs-style line? */
899 obj_coff_ln (0);
900 return;
901 }
902
903 this_base = get_absolute_expression ();
a5324a3e 904 if (streq (".bf", S_GET_NAME (def_symbol_in_progress)))
252b5132
RH
905 coff_line_base = this_base;
906
907 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
23dab925 908 SA_SET_SYM_LNNO (def_symbol_in_progress, this_base);
252b5132
RH
909
910 demand_empty_rest_of_line ();
911
912#ifndef NO_LISTING
a5324a3e 913 if (streq (".bf", S_GET_NAME (def_symbol_in_progress)))
252b5132
RH
914 {
915 extern int listing;
916
917 if (listing)
23dab925 918 listing_source_line ((unsigned int) this_base);
252b5132
RH
919 }
920#endif
921}
922
923static void
a5324a3e 924obj_coff_size (int ignore ATTRIBUTE_UNUSED)
252b5132
RH
925{
926 if (def_symbol_in_progress == NULL)
927 {
33eaf5de 928 as_warn (_(".size pseudo-op used outside of .def/.endef: ignored."));
252b5132
RH
929 demand_empty_rest_of_line ();
930 return;
a5324a3e 931 }
252b5132
RH
932
933 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
934 SA_SET_SYM_SIZE (def_symbol_in_progress, get_absolute_expression ());
935 demand_empty_rest_of_line ();
936}
937
938static void
a5324a3e 939obj_coff_scl (int ignore ATTRIBUTE_UNUSED)
252b5132
RH
940{
941 if (def_symbol_in_progress == NULL)
942 {
33eaf5de 943 as_warn (_(".scl pseudo-op used outside of .def/.endef: ignored."));
252b5132
RH
944 demand_empty_rest_of_line ();
945 return;
a5324a3e 946 }
252b5132
RH
947
948 S_SET_STORAGE_CLASS (def_symbol_in_progress, get_absolute_expression ());
949 demand_empty_rest_of_line ();
950}
951
952static void
a5324a3e 953obj_coff_tag (int ignore ATTRIBUTE_UNUSED)
252b5132
RH
954{
955 char *symbol_name;
956 char name_end;
957
958 if (def_symbol_in_progress == NULL)
959 {
33eaf5de 960 as_warn (_(".tag pseudo-op used outside of .def/.endef: ignored."));
252b5132
RH
961 demand_empty_rest_of_line ();
962 return;
963 }
964
965 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
d02603dc 966 name_end = get_symbol_name (&symbol_name);
252b5132
RH
967
968#ifdef tc_canonicalize_symbol_name
969 symbol_name = tc_canonicalize_symbol_name (symbol_name);
970#endif
971
972 /* Assume that the symbol referred to by .tag is always defined.
dcd619be 973 This was a bad assumption. I've added find_or_make. xoxorich. */
252b5132
RH
974 SA_SET_SYM_TAGNDX (def_symbol_in_progress,
975 tag_find_or_make (symbol_name));
976 if (SA_GET_SYM_TAGNDX (def_symbol_in_progress) == 0L)
a5324a3e 977 as_warn (_("tag not found for .tag %s"), symbol_name);
252b5132
RH
978
979 SF_SET_TAGGED (def_symbol_in_progress);
252b5132 980
d02603dc 981 (void) restore_line_pointer (name_end);
252b5132
RH
982 demand_empty_rest_of_line ();
983}
984
985static void
a5324a3e 986obj_coff_type (int ignore ATTRIBUTE_UNUSED)
252b5132
RH
987{
988 if (def_symbol_in_progress == NULL)
989 {
33eaf5de 990 as_warn (_(".type pseudo-op used outside of .def/.endef: ignored."));
252b5132
RH
991 demand_empty_rest_of_line ();
992 return;
a5324a3e 993 }
252b5132
RH
994
995 S_SET_DATA_TYPE (def_symbol_in_progress, get_absolute_expression ());
996
997 if (ISFCN (S_GET_DATA_TYPE (def_symbol_in_progress)) &&
998 S_GET_STORAGE_CLASS (def_symbol_in_progress) != C_TPDEF)
a5324a3e 999 SF_SET_FUNCTION (def_symbol_in_progress);
252b5132
RH
1000
1001 demand_empty_rest_of_line ();
1002}
1003
1004static void
a5324a3e 1005obj_coff_val (int ignore ATTRIBUTE_UNUSED)
252b5132
RH
1006{
1007 if (def_symbol_in_progress == NULL)
1008 {
33eaf5de 1009 as_warn (_(".val pseudo-op used outside of .def/.endef: ignored."));
252b5132
RH
1010 demand_empty_rest_of_line ();
1011 return;
a5324a3e 1012 }
252b5132
RH
1013
1014 if (is_name_beginner (*input_line_pointer))
1015 {
d02603dc
NC
1016 char *symbol_name;
1017 char name_end = get_symbol_name (&symbol_name);
252b5132
RH
1018
1019#ifdef tc_canonicalize_symbol_name
d02603dc 1020 symbol_name = tc_canonicalize_symbol_name (symbol_name);
252b5132 1021#endif
a5324a3e 1022 if (streq (symbol_name, "."))
252b5132 1023 {
a5324a3e 1024 /* If the .val is != from the .def (e.g. statics). */
49309057 1025 symbol_set_frag (def_symbol_in_progress, frag_now);
252b5132 1026 S_SET_VALUE (def_symbol_in_progress, (valueT) frag_now_fix ());
252b5132 1027 }
a5324a3e 1028 else if (! streq (S_GET_NAME (def_symbol_in_progress), symbol_name))
252b5132 1029 {
49309057
ILT
1030 expressionS exp;
1031
1032 exp.X_op = O_symbol;
1033 exp.X_add_symbol = symbol_find_or_make (symbol_name);
1034 exp.X_op_symbol = NULL;
1035 exp.X_add_number = 0;
1036 symbol_set_value_expression (def_symbol_in_progress, &exp);
252b5132
RH
1037
1038 /* If the segment is undefined when the forward reference is
1039 resolved, then copy the segment id from the forward
1040 symbol. */
1041 SF_SET_GET_SEGMENT (def_symbol_in_progress);
0561a208
ILT
1042
1043 /* FIXME: gcc can generate address expressions here in
1044 unusual cases (search for "obscure" in sdbout.c). We
1045 just ignore the offset here, thus generating incorrect
1046 debugging information. We ignore the rest of the line
1047 just below. */
252b5132 1048 }
0561a208 1049 /* Otherwise, it is the name of a non debug symbol and its value
dcd619be 1050 will be calculated later. */
d02603dc 1051 (void) restore_line_pointer (name_end);
252b5132
RH
1052 }
1053 else
1054 {
1055 S_SET_VALUE (def_symbol_in_progress, get_absolute_expression ());
a5324a3e 1056 }
252b5132
RH
1057
1058 demand_empty_rest_of_line ();
1059}
1060
977cdf5a
NC
1061#ifdef TE_PE
1062
1063/* Return nonzero if name begins with weak alternate symbol prefix. */
1064
1065static int
1066weak_is_altname (const char * name)
1067{
a5324a3e 1068 return strneq (name, weak_altprefix, sizeof (weak_altprefix) - 1);
977cdf5a
NC
1069}
1070
1071/* Return the name of the alternate symbol
1072 name corresponding to a weak symbol's name. */
1073
1074static const char *
1075weak_name2altname (const char * name)
1076{
29a2809e 1077 return concat (weak_altprefix, name, (char *) NULL);
977cdf5a
NC
1078}
1079
a5324a3e 1080/* Return the name of the weak symbol corresponding to an
708587a4 1081 alternate symbol. */
977cdf5a
NC
1082
1083static const char *
1084weak_altname2name (const char * name)
1085{
9c2799c2 1086 gas_assert (weak_is_altname (name));
b851162a 1087 return xstrdup (name + 6);
977cdf5a
NC
1088}
1089
1090/* Make a weak symbol name unique by
1091 appending the name of an external symbol. */
1092
1093static const char *
1094weak_uniquify (const char * name)
1095{
977cdf5a
NC
1096 const char * unique = "";
1097
22ba0981 1098#ifdef TE_PE
977cdf5a
NC
1099 if (an_external_name != NULL)
1100 unique = an_external_name;
1101#endif
9c2799c2 1102 gas_assert (weak_is_altname (name));
977cdf5a 1103
29a2809e 1104 return concat (name, ".", unique, (char *) NULL);
977cdf5a
NC
1105}
1106
06e77878
AO
1107void
1108pecoff_obj_set_weak_hook (symbolS *symbolP)
1109{
1110 symbolS *alternateP;
1111
1112 /* See _Microsoft Portable Executable and Common Object
1113 File Format Specification_, section 5.5.3.
1114 Create a symbol representing the alternate value.
1115 coff_frob_symbol will set the value of this symbol from
1116 the value of the weak symbol itself. */
1117 S_SET_STORAGE_CLASS (symbolP, C_NT_WEAK);
1118 S_SET_NUMBER_AUXILIARY (symbolP, 1);
1119 SA_SET_SYM_FSIZE (symbolP, IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY);
1120
1121 alternateP = symbol_find_or_make (weak_name2altname (S_GET_NAME (symbolP)));
1122 S_SET_EXTERNAL (alternateP);
1123 S_SET_STORAGE_CLASS (alternateP, C_NT_WEAK);
1124
1125 SA_SET_SYM_TAGNDX (symbolP, alternateP);
1126}
1127
1128void
1129pecoff_obj_clear_weak_hook (symbolS *symbolP)
1130{
1131 symbolS *alternateP;
1132
1133 S_SET_STORAGE_CLASS (symbolP, 0);
1134 SA_SET_SYM_FSIZE (symbolP, 0);
1135
1136 alternateP = symbol_find (weak_name2altname (S_GET_NAME (symbolP)));
1137 S_CLEAR_EXTERNAL (alternateP);
1138}
1139
977cdf5a
NC
1140#endif /* TE_PE */
1141
c87db184 1142/* Handle .weak. This is a GNU extension in formats other than PE. */
977cdf5a 1143
c87db184 1144static void
977cdf5a 1145obj_coff_weak (int ignore ATTRIBUTE_UNUSED)
c87db184
CF
1146{
1147 char *name;
1148 int c;
1149 symbolS *symbolP;
1150
1151 do
1152 {
d02603dc 1153 c = get_symbol_name (&name);
c87db184
CF
1154 if (*name == 0)
1155 {
1156 as_warn (_("badly formed .weak directive ignored"));
1157 ignore_rest_of_line ();
1158 return;
1159 }
977cdf5a 1160 c = 0;
c87db184
CF
1161 symbolP = symbol_find_or_make (name);
1162 *input_line_pointer = c;
d02603dc 1163 SKIP_WHITESPACE_AFTER_NAME ();
c87db184 1164 S_SET_WEAK (symbolP);
c87db184 1165
c87db184
CF
1166 if (c == ',')
1167 {
1168 input_line_pointer++;
1169 SKIP_WHITESPACE ();
1170 if (*input_line_pointer == '\n')
1171 c = '\n';
1172 }
1173
1174 }
1175 while (c == ',');
1176
1177 demand_empty_rest_of_line ();
1178}
1179
252b5132 1180void
a5324a3e 1181coff_obj_read_begin_hook (void)
252b5132 1182{
dcd619be 1183 /* These had better be the same. Usually 18 bytes. */
252b5132
RH
1184 know (sizeof (SYMENT) == sizeof (AUXENT));
1185 know (SYMESZ == AUXESZ);
252b5132
RH
1186 tag_init ();
1187}
1188
252b5132 1189symbolS *coff_last_function;
17fc154e 1190#ifndef OBJ_XCOFF
252b5132 1191static symbolS *coff_last_bf;
17fc154e 1192#endif
252b5132
RH
1193
1194void
a5324a3e 1195coff_frob_symbol (symbolS *symp, int *punt)
252b5132
RH
1196{
1197 static symbolS *last_tagP;
1198 static stack *block_stack;
1199 static symbolS *set_end;
1200 symbolS *next_set_end = NULL;
1201
1202 if (symp == &abs_symbol)
1203 {
1204 *punt = 1;
1205 return;
1206 }
1207
1208 if (current_lineno_sym)
a5324a3e 1209 coff_add_linesym (NULL);
252b5132
RH
1210
1211 if (!block_stack)
1212 block_stack = stack_init (512, sizeof (symbolS*));
1213
252b5132 1214#ifdef TE_PE
977cdf5a
NC
1215 if (S_GET_STORAGE_CLASS (symp) == C_NT_WEAK
1216 && ! S_IS_WEAK (symp)
1217 && weak_is_altname (S_GET_NAME (symp)))
1218 {
1219 /* This is a weak alternate symbol. All processing of
1220 PECOFFweak symbols is done here, through the alternate. */
06e77878
AO
1221 symbolS *weakp = symbol_find_noref (weak_altname2name
1222 (S_GET_NAME (symp)), 1);
977cdf5a 1223
9c2799c2
NC
1224 gas_assert (weakp);
1225 gas_assert (S_GET_NUMBER_AUXILIARY (weakp) == 1);
977cdf5a 1226
06e77878
AO
1227 if (! S_IS_WEAK (weakp))
1228 {
1229 /* The symbol was turned from weak to strong. Discard altname. */
1230 *punt = 1;
1231 return;
1232 }
1233 else if (symbol_equated_p (weakp))
977cdf5a
NC
1234 {
1235 /* The weak symbol has an alternate specified; symp is unneeded. */
1236 S_SET_STORAGE_CLASS (weakp, C_NT_WEAK);
1237 SA_SET_SYM_TAGNDX (weakp,
1238 symbol_get_value_expression (weakp)->X_add_symbol);
1239
1240 S_CLEAR_EXTERNAL (symp);
1241 *punt = 1;
1242 return;
1243 }
1244 else
1245 {
1246 /* The weak symbol has been assigned an alternate value.
1247 Copy this value to symp, and set symp as weakp's alternate. */
1248 if (S_GET_STORAGE_CLASS (weakp) != C_NT_WEAK)
1249 {
1250 S_SET_STORAGE_CLASS (symp, S_GET_STORAGE_CLASS (weakp));
1251 S_SET_STORAGE_CLASS (weakp, C_NT_WEAK);
1252 }
1253
1254 if (S_IS_DEFINED (weakp))
1255 {
1256 /* This is a defined weak symbol. Copy value information
1257 from the weak symbol itself to the alternate symbol. */
1258 symbol_set_value_expression (symp,
1259 symbol_get_value_expression (weakp));
1260 symbol_set_frag (symp, symbol_get_frag (weakp));
1261 S_SET_SEGMENT (symp, S_GET_SEGMENT (weakp));
1262 }
1263 else
1264 {
1265 /* This is an undefined weak symbol.
1266 Define the alternate symbol to zero. */
1267 S_SET_VALUE (symp, 0);
1268 S_SET_SEGMENT (symp, absolute_section);
1269 }
1270
1271 S_SET_NAME (symp, weak_uniquify (S_GET_NAME (symp)));
1272 S_SET_STORAGE_CLASS (symp, C_EXT);
1273
1274 S_SET_VALUE (weakp, 0);
1275 S_SET_SEGMENT (weakp, undefined_section);
1276 }
252b5132 1277 }
977cdf5a
NC
1278#else /* TE_PE */
1279 if (S_IS_WEAK (symp))
1280 S_SET_STORAGE_CLASS (symp, C_WEAKEXT);
1281#endif /* TE_PE */
252b5132
RH
1282
1283 if (!S_IS_DEFINED (symp)
1284 && !S_IS_WEAK (symp)
1285 && S_GET_STORAGE_CLASS (symp) != C_STAT)
1286 S_SET_STORAGE_CLASS (symp, C_EXT);
1287
1288 if (!SF_GET_DEBUG (symp))
1289 {
bdbe95c8
NC
1290 symbolS * real;
1291
252b5132
RH
1292 if (!SF_GET_LOCAL (symp)
1293 && !SF_GET_STATICS (symp)
39da8128 1294 && S_GET_STORAGE_CLASS (symp) != C_LABEL
a5324a3e 1295 && symbol_constant_p (symp)
06e77878 1296 && (real = symbol_find_noref (S_GET_NAME (symp), 1))
bdbe95c8 1297 && S_GET_STORAGE_CLASS (real) == C_NULL
252b5132
RH
1298 && real != symp)
1299 {
1300 c_symbol_merge (symp, real);
1301 *punt = 1;
39da8128 1302 return;
252b5132 1303 }
bdbe95c8 1304
5e0d736c 1305 if (!S_IS_DEFINED (symp) && !SF_GET_LOCAL (symp))
252b5132 1306 {
9c2799c2 1307 gas_assert (S_GET_VALUE (symp) == 0);
06e77878
AO
1308 if (S_IS_WEAKREFD (symp))
1309 *punt = 1;
1310 else
1311 S_SET_EXTERNAL (symp);
5e0d736c
DD
1312 }
1313 else if (S_GET_STORAGE_CLASS (symp) == C_NULL)
1314 {
1315 if (S_GET_SEGMENT (symp) == text_section
1316 && symp != seg_info (text_section)->sym)
1317 S_SET_STORAGE_CLASS (symp, C_LABEL);
252b5132 1318 else
5e0d736c 1319 S_SET_STORAGE_CLASS (symp, C_STAT);
252b5132 1320 }
bdbe95c8 1321
252b5132
RH
1322 if (SF_GET_PROCESS (symp))
1323 {
1324 if (S_GET_STORAGE_CLASS (symp) == C_BLOCK)
1325 {
a5324a3e 1326 if (streq (S_GET_NAME (symp), ".bb"))
252b5132
RH
1327 stack_push (block_stack, (char *) &symp);
1328 else
1329 {
1330 symbolS *begin;
bdbe95c8 1331
252b5132
RH
1332 begin = *(symbolS **) stack_pop (block_stack);
1333 if (begin == 0)
1334 as_warn (_("mismatched .eb"));
1335 else
1336 next_set_end = begin;
1337 }
1338 }
bdbe95c8 1339
c207c2c6
KT
1340 if (coff_last_function == 0 && SF_GET_FUNCTION (symp)
1341 && S_IS_DEFINED (symp))
252b5132
RH
1342 {
1343 union internal_auxent *auxp;
bdbe95c8 1344
252b5132
RH
1345 coff_last_function = symp;
1346 if (S_GET_NUMBER_AUXILIARY (symp) < 1)
1347 S_SET_NUMBER_AUXILIARY (symp, 1);
0561a208 1348 auxp = SYM_AUXENT (symp);
252b5132
RH
1349 memset (auxp->x_sym.x_fcnary.x_ary.x_dimen, 0,
1350 sizeof (auxp->x_sym.x_fcnary.x_ary.x_dimen));
1351 }
bdbe95c8 1352
c207c2c6
KT
1353 if (S_GET_STORAGE_CLASS (symp) == C_EFCN
1354 && S_IS_DEFINED (symp))
252b5132
RH
1355 {
1356 if (coff_last_function == 0)
161840f9
ILT
1357 as_fatal (_("C_EFCN symbol for %s out of scope"),
1358 S_GET_NAME (symp));
252b5132
RH
1359 SA_SET_SYM_FSIZE (coff_last_function,
1360 (long) (S_GET_VALUE (symp)
1361 - S_GET_VALUE (coff_last_function)));
1362 next_set_end = coff_last_function;
1363 coff_last_function = 0;
1364 }
1365 }
bdbe95c8 1366
252b5132
RH
1367 if (S_IS_EXTERNAL (symp))
1368 S_SET_STORAGE_CLASS (symp, C_EXT);
1369 else if (SF_GET_LOCAL (symp))
1370 *punt = 1;
1371
1372 if (SF_GET_FUNCTION (symp))
49309057 1373 symbol_get_bfdsym (symp)->flags |= BSF_FUNCTION;
252b5132
RH
1374 }
1375
8828d862
ILT
1376 /* Double check weak symbols. */
1377 if (S_IS_WEAK (symp) && S_IS_COMMON (symp))
1378 as_bad (_("Symbol `%s' can not be both weak and common"),
1379 S_GET_NAME (symp));
1380
252b5132
RH
1381 if (SF_GET_TAG (symp))
1382 last_tagP = symp;
1383 else if (S_GET_STORAGE_CLASS (symp) == C_EOS)
1384 next_set_end = last_tagP;
1385
1386#ifdef OBJ_XCOFF
1387 /* This is pretty horrible, but we have to set *punt correctly in
1388 order to call SA_SET_SYM_ENDNDX correctly. */
809ffe0d 1389 if (! symbol_used_in_reloc_p (symp)
49309057 1390 && ((symbol_get_bfdsym (symp)->flags & BSF_SECTION_SYM) != 0
670ec21d 1391 || (! (S_IS_EXTERNAL (symp) || S_IS_WEAK (symp))
809ffe0d 1392 && ! symbol_get_tc (symp)->output
252b5132
RH
1393 && S_GET_STORAGE_CLASS (symp) != C_FILE)))
1394 *punt = 1;
1395#endif
1396
1397 if (set_end != (symbolS *) NULL
1398 && ! *punt
49309057 1399 && ((symbol_get_bfdsym (symp)->flags & BSF_NOT_AT_END) != 0
252b5132
RH
1400 || (S_IS_DEFINED (symp)
1401 && ! S_IS_COMMON (symp)
1402 && (! S_IS_EXTERNAL (symp) || SF_GET_FUNCTION (symp)))))
1403 {
1404 SA_SET_SYM_ENDNDX (set_end, symp);
1405 set_end = NULL;
1406 }
1407
a04b544b
ILT
1408 if (next_set_end != NULL)
1409 {
1410 if (set_end != NULL)
20203fb9 1411 as_warn (_("Warning: internal error: forgetting to set endndx of %s"),
a04b544b
ILT
1412 S_GET_NAME (set_end));
1413 set_end = next_set_end;
1414 }
252b5132 1415
8642cce8 1416#ifndef OBJ_XCOFF
252b5132
RH
1417 if (! *punt
1418 && S_GET_STORAGE_CLASS (symp) == C_FCN
a5324a3e 1419 && streq (S_GET_NAME (symp), ".bf"))
252b5132
RH
1420 {
1421 if (coff_last_bf != NULL)
1422 SA_SET_SYM_ENDNDX (coff_last_bf, symp);
1423 coff_last_bf = symp;
1424 }
8642cce8 1425#endif
49309057 1426 if (coffsymbol (symbol_get_bfdsym (symp))->lineno)
252b5132
RH
1427 {
1428 int i;
1429 struct line_no *lptr;
1430 alent *l;
1431
49309057 1432 lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno;
252b5132
RH
1433 for (i = 0; lptr; lptr = lptr->next)
1434 i++;
49309057 1435 lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno;
252b5132
RH
1436
1437 /* We need i entries for line numbers, plus 1 for the first
1438 entry which BFD will override, plus 1 for the last zero
1439 entry (a marker for BFD). */
add39d23 1440 l = XNEWVEC (alent, (i + 2));
49309057 1441 coffsymbol (symbol_get_bfdsym (symp))->lineno = l;
252b5132
RH
1442 l[i + 1].line_number = 0;
1443 l[i + 1].u.sym = NULL;
1444 for (; i > 0; i--)
1445 {
1446 if (lptr->frag)
bea9907b 1447 lptr->l.u.offset += lptr->frag->fr_address / OCTETS_PER_BYTE;
252b5132
RH
1448 l[i] = lptr->l;
1449 lptr = lptr->next;
1450 }
1451 }
1452}
1453
1454void
a5324a3e
NC
1455coff_adjust_section_syms (bfd *abfd ATTRIBUTE_UNUSED,
1456 asection *sec,
1457 void * x ATTRIBUTE_UNUSED)
252b5132
RH
1458{
1459 symbolS *secsym;
1460 segment_info_type *seginfo = seg_info (sec);
1461 int nlnno, nrelocs = 0;
1462
1463 /* RS/6000 gas creates a .debug section manually in ppc_frob_file in
1464 tc-ppc.c. Do not get confused by it. */
1465 if (seginfo == NULL)
1466 return;
1467
a5324a3e 1468 if (streq (sec->name, ".text"))
252b5132
RH
1469 nlnno = coff_n_line_nos;
1470 else
1471 nlnno = 0;
1472 {
1473 /* @@ Hope that none of the fixups expand to more than one reloc
1474 entry... */
1475 fixS *fixp = seginfo->fix_root;
1476 while (fixp)
1477 {
1478 if (! fixp->fx_done)
1479 nrelocs++;
1480 fixp = fixp->fx_next;
1481 }
1482 }
587aac4e 1483 if (bfd_get_section_size (sec) == 0
252b5132
RH
1484 && nrelocs == 0
1485 && nlnno == 0
1486 && sec != text_section
1487 && sec != data_section
1488 && sec != bss_section)
1489 return;
a5324a3e 1490
252b5132 1491 secsym = section_symbol (sec);
945a1a6b
ILT
1492 /* This is an estimate; we'll plug in the real value using
1493 SET_SECTION_RELOCS later */
252b5132
RH
1494 SA_SET_SCN_NRELOC (secsym, nrelocs);
1495 SA_SET_SCN_NLINNO (secsym, nlnno);
1496}
1497
1498void
a5324a3e 1499coff_frob_file_after_relocs (void)
252b5132 1500{
a5324a3e 1501 bfd_map_over_sections (stdoutput, coff_adjust_section_syms, NULL);
252b5132
RH
1502}
1503
6ff96af6
NC
1504/* Implement the .section pseudo op:
1505 .section name {, "flags"}
1506 ^ ^
1507 | +--- optional flags: 'b' for bss
1508 | 'i' for info
1509 +-- section name 'l' for lib
1510 'n' for noload
1511 'o' for over
1512 'w' for data
1513 'd' (apparently m88k for data)
c3489828 1514 'e' for exclude
6ff96af6
NC
1515 'x' for text
1516 'r' for read-only data
1517 's' for shared data (PE)
63ad59ae 1518 'y' for noread
31907d5e 1519 '0' - '9' for power-of-two alignment (GNU extension).
6ff96af6
NC
1520 But if the argument is not a quoted string, treat it as a
1521 subsegment number.
1522
1523 Note the 'a' flag is silently ignored. This allows the same
1524 .section directive to be parsed in both ELF and COFF formats. */
252b5132
RH
1525
1526void
a5324a3e 1527obj_coff_section (int ignore ATTRIBUTE_UNUSED)
252b5132 1528{
a5324a3e 1529 /* Strip out the section name. */
252b5132
RH
1530 char *section_name;
1531 char c;
31907d5e 1532 int alignment = -1;
252b5132
RH
1533 char *name;
1534 unsigned int exp;
c9900432 1535 flagword flags, oldflags;
252b5132
RH
1536 asection *sec;
1537
1538 if (flag_mri)
1539 {
1540 char type;
1541
1542 s_mri_sect (&type);
1543 return;
1544 }
1545
d02603dc 1546 c = get_symbol_name (&section_name);
29a2809e 1547 name = xmemdup0 (section_name, input_line_pointer - section_name);
252b5132 1548 *input_line_pointer = c;
d02603dc 1549 SKIP_WHITESPACE_AFTER_NAME ();
252b5132
RH
1550
1551 exp = 0;
c9900432 1552 flags = SEC_NO_FLAGS;
252b5132
RH
1553
1554 if (*input_line_pointer == ',')
1555 {
1556 ++input_line_pointer;
1557 SKIP_WHITESPACE ();
1558 if (*input_line_pointer != '"')
1559 exp = get_absolute_expression ();
1560 else
1561 {
422fee64
NC
1562 unsigned char attr;
1563 int readonly_removed = 0;
1564 int load_removed = 0;
1565
1566 while (attr = *++input_line_pointer,
1567 attr != '"'
1568 && ! is_end_of_line[attr])
252b5132 1569 {
31907d5e
DK
1570 if (ISDIGIT (attr))
1571 {
1572 alignment = attr - '0';
1573 continue;
1574 }
422fee64 1575 switch (attr)
252b5132 1576 {
c3489828
KT
1577 case 'e':
1578 /* Exclude section from linking. */
1579 flags |= SEC_EXCLUDE;
1580 break;
1581
422fee64
NC
1582 case 'b':
1583 /* Uninitialised data section. */
1584 flags |= SEC_ALLOC;
1585 flags &=~ SEC_LOAD;
1586 break;
1587
1588 case 'n':
1589 /* Section not loaded. */
1590 flags &=~ SEC_LOAD;
1591 flags |= SEC_NEVER_LOAD;
1592 load_removed = 1;
1593 break;
1594
1595 case 's':
1596 /* Shared section. */
1597 flags |= SEC_COFF_SHARED;
1598 /* Fall through. */
1599 case 'd':
1600 /* Data section. */
1601 flags |= SEC_DATA;
1602 if (! load_removed)
1603 flags |= SEC_LOAD;
1604 flags &=~ SEC_READONLY;
1605 break;
e96c5464 1606
422fee64
NC
1607 case 'w':
1608 /* Writable section. */
1609 flags &=~ SEC_READONLY;
1610 readonly_removed = 1;
1611 break;
e96c5464 1612
422fee64
NC
1613 case 'a':
1614 /* Ignore. Here for compatibility with ELF. */
1615 break;
1616
1617 case 'r': /* Read-only section. Implies a data section. */
1618 readonly_removed = 0;
1619 /* Fall through. */
1620 case 'x': /* Executable section. */
1621 /* If we are setting the 'x' attribute or if the 'r'
1622 attribute is being used to restore the readonly status
1623 of a code section (eg "wxr") then set the SEC_CODE flag,
1624 otherwise set the SEC_DATA flag. */
1625 flags |= (attr == 'x' || (flags & SEC_CODE) ? SEC_CODE : SEC_DATA);
1626 if (! load_removed)
1627 flags |= SEC_LOAD;
1628 /* Note - the READONLY flag is set here, even for the 'x'
708587a4 1629 attribute in order to be compatible with the MSVC
422fee64
NC
1630 linker. */
1631 if (! readonly_removed)
1632 flags |= SEC_READONLY;
1633 break;
252b5132 1634
63ad59ae
KT
1635 case 'y':
1636 flags |= SEC_COFF_NOREAD | SEC_READONLY;
1637 break;
1638
252b5132
RH
1639 case 'i': /* STYP_INFO */
1640 case 'l': /* STYP_LIB */
1641 case 'o': /* STYP_OVER */
422fee64 1642 as_warn (_("unsupported section attribute '%c'"), attr);
252b5132
RH
1643 break;
1644
1645 default:
422fee64 1646 as_warn (_("unknown section attribute '%c'"), attr);
252b5132
RH
1647 break;
1648 }
252b5132 1649 }
422fee64 1650 if (attr == '"')
252b5132
RH
1651 ++input_line_pointer;
1652 }
1653 }
1654
1655 sec = subseg_new (name, (subsegT) exp);
c207c2c6 1656
31907d5e
DK
1657 if (alignment >= 0)
1658 sec->alignment_power = alignment;
252b5132 1659
c9900432
NC
1660 oldflags = bfd_get_section_flags (stdoutput, sec);
1661 if (oldflags == SEC_NO_FLAGS)
252b5132 1662 {
c9900432
NC
1663 /* Set section flags for a new section just created by subseg_new.
1664 Provide a default if no flags were parsed. */
1665 if (flags == SEC_NO_FLAGS)
1ad5eac0 1666 flags = TC_COFF_SECTION_DEFAULT_ATTRIBUTES;
dcd619be 1667
c9900432
NC
1668#ifdef COFF_LONG_SECTION_NAMES
1669 /* Add SEC_LINK_ONCE and SEC_LINK_DUPLICATES_DISCARD to .gnu.linkonce
1670 sections so adjust_reloc_syms in write.c will correctly handle
1671 relocs which refer to non-local symbols in these sections. */
a5324a3e 1672 if (strneq (name, ".gnu.linkonce", sizeof (".gnu.linkonce") - 1))
cc8a6dd0 1673 flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
c9900432 1674#endif
252b5132
RH
1675
1676 if (! bfd_set_section_flags (stdoutput, sec, flags))
cc8a6dd0
KH
1677 as_warn (_("error setting flags for \"%s\": %s"),
1678 bfd_section_name (stdoutput, sec),
1679 bfd_errmsg (bfd_get_error ()));
c9900432
NC
1680 }
1681 else if (flags != SEC_NO_FLAGS)
1682 {
a5324a3e 1683 /* This section's attributes have already been set. Warn if the
c9900432 1684 attributes don't match. */
5dd0794d 1685 flagword matchflags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
63ad59ae
KT
1686 | SEC_DATA | SEC_COFF_SHARED | SEC_NEVER_LOAD
1687 | SEC_COFF_NOREAD);
c9900432
NC
1688 if ((flags ^ oldflags) & matchflags)
1689 as_warn (_("Ignoring changed section attributes for %s"), name);
252b5132
RH
1690 }
1691
1692 demand_empty_rest_of_line ();
1693}
1694
1695void
a5324a3e 1696coff_adjust_symtab (void)
252b5132
RH
1697{
1698 if (symbol_rootP == NULL
1699 || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
a4528eeb 1700 c_dot_file_symbol ("fake", 0);
252b5132
RH
1701}
1702
1703void
a5324a3e 1704coff_frob_section (segT sec)
252b5132
RH
1705{
1706 segT strsec;
1707 char *p;
1708 fragS *fragp;
87975d2a 1709 bfd_vma n_entries;
252b5132
RH
1710
1711 /* The COFF back end in BFD requires that all section sizes be
bea9907b
TW
1712 rounded up to multiples of the corresponding section alignments,
1713 supposedly because standard COFF has no other way of encoding alignment
1714 for sections. If your COFF flavor has a different way of encoding
dcd619be 1715 section alignment, then skip this step, as TICOFF does. */
87975d2a 1716 bfd_vma size = bfd_get_section_size (sec);
bea9907b 1717#if !defined(TICOFF)
87975d2a
AM
1718 bfd_vma align_power = (bfd_vma) sec->alignment_power + OCTETS_PER_BYTE_POWER;
1719 bfd_vma mask = ((bfd_vma) 1 << align_power) - 1;
1720
252b5132
RH
1721 if (size & mask)
1722 {
7f788821
NC
1723 bfd_vma new_size;
1724 fragS *last;
dcd619be 1725
7f788821
NC
1726 new_size = (size + mask) & ~mask;
1727 bfd_set_section_size (stdoutput, sec, new_size);
1728
1729 /* If the size had to be rounded up, add some padding in
1730 the last non-empty frag. */
1731 fragp = seg_info (sec)->frchainP->frch_root;
1732 last = seg_info (sec)->frchainP->frch_last;
1733 while (fragp->fr_next != last)
cc8a6dd0 1734 fragp = fragp->fr_next;
7f788821
NC
1735 last->fr_address = size;
1736 fragp->fr_offset += new_size - size;
252b5132 1737 }
bea9907b 1738#endif
252b5132
RH
1739
1740 /* If the section size is non-zero, the section symbol needs an aux
1741 entry associated with it, indicating the size. We don't know
1742 all the values yet; coff_frob_symbol will fill them in later. */
bea9907b 1743#ifndef TICOFF
252b5132
RH
1744 if (size != 0
1745 || sec == text_section
1746 || sec == data_section
1747 || sec == bss_section)
bea9907b 1748#endif
252b5132
RH
1749 {
1750 symbolS *secsym = section_symbol (sec);
85645aed 1751 unsigned char sclass = C_STAT;
252b5132 1752
85645aed
TG
1753#ifdef OBJ_XCOFF
1754 if (bfd_get_section_flags (stdoutput, sec) & SEC_DEBUGGING)
1755 sclass = C_DWARF;
1756#endif
1757 S_SET_STORAGE_CLASS (secsym, sclass);
252b5132
RH
1758 S_SET_NUMBER_AUXILIARY (secsym, 1);
1759 SF_SET_STATICS (secsym);
1760 SA_SET_SCN_SCNLEN (secsym, size);
1761 }
a5324a3e 1762 /* FIXME: These should be in a "stabs.h" file, or maybe as.h. */
252b5132
RH
1763#ifndef STAB_SECTION_NAME
1764#define STAB_SECTION_NAME ".stab"
1765#endif
1766#ifndef STAB_STRING_SECTION_NAME
1767#define STAB_STRING_SECTION_NAME ".stabstr"
1768#endif
a5324a3e 1769 if (! streq (STAB_STRING_SECTION_NAME, sec->name))
252b5132
RH
1770 return;
1771
1772 strsec = sec;
1773 sec = subseg_get (STAB_SECTION_NAME, 0);
1774 /* size is already rounded up, since other section will be listed first */
587aac4e 1775 size = bfd_get_section_size (strsec);
252b5132 1776
587aac4e 1777 n_entries = bfd_get_section_size (sec) / 12 - 1;
252b5132
RH
1778
1779 /* Find first non-empty frag. It should be large enough. */
1780 fragp = seg_info (sec)->frchainP->frch_root;
1781 while (fragp && fragp->fr_fix == 0)
1782 fragp = fragp->fr_next;
9c2799c2 1783 gas_assert (fragp != 0 && fragp->fr_fix >= 12);
252b5132
RH
1784
1785 /* Store the values. */
1786 p = fragp->fr_literal;
1787 bfd_h_put_16 (stdoutput, n_entries, (bfd_byte *) p + 6);
1788 bfd_h_put_32 (stdoutput, size, (bfd_byte *) p + 8);
1789}
1790
1791void
a5324a3e 1792obj_coff_init_stab_section (segT seg)
252b5132 1793{
3b4dbbbf 1794 const char *file;
252b5132
RH
1795 char *p;
1796 char *stabstr_name;
1797 unsigned int stroff;
1798
dcd619be 1799 /* Make space for this first symbol. */
252b5132 1800 p = frag_more (12);
dcd619be 1801 /* Zero it out. */
252b5132 1802 memset (p, 0, 12);
3b4dbbbf 1803 file = as_where ((unsigned int *) NULL);
29a2809e 1804 stabstr_name = concat (seg->name, "str", (char *) NULL);
0acc7632 1805 stroff = get_stab_string_offset (file, stabstr_name, TRUE);
252b5132
RH
1806 know (stroff == 1);
1807 md_number_to_chars (p, stroff, 4);
1808}
1809
1810#ifdef DEBUG
9ccb8af9
AM
1811const char * s_get_name (symbolS *);
1812
252b5132 1813const char *
a5324a3e 1814s_get_name (symbolS *s)
252b5132
RH
1815{
1816 return ((s == NULL) ? "(NULL)" : S_GET_NAME (s));
1817}
1818
9ccb8af9
AM
1819void symbol_dump (void);
1820
252b5132 1821void
a5324a3e 1822symbol_dump (void)
252b5132
RH
1823{
1824 symbolS *symbolP;
1825
1826 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
a5324a3e
NC
1827 printf (_("0x%lx: \"%s\" type = %ld, class = %d, segment = %d\n"),
1828 (unsigned long) symbolP,
1829 S_GET_NAME (symbolP),
1830 (long) S_GET_DATA_TYPE (symbolP),
1831 S_GET_STORAGE_CLASS (symbolP),
1832 (int) S_GET_SEGMENT (symbolP));
252b5132
RH
1833}
1834
1835#endif /* DEBUG */
1836
7be1c489 1837const pseudo_typeS coff_pseudo_table[] =
252b5132 1838{
7be1c489
AM
1839 {"ABORT", s_abort, 0},
1840 {"appline", obj_coff_ln, 1},
1841 /* We accept the .bss directive for backward compatibility with
1842 earlier versions of gas. */
1843 {"bss", obj_coff_bss, 0},
c1711530
DK
1844#ifdef TE_PE
1845 /* PE provides an enhanced version of .comm with alignment. */
1846 {"comm", obj_coff_comm, 0},
1847#endif /* TE_PE */
7be1c489
AM
1848 {"def", obj_coff_def, 0},
1849 {"dim", obj_coff_dim, 0},
1850 {"endef", obj_coff_endef, 0},
1851 {"ident", obj_coff_ident, 0},
1852 {"line", obj_coff_line, 0},
1853 {"ln", obj_coff_ln, 0},
1854 {"scl", obj_coff_scl, 0},
1855 {"sect", obj_coff_section, 0},
1856 {"sect.s", obj_coff_section, 0},
1857 {"section", obj_coff_section, 0},
1858 {"section.s", obj_coff_section, 0},
1859 /* FIXME: We ignore the MRI short attribute. */
1860 {"size", obj_coff_size, 0},
1861 {"tag", obj_coff_tag, 0},
1862 {"type", obj_coff_type, 0},
1863 {"val", obj_coff_val, 0},
1864 {"version", s_ignore, 0},
1865 {"loc", obj_coff_loc, 0},
1866 {"optim", s_ignore, 0}, /* For sun386i cc (?) */
1867 {"weak", obj_coff_weak, 0},
1868#if defined TC_TIC4X
1869 /* The tic4x uses sdef instead of def. */
1870 {"sdef", obj_coff_def, 0},
f3d2b04b
KT
1871#endif
1872#if defined(SEH_CMDS)
1873 SEH_CMDS
252b5132 1874#endif
7be1c489
AM
1875 {NULL, NULL, 0}
1876};
1877\f
252b5132 1878
7be1c489 1879/* Support for a COFF emulation. */
252b5132
RH
1880
1881static void
7be1c489 1882coff_pop_insert (void)
252b5132 1883{
7be1c489 1884 pop_insert (coff_pseudo_table);
252b5132
RH
1885}
1886
a5324a3e 1887static int
7be1c489 1888coff_separate_stab_sections (void)
a5324a3e 1889{
7be1c489 1890 return 1;
a5324a3e
NC
1891}
1892
7be1c489 1893const struct format_ops coff_format_ops =
252b5132
RH
1894{
1895 bfd_target_coff_flavour,
4c63da97
AM
1896 0, /* dfl_leading_underscore */
1897 1, /* emit_section_symbols */
5110c57e
HPN
1898 0, /* begin */
1899 c_dot_file_symbol,
252b5132 1900 coff_frob_symbol,
4c63da97 1901 0, /* frob_file */
339681c0 1902 0, /* frob_file_before_adjust */
a161fe53 1903 0, /* frob_file_before_fix */
252b5132 1904 coff_frob_file_after_relocs,
4c63da97
AM
1905 0, /* s_get_size */
1906 0, /* s_set_size */
1907 0, /* s_get_align */
1908 0, /* s_set_align */
1909 0, /* s_get_other */
5110c57e 1910 0, /* s_set_other */
4c63da97 1911 0, /* s_get_desc */
5110c57e
HPN
1912 0, /* s_set_desc */
1913 0, /* s_get_type */
1914 0, /* s_set_type */
4c63da97
AM
1915 0, /* copy_symbol_attributes */
1916 0, /* generate_asm_lineno */
1917 0, /* process_stab */
5110c57e
HPN
1918 coff_separate_stab_sections,
1919 obj_coff_init_stab_section,
4c63da97 1920 0, /* sec_sym_ok_for_reloc */
252b5132 1921 coff_pop_insert,
4c63da97 1922 0, /* ecoff_set_ext */
252b5132 1923 coff_obj_read_begin_hook,
4cae74aa 1924 coff_obj_symbol_new_hook,
645ea3ea 1925 coff_obj_symbol_clone_hook,
6309d591 1926 coff_adjust_symtab
252b5132 1927};