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]

dwarf2out.c/tree.c patches for IA-64 debug info problems


(Kenner: note the problem resulting from your host_integerp changes.)

On 64-bit targets, gcc is emitting incorrect debug info for 8 byte enum values.
There are two problems.

The code for emitting 8 byte values thinks that an 8 byte value is always a
long long, and tries to emit it as two 4-byte values.  However, we can only
reach this point if longs are 8 bytes, hence we should be emitting the 8 byte
values directly as a single value.

The host_integerp tests are too strict.  They reject values that fit in an
unsigned long but not a long.  This causes us to loose debug info for all
unsigned long values that have the high bit set.  It seems sensible to add
code to host_integerp to handle unsigned type values when pos is 0.

Here is a testcase, extracted from emacs.

enum gdb_lisp_params
{
  gdb_data_seg_bits = 0x8000000000000000UL,
};

main()
{
  printf ("0x%lx\n", gdb_data_seg_bits);
}

This was tested on ia64-linux against the gdb testsuite.
If you actually try this, you will see that gdb also has bugs in the handling
of 8-byte enum values.  I will take that up with the gdb maintainers next
after gcc is OK.

This was also tested with an i686-linux bootstrap for the tree.c change.

If I don't get any comment on this, I will check it in.

2000-06-07  James E. Wilson  <wilson@cygnus.com>

	* dwarf2out.c (ASM_OUTPUT_DWARF_DATA8): Add new macro that uses
	UNALIGNED_DOUBLE_INT_ASM_OP.  Rename old macro to
	ASM_OUTPUT_DWARF_CONST_DOUBLE.
	(output_die, case dw_val_class_unsigned_const): Correct call to
	ASM_OUTPUT_DWARF_DATA8.
	(output_die, case dw_val_class_long_long): Use
	ASM_OUTPUT_DWARF_CONST_DOUBLE.
	* tree.c (host_integerp): Accept unsigned HOST_WIDE_INT values when
	pos is zero.
	
Index: dwarf2out.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/dwarf2out.c,v
retrieving revision 1.175
diff -p -r1.175 dwarf2out.c
*** dwarf2out.c	2000/05/31 01:36:58	1.175
--- dwarf2out.c	2000/06/08 00:26:00
*************** static void dwarf2out_frame_debug_expr	P
*** 405,410 ****
--- 405,416 ----
    fprintf ((FILE), "\t%s\t0x%x", UNALIGNED_INT_ASM_OP, (unsigned) (VALUE))
  #endif
  
+ #ifndef ASM_OUTPUT_DWARF_DATA8
+ #define ASM_OUTPUT_DWARF_DATA8(FILE,VALUE) \
+   fprintf ((FILE), "\t%s\t0x%lx", UNALIGNED_DOUBLE_INT_ASM_OP, \
+ 	   (unsigned long) (VALUE))
+ #endif
+ 
  #ifndef ASM_OUTPUT_DWARF_DATA
  #define ASM_OUTPUT_DWARF_DATA(FILE,VALUE) \
    fprintf ((FILE), "\t%s\t0x%lx", UNALIGNED_OFFSET_ASM_OP, \
*************** static void dwarf2out_frame_debug_expr	P
*** 417,424 ****
  	   (unsigned long) (VALUE))
  #endif
  
! #ifndef ASM_OUTPUT_DWARF_DATA8
! #define ASM_OUTPUT_DWARF_DATA8(FILE,HIGH_VALUE,LOW_VALUE)		\
    do {									\
      if (WORDS_BIG_ENDIAN)						\
        {									\
--- 423,430 ----
  	   (unsigned long) (VALUE))
  #endif
  
! #ifndef ASM_OUTPUT_DWARF_CONST_DOUBLE
! #define ASM_OUTPUT_DWARF_CONST_DOUBLE(FILE,HIGH_VALUE,LOW_VALUE)	\
    do {									\
      if (WORDS_BIG_ENDIAN)						\
        {									\
*************** typedef struct pubname_struct *pubname_r
*** 2011,2016 ****
--- 2017,2023 ----
  typedef dw_die_ref *arange_ref;
  
  /* Describe a double word constant value.  */
+ /* ??? Every instance of long_long in the code really means CONST_DOUBLE.  */
  
  typedef struct dw_long_long_struct
  {
*************** output_die (die)
*** 5098,5106 ****
  	      ASM_OUTPUT_DWARF_DATA4 (asm_out_file, AT_unsigned (a));
  	      break;
  	    case 8:
! 	      ASM_OUTPUT_DWARF_DATA8 (asm_out_file,
! 				      a->dw_attr_val.v.val_long_long.hi,
! 				      a->dw_attr_val.v.val_long_long.low);
  	      break;
  	    default:
  	      abort ();
--- 5105,5111 ----
  	      ASM_OUTPUT_DWARF_DATA4 (asm_out_file, AT_unsigned (a));
  	      break;
  	    case 8:
! 	      ASM_OUTPUT_DWARF_DATA8 (asm_out_file, AT_unsigned (a));
  	      break;
  	    default:
  	      abort ();
*************** output_die (die)
*** 5114,5122 ****
  		   ASM_COMMENT_START, dwarf_attr_name (a->dw_attr));
  
  	  fputc ('\n', asm_out_file);
! 	  ASM_OUTPUT_DWARF_DATA8 (asm_out_file,
! 				  a->dw_attr_val.v.val_long_long.hi,
! 				  a->dw_attr_val.v.val_long_long.low);
  
  	  if (flag_debug_asm)
  	    fprintf (asm_out_file,
--- 5119,5127 ----
  		   ASM_COMMENT_START, dwarf_attr_name (a->dw_attr));
  
  	  fputc ('\n', asm_out_file);
! 	  ASM_OUTPUT_DWARF_CONST_DOUBLE (asm_out_file,
! 					 a->dw_attr_val.v.val_long_long.hi,
! 					 a->dw_attr_val.v.val_long_long.low);
  
  	  if (flag_debug_asm)
  	    fprintf (asm_out_file,
Index: tree.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/tree.c,v
retrieving revision 1.147
diff -p -r1.147 tree.c
*** tree.c	2000/05/31 18:36:05	1.147
--- tree.c	2000/06/08 00:26:00
*************** host_integerp (t, pos)
*** 4306,4312 ****
  	  && ((TREE_INT_CST_HIGH (t) == 0
  	       && (HOST_WIDE_INT) TREE_INT_CST_LOW (t) >= 0)
  	      || (! pos && TREE_INT_CST_HIGH (t) == -1
! 		  && (HOST_WIDE_INT) TREE_INT_CST_LOW (t) < 0)));
  }
  
  /* Return the HOST_WIDE_INT least significant bits of T if it is an
--- 4306,4314 ----
  	  && ((TREE_INT_CST_HIGH (t) == 0
  	       && (HOST_WIDE_INT) TREE_INT_CST_LOW (t) >= 0)
  	      || (! pos && TREE_INT_CST_HIGH (t) == -1
! 		  && (HOST_WIDE_INT) TREE_INT_CST_LOW (t) < 0)
! 	      || (! pos && TREE_INT_CST_HIGH (t) == 0
! 		  && TREE_UNSIGNED (TREE_TYPE (t)))));
  }
  
  /* Return the HOST_WIDE_INT least significant bits of T if it is an

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