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