Coverage Report

Created: 2024-05-21 06:29

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