Coverage Report

Created: 2026-03-10 08:46

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