Coverage Report

Created: 2024-05-21 06:29

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