OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.20.1/] [gas/] [config/] [obj-elf.c] - Blame information for rev 205

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 205 julius
/* ELF object file format
2
   Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3
   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
4
   Free Software Foundation, Inc.
5
 
6
   This file is part of GAS, the GNU Assembler.
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
10
   published by the Free Software Foundation; either version 3,
11
   or (at your option) any later version.
12
 
13
   GAS is distributed in the hope that it will be useful, but
14
   WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
16
   the 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-elf.h"
24
#include "as.h"
25
#include "safe-ctype.h"
26
#include "subsegs.h"
27
#include "obstack.h"
28
#include "struc-symbol.h"
29
#include "dwarf2dbg.h"
30
 
31
#ifndef ECOFF_DEBUGGING
32
#define ECOFF_DEBUGGING 0
33
#else
34
#define NEED_ECOFF_DEBUG
35
#endif
36
 
37
#ifdef NEED_ECOFF_DEBUG
38
#include "ecoff.h"
39
#endif
40
 
41
#ifdef TC_ALPHA
42
#include "elf/alpha.h"
43
#endif
44
 
45
#ifdef TC_MIPS
46
#include "elf/mips.h"
47
#endif
48
 
49
#ifdef TC_PPC
50
#include "elf/ppc.h"
51
#endif
52
 
53
#ifdef TC_I370
54
#include "elf/i370.h"
55
#endif
56
 
57
#ifdef TC_I386
58
#include "elf/x86-64.h"
59
#endif
60
 
61
#ifdef TC_MEP
62
#include "elf/mep.h"
63
#endif
64
 
65
static void obj_elf_line (int);
66
static void obj_elf_size (int);
67
static void obj_elf_type (int);
68
static void obj_elf_ident (int);
69
static void obj_elf_weak (int);
70
static void obj_elf_local (int);
71
static void obj_elf_visibility (int);
72
static void obj_elf_symver (int);
73
static void obj_elf_subsection (int);
74
static void obj_elf_popsection (int);
75
static void obj_elf_tls_common (int);
76
static void obj_elf_lcomm (int);
77
static void obj_elf_struct (int);
78
 
79
static const pseudo_typeS elf_pseudo_table[] =
80
{
81
  {"comm", obj_elf_common, 0},
82
  {"common", obj_elf_common, 1},
83
  {"ident", obj_elf_ident, 0},
84
  {"lcomm", obj_elf_lcomm, 0},
85
  {"local", obj_elf_local, 0},
86
  {"previous", obj_elf_previous, 0},
87
  {"section", obj_elf_section, 0},
88
  {"section.s", obj_elf_section, 0},
89
  {"sect", obj_elf_section, 0},
90
  {"sect.s", obj_elf_section, 0},
91
  {"pushsection", obj_elf_section, 1},
92
  {"popsection", obj_elf_popsection, 0},
93
  {"size", obj_elf_size, 0},
94
  {"type", obj_elf_type, 0},
95
  {"version", obj_elf_version, 0},
96
  {"weak", obj_elf_weak, 0},
97
 
98
  /* These define symbol visibility.  */
99
  {"internal", obj_elf_visibility, STV_INTERNAL},
100
  {"hidden", obj_elf_visibility, STV_HIDDEN},
101
  {"protected", obj_elf_visibility, STV_PROTECTED},
102
 
103
  /* These are used for stabs-in-elf configurations.  */
104
  {"line", obj_elf_line, 0},
105
 
106
  /* This is a GNU extension to handle symbol versions.  */
107
  {"symver", obj_elf_symver, 0},
108
 
109
  /* A GNU extension to change subsection only.  */
110
  {"subsection", obj_elf_subsection, 0},
111
 
112
  /* These are GNU extensions to aid in garbage collecting C++ vtables.  */
113
  {"vtable_inherit", (void (*) (int)) &obj_elf_vtable_inherit, 0},
114
  {"vtable_entry", (void (*) (int)) &obj_elf_vtable_entry, 0},
115
 
116
  /* These are used for dwarf.  */
117
  {"2byte", cons, 2},
118
  {"4byte", cons, 4},
119
  {"8byte", cons, 8},
120
  /* These are used for dwarf2.  */
121
  { "file", (void (*) (int)) dwarf2_directive_file, 0 },
122
  { "loc",  dwarf2_directive_loc,  0 },
123
  { "loc_mark_labels", dwarf2_directive_loc_mark_labels, 0 },
124
 
125
  /* We need to trap the section changing calls to handle .previous.  */
126
  {"data", obj_elf_data, 0},
127
  {"offset", obj_elf_struct, 0},
128
  {"struct", obj_elf_struct, 0},
129
  {"text", obj_elf_text, 0},
130
 
131
  {"tls_common", obj_elf_tls_common, 0},
132
 
133
  /* End sentinel.  */
134
  {NULL, NULL, 0},
135
};
136
 
137
static const pseudo_typeS ecoff_debug_pseudo_table[] =
138
{
139
#ifdef NEED_ECOFF_DEBUG
140
  /* COFF style debugging information for ECOFF. .ln is not used; .loc
141
     is used instead.  */
142
  { "def",      ecoff_directive_def,    0 },
143
  { "dim",      ecoff_directive_dim,    0 },
144
  { "endef",    ecoff_directive_endef,  0 },
145
  { "file",     ecoff_directive_file,   0 },
146
  { "scl",      ecoff_directive_scl,    0 },
147
  { "tag",      ecoff_directive_tag,    0 },
148
  { "val",      ecoff_directive_val,    0 },
149
 
150
  /* COFF debugging requires pseudo-ops .size and .type, but ELF
151
     already has meanings for those.  We use .esize and .etype
152
     instead.  These are only generated by gcc anyhow.  */
153
  { "esize",    ecoff_directive_size,   0 },
154
  { "etype",    ecoff_directive_type,   0 },
155
 
156
  /* ECOFF specific debugging information.  */
157
  { "begin",    ecoff_directive_begin,  0 },
158
  { "bend",     ecoff_directive_bend,   0 },
159
  { "end",      ecoff_directive_end,    0 },
160
  { "ent",      ecoff_directive_ent,    0 },
161
  { "fmask",    ecoff_directive_fmask,  0 },
162
  { "frame",    ecoff_directive_frame,  0 },
163
  { "loc",      ecoff_directive_loc,    0 },
164
  { "mask",     ecoff_directive_mask,   0 },
165
 
166
  /* Other ECOFF directives.  */
167
  { "extern",   ecoff_directive_extern, 0 },
168
 
169
  /* These are used on Irix.  I don't know how to implement them.  */
170
  { "alias",    s_ignore,               0 },
171
  { "bgnb",     s_ignore,               0 },
172
  { "endb",     s_ignore,               0 },
173
  { "lab",      s_ignore,               0 },
174
  { "noalias",  s_ignore,               0 },
175
  { "verstamp", s_ignore,               0 },
176
  { "vreg",     s_ignore,               0 },
177
#endif
178
 
179
  {NULL, NULL, 0}                        /* end sentinel */
180
};
181
 
182
#undef NO_RELOC
183
#include "aout/aout64.h"
184
 
185
/* This is called when the assembler starts.  */
186
 
187
asection *elf_com_section_ptr;
188
 
189
void
190
elf_begin (void)
191
{
192
  asection *s;
193
 
194
  /* Add symbols for the known sections to the symbol table.  */
195
  s = bfd_get_section_by_name (stdoutput, TEXT_SECTION_NAME);
196
  symbol_table_insert (section_symbol (s));
197
  s = bfd_get_section_by_name (stdoutput, DATA_SECTION_NAME);
198
  symbol_table_insert (section_symbol (s));
199
  s = bfd_get_section_by_name (stdoutput, BSS_SECTION_NAME);
200
  symbol_table_insert (section_symbol (s));
201
  elf_com_section_ptr = bfd_com_section_ptr;
202
}
203
 
204
void
205
elf_pop_insert (void)
206
{
207
  pop_insert (elf_pseudo_table);
208
  if (ECOFF_DEBUGGING)
209
    pop_insert (ecoff_debug_pseudo_table);
210
}
211
 
212
static bfd_vma
213
elf_s_get_size (symbolS *sym)
214
{
215
  return S_GET_SIZE (sym);
216
}
217
 
218
static void
219
elf_s_set_size (symbolS *sym, bfd_vma sz)
220
{
221
  S_SET_SIZE (sym, sz);
222
}
223
 
224
static bfd_vma
225
elf_s_get_align (symbolS *sym)
226
{
227
  return S_GET_ALIGN (sym);
228
}
229
 
230
static void
231
elf_s_set_align (symbolS *sym, bfd_vma align)
232
{
233
  S_SET_ALIGN (sym, align);
234
}
235
 
236
int
237
elf_s_get_other (symbolS *sym)
238
{
239
  return elf_symbol (symbol_get_bfdsym (sym))->internal_elf_sym.st_other;
240
}
241
 
242
static void
243
elf_s_set_other (symbolS *sym, int other)
244
{
245
  S_SET_OTHER (sym, other);
246
}
247
 
248
static int
249
elf_sec_sym_ok_for_reloc (asection *sec)
250
{
251
  return obj_sec_sym_ok_for_reloc (sec);
252
}
253
 
254
void
255
elf_file_symbol (const char *s, int appfile)
256
{
257
  if (!appfile
258
      || symbol_rootP == NULL
259
      || symbol_rootP->bsym == NULL
260
      || (symbol_rootP->bsym->flags & BSF_FILE) == 0)
261
    {
262
      symbolS *sym;
263
      unsigned int name_length;
264
 
265
      sym = symbol_new (s, absolute_section, 0, NULL);
266
      symbol_set_frag (sym, &zero_address_frag);
267
 
268
      name_length = strlen (s);
269
      if (name_length > strlen (S_GET_NAME (sym)))
270
        {
271
          obstack_grow (&notes, s, name_length + 1);
272
          S_SET_NAME (sym, (const char *) obstack_finish (&notes));
273
        }
274
      else
275
        strcpy ((char *) S_GET_NAME (sym), s);
276
 
277
      symbol_get_bfdsym (sym)->flags |= BSF_FILE;
278
 
279
      if (symbol_rootP != sym)
280
        {
281
          symbol_remove (sym, &symbol_rootP, &symbol_lastP);
282
          symbol_insert (sym, symbol_rootP, &symbol_rootP, &symbol_lastP);
283
#ifdef DEBUG
284
          verify_symbol_chain (symbol_rootP, symbol_lastP);
285
#endif
286
        }
287
    }
288
 
289
#ifdef NEED_ECOFF_DEBUG
290
  ecoff_new_file (s, appfile);
291
#endif
292
}
293
 
294
/* Called from read.c:s_comm after we've parsed .comm symbol, size.
295
   Parse a possible alignment value.  */
296
 
297
symbolS *
298
elf_common_parse (int ignore ATTRIBUTE_UNUSED, symbolS *symbolP, addressT size)
299
{
300
  addressT align = 0;
301
  int is_local = symbol_get_obj (symbolP)->local;
302
 
303
  if (*input_line_pointer == ',')
304
    {
305
      char *save = input_line_pointer;
306
 
307
      input_line_pointer++;
308
      SKIP_WHITESPACE ();
309
 
310
      if (*input_line_pointer == '"')
311
        {
312
          /* For sparc.  Accept .common symbol, length, "bss"  */
313
          input_line_pointer++;
314
          /* Some use the dot, some don't.  */
315
          if (*input_line_pointer == '.')
316
            input_line_pointer++;
317
          /* Some say data, some say bss.  */
318
          if (strncmp (input_line_pointer, "bss\"", 4) == 0)
319
            input_line_pointer += 4;
320
          else if (strncmp (input_line_pointer, "data\"", 5) == 0)
321
            input_line_pointer += 5;
322
          else
323
            {
324
              char *p = input_line_pointer;
325
              char c;
326
 
327
              while (*--p != '"')
328
                ;
329
              while (!is_end_of_line[(unsigned char) *input_line_pointer])
330
                if (*input_line_pointer++ == '"')
331
                  break;
332
              c = *input_line_pointer;
333
              *input_line_pointer = '\0';
334
              as_bad (_("bad .common segment %s"), p);
335
              *input_line_pointer = c;
336
              ignore_rest_of_line ();
337
              return NULL;
338
            }
339
          /* ??? Don't ask me why these are always global.  */
340
          is_local = 0;
341
        }
342
      else
343
        {
344
          input_line_pointer = save;
345
          align = parse_align (is_local);
346
          if (align == (addressT) -1)
347
            return NULL;
348
        }
349
    }
350
 
351
  if (is_local)
352
    {
353
      bss_alloc (symbolP, size, align);
354
      S_CLEAR_EXTERNAL (symbolP);
355
    }
356
  else
357
    {
358
      S_SET_VALUE (symbolP, size);
359
      S_SET_ALIGN (symbolP, align);
360
      S_SET_EXTERNAL (symbolP);
361
      S_SET_SEGMENT (symbolP, elf_com_section_ptr);
362
    }
363
 
364
  symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
365
 
366
  return symbolP;
367
}
368
 
369
void
370
obj_elf_common (int is_common)
371
{
372
  if (flag_mri && is_common)
373
    s_mri_common (0);
374
  else
375
    s_comm_internal (0, elf_common_parse);
376
}
377
 
378
static void
379
obj_elf_tls_common (int ignore ATTRIBUTE_UNUSED)
380
{
381
  symbolS *symbolP = s_comm_internal (0, elf_common_parse);
382
 
383
  if (symbolP)
384
    symbol_get_bfdsym (symbolP)->flags |= BSF_THREAD_LOCAL;
385
}
386
 
387
static void
388
obj_elf_lcomm (int ignore ATTRIBUTE_UNUSED)
389
{
390
  symbolS *symbolP = s_comm_internal (0, s_lcomm_internal);
391
 
392
  if (symbolP)
393
    symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
394
}
395
 
396
static void
397
obj_elf_local (int ignore ATTRIBUTE_UNUSED)
398
{
399
  char *name;
400
  int c;
401
  symbolS *symbolP;
402
 
403
  do
404
    {
405
      name = input_line_pointer;
406
      c = get_symbol_end ();
407
      symbolP = symbol_find_or_make (name);
408
      *input_line_pointer = c;
409
      SKIP_WHITESPACE ();
410
      S_CLEAR_EXTERNAL (symbolP);
411
      symbol_get_obj (symbolP)->local = 1;
412
      if (c == ',')
413
        {
414
          input_line_pointer++;
415
          SKIP_WHITESPACE ();
416
          if (*input_line_pointer == '\n')
417
            c = '\n';
418
        }
419
    }
420
  while (c == ',');
421
  demand_empty_rest_of_line ();
422
}
423
 
424
static void
425
obj_elf_weak (int ignore ATTRIBUTE_UNUSED)
426
{
427
  char *name;
428
  int c;
429
  symbolS *symbolP;
430
 
431
  do
432
    {
433
      name = input_line_pointer;
434
      c = get_symbol_end ();
435
      symbolP = symbol_find_or_make (name);
436
      *input_line_pointer = c;
437
      SKIP_WHITESPACE ();
438
      S_SET_WEAK (symbolP);
439
      symbol_get_obj (symbolP)->local = 1;
440
      if (c == ',')
441
        {
442
          input_line_pointer++;
443
          SKIP_WHITESPACE ();
444
          if (*input_line_pointer == '\n')
445
            c = '\n';
446
        }
447
    }
448
  while (c == ',');
449
  demand_empty_rest_of_line ();
450
}
451
 
452
static void
453
obj_elf_visibility (int visibility)
454
{
455
  char *name;
456
  int c;
457
  symbolS *symbolP;
458
  asymbol *bfdsym;
459
  elf_symbol_type *elfsym;
460
 
461
  do
462
    {
463
      name = input_line_pointer;
464
      c = get_symbol_end ();
465
      symbolP = symbol_find_or_make (name);
466
      *input_line_pointer = c;
467
 
468
      SKIP_WHITESPACE ();
469
 
470
      bfdsym = symbol_get_bfdsym (symbolP);
471
      elfsym = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym);
472
 
473
      gas_assert (elfsym);
474
 
475
      elfsym->internal_elf_sym.st_other &= ~3;
476
      elfsym->internal_elf_sym.st_other |= visibility;
477
 
478
      if (c == ',')
479
        {
480
          input_line_pointer ++;
481
 
482
          SKIP_WHITESPACE ();
483
 
484
          if (*input_line_pointer == '\n')
485
            c = '\n';
486
        }
487
    }
488
  while (c == ',');
489
 
490
  demand_empty_rest_of_line ();
491
}
492
 
493
static segT previous_section;
494
static int previous_subsection;
495
 
496
struct section_stack
497
{
498
  struct section_stack *next;
499
  segT seg, prev_seg;
500
  int subseg, prev_subseg;
501
};
502
 
503
static struct section_stack *section_stack;
504
 
505
static bfd_boolean
506
get_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf)
507
{
508
  const char *gname = (const char *) inf;
509
  const char *group_name = elf_group_name (sec);
510
 
511
  return (group_name == gname
512
          || (group_name != NULL
513
              && gname != NULL
514
              && strcmp (group_name, gname) == 0));
515
}
516
 
517
/* Handle the .section pseudo-op.  This code supports two different
518
   syntaxes.
519
 
520
   The first is found on Solaris, and looks like
521
       .section ".sec1",#alloc,#execinstr,#write
522
   Here the names after '#' are the SHF_* flags to turn on for the
523
   section.  I'm not sure how it determines the SHT_* type (BFD
524
   doesn't really give us control over the type, anyhow).
525
 
526
   The second format is found on UnixWare, and probably most SVR4
527
   machines, and looks like
528
       .section .sec1,"a",@progbits
529
   The quoted string may contain any combination of a, w, x, and
530
   represents the SHF_* flags to turn on for the section.  The string
531
   beginning with '@' can be progbits or nobits.  There should be
532
   other possibilities, but I don't know what they are.  In any case,
533
   BFD doesn't really let us set the section type.  */
534
 
535
void
536
obj_elf_change_section (const char *name,
537
                        int type,
538
                        bfd_vma attr,
539
                        int entsize,
540
                        const char *group_name,
541
                        int linkonce,
542
                        int push)
543
{
544
  asection *old_sec;
545
  segT sec;
546
  flagword flags;
547
  const struct elf_backend_data *bed;
548
  const struct bfd_elf_special_section *ssect;
549
 
550
#ifdef md_flush_pending_output
551
  md_flush_pending_output ();
552
#endif
553
 
554
  /* Switch to the section, creating it if necessary.  */
555
  if (push)
556
    {
557
      struct section_stack *elt;
558
      elt = (struct section_stack *) xmalloc (sizeof (struct section_stack));
559
      elt->next = section_stack;
560
      elt->seg = now_seg;
561
      elt->prev_seg = previous_section;
562
      elt->subseg = now_subseg;
563
      elt->prev_subseg = previous_subsection;
564
      section_stack = elt;
565
    }
566
  previous_section = now_seg;
567
  previous_subsection = now_subseg;
568
 
569
  old_sec = bfd_get_section_by_name_if (stdoutput, name, get_section,
570
                                        (void *) group_name);
571
  if (old_sec)
572
    {
573
      sec = old_sec;
574
      subseg_set (sec, 0);
575
    }
576
  else
577
    sec = subseg_force_new (name, 0);
578
 
579
  bed = get_elf_backend_data (stdoutput);
580
  ssect = (*bed->get_sec_type_attr) (stdoutput, sec);
581
 
582
  if (ssect != NULL)
583
    {
584
      bfd_boolean override = FALSE;
585
 
586
      if (type == SHT_NULL)
587
        type = ssect->type;
588
      else if (type != ssect->type)
589
        {
590
          if (old_sec == NULL
591
              /* FIXME: gcc, as of 2002-10-22, will emit
592
 
593
                 .section .init_array,"aw",@progbits
594
 
595
                 for __attribute__ ((section (".init_array"))).
596
                 "@progbits" is incorrect.  Also for x86-64 large bss
597
                 sections, gcc, as of 2005-07-06, will emit
598
 
599
                 .section .lbss,"aw",@progbits
600
 
601
                 "@progbits" is incorrect.  */
602
#ifdef TC_I386
603
              && (bed->s->arch_size != 64
604
                  || !(ssect->attr & SHF_X86_64_LARGE))
605
#endif
606
              && ssect->type != SHT_INIT_ARRAY
607
              && ssect->type != SHT_FINI_ARRAY
608
              && ssect->type != SHT_PREINIT_ARRAY)
609
            {
610
              /* We allow to specify any type for a .note section.  */
611
              if (ssect->type != SHT_NOTE)
612
                as_warn (_("setting incorrect section type for %s"),
613
                         name);
614
            }
615
          else
616
            {
617
              as_warn (_("ignoring incorrect section type for %s"),
618
                       name);
619
              type = ssect->type;
620
            }
621
        }
622
 
623
      if (old_sec == NULL && (attr & ~ssect->attr) != 0)
624
        {
625
          /* As a GNU extension, we permit a .note section to be
626
             allocatable.  If the linker sees an allocatable .note
627
             section, it will create a PT_NOTE segment in the output
628
             file.  We also allow "x" for .note.GNU-stack.  */
629
          if (ssect->type == SHT_NOTE
630
              && (attr == SHF_ALLOC || attr == SHF_EXECINSTR))
631
            ;
632
          /* Allow different SHF_MERGE and SHF_STRINGS if we have
633
             something like .rodata.str.  */
634
          else if (ssect->suffix_length == -2
635
                   && name[ssect->prefix_length] == '.'
636
                   && (attr
637
                       & ~ssect->attr
638
                       & ~SHF_MERGE
639
                       & ~SHF_STRINGS) == 0)
640
            ;
641
          /* .interp, .strtab and .symtab can have SHF_ALLOC.  */
642
          else if (attr == SHF_ALLOC
643
                   && (strcmp (name, ".interp") == 0
644
                       || strcmp (name, ".strtab") == 0
645
                       || strcmp (name, ".symtab") == 0))
646
            override = TRUE;
647
          /* .note.GNU-stack can have SHF_EXECINSTR.  */
648
          else if (attr == SHF_EXECINSTR
649
                   && strcmp (name, ".note.GNU-stack") == 0)
650
            override = TRUE;
651
#ifdef TC_ALPHA
652
          /* A section on Alpha may have SHF_ALPHA_GPREL.  */
653
          else if ((attr & ~ssect->attr) == SHF_ALPHA_GPREL)
654
            override = TRUE;
655
#endif
656
          else
657
            {
658
              if (group_name == NULL)
659
                as_warn (_("setting incorrect section attributes for %s"),
660
                         name);
661
              override = TRUE;
662
            }
663
        }
664
      if (!override && old_sec == NULL)
665
        attr |= ssect->attr;
666
    }
667
 
668
  /* Convert ELF type and flags to BFD flags.  */
669
  flags = (SEC_RELOC
670
           | ((attr & SHF_WRITE) ? 0 : SEC_READONLY)
671
           | ((attr & SHF_ALLOC) ? SEC_ALLOC : 0)
672
           | (((attr & SHF_ALLOC) && type != SHT_NOBITS) ? SEC_LOAD : 0)
673
           | ((attr & SHF_EXECINSTR) ? SEC_CODE : 0)
674
           | ((attr & SHF_MERGE) ? SEC_MERGE : 0)
675
           | ((attr & SHF_STRINGS) ? SEC_STRINGS : 0)
676
           | ((attr & SHF_TLS) ? SEC_THREAD_LOCAL : 0));
677
#ifdef md_elf_section_flags
678
  flags = md_elf_section_flags (flags, attr, type);
679
#endif
680
 
681
  if (linkonce)
682
    flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
683
 
684
  if (old_sec == NULL)
685
    {
686
      symbolS *secsym;
687
 
688
      if (type == SHT_NULL)
689
        type = bfd_elf_get_default_section_type (flags);
690
      elf_section_type (sec) = type;
691
      elf_section_flags (sec) = attr;
692
 
693
      /* Prevent SEC_HAS_CONTENTS from being inadvertently set.  */
694
      if (type == SHT_NOBITS)
695
        seg_info (sec)->bss = 1;
696
 
697
      bfd_set_section_flags (stdoutput, sec, flags);
698
      if (flags & SEC_MERGE)
699
        sec->entsize = entsize;
700
      elf_group_name (sec) = group_name;
701
 
702
      /* Add a symbol for this section to the symbol table.  */
703
      secsym = symbol_find (name);
704
      if (secsym != NULL)
705
        symbol_set_bfdsym (secsym, sec->symbol);
706
      else
707
        symbol_table_insert (section_symbol (sec));
708
    }
709
  else
710
    {
711
      if (type != SHT_NULL
712
          && (unsigned) type != elf_section_type (old_sec))
713
        as_warn (_("ignoring changed section type for %s"), name);
714
 
715
      if (attr != 0)
716
        {
717
          /* If section attributes are specified the second time we see a
718
             particular section, then check that they are the same as we
719
             saw the first time.  */
720
          if (((old_sec->flags ^ flags)
721
               & (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
722
                  | SEC_EXCLUDE | SEC_SORT_ENTRIES | SEC_MERGE | SEC_STRINGS
723
                  | SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD
724
                  | SEC_THREAD_LOCAL)))
725
            as_warn (_("ignoring changed section attributes for %s"), name);
726
          if ((flags & SEC_MERGE) && old_sec->entsize != (unsigned) entsize)
727
            as_warn (_("ignoring changed section entity size for %s"), name);
728
        }
729
    }
730
 
731
#ifdef md_elf_section_change_hook
732
  md_elf_section_change_hook ();
733
#endif
734
}
735
 
736
static bfd_vma
737
obj_elf_parse_section_letters (char *str, size_t len)
738
{
739
  bfd_vma attr = 0;
740
 
741
  while (len > 0)
742
    {
743
      switch (*str)
744
        {
745
        case 'a':
746
          attr |= SHF_ALLOC;
747
          break;
748
        case 'w':
749
          attr |= SHF_WRITE;
750
          break;
751
        case 'x':
752
          attr |= SHF_EXECINSTR;
753
          break;
754
        case 'M':
755
          attr |= SHF_MERGE;
756
          break;
757
        case 'S':
758
          attr |= SHF_STRINGS;
759
          break;
760
        case 'G':
761
          attr |= SHF_GROUP;
762
          break;
763
        case 'T':
764
          attr |= SHF_TLS;
765
          break;
766
        /* Compatibility.  */
767
        case 'm':
768
          if (*(str - 1) == 'a')
769
            {
770
              attr |= SHF_MERGE;
771
              if (len > 1 && str[1] == 's')
772
                {
773
                  attr |= SHF_STRINGS;
774
                  str++, len--;
775
                }
776
              break;
777
            }
778
        default:
779
          {
780
            char *bad_msg = _("unrecognized .section attribute: want a,w,x,M,S,G,T");
781
#ifdef md_elf_section_letter
782
            bfd_vma md_attr = md_elf_section_letter (*str, &bad_msg);
783
            if (md_attr > 0)
784
              attr |= md_attr;
785
            else
786
#endif
787
              as_fatal ("%s", bad_msg);
788
          }
789
          break;
790
        }
791
      str++, len--;
792
    }
793
 
794
  return attr;
795
}
796
 
797
static int
798
obj_elf_section_type (char *str, size_t len, bfd_boolean warn)
799
{
800
  if (len == 8 && strncmp (str, "progbits", 8) == 0)
801
    return SHT_PROGBITS;
802
  if (len == 6 && strncmp (str, "nobits", 6) == 0)
803
    return SHT_NOBITS;
804
  if (len == 4 && strncmp (str, "note", 4) == 0)
805
    return SHT_NOTE;
806
  if (len == 10 && strncmp (str, "init_array", 10) == 0)
807
    return SHT_INIT_ARRAY;
808
  if (len == 10 && strncmp (str, "fini_array", 10) == 0)
809
    return SHT_FINI_ARRAY;
810
  if (len == 13 && strncmp (str, "preinit_array", 13) == 0)
811
    return SHT_PREINIT_ARRAY;
812
 
813
#ifdef md_elf_section_type
814
  {
815
    int md_type = md_elf_section_type (str, len);
816
    if (md_type >= 0)
817
      return md_type;
818
  }
819
#endif
820
 
821
  if (warn)
822
    as_warn (_("unrecognized section type"));
823
  return 0;
824
}
825
 
826
static bfd_vma
827
obj_elf_section_word (char *str, size_t len, int *type)
828
{
829
  int ret;
830
 
831
  if (len == 5 && strncmp (str, "write", 5) == 0)
832
    return SHF_WRITE;
833
  if (len == 5 && strncmp (str, "alloc", 5) == 0)
834
    return SHF_ALLOC;
835
  if (len == 9 && strncmp (str, "execinstr", 9) == 0)
836
    return SHF_EXECINSTR;
837
  if (len == 3 && strncmp (str, "tls", 3) == 0)
838
    return SHF_TLS;
839
 
840
#ifdef md_elf_section_word
841
  {
842
    bfd_vma md_attr = md_elf_section_word (str, len);
843
    if (md_attr > 0)
844
      return md_attr;
845
  }
846
#endif
847
 
848
  ret = obj_elf_section_type (str, len, FALSE);
849
  if (ret != 0)
850
    *type = ret;
851
  else
852
    as_warn (_("unrecognized section attribute"));
853
 
854
  return 0;
855
}
856
 
857
/* Get name of section.  */
858
static char *
859
obj_elf_section_name (void)
860
{
861
  char *name;
862
 
863
  SKIP_WHITESPACE ();
864
  if (*input_line_pointer == '"')
865
    {
866
      int dummy;
867
 
868
      name = demand_copy_C_string (&dummy);
869
      if (name == NULL)
870
        {
871
          ignore_rest_of_line ();
872
          return NULL;
873
        }
874
    }
875
  else
876
    {
877
      char *end = input_line_pointer;
878
 
879
      while (0 == strchr ("\n\t,; ", *end))
880
        end++;
881
      if (end == input_line_pointer)
882
        {
883
          as_bad (_("missing name"));
884
          ignore_rest_of_line ();
885
          return NULL;
886
        }
887
 
888
      name = (char *) xmalloc (end - input_line_pointer + 1);
889
      memcpy (name, input_line_pointer, end - input_line_pointer);
890
      name[end - input_line_pointer] = '\0';
891
#ifdef tc_canonicalize_section_name
892
      name = tc_canonicalize_section_name (name);
893
#endif
894
      input_line_pointer = end;
895
    }
896
  SKIP_WHITESPACE ();
897
  return name;
898
}
899
 
900
void
901
obj_elf_section (int push)
902
{
903
  char *name, *group_name, *beg;
904
  int type, dummy;
905
  bfd_vma attr;
906
  int entsize;
907
  int linkonce;
908
  subsegT new_subsection = -1;
909
 
910
#ifndef TC_I370
911
  if (flag_mri)
912
    {
913
      char mri_type;
914
 
915
#ifdef md_flush_pending_output
916
      md_flush_pending_output ();
917
#endif
918
 
919
      previous_section = now_seg;
920
      previous_subsection = now_subseg;
921
 
922
      s_mri_sect (&mri_type);
923
 
924
#ifdef md_elf_section_change_hook
925
      md_elf_section_change_hook ();
926
#endif
927
 
928
      return;
929
    }
930
#endif /* ! defined (TC_I370) */
931
 
932
  name = obj_elf_section_name ();
933
  if (name == NULL)
934
    return;
935
  type = SHT_NULL;
936
  attr = 0;
937
  group_name = NULL;
938
  entsize = 0;
939
  linkonce = 0;
940
 
941
  if (*input_line_pointer == ',')
942
    {
943
      /* Skip the comma.  */
944
      ++input_line_pointer;
945
      SKIP_WHITESPACE ();
946
 
947
      if (push && ISDIGIT (*input_line_pointer))
948
        {
949
          /* .pushsection has an optional subsection.  */
950
          new_subsection = (subsegT) get_absolute_expression ();
951
 
952
          SKIP_WHITESPACE ();
953
 
954
          /* Stop if we don't see a comma.  */
955
          if (*input_line_pointer != ',')
956
            goto done;
957
 
958
          /* Skip the comma.  */
959
          ++input_line_pointer;
960
          SKIP_WHITESPACE ();
961
        }
962
 
963
      if (*input_line_pointer == '"')
964
        {
965
          beg = demand_copy_C_string (&dummy);
966
          if (beg == NULL)
967
            {
968
              ignore_rest_of_line ();
969
              return;
970
            }
971
          attr |= obj_elf_parse_section_letters (beg, strlen (beg));
972
 
973
          SKIP_WHITESPACE ();
974
          if (*input_line_pointer == ',')
975
            {
976
              char c;
977
              char *save = input_line_pointer;
978
 
979
              ++input_line_pointer;
980
              SKIP_WHITESPACE ();
981
              c = *input_line_pointer;
982
              if (c == '"')
983
                {
984
                  beg = demand_copy_C_string (&dummy);
985
                  if (beg == NULL)
986
                    {
987
                      ignore_rest_of_line ();
988
                      return;
989
                    }
990
                  type = obj_elf_section_type (beg, strlen (beg), TRUE);
991
                }
992
              else if (c == '@' || c == '%')
993
                {
994
                  beg = ++input_line_pointer;
995
                  c = get_symbol_end ();
996
                  *input_line_pointer = c;
997
                  type = obj_elf_section_type (beg, input_line_pointer - beg, TRUE);
998
                }
999
              else
1000
                input_line_pointer = save;
1001
            }
1002
 
1003
          SKIP_WHITESPACE ();
1004
          if ((attr & SHF_MERGE) != 0 && *input_line_pointer == ',')
1005
            {
1006
              ++input_line_pointer;
1007
              SKIP_WHITESPACE ();
1008
              entsize = get_absolute_expression ();
1009
              SKIP_WHITESPACE ();
1010
              if (entsize < 0)
1011
                {
1012
                  as_warn (_("invalid merge entity size"));
1013
                  attr &= ~SHF_MERGE;
1014
                  entsize = 0;
1015
                }
1016
            }
1017
          else if ((attr & SHF_MERGE) != 0)
1018
            {
1019
              as_warn (_("entity size for SHF_MERGE not specified"));
1020
              attr &= ~SHF_MERGE;
1021
            }
1022
 
1023
          if ((attr & SHF_GROUP) != 0 && *input_line_pointer == ',')
1024
            {
1025
              ++input_line_pointer;
1026
              group_name = obj_elf_section_name ();
1027
              if (group_name == NULL)
1028
                attr &= ~SHF_GROUP;
1029
              else if (strncmp (input_line_pointer, ",comdat", 7) == 0)
1030
                {
1031
                  input_line_pointer += 7;
1032
                  linkonce = 1;
1033
                }
1034
              else if (strncmp (name, ".gnu.linkonce", 13) == 0)
1035
                linkonce = 1;
1036
            }
1037
          else if ((attr & SHF_GROUP) != 0)
1038
            {
1039
              as_warn (_("group name for SHF_GROUP not specified"));
1040
              attr &= ~SHF_GROUP;
1041
            }
1042
        }
1043
      else
1044
        {
1045
          do
1046
            {
1047
              char c;
1048
 
1049
              SKIP_WHITESPACE ();
1050
              if (*input_line_pointer != '#')
1051
                {
1052
                  as_bad (_("character following name is not '#'"));
1053
                  ignore_rest_of_line ();
1054
                  return;
1055
                }
1056
              beg = ++input_line_pointer;
1057
              c = get_symbol_end ();
1058
              *input_line_pointer = c;
1059
 
1060
              attr |= obj_elf_section_word (beg, input_line_pointer - beg, & type);
1061
 
1062
              SKIP_WHITESPACE ();
1063
            }
1064
          while (*input_line_pointer++ == ',');
1065
          --input_line_pointer;
1066
        }
1067
    }
1068
 
1069
done:
1070
  demand_empty_rest_of_line ();
1071
 
1072
  obj_elf_change_section (name, type, attr, entsize, group_name, linkonce, push);
1073
 
1074
  if (push && new_subsection != -1)
1075
    subseg_set (now_seg, new_subsection);
1076
}
1077
 
1078
/* Change to the .data section.  */
1079
 
1080
void
1081
obj_elf_data (int i)
1082
{
1083
#ifdef md_flush_pending_output
1084
  md_flush_pending_output ();
1085
#endif
1086
 
1087
  previous_section = now_seg;
1088
  previous_subsection = now_subseg;
1089
  s_data (i);
1090
 
1091
#ifdef md_elf_section_change_hook
1092
  md_elf_section_change_hook ();
1093
#endif
1094
}
1095
 
1096
/* Change to the .text section.  */
1097
 
1098
void
1099
obj_elf_text (int i)
1100
{
1101
#ifdef md_flush_pending_output
1102
  md_flush_pending_output ();
1103
#endif
1104
 
1105
  previous_section = now_seg;
1106
  previous_subsection = now_subseg;
1107
  s_text (i);
1108
 
1109
#ifdef md_elf_section_change_hook
1110
  md_elf_section_change_hook ();
1111
#endif
1112
}
1113
 
1114
/* Change to the *ABS* section.  */
1115
 
1116
void
1117
obj_elf_struct (int i)
1118
{
1119
#ifdef md_flush_pending_output
1120
  md_flush_pending_output ();
1121
#endif
1122
 
1123
  previous_section = now_seg;
1124
  previous_subsection = now_subseg;
1125
  s_struct (i);
1126
 
1127
#ifdef md_elf_section_change_hook
1128
  md_elf_section_change_hook ();
1129
#endif
1130
}
1131
 
1132
static void
1133
obj_elf_subsection (int ignore ATTRIBUTE_UNUSED)
1134
{
1135
  int temp;
1136
 
1137
#ifdef md_flush_pending_output
1138
  md_flush_pending_output ();
1139
#endif
1140
 
1141
  previous_section = now_seg;
1142
  previous_subsection = now_subseg;
1143
 
1144
  temp = get_absolute_expression ();
1145
  subseg_set (now_seg, (subsegT) temp);
1146
  demand_empty_rest_of_line ();
1147
 
1148
#ifdef md_elf_section_change_hook
1149
  md_elf_section_change_hook ();
1150
#endif
1151
}
1152
 
1153
/* This can be called from the processor backends if they change
1154
   sections.  */
1155
 
1156
void
1157
obj_elf_section_change_hook (void)
1158
{
1159
  previous_section = now_seg;
1160
  previous_subsection = now_subseg;
1161
}
1162
 
1163
void
1164
obj_elf_previous (int ignore ATTRIBUTE_UNUSED)
1165
{
1166
  segT new_section;
1167
  int new_subsection;
1168
 
1169
  if (previous_section == 0)
1170
    {
1171
      as_warn (_(".previous without corresponding .section; ignored"));
1172
      return;
1173
    }
1174
 
1175
#ifdef md_flush_pending_output
1176
  md_flush_pending_output ();
1177
#endif
1178
 
1179
  new_section = previous_section;
1180
  new_subsection = previous_subsection;
1181
  previous_section = now_seg;
1182
  previous_subsection = now_subseg;
1183
  subseg_set (new_section, new_subsection);
1184
 
1185
#ifdef md_elf_section_change_hook
1186
  md_elf_section_change_hook ();
1187
#endif
1188
}
1189
 
1190
static void
1191
obj_elf_popsection (int xxx ATTRIBUTE_UNUSED)
1192
{
1193
  struct section_stack *top = section_stack;
1194
 
1195
  if (top == NULL)
1196
    {
1197
      as_warn (_(".popsection without corresponding .pushsection; ignored"));
1198
      return;
1199
    }
1200
 
1201
#ifdef md_flush_pending_output
1202
  md_flush_pending_output ();
1203
#endif
1204
 
1205
  section_stack = top->next;
1206
  previous_section = top->prev_seg;
1207
  previous_subsection = top->prev_subseg;
1208
  subseg_set (top->seg, top->subseg);
1209
  free (top);
1210
 
1211
#ifdef md_elf_section_change_hook
1212
  md_elf_section_change_hook ();
1213
#endif
1214
}
1215
 
1216
static void
1217
obj_elf_line (int ignore ATTRIBUTE_UNUSED)
1218
{
1219
  /* Assume delimiter is part of expression.  BSD4.2 as fails with
1220
     delightful bug, so we are not being incompatible here.  */
1221
  new_logical_line (NULL, get_absolute_expression ());
1222
  demand_empty_rest_of_line ();
1223
}
1224
 
1225
/* This handles the .symver pseudo-op, which is used to specify a
1226
   symbol version.  The syntax is ``.symver NAME,SYMVERNAME''.
1227
   SYMVERNAME may contain ELF_VER_CHR ('@') characters.  This
1228
   pseudo-op causes the assembler to emit a symbol named SYMVERNAME
1229
   with the same value as the symbol NAME.  */
1230
 
1231
static void
1232
obj_elf_symver (int ignore ATTRIBUTE_UNUSED)
1233
{
1234
  char *name;
1235
  char c;
1236
  char old_lexat;
1237
  symbolS *sym;
1238
 
1239
  name = input_line_pointer;
1240
  c = get_symbol_end ();
1241
 
1242
  sym = symbol_find_or_make (name);
1243
 
1244
  *input_line_pointer = c;
1245
 
1246
  SKIP_WHITESPACE ();
1247
  if (*input_line_pointer != ',')
1248
    {
1249
      as_bad (_("expected comma after name in .symver"));
1250
      ignore_rest_of_line ();
1251
      return;
1252
    }
1253
 
1254
  ++input_line_pointer;
1255
  SKIP_WHITESPACE ();
1256
  name = input_line_pointer;
1257
 
1258
  /* Temporarily include '@' in symbol names.  */
1259
  old_lexat = lex_type[(unsigned char) '@'];
1260
  lex_type[(unsigned char) '@'] |= LEX_NAME;
1261
  c = get_symbol_end ();
1262
  lex_type[(unsigned char) '@'] = old_lexat;
1263
 
1264
  if (symbol_get_obj (sym)->versioned_name == NULL)
1265
    {
1266
      symbol_get_obj (sym)->versioned_name = xstrdup (name);
1267
 
1268
      *input_line_pointer = c;
1269
 
1270
      if (strchr (symbol_get_obj (sym)->versioned_name,
1271
                  ELF_VER_CHR) == NULL)
1272
        {
1273
          as_bad (_("missing version name in `%s' for symbol `%s'"),
1274
                  symbol_get_obj (sym)->versioned_name,
1275
                  S_GET_NAME (sym));
1276
          ignore_rest_of_line ();
1277
          return;
1278
        }
1279
    }
1280
  else
1281
    {
1282
      if (strcmp (symbol_get_obj (sym)->versioned_name, name))
1283
        {
1284
          as_bad (_("multiple versions [`%s'|`%s'] for symbol `%s'"),
1285
                  name, symbol_get_obj (sym)->versioned_name,
1286
                  S_GET_NAME (sym));
1287
          ignore_rest_of_line ();
1288
          return;
1289
        }
1290
 
1291
      *input_line_pointer = c;
1292
    }
1293
 
1294
  demand_empty_rest_of_line ();
1295
}
1296
 
1297
/* This handles the .vtable_inherit pseudo-op, which is used to indicate
1298
   to the linker the hierarchy in which a particular table resides.  The
1299
   syntax is ".vtable_inherit CHILDNAME, PARENTNAME".  */
1300
 
1301
struct fix *
1302
obj_elf_vtable_inherit (int ignore ATTRIBUTE_UNUSED)
1303
{
1304
  char *cname, *pname;
1305
  symbolS *csym, *psym;
1306
  char c, bad = 0;
1307
 
1308
  if (*input_line_pointer == '#')
1309
    ++input_line_pointer;
1310
 
1311
  cname = input_line_pointer;
1312
  c = get_symbol_end ();
1313
  csym = symbol_find (cname);
1314
 
1315
  /* GCFIXME: should check that we don't have two .vtable_inherits for
1316
     the same child symbol.  Also, we can currently only do this if the
1317
     child symbol is already exists and is placed in a fragment.  */
1318
 
1319
  if (csym == NULL || symbol_get_frag (csym) == NULL)
1320
    {
1321
      as_bad (_("expected `%s' to have already been set for .vtable_inherit"),
1322
              cname);
1323
      bad = 1;
1324
    }
1325
 
1326
  *input_line_pointer = c;
1327
 
1328
  SKIP_WHITESPACE ();
1329
  if (*input_line_pointer != ',')
1330
    {
1331
      as_bad (_("expected comma after name in .vtable_inherit"));
1332
      ignore_rest_of_line ();
1333
      return NULL;
1334
    }
1335
 
1336
  ++input_line_pointer;
1337
  SKIP_WHITESPACE ();
1338
 
1339
  if (*input_line_pointer == '#')
1340
    ++input_line_pointer;
1341
 
1342
  if (input_line_pointer[0] == '0'
1343
      && (input_line_pointer[1] == '\0'
1344
          || ISSPACE (input_line_pointer[1])))
1345
    {
1346
      psym = section_symbol (absolute_section);
1347
      ++input_line_pointer;
1348
    }
1349
  else
1350
    {
1351
      pname = input_line_pointer;
1352
      c = get_symbol_end ();
1353
      psym = symbol_find_or_make (pname);
1354
      *input_line_pointer = c;
1355
    }
1356
 
1357
  demand_empty_rest_of_line ();
1358
 
1359
  if (bad)
1360
    return NULL;
1361
 
1362
  gas_assert (symbol_get_value_expression (csym)->X_op == O_constant);
1363
  return fix_new (symbol_get_frag (csym),
1364
                  symbol_get_value_expression (csym)->X_add_number,
1365
                  0, psym, 0, 0, BFD_RELOC_VTABLE_INHERIT);
1366
}
1367
 
1368
/* This handles the .vtable_entry pseudo-op, which is used to indicate
1369
   to the linker that a vtable slot was used.  The syntax is
1370
   ".vtable_entry tablename, offset".  */
1371
 
1372
struct fix *
1373
obj_elf_vtable_entry (int ignore ATTRIBUTE_UNUSED)
1374
{
1375
  char *name;
1376
  symbolS *sym;
1377
  offsetT offset;
1378
  char c;
1379
 
1380
  if (*input_line_pointer == '#')
1381
    ++input_line_pointer;
1382
 
1383
  name = input_line_pointer;
1384
  c = get_symbol_end ();
1385
  sym = symbol_find_or_make (name);
1386
  *input_line_pointer = c;
1387
 
1388
  SKIP_WHITESPACE ();
1389
  if (*input_line_pointer != ',')
1390
    {
1391
      as_bad (_("expected comma after name in .vtable_entry"));
1392
      ignore_rest_of_line ();
1393
      return NULL;
1394
    }
1395
 
1396
  ++input_line_pointer;
1397
  if (*input_line_pointer == '#')
1398
    ++input_line_pointer;
1399
 
1400
  offset = get_absolute_expression ();
1401
 
1402
  demand_empty_rest_of_line ();
1403
 
1404
  return fix_new (frag_now, frag_now_fix (), 0, sym, offset, 0,
1405
                  BFD_RELOC_VTABLE_ENTRY);
1406
}
1407
 
1408
void
1409
elf_obj_read_begin_hook (void)
1410
{
1411
#ifdef NEED_ECOFF_DEBUG
1412
  if (ECOFF_DEBUGGING)
1413
    ecoff_read_begin_hook ();
1414
#endif
1415
}
1416
 
1417
void
1418
elf_obj_symbol_new_hook (symbolS *symbolP)
1419
{
1420
  struct elf_obj_sy *sy_obj;
1421
 
1422
  sy_obj = symbol_get_obj (symbolP);
1423
  sy_obj->size = NULL;
1424
  sy_obj->versioned_name = NULL;
1425
 
1426
#ifdef NEED_ECOFF_DEBUG
1427
  if (ECOFF_DEBUGGING)
1428
    ecoff_symbol_new_hook (symbolP);
1429
#endif
1430
}
1431
 
1432
/* When setting one symbol equal to another, by default we probably
1433
   want them to have the same "size", whatever it means in the current
1434
   context.  */
1435
 
1436
void
1437
elf_copy_symbol_attributes (symbolS *dest, symbolS *src)
1438
{
1439
  struct elf_obj_sy *srcelf = symbol_get_obj (src);
1440
  struct elf_obj_sy *destelf = symbol_get_obj (dest);
1441
  if (srcelf->size)
1442
    {
1443
      if (destelf->size == NULL)
1444
        destelf->size = (expressionS *) xmalloc (sizeof (expressionS));
1445
      *destelf->size = *srcelf->size;
1446
    }
1447
  else
1448
    {
1449
      if (destelf->size != NULL)
1450
        free (destelf->size);
1451
      destelf->size = NULL;
1452
    }
1453
  S_SET_SIZE (dest, S_GET_SIZE (src));
1454
  /* Don't copy visibility.  */
1455
  S_SET_OTHER (dest, (ELF_ST_VISIBILITY (S_GET_OTHER (dest))
1456
                      | (S_GET_OTHER (src) & ~ELF_ST_VISIBILITY (-1))));
1457
}
1458
 
1459
void
1460
obj_elf_version (int ignore ATTRIBUTE_UNUSED)
1461
{
1462
  char *name;
1463
  unsigned int c;
1464
  char *p;
1465
  asection *seg = now_seg;
1466
  subsegT subseg = now_subseg;
1467
  Elf_Internal_Note i_note;
1468
  Elf_External_Note e_note;
1469
  asection *note_secp = NULL;
1470
 
1471
  SKIP_WHITESPACE ();
1472
  if (*input_line_pointer == '\"')
1473
    {
1474
      unsigned int len;
1475
 
1476
      ++input_line_pointer;     /* -> 1st char of string.  */
1477
      name = input_line_pointer;
1478
 
1479
      while (is_a_char (c = next_char_of_string ()))
1480
        ;
1481
      c = *input_line_pointer;
1482
      *input_line_pointer = '\0';
1483
      *(input_line_pointer - 1) = '\0';
1484
      *input_line_pointer = c;
1485
 
1486
      /* Create the .note section.  */
1487
      note_secp = subseg_new (".note", 0);
1488
      bfd_set_section_flags (stdoutput,
1489
                             note_secp,
1490
                             SEC_HAS_CONTENTS | SEC_READONLY);
1491
 
1492
      /* Process the version string.  */
1493
      len = strlen (name) + 1;
1494
 
1495
      /* PR 3456: Although the name field is padded out to an 4-byte
1496
         boundary, the namesz field should not be adjusted.  */
1497
      i_note.namesz = len;
1498
      i_note.descsz = 0; /* No description.  */
1499
      i_note.type = NT_VERSION;
1500
      p = frag_more (sizeof (e_note.namesz));
1501
      md_number_to_chars (p, i_note.namesz, sizeof (e_note.namesz));
1502
      p = frag_more (sizeof (e_note.descsz));
1503
      md_number_to_chars (p, i_note.descsz, sizeof (e_note.descsz));
1504
      p = frag_more (sizeof (e_note.type));
1505
      md_number_to_chars (p, i_note.type, sizeof (e_note.type));
1506
      p = frag_more (len);
1507
      memcpy (p, name, len);
1508
 
1509
      frag_align (2, 0, 0);
1510
 
1511
      subseg_set (seg, subseg);
1512
    }
1513
  else
1514
    as_bad (_("expected quoted string"));
1515
 
1516
  demand_empty_rest_of_line ();
1517
}
1518
 
1519
static void
1520
obj_elf_size (int ignore ATTRIBUTE_UNUSED)
1521
{
1522
  char *name = input_line_pointer;
1523
  char c = get_symbol_end ();
1524
  char *p;
1525
  expressionS exp;
1526
  symbolS *sym;
1527
 
1528
  p = input_line_pointer;
1529
  *p = c;
1530
  SKIP_WHITESPACE ();
1531
  if (*input_line_pointer != ',')
1532
    {
1533
      *p = 0;
1534
      as_bad (_("expected comma after name `%s' in .size directive"), name);
1535
      *p = c;
1536
      ignore_rest_of_line ();
1537
      return;
1538
    }
1539
  input_line_pointer++;
1540
  expression (&exp);
1541
  if (exp.X_op == O_absent)
1542
    {
1543
      as_bad (_("missing expression in .size directive"));
1544
      exp.X_op = O_constant;
1545
      exp.X_add_number = 0;
1546
    }
1547
  *p = 0;
1548
  sym = symbol_find_or_make (name);
1549
  *p = c;
1550
  if (exp.X_op == O_constant)
1551
    {
1552
      S_SET_SIZE (sym, exp.X_add_number);
1553
      if (symbol_get_obj (sym)->size)
1554
        {
1555
          xfree (symbol_get_obj (sym)->size);
1556
          symbol_get_obj (sym)->size = NULL;
1557
        }
1558
    }
1559
  else
1560
    {
1561
      symbol_get_obj (sym)->size =
1562
          (expressionS *) xmalloc (sizeof (expressionS));
1563
      *symbol_get_obj (sym)->size = exp;
1564
    }
1565
  demand_empty_rest_of_line ();
1566
}
1567
 
1568
/* Handle the ELF .type pseudo-op.  This sets the type of a symbol.
1569
   There are six syntaxes:
1570
 
1571
   The first (used on Solaris) is
1572
       .type SYM,#function
1573
   The second (used on UnixWare) is
1574
       .type SYM,@function
1575
   The third (reportedly to be used on Irix 6.0) is
1576
       .type SYM STT_FUNC
1577
   The fourth (used on NetBSD/Arm and Linux/ARM) is
1578
       .type SYM,%function
1579
   The fifth (used on SVR4/860) is
1580
       .type SYM,"function"
1581
   The sixth (emitted by recent SunPRO under Solaris) is
1582
       .type SYM,[0-9]
1583
   where the integer is the STT_* value.
1584
   */
1585
 
1586
static char *
1587
obj_elf_type_name (char *cp)
1588
{
1589
  char *p;
1590
 
1591
  p = input_line_pointer;
1592
  if (*input_line_pointer >= '0'
1593
      && *input_line_pointer <= '9')
1594
    {
1595
      while (*input_line_pointer >= '0'
1596
             && *input_line_pointer <= '9')
1597
        ++input_line_pointer;
1598
      *cp = *input_line_pointer;
1599
      *input_line_pointer = '\0';
1600
    }
1601
  else
1602
    *cp = get_symbol_end ();
1603
 
1604
  return p;
1605
}
1606
 
1607
static void
1608
obj_elf_type (int ignore ATTRIBUTE_UNUSED)
1609
{
1610
  char *name;
1611
  char c;
1612
  int type;
1613
  const char *type_name;
1614
  symbolS *sym;
1615
  elf_symbol_type *elfsym;
1616
 
1617
  name = input_line_pointer;
1618
  c = get_symbol_end ();
1619
  sym = symbol_find_or_make (name);
1620
  elfsym = (elf_symbol_type *) symbol_get_bfdsym (sym);
1621
  *input_line_pointer = c;
1622
 
1623
  SKIP_WHITESPACE ();
1624
  if (*input_line_pointer == ',')
1625
    ++input_line_pointer;
1626
 
1627
  SKIP_WHITESPACE ();
1628
  if (   *input_line_pointer == '#'
1629
      || *input_line_pointer == '@'
1630
      || *input_line_pointer == '"'
1631
      || *input_line_pointer == '%')
1632
    ++input_line_pointer;
1633
 
1634
  type_name = obj_elf_type_name (& c);
1635
 
1636
  type = 0;
1637
  if (strcmp (type_name, "function") == 0
1638
      || strcmp (type_name, "2") == 0
1639
      || strcmp (type_name, "STT_FUNC") == 0)
1640
    type = BSF_FUNCTION;
1641
  else if (strcmp (type_name, "object") == 0
1642
           || strcmp (type_name, "1") == 0
1643
           || strcmp (type_name, "STT_OBJECT") == 0)
1644
    type = BSF_OBJECT;
1645
  else if (strcmp (type_name, "tls_object") == 0
1646
           || strcmp (type_name, "6") == 0
1647
           || strcmp (type_name, "STT_TLS") == 0)
1648
    type = BSF_OBJECT | BSF_THREAD_LOCAL;
1649
  else if (strcmp (type_name, "notype") == 0
1650
           || strcmp (type_name, "0") == 0
1651
           || strcmp (type_name, "STT_NOTYPE") == 0)
1652
    ;
1653
  else if (strcmp (type_name, "common") == 0
1654
           || strcmp (type_name, "5") == 0
1655
           || strcmp (type_name, "STT_COMMON") == 0)
1656
    {
1657
      type = BSF_OBJECT;
1658
 
1659
      if (! S_IS_COMMON (sym))
1660
        {
1661
          if (S_IS_VOLATILE (sym))
1662
            {
1663
              sym = symbol_clone (sym, 1);
1664
              S_SET_SEGMENT (sym, bfd_com_section_ptr);
1665
              S_SET_VALUE (sym, 0);
1666
              S_SET_EXTERNAL (sym);
1667
              symbol_set_frag (sym, &zero_address_frag);
1668
              S_CLEAR_VOLATILE (sym);
1669
            }
1670
          else if (S_IS_DEFINED (sym) || symbol_equated_p (sym))
1671
            as_bad (_("symbol '%s' is already defined"), S_GET_NAME (sym));
1672
          else
1673
            {
1674
              /* FIXME: Is it safe to just change the section ?  */
1675
              S_SET_SEGMENT (sym, bfd_com_section_ptr);
1676
              S_SET_VALUE (sym, 0);
1677
              S_SET_EXTERNAL (sym);
1678
            }
1679
        }
1680
    }
1681
  else if (strcmp (type_name, "gnu_indirect_function") == 0
1682
           || strcmp (type_name, "10") == 0
1683
           || strcmp (type_name, "STT_GNU_IFUNC") == 0)
1684
    {
1685
      const struct elf_backend_data *bed;
1686
 
1687
      bed = get_elf_backend_data (stdoutput);
1688
      if (!(bed->elf_osabi == ELFOSABI_LINUX
1689
            /* GNU/Linux is still using the default value 0.  */
1690
            || bed->elf_osabi == ELFOSABI_NONE))
1691
        as_bad (_("symbol type \"%s\" is supported only by GNU targets"),
1692
                type_name);
1693
      type = BSF_FUNCTION | BSF_GNU_INDIRECT_FUNCTION;
1694
    }
1695
  else if (strcmp (type_name, "gnu_unique_object") == 0)
1696
    {
1697
      struct elf_backend_data *bed;
1698
 
1699
      bed = (struct elf_backend_data *) get_elf_backend_data (stdoutput);
1700
      if (!(bed->elf_osabi == ELFOSABI_LINUX
1701
            /* GNU/Linux is still using the default value 0.  */
1702
            || bed->elf_osabi == ELFOSABI_NONE))
1703
        as_bad (_("symbol type \"%s\" is supported only by GNU targets"),
1704
                type_name);
1705
      type = BSF_OBJECT | BSF_GNU_UNIQUE;
1706
      /* PR 10549: Always set OSABI field to LINUX for objects containing unique symbols.  */
1707
      bed->elf_osabi = ELFOSABI_LINUX;
1708
    }
1709
#ifdef md_elf_symbol_type
1710
  else if ((type = md_elf_symbol_type (type_name, sym, elfsym)) != -1)
1711
    ;
1712
#endif
1713
  else
1714
    as_bad (_("unrecognized symbol type \"%s\""), type_name);
1715
 
1716
  *input_line_pointer = c;
1717
 
1718
  if (*input_line_pointer == '"')
1719
    ++input_line_pointer;
1720
 
1721
  elfsym->symbol.flags |= type;
1722
 
1723
  demand_empty_rest_of_line ();
1724
}
1725
 
1726
static void
1727
obj_elf_ident (int ignore ATTRIBUTE_UNUSED)
1728
{
1729
  static segT comment_section;
1730
  segT old_section = now_seg;
1731
  int old_subsection = now_subseg;
1732
 
1733
#ifdef md_flush_pending_output
1734
  md_flush_pending_output ();
1735
#endif
1736
 
1737
  if (!comment_section)
1738
    {
1739
      char *p;
1740
      comment_section = subseg_new (".comment", 0);
1741
      bfd_set_section_flags (stdoutput, comment_section,
1742
                             SEC_READONLY | SEC_HAS_CONTENTS
1743
                             | SEC_MERGE | SEC_STRINGS);
1744
      comment_section->entsize = 1;
1745
#ifdef md_elf_section_change_hook
1746
      md_elf_section_change_hook ();
1747
#endif
1748
      p = frag_more (1);
1749
      *p = 0;
1750
    }
1751
  else
1752
    subseg_set (comment_section, 0);
1753
  stringer (8 + 1);
1754
  subseg_set (old_section, old_subsection);
1755
}
1756
 
1757
#ifdef INIT_STAB_SECTION
1758
 
1759
/* The first entry in a .stabs section is special.  */
1760
 
1761
void
1762
obj_elf_init_stab_section (segT seg)
1763
{
1764
  char *file;
1765
  char *p;
1766
  char *stabstr_name;
1767
  unsigned int stroff;
1768
 
1769
  /* Force the section to align to a longword boundary.  Without this,
1770
     UnixWare ar crashes.  */
1771
  bfd_set_section_alignment (stdoutput, seg, 2);
1772
 
1773
  /* Make space for this first symbol.  */
1774
  p = frag_more (12);
1775
  /* Zero it out.  */
1776
  memset (p, 0, 12);
1777
  as_where (&file, NULL);
1778
  stabstr_name = (char *) xmalloc (strlen (segment_name (seg)) + 4);
1779
  strcpy (stabstr_name, segment_name (seg));
1780
  strcat (stabstr_name, "str");
1781
  stroff = get_stab_string_offset (file, stabstr_name);
1782
  know (stroff == 1);
1783
  md_number_to_chars (p, stroff, 4);
1784
  seg_info (seg)->stabu.p = p;
1785
}
1786
 
1787
#endif
1788
 
1789
/* Fill in the counts in the first entry in a .stabs section.  */
1790
 
1791
static void
1792
adjust_stab_sections (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED)
1793
{
1794
  char *name;
1795
  asection *strsec;
1796
  char *p;
1797
  int strsz, nsyms;
1798
 
1799
  if (strncmp (".stab", sec->name, 5))
1800
    return;
1801
  if (!strcmp ("str", sec->name + strlen (sec->name) - 3))
1802
    return;
1803
 
1804
  name = (char *) alloca (strlen (sec->name) + 4);
1805
  strcpy (name, sec->name);
1806
  strcat (name, "str");
1807
  strsec = bfd_get_section_by_name (abfd, name);
1808
  if (strsec)
1809
    strsz = bfd_section_size (abfd, strsec);
1810
  else
1811
    strsz = 0;
1812
  nsyms = bfd_section_size (abfd, sec) / 12 - 1;
1813
 
1814
  p = seg_info (sec)->stabu.p;
1815
  gas_assert (p != 0);
1816
 
1817
  bfd_h_put_16 (abfd, nsyms, p + 6);
1818
  bfd_h_put_32 (abfd, strsz, p + 8);
1819
}
1820
 
1821
#ifdef NEED_ECOFF_DEBUG
1822
 
1823
/* This function is called by the ECOFF code.  It is supposed to
1824
   record the external symbol information so that the backend can
1825
   write it out correctly.  The ELF backend doesn't actually handle
1826
   this at the moment, so we do it ourselves.  We save the information
1827
   in the symbol.  */
1828
 
1829
#ifdef OBJ_MAYBE_ELF
1830
static
1831
#endif
1832
void
1833
elf_ecoff_set_ext (symbolS *sym, struct ecoff_extr *ext)
1834
{
1835
  symbol_get_bfdsym (sym)->udata.p = ext;
1836
}
1837
 
1838
/* This function is called by bfd_ecoff_debug_externals.  It is
1839
   supposed to *EXT to the external symbol information, and return
1840
   whether the symbol should be used at all.  */
1841
 
1842
static bfd_boolean
1843
elf_get_extr (asymbol *sym, EXTR *ext)
1844
{
1845
  if (sym->udata.p == NULL)
1846
    return FALSE;
1847
  *ext = *(EXTR *) sym->udata.p;
1848
  return TRUE;
1849
}
1850
 
1851
/* This function is called by bfd_ecoff_debug_externals.  It has
1852
   nothing to do for ELF.  */
1853
 
1854
static void
1855
elf_set_index (asymbol *sym ATTRIBUTE_UNUSED,
1856
               bfd_size_type indx ATTRIBUTE_UNUSED)
1857
{
1858
}
1859
 
1860
#endif /* NEED_ECOFF_DEBUG */
1861
 
1862
void
1863
elf_frob_symbol (symbolS *symp, int *puntp)
1864
{
1865
  struct elf_obj_sy *sy_obj;
1866
 
1867
#ifdef NEED_ECOFF_DEBUG
1868
  if (ECOFF_DEBUGGING)
1869
    ecoff_frob_symbol (symp);
1870
#endif
1871
 
1872
  sy_obj = symbol_get_obj (symp);
1873
 
1874
  if (sy_obj->size != NULL)
1875
    {
1876
      switch (sy_obj->size->X_op)
1877
        {
1878
        case O_subtract:
1879
          S_SET_SIZE (symp,
1880
                      (S_GET_VALUE (sy_obj->size->X_add_symbol)
1881
                       + sy_obj->size->X_add_number
1882
                       - S_GET_VALUE (sy_obj->size->X_op_symbol)));
1883
          break;
1884
        case O_constant:
1885
          S_SET_SIZE (symp,
1886
                      (S_GET_VALUE (sy_obj->size->X_add_symbol)
1887
                       + sy_obj->size->X_add_number));
1888
          break;
1889
        default:
1890
          as_bad (_(".size expression too complicated to fix up"));
1891
          break;
1892
        }
1893
      free (sy_obj->size);
1894
      sy_obj->size = NULL;
1895
    }
1896
 
1897
  if (sy_obj->versioned_name != NULL)
1898
    {
1899
      char *p;
1900
 
1901
      p = strchr (sy_obj->versioned_name, ELF_VER_CHR);
1902
      know (p != NULL);
1903
 
1904
      /* This symbol was given a new name with the .symver directive.
1905
 
1906
         If this is an external reference, just rename the symbol to
1907
         include the version string.  This will make the relocs be
1908
         against the correct versioned symbol.
1909
 
1910
         If this is a definition, add an alias.  FIXME: Using an alias
1911
         will permit the debugging information to refer to the right
1912
         symbol.  However, it's not clear whether it is the best
1913
         approach.  */
1914
 
1915
      if (! S_IS_DEFINED (symp))
1916
        {
1917
          /* Verify that the name isn't using the @@ syntax--this is
1918
             reserved for definitions of the default version to link
1919
             against.  */
1920
          if (p[1] == ELF_VER_CHR)
1921
            {
1922
              as_bad (_("invalid attempt to declare external version name as default in symbol `%s'"),
1923
                      sy_obj->versioned_name);
1924
              *puntp = TRUE;
1925
            }
1926
          S_SET_NAME (symp, sy_obj->versioned_name);
1927
        }
1928
      else
1929
        {
1930
          if (p[1] == ELF_VER_CHR && p[2] == ELF_VER_CHR)
1931
            {
1932
              size_t l;
1933
 
1934
              /* The @@@ syntax is a special case. It renames the
1935
                 symbol name to versioned_name with one `@' removed.  */
1936
              l = strlen (&p[3]) + 1;
1937
              memmove (&p[2], &p[3], l);
1938
              S_SET_NAME (symp, sy_obj->versioned_name);
1939
            }
1940
          else
1941
            {
1942
              symbolS *symp2;
1943
 
1944
              /* FIXME: Creating a new symbol here is risky.  We're
1945
                 in the final loop over the symbol table.  We can
1946
                 get away with it only because the symbol goes to
1947
                 the end of the list, where the loop will still see
1948
                 it.  It would probably be better to do this in
1949
                 obj_frob_file_before_adjust.  */
1950
 
1951
              symp2 = symbol_find_or_make (sy_obj->versioned_name);
1952
 
1953
              /* Now we act as though we saw symp2 = sym.  */
1954
 
1955
              S_SET_SEGMENT (symp2, S_GET_SEGMENT (symp));
1956
 
1957
              /* Subtracting out the frag address here is a hack
1958
                 because we are in the middle of the final loop.  */
1959
              S_SET_VALUE (symp2,
1960
                           (S_GET_VALUE (symp)
1961
                            - symbol_get_frag (symp)->fr_address));
1962
 
1963
              symbol_set_frag (symp2, symbol_get_frag (symp));
1964
 
1965
              /* This will copy over the size information.  */
1966
              copy_symbol_attributes (symp2, symp);
1967
 
1968
              S_SET_OTHER (symp2, S_GET_OTHER (symp));
1969
 
1970
              if (S_IS_WEAK (symp))
1971
                S_SET_WEAK (symp2);
1972
 
1973
              if (S_IS_EXTERNAL (symp))
1974
                S_SET_EXTERNAL (symp2);
1975
            }
1976
        }
1977
    }
1978
 
1979
  /* Double check weak symbols.  */
1980
  if (S_IS_WEAK (symp))
1981
    {
1982
      if (S_IS_COMMON (symp))
1983
        as_bad (_("symbol `%s' can not be both weak and common"),
1984
                S_GET_NAME (symp));
1985
    }
1986
 
1987
#ifdef TC_MIPS
1988
  /* The Irix 5 and 6 assemblers set the type of any common symbol and
1989
     any undefined non-function symbol to STT_OBJECT.  We try to be
1990
     compatible, since newer Irix 5 and 6 linkers care.  However, we
1991
     only set undefined symbols to be STT_OBJECT if we are on Irix,
1992
     because that is the only time gcc will generate the necessary
1993
     .global directives to mark functions.  */
1994
 
1995
  if (S_IS_COMMON (symp))
1996
    symbol_get_bfdsym (symp)->flags |= BSF_OBJECT;
1997
 
1998
  if (strstr (TARGET_OS, "irix") != NULL
1999
      && ! S_IS_DEFINED (symp)
2000
      && (symbol_get_bfdsym (symp)->flags & BSF_FUNCTION) == 0)
2001
    symbol_get_bfdsym (symp)->flags |= BSF_OBJECT;
2002
#endif
2003
}
2004
 
2005
struct group_list
2006
{
2007
  asection **head;              /* Section lists.  */
2008
  unsigned int *elt_count;      /* Number of sections in each list.  */
2009
  unsigned int num_group;       /* Number of lists.  */
2010
};
2011
 
2012
/* Called via bfd_map_over_sections.  If SEC is a member of a group,
2013
   add it to a list of sections belonging to the group.  INF is a
2014
   pointer to a struct group_list, which is where we store the head of
2015
   each list.  */
2016
 
2017
static void
2018
build_group_lists (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf)
2019
{
2020
  struct group_list *list = (struct group_list *) inf;
2021
  const char *group_name = elf_group_name (sec);
2022
  unsigned int i;
2023
 
2024
  if (group_name == NULL)
2025
    return;
2026
 
2027
  /* If this group already has a list, add the section to the head of
2028
     the list.  */
2029
  for (i = 0; i < list->num_group; i++)
2030
    {
2031
      if (strcmp (group_name, elf_group_name (list->head[i])) == 0)
2032
        {
2033
          elf_next_in_group (sec) = list->head[i];
2034
          list->head[i] = sec;
2035
          list->elt_count[i] += 1;
2036
          return;
2037
        }
2038
    }
2039
 
2040
  /* New group.  Make the arrays bigger in chunks to minimize calls to
2041
     realloc.  */
2042
  i = list->num_group;
2043
  if ((i & 127) == 0)
2044
    {
2045
      unsigned int newsize = i + 128;
2046
      list->head = (asection **) xrealloc (list->head,
2047
                                           newsize * sizeof (*list->head));
2048
      list->elt_count = (unsigned int *)
2049
          xrealloc (list->elt_count, newsize * sizeof (*list->elt_count));
2050
    }
2051
  list->head[i] = sec;
2052
  list->elt_count[i] = 1;
2053
  list->num_group += 1;
2054
}
2055
 
2056
void
2057
elf_frob_file (void)
2058
{
2059
  struct group_list list;
2060
  unsigned int i;
2061
 
2062
  bfd_map_over_sections (stdoutput, adjust_stab_sections, NULL);
2063
 
2064
  /* Go find section groups.  */
2065
  list.num_group = 0;
2066
  list.head = NULL;
2067
  list.elt_count = NULL;
2068
  bfd_map_over_sections (stdoutput, build_group_lists, &list);
2069
 
2070
  /* Make the SHT_GROUP sections that describe each section group.  We
2071
     can't set up the section contents here yet, because elf section
2072
     indices have yet to be calculated.  elf.c:set_group_contents does
2073
     the rest of the work.  */
2074
  for (i = 0; i < list.num_group; i++)
2075
    {
2076
      const char *group_name = elf_group_name (list.head[i]);
2077
      const char *sec_name;
2078
      asection *s;
2079
      flagword flags;
2080
      struct symbol *sy;
2081
      int has_sym;
2082
      bfd_size_type size;
2083
 
2084
      flags = SEC_READONLY | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_GROUP;
2085
      for (s = list.head[i]; s != NULL; s = elf_next_in_group (s))
2086
        if ((s->flags ^ flags) & SEC_LINK_ONCE)
2087
          {
2088
            flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
2089
            if (s != list.head[i])
2090
              {
2091
                as_warn (_("assuming all members of group `%s' are COMDAT"),
2092
                         group_name);
2093
                break;
2094
              }
2095
          }
2096
 
2097
      sec_name = group_name;
2098
      sy = symbol_find_exact (group_name);
2099
      has_sym = 0;
2100
      if (sy != NULL
2101
          && (sy == symbol_lastP
2102
              || (sy->sy_next != NULL
2103
                  && sy->sy_next->sy_previous == sy)))
2104
        {
2105
          has_sym = 1;
2106
          sec_name = ".group";
2107
        }
2108
      s = subseg_force_new (sec_name, 0);
2109
      if (s == NULL
2110
          || !bfd_set_section_flags (stdoutput, s, flags)
2111
          || !bfd_set_section_alignment (stdoutput, s, 2))
2112
        {
2113
          as_fatal (_("can't create group: %s"),
2114
                    bfd_errmsg (bfd_get_error ()));
2115
        }
2116
      elf_section_type (s) = SHT_GROUP;
2117
 
2118
      /* Pass a pointer to the first section in this group.  */
2119
      elf_next_in_group (s) = list.head[i];
2120
      if (has_sym)
2121
        elf_group_id (s) = sy->bsym;
2122
 
2123
      size = 4 * (list.elt_count[i] + 1);
2124
      bfd_set_section_size (stdoutput, s, size);
2125
      s->contents = (unsigned char *) frag_more (size);
2126
      frag_now->fr_fix = frag_now_fix_octets ();
2127
      frag_wane (frag_now);
2128
    }
2129
 
2130
#ifdef elf_tc_final_processing
2131
  elf_tc_final_processing ();
2132
#endif
2133
}
2134
 
2135
/* It removes any unneeded versioned symbols from the symbol table.  */
2136
 
2137
void
2138
elf_frob_file_before_adjust (void)
2139
{
2140
  if (symbol_rootP)
2141
    {
2142
      symbolS *symp;
2143
 
2144
      for (symp = symbol_rootP; symp; symp = symbol_next (symp))
2145
        if (!S_IS_DEFINED (symp))
2146
          {
2147
            if (symbol_get_obj (symp)->versioned_name)
2148
              {
2149
                char *p;
2150
 
2151
                /* The @@@ syntax is a special case. If the symbol is
2152
                   not defined, 2 `@'s will be removed from the
2153
                   versioned_name.  */
2154
 
2155
                p = strchr (symbol_get_obj (symp)->versioned_name,
2156
                            ELF_VER_CHR);
2157
                know (p != NULL);
2158
                if (p[1] == ELF_VER_CHR && p[2] == ELF_VER_CHR)
2159
                  {
2160
                    size_t l = strlen (&p[3]) + 1;
2161
                    memmove (&p[1], &p[3], l);
2162
                  }
2163
                if (symbol_used_p (symp) == 0
2164
                    && symbol_used_in_reloc_p (symp) == 0)
2165
                  symbol_remove (symp, &symbol_rootP, &symbol_lastP);
2166
              }
2167
 
2168
            /* If there was .weak foo, but foo was neither defined nor
2169
               used anywhere, remove it.  */
2170
 
2171
            else if (S_IS_WEAK (symp)
2172
                     && symbol_used_p (symp) == 0
2173
                     && symbol_used_in_reloc_p (symp) == 0)
2174
              symbol_remove (symp, &symbol_rootP, &symbol_lastP);
2175
          }
2176
    }
2177
}
2178
 
2179
/* It is required that we let write_relocs have the opportunity to
2180
   optimize away fixups before output has begun, since it is possible
2181
   to eliminate all fixups for a section and thus we never should
2182
   have generated the relocation section.  */
2183
 
2184
void
2185
elf_frob_file_after_relocs (void)
2186
{
2187
#ifdef NEED_ECOFF_DEBUG
2188
  if (ECOFF_DEBUGGING)
2189
    /* Generate the ECOFF debugging information.  */
2190
    {
2191
      const struct ecoff_debug_swap *debug_swap;
2192
      struct ecoff_debug_info debug;
2193
      char *buf;
2194
      asection *sec;
2195
 
2196
      debug_swap
2197
        = get_elf_backend_data (stdoutput)->elf_backend_ecoff_debug_swap;
2198
      know (debug_swap != NULL);
2199
      ecoff_build_debug (&debug.symbolic_header, &buf, debug_swap);
2200
 
2201
      /* Set up the pointers in debug.  */
2202
#define SET(ptr, offset, type) \
2203
    debug.ptr = (type) (buf + debug.symbolic_header.offset)
2204
 
2205
      SET (line, cbLineOffset, unsigned char *);
2206
      SET (external_dnr, cbDnOffset, void *);
2207
      SET (external_pdr, cbPdOffset, void *);
2208
      SET (external_sym, cbSymOffset, void *);
2209
      SET (external_opt, cbOptOffset, void *);
2210
      SET (external_aux, cbAuxOffset, union aux_ext *);
2211
      SET (ss, cbSsOffset, char *);
2212
      SET (external_fdr, cbFdOffset, void *);
2213
      SET (external_rfd, cbRfdOffset, void *);
2214
      /* ssext and external_ext are set up just below.  */
2215
 
2216
#undef SET
2217
 
2218
      /* Set up the external symbols.  */
2219
      debug.ssext = debug.ssext_end = NULL;
2220
      debug.external_ext = debug.external_ext_end = NULL;
2221
      if (! bfd_ecoff_debug_externals (stdoutput, &debug, debug_swap, TRUE,
2222
                                       elf_get_extr, elf_set_index))
2223
        as_fatal (_("failed to set up debugging information: %s"),
2224
                  bfd_errmsg (bfd_get_error ()));
2225
 
2226
      sec = bfd_get_section_by_name (stdoutput, ".mdebug");
2227
      gas_assert (sec != NULL);
2228
 
2229
      know (!stdoutput->output_has_begun);
2230
 
2231
      /* We set the size of the section, call bfd_set_section_contents
2232
         to force the ELF backend to allocate a file position, and then
2233
         write out the data.  FIXME: Is this really the best way to do
2234
         this?  */
2235
      bfd_set_section_size
2236
        (stdoutput, sec, bfd_ecoff_debug_size (stdoutput, &debug, debug_swap));
2237
 
2238
      /* Pass BUF to bfd_set_section_contents because this will
2239
         eventually become a call to fwrite, and ISO C prohibits
2240
         passing a NULL pointer to a stdio function even if the
2241
         pointer will not be used.  */
2242
      if (! bfd_set_section_contents (stdoutput, sec, buf, 0, 0))
2243
        as_fatal (_("can't start writing .mdebug section: %s"),
2244
                  bfd_errmsg (bfd_get_error ()));
2245
 
2246
      know (stdoutput->output_has_begun);
2247
      know (sec->filepos != 0);
2248
 
2249
      if (! bfd_ecoff_write_debug (stdoutput, &debug, debug_swap,
2250
                                   sec->filepos))
2251
        as_fatal (_("could not write .mdebug section: %s"),
2252
                  bfd_errmsg (bfd_get_error ()));
2253
    }
2254
#endif /* NEED_ECOFF_DEBUG */
2255
}
2256
 
2257
#ifdef SCO_ELF
2258
 
2259
/* Heavily plagiarized from obj_elf_version.  The idea is to emit the
2260
   SCO specific identifier in the .notes section to satisfy the SCO
2261
   linker.
2262
 
2263
   This looks more complicated than it really is.  As opposed to the
2264
   "obvious" solution, this should handle the cross dev cases
2265
   correctly.  (i.e, hosting on a 64 bit big endian processor, but
2266
   generating SCO Elf code) Efficiency isn't a concern, as there
2267
   should be exactly one of these sections per object module.
2268
 
2269
   SCO OpenServer 5 identifies it's ELF modules with a standard ELF
2270
   .note section.
2271
 
2272
   int_32 namesz  = 4 ;  Name size
2273
   int_32 descsz  = 12 ; Descriptive information
2274
   int_32 type    = 1 ;
2275
   char   name[4] = "SCO" ; Originator name ALWAYS SCO + NULL
2276
   int_32 version = (major ver # << 16)  | version of tools ;
2277
   int_32 source  = (tool_id << 16 ) | 1 ;
2278
   int_32 info    = 0 ;    These are set by the SCO tools, but we
2279
                           don't know enough about the source
2280
                           environment to set them.  SCO ld currently
2281
                           ignores them, and recommends we set them
2282
                           to zero.  */
2283
 
2284
#define SCO_MAJOR_VERSION 0x1
2285
#define SCO_MINOR_VERSION 0x1
2286
 
2287
void
2288
sco_id (void)
2289
{
2290
 
2291
  char *name;
2292
  unsigned int c;
2293
  char ch;
2294
  char *p;
2295
  asection *seg = now_seg;
2296
  subsegT subseg = now_subseg;
2297
  Elf_Internal_Note i_note;
2298
  Elf_External_Note e_note;
2299
  asection *note_secp = NULL;
2300
  int i, len;
2301
 
2302
  /* create the .note section */
2303
 
2304
  note_secp = subseg_new (".note", 0);
2305
  bfd_set_section_flags (stdoutput,
2306
                         note_secp,
2307
                         SEC_HAS_CONTENTS | SEC_READONLY);
2308
 
2309
  /* process the version string */
2310
 
2311
  i_note.namesz = 4;
2312
  i_note.descsz = 12;           /* 12 descriptive bytes */
2313
  i_note.type = NT_VERSION;     /* Contains a version string */
2314
 
2315
  p = frag_more (sizeof (i_note.namesz));
2316
  md_number_to_chars (p, i_note.namesz, 4);
2317
 
2318
  p = frag_more (sizeof (i_note.descsz));
2319
  md_number_to_chars (p, i_note.descsz, 4);
2320
 
2321
  p = frag_more (sizeof (i_note.type));
2322
  md_number_to_chars (p, i_note.type, 4);
2323
 
2324
  p = frag_more (4);
2325
  strcpy (p, "SCO");
2326
 
2327
  /* Note: this is the version number of the ELF we're representing */
2328
  p = frag_more (4);
2329
  md_number_to_chars (p, (SCO_MAJOR_VERSION << 16) | (SCO_MINOR_VERSION), 4);
2330
 
2331
  /* Here, we pick a magic number for ourselves (yes, I "registered"
2332
     it with SCO.  The bottom bit shows that we are compat with the
2333
     SCO ABI.  */
2334
  p = frag_more (4);
2335
  md_number_to_chars (p, 0x4c520000 | 0x0001, 4);
2336
 
2337
  /* If we knew (or cared) what the source language options were, we'd
2338
     fill them in here.  SCO has given us permission to ignore these
2339
     and just set them to zero.  */
2340
  p = frag_more (4);
2341
  md_number_to_chars (p, 0x0000, 4);
2342
 
2343
  frag_align (2, 0, 0);
2344
 
2345
  /* We probably can't restore the current segment, for there likely
2346
     isn't one yet...  */
2347
  if (seg && subseg)
2348
    subseg_set (seg, subseg);
2349
 
2350
}
2351
 
2352
#endif /* SCO_ELF */
2353
 
2354
static int
2355
elf_separate_stab_sections (void)
2356
{
2357
#ifdef NEED_ECOFF_DEBUG
2358
  return (!ECOFF_DEBUGGING);
2359
#else
2360
  return 1;
2361
#endif
2362
}
2363
 
2364
static void
2365
elf_init_stab_section (segT seg)
2366
{
2367
#ifdef NEED_ECOFF_DEBUG
2368
  if (!ECOFF_DEBUGGING)
2369
#endif
2370
    obj_elf_init_stab_section (seg);
2371
}
2372
 
2373
const struct format_ops elf_format_ops =
2374
{
2375
  bfd_target_elf_flavour,
2376
  0,     /* dfl_leading_underscore */
2377
  1,    /* emit_section_symbols */
2378
  elf_begin,
2379
  elf_file_symbol,
2380
  elf_frob_symbol,
2381
  elf_frob_file,
2382
  elf_frob_file_before_adjust,
2383
  0,     /* obj_frob_file_before_fix */
2384
  elf_frob_file_after_relocs,
2385
  elf_s_get_size, elf_s_set_size,
2386
  elf_s_get_align, elf_s_set_align,
2387
  elf_s_get_other,
2388
  elf_s_set_other,
2389
  0,     /* s_get_desc */
2390
  0,     /* s_set_desc */
2391
  0,     /* s_get_type */
2392
  0,     /* s_set_type */
2393
  elf_copy_symbol_attributes,
2394
#ifdef NEED_ECOFF_DEBUG
2395
  ecoff_generate_asm_lineno,
2396
  ecoff_stab,
2397
#else
2398
  0,     /* generate_asm_lineno */
2399
  0,     /* process_stab */
2400
#endif
2401
  elf_separate_stab_sections,
2402
  elf_init_stab_section,
2403
  elf_sec_sym_ok_for_reloc,
2404
  elf_pop_insert,
2405
#ifdef NEED_ECOFF_DEBUG
2406
  elf_ecoff_set_ext,
2407
#else
2408
  0,     /* ecoff_set_ext */
2409
#endif
2410
  elf_obj_read_begin_hook,
2411
  elf_obj_symbol_new_hook
2412
};

powered by: WebSVN 2.1.0

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