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