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