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