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