gas/riscv: Produce version 3 DWARF CIE by default
[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 }
66f8b2cb 1863 out_one (flag_dwarf_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);
66f8b2cb
AB
1879 if (flag_dwarf_cie_version >= 4)
1880 {
1881 /* For now we are assuming a flat address space with 4 or 8 byte
1882 addresses. */
1883 int address_size = dwarf2_format_32bit ? 4 : 8;
1884 out_one (address_size); /* Address size. */
1885 out_one (0); /* Segment size. */
1886 }
289040ca
NC
1887 out_uleb128 (DWARF2_LINE_MIN_INSN_LENGTH); /* Code alignment. */
1888 out_sleb128 (DWARF2_CIE_DATA_ALIGNMENT); /* Data alignment. */
66f8b2cb 1889 if (flag_dwarf_cie_version == 1) /* Return column. */
22eb4a06
AB
1890 {
1891 if ((cie->return_column & 0xff) != cie->return_column)
1892 as_bad (_("return column number %d overflows in CIE version 1"),
1893 cie->return_column);
1894 out_one (cie->return_column);
1895 }
0da76f83
NC
1896 else
1897 out_uleb128 (cie->return_column);
38462edf
JJ
1898 if (eh_frame)
1899 {
1900 augmentation_size = 1 + (cie->lsda_encoding != DW_EH_PE_omit);
1901 if (cie->per_encoding != DW_EH_PE_omit)
1902 augmentation_size += 1 + encoding_size (cie->per_encoding);
1903 out_uleb128 (augmentation_size); /* Augmentation size. */
4e4e1355 1904
2f0c68f2 1905 emit_expr_encoded (&cie->personality, cie->per_encoding, TRUE);
4e4e1355
TS
1906
1907 if (cie->lsda_encoding != DW_EH_PE_omit)
1908 out_one (cie->lsda_encoding);
9b8ae42e 1909 }
8c9b70b1
RH
1910
1911 switch (DWARF2_FDE_RELOC_SIZE)
1912 {
1913 case 2:
1914 enc = DW_EH_PE_sdata2;
1915 break;
1916 case 4:
1917 enc = DW_EH_PE_sdata4;
1918 break;
1919 case 8:
1920 enc = DW_EH_PE_sdata8;
1921 break;
1922 default:
1923 abort ();
1924 }
3dd24306 1925#if CFI_DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr
8c9b70b1 1926 enc |= DW_EH_PE_pcrel;
364b6d8b 1927#endif
2f0c68f2
CM
1928#ifdef DWARF2_FDE_RELOC_ENCODING
1929 /* Allow target to override encoding. */
1930 enc = DWARF2_FDE_RELOC_ENCODING (enc);
1931#endif
1932 cie->fde_encoding = enc;
38462edf
JJ
1933 if (eh_frame)
1934 out_one (enc);
a4447b93
RH
1935
1936 if (cie->first)
72b016b4
NC
1937 {
1938 for (i = cie->first; i != cie->last; i = i->next)
83e12deb 1939 {
6303c4ae 1940 if (CUR_SEG (i) != CUR_SEG (cie))
72b016b4
NC
1941 continue;
1942 output_cfi_insn (i);
1943 }
1944 }
a4447b93 1945
38462edf 1946 frag_align (align, DW_CFA_nop, 0);
a4447b93
RH
1947 symbol_set_value_now (end_address);
1948}
54cfded0 1949
a4447b93
RH
1950static void
1951output_fde (struct fde_entry *fde, struct cie_entry *cie,
38462edf
JJ
1952 bfd_boolean eh_frame, struct cfi_insn_data *first,
1953 int align)
a4447b93
RH
1954{
1955 symbolS *after_size_address, *end_address;
1956 expressionS exp;
9b8ae42e 1957 offsetT augmentation_size;
38462edf 1958 enum dwarf2_format fmt = DWARF2_FORMAT (now_seg);
ea0de82e
AM
1959 unsigned int offset_size;
1960 unsigned int addr_size;
54cfded0 1961
a4447b93
RH
1962 after_size_address = symbol_temp_make ();
1963 end_address = symbol_temp_make ();
54cfded0 1964
a4447b93
RH
1965 exp.X_op = O_subtract;
1966 exp.X_add_symbol = end_address;
1967 exp.X_op_symbol = after_size_address;
1968 exp.X_add_number = 0;
38462edf
JJ
1969 if (eh_frame || fmt == dwarf2_format_32bit)
1970 offset_size = 4;
1971 else
1972 {
1973 if (fmt == dwarf2_format_64bit)
1974 out_four (-1);
1975 offset_size = 8;
1976 }
1977 emit_expr (&exp, offset_size); /* Length. */
a4447b93 1978 symbol_set_value_now (after_size_address);
54cfded0 1979
38462edf
JJ
1980 if (eh_frame)
1981 {
3251495b 1982 exp.X_op = O_subtract;
38462edf
JJ
1983 exp.X_add_symbol = after_size_address;
1984 exp.X_op_symbol = cie->start_address;
3251495b
RH
1985 exp.X_add_number = 0;
1986 emit_expr (&exp, offset_size); /* CIE offset. */
38462edf
JJ
1987 }
1988 else
1989 {
3251495b 1990 TC_DWARF2_EMIT_OFFSET (cie->start_address, offset_size);
38462edf 1991 }
364b6d8b 1992
2f0c68f2 1993 exp.X_op = O_symbol;
38462edf
JJ
1994 if (eh_frame)
1995 {
2f0c68f2
CM
1996 bfd_reloc_code_real_type code
1997 = tc_cfi_reloc_for_encoding (cie->fde_encoding);
ea0de82e 1998 addr_size = DWARF2_FDE_RELOC_SIZE;
2f0c68f2
CM
1999 if (code != BFD_RELOC_NONE)
2000 {
2001 reloc_howto_type *howto = bfd_reloc_type_lookup (stdoutput, code);
ea0de82e 2002 char *p = frag_more (addr_size);
86b9fea1 2003 gas_assert (addr_size == (unsigned) howto->bitsize / 8);
ea0de82e
AM
2004 md_number_to_chars (p, 0, addr_size);
2005 fix_new (frag_now, p - frag_now->fr_literal, addr_size,
2006 fde->start_address, 0, howto->pc_relative, code);
2f0c68f2
CM
2007 }
2008 else
2009 {
2010 exp.X_op = O_subtract;
2011 exp.X_add_number = 0;
3dd24306 2012#if CFI_DIFF_EXPR_OK
2f0c68f2
CM
2013 exp.X_add_symbol = fde->start_address;
2014 exp.X_op_symbol = symbol_temp_new_now ();
ea0de82e 2015 emit_expr (&exp, addr_size); /* Code offset. */
364b6d8b 2016#else
2f0c68f2
CM
2017 exp.X_op = O_symbol;
2018 exp.X_add_symbol = fde->start_address;
2019
2020#if defined(tc_cfi_emit_pcrel_expr)
ea0de82e 2021 tc_cfi_emit_pcrel_expr (&exp, addr_size); /* Code offset. */
364b6d8b 2022#else
ea0de82e 2023 emit_expr (&exp, addr_size); /* Code offset. */
364b6d8b 2024#endif
364b6d8b 2025#endif
2f0c68f2 2026 }
38462edf
JJ
2027 }
2028 else
2029 {
3251495b 2030 exp.X_add_number = 0;
2f0c68f2 2031 exp.X_add_symbol = fde->start_address;
38462edf
JJ
2032 addr_size = DWARF2_ADDR_SIZE (stdoutput);
2033 emit_expr (&exp, addr_size);
2034 }
54cfded0 2035
38462edf 2036 exp.X_op = O_subtract;
a4447b93 2037 exp.X_add_symbol = fde->end_address;
289040ca 2038 exp.X_op_symbol = fde->start_address; /* Code length. */
3251495b 2039 exp.X_add_number = 0;
38462edf 2040 emit_expr (&exp, addr_size);
54cfded0 2041
9b8ae42e 2042 augmentation_size = encoding_size (fde->lsda_encoding);
38462edf
JJ
2043 if (eh_frame)
2044 out_uleb128 (augmentation_size); /* Augmentation size. */
9b8ae42e 2045
2f0c68f2 2046 emit_expr_encoded (&fde->lsda, cie->lsda_encoding, FALSE);
39b82151 2047
a4447b93 2048 for (; first; first = first->next)
6303c4ae 2049 if (CUR_SEG (first) == CUR_SEG (fde))
67ed7401 2050 output_cfi_insn (first);
39b82151 2051
4df6ce47 2052 frag_align (align, DW_CFA_nop, 0);
a4447b93
RH
2053 symbol_set_value_now (end_address);
2054}
2055
2056static struct cie_entry *
38462edf
JJ
2057select_cie_for_fde (struct fde_entry *fde, bfd_boolean eh_frame,
2058 struct cfi_insn_data **pfirst, int align)
a4447b93
RH
2059{
2060 struct cfi_insn_data *i, *j;
2061 struct cie_entry *cie;
2062
2063 for (cie = cie_root; cie; cie = cie->next)
39b82151 2064 {
6303c4ae 2065 if (CUR_SEG (cie) != CUR_SEG (fde))
67ed7401 2066 continue;
09038062
ST
2067#ifdef tc_cie_fde_equivalent_extra
2068 if (!tc_cie_fde_equivalent_extra (cie, fde))
2069 continue;
2070#endif
67ed7401 2071 if (cie->return_column != fde->return_column
9b8ae42e
JJ
2072 || cie->signal_frame != fde->signal_frame
2073 || cie->per_encoding != fde->per_encoding
2074 || cie->lsda_encoding != fde->lsda_encoding)
a4447b93 2075 continue;
9b8ae42e
JJ
2076 if (cie->per_encoding != DW_EH_PE_omit)
2077 {
2078 if (cie->personality.X_op != fde->personality.X_op
9e1a8675
AM
2079 || (cie->personality.X_add_number
2080 != fde->personality.X_add_number))
9b8ae42e
JJ
2081 continue;
2082 switch (cie->personality.X_op)
2083 {
2084 case O_constant:
2085 if (cie->personality.X_unsigned != fde->personality.X_unsigned)
2086 continue;
2087 break;
2088 case O_symbol:
2089 if (cie->personality.X_add_symbol
2090 != fde->personality.X_add_symbol)
2091 continue;
2092 break;
2093 default:
2094 abort ();
2095 }
2096 }
a4447b93
RH
2097 for (i = cie->first, j = fde->data;
2098 i != cie->last && j != NULL;
2099 i = i->next, j = j->next)
39b82151 2100 {
a4447b93
RH
2101 if (i->insn != j->insn)
2102 goto fail;
2103 switch (i->insn)
2104 {
2105 case DW_CFA_advance_loc:
289040ca
NC
2106 case DW_CFA_remember_state:
2107 /* We reached the first advance/remember in the FDE,
2108 but did not reach the end of the CIE list. */
a4447b93
RH
2109 goto fail;
2110
2111 case DW_CFA_offset:
2112 case DW_CFA_def_cfa:
2113 if (i->u.ri.reg != j->u.ri.reg)
2114 goto fail;
2115 if (i->u.ri.offset != j->u.ri.offset)
2116 goto fail;
2117 break;
2118
2119 case DW_CFA_register:
2120 if (i->u.rr.reg1 != j->u.rr.reg1)
2121 goto fail;
2122 if (i->u.rr.reg2 != j->u.rr.reg2)
2123 goto fail;
2124 break;
2125
2126 case DW_CFA_def_cfa_register:
2be24b54
ML
2127 case DW_CFA_restore:
2128 case DW_CFA_undefined:
2129 case DW_CFA_same_value:
a4447b93
RH
2130 if (i->u.r != j->u.r)
2131 goto fail;
2132 break;
2133
2134 case DW_CFA_def_cfa_offset:
2135 if (i->u.i != j->u.i)
2136 goto fail;
2137 break;
2138
cdfbf930 2139 case CFI_escape:
f1c4cc75 2140 case CFI_val_encoded_addr:
73e76108 2141 case CFI_label:
cdfbf930
RH
2142 /* Don't bother matching these for now. */
2143 goto fail;
2144
a4447b93
RH
2145 default:
2146 abort ();
2147 }
39b82151 2148 }
a4447b93
RH
2149
2150 /* Success if we reached the end of the CIE list, and we've either
289040ca
NC
2151 run out of FDE entries or we've encountered an advance,
2152 remember, or escape. */
e9fad691
AM
2153 if (i == cie->last
2154 && (!j
2155 || j->insn == DW_CFA_advance_loc
289040ca 2156 || j->insn == DW_CFA_remember_state
f1c4cc75 2157 || j->insn == CFI_escape
73e76108
JB
2158 || j->insn == CFI_val_encoded_addr
2159 || j->insn == CFI_label))
39b82151 2160 {
a4447b93
RH
2161 *pfirst = j;
2162 return cie;
39b82151
ML
2163 }
2164
a4447b93 2165 fail:;
54cfded0
AM
2166 }
2167
add39d23 2168 cie = XNEW (struct cie_entry);
a4447b93
RH
2169 cie->next = cie_root;
2170 cie_root = cie;
6303c4ae 2171 SET_CUR_SEG (cie, CUR_SEG (fde));
a4447b93 2172 cie->return_column = fde->return_column;
63752a75 2173 cie->signal_frame = fde->signal_frame;
9b8ae42e
JJ
2174 cie->per_encoding = fde->per_encoding;
2175 cie->lsda_encoding = fde->lsda_encoding;
2176 cie->personality = fde->personality;
a4447b93 2177 cie->first = fde->data;
09038062
ST
2178#ifdef tc_cie_entry_init_extra
2179 tc_cie_entry_init_extra (cie, fde)
2180#endif
54cfded0 2181
a4447b93 2182 for (i = cie->first; i ; i = i->next)
e9fad691 2183 if (i->insn == DW_CFA_advance_loc
289040ca 2184 || i->insn == DW_CFA_remember_state
f1c4cc75 2185 || i->insn == CFI_escape
69602580
JB
2186 || i->insn == CFI_val_encoded_addr
2187 || i->insn == CFI_label)
a4447b93 2188 break;
54cfded0 2189
a4447b93
RH
2190 cie->last = i;
2191 *pfirst = i;
38462edf
JJ
2192
2193 output_cie (cie, eh_frame, align);
54cfded0 2194
a4447b93 2195 return cie;
54cfded0
AM
2196}
2197
38462edf
JJ
2198#ifdef md_reg_eh_frame_to_debug_frame
2199static void
6303c4ae 2200cfi_change_reg_numbers (struct cfi_insn_data *insn, segT ccseg)
38462edf
JJ
2201{
2202 for (; insn; insn = insn->next)
72b016b4 2203 {
6303c4ae 2204 if (CUR_SEG (insn) != ccseg)
83e12deb 2205 continue;
72b016b4
NC
2206 switch (insn->insn)
2207 {
2208 case DW_CFA_advance_loc:
2209 case DW_CFA_def_cfa_offset:
2210 case DW_CFA_remember_state:
2211 case DW_CFA_restore_state:
2212 case DW_CFA_GNU_window_save:
2213 case CFI_escape:
73e76108 2214 case CFI_label:
72b016b4 2215 break;
38462edf 2216
72b016b4
NC
2217 case DW_CFA_def_cfa:
2218 case DW_CFA_offset:
2219 insn->u.ri.reg = md_reg_eh_frame_to_debug_frame (insn->u.ri.reg);
2220 break;
38462edf 2221
72b016b4
NC
2222 case DW_CFA_def_cfa_register:
2223 case DW_CFA_undefined:
2224 case DW_CFA_same_value:
2225 case DW_CFA_restore:
2226 insn->u.r = md_reg_eh_frame_to_debug_frame (insn->u.r);
2227 break;
38462edf 2228
72b016b4
NC
2229 case DW_CFA_register:
2230 insn->u.rr.reg1 = md_reg_eh_frame_to_debug_frame (insn->u.rr.reg1);
2231 insn->u.rr.reg2 = md_reg_eh_frame_to_debug_frame (insn->u.rr.reg2);
2232 break;
38462edf 2233
72b016b4
NC
2234 case CFI_val_encoded_addr:
2235 insn->u.ea.reg = md_reg_eh_frame_to_debug_frame (insn->u.ea.reg);
2236 break;
38462edf 2237
72b016b4
NC
2238 default:
2239 abort ();
2240 }
2241 }
38462edf
JJ
2242}
2243#else
72b016b4 2244#define cfi_change_reg_numbers(insn, cseg) do { } while (0)
38462edf
JJ
2245#endif
2246
2f0c68f2
CM
2247#if SUPPORT_COMPACT_EH
2248static void
2249cfi_emit_eh_header (symbolS *sym, bfd_vma addend)
72b016b4 2250{
2f0c68f2 2251 expressionS exp;
72b016b4 2252
2f0c68f2
CM
2253 exp.X_add_number = addend;
2254 exp.X_add_symbol = sym;
2255 emit_expr_encoded (&exp, DW_EH_PE_sdata4 | DW_EH_PE_pcrel, FALSE);
2256}
72b016b4 2257
2f0c68f2
CM
2258static void
2259output_eh_header (struct fde_entry *fde)
2260{
2261 char *p;
2262 bfd_vma addend;
2263
2264 if (fde->eh_header_type == EH_COMPACT_INLINE)
2265 addend = 0;
2266 else
2267 addend = 1;
2268
2269 cfi_emit_eh_header (fde->start_address, addend);
2270
2271 if (fde->eh_header_type == EH_COMPACT_INLINE)
2272 {
2273 p = frag_more (4);
2274 /* Inline entries always use PR1. */
2275 *(p++) = 1;
2276 memcpy(p, fde->eh_data, 3);
6303c4ae
AM
2277 }
2278 else
2279 {
2f0c68f2
CM
2280 if (fde->eh_header_type == EH_COMPACT_LEGACY)
2281 addend = 1;
2282 else if (fde->eh_header_type == EH_COMPACT_OUTLINE
2283 || fde->eh_header_type == EH_COMPACT_OUTLINE_DONE)
2284 addend = 0;
2285 else
2286 abort ();
2287 cfi_emit_eh_header (fde->eh_loc, addend);
6303c4ae 2288 }
72b016b4 2289}
2f0c68f2 2290#endif
72b016b4 2291
54cfded0 2292void
a4447b93 2293cfi_finish (void)
54cfded0 2294{
72b016b4
NC
2295 struct cie_entry *cie, *cie_next;
2296 segT cfi_seg, ccseg;
a4447b93 2297 struct fde_entry *fde;
72b016b4
NC
2298 struct cfi_insn_data *first;
2299 int save_flag_traditional_format, seek_next_seg;
54cfded0 2300
a4447b93
RH
2301 if (all_fde_data == 0)
2302 return;
54cfded0 2303
bd5608dc 2304 cfi_sections_set = TRUE;
2f0c68f2
CM
2305 if ((all_cfi_sections & CFI_EMIT_eh_frame) != 0
2306 || (all_cfi_sections & CFI_EMIT_eh_frame_compact) != 0)
38462edf 2307 {
38462edf
JJ
2308 /* Make sure check_eh_frame doesn't do anything with our output. */
2309 save_flag_traditional_format = flag_traditional_format;
2310 flag_traditional_format = 1;
eafbc43f 2311
2f0c68f2 2312 if (!EH_FRAME_LINKONCE)
6303c4ae
AM
2313 {
2314 /* Open .eh_frame section. */
2315 cfi_seg = get_cfi_seg (NULL, ".eh_frame",
2316 (SEC_ALLOC | SEC_LOAD | SEC_DATA
2317 | DWARF2_EH_FRAME_READ_ONLY),
2318 EH_FRAME_ALIGNMENT);
67ed7401 2319#ifdef md_fix_up_eh_frame
6303c4ae 2320 md_fix_up_eh_frame (cfi_seg);
67ed7401 2321#else
6303c4ae 2322 (void) cfi_seg;
67ed7401 2323#endif
6303c4ae 2324 }
67ed7401 2325
72b016b4 2326 do
83e12deb 2327 {
72b016b4 2328 ccseg = NULL;
72b016b4 2329 seek_next_seg = 0;
67ed7401 2330
72b016b4 2331 for (cie = cie_root; cie; cie = cie_next)
38462edf 2332 {
72b016b4
NC
2333 cie_next = cie->next;
2334 free ((void *) cie);
38462edf 2335 }
72b016b4 2336 cie_root = NULL;
38462edf 2337
72b016b4
NC
2338 for (fde = all_fde_data; fde ; fde = fde->next)
2339 {
2f0c68f2
CM
2340 if ((fde->sections & CFI_EMIT_eh_frame) == 0
2341 && (fde->sections & CFI_EMIT_eh_frame_compact) == 0)
2342 continue;
2343
2344#if SUPPORT_COMPACT_EH
2345 /* Emit a LEGACY format header if we have processed all
9e1a8675 2346 of the .cfi directives without encountering either inline or
2f0c68f2
CM
2347 out-of-line compact unwinding opcodes. */
2348 if (fde->eh_header_type == EH_COMPACT_HAS_LSDA
2349 || fde->eh_header_type == EH_COMPACT_UNKNOWN)
2350 fde->eh_header_type = EH_COMPACT_LEGACY;
2351
2352 if (fde->eh_header_type != EH_COMPACT_LEGACY)
2353 continue;
2354#endif
2355 if (EH_FRAME_LINKONCE)
6303c4ae
AM
2356 {
2357 if (HANDLED (fde))
2358 continue;
2359 if (seek_next_seg && CUR_SEG (fde) != ccseg)
2360 {
2361 seek_next_seg = 2;
2362 continue;
2363 }
2364 if (!seek_next_seg)
2365 {
2366 ccseg = CUR_SEG (fde);
2367 /* Open .eh_frame section. */
2368 cfi_seg = get_cfi_seg (ccseg, ".eh_frame",
2369 (SEC_ALLOC | SEC_LOAD | SEC_DATA
2370 | DWARF2_EH_FRAME_READ_ONLY),
2371 EH_FRAME_ALIGNMENT);
72b016b4 2372#ifdef md_fix_up_eh_frame
6303c4ae 2373 md_fix_up_eh_frame (cfi_seg);
67ed7401 2374#else
6303c4ae 2375 (void) cfi_seg;
72b016b4 2376#endif
6303c4ae
AM
2377 seek_next_seg = 1;
2378 }
2379 SET_HANDLED (fde, 1);
72b016b4 2380 }
72b016b4
NC
2381
2382 if (fde->end_address == NULL)
2383 {
9e1a8675
AM
2384 as_bad (_("open CFI at the end of file; "
2385 "missing .cfi_endproc directive"));
72b016b4
NC
2386 fde->end_address = fde->start_address;
2387 }
2388
2389 cie = select_cie_for_fde (fde, TRUE, &first, 2);
2f0c68f2 2390 fde->eh_loc = symbol_temp_new_now ();
72b016b4
NC
2391 output_fde (fde, cie, TRUE, first,
2392 fde->next == NULL ? EH_FRAME_ALIGNMENT : 2);
2393 }
38462edf 2394 }
2f0c68f2 2395 while (EH_FRAME_LINKONCE && seek_next_seg == 2);
72b016b4 2396
2f0c68f2 2397 if (EH_FRAME_LINKONCE)
6303c4ae
AM
2398 for (fde = all_fde_data; fde ; fde = fde->next)
2399 SET_HANDLED (fde, 0);
38462edf 2400
2f0c68f2
CM
2401#if SUPPORT_COMPACT_EH
2402 if (compact_eh)
2403 {
2404 /* Create remaining out of line table entries. */
2405 do
2406 {
2407 ccseg = NULL;
2408 seek_next_seg = 0;
2409
2410 for (fde = all_fde_data; fde ; fde = fde->next)
2411 {
2412 if ((fde->sections & CFI_EMIT_eh_frame) == 0
2413 && (fde->sections & CFI_EMIT_eh_frame_compact) == 0)
2414 continue;
2415
2416 if (fde->eh_header_type != EH_COMPACT_OUTLINE)
2417 continue;
2418 if (HANDLED (fde))
2419 continue;
2420 if (seek_next_seg && CUR_SEG (fde) != ccseg)
2421 {
2422 seek_next_seg = 2;
2423 continue;
2424 }
2425 if (!seek_next_seg)
2426 {
2427 ccseg = CUR_SEG (fde);
2428 /* Open .gnu_extab section. */
2429 get_cfi_seg (ccseg, ".gnu_extab",
2430 (SEC_ALLOC | SEC_LOAD | SEC_DATA
2431 | DWARF2_EH_FRAME_READ_ONLY),
2432 1);
2433 seek_next_seg = 1;
2434 }
2435 SET_HANDLED (fde, 1);
2436
2437 frag_align (1, 0, 0);
2438 record_alignment (now_seg, 1);
2439 output_compact_unwind_data (fde, 1);
2440 }
2441 }
2442 while (EH_FRAME_LINKONCE && seek_next_seg == 2);
2443
2444 for (fde = all_fde_data; fde ; fde = fde->next)
2445 SET_HANDLED (fde, 0);
2446
2447 /* Create index table fragments. */
2448 do
2449 {
2450 ccseg = NULL;
2451 seek_next_seg = 0;
2452
2453 for (fde = all_fde_data; fde ; fde = fde->next)
2454 {
2455 if ((fde->sections & CFI_EMIT_eh_frame) == 0
2456 && (fde->sections & CFI_EMIT_eh_frame_compact) == 0)
2457 continue;
2458
2459 if (HANDLED (fde))
2460 continue;
2461 if (seek_next_seg && CUR_SEG (fde) != ccseg)
2462 {
2463 seek_next_seg = 2;
2464 continue;
2465 }
2466 if (!seek_next_seg)
2467 {
2468 ccseg = CUR_SEG (fde);
2469 /* Open .eh_frame_entry section. */
2470 cfi_seg = get_cfi_seg (ccseg, ".eh_frame_entry",
2471 (SEC_ALLOC | SEC_LOAD | SEC_DATA
2472 | DWARF2_EH_FRAME_READ_ONLY),
2473 2);
2474 seek_next_seg = 1;
2475 }
2476 SET_HANDLED (fde, 1);
2477
2478 output_eh_header (fde);
2479 }
2480 }
2481 while (seek_next_seg == 2);
2482
2483 for (fde = all_fde_data; fde ; fde = fde->next)
2484 SET_HANDLED (fde, 0);
2485 }
2486#endif /* SUPPORT_COMPACT_EH */
2487
38462edf
JJ
2488 flag_traditional_format = save_flag_traditional_format;
2489 }
2490
bd5608dc 2491 cfi_sections_set = TRUE;
2f0c68f2 2492 if ((all_cfi_sections & CFI_EMIT_debug_frame) != 0)
a4447b93 2493 {
38462edf 2494 int alignment = ffs (DWARF2_ADDR_SIZE (stdoutput)) - 1;
a4447b93 2495
6303c4ae
AM
2496 if (!SUPPORT_FRAME_LINKONCE)
2497 get_cfi_seg (NULL, ".debug_frame",
2498 SEC_READONLY | SEC_DEBUGGING,
2499 alignment);
2500
72b016b4 2501 do
83e12deb 2502 {
72b016b4 2503 ccseg = NULL;
72b016b4 2504 seek_next_seg = 0;
67ed7401 2505
72b016b4 2506 for (cie = cie_root; cie; cie = cie_next)
38462edf 2507 {
72b016b4
NC
2508 cie_next = cie->next;
2509 free ((void *) cie);
38462edf 2510 }
72b016b4 2511 cie_root = NULL;
38462edf 2512
72b016b4
NC
2513 for (fde = all_fde_data; fde ; fde = fde->next)
2514 {
2f0c68f2
CM
2515 if ((fde->sections & CFI_EMIT_debug_frame) == 0)
2516 continue;
2517
6303c4ae
AM
2518 if (SUPPORT_FRAME_LINKONCE)
2519 {
2520 if (HANDLED (fde))
2521 continue;
2522 if (seek_next_seg && CUR_SEG (fde) != ccseg)
2523 {
2524 seek_next_seg = 2;
2525 continue;
2526 }
2527 if (!seek_next_seg)
2528 {
2529 ccseg = CUR_SEG (fde);
2530 /* Open .debug_frame section. */
2531 get_cfi_seg (ccseg, ".debug_frame",
2532 SEC_READONLY | SEC_DEBUGGING,
2533 alignment);
2534 seek_next_seg = 1;
2535 }
2536 SET_HANDLED (fde, 1);
72b016b4 2537 }
72b016b4
NC
2538 if (fde->end_address == NULL)
2539 {
9e1a8675
AM
2540 as_bad (_("open CFI at the end of file; "
2541 "missing .cfi_endproc directive"));
72b016b4
NC
2542 fde->end_address = fde->start_address;
2543 }
2544
2545 fde->per_encoding = DW_EH_PE_omit;
2546 fde->lsda_encoding = DW_EH_PE_omit;
2547 cfi_change_reg_numbers (fde->data, ccseg);
2548 cie = select_cie_for_fde (fde, FALSE, &first, alignment);
2549 output_fde (fde, cie, FALSE, first, alignment);
2550 }
38462edf 2551 }
67ed7401 2552 while (SUPPORT_FRAME_LINKONCE && seek_next_seg == 2);
72b016b4 2553
6303c4ae
AM
2554 if (SUPPORT_FRAME_LINKONCE)
2555 for (fde = all_fde_data; fde ; fde = fde->next)
2556 SET_HANDLED (fde, 0);
38462edf 2557 }
54cfded0 2558}
0a7b15ff
JB
2559
2560#else /* TARGET_USE_CFIPOP */
d58a1929 2561
5ff2bd08 2562/* Emit an intelligible error message for missing support. */
d58a1929
RH
2563
2564static void
2565dot_cfi_dummy (int ignored ATTRIBUTE_UNUSED)
2566{
2567 as_bad (_("CFI is not supported for this target"));
2568 ignore_rest_of_line ();
2569}
2570
2571const pseudo_typeS cfi_pseudo_table[] =
2572 {
2573 { "cfi_sections", dot_cfi_dummy, 0 },
2574 { "cfi_startproc", dot_cfi_dummy, 0 },
2575 { "cfi_endproc", dot_cfi_dummy, 0 },
2f0c68f2 2576 { "cfi_fde_data", dot_cfi_dummy, 0 },
d58a1929
RH
2577 { "cfi_def_cfa", dot_cfi_dummy, 0 },
2578 { "cfi_def_cfa_register", dot_cfi_dummy, 0 },
2579 { "cfi_def_cfa_offset", dot_cfi_dummy, 0 },
2580 { "cfi_adjust_cfa_offset", dot_cfi_dummy, 0 },
2581 { "cfi_offset", dot_cfi_dummy, 0 },
2582 { "cfi_rel_offset", dot_cfi_dummy, 0 },
2583 { "cfi_register", dot_cfi_dummy, 0 },
2584 { "cfi_return_column", dot_cfi_dummy, 0 },
2585 { "cfi_restore", dot_cfi_dummy, 0 },
2586 { "cfi_undefined", dot_cfi_dummy, 0 },
2587 { "cfi_same_value", dot_cfi_dummy, 0 },
2588 { "cfi_remember_state", dot_cfi_dummy, 0 },
2589 { "cfi_restore_state", dot_cfi_dummy, 0 },
2590 { "cfi_window_save", dot_cfi_dummy, 0 },
2591 { "cfi_escape", dot_cfi_dummy, 0 },
2592 { "cfi_signal_frame", dot_cfi_dummy, 0 },
2593 { "cfi_personality", dot_cfi_dummy, 0 },
2f0c68f2 2594 { "cfi_personality_id", dot_cfi_dummy, 0 },
d58a1929
RH
2595 { "cfi_lsda", dot_cfi_dummy, 0 },
2596 { "cfi_val_encoded_addr", dot_cfi_dummy, 0 },
73e76108 2597 { "cfi_label", dot_cfi_dummy, 0 },
2f0c68f2 2598 { "cfi_inline_lsda", dot_cfi_dummy, 0 },
084303b8 2599 { "cfi_val_offset", dot_cfi_dummy, 0 },
d58a1929
RH
2600 { NULL, NULL, 0 }
2601 };
2602
0a7b15ff
JB
2603void
2604cfi_finish (void)
2605{
2606}
2607#endif /* TARGET_USE_CFIPOP */
This page took 0.922557 seconds and 4 git commands to generate.