Example #1
0
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;
}
Example #2
0
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);
    }
}