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