]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gas/dw2gencfi.c
Make "end" field in feature specs required again.
[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;
1a0670f3 1180 /* Fall through. */
f1c4cc75
RH
1181 default:
1182 encoding = DW_EH_PE_omit;
1183 break;
1184 }
1185
1186 insn_ptr->u.ea.encoding = encoding;
1187 if (encoding == DW_EH_PE_omit)
1188 {
1189 as_bad (_("wrong third argument to .cfi_val_encoded_addr"));
1190 ignore_rest_of_line ();
1191 return;
1192 }
1193
1194 demand_empty_rest_of_line ();
1195}
1196
69602580
JB
1197static void
1198dot_cfi_label (int ignored ATTRIBUTE_UNUSED)
1199{
1200 char *name = read_symbol_name ();
1201
1202 if (name == NULL)
1203 return;
1204
1205 /* If the last address was not at the current PC, advance to current. */
1206 if (symbol_get_frag (frchain_now->frch_cfi_data->last_address) != frag_now
1207 || S_GET_VALUE (frchain_now->frch_cfi_data->last_address)
1208 != frag_now_fix ())
1209 cfi_add_advance_loc (symbol_temp_new_now ());
1210
1211 cfi_add_label (name);
92e18d93 1212 free (name);
69602580
JB
1213
1214 demand_empty_rest_of_line ();
1215}
1216
38462edf
JJ
1217static void
1218dot_cfi_sections (int ignored ATTRIBUTE_UNUSED)
1219{
1220 int sections = 0;
1221
1222 SKIP_WHITESPACE ();
d02603dc 1223 if (is_name_beginner (*input_line_pointer) || *input_line_pointer == '"')
38462edf
JJ
1224 while (1)
1225 {
d02603dc 1226 char * saved_ilp;
38462edf
JJ
1227 char *name, c;
1228
d02603dc
NC
1229 saved_ilp = input_line_pointer;
1230 c = get_symbol_name (& name);
38462edf 1231
72b016b4
NC
1232 if (strncmp (name, ".eh_frame", sizeof ".eh_frame") == 0
1233 && name[9] != '_')
38462edf 1234 sections |= CFI_EMIT_eh_frame;
72b016b4 1235 else if (strncmp (name, ".debug_frame", sizeof ".debug_frame") == 0)
38462edf 1236 sections |= CFI_EMIT_debug_frame;
2f0c68f2
CM
1237#if SUPPORT_COMPACT_EH
1238 else if (strncmp (name, ".eh_frame_entry", sizeof ".eh_frame_entry") == 0)
1239 {
1240 compact_eh = TRUE;
1241 sections |= CFI_EMIT_eh_frame_compact;
1242 }
1243#endif
1bce6bd8
PB
1244#ifdef tc_cfi_section_name
1245 else if (strcmp (name, tc_cfi_section_name) == 0)
1246 sections |= CFI_EMIT_target;
1247#endif
38462edf
JJ
1248 else
1249 {
1250 *input_line_pointer = c;
d02603dc 1251 input_line_pointer = saved_ilp;
38462edf
JJ
1252 break;
1253 }
1254
1255 *input_line_pointer = c;
d02603dc 1256 SKIP_WHITESPACE_AFTER_NAME ();
38462edf
JJ
1257 if (*input_line_pointer == ',')
1258 {
1259 name = input_line_pointer++;
1260 SKIP_WHITESPACE ();
d02603dc 1261 if (!is_name_beginner (*input_line_pointer) && *input_line_pointer != '"')
38462edf
JJ
1262 {
1263 input_line_pointer = name;
1264 break;
1265 }
1266 }
d02603dc 1267 else if (is_name_beginner (*input_line_pointer) || *input_line_pointer == '"')
38462edf
JJ
1268 break;
1269 }
1270
1271 demand_empty_rest_of_line ();
2f0c68f2
CM
1272 if (cfi_sections_set && cfi_sections != sections)
1273 as_bad (_("inconsistent uses of .cfi_sections"));
38462edf
JJ
1274 cfi_sections = sections;
1275}
1276
54cfded0 1277static void
a4447b93 1278dot_cfi_startproc (int ignored ATTRIBUTE_UNUSED)
54cfded0 1279{
a4447b93 1280 int simple = 0;
39b82151 1281
ae424f82 1282 if (frchain_now->frch_cfi_data != NULL)
54cfded0
AM
1283 {
1284 as_bad (_("previous CFI entry not closed (missing .cfi_endproc)"));
7c9c8381 1285 ignore_rest_of_line ();
54cfded0
AM
1286 return;
1287 }
1288
a4447b93 1289 cfi_new_fde (symbol_temp_new_now ());
39b82151 1290
a4447b93 1291 SKIP_WHITESPACE ();
d02603dc 1292 if (is_name_beginner (*input_line_pointer) || *input_line_pointer == '"')
a4447b93 1293 {
d02603dc 1294 char * saved_ilp = input_line_pointer;
a4447b93 1295 char *name, c;
54cfded0 1296
d02603dc 1297 c = get_symbol_name (& name);
54cfded0 1298
a4447b93
RH
1299 if (strcmp (name, "simple") == 0)
1300 {
1301 simple = 1;
d02603dc 1302 restore_line_pointer (c);
a4447b93
RH
1303 }
1304 else
d02603dc 1305 input_line_pointer = saved_ilp;
a4447b93
RH
1306 }
1307 demand_empty_rest_of_line ();
1308
bd5608dc 1309 cfi_sections_set = TRUE;
2f0c68f2
CM
1310 all_cfi_sections |= cfi_sections;
1311 cfi_set_sections ();
ae424f82 1312 frchain_now->frch_cfi_data->cur_cfa_offset = 0;
a4447b93 1313 if (!simple)
39b82151 1314 tc_cfi_frame_initial_instructions ();
1bce6bd8
PB
1315
1316 if ((cfi_sections & CFI_EMIT_target) != 0)
1317 tc_cfi_startproc ();
54cfded0
AM
1318}
1319
a4447b93
RH
1320static void
1321dot_cfi_endproc (int ignored ATTRIBUTE_UNUSED)
1322{
ae424f82 1323 if (frchain_now->frch_cfi_data == NULL)
a4447b93
RH
1324 {
1325 as_bad (_(".cfi_endproc without corresponding .cfi_startproc"));
7c9c8381 1326 ignore_rest_of_line ();
a4447b93
RH
1327 return;
1328 }
54cfded0 1329
2f0c68f2 1330 last_fde = frchain_now->frch_cfi_data->cur_fde_data;
1bce6bd8 1331
a4447b93 1332 cfi_end_fde (symbol_temp_new_now ());
7c9c8381
JB
1333
1334 demand_empty_rest_of_line ();
1bce6bd8 1335
bd5608dc 1336 cfi_sections_set = TRUE;
1bce6bd8 1337 if ((cfi_sections & CFI_EMIT_target) != 0)
2f0c68f2 1338 tc_cfi_endproc (last_fde);
a4447b93 1339}
39b82151 1340
2f0c68f2
CM
1341static segT
1342get_cfi_seg (segT cseg, const char *base, flagword flags, int align)
54cfded0 1343{
2f0c68f2
CM
1344 /* Exclude .debug_frame sections for Compact EH. */
1345 if (SUPPORT_FRAME_LINKONCE || ((flags & SEC_DEBUGGING) == 0 && compact_eh))
1346 {
1347 struct dwcfi_seg_list *l;
1348
1349 l = dwcfi_hash_find_or_make (cseg, base, flags);
1350
1351 cseg = l->seg;
1352 subseg_set (cseg, l->subseg);
1353 }
1354 else
1355 {
1356 cseg = subseg_new (base, 0);
1357 bfd_set_section_flags (stdoutput, cseg, flags);
1358 }
1359 record_alignment (cseg, align);
1360 return cseg;
a4447b93 1361}
54cfded0 1362
2f0c68f2
CM
1363#if SUPPORT_COMPACT_EH
1364static void
1365dot_cfi_personality_id (int ignored ATTRIBUTE_UNUSED)
1366{
1367 struct fde_entry *fde;
54cfded0 1368
2f0c68f2
CM
1369 if (frchain_now->frch_cfi_data == NULL)
1370 {
1371 as_bad (_("CFI instruction used without previous .cfi_startproc"));
1372 ignore_rest_of_line ();
1373 return;
1374 }
1375
1376 fde = frchain_now->frch_cfi_data->cur_fde_data;
1377 fde->personality_id = cfi_parse_const ();
1378 demand_empty_rest_of_line ();
1379
1380 if (fde->personality_id == 0 || fde->personality_id > 3)
1381 {
1382 as_bad (_("wrong argument to .cfi_personality_id"));
1383 return;
1384 }
1385}
1386
1387static void
1388dot_cfi_fde_data (int ignored ATTRIBUTE_UNUSED)
a4447b93 1389{
2f0c68f2
CM
1390 if (frchain_now->frch_cfi_data == NULL)
1391 {
1392 as_bad (_(".cfi_fde_data without corresponding .cfi_startproc"));
1393 ignore_rest_of_line ();
1394 return;
1395 }
1396
1397 last_fde = frchain_now->frch_cfi_data->cur_fde_data;
1398
bd5608dc 1399 cfi_sections_set = TRUE;
2f0c68f2
CM
1400 if ((cfi_sections & CFI_EMIT_target) != 0
1401 || (cfi_sections & CFI_EMIT_eh_frame_compact) != 0)
1402 {
1403 struct cfi_escape_data *head, **tail, *e;
1404 int num_ops = 0;
1405
1406 tail = &head;
1407 if (!is_it_end_of_statement ())
1408 {
1409 num_ops = 0;
1410 do
1411 {
add39d23 1412 e = XNEW (struct cfi_escape_data);
2f0c68f2
CM
1413 do_parse_cons_expression (&e->exp, 1);
1414 *tail = e;
1415 tail = &e->next;
1416 num_ops++;
1417 }
1418 while (*input_line_pointer++ == ',');
1419 --input_line_pointer;
1420 }
1421 *tail = NULL;
1422
1423 if (last_fde->lsda_encoding != DW_EH_PE_omit)
1424 last_fde->eh_header_type = EH_COMPACT_HAS_LSDA;
1425 else if (num_ops <= 3 && last_fde->per_encoding == DW_EH_PE_omit)
1426 last_fde->eh_header_type = EH_COMPACT_INLINE;
1427 else
1428 last_fde->eh_header_type = EH_COMPACT_OUTLINE;
1429
1430 if (last_fde->eh_header_type == EH_COMPACT_INLINE)
1431 num_ops = 3;
1432
1433 last_fde->eh_data_size = num_ops;
add39d23 1434 last_fde->eh_data = XNEWVEC (bfd_byte, num_ops);
2f0c68f2
CM
1435 num_ops = 0;
1436 while (head)
1437 {
1438 e = head;
1439 head = e->next;
1440 last_fde->eh_data[num_ops++] = e->exp.X_add_number;
1441 free (e);
1442 }
1443 if (last_fde->eh_header_type == EH_COMPACT_INLINE)
1444 while (num_ops < 3)
1445 last_fde->eh_data[num_ops++] = tc_compact_eh_opcode_stop;
1446 }
1447
1448 demand_empty_rest_of_line ();
a4447b93 1449}
54cfded0 1450
2f0c68f2
CM
1451/* Function to emit the compact unwinding opcodes stored in the
1452 fde's eh_data field. The end of the opcode data will be
1453 padded to the value in align. */
54cfded0 1454
2f0c68f2
CM
1455static void
1456output_compact_unwind_data (struct fde_entry *fde, int align)
a4447b93 1457{
2f0c68f2
CM
1458 int data_size = fde->eh_data_size + 2;
1459 int align_padding;
1460 int amask;
1461 char *p;
1462
1463 fde->eh_loc = symbol_temp_new_now ();
1464
1465 p = frag_more (1);
1466 if (fde->personality_id != 0)
1467 *p = fde->personality_id;
1468 else if (fde->per_encoding != DW_EH_PE_omit)
1469 {
1470 *p = 0;
1471 emit_expr_encoded (&fde->personality, fde->per_encoding, FALSE);
1472 data_size += encoding_size (fde->per_encoding);
1473 }
1474 else
1475 *p = 1;
1476
1477 amask = (1 << align) - 1;
1478 align_padding = ((data_size + amask) & ~amask) - data_size;
1479
1480 p = frag_more (fde->eh_data_size + 1 + align_padding);
1481 memcpy (p, fde->eh_data, fde->eh_data_size);
1482 p += fde->eh_data_size;
1483
1484 while (align_padding-- > 0)
1485 *(p++) = tc_compact_eh_opcode_pad;
1486
1487 *(p++) = tc_compact_eh_opcode_stop;
1488 fde->eh_header_type = EH_COMPACT_OUTLINE_DONE;
a4447b93
RH
1489}
1490
2f0c68f2
CM
1491/* Handle the .cfi_inline_lsda directive. */
1492static void
1493dot_cfi_inline_lsda (int ignored ATTRIBUTE_UNUSED)
1494{
1495 segT ccseg;
1496 int align;
1497 long max_alignment = 28;
1498
1499 if (!last_fde)
1500 {
1501 as_bad (_("unexpected .cfi_inline_lsda"));
1502 ignore_rest_of_line ();
1503 return;
1504 }
1505
1506 if ((last_fde->sections & CFI_EMIT_eh_frame_compact) == 0)
1507 {
1508 as_bad (_(".cfi_inline_lsda not valid for this frame"));
1509 ignore_rest_of_line ();
1510 return;
1511 }
1512
1513 if (last_fde->eh_header_type != EH_COMPACT_UNKNOWN
1514 && last_fde->eh_header_type != EH_COMPACT_HAS_LSDA)
1515 {
1516 as_bad (_(".cfi_inline_lsda seen for frame without .cfi_lsda"));
1517 ignore_rest_of_line ();
1518 return;
1519 }
1520
1521#ifdef md_flush_pending_output
1522 md_flush_pending_output ();
1523#endif
1524
1525 align = get_absolute_expression ();
1526 if (align > max_alignment)
1527 {
1528 align = max_alignment;
1529 as_bad (_("Alignment too large: %d. assumed."), align);
1530 }
1531 else if (align < 0)
1532 {
1533 as_warn (_("Alignment negative: 0 assumed."));
1534 align = 0;
1535 }
1536
1537 demand_empty_rest_of_line ();
1538 ccseg = CUR_SEG (last_fde);
54cfded0 1539
2f0c68f2
CM
1540 /* Open .gnu_extab section. */
1541 get_cfi_seg (ccseg, ".gnu_extab",
1542 (SEC_ALLOC | SEC_LOAD | SEC_DATA
1543 | DWARF2_EH_FRAME_READ_ONLY),
1544 1);
1545
1546 frag_align (align, 0, 0);
1547 record_alignment (now_seg, align);
1548 if (last_fde->eh_header_type == EH_COMPACT_HAS_LSDA)
1549 output_compact_unwind_data (last_fde, align);
1550
1551 last_fde = NULL;
1552
1553 return;
1554}
1555#else /* !SUPPORT_COMPACT_EH */
a4447b93 1556static void
2f0c68f2 1557dot_cfi_inline_lsda (int ignored ATTRIBUTE_UNUSED)
a4447b93 1558{
2f0c68f2
CM
1559 as_bad (_(".cfi_inline_lsda is not supported for this target"));
1560 ignore_rest_of_line ();
54cfded0
AM
1561}
1562
a4447b93 1563static void
2f0c68f2 1564dot_cfi_fde_data (int ignored ATTRIBUTE_UNUSED)
54cfded0 1565{
2f0c68f2
CM
1566 as_bad (_(".cfi_fde_data is not supported for this target"));
1567 ignore_rest_of_line ();
a4447b93 1568}
54cfded0 1569
2f0c68f2
CM
1570static void
1571dot_cfi_personality_id (int ignored ATTRIBUTE_UNUSED)
1572{
1573 as_bad (_(".cfi_personality_id is not supported for this target"));
1574 ignore_rest_of_line ();
1575}
1576#endif
1577\f
a4447b93
RH
1578static void
1579output_cfi_insn (struct cfi_insn_data *insn)
1580{
1581 offsetT offset;
1582 unsigned int regno;
54cfded0 1583
a4447b93 1584 switch (insn->insn)
54cfded0 1585 {
a4447b93
RH
1586 case DW_CFA_advance_loc:
1587 {
1588 symbolS *from = insn->u.ll.lab1;
1589 symbolS *to = insn->u.ll.lab2;
1590
1591 if (symbol_get_frag (to) == symbol_get_frag (from))
1592 {
1593 addressT delta = S_GET_VALUE (to) - S_GET_VALUE (from);
1594 addressT scaled = delta / DWARF2_LINE_MIN_INSN_LENGTH;
1595
1596 if (scaled <= 0x3F)
1597 out_one (DW_CFA_advance_loc + scaled);
395e8345 1598 else if (scaled <= 0xFF)
a4447b93 1599 {
9b8ae42e 1600 out_one (DW_CFA_advance_loc1);
395e8345 1601 out_one (scaled);
a4447b93 1602 }
395e8345 1603 else if (scaled <= 0xFFFF)
a4447b93 1604 {
9b8ae42e 1605 out_one (DW_CFA_advance_loc2);
395e8345 1606 out_two (scaled);
a4447b93
RH
1607 }
1608 else
1609 {
9b8ae42e 1610 out_one (DW_CFA_advance_loc4);
395e8345 1611 out_four (scaled);
a4447b93
RH
1612 }
1613 }
1614 else
1615 {
1616 expressionS exp;
1617
1618 exp.X_op = O_subtract;
1619 exp.X_add_symbol = to;
1620 exp.X_op_symbol = from;
1621 exp.X_add_number = 0;
1622
1623 /* The code in ehopt.c expects that one byte of the encoding
1624 is already allocated to the frag. This comes from the way
1625 that it scans the .eh_frame section looking first for the
1626 .byte DW_CFA_advance_loc4. */
1fbfe785 1627 *frag_more (1) = DW_CFA_advance_loc4;
a4447b93
RH
1628
1629 frag_var (rs_cfa, 4, 0, DWARF2_LINE_MIN_INSN_LENGTH << 3,
1630 make_expr_symbol (&exp), frag_now_fix () - 1,
1631 (char *) frag_now);
1632 }
1633 }
1634 break;
1635
1636 case DW_CFA_def_cfa:
1637 offset = insn->u.ri.offset;
1638 if (offset < 0)
54cfded0 1639 {
a4447b93
RH
1640 out_one (DW_CFA_def_cfa_sf);
1641 out_uleb128 (insn->u.ri.reg);
dcb45a06 1642 out_sleb128 (offset / DWARF2_CIE_DATA_ALIGNMENT);
54cfded0
AM
1643 }
1644 else
1645 {
a4447b93
RH
1646 out_one (DW_CFA_def_cfa);
1647 out_uleb128 (insn->u.ri.reg);
1648 out_uleb128 (offset);
54cfded0
AM
1649 }
1650 break;
1651
a4447b93 1652 case DW_CFA_def_cfa_register:
2be24b54
ML
1653 case DW_CFA_undefined:
1654 case DW_CFA_same_value:
1655 out_one (insn->insn);
1656 out_uleb128 (insn->u.r);
54cfded0
AM
1657 break;
1658
a4447b93
RH
1659 case DW_CFA_def_cfa_offset:
1660 offset = insn->u.i;
1661 if (offset < 0)
1662 {
1663 out_one (DW_CFA_def_cfa_offset_sf);
dcb45a06 1664 out_sleb128 (offset / DWARF2_CIE_DATA_ALIGNMENT);
a4447b93
RH
1665 }
1666 else
1667 {
1668 out_one (DW_CFA_def_cfa_offset);
1669 out_uleb128 (offset);
1670 }
54cfded0
AM
1671 break;
1672
2be24b54
ML
1673 case DW_CFA_restore:
1674 regno = insn->u.r;
1675 if (regno <= 0x3F)
1676 {
1677 out_one (DW_CFA_restore + regno);
1678 }
1679 else
1680 {
1681 out_one (DW_CFA_restore_extended);
1682 out_uleb128 (regno);
1683 }
1684 break;
1685
a4447b93
RH
1686 case DW_CFA_offset:
1687 regno = insn->u.ri.reg;
1688 offset = insn->u.ri.offset / DWARF2_CIE_DATA_ALIGNMENT;
1689 if (offset < 0)
1690 {
1233ae62 1691 out_one (DW_CFA_offset_extended_sf);
a4447b93
RH
1692 out_uleb128 (regno);
1693 out_sleb128 (offset);
1694 }
1695 else if (regno <= 0x3F)
1696 {
1697 out_one (DW_CFA_offset + regno);
1698 out_uleb128 (offset);
1699 }
54cfded0
AM
1700 else
1701 {
a4447b93
RH
1702 out_one (DW_CFA_offset_extended);
1703 out_uleb128 (regno);
1704 out_uleb128 (offset);
54cfded0 1705 }
54cfded0
AM
1706 break;
1707
084303b8
AK
1708 case DW_CFA_val_offset:
1709 regno = insn->u.ri.reg;
1710 offset = insn->u.ri.offset / DWARF2_CIE_DATA_ALIGNMENT;
1711 if (offset < 0)
1712 {
1713 out_one (DW_CFA_val_offset_sf);
1714 out_uleb128 (regno);
1715 out_sleb128 (offset);
1716 }
1717 else
1718 {
1719 out_one (DW_CFA_val_offset);
1720 out_uleb128 (regno);
1721 out_uleb128 (offset);
1722 }
1723 break;
1724
a4447b93
RH
1725 case DW_CFA_register:
1726 out_one (DW_CFA_register);
1727 out_uleb128 (insn->u.rr.reg1);
1728 out_uleb128 (insn->u.rr.reg2);
39b82151
ML
1729 break;
1730
2be24b54
ML
1731 case DW_CFA_remember_state:
1732 case DW_CFA_restore_state:
2be24b54 1733 out_one (insn->insn);
54cfded0
AM
1734 break;
1735
364b6d8b
JJ
1736 case DW_CFA_GNU_window_save:
1737 out_one (DW_CFA_GNU_window_save);
1738 break;
1739
cdfbf930
RH
1740 case CFI_escape:
1741 {
1742 struct cfi_escape_data *e;
1743 for (e = insn->u.esc; e ; e = e->next)
1744 emit_expr (&e->exp, 1);
1745 break;
1746 }
1747
f1c4cc75
RH
1748 case CFI_val_encoded_addr:
1749 {
83e12deb 1750 unsigned encoding = insn->u.ea.encoding;
2f0c68f2 1751 offsetT enc_size;
f1c4cc75
RH
1752
1753 if (encoding == DW_EH_PE_omit)
1754 break;
1755 out_one (DW_CFA_val_expression);
1756 out_uleb128 (insn->u.ea.reg);
1757
83e12deb 1758 switch (encoding & 0x7)
f1c4cc75
RH
1759 {
1760 case DW_EH_PE_absptr:
2f0c68f2 1761 enc_size = DWARF2_ADDR_SIZE (stdoutput);
f1c4cc75
RH
1762 break;
1763 case DW_EH_PE_udata2:
2f0c68f2 1764 enc_size = 2;
f1c4cc75
RH
1765 break;
1766 case DW_EH_PE_udata4:
2f0c68f2 1767 enc_size = 4;
f1c4cc75
RH
1768 break;
1769 case DW_EH_PE_udata8:
2f0c68f2 1770 enc_size = 8;
f1c4cc75
RH
1771 break;
1772 default:
1773 abort ();
1774 }
1775
1776 /* If the user has requested absolute encoding,
1777 then use the smaller DW_OP_addr encoding. */
1778 if (insn->u.ea.encoding == DW_EH_PE_absptr)
1779 {
2f0c68f2 1780 out_uleb128 (1 + enc_size);
f1c4cc75
RH
1781 out_one (DW_OP_addr);
1782 }
1783 else
1784 {
2f0c68f2 1785 out_uleb128 (1 + 1 + enc_size);
f1c4cc75
RH
1786 out_one (DW_OP_GNU_encoded_addr);
1787 out_one (encoding);
1788
1789 if ((encoding & 0x70) == DW_EH_PE_pcrel)
1790 {
1791#if CFI_DIFF_EXPR_OK
1792 insn->u.ea.exp.X_op = O_subtract;
1793 insn->u.ea.exp.X_op_symbol = symbol_temp_new_now ();
1794#elif defined (tc_cfi_emit_pcrel_expr)
2f0c68f2 1795 tc_cfi_emit_pcrel_expr (&insn->u.ea.exp, enc_size);
f1c4cc75
RH
1796 break;
1797#else
1798 abort ();
1799#endif
1800 }
1801 }
2f0c68f2 1802 emit_expr (&insn->u.ea.exp, enc_size);
f1c4cc75
RH
1803 }
1804 break;
72b016b4 1805
69602580
JB
1806 case CFI_label:
1807 colon (insn->u.sym_name);
1808 break;
1809
54cfded0 1810 default:
a4447b93 1811 abort ();
54cfded0 1812 }
54cfded0
AM
1813}
1814
1815static void
38462edf 1816output_cie (struct cie_entry *cie, bfd_boolean eh_frame, int align)
54cfded0 1817{
a4447b93 1818 symbolS *after_size_address, *end_address;
7c0295b1 1819 expressionS exp;
a4447b93 1820 struct cfi_insn_data *i;
9b8ae42e 1821 offsetT augmentation_size;
8c9b70b1 1822 int enc;
38462edf 1823 enum dwarf2_format fmt = DWARF2_FORMAT (now_seg);
a4447b93
RH
1824
1825 cie->start_address = symbol_temp_new_now ();
1826 after_size_address = symbol_temp_make ();
1827 end_address = symbol_temp_make ();
1828
1829 exp.X_op = O_subtract;
1830 exp.X_add_symbol = end_address;
1831 exp.X_op_symbol = after_size_address;
1832 exp.X_add_number = 0;
1833
38462edf
JJ
1834 if (eh_frame || fmt == dwarf2_format_32bit)
1835 emit_expr (&exp, 4); /* Length. */
1836 else
1837 {
1838 if (fmt == dwarf2_format_64bit)
1839 out_four (-1);
1840 emit_expr (&exp, 8); /* Length. */
1841 }
a4447b93 1842 symbol_set_value_now (after_size_address);
38462edf
JJ
1843 if (eh_frame)
1844 out_four (0); /* CIE id. */
1845 else
1846 {
1847 out_four (-1); /* CIE id. */
1848 if (fmt != dwarf2_format_32bit)
1849 out_four (-1);
1850 }
289040ca 1851 out_one (DW_CIE_VERSION); /* Version. */
38462edf
JJ
1852 if (eh_frame)
1853 {
1854 out_one ('z'); /* Augmentation. */
1855 if (cie->per_encoding != DW_EH_PE_omit)
1856 out_one ('P');
1857 if (cie->lsda_encoding != DW_EH_PE_omit)
1858 out_one ('L');
1859 out_one ('R');
38462edf 1860 }
d905c788
TS
1861 if (cie->signal_frame)
1862 out_one ('S');
a4447b93 1863 out_one (0);
289040ca
NC
1864 out_uleb128 (DWARF2_LINE_MIN_INSN_LENGTH); /* Code alignment. */
1865 out_sleb128 (DWARF2_CIE_DATA_ALIGNMENT); /* Data alignment. */
0da76f83
NC
1866 if (DW_CIE_VERSION == 1) /* Return column. */
1867 out_one (cie->return_column);
1868 else
1869 out_uleb128 (cie->return_column);
38462edf
JJ
1870 if (eh_frame)
1871 {
1872 augmentation_size = 1 + (cie->lsda_encoding != DW_EH_PE_omit);
1873 if (cie->per_encoding != DW_EH_PE_omit)
1874 augmentation_size += 1 + encoding_size (cie->per_encoding);
1875 out_uleb128 (augmentation_size); /* Augmentation size. */
4e4e1355 1876
2f0c68f2 1877 emit_expr_encoded (&cie->personality, cie->per_encoding, TRUE);
4e4e1355
TS
1878
1879 if (cie->lsda_encoding != DW_EH_PE_omit)
1880 out_one (cie->lsda_encoding);
9b8ae42e 1881 }
8c9b70b1
RH
1882
1883 switch (DWARF2_FDE_RELOC_SIZE)
1884 {
1885 case 2:
1886 enc = DW_EH_PE_sdata2;
1887 break;
1888 case 4:
1889 enc = DW_EH_PE_sdata4;
1890 break;
1891 case 8:
1892 enc = DW_EH_PE_sdata8;
1893 break;
1894 default:
1895 abort ();
1896 }
3dd24306 1897#if CFI_DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr
8c9b70b1 1898 enc |= DW_EH_PE_pcrel;
364b6d8b 1899#endif
2f0c68f2
CM
1900#ifdef DWARF2_FDE_RELOC_ENCODING
1901 /* Allow target to override encoding. */
1902 enc = DWARF2_FDE_RELOC_ENCODING (enc);
1903#endif
1904 cie->fde_encoding = enc;
38462edf
JJ
1905 if (eh_frame)
1906 out_one (enc);
a4447b93
RH
1907
1908 if (cie->first)
72b016b4
NC
1909 {
1910 for (i = cie->first; i != cie->last; i = i->next)
83e12deb 1911 {
6303c4ae 1912 if (CUR_SEG (i) != CUR_SEG (cie))
72b016b4
NC
1913 continue;
1914 output_cfi_insn (i);
1915 }
1916 }
a4447b93 1917
38462edf 1918 frag_align (align, DW_CFA_nop, 0);
a4447b93
RH
1919 symbol_set_value_now (end_address);
1920}
54cfded0 1921
a4447b93
RH
1922static void
1923output_fde (struct fde_entry *fde, struct cie_entry *cie,
38462edf
JJ
1924 bfd_boolean eh_frame, struct cfi_insn_data *first,
1925 int align)
a4447b93
RH
1926{
1927 symbolS *after_size_address, *end_address;
1928 expressionS exp;
9b8ae42e 1929 offsetT augmentation_size;
38462edf
JJ
1930 enum dwarf2_format fmt = DWARF2_FORMAT (now_seg);
1931 int offset_size;
1932 int addr_size;
54cfded0 1933
a4447b93
RH
1934 after_size_address = symbol_temp_make ();
1935 end_address = symbol_temp_make ();
54cfded0 1936
a4447b93
RH
1937 exp.X_op = O_subtract;
1938 exp.X_add_symbol = end_address;
1939 exp.X_op_symbol = after_size_address;
1940 exp.X_add_number = 0;
38462edf
JJ
1941 if (eh_frame || fmt == dwarf2_format_32bit)
1942 offset_size = 4;
1943 else
1944 {
1945 if (fmt == dwarf2_format_64bit)
1946 out_four (-1);
1947 offset_size = 8;
1948 }
1949 emit_expr (&exp, offset_size); /* Length. */
a4447b93 1950 symbol_set_value_now (after_size_address);
54cfded0 1951
38462edf
JJ
1952 if (eh_frame)
1953 {
3251495b 1954 exp.X_op = O_subtract;
38462edf
JJ
1955 exp.X_add_symbol = after_size_address;
1956 exp.X_op_symbol = cie->start_address;
3251495b
RH
1957 exp.X_add_number = 0;
1958 emit_expr (&exp, offset_size); /* CIE offset. */
38462edf
JJ
1959 }
1960 else
1961 {
3251495b 1962 TC_DWARF2_EMIT_OFFSET (cie->start_address, offset_size);
38462edf 1963 }
364b6d8b 1964
2f0c68f2 1965 exp.X_op = O_symbol;
38462edf
JJ
1966 if (eh_frame)
1967 {
2f0c68f2
CM
1968 bfd_reloc_code_real_type code
1969 = tc_cfi_reloc_for_encoding (cie->fde_encoding);
1970 if (code != BFD_RELOC_NONE)
1971 {
1972 reloc_howto_type *howto = bfd_reloc_type_lookup (stdoutput, code);
1973 char *p = frag_more (4);
1974 md_number_to_chars (p, 0, 4);
1975 fix_new (frag_now, p - frag_now->fr_literal, 4, fde->start_address,
1976 0, howto->pc_relative, code);
1977 }
1978 else
1979 {
1980 exp.X_op = O_subtract;
1981 exp.X_add_number = 0;
3dd24306 1982#if CFI_DIFF_EXPR_OK
2f0c68f2
CM
1983 exp.X_add_symbol = fde->start_address;
1984 exp.X_op_symbol = symbol_temp_new_now ();
1985 emit_expr (&exp, DWARF2_FDE_RELOC_SIZE); /* Code offset. */
364b6d8b 1986#else
2f0c68f2
CM
1987 exp.X_op = O_symbol;
1988 exp.X_add_symbol = fde->start_address;
1989
1990#if defined(tc_cfi_emit_pcrel_expr)
1991 tc_cfi_emit_pcrel_expr (&exp, DWARF2_FDE_RELOC_SIZE); /* Code offset. */
364b6d8b 1992#else
2f0c68f2 1993 emit_expr (&exp, DWARF2_FDE_RELOC_SIZE); /* Code offset. */
364b6d8b 1994#endif
364b6d8b 1995#endif
2f0c68f2 1996 }
38462edf
JJ
1997 addr_size = DWARF2_FDE_RELOC_SIZE;
1998 }
1999 else
2000 {
3251495b 2001 exp.X_add_number = 0;
2f0c68f2 2002 exp.X_add_symbol = fde->start_address;
38462edf
JJ
2003 addr_size = DWARF2_ADDR_SIZE (stdoutput);
2004 emit_expr (&exp, addr_size);
2005 }
54cfded0 2006
38462edf 2007 exp.X_op = O_subtract;
a4447b93 2008 exp.X_add_symbol = fde->end_address;
289040ca 2009 exp.X_op_symbol = fde->start_address; /* Code length. */
3251495b 2010 exp.X_add_number = 0;
38462edf 2011 emit_expr (&exp, addr_size);
54cfded0 2012
9b8ae42e 2013 augmentation_size = encoding_size (fde->lsda_encoding);
38462edf
JJ
2014 if (eh_frame)
2015 out_uleb128 (augmentation_size); /* Augmentation size. */
9b8ae42e 2016
2f0c68f2 2017 emit_expr_encoded (&fde->lsda, cie->lsda_encoding, FALSE);
39b82151 2018
a4447b93 2019 for (; first; first = first->next)
6303c4ae 2020 if (CUR_SEG (first) == CUR_SEG (fde))
67ed7401 2021 output_cfi_insn (first);
39b82151 2022
4df6ce47 2023 frag_align (align, DW_CFA_nop, 0);
a4447b93
RH
2024 symbol_set_value_now (end_address);
2025}
2026
2027static struct cie_entry *
38462edf
JJ
2028select_cie_for_fde (struct fde_entry *fde, bfd_boolean eh_frame,
2029 struct cfi_insn_data **pfirst, int align)
a4447b93
RH
2030{
2031 struct cfi_insn_data *i, *j;
2032 struct cie_entry *cie;
2033
2034 for (cie = cie_root; cie; cie = cie->next)
39b82151 2035 {
6303c4ae 2036 if (CUR_SEG (cie) != CUR_SEG (fde))
67ed7401 2037 continue;
67ed7401 2038 if (cie->return_column != fde->return_column
9b8ae42e
JJ
2039 || cie->signal_frame != fde->signal_frame
2040 || cie->per_encoding != fde->per_encoding
2041 || cie->lsda_encoding != fde->lsda_encoding)
a4447b93 2042 continue;
9b8ae42e
JJ
2043 if (cie->per_encoding != DW_EH_PE_omit)
2044 {
2045 if (cie->personality.X_op != fde->personality.X_op
2046 || cie->personality.X_add_number
2047 != fde->personality.X_add_number)
2048 continue;
2049 switch (cie->personality.X_op)
2050 {
2051 case O_constant:
2052 if (cie->personality.X_unsigned != fde->personality.X_unsigned)
2053 continue;
2054 break;
2055 case O_symbol:
2056 if (cie->personality.X_add_symbol
2057 != fde->personality.X_add_symbol)
2058 continue;
2059 break;
2060 default:
2061 abort ();
2062 }
2063 }
a4447b93
RH
2064 for (i = cie->first, j = fde->data;
2065 i != cie->last && j != NULL;
2066 i = i->next, j = j->next)
39b82151 2067 {
a4447b93
RH
2068 if (i->insn != j->insn)
2069 goto fail;
2070 switch (i->insn)
2071 {
2072 case DW_CFA_advance_loc:
289040ca
NC
2073 case DW_CFA_remember_state:
2074 /* We reached the first advance/remember in the FDE,
2075 but did not reach the end of the CIE list. */
a4447b93
RH
2076 goto fail;
2077
2078 case DW_CFA_offset:
2079 case DW_CFA_def_cfa:
2080 if (i->u.ri.reg != j->u.ri.reg)
2081 goto fail;
2082 if (i->u.ri.offset != j->u.ri.offset)
2083 goto fail;
2084 break;
2085
2086 case DW_CFA_register:
2087 if (i->u.rr.reg1 != j->u.rr.reg1)
2088 goto fail;
2089 if (i->u.rr.reg2 != j->u.rr.reg2)
2090 goto fail;
2091 break;
2092
2093 case DW_CFA_def_cfa_register:
2be24b54
ML
2094 case DW_CFA_restore:
2095 case DW_CFA_undefined:
2096 case DW_CFA_same_value:
a4447b93
RH
2097 if (i->u.r != j->u.r)
2098 goto fail;
2099 break;
2100
2101 case DW_CFA_def_cfa_offset:
2102 if (i->u.i != j->u.i)
2103 goto fail;
2104 break;
2105
cdfbf930 2106 case CFI_escape:
f1c4cc75 2107 case CFI_val_encoded_addr:
73e76108 2108 case CFI_label:
cdfbf930
RH
2109 /* Don't bother matching these for now. */
2110 goto fail;
2111
a4447b93
RH
2112 default:
2113 abort ();
2114 }
39b82151 2115 }
a4447b93
RH
2116
2117 /* Success if we reached the end of the CIE list, and we've either
289040ca
NC
2118 run out of FDE entries or we've encountered an advance,
2119 remember, or escape. */
e9fad691
AM
2120 if (i == cie->last
2121 && (!j
2122 || j->insn == DW_CFA_advance_loc
289040ca 2123 || j->insn == DW_CFA_remember_state
f1c4cc75 2124 || j->insn == CFI_escape
73e76108
JB
2125 || j->insn == CFI_val_encoded_addr
2126 || j->insn == CFI_label))
39b82151 2127 {
a4447b93
RH
2128 *pfirst = j;
2129 return cie;
39b82151
ML
2130 }
2131
a4447b93 2132 fail:;
54cfded0
AM
2133 }
2134
add39d23 2135 cie = XNEW (struct cie_entry);
a4447b93
RH
2136 cie->next = cie_root;
2137 cie_root = cie;
6303c4ae 2138 SET_CUR_SEG (cie, CUR_SEG (fde));
a4447b93 2139 cie->return_column = fde->return_column;
63752a75 2140 cie->signal_frame = fde->signal_frame;
9b8ae42e
JJ
2141 cie->per_encoding = fde->per_encoding;
2142 cie->lsda_encoding = fde->lsda_encoding;
2143 cie->personality = fde->personality;
a4447b93 2144 cie->first = fde->data;
54cfded0 2145
a4447b93 2146 for (i = cie->first; i ; i = i->next)
e9fad691 2147 if (i->insn == DW_CFA_advance_loc
289040ca 2148 || i->insn == DW_CFA_remember_state
f1c4cc75 2149 || i->insn == CFI_escape
69602580
JB
2150 || i->insn == CFI_val_encoded_addr
2151 || i->insn == CFI_label)
a4447b93 2152 break;
54cfded0 2153
a4447b93
RH
2154 cie->last = i;
2155 *pfirst = i;
38462edf
JJ
2156
2157 output_cie (cie, eh_frame, align);
54cfded0 2158
a4447b93 2159 return cie;
54cfded0
AM
2160}
2161
38462edf
JJ
2162#ifdef md_reg_eh_frame_to_debug_frame
2163static void
6303c4ae 2164cfi_change_reg_numbers (struct cfi_insn_data *insn, segT ccseg)
38462edf
JJ
2165{
2166 for (; insn; insn = insn->next)
72b016b4 2167 {
6303c4ae 2168 if (CUR_SEG (insn) != ccseg)
83e12deb 2169 continue;
72b016b4
NC
2170 switch (insn->insn)
2171 {
2172 case DW_CFA_advance_loc:
2173 case DW_CFA_def_cfa_offset:
2174 case DW_CFA_remember_state:
2175 case DW_CFA_restore_state:
2176 case DW_CFA_GNU_window_save:
2177 case CFI_escape:
73e76108 2178 case CFI_label:
72b016b4 2179 break;
38462edf 2180
72b016b4
NC
2181 case DW_CFA_def_cfa:
2182 case DW_CFA_offset:
2183 insn->u.ri.reg = md_reg_eh_frame_to_debug_frame (insn->u.ri.reg);
2184 break;
38462edf 2185
72b016b4
NC
2186 case DW_CFA_def_cfa_register:
2187 case DW_CFA_undefined:
2188 case DW_CFA_same_value:
2189 case DW_CFA_restore:
2190 insn->u.r = md_reg_eh_frame_to_debug_frame (insn->u.r);
2191 break;
38462edf 2192
72b016b4
NC
2193 case DW_CFA_register:
2194 insn->u.rr.reg1 = md_reg_eh_frame_to_debug_frame (insn->u.rr.reg1);
2195 insn->u.rr.reg2 = md_reg_eh_frame_to_debug_frame (insn->u.rr.reg2);
2196 break;
38462edf 2197
72b016b4
NC
2198 case CFI_val_encoded_addr:
2199 insn->u.ea.reg = md_reg_eh_frame_to_debug_frame (insn->u.ea.reg);
2200 break;
38462edf 2201
72b016b4
NC
2202 default:
2203 abort ();
2204 }
2205 }
38462edf
JJ
2206}
2207#else
72b016b4 2208#define cfi_change_reg_numbers(insn, cseg) do { } while (0)
38462edf
JJ
2209#endif
2210
2f0c68f2
CM
2211#if SUPPORT_COMPACT_EH
2212static void
2213cfi_emit_eh_header (symbolS *sym, bfd_vma addend)
72b016b4 2214{
2f0c68f2 2215 expressionS exp;
72b016b4 2216
2f0c68f2
CM
2217 exp.X_add_number = addend;
2218 exp.X_add_symbol = sym;
2219 emit_expr_encoded (&exp, DW_EH_PE_sdata4 | DW_EH_PE_pcrel, FALSE);
2220}
72b016b4 2221
2f0c68f2
CM
2222static void
2223output_eh_header (struct fde_entry *fde)
2224{
2225 char *p;
2226 bfd_vma addend;
2227
2228 if (fde->eh_header_type == EH_COMPACT_INLINE)
2229 addend = 0;
2230 else
2231 addend = 1;
2232
2233 cfi_emit_eh_header (fde->start_address, addend);
2234
2235 if (fde->eh_header_type == EH_COMPACT_INLINE)
2236 {
2237 p = frag_more (4);
2238 /* Inline entries always use PR1. */
2239 *(p++) = 1;
2240 memcpy(p, fde->eh_data, 3);
6303c4ae
AM
2241 }
2242 else
2243 {
2f0c68f2
CM
2244 if (fde->eh_header_type == EH_COMPACT_LEGACY)
2245 addend = 1;
2246 else if (fde->eh_header_type == EH_COMPACT_OUTLINE
2247 || fde->eh_header_type == EH_COMPACT_OUTLINE_DONE)
2248 addend = 0;
2249 else
2250 abort ();
2251 cfi_emit_eh_header (fde->eh_loc, addend);
6303c4ae 2252 }
72b016b4 2253}
2f0c68f2 2254#endif
72b016b4 2255
54cfded0 2256void
a4447b93 2257cfi_finish (void)
54cfded0 2258{
72b016b4
NC
2259 struct cie_entry *cie, *cie_next;
2260 segT cfi_seg, ccseg;
a4447b93 2261 struct fde_entry *fde;
72b016b4
NC
2262 struct cfi_insn_data *first;
2263 int save_flag_traditional_format, seek_next_seg;
54cfded0 2264
a4447b93
RH
2265 if (all_fde_data == 0)
2266 return;
54cfded0 2267
bd5608dc 2268 cfi_sections_set = TRUE;
2f0c68f2
CM
2269 if ((all_cfi_sections & CFI_EMIT_eh_frame) != 0
2270 || (all_cfi_sections & CFI_EMIT_eh_frame_compact) != 0)
38462edf 2271 {
38462edf
JJ
2272 /* Make sure check_eh_frame doesn't do anything with our output. */
2273 save_flag_traditional_format = flag_traditional_format;
2274 flag_traditional_format = 1;
eafbc43f 2275
2f0c68f2 2276 if (!EH_FRAME_LINKONCE)
6303c4ae
AM
2277 {
2278 /* Open .eh_frame section. */
2279 cfi_seg = get_cfi_seg (NULL, ".eh_frame",
2280 (SEC_ALLOC | SEC_LOAD | SEC_DATA
2281 | DWARF2_EH_FRAME_READ_ONLY),
2282 EH_FRAME_ALIGNMENT);
67ed7401 2283#ifdef md_fix_up_eh_frame
6303c4ae 2284 md_fix_up_eh_frame (cfi_seg);
67ed7401 2285#else
6303c4ae 2286 (void) cfi_seg;
67ed7401 2287#endif
6303c4ae 2288 }
67ed7401 2289
72b016b4 2290 do
83e12deb 2291 {
72b016b4 2292 ccseg = NULL;
72b016b4 2293 seek_next_seg = 0;
67ed7401 2294
72b016b4 2295 for (cie = cie_root; cie; cie = cie_next)
38462edf 2296 {
72b016b4
NC
2297 cie_next = cie->next;
2298 free ((void *) cie);
38462edf 2299 }
72b016b4 2300 cie_root = NULL;
38462edf 2301
72b016b4
NC
2302 for (fde = all_fde_data; fde ; fde = fde->next)
2303 {
2f0c68f2
CM
2304 if ((fde->sections & CFI_EMIT_eh_frame) == 0
2305 && (fde->sections & CFI_EMIT_eh_frame_compact) == 0)
2306 continue;
2307
2308#if SUPPORT_COMPACT_EH
2309 /* Emit a LEGACY format header if we have processed all
2310 of the .cfi directives without encountering either inline or
2311 out-of-line compact unwinding opcodes. */
2312 if (fde->eh_header_type == EH_COMPACT_HAS_LSDA
2313 || fde->eh_header_type == EH_COMPACT_UNKNOWN)
2314 fde->eh_header_type = EH_COMPACT_LEGACY;
2315
2316 if (fde->eh_header_type != EH_COMPACT_LEGACY)
2317 continue;
2318#endif
2319 if (EH_FRAME_LINKONCE)
6303c4ae
AM
2320 {
2321 if (HANDLED (fde))
2322 continue;
2323 if (seek_next_seg && CUR_SEG (fde) != ccseg)
2324 {
2325 seek_next_seg = 2;
2326 continue;
2327 }
2328 if (!seek_next_seg)
2329 {
2330 ccseg = CUR_SEG (fde);
2331 /* Open .eh_frame section. */
2332 cfi_seg = get_cfi_seg (ccseg, ".eh_frame",
2333 (SEC_ALLOC | SEC_LOAD | SEC_DATA
2334 | DWARF2_EH_FRAME_READ_ONLY),
2335 EH_FRAME_ALIGNMENT);
72b016b4 2336#ifdef md_fix_up_eh_frame
6303c4ae 2337 md_fix_up_eh_frame (cfi_seg);
67ed7401 2338#else
6303c4ae 2339 (void) cfi_seg;
72b016b4 2340#endif
6303c4ae
AM
2341 seek_next_seg = 1;
2342 }
2343 SET_HANDLED (fde, 1);
72b016b4 2344 }
72b016b4
NC
2345
2346 if (fde->end_address == NULL)
2347 {
2348 as_bad (_("open CFI at the end of file; missing .cfi_endproc directive"));
2349 fde->end_address = fde->start_address;
2350 }
2351
2352 cie = select_cie_for_fde (fde, TRUE, &first, 2);
2f0c68f2 2353 fde->eh_loc = symbol_temp_new_now ();
72b016b4
NC
2354 output_fde (fde, cie, TRUE, first,
2355 fde->next == NULL ? EH_FRAME_ALIGNMENT : 2);
2356 }
38462edf 2357 }
2f0c68f2 2358 while (EH_FRAME_LINKONCE && seek_next_seg == 2);
72b016b4 2359
2f0c68f2 2360 if (EH_FRAME_LINKONCE)
6303c4ae
AM
2361 for (fde = all_fde_data; fde ; fde = fde->next)
2362 SET_HANDLED (fde, 0);
38462edf 2363
2f0c68f2
CM
2364#if SUPPORT_COMPACT_EH
2365 if (compact_eh)
2366 {
2367 /* Create remaining out of line table entries. */
2368 do
2369 {
2370 ccseg = NULL;
2371 seek_next_seg = 0;
2372
2373 for (fde = all_fde_data; fde ; fde = fde->next)
2374 {
2375 if ((fde->sections & CFI_EMIT_eh_frame) == 0
2376 && (fde->sections & CFI_EMIT_eh_frame_compact) == 0)
2377 continue;
2378
2379 if (fde->eh_header_type != EH_COMPACT_OUTLINE)
2380 continue;
2381 if (HANDLED (fde))
2382 continue;
2383 if (seek_next_seg && CUR_SEG (fde) != ccseg)
2384 {
2385 seek_next_seg = 2;
2386 continue;
2387 }
2388 if (!seek_next_seg)
2389 {
2390 ccseg = CUR_SEG (fde);
2391 /* Open .gnu_extab section. */
2392 get_cfi_seg (ccseg, ".gnu_extab",
2393 (SEC_ALLOC | SEC_LOAD | SEC_DATA
2394 | DWARF2_EH_FRAME_READ_ONLY),
2395 1);
2396 seek_next_seg = 1;
2397 }
2398 SET_HANDLED (fde, 1);
2399
2400 frag_align (1, 0, 0);
2401 record_alignment (now_seg, 1);
2402 output_compact_unwind_data (fde, 1);
2403 }
2404 }
2405 while (EH_FRAME_LINKONCE && seek_next_seg == 2);
2406
2407 for (fde = all_fde_data; fde ; fde = fde->next)
2408 SET_HANDLED (fde, 0);
2409
2410 /* Create index table fragments. */
2411 do
2412 {
2413 ccseg = NULL;
2414 seek_next_seg = 0;
2415
2416 for (fde = all_fde_data; fde ; fde = fde->next)
2417 {
2418 if ((fde->sections & CFI_EMIT_eh_frame) == 0
2419 && (fde->sections & CFI_EMIT_eh_frame_compact) == 0)
2420 continue;
2421
2422 if (HANDLED (fde))
2423 continue;
2424 if (seek_next_seg && CUR_SEG (fde) != ccseg)
2425 {
2426 seek_next_seg = 2;
2427 continue;
2428 }
2429 if (!seek_next_seg)
2430 {
2431 ccseg = CUR_SEG (fde);
2432 /* Open .eh_frame_entry section. */
2433 cfi_seg = get_cfi_seg (ccseg, ".eh_frame_entry",
2434 (SEC_ALLOC | SEC_LOAD | SEC_DATA
2435 | DWARF2_EH_FRAME_READ_ONLY),
2436 2);
2437 seek_next_seg = 1;
2438 }
2439 SET_HANDLED (fde, 1);
2440
2441 output_eh_header (fde);
2442 }
2443 }
2444 while (seek_next_seg == 2);
2445
2446 for (fde = all_fde_data; fde ; fde = fde->next)
2447 SET_HANDLED (fde, 0);
2448 }
2449#endif /* SUPPORT_COMPACT_EH */
2450
38462edf
JJ
2451 flag_traditional_format = save_flag_traditional_format;
2452 }
2453
bd5608dc 2454 cfi_sections_set = TRUE;
2f0c68f2 2455 if ((all_cfi_sections & CFI_EMIT_debug_frame) != 0)
a4447b93 2456 {
38462edf 2457 int alignment = ffs (DWARF2_ADDR_SIZE (stdoutput)) - 1;
a4447b93 2458
6303c4ae
AM
2459 if (!SUPPORT_FRAME_LINKONCE)
2460 get_cfi_seg (NULL, ".debug_frame",
2461 SEC_READONLY | SEC_DEBUGGING,
2462 alignment);
2463
72b016b4 2464 do
83e12deb 2465 {
72b016b4 2466 ccseg = NULL;
72b016b4 2467 seek_next_seg = 0;
67ed7401 2468
72b016b4 2469 for (cie = cie_root; cie; cie = cie_next)
38462edf 2470 {
72b016b4
NC
2471 cie_next = cie->next;
2472 free ((void *) cie);
38462edf 2473 }
72b016b4 2474 cie_root = NULL;
38462edf 2475
72b016b4
NC
2476 for (fde = all_fde_data; fde ; fde = fde->next)
2477 {
2f0c68f2
CM
2478 if ((fde->sections & CFI_EMIT_debug_frame) == 0)
2479 continue;
2480
6303c4ae
AM
2481 if (SUPPORT_FRAME_LINKONCE)
2482 {
2483 if (HANDLED (fde))
2484 continue;
2485 if (seek_next_seg && CUR_SEG (fde) != ccseg)
2486 {
2487 seek_next_seg = 2;
2488 continue;
2489 }
2490 if (!seek_next_seg)
2491 {
2492 ccseg = CUR_SEG (fde);
2493 /* Open .debug_frame section. */
2494 get_cfi_seg (ccseg, ".debug_frame",
2495 SEC_READONLY | SEC_DEBUGGING,
2496 alignment);
2497 seek_next_seg = 1;
2498 }
2499 SET_HANDLED (fde, 1);
72b016b4 2500 }
72b016b4
NC
2501 if (fde->end_address == NULL)
2502 {
2503 as_bad (_("open CFI at the end of file; missing .cfi_endproc directive"));
2504 fde->end_address = fde->start_address;
2505 }
2506
2507 fde->per_encoding = DW_EH_PE_omit;
2508 fde->lsda_encoding = DW_EH_PE_omit;
2509 cfi_change_reg_numbers (fde->data, ccseg);
2510 cie = select_cie_for_fde (fde, FALSE, &first, alignment);
2511 output_fde (fde, cie, FALSE, first, alignment);
2512 }
38462edf 2513 }
67ed7401 2514 while (SUPPORT_FRAME_LINKONCE && seek_next_seg == 2);
72b016b4 2515
6303c4ae
AM
2516 if (SUPPORT_FRAME_LINKONCE)
2517 for (fde = all_fde_data; fde ; fde = fde->next)
2518 SET_HANDLED (fde, 0);
38462edf 2519 }
54cfded0 2520}
0a7b15ff
JB
2521
2522#else /* TARGET_USE_CFIPOP */
d58a1929 2523
5ff2bd08 2524/* Emit an intelligible error message for missing support. */
d58a1929
RH
2525
2526static void
2527dot_cfi_dummy (int ignored ATTRIBUTE_UNUSED)
2528{
2529 as_bad (_("CFI is not supported for this target"));
2530 ignore_rest_of_line ();
2531}
2532
2533const pseudo_typeS cfi_pseudo_table[] =
2534 {
2535 { "cfi_sections", dot_cfi_dummy, 0 },
2536 { "cfi_startproc", dot_cfi_dummy, 0 },
2537 { "cfi_endproc", dot_cfi_dummy, 0 },
2f0c68f2 2538 { "cfi_fde_data", dot_cfi_dummy, 0 },
d58a1929
RH
2539 { "cfi_def_cfa", dot_cfi_dummy, 0 },
2540 { "cfi_def_cfa_register", dot_cfi_dummy, 0 },
2541 { "cfi_def_cfa_offset", dot_cfi_dummy, 0 },
2542 { "cfi_adjust_cfa_offset", dot_cfi_dummy, 0 },
2543 { "cfi_offset", dot_cfi_dummy, 0 },
2544 { "cfi_rel_offset", dot_cfi_dummy, 0 },
2545 { "cfi_register", dot_cfi_dummy, 0 },
2546 { "cfi_return_column", dot_cfi_dummy, 0 },
2547 { "cfi_restore", dot_cfi_dummy, 0 },
2548 { "cfi_undefined", dot_cfi_dummy, 0 },
2549 { "cfi_same_value", dot_cfi_dummy, 0 },
2550 { "cfi_remember_state", dot_cfi_dummy, 0 },
2551 { "cfi_restore_state", dot_cfi_dummy, 0 },
2552 { "cfi_window_save", dot_cfi_dummy, 0 },
2553 { "cfi_escape", dot_cfi_dummy, 0 },
2554 { "cfi_signal_frame", dot_cfi_dummy, 0 },
2555 { "cfi_personality", dot_cfi_dummy, 0 },
2f0c68f2 2556 { "cfi_personality_id", dot_cfi_dummy, 0 },
d58a1929
RH
2557 { "cfi_lsda", dot_cfi_dummy, 0 },
2558 { "cfi_val_encoded_addr", dot_cfi_dummy, 0 },
73e76108 2559 { "cfi_label", dot_cfi_dummy, 0 },
2f0c68f2 2560 { "cfi_inline_lsda", dot_cfi_dummy, 0 },
084303b8 2561 { "cfi_val_offset", dot_cfi_dummy, 0 },
d58a1929
RH
2562 { NULL, NULL, 0 }
2563 };
2564
0a7b15ff
JB
2565void
2566cfi_finish (void)
2567{
2568}
2569#endif /* TARGET_USE_CFIPOP */