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