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