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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-binutils/] [binutils-2.19.1/] [gas/] [config/] [obj-elf.c] - Blame information for rev 13

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

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

powered by: WebSVN 2.1.0

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