1/* dw2gencfi.c - Support for generating Dwarf2 CFI information. 2 Copyright (C) 2003-2017 Free Software Foundation, Inc. 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 9 the Free Software Foundation; either version 3, or (at your option) 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 19 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 20 02110-1301, USA. */ 21 22#include "as.h" 23#include "dw2gencfi.h" 24#include "subsegs.h" 25#include "dwarf2dbg.h" 26 27#ifdef TARGET_USE_CFIPOP 28 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 38#ifndef CFI_DIFF_LSDA_OK 39#define CFI_DIFF_LSDA_OK CFI_DIFF_EXPR_OK 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 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. */ 48#ifndef DWARF2_LINE_MIN_INSN_LENGTH 49#define DWARF2_LINE_MIN_INSN_LENGTH 1 50#endif 51 52/* By default, use 32-bit relocations from .eh_frame into .text. */ 53#ifndef DWARF2_FDE_RELOC_SIZE 54#define DWARF2_FDE_RELOC_SIZE 4 55#endif 56 57/* By default, use a read-only .eh_frame section. */ 58#ifndef DWARF2_EH_FRAME_READ_ONLY 59#define DWARF2_EH_FRAME_READ_ONLY SEC_READONLY 60#endif 61 62#ifndef EH_FRAME_ALIGNMENT 63#define EH_FRAME_ALIGNMENT (bfd_get_arch_size (stdoutput) == 64 ? 3 : 2) 64#endif 65 66#ifndef tc_cfi_frame_initial_instructions 67#define tc_cfi_frame_initial_instructions() ((void)0) 68#endif 69 70#ifndef tc_cfi_startproc 71# define tc_cfi_startproc() ((void)0) 72#endif 73 74#ifndef tc_cfi_endproc 75# define tc_cfi_endproc(fde) ((void) (fde)) 76#endif 77 78#define EH_FRAME_LINKONCE (SUPPORT_FRAME_LINKONCE || compact_eh) 79 80#ifndef DWARF2_FORMAT 81#define DWARF2_FORMAT(SEC) dwarf2_format_32bit 82#endif 83 84#ifndef DWARF2_ADDR_SIZE 85#define DWARF2_ADDR_SIZE(bfd) (bfd_arch_bits_per_address (bfd) / 8) 86#endif 87 88#if MULTIPLE_FRAME_SECTIONS 89#define CUR_SEG(structp) structp->cur_seg 90#define SET_CUR_SEG(structp, seg) structp->cur_seg = seg 91#define HANDLED(structp) structp->handled 92#define SET_HANDLED(structp, val) structp->handled = val 93#else 94#define CUR_SEG(structp) NULL 95#define SET_CUR_SEG(structp, seg) (void) (0 && seg) 96#define HANDLED(structp) 0 97#define SET_HANDLED(structp, val) (void) (0 && val) 98#endif 99 100#ifndef tc_cfi_reloc_for_encoding 101#define tc_cfi_reloc_for_encoding(e) BFD_RELOC_NONE 102#endif 103 104/* Private segment collection list. */ 105struct dwcfi_seg_list 106{ 107 segT seg; 108 int subseg; 109 char * seg_name; 110}; 111 112#ifdef SUPPORT_COMPACT_EH 113static bfd_boolean compact_eh; 114#else 115#define compact_eh 0 116#endif 117 118static struct hash_control *dwcfi_hash; 119 120/* Emit a single byte into the current segment. */ 121 122static inline void 123out_one (int byte) 124{ 125 FRAG_APPEND_1_CHAR (byte); 126} 127 128/* Emit a two-byte word into the current segment. */ 129 130static inline void 131out_two (int data) 132{ 133 md_number_to_chars (frag_more (2), data, 2); 134} 135 136/* Emit a four byte word into the current segment. */ 137 138static inline void 139out_four (int data) 140{ 141 md_number_to_chars (frag_more (4), data, 4); 142} 143 144/* Emit an unsigned "little-endian base 128" number. */ 145 146static void 147out_uleb128 (addressT value) 148{ 149 output_leb128 (frag_more (sizeof_leb128 (value, 0)), value, 0); 150} 151 152/* Emit an unsigned "little-endian base 128" number. */ 153 154static void 155out_sleb128 (offsetT value) 156{ 157 output_leb128 (frag_more (sizeof_leb128 (value, 1)), value, 1); 158} 159 160static offsetT 161encoding_size (unsigned char encoding) 162{ 163 if (encoding == DW_EH_PE_omit) 164 return 0; 165 switch (encoding & 0x7) 166 { 167 case 0: 168 return bfd_get_arch_size (stdoutput) == 64 ? 8 : 4; 169 case DW_EH_PE_udata2: 170 return 2; 171 case DW_EH_PE_udata4: 172 return 4; 173 case DW_EH_PE_udata8: 174 return 8; 175 default: 176 abort (); 177 } 178} 179 180/* Emit expression EXP in ENCODING. If EMIT_ENCODING is true, first 181 emit a byte containing ENCODING. */ 182 183static void 184emit_expr_encoded (expressionS *exp, int encoding, bfd_boolean emit_encoding) 185{ 186 offsetT size = encoding_size (encoding); 187 bfd_reloc_code_real_type code; 188 189 if (encoding == DW_EH_PE_omit) 190 return; 191 192 if (emit_encoding) 193 out_one (encoding); 194 195 code = tc_cfi_reloc_for_encoding (encoding); 196 if (code != BFD_RELOC_NONE) 197 { 198 reloc_howto_type *howto = bfd_reloc_type_lookup (stdoutput, code); 199 char *p = frag_more (size); 200 md_number_to_chars (p, 0, size); 201 fix_new (frag_now, p - frag_now->fr_literal, size, exp->X_add_symbol, 202 exp->X_add_number, howto->pc_relative, code); 203 } 204 else if ((encoding & 0x70) == DW_EH_PE_pcrel) 205 { 206#if CFI_DIFF_EXPR_OK 207 expressionS tmp = *exp; 208 tmp.X_op = O_subtract; 209 tmp.X_op_symbol = symbol_temp_new_now (); 210 emit_expr (&tmp, size); 211#elif defined (tc_cfi_emit_pcrel_expr) 212 tc_cfi_emit_pcrel_expr (exp, size); 213#else 214 abort (); 215#endif 216 } 217 else 218 emit_expr (exp, size); 219} 220 221/* Build based on segment the derived .debug_... 222 segment name containing origin segment's postfix name part. */ 223 224static char * 225get_debugseg_name (segT seg, const char *base_name) 226{ 227 const char *name; 228 229 if (!seg) 230 name = ""; 231 else 232 { 233 const char * dollar; 234 const char * dot; 235 236 name = bfd_get_section_name (stdoutput, seg); 237 238 dollar = strchr (name, '$'); 239 dot = strchr (name + 1, '.'); 240 241 if (!dollar && !dot) 242 { 243 if (!strcmp (base_name, ".eh_frame_entry") 244 && strcmp (name, ".text") != 0) 245 return concat (base_name, ".", name, NULL); 246 247 name = ""; 248 } 249 else if (!dollar) 250 name = dot; 251 else if (!dot) 252 name = dollar; 253 else if (dot < dollar) 254 name = dot; 255 else 256 name = dollar; 257 } 258 259 return concat (base_name, name, NULL); 260} 261 262/* Allocate a dwcfi_seg_list structure. */ 263 264static struct dwcfi_seg_list * 265alloc_debugseg_item (segT seg, int subseg, char *name) 266{ 267 struct dwcfi_seg_list *r; 268 269 r = (struct dwcfi_seg_list *) 270 xmalloc (sizeof (struct dwcfi_seg_list) + strlen (name)); 271 r->seg = seg; 272 r->subseg = subseg; 273 r->seg_name = name; 274 return r; 275} 276 277static segT 278is_now_linkonce_segment (void) 279{ 280 if (compact_eh) 281 return now_seg; 282 283 if ((bfd_get_section_flags (stdoutput, now_seg) 284 & (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD 285 | SEC_LINK_DUPLICATES_ONE_ONLY | SEC_LINK_DUPLICATES_SAME_SIZE 286 | SEC_LINK_DUPLICATES_SAME_CONTENTS)) != 0) 287 return now_seg; 288 return NULL; 289} 290 291/* Generate debug... segment with same linkonce properties 292 of based segment. */ 293 294static segT 295make_debug_seg (segT cseg, char *name, int sflags) 296{ 297 segT save_seg = now_seg; 298 int save_subseg = now_subseg; 299 segT r; 300 flagword flags; 301 302 r = subseg_new (name, 0); 303 304 /* Check if code segment is marked as linked once. */ 305 if (!cseg) 306 flags = 0; 307 else 308 flags = bfd_get_section_flags (stdoutput, cseg) 309 & (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD 310 | SEC_LINK_DUPLICATES_ONE_ONLY | SEC_LINK_DUPLICATES_SAME_SIZE 311 | SEC_LINK_DUPLICATES_SAME_CONTENTS); 312 313 /* Add standard section flags. */ 314 flags |= sflags; 315 316 /* Apply possibly linked once flags to new generated segment, too. */ 317 if (!bfd_set_section_flags (stdoutput, r, flags)) 318 as_bad (_("bfd_set_section_flags: %s"), 319 bfd_errmsg (bfd_get_error ())); 320 321 /* Restore to previous segment. */ 322 if (save_seg != NULL) 323 subseg_set (save_seg, save_subseg); 324 return r; 325} 326 327static void 328dwcfi_hash_insert (const char *name, struct dwcfi_seg_list *item) 329{ 330 const char *error_string; 331 332 if ((error_string = hash_jam (dwcfi_hash, name, (char *) item))) 333 as_fatal (_("Inserting \"%s\" into structure table failed: %s"), 334 name, error_string); 335} 336 337static struct dwcfi_seg_list * 338dwcfi_hash_find (char *name) 339{ 340 return (struct dwcfi_seg_list *) hash_find (dwcfi_hash, name); 341} 342 343static struct dwcfi_seg_list * 344dwcfi_hash_find_or_make (segT cseg, const char *base_name, int flags) 345{ 346 struct dwcfi_seg_list *item; 347 char *name; 348 349 /* Initialize dwcfi_hash once. */ 350 if (!dwcfi_hash) 351 dwcfi_hash = hash_new (); 352 353 name = get_debugseg_name (cseg, base_name); 354 355 item = dwcfi_hash_find (name); 356 if (!item) 357 { 358 item = alloc_debugseg_item (make_debug_seg (cseg, name, flags), 0, name); 359 360 dwcfi_hash_insert (item->seg_name, item); 361 } 362 else 363 free (name); 364 365 return item; 366} 367 368/* ??? Share this with dwarf2cfg.c. */ 369#ifndef TC_DWARF2_EMIT_OFFSET 370#define TC_DWARF2_EMIT_OFFSET generic_dwarf2_emit_offset 371 372/* Create an offset to .dwarf2_*. */ 373 374static void 375generic_dwarf2_emit_offset (symbolS *symbol, unsigned int size) 376{ 377 expressionS exp; 378 379 exp.X_op = O_symbol; 380 exp.X_add_symbol = symbol; 381 exp.X_add_number = 0; 382 emit_expr (&exp, size); 383} 384#endif 385 386struct cfi_escape_data 387{ 388 struct cfi_escape_data *next; 389 expressionS exp; 390}; 391 392struct cie_entry 393{ 394 struct cie_entry *next; 395#if MULTIPLE_FRAME_SECTIONS 396 segT cur_seg; 397#endif 398 symbolS *start_address; 399 unsigned int return_column; 400 unsigned int signal_frame; 401 unsigned char fde_encoding; 402 unsigned char per_encoding; 403 unsigned char lsda_encoding; 404 expressionS personality; 405 struct cfi_insn_data *first, *last; 406}; 407 408/* List of FDE entries. */ 409 410struct fde_entry *all_fde_data; 411static struct fde_entry **last_fde_data = &all_fde_data; 412 413/* List of CIEs so that they could be reused. */ 414static struct cie_entry *cie_root; 415 416/* Stack of old CFI data, for save/restore. */ 417struct cfa_save_data 418{ 419 struct cfa_save_data *next; 420 offsetT cfa_offset; 421}; 422 423/* Current open FDE entry. */ 424struct frch_cfi_data 425{ 426 struct fde_entry *cur_fde_data; 427 symbolS *last_address; 428 offsetT cur_cfa_offset; 429 struct cfa_save_data *cfa_save_stack; 430}; 431 432/* Construct a new FDE structure and add it to the end of the fde list. */ 433 434static struct fde_entry * 435alloc_fde_entry (void) 436{ 437 struct fde_entry *fde = XCNEW (struct fde_entry); 438 439 frchain_now->frch_cfi_data = XCNEW (struct frch_cfi_data); 440 frchain_now->frch_cfi_data->cur_fde_data = fde; 441 *last_fde_data = fde; 442 last_fde_data = &fde->next; 443 SET_CUR_SEG (fde, is_now_linkonce_segment ()); 444 SET_HANDLED (fde, 0); 445 fde->last = &fde->data; 446 fde->return_column = DWARF2_DEFAULT_RETURN_COLUMN; 447 fde->per_encoding = DW_EH_PE_omit; 448 fde->lsda_encoding = DW_EH_PE_omit; 449 fde->eh_header_type = EH_COMPACT_UNKNOWN; 450 451 return fde; 452} 453 454/* The following functions are available for a backend to construct its 455 own unwind information, usually from legacy unwind directives. */ 456 457/* Construct a new INSN structure and add it to the end of the insn list 458 for the currently active FDE. */ 459 460static bfd_boolean cfi_sections_set = FALSE; 461static int cfi_sections = CFI_EMIT_eh_frame; 462int all_cfi_sections = 0; 463static struct fde_entry *last_fde; 464 465static struct cfi_insn_data * 466alloc_cfi_insn_data (void) 467{ 468 struct cfi_insn_data *insn = XCNEW (struct cfi_insn_data); 469 struct fde_entry *cur_fde_data = frchain_now->frch_cfi_data->cur_fde_data; 470 471 *cur_fde_data->last = insn; 472 cur_fde_data->last = &insn->next; 473 SET_CUR_SEG (insn, is_now_linkonce_segment ()); 474 return insn; 475} 476 477/* Construct a new FDE structure that begins at LABEL. */ 478 479void 480cfi_new_fde (symbolS *label) 481{ 482 struct fde_entry *fde = alloc_fde_entry (); 483 fde->start_address = label; 484 frchain_now->frch_cfi_data->last_address = label; 485} 486 487/* End the currently open FDE. */ 488 489void 490cfi_end_fde (symbolS *label) 491{ 492 frchain_now->frch_cfi_data->cur_fde_data->end_address = label; 493 free (frchain_now->frch_cfi_data); 494 frchain_now->frch_cfi_data = NULL; 495} 496 497/* Set the return column for the current FDE. */ 498 499void 500cfi_set_return_column (unsigned regno) 501{ 502 frchain_now->frch_cfi_data->cur_fde_data->return_column = regno; 503} 504 505void 506cfi_set_sections (void) 507{ 508 frchain_now->frch_cfi_data->cur_fde_data->sections = all_cfi_sections; 509 cfi_sections_set = TRUE; 510} 511 512/* Universal functions to store new instructions. */ 513 514static void 515cfi_add_CFA_insn (int insn) 516{ 517 struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data (); 518 519 insn_ptr->insn = insn; 520} 521 522static void 523cfi_add_CFA_insn_reg (int insn, unsigned regno) 524{ 525 struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data (); 526 527 insn_ptr->insn = insn; 528 insn_ptr->u.r = regno; 529} 530 531static void 532cfi_add_CFA_insn_offset (int insn, offsetT offset) 533{ 534 struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data (); 535 536 insn_ptr->insn = insn; 537 insn_ptr->u.i = offset; 538} 539 540static void 541cfi_add_CFA_insn_reg_reg (int insn, unsigned reg1, unsigned reg2) 542{ 543 struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data (); 544 545 insn_ptr->insn = insn; 546 insn_ptr->u.rr.reg1 = reg1; 547 insn_ptr->u.rr.reg2 = reg2; 548} 549 550static void 551cfi_add_CFA_insn_reg_offset (int insn, unsigned regno, offsetT offset) 552{ 553 struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data (); 554 555 insn_ptr->insn = insn; 556 insn_ptr->u.ri.reg = regno; 557 insn_ptr->u.ri.offset = offset; 558} 559 560/* Add a CFI insn to advance the PC from the last address to LABEL. */ 561 562void 563cfi_add_advance_loc (symbolS *label) 564{ 565 struct cfi_insn_data *insn = alloc_cfi_insn_data (); 566 567 insn->insn = DW_CFA_advance_loc; 568 insn->u.ll.lab1 = frchain_now->frch_cfi_data->last_address; 569 insn->u.ll.lab2 = label; 570 571 frchain_now->frch_cfi_data->last_address = label; 572} 573 574/* Add a CFI insn to label the current position in the CFI segment. */ 575 576void 577cfi_add_label (const char *name) 578{ 579 unsigned int len = strlen (name) + 1; 580 struct cfi_insn_data *insn = alloc_cfi_insn_data (); 581 582 insn->insn = CFI_label; 583 obstack_grow (¬es, name, len); 584 insn->u.sym_name = (char *) obstack_finish (¬es); 585} 586 587/* Add a DW_CFA_offset record to the CFI data. */ 588 589void 590cfi_add_CFA_offset (unsigned regno, offsetT offset) 591{ 592 unsigned int abs_data_align; 593 594 gas_assert (DWARF2_CIE_DATA_ALIGNMENT != 0); 595 cfi_add_CFA_insn_reg_offset (DW_CFA_offset, regno, offset); 596 597 abs_data_align = (DWARF2_CIE_DATA_ALIGNMENT < 0 598 ? -DWARF2_CIE_DATA_ALIGNMENT : DWARF2_CIE_DATA_ALIGNMENT); 599 if (offset % abs_data_align) 600 as_bad (_("register save offset not a multiple of %u"), abs_data_align); 601} 602 603/* Add a DW_CFA_val_offset record to the CFI data. */ 604 605void 606cfi_add_CFA_val_offset (unsigned regno, offsetT offset) 607{ 608 unsigned int abs_data_align; 609 610 gas_assert (DWARF2_CIE_DATA_ALIGNMENT != 0); 611 cfi_add_CFA_insn_reg_offset (DW_CFA_val_offset, regno, offset); 612 613 abs_data_align = (DWARF2_CIE_DATA_ALIGNMENT < 0 614 ? -DWARF2_CIE_DATA_ALIGNMENT : DWARF2_CIE_DATA_ALIGNMENT); 615 if (offset % abs_data_align) 616 as_bad (_("register save offset not a multiple of %u"), abs_data_align); 617} 618 619/* Add a DW_CFA_def_cfa record to the CFI data. */ 620 621void 622cfi_add_CFA_def_cfa (unsigned regno, offsetT offset) 623{ 624 cfi_add_CFA_insn_reg_offset (DW_CFA_def_cfa, regno, offset); 625 frchain_now->frch_cfi_data->cur_cfa_offset = offset; 626} 627 628/* Add a DW_CFA_register record to the CFI data. */ 629 630void 631cfi_add_CFA_register (unsigned reg1, unsigned reg2) 632{ 633 cfi_add_CFA_insn_reg_reg (DW_CFA_register, reg1, reg2); 634} 635 636/* Add a DW_CFA_def_cfa_register record to the CFI data. */ 637 638void 639cfi_add_CFA_def_cfa_register (unsigned regno) 640{ 641 cfi_add_CFA_insn_reg (DW_CFA_def_cfa_register, regno); 642} 643 644/* Add a DW_CFA_def_cfa_offset record to the CFI data. */ 645 646void 647cfi_add_CFA_def_cfa_offset (offsetT offset) 648{ 649 cfi_add_CFA_insn_offset (DW_CFA_def_cfa_offset, offset); 650 frchain_now->frch_cfi_data->cur_cfa_offset = offset; 651} 652 653void 654cfi_add_CFA_restore (unsigned regno) 655{ 656 cfi_add_CFA_insn_reg (DW_CFA_restore, regno); 657} 658 659void 660cfi_add_CFA_undefined (unsigned regno) 661{ 662 cfi_add_CFA_insn_reg (DW_CFA_undefined, regno); 663} 664 665void 666cfi_add_CFA_same_value (unsigned regno) 667{ 668 cfi_add_CFA_insn_reg (DW_CFA_same_value, regno); 669} 670 671void 672cfi_add_CFA_remember_state (void) 673{ 674 struct cfa_save_data *p; 675 676 cfi_add_CFA_insn (DW_CFA_remember_state); 677 678 p = XNEW (struct cfa_save_data); 679 p->cfa_offset = frchain_now->frch_cfi_data->cur_cfa_offset; 680 p->next = frchain_now->frch_cfi_data->cfa_save_stack; 681 frchain_now->frch_cfi_data->cfa_save_stack = p; 682} 683 684void 685cfi_add_CFA_restore_state (void) 686{ 687 struct cfa_save_data *p; 688 689 cfi_add_CFA_insn (DW_CFA_restore_state); 690 691 p = frchain_now->frch_cfi_data->cfa_save_stack; 692 if (p) 693 { 694 frchain_now->frch_cfi_data->cur_cfa_offset = p->cfa_offset; 695 frchain_now->frch_cfi_data->cfa_save_stack = p->next; 696 free (p); 697 } 698 else 699 as_bad (_("CFI state restore without previous remember")); 700} 701 702 703/* Parse CFI assembler directives. */ 704 705static void dot_cfi (int); 706static void dot_cfi_escape (int); 707static void dot_cfi_sections (int); 708static void dot_cfi_startproc (int); 709static void dot_cfi_endproc (int); 710static void dot_cfi_fde_data (int); 711static void dot_cfi_personality (int); 712static void dot_cfi_personality_id (int); 713static void dot_cfi_lsda (int); 714static void dot_cfi_val_encoded_addr (int); 715static void dot_cfi_inline_lsda (int); 716static void dot_cfi_label (int); 717 718const pseudo_typeS cfi_pseudo_table[] = 719 { 720 { "cfi_sections", dot_cfi_sections, 0 }, 721 { "cfi_startproc", dot_cfi_startproc, 0 }, 722 { "cfi_endproc", dot_cfi_endproc, 0 }, 723 { "cfi_fde_data", dot_cfi_fde_data, 0 }, 724 { "cfi_def_cfa", dot_cfi, DW_CFA_def_cfa }, 725 { "cfi_def_cfa_register", dot_cfi, DW_CFA_def_cfa_register }, 726 { "cfi_def_cfa_offset", dot_cfi, DW_CFA_def_cfa_offset }, 727 { "cfi_adjust_cfa_offset", dot_cfi, CFI_adjust_cfa_offset }, 728 { "cfi_offset", dot_cfi, DW_CFA_offset }, 729 { "cfi_rel_offset", dot_cfi, CFI_rel_offset }, 730 { "cfi_register", dot_cfi, DW_CFA_register }, 731 { "cfi_return_column", dot_cfi, CFI_return_column }, 732 { "cfi_restore", dot_cfi, DW_CFA_restore }, 733 { "cfi_undefined", dot_cfi, DW_CFA_undefined }, 734 { "cfi_same_value", dot_cfi, DW_CFA_same_value }, 735 { "cfi_remember_state", dot_cfi, DW_CFA_remember_state }, 736 { "cfi_restore_state", dot_cfi, DW_CFA_restore_state }, 737 { "cfi_window_save", dot_cfi, DW_CFA_GNU_window_save }, 738 { "cfi_escape", dot_cfi_escape, 0 }, 739 { "cfi_signal_frame", dot_cfi, CFI_signal_frame }, 740 { "cfi_personality", dot_cfi_personality, 0 }, 741 { "cfi_personality_id", dot_cfi_personality_id, 0 }, 742 { "cfi_lsda", dot_cfi_lsda, 0 }, 743 { "cfi_val_encoded_addr", dot_cfi_val_encoded_addr, 0 }, 744 { "cfi_inline_lsda", dot_cfi_inline_lsda, 0 }, 745 { "cfi_label", dot_cfi_label, 0 }, 746 { "cfi_val_offset", dot_cfi, DW_CFA_val_offset }, 747 { NULL, NULL, 0 } 748 }; 749 750static void 751cfi_parse_separator (void) 752{ 753 SKIP_WHITESPACE (); 754 if (*input_line_pointer == ',') 755 input_line_pointer++; 756 else 757 as_bad (_("missing separator")); 758} 759 760#ifndef tc_parse_to_dw2regnum 761static void 762tc_parse_to_dw2regnum (expressionS *exp) 763{ 764# ifdef tc_regname_to_dw2regnum 765 SKIP_WHITESPACE (); 766 if (is_name_beginner (*input_line_pointer) 767 || (*input_line_pointer == '%' 768 && is_name_beginner (*++input_line_pointer))) 769 { 770 char *name, c; 771 772 c = get_symbol_name (& name); 773 774 exp->X_op = O_constant; 775 exp->X_add_number = tc_regname_to_dw2regnum (name); 776 777 restore_line_pointer (c); 778 } 779 else 780# endif 781 expression_and_evaluate (exp); 782} 783#endif 784 785static unsigned 786cfi_parse_reg (void) 787{ 788 int regno; 789 expressionS exp; 790 791 tc_parse_to_dw2regnum (&exp); 792 switch (exp.X_op) 793 { 794 case O_register: 795 case O_constant: 796 regno = exp.X_add_number; 797 break; 798 799 default: 800 regno = -1; 801 break; 802 } 803 804 if (regno < 0) 805 { 806 as_bad (_("bad register expression")); 807 regno = 0; 808 } 809 810 return regno; 811} 812 813static offsetT 814cfi_parse_const (void) 815{ 816 return get_absolute_expression (); 817} 818 819static void 820dot_cfi (int arg) 821{ 822 offsetT offset; 823 unsigned reg1, reg2; 824 825 if (frchain_now->frch_cfi_data == NULL) 826 { 827 as_bad (_("CFI instruction used without previous .cfi_startproc")); 828 ignore_rest_of_line (); 829 return; 830 } 831 832 /* If the last address was not at the current PC, advance to current. */ 833 if (symbol_get_frag (frchain_now->frch_cfi_data->last_address) != frag_now 834 || S_GET_VALUE (frchain_now->frch_cfi_data->last_address) 835 != frag_now_fix ()) 836 cfi_add_advance_loc (symbol_temp_new_now ()); 837 838 switch (arg) 839 { 840 case DW_CFA_offset: 841 reg1 = cfi_parse_reg (); 842 cfi_parse_separator (); 843 offset = cfi_parse_const (); 844 cfi_add_CFA_offset (reg1, offset); 845 break; 846 847 case DW_CFA_val_offset: 848 reg1 = cfi_parse_reg (); 849 cfi_parse_separator (); 850 offset = cfi_parse_const (); 851 cfi_add_CFA_val_offset (reg1, offset); 852 break; 853 854 case CFI_rel_offset: 855 reg1 = cfi_parse_reg (); 856 cfi_parse_separator (); 857 offset = cfi_parse_const (); 858 cfi_add_CFA_offset (reg1, 859 offset - frchain_now->frch_cfi_data->cur_cfa_offset); 860 break; 861 862 case DW_CFA_def_cfa: 863 reg1 = cfi_parse_reg (); 864 cfi_parse_separator (); 865 offset = cfi_parse_const (); 866 cfi_add_CFA_def_cfa (reg1, offset); 867 break; 868 869 case DW_CFA_register: 870 reg1 = cfi_parse_reg (); 871 cfi_parse_separator (); 872 reg2 = cfi_parse_reg (); 873 cfi_add_CFA_register (reg1, reg2); 874 break; 875 876 case DW_CFA_def_cfa_register: 877 reg1 = cfi_parse_reg (); 878 cfi_add_CFA_def_cfa_register (reg1); 879 break; 880 881 case DW_CFA_def_cfa_offset: 882 offset = cfi_parse_const (); 883 cfi_add_CFA_def_cfa_offset (offset); 884 break; 885 886 case CFI_adjust_cfa_offset: 887 offset = cfi_parse_const (); 888 cfi_add_CFA_def_cfa_offset (frchain_now->frch_cfi_data->cur_cfa_offset 889 + offset); 890 break; 891 892 case DW_CFA_restore: 893 for (;;) 894 { 895 reg1 = cfi_parse_reg (); 896 cfi_add_CFA_restore (reg1); 897 SKIP_WHITESPACE (); 898 if (*input_line_pointer != ',') 899 break; 900 ++input_line_pointer; 901 } 902 break; 903 904 case DW_CFA_undefined: 905 for (;;) 906 { 907 reg1 = cfi_parse_reg (); 908 cfi_add_CFA_undefined (reg1); 909 SKIP_WHITESPACE (); 910 if (*input_line_pointer != ',') 911 break; 912 ++input_line_pointer; 913 } 914 break; 915 916 case DW_CFA_same_value: 917 reg1 = cfi_parse_reg (); 918 cfi_add_CFA_same_value (reg1); 919 break; 920 921 case CFI_return_column: 922 reg1 = cfi_parse_reg (); 923 cfi_set_return_column (reg1); 924 break; 925 926 case DW_CFA_remember_state: 927 cfi_add_CFA_remember_state (); 928 break; 929 930 case DW_CFA_restore_state: 931 cfi_add_CFA_restore_state (); 932 break; 933 934 case DW_CFA_GNU_window_save: 935 cfi_add_CFA_insn (DW_CFA_GNU_window_save); 936 break; 937 938 case CFI_signal_frame: 939 frchain_now->frch_cfi_data->cur_fde_data->signal_frame = 1; 940 break; 941 942 default: 943 abort (); 944 } 945 946 demand_empty_rest_of_line (); 947} 948 949static void 950dot_cfi_escape (int ignored ATTRIBUTE_UNUSED) 951{ 952 struct cfi_escape_data *head, **tail, *e; 953 struct cfi_insn_data *insn; 954 955 if (frchain_now->frch_cfi_data == NULL) 956 { 957 as_bad (_("CFI instruction used without previous .cfi_startproc")); 958 ignore_rest_of_line (); 959 return; 960 } 961 962 /* If the last address was not at the current PC, advance to current. */ 963 if (symbol_get_frag (frchain_now->frch_cfi_data->last_address) != frag_now 964 || S_GET_VALUE (frchain_now->frch_cfi_data->last_address) 965 != frag_now_fix ()) 966 cfi_add_advance_loc (symbol_temp_new_now ()); 967 968 tail = &head; 969 do 970 { 971 e = XNEW (struct cfi_escape_data); 972 do_parse_cons_expression (&e->exp, 1); 973 *tail = e; 974 tail = &e->next; 975 } 976 while (*input_line_pointer++ == ','); 977 *tail = NULL; 978 979 insn = alloc_cfi_insn_data (); 980 insn->insn = CFI_escape; 981 insn->u.esc = head; 982 983 --input_line_pointer; 984 demand_empty_rest_of_line (); 985} 986 987static void 988dot_cfi_personality (int ignored ATTRIBUTE_UNUSED) 989{ 990 struct fde_entry *fde; 991 offsetT encoding; 992 993 if (frchain_now->frch_cfi_data == NULL) 994 { 995 as_bad (_("CFI instruction used without previous .cfi_startproc")); 996 ignore_rest_of_line (); 997 return; 998 } 999 1000 fde = frchain_now->frch_cfi_data->cur_fde_data; 1001 encoding = cfi_parse_const (); 1002 if (encoding == DW_EH_PE_omit) 1003 { 1004 demand_empty_rest_of_line (); 1005 fde->per_encoding = encoding; 1006 return; 1007 } 1008 1009 if ((encoding & 0xff) != encoding 1010 || ((((encoding & 0x70) != 0 1011#if CFI_DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr 1012 && (encoding & 0x70) != DW_EH_PE_pcrel 1013#endif 1014 ) 1015 /* leb128 can be handled, but does something actually need it? */ 1016 || (encoding & 7) == DW_EH_PE_uleb128 1017 || (encoding & 7) > DW_EH_PE_udata8) 1018 && tc_cfi_reloc_for_encoding (encoding) == BFD_RELOC_NONE)) 1019 { 1020 as_bad (_("invalid or unsupported encoding in .cfi_personality")); 1021 ignore_rest_of_line (); 1022 return; 1023 } 1024 1025 if (*input_line_pointer++ != ',') 1026 { 1027 as_bad (_(".cfi_personality requires encoding and symbol arguments")); 1028 ignore_rest_of_line (); 1029 return; 1030 } 1031 1032 expression_and_evaluate (&fde->personality); 1033 switch (fde->personality.X_op) 1034 { 1035 case O_symbol: 1036 break; 1037 case O_constant: 1038 if ((encoding & 0x70) == DW_EH_PE_pcrel) 1039 encoding = DW_EH_PE_omit; 1040 break; 1041 default: 1042 encoding = DW_EH_PE_omit; 1043 break; 1044 } 1045 1046 fde->per_encoding = encoding; 1047 1048 if (encoding == DW_EH_PE_omit) 1049 { 1050 as_bad (_("wrong second argument to .cfi_personality")); 1051 ignore_rest_of_line (); 1052 return; 1053 } 1054 1055 demand_empty_rest_of_line (); 1056} 1057 1058static void 1059dot_cfi_lsda (int ignored ATTRIBUTE_UNUSED) 1060{ 1061 struct fde_entry *fde; 1062 offsetT encoding; 1063 1064 if (frchain_now->frch_cfi_data == NULL) 1065 { 1066 as_bad (_("CFI instruction used without previous .cfi_startproc")); 1067 ignore_rest_of_line (); 1068 return; 1069 } 1070 1071 fde = frchain_now->frch_cfi_data->cur_fde_data; 1072 encoding = cfi_parse_const (); 1073 if (encoding == DW_EH_PE_omit) 1074 { 1075 demand_empty_rest_of_line (); 1076 fde->lsda_encoding = encoding; 1077 return; 1078 } 1079 1080 if ((encoding & 0xff) != encoding 1081 || ((((encoding & 0x70) != 0 1082#if CFI_DIFF_LSDA_OK || defined tc_cfi_emit_pcrel_expr 1083 && (encoding & 0x70) != DW_EH_PE_pcrel 1084#endif 1085 ) 1086 /* leb128 can be handled, but does something actually need it? */ 1087 || (encoding & 7) == DW_EH_PE_uleb128 1088 || (encoding & 7) > DW_EH_PE_udata8) 1089 && tc_cfi_reloc_for_encoding (encoding) == BFD_RELOC_NONE)) 1090 { 1091 as_bad (_("invalid or unsupported encoding in .cfi_lsda")); 1092 ignore_rest_of_line (); 1093 return; 1094 } 1095 1096 if (*input_line_pointer++ != ',') 1097 { 1098 as_bad (_(".cfi_lsda requires encoding and symbol arguments")); 1099 ignore_rest_of_line (); 1100 return; 1101 } 1102 1103 fde->lsda_encoding = encoding; 1104 1105 expression_and_evaluate (&fde->lsda); 1106 switch (fde->lsda.X_op) 1107 { 1108 case O_symbol: 1109 break; 1110 case O_constant: 1111 if ((encoding & 0x70) == DW_EH_PE_pcrel) 1112 encoding = DW_EH_PE_omit; 1113 break; 1114 default: 1115 encoding = DW_EH_PE_omit; 1116 break; 1117 } 1118 1119 fde->lsda_encoding = encoding; 1120 1121 if (encoding == DW_EH_PE_omit) 1122 { 1123 as_bad (_("wrong second argument to .cfi_lsda")); 1124 ignore_rest_of_line (); 1125 return; 1126 } 1127 1128 demand_empty_rest_of_line (); 1129} 1130 1131static void 1132dot_cfi_val_encoded_addr (int ignored ATTRIBUTE_UNUSED) 1133{ 1134 struct cfi_insn_data *insn_ptr; 1135 offsetT encoding; 1136 1137 if (frchain_now->frch_cfi_data == NULL) 1138 { 1139 as_bad (_("CFI instruction used without previous .cfi_startproc")); 1140 ignore_rest_of_line (); 1141 return; 1142 } 1143 1144 /* If the last address was not at the current PC, advance to current. */ 1145 if (symbol_get_frag (frchain_now->frch_cfi_data->last_address) != frag_now 1146 || S_GET_VALUE (frchain_now->frch_cfi_data->last_address) 1147 != frag_now_fix ()) 1148 cfi_add_advance_loc (symbol_temp_new_now ()); 1149 1150 insn_ptr = alloc_cfi_insn_data (); 1151 insn_ptr->insn = CFI_val_encoded_addr; 1152 1153 insn_ptr->u.ea.reg = cfi_parse_reg (); 1154 1155 cfi_parse_separator (); 1156 encoding = cfi_parse_const (); 1157 if ((encoding & 0xff) != encoding 1158 || ((encoding & 0x70) != 0 1159#if CFI_DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr 1160 && (encoding & 0x70) != DW_EH_PE_pcrel 1161#endif 1162 ) 1163 /* leb128 can be handled, but does something actually need it? */ 1164 || (encoding & 7) == DW_EH_PE_uleb128 1165 || (encoding & 7) > DW_EH_PE_udata8) 1166 { 1167 as_bad (_("invalid or unsupported encoding in .cfi_lsda")); 1168 encoding = DW_EH_PE_omit; 1169 } 1170 1171 cfi_parse_separator (); 1172 expression_and_evaluate (&insn_ptr->u.ea.exp); 1173 switch (insn_ptr->u.ea.exp.X_op) 1174 { 1175 case O_symbol: 1176 break; 1177 case O_constant: 1178 if ((encoding & 0x70) != DW_EH_PE_pcrel) 1179 break; 1180 /* Fall through. */ 1181 default: 1182 encoding = DW_EH_PE_omit; 1183 break; 1184 } 1185 1186 insn_ptr->u.ea.encoding = encoding; 1187 if (encoding == DW_EH_PE_omit) 1188 { 1189 as_bad (_("wrong third argument to .cfi_val_encoded_addr")); 1190 ignore_rest_of_line (); 1191 return; 1192 } 1193 1194 demand_empty_rest_of_line (); 1195} 1196 1197static void 1198dot_cfi_label (int ignored ATTRIBUTE_UNUSED) 1199{ 1200 char *name = read_symbol_name (); 1201 1202 if (name == NULL) 1203 return; 1204 1205 /* If the last address was not at the current PC, advance to current. */ 1206 if (symbol_get_frag (frchain_now->frch_cfi_data->last_address) != frag_now 1207 || S_GET_VALUE (frchain_now->frch_cfi_data->last_address) 1208 != frag_now_fix ()) 1209 cfi_add_advance_loc (symbol_temp_new_now ()); 1210 1211 cfi_add_label (name); 1212 free (name); 1213 1214 demand_empty_rest_of_line (); 1215} 1216 1217static void 1218dot_cfi_sections (int ignored ATTRIBUTE_UNUSED) 1219{ 1220 int sections = 0; 1221 1222 SKIP_WHITESPACE (); 1223 if (is_name_beginner (*input_line_pointer) || *input_line_pointer == '"') 1224 while (1) 1225 { 1226 char * saved_ilp; 1227 char *name, c; 1228 1229 saved_ilp = input_line_pointer; 1230 c = get_symbol_name (& name); 1231 1232 if (strncmp (name, ".eh_frame", sizeof ".eh_frame") == 0 1233 && name[9] != '_') 1234 sections |= CFI_EMIT_eh_frame; 1235 else if (strncmp (name, ".debug_frame", sizeof ".debug_frame") == 0) 1236 sections |= CFI_EMIT_debug_frame; 1237#if SUPPORT_COMPACT_EH 1238 else if (strncmp (name, ".eh_frame_entry", sizeof ".eh_frame_entry") == 0) 1239 { 1240 compact_eh = TRUE; 1241 sections |= CFI_EMIT_eh_frame_compact; 1242 } 1243#endif 1244#ifdef tc_cfi_section_name 1245 else if (strcmp (name, tc_cfi_section_name) == 0) 1246 sections |= CFI_EMIT_target; 1247#endif 1248 else 1249 { 1250 *input_line_pointer = c; 1251 input_line_pointer = saved_ilp; 1252 break; 1253 } 1254 1255 *input_line_pointer = c; 1256 SKIP_WHITESPACE_AFTER_NAME (); 1257 if (*input_line_pointer == ',') 1258 { 1259 name = input_line_pointer++; 1260 SKIP_WHITESPACE (); 1261 if (!is_name_beginner (*input_line_pointer) && *input_line_pointer != '"') 1262 { 1263 input_line_pointer = name; 1264 break; 1265 } 1266 } 1267 else if (is_name_beginner (*input_line_pointer) || *input_line_pointer == '"') 1268 break; 1269 } 1270 1271 demand_empty_rest_of_line (); 1272 if (cfi_sections_set 1273 && (sections & (CFI_EMIT_eh_frame | CFI_EMIT_eh_frame_compact)) 1274 && (cfi_sections & (CFI_EMIT_eh_frame | CFI_EMIT_eh_frame_compact)) 1275 != (sections & (CFI_EMIT_eh_frame | CFI_EMIT_eh_frame_compact))) 1276 as_bad (_("inconsistent uses of .cfi_sections")); 1277 cfi_sections = sections; 1278} 1279 1280static void 1281dot_cfi_startproc (int ignored ATTRIBUTE_UNUSED) 1282{ 1283 int simple = 0; 1284 1285 if (frchain_now->frch_cfi_data != NULL) 1286 { 1287 as_bad (_("previous CFI entry not closed (missing .cfi_endproc)")); 1288 ignore_rest_of_line (); 1289 return; 1290 } 1291 1292 cfi_new_fde (symbol_temp_new_now ()); 1293 1294 SKIP_WHITESPACE (); 1295 if (is_name_beginner (*input_line_pointer) || *input_line_pointer == '"') 1296 { 1297 char * saved_ilp = input_line_pointer; 1298 char *name, c; 1299 1300 c = get_symbol_name (& name); 1301 1302 if (strcmp (name, "simple") == 0) 1303 { 1304 simple = 1; 1305 restore_line_pointer (c); 1306 } 1307 else 1308 input_line_pointer = saved_ilp; 1309 } 1310 demand_empty_rest_of_line (); 1311 1312 cfi_sections_set = TRUE; 1313 all_cfi_sections |= cfi_sections; 1314 cfi_set_sections (); 1315 frchain_now->frch_cfi_data->cur_cfa_offset = 0; 1316 if (!simple) 1317 tc_cfi_frame_initial_instructions (); 1318 1319 if ((cfi_sections & CFI_EMIT_target) != 0) 1320 tc_cfi_startproc (); 1321} 1322 1323static void 1324dot_cfi_endproc (int ignored ATTRIBUTE_UNUSED) 1325{ 1326 if (frchain_now->frch_cfi_data == NULL) 1327 { 1328 as_bad (_(".cfi_endproc without corresponding .cfi_startproc")); 1329 ignore_rest_of_line (); 1330 return; 1331 } 1332 1333 last_fde = frchain_now->frch_cfi_data->cur_fde_data; 1334 1335 cfi_end_fde (symbol_temp_new_now ()); 1336 1337 demand_empty_rest_of_line (); 1338 1339 cfi_sections_set = TRUE; 1340 if ((cfi_sections & CFI_EMIT_target) != 0) 1341 tc_cfi_endproc (last_fde); 1342} 1343 1344static segT 1345get_cfi_seg (segT cseg, const char *base, flagword flags, int align) 1346{ 1347 /* Exclude .debug_frame sections for Compact EH. */ 1348 if (SUPPORT_FRAME_LINKONCE || ((flags & SEC_DEBUGGING) == 0 && compact_eh)) 1349 { 1350 struct dwcfi_seg_list *l; 1351 1352 l = dwcfi_hash_find_or_make (cseg, base, flags); 1353 1354 cseg = l->seg; 1355 subseg_set (cseg, l->subseg); 1356 } 1357 else 1358 { 1359 cseg = subseg_new (base, 0); 1360 bfd_set_section_flags (stdoutput, cseg, flags); 1361 } 1362 record_alignment (cseg, align); 1363 return cseg; 1364} 1365 1366#if SUPPORT_COMPACT_EH 1367static void 1368dot_cfi_personality_id (int ignored ATTRIBUTE_UNUSED) 1369{ 1370 struct fde_entry *fde; 1371 1372 if (frchain_now->frch_cfi_data == NULL) 1373 { 1374 as_bad (_("CFI instruction used without previous .cfi_startproc")); 1375 ignore_rest_of_line (); 1376 return; 1377 } 1378 1379 fde = frchain_now->frch_cfi_data->cur_fde_data; 1380 fde->personality_id = cfi_parse_const (); 1381 demand_empty_rest_of_line (); 1382 1383 if (fde->personality_id == 0 || fde->personality_id > 3) 1384 { 1385 as_bad (_("wrong argument to .cfi_personality_id")); 1386 return; 1387 } 1388} 1389 1390static void 1391dot_cfi_fde_data (int ignored ATTRIBUTE_UNUSED) 1392{ 1393 if (frchain_now->frch_cfi_data == NULL) 1394 { 1395 as_bad (_(".cfi_fde_data without corresponding .cfi_startproc")); 1396 ignore_rest_of_line (); 1397 return; 1398 } 1399 1400 last_fde = frchain_now->frch_cfi_data->cur_fde_data; 1401 1402 cfi_sections_set = TRUE; 1403 if ((cfi_sections & CFI_EMIT_target) != 0 1404 || (cfi_sections & CFI_EMIT_eh_frame_compact) != 0) 1405 { 1406 struct cfi_escape_data *head, **tail, *e; 1407 int num_ops = 0; 1408 1409 tail = &head; 1410 if (!is_it_end_of_statement ()) 1411 { 1412 num_ops = 0; 1413 do 1414 { 1415 e = XNEW (struct cfi_escape_data); 1416 do_parse_cons_expression (&e->exp, 1); 1417 *tail = e; 1418 tail = &e->next; 1419 num_ops++; 1420 } 1421 while (*input_line_pointer++ == ','); 1422 --input_line_pointer; 1423 } 1424 *tail = NULL; 1425 1426 if (last_fde->lsda_encoding != DW_EH_PE_omit) 1427 last_fde->eh_header_type = EH_COMPACT_HAS_LSDA; 1428 else if (num_ops <= 3 && last_fde->per_encoding == DW_EH_PE_omit) 1429 last_fde->eh_header_type = EH_COMPACT_INLINE; 1430 else 1431 last_fde->eh_header_type = EH_COMPACT_OUTLINE; 1432 1433 if (last_fde->eh_header_type == EH_COMPACT_INLINE) 1434 num_ops = 3; 1435 1436 last_fde->eh_data_size = num_ops; 1437 last_fde->eh_data = XNEWVEC (bfd_byte, num_ops); 1438 num_ops = 0; 1439 while (head) 1440 { 1441 e = head; 1442 head = e->next; 1443 last_fde->eh_data[num_ops++] = e->exp.X_add_number; 1444 free (e); 1445 } 1446 if (last_fde->eh_header_type == EH_COMPACT_INLINE) 1447 while (num_ops < 3) 1448 last_fde->eh_data[num_ops++] = tc_compact_eh_opcode_stop; 1449 } 1450 1451 demand_empty_rest_of_line (); 1452} 1453 1454/* Function to emit the compact unwinding opcodes stored in the 1455 fde's eh_data field. The end of the opcode data will be 1456 padded to the value in align. */ 1457 1458static void 1459output_compact_unwind_data (struct fde_entry *fde, int align) 1460{ 1461 int data_size = fde->eh_data_size + 2; 1462 int align_padding; 1463 int amask; 1464 char *p; 1465 1466 fde->eh_loc = symbol_temp_new_now (); 1467 1468 p = frag_more (1); 1469 if (fde->personality_id != 0) 1470 *p = fde->personality_id; 1471 else if (fde->per_encoding != DW_EH_PE_omit) 1472 { 1473 *p = 0; 1474 emit_expr_encoded (&fde->personality, fde->per_encoding, FALSE); 1475 data_size += encoding_size (fde->per_encoding); 1476 } 1477 else 1478 *p = 1; 1479 1480 amask = (1 << align) - 1; 1481 align_padding = ((data_size + amask) & ~amask) - data_size; 1482 1483 p = frag_more (fde->eh_data_size + 1 + align_padding); 1484 memcpy (p, fde->eh_data, fde->eh_data_size); 1485 p += fde->eh_data_size; 1486 1487 while (align_padding-- > 0) 1488 *(p++) = tc_compact_eh_opcode_pad; 1489 1490 *(p++) = tc_compact_eh_opcode_stop; 1491 fde->eh_header_type = EH_COMPACT_OUTLINE_DONE; 1492} 1493 1494/* Handle the .cfi_inline_lsda directive. */ 1495static void 1496dot_cfi_inline_lsda (int ignored ATTRIBUTE_UNUSED) 1497{ 1498 segT ccseg; 1499 int align; 1500 long max_alignment = 28; 1501 1502 if (!last_fde) 1503 { 1504 as_bad (_("unexpected .cfi_inline_lsda")); 1505 ignore_rest_of_line (); 1506 return; 1507 } 1508 1509 if ((last_fde->sections & CFI_EMIT_eh_frame_compact) == 0) 1510 { 1511 as_bad (_(".cfi_inline_lsda not valid for this frame")); 1512 ignore_rest_of_line (); 1513 return; 1514 } 1515 1516 if (last_fde->eh_header_type != EH_COMPACT_UNKNOWN 1517 && last_fde->eh_header_type != EH_COMPACT_HAS_LSDA) 1518 { 1519 as_bad (_(".cfi_inline_lsda seen for frame without .cfi_lsda")); 1520 ignore_rest_of_line (); 1521 return; 1522 } 1523 1524#ifdef md_flush_pending_output 1525 md_flush_pending_output (); 1526#endif 1527 1528 align = get_absolute_expression (); 1529 if (align > max_alignment) 1530 { 1531 align = max_alignment; 1532 as_bad (_("Alignment too large: %d. assumed."), align); 1533 } 1534 else if (align < 0) 1535 { 1536 as_warn (_("Alignment negative: 0 assumed.")); 1537 align = 0; 1538 } 1539 1540 demand_empty_rest_of_line (); 1541 ccseg = CUR_SEG (last_fde); 1542 1543 /* Open .gnu_extab section. */ 1544 get_cfi_seg (ccseg, ".gnu_extab", 1545 (SEC_ALLOC | SEC_LOAD | SEC_DATA 1546 | DWARF2_EH_FRAME_READ_ONLY), 1547 1); 1548 1549 frag_align (align, 0, 0); 1550 record_alignment (now_seg, align); 1551 if (last_fde->eh_header_type == EH_COMPACT_HAS_LSDA) 1552 output_compact_unwind_data (last_fde, align); 1553 1554 last_fde = NULL; 1555 1556 return; 1557} 1558#else /* !SUPPORT_COMPACT_EH */ 1559static void 1560dot_cfi_inline_lsda (int ignored ATTRIBUTE_UNUSED) 1561{ 1562 as_bad (_(".cfi_inline_lsda is not supported for this target")); 1563 ignore_rest_of_line (); 1564} 1565 1566static void 1567dot_cfi_fde_data (int ignored ATTRIBUTE_UNUSED) 1568{ 1569 as_bad (_(".cfi_fde_data is not supported for this target")); 1570 ignore_rest_of_line (); 1571} 1572 1573static void 1574dot_cfi_personality_id (int ignored ATTRIBUTE_UNUSED) 1575{ 1576 as_bad (_(".cfi_personality_id is not supported for this target")); 1577 ignore_rest_of_line (); 1578} 1579#endif 1580 1581static void 1582output_cfi_insn (struct cfi_insn_data *insn) 1583{ 1584 offsetT offset; 1585 unsigned int regno; 1586 1587 switch (insn->insn) 1588 { 1589 case DW_CFA_advance_loc: 1590 { 1591 symbolS *from = insn->u.ll.lab1; 1592 symbolS *to = insn->u.ll.lab2; 1593 1594 if (symbol_get_frag (to) == symbol_get_frag (from)) 1595 { 1596 addressT delta = S_GET_VALUE (to) - S_GET_VALUE (from); 1597 addressT scaled = delta / DWARF2_LINE_MIN_INSN_LENGTH; 1598 1599 if (scaled <= 0x3F) 1600 out_one (DW_CFA_advance_loc + scaled); 1601 else if (scaled <= 0xFF) 1602 { 1603 out_one (DW_CFA_advance_loc1); 1604 out_one (scaled); 1605 } 1606 else if (scaled <= 0xFFFF) 1607 { 1608 out_one (DW_CFA_advance_loc2); 1609 out_two (scaled); 1610 } 1611 else 1612 { 1613 out_one (DW_CFA_advance_loc4); 1614 out_four (scaled); 1615 } 1616 } 1617 else 1618 { 1619 expressionS exp; 1620 1621 exp.X_op = O_subtract; 1622 exp.X_add_symbol = to; 1623 exp.X_op_symbol = from; 1624 exp.X_add_number = 0; 1625 1626 /* The code in ehopt.c expects that one byte of the encoding 1627 is already allocated to the frag. This comes from the way 1628 that it scans the .eh_frame section looking first for the 1629 .byte DW_CFA_advance_loc4. */ 1630 *frag_more (1) = DW_CFA_advance_loc4; 1631 1632 frag_var (rs_cfa, 4, 0, DWARF2_LINE_MIN_INSN_LENGTH << 3, 1633 make_expr_symbol (&exp), frag_now_fix () - 1, 1634 (char *) frag_now); 1635 } 1636 } 1637 break; 1638 1639 case DW_CFA_def_cfa: 1640 offset = insn->u.ri.offset; 1641 if (offset < 0) 1642 { 1643 out_one (DW_CFA_def_cfa_sf); 1644 out_uleb128 (insn->u.ri.reg); 1645 out_sleb128 (offset / DWARF2_CIE_DATA_ALIGNMENT); 1646 } 1647 else 1648 { 1649 out_one (DW_CFA_def_cfa); 1650 out_uleb128 (insn->u.ri.reg); 1651 out_uleb128 (offset); 1652 } 1653 break; 1654 1655 case DW_CFA_def_cfa_register: 1656 case DW_CFA_undefined: 1657 case DW_CFA_same_value: 1658 out_one (insn->insn); 1659 out_uleb128 (insn->u.r); 1660 break; 1661 1662 case DW_CFA_def_cfa_offset: 1663 offset = insn->u.i; 1664 if (offset < 0) 1665 { 1666 out_one (DW_CFA_def_cfa_offset_sf); 1667 out_sleb128 (offset / DWARF2_CIE_DATA_ALIGNMENT); 1668 } 1669 else 1670 { 1671 out_one (DW_CFA_def_cfa_offset); 1672 out_uleb128 (offset); 1673 } 1674 break; 1675 1676 case DW_CFA_restore: 1677 regno = insn->u.r; 1678 if (regno <= 0x3F) 1679 { 1680 out_one (DW_CFA_restore + regno); 1681 } 1682 else 1683 { 1684 out_one (DW_CFA_restore_extended); 1685 out_uleb128 (regno); 1686 } 1687 break; 1688 1689 case DW_CFA_offset: 1690 regno = insn->u.ri.reg; 1691 offset = insn->u.ri.offset / DWARF2_CIE_DATA_ALIGNMENT; 1692 if (offset < 0) 1693 { 1694 out_one (DW_CFA_offset_extended_sf); 1695 out_uleb128 (regno); 1696 out_sleb128 (offset); 1697 } 1698 else if (regno <= 0x3F) 1699 { 1700 out_one (DW_CFA_offset + regno); 1701 out_uleb128 (offset); 1702 } 1703 else 1704 { 1705 out_one (DW_CFA_offset_extended); 1706 out_uleb128 (regno); 1707 out_uleb128 (offset); 1708 } 1709 break; 1710 1711 case DW_CFA_val_offset: 1712 regno = insn->u.ri.reg; 1713 offset = insn->u.ri.offset / DWARF2_CIE_DATA_ALIGNMENT; 1714 if (offset < 0) 1715 { 1716 out_one (DW_CFA_val_offset_sf); 1717 out_uleb128 (regno); 1718 out_sleb128 (offset); 1719 } 1720 else 1721 { 1722 out_one (DW_CFA_val_offset); 1723 out_uleb128 (regno); 1724 out_uleb128 (offset); 1725 } 1726 break; 1727 1728 case DW_CFA_register: 1729 out_one (DW_CFA_register); 1730 out_uleb128 (insn->u.rr.reg1); 1731 out_uleb128 (insn->u.rr.reg2); 1732 break; 1733 1734 case DW_CFA_remember_state: 1735 case DW_CFA_restore_state: 1736 out_one (insn->insn); 1737 break; 1738 1739 case DW_CFA_GNU_window_save: 1740 out_one (DW_CFA_GNU_window_save); 1741 break; 1742 1743 case CFI_escape: 1744 { 1745 struct cfi_escape_data *e; 1746 for (e = insn->u.esc; e ; e = e->next) 1747 emit_expr (&e->exp, 1); 1748 break; 1749 } 1750 1751 case CFI_val_encoded_addr: 1752 { 1753 unsigned encoding = insn->u.ea.encoding; 1754 offsetT enc_size; 1755 1756 if (encoding == DW_EH_PE_omit) 1757 break; 1758 out_one (DW_CFA_val_expression); 1759 out_uleb128 (insn->u.ea.reg); 1760 1761 switch (encoding & 0x7) 1762 { 1763 case DW_EH_PE_absptr: 1764 enc_size = DWARF2_ADDR_SIZE (stdoutput); 1765 break; 1766 case DW_EH_PE_udata2: 1767 enc_size = 2; 1768 break; 1769 case DW_EH_PE_udata4: 1770 enc_size = 4; 1771 break; 1772 case DW_EH_PE_udata8: 1773 enc_size = 8; 1774 break; 1775 default: 1776 abort (); 1777 } 1778 1779 /* If the user has requested absolute encoding, 1780 then use the smaller DW_OP_addr encoding. */ 1781 if (insn->u.ea.encoding == DW_EH_PE_absptr) 1782 { 1783 out_uleb128 (1 + enc_size); 1784 out_one (DW_OP_addr); 1785 } 1786 else 1787 { 1788 out_uleb128 (1 + 1 + enc_size); 1789 out_one (DW_OP_GNU_encoded_addr); 1790 out_one (encoding); 1791 1792 if ((encoding & 0x70) == DW_EH_PE_pcrel) 1793 { 1794#if CFI_DIFF_EXPR_OK 1795 insn->u.ea.exp.X_op = O_subtract; 1796 insn->u.ea.exp.X_op_symbol = symbol_temp_new_now (); 1797#elif defined (tc_cfi_emit_pcrel_expr) 1798 tc_cfi_emit_pcrel_expr (&insn->u.ea.exp, enc_size); 1799 break; 1800#else 1801 abort (); 1802#endif 1803 } 1804 } 1805 emit_expr (&insn->u.ea.exp, enc_size); 1806 } 1807 break; 1808 1809 case CFI_label: 1810 colon (insn->u.sym_name); 1811 break; 1812 1813 default: 1814 abort (); 1815 } 1816} 1817 1818static void 1819output_cie (struct cie_entry *cie, bfd_boolean eh_frame, int align) 1820{ 1821 symbolS *after_size_address, *end_address; 1822 expressionS exp; 1823 struct cfi_insn_data *i; 1824 offsetT augmentation_size; 1825 int enc; 1826 enum dwarf2_format fmt = DWARF2_FORMAT (now_seg); 1827 1828 cie->start_address = symbol_temp_new_now (); 1829 after_size_address = symbol_temp_make (); 1830 end_address = symbol_temp_make (); 1831 1832 exp.X_op = O_subtract; 1833 exp.X_add_symbol = end_address; 1834 exp.X_op_symbol = after_size_address; 1835 exp.X_add_number = 0; 1836 1837 if (eh_frame || fmt == dwarf2_format_32bit) 1838 emit_expr (&exp, 4); /* Length. */ 1839 else 1840 { 1841 if (fmt == dwarf2_format_64bit) 1842 out_four (-1); 1843 emit_expr (&exp, 8); /* Length. */ 1844 } 1845 symbol_set_value_now (after_size_address); 1846 if (eh_frame) 1847 out_four (0); /* CIE id. */ 1848 else 1849 { 1850 out_four (-1); /* CIE id. */ 1851 if (fmt != dwarf2_format_32bit) 1852 out_four (-1); 1853 } 1854 out_one (DW_CIE_VERSION); /* Version. */ 1855 if (eh_frame) 1856 { 1857 out_one ('z'); /* Augmentation. */ 1858 if (cie->per_encoding != DW_EH_PE_omit) 1859 out_one ('P'); 1860 if (cie->lsda_encoding != DW_EH_PE_omit) 1861 out_one ('L'); 1862 out_one ('R'); 1863 } 1864 if (cie->signal_frame) 1865 out_one ('S'); 1866 out_one (0); 1867 out_uleb128 (DWARF2_LINE_MIN_INSN_LENGTH); /* Code alignment. */ 1868 out_sleb128 (DWARF2_CIE_DATA_ALIGNMENT); /* Data alignment. */ 1869 if (DW_CIE_VERSION == 1) /* Return column. */ 1870 out_one (cie->return_column); 1871 else 1872 out_uleb128 (cie->return_column); 1873 if (eh_frame) 1874 { 1875 augmentation_size = 1 + (cie->lsda_encoding != DW_EH_PE_omit); 1876 if (cie->per_encoding != DW_EH_PE_omit) 1877 augmentation_size += 1 + encoding_size (cie->per_encoding); 1878 out_uleb128 (augmentation_size); /* Augmentation size. */ 1879 1880 emit_expr_encoded (&cie->personality, cie->per_encoding, TRUE); 1881 1882 if (cie->lsda_encoding != DW_EH_PE_omit) 1883 out_one (cie->lsda_encoding); 1884 } 1885 1886 switch (DWARF2_FDE_RELOC_SIZE) 1887 { 1888 case 2: 1889 enc = DW_EH_PE_sdata2; 1890 break; 1891 case 4: 1892 enc = DW_EH_PE_sdata4; 1893 break; 1894 case 8: 1895 enc = DW_EH_PE_sdata8; 1896 break; 1897 default: 1898 abort (); 1899 } 1900#if CFI_DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr 1901 enc |= DW_EH_PE_pcrel; 1902#endif 1903#ifdef DWARF2_FDE_RELOC_ENCODING 1904 /* Allow target to override encoding. */ 1905 enc = DWARF2_FDE_RELOC_ENCODING (enc); 1906#endif 1907 cie->fde_encoding = enc; 1908 if (eh_frame) 1909 out_one (enc); 1910 1911 if (cie->first) 1912 { 1913 for (i = cie->first; i != cie->last; i = i->next) 1914 { 1915 if (CUR_SEG (i) != CUR_SEG (cie)) 1916 continue; 1917 output_cfi_insn (i); 1918 } 1919 } 1920 1921 frag_align (align, DW_CFA_nop, 0); 1922 symbol_set_value_now (end_address); 1923} 1924 1925static void 1926output_fde (struct fde_entry *fde, struct cie_entry *cie, 1927 bfd_boolean eh_frame, struct cfi_insn_data *first, 1928 int align) 1929{ 1930 symbolS *after_size_address, *end_address; 1931 expressionS exp; 1932 offsetT augmentation_size; 1933 enum dwarf2_format fmt = DWARF2_FORMAT (now_seg); 1934 int offset_size; 1935 int addr_size; 1936 1937 after_size_address = symbol_temp_make (); 1938 end_address = symbol_temp_make (); 1939 1940 exp.X_op = O_subtract; 1941 exp.X_add_symbol = end_address; 1942 exp.X_op_symbol = after_size_address; 1943 exp.X_add_number = 0; 1944 if (eh_frame || fmt == dwarf2_format_32bit) 1945 offset_size = 4; 1946 else 1947 { 1948 if (fmt == dwarf2_format_64bit) 1949 out_four (-1); 1950 offset_size = 8; 1951 } 1952 emit_expr (&exp, offset_size); /* Length. */ 1953 symbol_set_value_now (after_size_address); 1954 1955 if (eh_frame) 1956 { 1957 exp.X_op = O_subtract; 1958 exp.X_add_symbol = after_size_address; 1959 exp.X_op_symbol = cie->start_address; 1960 exp.X_add_number = 0; 1961 emit_expr (&exp, offset_size); /* CIE offset. */ 1962 } 1963 else 1964 { 1965 TC_DWARF2_EMIT_OFFSET (cie->start_address, offset_size); 1966 } 1967 1968 exp.X_op = O_symbol; 1969 if (eh_frame) 1970 { 1971 bfd_reloc_code_real_type code 1972 = tc_cfi_reloc_for_encoding (cie->fde_encoding); 1973 if (code != BFD_RELOC_NONE) 1974 { 1975 reloc_howto_type *howto = bfd_reloc_type_lookup (stdoutput, code); 1976 char *p = frag_more (4); 1977 md_number_to_chars (p, 0, 4); 1978 fix_new (frag_now, p - frag_now->fr_literal, 4, fde->start_address, 1979 0, howto->pc_relative, code); 1980 } 1981 else 1982 { 1983 exp.X_op = O_subtract; 1984 exp.X_add_number = 0; 1985#if CFI_DIFF_EXPR_OK 1986 exp.X_add_symbol = fde->start_address; 1987 exp.X_op_symbol = symbol_temp_new_now (); 1988 emit_expr (&exp, DWARF2_FDE_RELOC_SIZE); /* Code offset. */ 1989#else 1990 exp.X_op = O_symbol; 1991 exp.X_add_symbol = fde->start_address; 1992 1993#if defined(tc_cfi_emit_pcrel_expr) 1994 tc_cfi_emit_pcrel_expr (&exp, DWARF2_FDE_RELOC_SIZE); /* Code offset. */ 1995#else 1996 emit_expr (&exp, DWARF2_FDE_RELOC_SIZE); /* Code offset. */ 1997#endif 1998#endif 1999 } 2000 addr_size = DWARF2_FDE_RELOC_SIZE; 2001 } 2002 else 2003 { 2004 exp.X_add_number = 0; 2005 exp.X_add_symbol = fde->start_address; 2006 addr_size = DWARF2_ADDR_SIZE (stdoutput); 2007 emit_expr (&exp, addr_size); 2008 } 2009 2010 exp.X_op = O_subtract; 2011 exp.X_add_symbol = fde->end_address; 2012 exp.X_op_symbol = fde->start_address; /* Code length. */ 2013 exp.X_add_number = 0; 2014 emit_expr (&exp, addr_size); 2015 2016 augmentation_size = encoding_size (fde->lsda_encoding); 2017 if (eh_frame) 2018 out_uleb128 (augmentation_size); /* Augmentation size. */ 2019 2020 emit_expr_encoded (&fde->lsda, cie->lsda_encoding, FALSE); 2021 2022 for (; first; first = first->next) 2023 if (CUR_SEG (first) == CUR_SEG (fde)) 2024 output_cfi_insn (first); 2025 2026 frag_align (align, DW_CFA_nop, 0); 2027 symbol_set_value_now (end_address); 2028} 2029 2030static struct cie_entry * 2031select_cie_for_fde (struct fde_entry *fde, bfd_boolean eh_frame, 2032 struct cfi_insn_data **pfirst, int align) 2033{ 2034 struct cfi_insn_data *i, *j; 2035 struct cie_entry *cie; 2036 2037 for (cie = cie_root; cie; cie = cie->next) 2038 { 2039 if (CUR_SEG (cie) != CUR_SEG (fde)) 2040 continue; 2041 if (cie->return_column != fde->return_column 2042 || cie->signal_frame != fde->signal_frame 2043 || cie->per_encoding != fde->per_encoding 2044 || cie->lsda_encoding != fde->lsda_encoding) 2045 continue; 2046 if (cie->per_encoding != DW_EH_PE_omit) 2047 { 2048 if (cie->personality.X_op != fde->personality.X_op 2049 || cie->personality.X_add_number 2050 != fde->personality.X_add_number) 2051 continue; 2052 switch (cie->personality.X_op) 2053 { 2054 case O_constant: 2055 if (cie->personality.X_unsigned != fde->personality.X_unsigned) 2056 continue; 2057 break; 2058 case O_symbol: 2059 if (cie->personality.X_add_symbol 2060 != fde->personality.X_add_symbol) 2061 continue; 2062 break; 2063 default: 2064 abort (); 2065 } 2066 } 2067 for (i = cie->first, j = fde->data; 2068 i != cie->last && j != NULL; 2069 i = i->next, j = j->next) 2070 { 2071 if (i->insn != j->insn) 2072 goto fail; 2073 switch (i->insn) 2074 { 2075 case DW_CFA_advance_loc: 2076 case DW_CFA_remember_state: 2077 /* We reached the first advance/remember in the FDE, 2078 but did not reach the end of the CIE list. */ 2079 goto fail; 2080 2081 case DW_CFA_offset: 2082 case DW_CFA_def_cfa: 2083 if (i->u.ri.reg != j->u.ri.reg) 2084 goto fail; 2085 if (i->u.ri.offset != j->u.ri.offset) 2086 goto fail; 2087 break; 2088 2089 case DW_CFA_register: 2090 if (i->u.rr.reg1 != j->u.rr.reg1) 2091 goto fail; 2092 if (i->u.rr.reg2 != j->u.rr.reg2) 2093 goto fail; 2094 break; 2095 2096 case DW_CFA_def_cfa_register: 2097 case DW_CFA_restore: 2098 case DW_CFA_undefined: 2099 case DW_CFA_same_value: 2100 if (i->u.r != j->u.r) 2101 goto fail; 2102 break; 2103 2104 case DW_CFA_def_cfa_offset: 2105 if (i->u.i != j->u.i) 2106 goto fail; 2107 break; 2108 2109 case CFI_escape: 2110 case CFI_val_encoded_addr: 2111 case CFI_label: 2112 /* Don't bother matching these for now. */ 2113 goto fail; 2114 2115 default: 2116 abort (); 2117 } 2118 } 2119 2120 /* Success if we reached the end of the CIE list, and we've either 2121 run out of FDE entries or we've encountered an advance, 2122 remember, or escape. */ 2123 if (i == cie->last 2124 && (!j 2125 || j->insn == DW_CFA_advance_loc 2126 || j->insn == DW_CFA_remember_state 2127 || j->insn == CFI_escape 2128 || j->insn == CFI_val_encoded_addr 2129 || j->insn == CFI_label)) 2130 { 2131 *pfirst = j; 2132 return cie; 2133 } 2134 2135 fail:; 2136 } 2137 2138 cie = XNEW (struct cie_entry); 2139 cie->next = cie_root; 2140 cie_root = cie; 2141 SET_CUR_SEG (cie, CUR_SEG (fde)); 2142 cie->return_column = fde->return_column; 2143 cie->signal_frame = fde->signal_frame; 2144 cie->per_encoding = fde->per_encoding; 2145 cie->lsda_encoding = fde->lsda_encoding; 2146 cie->personality = fde->personality; 2147 cie->first = fde->data; 2148 2149 for (i = cie->first; i ; i = i->next) 2150 if (i->insn == DW_CFA_advance_loc 2151 || i->insn == DW_CFA_remember_state 2152 || i->insn == CFI_escape 2153 || i->insn == CFI_val_encoded_addr 2154 || i->insn == CFI_label) 2155 break; 2156 2157 cie->last = i; 2158 *pfirst = i; 2159 2160 output_cie (cie, eh_frame, align); 2161 2162 return cie; 2163} 2164 2165#ifdef md_reg_eh_frame_to_debug_frame 2166static void 2167cfi_change_reg_numbers (struct cfi_insn_data *insn, segT ccseg) 2168{ 2169 for (; insn; insn = insn->next) 2170 { 2171 if (CUR_SEG (insn) != ccseg) 2172 continue; 2173 switch (insn->insn) 2174 { 2175 case DW_CFA_advance_loc: 2176 case DW_CFA_def_cfa_offset: 2177 case DW_CFA_remember_state: 2178 case DW_CFA_restore_state: 2179 case DW_CFA_GNU_window_save: 2180 case CFI_escape: 2181 case CFI_label: 2182 break; 2183 2184 case DW_CFA_def_cfa: 2185 case DW_CFA_offset: 2186 insn->u.ri.reg = md_reg_eh_frame_to_debug_frame (insn->u.ri.reg); 2187 break; 2188 2189 case DW_CFA_def_cfa_register: 2190 case DW_CFA_undefined: 2191 case DW_CFA_same_value: 2192 case DW_CFA_restore: 2193 insn->u.r = md_reg_eh_frame_to_debug_frame (insn->u.r); 2194 break; 2195 2196 case DW_CFA_register: 2197 insn->u.rr.reg1 = md_reg_eh_frame_to_debug_frame (insn->u.rr.reg1); 2198 insn->u.rr.reg2 = md_reg_eh_frame_to_debug_frame (insn->u.rr.reg2); 2199 break; 2200 2201 case CFI_val_encoded_addr: 2202 insn->u.ea.reg = md_reg_eh_frame_to_debug_frame (insn->u.ea.reg); 2203 break; 2204 2205 default: 2206 abort (); 2207 } 2208 } 2209} 2210#else 2211#define cfi_change_reg_numbers(insn, cseg) do { } while (0) 2212#endif 2213 2214#if SUPPORT_COMPACT_EH 2215static void 2216cfi_emit_eh_header (symbolS *sym, bfd_vma addend) 2217{ 2218 expressionS exp; 2219 2220 exp.X_add_number = addend; 2221 exp.X_add_symbol = sym; 2222 emit_expr_encoded (&exp, DW_EH_PE_sdata4 | DW_EH_PE_pcrel, FALSE); 2223} 2224 2225static void 2226output_eh_header (struct fde_entry *fde) 2227{ 2228 char *p; 2229 bfd_vma addend; 2230 2231 if (fde->eh_header_type == EH_COMPACT_INLINE) 2232 addend = 0; 2233 else 2234 addend = 1; 2235 2236 cfi_emit_eh_header (fde->start_address, addend); 2237 2238 if (fde->eh_header_type == EH_COMPACT_INLINE) 2239 { 2240 p = frag_more (4); 2241 /* Inline entries always use PR1. */ 2242 *(p++) = 1; 2243 memcpy(p, fde->eh_data, 3); 2244 } 2245 else 2246 { 2247 if (fde->eh_header_type == EH_COMPACT_LEGACY) 2248 addend = 1; 2249 else if (fde->eh_header_type == EH_COMPACT_OUTLINE 2250 || fde->eh_header_type == EH_COMPACT_OUTLINE_DONE) 2251 addend = 0; 2252 else 2253 abort (); 2254 cfi_emit_eh_header (fde->eh_loc, addend); 2255 } 2256} 2257#endif 2258 2259void 2260cfi_finish (void) 2261{ 2262 struct cie_entry *cie, *cie_next; 2263 segT cfi_seg, ccseg; 2264 struct fde_entry *fde; 2265 struct cfi_insn_data *first; 2266 int save_flag_traditional_format, seek_next_seg; 2267 2268 if (all_fde_data == 0) 2269 return; 2270 2271 cfi_sections_set = TRUE; 2272 if ((all_cfi_sections & CFI_EMIT_eh_frame) != 0 2273 || (all_cfi_sections & CFI_EMIT_eh_frame_compact) != 0) 2274 { 2275 /* Make sure check_eh_frame doesn't do anything with our output. */ 2276 save_flag_traditional_format = flag_traditional_format; 2277 flag_traditional_format = 1; 2278 2279 if (!EH_FRAME_LINKONCE) 2280 { 2281 /* Open .eh_frame section. */ 2282 cfi_seg = get_cfi_seg (NULL, ".eh_frame", 2283 (SEC_ALLOC | SEC_LOAD | SEC_DATA 2284 | DWARF2_EH_FRAME_READ_ONLY), 2285 EH_FRAME_ALIGNMENT); 2286#ifdef md_fix_up_eh_frame 2287 md_fix_up_eh_frame (cfi_seg); 2288#else 2289 (void) cfi_seg; 2290#endif 2291 } 2292 2293 do 2294 { 2295 ccseg = NULL; 2296 seek_next_seg = 0; 2297 2298 for (cie = cie_root; cie; cie = cie_next) 2299 { 2300 cie_next = cie->next; 2301 free ((void *) cie); 2302 } 2303 cie_root = NULL; 2304 2305 for (fde = all_fde_data; fde ; fde = fde->next) 2306 { 2307 if ((fde->sections & CFI_EMIT_eh_frame) == 0 2308 && (fde->sections & CFI_EMIT_eh_frame_compact) == 0) 2309 continue; 2310 2311#if SUPPORT_COMPACT_EH 2312 /* Emit a LEGACY format header if we have processed all 2313 of the .cfi directives without encountering either inline or 2314 out-of-line compact unwinding opcodes. */ 2315 if (fde->eh_header_type == EH_COMPACT_HAS_LSDA 2316 || fde->eh_header_type == EH_COMPACT_UNKNOWN) 2317 fde->eh_header_type = EH_COMPACT_LEGACY; 2318 2319 if (fde->eh_header_type != EH_COMPACT_LEGACY) 2320 continue; 2321#endif 2322 if (EH_FRAME_LINKONCE) 2323 { 2324 if (HANDLED (fde)) 2325 continue; 2326 if (seek_next_seg && CUR_SEG (fde) != ccseg) 2327 { 2328 seek_next_seg = 2; 2329 continue; 2330 } 2331 if (!seek_next_seg) 2332 { 2333 ccseg = CUR_SEG (fde); 2334 /* Open .eh_frame section. */ 2335 cfi_seg = get_cfi_seg (ccseg, ".eh_frame", 2336 (SEC_ALLOC | SEC_LOAD | SEC_DATA 2337 | DWARF2_EH_FRAME_READ_ONLY), 2338 EH_FRAME_ALIGNMENT); 2339#ifdef md_fix_up_eh_frame 2340 md_fix_up_eh_frame (cfi_seg); 2341#else 2342 (void) cfi_seg; 2343#endif 2344 seek_next_seg = 1; 2345 } 2346 SET_HANDLED (fde, 1); 2347 } 2348 2349 if (fde->end_address == NULL) 2350 { 2351 as_bad (_("open CFI at the end of file; missing .cfi_endproc directive")); 2352 fde->end_address = fde->start_address; 2353 } 2354 2355 cie = select_cie_for_fde (fde, TRUE, &first, 2); 2356 fde->eh_loc = symbol_temp_new_now (); 2357 output_fde (fde, cie, TRUE, first, 2358 fde->next == NULL ? EH_FRAME_ALIGNMENT : 2); 2359 } 2360 } 2361 while (EH_FRAME_LINKONCE && seek_next_seg == 2); 2362 2363 if (EH_FRAME_LINKONCE) 2364 for (fde = all_fde_data; fde ; fde = fde->next) 2365 SET_HANDLED (fde, 0); 2366 2367#if SUPPORT_COMPACT_EH 2368 if (compact_eh) 2369 { 2370 /* Create remaining out of line table entries. */ 2371 do 2372 { 2373 ccseg = NULL; 2374 seek_next_seg = 0; 2375 2376 for (fde = all_fde_data; fde ; fde = fde->next) 2377 { 2378 if ((fde->sections & CFI_EMIT_eh_frame) == 0 2379 && (fde->sections & CFI_EMIT_eh_frame_compact) == 0) 2380 continue; 2381 2382 if (fde->eh_header_type != EH_COMPACT_OUTLINE) 2383 continue; 2384 if (HANDLED (fde)) 2385 continue; 2386 if (seek_next_seg && CUR_SEG (fde) != ccseg) 2387 { 2388 seek_next_seg = 2; 2389 continue; 2390 } 2391 if (!seek_next_seg) 2392 { 2393 ccseg = CUR_SEG (fde); 2394 /* Open .gnu_extab section. */ 2395 get_cfi_seg (ccseg, ".gnu_extab", 2396 (SEC_ALLOC | SEC_LOAD | SEC_DATA 2397 | DWARF2_EH_FRAME_READ_ONLY), 2398 1); 2399 seek_next_seg = 1; 2400 } 2401 SET_HANDLED (fde, 1); 2402 2403 frag_align (1, 0, 0); 2404 record_alignment (now_seg, 1); 2405 output_compact_unwind_data (fde, 1); 2406 } 2407 } 2408 while (EH_FRAME_LINKONCE && seek_next_seg == 2); 2409 2410 for (fde = all_fde_data; fde ; fde = fde->next) 2411 SET_HANDLED (fde, 0); 2412 2413 /* Create index table fragments. */ 2414 do 2415 { 2416 ccseg = NULL; 2417 seek_next_seg = 0; 2418 2419 for (fde = all_fde_data; fde ; fde = fde->next) 2420 { 2421 if ((fde->sections & CFI_EMIT_eh_frame) == 0 2422 && (fde->sections & CFI_EMIT_eh_frame_compact) == 0) 2423 continue; 2424 2425 if (HANDLED (fde)) 2426 continue; 2427 if (seek_next_seg && CUR_SEG (fde) != ccseg) 2428 { 2429 seek_next_seg = 2; 2430 continue; 2431 } 2432 if (!seek_next_seg) 2433 { 2434 ccseg = CUR_SEG (fde); 2435 /* Open .eh_frame_entry section. */ 2436 cfi_seg = get_cfi_seg (ccseg, ".eh_frame_entry", 2437 (SEC_ALLOC | SEC_LOAD | SEC_DATA 2438 | DWARF2_EH_FRAME_READ_ONLY), 2439 2); 2440 seek_next_seg = 1; 2441 } 2442 SET_HANDLED (fde, 1); 2443 2444 output_eh_header (fde); 2445 } 2446 } 2447 while (seek_next_seg == 2); 2448 2449 for (fde = all_fde_data; fde ; fde = fde->next) 2450 SET_HANDLED (fde, 0); 2451 } 2452#endif /* SUPPORT_COMPACT_EH */ 2453 2454 flag_traditional_format = save_flag_traditional_format; 2455 } 2456 2457 cfi_sections_set = TRUE; 2458 if ((all_cfi_sections & CFI_EMIT_debug_frame) != 0) 2459 { 2460 int alignment = ffs (DWARF2_ADDR_SIZE (stdoutput)) - 1; 2461 2462 if (!SUPPORT_FRAME_LINKONCE) 2463 get_cfi_seg (NULL, ".debug_frame", 2464 SEC_READONLY | SEC_DEBUGGING, 2465 alignment); 2466 2467 do 2468 { 2469 ccseg = NULL; 2470 seek_next_seg = 0; 2471 2472 for (cie = cie_root; cie; cie = cie_next) 2473 { 2474 cie_next = cie->next; 2475 free ((void *) cie); 2476 } 2477 cie_root = NULL; 2478 2479 for (fde = all_fde_data; fde ; fde = fde->next) 2480 { 2481 if ((fde->sections & CFI_EMIT_debug_frame) == 0) 2482 continue; 2483 2484 if (SUPPORT_FRAME_LINKONCE) 2485 { 2486 if (HANDLED (fde)) 2487 continue; 2488 if (seek_next_seg && CUR_SEG (fde) != ccseg) 2489 { 2490 seek_next_seg = 2; 2491 continue; 2492 } 2493 if (!seek_next_seg) 2494 { 2495 ccseg = CUR_SEG (fde); 2496 /* Open .debug_frame section. */ 2497 get_cfi_seg (ccseg, ".debug_frame", 2498 SEC_READONLY | SEC_DEBUGGING, 2499 alignment); 2500 seek_next_seg = 1; 2501 } 2502 SET_HANDLED (fde, 1); 2503 } 2504 if (fde->end_address == NULL) 2505 { 2506 as_bad (_("open CFI at the end of file; missing .cfi_endproc directive")); 2507 fde->end_address = fde->start_address; 2508 } 2509 2510 fde->per_encoding = DW_EH_PE_omit; 2511 fde->lsda_encoding = DW_EH_PE_omit; 2512 cfi_change_reg_numbers (fde->data, ccseg); 2513 cie = select_cie_for_fde (fde, FALSE, &first, alignment); 2514 output_fde (fde, cie, FALSE, first, alignment); 2515 } 2516 } 2517 while (SUPPORT_FRAME_LINKONCE && seek_next_seg == 2); 2518 2519 if (SUPPORT_FRAME_LINKONCE) 2520 for (fde = all_fde_data; fde ; fde = fde->next) 2521 SET_HANDLED (fde, 0); 2522 } 2523} 2524 2525#else /* TARGET_USE_CFIPOP */ 2526 2527/* Emit an intelligible error message for missing support. */ 2528 2529static void 2530dot_cfi_dummy (int ignored ATTRIBUTE_UNUSED) 2531{ 2532 as_bad (_("CFI is not supported for this target")); 2533 ignore_rest_of_line (); 2534} 2535 2536const pseudo_typeS cfi_pseudo_table[] = 2537 { 2538 { "cfi_sections", dot_cfi_dummy, 0 }, 2539 { "cfi_startproc", dot_cfi_dummy, 0 }, 2540 { "cfi_endproc", dot_cfi_dummy, 0 }, 2541 { "cfi_fde_data", dot_cfi_dummy, 0 }, 2542 { "cfi_def_cfa", dot_cfi_dummy, 0 }, 2543 { "cfi_def_cfa_register", dot_cfi_dummy, 0 }, 2544 { "cfi_def_cfa_offset", dot_cfi_dummy, 0 }, 2545 { "cfi_adjust_cfa_offset", dot_cfi_dummy, 0 }, 2546 { "cfi_offset", dot_cfi_dummy, 0 }, 2547 { "cfi_rel_offset", dot_cfi_dummy, 0 }, 2548 { "cfi_register", dot_cfi_dummy, 0 }, 2549 { "cfi_return_column", dot_cfi_dummy, 0 }, 2550 { "cfi_restore", dot_cfi_dummy, 0 }, 2551 { "cfi_undefined", dot_cfi_dummy, 0 }, 2552 { "cfi_same_value", dot_cfi_dummy, 0 }, 2553 { "cfi_remember_state", dot_cfi_dummy, 0 }, 2554 { "cfi_restore_state", dot_cfi_dummy, 0 }, 2555 { "cfi_window_save", dot_cfi_dummy, 0 }, 2556 { "cfi_escape", dot_cfi_dummy, 0 }, 2557 { "cfi_signal_frame", dot_cfi_dummy, 0 }, 2558 { "cfi_personality", dot_cfi_dummy, 0 }, 2559 { "cfi_personality_id", dot_cfi_dummy, 0 }, 2560 { "cfi_lsda", dot_cfi_dummy, 0 }, 2561 { "cfi_val_encoded_addr", dot_cfi_dummy, 0 }, 2562 { "cfi_label", dot_cfi_dummy, 0 }, 2563 { "cfi_inline_lsda", dot_cfi_dummy, 0 }, 2564 { "cfi_val_offset", dot_cfi_dummy, 0 }, 2565 { NULL, NULL, 0 } 2566 }; 2567 2568void 2569cfi_finish (void) 2570{ 2571} 2572#endif /* TARGET_USE_CFIPOP */ 2573