Coverage Report

Created: 2026-07-25 10:20

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