Coverage Report

Created: 2023-08-28 06:31

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