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