Coverage Report

Created: 2026-09-14 08:07

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
339
#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
339
{
197
339
  pop_insert (elf_pseudo_table);
198
339
  if (ECOFF_DEBUGGING)
199
0
    pop_insert (ecoff_debug_pseudo_table);
200
339
}
201
202
void
203
elf_file_symbol (const char *s)
204
33
{
205
33
  asymbol *bsym;
206
33
  symbolS *sym = symbol_new (s, absolute_section, &zero_address_frag, 0);
207
33
  size_t name_length = strlen (s);
208
209
33
  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
33
  else
215
33
    strcpy ((char *) S_GET_NAME (sym), s);
216
217
33
  symbol_get_bfdsym (sym)->flags |= BSF_FILE;
218
219
33
  if (symbol_rootP != sym
220
33
      && ((bsym = symbol_get_bfdsym (symbol_rootP)) == NULL
221
33
    || (bsym->flags & BSF_FILE) == 0))
222
21
    {
223
21
      symbol_remove (sym, &symbol_rootP, &symbol_lastP);
224
21
      symbol_insert (sym, symbol_rootP, &symbol_rootP, &symbol_lastP);
225
21
    }
226
227
#ifdef DEBUG
228
  verify_symbol_chain (symbol_rootP, symbol_lastP);
229
#endif
230
231
#ifdef NEED_ECOFF_DEBUG
232
  ecoff_new_file (s);
233
#endif
234
33
}
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
26.0k
{
242
26.0k
  addressT align = 0;
243
26.0k
  int is_local = symbol_get_obj (symbolP)->local;
244
245
26.0k
  if (*input_line_pointer == ',')
246
136
    {
247
136
      char *save = input_line_pointer;
248
249
136
      input_line_pointer++;
250
136
      SKIP_WHITESPACE ();
251
252
136
      if (*input_line_pointer == '"')
253
1
  {
254
    /* For sparc.  Accept .common symbol, length, "bss"  */
255
1
    input_line_pointer++;
256
    /* Some use the dot, some don't.  */
257
1
    if (*input_line_pointer == '.')
258
0
      input_line_pointer++;
259
    /* Some say data, some say bss.  */
260
1
    if (startswith (input_line_pointer, "bss\""))
261
0
      input_line_pointer += 4;
262
1
    else if (startswith (input_line_pointer, "data\""))
263
0
      input_line_pointer += 5;
264
1
    else
265
1
      {
266
1
        char *p = input_line_pointer;
267
1
        char c;
268
269
1
        while (*--p != '"')
270
0
    ;
271
4
        while (!is_end_of_stmt (*input_line_pointer))
272
3
    if (*input_line_pointer++ == '"')
273
0
      break;
274
1
        c = *input_line_pointer;
275
1
        *input_line_pointer = '\0';
276
1
        as_bad (_("bad .common segment %s"), p);
277
1
        *input_line_pointer = c;
278
1
        return NULL;
279
1
      }
280
    /* ??? Don't ask me why these are always global.  */
281
0
    is_local = 0;
282
0
  }
283
135
      else
284
135
  {
285
135
    input_line_pointer = save;
286
135
    align = parse_align (is_local);
287
135
    if (align == (addressT) -1)
288
5
      return NULL;
289
135
  }
290
136
    }
291
292
26.0k
  if (is_local)
293
1
    {
294
1
      bss_alloc (symbolP, size, align);
295
1
      S_CLEAR_EXTERNAL (symbolP);
296
1
    }
297
26.0k
  else
298
26.0k
    {
299
26.0k
      S_SET_VALUE (symbolP, size);
300
26.0k
      S_SET_ALIGN (symbolP, align);
301
26.0k
      S_SET_EXTERNAL (symbolP);
302
26.0k
      S_SET_SEGMENT (symbolP, elf_com_section_ptr);
303
26.0k
    }
304
305
26.0k
  symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
306
307
26.0k
  return symbolP;
308
26.0k
}
309
310
void
311
obj_elf_common (int is_common)
312
26.1k
{
313
26.1k
  if (flag_mri && is_common)
314
1
    s_mri_common (0);
315
26.1k
  else
316
26.1k
    s_comm_internal (0, elf_common_parse);
317
26.1k
}
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
149
{
331
149
  symbolS *symbolP = s_comm_internal (0, s_lcomm_internal);
332
333
149
  if (symbolP)
334
4
    symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
335
149
}
336
337
static symbolS *
338
get_sym_from_input_line_and_check (void)
339
342
{
340
342
  char *name;
341
342
  char c;
342
342
  symbolS *sym;
343
344
342
  c = get_symbol_name (& name);
345
342
  sym = symbol_find_or_make (name);
346
342
  restore_line_pointer (c);
347
342
  SKIP_WHITESPACE ();
348
349
  /* There is no symbol name if input_line_pointer has not moved.  */
350
342
  if (name == input_line_pointer)
351
169
    as_bad (_("Missing symbol name in directive"));
352
342
  return sym;
353
342
}
354
355
static void
356
obj_elf_local (int ignore ATTRIBUTE_UNUSED)
357
6
{
358
6
  int c;
359
6
  symbolS *symbolP;
360
361
6
  do
362
18
    {
363
18
      symbolP = get_sym_from_input_line_and_check ();
364
18
      c = *input_line_pointer;
365
18
      S_CLEAR_EXTERNAL (symbolP);
366
18
      symbol_get_obj (symbolP)->local = 1;
367
18
      if (c == ',')
368
12
  {
369
12
    input_line_pointer++;
370
12
    SKIP_WHITESPACE ();
371
12
    if (*input_line_pointer == '\n')
372
0
      c = '\n';
373
12
  }
374
18
    }
375
18
  while (c == ',');
376
6
  demand_empty_rest_of_line ();
377
6
}
378
379
static void
380
obj_elf_weak (int ignore ATTRIBUTE_UNUSED)
381
9
{
382
9
  int c;
383
9
  symbolS *symbolP;
384
385
9
  do
386
12
    {
387
12
      symbolP = get_sym_from_input_line_and_check ();
388
12
      c = *input_line_pointer;
389
12
      S_SET_WEAK (symbolP);
390
12
      if (c == ',')
391
3
  {
392
3
    input_line_pointer++;
393
3
    SKIP_WHITESPACE ();
394
3
    if (*input_line_pointer == '\n')
395
0
      c = '\n';
396
3
  }
397
12
    }
398
12
  while (c == ',');
399
9
  demand_empty_rest_of_line ();
400
9
}
401
402
static void
403
obj_elf_visibility (int visibility)
404
3
{
405
3
  int c;
406
407
3
  do
408
3
    {
409
3
      symbolS *symbolP = get_sym_from_input_line_and_check ();
410
3
      const asymbol *bfdsym = symbol_get_bfdsym (symbolP);
411
3
      elf_symbol_type *elfsym = elf_symbol_from (bfdsym);
412
3
      int current = ELF_ST_VISIBILITY (elfsym->internal_elf_sym.st_other);
413
414
3
      gas_assert (elfsym);
415
416
3
      if (!current || visibility <= current)
417
3
  {
418
3
    elfsym->internal_elf_sym.st_other &= ~ELF_ST_VISIBILITY (~0);
419
3
    elfsym->internal_elf_sym.st_other |= visibility;
420
3
  }
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
3
      c = *input_line_pointer;
426
3
      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
3
    }
436
3
  while (c == ',');
437
438
3
  demand_empty_rest_of_line ();
439
3
}
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
54.5k
#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
54.5k
{
468
54.5k
  const char *linked_to_symbol_name = sec->map_head.linked_to_symbol_name;
469
54.5k
  unsigned int sh_info = elf_section_data (sec)->this_hdr.sh_info;
470
54.5k
  bfd_vma sh_flags = (elf_section_data (sec)->this_hdr.sh_flags
471
54.5k
          & SEC_ASSEMBLER_SHF_MASK);
472
473
54.5k
  return (sh_info == match->sh_info
474
54.4k
    && sh_flags == match->sh_flags
475
42.1k
    && ((bfd_section_flags (sec) & SEC_ASSEMBLER_SECTION_ID)
476
42.1k
         == (match->flags & SEC_ASSEMBLER_SECTION_ID))
477
42.1k
    && sec->section_id == match->section_id
478
42.1k
    && (linked_to_symbol_name == match->linked_to_symbol_name
479
11.9k
        || (linked_to_symbol_name != NULL
480
11.7k
      && match->linked_to_symbol_name != NULL
481
9
      && strcmp (linked_to_symbol_name,
482
9
           match->linked_to_symbol_name) == 0)));
483
54.5k
}
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
54.5k
{
490
54.5k
  struct elf_section_match *match = inf;
491
54.5k
  const char *gname = match->group_name;
492
54.5k
  const char *group_name = elf_group_name (sec);
493
494
54.5k
  return ((group_name == gname
495
58
     || (group_name != NULL
496
58
         && gname != NULL
497
0
         && strcmp (group_name, gname) == 0))
498
54.4k
    && match_section (sec, match));
499
54.5k
}
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
55
{
510
55
  if (!groups.indexes)
511
16
    {
512
16
      groups.num_group = 0;
513
16
      groups.head = NULL;
514
16
      groups.indexes = htab_create_alloc (16, hash_string_tuple, eq_string_tuple,
515
16
            NULL, notes_calloc, NULL);
516
16
      *group_idx = ~0u;
517
16
      return NULL;
518
16
    }
519
520
39
  *group_idx = str_hash_find_int (groups.indexes, match->group_name);
521
39
  if (*group_idx == ~0u)
522
11
    return NULL;
523
524
28
  asection *s;
525
54
  for (s = groups.head[*group_idx]; s != NULL; s = elf_next_in_group (s))
526
47
    if ((s->name == sec_name
527
47
   || strcmp (s->name, sec_name) == 0)
528
24
  && match_section (s, match))
529
21
      break;
530
28
  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
34
{
541
34
  if (*group_idx != ~0u)
542
7
    {
543
7
      elf_next_in_group (sec) = groups.head[*group_idx];
544
7
      groups.head[*group_idx] = sec;
545
7
      return;
546
7
    }
547
548
27
  unsigned int i = groups.num_group;
549
27
  if ((i & 127) == 0)
550
16
    groups.head = XRESIZEVEC (asection *, groups.head, i + 128);
551
27
  groups.head[i] = sec;
552
27
  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
27
  str_hash_insert_int (groups.indexes, match->group_name, i, 0);
557
27
}
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
31.3k
{
587
31.3k
  asection *old_sec;
588
31.3k
  segT sec;
589
31.3k
  flagword flags;
590
31.3k
  const struct bfd_elf_special_section *ssect;
591
592
31.3k
  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
31.3k
  if (push)
604
1
    {
605
1
      struct section_stack *elt;
606
1
      elt = XNEW (struct section_stack);
607
1
      elt->next = section_stack;
608
1
      elt->seg = now_seg;
609
1
      elt->prev_seg = previous_section;
610
1
      elt->subseg = now_subseg;
611
1
      elt->prev_subseg = previous_subsection;
612
1
      section_stack = elt;
613
1
    }
614
615
31.3k
  obj_elf_section_change_hook ();
616
617
31.3k
  unsigned int group_idx = ~0u;
618
31.3k
  if (match_p->group_name)
619
42
    old_sec = group_section_find (match_p, name, &group_idx);
620
31.3k
  else
621
31.3k
    old_sec = bfd_get_section_by_name_if (stdoutput, name, get_section_by_match,
622
31.3k
            match_p);
623
31.3k
  if (old_sec)
624
30.2k
    {
625
30.2k
      sec = old_sec;
626
30.2k
      subseg_set (sec, new_subsection);
627
30.2k
    }
628
1.13k
  else
629
1.13k
    {
630
1.13k
      sec = subseg_force_new (name, new_subsection);
631
1.13k
      if (match_p->group_name)
632
25
  group_section_insert (match_p, sec, &group_idx);
633
1.13k
    }
634
635
31.3k
  elf_backend_data *bed = get_elf_backend_data (stdoutput);
636
31.3k
  ssect = (*bed->get_sec_type_attr) (stdoutput, sec);
637
638
31.3k
  if (ssect != NULL)
639
27
    {
640
27
      bool override = false;
641
642
27
      if (type == SHT_NULL)
643
15
  type = ssect->type;
644
12
      else if (type != ssect->type)
645
11
  {
646
11
    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
9
#ifdef TC_I386
659
9
        && (bed->s->arch_size != 64
660
9
      || !(ssect->attr & SHF_X86_64_LARGE))
661
9
#endif
662
9
        && ssect->type != SHT_INIT_ARRAY
663
9
        && ssect->type != SHT_FINI_ARRAY
664
9
        && ssect->type != SHT_PREINIT_ARRAY)
665
9
      {
666
        /* We allow to specify any type for a .note section.  */
667
9
        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
9
      }
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
11
  }
680
681
27
      if (old_sec == NULL && ((attr & ~(SHF_LINK_ORDER
682
23
          | SHF_MASKOS
683
23
          | SHF_MASKPROC))
684
23
            & ~ssect->attr) != 0)
685
3
  {
686
    /* Strip SHF_GNU_RETAIN.  */
687
3
    bfd_vma generic_attr = attr;
688
3
    if (elf_tdata (stdoutput)->has_gnu_osabi)
689
1
      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
3
    if (ssect->type == SHT_NOTE
696
2
        && (generic_attr == SHF_ALLOC
697
2
      || generic_attr == SHF_EXECINSTR))
698
0
      ;
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
1
       && name[ssect->prefix_length] == '.'
703
1
       && (generic_attr
704
1
           & ~ssect->attr
705
1
           & ~SHF_MERGE
706
1
           & ~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
3
  }
739
740
27
      if (!override && old_sec == NULL)
741
20
  attr |= ssect->attr;
742
27
    }
743
744
  /* Convert ELF type and flags to BFD flags.  */
745
31.3k
  flags = (SEC_RELOC
746
31.3k
     | ((attr & SHF_WRITE) ? 0 : SEC_READONLY)
747
31.3k
     | ((attr & SHF_ALLOC) ? SEC_ALLOC : 0)
748
31.3k
     | (((attr & SHF_ALLOC) && type != SHT_NOBITS) ? SEC_LOAD : 0)
749
31.3k
     | ((attr & SHF_EXECINSTR) ? SEC_CODE : 0)
750
31.3k
     | ((attr & SHF_MERGE) ? SEC_MERGE : 0)
751
31.3k
     | ((attr & SHF_STRINGS) ? SEC_STRINGS : 0)
752
31.3k
     | ((attr & SHF_EXCLUDE) ? SEC_EXCLUDE: 0)
753
31.3k
     | ((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
31.3k
  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
31.3k
  if ((flags & SEC_ALLOC) == 0 && name [0] == '.')
767
661
    {
768
661
      if (   startswith (name, ".debug")
769
651
    || startswith (name, ".zdebug")
770
651
    || startswith (name, ".gnu.debuglto_.debug_")
771
651
    || startswith (name, ".gnu.linkonce.wi.")
772
651
    || startswith (name, GNU_BUILD_ATTRS_SECTION_NAME)
773
650
    || startswith (name, ".note.gnu"))
774
19
  flags |= SEC_ELF_OCTETS;
775
661
    }
776
777
31.3k
  if (old_sec == NULL)
778
1.13k
    {
779
1.13k
      if (type == SHT_NULL)
780
889
  type = bfd_elf_get_default_section_type (flags);
781
1.13k
      elf_section_type (sec) = type;
782
1.13k
      elf_section_flags (sec) = attr;
783
1.13k
      elf_section_data (sec)->this_hdr.sh_info = match_p->sh_info;
784
785
      /* Prevent SEC_HAS_CONTENTS from being inadvertently set.  */
786
1.13k
      if (type == SHT_NOBITS)
787
1
  seg_info (sec)->bss = 1;
788
789
      /* Set the section ID and flags.  */
790
1.13k
      sec->section_id = match_p->section_id;
791
1.13k
      flags |= match_p->flags;
792
793
      /* Set the linked-to symbol name.  */
794
1.13k
      sec->map_head.linked_to_symbol_name
795
1.13k
  = match_p->linked_to_symbol_name;
796
797
1.13k
      bfd_set_section_flags (sec, flags);
798
1.13k
      if (entsize != 0)
799
17
  sec->entsize = entsize;
800
1.13k
      elf_group_name (sec) = match_p->group_name;
801
802
      /* Add a symbol for this section to the symbol table.  */
803
1.13k
      symbol_table_insert (section_symbol (sec));
804
1.13k
    }
805
30.2k
  else
806
30.2k
    {
807
30.2k
      if (type != SHT_NULL
808
29.2k
    && (unsigned) type != elf_section_type (old_sec))
809
1
  {
810
1
    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
1
      as_warn (_("ignoring changed section type for %s"), name);
816
0
    else
817
      /* Do error when assembly isn't self-consistent.  */
818
0
      as_bad (_("changed section type for %s"), name);
819
1
  }
820
821
30.2k
      if (attr != 0)
822
29.1k
  {
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
29.1k
    if (((old_sec->flags ^ flags)
827
29.1k
         & (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
828
29.1k
      | SEC_EXCLUDE | SEC_SORT_ENTRIES | SEC_MERGE | SEC_STRINGS
829
29.1k
      | SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD
830
29.1k
      | SEC_THREAD_LOCAL)))
831
21
      {
832
21
        if (ssect != NULL)
833
0
    as_warn (_("ignoring changed section attributes for %s"), name);
834
21
        else
835
21
    as_bad (_("changed section attributes for %s"), name);
836
21
      }
837
29.1k
    else
838
      /* FIXME: Maybe we should consider removing a previously set
839
         processor or application specific attribute as suspicious?  */
840
29.1k
      elf_section_flags (sec) = attr;
841
842
29.1k
    if (entsize != 0
843
27
        && old_sec->entsize != (unsigned) entsize)
844
3
      as_bad (_("changed section entity size for %s"), name);
845
29.1k
  }
846
30.2k
    }
847
848
31.3k
#ifdef md_elf_section_change_hook
849
31.3k
  md_elf_section_change_hook ();
850
31.3k
#endif
851
31.3k
}
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
29.7k
{
869
29.7k
  bfd_vma attr = 0;
870
871
29.7k
  *is_clone = false;
872
29.7k
  *inherit = 0;
873
874
118k
  while (len > 0)
875
118k
    {
876
118k
      switch (*str)
877
118k
  {
878
16
  case 'a':
879
16
    attr |= SHF_ALLOC;
880
    /* Compatibility.  */
881
16
    if (len > 1 && str[1] == 'm')
882
8
      {
883
8
        attr |= SHF_MERGE;
884
8
        str++, len--;
885
8
        if (len > 1 && str[1] == 's')
886
0
    {
887
0
      attr |= SHF_STRINGS;
888
0
      str++, len--;
889
0
    }
890
8
      }
891
16
    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
5
  case 'e':
898
5
    attr |= SHF_EXCLUDE;
899
5
    break;
900
0
  case 'o':
901
0
    attr |= SHF_LINK_ORDER;
902
0
    break;
903
22
  case 'w':
904
22
    attr |= SHF_WRITE;
905
22
    break;
906
1
  case 'x':
907
1
    attr |= SHF_EXECINSTR;
908
1
    break;
909
10
  case 'E':
910
10
    *has_entsize = true;
911
10
    break;
912
0
  case 'G':
913
0
    attr |= SHF_GROUP;
914
0
    break;
915
3
  case 'M':
916
3
    attr |= SHF_MERGE;
917
3
    break;
918
8
  case 'R':
919
8
    if (gnu_attr == NULL)
920
0
      goto unrecognized;
921
8
    *gnu_attr |= SHF_GNU_RETAIN;
922
8
    break;
923
0
  case 'S':
924
0
    attr |= SHF_STRINGS;
925
0
    break;
926
3
  case 'T':
927
3
    attr |= SHF_TLS;
928
3
    break;
929
0
  case '?':
930
0
    *is_clone = true;
931
0
    break;
932
118k
  default:
933
118k
  unrecognized:
934
118k
    {
935
118k
      const char *md_extra = "";
936
937
118k
#ifdef md_elf_section_letter
938
118k
      bfd_vma md_attr = md_elf_section_letter (*str, &md_extra);
939
118k
      if (md_attr != (bfd_vma) -1)
940
0
        attr |= md_attr;
941
118k
      else
942
118k
#endif
943
118k
        if (ISDIGIT (*str))
944
59.2k
    {
945
59.2k
      char * end;
946
59.2k
      bfd_vma numeric_flags = strtoul (str, &end, 0);
947
948
59.2k
      attr |= numeric_flags;
949
950
59.2k
      if (gnu_attr != NULL)
951
59.2k
        {
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
59.2k
          *gnu_attr |= (numeric_flags & SHF_MASKOS);
961
59.2k
        }
962
963
      /* Update str and len, allowing for the fact that
964
         we will execute str++ and len-- below.  */
965
59.2k
      end --;
966
59.2k
      len -= (end - str);
967
59.2k
      str = end;
968
59.2k
    }
969
59.2k
        else if (!*inherit && !attr
970
29.6k
           && (gnu_attr == NULL || !*gnu_attr)
971
29.6k
           && (*str == '+' || *str == '-'))
972
29.5k
    *inherit = *str == '+' ? 1 : -1;
973
29.7k
        else
974
29.7k
    {
975
29.7k
      as_bad (_("unrecognized .%ssection attribute: want %s%s%s,? or number"),
976
29.7k
        push ? "push" : "",
977
29.7k
        gnu_attr != NULL ? "a,d,e,o,w,x,E,G,M,R,S,T"
978
29.7k
             : "a,e,o,w,x,E,G,M,S,T",
979
29.7k
        md_extra != NULL ? "," : "", md_extra);
980
29.7k
      return attr;
981
29.7k
    }
982
118k
    }
983
88.7k
    break;
984
118k
  }
985
88.8k
      str++, len--;
986
88.8k
    }
987
988
27
  return attr;
989
29.7k
}
990
991
static int
992
obj_elf_section_type (char *str, size_t len, bool warn)
993
11
{
994
11
  if (len == 8 && startswith (str, "progbits"))
995
0
    return SHT_PROGBITS;
996
11
  if (len == 6 && startswith (str, "nobits"))
997
0
    return SHT_NOBITS;
998
11
  if (len == 4 && startswith (str, "note"))
999
0
    return SHT_NOTE;
1000
11
  if (len == 10 && startswith (str, "init_array"))
1001
0
    return SHT_INIT_ARRAY;
1002
11
  if (len == 10 && startswith (str, "fini_array"))
1003
0
    return SHT_FINI_ARRAY;
1004
11
  if (len == 13 && startswith (str, "preinit_array"))
1005
0
    return SHT_PREINIT_ARRAY;
1006
1007
11
#ifdef md_elf_section_type
1008
11
  {
1009
11
    int md_type = md_elf_section_type (str, len);
1010
11
    if (md_type >= 0)
1011
2
      return md_type;
1012
11
  }
1013
9
#endif
1014
1015
9
  if (ISDIGIT (*str))
1016
1
    {
1017
1
      char * end;
1018
1
      int type = strtoul (str, & end, 0);
1019
1020
1
      if (warn && (size_t) (end - str) != len)
1021
0
  as_warn (_("extraneous characters at end of numeric section type"));
1022
1023
1
      return type;
1024
1
    }
1025
1026
8
  if (warn)
1027
8
    as_warn (_("unrecognized section type"));
1028
8
  return 0;
1029
9
}
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
31.5k
{
1062
31.5k
  char *name;
1063
1064
31.5k
  SKIP_WHITESPACE ();
1065
31.5k
  if (*input_line_pointer == '"')
1066
0
    {
1067
0
      int dummy;
1068
1069
0
      name = demand_copy_C_string (&dummy);
1070
0
      if (name == NULL)
1071
0
  {
1072
0
    ignore_rest_of_line ();
1073
0
    return NULL;
1074
0
  }
1075
0
    }
1076
31.5k
  else
1077
31.5k
    {
1078
31.5k
      char *end = input_line_pointer;
1079
1080
153k
      while (!is_whitespace (*end) && !is_end_of_stmt (*end) && *end != ',')
1081
122k
  end++;
1082
31.5k
      if (end == input_line_pointer)
1083
162
  {
1084
162
    as_bad (_("missing name"));
1085
162
    ignore_rest_of_line ();
1086
162
    return NULL;
1087
162
  }
1088
1089
31.4k
      obstack_grow0 (&notes, input_line_pointer, end - input_line_pointer);
1090
31.4k
      name = obstack_base (&notes);
1091
1092
31.4k
      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
31.4k
      obstack_finish (&notes);
1114
1115
#ifdef tc_canonicalize_section_name
1116
      name = tc_canonicalize_section_name (name);
1117
#endif
1118
31.4k
      input_line_pointer = end;
1119
31.4k
    }
1120
31.4k
  SKIP_WHITESPACE ();
1121
31.4k
  return name;
1122
31.5k
}
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
13
{
1130
13
  elf_group_name (sec) = gname;
1131
13
  elf_section_flags (sec) |= SHF_GROUP;
1132
1133
13
  struct elf_section_match match;
1134
13
  match.group_name = gname;
1135
13
  match.linked_to_symbol_name = sec->map_head.linked_to_symbol_name;
1136
13
  match.section_id = sec->section_id;
1137
13
  match.sh_info = elf_section_data (sec)->this_hdr.sh_info;
1138
13
  match.sh_flags = (elf_section_data (sec)->this_hdr.sh_flags
1139
13
        & SEC_ASSEMBLER_SHF_MASK);
1140
13
  match.flags = bfd_section_flags (sec) & SEC_ASSEMBLER_SECTION_ID;
1141
1142
13
  unsigned int group_idx;
1143
13
  if (!group_section_find (&match, sec->name, &group_idx))
1144
9
    group_section_insert (&match, sec, &group_idx);
1145
13
}
1146
1147
static void
1148
obj_elf_attach_to_group (int dummy ATTRIBUTE_UNUSED)
1149
28
{
1150
28
  const char * gname = obj_elf_section_name ();
1151
1152
28
  if (gname == NULL)
1153
0
    {
1154
0
      as_warn (_("group name not parseable"));
1155
0
      return;
1156
0
    }
1157
1158
28
  if (elf_group_name (now_seg))
1159
15
    {
1160
15
      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
15
      return;
1164
15
    }
1165
13
  elf_set_group_name (now_seg, gname);
1166
13
}
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
31.8k
{
1180
31.8k
  const char *name;
1181
31.8k
  char *beg;
1182
31.8k
  int type, dummy;
1183
31.8k
  bfd_vma attr;
1184
31.8k
  bfd_vma gnu_attr;
1185
31.8k
  int entsize;
1186
31.8k
  bool linkonce, has_entsize;
1187
31.8k
  subsegT new_subsection = 0;
1188
31.8k
  struct elf_section_match match;
1189
31.8k
  unsigned long linked_to_section_index = -1UL;
1190
1191
31.8k
  if (flag_mri)
1192
488
    {
1193
488
      char mri_type;
1194
1195
#ifdef md_flush_pending_output
1196
      md_flush_pending_output ();
1197
#endif
1198
1199
488
      obj_elf_section_change_hook ();
1200
1201
488
      s_mri_sect (&mri_type);
1202
1203
488
#ifdef md_elf_section_change_hook
1204
488
      md_elf_section_change_hook ();
1205
488
#endif
1206
1207
488
      return;
1208
488
    }
1209
1210
31.3k
  name = obj_elf_section_name ();
1211
31.3k
  if (name == NULL)
1212
2
    return;
1213
1214
31.3k
  memset (&match, 0, sizeof (match));
1215
1216
31.3k
  symbolS * sym;
1217
31.3k
  if ((sym = symbol_find (name)) != NULL
1218
30.4k
      && ! 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
31.3k
  type = SHT_NULL;
1228
31.3k
  attr = 0;
1229
31.3k
  gnu_attr = 0;
1230
31.3k
  entsize = 0;
1231
31.3k
  has_entsize = false;
1232
31.3k
  linkonce = 0;
1233
1234
31.3k
  if (*input_line_pointer == ',')
1235
30.0k
    {
1236
      /* Skip the comma.  */
1237
30.0k
      ++input_line_pointer;
1238
30.0k
      SKIP_WHITESPACE ();
1239
1240
30.0k
      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
30.0k
      if (*input_line_pointer == '"')
1257
29.7k
  {
1258
29.7k
    bool is_clone;
1259
29.7k
    int inherit;
1260
1261
29.7k
    beg = demand_copy_C_string (&dummy);
1262
29.7k
    if (beg == NULL)
1263
0
      {
1264
0
        ignore_rest_of_line ();
1265
0
        return;
1266
0
      }
1267
1268
29.7k
    elf_backend_data *bed = get_elf_backend_data (stdoutput);
1269
29.7k
    bool maybe_gnu = (bed->elf_osabi == ELFOSABI_NONE
1270
29.7k
          || bed->elf_osabi == ELFOSABI_GNU
1271
0
          || bed->elf_osabi == ELFOSABI_FREEBSD);
1272
29.7k
    attr = obj_elf_parse_section_letters (beg, strlen (beg), push,
1273
29.7k
            &is_clone, &inherit,
1274
29.7k
            maybe_gnu ? &gnu_attr : NULL,
1275
29.7k
            &has_entsize);
1276
1277
29.7k
    if (inherit > 0)
1278
29.5k
      attr |= elf_section_flags (now_seg);
1279
232
    else if (inherit < 0)
1280
11
      attr = elf_section_flags (now_seg) & ~attr;
1281
29.7k
    if (inherit)
1282
29.5k
      type = elf_section_type (now_seg);
1283
1284
29.7k
    if ((attr & (SHF_MERGE | SHF_STRINGS)) != 0)
1285
100
      has_entsize = true;
1286
1287
29.7k
    SKIP_WHITESPACE ();
1288
29.7k
    if (*input_line_pointer == ',')
1289
416
      {
1290
416
        char c;
1291
416
        char *save = input_line_pointer;
1292
1293
416
        ++input_line_pointer;
1294
416
        SKIP_WHITESPACE ();
1295
416
        c = *input_line_pointer;
1296
416
        if (c == '"')
1297
10
    {
1298
10
      beg = demand_copy_C_string (&dummy);
1299
10
      if (beg == NULL)
1300
0
        {
1301
0
          ignore_rest_of_line ();
1302
0
          return;
1303
0
        }
1304
10
      type = obj_elf_section_type (beg, strlen (beg), true);
1305
10
    }
1306
406
        else if (c == '@' || c == '%')
1307
1
    {
1308
1
      ++input_line_pointer;
1309
1310
1
      if (ISDIGIT (* input_line_pointer))
1311
0
        type = strtoul (input_line_pointer, &input_line_pointer, 0);
1312
1
      else
1313
1
        {
1314
1
          c = get_symbol_name (& beg);
1315
1
          (void) restore_line_pointer (c);
1316
1
          type = obj_elf_section_type (beg,
1317
1
               input_line_pointer - beg,
1318
1
               true);
1319
1
        }
1320
1
    }
1321
405
        else
1322
405
    input_line_pointer = save;
1323
416
      }
1324
1325
29.7k
    SKIP_WHITESPACE ();
1326
29.7k
    if (has_entsize && *input_line_pointer == ',')
1327
58
      {
1328
58
        ++input_line_pointer;
1329
58
        SKIP_WHITESPACE ();
1330
58
        if (inherit && *input_line_pointer == ','
1331
1
      && ((bfd_section_flags (now_seg)
1332
1
           & (SEC_MERGE | SEC_STRINGS)) != 0
1333
0
          || now_seg->entsize))
1334
1
    goto fetch_entsize;
1335
57
        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
57
        else
1349
57
    {
1350
57
      entsize = get_absolute_expression ();
1351
57
      SKIP_WHITESPACE ();
1352
57
      if (entsize <= 0)
1353
42
        {
1354
42
          as_warn (_("invalid section entity size"));
1355
42
          attr &= ~(SHF_MERGE | SHF_STRINGS);
1356
42
          has_entsize = false;
1357
42
          entsize = 0;
1358
42
        }
1359
57
    }
1360
57
      }
1361
29.6k
    else if (has_entsize && inherit
1362
32
        && ((bfd_section_flags (now_seg)
1363
32
       & (SEC_MERGE | SEC_STRINGS)) != 0
1364
18
      || now_seg->entsize))
1365
23
      {
1366
24
      fetch_entsize:
1367
24
        entsize = now_seg->entsize;
1368
24
      }
1369
29.6k
    else if ((attr & SHF_MERGE) != 0)
1370
17
      {
1371
        /* ??? Perhaps we should error here.  The manual says that
1372
     entsize must be specified if SHF_MERGE is set.  */
1373
17
        as_warn (_("entity size for SHF_MERGE not specified"));
1374
17
        attr &= ~(SHF_MERGE | SHF_STRINGS);
1375
17
        has_entsize = false;
1376
17
      }
1377
29.6k
    else if ((attr & SHF_STRINGS) != 0)
1378
7
      {
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
7
        entsize = 1;
1384
7
      }
1385
29.6k
    else if (has_entsize)
1386
0
      {
1387
0
        as_warn (_("entity size not specified"));
1388
0
        has_entsize = false;
1389
0
      }
1390
1391
29.7k
    if ((attr & (SHF_MERGE | SHF_STRINGS)) != 0 && type == SHT_NOBITS)
1392
8
      as_warn (_("bogus SHF_MERGE / SHF_STRINGS for SHT_NOBITS section"));
1393
1394
29.7k
    if ((attr & SHF_LINK_ORDER) != 0 && *input_line_pointer == ',')
1395
355
      {
1396
355
        ++input_line_pointer;
1397
355
        SKIP_WHITESPACE ();
1398
        /* Check for a numeric section index, rather than a symbol name.  */
1399
355
        if (ISDIGIT (* input_line_pointer))
1400
0
    {
1401
0
      linked_to_section_index = strtoul (input_line_pointer, & input_line_pointer, 0);
1402
0
    }
1403
355
        else if (inherit && *input_line_pointer == ','
1404
168
           && (elf_section_flags (now_seg) & SHF_LINK_ORDER) != 0)
1405
9
    goto fetch_linked_to;
1406
346
        else
1407
346
    {
1408
346
      char c;
1409
346
      unsigned int length;
1410
1411
346
      c = get_symbol_name (& beg);
1412
346
      (void) restore_line_pointer (c);
1413
346
      length = input_line_pointer - beg;
1414
346
      if (length)
1415
171
        match.linked_to_symbol_name
1416
171
          = notes_memdup (beg, length, length + 1);
1417
346
    }
1418
355
      }
1419
29.3k
    else if ((attr & SHF_LINK_ORDER) != 0 && inherit
1420
27
       && (elf_section_flags (now_seg) & SHF_LINK_ORDER) != 0)
1421
23
      {
1422
32
      fetch_linked_to:
1423
32
        if (now_seg->map_head.linked_to_symbol_name)
1424
12
    match.linked_to_symbol_name =
1425
12
      now_seg->map_head.linked_to_symbol_name;
1426
20
        else
1427
20
    linked_to_section_index =
1428
20
      elf_section_data (now_seg)->this_hdr.sh_link;
1429
32
      }
1430
1431
29.7k
    if ((attr & SHF_GROUP) != 0 && is_clone)
1432
0
      {
1433
0
        as_warn (_("? section flag ignored with G present"));
1434
0
        is_clone = false;
1435
0
      }
1436
1437
29.7k
    if ((attr & SHF_GROUP) != 0 && *input_line_pointer == ',')
1438
191
      {
1439
191
        ++input_line_pointer;
1440
191
        SKIP_WHITESPACE ();
1441
191
        if (inherit && *input_line_pointer == ','
1442
4
      && (elf_section_flags (now_seg) & SHF_GROUP) != 0)
1443
4
    goto fetch_group;
1444
187
        match.group_name = obj_elf_section_name ();
1445
187
        if (match.group_name == NULL)
1446
160
    attr &= ~SHF_GROUP;
1447
27
        else if (*input_line_pointer == ',')
1448
12
    {
1449
12
      ++input_line_pointer;
1450
12
      SKIP_WHITESPACE ();
1451
12
      if (startswith (input_line_pointer, "comdat"))
1452
0
        {
1453
0
          input_line_pointer += 6;
1454
0
          linkonce = 1;
1455
0
        }
1456
12
    }
1457
15
        else if (startswith (name, ".gnu.linkonce"))
1458
0
    linkonce = 1;
1459
187
      }
1460
29.5k
    else if ((attr & SHF_GROUP) != 0 && inherit
1461
176
       && (elf_section_flags (now_seg) & SHF_GROUP) != 0)
1462
11
      {
1463
15
      fetch_group:
1464
15
        match.group_name = elf_group_name (now_seg);
1465
15
        linkonce =
1466
15
          (bfd_section_flags (now_seg) & SEC_LINK_ONCE) != 0;
1467
15
      }
1468
29.5k
    else if ((attr & SHF_GROUP) != 0)
1469
173
      {
1470
173
        as_warn (_("group name for SHF_GROUP not specified"));
1471
173
        attr &= ~SHF_GROUP;
1472
173
      }
1473
1474
29.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
29.7k
    if ((gnu_attr & SHF_GNU_MBIND) != 0 && *input_line_pointer == ',')
1485
6
      {
1486
6
        char *save = input_line_pointer;
1487
6
        ++input_line_pointer;
1488
6
        SKIP_WHITESPACE ();
1489
6
        if (ISDIGIT (* input_line_pointer))
1490
4
    {
1491
4
      char *t = input_line_pointer;
1492
4
      match.sh_info = strtoul (input_line_pointer,
1493
4
          &input_line_pointer, 0);
1494
4
      if (match.sh_info == -1u)
1495
3
        {
1496
3
          as_warn (_("unsupported mbind section info: %s"), t);
1497
3
          match.sh_info = 0;
1498
3
        }
1499
4
    }
1500
2
        else
1501
2
    input_line_pointer = save;
1502
6
      }
1503
1504
29.7k
    if ((gnu_attr & SHF_GNU_RETAIN) != 0)
1505
207
      match.sh_flags |= SHF_GNU_RETAIN;
1506
1507
29.7k
    if (*input_line_pointer == ',')
1508
38
      {
1509
38
        char *save = input_line_pointer;
1510
1511
38
        ++input_line_pointer;
1512
38
        SKIP_WHITESPACE ();
1513
38
        if (startswith (input_line_pointer, "unique"))
1514
1
    {
1515
1
      input_line_pointer += 6;
1516
1
      SKIP_WHITESPACE ();
1517
1
      if (*input_line_pointer == ',')
1518
1
        {
1519
1
          ++input_line_pointer;
1520
1
          SKIP_WHITESPACE ();
1521
1
          if (ISDIGIT (* input_line_pointer))
1522
0
      {
1523
0
        bfd_vma id;
1524
0
        bool overflow;
1525
0
        char *t = input_line_pointer;
1526
0
        if (sizeof (bfd_vma) <= sizeof (unsigned long))
1527
0
          {
1528
0
            errno = 0;
1529
0
            id = strtoul (input_line_pointer,
1530
0
              &input_line_pointer, 0);
1531
0
            overflow = id == -1ul && errno == ERANGE;
1532
0
          }
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
0
        if (overflow || id > -1u)
1541
0
          {
1542
0
            char *linefeed, saved_char = 0;
1543
0
            if ((linefeed = strchr (t, '\n')) != NULL)
1544
0
        {
1545
0
          saved_char = *linefeed;
1546
0
          *linefeed = '\0';
1547
0
        }
1548
0
            as_bad (_("unsupported section id: %s"), t);
1549
0
            if (saved_char)
1550
0
        *linefeed = saved_char;
1551
0
          }
1552
0
        else
1553
0
          {
1554
0
            match.section_id = id;
1555
0
            match.flags |= SEC_ASSEMBLER_SECTION_ID;
1556
0
          }
1557
0
      }
1558
1
        }
1559
1
    }
1560
37
        else
1561
37
    input_line_pointer = save;
1562
38
      }
1563
29.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
30.0k
    }
1592
1593
31.3k
 done:
1594
31.3k
  demand_empty_rest_of_line ();
1595
1596
31.3k
  if ((gnu_attr & (SHF_GNU_MBIND | SHF_GNU_RETAIN)) != 0)
1597
231
    {
1598
231
      bool mbind_p = (gnu_attr & SHF_GNU_MBIND) != 0;
1599
1600
231
      if (mbind_p && (attr & SHF_ALLOC) == 0)
1601
1
  as_bad (_("SHF_ALLOC isn't set for GNU_MBIND section: %s"), name);
1602
1603
231
      if (mbind_p)
1604
30
  elf_tdata (stdoutput)->has_gnu_osabi |= elf_gnu_osabi_mbind;
1605
231
      if ((gnu_attr & SHF_GNU_RETAIN) != 0)
1606
207
  elf_tdata (stdoutput)->has_gnu_osabi |= elf_gnu_osabi_retain;
1607
1608
231
      attr |= gnu_attr;
1609
231
    }
1610
1611
31.3k
  change_section (name, type, attr, entsize, &match, linkonce, push,
1612
31.3k
      new_subsection);
1613
1614
31.3k
  if (linked_to_section_index != -1UL)
1615
20
    {
1616
20
      elf_section_flags (now_seg) |= SHF_LINK_ORDER;
1617
20
      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
20
    }
1620
31.3k
}
1621
1622
/* Change to the .bss section.  */
1623
1624
void
1625
obj_elf_bss (int i ATTRIBUTE_UNUSED)
1626
11
{
1627
11
  int temp;
1628
1629
#ifdef md_flush_pending_output
1630
  md_flush_pending_output ();
1631
#endif
1632
1633
11
  obj_elf_section_change_hook ();
1634
1635
11
  temp = get_absolute_expression ();
1636
11
  subseg_set (bss_section, temp);
1637
11
  demand_empty_rest_of_line ();
1638
1639
11
#ifdef md_elf_section_change_hook
1640
11
  md_elf_section_change_hook ();
1641
11
#endif
1642
11
}
1643
1644
/* Change to the .data section.  */
1645
1646
void
1647
obj_elf_data (int i)
1648
0
{
1649
#ifdef md_flush_pending_output
1650
  md_flush_pending_output ();
1651
#endif
1652
1653
0
  obj_elf_section_change_hook ();
1654
1655
0
  s_data (i);
1656
1657
0
#ifdef md_elf_section_change_hook
1658
0
  md_elf_section_change_hook ();
1659
0
#endif
1660
0
}
1661
1662
/* Change to the .text section.  */
1663
1664
void
1665
obj_elf_text (int i)
1666
158
{
1667
#ifdef md_flush_pending_output
1668
  md_flush_pending_output ();
1669
#endif
1670
1671
158
  obj_elf_section_change_hook ();
1672
1673
158
  s_text (i);
1674
1675
158
#ifdef md_elf_section_change_hook
1676
158
  md_elf_section_change_hook ();
1677
158
#endif
1678
158
}
1679
1680
/* Change to the *ABS* section.  */
1681
1682
void
1683
obj_elf_struct (int i)
1684
1.10k
{
1685
#ifdef md_flush_pending_output
1686
  md_flush_pending_output ();
1687
#endif
1688
1689
1.10k
  obj_elf_section_change_hook ();
1690
1691
1.10k
  s_struct (i);
1692
1693
1.10k
#ifdef md_elf_section_change_hook
1694
1.10k
  md_elf_section_change_hook ();
1695
1.10k
#endif
1696
1.10k
}
1697
1698
static void
1699
obj_elf_subsection (int ignore ATTRIBUTE_UNUSED)
1700
2
{
1701
2
  int temp;
1702
1703
#ifdef md_flush_pending_output
1704
  md_flush_pending_output ();
1705
#endif
1706
1707
2
  obj_elf_section_change_hook ();
1708
1709
2
  temp = get_absolute_expression ();
1710
2
  subseg_set (now_seg, temp);
1711
2
  demand_empty_rest_of_line ();
1712
1713
2
#ifdef md_elf_section_change_hook
1714
2
  md_elf_section_change_hook ();
1715
2
#endif
1716
2
}
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
34.2k
{
1724
34.2k
  previous_section = now_seg;
1725
34.2k
  previous_subsection = now_subseg;
1726
34.2k
}
1727
1728
void
1729
obj_elf_previous (int ignore ATTRIBUTE_UNUSED)
1730
21
{
1731
21
  segT new_section;
1732
21
  int new_subsection;
1733
1734
21
  if (previous_section == 0)
1735
2
    {
1736
2
      as_warn (_(".previous without corresponding .section; ignored"));
1737
2
      return;
1738
2
    }
1739
1740
#ifdef md_flush_pending_output
1741
  md_flush_pending_output ();
1742
#endif
1743
1744
19
  new_section = previous_section;
1745
19
  new_subsection = previous_subsection;
1746
19
  obj_elf_section_change_hook ();
1747
1748
19
  subseg_set (new_section, new_subsection);
1749
1750
19
#ifdef md_elf_section_change_hook
1751
19
  md_elf_section_change_hook ();
1752
19
#endif
1753
19
}
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
9
{
1784
  /* Assume delimiter is part of expression.  BSD4.2 as fails with
1785
     delightful bug, so we are not being incompatible here.  */
1786
9
  new_logical_line (NULL, get_absolute_expression ());
1787
9
  demand_empty_rest_of_line ();
1788
9
}
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
62
{
1796
62
  struct elf_versioned_name_list *versioned_name;
1797
62
  const char *p;
1798
1799
94
  for (p = ver + 1; *p == ELF_VER_CHR; p++)
1800
32
    ;
1801
1802
  /* NB: Since some tests in ld/testsuite/ld-elfvers have no version
1803
     names, we have to disable this.  */
1804
62
  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
62
  versioned_name = sy_obj->versioned_name;
1812
1813
62
  switch (p - ver)
1814
62
    {
1815
44
    case 1:
1816
48
    case 2:
1817
48
      break;
1818
14
    case 3:
1819
14
      if (sy_obj->rename)
1820
10
  {
1821
10
    if (strcmp (versioned_name->name, version_name) == 0)
1822
8
      return versioned_name;
1823
2
    else
1824
2
      {
1825
2
        as_bad (_("only one version name with `@@@' is allowed "
1826
2
      "for symbol `%s'"), sym_name);
1827
2
        return NULL;
1828
2
      }
1829
10
  }
1830
4
      sy_obj->rename = true;
1831
4
      break;
1832
0
    default:
1833
0
      as_bad (_("invalid version name '%s' for symbol `%s'"),
1834
0
        version_name, sym_name);
1835
0
      return NULL;
1836
62
    }
1837
1838
52
  for (;
1839
61
       versioned_name != NULL;
1840
52
       versioned_name = versioned_name->next)
1841
44
    if (strcmp (versioned_name->name, version_name) == 0)
1842
35
      return versioned_name;
1843
1844
  /* Add this versioned name to the head of the list,  */
1845
17
  versioned_name = notes_alloc (sizeof (*versioned_name));
1846
17
  versioned_name->name = notes_strdup (version_name);
1847
17
  versioned_name->next = sy_obj->versioned_name;
1848
17
  sy_obj->versioned_name = versioned_name;
1849
1850
17
  return versioned_name;
1851
52
}
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
100
{
1862
100
  char *name;
1863
100
  const char *sym_name;
1864
100
  char c;
1865
100
  char old_lexat;
1866
100
  symbolS *sym;
1867
100
  struct elf_obj_sy *sy_obj;
1868
100
  char *p;
1869
1870
100
  sym = get_sym_from_input_line_and_check ();
1871
1872
100
  if (*input_line_pointer != ',')
1873
0
    {
1874
0
      as_bad (_("expected comma after name in .symver"));
1875
0
      ignore_rest_of_line ();
1876
0
      return;
1877
0
    }
1878
1879
100
  ++input_line_pointer;
1880
100
  SKIP_WHITESPACE ();
1881
1882
  /* Temporarily include '@' in symbol names.  */
1883
100
  old_lexat = lex_type[(unsigned char) '@'];
1884
100
  lex_type[(unsigned char) '@'] |= LEX_NAME;
1885
100
  c = get_symbol_name (& name);
1886
100
  lex_type[(unsigned char) '@'] = old_lexat;
1887
100
  sym_name = S_GET_NAME (sym);
1888
1889
100
  if (S_IS_COMMON (sym))
1890
31
    {
1891
31
      as_bad (_("`%s' can't be versioned to common symbol '%s'"),
1892
31
        name, sym_name);
1893
31
      ignore_rest_of_line ();
1894
31
      return;
1895
31
    }
1896
1897
69
  p = strchr (name, ELF_VER_CHR);
1898
69
  if (p == NULL)
1899
7
    {
1900
7
      as_bad (_("missing version name in `%s' for symbol `%s'"),
1901
7
        name, sym_name);
1902
7
      ignore_rest_of_line ();
1903
7
      return;
1904
7
    }
1905
1906
62
  sy_obj = symbol_get_obj (sym);
1907
62
  if (obj_elf_find_and_add_versioned_name (name, sym_name,
1908
62
             p, sy_obj) == NULL)
1909
2
    {
1910
2
      sy_obj->bad_version = true;
1911
2
      ignore_rest_of_line ();
1912
2
      return;
1913
2
    }
1914
1915
60
  (void) restore_line_pointer (c);
1916
1917
60
  if (*input_line_pointer == ',')
1918
32
    {
1919
32
      char *save = input_line_pointer;
1920
1921
32
      ++input_line_pointer;
1922
32
      SKIP_WHITESPACE ();
1923
32
      if (startswith (input_line_pointer, "local"))
1924
0
  {
1925
0
    input_line_pointer += 5;
1926
0
    sy_obj->visibility = visibility_local;
1927
0
  }
1928
32
      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
32
      else if (startswith (input_line_pointer, "remove"))
1934
10
  {
1935
10
    input_line_pointer += 6;
1936
10
    sy_obj->visibility = visibility_remove;
1937
10
  }
1938
22
      else
1939
22
  input_line_pointer = save;
1940
32
    }
1941
1942
60
  demand_empty_rest_of_line ();
1943
60
}
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
0
{
1952
0
  char *cname, *pname;
1953
0
  symbolS *csym, *psym;
1954
0
  char c;
1955
0
  bool bad = false;
1956
1957
0
  if (*input_line_pointer == '#')
1958
0
    ++input_line_pointer;
1959
1960
0
  c = get_symbol_name (& cname);
1961
0
  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
0
  if (csym == NULL
1968
0
      || symbol_get_frag (csym) == NULL
1969
0
      || symbol_get_value_expression (csym)->X_op != O_constant)
1970
0
    {
1971
0
      as_bad (_("expected `%s' to have already been set for .vtable_inherit"),
1972
0
        cname);
1973
0
      bad = true;
1974
0
    }
1975
1976
0
  restore_line_pointer (c);
1977
1978
0
  SKIP_WHITESPACE ();
1979
0
  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
0
  ++input_line_pointer;
1987
0
  SKIP_WHITESPACE ();
1988
1989
0
  if (*input_line_pointer == '#')
1990
0
    ++input_line_pointer;
1991
1992
0
  if (input_line_pointer[0] == '0'
1993
0
      && (is_end_of_stmt (input_line_pointer[1])
1994
0
    || is_whitespace (input_line_pointer[1])))
1995
0
    {
1996
0
      psym = section_symbol (absolute_section);
1997
0
      ++input_line_pointer;
1998
0
    }
1999
0
  else
2000
0
    {
2001
0
      c = get_symbol_name (& pname);
2002
0
      psym = symbol_find_or_make (pname);
2003
0
      restore_line_pointer (c);
2004
0
    }
2005
2006
0
  demand_empty_rest_of_line ();
2007
2008
0
  if (bad)
2009
0
    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
0
}
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
0
{
2022
0
  static bool warned = false;
2023
2024
0
  if (!warned)
2025
0
    {
2026
0
      warned = true;
2027
0
      as_warn(".vtable_inherit has been deprecated");
2028
0
    }
2029
2030
0
  (void) obj_elf_get_vtable_inherit ();
2031
0
}
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
0
{
2040
0
  symbolS *sym;
2041
0
  offsetT offset;
2042
2043
0
  if (*input_line_pointer == '#')
2044
0
    ++input_line_pointer;
2045
2046
0
  sym = get_sym_from_input_line_and_check ();
2047
0
  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
0
  ++input_line_pointer;
2055
0
  if (*input_line_pointer == '#')
2056
0
    ++input_line_pointer;
2057
2058
0
  offset = get_absolute_expression ();
2059
2060
0
  demand_empty_rest_of_line ();
2061
2062
0
  return fix_new (frag_now, frag_now_fix (), 0, sym, offset, 0,
2063
0
      BFD_RELOC_VTABLE_ENTRY);
2064
0
}
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
0
{
2072
0
  static bool warned = false;
2073
2074
0
  if (!warned)
2075
0
    {
2076
0
      warned = true;
2077
0
      as_warn("'.vtable_entry' has been deprecated");
2078
0
    }
2079
2080
0
  (void) obj_elf_get_vtable_entry ();
2081
0
}
2082
2083
void
2084
elf_obj_read_begin_hook (void)
2085
339
{
2086
#ifdef NEED_ECOFF_DEBUG
2087
  if (ECOFF_DEBUGGING)
2088
    ecoff_read_begin_hook ();
2089
#endif
2090
339
}
2091
2092
void
2093
elf_obj_symbol_new_hook (symbolS *symbolP)
2094
145k
{
2095
145k
  struct elf_obj_sy *sy_obj;
2096
2097
145k
  sy_obj = symbol_get_obj (symbolP);
2098
145k
  sy_obj->size = NULL;
2099
145k
  sy_obj->versioned_name = NULL;
2100
2101
#ifdef NEED_ECOFF_DEBUG
2102
  if (ECOFF_DEBUGGING)
2103
    ecoff_symbol_new_hook (symbolP);
2104
#endif
2105
145k
}
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
8.18k
{
2113
8.18k
  struct elf_obj_sy *srcelf = symbol_get_obj (src);
2114
8.18k
  struct elf_obj_sy *destelf = symbol_get_obj (dest);
2115
8.18k
  if (!destelf->size && S_GET_SIZE (dest) == 0)
2116
8.18k
    {
2117
8.18k
      destelf->size = srcelf->size;
2118
8.18k
      S_SET_SIZE (dest, S_GET_SIZE (src));
2119
8.18k
    }
2120
8.18k
}
2121
2122
void
2123
elf_copy_symbol_attributes (symbolS *dest, symbolS *src)
2124
8.18k
{
2125
8.18k
  elf_copy_symbol_size (dest, src);
2126
  /* Don't copy visibility.  */
2127
8.18k
  S_SET_OTHER (dest, (ELF_ST_VISIBILITY (S_GET_OTHER (dest))
2128
8.18k
          | (S_GET_OTHER (src) & ~ELF_ST_VISIBILITY (-1))));
2129
8.18k
}
2130
2131
void
2132
obj_elf_version (int ignore ATTRIBUTE_UNUSED)
2133
47
{
2134
47
  char *name;
2135
47
  unsigned int c;
2136
47
  char *p;
2137
47
  asection *seg = now_seg;
2138
47
  subsegT subseg = now_subseg;
2139
47
  Elf_Internal_Note i_note;
2140
47
  Elf_External_Note e_note;
2141
47
  asection *note_secp = NULL;
2142
2143
47
  SKIP_WHITESPACE ();
2144
47
  if (*input_line_pointer == '\"')
2145
32
    {
2146
32
      unsigned int len;
2147
2148
32
      ++input_line_pointer; /* -> 1st char of string.  */
2149
32
      name = input_line_pointer;
2150
2151
133
      while (is_a_char (c = next_char_of_string ()))
2152
101
  ;
2153
32
      c = *input_line_pointer;
2154
32
      *input_line_pointer = '\0';
2155
32
      *(input_line_pointer - 1) = '\0';
2156
32
      *input_line_pointer = c;
2157
2158
      /* Create the .note section.  */
2159
32
      note_secp = subseg_new (".note", 0);
2160
32
      bfd_set_section_flags (note_secp, SEC_HAS_CONTENTS | SEC_READONLY);
2161
32
      record_alignment (note_secp, 2);
2162
2163
      /* Process the version string.  */
2164
32
      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
32
      i_note.namesz = len;
2169
32
      i_note.descsz = 0;  /* No description.  */
2170
32
      i_note.type = NT_VERSION;
2171
32
      p = frag_more (sizeof (e_note.namesz));
2172
32
      md_number_to_chars (p, i_note.namesz, sizeof (e_note.namesz));
2173
32
      p = frag_more (sizeof (e_note.descsz));
2174
32
      md_number_to_chars (p, i_note.descsz, sizeof (e_note.descsz));
2175
32
      p = frag_more (sizeof (e_note.type));
2176
32
      md_number_to_chars (p, i_note.type, sizeof (e_note.type));
2177
32
      p = frag_more (len);
2178
32
      memcpy (p, name, len);
2179
2180
32
      frag_align (2, 0, 0);
2181
2182
32
      subseg_set (seg, subseg);
2183
32
    }
2184
15
  else
2185
15
    as_bad (_("expected quoted string"));
2186
2187
47
  demand_empty_rest_of_line ();
2188
47
}
2189
2190
static void
2191
obj_elf_size (int ignore ATTRIBUTE_UNUSED)
2192
3
{
2193
3
  char *name;
2194
3
  char c = get_symbol_name (&name);
2195
3
  char *p;
2196
3
  expressionS exp;
2197
3
  symbolS *sym;
2198
2199
3
  p = input_line_pointer;
2200
3
  restore_line_pointer (c);
2201
3
  SKIP_WHITESPACE ();
2202
3
  if (*input_line_pointer != ',')
2203
0
    {
2204
0
      *p = 0;
2205
0
      as_bad (_("expected comma after name `%s' in .size directive"), name);
2206
0
      *p = c;
2207
0
      ignore_rest_of_line ();
2208
0
      return;
2209
0
    }
2210
3
  input_line_pointer++;
2211
3
  expression (&exp);
2212
3
  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
3
  *p = 0;
2219
3
  sym = symbol_find_or_make (name);
2220
3
  *p = c;
2221
3
  if (exp.X_op == O_constant)
2222
1
    {
2223
1
      S_SET_SIZE (sym, exp.X_add_number);
2224
1
      symbol_get_obj (sym)->size = NULL;
2225
1
    }
2226
2
  else
2227
2
    {
2228
2
      symbol_get_obj (sym)->size = notes_alloc (sizeof (exp));
2229
2
      *symbol_get_obj (sym)->size = exp;
2230
2
    }
2231
2232
  /* If the symbol in the directive matches the current function being
2233
     processed, indicate end of the current stream of ginsns.  */
2234
3
  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
3
  demand_empty_rest_of_line ();
2239
3
}
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
209
{
2262
209
  char *p;
2263
2264
209
  p = input_line_pointer;
2265
209
  if (*input_line_pointer >= '0'
2266
196
      && *input_line_pointer <= '9')
2267
22
    {
2268
47
      while (*input_line_pointer >= '0'
2269
26
       && *input_line_pointer <= '9')
2270
25
  ++input_line_pointer;
2271
22
      *cp = *input_line_pointer;
2272
22
      *input_line_pointer = '\0';
2273
22
    }
2274
187
  else
2275
187
    *cp = get_symbol_name (&p);
2276
2277
209
  return p;
2278
209
}
2279
2280
static void
2281
obj_elf_type (int ignore ATTRIBUTE_UNUSED)
2282
209
{
2283
209
  char c;
2284
209
  int type;
2285
209
  const char *type_name;
2286
209
  symbolS *sym;
2287
209
  elf_symbol_type *elfsym;
2288
2289
209
  sym = get_sym_from_input_line_and_check ();
2290
209
  c = *input_line_pointer;
2291
209
  elfsym = (elf_symbol_type *) symbol_get_bfdsym (sym);
2292
2293
209
  if (*input_line_pointer == ',')
2294
132
    ++input_line_pointer;
2295
2296
209
  SKIP_WHITESPACE ();
2297
209
  if (   *input_line_pointer == '#'
2298
209
      || *input_line_pointer == '@'
2299
36
      || *input_line_pointer == '"'
2300
36
      || *input_line_pointer == '%')
2301
173
    ++input_line_pointer;
2302
2303
209
  type_name = obj_elf_type_name (& c);
2304
2305
209
  type = 0;
2306
209
  if (strcmp (type_name, "function") == 0
2307
81
      || strcmp (type_name, "2") == 0
2308
81
      || strcmp (type_name, "STT_FUNC") == 0)
2309
128
    type = BSF_FUNCTION;
2310
81
  else if (strcmp (type_name, "object") == 0
2311
81
     || strcmp (type_name, "1") == 0
2312
81
     || strcmp (type_name, "STT_OBJECT") == 0)
2313
0
    type = BSF_OBJECT;
2314
81
  else if (strcmp (type_name, "tls_object") == 0
2315
81
     || strcmp (type_name, "6") == 0
2316
64
     || strcmp (type_name, "STT_TLS") == 0)
2317
36
    type = BSF_OBJECT | BSF_THREAD_LOCAL;
2318
45
  else if (strcmp (type_name, "notype") == 0
2319
37
     || strcmp (type_name, "0") == 0
2320
37
     || strcmp (type_name, "STT_NOTYPE") == 0)
2321
8
    ;
2322
37
  else if (strcmp (type_name, "common") == 0
2323
35
     || strcmp (type_name, "5") == 0
2324
32
     || strcmp (type_name, "STT_COMMON") == 0)
2325
5
    {
2326
5
      type = BSF_OBJECT;
2327
2328
5
      if (! S_IS_COMMON (sym))
2329
4
  {
2330
4
    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
4
    else if (S_IS_DEFINED (sym) || symbol_equated_p (sym))
2340
0
      as_bad (_("symbol '%s' is already defined"), S_GET_NAME (sym));
2341
4
    else
2342
4
      {
2343
        /* FIXME: Is it safe to just change the section ?  */
2344
4
        S_SET_SEGMENT (sym, bfd_com_section_ptr);
2345
4
        S_SET_VALUE (sym, 0);
2346
4
        S_SET_EXTERNAL (sym);
2347
4
      }
2348
4
  }
2349
5
    }
2350
32
  else if (strcmp (type_name, "gnu_indirect_function") == 0
2351
32
     || strcmp (type_name, "10") == 0
2352
31
     || 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
31
  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
31
  else
2382
31
    as_bad (_("unrecognized symbol type \"%s\""), type_name);
2383
2384
209
  *input_line_pointer = c;
2385
2386
209
  if (*input_line_pointer == '"')
2387
3
    ++input_line_pointer;
2388
2389
#ifdef md_elf_symbol_type_change
2390
  if (!md_elf_symbol_type_change (sym, elfsym, type))
2391
#endif
2392
209
    {
2393
209
      flagword mask = BSF_FUNCTION | BSF_OBJECT;
2394
2395
209
      if (type != BSF_FUNCTION)
2396
81
  mask |= BSF_GNU_INDIRECT_FUNCTION;
2397
209
      if (type != BSF_OBJECT)
2398
204
  {
2399
204
    mask |= BSF_GNU_UNIQUE | BSF_THREAD_LOCAL;
2400
2401
204
    if (S_IS_COMMON (sym))
2402
2
      {
2403
2
        as_bad (_("cannot change type of common symbol '%s'"),
2404
2
          S_GET_NAME (sym));
2405
2
        mask = type = 0;
2406
2
      }
2407
204
  }
2408
2409
      /* Don't warn when changing to STT_NOTYPE.  */
2410
209
      if (type)
2411
170
  {
2412
170
    flagword new = (elfsym->symbol.flags & ~mask) | type;
2413
2414
170
    if (new != (elfsym->symbol.flags | type))
2415
0
      as_warn (_("symbol '%s' already has its type set"), S_GET_NAME (sym));
2416
170
    elfsym->symbol.flags = new;
2417
170
  }
2418
39
      else
2419
39
  elfsym->symbol.flags &= ~mask;
2420
209
    }
2421
2422
209
  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
209
  demand_empty_rest_of_line ();
2433
209
}
2434
2435
static segT comment_section;
2436
2437
static void
2438
obj_elf_ident (int ignore ATTRIBUTE_UNUSED)
2439
0
{
2440
0
  segT old_section = now_seg;
2441
0
  int old_subsection = now_subseg;
2442
2443
#ifdef md_flush_pending_output
2444
  md_flush_pending_output ();
2445
#endif
2446
2447
0
  if (!comment_section)
2448
0
    {
2449
0
      char *p;
2450
0
      comment_section = subseg_new (".comment", 0);
2451
0
      bfd_set_section_flags (comment_section, (SEC_READONLY | SEC_HAS_CONTENTS
2452
0
                 | SEC_MERGE | SEC_STRINGS));
2453
0
      comment_section->entsize = 1;
2454
0
#ifdef md_elf_section_change_hook
2455
0
      md_elf_section_change_hook ();
2456
0
#endif
2457
0
      p = frag_more (1);
2458
0
      *p = 0;
2459
0
    }
2460
0
  else
2461
0
    {
2462
0
      subseg_set (comment_section, 0);
2463
0
#ifdef md_elf_section_change_hook
2464
0
      md_elf_section_change_hook ();
2465
0
#endif
2466
0
    }
2467
0
  stringer (8 + 1);
2468
0
  subseg_set (old_section, old_subsection);
2469
0
#ifdef md_elf_section_change_hook
2470
0
  md_elf_section_change_hook ();
2471
0
#endif
2472
0
}
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
13
{
2481
13
  char *file;
2482
13
  char *p;
2483
13
  unsigned int stroff;
2484
2485
  /* Force the section to align to a longword boundary.  Without this,
2486
     UnixWare ar crashes.  */
2487
13
  bfd_set_section_alignment (stab, 2);
2488
2489
  /* Make space for this first symbol.  */
2490
13
  p = frag_more (12);
2491
  /* Zero it out.  */
2492
13
  memset (p, 0, 12);
2493
13
  file = remap_debug_filename (as_where (NULL));
2494
13
  stroff = get_stab_string_offset (file, stabstr);
2495
13
  know (stroff == 1 || (stroff == 0 && file[0] == '\0'));
2496
13
  md_number_to_chars (p, stroff, 4);
2497
13
  seg_info (stab)->stabu.p = p;
2498
13
  free (file);
2499
13
}
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
339
{
3018
339
  asection *s;
3019
3020
  /* Add symbols for the known sections to the symbol table.  */
3021
339
  s = bfd_get_section_by_name (stdoutput, TEXT_SECTION_NAME);
3022
339
  symbol_table_insert (section_symbol (s));
3023
339
  s = bfd_get_section_by_name (stdoutput, DATA_SECTION_NAME);
3024
339
  symbol_table_insert (section_symbol (s));
3025
339
  s = bfd_get_section_by_name (stdoutput, BSS_SECTION_NAME);
3026
339
  symbol_table_insert (section_symbol (s));
3027
339
  elf_com_section_ptr = bfd_com_section_ptr;
3028
339
  previous_section = NULL;
3029
339
  previous_subsection = 0;
3030
339
  comment_section = NULL;
3031
339
  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
339
}
3044
3045
void
3046
elf_end (void)
3047
339
{
3048
339
  if (!ENABLE_LEAK_CHECK)
3049
0
    return;
3050
340
  while (section_stack)
3051
1
    {
3052
1
      struct section_stack *top = section_stack;
3053
1
      section_stack = top->next;
3054
1
      free (top);
3055
1
    }
3056
339
  if (groups.indexes)
3057
16
    {
3058
16
      htab_delete (groups.indexes);
3059
16
      free (groups.head);
3060
16
    }
3061
3062
#if TC_OBJ_ATTR_v1
3063
  oav1_attr_info_exit ();
3064
#endif /* TC_OBJ_ATTR_v1 */
3065
339
}
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 */