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