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