Coverage Report

Created: 2025-06-24 06:45

/src/binutils-gdb/gas/config/obj-elf.c
Line
Count
Source (jump to first uncovered line)
1
/* ELF object file format
2
   Copyright (C) 1992-2025 Free Software Foundation, Inc.
3
4
   This file is part of GAS, the GNU Assembler.
5
6
   GAS is free software; you can redistribute it and/or modify
7
   it under the terms of the GNU General Public License as
8
   published by the Free Software Foundation; either version 3,
9
   or (at your option) any later version.
10
11
   GAS is distributed in the hope that it will be useful, but
12
   WITHOUT ANY WARRANTY; without even the implied warranty of
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
14
   the GNU General Public License for more details.
15
16
   You should have received a copy of the GNU General Public License
17
   along with GAS; see the file COPYING.  If not, write to the Free
18
   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
19
   02110-1301, USA.  */
20
21
#define OBJ_HEADER "obj-elf.h"
22
#include "as.h"
23
#include "safe-ctype.h"
24
#include "subsegs.h"
25
#include "obstack.h"
26
#include "dwarf2dbg.h"
27
#include "ginsn.h"
28
29
#ifndef ECOFF_DEBUGGING
30
28
#define ECOFF_DEBUGGING 0
31
#else
32
#define NEED_ECOFF_DEBUG
33
#endif
34
35
#ifdef NEED_ECOFF_DEBUG
36
#include "ecoff.h"
37
#include "bfd/ecoff-bfd.h"
38
#endif
39
40
#ifdef TC_ALPHA
41
#include "elf/alpha.h"
42
#endif
43
44
#ifdef TC_MIPS
45
#include "elf/mips.h"
46
#endif
47
48
#ifdef TC_PPC
49
#include "elf/ppc.h"
50
#endif
51
52
#ifdef TC_I386
53
#include "elf/x86-64.h"
54
#endif
55
56
#ifdef TC_MEP
57
#include "elf/mep.h"
58
#endif
59
60
#ifdef TC_PRU
61
#include "elf/pru.h"
62
#endif
63
64
static void obj_elf_line (int);
65
static void obj_elf_size (int);
66
static void obj_elf_type (int);
67
static void obj_elf_ident (int);
68
static void obj_elf_weak (int);
69
static void obj_elf_local (int);
70
static void obj_elf_visibility (int);
71
static void obj_elf_symver (int);
72
static void obj_elf_subsection (int);
73
static void obj_elf_popsection (int);
74
static void obj_elf_gnu_attribute (int);
75
static void obj_elf_tls_common (int);
76
static void obj_elf_lcomm (int);
77
static void obj_elf_struct (int);
78
static void obj_elf_attach_to_group (int);
79
80
static const pseudo_typeS elf_pseudo_table[] =
81
{
82
  {"attach_to_group", obj_elf_attach_to_group, 0},
83
  {"comm", obj_elf_common, 0},
84
  {"common", obj_elf_common, 1},
85
  {"ident", obj_elf_ident, 0},
86
  {"lcomm", obj_elf_lcomm, 0},
87
  {"local", obj_elf_local, 0},
88
  {"previous", obj_elf_previous, 0},
89
  {"section", obj_elf_section, 0},
90
  {"section.s", obj_elf_section, 0},
91
  {"sect", obj_elf_section, 0},
92
  {"sect.s", obj_elf_section, 0},
93
  {"pushsection", obj_elf_section, 1},
94
  {"popsection", obj_elf_popsection, 0},
95
  {"size", obj_elf_size, 0},
96
  {"type", obj_elf_type, 0},
97
  {"version", obj_elf_version, 0},
98
  {"weak", obj_elf_weak, 0},
99
100
  /* These define symbol visibility.  */
101
  {"internal", obj_elf_visibility, STV_INTERNAL},
102
  {"hidden", obj_elf_visibility, STV_HIDDEN},
103
  {"protected", obj_elf_visibility, STV_PROTECTED},
104
105
  /* These are used for stabs-in-elf configurations.  */
106
  {"line", obj_elf_line, 0},
107
108
  /* This is a GNU extension to handle symbol versions.  */
109
  {"symver", obj_elf_symver, 0},
110
111
  /* A GNU extension to change subsection only.  */
112
  {"subsection", obj_elf_subsection, 0},
113
114
  /* These are GNU extensions to aid in garbage collecting C++ vtables.  */
115
  {"vtable_inherit", obj_elf_vtable_inherit, 0},
116
  {"vtable_entry", obj_elf_vtable_entry, 0},
117
118
  /* A GNU extension for object attributes.  */
119
  {"gnu_attribute", obj_elf_gnu_attribute, 0},
120
121
  /* These are used for dwarf2.  */
122
  { "file", dwarf2_directive_file, 0 },
123
  { "loc",  dwarf2_directive_loc,  0 },
124
  { "loc_mark_labels", dwarf2_directive_loc_mark_labels, 0 },
125
126
  /* We need to trap the section changing calls to handle .previous.  */
127
  {"data", obj_elf_data, 0},
128
  {"offset", obj_elf_struct, 0},
129
  {"struct", obj_elf_struct, 0},
130
  {"text", obj_elf_text, 0},
131
  {"bss", obj_elf_bss, 0},
132
133
  {"tls_common", obj_elf_tls_common, 0},
134
135
  /* End sentinel.  */
136
  {NULL, NULL, 0},
137
};
138
139
static const pseudo_typeS ecoff_debug_pseudo_table[] =
140
{
141
#ifdef NEED_ECOFF_DEBUG
142
  /* COFF style debugging information for ECOFF. .ln is not used; .loc
143
     is used instead.  */
144
  { "def",  ecoff_directive_def,  0 },
145
  { "dim",  ecoff_directive_dim,  0 },
146
  { "endef",  ecoff_directive_endef,  0 },
147
  { "file", ecoff_directive_file, 0 },
148
  { "scl",  ecoff_directive_scl,  0 },
149
  { "tag",  ecoff_directive_tag,  0 },
150
  { "val",  ecoff_directive_val,  0 },
151
152
  /* COFF debugging requires pseudo-ops .size and .type, but ELF
153
     already has meanings for those.  We use .esize and .etype
154
     instead.  These are only generated by gcc anyhow.  */
155
  { "esize",  ecoff_directive_size, 0 },
156
  { "etype",  ecoff_directive_type, 0 },
157
158
  /* ECOFF specific debugging information.  */
159
  { "aent", ecoff_directive_ent,  1 },
160
  { "begin",  ecoff_directive_begin,  0 },
161
  { "bend", ecoff_directive_bend, 0 },
162
  { "end",  ecoff_directive_end,  0 },
163
  { "ent",  ecoff_directive_ent,  0 },
164
  { "fmask",  ecoff_directive_fmask,  0 },
165
  { "frame",  ecoff_directive_frame,  0 },
166
  { "loc",  ecoff_directive_loc,  0 },
167
  { "mask", ecoff_directive_mask, 0 },
168
169
  /* Other ECOFF directives.  */
170
  { "extern", ecoff_directive_extern, 0 },
171
172
  /* These are used on Irix.  I don't know how to implement them.  */
173
  { "alias",  s_ignore,   0 },
174
  { "bgnb", s_ignore,   0 },
175
  { "endb", s_ignore,   0 },
176
  { "lab",  s_ignore,   0 },
177
  { "noalias",  s_ignore,   0 },
178
  { "verstamp", s_ignore,   0 },
179
  { "vreg", s_ignore,   0 },
180
#endif
181
182
  {NULL, NULL, 0}     /* end sentinel */
183
};
184
185
#undef NO_RELOC
186
#include "aout/aout64.h"
187
188
asection *elf_com_section_ptr;
189
190
void
191
elf_pop_insert (void)
192
28
{
193
28
  pop_insert (elf_pseudo_table);
194
28
  if (ECOFF_DEBUGGING)
195
0
    pop_insert (ecoff_debug_pseudo_table);
196
28
}
197
198
void
199
elf_file_symbol (const char *s)
200
432
{
201
432
  asymbol *bsym;
202
432
  symbolS *sym = symbol_new (s, absolute_section, &zero_address_frag, 0);
203
432
  size_t name_length = strlen (s);
204
205
432
  if (name_length > strlen (S_GET_NAME (sym)))
206
0
    {
207
0
      obstack_grow (&notes, s, name_length + 1);
208
0
      S_SET_NAME (sym, (const char *) obstack_finish (&notes));
209
0
    }
210
432
  else
211
432
    strcpy ((char *) S_GET_NAME (sym), s);
212
213
432
  symbol_get_bfdsym (sym)->flags |= BSF_FILE;
214
215
432
  if (symbol_rootP != sym
216
432
      && ((bsym = symbol_get_bfdsym (symbol_rootP)) == NULL
217
432
    || (bsym->flags & BSF_FILE) == 0))
218
12
    {
219
12
      symbol_remove (sym, &symbol_rootP, &symbol_lastP);
220
12
      symbol_insert (sym, symbol_rootP, &symbol_rootP, &symbol_lastP);
221
12
    }
222
223
#ifdef DEBUG
224
  verify_symbol_chain (symbol_rootP, symbol_lastP);
225
#endif
226
227
#ifdef NEED_ECOFF_DEBUG
228
  ecoff_new_file (s);
229
#endif
230
432
}
231
232
/* Called from read.c:s_comm after we've parsed .comm symbol, size.
233
   Parse a possible alignment value.  */
234
235
symbolS *
236
elf_common_parse (int ignore ATTRIBUTE_UNUSED, symbolS *symbolP, addressT size)
237
538
{
238
538
  addressT align = 0;
239
538
  int is_local = symbol_get_obj (symbolP)->local;
240
241
538
  if (*input_line_pointer == ',')
242
184
    {
243
184
      char *save = input_line_pointer;
244
245
184
      input_line_pointer++;
246
184
      SKIP_WHITESPACE ();
247
248
184
      if (*input_line_pointer == '"')
249
0
  {
250
    /* For sparc.  Accept .common symbol, length, "bss"  */
251
0
    input_line_pointer++;
252
    /* Some use the dot, some don't.  */
253
0
    if (*input_line_pointer == '.')
254
0
      input_line_pointer++;
255
    /* Some say data, some say bss.  */
256
0
    if (startswith (input_line_pointer, "bss\""))
257
0
      input_line_pointer += 4;
258
0
    else if (startswith (input_line_pointer, "data\""))
259
0
      input_line_pointer += 5;
260
0
    else
261
0
      {
262
0
        char *p = input_line_pointer;
263
0
        char c;
264
265
0
        while (*--p != '"')
266
0
    ;
267
0
        while (!is_end_of_stmt (*input_line_pointer))
268
0
    if (*input_line_pointer++ == '"')
269
0
      break;
270
0
        c = *input_line_pointer;
271
0
        *input_line_pointer = '\0';
272
0
        as_bad (_("bad .common segment %s"), p);
273
0
        *input_line_pointer = c;
274
0
        ignore_rest_of_line ();
275
0
        return NULL;
276
0
      }
277
    /* ??? Don't ask me why these are always global.  */
278
0
    is_local = 0;
279
0
  }
280
184
      else
281
184
  {
282
184
    input_line_pointer = save;
283
184
    align = parse_align (is_local);
284
184
    if (align == (addressT) -1)
285
175
      return NULL;
286
184
  }
287
184
    }
288
289
363
  if (is_local)
290
0
    {
291
0
      bss_alloc (symbolP, size, align);
292
0
      S_CLEAR_EXTERNAL (symbolP);
293
0
    }
294
363
  else
295
363
    {
296
363
      S_SET_VALUE (symbolP, size);
297
363
      S_SET_ALIGN (symbolP, align);
298
363
      S_SET_EXTERNAL (symbolP);
299
363
      S_SET_SEGMENT (symbolP, elf_com_section_ptr);
300
363
    }
301
302
363
  symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
303
304
363
  return symbolP;
305
538
}
306
307
void
308
obj_elf_common (int is_common)
309
684
{
310
684
  if (flag_mri && is_common)
311
0
    s_mri_common (0);
312
684
  else
313
684
    s_comm_internal (0, elf_common_parse);
314
684
}
315
316
static void
317
obj_elf_tls_common (int ignore ATTRIBUTE_UNUSED)
318
0
{
319
0
  symbolS *symbolP = s_comm_internal (0, elf_common_parse);
320
321
0
  if (symbolP)
322
0
    symbol_get_bfdsym (symbolP)->flags |= BSF_THREAD_LOCAL;
323
0
}
324
325
static void
326
obj_elf_lcomm (int ignore ATTRIBUTE_UNUSED)
327
656
{
328
656
  symbolS *symbolP = s_comm_internal (0, s_lcomm_internal);
329
330
656
  if (symbolP)
331
23
    symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
332
656
}
333
334
static symbolS *
335
get_sym_from_input_line_and_check (void)
336
4.08k
{
337
4.08k
  char *name;
338
4.08k
  char c;
339
4.08k
  symbolS *sym;
340
341
4.08k
  c = get_symbol_name (& name);
342
4.08k
  sym = symbol_find_or_make (name);
343
4.08k
  restore_line_pointer (c);
344
4.08k
  SKIP_WHITESPACE ();
345
346
  /* There is no symbol name if input_line_pointer has not moved.  */
347
4.08k
  if (name == input_line_pointer)
348
3.87k
    as_bad (_("Missing symbol name in directive"));
349
4.08k
  return sym;
350
4.08k
}
351
352
static void
353
obj_elf_local (int ignore ATTRIBUTE_UNUSED)
354
90
{
355
90
  int c;
356
90
  symbolS *symbolP;
357
358
90
  do
359
180
    {
360
180
      symbolP = get_sym_from_input_line_and_check ();
361
180
      c = *input_line_pointer;
362
180
      S_CLEAR_EXTERNAL (symbolP);
363
180
      symbol_get_obj (symbolP)->local = 1;
364
180
      if (c == ',')
365
90
  {
366
90
    input_line_pointer++;
367
90
    SKIP_WHITESPACE ();
368
90
    if (*input_line_pointer == '\n')
369
0
      c = '\n';
370
90
  }
371
180
    }
372
180
  while (c == ',');
373
90
  demand_empty_rest_of_line ();
374
90
}
375
376
static void
377
obj_elf_weak (int ignore ATTRIBUTE_UNUSED)
378
308
{
379
308
  int c;
380
308
  symbolS *symbolP;
381
382
308
  do
383
554
    {
384
554
      symbolP = get_sym_from_input_line_and_check ();
385
554
      c = *input_line_pointer;
386
554
      S_SET_WEAK (symbolP);
387
554
      if (c == ',')
388
500
  {
389
500
    input_line_pointer++;
390
500
    SKIP_WHITESPACE ();
391
500
    if (*input_line_pointer == '\n')
392
254
      c = '\n';
393
500
  }
394
554
    }
395
554
  while (c == ',');
396
308
  demand_empty_rest_of_line ();
397
308
}
398
399
static void
400
obj_elf_visibility (int visibility)
401
14
{
402
14
  int c;
403
14
  symbolS *symbolP;
404
14
  asymbol *bfdsym;
405
14
  elf_symbol_type *elfsym;
406
407
14
  do
408
28
    {
409
28
      symbolP = get_sym_from_input_line_and_check ();
410
411
28
      bfdsym = symbol_get_bfdsym (symbolP);
412
28
      elfsym = elf_symbol_from (bfdsym);
413
414
28
      gas_assert (elfsym);
415
416
28
      elfsym->internal_elf_sym.st_other &= ~3;
417
28
      elfsym->internal_elf_sym.st_other |= visibility;
418
419
28
      c = *input_line_pointer;
420
28
      if (c == ',')
421
14
  {
422
14
    input_line_pointer ++;
423
424
14
    SKIP_WHITESPACE ();
425
426
14
    if (*input_line_pointer == '\n')
427
0
      c = '\n';
428
14
  }
429
28
    }
430
28
  while (c == ',');
431
432
14
  demand_empty_rest_of_line ();
433
14
}
434
435
static segT previous_section;
436
static int previous_subsection;
437
438
struct section_stack
439
{
440
  struct section_stack *next;
441
  segT seg, prev_seg;
442
  int subseg, prev_subseg;
443
};
444
445
static struct section_stack *section_stack;
446
447
/* ELF section flags for unique sections.  */
448
93
#define SEC_ASSEMBLER_SHF_MASK SHF_GNU_RETAIN
449
450
struct group_list
451
{
452
  asection **head;    /* Section lists.  */
453
  unsigned int num_group; /* Number of lists.  */
454
  htab_t indexes; /* Maps group name to index in head array.  */
455
};
456
457
static struct group_list groups;
458
459
static bool
460
match_section (const asection *sec, const struct elf_section_match *match)
461
91
{
462
91
  const char *linked_to_symbol_name = sec->map_head.linked_to_symbol_name;
463
91
  unsigned int sh_info = elf_section_data (sec)->this_hdr.sh_info;
464
91
  bfd_vma sh_flags = (elf_section_data (sec)->this_hdr.sh_flags
465
91
          & SEC_ASSEMBLER_SHF_MASK);
466
467
91
  return (sh_info == match->sh_info
468
91
    && sh_flags == match->sh_flags
469
91
    && ((bfd_section_flags (sec) & SEC_ASSEMBLER_SECTION_ID)
470
91
         == (match->flags & SEC_ASSEMBLER_SECTION_ID))
471
91
    && sec->section_id == match->section_id
472
91
    && (linked_to_symbol_name == match->linked_to_symbol_name
473
91
        || (linked_to_symbol_name != NULL
474
0
      && match->linked_to_symbol_name != NULL
475
0
      && strcmp (linked_to_symbol_name,
476
0
           match->linked_to_symbol_name) == 0)));
477
91
}
478
479
/* Return TRUE iff SEC matches the section info INF.  */
480
481
static bool
482
get_section_by_match (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf)
483
91
{
484
91
  struct elf_section_match *match = (struct elf_section_match *) inf;
485
91
  const char *gname = match->group_name;
486
91
  const char *group_name = elf_group_name (sec);
487
488
91
  return ((group_name == gname
489
91
     || (group_name != NULL
490
0
         && gname != NULL
491
0
         && strcmp (group_name, gname) == 0))
492
91
    && match_section (sec, match));
493
91
}
494
495
/* Go look in section lists kept per group for SEC_NAME with
496
   properties given by MATCH.  If info for the group named by
497
   MATCH->GROUP_NAME has been initialised, set GROUP_IDX.  */
498
499
static asection *
500
group_section_find (const struct elf_section_match *match,
501
        const char *sec_name,
502
        unsigned int *group_idx)
503
2
{
504
2
  if (!groups.indexes)
505
2
    {
506
2
      groups.num_group = 0;
507
2
      groups.head = NULL;
508
2
      groups.indexes = htab_create_alloc (16, hash_string_tuple, eq_string_tuple,
509
2
            NULL, notes_calloc, NULL);
510
2
      *group_idx = ~0u;
511
2
      return NULL;
512
2
    }
513
514
0
  *group_idx = str_hash_find_int (groups.indexes, match->group_name);
515
0
  if (*group_idx == ~0u)
516
0
    return NULL;
517
518
0
  asection *s;
519
0
  for (s = groups.head[*group_idx]; s != NULL; s = elf_next_in_group (s))
520
0
    if ((s->name == sec_name
521
0
   || strcmp (s->name, sec_name) == 0)
522
0
  && match_section (s, match))
523
0
      break;
524
0
  return s;
525
0
}
526
527
/* Insert SEC into section lists kept per group.  MATCH and GROUP_IDX
528
   must be from a prior call to group_section_find.  */
529
530
static void
531
group_section_insert (const struct elf_section_match *match,
532
          asection *sec,
533
          unsigned int *group_idx)
534
2
{
535
2
  if (*group_idx != ~0u)
536
0
    {
537
0
      elf_next_in_group (sec) = groups.head[*group_idx];
538
0
      groups.head[*group_idx] = sec;
539
0
      return;
540
0
    }
541
542
2
  unsigned int i = groups.num_group;
543
2
  if ((i & 127) == 0)
544
2
    groups.head = XRESIZEVEC (asection *, groups.head, i + 128);
545
2
  groups.head[i] = sec;
546
2
  groups.num_group += 1;
547
548
  /* We keep the index into groups.head rather than the entry address
549
     because groups.head may be realloc'd.  */
550
2
  str_hash_insert_int (groups.indexes, match->group_name, i, 0);
551
2
}
552
553
/* Handle the .section pseudo-op.  This code supports two different
554
   syntaxes.
555
556
   The first is found on Solaris, and looks like
557
       .section ".sec1",#alloc,#execinstr,#write
558
   Here the names after '#' are the SHF_* flags to turn on for the
559
   section.  I'm not sure how it determines the SHT_* type (BFD
560
   doesn't really give us control over the type, anyhow).
561
562
   The second format is found on UnixWare, and probably most SVR4
563
   machines, and looks like
564
       .section .sec1,"a",@progbits
565
   The quoted string may contain any combination of a, w, x, and
566
   represents the SHF_* flags to turn on for the section.  The string
567
   beginning with '@' can be progbits or nobits.  There should be
568
   other possibilities, but I don't know what they are.  In any case,
569
   BFD doesn't really let us set the section type.  */
570
571
static void
572
change_section (const char *name,
573
    unsigned int type,
574
    bfd_vma attr,
575
    int entsize,
576
    struct elf_section_match *match_p,
577
    bool linkonce,
578
    bool push,
579
    subsegT new_subsection)
580
136
{
581
136
  asection *old_sec;
582
136
  segT sec;
583
136
  flagword flags;
584
136
  const struct elf_backend_data *bed;
585
136
  const struct bfd_elf_special_section *ssect;
586
587
136
  if (match_p == NULL)
588
0
    {
589
0
      static struct elf_section_match unused_match;
590
0
      match_p = &unused_match;
591
0
    }
592
593
#ifdef md_flush_pending_output
594
  md_flush_pending_output ();
595
#endif
596
597
  /* Switch to the section, creating it if necessary.  */
598
136
  if (push)
599
0
    {
600
0
      struct section_stack *elt;
601
0
      elt = XNEW (struct section_stack);
602
0
      elt->next = section_stack;
603
0
      elt->seg = now_seg;
604
0
      elt->prev_seg = previous_section;
605
0
      elt->subseg = now_subseg;
606
0
      elt->prev_subseg = previous_subsection;
607
0
      section_stack = elt;
608
0
    }
609
610
136
  obj_elf_section_change_hook ();
611
612
136
  unsigned int group_idx = ~0u;
613
136
  if (match_p->group_name)
614
0
    old_sec = group_section_find (match_p, name, &group_idx);
615
136
  else
616
136
    old_sec = bfd_get_section_by_name_if (stdoutput, name, get_section_by_match,
617
136
            (void *) match_p);
618
136
  if (old_sec)
619
91
    {
620
91
      sec = old_sec;
621
91
      subseg_set (sec, new_subsection);
622
91
    }
623
45
  else
624
45
    {
625
45
      sec = subseg_force_new (name, new_subsection);
626
45
      if (match_p->group_name)
627
0
  group_section_insert (match_p, sec, &group_idx);
628
45
    }
629
630
136
  bed = get_elf_backend_data (stdoutput);
631
136
  ssect = (*bed->get_sec_type_attr) (stdoutput, sec);
632
633
136
  if (ssect != NULL)
634
2
    {
635
2
      bool override = false;
636
637
2
      if (type == SHT_NULL)
638
2
  type = ssect->type;
639
0
      else if (type != ssect->type)
640
0
  {
641
0
    if (old_sec == NULL
642
        /* Some older versions of gcc will emit
643
644
     .section .init_array,"aw",@progbits
645
646
     for __attribute__ ((section (".init_array"))).
647
     "@progbits" is incorrect.  Also for x86-64 large bss
648
     sections, some older versions of gcc will emit
649
650
     .section .lbss,"aw",@progbits
651
652
     "@progbits" is incorrect.  */
653
0
#ifdef TC_I386
654
0
        && (bed->s->arch_size != 64
655
0
      || !(ssect->attr & SHF_X86_64_LARGE))
656
0
#endif
657
0
        && ssect->type != SHT_INIT_ARRAY
658
0
        && ssect->type != SHT_FINI_ARRAY
659
0
        && ssect->type != SHT_PREINIT_ARRAY)
660
0
      {
661
        /* We allow to specify any type for a .note section.  */
662
0
        if (ssect->type != SHT_NOTE
663
      /* Processor and application defined types are allowed too.  */
664
0
      && type < SHT_LOPROC)
665
0
    as_warn (_("setting incorrect section type for %s"),
666
0
       name);
667
0
      }
668
0
    else
669
0
      {
670
0
        as_warn (_("ignoring incorrect section type for %s"),
671
0
           name);
672
0
        type = ssect->type;
673
0
      }
674
0
  }
675
676
2
      if (old_sec == NULL && ((attr & ~(SHF_LINK_ORDER
677
1
          | SHF_MASKOS
678
1
          | SHF_MASKPROC))
679
1
            & ~ssect->attr) != 0)
680
0
  {
681
    /* Strip SHF_GNU_RETAIN.  */
682
0
    bfd_vma generic_attr = attr;
683
0
    if (elf_tdata (stdoutput)->has_gnu_osabi)
684
0
      generic_attr &= ~SHF_GNU_RETAIN;
685
686
    /* As a GNU extension, we permit a .note section to be
687
       allocatable.  If the linker sees an allocatable .note
688
       section, it will create a PT_NOTE segment in the output
689
       file.  We also allow "x" for .note.GNU-stack.  */
690
0
    if (ssect->type == SHT_NOTE
691
0
        && (generic_attr == SHF_ALLOC
692
0
      || generic_attr == SHF_EXECINSTR))
693
0
      ;
694
    /* Allow different SHF_MERGE and SHF_STRINGS if we have
695
       something like .rodata.str.  */
696
0
    else if (ssect->suffix_length == -2
697
0
       && name[ssect->prefix_length] == '.'
698
0
       && (generic_attr
699
0
           & ~ssect->attr
700
0
           & ~SHF_MERGE
701
0
           & ~SHF_STRINGS) == 0)
702
0
      ;
703
    /* .interp, .strtab and .symtab can have SHF_ALLOC.  */
704
0
    else if (generic_attr == SHF_ALLOC
705
0
       && (strcmp (name, ".interp") == 0
706
0
           || strcmp (name, ".strtab") == 0
707
0
           || strcmp (name, ".symtab") == 0))
708
0
      override = true;
709
    /* .note.GNU-stack can have SHF_EXECINSTR.  */
710
0
    else if (generic_attr == SHF_EXECINSTR
711
0
       && strcmp (name, ".note.GNU-stack") == 0)
712
0
      override = true;
713
#ifdef TC_ALPHA
714
    /* A section on Alpha may have SHF_ALPHA_GPREL.  */
715
    else if ((generic_attr & ~ssect->attr) == SHF_ALPHA_GPREL)
716
      override = true;
717
#endif
718
#ifdef TC_RX
719
    else if (generic_attr == (SHF_EXECINSTR | SHF_WRITE | SHF_ALLOC)
720
       && (ssect->type == SHT_INIT_ARRAY
721
           || ssect->type == SHT_FINI_ARRAY
722
           || ssect->type == SHT_PREINIT_ARRAY))
723
      /* RX init/fini arrays can and should have the "awx" attributes set.  */
724
      ;
725
#endif
726
0
    else
727
0
      {
728
0
        if (match_p->group_name == NULL)
729
0
    as_warn (_("setting incorrect section attributes for %s"),
730
0
       name);
731
0
        override = true;
732
0
      }
733
0
  }
734
735
2
      if (!override && old_sec == NULL)
736
1
  attr |= ssect->attr;
737
2
    }
738
739
  /* Convert ELF type and flags to BFD flags.  */
740
136
  flags = (SEC_RELOC
741
136
     | ((attr & SHF_WRITE) ? 0 : SEC_READONLY)
742
136
     | ((attr & SHF_ALLOC) ? SEC_ALLOC : 0)
743
136
     | (((attr & SHF_ALLOC) && type != SHT_NOBITS) ? SEC_LOAD : 0)
744
136
     | ((attr & SHF_EXECINSTR) ? SEC_CODE : 0)
745
136
     | ((attr & SHF_MERGE) ? SEC_MERGE : 0)
746
136
     | ((attr & SHF_STRINGS) ? SEC_STRINGS : 0)
747
136
     | ((attr & SHF_EXCLUDE) ? SEC_EXCLUDE: 0)
748
136
     | ((attr & SHF_TLS) ? SEC_THREAD_LOCAL : 0));
749
#ifdef md_elf_section_flags
750
  flags = md_elf_section_flags (flags, attr, type);
751
#endif
752
753
136
  if (linkonce)
754
0
    flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
755
756
  /* PR 28054: Set the SEC_ELF_OCTETS flag for debugging sections.
757
     Based on the code in bfd/elf.c:_bfd_elf_make_section_from_shdr().
758
759
     FIXME: We do not set the SEC_DEBUGGING flag because that causes
760
     problems for the FT32 and MSP430 targets.  Investigate and fix.  */
761
136
  if ((flags & SEC_ALLOC) == 0 && name [0] == '.')
762
75
    {
763
75
      if (   startswith (name, ".debug")
764
75
    || startswith (name, ".zdebug")
765
75
    || startswith (name, ".gnu.debuglto_.debug_")
766
75
    || startswith (name, ".gnu.linkonce.wi.")
767
75
    || startswith (name, GNU_BUILD_ATTRS_SECTION_NAME)
768
75
    || startswith (name, ".note.gnu"))
769
28
  flags |= SEC_ELF_OCTETS;
770
75
    }
771
772
136
  if (old_sec == NULL)
773
45
    {
774
45
      symbolS *secsym;
775
776
45
      if (type == SHT_NULL)
777
44
  type = bfd_elf_get_default_section_type (flags);
778
45
      elf_section_type (sec) = type;
779
45
      elf_section_flags (sec) = attr;
780
45
      elf_section_data (sec)->this_hdr.sh_info = match_p->sh_info;
781
782
      /* Prevent SEC_HAS_CONTENTS from being inadvertently set.  */
783
45
      if (type == SHT_NOBITS)
784
0
  seg_info (sec)->bss = 1;
785
786
      /* Set the section ID and flags.  */
787
45
      sec->section_id = match_p->section_id;
788
45
      flags |= match_p->flags;
789
790
      /* Set the linked-to symbol name.  */
791
45
      sec->map_head.linked_to_symbol_name
792
45
  = match_p->linked_to_symbol_name;
793
794
45
      bfd_set_section_flags (sec, flags);
795
45
      if (flags & (SEC_MERGE | SEC_STRINGS))
796
0
  sec->entsize = entsize;
797
45
      elf_group_name (sec) = match_p->group_name;
798
799
      /* Add a symbol for this section to the symbol table.  */
800
45
      secsym = symbol_find (name);
801
45
      if (secsym != NULL)
802
3
  {
803
    /* We could be repurposing an undefined symbol here: make sure we
804
       reset sy_value to look like other section symbols in order to avoid
805
       trying to incorrectly resolve this section symbol later on.  */
806
3
    static const expressionS exp = { .X_op = O_constant };
807
3
    symbol_set_value_expression (secsym, &exp);
808
3
    symbol_set_bfdsym (secsym, sec->symbol);
809
3
  }
810
42
      else
811
42
  symbol_table_insert (section_symbol (sec));
812
45
    }
813
91
  else
814
91
    {
815
91
      if (type != SHT_NULL
816
91
    && (unsigned) type != elf_section_type (old_sec))
817
0
  {
818
0
    if (ssect != NULL)
819
      /* This is a special section with known type.  User
820
         assembly might get the section type wrong; Even high
821
         profile projects like glibc have done so in the past.
822
         So don't error in this case.  */
823
0
      as_warn (_("ignoring changed section type for %s"), name);
824
0
    else
825
      /* Do error when assembly isn't self-consistent.  */
826
0
      as_bad (_("changed section type for %s"), name);
827
0
  }
828
829
91
      if (attr != 0)
830
0
  {
831
    /* If section attributes are specified the second time we see a
832
       particular section, then check that they are the same as we
833
       saw the first time.  */
834
0
    if (((old_sec->flags ^ flags)
835
0
         & (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
836
0
      | SEC_EXCLUDE | SEC_SORT_ENTRIES | SEC_MERGE | SEC_STRINGS
837
0
      | SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD
838
0
      | SEC_THREAD_LOCAL)))
839
0
      {
840
0
        if (ssect != NULL)
841
0
    as_warn (_("ignoring changed section attributes for %s"), name);
842
0
        else
843
0
    as_bad (_("changed section attributes for %s"), name);
844
0
      }
845
0
    else
846
      /* FIXME: Maybe we should consider removing a previously set
847
         processor or application specific attribute as suspicious?  */
848
0
      elf_section_flags (sec) = attr;
849
850
0
    if ((flags & (SEC_MERGE | SEC_STRINGS))
851
0
        && old_sec->entsize != (unsigned) entsize)
852
0
      as_bad (_("changed section entity size for %s"), name);
853
0
  }
854
91
    }
855
856
136
#ifdef md_elf_section_change_hook
857
136
  md_elf_section_change_hook ();
858
136
#endif
859
136
}
860
861
void
862
obj_elf_change_section (const char *name,
863
      unsigned int type,
864
      bfd_vma attr,
865
      int entsize,
866
      struct elf_section_match *match_p,
867
      bool linkonce)
868
0
{
869
0
  change_section (name, type, attr, entsize, match_p, linkonce, false, 0);
870
0
}
871
872
static bfd_vma
873
obj_elf_parse_section_letters (char *str, size_t len,
874
             bool *is_clone, int *inherit, bfd_vma *gnu_attr)
875
4
{
876
4
  bfd_vma attr = 0;
877
878
4
  *is_clone = false;
879
4
  *inherit = 0;
880
881
4
  while (len > 0)
882
0
    {
883
0
      switch (*str)
884
0
  {
885
0
  case 'a':
886
0
    attr |= SHF_ALLOC;
887
    /* Compatibility.  */
888
0
    if (len > 1 && str[1] == 'm')
889
0
      {
890
0
        attr |= SHF_MERGE;
891
0
        str++, len--;
892
0
        if (len > 1 && str[1] == 's')
893
0
    {
894
0
      attr |= SHF_STRINGS;
895
0
      str++, len--;
896
0
    }
897
0
      }
898
0
    break;
899
0
  case 'e':
900
0
    attr |= SHF_EXCLUDE;
901
0
    break;
902
0
  case 'o':
903
0
    attr |= SHF_LINK_ORDER;
904
0
    break;
905
0
  case 'w':
906
0
    attr |= SHF_WRITE;
907
0
    break;
908
0
  case 'x':
909
0
    attr |= SHF_EXECINSTR;
910
0
    break;
911
0
  case 'M':
912
0
    attr |= SHF_MERGE;
913
0
    break;
914
0
  case 'S':
915
0
    attr |= SHF_STRINGS;
916
0
    break;
917
0
  case 'G':
918
0
    attr |= SHF_GROUP;
919
0
    break;
920
0
  case 'T':
921
0
    attr |= SHF_TLS;
922
0
    break;
923
0
  case 'd':
924
0
    *gnu_attr |= SHF_GNU_MBIND;
925
0
    break;
926
0
  case 'R':
927
0
    *gnu_attr |= SHF_GNU_RETAIN;
928
0
    break;
929
0
  case '?':
930
0
    *is_clone = true;
931
0
    break;
932
0
  default:
933
0
    {
934
0
      const char *bad_msg = _("unrecognized .section attribute:"
935
0
            " want a,e,o,w,x,M,S,G,T or number");
936
0
#ifdef md_elf_section_letter
937
0
      bfd_vma md_attr = md_elf_section_letter (*str, &bad_msg);
938
0
      if (md_attr != (bfd_vma) -1)
939
0
        attr |= md_attr;
940
0
      else
941
0
#endif
942
0
        if (ISDIGIT (*str))
943
0
    {
944
0
      char * end;
945
0
      struct elf_backend_data *bed;
946
0
      bfd_vma numeric_flags = strtoul (str, &end, 0);
947
948
0
      attr |= numeric_flags;
949
950
0
      bed = (struct elf_backend_data *)
951
0
        get_elf_backend_data (stdoutput);
952
953
0
      if (bed->elf_osabi == ELFOSABI_NONE
954
0
          || bed->elf_osabi == ELFOSABI_STANDALONE
955
0
          || bed->elf_osabi == ELFOSABI_GNU
956
0
          || bed->elf_osabi == ELFOSABI_FREEBSD)
957
0
        {
958
          /* Add flags in the SHF_MASKOS range to gnu_attr for
959
       OSABIs that support those flags.
960
       Also adding the flags for ELFOSABI_{NONE,STANDALONE}
961
       allows them to be validated later in obj_elf_section.
962
       We can't just always set these bits in gnu_attr for
963
       all OSABIs, since Binutils does not recognize all
964
       SHF_MASKOS bits for non-GNU OSABIs.  It's therefore
965
       possible that numeric flags are being used to set bits
966
       in the SHF_MASKOS range for those targets, and we
967
       don't want assembly to fail in those situations.  */
968
0
          *gnu_attr |= (numeric_flags & SHF_MASKOS);
969
0
        }
970
971
      /* Update str and len, allowing for the fact that
972
         we will execute str++ and len-- below.  */
973
0
      end --;
974
0
      len -= (end - str);
975
0
      str = end;
976
0
    }
977
0
        else if (!attr && !*gnu_attr && (*str == '+' || *str == '-'))
978
0
    *inherit = *str == '+' ? 1 : -1;
979
0
        else
980
0
    as_fatal ("%s", bad_msg);
981
0
    }
982
0
    break;
983
0
  }
984
0
      str++, len--;
985
0
    }
986
987
4
  return attr;
988
4
}
989
990
static int
991
obj_elf_section_type (char *str, size_t len, bool warn)
992
0
{
993
0
  if (len == 8 && startswith (str, "progbits"))
994
0
    return SHT_PROGBITS;
995
0
  if (len == 6 && startswith (str, "nobits"))
996
0
    return SHT_NOBITS;
997
0
  if (len == 4 && startswith (str, "note"))
998
0
    return SHT_NOTE;
999
0
  if (len == 10 && startswith (str, "init_array"))
1000
0
    return SHT_INIT_ARRAY;
1001
0
  if (len == 10 && startswith (str, "fini_array"))
1002
0
    return SHT_FINI_ARRAY;
1003
0
  if (len == 13 && startswith (str, "preinit_array"))
1004
0
    return SHT_PREINIT_ARRAY;
1005
1006
0
#ifdef md_elf_section_type
1007
0
  {
1008
0
    int md_type = md_elf_section_type (str, len);
1009
0
    if (md_type >= 0)
1010
0
      return md_type;
1011
0
  }
1012
0
#endif
1013
1014
0
  if (ISDIGIT (*str))
1015
0
    {
1016
0
      char * end;
1017
0
      int type = strtoul (str, & end, 0);
1018
1019
0
      if (warn && (size_t) (end - str) != len)
1020
0
  as_warn (_("extraneous characters at end of numeric section type"));
1021
1022
0
      return type;
1023
0
    }
1024
1025
0
  if (warn)
1026
0
    as_warn (_("unrecognized section type"));
1027
0
  return 0;
1028
0
}
1029
1030
#ifdef TC_SPARC
1031
static bfd_vma
1032
obj_elf_section_word (char *str, size_t len, int *type)
1033
{
1034
  int ret;
1035
1036
  if (len == 5 && startswith (str, "write"))
1037
    return SHF_WRITE;
1038
  if (len == 5 && startswith (str, "alloc"))
1039
    return SHF_ALLOC;
1040
  if (len == 9 && startswith (str, "execinstr"))
1041
    return SHF_EXECINSTR;
1042
  if (len == 7 && startswith (str, "exclude"))
1043
    return SHF_EXCLUDE;
1044
  if (len == 3 && startswith (str, "tls"))
1045
    return SHF_TLS;
1046
1047
  ret = obj_elf_section_type (str, len, false);
1048
  if (ret != 0)
1049
    *type = ret;
1050
  else
1051
    as_warn (_("unrecognized section attribute"));
1052
1053
  return 0;
1054
}
1055
#endif
1056
1057
/* Get name of section.  */
1058
const char *
1059
obj_elf_section_name (void)
1060
148
{
1061
148
  char *name;
1062
1063
148
  SKIP_WHITESPACE ();
1064
148
  if (*input_line_pointer == '"')
1065
12
    {
1066
12
      int dummy;
1067
1068
12
      name = demand_copy_C_string (&dummy);
1069
12
      if (name == NULL)
1070
0
  {
1071
0
    ignore_rest_of_line ();
1072
0
    return NULL;
1073
0
  }
1074
12
    }
1075
136
  else
1076
136
    {
1077
136
      char *end = input_line_pointer;
1078
1079
2.05k
      while (!is_whitespace (*end) && !is_end_of_stmt (*end) && *end != ',')
1080
1.92k
  end++;
1081
136
      if (end == input_line_pointer)
1082
4
  {
1083
4
    as_bad (_("missing name"));
1084
4
    ignore_rest_of_line ();
1085
4
    return NULL;
1086
4
  }
1087
1088
132
      obstack_grow0 (&notes, input_line_pointer, end - input_line_pointer);
1089
132
      name = obstack_base (&notes);
1090
1091
132
      while (flag_sectname_subst)
1092
0
        {
1093
0
    char *subst = strchr (name, '%');
1094
0
    if (subst && subst[1] == 'S')
1095
0
      {
1096
0
        size_t head = subst - name;
1097
0
        size_t tail = strlen (subst + 2) + 1;
1098
0
        size_t slen = strlen (now_seg->name);
1099
1100
0
        if (slen > 2)
1101
0
    {
1102
0
      obstack_blank (&notes, slen - 2);
1103
0
      name = obstack_base (&notes);
1104
0
    }
1105
0
        memmove (name + head + slen, name + head + 2, tail);
1106
0
        memcpy (name + head, now_seg->name, slen);
1107
0
      }
1108
0
    else
1109
0
      break;
1110
0
  }
1111
1112
132
      obstack_finish (&notes);
1113
1114
#ifdef tc_canonicalize_section_name
1115
      name = tc_canonicalize_section_name (name);
1116
#endif
1117
132
      input_line_pointer = end;
1118
132
    }
1119
144
  SKIP_WHITESPACE ();
1120
144
  return name;
1121
148
}
1122
1123
/* Arrange to put SEC, known to be in group GNAME into the per-group
1124
   section lists kept by gas.  */
1125
1126
void
1127
elf_set_group_name (asection *sec, const char *gname)
1128
2
{
1129
2
  elf_group_name (sec) = gname;
1130
2
  elf_section_flags (sec) |= SHF_GROUP;
1131
1132
2
  struct elf_section_match match;
1133
2
  match.group_name = gname;
1134
2
  match.linked_to_symbol_name = sec->map_head.linked_to_symbol_name;
1135
2
  match.section_id = sec->section_id;
1136
2
  match.sh_info = elf_section_data (sec)->this_hdr.sh_info;
1137
2
  match.sh_flags = (elf_section_data (sec)->this_hdr.sh_flags
1138
2
        & SEC_ASSEMBLER_SHF_MASK);
1139
2
  match.flags = bfd_section_flags (sec) & SEC_ASSEMBLER_SECTION_ID;
1140
1141
2
  unsigned int group_idx;
1142
2
  if (!group_section_find (&match, sec->name, &group_idx))
1143
2
    group_section_insert (&match, sec, &group_idx);
1144
2
}
1145
1146
static void
1147
obj_elf_attach_to_group (int dummy ATTRIBUTE_UNUSED)
1148
4
{
1149
4
  const char * gname = obj_elf_section_name ();
1150
1151
4
  if (gname == NULL)
1152
0
    {
1153
0
      as_warn (_("group name not parseable"));
1154
0
      return;
1155
0
    }
1156
1157
4
  if (elf_group_name (now_seg))
1158
2
    {
1159
2
      if (strcmp (elf_group_name (now_seg), gname) != 0)
1160
0
  as_warn (_("section %s already has a group (%s)"),
1161
0
     bfd_section_name (now_seg), elf_group_name (now_seg));
1162
2
      return;
1163
2
    }
1164
2
  elf_set_group_name (now_seg, gname);
1165
2
}
1166
1167
void
1168
obj_elf_section (int push)
1169
689
{
1170
689
  const char *name;
1171
689
  char *beg;
1172
689
  int type, dummy;
1173
689
  bfd_vma attr;
1174
689
  bfd_vma gnu_attr;
1175
689
  int entsize;
1176
689
  bool linkonce;
1177
689
  subsegT new_subsection = 0;
1178
689
  struct elf_section_match match;
1179
689
  unsigned long linked_to_section_index = -1UL;
1180
1181
689
  if (flag_mri)
1182
545
    {
1183
545
      char mri_type;
1184
1185
#ifdef md_flush_pending_output
1186
      md_flush_pending_output ();
1187
#endif
1188
1189
545
      obj_elf_section_change_hook ();
1190
1191
545
      s_mri_sect (&mri_type);
1192
1193
545
#ifdef md_elf_section_change_hook
1194
545
      md_elf_section_change_hook ();
1195
545
#endif
1196
1197
545
      return;
1198
545
    }
1199
1200
144
  name = obj_elf_section_name ();
1201
144
  if (name == NULL)
1202
4
    return;
1203
1204
140
  memset (&match, 0, sizeof (match));
1205
1206
140
  symbolS * sym;
1207
140
  if ((sym = symbol_find (name)) != NULL
1208
140
      && ! symbol_section_p (sym)
1209
140
      && S_IS_DEFINED (sym)
1210
140
      && ! S_IS_VOLATILE (sym)
1211
140
      && ! S_CAN_BE_REDEFINED (sym))
1212
4
    {
1213
4
      as_bad (_("section name '%s' already defined as another symbol"), name);
1214
4
      ignore_rest_of_line ();
1215
4
      return;
1216
4
    }
1217
136
  type = SHT_NULL;
1218
136
  attr = 0;
1219
136
  gnu_attr = 0;
1220
136
  entsize = 0;
1221
136
  linkonce = 0;
1222
1223
136
  if (*input_line_pointer == ',')
1224
7
    {
1225
      /* Skip the comma.  */
1226
7
      ++input_line_pointer;
1227
7
      SKIP_WHITESPACE ();
1228
1229
7
      if (push && ISDIGIT (*input_line_pointer))
1230
0
  {
1231
    /* .pushsection has an optional subsection.  */
1232
0
    new_subsection = (subsegT) get_absolute_expression ();
1233
1234
0
    SKIP_WHITESPACE ();
1235
1236
    /* Stop if we don't see a comma.  */
1237
0
    if (*input_line_pointer != ',')
1238
0
      goto done;
1239
1240
    /* Skip the comma.  */
1241
0
    ++input_line_pointer;
1242
0
    SKIP_WHITESPACE ();
1243
0
  }
1244
1245
7
      if (*input_line_pointer == '"')
1246
4
  {
1247
4
    bool is_clone;
1248
4
    int inherit;
1249
1250
4
    beg = demand_copy_C_string (&dummy);
1251
4
    if (beg == NULL)
1252
0
      {
1253
0
        ignore_rest_of_line ();
1254
0
        return;
1255
0
      }
1256
4
    attr = obj_elf_parse_section_letters (beg, strlen (beg), &is_clone,
1257
4
            &inherit, &gnu_attr);
1258
1259
4
    if (inherit > 0)
1260
0
      attr |= elf_section_flags (now_seg);
1261
4
    else if (inherit < 0)
1262
0
      attr = elf_section_flags (now_seg) & ~attr;
1263
4
    if (inherit)
1264
0
      type = elf_section_type (now_seg);
1265
1266
4
    SKIP_WHITESPACE ();
1267
4
    if (*input_line_pointer == ',')
1268
0
      {
1269
0
        char c;
1270
0
        char *save = input_line_pointer;
1271
1272
0
        ++input_line_pointer;
1273
0
        SKIP_WHITESPACE ();
1274
0
        c = *input_line_pointer;
1275
0
        if (c == '"')
1276
0
    {
1277
0
      beg = demand_copy_C_string (&dummy);
1278
0
      if (beg == NULL)
1279
0
        {
1280
0
          ignore_rest_of_line ();
1281
0
          return;
1282
0
        }
1283
0
      type = obj_elf_section_type (beg, strlen (beg), true);
1284
0
    }
1285
0
        else if (c == '@' || c == '%')
1286
0
    {
1287
0
      ++input_line_pointer;
1288
1289
0
      if (ISDIGIT (* input_line_pointer))
1290
0
        type = strtoul (input_line_pointer, &input_line_pointer, 0);
1291
0
      else
1292
0
        {
1293
0
          c = get_symbol_name (& beg);
1294
0
          (void) restore_line_pointer (c);
1295
0
          type = obj_elf_section_type (beg,
1296
0
               input_line_pointer - beg,
1297
0
               true);
1298
0
        }
1299
0
    }
1300
0
        else
1301
0
    input_line_pointer = save;
1302
0
      }
1303
1304
4
    SKIP_WHITESPACE ();
1305
4
    if ((attr & (SHF_MERGE | SHF_STRINGS)) != 0
1306
4
        && *input_line_pointer == ',')
1307
0
      {
1308
0
        ++input_line_pointer;
1309
0
        SKIP_WHITESPACE ();
1310
0
        if (inherit && *input_line_pointer == ','
1311
0
      && (bfd_section_flags (now_seg)
1312
0
          & (SEC_MERGE | SEC_STRINGS)) != 0)
1313
0
    goto fetch_entsize;
1314
0
        if (is_end_of_stmt (*input_line_pointer))
1315
0
    {
1316
      /* ??? This is here for older versions of gcc that
1317
         test for gas string merge support with
1318
         '.section .rodata.str, "aMS", @progbits, 1'
1319
         Unfortunately '@' begins a comment on arm.
1320
         This isn't as_warn because gcc tests with
1321
         --fatal-warnings. */
1322
0
      as_tsktsk (_("missing merge / string entity size, 1 assumed"));
1323
0
      entsize = 1;
1324
0
    }
1325
0
        else
1326
0
    {
1327
0
      entsize = get_absolute_expression ();
1328
0
      SKIP_WHITESPACE ();
1329
0
      if (entsize <= 0)
1330
0
        {
1331
0
          as_warn (_("invalid merge / string entity size"));
1332
0
          attr &= ~(SHF_MERGE | SHF_STRINGS);
1333
0
          entsize = 0;
1334
0
        }
1335
0
    }
1336
0
      }
1337
4
    else if ((attr & (SHF_MERGE | SHF_STRINGS)) != 0 && inherit
1338
4
        && (bfd_section_flags (now_seg)
1339
0
      & (SEC_MERGE | SEC_STRINGS)) != 0)
1340
0
      {
1341
0
      fetch_entsize:
1342
0
        entsize = now_seg->entsize;
1343
0
      }
1344
4
    else if ((attr & SHF_MERGE) != 0)
1345
0
      {
1346
        /* ??? Perhaps we should error here.  The manual says that
1347
     entsize must be specified if SHF_MERGE is set.  */
1348
0
        as_warn (_("entity size for SHF_MERGE not specified"));
1349
0
        attr &= ~(SHF_MERGE | SHF_STRINGS);
1350
0
      }
1351
4
    else if ((attr & SHF_STRINGS) != 0)
1352
0
      {
1353
        /* Ideally we would warn about this, but older versions
1354
     of gas did not permit an entity size to be specified,
1355
     so we have to default this silently for
1356
     compatibility.  */
1357
0
        entsize = 1;
1358
0
      }
1359
1360
4
    if ((attr & (SHF_MERGE | SHF_STRINGS)) != 0 && type == SHT_NOBITS)
1361
0
      as_warn (_("bogus SHF_MERGE / SHF_STRINGS for SHT_NOBITS section"));
1362
1363
4
    if ((attr & SHF_LINK_ORDER) != 0 && *input_line_pointer == ',')
1364
0
      {
1365
0
        ++input_line_pointer;
1366
0
        SKIP_WHITESPACE ();
1367
        /* Check for a numeric section index, rather than a symbol name.  */
1368
0
        if (ISDIGIT (* input_line_pointer))
1369
0
    {
1370
0
      linked_to_section_index = strtoul (input_line_pointer, & input_line_pointer, 0);
1371
0
    }
1372
0
        else if (inherit && *input_line_pointer == ','
1373
0
           && (elf_section_flags (now_seg) & SHF_LINK_ORDER) != 0)
1374
0
    goto fetch_linked_to;
1375
0
        else
1376
0
    {
1377
0
      char c;
1378
0
      unsigned int length;
1379
1380
0
      c = get_symbol_name (& beg);
1381
0
      (void) restore_line_pointer (c);
1382
0
      length = input_line_pointer - beg;
1383
0
      if (length)
1384
0
        match.linked_to_symbol_name
1385
0
          = notes_memdup (beg, length, length + 1);
1386
0
    }
1387
0
      }
1388
4
    else if ((attr & SHF_LINK_ORDER) != 0 && inherit
1389
4
       && (elf_section_flags (now_seg) & SHF_LINK_ORDER) != 0)
1390
0
      {
1391
0
      fetch_linked_to:
1392
0
        if (now_seg->map_head.linked_to_symbol_name)
1393
0
    match.linked_to_symbol_name =
1394
0
      now_seg->map_head.linked_to_symbol_name;
1395
0
        else
1396
0
    linked_to_section_index =
1397
0
      elf_section_data (now_seg)->this_hdr.sh_link;
1398
0
      }
1399
1400
4
    if ((attr & SHF_GROUP) != 0 && is_clone)
1401
0
      {
1402
0
        as_warn (_("? section flag ignored with G present"));
1403
0
        is_clone = false;
1404
0
      }
1405
1406
4
    if ((attr & SHF_GROUP) != 0 && *input_line_pointer == ',')
1407
0
      {
1408
0
        ++input_line_pointer;
1409
0
        SKIP_WHITESPACE ();
1410
0
        if (inherit && *input_line_pointer == ','
1411
0
      && (elf_section_flags (now_seg) & SHF_GROUP) != 0)
1412
0
    goto fetch_group;
1413
0
        match.group_name = obj_elf_section_name ();
1414
0
        if (match.group_name == NULL)
1415
0
    attr &= ~SHF_GROUP;
1416
0
        else if (*input_line_pointer == ',')
1417
0
    {
1418
0
      ++input_line_pointer;
1419
0
      SKIP_WHITESPACE ();
1420
0
      if (startswith (input_line_pointer, "comdat"))
1421
0
        {
1422
0
          input_line_pointer += 6;
1423
0
          linkonce = 1;
1424
0
        }
1425
0
    }
1426
0
        else if (startswith (name, ".gnu.linkonce"))
1427
0
    linkonce = 1;
1428
0
      }
1429
4
    else if ((attr & SHF_GROUP) != 0 && inherit
1430
4
       && (elf_section_flags (now_seg) & SHF_GROUP) != 0)
1431
0
      {
1432
0
      fetch_group:
1433
0
        match.group_name = elf_group_name (now_seg);
1434
0
        linkonce =
1435
0
          (bfd_section_flags (now_seg) & SEC_LINK_ONCE) != 0;
1436
0
      }
1437
4
    else if ((attr & SHF_GROUP) != 0)
1438
0
      {
1439
0
        as_warn (_("group name for SHF_GROUP not specified"));
1440
0
        attr &= ~SHF_GROUP;
1441
0
      }
1442
1443
4
    if (is_clone)
1444
0
      {
1445
0
        const char *now_group = elf_group_name (now_seg);
1446
0
        if (now_group != NULL)
1447
0
    {
1448
0
      match.group_name = now_group;
1449
0
      linkonce = (now_seg->flags & SEC_LINK_ONCE) != 0;
1450
0
    }
1451
0
      }
1452
1453
4
    if ((gnu_attr & SHF_GNU_MBIND) != 0 && *input_line_pointer == ',')
1454
0
      {
1455
0
        char *save = input_line_pointer;
1456
0
        ++input_line_pointer;
1457
0
        SKIP_WHITESPACE ();
1458
0
        if (ISDIGIT (* input_line_pointer))
1459
0
    {
1460
0
      char *t = input_line_pointer;
1461
0
      match.sh_info = strtoul (input_line_pointer,
1462
0
          &input_line_pointer, 0);
1463
0
      if (match.sh_info == (unsigned int) -1)
1464
0
        {
1465
0
          as_warn (_("unsupported mbind section info: %s"), t);
1466
0
          match.sh_info = 0;
1467
0
        }
1468
0
    }
1469
0
        else
1470
0
    input_line_pointer = save;
1471
0
      }
1472
1473
4
    if ((gnu_attr & SHF_GNU_RETAIN) != 0)
1474
0
      match.sh_flags |= SHF_GNU_RETAIN;
1475
1476
4
    if (*input_line_pointer == ',')
1477
0
      {
1478
0
        char *save = input_line_pointer;
1479
1480
0
        ++input_line_pointer;
1481
0
        SKIP_WHITESPACE ();
1482
0
        if (startswith (input_line_pointer, "unique"))
1483
0
    {
1484
0
      input_line_pointer += 6;
1485
0
      SKIP_WHITESPACE ();
1486
0
      if (*input_line_pointer == ',')
1487
0
        {
1488
0
          ++input_line_pointer;
1489
0
          SKIP_WHITESPACE ();
1490
0
          if (ISDIGIT (* input_line_pointer))
1491
0
      {
1492
0
        bfd_vma id;
1493
0
        bool overflow;
1494
0
        char *t = input_line_pointer;
1495
0
        if (sizeof (bfd_vma) <= sizeof (unsigned long))
1496
0
          {
1497
0
            errno = 0;
1498
0
            id = strtoul (input_line_pointer,
1499
0
              &input_line_pointer, 0);
1500
0
            overflow = (id == (unsigned long) -1
1501
0
            && errno == ERANGE);
1502
0
          }
1503
0
        else
1504
0
          {
1505
0
            id = bfd_scan_vma
1506
0
        (input_line_pointer,
1507
0
         (const char **) &input_line_pointer, 0);
1508
0
            overflow = id == ~(bfd_vma) 0;
1509
0
          }
1510
0
        if (overflow || id > (unsigned int) -1)
1511
0
          {
1512
0
            char *linefeed, saved_char = 0;
1513
0
            if ((linefeed = strchr (t, '\n')) != NULL)
1514
0
        {
1515
0
          saved_char = *linefeed;
1516
0
          *linefeed = '\0';
1517
0
        }
1518
0
            as_bad (_("unsupported section id: %s"), t);
1519
0
            if (saved_char)
1520
0
        *linefeed = saved_char;
1521
0
          }
1522
0
        else
1523
0
          {
1524
0
            match.section_id = id;
1525
0
            match.flags |= SEC_ASSEMBLER_SECTION_ID;
1526
0
          }
1527
0
      }
1528
0
        }
1529
0
    }
1530
0
        else
1531
0
    input_line_pointer = save;
1532
0
      }
1533
4
  }
1534
#ifdef TC_SPARC
1535
      else
1536
  {
1537
    do
1538
      {
1539
        char c;
1540
1541
        SKIP_WHITESPACE ();
1542
        if (*input_line_pointer != '#')
1543
    {
1544
      as_bad (_("character following name is not '#'"));
1545
      ignore_rest_of_line ();
1546
      return;
1547
    }
1548
        ++input_line_pointer;
1549
        c = get_symbol_name (& beg);
1550
        (void) restore_line_pointer (c);
1551
1552
        attr |= obj_elf_section_word (beg, input_line_pointer - beg,
1553
              &type);
1554
1555
        SKIP_WHITESPACE ();
1556
      }
1557
    while (*input_line_pointer++ == ',');
1558
    --input_line_pointer;
1559
  }
1560
#endif
1561
7
    }
1562
1563
136
 done:
1564
136
  demand_empty_rest_of_line ();
1565
1566
136
  if ((gnu_attr & (SHF_GNU_MBIND | SHF_GNU_RETAIN)) != 0)
1567
0
    {
1568
0
      const struct elf_backend_data *bed;
1569
0
      bool mbind_p = (gnu_attr & SHF_GNU_MBIND) != 0;
1570
1571
0
      if (mbind_p && (attr & SHF_ALLOC) == 0)
1572
0
  as_bad (_("SHF_ALLOC isn't set for GNU_MBIND section: %s"), name);
1573
1574
0
      bed = get_elf_backend_data (stdoutput);
1575
1576
0
      if (bed->elf_osabi != ELFOSABI_GNU
1577
0
    && bed->elf_osabi != ELFOSABI_FREEBSD
1578
0
    && bed->elf_osabi != ELFOSABI_NONE)
1579
0
  as_bad (_("%s section is supported only by GNU and FreeBSD targets"),
1580
0
    mbind_p ? "GNU_MBIND" : "GNU_RETAIN");
1581
0
      else
1582
0
  {
1583
0
    if (mbind_p)
1584
0
      elf_tdata (stdoutput)->has_gnu_osabi |= elf_gnu_osabi_mbind;
1585
0
    if ((gnu_attr & SHF_GNU_RETAIN) != 0)
1586
0
      elf_tdata (stdoutput)->has_gnu_osabi |= elf_gnu_osabi_retain;
1587
1588
0
    attr |= gnu_attr;
1589
0
  }
1590
0
    }
1591
1592
136
  change_section (name, type, attr, entsize, &match, linkonce, push,
1593
136
      new_subsection);
1594
1595
136
  if (linked_to_section_index != -1UL)
1596
0
    {
1597
0
      elf_section_flags (now_seg) |= SHF_LINK_ORDER;
1598
0
      elf_section_data (now_seg)->this_hdr.sh_link = linked_to_section_index;
1599
      /* FIXME: Should we perform some sanity checking on the section index ?  */
1600
0
    }
1601
136
}
1602
1603
/* Change to the .bss section.  */
1604
1605
void
1606
obj_elf_bss (int i ATTRIBUTE_UNUSED)
1607
16
{
1608
16
  int temp;
1609
1610
#ifdef md_flush_pending_output
1611
  md_flush_pending_output ();
1612
#endif
1613
1614
16
  obj_elf_section_change_hook ();
1615
1616
16
  temp = get_absolute_expression ();
1617
16
  subseg_set (bss_section, (subsegT) temp);
1618
16
  demand_empty_rest_of_line ();
1619
1620
16
#ifdef md_elf_section_change_hook
1621
16
  md_elf_section_change_hook ();
1622
16
#endif
1623
16
}
1624
1625
/* Change to the .data section.  */
1626
1627
void
1628
obj_elf_data (int i)
1629
112
{
1630
#ifdef md_flush_pending_output
1631
  md_flush_pending_output ();
1632
#endif
1633
1634
112
  obj_elf_section_change_hook ();
1635
1636
112
  s_data (i);
1637
1638
112
#ifdef md_elf_section_change_hook
1639
112
  md_elf_section_change_hook ();
1640
112
#endif
1641
112
}
1642
1643
/* Change to the .text section.  */
1644
1645
void
1646
obj_elf_text (int i)
1647
1.26k
{
1648
#ifdef md_flush_pending_output
1649
  md_flush_pending_output ();
1650
#endif
1651
1652
1.26k
  obj_elf_section_change_hook ();
1653
1654
1.26k
  s_text (i);
1655
1656
1.26k
#ifdef md_elf_section_change_hook
1657
1.26k
  md_elf_section_change_hook ();
1658
1.26k
#endif
1659
1.26k
}
1660
1661
/* Change to the *ABS* section.  */
1662
1663
void
1664
obj_elf_struct (int i)
1665
457
{
1666
#ifdef md_flush_pending_output
1667
  md_flush_pending_output ();
1668
#endif
1669
1670
457
  obj_elf_section_change_hook ();
1671
1672
457
  s_struct (i);
1673
1674
457
#ifdef md_elf_section_change_hook
1675
457
  md_elf_section_change_hook ();
1676
457
#endif
1677
457
}
1678
1679
static void
1680
obj_elf_subsection (int ignore ATTRIBUTE_UNUSED)
1681
0
{
1682
0
  int temp;
1683
1684
#ifdef md_flush_pending_output
1685
  md_flush_pending_output ();
1686
#endif
1687
1688
0
  obj_elf_section_change_hook ();
1689
1690
0
  temp = get_absolute_expression ();
1691
0
  subseg_set (now_seg, (subsegT) temp);
1692
0
  demand_empty_rest_of_line ();
1693
1694
0
#ifdef md_elf_section_change_hook
1695
0
  md_elf_section_change_hook ();
1696
0
#endif
1697
0
}
1698
1699
/* This can be called from the processor backends if they change
1700
   sections.  */
1701
1702
void
1703
obj_elf_section_change_hook (void)
1704
2.98k
{
1705
2.98k
  previous_section = now_seg;
1706
2.98k
  previous_subsection = now_subseg;
1707
2.98k
}
1708
1709
void
1710
obj_elf_previous (int ignore ATTRIBUTE_UNUSED)
1711
0
{
1712
0
  segT new_section;
1713
0
  int new_subsection;
1714
1715
0
  if (previous_section == 0)
1716
0
    {
1717
0
      as_warn (_(".previous without corresponding .section; ignored"));
1718
0
      return;
1719
0
    }
1720
1721
#ifdef md_flush_pending_output
1722
  md_flush_pending_output ();
1723
#endif
1724
1725
0
  new_section = previous_section;
1726
0
  new_subsection = previous_subsection;
1727
0
  obj_elf_section_change_hook ();
1728
1729
0
  subseg_set (new_section, new_subsection);
1730
1731
0
#ifdef md_elf_section_change_hook
1732
0
  md_elf_section_change_hook ();
1733
0
#endif
1734
0
}
1735
1736
static void
1737
obj_elf_popsection (int xxx ATTRIBUTE_UNUSED)
1738
0
{
1739
0
  struct section_stack *top = section_stack;
1740
1741
0
  if (top == NULL)
1742
0
    {
1743
0
      as_warn (_(".popsection without corresponding .pushsection; ignored"));
1744
0
      return;
1745
0
    }
1746
1747
#ifdef md_flush_pending_output
1748
  md_flush_pending_output ();
1749
#endif
1750
1751
0
  section_stack = top->next;
1752
0
  previous_section = top->prev_seg;
1753
0
  previous_subsection = top->prev_subseg;
1754
0
  subseg_set (top->seg, top->subseg);
1755
0
  free (top);
1756
1757
0
#ifdef md_elf_section_change_hook
1758
0
  md_elf_section_change_hook ();
1759
0
#endif
1760
0
}
1761
1762
static void
1763
obj_elf_line (int ignore ATTRIBUTE_UNUSED)
1764
137
{
1765
  /* Assume delimiter is part of expression.  BSD4.2 as fails with
1766
     delightful bug, so we are not being incompatible here.  */
1767
137
  new_logical_line (NULL, get_absolute_expression ());
1768
137
  demand_empty_rest_of_line ();
1769
137
}
1770
1771
static struct elf_versioned_name_list *
1772
obj_elf_find_and_add_versioned_name (const char *version_name,
1773
             const char *sym_name,
1774
             const char *ver,
1775
             struct elf_obj_sy *sy_obj)
1776
0
{
1777
0
  struct elf_versioned_name_list *versioned_name;
1778
0
  const char *p;
1779
1780
0
  for (p = ver + 1; *p == ELF_VER_CHR; p++)
1781
0
    ;
1782
1783
  /* NB: Since some tests in ld/testsuite/ld-elfvers have no version
1784
     names, we have to disable this.  */
1785
0
  if (0 && *p == '\0')
1786
0
    {
1787
0
      as_bad (_("missing version name in `%s' for symbol `%s'"),
1788
0
        version_name, sym_name);
1789
0
      return NULL;
1790
0
    }
1791
1792
0
  versioned_name = sy_obj->versioned_name;
1793
1794
0
  switch (p - ver)
1795
0
    {
1796
0
    case 1:
1797
0
    case 2:
1798
0
      break;
1799
0
    case 3:
1800
0
      if (sy_obj->rename)
1801
0
  {
1802
0
    if (strcmp (versioned_name->name, version_name) == 0)
1803
0
      return versioned_name;
1804
0
    else
1805
0
      {
1806
0
        as_bad (_("only one version name with `@@@' is allowed "
1807
0
      "for symbol `%s'"), sym_name);
1808
0
        return NULL;
1809
0
      }
1810
0
  }
1811
0
      sy_obj->rename = true;
1812
0
      break;
1813
0
    default:
1814
0
      as_bad (_("invalid version name '%s' for symbol `%s'"),
1815
0
        version_name, sym_name);
1816
0
      return NULL;
1817
0
    }
1818
1819
0
  for (;
1820
0
       versioned_name != NULL;
1821
0
       versioned_name = versioned_name->next)
1822
0
    if (strcmp (versioned_name->name, version_name) == 0)
1823
0
      return versioned_name;
1824
1825
  /* Add this versioned name to the head of the list,  */
1826
0
  versioned_name = notes_alloc (sizeof (*versioned_name));
1827
0
  versioned_name->name = notes_strdup (version_name);
1828
0
  versioned_name->next = sy_obj->versioned_name;
1829
0
  sy_obj->versioned_name = versioned_name;
1830
1831
0
  return versioned_name;
1832
0
}
1833
1834
/* This handles the .symver pseudo-op, which is used to specify a
1835
   symbol version.  The syntax is ``.symver NAME,SYMVERNAME''.
1836
   SYMVERNAME may contain ELF_VER_CHR ('@') characters.  This
1837
   pseudo-op causes the assembler to emit a symbol named SYMVERNAME
1838
   with the same value as the symbol NAME.  */
1839
1840
static void
1841
obj_elf_symver (int ignore ATTRIBUTE_UNUSED)
1842
0
{
1843
0
  char *name;
1844
0
  const char *sym_name;
1845
0
  char c;
1846
0
  char old_lexat;
1847
0
  symbolS *sym;
1848
0
  struct elf_obj_sy *sy_obj;
1849
0
  char *p;
1850
1851
0
  sym = get_sym_from_input_line_and_check ();
1852
1853
0
  if (*input_line_pointer != ',')
1854
0
    {
1855
0
      as_bad (_("expected comma after name in .symver"));
1856
0
      ignore_rest_of_line ();
1857
0
      return;
1858
0
    }
1859
1860
0
  ++input_line_pointer;
1861
0
  SKIP_WHITESPACE ();
1862
1863
  /* Temporarily include '@' in symbol names.  */
1864
0
  old_lexat = lex_type[(unsigned char) '@'];
1865
0
  lex_type[(unsigned char) '@'] |= LEX_NAME;
1866
0
  c = get_symbol_name (& name);
1867
0
  lex_type[(unsigned char) '@'] = old_lexat;
1868
0
  sym_name = S_GET_NAME (sym);
1869
1870
0
  if (S_IS_COMMON (sym))
1871
0
    {
1872
0
      as_bad (_("`%s' can't be versioned to common symbol '%s'"),
1873
0
        name, sym_name);
1874
0
      ignore_rest_of_line ();
1875
0
      return;
1876
0
    }
1877
1878
0
  p = strchr (name, ELF_VER_CHR);
1879
0
  if (p == NULL)
1880
0
    {
1881
0
      as_bad (_("missing version name in `%s' for symbol `%s'"),
1882
0
        name, sym_name);
1883
0
      ignore_rest_of_line ();
1884
0
      return;
1885
0
    }
1886
1887
0
  sy_obj = symbol_get_obj (sym);
1888
0
  if (obj_elf_find_and_add_versioned_name (name, sym_name,
1889
0
             p, sy_obj) == NULL)
1890
0
    {
1891
0
      sy_obj->bad_version = true;
1892
0
      ignore_rest_of_line ();
1893
0
      return;
1894
0
    }
1895
1896
0
  (void) restore_line_pointer (c);
1897
1898
0
  if (*input_line_pointer == ',')
1899
0
    {
1900
0
      char *save = input_line_pointer;
1901
1902
0
      ++input_line_pointer;
1903
0
      SKIP_WHITESPACE ();
1904
0
      if (startswith (input_line_pointer, "local"))
1905
0
  {
1906
0
    input_line_pointer += 5;
1907
0
    sy_obj->visibility = visibility_local;
1908
0
  }
1909
0
      else if (startswith (input_line_pointer, "hidden"))
1910
0
  {
1911
0
    input_line_pointer += 6;
1912
0
    sy_obj->visibility = visibility_hidden;
1913
0
  }
1914
0
      else if (startswith (input_line_pointer, "remove"))
1915
0
  {
1916
0
    input_line_pointer += 6;
1917
0
    sy_obj->visibility = visibility_remove;
1918
0
  }
1919
0
      else
1920
0
  input_line_pointer = save;
1921
0
    }
1922
1923
0
  demand_empty_rest_of_line ();
1924
0
}
1925
1926
/* This handles the .vtable_inherit pseudo-op, which is used to indicate
1927
   to the linker the hierarchy in which a particular table resides.  The
1928
   syntax is ".vtable_inherit CHILDNAME, PARENTNAME".  */
1929
1930
struct fix *
1931
obj_elf_get_vtable_inherit (void)
1932
0
{
1933
0
  char *cname, *pname;
1934
0
  symbolS *csym, *psym;
1935
0
  char c, bad = 0;
1936
1937
0
  if (*input_line_pointer == '#')
1938
0
    ++input_line_pointer;
1939
1940
0
  c = get_symbol_name (& cname);
1941
0
  csym = symbol_find (cname);
1942
1943
  /* GCFIXME: should check that we don't have two .vtable_inherits for
1944
     the same child symbol.  Also, we can currently only do this if the
1945
     child symbol is already exists and is placed in a fragment.  */
1946
1947
0
  if (csym == NULL || symbol_get_frag (csym) == NULL)
1948
0
    {
1949
0
      as_bad (_("expected `%s' to have already been set for .vtable_inherit"),
1950
0
        cname);
1951
0
      bad = 1;
1952
0
    }
1953
1954
0
  restore_line_pointer (c);
1955
1956
0
  SKIP_WHITESPACE ();
1957
0
  if (*input_line_pointer != ',')
1958
0
    {
1959
0
      as_bad (_("expected comma after name in .vtable_inherit"));
1960
0
      ignore_rest_of_line ();
1961
0
      return NULL;
1962
0
    }
1963
1964
0
  ++input_line_pointer;
1965
0
  SKIP_WHITESPACE ();
1966
1967
0
  if (*input_line_pointer == '#')
1968
0
    ++input_line_pointer;
1969
1970
0
  if (input_line_pointer[0] == '0'
1971
0
      && (is_end_of_stmt (input_line_pointer[1])
1972
0
    || is_whitespace (input_line_pointer[1])))
1973
0
    {
1974
0
      psym = section_symbol (absolute_section);
1975
0
      ++input_line_pointer;
1976
0
    }
1977
0
  else
1978
0
    {
1979
0
      c = get_symbol_name (& pname);
1980
0
      psym = symbol_find_or_make (pname);
1981
0
      restore_line_pointer (c);
1982
0
    }
1983
1984
0
  demand_empty_rest_of_line ();
1985
1986
0
  if (bad)
1987
0
    return NULL;
1988
1989
0
  gas_assert (symbol_get_value_expression (csym)->X_op == O_constant);
1990
0
  return fix_new (symbol_get_frag (csym),
1991
0
      symbol_get_value_expression (csym)->X_add_number,
1992
0
      0, psym, 0, 0, BFD_RELOC_VTABLE_INHERIT);
1993
0
}
1994
1995
/* This is a version of obj_elf_get_vtable_inherit() that is
1996
   suitable for use in struct _pseudo_type tables.  */
1997
1998
void
1999
obj_elf_vtable_inherit (int ignore ATTRIBUTE_UNUSED)
2000
0
{
2001
0
  (void) obj_elf_get_vtable_inherit ();
2002
0
}
2003
2004
/* This handles the .vtable_entry pseudo-op, which is used to indicate
2005
   to the linker that a vtable slot was used.  The syntax is
2006
   ".vtable_entry tablename, offset".  */
2007
2008
struct fix *
2009
obj_elf_get_vtable_entry (void)
2010
0
{
2011
0
  symbolS *sym;
2012
0
  offsetT offset;
2013
2014
0
  if (*input_line_pointer == '#')
2015
0
    ++input_line_pointer;
2016
2017
0
  sym = get_sym_from_input_line_and_check ();
2018
0
  if (*input_line_pointer != ',')
2019
0
    {
2020
0
      as_bad (_("expected comma after name in .vtable_entry"));
2021
0
      ignore_rest_of_line ();
2022
0
      return NULL;
2023
0
    }
2024
2025
0
  ++input_line_pointer;
2026
0
  if (*input_line_pointer == '#')
2027
0
    ++input_line_pointer;
2028
2029
0
  offset = get_absolute_expression ();
2030
2031
0
  demand_empty_rest_of_line ();
2032
2033
0
  return fix_new (frag_now, frag_now_fix (), 0, sym, offset, 0,
2034
0
      BFD_RELOC_VTABLE_ENTRY);
2035
0
}
2036
2037
/* This is a version of obj_elf_get_vtable_entry() that is
2038
   suitable for use in struct _pseudo_type tables.  */
2039
2040
void
2041
obj_elf_vtable_entry (int ignore ATTRIBUTE_UNUSED)
2042
0
{
2043
0
  (void) obj_elf_get_vtable_entry ();
2044
0
}
2045
2046
0
#define skip_whitespace(str)  do { if (is_whitespace (*(str))) ++(str); } while (0)
2047
2048
static inline int
2049
skip_past_char (char ** str, char c)
2050
0
{
2051
0
  if (**str == c)
2052
0
    {
2053
0
      (*str)++;
2054
0
      return 0;
2055
0
    }
2056
0
  else
2057
0
    return -1;
2058
0
}
2059
0
#define skip_past_comma(str) skip_past_char (str, ',')
2060
2061
/* A list of attributes that have been explicitly set by the assembly code.
2062
   VENDOR is the vendor id, BASE is the tag shifted right by the number
2063
   of bits in MASK, and bit N of MASK is set if tag BASE+N has been set.  */
2064
struct recorded_attribute_info {
2065
  struct recorded_attribute_info *next;
2066
  int vendor;
2067
  unsigned int base;
2068
  unsigned long mask;
2069
};
2070
static struct recorded_attribute_info *recorded_attributes;
2071
2072
/* Record that we have seen an explicit specification of attribute TAG
2073
   for vendor VENDOR.  */
2074
2075
static void
2076
record_attribute (int vendor, unsigned int tag)
2077
0
{
2078
0
  unsigned int base;
2079
0
  unsigned long mask;
2080
0
  struct recorded_attribute_info *rai;
2081
2082
0
  base = tag / (8 * sizeof (rai->mask));
2083
0
  mask = 1UL << (tag % (8 * sizeof (rai->mask)));
2084
0
  for (rai = recorded_attributes; rai; rai = rai->next)
2085
0
    if (rai->vendor == vendor && rai->base == base)
2086
0
      {
2087
0
  rai->mask |= mask;
2088
0
  return;
2089
0
      }
2090
2091
0
  rai = XNEW (struct recorded_attribute_info);
2092
0
  rai->next = recorded_attributes;
2093
0
  rai->vendor = vendor;
2094
0
  rai->base = base;
2095
0
  rai->mask = mask;
2096
0
  recorded_attributes = rai;
2097
0
}
2098
2099
/* Return true if we have seen an explicit specification of attribute TAG
2100
   for vendor VENDOR.  */
2101
2102
bool
2103
obj_elf_seen_attribute (int vendor, unsigned int tag)
2104
0
{
2105
0
  unsigned int base;
2106
0
  unsigned long mask;
2107
0
  struct recorded_attribute_info *rai;
2108
2109
0
  base = tag / (8 * sizeof (rai->mask));
2110
0
  mask = 1UL << (tag % (8 * sizeof (rai->mask)));
2111
0
  for (rai = recorded_attributes; rai; rai = rai->next)
2112
0
    if (rai->vendor == vendor && rai->base == base)
2113
0
      return (rai->mask & mask) != 0;
2114
0
  return false;
2115
0
}
2116
2117
/* Parse an attribute directive for VENDOR.
2118
   Returns the attribute number read, or zero on error.  */
2119
2120
int
2121
obj_elf_vendor_attribute (int vendor)
2122
0
{
2123
0
  expressionS exp;
2124
0
  int type;
2125
0
  int tag;
2126
0
  unsigned int i = 0;
2127
0
  char *s = NULL;
2128
2129
  /* Read the first number or name.  */
2130
0
  skip_whitespace (input_line_pointer);
2131
0
  s = input_line_pointer;
2132
0
  if (ISDIGIT (*input_line_pointer))
2133
0
    {
2134
0
      expression (& exp);
2135
0
      if (exp.X_op != O_constant)
2136
0
  goto bad;
2137
0
      tag = exp.X_add_number;
2138
0
    }
2139
0
  else
2140
0
    {
2141
0
      char *name;
2142
2143
      /* A name may contain '_', but no other punctuation.  */
2144
0
      for (; ISALNUM (*input_line_pointer) || *input_line_pointer == '_';
2145
0
     ++input_line_pointer)
2146
0
  i++;
2147
0
      if (i == 0)
2148
0
  goto bad;
2149
2150
0
      name = xmemdup0 (s, i);
2151
2152
0
#ifndef CONVERT_SYMBOLIC_ATTRIBUTE
2153
0
#define CONVERT_SYMBOLIC_ATTRIBUTE(a) -1
2154
0
#endif
2155
2156
0
      tag = CONVERT_SYMBOLIC_ATTRIBUTE (name);
2157
0
      if (tag == -1)
2158
0
  {
2159
0
    as_bad (_("Attribute name not recognised: %s"), name);
2160
0
    ignore_rest_of_line ();
2161
0
    free (name);
2162
0
    return 0;
2163
0
  }
2164
0
      free (name);
2165
0
    }
2166
2167
0
  type = _bfd_elf_obj_attrs_arg_type (stdoutput, vendor, tag);
2168
2169
0
  if (skip_past_comma (&input_line_pointer) == -1)
2170
0
    goto bad;
2171
0
  if (type & 1)
2172
0
    {
2173
0
      expression (& exp);
2174
0
      if (exp.X_op != O_constant)
2175
0
  {
2176
0
    as_bad (_("expected numeric constant"));
2177
0
    ignore_rest_of_line ();
2178
0
    return 0;
2179
0
  }
2180
0
      i = exp.X_add_number;
2181
0
    }
2182
0
  if ((type & 3) == 3
2183
0
      && skip_past_comma (&input_line_pointer) == -1)
2184
0
    {
2185
0
      as_bad (_("expected comma"));
2186
0
      ignore_rest_of_line ();
2187
0
      return 0;
2188
0
    }
2189
0
  if (type & 2)
2190
0
    {
2191
0
      int len;
2192
2193
0
      skip_whitespace (input_line_pointer);
2194
0
      if (*input_line_pointer != '"')
2195
0
  goto bad_string;
2196
0
      s = demand_copy_C_string (&len);
2197
0
    }
2198
2199
0
  record_attribute (vendor, tag);
2200
0
  bool ok = false;
2201
0
  switch (type & 3)
2202
0
    {
2203
0
    case 3:
2204
0
      ok = bfd_elf_add_obj_attr_int_string (stdoutput, vendor, tag, i, s);
2205
0
      break;
2206
0
    case 2:
2207
0
      ok = bfd_elf_add_obj_attr_string (stdoutput, vendor, tag, s);
2208
0
      break;
2209
0
    case 1:
2210
0
      ok = bfd_elf_add_obj_attr_int (stdoutput, vendor, tag, i);
2211
0
      break;
2212
0
    default:
2213
0
      abort ();
2214
0
    }
2215
0
  if (!ok)
2216
0
    as_fatal (_("error adding attribute: %s"),
2217
0
        bfd_errmsg (bfd_get_error ()));
2218
2219
0
  demand_empty_rest_of_line ();
2220
0
  return tag;
2221
0
 bad_string:
2222
0
  as_bad (_("bad string constant"));
2223
0
  ignore_rest_of_line ();
2224
0
  return 0;
2225
0
 bad:
2226
0
  as_bad (_("expected <tag> , <value>"));
2227
0
  ignore_rest_of_line ();
2228
0
  return 0;
2229
0
}
2230
2231
/* Parse a .gnu_attribute directive.  */
2232
2233
static void
2234
obj_elf_gnu_attribute (int ignored ATTRIBUTE_UNUSED)
2235
0
{
2236
0
  obj_elf_vendor_attribute (OBJ_ATTR_GNU);
2237
0
}
2238
2239
void
2240
elf_obj_read_begin_hook (void)
2241
28
{
2242
#ifdef NEED_ECOFF_DEBUG
2243
  if (ECOFF_DEBUGGING)
2244
    ecoff_read_begin_hook ();
2245
#endif
2246
28
}
2247
2248
void
2249
elf_obj_symbol_new_hook (symbolS *symbolP)
2250
52.4k
{
2251
52.4k
  struct elf_obj_sy *sy_obj;
2252
2253
52.4k
  sy_obj = symbol_get_obj (symbolP);
2254
52.4k
  sy_obj->size = NULL;
2255
52.4k
  sy_obj->versioned_name = NULL;
2256
2257
#ifdef NEED_ECOFF_DEBUG
2258
  if (ECOFF_DEBUGGING)
2259
    ecoff_symbol_new_hook (symbolP);
2260
#endif
2261
52.4k
}
2262
2263
/* If size is unset, copy size from src.  Because we don't track whether
2264
   .size has been used, we can't differentiate .size dest, 0 from the case
2265
   where dest's size is unset.  */
2266
void
2267
elf_copy_symbol_size (symbolS *dest, symbolS *src)
2268
2.59k
{
2269
2.59k
  struct elf_obj_sy *srcelf = symbol_get_obj (src);
2270
2.59k
  struct elf_obj_sy *destelf = symbol_get_obj (dest);
2271
2.59k
  if (!destelf->size && S_GET_SIZE (dest) == 0)
2272
2.58k
    {
2273
2.58k
      destelf->size = srcelf->size;
2274
2.58k
      S_SET_SIZE (dest, S_GET_SIZE (src));
2275
2.58k
    }
2276
2.59k
}
2277
2278
void
2279
elf_copy_symbol_attributes (symbolS *dest, symbolS *src)
2280
2.59k
{
2281
2.59k
  elf_copy_symbol_size (dest, src);
2282
  /* Don't copy visibility.  */
2283
2.59k
  S_SET_OTHER (dest, (ELF_ST_VISIBILITY (S_GET_OTHER (dest))
2284
2.59k
          | (S_GET_OTHER (src) & ~ELF_ST_VISIBILITY (-1))));
2285
2.59k
}
2286
2287
void
2288
obj_elf_version (int ignore ATTRIBUTE_UNUSED)
2289
0
{
2290
0
  char *name;
2291
0
  unsigned int c;
2292
0
  char *p;
2293
0
  asection *seg = now_seg;
2294
0
  subsegT subseg = now_subseg;
2295
0
  Elf_Internal_Note i_note;
2296
0
  Elf_External_Note e_note;
2297
0
  asection *note_secp = NULL;
2298
2299
0
  SKIP_WHITESPACE ();
2300
0
  if (*input_line_pointer == '\"')
2301
0
    {
2302
0
      unsigned int len;
2303
2304
0
      ++input_line_pointer; /* -> 1st char of string.  */
2305
0
      name = input_line_pointer;
2306
2307
0
      while (is_a_char (c = next_char_of_string ()))
2308
0
  ;
2309
0
      c = *input_line_pointer;
2310
0
      *input_line_pointer = '\0';
2311
0
      *(input_line_pointer - 1) = '\0';
2312
0
      *input_line_pointer = c;
2313
2314
      /* Create the .note section.  */
2315
0
      note_secp = subseg_new (".note", 0);
2316
0
      bfd_set_section_flags (note_secp, SEC_HAS_CONTENTS | SEC_READONLY);
2317
0
      record_alignment (note_secp, 2);
2318
2319
      /* Process the version string.  */
2320
0
      len = strlen (name) + 1;
2321
2322
      /* PR 3456: Although the name field is padded out to an 4-byte
2323
   boundary, the namesz field should not be adjusted.  */
2324
0
      i_note.namesz = len;
2325
0
      i_note.descsz = 0;  /* No description.  */
2326
0
      i_note.type = NT_VERSION;
2327
0
      p = frag_more (sizeof (e_note.namesz));
2328
0
      md_number_to_chars (p, i_note.namesz, sizeof (e_note.namesz));
2329
0
      p = frag_more (sizeof (e_note.descsz));
2330
0
      md_number_to_chars (p, i_note.descsz, sizeof (e_note.descsz));
2331
0
      p = frag_more (sizeof (e_note.type));
2332
0
      md_number_to_chars (p, i_note.type, sizeof (e_note.type));
2333
0
      p = frag_more (len);
2334
0
      memcpy (p, name, len);
2335
2336
0
      frag_align (2, 0, 0);
2337
2338
0
      subseg_set (seg, subseg);
2339
0
    }
2340
0
  else
2341
0
    as_bad (_("expected quoted string"));
2342
2343
0
  demand_empty_rest_of_line ();
2344
0
}
2345
2346
static void
2347
obj_elf_size (int ignore ATTRIBUTE_UNUSED)
2348
23
{
2349
23
  char *name;
2350
23
  char c = get_symbol_name (&name);
2351
23
  char *p;
2352
23
  expressionS exp;
2353
23
  symbolS *sym;
2354
2355
23
  p = input_line_pointer;
2356
23
  restore_line_pointer (c);
2357
23
  SKIP_WHITESPACE ();
2358
23
  if (*input_line_pointer != ',')
2359
19
    {
2360
19
      *p = 0;
2361
19
      as_bad (_("expected comma after name `%s' in .size directive"), name);
2362
19
      *p = c;
2363
19
      ignore_rest_of_line ();
2364
19
      return;
2365
19
    }
2366
4
  input_line_pointer++;
2367
4
  expression (&exp);
2368
4
  if (exp.X_op == O_absent)
2369
2
    {
2370
2
      as_bad (_("missing expression in .size directive"));
2371
2
      exp.X_op = O_constant;
2372
2
      exp.X_add_number = 0;
2373
2
    }
2374
4
  *p = 0;
2375
4
  sym = symbol_find_or_make (name);
2376
4
  *p = c;
2377
4
  if (exp.X_op == O_constant)
2378
3
    {
2379
3
      S_SET_SIZE (sym, exp.X_add_number);
2380
3
      symbol_get_obj (sym)->size = NULL;
2381
3
    }
2382
1
  else
2383
1
    {
2384
1
      symbol_get_obj (sym)->size = notes_alloc (sizeof (exp));
2385
1
      *symbol_get_obj (sym)->size = exp;
2386
1
    }
2387
2388
  /* If the symbol in the directive matches the current function being
2389
     processed, indicate end of the current stream of ginsns.  */
2390
4
  if (flag_synth_cfi
2391
4
      && S_IS_FUNCTION (sym) && sym == ginsn_data_func_symbol ())
2392
0
    ginsn_data_end (symbol_temp_new_now ());
2393
2394
4
  demand_empty_rest_of_line ();
2395
4
}
2396
2397
/* Handle the ELF .type pseudo-op.  This sets the type of a symbol.
2398
   There are six syntaxes:
2399
2400
   The first (used on Solaris) is
2401
       .type SYM,#function
2402
   The second (used on UnixWare) is
2403
       .type SYM,@function
2404
   The third (reportedly to be used on Irix 6.0) is
2405
       .type SYM STT_FUNC
2406
   The fourth (used on NetBSD/Arm and Linux/ARM) is
2407
       .type SYM,%function
2408
   The fifth (used on SVR4/860) is
2409
       .type SYM,"function"
2410
   The sixth (emitted by recent SunPRO under Solaris) is
2411
       .type SYM,[0-9]
2412
   where the integer is the STT_* value.
2413
   */
2414
2415
static char *
2416
obj_elf_type_name (char *cp)
2417
3.32k
{
2418
3.32k
  char *p;
2419
2420
3.32k
  p = input_line_pointer;
2421
3.32k
  if (*input_line_pointer >= '0'
2422
3.32k
      && *input_line_pointer <= '9')
2423
27
    {
2424
93
      while (*input_line_pointer >= '0'
2425
93
       && *input_line_pointer <= '9')
2426
66
  ++input_line_pointer;
2427
27
      *cp = *input_line_pointer;
2428
27
      *input_line_pointer = '\0';
2429
27
    }
2430
3.29k
  else
2431
3.29k
    *cp = get_symbol_name (&p);
2432
2433
3.32k
  return p;
2434
3.32k
}
2435
2436
static void
2437
obj_elf_type (int ignore ATTRIBUTE_UNUSED)
2438
3.32k
{
2439
3.32k
  char c;
2440
3.32k
  int type;
2441
3.32k
  const char *type_name;
2442
3.32k
  symbolS *sym;
2443
3.32k
  elf_symbol_type *elfsym;
2444
2445
3.32k
  sym = get_sym_from_input_line_and_check ();
2446
3.32k
  c = *input_line_pointer;
2447
3.32k
  elfsym = (elf_symbol_type *) symbol_get_bfdsym (sym);
2448
2449
3.32k
  if (*input_line_pointer == ',')
2450
2
    ++input_line_pointer;
2451
2452
3.32k
  SKIP_WHITESPACE ();
2453
3.32k
  if (   *input_line_pointer == '#'
2454
3.32k
      || *input_line_pointer == '@'
2455
3.32k
      || *input_line_pointer == '"'
2456
3.32k
      || *input_line_pointer == '%')
2457
3.25k
    ++input_line_pointer;
2458
2459
3.32k
  type_name = obj_elf_type_name (& c);
2460
2461
3.32k
  type = 0;
2462
3.32k
  if (strcmp (type_name, "function") == 0
2463
3.32k
      || strcmp (type_name, "2") == 0
2464
3.32k
      || strcmp (type_name, "STT_FUNC") == 0)
2465
7
    type = BSF_FUNCTION;
2466
3.31k
  else if (strcmp (type_name, "object") == 0
2467
3.31k
     || strcmp (type_name, "1") == 0
2468
3.31k
     || strcmp (type_name, "STT_OBJECT") == 0)
2469
0
    type = BSF_OBJECT;
2470
3.31k
  else if (strcmp (type_name, "tls_object") == 0
2471
3.31k
     || strcmp (type_name, "6") == 0
2472
3.31k
     || strcmp (type_name, "STT_TLS") == 0)
2473
0
    type = BSF_OBJECT | BSF_THREAD_LOCAL;
2474
3.31k
  else if (strcmp (type_name, "notype") == 0
2475
3.31k
     || strcmp (type_name, "0") == 0
2476
3.31k
     || strcmp (type_name, "STT_NOTYPE") == 0)
2477
0
    ;
2478
3.31k
  else if (strcmp (type_name, "common") == 0
2479
3.31k
     || strcmp (type_name, "5") == 0
2480
3.31k
     || strcmp (type_name, "STT_COMMON") == 0)
2481
1.71k
    {
2482
1.71k
      type = BSF_OBJECT;
2483
2484
1.71k
      if (! S_IS_COMMON (sym))
2485
8
  {
2486
8
    if (S_IS_VOLATILE (sym))
2487
0
      {
2488
0
        sym = symbol_clone (sym, 1);
2489
0
        S_SET_SEGMENT (sym, bfd_com_section_ptr);
2490
0
        S_SET_VALUE (sym, 0);
2491
0
        S_SET_EXTERNAL (sym);
2492
0
        symbol_set_frag (sym, &zero_address_frag);
2493
0
        S_CLEAR_VOLATILE (sym);
2494
0
      }
2495
8
    else if (S_IS_DEFINED (sym) || symbol_equated_p (sym))
2496
0
      as_bad (_("symbol '%s' is already defined"), S_GET_NAME (sym));
2497
8
    else
2498
8
      {
2499
        /* FIXME: Is it safe to just change the section ?  */
2500
8
        S_SET_SEGMENT (sym, bfd_com_section_ptr);
2501
8
        S_SET_VALUE (sym, 0);
2502
8
        S_SET_EXTERNAL (sym);
2503
8
      }
2504
8
  }
2505
1.71k
    }
2506
1.60k
  else if (strcmp (type_name, "gnu_indirect_function") == 0
2507
1.60k
     || strcmp (type_name, "10") == 0
2508
1.60k
     || strcmp (type_name, "STT_GNU_IFUNC") == 0)
2509
4
    {
2510
4
      const struct elf_backend_data *bed;
2511
2512
4
      bed = get_elf_backend_data (stdoutput);
2513
4
      if (bed->elf_osabi != ELFOSABI_NONE
2514
4
    && bed->elf_osabi != ELFOSABI_GNU
2515
4
    && bed->elf_osabi != ELFOSABI_FREEBSD)
2516
0
  as_bad (_("symbol type \"%s\" is supported only by GNU "
2517
0
      "and FreeBSD targets"), type_name);
2518
      /* MIPS targets do not support IFUNCS.  */
2519
4
      else if (bed->target_id == MIPS_ELF_DATA)
2520
0
  as_bad (_("symbol type \"%s\" is not supported by "
2521
0
                    "MIPS targets"), type_name);
2522
4
      elf_tdata (stdoutput)->has_gnu_osabi |= elf_gnu_osabi_ifunc;
2523
4
      type = BSF_FUNCTION | BSF_GNU_INDIRECT_FUNCTION;
2524
4
    }
2525
1.59k
  else if (strcmp (type_name, "gnu_unique_object") == 0)
2526
0
    {
2527
0
      const struct elf_backend_data *bed;
2528
2529
0
      bed = get_elf_backend_data (stdoutput);
2530
0
      if (bed->elf_osabi != ELFOSABI_NONE
2531
0
    && bed->elf_osabi != ELFOSABI_GNU)
2532
0
  as_bad (_("symbol type \"%s\" is supported only by GNU targets"),
2533
0
    type_name);
2534
0
      elf_tdata (stdoutput)->has_gnu_osabi |= elf_gnu_osabi_unique;
2535
0
      type = BSF_OBJECT | BSF_GNU_UNIQUE;
2536
0
    }
2537
#ifdef md_elf_symbol_type
2538
  else if ((type = md_elf_symbol_type (type_name, sym, elfsym)) != -1)
2539
    ;
2540
#endif
2541
1.59k
  else
2542
1.59k
    as_bad (_("unrecognized symbol type \"%s\""), type_name);
2543
2544
3.32k
  *input_line_pointer = c;
2545
2546
3.32k
  if (*input_line_pointer == '"')
2547
799
    ++input_line_pointer;
2548
2549
#ifdef md_elf_symbol_type_change
2550
  if (!md_elf_symbol_type_change (sym, elfsym, type))
2551
#endif
2552
3.32k
    {
2553
3.32k
      flagword mask = BSF_FUNCTION | BSF_OBJECT;
2554
2555
3.32k
      if (type != BSF_FUNCTION)
2556
3.31k
  mask |= BSF_GNU_INDIRECT_FUNCTION;
2557
3.32k
      if (type != BSF_OBJECT)
2558
1.60k
  {
2559
1.60k
    mask |= BSF_GNU_UNIQUE | BSF_THREAD_LOCAL;
2560
2561
1.60k
    if (S_IS_COMMON (sym))
2562
1.54k
      {
2563
1.54k
        as_bad (_("cannot change type of common symbol '%s'"),
2564
1.54k
          S_GET_NAME (sym));
2565
1.54k
        mask = type = 0;
2566
1.54k
      }
2567
1.60k
  }
2568
2569
      /* Don't warn when changing to STT_NOTYPE.  */
2570
3.32k
      if (type)
2571
1.72k
  {
2572
1.72k
    flagword new = (elfsym->symbol.flags & ~mask) | type;
2573
2574
1.72k
    if (new != (elfsym->symbol.flags | type))
2575
0
      as_warn (_("symbol '%s' already has its type set"), S_GET_NAME (sym));
2576
1.72k
    elfsym->symbol.flags = new;
2577
1.72k
  }
2578
1.59k
      else
2579
1.59k
  elfsym->symbol.flags &= ~mask;
2580
3.32k
    }
2581
2582
3.32k
  if (S_IS_FUNCTION (sym) && flag_synth_cfi)
2583
0
    {
2584
      /* When using SCFI, .type directive indicates start of a new FDE for SCFI
2585
   processing.  So, we must first demarcate the previous block of ginsns,
2586
   if any, to mark the end of a previous FDE.  */
2587
0
      if (frchain_now->frch_ginsn_data)
2588
0
  ginsn_data_end (symbol_temp_new_now ());
2589
0
      ginsn_data_begin (sym);
2590
0
    }
2591
2592
3.32k
  demand_empty_rest_of_line ();
2593
3.32k
}
2594
2595
static segT comment_section;
2596
2597
static void
2598
obj_elf_ident (int ignore ATTRIBUTE_UNUSED)
2599
0
{
2600
0
  segT old_section = now_seg;
2601
0
  int old_subsection = now_subseg;
2602
2603
#ifdef md_flush_pending_output
2604
  md_flush_pending_output ();
2605
#endif
2606
2607
0
  if (!comment_section)
2608
0
    {
2609
0
      char *p;
2610
0
      comment_section = subseg_new (".comment", 0);
2611
0
      bfd_set_section_flags (comment_section, (SEC_READONLY | SEC_HAS_CONTENTS
2612
0
                 | SEC_MERGE | SEC_STRINGS));
2613
0
      comment_section->entsize = 1;
2614
0
#ifdef md_elf_section_change_hook
2615
0
      md_elf_section_change_hook ();
2616
0
#endif
2617
0
      p = frag_more (1);
2618
0
      *p = 0;
2619
0
    }
2620
0
  else
2621
0
    {
2622
0
      subseg_set (comment_section, 0);
2623
0
#ifdef md_elf_section_change_hook
2624
0
      md_elf_section_change_hook ();
2625
0
#endif
2626
0
    }
2627
0
  stringer (8 + 1);
2628
0
  subseg_set (old_section, old_subsection);
2629
0
#ifdef md_elf_section_change_hook
2630
0
  md_elf_section_change_hook ();
2631
0
#endif
2632
0
}
2633
2634
#ifdef INIT_STAB_SECTION
2635
2636
/* The first entry in a .stabs section is special.  */
2637
2638
void
2639
obj_elf_init_stab_section (segT stab, segT stabstr)
2640
12
{
2641
12
  char *file;
2642
12
  char *p;
2643
12
  unsigned int stroff;
2644
2645
  /* Force the section to align to a longword boundary.  Without this,
2646
     UnixWare ar crashes.  */
2647
12
  bfd_set_section_alignment (stab, 2);
2648
2649
  /* Make space for this first symbol.  */
2650
12
  p = frag_more (12);
2651
  /* Zero it out.  */
2652
12
  memset (p, 0, 12);
2653
12
  file = remap_debug_filename (as_where (NULL));
2654
12
  stroff = get_stab_string_offset (file, stabstr);
2655
12
  know (stroff == 1 || (stroff == 0 && file[0] == '\0'));
2656
12
  md_number_to_chars (p, stroff, 4);
2657
12
  seg_info (stab)->stabu.p = p;
2658
12
  free (file);
2659
12
}
2660
2661
#endif
2662
2663
/* Called via bfd_map_over_sections.  If SEC's linked_to_symbol_name
2664
   isn't NULL, set up its linked-to section.
2665
   For .stabs section, fill in the counts in the first entry.  */
2666
2667
static void
2668
set_additional_section_info (bfd *abfd,
2669
           asection *sec,
2670
           void *inf ATTRIBUTE_UNUSED)
2671
0
{
2672
0
  if (sec->map_head.linked_to_symbol_name)
2673
0
    {
2674
0
      symbolS *linked_to_sym;
2675
0
      linked_to_sym = symbol_find (sec->map_head.linked_to_symbol_name);
2676
0
      if (!linked_to_sym || !S_IS_DEFINED (linked_to_sym))
2677
0
  as_bad (_("undefined linked-to symbol `%s' on section `%s'"),
2678
0
    sec->map_head.linked_to_symbol_name,
2679
0
    bfd_section_name (sec));
2680
0
      else
2681
0
  elf_linked_to_section (sec) = S_GET_SEGMENT (linked_to_sym);
2682
0
    }
2683
2684
0
  char *name;
2685
0
  asection *strsec;
2686
0
  char *p;
2687
0
  int strsz, nsyms;
2688
2689
0
  if (!startswith (sec->name, ".stab"))
2690
0
    return;
2691
0
  if (!strcmp ("str", sec->name + strlen (sec->name) - 3))
2692
0
    return;
2693
2694
0
  name = concat (sec->name, "str", NULL);
2695
0
  strsec = bfd_get_section_by_name (abfd, name);
2696
0
  if (strsec)
2697
0
    strsz = bfd_section_size (strsec);
2698
0
  else
2699
0
    strsz = 0;
2700
0
  nsyms = bfd_section_size (sec) / 12 - 1;
2701
2702
0
  p = seg_info (sec)->stabu.p;
2703
0
  gas_assert (p != 0);
2704
2705
0
  bfd_h_put_16 (abfd, nsyms, p + 6);
2706
0
  bfd_h_put_32 (abfd, strsz, p + 8);
2707
0
  free (name);
2708
0
}
2709
2710
#ifdef NEED_ECOFF_DEBUG
2711
2712
/* This function is called by the ECOFF code.  It is supposed to
2713
   record the external symbol information so that the backend can
2714
   write it out correctly.  The ELF backend doesn't actually handle
2715
   this at the moment, so we do it ourselves.  We save the information
2716
   in the symbol.  */
2717
2718
#ifdef OBJ_MAYBE_ELF
2719
static
2720
#endif
2721
void
2722
elf_ecoff_set_ext (symbolS *sym, struct ecoff_extr *ext)
2723
{
2724
  symbol_get_bfdsym (sym)->udata.p = ext;
2725
}
2726
2727
/* This function is called by bfd_ecoff_debug_externals.  It is
2728
   supposed to *EXT to the external symbol information, and return
2729
   whether the symbol should be used at all.  */
2730
2731
static bool
2732
elf_get_extr (asymbol *sym, EXTR *ext)
2733
{
2734
  if (sym->udata.p == NULL)
2735
    return false;
2736
  *ext = *(EXTR *) sym->udata.p;
2737
  return true;
2738
}
2739
2740
/* This function is called by bfd_ecoff_debug_externals.  It has
2741
   nothing to do for ELF.  */
2742
2743
static void
2744
elf_set_index (asymbol *sym ATTRIBUTE_UNUSED,
2745
         bfd_size_type indx ATTRIBUTE_UNUSED)
2746
{
2747
}
2748
2749
#endif /* NEED_ECOFF_DEBUG */
2750
2751
void
2752
elf_frob_symbol (symbolS *symp, int *puntp)
2753
0
{
2754
0
  struct elf_obj_sy *sy_obj;
2755
0
  expressionS *size;
2756
0
  struct elf_versioned_name_list *versioned_name;
2757
2758
#ifdef NEED_ECOFF_DEBUG
2759
  if (ECOFF_DEBUGGING)
2760
    ecoff_frob_symbol (symp);
2761
#endif
2762
2763
0
  sy_obj = symbol_get_obj (symp);
2764
2765
0
  size = sy_obj->size;
2766
0
  if (size != NULL)
2767
0
    {
2768
0
      if (resolve_expression (size)
2769
0
    && size->X_op == O_constant)
2770
0
  S_SET_SIZE (symp, size->X_add_number);
2771
0
      else
2772
0
  {
2773
0
    if (!flag_allow_nonconst_size)
2774
0
      as_bad (_(".size expression for %s "
2775
0
          "does not evaluate to a constant"), S_GET_NAME (symp));
2776
0
    else
2777
0
      as_warn (_(".size expression for %s "
2778
0
           "does not evaluate to a constant"), S_GET_NAME (symp));
2779
0
  }
2780
0
      sy_obj->size = NULL;
2781
0
    }
2782
2783
0
  versioned_name = sy_obj->versioned_name;
2784
0
  if (versioned_name)
2785
0
    {
2786
      /* This symbol was given a new name with the .symver directive.
2787
   If this is an external reference, just rename the symbol to
2788
   include the version string.  This will make the relocs be
2789
   against the correct versioned symbol.  */
2790
2791
      /* We will have already reported an version error.  */
2792
0
      if (sy_obj->bad_version)
2793
0
  *puntp = true;
2794
      /* elf_frob_file_before_adjust only allows one version symbol for
2795
   renamed symbol.  */
2796
0
      else if (sy_obj->rename)
2797
0
  S_SET_NAME (symp, versioned_name->name);
2798
0
      else if (S_IS_COMMON (symp))
2799
0
  {
2800
0
    as_bad (_("`%s' can't be versioned to common symbol '%s'"),
2801
0
      versioned_name->name, S_GET_NAME (symp));
2802
0
    *puntp = true;
2803
0
  }
2804
0
      else
2805
0
  {
2806
0
    asymbol *bfdsym;
2807
0
    elf_symbol_type *elfsym;
2808
2809
    /* This is a definition.  Add an alias for each version.
2810
       FIXME: Using an alias will permit the debugging information
2811
       to refer to the right symbol.  However, it's not clear
2812
       whether it is the best approach.  */
2813
2814
    /* FIXME: Creating a new symbol here is risky.  We're
2815
       in the final loop over the symbol table.  We can
2816
       get away with it only because the symbol goes to
2817
       the end of the list, where the loop will still see
2818
       it.  It would probably be better to do this in
2819
       obj_frob_file_before_adjust.  */
2820
0
    for (; versioned_name != NULL;
2821
0
         versioned_name = versioned_name->next)
2822
0
      {
2823
0
        symbolS *symp2 = symbol_find_or_make (versioned_name->name);
2824
2825
0
        S_SET_SEGMENT (symp2, S_GET_SEGMENT (symp));
2826
2827
        /* Subtracting out the frag address here is a hack
2828
     because we are in the middle of the final loop.  */
2829
0
        S_SET_VALUE (symp2,
2830
0
         (S_GET_VALUE (symp)
2831
0
          - (symbol_get_frag (symp)->fr_address
2832
0
             / OCTETS_PER_BYTE)));
2833
2834
0
        symbol_set_frag (symp2, symbol_get_frag (symp));
2835
2836
        /* This will copy over the size information.  */
2837
0
        copy_symbol_attributes (symp2, symp);
2838
2839
0
        S_SET_OTHER (symp2, S_GET_OTHER (symp));
2840
2841
0
        if (S_IS_WEAK (symp))
2842
0
    S_SET_WEAK (symp2);
2843
2844
0
        if (S_IS_EXTERNAL (symp))
2845
0
    S_SET_EXTERNAL (symp2);
2846
0
      }
2847
2848
0
    switch (sy_obj->visibility)
2849
0
      {
2850
0
      case visibility_unchanged:
2851
0
        break;
2852
0
      case visibility_hidden:
2853
0
        bfdsym = symbol_get_bfdsym (symp);
2854
0
        elfsym = elf_symbol_from (bfdsym);
2855
0
        elfsym->internal_elf_sym.st_other &= ~3;
2856
0
        elfsym->internal_elf_sym.st_other |= STV_HIDDEN;
2857
0
        break;
2858
0
      case visibility_remove:
2859
        /* Don't remove the symbol if it is used in relocation.
2860
     Instead, mark it as to be removed and issue an error
2861
     if the symbol has more than one versioned name.  */
2862
0
        if (symbol_used_in_reloc_p (symp))
2863
0
    {
2864
0
      if (sy_obj->versioned_name->next != NULL)
2865
0
        as_bad (_("symbol '%s' with multiple versions cannot be used in relocation"),
2866
0
          S_GET_NAME (symp));
2867
0
      symbol_mark_removed (symp);
2868
0
    }
2869
0
        else
2870
0
    symbol_remove (symp, &symbol_rootP, &symbol_lastP);
2871
0
        break;
2872
0
      case visibility_local:
2873
0
        S_CLEAR_EXTERNAL (symp);
2874
0
        break;
2875
0
      }
2876
0
  }
2877
0
    }
2878
2879
  /* Double check weak symbols.  */
2880
0
  if (S_IS_WEAK (symp))
2881
0
    {
2882
0
      if (S_IS_COMMON (symp))
2883
0
  as_bad (_("symbol `%s' can not be both weak and common"),
2884
0
    S_GET_NAME (symp));
2885
0
    }
2886
0
}
2887
2888
/* Fix up SYMPP which has been marked to be removed by .symver.  */
2889
2890
void
2891
elf_fixup_removed_symbol (symbolS **sympp)
2892
0
{
2893
0
  symbolS *symp = *sympp;
2894
0
  struct elf_obj_sy *sy_obj = symbol_get_obj (symp);
2895
2896
  /* Replace the removed symbol with the versioned symbol.  */
2897
0
  symp = symbol_find (sy_obj->versioned_name->name);
2898
0
  *sympp = symp;
2899
0
}
2900
2901
/* Create symbols for group signature.  */
2902
2903
void
2904
elf_adjust_symtab (void)
2905
0
{
2906
0
  unsigned int i;
2907
2908
  /* Make the SHT_GROUP sections that describe each section group.  We
2909
     can't set up the section contents here yet, because elf section
2910
     indices have yet to be calculated.  elf.c:set_group_contents does
2911
     the rest of the work.  */
2912
0
 for (i = 0; i < groups.num_group; i++)
2913
0
    {
2914
0
      const char *group_name = elf_group_name (groups.head[i]);
2915
0
      const char *sec_name;
2916
0
      asection *s;
2917
0
      flagword flags;
2918
0
      struct symbol *sy;
2919
2920
0
      flags = SEC_READONLY | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_GROUP;
2921
0
      for (s = groups.head[i]; s != NULL; s = elf_next_in_group (s))
2922
0
  if ((s->flags ^ flags) & SEC_LINK_ONCE)
2923
0
    {
2924
0
      flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
2925
0
      if (s != groups.head[i])
2926
0
        {
2927
0
    as_warn (_("assuming all members of group `%s' are COMDAT"),
2928
0
       group_name);
2929
0
    break;
2930
0
        }
2931
0
    }
2932
2933
0
      sec_name = ".group";
2934
0
      s = subseg_force_new (sec_name, 0);
2935
0
      if (s == NULL
2936
0
    || !bfd_set_section_flags (s, flags)
2937
0
    || !bfd_set_section_alignment (s, 2))
2938
0
  {
2939
0
    as_fatal (_("can't create group: %s"),
2940
0
        bfd_errmsg (bfd_get_error ()));
2941
0
  }
2942
0
      elf_section_type (s) = SHT_GROUP;
2943
2944
      /* Pass a pointer to the first section in this group.  */
2945
0
      elf_next_in_group (s) = groups.head[i];
2946
0
      elf_sec_group (groups.head[i]) = s;
2947
      /* Make sure that the signature symbol for the group has the
2948
   name of the group.  */
2949
0
      sy = symbol_find_exact (group_name);
2950
0
      if (!sy || !symbol_on_chain (sy, symbol_rootP, symbol_lastP))
2951
0
  {
2952
    /* Create the symbol now.  */
2953
0
    sy = symbol_new (group_name, now_seg, frag_now, 0);
2954
#ifdef TE_SOLARIS
2955
    /* Before Solaris 11 build 154, Sun ld rejects local group
2956
       signature symbols, so make them weak hidden instead.  */
2957
    symbol_get_bfdsym (sy)->flags |= BSF_WEAK;
2958
    S_SET_OTHER (sy, STV_HIDDEN);
2959
#else
2960
0
    symbol_get_obj (sy)->local = 1;
2961
0
#endif
2962
0
    symbol_table_insert (sy);
2963
0
  }
2964
0
      elf_group_id (s) = symbol_get_bfdsym (sy);
2965
      /* Mark the group signature symbol as used so that it will be
2966
   included in the symbol table.  */
2967
0
      symbol_mark_used_in_reloc (sy);
2968
0
    }
2969
0
}
2970
2971
void
2972
elf_frob_file (void)
2973
0
{
2974
0
  bfd_map_over_sections (stdoutput, set_additional_section_info, NULL);
2975
2976
#ifdef elf_tc_final_processing
2977
  elf_tc_final_processing ();
2978
#endif
2979
0
}
2980
2981
/* It removes any unneeded versioned symbols from the symbol table.  */
2982
2983
void
2984
elf_frob_file_before_adjust (void)
2985
0
{
2986
0
  if (symbol_rootP)
2987
0
    {
2988
0
      symbolS *symp;
2989
2990
0
      for (symp = symbol_rootP; symp; symp = symbol_next (symp))
2991
0
  {
2992
0
    struct elf_obj_sy *sy_obj = symbol_get_obj (symp);
2993
0
    int is_defined = !!S_IS_DEFINED (symp);
2994
2995
0
    if (sy_obj->versioned_name)
2996
0
      {
2997
0
        char *p = strchr (sy_obj->versioned_name->name,
2998
0
        ELF_VER_CHR);
2999
3000
0
        if (sy_obj->rename)
3001
0
    {
3002
      /* The @@@ syntax is a special case. If the symbol is
3003
         not defined, 2 `@'s will be removed from the
3004
         versioned_name. Otherwise, 1 `@' will be removed.   */
3005
0
      size_t l = strlen (&p[3]) + 1;
3006
0
      memmove (&p[1 + is_defined], &p[3], l);
3007
0
    }
3008
3009
0
        if (!is_defined)
3010
0
    {
3011
      /* Verify that the name isn't using the @@ syntax--this
3012
         is reserved for definitions of the default version
3013
         to link against.  */
3014
0
      if (!sy_obj->rename && p[1] == ELF_VER_CHR)
3015
0
        {
3016
0
          as_bad (_("invalid attempt to declare external "
3017
0
        "version name as default in symbol `%s'"),
3018
0
            sy_obj->versioned_name->name);
3019
0
          return;
3020
0
        }
3021
3022
      /* Only one version symbol is allowed for undefined
3023
         symbol.  */
3024
0
      if (sy_obj->versioned_name->next)
3025
0
        {
3026
0
          as_bad (_("multiple versions [`%s'|`%s'] for "
3027
0
        "symbol `%s'"),
3028
0
            sy_obj->versioned_name->name,
3029
0
            sy_obj->versioned_name->next->name,
3030
0
            S_GET_NAME (symp));
3031
0
          return;
3032
0
        }
3033
3034
0
      sy_obj->rename = true;
3035
0
    }
3036
0
      }
3037
3038
    /* If there was .symver or .weak, but symbol was neither
3039
       defined nor used anywhere, remove it.  */
3040
0
    if (!is_defined
3041
0
        && (sy_obj->versioned_name || S_IS_WEAK (symp))
3042
0
        && symbol_used_p (symp) == 0
3043
0
        && symbol_used_in_reloc_p (symp) == 0)
3044
0
      symbol_remove (symp, &symbol_rootP, &symbol_lastP);
3045
0
  }
3046
0
    }
3047
0
}
3048
3049
/* It is required that we let write_relocs have the opportunity to
3050
   optimize away fixups before output has begun, since it is possible
3051
   to eliminate all fixups for a section and thus we never should
3052
   have generated the relocation section.  */
3053
3054
void
3055
elf_frob_file_after_relocs (void)
3056
0
{
3057
0
  unsigned int i;
3058
3059
  /* Set SHT_GROUP section size.  */
3060
0
  for (i = 0; i < groups.num_group; i++)
3061
0
    {
3062
0
      asection *s, *head, *group;
3063
0
      bfd_size_type size;
3064
3065
0
      head = groups.head[i];
3066
0
      size = 4;
3067
0
      for (s = head; s != NULL; s = elf_next_in_group (s))
3068
0
  size += (s->flags & SEC_RELOC) != 0 ? 8 : 4;
3069
3070
0
      group = elf_sec_group (head);
3071
0
      subseg_set (group, 0);
3072
0
      bfd_set_section_size (group, size);
3073
0
      group->contents = (unsigned char *) frag_more (size);
3074
0
      group->alloced = 1;
3075
0
      frag_now->fr_fix = frag_now_fix_octets ();
3076
0
      frag_wane (frag_now);
3077
0
    }
3078
3079
#ifdef NEED_ECOFF_DEBUG
3080
  if (ECOFF_DEBUGGING)
3081
    /* Generate the ECOFF debugging information.  */
3082
    {
3083
      const struct ecoff_debug_swap *debug_swap;
3084
      struct ecoff_debug_info debug;
3085
      char *buf;
3086
      asection *sec;
3087
3088
      debug_swap
3089
  = get_elf_backend_data (stdoutput)->elf_backend_ecoff_debug_swap;
3090
      know (debug_swap != NULL);
3091
      ecoff_build_debug (&debug.symbolic_header, &buf, debug_swap);
3092
3093
      /* Set up the pointers in debug.  */
3094
      debug.alloc_syments = true;
3095
#define SET(ptr, offset, type) \
3096
    debug.ptr = (type) (buf + debug.symbolic_header.offset)
3097
3098
      SET (line, cbLineOffset, unsigned char *);
3099
      SET (external_dnr, cbDnOffset, void *);
3100
      SET (external_pdr, cbPdOffset, void *);
3101
      SET (external_sym, cbSymOffset, void *);
3102
      SET (external_opt, cbOptOffset, void *);
3103
      SET (external_aux, cbAuxOffset, union aux_ext *);
3104
      SET (ss, cbSsOffset, char *);
3105
      SET (external_fdr, cbFdOffset, void *);
3106
      SET (external_rfd, cbRfdOffset, void *);
3107
      /* ssext and external_ext are set up just below.  */
3108
3109
#undef SET
3110
3111
      /* Set up the external symbols.  */
3112
      debug.ssext = debug.ssext_end = NULL;
3113
      debug.external_ext = debug.external_ext_end = NULL;
3114
      if (! bfd_ecoff_debug_externals (stdoutput, &debug, debug_swap, true,
3115
               elf_get_extr, elf_set_index))
3116
  as_fatal (_("failed to set up debugging information: %s"),
3117
      bfd_errmsg (bfd_get_error ()));
3118
3119
      sec = bfd_get_section_by_name (stdoutput, ".mdebug");
3120
      gas_assert (sec != NULL);
3121
3122
      know (!stdoutput->output_has_begun);
3123
3124
      /* We set the size of the section, call bfd_set_section_contents
3125
   to force the ELF backend to allocate a file position, and then
3126
   write out the data.  FIXME: Is this really the best way to do
3127
   this?  */
3128
      bfd_set_section_size (sec, bfd_ecoff_debug_size (stdoutput, &debug,
3129
                   debug_swap));
3130
3131
      /* Pass BUF to bfd_set_section_contents because this will
3132
   eventually become a call to fwrite, and ISO C prohibits
3133
   passing a NULL pointer to a stdio function even if the
3134
   pointer will not be used.  */
3135
      if (! bfd_set_section_contents (stdoutput, sec, buf, 0, 0))
3136
  as_fatal (_("can't start writing .mdebug section: %s"),
3137
      bfd_errmsg (bfd_get_error ()));
3138
3139
      know (stdoutput->output_has_begun);
3140
      know (sec->filepos != 0);
3141
3142
      if (! bfd_ecoff_write_debug (stdoutput, &debug, debug_swap,
3143
           sec->filepos))
3144
  as_fatal (_("could not write .mdebug section: %s"),
3145
      bfd_errmsg (bfd_get_error ()));
3146
    }
3147
#endif /* NEED_ECOFF_DEBUG */
3148
0
}
3149
3150
/* This is called when the assembler starts.  */
3151
3152
void
3153
elf_begin (void)
3154
28
{
3155
28
  asection *s;
3156
3157
  /* Add symbols for the known sections to the symbol table.  */
3158
28
  s = bfd_get_section_by_name (stdoutput, TEXT_SECTION_NAME);
3159
28
  symbol_table_insert (section_symbol (s));
3160
28
  s = bfd_get_section_by_name (stdoutput, DATA_SECTION_NAME);
3161
28
  symbol_table_insert (section_symbol (s));
3162
28
  s = bfd_get_section_by_name (stdoutput, BSS_SECTION_NAME);
3163
28
  symbol_table_insert (section_symbol (s));
3164
28
  elf_com_section_ptr = bfd_com_section_ptr;
3165
28
  previous_section = NULL;
3166
28
  previous_subsection = 0;
3167
28
  comment_section = NULL;
3168
28
  memset (&groups, 0, sizeof (groups));
3169
28
}
3170
3171
void
3172
elf_end (void)
3173
28
{
3174
28
  while (section_stack)
3175
0
    {
3176
0
      struct section_stack *top = section_stack;
3177
0
      section_stack = top->next;
3178
0
      free (top);
3179
0
    }
3180
28
  while (recorded_attributes)
3181
0
    {
3182
0
      struct recorded_attribute_info *rai = recorded_attributes;
3183
0
      recorded_attributes = rai->next;
3184
0
      free (rai);
3185
0
    }
3186
28
  if (groups.indexes)
3187
2
    {
3188
2
      htab_delete (groups.indexes);
3189
2
      free (groups.head);
3190
2
    }
3191
28
}
3192
3193
#ifdef USE_EMULATIONS
3194
3195
static bfd_vma
3196
elf_s_get_size (symbolS *sym)
3197
{
3198
  return S_GET_SIZE (sym);
3199
}
3200
3201
static void
3202
elf_s_set_size (symbolS *sym, bfd_vma sz)
3203
{
3204
  S_SET_SIZE (sym, sz);
3205
}
3206
3207
static bfd_vma
3208
elf_s_get_align (symbolS *sym)
3209
{
3210
  return S_GET_ALIGN (sym);
3211
}
3212
3213
static void
3214
elf_s_set_align (symbolS *sym, bfd_vma align)
3215
{
3216
  S_SET_ALIGN (sym, align);
3217
}
3218
3219
int
3220
elf_s_get_other (symbolS *sym)
3221
{
3222
  return elf_symbol (symbol_get_bfdsym (sym))->internal_elf_sym.st_other;
3223
}
3224
3225
static void
3226
elf_s_set_other (symbolS *sym, int other)
3227
{
3228
  S_SET_OTHER (sym, other);
3229
}
3230
3231
static int
3232
elf_sec_sym_ok_for_reloc (asection *sec)
3233
{
3234
  return obj_sec_sym_ok_for_reloc (sec);
3235
}
3236
3237
#ifdef NEED_ECOFF_DEBUG
3238
static void
3239
elf_process_stab (int what ATTRIBUTE_UNUSED,
3240
      const char *string ATTRIBUTE_UNUSED,
3241
      int type ATTRIBUTE_UNUSED,
3242
      int other ATTRIBUTE_UNUSED,
3243
      int desc ATTRIBUTE_UNUSED)
3244
{
3245
  if (ECOFF_DEBUGGING)
3246
    ecoff_stab (what, string, type, other, desc);
3247
}
3248
#else
3249
# define elf_process_stab NULL
3250
#endif
3251
3252
static int
3253
elf_separate_stab_sections (void)
3254
{
3255
#ifdef NEED_ECOFF_DEBUG
3256
  return (!ECOFF_DEBUGGING);
3257
#else
3258
  return 1;
3259
#endif
3260
}
3261
3262
#ifdef NEED_ECOFF_DEBUG
3263
static void
3264
elf_init_stab_section (segT stab, segT stabstr)
3265
{
3266
  if (!ECOFF_DEBUGGING)
3267
    obj_elf_init_stab_section (stab, stabstr);
3268
}
3269
#endif
3270
3271
const struct format_ops elf_format_ops =
3272
{
3273
  bfd_target_elf_flavour,
3274
  0,  /* dfl_leading_underscore */
3275
  1,  /* emit_section_symbols */
3276
  elf_begin,
3277
  elf_end,
3278
  elf_file_symbol,
3279
  NULL, /* assign_symbol */
3280
  elf_frob_symbol,
3281
  elf_frob_file,
3282
  elf_frob_file_before_adjust,
3283
  0,  /* obj_frob_file_before_fix */
3284
  elf_frob_file_after_relocs,
3285
  elf_s_get_size, elf_s_set_size,
3286
  elf_s_get_align, elf_s_set_align,
3287
  elf_s_get_other,
3288
  elf_s_set_other,
3289
  0,  /* s_get_desc */
3290
  0,  /* s_set_desc */
3291
  0,  /* s_get_type */
3292
  0,  /* s_set_type */
3293
  elf_copy_symbol_attributes,
3294
  elf_process_stab,
3295
  elf_separate_stab_sections,
3296
#ifdef NEED_ECOFF_DEBUG
3297
  elf_init_stab_section,
3298
#else
3299
  obj_elf_init_stab_section,
3300
#endif
3301
  elf_sec_sym_ok_for_reloc,
3302
  elf_pop_insert,
3303
#ifdef NEED_ECOFF_DEBUG
3304
  elf_ecoff_set_ext,
3305
#else
3306
  0,  /* ecoff_set_ext */
3307
#endif
3308
  elf_obj_read_begin_hook,
3309
  elf_obj_symbol_new_hook,
3310
  0,
3311
  elf_adjust_symtab
3312
};
3313
3314
#endif /* USE_EMULATIONS */