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