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