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