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