Coverage Report

Created: 2026-04-04 08:16

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/binutils-gdb/gas/dw2gencfi.c
Line
Count
Source
1
/* dw2gencfi.c - Support for generating Dwarf2 CFI information.
2
   Copyright (C) 2003-2026 Free Software Foundation, Inc.
3
   Contributed by Michal Ludvig <mludvig@suse.cz>
4
5
   This file is part of GAS, the GNU Assembler.
6
7
   GAS is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3, or (at your option)
10
   any later version.
11
12
   GAS is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
17
   You should have received a copy of the GNU General Public License
18
   along with GAS; see the file COPYING.  If not, write to the Free
19
   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
20
   02110-1301, USA.  */
21
22
#include "as.h"
23
#include "dw2gencfi.h"
24
#include "subsegs.h"
25
#include "dwarf2dbg.h"
26
#include "gen-sframe.h"
27
28
#ifdef TARGET_USE_CFIPOP
29
30
/* By default, use difference expressions if DIFF_EXPR_OK is defined.  */
31
#ifndef CFI_DIFF_EXPR_OK
32
# ifdef DIFF_EXPR_OK
33
#  define CFI_DIFF_EXPR_OK 1
34
# else
35
#  define CFI_DIFF_EXPR_OK 0
36
# endif
37
#endif
38
39
#ifndef CFI_DIFF_LSDA_OK
40
#define CFI_DIFF_LSDA_OK CFI_DIFF_EXPR_OK
41
#endif
42
43
#if CFI_DIFF_EXPR_OK == 1 && CFI_DIFF_LSDA_OK == 0
44
# error "CFI_DIFF_EXPR_OK should imply CFI_DIFF_LSDA_OK"
45
#endif
46
47
/* We re-use DWARF2_LINE_MIN_INSN_LENGTH for the code alignment field
48
   of the CIE.  Default to 1 if not otherwise specified.  */
49
#ifndef DWARF2_LINE_MIN_INSN_LENGTH
50
152
#define DWARF2_LINE_MIN_INSN_LENGTH 1
51
#endif
52
53
/* By default, use 32-bit relocations from .eh_frame into .text.  */
54
#ifndef DWARF2_FDE_RELOC_SIZE
55
149
#define DWARF2_FDE_RELOC_SIZE 4
56
#endif
57
58
/* By default, use a read-only .eh_frame section.  */
59
#ifndef DWARF2_EH_FRAME_READ_ONLY
60
77
#define DWARF2_EH_FRAME_READ_ONLY SEC_READONLY
61
#endif
62
63
#ifndef EH_FRAME_ALIGNMENT
64
132
#define EH_FRAME_ALIGNMENT (bfd_get_arch_size (stdoutput) == 64 ? 3 : 2)
65
#endif
66
67
342
#define EH_FRAME_LINKONCE (SUPPORT_FRAME_LINKONCE || compact_eh \
68
342
         || TARGET_MULTIPLE_EH_FRAME_SECTIONS)
69
70
#ifndef DWARF2_FORMAT
71
154
#define DWARF2_FORMAT(SEC) dwarf2_format_32bit
72
#endif
73
74
#ifndef DWARF2_ADDR_SIZE
75
#define DWARF2_ADDR_SIZE(bfd) (bfd_arch_bits_per_address (bfd) / 8)
76
#endif
77
78
#if MULTIPLE_FRAME_SECTIONS
79
#define CUR_SEG(structp) structp->cur_seg
80
#define SET_CUR_SEG(structp, seg) structp->cur_seg = seg
81
#define HANDLED(structp) structp->handled
82
#define SET_HANDLED(structp, val) structp->handled = val
83
#else
84
2.28k
#define CUR_SEG(structp) NULL
85
1.41k
#define SET_CUR_SEG(structp, seg) (void) (0 && seg)
86
0
#define HANDLED(structp) 0
87
90
#define SET_HANDLED(structp, val) (void) (0 && val)
88
#endif
89
90
#ifndef tc_cfi_reloc_for_encoding
91
85
#define tc_cfi_reloc_for_encoding(e) BFD_RELOC_NONE
92
#endif
93
94
/* Private segment collection list.  */
95
struct dwcfi_seg_list
96
{
97
  segT   seg;
98
  int    subseg;
99
  char * seg_name;
100
};
101
102
#ifdef SUPPORT_COMPACT_EH
103
static bool compact_eh;
104
#else
105
#define compact_eh 0
106
#endif
107
108
static htab_t dwcfi_hash;
109

110
/* Emit a single byte into the current segment.  */
111
112
static inline void
113
out_one (int byte)
114
1.27k
{
115
1.27k
  FRAG_APPEND_1_CHAR (byte);
116
1.27k
}
117
118
/* Emit a two-byte word into the current segment.  */
119
120
static inline void
121
out_two (int data)
122
0
{
123
0
  md_number_to_chars (frag_more (2), data, 2);
124
0
}
125
126
/* Emit a four byte word into the current segment.  */
127
128
static inline void
129
out_four (int data)
130
76
{
131
76
  md_number_to_chars (frag_more (4), data, 4);
132
76
}
133
134
/* Emit an unsigned "little-endian base 128" number.  */
135
136
static void
137
out_uleb128 (addressT value)
138
1.06k
{
139
1.06k
  output_leb128 (frag_more (sizeof_leb128 (value, 0)), value, 0);
140
1.06k
}
141
142
/* Emit an unsigned "little-endian base 128" number.  */
143
144
static void
145
out_sleb128 (offsetT value)
146
78
{
147
78
  output_leb128 (frag_more (sizeof_leb128 (value, 1)), value, 1);
148
78
}
149
150
static unsigned int
151
encoding_size (unsigned char encoding)
152
235
{
153
235
  if (encoding == DW_EH_PE_omit)
154
221
    return 0;
155
14
  switch (encoding & 0x7)
156
14
    {
157
8
    case 0:
158
8
      return bfd_get_arch_size (stdoutput) == 64 ? 8 : 4;
159
2
    case DW_EH_PE_udata2:
160
2
      return 2;
161
0
    case DW_EH_PE_udata4:
162
0
      return 4;
163
4
    case DW_EH_PE_udata8:
164
4
      return 8;
165
0
    default:
166
0
      abort ();
167
14
    }
168
14
}
169
170
/* Emit expression EXP in ENCODING.  If EMIT_ENCODING is true, first
171
   emit a byte containing ENCODING.  */
172
173
static void
174
emit_expr_encoded (expressionS *exp, int encoding, bool emit_encoding)
175
151
{
176
151
  unsigned int size = encoding_size (encoding);
177
151
  bfd_reloc_code_real_type code;
178
179
151
  if (encoding == DW_EH_PE_omit)
180
144
    return;
181
182
7
  if (emit_encoding)
183
1
    out_one (encoding);
184
185
7
  code = tc_cfi_reloc_for_encoding (encoding);
186
7
  if (code != BFD_RELOC_NONE)
187
0
    {
188
0
      reloc_howto_type *howto = bfd_reloc_type_lookup (stdoutput, code);
189
0
      char *p = frag_more (size);
190
0
      gas_assert (size == (unsigned) howto->bitsize / 8);
191
0
      md_number_to_chars (p, 0, size);
192
0
      fix_new (frag_now, p - frag_now->fr_literal, size, exp->X_add_symbol,
193
0
         exp->X_add_number, howto->pc_relative, code);
194
0
    }
195
7
  else if ((encoding & 0x70) == DW_EH_PE_pcrel)
196
1
    {
197
1
#if CFI_DIFF_EXPR_OK
198
1
      expressionS tmp = *exp;
199
1
      tmp.X_op = O_subtract;
200
1
      tmp.X_op_symbol = symbol_temp_new_now ();
201
1
      emit_expr (&tmp, size);
202
#elif defined (tc_cfi_emit_pcrel_expr)
203
      tc_cfi_emit_pcrel_expr (exp, size);
204
#else
205
      abort ();
206
#endif
207
1
    }
208
6
  else
209
6
    emit_expr (exp, size);
210
7
}
211

212
/* Build based on segment the derived .debug_...
213
   segment name containing origin segment's postfix name part.  */
214
215
static char *
216
get_debugseg_name (segT seg, const char *base_name)
217
0
{
218
0
  const char * name;
219
0
  const char * dollar;
220
0
  const char * dot;
221
222
0
  if (!seg
223
0
      || (name = bfd_section_name (seg)) == NULL
224
0
      || *name == 0)
225
0
    return notes_strdup (base_name);
226
  
227
0
  dollar = strchr (name, '$');
228
0
  dot = strchr (name + 1, '.');
229
230
0
  if (!dollar && !dot)
231
0
    {
232
0
      if (!strcmp (base_name, ".eh_frame_entry")
233
0
    && strcmp (name, ".text") != 0)
234
0
  return notes_concat (base_name, ".", name, (const char *) NULL);
235
236
0
      name = "";
237
0
    }
238
0
  else if (!dollar)
239
0
    name = dot;
240
0
  else if (!dot)
241
0
    name = dollar;
242
0
  else if (dot < dollar)
243
0
    name = dot;
244
0
  else
245
0
    name = dollar;
246
247
0
  return notes_concat (base_name, name, (const char *) NULL);
248
0
}
249
250
/* Allocate a dwcfi_seg_list structure.  */
251
252
static struct dwcfi_seg_list *
253
alloc_debugseg_item (segT seg, int subseg, char *name)
254
0
{
255
0
  struct dwcfi_seg_list *r;
256
257
0
  r = notes_alloc (sizeof (*r) + strlen (name));
258
0
  r->seg = seg;
259
0
  r->subseg = subseg;
260
0
  r->seg_name = name;
261
0
  return r;
262
0
}
263
264
static segT
265
is_now_linkonce_segment (void)
266
0
{
267
0
  if (compact_eh)
268
0
    return now_seg;
269
0
270
0
  if (TARGET_MULTIPLE_EH_FRAME_SECTIONS)
271
0
    return now_seg;
272
0
273
0
  if ((bfd_section_flags (now_seg)
274
0
       & (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD
275
0
    | SEC_LINK_DUPLICATES_ONE_ONLY | SEC_LINK_DUPLICATES_SAME_SIZE
276
0
    | SEC_LINK_DUPLICATES_SAME_CONTENTS)) != 0)
277
0
    return now_seg;
278
0
  return NULL;
279
0
}
280
281
/* Generate debug... segment with same linkonce properties
282
   of based segment.  */
283
284
static segT
285
make_debug_seg (segT cseg, char *name, int sflags)
286
0
{
287
0
  segT save_seg = now_seg;
288
0
  int save_subseg = now_subseg;
289
0
  segT r;
290
0
  flagword flags;
291
292
0
  r = subseg_new (name, 0);
293
294
  /* Check if code segment is marked as linked once.  */
295
0
  if (!cseg)
296
0
    flags = 0;
297
0
  else
298
0
    flags = (bfd_section_flags (cseg)
299
0
       & (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD
300
0
    | SEC_LINK_DUPLICATES_ONE_ONLY | SEC_LINK_DUPLICATES_SAME_SIZE
301
0
    | SEC_LINK_DUPLICATES_SAME_CONTENTS));
302
303
  /* Add standard section flags.  */
304
0
  flags |= sflags;
305
306
  /* Apply possibly linked once flags to new generated segment, too.  */
307
0
  if (!bfd_set_section_flags (r, flags))
308
0
    as_bad (_("bfd_set_section_flags: %s"),
309
0
      bfd_errmsg (bfd_get_error ()));
310
311
  /* Restore to previous segment.  */
312
0
  if (save_seg != NULL)
313
0
    subseg_set (save_seg, save_subseg);
314
0
  return r;
315
0
}
316
317
static struct dwcfi_seg_list *
318
dwcfi_hash_find (char *name)
319
0
{
320
0
  return (struct dwcfi_seg_list *) str_hash_find (dwcfi_hash, name);
321
0
}
322
323
static struct dwcfi_seg_list *
324
dwcfi_hash_find_or_make (segT cseg, const char *base_name, int flags)
325
0
{
326
0
  struct dwcfi_seg_list *item;
327
0
  char *name;
328
329
  /* Initialize dwcfi_hash once.  */
330
0
  if (!dwcfi_hash)
331
0
    dwcfi_hash = str_htab_create ();
332
333
0
  name = get_debugseg_name (cseg, base_name);
334
335
0
  item = dwcfi_hash_find (name);
336
0
  if (!item)
337
0
    {
338
0
      item = alloc_debugseg_item (make_debug_seg (cseg, name, flags), 0, name);
339
340
0
      str_hash_insert (dwcfi_hash, item->seg_name, item, 0);
341
0
    }
342
0
  else
343
0
    notes_free (name);
344
345
0
  return item;
346
0
}
347
348
/* ??? Share this with dwarf2cfg.c.  */
349
#ifndef TC_DWARF2_EMIT_OFFSET
350
5
#define TC_DWARF2_EMIT_OFFSET  generic_dwarf2_emit_offset
351
352
/* Create an offset to .dwarf2_*.  */
353
354
static void
355
generic_dwarf2_emit_offset (symbolS *symbol, unsigned int size)
356
5
{
357
5
  expressionS exp;
358
359
5
  exp.X_op = O_symbol;
360
5
  exp.X_add_symbol = symbol;
361
5
  exp.X_add_number = 0;
362
5
  emit_expr (&exp, size);
363
5
}
364
#endif
365
366
struct cie_entry
367
{
368
  struct cie_entry *next;
369
#if MULTIPLE_FRAME_SECTIONS
370
  segT cur_seg;
371
#endif
372
  symbolS *start_address;
373
  unsigned int return_column;
374
  unsigned int signal_frame;
375
  unsigned char fde_encoding;
376
  unsigned char per_encoding;
377
  unsigned char lsda_encoding;
378
  expressionS personality;
379
#ifdef tc_cie_entry_extras
380
  tc_cie_entry_extras
381
#endif
382
  struct cfi_insn_data *first, *last;
383
};
384
385
/* List of FDE entries.  */
386
387
struct fde_entry *all_fde_data;
388
static struct fde_entry **last_fde_data = &all_fde_data;
389
390
/* List of CIEs so that they could be reused.  */
391
static struct cie_entry *cie_root;
392
393
/* Construct a new FDE structure and add it to the end of the fde list.  */
394
395
static struct fde_entry *
396
alloc_fde_entry (void)
397
90
{
398
90
  struct fde_entry *fde = notes_calloc (1, sizeof (*fde));
399
400
90
  frchain_now->frch_cfi_data = notes_calloc (1, sizeof (struct frch_cfi_data));
401
90
  frchain_now->frch_cfi_data->cur_fde_data = fde;
402
90
  *last_fde_data = fde;
403
90
  last_fde_data = &fde->next;
404
90
  SET_CUR_SEG (fde, is_now_linkonce_segment ());
405
90
  SET_HANDLED (fde, 0);
406
90
  fde->last = &fde->data;
407
90
  fde->return_column = DWARF2_DEFAULT_RETURN_COLUMN;
408
90
  fde->per_encoding = DW_EH_PE_omit;
409
90
  fde->lsda_encoding = DW_EH_PE_omit;
410
90
  fde->eh_header_type = EH_COMPACT_UNKNOWN;
411
#ifdef tc_fde_entry_init_extra
412
  tc_fde_entry_init_extra (fde);
413
#endif
414
415
90
  return fde;
416
90
}
417
418
/* The following functions are available for a backend to construct its
419
   own unwind information, usually from legacy unwind directives.  */
420
421
/* Construct a new INSN structure and add it to the end of the insn list
422
   for the currently active FDE.  */
423
424
static bool cfi_sections_set = false;
425
static int cfi_sections = CFI_EMIT_eh_frame;
426
int all_cfi_sections = 0;
427
static struct fde_entry *last_fde;
428
429
static struct cfi_insn_data *
430
alloc_cfi_insn_data (void)
431
1.25k
{
432
1.25k
  struct cfi_insn_data *insn = notes_calloc (1, sizeof (*insn));
433
1.25k
  struct fde_entry *cur_fde_data = frchain_now->frch_cfi_data->cur_fde_data;
434
435
1.25k
  *cur_fde_data->last = insn;
436
1.25k
  cur_fde_data->last = &insn->next;
437
1.25k
  SET_CUR_SEG (insn, is_now_linkonce_segment ());
438
1.25k
#ifndef NO_LISTING
439
1.25k
  insn->listing_ctxt = cur_fde_data->listing_ctxt ? listing_tail : NULL;
440
1.25k
#endif
441
1.25k
  return insn;
442
1.25k
}
443
444
/* Construct a new FDE structure that begins at LABEL.  */
445
446
void
447
cfi_new_fde (symbolS *label, bool do_listing)
448
90
{
449
90
  struct fde_entry *fde = alloc_fde_entry ();
450
90
  fde->start_address = label;
451
90
  if (do_listing)
452
0
    {
453
0
#ifndef NO_LISTING
454
0
      fde->listing_ctxt = listing_tail;
455
0
#endif
456
0
    }
457
90
  frchain_now->frch_cfi_data->last_address = label;
458
90
}
459
460
/* End the currently open FDE.  */
461
462
void
463
cfi_end_fde (symbolS *label)
464
0
{
465
0
  struct fde_entry *cur_fde_data = frchain_now->frch_cfi_data->cur_fde_data;
466
467
0
  cur_fde_data->end_address = label;
468
0
#ifndef NO_LISTING
469
0
  cur_fde_data->listing_end = cur_fde_data->listing_ctxt ? listing_tail : NULL;
470
0
#endif
471
0
  frchain_now->frch_cfi_data = NULL;
472
0
}
473
474
/* Set the last FDE  .*/
475
void
476
cfi_set_last_fde (struct fde_entry *fde)
477
0
{
478
0
  last_fde = fde;
479
0
}
480
481
/* Set the return column for the current FDE.  */
482
483
void
484
cfi_set_return_column (unsigned regno)
485
0
{
486
0
  frchain_now->frch_cfi_data->cur_fde_data->return_column = regno;
487
0
}
488
489
void
490
cfi_set_sections (void)
491
90
{
492
90
  all_cfi_sections |= cfi_sections;
493
90
  frchain_now->frch_cfi_data->cur_fde_data->sections = all_cfi_sections;
494
90
  cfi_sections_set = true;
495
90
}
496
497
/* Universal functions to store new instructions.  */
498
499
static void
500
cfi_add_CFA_insn (int insn)
501
9
{
502
9
  struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data ();
503
504
9
  insn_ptr->insn = insn;
505
9
}
506
507
static void
508
cfi_add_CFA_insn_reg (int insn, unsigned regno)
509
631
{
510
631
  struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data ();
511
512
631
  insn_ptr->insn = insn;
513
631
  insn_ptr->u.r = regno;
514
631
}
515
516
static void
517
cfi_add_CFA_insn_offset (int insn, offsetT offset)
518
0
{
519
0
  struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data ();
520
521
0
  insn_ptr->insn = insn;
522
0
  insn_ptr->u.i = offset;
523
0
}
524
525
static void
526
cfi_add_CFA_insn_reg_reg (int insn, unsigned reg1, unsigned reg2)
527
3
{
528
3
  struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data ();
529
530
3
  insn_ptr->insn = insn;
531
3
  insn_ptr->u.rr.reg1 = reg1;
532
3
  insn_ptr->u.rr.reg2 = reg2;
533
3
}
534
535
static void
536
cfi_add_CFA_insn_reg_offset (int insn, unsigned regno, offsetT offset)
537
234
{
538
234
  struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data ();
539
540
234
  insn_ptr->insn = insn;
541
234
  insn_ptr->u.ri.reg = regno;
542
234
  insn_ptr->u.ri.offset = offset;
543
234
}
544
545
/* Add a CFI insn to advance the PC from the last address to LABEL.  */
546
547
void
548
cfi_add_advance_loc (symbolS *label)
549
94
{
550
94
  struct cfi_insn_data *insn = alloc_cfi_insn_data ();
551
552
94
  insn->insn = DW_CFA_advance_loc;
553
94
  insn->u.ll.lab1 = frchain_now->frch_cfi_data->last_address;
554
94
  insn->u.ll.lab2 = label;
555
556
94
  frchain_now->frch_cfi_data->last_address = label;
557
94
}
558
559
/* Add a CFI insn to label the current position in the CFI segment.  */
560
561
void
562
cfi_add_label (const char *name)
563
28
{
564
28
  struct cfi_insn_data *insn = alloc_cfi_insn_data ();
565
566
28
  insn->insn = CFI_label;
567
28
  insn->u.sym_name = notes_strdup (name);
568
28
}
569
570
/* Add a DW_CFA_offset record to the CFI data.  */
571
572
void
573
cfi_add_CFA_offset (unsigned regno, offsetT offset)
574
122
{
575
122
  unsigned int abs_data_align;
576
577
122
  gas_assert (DWARF2_CIE_DATA_ALIGNMENT != 0);
578
122
  cfi_add_CFA_insn_reg_offset (DW_CFA_offset, regno, offset);
579
580
122
  abs_data_align = (DWARF2_CIE_DATA_ALIGNMENT < 0
581
122
        ? -DWARF2_CIE_DATA_ALIGNMENT : DWARF2_CIE_DATA_ALIGNMENT);
582
122
  if (offset % abs_data_align)
583
1
    as_bad (_("register save offset not a multiple of %u"), abs_data_align);
584
122
}
585
586
/* Add a DW_CFA_val_offset record to the CFI data.  */
587
588
void
589
cfi_add_CFA_val_offset (unsigned regno, offsetT offset)
590
0
{
591
0
  unsigned int abs_data_align;
592
593
0
  gas_assert (DWARF2_CIE_DATA_ALIGNMENT != 0);
594
0
  cfi_add_CFA_insn_reg_offset (DW_CFA_val_offset, regno, offset);
595
596
0
  abs_data_align = (DWARF2_CIE_DATA_ALIGNMENT < 0
597
0
        ? -DWARF2_CIE_DATA_ALIGNMENT : DWARF2_CIE_DATA_ALIGNMENT);
598
0
  if (offset % abs_data_align)
599
0
    as_bad (_("register save offset not a multiple of %u"), abs_data_align);
600
0
}
601
602
/* Add a DW_CFA_def_cfa record to the CFI data.  */
603
604
void
605
cfi_add_CFA_def_cfa (unsigned regno, offsetT offset)
606
112
{
607
112
  cfi_add_CFA_insn_reg_offset (DW_CFA_def_cfa, regno, offset);
608
112
  frchain_now->frch_cfi_data->cur_cfa_offset = offset;
609
112
}
610
611
/* Add a DW_CFA_register record to the CFI data.  */
612
613
void
614
cfi_add_CFA_register (unsigned reg1, unsigned reg2)
615
3
{
616
3
  cfi_add_CFA_insn_reg_reg (DW_CFA_register, reg1, reg2);
617
3
}
618
619
/* Add a DW_CFA_def_cfa_register record to the CFI data.  */
620
621
void
622
cfi_add_CFA_def_cfa_register (unsigned regno)
623
13
{
624
13
  cfi_add_CFA_insn_reg (DW_CFA_def_cfa_register, regno);
625
13
}
626
627
/* Add a DW_CFA_def_cfa_offset record to the CFI data.  */
628
629
void
630
cfi_add_CFA_def_cfa_offset (offsetT offset)
631
0
{
632
0
  cfi_add_CFA_insn_offset (DW_CFA_def_cfa_offset, offset);
633
0
  frchain_now->frch_cfi_data->cur_cfa_offset = offset;
634
0
}
635
636
void
637
cfi_add_CFA_restore (unsigned regno)
638
40
{
639
40
  cfi_add_CFA_insn_reg (DW_CFA_restore, regno);
640
40
}
641
642
void
643
cfi_add_CFA_undefined (unsigned regno)
644
578
{
645
578
  cfi_add_CFA_insn_reg (DW_CFA_undefined, regno);
646
578
}
647
648
void
649
cfi_add_CFA_same_value (unsigned regno)
650
0
{
651
0
  cfi_add_CFA_insn_reg (DW_CFA_same_value, regno);
652
0
}
653
654
void
655
cfi_add_CFA_remember_state (void)
656
0
{
657
0
  struct cfa_save_data *p;
658
659
0
  cfi_add_CFA_insn (DW_CFA_remember_state);
660
661
0
  p = notes_alloc (sizeof (*p));
662
0
  p->cfa_offset = frchain_now->frch_cfi_data->cur_cfa_offset;
663
0
  p->next = frchain_now->frch_cfi_data->cfa_save_stack;
664
0
  frchain_now->frch_cfi_data->cfa_save_stack = p;
665
0
}
666
667
void
668
cfi_add_CFA_restore_state (void)
669
0
{
670
0
  struct cfa_save_data *p;
671
672
0
  cfi_add_CFA_insn (DW_CFA_restore_state);
673
674
0
  p = frchain_now->frch_cfi_data->cfa_save_stack;
675
0
  if (p)
676
0
    {
677
0
      frchain_now->frch_cfi_data->cur_cfa_offset = p->cfa_offset;
678
0
      frchain_now->frch_cfi_data->cfa_save_stack = p->next;
679
0
    }
680
0
  else
681
0
    as_bad (_("CFI state restore without previous remember"));
682
0
}
683
684

685
/* Parse CFI assembler directives.  */
686
687
static void dot_cfi (int);
688
static void dot_cfi_escape (int);
689
static void dot_cfi_startproc (int);
690
static void dot_cfi_endproc (int);
691
static void dot_cfi_fde_data (int);
692
static void dot_cfi_personality (int);
693
static void dot_cfi_personality_id (int);
694
static void dot_cfi_lsda (int);
695
static void dot_cfi_val_encoded_addr (int);
696
static void dot_cfi_inline_lsda (int);
697
static void dot_cfi_label (int);
698
699
const pseudo_typeS cfi_pseudo_table[] =
700
  {
701
    { "cfi_sections", dot_cfi_sections, 0 },
702
    { "cfi_startproc", dot_cfi_startproc, 0 },
703
    { "cfi_endproc", dot_cfi_endproc, 0 },
704
    { "cfi_fde_data", dot_cfi_fde_data, 0 },
705
    { "cfi_def_cfa", dot_cfi, DW_CFA_def_cfa },
706
    { "cfi_def_cfa_register", dot_cfi, DW_CFA_def_cfa_register },
707
    { "cfi_def_cfa_offset", dot_cfi, DW_CFA_def_cfa_offset },
708
    { "cfi_adjust_cfa_offset", dot_cfi, CFI_adjust_cfa_offset },
709
    { "cfi_offset", dot_cfi, DW_CFA_offset },
710
    { "cfi_rel_offset", dot_cfi, CFI_rel_offset },
711
    { "cfi_register", dot_cfi, DW_CFA_register },
712
    { "cfi_return_column", dot_cfi, CFI_return_column },
713
    { "cfi_restore", dot_cfi, DW_CFA_restore },
714
    { "cfi_undefined", dot_cfi, DW_CFA_undefined },
715
    { "cfi_same_value", dot_cfi, DW_CFA_same_value },
716
    { "cfi_remember_state", dot_cfi, DW_CFA_remember_state },
717
    { "cfi_restore_state", dot_cfi, DW_CFA_restore_state },
718
    { "cfi_window_save", dot_cfi, DW_CFA_GNU_window_save },
719
    { "cfi_negate_ra_state", dot_cfi, DW_CFA_AARCH64_negate_ra_state },
720
    { "cfi_negate_ra_state_with_pc", dot_cfi, DW_CFA_AARCH64_negate_ra_state_with_pc },
721
    { "cfi_escape", dot_cfi_escape, 0 },
722
    { "cfi_signal_frame", dot_cfi, CFI_signal_frame },
723
    { "cfi_personality", dot_cfi_personality, 0 },
724
    { "cfi_personality_id", dot_cfi_personality_id, 0 },
725
    { "cfi_lsda", dot_cfi_lsda, 0 },
726
    { "cfi_val_encoded_addr", dot_cfi_val_encoded_addr, 0 },
727
    { "cfi_inline_lsda", dot_cfi_inline_lsda, 0 },
728
    { "cfi_label", dot_cfi_label, 0 },
729
    { "cfi_val_offset", dot_cfi, DW_CFA_val_offset },
730
    { NULL, NULL, 0 }
731
  };
732
733
static void
734
cfi_parse_separator (void)
735
139
{
736
139
  SKIP_WHITESPACE ();
737
139
  if (*input_line_pointer == ',')
738
37
    input_line_pointer++;
739
102
  else
740
102
    as_bad (_("missing separator"));
741
139
}
742
743
#ifndef tc_parse_to_dw2regnum
744
static void
745
tc_parse_to_dw2regnum (expressionS *exp)
746
{
747
# ifdef tc_regname_to_dw2regnum
748
  SKIP_WHITESPACE ();
749
  if (is_name_beginner (*input_line_pointer)
750
      || (*input_line_pointer == '%'
751
    && is_name_beginner (*++input_line_pointer)))
752
    {
753
      char *name, c;
754
755
      c = get_symbol_name (& name);
756
757
      exp->X_op = O_constant;
758
      exp->X_add_number = tc_regname_to_dw2regnum (name);
759
760
      restore_line_pointer (c);
761
    }
762
  else
763
# endif
764
    expression_and_evaluate (exp);
765
}
766
#endif
767
768
static unsigned
769
cfi_parse_reg (void)
770
732
{
771
732
  int regno;
772
732
  expressionS exp;
773
774
732
  tc_parse_to_dw2regnum (&exp);
775
732
  switch (exp.X_op)
776
732
    {
777
0
    case O_register:
778
101
    case O_constant:
779
101
      regno = exp.X_add_number;
780
101
      break;
781
782
631
    default:
783
631
      regno = -1;
784
631
      break;
785
732
    }
786
787
732
  if (regno < 0)
788
631
    {
789
631
      as_bad (_("bad register expression"));
790
631
      regno = 0;
791
631
    }
792
793
732
  return regno;
794
732
}
795
796
static offsetT
797
cfi_parse_const (void)
798
165
{
799
165
  return get_absolute_expression ();
800
165
}
801
802
static void
803
dot_cfi (int arg)
804
167
{
805
167
  offsetT offset;
806
167
  unsigned reg1, reg2;
807
808
167
  if (frchain_now->frch_cfi_data == NULL)
809
5
    {
810
5
      as_bad (_("CFI instruction used without previous .cfi_startproc"));
811
5
      ignore_rest_of_line ();
812
5
      return;
813
5
    }
814
815
  /* If the last address was not at the current PC, advance to current.  */
816
162
  if (symbol_get_frag (frchain_now->frch_cfi_data->last_address) != frag_now
817
141
      || (S_GET_VALUE (frchain_now->frch_cfi_data->last_address)
818
141
    != frag_now_fix ()))
819
38
    cfi_add_advance_loc (symbol_temp_new_now ());
820
821
162
  switch (arg)
822
162
    {
823
8
    case DW_CFA_offset:
824
8
      reg1 = cfi_parse_reg ();
825
8
      cfi_parse_separator ();
826
8
      offset = cfi_parse_const ();
827
8
      cfi_add_CFA_offset (reg1, offset);
828
8
      break;
829
830
0
    case DW_CFA_val_offset:
831
0
      reg1 = cfi_parse_reg ();
832
0
      cfi_parse_separator ();
833
0
      offset = cfi_parse_const ();
834
0
      cfi_add_CFA_val_offset (reg1, offset);
835
0
      break;
836
837
24
    case CFI_rel_offset:
838
24
      reg1 = cfi_parse_reg ();
839
24
      cfi_parse_separator ();
840
24
      offset = cfi_parse_const ();
841
24
      cfi_add_CFA_offset (reg1,
842
24
        offset - frchain_now->frch_cfi_data->cur_cfa_offset);
843
24
      break;
844
845
22
    case DW_CFA_def_cfa:
846
22
      reg1 = cfi_parse_reg ();
847
22
      cfi_parse_separator ();
848
22
      offset = cfi_parse_const ();
849
22
      cfi_add_CFA_def_cfa (reg1, offset);
850
22
      break;
851
852
3
    case DW_CFA_register:
853
3
      reg1 = cfi_parse_reg ();
854
3
      cfi_parse_separator ();
855
3
      reg2 = cfi_parse_reg ();
856
3
      cfi_add_CFA_register (reg1, reg2);
857
3
      break;
858
859
13
    case DW_CFA_def_cfa_register:
860
13
      reg1 = cfi_parse_reg ();
861
13
      cfi_add_CFA_def_cfa_register (reg1);
862
13
      break;
863
864
0
    case DW_CFA_def_cfa_offset:
865
0
      offset = cfi_parse_const ();
866
0
      cfi_add_CFA_def_cfa_offset (offset);
867
0
      break;
868
869
0
    case CFI_adjust_cfa_offset:
870
0
      offset = cfi_parse_const ();
871
0
      cfi_add_CFA_def_cfa_offset (frchain_now->frch_cfi_data->cur_cfa_offset
872
0
          + offset);
873
0
      break;
874
875
37
    case DW_CFA_restore:
876
37
      for (;;)
877
40
  {
878
40
    reg1 = cfi_parse_reg ();
879
40
    cfi_add_CFA_restore (reg1);
880
40
    SKIP_WHITESPACE ();
881
40
    if (*input_line_pointer != ',')
882
37
      break;
883
3
    ++input_line_pointer;
884
3
  }
885
37
      break;
886
887
46
    case DW_CFA_undefined:
888
46
      for (;;)
889
578
  {
890
578
    reg1 = cfi_parse_reg ();
891
578
    cfi_add_CFA_undefined (reg1);
892
578
    SKIP_WHITESPACE ();
893
578
    if (*input_line_pointer != ',')
894
46
      break;
895
532
    ++input_line_pointer;
896
532
  }
897
46
      break;
898
899
0
    case DW_CFA_same_value:
900
0
      reg1 = cfi_parse_reg ();
901
0
      cfi_add_CFA_same_value (reg1);
902
0
      break;
903
904
0
    case CFI_return_column:
905
0
      reg1 = cfi_parse_reg ();
906
0
      cfi_set_return_column (reg1);
907
0
      break;
908
909
0
    case DW_CFA_remember_state:
910
0
      cfi_add_CFA_remember_state ();
911
0
      break;
912
913
0
    case DW_CFA_restore_state:
914
0
      cfi_add_CFA_restore_state ();
915
0
      break;
916
917
9
    case DW_CFA_GNU_window_save:
918
9
      cfi_add_CFA_insn (DW_CFA_GNU_window_save);
919
9
      break;
920
921
0
    case DW_CFA_AARCH64_negate_ra_state_with_pc:
922
0
      cfi_add_CFA_insn (DW_CFA_AARCH64_negate_ra_state_with_pc);
923
0
      break;
924
925
0
    case CFI_signal_frame:
926
0
      frchain_now->frch_cfi_data->cur_fde_data->signal_frame = 1;
927
0
      break;
928
929
0
    default:
930
0
      abort ();
931
162
    }
932
933
162
  demand_empty_rest_of_line ();
934
162
}
935
936
#ifndef TC_ADDRESS_BYTES
937
#define TC_ADDRESS_BYTES address_bytes
938
939
static inline unsigned int
940
address_bytes (void)
941
{
942
  /* Choose smallest of 1, 2, 4, 8 bytes that is large enough to
943
     contain an address.  */
944
  unsigned int n = (stdoutput->arch_info->bits_per_address - 1) / 8;
945
  n |= n >> 1;
946
  n |= n >> 2;
947
  return n + 1;
948
}
949
#endif
950
951
static void
952
dot_cfi_escape (int ignored ATTRIBUTE_UNUSED)
953
437
{
954
437
  struct cfi_escape_data *head, **tail;
955
437
  struct cfi_insn_data *insn;
956
957
437
  if (frchain_now->frch_cfi_data == NULL)
958
227
    {
959
227
      as_bad (_("CFI instruction used without previous .cfi_startproc"));
960
227
      ignore_rest_of_line ();
961
227
      return;
962
227
    }
963
964
  /* If the last address was not at the current PC, advance to current.  */
965
210
  if (symbol_get_frag (frchain_now->frch_cfi_data->last_address) != frag_now
966
210
      || (S_GET_VALUE (frchain_now->frch_cfi_data->last_address)
967
210
    != frag_now_fix ()))
968
35
    cfi_add_advance_loc (symbol_temp_new_now ());
969
970
210
  tail = &head;
971
210
  do
972
411
    {
973
411
      struct cfi_escape_data *e = notes_alloc (sizeof (*e));
974
411
      char *id, *ilp_save = input_line_pointer;
975
411
      char c = get_symbol_name (&id);
976
977
411
      if (strcmp (id, "sleb128") == 0)
978
0
  e->type = CFI_ESC_sleb128;
979
411
      else if (strcmp (id, "uleb128") == 0)
980
0
  e->type = CFI_ESC_uleb128;
981
411
      else if (strcmp (id, "data2") == 0)
982
0
  e->type = 2;
983
411
      else if (TC_ADDRESS_BYTES () >= 4 && strcmp (id, "data4") == 0)
984
3
  e->type = 4;
985
408
      else if (TC_ADDRESS_BYTES () >= 8 && strcmp (id, "data8") == 0)
986
195
  e->type = 8;
987
213
      else if (strcmp (id, "addr") == 0)
988
0
  e->type = TC_ADDRESS_BYTES ();
989
213
      else
990
213
  e->type = CFI_ESC_byte;
991
992
411
      c = restore_line_pointer (c);
993
994
411
      if (e->type != CFI_ESC_byte)
995
198
  {
996
198
    if (is_whitespace (c))
997
0
      c = *++input_line_pointer;
998
198
    if (c != '(')
999
198
      e->type = CFI_ESC_byte;
1000
198
  }
1001
411
      if (e->type == CFI_ESC_byte)
1002
411
  input_line_pointer = ilp_save;
1003
1004
411
      if (e->type == CFI_ESC_sleb128 || e->type == CFI_ESC_uleb128)
1005
0
  {
1006
    /* We're still at the opening parenthesis.  Leave it to expression()
1007
       to parse it and find the matching closing one.  */
1008
0
    expression (&e->exp);
1009
0
    e->reloc = TC_PARSE_CONS_RETURN_NONE;
1010
0
  }
1011
411
      else
1012
411
  {
1013
    /* We may still be at an opening parenthesis.  Leave it to expression()
1014
       to parse it and find the matching closing one.  */
1015
411
    e->reloc = do_parse_cons_expression (&e->exp, e->type);
1016
411
  }
1017
1018
411
      *tail = e;
1019
411
      tail = &e->next;
1020
411
    }
1021
411
  while (*input_line_pointer++ == ',');
1022
210
  *tail = NULL;
1023
1024
210
  insn = alloc_cfi_insn_data ();
1025
210
  insn->insn = CFI_escape;
1026
210
  insn->u.esc = head;
1027
1028
210
  --input_line_pointer;
1029
210
  demand_empty_rest_of_line ();
1030
210
}
1031
1032
static void
1033
dot_cfi_personality (int ignored ATTRIBUTE_UNUSED)
1034
4
{
1035
4
  struct fde_entry *fde;
1036
4
  offsetT encoding;
1037
1038
4
  if (frchain_now->frch_cfi_data == NULL)
1039
0
    {
1040
0
      as_bad (_("CFI instruction used without previous .cfi_startproc"));
1041
0
      ignore_rest_of_line ();
1042
0
      return;
1043
0
    }
1044
1045
4
  fde = frchain_now->frch_cfi_data->cur_fde_data;
1046
4
  encoding = cfi_parse_const ();
1047
4
  if (encoding == DW_EH_PE_omit)
1048
0
    {
1049
0
      demand_empty_rest_of_line ();
1050
0
      fde->per_encoding = encoding;
1051
0
      return;
1052
0
    }
1053
1054
4
  if ((encoding & 0xff) != encoding
1055
4
      || ((((encoding & 0x70) != 0
1056
0
#if CFI_DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr
1057
0
      && (encoding & 0x70) != DW_EH_PE_pcrel
1058
4
#endif
1059
4
      )
1060
     /* leb128 can be handled, but does something actually need it?  */
1061
4
     || (encoding & 7) == DW_EH_PE_uleb128
1062
4
     || (encoding & 7) > DW_EH_PE_udata8)
1063
0
    && tc_cfi_reloc_for_encoding (encoding) == BFD_RELOC_NONE))
1064
0
    {
1065
0
      as_bad (_("invalid or unsupported encoding in .cfi_personality"));
1066
0
      ignore_rest_of_line ();
1067
0
      return;
1068
0
    }
1069
1070
4
  if (*input_line_pointer++ != ',')
1071
0
    {
1072
0
      as_bad (_(".cfi_personality requires encoding and symbol arguments"));
1073
0
      ignore_rest_of_line ();
1074
0
      return;
1075
0
    }
1076
1077
4
  expression_and_evaluate (&fde->personality);
1078
4
  switch (fde->personality.X_op)
1079
4
    {
1080
0
    case O_symbol:
1081
0
      break;
1082
2
    case O_constant:
1083
2
      if ((encoding & 0x70) == DW_EH_PE_pcrel)
1084
0
  encoding = DW_EH_PE_omit;
1085
2
      break;
1086
2
    default:
1087
2
      encoding = DW_EH_PE_omit;
1088
2
      break;
1089
4
    }
1090
1091
4
  fde->per_encoding = encoding;
1092
1093
4
  if (encoding == DW_EH_PE_omit)
1094
2
    {
1095
2
      as_bad (_("wrong second argument to .cfi_personality"));
1096
2
      ignore_rest_of_line ();
1097
2
      return;
1098
2
    }
1099
1100
2
  demand_empty_rest_of_line ();
1101
2
}
1102
1103
static void
1104
dot_cfi_lsda (int ignored ATTRIBUTE_UNUSED)
1105
85
{
1106
85
  struct fde_entry *fde;
1107
85
  offsetT encoding;
1108
1109
85
  if (frchain_now->frch_cfi_data == NULL)
1110
19
    {
1111
19
      as_bad (_("CFI instruction used without previous .cfi_startproc"));
1112
19
      ignore_rest_of_line ();
1113
19
      return;
1114
19
    }
1115
1116
66
  fde = frchain_now->frch_cfi_data->cur_fde_data;
1117
66
  encoding = cfi_parse_const ();
1118
66
  if (encoding == DW_EH_PE_omit)
1119
0
    {
1120
0
      demand_empty_rest_of_line ();
1121
0
      fde->lsda_encoding = encoding;
1122
0
      return;
1123
0
    }
1124
1125
66
  if ((encoding & 0xff) != encoding
1126
64
      || ((((encoding & 0x70) != 0
1127
23
#if CFI_DIFF_LSDA_OK || defined tc_cfi_emit_pcrel_expr
1128
23
      && (encoding & 0x70) != DW_EH_PE_pcrel
1129
64
#endif
1130
64
      )
1131
     /* leb128 can be handled, but does something actually need it?  */
1132
64
     || (encoding & 7) == DW_EH_PE_uleb128
1133
55
     || (encoding & 7) > DW_EH_PE_udata8)
1134
0
    && tc_cfi_reloc_for_encoding (encoding) == BFD_RELOC_NONE))
1135
11
    {
1136
11
      as_bad (_("invalid or unsupported encoding in .cfi_lsda"));
1137
11
      ignore_rest_of_line ();
1138
11
      return;
1139
11
    }
1140
1141
55
  if (*input_line_pointer++ != ',')
1142
35
    {
1143
35
      as_bad (_(".cfi_lsda requires encoding and symbol arguments"));
1144
35
      ignore_rest_of_line ();
1145
35
      return;
1146
35
    }
1147
1148
20
  fde->lsda_encoding = encoding;
1149
1150
20
  expression_and_evaluate (&fde->lsda);
1151
20
  switch (fde->lsda.X_op)
1152
20
    {
1153
5
    case O_symbol:
1154
5
      break;
1155
15
    case O_constant:
1156
15
      if ((encoding & 0x70) == DW_EH_PE_pcrel)
1157
0
  encoding = DW_EH_PE_omit;
1158
15
      break;
1159
0
    default:
1160
0
      encoding = DW_EH_PE_omit;
1161
0
      break;
1162
20
    }
1163
1164
20
  fde->lsda_encoding = encoding;
1165
1166
20
  if (encoding == DW_EH_PE_omit)
1167
0
    {
1168
0
      as_bad (_("wrong second argument to .cfi_lsda"));
1169
0
      ignore_rest_of_line ();
1170
0
      return;
1171
0
    }
1172
1173
20
  demand_empty_rest_of_line ();
1174
20
}
1175
1176
static void
1177
dot_cfi_val_encoded_addr (int ignored ATTRIBUTE_UNUSED)
1178
41
{
1179
41
  struct cfi_insn_data *insn_ptr;
1180
41
  offsetT encoding;
1181
1182
41
  if (frchain_now->frch_cfi_data == NULL)
1183
0
    {
1184
0
      as_bad (_("CFI instruction used without previous .cfi_startproc"));
1185
0
      ignore_rest_of_line ();
1186
0
      return;
1187
0
    }
1188
1189
  /* If the last address was not at the current PC, advance to current.  */
1190
41
  if (symbol_get_frag (frchain_now->frch_cfi_data->last_address) != frag_now
1191
41
      || (S_GET_VALUE (frchain_now->frch_cfi_data->last_address)
1192
41
    != frag_now_fix ()))
1193
2
    cfi_add_advance_loc (symbol_temp_new_now ());
1194
1195
41
  insn_ptr = alloc_cfi_insn_data ();
1196
41
  insn_ptr->insn = CFI_val_encoded_addr;
1197
1198
41
  insn_ptr->u.ea.reg = cfi_parse_reg ();
1199
1200
41
  cfi_parse_separator ();
1201
41
  encoding = cfi_parse_const ();
1202
41
  if ((encoding & 0xff) != encoding
1203
28
      || ((encoding & 0x70) != 0
1204
2
#if CFI_DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr
1205
2
    && (encoding & 0x70) != DW_EH_PE_pcrel
1206
28
#endif
1207
28
    )
1208
      /* leb128 can be handled, but does something actually need it?  */
1209
28
      || (encoding & 7) == DW_EH_PE_uleb128
1210
28
      || (encoding & 7) > DW_EH_PE_udata8)
1211
13
    {
1212
13
      as_bad (_("invalid or unsupported encoding in .cfi_lsda"));
1213
13
      encoding = DW_EH_PE_omit;
1214
13
    }
1215
1216
41
  cfi_parse_separator ();
1217
41
  expression_and_evaluate (&insn_ptr->u.ea.exp);
1218
41
  switch (insn_ptr->u.ea.exp.X_op)
1219
41
    {
1220
16
    case O_symbol:
1221
16
      break;
1222
2
    case O_constant:
1223
2
      if ((encoding & 0x70) != DW_EH_PE_pcrel)
1224
2
  break;
1225
      /* Fall through.  */
1226
23
    default:
1227
23
      encoding = DW_EH_PE_omit;
1228
23
      break;
1229
41
    }
1230
1231
41
  insn_ptr->u.ea.encoding = encoding;
1232
41
  if (encoding == DW_EH_PE_omit)
1233
36
    {
1234
36
      as_bad (_("wrong third argument to .cfi_val_encoded_addr"));
1235
36
      ignore_rest_of_line ();
1236
36
      return;
1237
36
    }
1238
1239
5
  demand_empty_rest_of_line ();
1240
5
}
1241
1242
static void
1243
dot_cfi_label (int ignored ATTRIBUTE_UNUSED)
1244
45
{
1245
45
  char *name;
1246
1247
45
  if (frchain_now->frch_cfi_data == NULL)
1248
17
    {
1249
17
      as_bad (_("CFI instruction used without previous .cfi_startproc"));
1250
17
      ignore_rest_of_line ();
1251
17
      return;
1252
17
    }
1253
1254
28
  name = read_symbol_name ();
1255
28
  if (name == NULL)
1256
0
    return;
1257
1258
  /* If the last address was not at the current PC, advance to current.  */
1259
28
  if (symbol_get_frag (frchain_now->frch_cfi_data->last_address) != frag_now
1260
16
      || (S_GET_VALUE (frchain_now->frch_cfi_data->last_address)
1261
16
    != frag_now_fix ()))
1262
19
    cfi_add_advance_loc (symbol_temp_new_now ());
1263
1264
28
  cfi_add_label (name);
1265
28
  free (name);
1266
1267
28
  demand_empty_rest_of_line ();
1268
28
}
1269
1270
void
1271
dot_cfi_sections (int ignored ATTRIBUTE_UNUSED)
1272
56
{
1273
56
  int sections = 0;
1274
1275
56
  SKIP_WHITESPACE ();
1276
56
  if (is_name_beginner (*input_line_pointer) || *input_line_pointer == '"')
1277
74
    while (1)
1278
74
      {
1279
74
  char * saved_ilp;
1280
74
  char *name, c;
1281
1282
74
  saved_ilp = input_line_pointer;
1283
74
  c = get_symbol_name (& name);
1284
1285
74
  if (startswith (name, ".eh_frame")
1286
8
      && name[9] != '_')
1287
8
    sections |= CFI_EMIT_eh_frame;
1288
66
  else if (startswith (name, ".debug_frame"))
1289
4
    sections |= CFI_EMIT_debug_frame;
1290
#if SUPPORT_COMPACT_EH
1291
  else if (startswith (name, ".eh_frame_entry"))
1292
    {
1293
      compact_eh = true;
1294
      sections |= CFI_EMIT_eh_frame_compact;
1295
    }
1296
#endif
1297
#ifdef tc_cfi_section_name
1298
  else if (strcmp (name, tc_cfi_section_name) == 0)
1299
    sections |= CFI_EMIT_target;
1300
#endif
1301
62
  else if (startswith (name, ".sframe"))
1302
15
      sections |= CFI_EMIT_sframe;
1303
47
  else
1304
47
    {
1305
47
      *input_line_pointer = c;
1306
47
      input_line_pointer = saved_ilp;
1307
47
      break;
1308
47
    }
1309
1310
27
  restore_line_pointer (c);
1311
27
  SKIP_WHITESPACE ();
1312
27
  if (*input_line_pointer == ',')
1313
0
    {
1314
0
      name = input_line_pointer++;
1315
0
      SKIP_WHITESPACE ();
1316
0
      if (!is_name_beginner (*input_line_pointer)
1317
0
    && *input_line_pointer != '"')
1318
0
        {
1319
0
    input_line_pointer = name;
1320
0
    break;
1321
0
        }
1322
0
    }
1323
27
  else if (is_name_beginner (*input_line_pointer)
1324
19
     || *input_line_pointer == '"')
1325
8
    break;
1326
27
      }
1327
1328
56
  demand_empty_rest_of_line ();
1329
56
  if (cfi_sections_set
1330
44
      && (sections & (CFI_EMIT_eh_frame | CFI_EMIT_eh_frame_compact))
1331
8
      && ((cfi_sections & (CFI_EMIT_eh_frame | CFI_EMIT_eh_frame_compact))
1332
8
    != (sections & (CFI_EMIT_eh_frame | CFI_EMIT_eh_frame_compact))))
1333
8
    as_bad (_("inconsistent uses of .cfi_sections"));
1334
56
  cfi_sections = sections;
1335
56
}
1336
1337
static void
1338
dot_cfi_startproc (int ignored ATTRIBUTE_UNUSED)
1339
125
{
1340
125
  int simple = 0;
1341
1342
125
  if (frchain_now->frch_cfi_data != NULL)
1343
35
    {
1344
35
      as_bad (_("previous CFI entry not closed (missing .cfi_endproc)"));
1345
35
      ignore_rest_of_line ();
1346
35
      return;
1347
35
    }
1348
1349
90
  cfi_new_fde (symbol_temp_new_now (), listing & LISTING_LISTING);
1350
1351
90
  SKIP_WHITESPACE ();
1352
90
  if (is_name_beginner (*input_line_pointer) || *input_line_pointer == '"')
1353
14
    {
1354
14
      char * saved_ilp = input_line_pointer;
1355
14
      char *name, c;
1356
1357
14
      c = get_symbol_name (& name);
1358
1359
14
      if (strcmp (name, "simple") == 0)
1360
0
  {
1361
0
    simple = 1;
1362
0
    restore_line_pointer (c);
1363
0
  }
1364
14
      else
1365
14
  input_line_pointer = saved_ilp;
1366
14
    }
1367
90
  demand_empty_rest_of_line ();
1368
1369
90
  cfi_set_sections ();
1370
1371
90
  frchain_now->frch_cfi_data->cur_cfa_offset = 0;
1372
90
  if (!simple)
1373
90
    tc_cfi_frame_initial_instructions ();
1374
1375
90
  if ((all_cfi_sections & CFI_EMIT_target) != 0)
1376
0
    tc_cfi_startproc ();
1377
90
}
1378
1379
static void
1380
dot_cfi_endproc (int ignored ATTRIBUTE_UNUSED)
1381
3
{
1382
3
  if (frchain_now->frch_cfi_data == NULL)
1383
3
    {
1384
3
      as_bad (_(".cfi_endproc without corresponding .cfi_startproc"));
1385
3
      ignore_rest_of_line ();
1386
3
      return;
1387
3
    }
1388
1389
0
  cfi_set_last_fde (frchain_now->frch_cfi_data->cur_fde_data);
1390
1391
0
  cfi_end_fde (symbol_temp_new_now ());
1392
1393
0
  demand_empty_rest_of_line ();
1394
1395
0
  if ((all_cfi_sections & CFI_EMIT_target) != 0)
1396
0
    tc_cfi_endproc (last_fde);
1397
0
}
1398
1399
static segT
1400
get_cfi_seg (segT cseg, const char *base, flagword flags, int align)
1401
80
{
1402
  /* Exclude .debug_frame sections for Compact EH.  */
1403
80
  if (SUPPORT_FRAME_LINKONCE || ((flags & SEC_DEBUGGING) == 0 && compact_eh)
1404
80
      || ((flags & SEC_DEBUGGING) == 0 && TARGET_MULTIPLE_EH_FRAME_SECTIONS))
1405
0
    {
1406
0
      segT iseg = cseg;
1407
0
      struct dwcfi_seg_list *l;
1408
1409
0
      l = dwcfi_hash_find_or_make (cseg, base, flags);
1410
1411
0
      cseg = l->seg;
1412
0
      subseg_set (cseg, l->subseg);
1413
1414
0
      if (TARGET_MULTIPLE_EH_FRAME_SECTIONS
1415
0
    && (flags & DWARF2_EH_FRAME_READ_ONLY))
1416
0
  {
1417
0
    const frchainS *ifrch = seg_info (iseg)->frchainP;
1418
0
    const frchainS *frch = seg_info (cseg)->frchainP;
1419
0
    expressionS exp;
1420
1421
0
    exp.X_op = O_symbol;
1422
0
    exp.X_add_symbol = (symbolS *) local_symbol_make (cseg->name, cseg, frch->frch_root, 0);
1423
0
    exp.X_add_number = 0;
1424
0
    subseg_set (iseg, ifrch->frch_subseg);
1425
0
    fix_new_exp (ifrch->frch_root, 0, 0, &exp, 0, BFD_RELOC_NONE);
1426
1427
    /* Restore the original segment info.  */
1428
0
    subseg_set (cseg, l->subseg);
1429
0
  }
1430
0
    }
1431
80
  else
1432
80
    {
1433
80
      cseg = subseg_new (base, 0);
1434
80
      bfd_set_section_flags (cseg, flags);
1435
80
    }
1436
80
  record_alignment (cseg, align);
1437
80
  return cseg;
1438
80
}
1439
1440
#if SUPPORT_COMPACT_EH
1441
static void
1442
dot_cfi_personality_id (int ignored ATTRIBUTE_UNUSED)
1443
{
1444
  struct fde_entry *fde;
1445
1446
  if (frchain_now->frch_cfi_data == NULL)
1447
    {
1448
      as_bad (_("CFI instruction used without previous .cfi_startproc"));
1449
      ignore_rest_of_line ();
1450
      return;
1451
    }
1452
1453
  fde = frchain_now->frch_cfi_data->cur_fde_data;
1454
  fde->personality_id = cfi_parse_const ();
1455
  demand_empty_rest_of_line ();
1456
1457
  if (fde->personality_id == 0 || fde->personality_id > 3)
1458
    {
1459
      as_bad (_("wrong argument to .cfi_personality_id"));
1460
      return;
1461
    }
1462
}
1463
1464
static void
1465
dot_cfi_fde_data (int ignored ATTRIBUTE_UNUSED)
1466
{
1467
  if (frchain_now->frch_cfi_data == NULL)
1468
    {
1469
      as_bad (_(".cfi_fde_data without corresponding .cfi_startproc"));
1470
      ignore_rest_of_line ();
1471
      return;
1472
    }
1473
1474
  cfi_set_last_fde (frchain_now->frch_cfi_data->cur_fde_data);
1475
1476
  if ((all_cfi_sections & CFI_EMIT_target) != 0
1477
      || (all_cfi_sections & CFI_EMIT_eh_frame_compact) != 0)
1478
    {
1479
      struct cfi_escape_data *head, **tail, *e;
1480
      int num_ops = 0;
1481
1482
      tail = &head;
1483
      if (!is_it_end_of_statement ())
1484
  {
1485
    num_ops = 0;
1486
    do
1487
      {
1488
        e = XNEW (struct cfi_escape_data);
1489
        e->reloc = do_parse_cons_expression (&e->exp, 1);
1490
        if (e->reloc != TC_PARSE_CONS_RETURN_NONE
1491
      || e->exp.X_op != O_constant)
1492
    as_bad (_("only constants may be used with .cfi_fde_data"));
1493
        *tail = e;
1494
        tail = &e->next;
1495
        num_ops++;
1496
      }
1497
    while (*input_line_pointer++ == ',');
1498
    --input_line_pointer;
1499
  }
1500
      *tail = NULL;
1501
1502
      if (last_fde->lsda_encoding != DW_EH_PE_omit)
1503
  last_fde->eh_header_type = EH_COMPACT_HAS_LSDA;
1504
      else if (num_ops <= 3 && last_fde->per_encoding == DW_EH_PE_omit)
1505
  last_fde->eh_header_type = EH_COMPACT_INLINE;
1506
      else
1507
  last_fde->eh_header_type = EH_COMPACT_OUTLINE;
1508
1509
      if (last_fde->eh_header_type == EH_COMPACT_INLINE)
1510
  num_ops = 3;
1511
1512
      last_fde->eh_data_size = num_ops;
1513
      last_fde->eh_data =  XNEWVEC (bfd_byte, num_ops);
1514
      num_ops = 0;
1515
      while (head)
1516
  {
1517
    e = head;
1518
    head = e->next;
1519
    last_fde->eh_data[num_ops++] = e->exp.X_add_number;
1520
    free (e);
1521
  }
1522
      if (last_fde->eh_header_type == EH_COMPACT_INLINE)
1523
  while (num_ops < 3)
1524
    last_fde->eh_data[num_ops++] = tc_compact_eh_opcode_stop;
1525
    }
1526
1527
  demand_empty_rest_of_line ();
1528
}
1529
1530
/* Function to emit the compact unwinding opcodes stored in the
1531
   fde's eh_data field.  The end of the opcode data will be
1532
   padded to the value in align.  */
1533
1534
static void
1535
output_compact_unwind_data (struct fde_entry *fde, int align)
1536
{
1537
  int data_size = fde->eh_data_size + 2;
1538
  int align_padding;
1539
  int amask;
1540
  char *p;
1541
1542
  fde->eh_loc = symbol_temp_new_now ();
1543
1544
  p = frag_more (1);
1545
  if (fde->personality_id != 0)
1546
    *p = fde->personality_id;
1547
  else if (fde->per_encoding != DW_EH_PE_omit)
1548
    {
1549
      *p = 0;
1550
      emit_expr_encoded (&fde->personality, fde->per_encoding, false);
1551
      data_size += encoding_size (fde->per_encoding);
1552
    }
1553
  else
1554
    *p = 1;
1555
1556
  amask = (1 << align) - 1;
1557
  align_padding = ((data_size + amask) & ~amask) - data_size;
1558
1559
  p = frag_more (fde->eh_data_size + 1 + align_padding);
1560
  memcpy (p, fde->eh_data, fde->eh_data_size);
1561
  p += fde->eh_data_size;
1562
1563
  while (align_padding-- > 0)
1564
    *(p++) = tc_compact_eh_opcode_pad;
1565
1566
  *(p++) = tc_compact_eh_opcode_stop;
1567
  fde->eh_header_type = EH_COMPACT_OUTLINE_DONE;
1568
}
1569
1570
/* Handle the .cfi_inline_lsda directive.  */
1571
static void
1572
dot_cfi_inline_lsda (int ignored ATTRIBUTE_UNUSED)
1573
{
1574
  segT ccseg;
1575
  int align;
1576
  long max_alignment = 28;
1577
1578
  if (!last_fde)
1579
    {
1580
      as_bad (_("unexpected .cfi_inline_lsda"));
1581
      ignore_rest_of_line ();
1582
      return;
1583
    }
1584
1585
  if ((last_fde->sections & CFI_EMIT_eh_frame_compact) == 0)
1586
    {
1587
      as_bad (_(".cfi_inline_lsda not valid for this frame"));
1588
      ignore_rest_of_line ();
1589
      return;
1590
    }
1591
1592
  if (last_fde->eh_header_type != EH_COMPACT_UNKNOWN
1593
      && last_fde->eh_header_type != EH_COMPACT_HAS_LSDA)
1594
    {
1595
      as_bad (_(".cfi_inline_lsda seen for frame without .cfi_lsda"));
1596
      ignore_rest_of_line ();
1597
      return;
1598
    }
1599
1600
#ifdef md_flush_pending_output
1601
  md_flush_pending_output ();
1602
#endif
1603
1604
  align = get_absolute_expression ();
1605
  if (align > max_alignment)
1606
    {
1607
      align = max_alignment;
1608
      as_bad (_("Alignment too large: %d. assumed."), align);
1609
    }
1610
  else if (align < 0)
1611
    {
1612
      as_warn (_("Alignment negative: 0 assumed."));
1613
      align = 0;
1614
    }
1615
1616
  demand_empty_rest_of_line ();
1617
  ccseg = CUR_SEG (last_fde);
1618
1619
  /* Open .gnu_extab section.  */
1620
  get_cfi_seg (ccseg, ".gnu_extab",
1621
         (SEC_ALLOC | SEC_LOAD | SEC_DATA
1622
    | DWARF2_EH_FRAME_READ_ONLY),
1623
         1);
1624
1625
  frag_align (align, 0, 0);
1626
  record_alignment (now_seg, align);
1627
  if (last_fde->eh_header_type == EH_COMPACT_HAS_LSDA)
1628
    output_compact_unwind_data (last_fde, align);
1629
1630
  cfi_set_last_fde (NULL);
1631
1632
  return;
1633
}
1634
#else /* !SUPPORT_COMPACT_EH */
1635
static void
1636
dot_cfi_inline_lsda (int ignored ATTRIBUTE_UNUSED)
1637
0
{
1638
0
  as_bad (_(".cfi_inline_lsda is not supported for this target"));
1639
0
  ignore_rest_of_line ();
1640
0
}
1641
1642
static void
1643
dot_cfi_fde_data (int ignored ATTRIBUTE_UNUSED)
1644
0
{
1645
0
  as_bad (_(".cfi_fde_data is not supported for this target"));
1646
0
  ignore_rest_of_line ();
1647
0
}
1648
1649
static void
1650
dot_cfi_personality_id (int ignored ATTRIBUTE_UNUSED)
1651
0
{
1652
0
  as_bad (_(".cfi_personality_id is not supported for this target"));
1653
0
  ignore_rest_of_line ();
1654
0
}
1655
#endif
1656

1657
static void
1658
output_cfi_insn (struct cfi_insn_data *insn)
1659
1.12k
{
1660
1.12k
  offsetT offset;
1661
1.12k
  unsigned int regno;
1662
1663
1.12k
  switch (insn->insn)
1664
1.12k
    {
1665
81
    case DW_CFA_advance_loc:
1666
81
      {
1667
81
  symbolS *from = insn->u.ll.lab1;
1668
81
  symbolS *to = insn->u.ll.lab2;
1669
1670
81
  if (symbol_get_frag (to) == symbol_get_frag (from))
1671
56
    {
1672
56
      addressT delta = S_GET_VALUE (to) - S_GET_VALUE (from);
1673
56
      addressT scaled = delta / DWARF2_LINE_MIN_INSN_LENGTH;
1674
1675
56
      if (scaled == 0)
1676
0
        ;
1677
56
      else if (scaled <= 0x3F)
1678
50
        out_one (DW_CFA_advance_loc + scaled);
1679
6
      else if (scaled <= 0xFF)
1680
1
        {
1681
1
    out_one (DW_CFA_advance_loc1);
1682
1
    out_one (scaled);
1683
1
        }
1684
5
      else if (scaled <= 0xFFFF)
1685
0
        {
1686
0
    out_one (DW_CFA_advance_loc2);
1687
0
    out_two (scaled);
1688
0
        }
1689
5
      else
1690
5
        {
1691
5
    out_one (DW_CFA_advance_loc4);
1692
5
    out_four (scaled);
1693
5
        }
1694
56
    }
1695
25
  else
1696
25
    {
1697
25
      expressionS exp = {
1698
25
        .X_op = O_subtract,
1699
25
        .X_add_symbol = to,
1700
25
        .X_op_symbol = from,
1701
25
      };
1702
1703
      /* The code in ehopt.c expects that one byte of the encoding
1704
         is already allocated to the frag.  This comes from the way
1705
         that it scans the .eh_frame section looking first for the
1706
         .byte DW_CFA_advance_loc4.  Call frag_grow with the sum of
1707
         room needed by frag_more and frag_var to preallocate space
1708
         ensuring that the DW_CFA_advance_loc4 is in the fixed part
1709
         of the rs_cfa frag, so that the relax machinery can remove
1710
         the advance_loc should it advance by zero.  */
1711
25
      frag_grow (5);
1712
25
      *frag_more (1) = DW_CFA_advance_loc4;
1713
1714
25
      frag_var (rs_cfa, 4, 0, DWARF2_LINE_MIN_INSN_LENGTH << 3,
1715
25
          make_expr_symbol (&exp), frag_now_fix () - 1,
1716
25
          (char *) frag_now);
1717
25
    }
1718
81
      }
1719
81
      break;
1720
1721
92
    case DW_CFA_def_cfa:
1722
92
      offset = insn->u.ri.offset;
1723
92
      if (offset < 0)
1724
4
  {
1725
4
    out_one (DW_CFA_def_cfa_sf);
1726
4
    out_uleb128 (insn->u.ri.reg);
1727
4
    out_sleb128 (offset / DWARF2_CIE_DATA_ALIGNMENT);
1728
4
  }
1729
88
      else
1730
88
  {
1731
88
    out_one (DW_CFA_def_cfa);
1732
88
    out_uleb128 (insn->u.ri.reg);
1733
88
    out_uleb128 (offset);
1734
88
  }
1735
92
      break;
1736
1737
3
    case DW_CFA_def_cfa_register:
1738
558
    case DW_CFA_undefined:
1739
558
    case DW_CFA_same_value:
1740
558
      out_one (insn->insn);
1741
558
      out_uleb128 (insn->u.r);
1742
558
      break;
1743
1744
0
    case DW_CFA_def_cfa_offset:
1745
0
      offset = insn->u.i;
1746
0
      if (offset < 0)
1747
0
  {
1748
0
    out_one (DW_CFA_def_cfa_offset_sf);
1749
0
    out_sleb128 (offset / DWARF2_CIE_DATA_ALIGNMENT);
1750
0
  }
1751
0
      else
1752
0
  {
1753
0
    out_one (DW_CFA_def_cfa_offset);
1754
0
    out_uleb128 (offset);
1755
0
  }
1756
0
      break;
1757
1758
32
    case DW_CFA_restore:
1759
32
      regno = insn->u.r;
1760
32
      if (regno <= 0x3F)
1761
32
  {
1762
32
    out_one (DW_CFA_restore + regno);
1763
32
  }
1764
0
      else
1765
0
  {
1766
0
    out_one (DW_CFA_restore_extended);
1767
0
    out_uleb128 (regno);
1768
0
  }
1769
32
      break;
1770
1771
88
    case DW_CFA_offset:
1772
88
      regno = insn->u.ri.reg;
1773
88
      offset = insn->u.ri.offset / DWARF2_CIE_DATA_ALIGNMENT;
1774
88
      if (offset < 0)
1775
3
  {
1776
3
    out_one (DW_CFA_offset_extended_sf);
1777
3
    out_uleb128 (regno);
1778
3
    out_sleb128 (offset);
1779
3
  }
1780
85
      else if (regno <= 0x3F)
1781
78
  {
1782
78
    out_one (DW_CFA_offset + regno);
1783
78
    out_uleb128 (offset);
1784
78
  }
1785
7
      else
1786
7
  {
1787
7
    out_one (DW_CFA_offset_extended);
1788
7
    out_uleb128 (regno);
1789
7
    out_uleb128 (offset);
1790
7
  }
1791
88
      break;
1792
1793
0
    case DW_CFA_val_offset:
1794
0
      regno = insn->u.ri.reg;
1795
0
      offset = insn->u.ri.offset / DWARF2_CIE_DATA_ALIGNMENT;
1796
0
      if (offset < 0)
1797
0
  {
1798
0
    out_one (DW_CFA_val_offset_sf);
1799
0
    out_uleb128 (regno);
1800
0
    out_sleb128 (offset);
1801
0
  }
1802
0
      else
1803
0
  {
1804
0
    out_one (DW_CFA_val_offset);
1805
0
    out_uleb128 (regno);
1806
0
    out_uleb128 (offset);
1807
0
  }
1808
0
      break;
1809
1810
0
    case DW_CFA_register:
1811
0
      out_one (DW_CFA_register);
1812
0
      out_uleb128 (insn->u.rr.reg1);
1813
0
      out_uleb128 (insn->u.rr.reg2);
1814
0
      break;
1815
1816
0
    case DW_CFA_remember_state:
1817
0
    case DW_CFA_restore_state:
1818
0
      out_one (insn->insn);
1819
0
      break;
1820
1821
9
    case DW_CFA_GNU_window_save:
1822
9
      out_one (DW_CFA_GNU_window_save);
1823
9
      break;
1824
1825
0
    case DW_CFA_AARCH64_negate_ra_state_with_pc:
1826
0
      out_one (DW_CFA_AARCH64_negate_ra_state_with_pc);
1827
0
      break;
1828
1829
201
    case CFI_escape:
1830
201
      {
1831
201
  struct cfi_escape_data *e;
1832
600
  for (e = insn->u.esc; e ; e = e->next)
1833
399
    {
1834
399
      if (e->type == CFI_ESC_sleb128 || e->type == CFI_ESC_uleb128)
1835
0
        emit_leb128_expr (&e->exp, e->type == CFI_ESC_sleb128);
1836
399
      else
1837
399
        emit_expr_with_reloc (&e->exp, e->type, e->reloc);
1838
399
    }
1839
201
  break;
1840
0
      }
1841
1842
41
    case CFI_val_encoded_addr:
1843
41
      {
1844
41
  unsigned encoding = insn->u.ea.encoding;
1845
41
  offsetT enc_size;
1846
1847
41
  if (encoding == DW_EH_PE_omit)
1848
36
    break;
1849
5
  out_one (DW_CFA_val_expression);
1850
5
  out_uleb128 (insn->u.ea.reg);
1851
1852
5
  switch (encoding & 0x7)
1853
5
    {
1854
3
    case DW_EH_PE_absptr:
1855
3
      enc_size = DWARF2_ADDR_SIZE (stdoutput);
1856
3
      break;
1857
0
    case DW_EH_PE_udata2:
1858
0
      enc_size = 2;
1859
0
      break;
1860
0
    case DW_EH_PE_udata4:
1861
0
      enc_size = 4;
1862
0
      break;
1863
2
    case DW_EH_PE_udata8:
1864
2
      enc_size = 8;
1865
2
      break;
1866
0
    default:
1867
0
      abort ();
1868
5
    }
1869
1870
  /* If the user has requested absolute encoding,
1871
     then use the smaller DW_OP_addr encoding.  */
1872
5
  if (insn->u.ea.encoding == DW_EH_PE_absptr)
1873
3
    {
1874
3
      out_uleb128 (1 + enc_size);
1875
3
      out_one (DW_OP_addr);
1876
3
    }
1877
2
  else
1878
2
    {
1879
2
      out_uleb128 (1 + 1 + enc_size);
1880
2
      out_one (DW_OP_GNU_encoded_addr);
1881
2
      out_one (encoding);
1882
1883
2
      if ((encoding & 0x70) == DW_EH_PE_pcrel)
1884
2
        {
1885
2
#if CFI_DIFF_EXPR_OK
1886
2
    insn->u.ea.exp.X_op = O_subtract;
1887
2
    insn->u.ea.exp.X_op_symbol = symbol_temp_new_now ();
1888
#elif defined (tc_cfi_emit_pcrel_expr)
1889
    tc_cfi_emit_pcrel_expr (&insn->u.ea.exp, enc_size);
1890
    break;
1891
#else
1892
    abort ();
1893
#endif
1894
2
        }
1895
2
    }
1896
5
  emit_expr (&insn->u.ea.exp, enc_size);
1897
5
      }
1898
0
      break;
1899
1900
26
    case CFI_label:
1901
26
      colon (insn->u.sym_name);
1902
26
      break;
1903
1904
0
    default:
1905
0
      abort ();
1906
1.12k
    }
1907
1.12k
}
1908
1909
static void
1910
output_cie (struct cie_entry *cie, bool eh_frame, int align)
1911
71
{
1912
71
  symbolS *after_size_address, *end_address;
1913
71
  expressionS exp;
1914
71
  struct cfi_insn_data *i;
1915
71
  offsetT augmentation_size;
1916
71
  int enc;
1917
71
  enum dwarf2_format fmt = DWARF2_FORMAT (now_seg);
1918
1919
71
  cie->start_address = symbol_temp_new_now ();
1920
71
  after_size_address = symbol_temp_make ();
1921
71
  end_address = symbol_temp_make ();
1922
1923
71
  exp.X_op = O_subtract;
1924
71
  exp.X_add_symbol = end_address;
1925
71
  exp.X_op_symbol = after_size_address;
1926
71
  exp.X_add_number = 0;
1927
1928
71
  if (eh_frame || fmt == dwarf2_format_32bit)
1929
71
    emit_expr (&exp, 4);      /* Length.  */
1930
0
  else
1931
0
    {
1932
0
      if (fmt == dwarf2_format_64bit)
1933
0
  out_four (-1);
1934
0
      emit_expr (&exp, 8);      /* Length.  */
1935
0
    }
1936
71
  symbol_set_value_now (after_size_address);
1937
71
  if (eh_frame)
1938
68
    out_four (0);        /* CIE id.  */
1939
3
  else
1940
3
    {
1941
3
      out_four (-1);        /* CIE id.  */
1942
3
      if (fmt != dwarf2_format_32bit)
1943
0
  out_four (-1);
1944
3
    }
1945
71
  out_one (flag_dwarf_cie_version);   /* Version.  */
1946
71
  if (eh_frame)
1947
68
    {
1948
68
      out_one ('z');        /* Augmentation.  */
1949
68
      if (cie->per_encoding != DW_EH_PE_omit)
1950
1
  out_one ('P');
1951
68
      if (cie->lsda_encoding != DW_EH_PE_omit)
1952
6
  out_one ('L');
1953
68
      out_one ('R');
1954
#ifdef tc_output_cie_extra
1955
      tc_output_cie_extra (cie);
1956
#endif
1957
68
    }
1958
71
  if (cie->signal_frame)
1959
0
    out_one ('S');
1960
71
  out_one (0);
1961
71
  if (flag_dwarf_cie_version >= 4)
1962
0
    {
1963
      /* For now we are assuming a flat address space with 4 or 8 byte
1964
         addresses.  */
1965
0
      int address_size = dwarf2_format_32bit ? 4 : 8;
1966
0
      out_one (address_size);     /* Address size.  */
1967
0
      out_one (0);        /* Segment size.  */
1968
0
    }
1969
71
  out_uleb128 (DWARF2_LINE_MIN_INSN_LENGTH);  /* Code alignment.  */
1970
71
  out_sleb128 (DWARF2_CIE_DATA_ALIGNMENT);  /* Data alignment.  */
1971
71
  if (flag_dwarf_cie_version == 1)   /* Return column.  */
1972
71
    {
1973
71
      if ((cie->return_column & 0xff) != cie->return_column)
1974
0
  as_bad (_("return column number %d overflows in CIE version 1"),
1975
0
    cie->return_column);
1976
71
      out_one (cie->return_column);
1977
71
    }
1978
0
  else
1979
0
    out_uleb128 (cie->return_column);
1980
71
  if (eh_frame)
1981
68
    {
1982
68
      augmentation_size = 1 + (cie->lsda_encoding != DW_EH_PE_omit);
1983
68
      if (cie->per_encoding != DW_EH_PE_omit)
1984
1
  augmentation_size += 1 + encoding_size (cie->per_encoding);
1985
68
      out_uleb128 (augmentation_size);    /* Augmentation size.  */
1986
1987
68
      emit_expr_encoded (&cie->personality, cie->per_encoding, true);
1988
1989
68
      if (cie->lsda_encoding != DW_EH_PE_omit)
1990
6
  out_one (cie->lsda_encoding);
1991
68
    }
1992
1993
71
  switch (DWARF2_FDE_RELOC_SIZE)
1994
71
    {
1995
0
    case 2:
1996
0
      enc = DW_EH_PE_sdata2;
1997
0
      break;
1998
71
    case 4:
1999
71
      enc = DW_EH_PE_sdata4;
2000
71
      break;
2001
0
    case 8:
2002
0
      enc = DW_EH_PE_sdata8;
2003
0
      break;
2004
0
    default:
2005
0
      abort ();
2006
71
    }
2007
71
#if CFI_DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr
2008
71
  enc |= DW_EH_PE_pcrel;
2009
71
#endif
2010
#ifdef DWARF2_FDE_RELOC_ENCODING
2011
  /* Allow target to override encoding.  */
2012
  enc = DWARF2_FDE_RELOC_ENCODING (enc);
2013
#endif
2014
71
  cie->fde_encoding = enc;
2015
71
  if (eh_frame)
2016
68
    out_one (enc);
2017
2018
71
  if (cie->first)
2019
71
    {
2020
785
      for (i = cie->first; i != cie->last; i = i->next)
2021
714
  {
2022
714
    if (CUR_SEG (i) != CUR_SEG (cie))
2023
0
      continue;
2024
714
    output_cfi_insn (i);
2025
714
  }
2026
71
    }
2027
2028
71
  frag_align (align, DW_CFA_nop, 0);
2029
71
  symbol_set_value_now (end_address);
2030
71
}
2031
2032
static void
2033
output_fde (struct fde_entry *fde, struct cie_entry *cie,
2034
      bool eh_frame, struct cfi_insn_data *first,
2035
      int align)
2036
83
{
2037
83
  symbolS *after_size_address, *end_address;
2038
83
  expressionS exp;
2039
83
  offsetT augmentation_size;
2040
83
  enum dwarf2_format fmt = DWARF2_FORMAT (now_seg);
2041
83
  unsigned int offset_size;
2042
83
  unsigned int addr_size;
2043
2044
83
  after_size_address = symbol_temp_make ();
2045
83
  end_address = symbol_temp_make ();
2046
2047
83
  exp.X_op = O_subtract;
2048
83
  exp.X_add_symbol = end_address;
2049
83
  exp.X_op_symbol = after_size_address;
2050
83
  exp.X_add_number = 0;
2051
83
  if (eh_frame || fmt == dwarf2_format_32bit)
2052
83
    offset_size = 4;
2053
0
  else
2054
0
    {
2055
0
      if (fmt == dwarf2_format_64bit)
2056
0
  out_four (-1);
2057
0
      offset_size = 8;
2058
0
    }
2059
83
  emit_expr (&exp, offset_size);    /* Length.  */
2060
83
  symbol_set_value_now (after_size_address);
2061
2062
83
  if (eh_frame)
2063
78
    {
2064
78
      exp.X_op = O_subtract;
2065
78
      exp.X_add_symbol = after_size_address;
2066
78
      exp.X_op_symbol = cie->start_address;
2067
78
      exp.X_add_number = 0;
2068
78
      emit_expr (&exp, offset_size);    /* CIE offset.  */
2069
78
    }
2070
5
  else
2071
5
    {
2072
5
      TC_DWARF2_EMIT_OFFSET (cie->start_address, offset_size);
2073
5
    }
2074
2075
83
  exp.X_op = O_symbol;
2076
83
  if (eh_frame)
2077
78
    {
2078
78
      bfd_reloc_code_real_type code
2079
78
  = tc_cfi_reloc_for_encoding (cie->fde_encoding);
2080
78
      addr_size = DWARF2_FDE_RELOC_SIZE;
2081
78
      if (code != BFD_RELOC_NONE)
2082
0
  {
2083
0
    reloc_howto_type *howto = bfd_reloc_type_lookup (stdoutput, code);
2084
0
    char *p = frag_more (addr_size);
2085
0
    gas_assert (addr_size == (unsigned) howto->bitsize / 8);
2086
0
    md_number_to_chars (p, 0, addr_size);
2087
0
    fix_new (frag_now, p - frag_now->fr_literal, addr_size,
2088
0
       fde->start_address, 0, howto->pc_relative, code);
2089
0
  }
2090
78
      else
2091
78
  {
2092
78
    exp.X_op = O_subtract;
2093
78
    exp.X_add_number = 0;
2094
78
#if CFI_DIFF_EXPR_OK
2095
78
    exp.X_add_symbol = fde->start_address;
2096
78
    exp.X_op_symbol = symbol_temp_new_now ();
2097
78
    emit_expr (&exp, addr_size);  /* Code offset.  */
2098
#else
2099
    exp.X_op = O_symbol;
2100
    exp.X_add_symbol = fde->start_address;
2101
2102
#if defined(tc_cfi_emit_pcrel_expr)
2103
    tc_cfi_emit_pcrel_expr (&exp, addr_size);  /* Code offset.  */
2104
#else
2105
    emit_expr (&exp, addr_size);  /* Code offset.  */
2106
#endif
2107
#endif
2108
78
  }
2109
78
    }
2110
5
  else
2111
5
    {
2112
5
      exp.X_add_number = 0;
2113
5
      exp.X_add_symbol = fde->start_address;
2114
5
      addr_size = DWARF2_ADDR_SIZE (stdoutput);
2115
5
      emit_expr (&exp, addr_size);
2116
5
    }
2117
2118
83
  exp.X_op = O_subtract;
2119
83
  exp.X_add_symbol = fde->end_address;
2120
83
  exp.X_op_symbol = fde->start_address;   /* Code length.  */
2121
83
  exp.X_add_number = 0;
2122
83
  emit_expr (&exp, addr_size);
2123
2124
83
  augmentation_size = encoding_size (fde->lsda_encoding);
2125
83
  if (eh_frame)
2126
78
    out_uleb128 (augmentation_size);   /* Augmentation size.  */
2127
2128
83
  emit_expr_encoded (&fde->lsda, cie->lsda_encoding, false);
2129
2130
497
  for (; first; first = first->next)
2131
414
    if (CUR_SEG (first) == CUR_SEG (fde))
2132
414
      {
2133
414
#ifndef NO_LISTING
2134
414
  if (eh_frame)
2135
391
    listing_override_tail (first->listing_ctxt);
2136
414
#endif
2137
414
  output_cfi_insn (first);
2138
414
      }
2139
2140
83
#ifndef NO_LISTING
2141
  /* Associate any padding with .cfi_endproc.  */
2142
83
  if (eh_frame)
2143
78
    listing_override_tail (fde->listing_end);
2144
83
#endif
2145
2146
83
  frag_align (align, DW_CFA_nop, 0);
2147
83
  symbol_set_value_now (end_address);
2148
83
}
2149
2150
/* Allow these insns to be put in the initial sequence of a CIE.
2151
   If J is non-NULL, then compare I and J insns for a match.  */
2152
2153
static inline bool
2154
initial_cie_insn (const struct cfi_insn_data *i, const struct cfi_insn_data *j)
2155
790
{
2156
790
  if (j && i->insn != j->insn)
2157
0
    return false;
2158
790
  switch (i->insn)
2159
790
    {
2160
99
    case DW_CFA_offset:
2161
203
    case DW_CFA_def_cfa:
2162
203
    case DW_CFA_val_offset:
2163
203
      if (j)
2164
27
  {
2165
27
    if (i->u.ri.reg != j->u.ri.reg)
2166
1
      return false;
2167
26
    if (i->u.ri.offset != j->u.ri.offset)
2168
0
      return false;
2169
26
  }
2170
202
      break;
2171
2172
202
    case DW_CFA_register:
2173
0
      if (j)
2174
0
  {
2175
0
    if (i->u.rr.reg1 != j->u.rr.reg1)
2176
0
      return false;
2177
0
    if (i->u.rr.reg2 != j->u.rr.reg2)
2178
0
      return false;
2179
0
  }
2180
0
      break;
2181
2182
1
    case DW_CFA_def_cfa_register:
2183
18
    case DW_CFA_restore:
2184
558
    case DW_CFA_undefined:
2185
558
    case DW_CFA_same_value:
2186
558
      if (j)
2187
20
  {
2188
20
    if (i->u.r != j->u.r)
2189
0
      return false;
2190
20
  }
2191
558
      break;
2192
2193
558
    case DW_CFA_def_cfa_offset:
2194
0
      if (j)
2195
0
  {
2196
0
    if (i->u.i != j->u.i)
2197
0
      return false;
2198
0
  }
2199
0
      break;
2200
2201
29
    default:
2202
29
      return false;
2203
790
    }
2204
760
  return true;
2205
790
}
2206
2207
static struct cie_entry *
2208
select_cie_for_fde (struct fde_entry *fde, bool eh_frame,
2209
        struct cfi_insn_data **pfirst, int align)
2210
83
{
2211
83
  struct cfi_insn_data *i, *j;
2212
83
  struct cie_entry *cie;
2213
2214
85
  for (cie = cie_root; cie; cie = cie->next)
2215
14
    {
2216
14
      if (CUR_SEG (cie) != CUR_SEG (fde))
2217
0
  continue;
2218
#ifdef tc_cie_fde_equivalent_extra
2219
      if (!tc_cie_fde_equivalent_extra (cie, fde))
2220
  continue;
2221
#endif
2222
14
      if (cie->return_column != fde->return_column
2223
14
    || cie->signal_frame != fde->signal_frame
2224
14
    || cie->per_encoding != fde->per_encoding
2225
14
    || cie->lsda_encoding != fde->lsda_encoding)
2226
1
  continue;
2227
13
      if (cie->per_encoding != DW_EH_PE_omit)
2228
0
  {
2229
0
    if (cie->personality.X_op != fde->personality.X_op
2230
0
        || (cie->personality.X_add_number
2231
0
      != fde->personality.X_add_number))
2232
0
      continue;
2233
0
    switch (cie->personality.X_op)
2234
0
      {
2235
0
      case O_constant:
2236
0
        if (cie->personality.X_unsigned != fde->personality.X_unsigned)
2237
0
    continue;
2238
0
        break;
2239
0
      case O_symbol:
2240
0
        if (cie->personality.X_add_symbol
2241
0
      != fde->personality.X_add_symbol)
2242
0
    continue;
2243
0
        break;
2244
0
      default:
2245
0
        abort ();
2246
0
      }
2247
0
  }
2248
13
      for (i = cie->first, j = fde->data;
2249
59
     i != cie->last && j != NULL;
2250
46
     i = i->next, j = j->next)
2251
47
  {
2252
47
    if (!initial_cie_insn (i, j))
2253
1
      break;
2254
47
  }
2255
2256
13
      if (i == cie->last)
2257
12
  {
2258
12
    *pfirst = j;
2259
12
    return cie;
2260
12
  }
2261
13
    }
2262
2263
71
  cie = XNEW (struct cie_entry);
2264
71
  cie->next = cie_root;
2265
71
  cie_root = cie;
2266
71
  SET_CUR_SEG (cie, CUR_SEG (fde));
2267
71
  cie->return_column = fde->return_column;
2268
71
  cie->signal_frame = fde->signal_frame;
2269
71
  cie->per_encoding = fde->per_encoding;
2270
71
  cie->lsda_encoding = fde->lsda_encoding;
2271
71
  cie->personality = fde->personality;
2272
71
  cie->first = fde->data;
2273
#ifdef tc_cie_entry_init_extra
2274
  tc_cie_entry_init_extra (cie, fde);
2275
#endif
2276
2277
785
  for (i = cie->first; i ; i = i->next)
2278
743
    if (!initial_cie_insn (i, NULL))
2279
29
      break;
2280
2281
71
  cie->last = i;
2282
71
  *pfirst = i;
2283
2284
71
  output_cie (cie, eh_frame, align);
2285
2286
71
  return cie;
2287
83
}
2288
2289
#ifdef md_reg_eh_frame_to_debug_frame
2290
static void
2291
cfi_change_reg_numbers (struct cfi_insn_data *insn, segT ccseg)
2292
{
2293
  for (; insn; insn = insn->next)
2294
    {
2295
      if (CUR_SEG (insn) != ccseg)
2296
  continue;
2297
      switch (insn->insn)
2298
  {
2299
  case DW_CFA_advance_loc:
2300
  case DW_CFA_def_cfa_offset:
2301
  case DW_CFA_remember_state:
2302
  case DW_CFA_restore_state:
2303
  case DW_CFA_GNU_window_save:
2304
  case DW_CFA_AARCH64_negate_ra_state_with_pc:
2305
  case CFI_escape:
2306
  case CFI_label:
2307
    break;
2308
2309
  case DW_CFA_def_cfa:
2310
  case DW_CFA_offset:
2311
    insn->u.ri.reg = md_reg_eh_frame_to_debug_frame (insn->u.ri.reg);
2312
    break;
2313
2314
  case DW_CFA_def_cfa_register:
2315
  case DW_CFA_undefined:
2316
  case DW_CFA_same_value:
2317
  case DW_CFA_restore:
2318
    insn->u.r = md_reg_eh_frame_to_debug_frame (insn->u.r);
2319
    break;
2320
2321
  case DW_CFA_register:
2322
    insn->u.rr.reg1 = md_reg_eh_frame_to_debug_frame (insn->u.rr.reg1);
2323
    insn->u.rr.reg2 = md_reg_eh_frame_to_debug_frame (insn->u.rr.reg2);
2324
    break;
2325
2326
  case CFI_val_encoded_addr:
2327
    insn->u.ea.reg = md_reg_eh_frame_to_debug_frame (insn->u.ea.reg);
2328
    break;
2329
2330
  default:
2331
    abort ();
2332
  }
2333
    }
2334
}
2335
#else
2336
5
#define cfi_change_reg_numbers(insn, cseg) do { } while (0)
2337
#endif
2338
2339
#if SUPPORT_COMPACT_EH
2340
static void
2341
cfi_emit_eh_header (symbolS *sym, bfd_vma addend)
2342
{
2343
  expressionS exp;
2344
2345
  exp.X_add_number = addend;
2346
  exp.X_add_symbol = sym;
2347
  emit_expr_encoded (&exp, DW_EH_PE_sdata4 | DW_EH_PE_pcrel, false);
2348
}
2349
2350
static void
2351
output_eh_header (struct fde_entry *fde)
2352
{
2353
  char *p;
2354
  bfd_vma addend;
2355
2356
  if (fde->eh_header_type == EH_COMPACT_INLINE)
2357
    addend = 0;
2358
  else
2359
    addend = 1;
2360
2361
  cfi_emit_eh_header (fde->start_address, addend);
2362
2363
  if (fde->eh_header_type == EH_COMPACT_INLINE)
2364
    {
2365
      p = frag_more (4);
2366
      /* Inline entries always use PR1.  */
2367
      *(p++) = 1;
2368
      memcpy(p, fde->eh_data, 3);
2369
    }
2370
  else
2371
    {
2372
      if (fde->eh_header_type == EH_COMPACT_LEGACY)
2373
  addend = 1;
2374
      else if (fde->eh_header_type == EH_COMPACT_OUTLINE
2375
         || fde->eh_header_type == EH_COMPACT_OUTLINE_DONE)
2376
  addend = 0;
2377
      else
2378
  abort ();
2379
      cfi_emit_eh_header (fde->eh_loc, addend);
2380
    }
2381
}
2382
#endif
2383
2384
void
2385
cfi_finish (void)
2386
567
{
2387
567
  struct cie_entry *cie, *cie_next;
2388
567
  segT cfi_seg, ccseg;
2389
567
  struct fde_entry *fde;
2390
567
  struct cfi_insn_data *first;
2391
567
#ifndef NO_LISTING
2392
  /* We may temporarily replace listing_tail, which otherwise isn't supposed
2393
     to be changing anymore.  Play safe and restore the original value
2394
     afterwards.  */
2395
567
  struct list_info_struct *saved_listing_tail = NULL;
2396
567
#endif
2397
567
  int save_flag_traditional_format, seek_next_seg;
2398
2399
567
  if (all_fde_data == 0)
2400
490
    return;
2401
2402
77
  if ((all_cfi_sections & CFI_EMIT_eh_frame) != 0
2403
11
      || (all_cfi_sections & CFI_EMIT_eh_frame_compact) != 0)
2404
66
    {
2405
      /* Make sure check_eh_frame doesn't do anything with our output.  */
2406
66
      save_flag_traditional_format = flag_traditional_format;
2407
66
      flag_traditional_format = 1;
2408
2409
66
      if (!EH_FRAME_LINKONCE)
2410
66
  {
2411
    /* Open .eh_frame section.  */
2412
66
    cfi_seg = get_cfi_seg (NULL, ".eh_frame",
2413
66
         (SEC_ALLOC | SEC_LOAD | SEC_DATA
2414
66
          | DWARF2_EH_FRAME_READ_ONLY),
2415
66
         EH_FRAME_ALIGNMENT);
2416
#ifdef md_fix_up_eh_frame
2417
    md_fix_up_eh_frame (cfi_seg);
2418
#else
2419
66
    (void) cfi_seg;
2420
66
#endif
2421
66
  }
2422
2423
66
      do
2424
66
  {
2425
66
    ccseg = NULL;
2426
66
    seek_next_seg = 0;
2427
2428
144
    for (fde = all_fde_data; fde ; fde = fde->next)
2429
78
      {
2430
78
        if ((fde->sections & CFI_EMIT_eh_frame) == 0
2431
0
      && (fde->sections & CFI_EMIT_eh_frame_compact) == 0)
2432
0
    continue;
2433
2434
#if SUPPORT_COMPACT_EH
2435
        /* Emit a LEGACY format header if we have processed all
2436
     of the .cfi directives without encountering either inline or
2437
     out-of-line compact unwinding opcodes.  */
2438
        if (fde->eh_header_type == EH_COMPACT_HAS_LSDA
2439
      || fde->eh_header_type == EH_COMPACT_UNKNOWN)
2440
    fde->eh_header_type = EH_COMPACT_LEGACY;
2441
2442
        if (fde->eh_header_type != EH_COMPACT_LEGACY)
2443
    continue;
2444
#endif
2445
78
        if (EH_FRAME_LINKONCE)
2446
0
    {
2447
0
      if (HANDLED (fde))
2448
0
        continue;
2449
0
      if (seek_next_seg && CUR_SEG (fde) != ccseg)
2450
0
        {
2451
0
          seek_next_seg = 2;
2452
0
          continue;
2453
0
        }
2454
0
      if (!seek_next_seg)
2455
0
        {
2456
0
          ccseg = CUR_SEG (fde);
2457
          /* Open .eh_frame section.  */
2458
0
          cfi_seg = get_cfi_seg (ccseg, ".eh_frame",
2459
0
               (SEC_ALLOC | SEC_LOAD | SEC_DATA
2460
0
                | DWARF2_EH_FRAME_READ_ONLY),
2461
0
               EH_FRAME_ALIGNMENT);
2462
#ifdef md_fix_up_eh_frame
2463
          md_fix_up_eh_frame (cfi_seg);
2464
#else
2465
0
          (void) cfi_seg;
2466
0
#endif
2467
0
          seek_next_seg = 1;
2468
0
        }
2469
0
      SET_HANDLED (fde, 1);
2470
0
    }
2471
2472
78
        if (fde->end_address == NULL)
2473
78
    {
2474
78
      as_bad (_("open CFI at the end of file; "
2475
78
          "missing .cfi_endproc directive"));
2476
78
      fde->end_address = fde->start_address;
2477
78
    }
2478
2479
78
#ifndef NO_LISTING
2480
78
        {
2481
78
    struct list_info_struct *listing_prev
2482
78
      = listing_override_tail (fde->listing_ctxt);
2483
2484
78
    if (!saved_listing_tail)
2485
78
      saved_listing_tail = listing_prev;
2486
78
        }
2487
78
#endif
2488
2489
78
        cie = select_cie_for_fde (fde, true, &first, 2);
2490
78
        fde->eh_loc = symbol_temp_new_now ();
2491
78
        output_fde (fde, cie, true, first,
2492
78
        fde->next == NULL ? EH_FRAME_ALIGNMENT : 2);
2493
78
      }
2494
2495
134
    for (cie = cie_root; cie; cie = cie_next)
2496
68
      {
2497
68
        cie_next = cie->next;
2498
68
        free (cie);
2499
68
      }
2500
66
    cie_root = NULL;
2501
66
  }
2502
66
      while (EH_FRAME_LINKONCE && seek_next_seg == 2);
2503
2504
66
      if (EH_FRAME_LINKONCE)
2505
0
  for (fde = all_fde_data; fde ; fde = fde->next)
2506
0
    SET_HANDLED (fde, 0);
2507
2508
#if SUPPORT_COMPACT_EH
2509
      if (compact_eh)
2510
  {
2511
    /* Create remaining out of line table entries.  */
2512
    do
2513
      {
2514
        ccseg = NULL;
2515
        seek_next_seg = 0;
2516
2517
        for (fde = all_fde_data; fde ; fde = fde->next)
2518
    {
2519
      if ((fde->sections & CFI_EMIT_eh_frame) == 0
2520
          && (fde->sections & CFI_EMIT_eh_frame_compact) == 0)
2521
        continue;
2522
2523
      if (fde->eh_header_type != EH_COMPACT_OUTLINE)
2524
        continue;
2525
      if (HANDLED (fde))
2526
        continue;
2527
      if (seek_next_seg && CUR_SEG (fde) != ccseg)
2528
        {
2529
          seek_next_seg = 2;
2530
          continue;
2531
        }
2532
      if (!seek_next_seg)
2533
        {
2534
          ccseg = CUR_SEG (fde);
2535
          /* Open .gnu_extab section.  */
2536
          get_cfi_seg (ccseg, ".gnu_extab",
2537
           (SEC_ALLOC | SEC_LOAD | SEC_DATA
2538
            | DWARF2_EH_FRAME_READ_ONLY),
2539
           1);
2540
          seek_next_seg = 1;
2541
        }
2542
      SET_HANDLED (fde, 1);
2543
2544
      frag_align (1, 0, 0);
2545
      record_alignment (now_seg, 1);
2546
      output_compact_unwind_data (fde, 1);
2547
    }
2548
      }
2549
    while (EH_FRAME_LINKONCE && seek_next_seg == 2);
2550
2551
    for (fde = all_fde_data; fde ; fde = fde->next)
2552
      SET_HANDLED (fde, 0);
2553
2554
    /* Create index table fragments.  */
2555
    do
2556
      {
2557
        ccseg = NULL;
2558
        seek_next_seg = 0;
2559
2560
        for (fde = all_fde_data; fde ; fde = fde->next)
2561
    {
2562
      if ((fde->sections & CFI_EMIT_eh_frame) == 0
2563
          && (fde->sections & CFI_EMIT_eh_frame_compact) == 0)
2564
        continue;
2565
2566
      if (HANDLED (fde))
2567
        continue;
2568
      if (seek_next_seg && CUR_SEG (fde) != ccseg)
2569
        {
2570
          seek_next_seg = 2;
2571
          continue;
2572
        }
2573
      if (!seek_next_seg)
2574
        {
2575
          ccseg = CUR_SEG (fde);
2576
          /* Open .eh_frame_entry section.  */
2577
          cfi_seg = get_cfi_seg (ccseg, ".eh_frame_entry",
2578
               (SEC_ALLOC | SEC_LOAD | SEC_DATA
2579
                | DWARF2_EH_FRAME_READ_ONLY),
2580
               2);
2581
          seek_next_seg = 1;
2582
        }
2583
      SET_HANDLED (fde, 1);
2584
2585
      output_eh_header (fde);
2586
    }
2587
      }
2588
    while (seek_next_seg == 2);
2589
2590
    for (fde = all_fde_data; fde ; fde = fde->next)
2591
      SET_HANDLED (fde, 0);
2592
  }
2593
#endif /* SUPPORT_COMPACT_EH */
2594
2595
66
      flag_traditional_format = save_flag_traditional_format;
2596
66
    }
2597
2598
  /* Generate SFrame section if the user:
2599
  - enables via the command line option, or
2600
  - default-enabled at configure-time via --enable-default-sframe, or
2601
  - specifies .sframe in the .cfi_sections directive and does not disable
2602
    via the command line.  */
2603
77
  if (flag_gen_sframe == GEN_SFRAME_ENABLED
2604
77
      || flag_gen_sframe == GEN_SFRAME_CONFIG_ENABLED
2605
77
      || ((all_cfi_sections & CFI_EMIT_sframe) != 0
2606
11
    && flag_gen_sframe != GEN_SFRAME_DISABLED))
2607
11
    {
2608
11
#ifdef support_sframe_p
2609
11
      if (support_sframe_p () && !SUPPORT_FRAME_LINKONCE)
2610
11
  {
2611
11
    segT sframe_seg;
2612
11
    int alignment = ffs (DWARF2_ADDR_SIZE (stdoutput)) - 1;
2613
2614
11
    sframe_seg = get_cfi_seg (NULL, ".sframe",
2615
11
            (SEC_ALLOC | SEC_LOAD | SEC_DATA
2616
11
             | DWARF2_EH_FRAME_READ_ONLY),
2617
11
            alignment);
2618
11
    elf_section_type (sframe_seg) = SHT_GNU_SFRAME;
2619
11
    output_sframe (sframe_seg);
2620
11
  }
2621
0
      else
2622
0
#endif
2623
  /* Avoid erroring with DEFAULT_SFRAME for non-default options, like
2624
     -32 on x86_64.  */
2625
0
  sframe_as_bad ("%s", _(".sframe not supported for target"));
2626
11
    }
2627
2628
77
  if ((all_cfi_sections & CFI_EMIT_debug_frame) != 0)
2629
3
    {
2630
3
      int alignment = ffs (DWARF2_ADDR_SIZE (stdoutput)) - 1;
2631
2632
3
      if (!SUPPORT_FRAME_LINKONCE)
2633
3
  get_cfi_seg (NULL, ".debug_frame",
2634
3
         SEC_READONLY | SEC_DEBUGGING,
2635
3
         alignment);
2636
2637
3
      do
2638
3
  {
2639
3
    ccseg = NULL;
2640
3
    seek_next_seg = 0;
2641
2642
11
    for (fde = all_fde_data; fde ; fde = fde->next)
2643
8
      {
2644
8
        if ((fde->sections & CFI_EMIT_debug_frame) == 0)
2645
3
    continue;
2646
2647
5
        if (SUPPORT_FRAME_LINKONCE)
2648
0
    {
2649
0
      if (HANDLED (fde))
2650
0
        continue;
2651
0
      if (seek_next_seg && CUR_SEG (fde) != ccseg)
2652
0
        {
2653
0
          seek_next_seg = 2;
2654
0
          continue;
2655
0
        }
2656
0
      if (!seek_next_seg)
2657
0
        {
2658
0
          ccseg = CUR_SEG (fde);
2659
          /* Open .debug_frame section.  */
2660
0
          get_cfi_seg (ccseg, ".debug_frame",
2661
0
           SEC_READONLY | SEC_DEBUGGING,
2662
0
           alignment);
2663
0
          seek_next_seg = 1;
2664
0
        }
2665
0
      SET_HANDLED (fde, 1);
2666
0
    }
2667
5
        if (fde->end_address == NULL)
2668
2
    {
2669
2
      as_bad (_("open CFI at the end of file; "
2670
2
          "missing .cfi_endproc directive"));
2671
2
      fde->end_address = fde->start_address;
2672
2
    }
2673
2674
5
        fde->per_encoding = DW_EH_PE_omit;
2675
5
        fde->lsda_encoding = DW_EH_PE_omit;
2676
5
        cfi_change_reg_numbers (fde->data, ccseg);
2677
5
        cie = select_cie_for_fde (fde, false, &first, alignment);
2678
5
        output_fde (fde, cie, false, first, alignment);
2679
5
      }
2680
2681
6
    for (cie = cie_root; cie; cie = cie_next)
2682
3
      {
2683
3
        cie_next = cie->next;
2684
3
        free (cie);
2685
3
      }
2686
3
    cie_root = NULL;
2687
3
  }
2688
3
      while (SUPPORT_FRAME_LINKONCE && seek_next_seg == 2);
2689
2690
3
      if (SUPPORT_FRAME_LINKONCE)
2691
0
  for (fde = all_fde_data; fde ; fde = fde->next)
2692
0
    SET_HANDLED (fde, 0);
2693
3
    }
2694
77
  all_fde_data = NULL;
2695
77
  last_fde_data = &all_fde_data;
2696
77
  cfi_sections_set = false;
2697
77
  cfi_sections = CFI_EMIT_eh_frame;
2698
77
  all_cfi_sections = 0;
2699
77
  last_fde = NULL;
2700
77
  if (dwcfi_hash)
2701
0
    {
2702
0
      htab_delete (dwcfi_hash);
2703
0
      dwcfi_hash = NULL;
2704
0
    }
2705
2706
77
#ifndef NO_LISTING
2707
77
  if (saved_listing_tail)
2708
0
    listing_tail = saved_listing_tail;
2709
77
#endif
2710
77
}
2711
2712
#else /* TARGET_USE_CFIPOP */
2713
2714
/* Emit an intelligible error message for missing support.  */
2715
2716
static void
2717
dot_cfi_dummy (int ignored ATTRIBUTE_UNUSED)
2718
{
2719
  as_bad (_("CFI is not supported for this target"));
2720
  ignore_rest_of_line ();
2721
}
2722
2723
const pseudo_typeS cfi_pseudo_table[] =
2724
  {
2725
    { "cfi_sections", dot_cfi_dummy, 0 },
2726
    { "cfi_startproc", dot_cfi_dummy, 0 },
2727
    { "cfi_endproc", dot_cfi_dummy, 0 },
2728
    { "cfi_fde_data", dot_cfi_dummy, 0 },
2729
    { "cfi_def_cfa", dot_cfi_dummy, 0 },
2730
    { "cfi_def_cfa_register", dot_cfi_dummy, 0 },
2731
    { "cfi_def_cfa_offset", dot_cfi_dummy, 0 },
2732
    { "cfi_adjust_cfa_offset", dot_cfi_dummy, 0 },
2733
    { "cfi_offset", dot_cfi_dummy, 0 },
2734
    { "cfi_rel_offset", dot_cfi_dummy, 0 },
2735
    { "cfi_register", dot_cfi_dummy, 0 },
2736
    { "cfi_return_column", dot_cfi_dummy, 0 },
2737
    { "cfi_restore", dot_cfi_dummy, 0 },
2738
    { "cfi_undefined", dot_cfi_dummy, 0 },
2739
    { "cfi_same_value", dot_cfi_dummy, 0 },
2740
    { "cfi_remember_state", dot_cfi_dummy, 0 },
2741
    { "cfi_restore_state", dot_cfi_dummy, 0 },
2742
    { "cfi_window_save", dot_cfi_dummy, 0 },
2743
    { "cfi_negate_ra_state", dot_cfi_dummy, 0 },
2744
    { "cfi_negate_ra_state_with_pc", dot_cfi_dummy, 0 },
2745
    { "cfi_escape", dot_cfi_dummy, 0 },
2746
    { "cfi_signal_frame", dot_cfi_dummy, 0 },
2747
    { "cfi_personality", dot_cfi_dummy, 0 },
2748
    { "cfi_personality_id", dot_cfi_dummy, 0 },
2749
    { "cfi_lsda", dot_cfi_dummy, 0 },
2750
    { "cfi_val_encoded_addr", dot_cfi_dummy, 0 },
2751
    { "cfi_inline_lsda", dot_cfi_dummy, 0 },
2752
    { "cfi_label", dot_cfi_dummy, 0 },
2753
    { "cfi_val_offset", dot_cfi_dummy, 0 },
2754
    { NULL, NULL, 0 }
2755
  };
2756
2757
void
2758
cfi_finish (void)
2759
{
2760
}
2761
#endif /* TARGET_USE_CFIPOP */