Coverage Report

Created: 2023-08-28 06:31

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