source: trunk/binutils/gas/config/obj-coff.c@ 2562

Last change on this file since 2562 was 610, checked in by bird, 22 years ago

This commit was generated by cvs2svn to compensate for changes in r609,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 122.6 KB
Line 
1/* coff object file format
2 Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000, 2001, 2002
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 2, 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, 59 Temple Place - Suite 330, Boston, MA
21 02111-1307, USA. */
22
23#define OBJ_HEADER "obj-coff.h"
24
25#include "as.h"
26#include "obstack.h"
27#include "subsegs.h"
28
29/* I think this is probably always correct. */
30#ifndef KEEP_RELOC_INFO
31#define KEEP_RELOC_INFO
32#endif
33
34/* The BFD_ASSEMBLER version of obj_coff_section will use this macro to set
35 a new section's attributes when a directive has no valid flags or the
36 "w" flag is used. This default should be appropriate for most. */
37#ifndef TC_COFF_SECTION_DEFAULT_ATTRIBUTES
38#define TC_COFF_SECTION_DEFAULT_ATTRIBUTES (SEC_LOAD | SEC_DATA)
39#endif
40
41/* This is used to hold the symbol built by a sequence of pseudo-ops
42 from .def and .endef. */
43static symbolS *def_symbol_in_progress;
44
45typedef struct
46 {
47 unsigned long chunk_size;
48 unsigned long element_size;
49 unsigned long size;
50 char *data;
51 unsigned long pointer;
52 }
53stack;
54
55static stack *stack_init PARAMS ((unsigned long, unsigned long));
56static char *stack_push PARAMS ((stack *, char *));
57static char *stack_pop PARAMS ((stack *));
58static void tag_init PARAMS ((void));
59static void tag_insert PARAMS ((const char *, symbolS *));
60static symbolS *tag_find PARAMS ((char *));
61static symbolS *tag_find_or_make PARAMS ((char *));
62static void obj_coff_bss PARAMS ((int));
63static void obj_coff_weak PARAMS ((int));
64const char *s_get_name PARAMS ((symbolS * s));
65static void obj_coff_ln PARAMS ((int));
66static void obj_coff_def PARAMS ((int));
67static void obj_coff_endef PARAMS ((int));
68static void obj_coff_dim PARAMS ((int));
69static void obj_coff_line PARAMS ((int));
70static void obj_coff_size PARAMS ((int));
71static void obj_coff_scl PARAMS ((int));
72static void obj_coff_tag PARAMS ((int));
73static void obj_coff_val PARAMS ((int));
74static void obj_coff_type PARAMS ((int));
75static void obj_coff_ident PARAMS ((int));
76#ifdef BFD_ASSEMBLER
77static void obj_coff_loc PARAMS((int));
78#endif
79
80
81/* stack stuff */
82
83static stack *
84stack_init (chunk_size, element_size)
85 unsigned long chunk_size;
86 unsigned long element_size;
87{
88 stack *st;
89
90 st = (stack *) malloc (sizeof (stack));
91 if (!st)
92 return 0;
93 st->data = malloc (chunk_size);
94 if (!st->data)
95 {
96 free (st);
97 return 0;
98 }
99 st->pointer = 0;
100 st->size = chunk_size;
101 st->chunk_size = chunk_size;
102 st->element_size = element_size;
103 return st;
104}
105
106#if 0
107/* Not currently used. */
108static void
109stack_delete (st)
110 stack *st;
111{
112 free (st->data);
113 free (st);
114}
115#endif
116
117static char *
118stack_push (st, element)
119 stack *st;
120 char *element;
121{
122 if (st->pointer + st->element_size >= st->size)
123 {
124 st->size += st->chunk_size;
125 if ((st->data = xrealloc (st->data, st->size)) == (char *) 0)
126 return (char *) 0;
127 }
128 memcpy (st->data + st->pointer, element, st->element_size);
129 st->pointer += st->element_size;
130 return st->data + st->pointer;
131}
132
133static char *
134stack_pop (st)
135 stack *st;
136{
137 if (st->pointer < st->element_size)
138 {
139 st->pointer = 0;
140 return (char *) 0;
141 }
142 st->pointer -= st->element_size;
143 return st->data + st->pointer;
144}
145
146
147/*
148 * Maintain a list of the tagnames of the structres.
149 */
150
151static struct hash_control *tag_hash;
152
153static void
154tag_init ()
155{
156 tag_hash = hash_new ();
157}
158
159static void
160tag_insert (name, symbolP)
161 const char *name;
162 symbolS *symbolP;
163{
164 const char *error_string;
165
166 if ((error_string = hash_jam (tag_hash, name, (char *) symbolP)))
167 {
168 as_fatal (_("Inserting \"%s\" into structure table failed: %s"),
169 name, error_string);
170 }
171}
172
173static symbolS *
174tag_find (name)
175 char *name;
176{
177#ifdef STRIP_UNDERSCORE
178 if (*name == '_')
179 name++;
180#endif /* STRIP_UNDERSCORE */
181 return (symbolS *) hash_find (tag_hash, name);
182}
183
184static symbolS *
185tag_find_or_make (name)
186 char *name;
187{
188 symbolS *symbolP;
189
190 if ((symbolP = tag_find (name)) == NULL)
191 {
192 symbolP = symbol_new (name, undefined_section,
193 0, &zero_address_frag);
194
195 tag_insert (S_GET_NAME (symbolP), symbolP);
196#ifdef BFD_ASSEMBLER
197 symbol_table_insert (symbolP);
198#endif
199 } /* not found */
200
201 return symbolP;
202}
203
204/* We accept the .bss directive to set the section for backward
205 compatibility with earlier versions of gas. */
206
207static void
208obj_coff_bss (ignore)
209 int ignore ATTRIBUTE_UNUSED;
210{
211 if (*input_line_pointer == '\n')
212 subseg_new (".bss", get_absolute_expression ());
213 else
214 s_lcomm (0);
215}
216
217/* Handle .weak. This is a GNU extension. */
218
219static void
220obj_coff_weak (ignore)
221 int ignore ATTRIBUTE_UNUSED;
222{
223 char *name;
224 int c;
225 symbolS *symbolP;
226
227 do
228 {
229 name = input_line_pointer;
230 c = get_symbol_end ();
231 symbolP = symbol_find_or_make (name);
232 *input_line_pointer = c;
233 SKIP_WHITESPACE ();
234
235#if defined BFD_ASSEMBLER || defined S_SET_WEAK
236 S_SET_WEAK (symbolP);
237#endif
238
239#ifdef TE_PE
240 S_SET_STORAGE_CLASS (symbolP, C_NT_WEAK);
241#else
242 S_SET_STORAGE_CLASS (symbolP, C_WEAKEXT);
243#endif
244
245 if (c == ',')
246 {
247 input_line_pointer++;
248 SKIP_WHITESPACE ();
249 if (*input_line_pointer == '\n')
250 c = '\n';
251 }
252 }
253 while (c == ',');
254
255 demand_empty_rest_of_line ();
256}
257
258#ifdef BFD_ASSEMBLER
259
260static segT fetch_coff_debug_section PARAMS ((void));
261static void SA_SET_SYM_TAGNDX PARAMS ((symbolS *, symbolS *));
262static int S_GET_DATA_TYPE PARAMS ((symbolS *));
263void c_symbol_merge PARAMS ((symbolS *, symbolS *));
264static void add_lineno PARAMS ((fragS *, addressT, int));
265
266#define GET_FILENAME_STRING(X) \
267((char*) (&((X)->sy_symbol.ost_auxent->x_file.x_n.x_offset))[1])
268
269/* @@ Ick. */
270static segT
271fetch_coff_debug_section ()
272{
273 static segT debug_section;
274 if (!debug_section)
275 {
276 const asymbol *s;
277 s = bfd_make_debug_symbol (stdoutput, (char *) 0, 0);
278 assert (s != 0);
279 debug_section = s->section;
280 }
281 return debug_section;
282}
283
284void
285SA_SET_SYM_ENDNDX (sym, val)
286 symbolS *sym;
287 symbolS *val;
288{
289 combined_entry_type *entry, *p;
290
291 entry = &coffsymbol (symbol_get_bfdsym (sym))->native[1];
292 p = coffsymbol (symbol_get_bfdsym (val))->native;
293 entry->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p = p;
294 entry->fix_end = 1;
295}
296
297static void
298SA_SET_SYM_TAGNDX (sym, val)
299 symbolS *sym;
300 symbolS *val;
301{
302 combined_entry_type *entry, *p;
303
304 entry = &coffsymbol (symbol_get_bfdsym (sym))->native[1];
305 p = coffsymbol (symbol_get_bfdsym (val))->native;
306 entry->u.auxent.x_sym.x_tagndx.p = p;
307 entry->fix_tag = 1;
308}
309
310static int
311S_GET_DATA_TYPE (sym)
312 symbolS *sym;
313{
314 return coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_type;
315}
316
317int
318S_SET_DATA_TYPE (sym, val)
319 symbolS *sym;
320 int val;
321{
322 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_type = val;
323 return val;
324}
325
326int
327S_GET_STORAGE_CLASS (sym)
328 symbolS *sym;
329{
330 return coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_sclass;
331}
332
333int
334S_SET_STORAGE_CLASS (sym, val)
335 symbolS *sym;
336 int val;
337{
338 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_sclass = val;
339 return val;
340}
341
342/* Merge a debug symbol containing debug information into a normal symbol. */
343
344void
345c_symbol_merge (debug, normal)
346 symbolS *debug;
347 symbolS *normal;
348{
349 S_SET_DATA_TYPE (normal, S_GET_DATA_TYPE (debug));
350 S_SET_STORAGE_CLASS (normal, S_GET_STORAGE_CLASS (debug));
351
352 if (S_GET_NUMBER_AUXILIARY (debug) > S_GET_NUMBER_AUXILIARY (normal))
353 {
354 /* take the most we have */
355 S_SET_NUMBER_AUXILIARY (normal, S_GET_NUMBER_AUXILIARY (debug));
356 }
357
358 if (S_GET_NUMBER_AUXILIARY (debug) > 0)
359 {
360 /* Move all the auxiliary information. */
361 memcpy (SYM_AUXINFO (normal), SYM_AUXINFO (debug),
362 (S_GET_NUMBER_AUXILIARY (debug)
363 * sizeof (*SYM_AUXINFO (debug))));
364 }
365
366 /* Move the debug flags. */
367 SF_SET_DEBUG_FIELD (normal, SF_GET_DEBUG_FIELD (debug));
368}
369
370void
371c_dot_file_symbol (filename)
372 const char *filename;
373{
374 symbolS *symbolP;
375
376 /* BFD converts filename to a .file symbol with an aux entry. It
377 also handles chaining. */
378 symbolP = symbol_new (filename, bfd_abs_section_ptr, 0, &zero_address_frag);
379
380 S_SET_STORAGE_CLASS (symbolP, C_FILE);
381 S_SET_NUMBER_AUXILIARY (symbolP, 1);
382
383 symbol_get_bfdsym (symbolP)->flags = BSF_DEBUGGING;
384
385#ifndef NO_LISTING
386 {
387 extern int listing;
388 if (listing)
389 {
390 listing_source_file (filename);
391 }
392 }
393#endif
394
395 /* Make sure that the symbol is first on the symbol chain */
396 if (symbol_rootP != symbolP)
397 {
398 symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
399 symbol_insert (symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP);
400 } /* if not first on the list */
401}
402
403/* Line number handling */
404
405struct line_no {
406 struct line_no *next;
407 fragS *frag;
408 alent l;
409};
410
411int coff_line_base;
412
413/* Symbol of last function, which we should hang line#s off of. */
414static symbolS *line_fsym;
415
416#define in_function() (line_fsym != 0)
417#define clear_function() (line_fsym = 0)
418#define set_function(F) (line_fsym = (F), coff_add_linesym (F))
419
420
421
422void
423coff_obj_symbol_new_hook (symbolP)
424 symbolS *symbolP;
425{
426 long sz = (OBJ_COFF_MAX_AUXENTRIES + 1) * sizeof (combined_entry_type);
427 char * s = (char *) xmalloc (sz);
428
429 memset (s, 0, sz);
430 coffsymbol (symbol_get_bfdsym (symbolP))->native = (combined_entry_type *) s;
431
432 S_SET_DATA_TYPE (symbolP, T_NULL);
433 S_SET_STORAGE_CLASS (symbolP, 0);
434 S_SET_NUMBER_AUXILIARY (symbolP, 0);
435
436 if (S_IS_STRING (symbolP))
437 SF_SET_STRING (symbolP);
438
439 if (S_IS_LOCAL (symbolP))
440 SF_SET_LOCAL (symbolP);
441}
442
443
444
445/*
446 * Handle .ln directives.
447 */
448
449static symbolS *current_lineno_sym;
450static struct line_no *line_nos;
451/* @@ Blindly assume all .ln directives will be in the .text section... */
452int coff_n_line_nos;
453
454static void
455add_lineno (frag, offset, num)
456 fragS *frag;
457 addressT offset;
458 int num;
459{
460 struct line_no *new_line =
461 (struct line_no *) xmalloc (sizeof (struct line_no));
462 if (!current_lineno_sym)
463 {
464 abort ();
465 }
466
467#ifndef OBJ_XCOFF
468 /* The native aix assembler accepts negative line number */
469
470 if (num <= 0)
471 {
472 /* Zero is used as an end marker in the file. */
473 as_warn (_("Line numbers must be positive integers\n"));
474 num = 1;
475 }
476#endif /* OBJ_XCOFF */
477 new_line->next = line_nos;
478 new_line->frag = frag;
479 new_line->l.line_number = num;
480 new_line->l.u.offset = offset;
481 line_nos = new_line;
482 coff_n_line_nos++;
483}
484
485void
486coff_add_linesym (sym)
487 symbolS *sym;
488{
489 if (line_nos)
490 {
491 coffsymbol (symbol_get_bfdsym (current_lineno_sym))->lineno =
492 (alent *) line_nos;
493 coff_n_line_nos++;
494 line_nos = 0;
495 }
496 current_lineno_sym = sym;
497}
498
499static void
500obj_coff_ln (appline)
501 int appline;
502{
503 int l;
504
505 if (! appline && def_symbol_in_progress != NULL)
506 {
507 as_warn (_(".ln pseudo-op inside .def/.endef: ignored."));
508 demand_empty_rest_of_line ();
509 return;
510 }
511
512 l = get_absolute_expression ();
513
514 /* If there is no lineno symbol, treat a .ln
515 directive as if it were a .appline directive. */
516 if (appline || current_lineno_sym == NULL)
517 new_logical_line ((char *) NULL, l - 1);
518 else
519 add_lineno (frag_now, frag_now_fix (), l);
520
521#ifndef NO_LISTING
522 {
523 extern int listing;
524
525 if (listing)
526 {
527 if (! appline)
528 l += coff_line_base - 1;
529 listing_source_line (l);
530 }
531 }
532#endif
533
534 demand_empty_rest_of_line ();
535}
536
537/* .loc is essentially the same as .ln; parse it for assembler
538 compatibility. */
539
540static void
541obj_coff_loc (ignore)
542 int ignore ATTRIBUTE_UNUSED;
543{
544 int lineno;
545
546 /* FIXME: Why do we need this check? We need it for ECOFF, but why
547 do we need it for COFF? */
548 if (now_seg != text_section)
549 {
550 as_warn (_(".loc outside of .text"));
551 demand_empty_rest_of_line ();
552 return;
553 }
554
555 if (def_symbol_in_progress != NULL)
556 {
557 as_warn (_(".loc pseudo-op inside .def/.endef: ignored."));
558 demand_empty_rest_of_line ();
559 return;
560 }
561
562 /* Skip the file number. */
563 SKIP_WHITESPACE ();
564 get_absolute_expression ();
565 SKIP_WHITESPACE ();
566
567 lineno = get_absolute_expression ();
568
569#ifndef NO_LISTING
570 {
571 extern int listing;
572
573 if (listing)
574 {
575 lineno += coff_line_base - 1;
576 listing_source_line (lineno);
577 }
578 }
579#endif
580
581 demand_empty_rest_of_line ();
582
583 add_lineno (frag_now, frag_now_fix (), lineno);
584}
585
586/* Handle the .ident pseudo-op. */
587
588static void
589obj_coff_ident (ignore)
590 int ignore ATTRIBUTE_UNUSED;
591{
592 segT current_seg = now_seg;
593 subsegT current_subseg = now_subseg;
594
595#ifdef TE_PE
596 {
597 segT sec;
598
599 /* We could put it in .comment, but that creates an extra section
600 that shouldn't be loaded into memory, which requires linker
601 changes... For now, until proven otherwise, use .rdata. */
602 sec = subseg_new (".rdata$zzz", 0);
603 bfd_set_section_flags (stdoutput, sec,
604 ((SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA)
605 & bfd_applicable_section_flags (stdoutput)));
606 }
607#else
608 subseg_new (".comment", 0);
609#endif
610
611 stringer (1);
612 subseg_set (current_seg, current_subseg);
613}
614
615/*
616 * def()
617 *
618 * Handle .def directives.
619 *
620 * One might ask : why can't we symbol_new if the symbol does not
621 * already exist and fill it with debug information. Because of
622 * the C_EFCN special symbol. It would clobber the value of the
623 * function symbol before we have a chance to notice that it is
624 * a C_EFCN. And a second reason is that the code is more clear this
625 * way. (at least I think it is :-).
626 *
627 */
628
629#define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';')
630#define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \
631 *input_line_pointer == '\t') \
632 input_line_pointer++;
633
634static void
635obj_coff_def (what)
636 int what ATTRIBUTE_UNUSED;
637{
638 char name_end; /* Char after the end of name */
639 char *symbol_name; /* Name of the debug symbol */
640 char *symbol_name_copy; /* Temporary copy of the name */
641 unsigned int symbol_name_length;
642
643 if (def_symbol_in_progress != NULL)
644 {
645 as_warn (_(".def pseudo-op used inside of .def/.endef: ignored."));
646 demand_empty_rest_of_line ();
647 return;
648 } /* if not inside .def/.endef */
649
650 SKIP_WHITESPACES ();
651
652 symbol_name = input_line_pointer;
653#ifdef STRIP_UNDERSCORE
654 if (symbol_name[0] == '_' && symbol_name[1] != 0)
655 symbol_name++;
656#endif /* STRIP_UNDERSCORE */
657
658 name_end = get_symbol_end ();
659 symbol_name_length = strlen (symbol_name);
660 symbol_name_copy = xmalloc (symbol_name_length + 1);
661 strcpy (symbol_name_copy, symbol_name);
662#ifdef tc_canonicalize_symbol_name
663 symbol_name_copy = tc_canonicalize_symbol_name (symbol_name_copy);
664#endif
665
666 /* Initialize the new symbol */
667 def_symbol_in_progress = symbol_make (symbol_name_copy);
668 symbol_set_frag (def_symbol_in_progress, &zero_address_frag);
669 S_SET_VALUE (def_symbol_in_progress, 0);
670
671 if (S_IS_STRING (def_symbol_in_progress))
672 SF_SET_STRING (def_symbol_in_progress);
673
674 *input_line_pointer = name_end;
675
676 demand_empty_rest_of_line ();
677}
678
679unsigned int dim_index;
680
681static void
682obj_coff_endef (ignore)
683 int ignore ATTRIBUTE_UNUSED;
684{
685 symbolS *symbolP = NULL;
686
687 /* DIM BUG FIX sac@cygnus.com */
688 dim_index = 0;
689 if (def_symbol_in_progress == NULL)
690 {
691 as_warn (_(".endef pseudo-op used outside of .def/.endef: ignored."));
692 demand_empty_rest_of_line ();
693 return;
694 } /* if not inside .def/.endef */
695
696 /* Set the section number according to storage class. */
697 switch (S_GET_STORAGE_CLASS (def_symbol_in_progress))
698 {
699 case C_STRTAG:
700 case C_ENTAG:
701 case C_UNTAG:
702 SF_SET_TAG (def_symbol_in_progress);
703 /* intentional fallthrough */
704 case C_FILE:
705 case C_TPDEF:
706 SF_SET_DEBUG (def_symbol_in_progress);
707 S_SET_SEGMENT (def_symbol_in_progress, fetch_coff_debug_section ());
708 break;
709
710 case C_EFCN:
711 SF_SET_LOCAL (def_symbol_in_progress); /* Do not emit this symbol. */
712 /* intentional fallthrough */
713 case C_BLOCK:
714 SF_SET_PROCESS (def_symbol_in_progress); /* Will need processing before writing */
715 /* intentional fallthrough */
716 case C_FCN:
717 {
718 const char *name;
719 S_SET_SEGMENT (def_symbol_in_progress, text_section);
720
721 name = S_GET_NAME (def_symbol_in_progress);
722 if (name[0] == '.' && name[2] == 'f' && name[3] == '\0')
723 {
724 switch (name[1])
725 {
726 case 'b':
727 /* .bf */
728 if (! in_function ())
729 as_warn (_("`%s' symbol without preceding function"), name);
730 /* Will need relocating. */
731 SF_SET_PROCESS (def_symbol_in_progress);
732 clear_function ();
733 break;
734#ifdef TE_PE
735 case 'e':
736 /* .ef */
737 /* The MS compilers output the actual endline, not the
738 function-relative one... we want to match without
739 changing the assembler input. */
740 SA_SET_SYM_LNNO (def_symbol_in_progress,
741 (SA_GET_SYM_LNNO (def_symbol_in_progress)
742 + coff_line_base));
743 break;
744#endif
745 }
746 }
747 }
748 break;
749
750#ifdef C_AUTOARG
751 case C_AUTOARG:
752#endif /* C_AUTOARG */
753 case C_AUTO:
754 case C_REG:
755 case C_ARG:
756 case C_REGPARM:
757 case C_FIELD:
758
759 /* According to the COFF documentation:
760
761 http://osr5doc.sco.com:1996/topics/COFF_SectNumFld.html
762
763 A special section number (-2) marks symbolic debugging symbols,
764 including structure/union/enumeration tag names, typedefs, and
765 the name of the file. A section number of -1 indicates that the
766 symbol has a value but is not relocatable. Examples of
767 absolute-valued symbols include automatic and register variables,
768 function arguments, and .eos symbols.
769
770 But from Ian Lance Taylor:
771
772 http://sources.redhat.com/ml/binutils/2000-08/msg00202.html
773
774 the actual tools all marked them as section -1. So the GNU COFF
775 assembler follows historical COFF assemblers.
776
777 However, it causes problems for djgpp
778
779 http://sources.redhat.com/ml/binutils/2000-08/msg00210.html
780
781 By defining STRICTCOFF, a COFF port can make the assembler to
782 follow the documented behavior. */
783#ifdef STRICTCOFF
784 case C_MOS:
785 case C_MOE:
786 case C_MOU:
787 case C_EOS:
788#endif
789 SF_SET_DEBUG (def_symbol_in_progress);
790 S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
791 break;
792
793#ifndef STRICTCOFF
794 case C_MOS:
795 case C_MOE:
796 case C_MOU:
797 case C_EOS:
798 S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
799 break;
800#endif
801
802 case C_EXT:
803 case C_WEAKEXT:
804#ifdef TE_PE
805 case C_NT_WEAK:
806#endif
807 case C_STAT:
808 case C_LABEL:
809 /* Valid but set somewhere else (s_comm, s_lcomm, colon) */
810 break;
811
812 default:
813 case C_USTATIC:
814 case C_EXTDEF:
815 case C_ULABEL:
816 as_warn (_("unexpected storage class %d"),
817 S_GET_STORAGE_CLASS (def_symbol_in_progress));
818 break;
819 } /* switch on storage class */
820
821 /* Now that we have built a debug symbol, try to find if we should
822 merge with an existing symbol or not. If a symbol is C_EFCN or
823 absolute_section or untagged SEG_DEBUG it never merges. We also
824 don't merge labels, which are in a different namespace, nor
825 symbols which have not yet been defined since they are typically
826 unique, nor do we merge tags with non-tags. */
827
828 /* Two cases for functions. Either debug followed by definition or
829 definition followed by debug. For definition first, we will
830 merge the debug symbol into the definition. For debug first, the
831 lineno entry MUST point to the definition function or else it
832 will point off into space when obj_crawl_symbol_chain() merges
833 the debug symbol into the real symbol. Therefor, let's presume
834 the debug symbol is a real function reference. */
835
836 /* FIXME-SOON If for some reason the definition label/symbol is
837 never seen, this will probably leave an undefined symbol at link
838 time. */
839
840 if (S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_EFCN
841 || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_LABEL
842 || (!strcmp (bfd_get_section_name (stdoutput,
843 S_GET_SEGMENT (def_symbol_in_progress)),
844 "*DEBUG*")
845 && !SF_GET_TAG (def_symbol_in_progress))
846 || S_GET_SEGMENT (def_symbol_in_progress) == absolute_section
847 || ! symbol_constant_p (def_symbol_in_progress)
848 || (symbolP = symbol_find_base (S_GET_NAME (def_symbol_in_progress),
849 DO_NOT_STRIP)) == NULL
850 || SF_GET_TAG (def_symbol_in_progress) != SF_GET_TAG (symbolP))
851 {
852 /* If it already is at the end of the symbol list, do nothing */
853 if (def_symbol_in_progress != symbol_lastP)
854 {
855 symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
856 symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP,
857 &symbol_lastP);
858 }
859 }
860 else
861 {
862 /* This symbol already exists, merge the newly created symbol
863 into the old one. This is not mandatory. The linker can
864 handle duplicate symbols correctly. But I guess that it save
865 a *lot* of space if the assembly file defines a lot of
866 symbols. [loic] */
867
868 /* The debug entry (def_symbol_in_progress) is merged into the
869 previous definition. */
870
871 c_symbol_merge (def_symbol_in_progress, symbolP);
872 symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
873
874 def_symbol_in_progress = symbolP;
875
876 if (SF_GET_FUNCTION (def_symbol_in_progress)
877 || SF_GET_TAG (def_symbol_in_progress)
878 || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_STAT)
879 {
880 /* For functions, and tags, and static symbols, the symbol
881 *must* be where the debug symbol appears. Move the
882 existing symbol to the current place. */
883 /* If it already is at the end of the symbol list, do nothing */
884 if (def_symbol_in_progress != symbol_lastP)
885 {
886 symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
887 symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
888 }
889 }
890 }
891
892 if (SF_GET_TAG (def_symbol_in_progress))
893 {
894 symbolS *oldtag;
895
896 oldtag = symbol_find_base (S_GET_NAME (def_symbol_in_progress),
897 DO_NOT_STRIP);
898 if (oldtag == NULL || ! SF_GET_TAG (oldtag))
899 tag_insert (S_GET_NAME (def_symbol_in_progress),
900 def_symbol_in_progress);
901 }
902
903 if (SF_GET_FUNCTION (def_symbol_in_progress))
904 {
905 know (sizeof (def_symbol_in_progress) <= sizeof (long));
906 set_function (def_symbol_in_progress);
907 SF_SET_PROCESS (def_symbol_in_progress);
908
909 if (symbolP == NULL)
910 {
911 /* That is, if this is the first time we've seen the
912 function... */
913 symbol_table_insert (def_symbol_in_progress);
914 } /* definition follows debug */
915 } /* Create the line number entry pointing to the function being defined */
916
917 def_symbol_in_progress = NULL;
918 demand_empty_rest_of_line ();
919}
920
921static void
922obj_coff_dim (ignore)
923 int ignore ATTRIBUTE_UNUSED;
924{
925 int dim_index;
926
927 if (def_symbol_in_progress == NULL)
928 {
929 as_warn (_(".dim pseudo-op used outside of .def/.endef: ignored."));
930 demand_empty_rest_of_line ();
931 return;
932 } /* if not inside .def/.endef */
933
934 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
935
936 for (dim_index = 0; dim_index < DIMNUM; dim_index++)
937 {
938 SKIP_WHITESPACES ();
939 SA_SET_SYM_DIMEN (def_symbol_in_progress, dim_index,
940 get_absolute_expression ());
941
942 switch (*input_line_pointer)
943 {
944 case ',':
945 input_line_pointer++;
946 break;
947
948 default:
949 as_warn (_("badly formed .dim directive ignored"));
950 /* intentional fallthrough */
951 case '\n':
952 case ';':
953 dim_index = DIMNUM;
954 break;
955 }
956 }
957
958 demand_empty_rest_of_line ();
959}
960
961static void
962obj_coff_line (ignore)
963 int ignore ATTRIBUTE_UNUSED;
964{
965 int this_base;
966
967 if (def_symbol_in_progress == NULL)
968 {
969 /* Probably stabs-style line? */
970 obj_coff_ln (0);
971 return;
972 }
973
974 this_base = get_absolute_expression ();
975 if (!strcmp (".bf", S_GET_NAME (def_symbol_in_progress)))
976 coff_line_base = this_base;
977
978 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
979 SA_SET_SYM_LNNO (def_symbol_in_progress, this_base);
980
981 demand_empty_rest_of_line ();
982
983#ifndef NO_LISTING
984 if (strcmp (".bf", S_GET_NAME (def_symbol_in_progress)) == 0)
985 {
986 extern int listing;
987
988 if (listing)
989 listing_source_line ((unsigned int) this_base);
990 }
991#endif
992}
993
994static void
995obj_coff_size (ignore)
996 int ignore ATTRIBUTE_UNUSED;
997{
998 if (def_symbol_in_progress == NULL)
999 {
1000 as_warn (_(".size pseudo-op used outside of .def/.endef ignored."));
1001 demand_empty_rest_of_line ();
1002 return;
1003 } /* if not inside .def/.endef */
1004
1005 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
1006 SA_SET_SYM_SIZE (def_symbol_in_progress, get_absolute_expression ());
1007 demand_empty_rest_of_line ();
1008}
1009
1010static void
1011obj_coff_scl (ignore)
1012 int ignore ATTRIBUTE_UNUSED;
1013{
1014 if (def_symbol_in_progress == NULL)
1015 {
1016 as_warn (_(".scl pseudo-op used outside of .def/.endef ignored."));
1017 demand_empty_rest_of_line ();
1018 return;
1019 } /* if not inside .def/.endef */
1020
1021 S_SET_STORAGE_CLASS (def_symbol_in_progress, get_absolute_expression ());
1022 demand_empty_rest_of_line ();
1023}
1024
1025static void
1026obj_coff_tag (ignore)
1027 int ignore ATTRIBUTE_UNUSED;
1028{
1029 char *symbol_name;
1030 char name_end;
1031
1032 if (def_symbol_in_progress == NULL)
1033 {
1034 as_warn (_(".tag pseudo-op used outside of .def/.endef ignored."));
1035 demand_empty_rest_of_line ();
1036 return;
1037 }
1038
1039 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
1040 symbol_name = input_line_pointer;
1041 name_end = get_symbol_end ();
1042
1043#ifdef tc_canonicalize_symbol_name
1044 symbol_name = tc_canonicalize_symbol_name (symbol_name);
1045#endif
1046
1047 /* Assume that the symbol referred to by .tag is always defined.
1048 This was a bad assumption. I've added find_or_make. xoxorich. */
1049 SA_SET_SYM_TAGNDX (def_symbol_in_progress,
1050 tag_find_or_make (symbol_name));
1051 if (SA_GET_SYM_TAGNDX (def_symbol_in_progress) == 0L)
1052 {
1053 as_warn (_("tag not found for .tag %s"), symbol_name);
1054 } /* not defined */
1055
1056 SF_SET_TAGGED (def_symbol_in_progress);
1057 *input_line_pointer = name_end;
1058
1059 demand_empty_rest_of_line ();
1060}
1061
1062static void
1063obj_coff_type (ignore)
1064 int ignore ATTRIBUTE_UNUSED;
1065{
1066 if (def_symbol_in_progress == NULL)
1067 {
1068 as_warn (_(".type pseudo-op used outside of .def/.endef ignored."));
1069 demand_empty_rest_of_line ();
1070 return;
1071 } /* if not inside .def/.endef */
1072
1073 S_SET_DATA_TYPE (def_symbol_in_progress, get_absolute_expression ());
1074
1075 if (ISFCN (S_GET_DATA_TYPE (def_symbol_in_progress)) &&
1076 S_GET_STORAGE_CLASS (def_symbol_in_progress) != C_TPDEF)
1077 {
1078 SF_SET_FUNCTION (def_symbol_in_progress);
1079 } /* is a function */
1080
1081 demand_empty_rest_of_line ();
1082}
1083
1084static void
1085obj_coff_val (ignore)
1086 int ignore ATTRIBUTE_UNUSED;
1087{
1088 if (def_symbol_in_progress == NULL)
1089 {
1090 as_warn (_(".val pseudo-op used outside of .def/.endef ignored."));
1091 demand_empty_rest_of_line ();
1092 return;
1093 } /* if not inside .def/.endef */
1094
1095 if (is_name_beginner (*input_line_pointer))
1096 {
1097 char *symbol_name = input_line_pointer;
1098 char name_end = get_symbol_end ();
1099
1100#ifdef tc_canonicalize_symbol_name
1101 symbol_name = tc_canonicalize_symbol_name (symbol_name);
1102#endif
1103 if (!strcmp (symbol_name, "."))
1104 {
1105 symbol_set_frag (def_symbol_in_progress, frag_now);
1106 S_SET_VALUE (def_symbol_in_progress, (valueT) frag_now_fix ());
1107 /* If the .val is != from the .def (e.g. statics) */
1108 }
1109 else if (strcmp (S_GET_NAME (def_symbol_in_progress), symbol_name))
1110 {
1111 expressionS exp;
1112
1113 exp.X_op = O_symbol;
1114 exp.X_add_symbol = symbol_find_or_make (symbol_name);
1115 exp.X_op_symbol = NULL;
1116 exp.X_add_number = 0;
1117 symbol_set_value_expression (def_symbol_in_progress, &exp);
1118
1119 /* If the segment is undefined when the forward reference is
1120 resolved, then copy the segment id from the forward
1121 symbol. */
1122 SF_SET_GET_SEGMENT (def_symbol_in_progress);
1123
1124 /* FIXME: gcc can generate address expressions here in
1125 unusual cases (search for "obscure" in sdbout.c). We
1126 just ignore the offset here, thus generating incorrect
1127 debugging information. We ignore the rest of the line
1128 just below. */
1129 }
1130 /* Otherwise, it is the name of a non debug symbol and its value
1131 will be calculated later. */
1132 *input_line_pointer = name_end;
1133 }
1134 else
1135 {
1136 S_SET_VALUE (def_symbol_in_progress, get_absolute_expression ());
1137 } /* if symbol based */
1138
1139 demand_empty_rest_of_line ();
1140}
1141
1142void
1143coff_obj_read_begin_hook ()
1144{
1145 /* These had better be the same. Usually 18 bytes. */
1146#ifndef BFD_HEADERS
1147 know (sizeof (SYMENT) == sizeof (AUXENT));
1148 know (SYMESZ == AUXESZ);
1149#endif
1150 tag_init ();
1151}
1152
1153symbolS *coff_last_function;
1154#ifndef OBJ_XCOFF
1155static symbolS *coff_last_bf;
1156#endif
1157
1158void
1159coff_frob_symbol (symp, punt)
1160 symbolS *symp;
1161 int *punt;
1162{
1163 static symbolS *last_tagP;
1164 static stack *block_stack;
1165 static symbolS *set_end;
1166 symbolS *next_set_end = NULL;
1167
1168 if (symp == &abs_symbol)
1169 {
1170 *punt = 1;
1171 return;
1172 }
1173
1174 if (current_lineno_sym)
1175 coff_add_linesym ((symbolS *) 0);
1176
1177 if (!block_stack)
1178 block_stack = stack_init (512, sizeof (symbolS*));
1179
1180 if (S_IS_WEAK (symp))
1181 {
1182#ifdef TE_PE
1183 S_SET_STORAGE_CLASS (symp, C_NT_WEAK);
1184#else
1185 S_SET_STORAGE_CLASS (symp, C_WEAKEXT);
1186#endif
1187 }
1188
1189 if (!S_IS_DEFINED (symp)
1190 && !S_IS_WEAK (symp)
1191 && S_GET_STORAGE_CLASS (symp) != C_STAT)
1192 S_SET_STORAGE_CLASS (symp, C_EXT);
1193
1194 if (!SF_GET_DEBUG (symp))
1195 {
1196 symbolS * real;
1197
1198 if (!SF_GET_LOCAL (symp)
1199 && !SF_GET_STATICS (symp)
1200 && S_GET_STORAGE_CLASS (symp) != C_LABEL
1201 && symbol_constant_p(symp)
1202 && (real = symbol_find_base (S_GET_NAME (symp), DO_NOT_STRIP))
1203 && S_GET_STORAGE_CLASS (real) == C_NULL
1204 && real != symp)
1205 {
1206 c_symbol_merge (symp, real);
1207 *punt = 1;
1208 return;
1209 }
1210
1211 if (!S_IS_DEFINED (symp) && !SF_GET_LOCAL (symp))
1212 {
1213 assert (S_GET_VALUE (symp) == 0);
1214 S_SET_EXTERNAL (symp);
1215 }
1216 else if (S_GET_STORAGE_CLASS (symp) == C_NULL)
1217 {
1218 if (S_GET_SEGMENT (symp) == text_section
1219 && symp != seg_info (text_section)->sym)
1220 S_SET_STORAGE_CLASS (symp, C_LABEL);
1221 else
1222 S_SET_STORAGE_CLASS (symp, C_STAT);
1223 }
1224
1225 if (SF_GET_PROCESS (symp))
1226 {
1227 if (S_GET_STORAGE_CLASS (symp) == C_BLOCK)
1228 {
1229 if (!strcmp (S_GET_NAME (symp), ".bb"))
1230 stack_push (block_stack, (char *) &symp);
1231 else
1232 {
1233 symbolS *begin;
1234
1235 begin = *(symbolS **) stack_pop (block_stack);
1236 if (begin == 0)
1237 as_warn (_("mismatched .eb"));
1238 else
1239 next_set_end = begin;
1240 }
1241 }
1242
1243 if (coff_last_function == 0 && SF_GET_FUNCTION (symp))
1244 {
1245 union internal_auxent *auxp;
1246
1247 coff_last_function = symp;
1248 if (S_GET_NUMBER_AUXILIARY (symp) < 1)
1249 S_SET_NUMBER_AUXILIARY (symp, 1);
1250 auxp = SYM_AUXENT (symp);
1251 memset (auxp->x_sym.x_fcnary.x_ary.x_dimen, 0,
1252 sizeof (auxp->x_sym.x_fcnary.x_ary.x_dimen));
1253 }
1254
1255 if (S_GET_STORAGE_CLASS (symp) == C_EFCN)
1256 {
1257 if (coff_last_function == 0)
1258 as_fatal (_("C_EFCN symbol out of scope"));
1259 SA_SET_SYM_FSIZE (coff_last_function,
1260 (long) (S_GET_VALUE (symp)
1261 - S_GET_VALUE (coff_last_function)));
1262 next_set_end = coff_last_function;
1263 coff_last_function = 0;
1264 }
1265 }
1266
1267 if (S_IS_EXTERNAL (symp))
1268 S_SET_STORAGE_CLASS (symp, C_EXT);
1269 else if (SF_GET_LOCAL (symp))
1270 *punt = 1;
1271
1272 if (SF_GET_FUNCTION (symp))
1273 symbol_get_bfdsym (symp)->flags |= BSF_FUNCTION;
1274
1275 /* more ... */
1276 }
1277
1278 /* Double check weak symbols. */
1279 if (S_IS_WEAK (symp) && S_IS_COMMON (symp))
1280 as_bad (_("Symbol `%s' can not be both weak and common"),
1281 S_GET_NAME (symp));
1282
1283 if (SF_GET_TAG (symp))
1284 last_tagP = symp;
1285 else if (S_GET_STORAGE_CLASS (symp) == C_EOS)
1286 next_set_end = last_tagP;
1287
1288#ifdef OBJ_XCOFF
1289 /* This is pretty horrible, but we have to set *punt correctly in
1290 order to call SA_SET_SYM_ENDNDX correctly. */
1291 if (! symbol_used_in_reloc_p (symp)
1292 && ((symbol_get_bfdsym (symp)->flags & BSF_SECTION_SYM) != 0
1293 || (! S_IS_EXTERNAL (symp)
1294 && ! symbol_get_tc (symp)->output
1295 && S_GET_STORAGE_CLASS (symp) != C_FILE)))
1296 *punt = 1;
1297#endif
1298
1299 if (set_end != (symbolS *) NULL
1300 && ! *punt
1301 && ((symbol_get_bfdsym (symp)->flags & BSF_NOT_AT_END) != 0
1302 || (S_IS_DEFINED (symp)
1303 && ! S_IS_COMMON (symp)
1304 && (! S_IS_EXTERNAL (symp) || SF_GET_FUNCTION (symp)))))
1305 {
1306 SA_SET_SYM_ENDNDX (set_end, symp);
1307 set_end = NULL;
1308 }
1309
1310 if (next_set_end != NULL)
1311 {
1312 if (set_end != NULL)
1313 as_warn ("Warning: internal error: forgetting to set endndx of %s",
1314 S_GET_NAME (set_end));
1315 set_end = next_set_end;
1316 }
1317
1318#ifndef OBJ_XCOFF
1319 if (! *punt
1320 && S_GET_STORAGE_CLASS (symp) == C_FCN
1321 && strcmp (S_GET_NAME (symp), ".bf") == 0)
1322 {
1323 if (coff_last_bf != NULL)
1324 SA_SET_SYM_ENDNDX (coff_last_bf, symp);
1325 coff_last_bf = symp;
1326 }
1327#endif
1328 if (coffsymbol (symbol_get_bfdsym (symp))->lineno)
1329 {
1330 int i;
1331 struct line_no *lptr;
1332 alent *l;
1333
1334 lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno;
1335 for (i = 0; lptr; lptr = lptr->next)
1336 i++;
1337 lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno;
1338
1339 /* We need i entries for line numbers, plus 1 for the first
1340 entry which BFD will override, plus 1 for the last zero
1341 entry (a marker for BFD). */
1342 l = (alent *) xmalloc ((i + 2) * sizeof (alent));
1343 coffsymbol (symbol_get_bfdsym (symp))->lineno = l;
1344 l[i + 1].line_number = 0;
1345 l[i + 1].u.sym = NULL;
1346 for (; i > 0; i--)
1347 {
1348 if (lptr->frag)
1349 lptr->l.u.offset += lptr->frag->fr_address / OCTETS_PER_BYTE;
1350 l[i] = lptr->l;
1351 lptr = lptr->next;
1352 }
1353 }
1354}
1355
1356void
1357coff_adjust_section_syms (abfd, sec, x)
1358 bfd *abfd ATTRIBUTE_UNUSED;
1359 asection *sec;
1360 PTR x ATTRIBUTE_UNUSED;
1361{
1362 symbolS *secsym;
1363 segment_info_type *seginfo = seg_info (sec);
1364 int nlnno, nrelocs = 0;
1365
1366 /* RS/6000 gas creates a .debug section manually in ppc_frob_file in
1367 tc-ppc.c. Do not get confused by it. */
1368 if (seginfo == NULL)
1369 return;
1370
1371 if (!strcmp (sec->name, ".text"))
1372 nlnno = coff_n_line_nos;
1373 else
1374 nlnno = 0;
1375 {
1376 /* @@ Hope that none of the fixups expand to more than one reloc
1377 entry... */
1378 fixS *fixp = seginfo->fix_root;
1379 while (fixp)
1380 {
1381 if (! fixp->fx_done)
1382 nrelocs++;
1383 fixp = fixp->fx_next;
1384 }
1385 }
1386 if (bfd_get_section_size_before_reloc (sec) == 0
1387 && nrelocs == 0
1388 && nlnno == 0
1389 && sec != text_section
1390 && sec != data_section
1391 && sec != bss_section)
1392 return;
1393 secsym = section_symbol (sec);
1394 /* This is an estimate; we'll plug in the real value using
1395 SET_SECTION_RELOCS later */
1396 SA_SET_SCN_NRELOC (secsym, nrelocs);
1397 SA_SET_SCN_NLINNO (secsym, nlnno);
1398}
1399
1400void
1401coff_frob_file_after_relocs ()
1402{
1403 bfd_map_over_sections (stdoutput, coff_adjust_section_syms, (char*) 0);
1404}
1405
1406/* Implement the .section pseudo op:
1407 .section name {, "flags"}
1408 ^ ^
1409 | +--- optional flags: 'b' for bss
1410 | 'i' for info
1411 +-- section name 'l' for lib
1412 'n' for noload
1413 'o' for over
1414 'w' for data
1415 'd' (apparently m88k for data)
1416 'x' for text
1417 'r' for read-only data
1418 's' for shared data (PE)
1419 But if the argument is not a quoted string, treat it as a
1420 subsegment number.
1421
1422 Note the 'a' flag is silently ignored. This allows the same
1423 .section directive to be parsed in both ELF and COFF formats. */
1424
1425void
1426obj_coff_section (ignore)
1427 int ignore ATTRIBUTE_UNUSED;
1428{
1429 /* Strip out the section name */
1430 char *section_name;
1431 char c;
1432 char *name;
1433 unsigned int exp;
1434 flagword flags, oldflags;
1435 asection *sec;
1436
1437 if (flag_mri)
1438 {
1439 char type;
1440
1441 s_mri_sect (&type);
1442 return;
1443 }
1444
1445 section_name = input_line_pointer;
1446 c = get_symbol_end ();
1447
1448 name = xmalloc (input_line_pointer - section_name + 1);
1449 strcpy (name, section_name);
1450
1451 *input_line_pointer = c;
1452
1453 SKIP_WHITESPACE ();
1454
1455 exp = 0;
1456 flags = SEC_NO_FLAGS;
1457
1458 if (*input_line_pointer == ',')
1459 {
1460 ++input_line_pointer;
1461 SKIP_WHITESPACE ();
1462 if (*input_line_pointer != '"')
1463 exp = get_absolute_expression ();
1464 else
1465 {
1466 ++input_line_pointer;
1467 while (*input_line_pointer != '"'
1468 && ! is_end_of_line[(unsigned char) *input_line_pointer])
1469 {
1470 switch (*input_line_pointer)
1471 {
1472 case 'b': flags |= SEC_ALLOC; flags &=~ SEC_LOAD; break;
1473 case 'n': flags &=~ SEC_LOAD; flags |= SEC_NEVER_LOAD; break;
1474
1475 case 's': flags |= SEC_SHARED; /* fall through */
1476 case 'd': flags |= SEC_DATA | SEC_LOAD; /* fall through */
1477 case 'w': flags &=~ SEC_READONLY; break;
1478
1479 case 'a': break; /* For compatability with ELF. */
1480 case 'x': flags |= SEC_CODE | SEC_LOAD; break;
1481 case 'r': flags |= SEC_READONLY; break;
1482
1483 case 'i': /* STYP_INFO */
1484 case 'l': /* STYP_LIB */
1485 case 'o': /* STYP_OVER */
1486 as_warn (_("unsupported section attribute '%c'"),
1487 *input_line_pointer);
1488 break;
1489
1490 default:
1491 as_warn(_("unknown section attribute '%c'"),
1492 *input_line_pointer);
1493 break;
1494 }
1495 ++input_line_pointer;
1496 }
1497 if (*input_line_pointer == '"')
1498 ++input_line_pointer;
1499 }
1500 }
1501
1502 sec = subseg_new (name, (subsegT) exp);
1503
1504 oldflags = bfd_get_section_flags (stdoutput, sec);
1505 if (oldflags == SEC_NO_FLAGS)
1506 {
1507 /* Set section flags for a new section just created by subseg_new.
1508 Provide a default if no flags were parsed. */
1509 if (flags == SEC_NO_FLAGS)
1510 flags = TC_COFF_SECTION_DEFAULT_ATTRIBUTES;
1511
1512#ifdef COFF_LONG_SECTION_NAMES
1513 /* Add SEC_LINK_ONCE and SEC_LINK_DUPLICATES_DISCARD to .gnu.linkonce
1514 sections so adjust_reloc_syms in write.c will correctly handle
1515 relocs which refer to non-local symbols in these sections. */
1516 if (strncmp (name, ".gnu.linkonce", sizeof (".gnu.linkonce") - 1) == 0)
1517 flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
1518#endif
1519
1520 if (! bfd_set_section_flags (stdoutput, sec, flags))
1521 as_warn (_("error setting flags for \"%s\": %s"),
1522 bfd_section_name (stdoutput, sec),
1523 bfd_errmsg (bfd_get_error ()));
1524 }
1525 else if (flags != SEC_NO_FLAGS)
1526 {
1527 /* This section's attributes have already been set. Warn if the
1528 attributes don't match. */
1529 flagword matchflags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
1530 | SEC_DATA | SEC_SHARED | SEC_NEVER_LOAD);
1531 if ((flags ^ oldflags) & matchflags)
1532 as_warn (_("Ignoring changed section attributes for %s"), name);
1533 }
1534
1535 demand_empty_rest_of_line ();
1536}
1537
1538void
1539coff_adjust_symtab ()
1540{
1541 if (symbol_rootP == NULL
1542 || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
1543 c_dot_file_symbol ("fake");
1544}
1545
1546void
1547coff_frob_section (sec)
1548 segT sec;
1549{
1550 segT strsec;
1551 char *p;
1552 fragS *fragp;
1553 bfd_vma size, n_entries, mask;
1554 bfd_vma align_power = (bfd_vma)sec->alignment_power + OCTETS_PER_BYTE_POWER;
1555
1556 /* The COFF back end in BFD requires that all section sizes be
1557 rounded up to multiples of the corresponding section alignments,
1558 supposedly because standard COFF has no other way of encoding alignment
1559 for sections. If your COFF flavor has a different way of encoding
1560 section alignment, then skip this step, as TICOFF does. */
1561 size = bfd_get_section_size_before_reloc (sec);
1562 mask = ((bfd_vma) 1 << align_power) - 1;
1563#if !defined(TICOFF)
1564 if (size & mask)
1565 {
1566 bfd_vma new_size;
1567 fragS *last;
1568
1569 new_size = (size + mask) & ~mask;
1570 bfd_set_section_size (stdoutput, sec, new_size);
1571
1572 /* If the size had to be rounded up, add some padding in
1573 the last non-empty frag. */
1574 fragp = seg_info (sec)->frchainP->frch_root;
1575 last = seg_info (sec)->frchainP->frch_last;
1576 while (fragp->fr_next != last)
1577 fragp = fragp->fr_next;
1578 last->fr_address = size;
1579 fragp->fr_offset += new_size - size;
1580 }
1581#endif
1582
1583 /* If the section size is non-zero, the section symbol needs an aux
1584 entry associated with it, indicating the size. We don't know
1585 all the values yet; coff_frob_symbol will fill them in later. */
1586#ifndef TICOFF
1587 if (size != 0
1588 || sec == text_section
1589 || sec == data_section
1590 || sec == bss_section)
1591#endif
1592 {
1593 symbolS *secsym = section_symbol (sec);
1594
1595 S_SET_STORAGE_CLASS (secsym, C_STAT);
1596 S_SET_NUMBER_AUXILIARY (secsym, 1);
1597 SF_SET_STATICS (secsym);
1598 SA_SET_SCN_SCNLEN (secsym, size);
1599 }
1600
1601 /* @@ these should be in a "stabs.h" file, or maybe as.h */
1602#ifndef STAB_SECTION_NAME
1603#define STAB_SECTION_NAME ".stab"
1604#endif
1605#ifndef STAB_STRING_SECTION_NAME
1606#define STAB_STRING_SECTION_NAME ".stabstr"
1607#endif
1608 if (strcmp (STAB_STRING_SECTION_NAME, sec->name))
1609 return;
1610
1611 strsec = sec;
1612 sec = subseg_get (STAB_SECTION_NAME, 0);
1613 /* size is already rounded up, since other section will be listed first */
1614 size = bfd_get_section_size_before_reloc (strsec);
1615
1616 n_entries = bfd_get_section_size_before_reloc (sec) / 12 - 1;
1617
1618 /* Find first non-empty frag. It should be large enough. */
1619 fragp = seg_info (sec)->frchainP->frch_root;
1620 while (fragp && fragp->fr_fix == 0)
1621 fragp = fragp->fr_next;
1622 assert (fragp != 0 && fragp->fr_fix >= 12);
1623
1624 /* Store the values. */
1625 p = fragp->fr_literal;
1626 bfd_h_put_16 (stdoutput, n_entries, (bfd_byte *) p + 6);
1627 bfd_h_put_32 (stdoutput, size, (bfd_byte *) p + 8);
1628}
1629
1630void
1631obj_coff_init_stab_section (seg)
1632 segT seg;
1633{
1634 char *file;
1635 char *p;
1636 char *stabstr_name;
1637 unsigned int stroff;
1638
1639 /* Make space for this first symbol. */
1640 p = frag_more (12);
1641 /* Zero it out. */
1642 memset (p, 0, 12);
1643 as_where (&file, (unsigned int *) NULL);
1644 stabstr_name = (char *) xmalloc (strlen (seg->name) + 4);
1645 strcpy (stabstr_name, seg->name);
1646 strcat (stabstr_name, "str");
1647 stroff = get_stab_string_offset (file, stabstr_name);
1648 know (stroff == 1);
1649 md_number_to_chars (p, stroff, 4);
1650}
1651
1652#ifdef DEBUG
1653/* for debugging */
1654const char *
1655s_get_name (s)
1656 symbolS *s;
1657{
1658 return ((s == NULL) ? "(NULL)" : S_GET_NAME (s));
1659}
1660
1661void
1662symbol_dump ()
1663{
1664 symbolS *symbolP;
1665
1666 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
1667 {
1668 printf (_("0x%lx: \"%s\" type = %ld, class = %d, segment = %d\n"),
1669 (unsigned long) symbolP,
1670 S_GET_NAME(symbolP),
1671 (long) S_GET_DATA_TYPE(symbolP),
1672 S_GET_STORAGE_CLASS(symbolP),
1673 (int) S_GET_SEGMENT(symbolP));
1674 }
1675}
1676
1677#endif /* DEBUG */
1678
1679#else /* not BFD_ASSEMBLER */
1680
1681#include "frags.h"
1682/* This is needed because we include internal bfd things. */
1683#include <time.h>
1684
1685#include "libbfd.h"
1686#include "libcoff.h"
1687
1688#ifdef TE_PE
1689#include "coff/pe.h"
1690#endif
1691
1692/* The NOP_OPCODE is for the alignment fill value. Fill with nop so
1693 that we can stick sections together without causing trouble. */
1694#ifndef NOP_OPCODE
1695#define NOP_OPCODE 0x00
1696#endif
1697
1698/* The zeroes if symbol name is longer than 8 chars */
1699#define S_SET_ZEROES(s,v) ((s)->sy_symbol.ost_entry.n_zeroes = (v))
1700
1701#define MIN(a,b) ((a) < (b)? (a) : (b))
1702
1703/* This vector is used to turn a gas internal segment number into a
1704 section number suitable for insertion into a coff symbol table.
1705 This must correspond to seg_info_off_by_4. */
1706
1707const short seg_N_TYPE[] =
1708{ /* in: segT out: N_TYPE bits */
1709 C_ABS_SECTION,
1710 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
1711 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
1712 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
1713 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
1714 C_UNDEF_SECTION, /* SEG_UNKNOWN */
1715 C_UNDEF_SECTION, /* SEG_GOOF */
1716 C_UNDEF_SECTION, /* SEG_EXPR */
1717 C_DEBUG_SECTION, /* SEG_DEBUG */
1718 C_NTV_SECTION, /* SEG_NTV */
1719 C_PTV_SECTION, /* SEG_PTV */
1720 C_REGISTER_SECTION, /* SEG_REGISTER */
1721};
1722
1723int function_lineoff = -1; /* Offset in line#s where the last function
1724 started (the odd entry for line #0) */
1725
1726/* Structure used to keep the filenames which
1727 are too long around so that we can stick them
1728 into the string table. */
1729struct filename_list
1730{
1731 char *filename;
1732 struct filename_list *next;
1733};
1734
1735static struct filename_list *filename_list_head;
1736static struct filename_list *filename_list_tail;
1737
1738static symbolS *last_line_symbol;
1739
1740/* Add 4 to the real value to get the index and compensate the
1741 negatives. This vector is used by S_GET_SEGMENT to turn a coff
1742 section number into a segment number. */
1743
1744bfd *abfd;
1745static symbolS *previous_file_symbol;
1746static int line_base;
1747
1748void c_symbol_merge PARAMS ((symbolS *, symbolS *));
1749symbolS *c_section_symbol PARAMS ((char *, int));
1750void obj_coff_section PARAMS ((int));
1751void do_relocs_for PARAMS ((bfd *, object_headers *, unsigned long *));
1752char * symbol_to_chars PARAMS ((bfd *, char *, symbolS *));
1753void w_strings PARAMS ((char *));
1754
1755static void fixup_segment PARAMS ((segment_info_type *, segT));
1756static void fixup_mdeps PARAMS ((fragS *, object_headers *, segT));
1757static void fill_section PARAMS ((bfd *, object_headers *, unsigned long *));
1758static int c_line_new PARAMS ((symbolS *, long, int, fragS *));
1759static void w_symbols PARAMS ((bfd *, char *, symbolS *));
1760static void adjust_stab_section PARAMS ((bfd *, segT));
1761static void obj_coff_lcomm PARAMS ((int));
1762static void obj_coff_text PARAMS ((int));
1763static void obj_coff_data PARAMS ((int));
1764static unsigned int count_entries_in_chain PARAMS ((unsigned int));
1765static void coff_header_append PARAMS ((bfd *, object_headers *));
1766static unsigned int yank_symbols PARAMS ((void));
1767static unsigned int glue_symbols PARAMS ((symbolS **, symbolS **));
1768static unsigned int tie_tags PARAMS ((void));
1769static void crawl_symbols PARAMS ((object_headers *, bfd *));
1770static void do_linenos_for PARAMS ((bfd *, object_headers *, unsigned long *));
1771static void remove_subsegs PARAMS ((void));
1772
1773
1774
1775/* When not using BFD_ASSEMBLER, we permit up to 40 sections.
1776
1777 This array maps a COFF section number into a gas section number.
1778 Because COFF uses negative section numbers, you must add 4 to the
1779 COFF section number when indexing into this array; this is done via
1780 the SEG_INFO_FROM_SECTION_NUMBER macro. This must correspond to
1781 seg_N_TYPE. */
1782
1783static const segT seg_info_off_by_4[] =
1784{
1785 SEG_PTV,
1786 SEG_NTV,
1787 SEG_DEBUG,
1788 SEG_ABSOLUTE,
1789 SEG_UNKNOWN,
1790 SEG_E0, SEG_E1, SEG_E2, SEG_E3, SEG_E4,
1791 SEG_E5, SEG_E6, SEG_E7, SEG_E8, SEG_E9,
1792 SEG_E10, SEG_E11, SEG_E12, SEG_E13, SEG_E14,
1793 SEG_E15, SEG_E16, SEG_E17, SEG_E18, SEG_E19,
1794 SEG_E20, SEG_E21, SEG_E22, SEG_E23, SEG_E24,
1795 SEG_E25, SEG_E26, SEG_E27, SEG_E28, SEG_E29,
1796 SEG_E30, SEG_E31, SEG_E32, SEG_E33, SEG_E34,
1797 SEG_E35, SEG_E36, SEG_E37, SEG_E38, SEG_E39,
1798 (segT) 40,
1799 (segT) 41,
1800 (segT) 42,
1801 (segT) 43,
1802 (segT) 44,
1803 (segT) 45,
1804 (segT) 0,
1805 (segT) 0,
1806 (segT) 0,
1807 SEG_REGISTER
1808};
1809
1810#define SEG_INFO_FROM_SECTION_NUMBER(x) (seg_info_off_by_4[(x)+4])
1811
1812static relax_addressT relax_align PARAMS ((relax_addressT, long));
1813
1814static relax_addressT
1815relax_align (address, alignment)
1816 relax_addressT address;
1817 long alignment;
1818{
1819 relax_addressT mask;
1820 relax_addressT new_address;
1821
1822 mask = ~((~0) << alignment);
1823 new_address = (address + mask) & (~mask);
1824 return (new_address - address);
1825}
1826
1827segT
1828s_get_segment (x)
1829 symbolS * x;
1830{
1831 return SEG_INFO_FROM_SECTION_NUMBER (x->sy_symbol.ost_entry.n_scnum);
1832}
1833
1834static unsigned int size_section PARAMS ((bfd *, unsigned int));
1835
1836/* Calculate the size of the frag chain and fill in the section header
1837 to contain all of it, also fill in the addr of the sections. */
1838
1839static unsigned int
1840size_section (abfd, idx)
1841 bfd *abfd ATTRIBUTE_UNUSED;
1842 unsigned int idx;
1843{
1844
1845 unsigned int size = 0;
1846 fragS *frag = segment_info[idx].frchainP->frch_root;
1847
1848 while (frag)
1849 {
1850 size = frag->fr_address;
1851 if (frag->fr_address != size)
1852 {
1853 fprintf (stderr, _("Out of step\n"));
1854 size = frag->fr_address;
1855 }
1856
1857 switch (frag->fr_type)
1858 {
1859#ifdef TC_COFF_SIZEMACHDEP
1860 case rs_machine_dependent:
1861 size += TC_COFF_SIZEMACHDEP (frag);
1862 break;
1863#endif
1864 case rs_space:
1865 case rs_fill:
1866 case rs_org:
1867 size += frag->fr_fix;
1868 size += frag->fr_offset * frag->fr_var;
1869 break;
1870 case rs_align:
1871 case rs_align_code:
1872 case rs_align_test:
1873 {
1874 addressT off;
1875
1876 size += frag->fr_fix;
1877 off = relax_align (size, frag->fr_offset);
1878 if (frag->fr_subtype != 0 && off > frag->fr_subtype)
1879 off = 0;
1880 size += off;
1881 }
1882 break;
1883 default:
1884 BAD_CASE (frag->fr_type);
1885 break;
1886 }
1887 frag = frag->fr_next;
1888 }
1889 segment_info[idx].scnhdr.s_size = size;
1890 return size;
1891}
1892
1893static unsigned int
1894count_entries_in_chain (idx)
1895 unsigned int idx;
1896{
1897 unsigned int nrelocs;
1898 fixS *fixup_ptr;
1899
1900 /* Count the relocations. */
1901 fixup_ptr = segment_info[idx].fix_root;
1902 nrelocs = 0;
1903 while (fixup_ptr != (fixS *) NULL)
1904 {
1905 if (fixup_ptr->fx_done == 0 && TC_COUNT_RELOC (fixup_ptr))
1906 {
1907#if defined(TC_A29K) || defined(TC_OR32)
1908 if (fixup_ptr->fx_r_type == RELOC_CONSTH)
1909 nrelocs += 2;
1910 else
1911 nrelocs++;
1912#else
1913 nrelocs++;
1914#endif
1915 }
1916
1917 fixup_ptr = fixup_ptr->fx_next;
1918 }
1919 return nrelocs;
1920}
1921
1922#ifdef TE_AUX
1923
1924static int compare_external_relocs PARAMS ((const PTR, const PTR));
1925
1926/* AUX's ld expects relocations to be sorted. */
1927
1928static int
1929compare_external_relocs (x, y)
1930 const PTR x;
1931 const PTR y;
1932{
1933 struct external_reloc *a = (struct external_reloc *) x;
1934 struct external_reloc *b = (struct external_reloc *) y;
1935 bfd_vma aadr = bfd_getb32 (a->r_vaddr);
1936 bfd_vma badr = bfd_getb32 (b->r_vaddr);
1937 return (aadr < badr ? -1 : badr < aadr ? 1 : 0);
1938}
1939
1940#endif
1941
1942/* Output all the relocations for a section. */
1943
1944void
1945do_relocs_for (abfd, h, file_cursor)
1946 bfd * abfd;
1947 object_headers * h;
1948 unsigned long *file_cursor;
1949{
1950 unsigned int nrelocs;
1951 unsigned int idx;
1952 unsigned long reloc_start = *file_cursor;
1953
1954 for (idx = SEG_E0; idx < SEG_LAST; idx++)
1955 {
1956 if (segment_info[idx].scnhdr.s_name[0])
1957 {
1958 struct external_reloc *ext_ptr;
1959 struct external_reloc *external_reloc_vec;
1960 unsigned int external_reloc_size;
1961 unsigned int base = segment_info[idx].scnhdr.s_paddr;
1962 fixS *fix_ptr = segment_info[idx].fix_root;
1963 nrelocs = count_entries_in_chain (idx);
1964
1965 if (nrelocs)
1966 /* Bypass this stuff if no relocs. This also incidentally
1967 avoids a SCO bug, where free(malloc(0)) tends to crash. */
1968 {
1969 external_reloc_size = nrelocs * RELSZ;
1970 external_reloc_vec =
1971 (struct external_reloc *) malloc (external_reloc_size);
1972
1973 ext_ptr = external_reloc_vec;
1974
1975 /* Fill in the internal coff style reloc struct from the
1976 internal fix list. */
1977 while (fix_ptr)
1978 {
1979 struct internal_reloc intr;
1980
1981 /* Only output some of the relocations. */
1982 if (fix_ptr->fx_done == 0 && TC_COUNT_RELOC (fix_ptr))
1983 {
1984#ifdef TC_RELOC_MANGLE
1985 TC_RELOC_MANGLE (&segment_info[idx], fix_ptr, &intr,
1986 base);
1987#else
1988 symbolS *dot;
1989 symbolS *symbol_ptr = fix_ptr->fx_addsy;
1990
1991 intr.r_type = TC_COFF_FIX2RTYPE (fix_ptr);
1992 intr.r_vaddr =
1993 base + fix_ptr->fx_frag->fr_address + fix_ptr->fx_where;
1994
1995#ifdef TC_KEEP_FX_OFFSET
1996 intr.r_offset = fix_ptr->fx_offset;
1997#else
1998 intr.r_offset = 0;
1999#endif
2000
2001 while (symbol_ptr->sy_value.X_op == O_symbol
2002 && (! S_IS_DEFINED (symbol_ptr)
2003 || S_IS_COMMON (symbol_ptr)))
2004 {
2005 symbolS *n;
2006
2007 /* We must avoid looping, as that can occur
2008 with a badly written program. */
2009 n = symbol_ptr->sy_value.X_add_symbol;
2010 if (n == symbol_ptr)
2011 break;
2012 symbol_ptr = n;
2013 }
2014
2015 /* Turn the segment of the symbol into an offset. */
2016 if (symbol_ptr)
2017 {
2018 resolve_symbol_value (symbol_ptr);
2019 if (! symbol_ptr->sy_resolved)
2020 {
2021 char *file;
2022 unsigned int line;
2023
2024 if (expr_symbol_where (symbol_ptr, &file, &line))
2025 as_bad_where (file, line,
2026 _("unresolved relocation"));
2027 else
2028 as_bad (_("bad relocation: symbol `%s' not in symbol table"),
2029 S_GET_NAME (symbol_ptr));
2030 }
2031
2032 dot = segment_info[S_GET_SEGMENT (symbol_ptr)].dot;
2033 if (dot)
2034 intr.r_symndx = dot->sy_number;
2035 else
2036 intr.r_symndx = symbol_ptr->sy_number;
2037 }
2038 else
2039 intr.r_symndx = -1;
2040#endif
2041 (void) bfd_coff_swap_reloc_out (abfd, &intr, ext_ptr);
2042 ext_ptr++;
2043#if defined(TC_A29K)
2044 /* The 29k has a special kludge for the high 16 bit
2045 reloc. Two relocations are emited, R_IHIHALF,
2046 and R_IHCONST. The second one doesn't contain a
2047 symbol, but uses the value for offset. */
2048 if (intr.r_type == R_IHIHALF)
2049 {
2050 /* Now emit the second bit. */
2051 intr.r_type = R_IHCONST;
2052 intr.r_symndx = fix_ptr->fx_addnumber;
2053 (void) bfd_coff_swap_reloc_out (abfd, &intr, ext_ptr);
2054 ext_ptr++;
2055 }
2056#endif
2057#if defined(TC_OR32)
2058 /* The or32 has a special kludge for the high 16 bit
2059 reloc. Two relocations are emited, R_IHIHALF,
2060 and R_IHCONST. The second one doesn't contain a
2061 symbol, but uses the value for offset. */
2062 if (intr.r_type == R_IHIHALF)
2063 {
2064 /* Now emit the second bit. */
2065 intr.r_type = R_IHCONST;
2066 intr.r_symndx = fix_ptr->fx_addnumber;
2067 (void) bfd_coff_swap_reloc_out (abfd, & intr, ext_ptr);
2068 ext_ptr ++;
2069 }
2070#endif
2071 }
2072
2073 fix_ptr = fix_ptr->fx_next;
2074 }
2075#ifdef TE_AUX
2076 /* Sort the reloc table. */
2077 qsort ((PTR) external_reloc_vec, nrelocs,
2078 sizeof (struct external_reloc), compare_external_relocs);
2079#endif
2080 /* Write out the reloc table. */
2081 bfd_bwrite ((PTR) external_reloc_vec,
2082 (bfd_size_type) external_reloc_size, abfd);
2083 free (external_reloc_vec);
2084
2085 /* Fill in section header info. */
2086 segment_info[idx].scnhdr.s_relptr = *file_cursor;
2087 *file_cursor += external_reloc_size;
2088 segment_info[idx].scnhdr.s_nreloc = nrelocs;
2089 }
2090 else
2091 {
2092 /* No relocs. */
2093 segment_info[idx].scnhdr.s_relptr = 0;
2094 }
2095 }
2096 }
2097
2098 /* Set relocation_size field in file headers. */
2099 H_SET_RELOCATION_SIZE (h, *file_cursor - reloc_start, 0);
2100}
2101
2102/* Run through a frag chain and write out the data to go with it, fill
2103 in the scnhdrs with the info on the file postions. */
2104
2105static void
2106fill_section (abfd, h, file_cursor)
2107 bfd * abfd;
2108 object_headers *h ATTRIBUTE_UNUSED;
2109 unsigned long *file_cursor;
2110{
2111 unsigned int i;
2112 unsigned int paddr = 0;
2113
2114 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
2115 {
2116 unsigned int offset = 0;
2117 struct internal_scnhdr *s = &(segment_info[i].scnhdr);
2118
2119 PROGRESS (1);
2120
2121 if (s->s_name[0])
2122 {
2123 fragS *frag = segment_info[i].frchainP->frch_root;
2124 char *buffer = NULL;
2125
2126 if (s->s_size == 0)
2127 s->s_scnptr = 0;
2128 else
2129 {
2130 buffer = xmalloc (s->s_size);
2131 s->s_scnptr = *file_cursor;
2132 }
2133 know (s->s_paddr == paddr);
2134
2135 if (strcmp (s->s_name, ".text") == 0)
2136 s->s_flags |= STYP_TEXT;
2137 else if (strcmp (s->s_name, ".data") == 0)
2138 s->s_flags |= STYP_DATA;
2139 else if (strcmp (s->s_name, ".bss") == 0)
2140 {
2141 s->s_scnptr = 0;
2142 s->s_flags |= STYP_BSS;
2143
2144 /* @@ Should make the i386 and a29k coff targets define
2145 COFF_NOLOAD_PROBLEM, and have only one test here. */
2146#ifndef TC_I386
2147#ifndef TC_A29K
2148#ifndef TC_OR32
2149#ifndef COFF_NOLOAD_PROBLEM
2150 /* Apparently the SVR3 linker (and exec syscall) and UDI
2151 mondfe progrem are confused by noload sections. */
2152 s->s_flags |= STYP_NOLOAD;
2153#endif
2154#endif
2155#endif
2156#endif
2157 }
2158 else if (strcmp (s->s_name, ".lit") == 0)
2159 s->s_flags = STYP_LIT | STYP_TEXT;
2160 else if (strcmp (s->s_name, ".init") == 0)
2161 s->s_flags |= STYP_TEXT;
2162 else if (strcmp (s->s_name, ".fini") == 0)
2163 s->s_flags |= STYP_TEXT;
2164 else if (strncmp (s->s_name, ".comment", 8) == 0)
2165 s->s_flags |= STYP_INFO;
2166
2167 while (frag)
2168 {
2169 unsigned int fill_size;
2170 switch (frag->fr_type)
2171 {
2172 case rs_machine_dependent:
2173 if (frag->fr_fix)
2174 {
2175 memcpy (buffer + frag->fr_address,
2176 frag->fr_literal,
2177 (unsigned int) frag->fr_fix);
2178 offset += frag->fr_fix;
2179 }
2180
2181 break;
2182 case rs_space:
2183 case rs_fill:
2184 case rs_align:
2185 case rs_align_code:
2186 case rs_align_test:
2187 case rs_org:
2188 if (frag->fr_fix)
2189 {
2190 memcpy (buffer + frag->fr_address,
2191 frag->fr_literal,
2192 (unsigned int) frag->fr_fix);
2193 offset += frag->fr_fix;
2194 }
2195
2196 fill_size = frag->fr_var;
2197 if (fill_size && frag->fr_offset > 0)
2198 {
2199 unsigned int count;
2200 unsigned int off = frag->fr_fix;
2201 for (count = frag->fr_offset; count; count--)
2202 {
2203 if (fill_size + frag->fr_address + off <= s->s_size)
2204 {
2205 memcpy (buffer + frag->fr_address + off,
2206 frag->fr_literal + frag->fr_fix,
2207 fill_size);
2208 off += fill_size;
2209 offset += fill_size;
2210 }
2211 }
2212 }
2213 break;
2214 case rs_broken_word:
2215 break;
2216 default:
2217 abort ();
2218 }
2219 frag = frag->fr_next;
2220 }
2221
2222 if (s->s_size != 0)
2223 {
2224 if (s->s_scnptr != 0)
2225 {
2226 bfd_bwrite (buffer, s->s_size, abfd);
2227 *file_cursor += s->s_size;
2228 }
2229 free (buffer);
2230 }
2231 paddr += s->s_size;
2232 }
2233 }
2234}
2235
2236/* Coff file generation & utilities. */
2237
2238static void
2239coff_header_append (abfd, h)
2240 bfd * abfd;
2241 object_headers * h;
2242{
2243 unsigned int i;
2244 char buffer[1000];
2245 char buffero[1000];
2246#ifdef COFF_LONG_SECTION_NAMES
2247 unsigned long string_size = 4;
2248#endif
2249
2250 bfd_seek (abfd, (file_ptr) 0, 0);
2251
2252#ifndef OBJ_COFF_OMIT_OPTIONAL_HEADER
2253 H_SET_MAGIC_NUMBER (h, COFF_MAGIC);
2254 H_SET_VERSION_STAMP (h, 0);
2255 H_SET_ENTRY_POINT (h, 0);
2256 H_SET_TEXT_START (h, segment_info[SEG_E0].frchainP->frch_root->fr_address);
2257 H_SET_DATA_START (h, segment_info[SEG_E1].frchainP->frch_root->fr_address);
2258 H_SET_SIZEOF_OPTIONAL_HEADER (h, bfd_coff_swap_aouthdr_out(abfd, &h->aouthdr,
2259 buffero));
2260#else /* defined (OBJ_COFF_OMIT_OPTIONAL_HEADER) */
2261 H_SET_SIZEOF_OPTIONAL_HEADER (h, 0);
2262#endif /* defined (OBJ_COFF_OMIT_OPTIONAL_HEADER) */
2263
2264 i = bfd_coff_swap_filehdr_out (abfd, &h->filehdr, buffer);
2265
2266 bfd_bwrite (buffer, (bfd_size_type) i, abfd);
2267 bfd_bwrite (buffero, (bfd_size_type) H_GET_SIZEOF_OPTIONAL_HEADER (h), abfd);
2268
2269 for (i = SEG_E0; i < SEG_LAST; i++)
2270 {
2271 if (segment_info[i].scnhdr.s_name[0])
2272 {
2273 unsigned int size;
2274
2275#ifdef COFF_LONG_SECTION_NAMES
2276 /* Support long section names as found in PE. This code
2277 must coordinate with that in write_object_file and
2278 w_strings. */
2279 if (strlen (segment_info[i].name) > SCNNMLEN)
2280 {
2281 memset (segment_info[i].scnhdr.s_name, 0, SCNNMLEN);
2282 sprintf (segment_info[i].scnhdr.s_name, "/%lu", string_size);
2283 string_size += strlen (segment_info[i].name) + 1;
2284 }
2285#endif
2286 size = bfd_coff_swap_scnhdr_out (abfd,
2287 &(segment_info[i].scnhdr),
2288 buffer);
2289 if (size == 0)
2290 as_bad (_("bfd_coff_swap_scnhdr_out failed"));
2291 bfd_bwrite (buffer, (bfd_size_type) size, abfd);
2292 }
2293 }
2294}
2295
2296char *
2297symbol_to_chars (abfd, where, symbolP)
2298 bfd * abfd;
2299 char *where;
2300 symbolS * symbolP;
2301{
2302 unsigned int numaux = symbolP->sy_symbol.ost_entry.n_numaux;
2303 unsigned int i;
2304 valueT val;
2305
2306 /* Turn any symbols with register attributes into abs symbols. */
2307 if (S_GET_SEGMENT (symbolP) == reg_section)
2308 S_SET_SEGMENT (symbolP, absolute_section);
2309
2310 /* At the same time, relocate all symbols to their output value. */
2311#ifndef TE_PE
2312 val = (segment_info[S_GET_SEGMENT (symbolP)].scnhdr.s_paddr
2313 + S_GET_VALUE (symbolP));
2314#else
2315 val = S_GET_VALUE (symbolP);
2316#endif
2317
2318 S_SET_VALUE (symbolP, val);
2319
2320 symbolP->sy_symbol.ost_entry.n_value = val;
2321
2322 where += bfd_coff_swap_sym_out (abfd, &symbolP->sy_symbol.ost_entry,
2323 where);
2324
2325 for (i = 0; i < numaux; i++)
2326 {
2327 where += bfd_coff_swap_aux_out (abfd,
2328 &symbolP->sy_symbol.ost_auxent[i],
2329 S_GET_DATA_TYPE (symbolP),
2330 S_GET_STORAGE_CLASS (symbolP),
2331 i, numaux, where);
2332 }
2333
2334 return where;
2335}
2336
2337void
2338coff_obj_symbol_new_hook (symbolP)
2339 symbolS *symbolP;
2340{
2341 char underscore = 0; /* Symbol has leading _ */
2342
2343 /* Effective symbol. */
2344 /* Store the pointer in the offset. */
2345 S_SET_ZEROES (symbolP, 0L);
2346 S_SET_DATA_TYPE (symbolP, T_NULL);
2347 S_SET_STORAGE_CLASS (symbolP, 0);
2348 S_SET_NUMBER_AUXILIARY (symbolP, 0);
2349 /* Additional information. */
2350 symbolP->sy_symbol.ost_flags = 0;
2351 /* Auxiliary entries. */
2352 memset ((char *) &symbolP->sy_symbol.ost_auxent[0], 0, AUXESZ);
2353
2354 if (S_IS_STRING (symbolP))
2355 SF_SET_STRING (symbolP);
2356 if (!underscore && S_IS_LOCAL (symbolP))
2357 SF_SET_LOCAL (symbolP);
2358}
2359
2360/* Handle .ln directives. */
2361
2362static void
2363obj_coff_ln (appline)
2364 int appline;
2365{
2366 int l;
2367
2368 if (! appline && def_symbol_in_progress != NULL)
2369 {
2370 /* Wrong context. */
2371 as_warn (_(".ln pseudo-op inside .def/.endef: ignored."));
2372 demand_empty_rest_of_line ();
2373 return;
2374 }
2375
2376 l = get_absolute_expression ();
2377 c_line_new (0, frag_now_fix (), l, frag_now);
2378
2379 if (appline)
2380 new_logical_line ((char *) NULL, l - 1);
2381
2382#ifndef NO_LISTING
2383 {
2384 extern int listing;
2385
2386 if (listing)
2387 {
2388 if (! appline)
2389 l += line_base - 1;
2390 listing_source_line ((unsigned int) l);
2391 }
2392
2393 }
2394#endif
2395 demand_empty_rest_of_line ();
2396}
2397
2398/* Handle .def directives.
2399
2400 One might ask : why can't we symbol_new if the symbol does not
2401 already exist and fill it with debug information. Because of
2402 the C_EFCN special symbol. It would clobber the value of the
2403 function symbol before we have a chance to notice that it is
2404 a C_EFCN. And a second reason is that the code is more clear this
2405 way. (at least I think it is :-). */
2406
2407#define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';')
2408#define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \
2409 *input_line_pointer == '\t') \
2410 input_line_pointer++;
2411
2412static void
2413obj_coff_def (what)
2414 int what ATTRIBUTE_UNUSED;
2415{
2416 char name_end; /* Char after the end of name. */
2417 char *symbol_name; /* Name of the debug symbol. */
2418 char *symbol_name_copy; /* Temporary copy of the name. */
2419 unsigned int symbol_name_length;
2420
2421 if (def_symbol_in_progress != NULL)
2422 {
2423 as_warn (_(".def pseudo-op used inside of .def/.endef: ignored."));
2424 demand_empty_rest_of_line ();
2425 return;
2426 }
2427
2428 SKIP_WHITESPACES ();
2429
2430 def_symbol_in_progress = (symbolS *) obstack_alloc (&notes, sizeof (*def_symbol_in_progress));
2431 memset (def_symbol_in_progress, 0, sizeof (*def_symbol_in_progress));
2432
2433 symbol_name = input_line_pointer;
2434 name_end = get_symbol_end ();
2435 symbol_name_length = strlen (symbol_name);
2436 symbol_name_copy = xmalloc (symbol_name_length + 1);
2437 strcpy (symbol_name_copy, symbol_name);
2438#ifdef tc_canonicalize_symbol_name
2439 symbol_name_copy = tc_canonicalize_symbol_name (symbol_name_copy);
2440#endif
2441
2442 /* Initialize the new symbol. */
2443#ifdef STRIP_UNDERSCORE
2444 S_SET_NAME (def_symbol_in_progress, (*symbol_name_copy == '_'
2445 ? symbol_name_copy + 1
2446 : symbol_name_copy));
2447#else /* STRIP_UNDERSCORE */
2448 S_SET_NAME (def_symbol_in_progress, symbol_name_copy);
2449#endif /* STRIP_UNDERSCORE */
2450 /* free(symbol_name_copy); */
2451 def_symbol_in_progress->sy_name_offset = (unsigned long) ~0;
2452 def_symbol_in_progress->sy_number = ~0;
2453 def_symbol_in_progress->sy_frag = &zero_address_frag;
2454 S_SET_VALUE (def_symbol_in_progress, 0);
2455
2456 if (S_IS_STRING (def_symbol_in_progress))
2457 SF_SET_STRING (def_symbol_in_progress);
2458
2459 *input_line_pointer = name_end;
2460
2461 demand_empty_rest_of_line ();
2462}
2463
2464unsigned int dim_index;
2465
2466static void
2467obj_coff_endef (ignore)
2468 int ignore ATTRIBUTE_UNUSED;
2469{
2470 symbolS *symbolP = 0;
2471 /* DIM BUG FIX sac@cygnus.com */
2472 dim_index = 0;
2473 if (def_symbol_in_progress == NULL)
2474 {
2475 as_warn (_(".endef pseudo-op used outside of .def/.endef: ignored."));
2476 demand_empty_rest_of_line ();
2477 return;
2478 }
2479
2480 /* Set the section number according to storage class. */
2481 switch (S_GET_STORAGE_CLASS (def_symbol_in_progress))
2482 {
2483 case C_STRTAG:
2484 case C_ENTAG:
2485 case C_UNTAG:
2486 SF_SET_TAG (def_symbol_in_progress);
2487 /* Intentional fallthrough. */
2488
2489 case C_FILE:
2490 case C_TPDEF:
2491 SF_SET_DEBUG (def_symbol_in_progress);
2492 S_SET_SEGMENT (def_symbol_in_progress, SEG_DEBUG);
2493 break;
2494
2495 case C_EFCN:
2496 /* Do not emit this symbol. */
2497 SF_SET_LOCAL (def_symbol_in_progress);
2498 /* Intentional fallthrough. */
2499
2500 case C_BLOCK:
2501 /* Will need processing before writing. */
2502 SF_SET_PROCESS (def_symbol_in_progress);
2503 /* Intentional fallthrough. */
2504
2505 case C_FCN:
2506 S_SET_SEGMENT (def_symbol_in_progress, SEG_E0);
2507
2508 if (strcmp (S_GET_NAME (def_symbol_in_progress), ".bf") == 0)
2509 { /* .bf */
2510 if (function_lineoff < 0)
2511 fprintf (stderr, _("`.bf' symbol without preceding function\n"));
2512
2513 SA_GET_SYM_LNNOPTR (last_line_symbol) = function_lineoff;
2514
2515 SF_SET_PROCESS (last_line_symbol);
2516 SF_SET_ADJ_LNNOPTR (last_line_symbol);
2517 SF_SET_PROCESS (def_symbol_in_progress);
2518 function_lineoff = -1;
2519 }
2520
2521 /* Value is always set to . */
2522 def_symbol_in_progress->sy_frag = frag_now;
2523 S_SET_VALUE (def_symbol_in_progress, (valueT) frag_now_fix ());
2524 break;
2525
2526#ifdef C_AUTOARG
2527 case C_AUTOARG:
2528#endif /* C_AUTOARG */
2529 case C_AUTO:
2530 case C_REG:
2531 case C_MOS:
2532 case C_MOE:
2533 case C_MOU:
2534 case C_ARG:
2535 case C_REGPARM:
2536 case C_FIELD:
2537 case C_EOS:
2538 SF_SET_DEBUG (def_symbol_in_progress);
2539 S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
2540 break;
2541
2542 case C_EXT:
2543 case C_WEAKEXT:
2544#ifdef TE_PE
2545 case C_NT_WEAK:
2546#endif
2547 case C_STAT:
2548 case C_LABEL:
2549 /* Valid but set somewhere else (s_comm, s_lcomm, colon). */
2550 break;
2551
2552 case C_USTATIC:
2553 case C_EXTDEF:
2554 case C_ULABEL:
2555 as_warn (_("unexpected storage class %d"), S_GET_STORAGE_CLASS (def_symbol_in_progress));
2556 break;
2557 }
2558
2559 /* Now that we have built a debug symbol, try to find if we should
2560 merge with an existing symbol or not. If a symbol is C_EFCN or
2561 absolute_section or untagged SEG_DEBUG it never merges. We also
2562 don't merge labels, which are in a different namespace, nor
2563 symbols which have not yet been defined since they are typically
2564 unique, nor do we merge tags with non-tags. */
2565
2566 /* Two cases for functions. Either debug followed by definition or
2567 definition followed by debug. For definition first, we will
2568 merge the debug symbol into the definition. For debug first, the
2569 lineno entry MUST point to the definition function or else it
2570 will point off into space when crawl_symbols() merges the debug
2571 symbol into the real symbol. Therefor, let's presume the debug
2572 symbol is a real function reference. */
2573
2574 /* FIXME-SOON If for some reason the definition label/symbol is
2575 never seen, this will probably leave an undefined symbol at link
2576 time. */
2577
2578 if (S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_EFCN
2579 || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_LABEL
2580 || (S_GET_SEGMENT (def_symbol_in_progress) == SEG_DEBUG
2581 && !SF_GET_TAG (def_symbol_in_progress))
2582 || S_GET_SEGMENT (def_symbol_in_progress) == absolute_section
2583 || def_symbol_in_progress->sy_value.X_op != O_constant
2584 || (symbolP = symbol_find_base (S_GET_NAME (def_symbol_in_progress), DO_NOT_STRIP)) == NULL
2585 || (SF_GET_TAG (def_symbol_in_progress) != SF_GET_TAG (symbolP)))
2586 {
2587 symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP,
2588 &symbol_lastP);
2589 }
2590 else
2591 {
2592 /* This symbol already exists, merge the newly created symbol
2593 into the old one. This is not mandatory. The linker can
2594 handle duplicate symbols correctly. But I guess that it save
2595 a *lot* of space if the assembly file defines a lot of
2596 symbols. [loic] */
2597
2598 /* The debug entry (def_symbol_in_progress) is merged into the
2599 previous definition. */
2600
2601 c_symbol_merge (def_symbol_in_progress, symbolP);
2602 /* FIXME-SOON Should *def_symbol_in_progress be free'd? xoxorich. */
2603 def_symbol_in_progress = symbolP;
2604
2605 if (SF_GET_FUNCTION (def_symbol_in_progress)
2606 || SF_GET_TAG (def_symbol_in_progress)
2607 || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_STAT)
2608 {
2609 /* For functions, and tags, and static symbols, the symbol
2610 *must* be where the debug symbol appears. Move the
2611 existing symbol to the current place. */
2612 /* If it already is at the end of the symbol list, do nothing. */
2613 if (def_symbol_in_progress != symbol_lastP)
2614 {
2615 symbol_remove (def_symbol_in_progress, &symbol_rootP,
2616 &symbol_lastP);
2617 symbol_append (def_symbol_in_progress, symbol_lastP,
2618 &symbol_rootP, &symbol_lastP);
2619 }
2620 }
2621 }
2622
2623 if (SF_GET_TAG (def_symbol_in_progress))
2624 {
2625 symbolS *oldtag;
2626
2627 oldtag = symbol_find_base (S_GET_NAME (def_symbol_in_progress),
2628 DO_NOT_STRIP);
2629 if (oldtag == NULL || ! SF_GET_TAG (oldtag))
2630 tag_insert (S_GET_NAME (def_symbol_in_progress),
2631 def_symbol_in_progress);
2632 }
2633
2634 if (SF_GET_FUNCTION (def_symbol_in_progress))
2635 {
2636 know (sizeof (def_symbol_in_progress) <= sizeof (long));
2637 function_lineoff
2638 = c_line_new (def_symbol_in_progress, 0, 0, &zero_address_frag);
2639
2640 SF_SET_PROCESS (def_symbol_in_progress);
2641
2642 if (symbolP == NULL)
2643 {
2644 /* That is, if this is the first time we've seen the
2645 function... */
2646 symbol_table_insert (def_symbol_in_progress);
2647 }
2648 }
2649
2650 def_symbol_in_progress = NULL;
2651 demand_empty_rest_of_line ();
2652}
2653
2654static void
2655obj_coff_dim (ignore)
2656 int ignore ATTRIBUTE_UNUSED;
2657{
2658 int dim_index;
2659
2660 if (def_symbol_in_progress == NULL)
2661 {
2662 as_warn (_(".dim pseudo-op used outside of .def/.endef: ignored."));
2663 demand_empty_rest_of_line ();
2664 return;
2665 }
2666
2667 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
2668
2669 for (dim_index = 0; dim_index < DIMNUM; dim_index++)
2670 {
2671 SKIP_WHITESPACES ();
2672 SA_SET_SYM_DIMEN (def_symbol_in_progress, dim_index,
2673 get_absolute_expression ());
2674
2675 switch (*input_line_pointer)
2676 {
2677 case ',':
2678 input_line_pointer++;
2679 break;
2680
2681 default:
2682 as_warn (_("badly formed .dim directive ignored"));
2683 /* Intentional fallthrough. */
2684
2685 case '\n':
2686 case ';':
2687 dim_index = DIMNUM;
2688 break;
2689 }
2690 }
2691
2692 demand_empty_rest_of_line ();
2693}
2694
2695static void
2696obj_coff_line (ignore)
2697 int ignore ATTRIBUTE_UNUSED;
2698{
2699 int this_base;
2700 const char *name;
2701
2702 if (def_symbol_in_progress == NULL)
2703 {
2704 obj_coff_ln (0);
2705 return;
2706 }
2707
2708 name = S_GET_NAME (def_symbol_in_progress);
2709 this_base = get_absolute_expression ();
2710
2711 /* Only .bf symbols indicate the use of a new base line number; the
2712 line numbers associated with .ef, .bb, .eb are relative to the
2713 start of the containing function. */
2714 if (!strcmp (".bf", name))
2715 {
2716#if 0 /* XXX Can we ever have line numbers going backwards? */
2717 if (this_base > line_base)
2718#endif
2719 line_base = this_base;
2720
2721#ifndef NO_LISTING
2722 {
2723 extern int listing;
2724 if (listing)
2725 listing_source_line ((unsigned int) line_base);
2726 }
2727#endif
2728 }
2729
2730 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
2731 SA_SET_SYM_LNNO (def_symbol_in_progress, this_base);
2732
2733 demand_empty_rest_of_line ();
2734}
2735
2736static void
2737obj_coff_size (ignore)
2738 int ignore ATTRIBUTE_UNUSED;
2739{
2740 if (def_symbol_in_progress == NULL)
2741 {
2742 as_warn (_(".size pseudo-op used outside of .def/.endef ignored."));
2743 demand_empty_rest_of_line ();
2744 return;
2745 }
2746
2747 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
2748 SA_SET_SYM_SIZE (def_symbol_in_progress, get_absolute_expression ());
2749 demand_empty_rest_of_line ();
2750}
2751
2752static void
2753obj_coff_scl (ignore)
2754 int ignore ATTRIBUTE_UNUSED;
2755{
2756 if (def_symbol_in_progress == NULL)
2757 {
2758 as_warn (_(".scl pseudo-op used outside of .def/.endef ignored."));
2759 demand_empty_rest_of_line ();
2760 return;
2761 }
2762
2763 S_SET_STORAGE_CLASS (def_symbol_in_progress, get_absolute_expression ());
2764 demand_empty_rest_of_line ();
2765}
2766
2767static void
2768obj_coff_tag (ignore)
2769 int ignore ATTRIBUTE_UNUSED;
2770{
2771 char *symbol_name;
2772 char name_end;
2773
2774 if (def_symbol_in_progress == NULL)
2775 {
2776 as_warn (_(".tag pseudo-op used outside of .def/.endef ignored."));
2777 demand_empty_rest_of_line ();
2778 return;
2779 }
2780
2781 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
2782 symbol_name = input_line_pointer;
2783 name_end = get_symbol_end ();
2784#ifdef tc_canonicalize_symbol_name
2785 symbol_name = tc_canonicalize_symbol_name (symbol_name);
2786#endif
2787
2788 /* Assume that the symbol referred to by .tag is always defined.
2789 This was a bad assumption. I've added find_or_make. xoxorich. */
2790 SA_SET_SYM_TAGNDX (def_symbol_in_progress,
2791 (long) tag_find_or_make (symbol_name));
2792 if (SA_GET_SYM_TAGNDX (def_symbol_in_progress) == 0L)
2793 as_warn (_("tag not found for .tag %s"), symbol_name);
2794
2795 SF_SET_TAGGED (def_symbol_in_progress);
2796 *input_line_pointer = name_end;
2797
2798 demand_empty_rest_of_line ();
2799}
2800
2801static void
2802obj_coff_type (ignore)
2803 int ignore ATTRIBUTE_UNUSED;
2804{
2805 if (def_symbol_in_progress == NULL)
2806 {
2807 as_warn (_(".type pseudo-op used outside of .def/.endef ignored."));
2808 demand_empty_rest_of_line ();
2809 return;
2810 }
2811
2812 S_SET_DATA_TYPE (def_symbol_in_progress, get_absolute_expression ());
2813
2814 if (ISFCN (S_GET_DATA_TYPE (def_symbol_in_progress)) &&
2815 S_GET_STORAGE_CLASS (def_symbol_in_progress) != C_TPDEF)
2816 SF_SET_FUNCTION (def_symbol_in_progress);
2817
2818 demand_empty_rest_of_line ();
2819}
2820
2821static void
2822obj_coff_val (ignore)
2823 int ignore ATTRIBUTE_UNUSED;
2824{
2825 if (def_symbol_in_progress == NULL)
2826 {
2827 as_warn (_(".val pseudo-op used outside of .def/.endef ignored."));
2828 demand_empty_rest_of_line ();
2829 return;
2830 }
2831
2832 if (is_name_beginner (*input_line_pointer))
2833 {
2834 char *symbol_name = input_line_pointer;
2835 char name_end = get_symbol_end ();
2836
2837#ifdef tc_canonicalize_symbol_name
2838 symbol_name = tc_canonicalize_symbol_name (symbol_name);
2839#endif
2840
2841 if (!strcmp (symbol_name, "."))
2842 {
2843 def_symbol_in_progress->sy_frag = frag_now;
2844 S_SET_VALUE (def_symbol_in_progress, (valueT) frag_now_fix ());
2845 /* If the .val is != from the .def (e.g. statics). */
2846 }
2847 else if (strcmp (S_GET_NAME (def_symbol_in_progress), symbol_name))
2848 {
2849 def_symbol_in_progress->sy_value.X_op = O_symbol;
2850 def_symbol_in_progress->sy_value.X_add_symbol =
2851 symbol_find_or_make (symbol_name);
2852 def_symbol_in_progress->sy_value.X_op_symbol = NULL;
2853 def_symbol_in_progress->sy_value.X_add_number = 0;
2854
2855 /* If the segment is undefined when the forward reference is
2856 resolved, then copy the segment id from the forward
2857 symbol. */
2858 SF_SET_GET_SEGMENT (def_symbol_in_progress);
2859
2860 /* FIXME: gcc can generate address expressions here in
2861 unusual cases (search for "obscure" in sdbout.c). We
2862 just ignore the offset here, thus generating incorrect
2863 debugging information. We ignore the rest of the line
2864 just below. */
2865 }
2866 /* Otherwise, it is the name of a non debug symbol and
2867 its value will be calculated later. */
2868 *input_line_pointer = name_end;
2869
2870 /* FIXME: this is to avoid an error message in the
2871 FIXME case mentioned just above. */
2872 while (! is_end_of_line[(unsigned char) *input_line_pointer])
2873 ++input_line_pointer;
2874 }
2875 else
2876 {
2877 S_SET_VALUE (def_symbol_in_progress,
2878 (valueT) get_absolute_expression ());
2879 } /* if symbol based */
2880
2881 demand_empty_rest_of_line ();
2882}
2883
2884#ifdef TE_PE
2885
2886/* Handle the .linkonce pseudo-op. This is parsed by s_linkonce in
2887 read.c, which then calls this object file format specific routine. */
2888
2889void
2890obj_coff_pe_handle_link_once (type)
2891 enum linkonce_type type;
2892{
2893 seg_info (now_seg)->scnhdr.s_flags |= IMAGE_SCN_LNK_COMDAT;
2894
2895 /* We store the type in the seg_info structure, and use it to set up
2896 the auxiliary entry for the section symbol in c_section_symbol. */
2897 seg_info (now_seg)->linkonce = type;
2898}
2899
2900#endif /* TE_PE */
2901
2902void
2903coff_obj_read_begin_hook ()
2904{
2905 /* These had better be the same. Usually 18 bytes. */
2906#ifndef BFD_HEADERS
2907 know (sizeof (SYMENT) == sizeof (AUXENT));
2908 know (SYMESZ == AUXESZ);
2909#endif
2910 tag_init ();
2911}
2912
2913/* This function runs through the symbol table and puts all the
2914 externals onto another chain. */
2915
2916/* The chain of globals. */
2917symbolS *symbol_globalP;
2918symbolS *symbol_global_lastP;
2919
2920/* The chain of externals. */
2921symbolS *symbol_externP;
2922symbolS *symbol_extern_lastP;
2923
2924stack *block_stack;
2925symbolS *last_functionP;
2926static symbolS *last_bfP;
2927symbolS *last_tagP;
2928
2929static unsigned int
2930yank_symbols ()
2931{
2932 symbolS *symbolP;
2933 unsigned int symbol_number = 0;
2934 unsigned int last_file_symno = 0;
2935
2936 struct filename_list *filename_list_scan = filename_list_head;
2937
2938 for (symbolP = symbol_rootP;
2939 symbolP;
2940 symbolP = symbolP ? symbol_next (symbolP) : symbol_rootP)
2941 {
2942 if (symbolP->sy_mri_common)
2943 {
2944 if (S_GET_STORAGE_CLASS (symbolP) == C_EXT
2945#ifdef TE_PE
2946 || S_GET_STORAGE_CLASS (symbolP) == C_NT_WEAK
2947#endif
2948 || S_GET_STORAGE_CLASS (symbolP) == C_WEAKEXT)
2949 as_bad (_("%s: global symbols not supported in common sections"),
2950 S_GET_NAME (symbolP));
2951 symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
2952 continue;
2953 }
2954
2955 if (!SF_GET_DEBUG (symbolP))
2956 {
2957 /* Debug symbols do not need all this rubbish. */
2958 symbolS *real_symbolP;
2959
2960 /* L* and C_EFCN symbols never merge. */
2961 if (!SF_GET_LOCAL (symbolP)
2962 && !SF_GET_STATICS (symbolP)
2963 && S_GET_STORAGE_CLASS (symbolP) != C_LABEL
2964 && symbolP->sy_value.X_op == O_constant
2965 && (real_symbolP = symbol_find_base (S_GET_NAME (symbolP), DO_NOT_STRIP))
2966 && real_symbolP != symbolP)
2967 {
2968 /* FIXME-SOON: where do dups come from?
2969 Maybe tag references before definitions? xoxorich. */
2970 /* Move the debug data from the debug symbol to the
2971 real symbol. Do NOT do the oposite (i.e. move from
2972 real symbol to debug symbol and remove real symbol from the
2973 list.) Because some pointers refer to the real symbol
2974 whereas no pointers refer to the debug symbol. */
2975 c_symbol_merge (symbolP, real_symbolP);
2976 /* Replace the current symbol by the real one. */
2977 /* The symbols will never be the last or the first
2978 because : 1st symbol is .file and 3 last symbols are
2979 .text, .data, .bss. */
2980 symbol_remove (real_symbolP, &symbol_rootP, &symbol_lastP);
2981 symbol_insert (real_symbolP, symbolP, &symbol_rootP, &symbol_lastP);
2982 symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
2983 symbolP = real_symbolP;
2984 }
2985
2986 if (flag_readonly_data_in_text && (S_GET_SEGMENT (symbolP) == SEG_E1))
2987 S_SET_SEGMENT (symbolP, SEG_E0);
2988
2989 resolve_symbol_value (symbolP);
2990
2991 if (S_GET_STORAGE_CLASS (symbolP) == C_NULL)
2992 {
2993 if (!S_IS_DEFINED (symbolP) && !SF_GET_LOCAL (symbolP))
2994 {
2995 S_SET_EXTERNAL (symbolP);
2996 }
2997
2998 else if (S_GET_SEGMENT (symbolP) == SEG_E0)
2999 S_SET_STORAGE_CLASS (symbolP, C_LABEL);
3000
3001 else
3002 S_SET_STORAGE_CLASS (symbolP, C_STAT);
3003 }
3004
3005 /* Mainly to speed up if not -g. */
3006 if (SF_GET_PROCESS (symbolP))
3007 {
3008 /* Handle the nested blocks auxiliary info. */
3009 if (S_GET_STORAGE_CLASS (symbolP) == C_BLOCK)
3010 {
3011 if (!strcmp (S_GET_NAME (symbolP), ".bb"))
3012 stack_push (block_stack, (char *) &symbolP);
3013 else
3014 {
3015 /* .eb */
3016 symbolS *begin_symbolP;
3017
3018 begin_symbolP = *(symbolS **) stack_pop (block_stack);
3019 if (begin_symbolP == (symbolS *) 0)
3020 as_warn (_("mismatched .eb"));
3021 else
3022 SA_SET_SYM_ENDNDX (begin_symbolP, symbol_number + 2);
3023 }
3024 }
3025 /* If we are able to identify the type of a function, and we
3026 are out of a function (last_functionP == 0) then, the
3027 function symbol will be associated with an auxiliary
3028 entry. */
3029 if (last_functionP == (symbolS *) 0 &&
3030 SF_GET_FUNCTION (symbolP))
3031 {
3032 last_functionP = symbolP;
3033
3034 if (S_GET_NUMBER_AUXILIARY (symbolP) < 1)
3035 S_SET_NUMBER_AUXILIARY (symbolP, 1);
3036
3037 /* Clobber possible stale .dim information. */
3038#if 0
3039 /* Iffed out by steve - this fries the lnnoptr info too. */
3040 bzero (symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen,
3041 sizeof (symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen));
3042#endif
3043 }
3044 if (S_GET_STORAGE_CLASS (symbolP) == C_FCN)
3045 {
3046 if (strcmp (S_GET_NAME (symbolP), ".bf") == 0)
3047 {
3048 if (last_bfP != NULL)
3049 SA_SET_SYM_ENDNDX (last_bfP, symbol_number);
3050 last_bfP = symbolP;
3051 }
3052 }
3053 else if (S_GET_STORAGE_CLASS (symbolP) == C_EFCN)
3054 {
3055 /* I don't even know if this is needed for sdb. But
3056 the standard assembler generates it, so... */
3057 if (last_functionP == (symbolS *) 0)
3058 as_fatal (_("C_EFCN symbol out of scope"));
3059 SA_SET_SYM_FSIZE (last_functionP,
3060 (long) (S_GET_VALUE (symbolP) -
3061 S_GET_VALUE (last_functionP)));
3062 SA_SET_SYM_ENDNDX (last_functionP, symbol_number);
3063 last_functionP = (symbolS *) 0;
3064 }
3065 }
3066 }
3067 else if (SF_GET_TAG (symbolP))
3068 {
3069 /* First descriptor of a structure must point to
3070 the first slot after the structure description. */
3071 last_tagP = symbolP;
3072
3073 }
3074 else if (S_GET_STORAGE_CLASS (symbolP) == C_EOS)
3075 {
3076 /* +2 take in account the current symbol. */
3077 SA_SET_SYM_ENDNDX (last_tagP, symbol_number + 2);
3078 }
3079 else if (S_GET_STORAGE_CLASS (symbolP) == C_FILE)
3080 {
3081 /* If the filename was too long to fit in the
3082 auxent, put it in the string table. */
3083 if (SA_GET_FILE_FNAME_ZEROS (symbolP) == 0
3084 && SA_GET_FILE_FNAME_OFFSET (symbolP) != 0)
3085 {
3086 SA_SET_FILE_FNAME_OFFSET (symbolP, string_byte_count);
3087 string_byte_count += strlen (filename_list_scan->filename) + 1;
3088 filename_list_scan = filename_list_scan->next;
3089 }
3090 if (S_GET_VALUE (symbolP))
3091 {
3092 S_SET_VALUE (symbolP, last_file_symno);
3093 last_file_symno = symbol_number;
3094 }
3095 }
3096
3097#ifdef tc_frob_coff_symbol
3098 tc_frob_coff_symbol (symbolP);
3099#endif
3100
3101 /* We must put the external symbols apart. The loader
3102 does not bomb if we do not. But the references in
3103 the endndx field for a .bb symbol are not corrected
3104 if an external symbol is removed between .bb and .be.
3105 I.e in the following case :
3106 [20] .bb endndx = 22
3107 [21] foo external
3108 [22] .be
3109 ld will move the symbol 21 to the end of the list but
3110 endndx will still be 22 instead of 21. */
3111
3112 if (SF_GET_LOCAL (symbolP))
3113 {
3114 /* Remove C_EFCN and LOCAL (L...) symbols. */
3115 /* Next pointer remains valid. */
3116 symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
3117
3118 }
3119 else if (symbolP->sy_value.X_op == O_symbol
3120 && (! S_IS_DEFINED (symbolP) || S_IS_COMMON (symbolP)))
3121 {
3122 /* Skip symbols which were equated to undefined or common
3123 symbols. */
3124 symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
3125 }
3126 else if (!S_IS_DEFINED (symbolP)
3127 && !S_IS_DEBUG (symbolP)
3128 && !SF_GET_STATICS (symbolP)
3129 && (S_GET_STORAGE_CLASS (symbolP) == C_EXT
3130#ifdef TE_PE
3131 || S_GET_STORAGE_CLASS (symbolP) == C_NT_WEAK
3132#endif
3133 || S_GET_STORAGE_CLASS (symbolP) == C_WEAKEXT))
3134 {
3135 /* If external, Remove from the list. */
3136 symbolS *hold = symbol_previous (symbolP);
3137
3138 symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
3139 symbol_clear_list_pointers (symbolP);
3140 symbol_append (symbolP, symbol_extern_lastP, &symbol_externP, &symbol_extern_lastP);
3141 symbolP = hold;
3142 }
3143 else if (! S_IS_DEBUG (symbolP)
3144 && ! SF_GET_STATICS (symbolP)
3145 && ! SF_GET_FUNCTION (symbolP)
3146 && (S_GET_STORAGE_CLASS (symbolP) == C_EXT
3147#ifdef TE_PE
3148 || S_GET_STORAGE_CLASS (symbolP) == C_NT_WEAK
3149#endif
3150 || S_GET_STORAGE_CLASS (symbolP) == C_NT_WEAK))
3151 {
3152 symbolS *hold = symbol_previous (symbolP);
3153
3154 /* The O'Reilly COFF book says that defined global symbols
3155 come at the end of the symbol table, just before
3156 undefined global symbols. */
3157 symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
3158 symbol_clear_list_pointers (symbolP);
3159 symbol_append (symbolP, symbol_global_lastP, &symbol_globalP,
3160 &symbol_global_lastP);
3161 symbolP = hold;
3162 }
3163 else
3164 {
3165 if (SF_GET_STRING (symbolP))
3166 {
3167 symbolP->sy_name_offset = string_byte_count;
3168 string_byte_count += strlen (S_GET_NAME (symbolP)) + 1;
3169 }
3170 else
3171 {
3172 symbolP->sy_name_offset = 0;
3173 }
3174
3175 symbolP->sy_number = symbol_number;
3176 symbol_number += 1 + S_GET_NUMBER_AUXILIARY (symbolP);
3177 }
3178 }
3179
3180 return symbol_number;
3181}
3182
3183static unsigned int
3184glue_symbols (head, tail)
3185 symbolS **head;
3186 symbolS **tail;
3187{
3188 unsigned int symbol_number = 0;
3189
3190 while (*head != NULL)
3191 {
3192 symbolS *tmp = *head;
3193
3194 /* Append. */
3195 symbol_remove (tmp, head, tail);
3196 symbol_append (tmp, symbol_lastP, &symbol_rootP, &symbol_lastP);
3197
3198 /* Process. */
3199 if (SF_GET_STRING (tmp))
3200 {
3201 tmp->sy_name_offset = string_byte_count;
3202 string_byte_count += strlen (S_GET_NAME (tmp)) + 1;
3203 }
3204 else
3205 {
3206 /* Fix "long" names. */
3207 tmp->sy_name_offset = 0;
3208 }
3209
3210 tmp->sy_number = symbol_number;
3211 symbol_number += 1 + S_GET_NUMBER_AUXILIARY (tmp);
3212 }
3213
3214 return symbol_number;
3215}
3216
3217static unsigned int
3218tie_tags ()
3219{
3220 unsigned int symbol_number = 0;
3221 symbolS *symbolP;
3222
3223 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
3224 {
3225 symbolP->sy_number = symbol_number;
3226
3227 if (SF_GET_TAGGED (symbolP))
3228 {
3229 SA_SET_SYM_TAGNDX
3230 (symbolP,
3231 ((symbolS *) SA_GET_SYM_TAGNDX (symbolP))->sy_number);
3232 }
3233
3234 symbol_number += 1 + S_GET_NUMBER_AUXILIARY (symbolP);
3235 }
3236
3237 return symbol_number;
3238}
3239
3240
3241static void
3242crawl_symbols (h, abfd)
3243 object_headers *h;
3244 bfd *abfd ATTRIBUTE_UNUSED;
3245{
3246 unsigned int i;
3247
3248 /* Initialize the stack used to keep track of the matching .bb .be. */
3249
3250 block_stack = stack_init (512, sizeof (symbolS *));
3251
3252 /* The symbol list should be ordered according to the following sequence
3253 order :
3254 . .file symbol
3255 . debug entries for functions
3256 . fake symbols for the sections, including .text .data and .bss
3257 . defined symbols
3258 . undefined symbols
3259 But this is not mandatory. The only important point is to put the
3260 undefined symbols at the end of the list. */
3261
3262 /* Is there a .file symbol ? If not insert one at the beginning. */
3263 if (symbol_rootP == NULL
3264 || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
3265 c_dot_file_symbol ("fake");
3266
3267 /* Build up static symbols for the sections, they are filled in later. */
3268
3269 for (i = SEG_E0; i < SEG_LAST; i++)
3270 if (segment_info[i].scnhdr.s_name[0])
3271 segment_info[i].dot = c_section_symbol ((char *) segment_info[i].name,
3272 i - SEG_E0 + 1);
3273
3274 /* Take all the externals out and put them into another chain. */
3275 H_SET_SYMBOL_TABLE_SIZE (h, yank_symbols ());
3276 /* Take the externals and glue them onto the end. */
3277 H_SET_SYMBOL_TABLE_SIZE (h,
3278 (H_GET_SYMBOL_COUNT (h)
3279 + glue_symbols (&symbol_globalP,
3280 &symbol_global_lastP)
3281 + glue_symbols (&symbol_externP,
3282 &symbol_extern_lastP)));
3283
3284 H_SET_SYMBOL_TABLE_SIZE (h, tie_tags ());
3285 know (symbol_globalP == NULL);
3286 know (symbol_global_lastP == NULL);
3287 know (symbol_externP == NULL);
3288 know (symbol_extern_lastP == NULL);
3289}
3290
3291/* Find strings by crawling along symbol table chain. */
3292
3293void
3294w_strings (where)
3295 char *where;
3296{
3297 symbolS *symbolP;
3298 struct filename_list *filename_list_scan = filename_list_head;
3299
3300 /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK. */
3301 md_number_to_chars (where, (valueT) string_byte_count, 4);
3302 where += 4;
3303
3304#ifdef COFF_LONG_SECTION_NAMES
3305 /* Support long section names as found in PE. This code must
3306 coordinate with that in coff_header_append and write_object_file. */
3307 {
3308 unsigned int i;
3309
3310 for (i = SEG_E0; i < SEG_LAST; i++)
3311 {
3312 if (segment_info[i].scnhdr.s_name[0]
3313 && strlen (segment_info[i].name) > SCNNMLEN)
3314 {
3315 unsigned int size;
3316
3317 size = strlen (segment_info[i].name) + 1;
3318 memcpy (where, segment_info[i].name, size);
3319 where += size;
3320 }
3321 }
3322 }
3323#endif /* COFF_LONG_SECTION_NAMES */
3324
3325 for (symbolP = symbol_rootP;
3326 symbolP;
3327 symbolP = symbol_next (symbolP))
3328 {
3329 unsigned int size;
3330
3331 if (SF_GET_STRING (symbolP))
3332 {
3333 size = strlen (S_GET_NAME (symbolP)) + 1;
3334 memcpy (where, S_GET_NAME (symbolP), size);
3335 where += size;
3336 }
3337 if (S_GET_STORAGE_CLASS (symbolP) == C_FILE
3338 && SA_GET_FILE_FNAME_ZEROS (symbolP) == 0
3339 && SA_GET_FILE_FNAME_OFFSET (symbolP) != 0)
3340 {
3341 size = strlen (filename_list_scan->filename) + 1;
3342 memcpy (where, filename_list_scan->filename, size);
3343 filename_list_scan = filename_list_scan ->next;
3344 where += size;
3345 }
3346 }
3347}
3348
3349static void
3350do_linenos_for (abfd, h, file_cursor)
3351 bfd * abfd;
3352 object_headers * h;
3353 unsigned long *file_cursor;
3354{
3355 unsigned int idx;
3356 unsigned long start = *file_cursor;
3357
3358 for (idx = SEG_E0; idx < SEG_LAST; idx++)
3359 {
3360 segment_info_type *s = segment_info + idx;
3361
3362 if (s->scnhdr.s_nlnno != 0)
3363 {
3364 struct lineno_list *line_ptr;
3365
3366 struct external_lineno *buffer =
3367 (struct external_lineno *) xmalloc (s->scnhdr.s_nlnno * LINESZ);
3368
3369 struct external_lineno *dst = buffer;
3370
3371 /* Run through the table we've built and turn it into its external
3372 form, take this chance to remove duplicates. */
3373
3374 for (line_ptr = s->lineno_list_head;
3375 line_ptr != (struct lineno_list *) NULL;
3376 line_ptr = line_ptr->next)
3377 {
3378 if (line_ptr->line.l_lnno == 0)
3379 {
3380 /* Turn a pointer to a symbol into the symbols' index,
3381 provided that it has been initialised. */
3382 if (line_ptr->line.l_addr.l_symndx)
3383 line_ptr->line.l_addr.l_symndx =
3384 ((symbolS *) line_ptr->line.l_addr.l_symndx)->sy_number;
3385 }
3386 else
3387 line_ptr->line.l_addr.l_paddr += ((struct frag *) (line_ptr->frag))->fr_address;
3388
3389 (void) bfd_coff_swap_lineno_out (abfd, &(line_ptr->line), dst);
3390 dst++;
3391 }
3392
3393 s->scnhdr.s_lnnoptr = *file_cursor;
3394
3395 bfd_bwrite (buffer, (bfd_size_type) s->scnhdr.s_nlnno * LINESZ, abfd);
3396 free (buffer);
3397
3398 *file_cursor += s->scnhdr.s_nlnno * LINESZ;
3399 }
3400 }
3401
3402 H_SET_LINENO_SIZE (h, *file_cursor - start);
3403}
3404
3405/* Now we run through the list of frag chains in a segment and
3406 make all the subsegment frags appear at the end of the
3407 list, as if the seg 0 was extra long. */
3408
3409static void
3410remove_subsegs ()
3411{
3412 unsigned int i;
3413
3414 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
3415 {
3416 frchainS *head = segment_info[i].frchainP;
3417 fragS dummy;
3418 fragS *prev_frag = &dummy;
3419
3420 while (head && head->frch_seg == i)
3421 {
3422 prev_frag->fr_next = head->frch_root;
3423 prev_frag = head->frch_last;
3424 head = head->frch_next;
3425 }
3426 prev_frag->fr_next = 0;
3427 }
3428}
3429
3430unsigned long machine;
3431int coff_flags;
3432
3433#ifndef SUB_SEGMENT_ALIGN
3434#ifdef HANDLE_ALIGN
3435/* The last subsegment gets an aligment corresponding to the alignment
3436 of the section. This allows proper nop-filling at the end of
3437 code-bearing sections. */
3438#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) \
3439 (!(FRCHAIN)->frch_next || (FRCHAIN)->frch_next->frch_seg != (SEG) \
3440 ? get_recorded_alignment (SEG) : 0)
3441#else
3442#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 1
3443#endif
3444#endif
3445
3446extern void
3447write_object_file ()
3448{
3449 int i;
3450 const char *name;
3451 struct frchain *frchain_ptr;
3452
3453 object_headers headers;
3454 unsigned long file_cursor;
3455 bfd *abfd;
3456 unsigned int addr;
3457 abfd = bfd_openw (out_file_name, TARGET_FORMAT);
3458
3459 if (abfd == 0)
3460 {
3461 as_perror (_("FATAL: Can't create %s"), out_file_name);
3462 exit (EXIT_FAILURE);
3463 }
3464 bfd_set_format (abfd, bfd_object);
3465 bfd_set_arch_mach (abfd, BFD_ARCH, machine);
3466
3467 string_byte_count = 4;
3468
3469 /* Run through all the sub-segments and align them up. Also
3470 close any open frags. We tack a .fill onto the end of the
3471 frag chain so that any .align's size can be worked by looking
3472 at the next frag. */
3473 for (frchain_ptr = frchain_root;
3474 frchain_ptr != (struct frchain *) NULL;
3475 frchain_ptr = frchain_ptr->frch_next)
3476 {
3477 int alignment;
3478
3479 subseg_set (frchain_ptr->frch_seg, frchain_ptr->frch_subseg);
3480
3481 alignment = SUB_SEGMENT_ALIGN (now_seg, frchain_ptr);
3482
3483#ifdef md_do_align
3484 md_do_align (alignment, (char *) NULL, 0, 0, alignment_done);
3485#endif
3486 if (subseg_text_p (now_seg))
3487 frag_align_code (alignment, 0);
3488 else
3489 frag_align (alignment, 0, 0);
3490
3491#ifdef md_do_align
3492 alignment_done:
3493#endif
3494
3495 frag_wane (frag_now);
3496 frag_now->fr_fix = 0;
3497 know (frag_now->fr_next == NULL);
3498 }
3499
3500 remove_subsegs ();
3501
3502 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
3503 relax_segment (segment_info[i].frchainP->frch_root, i);
3504
3505 /* Relaxation has completed. Freeze all syms. */
3506 finalize_syms = 1;
3507
3508 H_SET_NUMBER_OF_SECTIONS (&headers, 0);
3509
3510 /* Find out how big the sections are, and set the addresses. */
3511 addr = 0;
3512 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
3513 {
3514 long size;
3515
3516 segment_info[i].scnhdr.s_paddr = addr;
3517 segment_info[i].scnhdr.s_vaddr = addr;
3518
3519 if (segment_info[i].scnhdr.s_name[0])
3520 {
3521 H_SET_NUMBER_OF_SECTIONS (&headers,
3522 H_GET_NUMBER_OF_SECTIONS (&headers) + 1);
3523
3524#ifdef COFF_LONG_SECTION_NAMES
3525 /* Support long section names as found in PE. This code
3526 must coordinate with that in coff_header_append and
3527 w_strings. */
3528 {
3529 unsigned int len;
3530
3531 len = strlen (segment_info[i].name);
3532 if (len > SCNNMLEN)
3533 string_byte_count += len + 1;
3534 }
3535#endif /* COFF_LONG_SECTION_NAMES */
3536 }
3537
3538 size = size_section (abfd, (unsigned int) i);
3539 addr += size;
3540
3541 /* I think the section alignment is only used on the i960; the
3542 i960 needs it, and it should do no harm on other targets. */
3543#ifdef ALIGNMENT_IN_S_FLAGS
3544 segment_info[i].scnhdr.s_flags |= (section_alignment[i] & 0xF) << 8;
3545#else
3546 segment_info[i].scnhdr.s_align = 1 << section_alignment[i];
3547#endif
3548
3549 if (i == SEG_E0)
3550 H_SET_TEXT_SIZE (&headers, size);
3551 else if (i == SEG_E1)
3552 H_SET_DATA_SIZE (&headers, size);
3553 else if (i == SEG_E2)
3554 H_SET_BSS_SIZE (&headers, size);
3555 }
3556
3557 /* Turn the gas native symbol table shape into a coff symbol table. */
3558 crawl_symbols (&headers, abfd);
3559
3560 if (string_byte_count == 4)
3561 string_byte_count = 0;
3562
3563 H_SET_STRING_SIZE (&headers, string_byte_count);
3564
3565#ifdef tc_frob_file
3566 tc_frob_file ();
3567#endif
3568
3569 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
3570 {
3571 fixup_mdeps (segment_info[i].frchainP->frch_root, &headers, i);
3572 fixup_segment (&segment_info[i], i);
3573 }
3574
3575 /* Look for ".stab" segments and fill in their initial symbols
3576 correctly. */
3577 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
3578 {
3579 name = segment_info[i].name;
3580
3581 if (name != NULL
3582 && strncmp (".stab", name, 5) == 0
3583 && strncmp (".stabstr", name, 8) != 0)
3584 adjust_stab_section (abfd, i);
3585 }
3586
3587 file_cursor = H_GET_TEXT_FILE_OFFSET (&headers);
3588
3589 bfd_seek (abfd, (file_ptr) file_cursor, 0);
3590
3591 /* Plant the data. */
3592 fill_section (abfd, &headers, &file_cursor);
3593
3594 do_relocs_for (abfd, &headers, &file_cursor);
3595
3596 do_linenos_for (abfd, &headers, &file_cursor);
3597
3598 H_SET_FILE_MAGIC_NUMBER (&headers, COFF_MAGIC);
3599#ifndef OBJ_COFF_OMIT_TIMESTAMP
3600 H_SET_TIME_STAMP (&headers, (long)time((time_t *)0));
3601#else
3602 H_SET_TIME_STAMP (&headers, 0);
3603#endif
3604#ifdef TC_COFF_SET_MACHINE
3605 TC_COFF_SET_MACHINE (&headers);
3606#endif
3607
3608#ifndef COFF_FLAGS
3609#define COFF_FLAGS 0
3610#endif
3611
3612#ifdef KEEP_RELOC_INFO
3613 H_SET_FLAGS (&headers, ((H_GET_LINENO_SIZE(&headers) ? 0 : F_LNNO) |
3614 COFF_FLAGS | coff_flags));
3615#else
3616 H_SET_FLAGS (&headers, ((H_GET_LINENO_SIZE(&headers) ? 0 : F_LNNO) |
3617 (H_GET_RELOCATION_SIZE(&headers) ? 0 : F_RELFLG) |
3618 COFF_FLAGS | coff_flags));
3619#endif
3620
3621 {
3622 unsigned int symtable_size = H_GET_SYMBOL_TABLE_SIZE (&headers);
3623 char *buffer1 = xmalloc (symtable_size + string_byte_count + 1);
3624
3625 H_SET_SYMBOL_TABLE_POINTER (&headers, bfd_tell (abfd));
3626 w_symbols (abfd, buffer1, symbol_rootP);
3627 if (string_byte_count > 0)
3628 w_strings (buffer1 + symtable_size);
3629 bfd_bwrite (buffer1, (bfd_size_type) symtable_size + string_byte_count,
3630 abfd);
3631 free (buffer1);
3632 }
3633
3634 coff_header_append (abfd, &headers);
3635#if 0
3636 /* Recent changes to write need this, but where it should
3637 go is up to Ken.. */
3638 if (!bfd_close_all_done (abfd))
3639 as_fatal (_("Can't close %s: %s"), out_file_name,
3640 bfd_errmsg (bfd_get_error ()));
3641#else
3642 {
3643 extern bfd *stdoutput;
3644 stdoutput = abfd;
3645 }
3646#endif
3647
3648}
3649
3650/* Add a new segment. This is called from subseg_new via the
3651 obj_new_segment macro. */
3652
3653segT
3654obj_coff_add_segment (name)
3655 const char *name;
3656{
3657 unsigned int i;
3658
3659#ifndef COFF_LONG_SECTION_NAMES
3660 char buf[SCNNMLEN + 1];
3661
3662 strncpy (buf, name, SCNNMLEN);
3663 buf[SCNNMLEN] = '\0';
3664 name = buf;
3665#endif
3666
3667 for (i = SEG_E0; i < SEG_LAST && segment_info[i].scnhdr.s_name[0]; i++)
3668 if (strcmp (name, segment_info[i].name) == 0)
3669 return (segT) i;
3670
3671 if (i == SEG_LAST)
3672 {
3673 as_bad (_("Too many new sections; can't add \"%s\""), name);
3674 return now_seg;
3675 }
3676
3677 /* Add a new section. */
3678 strncpy (segment_info[i].scnhdr.s_name, name,
3679 sizeof (segment_info[i].scnhdr.s_name));
3680 segment_info[i].scnhdr.s_flags = STYP_REG;
3681 segment_info[i].name = xstrdup (name);
3682
3683 return (segT) i;
3684}
3685
3686/* Implement the .section pseudo op:
3687 .section name {, "flags"}
3688 ^ ^
3689 | +--- optional flags: 'b' for bss
3690 | 'i' for info
3691 +-- section name 'l' for lib
3692 'n' for noload
3693 'o' for over
3694 'w' for data
3695 'd' (apparently m88k for data)
3696 'x' for text
3697 'r' for read-only data
3698 But if the argument is not a quoted string, treat it as a
3699 subsegment number. */
3700
3701void
3702obj_coff_section (ignore)
3703 int ignore ATTRIBUTE_UNUSED;
3704{
3705 /* Strip out the section name. */
3706 char *section_name, *name;
3707 char c;
3708 unsigned int exp;
3709 long flags;
3710
3711 if (flag_mri)
3712 {
3713 char type;
3714
3715 s_mri_sect (&type);
3716 flags = 0;
3717 if (type == 'C')
3718 flags = STYP_TEXT;
3719 else if (type == 'D')
3720 flags = STYP_DATA;
3721 segment_info[now_seg].scnhdr.s_flags |= flags;
3722
3723 return;
3724 }
3725
3726 section_name = input_line_pointer;
3727 c = get_symbol_end ();
3728
3729 name = xmalloc (input_line_pointer - section_name + 1);
3730 strcpy (name, section_name);
3731
3732 *input_line_pointer = c;
3733
3734 exp = 0;
3735 flags = 0;
3736
3737 SKIP_WHITESPACE ();
3738 if (*input_line_pointer == ',')
3739 {
3740 ++input_line_pointer;
3741 SKIP_WHITESPACE ();
3742
3743 if (*input_line_pointer != '"')
3744 exp = get_absolute_expression ();
3745 else
3746 {
3747 ++input_line_pointer;
3748 while (*input_line_pointer != '"'
3749 && ! is_end_of_line[(unsigned char) *input_line_pointer])
3750 {
3751 switch (*input_line_pointer)
3752 {
3753 case 'b': flags |= STYP_BSS; break;
3754 case 'i': flags |= STYP_INFO; break;
3755 case 'l': flags |= STYP_LIB; break;
3756 case 'n': flags |= STYP_NOLOAD; break;
3757 case 'o': flags |= STYP_OVER; break;
3758 case 'd':
3759 case 'w': flags |= STYP_DATA; break;
3760 case 'x': flags |= STYP_TEXT; break;
3761 case 'r': flags |= STYP_LIT; break;
3762 default:
3763 as_warn(_("unknown section attribute '%c'"),
3764 *input_line_pointer);
3765 break;
3766 }
3767 ++input_line_pointer;
3768 }
3769 if (*input_line_pointer == '"')
3770 ++input_line_pointer;
3771 }
3772 }
3773
3774 subseg_new (name, (subsegT) exp);
3775
3776 segment_info[now_seg].scnhdr.s_flags |= flags;
3777
3778 demand_empty_rest_of_line ();
3779}
3780
3781static void
3782obj_coff_text (ignore)
3783 int ignore ATTRIBUTE_UNUSED;
3784{
3785 subseg_new (".text", get_absolute_expression ());
3786}
3787
3788static void
3789obj_coff_data (ignore)
3790 int ignore ATTRIBUTE_UNUSED;
3791{
3792 if (flag_readonly_data_in_text)
3793 subseg_new (".text", get_absolute_expression () + 1000);
3794 else
3795 subseg_new (".data", get_absolute_expression ());
3796}
3797
3798static void
3799obj_coff_ident (ignore)
3800 int ignore ATTRIBUTE_UNUSED;
3801{
3802 segT current_seg = now_seg; /* Save current seg. */
3803 subsegT current_subseg = now_subseg;
3804
3805 subseg_new (".comment", 0); /* .comment seg. */
3806 stringer (1); /* Read string. */
3807 subseg_set (current_seg, current_subseg); /* Restore current seg. */
3808}
3809
3810void
3811c_symbol_merge (debug, normal)
3812 symbolS *debug;
3813 symbolS *normal;
3814{
3815 S_SET_DATA_TYPE (normal, S_GET_DATA_TYPE (debug));
3816 S_SET_STORAGE_CLASS (normal, S_GET_STORAGE_CLASS (debug));
3817
3818 if (S_GET_NUMBER_AUXILIARY (debug) > S_GET_NUMBER_AUXILIARY (normal))
3819 S_SET_NUMBER_AUXILIARY (normal, S_GET_NUMBER_AUXILIARY (debug));
3820
3821 if (S_GET_NUMBER_AUXILIARY (debug) > 0)
3822 memcpy ((char *) &normal->sy_symbol.ost_auxent[0],
3823 (char *) &debug->sy_symbol.ost_auxent[0],
3824 (unsigned int) (S_GET_NUMBER_AUXILIARY (debug) * AUXESZ));
3825
3826 /* Move the debug flags. */
3827 SF_SET_DEBUG_FIELD (normal, SF_GET_DEBUG_FIELD (debug));
3828}
3829
3830static int
3831c_line_new (symbol, paddr, line_number, frag)
3832 symbolS * symbol;
3833 long paddr;
3834 int line_number;
3835 fragS * frag;
3836{
3837 struct lineno_list *new_line =
3838 (struct lineno_list *) xmalloc (sizeof (struct lineno_list));
3839
3840 segment_info_type *s = segment_info + now_seg;
3841 new_line->line.l_lnno = line_number;
3842
3843 if (line_number == 0)
3844 {
3845 last_line_symbol = symbol;
3846 new_line->line.l_addr.l_symndx = (long) symbol;
3847 }
3848 else
3849 {
3850 new_line->line.l_addr.l_paddr = paddr;
3851 }
3852
3853 new_line->frag = (char *) frag;
3854 new_line->next = (struct lineno_list *) NULL;
3855
3856 if (s->lineno_list_head == (struct lineno_list *) NULL)
3857 s->lineno_list_head = new_line;
3858 else
3859 s->lineno_list_tail->next = new_line;
3860
3861 s->lineno_list_tail = new_line;
3862 return LINESZ * s->scnhdr.s_nlnno++;
3863}
3864
3865void
3866c_dot_file_symbol (filename)
3867 char *filename;
3868{
3869 symbolS *symbolP;
3870
3871 symbolP = symbol_new (".file",
3872 SEG_DEBUG,
3873 0,
3874 &zero_address_frag);
3875
3876 S_SET_STORAGE_CLASS (symbolP, C_FILE);
3877 S_SET_NUMBER_AUXILIARY (symbolP, 1);
3878
3879 if (strlen (filename) > FILNMLEN)
3880 {
3881 /* Filename is too long to fit into an auxent,
3882 we stick it into the string table instead. We keep
3883 a linked list of the filenames we find so we can emit
3884 them later. */
3885 struct filename_list *f = ((struct filename_list *)
3886 xmalloc (sizeof (struct filename_list)));
3887
3888 f->filename = filename;
3889 f->next = 0;
3890
3891 SA_SET_FILE_FNAME_ZEROS (symbolP, 0);
3892 SA_SET_FILE_FNAME_OFFSET (symbolP, 1);
3893
3894 if (filename_list_tail)
3895 filename_list_tail->next = f;
3896 else
3897 filename_list_head = f;
3898 filename_list_tail = f;
3899 }
3900 else
3901 {
3902 SA_SET_FILE_FNAME (symbolP, filename);
3903 }
3904#ifndef NO_LISTING
3905 {
3906 extern int listing;
3907 if (listing)
3908 listing_source_file (filename);
3909 }
3910#endif
3911 SF_SET_DEBUG (symbolP);
3912 S_SET_VALUE (symbolP, (valueT) previous_file_symbol);
3913
3914 previous_file_symbol = symbolP;
3915
3916 /* Make sure that the symbol is first on the symbol chain. */
3917 if (symbol_rootP != symbolP)
3918 {
3919 symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
3920 symbol_insert (symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP);
3921 }
3922}
3923
3924/* Build a 'section static' symbol. */
3925
3926symbolS *
3927c_section_symbol (name, idx)
3928 char *name;
3929 int idx;
3930{
3931 symbolS *symbolP;
3932
3933 symbolP = symbol_find_base (name, DO_NOT_STRIP);
3934 if (symbolP == NULL)
3935 symbolP = symbol_new (name, idx, 0, &zero_address_frag);
3936 else
3937 {
3938 /* Mmmm. I just love violating interfaces. Makes me feel...dirty. */
3939 S_SET_SEGMENT (symbolP, idx);
3940 symbolP->sy_frag = &zero_address_frag;
3941 }
3942
3943 S_SET_STORAGE_CLASS (symbolP, C_STAT);
3944 S_SET_NUMBER_AUXILIARY (symbolP, 1);
3945
3946 SF_SET_STATICS (symbolP);
3947
3948#ifdef TE_DELTA
3949 /* manfred@s-direktnet.de: section symbols *must* have the LOCAL bit cleared,
3950 which is set by the new definition of LOCAL_LABEL in tc-m68k.h. */
3951 SF_CLEAR_LOCAL (symbolP);
3952#endif
3953#ifdef TE_PE
3954 /* If the .linkonce pseudo-op was used for this section, we must
3955 store the information in the auxiliary entry for the section
3956 symbol. */
3957 if (segment_info[idx].linkonce != LINKONCE_UNSET)
3958 {
3959 int type;
3960
3961 switch (segment_info[idx].linkonce)
3962 {
3963 default:
3964 abort ();
3965 case LINKONCE_DISCARD:
3966 type = IMAGE_COMDAT_SELECT_ANY;
3967 break;
3968 case LINKONCE_ONE_ONLY:
3969 type = IMAGE_COMDAT_SELECT_NODUPLICATES;
3970 break;
3971 case LINKONCE_SAME_SIZE:
3972 type = IMAGE_COMDAT_SELECT_SAME_SIZE;
3973 break;
3974 case LINKONCE_SAME_CONTENTS:
3975 type = IMAGE_COMDAT_SELECT_EXACT_MATCH;
3976 break;
3977 }
3978
3979 SYM_AUXENT (symbolP)->x_scn.x_comdat = type;
3980 }
3981#endif /* TE_PE */
3982
3983 return symbolP;
3984}
3985
3986static void
3987w_symbols (abfd, where, symbol_rootP)
3988 bfd * abfd;
3989 char *where;
3990 symbolS * symbol_rootP;
3991{
3992 symbolS *symbolP;
3993 unsigned int i;
3994
3995 /* First fill in those values we have only just worked out. */
3996 for (i = SEG_E0; i < SEG_LAST; i++)
3997 {
3998 symbolP = segment_info[i].dot;
3999 if (symbolP)
4000 {
4001 SA_SET_SCN_SCNLEN (symbolP, segment_info[i].scnhdr.s_size);
4002 SA_SET_SCN_NRELOC (symbolP, segment_info[i].scnhdr.s_nreloc);
4003 SA_SET_SCN_NLINNO (symbolP, segment_info[i].scnhdr.s_nlnno);
4004 }
4005 }
4006
4007 /* Emit all symbols left in the symbol chain. */
4008 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
4009 {
4010 /* Used to save the offset of the name. It is used to point
4011 to the string in memory but must be a file offset. */
4012 char *temp;
4013
4014 /* We can't fix the lnnoptr field in yank_symbols with the other
4015 adjustments, because we have to wait until we know where they
4016 go in the file. */
4017 if (SF_GET_ADJ_LNNOPTR (symbolP))
4018 SA_GET_SYM_LNNOPTR (symbolP) +=
4019 segment_info[S_GET_SEGMENT (symbolP)].scnhdr.s_lnnoptr;
4020
4021 tc_coff_symbol_emit_hook (symbolP);
4022
4023 temp = S_GET_NAME (symbolP);
4024 if (SF_GET_STRING (symbolP))
4025 {
4026 S_SET_OFFSET (symbolP, symbolP->sy_name_offset);
4027 S_SET_ZEROES (symbolP, 0);
4028 }
4029 else
4030 {
4031 memset (symbolP->sy_symbol.ost_entry.n_name, 0, SYMNMLEN);
4032 strncpy (symbolP->sy_symbol.ost_entry.n_name, temp, SYMNMLEN);
4033 }
4034 where = symbol_to_chars (abfd, where, symbolP);
4035 S_SET_NAME (symbolP, temp);
4036 }
4037}
4038
4039static void
4040obj_coff_lcomm (ignore)
4041 int ignore ATTRIBUTE_UNUSED;
4042{
4043 s_lcomm(0);
4044 return;
4045#if 0
4046 char *name;
4047 char c;
4048 int temp;
4049 char *p;
4050
4051 symbolS *symbolP;
4052
4053 name = input_line_pointer;
4054
4055 c = get_symbol_end ();
4056 p = input_line_pointer;
4057 *p = c;
4058 SKIP_WHITESPACE ();
4059 if (*input_line_pointer != ',')
4060 {
4061 as_bad (_("Expected comma after name"));
4062 ignore_rest_of_line ();
4063 return;
4064 }
4065 if (*input_line_pointer == '\n')
4066 {
4067 as_bad (_("Missing size expression"));
4068 return;
4069 }
4070 input_line_pointer++;
4071 if ((temp = get_absolute_expression ()) < 0)
4072 {
4073 as_warn (_("lcomm length (%d.) <0! Ignored."), temp);
4074 ignore_rest_of_line ();
4075 return;
4076 }
4077 *p = 0;
4078
4079 symbolP = symbol_find_or_make (name);
4080
4081 if (S_GET_SEGMENT (symbolP) == SEG_UNKNOWN &&
4082 S_GET_VALUE (symbolP) == 0)
4083 {
4084 if (! need_pass_2)
4085 {
4086 char *p;
4087 segT current_seg = now_seg; /* Save current seg. */
4088 subsegT current_subseg = now_subseg;
4089
4090 subseg_set (SEG_E2, 1);
4091 symbolP->sy_frag = frag_now;
4092 p = frag_var(rs_org, 1, 1, (relax_substateT)0, symbolP,
4093 (offsetT) temp, (char *) 0);
4094 *p = 0;
4095 subseg_set (current_seg, current_subseg); /* Restore current seg. */
4096 S_SET_SEGMENT (symbolP, SEG_E2);
4097 S_SET_STORAGE_CLASS (symbolP, C_STAT);
4098 }
4099 }
4100 else
4101 as_bad (_("Symbol %s already defined"), name);
4102
4103 demand_empty_rest_of_line ();
4104#endif
4105}
4106
4107static void
4108fixup_mdeps (frags, h, this_segment)
4109 fragS *frags;
4110 object_headers *h ATTRIBUTE_UNUSED;
4111 segT this_segment;
4112{
4113 subseg_change (this_segment, 0);
4114
4115 while (frags)
4116 {
4117 switch (frags->fr_type)
4118 {
4119 case rs_align:
4120 case rs_align_code:
4121 case rs_align_test:
4122 case rs_org:
4123#ifdef HANDLE_ALIGN
4124 HANDLE_ALIGN (frags);
4125#endif
4126 frags->fr_type = rs_fill;
4127 frags->fr_offset =
4128 ((frags->fr_next->fr_address - frags->fr_address - frags->fr_fix)
4129 / frags->fr_var);
4130 break;
4131 case rs_machine_dependent:
4132 md_convert_frag (h, this_segment, frags);
4133 frag_wane (frags);
4134 break;
4135 default:
4136 ;
4137 }
4138 frags = frags->fr_next;
4139 }
4140}
4141
4142#if 1
4143
4144#ifndef TC_FORCE_RELOCATION
4145#define TC_FORCE_RELOCATION(fix) 0
4146#endif
4147
4148static void
4149fixup_segment (segP, this_segment_type)
4150 segment_info_type * segP;
4151 segT this_segment_type;
4152{
4153 fixS * fixP;
4154 symbolS *add_symbolP;
4155 symbolS *sub_symbolP;
4156 long add_number;
4157 int size;
4158 char *place;
4159 long where;
4160 char pcrel;
4161 fragS *fragP;
4162 segT add_symbol_segment = absolute_section;
4163
4164 for (fixP = segP->fix_root; fixP; fixP = fixP->fx_next)
4165 {
4166 fragP = fixP->fx_frag;
4167 know (fragP);
4168 where = fixP->fx_where;
4169 place = fragP->fr_literal + where;
4170 size = fixP->fx_size;
4171 add_symbolP = fixP->fx_addsy;
4172 sub_symbolP = fixP->fx_subsy;
4173 add_number = fixP->fx_offset;
4174 pcrel = fixP->fx_pcrel;
4175
4176 /* We want function-relative stabs to work on systems which
4177 may use a relaxing linker; thus we must handle the sym1-sym2
4178 fixups function-relative stabs generates.
4179
4180 Of course, if you actually enable relaxing in the linker, the
4181 line and block scoping information is going to be incorrect
4182 in some cases. The only way to really fix this is to support
4183 a reloc involving the difference of two symbols. */
4184 if (linkrelax
4185 && (!sub_symbolP || pcrel))
4186 continue;
4187
4188#ifdef TC_I960
4189 if (fixP->fx_tcbit && SF_GET_CALLNAME (add_symbolP))
4190 {
4191 /* Relocation should be done via the associated 'bal' entry
4192 point symbol. */
4193
4194 if (!SF_GET_BALNAME (tc_get_bal_of_call (add_symbolP)))
4195 {
4196 as_bad_where (fixP->fx_file, fixP->fx_line,
4197 _("No 'bal' entry point for leafproc %s"),
4198 S_GET_NAME (add_symbolP));
4199 continue;
4200 }
4201 fixP->fx_addsy = add_symbolP = tc_get_bal_of_call (add_symbolP);
4202 }
4203#endif
4204
4205 /* Make sure the symbols have been resolved; this may not have
4206 happened if these are expression symbols. */
4207 if (add_symbolP != NULL && ! add_symbolP->sy_resolved)
4208 resolve_symbol_value (add_symbolP);
4209
4210 if (add_symbolP != NULL)
4211 {
4212 /* If this fixup is against a symbol which has been equated
4213 to another symbol, convert it to the other symbol. */
4214 if (add_symbolP->sy_value.X_op == O_symbol
4215 && (! S_IS_DEFINED (add_symbolP)
4216 || S_IS_COMMON (add_symbolP)))
4217 {
4218 while (add_symbolP->sy_value.X_op == O_symbol
4219 && (! S_IS_DEFINED (add_symbolP)
4220 || S_IS_COMMON (add_symbolP)))
4221 {
4222 symbolS *n;
4223
4224 /* We must avoid looping, as that can occur with a
4225 badly written program. */
4226 n = add_symbolP->sy_value.X_add_symbol;
4227 if (n == add_symbolP)
4228 break;
4229 add_number += add_symbolP->sy_value.X_add_number;
4230 add_symbolP = n;
4231 }
4232 fixP->fx_addsy = add_symbolP;
4233 fixP->fx_offset = add_number;
4234 }
4235 }
4236
4237 if (sub_symbolP != NULL && ! sub_symbolP->sy_resolved)
4238 resolve_symbol_value (sub_symbolP);
4239
4240 if (add_symbolP != NULL
4241 && add_symbolP->sy_mri_common)
4242 {
4243 know (add_symbolP->sy_value.X_op == O_symbol);
4244 add_number += S_GET_VALUE (add_symbolP);
4245 fixP->fx_offset = add_number;
4246 add_symbolP = fixP->fx_addsy = add_symbolP->sy_value.X_add_symbol;
4247 }
4248
4249 if (add_symbolP)
4250 add_symbol_segment = S_GET_SEGMENT (add_symbolP);
4251
4252 if (sub_symbolP)
4253 {
4254 if (add_symbolP == NULL || add_symbol_segment == absolute_section)
4255 {
4256 if (add_symbolP != NULL)
4257 {
4258 add_number += S_GET_VALUE (add_symbolP);
4259 add_symbolP = NULL;
4260 fixP->fx_addsy = NULL;
4261 }
4262
4263 /* It's just -sym. */
4264 if (S_GET_SEGMENT (sub_symbolP) == absolute_section)
4265 {
4266 add_number -= S_GET_VALUE (sub_symbolP);
4267 fixP->fx_subsy = 0;
4268 fixP->fx_done = 1;
4269 }
4270 else
4271 {
4272#ifndef TC_M68K
4273 as_bad_where (fixP->fx_file, fixP->fx_line,
4274 _("Negative of non-absolute symbol %s"),
4275 S_GET_NAME (sub_symbolP));
4276#endif
4277 add_number -= S_GET_VALUE (sub_symbolP);
4278 } /* not absolute */
4279
4280 /* if sub_symbol is in the same segment that add_symbol
4281 and add_symbol is either in DATA, TEXT, BSS or ABSOLUTE. */
4282 }
4283 else if (S_GET_SEGMENT (sub_symbolP) == add_symbol_segment
4284 && SEG_NORMAL (add_symbol_segment))
4285 {
4286 /* Difference of 2 symbols from same segment. Can't
4287 make difference of 2 undefineds: 'value' means
4288 something different for N_UNDF. */
4289#ifdef TC_I960
4290 /* Makes no sense to use the difference of 2 arbitrary symbols
4291 as the target of a call instruction. */
4292 if (fixP->fx_tcbit)
4293 as_bad_where (fixP->fx_file, fixP->fx_line,
4294 _("callj to difference of 2 symbols"));
4295#endif /* TC_I960 */
4296 add_number += S_GET_VALUE (add_symbolP) -
4297 S_GET_VALUE (sub_symbolP);
4298 add_symbolP = NULL;
4299
4300 if (!TC_FORCE_RELOCATION (fixP))
4301 {
4302 fixP->fx_addsy = NULL;
4303 fixP->fx_subsy = NULL;
4304 fixP->fx_done = 1;
4305#ifdef TC_M68K /* is this right? */
4306 pcrel = 0;
4307 fixP->fx_pcrel = 0;
4308#endif
4309 }
4310 }
4311 else
4312 {
4313 /* Different segments in subtraction. */
4314 know (!(S_IS_EXTERNAL (sub_symbolP) && (S_GET_SEGMENT (sub_symbolP) == absolute_section)));
4315
4316 if ((S_GET_SEGMENT (sub_symbolP) == absolute_section))
4317 add_number -= S_GET_VALUE (sub_symbolP);
4318
4319#ifdef DIFF_EXPR_OK
4320 else if (S_GET_SEGMENT (sub_symbolP) == this_segment_type
4321#if 0 /* Okay for 68k, at least... */
4322 && !pcrel
4323#endif
4324 )
4325 {
4326 /* Make it pc-relative. */
4327 add_number += (md_pcrel_from (fixP)
4328 - S_GET_VALUE (sub_symbolP));
4329 pcrel = 1;
4330 fixP->fx_pcrel = 1;
4331 sub_symbolP = 0;
4332 fixP->fx_subsy = 0;
4333 }
4334#endif
4335 else
4336 {
4337 as_bad_where (fixP->fx_file, fixP->fx_line,
4338 _("Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %ld."),
4339 segment_name (S_GET_SEGMENT (sub_symbolP)),
4340 S_GET_NAME (sub_symbolP),
4341 (long) (fragP->fr_address + where));
4342 }
4343 }
4344 }
4345
4346 if (add_symbolP)
4347 {
4348 if (add_symbol_segment == this_segment_type && pcrel)
4349 {
4350 /* This fixup was made when the symbol's segment was
4351 SEG_UNKNOWN, but it is now in the local segment.
4352 So we know how to do the address without relocation. */
4353#ifdef TC_I960
4354 /* reloc_callj() may replace a 'call' with a 'calls' or a 'bal',
4355 in which cases it modifies *fixP as appropriate. In the case
4356 of a 'calls', no further work is required, and *fixP has been
4357 set up to make the rest of the code below a no-op. */
4358 reloc_callj (fixP);
4359#endif /* TC_I960 */
4360
4361 add_number += S_GET_VALUE (add_symbolP);
4362 add_number -= md_pcrel_from (fixP);
4363
4364 /* We used to do
4365 add_number -= segP->scnhdr.s_vaddr;
4366 if defined (TC_I386) || defined (TE_LYNX). I now
4367 think that was an error propagated from the case when
4368 we are going to emit the relocation. If we are not
4369 going to emit the relocation, then we just want to
4370 set add_number to the difference between the symbols.
4371 This is a case that would only arise when there is a
4372 PC relative reference from a section other than .text
4373 to a symbol defined in the same section, and the
4374 reference is not relaxed. Since jump instructions on
4375 the i386 are relaxed, this could only arise with a
4376 call instruction. */
4377
4378 pcrel = 0; /* Lie. Don't want further pcrel processing. */
4379 if (!TC_FORCE_RELOCATION (fixP))
4380 {
4381 fixP->fx_addsy = NULL;
4382 fixP->fx_done = 1;
4383 }
4384 }
4385 else
4386 {
4387 switch (add_symbol_segment)
4388 {
4389 case absolute_section:
4390#ifdef TC_I960
4391 /* See comment about reloc_callj() above. */
4392 reloc_callj (fixP);
4393#endif /* TC_I960 */
4394 add_number += S_GET_VALUE (add_symbolP);
4395 add_symbolP = NULL;
4396
4397 if (!TC_FORCE_RELOCATION (fixP))
4398 {
4399 fixP->fx_addsy = NULL;
4400 fixP->fx_done = 1;
4401 }
4402 break;
4403 default:
4404
4405#if defined(TC_A29K) || (defined(TE_PE) && defined(TC_I386)) || defined(TC_M88K) || defined(TC_OR32)
4406 /* This really should be handled in the linker, but
4407 backward compatibility forbids. */
4408 add_number += S_GET_VALUE (add_symbolP);
4409#else
4410 add_number += S_GET_VALUE (add_symbolP) +
4411 segment_info[S_GET_SEGMENT (add_symbolP)].scnhdr.s_paddr;
4412#endif
4413 break;
4414
4415 case SEG_UNKNOWN:
4416#ifdef TC_I960
4417 if ((int) fixP->fx_bit_fixP == 13)
4418 {
4419 /* This is a COBR instruction. They have only a
4420 13-bit displacement and are only to be used
4421 for local branches: flag as error, don't generate
4422 relocation. */
4423 as_bad_where (fixP->fx_file, fixP->fx_line,
4424 _("can't use COBR format with external label"));
4425 fixP->fx_addsy = NULL;
4426 fixP->fx_done = 1;
4427 continue;
4428 }
4429#endif /* TC_I960 */
4430#if ((defined (TC_I386) || defined (TE_LYNX) || defined (TE_AUX)) && !defined(TE_PE)) || defined (COFF_COMMON_ADDEND)
4431 /* 386 COFF uses a peculiar format in which the
4432 value of a common symbol is stored in the .text
4433 segment (I've checked this on SVR3.2 and SCO
4434 3.2.2) Ian Taylor <ian@cygnus.com>. */
4435 /* This is also true for 68k COFF on sysv machines
4436 (Checked on Motorola sysv68 R3V6 and R3V7.1, and also on
4437 UNIX System V/M68000, Release 1.0 from ATT/Bell Labs)
4438 Philippe De Muyter <phdm@info.ucl.ac.be>. */
4439 if (S_IS_COMMON (add_symbolP))
4440 add_number += S_GET_VALUE (add_symbolP);
4441#endif
4442 break;
4443
4444 }
4445 }
4446 }
4447
4448 if (pcrel)
4449 {
4450#if !defined(TC_M88K) && !(defined(TE_PE) && defined(TC_I386)) && !defined(TC_A29K) && !defined(TC_OR32)
4451 /* This adjustment is not correct on the m88k, for which the
4452 linker does all the computation. */
4453 add_number -= md_pcrel_from (fixP);
4454#endif
4455 if (add_symbolP == 0)
4456 fixP->fx_addsy = &abs_symbol;
4457#if defined (TC_I386) || defined (TE_LYNX) || defined (TC_I960) || defined (TC_M68K)
4458 /* On the 386 we must adjust by the segment vaddr as well.
4459 Ian Taylor.
4460
4461 I changed the i960 to work this way as well. This is
4462 compatible with the current GNU linker behaviour. I do
4463 not know what other i960 COFF assemblers do. This is not
4464 a common case: normally, only assembler code will contain
4465 a PC relative reloc, and only branches which do not
4466 originate in the .text section will have a non-zero
4467 address.
4468
4469 I changed the m68k to work this way as well. This will
4470 break existing PC relative relocs from sections which do
4471 not start at address 0, but it will make ld -r work.
4472 Ian Taylor, 4 Oct 96. */
4473
4474 add_number -= segP->scnhdr.s_vaddr;
4475#endif
4476 }
4477
4478 md_apply_fix3 (fixP, (valueT *) & add_number, this_segment_type);
4479
4480 if (!fixP->fx_bit_fixP && ! fixP->fx_no_overflow)
4481 {
4482#ifndef TC_M88K
4483 /* The m88k uses the offset field of the reloc to get around
4484 this problem. */
4485 if ((size == 1
4486 && ((add_number & ~0xFF)
4487 || (fixP->fx_signed && (add_number & 0x80)))
4488 && ((add_number & ~0xFF) != (-1 & ~0xFF)
4489 || (add_number & 0x80) == 0))
4490 || (size == 2
4491 && ((add_number & ~0xFFFF)
4492 || (fixP->fx_signed && (add_number & 0x8000)))
4493 && ((add_number & ~0xFFFF) != (-1 & ~0xFFFF)
4494 || (add_number & 0x8000) == 0)))
4495 {
4496 as_bad_where (fixP->fx_file, fixP->fx_line,
4497 _("Value of %ld too large for field of %d bytes at 0x%lx"),
4498 (long) add_number, size,
4499 (unsigned long) (fragP->fr_address + where));
4500 }
4501#endif
4502#ifdef WARN_SIGNED_OVERFLOW_WORD
4503 /* Warn if a .word value is too large when treated as a
4504 signed number. We already know it is not too negative.
4505 This is to catch over-large switches generated by gcc on
4506 the 68k. */
4507 if (!flag_signed_overflow_ok
4508 && size == 2
4509 && add_number > 0x7fff)
4510 as_bad_where (fixP->fx_file, fixP->fx_line,
4511 _("Signed .word overflow; switch may be too large; %ld at 0x%lx"),
4512 (long) add_number,
4513 (unsigned long) (fragP->fr_address + where));
4514#endif
4515 }
4516 }
4517}
4518
4519#endif
4520
4521/* The first entry in a .stab section is special. */
4522
4523void
4524obj_coff_init_stab_section (seg)
4525 segT seg;
4526{
4527 char *file;
4528 char *p;
4529 char *stabstr_name;
4530 unsigned int stroff;
4531
4532 /* Make space for this first symbol. */
4533 p = frag_more (12);
4534 /* Zero it out. */
4535 memset (p, 0, 12);
4536 as_where (&file, (unsigned int *) NULL);
4537 stabstr_name = (char *) alloca (strlen (segment_info[seg].name) + 4);
4538 strcpy (stabstr_name, segment_info[seg].name);
4539 strcat (stabstr_name, "str");
4540 stroff = get_stab_string_offset (file, stabstr_name);
4541 know (stroff == 1);
4542 md_number_to_chars (p, stroff, 4);
4543}
4544
4545/* Fill in the counts in the first entry in a .stab section. */
4546
4547static void
4548adjust_stab_section(abfd, seg)
4549 bfd *abfd;
4550 segT seg;
4551{
4552 segT stabstrseg = SEG_UNKNOWN;
4553 const char *secname, *name2;
4554 char *name;
4555 char *p = NULL;
4556 int i, strsz = 0, nsyms;
4557 fragS *frag = segment_info[seg].frchainP->frch_root;
4558
4559 /* Look for the associated string table section. */
4560
4561 secname = segment_info[seg].name;
4562 name = (char *) alloca (strlen (secname) + 4);
4563 strcpy (name, secname);
4564 strcat (name, "str");
4565
4566 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
4567 {
4568 name2 = segment_info[i].name;
4569 if (name2 != NULL && strncmp(name2, name, 8) == 0)
4570 {
4571 stabstrseg = i;
4572 break;
4573 }
4574 }
4575
4576 /* If we found the section, get its size. */
4577 if (stabstrseg != SEG_UNKNOWN)
4578 strsz = size_section (abfd, stabstrseg);
4579
4580 nsyms = size_section (abfd, seg) / 12 - 1;
4581
4582 /* Look for the first frag of sufficient size for the initial stab
4583 symbol, and collect a pointer to it. */
4584 while (frag && frag->fr_fix < 12)
4585 frag = frag->fr_next;
4586 assert (frag != 0);
4587 p = frag->fr_literal;
4588 assert (p != 0);
4589
4590 /* Write in the number of stab symbols and the size of the string
4591 table. */
4592 bfd_h_put_16 (abfd, (bfd_vma) nsyms, (bfd_byte *) p + 6);
4593 bfd_h_put_32 (abfd, (bfd_vma) strsz, (bfd_byte *) p + 8);
4594}
4595
4596#endif /* not BFD_ASSEMBLER */
4597
4598const pseudo_typeS coff_pseudo_table[] =
4599{
4600 {"def", obj_coff_def, 0},
4601 {"dim", obj_coff_dim, 0},
4602 {"endef", obj_coff_endef, 0},
4603 {"line", obj_coff_line, 0},
4604 {"ln", obj_coff_ln, 0},
4605#ifdef BFD_ASSEMBLER
4606 {"loc", obj_coff_loc, 0},
4607#endif
4608 {"appline", obj_coff_ln, 1},
4609 {"scl", obj_coff_scl, 0},
4610 {"size", obj_coff_size, 0},
4611 {"tag", obj_coff_tag, 0},
4612 {"type", obj_coff_type, 0},
4613 {"val", obj_coff_val, 0},
4614 {"section", obj_coff_section, 0},
4615 {"sect", obj_coff_section, 0},
4616 /* FIXME: We ignore the MRI short attribute. */
4617 {"section.s", obj_coff_section, 0},
4618 {"sect.s", obj_coff_section, 0},
4619 /* We accept the .bss directive for backward compatibility with
4620 earlier versions of gas. */
4621 {"bss", obj_coff_bss, 0},
4622 {"weak", obj_coff_weak, 0},
4623 {"ident", obj_coff_ident, 0},
4624#ifndef BFD_ASSEMBLER
4625 {"use", obj_coff_section, 0},
4626 {"text", obj_coff_text, 0},
4627 {"data", obj_coff_data, 0},
4628 {"lcomm", obj_coff_lcomm, 0},
4629#else
4630 {"optim", s_ignore, 0}, /* For sun386i cc (?) */
4631#endif
4632 {"version", s_ignore, 0},
4633 {"ABORT", s_abort, 0},
4634#if defined( TC_M88K ) || defined ( TC_TIC4X )
4635 /* The m88k and tic4x uses sdef instead of def. */
4636 {"sdef", obj_coff_def, 0},
4637#endif
4638 {NULL, NULL, 0} /* end sentinel */
4639}; /* coff_pseudo_table */
4640
4641
4642#ifdef BFD_ASSEMBLER
4643
4644/* Support for a COFF emulation. */
4645
4646static void coff_pop_insert PARAMS ((void));
4647static int coff_separate_stab_sections PARAMS ((void));
4648
4649static void
4650coff_pop_insert ()
4651{
4652 pop_insert (coff_pseudo_table);
4653}
4654
4655static int
4656coff_separate_stab_sections ()
4657{
4658 return 1;
4659}
4660
4661const struct format_ops coff_format_ops =
4662{
4663 bfd_target_coff_flavour,
4664 0, /* dfl_leading_underscore */
4665 1, /* emit_section_symbols */
4666 0, /* begin */
4667 c_dot_file_symbol,
4668 coff_frob_symbol,
4669 0, /* frob_file */
4670 0, /* frob_file_before_adjust */
4671 0, /* frob_file_before_fix */
4672 coff_frob_file_after_relocs,
4673 0, /* s_get_size */
4674 0, /* s_set_size */
4675 0, /* s_get_align */
4676 0, /* s_set_align */
4677 0, /* s_get_other */
4678 0, /* s_set_other */
4679 0, /* s_get_desc */
4680 0, /* s_set_desc */
4681 0, /* s_get_type */
4682 0, /* s_set_type */
4683 0, /* copy_symbol_attributes */
4684 0, /* generate_asm_lineno */
4685 0, /* process_stab */
4686 coff_separate_stab_sections,
4687 obj_coff_init_stab_section,
4688 0, /* sec_sym_ok_for_reloc */
4689 coff_pop_insert,
4690 0, /* ecoff_set_ext */
4691 coff_obj_read_begin_hook,
4692 coff_obj_symbol_new_hook
4693};
4694
4695#endif
Note: See TracBrowser for help on using the repository browser.