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