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