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