This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

PATCH: dwarf2out misalignment


We were miscalculating the size of DIEs once our abbrev table grew
large enough to require a two-byte LEB128 index, breaking libstdc++-v3.

2000-09-21  Jason Merrill  <jason@redhat.com>

	* dwarf2out.c (die_struct): Add die_mark field.
	(mark_dies, unmark_dies): New fns.
	(clear_die_sizes): Remove.
	(print_die): Check die_symbol rather than die_offset.
	(build_abbrev_table, output_pubnames, output_aranges): Check
	die_mark rather than die_offset.
	(output_comp_unit): Move calc_die_sizes after build_abbrev_table.
	Call mark_dies.

*** dwarf2out.c.~1~	Sun Sep 17 15:47:48 2000
--- dwarf2out.c	Wed Sep 20 21:55:32 2000
*************** typedef struct die_struct
*** 3021,3026 ****
--- 3021,3027 ----
    dw_die_ref die_sib;
    dw_offset die_offset;
    unsigned long die_abbrev;
+   int die_mark;
  }
  die_node;
  
*************** static unsigned long size_of_string	PARA
*** 3378,3384 ****
  static int constant_size		PARAMS ((long unsigned));
  static unsigned long size_of_die	PARAMS ((dw_die_ref));
  static void calc_die_sizes		PARAMS ((dw_die_ref));
! static void clear_die_sizes		PARAMS ((dw_die_ref));
  static unsigned long size_of_line_prolog PARAMS ((void));
  static unsigned long size_of_pubnames	PARAMS ((void));
  static unsigned long size_of_aranges	PARAMS ((void));
--- 3379,3386 ----
  static int constant_size		PARAMS ((long unsigned));
  static unsigned long size_of_die	PARAMS ((dw_die_ref));
  static void calc_die_sizes		PARAMS ((dw_die_ref));
! static void mark_dies			PARAMS ((dw_die_ref));
! static void unmark_dies			PARAMS ((dw_die_ref));
  static unsigned long size_of_line_prolog PARAMS ((void));
  static unsigned long size_of_pubnames	PARAMS ((void));
  static unsigned long size_of_aranges	PARAMS ((void));
*************** print_die (die, outfile)
*** 4893,4899 ****
  	case dw_val_class_die_ref:
  	  if (AT_ref (a) != NULL)
  	    {
! 	      if (AT_ref (a)->die_offset == 0)
  		fprintf (outfile, "die -> label: %s", AT_ref (a)->die_symbol);
  	      else
  		fprintf (outfile, "die -> %lu", AT_ref (a)->die_offset);
--- 4896,4902 ----
  	case dw_val_class_die_ref:
  	  if (AT_ref (a) != NULL)
  	    {
! 	      if (AT_ref (a)->die_symbol)
  		fprintf (outfile, "die -> label: %s", AT_ref (a)->die_symbol);
  	      else
  		fprintf (outfile, "die -> %lu", AT_ref (a)->die_offset);
*************** build_abbrev_table (die)
*** 5401,5411 ****
    register dw_attr_ref d_attr, a_attr;
  
    /* Scan the DIE references, and mark as external any that refer to
!      DIEs from other CUs (i.e. those with cleared die_offset).  */
    for (d_attr = die->die_attr; d_attr; d_attr = d_attr->dw_attr_next)
      {
        if (AT_class (d_attr) == dw_val_class_die_ref
! 	  && AT_ref (d_attr)->die_offset == 0)
  	{
  	  if (AT_ref (d_attr)->die_symbol == 0)
  	    abort ();
--- 5404,5414 ----
    register dw_attr_ref d_attr, a_attr;
  
    /* Scan the DIE references, and mark as external any that refer to
!      DIEs from other CUs (i.e. those which are not marked).  */
    for (d_attr = die->die_attr; d_attr; d_attr = d_attr->dw_attr_next)
      {
        if (AT_class (d_attr) == dw_val_class_die_ref
! 	  && AT_ref (d_attr)->die_mark == 0)
  	{
  	  if (AT_ref (d_attr)->die_symbol == 0)
  	    abort ();
*************** calc_die_sizes (die)
*** 5583,5600 ****
      next_die_offset += 1;
  }
  
! /* Clear the offsets and sizes for a die and its children.  We do this so
     that we know whether or not a reference needs to use FORM_ref_addr; only
!    DIEs in the same CU will have non-zero offsets available.  */
  
  static void
! clear_die_sizes (die)
       dw_die_ref die;
  {
    register dw_die_ref c;
!   die->die_offset = 0;
    for (c = die->die_child; c; c = c->die_sib)
!     clear_die_sizes (c);
  }
  
  /* Return the size of the line information prolog generated for the
--- 5586,5616 ----
      next_die_offset += 1;
  }
  
! /* Set the marks for a die and its children.  We do this so
     that we know whether or not a reference needs to use FORM_ref_addr; only
!    DIEs in the same CU will be marked.  We used to clear out the offset
!    and use that as the flag, but ran into ordering problems.  */
  
  static void
! mark_dies (die)
       dw_die_ref die;
  {
    register dw_die_ref c;
!   die->die_mark = 1;
!   for (c = die->die_child; c; c = c->die_sib)
!     mark_dies (c);
! }
! 
! /* Clear the marks for a die and its children.  */
! 
! static void
! unmark_dies (die)
!      dw_die_ref die;
! {
!   register dw_die_ref c;
!   die->die_mark = 0;
    for (c = die->die_child; c; c = c->die_sib)
!     unmark_dies (c);
  }
  
  /* Return the size of the line information prolog generated for the
*************** output_comp_unit (die)
*** 6069,6080 ****
    if (die->die_child == 0)
      return;
  
    /* Initialize the beginning DIE offset - and calculate sizes/offsets.   */
    next_die_offset = DWARF_COMPILE_UNIT_HEADER_SIZE;
    calc_die_sizes (die);
  
-   build_abbrev_table (die);
- 
    if (die->die_symbol)
      {
        secname = (char *) alloca (strlen (die->die_symbol) + 24);
--- 6085,6099 ----
    if (die->die_child == 0)
      return;
  
+   /* Mark all the DIEs in this CU so we know which get local refs.  */
+   mark_dies (die);
+ 
+   build_abbrev_table (die);
+ 
    /* Initialize the beginning DIE offset - and calculate sizes/offsets.   */
    next_die_offset = DWARF_COMPILE_UNIT_HEADER_SIZE;
    calc_die_sizes (die);
  
    if (die->die_symbol)
      {
        secname = (char *) alloca (strlen (die->die_symbol) + 24);
*************** output_comp_unit (die)
*** 6090,6099 ****
    output_compilation_unit_header ();
    output_die (die);
  
!   /* Leave the sizes on the main CU, since we do it last and we use the
!      sizes in output_pubnames.  */
    if (die->die_symbol)
!     clear_die_sizes (die);
  }
  
  /* The DWARF2 pubname for a nested thingy looks like "A::f".  The output
--- 6109,6118 ----
    output_compilation_unit_header ();
    output_die (die);
  
!   /* Leave the marks on the main CU, so we can check them in
!      output_pubnames.  */
    if (die->die_symbol)
!     unmark_dies (die);
  }
  
  /* The DWARF2 pubname for a nested thingy looks like "A::f".  The output
*************** output_pubnames ()
*** 6172,6178 ****
        register pubname_ref pub = &pubname_table[i];
  
        /* We shouldn't see pubnames for DIEs outside of the main CU.  */
!       if (pub->die->die_offset == 0)
  	abort ();
  
        ASM_OUTPUT_DWARF_DATA (asm_out_file, pub->die->die_offset);
--- 6191,6197 ----
        register pubname_ref pub = &pubname_table[i];
  
        /* We shouldn't see pubnames for DIEs outside of the main CU.  */
!       if (pub->die->die_mark == 0)
  	abort ();
  
        ASM_OUTPUT_DWARF_DATA (asm_out_file, pub->die->die_offset);
*************** output_aranges ()
*** 6289,6295 ****
        dw_die_ref die = arange_table[i];
  
        /* We shouldn't see aranges for DIEs outside of the main CU.  */
!       if (die->die_offset == 0)
  	abort ();
  
        if (die->die_tag == DW_TAG_subprogram)
--- 6308,6314 ----
        dw_die_ref die = arange_table[i];
  
        /* We shouldn't see aranges for DIEs outside of the main CU.  */
!       if (die->die_mark == 0)
  	abort ();
  
        if (die->die_tag == DW_TAG_subprogram)

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]