Coverage Report

Created: 2023-06-29 07:09

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