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