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