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