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