Coverage Report

Created: 2026-05-11 07:54

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