* configure.ac (alpha*-dec-osf*, i[[3456789]]86-*-rdos*,
[deliverable/binutils-gdb.git] / gas / dw2gencfi.c
CommitLineData
54cfded0 1/* dw2gencfi.c - Support for generating Dwarf2 CFI information.
72b016b4 2 Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
1fbfe785 3 Free Software Foundation, Inc.
54cfded0
AM
4 Contributed by Michal Ludvig <mludvig@suse.cz>
5
6 This file is part of GAS, the GNU Assembler.
7
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
ec2655a6 10 the Free Software Foundation; either version 3, or (at your option)
54cfded0
AM
11 any later version.
12
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to the Free
4b4da160
NC
20 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
21 02110-1301, USA. */
54cfded0 22
54cfded0
AM
23#include "as.h"
24#include "dw2gencfi.h"
ae424f82 25#include "subsegs.h"
38462edf 26#include "dwarf2dbg.h"
54cfded0 27
0a7b15ff 28#ifdef TARGET_USE_CFIPOP
a4447b93 29
3dd24306
DA
30/* By default, use difference expressions if DIFF_EXPR_OK is defined. */
31#ifndef CFI_DIFF_EXPR_OK
32# ifdef DIFF_EXPR_OK
33# define CFI_DIFF_EXPR_OK 1
34# else
35# define CFI_DIFF_EXPR_OK 0
36# endif
37#endif
38
2c678708 39#ifndef CFI_DIFF_LSDA_OK
72b016b4 40#define CFI_DIFF_LSDA_OK CFI_DIFF_EXPR_OK
2c678708
MK
41#endif
42
43#if CFI_DIFF_EXPR_OK == 1 && CFI_DIFF_LSDA_OK == 0
44# error "CFI_DIFF_EXPR_OK should imply CFI_DIFF_LSDA_OK"
45#endif
46
a4447b93
RH
47/* We re-use DWARF2_LINE_MIN_INSN_LENGTH for the code alignment field
48 of the CIE. Default to 1 if not otherwise specified. */
72b016b4
NC
49#ifndef DWARF2_LINE_MIN_INSN_LENGTH
50#define DWARF2_LINE_MIN_INSN_LENGTH 1
a4447b93
RH
51#endif
52
8c9b70b1
RH
53/* By default, use 32-bit relocations from .eh_frame into .text. */
54#ifndef DWARF2_FDE_RELOC_SIZE
72b016b4 55#define DWARF2_FDE_RELOC_SIZE 4
8c9b70b1
RH
56#endif
57
58/* By default, use a read-only .eh_frame section. */
59#ifndef DWARF2_EH_FRAME_READ_ONLY
72b016b4 60#define DWARF2_EH_FRAME_READ_ONLY SEC_READONLY
8c9b70b1
RH
61#endif
62
9393cb0d 63#ifndef EH_FRAME_ALIGNMENT
72b016b4 64#define EH_FRAME_ALIGNMENT (bfd_get_arch_size (stdoutput) == 64 ? 3 : 2)
9393cb0d
JJ
65#endif
66
a4447b93 67#ifndef tc_cfi_frame_initial_instructions
72b016b4 68#define tc_cfi_frame_initial_instructions() ((void)0)
a4447b93
RH
69#endif
70
38462edf 71#ifndef DWARF2_FORMAT
72b016b4 72#define DWARF2_FORMAT(SEC) dwarf2_format_32bit
38462edf
JJ
73#endif
74
f1c4cc75 75#ifndef DWARF2_ADDR_SIZE
72b016b4 76#define DWARF2_ADDR_SIZE(bfd) (bfd_arch_bits_per_address (bfd) / 8)
f1c4cc75
RH
77#endif
78
72b016b4
NC
79/* Private segment collection list. */
80struct dwcfi_seg_list
81{
82 segT seg;
83 int subseg;
84 char * seg_name;
85};
86
87#define FRAME_NAME ".eh_frame"
88
89static struct hash_control *dwcfi_hash;
90
91/* Build based on segment the derived .debug_...
92 segment name containing origin segment's postfix name part. */
93
94static char *
95get_debugseg_name (segT seg, const char *base_name)
96{
97 const char *name;
98
99 if (!seg)
100 name = "";
101 else
102 {
103 const char * dollar;
104 const char * dot;
105
106 name = bfd_get_section_name (stdoutput, seg);
107
108 dollar = strchr (name, '$');
109 dot = strchr (name + 1, '.');
110
111 if (!dollar && !dot)
112 name = "";
113 else if (!dollar)
114 name = dot;
115 else if (!dot)
116 name = dollar;
117 else if (dot < dollar)
118 name = dot;
119 else
120 name = dollar;
121 }
122
123 return concat (base_name, name, NULL);
124}
125
126/* Allocate a dwcfi_seg_list structure. */
127
128static struct dwcfi_seg_list *
129alloc_debugseg_item (segT seg, int subseg, char *name)
130{
131 struct dwcfi_seg_list *r;
132
133 r = (struct dwcfi_seg_list *)
134 xmalloc (sizeof (struct dwcfi_seg_list) + strlen (name));
135 r->seg = seg;
136 r->subseg = subseg;
137 r->seg_name = name;
138 return r;
139}
140
141static segT
142is_now_linkonce_segment (void)
143{
144#if defined (TE_PE) || defined (TE_PEP)
145 if ((bfd_get_section_flags (stdoutput, now_seg)
146 & (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD
147 | SEC_LINK_DUPLICATES_ONE_ONLY | SEC_LINK_DUPLICATES_SAME_SIZE
148 | SEC_LINK_DUPLICATES_SAME_CONTENTS)) != 0)
149 return now_seg;
150#endif
151 return NULL;
152}
153
154/* Generate debug... segment with same linkonce properties
155 of based segment. */
156
157static segT
158make_debug_seg (segT cseg, char *name, int sflags)
159{
160 segT save_seg = now_seg;
161 int save_subseg = now_subseg;
162 segT r;
163 flagword flags;
164
165 r = subseg_new (name, 0);
166
167 /* Check if code segment is marked as linked once. */
168 if (!cseg)
169 flags = 0;
170 else
171 flags = bfd_get_section_flags (stdoutput, cseg)
172 & (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD
173 | SEC_LINK_DUPLICATES_ONE_ONLY | SEC_LINK_DUPLICATES_SAME_SIZE
174 | SEC_LINK_DUPLICATES_SAME_CONTENTS);
175
176 /* Add standard section flags. */
177 flags |= sflags;
178
179 /* Apply possibly linked once flags to new generated segment, too. */
180 if (!bfd_set_section_flags (stdoutput, r, flags))
181 as_bad (_("bfd_set_section_flags: %s"),
182 bfd_errmsg (bfd_get_error ()));
183
184 /* Restore to previous segment. */
185 if (save_seg != NULL)
186 subseg_set (save_seg, save_subseg);
187 return r;
188}
189
190static void
191dwcfi_hash_insert (const char *name, struct dwcfi_seg_list *item)
192{
193 const char *error_string;
194
195 if ((error_string = hash_jam (dwcfi_hash, name, (char *) item)))
196 as_fatal (_("Inserting \"%s\" into structure table failed: %s"),
197 name, error_string);
198}
199
200static struct dwcfi_seg_list *
201dwcfi_hash_find (char *name)
202{
203 return (struct dwcfi_seg_list *) hash_find (dwcfi_hash, name);
204}
205
206static struct dwcfi_seg_list *
207dwcfi_hash_find_or_make (segT cseg, const char *base_name, int flags)
208{
209 struct dwcfi_seg_list *item;
210 char *name;
211
212 /* Initialize dwcfi_hash once. */
213 if (!dwcfi_hash)
214 dwcfi_hash = hash_new ();
215
216 name = get_debugseg_name (cseg, base_name);
217
218 item = dwcfi_hash_find (name);
219 if (!item)
220 {
221 item = alloc_debugseg_item (make_debug_seg (cseg, name, flags), 0, name);
222
223 dwcfi_hash_insert (item->seg_name, item);
224 }
225 else
226 free (name);
227
228 return item;
229}
230
3251495b
RH
231/* ??? Share this with dwarf2cfg.c. */
232#ifndef TC_DWARF2_EMIT_OFFSET
233#define TC_DWARF2_EMIT_OFFSET generic_dwarf2_emit_offset
234
235/* Create an offset to .dwarf2_*. */
236
237static void
238generic_dwarf2_emit_offset (symbolS *symbol, unsigned int size)
239{
240 expressionS exp;
241
242 exp.X_op = O_symbol;
243 exp.X_add_symbol = symbol;
244 exp.X_add_number = 0;
245 emit_expr (&exp, size);
246}
247#endif
248
72b016b4
NC
249struct cfi_escape_data
250{
1e9cc1c2
NC
251 struct cfi_escape_data *next;
252 expressionS exp;
253};
a4447b93
RH
254
255struct cfi_insn_data
39b82151 256{
a4447b93 257 struct cfi_insn_data *next;
72b016b4 258 segT cur_seg;
a4447b93 259 int insn;
72b016b4
NC
260 union
261 {
262 struct
263 {
a4447b93
RH
264 unsigned reg;
265 offsetT offset;
266 } ri;
267
72b016b4
NC
268 struct
269 {
a4447b93
RH
270 unsigned reg1;
271 unsigned reg2;
272 } rr;
273
274 unsigned r;
275 offsetT i;
276
72b016b4
NC
277 struct
278 {
a4447b93
RH
279 symbolS *lab1;
280 symbolS *lab2;
281 } ll;
cdfbf930 282
1e9cc1c2 283 struct cfi_escape_data *esc;
f1c4cc75 284
72b016b4
NC
285 struct
286 {
f1c4cc75
RH
287 unsigned reg, encoding;
288 expressionS exp;
289 } ea;
a4447b93 290 } u;
39b82151
ML
291};
292
a4447b93 293struct fde_entry
39b82151 294{
a4447b93 295 struct fde_entry *next;
72b016b4 296 segT cseg;
a4447b93
RH
297 symbolS *start_address;
298 symbolS *end_address;
299 struct cfi_insn_data *data;
300 struct cfi_insn_data **last;
9b8ae42e
JJ
301 unsigned char per_encoding;
302 unsigned char lsda_encoding;
303 expressionS personality;
304 expressionS lsda;
a4447b93 305 unsigned int return_column;
63752a75 306 unsigned int signal_frame;
72b016b4 307 int handled;
39b82151
ML
308};
309
a4447b93 310struct cie_entry
39b82151 311{
a4447b93 312 struct cie_entry *next;
72b016b4 313 segT cur_seg;
a4447b93
RH
314 symbolS *start_address;
315 unsigned int return_column;
63752a75 316 unsigned int signal_frame;
9b8ae42e
JJ
317 unsigned char per_encoding;
318 unsigned char lsda_encoding;
319 expressionS personality;
a4447b93 320 struct cfi_insn_data *first, *last;
39b82151
ML
321};
322
a4447b93 323/* List of FDE entries. */
72b016b4 324
a4447b93
RH
325static struct fde_entry *all_fde_data;
326static struct fde_entry **last_fde_data = &all_fde_data;
39b82151
ML
327
328/* List of CIEs so that they could be reused. */
329static struct cie_entry *cie_root;
330
fa87b337
RH
331/* Stack of old CFI data, for save/restore. */
332struct cfa_save_data
333{
334 struct cfa_save_data *next;
335 offsetT cfa_offset;
336};
337
ae424f82
JJ
338/* Current open FDE entry. */
339struct frch_cfi_data
340{
341 struct fde_entry *cur_fde_data;
342 symbolS *last_address;
343 offsetT cur_cfa_offset;
344 struct cfa_save_data *cfa_save_stack;
345};
a4447b93
RH
346\f
347/* Construct a new FDE structure and add it to the end of the fde list. */
54cfded0 348
a4447b93
RH
349static struct fde_entry *
350alloc_fde_entry (void)
351{
1e9cc1c2
NC
352 struct fde_entry *fde = (struct fde_entry *)
353 xcalloc (1, sizeof (struct fde_entry));
54cfded0 354
1e9cc1c2
NC
355 frchain_now->frch_cfi_data = (struct frch_cfi_data *)
356 xcalloc (1, sizeof (struct frch_cfi_data));
ae424f82 357 frchain_now->frch_cfi_data->cur_fde_data = fde;
a4447b93
RH
358 *last_fde_data = fde;
359 last_fde_data = &fde->next;
72b016b4
NC
360 fde->cseg = is_now_linkonce_segment ();
361 fde->handled = 0;
a4447b93
RH
362 fde->last = &fde->data;
363 fde->return_column = DWARF2_DEFAULT_RETURN_COLUMN;
9b8ae42e
JJ
364 fde->per_encoding = DW_EH_PE_omit;
365 fde->lsda_encoding = DW_EH_PE_omit;
a4447b93
RH
366
367 return fde;
368}
369
370/* The following functions are available for a backend to construct its
371 own unwind information, usually from legacy unwind directives. */
372
373/* Construct a new INSN structure and add it to the end of the insn list
374 for the currently active FDE. */
375
376static struct cfi_insn_data *
377alloc_cfi_insn_data (void)
54cfded0 378{
1e9cc1c2
NC
379 struct cfi_insn_data *insn = (struct cfi_insn_data *)
380 xcalloc (1, sizeof (struct cfi_insn_data));
ae424f82 381 struct fde_entry *cur_fde_data = frchain_now->frch_cfi_data->cur_fde_data;
a4447b93
RH
382
383 *cur_fde_data->last = insn;
384 cur_fde_data->last = &insn->next;
72b016b4 385 insn->cur_seg = is_now_linkonce_segment ();
54cfded0 386
a4447b93 387 return insn;
54cfded0
AM
388}
389
a4447b93
RH
390/* Construct a new FDE structure that begins at LABEL. */
391
72b016b4 392void
a4447b93 393cfi_new_fde (symbolS *label)
54cfded0 394{
a4447b93
RH
395 struct fde_entry *fde = alloc_fde_entry ();
396 fde->start_address = label;
ae424f82 397 frchain_now->frch_cfi_data->last_address = label;
54cfded0
AM
398}
399
a4447b93
RH
400/* End the currently open FDE. */
401
72b016b4 402void
a4447b93 403cfi_end_fde (symbolS *label)
54cfded0 404{
ae424f82
JJ
405 frchain_now->frch_cfi_data->cur_fde_data->end_address = label;
406 free (frchain_now->frch_cfi_data);
407 frchain_now->frch_cfi_data = NULL;
54cfded0
AM
408}
409
a4447b93
RH
410/* Set the return column for the current FDE. */
411
412void
413cfi_set_return_column (unsigned regno)
54cfded0 414{
ae424f82 415 frchain_now->frch_cfi_data->cur_fde_data->return_column = regno;
a4447b93 416}
54cfded0 417
2be24b54
ML
418/* Universal functions to store new instructions. */
419
420static void
72b016b4 421cfi_add_CFA_insn (int insn)
2be24b54
ML
422{
423 struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data ();
424
425 insn_ptr->insn = insn;
426}
427
428static void
429cfi_add_CFA_insn_reg (int insn, unsigned regno)
430{
431 struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data ();
432
433 insn_ptr->insn = insn;
434 insn_ptr->u.r = regno;
435}
436
437static void
438cfi_add_CFA_insn_offset (int insn, offsetT offset)
439{
440 struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data ();
441
442 insn_ptr->insn = insn;
443 insn_ptr->u.i = offset;
444}
445
446static void
447cfi_add_CFA_insn_reg_reg (int insn, unsigned reg1, unsigned reg2)
448{
449 struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data ();
450
451 insn_ptr->insn = insn;
452 insn_ptr->u.rr.reg1 = reg1;
453 insn_ptr->u.rr.reg2 = reg2;
454}
455
456static void
457cfi_add_CFA_insn_reg_offset (int insn, unsigned regno, offsetT offset)
458{
459 struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data ();
460
461 insn_ptr->insn = insn;
462 insn_ptr->u.ri.reg = regno;
463 insn_ptr->u.ri.offset = offset;
464}
465
a4447b93 466/* Add a CFI insn to advance the PC from the last address to LABEL. */
54cfded0 467
a4447b93
RH
468void
469cfi_add_advance_loc (symbolS *label)
470{
471 struct cfi_insn_data *insn = alloc_cfi_insn_data ();
7c0295b1 472
a4447b93 473 insn->insn = DW_CFA_advance_loc;
ae424f82 474 insn->u.ll.lab1 = frchain_now->frch_cfi_data->last_address;
a4447b93 475 insn->u.ll.lab2 = label;
54cfded0 476
ae424f82 477 frchain_now->frch_cfi_data->last_address = label;
a4447b93 478}
54cfded0 479
a4447b93
RH
480/* Add a DW_CFA_offset record to the CFI data. */
481
482void
483cfi_add_CFA_offset (unsigned regno, offsetT offset)
484{
fa87b337
RH
485 unsigned int abs_data_align;
486
9c2799c2 487 gas_assert (DWARF2_CIE_DATA_ALIGNMENT != 0);
2be24b54 488 cfi_add_CFA_insn_reg_offset (DW_CFA_offset, regno, offset);
fa87b337
RH
489
490 abs_data_align = (DWARF2_CIE_DATA_ALIGNMENT < 0
491 ? -DWARF2_CIE_DATA_ALIGNMENT : DWARF2_CIE_DATA_ALIGNMENT);
492 if (offset % abs_data_align)
493 as_bad (_("register save offset not a multiple of %u"), abs_data_align);
a4447b93 494}
54cfded0 495
a4447b93 496/* Add a DW_CFA_def_cfa record to the CFI data. */
54cfded0 497
a4447b93
RH
498void
499cfi_add_CFA_def_cfa (unsigned regno, offsetT offset)
500{
2be24b54 501 cfi_add_CFA_insn_reg_offset (DW_CFA_def_cfa, regno, offset);
ae424f82 502 frchain_now->frch_cfi_data->cur_cfa_offset = offset;
54cfded0
AM
503}
504
a4447b93
RH
505/* Add a DW_CFA_register record to the CFI data. */
506
507void
508cfi_add_CFA_register (unsigned reg1, unsigned reg2)
54cfded0 509{
2be24b54 510 cfi_add_CFA_insn_reg_reg (DW_CFA_register, reg1, reg2);
54cfded0
AM
511}
512
a4447b93
RH
513/* Add a DW_CFA_def_cfa_register record to the CFI data. */
514
515void
516cfi_add_CFA_def_cfa_register (unsigned regno)
54cfded0 517{
2be24b54 518 cfi_add_CFA_insn_reg (DW_CFA_def_cfa_register, regno);
54cfded0
AM
519}
520
a4447b93
RH
521/* Add a DW_CFA_def_cfa_offset record to the CFI data. */
522
54cfded0 523void
a4447b93 524cfi_add_CFA_def_cfa_offset (offsetT offset)
54cfded0 525{
2be24b54 526 cfi_add_CFA_insn_offset (DW_CFA_def_cfa_offset, offset);
ae424f82 527 frchain_now->frch_cfi_data->cur_cfa_offset = offset;
a4447b93 528}
54cfded0 529
2be24b54
ML
530void
531cfi_add_CFA_restore (unsigned regno)
532{
533 cfi_add_CFA_insn_reg (DW_CFA_restore, regno);
534}
535
536void
537cfi_add_CFA_undefined (unsigned regno)
538{
539 cfi_add_CFA_insn_reg (DW_CFA_undefined, regno);
540}
541
542void
543cfi_add_CFA_same_value (unsigned regno)
544{
545 cfi_add_CFA_insn_reg (DW_CFA_same_value, regno);
546}
547
548void
549cfi_add_CFA_remember_state (void)
550{
fa87b337
RH
551 struct cfa_save_data *p;
552
2be24b54 553 cfi_add_CFA_insn (DW_CFA_remember_state);
fa87b337 554
1e9cc1c2 555 p = (struct cfa_save_data *) xmalloc (sizeof (*p));
ae424f82
JJ
556 p->cfa_offset = frchain_now->frch_cfi_data->cur_cfa_offset;
557 p->next = frchain_now->frch_cfi_data->cfa_save_stack;
558 frchain_now->frch_cfi_data->cfa_save_stack = p;
2be24b54
ML
559}
560
561void
562cfi_add_CFA_restore_state (void)
563{
fa87b337
RH
564 struct cfa_save_data *p;
565
2be24b54 566 cfi_add_CFA_insn (DW_CFA_restore_state);
fa87b337 567
ae424f82 568 p = frchain_now->frch_cfi_data->cfa_save_stack;
fa87b337
RH
569 if (p)
570 {
ae424f82
JJ
571 frchain_now->frch_cfi_data->cur_cfa_offset = p->cfa_offset;
572 frchain_now->frch_cfi_data->cfa_save_stack = p->next;
fa87b337
RH
573 free (p);
574 }
289040ca
NC
575 else
576 as_bad (_("CFI state restore without previous remember"));
2be24b54
ML
577}
578
a4447b93
RH
579\f
580/* Parse CFI assembler directives. */
54cfded0 581
a4447b93 582static void dot_cfi (int);
cdfbf930 583static void dot_cfi_escape (int);
38462edf 584static void dot_cfi_sections (int);
a4447b93
RH
585static void dot_cfi_startproc (int);
586static void dot_cfi_endproc (int);
9b8ae42e
JJ
587static void dot_cfi_personality (int);
588static void dot_cfi_lsda (int);
f1c4cc75 589static void dot_cfi_val_encoded_addr (int);
54cfded0 590
a4447b93 591/* Fake CFI type; outside the byte range of any real CFI insn. */
2be24b54
ML
592#define CFI_adjust_cfa_offset 0x100
593#define CFI_return_column 0x101
fa87b337 594#define CFI_rel_offset 0x102
cdfbf930 595#define CFI_escape 0x103
63752a75 596#define CFI_signal_frame 0x104
f1c4cc75 597#define CFI_val_encoded_addr 0x105
54cfded0 598
a4447b93
RH
599const pseudo_typeS cfi_pseudo_table[] =
600 {
38462edf 601 { "cfi_sections", dot_cfi_sections, 0 },
a4447b93
RH
602 { "cfi_startproc", dot_cfi_startproc, 0 },
603 { "cfi_endproc", dot_cfi_endproc, 0 },
604 { "cfi_def_cfa", dot_cfi, DW_CFA_def_cfa },
605 { "cfi_def_cfa_register", dot_cfi, DW_CFA_def_cfa_register },
606 { "cfi_def_cfa_offset", dot_cfi, DW_CFA_def_cfa_offset },
607 { "cfi_adjust_cfa_offset", dot_cfi, CFI_adjust_cfa_offset },
608 { "cfi_offset", dot_cfi, DW_CFA_offset },
fa87b337 609 { "cfi_rel_offset", dot_cfi, CFI_rel_offset },
a4447b93 610 { "cfi_register", dot_cfi, DW_CFA_register },
2be24b54
ML
611 { "cfi_return_column", dot_cfi, CFI_return_column },
612 { "cfi_restore", dot_cfi, DW_CFA_restore },
613 { "cfi_undefined", dot_cfi, DW_CFA_undefined },
614 { "cfi_same_value", dot_cfi, DW_CFA_same_value },
615 { "cfi_remember_state", dot_cfi, DW_CFA_remember_state },
616 { "cfi_restore_state", dot_cfi, DW_CFA_restore_state },
6749011b 617 { "cfi_window_save", dot_cfi, DW_CFA_GNU_window_save },
cdfbf930 618 { "cfi_escape", dot_cfi_escape, 0 },
63752a75 619 { "cfi_signal_frame", dot_cfi, CFI_signal_frame },
9b8ae42e
JJ
620 { "cfi_personality", dot_cfi_personality, 0 },
621 { "cfi_lsda", dot_cfi_lsda, 0 },
f1c4cc75 622 { "cfi_val_encoded_addr", dot_cfi_val_encoded_addr, 0 },
a4447b93
RH
623 { NULL, NULL, 0 }
624 };
54cfded0
AM
625
626static void
a4447b93 627cfi_parse_separator (void)
54cfded0 628{
a4447b93
RH
629 SKIP_WHITESPACE ();
630 if (*input_line_pointer == ',')
631 input_line_pointer++;
632 else
633 as_bad (_("missing separator"));
54cfded0
AM
634}
635
a60de03c
JB
636#ifndef tc_parse_to_dw2regnum
637static void
72b016b4 638tc_parse_to_dw2regnum (expressionS *exp)
54cfded0 639{
a60de03c 640# ifdef tc_regname_to_dw2regnum
a4447b93
RH
641 SKIP_WHITESPACE ();
642 if (is_name_beginner (*input_line_pointer)
643 || (*input_line_pointer == '%'
644 && is_name_beginner (*++input_line_pointer)))
645 {
646 char *name, c;
647
648 name = input_line_pointer;
649 c = get_symbol_end ();
650
a60de03c
JB
651 exp->X_op = O_constant;
652 exp->X_add_number = tc_regname_to_dw2regnum (name);
54cfded0 653
a4447b93 654 *input_line_pointer = c;
a4447b93 655 }
a60de03c
JB
656 else
657# endif
658 expression_and_evaluate (exp);
659}
a4447b93
RH
660#endif
661
a60de03c
JB
662static unsigned
663cfi_parse_reg (void)
664{
665 int regno;
666 expressionS exp;
667
668 tc_parse_to_dw2regnum (&exp);
a4447b93 669 switch (exp.X_op)
54cfded0 670 {
a4447b93
RH
671 case O_register:
672 case O_constant:
673 regno = exp.X_add_number;
674 break;
675
676 default:
a60de03c
JB
677 regno = -1;
678 break;
679 }
680
681 if (regno < 0)
682 {
a4447b93
RH
683 as_bad (_("bad register expression"));
684 regno = 0;
54cfded0
AM
685 }
686
a4447b93
RH
687 return regno;
688}
689
690static offsetT
691cfi_parse_const (void)
692{
693 return get_absolute_expression ();
54cfded0
AM
694}
695
696static void
a4447b93 697dot_cfi (int arg)
54cfded0 698{
a4447b93
RH
699 offsetT offset;
700 unsigned reg1, reg2;
54cfded0 701
ae424f82 702 if (frchain_now->frch_cfi_data == NULL)
54cfded0
AM
703 {
704 as_bad (_("CFI instruction used without previous .cfi_startproc"));
7c9c8381 705 ignore_rest_of_line ();
54cfded0
AM
706 return;
707 }
708
a4447b93 709 /* If the last address was not at the current PC, advance to current. */
ae424f82
JJ
710 if (symbol_get_frag (frchain_now->frch_cfi_data->last_address) != frag_now
711 || S_GET_VALUE (frchain_now->frch_cfi_data->last_address)
712 != frag_now_fix ())
a4447b93 713 cfi_add_advance_loc (symbol_temp_new_now ());
54cfded0
AM
714
715 switch (arg)
716 {
a4447b93 717 case DW_CFA_offset:
a4447b93
RH
718 reg1 = cfi_parse_reg ();
719 cfi_parse_separator ();
720 offset = cfi_parse_const ();
2be24b54
ML
721 cfi_add_CFA_offset (reg1, offset);
722 break;
a4447b93 723
fa87b337
RH
724 case CFI_rel_offset:
725 reg1 = cfi_parse_reg ();
726 cfi_parse_separator ();
727 offset = cfi_parse_const ();
ae424f82
JJ
728 cfi_add_CFA_offset (reg1,
729 offset - frchain_now->frch_cfi_data->cur_cfa_offset);
fa87b337
RH
730 break;
731
2be24b54
ML
732 case DW_CFA_def_cfa:
733 reg1 = cfi_parse_reg ();
734 cfi_parse_separator ();
735 offset = cfi_parse_const ();
736 cfi_add_CFA_def_cfa (reg1, offset);
54cfded0
AM
737 break;
738
a4447b93
RH
739 case DW_CFA_register:
740 reg1 = cfi_parse_reg ();
741 cfi_parse_separator ();
742 reg2 = cfi_parse_reg ();
a4447b93 743 cfi_add_CFA_register (reg1, reg2);
39b82151
ML
744 break;
745
a4447b93
RH
746 case DW_CFA_def_cfa_register:
747 reg1 = cfi_parse_reg ();
748 cfi_add_CFA_def_cfa_register (reg1);
54cfded0
AM
749 break;
750
a4447b93
RH
751 case DW_CFA_def_cfa_offset:
752 offset = cfi_parse_const ();
753 cfi_add_CFA_def_cfa_offset (offset);
54cfded0
AM
754 break;
755
54cfded0 756 case CFI_adjust_cfa_offset:
a4447b93 757 offset = cfi_parse_const ();
ae424f82
JJ
758 cfi_add_CFA_def_cfa_offset (frchain_now->frch_cfi_data->cur_cfa_offset
759 + offset);
54cfded0
AM
760 break;
761
2be24b54 762 case DW_CFA_restore:
b57d375b
JB
763 for (;;)
764 {
765 reg1 = cfi_parse_reg ();
766 cfi_add_CFA_restore (reg1);
767 SKIP_WHITESPACE ();
768 if (*input_line_pointer != ',')
769 break;
770 ++input_line_pointer;
771 }
2be24b54
ML
772 break;
773
774 case DW_CFA_undefined:
b57d375b
JB
775 for (;;)
776 {
777 reg1 = cfi_parse_reg ();
778 cfi_add_CFA_undefined (reg1);
779 SKIP_WHITESPACE ();
780 if (*input_line_pointer != ',')
781 break;
782 ++input_line_pointer;
783 }
2be24b54
ML
784 break;
785
786 case DW_CFA_same_value:
787 reg1 = cfi_parse_reg ();
788 cfi_add_CFA_same_value (reg1);
789 break;
790
791 case CFI_return_column:
792 reg1 = cfi_parse_reg ();
793 cfi_set_return_column (reg1);
794 break;
795
796 case DW_CFA_remember_state:
797 cfi_add_CFA_remember_state ();
798 break;
799
800 case DW_CFA_restore_state:
801 cfi_add_CFA_restore_state ();
802 break;
803
364b6d8b
JJ
804 case DW_CFA_GNU_window_save:
805 cfi_add_CFA_insn (DW_CFA_GNU_window_save);
806 break;
807
63752a75 808 case CFI_signal_frame:
ae424f82 809 frchain_now->frch_cfi_data->cur_fde_data->signal_frame = 1;
63752a75
JJ
810 break;
811
54cfded0 812 default:
a4447b93 813 abort ();
54cfded0 814 }
54cfded0 815
a4447b93 816 demand_empty_rest_of_line ();
54cfded0
AM
817}
818
cdfbf930
RH
819static void
820dot_cfi_escape (int ignored ATTRIBUTE_UNUSED)
821{
822 struct cfi_escape_data *head, **tail, *e;
823 struct cfi_insn_data *insn;
824
ae424f82 825 if (frchain_now->frch_cfi_data == NULL)
cdfbf930
RH
826 {
827 as_bad (_("CFI instruction used without previous .cfi_startproc"));
7c9c8381 828 ignore_rest_of_line ();
cdfbf930
RH
829 return;
830 }
831
832 /* If the last address was not at the current PC, advance to current. */
ae424f82
JJ
833 if (symbol_get_frag (frchain_now->frch_cfi_data->last_address) != frag_now
834 || S_GET_VALUE (frchain_now->frch_cfi_data->last_address)
835 != frag_now_fix ())
cdfbf930
RH
836 cfi_add_advance_loc (symbol_temp_new_now ());
837
838 tail = &head;
839 do
840 {
1e9cc1c2 841 e = (struct cfi_escape_data *) xmalloc (sizeof (*e));
cdfbf930
RH
842 do_parse_cons_expression (&e->exp, 1);
843 *tail = e;
844 tail = &e->next;
845 }
846 while (*input_line_pointer++ == ',');
847 *tail = NULL;
848
849 insn = alloc_cfi_insn_data ();
850 insn->insn = CFI_escape;
851 insn->u.esc = head;
7c9c8381
JB
852
853 --input_line_pointer;
854 demand_empty_rest_of_line ();
cdfbf930
RH
855}
856
9b8ae42e
JJ
857static void
858dot_cfi_personality (int ignored ATTRIBUTE_UNUSED)
859{
860 struct fde_entry *fde;
861 offsetT encoding;
862
863 if (frchain_now->frch_cfi_data == NULL)
864 {
865 as_bad (_("CFI instruction used without previous .cfi_startproc"));
866 ignore_rest_of_line ();
867 return;
868 }
869
870 fde = frchain_now->frch_cfi_data->cur_fde_data;
f1c4cc75 871 encoding = cfi_parse_const ();
9b8ae42e
JJ
872 if (encoding == DW_EH_PE_omit)
873 {
874 demand_empty_rest_of_line ();
875 fde->per_encoding = encoding;
876 return;
877 }
878
879 if ((encoding & 0xff) != encoding
880 || ((encoding & 0x70) != 0
3dd24306 881#if CFI_DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr
9b8ae42e
JJ
882 && (encoding & 0x70) != DW_EH_PE_pcrel
883#endif
884 )
885 /* leb128 can be handled, but does something actually need it? */
886 || (encoding & 7) == DW_EH_PE_uleb128
887 || (encoding & 7) > DW_EH_PE_udata8)
888 {
889 as_bad (_("invalid or unsupported encoding in .cfi_personality"));
890 ignore_rest_of_line ();
891 return;
892 }
893
894 if (*input_line_pointer++ != ',')
895 {
896 as_bad (_(".cfi_personality requires encoding and symbol arguments"));
897 ignore_rest_of_line ();
898 return;
899 }
900
901 expression_and_evaluate (&fde->personality);
902 switch (fde->personality.X_op)
903 {
904 case O_symbol:
905 break;
906 case O_constant:
907 if ((encoding & 0x70) == DW_EH_PE_pcrel)
908 encoding = DW_EH_PE_omit;
909 break;
910 default:
911 encoding = DW_EH_PE_omit;
912 break;
913 }
914
915 fde->per_encoding = encoding;
916
917 if (encoding == DW_EH_PE_omit)
918 {
919 as_bad (_("wrong second argument to .cfi_personality"));
920 ignore_rest_of_line ();
921 return;
922 }
923
924 demand_empty_rest_of_line ();
925}
926
927static void
928dot_cfi_lsda (int ignored ATTRIBUTE_UNUSED)
929{
930 struct fde_entry *fde;
931 offsetT encoding;
932
933 if (frchain_now->frch_cfi_data == NULL)
934 {
935 as_bad (_("CFI instruction used without previous .cfi_startproc"));
936 ignore_rest_of_line ();
937 return;
938 }
939
940 fde = frchain_now->frch_cfi_data->cur_fde_data;
f1c4cc75 941 encoding = cfi_parse_const ();
9b8ae42e
JJ
942 if (encoding == DW_EH_PE_omit)
943 {
944 demand_empty_rest_of_line ();
945 fde->lsda_encoding = encoding;
946 return;
947 }
948
949 if ((encoding & 0xff) != encoding
950 || ((encoding & 0x70) != 0
2c678708 951#if CFI_DIFF_LSDA_OK || defined tc_cfi_emit_pcrel_expr
9b8ae42e
JJ
952 && (encoding & 0x70) != DW_EH_PE_pcrel
953#endif
954 )
955 /* leb128 can be handled, but does something actually need it? */
956 || (encoding & 7) == DW_EH_PE_uleb128
957 || (encoding & 7) > DW_EH_PE_udata8)
958 {
959 as_bad (_("invalid or unsupported encoding in .cfi_lsda"));
960 ignore_rest_of_line ();
961 return;
962 }
963
964 if (*input_line_pointer++ != ',')
965 {
966 as_bad (_(".cfi_lsda requires encoding and symbol arguments"));
967 ignore_rest_of_line ();
968 return;
969 }
970
971 fde->lsda_encoding = encoding;
972
973 expression_and_evaluate (&fde->lsda);
974 switch (fde->lsda.X_op)
975 {
976 case O_symbol:
977 break;
978 case O_constant:
979 if ((encoding & 0x70) == DW_EH_PE_pcrel)
980 encoding = DW_EH_PE_omit;
981 break;
982 default:
983 encoding = DW_EH_PE_omit;
984 break;
985 }
986
987 fde->lsda_encoding = encoding;
988
989 if (encoding == DW_EH_PE_omit)
990 {
991 as_bad (_("wrong second argument to .cfi_lsda"));
992 ignore_rest_of_line ();
993 return;
994 }
995
996 demand_empty_rest_of_line ();
997}
998
f1c4cc75
RH
999static void
1000dot_cfi_val_encoded_addr (int ignored ATTRIBUTE_UNUSED)
1001{
1002 struct cfi_insn_data *insn_ptr;
1003 offsetT encoding;
1004
1005 if (frchain_now->frch_cfi_data == NULL)
1006 {
1007 as_bad (_("CFI instruction used without previous .cfi_startproc"));
1008 ignore_rest_of_line ();
1009 return;
1010 }
1011
1012 /* If the last address was not at the current PC, advance to current. */
1013 if (symbol_get_frag (frchain_now->frch_cfi_data->last_address) != frag_now
1014 || S_GET_VALUE (frchain_now->frch_cfi_data->last_address)
1015 != frag_now_fix ())
1016 cfi_add_advance_loc (symbol_temp_new_now ());
1017
1018 insn_ptr = alloc_cfi_insn_data ();
1019 insn_ptr->insn = CFI_val_encoded_addr;
72b016b4 1020
f1c4cc75
RH
1021 insn_ptr->u.ea.reg = cfi_parse_reg ();
1022
1023 cfi_parse_separator ();
1024 encoding = cfi_parse_const ();
1025 if ((encoding & 0xff) != encoding
1026 || ((encoding & 0x70) != 0
1027#if CFI_DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr
1028 && (encoding & 0x70) != DW_EH_PE_pcrel
1029#endif
1030 )
1031 /* leb128 can be handled, but does something actually need it? */
1032 || (encoding & 7) == DW_EH_PE_uleb128
1033 || (encoding & 7) > DW_EH_PE_udata8)
1034 {
1035 as_bad (_("invalid or unsupported encoding in .cfi_lsda"));
1036 encoding = DW_EH_PE_omit;
1037 }
1038
1039 cfi_parse_separator ();
1040 expression_and_evaluate (&insn_ptr->u.ea.exp);
1041 switch (insn_ptr->u.ea.exp.X_op)
1042 {
1043 case O_symbol:
1044 break;
1045 case O_constant:
1046 if ((encoding & 0x70) != DW_EH_PE_pcrel)
1047 break;
1048 default:
1049 encoding = DW_EH_PE_omit;
1050 break;
1051 }
1052
1053 insn_ptr->u.ea.encoding = encoding;
1054 if (encoding == DW_EH_PE_omit)
1055 {
1056 as_bad (_("wrong third argument to .cfi_val_encoded_addr"));
1057 ignore_rest_of_line ();
1058 return;
1059 }
1060
1061 demand_empty_rest_of_line ();
1062}
1063
38462edf
JJ
1064/* By default emit .eh_frame only, not .debug_frame. */
1065#define CFI_EMIT_eh_frame (1 << 0)
1066#define CFI_EMIT_debug_frame (1 << 1)
1067static int cfi_sections = CFI_EMIT_eh_frame;
1068
1069static void
1070dot_cfi_sections (int ignored ATTRIBUTE_UNUSED)
1071{
1072 int sections = 0;
1073
1074 SKIP_WHITESPACE ();
1075 if (is_name_beginner (*input_line_pointer))
1076 while (1)
1077 {
1078 char *name, c;
1079
1080 name = input_line_pointer;
1081 c = get_symbol_end ();
1082
72b016b4
NC
1083 if (strncmp (name, ".eh_frame", sizeof ".eh_frame") == 0
1084 && name[9] != '_')
38462edf 1085 sections |= CFI_EMIT_eh_frame;
72b016b4 1086 else if (strncmp (name, ".debug_frame", sizeof ".debug_frame") == 0)
38462edf
JJ
1087 sections |= CFI_EMIT_debug_frame;
1088 else
1089 {
1090 *input_line_pointer = c;
1091 input_line_pointer = name;
1092 break;
1093 }
1094
1095 *input_line_pointer = c;
1096 SKIP_WHITESPACE ();
1097 if (*input_line_pointer == ',')
1098 {
1099 name = input_line_pointer++;
1100 SKIP_WHITESPACE ();
1101 if (!is_name_beginner (*input_line_pointer))
1102 {
1103 input_line_pointer = name;
1104 break;
1105 }
1106 }
1107 else if (is_name_beginner (*input_line_pointer))
1108 break;
1109 }
1110
1111 demand_empty_rest_of_line ();
1112 cfi_sections = sections;
1113}
1114
54cfded0 1115static void
a4447b93 1116dot_cfi_startproc (int ignored ATTRIBUTE_UNUSED)
54cfded0 1117{
a4447b93 1118 int simple = 0;
39b82151 1119
ae424f82 1120 if (frchain_now->frch_cfi_data != NULL)
54cfded0
AM
1121 {
1122 as_bad (_("previous CFI entry not closed (missing .cfi_endproc)"));
7c9c8381 1123 ignore_rest_of_line ();
54cfded0
AM
1124 return;
1125 }
1126
a4447b93 1127 cfi_new_fde (symbol_temp_new_now ());
39b82151 1128
a4447b93
RH
1129 SKIP_WHITESPACE ();
1130 if (is_name_beginner (*input_line_pointer))
1131 {
1132 char *name, c;
54cfded0 1133
a4447b93
RH
1134 name = input_line_pointer;
1135 c = get_symbol_end ();
54cfded0 1136
a4447b93
RH
1137 if (strcmp (name, "simple") == 0)
1138 {
1139 simple = 1;
1140 *input_line_pointer = c;
1141 }
1142 else
1143 input_line_pointer = name;
1144 }
1145 demand_empty_rest_of_line ();
1146
ae424f82 1147 frchain_now->frch_cfi_data->cur_cfa_offset = 0;
a4447b93 1148 if (!simple)
39b82151 1149 tc_cfi_frame_initial_instructions ();
54cfded0
AM
1150}
1151
a4447b93
RH
1152static void
1153dot_cfi_endproc (int ignored ATTRIBUTE_UNUSED)
1154{
ae424f82 1155 if (frchain_now->frch_cfi_data == NULL)
a4447b93
RH
1156 {
1157 as_bad (_(".cfi_endproc without corresponding .cfi_startproc"));
7c9c8381 1158 ignore_rest_of_line ();
a4447b93
RH
1159 return;
1160 }
54cfded0 1161
a4447b93 1162 cfi_end_fde (symbol_temp_new_now ());
7c9c8381
JB
1163
1164 demand_empty_rest_of_line ();
a4447b93 1165}
39b82151 1166
a4447b93
RH
1167\f
1168/* Emit a single byte into the current segment. */
54cfded0 1169
a4447b93
RH
1170static inline void
1171out_one (int byte)
54cfded0 1172{
a4447b93
RH
1173 FRAG_APPEND_1_CHAR (byte);
1174}
54cfded0 1175
a4447b93 1176/* Emit a two-byte word into the current segment. */
54cfded0 1177
a4447b93
RH
1178static inline void
1179out_two (int data)
1180{
1181 md_number_to_chars (frag_more (2), data, 2);
1182}
54cfded0 1183
a4447b93 1184/* Emit a four byte word into the current segment. */
54cfded0 1185
a4447b93
RH
1186static inline void
1187out_four (int data)
1188{
1189 md_number_to_chars (frag_more (4), data, 4);
1190}
1191
1192/* Emit an unsigned "little-endian base 128" number. */
54cfded0 1193
a4447b93
RH
1194static void
1195out_uleb128 (addressT value)
1196{
1197 output_leb128 (frag_more (sizeof_leb128 (value, 0)), value, 0);
54cfded0
AM
1198}
1199
a4447b93
RH
1200/* Emit an unsigned "little-endian base 128" number. */
1201
1202static void
1203out_sleb128 (offsetT value)
54cfded0 1204{
a4447b93
RH
1205 output_leb128 (frag_more (sizeof_leb128 (value, 1)), value, 1);
1206}
54cfded0 1207
a4447b93
RH
1208static void
1209output_cfi_insn (struct cfi_insn_data *insn)
1210{
1211 offsetT offset;
1212 unsigned int regno;
54cfded0 1213
a4447b93 1214 switch (insn->insn)
54cfded0 1215 {
a4447b93
RH
1216 case DW_CFA_advance_loc:
1217 {
1218 symbolS *from = insn->u.ll.lab1;
1219 symbolS *to = insn->u.ll.lab2;
1220
1221 if (symbol_get_frag (to) == symbol_get_frag (from))
1222 {
1223 addressT delta = S_GET_VALUE (to) - S_GET_VALUE (from);
1224 addressT scaled = delta / DWARF2_LINE_MIN_INSN_LENGTH;
1225
1226 if (scaled <= 0x3F)
1227 out_one (DW_CFA_advance_loc + scaled);
395e8345 1228 else if (scaled <= 0xFF)
a4447b93 1229 {
9b8ae42e 1230 out_one (DW_CFA_advance_loc1);
395e8345 1231 out_one (scaled);
a4447b93 1232 }
395e8345 1233 else if (scaled <= 0xFFFF)
a4447b93 1234 {
9b8ae42e 1235 out_one (DW_CFA_advance_loc2);
395e8345 1236 out_two (scaled);
a4447b93
RH
1237 }
1238 else
1239 {
9b8ae42e 1240 out_one (DW_CFA_advance_loc4);
395e8345 1241 out_four (scaled);
a4447b93
RH
1242 }
1243 }
1244 else
1245 {
1246 expressionS exp;
1247
1248 exp.X_op = O_subtract;
1249 exp.X_add_symbol = to;
1250 exp.X_op_symbol = from;
1251 exp.X_add_number = 0;
1252
1253 /* The code in ehopt.c expects that one byte of the encoding
1254 is already allocated to the frag. This comes from the way
1255 that it scans the .eh_frame section looking first for the
1256 .byte DW_CFA_advance_loc4. */
1fbfe785 1257 *frag_more (1) = DW_CFA_advance_loc4;
a4447b93
RH
1258
1259 frag_var (rs_cfa, 4, 0, DWARF2_LINE_MIN_INSN_LENGTH << 3,
1260 make_expr_symbol (&exp), frag_now_fix () - 1,
1261 (char *) frag_now);
1262 }
1263 }
1264 break;
1265
1266 case DW_CFA_def_cfa:
1267 offset = insn->u.ri.offset;
1268 if (offset < 0)
54cfded0 1269 {
a4447b93
RH
1270 out_one (DW_CFA_def_cfa_sf);
1271 out_uleb128 (insn->u.ri.reg);
dcb45a06 1272 out_sleb128 (offset / DWARF2_CIE_DATA_ALIGNMENT);
54cfded0
AM
1273 }
1274 else
1275 {
a4447b93
RH
1276 out_one (DW_CFA_def_cfa);
1277 out_uleb128 (insn->u.ri.reg);
1278 out_uleb128 (offset);
54cfded0
AM
1279 }
1280 break;
1281
a4447b93 1282 case DW_CFA_def_cfa_register:
2be24b54
ML
1283 case DW_CFA_undefined:
1284 case DW_CFA_same_value:
1285 out_one (insn->insn);
1286 out_uleb128 (insn->u.r);
54cfded0
AM
1287 break;
1288
a4447b93
RH
1289 case DW_CFA_def_cfa_offset:
1290 offset = insn->u.i;
1291 if (offset < 0)
1292 {
1293 out_one (DW_CFA_def_cfa_offset_sf);
dcb45a06 1294 out_sleb128 (offset / DWARF2_CIE_DATA_ALIGNMENT);
a4447b93
RH
1295 }
1296 else
1297 {
1298 out_one (DW_CFA_def_cfa_offset);
1299 out_uleb128 (offset);
1300 }
54cfded0
AM
1301 break;
1302
2be24b54
ML
1303 case DW_CFA_restore:
1304 regno = insn->u.r;
1305 if (regno <= 0x3F)
1306 {
1307 out_one (DW_CFA_restore + regno);
1308 }
1309 else
1310 {
1311 out_one (DW_CFA_restore_extended);
1312 out_uleb128 (regno);
1313 }
1314 break;
1315
a4447b93
RH
1316 case DW_CFA_offset:
1317 regno = insn->u.ri.reg;
1318 offset = insn->u.ri.offset / DWARF2_CIE_DATA_ALIGNMENT;
1319 if (offset < 0)
1320 {
1233ae62 1321 out_one (DW_CFA_offset_extended_sf);
a4447b93
RH
1322 out_uleb128 (regno);
1323 out_sleb128 (offset);
1324 }
1325 else if (regno <= 0x3F)
1326 {
1327 out_one (DW_CFA_offset + regno);
1328 out_uleb128 (offset);
1329 }
54cfded0
AM
1330 else
1331 {
a4447b93
RH
1332 out_one (DW_CFA_offset_extended);
1333 out_uleb128 (regno);
1334 out_uleb128 (offset);
54cfded0 1335 }
54cfded0
AM
1336 break;
1337
a4447b93
RH
1338 case DW_CFA_register:
1339 out_one (DW_CFA_register);
1340 out_uleb128 (insn->u.rr.reg1);
1341 out_uleb128 (insn->u.rr.reg2);
39b82151
ML
1342 break;
1343
2be24b54
ML
1344 case DW_CFA_remember_state:
1345 case DW_CFA_restore_state:
2be24b54 1346 out_one (insn->insn);
54cfded0
AM
1347 break;
1348
364b6d8b
JJ
1349 case DW_CFA_GNU_window_save:
1350 out_one (DW_CFA_GNU_window_save);
1351 break;
1352
cdfbf930
RH
1353 case CFI_escape:
1354 {
1355 struct cfi_escape_data *e;
1356 for (e = insn->u.esc; e ; e = e->next)
1357 emit_expr (&e->exp, 1);
1358 break;
1359 }
1360
f1c4cc75
RH
1361 case CFI_val_encoded_addr:
1362 {
1363 unsigned encoding = insn->u.ea.encoding;
1364 offsetT encoding_size;
1365
1366 if (encoding == DW_EH_PE_omit)
1367 break;
1368 out_one (DW_CFA_val_expression);
1369 out_uleb128 (insn->u.ea.reg);
1370
1371 switch (encoding & 0x7)
1372 {
1373 case DW_EH_PE_absptr:
1374 encoding_size = DWARF2_ADDR_SIZE (stdoutput);
1375 break;
1376 case DW_EH_PE_udata2:
1377 encoding_size = 2;
1378 break;
1379 case DW_EH_PE_udata4:
1380 encoding_size = 4;
1381 break;
1382 case DW_EH_PE_udata8:
1383 encoding_size = 8;
1384 break;
1385 default:
1386 abort ();
1387 }
1388
1389 /* If the user has requested absolute encoding,
1390 then use the smaller DW_OP_addr encoding. */
1391 if (insn->u.ea.encoding == DW_EH_PE_absptr)
1392 {
1393 out_uleb128 (1 + encoding_size);
1394 out_one (DW_OP_addr);
1395 }
1396 else
1397 {
1398 out_uleb128 (1 + 1 + encoding_size);
1399 out_one (DW_OP_GNU_encoded_addr);
1400 out_one (encoding);
1401
1402 if ((encoding & 0x70) == DW_EH_PE_pcrel)
1403 {
1404#if CFI_DIFF_EXPR_OK
1405 insn->u.ea.exp.X_op = O_subtract;
1406 insn->u.ea.exp.X_op_symbol = symbol_temp_new_now ();
1407#elif defined (tc_cfi_emit_pcrel_expr)
c0cf08ad 1408 tc_cfi_emit_pcrel_expr (&insn->u.ea.exp, encoding_size);
f1c4cc75
RH
1409 break;
1410#else
1411 abort ();
1412#endif
1413 }
1414 }
1415 emit_expr (&insn->u.ea.exp, encoding_size);
1416 }
1417 break;
72b016b4 1418
54cfded0 1419 default:
a4447b93 1420 abort ();
54cfded0 1421 }
54cfded0
AM
1422}
1423
9b8ae42e
JJ
1424static offsetT
1425encoding_size (unsigned char encoding)
1426{
1427 if (encoding == DW_EH_PE_omit)
1428 return 0;
1429 switch (encoding & 0x7)
1430 {
1431 case 0:
1432 return bfd_get_arch_size (stdoutput) == 64 ? 8 : 4;
1433 case DW_EH_PE_udata2:
1434 return 2;
1435 case DW_EH_PE_udata4:
1436 return 4;
1437 case DW_EH_PE_udata8:
1438 return 8;
1439 default:
1440 abort ();
1441 }
1442}
1443
54cfded0 1444static void
38462edf 1445output_cie (struct cie_entry *cie, bfd_boolean eh_frame, int align)
54cfded0 1446{
a4447b93 1447 symbolS *after_size_address, *end_address;
7c0295b1 1448 expressionS exp;
a4447b93 1449 struct cfi_insn_data *i;
9b8ae42e 1450 offsetT augmentation_size;
8c9b70b1 1451 int enc;
38462edf 1452 enum dwarf2_format fmt = DWARF2_FORMAT (now_seg);
a4447b93
RH
1453
1454 cie->start_address = symbol_temp_new_now ();
1455 after_size_address = symbol_temp_make ();
1456 end_address = symbol_temp_make ();
1457
1458 exp.X_op = O_subtract;
1459 exp.X_add_symbol = end_address;
1460 exp.X_op_symbol = after_size_address;
1461 exp.X_add_number = 0;
1462
38462edf
JJ
1463 if (eh_frame || fmt == dwarf2_format_32bit)
1464 emit_expr (&exp, 4); /* Length. */
1465 else
1466 {
1467 if (fmt == dwarf2_format_64bit)
1468 out_four (-1);
1469 emit_expr (&exp, 8); /* Length. */
1470 }
a4447b93 1471 symbol_set_value_now (after_size_address);
38462edf
JJ
1472 if (eh_frame)
1473 out_four (0); /* CIE id. */
1474 else
1475 {
1476 out_four (-1); /* CIE id. */
1477 if (fmt != dwarf2_format_32bit)
1478 out_four (-1);
1479 }
289040ca 1480 out_one (DW_CIE_VERSION); /* Version. */
38462edf
JJ
1481 if (eh_frame)
1482 {
1483 out_one ('z'); /* Augmentation. */
1484 if (cie->per_encoding != DW_EH_PE_omit)
1485 out_one ('P');
1486 if (cie->lsda_encoding != DW_EH_PE_omit)
1487 out_one ('L');
1488 out_one ('R');
38462edf 1489 }
d905c788
TS
1490 if (cie->signal_frame)
1491 out_one ('S');
a4447b93 1492 out_one (0);
289040ca
NC
1493 out_uleb128 (DWARF2_LINE_MIN_INSN_LENGTH); /* Code alignment. */
1494 out_sleb128 (DWARF2_CIE_DATA_ALIGNMENT); /* Data alignment. */
0da76f83
NC
1495 if (DW_CIE_VERSION == 1) /* Return column. */
1496 out_one (cie->return_column);
1497 else
1498 out_uleb128 (cie->return_column);
38462edf
JJ
1499 if (eh_frame)
1500 {
1501 augmentation_size = 1 + (cie->lsda_encoding != DW_EH_PE_omit);
1502 if (cie->per_encoding != DW_EH_PE_omit)
1503 augmentation_size += 1 + encoding_size (cie->per_encoding);
1504 out_uleb128 (augmentation_size); /* Augmentation size. */
4e4e1355
TS
1505
1506 if (cie->per_encoding != DW_EH_PE_omit)
9b8ae42e 1507 {
4e4e1355
TS
1508 offsetT size = encoding_size (cie->per_encoding);
1509 out_one (cie->per_encoding);
1510 exp = cie->personality;
1511 if ((cie->per_encoding & 0x70) == DW_EH_PE_pcrel)
1512 {
3dd24306 1513#if CFI_DIFF_EXPR_OK
4e4e1355
TS
1514 exp.X_op = O_subtract;
1515 exp.X_op_symbol = symbol_temp_new_now ();
1516 emit_expr (&exp, size);
9b8ae42e 1517#elif defined (tc_cfi_emit_pcrel_expr)
4e4e1355 1518 tc_cfi_emit_pcrel_expr (&exp, size);
9b8ae42e 1519#else
4e4e1355 1520 abort ();
9b8ae42e 1521#endif
4e4e1355
TS
1522 }
1523 else
1524 emit_expr (&exp, size);
9b8ae42e 1525 }
4e4e1355
TS
1526
1527 if (cie->lsda_encoding != DW_EH_PE_omit)
1528 out_one (cie->lsda_encoding);
9b8ae42e 1529 }
8c9b70b1
RH
1530
1531 switch (DWARF2_FDE_RELOC_SIZE)
1532 {
1533 case 2:
1534 enc = DW_EH_PE_sdata2;
1535 break;
1536 case 4:
1537 enc = DW_EH_PE_sdata4;
1538 break;
1539 case 8:
1540 enc = DW_EH_PE_sdata8;
1541 break;
1542 default:
1543 abort ();
1544 }
3dd24306 1545#if CFI_DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr
8c9b70b1 1546 enc |= DW_EH_PE_pcrel;
364b6d8b 1547#endif
38462edf
JJ
1548 if (eh_frame)
1549 out_one (enc);
a4447b93
RH
1550
1551 if (cie->first)
72b016b4
NC
1552 {
1553 for (i = cie->first; i != cie->last; i = i->next)
1554 {
1555 if (i->cur_seg != cie->cur_seg)
1556 continue;
1557 output_cfi_insn (i);
1558 }
1559 }
a4447b93 1560
38462edf 1561 frag_align (align, DW_CFA_nop, 0);
a4447b93
RH
1562 symbol_set_value_now (end_address);
1563}
54cfded0 1564
a4447b93
RH
1565static void
1566output_fde (struct fde_entry *fde, struct cie_entry *cie,
38462edf
JJ
1567 bfd_boolean eh_frame, struct cfi_insn_data *first,
1568 int align)
a4447b93
RH
1569{
1570 symbolS *after_size_address, *end_address;
1571 expressionS exp;
9b8ae42e 1572 offsetT augmentation_size;
38462edf
JJ
1573 enum dwarf2_format fmt = DWARF2_FORMAT (now_seg);
1574 int offset_size;
1575 int addr_size;
54cfded0 1576
a4447b93
RH
1577 after_size_address = symbol_temp_make ();
1578 end_address = symbol_temp_make ();
54cfded0 1579
a4447b93
RH
1580 exp.X_op = O_subtract;
1581 exp.X_add_symbol = end_address;
1582 exp.X_op_symbol = after_size_address;
1583 exp.X_add_number = 0;
38462edf
JJ
1584 if (eh_frame || fmt == dwarf2_format_32bit)
1585 offset_size = 4;
1586 else
1587 {
1588 if (fmt == dwarf2_format_64bit)
1589 out_four (-1);
1590 offset_size = 8;
1591 }
1592 emit_expr (&exp, offset_size); /* Length. */
a4447b93 1593 symbol_set_value_now (after_size_address);
54cfded0 1594
38462edf
JJ
1595 if (eh_frame)
1596 {
3251495b 1597 exp.X_op = O_subtract;
38462edf
JJ
1598 exp.X_add_symbol = after_size_address;
1599 exp.X_op_symbol = cie->start_address;
3251495b
RH
1600 exp.X_add_number = 0;
1601 emit_expr (&exp, offset_size); /* CIE offset. */
38462edf
JJ
1602 }
1603 else
1604 {
3251495b 1605 TC_DWARF2_EMIT_OFFSET (cie->start_address, offset_size);
38462edf 1606 }
364b6d8b 1607
38462edf
JJ
1608 if (eh_frame)
1609 {
3251495b
RH
1610 exp.X_op = O_subtract;
1611 exp.X_add_number = 0;
3dd24306 1612#if CFI_DIFF_EXPR_OK
38462edf
JJ
1613 exp.X_add_symbol = fde->start_address;
1614 exp.X_op_symbol = symbol_temp_new_now ();
1615 emit_expr (&exp, DWARF2_FDE_RELOC_SIZE); /* Code offset. */
364b6d8b 1616#else
38462edf
JJ
1617 exp.X_op = O_symbol;
1618 exp.X_add_symbol = fde->start_address;
364b6d8b 1619#ifdef tc_cfi_emit_pcrel_expr
38462edf 1620 tc_cfi_emit_pcrel_expr (&exp, DWARF2_FDE_RELOC_SIZE); /* Code offset. */
364b6d8b 1621#else
38462edf 1622 emit_expr (&exp, DWARF2_FDE_RELOC_SIZE); /* Code offset. */
364b6d8b 1623#endif
364b6d8b 1624#endif
38462edf
JJ
1625 addr_size = DWARF2_FDE_RELOC_SIZE;
1626 }
1627 else
1628 {
3251495b 1629 exp.X_op = O_symbol;
38462edf 1630 exp.X_add_symbol = fde->start_address;
3251495b 1631 exp.X_add_number = 0;
38462edf
JJ
1632 addr_size = DWARF2_ADDR_SIZE (stdoutput);
1633 emit_expr (&exp, addr_size);
1634 }
54cfded0 1635
38462edf 1636 exp.X_op = O_subtract;
a4447b93 1637 exp.X_add_symbol = fde->end_address;
289040ca 1638 exp.X_op_symbol = fde->start_address; /* Code length. */
3251495b 1639 exp.X_add_number = 0;
38462edf 1640 emit_expr (&exp, addr_size);
54cfded0 1641
9b8ae42e 1642 augmentation_size = encoding_size (fde->lsda_encoding);
38462edf
JJ
1643 if (eh_frame)
1644 out_uleb128 (augmentation_size); /* Augmentation size. */
9b8ae42e
JJ
1645
1646 if (fde->lsda_encoding != DW_EH_PE_omit)
1647 {
1648 exp = fde->lsda;
1649 if ((fde->lsda_encoding & 0x70) == DW_EH_PE_pcrel)
1650 {
2c678708 1651#if CFI_DIFF_LSDA_OK
9b8ae42e
JJ
1652 exp.X_op = O_subtract;
1653 exp.X_op_symbol = symbol_temp_new_now ();
1654 emit_expr (&exp, augmentation_size);
1655#elif defined (tc_cfi_emit_pcrel_expr)
1656 tc_cfi_emit_pcrel_expr (&exp, augmentation_size);
1657#else
1658 abort ();
1659#endif
1660 }
1661 else
1662 emit_expr (&exp, augmentation_size);
1663 }
39b82151 1664
a4447b93 1665 for (; first; first = first->next)
72b016b4
NC
1666 {
1667 if (first->cur_seg == fde->cseg)
1668 output_cfi_insn (first);
1669 }
39b82151 1670
4df6ce47 1671 frag_align (align, DW_CFA_nop, 0);
a4447b93
RH
1672 symbol_set_value_now (end_address);
1673}
1674
1675static struct cie_entry *
38462edf
JJ
1676select_cie_for_fde (struct fde_entry *fde, bfd_boolean eh_frame,
1677 struct cfi_insn_data **pfirst, int align)
a4447b93
RH
1678{
1679 struct cfi_insn_data *i, *j;
1680 struct cie_entry *cie;
1681
1682 for (cie = cie_root; cie; cie = cie->next)
39b82151 1683 {
72b016b4
NC
1684 if (cie->cur_seg != fde->cseg
1685 || cie->return_column != fde->return_column
9b8ae42e
JJ
1686 || cie->signal_frame != fde->signal_frame
1687 || cie->per_encoding != fde->per_encoding
1688 || cie->lsda_encoding != fde->lsda_encoding)
a4447b93 1689 continue;
9b8ae42e
JJ
1690 if (cie->per_encoding != DW_EH_PE_omit)
1691 {
1692 if (cie->personality.X_op != fde->personality.X_op
1693 || cie->personality.X_add_number
1694 != fde->personality.X_add_number)
1695 continue;
1696 switch (cie->personality.X_op)
1697 {
1698 case O_constant:
1699 if (cie->personality.X_unsigned != fde->personality.X_unsigned)
1700 continue;
1701 break;
1702 case O_symbol:
1703 if (cie->personality.X_add_symbol
1704 != fde->personality.X_add_symbol)
1705 continue;
1706 break;
1707 default:
1708 abort ();
1709 }
1710 }
a4447b93
RH
1711 for (i = cie->first, j = fde->data;
1712 i != cie->last && j != NULL;
1713 i = i->next, j = j->next)
39b82151 1714 {
a4447b93
RH
1715 if (i->insn != j->insn)
1716 goto fail;
1717 switch (i->insn)
1718 {
1719 case DW_CFA_advance_loc:
289040ca
NC
1720 case DW_CFA_remember_state:
1721 /* We reached the first advance/remember in the FDE,
1722 but did not reach the end of the CIE list. */
a4447b93
RH
1723 goto fail;
1724
1725 case DW_CFA_offset:
1726 case DW_CFA_def_cfa:
1727 if (i->u.ri.reg != j->u.ri.reg)
1728 goto fail;
1729 if (i->u.ri.offset != j->u.ri.offset)
1730 goto fail;
1731 break;
1732
1733 case DW_CFA_register:
1734 if (i->u.rr.reg1 != j->u.rr.reg1)
1735 goto fail;
1736 if (i->u.rr.reg2 != j->u.rr.reg2)
1737 goto fail;
1738 break;
1739
1740 case DW_CFA_def_cfa_register:
2be24b54
ML
1741 case DW_CFA_restore:
1742 case DW_CFA_undefined:
1743 case DW_CFA_same_value:
a4447b93
RH
1744 if (i->u.r != j->u.r)
1745 goto fail;
1746 break;
1747
1748 case DW_CFA_def_cfa_offset:
1749 if (i->u.i != j->u.i)
1750 goto fail;
1751 break;
1752
cdfbf930 1753 case CFI_escape:
f1c4cc75 1754 case CFI_val_encoded_addr:
cdfbf930
RH
1755 /* Don't bother matching these for now. */
1756 goto fail;
1757
a4447b93
RH
1758 default:
1759 abort ();
1760 }
39b82151 1761 }
a4447b93
RH
1762
1763 /* Success if we reached the end of the CIE list, and we've either
289040ca
NC
1764 run out of FDE entries or we've encountered an advance,
1765 remember, or escape. */
e9fad691
AM
1766 if (i == cie->last
1767 && (!j
1768 || j->insn == DW_CFA_advance_loc
289040ca 1769 || j->insn == DW_CFA_remember_state
f1c4cc75
RH
1770 || j->insn == CFI_escape
1771 || j->insn == CFI_val_encoded_addr))
39b82151 1772 {
a4447b93
RH
1773 *pfirst = j;
1774 return cie;
39b82151
ML
1775 }
1776
a4447b93 1777 fail:;
54cfded0
AM
1778 }
1779
1e9cc1c2 1780 cie = (struct cie_entry *) xmalloc (sizeof (struct cie_entry));
a4447b93
RH
1781 cie->next = cie_root;
1782 cie_root = cie;
72b016b4 1783 cie->cur_seg = fde->cseg;
a4447b93 1784 cie->return_column = fde->return_column;
63752a75 1785 cie->signal_frame = fde->signal_frame;
9b8ae42e
JJ
1786 cie->per_encoding = fde->per_encoding;
1787 cie->lsda_encoding = fde->lsda_encoding;
1788 cie->personality = fde->personality;
a4447b93 1789 cie->first = fde->data;
54cfded0 1790
a4447b93 1791 for (i = cie->first; i ; i = i->next)
e9fad691 1792 if (i->insn == DW_CFA_advance_loc
289040ca 1793 || i->insn == DW_CFA_remember_state
f1c4cc75
RH
1794 || i->insn == CFI_escape
1795 || i->insn == CFI_val_encoded_addr)
a4447b93 1796 break;
54cfded0 1797
a4447b93
RH
1798 cie->last = i;
1799 *pfirst = i;
38462edf
JJ
1800
1801 output_cie (cie, eh_frame, align);
54cfded0 1802
a4447b93 1803 return cie;
54cfded0
AM
1804}
1805
38462edf
JJ
1806#ifdef md_reg_eh_frame_to_debug_frame
1807static void
72b016b4 1808cfi_change_reg_numbers (struct cfi_insn_data *insn, segT ccseg)
38462edf
JJ
1809{
1810 for (; insn; insn = insn->next)
72b016b4
NC
1811 {
1812 if (insn->cur_seg != ccseg)
1813 continue;
1814 switch (insn->insn)
1815 {
1816 case DW_CFA_advance_loc:
1817 case DW_CFA_def_cfa_offset:
1818 case DW_CFA_remember_state:
1819 case DW_CFA_restore_state:
1820 case DW_CFA_GNU_window_save:
1821 case CFI_escape:
1822 break;
38462edf 1823
72b016b4
NC
1824 case DW_CFA_def_cfa:
1825 case DW_CFA_offset:
1826 insn->u.ri.reg = md_reg_eh_frame_to_debug_frame (insn->u.ri.reg);
1827 break;
38462edf 1828
72b016b4
NC
1829 case DW_CFA_def_cfa_register:
1830 case DW_CFA_undefined:
1831 case DW_CFA_same_value:
1832 case DW_CFA_restore:
1833 insn->u.r = md_reg_eh_frame_to_debug_frame (insn->u.r);
1834 break;
38462edf 1835
72b016b4
NC
1836 case DW_CFA_register:
1837 insn->u.rr.reg1 = md_reg_eh_frame_to_debug_frame (insn->u.rr.reg1);
1838 insn->u.rr.reg2 = md_reg_eh_frame_to_debug_frame (insn->u.rr.reg2);
1839 break;
38462edf 1840
72b016b4
NC
1841 case CFI_val_encoded_addr:
1842 insn->u.ea.reg = md_reg_eh_frame_to_debug_frame (insn->u.ea.reg);
1843 break;
38462edf 1844
72b016b4
NC
1845 default:
1846 abort ();
1847 }
1848 }
38462edf
JJ
1849}
1850#else
72b016b4 1851#define cfi_change_reg_numbers(insn, cseg) do { } while (0)
38462edf
JJ
1852#endif
1853
72b016b4
NC
1854static segT
1855get_cfi_seg (segT cseg, const char *base, flagword flags, int align)
1856{
1857 struct dwcfi_seg_list *l;
1858
1859 l = dwcfi_hash_find_or_make (cseg, base, flags);
1860
1861 subseg_set (l->seg, l->subseg);
1862 record_alignment (l->seg, align);
1863 return l->seg;
1864}
1865
54cfded0 1866void
a4447b93 1867cfi_finish (void)
54cfded0 1868{
72b016b4
NC
1869 struct cie_entry *cie, *cie_next;
1870 segT cfi_seg, ccseg;
a4447b93 1871 struct fde_entry *fde;
72b016b4
NC
1872 struct cfi_insn_data *first;
1873 int save_flag_traditional_format, seek_next_seg;
54cfded0 1874
a4447b93
RH
1875 if (all_fde_data == 0)
1876 return;
54cfded0 1877
38462edf
JJ
1878 if ((cfi_sections & CFI_EMIT_eh_frame) != 0)
1879 {
38462edf
JJ
1880 /* Make sure check_eh_frame doesn't do anything with our output. */
1881 save_flag_traditional_format = flag_traditional_format;
1882 flag_traditional_format = 1;
eafbc43f 1883
72b016b4
NC
1884 do
1885 {
1886 ccseg = NULL;
1887 cfi_seg = NULL;
1888 seek_next_seg = 0;
1889 for (cie = cie_root; cie; cie = cie_next)
38462edf 1890 {
72b016b4
NC
1891 cie_next = cie->next;
1892 free ((void *) cie);
38462edf 1893 }
72b016b4 1894 cie_root = NULL;
38462edf 1895
72b016b4
NC
1896 for (fde = all_fde_data; fde ; fde = fde->next)
1897 {
1898 if (fde->handled != 0)
1899 continue;
1900 if (seek_next_seg && fde->cseg != ccseg)
1901 {
1902 seek_next_seg = 2;
1903 continue;
1904 }
1905 if (!seek_next_seg)
1906 {
1907 ccseg = fde->cseg;
1908 /* Open .eh_frame section. */
1909 cfi_seg = get_cfi_seg (ccseg, ".eh_frame",
1910 SEC_ALLOC | SEC_LOAD | SEC_DATA
1911 | DWARF2_EH_FRAME_READ_ONLY,
1912 EH_FRAME_ALIGNMENT);
1913#ifdef md_fix_up_eh_frame
1914 md_fix_up_eh_frame (cfi_seg);
1915#endif
1916 seek_next_seg = 1;
1917 }
1918 fde->handled = 1;
1919
1920 if (fde->end_address == NULL)
1921 {
1922 as_bad (_("open CFI at the end of file; missing .cfi_endproc directive"));
1923 fde->end_address = fde->start_address;
1924 }
1925
1926 cie = select_cie_for_fde (fde, TRUE, &first, 2);
1927 output_fde (fde, cie, TRUE, first,
1928 fde->next == NULL ? EH_FRAME_ALIGNMENT : 2);
1929 }
38462edf 1930 }
72b016b4
NC
1931 while (seek_next_seg == 2);
1932
1933 for (fde = all_fde_data; fde ; fde = fde->next)
1934 fde->handled = 0;
38462edf
JJ
1935
1936 flag_traditional_format = save_flag_traditional_format;
1937 }
1938
1939 if ((cfi_sections & CFI_EMIT_debug_frame) != 0)
a4447b93 1940 {
38462edf 1941 int alignment = ffs (DWARF2_ADDR_SIZE (stdoutput)) - 1;
a4447b93 1942
72b016b4
NC
1943 do
1944 {
1945 ccseg = NULL;
1946 cfi_seg = NULL;
1947 seek_next_seg = 0;
1948 for (cie = cie_root; cie; cie = cie_next)
38462edf 1949 {
72b016b4
NC
1950 cie_next = cie->next;
1951 free ((void *) cie);
38462edf 1952 }
72b016b4 1953 cie_root = NULL;
38462edf 1954
72b016b4
NC
1955 for (fde = all_fde_data; fde ; fde = fde->next)
1956 {
1957 if (fde->handled != 0)
1958 continue;
1959 if (seek_next_seg && fde->cseg != ccseg)
1960 {
1961 seek_next_seg = 2;
1962 continue;
1963 }
1964 if (!seek_next_seg)
1965 {
1966 ccseg = fde->cseg;
1967 /* Open .debug_frame section. */
1968 cfi_seg = get_cfi_seg (ccseg, ".debug_frame",
1969 SEC_READONLY | SEC_DEBUGGING,
1970 alignment);
1971 seek_next_seg = 1;
1972 }
1973 fde->handled = 1;
1974 if (fde->end_address == NULL)
1975 {
1976 as_bad (_("open CFI at the end of file; missing .cfi_endproc directive"));
1977 fde->end_address = fde->start_address;
1978 }
1979
1980 fde->per_encoding = DW_EH_PE_omit;
1981 fde->lsda_encoding = DW_EH_PE_omit;
1982 cfi_change_reg_numbers (fde->data, ccseg);
1983 cie = select_cie_for_fde (fde, FALSE, &first, alignment);
1984 output_fde (fde, cie, FALSE, first, alignment);
1985 }
38462edf 1986 }
72b016b4
NC
1987 while (seek_next_seg == 2);
1988
1989 for (fde = all_fde_data; fde ; fde = fde->next)
1990 fde->handled = 0;
38462edf 1991 }
54cfded0 1992}
0a7b15ff
JB
1993
1994#else /* TARGET_USE_CFIPOP */
d58a1929 1995
5ff2bd08 1996/* Emit an intelligible error message for missing support. */
d58a1929
RH
1997
1998static void
1999dot_cfi_dummy (int ignored ATTRIBUTE_UNUSED)
2000{
2001 as_bad (_("CFI is not supported for this target"));
2002 ignore_rest_of_line ();
2003}
2004
2005const pseudo_typeS cfi_pseudo_table[] =
2006 {
2007 { "cfi_sections", dot_cfi_dummy, 0 },
2008 { "cfi_startproc", dot_cfi_dummy, 0 },
2009 { "cfi_endproc", dot_cfi_dummy, 0 },
2010 { "cfi_def_cfa", dot_cfi_dummy, 0 },
2011 { "cfi_def_cfa_register", dot_cfi_dummy, 0 },
2012 { "cfi_def_cfa_offset", dot_cfi_dummy, 0 },
2013 { "cfi_adjust_cfa_offset", dot_cfi_dummy, 0 },
2014 { "cfi_offset", dot_cfi_dummy, 0 },
2015 { "cfi_rel_offset", dot_cfi_dummy, 0 },
2016 { "cfi_register", dot_cfi_dummy, 0 },
2017 { "cfi_return_column", dot_cfi_dummy, 0 },
2018 { "cfi_restore", dot_cfi_dummy, 0 },
2019 { "cfi_undefined", dot_cfi_dummy, 0 },
2020 { "cfi_same_value", dot_cfi_dummy, 0 },
2021 { "cfi_remember_state", dot_cfi_dummy, 0 },
2022 { "cfi_restore_state", dot_cfi_dummy, 0 },
2023 { "cfi_window_save", dot_cfi_dummy, 0 },
2024 { "cfi_escape", dot_cfi_dummy, 0 },
2025 { "cfi_signal_frame", dot_cfi_dummy, 0 },
2026 { "cfi_personality", dot_cfi_dummy, 0 },
2027 { "cfi_lsda", dot_cfi_dummy, 0 },
2028 { "cfi_val_encoded_addr", dot_cfi_dummy, 0 },
2029 { NULL, NULL, 0 }
2030 };
2031
0a7b15ff
JB
2032void
2033cfi_finish (void)
2034{
2035}
2036#endif /* TARGET_USE_CFIPOP */
This page took 0.628214 seconds and 4 git commands to generate.