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