-Wimplicit-fallthrough dodgy fixes
[deliverable/binutils-gdb.git] / gas / dw2gencfi.c
CommitLineData
54cfded0 1/* dw2gencfi.c - Support for generating Dwarf2 CFI information.
6f2750fe 2 Copyright (C) 2003-2016 Free Software Foundation, Inc.
54cfded0
AM
3 Contributed by Michal Ludvig <mludvig@suse.cz>
4
5 This file is part of GAS, the GNU Assembler.
6
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
ec2655a6 9 the Free Software Foundation; either version 3, or (at your option)
54cfded0
AM
10 any later version.
11
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to the Free
4b4da160
NC
19 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
20 02110-1301, USA. */
54cfded0 21
54cfded0
AM
22#include "as.h"
23#include "dw2gencfi.h"
ae424f82 24#include "subsegs.h"
38462edf 25#include "dwarf2dbg.h"
54cfded0 26
0a7b15ff 27#ifdef TARGET_USE_CFIPOP
a4447b93 28
3dd24306
DA
29/* By default, use difference expressions if DIFF_EXPR_OK is defined. */
30#ifndef CFI_DIFF_EXPR_OK
31# ifdef DIFF_EXPR_OK
32# define CFI_DIFF_EXPR_OK 1
33# else
34# define CFI_DIFF_EXPR_OK 0
35# endif
36#endif
37
2c678708 38#ifndef CFI_DIFF_LSDA_OK
72b016b4 39#define CFI_DIFF_LSDA_OK CFI_DIFF_EXPR_OK
2c678708
MK
40#endif
41
42#if CFI_DIFF_EXPR_OK == 1 && CFI_DIFF_LSDA_OK == 0
43# error "CFI_DIFF_EXPR_OK should imply CFI_DIFF_LSDA_OK"
44#endif
45
a4447b93
RH
46/* We re-use DWARF2_LINE_MIN_INSN_LENGTH for the code alignment field
47 of the CIE. Default to 1 if not otherwise specified. */
72b016b4
NC
48#ifndef DWARF2_LINE_MIN_INSN_LENGTH
49#define DWARF2_LINE_MIN_INSN_LENGTH 1
a4447b93
RH
50#endif
51
8c9b70b1
RH
52/* By default, use 32-bit relocations from .eh_frame into .text. */
53#ifndef DWARF2_FDE_RELOC_SIZE
72b016b4 54#define DWARF2_FDE_RELOC_SIZE 4
8c9b70b1
RH
55#endif
56
57/* By default, use a read-only .eh_frame section. */
58#ifndef DWARF2_EH_FRAME_READ_ONLY
72b016b4 59#define DWARF2_EH_FRAME_READ_ONLY SEC_READONLY
8c9b70b1
RH
60#endif
61
9393cb0d 62#ifndef EH_FRAME_ALIGNMENT
72b016b4 63#define EH_FRAME_ALIGNMENT (bfd_get_arch_size (stdoutput) == 64 ? 3 : 2)
9393cb0d
JJ
64#endif
65
a4447b93 66#ifndef tc_cfi_frame_initial_instructions
72b016b4 67#define tc_cfi_frame_initial_instructions() ((void)0)
a4447b93
RH
68#endif
69
1bce6bd8
PB
70#ifndef tc_cfi_startproc
71# define tc_cfi_startproc() ((void)0)
72#endif
73
74#ifndef tc_cfi_endproc
6e789b26 75# define tc_cfi_endproc(fde) ((void) (fde))
1bce6bd8
PB
76#endif
77
2f0c68f2
CM
78#define EH_FRAME_LINKONCE (SUPPORT_FRAME_LINKONCE || compact_eh)
79
38462edf 80#ifndef DWARF2_FORMAT
72b016b4 81#define DWARF2_FORMAT(SEC) dwarf2_format_32bit
38462edf
JJ
82#endif
83
f1c4cc75 84#ifndef DWARF2_ADDR_SIZE
72b016b4 85#define DWARF2_ADDR_SIZE(bfd) (bfd_arch_bits_per_address (bfd) / 8)
f1c4cc75
RH
86#endif
87
2f0c68f2 88#if MULTIPLE_FRAME_SECTIONS
6303c4ae 89#define CUR_SEG(structp) structp->cur_seg
34bca508 90#define SET_CUR_SEG(structp, seg) structp->cur_seg = seg
6303c4ae
AM
91#define HANDLED(structp) structp->handled
92#define SET_HANDLED(structp, val) structp->handled = val
93#else
94#define CUR_SEG(structp) NULL
95#define SET_CUR_SEG(structp, seg) (void) (0 && seg)
96#define HANDLED(structp) 0
97#define SET_HANDLED(structp, val) (void) (0 && val)
98#endif
99
2f0c68f2
CM
100#ifndef tc_cfi_reloc_for_encoding
101#define tc_cfi_reloc_for_encoding(e) BFD_RELOC_NONE
102#endif
103
72b016b4
NC
104/* Private segment collection list. */
105struct dwcfi_seg_list
106{
107 segT seg;
108 int subseg;
109 char * seg_name;
110};
111
2f0c68f2
CM
112#ifdef SUPPORT_COMPACT_EH
113static bfd_boolean compact_eh;
114#else
115#define compact_eh 0
116#endif
72b016b4
NC
117
118static struct hash_control *dwcfi_hash;
2f0c68f2
CM
119\f
120/* Emit a single byte into the current segment. */
121
122static inline void
123out_one (int byte)
124{
125 FRAG_APPEND_1_CHAR (byte);
126}
127
128/* Emit a two-byte word into the current segment. */
129
130static inline void
131out_two (int data)
132{
133 md_number_to_chars (frag_more (2), data, 2);
134}
135
136/* Emit a four byte word into the current segment. */
137
138static inline void
139out_four (int data)
140{
141 md_number_to_chars (frag_more (4), data, 4);
142}
143
144/* Emit an unsigned "little-endian base 128" number. */
145
146static void
147out_uleb128 (addressT value)
148{
149 output_leb128 (frag_more (sizeof_leb128 (value, 0)), value, 0);
150}
151
152/* Emit an unsigned "little-endian base 128" number. */
153
154static void
155out_sleb128 (offsetT value)
156{
157 output_leb128 (frag_more (sizeof_leb128 (value, 1)), value, 1);
158}
159
160static offsetT
161encoding_size (unsigned char encoding)
162{
163 if (encoding == DW_EH_PE_omit)
164 return 0;
165 switch (encoding & 0x7)
166 {
167 case 0:
168 return bfd_get_arch_size (stdoutput) == 64 ? 8 : 4;
169 case DW_EH_PE_udata2:
170 return 2;
171 case DW_EH_PE_udata4:
172 return 4;
173 case DW_EH_PE_udata8:
174 return 8;
175 default:
176 abort ();
177 }
178}
179
180/* Emit expression EXP in ENCODING. If EMIT_ENCODING is true, first
181 emit a byte containing ENCODING. */
182
183static void
184emit_expr_encoded (expressionS *exp, int encoding, bfd_boolean emit_encoding)
185{
186 offsetT size = encoding_size (encoding);
187 bfd_reloc_code_real_type code;
188
189 if (encoding == DW_EH_PE_omit)
190 return;
72b016b4 191
2f0c68f2
CM
192 if (emit_encoding)
193 out_one (encoding);
194
195 code = tc_cfi_reloc_for_encoding (encoding);
196 if (code != BFD_RELOC_NONE)
197 {
198 reloc_howto_type *howto = bfd_reloc_type_lookup (stdoutput, code);
199 char *p = frag_more (size);
200 md_number_to_chars (p, 0, size);
201 fix_new (frag_now, p - frag_now->fr_literal, size, exp->X_add_symbol,
202 exp->X_add_number, howto->pc_relative, code);
203 }
204 else if ((encoding & 0x70) == DW_EH_PE_pcrel)
205 {
206#if CFI_DIFF_EXPR_OK
207 expressionS tmp = *exp;
208 tmp.X_op = O_subtract;
209 tmp.X_op_symbol = symbol_temp_new_now ();
210 emit_expr (&tmp, size);
211#elif defined (tc_cfi_emit_pcrel_expr)
212 tc_cfi_emit_pcrel_expr (exp, size);
213#else
214 abort ();
215#endif
216 }
217 else
218 emit_expr (exp, size);
219}
220\f
72b016b4
NC
221/* Build based on segment the derived .debug_...
222 segment name containing origin segment's postfix name part. */
223
224static char *
225get_debugseg_name (segT seg, const char *base_name)
226{
227 const char *name;
228
229 if (!seg)
230 name = "";
231 else
232 {
233 const char * dollar;
234 const char * dot;
235
236 name = bfd_get_section_name (stdoutput, seg);
237
238 dollar = strchr (name, '$');
239 dot = strchr (name + 1, '.');
240
241 if (!dollar && !dot)
2f0c68f2
CM
242 {
243 if (!strcmp (base_name, ".eh_frame_entry")
244 && strcmp (name, ".text") != 0)
245 return concat (base_name, ".", name, NULL);
246
247 name = "";
248 }
72b016b4
NC
249 else if (!dollar)
250 name = dot;
251 else if (!dot)
252 name = dollar;
253 else if (dot < dollar)
254 name = dot;
255 else
256 name = dollar;
257 }
258
259 return concat (base_name, name, NULL);
260}
261
262/* Allocate a dwcfi_seg_list structure. */
263
264static struct dwcfi_seg_list *
265alloc_debugseg_item (segT seg, int subseg, char *name)
266{
267 struct dwcfi_seg_list *r;
268
269 r = (struct dwcfi_seg_list *)
270 xmalloc (sizeof (struct dwcfi_seg_list) + strlen (name));
271 r->seg = seg;
272 r->subseg = subseg;
273 r->seg_name = name;
274 return r;
275}
276
277static segT
278is_now_linkonce_segment (void)
279{
2f0c68f2
CM
280 if (compact_eh)
281 return now_seg;
282
72b016b4
NC
283 if ((bfd_get_section_flags (stdoutput, now_seg)
284 & (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD
285 | SEC_LINK_DUPLICATES_ONE_ONLY | SEC_LINK_DUPLICATES_SAME_SIZE
286 | SEC_LINK_DUPLICATES_SAME_CONTENTS)) != 0)
287 return now_seg;
72b016b4
NC
288 return NULL;
289}
290
291/* Generate debug... segment with same linkonce properties
292 of based segment. */
293
294static segT
295make_debug_seg (segT cseg, char *name, int sflags)
296{
297 segT save_seg = now_seg;
298 int save_subseg = now_subseg;
299 segT r;
300 flagword flags;
301
302 r = subseg_new (name, 0);
303
304 /* Check if code segment is marked as linked once. */
305 if (!cseg)
306 flags = 0;
307 else
308 flags = bfd_get_section_flags (stdoutput, cseg)
309 & (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD
83e12deb
MR
310 | SEC_LINK_DUPLICATES_ONE_ONLY | SEC_LINK_DUPLICATES_SAME_SIZE
311 | SEC_LINK_DUPLICATES_SAME_CONTENTS);
72b016b4
NC
312
313 /* Add standard section flags. */
314 flags |= sflags;
315
316 /* Apply possibly linked once flags to new generated segment, too. */
317 if (!bfd_set_section_flags (stdoutput, r, flags))
318 as_bad (_("bfd_set_section_flags: %s"),
319 bfd_errmsg (bfd_get_error ()));
320
321 /* Restore to previous segment. */
322 if (save_seg != NULL)
323 subseg_set (save_seg, save_subseg);
324 return r;
325}
326
327static void
328dwcfi_hash_insert (const char *name, struct dwcfi_seg_list *item)
329{
330 const char *error_string;
331
332 if ((error_string = hash_jam (dwcfi_hash, name, (char *) item)))
333 as_fatal (_("Inserting \"%s\" into structure table failed: %s"),
334 name, error_string);
335}
336
337static struct dwcfi_seg_list *
338dwcfi_hash_find (char *name)
339{
340 return (struct dwcfi_seg_list *) hash_find (dwcfi_hash, name);
341}
342
343static struct dwcfi_seg_list *
344dwcfi_hash_find_or_make (segT cseg, const char *base_name, int flags)
345{
346 struct dwcfi_seg_list *item;
347 char *name;
348
349 /* Initialize dwcfi_hash once. */
350 if (!dwcfi_hash)
351 dwcfi_hash = hash_new ();
352
353 name = get_debugseg_name (cseg, base_name);
354
355 item = dwcfi_hash_find (name);
356 if (!item)
357 {
358 item = alloc_debugseg_item (make_debug_seg (cseg, name, flags), 0, name);
359
360 dwcfi_hash_insert (item->seg_name, item);
361 }
362 else
363 free (name);
364
365 return item;
366}
367
3251495b
RH
368/* ??? Share this with dwarf2cfg.c. */
369#ifndef TC_DWARF2_EMIT_OFFSET
370#define TC_DWARF2_EMIT_OFFSET generic_dwarf2_emit_offset
371
372/* Create an offset to .dwarf2_*. */
373
374static void
375generic_dwarf2_emit_offset (symbolS *symbol, unsigned int size)
376{
377 expressionS exp;
378
379 exp.X_op = O_symbol;
380 exp.X_add_symbol = symbol;
381 exp.X_add_number = 0;
382 emit_expr (&exp, size);
383}
384#endif
385
72b016b4
NC
386struct cfi_escape_data
387{
1e9cc1c2
NC
388 struct cfi_escape_data *next;
389 expressionS exp;
390};
a4447b93 391
a4447b93 392struct cie_entry
39b82151 393{
a4447b93 394 struct cie_entry *next;
2f0c68f2 395#if MULTIPLE_FRAME_SECTIONS
72b016b4 396 segT cur_seg;
67ed7401 397#endif
a4447b93
RH
398 symbolS *start_address;
399 unsigned int return_column;
63752a75 400 unsigned int signal_frame;
2f0c68f2 401 unsigned char fde_encoding;
9b8ae42e
JJ
402 unsigned char per_encoding;
403 unsigned char lsda_encoding;
404 expressionS personality;
a4447b93 405 struct cfi_insn_data *first, *last;
39b82151
ML
406};
407
a4447b93 408/* List of FDE entries. */
72b016b4 409
af385746 410struct fde_entry *all_fde_data;
a4447b93 411static struct fde_entry **last_fde_data = &all_fde_data;
39b82151
ML
412
413/* List of CIEs so that they could be reused. */
414static struct cie_entry *cie_root;
415
fa87b337
RH
416/* Stack of old CFI data, for save/restore. */
417struct cfa_save_data
418{
419 struct cfa_save_data *next;
420 offsetT cfa_offset;
421};
422
ae424f82
JJ
423/* Current open FDE entry. */
424struct frch_cfi_data
425{
426 struct fde_entry *cur_fde_data;
427 symbolS *last_address;
428 offsetT cur_cfa_offset;
429 struct cfa_save_data *cfa_save_stack;
430};
a4447b93
RH
431\f
432/* Construct a new FDE structure and add it to the end of the fde list. */
54cfded0 433
a4447b93
RH
434static struct fde_entry *
435alloc_fde_entry (void)
436{
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 ();
3d3424e9
MF
1272 if (cfi_sections_set
1273 && (sections & (CFI_EMIT_eh_frame | CFI_EMIT_eh_frame_compact))
1274 && (cfi_sections & (CFI_EMIT_eh_frame | CFI_EMIT_eh_frame_compact))
1275 != (sections & (CFI_EMIT_eh_frame | CFI_EMIT_eh_frame_compact)))
2f0c68f2 1276 as_bad (_("inconsistent uses of .cfi_sections"));
38462edf
JJ
1277 cfi_sections = sections;
1278}
1279
54cfded0 1280static void
a4447b93 1281dot_cfi_startproc (int ignored ATTRIBUTE_UNUSED)
54cfded0 1282{
a4447b93 1283 int simple = 0;
39b82151 1284
ae424f82 1285 if (frchain_now->frch_cfi_data != NULL)
54cfded0
AM
1286 {
1287 as_bad (_("previous CFI entry not closed (missing .cfi_endproc)"));
7c9c8381 1288 ignore_rest_of_line ();
54cfded0
AM
1289 return;
1290 }
1291
a4447b93 1292 cfi_new_fde (symbol_temp_new_now ());
39b82151 1293
a4447b93 1294 SKIP_WHITESPACE ();
d02603dc 1295 if (is_name_beginner (*input_line_pointer) || *input_line_pointer == '"')
a4447b93 1296 {
d02603dc 1297 char * saved_ilp = input_line_pointer;
a4447b93 1298 char *name, c;
54cfded0 1299
d02603dc 1300 c = get_symbol_name (& name);
54cfded0 1301
a4447b93
RH
1302 if (strcmp (name, "simple") == 0)
1303 {
1304 simple = 1;
d02603dc 1305 restore_line_pointer (c);
a4447b93
RH
1306 }
1307 else
d02603dc 1308 input_line_pointer = saved_ilp;
a4447b93
RH
1309 }
1310 demand_empty_rest_of_line ();
1311
bd5608dc 1312 cfi_sections_set = TRUE;
2f0c68f2
CM
1313 all_cfi_sections |= cfi_sections;
1314 cfi_set_sections ();
ae424f82 1315 frchain_now->frch_cfi_data->cur_cfa_offset = 0;
a4447b93 1316 if (!simple)
39b82151 1317 tc_cfi_frame_initial_instructions ();
1bce6bd8
PB
1318
1319 if ((cfi_sections & CFI_EMIT_target) != 0)
1320 tc_cfi_startproc ();
54cfded0
AM
1321}
1322
a4447b93
RH
1323static void
1324dot_cfi_endproc (int ignored ATTRIBUTE_UNUSED)
1325{
ae424f82 1326 if (frchain_now->frch_cfi_data == NULL)
a4447b93
RH
1327 {
1328 as_bad (_(".cfi_endproc without corresponding .cfi_startproc"));
7c9c8381 1329 ignore_rest_of_line ();
a4447b93
RH
1330 return;
1331 }
54cfded0 1332
2f0c68f2 1333 last_fde = frchain_now->frch_cfi_data->cur_fde_data;
1bce6bd8 1334
a4447b93 1335 cfi_end_fde (symbol_temp_new_now ());
7c9c8381
JB
1336
1337 demand_empty_rest_of_line ();
1bce6bd8 1338
bd5608dc 1339 cfi_sections_set = TRUE;
1bce6bd8 1340 if ((cfi_sections & CFI_EMIT_target) != 0)
2f0c68f2 1341 tc_cfi_endproc (last_fde);
a4447b93 1342}
39b82151 1343
2f0c68f2
CM
1344static segT
1345get_cfi_seg (segT cseg, const char *base, flagword flags, int align)
54cfded0 1346{
2f0c68f2
CM
1347 /* Exclude .debug_frame sections for Compact EH. */
1348 if (SUPPORT_FRAME_LINKONCE || ((flags & SEC_DEBUGGING) == 0 && compact_eh))
1349 {
1350 struct dwcfi_seg_list *l;
1351
1352 l = dwcfi_hash_find_or_make (cseg, base, flags);
1353
1354 cseg = l->seg;
1355 subseg_set (cseg, l->subseg);
1356 }
1357 else
1358 {
1359 cseg = subseg_new (base, 0);
1360 bfd_set_section_flags (stdoutput, cseg, flags);
1361 }
1362 record_alignment (cseg, align);
1363 return cseg;
a4447b93 1364}
54cfded0 1365
2f0c68f2
CM
1366#if SUPPORT_COMPACT_EH
1367static void
1368dot_cfi_personality_id (int ignored ATTRIBUTE_UNUSED)
1369{
1370 struct fde_entry *fde;
54cfded0 1371
2f0c68f2
CM
1372 if (frchain_now->frch_cfi_data == NULL)
1373 {
1374 as_bad (_("CFI instruction used without previous .cfi_startproc"));
1375 ignore_rest_of_line ();
1376 return;
1377 }
1378
1379 fde = frchain_now->frch_cfi_data->cur_fde_data;
1380 fde->personality_id = cfi_parse_const ();
1381 demand_empty_rest_of_line ();
1382
1383 if (fde->personality_id == 0 || fde->personality_id > 3)
1384 {
1385 as_bad (_("wrong argument to .cfi_personality_id"));
1386 return;
1387 }
1388}
1389
1390static void
1391dot_cfi_fde_data (int ignored ATTRIBUTE_UNUSED)
a4447b93 1392{
2f0c68f2
CM
1393 if (frchain_now->frch_cfi_data == NULL)
1394 {
1395 as_bad (_(".cfi_fde_data without corresponding .cfi_startproc"));
1396 ignore_rest_of_line ();
1397 return;
1398 }
1399
1400 last_fde = frchain_now->frch_cfi_data->cur_fde_data;
1401
bd5608dc 1402 cfi_sections_set = TRUE;
2f0c68f2
CM
1403 if ((cfi_sections & CFI_EMIT_target) != 0
1404 || (cfi_sections & CFI_EMIT_eh_frame_compact) != 0)
1405 {
1406 struct cfi_escape_data *head, **tail, *e;
1407 int num_ops = 0;
1408
1409 tail = &head;
1410 if (!is_it_end_of_statement ())
1411 {
1412 num_ops = 0;
1413 do
1414 {
add39d23 1415 e = XNEW (struct cfi_escape_data);
2f0c68f2
CM
1416 do_parse_cons_expression (&e->exp, 1);
1417 *tail = e;
1418 tail = &e->next;
1419 num_ops++;
1420 }
1421 while (*input_line_pointer++ == ',');
1422 --input_line_pointer;
1423 }
1424 *tail = NULL;
1425
1426 if (last_fde->lsda_encoding != DW_EH_PE_omit)
1427 last_fde->eh_header_type = EH_COMPACT_HAS_LSDA;
1428 else if (num_ops <= 3 && last_fde->per_encoding == DW_EH_PE_omit)
1429 last_fde->eh_header_type = EH_COMPACT_INLINE;
1430 else
1431 last_fde->eh_header_type = EH_COMPACT_OUTLINE;
1432
1433 if (last_fde->eh_header_type == EH_COMPACT_INLINE)
1434 num_ops = 3;
1435
1436 last_fde->eh_data_size = num_ops;
add39d23 1437 last_fde->eh_data = XNEWVEC (bfd_byte, num_ops);
2f0c68f2
CM
1438 num_ops = 0;
1439 while (head)
1440 {
1441 e = head;
1442 head = e->next;
1443 last_fde->eh_data[num_ops++] = e->exp.X_add_number;
1444 free (e);
1445 }
1446 if (last_fde->eh_header_type == EH_COMPACT_INLINE)
1447 while (num_ops < 3)
1448 last_fde->eh_data[num_ops++] = tc_compact_eh_opcode_stop;
1449 }
1450
1451 demand_empty_rest_of_line ();
a4447b93 1452}
54cfded0 1453
2f0c68f2
CM
1454/* Function to emit the compact unwinding opcodes stored in the
1455 fde's eh_data field. The end of the opcode data will be
1456 padded to the value in align. */
54cfded0 1457
2f0c68f2
CM
1458static void
1459output_compact_unwind_data (struct fde_entry *fde, int align)
a4447b93 1460{
2f0c68f2
CM
1461 int data_size = fde->eh_data_size + 2;
1462 int align_padding;
1463 int amask;
1464 char *p;
1465
1466 fde->eh_loc = symbol_temp_new_now ();
1467
1468 p = frag_more (1);
1469 if (fde->personality_id != 0)
1470 *p = fde->personality_id;
1471 else if (fde->per_encoding != DW_EH_PE_omit)
1472 {
1473 *p = 0;
1474 emit_expr_encoded (&fde->personality, fde->per_encoding, FALSE);
1475 data_size += encoding_size (fde->per_encoding);
1476 }
1477 else
1478 *p = 1;
1479
1480 amask = (1 << align) - 1;
1481 align_padding = ((data_size + amask) & ~amask) - data_size;
1482
1483 p = frag_more (fde->eh_data_size + 1 + align_padding);
1484 memcpy (p, fde->eh_data, fde->eh_data_size);
1485 p += fde->eh_data_size;
1486
1487 while (align_padding-- > 0)
1488 *(p++) = tc_compact_eh_opcode_pad;
1489
1490 *(p++) = tc_compact_eh_opcode_stop;
1491 fde->eh_header_type = EH_COMPACT_OUTLINE_DONE;
a4447b93
RH
1492}
1493
2f0c68f2
CM
1494/* Handle the .cfi_inline_lsda directive. */
1495static void
1496dot_cfi_inline_lsda (int ignored ATTRIBUTE_UNUSED)
1497{
1498 segT ccseg;
1499 int align;
1500 long max_alignment = 28;
1501
1502 if (!last_fde)
1503 {
1504 as_bad (_("unexpected .cfi_inline_lsda"));
1505 ignore_rest_of_line ();
1506 return;
1507 }
1508
1509 if ((last_fde->sections & CFI_EMIT_eh_frame_compact) == 0)
1510 {
1511 as_bad (_(".cfi_inline_lsda not valid for this frame"));
1512 ignore_rest_of_line ();
1513 return;
1514 }
1515
1516 if (last_fde->eh_header_type != EH_COMPACT_UNKNOWN
1517 && last_fde->eh_header_type != EH_COMPACT_HAS_LSDA)
1518 {
1519 as_bad (_(".cfi_inline_lsda seen for frame without .cfi_lsda"));
1520 ignore_rest_of_line ();
1521 return;
1522 }
1523
1524#ifdef md_flush_pending_output
1525 md_flush_pending_output ();
1526#endif
1527
1528 align = get_absolute_expression ();
1529 if (align > max_alignment)
1530 {
1531 align = max_alignment;
1532 as_bad (_("Alignment too large: %d. assumed."), align);
1533 }
1534 else if (align < 0)
1535 {
1536 as_warn (_("Alignment negative: 0 assumed."));
1537 align = 0;
1538 }
1539
1540 demand_empty_rest_of_line ();
1541 ccseg = CUR_SEG (last_fde);
54cfded0 1542
2f0c68f2
CM
1543 /* Open .gnu_extab section. */
1544 get_cfi_seg (ccseg, ".gnu_extab",
1545 (SEC_ALLOC | SEC_LOAD | SEC_DATA
1546 | DWARF2_EH_FRAME_READ_ONLY),
1547 1);
1548
1549 frag_align (align, 0, 0);
1550 record_alignment (now_seg, align);
1551 if (last_fde->eh_header_type == EH_COMPACT_HAS_LSDA)
1552 output_compact_unwind_data (last_fde, align);
1553
1554 last_fde = NULL;
1555
1556 return;
1557}
1558#else /* !SUPPORT_COMPACT_EH */
a4447b93 1559static void
2f0c68f2 1560dot_cfi_inline_lsda (int ignored ATTRIBUTE_UNUSED)
a4447b93 1561{
2f0c68f2
CM
1562 as_bad (_(".cfi_inline_lsda is not supported for this target"));
1563 ignore_rest_of_line ();
54cfded0
AM
1564}
1565
a4447b93 1566static void
2f0c68f2 1567dot_cfi_fde_data (int ignored ATTRIBUTE_UNUSED)
54cfded0 1568{
2f0c68f2
CM
1569 as_bad (_(".cfi_fde_data is not supported for this target"));
1570 ignore_rest_of_line ();
a4447b93 1571}
54cfded0 1572
2f0c68f2
CM
1573static void
1574dot_cfi_personality_id (int ignored ATTRIBUTE_UNUSED)
1575{
1576 as_bad (_(".cfi_personality_id is not supported for this target"));
1577 ignore_rest_of_line ();
1578}
1579#endif
1580\f
a4447b93
RH
1581static void
1582output_cfi_insn (struct cfi_insn_data *insn)
1583{
1584 offsetT offset;
1585 unsigned int regno;
54cfded0 1586
a4447b93 1587 switch (insn->insn)
54cfded0 1588 {
a4447b93
RH
1589 case DW_CFA_advance_loc:
1590 {
1591 symbolS *from = insn->u.ll.lab1;
1592 symbolS *to = insn->u.ll.lab2;
1593
1594 if (symbol_get_frag (to) == symbol_get_frag (from))
1595 {
1596 addressT delta = S_GET_VALUE (to) - S_GET_VALUE (from);
1597 addressT scaled = delta / DWARF2_LINE_MIN_INSN_LENGTH;
1598
1599 if (scaled <= 0x3F)
1600 out_one (DW_CFA_advance_loc + scaled);
395e8345 1601 else if (scaled <= 0xFF)
a4447b93 1602 {
9b8ae42e 1603 out_one (DW_CFA_advance_loc1);
395e8345 1604 out_one (scaled);
a4447b93 1605 }
395e8345 1606 else if (scaled <= 0xFFFF)
a4447b93 1607 {
9b8ae42e 1608 out_one (DW_CFA_advance_loc2);
395e8345 1609 out_two (scaled);
a4447b93
RH
1610 }
1611 else
1612 {
9b8ae42e 1613 out_one (DW_CFA_advance_loc4);
395e8345 1614 out_four (scaled);
a4447b93
RH
1615 }
1616 }
1617 else
1618 {
1619 expressionS exp;
1620
1621 exp.X_op = O_subtract;
1622 exp.X_add_symbol = to;
1623 exp.X_op_symbol = from;
1624 exp.X_add_number = 0;
1625
1626 /* The code in ehopt.c expects that one byte of the encoding
1627 is already allocated to the frag. This comes from the way
1628 that it scans the .eh_frame section looking first for the
1629 .byte DW_CFA_advance_loc4. */
1fbfe785 1630 *frag_more (1) = DW_CFA_advance_loc4;
a4447b93
RH
1631
1632 frag_var (rs_cfa, 4, 0, DWARF2_LINE_MIN_INSN_LENGTH << 3,
1633 make_expr_symbol (&exp), frag_now_fix () - 1,
1634 (char *) frag_now);
1635 }
1636 }
1637 break;
1638
1639 case DW_CFA_def_cfa:
1640 offset = insn->u.ri.offset;
1641 if (offset < 0)
54cfded0 1642 {
a4447b93
RH
1643 out_one (DW_CFA_def_cfa_sf);
1644 out_uleb128 (insn->u.ri.reg);
dcb45a06 1645 out_sleb128 (offset / DWARF2_CIE_DATA_ALIGNMENT);
54cfded0
AM
1646 }
1647 else
1648 {
a4447b93
RH
1649 out_one (DW_CFA_def_cfa);
1650 out_uleb128 (insn->u.ri.reg);
1651 out_uleb128 (offset);
54cfded0
AM
1652 }
1653 break;
1654
a4447b93 1655 case DW_CFA_def_cfa_register:
2be24b54
ML
1656 case DW_CFA_undefined:
1657 case DW_CFA_same_value:
1658 out_one (insn->insn);
1659 out_uleb128 (insn->u.r);
54cfded0
AM
1660 break;
1661
a4447b93
RH
1662 case DW_CFA_def_cfa_offset:
1663 offset = insn->u.i;
1664 if (offset < 0)
1665 {
1666 out_one (DW_CFA_def_cfa_offset_sf);
dcb45a06 1667 out_sleb128 (offset / DWARF2_CIE_DATA_ALIGNMENT);
a4447b93
RH
1668 }
1669 else
1670 {
1671 out_one (DW_CFA_def_cfa_offset);
1672 out_uleb128 (offset);
1673 }
54cfded0
AM
1674 break;
1675
2be24b54
ML
1676 case DW_CFA_restore:
1677 regno = insn->u.r;
1678 if (regno <= 0x3F)
1679 {
1680 out_one (DW_CFA_restore + regno);
1681 }
1682 else
1683 {
1684 out_one (DW_CFA_restore_extended);
1685 out_uleb128 (regno);
1686 }
1687 break;
1688
a4447b93
RH
1689 case DW_CFA_offset:
1690 regno = insn->u.ri.reg;
1691 offset = insn->u.ri.offset / DWARF2_CIE_DATA_ALIGNMENT;
1692 if (offset < 0)
1693 {
1233ae62 1694 out_one (DW_CFA_offset_extended_sf);
a4447b93
RH
1695 out_uleb128 (regno);
1696 out_sleb128 (offset);
1697 }
1698 else if (regno <= 0x3F)
1699 {
1700 out_one (DW_CFA_offset + regno);
1701 out_uleb128 (offset);
1702 }
54cfded0
AM
1703 else
1704 {
a4447b93
RH
1705 out_one (DW_CFA_offset_extended);
1706 out_uleb128 (regno);
1707 out_uleb128 (offset);
54cfded0 1708 }
54cfded0
AM
1709 break;
1710
084303b8
AK
1711 case DW_CFA_val_offset:
1712 regno = insn->u.ri.reg;
1713 offset = insn->u.ri.offset / DWARF2_CIE_DATA_ALIGNMENT;
1714 if (offset < 0)
1715 {
1716 out_one (DW_CFA_val_offset_sf);
1717 out_uleb128 (regno);
1718 out_sleb128 (offset);
1719 }
1720 else
1721 {
1722 out_one (DW_CFA_val_offset);
1723 out_uleb128 (regno);
1724 out_uleb128 (offset);
1725 }
1726 break;
1727
a4447b93
RH
1728 case DW_CFA_register:
1729 out_one (DW_CFA_register);
1730 out_uleb128 (insn->u.rr.reg1);
1731 out_uleb128 (insn->u.rr.reg2);
39b82151
ML
1732 break;
1733
2be24b54
ML
1734 case DW_CFA_remember_state:
1735 case DW_CFA_restore_state:
2be24b54 1736 out_one (insn->insn);
54cfded0
AM
1737 break;
1738
364b6d8b
JJ
1739 case DW_CFA_GNU_window_save:
1740 out_one (DW_CFA_GNU_window_save);
1741 break;
1742
cdfbf930
RH
1743 case CFI_escape:
1744 {
1745 struct cfi_escape_data *e;
1746 for (e = insn->u.esc; e ; e = e->next)
1747 emit_expr (&e->exp, 1);
1748 break;
1749 }
1750
f1c4cc75
RH
1751 case CFI_val_encoded_addr:
1752 {
83e12deb 1753 unsigned encoding = insn->u.ea.encoding;
2f0c68f2 1754 offsetT enc_size;
f1c4cc75
RH
1755
1756 if (encoding == DW_EH_PE_omit)
1757 break;
1758 out_one (DW_CFA_val_expression);
1759 out_uleb128 (insn->u.ea.reg);
1760
83e12deb 1761 switch (encoding & 0x7)
f1c4cc75
RH
1762 {
1763 case DW_EH_PE_absptr:
2f0c68f2 1764 enc_size = DWARF2_ADDR_SIZE (stdoutput);
f1c4cc75
RH
1765 break;
1766 case DW_EH_PE_udata2:
2f0c68f2 1767 enc_size = 2;
f1c4cc75
RH
1768 break;
1769 case DW_EH_PE_udata4:
2f0c68f2 1770 enc_size = 4;
f1c4cc75
RH
1771 break;
1772 case DW_EH_PE_udata8:
2f0c68f2 1773 enc_size = 8;
f1c4cc75
RH
1774 break;
1775 default:
1776 abort ();
1777 }
1778
1779 /* If the user has requested absolute encoding,
1780 then use the smaller DW_OP_addr encoding. */
1781 if (insn->u.ea.encoding == DW_EH_PE_absptr)
1782 {
2f0c68f2 1783 out_uleb128 (1 + enc_size);
f1c4cc75
RH
1784 out_one (DW_OP_addr);
1785 }
1786 else
1787 {
2f0c68f2 1788 out_uleb128 (1 + 1 + enc_size);
f1c4cc75
RH
1789 out_one (DW_OP_GNU_encoded_addr);
1790 out_one (encoding);
1791
1792 if ((encoding & 0x70) == DW_EH_PE_pcrel)
1793 {
1794#if CFI_DIFF_EXPR_OK
1795 insn->u.ea.exp.X_op = O_subtract;
1796 insn->u.ea.exp.X_op_symbol = symbol_temp_new_now ();
1797#elif defined (tc_cfi_emit_pcrel_expr)
2f0c68f2 1798 tc_cfi_emit_pcrel_expr (&insn->u.ea.exp, enc_size);
f1c4cc75
RH
1799 break;
1800#else
1801 abort ();
1802#endif
1803 }
1804 }
2f0c68f2 1805 emit_expr (&insn->u.ea.exp, enc_size);
f1c4cc75
RH
1806 }
1807 break;
72b016b4 1808
69602580
JB
1809 case CFI_label:
1810 colon (insn->u.sym_name);
1811 break;
1812
54cfded0 1813 default:
a4447b93 1814 abort ();
54cfded0 1815 }
54cfded0
AM
1816}
1817
1818static void
38462edf 1819output_cie (struct cie_entry *cie, bfd_boolean eh_frame, int align)
54cfded0 1820{
a4447b93 1821 symbolS *after_size_address, *end_address;
7c0295b1 1822 expressionS exp;
a4447b93 1823 struct cfi_insn_data *i;
9b8ae42e 1824 offsetT augmentation_size;
8c9b70b1 1825 int enc;
38462edf 1826 enum dwarf2_format fmt = DWARF2_FORMAT (now_seg);
a4447b93
RH
1827
1828 cie->start_address = symbol_temp_new_now ();
1829 after_size_address = symbol_temp_make ();
1830 end_address = symbol_temp_make ();
1831
1832 exp.X_op = O_subtract;
1833 exp.X_add_symbol = end_address;
1834 exp.X_op_symbol = after_size_address;
1835 exp.X_add_number = 0;
1836
38462edf
JJ
1837 if (eh_frame || fmt == dwarf2_format_32bit)
1838 emit_expr (&exp, 4); /* Length. */
1839 else
1840 {
1841 if (fmt == dwarf2_format_64bit)
1842 out_four (-1);
1843 emit_expr (&exp, 8); /* Length. */
1844 }
a4447b93 1845 symbol_set_value_now (after_size_address);
38462edf
JJ
1846 if (eh_frame)
1847 out_four (0); /* CIE id. */
1848 else
1849 {
1850 out_four (-1); /* CIE id. */
1851 if (fmt != dwarf2_format_32bit)
1852 out_four (-1);
1853 }
289040ca 1854 out_one (DW_CIE_VERSION); /* Version. */
38462edf
JJ
1855 if (eh_frame)
1856 {
1857 out_one ('z'); /* Augmentation. */
1858 if (cie->per_encoding != DW_EH_PE_omit)
1859 out_one ('P');
1860 if (cie->lsda_encoding != DW_EH_PE_omit)
1861 out_one ('L');
1862 out_one ('R');
38462edf 1863 }
d905c788
TS
1864 if (cie->signal_frame)
1865 out_one ('S');
a4447b93 1866 out_one (0);
289040ca
NC
1867 out_uleb128 (DWARF2_LINE_MIN_INSN_LENGTH); /* Code alignment. */
1868 out_sleb128 (DWARF2_CIE_DATA_ALIGNMENT); /* Data alignment. */
0da76f83
NC
1869 if (DW_CIE_VERSION == 1) /* Return column. */
1870 out_one (cie->return_column);
1871 else
1872 out_uleb128 (cie->return_column);
38462edf
JJ
1873 if (eh_frame)
1874 {
1875 augmentation_size = 1 + (cie->lsda_encoding != DW_EH_PE_omit);
1876 if (cie->per_encoding != DW_EH_PE_omit)
1877 augmentation_size += 1 + encoding_size (cie->per_encoding);
1878 out_uleb128 (augmentation_size); /* Augmentation size. */
4e4e1355 1879
2f0c68f2 1880 emit_expr_encoded (&cie->personality, cie->per_encoding, TRUE);
4e4e1355
TS
1881
1882 if (cie->lsda_encoding != DW_EH_PE_omit)
1883 out_one (cie->lsda_encoding);
9b8ae42e 1884 }
8c9b70b1
RH
1885
1886 switch (DWARF2_FDE_RELOC_SIZE)
1887 {
1888 case 2:
1889 enc = DW_EH_PE_sdata2;
1890 break;
1891 case 4:
1892 enc = DW_EH_PE_sdata4;
1893 break;
1894 case 8:
1895 enc = DW_EH_PE_sdata8;
1896 break;
1897 default:
1898 abort ();
1899 }
3dd24306 1900#if CFI_DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr
8c9b70b1 1901 enc |= DW_EH_PE_pcrel;
364b6d8b 1902#endif
2f0c68f2
CM
1903#ifdef DWARF2_FDE_RELOC_ENCODING
1904 /* Allow target to override encoding. */
1905 enc = DWARF2_FDE_RELOC_ENCODING (enc);
1906#endif
1907 cie->fde_encoding = enc;
38462edf
JJ
1908 if (eh_frame)
1909 out_one (enc);
a4447b93
RH
1910
1911 if (cie->first)
72b016b4
NC
1912 {
1913 for (i = cie->first; i != cie->last; i = i->next)
83e12deb 1914 {
6303c4ae 1915 if (CUR_SEG (i) != CUR_SEG (cie))
72b016b4
NC
1916 continue;
1917 output_cfi_insn (i);
1918 }
1919 }
a4447b93 1920
38462edf 1921 frag_align (align, DW_CFA_nop, 0);
a4447b93
RH
1922 symbol_set_value_now (end_address);
1923}
54cfded0 1924
a4447b93
RH
1925static void
1926output_fde (struct fde_entry *fde, struct cie_entry *cie,
38462edf
JJ
1927 bfd_boolean eh_frame, struct cfi_insn_data *first,
1928 int align)
a4447b93
RH
1929{
1930 symbolS *after_size_address, *end_address;
1931 expressionS exp;
9b8ae42e 1932 offsetT augmentation_size;
38462edf
JJ
1933 enum dwarf2_format fmt = DWARF2_FORMAT (now_seg);
1934 int offset_size;
1935 int addr_size;
54cfded0 1936
a4447b93
RH
1937 after_size_address = symbol_temp_make ();
1938 end_address = symbol_temp_make ();
54cfded0 1939
a4447b93
RH
1940 exp.X_op = O_subtract;
1941 exp.X_add_symbol = end_address;
1942 exp.X_op_symbol = after_size_address;
1943 exp.X_add_number = 0;
38462edf
JJ
1944 if (eh_frame || fmt == dwarf2_format_32bit)
1945 offset_size = 4;
1946 else
1947 {
1948 if (fmt == dwarf2_format_64bit)
1949 out_four (-1);
1950 offset_size = 8;
1951 }
1952 emit_expr (&exp, offset_size); /* Length. */
a4447b93 1953 symbol_set_value_now (after_size_address);
54cfded0 1954
38462edf
JJ
1955 if (eh_frame)
1956 {
3251495b 1957 exp.X_op = O_subtract;
38462edf
JJ
1958 exp.X_add_symbol = after_size_address;
1959 exp.X_op_symbol = cie->start_address;
3251495b
RH
1960 exp.X_add_number = 0;
1961 emit_expr (&exp, offset_size); /* CIE offset. */
38462edf
JJ
1962 }
1963 else
1964 {
3251495b 1965 TC_DWARF2_EMIT_OFFSET (cie->start_address, offset_size);
38462edf 1966 }
364b6d8b 1967
2f0c68f2 1968 exp.X_op = O_symbol;
38462edf
JJ
1969 if (eh_frame)
1970 {
2f0c68f2
CM
1971 bfd_reloc_code_real_type code
1972 = tc_cfi_reloc_for_encoding (cie->fde_encoding);
1973 if (code != BFD_RELOC_NONE)
1974 {
1975 reloc_howto_type *howto = bfd_reloc_type_lookup (stdoutput, code);
1976 char *p = frag_more (4);
1977 md_number_to_chars (p, 0, 4);
1978 fix_new (frag_now, p - frag_now->fr_literal, 4, fde->start_address,
1979 0, howto->pc_relative, code);
1980 }
1981 else
1982 {
1983 exp.X_op = O_subtract;
1984 exp.X_add_number = 0;
3dd24306 1985#if CFI_DIFF_EXPR_OK
2f0c68f2
CM
1986 exp.X_add_symbol = fde->start_address;
1987 exp.X_op_symbol = symbol_temp_new_now ();
1988 emit_expr (&exp, DWARF2_FDE_RELOC_SIZE); /* Code offset. */
364b6d8b 1989#else
2f0c68f2
CM
1990 exp.X_op = O_symbol;
1991 exp.X_add_symbol = fde->start_address;
1992
1993#if defined(tc_cfi_emit_pcrel_expr)
1994 tc_cfi_emit_pcrel_expr (&exp, DWARF2_FDE_RELOC_SIZE); /* Code offset. */
364b6d8b 1995#else
2f0c68f2 1996 emit_expr (&exp, DWARF2_FDE_RELOC_SIZE); /* Code offset. */
364b6d8b 1997#endif
364b6d8b 1998#endif
2f0c68f2 1999 }
38462edf
JJ
2000 addr_size = DWARF2_FDE_RELOC_SIZE;
2001 }
2002 else
2003 {
3251495b 2004 exp.X_add_number = 0;
2f0c68f2 2005 exp.X_add_symbol = fde->start_address;
38462edf
JJ
2006 addr_size = DWARF2_ADDR_SIZE (stdoutput);
2007 emit_expr (&exp, addr_size);
2008 }
54cfded0 2009
38462edf 2010 exp.X_op = O_subtract;
a4447b93 2011 exp.X_add_symbol = fde->end_address;
289040ca 2012 exp.X_op_symbol = fde->start_address; /* Code length. */
3251495b 2013 exp.X_add_number = 0;
38462edf 2014 emit_expr (&exp, addr_size);
54cfded0 2015
9b8ae42e 2016 augmentation_size = encoding_size (fde->lsda_encoding);
38462edf
JJ
2017 if (eh_frame)
2018 out_uleb128 (augmentation_size); /* Augmentation size. */
9b8ae42e 2019
2f0c68f2 2020 emit_expr_encoded (&fde->lsda, cie->lsda_encoding, FALSE);
39b82151 2021
a4447b93 2022 for (; first; first = first->next)
6303c4ae 2023 if (CUR_SEG (first) == CUR_SEG (fde))
67ed7401 2024 output_cfi_insn (first);
39b82151 2025
4df6ce47 2026 frag_align (align, DW_CFA_nop, 0);
a4447b93
RH
2027 symbol_set_value_now (end_address);
2028}
2029
2030static struct cie_entry *
38462edf
JJ
2031select_cie_for_fde (struct fde_entry *fde, bfd_boolean eh_frame,
2032 struct cfi_insn_data **pfirst, int align)
a4447b93
RH
2033{
2034 struct cfi_insn_data *i, *j;
2035 struct cie_entry *cie;
2036
2037 for (cie = cie_root; cie; cie = cie->next)
39b82151 2038 {
6303c4ae 2039 if (CUR_SEG (cie) != CUR_SEG (fde))
67ed7401 2040 continue;
67ed7401 2041 if (cie->return_column != fde->return_column
9b8ae42e
JJ
2042 || cie->signal_frame != fde->signal_frame
2043 || cie->per_encoding != fde->per_encoding
2044 || cie->lsda_encoding != fde->lsda_encoding)
a4447b93 2045 continue;
9b8ae42e
JJ
2046 if (cie->per_encoding != DW_EH_PE_omit)
2047 {
2048 if (cie->personality.X_op != fde->personality.X_op
2049 || cie->personality.X_add_number
2050 != fde->personality.X_add_number)
2051 continue;
2052 switch (cie->personality.X_op)
2053 {
2054 case O_constant:
2055 if (cie->personality.X_unsigned != fde->personality.X_unsigned)
2056 continue;
2057 break;
2058 case O_symbol:
2059 if (cie->personality.X_add_symbol
2060 != fde->personality.X_add_symbol)
2061 continue;
2062 break;
2063 default:
2064 abort ();
2065 }
2066 }
a4447b93
RH
2067 for (i = cie->first, j = fde->data;
2068 i != cie->last && j != NULL;
2069 i = i->next, j = j->next)
39b82151 2070 {
a4447b93
RH
2071 if (i->insn != j->insn)
2072 goto fail;
2073 switch (i->insn)
2074 {
2075 case DW_CFA_advance_loc:
289040ca
NC
2076 case DW_CFA_remember_state:
2077 /* We reached the first advance/remember in the FDE,
2078 but did not reach the end of the CIE list. */
a4447b93
RH
2079 goto fail;
2080
2081 case DW_CFA_offset:
2082 case DW_CFA_def_cfa:
2083 if (i->u.ri.reg != j->u.ri.reg)
2084 goto fail;
2085 if (i->u.ri.offset != j->u.ri.offset)
2086 goto fail;
2087 break;
2088
2089 case DW_CFA_register:
2090 if (i->u.rr.reg1 != j->u.rr.reg1)
2091 goto fail;
2092 if (i->u.rr.reg2 != j->u.rr.reg2)
2093 goto fail;
2094 break;
2095
2096 case DW_CFA_def_cfa_register:
2be24b54
ML
2097 case DW_CFA_restore:
2098 case DW_CFA_undefined:
2099 case DW_CFA_same_value:
a4447b93
RH
2100 if (i->u.r != j->u.r)
2101 goto fail;
2102 break;
2103
2104 case DW_CFA_def_cfa_offset:
2105 if (i->u.i != j->u.i)
2106 goto fail;
2107 break;
2108
cdfbf930 2109 case CFI_escape:
f1c4cc75 2110 case CFI_val_encoded_addr:
73e76108 2111 case CFI_label:
cdfbf930
RH
2112 /* Don't bother matching these for now. */
2113 goto fail;
2114
a4447b93
RH
2115 default:
2116 abort ();
2117 }
39b82151 2118 }
a4447b93
RH
2119
2120 /* Success if we reached the end of the CIE list, and we've either
289040ca
NC
2121 run out of FDE entries or we've encountered an advance,
2122 remember, or escape. */
e9fad691
AM
2123 if (i == cie->last
2124 && (!j
2125 || j->insn == DW_CFA_advance_loc
289040ca 2126 || j->insn == DW_CFA_remember_state
f1c4cc75 2127 || j->insn == CFI_escape
73e76108
JB
2128 || j->insn == CFI_val_encoded_addr
2129 || j->insn == CFI_label))
39b82151 2130 {
a4447b93
RH
2131 *pfirst = j;
2132 return cie;
39b82151
ML
2133 }
2134
a4447b93 2135 fail:;
54cfded0
AM
2136 }
2137
add39d23 2138 cie = XNEW (struct cie_entry);
a4447b93
RH
2139 cie->next = cie_root;
2140 cie_root = cie;
6303c4ae 2141 SET_CUR_SEG (cie, CUR_SEG (fde));
a4447b93 2142 cie->return_column = fde->return_column;
63752a75 2143 cie->signal_frame = fde->signal_frame;
9b8ae42e
JJ
2144 cie->per_encoding = fde->per_encoding;
2145 cie->lsda_encoding = fde->lsda_encoding;
2146 cie->personality = fde->personality;
a4447b93 2147 cie->first = fde->data;
54cfded0 2148
a4447b93 2149 for (i = cie->first; i ; i = i->next)
e9fad691 2150 if (i->insn == DW_CFA_advance_loc
289040ca 2151 || i->insn == DW_CFA_remember_state
f1c4cc75 2152 || i->insn == CFI_escape
69602580
JB
2153 || i->insn == CFI_val_encoded_addr
2154 || i->insn == CFI_label)
a4447b93 2155 break;
54cfded0 2156
a4447b93
RH
2157 cie->last = i;
2158 *pfirst = i;
38462edf
JJ
2159
2160 output_cie (cie, eh_frame, align);
54cfded0 2161
a4447b93 2162 return cie;
54cfded0
AM
2163}
2164
38462edf
JJ
2165#ifdef md_reg_eh_frame_to_debug_frame
2166static void
6303c4ae 2167cfi_change_reg_numbers (struct cfi_insn_data *insn, segT ccseg)
38462edf
JJ
2168{
2169 for (; insn; insn = insn->next)
72b016b4 2170 {
6303c4ae 2171 if (CUR_SEG (insn) != ccseg)
83e12deb 2172 continue;
72b016b4
NC
2173 switch (insn->insn)
2174 {
2175 case DW_CFA_advance_loc:
2176 case DW_CFA_def_cfa_offset:
2177 case DW_CFA_remember_state:
2178 case DW_CFA_restore_state:
2179 case DW_CFA_GNU_window_save:
2180 case CFI_escape:
73e76108 2181 case CFI_label:
72b016b4 2182 break;
38462edf 2183
72b016b4
NC
2184 case DW_CFA_def_cfa:
2185 case DW_CFA_offset:
2186 insn->u.ri.reg = md_reg_eh_frame_to_debug_frame (insn->u.ri.reg);
2187 break;
38462edf 2188
72b016b4
NC
2189 case DW_CFA_def_cfa_register:
2190 case DW_CFA_undefined:
2191 case DW_CFA_same_value:
2192 case DW_CFA_restore:
2193 insn->u.r = md_reg_eh_frame_to_debug_frame (insn->u.r);
2194 break;
38462edf 2195
72b016b4
NC
2196 case DW_CFA_register:
2197 insn->u.rr.reg1 = md_reg_eh_frame_to_debug_frame (insn->u.rr.reg1);
2198 insn->u.rr.reg2 = md_reg_eh_frame_to_debug_frame (insn->u.rr.reg2);
2199 break;
38462edf 2200
72b016b4
NC
2201 case CFI_val_encoded_addr:
2202 insn->u.ea.reg = md_reg_eh_frame_to_debug_frame (insn->u.ea.reg);
2203 break;
38462edf 2204
72b016b4
NC
2205 default:
2206 abort ();
2207 }
2208 }
38462edf
JJ
2209}
2210#else
72b016b4 2211#define cfi_change_reg_numbers(insn, cseg) do { } while (0)
38462edf
JJ
2212#endif
2213
2f0c68f2
CM
2214#if SUPPORT_COMPACT_EH
2215static void
2216cfi_emit_eh_header (symbolS *sym, bfd_vma addend)
72b016b4 2217{
2f0c68f2 2218 expressionS exp;
72b016b4 2219
2f0c68f2
CM
2220 exp.X_add_number = addend;
2221 exp.X_add_symbol = sym;
2222 emit_expr_encoded (&exp, DW_EH_PE_sdata4 | DW_EH_PE_pcrel, FALSE);
2223}
72b016b4 2224
2f0c68f2
CM
2225static void
2226output_eh_header (struct fde_entry *fde)
2227{
2228 char *p;
2229 bfd_vma addend;
2230
2231 if (fde->eh_header_type == EH_COMPACT_INLINE)
2232 addend = 0;
2233 else
2234 addend = 1;
2235
2236 cfi_emit_eh_header (fde->start_address, addend);
2237
2238 if (fde->eh_header_type == EH_COMPACT_INLINE)
2239 {
2240 p = frag_more (4);
2241 /* Inline entries always use PR1. */
2242 *(p++) = 1;
2243 memcpy(p, fde->eh_data, 3);
6303c4ae
AM
2244 }
2245 else
2246 {
2f0c68f2
CM
2247 if (fde->eh_header_type == EH_COMPACT_LEGACY)
2248 addend = 1;
2249 else if (fde->eh_header_type == EH_COMPACT_OUTLINE
2250 || fde->eh_header_type == EH_COMPACT_OUTLINE_DONE)
2251 addend = 0;
2252 else
2253 abort ();
2254 cfi_emit_eh_header (fde->eh_loc, addend);
6303c4ae 2255 }
72b016b4 2256}
2f0c68f2 2257#endif
72b016b4 2258
54cfded0 2259void
a4447b93 2260cfi_finish (void)
54cfded0 2261{
72b016b4
NC
2262 struct cie_entry *cie, *cie_next;
2263 segT cfi_seg, ccseg;
a4447b93 2264 struct fde_entry *fde;
72b016b4
NC
2265 struct cfi_insn_data *first;
2266 int save_flag_traditional_format, seek_next_seg;
54cfded0 2267
a4447b93
RH
2268 if (all_fde_data == 0)
2269 return;
54cfded0 2270
bd5608dc 2271 cfi_sections_set = TRUE;
2f0c68f2
CM
2272 if ((all_cfi_sections & CFI_EMIT_eh_frame) != 0
2273 || (all_cfi_sections & CFI_EMIT_eh_frame_compact) != 0)
38462edf 2274 {
38462edf
JJ
2275 /* Make sure check_eh_frame doesn't do anything with our output. */
2276 save_flag_traditional_format = flag_traditional_format;
2277 flag_traditional_format = 1;
eafbc43f 2278
2f0c68f2 2279 if (!EH_FRAME_LINKONCE)
6303c4ae
AM
2280 {
2281 /* Open .eh_frame section. */
2282 cfi_seg = get_cfi_seg (NULL, ".eh_frame",
2283 (SEC_ALLOC | SEC_LOAD | SEC_DATA
2284 | DWARF2_EH_FRAME_READ_ONLY),
2285 EH_FRAME_ALIGNMENT);
67ed7401 2286#ifdef md_fix_up_eh_frame
6303c4ae 2287 md_fix_up_eh_frame (cfi_seg);
67ed7401 2288#else
6303c4ae 2289 (void) cfi_seg;
67ed7401 2290#endif
6303c4ae 2291 }
67ed7401 2292
72b016b4 2293 do
83e12deb 2294 {
72b016b4 2295 ccseg = NULL;
72b016b4 2296 seek_next_seg = 0;
67ed7401 2297
72b016b4 2298 for (cie = cie_root; cie; cie = cie_next)
38462edf 2299 {
72b016b4
NC
2300 cie_next = cie->next;
2301 free ((void *) cie);
38462edf 2302 }
72b016b4 2303 cie_root = NULL;
38462edf 2304
72b016b4
NC
2305 for (fde = all_fde_data; fde ; fde = fde->next)
2306 {
2f0c68f2
CM
2307 if ((fde->sections & CFI_EMIT_eh_frame) == 0
2308 && (fde->sections & CFI_EMIT_eh_frame_compact) == 0)
2309 continue;
2310
2311#if SUPPORT_COMPACT_EH
2312 /* Emit a LEGACY format header if we have processed all
2313 of the .cfi directives without encountering either inline or
2314 out-of-line compact unwinding opcodes. */
2315 if (fde->eh_header_type == EH_COMPACT_HAS_LSDA
2316 || fde->eh_header_type == EH_COMPACT_UNKNOWN)
2317 fde->eh_header_type = EH_COMPACT_LEGACY;
2318
2319 if (fde->eh_header_type != EH_COMPACT_LEGACY)
2320 continue;
2321#endif
2322 if (EH_FRAME_LINKONCE)
6303c4ae
AM
2323 {
2324 if (HANDLED (fde))
2325 continue;
2326 if (seek_next_seg && CUR_SEG (fde) != ccseg)
2327 {
2328 seek_next_seg = 2;
2329 continue;
2330 }
2331 if (!seek_next_seg)
2332 {
2333 ccseg = CUR_SEG (fde);
2334 /* Open .eh_frame section. */
2335 cfi_seg = get_cfi_seg (ccseg, ".eh_frame",
2336 (SEC_ALLOC | SEC_LOAD | SEC_DATA
2337 | DWARF2_EH_FRAME_READ_ONLY),
2338 EH_FRAME_ALIGNMENT);
72b016b4 2339#ifdef md_fix_up_eh_frame
6303c4ae 2340 md_fix_up_eh_frame (cfi_seg);
67ed7401 2341#else
6303c4ae 2342 (void) cfi_seg;
72b016b4 2343#endif
6303c4ae
AM
2344 seek_next_seg = 1;
2345 }
2346 SET_HANDLED (fde, 1);
72b016b4 2347 }
72b016b4
NC
2348
2349 if (fde->end_address == NULL)
2350 {
2351 as_bad (_("open CFI at the end of file; missing .cfi_endproc directive"));
2352 fde->end_address = fde->start_address;
2353 }
2354
2355 cie = select_cie_for_fde (fde, TRUE, &first, 2);
2f0c68f2 2356 fde->eh_loc = symbol_temp_new_now ();
72b016b4
NC
2357 output_fde (fde, cie, TRUE, first,
2358 fde->next == NULL ? EH_FRAME_ALIGNMENT : 2);
2359 }
38462edf 2360 }
2f0c68f2 2361 while (EH_FRAME_LINKONCE && seek_next_seg == 2);
72b016b4 2362
2f0c68f2 2363 if (EH_FRAME_LINKONCE)
6303c4ae
AM
2364 for (fde = all_fde_data; fde ; fde = fde->next)
2365 SET_HANDLED (fde, 0);
38462edf 2366
2f0c68f2
CM
2367#if SUPPORT_COMPACT_EH
2368 if (compact_eh)
2369 {
2370 /* Create remaining out of line table entries. */
2371 do
2372 {
2373 ccseg = NULL;
2374 seek_next_seg = 0;
2375
2376 for (fde = all_fde_data; fde ; fde = fde->next)
2377 {
2378 if ((fde->sections & CFI_EMIT_eh_frame) == 0
2379 && (fde->sections & CFI_EMIT_eh_frame_compact) == 0)
2380 continue;
2381
2382 if (fde->eh_header_type != EH_COMPACT_OUTLINE)
2383 continue;
2384 if (HANDLED (fde))
2385 continue;
2386 if (seek_next_seg && CUR_SEG (fde) != ccseg)
2387 {
2388 seek_next_seg = 2;
2389 continue;
2390 }
2391 if (!seek_next_seg)
2392 {
2393 ccseg = CUR_SEG (fde);
2394 /* Open .gnu_extab section. */
2395 get_cfi_seg (ccseg, ".gnu_extab",
2396 (SEC_ALLOC | SEC_LOAD | SEC_DATA
2397 | DWARF2_EH_FRAME_READ_ONLY),
2398 1);
2399 seek_next_seg = 1;
2400 }
2401 SET_HANDLED (fde, 1);
2402
2403 frag_align (1, 0, 0);
2404 record_alignment (now_seg, 1);
2405 output_compact_unwind_data (fde, 1);
2406 }
2407 }
2408 while (EH_FRAME_LINKONCE && seek_next_seg == 2);
2409
2410 for (fde = all_fde_data; fde ; fde = fde->next)
2411 SET_HANDLED (fde, 0);
2412
2413 /* Create index table fragments. */
2414 do
2415 {
2416 ccseg = NULL;
2417 seek_next_seg = 0;
2418
2419 for (fde = all_fde_data; fde ; fde = fde->next)
2420 {
2421 if ((fde->sections & CFI_EMIT_eh_frame) == 0
2422 && (fde->sections & CFI_EMIT_eh_frame_compact) == 0)
2423 continue;
2424
2425 if (HANDLED (fde))
2426 continue;
2427 if (seek_next_seg && CUR_SEG (fde) != ccseg)
2428 {
2429 seek_next_seg = 2;
2430 continue;
2431 }
2432 if (!seek_next_seg)
2433 {
2434 ccseg = CUR_SEG (fde);
2435 /* Open .eh_frame_entry section. */
2436 cfi_seg = get_cfi_seg (ccseg, ".eh_frame_entry",
2437 (SEC_ALLOC | SEC_LOAD | SEC_DATA
2438 | DWARF2_EH_FRAME_READ_ONLY),
2439 2);
2440 seek_next_seg = 1;
2441 }
2442 SET_HANDLED (fde, 1);
2443
2444 output_eh_header (fde);
2445 }
2446 }
2447 while (seek_next_seg == 2);
2448
2449 for (fde = all_fde_data; fde ; fde = fde->next)
2450 SET_HANDLED (fde, 0);
2451 }
2452#endif /* SUPPORT_COMPACT_EH */
2453
38462edf
JJ
2454 flag_traditional_format = save_flag_traditional_format;
2455 }
2456
bd5608dc 2457 cfi_sections_set = TRUE;
2f0c68f2 2458 if ((all_cfi_sections & CFI_EMIT_debug_frame) != 0)
a4447b93 2459 {
38462edf 2460 int alignment = ffs (DWARF2_ADDR_SIZE (stdoutput)) - 1;
a4447b93 2461
6303c4ae
AM
2462 if (!SUPPORT_FRAME_LINKONCE)
2463 get_cfi_seg (NULL, ".debug_frame",
2464 SEC_READONLY | SEC_DEBUGGING,
2465 alignment);
2466
72b016b4 2467 do
83e12deb 2468 {
72b016b4 2469 ccseg = NULL;
72b016b4 2470 seek_next_seg = 0;
67ed7401 2471
72b016b4 2472 for (cie = cie_root; cie; cie = cie_next)
38462edf 2473 {
72b016b4
NC
2474 cie_next = cie->next;
2475 free ((void *) cie);
38462edf 2476 }
72b016b4 2477 cie_root = NULL;
38462edf 2478
72b016b4
NC
2479 for (fde = all_fde_data; fde ; fde = fde->next)
2480 {
2f0c68f2
CM
2481 if ((fde->sections & CFI_EMIT_debug_frame) == 0)
2482 continue;
2483
6303c4ae
AM
2484 if (SUPPORT_FRAME_LINKONCE)
2485 {
2486 if (HANDLED (fde))
2487 continue;
2488 if (seek_next_seg && CUR_SEG (fde) != ccseg)
2489 {
2490 seek_next_seg = 2;
2491 continue;
2492 }
2493 if (!seek_next_seg)
2494 {
2495 ccseg = CUR_SEG (fde);
2496 /* Open .debug_frame section. */
2497 get_cfi_seg (ccseg, ".debug_frame",
2498 SEC_READONLY | SEC_DEBUGGING,
2499 alignment);
2500 seek_next_seg = 1;
2501 }
2502 SET_HANDLED (fde, 1);
72b016b4 2503 }
72b016b4
NC
2504 if (fde->end_address == NULL)
2505 {
2506 as_bad (_("open CFI at the end of file; missing .cfi_endproc directive"));
2507 fde->end_address = fde->start_address;
2508 }
2509
2510 fde->per_encoding = DW_EH_PE_omit;
2511 fde->lsda_encoding = DW_EH_PE_omit;
2512 cfi_change_reg_numbers (fde->data, ccseg);
2513 cie = select_cie_for_fde (fde, FALSE, &first, alignment);
2514 output_fde (fde, cie, FALSE, first, alignment);
2515 }
38462edf 2516 }
67ed7401 2517 while (SUPPORT_FRAME_LINKONCE && seek_next_seg == 2);
72b016b4 2518
6303c4ae
AM
2519 if (SUPPORT_FRAME_LINKONCE)
2520 for (fde = all_fde_data; fde ; fde = fde->next)
2521 SET_HANDLED (fde, 0);
38462edf 2522 }
54cfded0 2523}
0a7b15ff
JB
2524
2525#else /* TARGET_USE_CFIPOP */
d58a1929 2526
5ff2bd08 2527/* Emit an intelligible error message for missing support. */
d58a1929
RH
2528
2529static void
2530dot_cfi_dummy (int ignored ATTRIBUTE_UNUSED)
2531{
2532 as_bad (_("CFI is not supported for this target"));
2533 ignore_rest_of_line ();
2534}
2535
2536const pseudo_typeS cfi_pseudo_table[] =
2537 {
2538 { "cfi_sections", dot_cfi_dummy, 0 },
2539 { "cfi_startproc", dot_cfi_dummy, 0 },
2540 { "cfi_endproc", dot_cfi_dummy, 0 },
2f0c68f2 2541 { "cfi_fde_data", dot_cfi_dummy, 0 },
d58a1929
RH
2542 { "cfi_def_cfa", dot_cfi_dummy, 0 },
2543 { "cfi_def_cfa_register", dot_cfi_dummy, 0 },
2544 { "cfi_def_cfa_offset", dot_cfi_dummy, 0 },
2545 { "cfi_adjust_cfa_offset", dot_cfi_dummy, 0 },
2546 { "cfi_offset", dot_cfi_dummy, 0 },
2547 { "cfi_rel_offset", dot_cfi_dummy, 0 },
2548 { "cfi_register", dot_cfi_dummy, 0 },
2549 { "cfi_return_column", dot_cfi_dummy, 0 },
2550 { "cfi_restore", dot_cfi_dummy, 0 },
2551 { "cfi_undefined", dot_cfi_dummy, 0 },
2552 { "cfi_same_value", dot_cfi_dummy, 0 },
2553 { "cfi_remember_state", dot_cfi_dummy, 0 },
2554 { "cfi_restore_state", dot_cfi_dummy, 0 },
2555 { "cfi_window_save", dot_cfi_dummy, 0 },
2556 { "cfi_escape", dot_cfi_dummy, 0 },
2557 { "cfi_signal_frame", dot_cfi_dummy, 0 },
2558 { "cfi_personality", dot_cfi_dummy, 0 },
2f0c68f2 2559 { "cfi_personality_id", dot_cfi_dummy, 0 },
d58a1929
RH
2560 { "cfi_lsda", dot_cfi_dummy, 0 },
2561 { "cfi_val_encoded_addr", dot_cfi_dummy, 0 },
73e76108 2562 { "cfi_label", dot_cfi_dummy, 0 },
2f0c68f2 2563 { "cfi_inline_lsda", dot_cfi_dummy, 0 },
084303b8 2564 { "cfi_val_offset", dot_cfi_dummy, 0 },
d58a1929
RH
2565 { NULL, NULL, 0 }
2566 };
2567
0a7b15ff
JB
2568void
2569cfi_finish (void)
2570{
2571}
2572#endif /* TARGET_USE_CFIPOP */
This page took 0.668992 seconds and 4 git commands to generate.