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