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