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