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