OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [binutils-2.18.50/] [gas/] [config/] [obj-coff.c] - Blame information for rev 866

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 38 julius
/* coff object file format
2
   Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3
   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007
4
   Free Software Foundation, Inc.
5
 
6
   This file is part of GAS.
7
 
8
   GAS is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 3, or (at your option)
11
   any later version.
12
 
13
   GAS is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
 
18
   You should have received a copy of the GNU General Public License
19
   along with GAS; see the file COPYING.  If not, write to the Free
20
   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
21
   02110-1301, USA.  */
22
 
23
#define OBJ_HEADER "obj-coff.h"
24
 
25
#include "as.h"
26
#include "obstack.h"
27
#include "subsegs.h"
28
 
29
#ifdef TE_PE
30
#include "coff/pe.h"
31
#endif
32
 
33
#define streq(a,b)     (strcmp ((a), (b)) == 0)
34
#define strneq(a,b,n)  (strncmp ((a), (b), (n)) == 0)
35
 
36
/* I think this is probably always correct.  */
37
#ifndef KEEP_RELOC_INFO
38
#define KEEP_RELOC_INFO
39
#endif
40
 
41
/* obj_coff_section will use this macro to set a new section's
42
   attributes when a directive has no valid flags or the "w" flag is
43
   used.  This default should be appropriate for most.  */
44
#ifndef TC_COFF_SECTION_DEFAULT_ATTRIBUTES
45
#define TC_COFF_SECTION_DEFAULT_ATTRIBUTES (SEC_LOAD | SEC_DATA)
46
#endif
47
 
48
/* This is used to hold the symbol built by a sequence of pseudo-ops
49
   from .def and .endef.  */
50
static symbolS *def_symbol_in_progress;
51
#ifdef TE_PE
52
/* PE weak alternate symbols begin with this string.  */
53
static const char weak_altprefix[] = ".weak.";
54
#endif /* TE_PE */
55
 
56
typedef struct
57
  {
58
    unsigned long chunk_size;
59
    unsigned long element_size;
60
    unsigned long size;
61
    char *data;
62
    unsigned long pointer;
63
  }
64
stack;
65
 
66
 
67
/* Stack stuff.  */
68
 
69
static stack *
70
stack_init (unsigned long chunk_size,
71
            unsigned long element_size)
72
{
73
  stack *st;
74
 
75
  st = malloc (sizeof (* st));
76
  if (!st)
77
    return NULL;
78
  st->data = malloc (chunk_size);
79
  if (!st->data)
80
    {
81
      free (st);
82
      return NULL;
83
    }
84
  st->pointer = 0;
85
  st->size = chunk_size;
86
  st->chunk_size = chunk_size;
87
  st->element_size = element_size;
88
  return st;
89
}
90
 
91
static char *
92
stack_push (stack *st, char *element)
93
{
94
  if (st->pointer + st->element_size >= st->size)
95
    {
96
      st->size += st->chunk_size;
97
      if ((st->data = xrealloc (st->data, st->size)) == NULL)
98
        return NULL;
99
    }
100
  memcpy (st->data + st->pointer, element, st->element_size);
101
  st->pointer += st->element_size;
102
  return st->data + st->pointer;
103
}
104
 
105
static char *
106
stack_pop (stack *st)
107
{
108
  if (st->pointer < st->element_size)
109
    {
110
      st->pointer = 0;
111
      return NULL;
112
    }
113
  st->pointer -= st->element_size;
114
  return st->data + st->pointer;
115
}
116
 
117
/* Maintain a list of the tagnames of the structures.  */
118
 
119
static struct hash_control *tag_hash;
120
 
121
static void
122
tag_init (void)
123
{
124
  tag_hash = hash_new ();
125
}
126
 
127
static void
128
tag_insert (const char *name, symbolS *symbolP)
129
{
130
  const char *error_string;
131
 
132
  if ((error_string = hash_jam (tag_hash, name, (char *) symbolP)))
133
    as_fatal (_("Inserting \"%s\" into structure table failed: %s"),
134
              name, error_string);
135
}
136
 
137
static symbolS *
138
tag_find (char *name)
139
{
140
  return (symbolS *) hash_find (tag_hash, name);
141
}
142
 
143
static symbolS *
144
tag_find_or_make (char *name)
145
{
146
  symbolS *symbolP;
147
 
148
  if ((symbolP = tag_find (name)) == NULL)
149
    {
150
      symbolP = symbol_new (name, undefined_section,
151
                            0, &zero_address_frag);
152
 
153
      tag_insert (S_GET_NAME (symbolP), symbolP);
154
      symbol_table_insert (symbolP);
155
    }
156
 
157
  return symbolP;
158
}
159
 
160
/* We accept the .bss directive to set the section for backward
161
   compatibility with earlier versions of gas.  */
162
 
163
static void
164
obj_coff_bss (int ignore ATTRIBUTE_UNUSED)
165
{
166
  if (*input_line_pointer == '\n')
167
    subseg_new (".bss", get_absolute_expression ());
168
  else
169
    s_lcomm (0);
170
}
171
 
172
#define GET_FILENAME_STRING(X) \
173
  ((char *) (&((X)->sy_symbol.ost_auxent->x_file.x_n.x_offset))[1])
174
 
175
/* @@ Ick.  */
176
static segT
177
fetch_coff_debug_section (void)
178
{
179
  static segT debug_section;
180
 
181
  if (!debug_section)
182
    {
183
      const asymbol *s;
184
 
185
      s = bfd_make_debug_symbol (stdoutput, NULL, 0);
186
      assert (s != 0);
187
      debug_section = s->section;
188
    }
189
  return debug_section;
190
}
191
 
192
void
193
SA_SET_SYM_ENDNDX (symbolS *sym, symbolS *val)
194
{
195
  combined_entry_type *entry, *p;
196
 
197
  entry = &coffsymbol (symbol_get_bfdsym (sym))->native[1];
198
  p = coffsymbol (symbol_get_bfdsym (val))->native;
199
  entry->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p = p;
200
  entry->fix_end = 1;
201
}
202
 
203
static void
204
SA_SET_SYM_TAGNDX (symbolS *sym, symbolS *val)
205
{
206
  combined_entry_type *entry, *p;
207
 
208
  entry = &coffsymbol (symbol_get_bfdsym (sym))->native[1];
209
  p = coffsymbol (symbol_get_bfdsym (val))->native;
210
  entry->u.auxent.x_sym.x_tagndx.p = p;
211
  entry->fix_tag = 1;
212
}
213
 
214
static int
215
S_GET_DATA_TYPE (symbolS *sym)
216
{
217
  return coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_type;
218
}
219
 
220
int
221
S_SET_DATA_TYPE (symbolS *sym, int val)
222
{
223
  coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_type = val;
224
  return val;
225
}
226
 
227
int
228
S_GET_STORAGE_CLASS (symbolS *sym)
229
{
230
  return coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_sclass;
231
}
232
 
233
int
234
S_SET_STORAGE_CLASS (symbolS *sym, int val)
235
{
236
  coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_sclass = val;
237
  return val;
238
}
239
 
240
/* Merge a debug symbol containing debug information into a normal symbol.  */
241
 
242
static void
243
c_symbol_merge (symbolS *debug, symbolS *normal)
244
{
245
  S_SET_DATA_TYPE (normal, S_GET_DATA_TYPE (debug));
246
  S_SET_STORAGE_CLASS (normal, S_GET_STORAGE_CLASS (debug));
247
 
248
  if (S_GET_NUMBER_AUXILIARY (debug) > S_GET_NUMBER_AUXILIARY (normal))
249
    /* Take the most we have.  */
250
    S_SET_NUMBER_AUXILIARY (normal, S_GET_NUMBER_AUXILIARY (debug));
251
 
252
  if (S_GET_NUMBER_AUXILIARY (debug) > 0)
253
    /* Move all the auxiliary information.  */
254
    memcpy (SYM_AUXINFO (normal), SYM_AUXINFO (debug),
255
            (S_GET_NUMBER_AUXILIARY (debug)
256
             * sizeof (*SYM_AUXINFO (debug))));
257
 
258
  /* Move the debug flags.  */
259
  SF_SET_DEBUG_FIELD (normal, SF_GET_DEBUG_FIELD (debug));
260
}
261
 
262
void
263
c_dot_file_symbol (const char *filename, int appfile ATTRIBUTE_UNUSED)
264
{
265
  symbolS *symbolP;
266
 
267
  /* BFD converts filename to a .file symbol with an aux entry.  It
268
     also handles chaining.  */
269
  symbolP = symbol_new (filename, bfd_abs_section_ptr, 0, &zero_address_frag);
270
 
271
  S_SET_STORAGE_CLASS (symbolP, C_FILE);
272
  S_SET_NUMBER_AUXILIARY (symbolP, 1);
273
 
274
  symbol_get_bfdsym (symbolP)->flags = BSF_DEBUGGING;
275
 
276
#ifndef NO_LISTING
277
  {
278
    extern int listing;
279
 
280
    if (listing)
281
      listing_source_file (filename);
282
  }
283
#endif
284
 
285
  /* Make sure that the symbol is first on the symbol chain.  */
286
  if (symbol_rootP != symbolP)
287
    {
288
      symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
289
      symbol_insert (symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP);
290
    }
291
}
292
 
293
/* Line number handling.  */
294
 
295
struct line_no
296
{
297
  struct line_no *next;
298
  fragS *frag;
299
  alent l;
300
};
301
 
302
int coff_line_base;
303
 
304
/* Symbol of last function, which we should hang line#s off of.  */
305
static symbolS *line_fsym;
306
 
307
#define in_function()           (line_fsym != 0)
308
#define clear_function()        (line_fsym = 0)
309
#define set_function(F)         (line_fsym = (F), coff_add_linesym (F))
310
 
311
 
312
void
313
coff_obj_symbol_new_hook (symbolS *symbolP)
314
{
315
  long   sz = (OBJ_COFF_MAX_AUXENTRIES + 1) * sizeof (combined_entry_type);
316
  char * s  = xmalloc (sz);
317
 
318
  memset (s, 0, sz);
319
  coffsymbol (symbol_get_bfdsym (symbolP))->native = (combined_entry_type *) s;
320
 
321
  S_SET_DATA_TYPE (symbolP, T_NULL);
322
  S_SET_STORAGE_CLASS (symbolP, 0);
323
  S_SET_NUMBER_AUXILIARY (symbolP, 0);
324
 
325
  if (S_IS_STRING (symbolP))
326
    SF_SET_STRING (symbolP);
327
 
328
  if (S_IS_LOCAL (symbolP))
329
    SF_SET_LOCAL (symbolP);
330
}
331
 
332
void
333
coff_obj_symbol_clone_hook (symbolS *newsymP, symbolS *orgsymP)
334
{
335
  long sz = (OBJ_COFF_MAX_AUXENTRIES + 1) * sizeof (combined_entry_type);
336
  combined_entry_type * s = xmalloc (sz);
337
 
338
  memcpy (s, coffsymbol (symbol_get_bfdsym (orgsymP))->native, sz);
339
  coffsymbol (symbol_get_bfdsym (newsymP))->native = s;
340
 
341
  SF_SET (newsymP, SF_GET (orgsymP));
342
}
343
 
344
 
345
/* Handle .ln directives.  */
346
 
347
static symbolS *current_lineno_sym;
348
static struct line_no *line_nos;
349
/* FIXME:  Blindly assume all .ln directives will be in the .text section.  */
350
int coff_n_line_nos;
351
 
352
static void
353
add_lineno (fragS * frag, addressT offset, int num)
354
{
355
  struct line_no * new_line = xmalloc (sizeof (* new_line));
356
 
357
  if (!current_lineno_sym)
358
    abort ();
359
 
360
#ifndef OBJ_XCOFF
361
  /* The native aix assembler accepts negative line number.  */
362
 
363
  if (num <= 0)
364
    {
365
      /* Zero is used as an end marker in the file.  */
366
      as_warn (_("Line numbers must be positive integers\n"));
367
      num = 1;
368
    }
369
#endif /* OBJ_XCOFF */
370
  new_line->next = line_nos;
371
  new_line->frag = frag;
372
  new_line->l.line_number = num;
373
  new_line->l.u.offset = offset;
374
  line_nos = new_line;
375
  coff_n_line_nos++;
376
}
377
 
378
void
379
coff_add_linesym (symbolS *sym)
380
{
381
  if (line_nos)
382
    {
383
      coffsymbol (symbol_get_bfdsym (current_lineno_sym))->lineno =
384
        (alent *) line_nos;
385
      coff_n_line_nos++;
386
      line_nos = 0;
387
    }
388
  current_lineno_sym = sym;
389
}
390
 
391
static void
392
obj_coff_ln (int appline)
393
{
394
  int l;
395
 
396
  if (! appline && def_symbol_in_progress != NULL)
397
    {
398
      as_warn (_(".ln pseudo-op inside .def/.endef: ignored."));
399
      demand_empty_rest_of_line ();
400
      return;
401
    }
402
 
403
  l = get_absolute_expression ();
404
 
405
  /* If there is no lineno symbol, treat a .ln
406
     directive as if it were a .appline directive.  */
407
  if (appline || current_lineno_sym == NULL)
408
    new_logical_line ((char *) NULL, l - 1);
409
  else
410
    add_lineno (frag_now, frag_now_fix (), l);
411
 
412
#ifndef NO_LISTING
413
  {
414
    extern int listing;
415
 
416
    if (listing)
417
      {
418
        if (! appline)
419
          l += coff_line_base - 1;
420
        listing_source_line (l);
421
      }
422
  }
423
#endif
424
 
425
  demand_empty_rest_of_line ();
426
}
427
 
428
/* .loc is essentially the same as .ln; parse it for assembler
429
   compatibility.  */
430
 
431
static void
432
obj_coff_loc (int ignore ATTRIBUTE_UNUSED)
433
{
434
  int lineno;
435
 
436
  /* FIXME: Why do we need this check?  We need it for ECOFF, but why
437
     do we need it for COFF?  */
438
  if (now_seg != text_section)
439
    {
440
      as_warn (_(".loc outside of .text"));
441
      demand_empty_rest_of_line ();
442
      return;
443
    }
444
 
445
  if (def_symbol_in_progress != NULL)
446
    {
447
      as_warn (_(".loc pseudo-op inside .def/.endef: ignored."));
448
      demand_empty_rest_of_line ();
449
      return;
450
    }
451
 
452
  /* Skip the file number.  */
453
  SKIP_WHITESPACE ();
454
  get_absolute_expression ();
455
  SKIP_WHITESPACE ();
456
 
457
  lineno = get_absolute_expression ();
458
 
459
#ifndef NO_LISTING
460
  {
461
    extern int listing;
462
 
463
    if (listing)
464
      {
465
        lineno += coff_line_base - 1;
466
        listing_source_line (lineno);
467
      }
468
  }
469
#endif
470
 
471
  demand_empty_rest_of_line ();
472
 
473
  add_lineno (frag_now, frag_now_fix (), lineno);
474
}
475
 
476
/* Handle the .ident pseudo-op.  */
477
 
478
static void
479
obj_coff_ident (int ignore ATTRIBUTE_UNUSED)
480
{
481
  segT current_seg = now_seg;
482
  subsegT current_subseg = now_subseg;
483
 
484
#ifdef TE_PE
485
  {
486
    segT sec;
487
 
488
    /* We could put it in .comment, but that creates an extra section
489
       that shouldn't be loaded into memory, which requires linker
490
       changes...  For now, until proven otherwise, use .rdata.  */
491
    sec = subseg_new (".rdata$zzz", 0);
492
    bfd_set_section_flags (stdoutput, sec,
493
                           ((SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA)
494
                            & bfd_applicable_section_flags (stdoutput)));
495
  }
496
#else
497
  subseg_new (".comment", 0);
498
#endif
499
 
500
  stringer (8 + 1);
501
  subseg_set (current_seg, current_subseg);
502
}
503
 
504
/* Handle .def directives.
505
 
506
   One might ask : why can't we symbol_new if the symbol does not
507
   already exist and fill it with debug information.  Because of
508
   the C_EFCN special symbol. It would clobber the value of the
509
   function symbol before we have a chance to notice that it is
510
   a C_EFCN. And a second reason is that the code is more clear this
511
   way. (at least I think it is :-).  */
512
 
513
#define SKIP_SEMI_COLON()       while (*input_line_pointer++ != ';')
514
#define SKIP_WHITESPACES()      while (*input_line_pointer == ' ' || \
515
                                       *input_line_pointer == '\t')  \
516
                                  input_line_pointer++;
517
 
518
static void
519
obj_coff_def (int what ATTRIBUTE_UNUSED)
520
{
521
  char name_end;                /* Char after the end of name.  */
522
  char *symbol_name;            /* Name of the debug symbol.  */
523
  char *symbol_name_copy;       /* Temporary copy of the name.  */
524
  unsigned int symbol_name_length;
525
 
526
  if (def_symbol_in_progress != NULL)
527
    {
528
      as_warn (_(".def pseudo-op used inside of .def/.endef: ignored."));
529
      demand_empty_rest_of_line ();
530
      return;
531
    }
532
 
533
  SKIP_WHITESPACES ();
534
 
535
  symbol_name = input_line_pointer;
536
  name_end = get_symbol_end ();
537
  symbol_name_length = strlen (symbol_name);
538
  symbol_name_copy = xmalloc (symbol_name_length + 1);
539
  strcpy (symbol_name_copy, symbol_name);
540
#ifdef tc_canonicalize_symbol_name
541
  symbol_name_copy = tc_canonicalize_symbol_name (symbol_name_copy);
542
#endif
543
 
544
  /* Initialize the new symbol.  */
545
  def_symbol_in_progress = symbol_make (symbol_name_copy);
546
  symbol_set_frag (def_symbol_in_progress, &zero_address_frag);
547
  S_SET_VALUE (def_symbol_in_progress, 0);
548
 
549
  if (S_IS_STRING (def_symbol_in_progress))
550
    SF_SET_STRING (def_symbol_in_progress);
551
 
552
  *input_line_pointer = name_end;
553
 
554
  demand_empty_rest_of_line ();
555
}
556
 
557
unsigned int dim_index;
558
 
559
static void
560
obj_coff_endef (int ignore ATTRIBUTE_UNUSED)
561
{
562
  symbolS *symbolP = NULL;
563
 
564
  dim_index = 0;
565
  if (def_symbol_in_progress == NULL)
566
    {
567
      as_warn (_(".endef pseudo-op used outside of .def/.endef: ignored."));
568
      demand_empty_rest_of_line ();
569
      return;
570
    }
571
 
572
  /* Set the section number according to storage class.  */
573
  switch (S_GET_STORAGE_CLASS (def_symbol_in_progress))
574
    {
575
    case C_STRTAG:
576
    case C_ENTAG:
577
    case C_UNTAG:
578
      SF_SET_TAG (def_symbol_in_progress);
579
      /* Fall through.  */
580
    case C_FILE:
581
    case C_TPDEF:
582
      SF_SET_DEBUG (def_symbol_in_progress);
583
      S_SET_SEGMENT (def_symbol_in_progress, fetch_coff_debug_section ());
584
      break;
585
 
586
    case C_EFCN:
587
      SF_SET_LOCAL (def_symbol_in_progress);    /* Do not emit this symbol.  */
588
      /* Fall through.  */
589
    case C_BLOCK:
590
      SF_SET_PROCESS (def_symbol_in_progress);  /* Will need processing before writing.  */
591
      /* Fall through.  */
592
    case C_FCN:
593
      {
594
        const char *name;
595
 
596
        S_SET_SEGMENT (def_symbol_in_progress, text_section);
597
 
598
        name = S_GET_NAME (def_symbol_in_progress);
599
        if (name[0] == '.' && name[2] == 'f' && name[3] == '\0')
600
          {
601
            switch (name[1])
602
              {
603
              case 'b':
604
                /* .bf */
605
                if (! in_function ())
606
                  as_warn (_("`%s' symbol without preceding function"), name);
607
                /* Will need relocating.  */
608
                SF_SET_PROCESS (def_symbol_in_progress);
609
                clear_function ();
610
                break;
611
#ifdef TE_PE
612
              case 'e':
613
                /* .ef */
614
                /* The MS compilers output the actual endline, not the
615
                   function-relative one... we want to match without
616
                   changing the assembler input.  */
617
                SA_SET_SYM_LNNO (def_symbol_in_progress,
618
                                 (SA_GET_SYM_LNNO (def_symbol_in_progress)
619
                                  + coff_line_base));
620
                break;
621
#endif
622
              }
623
          }
624
      }
625
      break;
626
 
627
#ifdef C_AUTOARG
628
    case C_AUTOARG:
629
#endif /* C_AUTOARG */
630
    case C_AUTO:
631
    case C_REG:
632
    case C_ARG:
633
    case C_REGPARM:
634
    case C_FIELD:
635
 
636
    /* According to the COFF documentation:
637
 
638
       http://osr5doc.sco.com:1996/topics/COFF_SectNumFld.html
639
 
640
       A special section number (-2) marks symbolic debugging symbols,
641
       including structure/union/enumeration tag names, typedefs, and
642
       the name of the file. A section number of -1 indicates that the
643
       symbol has a value but is not relocatable. Examples of
644
       absolute-valued symbols include automatic and register variables,
645
       function arguments, and .eos symbols.
646
 
647
       But from Ian Lance Taylor:
648
 
649
       http://sources.redhat.com/ml/binutils/2000-08/msg00202.html
650
 
651
       the actual tools all marked them as section -1. So the GNU COFF
652
       assembler follows historical COFF assemblers.
653
 
654
       However, it causes problems for djgpp
655
 
656
       http://sources.redhat.com/ml/binutils/2000-08/msg00210.html
657
 
658
       By defining STRICTCOFF, a COFF port can make the assembler to
659
       follow the documented behavior.  */
660
#ifdef STRICTCOFF
661
    case C_MOS:
662
    case C_MOE:
663
    case C_MOU:
664
    case C_EOS:
665
#endif
666
      SF_SET_DEBUG (def_symbol_in_progress);
667
      S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
668
      break;
669
 
670
#ifndef STRICTCOFF
671
    case C_MOS:
672
    case C_MOE:
673
    case C_MOU:
674
    case C_EOS:
675
      S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
676
      break;
677
#endif
678
 
679
    case C_EXT:
680
    case C_WEAKEXT:
681
#ifdef TE_PE
682
    case C_NT_WEAK:
683
#endif
684
    case C_STAT:
685
    case C_LABEL:
686
      /* Valid but set somewhere else (s_comm, s_lcomm, colon).  */
687
      break;
688
 
689
    default:
690
    case C_USTATIC:
691
    case C_EXTDEF:
692
    case C_ULABEL:
693
      as_warn (_("unexpected storage class %d"),
694
               S_GET_STORAGE_CLASS (def_symbol_in_progress));
695
      break;
696
    }
697
 
698
  /* Now that we have built a debug symbol, try to find if we should
699
     merge with an existing symbol or not.  If a symbol is C_EFCN or
700
     absolute_section or untagged SEG_DEBUG it never merges.  We also
701
     don't merge labels, which are in a different namespace, nor
702
     symbols which have not yet been defined since they are typically
703
     unique, nor do we merge tags with non-tags.  */
704
 
705
  /* Two cases for functions.  Either debug followed by definition or
706
     definition followed by debug.  For definition first, we will
707
     merge the debug symbol into the definition.  For debug first, the
708
     lineno entry MUST point to the definition function or else it
709
     will point off into space when obj_crawl_symbol_chain() merges
710
     the debug symbol into the real symbol.  Therefor, let's presume
711
     the debug symbol is a real function reference.  */
712
 
713
  /* FIXME-SOON If for some reason the definition label/symbol is
714
     never seen, this will probably leave an undefined symbol at link
715
     time.  */
716
 
717
  if (S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_EFCN
718
      || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_LABEL
719
      || (streq (bfd_get_section_name (stdoutput,
720
                                       S_GET_SEGMENT (def_symbol_in_progress)),
721
                 "*DEBUG*")
722
          && !SF_GET_TAG (def_symbol_in_progress))
723
      || S_GET_SEGMENT (def_symbol_in_progress) == absolute_section
724
      || ! symbol_constant_p (def_symbol_in_progress)
725
      || (symbolP = symbol_find (S_GET_NAME (def_symbol_in_progress))) == NULL
726
      || SF_GET_TAG (def_symbol_in_progress) != SF_GET_TAG (symbolP))
727
    {
728
      /* If it already is at the end of the symbol list, do nothing */
729
      if (def_symbol_in_progress != symbol_lastP)
730
        {
731
          symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
732
          symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP,
733
                         &symbol_lastP);
734
        }
735
    }
736
  else
737
    {
738
      /* This symbol already exists, merge the newly created symbol
739
         into the old one.  This is not mandatory. The linker can
740
         handle duplicate symbols correctly. But I guess that it save
741
         a *lot* of space if the assembly file defines a lot of
742
         symbols. [loic]  */
743
 
744
      /* The debug entry (def_symbol_in_progress) is merged into the
745
         previous definition.  */
746
 
747
      c_symbol_merge (def_symbol_in_progress, symbolP);
748
      symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
749
 
750
      def_symbol_in_progress = symbolP;
751
 
752
      if (SF_GET_FUNCTION (def_symbol_in_progress)
753
          || SF_GET_TAG (def_symbol_in_progress)
754
          || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_STAT)
755
        {
756
          /* For functions, and tags, and static symbols, the symbol
757
             *must* be where the debug symbol appears.  Move the
758
             existing symbol to the current place.  */
759
          /* If it already is at the end of the symbol list, do nothing.  */
760
          if (def_symbol_in_progress != symbol_lastP)
761
            {
762
              symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
763
              symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
764
            }
765
        }
766
    }
767
 
768
  if (SF_GET_TAG (def_symbol_in_progress))
769
    {
770
      symbolS *oldtag;
771
 
772
      oldtag = symbol_find (S_GET_NAME (def_symbol_in_progress));
773
      if (oldtag == NULL || ! SF_GET_TAG (oldtag))
774
        tag_insert (S_GET_NAME (def_symbol_in_progress),
775
                    def_symbol_in_progress);
776
    }
777
 
778
  if (SF_GET_FUNCTION (def_symbol_in_progress))
779
    {
780
      set_function (def_symbol_in_progress);
781
      SF_SET_PROCESS (def_symbol_in_progress);
782
 
783
      if (symbolP == NULL)
784
        /* That is, if this is the first time we've seen the
785
           function.  */
786
        symbol_table_insert (def_symbol_in_progress);
787
 
788
    }
789
 
790
  def_symbol_in_progress = NULL;
791
  demand_empty_rest_of_line ();
792
}
793
 
794
static void
795
obj_coff_dim (int ignore ATTRIBUTE_UNUSED)
796
{
797
  int dim_index;
798
 
799
  if (def_symbol_in_progress == NULL)
800
    {
801
      as_warn (_(".dim pseudo-op used outside of .def/.endef: ignored."));
802
      demand_empty_rest_of_line ();
803
      return;
804
    }
805
 
806
  S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
807
 
808
  for (dim_index = 0; dim_index < DIMNUM; dim_index++)
809
    {
810
      SKIP_WHITESPACES ();
811
      SA_SET_SYM_DIMEN (def_symbol_in_progress, dim_index,
812
                        get_absolute_expression ());
813
 
814
      switch (*input_line_pointer)
815
        {
816
        case ',':
817
          input_line_pointer++;
818
          break;
819
 
820
        default:
821
          as_warn (_("badly formed .dim directive ignored"));
822
          /* Fall through.  */
823
        case '\n':
824
        case ';':
825
          dim_index = DIMNUM;
826
          break;
827
        }
828
    }
829
 
830
  demand_empty_rest_of_line ();
831
}
832
 
833
static void
834
obj_coff_line (int ignore ATTRIBUTE_UNUSED)
835
{
836
  int this_base;
837
 
838
  if (def_symbol_in_progress == NULL)
839
    {
840
      /* Probably stabs-style line?  */
841
      obj_coff_ln (0);
842
      return;
843
    }
844
 
845
  this_base = get_absolute_expression ();
846
  if (streq (".bf", S_GET_NAME (def_symbol_in_progress)))
847
    coff_line_base = this_base;
848
 
849
  S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
850
  SA_SET_SYM_LNNO (def_symbol_in_progress, this_base);
851
 
852
  demand_empty_rest_of_line ();
853
 
854
#ifndef NO_LISTING
855
  if (streq (".bf", S_GET_NAME (def_symbol_in_progress)))
856
    {
857
      extern int listing;
858
 
859
      if (listing)
860
        listing_source_line ((unsigned int) this_base);
861
    }
862
#endif
863
}
864
 
865
static void
866
obj_coff_size (int ignore ATTRIBUTE_UNUSED)
867
{
868
  if (def_symbol_in_progress == NULL)
869
    {
870
      as_warn (_(".size pseudo-op used outside of .def/.endef ignored."));
871
      demand_empty_rest_of_line ();
872
      return;
873
    }
874
 
875
  S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
876
  SA_SET_SYM_SIZE (def_symbol_in_progress, get_absolute_expression ());
877
  demand_empty_rest_of_line ();
878
}
879
 
880
static void
881
obj_coff_scl (int ignore ATTRIBUTE_UNUSED)
882
{
883
  if (def_symbol_in_progress == NULL)
884
    {
885
      as_warn (_(".scl pseudo-op used outside of .def/.endef ignored."));
886
      demand_empty_rest_of_line ();
887
      return;
888
    }
889
 
890
  S_SET_STORAGE_CLASS (def_symbol_in_progress, get_absolute_expression ());
891
  demand_empty_rest_of_line ();
892
}
893
 
894
static void
895
obj_coff_tag (int ignore ATTRIBUTE_UNUSED)
896
{
897
  char *symbol_name;
898
  char name_end;
899
 
900
  if (def_symbol_in_progress == NULL)
901
    {
902
      as_warn (_(".tag pseudo-op used outside of .def/.endef ignored."));
903
      demand_empty_rest_of_line ();
904
      return;
905
    }
906
 
907
  S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
908
  symbol_name = input_line_pointer;
909
  name_end = get_symbol_end ();
910
 
911
#ifdef tc_canonicalize_symbol_name
912
  symbol_name = tc_canonicalize_symbol_name (symbol_name);
913
#endif
914
 
915
  /* Assume that the symbol referred to by .tag is always defined.
916
     This was a bad assumption.  I've added find_or_make. xoxorich.  */
917
  SA_SET_SYM_TAGNDX (def_symbol_in_progress,
918
                     tag_find_or_make (symbol_name));
919
  if (SA_GET_SYM_TAGNDX (def_symbol_in_progress) == 0L)
920
    as_warn (_("tag not found for .tag %s"), symbol_name);
921
 
922
  SF_SET_TAGGED (def_symbol_in_progress);
923
  *input_line_pointer = name_end;
924
 
925
  demand_empty_rest_of_line ();
926
}
927
 
928
static void
929
obj_coff_type (int ignore ATTRIBUTE_UNUSED)
930
{
931
  if (def_symbol_in_progress == NULL)
932
    {
933
      as_warn (_(".type pseudo-op used outside of .def/.endef ignored."));
934
      demand_empty_rest_of_line ();
935
      return;
936
    }
937
 
938
  S_SET_DATA_TYPE (def_symbol_in_progress, get_absolute_expression ());
939
 
940
  if (ISFCN (S_GET_DATA_TYPE (def_symbol_in_progress)) &&
941
      S_GET_STORAGE_CLASS (def_symbol_in_progress) != C_TPDEF)
942
    SF_SET_FUNCTION (def_symbol_in_progress);
943
 
944
  demand_empty_rest_of_line ();
945
}
946
 
947
static void
948
obj_coff_val (int ignore ATTRIBUTE_UNUSED)
949
{
950
  if (def_symbol_in_progress == NULL)
951
    {
952
      as_warn (_(".val pseudo-op used outside of .def/.endef ignored."));
953
      demand_empty_rest_of_line ();
954
      return;
955
    }
956
 
957
  if (is_name_beginner (*input_line_pointer))
958
    {
959
      char *symbol_name = input_line_pointer;
960
      char name_end = get_symbol_end ();
961
 
962
#ifdef tc_canonicalize_symbol_name
963
  symbol_name = tc_canonicalize_symbol_name (symbol_name);
964
#endif
965
      if (streq (symbol_name, "."))
966
        {
967
          /* If the .val is != from the .def (e.g. statics).  */
968
          symbol_set_frag (def_symbol_in_progress, frag_now);
969
          S_SET_VALUE (def_symbol_in_progress, (valueT) frag_now_fix ());
970
        }
971
      else if (! streq (S_GET_NAME (def_symbol_in_progress), symbol_name))
972
        {
973
          expressionS exp;
974
 
975
          exp.X_op = O_symbol;
976
          exp.X_add_symbol = symbol_find_or_make (symbol_name);
977
          exp.X_op_symbol = NULL;
978
          exp.X_add_number = 0;
979
          symbol_set_value_expression (def_symbol_in_progress, &exp);
980
 
981
          /* If the segment is undefined when the forward reference is
982
             resolved, then copy the segment id from the forward
983
             symbol.  */
984
          SF_SET_GET_SEGMENT (def_symbol_in_progress);
985
 
986
          /* FIXME: gcc can generate address expressions here in
987
             unusual cases (search for "obscure" in sdbout.c).  We
988
             just ignore the offset here, thus generating incorrect
989
             debugging information.  We ignore the rest of the line
990
             just below.  */
991
        }
992
      /* Otherwise, it is the name of a non debug symbol and its value
993
         will be calculated later.  */
994
      *input_line_pointer = name_end;
995
    }
996
  else
997
    {
998
      S_SET_VALUE (def_symbol_in_progress, get_absolute_expression ());
999
    }
1000
 
1001
  demand_empty_rest_of_line ();
1002
}
1003
 
1004
#ifdef TE_PE
1005
 
1006
/* Return nonzero if name begins with weak alternate symbol prefix.  */
1007
 
1008
static int
1009
weak_is_altname (const char * name)
1010
{
1011
  return strneq (name, weak_altprefix, sizeof (weak_altprefix) - 1);
1012
}
1013
 
1014
/* Return the name of the alternate symbol
1015
   name corresponding to a weak symbol's name.  */
1016
 
1017
static const char *
1018
weak_name2altname (const char * name)
1019
{
1020
  char *alt_name;
1021
 
1022
  alt_name = xmalloc (sizeof (weak_altprefix) + strlen (name));
1023
  strcpy (alt_name, weak_altprefix);
1024
  return strcat (alt_name, name);
1025
}
1026
 
1027
/* Return the name of the weak symbol corresponding to an
1028
   alternate symbol.  */
1029
 
1030
static const char *
1031
weak_altname2name (const char * name)
1032
{
1033
  char * weak_name;
1034
  char * dot;
1035
 
1036
  assert (weak_is_altname (name));
1037
 
1038
  weak_name = xstrdup (name + 6);
1039
  if ((dot = strchr (weak_name, '.')))
1040
    *dot = 0;
1041
  return weak_name;
1042
}
1043
 
1044
/* Make a weak symbol name unique by
1045
   appending the name of an external symbol.  */
1046
 
1047
static const char *
1048
weak_uniquify (const char * name)
1049
{
1050
  char *ret;
1051
  const char * unique = "";
1052
 
1053
#ifdef USE_UNIQUE
1054
  if (an_external_name != NULL)
1055
    unique = an_external_name;
1056
#endif
1057
  assert (weak_is_altname (name));
1058
 
1059
  if (strchr (name + sizeof (weak_altprefix), '.'))
1060
    return name;
1061
 
1062
  ret = xmalloc (strlen (name) + strlen (unique) + 2);
1063
  strcpy (ret, name);
1064
  strcat (ret, ".");
1065
  strcat (ret, unique);
1066
  return ret;
1067
}
1068
 
1069
void
1070
pecoff_obj_set_weak_hook (symbolS *symbolP)
1071
{
1072
  symbolS *alternateP;
1073
 
1074
  /* See _Microsoft Portable Executable and Common Object
1075
     File Format Specification_, section 5.5.3.
1076
     Create a symbol representing the alternate value.
1077
     coff_frob_symbol will set the value of this symbol from
1078
     the value of the weak symbol itself.  */
1079
  S_SET_STORAGE_CLASS (symbolP, C_NT_WEAK);
1080
  S_SET_NUMBER_AUXILIARY (symbolP, 1);
1081
  SA_SET_SYM_FSIZE (symbolP, IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY);
1082
 
1083
  alternateP = symbol_find_or_make (weak_name2altname (S_GET_NAME (symbolP)));
1084
  S_SET_EXTERNAL (alternateP);
1085
  S_SET_STORAGE_CLASS (alternateP, C_NT_WEAK);
1086
 
1087
  SA_SET_SYM_TAGNDX (symbolP, alternateP);
1088
}
1089
 
1090
void
1091
pecoff_obj_clear_weak_hook (symbolS *symbolP)
1092
{
1093
  symbolS *alternateP;
1094
 
1095
  S_SET_STORAGE_CLASS (symbolP, 0);
1096
  SA_SET_SYM_FSIZE (symbolP, 0);
1097
 
1098
  alternateP = symbol_find (weak_name2altname (S_GET_NAME (symbolP)));
1099
  S_CLEAR_EXTERNAL (alternateP);
1100
}
1101
 
1102
#endif  /* TE_PE */
1103
 
1104
/* Handle .weak.  This is a GNU extension in formats other than PE. */
1105
 
1106
static void
1107
obj_coff_weak (int ignore ATTRIBUTE_UNUSED)
1108
{
1109
  char *name;
1110
  int c;
1111
  symbolS *symbolP;
1112
 
1113
  do
1114
    {
1115
      name = input_line_pointer;
1116
      c = get_symbol_end ();
1117
      if (*name == 0)
1118
        {
1119
          as_warn (_("badly formed .weak directive ignored"));
1120
          ignore_rest_of_line ();
1121
          return;
1122
        }
1123
      c = 0;
1124
      symbolP = symbol_find_or_make (name);
1125
      *input_line_pointer = c;
1126
      SKIP_WHITESPACE ();
1127
      S_SET_WEAK (symbolP);
1128
 
1129
      if (c == ',')
1130
        {
1131
          input_line_pointer++;
1132
          SKIP_WHITESPACE ();
1133
          if (*input_line_pointer == '\n')
1134
            c = '\n';
1135
        }
1136
 
1137
    }
1138
  while (c == ',');
1139
 
1140
  demand_empty_rest_of_line ();
1141
}
1142
 
1143
void
1144
coff_obj_read_begin_hook (void)
1145
{
1146
  /* These had better be the same.  Usually 18 bytes.  */
1147
  know (sizeof (SYMENT) == sizeof (AUXENT));
1148
  know (SYMESZ == AUXESZ);
1149
  tag_init ();
1150
}
1151
 
1152
symbolS *coff_last_function;
1153
#ifndef OBJ_XCOFF
1154
static symbolS *coff_last_bf;
1155
#endif
1156
 
1157
void
1158
coff_frob_symbol (symbolS *symp, int *punt)
1159
{
1160
  static symbolS *last_tagP;
1161
  static stack *block_stack;
1162
  static symbolS *set_end;
1163
  symbolS *next_set_end = NULL;
1164
 
1165
  if (symp == &abs_symbol)
1166
    {
1167
      *punt = 1;
1168
      return;
1169
    }
1170
 
1171
  if (current_lineno_sym)
1172
    coff_add_linesym (NULL);
1173
 
1174
  if (!block_stack)
1175
    block_stack = stack_init (512, sizeof (symbolS*));
1176
 
1177
#ifdef TE_PE
1178
  if (S_GET_STORAGE_CLASS (symp) == C_NT_WEAK
1179
      && ! S_IS_WEAK (symp)
1180
      && weak_is_altname (S_GET_NAME (symp)))
1181
    {
1182
      /* This is a weak alternate symbol.  All processing of
1183
         PECOFFweak symbols is done here, through the alternate.  */
1184
      symbolS *weakp = symbol_find_noref (weak_altname2name
1185
                                          (S_GET_NAME (symp)), 1);
1186
 
1187
      assert (weakp);
1188
      assert (S_GET_NUMBER_AUXILIARY (weakp) == 1);
1189
 
1190
      if (! S_IS_WEAK (weakp))
1191
        {
1192
          /* The symbol was turned from weak to strong.  Discard altname.  */
1193
          *punt = 1;
1194
          return;
1195
        }
1196
      else if (symbol_equated_p (weakp))
1197
        {
1198
          /* The weak symbol has an alternate specified; symp is unneeded.  */
1199
          S_SET_STORAGE_CLASS (weakp, C_NT_WEAK);
1200
          SA_SET_SYM_TAGNDX (weakp,
1201
            symbol_get_value_expression (weakp)->X_add_symbol);
1202
 
1203
          S_CLEAR_EXTERNAL (symp);
1204
          *punt = 1;
1205
          return;
1206
        }
1207
      else
1208
        {
1209
          /* The weak symbol has been assigned an alternate value.
1210
             Copy this value to symp, and set symp as weakp's alternate.  */
1211
          if (S_GET_STORAGE_CLASS (weakp) != C_NT_WEAK)
1212
            {
1213
              S_SET_STORAGE_CLASS (symp, S_GET_STORAGE_CLASS (weakp));
1214
              S_SET_STORAGE_CLASS (weakp, C_NT_WEAK);
1215
            }
1216
 
1217
          if (S_IS_DEFINED (weakp))
1218
            {
1219
              /* This is a defined weak symbol.  Copy value information
1220
                 from the weak symbol itself to the alternate symbol.  */
1221
              symbol_set_value_expression (symp,
1222
                                           symbol_get_value_expression (weakp));
1223
              symbol_set_frag (symp, symbol_get_frag (weakp));
1224
              S_SET_SEGMENT (symp, S_GET_SEGMENT (weakp));
1225
            }
1226
          else
1227
            {
1228
              /* This is an undefined weak symbol.
1229
                 Define the alternate symbol to zero.  */
1230
              S_SET_VALUE (symp, 0);
1231
              S_SET_SEGMENT (symp, absolute_section);
1232
            }
1233
 
1234
          S_SET_NAME (symp, weak_uniquify (S_GET_NAME (symp)));
1235
          S_SET_STORAGE_CLASS (symp, C_EXT);
1236
 
1237
          S_SET_VALUE (weakp, 0);
1238
          S_SET_SEGMENT (weakp, undefined_section);
1239
        }
1240
    }
1241
#else /* TE_PE */
1242
  if (S_IS_WEAK (symp))
1243
    S_SET_STORAGE_CLASS (symp, C_WEAKEXT);
1244
#endif /* TE_PE */
1245
 
1246
  if (!S_IS_DEFINED (symp)
1247
      && !S_IS_WEAK (symp)
1248
      && S_GET_STORAGE_CLASS (symp) != C_STAT)
1249
    S_SET_STORAGE_CLASS (symp, C_EXT);
1250
 
1251
  if (!SF_GET_DEBUG (symp))
1252
    {
1253
      symbolS * real;
1254
 
1255
      if (!SF_GET_LOCAL (symp)
1256
          && !SF_GET_STATICS (symp)
1257
          && S_GET_STORAGE_CLASS (symp) != C_LABEL
1258
          && symbol_constant_p (symp)
1259
          && (real = symbol_find_noref (S_GET_NAME (symp), 1))
1260
          && S_GET_STORAGE_CLASS (real) == C_NULL
1261
          && real != symp)
1262
        {
1263
          c_symbol_merge (symp, real);
1264
          *punt = 1;
1265
          return;
1266
        }
1267
 
1268
      if (!S_IS_DEFINED (symp) && !SF_GET_LOCAL (symp))
1269
        {
1270
          assert (S_GET_VALUE (symp) == 0);
1271
          if (S_IS_WEAKREFD (symp))
1272
            *punt = 1;
1273
          else
1274
            S_SET_EXTERNAL (symp);
1275
        }
1276
      else if (S_GET_STORAGE_CLASS (symp) == C_NULL)
1277
        {
1278
          if (S_GET_SEGMENT (symp) == text_section
1279
              && symp != seg_info (text_section)->sym)
1280
            S_SET_STORAGE_CLASS (symp, C_LABEL);
1281
          else
1282
            S_SET_STORAGE_CLASS (symp, C_STAT);
1283
        }
1284
 
1285
      if (SF_GET_PROCESS (symp))
1286
        {
1287
          if (S_GET_STORAGE_CLASS (symp) == C_BLOCK)
1288
            {
1289
              if (streq (S_GET_NAME (symp), ".bb"))
1290
                stack_push (block_stack, (char *) &symp);
1291
              else
1292
                {
1293
                  symbolS *begin;
1294
 
1295
                  begin = *(symbolS **) stack_pop (block_stack);
1296
                  if (begin == 0)
1297
                    as_warn (_("mismatched .eb"));
1298
                  else
1299
                    next_set_end = begin;
1300
                }
1301
            }
1302
 
1303
          if (coff_last_function == 0 && SF_GET_FUNCTION (symp))
1304
            {
1305
              union internal_auxent *auxp;
1306
 
1307
              coff_last_function = symp;
1308
              if (S_GET_NUMBER_AUXILIARY (symp) < 1)
1309
                S_SET_NUMBER_AUXILIARY (symp, 1);
1310
              auxp = SYM_AUXENT (symp);
1311
              memset (auxp->x_sym.x_fcnary.x_ary.x_dimen, 0,
1312
                      sizeof (auxp->x_sym.x_fcnary.x_ary.x_dimen));
1313
            }
1314
 
1315
          if (S_GET_STORAGE_CLASS (symp) == C_EFCN)
1316
            {
1317
              if (coff_last_function == 0)
1318
                as_fatal (_("C_EFCN symbol for %s out of scope"),
1319
                          S_GET_NAME (symp));
1320
              SA_SET_SYM_FSIZE (coff_last_function,
1321
                                (long) (S_GET_VALUE (symp)
1322
                                        - S_GET_VALUE (coff_last_function)));
1323
              next_set_end = coff_last_function;
1324
              coff_last_function = 0;
1325
            }
1326
        }
1327
 
1328
      if (S_IS_EXTERNAL (symp))
1329
        S_SET_STORAGE_CLASS (symp, C_EXT);
1330
      else if (SF_GET_LOCAL (symp))
1331
        *punt = 1;
1332
 
1333
      if (SF_GET_FUNCTION (symp))
1334
        symbol_get_bfdsym (symp)->flags |= BSF_FUNCTION;
1335
    }
1336
 
1337
  /* Double check weak symbols.  */
1338
  if (S_IS_WEAK (symp) && S_IS_COMMON (symp))
1339
    as_bad (_("Symbol `%s' can not be both weak and common"),
1340
            S_GET_NAME (symp));
1341
 
1342
  if (SF_GET_TAG (symp))
1343
    last_tagP = symp;
1344
  else if (S_GET_STORAGE_CLASS (symp) == C_EOS)
1345
    next_set_end = last_tagP;
1346
 
1347
#ifdef OBJ_XCOFF
1348
  /* This is pretty horrible, but we have to set *punt correctly in
1349
     order to call SA_SET_SYM_ENDNDX correctly.  */
1350
  if (! symbol_used_in_reloc_p (symp)
1351
      && ((symbol_get_bfdsym (symp)->flags & BSF_SECTION_SYM) != 0
1352
          || (! (S_IS_EXTERNAL (symp) || S_IS_WEAK (symp))
1353
              && ! symbol_get_tc (symp)->output
1354
              && S_GET_STORAGE_CLASS (symp) != C_FILE)))
1355
    *punt = 1;
1356
#endif
1357
 
1358
  if (set_end != (symbolS *) NULL
1359
      && ! *punt
1360
      && ((symbol_get_bfdsym (symp)->flags & BSF_NOT_AT_END) != 0
1361
          || (S_IS_DEFINED (symp)
1362
              && ! S_IS_COMMON (symp)
1363
              && (! S_IS_EXTERNAL (symp) || SF_GET_FUNCTION (symp)))))
1364
    {
1365
      SA_SET_SYM_ENDNDX (set_end, symp);
1366
      set_end = NULL;
1367
    }
1368
 
1369
  if (next_set_end != NULL)
1370
    {
1371
      if (set_end != NULL)
1372
        as_warn ("Warning: internal error: forgetting to set endndx of %s",
1373
                 S_GET_NAME (set_end));
1374
      set_end = next_set_end;
1375
    }
1376
 
1377
#ifndef OBJ_XCOFF
1378
  if (! *punt
1379
      && S_GET_STORAGE_CLASS (symp) == C_FCN
1380
      && streq (S_GET_NAME (symp), ".bf"))
1381
    {
1382
      if (coff_last_bf != NULL)
1383
        SA_SET_SYM_ENDNDX (coff_last_bf, symp);
1384
      coff_last_bf = symp;
1385
    }
1386
#endif
1387
  if (coffsymbol (symbol_get_bfdsym (symp))->lineno)
1388
    {
1389
      int i;
1390
      struct line_no *lptr;
1391
      alent *l;
1392
 
1393
      lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno;
1394
      for (i = 0; lptr; lptr = lptr->next)
1395
        i++;
1396
      lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno;
1397
 
1398
      /* We need i entries for line numbers, plus 1 for the first
1399
         entry which BFD will override, plus 1 for the last zero
1400
         entry (a marker for BFD).  */
1401
      l = xmalloc ((i + 2) * sizeof (* l));
1402
      coffsymbol (symbol_get_bfdsym (symp))->lineno = l;
1403
      l[i + 1].line_number = 0;
1404
      l[i + 1].u.sym = NULL;
1405
      for (; i > 0; i--)
1406
        {
1407
          if (lptr->frag)
1408
            lptr->l.u.offset += lptr->frag->fr_address / OCTETS_PER_BYTE;
1409
          l[i] = lptr->l;
1410
          lptr = lptr->next;
1411
        }
1412
    }
1413
}
1414
 
1415
void
1416
coff_adjust_section_syms (bfd *abfd ATTRIBUTE_UNUSED,
1417
                          asection *sec,
1418
                          void * x ATTRIBUTE_UNUSED)
1419
{
1420
  symbolS *secsym;
1421
  segment_info_type *seginfo = seg_info (sec);
1422
  int nlnno, nrelocs = 0;
1423
 
1424
  /* RS/6000 gas creates a .debug section manually in ppc_frob_file in
1425
     tc-ppc.c.  Do not get confused by it.  */
1426
  if (seginfo == NULL)
1427
    return;
1428
 
1429
  if (streq (sec->name, ".text"))
1430
    nlnno = coff_n_line_nos;
1431
  else
1432
    nlnno = 0;
1433
  {
1434
    /* @@ Hope that none of the fixups expand to more than one reloc
1435
       entry...  */
1436
    fixS *fixp = seginfo->fix_root;
1437
    while (fixp)
1438
      {
1439
        if (! fixp->fx_done)
1440
          nrelocs++;
1441
        fixp = fixp->fx_next;
1442
      }
1443
  }
1444
  if (bfd_get_section_size (sec) == 0
1445
      && nrelocs == 0
1446
      && nlnno == 0
1447
      && sec != text_section
1448
      && sec != data_section
1449
      && sec != bss_section)
1450
    return;
1451
 
1452
  secsym = section_symbol (sec);
1453
  /* This is an estimate; we'll plug in the real value using
1454
     SET_SECTION_RELOCS later */
1455
  SA_SET_SCN_NRELOC (secsym, nrelocs);
1456
  SA_SET_SCN_NLINNO (secsym, nlnno);
1457
}
1458
 
1459
void
1460
coff_frob_file_after_relocs (void)
1461
{
1462
  bfd_map_over_sections (stdoutput, coff_adjust_section_syms, NULL);
1463
}
1464
 
1465
/* Implement the .section pseudo op:
1466
        .section name {, "flags"}
1467
                  ^         ^
1468
                  |         +--- optional flags: 'b' for bss
1469
                  |                              'i' for info
1470
                  +-- section name               'l' for lib
1471
                                                 'n' for noload
1472
                                                 'o' for over
1473
                                                 'w' for data
1474
                                                 'd' (apparently m88k for data)
1475
                                                 'x' for text
1476
                                                 'r' for read-only data
1477
                                                 's' for shared data (PE)
1478
   But if the argument is not a quoted string, treat it as a
1479
   subsegment number.
1480
 
1481
   Note the 'a' flag is silently ignored.  This allows the same
1482
   .section directive to be parsed in both ELF and COFF formats.  */
1483
 
1484
void
1485
obj_coff_section (int ignore ATTRIBUTE_UNUSED)
1486
{
1487
  /* Strip out the section name.  */
1488
  char *section_name;
1489
  char c;
1490
  char *name;
1491
  unsigned int exp;
1492
  flagword flags, oldflags;
1493
  asection *sec;
1494
 
1495
  if (flag_mri)
1496
    {
1497
      char type;
1498
 
1499
      s_mri_sect (&type);
1500
      return;
1501
    }
1502
 
1503
  section_name = input_line_pointer;
1504
  c = get_symbol_end ();
1505
 
1506
  name = xmalloc (input_line_pointer - section_name + 1);
1507
  strcpy (name, section_name);
1508
 
1509
  *input_line_pointer = c;
1510
 
1511
  SKIP_WHITESPACE ();
1512
 
1513
  exp = 0;
1514
  flags = SEC_NO_FLAGS;
1515
 
1516
  if (*input_line_pointer == ',')
1517
    {
1518
      ++input_line_pointer;
1519
      SKIP_WHITESPACE ();
1520
      if (*input_line_pointer != '"')
1521
        exp = get_absolute_expression ();
1522
      else
1523
        {
1524
          unsigned char attr;
1525
          int readonly_removed = 0;
1526
          int load_removed = 0;
1527
 
1528
          while (attr = *++input_line_pointer,
1529
                 attr != '"'
1530
                 && ! is_end_of_line[attr])
1531
            {
1532
              switch (attr)
1533
                {
1534
                case 'b':
1535
                  /* Uninitialised data section.  */
1536
                  flags |= SEC_ALLOC;
1537
                  flags &=~ SEC_LOAD;
1538
                  break;
1539
 
1540
                case 'n':
1541
                  /* Section not loaded.  */
1542
                  flags &=~ SEC_LOAD;
1543
                  flags |= SEC_NEVER_LOAD;
1544
                  load_removed = 1;
1545
                  break;
1546
 
1547
                case 's':
1548
                  /* Shared section.  */
1549
                  flags |= SEC_COFF_SHARED;
1550
                  /* Fall through.  */
1551
                case 'd':
1552
                  /* Data section.  */
1553
                  flags |= SEC_DATA;
1554
                  if (! load_removed)
1555
                    flags |= SEC_LOAD;
1556
                  flags &=~ SEC_READONLY;
1557
                  break;
1558
 
1559
                case 'w':
1560
                  /* Writable section.  */
1561
                  flags &=~ SEC_READONLY;
1562
                  readonly_removed = 1;
1563
                  break;
1564
 
1565
                case 'a':
1566
                  /* Ignore.  Here for compatibility with ELF.  */
1567
                  break;
1568
 
1569
                case 'r': /* Read-only section.  Implies a data section.  */
1570
                  readonly_removed = 0;
1571
                  /* Fall through.  */
1572
                case 'x': /* Executable section.  */
1573
                  /* If we are setting the 'x' attribute or if the 'r'
1574
                     attribute is being used to restore the readonly status
1575
                     of a code section (eg "wxr") then set the SEC_CODE flag,
1576
                     otherwise set the SEC_DATA flag.  */
1577
                  flags |= (attr == 'x' || (flags & SEC_CODE) ? SEC_CODE : SEC_DATA);
1578
                  if (! load_removed)
1579
                    flags |= SEC_LOAD;
1580
                  /* Note - the READONLY flag is set here, even for the 'x'
1581
                     attribute in order to be compatible with the MSVC
1582
                     linker.  */
1583
                  if (! readonly_removed)
1584
                    flags |= SEC_READONLY;
1585
                  break;
1586
 
1587
                case 'i': /* STYP_INFO */
1588
                case 'l': /* STYP_LIB */
1589
                case 'o': /* STYP_OVER */
1590
                  as_warn (_("unsupported section attribute '%c'"), attr);
1591
                  break;
1592
 
1593
                default:
1594
                  as_warn (_("unknown section attribute '%c'"), attr);
1595
                  break;
1596
                }
1597
            }
1598
          if (attr == '"')
1599
            ++input_line_pointer;
1600
        }
1601
    }
1602
 
1603
  sec = subseg_new (name, (subsegT) exp);
1604
 
1605
  oldflags = bfd_get_section_flags (stdoutput, sec);
1606
  if (oldflags == SEC_NO_FLAGS)
1607
    {
1608
      /* Set section flags for a new section just created by subseg_new.
1609
         Provide a default if no flags were parsed.  */
1610
      if (flags == SEC_NO_FLAGS)
1611
        flags = TC_COFF_SECTION_DEFAULT_ATTRIBUTES;
1612
 
1613
#ifdef COFF_LONG_SECTION_NAMES
1614
      /* Add SEC_LINK_ONCE and SEC_LINK_DUPLICATES_DISCARD to .gnu.linkonce
1615
         sections so adjust_reloc_syms in write.c will correctly handle
1616
         relocs which refer to non-local symbols in these sections.  */
1617
      if (strneq (name, ".gnu.linkonce", sizeof (".gnu.linkonce") - 1))
1618
        flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
1619
#endif
1620
 
1621
      if (! bfd_set_section_flags (stdoutput, sec, flags))
1622
        as_warn (_("error setting flags for \"%s\": %s"),
1623
                 bfd_section_name (stdoutput, sec),
1624
                 bfd_errmsg (bfd_get_error ()));
1625
    }
1626
  else if (flags != SEC_NO_FLAGS)
1627
    {
1628
      /* This section's attributes have already been set.  Warn if the
1629
         attributes don't match.  */
1630
      flagword matchflags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
1631
                             | SEC_DATA | SEC_COFF_SHARED | SEC_NEVER_LOAD);
1632
      if ((flags ^ oldflags) & matchflags)
1633
        as_warn (_("Ignoring changed section attributes for %s"), name);
1634
    }
1635
 
1636
  demand_empty_rest_of_line ();
1637
}
1638
 
1639
void
1640
coff_adjust_symtab (void)
1641
{
1642
  if (symbol_rootP == NULL
1643
      || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
1644
    c_dot_file_symbol ("fake", 0);
1645
}
1646
 
1647
void
1648
coff_frob_section (segT sec)
1649
{
1650
  segT strsec;
1651
  char *p;
1652
  fragS *fragp;
1653
  bfd_vma size, n_entries, mask;
1654
  bfd_vma align_power = (bfd_vma)sec->alignment_power + OCTETS_PER_BYTE_POWER;
1655
 
1656
  /* The COFF back end in BFD requires that all section sizes be
1657
     rounded up to multiples of the corresponding section alignments,
1658
     supposedly because standard COFF has no other way of encoding alignment
1659
     for sections.  If your COFF flavor has a different way of encoding
1660
     section alignment, then skip this step, as TICOFF does.  */
1661
  size = bfd_get_section_size (sec);
1662
  mask = ((bfd_vma) 1 << align_power) - 1;
1663
#if !defined(TICOFF)
1664
  if (size & mask)
1665
    {
1666
      bfd_vma new_size;
1667
      fragS *last;
1668
 
1669
      new_size = (size + mask) & ~mask;
1670
      bfd_set_section_size (stdoutput, sec, new_size);
1671
 
1672
      /* If the size had to be rounded up, add some padding in
1673
         the last non-empty frag.  */
1674
      fragp = seg_info (sec)->frchainP->frch_root;
1675
      last = seg_info (sec)->frchainP->frch_last;
1676
      while (fragp->fr_next != last)
1677
        fragp = fragp->fr_next;
1678
      last->fr_address = size;
1679
      fragp->fr_offset += new_size - size;
1680
    }
1681
#endif
1682
 
1683
  /* If the section size is non-zero, the section symbol needs an aux
1684
     entry associated with it, indicating the size.  We don't know
1685
     all the values yet; coff_frob_symbol will fill them in later.  */
1686
#ifndef TICOFF
1687
  if (size != 0
1688
      || sec == text_section
1689
      || sec == data_section
1690
      || sec == bss_section)
1691
#endif
1692
    {
1693
      symbolS *secsym = section_symbol (sec);
1694
 
1695
      S_SET_STORAGE_CLASS (secsym, C_STAT);
1696
      S_SET_NUMBER_AUXILIARY (secsym, 1);
1697
      SF_SET_STATICS (secsym);
1698
      SA_SET_SCN_SCNLEN (secsym, size);
1699
    }
1700
 
1701
  /* FIXME: These should be in a "stabs.h" file, or maybe as.h.  */
1702
#ifndef STAB_SECTION_NAME
1703
#define STAB_SECTION_NAME ".stab"
1704
#endif
1705
#ifndef STAB_STRING_SECTION_NAME
1706
#define STAB_STRING_SECTION_NAME ".stabstr"
1707
#endif
1708
  if (! streq (STAB_STRING_SECTION_NAME, sec->name))
1709
    return;
1710
 
1711
  strsec = sec;
1712
  sec = subseg_get (STAB_SECTION_NAME, 0);
1713
  /* size is already rounded up, since other section will be listed first */
1714
  size = bfd_get_section_size (strsec);
1715
 
1716
  n_entries = bfd_get_section_size (sec) / 12 - 1;
1717
 
1718
  /* Find first non-empty frag.  It should be large enough.  */
1719
  fragp = seg_info (sec)->frchainP->frch_root;
1720
  while (fragp && fragp->fr_fix == 0)
1721
    fragp = fragp->fr_next;
1722
  assert (fragp != 0 && fragp->fr_fix >= 12);
1723
 
1724
  /* Store the values.  */
1725
  p = fragp->fr_literal;
1726
  bfd_h_put_16 (stdoutput, n_entries, (bfd_byte *) p + 6);
1727
  bfd_h_put_32 (stdoutput, size, (bfd_byte *) p + 8);
1728
}
1729
 
1730
void
1731
obj_coff_init_stab_section (segT seg)
1732
{
1733
  char *file;
1734
  char *p;
1735
  char *stabstr_name;
1736
  unsigned int stroff;
1737
 
1738
  /* Make space for this first symbol.  */
1739
  p = frag_more (12);
1740
  /* Zero it out.  */
1741
  memset (p, 0, 12);
1742
  as_where (&file, (unsigned int *) NULL);
1743
  stabstr_name = xmalloc (strlen (seg->name) + 4);
1744
  strcpy (stabstr_name, seg->name);
1745
  strcat (stabstr_name, "str");
1746
  stroff = get_stab_string_offset (file, stabstr_name);
1747
  know (stroff == 1);
1748
  md_number_to_chars (p, stroff, 4);
1749
}
1750
 
1751
#ifdef DEBUG
1752
const char *
1753
s_get_name (symbolS *s)
1754
{
1755
  return ((s == NULL) ? "(NULL)" : S_GET_NAME (s));
1756
}
1757
 
1758
void
1759
symbol_dump (void)
1760
{
1761
  symbolS *symbolP;
1762
 
1763
  for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
1764
    printf (_("0x%lx: \"%s\" type = %ld, class = %d, segment = %d\n"),
1765
            (unsigned long) symbolP,
1766
            S_GET_NAME (symbolP),
1767
            (long) S_GET_DATA_TYPE (symbolP),
1768
            S_GET_STORAGE_CLASS (symbolP),
1769
            (int) S_GET_SEGMENT (symbolP));
1770
}
1771
 
1772
#endif /* DEBUG */
1773
 
1774
const pseudo_typeS coff_pseudo_table[] =
1775
{
1776
  {"ABORT", s_abort, 0},
1777
  {"appline", obj_coff_ln, 1},
1778
  /* We accept the .bss directive for backward compatibility with
1779
     earlier versions of gas.  */
1780
  {"bss", obj_coff_bss, 0},
1781
  {"def", obj_coff_def, 0},
1782
  {"dim", obj_coff_dim, 0},
1783
  {"endef", obj_coff_endef, 0},
1784
  {"ident", obj_coff_ident, 0},
1785
  {"line", obj_coff_line, 0},
1786
  {"ln", obj_coff_ln, 0},
1787
  {"scl", obj_coff_scl, 0},
1788
  {"sect", obj_coff_section, 0},
1789
  {"sect.s", obj_coff_section, 0},
1790
  {"section", obj_coff_section, 0},
1791
  {"section.s", obj_coff_section, 0},
1792
  /* FIXME: We ignore the MRI short attribute.  */
1793
  {"size", obj_coff_size, 0},
1794
  {"tag", obj_coff_tag, 0},
1795
  {"type", obj_coff_type, 0},
1796
  {"val", obj_coff_val, 0},
1797
  {"version", s_ignore, 0},
1798
  {"loc", obj_coff_loc, 0},
1799
  {"optim", s_ignore, 0},        /* For sun386i cc (?) */
1800
  {"weak", obj_coff_weak, 0},
1801
#if defined TC_TIC4X
1802
  /* The tic4x uses sdef instead of def.  */
1803
  {"sdef", obj_coff_def, 0},
1804
#endif
1805
  {NULL, NULL, 0}
1806
};
1807
 
1808
 
1809
/* Support for a COFF emulation.  */
1810
 
1811
static void
1812
coff_pop_insert (void)
1813
{
1814
  pop_insert (coff_pseudo_table);
1815
}
1816
 
1817
static int
1818
coff_separate_stab_sections (void)
1819
{
1820
  return 1;
1821
}
1822
 
1823
const struct format_ops coff_format_ops =
1824
{
1825
  bfd_target_coff_flavour,
1826
  0,     /* dfl_leading_underscore */
1827
  1,    /* emit_section_symbols */
1828
  0,    /* begin */
1829
  c_dot_file_symbol,
1830
  coff_frob_symbol,
1831
  0,     /* frob_file */
1832
  0,     /* frob_file_before_adjust */
1833
  0,     /* frob_file_before_fix */
1834
  coff_frob_file_after_relocs,
1835
  0,     /* s_get_size */
1836
  0,     /* s_set_size */
1837
  0,     /* s_get_align */
1838
  0,     /* s_set_align */
1839
  0,     /* s_get_other */
1840
  0,     /* s_set_other */
1841
  0,     /* s_get_desc */
1842
  0,     /* s_set_desc */
1843
  0,     /* s_get_type */
1844
  0,     /* s_set_type */
1845
  0,     /* copy_symbol_attributes */
1846
  0,     /* generate_asm_lineno */
1847
  0,     /* process_stab */
1848
  coff_separate_stab_sections,
1849
  obj_coff_init_stab_section,
1850
  0,     /* sec_sym_ok_for_reloc */
1851
  coff_pop_insert,
1852
  0,     /* ecoff_set_ext */
1853
  coff_obj_read_begin_hook,
1854
  coff_obj_symbol_new_hook
1855
};

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.