void cfi_finish (void) { segT cfi_seg; struct fde_entry *fde; int save_flag_traditional_format; if (all_fde_data == 0) return; /* Open .eh_frame section. */ cfi_seg = subseg_new (".eh_frame", 0); bfd_set_section_flags (stdoutput, cfi_seg, SEC_ALLOC | SEC_LOAD | SEC_DATA | DWARF2_EH_FRAME_READ_ONLY); subseg_set (cfi_seg, 0); record_alignment (cfi_seg, EH_FRAME_ALIGNMENT); #ifdef md_fix_up_eh_frame md_fix_up_eh_frame (cfi_seg); #endif /* Make sure check_eh_frame doesn't do anything with our output. */ save_flag_traditional_format = flag_traditional_format; flag_traditional_format = 1; for (fde = all_fde_data; fde ; fde = fde->next) { struct cfi_insn_data *first; struct cie_entry *cie; if (fde->end_address == NULL) { as_bad (_("open CFI at the end of file; missing .cfi_endproc directive")); fde->end_address = fde->start_address; } cie = select_cie_for_fde (fde, &first); output_fde (fde, cie, first, fde->next == NULL ? EH_FRAME_ALIGNMENT : 2); } flag_traditional_format = save_flag_traditional_format; }
void cfi_finish (void) { struct cie_entry *cie, *cie_next; segT cfi_seg, ccseg; struct fde_entry *fde; struct cfi_insn_data *first; int save_flag_traditional_format, seek_next_seg; if (all_fde_data == 0) return; if ((cfi_sections & CFI_EMIT_eh_frame) != 0) { /* Make sure check_eh_frame doesn't do anything with our output. */ save_flag_traditional_format = flag_traditional_format; flag_traditional_format = 1; if (!SUPPORT_FRAME_LINKONCE) { /* Open .eh_frame section. */ cfi_seg = get_cfi_seg (NULL, ".eh_frame", (SEC_ALLOC | SEC_LOAD | SEC_DATA | DWARF2_EH_FRAME_READ_ONLY), EH_FRAME_ALIGNMENT); #ifdef md_fix_up_eh_frame md_fix_up_eh_frame (cfi_seg); #else (void) cfi_seg; #endif } do { ccseg = NULL; seek_next_seg = 0; for (cie = cie_root; cie; cie = cie_next) { cie_next = cie->next; free ((void *) cie); } cie_root = NULL; for (fde = all_fde_data; fde ; fde = fde->next) { if (SUPPORT_FRAME_LINKONCE) { if (HANDLED (fde)) continue; if (seek_next_seg && CUR_SEG (fde) != ccseg) { seek_next_seg = 2; continue; } if (!seek_next_seg) { ccseg = CUR_SEG (fde); /* Open .eh_frame section. */ cfi_seg = get_cfi_seg (ccseg, ".eh_frame", (SEC_ALLOC | SEC_LOAD | SEC_DATA | DWARF2_EH_FRAME_READ_ONLY), EH_FRAME_ALIGNMENT); #ifdef md_fix_up_eh_frame md_fix_up_eh_frame (cfi_seg); #else (void) cfi_seg; #endif seek_next_seg = 1; } SET_HANDLED (fde, 1); } if (fde->end_address == NULL) { as_bad (_("open CFI at the end of file; missing .cfi_endproc directive")); fde->end_address = fde->start_address; } cie = select_cie_for_fde (fde, TRUE, &first, 2); output_fde (fde, cie, TRUE, first, fde->next == NULL ? EH_FRAME_ALIGNMENT : 2); } } while (SUPPORT_FRAME_LINKONCE && seek_next_seg == 2); if (SUPPORT_FRAME_LINKONCE) for (fde = all_fde_data; fde ; fde = fde->next) SET_HANDLED (fde, 0); flag_traditional_format = save_flag_traditional_format; } if ((cfi_sections & CFI_EMIT_debug_frame) != 0) { int alignment = ffs (DWARF2_ADDR_SIZE (stdoutput)) - 1; if (!SUPPORT_FRAME_LINKONCE) get_cfi_seg (NULL, ".debug_frame", SEC_READONLY | SEC_DEBUGGING, alignment); do { ccseg = NULL; seek_next_seg = 0; for (cie = cie_root; cie; cie = cie_next) { cie_next = cie->next; free ((void *) cie); } cie_root = NULL; for (fde = all_fde_data; fde ; fde = fde->next) { if (SUPPORT_FRAME_LINKONCE) { if (HANDLED (fde)) continue; if (seek_next_seg && CUR_SEG (fde) != ccseg) { seek_next_seg = 2; continue; } if (!seek_next_seg) { ccseg = CUR_SEG (fde); /* Open .debug_frame section. */ get_cfi_seg (ccseg, ".debug_frame", SEC_READONLY | SEC_DEBUGGING, alignment); seek_next_seg = 1; } SET_HANDLED (fde, 1); } if (fde->end_address == NULL) { as_bad (_("open CFI at the end of file; missing .cfi_endproc directive")); fde->end_address = fde->start_address; } fde->per_encoding = DW_EH_PE_omit; fde->lsda_encoding = DW_EH_PE_omit; cfi_change_reg_numbers (fde->data, ccseg); cie = select_cie_for_fde (fde, FALSE, &first, alignment); output_fde (fde, cie, FALSE, first, alignment); } } while (SUPPORT_FRAME_LINKONCE && seek_next_seg == 2); if (SUPPORT_FRAME_LINKONCE) for (fde = all_fde_data; fde ; fde = fde->next) SET_HANDLED (fde, 0); } }