gas: free allocated symbol name in .cfi_label handling
[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);
92e18d93 1189 free (name);
69602580
JB
1190
1191 demand_empty_rest_of_line ();
1192}
1193
38462edf
JJ
1194static void
1195dot_cfi_sections (int ignored ATTRIBUTE_UNUSED)
1196{
1197 int sections = 0;
1198
1199 SKIP_WHITESPACE ();
d02603dc 1200 if (is_name_beginner (*input_line_pointer) || *input_line_pointer == '"')
38462edf
JJ
1201 while (1)
1202 {
d02603dc 1203 char * saved_ilp;
38462edf
JJ
1204 char *name, c;
1205
d02603dc
NC
1206 saved_ilp = input_line_pointer;
1207 c = get_symbol_name (& name);
38462edf 1208
72b016b4
NC
1209 if (strncmp (name, ".eh_frame", sizeof ".eh_frame") == 0
1210 && name[9] != '_')
38462edf 1211 sections |= CFI_EMIT_eh_frame;
72b016b4 1212 else if (strncmp (name, ".debug_frame", sizeof ".debug_frame") == 0)
38462edf 1213 sections |= CFI_EMIT_debug_frame;
2f0c68f2
CM
1214#if SUPPORT_COMPACT_EH
1215 else if (strncmp (name, ".eh_frame_entry", sizeof ".eh_frame_entry") == 0)
1216 {
1217 compact_eh = TRUE;
1218 sections |= CFI_EMIT_eh_frame_compact;
1219 }
1220#endif
1bce6bd8
PB
1221#ifdef tc_cfi_section_name
1222 else if (strcmp (name, tc_cfi_section_name) == 0)
1223 sections |= CFI_EMIT_target;
1224#endif
38462edf
JJ
1225 else
1226 {
1227 *input_line_pointer = c;
d02603dc 1228 input_line_pointer = saved_ilp;
38462edf
JJ
1229 break;
1230 }
1231
1232 *input_line_pointer = c;
d02603dc 1233 SKIP_WHITESPACE_AFTER_NAME ();
38462edf
JJ
1234 if (*input_line_pointer == ',')
1235 {
1236 name = input_line_pointer++;
1237 SKIP_WHITESPACE ();
d02603dc 1238 if (!is_name_beginner (*input_line_pointer) && *input_line_pointer != '"')
38462edf
JJ
1239 {
1240 input_line_pointer = name;
1241 break;
1242 }
1243 }
d02603dc 1244 else if (is_name_beginner (*input_line_pointer) || *input_line_pointer == '"')
38462edf
JJ
1245 break;
1246 }
1247
1248 demand_empty_rest_of_line ();
2f0c68f2
CM
1249 if (cfi_sections_set && cfi_sections != sections)
1250 as_bad (_("inconsistent uses of .cfi_sections"));
1251 cfi_sections_set = TRUE;
38462edf
JJ
1252 cfi_sections = sections;
1253}
1254
54cfded0 1255static void
a4447b93 1256dot_cfi_startproc (int ignored ATTRIBUTE_UNUSED)
54cfded0 1257{
a4447b93 1258 int simple = 0;
39b82151 1259
ae424f82 1260 if (frchain_now->frch_cfi_data != NULL)
54cfded0
AM
1261 {
1262 as_bad (_("previous CFI entry not closed (missing .cfi_endproc)"));
7c9c8381 1263 ignore_rest_of_line ();
54cfded0
AM
1264 return;
1265 }
1266
a4447b93 1267 cfi_new_fde (symbol_temp_new_now ());
39b82151 1268
a4447b93 1269 SKIP_WHITESPACE ();
d02603dc 1270 if (is_name_beginner (*input_line_pointer) || *input_line_pointer == '"')
a4447b93 1271 {
d02603dc 1272 char * saved_ilp = input_line_pointer;
a4447b93 1273 char *name, c;
54cfded0 1274
d02603dc 1275 c = get_symbol_name (& name);
54cfded0 1276
a4447b93
RH
1277 if (strcmp (name, "simple") == 0)
1278 {
1279 simple = 1;
d02603dc 1280 restore_line_pointer (c);
a4447b93
RH
1281 }
1282 else
d02603dc 1283 input_line_pointer = saved_ilp;
a4447b93
RH
1284 }
1285 demand_empty_rest_of_line ();
1286
2f0c68f2
CM
1287 all_cfi_sections |= cfi_sections;
1288 cfi_set_sections ();
ae424f82 1289 frchain_now->frch_cfi_data->cur_cfa_offset = 0;
a4447b93 1290 if (!simple)
39b82151 1291 tc_cfi_frame_initial_instructions ();
1bce6bd8
PB
1292
1293 if ((cfi_sections & CFI_EMIT_target) != 0)
1294 tc_cfi_startproc ();
54cfded0
AM
1295}
1296
a4447b93
RH
1297static void
1298dot_cfi_endproc (int ignored ATTRIBUTE_UNUSED)
1299{
ae424f82 1300 if (frchain_now->frch_cfi_data == NULL)
a4447b93
RH
1301 {
1302 as_bad (_(".cfi_endproc without corresponding .cfi_startproc"));
7c9c8381 1303 ignore_rest_of_line ();
a4447b93
RH
1304 return;
1305 }
54cfded0 1306
2f0c68f2 1307 last_fde = frchain_now->frch_cfi_data->cur_fde_data;
1bce6bd8 1308
a4447b93 1309 cfi_end_fde (symbol_temp_new_now ());
7c9c8381
JB
1310
1311 demand_empty_rest_of_line ();
1bce6bd8
PB
1312
1313 if ((cfi_sections & CFI_EMIT_target) != 0)
2f0c68f2 1314 tc_cfi_endproc (last_fde);
a4447b93 1315}
39b82151 1316
2f0c68f2
CM
1317static segT
1318get_cfi_seg (segT cseg, const char *base, flagword flags, int align)
54cfded0 1319{
2f0c68f2
CM
1320 /* Exclude .debug_frame sections for Compact EH. */
1321 if (SUPPORT_FRAME_LINKONCE || ((flags & SEC_DEBUGGING) == 0 && compact_eh))
1322 {
1323 struct dwcfi_seg_list *l;
1324
1325 l = dwcfi_hash_find_or_make (cseg, base, flags);
1326
1327 cseg = l->seg;
1328 subseg_set (cseg, l->subseg);
1329 }
1330 else
1331 {
1332 cseg = subseg_new (base, 0);
1333 bfd_set_section_flags (stdoutput, cseg, flags);
1334 }
1335 record_alignment (cseg, align);
1336 return cseg;
a4447b93 1337}
54cfded0 1338
2f0c68f2
CM
1339#if SUPPORT_COMPACT_EH
1340static void
1341dot_cfi_personality_id (int ignored ATTRIBUTE_UNUSED)
1342{
1343 struct fde_entry *fde;
54cfded0 1344
2f0c68f2
CM
1345 if (frchain_now->frch_cfi_data == NULL)
1346 {
1347 as_bad (_("CFI instruction used without previous .cfi_startproc"));
1348 ignore_rest_of_line ();
1349 return;
1350 }
1351
1352 fde = frchain_now->frch_cfi_data->cur_fde_data;
1353 fde->personality_id = cfi_parse_const ();
1354 demand_empty_rest_of_line ();
1355
1356 if (fde->personality_id == 0 || fde->personality_id > 3)
1357 {
1358 as_bad (_("wrong argument to .cfi_personality_id"));
1359 return;
1360 }
1361}
1362
1363static void
1364dot_cfi_fde_data (int ignored ATTRIBUTE_UNUSED)
a4447b93 1365{
2f0c68f2
CM
1366 if (frchain_now->frch_cfi_data == NULL)
1367 {
1368 as_bad (_(".cfi_fde_data without corresponding .cfi_startproc"));
1369 ignore_rest_of_line ();
1370 return;
1371 }
1372
1373 last_fde = frchain_now->frch_cfi_data->cur_fde_data;
1374
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 {
1387 e = (struct cfi_escape_data *) xmalloc (sizeof (*e));
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;
1409 last_fde->eh_data = (bfd_byte *) xmalloc (num_ops);
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
1e9cc1c2 2093 cie = (struct cie_entry *) xmalloc (sizeof (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
2f0c68f2
CM
2226 if ((all_cfi_sections & CFI_EMIT_eh_frame) != 0
2227 || (all_cfi_sections & CFI_EMIT_eh_frame_compact) != 0)
38462edf 2228 {
38462edf
JJ
2229 /* Make sure check_eh_frame doesn't do anything with our output. */
2230 save_flag_traditional_format = flag_traditional_format;
2231 flag_traditional_format = 1;
eafbc43f 2232
2f0c68f2 2233 if (!EH_FRAME_LINKONCE)
6303c4ae
AM
2234 {
2235 /* Open .eh_frame section. */
2236 cfi_seg = get_cfi_seg (NULL, ".eh_frame",
2237 (SEC_ALLOC | SEC_LOAD | SEC_DATA
2238 | DWARF2_EH_FRAME_READ_ONLY),
2239 EH_FRAME_ALIGNMENT);
67ed7401 2240#ifdef md_fix_up_eh_frame
6303c4ae 2241 md_fix_up_eh_frame (cfi_seg);
67ed7401 2242#else
6303c4ae 2243 (void) cfi_seg;
67ed7401 2244#endif
6303c4ae 2245 }
67ed7401 2246
72b016b4 2247 do
83e12deb 2248 {
72b016b4 2249 ccseg = NULL;
72b016b4 2250 seek_next_seg = 0;
67ed7401 2251
72b016b4 2252 for (cie = cie_root; cie; cie = cie_next)
38462edf 2253 {
72b016b4
NC
2254 cie_next = cie->next;
2255 free ((void *) cie);
38462edf 2256 }
72b016b4 2257 cie_root = NULL;
38462edf 2258
72b016b4
NC
2259 for (fde = all_fde_data; fde ; fde = fde->next)
2260 {
2f0c68f2
CM
2261 if ((fde->sections & CFI_EMIT_eh_frame) == 0
2262 && (fde->sections & CFI_EMIT_eh_frame_compact) == 0)
2263 continue;
2264
2265#if SUPPORT_COMPACT_EH
2266 /* Emit a LEGACY format header if we have processed all
2267 of the .cfi directives without encountering either inline or
2268 out-of-line compact unwinding opcodes. */
2269 if (fde->eh_header_type == EH_COMPACT_HAS_LSDA
2270 || fde->eh_header_type == EH_COMPACT_UNKNOWN)
2271 fde->eh_header_type = EH_COMPACT_LEGACY;
2272
2273 if (fde->eh_header_type != EH_COMPACT_LEGACY)
2274 continue;
2275#endif
2276 if (EH_FRAME_LINKONCE)
6303c4ae
AM
2277 {
2278 if (HANDLED (fde))
2279 continue;
2280 if (seek_next_seg && CUR_SEG (fde) != ccseg)
2281 {
2282 seek_next_seg = 2;
2283 continue;
2284 }
2285 if (!seek_next_seg)
2286 {
2287 ccseg = CUR_SEG (fde);
2288 /* Open .eh_frame section. */
2289 cfi_seg = get_cfi_seg (ccseg, ".eh_frame",
2290 (SEC_ALLOC | SEC_LOAD | SEC_DATA
2291 | DWARF2_EH_FRAME_READ_ONLY),
2292 EH_FRAME_ALIGNMENT);
72b016b4 2293#ifdef md_fix_up_eh_frame
6303c4ae 2294 md_fix_up_eh_frame (cfi_seg);
67ed7401 2295#else
6303c4ae 2296 (void) cfi_seg;
72b016b4 2297#endif
6303c4ae
AM
2298 seek_next_seg = 1;
2299 }
2300 SET_HANDLED (fde, 1);
72b016b4 2301 }
72b016b4
NC
2302
2303 if (fde->end_address == NULL)
2304 {
2305 as_bad (_("open CFI at the end of file; missing .cfi_endproc directive"));
2306 fde->end_address = fde->start_address;
2307 }
2308
2309 cie = select_cie_for_fde (fde, TRUE, &first, 2);
2f0c68f2 2310 fde->eh_loc = symbol_temp_new_now ();
72b016b4
NC
2311 output_fde (fde, cie, TRUE, first,
2312 fde->next == NULL ? EH_FRAME_ALIGNMENT : 2);
2313 }
38462edf 2314 }
2f0c68f2 2315 while (EH_FRAME_LINKONCE && seek_next_seg == 2);
72b016b4 2316
2f0c68f2 2317 if (EH_FRAME_LINKONCE)
6303c4ae
AM
2318 for (fde = all_fde_data; fde ; fde = fde->next)
2319 SET_HANDLED (fde, 0);
38462edf 2320
2f0c68f2
CM
2321#if SUPPORT_COMPACT_EH
2322 if (compact_eh)
2323 {
2324 /* Create remaining out of line table entries. */
2325 do
2326 {
2327 ccseg = NULL;
2328 seek_next_seg = 0;
2329
2330 for (fde = all_fde_data; fde ; fde = fde->next)
2331 {
2332 if ((fde->sections & CFI_EMIT_eh_frame) == 0
2333 && (fde->sections & CFI_EMIT_eh_frame_compact) == 0)
2334 continue;
2335
2336 if (fde->eh_header_type != EH_COMPACT_OUTLINE)
2337 continue;
2338 if (HANDLED (fde))
2339 continue;
2340 if (seek_next_seg && CUR_SEG (fde) != ccseg)
2341 {
2342 seek_next_seg = 2;
2343 continue;
2344 }
2345 if (!seek_next_seg)
2346 {
2347 ccseg = CUR_SEG (fde);
2348 /* Open .gnu_extab section. */
2349 get_cfi_seg (ccseg, ".gnu_extab",
2350 (SEC_ALLOC | SEC_LOAD | SEC_DATA
2351 | DWARF2_EH_FRAME_READ_ONLY),
2352 1);
2353 seek_next_seg = 1;
2354 }
2355 SET_HANDLED (fde, 1);
2356
2357 frag_align (1, 0, 0);
2358 record_alignment (now_seg, 1);
2359 output_compact_unwind_data (fde, 1);
2360 }
2361 }
2362 while (EH_FRAME_LINKONCE && seek_next_seg == 2);
2363
2364 for (fde = all_fde_data; fde ; fde = fde->next)
2365 SET_HANDLED (fde, 0);
2366
2367 /* Create index table fragments. */
2368 do
2369 {
2370 ccseg = NULL;
2371 seek_next_seg = 0;
2372
2373 for (fde = all_fde_data; fde ; fde = fde->next)
2374 {
2375 if ((fde->sections & CFI_EMIT_eh_frame) == 0
2376 && (fde->sections & CFI_EMIT_eh_frame_compact) == 0)
2377 continue;
2378
2379 if (HANDLED (fde))
2380 continue;
2381 if (seek_next_seg && CUR_SEG (fde) != ccseg)
2382 {
2383 seek_next_seg = 2;
2384 continue;
2385 }
2386 if (!seek_next_seg)
2387 {
2388 ccseg = CUR_SEG (fde);
2389 /* Open .eh_frame_entry section. */
2390 cfi_seg = get_cfi_seg (ccseg, ".eh_frame_entry",
2391 (SEC_ALLOC | SEC_LOAD | SEC_DATA
2392 | DWARF2_EH_FRAME_READ_ONLY),
2393 2);
2394 seek_next_seg = 1;
2395 }
2396 SET_HANDLED (fde, 1);
2397
2398 output_eh_header (fde);
2399 }
2400 }
2401 while (seek_next_seg == 2);
2402
2403 for (fde = all_fde_data; fde ; fde = fde->next)
2404 SET_HANDLED (fde, 0);
2405 }
2406#endif /* SUPPORT_COMPACT_EH */
2407
38462edf
JJ
2408 flag_traditional_format = save_flag_traditional_format;
2409 }
2410
2f0c68f2 2411 if ((all_cfi_sections & CFI_EMIT_debug_frame) != 0)
a4447b93 2412 {
38462edf 2413 int alignment = ffs (DWARF2_ADDR_SIZE (stdoutput)) - 1;
a4447b93 2414
6303c4ae
AM
2415 if (!SUPPORT_FRAME_LINKONCE)
2416 get_cfi_seg (NULL, ".debug_frame",
2417 SEC_READONLY | SEC_DEBUGGING,
2418 alignment);
2419
72b016b4 2420 do
83e12deb 2421 {
72b016b4 2422 ccseg = NULL;
72b016b4 2423 seek_next_seg = 0;
67ed7401 2424
72b016b4 2425 for (cie = cie_root; cie; cie = cie_next)
38462edf 2426 {
72b016b4
NC
2427 cie_next = cie->next;
2428 free ((void *) cie);
38462edf 2429 }
72b016b4 2430 cie_root = NULL;
38462edf 2431
72b016b4
NC
2432 for (fde = all_fde_data; fde ; fde = fde->next)
2433 {
2f0c68f2
CM
2434 if ((fde->sections & CFI_EMIT_debug_frame) == 0)
2435 continue;
2436
6303c4ae
AM
2437 if (SUPPORT_FRAME_LINKONCE)
2438 {
2439 if (HANDLED (fde))
2440 continue;
2441 if (seek_next_seg && CUR_SEG (fde) != ccseg)
2442 {
2443 seek_next_seg = 2;
2444 continue;
2445 }
2446 if (!seek_next_seg)
2447 {
2448 ccseg = CUR_SEG (fde);
2449 /* Open .debug_frame section. */
2450 get_cfi_seg (ccseg, ".debug_frame",
2451 SEC_READONLY | SEC_DEBUGGING,
2452 alignment);
2453 seek_next_seg = 1;
2454 }
2455 SET_HANDLED (fde, 1);
72b016b4 2456 }
72b016b4
NC
2457 if (fde->end_address == NULL)
2458 {
2459 as_bad (_("open CFI at the end of file; missing .cfi_endproc directive"));
2460 fde->end_address = fde->start_address;
2461 }
2462
2463 fde->per_encoding = DW_EH_PE_omit;
2464 fde->lsda_encoding = DW_EH_PE_omit;
2465 cfi_change_reg_numbers (fde->data, ccseg);
2466 cie = select_cie_for_fde (fde, FALSE, &first, alignment);
2467 output_fde (fde, cie, FALSE, first, alignment);
2468 }
38462edf 2469 }
67ed7401 2470 while (SUPPORT_FRAME_LINKONCE && seek_next_seg == 2);
72b016b4 2471
6303c4ae
AM
2472 if (SUPPORT_FRAME_LINKONCE)
2473 for (fde = all_fde_data; fde ; fde = fde->next)
2474 SET_HANDLED (fde, 0);
38462edf 2475 }
54cfded0 2476}
0a7b15ff
JB
2477
2478#else /* TARGET_USE_CFIPOP */
d58a1929 2479
5ff2bd08 2480/* Emit an intelligible error message for missing support. */
d58a1929
RH
2481
2482static void
2483dot_cfi_dummy (int ignored ATTRIBUTE_UNUSED)
2484{
2485 as_bad (_("CFI is not supported for this target"));
2486 ignore_rest_of_line ();
2487}
2488
2489const pseudo_typeS cfi_pseudo_table[] =
2490 {
2491 { "cfi_sections", dot_cfi_dummy, 0 },
2492 { "cfi_startproc", dot_cfi_dummy, 0 },
2493 { "cfi_endproc", dot_cfi_dummy, 0 },
2f0c68f2 2494 { "cfi_fde_data", dot_cfi_dummy, 0 },
d58a1929
RH
2495 { "cfi_def_cfa", dot_cfi_dummy, 0 },
2496 { "cfi_def_cfa_register", dot_cfi_dummy, 0 },
2497 { "cfi_def_cfa_offset", dot_cfi_dummy, 0 },
2498 { "cfi_adjust_cfa_offset", dot_cfi_dummy, 0 },
2499 { "cfi_offset", dot_cfi_dummy, 0 },
2500 { "cfi_rel_offset", dot_cfi_dummy, 0 },
2501 { "cfi_register", dot_cfi_dummy, 0 },
2502 { "cfi_return_column", dot_cfi_dummy, 0 },
2503 { "cfi_restore", dot_cfi_dummy, 0 },
2504 { "cfi_undefined", dot_cfi_dummy, 0 },
2505 { "cfi_same_value", dot_cfi_dummy, 0 },
2506 { "cfi_remember_state", dot_cfi_dummy, 0 },
2507 { "cfi_restore_state", dot_cfi_dummy, 0 },
2508 { "cfi_window_save", dot_cfi_dummy, 0 },
2509 { "cfi_escape", dot_cfi_dummy, 0 },
2510 { "cfi_signal_frame", dot_cfi_dummy, 0 },
2511 { "cfi_personality", dot_cfi_dummy, 0 },
2f0c68f2 2512 { "cfi_personality_id", dot_cfi_dummy, 0 },
d58a1929
RH
2513 { "cfi_lsda", dot_cfi_dummy, 0 },
2514 { "cfi_val_encoded_addr", dot_cfi_dummy, 0 },
73e76108 2515 { "cfi_label", dot_cfi_dummy, 0 },
2f0c68f2 2516 { "cfi_inline_lsda", dot_cfi_dummy, 0 },
d58a1929
RH
2517 { NULL, NULL, 0 }
2518 };
2519
0a7b15ff
JB
2520void
2521cfi_finish (void)
2522{
2523}
2524#endif /* TARGET_USE_CFIPOP */
This page took 0.648786 seconds and 4 git commands to generate.