gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gas / dw2gencfi.c
CommitLineData
54cfded0 1/* dw2gencfi.c - Support for generating Dwarf2 CFI information.
b3adc24a 2 Copyright (C) 2003-2020 Free Software Foundation, Inc.
54cfded0
AM
3 Contributed by Michal Ludvig <mludvig@suse.cz>
4
5 This file is part of GAS, the GNU Assembler.
6
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
ec2655a6 9 the Free Software Foundation; either version 3, or (at your option)
54cfded0
AM
10 any later version.
11
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to the Free
4b4da160
NC
19 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
20 02110-1301, USA. */
54cfded0 21
54cfded0
AM
22#include "as.h"
23#include "dw2gencfi.h"
ae424f82 24#include "subsegs.h"
38462edf 25#include "dwarf2dbg.h"
54cfded0 26
0a7b15ff 27#ifdef TARGET_USE_CFIPOP
a4447b93 28
3dd24306
DA
29/* By default, use difference expressions if DIFF_EXPR_OK is defined. */
30#ifndef CFI_DIFF_EXPR_OK
31# ifdef DIFF_EXPR_OK
32# define CFI_DIFF_EXPR_OK 1
33# else
34# define CFI_DIFF_EXPR_OK 0
35# endif
36#endif
37
2c678708 38#ifndef CFI_DIFF_LSDA_OK
72b016b4 39#define CFI_DIFF_LSDA_OK CFI_DIFF_EXPR_OK
2c678708
MK
40#endif
41
42#if CFI_DIFF_EXPR_OK == 1 && CFI_DIFF_LSDA_OK == 0
43# error "CFI_DIFF_EXPR_OK should imply CFI_DIFF_LSDA_OK"
44#endif
45
a4447b93
RH
46/* We re-use DWARF2_LINE_MIN_INSN_LENGTH for the code alignment field
47 of the CIE. Default to 1 if not otherwise specified. */
72b016b4
NC
48#ifndef DWARF2_LINE_MIN_INSN_LENGTH
49#define DWARF2_LINE_MIN_INSN_LENGTH 1
a4447b93
RH
50#endif
51
8c9b70b1
RH
52/* By default, use 32-bit relocations from .eh_frame into .text. */
53#ifndef DWARF2_FDE_RELOC_SIZE
72b016b4 54#define DWARF2_FDE_RELOC_SIZE 4
8c9b70b1
RH
55#endif
56
57/* By default, use a read-only .eh_frame section. */
58#ifndef DWARF2_EH_FRAME_READ_ONLY
72b016b4 59#define DWARF2_EH_FRAME_READ_ONLY SEC_READONLY
8c9b70b1
RH
60#endif
61
9393cb0d 62#ifndef EH_FRAME_ALIGNMENT
72b016b4 63#define EH_FRAME_ALIGNMENT (bfd_get_arch_size (stdoutput) == 64 ? 3 : 2)
9393cb0d
JJ
64#endif
65
a4447b93 66#ifndef tc_cfi_frame_initial_instructions
72b016b4 67#define tc_cfi_frame_initial_instructions() ((void)0)
a4447b93
RH
68#endif
69
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 },
e8dc9b5b 729 { "cfi_negate_ra_state", dot_cfi, DW_CFA_AARCH64_negate_ra_state },
cdfbf930 730 { "cfi_escape", dot_cfi_escape, 0 },
63752a75 731 { "cfi_signal_frame", dot_cfi, CFI_signal_frame },
9b8ae42e 732 { "cfi_personality", dot_cfi_personality, 0 },
2f0c68f2 733 { "cfi_personality_id", dot_cfi_personality_id, 0 },
9b8ae42e 734 { "cfi_lsda", dot_cfi_lsda, 0 },
f1c4cc75 735 { "cfi_val_encoded_addr", dot_cfi_val_encoded_addr, 0 },
2f0c68f2 736 { "cfi_inline_lsda", dot_cfi_inline_lsda, 0 },
69602580 737 { "cfi_label", dot_cfi_label, 0 },
084303b8 738 { "cfi_val_offset", dot_cfi, DW_CFA_val_offset },
a4447b93
RH
739 { NULL, NULL, 0 }
740 };
54cfded0
AM
741
742static void
a4447b93 743cfi_parse_separator (void)
54cfded0 744{
a4447b93
RH
745 SKIP_WHITESPACE ();
746 if (*input_line_pointer == ',')
747 input_line_pointer++;
748 else
749 as_bad (_("missing separator"));
54cfded0
AM
750}
751
a60de03c
JB
752#ifndef tc_parse_to_dw2regnum
753static void
72b016b4 754tc_parse_to_dw2regnum (expressionS *exp)
54cfded0 755{
a60de03c 756# ifdef tc_regname_to_dw2regnum
a4447b93
RH
757 SKIP_WHITESPACE ();
758 if (is_name_beginner (*input_line_pointer)
759 || (*input_line_pointer == '%'
760 && is_name_beginner (*++input_line_pointer)))
761 {
762 char *name, c;
763
d02603dc 764 c = get_symbol_name (& name);
a4447b93 765
a60de03c
JB
766 exp->X_op = O_constant;
767 exp->X_add_number = tc_regname_to_dw2regnum (name);
54cfded0 768
d02603dc 769 restore_line_pointer (c);
a4447b93 770 }
a60de03c
JB
771 else
772# endif
773 expression_and_evaluate (exp);
774}
a4447b93
RH
775#endif
776
a60de03c
JB
777static unsigned
778cfi_parse_reg (void)
779{
780 int regno;
781 expressionS exp;
782
783 tc_parse_to_dw2regnum (&exp);
a4447b93 784 switch (exp.X_op)
54cfded0 785 {
a4447b93
RH
786 case O_register:
787 case O_constant:
788 regno = exp.X_add_number;
789 break;
790
791 default:
a60de03c
JB
792 regno = -1;
793 break;
794 }
795
796 if (regno < 0)
797 {
a4447b93
RH
798 as_bad (_("bad register expression"));
799 regno = 0;
54cfded0
AM
800 }
801
a4447b93
RH
802 return regno;
803}
804
805static offsetT
806cfi_parse_const (void)
807{
808 return get_absolute_expression ();
54cfded0
AM
809}
810
811static void
a4447b93 812dot_cfi (int arg)
54cfded0 813{
a4447b93
RH
814 offsetT offset;
815 unsigned reg1, reg2;
54cfded0 816
ae424f82 817 if (frchain_now->frch_cfi_data == NULL)
54cfded0
AM
818 {
819 as_bad (_("CFI instruction used without previous .cfi_startproc"));
7c9c8381 820 ignore_rest_of_line ();
54cfded0
AM
821 return;
822 }
823
a4447b93 824 /* If the last address was not at the current PC, advance to current. */
ae424f82 825 if (symbol_get_frag (frchain_now->frch_cfi_data->last_address) != frag_now
9e1a8675
AM
826 || (S_GET_VALUE (frchain_now->frch_cfi_data->last_address)
827 != frag_now_fix ()))
a4447b93 828 cfi_add_advance_loc (symbol_temp_new_now ());
54cfded0
AM
829
830 switch (arg)
831 {
a4447b93 832 case DW_CFA_offset:
a4447b93
RH
833 reg1 = cfi_parse_reg ();
834 cfi_parse_separator ();
835 offset = cfi_parse_const ();
2be24b54
ML
836 cfi_add_CFA_offset (reg1, offset);
837 break;
a4447b93 838
084303b8
AK
839 case DW_CFA_val_offset:
840 reg1 = cfi_parse_reg ();
841 cfi_parse_separator ();
842 offset = cfi_parse_const ();
843 cfi_add_CFA_val_offset (reg1, offset);
844 break;
845
fa87b337
RH
846 case CFI_rel_offset:
847 reg1 = cfi_parse_reg ();
848 cfi_parse_separator ();
849 offset = cfi_parse_const ();
ae424f82
JJ
850 cfi_add_CFA_offset (reg1,
851 offset - frchain_now->frch_cfi_data->cur_cfa_offset);
fa87b337
RH
852 break;
853
2be24b54
ML
854 case DW_CFA_def_cfa:
855 reg1 = cfi_parse_reg ();
856 cfi_parse_separator ();
857 offset = cfi_parse_const ();
858 cfi_add_CFA_def_cfa (reg1, offset);
54cfded0
AM
859 break;
860
a4447b93
RH
861 case DW_CFA_register:
862 reg1 = cfi_parse_reg ();
863 cfi_parse_separator ();
864 reg2 = cfi_parse_reg ();
a4447b93 865 cfi_add_CFA_register (reg1, reg2);
39b82151
ML
866 break;
867
a4447b93
RH
868 case DW_CFA_def_cfa_register:
869 reg1 = cfi_parse_reg ();
870 cfi_add_CFA_def_cfa_register (reg1);
54cfded0
AM
871 break;
872
a4447b93
RH
873 case DW_CFA_def_cfa_offset:
874 offset = cfi_parse_const ();
875 cfi_add_CFA_def_cfa_offset (offset);
54cfded0
AM
876 break;
877
54cfded0 878 case CFI_adjust_cfa_offset:
a4447b93 879 offset = cfi_parse_const ();
ae424f82
JJ
880 cfi_add_CFA_def_cfa_offset (frchain_now->frch_cfi_data->cur_cfa_offset
881 + offset);
54cfded0
AM
882 break;
883
2be24b54 884 case DW_CFA_restore:
b57d375b
JB
885 for (;;)
886 {
887 reg1 = cfi_parse_reg ();
888 cfi_add_CFA_restore (reg1);
889 SKIP_WHITESPACE ();
890 if (*input_line_pointer != ',')
891 break;
892 ++input_line_pointer;
893 }
2be24b54
ML
894 break;
895
896 case DW_CFA_undefined:
b57d375b
JB
897 for (;;)
898 {
899 reg1 = cfi_parse_reg ();
900 cfi_add_CFA_undefined (reg1);
901 SKIP_WHITESPACE ();
902 if (*input_line_pointer != ',')
903 break;
904 ++input_line_pointer;
905 }
2be24b54
ML
906 break;
907
908 case DW_CFA_same_value:
909 reg1 = cfi_parse_reg ();
910 cfi_add_CFA_same_value (reg1);
911 break;
912
913 case CFI_return_column:
914 reg1 = cfi_parse_reg ();
915 cfi_set_return_column (reg1);
916 break;
917
918 case DW_CFA_remember_state:
919 cfi_add_CFA_remember_state ();
920 break;
921
922 case DW_CFA_restore_state:
923 cfi_add_CFA_restore_state ();
924 break;
925
364b6d8b
JJ
926 case DW_CFA_GNU_window_save:
927 cfi_add_CFA_insn (DW_CFA_GNU_window_save);
928 break;
929
63752a75 930 case CFI_signal_frame:
ae424f82 931 frchain_now->frch_cfi_data->cur_fde_data->signal_frame = 1;
63752a75
JJ
932 break;
933
54cfded0 934 default:
a4447b93 935 abort ();
54cfded0 936 }
54cfded0 937
a4447b93 938 demand_empty_rest_of_line ();
54cfded0
AM
939}
940
cdfbf930
RH
941static void
942dot_cfi_escape (int ignored ATTRIBUTE_UNUSED)
943{
944 struct cfi_escape_data *head, **tail, *e;
945 struct cfi_insn_data *insn;
946
ae424f82 947 if (frchain_now->frch_cfi_data == NULL)
cdfbf930
RH
948 {
949 as_bad (_("CFI instruction used without previous .cfi_startproc"));
7c9c8381 950 ignore_rest_of_line ();
cdfbf930
RH
951 return;
952 }
953
954 /* If the last address was not at the current PC, advance to current. */
ae424f82 955 if (symbol_get_frag (frchain_now->frch_cfi_data->last_address) != frag_now
9e1a8675
AM
956 || (S_GET_VALUE (frchain_now->frch_cfi_data->last_address)
957 != frag_now_fix ()))
cdfbf930
RH
958 cfi_add_advance_loc (symbol_temp_new_now ());
959
960 tail = &head;
961 do
962 {
add39d23 963 e = XNEW (struct cfi_escape_data);
cdfbf930
RH
964 do_parse_cons_expression (&e->exp, 1);
965 *tail = e;
966 tail = &e->next;
967 }
968 while (*input_line_pointer++ == ',');
969 *tail = NULL;
970
971 insn = alloc_cfi_insn_data ();
972 insn->insn = CFI_escape;
973 insn->u.esc = head;
7c9c8381
JB
974
975 --input_line_pointer;
976 demand_empty_rest_of_line ();
cdfbf930
RH
977}
978
9b8ae42e
JJ
979static void
980dot_cfi_personality (int ignored ATTRIBUTE_UNUSED)
981{
982 struct fde_entry *fde;
983 offsetT encoding;
984
985 if (frchain_now->frch_cfi_data == NULL)
986 {
987 as_bad (_("CFI instruction used without previous .cfi_startproc"));
988 ignore_rest_of_line ();
989 return;
990 }
991
992 fde = frchain_now->frch_cfi_data->cur_fde_data;
f1c4cc75 993 encoding = cfi_parse_const ();
9b8ae42e
JJ
994 if (encoding == DW_EH_PE_omit)
995 {
996 demand_empty_rest_of_line ();
997 fde->per_encoding = encoding;
998 return;
999 }
1000
1001 if ((encoding & 0xff) != encoding
2f0c68f2 1002 || ((((encoding & 0x70) != 0
3dd24306 1003#if CFI_DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr
9e1a8675 1004 && (encoding & 0x70) != DW_EH_PE_pcrel
9b8ae42e 1005#endif
9e1a8675
AM
1006 )
1007 /* leb128 can be handled, but does something actually need it? */
2f0c68f2
CM
1008 || (encoding & 7) == DW_EH_PE_uleb128
1009 || (encoding & 7) > DW_EH_PE_udata8)
9e1a8675 1010 && tc_cfi_reloc_for_encoding (encoding) == BFD_RELOC_NONE))
9b8ae42e
JJ
1011 {
1012 as_bad (_("invalid or unsupported encoding in .cfi_personality"));
1013 ignore_rest_of_line ();
1014 return;
1015 }
1016
1017 if (*input_line_pointer++ != ',')
1018 {
1019 as_bad (_(".cfi_personality requires encoding and symbol arguments"));
1020 ignore_rest_of_line ();
1021 return;
1022 }
1023
1024 expression_and_evaluate (&fde->personality);
1025 switch (fde->personality.X_op)
1026 {
1027 case O_symbol:
1028 break;
1029 case O_constant:
1030 if ((encoding & 0x70) == DW_EH_PE_pcrel)
1031 encoding = DW_EH_PE_omit;
1032 break;
1033 default:
1034 encoding = DW_EH_PE_omit;
1035 break;
1036 }
1037
1038 fde->per_encoding = encoding;
1039
1040 if (encoding == DW_EH_PE_omit)
1041 {
1042 as_bad (_("wrong second argument to .cfi_personality"));
1043 ignore_rest_of_line ();
1044 return;
1045 }
1046
1047 demand_empty_rest_of_line ();
1048}
1049
1050static void
1051dot_cfi_lsda (int ignored ATTRIBUTE_UNUSED)
1052{
1053 struct fde_entry *fde;
1054 offsetT encoding;
1055
1056 if (frchain_now->frch_cfi_data == NULL)
1057 {
1058 as_bad (_("CFI instruction used without previous .cfi_startproc"));
1059 ignore_rest_of_line ();
1060 return;
1061 }
1062
1063 fde = frchain_now->frch_cfi_data->cur_fde_data;
f1c4cc75 1064 encoding = cfi_parse_const ();
9b8ae42e
JJ
1065 if (encoding == DW_EH_PE_omit)
1066 {
1067 demand_empty_rest_of_line ();
1068 fde->lsda_encoding = encoding;
1069 return;
1070 }
1071
1072 if ((encoding & 0xff) != encoding
2f0c68f2 1073 || ((((encoding & 0x70) != 0
2c678708 1074#if CFI_DIFF_LSDA_OK || defined tc_cfi_emit_pcrel_expr
2f0c68f2 1075 && (encoding & 0x70) != DW_EH_PE_pcrel
9b8ae42e 1076#endif
9e1a8675
AM
1077 )
1078 /* leb128 can be handled, but does something actually need it? */
2f0c68f2
CM
1079 || (encoding & 7) == DW_EH_PE_uleb128
1080 || (encoding & 7) > DW_EH_PE_udata8)
1081 && tc_cfi_reloc_for_encoding (encoding) == BFD_RELOC_NONE))
9b8ae42e
JJ
1082 {
1083 as_bad (_("invalid or unsupported encoding in .cfi_lsda"));
1084 ignore_rest_of_line ();
1085 return;
1086 }
1087
1088 if (*input_line_pointer++ != ',')
1089 {
1090 as_bad (_(".cfi_lsda requires encoding and symbol arguments"));
1091 ignore_rest_of_line ();
1092 return;
1093 }
1094
1095 fde->lsda_encoding = encoding;
1096
1097 expression_and_evaluate (&fde->lsda);
1098 switch (fde->lsda.X_op)
1099 {
1100 case O_symbol:
1101 break;
1102 case O_constant:
1103 if ((encoding & 0x70) == DW_EH_PE_pcrel)
1104 encoding = DW_EH_PE_omit;
1105 break;
1106 default:
1107 encoding = DW_EH_PE_omit;
1108 break;
1109 }
1110
1111 fde->lsda_encoding = encoding;
1112
1113 if (encoding == DW_EH_PE_omit)
1114 {
1115 as_bad (_("wrong second argument to .cfi_lsda"));
1116 ignore_rest_of_line ();
1117 return;
1118 }
1119
1120 demand_empty_rest_of_line ();
1121}
1122
f1c4cc75
RH
1123static void
1124dot_cfi_val_encoded_addr (int ignored ATTRIBUTE_UNUSED)
1125{
1126 struct cfi_insn_data *insn_ptr;
1127 offsetT encoding;
1128
1129 if (frchain_now->frch_cfi_data == NULL)
1130 {
1131 as_bad (_("CFI instruction used without previous .cfi_startproc"));
1132 ignore_rest_of_line ();
1133 return;
1134 }
1135
1136 /* If the last address was not at the current PC, advance to current. */
1137 if (symbol_get_frag (frchain_now->frch_cfi_data->last_address) != frag_now
9e1a8675
AM
1138 || (S_GET_VALUE (frchain_now->frch_cfi_data->last_address)
1139 != frag_now_fix ()))
f1c4cc75
RH
1140 cfi_add_advance_loc (symbol_temp_new_now ());
1141
1142 insn_ptr = alloc_cfi_insn_data ();
1143 insn_ptr->insn = CFI_val_encoded_addr;
72b016b4 1144
f1c4cc75
RH
1145 insn_ptr->u.ea.reg = cfi_parse_reg ();
1146
1147 cfi_parse_separator ();
1148 encoding = cfi_parse_const ();
1149 if ((encoding & 0xff) != encoding
1150 || ((encoding & 0x70) != 0
1151#if CFI_DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr
1152 && (encoding & 0x70) != DW_EH_PE_pcrel
1153#endif
1154 )
9e1a8675 1155 /* leb128 can be handled, but does something actually need it? */
f1c4cc75
RH
1156 || (encoding & 7) == DW_EH_PE_uleb128
1157 || (encoding & 7) > DW_EH_PE_udata8)
1158 {
1159 as_bad (_("invalid or unsupported encoding in .cfi_lsda"));
1160 encoding = DW_EH_PE_omit;
1161 }
1162
1163 cfi_parse_separator ();
1164 expression_and_evaluate (&insn_ptr->u.ea.exp);
1165 switch (insn_ptr->u.ea.exp.X_op)
1166 {
1167 case O_symbol:
1168 break;
1169 case O_constant:
1170 if ((encoding & 0x70) != DW_EH_PE_pcrel)
83e12deb 1171 break;
1a0670f3 1172 /* Fall through. */
f1c4cc75
RH
1173 default:
1174 encoding = DW_EH_PE_omit;
1175 break;
1176 }
1177
1178 insn_ptr->u.ea.encoding = encoding;
1179 if (encoding == DW_EH_PE_omit)
1180 {
1181 as_bad (_("wrong third argument to .cfi_val_encoded_addr"));
1182 ignore_rest_of_line ();
1183 return;
1184 }
1185
1186 demand_empty_rest_of_line ();
1187}
1188
69602580
JB
1189static void
1190dot_cfi_label (int ignored ATTRIBUTE_UNUSED)
1191{
314a80c4 1192 char *name;
1193
1194 if (frchain_now->frch_cfi_data == NULL)
1195 {
1196 as_bad (_("CFI instruction used without previous .cfi_startproc"));
1197 ignore_rest_of_line ();
1198 return;
1199 }
69602580 1200
314a80c4 1201 name = read_symbol_name ();
69602580
JB
1202 if (name == NULL)
1203 return;
1204
1205 /* If the last address was not at the current PC, advance to current. */
1206 if (symbol_get_frag (frchain_now->frch_cfi_data->last_address) != frag_now
9e1a8675
AM
1207 || (S_GET_VALUE (frchain_now->frch_cfi_data->last_address)
1208 != frag_now_fix ()))
69602580
JB
1209 cfi_add_advance_loc (symbol_temp_new_now ());
1210
1211 cfi_add_label (name);
92e18d93 1212 free (name);
69602580
JB
1213
1214 demand_empty_rest_of_line ();
1215}
1216
38462edf
JJ
1217static void
1218dot_cfi_sections (int ignored ATTRIBUTE_UNUSED)
1219{
1220 int sections = 0;
1221
1222 SKIP_WHITESPACE ();
d02603dc 1223 if (is_name_beginner (*input_line_pointer) || *input_line_pointer == '"')
38462edf
JJ
1224 while (1)
1225 {
d02603dc 1226 char * saved_ilp;
38462edf
JJ
1227 char *name, c;
1228
d02603dc
NC
1229 saved_ilp = input_line_pointer;
1230 c = get_symbol_name (& name);
38462edf 1231
72b016b4
NC
1232 if (strncmp (name, ".eh_frame", sizeof ".eh_frame") == 0
1233 && name[9] != '_')
38462edf 1234 sections |= CFI_EMIT_eh_frame;
72b016b4 1235 else if (strncmp (name, ".debug_frame", sizeof ".debug_frame") == 0)
38462edf 1236 sections |= CFI_EMIT_debug_frame;
2f0c68f2 1237#if SUPPORT_COMPACT_EH
9e1a8675
AM
1238 else if (strncmp (name, ".eh_frame_entry",
1239 sizeof ".eh_frame_entry") == 0)
2f0c68f2
CM
1240 {
1241 compact_eh = TRUE;
1242 sections |= CFI_EMIT_eh_frame_compact;
1243 }
1244#endif
1bce6bd8
PB
1245#ifdef tc_cfi_section_name
1246 else if (strcmp (name, tc_cfi_section_name) == 0)
1247 sections |= CFI_EMIT_target;
1248#endif
38462edf
JJ
1249 else
1250 {
1251 *input_line_pointer = c;
d02603dc 1252 input_line_pointer = saved_ilp;
38462edf
JJ
1253 break;
1254 }
1255
1256 *input_line_pointer = c;
d02603dc 1257 SKIP_WHITESPACE_AFTER_NAME ();
38462edf
JJ
1258 if (*input_line_pointer == ',')
1259 {
1260 name = input_line_pointer++;
1261 SKIP_WHITESPACE ();
9e1a8675
AM
1262 if (!is_name_beginner (*input_line_pointer)
1263 && *input_line_pointer != '"')
38462edf
JJ
1264 {
1265 input_line_pointer = name;
1266 break;
1267 }
1268 }
9e1a8675
AM
1269 else if (is_name_beginner (*input_line_pointer)
1270 || *input_line_pointer == '"')
38462edf
JJ
1271 break;
1272 }
1273
1274 demand_empty_rest_of_line ();
3d3424e9
MF
1275 if (cfi_sections_set
1276 && (sections & (CFI_EMIT_eh_frame | CFI_EMIT_eh_frame_compact))
9e1a8675
AM
1277 && ((cfi_sections & (CFI_EMIT_eh_frame | CFI_EMIT_eh_frame_compact))
1278 != (sections & (CFI_EMIT_eh_frame | CFI_EMIT_eh_frame_compact))))
2f0c68f2 1279 as_bad (_("inconsistent uses of .cfi_sections"));
38462edf
JJ
1280 cfi_sections = sections;
1281}
1282
54cfded0 1283static void
a4447b93 1284dot_cfi_startproc (int ignored ATTRIBUTE_UNUSED)
54cfded0 1285{
a4447b93 1286 int simple = 0;
39b82151 1287
ae424f82 1288 if (frchain_now->frch_cfi_data != NULL)
54cfded0
AM
1289 {
1290 as_bad (_("previous CFI entry not closed (missing .cfi_endproc)"));
7c9c8381 1291 ignore_rest_of_line ();
54cfded0
AM
1292 return;
1293 }
1294
a4447b93 1295 cfi_new_fde (symbol_temp_new_now ());
39b82151 1296
a4447b93 1297 SKIP_WHITESPACE ();
d02603dc 1298 if (is_name_beginner (*input_line_pointer) || *input_line_pointer == '"')
a4447b93 1299 {
d02603dc 1300 char * saved_ilp = input_line_pointer;
a4447b93 1301 char *name, c;
54cfded0 1302
d02603dc 1303 c = get_symbol_name (& name);
54cfded0 1304
a4447b93
RH
1305 if (strcmp (name, "simple") == 0)
1306 {
1307 simple = 1;
d02603dc 1308 restore_line_pointer (c);
a4447b93
RH
1309 }
1310 else
d02603dc 1311 input_line_pointer = saved_ilp;
a4447b93
RH
1312 }
1313 demand_empty_rest_of_line ();
1314
bd5608dc 1315 cfi_sections_set = TRUE;
2f0c68f2
CM
1316 all_cfi_sections |= cfi_sections;
1317 cfi_set_sections ();
ae424f82 1318 frchain_now->frch_cfi_data->cur_cfa_offset = 0;
a4447b93 1319 if (!simple)
39b82151 1320 tc_cfi_frame_initial_instructions ();
1bce6bd8
PB
1321
1322 if ((cfi_sections & CFI_EMIT_target) != 0)
1323 tc_cfi_startproc ();
54cfded0
AM
1324}
1325
a4447b93
RH
1326static void
1327dot_cfi_endproc (int ignored ATTRIBUTE_UNUSED)
1328{
ae424f82 1329 if (frchain_now->frch_cfi_data == NULL)
a4447b93
RH
1330 {
1331 as_bad (_(".cfi_endproc without corresponding .cfi_startproc"));
7c9c8381 1332 ignore_rest_of_line ();
a4447b93
RH
1333 return;
1334 }
54cfded0 1335
2f0c68f2 1336 last_fde = frchain_now->frch_cfi_data->cur_fde_data;
1bce6bd8 1337
a4447b93 1338 cfi_end_fde (symbol_temp_new_now ());
7c9c8381
JB
1339
1340 demand_empty_rest_of_line ();
1bce6bd8 1341
bd5608dc 1342 cfi_sections_set = TRUE;
1bce6bd8 1343 if ((cfi_sections & CFI_EMIT_target) != 0)
2f0c68f2 1344 tc_cfi_endproc (last_fde);
a4447b93 1345}
39b82151 1346
2f0c68f2
CM
1347static segT
1348get_cfi_seg (segT cseg, const char *base, flagword flags, int align)
54cfded0 1349{
2f0c68f2
CM
1350 /* Exclude .debug_frame sections for Compact EH. */
1351 if (SUPPORT_FRAME_LINKONCE || ((flags & SEC_DEBUGGING) == 0 && compact_eh))
1352 {
1353 struct dwcfi_seg_list *l;
1354
1355 l = dwcfi_hash_find_or_make (cseg, base, flags);
1356
1357 cseg = l->seg;
1358 subseg_set (cseg, l->subseg);
1359 }
1360 else
1361 {
1362 cseg = subseg_new (base, 0);
fd361982 1363 bfd_set_section_flags (cseg, flags);
2f0c68f2
CM
1364 }
1365 record_alignment (cseg, align);
1366 return cseg;
a4447b93 1367}
54cfded0 1368
2f0c68f2
CM
1369#if SUPPORT_COMPACT_EH
1370static void
1371dot_cfi_personality_id (int ignored ATTRIBUTE_UNUSED)
1372{
1373 struct fde_entry *fde;
54cfded0 1374
2f0c68f2
CM
1375 if (frchain_now->frch_cfi_data == NULL)
1376 {
1377 as_bad (_("CFI instruction used without previous .cfi_startproc"));
1378 ignore_rest_of_line ();
1379 return;
1380 }
1381
1382 fde = frchain_now->frch_cfi_data->cur_fde_data;
1383 fde->personality_id = cfi_parse_const ();
1384 demand_empty_rest_of_line ();
1385
1386 if (fde->personality_id == 0 || fde->personality_id > 3)
1387 {
1388 as_bad (_("wrong argument to .cfi_personality_id"));
1389 return;
1390 }
1391}
1392
1393static void
1394dot_cfi_fde_data (int ignored ATTRIBUTE_UNUSED)
a4447b93 1395{
2f0c68f2
CM
1396 if (frchain_now->frch_cfi_data == NULL)
1397 {
1398 as_bad (_(".cfi_fde_data without corresponding .cfi_startproc"));
1399 ignore_rest_of_line ();
1400 return;
1401 }
1402
1403 last_fde = frchain_now->frch_cfi_data->cur_fde_data;
1404
bd5608dc 1405 cfi_sections_set = TRUE;
2f0c68f2
CM
1406 if ((cfi_sections & CFI_EMIT_target) != 0
1407 || (cfi_sections & CFI_EMIT_eh_frame_compact) != 0)
1408 {
1409 struct cfi_escape_data *head, **tail, *e;
1410 int num_ops = 0;
1411
1412 tail = &head;
1413 if (!is_it_end_of_statement ())
1414 {
1415 num_ops = 0;
1416 do
1417 {
add39d23 1418 e = XNEW (struct cfi_escape_data);
2f0c68f2
CM
1419 do_parse_cons_expression (&e->exp, 1);
1420 *tail = e;
1421 tail = &e->next;
1422 num_ops++;
1423 }
1424 while (*input_line_pointer++ == ',');
1425 --input_line_pointer;
1426 }
1427 *tail = NULL;
1428
1429 if (last_fde->lsda_encoding != DW_EH_PE_omit)
1430 last_fde->eh_header_type = EH_COMPACT_HAS_LSDA;
1431 else if (num_ops <= 3 && last_fde->per_encoding == DW_EH_PE_omit)
1432 last_fde->eh_header_type = EH_COMPACT_INLINE;
1433 else
1434 last_fde->eh_header_type = EH_COMPACT_OUTLINE;
1435
1436 if (last_fde->eh_header_type == EH_COMPACT_INLINE)
1437 num_ops = 3;
1438
1439 last_fde->eh_data_size = num_ops;
add39d23 1440 last_fde->eh_data = XNEWVEC (bfd_byte, num_ops);
2f0c68f2
CM
1441 num_ops = 0;
1442 while (head)
1443 {
1444 e = head;
1445 head = e->next;
1446 last_fde->eh_data[num_ops++] = e->exp.X_add_number;
1447 free (e);
1448 }
1449 if (last_fde->eh_header_type == EH_COMPACT_INLINE)
1450 while (num_ops < 3)
1451 last_fde->eh_data[num_ops++] = tc_compact_eh_opcode_stop;
1452 }
1453
1454 demand_empty_rest_of_line ();
a4447b93 1455}
54cfded0 1456
2f0c68f2
CM
1457/* Function to emit the compact unwinding opcodes stored in the
1458 fde's eh_data field. The end of the opcode data will be
1459 padded to the value in align. */
54cfded0 1460
2f0c68f2
CM
1461static void
1462output_compact_unwind_data (struct fde_entry *fde, int align)
a4447b93 1463{
2f0c68f2
CM
1464 int data_size = fde->eh_data_size + 2;
1465 int align_padding;
1466 int amask;
1467 char *p;
1468
1469 fde->eh_loc = symbol_temp_new_now ();
1470
1471 p = frag_more (1);
1472 if (fde->personality_id != 0)
1473 *p = fde->personality_id;
1474 else if (fde->per_encoding != DW_EH_PE_omit)
1475 {
1476 *p = 0;
1477 emit_expr_encoded (&fde->personality, fde->per_encoding, FALSE);
1478 data_size += encoding_size (fde->per_encoding);
1479 }
1480 else
1481 *p = 1;
1482
1483 amask = (1 << align) - 1;
1484 align_padding = ((data_size + amask) & ~amask) - data_size;
1485
1486 p = frag_more (fde->eh_data_size + 1 + align_padding);
1487 memcpy (p, fde->eh_data, fde->eh_data_size);
1488 p += fde->eh_data_size;
1489
1490 while (align_padding-- > 0)
1491 *(p++) = tc_compact_eh_opcode_pad;
1492
1493 *(p++) = tc_compact_eh_opcode_stop;
1494 fde->eh_header_type = EH_COMPACT_OUTLINE_DONE;
a4447b93
RH
1495}
1496
2f0c68f2
CM
1497/* Handle the .cfi_inline_lsda directive. */
1498static void
1499dot_cfi_inline_lsda (int ignored ATTRIBUTE_UNUSED)
1500{
1501 segT ccseg;
1502 int align;
1503 long max_alignment = 28;
1504
1505 if (!last_fde)
1506 {
1507 as_bad (_("unexpected .cfi_inline_lsda"));
1508 ignore_rest_of_line ();
1509 return;
1510 }
1511
1512 if ((last_fde->sections & CFI_EMIT_eh_frame_compact) == 0)
1513 {
1514 as_bad (_(".cfi_inline_lsda not valid for this frame"));
1515 ignore_rest_of_line ();
1516 return;
1517 }
1518
1519 if (last_fde->eh_header_type != EH_COMPACT_UNKNOWN
1520 && last_fde->eh_header_type != EH_COMPACT_HAS_LSDA)
1521 {
1522 as_bad (_(".cfi_inline_lsda seen for frame without .cfi_lsda"));
1523 ignore_rest_of_line ();
1524 return;
1525 }
1526
1527#ifdef md_flush_pending_output
1528 md_flush_pending_output ();
1529#endif
1530
1531 align = get_absolute_expression ();
1532 if (align > max_alignment)
1533 {
1534 align = max_alignment;
1535 as_bad (_("Alignment too large: %d. assumed."), align);
1536 }
1537 else if (align < 0)
1538 {
1539 as_warn (_("Alignment negative: 0 assumed."));
1540 align = 0;
1541 }
1542
1543 demand_empty_rest_of_line ();
1544 ccseg = CUR_SEG (last_fde);
54cfded0 1545
2f0c68f2
CM
1546 /* Open .gnu_extab section. */
1547 get_cfi_seg (ccseg, ".gnu_extab",
1548 (SEC_ALLOC | SEC_LOAD | SEC_DATA
1549 | DWARF2_EH_FRAME_READ_ONLY),
1550 1);
1551
1552 frag_align (align, 0, 0);
1553 record_alignment (now_seg, align);
1554 if (last_fde->eh_header_type == EH_COMPACT_HAS_LSDA)
1555 output_compact_unwind_data (last_fde, align);
1556
1557 last_fde = NULL;
1558
1559 return;
1560}
1561#else /* !SUPPORT_COMPACT_EH */
a4447b93 1562static void
2f0c68f2 1563dot_cfi_inline_lsda (int ignored ATTRIBUTE_UNUSED)
a4447b93 1564{
2f0c68f2
CM
1565 as_bad (_(".cfi_inline_lsda is not supported for this target"));
1566 ignore_rest_of_line ();
54cfded0
AM
1567}
1568
a4447b93 1569static void
2f0c68f2 1570dot_cfi_fde_data (int ignored ATTRIBUTE_UNUSED)
54cfded0 1571{
2f0c68f2
CM
1572 as_bad (_(".cfi_fde_data is not supported for this target"));
1573 ignore_rest_of_line ();
a4447b93 1574}
54cfded0 1575
2f0c68f2
CM
1576static void
1577dot_cfi_personality_id (int ignored ATTRIBUTE_UNUSED)
1578{
1579 as_bad (_(".cfi_personality_id is not supported for this target"));
1580 ignore_rest_of_line ();
1581}
1582#endif
1583\f
a4447b93
RH
1584static void
1585output_cfi_insn (struct cfi_insn_data *insn)
1586{
1587 offsetT offset;
1588 unsigned int regno;
54cfded0 1589
a4447b93 1590 switch (insn->insn)
54cfded0 1591 {
a4447b93
RH
1592 case DW_CFA_advance_loc:
1593 {
1594 symbolS *from = insn->u.ll.lab1;
1595 symbolS *to = insn->u.ll.lab2;
1596
1597 if (symbol_get_frag (to) == symbol_get_frag (from))
1598 {
1599 addressT delta = S_GET_VALUE (to) - S_GET_VALUE (from);
1600 addressT scaled = delta / DWARF2_LINE_MIN_INSN_LENGTH;
1601
6f69abb0
AM
1602 if (scaled == 0)
1603 ;
1604 else if (scaled <= 0x3F)
a4447b93 1605 out_one (DW_CFA_advance_loc + scaled);
395e8345 1606 else if (scaled <= 0xFF)
a4447b93 1607 {
9b8ae42e 1608 out_one (DW_CFA_advance_loc1);
395e8345 1609 out_one (scaled);
a4447b93 1610 }
395e8345 1611 else if (scaled <= 0xFFFF)
a4447b93 1612 {
9b8ae42e 1613 out_one (DW_CFA_advance_loc2);
395e8345 1614 out_two (scaled);
a4447b93
RH
1615 }
1616 else
1617 {
9b8ae42e 1618 out_one (DW_CFA_advance_loc4);
395e8345 1619 out_four (scaled);
a4447b93
RH
1620 }
1621 }
1622 else
1623 {
1624 expressionS exp;
1625
1626 exp.X_op = O_subtract;
1627 exp.X_add_symbol = to;
1628 exp.X_op_symbol = from;
1629 exp.X_add_number = 0;
1630
1631 /* The code in ehopt.c expects that one byte of the encoding
1632 is already allocated to the frag. This comes from the way
1633 that it scans the .eh_frame section looking first for the
b9d8f560
AM
1634 .byte DW_CFA_advance_loc4. Call frag_grow with the sum of
1635 room needed by frag_more and frag_var to preallocate space
1636 ensuring that the DW_CFA_advance_loc4 is in the fixed part
1637 of the rs_cfa frag, so that the relax machinery can remove
1638 the advance_loc should it advance by zero. */
1639 frag_grow (5);
1fbfe785 1640 *frag_more (1) = DW_CFA_advance_loc4;
a4447b93
RH
1641
1642 frag_var (rs_cfa, 4, 0, DWARF2_LINE_MIN_INSN_LENGTH << 3,
1643 make_expr_symbol (&exp), frag_now_fix () - 1,
1644 (char *) frag_now);
1645 }
1646 }
1647 break;
1648
1649 case DW_CFA_def_cfa:
1650 offset = insn->u.ri.offset;
1651 if (offset < 0)
54cfded0 1652 {
a4447b93
RH
1653 out_one (DW_CFA_def_cfa_sf);
1654 out_uleb128 (insn->u.ri.reg);
dcb45a06 1655 out_sleb128 (offset / DWARF2_CIE_DATA_ALIGNMENT);
54cfded0
AM
1656 }
1657 else
1658 {
a4447b93
RH
1659 out_one (DW_CFA_def_cfa);
1660 out_uleb128 (insn->u.ri.reg);
1661 out_uleb128 (offset);
54cfded0
AM
1662 }
1663 break;
1664
a4447b93 1665 case DW_CFA_def_cfa_register:
2be24b54
ML
1666 case DW_CFA_undefined:
1667 case DW_CFA_same_value:
1668 out_one (insn->insn);
1669 out_uleb128 (insn->u.r);
54cfded0
AM
1670 break;
1671
a4447b93
RH
1672 case DW_CFA_def_cfa_offset:
1673 offset = insn->u.i;
1674 if (offset < 0)
1675 {
1676 out_one (DW_CFA_def_cfa_offset_sf);
dcb45a06 1677 out_sleb128 (offset / DWARF2_CIE_DATA_ALIGNMENT);
a4447b93
RH
1678 }
1679 else
1680 {
1681 out_one (DW_CFA_def_cfa_offset);
1682 out_uleb128 (offset);
1683 }
54cfded0
AM
1684 break;
1685
2be24b54
ML
1686 case DW_CFA_restore:
1687 regno = insn->u.r;
1688 if (regno <= 0x3F)
1689 {
1690 out_one (DW_CFA_restore + regno);
1691 }
1692 else
1693 {
1694 out_one (DW_CFA_restore_extended);
1695 out_uleb128 (regno);
1696 }
1697 break;
1698
a4447b93
RH
1699 case DW_CFA_offset:
1700 regno = insn->u.ri.reg;
1701 offset = insn->u.ri.offset / DWARF2_CIE_DATA_ALIGNMENT;
1702 if (offset < 0)
1703 {
1233ae62 1704 out_one (DW_CFA_offset_extended_sf);
a4447b93
RH
1705 out_uleb128 (regno);
1706 out_sleb128 (offset);
1707 }
1708 else if (regno <= 0x3F)
1709 {
1710 out_one (DW_CFA_offset + regno);
1711 out_uleb128 (offset);
1712 }
54cfded0
AM
1713 else
1714 {
a4447b93
RH
1715 out_one (DW_CFA_offset_extended);
1716 out_uleb128 (regno);
1717 out_uleb128 (offset);
54cfded0 1718 }
54cfded0
AM
1719 break;
1720
084303b8
AK
1721 case DW_CFA_val_offset:
1722 regno = insn->u.ri.reg;
1723 offset = insn->u.ri.offset / DWARF2_CIE_DATA_ALIGNMENT;
1724 if (offset < 0)
1725 {
1726 out_one (DW_CFA_val_offset_sf);
1727 out_uleb128 (regno);
1728 out_sleb128 (offset);
1729 }
1730 else
1731 {
1732 out_one (DW_CFA_val_offset);
1733 out_uleb128 (regno);
1734 out_uleb128 (offset);
1735 }
1736 break;
1737
a4447b93
RH
1738 case DW_CFA_register:
1739 out_one (DW_CFA_register);
1740 out_uleb128 (insn->u.rr.reg1);
1741 out_uleb128 (insn->u.rr.reg2);
39b82151
ML
1742 break;
1743
2be24b54
ML
1744 case DW_CFA_remember_state:
1745 case DW_CFA_restore_state:
2be24b54 1746 out_one (insn->insn);
54cfded0
AM
1747 break;
1748
364b6d8b
JJ
1749 case DW_CFA_GNU_window_save:
1750 out_one (DW_CFA_GNU_window_save);
1751 break;
1752
cdfbf930
RH
1753 case CFI_escape:
1754 {
1755 struct cfi_escape_data *e;
1756 for (e = insn->u.esc; e ; e = e->next)
1757 emit_expr (&e->exp, 1);
1758 break;
1759 }
1760
f1c4cc75
RH
1761 case CFI_val_encoded_addr:
1762 {
83e12deb 1763 unsigned encoding = insn->u.ea.encoding;
2f0c68f2 1764 offsetT enc_size;
f1c4cc75
RH
1765
1766 if (encoding == DW_EH_PE_omit)
1767 break;
1768 out_one (DW_CFA_val_expression);
1769 out_uleb128 (insn->u.ea.reg);
1770
83e12deb 1771 switch (encoding & 0x7)
f1c4cc75
RH
1772 {
1773 case DW_EH_PE_absptr:
2f0c68f2 1774 enc_size = DWARF2_ADDR_SIZE (stdoutput);
f1c4cc75
RH
1775 break;
1776 case DW_EH_PE_udata2:
2f0c68f2 1777 enc_size = 2;
f1c4cc75
RH
1778 break;
1779 case DW_EH_PE_udata4:
2f0c68f2 1780 enc_size = 4;
f1c4cc75
RH
1781 break;
1782 case DW_EH_PE_udata8:
2f0c68f2 1783 enc_size = 8;
f1c4cc75
RH
1784 break;
1785 default:
1786 abort ();
1787 }
1788
1789 /* If the user has requested absolute encoding,
1790 then use the smaller DW_OP_addr encoding. */
1791 if (insn->u.ea.encoding == DW_EH_PE_absptr)
1792 {
2f0c68f2 1793 out_uleb128 (1 + enc_size);
f1c4cc75
RH
1794 out_one (DW_OP_addr);
1795 }
1796 else
1797 {
2f0c68f2 1798 out_uleb128 (1 + 1 + enc_size);
f1c4cc75
RH
1799 out_one (DW_OP_GNU_encoded_addr);
1800 out_one (encoding);
1801
1802 if ((encoding & 0x70) == DW_EH_PE_pcrel)
1803 {
1804#if CFI_DIFF_EXPR_OK
1805 insn->u.ea.exp.X_op = O_subtract;
1806 insn->u.ea.exp.X_op_symbol = symbol_temp_new_now ();
1807#elif defined (tc_cfi_emit_pcrel_expr)
2f0c68f2 1808 tc_cfi_emit_pcrel_expr (&insn->u.ea.exp, enc_size);
f1c4cc75
RH
1809 break;
1810#else
1811 abort ();
1812#endif
1813 }
1814 }
2f0c68f2 1815 emit_expr (&insn->u.ea.exp, enc_size);
f1c4cc75
RH
1816 }
1817 break;
72b016b4 1818
69602580
JB
1819 case CFI_label:
1820 colon (insn->u.sym_name);
1821 break;
1822
54cfded0 1823 default:
a4447b93 1824 abort ();
54cfded0 1825 }
54cfded0
AM
1826}
1827
1828static void
38462edf 1829output_cie (struct cie_entry *cie, bfd_boolean eh_frame, int align)
54cfded0 1830{
a4447b93 1831 symbolS *after_size_address, *end_address;
7c0295b1 1832 expressionS exp;
a4447b93 1833 struct cfi_insn_data *i;
9b8ae42e 1834 offsetT augmentation_size;
8c9b70b1 1835 int enc;
38462edf 1836 enum dwarf2_format fmt = DWARF2_FORMAT (now_seg);
a4447b93
RH
1837
1838 cie->start_address = symbol_temp_new_now ();
1839 after_size_address = symbol_temp_make ();
1840 end_address = symbol_temp_make ();
1841
1842 exp.X_op = O_subtract;
1843 exp.X_add_symbol = end_address;
1844 exp.X_op_symbol = after_size_address;
1845 exp.X_add_number = 0;
1846
38462edf
JJ
1847 if (eh_frame || fmt == dwarf2_format_32bit)
1848 emit_expr (&exp, 4); /* Length. */
1849 else
1850 {
1851 if (fmt == dwarf2_format_64bit)
1852 out_four (-1);
1853 emit_expr (&exp, 8); /* Length. */
1854 }
a4447b93 1855 symbol_set_value_now (after_size_address);
38462edf
JJ
1856 if (eh_frame)
1857 out_four (0); /* CIE id. */
1858 else
1859 {
1860 out_four (-1); /* CIE id. */
1861 if (fmt != dwarf2_format_32bit)
1862 out_four (-1);
1863 }
66f8b2cb 1864 out_one (flag_dwarf_cie_version); /* Version. */
38462edf
JJ
1865 if (eh_frame)
1866 {
1867 out_one ('z'); /* Augmentation. */
1868 if (cie->per_encoding != DW_EH_PE_omit)
1869 out_one ('P');
1870 if (cie->lsda_encoding != DW_EH_PE_omit)
1871 out_one ('L');
1872 out_one ('R');
09038062 1873#ifdef tc_output_cie_extra
c6803386 1874 tc_output_cie_extra (cie);
09038062 1875#endif
38462edf 1876 }
d905c788
TS
1877 if (cie->signal_frame)
1878 out_one ('S');
a4447b93 1879 out_one (0);
66f8b2cb
AB
1880 if (flag_dwarf_cie_version >= 4)
1881 {
1882 /* For now we are assuming a flat address space with 4 or 8 byte
1883 addresses. */
1884 int address_size = dwarf2_format_32bit ? 4 : 8;
1885 out_one (address_size); /* Address size. */
1886 out_one (0); /* Segment size. */
1887 }
289040ca
NC
1888 out_uleb128 (DWARF2_LINE_MIN_INSN_LENGTH); /* Code alignment. */
1889 out_sleb128 (DWARF2_CIE_DATA_ALIGNMENT); /* Data alignment. */
66f8b2cb 1890 if (flag_dwarf_cie_version == 1) /* Return column. */
22eb4a06
AB
1891 {
1892 if ((cie->return_column & 0xff) != cie->return_column)
1893 as_bad (_("return column number %d overflows in CIE version 1"),
1894 cie->return_column);
1895 out_one (cie->return_column);
1896 }
0da76f83
NC
1897 else
1898 out_uleb128 (cie->return_column);
38462edf
JJ
1899 if (eh_frame)
1900 {
1901 augmentation_size = 1 + (cie->lsda_encoding != DW_EH_PE_omit);
1902 if (cie->per_encoding != DW_EH_PE_omit)
1903 augmentation_size += 1 + encoding_size (cie->per_encoding);
1904 out_uleb128 (augmentation_size); /* Augmentation size. */
4e4e1355 1905
2f0c68f2 1906 emit_expr_encoded (&cie->personality, cie->per_encoding, TRUE);
4e4e1355
TS
1907
1908 if (cie->lsda_encoding != DW_EH_PE_omit)
1909 out_one (cie->lsda_encoding);
9b8ae42e 1910 }
8c9b70b1
RH
1911
1912 switch (DWARF2_FDE_RELOC_SIZE)
1913 {
1914 case 2:
1915 enc = DW_EH_PE_sdata2;
1916 break;
1917 case 4:
1918 enc = DW_EH_PE_sdata4;
1919 break;
1920 case 8:
1921 enc = DW_EH_PE_sdata8;
1922 break;
1923 default:
1924 abort ();
1925 }
3dd24306 1926#if CFI_DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr
8c9b70b1 1927 enc |= DW_EH_PE_pcrel;
364b6d8b 1928#endif
2f0c68f2
CM
1929#ifdef DWARF2_FDE_RELOC_ENCODING
1930 /* Allow target to override encoding. */
1931 enc = DWARF2_FDE_RELOC_ENCODING (enc);
1932#endif
1933 cie->fde_encoding = enc;
38462edf
JJ
1934 if (eh_frame)
1935 out_one (enc);
a4447b93
RH
1936
1937 if (cie->first)
72b016b4
NC
1938 {
1939 for (i = cie->first; i != cie->last; i = i->next)
83e12deb 1940 {
6303c4ae 1941 if (CUR_SEG (i) != CUR_SEG (cie))
72b016b4
NC
1942 continue;
1943 output_cfi_insn (i);
1944 }
1945 }
a4447b93 1946
38462edf 1947 frag_align (align, DW_CFA_nop, 0);
a4447b93
RH
1948 symbol_set_value_now (end_address);
1949}
54cfded0 1950
a4447b93
RH
1951static void
1952output_fde (struct fde_entry *fde, struct cie_entry *cie,
38462edf
JJ
1953 bfd_boolean eh_frame, struct cfi_insn_data *first,
1954 int align)
a4447b93
RH
1955{
1956 symbolS *after_size_address, *end_address;
1957 expressionS exp;
9b8ae42e 1958 offsetT augmentation_size;
38462edf 1959 enum dwarf2_format fmt = DWARF2_FORMAT (now_seg);
ea0de82e
AM
1960 unsigned int offset_size;
1961 unsigned int addr_size;
54cfded0 1962
a4447b93
RH
1963 after_size_address = symbol_temp_make ();
1964 end_address = symbol_temp_make ();
54cfded0 1965
a4447b93
RH
1966 exp.X_op = O_subtract;
1967 exp.X_add_symbol = end_address;
1968 exp.X_op_symbol = after_size_address;
1969 exp.X_add_number = 0;
38462edf
JJ
1970 if (eh_frame || fmt == dwarf2_format_32bit)
1971 offset_size = 4;
1972 else
1973 {
1974 if (fmt == dwarf2_format_64bit)
1975 out_four (-1);
1976 offset_size = 8;
1977 }
1978 emit_expr (&exp, offset_size); /* Length. */
a4447b93 1979 symbol_set_value_now (after_size_address);
54cfded0 1980
38462edf
JJ
1981 if (eh_frame)
1982 {
3251495b 1983 exp.X_op = O_subtract;
38462edf
JJ
1984 exp.X_add_symbol = after_size_address;
1985 exp.X_op_symbol = cie->start_address;
3251495b
RH
1986 exp.X_add_number = 0;
1987 emit_expr (&exp, offset_size); /* CIE offset. */
38462edf
JJ
1988 }
1989 else
1990 {
3251495b 1991 TC_DWARF2_EMIT_OFFSET (cie->start_address, offset_size);
38462edf 1992 }
364b6d8b 1993
2f0c68f2 1994 exp.X_op = O_symbol;
38462edf
JJ
1995 if (eh_frame)
1996 {
2f0c68f2
CM
1997 bfd_reloc_code_real_type code
1998 = tc_cfi_reloc_for_encoding (cie->fde_encoding);
ea0de82e 1999 addr_size = DWARF2_FDE_RELOC_SIZE;
2f0c68f2
CM
2000 if (code != BFD_RELOC_NONE)
2001 {
2002 reloc_howto_type *howto = bfd_reloc_type_lookup (stdoutput, code);
ea0de82e 2003 char *p = frag_more (addr_size);
86b9fea1 2004 gas_assert (addr_size == (unsigned) howto->bitsize / 8);
ea0de82e
AM
2005 md_number_to_chars (p, 0, addr_size);
2006 fix_new (frag_now, p - frag_now->fr_literal, addr_size,
2007 fde->start_address, 0, howto->pc_relative, code);
2f0c68f2
CM
2008 }
2009 else
2010 {
2011 exp.X_op = O_subtract;
2012 exp.X_add_number = 0;
3dd24306 2013#if CFI_DIFF_EXPR_OK
2f0c68f2
CM
2014 exp.X_add_symbol = fde->start_address;
2015 exp.X_op_symbol = symbol_temp_new_now ();
ea0de82e 2016 emit_expr (&exp, addr_size); /* Code offset. */
364b6d8b 2017#else
2f0c68f2
CM
2018 exp.X_op = O_symbol;
2019 exp.X_add_symbol = fde->start_address;
2020
2021#if defined(tc_cfi_emit_pcrel_expr)
ea0de82e 2022 tc_cfi_emit_pcrel_expr (&exp, addr_size); /* Code offset. */
364b6d8b 2023#else
ea0de82e 2024 emit_expr (&exp, addr_size); /* Code offset. */
364b6d8b 2025#endif
364b6d8b 2026#endif
2f0c68f2 2027 }
38462edf
JJ
2028 }
2029 else
2030 {
3251495b 2031 exp.X_add_number = 0;
2f0c68f2 2032 exp.X_add_symbol = fde->start_address;
38462edf
JJ
2033 addr_size = DWARF2_ADDR_SIZE (stdoutput);
2034 emit_expr (&exp, addr_size);
2035 }
54cfded0 2036
38462edf 2037 exp.X_op = O_subtract;
a4447b93 2038 exp.X_add_symbol = fde->end_address;
289040ca 2039 exp.X_op_symbol = fde->start_address; /* Code length. */
3251495b 2040 exp.X_add_number = 0;
38462edf 2041 emit_expr (&exp, addr_size);
54cfded0 2042
9b8ae42e 2043 augmentation_size = encoding_size (fde->lsda_encoding);
38462edf
JJ
2044 if (eh_frame)
2045 out_uleb128 (augmentation_size); /* Augmentation size. */
9b8ae42e 2046
2f0c68f2 2047 emit_expr_encoded (&fde->lsda, cie->lsda_encoding, FALSE);
39b82151 2048
a4447b93 2049 for (; first; first = first->next)
6303c4ae 2050 if (CUR_SEG (first) == CUR_SEG (fde))
67ed7401 2051 output_cfi_insn (first);
39b82151 2052
4df6ce47 2053 frag_align (align, DW_CFA_nop, 0);
a4447b93
RH
2054 symbol_set_value_now (end_address);
2055}
2056
2057static struct cie_entry *
38462edf
JJ
2058select_cie_for_fde (struct fde_entry *fde, bfd_boolean eh_frame,
2059 struct cfi_insn_data **pfirst, int align)
a4447b93
RH
2060{
2061 struct cfi_insn_data *i, *j;
2062 struct cie_entry *cie;
2063
2064 for (cie = cie_root; cie; cie = cie->next)
39b82151 2065 {
6303c4ae 2066 if (CUR_SEG (cie) != CUR_SEG (fde))
67ed7401 2067 continue;
09038062
ST
2068#ifdef tc_cie_fde_equivalent_extra
2069 if (!tc_cie_fde_equivalent_extra (cie, fde))
2070 continue;
2071#endif
67ed7401 2072 if (cie->return_column != fde->return_column
9b8ae42e
JJ
2073 || cie->signal_frame != fde->signal_frame
2074 || cie->per_encoding != fde->per_encoding
2075 || cie->lsda_encoding != fde->lsda_encoding)
a4447b93 2076 continue;
9b8ae42e
JJ
2077 if (cie->per_encoding != DW_EH_PE_omit)
2078 {
2079 if (cie->personality.X_op != fde->personality.X_op
9e1a8675
AM
2080 || (cie->personality.X_add_number
2081 != fde->personality.X_add_number))
9b8ae42e
JJ
2082 continue;
2083 switch (cie->personality.X_op)
2084 {
2085 case O_constant:
2086 if (cie->personality.X_unsigned != fde->personality.X_unsigned)
2087 continue;
2088 break;
2089 case O_symbol:
2090 if (cie->personality.X_add_symbol
2091 != fde->personality.X_add_symbol)
2092 continue;
2093 break;
2094 default:
2095 abort ();
2096 }
2097 }
a4447b93
RH
2098 for (i = cie->first, j = fde->data;
2099 i != cie->last && j != NULL;
2100 i = i->next, j = j->next)
39b82151 2101 {
a4447b93
RH
2102 if (i->insn != j->insn)
2103 goto fail;
2104 switch (i->insn)
2105 {
2106 case DW_CFA_advance_loc:
289040ca
NC
2107 case DW_CFA_remember_state:
2108 /* We reached the first advance/remember in the FDE,
2109 but did not reach the end of the CIE list. */
a4447b93
RH
2110 goto fail;
2111
2112 case DW_CFA_offset:
2113 case DW_CFA_def_cfa:
2114 if (i->u.ri.reg != j->u.ri.reg)
2115 goto fail;
2116 if (i->u.ri.offset != j->u.ri.offset)
2117 goto fail;
2118 break;
2119
2120 case DW_CFA_register:
2121 if (i->u.rr.reg1 != j->u.rr.reg1)
2122 goto fail;
2123 if (i->u.rr.reg2 != j->u.rr.reg2)
2124 goto fail;
2125 break;
2126
2127 case DW_CFA_def_cfa_register:
2be24b54
ML
2128 case DW_CFA_restore:
2129 case DW_CFA_undefined:
2130 case DW_CFA_same_value:
a4447b93
RH
2131 if (i->u.r != j->u.r)
2132 goto fail;
2133 break;
2134
2135 case DW_CFA_def_cfa_offset:
2136 if (i->u.i != j->u.i)
2137 goto fail;
2138 break;
2139
cdfbf930 2140 case CFI_escape:
f1c4cc75 2141 case CFI_val_encoded_addr:
73e76108 2142 case CFI_label:
cdfbf930
RH
2143 /* Don't bother matching these for now. */
2144 goto fail;
2145
a4447b93
RH
2146 default:
2147 abort ();
2148 }
39b82151 2149 }
a4447b93
RH
2150
2151 /* Success if we reached the end of the CIE list, and we've either
289040ca
NC
2152 run out of FDE entries or we've encountered an advance,
2153 remember, or escape. */
e9fad691
AM
2154 if (i == cie->last
2155 && (!j
2156 || j->insn == DW_CFA_advance_loc
289040ca 2157 || j->insn == DW_CFA_remember_state
f1c4cc75 2158 || j->insn == CFI_escape
73e76108
JB
2159 || j->insn == CFI_val_encoded_addr
2160 || j->insn == CFI_label))
39b82151 2161 {
a4447b93
RH
2162 *pfirst = j;
2163 return cie;
39b82151
ML
2164 }
2165
a4447b93 2166 fail:;
54cfded0
AM
2167 }
2168
add39d23 2169 cie = XNEW (struct cie_entry);
a4447b93
RH
2170 cie->next = cie_root;
2171 cie_root = cie;
6303c4ae 2172 SET_CUR_SEG (cie, CUR_SEG (fde));
a4447b93 2173 cie->return_column = fde->return_column;
63752a75 2174 cie->signal_frame = fde->signal_frame;
9b8ae42e
JJ
2175 cie->per_encoding = fde->per_encoding;
2176 cie->lsda_encoding = fde->lsda_encoding;
2177 cie->personality = fde->personality;
a4447b93 2178 cie->first = fde->data;
09038062
ST
2179#ifdef tc_cie_entry_init_extra
2180 tc_cie_entry_init_extra (cie, fde)
2181#endif
54cfded0 2182
a4447b93 2183 for (i = cie->first; i ; i = i->next)
e9fad691 2184 if (i->insn == DW_CFA_advance_loc
289040ca 2185 || i->insn == DW_CFA_remember_state
f1c4cc75 2186 || i->insn == CFI_escape
69602580
JB
2187 || i->insn == CFI_val_encoded_addr
2188 || i->insn == CFI_label)
a4447b93 2189 break;
54cfded0 2190
a4447b93
RH
2191 cie->last = i;
2192 *pfirst = i;
38462edf
JJ
2193
2194 output_cie (cie, eh_frame, align);
54cfded0 2195
a4447b93 2196 return cie;
54cfded0
AM
2197}
2198
38462edf
JJ
2199#ifdef md_reg_eh_frame_to_debug_frame
2200static void
6303c4ae 2201cfi_change_reg_numbers (struct cfi_insn_data *insn, segT ccseg)
38462edf
JJ
2202{
2203 for (; insn; insn = insn->next)
72b016b4 2204 {
6303c4ae 2205 if (CUR_SEG (insn) != ccseg)
83e12deb 2206 continue;
72b016b4
NC
2207 switch (insn->insn)
2208 {
2209 case DW_CFA_advance_loc:
2210 case DW_CFA_def_cfa_offset:
2211 case DW_CFA_remember_state:
2212 case DW_CFA_restore_state:
2213 case DW_CFA_GNU_window_save:
2214 case CFI_escape:
73e76108 2215 case CFI_label:
72b016b4 2216 break;
38462edf 2217
72b016b4
NC
2218 case DW_CFA_def_cfa:
2219 case DW_CFA_offset:
2220 insn->u.ri.reg = md_reg_eh_frame_to_debug_frame (insn->u.ri.reg);
2221 break;
38462edf 2222
72b016b4
NC
2223 case DW_CFA_def_cfa_register:
2224 case DW_CFA_undefined:
2225 case DW_CFA_same_value:
2226 case DW_CFA_restore:
2227 insn->u.r = md_reg_eh_frame_to_debug_frame (insn->u.r);
2228 break;
38462edf 2229
72b016b4
NC
2230 case DW_CFA_register:
2231 insn->u.rr.reg1 = md_reg_eh_frame_to_debug_frame (insn->u.rr.reg1);
2232 insn->u.rr.reg2 = md_reg_eh_frame_to_debug_frame (insn->u.rr.reg2);
2233 break;
38462edf 2234
72b016b4
NC
2235 case CFI_val_encoded_addr:
2236 insn->u.ea.reg = md_reg_eh_frame_to_debug_frame (insn->u.ea.reg);
2237 break;
38462edf 2238
72b016b4
NC
2239 default:
2240 abort ();
2241 }
2242 }
38462edf
JJ
2243}
2244#else
72b016b4 2245#define cfi_change_reg_numbers(insn, cseg) do { } while (0)
38462edf
JJ
2246#endif
2247
2f0c68f2
CM
2248#if SUPPORT_COMPACT_EH
2249static void
2250cfi_emit_eh_header (symbolS *sym, bfd_vma addend)
72b016b4 2251{
2f0c68f2 2252 expressionS exp;
72b016b4 2253
2f0c68f2
CM
2254 exp.X_add_number = addend;
2255 exp.X_add_symbol = sym;
2256 emit_expr_encoded (&exp, DW_EH_PE_sdata4 | DW_EH_PE_pcrel, FALSE);
2257}
72b016b4 2258
2f0c68f2
CM
2259static void
2260output_eh_header (struct fde_entry *fde)
2261{
2262 char *p;
2263 bfd_vma addend;
2264
2265 if (fde->eh_header_type == EH_COMPACT_INLINE)
2266 addend = 0;
2267 else
2268 addend = 1;
2269
2270 cfi_emit_eh_header (fde->start_address, addend);
2271
2272 if (fde->eh_header_type == EH_COMPACT_INLINE)
2273 {
2274 p = frag_more (4);
2275 /* Inline entries always use PR1. */
2276 *(p++) = 1;
2277 memcpy(p, fde->eh_data, 3);
6303c4ae
AM
2278 }
2279 else
2280 {
2f0c68f2
CM
2281 if (fde->eh_header_type == EH_COMPACT_LEGACY)
2282 addend = 1;
2283 else if (fde->eh_header_type == EH_COMPACT_OUTLINE
2284 || fde->eh_header_type == EH_COMPACT_OUTLINE_DONE)
2285 addend = 0;
2286 else
2287 abort ();
2288 cfi_emit_eh_header (fde->eh_loc, addend);
6303c4ae 2289 }
72b016b4 2290}
2f0c68f2 2291#endif
72b016b4 2292
54cfded0 2293void
a4447b93 2294cfi_finish (void)
54cfded0 2295{
72b016b4
NC
2296 struct cie_entry *cie, *cie_next;
2297 segT cfi_seg, ccseg;
a4447b93 2298 struct fde_entry *fde;
72b016b4
NC
2299 struct cfi_insn_data *first;
2300 int save_flag_traditional_format, seek_next_seg;
54cfded0 2301
a4447b93
RH
2302 if (all_fde_data == 0)
2303 return;
54cfded0 2304
bd5608dc 2305 cfi_sections_set = TRUE;
2f0c68f2
CM
2306 if ((all_cfi_sections & CFI_EMIT_eh_frame) != 0
2307 || (all_cfi_sections & CFI_EMIT_eh_frame_compact) != 0)
38462edf 2308 {
38462edf
JJ
2309 /* Make sure check_eh_frame doesn't do anything with our output. */
2310 save_flag_traditional_format = flag_traditional_format;
2311 flag_traditional_format = 1;
eafbc43f 2312
2f0c68f2 2313 if (!EH_FRAME_LINKONCE)
6303c4ae
AM
2314 {
2315 /* Open .eh_frame section. */
2316 cfi_seg = get_cfi_seg (NULL, ".eh_frame",
2317 (SEC_ALLOC | SEC_LOAD | SEC_DATA
2318 | DWARF2_EH_FRAME_READ_ONLY),
2319 EH_FRAME_ALIGNMENT);
67ed7401 2320#ifdef md_fix_up_eh_frame
6303c4ae 2321 md_fix_up_eh_frame (cfi_seg);
67ed7401 2322#else
6303c4ae 2323 (void) cfi_seg;
67ed7401 2324#endif
6303c4ae 2325 }
67ed7401 2326
72b016b4 2327 do
83e12deb 2328 {
72b016b4 2329 ccseg = NULL;
72b016b4 2330 seek_next_seg = 0;
67ed7401 2331
72b016b4 2332 for (cie = cie_root; cie; cie = cie_next)
38462edf 2333 {
72b016b4
NC
2334 cie_next = cie->next;
2335 free ((void *) cie);
38462edf 2336 }
72b016b4 2337 cie_root = NULL;
38462edf 2338
72b016b4
NC
2339 for (fde = all_fde_data; fde ; fde = fde->next)
2340 {
2f0c68f2
CM
2341 if ((fde->sections & CFI_EMIT_eh_frame) == 0
2342 && (fde->sections & CFI_EMIT_eh_frame_compact) == 0)
2343 continue;
2344
2345#if SUPPORT_COMPACT_EH
2346 /* Emit a LEGACY format header if we have processed all
9e1a8675 2347 of the .cfi directives without encountering either inline or
2f0c68f2
CM
2348 out-of-line compact unwinding opcodes. */
2349 if (fde->eh_header_type == EH_COMPACT_HAS_LSDA
2350 || fde->eh_header_type == EH_COMPACT_UNKNOWN)
2351 fde->eh_header_type = EH_COMPACT_LEGACY;
2352
2353 if (fde->eh_header_type != EH_COMPACT_LEGACY)
2354 continue;
2355#endif
2356 if (EH_FRAME_LINKONCE)
6303c4ae
AM
2357 {
2358 if (HANDLED (fde))
2359 continue;
2360 if (seek_next_seg && CUR_SEG (fde) != ccseg)
2361 {
2362 seek_next_seg = 2;
2363 continue;
2364 }
2365 if (!seek_next_seg)
2366 {
2367 ccseg = CUR_SEG (fde);
2368 /* Open .eh_frame section. */
2369 cfi_seg = get_cfi_seg (ccseg, ".eh_frame",
2370 (SEC_ALLOC | SEC_LOAD | SEC_DATA
2371 | DWARF2_EH_FRAME_READ_ONLY),
2372 EH_FRAME_ALIGNMENT);
72b016b4 2373#ifdef md_fix_up_eh_frame
6303c4ae 2374 md_fix_up_eh_frame (cfi_seg);
67ed7401 2375#else
6303c4ae 2376 (void) cfi_seg;
72b016b4 2377#endif
6303c4ae
AM
2378 seek_next_seg = 1;
2379 }
2380 SET_HANDLED (fde, 1);
72b016b4 2381 }
72b016b4
NC
2382
2383 if (fde->end_address == NULL)
2384 {
9e1a8675
AM
2385 as_bad (_("open CFI at the end of file; "
2386 "missing .cfi_endproc directive"));
72b016b4
NC
2387 fde->end_address = fde->start_address;
2388 }
2389
2390 cie = select_cie_for_fde (fde, TRUE, &first, 2);
2f0c68f2 2391 fde->eh_loc = symbol_temp_new_now ();
72b016b4
NC
2392 output_fde (fde, cie, TRUE, first,
2393 fde->next == NULL ? EH_FRAME_ALIGNMENT : 2);
2394 }
38462edf 2395 }
2f0c68f2 2396 while (EH_FRAME_LINKONCE && seek_next_seg == 2);
72b016b4 2397
2f0c68f2 2398 if (EH_FRAME_LINKONCE)
6303c4ae
AM
2399 for (fde = all_fde_data; fde ; fde = fde->next)
2400 SET_HANDLED (fde, 0);
38462edf 2401
2f0c68f2
CM
2402#if SUPPORT_COMPACT_EH
2403 if (compact_eh)
2404 {
2405 /* Create remaining out of line table entries. */
2406 do
2407 {
2408 ccseg = NULL;
2409 seek_next_seg = 0;
2410
2411 for (fde = all_fde_data; fde ; fde = fde->next)
2412 {
2413 if ((fde->sections & CFI_EMIT_eh_frame) == 0
2414 && (fde->sections & CFI_EMIT_eh_frame_compact) == 0)
2415 continue;
2416
2417 if (fde->eh_header_type != EH_COMPACT_OUTLINE)
2418 continue;
2419 if (HANDLED (fde))
2420 continue;
2421 if (seek_next_seg && CUR_SEG (fde) != ccseg)
2422 {
2423 seek_next_seg = 2;
2424 continue;
2425 }
2426 if (!seek_next_seg)
2427 {
2428 ccseg = CUR_SEG (fde);
2429 /* Open .gnu_extab section. */
2430 get_cfi_seg (ccseg, ".gnu_extab",
2431 (SEC_ALLOC | SEC_LOAD | SEC_DATA
2432 | DWARF2_EH_FRAME_READ_ONLY),
2433 1);
2434 seek_next_seg = 1;
2435 }
2436 SET_HANDLED (fde, 1);
2437
2438 frag_align (1, 0, 0);
2439 record_alignment (now_seg, 1);
2440 output_compact_unwind_data (fde, 1);
2441 }
2442 }
2443 while (EH_FRAME_LINKONCE && seek_next_seg == 2);
2444
2445 for (fde = all_fde_data; fde ; fde = fde->next)
2446 SET_HANDLED (fde, 0);
2447
2448 /* Create index table fragments. */
2449 do
2450 {
2451 ccseg = NULL;
2452 seek_next_seg = 0;
2453
2454 for (fde = all_fde_data; fde ; fde = fde->next)
2455 {
2456 if ((fde->sections & CFI_EMIT_eh_frame) == 0
2457 && (fde->sections & CFI_EMIT_eh_frame_compact) == 0)
2458 continue;
2459
2460 if (HANDLED (fde))
2461 continue;
2462 if (seek_next_seg && CUR_SEG (fde) != ccseg)
2463 {
2464 seek_next_seg = 2;
2465 continue;
2466 }
2467 if (!seek_next_seg)
2468 {
2469 ccseg = CUR_SEG (fde);
2470 /* Open .eh_frame_entry section. */
2471 cfi_seg = get_cfi_seg (ccseg, ".eh_frame_entry",
2472 (SEC_ALLOC | SEC_LOAD | SEC_DATA
2473 | DWARF2_EH_FRAME_READ_ONLY),
2474 2);
2475 seek_next_seg = 1;
2476 }
2477 SET_HANDLED (fde, 1);
2478
2479 output_eh_header (fde);
2480 }
2481 }
2482 while (seek_next_seg == 2);
2483
2484 for (fde = all_fde_data; fde ; fde = fde->next)
2485 SET_HANDLED (fde, 0);
2486 }
2487#endif /* SUPPORT_COMPACT_EH */
2488
38462edf
JJ
2489 flag_traditional_format = save_flag_traditional_format;
2490 }
2491
bd5608dc 2492 cfi_sections_set = TRUE;
2f0c68f2 2493 if ((all_cfi_sections & CFI_EMIT_debug_frame) != 0)
a4447b93 2494 {
38462edf 2495 int alignment = ffs (DWARF2_ADDR_SIZE (stdoutput)) - 1;
a4447b93 2496
6303c4ae
AM
2497 if (!SUPPORT_FRAME_LINKONCE)
2498 get_cfi_seg (NULL, ".debug_frame",
2499 SEC_READONLY | SEC_DEBUGGING,
2500 alignment);
2501
72b016b4 2502 do
83e12deb 2503 {
72b016b4 2504 ccseg = NULL;
72b016b4 2505 seek_next_seg = 0;
67ed7401 2506
72b016b4 2507 for (cie = cie_root; cie; cie = cie_next)
38462edf 2508 {
72b016b4
NC
2509 cie_next = cie->next;
2510 free ((void *) cie);
38462edf 2511 }
72b016b4 2512 cie_root = NULL;
38462edf 2513
72b016b4
NC
2514 for (fde = all_fde_data; fde ; fde = fde->next)
2515 {
2f0c68f2
CM
2516 if ((fde->sections & CFI_EMIT_debug_frame) == 0)
2517 continue;
2518
6303c4ae
AM
2519 if (SUPPORT_FRAME_LINKONCE)
2520 {
2521 if (HANDLED (fde))
2522 continue;
2523 if (seek_next_seg && CUR_SEG (fde) != ccseg)
2524 {
2525 seek_next_seg = 2;
2526 continue;
2527 }
2528 if (!seek_next_seg)
2529 {
2530 ccseg = CUR_SEG (fde);
2531 /* Open .debug_frame section. */
2532 get_cfi_seg (ccseg, ".debug_frame",
2533 SEC_READONLY | SEC_DEBUGGING,
2534 alignment);
2535 seek_next_seg = 1;
2536 }
2537 SET_HANDLED (fde, 1);
72b016b4 2538 }
72b016b4
NC
2539 if (fde->end_address == NULL)
2540 {
9e1a8675
AM
2541 as_bad (_("open CFI at the end of file; "
2542 "missing .cfi_endproc directive"));
72b016b4
NC
2543 fde->end_address = fde->start_address;
2544 }
2545
2546 fde->per_encoding = DW_EH_PE_omit;
2547 fde->lsda_encoding = DW_EH_PE_omit;
2548 cfi_change_reg_numbers (fde->data, ccseg);
2549 cie = select_cie_for_fde (fde, FALSE, &first, alignment);
2550 output_fde (fde, cie, FALSE, first, alignment);
2551 }
38462edf 2552 }
67ed7401 2553 while (SUPPORT_FRAME_LINKONCE && seek_next_seg == 2);
72b016b4 2554
6303c4ae
AM
2555 if (SUPPORT_FRAME_LINKONCE)
2556 for (fde = all_fde_data; fde ; fde = fde->next)
2557 SET_HANDLED (fde, 0);
38462edf 2558 }
54cfded0 2559}
0a7b15ff
JB
2560
2561#else /* TARGET_USE_CFIPOP */
d58a1929 2562
5ff2bd08 2563/* Emit an intelligible error message for missing support. */
d58a1929
RH
2564
2565static void
2566dot_cfi_dummy (int ignored ATTRIBUTE_UNUSED)
2567{
2568 as_bad (_("CFI is not supported for this target"));
2569 ignore_rest_of_line ();
2570}
2571
2572const pseudo_typeS cfi_pseudo_table[] =
2573 {
2574 { "cfi_sections", dot_cfi_dummy, 0 },
2575 { "cfi_startproc", dot_cfi_dummy, 0 },
2576 { "cfi_endproc", dot_cfi_dummy, 0 },
2f0c68f2 2577 { "cfi_fde_data", dot_cfi_dummy, 0 },
d58a1929
RH
2578 { "cfi_def_cfa", dot_cfi_dummy, 0 },
2579 { "cfi_def_cfa_register", dot_cfi_dummy, 0 },
2580 { "cfi_def_cfa_offset", dot_cfi_dummy, 0 },
2581 { "cfi_adjust_cfa_offset", dot_cfi_dummy, 0 },
2582 { "cfi_offset", dot_cfi_dummy, 0 },
2583 { "cfi_rel_offset", dot_cfi_dummy, 0 },
2584 { "cfi_register", dot_cfi_dummy, 0 },
2585 { "cfi_return_column", dot_cfi_dummy, 0 },
2586 { "cfi_restore", dot_cfi_dummy, 0 },
2587 { "cfi_undefined", dot_cfi_dummy, 0 },
2588 { "cfi_same_value", dot_cfi_dummy, 0 },
2589 { "cfi_remember_state", dot_cfi_dummy, 0 },
2590 { "cfi_restore_state", dot_cfi_dummy, 0 },
2591 { "cfi_window_save", dot_cfi_dummy, 0 },
2592 { "cfi_escape", dot_cfi_dummy, 0 },
2593 { "cfi_signal_frame", dot_cfi_dummy, 0 },
2594 { "cfi_personality", dot_cfi_dummy, 0 },
2f0c68f2 2595 { "cfi_personality_id", dot_cfi_dummy, 0 },
d58a1929
RH
2596 { "cfi_lsda", dot_cfi_dummy, 0 },
2597 { "cfi_val_encoded_addr", dot_cfi_dummy, 0 },
73e76108 2598 { "cfi_label", dot_cfi_dummy, 0 },
2f0c68f2 2599 { "cfi_inline_lsda", dot_cfi_dummy, 0 },
084303b8 2600 { "cfi_val_offset", dot_cfi_dummy, 0 },
d58a1929
RH
2601 { NULL, NULL, 0 }
2602 };
2603
0a7b15ff
JB
2604void
2605cfi_finish (void)
2606{
2607}
2608#endif /* TARGET_USE_CFIPOP */
This page took 0.858298 seconds and 4 git commands to generate.