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