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