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