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