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