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