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