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