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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [binutils-2.20.1/] [gas/] [config/] [obj-coff.c] - Blame information for rev 818

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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