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