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