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