Coverage Report

Created: 2026-10-02 09:53

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
354
#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
387
#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
67
#define DWARF2_EH_FRAME_READ_ONLY SEC_READONLY
61
#endif
62
63
#ifndef EH_FRAME_ALIGNMENT
64
88
#define EH_FRAME_ALIGNMENT (bfd_get_arch_size (stdoutput) == 64 ? 3 : 2)
65
#endif
66
67
502
#define EH_FRAME_LINKONCE (SUPPORT_FRAME_LINKONCE || compact_eh \
68
502
         || TARGET_MULTIPLE_EH_FRAME_SECTIONS)
69
70
#ifndef DWARF2_FORMAT
71
398
#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.35k
#define CUR_SEG(structp) NULL
85
2.39k
#define SET_CUR_SEG(structp, seg) (void) (0 && seg)
86
0
#define HANDLED(structp) 0
87
353
#define SET_HANDLED(structp, val) (void) (0 && val)
88
#endif
89
90
#ifndef tc_cfi_reloc_for_encoding
91
334
#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.18k
{
115
1.18k
  FRAG_APPEND_1_CHAR (byte);
116
1.18k
}
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
198
{
131
198
  md_number_to_chars (frag_more (4), data, 4);
132
198
}
133
134
/* Emit an unsigned "little-endian base 128" number.  */
135
136
static void
137
out_uleb128 (addressT value)
138
1.20k
{
139
1.20k
  output_leb128 (frag_more (sizeof_leb128 (value, 0)), value, 0);
140
1.20k
}
141
142
/* Emit an unsigned "little-endian base 128" number.  */
143
144
static void
145
out_sleb128 (offsetT value)
146
74
{
147
74
  output_leb128 (frag_more (sizeof_leb128 (value, 1)), value, 1);
148
74
}
149
150
static unsigned int
151
encoding_size (unsigned char encoding)
152
733
{
153
733
  if (encoding == DW_EH_PE_omit)
154
717
    return 0;
155
16
  switch (encoding & 0x7)
156
16
    {
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
2
    case DW_EH_PE_udata4:
162
2
      return 4;
163
4
    case DW_EH_PE_udata8:
164
4
      return 8;
165
0
    default:
166
0
      abort ();
167
16
    }
168
16
}
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
388
{
176
388
  unsigned int size = encoding_size (encoding);
177
388
  bfd_reloc_code_real_type code;
178
179
388
  if (encoding == DW_EH_PE_omit)
180
380
    return;
181
182
8
  if (emit_encoding)
183
8
    out_one (encoding);
184
185
8
  code = tc_cfi_reloc_for_encoding (encoding);
186
8
  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
8
  else if ((encoding & 0x70) == DW_EH_PE_pcrel)
196
0
    {
197
0
#if CFI_DIFF_EXPR_OK
198
0
      expressionS tmp = *exp;
199
0
      tmp.X_op = O_subtract;
200
0
      tmp.X_op_symbol = symbol_temp_new_now ();
201
0
      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
0
    }
208
8
  else
209
8
    emit_expr (exp, size);
210
8
}
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
11
#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
11
{
357
11
  expressionS exp;
358
359
11
  exp.X_op = O_symbol;
360
11
  exp.X_add_symbol = symbol;
361
11
  exp.X_add_number = 0;
362
11
  emit_expr (&exp, size);
363
11
}
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
353
{
398
353
  struct fde_entry *fde = notes_calloc (1, sizeof (*fde));
399
400
353
  frchain_now->frch_cfi_data = notes_calloc (1, sizeof (struct frch_cfi_data));
401
353
  frchain_now->frch_cfi_data->cur_fde_data = fde;
402
353
  *last_fde_data = fde;
403
353
  last_fde_data = &fde->next;
404
353
  SET_CUR_SEG (fde, is_now_linkonce_segment ());
405
353
  SET_HANDLED (fde, 0);
406
353
  fde->last = &fde->data;
407
353
  fde->return_column = DWARF2_DEFAULT_RETURN_COLUMN;
408
353
  fde->per_encoding = DW_EH_PE_omit;
409
353
  fde->lsda_encoding = DW_EH_PE_omit;
410
353
  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
353
  return fde;
416
353
}
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.98k
{
432
1.98k
  struct cfi_insn_data *insn = notes_calloc (1, sizeof (*insn));
433
1.98k
  struct fde_entry *cur_fde_data = frchain_now->frch_cfi_data->cur_fde_data;
434
435
1.98k
  *cur_fde_data->last = insn;
436
1.98k
  cur_fde_data->last = &insn->next;
437
1.98k
  SET_CUR_SEG (insn, is_now_linkonce_segment ());
438
1.98k
#ifndef NO_LISTING
439
1.98k
  insn->listing_ctxt = cur_fde_data->listing_ctxt ? listing_tail : NULL;
440
1.98k
#endif
441
1.98k
  return insn;
442
1.98k
}
443
444
/* Construct a new FDE structure that begins at LABEL.  */
445
446
void
447
cfi_new_fde (symbolS *label, bool do_listing)
448
353
{
449
353
  struct fde_entry *fde = alloc_fde_entry ();
450
353
  fde->start_address = label;
451
353
  if (do_listing)
452
0
    {
453
0
#ifndef NO_LISTING
454
0
      fde->listing_ctxt = listing_tail;
455
0
#endif
456
0
    }
457
353
  frchain_now->frch_cfi_data->last_address = label;
458
353
}
459
460
/* End the currently open FDE.  */
461
462
void
463
cfi_end_fde (symbolS *label)
464
1
{
465
1
  struct fde_entry *cur_fde_data = frchain_now->frch_cfi_data->cur_fde_data;
466
467
1
  cur_fde_data->end_address = label;
468
1
#ifndef NO_LISTING
469
1
  cur_fde_data->listing_end = cur_fde_data->listing_ctxt ? listing_tail : NULL;
470
1
#endif
471
1
  frchain_now->frch_cfi_data = NULL;
472
1
}
473
474
/* Set the last FDE  .*/
475
void
476
cfi_set_last_fde (struct fde_entry *fde)
477
1
{
478
1
  last_fde = fde;
479
1
}
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
353
{
492
353
  all_cfi_sections |= cfi_sections;
493
353
  frchain_now->frch_cfi_data->cur_fde_data->sections = all_cfi_sections;
494
353
  cfi_sections_set = true;
495
353
}
496
497
/* Universal functions to store new instructions.  */
498
499
static void
500
cfi_add_CFA_insn (int insn)
501
2
{
502
2
  struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data ();
503
504
2
  insn_ptr->insn = insn;
505
2
}
506
507
static void
508
cfi_add_CFA_insn_reg (int insn, unsigned regno)
509
194
{
510
194
  struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data ();
511
512
194
  insn_ptr->insn = insn;
513
194
  insn_ptr->u.r = regno;
514
194
}
515
516
static void
517
cfi_add_CFA_insn_offset (int insn, offsetT offset)
518
420
{
519
420
  struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data ();
520
521
420
  insn_ptr->insn = insn;
522
420
  insn_ptr->u.i = offset;
523
420
}
524
525
static void
526
cfi_add_CFA_insn_reg_reg (int insn, unsigned reg1, unsigned reg2)
527
21
{
528
21
  struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data ();
529
530
21
  insn_ptr->insn = insn;
531
21
  insn_ptr->u.rr.reg1 = reg1;
532
21
  insn_ptr->u.rr.reg2 = reg2;
533
21
}
534
535
static void
536
cfi_add_CFA_insn_reg_offset (int insn, unsigned regno, offsetT offset)
537
918
{
538
918
  struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data ();
539
540
918
  insn_ptr->insn = insn;
541
918
  insn_ptr->u.ri.reg = regno;
542
918
  insn_ptr->u.ri.offset = offset;
543
918
}
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
331
{
550
331
  struct cfi_insn_data *insn = alloc_cfi_insn_data ();
551
552
331
  insn->insn = DW_CFA_advance_loc;
553
331
  insn->u.ll.lab1 = frchain_now->frch_cfi_data->last_address;
554
331
  insn->u.ll.lab2 = label;
555
556
331
  frchain_now->frch_cfi_data->last_address = label;
557
331
}
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
14
{
564
14
  struct cfi_insn_data *insn = alloc_cfi_insn_data ();
565
566
14
  insn->insn = CFI_label;
567
14
  insn->u.sym_name = notes_strdup (name);
568
14
}
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
384
{
575
384
  unsigned int abs_data_align;
576
577
384
  gas_assert (DWARF2_CIE_DATA_ALIGNMENT != 0);
578
384
  cfi_add_CFA_insn_reg_offset (DW_CFA_offset, regno, offset);
579
580
384
  abs_data_align = (DWARF2_CIE_DATA_ALIGNMENT < 0
581
384
        ? -DWARF2_CIE_DATA_ALIGNMENT : DWARF2_CIE_DATA_ALIGNMENT);
582
384
  if (offset % abs_data_align)
583
13
    as_bad (_("register save offset not a multiple of %u"), abs_data_align);
584
384
}
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
40
{
591
40
  unsigned int abs_data_align;
592
593
40
  gas_assert (DWARF2_CIE_DATA_ALIGNMENT != 0);
594
40
  cfi_add_CFA_insn_reg_offset (DW_CFA_val_offset, regno, offset);
595
596
40
  abs_data_align = (DWARF2_CIE_DATA_ALIGNMENT < 0
597
40
        ? -DWARF2_CIE_DATA_ALIGNMENT : DWARF2_CIE_DATA_ALIGNMENT);
598
40
  if (offset % abs_data_align)
599
10
    as_bad (_("register save offset not a multiple of %u"), abs_data_align);
600
40
}
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
494
{
607
494
  cfi_add_CFA_insn_reg_offset (DW_CFA_def_cfa, regno, offset);
608
494
  frchain_now->frch_cfi_data->cur_cfa_offset = offset;
609
494
}
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
21
{
616
21
  cfi_add_CFA_insn_reg_reg (DW_CFA_register, reg1, reg2);
617
21
}
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
5
{
624
5
  cfi_add_CFA_insn_reg (DW_CFA_def_cfa_register, regno);
625
5
}
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
420
{
632
420
  cfi_add_CFA_insn_offset (DW_CFA_def_cfa_offset, offset);
633
420
  frchain_now->frch_cfi_data->cur_cfa_offset = offset;
634
420
}
635
636
void
637
cfi_add_CFA_restore (unsigned regno)
638
33
{
639
33
  cfi_add_CFA_insn_reg (DW_CFA_restore, regno);
640
33
}
641
642
void
643
cfi_add_CFA_undefined (unsigned regno)
644
156
{
645
156
  cfi_add_CFA_insn_reg (DW_CFA_undefined, regno);
646
156
}
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
309
{
736
309
  SKIP_WHITESPACE ();
737
309
  if (*input_line_pointer == ',')
738
36
    input_line_pointer++;
739
273
  else
740
273
    as_bad (_("missing separator"));
741
309
}
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
492
{
771
492
  int regno;
772
492
  expressionS exp;
773
774
492
  tc_parse_to_dw2regnum (&exp);
775
492
  switch (exp.X_op)
776
492
    {
777
0
    case O_register:
778
145
    case O_constant:
779
145
      regno = exp.X_add_number;
780
145
      break;
781
782
347
    default:
783
347
      regno = -1;
784
347
      break;
785
492
    }
786
787
492
  if (regno < 0)
788
347
    {
789
347
      as_bad (_("bad register expression"));
790
347
      regno = 0;
791
347
    }
792
793
492
  return regno;
794
492
}
795
796
static offsetT
797
cfi_parse_const (void)
798
749
{
799
749
  return get_absolute_expression ();
800
749
}
801
802
static void
803
dot_cfi (int arg)
804
709
{
805
709
  offsetT offset;
806
709
  unsigned reg1, reg2;
807
808
709
  if (frchain_now->frch_cfi_data == NULL)
809
8
    {
810
8
      as_bad (_("CFI instruction used without previous .cfi_startproc"));
811
8
      ignore_rest_of_line ();
812
8
      return;
813
8
    }
814
815
  /* If the last address was not at the current PC, advance to current.  */
816
701
  if (symbol_get_frag (frchain_now->frch_cfi_data->last_address) != frag_now
817
678
      || (S_GET_VALUE (frchain_now->frch_cfi_data->last_address)
818
678
    != frag_now_fix ()))
819
309
    cfi_add_advance_loc (symbol_temp_new_now ());
820
821
701
  switch (arg)
822
701
    {
823
10
    case DW_CFA_offset:
824
10
      reg1 = cfi_parse_reg ();
825
10
      cfi_parse_separator ();
826
10
      offset = cfi_parse_const ();
827
10
      cfi_add_CFA_offset (reg1, offset);
828
10
      break;
829
830
40
    case DW_CFA_val_offset:
831
40
      reg1 = cfi_parse_reg ();
832
40
      cfi_parse_separator ();
833
40
      offset = cfi_parse_const ();
834
40
      cfi_add_CFA_val_offset (reg1, offset);
835
40
      break;
836
837
27
    case CFI_rel_offset:
838
27
      reg1 = cfi_parse_reg ();
839
27
      cfi_parse_separator ();
840
27
      offset = cfi_parse_const ();
841
27
      cfi_add_CFA_offset (reg1,
842
27
        offset - frchain_now->frch_cfi_data->cur_cfa_offset);
843
27
      break;
844
845
147
    case DW_CFA_def_cfa:
846
147
      reg1 = cfi_parse_reg ();
847
147
      cfi_parse_separator ();
848
147
      offset = cfi_parse_const ();
849
147
      cfi_add_CFA_def_cfa (reg1, offset);
850
147
      break;
851
852
21
    case DW_CFA_register:
853
21
      reg1 = cfi_parse_reg ();
854
21
      cfi_parse_separator ();
855
21
      reg2 = cfi_parse_reg ();
856
21
      cfi_add_CFA_register (reg1, reg2);
857
21
      break;
858
859
5
    case DW_CFA_def_cfa_register:
860
5
      reg1 = cfi_parse_reg ();
861
5
      cfi_add_CFA_def_cfa_register (reg1);
862
5
      break;
863
864
420
    case DW_CFA_def_cfa_offset:
865
420
      offset = cfi_parse_const ();
866
420
      cfi_add_CFA_def_cfa_offset (offset);
867
420
      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
13
    case DW_CFA_restore:
876
13
      for (;;)
877
33
  {
878
33
    reg1 = cfi_parse_reg ();
879
33
    cfi_add_CFA_restore (reg1);
880
33
    SKIP_WHITESPACE ();
881
33
    if (*input_line_pointer != ',')
882
13
      break;
883
20
    ++input_line_pointer;
884
20
  }
885
13
      break;
886
887
16
    case DW_CFA_undefined:
888
16
      for (;;)
889
156
  {
890
156
    reg1 = cfi_parse_reg ();
891
156
    cfi_add_CFA_undefined (reg1);
892
156
    SKIP_WHITESPACE ();
893
156
    if (*input_line_pointer != ',')
894
16
      break;
895
140
    ++input_line_pointer;
896
140
  }
897
16
      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
2
    case DW_CFA_GNU_window_save:
918
2
      cfi_add_CFA_insn (DW_CFA_GNU_window_save);
919
2
      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
701
    }
932
933
701
  demand_empty_rest_of_line ();
934
701
}
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
54
{
954
54
  struct cfi_escape_data *head, **tail;
955
54
  struct cfi_insn_data *insn;
956
957
54
  if (frchain_now->frch_cfi_data == NULL)
958
5
    {
959
5
      as_bad (_("CFI instruction used without previous .cfi_startproc"));
960
5
      ignore_rest_of_line ();
961
5
      return;
962
5
    }
963
964
  /* If the last address was not at the current PC, advance to current.  */
965
49
  if (symbol_get_frag (frchain_now->frch_cfi_data->last_address) != frag_now
966
38
      || (S_GET_VALUE (frchain_now->frch_cfi_data->last_address)
967
38
    != frag_now_fix ()))
968
11
    cfi_add_advance_loc (symbol_temp_new_now ());
969
970
49
  tail = &head;
971
49
  do
972
123
    {
973
123
      struct cfi_escape_data *e = notes_alloc (sizeof (*e));
974
123
      char *id, *ilp_save = input_line_pointer;
975
123
      char c = get_symbol_name (&id);
976
977
123
      if (strcmp (id, "sleb128") == 0)
978
2
  e->type = CFI_ESC_sleb128;
979
121
      else if (strcmp (id, "uleb128") == 0)
980
1
  e->type = CFI_ESC_uleb128;
981
120
      else if (strcmp (id, "data2") == 0)
982
7
  e->type = 2;
983
113
      else if (TC_ADDRESS_BYTES () >= 4 && strcmp (id, "data4") == 0)
984
2
  e->type = 4;
985
111
      else if (TC_ADDRESS_BYTES () >= 8 && strcmp (id, "data8") == 0)
986
1
  e->type = 8;
987
110
      else if (strcmp (id, "addr") == 0)
988
0
  e->type = TC_ADDRESS_BYTES ();
989
110
      else
990
110
  e->type = CFI_ESC_byte;
991
992
123
      c = restore_line_pointer (c);
993
994
123
      if (e->type != CFI_ESC_byte)
995
13
  {
996
13
    if (is_whitespace (c))
997
1
      c = *++input_line_pointer;
998
13
    if (c != '(')
999
11
      e->type = CFI_ESC_byte;
1000
13
  }
1001
123
      if (e->type == CFI_ESC_byte)
1002
121
  input_line_pointer = ilp_save;
1003
1004
123
      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
123
      else
1012
123
  {
1013
    /* We may still be at an opening parenthesis.  Leave it to expression()
1014
       to parse it and find the matching closing one.  */
1015
123
    e->reloc = do_parse_cons_expression (&e->exp, e->type);
1016
123
  }
1017
1018
123
      *tail = e;
1019
123
      tail = &e->next;
1020
123
    }
1021
123
  while (*input_line_pointer++ == ',');
1022
49
  *tail = NULL;
1023
1024
49
  insn = alloc_cfi_insn_data ();
1025
49
  insn->insn = CFI_escape;
1026
49
  insn->u.esc = head;
1027
1028
49
  --input_line_pointer;
1029
49
  demand_empty_rest_of_line ();
1030
49
}
1031
1032
static void
1033
dot_cfi_personality (int ignored ATTRIBUTE_UNUSED)
1034
63
{
1035
63
  struct fde_entry *fde;
1036
63
  offsetT encoding;
1037
1038
63
  if (frchain_now->frch_cfi_data == NULL)
1039
1
    {
1040
1
      as_bad (_("CFI instruction used without previous .cfi_startproc"));
1041
1
      ignore_rest_of_line ();
1042
1
      return;
1043
1
    }
1044
1045
62
  fde = frchain_now->frch_cfi_data->cur_fde_data;
1046
62
  encoding = cfi_parse_const ();
1047
62
  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
62
  if ((encoding & 0xff) != encoding
1055
60
      || ((((encoding & 0x70) != 0
1056
22
#if CFI_DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr
1057
22
      && (encoding & 0x70) != DW_EH_PE_pcrel
1058
60
#endif
1059
60
      )
1060
     /* leb128 can be handled, but does something actually need it?  */
1061
38
     || (encoding & 7) == DW_EH_PE_uleb128
1062
38
     || (encoding & 7) > DW_EH_PE_udata8)
1063
0
    && tc_cfi_reloc_for_encoding (encoding) == BFD_RELOC_NONE))
1064
30
    {
1065
30
      as_bad (_("invalid or unsupported encoding in .cfi_personality"));
1066
30
      ignore_rest_of_line ();
1067
30
      return;
1068
30
    }
1069
1070
32
  if (*input_line_pointer++ != ',')
1071
1
    {
1072
1
      as_bad (_(".cfi_personality requires encoding and symbol arguments"));
1073
1
      ignore_rest_of_line ();
1074
1
      return;
1075
1
    }
1076
1077
31
  expression_and_evaluate (&fde->personality);
1078
31
  switch (fde->personality.X_op)
1079
31
    {
1080
13
    case O_symbol:
1081
13
      break;
1082
18
    case O_constant:
1083
18
      if ((encoding & 0x70) == DW_EH_PE_pcrel)
1084
0
  encoding = DW_EH_PE_omit;
1085
18
      break;
1086
0
    default:
1087
0
      encoding = DW_EH_PE_omit;
1088
0
      break;
1089
31
    }
1090
1091
31
  fde->per_encoding = encoding;
1092
1093
31
  if (encoding == DW_EH_PE_omit)
1094
0
    {
1095
0
      as_bad (_("wrong second argument to .cfi_personality"));
1096
0
      ignore_rest_of_line ();
1097
0
      return;
1098
0
    }
1099
1100
31
  demand_empty_rest_of_line ();
1101
31
}
1102
1103
static void
1104
dot_cfi_lsda (int ignored ATTRIBUTE_UNUSED)
1105
14
{
1106
14
  struct fde_entry *fde;
1107
14
  offsetT encoding;
1108
1109
14
  if (frchain_now->frch_cfi_data == NULL)
1110
3
    {
1111
3
      as_bad (_("CFI instruction used without previous .cfi_startproc"));
1112
3
      ignore_rest_of_line ();
1113
3
      return;
1114
3
    }
1115
1116
11
  fde = frchain_now->frch_cfi_data->cur_fde_data;
1117
11
  encoding = cfi_parse_const ();
1118
11
  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
11
  if ((encoding & 0xff) != encoding
1126
10
      || ((((encoding & 0x70) != 0
1127
9
#if CFI_DIFF_LSDA_OK || defined tc_cfi_emit_pcrel_expr
1128
9
      && (encoding & 0x70) != DW_EH_PE_pcrel
1129
10
#endif
1130
10
      )
1131
     /* leb128 can be handled, but does something actually need it?  */
1132
2
     || (encoding & 7) == DW_EH_PE_uleb128
1133
2
     || (encoding & 7) > DW_EH_PE_udata8)
1134
0
    && tc_cfi_reloc_for_encoding (encoding) == BFD_RELOC_NONE))
1135
9
    {
1136
9
      as_bad (_("invalid or unsupported encoding in .cfi_lsda"));
1137
9
      ignore_rest_of_line ();
1138
9
      return;
1139
9
    }
1140
1141
2
  if (*input_line_pointer++ != ',')
1142
1
    {
1143
1
      as_bad (_(".cfi_lsda requires encoding and symbol arguments"));
1144
1
      ignore_rest_of_line ();
1145
1
      return;
1146
1
    }
1147
1148
1
  fde->lsda_encoding = encoding;
1149
1150
1
  expression_and_evaluate (&fde->lsda);
1151
1
  switch (fde->lsda.X_op)
1152
1
    {
1153
1
    case O_symbol:
1154
1
      break;
1155
0
    case O_constant:
1156
0
      if ((encoding & 0x70) == DW_EH_PE_pcrel)
1157
0
  encoding = DW_EH_PE_omit;
1158
0
      break;
1159
0
    default:
1160
0
      encoding = DW_EH_PE_omit;
1161
0
      break;
1162
1
    }
1163
1164
1
  fde->lsda_encoding = encoding;
1165
1166
1
  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
1
  demand_empty_rest_of_line ();
1174
1
}
1175
1176
static void
1177
dot_cfi_val_encoded_addr (int ignored ATTRIBUTE_UNUSED)
1178
33
{
1179
33
  struct cfi_insn_data *insn_ptr;
1180
33
  offsetT encoding;
1181
1182
33
  if (frchain_now->frch_cfi_data == NULL)
1183
1
    {
1184
1
      as_bad (_("CFI instruction used without previous .cfi_startproc"));
1185
1
      ignore_rest_of_line ();
1186
1
      return;
1187
1
    }
1188
1189
  /* If the last address was not at the current PC, advance to current.  */
1190
32
  if (symbol_get_frag (frchain_now->frch_cfi_data->last_address) != frag_now
1191
31
      || (S_GET_VALUE (frchain_now->frch_cfi_data->last_address)
1192
31
    != frag_now_fix ()))
1193
1
    cfi_add_advance_loc (symbol_temp_new_now ());
1194
1195
32
  insn_ptr = alloc_cfi_insn_data ();
1196
32
  insn_ptr->insn = CFI_val_encoded_addr;
1197
1198
32
  insn_ptr->u.ea.reg = cfi_parse_reg ();
1199
1200
32
  cfi_parse_separator ();
1201
32
  encoding = cfi_parse_const ();
1202
32
  if ((encoding & 0xff) != encoding
1203
31
      || ((encoding & 0x70) != 0
1204
24
#if CFI_DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr
1205
24
    && (encoding & 0x70) != DW_EH_PE_pcrel
1206
31
#endif
1207
31
    )
1208
      /* leb128 can be handled, but does something actually need it?  */
1209
31
      || (encoding & 7) == DW_EH_PE_uleb128
1210
31
      || (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
32
  cfi_parse_separator ();
1217
32
  expression_and_evaluate (&insn_ptr->u.ea.exp);
1218
32
  switch (insn_ptr->u.ea.exp.X_op)
1219
32
    {
1220
11
    case O_symbol:
1221
11
      break;
1222
2
    case O_constant:
1223
2
      if ((encoding & 0x70) != DW_EH_PE_pcrel)
1224
0
  break;
1225
      /* Fall through.  */
1226
21
    default:
1227
21
      encoding = DW_EH_PE_omit;
1228
21
      break;
1229
32
    }
1230
1231
32
  insn_ptr->u.ea.encoding = encoding;
1232
32
  if (encoding == DW_EH_PE_omit)
1233
21
    {
1234
21
      as_bad (_("wrong third argument to .cfi_val_encoded_addr"));
1235
21
      ignore_rest_of_line ();
1236
21
      return;
1237
21
    }
1238
1239
11
  demand_empty_rest_of_line ();
1240
11
}
1241
1242
static void
1243
dot_cfi_label (int ignored ATTRIBUTE_UNUSED)
1244
16
{
1245
16
  char *name;
1246
1247
16
  if (frchain_now->frch_cfi_data == NULL)
1248
2
    {
1249
2
      as_bad (_("CFI instruction used without previous .cfi_startproc"));
1250
2
      ignore_rest_of_line ();
1251
2
      return;
1252
2
    }
1253
1254
14
  name = read_symbol_name ();
1255
14
  if (name == NULL)
1256
0
    return;
1257
1258
  /* If the last address was not at the current PC, advance to current.  */
1259
14
  if (symbol_get_frag (frchain_now->frch_cfi_data->last_address) != frag_now
1260
4
      || (S_GET_VALUE (frchain_now->frch_cfi_data->last_address)
1261
4
    != frag_now_fix ()))
1262
10
    cfi_add_advance_loc (symbol_temp_new_now ());
1263
1264
14
  cfi_add_label (name);
1265
14
  free (name);
1266
1267
14
  demand_empty_rest_of_line ();
1268
14
}
1269
1270
void
1271
dot_cfi_sections (int ignored ATTRIBUTE_UNUSED)
1272
170
{
1273
170
  int sections = 0;
1274
1275
170
  SKIP_WHITESPACE ();
1276
170
  if (is_name_beginner (*input_line_pointer) || *input_line_pointer == '"')
1277
73
    while (1)
1278
73
      {
1279
73
  char * saved_ilp;
1280
73
  char *name, c;
1281
1282
73
  saved_ilp = input_line_pointer;
1283
73
  c = get_symbol_name (& name);
1284
1285
73
  if (startswith (name, ".eh_frame")
1286
0
      && name[9] != '_')
1287
0
    sections |= CFI_EMIT_eh_frame;
1288
73
  else if (startswith (name, ".debug_frame"))
1289
11
    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
27
      sections |= CFI_EMIT_sframe;
1303
35
  else
1304
35
    {
1305
35
      *input_line_pointer = c;
1306
35
      input_line_pointer = saved_ilp;
1307
35
      break;
1308
35
    }
1309
1310
38
  restore_line_pointer (c);
1311
38
  SKIP_WHITESPACE ();
1312
38
  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
38
  else if (is_name_beginner (*input_line_pointer)
1324
33
     || *input_line_pointer == '"')
1325
5
    break;
1326
38
      }
1327
1328
170
  demand_empty_rest_of_line ();
1329
170
  if (cfi_sections_set
1330
145
      && (sections & (CFI_EMIT_eh_frame | CFI_EMIT_eh_frame_compact))
1331
0
      && ((cfi_sections & (CFI_EMIT_eh_frame | CFI_EMIT_eh_frame_compact))
1332
0
    != (sections & (CFI_EMIT_eh_frame | CFI_EMIT_eh_frame_compact))))
1333
0
    as_bad (_("inconsistent uses of .cfi_sections"));
1334
170
  cfi_sections = sections;
1335
170
}
1336
1337
static void
1338
dot_cfi_startproc (int ignored ATTRIBUTE_UNUSED)
1339
779
{
1340
779
  int simple = 0;
1341
1342
779
  if (frchain_now->frch_cfi_data != NULL)
1343
426
    {
1344
426
      as_bad (_("previous CFI entry not closed (missing .cfi_endproc)"));
1345
426
      ignore_rest_of_line ();
1346
426
      return;
1347
426
    }
1348
1349
353
  cfi_new_fde (symbol_temp_new_now (), listing & LISTING_LISTING);
1350
1351
353
  SKIP_WHITESPACE ();
1352
353
  if (is_name_beginner (*input_line_pointer) || *input_line_pointer == '"')
1353
36
    {
1354
36
      char * saved_ilp = input_line_pointer;
1355
36
      char *name, c;
1356
1357
36
      c = get_symbol_name (& name);
1358
1359
36
      if (strcmp (name, "simple") == 0)
1360
6
  {
1361
6
    simple = 1;
1362
6
    restore_line_pointer (c);
1363
6
  }
1364
30
      else
1365
30
  input_line_pointer = saved_ilp;
1366
36
    }
1367
353
  demand_empty_rest_of_line ();
1368
1369
353
  cfi_set_sections ();
1370
1371
353
  frchain_now->frch_cfi_data->cur_cfa_offset = 0;
1372
353
  if (!simple)
1373
347
    tc_cfi_frame_initial_instructions ();
1374
1375
353
  if ((all_cfi_sections & CFI_EMIT_target) != 0)
1376
0
    tc_cfi_startproc ();
1377
353
}
1378
1379
static void
1380
dot_cfi_endproc (int ignored ATTRIBUTE_UNUSED)
1381
1
{
1382
1
  if (frchain_now->frch_cfi_data == NULL)
1383
0
    {
1384
0
      as_bad (_(".cfi_endproc without corresponding .cfi_startproc"));
1385
0
      ignore_rest_of_line ();
1386
0
      return;
1387
0
    }
1388
1389
1
  cfi_set_last_fde (frchain_now->frch_cfi_data->cur_fde_data);
1390
1391
1
  cfi_end_fde (symbol_temp_new_now ());
1392
1393
1
  demand_empty_rest_of_line ();
1394
1395
1
  if ((all_cfi_sections & CFI_EMIT_target) != 0)
1396
0
    tc_cfi_endproc (last_fde);
1397
1
}
1398
1399
static segT
1400
get_cfi_seg (segT cseg, const char *base, flagword flags, int align)
1401
74
{
1402
  /* Exclude .debug_frame sections for Compact EH.  */
1403
74
  if (SUPPORT_FRAME_LINKONCE || ((flags & SEC_DEBUGGING) == 0 && compact_eh)
1404
74
      || ((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
74
  else
1432
74
    {
1433
74
      cseg = subseg_new (base, 0);
1434
74
      bfd_set_section_flags (cseg, flags);
1435
74
    }
1436
74
  record_alignment (cseg, align);
1437
74
  return cseg;
1438
74
}
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
2
{
1638
2
  as_bad (_(".cfi_inline_lsda is not supported for this target"));
1639
2
  ignore_rest_of_line ();
1640
2
}
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
890
{
1660
890
  offsetT offset;
1661
890
  unsigned int regno;
1662
1663
890
  switch (insn->insn)
1664
890
    {
1665
293
    case DW_CFA_advance_loc:
1666
293
      {
1667
293
  symbolS *from = insn->u.ll.lab1;
1668
293
  symbolS *to = insn->u.ll.lab2;
1669
1670
293
  if (symbol_get_frag (to) == symbol_get_frag (from))
1671
274
    {
1672
274
      addressT delta = S_GET_VALUE (to) - S_GET_VALUE (from);
1673
274
      addressT scaled = delta / DWARF2_LINE_MIN_INSN_LENGTH;
1674
1675
274
      if (scaled == 0)
1676
0
        ;
1677
274
      else if (scaled <= 0x3F)
1678
137
        out_one (DW_CFA_advance_loc + scaled);
1679
137
      else if (scaled <= 0xFF)
1680
0
        {
1681
0
    out_one (DW_CFA_advance_loc1);
1682
0
    out_one (scaled);
1683
0
        }
1684
137
      else if (scaled <= 0xFFFF)
1685
0
        {
1686
0
    out_one (DW_CFA_advance_loc2);
1687
0
    out_two (scaled);
1688
0
        }
1689
137
      else
1690
137
        {
1691
137
    out_one (DW_CFA_advance_loc4);
1692
137
    out_four (scaled);
1693
137
        }
1694
274
    }
1695
19
  else
1696
19
    {
1697
19
      expressionS exp = {
1698
19
        .X_op = O_subtract,
1699
19
        .X_add_symbol = to,
1700
19
        .X_op_symbol = from,
1701
19
      };
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
19
      frag_grow (5);
1712
19
      *frag_more (1) = DW_CFA_advance_loc4;
1713
1714
19
      frag_var (rs_cfa, 4, 0, DWARF2_LINE_MIN_INSN_LENGTH << 3,
1715
19
          make_expr_symbol (&exp), frag_now_fix () - 1,
1716
19
          (char *) frag_now);
1717
19
    }
1718
293
      }
1719
293
      break;
1720
1721
199
    case DW_CFA_def_cfa:
1722
199
      offset = insn->u.ri.offset;
1723
199
      if (offset < 0)
1724
0
  {
1725
0
    out_one (DW_CFA_def_cfa_sf);
1726
0
    out_uleb128 (insn->u.ri.reg);
1727
0
    out_sleb128 (offset / DWARF2_CIE_DATA_ALIGNMENT);
1728
0
  }
1729
199
      else
1730
199
  {
1731
199
    out_one (DW_CFA_def_cfa);
1732
199
    out_uleb128 (insn->u.ri.reg);
1733
199
    out_uleb128 (offset);
1734
199
  }
1735
199
      break;
1736
1737
2
    case DW_CFA_def_cfa_register:
1738
73
    case DW_CFA_undefined:
1739
73
    case DW_CFA_same_value:
1740
73
      out_one (insn->insn);
1741
73
      out_uleb128 (insn->u.r);
1742
73
      break;
1743
1744
143
    case DW_CFA_def_cfa_offset:
1745
143
      offset = insn->u.i;
1746
143
      if (offset < 0)
1747
1
  {
1748
1
    out_one (DW_CFA_def_cfa_offset_sf);
1749
1
    out_sleb128 (offset / DWARF2_CIE_DATA_ALIGNMENT);
1750
1
  }
1751
142
      else
1752
142
  {
1753
142
    out_one (DW_CFA_def_cfa_offset);
1754
142
    out_uleb128 (offset);
1755
142
  }
1756
143
      break;
1757
1758
9
    case DW_CFA_restore:
1759
9
      regno = insn->u.r;
1760
9
      if (regno <= 0x3F)
1761
0
  {
1762
0
    out_one (DW_CFA_restore + regno);
1763
0
  }
1764
9
      else
1765
9
  {
1766
9
    out_one (DW_CFA_restore_extended);
1767
9
    out_uleb128 (regno);
1768
9
  }
1769
9
      break;
1770
1771
76
    case DW_CFA_offset:
1772
76
      regno = insn->u.ri.reg;
1773
76
      offset = insn->u.ri.offset / DWARF2_CIE_DATA_ALIGNMENT;
1774
76
      if (offset < 0)
1775
8
  {
1776
8
    out_one (DW_CFA_offset_extended_sf);
1777
8
    out_uleb128 (regno);
1778
8
    out_sleb128 (offset);
1779
8
  }
1780
68
      else if (regno <= 0x3F)
1781
68
  {
1782
68
    out_one (DW_CFA_offset + regno);
1783
68
    out_uleb128 (offset);
1784
68
  }
1785
0
      else
1786
0
  {
1787
0
    out_one (DW_CFA_offset_extended);
1788
0
    out_uleb128 (regno);
1789
0
    out_uleb128 (offset);
1790
0
  }
1791
76
      break;
1792
1793
14
    case DW_CFA_val_offset:
1794
14
      regno = insn->u.ri.reg;
1795
14
      offset = insn->u.ri.offset / DWARF2_CIE_DATA_ALIGNMENT;
1796
14
      if (offset < 0)
1797
4
  {
1798
4
    out_one (DW_CFA_val_offset_sf);
1799
4
    out_uleb128 (regno);
1800
4
    out_sleb128 (offset);
1801
4
  }
1802
10
      else
1803
10
  {
1804
10
    out_one (DW_CFA_val_offset);
1805
10
    out_uleb128 (regno);
1806
10
    out_uleb128 (offset);
1807
10
  }
1808
14
      break;
1809
1810
10
    case DW_CFA_register:
1811
10
      out_one (DW_CFA_register);
1812
10
      out_uleb128 (insn->u.rr.reg1);
1813
10
      out_uleb128 (insn->u.rr.reg2);
1814
10
      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
2
    case DW_CFA_GNU_window_save:
1822
2
      out_one (DW_CFA_GNU_window_save);
1823
2
      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
22
    case CFI_escape:
1830
22
      {
1831
22
  struct cfi_escape_data *e;
1832
61
  for (e = insn->u.esc; e ; e = e->next)
1833
39
    {
1834
39
      if (e->type == CFI_ESC_sleb128 || e->type == CFI_ESC_uleb128)
1835
0
        emit_leb128_expr (&e->exp, e->type == CFI_ESC_sleb128);
1836
39
      else
1837
39
        emit_expr_with_reloc (&e->exp, e->type, e->reloc);
1838
39
    }
1839
22
  break;
1840
0
      }
1841
1842
33
    case CFI_val_encoded_addr:
1843
33
      {
1844
33
  unsigned encoding = insn->u.ea.encoding;
1845
33
  offsetT enc_size;
1846
1847
33
  if (encoding == DW_EH_PE_omit)
1848
23
    break;
1849
10
  out_one (DW_CFA_val_expression);
1850
10
  out_uleb128 (insn->u.ea.reg);
1851
1852
10
  switch (encoding & 0x7)
1853
10
    {
1854
0
    case DW_EH_PE_absptr:
1855
0
      enc_size = DWARF2_ADDR_SIZE (stdoutput);
1856
0
      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
10
    case DW_EH_PE_udata8:
1864
10
      enc_size = 8;
1865
10
      break;
1866
0
    default:
1867
0
      abort ();
1868
10
    }
1869
1870
  /* If the user has requested absolute encoding,
1871
     then use the smaller DW_OP_addr encoding.  */
1872
10
  if (insn->u.ea.encoding == DW_EH_PE_absptr)
1873
0
    {
1874
0
      out_uleb128 (1 + enc_size);
1875
0
      out_one (DW_OP_addr);
1876
0
    }
1877
10
  else
1878
10
    {
1879
10
      out_uleb128 (1 + 1 + enc_size);
1880
10
      out_one (DW_OP_GNU_encoded_addr);
1881
10
      out_one (encoding);
1882
1883
10
      if ((encoding & 0x70) == DW_EH_PE_pcrel)
1884
10
        {
1885
10
#if CFI_DIFF_EXPR_OK
1886
10
    insn->u.ea.exp.X_op = O_subtract;
1887
10
    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
10
        }
1895
10
    }
1896
10
  emit_expr (&insn->u.ea.exp, enc_size);
1897
10
      }
1898
0
      break;
1899
1900
16
    case CFI_label:
1901
16
      colon (insn->u.sym_name);
1902
16
      break;
1903
1904
0
    default:
1905
0
      abort ();
1906
890
    }
1907
890
}
1908
1909
static void
1910
output_cie (struct cie_entry *cie, bool eh_frame, int align)
1911
61
{
1912
61
  symbolS *after_size_address, *end_address;
1913
61
  expressionS exp;
1914
61
  struct cfi_insn_data *i;
1915
61
  offsetT augmentation_size;
1916
61
  int enc;
1917
61
  enum dwarf2_format fmt = DWARF2_FORMAT (now_seg);
1918
1919
61
  cie->start_address = symbol_temp_new_now ();
1920
61
  after_size_address = symbol_temp_make ();
1921
61
  end_address = symbol_temp_make ();
1922
1923
61
  exp.X_op = O_subtract;
1924
61
  exp.X_add_symbol = end_address;
1925
61
  exp.X_op_symbol = after_size_address;
1926
61
  exp.X_add_number = 0;
1927
1928
61
  if (eh_frame || fmt == dwarf2_format_32bit)
1929
61
    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
61
  symbol_set_value_now (after_size_address);
1937
61
  if (eh_frame)
1938
51
    out_four (0);        /* CIE id.  */
1939
10
  else
1940
10
    {
1941
10
      out_four (-1);        /* CIE id.  */
1942
10
      if (fmt != dwarf2_format_32bit)
1943
0
  out_four (-1);
1944
10
    }
1945
61
  out_one (flag_dwarf_cie_version);   /* Version.  */
1946
61
  if (eh_frame)
1947
51
    {
1948
51
      out_one ('z');        /* Augmentation.  */
1949
51
      if (cie->per_encoding != DW_EH_PE_omit)
1950
8
  out_one ('P');
1951
51
      if (cie->lsda_encoding != DW_EH_PE_omit)
1952
0
  out_one ('L');
1953
51
      out_one ('R');
1954
#ifdef tc_output_cie_extra
1955
      tc_output_cie_extra (cie);
1956
#endif
1957
51
    }
1958
61
  if (cie->signal_frame)
1959
0
    out_one ('S');
1960
61
  out_one (0);
1961
61
  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
61
  out_uleb128 (DWARF2_LINE_MIN_INSN_LENGTH);  /* Code alignment.  */
1970
61
  out_sleb128 (DWARF2_CIE_DATA_ALIGNMENT);  /* Data alignment.  */
1971
61
  if (flag_dwarf_cie_version == 1)   /* Return column.  */
1972
61
    {
1973
61
      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
61
      out_one (cie->return_column);
1977
61
    }
1978
0
  else
1979
0
    out_uleb128 (cie->return_column);
1980
61
  if (eh_frame)
1981
51
    {
1982
51
      augmentation_size = 1 + (cie->lsda_encoding != DW_EH_PE_omit);
1983
51
      if (cie->per_encoding != DW_EH_PE_omit)
1984
8
  augmentation_size += 1 + encoding_size (cie->per_encoding);
1985
51
      out_uleb128 (augmentation_size);    /* Augmentation size.  */
1986
1987
51
      emit_expr_encoded (&cie->personality, cie->per_encoding, true);
1988
1989
51
      if (cie->lsda_encoding != DW_EH_PE_omit)
1990
0
  out_one (cie->lsda_encoding);
1991
51
    }
1992
1993
61
  switch (DWARF2_FDE_RELOC_SIZE)
1994
61
    {
1995
0
    case 2:
1996
0
      enc = DW_EH_PE_sdata2;
1997
0
      break;
1998
61
    case 4:
1999
61
      enc = DW_EH_PE_sdata4;
2000
61
      break;
2001
0
    case 8:
2002
0
      enc = DW_EH_PE_sdata8;
2003
0
      break;
2004
0
    default:
2005
0
      abort ();
2006
61
    }
2007
61
#if CFI_DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr
2008
61
  enc |= DW_EH_PE_pcrel;
2009
61
#endif
2010
#ifdef DWARF2_FDE_RELOC_ENCODING
2011
  /* Allow target to override encoding.  */
2012
  enc = DWARF2_FDE_RELOC_ENCODING (enc);
2013
#endif
2014
61
  cie->fde_encoding = enc;
2015
61
  if (eh_frame)
2016
51
    out_one (enc);
2017
2018
61
  if (cie->first)
2019
61
    {
2020
291
      for (i = cie->first; i != cie->last; i = i->next)
2021
230
  {
2022
230
    if (CUR_SEG (i) != CUR_SEG (cie))
2023
0
      continue;
2024
230
    output_cfi_insn (i);
2025
230
  }
2026
61
    }
2027
2028
61
  frag_align (align, DW_CFA_nop, 0);
2029
61
  symbol_set_value_now (end_address);
2030
61
}
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
337
{
2037
337
  symbolS *after_size_address, *end_address;
2038
337
  expressionS exp;
2039
337
  offsetT augmentation_size;
2040
337
  enum dwarf2_format fmt = DWARF2_FORMAT (now_seg);
2041
337
  unsigned int offset_size;
2042
337
  unsigned int addr_size;
2043
2044
337
  after_size_address = symbol_temp_make ();
2045
337
  end_address = symbol_temp_make ();
2046
2047
337
  exp.X_op = O_subtract;
2048
337
  exp.X_add_symbol = end_address;
2049
337
  exp.X_op_symbol = after_size_address;
2050
337
  exp.X_add_number = 0;
2051
337
  if (eh_frame || fmt == dwarf2_format_32bit)
2052
337
    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
337
  emit_expr (&exp, offset_size);    /* Length.  */
2060
337
  symbol_set_value_now (after_size_address);
2061
2062
337
  if (eh_frame)
2063
326
    {
2064
326
      exp.X_op = O_subtract;
2065
326
      exp.X_add_symbol = after_size_address;
2066
326
      exp.X_op_symbol = cie->start_address;
2067
326
      exp.X_add_number = 0;
2068
326
      emit_expr (&exp, offset_size);    /* CIE offset.  */
2069
326
    }
2070
11
  else
2071
11
    {
2072
11
      TC_DWARF2_EMIT_OFFSET (cie->start_address, offset_size);
2073
11
    }
2074
2075
337
  exp.X_op = O_symbol;
2076
337
  if (eh_frame)
2077
326
    {
2078
326
      bfd_reloc_code_real_type code
2079
326
  = tc_cfi_reloc_for_encoding (cie->fde_encoding);
2080
326
      addr_size = DWARF2_FDE_RELOC_SIZE;
2081
326
      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
326
      else
2091
326
  {
2092
326
    exp.X_op = O_subtract;
2093
326
    exp.X_add_number = 0;
2094
326
#if CFI_DIFF_EXPR_OK
2095
326
    exp.X_add_symbol = fde->start_address;
2096
326
    exp.X_op_symbol = symbol_temp_new_now ();
2097
326
    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
326
  }
2109
326
    }
2110
11
  else
2111
11
    {
2112
11
      exp.X_add_number = 0;
2113
11
      exp.X_add_symbol = fde->start_address;
2114
11
      addr_size = DWARF2_ADDR_SIZE (stdoutput);
2115
11
      emit_expr (&exp, addr_size);
2116
11
    }
2117
2118
337
  exp.X_op = O_subtract;
2119
337
  exp.X_add_symbol = fde->end_address;
2120
337
  exp.X_op_symbol = fde->start_address;   /* Code length.  */
2121
337
  exp.X_add_number = 0;
2122
337
  emit_expr (&exp, addr_size);
2123
2124
337
  augmentation_size = encoding_size (fde->lsda_encoding);
2125
337
  if (eh_frame)
2126
326
    out_uleb128 (augmentation_size);   /* Augmentation size.  */
2127
2128
337
  emit_expr_encoded (&fde->lsda, cie->lsda_encoding, false);
2129
2130
997
  for (; first; first = first->next)
2131
660
    if (CUR_SEG (first) == CUR_SEG (fde))
2132
660
      {
2133
660
#ifndef NO_LISTING
2134
660
  if (eh_frame)
2135
628
    listing_override_tail (first->listing_ctxt);
2136
660
#endif
2137
660
  output_cfi_insn (first);
2138
660
      }
2139
2140
337
#ifndef NO_LISTING
2141
  /* Associate any padding with .cfi_endproc.  */
2142
337
  if (eh_frame)
2143
326
    listing_override_tail (fde->listing_end);
2144
337
#endif
2145
2146
337
  frag_align (align, DW_CFA_nop, 0);
2147
337
  symbol_set_value_now (end_address);
2148
337
}
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
1.08k
{
2156
1.08k
  if (j && i->insn != j->insn)
2157
3
    return false;
2158
1.08k
  switch (i->insn)
2159
1.08k
    {
2160
352
    case DW_CFA_offset:
2161
692
    case DW_CFA_def_cfa:
2162
704
    case DW_CFA_val_offset:
2163
704
      if (j)
2164
562
  {
2165
562
    if (i->u.ri.reg != j->u.ri.reg)
2166
2
      return false;
2167
560
    if (i->u.ri.offset != j->u.ri.offset)
2168
0
      return false;
2169
560
  }
2170
702
      break;
2171
2172
702
    case DW_CFA_register:
2173
12
      if (j)
2174
3
  {
2175
3
    if (i->u.rr.reg1 != j->u.rr.reg1)
2176
0
      return false;
2177
3
    if (i->u.rr.reg2 != j->u.rr.reg2)
2178
1
      return false;
2179
3
  }
2180
11
      break;
2181
2182
11
    case DW_CFA_def_cfa_register:
2183
4
    case DW_CFA_restore:
2184
75
    case DW_CFA_undefined:
2185
75
    case DW_CFA_same_value:
2186
75
      if (j)
2187
2
  {
2188
2
    if (i->u.r != j->u.r)
2189
0
      return false;
2190
2
  }
2191
75
      break;
2192
2193
273
    case DW_CFA_def_cfa_offset:
2194
273
      if (j)
2195
267
  {
2196
267
    if (i->u.i != j->u.i)
2197
0
      return false;
2198
267
  }
2199
273
      break;
2200
2201
273
    default:
2202
20
      return false;
2203
1.08k
    }
2204
1.06k
  return true;
2205
1.08k
}
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
337
{
2211
337
  struct cfi_insn_data *i, *j;
2212
337
  struct cie_entry *cie;
2213
2214
348
  for (cie = cie_root; cie; cie = cie->next)
2215
287
    {
2216
287
      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
287
      if (cie->return_column != fde->return_column
2223
287
    || cie->signal_frame != fde->signal_frame
2224
287
    || cie->per_encoding != fde->per_encoding
2225
285
    || cie->lsda_encoding != fde->lsda_encoding)
2226
2
  continue;
2227
285
      if (cie->per_encoding != DW_EH_PE_omit)
2228
1
  {
2229
1
    if (cie->personality.X_op != fde->personality.X_op
2230
1
        || (cie->personality.X_add_number
2231
1
      != fde->personality.X_add_number))
2232
0
      continue;
2233
1
    switch (cie->personality.X_op)
2234
1
      {
2235
1
      case O_constant:
2236
1
        if (cie->personality.X_unsigned != fde->personality.X_unsigned)
2237
0
    continue;
2238
1
        break;
2239
1
      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
1
      }
2247
1
  }
2248
285
      for (i = cie->first, j = fde->data;
2249
1.11k
     i != cie->last && j != NULL;
2250
831
     i = i->next, j = j->next)
2251
837
  {
2252
837
    if (!initial_cie_insn (i, j))
2253
6
      break;
2254
837
  }
2255
2256
285
      if (i == cie->last)
2257
276
  {
2258
276
    *pfirst = j;
2259
276
    return cie;
2260
276
  }
2261
285
    }
2262
2263
61
  cie = XNEW (struct cie_entry);
2264
61
  cie->next = cie_root;
2265
61
  cie_root = cie;
2266
61
  SET_CUR_SEG (cie, CUR_SEG (fde));
2267
61
  cie->return_column = fde->return_column;
2268
61
  cie->signal_frame = fde->signal_frame;
2269
61
  cie->per_encoding = fde->per_encoding;
2270
61
  cie->lsda_encoding = fde->lsda_encoding;
2271
61
  cie->personality = fde->personality;
2272
61
  cie->first = fde->data;
2273
#ifdef tc_cie_entry_init_extra
2274
  tc_cie_entry_init_extra (cie, fde);
2275
#endif
2276
2277
291
  for (i = cie->first; i ; i = i->next)
2278
250
    if (!initial_cie_insn (i, NULL))
2279
20
      break;
2280
2281
61
  cie->last = i;
2282
61
  *pfirst = i;
2283
2284
61
  output_cie (cie, eh_frame, align);
2285
2286
61
  return cie;
2287
337
}
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
11
#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
281
{
2387
281
  struct cie_entry *cie, *cie_next;
2388
281
  segT cfi_seg, ccseg;
2389
281
  struct fde_entry *fde;
2390
281
  struct cfi_insn_data *first;
2391
281
#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
281
  struct list_info_struct *saved_listing_tail = NULL;
2396
281
#endif
2397
281
  int save_flag_traditional_format, seek_next_seg;
2398
2399
281
  if (all_fde_data == 0)
2400
212
    return;
2401
2402
69
  if ((all_cfi_sections & CFI_EMIT_eh_frame) != 0
2403
25
      || (all_cfi_sections & CFI_EMIT_eh_frame_compact) != 0)
2404
44
    {
2405
      /* Make sure check_eh_frame doesn't do anything with our output.  */
2406
44
      save_flag_traditional_format = flag_traditional_format;
2407
44
      flag_traditional_format = 1;
2408
2409
44
      if (!EH_FRAME_LINKONCE)
2410
44
  {
2411
    /* Open .eh_frame section.  */
2412
44
    cfi_seg = get_cfi_seg (NULL, ".eh_frame",
2413
44
         (SEC_ALLOC | SEC_LOAD | SEC_DATA
2414
44
          | DWARF2_EH_FRAME_READ_ONLY),
2415
44
         EH_FRAME_ALIGNMENT);
2416
#ifdef md_fix_up_eh_frame
2417
    md_fix_up_eh_frame (cfi_seg);
2418
#else
2419
44
    (void) cfi_seg;
2420
44
#endif
2421
44
  }
2422
2423
44
      do
2424
44
  {
2425
44
    ccseg = NULL;
2426
44
    seek_next_seg = 0;
2427
2428
370
    for (fde = all_fde_data; fde ; fde = fde->next)
2429
326
      {
2430
326
        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
326
        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
326
        if (fde->end_address == NULL)
2473
325
    {
2474
325
      as_bad (_("open CFI at the end of file; "
2475
325
          "missing .cfi_endproc directive"));
2476
325
      fde->end_address = fde->start_address;
2477
325
    }
2478
2479
326
#ifndef NO_LISTING
2480
326
        {
2481
326
    struct list_info_struct *listing_prev
2482
326
      = listing_override_tail (fde->listing_ctxt);
2483
2484
326
    if (!saved_listing_tail)
2485
326
      saved_listing_tail = listing_prev;
2486
326
        }
2487
326
#endif
2488
2489
326
        cie = select_cie_for_fde (fde, true, &first, 2);
2490
326
        fde->eh_loc = symbol_temp_new_now ();
2491
326
        output_fde (fde, cie, true, first,
2492
326
        fde->next == NULL ? EH_FRAME_ALIGNMENT : 2);
2493
326
      }
2494
2495
95
    for (cie = cie_root; cie; cie = cie_next)
2496
51
      {
2497
51
        cie_next = cie->next;
2498
51
        free (cie);
2499
51
      }
2500
44
    cie_root = NULL;
2501
44
  }
2502
44
      while (EH_FRAME_LINKONCE && seek_next_seg == 2);
2503
2504
44
      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
44
      flag_traditional_format = save_flag_traditional_format;
2596
44
    }
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
69
  if (flag_gen_sframe == GEN_SFRAME_ENABLED
2604
69
      || flag_gen_sframe == GEN_SFRAME_CONFIG_ENABLED
2605
69
      || ((all_cfi_sections & CFI_EMIT_sframe) != 0
2606
23
    && flag_gen_sframe != GEN_SFRAME_DISABLED))
2607
23
    {
2608
23
#ifdef support_sframe_p
2609
23
      if (support_sframe_p () && !SUPPORT_FRAME_LINKONCE)
2610
23
  {
2611
23
    segT sframe_seg;
2612
23
    int alignment = ffs (DWARF2_ADDR_SIZE (stdoutput)) - 1;
2613
2614
23
    sframe_seg = get_cfi_seg (NULL, ".sframe",
2615
23
            (SEC_ALLOC | SEC_LOAD | SEC_DATA
2616
23
             | DWARF2_EH_FRAME_READ_ONLY),
2617
23
            alignment);
2618
23
    elf_section_type (sframe_seg) = SHT_GNU_SFRAME;
2619
23
    output_sframe (sframe_seg);
2620
23
  }
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
23
    }
2627
2628
69
  if ((all_cfi_sections & CFI_EMIT_debug_frame) != 0)
2629
7
    {
2630
7
      int alignment = ffs (DWARF2_ADDR_SIZE (stdoutput)) - 1;
2631
2632
7
      if (!SUPPORT_FRAME_LINKONCE)
2633
7
  get_cfi_seg (NULL, ".debug_frame",
2634
7
         SEC_READONLY | SEC_DEBUGGING,
2635
7
         alignment);
2636
2637
7
      do
2638
7
  {
2639
7
    ccseg = NULL;
2640
7
    seek_next_seg = 0;
2641
2642
22
    for (fde = all_fde_data; fde ; fde = fde->next)
2643
15
      {
2644
15
        if ((fde->sections & CFI_EMIT_debug_frame) == 0)
2645
4
    continue;
2646
2647
11
        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
11
        if (fde->end_address == NULL)
2668
5
    {
2669
5
      as_bad (_("open CFI at the end of file; "
2670
5
          "missing .cfi_endproc directive"));
2671
5
      fde->end_address = fde->start_address;
2672
5
    }
2673
2674
11
        fde->per_encoding = DW_EH_PE_omit;
2675
11
        fde->lsda_encoding = DW_EH_PE_omit;
2676
11
        cfi_change_reg_numbers (fde->data, ccseg);
2677
11
        cie = select_cie_for_fde (fde, false, &first, alignment);
2678
11
        output_fde (fde, cie, false, first, alignment);
2679
11
      }
2680
2681
17
    for (cie = cie_root; cie; cie = cie_next)
2682
10
      {
2683
10
        cie_next = cie->next;
2684
10
        free (cie);
2685
10
      }
2686
7
    cie_root = NULL;
2687
7
  }
2688
7
      while (SUPPORT_FRAME_LINKONCE && seek_next_seg == 2);
2689
2690
7
      if (SUPPORT_FRAME_LINKONCE)
2691
0
  for (fde = all_fde_data; fde ; fde = fde->next)
2692
0
    SET_HANDLED (fde, 0);
2693
7
    }
2694
69
  all_fde_data = NULL;
2695
69
  last_fde_data = &all_fde_data;
2696
69
  cfi_sections_set = false;
2697
69
  cfi_sections = CFI_EMIT_eh_frame;
2698
69
  all_cfi_sections = 0;
2699
69
  last_fde = NULL;
2700
69
  if (dwcfi_hash)
2701
0
    {
2702
0
      htab_delete (dwcfi_hash);
2703
0
      dwcfi_hash = NULL;
2704
0
    }
2705
2706
69
#ifndef NO_LISTING
2707
69
  if (saved_listing_tail)
2708
0
    listing_tail = saved_listing_tail;
2709
69
#endif
2710
69
}
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 */