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