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