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