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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [gas/] [config/] [obj-coff.c] - Blame information for rev 163

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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