Coverage Report

Created: 2026-04-04 08:16

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
567
#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
567
{
197
567
  pop_insert (elf_pseudo_table);
198
567
  if (ECOFF_DEBUGGING)
199
0
    pop_insert (ecoff_debug_pseudo_table);
200
567
}
201
202
void
203
elf_file_symbol (const char *s)
204
150
{
205
150
  asymbol *bsym;
206
150
  symbolS *sym = symbol_new (s, absolute_section, &zero_address_frag, 0);
207
150
  size_t name_length = strlen (s);
208
209
150
  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
150
  else
215
150
    strcpy ((char *) S_GET_NAME (sym), s);
216
217
150
  symbol_get_bfdsym (sym)->flags |= BSF_FILE;
218
219
150
  if (symbol_rootP != sym
220
150
      && ((bsym = symbol_get_bfdsym (symbol_rootP)) == NULL
221
150
    || (bsym->flags & BSF_FILE) == 0))
222
17
    {
223
17
      symbol_remove (sym, &symbol_rootP, &symbol_lastP);
224
17
      symbol_insert (sym, symbol_rootP, &symbol_rootP, &symbol_lastP);
225
17
    }
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
150
}
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
61
{
242
61
  addressT align = 0;
243
61
  int is_local = symbol_get_obj (symbolP)->local;
244
245
61
  if (*input_line_pointer == ',')
246
6
    {
247
6
      char *save = input_line_pointer;
248
249
6
      input_line_pointer++;
250
6
      SKIP_WHITESPACE ();
251
252
6
      if (*input_line_pointer == '"')
253
0
  {
254
    /* For sparc.  Accept .common symbol, length, "bss"  */
255
0
    input_line_pointer++;
256
    /* Some use the dot, some don't.  */
257
0
    if (*input_line_pointer == '.')
258
0
      input_line_pointer++;
259
    /* Some say data, some say bss.  */
260
0
    if (startswith (input_line_pointer, "bss\""))
261
0
      input_line_pointer += 4;
262
0
    else if (startswith (input_line_pointer, "data\""))
263
0
      input_line_pointer += 5;
264
0
    else
265
0
      {
266
0
        char *p = input_line_pointer;
267
0
        char c;
268
269
0
        while (*--p != '"')
270
0
    ;
271
0
        while (!is_end_of_stmt (*input_line_pointer))
272
0
    if (*input_line_pointer++ == '"')
273
0
      break;
274
0
        c = *input_line_pointer;
275
0
        *input_line_pointer = '\0';
276
0
        as_bad (_("bad .common segment %s"), p);
277
0
        *input_line_pointer = c;
278
0
        ignore_rest_of_line ();
279
0
        return NULL;
280
0
      }
281
    /* ??? Don't ask me why these are always global.  */
282
0
    is_local = 0;
283
0
  }
284
6
      else
285
6
  {
286
6
    input_line_pointer = save;
287
6
    align = parse_align (is_local);
288
6
    if (align == (addressT) -1)
289
1
      return NULL;
290
6
  }
291
6
    }
292
293
60
  if (is_local)
294
0
    {
295
0
      bss_alloc (symbolP, size, align);
296
0
      S_CLEAR_EXTERNAL (symbolP);
297
0
    }
298
60
  else
299
60
    {
300
60
      S_SET_VALUE (symbolP, size);
301
60
      S_SET_ALIGN (symbolP, align);
302
60
      S_SET_EXTERNAL (symbolP);
303
60
      S_SET_SEGMENT (symbolP, elf_com_section_ptr);
304
60
    }
305
306
60
  symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
307
308
60
  return symbolP;
309
61
}
310
311
void
312
obj_elf_common (int is_common)
313
148
{
314
148
  if (flag_mri && is_common)
315
2
    s_mri_common (0);
316
146
  else
317
146
    s_comm_internal (0, elf_common_parse);
318
148
}
319
320
static void
321
obj_elf_tls_common (int ignore ATTRIBUTE_UNUSED)
322
2
{
323
2
  symbolS *symbolP = s_comm_internal (0, elf_common_parse);
324
325
2
  if (symbolP)
326
0
    symbol_get_bfdsym (symbolP)->flags |= BSF_THREAD_LOCAL;
327
2
}
328
329
static void
330
obj_elf_lcomm (int ignore ATTRIBUTE_UNUSED)
331
146
{
332
146
  symbolS *symbolP = s_comm_internal (0, s_lcomm_internal);
333
334
146
  if (symbolP)
335
4
    symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
336
146
}
337
338
static symbolS *
339
get_sym_from_input_line_and_check (void)
340
741
{
341
741
  char *name;
342
741
  char c;
343
741
  symbolS *sym;
344
345
741
  c = get_symbol_name (& name);
346
741
  sym = symbol_find_or_make (name);
347
741
  restore_line_pointer (c);
348
741
  SKIP_WHITESPACE ();
349
350
  /* There is no symbol name if input_line_pointer has not moved.  */
351
741
  if (name == input_line_pointer)
352
563
    as_bad (_("Missing symbol name in directive"));
353
741
  return sym;
354
741
}
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
53
{
383
53
  int c;
384
53
  symbolS *symbolP;
385
386
53
  do
387
320
    {
388
320
      symbolP = get_sym_from_input_line_and_check ();
389
320
      c = *input_line_pointer;
390
320
      S_SET_WEAK (symbolP);
391
320
      if (c == ',')
392
267
  {
393
267
    input_line_pointer++;
394
267
    SKIP_WHITESPACE ();
395
267
    if (*input_line_pointer == '\n')
396
0
      c = '\n';
397
267
  }
398
320
    }
399
320
  while (c == ',');
400
53
  demand_empty_rest_of_line ();
401
53
}
402
403
static void
404
obj_elf_visibility (int visibility)
405
5
{
406
5
  int c;
407
5
  symbolS *symbolP;
408
5
  asymbol *bfdsym;
409
5
  elf_symbol_type *elfsym;
410
411
5
  do
412
5
    {
413
5
      symbolP = get_sym_from_input_line_and_check ();
414
415
5
      bfdsym = symbol_get_bfdsym (symbolP);
416
5
      elfsym = elf_symbol_from (bfdsym);
417
418
5
      gas_assert (elfsym);
419
420
5
      elfsym->internal_elf_sym.st_other &= ~3;
421
5
      elfsym->internal_elf_sym.st_other |= visibility;
422
423
5
      c = *input_line_pointer;
424
5
      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
5
    }
434
5
  while (c == ',');
435
436
5
  demand_empty_rest_of_line ();
437
5
}
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
345k
#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
345k
{
466
345k
  const char *linked_to_symbol_name = sec->map_head.linked_to_symbol_name;
467
345k
  unsigned int sh_info = elf_section_data (sec)->this_hdr.sh_info;
468
345k
  bfd_vma sh_flags = (elf_section_data (sec)->this_hdr.sh_flags
469
345k
          & SEC_ASSEMBLER_SHF_MASK);
470
471
345k
  return (sh_info == match->sh_info
472
345k
    && sh_flags == match->sh_flags
473
6.58k
    && ((bfd_section_flags (sec) & SEC_ASSEMBLER_SECTION_ID)
474
6.58k
         == (match->flags & SEC_ASSEMBLER_SECTION_ID))
475
6.58k
    && sec->section_id == match->section_id
476
6.58k
    && (linked_to_symbol_name == match->linked_to_symbol_name
477
18
        || (linked_to_symbol_name != NULL
478
7
      && match->linked_to_symbol_name != NULL
479
7
      && strcmp (linked_to_symbol_name,
480
7
           match->linked_to_symbol_name) == 0)));
481
345k
}
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
344k
{
488
344k
  struct elf_section_match *match = inf;
489
344k
  const char *gname = match->group_name;
490
344k
  const char *group_name = elf_group_name (sec);
491
492
344k
  return ((group_name == gname
493
10.2k
     || (group_name != NULL
494
10.2k
         && gname != NULL
495
0
         && strcmp (group_name, gname) == 0))
496
334k
    && match_section (sec, match));
497
344k
}
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
1.53k
{
508
1.53k
  if (!groups.indexes)
509
9
    {
510
9
      groups.num_group = 0;
511
9
      groups.head = NULL;
512
9
      groups.indexes = htab_create_alloc (16, hash_string_tuple, eq_string_tuple,
513
9
            NULL, notes_calloc, NULL);
514
9
      *group_idx = ~0u;
515
9
      return NULL;
516
9
    }
517
518
1.52k
  *group_idx = str_hash_find_int (groups.indexes, match->group_name);
519
1.52k
  if (*group_idx == ~0u)
520
4
    return NULL;
521
522
1.52k
  asection *s;
523
11.9k
  for (s = groups.head[*group_idx]; s != NULL; s = elf_next_in_group (s))
524
11.7k
    if ((s->name == sec_name
525
11.7k
   || strcmp (s->name, sec_name) == 0)
526
11.2k
  && match_section (s, match))
527
1.32k
      break;
528
1.52k
  return s;
529
1.52k
}
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
218
{
539
218
  if (*group_idx != ~0u)
540
205
    {
541
205
      elf_next_in_group (sec) = groups.head[*group_idx];
542
205
      groups.head[*group_idx] = sec;
543
205
      return;
544
205
    }
545
546
13
  unsigned int i = groups.num_group;
547
13
  if ((i & 127) == 0)
548
9
    groups.head = XRESIZEVEC (asection *, groups.head, i + 128);
549
13
  groups.head[i] = sec;
550
13
  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
13
  str_hash_insert_int (groups.indexes, match->group_name, i, 0);
555
13
}
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
8.86k
{
585
8.86k
  asection *old_sec;
586
8.86k
  segT sec;
587
8.86k
  flagword flags;
588
8.86k
  const struct bfd_elf_special_section *ssect;
589
590
8.86k
  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
8.86k
  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
8.86k
  obj_elf_section_change_hook ();
614
615
8.86k
  unsigned int group_idx = ~0u;
616
8.86k
  if (match_p->group_name)
617
1.52k
    old_sec = group_section_find (match_p, name, &group_idx);
618
7.33k
  else
619
7.33k
    old_sec = bfd_get_section_by_name_if (stdoutput, name, get_section_by_match,
620
7.33k
            match_p);
621
8.86k
  if (old_sec)
622
6.56k
    {
623
6.56k
      sec = old_sec;
624
6.56k
      subseg_set (sec, new_subsection);
625
6.56k
    }
626
2.29k
  else
627
2.29k
    {
628
2.29k
      sec = subseg_force_new (name, new_subsection);
629
2.29k
      if (match_p->group_name)
630
210
  group_section_insert (match_p, sec, &group_idx);
631
2.29k
    }
632
633
8.86k
  elf_backend_data *bed = get_elf_backend_data (stdoutput);
634
8.86k
  ssect = (*bed->get_sec_type_attr) (stdoutput, sec);
635
636
8.86k
  if (ssect != NULL)
637
21
    {
638
21
      bool override = false;
639
640
21
      if (type == SHT_NULL)
641
19
  type = ssect->type;
642
2
      else if (type != ssect->type)
643
2
  {
644
2
    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
2
#ifdef TC_I386
657
2
        && (bed->s->arch_size != 64
658
2
      || !(ssect->attr & SHF_X86_64_LARGE))
659
2
#endif
660
2
        && ssect->type != SHT_INIT_ARRAY
661
2
        && ssect->type != SHT_FINI_ARRAY
662
2
        && ssect->type != SHT_PREINIT_ARRAY)
663
2
      {
664
        /* We allow to specify any type for a .note section.  */
665
2
        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
2
      }
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
2
  }
678
679
21
      if (old_sec == NULL && ((attr & ~(SHF_LINK_ORDER
680
20
          | SHF_MASKOS
681
20
          | SHF_MASKPROC))
682
20
            & ~ssect->attr) != 0)
683
6
  {
684
    /* Strip SHF_GNU_RETAIN.  */
685
6
    bfd_vma generic_attr = attr;
686
6
    if (elf_tdata (stdoutput)->has_gnu_osabi)
687
2
      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
6
    if (ssect->type == SHT_NOTE
694
6
        && (generic_attr == SHF_ALLOC
695
6
      || generic_attr == SHF_EXECINSTR))
696
0
      ;
697
    /* Allow different SHF_MERGE and SHF_STRINGS if we have
698
       something like .rodata.str.  */
699
6
    else if (ssect->suffix_length == -2
700
0
       && name[ssect->prefix_length] == '.'
701
0
       && (generic_attr
702
0
           & ~ssect->attr
703
0
           & ~SHF_MERGE
704
0
           & ~SHF_STRINGS) == 0)
705
0
      ;
706
    /* .interp, .strtab and .symtab can have SHF_ALLOC.  */
707
6
    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
6
    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
6
    else
730
6
      {
731
6
        if (match_p->group_name == NULL)
732
2
    as_warn (_("setting incorrect section attributes for %s"),
733
2
       name);
734
6
        override = true;
735
6
      }
736
6
  }
737
738
21
      if (!override && old_sec == NULL)
739
14
  attr |= ssect->attr;
740
21
    }
741
742
  /* Convert ELF type and flags to BFD flags.  */
743
8.86k
  flags = (SEC_RELOC
744
8.86k
     | ((attr & SHF_WRITE) ? 0 : SEC_READONLY)
745
8.86k
     | ((attr & SHF_ALLOC) ? SEC_ALLOC : 0)
746
8.86k
     | (((attr & SHF_ALLOC) && type != SHT_NOBITS) ? SEC_LOAD : 0)
747
8.86k
     | ((attr & SHF_EXECINSTR) ? SEC_CODE : 0)
748
8.86k
     | ((attr & SHF_MERGE) ? SEC_MERGE : 0)
749
8.86k
     | ((attr & SHF_STRINGS) ? SEC_STRINGS : 0)
750
8.86k
     | ((attr & SHF_EXCLUDE) ? SEC_EXCLUDE: 0)
751
8.86k
     | ((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
8.86k
  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
8.86k
  if ((flags & SEC_ALLOC) == 0 && name [0] == '.')
765
70
    {
766
70
      if (   startswith (name, ".debug")
767
55
    || startswith (name, ".zdebug")
768
55
    || startswith (name, ".gnu.debuglto_.debug_")
769
38
    || startswith (name, ".gnu.linkonce.wi.")
770
38
    || startswith (name, GNU_BUILD_ATTRS_SECTION_NAME)
771
30
    || startswith (name, ".note.gnu"))
772
42
  flags |= SEC_ELF_OCTETS;
773
70
    }
774
775
8.86k
  if (old_sec == NULL)
776
2.29k
    {
777
2.29k
      if (type == SHT_NULL)
778
652
  type = bfd_elf_get_default_section_type (flags);
779
2.29k
      elf_section_type (sec) = type;
780
2.29k
      elf_section_flags (sec) = attr;
781
2.29k
      elf_section_data (sec)->this_hdr.sh_info = match_p->sh_info;
782
783
      /* Prevent SEC_HAS_CONTENTS from being inadvertently set.  */
784
2.29k
      if (type == SHT_NOBITS)
785
0
  seg_info (sec)->bss = 1;
786
787
      /* Set the section ID and flags.  */
788
2.29k
      sec->section_id = match_p->section_id;
789
2.29k
      flags |= match_p->flags;
790
791
      /* Set the linked-to symbol name.  */
792
2.29k
      sec->map_head.linked_to_symbol_name
793
2.29k
  = match_p->linked_to_symbol_name;
794
795
2.29k
      bfd_set_section_flags (sec, flags);
796
2.29k
      if (entsize != 0)
797
248
  sec->entsize = entsize;
798
2.29k
      elf_group_name (sec) = match_p->group_name;
799
800
      /* Add a symbol for this section to the symbol table.  */
801
2.29k
      symbol_table_insert (section_symbol (sec));
802
2.29k
    }
803
6.56k
  else
804
6.56k
    {
805
6.56k
      if (type != SHT_NULL
806
1.40k
    && (unsigned) type != elf_section_type (old_sec))
807
19
  {
808
19
    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
19
    else
815
      /* Do error when assembly isn't self-consistent.  */
816
19
      as_bad (_("changed section type for %s"), name);
817
19
  }
818
819
6.56k
      if (attr != 0)
820
5.59k
  {
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
5.59k
    if (((old_sec->flags ^ flags)
825
5.59k
         & (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
826
5.59k
      | SEC_EXCLUDE | SEC_SORT_ENTRIES | SEC_MERGE | SEC_STRINGS
827
5.59k
      | SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD
828
5.59k
      | SEC_THREAD_LOCAL)))
829
8
      {
830
8
        if (ssect != NULL)
831
0
    as_warn (_("ignoring changed section attributes for %s"), name);
832
8
        else
833
8
    as_bad (_("changed section attributes for %s"), name);
834
8
      }
835
5.58k
    else
836
      /* FIXME: Maybe we should consider removing a previously set
837
         processor or application specific attribute as suspicious?  */
838
5.58k
      elf_section_flags (sec) = attr;
839
840
5.59k
    if (entsize != 0
841
0
        && old_sec->entsize != (unsigned) entsize)
842
0
      as_bad (_("changed section entity size for %s"), name);
843
5.59k
  }
844
6.56k
    }
845
846
8.86k
#ifdef md_elf_section_change_hook
847
8.86k
  md_elf_section_change_hook ();
848
8.86k
#endif
849
8.86k
}
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
8.03k
{
867
8.03k
  bfd_vma attr = 0;
868
869
8.03k
  *is_clone = false;
870
8.03k
  *inherit = 0;
871
872
30.6k
  while (len > 0)
873
30.0k
    {
874
30.0k
      switch (*str)
875
30.0k
  {
876
25
  case 'a':
877
25
    attr |= SHF_ALLOC;
878
    /* Compatibility.  */
879
25
    if (len > 1 && str[1] == 'm')
880
4
      {
881
4
        attr |= SHF_MERGE;
882
4
        str++, len--;
883
4
        if (len > 1 && str[1] == 's')
884
0
    {
885
0
      attr |= SHF_STRINGS;
886
0
      str++, len--;
887
0
    }
888
4
      }
889
25
    break;
890
532
  case 'd':
891
532
    if (gnu_attr == NULL)
892
0
      goto unrecognized;
893
532
    *gnu_attr |= SHF_GNU_MBIND;
894
532
    break;
895
12
  case 'e':
896
12
    attr |= SHF_EXCLUDE;
897
12
    break;
898
0
  case 'o':
899
0
    attr |= SHF_LINK_ORDER;
900
0
    break;
901
763
  case 'w':
902
763
    attr |= SHF_WRITE;
903
763
    break;
904
2
  case 'x':
905
2
    attr |= SHF_EXECINSTR;
906
2
    break;
907
0
  case 'E':
908
0
    *has_entsize = true;
909
0
    break;
910
728
  case 'G':
911
728
    attr |= SHF_GROUP;
912
728
    break;
913
2
  case 'M':
914
2
    attr |= SHF_MERGE;
915
2
    break;
916
101
  case 'R':
917
101
    if (gnu_attr == NULL)
918
0
      goto unrecognized;
919
101
    *gnu_attr |= SHF_GNU_RETAIN;
920
101
    break;
921
0
  case 'S':
922
0
    attr |= SHF_STRINGS;
923
0
    break;
924
114
  case 'T':
925
114
    attr |= SHF_TLS;
926
114
    break;
927
1
  case '?':
928
1
    *is_clone = true;
929
1
    break;
930
27.8k
  default:
931
27.8k
  unrecognized:
932
27.8k
    {
933
27.8k
      const char *md_extra = "";
934
935
27.8k
#ifdef md_elf_section_letter
936
27.8k
      bfd_vma md_attr = md_elf_section_letter (*str, &md_extra);
937
27.8k
      if (md_attr != (bfd_vma) -1)
938
1
        attr |= md_attr;
939
27.8k
      else
940
27.8k
#endif
941
27.8k
        if (ISDIGIT (*str))
942
17.3k
    {
943
17.3k
      char * end;
944
17.3k
      bfd_vma numeric_flags = strtoul (str, &end, 0);
945
946
17.3k
      attr |= numeric_flags;
947
948
17.3k
      if (gnu_attr != NULL)
949
17.3k
        {
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
17.3k
          *gnu_attr |= (numeric_flags & SHF_MASKOS);
959
17.3k
        }
960
961
      /* Update str and len, allowing for the fact that
962
         we will execute str++ and len-- below.  */
963
17.3k
      end --;
964
17.3k
      len -= (end - str);
965
17.3k
      str = end;
966
17.3k
    }
967
10.4k
        else if (!*inherit && !attr
968
3.17k
           && (gnu_attr == NULL || !*gnu_attr)
969
3.17k
           && (*str == '+' || *str == '-'))
970
2.99k
    *inherit = *str == '+' ? 1 : -1;
971
7.49k
        else
972
7.49k
    {
973
7.49k
      as_bad (_("unrecognized .%ssection attribute: want %s%s%s,? or number"),
974
7.49k
        push ? "push" : "",
975
7.49k
        gnu_attr != NULL ? "a,d,e,o,w,x,E,G,M,R,S,T"
976
7.49k
             : "a,e,o,w,x,E,G,M,S,T",
977
7.49k
        md_extra != NULL ? "," : "", md_extra);
978
7.49k
      return attr;
979
7.49k
    }
980
27.8k
    }
981
20.3k
    break;
982
30.0k
  }
983
22.5k
      str++, len--;
984
22.5k
    }
985
986
537
  return attr;
987
8.03k
}
988
989
static int
990
obj_elf_section_type (char *str, size_t len, bool warn)
991
251
{
992
251
  if (len == 8 && startswith (str, "progbits"))
993
0
    return SHT_PROGBITS;
994
251
  if (len == 6 && startswith (str, "nobits"))
995
0
    return SHT_NOBITS;
996
251
  if (len == 4 && startswith (str, "note"))
997
1
    return SHT_NOTE;
998
250
  if (len == 10 && startswith (str, "init_array"))
999
0
    return SHT_INIT_ARRAY;
1000
250
  if (len == 10 && startswith (str, "fini_array"))
1001
0
    return SHT_FINI_ARRAY;
1002
250
  if (len == 13 && startswith (str, "preinit_array"))
1003
0
    return SHT_PREINIT_ARRAY;
1004
1005
250
#ifdef md_elf_section_type
1006
250
  {
1007
250
    int md_type = md_elf_section_type (str, len);
1008
250
    if (md_type >= 0)
1009
6
      return md_type;
1010
250
  }
1011
244
#endif
1012
1013
244
  if (ISDIGIT (*str))
1014
21
    {
1015
21
      char * end;
1016
21
      int type = strtoul (str, & end, 0);
1017
1018
21
      if (warn && (size_t) (end - str) != len)
1019
18
  as_warn (_("extraneous characters at end of numeric section type"));
1020
1021
21
      return type;
1022
21
    }
1023
1024
223
  if (warn)
1025
223
    as_warn (_("unrecognized section type"));
1026
223
  return 0;
1027
244
}
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
9.82k
{
1060
9.82k
  char *name;
1061
1062
9.82k
  SKIP_WHITESPACE ();
1063
9.82k
  if (*input_line_pointer == '"')
1064
469
    {
1065
469
      int dummy;
1066
1067
469
      name = demand_copy_C_string (&dummy);
1068
469
      if (name == NULL)
1069
4
  {
1070
4
    ignore_rest_of_line ();
1071
4
    return NULL;
1072
4
  }
1073
469
    }
1074
9.36k
  else
1075
9.36k
    {
1076
9.36k
      char *end = input_line_pointer;
1077
1078
52.3k
      while (!is_whitespace (*end) && !is_end_of_stmt (*end) && *end != ',')
1079
43.0k
  end++;
1080
9.36k
      if (end == input_line_pointer)
1081
9
  {
1082
9
    as_bad (_("missing name"));
1083
9
    ignore_rest_of_line ();
1084
9
    return NULL;
1085
9
  }
1086
1087
9.35k
      obstack_grow0 (&notes, input_line_pointer, end - input_line_pointer);
1088
9.35k
      name = obstack_base (&notes);
1089
1090
9.35k
      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
9.35k
      obstack_finish (&notes);
1112
1113
#ifdef tc_canonicalize_section_name
1114
      name = tc_canonicalize_section_name (name);
1115
#endif
1116
9.35k
      input_line_pointer = end;
1117
9.35k
    }
1118
9.81k
  SKIP_WHITESPACE ();
1119
9.81k
  return name;
1120
9.82k
}
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
13
{
1128
13
  elf_group_name (sec) = gname;
1129
13
  elf_section_flags (sec) |= SHF_GROUP;
1130
1131
13
  struct elf_section_match match;
1132
13
  match.group_name = gname;
1133
13
  match.linked_to_symbol_name = sec->map_head.linked_to_symbol_name;
1134
13
  match.section_id = sec->section_id;
1135
13
  match.sh_info = elf_section_data (sec)->this_hdr.sh_info;
1136
13
  match.sh_flags = (elf_section_data (sec)->this_hdr.sh_flags
1137
13
        & SEC_ASSEMBLER_SHF_MASK);
1138
13
  match.flags = bfd_section_flags (sec) & SEC_ASSEMBLER_SECTION_ID;
1139
1140
13
  unsigned int group_idx;
1141
13
  if (!group_section_find (&match, sec->name, &group_idx))
1142
8
    group_section_insert (&match, sec, &group_idx);
1143
13
}
1144
1145
static void
1146
obj_elf_attach_to_group (int dummy ATTRIBUTE_UNUSED)
1147
13
{
1148
13
  const char * gname = obj_elf_section_name ();
1149
1150
13
  if (gname == NULL)
1151
0
    {
1152
0
      as_warn (_("group name not parseable"));
1153
0
      return;
1154
0
    }
1155
1156
13
  if (elf_group_name (now_seg))
1157
0
    {
1158
0
      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
0
      return;
1162
0
    }
1163
13
  elf_set_group_name (now_seg, gname);
1164
13
}
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
12.8k
{
1178
12.8k
  const char *name;
1179
12.8k
  char *beg;
1180
12.8k
  int type, dummy;
1181
12.8k
  bfd_vma attr;
1182
12.8k
  bfd_vma gnu_attr;
1183
12.8k
  int entsize;
1184
12.8k
  bool linkonce, has_entsize;
1185
12.8k
  subsegT new_subsection = 0;
1186
12.8k
  struct elf_section_match match;
1187
12.8k
  unsigned long linked_to_section_index = -1UL;
1188
1189
12.8k
  if (flag_mri)
1190
3.95k
    {
1191
3.95k
      char mri_type;
1192
1193
#ifdef md_flush_pending_output
1194
      md_flush_pending_output ();
1195
#endif
1196
1197
3.95k
      obj_elf_section_change_hook ();
1198
1199
3.95k
      s_mri_sect (&mri_type);
1200
1201
3.95k
#ifdef md_elf_section_change_hook
1202
3.95k
      md_elf_section_change_hook ();
1203
3.95k
#endif
1204
1205
3.95k
      return;
1206
3.95k
    }
1207
1208
8.86k
  name = obj_elf_section_name ();
1209
8.86k
  if (name == NULL)
1210
8
    return;
1211
1212
8.86k
  memset (&match, 0, sizeof (match));
1213
1214
8.86k
  symbolS * sym;
1215
8.86k
  if ((sym = symbol_find (name)) != NULL
1216
8.74k
      && ! 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
8.86k
  type = SHT_NULL;
1226
8.86k
  attr = 0;
1227
8.86k
  gnu_attr = 0;
1228
8.86k
  entsize = 0;
1229
8.86k
  has_entsize = false;
1230
8.86k
  linkonce = 0;
1231
1232
8.86k
  if (*input_line_pointer == ',')
1233
8.04k
    {
1234
      /* Skip the comma.  */
1235
8.04k
      ++input_line_pointer;
1236
8.04k
      SKIP_WHITESPACE ();
1237
1238
8.04k
      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
8.04k
      if (*input_line_pointer == '"')
1255
8.03k
  {
1256
8.03k
    bool is_clone;
1257
8.03k
    int inherit;
1258
1259
8.03k
    beg = demand_copy_C_string (&dummy);
1260
8.03k
    if (beg == NULL)
1261
0
      {
1262
0
        ignore_rest_of_line ();
1263
0
        return;
1264
0
      }
1265
1266
8.03k
    elf_backend_data *bed = get_elf_backend_data (stdoutput);
1267
8.03k
    bool maybe_gnu = (bed->elf_osabi == ELFOSABI_NONE
1268
8.03k
          || bed->elf_osabi == ELFOSABI_GNU
1269
0
          || bed->elf_osabi == ELFOSABI_FREEBSD);
1270
8.03k
    attr = obj_elf_parse_section_letters (beg, strlen (beg), push,
1271
8.03k
            &is_clone, &inherit,
1272
8.03k
            maybe_gnu ? &gnu_attr : NULL,
1273
8.03k
            &has_entsize);
1274
1275
8.03k
    if (inherit > 0)
1276
2.99k
      attr |= elf_section_flags (now_seg);
1277
5.04k
    else if (inherit < 0)
1278
0
      attr = elf_section_flags (now_seg) & ~attr;
1279
8.03k
    if (inherit)
1280
2.99k
      type = elf_section_type (now_seg);
1281
1282
8.03k
    if ((attr & (SHF_MERGE | SHF_STRINGS)) != 0)
1283
4.29k
      has_entsize = true;
1284
1285
8.03k
    SKIP_WHITESPACE ();
1286
8.03k
    if (*input_line_pointer == ',')
1287
2.83k
      {
1288
2.83k
        char c;
1289
2.83k
        char *save = input_line_pointer;
1290
1291
2.83k
        ++input_line_pointer;
1292
2.83k
        SKIP_WHITESPACE ();
1293
2.83k
        c = *input_line_pointer;
1294
2.83k
        if (c == '"')
1295
248
    {
1296
248
      beg = demand_copy_C_string (&dummy);
1297
248
      if (beg == NULL)
1298
0
        {
1299
0
          ignore_rest_of_line ();
1300
0
          return;
1301
0
        }
1302
248
      type = obj_elf_section_type (beg, strlen (beg), true);
1303
248
    }
1304
2.58k
        else if (c == '@' || c == '%')
1305
3
    {
1306
3
      ++input_line_pointer;
1307
1308
3
      if (ISDIGIT (* input_line_pointer))
1309
0
        type = strtoul (input_line_pointer, &input_line_pointer, 0);
1310
3
      else
1311
3
        {
1312
3
          c = get_symbol_name (& beg);
1313
3
          (void) restore_line_pointer (c);
1314
3
          type = obj_elf_section_type (beg,
1315
3
               input_line_pointer - beg,
1316
3
               true);
1317
3
        }
1318
3
    }
1319
2.58k
        else
1320
2.58k
    input_line_pointer = save;
1321
2.83k
      }
1322
1323
8.03k
    SKIP_WHITESPACE ();
1324
8.03k
    if (has_entsize && *input_line_pointer == ',')
1325
369
      {
1326
369
        ++input_line_pointer;
1327
369
        SKIP_WHITESPACE ();
1328
369
        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
369
        if (is_end_of_stmt (*input_line_pointer)
1334
1
      && (bfd_section_flags (now_seg)
1335
1
          & (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
369
        else
1347
369
    {
1348
369
      entsize = get_absolute_expression ();
1349
369
      SKIP_WHITESPACE ();
1350
369
      if (entsize <= 0)
1351
369
        {
1352
369
          as_warn (_("invalid section entity size"));
1353
369
          attr &= ~(SHF_MERGE | SHF_STRINGS);
1354
369
          has_entsize = false;
1355
369
          entsize = 0;
1356
369
        }
1357
369
    }
1358
369
      }
1359
7.66k
    else if (has_entsize && inherit
1360
539
        && ((bfd_section_flags (now_seg)
1361
539
       & (SEC_MERGE | SEC_STRINGS)) != 0
1362
539
      || now_seg->entsize))
1363
0
      {
1364
0
      fetch_entsize:
1365
0
        entsize = now_seg->entsize;
1366
0
      }
1367
7.66k
    else if ((attr & SHF_MERGE) != 0)
1368
3.67k
      {
1369
        /* ??? Perhaps we should error here.  The manual says that
1370
     entsize must be specified if SHF_MERGE is set.  */
1371
3.67k
        as_warn (_("entity size for SHF_MERGE not specified"));
1372
3.67k
        attr &= ~(SHF_MERGE | SHF_STRINGS);
1373
3.67k
        has_entsize = false;
1374
3.67k
      }
1375
3.99k
    else if ((attr & SHF_STRINGS) != 0)
1376
248
      {
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
248
        entsize = 1;
1382
248
      }
1383
3.74k
    else if (has_entsize)
1384
0
      {
1385
0
        as_warn (_("entity size not specified"));
1386
0
        has_entsize = false;
1387
0
      }
1388
1389
8.03k
    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
8.03k
    if ((attr & SHF_LINK_ORDER) != 0 && *input_line_pointer == ',')
1393
1.14k
      {
1394
1.14k
        ++input_line_pointer;
1395
1.14k
        SKIP_WHITESPACE ();
1396
        /* Check for a numeric section index, rather than a symbol name.  */
1397
1.14k
        if (ISDIGIT (* input_line_pointer))
1398
2
    {
1399
2
      linked_to_section_index = strtoul (input_line_pointer, & input_line_pointer, 0);
1400
2
    }
1401
1.14k
        else if (inherit && *input_line_pointer == ','
1402
0
           && (elf_section_flags (now_seg) & SHF_LINK_ORDER) != 0)
1403
0
    goto fetch_linked_to;
1404
1.14k
        else
1405
1.14k
    {
1406
1.14k
      char c;
1407
1.14k
      unsigned int length;
1408
1409
1.14k
      c = get_symbol_name (& beg);
1410
1.14k
      (void) restore_line_pointer (c);
1411
1.14k
      length = input_line_pointer - beg;
1412
1.14k
      if (length)
1413
12
        match.linked_to_symbol_name
1414
12
          = notes_memdup (beg, length, length + 1);
1415
1.14k
    }
1416
1.14k
      }
1417
6.88k
    else if ((attr & SHF_LINK_ORDER) != 0 && inherit
1418
1.65k
       && (elf_section_flags (now_seg) & SHF_LINK_ORDER) != 0)
1419
1.16k
      {
1420
1.16k
      fetch_linked_to:
1421
1.16k
        if (now_seg->map_head.linked_to_symbol_name)
1422
7
    match.linked_to_symbol_name =
1423
7
      now_seg->map_head.linked_to_symbol_name;
1424
1.16k
        else
1425
1.16k
    linked_to_section_index =
1426
1.16k
      elf_section_data (now_seg)->this_hdr.sh_link;
1427
1.16k
      }
1428
1429
8.03k
    if ((attr & SHF_GROUP) != 0 && is_clone)
1430
1
      {
1431
1
        as_warn (_("? section flag ignored with G present"));
1432
1
        is_clone = false;
1433
1
      }
1434
1435
8.03k
    if ((attr & SHF_GROUP) != 0 && *input_line_pointer == ',')
1436
947
      {
1437
947
        ++input_line_pointer;
1438
947
        SKIP_WHITESPACE ();
1439
947
        if (inherit && *input_line_pointer == ','
1440
0
      && (elf_section_flags (now_seg) & SHF_GROUP) != 0)
1441
0
    goto fetch_group;
1442
947
        match.group_name = obj_elf_section_name ();
1443
947
        if (match.group_name == NULL)
1444
5
    attr &= ~SHF_GROUP;
1445
942
        else if (*input_line_pointer == ',')
1446
585
    {
1447
585
      ++input_line_pointer;
1448
585
      SKIP_WHITESPACE ();
1449
585
      if (startswith (input_line_pointer, "comdat"))
1450
0
        {
1451
0
          input_line_pointer += 6;
1452
0
          linkonce = 1;
1453
0
        }
1454
585
    }
1455
357
        else if (startswith (name, ".gnu.linkonce"))
1456
0
    linkonce = 1;
1457
947
      }
1458
7.08k
    else if ((attr & SHF_GROUP) != 0 && inherit
1459
2.05k
       && (elf_section_flags (now_seg) & SHF_GROUP) != 0)
1460
583
      {
1461
583
      fetch_group:
1462
583
        match.group_name = elf_group_name (now_seg);
1463
583
        linkonce =
1464
583
          (bfd_section_flags (now_seg) & SEC_LINK_ONCE) != 0;
1465
583
      }
1466
6.50k
    else if ((attr & SHF_GROUP) != 0)
1467
3.03k
      {
1468
3.03k
        as_warn (_("group name for SHF_GROUP not specified"));
1469
3.03k
        attr &= ~SHF_GROUP;
1470
3.03k
      }
1471
1472
8.03k
    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
8.03k
    if ((gnu_attr & SHF_GNU_MBIND) != 0 && *input_line_pointer == ',')
1483
133
      {
1484
133
        char *save = input_line_pointer;
1485
133
        ++input_line_pointer;
1486
133
        SKIP_WHITESPACE ();
1487
133
        if (ISDIGIT (* input_line_pointer))
1488
133
    {
1489
133
      char *t = input_line_pointer;
1490
133
      match.sh_info = strtoul (input_line_pointer,
1491
133
          &input_line_pointer, 0);
1492
133
      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
133
    }
1498
0
        else
1499
0
    input_line_pointer = save;
1500
133
      }
1501
1502
8.03k
    if ((gnu_attr & SHF_GNU_RETAIN) != 0)
1503
2.53k
      match.sh_flags |= SHF_GNU_RETAIN;
1504
1505
8.03k
    if (*input_line_pointer == ',')
1506
1
      {
1507
1
        char *save = input_line_pointer;
1508
1509
1
        ++input_line_pointer;
1510
1
        SKIP_WHITESPACE ();
1511
1
        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
1
        else
1559
1
    input_line_pointer = save;
1560
1
      }
1561
8.03k
  }
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
8.04k
    }
1590
1591
8.86k
 done:
1592
8.86k
  demand_empty_rest_of_line ();
1593
1594
8.86k
  if ((gnu_attr & (SHF_GNU_MBIND | SHF_GNU_RETAIN)) != 0)
1595
2.94k
    {
1596
2.94k
      bool mbind_p = (gnu_attr & SHF_GNU_MBIND) != 0;
1597
1598
2.94k
      if (mbind_p && (attr & SHF_ALLOC) == 0)
1599
151
  as_bad (_("SHF_ALLOC isn't set for GNU_MBIND section: %s"), name);
1600
1601
2.94k
      if (mbind_p)
1602
1.45k
  elf_tdata (stdoutput)->has_gnu_osabi |= elf_gnu_osabi_mbind;
1603
2.94k
      if ((gnu_attr & SHF_GNU_RETAIN) != 0)
1604
2.53k
  elf_tdata (stdoutput)->has_gnu_osabi |= elf_gnu_osabi_retain;
1605
1606
2.94k
      attr |= gnu_attr;
1607
2.94k
    }
1608
1609
8.86k
  change_section (name, type, attr, entsize, &match, linkonce, push,
1610
8.86k
      new_subsection);
1611
1612
8.86k
  if (linked_to_section_index != -1UL)
1613
1.16k
    {
1614
1.16k
      elf_section_flags (now_seg) |= SHF_LINK_ORDER;
1615
1.16k
      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
1.16k
    }
1618
8.86k
}
1619
1620
/* Change to the .bss section.  */
1621
1622
void
1623
obj_elf_bss (int i ATTRIBUTE_UNUSED)
1624
26
{
1625
26
  int temp;
1626
1627
#ifdef md_flush_pending_output
1628
  md_flush_pending_output ();
1629
#endif
1630
1631
26
  obj_elf_section_change_hook ();
1632
1633
26
  temp = get_absolute_expression ();
1634
26
  subseg_set (bss_section, temp);
1635
26
  demand_empty_rest_of_line ();
1636
1637
26
#ifdef md_elf_section_change_hook
1638
26
  md_elf_section_change_hook ();
1639
26
#endif
1640
26
}
1641
1642
/* Change to the .data section.  */
1643
1644
void
1645
obj_elf_data (int i)
1646
1
{
1647
#ifdef md_flush_pending_output
1648
  md_flush_pending_output ();
1649
#endif
1650
1651
1
  obj_elf_section_change_hook ();
1652
1653
1
  s_data (i);
1654
1655
1
#ifdef md_elf_section_change_hook
1656
1
  md_elf_section_change_hook ();
1657
1
#endif
1658
1
}
1659
1660
/* Change to the .text section.  */
1661
1662
void
1663
obj_elf_text (int i)
1664
381
{
1665
#ifdef md_flush_pending_output
1666
  md_flush_pending_output ();
1667
#endif
1668
1669
381
  obj_elf_section_change_hook ();
1670
1671
381
  s_text (i);
1672
1673
381
#ifdef md_elf_section_change_hook
1674
381
  md_elf_section_change_hook ();
1675
381
#endif
1676
381
}
1677
1678
/* Change to the *ABS* section.  */
1679
1680
void
1681
obj_elf_struct (int i)
1682
232
{
1683
#ifdef md_flush_pending_output
1684
  md_flush_pending_output ();
1685
#endif
1686
1687
232
  obj_elf_section_change_hook ();
1688
1689
232
  s_struct (i);
1690
1691
232
#ifdef md_elf_section_change_hook
1692
232
  md_elf_section_change_hook ();
1693
232
#endif
1694
232
}
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
13.6k
{
1722
13.6k
  previous_section = now_seg;
1723
13.6k
  previous_subsection = now_subseg;
1724
13.6k
}
1725
1726
void
1727
obj_elf_previous (int ignore ATTRIBUTE_UNUSED)
1728
4
{
1729
4
  segT new_section;
1730
4
  int new_subsection;
1731
1732
4
  if (previous_section == 0)
1733
0
    {
1734
0
      as_warn (_(".previous without corresponding .section; ignored"));
1735
0
      return;
1736
0
    }
1737
1738
#ifdef md_flush_pending_output
1739
  md_flush_pending_output ();
1740
#endif
1741
1742
4
  new_section = previous_section;
1743
4
  new_subsection = previous_subsection;
1744
4
  obj_elf_section_change_hook ();
1745
1746
4
  subseg_set (new_section, new_subsection);
1747
1748
4
#ifdef md_elf_section_change_hook
1749
4
  md_elf_section_change_hook ();
1750
4
#endif
1751
4
}
1752
1753
static void
1754
obj_elf_popsection (int xxx ATTRIBUTE_UNUSED)
1755
2
{
1756
2
  struct section_stack *top = section_stack;
1757
1758
2
  if (top == NULL)
1759
2
    {
1760
2
      as_warn (_(".popsection without corresponding .pushsection; ignored"));
1761
2
      return;
1762
2
    }
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
22
{
1782
  /* Assume delimiter is part of expression.  BSD4.2 as fails with
1783
     delightful bug, so we are not being incompatible here.  */
1784
22
  new_logical_line (NULL, get_absolute_expression ());
1785
22
  demand_empty_rest_of_line ();
1786
22
}
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
56
{
1794
56
  struct elf_versioned_name_list *versioned_name;
1795
56
  const char *p;
1796
1797
368
  for (p = ver + 1; *p == ELF_VER_CHR; p++)
1798
312
    ;
1799
1800
  /* NB: Since some tests in ld/testsuite/ld-elfvers have no version
1801
     names, we have to disable this.  */
1802
56
  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
56
  versioned_name = sy_obj->versioned_name;
1810
1811
56
  switch (p - ver)
1812
56
    {
1813
28
    case 1:
1814
28
    case 2:
1815
28
      break;
1816
12
    case 3:
1817
12
      if (sy_obj->rename)
1818
11
  {
1819
11
    if (strcmp (versioned_name->name, version_name) == 0)
1820
0
      return versioned_name;
1821
11
    else
1822
11
      {
1823
11
        as_bad (_("only one version name with `@@@' is allowed "
1824
11
      "for symbol `%s'"), sym_name);
1825
11
        return NULL;
1826
11
      }
1827
11
  }
1828
1
      sy_obj->rename = true;
1829
1
      break;
1830
16
    default:
1831
16
      as_bad (_("invalid version name '%s' for symbol `%s'"),
1832
16
        version_name, sym_name);
1833
16
      return NULL;
1834
56
    }
1835
1836
29
  for (;
1837
84
       versioned_name != NULL;
1838
55
       versioned_name = versioned_name->next)
1839
70
    if (strcmp (versioned_name->name, version_name) == 0)
1840
15
      return versioned_name;
1841
1842
  /* Add this versioned name to the head of the list,  */
1843
14
  versioned_name = notes_alloc (sizeof (*versioned_name));
1844
14
  versioned_name->name = notes_strdup (version_name);
1845
14
  versioned_name->next = sy_obj->versioned_name;
1846
14
  sy_obj->versioned_name = versioned_name;
1847
1848
14
  return versioned_name;
1849
29
}
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
110
{
1860
110
  char *name;
1861
110
  const char *sym_name;
1862
110
  char c;
1863
110
  char old_lexat;
1864
110
  symbolS *sym;
1865
110
  struct elf_obj_sy *sy_obj;
1866
110
  char *p;
1867
1868
110
  sym = get_sym_from_input_line_and_check ();
1869
1870
110
  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
110
  ++input_line_pointer;
1878
110
  SKIP_WHITESPACE ();
1879
1880
  /* Temporarily include '@' in symbol names.  */
1881
110
  old_lexat = lex_type[(unsigned char) '@'];
1882
110
  lex_type[(unsigned char) '@'] |= LEX_NAME;
1883
110
  c = get_symbol_name (& name);
1884
110
  lex_type[(unsigned char) '@'] = old_lexat;
1885
110
  sym_name = S_GET_NAME (sym);
1886
1887
110
  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
80
  p = strchr (name, ELF_VER_CHR);
1896
80
  if (p == NULL)
1897
24
    {
1898
24
      as_bad (_("missing version name in `%s' for symbol `%s'"),
1899
24
        name, sym_name);
1900
24
      ignore_rest_of_line ();
1901
24
      return;
1902
24
    }
1903
1904
56
  sy_obj = symbol_get_obj (sym);
1905
56
  if (obj_elf_find_and_add_versioned_name (name, sym_name,
1906
56
             p, sy_obj) == NULL)
1907
27
    {
1908
27
      sy_obj->bad_version = true;
1909
27
      ignore_rest_of_line ();
1910
27
      return;
1911
27
    }
1912
1913
29
  (void) restore_line_pointer (c);
1914
1915
29
  if (*input_line_pointer == ',')
1916
4
    {
1917
4
      char *save = input_line_pointer;
1918
1919
4
      ++input_line_pointer;
1920
4
      SKIP_WHITESPACE ();
1921
4
      if (startswith (input_line_pointer, "local"))
1922
0
  {
1923
0
    input_line_pointer += 5;
1924
0
    sy_obj->visibility = visibility_local;
1925
0
  }
1926
4
      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
4
      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
4
      else
1937
4
  input_line_pointer = save;
1938
4
    }
1939
1940
29
  demand_empty_rest_of_line ();
1941
29
}
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
41
{
1950
41
  char *cname, *pname;
1951
41
  symbolS *csym, *psym;
1952
41
  char c;
1953
41
  bool bad = false;
1954
1955
41
  if (*input_line_pointer == '#')
1956
0
    ++input_line_pointer;
1957
1958
41
  c = get_symbol_name (& cname);
1959
41
  csym = symbol_find (cname);
1960
1961
  /* GCFIXME: should check that we don't have two .vtable_inherits for
1962
     the same child symbol.  Also, we can currently only do this if the
1963
     child symbol is already exists and is placed in a fragment.  */
1964
1965
41
  if (csym == NULL
1966
37
      || symbol_get_frag (csym) == NULL
1967
37
      || symbol_get_value_expression (csym)->X_op != O_constant)
1968
7
    {
1969
7
      as_bad (_("expected `%s' to have already been set for .vtable_inherit"),
1970
7
        cname);
1971
7
      bad = true;
1972
7
    }
1973
1974
41
  restore_line_pointer (c);
1975
1976
41
  SKIP_WHITESPACE ();
1977
41
  if (*input_line_pointer != ',')
1978
5
    {
1979
5
      as_bad (_("expected comma after name in .vtable_inherit"));
1980
5
      ignore_rest_of_line ();
1981
5
      return NULL;
1982
5
    }
1983
1984
36
  ++input_line_pointer;
1985
36
  SKIP_WHITESPACE ();
1986
1987
36
  if (*input_line_pointer == '#')
1988
0
    ++input_line_pointer;
1989
1990
36
  if (input_line_pointer[0] == '0'
1991
0
      && (is_end_of_stmt (input_line_pointer[1])
1992
0
    || is_whitespace (input_line_pointer[1])))
1993
0
    {
1994
0
      psym = section_symbol (absolute_section);
1995
0
      ++input_line_pointer;
1996
0
    }
1997
36
  else
1998
36
    {
1999
36
      c = get_symbol_name (& pname);
2000
36
      psym = symbol_find_or_make (pname);
2001
36
      restore_line_pointer (c);
2002
36
    }
2003
2004
36
  demand_empty_rest_of_line ();
2005
2006
36
  if (bad)
2007
6
    return NULL;
2008
2009
30
  return fix_new (symbol_get_frag (csym),
2010
30
      symbol_get_value_expression (csym)->X_add_number,
2011
30
      0, psym, 0, 0, BFD_RELOC_VTABLE_INHERIT);
2012
36
}
2013
2014
/* This is a version of obj_elf_get_vtable_inherit() that is
2015
   suitable for use in struct _pseudo_type tables.  */
2016
2017
void
2018
obj_elf_vtable_inherit (int ignore ATTRIBUTE_UNUSED)
2019
41
{
2020
41
  (void) obj_elf_get_vtable_inherit ();
2021
41
}
2022
2023
/* This handles the .vtable_entry pseudo-op, which is used to indicate
2024
   to the linker that a vtable slot was used.  The syntax is
2025
   ".vtable_entry tablename, offset".  */
2026
2027
struct fix *
2028
obj_elf_get_vtable_entry (void)
2029
18
{
2030
18
  symbolS *sym;
2031
18
  offsetT offset;
2032
2033
18
  if (*input_line_pointer == '#')
2034
0
    ++input_line_pointer;
2035
2036
18
  sym = get_sym_from_input_line_and_check ();
2037
18
  if (*input_line_pointer != ',')
2038
12
    {
2039
12
      as_bad (_("expected comma after name in .vtable_entry"));
2040
12
      ignore_rest_of_line ();
2041
12
      return NULL;
2042
12
    }
2043
2044
6
  ++input_line_pointer;
2045
6
  if (*input_line_pointer == '#')
2046
5
    ++input_line_pointer;
2047
2048
6
  offset = get_absolute_expression ();
2049
2050
6
  demand_empty_rest_of_line ();
2051
2052
6
  return fix_new (frag_now, frag_now_fix (), 0, sym, offset, 0,
2053
6
      BFD_RELOC_VTABLE_ENTRY);
2054
18
}
2055
2056
/* This is a version of obj_elf_get_vtable_entry() that is
2057
   suitable for use in struct _pseudo_type tables.  */
2058
2059
void
2060
obj_elf_vtable_entry (int ignore ATTRIBUTE_UNUSED)
2061
18
{
2062
18
  (void) obj_elf_get_vtable_entry ();
2063
18
}
2064
2065
void
2066
elf_obj_read_begin_hook (void)
2067
567
{
2068
#ifdef NEED_ECOFF_DEBUG
2069
  if (ECOFF_DEBUGGING)
2070
    ecoff_read_begin_hook ();
2071
#endif
2072
567
}
2073
2074
void
2075
elf_obj_symbol_new_hook (symbolS *symbolP)
2076
53.7k
{
2077
53.7k
  struct elf_obj_sy *sy_obj;
2078
2079
53.7k
  sy_obj = symbol_get_obj (symbolP);
2080
53.7k
  sy_obj->size = NULL;
2081
53.7k
  sy_obj->versioned_name = NULL;
2082
2083
#ifdef NEED_ECOFF_DEBUG
2084
  if (ECOFF_DEBUGGING)
2085
    ecoff_symbol_new_hook (symbolP);
2086
#endif
2087
53.7k
}
2088
2089
/* If size is unset, copy size from src.  Because we don't track whether
2090
   .size has been used, we can't differentiate .size dest, 0 from the case
2091
   where dest's size is unset.  */
2092
void
2093
elf_copy_symbol_size (symbolS *dest, symbolS *src)
2094
3.92k
{
2095
3.92k
  struct elf_obj_sy *srcelf = symbol_get_obj (src);
2096
3.92k
  struct elf_obj_sy *destelf = symbol_get_obj (dest);
2097
3.92k
  if (!destelf->size && S_GET_SIZE (dest) == 0)
2098
3.91k
    {
2099
3.91k
      destelf->size = srcelf->size;
2100
3.91k
      S_SET_SIZE (dest, S_GET_SIZE (src));
2101
3.91k
    }
2102
3.92k
}
2103
2104
void
2105
elf_copy_symbol_attributes (symbolS *dest, symbolS *src)
2106
3.92k
{
2107
3.92k
  elf_copy_symbol_size (dest, src);
2108
  /* Don't copy visibility.  */
2109
3.92k
  S_SET_OTHER (dest, (ELF_ST_VISIBILITY (S_GET_OTHER (dest))
2110
3.92k
          | (S_GET_OTHER (src) & ~ELF_ST_VISIBILITY (-1))));
2111
3.92k
}
2112
2113
void
2114
obj_elf_version (int ignore ATTRIBUTE_UNUSED)
2115
37
{
2116
37
  char *name;
2117
37
  unsigned int c;
2118
37
  char *p;
2119
37
  asection *seg = now_seg;
2120
37
  subsegT subseg = now_subseg;
2121
37
  Elf_Internal_Note i_note;
2122
37
  Elf_External_Note e_note;
2123
37
  asection *note_secp = NULL;
2124
2125
37
  SKIP_WHITESPACE ();
2126
37
  if (*input_line_pointer == '\"')
2127
0
    {
2128
0
      unsigned int len;
2129
2130
0
      ++input_line_pointer; /* -> 1st char of string.  */
2131
0
      name = input_line_pointer;
2132
2133
0
      while (is_a_char (c = next_char_of_string ()))
2134
0
  ;
2135
0
      c = *input_line_pointer;
2136
0
      *input_line_pointer = '\0';
2137
0
      *(input_line_pointer - 1) = '\0';
2138
0
      *input_line_pointer = c;
2139
2140
      /* Create the .note section.  */
2141
0
      note_secp = subseg_new (".note", 0);
2142
0
      bfd_set_section_flags (note_secp, SEC_HAS_CONTENTS | SEC_READONLY);
2143
0
      record_alignment (note_secp, 2);
2144
2145
      /* Process the version string.  */
2146
0
      len = strlen (name) + 1;
2147
2148
      /* PR 3456: Although the name field is padded out to an 4-byte
2149
   boundary, the namesz field should not be adjusted.  */
2150
0
      i_note.namesz = len;
2151
0
      i_note.descsz = 0;  /* No description.  */
2152
0
      i_note.type = NT_VERSION;
2153
0
      p = frag_more (sizeof (e_note.namesz));
2154
0
      md_number_to_chars (p, i_note.namesz, sizeof (e_note.namesz));
2155
0
      p = frag_more (sizeof (e_note.descsz));
2156
0
      md_number_to_chars (p, i_note.descsz, sizeof (e_note.descsz));
2157
0
      p = frag_more (sizeof (e_note.type));
2158
0
      md_number_to_chars (p, i_note.type, sizeof (e_note.type));
2159
0
      p = frag_more (len);
2160
0
      memcpy (p, name, len);
2161
2162
0
      frag_align (2, 0, 0);
2163
2164
0
      subseg_set (seg, subseg);
2165
0
    }
2166
37
  else
2167
37
    as_bad (_("expected quoted string"));
2168
2169
37
  demand_empty_rest_of_line ();
2170
37
}
2171
2172
static void
2173
obj_elf_size (int ignore ATTRIBUTE_UNUSED)
2174
10
{
2175
10
  char *name;
2176
10
  char c = get_symbol_name (&name);
2177
10
  char *p;
2178
10
  expressionS exp;
2179
10
  symbolS *sym;
2180
2181
10
  p = input_line_pointer;
2182
10
  restore_line_pointer (c);
2183
10
  SKIP_WHITESPACE ();
2184
10
  if (*input_line_pointer != ',')
2185
2
    {
2186
2
      *p = 0;
2187
2
      as_bad (_("expected comma after name `%s' in .size directive"), name);
2188
2
      *p = c;
2189
2
      ignore_rest_of_line ();
2190
2
      return;
2191
2
    }
2192
8
  input_line_pointer++;
2193
8
  expression (&exp);
2194
8
  if (exp.X_op == O_absent)
2195
2
    {
2196
2
      as_bad (_("missing expression in .size directive"));
2197
2
      exp.X_op = O_constant;
2198
2
      exp.X_add_number = 0;
2199
2
    }
2200
8
  *p = 0;
2201
8
  sym = symbol_find_or_make (name);
2202
8
  *p = c;
2203
8
  if (exp.X_op == O_constant)
2204
3
    {
2205
3
      S_SET_SIZE (sym, exp.X_add_number);
2206
3
      symbol_get_obj (sym)->size = NULL;
2207
3
    }
2208
5
  else
2209
5
    {
2210
5
      symbol_get_obj (sym)->size = notes_alloc (sizeof (exp));
2211
5
      *symbol_get_obj (sym)->size = exp;
2212
5
    }
2213
2214
  /* If the symbol in the directive matches the current function being
2215
     processed, indicate end of the current stream of ginsns.  */
2216
8
  if (flag_synth_cfi
2217
0
      && S_IS_FUNCTION (sym) && sym == ginsn_data_func_symbol ())
2218
0
    ginsn_data_end (symbol_temp_new_now ());
2219
2220
8
  demand_empty_rest_of_line ();
2221
8
}
2222
2223
/* Handle the ELF .type pseudo-op.  This sets the type of a symbol.
2224
   There are six syntaxes:
2225
2226
   The first (used on Solaris) is
2227
       .type SYM,#function
2228
   The second (used on UnixWare) is
2229
       .type SYM,@function
2230
   The third (reportedly to be used on Irix 6.0) is
2231
       .type SYM STT_FUNC
2232
   The fourth (used on NetBSD/Arm and Linux/ARM) is
2233
       .type SYM,%function
2234
   The fifth (used on SVR4/860) is
2235
       .type SYM,"function"
2236
   The sixth (emitted by recent SunPRO under Solaris) is
2237
       .type SYM,[0-9]
2238
   where the integer is the STT_* value.
2239
   */
2240
2241
static char *
2242
obj_elf_type_name (char *cp)
2243
288
{
2244
288
  char *p;
2245
2246
288
  p = input_line_pointer;
2247
288
  if (*input_line_pointer >= '0'
2248
265
      && *input_line_pointer <= '9')
2249
101
    {
2250
207
      while (*input_line_pointer >= '0'
2251
106
       && *input_line_pointer <= '9')
2252
106
  ++input_line_pointer;
2253
101
      *cp = *input_line_pointer;
2254
101
      *input_line_pointer = '\0';
2255
101
    }
2256
187
  else
2257
187
    *cp = get_symbol_name (&p);
2258
2259
288
  return p;
2260
288
}
2261
2262
static void
2263
obj_elf_type (int ignore ATTRIBUTE_UNUSED)
2264
288
{
2265
288
  char c;
2266
288
  int type;
2267
288
  const char *type_name;
2268
288
  symbolS *sym;
2269
288
  elf_symbol_type *elfsym;
2270
2271
288
  sym = get_sym_from_input_line_and_check ();
2272
288
  c = *input_line_pointer;
2273
288
  elfsym = (elf_symbol_type *) symbol_get_bfdsym (sym);
2274
2275
288
  if (*input_line_pointer == ',')
2276
2
    ++input_line_pointer;
2277
2278
288
  SKIP_WHITESPACE ();
2279
288
  if (   *input_line_pointer == '#'
2280
254
      || *input_line_pointer == '@'
2281
184
      || *input_line_pointer == '"'
2282
174
      || *input_line_pointer == '%')
2283
139
    ++input_line_pointer;
2284
2285
288
  type_name = obj_elf_type_name (& c);
2286
2287
288
  type = 0;
2288
288
  if (strcmp (type_name, "function") == 0
2289
280
      || strcmp (type_name, "2") == 0
2290
219
      || strcmp (type_name, "STT_FUNC") == 0)
2291
83
    type = BSF_FUNCTION;
2292
205
  else if (strcmp (type_name, "object") == 0
2293
205
     || strcmp (type_name, "1") == 0
2294
187
     || strcmp (type_name, "STT_OBJECT") == 0)
2295
23
    type = BSF_OBJECT;
2296
182
  else if (strcmp (type_name, "tls_object") == 0
2297
182
     || strcmp (type_name, "6") == 0
2298
165
     || strcmp (type_name, "STT_TLS") == 0)
2299
17
    type = BSF_OBJECT | BSF_THREAD_LOCAL;
2300
165
  else if (strcmp (type_name, "notype") == 0
2301
165
     || strcmp (type_name, "0") == 0
2302
164
     || strcmp (type_name, "STT_NOTYPE") == 0)
2303
1
    ;
2304
164
  else if (strcmp (type_name, "common") == 0
2305
127
     || strcmp (type_name, "5") == 0
2306
125
     || strcmp (type_name, "STT_COMMON") == 0)
2307
43
    {
2308
43
      type = BSF_OBJECT;
2309
2310
43
      if (! S_IS_COMMON (sym))
2311
6
  {
2312
6
    if (S_IS_VOLATILE (sym))
2313
0
      {
2314
0
        sym = symbol_clone (sym, 1);
2315
0
        S_SET_SEGMENT (sym, bfd_com_section_ptr);
2316
0
        S_SET_VALUE (sym, 0);
2317
0
        S_SET_EXTERNAL (sym);
2318
0
        symbol_set_frag (sym, &zero_address_frag);
2319
0
        S_CLEAR_VOLATILE (sym);
2320
0
      }
2321
6
    else if (S_IS_DEFINED (sym) || symbol_equated_p (sym))
2322
0
      as_bad (_("symbol '%s' is already defined"), S_GET_NAME (sym));
2323
6
    else
2324
6
      {
2325
        /* FIXME: Is it safe to just change the section ?  */
2326
6
        S_SET_SEGMENT (sym, bfd_com_section_ptr);
2327
6
        S_SET_VALUE (sym, 0);
2328
6
        S_SET_EXTERNAL (sym);
2329
6
      }
2330
6
  }
2331
43
    }
2332
121
  else if (strcmp (type_name, "gnu_indirect_function") == 0
2333
121
     || strcmp (type_name, "10") == 0
2334
120
     || strcmp (type_name, "STT_GNU_IFUNC") == 0)
2335
3
    {
2336
3
      elf_backend_data *bed = get_elf_backend_data (stdoutput);
2337
3
      if (bed->elf_osabi != ELFOSABI_NONE
2338
3
    && bed->elf_osabi != ELFOSABI_GNU
2339
0
    && bed->elf_osabi != ELFOSABI_FREEBSD)
2340
0
  as_bad (_("symbol type \"%s\" is supported only by GNU "
2341
0
      "and FreeBSD targets"), type_name);
2342
      /* MIPS targets do not support IFUNCS.  */
2343
3
      else if (bed->target_id == MIPS_ELF_DATA)
2344
0
  as_bad (_("symbol type \"%s\" is not supported by "
2345
0
                    "MIPS targets"), type_name);
2346
3
      elf_tdata (stdoutput)->has_gnu_osabi |= elf_gnu_osabi_ifunc;
2347
3
      type = BSF_FUNCTION | BSF_GNU_INDIRECT_FUNCTION;
2348
3
    }
2349
118
  else if (strcmp (type_name, "gnu_unique_object") == 0)
2350
8
    {
2351
8
      elf_backend_data *bed = get_elf_backend_data (stdoutput);
2352
8
      if (bed->elf_osabi != ELFOSABI_NONE
2353
8
    && bed->elf_osabi != ELFOSABI_GNU)
2354
0
  as_bad (_("symbol type \"%s\" is supported only by GNU targets"),
2355
0
    type_name);
2356
8
      elf_tdata (stdoutput)->has_gnu_osabi |= elf_gnu_osabi_unique;
2357
8
      type = BSF_OBJECT | BSF_GNU_UNIQUE;
2358
8
    }
2359
#ifdef md_elf_symbol_type
2360
  else if ((type = md_elf_symbol_type (type_name, sym, elfsym)) != -1)
2361
    ;
2362
#endif
2363
110
  else
2364
110
    as_bad (_("unrecognized symbol type \"%s\""), type_name);
2365
2366
288
  *input_line_pointer = c;
2367
2368
288
  if (*input_line_pointer == '"')
2369
23
    ++input_line_pointer;
2370
2371
#ifdef md_elf_symbol_type_change
2372
  if (!md_elf_symbol_type_change (sym, elfsym, type))
2373
#endif
2374
288
    {
2375
288
      flagword mask = BSF_FUNCTION | BSF_OBJECT;
2376
2377
288
      if (type != BSF_FUNCTION)
2378
205
  mask |= BSF_GNU_INDIRECT_FUNCTION;
2379
288
      if (type != BSF_OBJECT)
2380
222
  {
2381
222
    mask |= BSF_GNU_UNIQUE | BSF_THREAD_LOCAL;
2382
2383
222
    if (S_IS_COMMON (sym))
2384
5
      {
2385
5
        as_bad (_("cannot change type of common symbol '%s'"),
2386
5
          S_GET_NAME (sym));
2387
5
        mask = type = 0;
2388
5
      }
2389
222
  }
2390
2391
      /* Don't warn when changing to STT_NOTYPE.  */
2392
288
      if (type)
2393
177
  {
2394
177
    flagword new = (elfsym->symbol.flags & ~mask) | type;
2395
2396
177
    if (new != (elfsym->symbol.flags | type))
2397
34
      as_warn (_("symbol '%s' already has its type set"), S_GET_NAME (sym));
2398
177
    elfsym->symbol.flags = new;
2399
177
  }
2400
111
      else
2401
111
  elfsym->symbol.flags &= ~mask;
2402
288
    }
2403
2404
288
  if (S_IS_FUNCTION (sym) && flag_synth_cfi)
2405
0
    {
2406
      /* When using SCFI, .type directive indicates start of a new FDE for SCFI
2407
   processing.  So, we must first demarcate the previous block of ginsns,
2408
   if any, to mark the end of a previous FDE.  */
2409
0
      if (frchain_now->frch_ginsn_data)
2410
0
  ginsn_data_end (symbol_temp_new_now ());
2411
0
      ginsn_data_begin (sym);
2412
0
    }
2413
2414
288
  demand_empty_rest_of_line ();
2415
288
}
2416
2417
static segT comment_section;
2418
2419
static void
2420
obj_elf_ident (int ignore ATTRIBUTE_UNUSED)
2421
0
{
2422
0
  segT old_section = now_seg;
2423
0
  int old_subsection = now_subseg;
2424
2425
#ifdef md_flush_pending_output
2426
  md_flush_pending_output ();
2427
#endif
2428
2429
0
  if (!comment_section)
2430
0
    {
2431
0
      char *p;
2432
0
      comment_section = subseg_new (".comment", 0);
2433
0
      bfd_set_section_flags (comment_section, (SEC_READONLY | SEC_HAS_CONTENTS
2434
0
                 | SEC_MERGE | SEC_STRINGS));
2435
0
      comment_section->entsize = 1;
2436
0
#ifdef md_elf_section_change_hook
2437
0
      md_elf_section_change_hook ();
2438
0
#endif
2439
0
      p = frag_more (1);
2440
0
      *p = 0;
2441
0
    }
2442
0
  else
2443
0
    {
2444
0
      subseg_set (comment_section, 0);
2445
0
#ifdef md_elf_section_change_hook
2446
0
      md_elf_section_change_hook ();
2447
0
#endif
2448
0
    }
2449
0
  stringer (8 + 1);
2450
0
  subseg_set (old_section, old_subsection);
2451
0
#ifdef md_elf_section_change_hook
2452
0
  md_elf_section_change_hook ();
2453
0
#endif
2454
0
}
2455
2456
#ifdef INIT_STAB_SECTION
2457
2458
/* The first entry in a .stabs section is special.  */
2459
2460
void
2461
obj_elf_init_stab_section (segT stab, segT stabstr)
2462
20
{
2463
20
  char *file;
2464
20
  char *p;
2465
20
  unsigned int stroff;
2466
2467
  /* Force the section to align to a longword boundary.  Without this,
2468
     UnixWare ar crashes.  */
2469
20
  bfd_set_section_alignment (stab, 2);
2470
2471
  /* Make space for this first symbol.  */
2472
20
  p = frag_more (12);
2473
  /* Zero it out.  */
2474
20
  memset (p, 0, 12);
2475
20
  file = remap_debug_filename (as_where (NULL));
2476
20
  stroff = get_stab_string_offset (file, stabstr);
2477
20
  know (stroff == 1 || (stroff == 0 && file[0] == '\0'));
2478
20
  md_number_to_chars (p, stroff, 4);
2479
20
  seg_info (stab)->stabu.p = p;
2480
20
  free (file);
2481
20
}
2482
2483
#endif
2484
2485
/* Called via bfd_map_over_sections.  If SEC's linked_to_symbol_name
2486
   isn't NULL, set up its linked-to section.
2487
   For .stabs section, fill in the counts in the first entry.  */
2488
2489
static void
2490
set_additional_section_info (bfd *abfd,
2491
           asection *sec,
2492
           void *inf ATTRIBUTE_UNUSED)
2493
0
{
2494
0
  if (sec->map_head.linked_to_symbol_name)
2495
0
    {
2496
0
      symbolS *linked_to_sym;
2497
0
      linked_to_sym = symbol_find (sec->map_head.linked_to_symbol_name);
2498
0
      if (!linked_to_sym || !S_IS_DEFINED (linked_to_sym))
2499
0
  as_bad (_("undefined linked-to symbol `%s' on section `%s'"),
2500
0
    sec->map_head.linked_to_symbol_name,
2501
0
    bfd_section_name (sec));
2502
0
      else
2503
0
  elf_linked_to_section (sec) = S_GET_SEGMENT (linked_to_sym);
2504
0
    }
2505
2506
0
  char *name;
2507
0
  asection *strsec;
2508
0
  char *p;
2509
0
  int strsz, nsyms;
2510
2511
0
  if (!startswith (sec->name, ".stab"))
2512
0
    return;
2513
0
  if (!strcmp ("str", sec->name + strlen (sec->name) - 3))
2514
0
    return;
2515
2516
0
  name = concat (sec->name, "str", (const char *) NULL);
2517
0
  strsec = bfd_get_section_by_name (abfd, name);
2518
0
  if (strsec)
2519
0
    strsz = bfd_section_size (strsec);
2520
0
  else
2521
0
    strsz = 0;
2522
0
  nsyms = bfd_section_size (sec) / 12 - 1;
2523
2524
0
  p = seg_info (sec)->stabu.p;
2525
0
  gas_assert (p != 0);
2526
2527
0
  bfd_h_put_16 (abfd, nsyms, p + 6);
2528
0
  bfd_h_put_32 (abfd, strsz, p + 8);
2529
0
  free (name);
2530
0
}
2531
2532
#ifdef NEED_ECOFF_DEBUG
2533
2534
/* This function is called by the ECOFF code.  It is supposed to
2535
   record the external symbol information so that the backend can
2536
   write it out correctly.  The ELF backend doesn't actually handle
2537
   this at the moment, so we do it ourselves.  We save the information
2538
   in the symbol.  */
2539
2540
#ifdef OBJ_MAYBE_ELF
2541
static
2542
#endif
2543
void
2544
elf_ecoff_set_ext (symbolS *sym, struct ecoff_extr *ext)
2545
{
2546
  symbol_get_bfdsym (sym)->udata.p = ext;
2547
}
2548
2549
/* This function is called by bfd_ecoff_debug_externals.  It is
2550
   supposed to *EXT to the external symbol information, and return
2551
   whether the symbol should be used at all.  */
2552
2553
static bool
2554
elf_get_extr (asymbol *sym, EXTR *ext)
2555
{
2556
  if (sym->udata.p == NULL)
2557
    return false;
2558
  *ext = *(EXTR *) sym->udata.p;
2559
  return true;
2560
}
2561
2562
/* This function is called by bfd_ecoff_debug_externals.  It has
2563
   nothing to do for ELF.  */
2564
2565
static void
2566
elf_set_index (asymbol *sym ATTRIBUTE_UNUSED,
2567
         bfd_size_type indx ATTRIBUTE_UNUSED)
2568
{
2569
}
2570
2571
#endif /* NEED_ECOFF_DEBUG */
2572
2573
void
2574
elf_frob_symbol (symbolS *symp, int *puntp)
2575
0
{
2576
0
  struct elf_obj_sy *sy_obj;
2577
0
  expressionS *size;
2578
0
  struct elf_versioned_name_list *versioned_name;
2579
2580
#ifdef NEED_ECOFF_DEBUG
2581
  if (ECOFF_DEBUGGING)
2582
    ecoff_frob_symbol (symp);
2583
#endif
2584
2585
0
  sy_obj = symbol_get_obj (symp);
2586
2587
0
  size = sy_obj->size;
2588
0
  if (size != NULL)
2589
0
    {
2590
0
      if (resolve_expression (size)
2591
0
    && size->X_op == O_constant)
2592
0
  S_SET_SIZE (symp, size->X_add_number);
2593
0
      else
2594
0
  {
2595
0
    if (!flag_allow_nonconst_size)
2596
0
      as_bad (_(".size expression for %s "
2597
0
          "does not evaluate to a constant"), S_GET_NAME (symp));
2598
0
    else
2599
0
      as_warn (_(".size expression for %s "
2600
0
           "does not evaluate to a constant"), S_GET_NAME (symp));
2601
0
  }
2602
0
      sy_obj->size = NULL;
2603
0
    }
2604
2605
0
  versioned_name = sy_obj->versioned_name;
2606
0
  if (versioned_name)
2607
0
    {
2608
      /* This symbol was given a new name with the .symver directive.
2609
   If this is an external reference, just rename the symbol to
2610
   include the version string.  This will make the relocs be
2611
   against the correct versioned symbol.  */
2612
2613
      /* We will have already reported an version error.  */
2614
0
      if (sy_obj->bad_version)
2615
0
  *puntp = true;
2616
      /* elf_frob_file_before_adjust only allows one version symbol for
2617
   renamed symbol.  */
2618
0
      else if (sy_obj->rename)
2619
0
  S_SET_NAME (symp, versioned_name->name);
2620
0
      else if (S_IS_COMMON (symp))
2621
0
  {
2622
0
    as_bad (_("`%s' can't be versioned to common symbol '%s'"),
2623
0
      versioned_name->name, S_GET_NAME (symp));
2624
0
    *puntp = true;
2625
0
  }
2626
0
      else
2627
0
  {
2628
0
    asymbol *bfdsym;
2629
0
    elf_symbol_type *elfsym;
2630
2631
    /* This is a definition.  Add an alias for each version.
2632
       FIXME: Using an alias will permit the debugging information
2633
       to refer to the right symbol.  However, it's not clear
2634
       whether it is the best approach.  */
2635
2636
    /* FIXME: Creating a new symbol here is risky.  We're
2637
       in the final loop over the symbol table.  We can
2638
       get away with it only because the symbol goes to
2639
       the end of the list, where the loop will still see
2640
       it.  It would probably be better to do this in
2641
       obj_frob_file_before_adjust.  */
2642
0
    for (; versioned_name != NULL;
2643
0
         versioned_name = versioned_name->next)
2644
0
      {
2645
0
        symbolS *symp2 = symbol_find_or_make (versioned_name->name);
2646
2647
0
        S_SET_SEGMENT (symp2, S_GET_SEGMENT (symp));
2648
2649
        /* Subtracting out the frag address here is a hack
2650
     because we are in the middle of the final loop.  */
2651
0
        S_SET_VALUE (symp2,
2652
0
         (S_GET_VALUE (symp)
2653
0
          - (symbol_get_frag (symp)->fr_address
2654
0
             / OCTETS_PER_BYTE)));
2655
2656
0
        symbol_set_frag (symp2, symbol_get_frag (symp));
2657
2658
        /* This will copy over the size information.  */
2659
0
        copy_symbol_attributes (symp2, symp);
2660
2661
0
        S_SET_OTHER (symp2, S_GET_OTHER (symp));
2662
2663
0
        if (S_IS_WEAK (symp))
2664
0
    S_SET_WEAK (symp2);
2665
2666
0
        if (S_IS_EXTERNAL (symp))
2667
0
    S_SET_EXTERNAL (symp2);
2668
0
      }
2669
2670
0
    switch (sy_obj->visibility)
2671
0
      {
2672
0
      case visibility_unchanged:
2673
0
        break;
2674
0
      case visibility_hidden:
2675
0
        bfdsym = symbol_get_bfdsym (symp);
2676
0
        elfsym = elf_symbol_from (bfdsym);
2677
0
        elfsym->internal_elf_sym.st_other &= ~3;
2678
0
        elfsym->internal_elf_sym.st_other |= STV_HIDDEN;
2679
0
        break;
2680
0
      case visibility_remove:
2681
        /* Don't remove the symbol if it is used in relocation.
2682
     Instead, mark it as to be removed and issue an error
2683
     if the symbol has more than one versioned name.  */
2684
0
        if (symbol_used_in_reloc_p (symp))
2685
0
    {
2686
0
      if (sy_obj->versioned_name->next != NULL)
2687
0
        as_bad (_("symbol '%s' with multiple versions cannot be used in relocation"),
2688
0
          S_GET_NAME (symp));
2689
0
      symbol_mark_removed (symp);
2690
0
    }
2691
0
        else
2692
0
    symbol_remove (symp, &symbol_rootP, &symbol_lastP);
2693
0
        break;
2694
0
      case visibility_local:
2695
0
        S_CLEAR_EXTERNAL (symp);
2696
0
        break;
2697
0
      }
2698
0
  }
2699
0
    }
2700
2701
  /* Double check weak symbols.  */
2702
0
  if (S_IS_WEAK (symp))
2703
0
    {
2704
0
      if (S_IS_COMMON (symp))
2705
0
  as_bad (_("symbol `%s' can not be both weak and common"),
2706
0
    S_GET_NAME (symp));
2707
0
    }
2708
0
}
2709
2710
/* Fix up SYMPP which has been marked to be removed by .symver.  */
2711
2712
void
2713
elf_fixup_removed_symbol (symbolS **sympp)
2714
0
{
2715
0
  symbolS *symp = *sympp;
2716
0
  struct elf_obj_sy *sy_obj = symbol_get_obj (symp);
2717
2718
  /* Replace the removed symbol with the versioned symbol.  */
2719
0
  symp = symbol_find (sy_obj->versioned_name->name);
2720
0
  *sympp = symp;
2721
0
}
2722
2723
/* Create symbols for group signature.  */
2724
2725
void
2726
elf_adjust_symtab (void)
2727
0
{
2728
0
  unsigned int i;
2729
2730
  /* Make the SHT_GROUP sections that describe each section group.  We
2731
     can't set up the section contents here yet, because elf section
2732
     indices have yet to be calculated.  elf.c:set_group_contents does
2733
     the rest of the work.  */
2734
0
 for (i = 0; i < groups.num_group; i++)
2735
0
    {
2736
0
      const char *group_name = elf_group_name (groups.head[i]);
2737
0
      const char *sec_name;
2738
0
      asection *s;
2739
0
      flagword flags;
2740
0
      struct symbol *sy;
2741
2742
0
      flags = SEC_READONLY | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_GROUP;
2743
0
      for (s = groups.head[i]; s != NULL; s = elf_next_in_group (s))
2744
0
  if ((s->flags ^ flags) & SEC_LINK_ONCE)
2745
0
    {
2746
0
      flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
2747
0
      if (s != groups.head[i])
2748
0
        {
2749
0
    as_warn (_("assuming all members of group `%s' are COMDAT"),
2750
0
       group_name);
2751
0
    break;
2752
0
        }
2753
0
    }
2754
2755
0
      sec_name = ".group";
2756
0
      s = subseg_force_new (sec_name, 0);
2757
0
      if (s == NULL
2758
0
    || !bfd_set_section_flags (s, flags)
2759
0
    || !bfd_set_section_alignment (s, 2))
2760
0
  {
2761
0
    as_fatal (_("can't create group: %s"),
2762
0
        bfd_errmsg (bfd_get_error ()));
2763
0
  }
2764
0
      elf_section_type (s) = SHT_GROUP;
2765
2766
      /* Pass a pointer to the first section in this group.  */
2767
0
      elf_next_in_group (s) = groups.head[i];
2768
0
      elf_sec_group (groups.head[i]) = s;
2769
      /* Make sure that the signature symbol for the group has the
2770
   name of the group.  */
2771
0
      sy = symbol_find_exact (group_name);
2772
0
      if (!sy || !symbol_on_chain (sy, symbol_rootP, symbol_lastP))
2773
0
  {
2774
    /* Create the symbol now.  */
2775
0
    sy = symbol_new (group_name, now_seg, frag_now, 0);
2776
#ifdef TE_SOLARIS
2777
    /* Before Solaris 11 build 154, Sun ld rejects local group
2778
       signature symbols, so make them weak hidden instead.  */
2779
    symbol_get_bfdsym (sy)->flags |= BSF_WEAK;
2780
    S_SET_OTHER (sy, STV_HIDDEN);
2781
#else
2782
0
    symbol_get_obj (sy)->local = 1;
2783
0
#endif
2784
0
    symbol_table_insert (sy);
2785
0
  }
2786
0
      elf_group_id (s) = symbol_get_bfdsym (sy);
2787
      /* Mark the group signature symbol as used so that it will be
2788
   included in the symbol table.  */
2789
0
      symbol_mark_used_in_reloc (sy);
2790
0
    }
2791
0
}
2792
2793
void
2794
elf_frob_file (void)
2795
0
{
2796
0
  bfd_map_over_sections (stdoutput, set_additional_section_info, NULL);
2797
2798
#ifdef elf_tc_final_processing
2799
  elf_tc_final_processing ();
2800
#endif
2801
0
}
2802
2803
/* It removes any unneeded versioned symbols from the symbol table.  */
2804
2805
void
2806
elf_frob_file_before_adjust (void)
2807
0
{
2808
0
  if (symbol_rootP)
2809
0
    {
2810
0
      symbolS *symp;
2811
2812
0
      for (symp = symbol_rootP; symp; symp = symbol_next (symp))
2813
0
  {
2814
0
    struct elf_obj_sy *sy_obj = symbol_get_obj (symp);
2815
0
    int is_defined = !!S_IS_DEFINED (symp);
2816
2817
0
    if (sy_obj->versioned_name)
2818
0
      {
2819
0
        char *p = strchr (sy_obj->versioned_name->name,
2820
0
        ELF_VER_CHR);
2821
2822
        /* NB: Malformed versioned symbols may not have @@@.  */
2823
0
        if (sy_obj->rename
2824
0
      && p[1] == ELF_VER_CHR
2825
0
      && p[2] == ELF_VER_CHR)
2826
0
    {
2827
      /* The @@@ syntax is a special case. If the symbol is
2828
         not defined, 2 `@'s will be removed from the
2829
         versioned_name. Otherwise, 1 `@' will be removed.   */
2830
0
      size_t l = strlen (&p[3]) + 1;
2831
0
      memmove (&p[1 + is_defined], &p[3], l);
2832
0
    }
2833
2834
0
        if (!is_defined)
2835
0
    {
2836
      /* Verify that the name isn't using the @@ syntax--this
2837
         is reserved for definitions of the default version
2838
         to link against.  */
2839
0
      if (!sy_obj->rename && p[1] == ELF_VER_CHR)
2840
0
        {
2841
0
          as_bad (_("invalid attempt to declare external "
2842
0
        "version name as default in symbol `%s'"),
2843
0
            sy_obj->versioned_name->name);
2844
0
          return;
2845
0
        }
2846
2847
      /* Only one version symbol is allowed for undefined
2848
         symbol.  */
2849
0
      if (sy_obj->versioned_name->next)
2850
0
        {
2851
0
          as_bad (_("multiple versions [`%s'|`%s'] for "
2852
0
        "symbol `%s'"),
2853
0
            sy_obj->versioned_name->name,
2854
0
            sy_obj->versioned_name->next->name,
2855
0
            S_GET_NAME (symp));
2856
0
          return;
2857
0
        }
2858
2859
0
      sy_obj->rename = true;
2860
0
    }
2861
0
      }
2862
2863
    /* If there was .symver or .weak, but symbol was neither
2864
       defined nor used anywhere, remove it.  */
2865
0
    if (!is_defined
2866
0
        && (sy_obj->versioned_name || S_IS_WEAK (symp))
2867
0
        && symbol_used_p (symp) == 0
2868
0
        && symbol_used_in_reloc_p (symp) == 0)
2869
0
      symbol_remove (symp, &symbol_rootP, &symbol_lastP);
2870
0
  }
2871
0
    }
2872
0
}
2873
2874
/* It is required that we let write_relocs have the opportunity to
2875
   optimize away fixups before output has begun, since it is possible
2876
   to eliminate all fixups for a section and thus we never should
2877
   have generated the relocation section.  */
2878
2879
void
2880
elf_frob_file_after_relocs (void)
2881
0
{
2882
0
  unsigned int i;
2883
2884
  /* Set SHT_GROUP section size.  */
2885
0
  for (i = 0; i < groups.num_group; i++)
2886
0
    {
2887
0
      asection *s, *head, *group;
2888
0
      bfd_size_type size;
2889
2890
0
      head = groups.head[i];
2891
0
      size = 4;
2892
0
      for (s = head; s != NULL; s = elf_next_in_group (s))
2893
0
  size += (s->flags & SEC_RELOC) != 0 ? 8 : 4;
2894
2895
0
      group = elf_sec_group (head);
2896
0
      subseg_set (group, 0);
2897
0
      bfd_set_section_size (group, size);
2898
0
      group->contents = (unsigned char *) frag_more (size);
2899
0
      group->alloced = 1;
2900
0
      frag_now->fr_fix = frag_now_fix_octets ();
2901
0
      frag_wane (frag_now);
2902
0
    }
2903
2904
#ifdef NEED_ECOFF_DEBUG
2905
  if (ECOFF_DEBUGGING)
2906
    /* Generate the ECOFF debugging information.  */
2907
    {
2908
      const struct ecoff_debug_swap *debug_swap;
2909
      struct ecoff_debug_info debug;
2910
      char *buf;
2911
      asection *sec;
2912
2913
      debug_swap
2914
  = get_elf_backend_data (stdoutput)->elf_backend_ecoff_debug_swap;
2915
      know (debug_swap != NULL);
2916
      ecoff_build_debug (&debug.symbolic_header, &buf, debug_swap);
2917
2918
      /* Set up the pointers in debug.  */
2919
      debug.alloc_syments = true;
2920
#define SET(ptr, offset, type) \
2921
    debug.ptr = (type) (buf + debug.symbolic_header.offset)
2922
2923
      SET (line, cbLineOffset, unsigned char *);
2924
      SET (external_dnr, cbDnOffset, void *);
2925
      SET (external_pdr, cbPdOffset, void *);
2926
      SET (external_sym, cbSymOffset, void *);
2927
      SET (external_opt, cbOptOffset, void *);
2928
      SET (external_aux, cbAuxOffset, union aux_ext *);
2929
      SET (ss, cbSsOffset, char *);
2930
      SET (external_fdr, cbFdOffset, void *);
2931
      SET (external_rfd, cbRfdOffset, void *);
2932
      /* ssext and external_ext are set up just below.  */
2933
2934
#undef SET
2935
2936
      /* Set up the external symbols.  */
2937
      debug.ssext = debug.ssext_end = NULL;
2938
      debug.external_ext = debug.external_ext_end = NULL;
2939
      if (! bfd_ecoff_debug_externals (stdoutput, &debug, debug_swap, true,
2940
               elf_get_extr, elf_set_index))
2941
  as_fatal (_("failed to set up debugging information: %s"),
2942
      bfd_errmsg (bfd_get_error ()));
2943
2944
      sec = bfd_get_section_by_name (stdoutput, ".mdebug");
2945
      gas_assert (sec != NULL);
2946
2947
      know (!stdoutput->output_has_begun);
2948
2949
      /* We set the size of the section, call bfd_set_section_contents
2950
   to force the ELF backend to allocate a file position, and then
2951
   write out the data.  FIXME: Is this really the best way to do
2952
   this?  */
2953
      bfd_set_section_size (sec, bfd_ecoff_debug_size (stdoutput, &debug,
2954
                   debug_swap));
2955
2956
      /* Pass BUF to bfd_set_section_contents because this will
2957
   eventually become a call to fwrite, and ISO C prohibits
2958
   passing a NULL pointer to a stdio function even if the
2959
   pointer will not be used.  */
2960
      if (! bfd_set_section_contents (stdoutput, sec, buf, 0, 0))
2961
  as_fatal (_("can't start writing .mdebug section: %s"),
2962
      bfd_errmsg (bfd_get_error ()));
2963
2964
      know (stdoutput->output_has_begun);
2965
      know (sec->filepos != 0);
2966
2967
      if (! bfd_ecoff_write_debug (stdoutput, &debug, debug_swap,
2968
           sec->filepos))
2969
  as_fatal (_("could not write .mdebug section: %s"),
2970
      bfd_errmsg (bfd_get_error ()));
2971
    }
2972
#endif /* NEED_ECOFF_DEBUG */
2973
0
}
2974
2975
/* This is called when the assembler starts.  */
2976
2977
void
2978
elf_begin (void)
2979
567
{
2980
567
  asection *s;
2981
2982
  /* Add symbols for the known sections to the symbol table.  */
2983
567
  s = bfd_get_section_by_name (stdoutput, TEXT_SECTION_NAME);
2984
567
  symbol_table_insert (section_symbol (s));
2985
567
  s = bfd_get_section_by_name (stdoutput, DATA_SECTION_NAME);
2986
567
  symbol_table_insert (section_symbol (s));
2987
567
  s = bfd_get_section_by_name (stdoutput, BSS_SECTION_NAME);
2988
567
  symbol_table_insert (section_symbol (s));
2989
567
  elf_com_section_ptr = bfd_com_section_ptr;
2990
567
  previous_section = NULL;
2991
567
  previous_subsection = 0;
2992
567
  comment_section = NULL;
2993
567
  memset (&groups, 0, sizeof (groups));
2994
2995
#ifdef TC_OBJ_ATTR
2996
  /* Set the object attribute version for the output object to the default
2997
     value supported by the backend.  */
2998
  elf_obj_attr_version (stdoutput)
2999
    = get_elf_backend_data (stdoutput)->default_obj_attr_version;
3000
3001
#if TC_OBJ_ATTR_v1
3002
  oav1_attr_info_init ();
3003
#endif /* TC_OBJ_ATTR_v1 */
3004
#endif /* TC_OBJ_ATTR */
3005
567
}
3006
3007
void
3008
elf_end (void)
3009
567
{
3010
567
  if (!ENABLE_LEAK_CHECK)
3011
0
    return;
3012
567
  while (section_stack)
3013
0
    {
3014
0
      struct section_stack *top = section_stack;
3015
0
      section_stack = top->next;
3016
0
      free (top);
3017
0
    }
3018
567
  if (groups.indexes)
3019
9
    {
3020
9
      htab_delete (groups.indexes);
3021
9
      free (groups.head);
3022
9
    }
3023
3024
#if TC_OBJ_ATTR_v1
3025
  oav1_attr_info_exit ();
3026
#endif /* TC_OBJ_ATTR_v1 */
3027
567
}
3028
3029
#ifdef USE_EMULATIONS
3030
3031
static bfd_vma
3032
elf_s_get_size (symbolS *sym)
3033
{
3034
  return S_GET_SIZE (sym);
3035
}
3036
3037
static void
3038
elf_s_set_size (symbolS *sym, bfd_vma sz)
3039
{
3040
  S_SET_SIZE (sym, sz);
3041
}
3042
3043
static bfd_vma
3044
elf_s_get_align (symbolS *sym)
3045
{
3046
  return S_GET_ALIGN (sym);
3047
}
3048
3049
static void
3050
elf_s_set_align (symbolS *sym, bfd_vma align)
3051
{
3052
  S_SET_ALIGN (sym, align);
3053
}
3054
3055
int
3056
elf_s_get_other (symbolS *sym)
3057
{
3058
  return elf_symbol (symbol_get_bfdsym (sym))->internal_elf_sym.st_other;
3059
}
3060
3061
static void
3062
elf_s_set_other (symbolS *sym, int other)
3063
{
3064
  S_SET_OTHER (sym, other);
3065
}
3066
3067
static int
3068
elf_sec_sym_ok_for_reloc (asection *sec)
3069
{
3070
  return obj_sec_sym_ok_for_reloc (sec);
3071
}
3072
3073
#ifdef NEED_ECOFF_DEBUG
3074
static void
3075
elf_process_stab (int what ATTRIBUTE_UNUSED,
3076
      const char *string ATTRIBUTE_UNUSED,
3077
      int type ATTRIBUTE_UNUSED,
3078
      int other ATTRIBUTE_UNUSED,
3079
      int desc ATTRIBUTE_UNUSED)
3080
{
3081
  if (ECOFF_DEBUGGING)
3082
    ecoff_stab (what, string, type, other, desc);
3083
}
3084
#else
3085
# define elf_process_stab NULL
3086
#endif
3087
3088
static int
3089
elf_separate_stab_sections (void)
3090
{
3091
#ifdef NEED_ECOFF_DEBUG
3092
  return (!ECOFF_DEBUGGING);
3093
#else
3094
  return 1;
3095
#endif
3096
}
3097
3098
#ifdef NEED_ECOFF_DEBUG
3099
static void
3100
elf_init_stab_section (segT stab, segT stabstr)
3101
{
3102
  if (!ECOFF_DEBUGGING)
3103
    obj_elf_init_stab_section (stab, stabstr);
3104
}
3105
#endif
3106
3107
const struct format_ops elf_format_ops =
3108
{
3109
  bfd_target_elf_flavour,
3110
  0,  /* dfl_leading_underscore */
3111
  1,  /* emit_section_symbols */
3112
  elf_begin,
3113
  elf_end,
3114
  elf_file_symbol,
3115
  NULL, /* assign_symbol */
3116
  elf_frob_symbol,
3117
  elf_frob_file,
3118
  elf_frob_file_before_adjust,
3119
  0,  /* obj_frob_file_before_fix */
3120
  elf_frob_file_after_relocs,
3121
  elf_s_get_size, elf_s_set_size,
3122
  elf_s_get_align, elf_s_set_align,
3123
  elf_s_get_other,
3124
  elf_s_set_other,
3125
  0,  /* s_get_desc */
3126
  0,  /* s_set_desc */
3127
  0,  /* s_get_type */
3128
  0,  /* s_set_type */
3129
  elf_copy_symbol_attributes,
3130
  elf_process_stab,
3131
  elf_separate_stab_sections,
3132
#ifdef NEED_ECOFF_DEBUG
3133
  elf_init_stab_section,
3134
#else
3135
  obj_elf_init_stab_section,
3136
#endif
3137
  elf_sec_sym_ok_for_reloc,
3138
  elf_pop_insert,
3139
#ifdef NEED_ECOFF_DEBUG
3140
  elf_ecoff_set_ext,
3141
#else
3142
  0,  /* ecoff_set_ext */
3143
#endif
3144
  elf_obj_read_begin_hook,
3145
  elf_obj_symbol_new_hook,
3146
  0,
3147
  elf_adjust_symtab
3148
};
3149
3150
#endif /* USE_EMULATIONS */