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