Coverage Report

Created: 2026-10-02 09:53

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
281
#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
281
{
197
281
  pop_insert (elf_pseudo_table);
198
281
  if (ECOFF_DEBUGGING)
199
0
    pop_insert (ecoff_debug_pseudo_table);
200
281
}
201
202
void
203
elf_file_symbol (const char *s)
204
157
{
205
157
  asymbol *bsym;
206
157
  symbolS *sym = symbol_new (s, absolute_section, &zero_address_frag, 0);
207
157
  size_t name_length = strlen (s);
208
209
157
  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
157
  else
215
157
    strcpy ((char *) S_GET_NAME (sym), s);
216
217
157
  symbol_get_bfdsym (sym)->flags |= BSF_FILE;
218
219
157
  if (symbol_rootP != sym
220
157
      && ((bsym = symbol_get_bfdsym (symbol_rootP)) == NULL
221
157
    || (bsym->flags & BSF_FILE) == 0))
222
18
    {
223
18
      symbol_remove (sym, &symbol_rootP, &symbol_lastP);
224
18
      symbol_insert (sym, symbol_rootP, &symbol_rootP, &symbol_lastP);
225
18
    }
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
157
}
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
414
{
242
414
  addressT align = 0;
243
414
  int is_local = symbol_get_obj (symbolP)->local;
244
245
414
  if (*input_line_pointer == ',')
246
140
    {
247
140
      char *save = input_line_pointer;
248
249
140
      input_line_pointer++;
250
140
      SKIP_WHITESPACE ();
251
252
140
      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
139
      else
284
139
  {
285
139
    input_line_pointer = save;
286
139
    align = parse_align (is_local);
287
139
    if (align == (addressT) -1)
288
11
      return NULL;
289
139
  }
290
140
    }
291
292
402
  if (is_local)
293
1
    {
294
1
      bss_alloc (symbolP, size, align);
295
1
      S_CLEAR_EXTERNAL (symbolP);
296
1
    }
297
401
  else
298
401
    {
299
401
      S_SET_VALUE (symbolP, size);
300
401
      S_SET_ALIGN (symbolP, align);
301
401
      S_SET_EXTERNAL (symbolP);
302
401
      S_SET_SEGMENT (symbolP, elf_com_section_ptr);
303
401
    }
304
305
402
  symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
306
307
402
  return symbolP;
308
414
}
309
310
void
311
obj_elf_common (int is_common)
312
493
{
313
493
  if (flag_mri && is_common)
314
0
    s_mri_common (0);
315
493
  else
316
493
    s_comm_internal (0, elf_common_parse);
317
493
}
318
319
static void
320
obj_elf_tls_common (int ignore ATTRIBUTE_UNUSED)
321
13
{
322
13
  symbolS *symbolP = s_comm_internal (0, elf_common_parse);
323
324
13
  if (symbolP)
325
0
    symbol_get_bfdsym (symbolP)->flags |= BSF_THREAD_LOCAL;
326
13
}
327
328
static void
329
obj_elf_lcomm (int ignore ATTRIBUTE_UNUSED)
330
137
{
331
137
  symbolS *symbolP = s_comm_internal (0, s_lcomm_internal);
332
333
137
  if (symbolP)
334
3
    symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
335
137
}
336
337
static symbolS *
338
get_sym_from_input_line_and_check (void)
339
330
{
340
330
  char *name;
341
330
  char c;
342
330
  symbolS *sym;
343
344
330
  c = get_symbol_name (& name);
345
330
  sym = symbol_find_or_make (name);
346
330
  restore_line_pointer (c);
347
330
  SKIP_WHITESPACE ();
348
349
  /* There is no symbol name if input_line_pointer has not moved.  */
350
330
  if (name == input_line_pointer)
351
160
    as_bad (_("Missing symbol name in directive"));
352
330
  return sym;
353
330
}
354
355
static void
356
obj_elf_local (int ignore ATTRIBUTE_UNUSED)
357
4
{
358
4
  int c;
359
4
  symbolS *symbolP;
360
361
4
  do
362
12
    {
363
12
      symbolP = get_sym_from_input_line_and_check ();
364
12
      c = *input_line_pointer;
365
12
      S_CLEAR_EXTERNAL (symbolP);
366
12
      symbol_get_obj (symbolP)->local = 1;
367
12
      if (c == ',')
368
8
  {
369
8
    input_line_pointer++;
370
8
    SKIP_WHITESPACE ();
371
8
    if (*input_line_pointer == '\n')
372
0
      c = '\n';
373
8
  }
374
12
    }
375
12
  while (c == ',');
376
4
  demand_empty_rest_of_line ();
377
4
}
378
379
static void
380
obj_elf_weak (int ignore ATTRIBUTE_UNUSED)
381
6
{
382
6
  int c;
383
6
  symbolS *symbolP;
384
385
6
  do
386
9
    {
387
9
      symbolP = get_sym_from_input_line_and_check ();
388
9
      c = *input_line_pointer;
389
9
      S_SET_WEAK (symbolP);
390
9
      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
9
    }
398
9
  while (c == ',');
399
6
  demand_empty_rest_of_line ();
400
6
}
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
30.2k
#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
30.2k
{
468
30.2k
  const char *linked_to_symbol_name = sec->map_head.linked_to_symbol_name;
469
30.2k
  unsigned int sh_info = elf_section_data (sec)->this_hdr.sh_info;
470
30.2k
  bfd_vma sh_flags = (elf_section_data (sec)->this_hdr.sh_flags
471
30.2k
          & SEC_ASSEMBLER_SHF_MASK);
472
473
30.2k
  return (sh_info == match->sh_info
474
30.2k
    && sh_flags == match->sh_flags
475
30.1k
    && ((bfd_section_flags (sec) & SEC_ASSEMBLER_SECTION_ID)
476
30.1k
         == (match->flags & SEC_ASSEMBLER_SECTION_ID))
477
30.1k
    && sec->section_id == match->section_id
478
30.1k
    && (linked_to_symbol_name == match->linked_to_symbol_name
479
24
        || (linked_to_symbol_name != NULL
480
16
      && match->linked_to_symbol_name != NULL
481
10
      && strcmp (linked_to_symbol_name,
482
10
           match->linked_to_symbol_name) == 0)));
483
30.2k
}
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
30.1k
{
490
30.1k
  struct elf_section_match *match = inf;
491
30.1k
  const char *gname = match->group_name;
492
30.1k
  const char *group_name = elf_group_name (sec);
493
494
30.1k
  return ((group_name == gname
495
29
     || (group_name != NULL
496
29
         && gname != NULL
497
0
         && strcmp (group_name, gname) == 0))
498
30.1k
    && match_section (sec, match));
499
30.1k
}
500
501
/* Go look in section lists kept per group for SEC_NAME with
502
   properties given by MATCH.  If info for the group named by
503
   MATCH->GROUP_NAME has been initialised, set GROUP_IDX.  */
504
505
static asection *
506
group_section_find (const struct elf_section_match *match,
507
        const char *sec_name,
508
        unsigned int *group_idx)
509
47
{
510
47
  if (!groups.indexes)
511
11
    {
512
11
      groups.num_group = 0;
513
11
      groups.head = NULL;
514
11
      groups.indexes = htab_create_alloc (16, hash_string_tuple, eq_string_tuple,
515
11
            NULL, notes_calloc, NULL);
516
11
      *group_idx = ~0u;
517
11
      return NULL;
518
11
    }
519
520
36
  *group_idx = str_hash_find_int (groups.indexes, match->group_name);
521
36
  if (*group_idx == ~0u)
522
10
    return NULL;
523
524
26
  asection *s;
525
95
  for (s = groups.head[*group_idx]; s != NULL; s = elf_next_in_group (s))
526
80
    if ((s->name == sec_name
527
80
   || strcmp (s->name, sec_name) == 0)
528
58
  && match_section (s, match))
529
11
      break;
530
26
  return s;
531
36
}
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
36
{
541
36
  if (*group_idx != ~0u)
542
15
    {
543
15
      elf_next_in_group (sec) = groups.head[*group_idx];
544
15
      groups.head[*group_idx] = sec;
545
15
      return;
546
15
    }
547
548
21
  unsigned int i = groups.num_group;
549
21
  if ((i & 127) == 0)
550
11
    groups.head = XRESIZEVEC (asection *, groups.head, i + 128);
551
21
  groups.head[i] = sec;
552
21
  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
21
  str_hash_insert_int (groups.indexes, match->group_name, i, 0);
557
21
}
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.0k
{
587
31.0k
  asection *old_sec;
588
31.0k
  segT sec;
589
31.0k
  flagword flags;
590
31.0k
  const struct bfd_elf_special_section *ssect;
591
592
31.0k
  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.0k
  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.0k
  obj_elf_section_change_hook ();
616
617
31.0k
  unsigned int group_idx = ~0u;
618
31.0k
  if (match_p->group_name)
619
38
    old_sec = group_section_find (match_p, name, &group_idx);
620
31.0k
  else
621
31.0k
    old_sec = bfd_get_section_by_name_if (stdoutput, name, get_section_by_match,
622
31.0k
            match_p);
623
31.0k
  if (old_sec)
624
30.1k
    {
625
30.1k
      sec = old_sec;
626
30.1k
      subseg_set (sec, new_subsection);
627
30.1k
    }
628
955
  else
629
955
    {
630
955
      sec = subseg_force_new (name, new_subsection);
631
955
      if (match_p->group_name)
632
28
  group_section_insert (match_p, sec, &group_idx);
633
955
    }
634
635
31.0k
  elf_backend_data *bed = get_elf_backend_data (stdoutput);
636
31.0k
  ssect = (*bed->get_sec_type_attr) (stdoutput, sec);
637
638
31.0k
  if (ssect != NULL)
639
39
    {
640
39
      bool override = false;
641
642
39
      if (type == SHT_NULL)
643
23
  type = ssect->type;
644
16
      else if (type != ssect->type)
645
12
  {
646
12
    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
10
#ifdef TC_I386
659
10
        && (bed->s->arch_size != 64
660
10
      || !(ssect->attr & SHF_X86_64_LARGE))
661
10
#endif
662
10
        && ssect->type != SHT_INIT_ARRAY
663
10
        && ssect->type != SHT_FINI_ARRAY
664
10
        && ssect->type != SHT_PREINIT_ARRAY)
665
10
      {
666
        /* We allow to specify any type for a .note section.  */
667
10
        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
10
      }
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
12
  }
680
681
39
      if (old_sec == NULL && ((attr & ~(SHF_LINK_ORDER
682
29
          | SHF_MASKOS
683
29
          | SHF_MASKPROC))
684
29
            & ~ssect->attr) != 0)
685
5
  {
686
    /* Strip SHF_GNU_RETAIN.  */
687
5
    bfd_vma generic_attr = attr;
688
5
    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
5
    if (ssect->type == SHT_NOTE
696
4
        && (generic_attr == SHF_ALLOC
697
4
      || generic_attr == SHF_EXECINSTR))
698
0
      ;
699
    /* Allow different SHF_MERGE and SHF_STRINGS if we have
700
       something like .rodata.str.  */
701
5
    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
5
    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
5
    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
5
    else
732
5
      {
733
5
        if (match_p->group_name == NULL)
734
4
    as_warn (_("setting incorrect section attributes for %s"),
735
4
       name);
736
5
        override = true;
737
5
      }
738
5
  }
739
740
39
      if (!override && old_sec == NULL)
741
24
  attr |= ssect->attr;
742
39
    }
743
744
  /* Convert ELF type and flags to BFD flags.  */
745
31.0k
  flags = (SEC_RELOC
746
31.0k
     | ((attr & SHF_WRITE) ? 0 : SEC_READONLY)
747
31.0k
     | ((attr & SHF_ALLOC) ? SEC_ALLOC : 0)
748
31.0k
     | (((attr & SHF_ALLOC) && type != SHT_NOBITS) ? SEC_LOAD : 0)
749
31.0k
     | ((attr & SHF_EXECINSTR) ? SEC_CODE : 0)
750
31.0k
     | ((attr & SHF_MERGE) ? SEC_MERGE : 0)
751
31.0k
     | ((attr & SHF_STRINGS) ? SEC_STRINGS : 0)
752
31.0k
     | ((attr & SHF_EXCLUDE) ? SEC_EXCLUDE: 0)
753
31.0k
     | ((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.0k
  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.0k
  if ((flags & SEC_ALLOC) == 0 && name [0] == '.')
767
398
    {
768
398
      if (   startswith (name, ".debug")
769
391
    || startswith (name, ".zdebug")
770
391
    || startswith (name, ".gnu.debuglto_.debug_")
771
391
    || startswith (name, ".gnu.linkonce.wi.")
772
391
    || startswith (name, GNU_BUILD_ATTRS_SECTION_NAME)
773
390
    || startswith (name, ".note.gnu"))
774
16
  flags |= SEC_ELF_OCTETS;
775
398
    }
776
777
31.0k
  if (old_sec == NULL)
778
955
    {
779
955
      if (type == SHT_NULL)
780
882
  type = bfd_elf_get_default_section_type (flags);
781
955
      elf_section_type (sec) = type;
782
955
      elf_section_flags (sec) = attr;
783
955
      elf_section_data (sec)->this_hdr.sh_info = match_p->sh_info;
784
785
      /* Prevent SEC_HAS_CONTENTS from being inadvertently set.  */
786
955
      if (type == SHT_NOBITS)
787
3
  seg_info (sec)->bss = 1;
788
789
      /* Set the section ID and flags.  */
790
955
      sec->section_id = match_p->section_id;
791
955
      flags |= match_p->flags;
792
793
      /* Set the linked-to symbol name.  */
794
955
      sec->map_head.linked_to_symbol_name
795
955
  = match_p->linked_to_symbol_name;
796
797
955
      bfd_set_section_flags (sec, flags);
798
955
      if (entsize != 0)
799
11
  sec->entsize = entsize;
800
955
      elf_group_name (sec) = match_p->group_name;
801
802
      /* Add a symbol for this section to the symbol table.  */
803
955
      symbol_table_insert (section_symbol (sec));
804
955
    }
805
30.1k
  else
806
30.1k
    {
807
30.1k
      if (type != SHT_NULL
808
29.1k
    && (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.1k
      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
13
      {
832
13
        if (ssect != NULL)
833
3
    as_warn (_("ignoring changed section attributes for %s"), name);
834
10
        else
835
10
    as_bad (_("changed section attributes for %s"), name);
836
13
      }
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
11
        && old_sec->entsize != (unsigned) entsize)
844
1
      as_bad (_("changed section entity size for %s"), name);
845
29.1k
  }
846
30.1k
    }
847
848
31.0k
#ifdef md_elf_section_change_hook
849
31.0k
  md_elf_section_change_hook ();
850
31.0k
#endif
851
31.0k
}
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.2k
{
869
29.2k
  bfd_vma attr = 0;
870
871
29.2k
  *is_clone = false;
872
29.2k
  *inherit = 0;
873
874
117k
  while (len > 0)
875
117k
    {
876
117k
      switch (*str)
877
117k
  {
878
10
  case 'a':
879
10
    attr |= SHF_ALLOC;
880
    /* Compatibility.  */
881
10
    if (len > 1 && str[1] == 'm')
882
0
      {
883
0
        attr |= SHF_MERGE;
884
0
        str++, len--;
885
0
        if (len > 1 && str[1] == 's')
886
0
    {
887
0
      attr |= SHF_STRINGS;
888
0
      str++, len--;
889
0
    }
890
0
      }
891
10
    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
4
  case 'e':
898
4
    attr |= SHF_EXCLUDE;
899
4
    break;
900
0
  case 'o':
901
0
    attr |= SHF_LINK_ORDER;
902
0
    break;
903
9
  case 'w':
904
9
    attr |= SHF_WRITE;
905
9
    break;
906
0
  case 'x':
907
0
    attr |= SHF_EXECINSTR;
908
0
    break;
909
0
  case 'E':
910
0
    *has_entsize = true;
911
0
    break;
912
0
  case 'G':
913
0
    attr |= SHF_GROUP;
914
0
    break;
915
0
  case 'M':
916
0
    attr |= SHF_MERGE;
917
0
    break;
918
16
  case 'R':
919
16
    if (gnu_attr == NULL)
920
0
      goto unrecognized;
921
16
    *gnu_attr |= SHF_GNU_RETAIN;
922
16
    break;
923
9
  case 'S':
924
9
    attr |= SHF_STRINGS;
925
9
    break;
926
8
  case 'T':
927
8
    attr |= SHF_TLS;
928
8
    break;
929
9
  case '?':
930
9
    *is_clone = true;
931
9
    break;
932
116k
  default:
933
116k
  unrecognized:
934
116k
    {
935
116k
      const char *md_extra = "";
936
937
116k
#ifdef md_elf_section_letter
938
116k
      bfd_vma md_attr = md_elf_section_letter (*str, &md_extra);
939
116k
      if (md_attr != (bfd_vma) -1)
940
0
        attr |= md_attr;
941
116k
      else
942
116k
#endif
943
116k
        if (ISDIGIT (*str))
944
58.5k
    {
945
58.5k
      char * end;
946
58.5k
      bfd_vma numeric_flags = strtoul (str, &end, 0);
947
948
58.5k
      attr |= numeric_flags;
949
950
58.5k
      if (gnu_attr != NULL)
951
58.5k
        {
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
58.5k
          *gnu_attr |= (numeric_flags & SHF_MASKOS);
961
58.5k
        }
962
963
      /* Update str and len, allowing for the fact that
964
         we will execute str++ and len-- below.  */
965
58.5k
      end --;
966
58.5k
      len -= (end - str);
967
58.5k
      str = end;
968
58.5k
    }
969
58.4k
        else if (!*inherit && !attr
970
29.1k
           && (gnu_attr == NULL || !*gnu_attr)
971
29.1k
           && (*str == '+' || *str == '-'))
972
29.1k
    *inherit = *str == '+' ? 1 : -1;
973
29.2k
        else
974
29.2k
    {
975
29.2k
      as_bad (_("unrecognized .%ssection attribute: want %s%s%s,? or number"),
976
29.2k
        push ? "push" : "",
977
29.2k
        gnu_attr != NULL ? "a,d,e,o,w,x,E,G,M,R,S,T"
978
29.2k
             : "a,e,o,w,x,E,G,M,S,T",
979
29.2k
        md_extra != NULL ? "," : "", md_extra);
980
29.2k
      return attr;
981
29.2k
    }
982
116k
    }
983
87.7k
    break;
984
117k
  }
985
87.8k
      str++, len--;
986
87.8k
    }
987
988
13
  return attr;
989
29.2k
}
990
991
static int
992
obj_elf_section_type (char *str, size_t len, bool warn)
993
24
{
994
24
  if (len == 8 && startswith (str, "progbits"))
995
0
    return SHT_PROGBITS;
996
24
  if (len == 6 && startswith (str, "nobits"))
997
0
    return SHT_NOBITS;
998
24
  if (len == 4 && startswith (str, "note"))
999
0
    return SHT_NOTE;
1000
24
  if (len == 10 && startswith (str, "init_array"))
1001
0
    return SHT_INIT_ARRAY;
1002
24
  if (len == 10 && startswith (str, "fini_array"))
1003
0
    return SHT_FINI_ARRAY;
1004
24
  if (len == 13 && startswith (str, "preinit_array"))
1005
0
    return SHT_PREINIT_ARRAY;
1006
1007
24
#ifdef md_elf_section_type
1008
24
  {
1009
24
    int md_type = md_elf_section_type (str, len);
1010
24
    if (md_type >= 0)
1011
9
      return md_type;
1012
24
  }
1013
15
#endif
1014
1015
15
  if (ISDIGIT (*str))
1016
8
    {
1017
8
      char * end;
1018
8
      int type = strtoul (str, & end, 0);
1019
1020
8
      if (warn && (size_t) (end - str) != len)
1021
7
  as_warn (_("extraneous characters at end of numeric section type"));
1022
1023
8
      return type;
1024
8
    }
1025
1026
7
  if (warn)
1027
7
    as_warn (_("unrecognized section type"));
1028
7
  return 0;
1029
15
}
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.1k
{
1062
31.1k
  char *name;
1063
1064
31.1k
  SKIP_WHITESPACE ();
1065
31.1k
  if (*input_line_pointer == '"')
1066
1
    {
1067
1
      int dummy;
1068
1069
1
      name = demand_copy_C_string (&dummy);
1070
1
      if (name == NULL)
1071
0
  {
1072
0
    ignore_rest_of_line ();
1073
0
    return NULL;
1074
0
  }
1075
1
    }
1076
31.1k
  else
1077
31.1k
    {
1078
31.1k
      char *end = input_line_pointer;
1079
1080
183k
      while (!is_whitespace (*end) && !is_end_of_stmt (*end) && *end != ',')
1081
152k
  end++;
1082
31.1k
      if (end == input_line_pointer)
1083
4
  {
1084
4
    as_bad (_("missing name"));
1085
4
    ignore_rest_of_line ();
1086
4
    return NULL;
1087
4
  }
1088
1089
31.1k
      obstack_grow0 (&notes, input_line_pointer, end - input_line_pointer);
1090
31.1k
      name = obstack_base (&notes);
1091
1092
31.1k
      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.1k
      obstack_finish (&notes);
1114
1115
#ifdef tc_canonicalize_section_name
1116
      name = tc_canonicalize_section_name (name);
1117
#endif
1118
31.1k
      input_line_pointer = end;
1119
31.1k
    }
1120
31.1k
  SKIP_WHITESPACE ();
1121
31.1k
  return name;
1122
31.1k
}
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
9
{
1130
9
  elf_group_name (sec) = gname;
1131
9
  elf_section_flags (sec) |= SHF_GROUP;
1132
1133
9
  struct elf_section_match match;
1134
9
  match.group_name = gname;
1135
9
  match.linked_to_symbol_name = sec->map_head.linked_to_symbol_name;
1136
9
  match.section_id = sec->section_id;
1137
9
  match.sh_info = elf_section_data (sec)->this_hdr.sh_info;
1138
9
  match.sh_flags = (elf_section_data (sec)->this_hdr.sh_flags
1139
9
        & SEC_ASSEMBLER_SHF_MASK);
1140
9
  match.flags = bfd_section_flags (sec) & SEC_ASSEMBLER_SECTION_ID;
1141
1142
9
  unsigned int group_idx;
1143
9
  if (!group_section_find (&match, sec->name, &group_idx))
1144
8
    group_section_insert (&match, sec, &group_idx);
1145
9
}
1146
1147
static void
1148
obj_elf_attach_to_group (int dummy ATTRIBUTE_UNUSED)
1149
17
{
1150
17
  const char * gname = obj_elf_section_name ();
1151
1152
17
  if (gname == NULL)
1153
0
    {
1154
0
      as_warn (_("group name not parseable"));
1155
0
      return;
1156
0
    }
1157
1158
17
  if (elf_group_name (now_seg))
1159
8
    {
1160
8
      if (strcmp (elf_group_name (now_seg), gname) != 0)
1161
2
  as_warn (_("section %s already has a group (%s)"),
1162
2
     bfd_section_name (now_seg), elf_group_name (now_seg));
1163
8
      return;
1164
8
    }
1165
9
  elf_set_group_name (now_seg, gname);
1166
9
}
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.7k
{
1180
31.7k
  const char *name;
1181
31.7k
  char *beg;
1182
31.7k
  int type, dummy;
1183
31.7k
  bfd_vma attr;
1184
31.7k
  bfd_vma gnu_attr;
1185
31.7k
  int entsize;
1186
31.7k
  bool linkonce, has_entsize;
1187
31.7k
  subsegT new_subsection = 0;
1188
31.7k
  struct elf_section_match match;
1189
31.7k
  unsigned long linked_to_section_index = -1UL;
1190
1191
31.7k
  if (flag_mri)
1192
666
    {
1193
666
      char mri_type;
1194
1195
#ifdef md_flush_pending_output
1196
      md_flush_pending_output ();
1197
#endif
1198
1199
666
      obj_elf_section_change_hook ();
1200
1201
666
      s_mri_sect (&mri_type);
1202
1203
666
#ifdef md_elf_section_change_hook
1204
666
      md_elf_section_change_hook ();
1205
666
#endif
1206
1207
666
      return;
1208
666
    }
1209
1210
31.0k
  name = obj_elf_section_name ();
1211
31.0k
  if (name == NULL)
1212
3
    return;
1213
1214
31.0k
  memset (&match, 0, sizeof (match));
1215
1216
31.0k
  symbolS * sym;
1217
31.0k
  if ((sym = symbol_find (name)) != NULL
1218
30.1k
      && ! 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.0k
  type = SHT_NULL;
1228
31.0k
  attr = 0;
1229
31.0k
  gnu_attr = 0;
1230
31.0k
  entsize = 0;
1231
31.0k
  has_entsize = false;
1232
31.0k
  linkonce = 0;
1233
1234
31.0k
  if (*input_line_pointer == ',')
1235
29.8k
    {
1236
      /* Skip the comma.  */
1237
29.8k
      ++input_line_pointer;
1238
29.8k
      SKIP_WHITESPACE ();
1239
1240
29.8k
      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
29.8k
      if (*input_line_pointer == '"')
1257
29.2k
  {
1258
29.2k
    bool is_clone;
1259
29.2k
    int inherit;
1260
1261
29.2k
    beg = demand_copy_C_string (&dummy);
1262
29.2k
    if (beg == NULL)
1263
0
      {
1264
0
        ignore_rest_of_line ();
1265
0
        return;
1266
0
      }
1267
1268
29.2k
    elf_backend_data *bed = get_elf_backend_data (stdoutput);
1269
29.2k
    bool maybe_gnu = (bed->elf_osabi == ELFOSABI_NONE
1270
29.2k
          || bed->elf_osabi == ELFOSABI_GNU
1271
0
          || bed->elf_osabi == ELFOSABI_FREEBSD);
1272
29.2k
    attr = obj_elf_parse_section_letters (beg, strlen (beg), push,
1273
29.2k
            &is_clone, &inherit,
1274
29.2k
            maybe_gnu ? &gnu_attr : NULL,
1275
29.2k
            &has_entsize);
1276
1277
29.2k
    if (inherit > 0)
1278
29.1k
      attr |= elf_section_flags (now_seg);
1279
90
    else if (inherit < 0)
1280
15
      attr = elf_section_flags (now_seg) & ~attr;
1281
29.2k
    if (inherit)
1282
29.1k
      type = elf_section_type (now_seg);
1283
1284
29.2k
    if ((attr & (SHF_MERGE | SHF_STRINGS)) != 0)
1285
260
      has_entsize = true;
1286
1287
29.2k
    SKIP_WHITESPACE ();
1288
29.2k
    if (*input_line_pointer == ',')
1289
284
      {
1290
284
        char c;
1291
284
        char *save = input_line_pointer;
1292
1293
284
        ++input_line_pointer;
1294
284
        SKIP_WHITESPACE ();
1295
284
        c = *input_line_pointer;
1296
284
        if (c == '"')
1297
24
    {
1298
24
      beg = demand_copy_C_string (&dummy);
1299
24
      if (beg == NULL)
1300
0
        {
1301
0
          ignore_rest_of_line ();
1302
0
          return;
1303
0
        }
1304
24
      type = obj_elf_section_type (beg, strlen (beg), true);
1305
24
    }
1306
260
        else if (c == '@' || c == '%')
1307
0
    {
1308
0
      ++input_line_pointer;
1309
1310
0
      if (ISDIGIT (* input_line_pointer))
1311
0
        type = strtoul (input_line_pointer, &input_line_pointer, 0);
1312
0
      else
1313
0
        {
1314
0
          c = get_symbol_name (& beg);
1315
0
          (void) restore_line_pointer (c);
1316
0
          type = obj_elf_section_type (beg,
1317
0
               input_line_pointer - beg,
1318
0
               true);
1319
0
        }
1320
0
    }
1321
260
        else
1322
260
    input_line_pointer = save;
1323
284
      }
1324
1325
29.2k
    SKIP_WHITESPACE ();
1326
29.2k
    if (has_entsize && *input_line_pointer == ',')
1327
226
      {
1328
226
        ++input_line_pointer;
1329
226
        SKIP_WHITESPACE ();
1330
226
        if (inherit && *input_line_pointer == ','
1331
197
      && ((bfd_section_flags (now_seg)
1332
197
           & (SEC_MERGE | SEC_STRINGS)) != 0
1333
196
          || now_seg->entsize))
1334
1
    goto fetch_entsize;
1335
225
        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
225
        else
1349
225
    {
1350
225
      entsize = get_absolute_expression ();
1351
225
      SKIP_WHITESPACE ();
1352
225
      if (entsize <= 0)
1353
221
        {
1354
221
          as_warn (_("invalid section entity size"));
1355
221
          attr &= ~(SHF_MERGE | SHF_STRINGS);
1356
221
          has_entsize = false;
1357
221
          entsize = 0;
1358
221
        }
1359
225
    }
1360
225
      }
1361
29.0k
    else if (has_entsize && inherit
1362
10
        && ((bfd_section_flags (now_seg)
1363
10
       & (SEC_MERGE | SEC_STRINGS)) != 0
1364
6
      || now_seg->entsize))
1365
4
      {
1366
5
      fetch_entsize:
1367
5
        entsize = now_seg->entsize;
1368
5
      }
1369
29.0k
    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.0k
    else if ((attr & SHF_STRINGS) != 0)
1378
13
      {
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
13
        entsize = 1;
1384
13
      }
1385
28.9k
    else if (has_entsize)
1386
0
      {
1387
0
        as_warn (_("entity size not specified"));
1388
0
        has_entsize = false;
1389
0
      }
1390
1391
29.2k
    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.2k
    if ((attr & SHF_LINK_ORDER) != 0 && *input_line_pointer == ',')
1395
37
      {
1396
37
        ++input_line_pointer;
1397
37
        SKIP_WHITESPACE ();
1398
        /* Check for a numeric section index, rather than a symbol name.  */
1399
37
        if (ISDIGIT (* input_line_pointer))
1400
3
    {
1401
3
      linked_to_section_index = strtoul (input_line_pointer, & input_line_pointer, 0);
1402
3
    }
1403
34
        else if (inherit && *input_line_pointer == ','
1404
12
           && (elf_section_flags (now_seg) & SHF_LINK_ORDER) != 0)
1405
9
    goto fetch_linked_to;
1406
25
        else
1407
25
    {
1408
25
      char c;
1409
25
      unsigned int length;
1410
1411
25
      c = get_symbol_name (& beg);
1412
25
      (void) restore_line_pointer (c);
1413
25
      length = input_line_pointer - beg;
1414
25
      if (length)
1415
11
        match.linked_to_symbol_name
1416
11
          = notes_memdup (beg, length, length + 1);
1417
25
    }
1418
37
      }
1419
29.2k
    else if ((attr & SHF_LINK_ORDER) != 0 && inherit
1420
13
       && (elf_section_flags (now_seg) & SHF_LINK_ORDER) != 0)
1421
12
      {
1422
21
      fetch_linked_to:
1423
21
        if (now_seg->map_head.linked_to_symbol_name)
1424
4
    match.linked_to_symbol_name =
1425
4
      now_seg->map_head.linked_to_symbol_name;
1426
17
        else
1427
17
    linked_to_section_index =
1428
17
      elf_section_data (now_seg)->this_hdr.sh_link;
1429
21
      }
1430
1431
29.2k
    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.2k
    if ((attr & SHF_GROUP) != 0 && *input_line_pointer == ',')
1438
27
      {
1439
27
        ++input_line_pointer;
1440
27
        SKIP_WHITESPACE ();
1441
27
        if (inherit && *input_line_pointer == ','
1442
5
      && (elf_section_flags (now_seg) & SHF_GROUP) != 0)
1443
5
    goto fetch_group;
1444
22
        match.group_name = obj_elf_section_name ();
1445
22
        if (match.group_name == NULL)
1446
1
    attr &= ~SHF_GROUP;
1447
21
        else if (*input_line_pointer == ',')
1448
4
    {
1449
4
      ++input_line_pointer;
1450
4
      SKIP_WHITESPACE ();
1451
4
      if (startswith (input_line_pointer, "comdat"))
1452
0
        {
1453
0
          input_line_pointer += 6;
1454
0
          linkonce = 1;
1455
0
        }
1456
4
    }
1457
17
        else if (startswith (name, ".gnu.linkonce"))
1458
0
    linkonce = 1;
1459
22
      }
1460
29.2k
    else if ((attr & SHF_GROUP) != 0 && inherit
1461
16
       && (elf_section_flags (now_seg) & SHF_GROUP) != 0)
1462
12
      {
1463
17
      fetch_group:
1464
17
        match.group_name = elf_group_name (now_seg);
1465
17
        linkonce =
1466
17
          (bfd_section_flags (now_seg) & SEC_LINK_ONCE) != 0;
1467
17
      }
1468
29.2k
    else if ((attr & SHF_GROUP) != 0)
1469
16
      {
1470
16
        as_warn (_("group name for SHF_GROUP not specified"));
1471
16
        attr &= ~SHF_GROUP;
1472
16
      }
1473
1474
29.2k
    if (is_clone)
1475
9
      {
1476
9
        const char *now_group = elf_group_name (now_seg);
1477
9
        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
9
      }
1483
1484
29.2k
    if ((gnu_attr & SHF_GNU_MBIND) != 0 && *input_line_pointer == ',')
1485
3
      {
1486
3
        char *save = input_line_pointer;
1487
3
        ++input_line_pointer;
1488
3
        SKIP_WHITESPACE ();
1489
3
        if (ISDIGIT (* input_line_pointer))
1490
3
    {
1491
3
      char *t = input_line_pointer;
1492
3
      match.sh_info = strtoul (input_line_pointer,
1493
3
          &input_line_pointer, 0);
1494
3
      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
3
    }
1500
0
        else
1501
0
    input_line_pointer = save;
1502
3
      }
1503
1504
29.2k
    if ((gnu_attr & SHF_GNU_RETAIN) != 0)
1505
30
      match.sh_flags |= SHF_GNU_RETAIN;
1506
1507
29.2k
    if (*input_line_pointer == ',')
1508
214
      {
1509
214
        char *save = input_line_pointer;
1510
1511
214
        ++input_line_pointer;
1512
214
        SKIP_WHITESPACE ();
1513
214
        if (startswith (input_line_pointer, "unique"))
1514
0
    {
1515
0
      input_line_pointer += 6;
1516
0
      SKIP_WHITESPACE ();
1517
0
      if (*input_line_pointer == ',')
1518
0
        {
1519
0
          ++input_line_pointer;
1520
0
          SKIP_WHITESPACE ();
1521
0
          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
0
        }
1559
0
    }
1560
214
        else
1561
214
    input_line_pointer = save;
1562
214
      }
1563
29.2k
  }
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
29.8k
    }
1592
1593
31.0k
 done:
1594
31.0k
  demand_empty_rest_of_line ();
1595
1596
31.0k
  if ((gnu_attr & (SHF_GNU_MBIND | SHF_GNU_RETAIN)) != 0)
1597
41
    {
1598
41
      bool mbind_p = (gnu_attr & SHF_GNU_MBIND) != 0;
1599
1600
41
      if (mbind_p && (attr & SHF_ALLOC) == 0)
1601
0
  as_bad (_("SHF_ALLOC isn't set for GNU_MBIND section: %s"), name);
1602
1603
41
      if (mbind_p)
1604
13
  elf_tdata (stdoutput)->has_gnu_osabi |= elf_gnu_osabi_mbind;
1605
41
      if ((gnu_attr & SHF_GNU_RETAIN) != 0)
1606
30
  elf_tdata (stdoutput)->has_gnu_osabi |= elf_gnu_osabi_retain;
1607
1608
41
      attr |= gnu_attr;
1609
41
    }
1610
1611
31.0k
  change_section (name, type, attr, entsize, &match, linkonce, push,
1612
31.0k
      new_subsection);
1613
1614
31.0k
  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.0k
}
1621
1622
/* Change to the .bss section.  */
1623
1624
void
1625
obj_elf_bss (int i ATTRIBUTE_UNUSED)
1626
8
{
1627
8
  int temp;
1628
1629
#ifdef md_flush_pending_output
1630
  md_flush_pending_output ();
1631
#endif
1632
1633
8
  obj_elf_section_change_hook ();
1634
1635
8
  temp = get_absolute_expression ();
1636
8
  subseg_set (bss_section, temp);
1637
8
  demand_empty_rest_of_line ();
1638
1639
8
#ifdef md_elf_section_change_hook
1640
8
  md_elf_section_change_hook ();
1641
8
#endif
1642
8
}
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
26
{
1667
#ifdef md_flush_pending_output
1668
  md_flush_pending_output ();
1669
#endif
1670
1671
26
  obj_elf_section_change_hook ();
1672
1673
26
  s_text (i);
1674
1675
26
#ifdef md_elf_section_change_hook
1676
26
  md_elf_section_change_hook ();
1677
26
#endif
1678
26
}
1679
1680
/* Change to the *ABS* section.  */
1681
1682
void
1683
obj_elf_struct (int i)
1684
442
{
1685
#ifdef md_flush_pending_output
1686
  md_flush_pending_output ();
1687
#endif
1688
1689
442
  obj_elf_section_change_hook ();
1690
1691
442
  s_struct (i);
1692
1693
442
#ifdef md_elf_section_change_hook
1694
442
  md_elf_section_change_hook ();
1695
442
#endif
1696
442
}
1697
1698
static void
1699
obj_elf_subsection (int ignore ATTRIBUTE_UNUSED)
1700
3
{
1701
3
  int temp;
1702
1703
#ifdef md_flush_pending_output
1704
  md_flush_pending_output ();
1705
#endif
1706
1707
3
  obj_elf_section_change_hook ();
1708
1709
3
  temp = get_absolute_expression ();
1710
3
  subseg_set (now_seg, temp);
1711
3
  demand_empty_rest_of_line ();
1712
1713
3
#ifdef md_elf_section_change_hook
1714
3
  md_elf_section_change_hook ();
1715
3
#endif
1716
3
}
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
32.6k
{
1724
32.6k
  previous_section = now_seg;
1725
32.6k
  previous_subsection = now_subseg;
1726
32.6k
}
1727
1728
void
1729
obj_elf_previous (int ignore ATTRIBUTE_UNUSED)
1730
17
{
1731
17
  segT new_section;
1732
17
  int new_subsection;
1733
1734
17
  if (previous_section == 0)
1735
1
    {
1736
1
      as_warn (_(".previous without corresponding .section; ignored"));
1737
1
      return;
1738
1
    }
1739
1740
#ifdef md_flush_pending_output
1741
  md_flush_pending_output ();
1742
#endif
1743
1744
16
  new_section = previous_section;
1745
16
  new_subsection = previous_subsection;
1746
16
  obj_elf_section_change_hook ();
1747
1748
16
  subseg_set (new_section, new_subsection);
1749
1750
16
#ifdef md_elf_section_change_hook
1751
16
  md_elf_section_change_hook ();
1752
16
#endif
1753
16
}
1754
1755
static void
1756
obj_elf_popsection (int xxx ATTRIBUTE_UNUSED)
1757
0
{
1758
0
  struct section_stack *top = section_stack;
1759
1760
0
  if (top == NULL)
1761
0
    {
1762
0
      as_warn (_(".popsection without corresponding .pushsection; ignored"));
1763
0
      return;
1764
0
    }
1765
1766
#ifdef md_flush_pending_output
1767
  md_flush_pending_output ();
1768
#endif
1769
1770
0
  section_stack = top->next;
1771
0
  previous_section = top->prev_seg;
1772
0
  previous_subsection = top->prev_subseg;
1773
0
  subseg_set (top->seg, top->subseg);
1774
0
  free (top);
1775
1776
0
#ifdef md_elf_section_change_hook
1777
0
  md_elf_section_change_hook ();
1778
0
#endif
1779
0
}
1780
1781
static void
1782
obj_elf_line (int ignore ATTRIBUTE_UNUSED)
1783
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
27
{
1796
27
  struct elf_versioned_name_list *versioned_name;
1797
27
  const char *p;
1798
1799
58
  for (p = ver + 1; *p == ELF_VER_CHR; p++)
1800
31
    ;
1801
1802
  /* NB: Since some tests in ld/testsuite/ld-elfvers have no version
1803
     names, we have to disable this.  */
1804
27
  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
27
  versioned_name = sy_obj->versioned_name;
1812
1813
27
  switch (p - ver)
1814
27
    {
1815
10
    case 1:
1816
13
    case 2:
1817
13
      break;
1818
14
    case 3:
1819
14
      if (sy_obj->rename)
1820
11
  {
1821
11
    if (strcmp (versioned_name->name, version_name) == 0)
1822
8
      return versioned_name;
1823
3
    else
1824
3
      {
1825
3
        as_bad (_("only one version name with `@@@' is allowed "
1826
3
      "for symbol `%s'"), sym_name);
1827
3
        return NULL;
1828
3
      }
1829
11
  }
1830
3
      sy_obj->rename = true;
1831
3
      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
27
    }
1837
1838
16
  for (;
1839
19
       versioned_name != NULL;
1840
16
       versioned_name = versioned_name->next)
1841
7
    if (strcmp (versioned_name->name, version_name) == 0)
1842
4
      return versioned_name;
1843
1844
  /* Add this versioned name to the head of the list,  */
1845
12
  versioned_name = notes_alloc (sizeof (*versioned_name));
1846
12
  versioned_name->name = notes_strdup (version_name);
1847
12
  versioned_name->next = sy_obj->versioned_name;
1848
12
  sy_obj->versioned_name = versioned_name;
1849
1850
12
  return versioned_name;
1851
16
}
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
64
{
1862
64
  char *name;
1863
64
  const char *sym_name;
1864
64
  char c;
1865
64
  char old_lexat;
1866
64
  symbolS *sym;
1867
64
  struct elf_obj_sy *sy_obj;
1868
64
  char *p;
1869
1870
64
  sym = get_sym_from_input_line_and_check ();
1871
1872
64
  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
64
  ++input_line_pointer;
1880
64
  SKIP_WHITESPACE ();
1881
1882
  /* Temporarily include '@' in symbol names.  */
1883
64
  old_lexat = lex_type[(unsigned char) '@'];
1884
64
  lex_type[(unsigned char) '@'] |= LEX_NAME;
1885
64
  c = get_symbol_name (& name);
1886
64
  lex_type[(unsigned char) '@'] = old_lexat;
1887
64
  sym_name = S_GET_NAME (sym);
1888
1889
64
  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
33
  p = strchr (name, ELF_VER_CHR);
1898
33
  if (p == NULL)
1899
6
    {
1900
6
      as_bad (_("missing version name in `%s' for symbol `%s'"),
1901
6
        name, sym_name);
1902
6
      ignore_rest_of_line ();
1903
6
      return;
1904
6
    }
1905
1906
27
  sy_obj = symbol_get_obj (sym);
1907
27
  if (obj_elf_find_and_add_versioned_name (name, sym_name,
1908
27
             p, sy_obj) == NULL)
1909
3
    {
1910
3
      sy_obj->bad_version = true;
1911
3
      ignore_rest_of_line ();
1912
3
      return;
1913
3
    }
1914
1915
24
  (void) restore_line_pointer (c);
1916
1917
24
  if (*input_line_pointer == ',')
1918
12
    {
1919
12
      char *save = input_line_pointer;
1920
1921
12
      ++input_line_pointer;
1922
12
      SKIP_WHITESPACE ();
1923
12
      if (startswith (input_line_pointer, "local"))
1924
0
  {
1925
0
    input_line_pointer += 5;
1926
0
    sy_obj->visibility = visibility_local;
1927
0
  }
1928
12
      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
12
      else if (startswith (input_line_pointer, "remove"))
1934
9
  {
1935
9
    input_line_pointer += 6;
1936
9
    sy_obj->visibility = visibility_remove;
1937
9
  }
1938
3
      else
1939
3
  input_line_pointer = save;
1940
12
    }
1941
1942
24
  demand_empty_rest_of_line ();
1943
24
}
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
1.11k
{
1952
1.11k
  char *cname, *pname;
1953
1.11k
  symbolS *csym, *psym;
1954
1.11k
  char c;
1955
1.11k
  bool bad = false;
1956
1957
1.11k
  if (*input_line_pointer == '#')
1958
0
    ++input_line_pointer;
1959
1960
1.11k
  c = get_symbol_name (& cname);
1961
1.11k
  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
1.11k
  if (csym == NULL
1968
1.11k
      || symbol_get_frag (csym) == NULL
1969
1.11k
      || symbol_get_value_expression (csym)->X_op != O_constant)
1970
1.11k
    {
1971
1.11k
      as_bad (_("expected `%s' to have already been set for .vtable_inherit"),
1972
1.11k
        cname);
1973
1.11k
      bad = true;
1974
1.11k
    }
1975
1976
1.11k
  restore_line_pointer (c);
1977
1978
1.11k
  SKIP_WHITESPACE ();
1979
1.11k
  if (*input_line_pointer != ',')
1980
1.11k
    {
1981
1.11k
      as_bad (_("expected comma after name in .vtable_inherit"));
1982
1.11k
      ignore_rest_of_line ();
1983
1.11k
      return NULL;
1984
1.11k
    }
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
1.11k
{
2022
1.11k
  static bool warned = false;
2023
2024
1.11k
  if (!warned)
2025
1
    {
2026
1
      warned = true;
2027
1
      as_warn(".vtable_inherit has been deprecated");
2028
1
    }
2029
2030
1.11k
  (void) obj_elf_get_vtable_inherit ();
2031
1.11k
}
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
281
{
2086
#ifdef NEED_ECOFF_DEBUG
2087
  if (ECOFF_DEBUGGING)
2088
    ecoff_read_begin_hook ();
2089
#endif
2090
281
}
2091
2092
void
2093
elf_obj_symbol_new_hook (symbolS *symbolP)
2094
38.4k
{
2095
38.4k
  struct elf_obj_sy *sy_obj;
2096
2097
38.4k
  sy_obj = symbol_get_obj (symbolP);
2098
38.4k
  sy_obj->size = NULL;
2099
38.4k
  sy_obj->versioned_name = NULL;
2100
2101
#ifdef NEED_ECOFF_DEBUG
2102
  if (ECOFF_DEBUGGING)
2103
    ecoff_symbol_new_hook (symbolP);
2104
#endif
2105
38.4k
}
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
4.00k
{
2113
4.00k
  struct elf_obj_sy *srcelf = symbol_get_obj (src);
2114
4.00k
  struct elf_obj_sy *destelf = symbol_get_obj (dest);
2115
4.00k
  if (!destelf->size && S_GET_SIZE (dest) == 0)
2116
4.00k
    {
2117
4.00k
      destelf->size = srcelf->size;
2118
4.00k
      S_SET_SIZE (dest, S_GET_SIZE (src));
2119
4.00k
    }
2120
4.00k
}
2121
2122
void
2123
elf_copy_symbol_attributes (symbolS *dest, symbolS *src)
2124
4.00k
{
2125
4.00k
  elf_copy_symbol_size (dest, src);
2126
  /* Don't copy visibility.  */
2127
4.00k
  S_SET_OTHER (dest, (ELF_ST_VISIBILITY (S_GET_OTHER (dest))
2128
4.00k
          | (S_GET_OTHER (src) & ~ELF_ST_VISIBILITY (-1))));
2129
4.00k
}
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
2
{
2193
2
  char *name;
2194
2
  char c = get_symbol_name (&name);
2195
2
  char *p;
2196
2
  expressionS exp;
2197
2
  symbolS *sym;
2198
2199
2
  p = input_line_pointer;
2200
2
  restore_line_pointer (c);
2201
2
  SKIP_WHITESPACE ();
2202
2
  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
2
  input_line_pointer++;
2211
2
  expression (&exp);
2212
2
  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
2
  *p = 0;
2219
2
  sym = symbol_find_or_make (name);
2220
2
  *p = c;
2221
2
  if (exp.X_op == O_constant)
2222
0
    {
2223
0
      S_SET_SIZE (sym, exp.X_add_number);
2224
0
      symbol_get_obj (sym)->size = NULL;
2225
0
    }
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
2
  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
2
  demand_empty_rest_of_line ();
2239
2
}
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
242
{
2262
242
  char *p;
2263
2264
242
  p = input_line_pointer;
2265
242
  if (*input_line_pointer >= '0'
2266
229
      && *input_line_pointer <= '9')
2267
21
    {
2268
43
      while (*input_line_pointer >= '0'
2269
22
       && *input_line_pointer <= '9')
2270
22
  ++input_line_pointer;
2271
21
      *cp = *input_line_pointer;
2272
21
      *input_line_pointer = '\0';
2273
21
    }
2274
221
  else
2275
221
    *cp = get_symbol_name (&p);
2276
2277
242
  return p;
2278
242
}
2279
2280
static void
2281
obj_elf_type (int ignore ATTRIBUTE_UNUSED)
2282
242
{
2283
242
  char c;
2284
242
  int type;
2285
242
  const char *type_name;
2286
242
  symbolS *sym;
2287
242
  elf_symbol_type *elfsym;
2288
2289
242
  sym = get_sym_from_input_line_and_check ();
2290
242
  c = *input_line_pointer;
2291
242
  elfsym = (elf_symbol_type *) symbol_get_bfdsym (sym);
2292
2293
242
  if (*input_line_pointer == ',')
2294
131
    ++input_line_pointer;
2295
2296
242
  SKIP_WHITESPACE ();
2297
242
  if (   *input_line_pointer == '#'
2298
242
      || *input_line_pointer == '@'
2299
36
      || *input_line_pointer == '"'
2300
36
      || *input_line_pointer == '%')
2301
206
    ++input_line_pointer;
2302
2303
242
  type_name = obj_elf_type_name (& c);
2304
2305
242
  type = 0;
2306
242
  if (strcmp (type_name, "function") == 0
2307
116
      || strcmp (type_name, "2") == 0
2308
116
      || strcmp (type_name, "STT_FUNC") == 0)
2309
126
    type = BSF_FUNCTION;
2310
116
  else if (strcmp (type_name, "object") == 0
2311
116
     || strcmp (type_name, "1") == 0
2312
116
     || strcmp (type_name, "STT_OBJECT") == 0)
2313
0
    type = BSF_OBJECT;
2314
116
  else if (strcmp (type_name, "tls_object") == 0
2315
116
     || strcmp (type_name, "6") == 0
2316
99
     || strcmp (type_name, "STT_TLS") == 0)
2317
36
    type = BSF_OBJECT | BSF_THREAD_LOCAL;
2318
80
  else if (strcmp (type_name, "notype") == 0
2319
80
     || strcmp (type_name, "0") == 0
2320
80
     || strcmp (type_name, "STT_NOTYPE") == 0)
2321
0
    ;
2322
80
  else if (strcmp (type_name, "common") == 0
2323
44
     || strcmp (type_name, "5") == 0
2324
41
     || strcmp (type_name, "STT_COMMON") == 0)
2325
39
    {
2326
39
      type = BSF_OBJECT;
2327
2328
39
      if (! S_IS_COMMON (sym))
2329
38
  {
2330
38
    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
38
    else if (S_IS_DEFINED (sym) || symbol_equated_p (sym))
2340
34
      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
38
  }
2349
39
    }
2350
41
  else if (strcmp (type_name, "gnu_indirect_function") == 0
2351
41
     || strcmp (type_name, "10") == 0
2352
40
     || 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
40
  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
40
  else
2382
40
    as_bad (_("unrecognized symbol type \"%s\""), type_name);
2383
2384
242
  *input_line_pointer = c;
2385
2386
242
  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
242
    {
2393
242
      flagword mask = BSF_FUNCTION | BSF_OBJECT;
2394
2395
242
      if (type != BSF_FUNCTION)
2396
116
  mask |= BSF_GNU_INDIRECT_FUNCTION;
2397
242
      if (type != BSF_OBJECT)
2398
203
  {
2399
203
    mask |= BSF_GNU_UNIQUE | BSF_THREAD_LOCAL;
2400
2401
203
    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
203
  }
2408
2409
      /* Don't warn when changing to STT_NOTYPE.  */
2410
242
      if (type)
2411
202
  {
2412
202
    flagword new = (elfsym->symbol.flags & ~mask) | type;
2413
2414
202
    if (new != (elfsym->symbol.flags | type))
2415
0
      as_warn (_("symbol '%s' already has its type set"), S_GET_NAME (sym));
2416
202
    elfsym->symbol.flags = new;
2417
202
  }
2418
40
      else
2419
40
  elfsym->symbol.flags &= ~mask;
2420
242
    }
2421
2422
242
  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
242
  demand_empty_rest_of_line ();
2433
242
}
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
12
{
2481
12
  char *file;
2482
12
  char *p;
2483
12
  unsigned int stroff;
2484
2485
  /* Force the section to align to a longword boundary.  Without this,
2486
     UnixWare ar crashes.  */
2487
12
  bfd_set_section_alignment (stab, 2);
2488
2489
  /* Make space for this first symbol.  */
2490
12
  p = frag_more (12);
2491
  /* Zero it out.  */
2492
12
  memset (p, 0, 12);
2493
12
  file = remap_debug_filename (as_where (NULL));
2494
12
  stroff = get_stab_string_offset (file, stabstr);
2495
12
  know (stroff == 1 || (stroff == 0 && file[0] == '\0'));
2496
12
  md_number_to_chars (p, stroff, 4);
2497
12
  seg_info (stab)->stabu.p = p;
2498
12
  free (file);
2499
12
}
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
281
{
3018
281
  asection *s;
3019
3020
  /* Add symbols for the known sections to the symbol table.  */
3021
281
  s = bfd_get_section_by_name (stdoutput, TEXT_SECTION_NAME);
3022
281
  symbol_table_insert (section_symbol (s));
3023
281
  s = bfd_get_section_by_name (stdoutput, DATA_SECTION_NAME);
3024
281
  symbol_table_insert (section_symbol (s));
3025
281
  s = bfd_get_section_by_name (stdoutput, BSS_SECTION_NAME);
3026
281
  symbol_table_insert (section_symbol (s));
3027
281
  elf_com_section_ptr = bfd_com_section_ptr;
3028
281
  previous_section = NULL;
3029
281
  previous_subsection = 0;
3030
281
  comment_section = NULL;
3031
281
  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
281
}
3044
3045
void
3046
elf_end (void)
3047
281
{
3048
281
  if (!ENABLE_LEAK_CHECK)
3049
0
    return;
3050
282
  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
281
  if (groups.indexes)
3057
11
    {
3058
11
      htab_delete (groups.indexes);
3059
11
      free (groups.head);
3060
11
    }
3061
3062
#if TC_OBJ_ATTR_v1
3063
  oav1_attr_info_exit ();
3064
#endif /* TC_OBJ_ATTR_v1 */
3065
281
}
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 */