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