* config/te-aix5.h: Typo fix.
[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 {
571 lineno += coff_line_base - 1;
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
ILT
718 if (name[0] == '.' && name[2] == 'f' && name[3] == '\0')
719 {
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),
845 DO_NOT_STRIP)) == NULL
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)
9690c54d
ILT
850 {
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);
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
1400/*
1401 * implement the .section pseudo op:
1402 * .section name {, "flags"}
1403 * ^ ^
1404 * | +--- optional flags: 'b' for bss
1405 * | 'i' for info
1406 * +-- section name 'l' for lib
1407 * 'n' for noload
1408 * 'o' for over
1409 * 'w' for data
1410 * 'd' (apparently m88k for data)
1411 * 'x' for text
1412 * 'r' for read-only data
2dcc60be 1413 * 's' for shared data (PE)
252b5132
RH
1414 * But if the argument is not a quoted string, treat it as a
1415 * subsegment number.
1416 */
1417
1418void
1419obj_coff_section (ignore)
c4bf532f 1420 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
1421{
1422 /* Strip out the section name */
1423 char *section_name;
1424 char c;
1425 char *name;
1426 unsigned int exp;
c9900432 1427 flagword flags, oldflags;
252b5132
RH
1428 asection *sec;
1429
1430 if (flag_mri)
1431 {
1432 char type;
1433
1434 s_mri_sect (&type);
1435 return;
1436 }
1437
1438 section_name = input_line_pointer;
1439 c = get_symbol_end ();
1440
1441 name = xmalloc (input_line_pointer - section_name + 1);
1442 strcpy (name, section_name);
1443
1444 *input_line_pointer = c;
1445
1446 SKIP_WHITESPACE ();
1447
1448 exp = 0;
c9900432 1449 flags = SEC_NO_FLAGS;
252b5132
RH
1450
1451 if (*input_line_pointer == ',')
1452 {
1453 ++input_line_pointer;
1454 SKIP_WHITESPACE ();
1455 if (*input_line_pointer != '"')
1456 exp = get_absolute_expression ();
1457 else
1458 {
1459 ++input_line_pointer;
1460 while (*input_line_pointer != '"'
1461 && ! is_end_of_line[(unsigned char) *input_line_pointer])
1462 {
1463 switch (*input_line_pointer)
1464 {
1465 case 'b': flags |= SEC_ALLOC; flags &=~ SEC_LOAD; break;
1af96959 1466 case 'n': flags &=~ SEC_LOAD; flags |= SEC_NEVER_LOAD; break;
5881e4aa
ILT
1467 case 'd': flags |= SEC_DATA | SEC_LOAD; /* fall through */
1468 case 'w': flags &=~ SEC_READONLY; break;
1469 case 'x': flags |= SEC_CODE | SEC_LOAD; break;
252b5132 1470 case 'r': flags |= SEC_READONLY; break;
2dcc60be 1471 case 's': flags |= SEC_SHARED; break;
252b5132
RH
1472
1473 case 'i': /* STYP_INFO */
1474 case 'l': /* STYP_LIB */
1475 case 'o': /* STYP_OVER */
1476 as_warn (_("unsupported section attribute '%c'"),
1477 *input_line_pointer);
1478 break;
1479
1480 default:
1481 as_warn(_("unknown section attribute '%c'"),
1482 *input_line_pointer);
1483 break;
1484 }
1485 ++input_line_pointer;
1486 }
1487 if (*input_line_pointer == '"')
1488 ++input_line_pointer;
1489 }
1490 }
1491
1492 sec = subseg_new (name, (subsegT) exp);
1493
c9900432
NC
1494 oldflags = bfd_get_section_flags (stdoutput, sec);
1495 if (oldflags == SEC_NO_FLAGS)
252b5132 1496 {
c9900432
NC
1497 /* Set section flags for a new section just created by subseg_new.
1498 Provide a default if no flags were parsed. */
1499 if (flags == SEC_NO_FLAGS)
1ad5eac0 1500 flags = TC_COFF_SECTION_DEFAULT_ATTRIBUTES;
dcd619be 1501
c9900432
NC
1502#ifdef COFF_LONG_SECTION_NAMES
1503 /* Add SEC_LINK_ONCE and SEC_LINK_DUPLICATES_DISCARD to .gnu.linkonce
1504 sections so adjust_reloc_syms in write.c will correctly handle
1505 relocs which refer to non-local symbols in these sections. */
814f6641 1506 if (strncmp (name, ".gnu.linkonce", sizeof (".gnu.linkonce") - 1) == 0)
c9900432
NC
1507 flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
1508#endif
252b5132
RH
1509
1510 if (! bfd_set_section_flags (stdoutput, sec, flags))
c9900432
NC
1511 as_warn (_("error setting flags for \"%s\": %s"),
1512 bfd_section_name (stdoutput, sec),
1513 bfd_errmsg (bfd_get_error ()));
1514 }
1515 else if (flags != SEC_NO_FLAGS)
1516 {
1517 /* This section's attributes have already been set. Warn if the
1518 attributes don't match. */
5dd0794d
AM
1519 flagword matchflags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
1520 | SEC_DATA | SEC_SHARED | SEC_NEVER_LOAD);
c9900432
NC
1521 if ((flags ^ oldflags) & matchflags)
1522 as_warn (_("Ignoring changed section attributes for %s"), name);
252b5132
RH
1523 }
1524
1525 demand_empty_rest_of_line ();
1526}
1527
1528void
1529coff_adjust_symtab ()
1530{
1531 if (symbol_rootP == NULL
1532 || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
1533 c_dot_file_symbol ("fake");
1534}
1535
1536void
1537coff_frob_section (sec)
1538 segT sec;
1539{
1540 segT strsec;
1541 char *p;
1542 fragS *fragp;
1543 bfd_vma size, n_entries, mask;
bea9907b 1544 bfd_vma align_power = (bfd_vma)sec->alignment_power + OCTETS_PER_BYTE_POWER;
252b5132
RH
1545
1546 /* The COFF back end in BFD requires that all section sizes be
bea9907b
TW
1547 rounded up to multiples of the corresponding section alignments,
1548 supposedly because standard COFF has no other way of encoding alignment
1549 for sections. If your COFF flavor has a different way of encoding
dcd619be 1550 section alignment, then skip this step, as TICOFF does. */
252b5132 1551 size = bfd_get_section_size_before_reloc (sec);
bea9907b
TW
1552 mask = ((bfd_vma) 1 << align_power) - 1;
1553#if !defined(TICOFF)
252b5132
RH
1554 if (size & mask)
1555 {
7f788821
NC
1556 bfd_vma new_size;
1557 fragS *last;
dcd619be 1558
7f788821
NC
1559 new_size = (size + mask) & ~mask;
1560 bfd_set_section_size (stdoutput, sec, new_size);
1561
1562 /* If the size had to be rounded up, add some padding in
1563 the last non-empty frag. */
1564 fragp = seg_info (sec)->frchainP->frch_root;
1565 last = seg_info (sec)->frchainP->frch_last;
1566 while (fragp->fr_next != last)
1567 fragp = fragp->fr_next;
1568 last->fr_address = size;
1569 fragp->fr_offset += new_size - size;
252b5132 1570 }
bea9907b 1571#endif
252b5132
RH
1572
1573 /* If the section size is non-zero, the section symbol needs an aux
1574 entry associated with it, indicating the size. We don't know
1575 all the values yet; coff_frob_symbol will fill them in later. */
bea9907b 1576#ifndef TICOFF
252b5132
RH
1577 if (size != 0
1578 || sec == text_section
1579 || sec == data_section
1580 || sec == bss_section)
bea9907b 1581#endif
252b5132
RH
1582 {
1583 symbolS *secsym = section_symbol (sec);
1584
1585 S_SET_STORAGE_CLASS (secsym, C_STAT);
1586 S_SET_NUMBER_AUXILIARY (secsym, 1);
1587 SF_SET_STATICS (secsym);
1588 SA_SET_SCN_SCNLEN (secsym, size);
1589 }
1590
1591 /* @@ these should be in a "stabs.h" file, or maybe as.h */
1592#ifndef STAB_SECTION_NAME
1593#define STAB_SECTION_NAME ".stab"
1594#endif
1595#ifndef STAB_STRING_SECTION_NAME
1596#define STAB_STRING_SECTION_NAME ".stabstr"
1597#endif
1598 if (strcmp (STAB_STRING_SECTION_NAME, sec->name))
1599 return;
1600
1601 strsec = sec;
1602 sec = subseg_get (STAB_SECTION_NAME, 0);
1603 /* size is already rounded up, since other section will be listed first */
1604 size = bfd_get_section_size_before_reloc (strsec);
1605
1606 n_entries = bfd_get_section_size_before_reloc (sec) / 12 - 1;
1607
1608 /* Find first non-empty frag. It should be large enough. */
1609 fragp = seg_info (sec)->frchainP->frch_root;
1610 while (fragp && fragp->fr_fix == 0)
1611 fragp = fragp->fr_next;
1612 assert (fragp != 0 && fragp->fr_fix >= 12);
1613
1614 /* Store the values. */
1615 p = fragp->fr_literal;
1616 bfd_h_put_16 (stdoutput, n_entries, (bfd_byte *) p + 6);
1617 bfd_h_put_32 (stdoutput, size, (bfd_byte *) p + 8);
1618}
1619
1620void
1621obj_coff_init_stab_section (seg)
1622 segT seg;
1623{
1624 char *file;
1625 char *p;
1626 char *stabstr_name;
1627 unsigned int stroff;
1628
dcd619be 1629 /* Make space for this first symbol. */
252b5132 1630 p = frag_more (12);
dcd619be 1631 /* Zero it out. */
252b5132
RH
1632 memset (p, 0, 12);
1633 as_where (&file, (unsigned int *) NULL);
23deb923 1634 stabstr_name = (char *) xmalloc (strlen (seg->name) + 4);
252b5132
RH
1635 strcpy (stabstr_name, seg->name);
1636 strcat (stabstr_name, "str");
1637 stroff = get_stab_string_offset (file, stabstr_name);
1638 know (stroff == 1);
1639 md_number_to_chars (p, stroff, 4);
1640}
1641
1642#ifdef DEBUG
1643/* for debugging */
1644const char *
1645s_get_name (s)
1646 symbolS *s;
1647{
1648 return ((s == NULL) ? "(NULL)" : S_GET_NAME (s));
1649}
1650
1651void
1652symbol_dump ()
1653{
1654 symbolS *symbolP;
1655
1656 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
1657 {
814f6641 1658 printf (_("0x%lx: \"%s\" type = %ld, class = %d, segment = %d\n"),
252b5132
RH
1659 (unsigned long) symbolP,
1660 S_GET_NAME(symbolP),
1661 (long) S_GET_DATA_TYPE(symbolP),
1662 S_GET_STORAGE_CLASS(symbolP),
1663 (int) S_GET_SEGMENT(symbolP));
1664 }
1665}
1666
1667#endif /* DEBUG */
1668
1669#else /* not BFD_ASSEMBLER */
1670
1671#include "frags.h"
dcd619be 1672/* This is needed because we include internal bfd things. */
252b5132
RH
1673#include <time.h>
1674
1675#include "libbfd.h"
1676#include "libcoff.h"
1677
1678#ifdef TE_PE
1679#include "coff/pe.h"
1680#endif
1681
1682/* The NOP_OPCODE is for the alignment fill value. Fill with nop so
1683 that we can stick sections together without causing trouble. */
1684#ifndef NOP_OPCODE
1685#define NOP_OPCODE 0x00
1686#endif
1687
1688/* The zeroes if symbol name is longer than 8 chars */
1689#define S_SET_ZEROES(s,v) ((s)->sy_symbol.ost_entry.n_zeroes = (v))
1690
1691#define MIN(a,b) ((a) < (b)? (a) : (b))
a04b544b
ILT
1692
1693/* This vector is used to turn a gas internal segment number into a
1694 section number suitable for insertion into a coff symbol table.
1695 This must correspond to seg_info_off_by_4. */
252b5132
RH
1696
1697const short seg_N_TYPE[] =
1698{ /* in: segT out: N_TYPE bits */
1699 C_ABS_SECTION,
1700 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
1701 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
1702 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
1703 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
1704 C_UNDEF_SECTION, /* SEG_UNKNOWN */
1705 C_UNDEF_SECTION, /* SEG_GOOF */
1706 C_UNDEF_SECTION, /* SEG_EXPR */
1707 C_DEBUG_SECTION, /* SEG_DEBUG */
1708 C_NTV_SECTION, /* SEG_NTV */
1709 C_PTV_SECTION, /* SEG_PTV */
1710 C_REGISTER_SECTION, /* SEG_REGISTER */
1711};
1712
1713int function_lineoff = -1; /* Offset in line#s where the last function
1714 started (the odd entry for line #0) */
1715
1716/* structure used to keep the filenames which
1717 are too long around so that we can stick them
1718 into the string table */
dcd619be 1719struct filename_list
252b5132
RH
1720{
1721 char *filename;
1722 struct filename_list *next;
1723};
1724
1725static struct filename_list *filename_list_head;
1726static struct filename_list *filename_list_tail;
1727
1728static symbolS *last_line_symbol;
1729
1730/* Add 4 to the real value to get the index and compensate the
1731 negatives. This vector is used by S_GET_SEGMENT to turn a coff
1732 section number into a segment number
1733*/
1734static symbolS *previous_file_symbol;
1735void c_symbol_merge ();
1736static int line_base;
1737
1738symbolS *c_section_symbol ();
1739bfd *abfd;
1740
1741static void fixup_segment PARAMS ((segment_info_type *segP,
1742 segT this_segment_type));
1743
252b5132
RH
1744static void fixup_mdeps PARAMS ((fragS *,
1745 object_headers *,
1746 segT));
1747
252b5132
RH
1748static void fill_section PARAMS ((bfd * abfd,
1749 object_headers *,
1750 unsigned long *));
1751
252b5132
RH
1752static int c_line_new PARAMS ((symbolS * symbol, long paddr,
1753 int line_number,
1754 fragS * frag));
1755
252b5132
RH
1756static void w_symbols PARAMS ((bfd * abfd, char *where,
1757 symbolS * symbol_rootP));
1758
1759static void adjust_stab_section PARAMS ((bfd *abfd, segT seg));
1760
1761static void obj_coff_lcomm PARAMS ((int));
1762static void obj_coff_text PARAMS ((int));
1763static void obj_coff_data PARAMS ((int));
252b5132
RH
1764void obj_coff_section PARAMS ((int));
1765
a04b544b 1766/* When not using BFD_ASSEMBLER, we permit up to 40 sections.
252b5132 1767
a04b544b
ILT
1768 This array maps a COFF section number into a gas section number.
1769 Because COFF uses negative section numbers, you must add 4 to the
1770 COFF section number when indexing into this array; this is done via
1771 the SEG_INFO_FROM_SECTION_NUMBER macro. This must correspond to
1772 seg_N_TYPE. */
252b5132 1773
a04b544b 1774static const segT seg_info_off_by_4[] =
252b5132 1775{
a04b544b
ILT
1776 SEG_PTV,
1777 SEG_NTV,
1778 SEG_DEBUG,
1779 SEG_ABSOLUTE,
1780 SEG_UNKNOWN,
1781 SEG_E0, SEG_E1, SEG_E2, SEG_E3, SEG_E4,
1782 SEG_E5, SEG_E6, SEG_E7, SEG_E8, SEG_E9,
1783 SEG_E10, SEG_E11, SEG_E12, SEG_E13, SEG_E14,
1784 SEG_E15, SEG_E16, SEG_E17, SEG_E18, SEG_E19,
1785 SEG_E20, SEG_E21, SEG_E22, SEG_E23, SEG_E24,
1786 SEG_E25, SEG_E26, SEG_E27, SEG_E28, SEG_E29,
1787 SEG_E30, SEG_E31, SEG_E32, SEG_E33, SEG_E34,
1788 SEG_E35, SEG_E36, SEG_E37, SEG_E38, SEG_E39,
1789 (segT) 40,
1790 (segT) 41,
1791 (segT) 42,
1792 (segT) 43,
1793 (segT) 44,
1794 (segT) 45,
1795 (segT) 0,
1796 (segT) 0,
1797 (segT) 0,
1798 SEG_REGISTER
252b5132
RH
1799};
1800
252b5132
RH
1801#define SEG_INFO_FROM_SECTION_NUMBER(x) (seg_info_off_by_4[(x)+4])
1802
1803static relax_addressT
1804relax_align (address, alignment)
1805 relax_addressT address;
1806 long alignment;
1807{
1808 relax_addressT mask;
1809 relax_addressT new_address;
1810
1811 mask = ~((~0) << alignment);
1812 new_address = (address + mask) & (~mask);
1813 return (new_address - address);
1814}
1815
252b5132
RH
1816segT
1817s_get_segment (x)
1818 symbolS * x;
1819{
a04b544b 1820 return SEG_INFO_FROM_SECTION_NUMBER (x->sy_symbol.ost_entry.n_scnum);
252b5132
RH
1821}
1822
1823/* calculate the size of the frag chain and fill in the section header
1824 to contain all of it, also fill in the addr of the sections */
1825static unsigned int
1826size_section (abfd, idx)
a04b544b 1827 bfd *abfd ATTRIBUTE_UNUSED;
252b5132
RH
1828 unsigned int idx;
1829{
1830
1831 unsigned int size = 0;
1832 fragS *frag = segment_info[idx].frchainP->frch_root;
1833 while (frag)
1834 {
1835 size = frag->fr_address;
1836 if (frag->fr_address != size)
1837 {
1838 fprintf (stderr, _("Out of step\n"));
1839 size = frag->fr_address;
1840 }
1841
1842 switch (frag->fr_type)
1843 {
1844#ifdef TC_COFF_SIZEMACHDEP
1845 case rs_machine_dependent:
1846 size += TC_COFF_SIZEMACHDEP (frag);
1847 break;
1848#endif
1849 case rs_space:
252b5132
RH
1850 case rs_fill:
1851 case rs_org:
1852 size += frag->fr_fix;
1853 size += frag->fr_offset * frag->fr_var;
1854 break;
1855 case rs_align:
1856 case rs_align_code:
0a9ef439 1857 case rs_align_test:
252b5132
RH
1858 {
1859 addressT off;
1860
1861 size += frag->fr_fix;
1862 off = relax_align (size, frag->fr_offset);
1863 if (frag->fr_subtype != 0 && off > frag->fr_subtype)
1864 off = 0;
1865 size += off;
1866 }
1867 break;
1868 default:
1869 BAD_CASE (frag->fr_type);
1870 break;
1871 }
1872 frag = frag->fr_next;
1873 }
1874 segment_info[idx].scnhdr.s_size = size;
1875 return size;
1876}
1877
252b5132
RH
1878static unsigned int
1879count_entries_in_chain (idx)
1880 unsigned int idx;
1881{
1882 unsigned int nrelocs;
1883 fixS *fixup_ptr;
1884
1885 /* Count the relocations */
1886 fixup_ptr = segment_info[idx].fix_root;
1887 nrelocs = 0;
1888 while (fixup_ptr != (fixS *) NULL)
1889 {
1890 if (fixup_ptr->fx_done == 0 && TC_COUNT_RELOC (fixup_ptr))
1891 {
3b16e843 1892#if defined(TC_A29K) || defined(TC_OR32)
252b5132
RH
1893 if (fixup_ptr->fx_r_type == RELOC_CONSTH)
1894 nrelocs += 2;
1895 else
1896 nrelocs++;
1897#else
1898 nrelocs++;
1899#endif
1900 }
1901
1902 fixup_ptr = fixup_ptr->fx_next;
1903 }
1904 return nrelocs;
1905}
1906
1907#ifdef TE_AUX
1908
1909static int compare_external_relocs PARAMS ((const PTR, const PTR));
1910
1911/* AUX's ld expects relocations to be sorted */
1912static int
1913compare_external_relocs (x, y)
1914 const PTR x;
1915 const PTR y;
1916{
1917 struct external_reloc *a = (struct external_reloc *) x;
1918 struct external_reloc *b = (struct external_reloc *) y;
1919 bfd_vma aadr = bfd_getb32 (a->r_vaddr);
1920 bfd_vma badr = bfd_getb32 (b->r_vaddr);
1921 return (aadr < badr ? -1 : badr < aadr ? 1 : 0);
1922}
1923
1924#endif
1925
1926/* output all the relocations for a section */
1927void
1928do_relocs_for (abfd, h, file_cursor)
1929 bfd * abfd;
1930 object_headers * h;
1931 unsigned long *file_cursor;
1932{
1933 unsigned int nrelocs;
1934 unsigned int idx;
1935 unsigned long reloc_start = *file_cursor;
1936
1937 for (idx = SEG_E0; idx < SEG_LAST; idx++)
1938 {
1939 if (segment_info[idx].scnhdr.s_name[0])
1940 {
1941 struct external_reloc *ext_ptr;
1942 struct external_reloc *external_reloc_vec;
1943 unsigned int external_reloc_size;
1944 unsigned int base = segment_info[idx].scnhdr.s_paddr;
1945 fixS *fix_ptr = segment_info[idx].fix_root;
1946 nrelocs = count_entries_in_chain (idx);
1947
1948 if (nrelocs)
1949 /* Bypass this stuff if no relocs. This also incidentally
1950 avoids a SCO bug, where free(malloc(0)) tends to crash. */
1951 {
1952 external_reloc_size = nrelocs * RELSZ;
1953 external_reloc_vec =
1954 (struct external_reloc *) malloc (external_reloc_size);
1955
1956 ext_ptr = external_reloc_vec;
1957
1958 /* Fill in the internal coff style reloc struct from the
1959 internal fix list. */
1960 while (fix_ptr)
1961 {
1962 struct internal_reloc intr;
1963
1964 /* Only output some of the relocations */
1965 if (fix_ptr->fx_done == 0 && TC_COUNT_RELOC (fix_ptr))
1966 {
1967#ifdef TC_RELOC_MANGLE
1968 TC_RELOC_MANGLE (&segment_info[idx], fix_ptr, &intr,
1969 base);
1970
1971#else
1972 symbolS *dot;
1973 symbolS *symbol_ptr = fix_ptr->fx_addsy;
1974
1975 intr.r_type = TC_COFF_FIX2RTYPE (fix_ptr);
1976 intr.r_vaddr =
1977 base + fix_ptr->fx_frag->fr_address + fix_ptr->fx_where;
1978
1979#ifdef TC_KEEP_FX_OFFSET
1980 intr.r_offset = fix_ptr->fx_offset;
1981#else
1982 intr.r_offset = 0;
1983#endif
1984
1985 while (symbol_ptr->sy_value.X_op == O_symbol
1986 && (! S_IS_DEFINED (symbol_ptr)
1987 || S_IS_COMMON (symbol_ptr)))
1988 {
1989 symbolS *n;
1990
1991 /* We must avoid looping, as that can occur
1992 with a badly written program. */
1993 n = symbol_ptr->sy_value.X_add_symbol;
1994 if (n == symbol_ptr)
1995 break;
1996 symbol_ptr = n;
1997 }
1998
1999 /* Turn the segment of the symbol into an offset. */
2000 if (symbol_ptr)
2001 {
6386f3a7 2002 resolve_symbol_value (symbol_ptr);
252b5132
RH
2003 if (! symbol_ptr->sy_resolved)
2004 {
2005 char *file;
2006 unsigned int line;
2007
2008 if (expr_symbol_where (symbol_ptr, &file, &line))
2009 as_bad_where (file, line,
2010 _("unresolved relocation"));
2011 else
2012 as_bad (_("bad relocation: symbol `%s' not in symbol table"),
2013 S_GET_NAME (symbol_ptr));
2014 }
2015 dot = segment_info[S_GET_SEGMENT (symbol_ptr)].dot;
2016 if (dot)
2017 {
2018 intr.r_symndx = dot->sy_number;
2019 }
2020 else
2021 {
2022 intr.r_symndx = symbol_ptr->sy_number;
2023 }
2024
2025 }
2026 else
2027 {
2028 intr.r_symndx = -1;
2029 }
2030#endif
2031
2032 (void) bfd_coff_swap_reloc_out (abfd, &intr, ext_ptr);
2033 ext_ptr++;
2034
2035#if defined(TC_A29K)
2036
2037 /* The 29k has a special kludge for the high 16 bit
2038 reloc. Two relocations are emited, R_IHIHALF,
2039 and R_IHCONST. The second one doesn't contain a
2040 symbol, but uses the value for offset. */
2041
2042 if (intr.r_type == R_IHIHALF)
2043 {
2044 /* now emit the second bit */
2045 intr.r_type = R_IHCONST;
2046 intr.r_symndx = fix_ptr->fx_addnumber;
2047 (void) bfd_coff_swap_reloc_out (abfd, &intr, ext_ptr);
2048 ext_ptr++;
2049 }
3b16e843
NC
2050#endif
2051#if defined(TC_OR32)
2052 /* The or32 has a special kludge for the high 16 bit
2053 reloc. Two relocations are emited, R_IHIHALF,
2054 and R_IHCONST. The second one doesn't contain a
2055 symbol, but uses the value for offset. */
2056 if (intr.r_type == R_IHIHALF)
2057 {
2058 /* Now emit the second bit. */
2059 intr.r_type = R_IHCONST;
2060 intr.r_symndx = fix_ptr->fx_addnumber;
2061 (void) bfd_coff_swap_reloc_out (abfd, & intr, ext_ptr);
2062 ext_ptr ++;
2063 }
252b5132
RH
2064#endif
2065 }
2066
2067 fix_ptr = fix_ptr->fx_next;
2068 }
2069
2070#ifdef TE_AUX
2071 /* Sort the reloc table */
2072 qsort ((PTR) external_reloc_vec, nrelocs,
2073 sizeof (struct external_reloc), compare_external_relocs);
2074#endif
2075
2076 /* Write out the reloc table */
0e1a166b
AM
2077 bfd_bwrite ((PTR) external_reloc_vec,
2078 (bfd_size_type) external_reloc_size, abfd);
252b5132
RH
2079 free (external_reloc_vec);
2080
2081 /* Fill in section header info. */
2082 segment_info[idx].scnhdr.s_relptr = *file_cursor;
2083 *file_cursor += external_reloc_size;
2084 segment_info[idx].scnhdr.s_nreloc = nrelocs;
2085 }
2086 else
2087 {
2088 /* No relocs */
2089 segment_info[idx].scnhdr.s_relptr = 0;
2090 }
2091 }
2092 }
2093 /* Set relocation_size field in file headers */
2094 H_SET_RELOCATION_SIZE (h, *file_cursor - reloc_start, 0);
2095}
2096
252b5132
RH
2097/* run through a frag chain and write out the data to go with it, fill
2098 in the scnhdrs with the info on the file postions
2099*/
2100static void
2101fill_section (abfd, h, file_cursor)
2102 bfd * abfd;
a04b544b 2103 object_headers *h ATTRIBUTE_UNUSED;
252b5132
RH
2104 unsigned long *file_cursor;
2105{
2106
2107 unsigned int i;
2108 unsigned int paddr = 0;
2109
2110 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
2111 {
2112 unsigned int offset = 0;
2113 struct internal_scnhdr *s = &(segment_info[i].scnhdr);
2114
2115 PROGRESS (1);
2116
2117 if (s->s_name[0])
2118 {
2119 fragS *frag = segment_info[i].frchainP->frch_root;
ea3b9044 2120 char *buffer = NULL;
252b5132
RH
2121
2122 if (s->s_size == 0)
2123 s->s_scnptr = 0;
2124 else
2125 {
2126 buffer = xmalloc (s->s_size);
2127 s->s_scnptr = *file_cursor;
2128 }
2129 know (s->s_paddr == paddr);
2130
2131 if (strcmp (s->s_name, ".text") == 0)
2132 s->s_flags |= STYP_TEXT;
2133 else if (strcmp (s->s_name, ".data") == 0)
2134 s->s_flags |= STYP_DATA;
2135 else if (strcmp (s->s_name, ".bss") == 0)
2136 {
2137 s->s_scnptr = 0;
2138 s->s_flags |= STYP_BSS;
2139
2140 /* @@ Should make the i386 and a29k coff targets define
2141 COFF_NOLOAD_PROBLEM, and have only one test here. */
2142#ifndef TC_I386
2143#ifndef TC_A29K
3b16e843 2144#ifndef TC_OR32
252b5132
RH
2145#ifndef COFF_NOLOAD_PROBLEM
2146 /* Apparently the SVR3 linker (and exec syscall) and UDI
2147 mondfe progrem are confused by noload sections. */
2148 s->s_flags |= STYP_NOLOAD;
2149#endif
2150#endif
3b16e843 2151#endif
252b5132
RH
2152#endif
2153 }
2154 else if (strcmp (s->s_name, ".lit") == 0)
2155 s->s_flags = STYP_LIT | STYP_TEXT;
2156 else if (strcmp (s->s_name, ".init") == 0)
2157 s->s_flags |= STYP_TEXT;
2158 else if (strcmp (s->s_name, ".fini") == 0)
2159 s->s_flags |= STYP_TEXT;
2160 else if (strncmp (s->s_name, ".comment", 8) == 0)
2161 s->s_flags |= STYP_INFO;
2162
2163 while (frag)
2164 {
2165 unsigned int fill_size;
2166 switch (frag->fr_type)
2167 {
2168 case rs_machine_dependent:
2169 if (frag->fr_fix)
2170 {
2171 memcpy (buffer + frag->fr_address,
2172 frag->fr_literal,
2173 (unsigned int) frag->fr_fix);
2174 offset += frag->fr_fix;
2175 }
2176
2177 break;
2178 case rs_space:
252b5132
RH
2179 case rs_fill:
2180 case rs_align:
2181 case rs_align_code:
0a9ef439 2182 case rs_align_test:
252b5132
RH
2183 case rs_org:
2184 if (frag->fr_fix)
2185 {
2186 memcpy (buffer + frag->fr_address,
2187 frag->fr_literal,
2188 (unsigned int) frag->fr_fix);
2189 offset += frag->fr_fix;
2190 }
2191
2192 fill_size = frag->fr_var;
2193 if (fill_size && frag->fr_offset > 0)
2194 {
2195 unsigned int count;
2196 unsigned int off = frag->fr_fix;
2197 for (count = frag->fr_offset; count; count--)
2198 {
2199 if (fill_size + frag->fr_address + off <= s->s_size)
2200 {
2201 memcpy (buffer + frag->fr_address + off,
2202 frag->fr_literal + frag->fr_fix,
2203 fill_size);
2204 off += fill_size;
2205 offset += fill_size;
2206 }
2207 }
2208 }
2209 break;
2210 case rs_broken_word:
2211 break;
2212 default:
2213 abort ();
2214 }
2215 frag = frag->fr_next;
2216 }
2217
2218 if (s->s_size != 0)
2219 {
2220 if (s->s_scnptr != 0)
2221 {
0e1a166b 2222 bfd_bwrite (buffer, s->s_size, abfd);
252b5132
RH
2223 *file_cursor += s->s_size;
2224 }
2225 free (buffer);
2226 }
2227 paddr += s->s_size;
2228 }
2229 }
2230}
2231
2232/* Coff file generation & utilities */
2233
2234static void
2235coff_header_append (abfd, h)
2236 bfd * abfd;
2237 object_headers * h;
2238{
2239 unsigned int i;
2240 char buffer[1000];
2241 char buffero[1000];
2242#ifdef COFF_LONG_SECTION_NAMES
2243 unsigned long string_size = 4;
2244#endif
2245
0e1a166b 2246 bfd_seek (abfd, (file_ptr) 0, 0);
252b5132
RH
2247
2248#ifndef OBJ_COFF_OMIT_OPTIONAL_HEADER
2249 H_SET_MAGIC_NUMBER (h, COFF_MAGIC);
2250 H_SET_VERSION_STAMP (h, 0);
2251 H_SET_ENTRY_POINT (h, 0);
2252 H_SET_TEXT_START (h, segment_info[SEG_E0].frchainP->frch_root->fr_address);
2253 H_SET_DATA_START (h, segment_info[SEG_E1].frchainP->frch_root->fr_address);
2254 H_SET_SIZEOF_OPTIONAL_HEADER (h, bfd_coff_swap_aouthdr_out(abfd, &h->aouthdr,
2255 buffero));
2256#else /* defined (OBJ_COFF_OMIT_OPTIONAL_HEADER) */
2257 H_SET_SIZEOF_OPTIONAL_HEADER (h, 0);
2258#endif /* defined (OBJ_COFF_OMIT_OPTIONAL_HEADER) */
2259
2260 i = bfd_coff_swap_filehdr_out (abfd, &h->filehdr, buffer);
2261
0e1a166b
AM
2262 bfd_bwrite (buffer, (bfd_size_type) i, abfd);
2263 bfd_bwrite (buffero, (bfd_size_type) H_GET_SIZEOF_OPTIONAL_HEADER (h), abfd);
252b5132
RH
2264
2265 for (i = SEG_E0; i < SEG_LAST; i++)
2266 {
2267 if (segment_info[i].scnhdr.s_name[0])
2268 {
2269 unsigned int size;
2270
2271#ifdef COFF_LONG_SECTION_NAMES
2272 /* Support long section names as found in PE. This code
2273 must coordinate with that in write_object_file and
2274 w_strings. */
2275 if (strlen (segment_info[i].name) > SCNNMLEN)
2276 {
2277 memset (segment_info[i].scnhdr.s_name, 0, SCNNMLEN);
2278 sprintf (segment_info[i].scnhdr.s_name, "/%lu", string_size);
2279 string_size += strlen (segment_info[i].name) + 1;
2280 }
2281#endif
2282
2283 size = bfd_coff_swap_scnhdr_out (abfd,
2284 &(segment_info[i].scnhdr),
2285 buffer);
2286 if (size == 0)
2287 as_bad (_("bfd_coff_swap_scnhdr_out failed"));
0e1a166b 2288 bfd_bwrite (buffer, (bfd_size_type) size, abfd);
252b5132
RH
2289 }
2290 }
2291}
2292
252b5132
RH
2293char *
2294symbol_to_chars (abfd, where, symbolP)
2295 bfd * abfd;
2296 char *where;
2297 symbolS * symbolP;
2298{
2299 unsigned int numaux = symbolP->sy_symbol.ost_entry.n_numaux;
2300 unsigned int i;
2301 valueT val;
2302
2303 /* Turn any symbols with register attributes into abs symbols */
2304 if (S_GET_SEGMENT (symbolP) == reg_section)
2305 {
2306 S_SET_SEGMENT (symbolP, absolute_section);
2307 }
2308 /* At the same time, relocate all symbols to their output value */
2309
2310#ifndef TE_PE
2311 val = (segment_info[S_GET_SEGMENT (symbolP)].scnhdr.s_paddr
2312 + S_GET_VALUE (symbolP));
2313#else
2314 val = S_GET_VALUE (symbolP);
2315#endif
2316
2317 S_SET_VALUE (symbolP, val);
2318
2319 symbolP->sy_symbol.ost_entry.n_value = val;
2320
2321 where += bfd_coff_swap_sym_out (abfd, &symbolP->sy_symbol.ost_entry,
2322 where);
2323
2324 for (i = 0; i < numaux; i++)
2325 {
2326 where += bfd_coff_swap_aux_out (abfd,
2327 &symbolP->sy_symbol.ost_auxent[i],
2328 S_GET_DATA_TYPE (symbolP),
2329 S_GET_STORAGE_CLASS (symbolP),
2330 i, numaux, where);
2331 }
2332 return where;
2333
2334}
2335
2336void
2337coff_obj_symbol_new_hook (symbolP)
2338 symbolS *symbolP;
2339{
2340 char underscore = 0; /* Symbol has leading _ */
2341
2342 /* Effective symbol */
dcd619be 2343 /* Store the pointer in the offset. */
252b5132
RH
2344 S_SET_ZEROES (symbolP, 0L);
2345 S_SET_DATA_TYPE (symbolP, T_NULL);
2346 S_SET_STORAGE_CLASS (symbolP, 0);
2347 S_SET_NUMBER_AUXILIARY (symbolP, 0);
2348 /* Additional information */
2349 symbolP->sy_symbol.ost_flags = 0;
2350 /* Auxiliary entries */
2351 memset ((char *) &symbolP->sy_symbol.ost_auxent[0], 0, AUXESZ);
2352
2353 if (S_IS_STRING (symbolP))
2354 SF_SET_STRING (symbolP);
2355 if (!underscore && S_IS_LOCAL (symbolP))
2356 SF_SET_LOCAL (symbolP);
2357}
2358
2359/*
2360 * Handle .ln directives.
2361 */
2362
2363static void
2364obj_coff_ln (appline)
2365 int appline;
2366{
2367 int l;
2368
2369 if (! appline && def_symbol_in_progress != NULL)
2370 {
2371 as_warn (_(".ln pseudo-op inside .def/.endef: ignored."));
2372 demand_empty_rest_of_line ();
2373 return;
2374 } /* wrong context */
2375
2376 l = get_absolute_expression ();
2377 c_line_new (0, frag_now_fix (), l, frag_now);
2378
2379 if (appline)
2380 new_logical_line ((char *) NULL, l - 1);
2381
2382#ifndef NO_LISTING
2383 {
2384 extern int listing;
2385
2386 if (listing)
2387 {
2388 if (! appline)
2389 l += line_base - 1;
2390 listing_source_line ((unsigned int) l);
2391 }
2392
2393 }
2394#endif
2395 demand_empty_rest_of_line ();
2396}
2397
2398/*
2399 * def()
2400 *
2401 * Handle .def directives.
2402 *
2403 * One might ask : why can't we symbol_new if the symbol does not
2404 * already exist and fill it with debug information. Because of
2405 * the C_EFCN special symbol. It would clobber the value of the
2406 * function symbol before we have a chance to notice that it is
2407 * a C_EFCN. And a second reason is that the code is more clear this
2408 * way. (at least I think it is :-).
2409 *
2410 */
2411
2412#define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';')
2413#define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \
2414 *input_line_pointer == '\t') \
2415 input_line_pointer++;
2416
2417static void
2418obj_coff_def (what)
a04b544b 2419 int what ATTRIBUTE_UNUSED;
252b5132
RH
2420{
2421 char name_end; /* Char after the end of name */
2422 char *symbol_name; /* Name of the debug symbol */
2423 char *symbol_name_copy; /* Temporary copy of the name */
2424 unsigned int symbol_name_length;
2425
2426 if (def_symbol_in_progress != NULL)
2427 {
2428 as_warn (_(".def pseudo-op used inside of .def/.endef: ignored."));
2429 demand_empty_rest_of_line ();
2430 return;
2431 } /* if not inside .def/.endef */
2432
2433 SKIP_WHITESPACES ();
2434
2435 def_symbol_in_progress = (symbolS *) obstack_alloc (&notes, sizeof (*def_symbol_in_progress));
2436 memset (def_symbol_in_progress, 0, sizeof (*def_symbol_in_progress));
2437
2438 symbol_name = input_line_pointer;
2439 name_end = get_symbol_end ();
2440 symbol_name_length = strlen (symbol_name);
2441 symbol_name_copy = xmalloc (symbol_name_length + 1);
2442 strcpy (symbol_name_copy, symbol_name);
2443#ifdef tc_canonicalize_symbol_name
2444 symbol_name_copy = tc_canonicalize_symbol_name (symbol_name_copy);
2445#endif
2446
2447 /* Initialize the new symbol */
2448#ifdef STRIP_UNDERSCORE
2449 S_SET_NAME (def_symbol_in_progress, (*symbol_name_copy == '_'
2450 ? symbol_name_copy + 1
2451 : symbol_name_copy));
2452#else /* STRIP_UNDERSCORE */
2453 S_SET_NAME (def_symbol_in_progress, symbol_name_copy);
2454#endif /* STRIP_UNDERSCORE */
2455 /* free(symbol_name_copy); */
2456 def_symbol_in_progress->sy_name_offset = (unsigned long) ~0;
2457 def_symbol_in_progress->sy_number = ~0;
2458 def_symbol_in_progress->sy_frag = &zero_address_frag;
2459 S_SET_VALUE (def_symbol_in_progress, 0);
2460
2461 if (S_IS_STRING (def_symbol_in_progress))
2462 SF_SET_STRING (def_symbol_in_progress);
2463
2464 *input_line_pointer = name_end;
2465
2466 demand_empty_rest_of_line ();
2467}
2468
2469unsigned int dim_index;
2470
252b5132
RH
2471static void
2472obj_coff_endef (ignore)
a04b544b 2473 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
2474{
2475 symbolS *symbolP = 0;
2476 /* DIM BUG FIX sac@cygnus.com */
2477 dim_index = 0;
2478 if (def_symbol_in_progress == NULL)
2479 {
2480 as_warn (_(".endef pseudo-op used outside of .def/.endef: ignored."));
2481 demand_empty_rest_of_line ();
2482 return;
2483 } /* if not inside .def/.endef */
2484
dcd619be 2485 /* Set the section number according to storage class. */
252b5132
RH
2486 switch (S_GET_STORAGE_CLASS (def_symbol_in_progress))
2487 {
2488 case C_STRTAG:
2489 case C_ENTAG:
2490 case C_UNTAG:
2491 SF_SET_TAG (def_symbol_in_progress);
2492 /* intentional fallthrough */
2493 case C_FILE:
2494 case C_TPDEF:
2495 SF_SET_DEBUG (def_symbol_in_progress);
2496 S_SET_SEGMENT (def_symbol_in_progress, SEG_DEBUG);
2497 break;
2498
2499 case C_EFCN:
dcd619be 2500 SF_SET_LOCAL (def_symbol_in_progress); /* Do not emit this symbol. */
252b5132
RH
2501 /* intentional fallthrough */
2502 case C_BLOCK:
2503 SF_SET_PROCESS (def_symbol_in_progress); /* Will need processing before writing */
2504 /* intentional fallthrough */
2505 case C_FCN:
2506 S_SET_SEGMENT (def_symbol_in_progress, SEG_E0);
2507
2508 if (strcmp (S_GET_NAME (def_symbol_in_progress), ".bf") == 0)
2509 { /* .bf */
2510 if (function_lineoff < 0)
2511 {
2512 fprintf (stderr, _("`.bf' symbol without preceding function\n"));
2513 } /* missing function symbol */
2514 SA_GET_SYM_LNNOPTR (last_line_symbol) = function_lineoff;
2515
2516 SF_SET_PROCESS (last_line_symbol);
2517 SF_SET_ADJ_LNNOPTR (last_line_symbol);
2518 SF_SET_PROCESS (def_symbol_in_progress);
2519 function_lineoff = -1;
2520 }
dcd619be 2521 /* Value is always set to . */
252b5132
RH
2522 def_symbol_in_progress->sy_frag = frag_now;
2523 S_SET_VALUE (def_symbol_in_progress, (valueT) frag_now_fix ());
2524 break;
2525
2526#ifdef C_AUTOARG
2527 case C_AUTOARG:
2528#endif /* C_AUTOARG */
2529 case C_AUTO:
2530 case C_REG:
2531 case C_MOS:
2532 case C_MOE:
2533 case C_MOU:
2534 case C_ARG:
2535 case C_REGPARM:
2536 case C_FIELD:
2537 case C_EOS:
2538 SF_SET_DEBUG (def_symbol_in_progress);
2539 S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
2540 break;
2541
2542 case C_EXT:
2543 case C_WEAKEXT:
2544#ifdef TE_PE
2545 case C_NT_WEAK:
2546#endif
2547 case C_STAT:
2548 case C_LABEL:
2549 /* Valid but set somewhere else (s_comm, s_lcomm, colon) */
2550 break;
2551
2552 case C_USTATIC:
2553 case C_EXTDEF:
2554 case C_ULABEL:
2555 as_warn (_("unexpected storage class %d"), S_GET_STORAGE_CLASS (def_symbol_in_progress));
2556 break;
2557 } /* switch on storage class */
2558
2559 /* Now that we have built a debug symbol, try to find if we should
2560 merge with an existing symbol or not. If a symbol is C_EFCN or
2561 absolute_section or untagged SEG_DEBUG it never merges. We also
2562 don't merge labels, which are in a different namespace, nor
2563 symbols which have not yet been defined since they are typically
2564 unique, nor do we merge tags with non-tags. */
2565
2566 /* Two cases for functions. Either debug followed by definition or
2567 definition followed by debug. For definition first, we will
2568 merge the debug symbol into the definition. For debug first, the
2569 lineno entry MUST point to the definition function or else it
2570 will point off into space when crawl_symbols() merges the debug
2571 symbol into the real symbol. Therefor, let's presume the debug
dcd619be 2572 symbol is a real function reference. */
252b5132
RH
2573
2574 /* FIXME-SOON If for some reason the definition label/symbol is
2575 never seen, this will probably leave an undefined symbol at link
dcd619be 2576 time. */
252b5132
RH
2577
2578 if (S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_EFCN
2579 || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_LABEL
2580 || (S_GET_SEGMENT (def_symbol_in_progress) == SEG_DEBUG
2581 && !SF_GET_TAG (def_symbol_in_progress))
2582 || S_GET_SEGMENT (def_symbol_in_progress) == absolute_section
2583 || def_symbol_in_progress->sy_value.X_op != O_constant
2584 || (symbolP = symbol_find_base (S_GET_NAME (def_symbol_in_progress), DO_NOT_STRIP)) == NULL
2585 || (SF_GET_TAG (def_symbol_in_progress) != SF_GET_TAG (symbolP)))
2586 {
2587 symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP,
2588 &symbol_lastP);
2589 }
2590 else
2591 {
2592 /* This symbol already exists, merge the newly created symbol
2593 into the old one. This is not mandatory. The linker can
2594 handle duplicate symbols correctly. But I guess that it save
2595 a *lot* of space if the assembly file defines a lot of
2596 symbols. [loic] */
2597
2598 /* The debug entry (def_symbol_in_progress) is merged into the
2599 previous definition. */
2600
2601 c_symbol_merge (def_symbol_in_progress, symbolP);
dcd619be 2602 /* FIXME-SOON Should *def_symbol_in_progress be free'd? xoxorich. */
252b5132
RH
2603 def_symbol_in_progress = symbolP;
2604
2605 if (SF_GET_FUNCTION (def_symbol_in_progress)
2606 || SF_GET_TAG (def_symbol_in_progress)
2607 || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_STAT)
2608 {
2609 /* For functions, and tags, and static symbols, the symbol
2610 *must* be where the debug symbol appears. Move the
dcd619be 2611 existing symbol to the current place. */
252b5132
RH
2612 /* If it already is at the end of the symbol list, do nothing */
2613 if (def_symbol_in_progress != symbol_lastP)
2614 {
2615 symbol_remove (def_symbol_in_progress, &symbol_rootP,
2616 &symbol_lastP);
2617 symbol_append (def_symbol_in_progress, symbol_lastP,
2618 &symbol_rootP, &symbol_lastP);
2619 } /* if not already in place */
2620 } /* if function */
2621 } /* normal or mergable */
2622
2623 if (SF_GET_TAG (def_symbol_in_progress))
2624 {
2625 symbolS *oldtag;
2626
2627 oldtag = symbol_find_base (S_GET_NAME (def_symbol_in_progress),
2628 DO_NOT_STRIP);
2629 if (oldtag == NULL || ! SF_GET_TAG (oldtag))
2630 tag_insert (S_GET_NAME (def_symbol_in_progress),
2631 def_symbol_in_progress);
2632 }
2633
2634 if (SF_GET_FUNCTION (def_symbol_in_progress))
2635 {
2636 know (sizeof (def_symbol_in_progress) <= sizeof (long));
2637 function_lineoff
2638 = c_line_new (def_symbol_in_progress, 0, 0, &zero_address_frag);
2639
2640 SF_SET_PROCESS (def_symbol_in_progress);
2641
2642 if (symbolP == NULL)
2643 {
2644 /* That is, if this is the first time we've seen the
dcd619be 2645 function... */
252b5132
RH
2646 symbol_table_insert (def_symbol_in_progress);
2647 } /* definition follows debug */
2648 } /* Create the line number entry pointing to the function being defined */
2649
2650 def_symbol_in_progress = NULL;
2651 demand_empty_rest_of_line ();
2652}
2653
2654static void
2655obj_coff_dim (ignore)
a04b544b 2656 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
2657{
2658 int dim_index;
2659
2660 if (def_symbol_in_progress == NULL)
2661 {
2662 as_warn (_(".dim pseudo-op used outside of .def/.endef: ignored."));
2663 demand_empty_rest_of_line ();
2664 return;
2665 } /* if not inside .def/.endef */
2666
2667 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
2668
2669 for (dim_index = 0; dim_index < DIMNUM; dim_index++)
2670 {
2671 SKIP_WHITESPACES ();
2672 SA_SET_SYM_DIMEN (def_symbol_in_progress, dim_index,
2673 get_absolute_expression ());
2674
2675 switch (*input_line_pointer)
2676 {
2677 case ',':
2678 input_line_pointer++;
2679 break;
2680
2681 default:
2682 as_warn (_("badly formed .dim directive ignored"));
2683 /* intentional fallthrough */
2684 case '\n':
2685 case ';':
2686 dim_index = DIMNUM;
2687 break;
2688 }
2689 }
2690
2691 demand_empty_rest_of_line ();
2692}
2693
2694static void
2695obj_coff_line (ignore)
a04b544b 2696 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
2697{
2698 int this_base;
2699 const char *name;
2700
2701 if (def_symbol_in_progress == NULL)
2702 {
2703 obj_coff_ln (0);
2704 return;
2705 }
2706
2707 name = S_GET_NAME (def_symbol_in_progress);
2708 this_base = get_absolute_expression ();
2709
2710 /* Only .bf symbols indicate the use of a new base line number; the
2711 line numbers associated with .ef, .bb, .eb are relative to the
2712 start of the containing function. */
2713 if (!strcmp (".bf", name))
2714 {
2715#if 0 /* XXX Can we ever have line numbers going backwards? */
2716 if (this_base > line_base)
2717#endif
2718 {
2719 line_base = this_base;
2720 }
2721
2722#ifndef NO_LISTING
2723 {
2724 extern int listing;
2725 if (listing)
2726 {
2727 listing_source_line ((unsigned int) line_base);
2728 }
2729 }
2730#endif
2731 }
2732
2733 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
2734 SA_SET_SYM_LNNO (def_symbol_in_progress, this_base);
2735
2736 demand_empty_rest_of_line ();
2737}
2738
2739static void
2740obj_coff_size (ignore)
a04b544b 2741 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
2742{
2743 if (def_symbol_in_progress == NULL)
2744 {
2745 as_warn (_(".size pseudo-op used outside of .def/.endef ignored."));
2746 demand_empty_rest_of_line ();
2747 return;
2748 } /* if not inside .def/.endef */
2749
2750 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
2751 SA_SET_SYM_SIZE (def_symbol_in_progress, get_absolute_expression ());
2752 demand_empty_rest_of_line ();
2753}
2754
2755static void
2756obj_coff_scl (ignore)
a04b544b 2757 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
2758{
2759 if (def_symbol_in_progress == NULL)
2760 {
2761 as_warn (_(".scl pseudo-op used outside of .def/.endef ignored."));
2762 demand_empty_rest_of_line ();
2763 return;
2764 } /* if not inside .def/.endef */
2765
2766 S_SET_STORAGE_CLASS (def_symbol_in_progress, get_absolute_expression ());
2767 demand_empty_rest_of_line ();
2768}
2769
2770static void
2771obj_coff_tag (ignore)
a04b544b 2772 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
2773{
2774 char *symbol_name;
2775 char name_end;
2776
2777 if (def_symbol_in_progress == NULL)
2778 {
2779 as_warn (_(".tag pseudo-op used outside of .def/.endef ignored."));
2780 demand_empty_rest_of_line ();
2781 return;
2782 }
2783
2784 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
2785 symbol_name = input_line_pointer;
2786 name_end = get_symbol_end ();
2787#ifdef tc_canonicalize_symbol_name
2788 symbol_name = tc_canonicalize_symbol_name (symbol_name);
2789#endif
2790
2791 /* Assume that the symbol referred to by .tag is always defined.
dcd619be 2792 This was a bad assumption. I've added find_or_make. xoxorich. */
252b5132
RH
2793 SA_SET_SYM_TAGNDX (def_symbol_in_progress,
2794 (long) tag_find_or_make (symbol_name));
2795 if (SA_GET_SYM_TAGNDX (def_symbol_in_progress) == 0L)
2796 {
2797 as_warn (_("tag not found for .tag %s"), symbol_name);
2798 } /* not defined */
2799
2800 SF_SET_TAGGED (def_symbol_in_progress);
2801 *input_line_pointer = name_end;
2802
2803 demand_empty_rest_of_line ();
2804}
2805
2806static void
2807obj_coff_type (ignore)
a04b544b 2808 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
2809{
2810 if (def_symbol_in_progress == NULL)
2811 {
2812 as_warn (_(".type pseudo-op used outside of .def/.endef ignored."));
2813 demand_empty_rest_of_line ();
2814 return;
2815 } /* if not inside .def/.endef */
2816
2817 S_SET_DATA_TYPE (def_symbol_in_progress, get_absolute_expression ());
2818
2819 if (ISFCN (S_GET_DATA_TYPE (def_symbol_in_progress)) &&
2820 S_GET_STORAGE_CLASS (def_symbol_in_progress) != C_TPDEF)
2821 {
2822 SF_SET_FUNCTION (def_symbol_in_progress);
2823 } /* is a function */
2824
2825 demand_empty_rest_of_line ();
2826}
2827
2828static void
2829obj_coff_val (ignore)
a04b544b 2830 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
2831{
2832 if (def_symbol_in_progress == NULL)
2833 {
2834 as_warn (_(".val pseudo-op used outside of .def/.endef ignored."));
2835 demand_empty_rest_of_line ();
2836 return;
2837 } /* if not inside .def/.endef */
2838
2839 if (is_name_beginner (*input_line_pointer))
2840 {
2841 char *symbol_name = input_line_pointer;
2842 char name_end = get_symbol_end ();
2843
2844#ifdef tc_canonicalize_symbol_name
2845 symbol_name = tc_canonicalize_symbol_name (symbol_name);
2846#endif
2847
2848 if (!strcmp (symbol_name, "."))
2849 {
2850 def_symbol_in_progress->sy_frag = frag_now;
2851 S_SET_VALUE (def_symbol_in_progress, (valueT) frag_now_fix ());
2852 /* If the .val is != from the .def (e.g. statics) */
2853 }
2854 else if (strcmp (S_GET_NAME (def_symbol_in_progress), symbol_name))
2855 {
2856 def_symbol_in_progress->sy_value.X_op = O_symbol;
2857 def_symbol_in_progress->sy_value.X_add_symbol =
2858 symbol_find_or_make (symbol_name);
2859 def_symbol_in_progress->sy_value.X_op_symbol = NULL;
2860 def_symbol_in_progress->sy_value.X_add_number = 0;
2861
2862 /* If the segment is undefined when the forward reference is
2863 resolved, then copy the segment id from the forward
2864 symbol. */
2865 SF_SET_GET_SEGMENT (def_symbol_in_progress);
2866
0561a208
ILT
2867 /* FIXME: gcc can generate address expressions here in
2868 unusual cases (search for "obscure" in sdbout.c). We
2869 just ignore the offset here, thus generating incorrect
2870 debugging information. We ignore the rest of the line
2871 just below. */
252b5132
RH
2872 }
2873 /* Otherwise, it is the name of a non debug symbol and
dcd619be 2874 its value will be calculated later. */
252b5132
RH
2875 *input_line_pointer = name_end;
2876
2877 /* FIXME: this is to avoid an error message in the
2878 FIXME case mentioned just above. */
2879 while (! is_end_of_line[(unsigned char) *input_line_pointer])
2880 ++input_line_pointer;
2881 }
2882 else
2883 {
2884 S_SET_VALUE (def_symbol_in_progress,
2885 (valueT) get_absolute_expression ());
2886 } /* if symbol based */
2887
2888 demand_empty_rest_of_line ();
2889}
2890
2891#ifdef TE_PE
2892
2893/* Handle the .linkonce pseudo-op. This is parsed by s_linkonce in
2894 read.c, which then calls this object file format specific routine. */
2895
2896void
2897obj_coff_pe_handle_link_once (type)
2898 enum linkonce_type type;
2899{
2900 seg_info (now_seg)->scnhdr.s_flags |= IMAGE_SCN_LNK_COMDAT;
2901
2902 /* We store the type in the seg_info structure, and use it to set up
2903 the auxiliary entry for the section symbol in c_section_symbol. */
2904 seg_info (now_seg)->linkonce = type;
2905}
2906
2907#endif /* TE_PE */
2908
2909void
2910coff_obj_read_begin_hook ()
2911{
dcd619be 2912 /* These had better be the same. Usually 18 bytes. */
252b5132
RH
2913#ifndef BFD_HEADERS
2914 know (sizeof (SYMENT) == sizeof (AUXENT));
2915 know (SYMESZ == AUXESZ);
2916#endif
2917 tag_init ();
2918}
2919
2920/* This function runs through the symbol table and puts all the
2921 externals onto another chain */
2922
2923/* The chain of globals. */
2924symbolS *symbol_globalP;
2925symbolS *symbol_global_lastP;
2926
2927/* The chain of externals */
2928symbolS *symbol_externP;
2929symbolS *symbol_extern_lastP;
2930
2931stack *block_stack;
2932symbolS *last_functionP;
2933static symbolS *last_bfP;
2934symbolS *last_tagP;
2935
2936static unsigned int
2937yank_symbols ()
2938{
2939 symbolS *symbolP;
2940 unsigned int symbol_number = 0;
2941 unsigned int last_file_symno = 0;
2942
2943 struct filename_list *filename_list_scan = filename_list_head;
2944
2945 for (symbolP = symbol_rootP;
2946 symbolP;
2947 symbolP = symbolP ? symbol_next (symbolP) : symbol_rootP)
2948 {
2949 if (symbolP->sy_mri_common)
2950 {
2951 if (S_GET_STORAGE_CLASS (symbolP) == C_EXT
2952#ifdef TE_PE
2953 || S_GET_STORAGE_CLASS (symbolP) == C_NT_WEAK
2954#endif
2955 || S_GET_STORAGE_CLASS (symbolP) == C_WEAKEXT)
2956 as_bad (_("%s: global symbols not supported in common sections"),
2957 S_GET_NAME (symbolP));
2958 symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
2959 continue;
2960 }
2961
2962 if (!SF_GET_DEBUG (symbolP))
2963 {
2964 /* Debug symbols do not need all this rubbish */
2965 symbolS *real_symbolP;
2966
dcd619be 2967 /* L* and C_EFCN symbols never merge. */
252b5132
RH
2968 if (!SF_GET_LOCAL (symbolP)
2969 && !SF_GET_STATICS (symbolP)
2970 && S_GET_STORAGE_CLASS (symbolP) != C_LABEL
2971 && symbolP->sy_value.X_op == O_constant
2972 && (real_symbolP = symbol_find_base (S_GET_NAME (symbolP), DO_NOT_STRIP))
2973 && real_symbolP != symbolP)
2974 {
2975 /* FIXME-SOON: where do dups come from?
dcd619be 2976 Maybe tag references before definitions? xoxorich. */
252b5132
RH
2977 /* Move the debug data from the debug symbol to the
2978 real symbol. Do NOT do the oposite (i.e. move from
2979 real symbol to debug symbol and remove real symbol from the
2980 list.) Because some pointers refer to the real symbol
dcd619be 2981 whereas no pointers refer to the debug symbol. */
252b5132
RH
2982 c_symbol_merge (symbolP, real_symbolP);
2983 /* Replace the current symbol by the real one */
2984 /* The symbols will never be the last or the first
2985 because : 1st symbol is .file and 3 last symbols are
2986 .text, .data, .bss */
2987 symbol_remove (real_symbolP, &symbol_rootP, &symbol_lastP);
2988 symbol_insert (real_symbolP, symbolP, &symbol_rootP, &symbol_lastP);
2989 symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
2990 symbolP = real_symbolP;
2991 } /* if not local but dup'd */
2992
2993 if (flag_readonly_data_in_text && (S_GET_SEGMENT (symbolP) == SEG_E1))
2994 {
2995 S_SET_SEGMENT (symbolP, SEG_E0);
2996 } /* push data into text */
2997
6386f3a7 2998 resolve_symbol_value (symbolP);
252b5132
RH
2999
3000 if (S_GET_STORAGE_CLASS (symbolP) == C_NULL)
3001 {
3002 if (!S_IS_DEFINED (symbolP) && !SF_GET_LOCAL (symbolP))
3003 {
3004 S_SET_EXTERNAL (symbolP);
3005 }
3006 else if (S_GET_SEGMENT (symbolP) == SEG_E0)
3007 {
3008 S_SET_STORAGE_CLASS (symbolP, C_LABEL);
3009 }
3010 else
3011 {
3012 S_SET_STORAGE_CLASS (symbolP, C_STAT);
3013 }
3014 }
3015
3016 /* Mainly to speed up if not -g */
3017 if (SF_GET_PROCESS (symbolP))
3018 {
dcd619be 3019 /* Handle the nested blocks auxiliary info. */
252b5132
RH
3020 if (S_GET_STORAGE_CLASS (symbolP) == C_BLOCK)
3021 {
3022 if (!strcmp (S_GET_NAME (symbolP), ".bb"))
3023 stack_push (block_stack, (char *) &symbolP);
3024 else
3025 { /* .eb */
3026 register symbolS *begin_symbolP;
3027 begin_symbolP = *(symbolS **) stack_pop (block_stack);
3028 if (begin_symbolP == (symbolS *) 0)
3029 as_warn (_("mismatched .eb"));
3030 else
3031 SA_SET_SYM_ENDNDX (begin_symbolP, symbol_number + 2);
3032 }
3033 }
3034 /* If we are able to identify the type of a function, and we
3035 are out of a function (last_functionP == 0) then, the
3036 function symbol will be associated with an auxiliary
dcd619be 3037 entry. */
252b5132
RH
3038 if (last_functionP == (symbolS *) 0 &&
3039 SF_GET_FUNCTION (symbolP))
3040 {
3041 last_functionP = symbolP;
3042
3043 if (S_GET_NUMBER_AUXILIARY (symbolP) < 1)
3044 {
3045 S_SET_NUMBER_AUXILIARY (symbolP, 1);
3046 } /* make it at least 1 */
3047
dcd619be 3048 /* Clobber possible stale .dim information. */
252b5132
RH
3049#if 0
3050 /* Iffed out by steve - this fries the lnnoptr info too */
3051 bzero (symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen,
3052 sizeof (symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen));
3053#endif
3054 }
3055 if (S_GET_STORAGE_CLASS (symbolP) == C_FCN)
3056 {
3057 if (strcmp (S_GET_NAME (symbolP), ".bf") == 0)
3058 {
3059 if (last_bfP != NULL)
3060 SA_SET_SYM_ENDNDX (last_bfP, symbol_number);
3061 last_bfP = symbolP;
3062 }
3063 }
3064 else if (S_GET_STORAGE_CLASS (symbolP) == C_EFCN)
3065 {
3066 /* I don't even know if this is needed for sdb. But
3067 the standard assembler generates it, so... */
3068 if (last_functionP == (symbolS *) 0)
3069 as_fatal (_("C_EFCN symbol out of scope"));
3070 SA_SET_SYM_FSIZE (last_functionP,
3071 (long) (S_GET_VALUE (symbolP) -
3072 S_GET_VALUE (last_functionP)));
3073 SA_SET_SYM_ENDNDX (last_functionP, symbol_number);
3074 last_functionP = (symbolS *) 0;
3075 }
3076 }
3077 }
3078 else if (SF_GET_TAG (symbolP))
3079 {
3080 /* First descriptor of a structure must point to
dcd619be 3081 the first slot after the structure description. */
252b5132
RH
3082 last_tagP = symbolP;
3083
3084 }
3085 else if (S_GET_STORAGE_CLASS (symbolP) == C_EOS)
3086 {
3087 /* +2 take in account the current symbol */
3088 SA_SET_SYM_ENDNDX (last_tagP, symbol_number + 2);
3089 }
3090 else if (S_GET_STORAGE_CLASS (symbolP) == C_FILE)
3091 {
3092 /* If the filename was too long to fit in the
3093 auxent, put it in the string table */
3094 if (SA_GET_FILE_FNAME_ZEROS (symbolP) == 0
3095 && SA_GET_FILE_FNAME_OFFSET (symbolP) != 0)
3096 {
3097 SA_SET_FILE_FNAME_OFFSET (symbolP, string_byte_count);
3098 string_byte_count += strlen (filename_list_scan->filename) + 1;
3099 filename_list_scan = filename_list_scan->next;
3100 }
3101 if (S_GET_VALUE (symbolP))
3102 {
3103 S_SET_VALUE (symbolP, last_file_symno);
3104 last_file_symno = symbol_number;
3105 } /* no one points at the first .file symbol */
3106 } /* if debug or tag or eos or file */
3107
3108#ifdef tc_frob_coff_symbol
3109 tc_frob_coff_symbol (symbolP);
3110#endif
3111
3112 /* We must put the external symbols apart. The loader
3113 does not bomb if we do not. But the references in
3114 the endndx field for a .bb symbol are not corrected
3115 if an external symbol is removed between .bb and .be.
3116 I.e in the following case :
3117 [20] .bb endndx = 22
3118 [21] foo external
3119 [22] .be
3120 ld will move the symbol 21 to the end of the list but
dcd619be 3121 endndx will still be 22 instead of 21. */
252b5132
RH
3122
3123 if (SF_GET_LOCAL (symbolP))
3124 {
3125 /* remove C_EFCN and LOCAL (L...) symbols */
3126 /* next pointer remains valid */
3127 symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
3128
3129 }
3130 else if (symbolP->sy_value.X_op == O_symbol
3131 && (! S_IS_DEFINED (symbolP) || S_IS_COMMON (symbolP)))
3132 {
3133 /* Skip symbols which were equated to undefined or common
3134 symbols. */
3135 symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
3136 }
3137 else if (!S_IS_DEFINED (symbolP)
3138 && !S_IS_DEBUG (symbolP)
3139 && !SF_GET_STATICS (symbolP)
3140 && (S_GET_STORAGE_CLASS (symbolP) == C_EXT
3141#ifdef TE_PE
3142 || S_GET_STORAGE_CLASS (symbolP) == C_NT_WEAK
3143#endif
3144 || S_GET_STORAGE_CLASS (symbolP) == C_WEAKEXT))
3145 {
3146 /* if external, Remove from the list */
3147 symbolS *hold = symbol_previous (symbolP);
3148
3149 symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
3150 symbol_clear_list_pointers (symbolP);
3151 symbol_append (symbolP, symbol_extern_lastP, &symbol_externP, &symbol_extern_lastP);
3152 symbolP = hold;
3153 }
3154 else if (! S_IS_DEBUG (symbolP)
3155 && ! SF_GET_STATICS (symbolP)
3156 && ! SF_GET_FUNCTION (symbolP)
3157 && (S_GET_STORAGE_CLASS (symbolP) == C_EXT
3158#ifdef TE_PE
3159 || S_GET_STORAGE_CLASS (symbolP) == C_NT_WEAK
3160#endif
3161 || S_GET_STORAGE_CLASS (symbolP) == C_NT_WEAK))
3162 {
3163 symbolS *hold = symbol_previous (symbolP);
3164
3165 /* The O'Reilly COFF book says that defined global symbols
3166 come at the end of the symbol table, just before
3167 undefined global symbols. */
3168
3169 symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
3170 symbol_clear_list_pointers (symbolP);
3171 symbol_append (symbolP, symbol_global_lastP, &symbol_globalP,
3172 &symbol_global_lastP);
3173 symbolP = hold;
3174 }
3175 else
3176 {
3177 if (SF_GET_STRING (symbolP))
3178 {
3179 symbolP->sy_name_offset = string_byte_count;
3180 string_byte_count += strlen (S_GET_NAME (symbolP)) + 1;
3181 }
3182 else
3183 {
3184 symbolP->sy_name_offset = 0;
3185 } /* fix "long" names */
3186
3187 symbolP->sy_number = symbol_number;
3188 symbol_number += 1 + S_GET_NUMBER_AUXILIARY (symbolP);
3189 } /* if local symbol */
3190 } /* traverse the symbol list */
3191 return symbol_number;
3192
3193}
3194
252b5132
RH
3195static unsigned int
3196glue_symbols (head, tail)
3197 symbolS **head;
3198 symbolS **tail;
3199{
3200 unsigned int symbol_number = 0;
3201
3202 while (*head != NULL)
3203 {
3204 symbolS *tmp = *head;
3205
3206 /* append */
3207 symbol_remove (tmp, head, tail);
3208 symbol_append (tmp, symbol_lastP, &symbol_rootP, &symbol_lastP);
3209
3210 /* and process */
3211 if (SF_GET_STRING (tmp))
3212 {
3213 tmp->sy_name_offset = string_byte_count;
3214 string_byte_count += strlen (S_GET_NAME (tmp)) + 1;
3215 }
3216 else
3217 {
3218 tmp->sy_name_offset = 0;
3219 } /* fix "long" names */
3220
3221 tmp->sy_number = symbol_number;
3222 symbol_number += 1 + S_GET_NUMBER_AUXILIARY (tmp);
3223 } /* append the entire extern chain */
3224
3225 return symbol_number;
3226}
3227
3228static unsigned int
3229tie_tags ()
3230{
3231 unsigned int symbol_number = 0;
3232 symbolS *symbolP;
3233
3234 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
3235 {
3236 symbolP->sy_number = symbol_number;
3237
3238 if (SF_GET_TAGGED (symbolP))
3239 {
3240 SA_SET_SYM_TAGNDX
3241 (symbolP,
3242 ((symbolS *) SA_GET_SYM_TAGNDX (symbolP))->sy_number);
3243 }
3244
3245 symbol_number += 1 + S_GET_NUMBER_AUXILIARY (symbolP);
3246 }
3247
3248 return symbol_number;
3249}
3250
3251static void
3252crawl_symbols (h, abfd)
3253 object_headers *h;
a04b544b 3254 bfd *abfd ATTRIBUTE_UNUSED;
252b5132
RH
3255{
3256 unsigned int i;
3257
3258 /* Initialize the stack used to keep track of the matching .bb .be */
3259
3260 block_stack = stack_init (512, sizeof (symbolS *));
3261
3262 /* The symbol list should be ordered according to the following sequence
3263 * order :
3264 * . .file symbol
3265 * . debug entries for functions
3266 * . fake symbols for the sections, including .text .data and .bss
3267 * . defined symbols
3268 * . undefined symbols
3269 * But this is not mandatory. The only important point is to put the
3270 * undefined symbols at the end of the list.
3271 */
3272
dcd619be 3273 /* Is there a .file symbol ? If not insert one at the beginning. */
252b5132
RH
3274 if (symbol_rootP == NULL
3275 || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
3276 {
3277 c_dot_file_symbol ("fake");
3278 }
3279
3280 /*
3281 * Build up static symbols for the sections, they are filled in later
3282 */
3283
252b5132
RH
3284 for (i = SEG_E0; i < SEG_LAST; i++)
3285 if (segment_info[i].scnhdr.s_name[0])
3286 segment_info[i].dot = c_section_symbol (segment_info[i].name,
3287 i - SEG_E0 + 1);
3288
3289 /* Take all the externals out and put them into another chain */
3290 H_SET_SYMBOL_TABLE_SIZE (h, yank_symbols ());
3291 /* Take the externals and glue them onto the end.*/
3292 H_SET_SYMBOL_TABLE_SIZE (h,
3293 (H_GET_SYMBOL_COUNT (h)
3294 + glue_symbols (&symbol_globalP,
3295 &symbol_global_lastP)
3296 + glue_symbols (&symbol_externP,
3297 &symbol_extern_lastP)));
3298
3299 H_SET_SYMBOL_TABLE_SIZE (h, tie_tags ());
3300 know (symbol_globalP == NULL);
3301 know (symbol_global_lastP == NULL);
3302 know (symbol_externP == NULL);
3303 know (symbol_extern_lastP == NULL);
3304}
3305
3306/*
3307 * Find strings by crawling along symbol table chain.
3308 */
3309
3310void
3311w_strings (where)
3312 char *where;
3313{
3314 symbolS *symbolP;
3315 struct filename_list *filename_list_scan = filename_list_head;
3316
3317 /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
3318 md_number_to_chars (where, (valueT) string_byte_count, 4);
3319 where += 4;
3320
3321#ifdef COFF_LONG_SECTION_NAMES
3322 /* Support long section names as found in PE. This code must
3323 coordinate with that in coff_header_append and write_object_file. */
3324 {
3325 unsigned int i;
3326
3327 for (i = SEG_E0; i < SEG_LAST; i++)
3328 {
3329 if (segment_info[i].scnhdr.s_name[0]
3330 && strlen (segment_info[i].name) > SCNNMLEN)
3331 {
3332 unsigned int size;
3333
3334 size = strlen (segment_info[i].name) + 1;
3335 memcpy (where, segment_info[i].name, size);
3336 where += size;
3337 }
3338 }
3339 }
3340#endif /* COFF_LONG_SECTION_NAMES */
3341
3342 for (symbolP = symbol_rootP;
3343 symbolP;
3344 symbolP = symbol_next (symbolP))
3345 {
3346 unsigned int size;
3347
3348 if (SF_GET_STRING (symbolP))
3349 {
3350 size = strlen (S_GET_NAME (symbolP)) + 1;
3351 memcpy (where, S_GET_NAME (symbolP), size);
3352 where += size;
3353 }
3354 if (S_GET_STORAGE_CLASS (symbolP) == C_FILE
3355 && SA_GET_FILE_FNAME_ZEROS (symbolP) == 0
3356 && SA_GET_FILE_FNAME_OFFSET (symbolP) != 0)
3357 {
3358 size = strlen (filename_list_scan->filename) + 1;
3359 memcpy (where, filename_list_scan->filename, size);
3360 filename_list_scan = filename_list_scan ->next;
3361 where += size;
3362 }
3363 }
3364}
3365
3366static void
3367do_linenos_for (abfd, h, file_cursor)
3368 bfd * abfd;
3369 object_headers * h;
3370 unsigned long *file_cursor;
3371{
3372 unsigned int idx;
3373 unsigned long start = *file_cursor;
3374
3375 for (idx = SEG_E0; idx < SEG_LAST; idx++)
3376 {
3377 segment_info_type *s = segment_info + idx;
3378
252b5132
RH
3379 if (s->scnhdr.s_nlnno != 0)
3380 {
3381 struct lineno_list *line_ptr;
3382
3383 struct external_lineno *buffer =
3384 (struct external_lineno *) xmalloc (s->scnhdr.s_nlnno * LINESZ);
3385
3386 struct external_lineno *dst = buffer;
3387
3388 /* Run through the table we've built and turn it into its external
3389 form, take this chance to remove duplicates */
3390
3391 for (line_ptr = s->lineno_list_head;
3392 line_ptr != (struct lineno_list *) NULL;
3393 line_ptr = line_ptr->next)
3394 {
252b5132
RH
3395 if (line_ptr->line.l_lnno == 0)
3396 {
ea3b9044
NC
3397 /* Turn a pointer to a symbol into the symbols' index,
3398 provided that it has been initialised. */
3399 if (line_ptr->line.l_addr.l_symndx)
3400 line_ptr->line.l_addr.l_symndx =
3401 ((symbolS *) line_ptr->line.l_addr.l_symndx)->sy_number;
252b5132
RH
3402 }
3403 else
3404 {
3405 line_ptr->line.l_addr.l_paddr += ((struct frag *) (line_ptr->frag))->fr_address;
3406 }
3407
252b5132
RH
3408 (void) bfd_coff_swap_lineno_out (abfd, &(line_ptr->line), dst);
3409 dst++;
3410
3411 }
3412
3413 s->scnhdr.s_lnnoptr = *file_cursor;
3414
0e1a166b 3415 bfd_bwrite (buffer, (bfd_size_type) s->scnhdr.s_nlnno * LINESZ, abfd);
252b5132
RH
3416 free (buffer);
3417
3418 *file_cursor += s->scnhdr.s_nlnno * LINESZ;
3419 }
3420 }
3421 H_SET_LINENO_SIZE (h, *file_cursor - start);
3422}
3423
252b5132
RH
3424/* Now we run through the list of frag chains in a segment and
3425 make all the subsegment frags appear at the end of the
3426 list, as if the seg 0 was extra long */
3427
3428static void
3429remove_subsegs ()
3430{
3431 unsigned int i;
3432
3433 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
3434 {
3435 frchainS *head = segment_info[i].frchainP;
3436 fragS dummy;
3437 fragS *prev_frag = &dummy;
3438
3439 while (head && head->frch_seg == i)
3440 {
3441 prev_frag->fr_next = head->frch_root;
3442 prev_frag = head->frch_last;
3443 head = head->frch_next;
3444 }
3445 prev_frag->fr_next = 0;
3446 }
3447}
3448
3449unsigned long machine;
3450int coff_flags;
3451extern void
3452write_object_file ()
3453{
3454 int i;
3455 const char *name;
3456 struct frchain *frchain_ptr;
3457
3458 object_headers headers;
3459 unsigned long file_cursor;
3460 bfd *abfd;
3461 unsigned int addr;
3462 abfd = bfd_openw (out_file_name, TARGET_FORMAT);
3463
252b5132
RH
3464 if (abfd == 0)
3465 {
3466 as_perror (_("FATAL: Can't create %s"), out_file_name);
3467 exit (EXIT_FAILURE);
3468 }
3469 bfd_set_format (abfd, bfd_object);
3470 bfd_set_arch_mach (abfd, BFD_ARCH, machine);
3471
3472 string_byte_count = 4;
3473
3474 for (frchain_ptr = frchain_root;
3475 frchain_ptr != (struct frchain *) NULL;
3476 frchain_ptr = frchain_ptr->frch_next)
3477 {
3478 /* Run through all the sub-segments and align them up. Also
3479 close any open frags. We tack a .fill onto the end of the
3480 frag chain so that any .align's size can be worked by looking
3481 at the next frag. */
3482
3483 subseg_set (frchain_ptr->frch_seg, frchain_ptr->frch_subseg);
b9e57a38 3484
252b5132
RH
3485#ifndef SUB_SEGMENT_ALIGN
3486#define SUB_SEGMENT_ALIGN(SEG) 1
3487#endif
3488#ifdef md_do_align
3489 md_do_align (SUB_SEGMENT_ALIGN (now_seg), (char *) NULL, 0, 0,
3490 alignment_done);
3491#endif
0a9ef439
RH
3492 if (subseg_text_p (now_seg))
3493 frag_align_code (SUB_SEGMENT_ALIGN (now_seg), 0);
3494 else
3495 frag_align (SUB_SEGMENT_ALIGN (now_seg), 0, 0);
3496
252b5132
RH
3497#ifdef md_do_align
3498 alignment_done:
3499#endif
0a9ef439 3500
252b5132
RH
3501 frag_wane (frag_now);
3502 frag_now->fr_fix = 0;
3503 know (frag_now->fr_next == NULL);
3504 }
3505
252b5132
RH
3506 remove_subsegs ();
3507
252b5132
RH
3508 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
3509 {
3510 relax_segment (segment_info[i].frchainP->frch_root, i);
3511 }
3512
1cd55018
AM
3513 /* Relaxation has completed. Freeze all syms. */
3514 finalize_syms = 1;
3515
252b5132
RH
3516 H_SET_NUMBER_OF_SECTIONS (&headers, 0);
3517
3518 /* Find out how big the sections are, and set the addresses. */
3519 addr = 0;
3520 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
3521 {
3522 long size;
3523
3524 segment_info[i].scnhdr.s_paddr = addr;
3525 segment_info[i].scnhdr.s_vaddr = addr;
3526
3527 if (segment_info[i].scnhdr.s_name[0])
3528 {
3529 H_SET_NUMBER_OF_SECTIONS (&headers,
3530 H_GET_NUMBER_OF_SECTIONS (&headers) + 1);
3531
3532#ifdef COFF_LONG_SECTION_NAMES
3533 /* Support long section names as found in PE. This code
3534 must coordinate with that in coff_header_append and
3535 w_strings. */
3536 {
3537 unsigned int len;
3538
3539 len = strlen (segment_info[i].name);
3540 if (len > SCNNMLEN)
3541 string_byte_count += len + 1;
3542 }
3543#endif /* COFF_LONG_SECTION_NAMES */
3544 }
3545
3546 size = size_section (abfd, (unsigned int) i);
3547 addr += size;
3548
3549 /* I think the section alignment is only used on the i960; the
3550 i960 needs it, and it should do no harm on other targets. */
3551#ifdef ALIGNMENT_IN_S_FLAGS
3552 segment_info[i].scnhdr.s_flags |= (section_alignment[i] & 0xF) << 8;
3553#else
3554 segment_info[i].scnhdr.s_align = 1 << section_alignment[i];
3555#endif
3556
3557 if (i == SEG_E0)
3558 H_SET_TEXT_SIZE (&headers, size);
3559 else if (i == SEG_E1)
3560 H_SET_DATA_SIZE (&headers, size);
3561 else if (i == SEG_E2)
3562 H_SET_BSS_SIZE (&headers, size);
3563 }
3564
3565 /* Turn the gas native symbol table shape into a coff symbol table */
3566 crawl_symbols (&headers, abfd);
3567
3568 if (string_byte_count == 4)
3569 string_byte_count = 0;
3570
3571 H_SET_STRING_SIZE (&headers, string_byte_count);
3572
3573#ifdef tc_frob_file
3574 tc_frob_file ();
3575#endif
3576
3577 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
3578 {
3579 fixup_mdeps (segment_info[i].frchainP->frch_root, &headers, i);
3580 fixup_segment (&segment_info[i], i);
3581 }
3582
3583 /* Look for ".stab" segments and fill in their initial symbols
dcd619be 3584 correctly. */
252b5132
RH
3585 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
3586 {
3587 name = segment_info[i].name;
3588
3589 if (name != NULL
3590 && strncmp (".stab", name, 5) == 0
3591 && strncmp (".stabstr", name, 8) != 0)
3592 adjust_stab_section (abfd, i);
3593 }
3594
3595 file_cursor = H_GET_TEXT_FILE_OFFSET (&headers);
3596
3597 bfd_seek (abfd, (file_ptr) file_cursor, 0);
3598
3599 /* Plant the data */
3600
3601 fill_section (abfd, &headers, &file_cursor);
3602
3603 do_relocs_for (abfd, &headers, &file_cursor);
3604
3605 do_linenos_for (abfd, &headers, &file_cursor);
3606
3607 H_SET_FILE_MAGIC_NUMBER (&headers, COFF_MAGIC);
3608#ifndef OBJ_COFF_OMIT_TIMESTAMP
3609 H_SET_TIME_STAMP (&headers, (long)time((time_t *)0));
3610#else
3611 H_SET_TIME_STAMP (&headers, 0);
3612#endif
3613#ifdef TC_COFF_SET_MACHINE
3614 TC_COFF_SET_MACHINE (&headers);
3615#endif
3616
3617#ifndef COFF_FLAGS
3618#define COFF_FLAGS 0
3619#endif
3620
3621#ifdef KEEP_RELOC_INFO
3622 H_SET_FLAGS (&headers, ((H_GET_LINENO_SIZE(&headers) ? 0 : F_LNNO) |
3623 COFF_FLAGS | coff_flags));
3624#else
3625 H_SET_FLAGS (&headers, ((H_GET_LINENO_SIZE(&headers) ? 0 : F_LNNO) |
3626 (H_GET_RELOCATION_SIZE(&headers) ? 0 : F_RELFLG) |
3627 COFF_FLAGS | coff_flags));
3628#endif
3629
3630 {
3631 unsigned int symtable_size = H_GET_SYMBOL_TABLE_SIZE (&headers);
3632 char *buffer1 = xmalloc (symtable_size + string_byte_count + 1);
3633
3634 H_SET_SYMBOL_TABLE_POINTER (&headers, bfd_tell (abfd));
3635 w_symbols (abfd, buffer1, symbol_rootP);
3636 if (string_byte_count > 0)
3637 w_strings (buffer1 + symtable_size);
0e1a166b
AM
3638 bfd_bwrite (buffer1, (bfd_size_type) symtable_size + string_byte_count,
3639 abfd);
252b5132
RH
3640 free (buffer1);
3641 }
3642
3643 coff_header_append (abfd, &headers);
3644#if 0
3645 /* Recent changes to write need this, but where it should
dcd619be 3646 go is up to Ken.. */
252b5132
RH
3647 if (bfd_close_all_done (abfd) == false)
3648 as_fatal (_("Can't close %s: %s"), out_file_name,
3649 bfd_errmsg (bfd_get_error ()));
3650#else
3651 {
3652 extern bfd *stdoutput;
3653 stdoutput = abfd;
3654 }
3655#endif
3656
3657}
3658
3659/* Add a new segment. This is called from subseg_new via the
3660 obj_new_segment macro. */
3661
3662segT
3663obj_coff_add_segment (name)
3664 const char *name;
3665{
3666 unsigned int i;
3667
3668#ifndef COFF_LONG_SECTION_NAMES
3669 char buf[SCNNMLEN + 1];
3670
3671 strncpy (buf, name, SCNNMLEN);
3672 buf[SCNNMLEN] = '\0';
3673 name = buf;
3674#endif
3675
3676 for (i = SEG_E0; i < SEG_LAST && segment_info[i].scnhdr.s_name[0]; i++)
3677 if (strcmp (name, segment_info[i].name) == 0)
3678 return (segT) i;
3679
3680 if (i == SEG_LAST)
3681 {
3682 as_bad (_("Too many new sections; can't add \"%s\""), name);
3683 return now_seg;
3684 }
3685
3686 /* Add a new section. */
3687 strncpy (segment_info[i].scnhdr.s_name, name,
3688 sizeof (segment_info[i].scnhdr.s_name));
3689 segment_info[i].scnhdr.s_flags = STYP_REG;
3690 segment_info[i].name = xstrdup (name);
3691
3692 return (segT) i;
3693}
3694
3695/*
3696 * implement the .section pseudo op:
3697 * .section name {, "flags"}
3698 * ^ ^
3699 * | +--- optional flags: 'b' for bss
3700 * | 'i' for info
3701 * +-- section name 'l' for lib
3702 * 'n' for noload
3703 * 'o' for over
3704 * 'w' for data
3705 * 'd' (apparently m88k for data)
3706 * 'x' for text
3707 * 'r' for read-only data
3708 * But if the argument is not a quoted string, treat it as a
3709 * subsegment number.
3710 */
3711
3712void
3713obj_coff_section (ignore)
a04b544b 3714 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
3715{
3716 /* Strip out the section name */
3717 char *section_name, *name;
3718 char c;
3719 unsigned int exp;
3720 long flags;
3721
3722 if (flag_mri)
3723 {
3724 char type;
3725
3726 s_mri_sect (&type);
3727 flags = 0;
3728 if (type == 'C')
3729 flags = STYP_TEXT;
3730 else if (type == 'D')
3731 flags = STYP_DATA;
3732 segment_info[now_seg].scnhdr.s_flags |= flags;
3733
3734 return;
3735 }
3736
3737 section_name = input_line_pointer;
3738 c = get_symbol_end ();
3739
3740 name = xmalloc (input_line_pointer - section_name + 1);
3741 strcpy (name, section_name);
3742
3743 *input_line_pointer = c;
3744
3745 exp = 0;
3746 flags = 0;
3747
3748 SKIP_WHITESPACE ();
3749 if (*input_line_pointer == ',')
3750 {
3751 ++input_line_pointer;
3752 SKIP_WHITESPACE ();
3753
3754 if (*input_line_pointer != '"')
3755 exp = get_absolute_expression ();
3756 else
3757 {
3758 ++input_line_pointer;
3759 while (*input_line_pointer != '"'
3760 && ! is_end_of_line[(unsigned char) *input_line_pointer])
3761 {
3762 switch (*input_line_pointer)
3763 {
3764 case 'b': flags |= STYP_BSS; break;
3765 case 'i': flags |= STYP_INFO; break;
3766 case 'l': flags |= STYP_LIB; break;
3767 case 'n': flags |= STYP_NOLOAD; break;
3768 case 'o': flags |= STYP_OVER; break;
3769 case 'd':
3770 case 'w': flags |= STYP_DATA; break;
3771 case 'x': flags |= STYP_TEXT; break;
3772 case 'r': flags |= STYP_LIT; break;
3773 default:
3774 as_warn(_("unknown section attribute '%c'"),
3775 *input_line_pointer);
3776 break;
3777 }
3778 ++input_line_pointer;
3779 }
3780 if (*input_line_pointer == '"')
3781 ++input_line_pointer;
3782 }
3783 }
3784
3785 subseg_new (name, (subsegT) exp);
3786
3787 segment_info[now_seg].scnhdr.s_flags |= flags;
3788
3789 demand_empty_rest_of_line ();
3790}
3791
252b5132
RH
3792static void
3793obj_coff_text (ignore)
a04b544b 3794 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
3795{
3796 subseg_new (".text", get_absolute_expression ());
3797}
3798
252b5132
RH
3799static void
3800obj_coff_data (ignore)
a04b544b 3801 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
3802{
3803 if (flag_readonly_data_in_text)
3804 subseg_new (".text", get_absolute_expression () + 1000);
3805 else
3806 subseg_new (".data", get_absolute_expression ());
3807}
3808
3809static void
3810obj_coff_ident (ignore)
a04b544b 3811 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
3812{
3813 segT current_seg = now_seg; /* save current seg */
3814 subsegT current_subseg = now_subseg;
3815 subseg_new (".comment", 0); /* .comment seg */
3816 stringer (1); /* read string */
3817 subseg_set (current_seg, current_subseg); /* restore current seg */
3818}
3819
3820void
3821c_symbol_merge (debug, normal)
3822 symbolS *debug;
3823 symbolS *normal;
3824{
3825 S_SET_DATA_TYPE (normal, S_GET_DATA_TYPE (debug));
3826 S_SET_STORAGE_CLASS (normal, S_GET_STORAGE_CLASS (debug));
3827
3828 if (S_GET_NUMBER_AUXILIARY (debug) > S_GET_NUMBER_AUXILIARY (normal))
3829 {
3830 S_SET_NUMBER_AUXILIARY (normal, S_GET_NUMBER_AUXILIARY (debug));
3831 } /* take the most we have */
3832
3833 if (S_GET_NUMBER_AUXILIARY (debug) > 0)
3834 {
3835 memcpy ((char *) &normal->sy_symbol.ost_auxent[0],
3836 (char *) &debug->sy_symbol.ost_auxent[0],
3837 (unsigned int) (S_GET_NUMBER_AUXILIARY (debug) * AUXESZ));
3838 } /* Move all the auxiliary information */
3839
dcd619be 3840 /* Move the debug flags. */
252b5132
RH
3841 SF_SET_DEBUG_FIELD (normal, SF_GET_DEBUG_FIELD (debug));
3842} /* c_symbol_merge() */
3843
3844static int
3845c_line_new (symbol, paddr, line_number, frag)
3846 symbolS * symbol;
3847 long paddr;
3848 int line_number;
3849 fragS * frag;
3850{
3851 struct lineno_list *new_line =
3852 (struct lineno_list *) xmalloc (sizeof (struct lineno_list));
3853
3854 segment_info_type *s = segment_info + now_seg;
3855 new_line->line.l_lnno = line_number;
3856
3857 if (line_number == 0)
3858 {
3859 last_line_symbol = symbol;
3860 new_line->line.l_addr.l_symndx = (long) symbol;
3861 }
3862 else
3863 {
3864 new_line->line.l_addr.l_paddr = paddr;
3865 }
3866
3867 new_line->frag = (char *) frag;
3868 new_line->next = (struct lineno_list *) NULL;
3869
252b5132
RH
3870 if (s->lineno_list_head == (struct lineno_list *) NULL)
3871 {
3872 s->lineno_list_head = new_line;
3873 }
3874 else
3875 {
3876 s->lineno_list_tail->next = new_line;
3877 }
3878 s->lineno_list_tail = new_line;
3879 return LINESZ * s->scnhdr.s_nlnno++;
3880}
3881
3882void
3883c_dot_file_symbol (filename)
3884 char *filename;
3885{
3886 symbolS *symbolP;
3887
3888 symbolP = symbol_new (".file",
3889 SEG_DEBUG,
3890 0,
3891 &zero_address_frag);
3892
3893 S_SET_STORAGE_CLASS (symbolP, C_FILE);
3894 S_SET_NUMBER_AUXILIARY (symbolP, 1);
3895
3896 if (strlen (filename) > FILNMLEN)
3897 {
3898 /* Filename is too long to fit into an auxent,
3899 we stick it into the string table instead. We keep
3900 a linked list of the filenames we find so we can emit
3901 them later.*/
3902 struct filename_list *f = ((struct filename_list *)
3903 xmalloc (sizeof (struct filename_list)));
3904
3905 f->filename = filename;
3906 f->next = 0;
3907
3908 SA_SET_FILE_FNAME_ZEROS (symbolP, 0);
3909 SA_SET_FILE_FNAME_OFFSET (symbolP, 1);
3910
dcd619be 3911 if (filename_list_tail)
252b5132
RH
3912 filename_list_tail->next = f;
3913 else
3914 filename_list_head = f;
dcd619be 3915 filename_list_tail = f;
252b5132 3916 }
dcd619be 3917 else
252b5132
RH
3918 {
3919 SA_SET_FILE_FNAME (symbolP, filename);
3920 }
3921#ifndef NO_LISTING
3922 {
3923 extern int listing;
3924 if (listing)
3925 {
3926 listing_source_file (filename);
3927 }
3928
3929 }
3930
3931#endif
3932 SF_SET_DEBUG (symbolP);
3933 S_SET_VALUE (symbolP, (valueT) previous_file_symbol);
3934
3935 previous_file_symbol = symbolP;
3936
3937 /* Make sure that the symbol is first on the symbol chain */
3938 if (symbol_rootP != symbolP)
3939 {
3940 symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
3941 symbol_insert (symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP);
3942 }
3943} /* c_dot_file_symbol() */
3944
3945/*
3946 * Build a 'section static' symbol.
3947 */
3948
3949symbolS *
3950c_section_symbol (name, idx)
3951 char *name;
3952 int idx;
3953{
3954 symbolS *symbolP;
3955
3956 symbolP = symbol_find_base (name, DO_NOT_STRIP);
3957 if (symbolP == NULL)
3958 symbolP = symbol_new (name, idx, 0, &zero_address_frag);
3959 else
3960 {
3961 /* Mmmm. I just love violating interfaces. Makes me feel...dirty. */
3962 S_SET_SEGMENT (symbolP, idx);
3963 symbolP->sy_frag = &zero_address_frag;
3964 }
3965
3966 S_SET_STORAGE_CLASS (symbolP, C_STAT);
3967 S_SET_NUMBER_AUXILIARY (symbolP, 1);
3968
3969 SF_SET_STATICS (symbolP);
3970
3971#ifdef TE_DELTA
3972 /* manfred@s-direktnet.de: section symbols *must* have the LOCAL bit cleared,
3973 which is set by the new definition of LOCAL_LABEL in tc-m68k.h. */
3974 SF_CLEAR_LOCAL (symbolP);
3975#endif
3976#ifdef TE_PE
3977 /* If the .linkonce pseudo-op was used for this section, we must
3978 store the information in the auxiliary entry for the section
3979 symbol. */
3980 if (segment_info[idx].linkonce != LINKONCE_UNSET)
3981 {
3982 int type;
3983
3984 switch (segment_info[idx].linkonce)
3985 {
3986 default:
3987 abort ();
3988 case LINKONCE_DISCARD:
3989 type = IMAGE_COMDAT_SELECT_ANY;
3990 break;
3991 case LINKONCE_ONE_ONLY:
3992 type = IMAGE_COMDAT_SELECT_NODUPLICATES;
3993 break;
3994 case LINKONCE_SAME_SIZE:
3995 type = IMAGE_COMDAT_SELECT_SAME_SIZE;
3996 break;
3997 case LINKONCE_SAME_CONTENTS:
3998 type = IMAGE_COMDAT_SELECT_EXACT_MATCH;
3999 break;
4000 }
4001
4002 SYM_AUXENT (symbolP)->x_scn.x_comdat = type;
4003 }
4004#endif /* TE_PE */
4005
4006 return symbolP;
4007} /* c_section_symbol() */
4008
4009static void
4010w_symbols (abfd, where, symbol_rootP)
4011 bfd * abfd;
4012 char *where;
4013 symbolS * symbol_rootP;
4014{
4015 symbolS *symbolP;
4016 unsigned int i;
4017
4018 /* First fill in those values we have only just worked out */
4019 for (i = SEG_E0; i < SEG_LAST; i++)
4020 {
4021 symbolP = segment_info[i].dot;
4022 if (symbolP)
4023 {
4024 SA_SET_SCN_SCNLEN (symbolP, segment_info[i].scnhdr.s_size);
4025 SA_SET_SCN_NRELOC (symbolP, segment_info[i].scnhdr.s_nreloc);
4026 SA_SET_SCN_NLINNO (symbolP, segment_info[i].scnhdr.s_nlnno);
4027 }
4028 }
4029
4030 /*
4031 * Emit all symbols left in the symbol chain.
4032 */
4033 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
4034 {
4035 /* Used to save the offset of the name. It is used to point
dcd619be 4036 to the string in memory but must be a file offset. */
252b5132
RH
4037 register char *temp;
4038
4039 /* We can't fix the lnnoptr field in yank_symbols with the other
4040 adjustments, because we have to wait until we know where they
4041 go in the file. */
4042 if (SF_GET_ADJ_LNNOPTR (symbolP))
4043 {
4044 SA_GET_SYM_LNNOPTR (symbolP) +=
4045 segment_info[S_GET_SEGMENT (symbolP)].scnhdr.s_lnnoptr;
4046 }
4047
4048 tc_coff_symbol_emit_hook (symbolP);
4049
4050 temp = S_GET_NAME (symbolP);
4051 if (SF_GET_STRING (symbolP))
4052 {
4053 S_SET_OFFSET (symbolP, symbolP->sy_name_offset);
4054 S_SET_ZEROES (symbolP, 0);
4055 }
4056 else
4057 {
4058 memset (symbolP->sy_symbol.ost_entry.n_name, 0, SYMNMLEN);
4059 strncpy (symbolP->sy_symbol.ost_entry.n_name, temp, SYMNMLEN);
4060 }
4061 where = symbol_to_chars (abfd, where, symbolP);
4062 S_SET_NAME (symbolP, temp);
4063 }
4064
4065} /* w_symbols() */
4066
4067static void
4068obj_coff_lcomm (ignore)
a04b544b 4069 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
4070{
4071 s_lcomm(0);
4072 return;
4073#if 0
4074 char *name;
4075 char c;
4076 int temp;
4077 char *p;
4078
4079 symbolS *symbolP;
4080
4081 name = input_line_pointer;
4082
4083 c = get_symbol_end ();
4084 p = input_line_pointer;
4085 *p = c;
4086 SKIP_WHITESPACE ();
4087 if (*input_line_pointer != ',')
4088 {
4089 as_bad (_("Expected comma after name"));
4090 ignore_rest_of_line ();
4091 return;
4092 }
4093 if (*input_line_pointer == '\n')
4094 {
4095 as_bad (_("Missing size expression"));
4096 return;
4097 }
4098 input_line_pointer++;
4099 if ((temp = get_absolute_expression ()) < 0)
4100 {
4101 as_warn (_("lcomm length (%d.) <0! Ignored."), temp);
4102 ignore_rest_of_line ();
4103 return;
4104 }
4105 *p = 0;
4106
708b82c7 4107 symbolP = symbol_find_or_make (name);
252b5132 4108
708b82c7
NC
4109 if (S_GET_SEGMENT (symbolP) == SEG_UNKNOWN &&
4110 S_GET_VALUE (symbolP) == 0)
252b5132
RH
4111 {
4112 if (! need_pass_2)
4113 {
4114 char *p;
4115 segT current_seg = now_seg; /* save current seg */
4116 subsegT current_subseg = now_subseg;
4117
4118 subseg_set (SEG_E2, 1);
4119 symbolP->sy_frag = frag_now;
4120 p = frag_var(rs_org, 1, 1, (relax_substateT)0, symbolP,
4121 (offsetT) temp, (char *) 0);
4122 *p = 0;
4123 subseg_set (current_seg, current_subseg); /* restore current seg */
708b82c7
NC
4124 S_SET_SEGMENT (symbolP, SEG_E2);
4125 S_SET_STORAGE_CLASS (symbolP, C_STAT);
252b5132
RH
4126 }
4127 }
4128 else
708b82c7 4129 as_bad (_("Symbol %s already defined"), name);
252b5132 4130
708b82c7 4131 demand_empty_rest_of_line ();
252b5132
RH
4132#endif
4133}
4134
4135static void
4136fixup_mdeps (frags, h, this_segment)
4137 fragS * frags;
4138 object_headers * h;
4139 segT this_segment;
4140{
4141 subseg_change (this_segment, 0);
4142 while (frags)
4143 {
4144 switch (frags->fr_type)
4145 {
4146 case rs_align:
4147 case rs_align_code:
0a9ef439 4148 case rs_align_test:
252b5132
RH
4149 case rs_org:
4150#ifdef HANDLE_ALIGN
4151 HANDLE_ALIGN (frags);
4152#endif
4153 frags->fr_type = rs_fill;
4154 frags->fr_offset =
4155 ((frags->fr_next->fr_address - frags->fr_address - frags->fr_fix)
4156 / frags->fr_var);
4157 break;
4158 case rs_machine_dependent:
4159 md_convert_frag (h, this_segment, frags);
4160 frag_wane (frags);
4161 break;
4162 default:
4163 ;
4164 }
4165 frags = frags->fr_next;
4166 }
4167}
4168
4169#if 1
4170
4171#ifndef TC_FORCE_RELOCATION
4172#define TC_FORCE_RELOCATION(fix) 0
4173#endif
4174
4175static void
4176fixup_segment (segP, this_segment_type)
4177 segment_info_type * segP;
4178 segT this_segment_type;
4179{
4180 register fixS * fixP;
4181 register symbolS *add_symbolP;
4182 register symbolS *sub_symbolP;
4183 long add_number;
4184 register int size;
4185 register char *place;
4186 register long where;
4187 register char pcrel;
4188 register fragS *fragP;
4189 register segT add_symbol_segment = absolute_section;
4190
4191 for (fixP = segP->fix_root; fixP; fixP = fixP->fx_next)
4192 {
4193 fragP = fixP->fx_frag;
4194 know (fragP);
4195 where = fixP->fx_where;
4196 place = fragP->fr_literal + where;
4197 size = fixP->fx_size;
4198 add_symbolP = fixP->fx_addsy;
4199 sub_symbolP = fixP->fx_subsy;
4200 add_number = fixP->fx_offset;
4201 pcrel = fixP->fx_pcrel;
4202
4203 /* We want function-relative stabs to work on systems which
4204 may use a relaxing linker; thus we must handle the sym1-sym2
4205 fixups function-relative stabs generates.
4206
4207 Of course, if you actually enable relaxing in the linker, the
4208 line and block scoping information is going to be incorrect
4209 in some cases. The only way to really fix this is to support
4210 a reloc involving the difference of two symbols. */
4211 if (linkrelax
4212 && (!sub_symbolP || pcrel))
4213 continue;
4214
4215#ifdef TC_I960
4216 if (fixP->fx_tcbit && SF_GET_CALLNAME (add_symbolP))
4217 {
4218 /* Relocation should be done via the associated 'bal' entry
dcd619be 4219 point symbol. */
252b5132
RH
4220
4221 if (!SF_GET_BALNAME (tc_get_bal_of_call (add_symbolP)))
4222 {
4223 as_bad_where (fixP->fx_file, fixP->fx_line,
4224 _("No 'bal' entry point for leafproc %s"),
4225 S_GET_NAME (add_symbolP));
4226 continue;
4227 }
4228 fixP->fx_addsy = add_symbolP = tc_get_bal_of_call (add_symbolP);
4229 }
4230#endif
4231
4232 /* Make sure the symbols have been resolved; this may not have
4233 happened if these are expression symbols. */
4234 if (add_symbolP != NULL && ! add_symbolP->sy_resolved)
6386f3a7 4235 resolve_symbol_value (add_symbolP);
252b5132
RH
4236
4237 if (add_symbolP != NULL)
4238 {
4239 /* If this fixup is against a symbol which has been equated
4240 to another symbol, convert it to the other symbol. */
4241 if (add_symbolP->sy_value.X_op == O_symbol
4242 && (! S_IS_DEFINED (add_symbolP)
4243 || S_IS_COMMON (add_symbolP)))
4244 {
4245 while (add_symbolP->sy_value.X_op == O_symbol
4246 && (! S_IS_DEFINED (add_symbolP)
4247 || S_IS_COMMON (add_symbolP)))
4248 {
4249 symbolS *n;
4250
4251 /* We must avoid looping, as that can occur with a
4252 badly written program. */
4253 n = add_symbolP->sy_value.X_add_symbol;
4254 if (n == add_symbolP)
4255 break;
4256 add_number += add_symbolP->sy_value.X_add_number;
4257 add_symbolP = n;
4258 }
4259 fixP->fx_addsy = add_symbolP;
4260 fixP->fx_offset = add_number;
4261 }
4262 }
4263
4264 if (sub_symbolP != NULL && ! sub_symbolP->sy_resolved)
6386f3a7 4265 resolve_symbol_value (sub_symbolP);
252b5132
RH
4266
4267 if (add_symbolP != NULL
4268 && add_symbolP->sy_mri_common)
4269 {
4270 know (add_symbolP->sy_value.X_op == O_symbol);
4271 add_number += S_GET_VALUE (add_symbolP);
4272 fixP->fx_offset = add_number;
4273 add_symbolP = fixP->fx_addsy = add_symbolP->sy_value.X_add_symbol;
4274 }
4275
4276 if (add_symbolP)
4277 {
4278 add_symbol_segment = S_GET_SEGMENT (add_symbolP);
4279 } /* if there is an addend */
4280
4281 if (sub_symbolP)
4282 {
4283 if (add_symbolP == NULL || add_symbol_segment == absolute_section)
4284 {
4285 if (add_symbolP != NULL)
4286 {
4287 add_number += S_GET_VALUE (add_symbolP);
4288 add_symbolP = NULL;
4289 fixP->fx_addsy = NULL;
4290 }
4291
4292 /* It's just -sym. */
4293 if (S_GET_SEGMENT (sub_symbolP) == absolute_section)
4294 {
4295 add_number -= S_GET_VALUE (sub_symbolP);
4296 fixP->fx_subsy = 0;
4297 fixP->fx_done = 1;
4298 }
4299 else
4300 {
4301#ifndef TC_M68K
4302 as_bad_where (fixP->fx_file, fixP->fx_line,
4303 _("Negative of non-absolute symbol %s"),
4304 S_GET_NAME (sub_symbolP));
4305#endif
4306 add_number -= S_GET_VALUE (sub_symbolP);
4307 } /* not absolute */
4308
4309 /* if sub_symbol is in the same segment that add_symbol
4310 and add_symbol is either in DATA, TEXT, BSS or ABSOLUTE */
4311 }
4312 else if (S_GET_SEGMENT (sub_symbolP) == add_symbol_segment
4313 && SEG_NORMAL (add_symbol_segment))
4314 {
4315 /* Difference of 2 symbols from same segment. Can't
4316 make difference of 2 undefineds: 'value' means
dcd619be 4317 something different for N_UNDF. */
252b5132
RH
4318#ifdef TC_I960
4319 /* Makes no sense to use the difference of 2 arbitrary symbols
4320 as the target of a call instruction. */
4321 if (fixP->fx_tcbit)
4322 {
4323 as_bad_where (fixP->fx_file, fixP->fx_line,
4324 _("callj to difference of 2 symbols"));
4325 }
4326#endif /* TC_I960 */
4327 add_number += S_GET_VALUE (add_symbolP) -
4328 S_GET_VALUE (sub_symbolP);
4329 add_symbolP = NULL;
4330
4331 if (!TC_FORCE_RELOCATION (fixP))
4332 {
4333 fixP->fx_addsy = NULL;
4334 fixP->fx_subsy = NULL;
4335 fixP->fx_done = 1;
4336#ifdef TC_M68K /* is this right? */
4337 pcrel = 0;
4338 fixP->fx_pcrel = 0;
4339#endif
4340 }
4341 }
4342 else
4343 {
dcd619be 4344 /* Different segments in subtraction. */
252b5132
RH
4345 know (!(S_IS_EXTERNAL (sub_symbolP) && (S_GET_SEGMENT (sub_symbolP) == absolute_section)));
4346
4347 if ((S_GET_SEGMENT (sub_symbolP) == absolute_section))
4348 {
4349 add_number -= S_GET_VALUE (sub_symbolP);
4350 }
4351#ifdef DIFF_EXPR_OK
4352 else if (S_GET_SEGMENT (sub_symbolP) == this_segment_type
dcd619be 4353#if 0 /* Okay for 68k, at least... */
252b5132
RH
4354 && !pcrel
4355#endif
4356 )
4357 {
4358 /* Make it pc-relative. */
4359 add_number += (md_pcrel_from (fixP)
4360 - S_GET_VALUE (sub_symbolP));
4361 pcrel = 1;
4362 fixP->fx_pcrel = 1;
4363 sub_symbolP = 0;
4364 fixP->fx_subsy = 0;
4365 }
4366#endif
4367 else
4368 {
4369 as_bad_where (fixP->fx_file, fixP->fx_line,
4370 _("Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %ld."),
4371 segment_name (S_GET_SEGMENT (sub_symbolP)),
4372 S_GET_NAME (sub_symbolP),
4373 (long) (fragP->fr_address + where));
4374 } /* if absolute */
4375 }
4376 } /* if sub_symbolP */
4377
4378 if (add_symbolP)
4379 {
4380 if (add_symbol_segment == this_segment_type && pcrel)
4381 {
4382 /*
4383 * This fixup was made when the symbol's segment was
4384 * SEG_UNKNOWN, but it is now in the local segment.
4385 * So we know how to do the address without relocation.
4386 */
4387#ifdef TC_I960
4388 /* reloc_callj() may replace a 'call' with a 'calls' or a 'bal',
4389 * in which cases it modifies *fixP as appropriate. In the case
4390 * of a 'calls', no further work is required, and *fixP has been
4391 * set up to make the rest of the code below a no-op.
4392 */
4393 reloc_callj (fixP);
4394#endif /* TC_I960 */
4395
4396 add_number += S_GET_VALUE (add_symbolP);
4397 add_number -= md_pcrel_from (fixP);
4398
4399 /* We used to do
4400 add_number -= segP->scnhdr.s_vaddr;
4401 if defined (TC_I386) || defined (TE_LYNX). I now
4402 think that was an error propagated from the case when
4403 we are going to emit the relocation. If we are not
4404 going to emit the relocation, then we just want to
4405 set add_number to the difference between the symbols.
4406 This is a case that would only arise when there is a
4407 PC relative reference from a section other than .text
4408 to a symbol defined in the same section, and the
4409 reference is not relaxed. Since jump instructions on
4410 the i386 are relaxed, this could only arise with a
4411 call instruction. */
4412
dcd619be 4413 pcrel = 0; /* Lie. Don't want further pcrel processing. */
252b5132
RH
4414 if (!TC_FORCE_RELOCATION (fixP))
4415 {
4416 fixP->fx_addsy = NULL;
4417 fixP->fx_done = 1;
4418 }
4419 }
4420 else
4421 {
4422 switch (add_symbol_segment)
4423 {
4424 case absolute_section:
4425#ifdef TC_I960
4426 reloc_callj (fixP); /* See comment about reloc_callj() above*/
4427#endif /* TC_I960 */
4428 add_number += S_GET_VALUE (add_symbolP);
4429 add_symbolP = NULL;
4430
4431 if (!TC_FORCE_RELOCATION (fixP))
4432 {
4433 fixP->fx_addsy = NULL;
4434 fixP->fx_done = 1;
4435 }
4436 break;
4437 default:
4438
3b16e843 4439#if defined(TC_A29K) || (defined(TE_PE) && defined(TC_I386)) || defined(TC_M88K) || defined(TC_OR32)
252b5132
RH
4440 /* This really should be handled in the linker, but
4441 backward compatibility forbids. */
4442 add_number += S_GET_VALUE (add_symbolP);
4443#else
4444 add_number += S_GET_VALUE (add_symbolP) +
4445 segment_info[S_GET_SEGMENT (add_symbolP)].scnhdr.s_paddr;
4446#endif
4447 break;
4448
4449 case SEG_UNKNOWN:
4450#ifdef TC_I960
4451 if ((int) fixP->fx_bit_fixP == 13)
4452 {
4453 /* This is a COBR instruction. They have only a
4454 * 13-bit displacement and are only to be used
4455 * for local branches: flag as error, don't generate
4456 * relocation.
4457 */
4458 as_bad_where (fixP->fx_file, fixP->fx_line,
4459 _("can't use COBR format with external label"));
4460 fixP->fx_addsy = NULL;
4461 fixP->fx_done = 1;
4462 continue;
4463 } /* COBR */
4464#endif /* TC_I960 */
4465#if ((defined (TC_I386) || defined (TE_LYNX) || defined (TE_AUX)) && !defined(TE_PE)) || defined (COFF_COMMON_ADDEND)
4466 /* 386 COFF uses a peculiar format in which the
4467 value of a common symbol is stored in the .text
4468 segment (I've checked this on SVR3.2 and SCO
4469 3.2.2) Ian Taylor <ian@cygnus.com>. */
4470 /* This is also true for 68k COFF on sysv machines
4471 (Checked on Motorola sysv68 R3V6 and R3V7.1, and also on
4472 UNIX System V/M68000, Release 1.0 from ATT/Bell Labs)
dcd619be 4473 Philippe De Muyter <phdm@info.ucl.ac.be>. */
252b5132
RH
4474 if (S_IS_COMMON (add_symbolP))
4475 add_number += S_GET_VALUE (add_symbolP);
4476#endif
4477 break;
4478
252b5132
RH
4479 } /* switch on symbol seg */
4480 } /* if not in local seg */
4481 } /* if there was a + symbol */
4482
4483 if (pcrel)
4484 {
3b16e843 4485#if !defined(TC_M88K) && !(defined(TE_PE) && defined(TC_I386)) && !defined(TC_A29K) && !defined(TC_OR32)
252b5132
RH
4486 /* This adjustment is not correct on the m88k, for which the
4487 linker does all the computation. */
4488 add_number -= md_pcrel_from (fixP);
4489#endif
4490 if (add_symbolP == 0)
4491 {
4492 fixP->fx_addsy = &abs_symbol;
4493 } /* if there's an add_symbol */
4494#if defined (TC_I386) || defined (TE_LYNX) || defined (TC_I960) || defined (TC_M68K)
4495 /* On the 386 we must adjust by the segment vaddr as well.
4496 Ian Taylor.
4497
4498 I changed the i960 to work this way as well. This is
4499 compatible with the current GNU linker behaviour. I do
4500 not know what other i960 COFF assemblers do. This is not
4501 a common case: normally, only assembler code will contain
4502 a PC relative reloc, and only branches which do not
4503 originate in the .text section will have a non-zero
4504 address.
4505
4506 I changed the m68k to work this way as well. This will
4507 break existing PC relative relocs from sections which do
4508 not start at address 0, but it will make ld -r work.
4509 Ian Taylor, 4 Oct 96. */
4510
4511 add_number -= segP->scnhdr.s_vaddr;
4512#endif
4513 } /* if pcrel */
4514
94f592af 4515 md_apply_fix3 (fixP, (valueT *) & add_number, this_segment_type);
ec0f0840 4516
252b5132
RH
4517 if (!fixP->fx_bit_fixP && ! fixP->fx_no_overflow)
4518 {
4519#ifndef TC_M88K
4520 /* The m88k uses the offset field of the reloc to get around
4521 this problem. */
4522 if ((size == 1
4523 && ((add_number & ~0xFF)
4524 || (fixP->fx_signed && (add_number & 0x80)))
4525 && ((add_number & ~0xFF) != (-1 & ~0xFF)
4526 || (add_number & 0x80) == 0))
4527 || (size == 2
4528 && ((add_number & ~0xFFFF)
4529 || (fixP->fx_signed && (add_number & 0x8000)))
4530 && ((add_number & ~0xFFFF) != (-1 & ~0xFFFF)
4531 || (add_number & 0x8000) == 0)))
4532 {
4533 as_bad_where (fixP->fx_file, fixP->fx_line,
4534 _("Value of %ld too large for field of %d bytes at 0x%lx"),
4535 (long) add_number, size,
4536 (unsigned long) (fragP->fr_address + where));
4537 }
4538#endif
4539#ifdef WARN_SIGNED_OVERFLOW_WORD
4540 /* Warn if a .word value is too large when treated as a
4541 signed number. We already know it is not too negative.
4542 This is to catch over-large switches generated by gcc on
4543 the 68k. */
4544 if (!flag_signed_overflow_ok
4545 && size == 2
4546 && add_number > 0x7fff)
4547 as_bad_where (fixP->fx_file, fixP->fx_line,
4548 _("Signed .word overflow; switch may be too large; %ld at 0x%lx"),
4549 (long) add_number,
4550 (unsigned long) (fragP->fr_address + where));
4551#endif
4552 } /* not a bit fix */
dcd619be 4553 } /* For each fixS in this segment. */
252b5132
RH
4554} /* fixup_segment() */
4555
4556#endif
4557
4558/* The first entry in a .stab section is special. */
4559
4560void
4561obj_coff_init_stab_section (seg)
4562 segT seg;
4563{
4564 char *file;
4565 char *p;
4566 char *stabstr_name;
4567 unsigned int stroff;
4568
dcd619be 4569 /* Make space for this first symbol. */
252b5132 4570 p = frag_more (12);
dcd619be 4571 /* Zero it out. */
252b5132
RH
4572 memset (p, 0, 12);
4573 as_where (&file, (unsigned int *) NULL);
4574 stabstr_name = (char *) alloca (strlen (segment_info[seg].name) + 4);
4575 strcpy (stabstr_name, segment_info[seg].name);
4576 strcat (stabstr_name, "str");
4577 stroff = get_stab_string_offset (file, stabstr_name);
4578 know (stroff == 1);
4579 md_number_to_chars (p, stroff, 4);
4580}
4581
4582/* Fill in the counts in the first entry in a .stab section. */
4583
4584static void
4585adjust_stab_section(abfd, seg)
4586 bfd *abfd;
4587 segT seg;
4588{
4589 segT stabstrseg = SEG_UNKNOWN;
4590 const char *secname, *name2;
4591 char *name;
4592 char *p = NULL;
4593 int i, strsz = 0, nsyms;
4594 fragS *frag = segment_info[seg].frchainP->frch_root;
4595
dcd619be 4596 /* Look for the associated string table section. */
252b5132
RH
4597
4598 secname = segment_info[seg].name;
4599 name = (char *) alloca (strlen (secname) + 4);
4600 strcpy (name, secname);
4601 strcat (name, "str");
4602
4603 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
4604 {
4605 name2 = segment_info[i].name;
4606 if (name2 != NULL && strncmp(name2, name, 8) == 0)
4607 {
4608 stabstrseg = i;
4609 break;
4610 }
4611 }
4612
dcd619be 4613 /* If we found the section, get its size. */
252b5132
RH
4614 if (stabstrseg != SEG_UNKNOWN)
4615 strsz = size_section (abfd, stabstrseg);
4616
4617 nsyms = size_section (abfd, seg) / 12 - 1;
4618
4619 /* Look for the first frag of sufficient size for the initial stab
dcd619be 4620 symbol, and collect a pointer to it. */
252b5132
RH
4621 while (frag && frag->fr_fix < 12)
4622 frag = frag->fr_next;
4623 assert (frag != 0);
4624 p = frag->fr_literal;
4625 assert (p != 0);
4626
4627 /* Write in the number of stab symbols and the size of the string
dcd619be 4628 table. */
252b5132
RH
4629 bfd_h_put_16 (abfd, (bfd_vma) nsyms, (bfd_byte *) p + 6);
4630 bfd_h_put_32 (abfd, (bfd_vma) strsz, (bfd_byte *) p + 8);
4631}
4632
4633#endif /* not BFD_ASSEMBLER */
4634
4c63da97 4635const pseudo_typeS coff_pseudo_table[] =
252b5132
RH
4636{
4637 {"def", obj_coff_def, 0},
4638 {"dim", obj_coff_dim, 0},
4639 {"endef", obj_coff_endef, 0},
4640 {"line", obj_coff_line, 0},
4641 {"ln", obj_coff_ln, 0},
28428223
ILT
4642#ifdef BFD_ASSEMBLER
4643 {"loc", obj_coff_loc, 0},
4644#endif
252b5132
RH
4645 {"appline", obj_coff_ln, 1},
4646 {"scl", obj_coff_scl, 0},
4647 {"size", obj_coff_size, 0},
4648 {"tag", obj_coff_tag, 0},
4649 {"type", obj_coff_type, 0},
4650 {"val", obj_coff_val, 0},
4651 {"section", obj_coff_section, 0},
4652 {"sect", obj_coff_section, 0},
4653 /* FIXME: We ignore the MRI short attribute. */
4654 {"section.s", obj_coff_section, 0},
4655 {"sect.s", obj_coff_section, 0},
4656 /* We accept the .bss directive for backward compatibility with
4657 earlier versions of gas. */
4658 {"bss", obj_coff_bss, 0},
4659 {"weak", obj_coff_weak, 0},
7a6284c4 4660 {"ident", obj_coff_ident, 0},
252b5132
RH
4661#ifndef BFD_ASSEMBLER
4662 {"use", obj_coff_section, 0},
4663 {"text", obj_coff_text, 0},
4664 {"data", obj_coff_data, 0},
4665 {"lcomm", obj_coff_lcomm, 0},
252b5132
RH
4666#else
4667 {"optim", s_ignore, 0}, /* For sun386i cc (?) */
252b5132
RH
4668#endif
4669 {"version", s_ignore, 0},
4670 {"ABORT", s_abort, 0},
4671#ifdef TC_M88K
4672 /* The m88k uses sdef instead of def. */
4673 {"sdef", obj_coff_def, 0},
4674#endif
a04b544b 4675 {NULL, NULL, 0} /* end sentinel */
4c63da97 4676}; /* coff_pseudo_table */
252b5132
RH
4677\f
4678#ifdef BFD_ASSEMBLER
4679
4680/* Support for a COFF emulation. */
4681
4c63da97 4682static void coff_pop_insert PARAMS ((void));
5110c57e 4683static int coff_separate_stab_sections PARAMS ((void));
4c63da97 4684
252b5132
RH
4685static void
4686coff_pop_insert ()
4687{
4c63da97 4688 pop_insert (coff_pseudo_table);
252b5132
RH
4689}
4690
5110c57e
HPN
4691static int
4692coff_separate_stab_sections ()
4693{
4694 return 1;
4695}
4696
252b5132
RH
4697const struct format_ops coff_format_ops =
4698{
4699 bfd_target_coff_flavour,
4c63da97
AM
4700 0, /* dfl_leading_underscore */
4701 1, /* emit_section_symbols */
5110c57e
HPN
4702 0, /* begin */
4703 c_dot_file_symbol,
252b5132 4704 coff_frob_symbol,
4c63da97 4705 0, /* frob_file */
339681c0 4706 0, /* frob_file_before_adjust */
252b5132 4707 coff_frob_file_after_relocs,
4c63da97
AM
4708 0, /* s_get_size */
4709 0, /* s_set_size */
4710 0, /* s_get_align */
4711 0, /* s_set_align */
4712 0, /* s_get_other */
5110c57e 4713 0, /* s_set_other */
4c63da97 4714 0, /* s_get_desc */
5110c57e
HPN
4715 0, /* s_set_desc */
4716 0, /* s_get_type */
4717 0, /* s_set_type */
4c63da97
AM
4718 0, /* copy_symbol_attributes */
4719 0, /* generate_asm_lineno */
4720 0, /* process_stab */
5110c57e
HPN
4721 coff_separate_stab_sections,
4722 obj_coff_init_stab_section,
4c63da97 4723 0, /* sec_sym_ok_for_reloc */
252b5132 4724 coff_pop_insert,
4c63da97 4725 0, /* ecoff_set_ext */
252b5132 4726 coff_obj_read_begin_hook,
4c63da97 4727 coff_obj_symbol_new_hook
252b5132
RH
4728};
4729
4730#endif
This page took 0.335793 seconds and 4 git commands to generate.