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