gdb: add target_ops::supports_displaced_step
[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 1534 asection *sec;
b7780957 1535 bfd_boolean is_bss = FALSE;
252b5132
RH
1536
1537 if (flag_mri)
1538 {
1539 char type;
1540
1541 s_mri_sect (&type);
1542 return;
1543 }
1544
d02603dc 1545 c = get_symbol_name (&section_name);
29a2809e 1546 name = xmemdup0 (section_name, input_line_pointer - section_name);
252b5132 1547 *input_line_pointer = c;
d02603dc 1548 SKIP_WHITESPACE_AFTER_NAME ();
252b5132
RH
1549
1550 exp = 0;
c9900432 1551 flags = SEC_NO_FLAGS;
252b5132
RH
1552
1553 if (*input_line_pointer == ',')
1554 {
1555 ++input_line_pointer;
1556 SKIP_WHITESPACE ();
1557 if (*input_line_pointer != '"')
1558 exp = get_absolute_expression ();
1559 else
1560 {
422fee64
NC
1561 unsigned char attr;
1562 int readonly_removed = 0;
1563 int load_removed = 0;
1564
1565 while (attr = *++input_line_pointer,
1566 attr != '"'
1567 && ! is_end_of_line[attr])
252b5132 1568 {
31907d5e
DK
1569 if (ISDIGIT (attr))
1570 {
1571 alignment = attr - '0';
1572 continue;
1573 }
422fee64 1574 switch (attr)
252b5132 1575 {
c3489828
KT
1576 case 'e':
1577 /* Exclude section from linking. */
1578 flags |= SEC_EXCLUDE;
1579 break;
1580
422fee64
NC
1581 case 'b':
1582 /* Uninitialised data section. */
1583 flags |= SEC_ALLOC;
1584 flags &=~ SEC_LOAD;
b7780957 1585 is_bss = TRUE;
422fee64
NC
1586 break;
1587
1588 case 'n':
1589 /* Section not loaded. */
1590 flags &=~ SEC_LOAD;
1591 flags |= SEC_NEVER_LOAD;
1592 load_removed = 1;
1593 break;
1594
1595 case 's':
1596 /* Shared section. */
1597 flags |= SEC_COFF_SHARED;
1598 /* Fall through. */
1599 case 'd':
1600 /* Data section. */
1601 flags |= SEC_DATA;
1602 if (! load_removed)
1603 flags |= SEC_LOAD;
1604 flags &=~ SEC_READONLY;
1605 break;
e96c5464 1606
422fee64
NC
1607 case 'w':
1608 /* Writable section. */
1609 flags &=~ SEC_READONLY;
1610 readonly_removed = 1;
1611 break;
e96c5464 1612
422fee64
NC
1613 case 'a':
1614 /* Ignore. Here for compatibility with ELF. */
1615 break;
1616
1617 case 'r': /* Read-only section. Implies a data section. */
1618 readonly_removed = 0;
1619 /* Fall through. */
1620 case 'x': /* Executable section. */
1621 /* If we are setting the 'x' attribute or if the 'r'
1622 attribute is being used to restore the readonly status
1623 of a code section (eg "wxr") then set the SEC_CODE flag,
1624 otherwise set the SEC_DATA flag. */
1625 flags |= (attr == 'x' || (flags & SEC_CODE) ? SEC_CODE : SEC_DATA);
1626 if (! load_removed)
1627 flags |= SEC_LOAD;
1628 /* Note - the READONLY flag is set here, even for the 'x'
708587a4 1629 attribute in order to be compatible with the MSVC
422fee64
NC
1630 linker. */
1631 if (! readonly_removed)
1632 flags |= SEC_READONLY;
1633 break;
252b5132 1634
63ad59ae
KT
1635 case 'y':
1636 flags |= SEC_COFF_NOREAD | SEC_READONLY;
1637 break;
1638
252b5132
RH
1639 case 'i': /* STYP_INFO */
1640 case 'l': /* STYP_LIB */
1641 case 'o': /* STYP_OVER */
422fee64 1642 as_warn (_("unsupported section attribute '%c'"), attr);
252b5132
RH
1643 break;
1644
1645 default:
422fee64 1646 as_warn (_("unknown section attribute '%c'"), attr);
252b5132
RH
1647 break;
1648 }
252b5132 1649 }
422fee64 1650 if (attr == '"')
252b5132
RH
1651 ++input_line_pointer;
1652 }
1653 }
1654
1655 sec = subseg_new (name, (subsegT) exp);
c207c2c6 1656
b7780957
J
1657 if (is_bss)
1658 seg_info (sec)->bss = 1;
1659
31907d5e
DK
1660 if (alignment >= 0)
1661 sec->alignment_power = alignment;
252b5132 1662
fd361982 1663 oldflags = bfd_section_flags (sec);
c9900432 1664 if (oldflags == SEC_NO_FLAGS)
252b5132 1665 {
c9900432
NC
1666 /* Set section flags for a new section just created by subseg_new.
1667 Provide a default if no flags were parsed. */
1668 if (flags == SEC_NO_FLAGS)
1ad5eac0 1669 flags = TC_COFF_SECTION_DEFAULT_ATTRIBUTES;
dcd619be 1670
c9900432
NC
1671#ifdef COFF_LONG_SECTION_NAMES
1672 /* Add SEC_LINK_ONCE and SEC_LINK_DUPLICATES_DISCARD to .gnu.linkonce
1673 sections so adjust_reloc_syms in write.c will correctly handle
1674 relocs which refer to non-local symbols in these sections. */
a5324a3e 1675 if (strneq (name, ".gnu.linkonce", sizeof (".gnu.linkonce") - 1))
cc8a6dd0 1676 flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
c9900432 1677#endif
252b5132 1678
fd361982 1679 if (!bfd_set_section_flags (sec, flags))
cc8a6dd0 1680 as_warn (_("error setting flags for \"%s\": %s"),
fd361982 1681 bfd_section_name (sec),
cc8a6dd0 1682 bfd_errmsg (bfd_get_error ()));
c9900432
NC
1683 }
1684 else if (flags != SEC_NO_FLAGS)
1685 {
a5324a3e 1686 /* This section's attributes have already been set. Warn if the
c9900432 1687 attributes don't match. */
5dd0794d 1688 flagword matchflags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
63ad59ae
KT
1689 | SEC_DATA | SEC_COFF_SHARED | SEC_NEVER_LOAD
1690 | SEC_COFF_NOREAD);
c9900432
NC
1691 if ((flags ^ oldflags) & matchflags)
1692 as_warn (_("Ignoring changed section attributes for %s"), name);
252b5132
RH
1693 }
1694
1695 demand_empty_rest_of_line ();
1696}
1697
1698void
a5324a3e 1699coff_adjust_symtab (void)
252b5132
RH
1700{
1701 if (symbol_rootP == NULL
1702 || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
a4528eeb 1703 c_dot_file_symbol ("fake", 0);
252b5132
RH
1704}
1705
1706void
a5324a3e 1707coff_frob_section (segT sec)
252b5132
RH
1708{
1709 segT strsec;
1710 char *p;
1711 fragS *fragp;
87975d2a 1712 bfd_vma n_entries;
252b5132
RH
1713
1714 /* The COFF back end in BFD requires that all section sizes be
bea9907b
TW
1715 rounded up to multiples of the corresponding section alignments,
1716 supposedly because standard COFF has no other way of encoding alignment
1717 for sections. If your COFF flavor has a different way of encoding
dcd619be 1718 section alignment, then skip this step, as TICOFF does. */
fd361982 1719 bfd_vma size = bfd_section_size (sec);
bea9907b 1720#if !defined(TICOFF)
87975d2a
AM
1721 bfd_vma align_power = (bfd_vma) sec->alignment_power + OCTETS_PER_BYTE_POWER;
1722 bfd_vma mask = ((bfd_vma) 1 << align_power) - 1;
1723
252b5132
RH
1724 if (size & mask)
1725 {
7f788821
NC
1726 bfd_vma new_size;
1727 fragS *last;
dcd619be 1728
7f788821 1729 new_size = (size + mask) & ~mask;
fd361982 1730 bfd_set_section_size (sec, new_size);
7f788821
NC
1731
1732 /* If the size had to be rounded up, add some padding in
1733 the last non-empty frag. */
1734 fragp = seg_info (sec)->frchainP->frch_root;
1735 last = seg_info (sec)->frchainP->frch_last;
1736 while (fragp->fr_next != last)
cc8a6dd0 1737 fragp = fragp->fr_next;
7f788821
NC
1738 last->fr_address = size;
1739 fragp->fr_offset += new_size - size;
252b5132 1740 }
bea9907b 1741#endif
252b5132
RH
1742
1743 /* If the section size is non-zero, the section symbol needs an aux
1744 entry associated with it, indicating the size. We don't know
1745 all the values yet; coff_frob_symbol will fill them in later. */
bea9907b 1746#ifndef TICOFF
252b5132
RH
1747 if (size != 0
1748 || sec == text_section
1749 || sec == data_section
1750 || sec == bss_section)
bea9907b 1751#endif
252b5132
RH
1752 {
1753 symbolS *secsym = section_symbol (sec);
85645aed 1754 unsigned char sclass = C_STAT;
252b5132 1755
85645aed 1756#ifdef OBJ_XCOFF
fd361982 1757 if (bfd_section_flags (sec) & SEC_DEBUGGING)
85645aed
TG
1758 sclass = C_DWARF;
1759#endif
1760 S_SET_STORAGE_CLASS (secsym, sclass);
252b5132
RH
1761 S_SET_NUMBER_AUXILIARY (secsym, 1);
1762 SF_SET_STATICS (secsym);
1763 SA_SET_SCN_SCNLEN (secsym, size);
1764 }
a5324a3e 1765 /* FIXME: These should be in a "stabs.h" file, or maybe as.h. */
252b5132
RH
1766#ifndef STAB_SECTION_NAME
1767#define STAB_SECTION_NAME ".stab"
1768#endif
1769#ifndef STAB_STRING_SECTION_NAME
1770#define STAB_STRING_SECTION_NAME ".stabstr"
1771#endif
a5324a3e 1772 if (! streq (STAB_STRING_SECTION_NAME, sec->name))
252b5132
RH
1773 return;
1774
1775 strsec = sec;
1776 sec = subseg_get (STAB_SECTION_NAME, 0);
1777 /* size is already rounded up, since other section will be listed first */
fd361982 1778 size = bfd_section_size (strsec);
252b5132 1779
fd361982 1780 n_entries = bfd_section_size (sec) / 12 - 1;
252b5132
RH
1781
1782 /* Find first non-empty frag. It should be large enough. */
1783 fragp = seg_info (sec)->frchainP->frch_root;
1784 while (fragp && fragp->fr_fix == 0)
1785 fragp = fragp->fr_next;
9c2799c2 1786 gas_assert (fragp != 0 && fragp->fr_fix >= 12);
252b5132
RH
1787
1788 /* Store the values. */
1789 p = fragp->fr_literal;
1790 bfd_h_put_16 (stdoutput, n_entries, (bfd_byte *) p + 6);
1791 bfd_h_put_32 (stdoutput, size, (bfd_byte *) p + 8);
1792}
1793
1794void
a5324a3e 1795obj_coff_init_stab_section (segT seg)
252b5132 1796{
3b4dbbbf 1797 const char *file;
252b5132
RH
1798 char *p;
1799 char *stabstr_name;
1800 unsigned int stroff;
1801
dcd619be 1802 /* Make space for this first symbol. */
252b5132 1803 p = frag_more (12);
dcd619be 1804 /* Zero it out. */
252b5132 1805 memset (p, 0, 12);
3b4dbbbf 1806 file = as_where ((unsigned int *) NULL);
29a2809e 1807 stabstr_name = concat (seg->name, "str", (char *) NULL);
0acc7632 1808 stroff = get_stab_string_offset (file, stabstr_name, TRUE);
252b5132
RH
1809 know (stroff == 1);
1810 md_number_to_chars (p, stroff, 4);
1811}
1812
1813#ifdef DEBUG
9ccb8af9
AM
1814const char * s_get_name (symbolS *);
1815
252b5132 1816const char *
a5324a3e 1817s_get_name (symbolS *s)
252b5132
RH
1818{
1819 return ((s == NULL) ? "(NULL)" : S_GET_NAME (s));
1820}
1821
9ccb8af9
AM
1822void symbol_dump (void);
1823
252b5132 1824void
a5324a3e 1825symbol_dump (void)
252b5132
RH
1826{
1827 symbolS *symbolP;
1828
1829 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
a5324a3e
NC
1830 printf (_("0x%lx: \"%s\" type = %ld, class = %d, segment = %d\n"),
1831 (unsigned long) symbolP,
1832 S_GET_NAME (symbolP),
1833 (long) S_GET_DATA_TYPE (symbolP),
1834 S_GET_STORAGE_CLASS (symbolP),
1835 (int) S_GET_SEGMENT (symbolP));
252b5132
RH
1836}
1837
1838#endif /* DEBUG */
1839
7be1c489 1840const pseudo_typeS coff_pseudo_table[] =
252b5132 1841{
7be1c489
AM
1842 {"ABORT", s_abort, 0},
1843 {"appline", obj_coff_ln, 1},
1844 /* We accept the .bss directive for backward compatibility with
1845 earlier versions of gas. */
1846 {"bss", obj_coff_bss, 0},
c1711530
DK
1847#ifdef TE_PE
1848 /* PE provides an enhanced version of .comm with alignment. */
1849 {"comm", obj_coff_comm, 0},
1850#endif /* TE_PE */
7be1c489
AM
1851 {"def", obj_coff_def, 0},
1852 {"dim", obj_coff_dim, 0},
1853 {"endef", obj_coff_endef, 0},
1854 {"ident", obj_coff_ident, 0},
1855 {"line", obj_coff_line, 0},
1856 {"ln", obj_coff_ln, 0},
1857 {"scl", obj_coff_scl, 0},
1858 {"sect", obj_coff_section, 0},
1859 {"sect.s", obj_coff_section, 0},
1860 {"section", obj_coff_section, 0},
1861 {"section.s", obj_coff_section, 0},
1862 /* FIXME: We ignore the MRI short attribute. */
1863 {"size", obj_coff_size, 0},
1864 {"tag", obj_coff_tag, 0},
1865 {"type", obj_coff_type, 0},
1866 {"val", obj_coff_val, 0},
1867 {"version", s_ignore, 0},
1868 {"loc", obj_coff_loc, 0},
1869 {"optim", s_ignore, 0}, /* For sun386i cc (?) */
1870 {"weak", obj_coff_weak, 0},
1871#if defined TC_TIC4X
1872 /* The tic4x uses sdef instead of def. */
1873 {"sdef", obj_coff_def, 0},
f3d2b04b
KT
1874#endif
1875#if defined(SEH_CMDS)
1876 SEH_CMDS
252b5132 1877#endif
7be1c489
AM
1878 {NULL, NULL, 0}
1879};
1880\f
252b5132 1881
7be1c489 1882/* Support for a COFF emulation. */
252b5132
RH
1883
1884static void
7be1c489 1885coff_pop_insert (void)
252b5132 1886{
7be1c489 1887 pop_insert (coff_pseudo_table);
252b5132
RH
1888}
1889
a5324a3e 1890static int
7be1c489 1891coff_separate_stab_sections (void)
a5324a3e 1892{
7be1c489 1893 return 1;
a5324a3e
NC
1894}
1895
7be1c489 1896const struct format_ops coff_format_ops =
252b5132
RH
1897{
1898 bfd_target_coff_flavour,
4c63da97
AM
1899 0, /* dfl_leading_underscore */
1900 1, /* emit_section_symbols */
5110c57e
HPN
1901 0, /* begin */
1902 c_dot_file_symbol,
252b5132 1903 coff_frob_symbol,
4c63da97 1904 0, /* frob_file */
339681c0 1905 0, /* frob_file_before_adjust */
a161fe53 1906 0, /* frob_file_before_fix */
252b5132 1907 coff_frob_file_after_relocs,
4c63da97
AM
1908 0, /* s_get_size */
1909 0, /* s_set_size */
1910 0, /* s_get_align */
1911 0, /* s_set_align */
1912 0, /* s_get_other */
5110c57e 1913 0, /* s_set_other */
4c63da97 1914 0, /* s_get_desc */
5110c57e
HPN
1915 0, /* s_set_desc */
1916 0, /* s_get_type */
1917 0, /* s_set_type */
4c63da97
AM
1918 0, /* copy_symbol_attributes */
1919 0, /* generate_asm_lineno */
1920 0, /* process_stab */
5110c57e
HPN
1921 coff_separate_stab_sections,
1922 obj_coff_init_stab_section,
4c63da97 1923 0, /* sec_sym_ok_for_reloc */
252b5132 1924 coff_pop_insert,
4c63da97 1925 0, /* ecoff_set_ext */
252b5132 1926 coff_obj_read_begin_hook,
4cae74aa 1927 coff_obj_symbol_new_hook,
645ea3ea 1928 coff_obj_symbol_clone_hook,
6309d591 1929 coff_adjust_symtab
252b5132 1930};
This page took 1.040051 seconds and 4 git commands to generate.